mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-24 00:02:43 +02:00
portx64: pd-extract: bg (extract roomgfxdata) and some model fixes
This commit is contained in:
1 parent
ef4b60d384
commit
10a3992a62
4 files changed
+540
-155
No files matched your search
+43
-12
@@ -1,20 +1,48 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
#ifndef _PDE_COMMON_H
|
||||
#define _PDE_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define srctoh16(value) be16toh(value)
|
||||
#define srctoh32(value) be32toh(value)
|
||||
#define srctoh64(value) be64toh(value)
|
||||
#include <winsock2.h>
|
||||
#include <sys/param.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) htobe16(value)
|
||||
#define htodst32(value) htobe32(value)
|
||||
#define htodst64(value) htobe64(value)
|
||||
#define dsttoh16(value) be16toh(value)
|
||||
#define dsttoh32(value) be32toh(value)
|
||||
#define dsttoh64(value) be64toh(value)
|
||||
#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)
|
||||
@@ -66,6 +94,9 @@ int rzip_deflate(uint8_t *dst, size_t *dstlen, uint8_t *src, size_t srclen);
|
||||
void gbi_reset(void);
|
||||
void gbi_set_segment(int segment, uint32_t offset);
|
||||
void gbi_set_vtx(uint32_t src_offset, uint32_t dst_offset);
|
||||
uint32_t gbi_convert_gdl(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t srcpos);
|
||||
uint32_t gbi_convert_gdl(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t srcpos, int segment_cmds);
|
||||
void gbi_convert_vtx(uint8_t* dst, uint32_t dstpos, int count);
|
||||
void gbi_gdl_rewrite_addrs(uint8_t* dst, uint32_t offset);
|
||||
void gbi_add_tex_addr(uint32_t src_offset, uint32_t dst_offset);
|
||||
|
||||
#endif
|
||||
+341
-49
@@ -3,6 +3,45 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "system.h"
|
||||
|
||||
struct ptrmarker {
|
||||
uint32_t ptr_src;
|
||||
uintptr_t ptr_host;
|
||||
};
|
||||
|
||||
|
||||
struct ptrmarker m_PtrMarkers[2048];
|
||||
int m_NumPtrMarkers;
|
||||
int m_SizeGDLs;
|
||||
|
||||
static void add_marker(uint32_t ptr_src, uintptr_t ptr_host)
|
||||
{
|
||||
if (m_NumPtrMarkers >= ARRAYCOUNT(m_PtrMarkers)) {
|
||||
fprintf(stderr, "[BG] Marker limit exceeded\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
m_PtrMarkers[m_NumPtrMarkers].ptr_src = ptr_src;
|
||||
m_PtrMarkers[m_NumPtrMarkers].ptr_host = ptr_host;
|
||||
m_NumPtrMarkers++;
|
||||
}
|
||||
|
||||
static struct ptrmarker* find_marker(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;
|
||||
}
|
||||
|
||||
static void reset_markers()
|
||||
{
|
||||
m_NumPtrMarkers = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4 bytes decompressed size of primary data
|
||||
@@ -113,9 +152,57 @@ struct light {
|
||||
int16_t bbox[4][3];
|
||||
};
|
||||
|
||||
struct n64_roomblock {
|
||||
uint8_t type;
|
||||
uint32_t ptr_next;
|
||||
uint32_t ptr_gdl;
|
||||
uint32_t ptr_vertices;
|
||||
uint32_t ptr_colours;
|
||||
};
|
||||
|
||||
struct host_roomblock {
|
||||
uint8_t type;
|
||||
uintptr_t ptr_next;
|
||||
uintptr_t ptr_gdl;
|
||||
uintptr_t ptr_vertices;
|
||||
uintptr_t ptr_colours;
|
||||
};
|
||||
|
||||
struct n64_roomgfxdata {
|
||||
uint32_t ptr_vertices;
|
||||
uint32_t ptr_colours;
|
||||
uint32_t ptr_opablocks;
|
||||
uint32_t ptr_xlublocks;
|
||||
int16_t lightsindex;
|
||||
int16_t numlights;
|
||||
int16_t numvertices;
|
||||
int16_t numcolours;
|
||||
// roomblocks[]
|
||||
};
|
||||
|
||||
struct host_roomgfxdata {
|
||||
uintptr_t ptr_vertices;
|
||||
uintptr_t ptr_colours;
|
||||
uintptr_t ptr_opablocks;
|
||||
uintptr_t ptr_xlublocks;
|
||||
int16_t lightsindex;
|
||||
int16_t numlights;
|
||||
int16_t numvertices;
|
||||
int16_t numcolours;
|
||||
// roomblocks[]
|
||||
};
|
||||
|
||||
struct vtx {
|
||||
int16_t coord[3];
|
||||
uint8_t flag;
|
||||
uint8_t color;
|
||||
uint16_t s;
|
||||
uint16_t t;
|
||||
};
|
||||
|
||||
int m_NumRooms;
|
||||
|
||||
uint16_t m_AllocSizes[512];
|
||||
uint32_t m_AllocSizes[512];
|
||||
|
||||
static void convert_primary_rooms(uint8_t *dst, uint32_t *dstpos, uint8_t *src, uint32_t *srcpos)
|
||||
{
|
||||
@@ -137,11 +224,11 @@ static void convert_primary_rooms(uint8_t *dst, uint32_t *dstpos, uint8_t *src,
|
||||
host_rooms[i].br_light_max = n64_rooms[i].br_light_max;
|
||||
}
|
||||
|
||||
*srcpos += sizeof(*n64_rooms) * (m_NumRooms + 1);
|
||||
*dstpos += sizeof(*host_rooms) * (m_NumRooms + 1);
|
||||
*srcpos += sizeof(*n64_rooms) * (m_NumRooms + 2);
|
||||
*dstpos += sizeof(*host_rooms) * (m_NumRooms +2);
|
||||
}
|
||||
|
||||
static void convert_primary_portals(uint8_t *dst, uint32_t *dstpos, uint8_t *src, uint32_t *srcpos)
|
||||
static void convert_primary_portals(uint8_t *dst, uint32_t *dstpos, uint8_t *src, uint32_t *srcpos, uint32_t *src_portalvtxs, uint32_t *dst_portalvtxs)
|
||||
{
|
||||
struct portal *n64_portals = (struct portal *) &src[*srcpos];
|
||||
struct portal *host_portals = (struct portal *) &dst[*dstpos];
|
||||
@@ -164,13 +251,12 @@ static void convert_primary_portals(uint8_t *dst, uint32_t *dstpos, uint8_t *src
|
||||
*srcpos += sizeof(*n64_portals) * (numportals + 1);
|
||||
*dstpos += sizeof(*host_portals) * (numportals + 1);
|
||||
|
||||
// Convert portal vertices
|
||||
uint8_t *n64_vtxdata = &src[*srcpos];
|
||||
uint8_t *host_vtxdata = &dst[*dstpos];
|
||||
*src_portalvtxs = *srcpos;
|
||||
*dst_portalvtxs = *dstpos;
|
||||
|
||||
for (int i = 0; i < numportals; i++) {
|
||||
struct portalvertices *n64_pvertices = (struct portalvertices*) &n64_vtxdata[*srcpos];
|
||||
struct portalvertices *host_pvertices = (struct portalvertices*) &host_vtxdata[*dstpos];
|
||||
while (1) {
|
||||
struct portalvertices *n64_pvertices = (struct portalvertices*)&src[*srcpos];
|
||||
struct portalvertices *host_pvertices = (struct portalvertices*)&dst[*dstpos];
|
||||
|
||||
host_pvertices->count = n64_pvertices->count;
|
||||
|
||||
@@ -182,10 +268,12 @@ static void convert_primary_portals(uint8_t *dst, uint32_t *dstpos, uint8_t *src
|
||||
|
||||
*srcpos += 4 + host_pvertices->count * 12;
|
||||
*dstpos += 4 + host_pvertices->count * 12;
|
||||
|
||||
if (host_pvertices->count == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
static void convert_primary_bgcmds(uint8_t *dst, uint32_t *dstpos, uint8_t *src, uint32_t *srcpos)
|
||||
static void convert_primary_bgcmds(uint8_t *dst, uint32_t *dstpos, uint8_t *src, uint32_t *srcpos, uint32_t dst_portalvtxs, uint32_t src_portalvtxs)
|
||||
{
|
||||
struct bgcmd *n64_cmds = (struct bgcmd *) &src[*srcpos];
|
||||
struct bgcmd *host_cmds = (struct bgcmd *) &dst[*dstpos];
|
||||
@@ -201,6 +289,11 @@ static void convert_primary_bgcmds(uint8_t *dst, uint32_t *dstpos, uint8_t *src,
|
||||
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) {
|
||||
uint32_t offset = host_cmds[i].param - src_portalvtxs;
|
||||
host_cmds[i].param = dst_portalvtxs + offset;
|
||||
}
|
||||
}
|
||||
|
||||
*srcpos += sizeof(*n64_cmds) * num_cmds;
|
||||
@@ -238,21 +331,196 @@ static void convert_primary_lights(uint8_t *dst, uint32_t *dstpos, uint8_t *src,
|
||||
*dstpos += sizeof(*host_lights) * num_lights;
|
||||
}
|
||||
|
||||
static uint32_t convert_section1_roomgfxdata(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t srcpos)
|
||||
#define BLOCK_LEAF 0
|
||||
#define BLOCK_PARENT 1
|
||||
|
||||
void relink_ptr(uintptr_t** ptr)
|
||||
{
|
||||
return dstpos;
|
||||
if (!*ptr) return;
|
||||
|
||||
struct ptrmarker* marker = find_marker(*ptr);
|
||||
if (!marker) {
|
||||
fprintf(stderr, "[BG] WARNING: Unable to relink pointer: %p\n", ptr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*ptr = marker->ptr_host;
|
||||
}
|
||||
|
||||
static size_t sum(uint8_t *ptr, uint8_t *end)
|
||||
static uint32_t convert_section1_roomgfxdata(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t compsize, uint32_t src_roomoffset, uint32_t dst_roomoffset)
|
||||
{
|
||||
size_t sum = 0;
|
||||
reset_markers();
|
||||
dst_roomoffset += 0x0f000000;
|
||||
size_t infsize = rzip_get_infsize(src);
|
||||
uint8_t* src_roomgfxdata = calloc(1, infsize);
|
||||
|
||||
while (ptr < end) {
|
||||
sum = (sum + *ptr) & 0xffffffff;
|
||||
ptr++;
|
||||
int ret = rzip_inflate(src_roomgfxdata, infsize, src, compsize);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Unable to inflate roomgfxdata %d\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return sum;
|
||||
uintptr_t gdls_addr[64];
|
||||
int numgdls = 0;
|
||||
|
||||
struct n64_roomgfxdata *src_header = (struct n64_roomgfxdata*)src_roomgfxdata;
|
||||
struct host_roomgfxdata *dst_header = (struct host_roomgfxdata*)&dst[dstpos];
|
||||
|
||||
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_roomoffset;
|
||||
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_roomgfxdata[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);
|
||||
|
||||
add_marker(curpos_src + src_roomoffset, curpos_dst + dst_roomoffset);
|
||||
|
||||
if (src_roomblock->type == BLOCK_PARENT) {
|
||||
ncoords++;
|
||||
uintptr_t vtx_ptr = dest_roomblock->ptr_vertices - src_roomoffset;
|
||||
if (vtx_ptr < endpos) endpos = vtx_ptr;
|
||||
}
|
||||
else if (src_roomblock->ptr_gdl) {
|
||||
gdls_addr[numgdls++] = srctoh32(src_roomblock->ptr_gdl) - src_roomoffset;
|
||||
}
|
||||
|
||||
curpos_src += sizeof(struct n64_roomblock);
|
||||
curpos_dst += sizeof(struct host_roomblock);
|
||||
numblocks++;
|
||||
}
|
||||
|
||||
// block coords
|
||||
for (size_t i = 0; i < ncoords; i++) {
|
||||
uint32_t *src_coord = (uint32_t*)(src_roomgfxdata + curpos_src);
|
||||
uint32_t *dst_coord = (uint32_t*)(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]);
|
||||
|
||||
add_marker(curpos_src + src_roomoffset, curpos_dst + dst_roomoffset);
|
||||
|
||||
curpos_src += 6 * sizeof(uint32_t);
|
||||
curpos_dst += 6 * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
curpos_dst = ALIGN8(curpos_dst);
|
||||
|
||||
// vertices
|
||||
uintptr_t ptr_src_vertices = curpos_src = ALIGN8(dst_header->ptr_vertices - src_roomoffset);
|
||||
uintptr_t ptr_dst_vertices = curpos_dst + dst_roomoffset;
|
||||
|
||||
add_marker(curpos_src + src_roomoffset, curpos_dst + dst_roomoffset);
|
||||
|
||||
uintptr_t vtx_end = dst_header->ptr_colours - src_roomoffset;
|
||||
vtx_end = dst_header->ptr_colours == 0 ? infsize : vtx_end;
|
||||
|
||||
while (curpos_src < vtx_end) {
|
||||
struct vtx *src_vtx = (struct vtx*)(src_roomgfxdata + 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_roomoffset);
|
||||
ptr_dst_colors = curpos_dst + dst_roomoffset;
|
||||
|
||||
add_marker(curpos_src + src_roomoffset, 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_roomgfxdata + curpos_src, col_len);
|
||||
curpos_src += col_len;
|
||||
curpos_dst += col_len;
|
||||
}
|
||||
|
||||
// gdls
|
||||
gbi_set_vtx(src_header->ptr_vertices, ptr_src_vertices);
|
||||
gbi_set_segment(0x0e, dst_header->ptr_vertices);
|
||||
|
||||
m_SizeGDLs = 0;
|
||||
uintptr_t gdlstart = curpos_dst;
|
||||
for (size_t i = 0; i < numgdls; i++) {
|
||||
add_marker(gdls_addr[i] + src_roomoffset, curpos_dst + dst_roomoffset);
|
||||
curpos_dst = gbi_convert_gdl(dst, curpos_dst, src_roomgfxdata, 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];
|
||||
|
||||
relink_ptr(&block->ptr_next);
|
||||
|
||||
if (block->type == BLOCK_LEAF) {
|
||||
relink_ptr(&block->ptr_gdl);
|
||||
uint32_t offset_vtx = block->ptr_vertices - ptr_src_vertices - src_roomoffset;
|
||||
uint32_t offset_col = block->ptr_colours - ptr_src_colors - src_roomoffset;
|
||||
|
||||
block->ptr_vertices = ptr_dst_vertices + offset_vtx;
|
||||
block->ptr_colours = ptr_dst_colors + offset_col;
|
||||
}
|
||||
else {
|
||||
relink_ptr(&block->ptr_gdl); // child
|
||||
relink_ptr(&block->ptr_vertices); // coord
|
||||
}
|
||||
}
|
||||
|
||||
// relink ptrs: header
|
||||
relink_ptr(&dst_header->ptr_vertices);
|
||||
relink_ptr(&dst_header->ptr_colours);
|
||||
relink_ptr(&dst_header->ptr_opablocks);
|
||||
relink_ptr(&dst_header->ptr_xlublocks);
|
||||
|
||||
free(src_roomgfxdata);
|
||||
return curpos_dst;
|
||||
}
|
||||
|
||||
static uint32_t convert_section1(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t srcpos, struct fileheader *n64_header)
|
||||
@@ -276,51 +544,67 @@ static uint32_t convert_section1(uint8_t *dst, uint32_t dstpos, uint8_t *src, ui
|
||||
|
||||
// Convert primary
|
||||
struct host_primaryheader *host_primary_header = (struct host_primaryheader *) &dstbin[dstbinpos];
|
||||
struct n64_primaryheader *n64_primary_header = (struct n64_primaryheader *) &srcbin[srcbinpos];
|
||||
srcbinpos += sizeof(struct n64_primaryheader);
|
||||
dstbinpos += sizeof(*host_primary_header);
|
||||
|
||||
uint32_t src_bgcmds = srctodst32(n64_primary_header->ptr_bgcmds) - 0x0f000000;
|
||||
|
||||
host_primary_header->unused1 = 0;
|
||||
host_primary_header->unused2 = 0;
|
||||
|
||||
host_primary_header->ptr_rooms = dstbinpos;
|
||||
host_primary_header->ptr_rooms = dstbinpos + 0x0f000000;
|
||||
convert_primary_rooms(dstbin, &dstbinpos, srcbin, &srcbinpos);
|
||||
|
||||
if (n64_primary_header->ptr_lights) {
|
||||
host_primary_header->ptr_lights = dstbinpos + 0x0f000000;
|
||||
srcbinpos = srctodst32(n64_primary_header->ptr_lights) - 0x0f000000;
|
||||
convert_primary_lights(dstbin, &dstbinpos, srcbin, &srcbinpos, src_bgcmds);
|
||||
}
|
||||
|
||||
host_primary_header->ptr_portals = dstbinpos;
|
||||
convert_primary_portals(dstbin, &dstbinpos, srcbin, &srcbinpos);
|
||||
host_primary_header->ptr_portals = dstbinpos + 0x0f000000;
|
||||
srcbinpos = srctodst32(n64_primary_header->ptr_portals) - 0x0f000000;
|
||||
uint32_t src_portalvtxs, dst_portalvtxs;
|
||||
convert_primary_portals(dstbin, &dstbinpos, srcbin, &srcbinpos, &src_portalvtxs, &dst_portalvtxs);
|
||||
|
||||
host_primary_header->ptr_bgcmds = dstbinpos;
|
||||
convert_primary_bgcmds(dstbin, &dstbinpos, srcbin, &srcbinpos);
|
||||
|
||||
host_primary_header->ptr_lights = dstbinpos;
|
||||
convert_primary_lights(dstbin, &dstbinpos, srcbin, &srcbinpos, infsize);
|
||||
host_primary_header->ptr_bgcmds = dstbinpos + 0x0f000000;
|
||||
srcbinpos = src_bgcmds;
|
||||
convert_primary_bgcmds(dstbin, &dstbinpos, srcbin, &srcbinpos, dst_portalvtxs, src_portalvtxs);
|
||||
|
||||
// Convert room gfxdata
|
||||
uint32_t n64_primary_diff = n64_header->primary_infsize - n64_header->primary_cmpsize;
|
||||
struct n64_room *n64_rooms = (struct n64_room *) &src[sizeof(*n64_header)];
|
||||
struct host_room *host_rooms = (struct host_room *) &dst[dstbinpos];
|
||||
|
||||
uint8_t *roomgfxbuf = calloc(1, 1024 * 1024);
|
||||
uint8_t *allcmp = calloc(1, 1024 * 1024);
|
||||
int roomgfxbufpos = 0;
|
||||
uint32_t n64_primary_diff = srctoh32(n64_header->primary_infsize) - srctoh32(n64_header->primary_cmpsize) - 0xc;
|
||||
struct n64_room *n64_rooms = (struct n64_room *) &srcbin[sizeof(struct n64_primaryheader)];
|
||||
struct host_room *host_rooms = (struct host_room *) &dstbin[sizeof(struct host_primaryheader)];
|
||||
|
||||
uint8_t *roomgfxbuf = calloc(1, (size_t)1024 * 1024);
|
||||
uint8_t *allcmp = calloc(1, (size_t)1024 * 1024);
|
||||
int cmppos = 0;
|
||||
|
||||
//for (int i = 0; i < m_NumRooms; i++) {
|
||||
// host_rooms[i].ptr_gfxdata = dstbinpos + cmppos;
|
||||
host_rooms[0].ptr_gfxdata = 0;
|
||||
for (int i = 1; i <= m_NumRooms; i++) {
|
||||
host_rooms[i].ptr_gfxdata = dstbinpos + cmppos + 0x0f000000;
|
||||
|
||||
// srcpos = srctoh32(n64_rooms[i].ptr_gfxdata) - n64_primary_diff;
|
||||
// roomgfxbufpos = convert_section1_roomgfxdata(roomgfxbuf, 0, src, srcpos);
|
||||
if (i == m_NumRooms) break;
|
||||
|
||||
// size_t ziplen = 0;
|
||||
// ret = rzip_deflate(&allcmp[cmppos], &ziplen, roomgfxbuf, roomgfxbufpos);
|
||||
uint32_t gfxdatacompsize = srctoh32(n64_rooms[i + 1].ptr_gfxdata) - srctoh32(n64_rooms[i].ptr_gfxdata);
|
||||
srcpos = srctoh32(n64_rooms[i].ptr_gfxdata) - n64_primary_diff - 0x0f000000;
|
||||
uint32_t src_roomoffset = srctoh32(n64_rooms[i].ptr_gfxdata);
|
||||
uint32_t roomgfxbufpos = convert_section1_roomgfxdata(roomgfxbuf, 0, src+srcpos, gfxdatacompsize, src_roomoffset, dstbinpos + cmppos);
|
||||
|
||||
// if (ret < 0) {
|
||||
// fprintf(stderr, "Unable to compress BG roomgfxdata for room 0x%x: %d\n", i, ret);
|
||||
// exit(EXIT_FAILURE);
|
||||
// }
|
||||
size_t ziplen = 0;
|
||||
ret = rzip_deflate(&allcmp[cmppos], &ziplen, roomgfxbuf, roomgfxbufpos);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Unable to compress BG roomgfxdata for room 0x%x: %d\n", i, ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// ziplen = ALIGN16(ziplen);
|
||||
// cmppos += ziplen;
|
||||
//}
|
||||
ziplen = ALIGN16(ziplen);
|
||||
cmppos += ziplen;
|
||||
|
||||
m_AllocSizes[i - 1] = roomgfxbufpos + (ziplen > m_SizeGDLs ? ziplen*4 : m_SizeGDLs*4);
|
||||
}
|
||||
|
||||
host_rooms[m_NumRooms+1].ptr_gfxdata = 0;
|
||||
|
||||
// Zip primary
|
||||
size_t ziplen = 0;
|
||||
@@ -392,7 +676,7 @@ static void convert_section3_allocsizes(uint8_t *dst, uint32_t *dstpos, uint8_t
|
||||
uint16_t *dst_sizes = (uint16_t *) &dst[*dstpos];
|
||||
|
||||
for (int i = 0; i < m_NumRooms; i++) {
|
||||
dst_sizes[i] = m_AllocSizes[i];
|
||||
dst_sizes[i] = (m_AllocSizes[i] - 0x100) / 0x10;
|
||||
}
|
||||
|
||||
*srcpos += sizeof(uint16_t) * (m_NumRooms - 1);
|
||||
@@ -465,11 +749,17 @@ void extract_file_bg(char *filename, uint32_t romoffset, size_t len)
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
if (strcmp(filename, "ob/ob_mid.seg") == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t dstlen = len * 2;
|
||||
uint8_t *dst = calloc(1, dstlen);
|
||||
uint32_t dstpos = 0;
|
||||
m_NumPtrMarkers = 0;
|
||||
m_SizeGDLs = 0;
|
||||
gbi_reset();
|
||||
|
||||
printf("--------------------------------------------------------------------------------\n");
|
||||
printf("-- %s\n", filename);
|
||||
@@ -489,6 +779,8 @@ void extract_file_bg(char *filename, uint32_t romoffset, size_t len)
|
||||
dstpos = convert_zipped_section(3, dst, dstpos, src, n64_section3_start + sizeof(*n64_section3header), n64_section3header);
|
||||
dstpos = ALIGN16(dstpos);
|
||||
|
||||
sysLogPrintf(LOG_NOTE, "%s %d %d %.3f", filename, len, dstpos, (f32)dstpos / len);
|
||||
|
||||
char outfilename[1024];
|
||||
sprintf(outfilename, "%s/files/%s", g_OutPath, filename);
|
||||
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "system.h"
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#undef near
|
||||
#undef far
|
||||
|
||||
enum contenttype {
|
||||
/* 0*/ CT_MODELDEF,
|
||||
@@ -45,7 +51,7 @@ struct alignconfig m_AlignConfigs[] = {
|
||||
/* 2*/ { 4, 4 },
|
||||
/* 3*/ { 8, 8 },
|
||||
/* 4*/ { 4, 4 },
|
||||
/* 5*/ { 4, 8 },
|
||||
/* 5*/ { 8, 8 },
|
||||
/* 6*/ { 8, 8 },
|
||||
/* 7*/ { 4, 4 },
|
||||
/* 8*/ { 4, 4 },
|
||||
@@ -396,6 +402,8 @@ static void populate_markers(uint8_t *src)
|
||||
for (int i = 0; i < m_NumMarkers; i++) {
|
||||
struct marker *marker = &m_Markers[i];
|
||||
void *src_thing = &src[marker->src_offset];
|
||||
int numvtx = 0;
|
||||
uint32_t colstart = 0;
|
||||
|
||||
switch (marker->type) {
|
||||
case CT_MODELDEF:
|
||||
@@ -439,9 +447,14 @@ static void populate_markers(uint8_t *src)
|
||||
break;
|
||||
case CT_RODATA_GUNDL:
|
||||
struct src_rodata_gundl *src_gundl = src_thing;
|
||||
numvtx = srctoh16(src_gundl->numvertices);
|
||||
colstart = srctoh32(src_gundl->ptr_vertices) + numvtx * 12;
|
||||
colstart = ALIGN(colstart, m_AlignConfigs[marker->type].before);
|
||||
|
||||
set_marker(srctoh32(src_gundl->ptr_opagdl), CT_GDL, marker->src_offset);
|
||||
set_marker(srctoh32(src_gundl->ptr_xlugdl), CT_GDL, marker->src_offset);
|
||||
set_marker(srctoh32(src_gundl->ptr_vertices), CT_VTXCOL, marker->src_offset);
|
||||
set_marker(colstart, CT_VTXCOL, marker->src_offset);
|
||||
break;
|
||||
case CT_RODATA_DISTANCE:
|
||||
struct src_rodata_distance *src_dist = src_thing;
|
||||
@@ -462,11 +475,18 @@ static void populate_markers(uint8_t *src)
|
||||
break;
|
||||
case CT_RODATA_STARGUNFIRE:
|
||||
struct src_rodata_stargunfire *src_stargunfire = src_thing;
|
||||
numvtx = srctoh16(src_stargunfire->unk00);
|
||||
|
||||
set_marker(srctoh32(src_stargunfire->ptr_vertices), CT_VTXCOL, marker->src_offset);
|
||||
set_marker(srctoh32(src_stargunfire->ptr_vertices) + numvtx * 12, CT_VTXCOL, marker->src_offset);
|
||||
set_marker(srctoh32(src_stargunfire->ptr_gdl), CT_GDL, marker->src_offset);
|
||||
break;
|
||||
case CT_RODATA_DL:
|
||||
struct src_rodata_dl *src_dl = src_thing;
|
||||
numvtx = srctoh16(src_dl->numvertices);
|
||||
colstart = srctoh32(src_dl->ptr_vertices) + numvtx * 12;
|
||||
colstart = ALIGN(colstart, 8);
|
||||
|
||||
set_marker(srctoh32(src_dl->ptr_opagdl), CT_GDL, marker->src_offset);
|
||||
set_marker(srctoh32(src_dl->ptr_xlugdl), CT_GDL, marker->src_offset);
|
||||
set_marker(srctoh32(src_dl->ptr_colours), CT_VTXCOL, marker->src_offset);
|
||||
@@ -609,10 +629,7 @@ static uint32_t convert_content(uint8_t *dst, uint8_t *src, uint32_t src_file_le
|
||||
dst_vtx = dsttoh32(dst_rodata->ptr_vertices) & 0x00ffffff;
|
||||
}
|
||||
|
||||
gbi_set_vtx(src_vtx, dst_vtx);
|
||||
gbi_set_segment(0x04, dst_vtx);
|
||||
gbi_set_segment(0x05, 0);
|
||||
dstpos = gbi_convert_gdl(dst, dstpos, src, marker->src_offset);
|
||||
dstpos = gbi_convert_gdl(dst, dstpos, src, marker->src_offset, 0);
|
||||
break;
|
||||
case CT_RODATA_CHRINFO:
|
||||
struct generic_rodata_chrinfo *src_chrinfo = src_thing;
|
||||
@@ -803,6 +820,7 @@ static void relink_pointers(uint8_t *dst, uint8_t *src)
|
||||
struct dst_texconfig *dst_texconfig = dst_thing;
|
||||
if ((srctoh32(src_texconfig->ptr) & 0xff000000) == 0x05000000) {
|
||||
dst_texconfig->ptr = htodst32(resolve_pointer(srctoh32(src_texconfig->ptr)));
|
||||
gbi_add_tex_addr(srctoh32(src_texconfig->ptr), dst_texconfig->ptr);
|
||||
}
|
||||
break;
|
||||
case CT_PARTS:
|
||||
@@ -825,6 +843,17 @@ static void relink_pointers(uint8_t *dst, uint8_t *src)
|
||||
dst_gundl->ptr_opagdl = htodst32(resolve_pointer(srctoh32(src_gundl->ptr_opagdl)));
|
||||
dst_gundl->ptr_xlugdl = htodst32(resolve_pointer(srctoh32(src_gundl->ptr_xlugdl)));
|
||||
dst_gundl->ptr_vertices = htodst32(resolve_pointer(srctoh32(src_gundl->ptr_vertices)));
|
||||
|
||||
gbi_convert_vtx(dst, dst_gundl->ptr_vertices & 0x00ffffff, dst_gundl->numvertices);
|
||||
|
||||
gbi_set_vtx(srctoh32(src_gundl->ptr_vertices), dst_gundl->ptr_vertices);
|
||||
gbi_set_segment(0x04, dst_gundl->ptr_vertices);
|
||||
|
||||
gbi_gdl_rewrite_addrs(dst, dst_gundl->ptr_opagdl);
|
||||
gbi_gdl_rewrite_addrs(dst, dst_gundl->ptr_xlugdl);
|
||||
|
||||
if (dst_gundl->ptr_opagdl) dst_gundl->ptr_opagdl |= 1;
|
||||
if (dst_gundl->ptr_xlugdl) dst_gundl->ptr_xlugdl |= 1;
|
||||
break;
|
||||
case CT_RODATA_DISTANCE:
|
||||
struct src_rodata_distance *src_dist = src_thing;
|
||||
@@ -841,6 +870,9 @@ static void relink_pointers(uint8_t *dst, uint8_t *src)
|
||||
struct src_rodata_chrgunfire *src_chrgunfire = src_thing;
|
||||
struct dst_rodata_chrgunfire *dst_chrgunfire = dst_thing;
|
||||
dst_chrgunfire->ptr_texture = htodst32(resolve_pointer(srctoh32(src_chrgunfire->ptr_texture)));
|
||||
if ((srctoh32(dst_chrgunfire->ptr_texture) & 0xff000000) == 0x05000000) {
|
||||
gbi_add_tex_addr(srctoh32(dst_chrgunfire->ptr_texture), dst_chrgunfire->ptr_texture);
|
||||
}
|
||||
break;
|
||||
case CT_RODATA_TOGGLE:
|
||||
struct src_rodata_toggle *src_toggle = src_thing;
|
||||
@@ -852,6 +884,13 @@ static void relink_pointers(uint8_t *dst, uint8_t *src)
|
||||
struct dst_rodata_stargunfire *dst_stargunfire = dst_thing;
|
||||
dst_stargunfire->ptr_vertices = htodst32(resolve_pointer(srctoh32(src_stargunfire->ptr_vertices)));
|
||||
dst_stargunfire->ptr_gdl = htodst32(resolve_pointer(srctoh32(src_stargunfire->ptr_gdl)));
|
||||
|
||||
gbi_convert_vtx(dst, dst_stargunfire->ptr_vertices & 0x00ffffff, dst_stargunfire->unk00);
|
||||
|
||||
gbi_set_vtx(srctoh32(src_stargunfire->ptr_vertices), dst_stargunfire->ptr_vertices);
|
||||
gbi_set_segment(0x04, dst_stargunfire->ptr_vertices);
|
||||
gbi_gdl_rewrite_addrs(dst, dst_stargunfire->ptr_gdl);
|
||||
if (dst_stargunfire->ptr_gdl) dst_stargunfire->ptr_gdl |= 1;
|
||||
break;
|
||||
case CT_RODATA_DL:
|
||||
struct src_rodata_dl *src_dl = src_thing;
|
||||
@@ -860,6 +899,16 @@ static void relink_pointers(uint8_t *dst, uint8_t *src)
|
||||
dst_dl->ptr_xlugdl = htodst32(resolve_pointer(srctoh32(src_dl->ptr_xlugdl)));
|
||||
dst_dl->ptr_colours = htodst32(resolve_pointer(srctoh32(src_dl->ptr_colours)));
|
||||
dst_dl->ptr_vertices = htodst32(resolve_pointer(srctoh32(src_dl->ptr_vertices)));
|
||||
|
||||
gbi_convert_vtx(dst, dst_dl->ptr_vertices & 0x00ffffff, dst_dl->numvertices);
|
||||
|
||||
gbi_set_vtx(srctoh32(src_dl->ptr_vertices), dst_dl->ptr_vertices);
|
||||
gbi_set_segment(0x04, dst_dl->ptr_vertices);
|
||||
gbi_gdl_rewrite_addrs(dst, dst_dl->ptr_opagdl);
|
||||
gbi_gdl_rewrite_addrs(dst, dst_dl->ptr_xlugdl);
|
||||
|
||||
if (dst_dl->ptr_opagdl) dst_dl->ptr_opagdl |= 1;
|
||||
if (dst_dl->ptr_xlugdl) dst_dl->ptr_xlugdl |= 1;
|
||||
break;
|
||||
case CT_TEXDATA:
|
||||
case CT_VTXCOL:
|
||||
@@ -904,6 +953,7 @@ static int convert_model(uint8_t *dst, uint8_t *src, uint32_t srclen)
|
||||
|
||||
void extract_file_model(char *filename, uint32_t romoffset, size_t len)
|
||||
{
|
||||
gbi_reset();
|
||||
// Unzip it
|
||||
size_t infsize = rzip_get_infsize(&g_Rom[romoffset]);
|
||||
uint8_t *src = malloc(infsize);
|
||||
@@ -916,7 +966,7 @@ void extract_file_model(char *filename, uint32_t romoffset, size_t len)
|
||||
}
|
||||
|
||||
// Convert it
|
||||
uint8_t *dst = calloc(1, infsize * 4);
|
||||
uint8_t *dst = calloc(1, infsize * 2);
|
||||
|
||||
int dstpos = convert_model(dst, src, infsize);
|
||||
|
||||
@@ -942,6 +992,8 @@ void extract_file_model(char *filename, uint32_t romoffset, size_t len)
|
||||
char outfilename[1024];
|
||||
sprintf(outfilename, "%s/files/%s", g_OutPath, filename);
|
||||
|
||||
sysLogPrintf(LOG_NOTE, "%s %d %d %.3f", filename, infsize, dstpos, (f32)dstpos/infsize);
|
||||
|
||||
FILE *fp = openfile(outfilename);
|
||||
fwrite(zipped, ziplen, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
+98
-88
@@ -21,71 +21,69 @@ struct vtx {
|
||||
int16_t t;
|
||||
};
|
||||
|
||||
struct texaddr {
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
};
|
||||
|
||||
uint32_t m_Segments[16];
|
||||
uint8_t m_Seen[1024];
|
||||
uint32_t m_SrcVtxOffset;
|
||||
uint32_t m_DstVtxOffset;
|
||||
|
||||
struct texaddr m_TexAddrs[64];
|
||||
int m_NumTexAddr;
|
||||
|
||||
void gbi_reset(void)
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(m_Segments); i++) {
|
||||
m_Segments[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAYCOUNT(m_Seen); i++) {
|
||||
m_Seen[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
m_SrcVtxOffset = 0;
|
||||
m_DstVtxOffset = 0;
|
||||
m_NumTexAddr = 0;
|
||||
}
|
||||
|
||||
void gbi_set_segment(int segment, uint32_t offset)
|
||||
{
|
||||
m_Segments[segment] = offset;
|
||||
m_Segments[segment] = offset & 0x00ffffff;
|
||||
}
|
||||
|
||||
void gbi_set_vtx(uint32_t src_offset, uint32_t dst_offset)
|
||||
{
|
||||
m_SrcVtxOffset = src_offset;
|
||||
m_DstVtxOffset = dst_offset;
|
||||
m_SrcVtxOffset = src_offset & 0x00ffffff;
|
||||
m_DstVtxOffset = dst_offset & 0x00ffffff;
|
||||
}
|
||||
|
||||
static void gbi_convert_col(uint8_t *dst, uint32_t dstpos, int count)
|
||||
void gbi_add_tex_addr(uint32_t src_offset, uint32_t dst_offset)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
int index = dstpos / 4;
|
||||
m_TexAddrs[m_NumTexAddr].src = src_offset & 0x00ffffff;
|
||||
m_TexAddrs[m_NumTexAddr++].dst = dst_offset & 0x00ffffff;
|
||||
}
|
||||
|
||||
if (!m_Seen[index]) {
|
||||
uint32_t *col = (uint32_t *) &dst[dstpos];
|
||||
|
||||
*col = srctodst32(*col);
|
||||
|
||||
m_Seen[index] = 1;
|
||||
}
|
||||
|
||||
dstpos += sizeof(uint32_t);
|
||||
uint32_t gbi_find_tex_addr(uint32_t src_offset)
|
||||
{
|
||||
for (int i = 0; i < m_NumTexAddr; i++) {
|
||||
if (m_TexAddrs[i].src == src_offset)
|
||||
return m_TexAddrs[i].dst;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gbi_convert_vtx(uint8_t *dst, uint32_t dstpos, int count)
|
||||
void gbi_convert_vtx(uint8_t *dst, uint32_t offset, int count)
|
||||
{
|
||||
if (!offset) return;
|
||||
struct vtx* vtxs = (struct vtx*)(dst + offset);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int index = dstpos / 4;
|
||||
struct vtx* vtx = &vtxs[i];
|
||||
|
||||
if (!m_Seen[index]) {
|
||||
struct vtx *vtx = (struct vtx *) &dst[dstpos];
|
||||
|
||||
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);
|
||||
|
||||
m_Seen[index] = 1;
|
||||
}
|
||||
|
||||
dstpos += 12;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,93 +92,105 @@ static void gbi_convert_vtx(uint8_t *dst, uint32_t dstpos, int count)
|
||||
#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_MOVEWORD(cmd) \
|
||||
|| CMD_IS_SETTIMG(cmd)
|
||||
|
||||
static void gbi_convert_vtx_by_cmd(uint64_t cmd, uint8_t *dst)
|
||||
{
|
||||
uint8_t segment = cmd & 0xff000000;
|
||||
uint8_t offset = cmd & 0x00ffffff;
|
||||
uint32_t num_bytes = (cmd >> 32) & 0xffff;
|
||||
int num_vertices = num_bytes / 12;
|
||||
|
||||
if (segment == 5) {
|
||||
uint32_t dst_offset = offset - m_SrcVtxOffset + m_DstVtxOffset;
|
||||
gbi_convert_vtx(dst, dst_offset, num_vertices);
|
||||
} else {
|
||||
gbi_convert_vtx(dst, m_Segments[segment] + offset, num_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
static void gbi_convert_col_by_cmd(uint64_t cmd, uint8_t *dst)
|
||||
{
|
||||
uint8_t segment = cmd & 0xff000000;
|
||||
uint8_t offset = cmd & 0x00ffffff;
|
||||
uint32_t num_bytes = (cmd >> 32) & 0xffff;
|
||||
int num_colours = num_bytes / 4;
|
||||
|
||||
if (segment == 5) {
|
||||
uint32_t dst_offset = offset - m_SrcVtxOffset + m_DstVtxOffset;
|
||||
gbi_convert_col(dst, dst_offset, num_colours);
|
||||
} else {
|
||||
gbi_convert_col(dst, m_Segments[segment] + offset, num_colours);
|
||||
}
|
||||
}
|
||||
#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 uint64_t gbi_rewrite_addr(uint64_t cmd)
|
||||
static uint64_t gbi_rewrite_addr(uint64_t cmd, uint8_t opcode)
|
||||
{
|
||||
uint8_t segment = cmd & 0xff000000;
|
||||
uint8_t offset = cmd & 0x00ffffff;
|
||||
uint8_t segment = (cmd & 0x0f000000) >> 24;
|
||||
uint32_t offset = cmd & 0x00ffffff;
|
||||
|
||||
if (segment == 5) {
|
||||
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);
|
||||
if (opcode == 0xfd) {
|
||||
offset = gbi_find_tex_addr(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;
|
||||
offset = offset - m_SrcVtxOffset + m_DstVtxOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return (cmd & 0xffffffffff000000) | offset;
|
||||
}
|
||||
|
||||
uint32_t gbi_convert_gdl(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t srcpos)
|
||||
void gbi_gdl_rewrite_addrs(uint8_t *dst, uint32_t offset)
|
||||
{
|
||||
if (!offset) return;
|
||||
|
||||
uint64_t *cmds = (uint64_t*)(dst + (offset & 0x00ffffff));
|
||||
if (!cmds) return;
|
||||
|
||||
uint64_t cmd;
|
||||
|
||||
do {
|
||||
cmd = *cmds;
|
||||
|
||||
if (CMD_HAS_ADDR((cmd << 32))) {
|
||||
uint8_t opcode = (cmd >> 24) & 0xff;
|
||||
cmds[1] = gbi_rewrite_addr(cmds[1], opcode);
|
||||
}
|
||||
|
||||
if (CMD_IS_SEGMENTED((cmd << 32))) {
|
||||
cmds[1] |= 1;
|
||||
}
|
||||
|
||||
cmds += 2;
|
||||
} while (!CMD_IS_ENDDL((cmd << 32)));
|
||||
}
|
||||
|
||||
uint32_t gbi_convert_gdl(uint8_t *dst, uint32_t dstpos, uint8_t *src, uint32_t srcpos, int segment_cmds)
|
||||
{
|
||||
dstpos = ALIGN8(dstpos);
|
||||
|
||||
uint64_t *n64_cmd = (uint64_t *) &src[srcpos];
|
||||
uint64_t *host_cmd = (uint64_t *) &dst[dstpos];
|
||||
uint64_t *n64_cmd = (uint64_t*)&src[srcpos];
|
||||
uint64_t *host_cmd = (uint64_t*)&dst[dstpos];
|
||||
uint64_t cmd;
|
||||
|
||||
do {
|
||||
cmd = srctoh64(*n64_cmd);
|
||||
|
||||
#if HOST_DWORDS_PER_CMD == 2
|
||||
if (CMD_HAS_ADDR(cmd)) {
|
||||
cmd = gbi_rewrite_addr(cmd);
|
||||
host_cmd[0] = htodst64(cmd & 0xffffffff00000000);
|
||||
host_cmd[1] = htodst64(cmd & 0x00000000ffffffff);
|
||||
} else {
|
||||
host_cmd[0] = htodst64(cmd);
|
||||
host_cmd[1] = 0;
|
||||
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] = htodst64(cmd);
|
||||
#endif
|
||||
dstpos += sizeof(*host_cmd) * HOST_DWORDS_PER_CMD;
|
||||
|
||||
if (CMD_IS_VTX(cmd)) {
|
||||
gbi_convert_vtx_by_cmd(cmd, dst);
|
||||
} else if (CMD_IS_COL(cmd)) {
|
||||
gbi_convert_col_by_cmd(cmd, dst);
|
||||
if (segment_cmds && CMD_IS_SEGMENTED(cmd)) {
|
||||
host_cmd[0] |= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
dstpos += sizeof(*host_cmd) * HOST_DWORDS_PER_CMD;
|
||||
host_cmd += HOST_DWORDS_PER_CMD;
|
||||
n64_cmd++;
|
||||
} while (!CMD_IS_ENDDL(cmd));
|
||||
|
||||
Reference in new issue
Block a user