diff options
Diffstat (limited to 'src/p_maputl.c')
-rw-r--r-- | src/p_maputl.c | 146 |
1 files changed, 81 insertions, 65 deletions
diff --git a/src/p_maputl.c b/src/p_maputl.c index babe7f28..4ab5d1d5 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -745,100 +745,116 @@ extern fixed_t bulletslope; typedef struct { - int len; - int *adr; + int len; + void *addr; + boolean int16_array; } intercepts_overrun_t; // Intercepts memory table. This is where various variables are located // in memory in Vanilla Doom. When the intercepts table overflows, we // need to write to them. // -// These are treated as ints when writing, which is okay in most cases, -// as most of them are ints. However, there is one potential -// cross-platform issue when overwriting the playerstarts[] array, as -// this contains 16-bit integers, and these fields may get the wrong -// values. +// Almost all of the values to overwrite are 32-bit integers, except for +// playerstarts, which is effectively an array of 16-bit integers and +// must be treated differently. static intercepts_overrun_t intercepts_overrun[] = { - {4, NULL}, - {4, NULL}, //&earlyout}, - {4, NULL}, //&intercept_p}, - {4, &lowfloor}, - {4, &openbottom}, - {4, &opentop}, - {4, &openrange}, - {4, NULL}, - {120, NULL}, //&activeplats}, - {8, NULL}, - {4, &bulletslope}, - {4, NULL}, //&swingx}, - {4, NULL}, //&swingy}, - {4, NULL}, - {40, (int*)&playerstarts}, - {4, NULL}, //&blocklinks}, - {4, &bmapwidth}, - {4, NULL}, //&blockmap}, - {4, &bmaporgx}, - {4, &bmaporgy}, - {4, NULL}, //&blockmaplump}, - {4, &bmapheight}, - {0, NULL} + {4, NULL, false}, + {4, NULL, /* &earlyout, */ false}, + {4, NULL, /* &intercept_p, */ false}, + {4, &lowfloor, false}, + {4, &openbottom, false}, + {4, &opentop, false}, + {4, &openrange, false}, + {4, NULL, false}, + {120, NULL, /* &activeplats, */ false}, + {8, NULL, false}, + {4, &bulletslope, false}, + {4, NULL, /* &swingx, */ false}, + {4, NULL, /* &swingy, */ false}, + {4, NULL, false}, + {40, &playerstarts, true}, + {4, NULL, /* &blocklinks, */ false}, + {4, &bmapwidth, false}, + {4, NULL, /* &blockmap, */ false}, + {4, &bmaporgx, false}, + {4, &bmaporgy, false}, + {4, NULL, /* &blockmaplump, */ false}, + {4, &bmapheight, false}, + {0, NULL, false}, }; // Overwrite a specific memory location with a value. static void InterceptsMemoryOverrun(int location, int value) { - int i, offset; + int i, offset; + int index; + void *addr; - i = 0; - offset = 0; + i = 0; + offset = 0; - // Search down the array until we find the right entry + // Search down the array until we find the right entry - while (intercepts_overrun[i].len != 0) - { - if (offset + intercepts_overrun[i].len > location) - { - if (intercepts_overrun[i].adr != NULL) - { - intercepts_overrun[i].adr[(location - offset) / 4] - = value; - } - break; - } - - offset += intercepts_overrun[i].len; - ++i; - } + while (intercepts_overrun[i].len != 0) + { + if (offset + intercepts_overrun[i].len > location) + { + addr = intercepts_overrun[i].addr; + + // Write the value to the memory location. + // 16-bit and 32-bit values are written differently. + + if (addr != NULL) + { + if (intercepts_overrun[i].int16_array) + { + index = (location - offset) / 2; + ((short *) addr)[index] = value & 0xffff; + ((short *) addr)[index + 1] = (value >> 16) & 0xffff; + } + else + { + index = (location - offset) / 4; + ((int *) addr)[index] = value; + } + } + + break; + } + + offset += intercepts_overrun[i].len; + ++i; + } } // Emulate overruns of the intercepts[] array. static void InterceptsOverrun(int num_intercepts, intercept_t *intercept) { - int location; + int location; - if (num_intercepts <= MAXINTERCEPTS_ORIGINAL) - { - // No overrun + if (num_intercepts <= MAXINTERCEPTS_ORIGINAL) + { + // No overrun - return; - } + return; + } - location = (num_intercepts - MAXINTERCEPTS_ORIGINAL - 1) * 12; + location = (num_intercepts - MAXINTERCEPTS_ORIGINAL - 1) * 12; - // Overwrite memory that is overwritten in Vanilla Doom, using - // the values from the intercept structure. - // - // Note: the ->d.{thing,line} member should really have its - // address translated into the correct address value for - // Vanilla Doom. + // Overwrite memory that is overwritten in Vanilla Doom, using + // the values from the intercept structure. + // + // Note: the ->d.{thing,line} member should really have its + // address translated into the correct address value for + // Vanilla Doom. - InterceptsMemoryOverrun(location, intercept->frac); - InterceptsMemoryOverrun(location + 4, intercept->isaline); - InterceptsMemoryOverrun(location + 8, (int) intercept->d.thing); + InterceptsMemoryOverrun(location, intercept->frac); + InterceptsMemoryOverrun(location + 4, intercept->isaline); + InterceptsMemoryOverrun(location + 8, (int) intercept->d.thing); } |