Extend graphics stacks (fixes OOM crashes) and add recomp_printf

This commit is contained in:
Mr-Wiseguy
2025-02-22 02:39:06 -05:00
parent bfa91bb098
commit b1af6412d2
13 changed files with 873 additions and 3 deletions
+123
View File
@@ -0,0 +1,123 @@
#include "patches.h"
#include "misc_funcs.h"
extern struct {
s32 unk0;
s32 game_mode; //game_mode
f32 unk8;
s32 unkC; //freeze_scene_flag (used for pause menu)
f32 unk10;
u8 transition;
u8 map;
u8 exit;
u8 unk17; //reset_on_map_load
u8 unk18;
u8 unk19;
u8 unk1A;
u8 unk1B;
u8 unk1C;
} D_8037E8E0;
void scissorBox_setDefault(void);
void getGraphicsStacks(Gfx **gfx, Mtx **mtx, Vtx **vtx);
s32 getActiveFramebuffer(void);
void func_802E39D0(Gfx **gdl, Mtx **mptr, Vtx **vptr, s32 framebuffer_idx, s32 arg4);
void viMgr_func_8024C1DC(void);
void func_80253EC4(Gfx *arg0, Gfx *arg1);
void dummy_func_80254464();
// 10x the original sizes.
#define GFX_BUFFER_COUNT 37000
#define MTX_BUFFER_COUNT 7000
#define VTX_BUFFER_COUNT 4300
struct {
Gfx gfx[2][GFX_BUFFER_COUNT];
Mtx mtx[2][MTX_BUFFER_COUNT];
Vtx vtx[2][VTX_BUFFER_COUNT];
} ExtendedBuffers;
extern Gfx *sGfxStack[2];
extern Mtx *sMtxStack[2];
extern Vtx *sVtxStack[2];
extern s32 sStackSelector;
extern s32 gTextureFilterPoint;
extern u32 heap_occupiedBytes;
// @recomp Patched to not free anything.
RECOMP_PATCH void graphicsCache_release(void) {
if (sGfxStack[0]) {
// @recomp Nothing to free, as the extended buffers are statically allocated.
sGfxStack[0] = NULL;
}
}
// @recomp Patched to use the extended buffers for the graphics stacks.
RECOMP_PATCH void graphicsCache_init(void){
if(sGfxStack[0] == NULL){
// @recomp Point the stacks to the extended buffers.
sGfxStack[0] = ExtendedBuffers.gfx[0];
sGfxStack[1] = ExtendedBuffers.gfx[1];
sMtxStack[0] = ExtendedBuffers.mtx[0];
sMtxStack[1] = ExtendedBuffers.mtx[1];
sVtxStack[0] = ExtendedBuffers.vtx[0];
sVtxStack[1] = ExtendedBuffers.vtx[1];
dummy_func_80254464();
}
sStackSelector = 0;
gTextureFilterPoint = 0;
}
// @recomp Patched to check for graphics stack overflow after processing a frame.
RECOMP_PATCH void game_draw(s32 arg0){
Gfx *gfx;
Gfx *gfx_start;
Gfx *sp2C;
Mtx *mtx;
Vtx *vtx;
if(arg0) {
scissorBox_setDefault();
}
getGraphicsStacks(&gfx, &mtx, &vtx);
if(D_8037E8E0.unkC == 1){
getGraphicsStacks(&gfx, &mtx, &vtx);
}
// @recomp Track the original values.
Mtx* mtx_start = mtx;
Vtx* vtx_start = vtx;
gfx_start = gfx;
func_802E39D0(&gfx, &mtx, &vtx, getActiveFramebuffer(), arg0);
// @recomp Check for graphics stack overflow
u32 gfx_count = gfx - gfx_start;
u32 mtx_count = mtx - mtx_start;
u32 vtx_count = vtx - vtx_start;
// recomp_printf("gfx: %-5u mtx: %-5u vtx: %-5u (%06X / %06X)\n", gfx_count, mtx_count, vtx_count, heap_occupiedBytes, 0x210520);
if (gfx_count >= GFX_BUFFER_COUNT) {
recomp_error("Gfx buffer overflow\n");
}
if (mtx_count >= MTX_BUFFER_COUNT) {
recomp_error("Mtx buffer overflow\n");
}
if (vtx_count >= VTX_BUFFER_COUNT) {
recomp_error("Vtx buffer overflow\n");
}
if(D_8037E8E0.unkC == 0){
sp2C = gfx;
viMgr_func_8024C1DC();
func_80253EC4(gfx_start, sp2C);
if(arg0) {
scissorBox_setDefault();
}
}
}
+1
View File
@@ -6,5 +6,6 @@
DECLARE_FUNC(void, recomp_load_overlays, u32 rom, void* ram, u32 size);
DECLARE_FUNC(void, recomp_puts, const char* data, u32 size);
DECLARE_FUNC(void, recomp_exit);
DECLARE_FUNC(void, recomp_error, const char* str);
#endif
+5
View File
@@ -25,11 +25,16 @@ void osWriteBackDCacheAll(void);
#define free free_recomp
#define realloc realloc_recomp
#define memcpy memcpy_recomp
#define strchr strchr_recomp
#define strlen strlen_recomp
#include "ultra64.h"
typedef int bool;
typedef unsigned size_t;
void memcpy(void * dst, void *src, int size);
char* strchr(const char* s, int c);
int recomp_printf(const char* fmt, ...);
#endif
+19
View File
@@ -0,0 +1,19 @@
#include "patches.h"
#include "xstdio.h"
#include "misc_funcs.h"
void* proutPrintf(void* dst, const char* fmt, size_t size) {
recomp_puts(fmt, size);
return (void*)1;
}
RECOMP_EXPORT int recomp_printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int ret = _Printf(&proutPrintf, NULL, fmt, args);
va_end(args);
return ret;
}
+6
View File
@@ -25,3 +25,9 @@ recomp_create_actor_data = 0x8F000050;
recomp_destroy_actor_data = 0x8F000054;
recomp_get_actor_data = 0x8F000058;
recomp_get_actor_spawn_index = 0x8F00005C;
recomp_error = 0x8F000060;
memcpy_recomp = 0x8F000064;
__divdi3_recomp = 0x8F000068;
__udivdi3_recomp = 0x8F00006C;
__umoddi3_recomp = 0x8F000070;
strlen_recomp = 0x8F000074;
+322
View File
@@ -0,0 +1,322 @@
#include "patches.h"
#include "string.h"
#include "xstdio.h"
typedef struct LDIV_T {
long quot;
long rem;
} ldiv_t;
ldiv_t ldiv(long num, long denom) {
ldiv_t ret;
ret.quot = num / denom;
ret.rem = num - denom * ret.quot;
if (ret.quot < 0 && ret.rem > 0) {
ret.quot += 1;
ret.rem -= denom;
}
return ret;
}
#define BUFF_LEN 0x20
static short _Ldunscale(short* pex, ldouble* px);
static void _Genld(_Pft* px, char code, unsigned char* p, short nsig, short xexp);
static const ldouble pows[] = {10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L};
// float properties
#define _D0 0
#define _DBIAS 0x3ff
#define _DLONG 1
#define _DOFF 4
#define _FBIAS 0x7e
#define _FOFF 7
#define _FRND 1
#define _LBIAS 0x3ffe
#define _LOFF 15
// integer properties
#define _C2 1
#define _CSIGN 1
#define _ILONG 0
#define _MBMAX 8
#define NAN 2
#define INF 1
#define FINITE -1
#define _DFRAC ((1 << _DOFF) - 1)
#define _DMASK (0x7fff & ~_DFRAC)
#define _DMAX ((1 << (15 - _DOFF)) - 1)
#define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1))
#define _DSIGN 0x8000
#define _D1 1 // big-endian order
#define _D2 2
#define _D3 3
#define ALIGN(s, align) (((unsigned int)(s) + ((align)-1)) & ~((align)-1))
void _Ldtob(_Pft* px, char code) {
char buff[BUFF_LEN];
char *p;
ldouble ldval;
short err;
short nsig;
short xexp;
p = buff;
ldval = px->v.ld;
if (px->prec < 0) {
px->prec = 6;
} else if (px->prec == 0 && (code == 'g' || code == 'G')) {
px->prec = 1;
}
err = _Ldunscale(&xexp, &px->v.ld);
if (err > 0) {
memcpy(px->s, err == 2 ? "NaN" : "Inf", px->n1 = 3);
return;
} else if (err == 0) {
nsig = 0;
xexp = 0;
} else {
{
int i;
int n;
if (ldval < 0) {
ldval = -ldval;
}
// what
if ((xexp = xexp * 30103 / 100000 - 4) < 0) {
n = ALIGN(-xexp, 4), xexp = -n;
for (i = 0; n > 0; n >>= 1, i++) {
if (n & 1) {
ldval *= pows[i];
}
}
} else if (xexp > 0) {
ldouble factor = 1;
xexp &= ~3;
for (n = xexp, i = 0; n > 0; n >>= 1, i++) {
if (n & 1) {
factor *= pows[i];
}
}
ldval /= factor;
}
}
{
int gen = px->prec + ((code == 'f') ? 10 + xexp : 6);
if (gen > 0x13) {
gen = 0x13;
}
for (*p++ = '0'; gen > 0 && 0 < ldval; p += 8) {
int j;
long lo = ldval;
if ((gen -= 8) > 0) {
ldval = (ldval - lo) * 1e8;
}
for (p += 8, j = 8; lo > 0 && --j >= 0;) {
ldiv_t qr;
qr = ldiv(lo, 10);
*--p = qr.rem + '0', lo = qr.quot;
}
while (--j >= 0) {
*--p = '0';
}
}
gen = p - &buff[1];
for (p = &buff[1], xexp += 7; *p == '0'; p++) {
--gen, --xexp;
}
nsig = px->prec + ((code == 'f') ? xexp + 1 : ((code == 'e' || code == 'E') ? 1 : 0));
if (gen < nsig) {
nsig = gen;
}
if (nsig > 0) {
const char drop = nsig < gen && '5' <= p[nsig] ? '9' : '0';
int n;
for (n = nsig; p[--n] == drop;) {
--nsig;
}
if (drop == '9') {
++p[n];
}
if (n < 0) {
--p, ++nsig, ++xexp;
}
}
}
}
_Genld(px, code, p, nsig, xexp);
}
short _Ldunscale(short* pex, ldouble* px) {
unsigned short* ps = (unsigned short*)px;
short xchar = (ps[_D0] & _DMASK) >> _DOFF;
if (xchar == _DMAX) {
*pex = 0;
return (ps[_D0] & _DFRAC) || ps[_D1] || ps[_D2] || ps[_D3] ? 2 : 1;
} else if (xchar > 0) {
ps[_D0] = (ps[_D0] & ~_DMASK) | 0x3FF0;
*pex = xchar - 0x3FE;
return -1;
} else if (xchar < 0) {
return 2;
} else {
*pex = 0;
return 0;
}
}
void _Genld(_Pft* px, char code, unsigned char* p, short nsig, short xexp) {
const unsigned char point = '.';
if (nsig <= 0) {
nsig = 1, p = "0";
}
if (code == 'f' || (code == 'g' || code == 'G') && xexp >= -4 && xexp < px->prec) {
xexp++;
if (code != 'f') {
if (((px->flags & 8) == 0) && nsig < px->prec) {
px->prec = nsig;
}
if ((px->prec -= xexp) < 0) {
px->prec = 0;
}
}
if (xexp <= 0) {
px->s[px->n1++] = '0';
if (px->prec > 0 || (px->flags & 8)) {
px->s[px->n1++] = point;
}
if (px->prec < -xexp) {
xexp = -px->prec;
}
px->nz1 = -xexp;
px->prec += xexp;
if (px->prec < nsig) {
nsig = px->prec;
}
memcpy(&px->s[px->n1], p, px->n2 = nsig);
px->nz2 = px->prec - nsig;
} else if (nsig < xexp) {
memcpy(&px->s[px->n1], p, nsig);
px->n1 += nsig;
px->nz1 = xexp - nsig;
if (px->prec > 0 || (px->flags & 8)) {
px->s[px->n1] = point;
px->n2++;
}
px->nz2 = px->prec;
} else {
memcpy(&px->s[px->n1], p, xexp);
px->n1 += xexp;
nsig -= xexp;
if (px->prec > 0 || (px->flags & 8)) {
px->s[px->n1++] = point;
}
if (px->prec < nsig) {
nsig = px->prec;
}
memcpy(&px->s[px->n1], &p[xexp], nsig);
px->n1 += nsig;
px->nz1 = px->prec - nsig;
}
} else {
if (code == 'g' || code == 'G') {
if (nsig < px->prec) {
px->prec = nsig;
}
if (--px->prec < 0) {
px->prec = 0;
}
code = (code == 'g') ? 'e' : 'E';
}
px->s[px->n1++] = *p++;
if (px->prec > 0 || (px->flags & 8)) {
px->s[px->n1++] = point;
}
if (px->prec > 0) {
if (px->prec < --nsig) {
nsig = px->prec;
}
memcpy(&px->s[px->n1], p, nsig);
px->n1 += nsig;
px->nz1 = px->prec - nsig;
}
p = &px->s[px->n1];
*p++ = code;
if (xexp >= 0) {
*p++ = '+';
} else {
*p++ = '-';
xexp = -xexp;
}
if (xexp >= 100) {
if (xexp >= 1000) {
*p++ = (xexp / 1000) + '0', xexp %= 1000;
}
*p++ = (xexp / 100) + '0', xexp %= 100;
}
*p++ = (xexp / 10) + '0', xexp %= 10;
*p++ = xexp + '0';
px->n2 = (size_t)p - ((size_t)px->s + px->n1);
}
if ((px->flags & 0x14) == 0x10) {
int n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2;
if (n < px->width) {
px->nz0 = px->width - n;
}
}
}
+78
View File
@@ -0,0 +1,78 @@
#include "patches.h"
#include "string.h"
#include "xstdio.h"
typedef struct lldiv_t
{
long long quot;
long long rem;
} lldiv_t;
extern long long __divdi3_recomp(long long num, long long denom);
extern unsigned long long __udivdi3_recomp(unsigned long long num, unsigned long long denom);
extern unsigned long long __umoddi3_recomp(unsigned long long num, unsigned long long denom);
__attribute__((noinline))
lldiv_t lldiv(long long num, long long denom) {
lldiv_t ret;
ret.quot = __divdi3_recomp(num, denom);
ret.rem = num - denom * ret.quot;
if (ret.quot < 0 && ret.rem > 0) {
ret.quot += 1;
ret.rem -= denom;
}
return ret;
}
#define BUFF_LEN 0x18
static char ldigs[] = "0123456789abcdef";
static char udigs[] = "0123456789ABCDEF";
void _Litob(_Pft *px, char code) {
char buff[BUFF_LEN];
const char *digs;
int base;
int i;
unsigned long long ullval;
digs = (code == 'X') ? udigs : ldigs;
base = (code == 'o') ? 8 : ((code != 'x' && code != 'X') ? 10 : 16);
i = BUFF_LEN;
ullval = px->v.ll;
if ((code == 'd' || code == 'i') && px->v.ll < 0) {
ullval = -ullval;
}
if (ullval != 0 || px->prec != 0) {
buff[--i] = digs[__umoddi3_recomp(ullval, base)];
}
px->v.ll = (long long)__udivdi3_recomp(ullval, base);
while (px->v.ll > 0 && i > 0) {
lldiv_t qr = lldiv(px->v.ll, base);
px->v.ll = qr.quot;
buff[--i] = digs[qr.rem];
}
px->n1 = BUFF_LEN - i;
memcpy(px->s, buff + i, px->n1);
if (px->n1 < px->prec) {
px->nz0 = px->prec - px->n1;
}
if (px->prec < 0 && (px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) {
if ((i = px->width - px->n0 - px->nz0 - px->n1) > 0) {
px->nz0 += i;
}
}
}
+262
View File
@@ -0,0 +1,262 @@
#include "patches.h"
#include "string.h"
#include "stdarg.h"
#include "xstdio.h"
char* strchr(const char* s, int c) {
const char ch = c;
while (*s != ch) {
if (*s == 0) {
return NULL;
}
s++;
}
return (char*)s;
}
#define isdigit(x) ((x >= '0' && x <= '9'))
#define LDSIGN(x) (((unsigned short *)&(x))[0] & 0x8000)
#define ATOI(dst, src) \
for (dst = 0; isdigit(*src); ++src) \
{ \
if (dst < 999) \
dst = dst * 10 + *src - '0'; \
}
#define MAX_PAD ((sizeof(spaces) - 1))
#define PAD(s, n) \
if (0 < (n)) \
{ \
int i, j = (n); \
for (; 0 < j; j -= i) \
{ \
i = MAX_PAD < (unsigned int)j ? (int)MAX_PAD : j; \
PUT(s, i); \
} \
}
#define PUT(s, n) \
if (0 < (n)) \
{ \
if ((arg = (*pfn)(arg, s, n)) != NULL) \
x.nchar += (n); \
else \
return x.nchar; \
}
static char spaces[] = " ";
static char zeroes[] = "00000000000000000000000000000000";
static void _Putfld(_Pft *px, va_list *pap, char code, char *ac);
int _Printf(void* pfn(void*,const char*,size_t), void *arg, const char *fmt, va_list ap) {
_Pft x;
x.nchar = 0;
while (1) {
const char *s;
char c;
const char *t;
static const char fchar[] = {' ', '+', '-', '#', '0', '\0'};
static const unsigned int fbit[] = {FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0};
char ac[32];
s = fmt;
for (c = *s; c != 0 && c != '%';) {
c = *++s;
}
PUT(fmt, s - fmt);
if (c == 0) {
return x.nchar;
}
fmt = ++s;
for (x.flags = 0; (t = strchr(fchar, *s)) != NULL; s++) {
x.flags |= fbit[t - fchar];
}
if (*s == '*') {
x.width = va_arg(ap, int);
if (x.width < 0) {
x.width = -x.width;
x.flags |= FLAGS_MINUS;
}
s++;
} else
ATOI(x.width, s);
if (*s != '.') {
x.prec = -1;
} else if (*++s == '*') {
x.prec = va_arg(ap, int);
++s;
} else
for (x.prec = 0; isdigit(*s); s++) {
if (x.prec < 999)
x.prec = x.prec * 10 + *s - '0';
}
x.qual = strchr("hlL", *s) ? *s++ : '\0';
if (x.qual == 'l' && *s == 'l') {
x.qual = 'L';
++s;
}
_Putfld(&x, &ap, *s, ac);
x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + x.n2 + x.nz2;
{
if (!(x.flags & FLAGS_MINUS)) {
int i, j;
if (0 < (x.width))
{
i, j = x.width;
for (; 0 < j; j -= i)
{
i = MAX_PAD < (unsigned int)j ? (int)MAX_PAD : j;
PUT(spaces, i);
}
}
}
PUT(ac, x.n0);
PAD(zeroes, x.nz0)
PUT(x.s, x.n1);
PAD(zeroes, x.nz1);
PUT(x.s + x.n1, x.n2);
PAD(zeroes, x.nz2);
if (x.flags & FLAGS_MINUS) {
PAD(spaces, x.width);
}
}
fmt = s + 1;
}
return 0;
}
static void _Putfld(_Pft *px, va_list *pap, char code, char *ac) {
px->n0 = px->nz0 = px->n1 = px->nz1 = px->n2 =
px->nz2 = 0;
switch (code) {
case 'c':
ac[px->n0++] = va_arg(*pap, int);
break;
case 'd':
case 'i':
if (px->qual == 'l') {
px->v.ll = va_arg(*pap, long);
} else if (px->qual == 'L') {
px->v.ll = va_arg(*pap, long long);
} else {
px->v.ll = va_arg(*pap, int);
}
if (px->qual == 'h') {
px->v.ll = (short)px->v.ll;
}
if (px->v.ll < 0) {
ac[px->n0++] = '-';
} else if (px->flags & FLAGS_PLUS) {
ac[px->n0++] = '+';
} else if (px->flags & FLAGS_SPACE) {
ac[px->n0++] = ' ';
}
px->s = (char *)&ac[px->n0];
_Litob(px, code);
break;
case 'x':
case 'X':
case 'u':
case 'o':
if (px->qual == 'l') {
px->v.ll = va_arg(*pap, long);
} else if (px->qual == 'L') {
px->v.ll = va_arg(*pap, long long);
} else {
px->v.ll = va_arg(*pap, int);
}
if (px->qual == 'h') {
px->v.ll = (unsigned short)px->v.ll;
} else if (px->qual == 0) {
px->v.ll = (unsigned int)px->v.ll;
}
if (px->flags & FLAGS_HASH) {
ac[px->n0++] = '0';
if (code == 'x' || code == 'X') {
ac[px->n0++] = code;
}
}
px->s = (char *)&ac[px->n0];
_Litob(px, code);
break;
case 'e':
case 'f':
case 'g':
case 'E':
case 'G':
px->v.ld = px->qual == 'L' ? va_arg(*pap, ldouble) : va_arg(*pap, double);
if (LDSIGN(px->v.ld))
ac[px->n0++] = '-';
else if (px->flags & FLAGS_PLUS)
ac[px->n0++] = '+';
else if (px->flags & FLAGS_SPACE)
ac[px->n0++] = ' ';
px->s = (char *)&ac[px->n0];
_Ldtob(px, code);
break;
case 'n':
if (px->qual == 'h') {
*va_arg(*pap, unsigned short *) = px->nchar;
} else if (px->qual == 'l') {
*va_arg(*pap, unsigned long *) = px->nchar;
} else if (px->qual == 'L') {
*va_arg(*pap, unsigned long long *) = px->nchar;
} else {
*va_arg(*pap, unsigned int *) = px->nchar;
}
break;
case 'p':
px->v.ll = (long)va_arg(*pap, void *);
px->s = (char *)&ac[px->n0];
_Litob(px, 'x');
break;
case 's':
px->s = va_arg(*pap, char *);
px->n1 = strlen(px->s);
if (px->prec >= 0 && px->prec < px->n1) {
px->n1 = px->prec;
}
break;
case '%':
ac[px->n0++] = '%';
break;
default:
ac[px->n0++] = code;
break;
}
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef _XSTDIO_H
#define _XSTDIO_H
#include "stdarg.h"
#ifdef __sgi
typedef double ldouble; // IDO does not support long doubles
#else
typedef long double ldouble;
#endif
typedef struct {
/* 0x0 */ union {
/* 0x0 */ long long ll;
/* 0x0 */ ldouble ld;
} v;
/* 0x8 */ unsigned char* s;
/* 0xC */ int n0;
/* 0x10 */ int nz0;
/* 0x14 */ int n1;
/* 0x18 */ int nz1;
/* 0x1C */ int n2;
/* 0x20 */ int nz2;
/* 0x24 */ int prec;
/* 0x28 */ int width;
/* 0x2C */ size_t nchar;
/* 0x30 */ unsigned int flags;
/* 0x34 */ char qual;
} _Pft;
#define FLAGS_SPACE 1
#define FLAGS_PLUS 2
#define FLAGS_MINUS 4
#define FLAGS_HASH 8
#define FLAGS_ZERO 16
int _Printf(void* pfn(void*,const char*,size_t), void *arg, const char *fmt, va_list ap);
void _Litob(_Pft *px, char code);
void _Ldtob(_Pft* px, char code);
#endif
+13
View File
@@ -32,6 +32,19 @@ extern "C" void recomp_exit(uint8_t* rdram, recomp_context* ctx) {
ultramodern::quit();
}
extern "C" void recomp_error(uint8_t* rdram, recomp_context* ctx) {
std::string str{};
PTR(u8) str_ptr = _arg<0, PTR(u8)>(rdram, ctx);
for (size_t i = 0; MEM_B(str_ptr, i) != '\x00'; i++) {
str += (char)MEM_B(str_ptr, i);
}
recompui::message_box(str.c_str());
assert(false);
ultramodern::error_handling::quick_exit(__FILE__, __LINE__, __FUNCTION__);
}
extern "C" void recomp_get_gyro_deltas(uint8_t* rdram, recomp_context* ctx) {
float* x_out = _arg<0, float*>(rdram, ctx);
float* y_out = _arg<1, float*>(rdram, ctx);
-2
View File
@@ -4,7 +4,6 @@
#include "librecomp/game.hpp"
#include "banjo_game.h"
#include "recomp_data.h"
#ifdef _MSC_VER
inline uint32_t byteswap(uint32_t val) {
@@ -121,5 +120,4 @@ std::vector<uint8_t> banjo::decompress_bk(std::span<const uint8_t> compressed_ro
void banjo::bk_on_init(uint8_t* rdram, recomp_context* ctx) {
MEM_W(0, (int32_t)0x80000310) = 6103;
recomp::do_rom_read(rdram, (int32_t)0x80000000, 0x100004C0, 0x2A4);
recomp::init_extended_actor_data();
}
+2
View File
@@ -26,6 +26,7 @@
#include "banjo_sound.h"
#include "banjo_render.h"
#include "banjo_game.h"
#include "recomp_data.h"
#include "ovl_patches.hpp"
#include "librecomp/game.hpp"
#include "librecomp/mods.hpp"
@@ -586,6 +587,7 @@ int main(int argc, char** argv) {
banjo::register_bk_overlays();
banjo::register_bk_patches();
recomp::init_extended_actor_data();
banjo::load_config();
recomp::rsp::callbacks_t rsp_callbacks{