mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-08-16 04:44:08 -04:00
Store pads in their full unpacked format
This commit is contained in:
@@ -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.
|
||||
#
|
||||
|
||||
+17
-195
@@ -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)
|
||||
|
||||
+4
-21
@@ -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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+31
-41
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user