init files
This commit is contained in:
commit
8197a022bd
1409 changed files with 139317 additions and 0 deletions
209
loader/tools/wcrush/wca/main.cpp
Normal file
209
loader/tools/wcrush/wca/main.cpp
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
// this pretty much does the same as the taboo depacker on the C64-end
|
||||
// (aka decrush.tas), except it doesn't run on a C64 but a PC and it's
|
||||
// sole purpose is to walk through a raw crushed binary and tell you
|
||||
// how the depacker would interprete the information stored in it.
|
||||
// or in other words, it's just a debugging aid for the levelcrusher I wrote.
|
||||
|
||||
// latest changes: added some sanity checks to keep operations within buffer limits (hopefully)
|
||||
|
||||
// Note: does currently only support files crushed with max compression ("speed"=6)
|
||||
|
||||
// #include <SDKDDKVer.h> //VS 2013 stuff, remove or change to whatever your dev-tools require
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define maxsize 0xffff
|
||||
|
||||
const uint8_t packbits[56] = {
|
||||
2, 2, 1, 1, 2, 2, 1, 1, // worst compression (speed 0)
|
||||
3, 1, 2, 2, 3, 1, 2, 2,
|
||||
3, 2, 2, 2, 3, 2, 2, 2,
|
||||
4, 2, 2, 2, 4, 2, 2, 2,
|
||||
4, 2, 2, 3, 4, 2, 2, 2,
|
||||
4, 2, 3, 3, 4, 2, 2, 2,
|
||||
4, 3, 3, 3, 4, 2, 2, 2 }; // best compression (speed 6)
|
||||
|
||||
uint8_t inbuf[maxsize+1];
|
||||
uint8_t outbuf[maxsize+1]; // dummy output, only there to be able to show repeat byte sequences
|
||||
|
||||
uint32_t srcidx, tgtidx, refidx, offset, ctrlbyte;
|
||||
int32_t chunkofs, len, chunks, chunkwidth, bitnum, columns;
|
||||
uint64_t fsize; // just in case someone stupid (aka me) tries to run a TB-sized file through the analyzer
|
||||
int speed = 6;
|
||||
|
||||
// show the data bytes currently handled by depacker in somewhat formatted fashion:
|
||||
|
||||
void movedata(uint8_t buffer1[], uint8_t buffer2[], uint32_t& idx1, uint32_t& idx2, int32_t len)
|
||||
{
|
||||
columns = 16;
|
||||
printf("%04x: ", idx2);
|
||||
while (0 < len--) // to filter out negative lens as well, just in case...
|
||||
{
|
||||
printf(" %02x", buffer1[idx1]);
|
||||
buffer2[idx2++] = buffer1[idx1++];
|
||||
if (--columns == 8)
|
||||
printf(" ");
|
||||
if (!columns)
|
||||
{
|
||||
printf("\n");
|
||||
if (len)
|
||||
printf("%04x: ", idx2);
|
||||
columns = 16;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if (columns != 16)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
// extract control bit from input buffer, return 1 if set, else 0.
|
||||
// also show value [and address] of current control byte
|
||||
|
||||
uint16_t getbit()
|
||||
{
|
||||
if (--bitnum <0)
|
||||
{
|
||||
ctrlbyte = inbuf[srcidx];
|
||||
bitnum = 7;
|
||||
printf("(%04X:%02X)", srcidx,ctrlbyte);
|
||||
if (srcidx < fsize) // sanity check
|
||||
srcidx++;
|
||||
}
|
||||
return (ctrlbyte &(1<<bitnum))>>bitnum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("\ncrushfile analyzer v0.1b by manic mailman\n\n");
|
||||
|
||||
// some help for the end user if input parameter is missing:
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("usage: wca <raw crushed binary> [speed 0..6]\n");
|
||||
printf("example: wca crushed 6 > log.txt\n");
|
||||
printf("if no speed is given speed 6 is assumed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if filename is provided try to open file, if possible:
|
||||
|
||||
printf("trying to analyze %s...\n\n", argv[1]);
|
||||
FILE * infile;
|
||||
infile = fopen(argv[1], "rb");
|
||||
if (infile == NULL)
|
||||
{
|
||||
printf("can't open file!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fseek(infile, 0, SEEK_END);
|
||||
fsize = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
// more error msgs if file is too large or too short to be a valid crushed binary
|
||||
|
||||
if (fsize > maxsize) // if file too large
|
||||
{
|
||||
printf("file too large!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fsize < 4)
|
||||
{
|
||||
printf("nothing to analyze!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argv[2] != NULL)
|
||||
speed = atoi(argv[2]);
|
||||
speed = speed * 8;
|
||||
|
||||
// could be valid, so here we go:
|
||||
|
||||
ssize_t bytes_read = fread(inbuf, 1, fsize&maxsize, infile);
|
||||
(void) bytes_read;
|
||||
fclose(infile);
|
||||
tgtidx = inbuf[0] + 0x100 * inbuf[1];
|
||||
printf("start address: %d/%04X, size: %d bytes.\n\n", tgtidx, tgtidx, (int) fsize);
|
||||
srcidx = 2; // skip start address
|
||||
bitnum = 0; // to read 1st control byte right away
|
||||
|
||||
do {
|
||||
|
||||
//if end of either input data or output buffer reached before reading endmark:
|
||||
|
||||
if (srcidx >= fsize || tgtidx >= maxsize)
|
||||
{
|
||||
printf("no valid endmark found, aborting.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// copy uncompressed bytes if control bit == 0, else repeat bytes:
|
||||
|
||||
if (!getbit())
|
||||
{
|
||||
len = 1;
|
||||
while (!getbit() && len < maxsize) // get length of run from stopbit,bit... sequence
|
||||
len = len * 2 + getbit();
|
||||
printf(" COPY %04X uncompressed bytes from %04X to %04X\n", len, srcidx, tgtidx);
|
||||
|
||||
if (tgtidx + len > maxsize) // sanity check
|
||||
len = maxsize - tgtidx;
|
||||
if (srcidx + len > fsize) // sanity check
|
||||
len = fsize&maxsize - srcidx;
|
||||
|
||||
movedata(inbuf, outbuf, srcidx, tgtidx, len);
|
||||
}
|
||||
|
||||
// repeat a sequence of bytes that has already been decompressed:
|
||||
|
||||
len = 1;
|
||||
if (getbit()) // 3+ byte sequence
|
||||
{
|
||||
chunkofs = speed;
|
||||
while (!getbit() && len < 0x100) // get len from stopbit,bit...sequence
|
||||
len = len * 2 + getbit();
|
||||
len += 2;
|
||||
}
|
||||
else // 2+ byte sequence
|
||||
{
|
||||
chunkofs = speed + 4;
|
||||
len++;
|
||||
}
|
||||
|
||||
// if reference length is valid repeat 2 or more bytes:
|
||||
|
||||
if (len < 0x100)
|
||||
{
|
||||
offset = 0;
|
||||
chunks = 2 * getbit() + getbit(); // get # of bitchunks (2 bits)
|
||||
do {
|
||||
chunkwidth = packbits[chunkofs + chunks]; // bitwidth of current chunk
|
||||
while (chunkwidth--)
|
||||
offset = 2 * offset + getbit(); //shift in offset bits of current chunk
|
||||
if (chunks) // +1 if more bitchunks remaining
|
||||
offset++;
|
||||
} while (chunks--);
|
||||
refidx = tgtidx - (offset + len);
|
||||
printf(" REPEAT %02X bytes from %04X at %04X (offset %d)\n", len, refidx, tgtidx, offset);
|
||||
|
||||
if (tgtidx + len > maxsize) // sanity check
|
||||
len = maxsize - tgtidx;
|
||||
movedata(outbuf, outbuf, refidx, tgtidx, len);
|
||||
}
|
||||
|
||||
// else depacker has reached end of input data (or crapped out somewhere before)
|
||||
|
||||
else
|
||||
{
|
||||
printf(" endmark found (%d/%04X)\n", len-2, len-2);
|
||||
if (srcidx < fsize)
|
||||
printf("warning: endmark is not at end of input data!\n");
|
||||
}
|
||||
|
||||
} while (len < 0x100);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue