diff --git a/.gitignore b/.gitignore
index a03e315..b189bfc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,7 @@
*.log
*.tlog
*.aps
+*.user
.vs/
+debug/
diff --git a/TapCompressionTool/C64TapCompression/C64TapCompression.vcxproj b/TapCompressionTool/C64TapCompression/C64TapCompression.vcxproj
index 8d8a14e..69155b1 100644
--- a/TapCompressionTool/C64TapCompression/C64TapCompression.vcxproj
+++ b/TapCompressionTool/C64TapCompression/C64TapCompression.vcxproj
@@ -142,9 +142,6 @@
true
-
-
-
diff --git a/TapCompressionTool/C64TapCompression/ReadMe.txt b/TapCompressionTool/C64TapCompression/ReadMe.txt
deleted file mode 100644
index b4b342c..0000000
--- a/TapCompressionTool/C64TapCompression/ReadMe.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-========================================================================
- CONSOLE APPLICATION : C64TapCompression Project Overview
-========================================================================
-
-AppWizard has created this C64TapCompression application for you.
-
-This file contains a summary of what you will find in each of the files that
-make up your C64TapCompression application.
-
-
-C64TapCompression.vcxproj
- This is the main project file for VC++ projects generated using an Application Wizard.
- It contains information about the version of Visual C++ that generated the file, and
- information about the platforms, configurations, and project features selected with the
- Application Wizard.
-
-C64TapCompression.vcxproj.filters
- This is the filters file for VC++ projects generated using an Application Wizard.
- It contains information about the association between the files in your project
- and the filters. This association is used in the IDE to show grouping of files with
- similar extensions under a specific node (for e.g. ".cpp" files are associated with the
- "Source Files" filter).
-
-C64TapCompression.cpp
- This is the main application source file.
-
-/////////////////////////////////////////////////////////////////////////////
-Other standard files:
-
-StdAfx.h, StdAfx.cpp
- These files are used to build a precompiled header (PCH) file
- named C64TapCompression.pch and a precompiled types file named StdAfx.obj.
-
-/////////////////////////////////////////////////////////////////////////////
-Other notes:
-
-AppWizard uses "TODO:" comments to indicate parts of the source code you
-should add to or customize.
-
-/////////////////////////////////////////////////////////////////////////////
diff --git a/TapCompressionTool/C64TapCompression/Release/Resource.res b/TapCompressionTool/C64TapCompression/Release/Resource.res
index bec3c1d..2de4029 100644
Binary files a/TapCompressionTool/C64TapCompression/Release/Resource.res and b/TapCompressionTool/C64TapCompression/Release/Resource.res differ
diff --git a/TapCompressionTool/C64TapCompression/Resource.rc b/TapCompressionTool/C64TapCompression/Resource.rc
index 5887a5d..a20dbc3 100644
Binary files a/TapCompressionTool/C64TapCompression/Resource.rc and b/TapCompressionTool/C64TapCompression/Resource.rc differ
diff --git a/TapCompressionTool/C64TapCompression/TapCompression.cpp b/TapCompressionTool/C64TapCompression/TapCompression.cpp
index 55e4157..17be1f2 100644
--- a/TapCompressionTool/C64TapCompression/TapCompression.cpp
+++ b/TapCompressionTool/C64TapCompression/TapCompression.cpp
@@ -1,9 +1,6 @@
-
#include "stdafx.h"
-
#include
#include
-
#include
#include
@@ -12,354 +9,21 @@
using namespace std;
-#define BITS_INDEX 8 // 8,9 or 10 good value is 10
-#define BITS_REPEAT (16 - BITS_INDEX)
-#define WINDOW_SIZE (1<> (8 - SHIFT)) << 8)) + WINDOW_SIZE;
- a &= REPEAT_MASK;
- for (int i = 0; i <= a; i++) {
- u8 v = window[(idx + i)&(WINDOW_SIZE - 1)];
- window[(head++)&(WINDOW_SIZE - 1)] = v;
- fputc(v, fileWrite);
- }
- }
- }
- fclose(fileWrite);
- fclose(fileRead);
-}
-
-
-#define FAT_BUF_SIZE 128
-
-u8 g_fat_buffer[FAT_BUF_SIZE];
-
-void LZLikeDecodeToFile2(const char* fileName)
-{
-
- memset(g_fat_buffer,0, FAT_BUF_SIZE);
- memset(window, 0, FAT_BUF_SIZE);
-
- FILE* fileRead;
- fopen_s(&fileRead, fileName, "rb");
- fseek(fileRead, 0, SEEK_END);
- long size = ftell(fileRead);
- fseek(fileRead, 0, SEEK_SET);
- FILE* fileWrite;
- fopen_s(&fileWrite, "C:\\Users\\Admin\\Desktop\\New folder\\temp.tap", "wb");
-
-
- printf("FAT_BUF_SIZE %d\n", FAT_BUF_SIZE);
- printf("size %d\n", size);
- printf("size/FAT_BUF_SIZE %d\n", size/ FAT_BUF_SIZE);
-
- uint32_t head = 0;
- for (uint32_t i = 0; i> (8 - SHIFT)) << 8)) + WINDOW_SIZE;
- a &= REPEAT_MASK;
- for (uint16_t i = 0; i <= a; i++) {
- uint8_t v = window[(idx + i)&(WINDOW_SIZE - 1)];
- window[(head++)&(WINDOW_SIZE - 1)] = v;
- size_t r = fwrite(&v, 1, 1, fileWrite);
- }
- }
- }
- }
-
-
- u16 leftover = size % FAT_BUF_SIZE;
- if (leftover) {
-
- size_t r = fread(&g_fat_buffer[0], leftover, 1, fileRead);
-
- for (uint8_t k = 0; k> (8 - SHIFT)) << 8)) + WINDOW_SIZE;
- a &= REPEAT_MASK;
- for (uint16_t i = 0; i <= a; i++) {
- uint8_t v = window[(idx + i)&(WINDOW_SIZE - 1)];
- window[(head++)&(WINDOW_SIZE - 1)] = v;
- size_t r = fwrite(&v, 1, 1, fileWrite);
- }
- }
- }
-
- }
-
- fclose(fileWrite);
- fclose(fileRead);
-}
-
-
-u8 writeCache[16];
-
-void LZLikeDecodeToFile3(const char* fileName)
-{
-
- memset(g_fat_buffer, 0, FAT_BUF_SIZE);
- memset(window, 0, WINDOW_SIZE);
- memset(writeCache, 0, 16);
-
- FILE* fileRead;
- fopen_s(&fileRead, fileName, "rb");
- fseek(fileRead, 0, SEEK_END);
- long size = ftell(fileRead);
- fseek(fileRead, 0, SEEK_SET);
- FILE* fileWrite;
- fopen_s(&fileWrite, "C:\\Users\\Admin\\Desktop\\New folder\\temp.tap", "wb");
-
-
- printf("FAT_BUF_SIZE %d\n", FAT_BUF_SIZE);
- printf("size %d\n", size);
- printf("size/FAT_BUF_SIZE %d\n", size / FAT_BUF_SIZE);
-
- uint32_t head = 0;
- u16 amount = 0;
- for (uint32_t i = 0; i> (8 - SHIFT)) << 8)) + WINDOW_SIZE;
- g_fat_buffer[k + 0] &= REPEAT_MASK;
- for (uint16_t i = 0; i <= g_fat_buffer[k + 0]; i++) {
- uint8_t v = window[(idx + i)&(WINDOW_SIZE - 1)];
- window[(head++)&(WINDOW_SIZE - 1)] = v;
- writeCache[amount] = v;
- amount++;
- if (amount == 16) {
- fwrite(&writeCache[0], 16, 1, fileWrite);
- amount = 0;
- }
- }
- }
- }
- }
-
- u16 leftover = size % FAT_BUF_SIZE;
- if (leftover) {
- size_t r = fread(&g_fat_buffer[0], leftover, 1, fileRead);
- for (uint8_t k = 0; k> (8 - SHIFT)) << 8)) + WINDOW_SIZE;
- g_fat_buffer[k + 0] &= REPEAT_MASK;
- for (uint16_t i = 0; i <= g_fat_buffer[k + 0]; i++) {
- uint8_t v = window[(idx + i)&(WINDOW_SIZE - 1)];
- window[(head++)&(WINDOW_SIZE - 1)] = v;
- writeCache[amount] = v;
- amount++;
- if (amount == 16) {
- fwrite(&writeCache[0], 16, 1, fileWrite);
- amount = 0;
- }
- }
- }
- }
- }
-
- if (amount > 0) {
- fwrite(&writeCache[0], amount, 1, fileWrite);
- }
-
- fclose(fileWrite);
- fclose(fileRead);
-}
-
-
-//uint16_t head = 0;
-u8 amount = 0; // write cache will be small (well under a byte !! 16bytes maybe , 32 tops )
-//FILE* fileRead;
-//FILE* fileWrite;
-
-void decodeSection( /* FILE* fileRead, FILE* FileWrite ,*/ u16 amountToRead) {
- size_t r = fread(&g_fat_buffer[0], amountToRead, 1, fileRead);
- for (uint8_t k = 0; k> (8 - SHIFT)) << 8)) + WINDOW_SIZE;
- g_fat_buffer[k + 0] &= REPEAT_MASK;
- for (uint16_t i = 0; i <= g_fat_buffer[k + 0]; i++) {
- uint8_t v = window[(idx + i)&(WINDOW_SIZE - 1)];
- window[(head++)&(WINDOW_SIZE - 1)] = v;
- writeCache[amount++] = v;
- if (amount == 16) {
- fwrite(&writeCache[0], 16, 1, fileWrite);
- amount = 0;
- }
- }
- }
- }
-}
-
-
-void LZLikeDecodeToFile4(const char* fileName) {
-
- head = 0;
- amount = 0;
-
- //FILE* fileRead;
- fopen_s(&fileRead, fileName, "rb");
- fseek(fileRead, 0, SEEK_END);
- long size = ftell(fileRead);
- fseek(fileRead, 0, SEEK_SET);
-// FILE* fileWrite;
- fopen_s(&fileWrite, "C:\\Users\\Admin\\Desktop\\New folder\\temp.tap", "wb");
-
- printf("FAT_BUF_SIZE %d\n", FAT_BUF_SIZE);
- printf("size %d\n", size);
- printf("size/FAT_BUF_SIZE %d\n", size / FAT_BUF_SIZE);
-
- for (uint32_t i = 0; i 0) {
- fwrite(&writeCache[0], amount, 1, fileWrite);
- }
-
- fclose(fileWrite);
- fclose(fileRead);
-}
-
+#define FAT_BUF_SIZE (128)
+u8 window[WINDOW_SIZE];
u8* LZLikeDecode(u8 *out, u8 *in, u8 *end) {
u16 head = 0;
@@ -367,16 +31,12 @@ u8* LZLikeDecode(u8 *out, u8 *in, u8 *end) {
u8 a = *(in++);
u8 b = *(in++);
if (a == 0) {
- // no special repetition, cache and output disgarding 2nd byte
+ // no special repetition, recreate history
window[(head++)&(WINDOW_SIZE - 1)] = b;
*(out++) = b;
}
else {
- // index : example 2 bits from 'a' and 8 bits from 'b'
-
- u16 idx = head - 1 - (b + ((a >> (8-SHIFT)) << 8)) + WINDOW_SIZE;
- a &= REPEAT_MASK; // use the (say 6) bits left over
-
+ u16 idx = head - 1 - b + WINDOW_SIZE;
for (int i = 0; i <= a; i++) {
u8 v = window[(idx + i)&(WINDOW_SIZE - 1)];
window[(head++)&(WINDOW_SIZE - 1)] = v;
@@ -387,15 +47,11 @@ u8* LZLikeDecode(u8 *out, u8 *in, u8 *end) {
return out;
}
-
-
u8* LZLikeEncode(u8 *out, u8 *in, u8 *end) {
-// int i = 0;
u8* pcurrentBlockStart = in;
while (pcurrentBlockStart < end) {
- u16 byteOrOffset = *pcurrentBlockStart;
+ u8 offset = *pcurrentBlockStart;
u16 repetitionLength = 1;
- // for (int wi = 0; wi < WINDOW_SIZE; wi++) {
for (int wi = WINDOW_SIZE-1; wi > 0; wi--) {
u8* psearchIndex = pcurrentBlockStart;
if (psearchIndex > in + wi) {
@@ -407,27 +63,21 @@ u8* LZLikeEncode(u8 *out, u8 *in, u8 *end) {
}
if (len > repetitionLength) {
repetitionLength = len; // found a sequence in the past
- byteOrOffset = wi; // distance we looked back in bytes
- // i++;
-
+ offset = wi; // distance we looked back in bytes
if (len == REPEAT_LIMIT)
break;
}
}
}
-
- u8 v = (repetitionLength - 1) | ((byteOrOffset & 0xFF00) >> SHIFT);
-
- // * No sequence: writes [0],[byte]
- // * Found sequence: writes [no# repetitions 6bits + 2bits offset],[8bits offset]
- // WINDOW_SIZE uses 1024 in the case of 2^10bits
- *(out++) = v;
- *(out++) = byteOrOffset & 0xff;
+ // - No sequence: writes [0],[byte]
+ // - Found sequence: writes [8 repetitions bits],[8 offset bits]
+ // Remember an Arduino has to decode all this with its 2KB of dynamic memory to run the whole microcontroller.
+ // Even just using one extra bit on offset from repetitions, so 9 bits will eat 512bytes (and 10bits will eat 1024bytes)
+ // (8 is just doable at 256bytes without giving the Tapuino code a big facelift)
+ *(out++) = repetitionLength - 1; // how many repeating occurrences discovered
+ *(out++) = offset; // where to start history playback
pcurrentBlockStart += repetitionLength;
}
-
- //printf("%d\n", i);
-
return out;
}
@@ -437,49 +87,24 @@ u8* LZLikeEncode(u8 *out, u8 *in, u8 *end) {
int main(int argc, char **argv)
{
string folder = "";
-
if (argc == 2) {
- folder = argv[1]; // "C:\\Users\\Admin\\Desktop\\New folder\\taps2compress\\";
-
- // printf("%s\n", argv[1]);
+ folder = argv[1];
}
else {
- printf("ERROR: Missing command line pramater - please provide a path to your TAP files\n\n");
-
- printf("This tool finds and compresses all TAP files inside a folder\n");
+ printf("Help : This tool finds and compresses all TAP files inside a given folder\n");
printf(" - Orignal TAP files will not deleted\n");
printf(" - Compressed files will be created with a ZAP file extension\n\n");
-
- printf("Example usage: Compresses tap files found in the... \n");
- printf(" TAPCOMPRESSION [.\\] tools run path\n");
- printf(" TAPCOMPRESSION [yourTaps\\] relative folder\n");
- printf(" TAPCOMPRESSION [c:\\data\\c64\\yourTaps\\] absolute path\n");
+ printf("Example usage:\n");
+ printf(" TAPCOMPRESSION [.\\] (tools run path)\n");
+ printf(" TAPCOMPRESSION [yourTaps\\] (relative folder)\n");
+ printf(" TAPCOMPRESSION [c:\\data\\c64\\yourTaps\\] (absolute path)\n");
getchar();
return 0;
}
-// printf("WINDOW_SIZE=%d\n", WINDOW_SIZE);
-
-
- ////LZLikeDecodeToFile((folder + "180.zap").c_str());
- ////LZLikeDecodeToFile4((folder + "180.zap").c_str());
- //
- //LZLikeReset();
-
- //for (int i = 0; i < 1000; i++) {
- // ReadDecodeAmount(g_fat_buffer, 128);
- // fwrite(g_fat_buffer, 128, 1, fileWrite);
- //}
- //fclose(fileWrite);
-
- //fclose(fileRead);
- //return 0;
-
WIN32_FIND_DATAA ffd;
- printf("%s\n" , folder.c_str());
-
-// todo missing end will crash \\
+ printf("Packing all tap files found here: %s\n\n" , folder.c_str());
HANDLE hFind = FindFirstFileA((folder + "*.tap").c_str(), &ffd);
@@ -488,8 +113,6 @@ int main(int argc, char **argv)
return 0;
}
- int filesize = 0;
-
vector files;
do {
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
@@ -504,11 +127,12 @@ int main(int argc, char **argv)
int totalOriginal = 0;
int totalCompressed = 0;
-
+ int passed = 0;
for (vector::iterator it = files.begin(); it != files.end(); it++)
{
string fileName = *it;
- printf("PROCESSING: %s\n", fileName.c_str());
+ std::string inFilename = fileName.substr(fileName.find_last_of("/\\") + 1);
+ printf("%d) %s found, ", passed+1 , inFilename.c_str() );
FILE *f;
fopen_s(&f, fileName.c_str(), "rb");
@@ -521,13 +145,15 @@ int main(int argc, char **argv)
fclose(f);
u8 *out = (u8*)malloc(2 * size); // worst case
u8 *eout = LZLikeEncode(out, data, data + size);
- printf("Compressed from %d to %d bytes...", (int)size, (int)(eout - out));
+ printf("packed %d -> %d bytes, ", (int)size, (int)(eout - out));
totalOriginal += size;
- totalCompressed += (eout - out);
+ totalCompressed += (int)(eout - out);
//----------
string newfilename = fileName.substr(0, fileName.find_last_of('.')) + ".zap";
+ std::string base_filename = newfilename.substr(newfilename.find_last_of("/\\") + 1);
+ printf("%s saved, ", base_filename.c_str());
// if (remove(newfilename.c_str())==-1)
@@ -553,164 +179,20 @@ int main(int argc, char **argv)
return 1;
}
else {
- printf("verify OK\n");
+ passed++;
+ printf("verify Passed\n");
}
free(data);
-
free(dest);
}
}
- printf("=========================\n");
- printf("Original Total : %d\n", totalOriginal);
- printf("Compression Total: %d\n", totalCompressed);
- printf("saving %d bytes, %dKB, %dMB \n", totalOriginal - totalCompressed, (totalOriginal - totalCompressed)/1024, (totalOriginal - totalCompressed)/1024/1024);
- printf("=========================\n");
- getchar();
+ printf("\nStats:\n%d bytes total for original taps\n", totalOriginal);
+ printf("%d bytes total for compressed\n", totalCompressed);
+ printf("saving %d bytes, %dKB, %dMB (%d files)\n", totalOriginal - totalCompressed, (totalOriginal - totalCompressed)/1024, (totalOriginal - totalCompressed)/1024/1024,passed);
-
-}
-
-int main2(int argc, char **argv)
-{
-
- printf(" BITS_INDEX:%d\n", BITS_INDEX);
- printf(" BITS_REPEAT: %d\n", BITS_REPEAT);
- printf(" WINDOW_SIZE: %d\n", WINDOW_SIZE);
- printf(" SHIFT: %d\n", SHIFT);
- printf(" REPEAT_LIMIT: %d\n", REPEAT_LIMIT);
- printf(" REPEAT_MASK: %02x\n", REPEAT_MASK);
-
- if (argc != 3)
- {
- printf("Usage: c64convert source.tap dest.tpz\n");
- return 1;
- }
- FILE *f;
- fopen_s(&f, argv[1], "rb");
- if (f)
- {
- fseek(f, 0, SEEK_END);
- long size = ftell(f);
- printf("Loaded %s (%d bytes)\n", argv[1], (int)size);
- fseek(f, 0, SEEK_SET);
- u8 *data = (u8*)malloc(size);
- fread(data, 1, size, f);
- fclose(f);
- printf("Read done\n");
- u8 *out = (u8*)malloc(2 * size); // worst case
- u8 *eout = LZLikeEncode(out, data, data + size);
- printf("Compressed:%d/%d\n", (int)(eout - out), (int)size);
- FILE *g;
- fopen_s(&g, argv[2], "wb");
- if (g)
- {
- fwrite(out, 1, eout - out, g);
- fclose(g);
- }
- else
- {
- printf("Couldn't open '%s' for write\n", argv[2]);
- return 1;
- }
- u8 *dest = (u8*)malloc(size);
- u8 *edest = LZLikeDecode(dest, out, eout);
-
-
- // LZLikeDecodeToFile("_180.tap", out, eout);
-
-
- if (memcmp(dest, data, size) != 0)
- {
- printf("Decompress error %d/%d\n", (int)(edest - dest), (int)size);
- return 1;
- }
- }
- else
- {
- printf("Couldn't open '%s' for read\n", argv[1]);
- return 1;
- }
- return 0;
+
+// getchar();
}
-
-
-//u8* LZLikeEncode(u8 *out, u8 *in, u8 *end) {
-// int inDataSize = (int)(end - in);
-// int currentBlockStart = 0;
-// while (currentBlockStart < inDataSize) {
-// int byteOrDistance = in[currentBlockStart];
-// int repetitionLength = 1;
-// for (int wi = 0; wi < WINDOW_SIZE; wi++) {
-// u8* psearchIndex = &in[currentBlockStart];
-// if (psearchIndex > in + wi) {
-// int len = 0;
-// while (*psearchIndex == *(psearchIndex - 1 - wi) && len < 64 && psearchIndex < end) {
-// len++;
-// psearchIndex++;
-// }
-// if (len > repetitionLength) {
-// repetitionLength = len; // found more repetition in the past
-// byteOrDistance = wi; // how far did we look back in bytes
-// }
-// }
-// }
-//
-// int v = (repetitionLength - 1) | ((byteOrDistance >> 8) << 6);
-// *(out++) = v;
-// *(out++) = byteOrDistance;
-// currentBlockStart += repetitionLength;
-// }
-// return out;
-//}
-
-//
-//
-//
-//u8* LZLikeEncode(u8 *out, u8 *in, u8 *end) {
-// int inDataSize = (int)(end - in);
-// int currentBlockStart = 0;
-// while (currentBlockStart < inDataSize) {
-// int byteOrDistance = in[currentBlockStart];
-// int repetitionLength = 1;
-// for (int wi = 0; wi < WINDOW_SIZE; wi++) {
-// int searchIndex = currentBlockStart;
-//
-//
-// if (searchIndex - 1 - wi >= 0) {
-// int len = 0;
-// while (in[searchIndex] == in[searchIndex - 1 - wi] && len < 64 && searchIndex < inDataSize) {
-// len++;
-// searchIndex++;
-// }
-// if (len > repetitionLength) {
-// repetitionLength = len; // found more repetition in the past
-// byteOrDistance = wi; // how far did we look back in bytes
-// }
-// }
-// }
-//
-// int v = (repetitionLength - 1) | ((byteOrDistance >> 8) << 6);
-// *(out++) = v;
-// *(out++) = byteOrDistance;
-// currentBlockStart += repetitionLength;
-// }
-// return out;
-//}
-//
-//void printBits(size_t const size, void const * const ptr)
-//{
-// unsigned char *b = (unsigned char*)ptr;
-// unsigned char byte;
-// int i, j;
-//
-// for (i = size - 1; i >= 0; i--) {
-// for (j = 7; j >= 0; j--) {
-// byte = (b[i] >> j) & 1;
-// printf("%u", byte);
-// }
-// }
-// puts("");
-//}
\ No newline at end of file