From 8049252f651bb31f6965303c7f141980b0aa5c6b Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Tue, 24 Apr 2012 08:19:48 -0400 Subject: [PATCH] new progs format proposal for engine developers (45% of globals are 0, why write them, let the engine populate them. We can essentially save 9884 bytes in xonotic's progs.dat with this new format.) --- code.c | 20 +++++++++++++++++--- gmqcc.h | 1 + main.c | 12 +++++++++--- propsal.txt | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 propsal.txt diff --git a/code.c b/code.c index 66dc951..3925088 100644 --- a/code.c +++ b/code.c @@ -28,8 +28,11 @@ typedef struct { } prog_section; typedef struct { - uint32_t version; /* Program version (6) */ - uint32_t crc16; /* What is this? */ + uint16_t version; /* Program version (6) */ + uint16_t flags; /* see propsal.txt */ + uint16_t crc16; /* What is this? */ + uint16_t skip; /* see propsal.txt */ + prog_section statements; /* prog_section_statement */ prog_section defs; /* prog_section_def */ prog_section fields; /* prog_section_field */ @@ -90,6 +93,10 @@ int code_strings_add(const char *src) { } void code_init() { + /* omit creation of null code */ + if (opts_omit_nullcode) + return; + /* * The way progs.dat is suppose to work is odd, there needs to be * some null (empty) statements, functions, and 28 globals @@ -137,6 +144,13 @@ void code_test() { void code_write() { prog_header code_header={0}; + + /* see proposal.txt */ + if (opts_omit_nullcode) { + code_header.skip = 28; + code_header.flags = 1; + } + code_header.version = 6; code_header.crc16 = 0; /* TODO: */ code_header.statements = (prog_section){sizeof(prog_header), code_statements_elements }; @@ -150,7 +164,7 @@ void code_write() { if (opts_darkplaces_stringtablebug) { util_debug("GEN", "Patching stringtable for -fdarkplaces-stringtablebug\n"); - /* >= + padd */ + /* >= + P */ code_chars_add('\0'); /* > */ code_chars_add('\0'); /* = */ code_chars_add('\0'); /* P */ diff --git a/gmqcc.h b/gmqcc.h index f27f41e..5edaeae 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -485,4 +485,5 @@ enum { extern int opts_debug; extern int opts_memchk; extern int opts_darkplaces_stringtablebug; +extern int opts_omit_nullcode; #endif diff --git a/main.c b/main.c index 2c0be85..e24a7fe 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,7 @@ int opts_debug = 0; int opts_memchk = 0; int opts_compiler = COMPILER_GMQCC; int opts_darkplaces_stringtablebug = 0; +int opts_omit_nullcode = 0; static const int usage(const char *const app) { printf("usage:\n"); @@ -48,8 +49,9 @@ static const int usage(const char *const app) { printf(" -std=ftqecc -- fteqcc QuakeC\n"); printf(" -std=qccx -- qccx QuakeC\n"); printf(" -std=gmqcc -- this compiler QuakeC (default selection)\n"); - printf(" code flags -f*\n"); - printf(" -fdarkplaces-stringtablebug -- patches the string table to work with bugged versions of darkplaces\n"); + printf(" codegen flags:\n"); + printf(" -fdarkplaces-string-table-bug -- patches the string table to work with bugged versions of darkplaces\n"); + printf(" -fomit-nullcode -- omits the generation of null code (will break everywhere see propsal.txt)\n"); return -1; } @@ -92,10 +94,14 @@ int main(int argc, char **argv) { } /* code specific switches */ - if (!strncmp(&argv[1][1], "fdarkplaces-stringtablebug", 26)) { + if (!strcmp(&argv[1][1], "fdarkplaces-string-table-bug")) { opts_darkplaces_stringtablebug = 1; break; } + if (!strcmp(&argv[1][1], "fomit-nullcode")) { + opts_omit_nullcode = 1; + break; + } return usage(app); } diff --git a/propsal.txt b/propsal.txt new file mode 100644 index 0000000..88658e1 --- /dev/null +++ b/propsal.txt @@ -0,0 +1,35 @@ +This is a propsal to extend the progs.dat file format without breaking +backwards compatability. Currently the progs file format header has a +description simaler to this: + +struct { + uint32_t version; + uint32_t crc16; + .... + uint32_t entfield; +} + +The obvious notable issue here is version and crc16 are larger than they +essentially need to be, if we made version and crc16 both uint16_t we can +give ourselfs 32 bytes (2x16) to store additional data that can be used +to make smaller progs.dat files. + +I propose a new structual layout like this: +struct { + uint16_t version; + uint16_t flags; /* contains a skip field */ + uint16_t crc16; + uint16_t skip; /* skiped globals */ + .... + uint32_t entfield; +} + +about 45% of globals are zero, if we could order them at the top of the +globals array we can essentially use the skip field to specify how much +zero globals the engine would have to populate (instead of being stored +in the actual file itself) flags can specify if the progs.dat file skiped +globals on the write of the progs.dat file. + +Of course only one bit in the flags would have to be set to specify if the +file contains a skip field. Which lends itself to the fact that flags could +later be extended for other things. -- 2.39.2