diff options
| -rw-r--r-- | inc/demo.h | 2 | ||||
| -rw-r--r-- | src/demo.c | 81 | ||||
| -rw-r--r-- | src/main.c | 13 | ||||
| -rw-r--r-- | src/pack.c | 41 |
4 files changed, 122 insertions, 15 deletions
@@ -119,6 +119,8 @@ int readdemochunks(FILE *fp, demodata *dd, unsigned char ver); int writedemoheader(FILE *outfile, demoheader *header); int writedemotimeline(FILE *outfile, demotimeline *timeline); int writedemomap(FILE *outfile, demomap *map, int mapsize, unsigned char version); + int writedemotick(FILE *outfile, demotick *tick, unsigned char version); +int writedemosnap(FILE *outfile, demosnap *snap, unsigned char version); #endif // DEMO_H @@ -133,9 +133,17 @@ int readdemosnap(FILE *fp, demosnap *snap, int size) char data[size]; char unpacked[1024 * 8]; - fread(data, sizeof(unsigned char), size, fp); + fread(data, 1, size, fp); - if (decompresshuff((char *)data, size, (char *)unpacked, 1034 * 8) < 0) + int ret = decompresshuff((char *)data, size, (char *)unpacked, 1034 * 8); + /* + printf("READ={compressed size = %d, ret: %d, data: [ ", size, ret); + for (int i = 0; i < ret; i++) + printf("%x ", unpacked[i] & 0xff); + printf("]}\n"); + */ + + if (ret < 0) { printf("[ ERROR ] error while decompressing snap cunk!\n"); return 0; @@ -147,7 +155,7 @@ int readdemosnap(FILE *fp, demosnap *snap, int size) snap->numitems = readint(&cp); snap->offsets = (int *)malloc(snap->numitems * sizeof(int)); - snap->items = (demosnapitem *)malloc(snap->numitems * sizeof(int)); + snap->items = (demosnapitem *)malloc(snap->numitems * sizeof(demosnapitem)); for (int i = 0; i < snap->numitems; i++) snap->offsets[i] = readint(&cp); @@ -155,6 +163,7 @@ int readdemosnap(FILE *fp, demosnap *snap, int size) for (int i = 0; i < snap->numitems; i++) { unsigned int item_key = (unsigned int)readint(&cp); + // printf("READKEY: %u\n", item_key); snap->items[i].type = (item_key >> 16) & 0xffff; snap->items[i].id = (item_key & 0xffff); @@ -254,7 +263,7 @@ int readdemochunk(FILE *fp, demochunk *chunk, unsigned char ver) { printf("(type: %d, id: %d) { ", snap->items[i].type, snap->items[i].id); for (int y = 0; y < snap->items[i].numdata; y++) - printf("%d, ", snap->items[i].data[y]); + printf("%i, ", snap->items[i].data[y]); printf("} "); } printf("], "); @@ -373,6 +382,36 @@ int writedemomap(FILE *fp, demomap *dm, int mapsize, unsigned char ver) return 1; } +/* lifted from + * https://github.com/ddnet/ddnet/blob/79df5893ff26fa75d67e46f99e58f75b739ac362/src/engine/shared/demo.cpp#L270 */ +int writedemochunkheader(FILE *fp, demochunktype type, int size) +{ + unsigned char header[3]; + header[0] = (((int)type) & 0x3) << 5; + if (size < 30) + { + header[0] |= size; + fputc(*header, fp); + } + else + { + if (size < 256) + { + header[0] |= 30; + header[1] = size & 0xff; + fwrite(header, 1, 2, fp); + } + else + { + header[0] |= 31; + header[1] = size & 0xff; + header[2] = size >> 8; + fwrite(header, 1, 3, fp); + } + } + return -1; +} + // TODO add erro checking int writedemotick(FILE *fp, demotick *tick, unsigned char ver) { @@ -384,22 +423,48 @@ int writedemotick(FILE *fp, demotick *tick, unsigned char ver) if (tick->innline) { header |= tick->delta; - fwrite(&header, 1, 1, fp); + fputc(header, fp); } else { - fwrite(&header, 1, 1, fp); + fputc(header, fp); unsigned char intbuf[4]; tobigendian(tick->delta, intbuf); fwrite(intbuf, 4, 1, fp); } - // printf("%2X\n", header); return 1; } int writedemosnap(FILE *fp, demosnap *snap, unsigned char ver) { - + char compressed[64 * 1024]; + char decompressed[64 * 1024]; + + char *cp = decompressed; + + writeint(snap->datasize, &cp); + writeint(snap->numitems, &cp); + + for (int i = 0; i < snap->numitems; i++) + writeint(snap->offsets[i], &cp); + + for (int i = 0; i < snap->numitems; i++) + { + unsigned int key = (snap->items[i].type << 16) | snap->items[i].id; + // printf("WRITEKEY: %u\n", key); + writeint((int)key, &cp); + + for (int y = 0; y < snap->items[i].numdata; y++) + writeint(snap->items[i].data[y], &cp); + } + int size = cp - decompressed; + + int datasize = compresshuff(decompressed, size, compressed, 64 * 1024); + datasize = ((datasize + 3) / 4) * 4; + + writedemochunkheader(fp, DEMOSNAP, datasize); + fwrite(compressed, 1, datasize, fp); + return 1; } @@ -112,8 +112,12 @@ int testdecompress(char *line) void dumbtestpacker() { + char b[] = {0xe0, 0xce, 0xf0, 0xaf, 0x09, 0xb7}; + char *c = b; + printf("test: %d\n", readint(&c)); + char buf[16] = {0}; - int in = 550; + int in = 196618; int in2 = 8763289; printf("input: %d\n", in); @@ -140,6 +144,9 @@ void dumbtestpacker() int main() { + dumbtestpacker(); + // exit(0); + inithuff(NULL); FILE *fp = fopen("data/test.demo", "r"); @@ -165,6 +172,10 @@ int main() if (dd.chunks[i].type == DEMOTICK) { writedemotick(op, dd.chunks[i].data.tick, dh.version); + } + else if (dd.chunks[i].type == DEMOSNAP) + { + writedemosnap(op, dd.chunks[i].data.snap, dh.version); exit(0); } } @@ -19,11 +19,11 @@ int readint(char **cp) int len = 1; unsigned char src = **cp; - (*cp)++; - int sign = (src >> 6) & 1; + int sign = ((src >> 6) & 1); result |= (src & 0b00111111); + for (int i = 0; i < 4; i++) { // printf("(%d, ", src); @@ -32,6 +32,7 @@ int readint(char **cp) src = **cp; (*cp)++; + len++; if (i == 3 && (src & 0b11110000) != 0) @@ -47,9 +48,37 @@ int readint(char **cp) return result; } -void writeint(int in, char **cp) +/* +int readint(char **src) +{ + printf("starting read: %x, ", **src & 0xff); + const int sign = (**src >> 6) & 1; + + int out = **src & 0x3f; + + const static int masks[] = {0x7F, 0x7F, 0x7F, 0x0F}; + const static int shifts[] = {6, 6 + 7, 6 + 7 + 7, 6 + 7 + 7 + 7}; + + for (unsigned int i = 0; i < sizeof(masks); i++) + { + if (!(**src & 0x80)) + break; + (*src)++; + printf("%x, ", **src & 0xff); + out |= (**src & masks[i]) << shifts[i]; + } + (*src)++; + out ^= -sign; + printf(" result: %d\n", out); + return out; +} +*/ + +void writeint(int i, char **cp) { - int sign = in < 0; + // printf("printing int: %d\n", i); + int sign = i < 0; + unsigned int in = i; in = (in ^ -sign); char next = (in & 0b00111111); in >>= 6; @@ -60,7 +89,7 @@ void writeint(int in, char **cp) if (sign != 0) head |= 0b01000000; - printf("writing: %2X\n", head | next); + // printf("printing: %x\n", (head | next) & 0xff); **cp = head | next; (*cp)++; @@ -74,7 +103,7 @@ void writeint(int in, char **cp) else head = 0; - printf("writing: %2X\n", head | next); + // printf("printing: %x\n", (head | next) & 0xff); **cp = head | next; (*cp)++; } |
