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.)

This commit is contained in:
Dale Weiler 2012-04-24 08:19:48 -04:00
parent cda5076356
commit 8049252f65
4 changed files with 62 additions and 6 deletions

20
code.c
View file

@ -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 */

View file

@ -485,4 +485,5 @@ enum {
extern int opts_debug;
extern int opts_memchk;
extern int opts_darkplaces_stringtablebug;
extern int opts_omit_nullcode;
#endif

12
main.c
View file

@ -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);
}

35
propsal.txt Normal file
View file

@ -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.