summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohannes <johannes.herman@gmail.com>2024-02-07 19:48:13 +0100
committerjohannes <johannes.herman@gmail.com>2024-02-07 19:48:13 +0100
commite266d45b055a61f51066c469733ce17d3ee524eb (patch)
tree44619dc72cb8228d199f258e68c1508d8ce81647
parenta883cabd1df1f440a027d1f936bbebe5a71dba36 (diff)
added write snap, fixed some bugs
-rw-r--r--inc/demo.h2
-rw-r--r--src/demo.c81
-rw-r--r--src/main.c13
-rw-r--r--src/pack.c41
4 files changed, 122 insertions, 15 deletions
diff --git a/inc/demo.h b/inc/demo.h
index 8b99477..2ee9420 100644
--- a/inc/demo.h
+++ b/inc/demo.h
@@ -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
diff --git a/src/demo.c b/src/demo.c
index a9879c0..b2c44fd 100644
--- a/src/demo.c
+++ b/src/demo.c
@@ -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;
}
diff --git a/src/main.c b/src/main.c
index 0c71919..5408903 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}
}
diff --git a/src/pack.c b/src/pack.c
index 0d23ca7..bc6c604 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -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)++;
}