portx64: moved pdextract code to src/preprocess, renamed files and function names to follow the port standard

This commit is contained in:
Raf committed 2024-08-08 22:00:08 +08:00
1 parent 4d60c93beb
commit c519997b33
13 files changed
+4958 -98

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
#include "common.h"
#include "system.h"
struct ptrmarker m_PtrMarkers[1024*8];
int m_NumPtrMarkers;
void addMarker(u32 ptr_src, uintptr_t ptr_host)
{
if (m_NumPtrMarkers >= ARRAYCOUNT(m_PtrMarkers)) {
sysLogPrintf(LOG_ERROR, "Marker limit exceeded");
exit(EXIT_FAILURE);
}
m_PtrMarkers[m_NumPtrMarkers].ptr_src = ptr_src;
m_PtrMarkers[m_NumPtrMarkers].ptr_host = ptr_host;
m_NumPtrMarkers++;
}
struct ptrmarker* findPtrMarker(uintptr_t ptr_src)
{
for (int i = 0; i < m_NumPtrMarkers; i++) {
if (m_PtrMarkers[i].ptr_src == ptr_src) {
return &m_PtrMarkers[i];
}
}
return NULL;
}
void resetMarkers()
{
m_NumPtrMarkers = 0;
}
+119
View File
@@ -0,0 +1,119 @@
#ifndef _PDE_COMMON_H
#define _PDE_COMMON_H
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
// this BS comes from windows.h
#undef near
#undef far
#include <sys/param.h>
#include <PR/ultratypes.h>
#include "types.h"
#include "constants.h"
#if __BIG_ENDIAN__
#define htonll(x) (x)
#define ntohll(x) (x)
#else
#define htonll(x) ((((uint64_t)htonl(x&0xFFFFFFFF)) << 32) + htonl(x >> 32))
#define ntohll(x) ((((uint64_t)ntohl(x&0xFFFFFFFF)) << 32) + ntohl(x >> 32))
#endif
#define htobe16(x) htons(x)
#define htole16(x) (x)
#define be16toh(x) ntohs(x)
#define le16toh(x) (x)
#define htobe32(x) htonl(x)
#define htole32(x) (x)
#define be32toh(x) ntohl(x)
#define le32toh(x) (x)
#define htobe64(x) htonll(x)
#define htole64(x) (x)
#define be64toh(x) ntohll(x)
#define le64toh(x) (x)
#define srctoh16(value) ntohs(value)
#define srctoh32(value) ntohl(value)
#define srctoh64(value) ntohll(value)
#ifdef FORCE_BE32
#define htodst16(value) htons(value)
#define htodst32(value) htonl(value)
#define htodst64(value) htonll(value)
#define dsttoh16(value) ntohs(value)
#define dsttoh32(value) ntohl(value)
#define dsttoh64(value) ntohll(value)
#else
#define htodst16(value) (value)
#define htodst32(value) (value)
#define htodst64(value) (value)
#define dsttoh16(value) (value)
#define dsttoh32(value) (value)
#define dsttoh64(value) (value)
#endif
#define srctodst16(value) htodst16(srctoh16(value))
#define srctodst32(value) htodst32(srctoh32(value))
#define srctodst64(value) htodst64(srctoh64(value))
#ifdef FORCE_BE32
#define uintptr_t u32
#endif
#define ALIGN(val, size) ((val + (size - 1)) & ~(size - 1))
#define PD_PTR_BASE(x, b) (void *)((u8 *)b + (uintptr_t)x)
#define PD_PTR_BASEOFS(x, b, d) (void *)((u8 *)b - d + (uintptr_t)x)
static inline f32 swapF32(f32 x) { *(u32*)&x = PD_BE32(*(u32*)&x); return x; }
static inline u32 swapU32(u32 x) { return PD_BE32(x); }
static inline s32 swapS32(s32 x) { return PD_BE32(x); }
static inline u16 swapU16(u16 x) { return PD_BE16(x); }
static inline s16 swapS16(s16 x) { return PD_BE16(x); }
static inline void* swapPtr(void** x) { return (void*)PD_BEPTR((uintptr_t)x); }
static inline struct coord swapCrd(struct coord crd) { crd.x = swapF32(crd.x); crd.y = swapF32(crd.y); crd.z = swapF32(crd.z); return crd; }
static inline u32 swapUnk(u32 x) { assert(0 && "unknown type"); return x; }
#define PD_SWAP_VAL(x) x = _Generic((x), \
f32: swapF32, \
u32: swapU32, \
s32: swapS32, \
u16: swapU16, \
s16: swapS16, \
struct coord: swapCrd, \
default: swapUnk \
)(x)
#define PD_SWAP_PTR(x) x = swapPtr((void *)(x))
// gbi related functions
void gbiReset(void);
void gbiSetSegment(int segment, u32 offset);
void gbiSetVtx(u32 src_offset, u32 dst_offset);
u32 gbiConvertGdl(u8 *dst, u32 dstpos, u8 *src, u32 srcpos, int segment_cmds);
void gbiConvertVtx(u8* dst, u32 dstpos, int count);
void gbiGdlRewriteAddrs(u8* dst, u32 offset);
void gbiAddTexAddr(u32 src_offset, u32 dst_offset);
// ptr marker functions
struct ptrmarker {
u32 ptr_src;
uintptr_t ptr_host;
};
void addMarker(u32 ptr_src, uintptr_t ptr_host);
struct ptrmarker* findPtrMarker(uintptr_t ptr_src);
void resetMarkers();
#endif
+651
View File
@@ -0,0 +1,651 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "data.h"
#include "bss.h"
#include "platform.h"
#include "common.h"
#include "system.h"
int m_SizeGDLs;
/**
* 4 bytes decompressed size of primary data
* 4 bytes compressed size of section 1 in its entirety
* 4 bytes compressed size of primary data
* Section 1:
* Primary: (zipped)
* 4 bytes null
* 4 bytes pointer to room table
* 4 bytes pointer to portal table
* 4 bytes pointer to bgcmds
* 4 bytes pointer to lights table
* 4 bytes null
* (room table)
* (portal table)
* (bgcmds)
* (lights table)
* room 1 (zipped)
* room 2 (zipped)
* ...
* Section 2:
* 2 bytes decompressed size of section (mask with 0x7fff)
* 2 bytes compressed size of section
* Texture ID list (zipped)
* Section 3:
* 2 bytes decompressed size of section (mask with 0x7fff)
* 2 bytes compressed size of section
* Zipped:
* (room bbox table)
* (list of roomgfxdata sizes)
* (list of light counts per room)
*/
struct fileheader {
u32 primary_infsize;
u32 section1_cmpsize;
u32 primary_cmpsize;
};
struct sectionheader {
u16 infsize;
u16 cmpsize;
};
struct n64_primaryheader {
u32 unused1;
u32 ptr_rooms;
u32 ptr_portals;
u32 ptr_bgcmds;
u32 ptr_lights;
u32 unused2;
};
struct host_primaryheader {
uintptr_t unused1;
uintptr_t ptr_rooms;
uintptr_t ptr_portals;
uintptr_t ptr_bgcmds;
uintptr_t ptr_lights;
uintptr_t unused2;
};
struct n64_room {
u32 ptr_gfxdata;
u32 pos[3];
u8 br_light_min;
u8 br_light_max;
};
struct host_room {
uintptr_t ptr_gfxdata;
u32 pos[3];
u8 br_light_min;
u8 br_light_max;
};
struct portal {
u16 verticesoffset;
s16 roomnum1;
s16 roomnum2;
u8 flags;
};
struct generic_portalvertices {
u8 count;
u32 vertices[1][3];
};
/*
struct light {
u16 roomnum;
u16 colour;
u8 brightness;
u8 sparkable : 1;
u8 healthy : 1;
u8 on : 1;
u8 sparking : 1;
u8 vulnerable : 1;
u8 brightnessmult;
s8 dirx;
s8 diry;
s8 dirz;
s16 bbox[4][3];
};*/
struct n64_roomblock {
u8 type;
u32 ptr_next;
u32 ptr_gdl;
u32 ptr_vertices;
u32 ptr_colours;
};
struct host_roomblock {
u8 type;
uintptr_t ptr_next;
uintptr_t ptr_gdl;
uintptr_t ptr_vertices;
uintptr_t ptr_colours;
};
struct n64_roomgfxdata {
u32 ptr_vertices;
u32 ptr_colours;
u32 ptr_opablocks;
u32 ptr_xlublocks;
s16 lightsindex;
s16 numlights;
s16 numvertices;
s16 numcolours;
// roomblocks[]
};
struct host_roomgfxdata {
uintptr_t ptr_vertices;
uintptr_t ptr_colours;
uintptr_t ptr_opablocks;
uintptr_t ptr_xlublocks;
s16 lightsindex;
s16 numlights;
s16 numvertices;
s16 numcolours;
// roomblocks[]
};
struct vtx {
s16 coord[3];
u8 flag;
u8 color;
u16 s;
u16 t;
};
int m_NumRooms;
u32 m_AllocSizes[512];
static void convertPrimaryRooms(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos)
{
struct n64_room *n64_rooms = (struct n64_room *) &src[*srcpos];
struct host_room *host_rooms = (struct host_room *) &dst[*dstpos];
m_NumRooms = 0;
for (int i = 1; n64_rooms[i].ptr_gfxdata != 0; i++) {
m_NumRooms++;
}
for (int i = 0; i < m_NumRooms + 1; i++) {
host_rooms[i].ptr_gfxdata = srctodst32(n64_rooms[i].ptr_gfxdata);
host_rooms[i].pos[0] = srctodst32(n64_rooms[i].pos[0]);
host_rooms[i].pos[1] = srctodst32(n64_rooms[i].pos[1]);
host_rooms[i].pos[2] = srctodst32(n64_rooms[i].pos[2]);
host_rooms[i].br_light_min = n64_rooms[i].br_light_min;
host_rooms[i].br_light_max = n64_rooms[i].br_light_max;
}
*srcpos += sizeof(*n64_rooms) * (m_NumRooms + 2);
*dstpos += sizeof(*host_rooms) * (m_NumRooms +2);
}
static void convertPrimaryPortals(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos, u32 *src_portalvtxs, u32 *dst_portalvtxs)
{
struct portal *n64_portals = (struct portal *) &src[*srcpos];
struct portal *host_portals = (struct portal *) &dst[*dstpos];
// Count portals
int numportals = 0;
for (int i = 0; n64_portals[i].verticesoffset != 0; i++) {
numportals++;
}
// Convert portals
for (int i = 0; i < numportals; i++) {
host_portals[i].verticesoffset = srctodst16(n64_portals[i].verticesoffset);
host_portals[i].roomnum1 = srctodst16(n64_portals[i].roomnum1);
host_portals[i].roomnum2 = srctodst16(n64_portals[i].roomnum2);
host_portals[i].flags = n64_portals[i].flags;
}
*srcpos += sizeof(*n64_portals) * (numportals + 1);
*dstpos += sizeof(*host_portals) * (numportals + 1);
*src_portalvtxs = *srcpos;
*dst_portalvtxs = *dstpos;
while (1) {
struct generic_portalvertices *n64_pvertices = (struct generic_portalvertices*)&src[*srcpos];
struct generic_portalvertices*host_pvertices = (struct generic_portalvertices*)&dst[*dstpos];
host_pvertices->count = n64_pvertices->count;
for (int j = 0; j < host_pvertices->count; j++) {
//host_pvertices->vertices[j].x = srctodst32(n64_pvertices->vertices[j].x);
//host_pvertices->vertices[j].y = srctodst32(n64_pvertices->vertices[j].y);
//host_pvertices->vertices[j].z = srctodst32(n64_pvertices->vertices[j].z);
host_pvertices->vertices[j][0] = srctodst32(n64_pvertices->vertices[j][0]);
host_pvertices->vertices[j][1] = srctodst32(n64_pvertices->vertices[j][1]);
host_pvertices->vertices[j][2] = srctodst32(n64_pvertices->vertices[j][2]);
}
*srcpos += 4 + host_pvertices->count * 12;
*dstpos += 4 + host_pvertices->count * 12;
if (host_pvertices->count == 0) break;
}
}
static void convertPrimaryBgCmds(u8 *dst, u32 *dstpos, u8 *src, u32 dst_portalvtxs, u32 src_portalvtxs)
{
struct bgcmd *n64_cmds = (struct bgcmd *) src;
struct bgcmd *host_cmds = (struct bgcmd *) &dst[*dstpos];
int num_cmds = 0;
for (int i = 0; n64_cmds[i].type != 0; i++) {
num_cmds++;
}
num_cmds++;
for (int i = 0; i < num_cmds; i++) {
host_cmds[i].type = n64_cmds[i].type;
host_cmds[i].len = n64_cmds[i].len;
host_cmds[i].param = srctodst32(n64_cmds[i].param);
if (host_cmds[i].type == 0x64) {
u32 offset = host_cmds[i].param - src_portalvtxs;
host_cmds[i].param = dst_portalvtxs + offset;
}
}
*dstpos += sizeof(*host_cmds) * num_cmds;
}
static void convertPrimaryLights(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos, u32 end)
{
struct light *n64_lights = (struct light *) &src[*srcpos];
struct light *host_lights = (struct light *) &dst[*dstpos];
int num_lights = (end - *srcpos) / sizeof(struct light);
for (int i = 0; i < num_lights; i++) {
host_lights[i].roomnum = srctodst16(n64_lights[i].roomnum);
host_lights[i].colour = srctodst16(n64_lights[i].colour);
host_lights[i].brightness = n64_lights[i].brightness;
host_lights[i].sparkable = n64_lights[i].sparkable;
host_lights[i].healthy = n64_lights[i].healthy;
host_lights[i].on = n64_lights[i].on;
host_lights[i].sparking = n64_lights[i].sparking;
host_lights[i].vulnerable = n64_lights[i].vulnerable;
host_lights[i].brightnessmult = n64_lights[i].brightnessmult;
host_lights[i].dirx = n64_lights[i].dirx;
host_lights[i].diry = n64_lights[i].diry;
host_lights[i].dirz = n64_lights[i].dirz;
for (int j = 0; j < 4; j++) {
host_lights[i].bbox[j].x = srctodst16(n64_lights[i].bbox[j].x);
host_lights[i].bbox[j].y = srctodst16(n64_lights[i].bbox[j].y);
host_lights[i].bbox[j].z = srctodst16(n64_lights[i].bbox[j].z);
}
}
*srcpos += sizeof(*n64_lights) * num_lights;
*dstpos += sizeof(*host_lights) * num_lights;
}
#define BLOCK_LEAF 0
#define BLOCK_PARENT 1
void relinkPtr(uintptr_t** ptr)
{
if (!*ptr) return;
struct ptrmarker* marker = findPtrMarker(*ptr);
if (!marker) {
fprintf(stderr, "[BG] WARNING: Unable to relink pointer: %p\n", ptr);
exit(EXIT_FAILURE);
}
*ptr = marker->ptr_host;
}
static u32 convertRoomGfxData(u8 *dst, u8 *src, u32 infsize, u32 src_ofs)
{
resetMarkers();
gbiReset();
u32 dst_roomoffset = src_ofs;
uintptr_t gdls_addr[64];
int numgdls = 0;
struct n64_roomgfxdata *src_header = (struct n64_roomgfxdata*)src;
struct host_roomgfxdata *dst_header = (struct host_roomgfxdata*)dst;
dst_header->ptr_vertices = srctoh32(src_header->ptr_vertices);
dst_header->ptr_colours = srctoh32(src_header->ptr_colours);
dst_header->ptr_opablocks = srctoh32(src_header->ptr_opablocks);
dst_header->ptr_xlublocks = srctoh32(src_header->ptr_xlublocks);
dst_header->lightsindex = srctoh16(src_header->lightsindex);
dst_header->numlights = srctoh16(src_header->numlights);
dst_header->numvertices = srctoh16(src_header->numvertices);
dst_header->numcolours = srctoh16(src_header->numcolours);
intptr_t endpos = dst_header->ptr_vertices - src_ofs;
uintptr_t curpos_src = sizeof(struct n64_roomgfxdata);
uintptr_t curpos_dst = sizeof(struct host_roomgfxdata);
// roomblocks
int ncoords = 0;
// save the ptr to roomblocks here to iterate later to fix the pointers
struct host_roomblock *ptr_dst_roomblocks = (struct host_roomblock*)&dst[curpos_dst];
int numblocks = 0;
while ((intptr_t)(curpos_src + sizeof(struct n64_roomblock)) <= endpos) {
struct n64_roomblock *src_roomblock = (struct n64_roomblock*)&src[curpos_src];
struct host_roomblock *dest_roomblock = (struct host_roomblock*)&dst[curpos_dst];
dest_roomblock->type = src_roomblock->type;
dest_roomblock->ptr_next = srctoh32(src_roomblock->ptr_next);
dest_roomblock->ptr_gdl = srctoh32(src_roomblock->ptr_gdl);
dest_roomblock->ptr_vertices = srctoh32(src_roomblock->ptr_vertices);
dest_roomblock->ptr_colours = srctoh32(src_roomblock->ptr_colours);
addMarker(curpos_src + src_ofs, curpos_dst + dst_roomoffset);
if (src_roomblock->type == BLOCK_PARENT) {
ncoords++;
uintptr_t vtx_ptr = dest_roomblock->ptr_vertices - src_ofs;
if (vtx_ptr < endpos) endpos = vtx_ptr;
}
else if (src_roomblock->ptr_gdl) {
gdls_addr[numgdls++] = srctoh32(src_roomblock->ptr_gdl) - src_ofs;
}
curpos_src += sizeof(struct n64_roomblock);
curpos_dst += sizeof(struct host_roomblock);
numblocks++;
}
// block coords
for (size_t i = 0; i < ncoords; i++) {
u32 *src_coord = (u32*)(src + curpos_src);
u32 *dst_coord = (u32*)(dst + curpos_dst);
dst_coord[0] = srctoh32(src_coord[0]);
dst_coord[1] = srctoh32(src_coord[1]);
dst_coord[2] = srctoh32(src_coord[2]);
dst_coord[3] = srctoh32(src_coord[3]);
dst_coord[4] = srctoh32(src_coord[4]);
dst_coord[5] = srctoh32(src_coord[5]);
addMarker(curpos_src + src_ofs, curpos_dst + dst_roomoffset);
curpos_src += 6 * sizeof(u32);
curpos_dst += 6 * sizeof(u32);
}
curpos_dst = ALIGN8(curpos_dst);
// vertices
uintptr_t ptr_src_vertices = curpos_src = ALIGN8(dst_header->ptr_vertices - src_ofs);
uintptr_t ptr_dst_vertices = curpos_dst + dst_roomoffset;
addMarker(curpos_src + src_ofs, curpos_dst + dst_roomoffset);
uintptr_t vtx_end = dst_header->ptr_colours - src_ofs;
while (dst_header->ptr_colours && curpos_src < vtx_end) {
struct vtx *src_vtx = (struct vtx*)(src + curpos_src);
struct vtx *dst_vtx = (struct vtx*)(dst + curpos_dst);
dst_vtx->coord[0] = srctoh16(src_vtx->coord[0]);
dst_vtx->coord[1] = srctoh16(src_vtx->coord[1]);
dst_vtx->coord[2] = srctoh16(src_vtx->coord[2]);
dst_vtx->flag = src_vtx->flag;
dst_vtx->color = src_vtx->color;
dst_vtx->s = srctoh16(src_vtx->s);
dst_vtx->t = srctoh16(src_vtx->t);
curpos_src += sizeof(struct vtx);
curpos_dst += sizeof(struct vtx);
}
curpos_dst = ALIGN8(curpos_dst);
// colors
uintptr_t ptr_src_colors = 0;
uintptr_t ptr_dst_colors = 0;
if (dst_header->ptr_colours) {
ptr_src_colors = curpos_src = ALIGN8(dst_header->ptr_colours - src_ofs);
ptr_dst_colors = curpos_dst + dst_roomoffset;
addMarker(curpos_src + src_ofs, curpos_dst + dst_roomoffset);
uintptr_t col_end = numgdls > 0 != 0 ? gdls_addr[0] : infsize;
size_t col_len = col_end - curpos_src;
memcpy(dst + curpos_dst, src + curpos_src, col_len);
curpos_src += col_len;
curpos_dst += col_len;
}
// gdls
gbiSetVtx(src_header->ptr_vertices, ptr_src_vertices);
gbiSetSegment(0x0e, dst_header->ptr_vertices);
m_SizeGDLs = 0;
uintptr_t gdlstart = curpos_dst;
for (size_t i = 0; i < numgdls; i++) {
addMarker(gdls_addr[i] + src_ofs, curpos_dst + dst_roomoffset);
curpos_dst = gbiConvertGdl(dst, curpos_dst, src, gdls_addr[i], 1);
}
m_SizeGDLs = curpos_dst - gdlstart;
// relink ptrs: roomblocks
for (size_t i = 0; i < numblocks; i++) {
struct host_roomblock *block = (struct host_roomblock*)&ptr_dst_roomblocks[i];
relinkPtr(&block->ptr_next);
if (block->type == BLOCK_LEAF) {
relinkPtr(&block->ptr_gdl);
u32 offset_vtx = block->ptr_vertices - ptr_src_vertices - src_ofs;
u32 offset_col = block->ptr_colours - ptr_src_colors - src_ofs;
block->ptr_vertices = ptr_dst_vertices + offset_vtx;
block->ptr_colours = ptr_dst_colors + offset_col;
}
else {
relinkPtr(&block->ptr_gdl); // child
relinkPtr(&block->ptr_vertices); // coord
}
}
// relink ptrs: header
relinkPtr(&dst_header->ptr_vertices);
relinkPtr(&dst_header->ptr_colours);
relinkPtr(&dst_header->ptr_opablocks);
relinkPtr(&dst_header->ptr_xlublocks);
return curpos_dst;
}
static u32 convertSection1(u8 *dst, u8 *src, u32 ofs)
{
// Convert primary
u32 srcpos = 0;
u32 dstpos = 0;
struct host_primaryheader *host_primary_header = (struct host_primaryheader *) dst;
struct n64_primaryheader *n64_primary_header = (struct n64_primaryheader *) src;
srcpos += sizeof(struct n64_primaryheader);
dstpos += sizeof(*host_primary_header);
u32 src_bgcmds = srctodst32(n64_primary_header->ptr_bgcmds) - ofs;
host_primary_header->unused1 = 0;
host_primary_header->unused2 = 0;
host_primary_header->ptr_rooms = dstpos + ofs;
convertPrimaryRooms(dst, &dstpos, src, &srcpos);
if (n64_primary_header->ptr_lights) {
host_primary_header->ptr_lights = dstpos + ofs;
srcpos = srctodst32(n64_primary_header->ptr_lights) - ofs;
convertPrimaryLights(dst, &dstpos, src, &srcpos, src_bgcmds);
}
host_primary_header->ptr_portals = dstpos + ofs;
srcpos = srctodst32(n64_primary_header->ptr_portals) - ofs;
u32 src_portalvtxs, dst_portalvtxs;
convertPrimaryPortals(dst, &dstpos, src, &srcpos, &src_portalvtxs, &dst_portalvtxs);
host_primary_header->ptr_bgcmds = dstpos + ofs;
convertPrimaryBgCmds(dst, &dstpos, &src[src_bgcmds], dst_portalvtxs, src_portalvtxs);
return dstpos;
}
static void convert_section2_texturenums(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos, u32 srclen)
{
u16 *src_ids = (u16 *) &src[*srcpos];
u16 *dst_ids = (u16 *) &dst[*dstpos];
int count = srclen / sizeof(u16);
for (int i = 0; i < count; i++) {
dst_ids[i] = srctodst16(src_ids[i]);
}
*srcpos += srclen;
*dstpos += srclen;
}
static void convert_section3_bboxes(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos)
{
s16 *src_bboxes = (s16 *) &src[*srcpos];
s16 *dst_bboxes = (s16 *) &dst[*dstpos];
for (int i = 0; i < m_NumRooms; i++) {
dst_bboxes[i * 6 + 0] = srctodst16(src_bboxes[i * 6 + 0]);
dst_bboxes[i * 6 + 1] = srctodst16(src_bboxes[i * 6 + 1]);
dst_bboxes[i * 6 + 2] = srctodst16(src_bboxes[i * 6 + 2]);
dst_bboxes[i * 6 + 3] = srctodst16(src_bboxes[i * 6 + 3]);
dst_bboxes[i * 6 + 4] = srctodst16(src_bboxes[i * 6 + 4]);
dst_bboxes[i * 6 + 5] = srctodst16(src_bboxes[i * 6 + 5]);
}
*srcpos += sizeof(s16) * 6 * (m_NumRooms - 1);
*dstpos += sizeof(s16) * 6 * (m_NumRooms - 1);
}
static void convert_section3_allocsizes(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos)
{
u16 *dst_sizes = (u16 *) &dst[*dstpos];
for (int i = 0; i < m_NumRooms; i++) {
dst_sizes[i] = (m_AllocSizes[i] - 0x100) / 0x10;
}
*srcpos += sizeof(u16) * (m_NumRooms - 1);
*dstpos += sizeof(u16) * (m_NumRooms - 1);
}
static void convert_section3_lightcounts(u8 *dst, u32 *dstpos, u8 *src, u32 *srcpos)
{
memcpy(&dst[*dstpos], &src[*srcpos], m_NumRooms);
*srcpos += (m_NumRooms - 1);
*dstpos += (m_NumRooms - 1);
}
void preprocessBgSection1(u8 *data, u32 size, u32 ofs)
{
u8 *dst = sysMemZeroAlloc(size);
u32 newSize = convertSection1(dst, data, ofs);
if (newSize > size) {
sysLogPrintf(LOG_ERROR, "overflow when trying to preprocess a bg file, size %d newsize %d", size, newSize);
exit(EXIT_FAILURE);
}
memcpy(data, dst, newSize);
sysMemFree(dst);
}
u32 preprocessBgRoom(u8 *data, u32 size, u32 room_ofs)
{
size *= 2;
u8 *dst = sysMemZeroAlloc(size);
u32 newSize = convertRoomGfxData(dst, data, size, room_ofs);
if (newSize > size) {
sysLogPrintf(LOG_ERROR, "overflow when trying to preprocess a bg room, size %d newsize %d", size, newSize);
exit(EXIT_FAILURE);
}
memcpy(data, dst, newSize);
sysMemFree(dst);
return newSize;
}
void preprocessBgSection1Header(u8* data, u32 size)
{
u32* header = (u32*)data;
PD_SWAP_VAL(header[0]); // inflatedsize
PD_SWAP_VAL(header[1]); // section1size
PD_SWAP_VAL(header[2]); // primcompsize
}
void preprocessBgSection2Header(u8* data, u32 size)
{
u16* header = (u16*)data;
PD_SWAP_VAL(header[0]); // inflatedsize
PD_SWAP_VAL(header[1]); // section2compsize
}
void preprocessBgSection2(u8* data, u32 size)
{
// section2 is a texture id list
u16* section2 = (u16*)data;
for (s32 i = 0; i < size; ++i) {
PD_SWAP_VAL(section2[i]);
}
}
void preprocessBgSection3Header(u8* data, u32 size)
{
u16* header = (u16*)data;
PD_SWAP_VAL(header[0]);
PD_SWAP_VAL(header[1]);
}
void preprocessBgSection3(u8* data, u32 size)
{
// room bounding boxes, 6x s16 per room
s16* bbox = (s16*)data;
for (s32 i = 1; i < g_Vars.roomcount; ++i) {
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
}
// gfxdatalen list
u16* gfxdatalen = (u16*)bbox;
for (s32 i = 1; i < g_Vars.roomcount; ++i) {
PD_SWAP_VAL(*gfxdatalen); ++gfxdatalen;
}
}
+95
View File
@@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "romdata.h"
#include "system.h"
static int getNextNonZero(u8 *src, u32 offset, size_t len)
{
u32 *ptr = (u32 *) &src[offset];
u32 *end = (u32 *) &src[len];
while (ptr < end) {
if (*ptr != 0) {
return srctoh32(*ptr);
}
ptr++;
}
return 0;
}
static int getNumStrings(u8 *src, size_t len)
{
u32 ptr_table_len = getNextNonZero(src, 0, len);
if (ptr_table_len) {
return ptr_table_len / sizeof(u32);
}
return 1;
}
u32 convertLangFile(u8 *dst, u8 *src, size_t srclen)
{
// Convert it
u32 *src_offsets = (u32 *) src;
size_t src_ptr_table_len = srctoh32(src_offsets[0]);
size_t src_str_table_len = srclen - src_ptr_table_len;
int num_strings = getNumStrings(src, srclen);
size_t dst_ptr_table_len = num_strings * sizeof(uintptr_t);
size_t dst_str_table_len = src_str_table_len;
int cur_dst_offset = dst_ptr_table_len;
uintptr_t *dst_offsets = (uintptr_t *) dst;
for (int i = 0; i < num_strings; i++) {
u32 src_offset = srctoh32(src_offsets[i]);
if (src_offset) {
// Write pointer
dst_offsets[i] = htodst32(cur_dst_offset);
// Write string
u32 end = getNextNonZero(src, (i + 1) * 4, num_strings * 4);
if (!end) {
end = srclen;
}
size_t len = end - src_offset;
len = ALIGN4(len);
memcpy(&dst[cur_dst_offset], &src[src_offset], len);
cur_dst_offset += len;
} else {
// Write pointer
dst_offsets[i] = 0;
}
}
return ALIGN16(cur_dst_offset);
}
u8 *preprocessLangFile(u8 *data, u32 size, u32 *outSize) {
u32 newSizeEstimated = romdataFileGetEstimatedSize(size, FT_LANG);
u8 *dst = sysMemZeroAlloc(newSizeEstimated);
u32 newSize = convertLangFile(dst, data, size);
if (newSize > newSizeEstimated) {
sysLogPrintf(LOG_ERROR, "overflow when trying to preprocess a lang file, size %d newsize %d", size, newSize);
exit(EXIT_FAILURE);
}
memcpy(data, dst, newSize);
sysMemFree(dst);
*outSize = newSize;
return 0;
}
File diff suppressed because it is too large. Load diff
+330
View File
@@ -0,0 +1,330 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "romdata.h"
#include "system.h"
#define PADFLAG_INTPOS 0x0001
#define PADFLAG_UPALIGNTOX 0x0002
#define PADFLAG_UPALIGNTOY 0x0004
#define PADFLAG_UPALIGNTOZ 0x0008
#define PADFLAG_UPALIGNINVERT 0x0010
#define PADFLAG_LOOKALIGNTOX 0x0020
#define PADFLAG_LOOKALIGNTOY 0x0040
#define PADFLAG_LOOKALIGNTOZ 0x0080
#define PADFLAG_LOOKALIGNINVERT 0x0100
#define PADFLAG_HASBBOXDATA 0x0200
struct n64_header {
s32 num_pads;
s32 num_covers;
u32 ptr_waypoints;
u32 ptr_waygroups;
u32 ptr_cover;
};
struct host_header {
s32 num_pads;
s32 num_covers;
uintptr_t ptr_waypoints;
uintptr_t ptr_waygroups;
uintptr_t ptr_cover;
};
struct padheader {
u32 flags : 18;
u32 room : 10;
u32 liftnum : 4;
};
struct n64_waypoint {
s32 padnum;
u32 ptr_neighbours;
s32 groupnum;
s32 step;
};
struct host_waypoint {
s32 padnum;
uintptr_t ptr_neighbours;
s32 groupnum;
s32 step;
};
struct n64_waygroup {
u32 ptr_neighbours;
u32 ptr_waypoints;
s32 step;
};
struct host_waygroup {
uintptr_t ptr_neighbours;
uintptr_t ptr_waypoints;
s32 step;
};
struct generic_coverdefinition {
u32 pos[3];
u32 dir[3];
u16 flags;
u16 unk1a;
};
static int convertPads(u8 *dst, int dstpos, u8 *src, int srcpos, int num_pads)
{
u16 *src_offsets = (u16 *) &src[srcpos];
u16 *dst_offsets = (u16 *) &dst[dstpos];
dstpos += num_pads * sizeof(u16);
for (int i = 0; i < num_pads; i++) {
dstpos = ALIGN4(dstpos);
srcpos = srctoh16(src_offsets[i]);
dst_offsets[i] = htodst16(dstpos);
// Header
u32 n64_padheader = srctoh32(*(u32 *) &src[srcpos]);
struct padheader *host_padheader = (struct padheader *) &dst[dstpos];
u32 flags = (n64_padheader >> 14) & 0x3ffff;
*(u32*)host_padheader = htodst32(n64_padheader);
srcpos += sizeof(struct padheader);
dstpos += sizeof(struct padheader);
// Position
if (flags & PADFLAG_INTPOS) {
s16 *srcptr = (s16 *) &src[srcpos];
s16 *dstptr = (s16 *) &dst[dstpos];
dstptr[0] = srctodst16(srcptr[0]);
dstptr[1] = srctodst16(srcptr[1]);
dstptr[2] = srctodst16(srcptr[2]);
srcpos += 8;
dstpos += 8;
} else {
u32 *srcptr = (u32 *) &src[srcpos];
u32 *dstptr = (u32 *) &dst[dstpos];
dstptr[0] = srctodst32(srcptr[0]);
dstptr[1] = srctodst32(srcptr[1]);
dstptr[2] = srctodst32(srcptr[2]);
srcpos += 12;
dstpos += 12;
}
// Up
if ((flags & (PADFLAG_UPALIGNTOX | PADFLAG_UPALIGNTOY | PADFLAG_UPALIGNTOZ)) == 0) {
u32 *srcptr = (u32 *) &src[srcpos];
u32 *dstptr = (u32 *) &dst[dstpos];
dstptr[0] = srctodst32(srcptr[0]);
dstptr[1] = srctodst32(srcptr[1]);
dstptr[2] = srctodst32(srcptr[2]);
srcpos += 12;
dstpos += 12;
}
// Look
if ((flags & (PADFLAG_LOOKALIGNTOX | PADFLAG_LOOKALIGNTOY | PADFLAG_LOOKALIGNTOZ)) == 0) {
u32 *srcptr = (u32 *) &src[srcpos];
u32 *dstptr = (u32 *) &dst[dstpos];
dstptr[0] = srctodst32(srcptr[0]);
dstptr[1] = srctodst32(srcptr[1]);
dstptr[2] = srctodst32(srcptr[2]);
srcpos += 12;
dstpos += 12;
}
// Bbox
if (flags & PADFLAG_HASBBOXDATA) {
u32 *srcptr = (u32 *) &src[srcpos];
u32 *dstptr = (u32 *) &dst[dstpos];
dstptr[0] = srctodst32(srcptr[0]);
dstptr[1] = srctodst32(srcptr[1]);
dstptr[2] = srctodst32(srcptr[2]);
dstptr[3] = srctodst32(srcptr[3]);
dstptr[4] = srctodst32(srcptr[4]);
dstptr[5] = srctodst32(srcptr[5]);
srcpos += 4 * 6;
dstpos += 4 * 6;
}
}
return dstpos;
}
static int convertWayPoints(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct n64_waypoint *n64_waypoints = (struct n64_waypoint *) &src[srcpos];
struct host_waypoint *host_waypoints = (struct host_waypoint *) &dst[dstpos];
int num_waypoints;
for (num_waypoints = 0; n64_waypoints[num_waypoints].padnum != -1; num_waypoints++);
dstpos += (num_waypoints + 1) * sizeof(struct host_waypoint);
u32 *host_neighbours = (u32 *) &dst[dstpos];
int n = 0;
for (int i = 0; i < num_waypoints; i++) {
host_waypoints[i].padnum = srctodst32(n64_waypoints[i].padnum);
host_waypoints[i].ptr_neighbours = htodst32(dstpos);
host_waypoints[i].groupnum = srctodst32(n64_waypoints[i].groupnum);
host_waypoints[i].step = 0;
u32 *n64_neighbours = (u32 *) &src[srctoh32(n64_waypoints[i].ptr_neighbours)];
for (int j = 0; n64_neighbours[j] != 0xffffffff; j++) {
host_neighbours[n++] = srctodst32(n64_neighbours[j]);
dstpos += 4;
}
host_neighbours[n++] = 0xffffffff;
dstpos += 4;
}
// Terminator
host_waypoints[num_waypoints].padnum = 0xffffffff;
host_waypoints[num_waypoints].ptr_neighbours = 0;
host_waypoints[num_waypoints].groupnum = 0;
host_waypoints[num_waypoints].step = 0;
return dstpos;
}
static int convertWayGroups(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct n64_waygroup *n64_waygroups = (struct n64_waygroup *) &src[srcpos];
struct host_waygroup *host_waygroups = (struct host_waygroup *) &dst[dstpos];
int num_waygroups;
for (num_waygroups = 0; n64_waygroups[num_waygroups].ptr_neighbours != 0; num_waygroups++);
dstpos += (num_waygroups + 1) * sizeof(struct host_waygroup);
// Waygroups and child waypoints
u32 *host_waypoints = (u32 *) &dst[dstpos];
int n = 0;
for (int i = 0; i < num_waygroups; i++) {
host_waygroups[i].ptr_waypoints = htodst32(dstpos);
host_waygroups[i].step = 0;
u32 *n64_waypoints = (u32 *) &src[srctoh32(n64_waygroups[i].ptr_waypoints)];
for (int j = 0; n64_waypoints[j] != 0xffffffff; j++) {
host_waypoints[n++] = srctodst32(n64_waypoints[j]);
dstpos += 4;
}
host_waypoints[n++] = 0xffffffff;
dstpos += 4;
}
// Terminator
host_waygroups[num_waygroups].ptr_neighbours = 0;
host_waygroups[num_waygroups].ptr_waypoints = 0;
host_waygroups[num_waygroups].step = 0;
// Waygroup neighbours
u32 *host_neighbours = (u32 *) &dst[dstpos];
n = 0;
for (int i = 0; i < num_waygroups; i++) {
host_waygroups[i].ptr_neighbours = htodst32(dstpos);
u32 *n64_neighbours = (u32 *) &src[srctoh32(n64_waygroups[i].ptr_neighbours)];
for (int j = 0; n64_neighbours[j] != 0xffffffff; j++) {
host_neighbours[n++] = srctodst32(n64_neighbours[j]);
dstpos += 4;
}
host_neighbours[n++] = 0xffffffff;
dstpos += 4;
}
return dstpos;
}
static int convertCover(u8 *dst, int dstpos, u8 *src, int srcpos, int num_covers)
{
struct generic_coverdefinition *n64_covers = (struct generic_coverdefinition *) &src[srcpos];
struct generic_coverdefinition *host_covers = (struct generic_coverdefinition *) &dst[dstpos];
for (int i = 0; i < num_covers; i++) {
host_covers[i].pos[0] = srctodst32(n64_covers[i].pos[0]);
host_covers[i].pos[1] = srctodst32(n64_covers[i].pos[1]);
host_covers[i].pos[2] = srctodst32(n64_covers[i].pos[2]);
host_covers[i].dir[0] = srctodst32(n64_covers[i].dir[0]);
host_covers[i].dir[1] = srctodst32(n64_covers[i].dir[1]);
host_covers[i].dir[2] = srctodst32(n64_covers[i].dir[2]);
host_covers[i].flags = srctodst16(n64_covers[i].flags);
host_covers[i].unk1a = srctodst16(n64_covers[i].unk1a);
}
dstpos += num_covers * sizeof(struct generic_coverdefinition);
return dstpos;
}
static int convertPadsFile(u8 *dst, u8 *src)
{
int dstpos = 0;
struct n64_header *n64_header = (struct n64_header *) src;
struct host_header *host_header = (struct host_header *) dst;
int num_pads = srctoh32(n64_header->num_pads);
int num_covers = srctoh32(n64_header->num_covers);
host_header->num_pads = htodst32(num_pads);
host_header->num_covers = htodst32(num_covers);
dstpos += sizeof(struct host_header);
// Pads
dstpos = convertPads(dst, dstpos, src, sizeof(struct n64_header), num_pads);
// Waypoints
host_header->ptr_waypoints = htodst32(dstpos);
dstpos = convertWayPoints(dst, dstpos, src, srctoh32(n64_header->ptr_waypoints));
// Waygroups
host_header->ptr_waygroups = htodst32(dstpos);
dstpos = convertWayGroups(dst, dstpos, src, srctoh32(n64_header->ptr_waygroups));
// Cover
host_header->ptr_cover = htodst32(dstpos);
dstpos = convertCover(dst, dstpos, src, srctoh32(n64_header->ptr_cover), num_covers);
return dstpos;
}
u8* preprocessPadsFile(u8 *data, u32 size, u32 *outSize) {
u32 newSizeEstimated = romdataFileGetEstimatedSize(size, FT_PADS);
u8* dst = sysMemZeroAlloc(newSizeEstimated);
u32 newSize = convertPadsFile(dst, data);
if (newSize > newSizeEstimated) {
sysLogPrintf(LOG_ERROR, "overflow when trying to preprocess a pads file, size %d newsize %d", size, newSize);
exit(EXIT_FAILURE);
}
memcpy(data, dst, newSize);
sysMemFree(dst);
*outSize = newSize;
return 0;
}
File diff suppressed because it is too large. Load diff
+107
View File
@@ -0,0 +1,107 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "romdata.h"
#include "system.h"
struct tile {
u8 type;
u8 numvertices;
u16 flags;
u16 floortype;
u8 xmin;
u8 ymin;
u8 zmin;
u8 xmax;
u8 ymax;
u8 zmax;
u16 floorcol;
};
u32 convertTiles(u8 *dst, u8 *src, size_t srclen)
{
int num_rooms = srctoh32(*(u32 *) src);
size_t src_ptr_table_len = (num_rooms + 1) * 4;
size_t dst_ptr_table_len = (num_rooms + 1) * sizeof(u32);
u32 *src_offsets = (u32 *) &src[4];
size_t data_len = srclen - src_ptr_table_len - 4;
*(u32 *) dst = htodst32(num_rooms);
u32 *dst_offsets = (u32 *) (dst + sizeof(u32));
u32 cur_dst_offset = dst_ptr_table_len + sizeof(u32);
u32 cur_src_offset = srctoh32(src_offsets[0]);
u32 end_src_offset = srctoh32(src_offsets[num_rooms]);
int room = 0;
while (1) {
// Check if this is a new room and write the pointer offset if so
while (room < (num_rooms + 1) && srctoh32(src_offsets[room]) == cur_src_offset) {
dst_offsets[room] = htodst32(cur_dst_offset);
room++;
}
if (cur_src_offset >= end_src_offset) {
break;
}
// Write tile data
struct tile *n64tile = (struct tile *) &src[cur_src_offset];
struct tile hosttile;
hosttile.type = n64tile->type;
hosttile.numvertices = n64tile->numvertices;
hosttile.flags = srctodst16(n64tile->flags);
hosttile.floortype = srctodst16(n64tile->floortype);
hosttile.xmin = n64tile->xmin;
hosttile.ymin = n64tile->ymin;
hosttile.zmin = n64tile->zmin;
hosttile.xmax = n64tile->xmax;
hosttile.ymax = n64tile->ymax;
hosttile.zmax = n64tile->zmax;
hosttile.floorcol = srctodst16(n64tile->floorcol);
memcpy(&dst[cur_dst_offset], &hosttile, sizeof(struct tile));
cur_dst_offset += sizeof(struct tile);
cur_src_offset += sizeof(struct tile);
// Write tile vertices
for (int i = 0; i < hosttile.numvertices; i++) {
*(s16 *) &dst[cur_dst_offset + 0] = srctodst16(*(s16 *) &src[cur_src_offset + 0]);
*(s16 *) &dst[cur_dst_offset + 2] = srctodst16(*(s16 *) &src[cur_src_offset + 2]);
*(s16 *) &dst[cur_dst_offset + 4] = srctodst16(*(s16 *) &src[cur_src_offset + 4]);
cur_dst_offset += 6;
cur_src_offset += 6;
}
}
return ALIGN16(cur_dst_offset);
}
u8 *preprocessTilesFile(u8 *data, u32 size, u32 *outSize)
{
u32 newSizeEstimated = romdataFileGetEstimatedSize(size, FT_TILES);
u8 *dst = sysMemZeroAlloc(newSizeEstimated);
u32 newSize = convertTiles(dst, data, size);
if (newSize > newSizeEstimated) {
sysLogPrintf(LOG_ERROR, "overflow when trying to preprocess a tiles file, size %d newsize %d", size, newSize);
exit(EXIT_FAILURE);
}
memcpy(data, dst, newSize);
sysMemFree(dst);
*outSize = newSize;
return 0;
}
@@ -14,30 +14,7 @@
#include "romdata.h"
#include "mod.h"
#include "system.h"
static inline f32 swapF32(f32 x) { *(u32 *)&x = PD_BE32(*(u32 *)&x); return x; }
static inline u32 swapU32(u32 x) { return PD_BE32(x); }
static inline s32 swapS32(s32 x) { return PD_BE32(x); }
static inline u16 swapU16(u16 x) { return PD_BE16(x); }
static inline s16 swapS16(s16 x) { return PD_BE16(x); }
static inline void *swapPtr(void **x) { return (void *)PD_BEPTR((uintptr_t)x); }
static inline struct coord swapCrd(struct coord crd) { crd.x = swapF32(crd.x); crd.y = swapF32(crd.y); crd.z = swapF32(crd.z); return crd; }
static inline u32 swapUnk(u32 x) { assert(0 && "unknown type"); return x; }
#define PD_SWAP_VAL(x) x = _Generic((x), \
f32: swapF32, \
u32: swapU32, \
s32: swapS32, \
u16: swapU16, \
s16: swapS16, \
struct coord: swapCrd, \
default: swapUnk \
)(x)
#define PD_SWAP_PTR(x) x = swapPtr((void *)(x))
#define PD_PTR_BASE(x, b) (void *)((u8 *)b + (uintptr_t)x)
#define PD_PTR_BASEOFS(x, b, d) (void *)((u8 *)b - d + (uintptr_t)x)
#include "common.h"
// HACK: to prevent double-swapping stuff, flag swapped offsets in a bitmap
@@ -275,77 +252,3 @@ u8* preprocessTexturesList(u8* data, u32 size, u32* outSize)
}
return 0;
}
void preprocessBgSection1Header(u8 *data, u32 size)
{
u32 *header = (u32 *)data;
PD_SWAP_VAL(header[0]); // inflatedsize
PD_SWAP_VAL(header[1]); // section1size
PD_SWAP_VAL(header[2]); // primcompsize
}
void preprocessBgSection2Header(u8 *data, u32 size)
{
u16 *header = (u16 *)data;
PD_SWAP_VAL(header[0]); // inflatedsize
PD_SWAP_VAL(header[1]); // section2compsize
}
void preprocessBgSection2(u8 *data, u32 size)
{
// section2 is a texture id list
u16 *section2 = (u16 *)data;
for (s32 i = 0; i < size; ++i) {
PD_SWAP_VAL(section2[i]);
}
}
void preprocessBgSection3Header(u8 *data, u32 size)
{
u16 *header = (u16 *)data;
PD_SWAP_VAL(header[0]);
PD_SWAP_VAL(header[1]);
}
void preprocessBgSection3(u8 *data, u32 size)
{
// room bounding boxes, 6x s16 per room
s16 *bbox = (s16 *)data;
for (s32 i = 1; i < g_Vars.roomcount; ++i) {
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
PD_SWAP_VAL(*bbox); ++bbox;
}
// gfxdatalen list
u16 *gfxdatalen = (u16 *)bbox;
for (s32 i = 1; i < g_Vars.roomcount; ++i) {
PD_SWAP_VAL(*gfxdatalen); ++gfxdatalen;
}
}
void preprocessBgLights(u8 *data, u32 ofs)
{
struct light *lbase = (void *)data;
if (!lbase) {
return;
}
for (s32 i = 0; i < g_Vars.roomcount; ++i) {
if (g_Rooms[i].numlights) {
struct light *lit = &lbase[g_Rooms[i].lightindex];
for (s32 j = 0; j < g_Rooms[i].numlights; ++j, ++lit) {
PD_SWAP_VAL(lit->colour);
PD_SWAP_VAL(lit->roomnum);
for (s32 k = 0; k < ARRAYCOUNT(lit->bbox); ++k) {
PD_SWAP_VAL(lit->bbox[k].x);
PD_SWAP_VAL(lit->bbox[k].y);
PD_SWAP_VAL(lit->bbox[k].z);
}
}
}
}
}
+426
View File
@@ -0,0 +1,426 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libaudio.h"
#include "common.h"
#include "system.h"
struct generic_adpcm_book {
s32 order;
s32 npredictors;
s16 book[128];
};
struct generic_adpcm_loop {
u32 start;
u32 end;
u32 count;
s16 state[16];
};
struct generic_raw_loop {
u32 start;
u32 end;
u32 count;
};
struct generic_envelope {
s32 attackTime;
s32 decayTime;
s32 releaseTime;
u8 attackVolume;
u8 decayVolume;
};
struct generic_keymap {
u8 velocityMin;
u8 velocityMax;
u8 keyMin;
u8 keyMax;
u8 keyBase;
s8 detune;
};
struct n64_adpcm_waveinfo {
u32 loop; // ptr to struct generic_adpcm_loop
u32 book; // ptr to struct generic_adpcm_book
};
struct host_adpcm_waveinfo {
uintptr_t loop; // ptr to struct generic_adpcm_loop
uintptr_t book; // ptr to struct generic_adpcm_book
};
struct n64_raw_waveinfo {
u32 loop; // ptr to struct generic_raw_loop
};
struct host_raw_waveinfo {
uintptr_t loop; // ptr to struct generic_raw_loop
};
struct n64_wavetable {
u32 base;
s32 len;
u8 type;
u8 flags;
union {
struct n64_adpcm_waveinfo adpcmWave;
struct n64_raw_waveinfo rawWave;
} waveInfo;
};
struct host_wavetable {
uintptr_t base;
s32 len;
u8 type;
u8 flags;
union {
struct host_adpcm_waveinfo adpcmWave;
struct host_raw_waveinfo rawWave;
} waveInfo;
};
struct n64_sound {
u32 envelope; // ptr to struct generic_envelope
u32 keyMap; // ptr to struct generic_keymap
u32 wavetable; // ptr to struct n64_wavetable
u8 samplePan;
u8 sampleVolume;
u8 flags;
};
struct host_sound {
uintptr_t envelope; // ptr to struct generic_envelope
uintptr_t keyMap; // ptr to struct generic_keymap
uintptr_t wavetable; // ptr to struct host_wavetable
u8 samplePan;
u8 sampleVolume;
u8 flags;
};
struct n64_instrument {
u8 volume;
u8 pan;
u8 priority;
u8 flags;
u8 tremType;
u8 tremRate;
u8 tremDepth;
u8 tremDelay;
u8 vibType;
u8 vibRate;
u8 vibDepth;
u8 vibDelay;
s16 bendRange;
s16 soundCount;
u32 soundArray[1]; // ptr to struct n64_sound
};
struct host_instrument {
u8 volume;
u8 pan;
u8 priority;
u8 flags;
u8 tremType;
u8 tremRate;
u8 tremDepth;
u8 tremDelay;
u8 vibType;
u8 vibRate;
u8 vibDepth;
u8 vibDelay;
s16 bendRange;
s16 soundCount;
uintptr_t soundArray[1]; // ptr to struct host_sound
};
struct n64_bank {
s16 instCount;
u8 flags;
u8 pad;
s32 sampleRate;
u32 percussion; // ptr to struct n64_instrument
u32 instArray[1]; // ptr to struct n64_instrument
};
struct host_bank {
s16 instCount;
u8 flags;
u8 pad;
s32 sampleRate;
uintptr_t percussion; // ptr to struct host_instrument
uintptr_t instArray[1]; // ptr to struct host_instrument
};
struct n64_bankfile {
s16 revision;
s16 bankCount;
u32 bankArray[1]; // ptr to struct n64_bank
};
struct host_bankfile {
s16 revision;
s16 bankCount;
uintptr_t bankArray[1]; // ptr to struct host_bank
};
// only proceeds to convert the next item if it's not already converted
#define AL_NEXT_ITEM(field, func) { \
struct ptrmarker *marker = findPtrMarker(srcpos); \
if (marker == NULL) { \
field = htodst32(dstpos); \
addMarker(srcpos, field); \
dstpos = func(dst, dstpos, src, srcpos); \
} else { \
field = marker->ptr_host; } \
}
static int convertAudioEnvelope(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct generic_envelope *n64_envelope = (struct generic_envelope *) &src[srcpos];
struct generic_envelope *host_envelope = (struct generic_envelope *) &dst[dstpos];
dstpos += sizeof(struct generic_envelope);
host_envelope->attackTime = srctodst32(n64_envelope->attackTime);
host_envelope->decayTime = srctodst32(n64_envelope->decayTime);
host_envelope->releaseTime = srctodst32(n64_envelope->releaseTime);
host_envelope->attackVolume = n64_envelope->attackVolume;
host_envelope->decayVolume = n64_envelope->decayVolume;
return dstpos;
}
static int convertAudioKeyMap(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct generic_keymap *n64_keymap = (struct generic_keymap *) &src[srcpos];
struct generic_keymap *host_keymap = (struct generic_keymap *) &dst[dstpos];
dstpos += sizeof(struct generic_keymap);
host_keymap->velocityMin = n64_keymap->velocityMin;
host_keymap->velocityMax = n64_keymap->velocityMax;
host_keymap->keyMin = n64_keymap->keyMin;
host_keymap->keyMax = n64_keymap->keyMax;
host_keymap->keyBase = n64_keymap->keyBase;
host_keymap->detune = n64_keymap->detune;
return dstpos;
}
static int convertAudioAdpcmLoop(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct generic_adpcm_loop *n64_loop = (struct generic_adpcm_loop *) &src[srcpos];
struct generic_adpcm_loop *host_loop = (struct generic_adpcm_loop *) &dst[dstpos];
dstpos += sizeof(struct generic_adpcm_loop);
host_loop->start = srctodst32(n64_loop->start);
host_loop->end = srctodst32(n64_loop->end);
host_loop->count = srctodst32(n64_loop->count);
for (int i = 0; i < ARRAYCOUNT(host_loop->state); i++) {
host_loop->state[i] = srctodst16(n64_loop->state[i]);
}
return dstpos;
}
static int convertAudioAdpcmBook(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct generic_adpcm_book *n64_book = (struct generic_adpcm_book *) &src[srcpos];
struct generic_adpcm_book *host_book = (struct generic_adpcm_book *) &dst[dstpos];
dstpos += sizeof(struct generic_adpcm_book);
host_book->order = srctodst32(n64_book->order);
host_book->npredictors = srctodst32(n64_book->npredictors);
for (int i = 0; i < ARRAYCOUNT(host_book->book); i++) {
host_book->book[i] = srctodst16(n64_book->book[i]);
}
return dstpos;
}
static int convertAudioRawLoop(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct generic_raw_loop *n64_loop = (struct generic_raw_loop *) &src[srcpos];
struct generic_raw_loop *host_loop = (struct generic_raw_loop *) &dst[dstpos];
dstpos += sizeof(struct generic_raw_loop);
host_loop->start = srctodst32(n64_loop->start);
host_loop->end = srctodst32(n64_loop->end);
host_loop->count = srctodst32(n64_loop->count);
return dstpos;
}
static int convertAudioWaveTable(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct n64_wavetable *n64_wavetable = (struct n64_wavetable *) &src[srcpos];
struct host_wavetable *host_wavetable = (struct host_wavetable *) &dst[dstpos];
dstpos += sizeof(struct host_wavetable);
host_wavetable->base = srctodst32(n64_wavetable->base);
host_wavetable->len = srctodst32(n64_wavetable->len);
host_wavetable->type = n64_wavetable->type;
host_wavetable->flags = n64_wavetable->flags;
if (host_wavetable->type == AL_ADPCM_WAVE) {
if (n64_wavetable->waveInfo.adpcmWave.loop) {
srcpos = srctoh32(n64_wavetable->waveInfo.adpcmWave.loop);
AL_NEXT_ITEM(host_wavetable->waveInfo.adpcmWave.loop, convertAudioAdpcmLoop);
} else {
host_wavetable->waveInfo.adpcmWave.loop = 0;
}
if (n64_wavetable->waveInfo.adpcmWave.book) {
srcpos = srctoh32(n64_wavetable->waveInfo.adpcmWave.book);
AL_NEXT_ITEM(host_wavetable->waveInfo.adpcmWave.book, convertAudioAdpcmBook);
} else {
host_wavetable->waveInfo.adpcmWave.book = 0;
}
} else if (host_wavetable->type == AL_RAW16_WAVE) {
if (n64_wavetable->waveInfo.rawWave.loop) {
srcpos = srctoh32(n64_wavetable->waveInfo.rawWave.loop);
AL_NEXT_ITEM(host_wavetable->waveInfo.rawWave.loop, convertAudioRawLoop);
} else {
host_wavetable->waveInfo.rawWave.loop = 0;
}
}
return dstpos;
}
static int convertAudioSound(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct n64_sound *n64_sound = (struct n64_sound *) &src[srcpos];
struct host_sound *host_sound = (struct host_sound *) &dst[dstpos];
dstpos += sizeof(struct host_sound);
if (n64_sound->envelope) {
srcpos = srctoh32(n64_sound->envelope);
AL_NEXT_ITEM(host_sound->envelope, convertAudioEnvelope);
} else {
host_sound->envelope = 0;
}
if (n64_sound->keyMap) {
srcpos = srctoh32(n64_sound->keyMap);
AL_NEXT_ITEM(host_sound->keyMap, convertAudioKeyMap);
} else {
host_sound->keyMap = 0;
}
if (n64_sound->wavetable) {
srcpos = srctoh32(n64_sound->wavetable);
AL_NEXT_ITEM(host_sound->wavetable, convertAudioWaveTable);
} else {
host_sound->wavetable = 0;
}
host_sound->samplePan = n64_sound->samplePan;
host_sound->sampleVolume = n64_sound->sampleVolume;
host_sound->flags = n64_sound->flags;
return dstpos;
}
static int convertAudioInstrument(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct n64_instrument *n64_instrument = (struct n64_instrument *) &src[srcpos];
struct host_instrument *host_instrument = (struct host_instrument *) &dst[dstpos];
int soundCount = srctoh16(n64_instrument->soundCount);
host_instrument->volume = n64_instrument->volume;
host_instrument->pan = n64_instrument->pan;
host_instrument->priority = n64_instrument->priority;
host_instrument->flags = n64_instrument->flags;
host_instrument->tremType = n64_instrument->tremType;
host_instrument->tremRate = n64_instrument->tremRate;
host_instrument->tremDepth = n64_instrument->tremDepth;
host_instrument->tremDelay = n64_instrument->tremDelay;
host_instrument->vibType = n64_instrument->vibType;
host_instrument->vibRate = n64_instrument->vibRate;
host_instrument->vibDepth = n64_instrument->vibDepth;
host_instrument->vibDelay = n64_instrument->vibDelay;
host_instrument->bendRange = srctodst16(n64_instrument->bendRange);
host_instrument->soundCount = htodst16(soundCount);
dstpos = dstpos + sizeof(struct host_instrument) + sizeof(uintptr_t) * (soundCount - 1);
for (int i = 0; i < soundCount; i++) {
srcpos = srctoh32(n64_instrument->soundArray[i]);
AL_NEXT_ITEM(host_instrument->soundArray[i], convertAudioSound);
}
return dstpos;
}
static int convertAudioBank(u8 *dst, int dstpos, u8 *src, int srcpos)
{
struct n64_bank *n64_bank = (struct n64_bank *) &src[srcpos];
struct host_bank *host_bank = (struct host_bank *) &dst[dstpos];
int instCount = srctoh16(n64_bank->instCount);
host_bank->instCount = htodst16(instCount);
host_bank->flags = n64_bank->flags;
host_bank->pad = n64_bank->pad;
host_bank->sampleRate = srctodst32(n64_bank->sampleRate);
dstpos = dstpos + sizeof(struct host_bank) + sizeof(uintptr_t) * (instCount - 1);
if (n64_bank->percussion) {
srcpos = srctoh32(n64_bank->percussion);
AL_NEXT_ITEM(host_bank->percussion, convertAudioInstrument);
} else {
host_bank->percussion = 0;
}
for (int i = 0; i < instCount; i++) {
srcpos = srctoh32(n64_bank->instArray[i]);
AL_NEXT_ITEM(host_bank->instArray[i], convertAudioInstrument);
}
return dstpos;
}
static int convertAudioBankFile(u8 *dst, u8 *src)
{
struct n64_bankfile *n64_bankfile = (struct n64_bankfile *)src;
struct host_bankfile *host_bankfile = (struct host_bankfile *)dst;
int bankCount = srctoh16(n64_bankfile->bankCount);
host_bankfile->revision = srctodst16(n64_bankfile->revision);
host_bankfile->bankCount = htodst16(bankCount);
u32 dstpos = sizeof(struct host_bankfile) + sizeof(uintptr_t) * (bankCount - 1);
for (int i = 0; i < bankCount; i++) {
host_bankfile->bankArray[i] = htodst32(dstpos);
u32 srcpos = srctoh32(n64_bankfile->bankArray[i]);
dstpos = convertAudioBank(dst, dstpos, src, srcpos);
}
return dstpos;
}
u8 *preprocessALBankFile(u8 *src, u32 size, u32 *outSize)
{
resetMarkers();
u32 dstlen = size * 3;
u8 *dst = sysMemZeroAlloc(dstlen);
*outSize = convertAudioBankFile(dst, src);
*outSize = ALIGN16(*outSize);
return dst;
}
+122
View File
@@ -0,0 +1,122 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "system.h"
struct n64fontchar {
u8 index;
s8 baseline;
u8 height;
u8 width;
s32 kerningindex;
u32 pixeldata;
};
struct hostfontchar {
u8 index;
s8 baseline;
u8 height;
u8 width;
s32 kerningindex;
uintptr_t pixeldata;
};
struct n64fontcharjpn {
u16 index;
s8 baseline;
u8 height;
u8 width;
s16 kerningindex;
u32 pixeldata;
};
struct hostfontcharjpn {
u16 index;
s8 baseline;
u8 height;
u8 width;
s16 kerningindex;
uintptr_t pixeldata;
};
struct fontdef {
const char *name;
u32 offsets[3];
int pal_extra_chars;
};
u8 *preprocessFont(u8 *src, u32 srclen, u32 *outSize)
{
int num_chars = 94;
#if VERSION == VERSION_PAL_FINAL
// PAL has more characters in these fonts
extern u8* _fonthandelgothicsmSegmentRomStart;
extern u8* _fonthandelgothicxsSegmentRomStart;
extern u8* _fonthandelgothicmdSegmentRomStart;
if (src == _fonthandelgothicsmSegmentRomStart
|| src == _fonthandelgothicxsSegmentRomStart
|| src == _fonthandelgothicmdSegmentRomStart) {
numchars = 135;
}
#endif
size_t dstlen = srclen - (num_chars * sizeof(struct n64fontchar)) + (num_chars * sizeof(struct hostfontchar)) + 0x20;
u8* dst = sysMemZeroAlloc(dstlen);
// Kerning table
s32 *src_kerning_table = (s32 *)src;
s32 *dst_kerning_table = (s32 *)dst;
for (int i = 0; i < 13 * 13; i++) {
dst_kerning_table[i] = srctodst32(src_kerning_table[i]);
}
u32 src_offset = ALIGN(13 * 13 * 4, sizeof(u32));
u32 dst_offset = ALIGN(13 * 13 * 4, sizeof(uintptr_t));
// Character table
#if VERSION == VERSION_JPN_FINAL
struct n64fontcharjpn *src_char_table = (struct n64fontcharjpn *) &src[src_offset];
struct hostfontcharjpn *dst_char_table = (struct hostfontcharjpn *) &dst[dst_offset];
u32 diff = (dst_offset + num_chars * sizeof(struct hostfontcharjpn)) - (src_offset + num_chars * sizeof(struct n64fontcharjpn));
for (int i = 0; i < num_chars; i++) {
dst_char_table[i].index = srctodst16(src_char_table[i].index);
dst_char_table[i].baseline = src_char_table[i].baseline;
dst_char_table[i].height = src_char_table[i].height;
dst_char_table[i].width = src_char_table[i].width;
dst_char_table[i].kerningindex = srctodst16(src_char_table[i].kerningindex);
dst_char_table[i].pixeldata = src_char_table[i].pixeldata ? srctodst32(src_char_table[i].pixeldata) + diff : 0;
}
src_offset += num_chars * sizeof(struct n64fontcharjpn);
dst_offset += num_chars * sizeof(struct hostfontcharjpn);
#else
struct n64fontchar *src_char_table = (struct n64fontchar *) &src[src_offset];
struct hostfontchar *dst_char_table = (struct hostfontchar *) &dst[dst_offset];
u32 diff = (dst_offset + num_chars * sizeof(struct hostfontchar)) - (src_offset + num_chars * sizeof(struct n64fontchar));
for (int i = 0; i < num_chars; i++) {
dst_char_table[i].index = src_char_table[i].index;
dst_char_table[i].baseline = src_char_table[i].baseline;
dst_char_table[i].height = src_char_table[i].height;
dst_char_table[i].width = src_char_table[i].width;
dst_char_table[i].kerningindex = srctodst32(src_char_table[i].kerningindex);
dst_char_table[i].pixeldata = src_char_table[i].pixeldata ? srctodst32(src_char_table[i].pixeldata) + diff : 0;
}
src_offset += num_chars * sizeof(struct n64fontchar);
dst_offset += num_chars * sizeof(struct hostfontchar);
#endif
// Pixel data
u32 len = srclen - src_offset;
memcpy(&dst[dst_offset], &src[src_offset], len);
if (outSize) *outSize = ALIGN16(dst_offset + len);
return dst;
}
+642
View File
@@ -0,0 +1,642 @@
#ifndef _IN_SETUP_DECL
#define _IN_SETUP_DECL
#include "common.h"
struct n64_stagesetup {
u32 ptr_waypoints;
u32 ptr_waygroups;
u32 ptr_cover;
u32 ptr_intro;
u32 ptr_props;
u32 ptr_paths;
u32 ptr_ailists;
u32 ptr_padfiledata;
};
struct n64_coord {
f32 x;
f32 y;
f32 z;
};
struct n64_defaultobj {
u16 extrascale;
u8 hidden2;
u8 type;
s16 modelnum;
s16 pad;
u32 flags;
u32 flags2;
u32 flags3;
u32 ptr_prop;
u32 ptr_model;
f32 realrot[3][3];
u32 hidden;
union {
u32 ptr_geotilef;
u32 ptr_geoblock;
u32 ptr_geocyl;
u32 ptr_unkgeo;
};
union {
u32 ptr_projectile;
u32 ptr_embedment;
};
s16 damage;
s16 maxdamage;
u8 shadecol[4];
u8 nextcol[4];
u16 floorcol;
s8 geocount;
s8 _pad_;
};
struct n64_doorobj {
struct n64_defaultobj base;
f32 maxfrac;
f32 perimfrac;
f32 accel;
f32 decel;
f32 maxspeed;
u16 doorflags;
u16 doortype;
u32 keyflags;
s32 autoclosetime;
f32 frac;
f32 fracspeed;
s8 mode;
s8 glasshits;
s16 fadealpha;
s16 xludist;
s16 opadist;
struct n64_coord startpos;
f32 mtx98[3][3];
u32 ptr_sibling;
s32 lastopen60;
s16 portalnum;
s8 soundtype;
s8 fadetime60;
s32 lastcalc60;
u8 laserfade;
u8 unusedmaybe[3];
u8 shadeinfo1[4];
u8 shadeinfo2[4];
u8 actual1;
u8 actual2;
u8 extra1;
u8 extra2;
};
struct n64_doorscaleobj {
u32 unk00;
s32 scale;
};
struct n64_keyobj {
struct n64_defaultobj base;
u32 keyflags;
};
struct n64_alarmobj {
struct n64_defaultobj base;
};
struct n64_cctvobj {
struct n64_defaultobj base;
s16 lookatpadnum;
s16 toleft;
//Mtxf camrotm;
f32 m[4][4];
f32 yzero;
f32 yrot;
f32 yleft;
f32 yright;
f32 yspeed;
f32 ymaxspeed;
s32 seebondtime60;
f32 maxdist;
f32 xzero;
};
struct n64_ammocrateobj {
struct n64_defaultobj base;
s32 ammotype;
};
struct n64_gset {
u8 weaponnum;
u8 unk0639;
u8 unk063a;
u8 weaponfunc;
};
struct n64_weaponobj {
struct n64_defaultobj base;
union {
struct n64_gset gset;
struct {
u8 weaponnum;
s8 unk5d;
s8 unk5e;
u8 gunfunc;
};
};
s8 fadeouttimer60;
s8 dualweaponnum;
union {
s16 timer240;
s16 team;
};
u32 ptr_dualweapon;
};
struct n64_packedchr {
s16 chrindex;
s8 unk02;
s8 typenum;
u32 spawnflags;
s16 chrnum;
u16 padnum;
u8 bodynum;
s8 headnum;
u16 ailistnum;
u16 padpreset;
u16 chrpreset;
u16 hearscale;
u16 viewdist;
u32 flags;
u32 flags2;
u8 team;
u8 squadron;
s16 chair;
u32 convtalk;
u8 tude;
u8 naturalanim;
u8 yvisang;
u8 teamscandist;
};
struct n64_tvscreen {
u32 ptr_cmdlist;
u16 offset;
s16 pause60;
u32 ptr_tconfig;
f32 rot;
f32 xscale;
f32 xscalefrac;
f32 xscaleinc;
f32 xscaleold;
f32 xscalenew;
f32 yscale;
f32 yscalefrac;
f32 yscaleinc;
f32 yscaleold;
f32 yscalenew;
f32 xmid;
f32 xmidfrac;
f32 xmidinc;
f32 xmidold;
f32 xmidnew;
f32 ymid;
f32 ymidfrac;
f32 ymidinc;
f32 ymidold;
f32 ymidnew;
u8 red;
u8 redold;
u8 rednew;
u8 green;
u8 greenold;
u8 greennew;
u8 blue;
u8 blueold;
u8 bluenew;
u8 alpha;
u8 alphaold;
u8 alphanew;
f32 colfrac;
f32 colinc;
};
struct n64_singlemonitorobj {
struct n64_defaultobj base;
struct n64_tvscreen screen;
s16 owneroffset;
s8 ownerpart;
u8 imagenum;
};
struct n64_multimonitorobj {
struct n64_defaultobj base;
struct n64_tvscreen screens[4];
u8 imagenums[4];
};
struct n64_hangingmonitorsobj {
struct n64_defaultobj base;
};
struct n64_autogunobj {
struct n64_defaultobj base;
s16 targetpad;
s8 firing;
u8 firecount;
f32 yzero;
f32 ymaxleft;
f32 ymaxright;
f32 yrot;
f32 yspeed;
f32 xzero;
f32 xrot;
f32 xspeed;
f32 maxspeed;
f32 aimdist;
f32 barrelspeed;
f32 barrelrot;
s32 lastseebond60;
s32 lastaimbond60;
s32 allowsoundframe;
u32 ptr_beam;
f32 shotbondsum;
u32 ptr_target;
u8 targetteam;
u8 ammoquantity;
s16 nextchrtest;
};
struct n64_linkgunsobj {
u32 unk00;
s16 offset1;
s16 offset2;
};
struct n64_debrisobj {
struct n64_defaultobj base;
};
struct n64_hatobj {
struct n64_defaultobj base;
};
struct n64_grenadeprobobj { // objtype 0x12
u32 unk00;
s16 chrnum;
u16 probability;
};
struct n64_linkliftdoorobj {
u32 unk00;
u32 ptr_door;
u32 ptr_lift;
u32 ptr_next;
s32 stopnum;
};
struct n64_multiammocrateslot {
u16 modelnum;
u16 quantity;
};
struct n64_multiammocrateobj {
struct n64_defaultobj base;
struct n64_multiammocrateslot slots[19];
};
struct n64_shieldobj {
struct n64_defaultobj base;
f32 initialamount;
f32 amount;
u32 unk64;
};
struct n64_tag {
u32 identifier;
u16 tagnum;
s16 cmdoffset;
u32 ptr_next;
u32 ptr_obj;
};
struct n64_objective {
u32 unk00;
s32 index;
u32 text;
u16 unk0c;
u8 flags;
s8 difficulties;
};
struct n64_stdobjective {
u32 cmd;
};
struct n64_objectivecmd {
u8 cmd0[4];
u32 cmd1;
};
struct n64_briefingobj {
u32 unk00;
u32 type;
u32 text;
u32 ptr_next;
};
struct n64_padlockeddoorobj {
u32 unk00;
u32 ptr_door;
u32 ptr_lock;
u32 ptr_next;
};
struct n64_truckobj {
struct n64_defaultobj base;
u32 ptr_ailist;
u16 aioffset;
s16 aireturnlist;
f32 speed;
f32 wheelxrot;
f32 wheelyrot;
f32 speedaim;
f32 speedtime60;
f32 turnrot60;
f32 roty;
u32 ptr_path;
s32 nextstep;
};
struct n64_tankobj {
u8 _pad_[128];
};
struct n64_heliobj {
struct n64_defaultobj base;
u32 ptr_ailist;
u16 aioffset;
s16 aireturnlist;
f32 rotoryrot;
f32 rotoryspeed;
f32 rotoryspeedaim;
f32 rotoryspeedtime;
f32 speed;
f32 speedaim;
f32 speedtime60;
f32 yrot;
u32 ptr_path;
s32 nextstep;
};
struct n64_glassobj {
struct n64_defaultobj base;
s16 portalnum;
s16 _pad_;
};
struct n64_safeobj {
struct n64_defaultobj base;
};
struct n64_safeitemobj {
u32 unk00;
u32 ptr_item;
u32 ptr_safe;
u32 ptr_door;
u32 ptr_next;
};
struct n64_cameraposobj {
s32 type;
f32 x;
f32 y;
f32 z;
f32 theta;
f32 verta;
s32 pad;
};
struct n64_tintedglassobj {
struct n64_defaultobj base;
s16 xludist;
s16 opadist;
s16 opacity;
s16 portalnum;
f32 unk64;
};
struct n64_liftobj {
struct n64_defaultobj base;
s16 pads[4];
u32 ptr_doors[4];
f32 dist;
f32 speed;
f32 accel;
f32 maxspeed;
s8 soundtype;
s8 levelcur;
s8 levelaim;
s8 _pad_;
struct n64_coord prevpos;
};
struct n64_linksceneryobj {
u32 unk00;
u32 ptr_trigger;
u32 ptr_unexp;
u32 ptr_exp;
u32 ptr_next;
};
struct n64_blockedpathobj {
u32 unk00;
u32 ptr_blocker;
s16 waypoint1;
s16 waypoint2;
u32 ptr_next;
};
struct n64_hov {
u8 type;
u8 flags;
s16 _pad_;
f32 bobycur;
f32 bobytarget;
f32 bobyspeed;
f32 yrot;
f32 bobpitchcur;
f32 bobpitchtarget;
f32 bobpitchspeed;
f32 bobrollcur;
f32 bobrolltarget;
f32 bobrollspeed;
f32 groundpitch;
f32 y;
f32 ground;
s32 prevframe60;
s32 prevgroundframe60;
};
struct n64_hoverbikeobj {
struct n64_defaultobj base;
struct n64_hov hov;
f32 speed[2];
f32 prevpos[2];
f32 w;
f32 rels[2];
f32 exreal;
f32 ezreal;
f32 ezreal2;
f32 leanspeed;
f32 leandiff;
s32 maxspeedtime240;
f32 speedabs[2];
f32 speedrel[2];
};
struct n64_hoverpropobj {
struct n64_defaultobj base;
struct n64_hov hov;
};
struct n64_fanobj {
struct n64_defaultobj base;
f32 yrot;
f32 yrotprev;
f32 ymaxspeed;
f32 yspeed;
f32 yaccel;
s8 on;
u8 _pad_[3];
};
struct n64_hovercarobj {
struct n64_defaultobj base;
u32 ptr_ailist;
u16 aioffset;
s16 aireturnlist;
f32 speed;
f32 speedaim;
f32 speedtime60;
f32 turnyspeed60;
f32 turnxspeed60;
f32 turnrot60;
f32 roty;
f32 rotx;
f32 rotz;
u32 ptr_path;
s32 nextstep;
s16 status;
s16 dead;
s16 deadtimer60;
s16 sparkstimer60;
};
struct n64_chopperobj {
struct n64_defaultobj base;
u32 ptr_ailist;
u16 aioffset;
s16 aireturnlist;
union {
struct {
f32 speed;
f32 speedaim;
f32 speedtime60;
};
struct n64_coord fall;
};
f32 turnyspeed60;
f32 turnxspeed60;
f32 turnrot60;
f32 roty;
f32 rotx;
f32 rotz;
u32 ptr_path;
s32 nextstep;//
s16 weaponsarmed;
s16 ontarget;
s16 target;
u8 attackmode;
u8 cw;
f32 vx;
f32 vy;
f32 vz;
f32 power;
f32 otx;
f32 oty;
f32 otz;
f32 bob;
f32 bobstrength;
s32 targetvisible;
s32 timer60;
s32 patroltimer60;
f32 gunturnyspeed60;
f32 gunturnxspeed60;
f32 gunroty;
f32 gunrotx;
f32 barrelrotspeed;
f32 barrelrot;
u32 ptr_fireslotthing;
s32 dead;
};
struct n64_escalatorobj {
struct n64_defaultobj base;
s32 frame;
struct n64_coord prevpos;
};
struct n64_textoverride {
u32 unk00;
s32 objoffset;
s32 weapon;
u32 obtaintext;
u32 ownertext;
u32 inventorytext;
u32 inventory2text;
u32 pickuptext;
u32 ptr_next;
u32 ptr_obj;
};
struct n64_criteria_roomentered {
u32 unk00;
u32 pad;
u32 status;
u32 ptr_next;
};
struct n64_criteria_throwinroom {
u32 unk00;
u32 unk04;
u32 pad;
u32 status;
u32 ptr_next;
};
struct n64_criteria_holograph {
u32 unk00;
u32 obj;
u32 status;
u32 ptr_next;
};
struct n64_ailist {
u32 ptr_list;
s32 id;
};
struct n64_path {
u32 ptr_pads;
u8 id;
u8 flags;
u16 len;
};
#endif
+209
View File
@@ -0,0 +1,209 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "gbi.h"
#ifdef FORCE_BE32
#define HOST_DWORDS_PER_CMD 1
#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu
#define HOST_DWORDS_PER_CMD 2
#else
#define HOST_DWORDS_PER_CMD 1
#endif
struct vtx {
s16 x;
s16 y;
s16 z;
u8 flags;
u8 colour;
s16 s;
s16 t;
};
struct texaddr {
u32 src;
u32 dst;
};
u32 m_Segments[16];
u32 m_SrcVtxOffset;
u32 m_DstVtxOffset;
struct texaddr m_TexAddrs[64];
int m_NumTexAddr;
void gbiReset(void)
{
for (int i = 0; i < ARRAYCOUNT(m_Segments); i++) {
m_Segments[i] = 0;
}
m_SrcVtxOffset = 0;
m_DstVtxOffset = 0;
m_NumTexAddr = 0;
}
void gbiSetSegment(int segment, u32 offset)
{
m_Segments[segment] = offset & 0x00ffffff;
}
void gbiSetVtx(u32 src_offset, u32 dst_offset)
{
m_SrcVtxOffset = src_offset & 0x00ffffff;
m_DstVtxOffset = dst_offset & 0x00ffffff;
}
void gbiAddTexAddr(u32 src_offset, u32 dst_offset)
{
m_TexAddrs[m_NumTexAddr].src = src_offset & 0x00ffffff;
m_TexAddrs[m_NumTexAddr++].dst = dst_offset & 0x00ffffff;
}
u32 gbiFindTexAddr(u32 src_offset)
{
for (int i = 0; i < m_NumTexAddr; i++) {
if (m_TexAddrs[i].src == src_offset)
return m_TexAddrs[i].dst;
}
return 0;
}
void gbiConvertVtx(u8 *dst, u32 offset, int count)
{
if (!offset) return;
struct vtx* vtxs = (struct vtx*)(dst + offset);
for (int i = 0; i < count; i++) {
struct vtx* vtx = &vtxs[i];
vtx->x = srctodst16(vtx->x);
vtx->y = srctodst16(vtx->y);
vtx->z = srctodst16(vtx->z);
vtx->s = srctodst16(vtx->s);
vtx->t = srctodst16(vtx->t);
}
}
#define CMD_IS_VTX(cmd) ((cmd & 0xff00000000000000) == 0x0400000000000000)
#define CMD_IS_DL(cmd) ((cmd & 0xff00000000000000) == 0x0600000000000000)
#define CMD_IS_COL(cmd) ((cmd & 0xff00000000000000) == 0x0700000000000000)
#define CMD_IS_ENDDL(cmd) ((cmd & 0xff00000000000000) == 0xb800000000000000)
#define CMD_IS_MOVEWORD(cmd) ((cmd & 0xff00000000000000) == 0xbc00000000000000)
#define CMD_IS_MOVEMEM(cmd) ((cmd & 0xff00000000000000) == 0x0300000000000000)
#define CMD_IS_MTX(cmd) ((cmd & 0xff00000000000000) == 0x0100000000000000)
#define CMD_IS_SETTIMG(cmd) ((cmd & 0xff00000000000000) == 0xfd00000000000000)
#define CMD_IS_SETZIMG(cmd) ((cmd & 0xff00000000000000) == 0xfe00000000000000)
#define CMD_IS_SETCIMG(cmd) ((cmd & 0xff00000000000000) == 0xff00000000000000)
#define CMD_HAS_ADDR(cmd) CMD_IS_VTX(cmd) \
|| CMD_IS_COL(cmd) \
|| CMD_IS_MOVEWORD(cmd) \
|| CMD_IS_SETTIMG(cmd)
#define CMD_IS_SEGMENTED(cmd) ( CMD_IS_MOVEMEM(cmd) \
|| CMD_IS_MTX(cmd) \
|| CMD_IS_VTX(cmd) \
|| CMD_IS_COL(cmd) \
|| CMD_IS_DL(cmd) \
|| CMD_IS_SETTIMG(cmd) \
|| CMD_IS_SETCIMG(cmd) \
|| CMD_IS_SETZIMG(cmd))
/**
* Segment 5 is the start of the model file. The data in these files shifts
* depending on the pointer size, so this function adjusts the offset accordingly.
*/
static u64 gbiRewriteAddr(u64 cmd, u8 opcode)
{
u8 segment = (cmd & 0x0f000000) >> 24;
u32 offset = cmd & 0x00ffffff;
if (segment == 5) {
if (opcode == 0xfd) {
offset = gbiFindTexAddr(offset);
}
else {
if (offset < m_SrcVtxOffset) {
printf("Tried to load data from offset 0x%x but segment starts at 0x%x\n", offset, m_SrcVtxOffset);
exit(EXIT_FAILURE);
}
offset = offset - m_SrcVtxOffset + m_DstVtxOffset;
}
}
return (cmd & 0xffffffffff000000) | offset;
}
void gbiGdlRewriteAddrs(u8 *dst, u32 offset)
{
if (!offset) return;
u64 *cmds = (u64 *)(dst + (offset & 0x00ffffff));
if (!cmds) return;
u64 cmd;
do {
cmd = *cmds;
Gfx* gfxcmd = cmds;
int idx = 0;
u8 opcode = (cmd >> 24) & 0xff;
#if HOST_DWORDS_PER_CMD == 2
idx = 1;
opcode = (cmd >> 24) & 0xff;
#endif
cmd = (u64)opcode << 56;
if (CMD_HAS_ADDR(cmd)) {
cmds[idx] = gbiRewriteAddr(cmds[idx], opcode);
}
if (CMD_IS_SEGMENTED(cmd)) {
gfxcmd->words.w1 |= 1;
}
cmds += HOST_DWORDS_PER_CMD;
} while (!CMD_IS_ENDDL(cmd));
}
u32 gbiConvertGdl(u8 *dst, u32 dstpos, u8 *src, u32 srcpos, int segment_cmds)
{
dstpos = ALIGN8(dstpos);
u64 *n64_cmd = (u64*)&src[srcpos];
u64 *host_cmd = (u64*)&dst[dstpos];
u64 cmd;
do {
cmd = srctoh64(*n64_cmd);
#if HOST_DWORDS_PER_CMD == 2
host_cmd[0] = htodst64((cmd & 0xffffffff00000000) >> 32);
host_cmd[1] = htodst64(cmd & 0xffffffff);
if (segment_cmds && CMD_IS_SEGMENTED(cmd)) {
host_cmd[1] |= 1;
}
#else
host_cmd[0] = (cmd >> 32) | ((cmd & 0xffffffff) << 32);
if (segment_cmds && CMD_IS_SEGMENTED(cmd)) {
Gfx* gfxcmd = (Gfx*)host_cmd;
gfxcmd->words.w1 |= 1;
}
#endif
dstpos += sizeof(*host_cmd) * HOST_DWORDS_PER_CMD;
host_cmd += HOST_DWORDS_PER_CMD;
n64_cmd++;
} while (!CMD_IS_ENDDL(cmd));
return dstpos;
}