mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-24 00:02:43 +02:00
599 lines
16 KiB
C
599 lines
16 KiB
C
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "common.h"
|
|
#include "system.h"
|
|
#include "platform.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 portalvertices {
|
|
u8 count;
|
|
u32 vertices[1][3];
|
|
};
|
|
|
|
struct bgcmd {
|
|
u8 type;
|
|
u8 len;
|
|
s32 param;
|
|
};
|
|
|
|
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 convert_primary_rooms(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 convert_primary_portals(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 portalvertices *n64_pvertices = (struct portalvertices*)&src[*srcpos];
|
|
struct portalvertices *host_pvertices = (struct portalvertices*)&dst[*dstpos];
|
|
|
|
host_pvertices->count = n64_pvertices->count;
|
|
|
|
for (int j = 0; j < host_pvertices->count; j++) {
|
|
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 convert_primary_bgcmds(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 convert_primary_lights(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][0] = srctodst16(n64_lights[i].bbox[j][0]);
|
|
host_lights[i].bbox[j][1] = srctodst16(n64_lights[i].bbox[j][1]);
|
|
host_lights[i].bbox[j][2] = srctodst16(n64_lights[i].bbox[j][2]);
|
|
}
|
|
}
|
|
|
|
*srcpos += sizeof(*n64_lights) * num_lights;
|
|
*dstpos += sizeof(*host_lights) * num_lights;
|
|
}
|
|
|
|
#define BLOCK_LEAF 0
|
|
#define BLOCK_PARENT 1
|
|
|
|
void relink_ptr(uintptr_t** ptr)
|
|
{
|
|
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 u32 convert_section1_roomgfxdata(u8 *dst, u8 *src, u32 infsize, u32 src_ofs)
|
|
{
|
|
reset_markers();
|
|
|
|
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);
|
|
|
|
add_marker(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]);
|
|
|
|
add_marker(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;
|
|
|
|
add_marker(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;
|
|
|
|
add_marker(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
|
|
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_ofs, curpos_dst + dst_roomoffset);
|
|
curpos_dst = gbi_convert_gdl(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];
|
|
|
|
relink_ptr(&block->ptr_next);
|
|
|
|
if (block->type == BLOCK_LEAF) {
|
|
relink_ptr(&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 {
|
|
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);
|
|
|
|
return curpos_dst;
|
|
}
|
|
|
|
static u32 convert_section1(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;
|
|
convert_primary_rooms(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;
|
|
convert_primary_lights(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;
|
|
convert_primary_portals(dst, &dstpos, src, &srcpos, &src_portalvtxs, &dst_portalvtxs);
|
|
|
|
host_primary_header->ptr_bgcmds = dstpos + ofs;
|
|
convert_primary_bgcmds(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);
|
|
}
|
|
|
|
#ifdef PLATFORM_64BIT
|
|
void preprocessBgSection1(u8 *data, u32 size, u32 ofs)
|
|
{
|
|
u8 *dst = sysMemZeroAlloc(size);
|
|
|
|
u32 newSize = convert_section1(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 = convert_section1_roomgfxdata(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;
|
|
}
|
|
#endif |