diff --git a/Makefile b/Makefile index c85e70f09..af796ac4b 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ PAL = 0 ROMALLOCATION_DATA = 0x015000 ROMALLOCATION_LIB = 0x038800 -ROMALLOCATION_GAME = 0x144ee0 +ROMALLOCATION_GAME = 0x100000 # ROM_SIZE - The desired ROM size in megabytes. # diff --git a/src/game/pad.c b/src/game/pad.c index 89bbf62fa..22b2de39c 100644 --- a/src/game/pad.c +++ b/src/game/pad.c @@ -6,7 +6,7 @@ #include "types.h" struct padsfileheader *g_PadsFile; -u16 *g_PadOffsets; +struct pad *g_Pads; u32 var800a2358; u32 var800a235c; u16 *g_CoverFlags; @@ -17,140 +17,12 @@ u16 *g_SpecialCoverNums; void padUnpack(s32 padnum, u32 fields, struct pad *pad) { - s32 offset; - u32 *header; - f32 *fbuffer; - u8 *ptr; - - if (pad); - - offset = g_PadOffsets[padnum]; - ptr = (u8 *) &g_StageSetup.padfiledata[offset]; - header = (u32 *) ptr; - - // Header format: - // flags, room and liftnum - // ffffffff ffffffff ffrrrrrr rrrrllll - - if (fields & PADFIELD_ROOM) { - pad->room = (s32)(*header << 18) >> 22; - } - - if (fields & PADFIELD_LIFT) { - pad->liftnum = *header & 0x0000000f; - } - - ptr += 4; - - if ((*header >> 14) & PADFLAG_INTPOS) { - if (fields & PADFIELD_POS) { - s16 *sbuffer = (s16 *) ptr; - pad->pos.x = sbuffer[0]; - pad->pos.y = sbuffer[1]; - pad->pos.z = sbuffer[2]; - } - ptr += 8; - } else { - if (fields & PADFIELD_POS) { - fbuffer = (f32 *) ptr; - pad->pos.x = fbuffer[0]; - pad->pos.y = fbuffer[1]; - pad->pos.z = fbuffer[2]; - } - ptr += 12; - } - - if ((*header >> 14) & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) { - if (fields & (PADFIELD_UP | PADFIELD_NORMAL)) { - if ((*header >> 14) & PADFLAG_UPALIGNTOX) { - pad->up.x = ((*header >> 14) & PADFLAG_UPALIGNINVERT) ? -1 : 1; - pad->up.y = 0; - pad->up.z = 0; - } else if ((*header >> 14) & PADFLAG_UPALIGNTOY) { - pad->up.x = 0; - pad->up.y = ((*header >> 14) & PADFLAG_UPALIGNINVERT) ? -1 : 1; - pad->up.z = 0; - } else { - pad->up.x = 0; - pad->up.y = 0; - pad->up.z = ((*header >> 14) & PADFLAG_UPALIGNINVERT) ? -1 : 1; - } - } - } else { - if (fields & (PADFIELD_UP | PADFIELD_NORMAL)) { - fbuffer = (f32 *) ptr; - pad->up.x = fbuffer[0]; - pad->up.y = fbuffer[1]; - pad->up.z = fbuffer[2]; - } - ptr += 12; - } - - if ((*header >> 14) & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) { - if (fields & (PADFIELD_LOOK | PADFIELD_NORMAL)) { - if ((*header >> 14) & PADFLAG_LOOKALIGNTOX) { - pad->look.x = ((*header >> 14) & PADFLAG_LOOKALIGNINVERT) ? -1 : 1; - pad->look.y = 0; - pad->look.z = 0; - } else if ((*header >> 14) & PADFLAG_LOOKALIGNTOY) { - pad->look.x = 0; - pad->look.y = ((*header >> 14) & PADFLAG_LOOKALIGNINVERT) ? -1 : 1; - pad->look.z = 0; - } else { - pad->look.x = 0; - pad->look.y = 0; - pad->look.z = ((*header >> 14) & PADFLAG_LOOKALIGNINVERT) ? -1 : 1; - } - } - } else { - if (fields & (PADFIELD_LOOK | PADFIELD_NORMAL)) { - fbuffer = (f32 *) ptr; - pad->look.x = fbuffer[0]; - pad->look.y = fbuffer[1]; - pad->look.z = fbuffer[2]; - } - ptr += 12; - } - - if (fields & PADFIELD_NORMAL) { - pad->normal.x = pad->up.y * pad->look.z - pad->look.y * pad->up.z; - pad->normal.y = pad->up.z * pad->look.x - pad->look.z * pad->up.x; - pad->normal.z = pad->up.x * pad->look.y - pad->look.x * pad->up.y; - } - - if ((*header >> 14) & PADFLAG_HASBBOXDATA) { - if (fields & PADFIELD_BBOX) { - fbuffer = (f32 *) ptr; - pad->bbox.xmin = fbuffer[0]; - pad->bbox.xmax = fbuffer[1]; - pad->bbox.ymin = fbuffer[2]; - pad->bbox.ymax = fbuffer[3]; - pad->bbox.zmin = fbuffer[4]; - pad->bbox.zmax = fbuffer[5]; - } - ptr += 4 * 6; - } else { - if (fields & PADFIELD_BBOX) { - pad->bbox.xmin = -100; - pad->bbox.ymin = -100; - pad->bbox.zmin = -100; - pad->bbox.xmax = 100; - pad->bbox.ymax = 100; - pad->bbox.zmax = 100; - } - } - - if (fields & PADFIELD_FLAGS) { - pad->flags = (*header >> 14); - } + *pad = g_Pads[padnum]; } bool padHasBboxData(s32 padnum) { - u32 offset = g_PadOffsets[padnum]; - u32 *header = (u32 *)&g_StageSetup.padfiledata[offset]; - - return ((*header >> 14) & PADFLAG_HASBBOXDATA) != 0; + return (g_Pads[padnum].flags & PADFLAG_HASBBOXDATA) != 0; } void padGetCentre(s32 padnum, struct coord *coord) @@ -185,97 +57,47 @@ void padGetCentre(s32 padnum, struct coord *coord) */ void padRotateForDoor(s32 padnum) { - u32 stack; - u32 *ptr; - u32 *header; - struct coord *look; struct coord *up; f32 scale; - s32 offset; - offset = g_PadOffsets[padnum]; - ptr = (u32 *) &g_StageSetup.padfiledata[offset]; - header = ptr; - - ptr++; - - if ((*header >> 14) & PADFLAG_INTPOS) { - ptr += 2; - } else { - ptr += 3; - } - - if (((*header >> 14) & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) == 0) { - up = (struct coord *) ptr; + if ((g_Pads[padnum].flags & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) == 0) { + up = &g_Pads[padnum].up; up->y = 0; scale = 1 / sqrtf(up->f[0] * up->f[0] + up->f[2] * up->f[2]); up->x *= scale; up->z *= scale; - - ptr += 3; } - if ((*header >> 14) & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) { + if (g_Pads[padnum].flags & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) { // Unset the LOOKALIGN flags, then set LOOKALIGNTOY - *header = *header ^ (((*header >> 14) ^ ((*header >> 14) & ~(PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ | PADFLAG_LOOKALIGNINVERT))) << 14); - *header = *header ^ (((*header >> 14) ^ ((*header >> 14) | PADFLAG_LOOKALIGNTOY)) << 14); + g_Pads[padnum].flags &= ~PADFLAG_LOOKALIGNTOX; + g_Pads[padnum].flags &= ~PADFLAG_LOOKALIGNTOZ; + g_Pads[padnum].flags &= ~PADFLAG_LOOKALIGNINVERT; + g_Pads[padnum].flags |= PADFLAG_LOOKALIGNTOY; } else { - look = (struct coord *) ptr; - - look->x = 0.0f; - look->y = 1.0f; - look->z = 0.0f; + g_Pads[padnum].look.x = 0.0f; + g_Pads[padnum].look.y = 1.0f; + g_Pads[padnum].look.z = 0.0f; } } void padCopyBboxFromPad(s32 padnum, struct pad *src) { - u32 offset = g_PadOffsets[padnum]; - f32 *fbuffer = (f32 *)&g_StageSetup.padfiledata[offset]; - u32 *header = (u32 *)fbuffer; - - if ((*header >> 14) & PADFLAG_HASBBOXDATA) { - fbuffer++; - - if ((*header >> 14) & PADFLAG_INTPOS) { - fbuffer += 2; - } else { - fbuffer += 3; - } - - if (((*header >> 14) & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) == 0) { - fbuffer += 3; - } - - if (((*header >> 14) & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) == 0) { - fbuffer += 3; - } - - fbuffer[0] = src->bbox.xmin; - fbuffer[1] = src->bbox.xmax; - fbuffer[2] = src->bbox.ymin; - fbuffer[3] = src->bbox.ymax; - fbuffer[4] = src->bbox.zmin; - fbuffer[5] = src->bbox.zmax; + if (g_Pads[padnum].flags & PADFLAG_HASBBOXDATA) { + g_Pads[padnum].bbox = src->bbox; } } void padSetFlag(s32 padnum, u32 flag) { - u32 offset = g_PadOffsets[padnum]; - u32 *header = (u32 *)&g_StageSetup.padfiledata[offset]; - - *header = *header ^ ((*header >> 14) ^ ((*header >> 14) | flag)) << 14; + g_Pads[padnum].flags |= flag; } void padUnsetFlag(s32 padnum, u32 flag) { - u32 offset = g_PadOffsets[padnum]; - u32 *header = (u32 *)&g_StageSetup.padfiledata[offset]; - - *header = *header ^ ((*header >> 14) ^ ((*header >> 14) & ~flag)) << 14; + g_Pads[padnum].flags &= ~flag; } bool func0f1162c4(s32 padnum, s32 arg1) diff --git a/src/game/setuppads.c b/src/game/setuppads.c index 693f3a430..ce241c591 100644 --- a/src/game/setuppads.c +++ b/src/game/setuppads.c @@ -40,17 +40,15 @@ void setupPreparePads(void) s32 offset; g_PadsFile = (struct padsfileheader *)g_StageSetup.padfiledata; - g_PadOffsets = (u16 *)(g_StageSetup.padfiledata + 0x14); + g_Pads = (struct pad *)(g_StageSetup.padfiledata + 0x14); padnum = 0; numpads = g_PadsFile->numpads; for (; padnum < numpads; padnum++) { - offset = g_PadOffsets[padnum]; - packedpad = (struct packedpad *) &g_StageSetup.padfiledata[offset]; padUnpack(padnum, PADFIELD_POS | PADFIELD_BBOX, &pad); // If room is negative (ie. not specified) - if (packedpad->room < 0) { + if (g_Pads[padnum].room < 0) { roomsptr = NULL; bgFindRoomsByPos(&pad.pos, inrooms, aboverooms, 20, NULL); @@ -64,27 +62,12 @@ void setupPreparePads(void) roomnum = cdFindFloorRoomAtPos(&pad.pos, roomsptr); if (roomnum > 0) { - packedpad->room = roomnum; + g_Pads[padnum].room = roomnum; } else { - packedpad->room = roomsptr[0]; + g_Pads[padnum].room = roomsptr[0]; } } } - - // Scale the bbox by 1 and save it back into the packed pad data. - // Yeah, this is effectively doing nothing. - if ((*(u32 *) packedpad >> 14) & PADFLAG_HASBBOXDATA) { - f32 scale = 1; - - pad.bbox.xmin *= scale; - pad.bbox.xmax *= scale; - pad.bbox.ymin *= scale; - pad.bbox.ymax *= scale; - pad.bbox.zmin *= scale; - pad.bbox.zmax *= scale; - - padCopyBboxFromPad(padnum, &pad); - } } g_StageSetup.waypoints = (struct waypoint *) ((u32)g_StageSetup.padfiledata + g_PadsFile->waypointsoffset); diff --git a/src/include/bss.h b/src/include/bss.h index b05680fe4..7c02c744a 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -185,7 +185,7 @@ extern struct fileguid g_GameFileGuid; extern u8 g_AltTitleUnlocked; extern u8 g_AltTitleEnabled; extern struct padsfileheader *g_PadsFile; -extern u16 *g_PadOffsets; +extern struct pad *g_Pads; extern u16 *g_CoverFlags; extern s32 *g_CoverRooms; extern struct covercandidate *g_CoverCandidates; diff --git a/tools/assetmgr/mkpads b/tools/assetmgr/mkpads index 510612ee7..351145ed2 100755 --- a/tools/assetmgr/mkpads +++ b/tools/assetmgr/mkpads @@ -102,54 +102,44 @@ class App(): def make_pads(self): output = bytes() - offsets = bytes() - start = pos = assetmgr.align4(0x14 + len(self.json['pads']) * 2) for pad in self.json['pads']: - # flags, room and liftnum - # ffffffff ffffffff ffrrrrrr rrrrllll + output += self.make_float(pad['pos'][0]) + output += self.make_float(pad['pos'][1]) + output += self.make_float(pad['pos'][2]) + + output += self.make_float(pad['dir'][0]) + output += self.make_float(pad['dir'][1]) + output += self.make_float(pad['dir'][2]) + + output += self.make_float(pad['up'][0]) + output += self.make_float(pad['up'][1]) + output += self.make_float(pad['up'][2]) + + # normal + output += self.make_float(pad['up'][1] * pad['dir'][2] - pad['dir'][1] * pad['up'][2]); + output += self.make_float(pad['up'][2] * pad['dir'][0] - pad['dir'][2] * pad['up'][0]); + output += self.make_float(pad['up'][0] * pad['dir'][1] - pad['dir'][0] * pad['up'][1]); + + output += self.make_float(pad['xmin']) + output += self.make_float(pad['xmax']) + output += self.make_float(pad['ymin']) + output += self.make_float(pad['ymax']) + output += self.make_float(pad['zmin']) + output += self.make_float(pad['zmax']) + + # room is filled in at runtime + room = 0xffffffff + output += room.to_bytes(4, 'big') + flags = self.make_pad_flags(pad) + output += flags.to_bytes(4, 'big') - word = (flags << 14) | 0x3ff0 | (pad['liftnum'] & 0x0f) - - output += word.to_bytes(4, 'big') - - if flags & PADFLAG_INTPOS: - output += self.make_unsigned(pad['pos'][0]).to_bytes(2, 'big') - output += self.make_unsigned(pad['pos'][1]).to_bytes(2, 'big') - output += self.make_unsigned(pad['pos'][2]).to_bytes(2, 'big') - output += b'\x00\x00' - else: - output += self.make_float(pad['pos'][0]) - output += self.make_float(pad['pos'][1]) - output += self.make_float(pad['pos'][2]) - - if (flags & 0x0e) == 0: - output += self.make_float(pad['up'][0]) - output += self.make_float(pad['up'][1]) - output += self.make_float(pad['up'][2]) - - if (flags & 0xe0) == 0: - output += self.make_float(pad['dir'][0]) - output += self.make_float(pad['dir'][1]) - output += self.make_float(pad['dir'][2]) - - if flags & PADFLAG_HASBBOXDATA: - output += self.make_float(pad['xmin']) - output += self.make_float(pad['xmax']) - output += self.make_float(pad['ymin']) - output += self.make_float(pad['ymax']) - output += self.make_float(pad['zmin']) - output += self.make_float(pad['zmax']) + output += pad['liftnum'].to_bytes(1, 'big') output = assetmgr.pad4(output) - offsets += pos.to_bytes(2, 'big') - pos = start + len(output) - - offsets = assetmgr.pad4(offsets) - - return offsets + output + return output # Some pads need to store 0x80000000 (negative 0), but this isn't supported # in JSON, nor does it appear to be a thing in Python, hence this hack.