#include #include #include #include #include #include #include "data.h" #include "bss.h" #include "game/setuputils.h" #include "game/texdecompress.h" #include "mod.h" #include "preprocess/common.h" u8 *preprocessAnimations(u8* data, u32 size, u32* outSize) { // set the anim table pointers as well extern u8 *_animationsTableRomStart; extern u8 *_animationsTableRomEnd; // the animation table is at the end of the segment u32 *animtbl = (void *)(data + size - 0x38a0); _animationsTableRomStart = (u8 *)animtbl; _animationsTableRomEnd = data + size; PD_SWAP_VAL(*animtbl); const u32 count = *animtbl++; struct animtableentry *anim = (struct animtableentry *)animtbl; for (u32 i = 0; i < count; ++i, ++anim) { PD_SWAP_VAL(anim->numframes); PD_SWAP_VAL(anim->bytesperframe); PD_SWAP_VAL(anim->headerlen); PD_SWAP_VAL(anim->data); // if an external replacement exists, replace the table entry and mark the offset if (modAnimationLoadDescriptor(i, anim) > 0) { anim->data = 0xffffffff; } } return NULL; } u8 *preprocessMpConfigs(u8* data, u32 size, u32* outSize) { const u32 count = size / sizeof(struct mpconfig); struct mpconfig *cfg = (struct mpconfig *)data; for (u32 i = 0; i < count; ++i, ++cfg) { PD_SWAP_VAL(cfg->setup.options); PD_SWAP_VAL(cfg->setup.teamscorelimit); PD_SWAP_VAL(cfg->setup.chrslots); #if MAX_PLAYERS > 4 // make space for the extra players cfg->setup.chrslots = (cfg->setup.chrslots & 0x000f) | ((cfg->setup.chrslots & 0x0ff0) << 4); #endif // TODO: are these required or are they always 0? PD_SWAP_VAL(cfg->setup.fileguid.deviceserial); PD_SWAP_VAL(cfg->setup.fileguid.fileid); // convert MPWEAPON_ to take classic weapons and JPN weapons into account for (s32 j = 0; j < ARRAYCOUNT(cfg->setup.weapons); ++j) { #if VERSION == VERSION_JPN_FINAL /* TODO: replace with runtime check */ if (cfg->setup.weapons[j] >= 0x24) { // weapons after and including the shield need to be shifted cfg->setup.weapons[j] += (MPWEAPON_SHIELD - MPWEAPON_PP9I); } if (cfg->setup.weapons[j] >= 0x19) { // weapons after the combat knife also need to be shifted up in JPN cfg->setup.weapons[j]++; } #else // in other versions we only care about the shield and above if (cfg->setup.weapons[j] >= 0x25) { cfg->setup.weapons[j] += (MPWEAPON_SHIELD - MPWEAPON_PP9I); } #endif } } return NULL; } u8 *preprocessTexturesList(u8* data, u32 size, u32* outSize) { struct texture *tex = (struct texture *)data; const u32 count = size / sizeof(*tex); for (u32 i = 0; i < count; ++i, ++tex) { // TODO: it sure looks like none of the fields except soundsurfacetype, surfacetype and dataoffset are set // just swap the last 3 bytes of the first word... const u32 dofs = (u32)tex->dataoffset << 8; tex->dataoffset = PD_BE32(dofs); // ...and the surface types in the first byte const u8 tmp = tex->soundsurfacetype; tex->soundsurfacetype = tex->surfacetype; tex->surfacetype = tmp; } return NULL; }