forked from Ports/perfect_dark
portx64: moved pdextract code to src/preprocess, renamed files and function names to follow the port standard
This commit is contained in:
1 parent
4d60c93beb
commit
c519997b33
13 files changed
+4958
-98
No files matched your search
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user