From 9d6fd32206503e8250520a3989612e6a0101735a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Nov 2010 09:02:56 +0900 Subject: [PATCH] Ensure the the progs data is aligned. Some QuakeC compilers (eg, FTE) insert a data chunk between the progs header and the rest of the progs data. Unfortunately, FTE does not maintain the assumed 32-bit alignment. --- libs/gamecode/engine/pr_load.c | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/libs/gamecode/engine/pr_load.c b/libs/gamecode/engine/pr_load.c index d7b2d76ae..34e57e51a 100644 --- a/libs/gamecode/engine/pr_load.c +++ b/libs/gamecode/engine/pr_load.c @@ -100,11 +100,13 @@ free_progs_mem (progs_t *pr, void *mem) } VISIBLE void -PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone) +PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int edicts, int zone) { size_t i; int mem_size; + int offset_tweak; dprograms_t progs; + byte *base; if (!pr->file_error) pr->file_error = file_error; @@ -152,8 +154,13 @@ PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone) } } + // Some compilers (eg, FTE) put extra data between the header and the + // strings section. What's worse, they de-align the data. + offset_tweak = progs.ofs_strings % sizeof (pr_int_t); + offset_tweak = (sizeof (pr_int_t) - offset_tweak) % sizeof (pr_int_t); + // size of progs themselves - pr->progs_size = size; + pr->progs_size = size + offset_tweak; Sys_DPrintf ("Programs occupy %iK.\n", size / 1024); // round off to next highest whole word address (esp for Alpha) // this ensures that pointers in the engine data area are always @@ -187,9 +194,10 @@ PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone) ((byte *) pr->progs)[mem_size] = 0; memcpy (pr->progs, &progs, sizeof (progs)); - Qread (file, pr->progs + 1, size - sizeof (progs)); - CRC_ProcessBlock ((byte *)(pr->progs + 1), &pr->crc, - size - sizeof (progs)); + base = (byte *) (pr->progs + 1) + offset_tweak; + Qread (file, base, size - sizeof (progs)); + CRC_ProcessBlock (base, &pr->crc, size - sizeof (progs)); + base -= sizeof (progs); // offsets are from file start if (pr->edicts) *pr->edicts = (edict_t *)((byte *) pr->progs + pr->progs_size); @@ -199,18 +207,14 @@ PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone) PR_Zone_Init (pr); pr->pr_functions = - (dfunction_t *) ((byte *) pr->progs + pr->progs->ofs_functions); - pr->pr_strings = (char *) pr->progs + pr->progs->ofs_strings; - pr->pr_stringsize = (char *) pr->zone + pr->zone_size - (char *) pr->progs; - pr->pr_globaldefs = - (ddef_t *) ((byte *) pr->progs + pr->progs->ofs_globaldefs); - pr->pr_fielddefs = - (ddef_t *) ((byte *) pr->progs + pr->progs->ofs_fielddefs); - pr->pr_statements = - (dstatement_t *) ((byte *) pr->progs + pr->progs->ofs_statements); + (dfunction_t *) (base + pr->progs->ofs_functions); + pr->pr_strings = (char *) base + pr->progs->ofs_strings; + pr->pr_stringsize = (char *) pr->zone + pr->zone_size - (char *) base; + pr->pr_globaldefs = (ddef_t *) (base + pr->progs->ofs_globaldefs); + pr->pr_fielddefs = (ddef_t *) (base + pr->progs->ofs_fielddefs); + pr->pr_statements = (dstatement_t *) (base + pr->progs->ofs_statements); - pr->pr_globals = - (pr_type_t *) ((byte *) pr->progs + pr->progs->ofs_globals); + pr->pr_globals = (pr_type_t *) (base + pr->progs->ofs_globals); pr->globals_size = (pr_type_t*)((byte *) pr->zone + pr->zone_size) - pr->pr_globals;