subrepo:
  subdir:   "soh"
  merged:   "ba904bbd0"
upstream:
  origin:   "https://github.com/HarbourMasters/soh.git"
  branch:   "master"
  commit:   "ba904bbd0"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
This commit is contained in:
M4xw 2022-03-22 02:51:23 +01:00
parent 0bb0e7b53b
commit 39cc86c260
2466 changed files with 451557 additions and 0 deletions

569
soh/src/code/PreRender.c Normal file
View file

@ -0,0 +1,569 @@
#include "global.h"
#include "alloca.h"
#include <string.h>
void PreRender_SetValuesSave(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg) {
this->widthSave = width;
this->heightSave = height;
this->fbufSave = fbuf;
this->cvgSave = cvg;
this->zbufSave = zbuf;
this->ulxSave = 0;
this->ulySave = 0;
this->lrxSave = width - 1;
this->lrySave = height - 1;
}
void PreRender_Init(PreRender* this) {
memset(this,0, sizeof(PreRender));
ListAlloc_Init(&this->alloc);
}
void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf) {
this->width = width;
this->height = height;
this->fbuf = fbuf;
this->zbuf = zbuf;
this->ulx = 0;
this->uly = 0;
this->lrx = width - 1;
this->lry = height - 1;
}
void PreRender_Destroy(PreRender* this) {
ListAlloc_FreeAll(&this->alloc);
}
void func_800C0F28(PreRender* this, Gfx** gfxp, void* buf, void* bufSave) {
Gfx* gfx;
s32 x;
s32 x2;
s32 dx;
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 215);
LogUtils_CheckNullPointer("glistpp", gfxp, "../PreRender.c", 216);
gfx = *gfxp;
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 218);
gDPPipeSync(gfx++);
gDPSetOtherMode(gfx++,
G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, bufSave);
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, this->width, this->height);
dx = 0x1000 / (this->width * 2);
x = this->height;
x2 = 0;
while (x > 0) {
s32 uls = 0;
s32 lrs = this->width - 1;
s32 ult;
s32 lrt;
dx = CLAMP_MAX(dx, x);
ult = x2;
lrt = (ult + dx) - 1;
gDPLoadTextureTile(gfx++, buf, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->height, uls, ult, lrs, lrt, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
gSPTextureRectangle(gfx++, uls << 2, ult << 2, lrs << 2, lrt << 2, G_TX_RENDERTILE, uls << 5, ult << 5, 4 << 10,
1 << 10);
x -= dx;
x2 += dx;
}
gDPPipeSync(gfx++);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf);
*gfxp = gfx;
}
void func_800C1258(PreRender* this, Gfx** gfxp) {
Gfx* gfx;
s32 y;
s32 y2;
s32 dy;
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 278);
LogUtils_CheckNullPointer("glistpp", gfxp, "../PreRender.c", 279);
gfx = *gfxp;
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 281);
gDPPipeSync(gfx++);
gDPSetOtherMode(gfx++,
G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf);
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, this->ulx, this->uly, this->lrx + 1, this->lry + 1);
dy = 0x1000 / ((this->lrxSave - this->ulxSave + 1) * 2);
y = (this->lrySave - this->ulySave) + 1;
y2 = 0;
while (y > 0) {
s32 ult;
s32 lrt;
s32 uly;
dy = CLAMP_MAX(dy, y);
ult = this->ulySave + y2;
lrt = (ult + dy) - 1;
uly = this->uly + y2;
gDPLoadTextureTile(gfx++, this->fbufSave, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->widthSave, this->height - 1,
this->ulxSave, ult, this->lrxSave, lrt, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gfx++, this->ulx << 2, uly << 2, this->lrx << 2, (uly + dy - 1) << 2, G_TX_RENDERTILE,
this->ulxSave << 5, ult << 5, 4 << 10, 1 << 10);
y -= dy;
y2 += dy;
}
gDPPipeSync(gfx++);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf);
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, this->width, this->height);
*gfxp = gfx;
}
void func_800C170C(PreRender* this, Gfx** gfxp, void* fbuf, void* fbufSave, u32 r, u32 g, u32 b, u32 a) {
Gfx* gfx;
s32 x;
s32 x2;
s32 dx;
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 343);
LogUtils_CheckNullPointer("glistpp", gfxp, "../PreRender.c", 344);
gfx = *gfxp;
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 346);
gDPPipeSync(gfx++);
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2);
gDPSetEnvColor(gfx++, r, g, b, a);
gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1);
gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, 1, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, 1);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, fbufSave);
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, this->width, this->height);
dx = 0x1000 / (this->width * 2);
x = this->height;
x2 = 0;
while (x > 0) {
s32 uls = 0;
s32 lrs = this->width - 1;
s32 ult;
s32 lrt;
dx = CLAMP_MAX(dx, x);
ult = x2;
lrt = x2 + dx - 1;
gDPLoadTextureTile(gfx++, fbuf, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->height, uls, ult, lrs, lrt, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5,
ult << 5, 1 << 10, 1 << 10);
x -= dx;
x2 += dx;
}
gDPPipeSync(gfx++);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf);
*gfxp = gfx;
}
void func_800C1AE8(PreRender* this, Gfx** gfxp, void* fbuf, void* fbufSave) {
func_800C170C(this, gfxp, fbuf, fbufSave, 255, 255, 255, 255);
}
void func_800C1B24(PreRender* this, Gfx** gfxp, void* fbuf, void* cvgSave) {
Gfx* gfx;
s32 x;
s32 x2;
s32 dx;
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 422);
LogUtils_CheckNullPointer("glistpp", gfxp, "../PreRender.c", 423);
gfx = *gfxp;
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 425);
gDPPipeSync(gfx++);
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_PASS | G_RM_OPA_CI2);
gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 0, 0, 0, 0, TEXEL0, 0, 0, 0, 0);
gDPSetColorImage(gfx++, G_IM_FMT_I, G_IM_SIZ_8b, this->width, cvgSave);
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, this->width, this->height);
dx = 0x1000 / (this->width * 2);
x = this->height;
x2 = 0;
while (x > 0) {
s32 uls = 0;
s32 lrs = this->width - 1;
s32 ult;
s32 lrt;
dx = CLAMP_MAX(dx, x);
ult = x2;
lrt = x2 + dx - 1;
gDPLoadTextureTile(gfx++, fbuf, G_IM_FMT_IA, G_IM_SIZ_16b, this->width, this->height, uls, ult, lrs, lrt, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5,
ult << 5, 1 << 10, 1 << 10);
x -= dx;
x2 += dx;
}
gDPPipeSync(gfx++);
gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf);
*gfxp = gfx;
}
void func_800C1E9C(PreRender* this, Gfx** gfxp) {
LogUtils_CheckNullPointer("this->zbuf_save", this->zbufSave, "../PreRender.c", 481);
LogUtils_CheckNullPointer("this->zbuf", this->zbuf, "../PreRender.c", 482);
if ((this->zbufSave != NULL) && (this->zbuf != NULL)) {
func_800C0F28(this, gfxp, this->zbuf, this->zbufSave);
}
}
void func_800C1F20(PreRender* this, Gfx** gfxp) {
LogUtils_CheckNullPointer("this->fbuf_save", this->fbufSave, "../PreRender.c", 495);
LogUtils_CheckNullPointer("this->fbuf", this->fbuf, "../PreRender.c", 496);
if ((this->fbufSave != NULL) && (this->fbuf != NULL)) {
func_800C1AE8(this, gfxp, this->fbuf, this->fbufSave);
}
}
void func_800C1FA4(PreRender* this, Gfx** gfxp) {
Gfx* gfx = *gfxp;
gDPPipeSync(gfx++);
gDPSetBlendColor(gfx++, 255, 255, 255, 8);
gDPSetPrimDepth(gfx++, -1, -1);
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2);
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, this->width, this->height);
gDPFillRectangle(gfx++, 0, 0, this->width, this->height);
gDPPipeSync(gfx++);
*gfxp = gfx;
}
void func_800C20B4(PreRender* this, Gfx** gfxp) {
func_800C1FA4(this, gfxp);
LogUtils_CheckNullPointer("this->cvg_save", this->cvgSave, "../PreRender.c", 532);
if (this->cvgSave != NULL) {
func_800C1B24(this, gfxp, this->fbuf, this->cvgSave);
}
}
void func_800C2118(PreRender* this, Gfx** gfxp) {
func_800C0F28(this, gfxp, this->zbufSave, this->zbuf);
}
void func_800C213C(PreRender* this, Gfx** gfxp) {
Gfx* gfx;
s32 y;
s32 y2;
s32 dy;
s32 rtile = 1;
if (this->cvgSave != NULL) {
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 563);
LogUtils_CheckNullPointer("glistpp", gfxp, "../PreRender.c", 564);
gfx = *gfxp;
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 566);
gDPPipeSync(gfx++);
gDPSetEnvColor(gfx++, 255, 255, 255, 32);
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_2CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA |
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) |
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1));
gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 1, 0, TEXEL1, ENVIRONMENT, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED);
dy = 4;
y = this->height;
y2 = 0;
while (y > 0) {
s32 uls = 0;
s32 lrs = this->width - 1;
s32 ult;
s32 lrt;
dy = CLAMP_MAX(dy, y);
ult = y2;
lrt = (y2 + dy - 1);
gDPLoadMultiTile(gfx++, this->fbufSave, 0x0000, G_TX_RENDERTILE, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width,
this->height, uls, ult, lrs, lrt, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPLoadMultiTile(gfx++, this->cvgSave, 0x0160, rtile, G_IM_FMT_I, G_IM_SIZ_8b, this->width, this->height,
uls, ult, lrs, lrt, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5,
ult << 5, 1 << 10, 1 << 10);
y -= dy;
y2 += dy;
}
gDPPipeSync(gfx++);
*gfxp = gfx;
}
}
void func_800C24BC(PreRender* this, Gfx** gfxp) {
func_800C0F28(this, gfxp, this->fbufSave, this->fbuf);
}
void func_800C24E0(PreRender* this, Gfx** gfxp) {
func_800C1258(this, gfxp);
}
void func_800C2500(PreRender* this, s32 x, s32 y) {
s32 i;
s32 j;
s32 buffA[3 * 5];
s32 buffR[3 * 5];
s32 buffG[3 * 5];
s32 buffB[3 * 5];
s32 x1;
s32 y1;
s32 pad;
s32 pxR;
s32 pxG;
s32 pxB;
s32 pxR2;
s32 pxG2;
s32 pxB2;
Color_RGBA16 pxIn;
Color_RGBA16 pxOut;
u32 pxR3;
u32 pxG3;
u32 pxB3;
/*
Picture this as a 3x5 rectangle where the middle pixel (index 7) correspond to (x, y)
_ _ _ _ _
| 0 1 2 3 4 |
| 5 6 7 8 9 |
| A B C D E |
*/
for (i = 0; i < 3 * 5; i++) {
x1 = (i % 5) + x - 2;
y1 = (i / 5) + y - 1;
if (x1 < 0) {
x1 = 0;
} else if (x1 > (this->width - 1)) {
x1 = this->width - 1;
}
if (y1 < 0) {
y1 = 0;
} else if (y1 > (this->height - 1)) {
y1 = this->height - 1;
}
pxIn.rgba = this->fbufSave[x1 + y1 * this->width];
buffR[i] = (pxIn.r << 3) | (pxIn.r >> 2);
buffG[i] = (pxIn.g << 3) | (pxIn.g >> 2);
buffB[i] = (pxIn.b << 3) | (pxIn.b >> 2);
buffA[i] = this->cvgSave[x1 + y1 * this->width] >> 5; // A
}
if (buffA[7] == 7) {
osSyncPrintf("Error, should not be in here \n");
return;
}
pxR = pxR2 = buffR[7];
pxG = pxG2 = buffG[7];
pxB = pxB2 = buffB[7];
for (i = 1; i < 3 * 5; i += 2) {
if (buffA[i] == 7) {
if (pxR < buffR[i]) {
for (j = 1; j < 15; j += 2) {
if ((i != j) && (buffR[j] >= buffR[i]) && (buffA[j] == 7)) {
pxR = buffR[i];
}
}
}
if (pxG < buffG[i]) {
for (j = 1; j < 15; j += 2) {
if ((i != j) && (buffG[j] >= buffG[i]) && (buffA[j] == 7)) {
pxG = buffG[i];
}
}
}
if (pxB < buffB[i]) {
for (j = 1; j < 15; j += 2) {
if ((i != j) && (buffB[j] >= buffB[i]) && (buffA[j] == 7)) {
pxB = buffB[i];
}
}
}
if (1) {}
if (pxR2 > buffR[i]) {
for (j = 1; j < 15; j += 2) {
if ((i != j) && (buffR[j] <= buffR[i]) && (buffA[j] == 7)) {
pxR2 = buffR[i];
}
}
}
if (pxG2 > buffG[i]) {
for (j = 1; j < 15; j += 2) {
if ((i != j) && (buffG[j] <= buffG[i]) && (buffA[j] == 7)) {
pxG2 = buffG[i];
}
}
}
if (pxB2 > buffB[i]) {
for (j = 1; j < 15; j += 2) {
if ((i != j) && (buffB[j] <= buffB[i]) && (buffA[j] == 7)) {
pxB2 = buffB[i];
}
}
}
}
}
pxR3 = buffR[7] + ((s32)((7 - buffA[7]) * ((pxR + pxR2) - (buffR[7] << 1)) + 4) >> 3);
pxG3 = buffG[7] + ((s32)((7 - buffA[7]) * ((pxG + pxG2) - (buffG[7] << 1)) + 4) >> 3);
pxB3 = buffB[7] + ((s32)((7 - buffA[7]) * ((pxB + pxB2) - (buffB[7] << 1)) + 4) >> 3);
pxOut.r = pxR3 >> 3;
pxOut.g = pxG3 >> 3;
pxOut.b = pxB3 >> 3;
pxOut.a = 1;
this->fbufSave[x + y * this->width] = pxOut.rgba;
}
void func_800C2FE4(PreRender* this) {
s32 x;
s32 y;
s32 phi_v0;
u8* buffR = alloca(this->width);
u8* buffG = alloca(this->width);
u8* buffB = alloca(this->width);
s32 pad[3];
s32 pxR;
s32 pxG;
s32 pxB;
for (y = 0; y < this->height; y++) {
for (x = 0; x < this->width; x++) {
Color_RGBA16 pxIn;
pxIn.rgba = this->fbufSave[x + y * this->width];
buffR[x] = pxIn.r;
buffG[x] = pxIn.g;
buffB[x] = pxIn.b;
}
for (x = 1; x < this->width - 1; x++) {
Color_RGBA16 pxOut;
s32 a = this->cvgSave[x + y * this->width];
a >>= 5;
if (a == 7) {
continue;
}
if (((HREG(80) == 0xF) ? HREG(81) : 0) != 0) {
if (((HREG(80) == 0xF) ? HREG(81) : 0) != 0) {}
if (((HREG(80) == 0xF) ? HREG(81) : 0) == 5) {
pxR = 31;
pxG = 0;
pxB = 0;
} else {
u8* temp_s0 = &buffR[x - 1];
u8* temp_s1 = &buffG[x - 1];
u8* temp_s2 = &buffB[x - 1];
if (((HREG(80) == 0xF) ? HREG(81) : 0) == 3) {
osSyncPrintf("red=%3d %3d %3d %3d grn=%3d %3d %3d %3d blu=%3d %3d %3d %3d \n", temp_s0[0],
temp_s0[1], temp_s0[2], MEDIAN3(temp_s0[0], temp_s0[1], temp_s0[2]), temp_s1[0],
temp_s1[1], temp_s1[2], MEDIAN3(temp_s1[0], temp_s1[1], temp_s1[2]), temp_s2[0],
temp_s2[1], temp_s2[2], MEDIAN3(temp_s2[0], temp_s2[1], temp_s2[2]));
}
if (((HREG(80) == 0xF) ? HREG(81) : 0) == 1) {
pxR = MEDIAN3(temp_s0[0], temp_s0[1], temp_s0[2]);
pxG = MEDIAN3(temp_s1[0], temp_s1[1], temp_s1[2]);
pxB = MEDIAN3(temp_s2[0], temp_s2[1], temp_s2[2]);
} else {
pxR = MEDIAN3(temp_s0[0], temp_s0[1], temp_s0[2]);
pxG = MEDIAN3(temp_s1[0], temp_s1[1], temp_s1[2]);
pxB = MEDIAN3(temp_s2[0], temp_s2[1], temp_s2[2]);
}
}
pxOut.r = pxR;
pxOut.g = pxG;
pxOut.b = pxB;
pxOut.a = 1;
}
this->fbufSave[x + y * this->width] = pxOut.rgba;
}
}
}
void PreRender_Calc(PreRender* this) {
s32 x;
s32 y;
// OTRTODO: I think this is currently causing some kind of buffer overflow...?
return;
if ((this->cvgSave != NULL) && (this->fbufSave != NULL)) {
for (y = 0; y < this->height; y++) {
for (x = 0; x < this->width; x++) {
s32 a = this->cvgSave[x + y * this->width];
a >>= 5;
a++;
if (a != 8) {
func_800C2500(this, x, y);
}
}
}
if (HREG(80) == 0xF ? HREG(81) : 0) {
func_800C2FE4(this);
}
}
}

142
soh/src/code/TwoHeadArena.c Normal file
View file

@ -0,0 +1,142 @@
#include "global.h"
#include <string.h>
void THGA_Ct(TwoHeadGfxArena* thga, Gfx* start, size_t size) {
THA_Ct((TwoHeadArena*)thga, start, size);
}
void THGA_Dt(TwoHeadGfxArena* thga) {
THA_Dt((TwoHeadArena*)thga);
}
u32 THGA_IsCrash(TwoHeadGfxArena* thga) {
return THA_IsCrash((TwoHeadArena*)thga);
}
void THGA_Init(TwoHeadGfxArena* thga) {
THA_Init((TwoHeadArena*)thga);
}
s32 THGA_GetSize(TwoHeadGfxArena* thga) {
return THA_GetSize((TwoHeadArena*)thga);
}
Gfx* THGA_GetHead(TwoHeadGfxArena* thga) {
return THA_GetHead((TwoHeadArena*)thga);
}
void THGA_SetHead(TwoHeadGfxArena* thga, Gfx* start) {
THA_SetHead((TwoHeadArena*)thga, start);
}
Gfx* THGA_GetTail(TwoHeadGfxArena* thga) {
return THA_GetTail((TwoHeadArena*)thga);
}
Gfx* THGA_AllocStartArray8(TwoHeadGfxArena* thga, u32 count) {
return THA_AllocStart((TwoHeadArena*)thga, count * 8);
}
Gfx* THGA_AllocStart8(TwoHeadGfxArena* thga) {
return THGA_AllocStartArray8(thga, 1);
}
Gfx* THGA_AllocStart8Wrapper(TwoHeadGfxArena* thga) {
return THGA_AllocStart8(thga);
}
Gfx* THGA_AllocEnd(TwoHeadGfxArena* thga, size_t size) {
return THA_AllocEnd((TwoHeadArena*)thga, size);
}
Gfx* THGA_AllocEndArray64(TwoHeadGfxArena* thga, u32 count) {
return THGA_AllocEnd(thga, count * 0x40);
}
Gfx* THGA_AllocEnd64(TwoHeadGfxArena* thga) {
return THGA_AllocEnd(thga, 0x40);
}
Gfx* THGA_AllocEndArray16(TwoHeadGfxArena* thga, u32 count) {
return THGA_AllocEnd(thga, count * 0x10);
}
Gfx* THGA_AllocEnd16(TwoHeadGfxArena* thga) {
return THGA_AllocEnd(thga, 0x10);
}
void* THA_GetHead(TwoHeadArena* tha) {
return tha->head;
}
void THA_SetHead(TwoHeadArena* tha, void* start) {
tha->head = start;
}
void* THA_GetTail(TwoHeadArena* tha) {
return tha->tail;
}
void* THA_AllocStart(TwoHeadArena* tha, size_t size) {
void* start = tha->head;
tha->head = (uintptr_t)tha->head + size;
return start;
}
void* THA_AllocStart1(TwoHeadArena* tha) {
return THA_AllocStart(tha, 1);
}
void* THA_AllocEnd(TwoHeadArena* tha, size_t size) {
size_t mask;
if (size == 8) {
mask = ~7;
} else if (size == 4 || size == 12) {
mask = ~3;
} else if (size == 2 || size == 6 || size == 10 || size == 12 || size == 14) {
mask = ~1;
} else {
mask = (size >= 0x10) ? ~0xF : 0;
}
tha->tail = (((uintptr_t)tha->tail & mask) - size) & mask;
return tha->tail;
}
void* THA_AllocEndAlign16(TwoHeadArena* tha, size_t size) {
size_t mask = ~0xF;
tha->tail = (((uintptr_t)tha->tail & mask) - size) & mask;
return tha->tail;
}
void* THA_AllocEndAlign(TwoHeadArena* tha, size_t size, size_t mask) {
tha->tail = (((uintptr_t)tha->tail & mask) - size) & mask;
return tha->tail;
}
s32 THA_GetSize(TwoHeadArena* tha) {
return (uintptr_t)tha->tail - (uintptr_t)tha->head;
}
u32 THA_IsCrash(TwoHeadArena* tha) {
return THA_GetSize(tha) < 0;
}
void THA_Init(TwoHeadArena* tha) {
tha->head = tha->bufp;
tha->tail = (uintptr_t)tha->bufp + tha->size;
}
void THA_Ct(TwoHeadArena* tha, void* ptr, size_t size) {
tha->bufp = ptr;
tha->size = size;
THA_Init(tha);
}
void THA_Dt(TwoHeadArena* tha) {
memset(tha,0, sizeof(TwoHeadArena));
}

823
soh/src/code/__osMalloc.c Normal file
View file

@ -0,0 +1,823 @@
#include "global.h"
#include "vt.h"
#include <string.h>
#define FILL_ALLOCBLOCK (1 << 0)
#define FILL_FREEBLOCK (1 << 1)
#define CHECK_FREE_BLOCK (1 << 2)
#define NODE_MAGIC (0x7373)
#define BLOCK_UNINIT_MAGIC (0xAB)
#define BLOCK_UNINIT_MAGIC_32 (0xABABABAB)
#define BLOCK_ALLOC_MAGIC (0xCD)
#define BLOCK_ALLOC_MAGIC_32 (0xCDCDCDCD)
#define BLOCK_FREE_MAGIC (0xEF)
#define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF)
OSMesg sArenaLockMsg;
u32 __osMalloc_FreeBlockTest_Enable;
u32 ArenaImpl_GetFillAllocBlock(Arena* arena) {
return (arena->flag & FILL_ALLOCBLOCK) != 0;
}
u32 ArenaImpl_GetFillFreeBlock(Arena* arena) {
return (arena->flag & FILL_FREEBLOCK) != 0;
}
u32 ArenaImpl_GetCheckFreeBlock(Arena* arena) {
return (arena->flag & CHECK_FREE_BLOCK) != 0;
}
void ArenaImpl_SetFillAllocBlock(Arena* arena) {
arena->flag |= FILL_ALLOCBLOCK;
}
void ArenaImpl_SetFillFreeBlock(Arena* arena) {
arena->flag |= FILL_FREEBLOCK;
}
void ArenaImpl_SetCheckFreeBlock(Arena* arena) {
arena->flag |= CHECK_FREE_BLOCK;
}
void ArenaImpl_UnsetFillAllocBlock(Arena* arena) {
arena->flag &= ~FILL_ALLOCBLOCK;
}
void ArenaImpl_UnsetFillFreeBlock(Arena* arena) {
arena->flag &= ~FILL_FREEBLOCK;
}
void ArenaImpl_UnsetCheckFreeBlock(Arena* arena) {
arena->flag &= ~CHECK_FREE_BLOCK;
}
#if 0
void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena) {
node->filename = file;
node->line = line;
node->threadId = osGetThreadId(NULL);
node->arena = arena;
node->time = osGetTime();
}
#endif
void ArenaImpl_LockInit(Arena* arena) {
osCreateMesgQueue(&arena->lock, &sArenaLockMsg, 1);
}
void ArenaImpl_Lock(Arena* arena) {
osSendMesg(&arena->lock, NULL, OS_MESG_BLOCK);
}
void ArenaImpl_Unlock(Arena* arena) {
osRecvMesg(&arena->lock, NULL, OS_MESG_BLOCK);
}
ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node) {
ArenaNode* next = node->next;
if (next != NULL && (next == NULL || (next->magic != NODE_MAGIC))) {
osSyncPrintf(VT_COL(RED, WHITE) "緊急事態!メモリリーク発見! (block=%08x)\n" VT_RST, next);
next = NULL;
node->next = NULL;
}
return next;
}
ArenaNode* ArenaImpl_GetPrevBlock(ArenaNode* node) {
ArenaNode* prev = node->prev;
if (prev != NULL && (prev == NULL || (prev->magic != NODE_MAGIC))) {
osSyncPrintf(VT_COL(RED, WHITE) "緊急事態!メモリリーク発見! (block=%08x)\n" VT_RST, prev);
prev = NULL;
node->prev = NULL;
}
return prev;
}
ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) {
ArenaNode* last = NULL;
ArenaNode* iter;
if (arena != NULL && arena->head != NULL && arena->head->magic == NODE_MAGIC) {
iter = arena->head;
while (iter != NULL) {
last = iter;
iter = ArenaImpl_GetNextBlock(iter);
}
}
return last;
}
void __osMallocInit(Arena* arena, void* start, size_t size) {
memset(arena,0, sizeof(Arena));
ArenaImpl_LockInit(arena);
__osMallocAddBlock(arena, start, size);
arena->isInit = true;
}
void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size) {
s32 diff;
ptrdiff_t size2;
ArenaNode* firstNode;
ArenaNode* lastNode;
if (start != NULL) {
firstNode = (ArenaNode*)ALIGN16((uintptr_t)start);
diff = (uintptr_t)firstNode - (uintptr_t)start;
size2 = (size - diff) & ~0xF;
if (size2 > (ptrdiff_t)sizeof(ArenaNode)) {
memset(firstNode, BLOCK_UNINIT_MAGIC, size2); // memset
firstNode->next = NULL;
firstNode->prev = NULL;
firstNode->size = size2 - sizeof(ArenaNode);
firstNode->isFree = true;
firstNode->magic = NODE_MAGIC;
ArenaImpl_Lock(arena);
lastNode = ArenaImpl_GetLastBlock(arena);
if (lastNode == NULL) {
arena->head = firstNode;
arena->start = start;
} else {
firstNode->prev = lastNode;
lastNode->next = firstNode;
}
ArenaImpl_Unlock(arena);
}
}
}
void ArenaImpl_RemoveAllBlocks(Arena* arena) {
ArenaNode* iter;
ArenaNode* next;
ArenaImpl_Lock(arena);
iter = arena->head;
while (iter != NULL) {
next = ArenaImpl_GetNextBlock(iter);
memset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode)); // memset
iter = next;
}
ArenaImpl_Unlock(arena);
}
void __osMallocCleanup(Arena* arena) {
ArenaImpl_RemoveAllBlocks(arena);
memset(arena, 0, sizeof(*arena));
}
u8 __osMallocIsInitalized(Arena* arena) {
return arena->isInit;
}
void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) {
ArenaNode* node2 = node;
u32* start;
u32* end;
u32* iter;
if (__osMalloc_FreeBlockTest_Enable) {
start = (u32*)((uintptr_t)node + sizeof(ArenaNode));
end = (u32*)((uintptr_t)start + node2->size);
iter = start;
while (iter < end) {
if (*iter != BLOCK_UNINIT_MAGIC_32 && *iter != BLOCK_FREE_MAGIC_32) {
osSyncPrintf(
VT_COL(RED, WHITE) "緊急事態!メモリリーク検出! (block=%08x s=%08x e=%08x p=%08x)\n" VT_RST, node,
start, end, iter);
__osDisplayArena(arena);
return;
}
iter++;
}
}
}
void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 line) {
ArenaNode* iter;
u32 blockSize;
ArenaNode* newNode;
void* alloc = NULL;
ArenaNode* next;
iter = arena->head;
size = ALIGN16(size);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
while (iter != NULL) {
if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) {
__osMalloc_FreeBlockTest(arena, iter);
}
if (blockSize < iter->size) {
newNode = (ArenaNode*)((uintptr_t)iter + blockSize);
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = iter->size - blockSize;
newNode->isFree = true;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size = size;
next = ArenaImpl_GetNextBlock(newNode);
if (next) {
next->prev = newNode;
}
}
iter->isFree = false;
//ArenaImpl_SetDebugInfo(iter, file, line, arena);
alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) {
memset(alloc, BLOCK_ALLOC_MAGIC, size);
}
break;
}
iter = ArenaImpl_GetNextBlock(iter);
}
return alloc;
}
void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line) {
void* alloc;
ArenaImpl_Lock(arena);
alloc = __osMalloc_NoLockDebug(arena, size, file, line);
ArenaImpl_Unlock(arena);
return alloc;
}
void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) {
ArenaNode* iter;
ArenaNode* newNode;
u32 blockSize;
ArenaNode* next;
void* allocR = NULL;
size = ALIGN16(size);
ArenaImpl_Lock(arena);
iter = ArenaImpl_GetLastBlock(arena);
while (iter != NULL) {
if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) {
__osMalloc_FreeBlockTest(arena, iter);
}
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size) {
newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size));
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = size;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size -= blockSize;
next = ArenaImpl_GetNextBlock(newNode);
if (next) {
next->prev = newNode;
}
iter = newNode;
}
iter->isFree = false;
//ArenaImpl_SetDebugInfo(iter, file, line, arena);
allocR = (void*)((uintptr_t)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) {
memset(allocR, BLOCK_ALLOC_MAGIC, size);
}
break;
}
iter = ArenaImpl_GetPrevBlock(iter);
}
ArenaImpl_Unlock(arena);
return allocR;
}
void* __osMalloc_NoLock(Arena* arena, size_t size) {
ArenaNode* iter;
u32 blockSize;
ArenaNode* newNode;
void* alloc = NULL;
ArenaNode* next;
iter = arena->head;
size = ALIGN16(size);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
while (iter != NULL) {
if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) {
__osMalloc_FreeBlockTest(arena, iter);
}
if (blockSize < iter->size) {
newNode = (ArenaNode*)((uintptr_t)iter + blockSize);
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = iter->size - blockSize;
newNode->isFree = true;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size = size;
next = ArenaImpl_GetNextBlock(newNode);
if (next) {
next->prev = newNode;
}
}
iter->isFree = false;
//ArenaImpl_SetDebugInfo(iter, NULL, 0, arena);
alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) {
memset(alloc, BLOCK_ALLOC_MAGIC, size);
}
break;
}
iter = ArenaImpl_GetNextBlock(iter);
}
return alloc;
}
void* __osMalloc(Arena* arena, size_t size) {
void* alloc;
ArenaImpl_Lock(arena);
alloc = __osMalloc_NoLock(arena, size);
ArenaImpl_Unlock(arena);
return alloc;
}
void* __osMallocR(Arena* arena, size_t size) {
ArenaNode* iter;
ArenaNode* newNode;
u32 blockSize;
ArenaNode* next;
void* alloc = NULL;
size = ALIGN16(size);
ArenaImpl_Lock(arena);
iter = ArenaImpl_GetLastBlock(arena);
while (iter != NULL) {
if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) {
__osMalloc_FreeBlockTest(arena, iter);
}
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size) {
newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size));
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = size;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size -= blockSize;
next = ArenaImpl_GetNextBlock(newNode);
if (next) {
next->prev = newNode;
}
iter = newNode;
}
iter->isFree = false;
//ArenaImpl_SetDebugInfo(iter, NULL, 0, arena);
alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) {
memset(alloc, BLOCK_ALLOC_MAGIC, size);
}
break;
}
iter = ArenaImpl_GetPrevBlock(iter);
}
ArenaImpl_Unlock(arena);
return alloc;
}
void __osFree_NoLock(Arena* arena, void* ptr) {
ArenaNode* node;
ArenaNode* next;
ArenaNode* prev;
ArenaNode* newNext;
if (ptr == NULL) {
return;
}
node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode));
if (node == NULL || node->magic != NODE_MAGIC) {
// "__osFree: Unauthorized release (%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x)\n" VT_RST, ptr);
return;
}
if (node->isFree) {
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x)\n" VT_RST, ptr); // "__osFree: Double release (%08x)"
return;
}
#if 0
if (arena != node->arena && arena != NULL) {
// "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena,
node->arena);
return;
}
#endif
next = ArenaImpl_GetNextBlock(node);
prev = ArenaImpl_GetPrevBlock(node);
node->isFree = true;
//ArenaImpl_SetDebugInfo(node, NULL, 0, arena);
if (arena->flag & FILL_FREEBLOCK) {
memset((uintptr_t)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size);
}
newNext = next;
if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) {
newNext = ArenaImpl_GetNextBlock(next);
if (newNext != NULL) {
newNext->prev = node;
}
node->size += next->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) {
memset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
node->next = newNext;
next = newNext;
}
if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) {
if (next) {
next->prev = prev;
}
prev->next = next;
prev->size += node->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) {
memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
}
}
void __osFree(Arena* arena, void* ptr) {
ArenaImpl_Lock(arena);
__osFree_NoLock(arena, ptr);
ArenaImpl_Unlock(arena);
}
void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
ArenaNode* node;
ArenaNode* next;
ArenaNode* prev;
ArenaNode* newNext;
if (ptr == NULL) {
return;
}
node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode));
if (node == NULL || node->magic != NODE_MAGIC) {
// "__osFree: Unauthorized release (%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line);
return;
}
if (node->isFree) {
// "__osFree: Double release (%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line);
return;
}
#if 0
if (arena != node->arena && arena != NULL) {
// "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena,
node->arena);
return;
}
#endif
next = ArenaImpl_GetNextBlock(node);
prev = ArenaImpl_GetPrevBlock(node);
node->isFree = true;
//ArenaImpl_SetDebugInfo(node, file, line, arena);
if (arena->flag & FILL_FREEBLOCK) {
memset((uintptr_t)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size);
}
newNext = node->next;
if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) {
newNext = ArenaImpl_GetNextBlock(next);
if (newNext != NULL) {
newNext->prev = node;
}
node->size += next->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) {
memset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
node->next = newNext;
next = newNext;
}
if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) {
if (next != NULL) {
next->prev = prev;
}
prev->next = next;
prev->size += node->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) {
memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
}
}
void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line) {
ArenaImpl_Lock(arena);
__osFree_NoLockDebug(arena, ptr, file, line);
ArenaImpl_Unlock(arena);
}
void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
void* newAlloc;
ArenaNode* node;
ArenaNode* next;
ArenaNode* newNext;
ArenaNode* overNext;
ArenaNode* newNext2;
ArenaNode* next2;
size_t sizeDiff;
ArenaNode* overNext2;
ArenaNode localCopy;
u32 blockSize;
s32 pad;
newSize = ALIGN16(newSize);
osSyncPrintf("__osRealloc(%08x, %d)\n", ptr, newSize);
ArenaImpl_Lock(arena);
if (ptr == NULL) {
ptr = __osMalloc_NoLock(arena, newSize);
} else if (newSize == 0) {
__osFree_NoLock(arena, ptr);
ptr = NULL;
} else {
node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode));
if (newSize == node->size) {
// "Does nothing because the memory block size does not change"
osSyncPrintf("メモリブロックサイズが変わらないためなにもしません\n");
} else if (node->size < newSize) {
next = ArenaImpl_GetNextBlock(node);
sizeDiff = newSize - node->size;
if ((uintptr_t)next == ((uintptr_t)node + node->size + sizeof(ArenaNode)) && next->isFree && next->size >= sizeDiff) {
// "Merge because there is a free block after the current memory block"
osSyncPrintf("現メモリブロックの後ろにフリーブロックがあるので結合します\n");
next->size -= sizeDiff;
overNext = ArenaImpl_GetNextBlock(next);
newNext = (ArenaNode*)((uintptr_t)next + sizeDiff);
if (overNext != NULL) {
overNext->prev = newNext;
}
node->next = newNext;
node->size = newSize;
func_801068B0(newNext, next, sizeof(ArenaNode)); // memcpy
} else {
// "Allocate a new memory block and move the contents"
osSyncPrintf("新たにメモリブロックを確保して内容を移動します\n");
newAlloc = __osMalloc_NoLock(arena, newSize);
if (newAlloc != NULL) {
memcpy(newAlloc, ptr, node->size);
__osFree_NoLock(arena, ptr);
}
ptr = newAlloc;
}
} else if (newSize < node->size) {
next2 = ArenaImpl_GetNextBlock(node);
if (next2 != NULL && next2->isFree) {
blockSize = ALIGN16(newSize) + sizeof(ArenaNode);
// "Increased free block behind current memory block"
osSyncPrintf("現メモリブロックの後ろのフリーブロックを大きくしました\n");
newNext2 = (ArenaNode*)((uintptr_t)node + blockSize);
localCopy = *next2;
*newNext2 = localCopy;
newNext2->size += node->size - newSize;
node->next = newNext2;
node->size = newSize;
overNext2 = ArenaImpl_GetNextBlock(newNext2);
if (overNext2 != NULL) {
overNext2->prev = newNext2;
}
} else if (newSize + sizeof(ArenaNode) < node->size) {
blockSize = ALIGN16(newSize) + sizeof(ArenaNode);
// "Generated because there is no free block after the current memory block"
osSyncPrintf("現メモリブロックの後ろにフリーブロックがないので生成します\n");
newNext2 = (ArenaNode*)((uintptr_t)node + blockSize);
newNext2->next = ArenaImpl_GetNextBlock(node);
newNext2->prev = node;
newNext2->size = node->size - blockSize;
newNext2->isFree = true;
newNext2->magic = NODE_MAGIC;
node->next = newNext2;
node->size = newSize;
overNext2 = ArenaImpl_GetNextBlock(newNext2);
if (overNext2 != NULL) {
overNext2->prev = newNext2;
}
} else {
// "There is no room to generate free blocks"
osSyncPrintf("フリーブロック生成するだけの空きがありません\n");
ptr = NULL;
}
}
}
ArenaImpl_Unlock(arena);
return ptr;
}
void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file, s32 line) {
return __osRealloc(arena, ptr, newSize);
}
void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc) {
ArenaNode* iter;
ArenaImpl_Lock(arena);
*outMaxFree = 0;
*outFree = 0;
*outAlloc = 0;
iter = arena->head;
while (iter != NULL) {
if (iter->isFree) {
*outFree += iter->size;
if (*outMaxFree < iter->size) {
*outMaxFree = iter->size;
}
} else {
*outAlloc += iter->size;
}
iter = ArenaImpl_GetNextBlock(iter);
}
ArenaImpl_Unlock(arena);
}
void __osDisplayArena(Arena* arena) {
size_t freeSize;
size_t allocatedSize;
size_t maxFree;
ArenaNode* iter;
ArenaNode* next;
if (!__osMallocIsInitalized(arena)) {
osSyncPrintf("アリーナは初期化されていません\n"); // "Arena is not initalized"
return;
}
ArenaImpl_Lock(arena);
maxFree = 0;
freeSize = 0;
allocatedSize = 0;
osSyncPrintf("アリーナの内容 (0x%08x)\n", arena); // "Arena contents (0x%08x)"
// "Memory node range status size [time s ms us ns: TID: src: line]"
osSyncPrintf("メモリブロック範囲 status サイズ [時刻 s ms us ns: TID:src:行]\n");
iter = arena->head;
while (iter != NULL) {
if (iter != NULL && iter->magic == NODE_MAGIC) {
next = iter->next;
osSyncPrintf("%08x-%08x%c %s %08x", iter, ((uintptr_t)iter + sizeof(ArenaNode) + iter->size),
(next == NULL) ? '$' : (iter != next->prev ? '!' : ' '),
iter->isFree ? "空き" : "確保", //? "Free" : "Secure"
iter->size);
#if 0
if (!iter->isFree) {
osSyncPrintf(" [%016llu:%2d:%s:%d]", OS_CYCLES_TO_NSEC(iter->time), iter->threadId,
iter->filename != NULL ? iter->filename : "**NULL**", iter->line);
}
#endif
osSyncPrintf("\n");
if (iter->isFree) {
freeSize += iter->size;
if (maxFree < iter->size) {
maxFree = iter->size;
}
} else {
allocatedSize += iter->size;
}
} else {
osSyncPrintf("%08x Block Invalid\n", iter);
next = NULL;
}
iter = next;
}
// "Total reserved node size 0x%08x bytes"
osSyncPrintf("確保ブロックサイズの合計 0x%08x バイト\n", allocatedSize);
// "Total free node size 0x%08x bytes"
osSyncPrintf("空きブロックサイズの合計 0x%08x バイト\n", freeSize);
// "Maximum free node size 0x%08x bytes"
osSyncPrintf("最大空きブロックサイズ 0x%08x バイト\n", maxFree);
ArenaImpl_Unlock(arena);
}
void ArenaImpl_FaultClient(Arena* arena) {
size_t freeSize;
size_t allocatedSize;
size_t maxFree;
ArenaNode* iter;
ArenaNode* next;
FaultDrawer_Printf("ARENA INFO (0x%08x)\n", arena);
if (!__osMallocIsInitalized(arena)) {
FaultDrawer_Printf("Arena is uninitalized\n", arena);
return;
}
maxFree = 0;
freeSize = 0;
allocatedSize = 0;
FaultDrawer_Printf("Memory Block Region status size\n");
iter = arena->head;
while (iter != NULL) {
if (iter != NULL && iter->magic == NODE_MAGIC) {
next = iter->next;
FaultDrawer_Printf("%08x-%08x%c %s %08x", iter, ((uintptr_t)iter + sizeof(ArenaNode) + iter->size),
(!next) ? '$' : (iter != next->prev ? '!' : ' '), iter->isFree ? "F" : "A", iter->size);
FaultDrawer_Printf("\n");
if (iter->isFree) {
freeSize += iter->size;
if (maxFree < iter->size) {
maxFree = iter->size;
}
} else {
allocatedSize += iter->size;
}
} else {
FaultDrawer_SetFontColor(0xF801);
FaultDrawer_Printf("%08x Block Invalid\n", iter);
next = NULL;
}
iter = next;
}
FaultDrawer_SetFontColor(0x7F1);
FaultDrawer_Printf("Total Alloc Block Size %08x\n", allocatedSize);
FaultDrawer_Printf("Total Free Block Size %08x\n", freeSize);
FaultDrawer_Printf("Largest Free Block Size %08x\n", maxFree);
}
u32 __osCheckArena(Arena* arena) {
ArenaNode* iter;
u32 error = 0;
ArenaImpl_Lock(arena);
// "Checking the contents of the arena. . (%08x)"
osSyncPrintf("アリーナの内容をチェックしています... (%08x)\n", arena);
iter = arena->head;
while (iter != NULL) {
if (iter && iter->magic == NODE_MAGIC) {
// "Oops!! (%08x %08x)"
osSyncPrintf(VT_COL(RED, WHITE) "おおっと!! (%08x %08x)\n" VT_RST, iter, iter->magic);
error = 1;
break;
}
iter = ArenaImpl_GetNextBlock(iter);
}
if (error == 0) {
osSyncPrintf("アリーナはまだ、いけそうです\n"); // "The arena is still going well"
}
ArenaImpl_Unlock(arena);
return error;
}
u8 func_800FF334(Arena* arena) {
return arena->unk_20;
}

121
soh/src/code/audioMgr.c Normal file
View file

@ -0,0 +1,121 @@
#include "global.h"
#include "SohHooks.h"
#include <string.h>
void func_800C3C80(AudioMgr* audioMgr) {
AudioTask* task;
task = audioMgr->rspTask;
if (audioMgr->rspTask->taskQueue != NULL) {
osSendMesg(task->taskQueue, NULL, OS_MESG_BLOCK);
}
}
void AudioMgr_HandleRetrace(AudioMgr* audioMgr) {
AudioTask* rspTask;
if (SREG(20) > 0) {
audioMgr->rspTask = NULL;
}
if (audioMgr->rspTask != NULL) {
audioMgr->audioTask.next = NULL;
audioMgr->audioTask.flags = 2;
audioMgr->audioTask.framebuffer = NULL;
audioMgr->audioTask.list = audioMgr->rspTask->task;
audioMgr->audioTask.msgQ = &audioMgr->unk_AC;
audioMgr->audioTask.msg = NULL;
osSendMesg(&audioMgr->sched->cmdQ, &audioMgr->audioTask, OS_MESG_BLOCK);
Sched_SendEntryMsg(audioMgr->sched);
}
D_8016A550 = osGetTime();
if (SREG(20) >= 2) {
rspTask = NULL;
} else {
rspTask = func_800E4FE0();
}
D_8016A558 += osGetTime() - D_8016A550;
D_8016A550 = 0;
if (audioMgr->rspTask != NULL) {
osRecvMesg(&audioMgr->unk_AC, NULL, OS_MESG_BLOCK);
func_800C3C80(audioMgr);
}
audioMgr->rspTask = rspTask;
}
void AudioMgr_HandlePRENMI(AudioMgr* audioMgr) {
// "Audio manager received OS_SC_PRE_NMI_MSG"
osSyncPrintf("オーディオマネージャが OS_SC_PRE_NMI_MSG を受け取りました\n");
Audio_PreNMI();
}
void AudioMgr_ThreadEntry(void* arg0) {
AudioMgr* audioMgr = (AudioMgr*)arg0;
s16* msg = NULL;
//while (true) {
osRecvMesg(&audioMgr->unk_74, (OSMesg*)&msg, OS_MESG_BLOCK);
AudioMgr_HandleRetrace(audioMgr);
/*switch (*msg) {
case OS_SC_RETRACE_MSG:
AudioMgr_HandleRetrace(audioMgr);
while (audioMgr->unk_74.validCount != 0) {
osRecvMesg(&audioMgr->unk_74, (OSMesg*)&msg, OS_MESG_BLOCK);
switch (*msg) {
case OS_SC_RETRACE_MSG:
break;
case OS_SC_PRE_NMI_MSG:
AudioMgr_HandlePRENMI(audioMgr);
break;
}
}
break;
case OS_SC_PRE_NMI_MSG:
AudioMgr_HandlePRENMI(audioMgr);
break;
}*/
//}
}
void AudioMgr_Unlock(AudioMgr* audioMgr) {
osRecvMesg(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK);
}
void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, SchedContext* sched, IrqMgr* irqMgr) {
AudioPlayer_Init();
memset(audioMgr,0, sizeof(AudioMgr));
audioMgr->sched = sched;
audioMgr->irqMgr = irqMgr;
audioMgr->rspTask = NULL;
osCreateMesgQueue(&audioMgr->unk_AC, &audioMgr->unk_C4, 1);
osCreateMesgQueue(&audioMgr->unk_74, &audioMgr->unk_8C, 8);
osCreateMesgQueue(&audioMgr->unk_C8, &audioMgr->unk_E0, 1);
osSendMesg(&audioMgr->unk_AC, NULL, OS_MESG_BLOCK);
static bool hasInitialized = false;
if (!hasInitialized) {
IrqMgrClient irqClient;
osSyncPrintf("オーディオマネージャスレッド実行開始\n"); // "Start running audio manager thread"
Audio_Init();
AudioLoad_SetDmaHandler(DmaMgr_DmaHandler);
Audio_InitSound();
osSendMesg(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK);
bind_hook(AUDIO_INIT);
init_hook(0);
call_hook(0);
// Removed due to crash
//IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->unk_74);
hasInitialized = true;
}
//osCreateThread(&audioMgr->unk_E8, id, AudioMgr_ThreadEntry, audioMgr, stack, pri);
//osStartThread(&audioMgr->unk_E8);
}

680
soh/src/code/audio_data.c Normal file
View file

@ -0,0 +1,680 @@
#include "global.h"
// clang-format off
s16 gSawtoothWaveSample[] = {
// Frequency of 1
0, 1023, 2047, 3071, 4095, 5119, 6143, 7167,
8191, 9215, 10239, 11263, 12287, 13311, 14335, 15359,
16383, 17407, 18431, 19455, 20479, 21503, 22527, 23551,
24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743,
-32767, -31743, -30719, -29695, -28671, -27647, -26623, -25599,
-24575, -23551, -22527, -21503, -20479, -19455, -18431, -17407,
-16383, -15359, -14335, -13311, -12287, -11263, -10239, -9215,
-8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023,
// Frequency of 2
0, 2047, 4095, 6143, 8191, 10239, 12287, 14335,
16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719,
-32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431,
-16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047,
0, 2047, 4095, 6143, 8191, 10239, 12287, 14335,
16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719,
-32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431,
-16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047,
// Frequency of 4
0, 4095, 8191, 12287, 16383, 20479, 24575, 28671,
-32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095,
0, 4095, 8191, 12287, 16383, 20479, 24575, 28671,
-32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095,
0, 4095, 8191, 12287, 16383, 20479, 24575, 28671,
-32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095,
0, 4095, 8191, 12287, 16383, 20479, 24575, 28671,
-32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095,
// Frequency of 8
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
};
s16 gTriangleWaveSample[] = {
// Frequency of 1
0, 2047, 4095, 6143, 8191, 10239, 12287, 14335,
16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719,
32767, 30719, 28671, 26623, 24575, 22527, 20479, 18431,
16383, 14335, 12287, 10239, 8191, 6143, 4095, 2047,
0, -2047, -4095, -6143, -8191, -10239, -12287, -14335,
-16383, -18431, -20479, -22527, -24575, -26623, -28671, -30719,
-32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431,
-16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047,
// Frequency of 2
0, 4095, 8191, 12287, 16383, 20479, 24575, 28671,
32767, 28671, 24575, 20479, 16383, 12287, 8191, 4095,
0, -4095, -8191, -12287, -16383, -20479, -24575, -28671,
-32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095,
0, 4095, 8191, 12287, 16383, 20479, 24575, 28671,
32767, 28671, 24575, 20479, 16383, 12287, 8191, 4095,
0, -4095, -8191, -12287, -16383, -20479, -24575, -28671,
-32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095,
// Frequency of 4
0, 8191, 16383, 24575, 32767, 24575, 16383, 8191,
0, -8191, -16383, -24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, 32767, 24575, 16383, 8191,
0, -8191, -16383, -24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, 32767, 24575, 16383, 8191,
0, -8191, -16383, -24575, -32767, -24575, -16383, -8191,
0, 8191, 16383, 24575, 32767, 24575, 16383, 8191,
0, -8191, -16383, -24575, -32767, -24575, -16383, -8191,
// Frequency of 8
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
};
s16 gSineWaveSample[] = {
// Frequency of 1
0, 3211, 6392, 9511, 12539, 15446, 18204, 20787,
23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609,
32767, 32609, 32137, 31356, 30272, 28897, 27244, 25329,
23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211,
0, -3211, -6392, -9511, -12539, -15446, -18204, -20787,
-23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609,
-32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329,
-23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211,
// Frequency of 2
0, 6392, 12539, 18204, 23169, 27244, 30272, 32137,
32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392,
0, -6392, -12539, -18204, -23169, -27244, -30272, -32137,
-32767, -32137, -30272, -27244, -23169, -18204, -12539, -6392,
0, 6392, 12539, 18204, 23169, 27244, 30272, 32137,
32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392,
0, -6392, -12539, -18204, -23169, -27244, -30272, -32137,
-32767, -32137, -30272, -27244, -23169, -18204, -12539, -6392,
// Frequency of 4
0, 12539, 23169, 30272, 32767, 30272, 23169, 12539,
0, -12539, -23169, -30272, -32767, -30272, -23169, -12539,
0, 12539, 23169, 30272, 32767, 30272, 23169, 12539,
0, -12539, -23169, -30272, -32767, -30272, -23169, -12539,
0, 12539, 23169, 30272, 32767, 30272, 23169, 12539,
0, -12539, -23169, -30272, -32767, -30272, -23169, -12539,
0, 12539, 23169, 30272, 32767, 30272, 23169, 12539,
0, -12539, -23169, -30272, -32767, -30272, -23169, -12539,
// Frequency of 8
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
};
s16 gSquareWaveSample[] = {
// Frequency of 1
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767,
-32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767,
// Frequency of 2
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767,
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
0, 0, 0, 0, 0, 0, 0, 0,
// Frequency of 4
-32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767,
0, 0, 0, 0, 32767, 32767, 32767, 32767,
0, 0, 0, 0, -32767, -32767, -32767, -32767,
0, 0, 0, 0, 32767, 32767, 32767, 32767,
0, 0, 0, 0, -32767, -32767, -32767, -32767,
0, 0, 0, 0, 32767, 32767, 32767, 32767,
0, 0, 0, 0, -32767, -32767, -32767, -32767,
0, 0, 0, 0, 32767, 32767, 32767, 32767,
0, 0, 0, 0, -32767, -32767, -32767, -32767,
// Frequency of 8
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
0, 0, 32767, 32767, 0, 0, -32767, -32767,
};
s16 gWhiteNoiseSample[] = {
// Frequency of 1
0, -25689, -25791, 27803, -27568, -21030, 22174, 6298,
27071, -18531, 28649, 2284, 3380, 6890, -12682, -21114,
10000, -24520, 32296, 12248, 15096, 15354, -12021, -31545,
-12929, 6388, -11064, 30456, -30316, -21999, 29691, 27649,
0, -27649, -29691, 21999, 30316, -30457, 11064, -6387,
12929, 31544, 12021, -15353, -15096, -12249, -32296, 24521,
-10000, 21113, 12682, -6889, -3380, -2285, -28649, 18532,
-27071, -6299, -22174, 21031, 27568, -27804, 25791, 25690,
// Frequency of 2
0, -25791, -27568, 22174, 27071, 28649, 3380, -12682,
10000, 32296, 15096, -12021, -12929, -11064, -30316, 29691,
0, -29691, 30316, 11064, 12929, 12021, -15096, -32296,
-10000, 12682, -3380, -28649, -27071, -22174, 27568, 25791,
0, -25791, -27568, 22174, 27071, 28649, 3380, -12682,
10000, 32296, 15096, -12021, -12929, -11064, -30316, 29691,
0, -29691, 30316, 11064, 12929, 12021, -15096, -32296,
-10000, 12682, -3380, -28649, -27071, -22174, 27568, 25791,
// Frequency of 4
0, -27568, 27071, 3380, 10000, 15096, -12929, -30316,
0, 30316, 12929, -15096, -10000, -3380, -27071, 27568,
0, -27568, 27071, 3380, 10000, 15096, -12929, -30316,
0, 30316, 12929, -15096, -10000, -3380, -27071, 27568,
0, -27568, 27071, 3380, 10000, 15096, -12929, -30316,
0, 30316, 12929, -15096, -10000, -3380, -27071, 27568,
0, -27568, 27071, 3380, 10000, 15096, -12929, -30316,
0, 30316, 12929, -15096, -10000, -3380, -27071, 27568,
// Frequency of 8
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
0, 27071, 10000, -12929, 0, 12929, -10000, -27071,
};
// Sine White Noise?
s16 D_8012EA90[] = {
// Frequency of 1
0, 16316, 20148, 20257, 27209, -32657, 29264, 27259,
-29394, -21494, -26410, 30770, 30033, 29130, 20206, 14129,
20000, 25677, 19024, 9146, 6921, 4506, -5868, -13122,
-7858, -1885, -7042, -14025, -11903, -8647, -12346, -12396,
0, 12396, 12346, 8647, 11903, 14024, 7042, 1886,
7858, 13121, 5868, -4505, -6921, -9147, -19024, -25676,
-20000, -14130, -20206, -29129, -30033, -30771, 26410, 21495,
29394, -27260, -29264, 32658, -27209, -20258, -20148, -16315,
// Frequency of 2
0, 20148, 27209, 29264, -29394, -26410, 30033, 20206,
20000, 19024, 6921, -5868, -7858, -7042, -11903, -12346,
0, 12346, 11903, 7042, 7858, 5868, -6921, -19024,
-20000, -20206, -30033, 26410, 29394, -29264, -27209, -20148,
0, 20148, 27209, 29264, -29394, -26410, 30033, 20206,
20000, 19024, 6921, -5868, -7858, -7042, -11903, -12346,
0, 12346, 11903, 7042, 7858, 5868, -6921, -19024,
-20000, -20206, -30033, 26410, 29394, -29264, -27209, -20148,
// Frequency of 4
0, 27209, -29394, 30033, 20000, 6921, -7858, -11903,
0, 11903, 7858, -6921, -20000, -30033, 29394, -27209,
0, 27209, -29394, 30033, 20000, 6921, -7858, -11903,
0, 11903, 7858, -6921, -20000, -30033, 29394, -27209,
0, 27209, -29394, 30033, 20000, 6921, -7858, -11903,
0, 11903, 7858, -6921, -20000, -30033, 29394, -27209,
0, 27209, -29394, 30033, 20000, 6921, -7858, -11903,
0, 11903, 7858, -6921, -20000, -30033, 29394, -27209,
// Frequency of 8
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
0, -29394, 20000, -7858, 0, 7858, -20000, 29394,
};
// Pulse Wave (duty cycle = 12.5%)
s16 gEighthPulseWaveSample[] = {
// Frequency of 1
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, -32767, -32767, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// Frequency of 2
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, 0, 0, 0, 0, 0, 0,
// Frequency of 4
0, 0, 0, 0, 32767, 0, 0, 0,
0, 0, 0, 0, -32767, 0, 0, 0,
0, 0, 0, 0, 32767, 0, 0, 0,
0, 0, 0, 0, -32767, 0, 0, 0,
0, 0, 0, 0, 32767, 0, 0, 0,
0, 0, 0, 0, -32767, 0, 0, 0,
0, 0, 0, 0, 32767, 0, 0, 0,
0, 0, 0, 0, -32767, 0, 0, 0,
// Frequency of 8
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
};
// Pulse Wave (duty cycle = 25%)
s16 gQuarterPulseWaveSample[] = {
// Frequency of 1
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767,
0, 0, 0, 0, 0, 0, 0, 0,
// Frequency of 2
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, -32767, -32767, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32767, 32767, 32767, 32767, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-32767, -32767, -32767, -32767, 0, 0, 0, 0,
// Frequency of 4
0, 0, 0, 0, 32767, 32767, 0, 0,
0, 0, 0, 0, -32767, -32767, 0, 0,
0, 0, 0, 0, 32767, 32767, 0, 0,
0, 0, 0, 0, -32767, -32767, 0, 0,
0, 0, 0, 0, 32767, 32767, 0, 0,
0, 0, 0, 0, -32767, -32767, 0, 0,
0, 0, 0, 0, 32767, 32767, 0, 0,
0, 0, 0, 0, -32767, -32767, 0, 0,
// Frequency of 8
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
0, 0, 32767, 0, 0, 0, -32767, 0,
};
// clang-format on
s16* gWaveSamples[] = {
gSawtoothWaveSample, gTriangleWaveSample, gSineWaveSample, gSquareWaveSample, gWhiteNoiseSample,
D_8012EA90, gEighthPulseWaveSample, gQuarterPulseWaveSample, gQuarterPulseWaveSample,
};
f32 gBendPitchOneOctaveFrequencies[] = {
0.5f, 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f,
0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, 0.551614f,
0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, 0.579387f, 0.582558f,
0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.60195f, 0.605245f, 0.608557f, 0.611888f, 0.615236f,
0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f, 0.639196f, 0.642694f, 0.646212f, 0.649748f,
0.653304f, 0.65688f, 0.660475f, 0.664089f, 0.667724f, 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f,
0.689952f, 0.693727f, 0.697524f, 0.701341f, 0.70518f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f,
0.728655f, 0.732642f, 0.736652f, 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.76534f,
0.769529f, 0.77374f, 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f,
0.812696f, 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.83975f, 0.844346f, 0.848966f, 0.853613f,
0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.89659f, 0.901496f,
0.90643f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.94173f, 0.946884f, 0.952066f,
0.957277f, 0.962516f, 0.967783f, 0.97308f, 0.978405f, 0.98376f, 0.989144f, 0.994557f, 1.0f, 1.005473f,
1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f, 1.04463f, 1.050347f, 1.056095f, 1.061875f,
1.067687f, 1.07353f, 1.079405f, 1.085312f, 1.091252f, 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f,
1.127579f, 1.13375f, 1.139955f, 1.146193f, 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f,
1.190831f, 1.197348f, 1.203901f, 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f,
1.257631f, 1.264514f, 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f,
1.328178f, 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f,
1.402683f, 1.41036f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f, 1.473304f,
1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f, 1.547481f, 1.55595f,
1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f, 1.625392f, 1.634287f, 1.643231f,
1.652224f, 1.661266f, 1.670358f, 1.6795f, 1.688691f, 1.697933f, 1.707225f, 1.716569f, 1.725963f, 1.735409f,
1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f, 1.793179f, 1.802993f, 1.81286f, 1.822782f, 1.832757f,
1.842788f, 1.852873f, 1.863013f, 1.873209f, 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f,
1.946159f, 1.95681f, 1.96752f, 1.978287f, 1.989114f, 2.0f,
};
f32 gBendPitchTwoSemitonesFrequencies[] = {
0.890899f, 0.890899f, 0.89171f, 0.892521f, 0.893333f, 0.894146f, 0.89496f, 0.895774f, 0.89659f, 0.897406f,
0.898222f, 0.89904f, 0.899858f, 0.900677f, 0.901496f, 0.902317f, 0.903138f, 0.90396f, 0.904783f, 0.905606f,
0.90643f, 0.907255f, 0.908081f, 0.908907f, 0.909734f, 0.910562f, 0.911391f, 0.91222f, 0.91305f, 0.913881f,
0.914713f, 0.915545f, 0.916379f, 0.917213f, 0.918047f, 0.918883f, 0.919719f, 0.920556f, 0.921394f, 0.922232f,
0.923072f, 0.923912f, 0.924752f, 0.925594f, 0.926436f, 0.927279f, 0.928123f, 0.928968f, 0.929813f, 0.93066f,
0.931507f, 0.932354f, 0.933203f, 0.934052f, 0.934902f, 0.935753f, 0.936604f, 0.937457f, 0.93831f, 0.939164f,
0.940019f, 0.940874f, 0.94173f, 0.942587f, 0.943445f, 0.944304f, 0.945163f, 0.946023f, 0.946884f, 0.947746f,
0.948608f, 0.949472f, 0.950336f, 0.951201f, 0.952066f, 0.952933f, 0.9538f, 0.954668f, 0.955537f, 0.956406f,
0.957277f, 0.958148f, 0.95902f, 0.959893f, 0.960766f, 0.961641f, 0.962516f, 0.963392f, 0.964268f, 0.965146f,
0.966024f, 0.966903f, 0.967783f, 0.968664f, 0.969546f, 0.970428f, 0.971311f, 0.972195f, 0.97308f, 0.973965f,
0.974852f, 0.975739f, 0.976627f, 0.977516f, 0.978405f, 0.979296f, 0.980187f, 0.981079f, 0.981972f, 0.982865f,
0.98376f, 0.984655f, 0.985551f, 0.986448f, 0.987346f, 0.988244f, 0.989144f, 0.990044f, 0.990945f, 0.991847f,
0.992749f, 0.993653f, 0.994557f, 0.995462f, 0.996368f, 0.997275f, 0.998182f, 0.999091f, 1.0f, 1.00091f,
1.001821f, 1.002733f, 1.003645f, 1.004559f, 1.005473f, 1.006388f, 1.007304f, 1.00822f, 1.009138f, 1.010056f,
1.010975f, 1.011896f, 1.012816f, 1.013738f, 1.014661f, 1.015584f, 1.016508f, 1.017433f, 1.018359f, 1.019286f,
1.020214f, 1.021142f, 1.022071f, 1.023002f, 1.023933f, 1.024864f, 1.025797f, 1.026731f, 1.027665f, 1.0286f,
1.029536f, 1.030473f, 1.031411f, 1.03235f, 1.033289f, 1.03423f, 1.035171f, 1.036113f, 1.037056f, 1.038f,
1.038944f, 1.03989f, 1.040836f, 1.041783f, 1.042731f, 1.04368f, 1.04463f, 1.045581f, 1.046532f, 1.047485f,
1.048438f, 1.049392f, 1.050347f, 1.051303f, 1.05226f, 1.053217f, 1.054176f, 1.055135f, 1.056095f, 1.057056f,
1.058018f, 1.058981f, 1.059945f, 1.06091f, 1.061875f, 1.062842f, 1.063809f, 1.064777f, 1.065746f, 1.066716f,
1.067687f, 1.068658f, 1.069631f, 1.070604f, 1.071578f, 1.072554f, 1.07353f, 1.074507f, 1.075485f, 1.076463f,
1.077443f, 1.078424f, 1.079405f, 1.080387f, 1.08137f, 1.082355f, 1.08334f, 1.084325f, 1.085312f, 1.0863f,
1.087289f, 1.088278f, 1.089268f, 1.09026f, 1.091252f, 1.092245f, 1.093239f, 1.094234f, 1.09523f, 1.096226f,
1.097224f, 1.098223f, 1.099222f, 1.100222f, 1.101224f, 1.102226f, 1.103229f, 1.104233f, 1.105238f, 1.106244f,
1.10725f, 1.108258f, 1.109267f, 1.110276f, 1.111287f, 1.112298f, 1.11331f, 1.114323f, 1.115337f, 1.116352f,
1.117368f, 1.118385f, 1.119403f, 1.120422f, 1.121441f, 1.122462f,
};
f32 gNoteFrequencies[] = {
/* 0x00 */ 0.105112f, // NOTE_A0
/* 0x01 */ 0.111362f, // NOTE_BFLAT0
/* 0x02 */ 0.117984f, // NOTE_B0
/* 0x03 */ 0.125f, // NOTE_C1
/* 0x04 */ 0.132433f, // NOTE_DFLAT1
/* 0x05 */ 0.140308f, // NOTE_D1
/* 0x06 */ 0.148651f, // NOTE_EFLAT1
/* 0x07 */ 0.15749f, // NOTE_E1
/* 0x08 */ 0.166855f, // NOTE_F1
/* 0x09 */ 0.176777f, // NOTE_GFLAT1
/* 0x0A */ 0.187288f, // NOTE_G1
/* 0x0B */ 0.198425f, // NOTE_AFLAT1
/* 0x0C */ 0.210224f, // NOTE_A1
/* 0x0D */ 0.222725f, // NOTE_BFLAT1
/* 0x0E */ 0.235969f, // NOTE_B1
/* 0x0F */ 0.25f, // NOTE_C2
/* 0x10 */ 0.264866f, // NOTE_DFLAT2
/* 0x11 */ 0.280616f, // NOTE_D2
/* 0x12 */ 0.297302f, // NOTE_EFLAT2
/* 0x13 */ 0.31498f, // NOTE_E2
/* 0x14 */ 0.33371f, // NOTE_F2
/* 0x15 */ 0.353553f, // NOTE_GFLAT2
/* 0x16 */ 0.374577f, // NOTE_G2
/* 0x17 */ 0.39685f, // NOTE_AFLAT2
/* 0x18 */ 0.420448f, // NOTE_A2
/* 0x19 */ 0.445449f, // NOTE_BFLAT2
/* 0x1A */ 0.471937f, // NOTE_B2
/* 0x1B */ 0.5f, // NOTE_C3
/* 0x1C */ 0.529732f, // NOTE_DFLAT3
/* 0x1D */ 0.561231f, // NOTE_D3
/* 0x1E */ 0.594604f, // NOTE_EFLAT3
/* 0x1F */ 0.629961f, // NOTE_E3
/* 0x20 */ 0.66742f, // NOTE_F3
/* 0x21 */ 0.707107f, // NOTE_GFLAT3
/* 0x22 */ 0.749154f, // NOTE_G3
/* 0x23 */ 0.793701f, // NOTE_AFLAT3
/* 0x24 */ 0.840897f, // NOTE_A3
/* 0x25 */ 0.890899f, // NOTE_BFLAT3
/* 0x26 */ 0.943875f, // NOTE_B3
/* 0x27 */ 1.0f, // NOTE_C4 (Middle C)
/* 0x28 */ 1.059463f, // NOTE_DFLAT4
/* 0x29 */ 1.122462f, // NOTE_D4
/* 0x2A */ 1.189207f, // NOTE_EFLAT4
/* 0x2B */ 1.259921f, // NOTE_E4
/* 0x2C */ 1.33484f, // NOTE_F4
/* 0x2D */ 1.414214f, // NOTE_GFLAT4
/* 0x2E */ 1.498307f, // NOTE_G4
/* 0x2F */ 1.587401f, // NOTE_AFLAT4
/* 0x30 */ 1.681793f, // NOTE_A4
/* 0x31 */ 1.781798f, // NOTE_BFLAT4
/* 0x32 */ 1.887749f, // NOTE_B4
/* 0x33 */ 2.0f, // NOTE_C5
/* 0x34 */ 2.118926f, // NOTE_DFLAT5
/* 0x35 */ 2.244924f, // NOTE_D5
/* 0x36 */ 2.378414f, // NOTE_EFLAT5
/* 0x37 */ 2.519842f, // NOTE_E5
/* 0x38 */ 2.66968f, // NOTE_F5
/* 0x39 */ 2.828428f, // NOTE_GFLAT5
/* 0x3A */ 2.996615f, // NOTE_G5
/* 0x3B */ 3.174803f, // NOTE_AFLAT5
/* 0x3C */ 3.363586f, // NOTE_A5
/* 0x3D */ 3.563596f, // NOTE_BFLAT5
/* 0x3E */ 3.775498f, // NOTE_B5
/* 0x3F */ 4.0f, // NOTE_C6
/* 0x40 */ 4.237853f, // NOTE_DFLAT6
/* 0x41 */ 4.489849f, // NOTE_D6
/* 0x42 */ 4.756829f, // NOTE_EFLAT6
/* 0x43 */ 5.039685f, // NOTE_E6
/* 0x44 */ 5.33936f, // NOTE_F6
/* 0x45 */ 5.656855f, // NOTE_GFLAT6
/* 0x46 */ 5.993229f, // NOTE_G6
/* 0x47 */ 6.349606f, // NOTE_AFLAT6
/* 0x48 */ 6.727173f, // NOTE_A6
/* 0x49 */ 7.127192f, // NOTE_BFLAT6
/* 0x4A */ 7.550996f, // NOTE_B6
/* 0x4B */ 8.0f, // NOTE_C7
/* 0x4C */ 8.475705f, // NOTE_DFLAT7
/* 0x4D */ 8.979697f, // NOTE_D7
/* 0x4E */ 9.513658f, // NOTE_EFLAT7
/* 0x4F */ 10.07937f, // NOTE_E7
/* 0x50 */ 10.6787205f, // NOTE_F7
/* 0x51 */ 11.31371f, // NOTE_GFLAT7
/* 0x52 */ 11.986459f, // NOTE_G7
/* 0x53 */ 12.699211f, // NOTE_AFLAT7
/* 0x54 */ 13.454346f, // NOTE_A7
/* 0x55 */ 14.254383f, // NOTE_BFLAT7
/* 0x56 */ 15.101993f, // NOTE_B7
/* 0x57 */ 16.0f, // NOTE_C8
/* 0x58 */ 16.95141f, // NOTE_DFLAT8
/* 0x59 */ 17.959395f, // NOTE_D8
/* 0x5A */ 19.027315f, // NOTE_EFLAT8
/* 0x5B */ 20.15874f, // NOTE_E8
/* 0x5C */ 21.35744f, // NOTE_F8
/* 0x5D */ 22.62742f, // NOTE_GFLAT8
/* 0x5E */ 23.972918f, // NOTE_G8
/* 0x5F */ 25.398422f, // NOTE_AFLAT8
/* 0x60 */ 26.908691f, // NOTE_A8
/* 0x61 */ 28.508766f, // NOTE_BFLAT8
/* 0x62 */ 30.203985f, // NOTE_B8
/* 0x63 */ 32.0f, // NOTE_C9
/* 0x64 */ 33.90282f, // NOTE_DFLAT9
/* 0x65 */ 35.91879f, // NOTE_D9
/* 0x66 */ 38.05463f, // NOTE_EFLAT9
/* 0x67 */ 40.31748f, // NOTE_E9
/* 0x68 */ 42.71488f, // NOTE_F9
/* 0x69 */ 45.25484f, // NOTE_GFLAT9
/* 0x6A */ 47.945835f, // NOTE_G9
/* 0x6B */ 50.796845f, // NOTE_AFLAT9
/* 0x6C */ 53.817383f, // NOTE_A9
/* 0x6D */ 57.017532f, // NOTE_BFLAT9
/* 0x6E */ 60.40797f, // NOTE_B9
/* 0x6F */ 64.0f, // NOTE_C10
/* 0x70 */ 67.80564f, // NOTE_DFLAT10
/* 0x71 */ 71.83758f, // NOTE_D10
/* 0x72 */ 76.10926f, // NOTE_EFLAT10
/* 0x73 */ 80.63496f, // NOTE_E10
/* 0x74 */ 85.42976f, // NOTE_F10
/* 0x75 */ 0.055681f, // NOTE_BFLATNEG1
/* 0x76 */ 0.058992f, // NOTE_BNEG1
/* 0x77 */ 0.0625f, // NOTE_C0
/* 0x78 */ 0.066216f, // NOTE_DFLAT0
/* 0x79 */ 0.070154f, // NOTE_D0
/* 0x7A */ 0.074325f, // NOTE_EFLAT0
/* 0x7B */ 0.078745f, // NOTE_E0
/* 0x7C */ 0.083427f, // NOTE_F0
/* 0x7D */ 0.088388f, // NOTE_GFLAT0
/* 0x7E */ 0.093644f, // NOTE_G0
/* 0x7F */ 0.099213f, // NOTE_AFLAT0
};
u8 gDefaultShortNoteVelocityTable[] = {
12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127,
};
u8 gDefaultShortNoteGateTimeTable[] = {
229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0,
};
AdsrEnvelope gDefaultEnvelope[] = {
// OTRTODO: Byteswapped manually for quick audio support.
{ 0x0100, 0x007D },
{ 0xE803, 0x007D },
{ 0xFFFF, 0x0000 },
{ 0x0000, 0x0000 },
/* { 1, 32000 },
{ 1000, 32000 },
{ -1, 0 },
{ 0, 0 },
*/
};
NoteSubEu gZeroNoteSub = { 0 };
NoteSubEu gDefaultNoteSub = {
{ 1, 1, 0, 0, 0, 0, 0, 0 }, { 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
u16 gHeadsetPanQuantization[64] = {
60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18,
16, 14, 12, 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
s32 D_8012FBA4 = 0;
// clang-format off
s16 D_8012FBA8[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 500, 0, 0, 0, 0,
0, 0, 0, 500, 0, 0, 0, 0,
0, 0, 0, 500, 0, 0, 0, 0,
0, 0, 0, 500, 0, 0, 0, 0,
};
// clang-format on
f32 gHeadsetPanVolume[] = {
1.0f, 0.995386f, 0.990772f, 0.986157f, 0.981543f, 0.976929f, 0.972315f, 0.967701f, 0.963087f, 0.958472f,
0.953858f, 0.949244f, 0.94463f, 0.940016f, 0.935402f, 0.930787f, 0.926173f, 0.921559f, 0.916945f, 0.912331f,
0.907717f, 0.903102f, 0.898488f, 0.893874f, 0.88926f, 0.884646f, 0.880031f, 0.875417f, 0.870803f, 0.866189f,
0.861575f, 0.856961f, 0.852346f, 0.847732f, 0.843118f, 0.838504f, 0.83389f, 0.829276f, 0.824661f, 0.820047f,
0.815433f, 0.810819f, 0.806205f, 0.801591f, 0.796976f, 0.792362f, 0.787748f, 0.783134f, 0.77852f, 0.773906f,
0.769291f, 0.764677f, 0.760063f, 0.755449f, 0.750835f, 0.74622f, 0.741606f, 0.736992f, 0.732378f, 0.727764f,
0.72315f, 0.718535f, 0.713921f, 0.709307f, 0.70537f, 0.70211f, 0.69885f, 0.695591f, 0.692331f, 0.689071f,
0.685811f, 0.682551f, 0.679291f, 0.676031f, 0.672772f, 0.669512f, 0.666252f, 0.662992f, 0.659732f, 0.656472f,
0.653213f, 0.649953f, 0.646693f, 0.643433f, 0.640173f, 0.636913f, 0.633654f, 0.630394f, 0.627134f, 0.623874f,
0.620614f, 0.617354f, 0.614094f, 0.610835f, 0.607575f, 0.604315f, 0.601055f, 0.597795f, 0.594535f, 0.591276f,
0.588016f, 0.584756f, 0.581496f, 0.578236f, 0.574976f, 0.571717f, 0.568457f, 0.565197f, 0.561937f, 0.558677f,
0.555417f, 0.552157f, 0.548898f, 0.545638f, 0.542378f, 0.539118f, 0.535858f, 0.532598f, 0.529339f, 0.526079f,
0.522819f, 0.519559f, 0.516299f, 0.513039f, 0.50978f, 0.50652f, 0.50326f, 0.5f,
};
f32 gStereoPanVolume[] = {
0.707f, 0.716228f, 0.725457f, 0.734685f, 0.743913f, 0.753142f, 0.76237f, 0.771598f, 0.780827f, 0.790055f,
0.799283f, 0.808512f, 0.81774f, 0.826968f, 0.836197f, 0.845425f, 0.854654f, 0.863882f, 0.87311f, 0.882339f,
0.891567f, 0.900795f, 0.910024f, 0.919252f, 0.92848f, 0.937709f, 0.946937f, 0.956165f, 0.965394f, 0.974622f,
0.98385f, 0.993079f, 0.997693f, 0.988465f, 0.979236f, 0.970008f, 0.960779f, 0.951551f, 0.942323f, 0.933095f,
0.923866f, 0.914638f, 0.905409f, 0.896181f, 0.886953f, 0.877724f, 0.868496f, 0.859268f, 0.850039f, 0.840811f,
0.831583f, 0.822354f, 0.813126f, 0.803898f, 0.794669f, 0.785441f, 0.776213f, 0.766984f, 0.757756f, 0.748528f,
0.739299f, 0.730071f, 0.720843f, 0.711614f, 0.695866f, 0.673598f, 0.651331f, 0.629063f, 0.606795f, 0.584528f,
0.56226f, 0.539992f, 0.517724f, 0.495457f, 0.473189f, 0.450921f, 0.428654f, 0.406386f, 0.384118f, 0.36185f,
0.339583f, 0.317315f, 0.295047f, 0.27278f, 0.250512f, 0.228244f, 0.205976f, 0.183709f, 0.161441f, 0.139173f,
0.116905f, 0.094638f, 0.07237f, 0.050102f, 0.027835f, 0.005567f, 0.00835f, 0.019484f, 0.030618f, 0.041752f,
0.052886f, 0.06402f, 0.075154f, 0.086287f, 0.097421f, 0.108555f, 0.119689f, 0.130823f, 0.141957f, 0.153091f,
0.164224f, 0.175358f, 0.186492f, 0.197626f, 0.20876f, 0.219894f, 0.231028f, 0.242161f, 0.253295f, 0.264429f,
0.275563f, 0.286697f, 0.297831f, 0.308965f, 0.320098f, 0.331232f, 0.342366f, 0.3535f,
};
f32 gDefaultPanVolume[] = {
1.0f, 0.999924f, 0.999694f, 0.999312f, 0.998776f, 0.998088f, 0.997248f, 0.996254f, 0.995109f, 0.993811f,
0.992361f, 0.990759f, 0.989006f, 0.987101f, 0.985045f, 0.982839f, 0.980482f, 0.977976f, 0.97532f, 0.972514f,
0.96956f, 0.966457f, 0.963207f, 0.959809f, 0.956265f, 0.952574f, 0.948737f, 0.944755f, 0.940629f, 0.936359f,
0.931946f, 0.92739f, 0.922692f, 0.917853f, 0.912873f, 0.907754f, 0.902497f, 0.897101f, 0.891567f, 0.885898f,
0.880093f, 0.874153f, 0.868079f, 0.861873f, 0.855535f, 0.849066f, 0.842467f, 0.835739f, 0.828884f, 0.821901f,
0.814793f, 0.807561f, 0.800204f, 0.792725f, 0.785125f, 0.777405f, 0.769566f, 0.76161f, 0.753536f, 0.745348f,
0.737045f, 0.72863f, 0.720103f, 0.711466f, 0.70272f, 0.693867f, 0.684908f, 0.675843f, 0.666676f, 0.657406f,
0.648036f, 0.638567f, 0.629f, 0.619337f, 0.609579f, 0.599728f, 0.589785f, 0.579752f, 0.56963f, 0.559421f,
0.549126f, 0.538748f, 0.528287f, 0.517745f, 0.507124f, 0.496425f, 0.485651f, 0.474802f, 0.46388f, 0.452888f,
0.441826f, 0.430697f, 0.419502f, 0.408243f, 0.396921f, 0.385538f, 0.374097f, 0.362598f, 0.351044f, 0.339436f,
0.327776f, 0.316066f, 0.304308f, 0.292503f, 0.280653f, 0.268761f, 0.256827f, 0.244854f, 0.232844f, 0.220798f,
0.208718f, 0.196606f, 0.184465f, 0.172295f, 0.160098f, 0.147877f, 0.135634f, 0.12337f, 0.111087f, 0.098786f,
0.086471f, 0.074143f, 0.061803f, 0.049454f, 0.037097f, 0.024734f, 0.012368f, 0.0f,
};
s16 sLowPassFilterData[16 * 8] = {
/* 0x0 */ 0, 0, 0, 32767, 0, 0, 0, 0, // Identity filter (delta function)
/* 0x1 */ 3854, 4188, 4398, 4469, 4398, 4188, 3854, 3416,
/* 0x2 */ 3415, 4314, 4915, 5126, 4915, 4314, 3415, 2351,
/* 0x3 */ 2636, 4433, 5762, 6252, 5762, 4433, 2636, 849,
/* 0x4 */ 1334, 4196, 6646, 7609, 6646, 4196, 1334, -802,
/* 0x5 */ -265, 3421, 7292, 8944, 7292, 3421, -265, -1863,
/* 0x6 */ -1558, 2065, 7146, 9546, 7146, 2065, -1558, -1682,
/* 0x7 */ -2353, 726, 7441, 11028, 7441, 726, -2353, -697,
/* 0x8 */ -2252, -693, 7121, 11962, 7121, -693, -2252, 668,
/* 0x9 */ -1373, -1819, 6299, 12298, 6299, -1819, -1373, 1484,
/* 0xA */ -213, -2740, 5843, 13680, 5843, -2740, -213, 1494,
/* 0xB */ 980, -3081, 4883, 14286, 4883, -3081, 980, 590,
/* 0xC */ 1769, -2973, 3866, 14981, 3866, -2973, 1769, -568,
/* 0xD */ 2023, -2554, 2911, 16397, 2911, -2554, 2023, -1391,
/* 0xE */ 1766, -1918, 2016, 19800, 2016, -1918, 1766, -1564,
/* 0xF */ 841, -853, 863, 26829, 863, -853, 841, -820,
};
s16 sHighPassFilterData[15 * 8] = {
/* 0x0 */ -289, -291, -289, 30736, -289, -291, -289, -290,
/* 0x1 */ -464, -467, -467, 29506, -467, -467, -464, -463,
/* 0x2 */ -662, -670, -672, 28101, -672, -670, -662, -656,
/* 0x3 */ -839, -855, -861, 26830, -861, -855, -839, -822,
/* 0x4 */ -996, -1024, -1038, 25685, -1038, -1024, -996, -963,
/* 0x5 */ -1184, -1236, -1266, 24272, -1266, -1236, -1184, -1118,
/* 0x6 */ -1357, -1450, -1506, 22900, -1506, -1450, -1357, -1238,
/* 0x7 */ -1514, -1680, -1784, 21498, -1784, -1680, -1514, -1307,
/* 0x8 */ -1613, -1877, -2048, 20390, -2048, -1877, -1613, -1298,
/* 0x9 */ -1657, -2185, -2559, 18869, -2559, -2185, -1657, -1093,
/* 0xA */ -1524, -2395, -3078, 18030, -3078, -2395, -1524, -739,
/* 0xB */ -1253, -2504, -3621, 17642, -3621, -2504, -1253, -367,
/* 0xC */ -525, -2367, -4732, 17517, -4732, -2367, -525, 0,
/* 0xD */ -34, -1762, -5706, 17503, -5706, -1762, -34, -258,
/* 0xE */ -772, -3, -6985, 17240, -6985, -3, -772, -3,
};
s16 D_80130418[8 * 8] = {
/* 0x0 */ 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137,
/* 0x1 */ 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392,
/* 0x2 */ 0, -3211, -6392, -9511, -12539, -15446, -18204, -20787,
/* 0x3 */ -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609,
/* 0x4 */ -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329,
/* 0x5 */ -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609,
/* 0x6 */ -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329,
/* 0x7 */ -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211,
};

View file

@ -0,0 +1,335 @@
#include <math.h>
#include "ultra64.h"
#include "global.h"
#define ROUND(num) floorf((num) * 100) / 100;
void Audio_SequenceChannelProcessSound(SequenceChannel* channel, s32 recalculateVolume, s32 b) {
f32 channelVolume;
f32 chanFreqScale;
s32 i;
if (channel->changes.s.volume || recalculateVolume) {
channelVolume = ROUND((channel->volume * (channel->volumeScale * channel->seqPlayer->appliedFadeVolume)) *
channel->seqPlayer->gameVolume);
if (channel->seqPlayer->muted && (channel->muteBehavior & 0x20)) {
channelVolume = channel->seqPlayer->muteVolumeScale * channelVolume;
}
channel->appliedVolume = (channelVolume * channelVolume);
}
if (channel->changes.s.pan) {
channel->pan = channel->newPan * channel->panChannelWeight;
}
chanFreqScale = channel->freqScale;
if (b != 0) {
chanFreqScale *= channel->seqPlayer->unk_34;
channel->changes.s.freqScale = true;
}
for (i = 0; i < 4; i++) {
SequenceLayer* layer = channel->layers[i];
if (layer != NULL && layer->enabled && layer->note != NULL) {
if (layer->notePropertiesNeedInit) {
layer->noteFreqScale = layer->freqScale * chanFreqScale;
layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume;
layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7;
layer->notePropertiesNeedInit = false;
} else {
if (channel->changes.s.freqScale) {
layer->noteFreqScale = layer->freqScale * chanFreqScale;
}
if (channel->changes.s.volume || recalculateVolume) {
layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume;
}
if (channel->changes.s.pan) {
layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7;
}
}
}
}
channel->changes.asByte = 0;
}
void Audio_SequencePlayerProcessSound(SequencePlayer* seqPlayer) {
s32 i;
if (seqPlayer->fadeTimer != 0) {
seqPlayer->fadeVolume += seqPlayer->fadeVelocity;
seqPlayer->recalculateVolume = true;
if (seqPlayer->fadeVolume > 1.0f) {
seqPlayer->fadeVolume = 1.0f;
}
if (seqPlayer->fadeVolume < 0) {
seqPlayer->fadeVolume = 0;
}
if (--seqPlayer->fadeTimer == 0 && seqPlayer->state == 2) {
AudioSeq_SequencePlayerDisable(seqPlayer);
return;
}
}
if (seqPlayer->recalculateVolume) {
seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale;
}
for (i = 0; i < 16; i++) {
if (seqPlayer->channels[i]->enabled == 1) {
Audio_SequenceChannelProcessSound(seqPlayer->channels[i], seqPlayer->recalculateVolume, seqPlayer->unk_0b1);
}
}
seqPlayer->recalculateVolume = false;
}
f32 Audio_GetPortamentoFreqScale(Portamento* p) {
u32 loResCur;
f32 result;
p->cur += p->speed;
loResCur = (p->cur >> 8) & 0xFF;
if (loResCur >= 127) {
loResCur = 127;
p->mode = 0;
}
result = 1.0f + p->extent * (gBendPitchOneOctaveFrequencies[loResCur + 128] - 1.0f);
return result;
}
s16 Audio_GetVibratoPitchChange(VibratoState* vib) {
s32 index;
vib->time += (s32)vib->rate;
index = (vib->time >> 10) & 0x3F;
return vib->curve[index];
}
f32 Audio_GetVibratoFreqScale(VibratoState* vib) {
static f32 D_80130510 = 0.0f;
static s32 D_80130514 = 0;
f32 pitchChange;
f32 extent;
f32 invExtent;
f32 result;
f32 temp;
SequenceChannel* channel = vib->channel;
if (vib->delay != 0) {
vib->delay--;
return 1;
}
//! @bug this probably meant to compare with gAudioContext.sequenceChannelNone.
//! -1 isn't used as a channel pointer anywhere else.
if (channel != ((SequenceChannel*)(-1))) {
if (vib->extentChangeTimer) {
if (vib->extentChangeTimer == 1) {
vib->extent = (s32)channel->vibratoExtentTarget;
} else {
vib->extent += ((s32)channel->vibratoExtentTarget - vib->extent) / (s32)vib->extentChangeTimer;
}
vib->extentChangeTimer--;
} else if (channel->vibratoExtentTarget != (s32)vib->extent) {
if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) {
vib->extent = (s32)channel->vibratoExtentTarget;
}
}
if (vib->rateChangeTimer) {
if (vib->rateChangeTimer == 1) {
vib->rate = (s32)channel->vibratoRateTarget;
} else {
vib->rate += ((s32)channel->vibratoRateTarget - vib->rate) / (s32)vib->rateChangeTimer;
}
vib->rateChangeTimer--;
} else if (channel->vibratoRateTarget != (s32)vib->rate) {
if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) {
vib->rate = (s32)channel->vibratoRateTarget;
}
}
}
if (vib->extent == 0) {
return 1.0f;
}
pitchChange = Audio_GetVibratoPitchChange(vib) + 32768.0f;
temp = vib->extent / 4096.0f;
extent = temp + 1.0f;
invExtent = 1.0f / extent;
result = 1.0f / ((extent - invExtent) * pitchChange / 65536.0f + invExtent);
D_80130510 += result;
D_80130514++;
return result;
}
void Audio_NoteVibratoUpdate(Note* note) {
if (note->portamento.mode != 0) {
note->playbackState.portamentoFreqScale = Audio_GetPortamentoFreqScale(&note->portamento);
}
if (note->vibratoState.active) {
note->playbackState.vibratoFreqScale = Audio_GetVibratoFreqScale(&note->vibratoState);
}
}
void Audio_NoteVibratoInit(Note* note) {
VibratoState* vib;
SequenceChannel* channel;
note->playbackState.vibratoFreqScale = 1.0f;
vib = &note->vibratoState;
vib->active = 1;
vib->time = 0;
vib->curve = gWaveSamples[2];
vib->channel = note->playbackState.parentLayer->channel;
channel = vib->channel;
if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) {
vib->extent = (s32)channel->vibratoExtentTarget;
} else {
vib->extent = (s32)channel->vibratoExtentStart;
}
if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) {
vib->rate = (s32)channel->vibratoRateTarget;
} else {
vib->rate = (s32)channel->vibratoRateStart;
}
vib->delay = channel->vibratoDelay;
}
void Audio_NotePortamentoInit(Note* note) {
note->playbackState.portamentoFreqScale = 1.0f;
note->portamento = note->playbackState.parentLayer->portamento;
}
void Audio_AdsrInit(AdsrState* adsr, AdsrEnvelope* envelope, s16* volOut) {
adsr->action.asByte = 0;
adsr->delay = 0;
adsr->envelope = envelope;
adsr->sustain = 0.0f;
adsr->current = 0.0f;
// (An older versions of the audio engine used in Super Mario 64 did
// adsr->volOut = volOut. That line and associated struct member were
// removed, but the function parameter was forgotten and remains.)
}
f32 Audio_AdsrUpdate(AdsrState* adsr) {
u8 state = adsr->action.s.state;
switch (state) {
case ADSR_STATE_DISABLED:
return 0.0f;
case ADSR_STATE_INITIAL: {
if (adsr->action.s.hang) {
adsr->action.s.state = ADSR_STATE_HANG;
break;
}
// fallthrough
}
case ADSR_STATE_START_LOOP:
adsr->envIndex = 0;
adsr->action.s.state = ADSR_STATE_LOOP;
// fallthrough
retry:
case ADSR_STATE_LOOP:
adsr->delay = (s16)_byteswap_ushort(adsr->envelope[adsr->envIndex].delay);
switch (adsr->delay) {
case ADSR_DISABLE:
adsr->action.s.state = ADSR_STATE_DISABLED;
break;
case ADSR_HANG:
adsr->action.s.state = ADSR_STATE_HANG;
break;
case ADSR_GOTO:
adsr->envIndex = (s16)_byteswap_ushort(adsr->envelope[adsr->envIndex].arg);
goto retry;
case ADSR_RESTART:
adsr->action.s.state = ADSR_STATE_INITIAL;
break;
default:
adsr->delay *= gAudioContext.audioBufferParameters.unk_24;
if (adsr->delay == 0) {
adsr->delay = 1;
}
adsr->target = (s16)_byteswap_ushort(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
adsr->target = adsr->target * adsr->target;
adsr->velocity = (adsr->target - adsr->current) / adsr->delay;
adsr->action.s.state = ADSR_STATE_FADE;
adsr->envIndex++;
break;
}
if (adsr->action.s.state != ADSR_STATE_FADE) {
break;
}
// fallthrough
case ADSR_STATE_FADE:
adsr->current += adsr->velocity;
if (--adsr->delay <= 0) {
adsr->action.s.state = ADSR_STATE_LOOP;
}
// fallthrough
case ADSR_STATE_HANG:
break;
case ADSR_STATE_DECAY:
case ADSR_STATE_RELEASE: {
adsr->current -= adsr->fadeOutVel;
if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) {
if (adsr->current < adsr->sustain) {
adsr->current = adsr->sustain;
adsr->delay = 128;
adsr->action.s.state = ADSR_STATE_SUSTAIN;
}
break;
}
if (adsr->current < 0.00001f) {
adsr->current = 0.0f;
adsr->action.s.state = ADSR_STATE_DISABLED;
}
break;
}
case ADSR_STATE_SUSTAIN:
adsr->delay -= 1;
if (adsr->delay == 0) {
adsr->action.s.state = ADSR_STATE_RELEASE;
}
break;
}
if (adsr->action.s.decay) {
adsr->action.s.state = ADSR_STATE_DECAY;
adsr->action.s.decay = false;
}
if (adsr->action.s.release) {
adsr->action.s.state = ADSR_STATE_RELEASE;
adsr->action.s.release = false;
}
if (adsr->current < 0.0f) {
return 0.0f;
}
if (adsr->current > 1.0f) {
return 1.0f;
}
return adsr->current;
}

1405
soh/src/code/audio_heap.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,88 @@
#include "global.h"
u8 D_8016F0E0[0xA0]; // unused
AudioContext gAudioContext;
void (*D_801755D0)(void);
s32 D_801755D8[3]; // unused
const s16 D_8014A6C0[] = {
0x1C00, // unused
0x0030, // gTatumsPerBeat
};
const AudioContextInitSizes D_8014A6C4 = { 0x37F00, 0xE0E0, 0xBCE0 };
ReverbSettings D_80133420[][3] = {
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x20, 0x0800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0x0, 0x0 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0xB, 0xB },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x38, 0x2800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0x7, 0x7 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x50, 0x5000, 0, 0, 0x7FFF, 0x1000, 0x1000, 0xFF, 0x3000, 0x7, 0x7 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x1800, 0x1800, 0xFF, 0x3000, 0x7, 0x7 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x40, 0x5C00, 0, 0, 0x7FFF, 0x2000, 0x2000, 0xFF, 0x3000, 0x4, 0x4 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x30, 0x6000, 0, 0, 0x7FFF, 0x1000, 0x1000, 0xFF, 0x3000, 0xA, 0xA },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x30, 0x6800, 0, 0, 0x7FFF, 0x1400, 0x1400, 0xFF, 0x3000, 0x6, 0x6 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 2, 0x50, 0x5000, 0, 0, 0x7FFF, 0xD000, 0x3000, 0xFF, 0x3000, 0x0, 0x0 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x20, 0x0000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0x0, 0x0 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0xB, 0xB },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
},
{
{ 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
{ 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 },
},
};
AudioSpec gAudioSpecs[18] = {
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 22050, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
};

2157
soh/src/code/audio_load.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,929 @@
#include "global.h"
#include "Cvar.h"
void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) {
f32 volRight, volLeft;
s32 smallPanIndex;
u64 pad;
u8 strongLeft;
u8 strongRight;
f32 vel;
u8 pan;
u8 reverbVol;
StereoData sp24;
s32 stereoHeadsetEffects = note->playbackState.stereoHeadsetEffects;
vel = attrs->velocity;
pan = attrs->pan;
reverbVol = attrs->reverbVol;
sp24 = attrs->stereo.s;
sub->bitField0 = note->noteSubEu.bitField0;
sub->bitField1 = note->noteSubEu.bitField1;
sub->sound.samples = note->noteSubEu.sound.samples;
sub->unk_06 = note->noteSubEu.unk_06;
Audio_NoteSetResamplingRate(sub, attrs->frequency);
pan &= 0x7F;
sub->bitField0.stereoStrongRight = false;
sub->bitField0.stereoStrongLeft = false;
sub->bitField0.stereoHeadsetEffects = sp24.stereoHeadsetEffects;
sub->bitField0.usesHeadsetPanEffects = sp24.usesHeadsetPanEffects;
if (stereoHeadsetEffects && gAudioContext.soundMode == 1) {
smallPanIndex = pan >> 1;
if (smallPanIndex > 0x3F) {
smallPanIndex = 0x3F;
}
sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex];
sub->headsetPanRight = gHeadsetPanQuantization[0x3F - smallPanIndex];
sub->bitField1.usesHeadsetPanEffects2 = true;
volLeft = gHeadsetPanVolume[pan];
volRight = gHeadsetPanVolume[0x7F - pan];
} else if (stereoHeadsetEffects && gAudioContext.soundMode == 0) {
strongLeft = strongRight = 0;
sub->headsetPanRight = 0;
sub->headsetPanLeft = 0;
sub->bitField1.usesHeadsetPanEffects2 = false;
volLeft = gStereoPanVolume[pan];
volRight = gStereoPanVolume[0x7F - pan];
if (pan < 0x20) {
strongLeft = 1;
} else if (pan > 0x60) {
strongRight = 1;
}
sub->bitField0.stereoStrongRight = strongRight;
sub->bitField0.stereoStrongLeft = strongLeft;
switch (sp24.bit2) {
case 0:
break;
case 1:
sub->bitField0.stereoStrongRight = sp24.strongRight;
sub->bitField0.stereoStrongLeft = sp24.strongLeft;
break;
case 2:
sub->bitField0.stereoStrongRight = sp24.strongRight | strongRight;
sub->bitField0.stereoStrongLeft = sp24.strongLeft | strongLeft;
break;
case 3:
sub->bitField0.stereoStrongRight = sp24.strongRight ^ strongRight;
sub->bitField0.stereoStrongLeft = sp24.strongLeft ^ strongLeft;
break;
}
} else if (gAudioContext.soundMode == 3) {
sub->bitField0.stereoHeadsetEffects = false;
sub->bitField0.usesHeadsetPanEffects = false;
volLeft = 0.707f; // approx 1/sqrt(2)
volRight = 0.707f;
} else {
sub->bitField0.stereoStrongRight = sp24.strongRight;
sub->bitField0.stereoStrongLeft = sp24.strongLeft;
volLeft = gDefaultPanVolume[pan];
volRight = gDefaultPanVolume[0x7F - pan];
}
vel = 0.0f > vel ? 0.0f : vel;
vel = 1.0f < vel ? 1.0f : vel;
float master_vol = CVar_GetFloat("gGameMasterVolume", 1.0f);
sub->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f)) * master_vol;
sub->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f)) * master_vol;
sub->unk_2 = attrs->unk_1;
sub->filter = attrs->filter;
sub->unk_07 = attrs->unk_14;
sub->unk_0E = attrs->unk_16;
sub->reverbVol = reverbVol;
}
void Audio_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRateInput) {
f32 resamplingRate = 0.0f;
if (resamplingRateInput < 2.0f) {
noteSubEu->bitField1.hasTwoParts = false;
if (1.99998f < resamplingRateInput) {
resamplingRate = 1.99998f;
} else {
resamplingRate = resamplingRateInput;
}
} else {
noteSubEu->bitField1.hasTwoParts = true;
if (3.99996f < resamplingRateInput) {
resamplingRate = 1.99998f;
} else {
resamplingRate = resamplingRateInput * 0.5f;
}
}
noteSubEu->resamplingRateFixedPoint = (s32)(resamplingRate * 32768.0f);
}
void Audio_NoteInit(Note* note) {
if (note->playbackState.parentLayer->adsr.releaseRate == 0) {
Audio_AdsrInit(&note->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope,
&note->playbackState.adsrVolScaleUnused);
} else {
Audio_AdsrInit(&note->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope,
&note->playbackState.adsrVolScaleUnused);
}
note->playbackState.unk_04 = 0;
note->playbackState.adsr.action.s.state = ADSR_STATE_INITIAL;
note->noteSubEu = gDefaultNoteSub;
}
void Audio_NoteDisable(Note* note) {
if (note->noteSubEu.bitField0.needsInit == true) {
note->noteSubEu.bitField0.needsInit = false;
}
note->playbackState.priority = 0;
note->noteSubEu.bitField0.enabled = false;
note->playbackState.unk_04 = 0;
note->noteSubEu.bitField0.finished = false;
note->playbackState.parentLayer = NO_LAYER;
note->playbackState.prevParentLayer = NO_LAYER;
note->playbackState.adsr.action.s.state = ADSR_STATE_DISABLED;
note->playbackState.adsr.current = 0;
}
void Audio_ProcessNotes(void) {
s32 pad[2];
NoteAttributes* attrs;
NoteSubEu* noteSubEu2;
NoteSubEu* noteSubEu;
Note* note;
NotePlaybackState* playbackState;
NoteSubAttributes subAttrs;
u8 bookOffset;
f32 scale;
s32 i;
for (i = 0; i < gAudioContext.numNotes; i++) {
note = &gAudioContext.notes[i];
noteSubEu2 = &gAudioContext.noteSubsEu[gAudioContext.noteSubEuOffset + i];
playbackState = &note->playbackState;
if (playbackState->parentLayer != NO_LAYER) {
if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) {
playbackState->adsr.action.s.release = true;
playbackState->adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
playbackState->priority = 1;
playbackState->unk_04 = 2;
goto out;
} else if (!playbackState->parentLayer->enabled && playbackState->unk_04 == 0 &&
playbackState->priority >= 1) {
// do nothing
} else if (playbackState->parentLayer->channel->seqPlayer == NULL) {
AudioSeq_SequenceChannelDisable(playbackState->parentLayer->channel);
playbackState->priority = 1;
playbackState->unk_04 = 1;
continue;
} else if (playbackState->parentLayer->channel->seqPlayer->muted &&
(playbackState->parentLayer->channel->muteBehavior & 0x40)) {
// do nothing
} else {
goto out;
}
Audio_SeqLayerNoteRelease(playbackState->parentLayer);
Audio_AudioListRemove(&note->listItem);
Audio_AudioListPushFront(&note->listItem.pool->decaying, &note->listItem);
playbackState->priority = 1;
playbackState->unk_04 = 2;
} else if (playbackState->unk_04 == 0 && playbackState->priority >= 1) {
continue;
}
out:
if (playbackState->priority != 0) {
if (1) {}
noteSubEu = &note->noteSubEu;
if (playbackState->unk_04 >= 1 || noteSubEu->bitField0.finished) {
if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED || noteSubEu->bitField0.finished) {
if (playbackState->wantedParentLayer != NO_LAYER) {
Audio_NoteDisable(note);
if (playbackState->wantedParentLayer->channel != NULL) {
Audio_NoteInitForLayer(note, playbackState->wantedParentLayer);
Audio_NoteVibratoInit(note);
Audio_NotePortamentoInit(note);
Audio_AudioListRemove(&note->listItem);
AudioSeq_AudioListPushBack(&note->listItem.pool->active, &note->listItem);
playbackState->wantedParentLayer = NO_LAYER;
// don't skip
} else {
Audio_NoteDisable(note);
Audio_AudioListRemove(&note->listItem);
AudioSeq_AudioListPushBack(&note->listItem.pool->disabled, &note->listItem);
playbackState->wantedParentLayer = NO_LAYER;
goto skip;
}
} else {
if (playbackState->parentLayer != NO_LAYER) {
playbackState->parentLayer->bit1 = true;
}
Audio_NoteDisable(note);
Audio_AudioListRemove(&note->listItem);
AudioSeq_AudioListPushBack(&note->listItem.pool->disabled, &note->listItem);
continue;
}
}
} else if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED) {
if (playbackState->parentLayer != NO_LAYER) {
playbackState->parentLayer->bit1 = true;
}
Audio_NoteDisable(note);
Audio_AudioListRemove(&note->listItem);
AudioSeq_AudioListPushBack(&note->listItem.pool->disabled, &note->listItem);
continue;
}
scale = Audio_AdsrUpdate(&playbackState->adsr);
Audio_NoteVibratoUpdate(note);
attrs = &playbackState->attributes;
if (playbackState->unk_04 == 1 || playbackState->unk_04 == 2) {
subAttrs.frequency = attrs->freqScale;
subAttrs.velocity = attrs->velocity;
subAttrs.pan = attrs->pan;
subAttrs.reverbVol = attrs->reverb;
subAttrs.stereo = attrs->stereo;
subAttrs.unk_1 = attrs->unk_1;
subAttrs.filter = attrs->filter;
subAttrs.unk_14 = attrs->unk_4;
subAttrs.unk_16 = attrs->unk_6;
bookOffset = noteSubEu->bitField1.bookOffset;
} else {
SequenceLayer* layer = playbackState->parentLayer;
SequenceChannel* channel = layer->channel;
subAttrs.frequency = layer->noteFreqScale;
subAttrs.velocity = layer->noteVelocity;
subAttrs.pan = layer->notePan;
if (layer->stereo.asByte == 0) {
subAttrs.stereo = channel->stereo;
} else {
subAttrs.stereo = layer->stereo;
}
subAttrs.reverbVol = channel->reverb;
subAttrs.unk_1 = channel->unk_0C;
subAttrs.filter = channel->filter;
subAttrs.unk_14 = channel->unk_0F;
subAttrs.unk_16 = channel->unk_20;
bookOffset = channel->bookOffset & 0x7;
if (channel->seqPlayer->muted && (channel->muteBehavior & 8)) {
subAttrs.frequency = 0.0f;
subAttrs.velocity = 0.0f;
}
}
subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale;
subAttrs.frequency *= gAudioContext.audioBufferParameters.resampleRate;
subAttrs.velocity *= scale;
Audio_InitNoteSub(note, noteSubEu2, &subAttrs);
noteSubEu->bitField1.bookOffset = bookOffset;
skip:;
}
}
}
SoundFontSound* Audio_InstrumentGetSound(Instrument* instrument, s32 semitone) {
SoundFontSound* sound;
if (semitone < instrument->normalRangeLo) {
sound = &instrument->lowNotesSound;
} else if (semitone <= instrument->normalRangeHi) {
sound = &instrument->normalNotesSound;
} else {
sound = &instrument->highNotesSound;
}
return sound;
}
Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) {
Instrument* inst;
if (fontId == 0xFF) {
return NULL;
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
gAudioContext.audioErrorFlags = fontId + 0x10000000;
return NULL;
}
if (instId >= gAudioContext.soundFonts[fontId].numInstruments) {
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000;
return NULL;
}
inst = gAudioContext.soundFonts[fontId].instruments[instId];
if (inst == NULL) {
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x1000000;
return inst;
}
return inst;
}
Drum* Audio_GetDrum(s32 fontId, s32 drumId) {
Drum* drum;
if (fontId == 0xFF) {
return NULL;
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
gAudioContext.audioErrorFlags = fontId + 0x10000000;
return NULL;
}
if (drumId >= gAudioContext.soundFonts[fontId].numDrums) {
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000;
return NULL;
}
drum = gAudioContext.soundFonts[fontId].drums[drumId];
if (drum == NULL) {
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x5000000;
}
return drum;
}
SoundFontSound* Audio_GetSfx(s32 fontId, s32 sfxId) {
SoundFontSound* sfx;
if (fontId == 0xFF) {
return NULL;
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
gAudioContext.audioErrorFlags = fontId + 0x10000000;
return NULL;
}
if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) {
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000;
return NULL;
}
sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId];
if (sfx == NULL) {
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x5000000;
}
if (sfx->sample == NULL) {
return NULL;
}
return sfx;
}
s32 Audio_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* value) {
if (fontId == 0xFF) {
return -1;
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
return -2;
}
switch (instrumentType) {
case 0:
if (index >= gAudioContext.soundFonts[fontId].numDrums) {
return -3;
}
gAudioContext.soundFonts[fontId].drums[index] = value;
break;
case 1:
if (index >= gAudioContext.soundFonts[fontId].numSfx) {
return -3;
}
gAudioContext.soundFonts[fontId].soundEffects[index] = *(SoundFontSound*)value;
break;
default:
if (index >= gAudioContext.soundFonts[fontId].numInstruments) {
return -3;
}
gAudioContext.soundFonts[fontId].instruments[index] = value;
break;
}
return 0;
}
void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
Note* note;
NoteAttributes* attrs;
SequenceChannel* chan;
s32 i;
if (layer == NO_LAYER) {
return;
}
layer->bit3 = false;
if (layer->note == NULL) {
return;
}
note = layer->note;
attrs = &note->playbackState.attributes;
if (note->playbackState.wantedParentLayer == layer) {
note->playbackState.wantedParentLayer = NO_LAYER;
}
if (note->playbackState.parentLayer != layer) {
if (note->playbackState.parentLayer == NO_LAYER && note->playbackState.wantedParentLayer == NO_LAYER &&
note->playbackState.prevParentLayer == layer && target != ADSR_STATE_DECAY) {
note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
note->playbackState.adsr.action.s.release = true;
}
return;
}
if (note->playbackState.adsr.action.s.state != ADSR_STATE_DECAY) {
attrs->freqScale = layer->noteFreqScale;
attrs->velocity = layer->noteVelocity;
attrs->pan = layer->notePan;
if (layer->channel != NULL) {
chan = layer->channel;
attrs->reverb = chan->reverb;
attrs->unk_1 = chan->unk_0C;
attrs->filter = chan->filter;
if (attrs->filter != NULL) {
for (i = 0; i < 8; i++) {
attrs->filterBuf[i] = attrs->filter[i];
}
attrs->filter = attrs->filterBuf;
}
attrs->unk_6 = chan->unk_20;
attrs->unk_4 = chan->unk_0F;
if (chan->seqPlayer->muted && (chan->muteBehavior & 8)) {
note->noteSubEu.bitField0.finished = true;
}
if (layer->stereo.asByte == 0) {
attrs->stereo = chan->stereo;
} else {
attrs->stereo = layer->stereo;
}
note->playbackState.priority = chan->someOtherPriority;
} else {
attrs->stereo = layer->stereo;
note->playbackState.priority = 1;
}
note->playbackState.prevParentLayer = note->playbackState.parentLayer;
note->playbackState.parentLayer = NO_LAYER;
if (target == ADSR_STATE_RELEASE) {
note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
note->playbackState.adsr.action.s.release = true;
note->playbackState.unk_04 = 2;
} else {
note->playbackState.unk_04 = 1;
note->playbackState.adsr.action.s.decay = true;
if (layer->adsr.releaseRate == 0) {
note->playbackState.adsr.fadeOutVel = gAudioContext.unk_3520[layer->channel->adsr.releaseRate];
} else {
note->playbackState.adsr.fadeOutVel = gAudioContext.unk_3520[layer->adsr.releaseRate];
}
note->playbackState.adsr.sustain =
((f32)(s32)(layer->channel->adsr.sustain) * note->playbackState.adsr.current) / 256.0f;
}
}
if (target == ADSR_STATE_DECAY) {
Audio_AudioListRemove(&note->listItem);
Audio_AudioListPushFront(&note->listItem.pool->decaying, &note->listItem);
}
}
void Audio_SeqLayerNoteDecay(SequenceLayer* layer) {
Audio_SeqLayerDecayRelease(layer, ADSR_STATE_DECAY);
}
void Audio_SeqLayerNoteRelease(SequenceLayer* layer) {
Audio_SeqLayerDecayRelease(layer, ADSR_STATE_RELEASE);
}
s32 Audio_BuildSyntheticWave(Note* note, SequenceLayer* layer, s32 waveId) {
f32 freqScale;
f32 ratio;
u8 sampleCountIndex;
if (waveId < 128) {
waveId = 128;
}
freqScale = layer->freqScale;
if (layer->portamento.mode != 0 && 0.0f < layer->portamento.extent) {
freqScale *= (layer->portamento.extent + 1.0f);
}
if (freqScale < 0.99999f) {
sampleCountIndex = 0;
ratio = 1.0465f;
} else if (freqScale < 1.99999f) {
sampleCountIndex = 1;
ratio = 0.52325f;
} else if (freqScale < 3.99999f) {
sampleCountIndex = 2;
ratio = 0.26263f;
} else {
sampleCountIndex = 3;
ratio = 0.13081f;
}
layer->freqScale *= ratio;
note->playbackState.waveId = waveId;
note->playbackState.sampleCountIndex = sampleCountIndex;
note->noteSubEu.sound.samples = &gWaveSamples[waveId - 128][sampleCountIndex * 64];
return sampleCountIndex;
}
void Audio_InitSyntheticWave(Note* note, SequenceLayer* layer) {
s32 sampleCountIndex;
s32 waveSampleCountIndex;
s32 waveId = layer->instOrWave;
if (waveId == 0xFF) {
waveId = layer->channel->instOrWave;
}
sampleCountIndex = note->playbackState.sampleCountIndex;
waveSampleCountIndex = Audio_BuildSyntheticWave(note, layer, waveId);
if (waveSampleCountIndex != sampleCountIndex) {
note->noteSubEu.unk_06 = waveSampleCountIndex * 4 + sampleCountIndex;
}
}
void Audio_InitNoteList(AudioListItem* list) {
list->prev = list;
list->next = list;
list->u.count = 0;
}
void Audio_InitNoteLists(NotePool* pool) {
Audio_InitNoteList(&pool->disabled);
Audio_InitNoteList(&pool->decaying);
Audio_InitNoteList(&pool->releasing);
Audio_InitNoteList(&pool->active);
pool->disabled.pool = pool;
pool->decaying.pool = pool;
pool->releasing.pool = pool;
pool->active.pool = pool;
}
void Audio_InitNoteFreeList(void) {
s32 i;
Audio_InitNoteLists(&gAudioContext.noteFreeLists);
for (i = 0; i < gAudioContext.numNotes; i++) {
gAudioContext.notes[i].listItem.u.value = &gAudioContext.notes[i];
gAudioContext.notes[i].listItem.prev = NULL;
AudioSeq_AudioListPushBack(&gAudioContext.noteFreeLists.disabled, &gAudioContext.notes[i].listItem);
}
}
void Audio_NotePoolClear(NotePool* pool) {
s32 i;
AudioListItem* source;
AudioListItem* cur;
AudioListItem* dest;
for (i = 0; i < 4; i++) {
switch (i) {
case 0:
source = &pool->disabled;
dest = &gAudioContext.noteFreeLists.disabled;
break;
case 1:
source = &pool->decaying;
dest = &gAudioContext.noteFreeLists.decaying;
break;
case 2:
source = &pool->releasing;
dest = &gAudioContext.noteFreeLists.releasing;
break;
case 3:
source = &pool->active;
dest = &gAudioContext.noteFreeLists.active;
break;
}
for (;;) {
cur = source->next;
if (cur == source || cur == NULL) {
break;
}
Audio_AudioListRemove(cur);
AudioSeq_AudioListPushBack(dest, cur);
}
}
}
void Audio_NotePoolFill(NotePool* pool, s32 count) {
s32 i;
s32 j;
Note* note;
AudioListItem* source;
AudioListItem* dest;
Audio_NotePoolClear(pool);
for (i = 0, j = 0; j < count; i++) {
if (i == 4) {
return;
}
switch (i) {
case 0:
source = &gAudioContext.noteFreeLists.disabled;
dest = &pool->disabled;
break;
case 1:
source = &gAudioContext.noteFreeLists.decaying;
dest = &pool->decaying;
break;
case 2:
source = &gAudioContext.noteFreeLists.releasing;
dest = &pool->releasing;
break;
case 3:
source = &gAudioContext.noteFreeLists.active;
dest = &pool->active;
break;
}
while (j < count) {
note = AudioSeq_AudioListPopBack(source);
if (note == NULL) {
break;
}
AudioSeq_AudioListPushBack(dest, &note->listItem);
j++;
}
}
}
void Audio_AudioListPushFront(AudioListItem* list, AudioListItem* item) {
// add 'item' to the front of the list given by 'list', if it's not in any list
if (item->prev == NULL) {
item->prev = list;
item->next = list->next;
list->next->prev = item;
list->next = item;
list->u.count++;
item->pool = list->pool;
}
}
void Audio_AudioListRemove(AudioListItem* item) {
// remove 'item' from the list it's in, if any
if (item->prev != NULL) {
item->prev->next = item->next;
item->next->prev = item->prev;
item->prev = NULL;
}
}
Note* Audio_FindNodeWithPrioLessThan(AudioListItem* list, s32 limit) {
AudioListItem* cur = list->next;
AudioListItem* best;
if (cur == list) {
return NULL;
}
for (best = cur; cur != list; cur = cur->next) {
if (((Note*)best->u.value)->playbackState.priority >= ((Note*)cur->u.value)->playbackState.priority) {
best = cur;
}
}
if (best == NULL) {
return NULL;
}
if (limit <= ((Note*)best->u.value)->playbackState.priority) {
return NULL;
}
return best->u.value;
}
void Audio_NoteInitForLayer(Note* note, SequenceLayer* layer) {
s32 pad[3];
s16 instId;
NotePlaybackState* playback = &note->playbackState;
NoteSubEu* sub = &note->noteSubEu;
note->playbackState.prevParentLayer = NO_LAYER;
note->playbackState.parentLayer = layer;
playback->priority = layer->channel->notePriority;
layer->notePropertiesNeedInit = true;
layer->bit3 = true;
layer->note = note;
layer->channel->noteUnused = note;
layer->channel->layerUnused = layer;
layer->noteVelocity = 0.0f;
Audio_NoteInit(note);
instId = layer->instOrWave;
if (instId == 0xFF) {
instId = layer->channel->instOrWave;
}
sub->sound.soundFontSound = layer->sound;
if (instId >= 0x80 && instId < 0xC0) {
sub->bitField1.isSyntheticWave = true;
} else {
sub->bitField1.isSyntheticWave = false;
}
if (sub->bitField1.isSyntheticWave) {
Audio_BuildSyntheticWave(note, layer, instId);
}
playback->fontId = layer->channel->fontId;
playback->stereoHeadsetEffects = layer->channel->stereoHeadsetEffects;
sub->bitField1.reverbIndex = layer->channel->reverbIndex & 3;
}
void func_800E82C0(Note* note, SequenceLayer* layer) {
// similar to Audio_NoteReleaseAndTakeOwnership, hard to say what the difference is
Audio_SeqLayerNoteRelease(note->playbackState.parentLayer);
note->playbackState.wantedParentLayer = layer;
}
void Audio_NoteReleaseAndTakeOwnership(Note* note, SequenceLayer* layer) {
note->playbackState.wantedParentLayer = layer;
note->playbackState.priority = layer->channel->notePriority;
note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
note->playbackState.adsr.action.s.release = true;
}
Note* Audio_AllocNoteFromDisabled(NotePool* pool, SequenceLayer* layer) {
Note* note = AudioSeq_AudioListPopBack(&pool->disabled);
if (note != NULL) {
Audio_NoteInitForLayer(note, layer);
Audio_AudioListPushFront(&pool->active, &note->listItem);
}
return note;
}
Note* Audio_AllocNoteFromDecaying(NotePool* pool, SequenceLayer* layer) {
Note* note = AudioSeq_AudioListPopBack(&pool->decaying);
if (note != NULL) {
Audio_NoteReleaseAndTakeOwnership(note, layer);
AudioSeq_AudioListPushBack(&pool->releasing, &note->listItem);
}
return note;
}
Note* Audio_AllocNoteFromActive(NotePool* pool, SequenceLayer* layer) {
Note* rNote;
Note* aNote;
s32 rPriority;
s32 aPriority;
rPriority = aPriority = 0x10;
rNote = Audio_FindNodeWithPrioLessThan(&pool->releasing, layer->channel->notePriority);
if (rNote != NULL) {
rPriority = rNote->playbackState.priority;
}
aNote = Audio_FindNodeWithPrioLessThan(&pool->active, layer->channel->notePriority);
if (aNote != NULL) {
aPriority = aNote->playbackState.priority;
}
if (rNote == NULL && aNote == NULL) {
return NULL;
}
if (aPriority < rPriority) {
Audio_AudioListRemove(&aNote->listItem);
func_800E82C0(aNote, layer);
AudioSeq_AudioListPushBack(&pool->releasing, &aNote->listItem);
aNote->playbackState.priority = layer->channel->notePriority;
return aNote;
}
rNote->playbackState.wantedParentLayer = layer;
rNote->playbackState.priority = layer->channel->notePriority;
return rNote;
}
Note* Audio_AllocNote(SequenceLayer* layer) {
Note* ret;
u32 policy = layer->channel->noteAllocPolicy;
if (policy & 1) {
ret = layer->note;
if (ret != NULL && ret->playbackState.prevParentLayer == layer &&
ret->playbackState.wantedParentLayer == NO_LAYER) {
Audio_NoteReleaseAndTakeOwnership(ret, layer);
Audio_AudioListRemove(&ret->listItem);
AudioSeq_AudioListPushBack(&ret->listItem.pool->releasing, &ret->listItem);
return ret;
}
}
if (policy & 2) {
if (!(ret = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromActive(&layer->channel->notePool, layer))) {
goto null_return;
}
return ret;
}
if (policy & 4) {
if (!(ret = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) &&
!(ret = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer))) {
goto null_return;
}
return ret;
}
if (policy & 8) {
if (!(ret = Audio_AllocNoteFromDisabled(&gAudioContext.noteFreeLists, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&gAudioContext.noteFreeLists, layer)) &&
!(ret = Audio_AllocNoteFromActive(&gAudioContext.noteFreeLists, layer))) {
goto null_return;
}
return ret;
}
if (!(ret = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDisabled(&gAudioContext.noteFreeLists, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) &&
!(ret = Audio_AllocNoteFromDecaying(&gAudioContext.noteFreeLists, layer)) &&
!(ret = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) &&
!(ret = Audio_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer)) &&
!(ret = Audio_AllocNoteFromActive(&gAudioContext.noteFreeLists, layer))) {
goto null_return;
}
return ret;
null_return:
layer->bit3 = true;
return NULL;
}
void Audio_NoteInitAll(void) {
Note* note;
s32 i;
for (i = 0; i < gAudioContext.numNotes; i++) {
note = &gAudioContext.notes[i];
note->noteSubEu = gZeroNoteSub;
note->playbackState.priority = 0;
note->playbackState.unk_04 = 0;
note->playbackState.parentLayer = NO_LAYER;
note->playbackState.wantedParentLayer = NO_LAYER;
note->playbackState.prevParentLayer = NO_LAYER;
note->playbackState.waveId = 0;
note->playbackState.attributes.velocity = 0.0f;
note->playbackState.adsrVolScaleUnused = 0;
note->playbackState.adsr.action.asByte = 0;
note->vibratoState.active = 0;
note->portamento.cur = 0;
note->portamento.speed = 0;
note->playbackState.stereoHeadsetEffects = false;
note->unk_BC = 0;
note->synthesisState.synthesisBuffers = AudioHeap_AllocDmaMemory(&gAudioContext.notesAndBuffersPool, 0x1E0);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,241 @@
#include "ultra64.h"
#include "global.h"
SoundParams sEnemyBankParams[] = {
{ 0x18, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x30, 0x3 },
{ 0x38, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x2 }, { 0x20, 0x81 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 },
{ 0x40, 0x3 }, { 0x20, 0x2000 }, { 0x28, 0x3 }, { 0x28, 0x3 }, { 0x20, 0x2 }, { 0x28, 0x3 },
{ 0x38, 0x3 }, { 0x30, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x40, 0x1 }, { 0x18, 0x0 }, { 0x14, 0x0 },
{ 0x14, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x44, 0x3 }, { 0x18, 0x0 }, { 0x30, 0x2 },
{ 0x32, 0x2 }, { 0x38, 0x1 }, { 0x20, 0x0 }, { 0x40, 0x1 }, { 0x18, 0x0 }, { 0x28, 0x0 },
{ 0x18, 0x0 }, { 0x30, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x14, 0x0 }, { 0x18, 0x80 },
{ 0x38, 0x2 }, { 0x30, 0x0 }, { 0x28, 0x1 }, { 0x30, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 },
{ 0x30, 0x0 }, { 0x18, 0x0 }, { 0x20, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x1 },
{ 0x40, 0x1 }, { 0x38, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x1 }, { 0x38, 0x1 },
{ 0x20, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x1 }, { 0x40, 0x1 }, { 0x30, 0x3 }, { 0x30, 0x2000 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x18, 0x3 }, { 0x30, 0x3 }, { 0x28, 0x0 }, { 0x30, 0x0 },
{ 0x18, 0x0 }, { 0x30, 0x0 }, { 0x28, 0x0 }, { 0x30, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 },
{ 0x28, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x1 }, { 0x14, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x0 },
{ 0x40, 0x1 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x0 }, { 0x38, 0x1 },
{ 0x20, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x14, 0x0 }, { 0x30, 0x3 }, { 0x20, 0x1 },
{ 0x20, 0x1 }, { 0x30, 0x2 }, { 0x30, 0x2 }, { 0x38, 0x2 }, { 0x40, 0x2 }, { 0x40, 0x2 },
{ 0x14, 0x81 }, { 0x34, 0x0 }, { 0x40, 0x0 }, { 0x20, 0x0 }, { 0x28, 0x0 }, { 0x28, 0x0 },
{ 0x30, 0x0 }, { 0x14, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x20, 0x0 }, { 0x30, 0x3 },
{ 0x30, 0x0 }, { 0x40, 0x1 }, { 0x40, 0x3 }, { 0x40, 0x1 }, { 0x28, 0x1 }, { 0x30, 0x3 },
{ 0x20, 0x0 }, { 0x38, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x0 }, { 0x20, 0x0 },
{ 0x38, 0x2000 }, { 0x30, 0x3 }, { 0x30, 0x2000 }, { 0x30, 0x0 }, { 0x14, 0x0 }, { 0x38, 0x1 },
{ 0x40, 0x1 }, { 0x14, 0x0 }, { 0x20, 0x0 }, { 0x20, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x1 },
{ 0x40, 0x1 }, { 0x30, 0x0 }, { 0x34, 0x1 }, { 0x40, 0x1 }, { 0x30, 0x3 }, { 0x30, 0x2 },
{ 0x30, 0x2000 }, { 0x20, 0x43 }, { 0x20, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x38, 0x3 }, { 0x30, 0x2000 }, { 0x30, 0x3 }, { 0x30, 0x2 }, { 0x30, 0x2000 }, { 0x30, 0x3 },
{ 0x38, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x403 }, { 0x38, 0x1 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x20, 0x0 }, { 0x34, 0x0 }, { 0x18, 0x1 }, { 0x20, 0x2000 },
{ 0x30, 0x2000 }, { 0x14, 0x3 }, { 0x28, 0x3 }, { 0x28, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 },
{ 0x20, 0x0 }, { 0x14, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x28, 0x0 }, { 0x28, 0x0 },
{ 0x40, 0x1 }, { 0x40, 0x1 }, { 0x20, 0x0 }, { 0x20, 0x0 }, { 0x14, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x38, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x1 }, { 0x28, 0x3 },
{ 0x28, 0x83 }, { 0x28, 0x82 }, { 0x30, 0x3 }, { 0x30, 0x2000 }, { 0x30, 0x2000 }, { 0x38, 0x1 },
{ 0x20, 0x0 }, { 0x34, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x34, 0x2000 }, { 0x20, 0x0 },
{ 0x38, 0x0 }, { 0x40, 0x1 }, { 0x30, 0x3 }, { 0x30, 0x2 }, { 0x30, 0x2 }, { 0x38, 0x3 },
{ 0x30, 0x3 }, { 0x32, 0x3 }, { 0x34, 0x3 }, { 0x34, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x28, 0x82 }, { 0x40, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x20, 0x0 }, { 0x20, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x80 }, { 0x30, 0x3 }, { 0x18, 0x3 },
{ 0x34, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x18, 0x3 }, { 0x30, 0x2000 }, { 0x38, 0x3 },
{ 0x30, 0x3 }, { 0x40, 0x3 }, { 0x40, 0x2000 }, { 0x38, 0x3 }, { 0x30, 0x2000 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x2 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x2000 }, { 0x38, 0x3 }, { 0x38, 0x3 }, { 0x38, 0x3 },
{ 0x38, 0x2000 }, { 0x40, 0x2000 }, { 0x18, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x2 }, { 0x20, 0x2 },
{ 0x24, 0x3 }, { 0x28, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x3 }, { 0x18, 0x1 }, { 0x34, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x34, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x1 }, { 0x14, 0x0 },
{ 0x40, 0x1 }, { 0x30, 0x1 }, { 0x30, 0x1 }, { 0x30, 0x1 }, { 0x38, 0x3 }, { 0x30, 0x0 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x38, 0x3 }, { 0x30, 0x2 }, { 0x38, 0x3 },
{ 0x38, 0x3 }, { 0x30, 0x83 }, { 0x38, 0x3 }, { 0x30, 0x3 }, { 0x34, 0x3 }, { 0x20, 0x2 },
{ 0x34, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x20, 0x3 }, { 0x14, 0x0 }, { 0x20, 0x1 },
{ 0x30, 0x3 }, { 0x40, 0x1 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x20, 0x0 }, { 0x20, 0x0 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x28, 0x2 }, { 0x30, 0x0 },
{ 0x38, 0x1 }, { 0x28, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x40, 0x3 },
{ 0x14, 0x0 }, { 0x30, 0x0 }, { 0x38, 0x1 }, { 0x30, 0x1 }, { 0x40, 0x1 }, { 0x28, 0x0 },
{ 0x28, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x2000 }, { 0x38, 0x3 }, { 0x38, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x34, 0x3 },
{ 0x38, 0x3 }, { 0x40, 0x3 }, { 0x10, 0x0 }, { 0x34, 0x0 }, { 0x18, 0x0 }, { 0x30, 0x0 },
{ 0x14, 0x0 }, { 0x34, 0x0 }, { 0x28, 0x1 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x30, 0x0 },
{ 0x38, 0x3 }, { 0x20, 0x0 }, { 0x20, 0x2 }, { 0x30, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x38, 0x3 }, { 0x30, 0x3 }, { 0x20, 0x2000 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x40, 0x1 },
{ 0x30, 0x0 }, { 0x20, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x2000 },
{ 0x30, 0x3 }, { 0x30, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x18, 0x0 }, { 0x28, 0x0 },
{ 0x34, 0x0 }, { 0x34, 0x0 }, { 0x34, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x30, 0x3 },
{ 0x30, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x38, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x40, 0x3 }, { 0x40, 0x2 }, { 0x18, 0x0 }, { 0x44, 0x3 }, { 0x34, 0x0 }, { 0x18, 0x0 },
{ 0x30, 0x0 }, { 0x38, 0x1 }, { 0x40, 0x1 }, { 0x18, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 },
{ 0x38, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 }, { 0x36, 0x3 }, { 0x34, 0x3 }, { 0x28, 0x82 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x0 }, { 0x30, 0x2000 }, { 0x30, 0x2000 }, { 0x30, 0x2000 }, { 0x30, 0x0 }, { 0x30, 0x2000 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x28, 0x3 }, { 0x30, 0x3 }, { 0x40, 0x3 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x0 }, { 0x20, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x38, 0x3 }, { 0x38, 0x3 },
{ 0x20, 0x3 }, { 0x30, 0x3 }, { 0x44, 0x3 }, { 0x30, 0x83 }, { 0x30, 0x3 }, { 0x30, 0x3 },
{ 0x34, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x20, 0x2 }, { 0x30, 0x3 }, { 0x20, 0x3 },
{ 0x30, 0x0 }, { 0x30, 0x2 }, { 0x40, 0x2 }, { 0x40, 0x3 }, { 0x34, 0x2 }, { 0x30, 0x3 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x1 }, { 0x34, 0x3 }, { 0x24, 0x3 }, { 0x34, 0x1 },
{ 0x20, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x8, 0x1 }, { 0x30, 0x1 }, { 0x30, 0x3 },
{ 0x38, 0x3 }, { 0x20, 0x2000 }, { 0x34, 0x3 }, { 0x34, 0x2000 }, { 0x8, 0x0 }, { 0x40, 0x3 },
{ 0x34, 0x3 },
};
SoundParams sPlayerBankParams[] = {
{ 0x20, 0x480 }, { 0x20, 0x480 }, { 0x20, 0x480 }, { 0x20, 0x480 }, { 0x20, 0x440 }, { 0x20, 0x440 },
{ 0x20, 0x440 }, { 0x20, 0x440 }, { 0x20, 0x480 }, { 0x20, 0x440 }, { 0x20, 0x480 }, { 0x20, 0x400 },
{ 0x20, 0x400 }, { 0x20, 0x400 }, { 0x20, 0x400 }, { 0x20, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 },
{ 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 },
{ 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x400 },
{ 0x30, 0x400 }, { 0x30, 0x400 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 },
{ 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 },
{ 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 }, { 0x40, 0x440 },
{ 0x30, 0x80 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x400 }, { 0x30, 0x400 },
{ 0x30, 0x400 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x80 }, { 0x30, 0x400 }, { 0x30, 0x400 },
{ 0x40, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x402 }, { 0x30, 0x400 }, { 0x30, 0x40 }, { 0x30, 0x40 },
{ 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x40 },
{ 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 },
{ 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 },
{ 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 }, { 0x80, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x400 }, { 0x30, 0x400 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x80 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x2000 }, { 0x30, 0xC00 }, { 0x30, 0x400 },
{ 0x30, 0x400 }, { 0x30, 0x400 }, { 0x20, 0x80 }, { 0x20, 0x80 }, { 0x20, 0x80 }, { 0x20, 0x80 },
{ 0x20, 0x40 }, { 0x20, 0x40 }, { 0x20, 0x40 }, { 0x20, 0x40 }, { 0x20, 0x80 }, { 0x20, 0x80 },
{ 0x20, 0x80 }, { 0x20, 0x0 }, { 0x20, 0x0 }, { 0x20, 0x0 }, { 0x20, 0x0 }, { 0x20, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 },
{ 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 },
{ 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 }, { 0x40, 0x0 },
{ 0x40, 0x0 }, { 0x40, 0x0 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 },
{ 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 },
{ 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 }, { 0x30, 0x440 },
{ 0x30, 0xC00 }, { 0x30, 0x80 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x60, 0x2 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x800 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 },
};
SoundParams sItemBankParams[] = {
{ 0x30, 0x8040 }, { 0x30, 0x40 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x440 }, { 0x30, 0x440 },
{ 0x60, 0x83 }, { 0x30, 0x440 }, { 0x80, 0x43 }, { 0x30, 0x0 }, { 0x30, 0x40 }, { 0x30, 0x400 },
{ 0x30, 0x401 }, { 0x50, 0x0 }, { 0x90, 0x2 }, { 0x50, 0x2 }, { 0x30, 0x400 }, { 0x40, 0x2 },
{ 0x30, 0x40 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x34, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x80 }, { 0x30, 0x40 }, { 0x30, 0x400 }, { 0x20, 0x400 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x60, 0x43 },
{ 0x30, 0x1 }, { 0x30, 0x401 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0xA0, 0x2 }, { 0xA0, 0x2 },
{ 0x30, 0x400 }, { 0x30, 0x0 }, { 0x60, 0x0 }, { 0x60, 0x0 }, { 0x60, 0x0 }, { 0x30, 0x400 },
{ 0x30, 0x0 }, { 0x60, 0x81 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x60, 0x8003 }, { 0x60, 0x8003 },
{ 0x60, 0x8003 }, { 0x30, 0x4000 }, { 0x30, 0x4000 }, { 0x30, 0x40 }, { 0x80, 0x3 }, { 0x80, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x40 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x80, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 },
};
SoundParams sEnvBankParams[] = {
{ 0x70, 0x640 }, { 0x80, 0x40 }, { 0x30, 0x0 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x40, 0x40 },
{ 0x30, 0x480 }, { 0x38, 0x2 }, { 0x30, 0x40 }, { 0x30, 0x40 }, { 0x80, 0x2 }, { 0xA0, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x2 }, { 0x30, 0x40 },
{ 0x30, 0x40 }, { 0x30, 0x0 }, { 0x60, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x82 },
{ 0x30, 0x0 }, { 0x40, 0x0 }, { 0x38, 0x0 }, { 0x28, 0x0 }, { 0x60, 0x0 }, { 0x70, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0xA0, 0x2008 }, { 0x20, 0x2 }, { 0x30, 0x0 },
{ 0x30, 0x800 }, { 0x30, 0x8800 }, { 0x30, 0x8000 }, { 0x30, 0x2 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x400 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x80 },
{ 0x60, 0x42 }, { 0x10, 0x0 }, { 0xA0, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x10 }, { 0x30, 0x3 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x0 }, { 0xA0, 0x3 },
{ 0x30, 0x0 }, { 0x30, 0x400 }, { 0x30, 0x400 }, { 0x70, 0x13 }, { 0x60, 0x8000 }, { 0x30, 0x8000 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x2003 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x2010 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x40, 0x0 }, { 0x30, 0xC2 }, { 0x70, 0x2 },
{ 0x60, 0x2 }, { 0x30, 0x0 }, { 0x60, 0x1 }, { 0x30, 0x2 }, { 0x30, 0x0 }, { 0x90, 0x3 },
{ 0x90, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x3800 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x803 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x2 }, { 0x30, 0x2 }, { 0x40, 0x0 }, { 0x1C, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x60, 0x200 }, { 0x30, 0x800 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x3 },
{ 0x30, 0x3 }, { 0x30, 0x2000 }, { 0x30, 0x2000 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x80 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x800 }, { 0x30, 0x800 }, { 0x30, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x8000 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x60, 0x3 },
{ 0x30, 0x80 }, { 0x30, 0x2000 }, { 0x30, 0x0 }, { 0x30, 0x1 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x2 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0xA0, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0xC0 }, { 0x30, 0x2 },
{ 0x30, 0x2 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x0 }, { 0x30, 0x4083 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x80, 0x0 }, { 0x60, 0x0 }, { 0x90, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x60, 0xC3 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x30, 0x3 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0xA0, 0x800 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x2 }, { 0x30, 0x0 }, { 0x30, 0x3 }, { 0x20, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 },
};
SoundParams sSystemBankParams[] = {
{ 0xC0, 0x0 }, { 0xC0, 0x0 }, { 0xB0, 0x20 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x50, 0x0 },
{ 0x30, 0x20 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x28, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x18, 0x0 }, { 0x2C, 0x0 }, { 0x2C, 0x0 }, { 0x20, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x20, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x60, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 },
};
SoundParams sOcarinaBankParams[] = {
{ 0x30, 0x0 }, { 0x30, 0x20 }, { 0x30, 0x642 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
};
SoundParams sVoiceBankParams[] = {
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x20, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x442 }, { 0x30, 0x442 }, { 0x30, 0x402 },
{ 0x30, 0x402 }, { 0x50, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 },
{ 0x30, 0x482 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x80, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x20, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x442 },
{ 0x30, 0x442 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x50, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x481 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 },
{ 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x30, 0x402 }, { 0x60, 0x20 }, { 0x30, 0x20 },
{ 0x30, 0x20 }, { 0x60, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x0 },
{ 0x30, 0x0 }, { 0x30, 0x0 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8043 }, { 0x30, 0x8043 }, { 0x30, 0x8043 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 }, { 0x30, 0x8041 },
{ 0x30, 0x8041 }, { 0x30, 0x8041 },
};
SoundParams* gSoundParams[7] = {
sPlayerBankParams, sItemBankParams, sEnvBankParams, sEnemyBankParams,
sSystemBankParams, sOcarinaBankParams, sVoiceBankParams,
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
#include "global.h"
#include "vt.h"
void func_800430A0(CollisionContext* colCtx, s32 bgId, Actor* actor) {
MtxF prevTransform;
MtxF prevTransformInv;
MtxF curTransform;
Vec3f pos;
Vec3f tempPos;
if (DynaPoly_IsBgIdBgActor(bgId)) {
SkinMatrix_SetTranslateRotateYXZScale(
&prevTransform, colCtx->dyna.bgActors[bgId].prevTransform.scale.x,
colCtx->dyna.bgActors[bgId].prevTransform.scale.y, colCtx->dyna.bgActors[bgId].prevTransform.scale.z,
colCtx->dyna.bgActors[bgId].prevTransform.rot.x, colCtx->dyna.bgActors[bgId].prevTransform.rot.y,
colCtx->dyna.bgActors[bgId].prevTransform.rot.z, colCtx->dyna.bgActors[bgId].prevTransform.pos.x,
colCtx->dyna.bgActors[bgId].prevTransform.pos.y, colCtx->dyna.bgActors[bgId].prevTransform.pos.z);
if (SkinMatrix_Invert(&prevTransform, &prevTransformInv) != 2) {
SkinMatrix_SetTranslateRotateYXZScale(
&curTransform, colCtx->dyna.bgActors[bgId].curTransform.scale.x,
colCtx->dyna.bgActors[bgId].curTransform.scale.y, colCtx->dyna.bgActors[bgId].curTransform.scale.z,
colCtx->dyna.bgActors[bgId].curTransform.rot.x, colCtx->dyna.bgActors[bgId].curTransform.rot.y,
colCtx->dyna.bgActors[bgId].curTransform.rot.z, colCtx->dyna.bgActors[bgId].curTransform.pos.x,
colCtx->dyna.bgActors[bgId].curTransform.pos.y, colCtx->dyna.bgActors[bgId].curTransform.pos.z);
SkinMatrix_Vec3fMtxFMultXYZ(&prevTransformInv, &actor->world.pos, &tempPos);
SkinMatrix_Vec3fMtxFMultXYZ(&curTransform, &tempPos, &pos);
actor->world.pos = pos;
if (BGCHECK_XYZ_ABSMAX <= pos.x || pos.x <= -BGCHECK_XYZ_ABSMAX || BGCHECK_XYZ_ABSMAX <= pos.y ||
pos.y <= -BGCHECK_XYZ_ABSMAX || BGCHECK_XYZ_ABSMAX <= pos.z || pos.z <= -BGCHECK_XYZ_ABSMAX) {
osSyncPrintf(VT_FGCOL(RED));
//! @bug file and line are not passed to osSyncPrintf
// "Position is not valid"
osSyncPrintf(
"BGCheckCollection_typicalActorPos():位置が妥当ではありません。\npos (%f,%f,%f) file:%s line:%d\n",
pos.x, pos.y, pos.z);
osSyncPrintf(VT_RST);
}
}
}
}
/**
* Rotate actor
*/
void func_800432A0(CollisionContext* colCtx, s32 bgId, Actor* actor) {
if (DynaPoly_IsBgIdBgActor(bgId)) {
s16 rot = colCtx->dyna.bgActors[bgId].curTransform.rot.y - colCtx->dyna.bgActors[bgId].prevTransform.rot.y;
if (actor->id == ACTOR_PLAYER) {
((Player*)actor)->currentYaw += rot;
}
actor->shape.rot.y += rot;
actor->world.rot.y += rot;
}
}
void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId) {
if (DynaPoly_IsBgIdBgActor(bgId)) {
DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, bgId);
if (dynaActor != NULL) {
func_800434A8(dynaActor);
if (CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_26)) {
func_80043538(dynaActor);
}
}
}
}
/**
* Transform actor's position
* `actor` is the actor to update
*/
s32 func_800433A4(CollisionContext* colCtx, s32 bgId, Actor* actor) {
s32 result = false;
DynaPolyActor* dynaActor;
if (DynaPoly_IsBgIdBgActor(bgId) == false) {
return false;
}
if ((colCtx->dyna.bgActorFlags[bgId] & 2) || !(colCtx->dyna.bgActorFlags[bgId] & 1)) {
return false;
}
dynaActor = DynaPoly_GetActor(colCtx, bgId);
if (dynaActor == NULL) {
return false;
}
if (dynaActor->unk_15C & 1) {
func_800430A0(colCtx, bgId, actor);
result = true;
}
if (dynaActor->unk_15C & 2) {
func_800432A0(colCtx, bgId, actor);
result = true;
}
return result;
}

View file

@ -0,0 +1,114 @@
#include "global.h"
void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags) {
dynaActor->bgId = -1;
dynaActor->unk_15C = flags;
dynaActor->unk_160 = 0;
dynaActor->unk_150 = 0.0f;
dynaActor->unk_154 = 0.0f;
}
void func_800434A0(DynaPolyActor* dynaActor) {
dynaActor->unk_160 = 0;
}
void func_800434A8(DynaPolyActor* dynaActor) {
dynaActor->unk_160 |= 1;
}
void func_800434B8(DynaPolyActor* dynaActor) {
dynaActor->unk_160 |= 2;
}
void func_800434C8(CollisionContext* colCtx, s32 floorBgId) {
DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, floorBgId);
if (dynaActor != NULL) {
func_800434B8(dynaActor);
}
}
void func_800434F8(DynaPolyActor* dynaActor) {
dynaActor->unk_160 |= 4;
}
void func_80043508(CollisionContext* colCtx, s32 floorBgId) {
DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, floorBgId);
if (dynaActor != NULL) {
func_800434F8(dynaActor);
}
}
void func_80043538(DynaPolyActor* dynaActor) {
dynaActor->unk_160 |= 8;
}
s32 func_80043548(DynaPolyActor* dynaActor) {
if (dynaActor->unk_160 & 1) {
return true;
} else {
return false;
}
}
s32 func_8004356C(DynaPolyActor* dynaActor) {
if (dynaActor->unk_160 & 2) {
return true;
} else {
return false;
}
}
s32 func_80043590(DynaPolyActor* dynaActor) {
if (dynaActor->unk_160 & 4) {
return true;
} else {
return false;
}
}
s32 func_800435B4(DynaPolyActor* dynaActor) {
if (dynaActor->unk_160 & 8) {
return true;
} else {
return false;
}
}
s32 func_800435D8(GlobalContext* globalCtx, DynaPolyActor* dynaActor, s16 arg2, s16 arg3, s16 arg4) {
Vec3f posA;
Vec3f posB;
Vec3f posResult;
f32 sin = Math_SinS(dynaActor->unk_158);
f32 cos = Math_CosS(dynaActor->unk_158);
s32 bgId;
CollisionPoly* poly;
f32 a2;
f32 a3;
f32 sign = (0.0f <= dynaActor->unk_150) ? 1.0f : -1.0f;
a2 = (f32)arg2 - 0.1f;
posA.x = dynaActor->actor.world.pos.x + (a2 * cos);
posA.y = dynaActor->actor.world.pos.y + arg4;
posA.z = dynaActor->actor.world.pos.z - (a2 * sin);
a3 = (f32)arg3 - 0.1f;
posB.x = sign * a3 * sin + posA.x;
posB.y = posA.y;
posB.z = sign * a3 * cos + posA.z;
if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &posA, &posB, &posResult, &poly, true, false, false, true, &bgId,
&dynaActor->actor, 0.0f)) {
return false;
}
posA.x = (dynaActor->actor.world.pos.x * 2) - posA.x;
posA.z = (dynaActor->actor.world.pos.z * 2) - posA.z;
posB.x = sign * a3 * sin + posA.x;
posB.z = sign * a3 * cos + posA.z;
if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &posA, &posB, &posResult, &poly, true, false, false, true, &bgId,
&dynaActor->actor, 0.0f)) {
return false;
}
return true;
}

View file

@ -0,0 +1,33 @@
#include "global.h"
void Flags_UnsetAllEnv(GlobalContext* globalCtx) {
u8 i;
for (i = 0; i < 20; i++) {
globalCtx->envFlags[i] = 0;
}
}
void Flags_SetEnv(GlobalContext* globalCtx, s16 flag) {
s16 index = flag / 16;
s16 bit = flag % 16;
s16 mask = 1 << bit;
globalCtx->envFlags[index] |= mask;
}
void Flags_UnsetEnv(GlobalContext* globalCtx, s16 flag) {
s16 index = flag / 16;
s16 bit = flag % 16;
s16 mask = (1 << bit) ^ 0xFFFF;
globalCtx->envFlags[index] &= mask;
}
s32 Flags_GetEnv(GlobalContext* globalCtx, s16 flag) {
s16 index = flag / 16;
s16 bit = flag % 16;
s16 mask = 1 << bit;
return globalCtx->envFlags[index] & mask;
}

View file

@ -0,0 +1,40 @@
#include "global.h"
f32 func_8006C510(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5) {
char pad[0x1C];
f32 sq = SQ(arg0);
f32 cube = sq * arg0;
return (((cube + cube) - sq * 3.0f) + 1.0f) * arg2 + (sq * 3.0f - (cube + cube)) * arg3 +
((cube - (sq + sq)) + arg0) * arg4 * arg1 + (cube - sq) * arg5 * arg1;
}
f32 func_8006C5A8(f32 target, TransformData* transData, s32 refIdx) {
s32 i;
s32 j;
if (target <= transData->unk_02) {
return transData->unk_08;
}
if (target >= transData[refIdx - 1].unk_02) {
return transData[refIdx - 1].unk_08;
}
for (i = 0;; i++) {
j = i + 1;
if (transData[j].unk_02 > target) {
if (transData[i].unk_00 & 1) {
return transData[i].unk_08;
} else if (transData[i].unk_00 & 2) {
return transData[i].unk_08 +
((target - (f32)transData[i].unk_02) / ((f32)transData[j].unk_02 - (f32)transData[i].unk_02)) *
(transData[j].unk_08 - transData[i].unk_08);
} else {
f32 diff = (f32)transData[j].unk_02 - (f32)transData[i].unk_02;
return func_8006C510((target - transData[i].unk_02) / ((f32)transData[j].unk_02 - transData[i].unk_02),
diff * (1.0f / 30.0f), transData[i].unk_08, transData[j].unk_08,
transData[i].unk_06, transData[j].unk_04);
}
}
}
}

View file

@ -0,0 +1,224 @@
#include "global.h"
#include "textures/icon_item_static/icon_item_static.h"
#include "textures/icon_item_24_static/icon_item_24_static.h"
#include "textures/parameter_static/parameter_static.h"
// Bit Flag array in which gBitFlags[n] is literally (1 << n)
u32 gBitFlags[] = {
(1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7),
(1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15),
(1 << 16), (1 << 17), (1 << 18), (1 << 19), (1 << 20), (1 << 21), (1 << 22), (1 << 23),
(1 << 24), (1 << 25), (1 << 26), (1 << 27), (1 << 28), (1 << 29), (1 << 30), (1 << 31),
};
u16 gEquipMasks[] = { 0x000F, 0x00F0, 0x0F00, 0xF000 };
u16 gEquipNegMasks[] = { 0xFFF0, 0xFF0F, 0xF0FF, 0x0FFF };
u32 gUpgradeMasks[] = {
0x00000007, 0x00000038, 0x000001C0, 0x00000E00, 0x00003000, 0x0001C000, 0x000E0000, 0x00700000,
};
u32 gUpgradeNegMasks[] = {
0xFFFFFFF8, 0xFFFFFFC7, 0xFFFFFE3F, 0xFFFFF1FF, 0xFFFFCFFF, 0xFFFE3FFF, 0xFFF1FFFF, 0xFF8FFFFF,
};
u8 gEquipShifts[] = { 0, 4, 8, 12 };
u8 gUpgradeShifts[] = { 0, 3, 6, 9, 12, 14, 17, 20 };
u16 gUpgradeCapacities[][4] = {
{ 0, 30, 40, 50 }, // Quivers
{ 0, 20, 30, 40 }, // Bomb Bags
{ 0, 0, 0, 0 }, // Unused (Scale)
{ 0, 0, 0, 0 }, // Unused (Strength)
{ 99, 200, 500, 500 }, // Wallets
{ 0, 30, 40, 50 }, // Deku Seed Bullet Bags
{ 0, 10, 20, 30 }, // Deku Stick Upgrades
{ 0, 20, 30, 40 }, // Deku Nut Upgrades
};
u32 gGsFlagsMasks[] = { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 };
u32 gGsFlagsShifts[] = { 0, 8, 16, 24 };
void* gItemIcons[] = {
gDekuStickIconTex,
gDekuNutIconTex,
gBombIconTex,
gFairyBowIconTex,
gFireArrowIconTex,
gDinsFireIconTex,
gFairySlingshotIconTex,
gFairyOcarinaIconTex,
gOcarinaofTimeIconTex,
gBombchuIconTex,
gHookshotIconTex,
gLongshotIconTex,
gIceArrowIconTex,
gFaroresWindIconTex,
gBoomerangIconTex,
gLensofTruthIconTex,
gMagicBeansIconTex,
gMegatonHammerIconTex,
gLightArrowIconTex,
gNayrusLoveIconTex,
gEmptyBottleIconTex,
gRedPotionIconTex,
gGreenPotionIconTex,
gBluePotionIconTex,
gBottledFairyIconTex,
gFishIconTex,
gMilkFullIconTex,
gRutosLetterIconTex,
gBlueFireIconTex,
gBugIconTex,
gBigPoeIconTex,
gMilkhalfIconTex,
gPoeIconTex,
gWeirdEggIconTex,
gCuccoIconTex,
gZeldasLetterIconTex,
gKeatonMaskIconTex,
gSkullMaskIconTex,
gSpookyMaskIconTex,
gBunnyHoodIconTex,
gGoronMaskIconTex,
gZoraMaskIconTex,
gGerudoMaskIconTex,
gMaskofTruthIconTex,
gSoldOutIconTex,
gPocketEggIconTex,
gPocketCuccoIconTex,
gCojiroIconTex,
gOddMushroomIconTex,
gOddPotionIconTex,
gPoachersSawIconTex,
gBrokenBiggoronSwordIconTex,
gPrescriptionIconTex,
gEyeBallFrogIconTex,
gEyeDropsIconTex,
gClaimCheckIconTex,
gFairyBowFireIconTex,
gFairyBowIceIconTex,
gFairyBowLightIconTex,
gKokiriSwordIconTex,
gMasterSwordIconTex,
gBiggoronSwordIconTex,
gDekuShieldIconTex,
gHylianShieldIconTex,
gMirrorShieldIconTex,
gKokiriTunicIconTex,
gGoronTunicIconTex,
gZoraTunicIconTex,
gKokiriBootsIconTex,
gIronBootsIconTex,
gHoverBootsIconTex,
gBulletBag30IconTex,
gBulletBag40IconTex,
gBulletBag50IconTex,
gQuiver30IconTex,
gQuiver40IconTex,
gQuiver50IconTex,
gBombBag20IconTex,
gBombBag30IconTex,
gBombBag40IconTex,
gGoronsBraceletIconTex,
gSilverGauntletsIconTex,
gGoldenGauntletsIconTex,
gSilverScaleIconTex,
gGoldenScaleIconTex,
gBrokenGiantsKnifeIconTex,
gAdultsWalletIconTex,
gGiantsWalletIconTex,
gDekuSeedsIconTex,
gFishingPoleIconTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gSongNoteTex,
gForestMedallionIconTex,
gFireMedallionIconTex,
gWaterMedallionIconTex,
gSpiritMedallionIconTex,
gShadowMedallionIconTex,
gLightMedallionIconTex,
gKokiriEmeraldIconTex,
gGoronRubyIconTex,
gZoraSapphireIconTex,
gStoneOfAgonyIconTex,
gGerudosCardIconTex,
gGoldSkulltulaIconTex,
gHeartContainerIconTex,
gUnusedPieceOfHeartIconTex,
gBossKeyIconTex,
gCompassIconTex,
gDungeonMapIconTex,
gSmallKeyIconTex,
gSmallMagicJarIconTex,
gBigMagicJarIconTex,
gHeartPieceIcon1Tex,
gHeartPieceIcon2Tex,
gHeartPieceIcon3Tex,
gOcarinaCUpTex,
gOcarinaCDownTex,
gOcarinaCLeftTex,
gOcarinaCRightTex,
gOcarinaATex,
};
// Used to map item IDs to inventory slots
u8 gItemSlots[] = {
SLOT_STICK, SLOT_NUT, SLOT_BOMB, SLOT_BOW, SLOT_ARROW_FIRE, SLOT_DINS_FIRE,
SLOT_SLINGSHOT, SLOT_OCARINA, SLOT_OCARINA, SLOT_BOMBCHU, SLOT_HOOKSHOT, SLOT_HOOKSHOT,
SLOT_ARROW_ICE, SLOT_FARORES_WIND, SLOT_BOOMERANG, SLOT_LENS, SLOT_BEAN, SLOT_HAMMER,
SLOT_ARROW_LIGHT, SLOT_NAYRUS_LOVE, SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1,
SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1,
SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_BOTTLE_1, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD,
SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD,
SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_CHILD, SLOT_TRADE_ADULT, SLOT_TRADE_ADULT, SLOT_TRADE_ADULT,
SLOT_TRADE_ADULT, SLOT_TRADE_ADULT, SLOT_TRADE_ADULT, SLOT_TRADE_ADULT, SLOT_TRADE_ADULT, SLOT_TRADE_ADULT,
SLOT_TRADE_ADULT, SLOT_TRADE_ADULT,
};
void Inventory_ChangeEquipment(s16 equipment, u16 value) {
gSaveContext.equips.equipment &= gEquipNegMasks[equipment];
gSaveContext.equips.equipment |= value << gEquipShifts[equipment];
}
u8 Inventory_DeleteEquipment(GlobalContext* globalCtx, s16 equipment) {
Player* player = GET_PLAYER(globalCtx);
s32 pad;
u16 sp26 = gSaveContext.equips.equipment & gEquipMasks[equipment];
// "Erasing equipment item = %d zzz=%d"
osSyncPrintf("装備アイテム抹消 = %d zzz=%d\n", equipment, sp26);
if (sp26) {
sp26 >>= gEquipShifts[equipment];
gSaveContext.equips.equipment &= gEquipNegMasks[equipment];
gSaveContext.inventory.equipment ^= gBitFlags[sp26 - 1] << gEquipShifts[equipment];
if (equipment == EQUIP_TUNIC) {
gSaveContext.equips.equipment |= 0x0100;
}
if (equipment == EQUIP_SWORD) {
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
gSaveContext.infTable[29] = 1;
}
Player_SetEquipmentData(globalCtx, player);
globalCtx->pauseCtx.cursorSpecialPos = PAUSE_CURSOR_PAGE_LEFT;
}
return sp26;
}
void Inventory_ChangeUpgrade(s16 upgrade, s16 value) {
gSaveContext.inventory.upgrades &= gUpgradeNegMasks[upgrade];
gSaveContext.inventory.upgrades |= value << gUpgradeShifts[upgrade];
}

View file

@ -0,0 +1,91 @@
#include "global.h"
UnkRumbleStruct D_80160FD0;
void func_800A9F30(PadMgr* a, s32 b) {
func_800D2E30(&D_80160FD0);
PadMgr_RumbleSet(a, D_80160FD0.rumbleEnable);
}
void func_800A9F6C(f32 a, u8 b, u8 c, u8 d) {
s32 temp1;
s32 temp2;
if (1000000.0f < a) {
temp1 = 1000;
} else {
temp1 = sqrtf(a);
}
if ((temp1 < 1000) && (b != 0) && (d != 0)) {
temp2 = b - (temp1 * 255) / 1000;
if (temp2 > 0) {
D_80160FD0.unk_10A = temp2;
D_80160FD0.unk_10B = c;
D_80160FD0.unk_10C = d;
}
}
}
void func_800AA000(f32 a, u8 b, u8 c, u8 d) {
s32 temp1;
s32 temp2;
s32 i;
if (1000000.0f < a) {
temp1 = 1000;
} else {
temp1 = sqrtf(a);
}
if (temp1 < 1000 && b != 0 && d != 0) {
temp2 = b - (temp1 * 255) / 1000;
for (i = 0; i < 0x40; i++) {
if (D_80160FD0.unk_04[i] == 0) {
if (temp2 > 0) {
D_80160FD0.unk_04[i] = temp2;
D_80160FD0.unk_44[i] = c;
D_80160FD0.unk_84[i] = d;
}
break;
}
}
}
}
void func_800AA0B4(void) {
func_800D3140(&D_80160FD0);
gPadMgr.retraceCallback = func_800A9F30;
gPadMgr.retraceCallbackValue = 0;
if (1) {}
}
void func_800AA0F0(void) {
PadMgr* padmgr = &gPadMgr;
if ((padmgr->retraceCallback == func_800A9F30) && (padmgr->retraceCallbackValue == 0)) {
padmgr->retraceCallback = NULL;
padmgr->retraceCallbackValue = 0;
}
func_800D3178(&D_80160FD0);
}
u32 func_800AA148(void) {
return gPadMgr.pakType[0] == 1;
}
void func_800AA15C(void) {
D_80160FD0.unk_104 = 2;
}
void func_800AA16C(void) {
D_80160FD0.unk_104 = 0;
}
void func_800AA178(u32 a) {
D_80160FD0.unk_105 = !!a;
}

View file

@ -0,0 +1,97 @@
#include "global.h"
// Note : This file is related to z_vismono, the original name was probably z_vis<something before "mono"
// alphabetically>
Gfx D_8012AC00[] = {
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2),
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
gsDPPipeSync(),
gsDPSetBlendColor(0, 0, 0, 8),
gsSPEndDisplayList(),
};
Gfx D_8012AC28[] = {
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) |
GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)),
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
gsSPEndDisplayList(),
};
Gfx D_8012AC40[] = {
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
gsSPEndDisplayList(),
};
Gfx D_8012AC58[] = {
gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE),
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2),
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
gsSPEndDisplayList(),
};
// Init
void func_800ACE70(struct_801664F0* this) {
this->type = 0;
this->setScissor = false;
this->color.r = 255;
this->color.g = 255;
this->color.b = 255;
this->color.a = 255;
}
// Destroy
void func_800ACE90(struct_801664F0* this) {
}
// Draw
void func_800ACE98(struct_801664F0* this, Gfx** gfxp) {
Gfx* gfx = *gfxp;
gDPPipeSync(gfx++);
gDPSetPrimDepth(gfx++, -1, -1);
if (this->setScissor == true) {
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
switch (this->type) {
case 1:
gSPDisplayList(gfx++, D_8012AC40);
break;
case 2:
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->color.rgba);
gSPDisplayList(gfx++, D_8012AC58);
break;
case 3:
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->color.rgba);
gSPDisplayList(gfx++, D_8012AC00);
break;
case 4:
gDPSetColor(gfx++, G_SETFOGCOLOR, this->color.rgba);
gSPDisplayList(gfx++, D_8012AC28);
break;
}
gDPPipeSync(gfx++);
*gfxp = gfx;
}

View file

@ -0,0 +1,64 @@
#include "global.h"
// Note : This file is related to z_vismono, the original name was probably z_vis<something after "mono" alphabetically>
// z-buffer
extern u16 D_0E000000[];
// Init
void func_800AD920(struct_80166500* this) {
this->useRgba = false;
this->setScissor = false;
this->primColor.r = 255;
this->primColor.g = 255;
this->primColor.b = 255;
this->primColor.a = 255;
this->envColor.a = 255;
this->envColor.r = 0;
this->envColor.g = 0;
this->envColor.b = 0;
}
// Destroy
void func_800AD950(struct_80166500* this) {
}
// Draw
void func_800AD958(struct_80166500* this, Gfx** gfxp) {
Gfx* gfx = *gfxp;
// OTRTODO
#if 0
u16* tex = D_0E000000;
s32 fmt = this->useRgba == false ? G_IM_FMT_IA : G_IM_FMT_RGBA;
s32 y;
s32 height = 6;
gDPPipeSync(gfx++);
if (this->setScissor == true) {
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2);
gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT,
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT);
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba);
gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba);
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
gDPLoadTextureBlock(gfx++, tex, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, height, 0, G_TX_NOMIRROR | G_TX_CLAMP,
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gfx++, 0, (y) << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 0, 0,
(1 << 10), (1 << 10));
tex += SCREEN_WIDTH * height;
}
gDPPipeSync(gfx++);
*gfxp = gfx;
#endif
}

View file

@ -0,0 +1,71 @@
#include "global.h"
// The code in this file is very similar to a spline system used in Super Mario 64 for cutscene camera movement
void func_800BB0A0(f32 u, Vec3f* pos, f32* roll, f32* viewAngle, f32* point0, f32* point1, f32* point2, f32* point3) {
f32 coeff[4];
u = CLAMP_MAX(u, 1.0f);
coeff[0] = (1.0f - u) * (1.0f - u) * (1.0f - u) / 6.0f;
coeff[1] = u * u * u / 2.0f - u * u + 2.0f / 3.0f;
coeff[2] = -u * u * u / 2.0f + u * u / 2.0f + u / 2.0f + 1.0f / 6.0f;
coeff[3] = u * u * u / 6.0f;
pos->x = (coeff[0] * point0[0]) + (coeff[1] * point1[0]) + (coeff[2] * point2[0]) + (coeff[3] * point3[0]);
pos->y = (coeff[0] * point0[1]) + (coeff[1] * point1[1]) + (coeff[2] * point2[1]) + (coeff[3] * point3[1]);
pos->z = (coeff[0] * point0[2]) + (coeff[1] * point1[2]) + (coeff[2] * point2[2]) + (coeff[3] * point3[2]);
*roll = (coeff[0] * point0[3]) + (coeff[1] * point1[3]) + (coeff[2] * point2[3]) + (coeff[3] * point3[3]);
*viewAngle = (coeff[0] * point0[4]) + (coeff[1] * point1[4]) + (coeff[2] * point2[4]) + (coeff[3] * point3[4]);
}
s32 func_800BB2B4(Vec3f* pos, f32* roll, f32* fov, CutsceneCameraPoint* point, s16* keyFrame, f32* curFrame) {
s32 ret = false;
f32 pointData[4][5];
s32 i;
f32 progress = *curFrame;
s32 key = *keyFrame;
f32 speed1 = 0.0f;
f32 speed2 = 0.0f;
f32 advance;
if (key < 0) {
progress = 0.0f;
}
if ((point[key].continueFlag == -1) || (point[key + 1].continueFlag == -1) || (point[key + 2].continueFlag == -1)) {
return true;
}
for (i = 0; i < 4; i++) {
pointData[i][0] = point[key + i].pos.x;
pointData[i][1] = point[key + i].pos.y;
pointData[i][2] = point[key + i].pos.z;
pointData[i][3] = point[key + i].cameraRoll;
pointData[i][4] = point[key + i].viewAngle;
}
func_800BB0A0(progress, pos, roll, fov, pointData[0], pointData[1], pointData[2], pointData[3]);
if (point[*keyFrame + 1].nextPointFrame != 0) {
speed1 = 1.0f / point[*keyFrame + 1].nextPointFrame;
}
if (point[*keyFrame + 2].nextPointFrame != 0) {
speed2 = 1.0f / point[*keyFrame + 2].nextPointFrame;
}
advance = (*curFrame * (speed2 - speed1)) + speed1;
if (advance < 0.0f) {
advance = 0;
}
*curFrame += advance;
if (*curFrame >= 1) {
if (point[++*keyFrame + 3].continueFlag == -1) {
*keyFrame = 0;
ret = true;
}
*curFrame -= 1;
}
return ret;
}

View file

@ -0,0 +1,13 @@
#include "global.h"
u8 D_8012D200[] = {
0, 1, 2, 3, 4, 5, 6,
};
void func_800C3C20(void) {
s32 i;
for (i = 0; (i < ARRAY_COUNT(D_8012D200)) & 0xFFFFFFFF; i++) {
Audio_StopSfxByBank(D_8012D200[i]);
}
}

View file

@ -0,0 +1,120 @@
#include "global.h"
#include <string.h>
void func_800D2E30(UnkRumbleStruct* arg0) {
static u8 D_8012DBB0 = 1;
s32 i;
s32 unk_a3;
s32 index = -1;
for (i = 0; i < 4; i++) {
arg0->rumbleEnable[i] = 0;
}
if (arg0->unk_105 == 0) {
if (D_8012DBB0 != 0) {
for (i = 0; i < 4; i++) {
gPadMgr.pakType[i] = 0;
}
}
D_8012DBB0 = arg0->unk_105;
return;
}
D_8012DBB0 = arg0->unk_105;
if (arg0->unk_104 == 2) {
for (i = 0; i < 4; ++i) {
gPadMgr.pakType[i] = 0;
}
for (i = 0; i < 0x40; i++) {
arg0->unk_C4[i] = 0;
arg0->unk_84[i] = 0;
arg0->unk_44[i] = 0;
arg0->unk_04[i] = 0;
}
arg0->unk_106 = arg0->unk_108 = arg0->unk_10A = arg0->unk_10B = arg0->unk_10C = arg0->unk_10D = 0;
arg0->unk_104 = 1;
}
if (arg0->unk_104 != 0) {
for (i = 0; i < 0x40; i++) {
if (arg0->unk_04[i] != 0) {
if (arg0->unk_44[i] > 0) {
arg0->unk_44[i]--;
} else {
unk_a3 = arg0->unk_04[i] - arg0->unk_84[i];
if (unk_a3 > 0) {
arg0->unk_04[i] = unk_a3;
} else {
arg0->unk_04[i] = 0;
}
}
unk_a3 = arg0->unk_C4[i] + arg0->unk_04[i];
arg0->unk_C4[i] = unk_a3;
if (index == -1) {
index = i;
arg0->rumbleEnable[0] = (unk_a3 >= 0x100);
} else if (arg0->unk_04[index] < arg0->unk_04[i]) {
index = i;
arg0->rumbleEnable[0] = (unk_a3 >= 0x100);
}
}
}
if (arg0->unk_10A != 0) {
if (arg0->unk_10B > 0) {
arg0->unk_10B--;
} else {
unk_a3 = arg0->unk_10A - arg0->unk_10C;
if (unk_a3 > 0) {
arg0->unk_10A = unk_a3;
} else {
arg0->unk_10A = 0;
}
}
unk_a3 = arg0->unk_10D + arg0->unk_10A;
arg0->unk_10D = unk_a3;
arg0->rumbleEnable[0] = (unk_a3 >= 0x100);
}
if (arg0->unk_10A != 0) {
unk_a3 = arg0->unk_10A;
} else {
if (index == -1) {
unk_a3 = 0;
} else {
unk_a3 = arg0->unk_04[index];
}
}
if (unk_a3 == 0) {
if ((++arg0->unk_108) >= 6) {
arg0->unk_106 = 0;
arg0->unk_108 = 5;
}
} else {
arg0->unk_108 = 0;
if ((++arg0->unk_106) >= 0x1C21) {
arg0->unk_104 = 0;
}
}
} else {
for (i = 0; i < 0x40; i++) {
arg0->unk_C4[i] = 0;
arg0->unk_84[i] = 0;
arg0->unk_44[i] = 0;
arg0->unk_04[i] = 0;
}
arg0->unk_106 = arg0->unk_108 = arg0->unk_10A = arg0->unk_10B = arg0->unk_10C = arg0->unk_10D = 0;
}
}
void func_800D3140(UnkRumbleStruct* arg0) {
memset(arg0, 0,sizeof(UnkRumbleStruct));
arg0->unk_104 = 2;
arg0->unk_105 = 1;
}
void func_800D3178(UnkRumbleStruct* arg0) {
memset(arg0, 0, sizeof(UnkRumbleStruct));
}

View file

@ -0,0 +1,19 @@
#include "global.h"
#include "vt.h"
u32 gIsCtrlr2Valid = false;
void func_800D31A0(void) {
osSyncPrintf(VT_FGCOL(RED) "\n**** Freeze!! ****\n" VT_RST);
while (true) {
Sleep_Msec(1000);
}
}
void func_800D31F0(void) {
gIsCtrlr2Valid = (gPadMgr.validCtrlrsMask & 2) != 0;
}
void func_800D3210(void) {
gIsCtrlr2Valid = false;
}

View file

@ -0,0 +1,865 @@
#include "global.h"
#define SAMPLES_TO_OVERPRODUCE 0x10
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80
typedef enum {
CHAN_UPD_UNK_0, // 0
CHAN_UPD_VOL_SCALE, // 1
CHAN_UPD_VOL, // 2
CHAN_UPD_PAN_SIGNED, // 3
CHAN_UPD_FREQ_SCALE, // 4
CHAN_UPD_REVERB, // 5
CHAN_UPD_SCRIPT_IO, // 6
CHAN_UPD_PAN_UNSIGNED, // 7
CHAN_UPD_STOP_SOMETHING2, // 8
CHAN_UPD_MUTE_BEHAVE, // 9
CHAN_UPD_VIBE_X8, // 10
CHAN_UPD_VIBE_X32, // 11
CHAN_UPD_UNK_0F, // 12
CHAN_UPD_UNK_20, // 13
CHAN_UPD_STEREO // 14
} ChannelUpdateType;
void func_800E6300(SequenceChannel* channel, AudioCmd* arg1);
void func_800E59AC(s32 playerIdx, s32 fadeTimer);
void Audio_InitMesgQueues(void);
AudioTask* func_800E5000(void);
void Audio_ProcessCmds(u32);
void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* arg1);
void func_800E5958(s32 playerIdx, s32 fadeTimer);
s32 func_800E66C0(s32 arg0);
// AudioMgr_Retrace
AudioTask* func_800E4FE0(void) {
return func_800E5000();
}
extern u64 rspAspMainDataStart[];
extern u64 rspAspMainDataEnd[];
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples) {
// OTRTODO: uintptr_t?
u32 sp4C;
gAudioContext.totalTaskCnt++;
AudioLoad_DecreaseSampleDmaTtls();
AudioLoad_ProcessLoads(gAudioContext.resetStatus);
AudioLoad_ProcessScriptLoads();
if (gAudioContext.resetStatus != 0) {
if (AudioHeap_ResetStep() == 0) {
if (gAudioContext.resetStatus == 0) {
osSendMesg(gAudioContext.audioResetQueueP, gAudioContext.audioResetSpecIdToLoad, OS_MESG_NOBLOCK);
}
}
}
int j = 0;
if (gAudioContext.resetStatus == 0) {
// msg = 0000RREE R = read pos, E = End Pos
while (osRecvMesg(gAudioContext.cmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) {
Audio_ProcessCmds(sp4C);
j++;
}
if ((j == 0) && (gAudioContext.cmdQueueFinished)) {
Audio_ScheduleProcessCmds();
}
}
s32 writtenCmds;
AudioSynth_Update(gAudioContext.curAbiCmdBuf, &writtenCmds, samples, num_samples);
gAudioContext.audioRandom = (gAudioContext.audioRandom + gAudioContext.totalTaskCnt) * osGetCount();
}
AudioTask* func_800E5000(void) {
return NULL;
static s32 sMaxAbiCmdCnt = 0x80;
static AudioTask* sWaitingAudioTask = NULL;
u32 samplesRemainingInAi;
s32 abiCmdCnt;
s32 pad;
s32 j;
s32 sp5C;
s16* currAiBuffer;
OSTask_t* task;
s32 index;
u32 sp4C;
s32 sp48;
s32 i;
gAudioContext.totalTaskCnt++;
if (gAudioContext.totalTaskCnt % (gAudioContext.audioBufferParameters.specUnk4) != 0) {
if (D_801755D0 != NULL) {
D_801755D0();
}
if ((gAudioContext.totalTaskCnt % gAudioContext.audioBufferParameters.specUnk4) + 1 ==
gAudioContext.audioBufferParameters.specUnk4) {
return sWaitingAudioTask;
} else {
return NULL;
}
}
osSendMesg(gAudioContext.taskStartQueueP, gAudioContext.totalTaskCnt, OS_MESG_NOBLOCK);
gAudioContext.rspTaskIdx ^= 1;
gAudioContext.curAIBufIdx++;
gAudioContext.curAIBufIdx %= 3;
index = (gAudioContext.curAIBufIdx - 2 + 3) % 3;
samplesRemainingInAi = osAiGetLength() / 4;
if (gAudioContext.resetTimer < 16) {
if (gAudioContext.aiBufLengths[index] != 0) {
osAiSetNextBuffer(gAudioContext.aiBuffers[index], gAudioContext.aiBufLengths[index] * 4);
if (gAudioContext.aiBuffers[index]) {}
if (gAudioContext.aiBufLengths[index]) {}
}
}
if (D_801755D0 != NULL) {
D_801755D0();
}
sp5C = gAudioContext.curAudioFrameDmaCount;
for (i = 0; i < gAudioContext.curAudioFrameDmaCount; i++) {
if (osRecvMesg(&gAudioContext.currAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK) == 0) {
sp5C--;
}
}
if (sp5C != 0) {
for (i = 0; i < sp5C; i++) {
osRecvMesg(&gAudioContext.currAudioFrameDmaQueue, NULL, OS_MESG_BLOCK);
}
}
sp48 = gAudioContext.currAudioFrameDmaQueue.validCount;
if (sp48 != 0) {
for (i = 0; i < sp48; i++) {
osRecvMesg(&gAudioContext.currAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK);
}
}
gAudioContext.curAudioFrameDmaCount = 0;
AudioLoad_DecreaseSampleDmaTtls();
AudioLoad_ProcessLoads(gAudioContext.resetStatus);
AudioLoad_ProcessScriptLoads();
if (gAudioContext.resetStatus != 0) {
if (AudioHeap_ResetStep() == 0) {
if (gAudioContext.resetStatus == 0) {
osSendMesg(gAudioContext.audioResetQueueP, gAudioContext.audioResetSpecIdToLoad, OS_MESG_NOBLOCK);
}
sWaitingAudioTask = NULL;
return NULL;
}
}
if (gAudioContext.resetTimer > 16) {
return NULL;
}
if (gAudioContext.resetTimer != 0) {
gAudioContext.resetTimer++;
}
gAudioContext.currTask = &gAudioContext.rspTask[gAudioContext.rspTaskIdx];
gAudioContext.curAbiCmdBuf = gAudioContext.abiCmdBufs[gAudioContext.rspTaskIdx];
index = gAudioContext.curAIBufIdx;
currAiBuffer = gAudioContext.aiBuffers[index];
gAudioContext.aiBufLengths[index] =
(s16)((((gAudioContext.audioBufferParameters.samplesPerFrameTarget - samplesRemainingInAi) +
EXTRA_BUFFERED_AI_SAMPLES_TARGET) &
~0xF) +
SAMPLES_TO_OVERPRODUCE);
if (gAudioContext.aiBufLengths[index] < gAudioContext.audioBufferParameters.minAiBufferLength) {
gAudioContext.aiBufLengths[index] = gAudioContext.audioBufferParameters.minAiBufferLength;
}
if (gAudioContext.aiBufLengths[index] > gAudioContext.audioBufferParameters.maxAiBufferLength) {
gAudioContext.aiBufLengths[index] = gAudioContext.audioBufferParameters.maxAiBufferLength;
}
j = 0;
if (gAudioContext.resetStatus == 0) {
// msg = 0000RREE R = read pos, E = End Pos
while (osRecvMesg(gAudioContext.cmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) {
if (1) {}
if (1) {}
if (1) {}
Audio_ProcessCmds(sp4C);
j++;
}
if ((j == 0) && (gAudioContext.cmdQueueFinished)) {
Audio_ScheduleProcessCmds();
}
}
gAudioContext.curAbiCmdBuf =
AudioSynth_Update(gAudioContext.curAbiCmdBuf, &abiCmdCnt, currAiBuffer, gAudioContext.aiBufLengths[index]);
gAudioContext.audioRandom = (gAudioContext.audioRandom + gAudioContext.totalTaskCnt) * osGetCount();
gAudioContext.audioRandom =
gAudioContext.aiBuffers[index][gAudioContext.totalTaskCnt & 0xFF] + gAudioContext.audioRandom;
gWaveSamples[8] = (s16*)(((u8*)func_800E4FE0) + (gAudioContext.audioRandom & 0xFFF0));
index = gAudioContext.rspTaskIdx;
gAudioContext.currTask->taskQueue = NULL;
gAudioContext.currTask->unk_44 = NULL;
task = &gAudioContext.currTask->task.t;
task->type = M_AUDTASK;
task->flags = 0;
//task->ucode_boot = D_801120C0;
task->ucode_boot_size = 0x1000;
//task->ucode_data_size = ((rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64)) - 1;
//task->ucode = D_801120C0;
//task->ucode_data = rspAspMainDataStart;
task->ucode_size = 0x1000;
task->dram_stack = NULL;
task->dram_stack_size = 0;
task->output_buff = NULL;
task->output_buff_size = NULL;
if (1) {}
task->data_ptr = (u64*)gAudioContext.abiCmdBufs[index];
task->data_size = abiCmdCnt * sizeof(Acmd);
task->yield_data_ptr = NULL;
task->yield_data_size = 0;
if (sMaxAbiCmdCnt < abiCmdCnt) {
sMaxAbiCmdCnt = abiCmdCnt;
}
if (gAudioContext.audioBufferParameters.specUnk4 == 1) {
return gAudioContext.currTask;
} else {
sWaitingAudioTask = gAudioContext.currTask;
return NULL;
}
}
#define ACMD_SND_MDE ((u32)0xF0000000)
#define ACMD_MUTE ((u32)0xF1000000)
void func_800E5584(AudioCmd* cmd) {
s32 i;
s32 pad;
s32 pad2;
u32 temp_a1_5;
u32 temp_t7;
switch (cmd->op) {
case 0x81:
AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2);
return;
case 0x82:
AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2);
func_800E59AC(cmd->arg0, cmd->data);
return;
case 0x85:
AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, cmd->data);
return;
case 0x83:
if (gAudioContext.seqPlayers[cmd->arg0].enabled) {
if (cmd->asInt == 0) {
AudioSeq_SequencePlayerDisableAsFinished(&gAudioContext.seqPlayers[cmd->arg0]);
} else {
func_800E5958(cmd->arg0, cmd->asInt);
}
}
return;
case 0xF0:
gAudioContext.soundMode = cmd->asUInt;
return;
case 0xF1:
for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) {
SequencePlayer* seqPlayer = &gAudioContext.seqPlayers[i];
seqPlayer->muted = 1;
seqPlayer->recalculateVolume = 1;
}
return;
case 0xF2:
if (cmd->asUInt == 1) {
for (i = 0; i < gAudioContext.numNotes; i++) {
Note* note = &gAudioContext.notes[i];
NoteSubEu* subEu = &note->noteSubEu;
if (subEu->bitField0.enabled && note->playbackState.unk_04 == 0) {
if (note->playbackState.parentLayer->channel->muteBehavior & 8) {
subEu->bitField0.finished = 1;
}
}
}
}
for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) {
SequencePlayer* seqPlayer = &gAudioContext.seqPlayers[i];
seqPlayer->muted = 0;
seqPlayer->recalculateVolume = 1;
}
return;
case 0xF3:
AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2);
return;
case 0xF4:
AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioContext.externalLoadQueue);
return;
case 0xF5:
AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioContext.externalLoadQueue);
return;
case 0xFC:
AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioContext.externalLoadQueue);
return;
case 0xF6:
AudioLoad_DiscardSeqFonts(cmd->arg1);
return;
case 0x90:
gAudioContext.unk_5BDC[cmd->arg0] = cmd->asUShort;
return;
case 0xF9:
gAudioContext.resetStatus = 5;
gAudioContext.audioResetSpecIdToLoad = cmd->asUInt;
return;
case 0xFB:
D_801755D0 = (void (*)(void))cmd->asUInt;
return;
case 0xE0:
case 0xE1:
case 0xE2:
Audio_SetFontInstrument(cmd->op - 0xE0, cmd->arg0, cmd->arg1, cmd->data);
return;
case 0xFE:
temp_t7 = cmd->asUInt;
if (temp_t7 == 1) {
for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) {
SequencePlayer* seqPlayer = &gAudioContext.seqPlayers[i];
if (seqPlayer->enabled) {
AudioSeq_SequencePlayerDisableAsFinished(seqPlayer);
}
}
}
func_800E66C0(temp_t7);
return;
case 0xE3:
AudioHeap_PopCache(cmd->asInt);
return;
default:
return;
}
}
// SetFadeOutTimer
void func_800E5958(s32 playerIdx, s32 fadeTimer) {
SequencePlayer* seqPlayer = &gAudioContext.seqPlayers[playerIdx];
if (fadeTimer == 0) {
fadeTimer = 1;
}
seqPlayer->fadeVelocity = -(seqPlayer->fadeVolume / fadeTimer);
seqPlayer->state = 2;
seqPlayer->fadeTimer = fadeTimer;
}
// SetFadeInTimer
void func_800E59AC(s32 playerIdx, s32 fadeTimer) {
SequencePlayer* seqPlayer;
if (fadeTimer != 0) {
seqPlayer = &gAudioContext.seqPlayers[playerIdx];
seqPlayer->state = 1;
seqPlayer->fadeTimerUnkEu = fadeTimer;
seqPlayer->fadeTimer = fadeTimer;
seqPlayer->fadeVolume = 0.0f;
seqPlayer->fadeVelocity = 0.0f;
}
}
void Audio_InitMesgQueuesInternal(void) {
gAudioContext.cmdWrPos = 0;
gAudioContext.cmdRdPos = 0;
gAudioContext.cmdQueueFinished = 0;
gAudioContext.taskStartQueueP = &gAudioContext.taskStartQueue;
gAudioContext.cmdProcQueueP = &gAudioContext.cmdProcQueue;
gAudioContext.audioResetQueueP = &gAudioContext.audioResetQueue;
osCreateMesgQueue(gAudioContext.taskStartQueueP, gAudioContext.taskStartMsgs,
ARRAY_COUNT(gAudioContext.taskStartMsgs));
osCreateMesgQueue(gAudioContext.cmdProcQueueP, gAudioContext.cmdProcMsgs, ARRAY_COUNT(gAudioContext.cmdProcMsgs));
osCreateMesgQueue(gAudioContext.audioResetQueueP, gAudioContext.audioResetMesgs,
ARRAY_COUNT(gAudioContext.audioResetMesgs));
}
void Audio_QueueCmd(u32 opArgs, void** data) {
AudioCmd* cmd = &gAudioContext.cmdBuf[gAudioContext.cmdWrPos & 0xFF];
cmd->opArgs = opArgs;
cmd->data = *data;
gAudioContext.cmdWrPos++;
if (gAudioContext.cmdWrPos == gAudioContext.cmdRdPos) {
gAudioContext.cmdWrPos--;
}
}
void Audio_QueueCmdF32(u32 opArgs, f32 data) {
Audio_QueueCmd(opArgs, (void**)&data);
}
void Audio_QueueCmdS32(u32 opArgs, s32 data) {
Audio_QueueCmd(opArgs, (void**)&data);
}
void Audio_QueueCmdS8(u32 opArgs, s8 data) {
u32 uData = data << 0x18;
Audio_QueueCmd(opArgs, (void**)&uData);
}
void Audio_QueueCmdU16(u32 opArgs, u16 data) {
u32 uData = data << 0x10;
Audio_QueueCmd(opArgs, (void**)&uData);
}
s32 Audio_ScheduleProcessCmds(void) {
static s32 D_801304E8 = 0;
s32 ret;
if (D_801304E8 < (u8)((gAudioContext.cmdWrPos - gAudioContext.cmdRdPos) + 0x100)) {
D_801304E8 = (u8)((gAudioContext.cmdWrPos - gAudioContext.cmdRdPos) + 0x100);
}
ret =
osSendMesg(gAudioContext.cmdProcQueueP,
(void*)(((gAudioContext.cmdRdPos & 0xFF) << 8) | (gAudioContext.cmdWrPos & 0xFF)), OS_MESG_NOBLOCK);
if (ret != -1) {
gAudioContext.cmdRdPos = gAudioContext.cmdWrPos;
ret = 0;
} else {
return -1;
}
return ret;
}
void Audio_ResetCmdQueue(void) {
gAudioContext.cmdQueueFinished = 0;
gAudioContext.cmdRdPos = gAudioContext.cmdWrPos;
}
void Audio_ProcessCmd(AudioCmd* cmd) {
SequencePlayer* seqPlayer;
u16 phi_v0;
s32 i;
if ((cmd->op & 0xF0) == 0xF0) {
func_800E5584(cmd);
return;
}
if (cmd->arg0 < gAudioContext.audioBufferParameters.numSequencePlayers) {
seqPlayer = &gAudioContext.seqPlayers[cmd->arg0];
if (cmd->op & 0x80) {
func_800E5584(cmd);
return;
}
if (cmd->op & 0x40) {
func_800E6128(seqPlayer, cmd);
return;
}
if (cmd->arg1 < 0x10) {
func_800E6300(seqPlayer->channels[cmd->arg1], cmd);
return;
}
if (cmd->arg1 == 0xFF) {
phi_v0 = gAudioContext.unk_5BDC[cmd->arg0];
for (i = 0; i < 0x10; i++) {
if (phi_v0 & 1) {
func_800E6300(seqPlayer->channels[i], cmd);
}
phi_v0 = phi_v0 >> 1;
}
}
}
}
void Audio_ProcessCmds(u32 msg) {
static u8 curCmdRdPos = 0;
AudioCmd* cmd;
u8 endPos;
if (!gAudioContext.cmdQueueFinished) {
curCmdRdPos = msg >> 8;
}
while (true) {
endPos = msg & 0xFF;
if (curCmdRdPos == endPos) {
gAudioContext.cmdQueueFinished = 0;
return;
}
cmd = &gAudioContext.cmdBuf[curCmdRdPos++ & 0xFF];
if (cmd->op == 0xF8) {
gAudioContext.cmdQueueFinished = 1;
return;
}
Audio_ProcessCmd(cmd);
cmd->op = 0;
}
}
u32 func_800E5E20(u32* out) {
u32 sp1C;
if (osRecvMesg(&gAudioContext.externalLoadQueue, (OSMesg*)&sp1C, OS_MESG_NOBLOCK) == -1) {
*out = 0;
return 0;
}
*out = sp1C & 0xFFFFFF;
return sp1C >> 0x18;
}
u8* func_800E5E84(s32 arg0, u32* arg1) {
return AudioLoad_GetFontsForSequence(arg0, arg1);
}
void func_800E5EA4(s32 arg0, u32* arg1, u32* arg2) {
*arg1 = gAudioContext.soundFonts[arg0].sampleBankId1;
*arg2 = gAudioContext.soundFonts[arg0].sampleBankId2;
}
s32 func_800E5EDC(void) {
s32 pad;
s32 sp18;
if (osRecvMesg(gAudioContext.audioResetQueueP, (OSMesg*)&sp18, OS_MESG_NOBLOCK) == -1) {
return 0;
} else if (gAudioContext.audioResetSpecIdToLoad != sp18) {
return -1;
} else {
return 1;
}
}
void func_800E5F34(void) {
// macro?
// clang-format off
s32 chk = -1; s32 sp28; do {} while (osRecvMesg(gAudioContext.audioResetQueueP, (OSMesg*)&sp28, OS_MESG_NOBLOCK) != chk);
// clang-format on
}
s32 func_800E5F88(s32 resetPreloadID) {
s32 resetStatus;
OSMesg msg;
s32 pad;
func_800E5F34();
resetStatus = gAudioContext.resetStatus;
if (resetStatus != 0) {
Audio_ResetCmdQueue();
if (gAudioContext.audioResetSpecIdToLoad == resetPreloadID) {
return -2;
} else if (resetStatus > 2) {
gAudioContext.audioResetSpecIdToLoad = resetPreloadID;
return -3;
} else {
osRecvMesg(gAudioContext.audioResetQueueP, &msg, OS_MESG_BLOCK);
}
}
func_800E5F34();
Audio_QueueCmdS32(0xF9000000, resetPreloadID);
return Audio_ScheduleProcessCmds();
}
void Audio_PreNMIInternal(void) {
gAudioContext.resetTimer = 1;
if (gAudioContextInitalized) {
func_800E5F88(0);
gAudioContext.resetStatus = 0;
}
}
s8 func_800E6070(s32 playerIdx, s32 channelIdx, s32 scriptIdx) {
SequencePlayer* seqPlayer = &gAudioContext.seqPlayers[playerIdx];
SequenceChannel* channel;
if (seqPlayer->enabled) {
channel = seqPlayer->channels[channelIdx];
return channel->soundScriptIO[scriptIdx];
} else {
return -1;
}
}
s8 func_800E60C4(s32 playerIdx, s32 arg1) {
return gAudioContext.seqPlayers[playerIdx].soundScriptIO[arg1];
}
void Audio_InitExternalPool(void* mem, size_t size) {
AudioHeap_AllocPoolInit(&gAudioContext.externalPool, mem, size);
}
void Audio_DestroyExternalPool(void) {
gAudioContext.externalPool.start = NULL;
}
void Audio_SetGameVolume(int player_id, f32 volume) {
gAudioContext.seqPlayers[player_id].gameVolume = volume;
gAudioContext.seqPlayers[player_id].recalculateVolume = true;
}
float Audio_GetGameVolume(int player_id) {
return gAudioContext.seqPlayers[player_id].gameVolume;
}
void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) {
f32 fadeVolume;
switch (cmd->op) {
case 0x41:
if (seqPlayer->fadeVolumeScale != cmd->asFloat) {
seqPlayer->fadeVolumeScale = cmd->asFloat;
seqPlayer->recalculateVolume = 1;
}
return;
case 0x47:
seqPlayer->tempo = cmd->asInt * 0x30;
return;
case 0x49:
seqPlayer->unk_0C = cmd->asInt * 0x30;
return;
case 0x4E:
seqPlayer->unk_0C = cmd->asInt;
return;
case 0x48:
seqPlayer->transposition = cmd->asSbyte;
return;
case 0x46:
seqPlayer->soundScriptIO[cmd->arg2] = cmd->asSbyte;
return;
case 0x4A:
fadeVolume = (s32)cmd->arg1 / 127.0f;
goto block_11;
case 0x4B:
fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume;
block_11:
if (seqPlayer->state != 2) {
seqPlayer->volume = seqPlayer->fadeVolume;
if (cmd->asInt == 0) {
seqPlayer->fadeVolume = fadeVolume;
} else {
s32 tmp = cmd->asInt;
seqPlayer->state = 0;
seqPlayer->fadeTimer = tmp;
seqPlayer->fadeVelocity = (fadeVolume - seqPlayer->fadeVolume) / tmp;
}
}
return;
case 0x4C:
if (seqPlayer->state != 2) {
if (cmd->asInt == 0) {
seqPlayer->fadeVolume = seqPlayer->volume;
} else {
s32 tmp = cmd->asInt;
seqPlayer->state = 0;
seqPlayer->fadeTimer = tmp;
seqPlayer->fadeVelocity = (seqPlayer->volume - seqPlayer->fadeVolume) / tmp;
}
}
return;
case 0x4D:
seqPlayer->unk_34 = cmd->asFloat;
if (seqPlayer->unk_34 == 1.0f) {
seqPlayer->unk_0b1 = 0;
} else {
seqPlayer->unk_0b1 = 1;
}
}
}
void func_800E6300(SequenceChannel* channel, AudioCmd* cmd) {
switch (cmd->op) {
case CHAN_UPD_VOL_SCALE:
if (channel->volumeScale != cmd->asFloat) {
channel->volumeScale = cmd->asFloat;
channel->changes.s.volume = 1;
}
return;
case CHAN_UPD_VOL:
if (channel->volume != cmd->asFloat) {
channel->volume = cmd->asFloat;
channel->changes.s.volume = 1;
}
return;
case CHAN_UPD_PAN_SIGNED:
if (channel->newPan != cmd->asSbyte) {
channel->newPan = cmd->asSbyte;
channel->changes.s.pan = 1;
}
return;
case CHAN_UPD_PAN_UNSIGNED:
if (channel->newPan != cmd->asSbyte) {
channel->panChannelWeight = cmd->asSbyte;
channel->changes.s.pan = 1;
}
return;
case CHAN_UPD_FREQ_SCALE:
if (channel->freqScale != cmd->asFloat) {
channel->freqScale = cmd->asFloat;
channel->changes.s.freqScale = 1;
}
return;
case CHAN_UPD_REVERB:
if (channel->reverb != cmd->asSbyte) {
channel->reverb = cmd->asSbyte;
}
return;
case CHAN_UPD_SCRIPT_IO:
if (cmd->arg2 < 8) {
channel->soundScriptIO[cmd->arg2] = cmd->asSbyte;
}
return;
case CHAN_UPD_STOP_SOMETHING2:
channel->stopSomething2 = cmd->asSbyte;
return;
case CHAN_UPD_MUTE_BEHAVE:
channel->muteBehavior = cmd->asSbyte;
return;
case CHAN_UPD_VIBE_X8:
channel->vibratoExtentTarget = cmd->asUbyte * 8;
channel->vibratoExtentChangeDelay = 1;
return;
case CHAN_UPD_VIBE_X32:
channel->vibratoRateTarget = cmd->asUbyte * 32;
channel->vibratoRateChangeDelay = 1;
return;
case CHAN_UPD_UNK_0F:
channel->unk_0F = cmd->asUbyte;
return;
case CHAN_UPD_UNK_20:
channel->unk_20 = cmd->asUShort;
return;
case CHAN_UPD_STEREO:
channel->stereo.asByte = cmd->asUbyte;
return;
}
}
void func_800E64B0(s32 arg0, s32 arg1, s32 arg2) {
Audio_QueueCmdS32(((arg0 & 0xFF) << 0x10) | 0xFA000000 | ((arg1 & 0xFF) << 8) | (arg2 & 0xFF), 1);
}
void func_800E64F8(void) {
Audio_QueueCmdS32(0xFA000000, 0);
}
void func_800E651C(u32 arg0, s32 arg1) {
Audio_QueueCmdS32((arg1 & 0xFF) | 0xFD000000, arg0);
}
void Audio_WaitForAudioTask(void) {
osRecvMesg(gAudioContext.taskStartQueueP, NULL, OS_MESG_NOBLOCK);
osRecvMesg(gAudioContext.taskStartQueueP, NULL, OS_MESG_BLOCK);
}
s32 func_800E6590(s32 playerIdx, s32 arg1, s32 arg2) {
SequencePlayer* seqPlayer;
SequenceLayer* layer;
Note* note;
SoundFontSound* sound;
s32 loopEnd;
s32 samplePos;
seqPlayer = &gAudioContext.seqPlayers[playerIdx];
if (seqPlayer->enabled && seqPlayer->channels[arg1]->enabled) {
layer = seqPlayer->channels[arg1]->layers[arg2];
if (layer == NULL) {
return 0;
}
if (layer->enabled) {
if (layer->note == NULL) {
return 0;
}
if (!layer->bit3) {
return 0;
}
note = layer->note;
if (layer == note->playbackState.parentLayer) {
sound = note->noteSubEu.sound.soundFontSound;
if (sound == NULL) {
return 0;
}
loopEnd = sound->sample->loop->end;
samplePos = note->synthesisState.samplePosInt;
return loopEnd - samplePos;
}
return 0;
}
}
return 0;
}
s32 func_800E6680(void) {
return func_800E66C0(0);
}
void func_800E66A0(void) {
func_800E66C0(2);
}
s32 func_800E66C0(s32 arg0) {
s32 phi_v1;
NotePlaybackState* temp_a2;
NoteSubEu* temp_a3;
s32 i;
Note* note;
SoundFontSound* sound;
phi_v1 = 0;
for (i = 0; i < gAudioContext.numNotes; i++) {
note = &gAudioContext.notes[i];
temp_a2 = &note->playbackState;
if (note->noteSubEu.bitField0.enabled) {
temp_a3 = &note->noteSubEu;
if (temp_a2->adsr.action.s.state != 0) {
if (arg0 >= 2) {
sound = temp_a3->sound.soundFontSound;
if (sound == NULL || temp_a3->bitField1.isSyntheticWave) {
continue;
}
if (sound->sample->medium == MEDIUM_RAM) {
continue;
}
}
phi_v1++;
if ((arg0 & 1) == 1) {
temp_a2->adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
temp_a2->adsr.action.s.release = 1;
}
}
}
}
return phi_v1;
}
u32 Audio_NextRandom(void) {
static u32 audRand = 0x12345678;
audRand = ((osGetCount() + 0x1234567) * (audRand + gAudioContext.totalTaskCnt));
audRand += gAudioContext.audioRandom;
return audRand;
}
void Audio_InitMesgQueues(void) {
Audio_InitMesgQueuesInternal();
}

View file

@ -0,0 +1,15 @@
#include "global.h"
void Audio_InvalDCache(void* buf, size_t size) {
OSIntMask prevMask = osSetIntMask(1);
osInvalDCache(buf, size);
osSetIntMask(prevMask);
}
void Audio_WritebackDCache(void* buf, size_t size) {
OSIntMask prevMask = osSetIntMask(1);
osWritebackDCache(buf, size);
osSetIntMask(prevMask);
}

5056
soh/src/code/code_800EC960.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,792 @@
#include "ultra64.h"
#include "global.h"
#include "vt.h"
typedef struct {
/* 0x00 */ u16 sfxId;
/* 0x04 */ Vec3f* pos;
/* 0x08 */ u8 token;
/* 0x0C */ f32* freqScale;
/* 0x10 */ f32* vol;
/* 0x14 */ s8* reverbAdd;
} SoundRequest; // size = 0x18
typedef struct {
/* 0x00 */ f32 value;
/* 0x04 */ f32 target;
/* 0x08 */ f32 step;
/* 0x0C */ u16 remainingFrames;
} UnusedBankLerp; // size = 0x10
// rodata for Audio_ProcessSoundRequest (this file)
// (probably moved to .data due to -use_readwrite_const)
char D_80133340[] = "SE";
// rodata for Audio_ChooseActiveSounds (this file)
char D_80133344[] = VT_COL(RED, WHITE) "<INAGAKI CHECK> dist over! flag:%04X ptr:%08X pos:%f-%f-%f" VT_RST "\n";
// file padding
s32 D_8013338C = 0;
// rodata for Audio_ProcessSeqCmd (code_800F9280.c)
char D_80133390[] = "SEQ H";
char D_80133398[] = " L";
SoundBankEntry D_8016BAD0[9];
SoundBankEntry D_8016BC80[12];
SoundBankEntry D_8016BEC0[22];
SoundBankEntry D_8016C2E0[20];
SoundBankEntry D_8016C6A0[8];
SoundBankEntry D_8016C820[3];
SoundBankEntry D_8016C8B0[5];
SoundRequest sSoundRequests[0x100];
u8 sSoundBankListEnd[7];
u8 sSoundBankFreeListStart[7];
u8 sSoundBankUnused[7];
ActiveSound gActiveSounds[7][3];
u8 sCurSfxPlayerChannelIdx;
u8 gSoundBankMuted[7];
UnusedBankLerp sUnusedBankLerp[7];
u16 gAudioSfxSwapSource[10];
u16 gAudioSfxSwapTarget[10];
u8 gAudioSfxSwapMode[10];
// sSoundRequests ring buffer endpoints. read index <= write index, wrapping around mod 256.
u8 sSoundRequestWriteIndex = 0;
u8 sSoundRequestReadIndex = 0;
/**
* Array of pointers to arrays of SoundBankEntry of sizes: 9, 12, 22, 20, 8, 3, 5
*
* 0 : Player Bank size 9
* 1 : Item Bank size 12
* 2 : Environment Bank size 22
* 3 : Enemy Bank size 20
* 4 : System Bank size 8
* 5 : Ocarina Bank size 3
* 6 : Voice Bank size 5
*/
SoundBankEntry* gSoundBanks[7] = {
D_8016BAD0, D_8016BC80, D_8016BEC0, D_8016C2E0, D_8016C6A0, D_8016C820, D_8016C8B0,
};
u8 sBankSizes[ARRAY_COUNT(gSoundBanks)] = {
ARRAY_COUNT(D_8016BAD0), ARRAY_COUNT(D_8016BC80), ARRAY_COUNT(D_8016BEC0), ARRAY_COUNT(D_8016C2E0),
ARRAY_COUNT(D_8016C6A0), ARRAY_COUNT(D_8016C820), ARRAY_COUNT(D_8016C8B0),
};
u8 gSfxChannelLayout = 0;
u16 D_801333D0 = 0;
Vec3f D_801333D4 = { 0.0f, 0.0f, 0.0f }; // default pos
f32 D_801333E0 = 1.0f; // default freqScale
s32 D_801333E4 = 0; // unused
s8 D_801333E8 = 0; // default reverbAdd
s32 D_801333EC = 0; // unused
u8 D_801333F0 = 0;
u8 gAudioSfxSwapOff = 0;
u8 D_801333F8 = 0;
void Audio_SetSoundBanksMute(u16 muteMask) {
u8 bankId;
for (bankId = 0; bankId < ARRAY_COUNT(gSoundBanks); bankId++) {
if (muteMask & 1) {
gSoundBankMuted[bankId] = true;
} else {
gSoundBankMuted[bankId] = false;
}
muteMask = muteMask >> 1;
}
}
void Audio_QueueSeqCmdMute(u8 channelIdx) {
D_801333D0 |= (1 << channelIdx);
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 2, 0x40, 0xF);
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 2, 0x40, 0xF);
}
void Audio_ClearBGMMute(u8 channelIdx) {
D_801333D0 &= ((1 << channelIdx) ^ 0xFFFF);
if (D_801333D0 == 0) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 2, 0x7F, 0xF);
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 2, 0x7F, 0xF);
}
}
void Audio_PlaySoundGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* vol, s8* reverbAdd)
{
u8 i;
SoundRequest* req;
if (!gSoundBankMuted[SFX_BANK_SHIFT(sfxId)]) {
req = &sSoundRequests[sSoundRequestWriteIndex];
if (!gAudioSfxSwapOff) {
for (i = 0; i < 10; i++) {
if (sfxId == gAudioSfxSwapSource[i]) {
if (gAudioSfxSwapMode[i] == 0) { // "SWAP"
sfxId = gAudioSfxSwapTarget[i];
} else { // "ADD"
req->sfxId = gAudioSfxSwapTarget[i];
req->pos = pos;
req->token = token;
req->freqScale = freqScale;
req->vol = vol;
req->reverbAdd = reverbAdd;
sSoundRequestWriteIndex++;
req = &sSoundRequests[sSoundRequestWriteIndex];
}
i = 10; // "break;"
}
}
}
req->sfxId = sfxId;
req->pos = pos;
req->token = token;
req->freqScale = freqScale;
req->vol = vol;
req->reverbAdd = reverbAdd;
sSoundRequestWriteIndex++;
}
}
void Audio_RemoveMatchingSoundRequests(u8 aspect, SoundBankEntry* cmp) {
SoundRequest* req;
s32 remove;
u8 i = sSoundRequestReadIndex;
for (; i != sSoundRequestWriteIndex; i++) {
remove = false;
req = &sSoundRequests[i];
switch (aspect) {
case 0:
if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(cmp->sfxId)) {
remove = true;
}
break;
case 1:
if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(cmp->sfxId) && (&req->pos->x == cmp->posX)) {
remove = true;
}
break;
case 2:
if (&req->pos->x == cmp->posX) {
remove = true;
}
break;
case 3:
if (&req->pos->x == cmp->posX && req->sfxId == cmp->sfxId) {
remove = true;
}
break;
case 4:
if (req->token == cmp->token && req->sfxId == cmp->sfxId) {
remove = true;
}
break;
case 5:
if (req->sfxId == cmp->sfxId) {
remove = true;
}
break;
}
if (remove) {
req->sfxId = 0;
}
}
}
void Audio_ProcessSoundRequest(void)
{
u16 sfxId;
u8 count;
u8 index;
SoundRequest* req;
SoundBankEntry* entry;
SoundParams* soundParams;
s32 bankId;
u8 evictImportance;
u8 evictIndex;
req = &sSoundRequests[sSoundRequestReadIndex];
evictIndex = 0x80;
if (req->sfxId == 0) {
return;
}
bankId = SFX_BANK(req->sfxId);
if ((1 << bankId) & D_801333F0) {
AudioDebug_ScrPrt((const s8*)D_80133340, req->sfxId);
bankId = SFX_BANK(req->sfxId);
}
count = 0;
index = gSoundBanks[bankId][0].next;
while (index != 0xFF && index != 0) {
if (gSoundBanks[bankId][index].posX == &req->pos->x) {
if ((gSoundParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].params & 0x20) &&
gSoundParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance ==
gSoundBanks[bankId][index].sfxImportance) {
return;
}
if (gSoundBanks[bankId][index].sfxId == req->sfxId) {
count = gUsedChannelsPerBank[gSfxChannelLayout][bankId];
} else {
if (count == 0) {
evictIndex = index;
sfxId = gSoundBanks[bankId][index].sfxId & 0xFFFF;
evictImportance = gSoundParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance;
} else if (gSoundBanks[bankId][index].sfxImportance < evictImportance) {
evictIndex = index;
sfxId = gSoundBanks[bankId][index].sfxId & 0xFFFF;
evictImportance = gSoundParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance;
}
count++;
if (count == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) {
if (gSoundParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance >= evictImportance) {
index = evictIndex;
} else {
index = 0;
}
}
}
if (count == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) {
soundParams = &gSoundParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)];
if ((req->sfxId & 0xC00) || (soundParams->params & 4) || (index == evictIndex)) {
if ((gSoundBanks[bankId][index].sfxParams & 8) &&
gSoundBanks[bankId][index].state != SFX_STATE_QUEUED) {
Audio_ClearBGMMute(gSoundBanks[bankId][index].channelIdx);
}
gSoundBanks[bankId][index].token = req->token;
gSoundBanks[bankId][index].sfxId = req->sfxId;
gSoundBanks[bankId][index].state = SFX_STATE_QUEUED;
gSoundBanks[bankId][index].freshness = 2;
gSoundBanks[bankId][index].freqScale = req->freqScale;
gSoundBanks[bankId][index].vol = req->vol;
gSoundBanks[bankId][index].reverbAdd = req->reverbAdd;
gSoundBanks[bankId][index].sfxParams = soundParams->params;
gSoundBanks[bankId][index].sfxImportance = soundParams->importance;
} else if (gSoundBanks[bankId][index].state == SFX_STATE_PLAYING_2) {
gSoundBanks[bankId][index].state = SFX_STATE_PLAYING_1;
}
index = 0;
}
}
if (index != 0) {
index = gSoundBanks[bankId][index].next;
}
}
if (gSoundBanks[bankId][sSoundBankFreeListStart[bankId]].next != 0xFF && index != 0) {
index = sSoundBankFreeListStart[bankId];
entry = &gSoundBanks[bankId][index];
entry->posX = &req->pos->x;
entry->posY = &req->pos->y;
entry->posZ = &req->pos->z;
entry->token = req->token;
entry->freqScale = req->freqScale;
entry->vol = req->vol;
entry->reverbAdd = req->reverbAdd;
soundParams = &gSoundParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)];
entry->sfxParams = soundParams->params;
entry->sfxImportance = soundParams->importance;
entry->sfxId = req->sfxId;
entry->state = SFX_STATE_QUEUED;
entry->freshness = 2;
entry->prev = sSoundBankListEnd[bankId];
gSoundBanks[bankId][sSoundBankListEnd[bankId]].next = sSoundBankFreeListStart[bankId];
sSoundBankListEnd[bankId] = sSoundBankFreeListStart[bankId];
sSoundBankFreeListStart[bankId] = gSoundBanks[bankId][sSoundBankFreeListStart[bankId]].next;
gSoundBanks[bankId][sSoundBankFreeListStart[bankId]].prev = 0xFF;
entry->next = 0xFF;
}
}
void Audio_RemoveSoundBankEntry(u8 bankId, u8 entryIndex)
{
SoundBankEntry* entry = &gSoundBanks[bankId][entryIndex];
u8 i;
if (entry->sfxParams & 8) {
Audio_ClearBGMMute(entry->channelIdx);
}
if (entryIndex == sSoundBankListEnd[bankId]) {
sSoundBankListEnd[bankId] = entry->prev;
} else {
gSoundBanks[bankId][entry->next].prev = entry->prev;
}
gSoundBanks[bankId][entry->prev].next = entry->next;
entry->next = sSoundBankFreeListStart[bankId];
entry->prev = 0xFF;
gSoundBanks[bankId][sSoundBankFreeListStart[bankId]].prev = entryIndex;
sSoundBankFreeListStart[bankId] = entryIndex;
entry->state = SFX_STATE_EMPTY;
for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
if (gActiveSounds[bankId][i].entryIndex == entryIndex) {
gActiveSounds[bankId][i].entryIndex = 0xFF;
i = gChannelsPerBank[gSfxChannelLayout][bankId];
}
}
}
void Audio_ChooseActiveSounds(u8 bankId)
{
u8 numChosenSounds;
u8 numChannels;
u8 entryIndex;
u8 i;
u8 j;
u8 k;
u8 sfxImportance;
u8 needNewSound;
u8 chosenEntryIndex;
u16 temp3;
f32 tempf1;
SoundBankEntry* entry;
ActiveSound chosenSounds[MAX_CHANNELS_PER_BANK];
ActiveSound* activeSound;
s32 pad;
numChosenSounds = 0;
for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) {
chosenSounds[i].priority = 0x7FFFFFFF;
chosenSounds[i].entryIndex = 0xFF;
}
entryIndex = gSoundBanks[bankId][0].next;
k = 0;
while (entryIndex != 0xFF) {
if ((gSoundBanks[bankId][entryIndex].state == SFX_STATE_QUEUED) &&
(gSoundBanks[bankId][entryIndex].sfxId & 0xC00)) {
gSoundBanks[bankId][entryIndex].freshness--;
} else if (!(gSoundBanks[bankId][entryIndex].sfxId & 0xC00) &&
(gSoundBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_2)) {
Audio_QueueCmdS8((gSoundBanks[bankId][entryIndex].channelIdx << 8) | 0x6020000, 0);
Audio_RemoveSoundBankEntry(bankId, entryIndex);
}
if (gSoundBanks[bankId][entryIndex].freshness == 0) {
Audio_RemoveSoundBankEntry(bankId, entryIndex);
} else if (gSoundBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) {
entry = &gSoundBanks[bankId][entryIndex];
if (&D_801333D4.x == entry[0].posX) {
entry->dist = 0.0f;
} else {
tempf1 = *entry->posY * 1;
entry->dist = (SQ(*entry->posX) + SQ(tempf1) + SQ(*entry->posZ)) * 1;
}
sfxImportance = entry->sfxImportance;
if (entry->sfxParams & 0x10) {
entry->priority = SQ(0xFF - sfxImportance) * SQ(76);
} else {
if (entry->dist > 0x7FFFFFD0) {
entry->dist = 0x70000008;
osSyncPrintf(D_80133344, entry->sfxId, entry->posX, entry->posZ, *entry->posX, *entry->posY,
*entry->posZ);
}
temp3 = entry->sfxId; // fake
entry->priority = (u32)entry->dist + (SQ(0xFF - sfxImportance) * SQ(76)) + temp3 - temp3;
if (*entry->posZ < 0.0f) {
entry->priority += (s32)(-*entry->posZ * 6.0f);
}
}
if (entry->dist > SQ(1e5f)) {
if (entry->state == SFX_STATE_PLAYING_1) {
Audio_QueueCmdS8((entry->channelIdx << 8) | 0x6020000, 0);
if (entry->sfxId & 0xC00) {
Audio_RemoveSoundBankEntry(bankId, entryIndex);
entryIndex = k;
}
}
} else {
numChannels = gChannelsPerBank[gSfxChannelLayout][bankId];
for (i = 0; i < numChannels; i++) {
if (chosenSounds[i].priority >= entry->priority) {
if (numChosenSounds < gChannelsPerBank[gSfxChannelLayout][bankId]) {
numChosenSounds++;
}
for (j = numChannels - 1; j > i; j--) {
chosenSounds[j].priority = chosenSounds[j - 1].priority;
chosenSounds[j].entryIndex = chosenSounds[j - 1].entryIndex;
}
chosenSounds[i].priority = entry->priority;
chosenSounds[i].entryIndex = entryIndex;
i = numChannels; // "break;"
}
}
}
k = entryIndex;
}
entryIndex = gSoundBanks[bankId][k].next;
}
for (i = 0; i < numChosenSounds; i++) {
entry = &gSoundBanks[bankId][chosenSounds[i].entryIndex];
if (entry->state == SFX_STATE_QUEUED) {
entry->state = SFX_STATE_READY;
} else if (entry->state == SFX_STATE_PLAYING_1) {
entry->state = SFX_STATE_PLAYING_REFRESH;
}
}
// Pick something to play for all channels.
numChannels = gChannelsPerBank[gSfxChannelLayout][bankId];
for (i = 0; i < numChannels; i++) {
needNewSound = false;
activeSound = &gActiveSounds[bankId][i];
if (activeSound->entryIndex == 0xFF) {
needNewSound = true;
} else {
entry = &gSoundBanks[bankId][activeSound[0].entryIndex];
if (entry->state == SFX_STATE_PLAYING_1) {
if (entry->sfxId & 0xC00) {
Audio_RemoveSoundBankEntry(bankId, activeSound->entryIndex);
} else {
entry->state = SFX_STATE_QUEUED;
}
needNewSound = true;
} else if (entry->state == SFX_STATE_EMPTY) {
activeSound->entryIndex = 0xFF;
needNewSound = true;
} else {
// Sound is already playing as it should, nothing to do.
for (j = 0; j < numChannels; j++) {
if (activeSound->entryIndex == chosenSounds[j].entryIndex) {
chosenSounds[j].entryIndex = 0xFF;
j = numChannels;
}
}
numChosenSounds--;
}
}
if (needNewSound == true) {
for (j = 0; j < numChannels; j++) {
chosenEntryIndex = chosenSounds[j].entryIndex;
if ((chosenEntryIndex != 0xFF) &&
(gSoundBanks[bankId][chosenEntryIndex].state != SFX_STATE_PLAYING_REFRESH)) {
for (k = 0; k < numChannels; k++) {
if (chosenEntryIndex == gActiveSounds[bankId][k].entryIndex) {
needNewSound = false;
k = numChannels; // "break;"
}
}
if (needNewSound == true) {
activeSound->entryIndex = chosenEntryIndex;
chosenSounds[j].entryIndex = 0xFF;
j = numChannels + 1;
numChosenSounds--;
}
}
}
if (j == numChannels) {
// nothing found
activeSound->entryIndex = 0xFF;
}
}
}
}
void Audio_PlayActiveSounds(u8 bankId)
{
u8 entryIndex;
SequenceChannel* channel;
SoundBankEntry* entry;
u8 i;
for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
entryIndex = gActiveSounds[bankId][i].entryIndex;
if (entryIndex != 0xFF) {
entry = &gSoundBanks[bankId][entryIndex];
channel = gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIdx];
if (entry->state == SFX_STATE_READY) {
entry->channelIdx = sCurSfxPlayerChannelIdx;
if (entry->sfxParams & 8) {
Audio_QueueSeqCmdMute(sCurSfxPlayerChannelIdx);
}
if (entry->sfxParams & 0xC0) {
switch (entry->sfxParams & 0xC0) {
case 0x40:
entry->unk_2F = Audio_NextRandom() & 0xF;
break;
case 0x80:
entry->unk_2F = Audio_NextRandom() & 0x1F;
break;
case 0xC0:
entry->unk_2F = Audio_NextRandom() & 0x3F;
break;
default:
entry->unk_2F = 0;
break;
}
}
Audio_SetSoundProperties(bankId, entryIndex, sCurSfxPlayerChannelIdx);
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8), 1);
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8) | 4,
entry->sfxId & 0xFF);
if (gIsLargeSoundBank[bankId]) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8) | 5,
(entry->sfxId & 0x100) >> 8);
}
if (entry->sfxId & 0xC00) {
entry->state = SFX_STATE_PLAYING_1;
} else {
entry->state = SFX_STATE_PLAYING_2;
}
} else if ((u8)channel->soundScriptIO[1] == 0xFF) {
Audio_RemoveSoundBankEntry(bankId, entryIndex);
} else if (entry->state == SFX_STATE_PLAYING_REFRESH) {
Audio_SetSoundProperties(bankId, entryIndex, sCurSfxPlayerChannelIdx);
if (entry->sfxId & 0xC00) {
entry->state = SFX_STATE_PLAYING_1;
} else {
entry->state = SFX_STATE_PLAYING_2;
}
}
}
sCurSfxPlayerChannelIdx++;
}
}
void Audio_StopSfxByBank(u8 bankId)
{
SoundBankEntry* entry;
s32 pad;
SoundBankEntry cmp;
u8 entryIndex = gSoundBanks[bankId][0].next;
while (entryIndex != 0xFF) {
entry = &gSoundBanks[bankId][entryIndex];
if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0);
}
if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSoundBankEntry(bankId, entryIndex);
}
entryIndex = gSoundBanks[bankId][0].next;
}
cmp.sfxId = bankId << 12;
Audio_RemoveMatchingSoundRequests(0, &cmp);
}
void func_800F8884(u8 bankId, Vec3f* pos) {
SoundBankEntry* entry;
u8 entryIndex = gSoundBanks[bankId][0].next;
u8 prevEntryIndex = 0;
while (entryIndex != 0xFF) {
entry = &gSoundBanks[bankId][entryIndex];
if (entry->posX == &pos->x) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0);
}
if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSoundBankEntry(bankId, entryIndex);
}
} else {
prevEntryIndex = entryIndex;
}
entryIndex = gSoundBanks[bankId][prevEntryIndex].next;
}
}
void Audio_StopSfxByPosAndBank(u8 bankId, Vec3f* pos) {
SoundBankEntry cmp;
func_800F8884(bankId, pos);
cmp.sfxId = bankId << 12;
cmp.posX = &pos->x;
Audio_RemoveMatchingSoundRequests(1, &cmp);
}
void Audio_StopSfxByPos(Vec3f* pos) {
u8 i;
SoundBankEntry cmp;
for (i = 0; i < ARRAY_COUNT(gSoundBanks); i++) {
func_800F8884(i, pos);
}
cmp.posX = &pos->x;
Audio_RemoveMatchingSoundRequests(2, &cmp);
}
void Audio_StopSfxByPosAndId(Vec3f* pos, u16 sfxId)
{
SoundBankEntry* entry;
u8 entryIndex = gSoundBanks[SFX_BANK(sfxId)][0].next;
u8 prevEntryIndex = 0;
SoundBankEntry cmp;
while (entryIndex != 0xFF) {
entry = &gSoundBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->posX == &pos->x && entry->sfxId == sfxId) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0);
}
if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSoundBankEntry(SFX_BANK(sfxId), entryIndex);
}
entryIndex = 0xFF;
} else {
prevEntryIndex = entryIndex;
}
if (entryIndex != 0xFF) {
entryIndex = gSoundBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
}
}
cmp.posX = &pos->x;
cmp.sfxId = sfxId;
Audio_RemoveMatchingSoundRequests(3, &cmp);
}
void Audio_StopSfxByTokenAndId(u8 token, u16 sfxId) {
SoundBankEntry* entry;
u8 entryIndex = gSoundBanks[SFX_BANK(sfxId)][0].next;
u8 prevEntryIndex = 0;
SoundBankEntry cmp;
while (entryIndex != 0xFF) {
entry = &gSoundBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->token == token && entry->sfxId == sfxId) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0);
}
if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSoundBankEntry(SFX_BANK(sfxId), entryIndex);
}
} else {
prevEntryIndex = entryIndex;
}
if (entryIndex != 0xFF) {
entryIndex = gSoundBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
}
}
cmp.token = token;
cmp.sfxId = sfxId;
Audio_RemoveMatchingSoundRequests(4, &cmp);
}
void Audio_StopSfxById(u32 sfxId) {
SoundBankEntry* entry;
u8 entryIndex = gSoundBanks[SFX_BANK(sfxId)][0].next;
u8 prevEntryIndex = 0;
SoundBankEntry cmp;
while (entryIndex != 0xFF) {
entry = &gSoundBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->sfxId == sfxId) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0);
}
if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSoundBankEntry(SFX_BANK(sfxId), entryIndex);
}
} else {
prevEntryIndex = entryIndex;
}
entryIndex = gSoundBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
}
cmp.sfxId = sfxId;
Audio_RemoveMatchingSoundRequests(5, &cmp);
}
void Audio_ProcessSoundRequests(void) {
while (sSoundRequestWriteIndex != sSoundRequestReadIndex) {
Audio_ProcessSoundRequest();
sSoundRequestReadIndex++;
}
}
void Audio_SetUnusedBankLerp(u8 bankId, u8 target, u16 delay) {
if (delay == 0) {
delay++;
}
sUnusedBankLerp[bankId].target = target / 127.0f;
sUnusedBankLerp[bankId].remainingFrames = delay;
sUnusedBankLerp[bankId].step = ((sUnusedBankLerp[bankId].value - sUnusedBankLerp[bankId].target) / delay);
}
void Audio_StepUnusedBankLerp(u8 bankId) {
if (sUnusedBankLerp[bankId].remainingFrames != 0) {
sUnusedBankLerp[bankId].remainingFrames--;
if (sUnusedBankLerp[bankId].remainingFrames != 0) {
sUnusedBankLerp[bankId].value -= sUnusedBankLerp[bankId].step;
} else {
sUnusedBankLerp[bankId].value = sUnusedBankLerp[bankId].target;
}
}
}
void func_800F8F88(void) {
u8 bankId;
if (IS_SEQUENCE_CHANNEL_VALID(gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[0])) {
sCurSfxPlayerChannelIdx = 0;
for (bankId = 0; bankId < ARRAY_COUNT(gSoundBanks); bankId++) {
Audio_ChooseActiveSounds(bankId);
Audio_PlayActiveSounds(bankId);
Audio_StepUnusedBankLerp(bankId);
}
}
}
u8 Audio_IsSfxPlaying(u32 sfxId)
{
SoundBankEntry* entry;
u8 entryIndex = gSoundBanks[SFX_BANK(sfxId)][0].next;
while (entryIndex != 0xFF) {
entry = &gSoundBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->sfxId == sfxId) {
return true;
}
entryIndex = entry->next;
}
return false;
}
void Audio_ResetSounds(void) {
u8 bankId;
u8 i;
u8 entryIndex;
sSoundRequestWriteIndex = 0;
sSoundRequestReadIndex = 0;
D_801333D0 = 0;
for (bankId = 0; bankId < ARRAY_COUNT(gSoundBanks); bankId++) {
sSoundBankListEnd[bankId] = 0;
sSoundBankFreeListStart[bankId] = 1;
sSoundBankUnused[bankId] = 0;
gSoundBankMuted[bankId] = false;
sUnusedBankLerp[bankId].value = 1.0f;
sUnusedBankLerp[bankId].remainingFrames = 0;
}
for (bankId = 0; bankId < ARRAY_COUNT(gSoundBanks); bankId++) {
for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) {
gActiveSounds[bankId][i].entryIndex = 0xFF;
}
}
for (bankId = 0; bankId < ARRAY_COUNT(gSoundBanks); bankId++) {
gSoundBanks[bankId][0].prev = 0xFF;
gSoundBanks[bankId][0].next = 0xFF;
for (i = 1; i < sBankSizes[bankId] - 1; i++) {
gSoundBanks[bankId][i].prev = i - 1;
gSoundBanks[bankId][i].next = i + 1;
}
gSoundBanks[bankId][i].prev = i - 1;
gSoundBanks[bankId][i].next = 0xFF;
}
if (D_801333F8 == 0) {
for (bankId = 0; bankId < 10; bankId++) {
gAudioSfxSwapSource[bankId] = 0;
gAudioSfxSwapTarget[bankId] = 0;
gAudioSfxSwapMode[bankId] = 0;
}
D_801333F8++;
}
}

View file

@ -0,0 +1,710 @@
#include "ultra64.h"
#include "global.h"
#include "ultra64/abi.h"
#include "mixer.h"
typedef struct {
u8 unk_0;
u8 unk_1; // importance?
} Struct_8016E320;
Struct_8016E320 D_8016E320[4][5];
u8 D_8016E348[4];
u32 sAudioSeqCmds[0x100];
unk_D_8016E750 D_8016E750[4];
u8 sSeqCmdWrPos = 0;
u8 sSeqCmdRdPos = 0;
u8 D_80133408 = 0;
u8 D_8013340C = 1;
u8 D_80133410[] = { 0, 1, 2, 3 };
u8 gAudioSpecId = 0;
u8 D_80133418 = 0;
// TODO: clean up these macros. They are similar to ones in code_800EC960.c but without casts.
#define Audio_StartSeq(playerIdx, fadeTimer, seqId) \
Audio_QueueSeqCmd(0x00000000 | ((playerIdx) << 24) | ((fadeTimer) << 16) | (seqId))
#define Audio_SeqCmdA(playerIdx, a) Audio_QueueSeqCmd(0xA0000000 | ((playerIdx) << 24) | (a))
#define Audio_SeqCmdB30(playerIdx, a, b) Audio_QueueSeqCmd(0xB0003000 | ((playerIdx) << 24) | ((a) << 16) | (b))
#define Audio_SeqCmdB40(playerIdx, a, b) Audio_QueueSeqCmd(0xB0004000 | ((playerIdx) << 24) | ((a) << 16) | (b))
#define Audio_SeqCmd3(playerIdx, a) Audio_QueueSeqCmd(0x30000000 | ((playerIdx) << 24) | (a))
#define Audio_SeqCmd5(playerIdx, a, b) Audio_QueueSeqCmd(0x50000000 | ((playerIdx) << 24) | ((a) << 16) | (b))
#define Audio_SeqCmd4(playerIdx, a, b) Audio_QueueSeqCmd(0x40000000 | ((playerIdx) << 24) | ((a) << 16) | (b))
#define Audio_SetVolScaleNow(playerIdx, volFadeTimer, volScale) \
Audio_ProcessSeqCmd(0x40000000 | ((u8)playerIdx << 24) | ((u8)volFadeTimer << 16) | ((u8)(volScale * 127.0f)));
void func_800F9280(u8 playerIdx, u8 seqId, u8 arg2, u16 fadeTimer) {
u8 i;
u16 dur;
s32 pad;
if (D_80133408 == 0 || playerIdx == SEQ_PLAYER_SFX) {
arg2 &= 0x7F;
if (arg2 == 0x7F) {
dur = (fadeTimer >> 3) * 60 * gAudioContext.audioBufferParameters.updatesPerFrame;
Audio_QueueCmdS32(0x85000000 | _SHIFTL(playerIdx, 16, 8) | _SHIFTL(seqId, 8, 8), dur);
} else {
Audio_QueueCmdS32(0x82000000 | _SHIFTL(playerIdx, 16, 8) | _SHIFTL(seqId, 8, 8),
(fadeTimer * (u16)gAudioContext.audioBufferParameters.updatesPerFrame) / 4);
}
D_8016E750[playerIdx].unk_254 = seqId | (arg2 << 8);
D_8016E750[playerIdx].unk_256 = seqId | (arg2 << 8);
if (D_8016E750[playerIdx].volCur != 1.0f) {
Audio_QueueCmdF32(0x41000000 | _SHIFTL(playerIdx, 16, 8), D_8016E750[playerIdx].volCur);
}
D_8016E750[playerIdx].unk_28 = 0;
D_8016E750[playerIdx].unk_18 = 0;
D_8016E750[playerIdx].unk_14 = 0;
for (i = 0; i < 0x10; i++) {
D_8016E750[playerIdx].unk_50[i].unk_00 = 1.0f;
D_8016E750[playerIdx].unk_50[i].unk_0C = 0;
D_8016E750[playerIdx].unk_50[i].unk_10 = 1.0f;
D_8016E750[playerIdx].unk_50[i].unk_1C = 0;
}
D_8016E750[playerIdx].unk_250 = 0;
D_8016E750[playerIdx].unk_252 = 0;
}
}
void func_800F9474(u8 playerIdx, u16 arg1) {
Audio_QueueCmdS32(0x83000000 | ((u8)playerIdx << 16),
(arg1 * (u16)gAudioContext.audioBufferParameters.updatesPerFrame) / 4);
D_8016E750[playerIdx].unk_254 = NA_BGM_DISABLED;
}
typedef enum {
SEQ_START,
CMD1,
CMD2,
CMD3,
SEQ_VOL_UPD,
CMD5,
CMD6,
CMD7,
CMD8,
CMD9,
CMDA,
CMDB,
CMDC,
CMDD,
CMDE,
CMDF
} SeqCmdType;
void Audio_ProcessSeqCmd(u32 cmd) {
s32 pad[2];
u16 fadeTimer;
u16 channelMask;
u16 val;
u8 oldSpec;
u8 spec;
u8 op;
u8 subOp;
u8 playerIdx;
u8 seqId;
u8 seqArgs;
u8 found;
u8 port;
u8 duration;
u8 chanIdx;
u8 i;
s32 new_var;
f32 freqScale;
if (D_8013340C && (cmd & 0xF0000000) != 0x70000000) {
AudioDebug_ScrPrt((const s8*)D_80133390, (cmd >> 16) & 0xFFFF); // "SEQ H"
AudioDebug_ScrPrt((const s8*)D_80133398, cmd & 0xFFFF); // " L"
}
op = cmd >> 28;
playerIdx = (cmd & 0xF000000) >> 24;
switch (op) {
case 0x0:
// play sequence immediately
seqId = cmd & 0xFF;
seqArgs = (cmd & 0xFF00) >> 8;
fadeTimer = (cmd & 0xFF0000) >> 13;
if ((D_8016E750[playerIdx].unk_260 == 0) && (seqArgs < 0x80)) {
func_800F9280(playerIdx, seqId, seqArgs, fadeTimer);
}
break;
case 0x1:
// disable seq player
fadeTimer = (cmd & 0xFF0000) >> 13;
func_800F9474(playerIdx, fadeTimer);
break;
case 0x2:
// queue sequence
seqId = cmd & 0xFF;
seqArgs = (cmd & 0xFF00) >> 8;
fadeTimer = (cmd & 0xFF0000) >> 13;
new_var = seqArgs;
for (i = 0; i < D_8016E348[playerIdx]; i++) {
if (D_8016E320[playerIdx][i].unk_0 == seqId) {
if (i == 0) {
func_800F9280(playerIdx, seqId, seqArgs, fadeTimer);
}
return;
}
}
found = D_8016E348[playerIdx];
for (i = 0; i < D_8016E348[playerIdx]; i++) {
if (D_8016E320[playerIdx][i].unk_1 <= new_var) {
found = i;
i = D_8016E348[playerIdx]; // "break;"
}
}
if (D_8016E348[playerIdx] < 5) {
D_8016E348[playerIdx]++;
}
for (i = D_8016E348[playerIdx] - 1; i != found; i--) {
D_8016E320[playerIdx][i].unk_1 = D_8016E320[playerIdx][i - 1].unk_1;
D_8016E320[playerIdx][i].unk_0 = D_8016E320[playerIdx][i - 1].unk_0;
}
D_8016E320[playerIdx][found].unk_1 = seqArgs;
D_8016E320[playerIdx][found].unk_0 = seqId;
if (found == 0) {
func_800F9280(playerIdx, seqId, seqArgs, fadeTimer);
}
break;
case 0x3:
// unqueue/stop sequence
seqId = cmd & 0xFF;
fadeTimer = (cmd & 0xFF0000) >> 13;
found = D_8016E348[playerIdx];
for (i = 0; i < D_8016E348[playerIdx]; i++) {
if (D_8016E320[playerIdx][i].unk_0 == seqId) {
found = i;
i = D_8016E348[playerIdx]; // "break;"
}
}
if (found != D_8016E348[playerIdx]) {
for (i = found; i < D_8016E348[playerIdx] - 1; i++) {
D_8016E320[playerIdx][i].unk_1 = D_8016E320[playerIdx][i + 1].unk_1;
D_8016E320[playerIdx][i].unk_0 = D_8016E320[playerIdx][i + 1].unk_0;
}
D_8016E348[playerIdx]--;
}
if (found == 0) {
func_800F9474(playerIdx, fadeTimer);
if (D_8016E348[playerIdx] != 0) {
func_800F9280(playerIdx, D_8016E320[playerIdx][0].unk_0, D_8016E320[playerIdx][0].unk_1, fadeTimer);
}
}
break;
case 0x4:
// transition seq volume
duration = (cmd & 0xFF0000) >> 15;
val = cmd & 0xFF;
if (duration == 0) {
duration++;
}
D_8016E750[playerIdx].volTarget = (f32)val / 127.0f;
if (D_8016E750[playerIdx].volCur != D_8016E750[playerIdx].volTarget) {
D_8016E750[playerIdx].unk_08 =
(D_8016E750[playerIdx].volCur - D_8016E750[playerIdx].volTarget) / (f32)duration;
D_8016E750[playerIdx].unk_0C = duration;
}
break;
case 0x5:
// transition freq scale for all channels
duration = (cmd & 0xFF0000) >> 15;
val = cmd & 0xFFFF;
if (duration == 0) {
duration++;
}
freqScale = (f32)val / 1000.0f;
for (i = 0; i < 16; i++) {
D_8016E750[playerIdx].unk_50[i].unk_14 = freqScale;
D_8016E750[playerIdx].unk_50[i].unk_1C = duration;
D_8016E750[playerIdx].unk_50[i].unk_18 =
(D_8016E750[playerIdx].unk_50[i].unk_10 - freqScale) / (f32)duration;
}
D_8016E750[playerIdx].unk_250 = 0xFFFF;
break;
case 0xD:
// transition freq scale
duration = (cmd & 0xFF0000) >> 15;
chanIdx = (cmd & 0xF000) >> 12;
val = cmd & 0xFFF;
if (duration == 0) {
duration++;
}
freqScale = (f32)val / 1000.0f;
D_8016E750[playerIdx].unk_50[chanIdx].unk_14 = freqScale;
D_8016E750[playerIdx].unk_50[chanIdx].unk_18 =
(D_8016E750[playerIdx].unk_50[chanIdx].unk_10 - freqScale) / (f32)duration;
D_8016E750[playerIdx].unk_50[chanIdx].unk_1C = duration;
D_8016E750[playerIdx].unk_250 |= 1 << chanIdx;
break;
case 0x6:
// transition vol scale
duration = (cmd & 0xFF0000) >> 15;
chanIdx = (cmd & 0xF00) >> 8;
val = cmd & 0xFF;
if (duration == 0) {
duration++;
}
D_8016E750[playerIdx].unk_50[chanIdx].unk_04 = (f32)val / 127.0f;
if (D_8016E750[playerIdx].unk_50[chanIdx].unk_00 != D_8016E750[playerIdx].unk_50[chanIdx].unk_04) {
D_8016E750[playerIdx].unk_50[chanIdx].unk_08 =
(D_8016E750[playerIdx].unk_50[chanIdx].unk_00 - D_8016E750[playerIdx].unk_50[chanIdx].unk_04) /
(f32)duration;
D_8016E750[playerIdx].unk_50[chanIdx].unk_0C = duration;
D_8016E750[playerIdx].unk_252 |= 1 << chanIdx;
}
break;
case 0x7:
// set global io port
port = (cmd & 0xFF0000) >> 16;
val = cmd & 0xFF;
Audio_QueueCmdS8(0x46000000 | _SHIFTL(playerIdx, 16, 8) | _SHIFTL(port, 0, 8), val);
break;
case 0x8:
// set io port if channel masked
chanIdx = (cmd & 0xF00) >> 8;
port = (cmd & 0xFF0000) >> 16;
val = cmd & 0xFF;
if ((D_8016E750[playerIdx].unk_258 & (1 << chanIdx)) == 0) {
Audio_QueueCmdS8(0x06000000 | _SHIFTL(playerIdx, 16, 8) | _SHIFTL(chanIdx, 8, 8) | _SHIFTL(port, 0, 8),
val);
}
break;
case 0x9:
// set channel mask for command 0x8
D_8016E750[playerIdx].unk_258 = cmd & 0xFFFF;
break;
case 0xA:
// set channel stop mask
channelMask = cmd & 0xFFFF;
if (channelMask != 0) {
// with channel mask channelMask...
Audio_QueueCmdU16(0x90000000 | _SHIFTL(playerIdx, 16, 8), channelMask);
// stop channels
Audio_QueueCmdS8(0x08000000 | _SHIFTL(playerIdx, 16, 8) | 0xFF00, 1);
}
if ((channelMask ^ 0xFFFF) != 0) {
// with channel mask ~channelMask...
Audio_QueueCmdU16(0x90000000 | _SHIFTL(playerIdx, 16, 8), (channelMask ^ 0xFFFF));
// unstop channels
Audio_QueueCmdS8(0x08000000 | _SHIFTL(playerIdx, 16, 8) | 0xFF00, 0);
}
break;
case 0xB:
// update tempo
D_8016E750[playerIdx].unk_14 = cmd;
break;
case 0xC:
// start sequence with setup commands
subOp = (cmd & 0xF00000) >> 20;
if (subOp != 0xF) {
if (D_8016E750[playerIdx].unk_4D < 7) {
found = D_8016E750[playerIdx].unk_4D++;
if (found < 8) {
D_8016E750[playerIdx].unk_2C[found] = cmd;
D_8016E750[playerIdx].unk_4C = 2;
}
}
} else {
D_8016E750[playerIdx].unk_4D = 0;
}
break;
case 0xE:
subOp = (cmd & 0xF00) >> 8;
val = cmd & 0xFF;
switch (subOp) {
case 0:
// set sound mode
Audio_QueueCmdS32(0xF0000000, D_80133410[val]);
break;
case 1:
// set sequence starting disabled?
D_80133408 = val & 1;
break;
}
break;
case 0xF:
// change spec
spec = cmd & 0xFF;
gSfxChannelLayout = (cmd & 0xFF00) >> 8;
oldSpec = gAudioSpecId;
gAudioSpecId = spec;
func_800E5F88(spec);
func_800F71BC(oldSpec);
Audio_QueueCmdS32(0xF8000000, 0);
break;
}
}
void Audio_QueueSeqCmd(u32 cmd) {
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
}
void Audio_ProcessSeqCmds(void) {
while (sSeqCmdWrPos != sSeqCmdRdPos) {
Audio_ProcessSeqCmd(sAudioSeqCmds[sSeqCmdRdPos++]);
}
}
u16 func_800FA0B4(u8 playerIdx) {
if (!gAudioContext.seqPlayers[playerIdx].enabled) {
return NA_BGM_DISABLED;
}
return D_8016E750[playerIdx].unk_254;
}
s32 func_800FA11C(u32 arg0, u32 arg1) {
u8 i;
for (i = sSeqCmdRdPos; i != sSeqCmdWrPos; i++) {
if (arg0 == (sAudioSeqCmds[i] & arg1)) {
return false;
}
}
return true;
}
void func_800FA174(u8 playerIdx) {
D_8016E348[playerIdx] = 0;
}
void func_800FA18C(u8 playerIdx, u8 arg1) {
u8 i;
for (i = 0; i < D_8016E750[playerIdx].unk_4D; i++) {
u8 unkb = (D_8016E750[playerIdx].unk_2C[i] & 0xF00000) >> 20;
if (unkb == arg1) {
D_8016E750[playerIdx].unk_2C[i] = 0xFF000000;
}
}
}
void Audio_SetVolScale(u8 playerIdx, u8 scaleIdx, u8 targetVol, u8 volFadeTimer) {
f32 volScale;
u8 i;
D_8016E750[playerIdx].volScales[scaleIdx] = targetVol & 0x7F;
if (volFadeTimer != 0) {
D_8016E750[playerIdx].fadeVolUpdate = 1;
D_8016E750[playerIdx].volFadeTimer = volFadeTimer;
} else {
for (i = 0, volScale = 1.0f; i < 4; i++) {
volScale *= D_8016E750[playerIdx].volScales[i] / 127.0f;
}
Audio_SetVolScaleNow(playerIdx, volFadeTimer, volScale);
}
}
void func_800FA3DC(void) {
u32 temp_a1;
u16 temp_lo;
u16 temp_v1;
u16 phi_a2;
u8 temp_v0_4;
u8 temp_a0;
u8 temp_s1;
u8 temp_s0_3;
u8 temp_a3_3;
s32 pad[3];
u32 dummy;
f32 phi_f0;
u8 phi_t0;
u8 playerIdx;
u8 j;
u8 k;
for (playerIdx = 0; playerIdx < 4; playerIdx++) {
if (D_8016E750[playerIdx].unk_260 != 0) {
switch (func_800E5E20(&dummy)) {
case 1:
case 2:
case 3:
case 4:
D_8016E750[playerIdx].unk_260 = 0;
Audio_ProcessSeqCmd(D_8016E750[playerIdx].unk_25C);
break;
}
}
if (D_8016E750[playerIdx].fadeVolUpdate) {
phi_f0 = 1.0f;
for (j = 0; j < 4; j++) {
phi_f0 *= (D_8016E750[playerIdx].volScales[j] / 127.0f);
}
Audio_SeqCmd4(playerIdx, D_8016E750[playerIdx].volFadeTimer, (u8)(phi_f0 * 127.0f));
D_8016E750[playerIdx].fadeVolUpdate = 0;
}
if (D_8016E750[playerIdx].unk_0C != 0) {
D_8016E750[playerIdx].unk_0C--;
if (D_8016E750[playerIdx].unk_0C != 0) {
D_8016E750[playerIdx].volCur = D_8016E750[playerIdx].volCur - D_8016E750[playerIdx].unk_08;
} else {
D_8016E750[playerIdx].volCur = D_8016E750[playerIdx].volTarget;
}
Audio_QueueCmdF32(0x41000000 | _SHIFTL(playerIdx, 16, 8), D_8016E750[playerIdx].volCur);
}
if (D_8016E750[playerIdx].unk_14 != 0) {
temp_a1 = D_8016E750[playerIdx].unk_14;
phi_t0 = (temp_a1 & 0xFF0000) >> 15;
phi_a2 = temp_a1 & 0xFFF;
if (phi_t0 == 0) {
phi_t0++;
}
if (gAudioContext.seqPlayers[playerIdx].enabled) {
temp_lo = gAudioContext.seqPlayers[playerIdx].tempo / 0x30;
temp_v0_4 = (temp_a1 & 0xF000) >> 12;
switch (temp_v0_4) {
case 1:
phi_a2 += temp_lo;
break;
case 2:
if (phi_a2 < temp_lo) {
phi_a2 = temp_lo - phi_a2;
}
break;
case 3:
phi_a2 = temp_lo * (phi_a2 / 100.0f);
break;
case 4:
if (D_8016E750[playerIdx].unk_18) {
phi_a2 = D_8016E750[playerIdx].unk_18;
} else {
phi_a2 = temp_lo;
}
break;
}
if (phi_a2 > 300) {
phi_a2 = 300;
}
if (D_8016E750[playerIdx].unk_18 == 0) {
D_8016E750[playerIdx].unk_18 = temp_lo;
}
D_8016E750[playerIdx].unk_20 = phi_a2;
D_8016E750[playerIdx].unk_1C = gAudioContext.seqPlayers[playerIdx].tempo / 0x30;
D_8016E750[playerIdx].unk_24 = (D_8016E750[playerIdx].unk_1C - D_8016E750[playerIdx].unk_20) / phi_t0;
D_8016E750[playerIdx].unk_28 = phi_t0;
D_8016E750[playerIdx].unk_14 = 0;
}
}
if (D_8016E750[playerIdx].unk_28 != 0) {
D_8016E750[playerIdx].unk_28--;
if (D_8016E750[playerIdx].unk_28 != 0) {
D_8016E750[playerIdx].unk_1C = D_8016E750[playerIdx].unk_1C - D_8016E750[playerIdx].unk_24;
} else {
D_8016E750[playerIdx].unk_1C = D_8016E750[playerIdx].unk_20;
}
// set tempo
Audio_QueueCmdS32(0x47000000 | _SHIFTL(playerIdx, 16, 8), D_8016E750[playerIdx].unk_1C);
}
if (D_8016E750[playerIdx].unk_252 != 0) {
for (k = 0; k < 0x10; k++) {
if (D_8016E750[playerIdx].unk_50[k].unk_0C != 0) {
D_8016E750[playerIdx].unk_50[k].unk_0C--;
if (D_8016E750[playerIdx].unk_50[k].unk_0C != 0) {
D_8016E750[playerIdx].unk_50[k].unk_00 -= D_8016E750[playerIdx].unk_50[k].unk_08;
} else {
D_8016E750[playerIdx].unk_50[k].unk_00 = D_8016E750[playerIdx].unk_50[k].unk_04;
D_8016E750[playerIdx].unk_252 ^= (1 << k);
}
// CHAN_UPD_VOL_SCALE (playerIdx = seq, k = chan)
Audio_QueueCmdF32(0x01000000 | _SHIFTL(playerIdx, 16, 8) | _SHIFTL(k, 8, 8),
D_8016E750[playerIdx].unk_50[k].unk_00);
}
}
}
if (D_8016E750[playerIdx].unk_250 != 0) {
for (k = 0; k < 0x10; k++) {
if (D_8016E750[playerIdx].unk_50[k].unk_1C != 0) {
D_8016E750[playerIdx].unk_50[k].unk_1C--;
if (D_8016E750[playerIdx].unk_50[k].unk_1C != 0) {
D_8016E750[playerIdx].unk_50[k].unk_10 -= D_8016E750[playerIdx].unk_50[k].unk_18;
} else {
D_8016E750[playerIdx].unk_50[k].unk_10 = D_8016E750[playerIdx].unk_50[k].unk_14;
D_8016E750[playerIdx].unk_250 ^= (1 << k);
}
// CHAN_UPD_FREQ_SCALE
Audio_QueueCmdF32(0x04000000 | _SHIFTL(playerIdx, 16, 8) | _SHIFTL(k, 8, 8),
D_8016E750[playerIdx].unk_50[k].unk_10);
}
}
}
if (D_8016E750[playerIdx].unk_4D != 0) {
if (func_800FA11C(0xF0000000, 0xF0000000) == 0) {
D_8016E750[playerIdx].unk_4D = 0;
return;
}
if (D_8016E750[playerIdx].unk_4C != 0) {
D_8016E750[playerIdx].unk_4C--;
continue;
}
if (gAudioContext.seqPlayers[playerIdx].enabled) {
continue;
}
for (j = 0; j < D_8016E750[playerIdx].unk_4D; j++) {
temp_a0 = (D_8016E750[playerIdx].unk_2C[j] & 0x00F00000) >> 20;
temp_s1 = (D_8016E750[playerIdx].unk_2C[j] & 0x000F0000) >> 16;
temp_s0_3 = (D_8016E750[playerIdx].unk_2C[j] & 0xFF00) >> 8;
temp_a3_3 = D_8016E750[playerIdx].unk_2C[j] & 0xFF;
switch (temp_a0) {
case 0:
Audio_SetVolScale(temp_s1, 1, 0x7F, temp_a3_3);
break;
case 7:
if (D_8016E348[playerIdx] == temp_a3_3) {
Audio_SetVolScale(temp_s1, 1, 0x7F, temp_s0_3);
}
break;
case 1:
Audio_SeqCmd3(playerIdx, D_8016E750[playerIdx].unk_254);
break;
case 2:
Audio_StartSeq(temp_s1, 1, D_8016E750[temp_s1].unk_254);
D_8016E750[temp_s1].fadeVolUpdate = 1;
D_8016E750[temp_s1].volScales[1] = 0x7F;
break;
case 3:
Audio_SeqCmdB30(temp_s1, temp_s0_3, temp_a3_3);
break;
case 4:
Audio_SeqCmdB40(temp_s1, temp_a3_3, 0);
break;
case 5:
temp_v1 = D_8016E750[playerIdx].unk_2C[j] & 0xFFFF;
Audio_StartSeq(temp_s1, D_8016E750[temp_s1].unk_4E, temp_v1);
Audio_SetVolScale(temp_s1, 1, 0x7F, 0);
D_8016E750[temp_s1].unk_4E = 0;
break;
case 6:
D_8016E750[playerIdx].unk_4E = temp_s0_3;
break;
case 8:
Audio_SetVolScale(temp_s1, temp_s0_3, 0x7F, temp_a3_3);
break;
case 14:
if (temp_a3_3 & 1) {
Audio_QueueCmdS32(0xE3000000, SEQUENCE_TABLE);
}
if (temp_a3_3 & 2) {
Audio_QueueCmdS32(0xE3000000, FONT_TABLE);
}
if (temp_a3_3 & 4) {
Audio_QueueCmdS32(0xE3000000, SAMPLE_TABLE);
}
break;
case 9:
temp_v1 = D_8016E750[playerIdx].unk_2C[j] & 0xFFFF;
Audio_SeqCmdA(temp_s1, temp_v1);
break;
case 10:
Audio_SeqCmd5(temp_s1, temp_s0_3, (temp_a3_3 * 10) & 0xFFFF);
break;
}
}
D_8016E750[playerIdx].unk_4D = 0;
}
}
}
u8 func_800FAD34(void) {
if (D_80133418 != 0) {
if (D_80133418 == 1) {
if (func_800E5EDC() == 1) {
D_80133418 = 0;
Audio_QueueCmdS8(0x46020000, gSfxChannelLayout);
func_800F7170();
}
} else if (D_80133418 == 2) {
while (func_800E5EDC() != 1) {}
D_80133418 = 0;
Audio_QueueCmdS8(0x46020000, gSfxChannelLayout);
func_800F7170();
}
}
return D_80133418;
}
void func_800FADF8(void) {
u8 playerIdx, j;
for (playerIdx = 0; playerIdx < 4; playerIdx++) {
D_8016E348[playerIdx] = 0;
D_8016E750[playerIdx].unk_254 = NA_BGM_DISABLED;
D_8016E750[playerIdx].unk_256 = NA_BGM_DISABLED;
D_8016E750[playerIdx].unk_28 = 0;
D_8016E750[playerIdx].unk_18 = 0;
D_8016E750[playerIdx].unk_14 = 0;
D_8016E750[playerIdx].unk_258 = 0;
D_8016E750[playerIdx].unk_4D = 0;
D_8016E750[playerIdx].unk_4E = 0;
D_8016E750[playerIdx].unk_250 = 0;
D_8016E750[playerIdx].unk_252 = 0;
for (j = 0; j < 4; j++) {
D_8016E750[playerIdx].volScales[j] = 0x7F;
}
D_8016E750[playerIdx].volFadeTimer = 1;
D_8016E750[playerIdx].fadeVolUpdate = 1;
}
}
void func_800FAEB4(void) {
u8 playerIdx, j;
for (playerIdx = 0; playerIdx < 4; playerIdx++) {
D_8016E750[playerIdx].volCur = 1.0f;
D_8016E750[playerIdx].unk_0C = 0;
D_8016E750[playerIdx].fadeVolUpdate = 0;
for (j = 0; j < 4; j++) {
D_8016E750[playerIdx].volScales[j] = 0x7F;
}
}
func_800FADF8();
}

View file

@ -0,0 +1,52 @@
#include "global.h"
#define printSpStatus(x, name) \
if (x & SP_STATUS_##name) \
osSyncPrintf(#name " ")
#define printDpStatus(x, name) \
if (x & DPC_STATUS_##name) \
osSyncPrintf(#name " ")
void func_800FBCE0() {
u32 spStatus = __osSpGetStatus();
u32 dpStatus = osDpGetStatus();
osSyncPrintf("osSpGetStatus=%08x: ", spStatus);
printSpStatus(spStatus, HALT);
printSpStatus(spStatus, BROKE);
printSpStatus(spStatus, DMA_BUSY);
printSpStatus(spStatus, DMA_FULL);
printSpStatus(spStatus, IO_FULL);
printSpStatus(spStatus, SSTEP);
printSpStatus(spStatus, INTR_BREAK);
printSpStatus(spStatus, YIELD);
printSpStatus(spStatus, YIELDED);
printSpStatus(spStatus, TASKDONE);
printSpStatus(spStatus, SIG3);
printSpStatus(spStatus, SIG4);
printSpStatus(spStatus, SIG5);
printSpStatus(spStatus, SIG6);
printSpStatus(spStatus, SIG7);
osSyncPrintf("\n");
osSyncPrintf("osDpGetStatus=%08x:", dpStatus);
printDpStatus(dpStatus, XBUS_DMEM_DMA);
printDpStatus(dpStatus, FREEZE);
printDpStatus(dpStatus, FLUSH);
printDpStatus(dpStatus, START_GCLK);
printDpStatus(dpStatus, TMEM_BUSY);
printDpStatus(dpStatus, PIPE_BUSY);
printDpStatus(dpStatus, CMD_BUSY);
printDpStatus(dpStatus, CBUF_READY);
printDpStatus(dpStatus, DMA_BUSY);
printDpStatus(dpStatus, END_VALID);
printDpStatus(dpStatus, START_VALID);
osSyncPrintf("\n");
}
void func_800FBFD8() {
func_800FBCE0();
osDpSetStatus(DPC_SET_FREEZE | DPC_SET_FLUSH);
__osSpSetStatus(SP_SET_HALT | SP_SET_SIG2 | SP_CLR_INTR_BREAK);
func_800FBCE0();
}

View file

@ -0,0 +1,201 @@
#include "global.h"
typedef void (*arg3_800FC868)(void*);
typedef void (*arg3_800FC8D8)(void*, u32);
typedef void (*arg3_800FC948)(void*, u32, u32, u32, u32, u32, u32, u32, u32);
typedef void (*arg3_800FCA18)(void*, u32);
typedef struct InitFunc {
s32 nextOffset;
void (*func)(void);
} InitFunc;
// .data
void* sInitFuncs = NULL;
char sNew[] = { 'n', 'e', 'w' };
char D_80134488[0x18] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00,
0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
};
s32 Overlay_Load(uintptr_t vRomStart, uintptr_t vRomEnd, void* vRamStart, void* vRamEnd, void* allocatedVRamAddr)
{
return 0;
#if 0
s32 pad;
uintptr_t end;
u32 bssSize;
OverlayRelocationSection* ovl;
u32 relocCnt;
u32 ovlOffset;
size_t size;
if (gOverlayLogSeverity >= 3) {
// "Start loading dynamic link function"
osSyncPrintf("\nダイナミックリンクファンクションのロードを開始します\n");
}
if (gOverlayLogSeverity >= 3) {
size = vRomEnd - vRomStart;
// "DMA transfer of TEXT, DATA, RODATA + rel (%08x-%08x)"
osSyncPrintf("TEXT,DATA,RODATA+relを転送します(%08x-%08x)\n", allocatedVRamAddr,
(uintptr_t)allocatedVRamAddr + size);
}
size = vRomEnd - vRomStart;
end = (uintptr_t)allocatedVRamAddr + size;
DmaMgr_SendRequest0(allocatedVRamAddr, vRomStart, size);
ovlOffset = ((s32*)end)[-1];
ovl = (OverlayRelocationSection*)((uintptr_t)end - ovlOffset);
if (gOverlayLogSeverity >= 3) {
osSyncPrintf("TEXT(%08x), DATA(%08x), RODATA(%08x), BSS(%08x)\n", ovl->textSize, ovl->dataSize, ovl->rodataSize,
ovl->bssSize);
}
if (gOverlayLogSeverity >= 3) {
osSyncPrintf("リロケーションします\n"); // "Relocate"
}
Overlay_Relocate(allocatedVRamAddr, ovl, vRamStart);
bssSize = ovl->bssSize;
if (bssSize != 0) {
if (gOverlayLogSeverity >= 3) {
// "Clear BSS area (% 08x-% 08x)"
osSyncPrintf("BSS領域をクリアします(%08x-%08x)\n", end, end + ovl->bssSize);
}
size = ovl->bssSize;
bssSize = size;
bzero((void*)end, bssSize);
relocCnt = ovl->nRelocations;
(void)relocCnt; // suppresses set but unused warning
}
size = (uintptr_t)&ovl->relocations[ovl->nRelocations] - (uintptr_t)ovl;
if (gOverlayLogSeverity >= 3) {
// "Clear REL area (%08x-%08x)"
osSyncPrintf("REL領域をクリアします(%08x-%08x)\n", ovl, (uintptr_t)ovl + size);
}
bzero(ovl, size);
size = (uintptr_t)vRamEnd - (uintptr_t)vRamStart;
osWritebackDCache(allocatedVRamAddr, size);
osInvalICache(allocatedVRamAddr, size);
if (gOverlayLogSeverity >= 3) {
// "Finish loading dynamic link function"
osSyncPrintf("ダイナミックリンクファンクションのロードを終了します\n\n");
}
return size;
#endif
}
// possibly some kind of new() function
void* func_800FC800(size_t size) {
if (size == 0) {
size = 1;
}
return __osMallocDebug(&gSystemArena, size, sNew, 0);
}
// possible some kind of delete() function
void func_800FC83C(void* ptr) {
if (ptr != NULL) {
__osFree(&gSystemArena, ptr);
}
}
void func_800FC868(void* blk, u32 nBlk, u32 blkSize, arg3_800FC868 arg3) {
uintptr_t pos;
for (pos = (uintptr_t)blk; pos < (uintptr_t)blk + (nBlk * blkSize); pos = (uintptr_t)pos + (blkSize & ~0)) {
arg3((void*)pos);
}
}
void func_800FC8D8(void* blk, u32 nBlk, s32 blkSize, arg3_800FC8D8 arg3) {
uintptr_t pos;
for (pos = (uintptr_t)blk; pos < (uintptr_t)blk + (nBlk * blkSize); pos = (uintptr_t)pos + (blkSize & ~0)) {
arg3((void*)pos, 2);
}
}
void* func_800FC948(void* blk, u32 nBlk, u32 blkSize, arg3_800FC948 arg3) {
uintptr_t pos;
if (blk == NULL) {
blk = func_800FC800(nBlk * blkSize);
}
if (blk != NULL && arg3 != NULL) {
pos = (uintptr_t)blk;
while (pos < (uintptr_t)blk + (nBlk * blkSize)) {
arg3((void*)pos, 0, 0, 0, 0, 0, 0, 0, 0);
pos = (uintptr_t)pos + (blkSize & ~0);
}
}
return blk;
}
void func_800FCA18(void* blk, u32 nBlk, u32 blkSize, arg3_800FCA18 arg3, s32 arg4) {
uintptr_t pos;
uintptr_t end;
s32 masked_arg2;
if (blk == 0) {
return;
}
if (arg3 != 0) {
end = (uintptr_t)blk;
masked_arg2 = (s32)(blkSize & ~0);
pos = (uintptr_t)end + (nBlk * blkSize);
if (masked_arg2) {}
while (pos > end) {
pos -= masked_arg2;
arg3((void*)pos, 2);
if (1) {}
}
if (!masked_arg2) {}
}
if (arg4 != 0) {
func_800FC83C(blk);
}
}
void func_800FCB34(void) {
InitFunc* initFunc = (InitFunc*)&sInitFuncs;
u32 nextOffset = initFunc->nextOffset;
InitFunc* prev = NULL;
while (nextOffset != 0) {
initFunc = (InitFunc*)((s32)initFunc + nextOffset);
if (initFunc->func != NULL) {
(*initFunc->func)();
}
nextOffset = initFunc->nextOffset;
initFunc->nextOffset = (s32)prev;
prev = initFunc;
}
sInitFuncs = prev;
}
void SystemHeap_Init(void* start, size_t size) {
SystemArena_Init(start, size);
func_800FCB34();
}

View file

@ -0,0 +1,161 @@
#include "global.h"
#include "fp.h"
s32 gUseAtanContFrac;
f32 Math_FTanF(f32 x) {
f32 sin = sinf(x);
f32 cos = cosf(x);
return sin / cos;
}
f32 Math_FFloorF(f32 x) {
return floorf(x);
}
f32 Math_FCeilF(f32 x) {
return ceilf(x);
}
f32 Math_FRoundF(f32 x) {
return roundf(x);
}
f32 Math_FTruncF(f32 x) {
return truncf(x);
}
f32 Math_FNearbyIntF(f32 x) {
return nearbyintf(x);
}
/* Arctangent approximation using a Taylor series (one quadrant) */
f32 Math_FAtanTaylorQF(f32 x) {
static const f32 coeffs[] = {
-1.0f / 3, +1.0f / 5, -1.0f / 7, +1.0f / 9, -1.0f / 11, +1.0f / 13, -1.0f / 15, +1.0f / 17, 0.0f,
};
f32 poly = x;
f32 sq = SQ(x);
f32 exp = x * sq;
const f32* c = coeffs;
f32 term;
while (1) {
term = *c++ * exp;
if (poly + term == poly) {
break;
}
poly = poly + term;
exp = exp * sq;
}
return poly;
}
/* Ditto for two quadrants */
f32 Math_FAtanTaylorF(f32 x) {
f32 t;
f32 q;
if (x > 0.0f) {
t = x;
} else if (x < 0.0f) {
t = -x;
} else if (x == 0.0f) {
return 0.0f;
} else {
return qNaN0x10000;
}
if (t <= M_SQRT2 - 1.0f) {
return Math_FAtanTaylorQF(x);
}
if (t >= M_SQRT2 + 1.0f) {
q = M_PI / 2 - Math_FAtanTaylorQF(1.0f / t);
} else {
q = M_PI / 4 - Math_FAtanTaylorQF((1.0f - t) / (1.0f + t));
}
if (x > 0.0f) {
return q;
} else {
return -q;
}
}
/* Arctangent approximation using a continued fraction */
f32 Math_FAtanContFracF(f32 x) {
s32 sector;
f32 z;
f32 conv;
f32 sq;
s32 i;
if (x >= -1.0f && x <= 1.0f) {
sector = 0;
} else if (x > 1.0f) {
sector = 1;
x = 1.0f / x;
} else if (x < -1.0f) {
sector = -1;
x = 1.0f / x;
} else {
return qNaN0x10000;
}
sq = SQ(x);
conv = 0.0f;
z = 8.0f;
for (i = 8; i != 0; i--) {
conv = SQ(z) * sq / (2.0f * z + 1.0f + conv);
z -= 1.0f;
}
conv = x / (1.0f + conv);
if (sector == 0) {
return conv;
} else if (sector > 0) {
return M_PI / 2 - conv;
} else {
return -M_PI / 2 - conv;
}
}
f32 Math_FAtanF(f32 x) {
if (!gUseAtanContFrac) {
return Math_FAtanTaylorF(x);
} else {
return Math_FAtanContFracF(x);
}
}
f32 Math_FAtan2F(f32 y, f32 x) {
if (x == 0.0f) {
if (y == 0.0f) {
return 0.0f;
} else if (y > 0.0f) {
return M_PI / 2;
} else if (y < 0.0f) {
return -M_PI / 2;
} else {
return qNaN0x10000;
}
} else if (x >= 0.0f) {
return Math_FAtanF(y / x);
} else if (y < 0.0f) {
return Math_FAtanF(y / x) - M_PI;
} else {
return M_PI - Math_FAtanF(-(y / x));
}
}
f32 Math_FAsinF(f32 x) {
return Math_FAtan2F(x, sqrtf(1.0f - SQ(x)));
}
f32 Math_FAcosF(f32 x) {
return M_PI / 2 - Math_FAsinF(x);
}

View file

@ -0,0 +1,82 @@
#include "global.h"
// The latest generated random number, used to generate the next number in the sequence.
static u32 sRandInt = 1;
// Space to store a value to be re-interpreted as a float.
static u32 sRandFloat;
/**
* Gets the next integer in the sequence of pseudo-random numbers.
*/
u32 Rand_Next(void) {
return sRandInt = (sRandInt * 1664525) + 1013904223;
}
/**
* Seeds the pseudo-random number generator by providing a starting value.
*/
void Rand_Seed(u32 seed) {
sRandInt = seed;
}
/**
* Returns a pseudo-random floating-point number between 0.0f and 1.0f, by generating
* the next integer and masking it to an IEEE-754 compliant floating-point number
* between 1.0f and 2.0f, returning the result subtract 1.0f.
*/
f32 Rand_ZeroOne(void) {
sRandInt = (sRandInt * 1664525) + 1013904223;
sRandFloat = ((sRandInt >> 9) | 0x3F800000);
return *((f32*)&sRandFloat) - 1.0f;
}
/**
* Returns a pseudo-random floating-point number between -0.5f and 0.5f by the same
* manner in which Rand_ZeroOne generates its result.
*/
f32 Rand_Centered(void) {
sRandInt = (sRandInt * 1664525) + 1013904223;
sRandFloat = ((sRandInt >> 9) | 0x3F800000);
return *((f32*)&sRandFloat) - 1.5f;
}
/**
* Seeds a pseudo-random number at rndNum with a provided seed.
*/
void Rand_Seed_Variable(u32* rndNum, u32 seed) {
*rndNum = seed;
}
/**
* Generates the next pseudo-random integer from the provided rndNum.
*/
u32 Rand_Next_Variable(u32* rndNum) {
return *rndNum = (*rndNum * 1664525) + 1013904223;
}
/**
* Generates the next pseudo-random floating-point number between 0.0f and
* 1.0f from the provided rndNum.
*/
f32 Rand_ZeroOne_Variable(u32* rndNum) {
u32 next = (*rndNum * 1664525) + 1013904223;
// clang-format off
*rndNum = next; sRandFloat = (next >> 9) | 0x3F800000;
// clang-format on
return *((f32*)&sRandFloat) - 1.0f;
}
/**
* Generates the next pseudo-random floating-point number between -0.5f and
* 0.5f from the provided rndNum.
*/
f32 Rand_Centered_Variable(u32* rndNum) {
u32 next = (*rndNum * 1664525) + 1013904223;
// clang-format off
*rndNum = next; sRandFloat = (next >> 9) | 0x3F800000;
// clang-format on
return *((f32*)&sRandFloat) - 1.5f;
}

View file

@ -0,0 +1,12 @@
#include "global.h"
// fmodf?
f32 func_801067F0(f32 arg0, f32 arg1) {
s32 sp4;
if (arg1 == 0.0f) {
return 0.0f;
}
sp4 = arg0 / arg1;
return arg0 - (sp4 * arg1);
}

View file

@ -0,0 +1,24 @@
#include "global.h"
// memmove used in __osMalloc.c
void* func_801068B0(void* dst, void* src, size_t size) {
u8* spC = dst;
u8* sp8 = src;
register s32 a3;
if (spC == sp8) {
return dst;
}
if (spC < sp8) {
for (a3 = size--; a3 != 0; a3 = size--) {
*spC++ = *sp8++;
}
} else {
spC += size - 1;
sp8 += size - 1;
for (a3 = size--; a3 != 0; a3 = size--) {
*spC-- = *sp8--;
}
}
return dst;
}

2312
soh/src/code/db_camera.c Normal file

File diff suppressed because it is too large Load diff

113
soh/src/code/debug_malloc.c Normal file
View file

@ -0,0 +1,113 @@
#include "global.h"
#include <string.h>
#define LOG_SEVERITY_NOLOG 0
#define LOG_SEVERITY_ERROR 2
#define LOG_SEVERITY_VERBOSE 3
s32 gDebugArenaLogSeverity = LOG_SEVERITY_ERROR;
Arena sDebugArena;
void DebugArena_CheckPointer(void* ptr, size_t size, const char* name, const char* action) {
if (ptr == NULL) {
if (gDebugArenaLogSeverity >= LOG_SEVERITY_ERROR) {
// "%s: %u bytes %s failed\n"
osSyncPrintf("%s: %u バイトの%sに失敗しました\n", name, size, action);
__osDisplayArena(&sDebugArena);
return;
}
} else if (gDebugArenaLogSeverity >= LOG_SEVERITY_VERBOSE) {
// "%s: %u bytes %s succeeded\n"
osSyncPrintf("%s: %u バイトの%sに成功しました\n", name, size, action);
}
}
void* DebugArena_Malloc(size_t size) {
void* ptr = __osMalloc(&sDebugArena, size);
DebugArena_CheckPointer(ptr, size, "debug_malloc", "確保"); // "Secure"
return ptr;
}
void* DebugArena_MallocDebug(size_t size, const char* file, s32 line) {
void* ptr = __osMallocDebug(&sDebugArena, size, file, line);
DebugArena_CheckPointer(ptr, size, "debug_malloc_DEBUG", "確保"); // "Secure"
return ptr;
}
void* DebugArena_MallocR(size_t size) {
void* ptr = __osMallocR(&sDebugArena, size);
DebugArena_CheckPointer(ptr, size, "debug_malloc_r", "確保"); // "Secure"
return ptr;
}
void* DebugArena_MallocRDebug(size_t size, const char* file, s32 line) {
void* ptr = __osMallocRDebug(&sDebugArena, size, file, line);
DebugArena_CheckPointer(ptr, size, "debug_malloc_r_DEBUG", "確保"); // "Secure"
return ptr;
}
void* DebugArena_Realloc(void* ptr, size_t newSize) {
ptr = __osRealloc(&sDebugArena, ptr, newSize);
DebugArena_CheckPointer(ptr, newSize, "debug_realloc", "再確保"); // "Re-securing"
return ptr;
}
void* DebugArena_ReallocDebug(void* ptr, size_t newSize, const char* file, s32 line) {
ptr = __osReallocDebug(&sDebugArena, ptr, newSize, file, line);
DebugArena_CheckPointer(ptr, newSize, "debug_realloc_DEBUG", "再確保"); // "Re-securing"
return ptr;
}
void DebugArena_Free(void* ptr) {
__osFree(&sDebugArena, ptr);
}
void DebugArena_FreeDebug(void* ptr, const char* file, s32 line) {
__osFreeDebug(&sDebugArena, ptr, file, line);
}
void* DebugArena_Calloc(size_t num, size_t size) {
void* ret;
size_t n = num * size;
ret = __osMalloc(&sDebugArena, n);
if (ret != NULL) {
memset(ret, 0, n);
}
DebugArena_CheckPointer(ret, n, "debug_calloc", "確保");
return ret;
}
void DebugArena_Display(void) {
// "Zelda heap display" ("Zelda" should probably have been changed to "Debug")
osSyncPrintf("ゼルダヒープ表示\n");
__osDisplayArena(&sDebugArena);
}
void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc) {
ArenaImpl_GetSizes(&sDebugArena, outMaxFree, outFree, outAlloc);
}
void DebugArena_Check(void) {
__osCheckArena(&sDebugArena);
}
void DebugArena_Init(void* start, size_t size) {
gDebugArenaLogSeverity = LOG_SEVERITY_NOLOG;
__osMallocInit(&sDebugArena, start, size);
}
void DebugArena_Cleanup(void) {
gDebugArenaLogSeverity = LOG_SEVERITY_NOLOG;
__osMallocCleanup(&sDebugArena);
}
u8 DebugArena_IsInitalized(void) {
return __osMallocIsInitalized(&sDebugArena);
}

1132
soh/src/code/fault.c Normal file

File diff suppressed because it is too large Load diff

308
soh/src/code/fault_drawer.c Normal file
View file

@ -0,0 +1,308 @@
#include "global.h"
#include "vt.h"
#include <string.h>
// rodata
const u32 sFaultDrawerFont[] = {
0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0, 0x06611DC0, 0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990,
0x05589760, 0x0DD22990, 0x05599770, 0x04DFFD40, 0x026EF700, 0x00000000, 0x00000000, 0x08BFFB00, 0x0EFFFFC0,
0x0BF00FB0, 0x0FF00330, 0x0FF00FF0, 0x0FF00220, 0x0CFBBF60, 0x0FFCCE20, 0x0DD44FF0, 0x0FF00220, 0x0FF00FF0,
0x0FF00330, 0x0CFBBF40, 0x0EF77740, 0x00000000, 0x00000000, 0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0, 0x06611DC0,
0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990, 0x05589760, 0x0DD22990, 0x05599770, 0x04DFFD40,
0x026EF700, 0x00000000, 0x00000000, 0x08BFFB00, 0x000DE000, 0x0BF00FB0, 0x005DE600, 0x0FF00FF0, 0x055CC660,
0x0CFBBF60, 0x773FF377, 0x0DD44FF0, 0xBB3FF3BB, 0x0FF00FF0, 0x099CCAA0, 0x0CFBBF40, 0x009DEA00, 0x00000000,
0x000DE000, 0x04C22C40, 0x028D5020, 0x0CCAACC0, 0x21F91710, 0x04C22C40, 0x12493400, 0x00820800, 0x01975110,
0x088A8880, 0x04615241, 0x00800800, 0x43117530, 0x00A20800, 0x60055600, 0x00000000, 0x04400040, 0x00221100,
0x00000080, 0x000FB000, 0x00000880, 0x040DA400, 0x00008800, 0x08CDE880, 0x022AA220, 0x08CDE880, 0x02AA2220,
0x040DA400, 0x0CD10000, 0x000FB000, 0x8C510000, 0x00221100, 0x81100000, 0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0,
0x06611DC0, 0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990, 0x05589760, 0x0DD22990, 0x05599770,
0x04DFFD40, 0x026EF700, 0x00000000, 0x00000000, 0x00333300, 0x04489980, 0x033CC330, 0x00CD1088, 0x033CC330,
0x02BF62A8, 0x00333320, 0x01104C80, 0x01100330, 0x0015C800, 0x033CC330, 0x02673220, 0x003FF300, 0x04409900,
0x00880000, 0x00000000, 0x05DFFD10, 0x07FFFF60, 0x1CE00EC1, 0x0FF00990, 0x1EE11661, 0x0FF00110, 0x1EF45621,
0x0FF66710, 0x1EF23661, 0x0FF08990, 0x1EF10FE1, 0x0FF00990, 0x16ECCE21, 0x07FBBB20, 0x01111110, 0x00000000,
0x09B66FD0, 0x27D88E60, 0x0992ED10, 0x2FF02EE0, 0x099AE510, 0x2FF62EE0, 0x099B7510, 0x2FD64EE0, 0x0DDAE510,
0x2FD04EE0, 0x0DD2ED10, 0x2FD00EE0, 0x09F66F90, 0x27D99F70, 0x00000000, 0x00000000, 0x07FFFF00, 0x8F711FF0,
0x2FD00FF0, 0x8F711FF0, 0x2FD00770, 0x8E611EE0, 0x27DDDF60, 0x8E691EE0, 0x27764AA0, 0x8EE99EE0, 0x2FD06E80,
0x8AE7FEA0, 0x07FA8E60, 0x88277A80, 0x00000000, 0x00000000, 0x077CCFF0, 0x13266011, 0x077CCFF0, 0x03766510,
0x0239D720, 0x04533540, 0x002FF200, 0x01133110, 0x005FB100, 0x00033000, 0x055EE550, 0x01133110, 0x055EEDD0,
0x02233000, 0x00088880, 0x8AABB888, 0x00001100, 0x00044510, 0x04623320, 0x00440110, 0x04C89AA0, 0x00EEAB10,
0x0CE66720, 0x0EF55FB0, 0x0EE00660, 0x0BF62B90, 0x0EE00660, 0x03FC8990, 0x04EEEEA0, 0x00773BB0, 0x00000000,
0x08888800, 0x09900000, 0x00111000, 0x09922440, 0x00011000, 0x09908800, 0x26EFDE20, 0x099BB540, 0x2EC33CE2,
0x0D9A2550, 0x2EC33CE2, 0x0DDAA550, 0x2EC33CE2, 0x09D6ED10, 0x26CBBC62, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00011000, 0x05FBFFE0, 0x8E6116E8, 0x0FF40330, 0x8F7117F8, 0x07FC8B30, 0x8E6996E8,
0x05733BA0, 0x8A6DD6A8, 0x0DD88A20, 0x08A779B2, 0x01100220, 0x00000000, 0x00000080, 0x8A011000, 0x00000800,
0x80A11000, 0x07744F70, 0x80A99000, 0x0231DF20, 0x84E60004, 0x0027DA20, 0xC8AA4C40, 0x00573B20, 0x00A11800,
0x05546F50, 0x00A99800, 0x02222080, 0x02001888,
};
FaultDrawer sFaultDrawerDefault = {
(u16*)(0x80400000 - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])), // fb
SCREEN_WIDTH, // w
SCREEN_HEIGHT, // h
16, // yStart
223, // yEnd
22, // xStart
297, // xEnd
GPACK_RGBA5551(255, 255, 255, 255), // foreColor
GPACK_RGBA5551(0, 0, 0, 0), // backColor
22, // cursorX
16, // cursorY
sFaultDrawerFont, // font
8,
8,
0,
0,
{
// printColors
GPACK_RGBA5551(0, 0, 0, 1),
GPACK_RGBA5551(255, 0, 0, 1),
GPACK_RGBA5551(0, 255, 0, 1),
GPACK_RGBA5551(255, 255, 0, 1),
GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 0, 255, 1),
GPACK_RGBA5551(0, 255, 255, 1),
GPACK_RGBA5551(255, 255, 255, 1),
GPACK_RGBA5551(120, 120, 120, 1),
GPACK_RGBA5551(176, 176, 176, 1),
},
0, // escCode
0, // osSyncPrintfEnabled
NULL, // inputCallback
};
FaultDrawer sFaultDrawerStruct;
char D_8016B6C0[0x20];
void FaultDrawer_SetOsSyncPrintfEnabled(u32 enabled) {
sFaultDrawerStruct.osSyncPrintfEnabled = enabled;
}
void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 color) {
u16* fb;
s32 x, y;
s32 xDiff = sFaultDrawerStruct.w - xStart;
s32 yDiff = sFaultDrawerStruct.h - yStart;
s32 xSize = xEnd - xStart + 1;
s32 ySize = yEnd - yStart + 1;
if (xDiff > 0 && yDiff > 0) {
if (xDiff < xSize) {
xSize = xDiff;
}
if (yDiff < ySize) {
ySize = yDiff;
}
fb = sFaultDrawerStruct.fb + sFaultDrawerStruct.w * yStart + xStart;
for (y = 0; y < ySize; y++) {
for (x = 0; x < xSize; x++) {
*fb++ = color;
}
fb += sFaultDrawerStruct.w - xSize;
}
osWritebackDCacheAll();
}
}
void FaultDrawer_DrawChar(char c) {
u16* fb;
s32 x, y;
const u32* dataPtr;
u32 data;
s32 cursorX = sFaultDrawerStruct.cursorX;
s32 cursorY = sFaultDrawerStruct.cursorY;
const u32** fontData = &sFaultDrawerStruct.fontData;
s32 shift = c % 4;
dataPtr = &fontData[0][(((c / 8) * 16) + ((c & 4) >> 2))];
fb = sFaultDrawerStruct.fb + (sFaultDrawerStruct.w * cursorY) + cursorX;
if ((sFaultDrawerStruct.xStart <= cursorX) &&
((sFaultDrawerStruct.charW + cursorX - 1) <= sFaultDrawerStruct.xEnd) &&
(sFaultDrawerStruct.yStart <= cursorY) &&
((sFaultDrawerStruct.charH + cursorY - 1) <= sFaultDrawerStruct.yEnd)) {
for (y = 0; y < sFaultDrawerStruct.charH; y++) {
u32 mask = 0x10000000 << shift;
data = *dataPtr;
for (x = 0; x < sFaultDrawerStruct.charW; x++) {
if (mask & data) {
fb[x] = sFaultDrawerStruct.foreColor;
} else if (sFaultDrawerStruct.backColor & 1) {
fb[x] = sFaultDrawerStruct.backColor;
}
mask >>= 4;
}
fb += sFaultDrawerStruct.w;
dataPtr += 2;
}
}
}
s32 FaultDrawer_ColorToPrintColor(u16 color) {
s32 i;
for (i = 0; i < 10; i++) {
if (color == sFaultDrawerStruct.printColors[i]) {
return i;
}
}
return -1;
}
void FaultDrawer_UpdatePrintColor() {
s32 idx;
if (sFaultDrawerStruct.osSyncPrintfEnabled) {
osSyncPrintf(VT_RST);
idx = FaultDrawer_ColorToPrintColor(sFaultDrawerStruct.foreColor);
if (idx >= 0 && idx < 8) {
osSyncPrintf(VT_SGR("3%d"), idx);
}
idx = FaultDrawer_ColorToPrintColor(sFaultDrawerStruct.backColor);
if (idx >= 0 && idx < 8) {
osSyncPrintf(VT_SGR("4%d"), idx);
}
}
}
void FaultDrawer_SetForeColor(u16 color) {
sFaultDrawerStruct.foreColor = color;
FaultDrawer_UpdatePrintColor();
}
void FaultDrawer_SetBackColor(u16 color) {
sFaultDrawerStruct.backColor = color;
FaultDrawer_UpdatePrintColor();
}
void FaultDrawer_SetFontColor(u16 color) {
FaultDrawer_SetForeColor(color | 1); // force alpha to be set
}
void FaultDrawer_SetCharPad(s8 padW, s8 padH) {
sFaultDrawerStruct.charWPad = padW;
sFaultDrawerStruct.charHPad = padH;
}
void FaultDrawer_SetCursor(s32 x, s32 y) {
if (sFaultDrawerStruct.osSyncPrintfEnabled) {
osSyncPrintf(VT_CUP("%d", "%d"),
(y - sFaultDrawerStruct.yStart) / (sFaultDrawerStruct.charH + sFaultDrawerStruct.charHPad),
(x - sFaultDrawerStruct.xStart) / (sFaultDrawerStruct.charW + sFaultDrawerStruct.charWPad));
}
sFaultDrawerStruct.cursorX = x;
sFaultDrawerStruct.cursorY = y;
}
void FaultDrawer_FillScreen() {
if (sFaultDrawerStruct.osSyncPrintfEnabled) {
osSyncPrintf(VT_CLS);
}
FaultDrawer_DrawRecImpl(sFaultDrawerStruct.xStart, sFaultDrawerStruct.yStart, sFaultDrawerStruct.xEnd,
sFaultDrawerStruct.yEnd, sFaultDrawerStruct.backColor | 1);
FaultDrawer_SetCursor(sFaultDrawerStruct.xStart, sFaultDrawerStruct.yStart);
}
void* FaultDrawer_FormatStringFunc(void* arg, const char* str, u32 count) {
for (; count != 0; count--, str++) {
s32 curXStart;
s32 curXEnd;
if (sFaultDrawerStruct.escCode) {
sFaultDrawerStruct.escCode = false;
if (*str > 0x30 && *str < 0x3A) {
FaultDrawer_SetForeColor(sFaultDrawerStruct.printColors[*str - 0x30]);
}
curXStart = sFaultDrawerStruct.cursorX;
curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW;
} else {
switch (*str) {
case '\n':
if (sFaultDrawerStruct.osSyncPrintfEnabled) {
osSyncPrintf("\n");
}
sFaultDrawerStruct.cursorX = sFaultDrawerStruct.w;
curXStart = sFaultDrawerStruct.cursorX;
curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW;
break;
case '\x1A':
sFaultDrawerStruct.escCode = true;
curXStart = sFaultDrawerStruct.cursorX;
curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW;
break;
default:
if (sFaultDrawerStruct.osSyncPrintfEnabled) {
osSyncPrintf("%c", *str);
}
FaultDrawer_DrawChar(*str);
sFaultDrawerStruct.cursorX += sFaultDrawerStruct.charW + sFaultDrawerStruct.charWPad;
curXStart = sFaultDrawerStruct.cursorX;
curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW;
}
}
if (curXEnd <= curXStart) {
sFaultDrawerStruct.cursorX = sFaultDrawerStruct.xStart;
sFaultDrawerStruct.cursorY += sFaultDrawerStruct.charH + sFaultDrawerStruct.charHPad;
if (sFaultDrawerStruct.yEnd - sFaultDrawerStruct.charH <= sFaultDrawerStruct.cursorY) {
if (sFaultDrawerStruct.inputCallback) {
sFaultDrawerStruct.inputCallback();
FaultDrawer_FillScreen();
}
sFaultDrawerStruct.cursorY = sFaultDrawerStruct.yStart;
}
}
}
osWritebackDCacheAll();
return arg;
}
void FaultDrawer_VPrintf(const char* str, char* args) { // va_list
_Printf(FaultDrawer_FormatStringFunc, (char*)&sFaultDrawerStruct, str, args);
}
void FaultDrawer_Printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
FaultDrawer_VPrintf(fmt, args);
va_end(args);
}
void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
FaultDrawer_SetCursor(x, y);
FaultDrawer_VPrintf(fmt, args);
va_end(args);
}
void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h) {
sFaultDrawerStruct.fb = fb;
sFaultDrawerStruct.w = w;
sFaultDrawerStruct.h = h;
}
void FaultDrawer_SetInputCallback(void (*callback)()) {
sFaultDrawerStruct.inputCallback = callback;
}
void FaultDrawer_WritebackFBDCache() {
osWritebackDCache(sFaultDrawerStruct.fb, sFaultDrawerStruct.w * sFaultDrawerStruct.h * 2);
}
void FaultDrawer_SetDefault() {
memcpy(&sFaultDrawerStruct, &sFaultDrawerDefault, sizeof(FaultDrawer));
sFaultDrawerStruct.fb = (u16*)((osMemSize | 0x80000000) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH]));
}

152
soh/src/code/flg_set.c Normal file
View file

@ -0,0 +1,152 @@
#include "global.h"
void FlagSet_Update(GlobalContext* globalCtx) {
static s32 entryIdx = 0;
static u32 curBit = 0;
static s32 timer = 0;
static s32 bitIdx; // ? this doesn't need to be static
FlagSetEntry entries[53] = {
{ &gSaveContext.eventChkInf[0], "event_chk_inf[0]" }, { &gSaveContext.eventChkInf[1], "event_chk_inf[1]" },
{ &gSaveContext.eventChkInf[2], "event_chk_inf[2]" }, { &gSaveContext.eventChkInf[3], "event_chk_inf[3]" },
{ &gSaveContext.eventChkInf[4], "event_chk_inf[4]" }, { &gSaveContext.eventChkInf[5], "event_chk_inf[5]" },
{ &gSaveContext.eventChkInf[6], "event_chk_inf[6]" }, { &gSaveContext.eventChkInf[7], "event_chk_inf[7]" },
{ &gSaveContext.eventChkInf[8], "event_chk_inf[8]" }, { &gSaveContext.eventChkInf[9], "event_chk_inf[9]" },
{ &gSaveContext.eventChkInf[10], "event_chk_inf[10]" }, { &gSaveContext.eventChkInf[11], "event_chk_inf[11]" },
{ &gSaveContext.eventChkInf[12], "event_chk_inf[12]" }, { &gSaveContext.eventChkInf[13], "event_chk_inf[13]" },
{ &gSaveContext.itemGetInf[0], "item_get_inf[0]" }, { &gSaveContext.itemGetInf[1], "item_get_inf[1]" },
{ &gSaveContext.itemGetInf[2], "item_get_inf[2]" }, { &gSaveContext.itemGetInf[3], "item_get_inf[3]" },
{ &gSaveContext.infTable[0], "inf_table[0]" }, { &gSaveContext.infTable[1], "inf_table[1]" },
{ &gSaveContext.infTable[2], "inf_table[2]" }, { &gSaveContext.infTable[3], "inf_table[3]" },
{ &gSaveContext.infTable[4], "inf_table[4]" }, { &gSaveContext.infTable[5], "inf_table[5]" },
{ &gSaveContext.infTable[6], "inf_table[6]" }, { &gSaveContext.infTable[7], "inf_table[7]" },
{ &gSaveContext.infTable[8], "inf_table[8]" }, { &gSaveContext.infTable[9], "inf_table[9]" },
{ &gSaveContext.infTable[10], "inf_table[10]" }, { &gSaveContext.infTable[11], "inf_table[11]" },
{ &gSaveContext.infTable[12], "inf_table[12]" }, { &gSaveContext.infTable[13], "inf_table[13]" },
{ &gSaveContext.infTable[14], "inf_table[14]" }, { &gSaveContext.infTable[15], "inf_table[15]" },
{ &gSaveContext.infTable[16], "inf_table[16]" }, { &gSaveContext.infTable[17], "inf_table[17]" },
{ &gSaveContext.infTable[18], "inf_table[18]" }, { &gSaveContext.infTable[19], "inf_table[19]" },
{ &gSaveContext.infTable[20], "inf_table[20]" }, { &gSaveContext.infTable[21], "inf_table[21]" },
{ &gSaveContext.infTable[22], "inf_table[22]" }, { &gSaveContext.infTable[23], "inf_table[23]" },
{ &gSaveContext.infTable[24], "inf_table[24]" }, { &gSaveContext.infTable[25], "inf_table[25]" },
{ &gSaveContext.infTable[26], "inf_table[26]" }, { &gSaveContext.infTable[27], "inf_table[27]" },
{ &gSaveContext.infTable[28], "inf_table[28]" }, { &gSaveContext.infTable[29], "inf_table[29]" },
{ &gSaveContext.eventInf[0], "event_inf[0]" }, { &gSaveContext.eventInf[1], "event_inf[1]" },
{ &gSaveContext.eventInf[2], "event_inf[2]" }, { &gSaveContext.eventInf[3], "event_inf[3]" },
};
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
Input* input = &globalCtx->state.input[0];
Gfx* gfx;
Gfx* polyOpa;
OPEN_DISPS(gfxCtx, "../flg_set.c", 131);
{
GfxPrint printer;
s32 pad;
polyOpa = POLY_OPA_DISP;
gfx = Graph_GfxPlusOne(polyOpa);
gSPDisplayList(OVERLAY_DISP++, gfx);
GfxPrint_Init(&printer);
GfxPrint_Open(&printer, gfx);
GfxPrint_SetColor(&printer, 250, 50, 50, 255);
GfxPrint_SetPos(&printer, 4, 13);
GfxPrint_Printf(&printer, entries[entryIdx].name);
GfxPrint_SetPos(&printer, 4, 15);
for (bitIdx = 15; bitIdx >= 0; bitIdx--) {
if ((u32)bitIdx == curBit) {
GfxPrint_SetColor(&printer, 200, 200, 200, 255);
} else {
GfxPrint_SetColor(&printer, 100, 100, 100, 255);
}
if (*entries[entryIdx].value & (1 << bitIdx)) {
GfxPrint_Printf(&printer, "1");
} else {
GfxPrint_Printf(&printer, "0");
}
if ((bitIdx % 4) == 0) {
GfxPrint_Printf(&printer, " ");
}
}
if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) {
timer = 10;
curBit++;
}
if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) {
curBit--;
timer = 10;
}
if (timer == 0) {
if (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) {
curBit++;
timer = 2;
}
if (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) {
curBit--;
timer = 2;
}
}
curBit %= 16;
if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) {
entryIdx--;
if (entryIdx < 0) {
entryIdx = 0;
}
timer = 10;
}
if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
timer = 10;
entryIdx++;
if (!entries[entryIdx].value) {
entryIdx--;
}
}
if (timer == 0) {
if (CHECK_BTN_ALL(input->cur.button, BTN_DUP)) {
entryIdx--;
timer = 2;
if (entryIdx < 0) {
entryIdx = 0;
}
}
if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN)) {
timer = 2;
entryIdx++;
if (!entries[entryIdx].value) {
entryIdx--;
}
}
}
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
*entries[entryIdx].value ^= (1 << curBit);
}
if (timer != 0) {
timer--;
}
gfx = GfxPrint_Close(&printer);
GfxPrint_Destroy(&printer);
gSPEndDisplayList(gfx++);
Graph_BranchDlist(polyOpa, gfx);
POLY_OPA_DISP = gfx;
}
if (CHECK_BTN_ALL(input->press.button, BTN_L)) {
globalCtx->pauseCtx.debugState = 0;
}
CLOSE_DISPS(gfxCtx, "../flg_set.c", 241);
}

505
soh/src/code/game.c Normal file
View file

@ -0,0 +1,505 @@
#include "global.h"
#include "vt.h"
SpeedMeter D_801664D0;
struct_801664F0 D_801664F0;
struct_80166500 D_80166500;
VisMono sMonoColors;
ViMode sViMode;
FaultClient sGameFaultClient;
u16 sLastButtonPressed;
void GameState_FaultPrint(void) {
static char sBtnChars[] = "ABZSuldr*+LRudlr";
s32 i;
osSyncPrintf("last_button=%04x\n", sLastButtonPressed);
FaultDrawer_DrawText(120, 180, "%08x", sLastButtonPressed);
for (i = 0; i < ARRAY_COUNT(sBtnChars); i++) {
if (sLastButtonPressed & (1 << i)) {
FaultDrawer_DrawText((i * 8) + 0x78, 0xBE, "%c", sBtnChars[i]);
}
}
}
void GameState_SetFBFilter(Gfx** gfx) {
Gfx* gfxP;
gfxP = *gfx;
if ((R_FB_FILTER_TYPE > 0) && (R_FB_FILTER_TYPE < 5)) {
D_801664F0.type = R_FB_FILTER_TYPE;
D_801664F0.color.r = R_FB_FILTER_PRIM_COLOR(0);
D_801664F0.color.g = R_FB_FILTER_PRIM_COLOR(1);
D_801664F0.color.b = R_FB_FILTER_PRIM_COLOR(2);
D_801664F0.color.a = R_FB_FILTER_A;
func_800ACE98(&D_801664F0, &gfxP);
} else if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) {
D_80166500.useRgba = (R_FB_FILTER_TYPE == 6);
D_80166500.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
D_80166500.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
D_80166500.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
D_80166500.primColor.a = R_FB_FILTER_A;
D_80166500.envColor.r = R_FB_FILTER_ENV_COLOR(0);
D_80166500.envColor.g = R_FB_FILTER_ENV_COLOR(1);
D_80166500.envColor.b = R_FB_FILTER_ENV_COLOR(2);
D_80166500.envColor.a = R_FB_FILTER_A;
func_800AD958(&D_80166500, &gfxP);
} else if (R_FB_FILTER_TYPE == 7) {
sMonoColors.unk_00 = 0;
sMonoColors.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
sMonoColors.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
sMonoColors.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
sMonoColors.primColor.a = R_FB_FILTER_A;
sMonoColors.envColor.r = R_FB_FILTER_ENV_COLOR(0);
sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1);
sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2);
sMonoColors.envColor.a = R_FB_FILTER_A;
VisMono_Draw(&sMonoColors, &gfxP);
}
*gfx = gfxP;
}
void func_800C4344(GameState* gameState) {
Input* selectedInput;
s32 hexDumpSize;
u16 hReg82;
if (HREG(80) == 0x14) {
__osMalloc_FreeBlockTest_Enable = HREG(82);
}
if (HREG(80) == 0xC) {
selectedInput = &gameState->input[(u32)HREG(81) < 4U ? HREG(81) : 0];
hReg82 = HREG(82);
HREG(83) = selectedInput->cur.button;
HREG(84) = selectedInput->press.button;
HREG(85) = selectedInput->rel.stick_x;
HREG(86) = selectedInput->rel.stick_y;
HREG(87) = selectedInput->rel.stick_x;
HREG(88) = selectedInput->rel.stick_y;
HREG(89) = selectedInput->cur.stick_x;
HREG(90) = selectedInput->cur.stick_y;
HREG(93) = (selectedInput->cur.button == hReg82);
HREG(94) = CHECK_BTN_ALL(selectedInput->cur.button, hReg82);
HREG(95) = CHECK_BTN_ALL(selectedInput->press.button, hReg82);
}
if (gIsCtrlr2Valid) {
func_8006390C(&gameState->input[1]);
}
D_80009460 = HREG(60);
gDmaMgrDmaBuffSize = SREG(21) != 0 ? ALIGN16(SREG(21)) : 0x2000;
gSystemArenaLogSeverity = HREG(61);
gZeldaArenaLogSeverity = HREG(62);
if (HREG(80) == 8) {
if (HREG(94) != 8) {
HREG(94) = 8;
HREG(81) = 0;
HREG(82) = 0;
HREG(83) = 0;
}
if (HREG(81) < 0) {
HREG(81) = 0;
// & 0xFFFFFFFF necessary for matching.
hexDumpSize = (HREG(83) == 0 ? 0x100 : HREG(83) * 0x10) & 0xFFFFFFFF;
LogUtils_LogHexDump(PHYSICAL_TO_VIRTUAL(HREG(82) << 8), hexDumpSize);
}
}
}
void GameState_DrawInputDisplay(u16 input, Gfx** gfx) {
static const u16 sInpDispBtnColors[] = {
GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1),
GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(120, 120, 120, 1), GPACK_RGBA5551(120, 120, 120, 1),
GPACK_RGBA5551(0, 255, 255, 1), GPACK_RGBA5551(255, 0, 255, 1), GPACK_RGBA5551(120, 120, 120, 1),
GPACK_RGBA5551(120, 120, 120, 1), GPACK_RGBA5551(120, 120, 120, 1), GPACK_RGBA5551(120, 120, 120, 1),
GPACK_RGBA5551(255, 0, 0, 1), GPACK_RGBA5551(120, 120, 120, 1), GPACK_RGBA5551(0, 255, 0, 1),
GPACK_RGBA5551(0, 0, 255, 1),
};
s32 i, j, k;
Gfx* gfxP = *gfx;
gDPPipeSync(gfxP++);
gDPSetOtherMode(gfxP++,
G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_FILL | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
for (i = 0; i < 16; i++) {
j = i;
if (input & (1 << i)) {
gDPSetFillColor(gfxP++, (sInpDispBtnColors[i] << 0x10) | sInpDispBtnColors[i]);
k = i + 1;
gDPFillRectangle(gfxP++, (j * 4) + 226, 220, (k * 4) + 225, 223);
gDPPipeSync(gfxP++);
}
}
*gfx = gfxP;
}
void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) {
Gfx* newDList;
Gfx* polyOpaP;
OPEN_DISPS(gfxCtx, "../game.c", 746);
newDList = Graph_GfxPlusOne(polyOpaP = POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, newDList);
if (R_ENABLE_FB_FILTER == 1) {
GameState_SetFBFilter(&newDList);
}
sLastButtonPressed = gameState->input[0].press.button | gameState->input[0].cur.button;
if (R_DISABLE_INPUT_DISPLAY == 0 && CVar_GetS32("gDebugEnabled", 0)) {
GameState_DrawInputDisplay(sLastButtonPressed, &newDList);
}
if (R_ENABLE_AUDIO_DBG & 1) {
s32 pad;
GfxPrint printer;
GfxPrint_Init(&printer);
GfxPrint_Open(&printer, newDList);
AudioDebug_Draw(&printer);
newDList = GfxPrint_Close(&printer);
GfxPrint_Destroy(&printer);
}
if (R_ENABLE_ARENA_DBG < 0) {
s32 pad;
DebugArena_Display();
SystemArena_Display();
// "%08x bytes left until the death of Hyrule (game_alloc)"
osSyncPrintf("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetSize(&gameState->tha));
R_ENABLE_ARENA_DBG = 0;
}
gSPEndDisplayList(newDList++);
Graph_BranchDlist(polyOpaP, newDList);
POLY_OPA_DISP = newDList;
if (1) {}
CLOSE_DISPS(gfxCtx, "../game.c", 800);
func_80063D7C(gfxCtx);
if (R_ENABLE_ARENA_DBG != 0) {
SpeedMeter_DrawTimeEntries(&D_801664D0, gfxCtx);
SpeedMeter_DrawAllocEntries(&D_801664D0, gfxCtx, gameState);
}
}
void GameState_SetFrameBuffer(GraphicsContext* gfxCtx) {
OPEN_DISPS(gfxCtx, "../game.c", 814);
gSPSegment(POLY_OPA_DISP++, 0, 0);
gSPSegment(POLY_OPA_DISP++, 0xF, gfxCtx->curFrameBuffer);
gSPSegment(POLY_OPA_DISP++, 0xE, gZBuffer);
gSPSegment(POLY_XLU_DISP++, 0, 0);
gSPSegment(POLY_XLU_DISP++, 0xF, gfxCtx->curFrameBuffer);
gSPSegment(POLY_XLU_DISP++, 0xE, gZBuffer);
gSPSegment(OVERLAY_DISP++, 0, 0);
gSPSegment(OVERLAY_DISP++, 0xF, gfxCtx->curFrameBuffer);
gSPSegment(OVERLAY_DISP++, 0xE, gZBuffer);
CLOSE_DISPS(gfxCtx, "../game.c", 838);
}
void func_800C49F4(GraphicsContext* gfxCtx) {
Gfx* newDlist;
Gfx* polyOpaP;
OPEN_DISPS(gfxCtx, "../game.c", 846);
newDlist = Graph_GfxPlusOne(polyOpaP = POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, newDlist);
gSPEndDisplayList(newDlist++);
Graph_BranchDlist(polyOpaP, newDlist);
POLY_OPA_DISP = newDlist;
if (1) {}
CLOSE_DISPS(gfxCtx, "../game.c", 865);
}
void PadMgr_RequestPadData(PadMgr*, Input*, s32);
void GameState_ReqPadData(GameState* gameState) {
PadMgr_RequestPadData(&gPadMgr, &gameState->input[0], 1);
}
// OTRTODO
int fbTest = -1;
void GameState_Update(GameState* gameState) {
GraphicsContext* gfxCtx = gameState->gfxCtx;
if (fbTest == -1)
{
fbTest = gfx_create_framebuffer(64, 112);
//fbTest = gfx_create_framebuffer(256, 512);
}
GameState_SetFrameBuffer(gfxCtx);
gameState->main(gameState);
func_800C4344(gameState);
if (SREG(63) == 1u) {
if (SREG(48) < 0) {
SREG(48) = 0;
gfxCtx->viMode = &gViConfigMode;
gfxCtx->viFeatures = gViConfigFeatures;
gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale;
} else if (SREG(48) > 0) {
ViMode_Update(&sViMode, gameState->input);
gfxCtx->viMode = &sViMode.customViMode;
gfxCtx->viFeatures = sViMode.viFeatures;
gfxCtx->xScale = 1.0f;
gfxCtx->yScale = 1.0f;
}
} else if (SREG(63) >= 2) {
gfxCtx->viMode = &gViConfigMode;
gfxCtx->viFeatures = gViConfigFeatures;
gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale;
if (SREG(63) == 6 || (SREG(63) == 2u && osTvType == OS_TV_NTSC)) {
gfxCtx->viMode = &osViModeNtscLan1;
gfxCtx->yScale = 1.0f;
}
if (SREG(63) == 5 || (SREG(63) == 2u && osTvType == OS_TV_MPAL)) {
gfxCtx->viMode = &osViModeMpalLan1;
gfxCtx->yScale = 1.0f;
}
if (SREG(63) == 4 || (SREG(63) == 2u && osTvType == OS_TV_PAL)) {
gfxCtx->viMode = &osViModePalLan1;
gfxCtx->yScale = 1.0f;
}
if (SREG(63) == 3 || (SREG(63) == 2u && osTvType == OS_TV_PAL)) {
gfxCtx->viMode = &osViModeFpalLan1;
gfxCtx->yScale = 0.833f;
}
} else {
gfxCtx->viMode = NULL;
}
if (HREG(80) == 0x15) {
if (HREG(95) != 0x15) {
HREG(95) = 0x15;
HREG(81) = 0;
HREG(82) = gViConfigAdditionalScanLines;
HREG(83) = 0;
HREG(84) = 0;
}
if (HREG(82) < 0) {
HREG(82) = 0;
}
if (HREG(82) > 0x30) {
HREG(82) = 0x30;
}
if ((HREG(83) != HREG(82)) || HREG(84) != HREG(81)) {
HREG(83) = HREG(82);
HREG(84) = HREG(81);
gViConfigAdditionalScanLines = HREG(82);
gViConfigYScale = HREG(81) == 0 ? 240.0f / (gViConfigAdditionalScanLines + 240.0f) : 1.0f;
D_80009430 = 1;
}
}
if (R_PAUSE_MENU_MODE != 2u) {
GameState_Draw(gameState, gfxCtx);
func_800C49F4(gfxCtx);
}
gameState->frames++;
}
void GameState_InitArena(GameState* gameState, size_t size) {
void* arena;
osSyncPrintf("ハイラル確保 サイズ=%u バイト\n"); // "Hyrule reserved size = %u bytes"
arena = GameAlloc_MallocDebug(&gameState->alloc, size, "../game.c", 992);
if (arena != NULL) {
THA_Ct(&gameState->tha, arena, size);
osSyncPrintf("ハイラル確保成功\n"); // "Successful Hyral"
} else {
THA_Ct(&gameState->tha, NULL, 0);
osSyncPrintf("ハイラル確保失敗\n"); // "Failure to secure Hyrule"
Fault_AddHungupAndCrash("../game.c", 999);
}
}
void GameState_Realloc(GameState* gameState, size_t size) {
GameAlloc* alloc = &gameState->alloc;
void* gameArena;
u32 systemMaxFree;
u32 systemFree;
u32 systemAlloc;
void* thaBufp = gameState->tha.bufp;
THA_Dt(&gameState->tha);
GameAlloc_Free(alloc, thaBufp);
osSyncPrintf("ハイラル一時解放!!\n"); // "Hyrule temporarily released!!"
SystemArena_GetSizes(&systemMaxFree, &systemFree, &systemAlloc);
if ((systemMaxFree - 0x10) < size) {
osSyncPrintf("%c", 7);
osSyncPrintf(VT_FGCOL(RED));
// "Not enough memory. Change the hyral size to the largest possible value"
osSyncPrintf("メモリが足りません。ハイラルサイズを可能な最大値に変更します\n");
osSyncPrintf("(hyral=%08x max=%08x free=%08x alloc=%08x)\n", size, systemMaxFree, systemFree, systemAlloc);
osSyncPrintf(VT_RST);
size = systemMaxFree - 0x10;
}
osSyncPrintf("ハイラル再確保 サイズ=%u バイト\n", size); // "Hyral reallocate size = %u bytes"
gameArena = GameAlloc_MallocDebug(alloc, size, "../game.c", 1033);
if (gameArena != NULL) {
THA_Ct(&gameState->tha, gameArena, size);
osSyncPrintf("ハイラル再確保成功\n"); // "Successful reacquisition of Hyrule"
} else {
THA_Ct(&gameState->tha, NULL, 0);
osSyncPrintf("ハイラル再確保失敗\n"); // "Failure to secure Hyral"
SystemArena_Display();
Fault_AddHungupAndCrash("../game.c", 1044);
}
}
void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* gfxCtx) {
OSTime startTime;
OSTime endTime;
osSyncPrintf("game コンストラクタ開始\n"); // "game constructor start"
gameState->gfxCtx = gfxCtx;
gameState->frames = 0;
gameState->main = NULL;
gameState->destroy = NULL;
gameState->running = 1;
startTime = osGetTime();
gameState->size = 0;
gameState->init = NULL;
endTime = osGetTime();
// "game_set_next_game_null processing time %d us"
osSyncPrintf("game_set_next_game_null 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
startTime = endTime;
GameAlloc_Init(&gameState->alloc);
endTime = osGetTime();
// "gamealloc_init processing time %d us"
osSyncPrintf("gamealloc_init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
startTime = endTime;
GameState_InitArena(gameState, 0x100000);
R_UPDATE_RATE = 3;
init(gameState);
endTime = osGetTime();
// "init processing time %d us"
osSyncPrintf("init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
startTime = endTime;
LogUtils_CheckNullPointer("this->cleanup", gameState->destroy, "../game.c", 1088);
func_800ACE70(&D_801664F0);
func_800AD920(&D_80166500);
VisMono_Init(&sMonoColors);
if (SREG(48) == 0) {
ViMode_Init(&sViMode);
}
SpeedMeter_Init(&D_801664D0);
func_800AA0B4();
osSendMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK);
endTime = osGetTime();
// "Other initialization processing time %d us"
osSyncPrintf("その他初期化 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
Fault_AddClient(&sGameFaultClient, GameState_FaultPrint, NULL, NULL);
osSyncPrintf("game コンストラクタ終了\n"); // "game constructor end"
}
void GameState_Destroy(GameState* gameState) {
osSyncPrintf("game デストラクタ開始\n"); // "game destructor start"
func_800C3C20();
func_800F3054();
osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK);
LogUtils_CheckNullPointer("this->cleanup", gameState->destroy, "../game.c", 1139);
if (gameState->destroy != NULL) {
gameState->destroy(gameState);
}
func_800AA0F0();
SpeedMeter_Destroy(&D_801664D0);
func_800ACE90(&D_801664F0);
func_800AD950(&D_80166500);
VisMono_Destroy(&sMonoColors);
if (SREG(48) == 0) {
ViMode_Destroy(&sViMode);
}
THA_Dt(&gameState->tha);
GameAlloc_Cleanup(&gameState->alloc);
SystemArena_Display();
Fault_RemoveClient(&sGameFaultClient);
osSyncPrintf("game デストラクタ終了\n"); // "game destructor end"
}
GameStateFunc GameState_GetInit(GameState* gameState) {
return gameState->init;
}
size_t GameState_GetSize(GameState* gameState) {
return gameState->size;
}
u32 GameState_IsRunning(GameState* gameState) {
return gameState->running;
}
void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line)
{
void* ret;
if (THA_IsCrash(&gameState->tha)) {
osSyncPrintf("ハイラルは滅亡している\n");
ret = NULL;
} else if ((uintptr_t)THA_GetSize(&gameState->tha) < size) {
// "Hyral on the verge of extinction does not have %d bytes left (%d bytes until extinction)"
osSyncPrintf("滅亡寸前のハイラルには %d バイトの余力もない(滅亡まであと %d バイト)\n", size,
THA_GetSize(&gameState->tha));
ret = NULL;
} else {
ret = THA_AllocEndAlign16(&gameState->tha, size);
if (THA_IsCrash(&gameState->tha)) {
osSyncPrintf("ハイラルは滅亡してしまった\n"); // "Hyrule has been destroyed"
ret = NULL;
}
}
if (ret != NULL) {
osSyncPrintf(VT_FGCOL(GREEN));
osSyncPrintf("game_alloc(%08x) %08x-%08x [%s:%d]\n", size, ret, (uintptr_t)ret + size, file, line);
osSyncPrintf(VT_RST);
}
return ret;
}
void* GameState_AllocEndAlign16(GameState* gameState, size_t size) {
return THA_AllocEndAlign16(&gameState->tha, size);
}
s32 GameState_GetArenaSize(GameState* gameState) {
return THA_GetSize(&gameState->tha);
}

80
soh/src/code/gamealloc.c Normal file
View file

@ -0,0 +1,80 @@
#include "global.h"
void GameAlloc_Log(GameAlloc* this) {
GameAllocEntry* iter;
osSyncPrintf("this = %08x\n", this);
iter = this->base.next;
while (iter != &this->base) {
osSyncPrintf("ptr = %08x size = %d\n", iter, iter->size);
iter = iter->next;
}
}
void* GameAlloc_MallocDebug(GameAlloc* this, size_t size, const char* file, s32 line) {
GameAllocEntry* ptr = SystemArena_MallocDebug(size + sizeof(GameAllocEntry), file, line);
if (ptr != NULL) {
ptr->size = size;
ptr->prev = this->head;
this->head->next = ptr;
this->head = ptr;
ptr->next = &this->base;
this->base.prev = this->head;
return ptr + 1;
} else {
return NULL;
}
}
void* GameAlloc_Malloc(GameAlloc* this, size_t size) {
GameAllocEntry* ptr = SystemArena_MallocDebug(size + sizeof(GameAllocEntry), "../gamealloc.c", 93);
if (ptr != NULL) {
ptr->size = size;
ptr->prev = this->head;
this->head->next = ptr;
this->head = ptr;
ptr->next = &this->base;
this->base.prev = this->head;
return ptr + 1;
} else {
return NULL;
}
}
void GameAlloc_Free(GameAlloc* this, void* data) {
GameAllocEntry* ptr;
if (data != NULL) {
ptr = &((GameAllocEntry*)data)[-1];
LogUtils_CheckNullPointer("ptr->prev", ptr->prev, "../gamealloc.c", 120);
LogUtils_CheckNullPointer("ptr->next", ptr->next, "../gamealloc.c", 121);
ptr->prev->next = ptr->next;
ptr->next->prev = ptr->prev;
this->head = this->base.prev;
SystemArena_FreeDebug(ptr, "../gamealloc.c", 125);
}
}
void GameAlloc_Cleanup(GameAlloc* this) {
GameAllocEntry* next = this->base.next;
GameAllocEntry* cur;
while (&this->base != next) {
cur = next;
next = next->next;
SystemArena_FreeDebug(cur, "../gamealloc.c", 145);
}
this->head = &this->base;
this->base.next = &this->base;
this->base.prev = &this->base;
}
void GameAlloc_Init(GameAlloc* this) {
this->head = &this->base;
this->base.next = &this->base;
this->base.prev = &this->base;
}

313
soh/src/code/gfxprint.c Normal file
View file

@ -0,0 +1,313 @@
#include "global.h"
u16 sGfxPrintFontTLUT[64] = {
0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000,
0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000,
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
};
u16 sGfxPrintRainbowTLUT[16] = {
0xF801, 0xFBC1, 0xFFC1, 0x07C1, 0x0421, 0x003F, 0x803F, 0xF83F,
0xF801, 0xFBC1, 0xFFC1, 0x07C1, 0x0421, 0x003F, 0x803F, 0xF83F,
};
u8 sGfxPrintRainbowData[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
u8 sGfxPrintFontData[(16 * 256) / 2] = {
0x00, 0xDF, 0xFD, 0x00, 0x0A, 0xEE, 0xFF, 0xA0, 0x0D, 0xF2, 0x2D, 0xD0, 0x06, 0x61, 0x1D, 0xC0, 0x01, 0x12, 0x2D,
0xD0, 0x06, 0x71, 0x99, 0x00, 0x01, 0x1E, 0xED, 0x10, 0x07, 0x7E, 0xF7, 0x00, 0x01, 0x56, 0x29, 0x90, 0x05, 0x58,
0x97, 0x60, 0x0D, 0xD2, 0x29, 0x90, 0x05, 0x59, 0x97, 0x70, 0x04, 0xDF, 0xFD, 0x40, 0x02, 0x6E, 0xF7, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xBF, 0xFB, 0x00, 0x0E, 0xFF, 0xFF, 0xC0, 0x0B, 0xF0, 0x0F, 0xB0,
0x0F, 0xF0, 0x03, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x02, 0x20, 0x0C, 0xFB, 0xBF, 0x60, 0x0F, 0xFC, 0xCE,
0x20, 0x0D, 0xD4, 0x4F, 0xF0, 0x0F, 0xF0, 0x02, 0x20, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x03, 0x30, 0x0C, 0xFB,
0xBF, 0x40, 0x0E, 0xF7, 0x77, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFD, 0x00, 0x0A,
0xEE, 0xFF, 0xA0, 0x0D, 0xF2, 0x2D, 0xD0, 0x06, 0x61, 0x1D, 0xC0, 0x01, 0x12, 0x2D, 0xD0, 0x06, 0x71, 0x99, 0x00,
0x01, 0x1E, 0xED, 0x10, 0x07, 0x7E, 0xF7, 0x00, 0x01, 0x56, 0x29, 0x90, 0x05, 0x58, 0x97, 0x60, 0x0D, 0xD2, 0x29,
0x90, 0x05, 0x59, 0x97, 0x70, 0x04, 0xDF, 0xFD, 0x40, 0x02, 0x6E, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0xBF, 0xFB, 0x00, 0x00, 0x0D, 0xE0, 0x00, 0x0B, 0xF0, 0x0F, 0xB0, 0x00, 0x5D, 0xE6, 0x00, 0x0F,
0xF0, 0x0F, 0xF0, 0x05, 0x5C, 0xC6, 0x60, 0x0C, 0xFB, 0xBF, 0x60, 0x77, 0x3F, 0xF3, 0x77, 0x0D, 0xD4, 0x4F, 0xF0,
0xBB, 0x3F, 0xF3, 0xBB, 0x0F, 0xF0, 0x0F, 0xF0, 0x09, 0x9C, 0xCA, 0xA0, 0x0C, 0xFB, 0xBF, 0x40, 0x00, 0x9D, 0xEA,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xE0, 0x00, 0x04, 0xC2, 0x2C, 0x40, 0x02, 0x8D, 0x50, 0x20, 0x0C, 0xCA,
0xAC, 0xC0, 0x21, 0xF9, 0x17, 0x10, 0x04, 0xC2, 0x2C, 0x40, 0x12, 0x49, 0x34, 0x00, 0x00, 0x82, 0x08, 0x00, 0x01,
0x97, 0x51, 0x10, 0x08, 0x8A, 0x88, 0x80, 0x04, 0x61, 0x52, 0x41, 0x00, 0x80, 0x08, 0x00, 0x43, 0x11, 0x75, 0x30,
0x00, 0xA2, 0x08, 0x00, 0x60, 0x05, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x40, 0x00, 0x22, 0x11,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0F, 0xB0, 0x00, 0x00, 0x00, 0x08, 0x80, 0x04, 0x0D, 0xA4, 0x00, 0x00, 0x00,
0x88, 0x00, 0x08, 0xCD, 0xE8, 0x80, 0x02, 0x2A, 0xA2, 0x20, 0x08, 0xCD, 0xE8, 0x80, 0x02, 0xAA, 0x22, 0x20, 0x04,
0x0D, 0xA4, 0x00, 0x0C, 0xD1, 0x00, 0x00, 0x00, 0x0F, 0xB0, 0x00, 0x8C, 0x51, 0x00, 0x00, 0x00, 0x22, 0x11, 0x00,
0x81, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFD, 0x00, 0x0A, 0xEE, 0xFF, 0xA0, 0x0D, 0xF2, 0x2D, 0xD0, 0x06, 0x61, 0x1D,
0xC0, 0x01, 0x12, 0x2D, 0xD0, 0x06, 0x71, 0x99, 0x00, 0x01, 0x1E, 0xED, 0x10, 0x07, 0x7E, 0xF7, 0x00, 0x01, 0x56,
0x29, 0x90, 0x05, 0x58, 0x97, 0x60, 0x0D, 0xD2, 0x29, 0x90, 0x05, 0x59, 0x97, 0x70, 0x04, 0xDF, 0xFD, 0x40, 0x02,
0x6E, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x00, 0x04, 0x48, 0x99, 0x80,
0x03, 0x3C, 0xC3, 0x30, 0x00, 0xCD, 0x10, 0x88, 0x03, 0x3C, 0xC3, 0x30, 0x02, 0xBF, 0x62, 0xA8, 0x00, 0x33, 0x33,
0x20, 0x01, 0x10, 0x4C, 0x80, 0x01, 0x10, 0x03, 0x30, 0x00, 0x15, 0xC8, 0x00, 0x03, 0x3C, 0xC3, 0x30, 0x02, 0x67,
0x32, 0x20, 0x00, 0x3F, 0xF3, 0x00, 0x04, 0x40, 0x99, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0xDF, 0xFD, 0x10, 0x07, 0xFF, 0xFF, 0x60, 0x1C, 0xE0, 0x0E, 0xC1, 0x0F, 0xF0, 0x09, 0x90, 0x1E, 0xE1, 0x16, 0x61,
0x0F, 0xF0, 0x01, 0x10, 0x1E, 0xF4, 0x56, 0x21, 0x0F, 0xF6, 0x67, 0x10, 0x1E, 0xF2, 0x36, 0x61, 0x0F, 0xF0, 0x89,
0x90, 0x1E, 0xF1, 0x0F, 0xE1, 0x0F, 0xF0, 0x09, 0x90, 0x16, 0xEC, 0xCE, 0x21, 0x07, 0xFB, 0xBB, 0x20, 0x01, 0x11,
0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0xB6, 0x6F, 0xD0, 0x27, 0xD8, 0x8E, 0x60, 0x09, 0x92, 0xED, 0x10, 0x2F,
0xF0, 0x2E, 0xE0, 0x09, 0x9A, 0xE5, 0x10, 0x2F, 0xF6, 0x2E, 0xE0, 0x09, 0x9B, 0x75, 0x10, 0x2F, 0xD6, 0x4E, 0xE0,
0x0D, 0xDA, 0xE5, 0x10, 0x2F, 0xD0, 0x4E, 0xE0, 0x0D, 0xD2, 0xED, 0x10, 0x2F, 0xD0, 0x0E, 0xE0, 0x09, 0xF6, 0x6F,
0x90, 0x27, 0xD9, 0x9F, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x8F, 0x71,
0x1F, 0xF0, 0x2F, 0xD0, 0x0F, 0xF0, 0x8F, 0x71, 0x1F, 0xF0, 0x2F, 0xD0, 0x07, 0x70, 0x8E, 0x61, 0x1E, 0xE0, 0x27,
0xDD, 0xDF, 0x60, 0x8E, 0x69, 0x1E, 0xE0, 0x27, 0x76, 0x4A, 0xA0, 0x8E, 0xE9, 0x9E, 0xE0, 0x2F, 0xD0, 0x6E, 0x80,
0x8A, 0xE7, 0xFE, 0xA0, 0x07, 0xFA, 0x8E, 0x60, 0x88, 0x27, 0x7A, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x7C, 0xCF, 0xF0, 0x13, 0x26, 0x60, 0x11, 0x07, 0x7C, 0xCF, 0xF0, 0x03, 0x76, 0x65, 0x10, 0x02, 0x39,
0xD7, 0x20, 0x04, 0x53, 0x35, 0x40, 0x00, 0x2F, 0xF2, 0x00, 0x01, 0x13, 0x31, 0x10, 0x00, 0x5F, 0xB1, 0x00, 0x00,
0x03, 0x30, 0x00, 0x05, 0x5E, 0xE5, 0x50, 0x01, 0x13, 0x31, 0x10, 0x05, 0x5E, 0xED, 0xD0, 0x02, 0x23, 0x30, 0x00,
0x00, 0x08, 0x88, 0x80, 0x8A, 0xAB, 0xB8, 0x88, 0x00, 0x00, 0x11, 0x00, 0x00, 0x04, 0x45, 0x10, 0x04, 0x62, 0x33,
0x20, 0x00, 0x44, 0x01, 0x10, 0x04, 0xC8, 0x9A, 0xA0, 0x00, 0xEE, 0xAB, 0x10, 0x0C, 0xE6, 0x67, 0x20, 0x0E, 0xF5,
0x5F, 0xB0, 0x0E, 0xE0, 0x06, 0x60, 0x0B, 0xF6, 0x2B, 0x90, 0x0E, 0xE0, 0x06, 0x60, 0x03, 0xFC, 0x89, 0x90, 0x04,
0xEE, 0xEE, 0xA0, 0x00, 0x77, 0x3B, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x88, 0x00, 0x09, 0x90, 0x00, 0x00,
0x00, 0x11, 0x10, 0x00, 0x09, 0x92, 0x24, 0x40, 0x00, 0x01, 0x10, 0x00, 0x09, 0x90, 0x88, 0x00, 0x26, 0xEF, 0xDE,
0x20, 0x09, 0x9B, 0xB5, 0x40, 0x2E, 0xC3, 0x3C, 0xE2, 0x0D, 0x9A, 0x25, 0x50, 0x2E, 0xC3, 0x3C, 0xE2, 0x0D, 0xDA,
0xA5, 0x50, 0x2E, 0xC3, 0x3C, 0xE2, 0x09, 0xD6, 0xED, 0x10, 0x26, 0xCB, 0xBC, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00,
0x05, 0xFB, 0xFF, 0xE0, 0x8E, 0x61, 0x16, 0xE8, 0x0F, 0xF4, 0x03, 0x30, 0x8F, 0x71, 0x17, 0xF8, 0x07, 0xFC, 0x8B,
0x30, 0x8E, 0x69, 0x96, 0xE8, 0x05, 0x73, 0x3B, 0xA0, 0x8A, 0x6D, 0xD6, 0xA8, 0x0D, 0xD8, 0x8A, 0x20, 0x08, 0xA7,
0x79, 0xB2, 0x01, 0x10, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8A, 0x01, 0x10, 0x00, 0x00,
0x00, 0x08, 0x00, 0x80, 0xA1, 0x10, 0x00, 0x07, 0x74, 0x4F, 0x70, 0x80, 0xA9, 0x90, 0x00, 0x02, 0x31, 0xDF, 0x20,
0x84, 0xE6, 0x00, 0x04, 0x00, 0x27, 0xDA, 0x20, 0xC8, 0xAA, 0x4C, 0x40, 0x00, 0x57, 0x3B, 0x20, 0x00, 0xA1, 0x18,
0x00, 0x05, 0x54, 0x6F, 0x50, 0x00, 0xA9, 0x98, 0x00, 0x02, 0x22, 0x20, 0x80, 0x02, 0x00, 0x18, 0x88, 0x00, 0x04,
0x44, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x44, 0x40, 0x0C, 0x44, 0x44, 0x00, 0x00, 0x04, 0x40, 0x00, 0x88,
0xC0, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x0C, 0x46, 0xA4, 0x40, 0x00, 0x0C, 0xC0, 0x00, 0x08, 0x8E, 0xE0, 0x00,
0x02, 0x08, 0x80, 0x00, 0x80, 0xD0, 0x88, 0x00, 0x28, 0xA8, 0x80, 0x00, 0x88, 0xCD, 0x4C, 0x40, 0x0A, 0x88, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE0, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x88, 0x00, 0x80, 0x01, 0x06, 0x10, 0x00, 0x56, 0xE7, 0x50, 0x80, 0x02, 0x1F, 0xF1, 0x00, 0x38,
0x8C, 0xB8, 0x00, 0x0B, 0xF6, 0x0B, 0x00, 0x94, 0xC0, 0x28, 0x00, 0x06, 0x07, 0x6A, 0x00, 0xCB, 0xA6, 0xC8, 0x00,
0x00, 0x47, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x39, 0x14,
0x20, 0x02, 0x22, 0x24, 0x00, 0x08, 0xAE, 0xA8, 0x60, 0x04, 0x28, 0x99, 0x70, 0x07, 0x75, 0xD1, 0x04, 0x0F, 0xB3,
0x33, 0xD0, 0x00, 0xAE, 0xBE, 0xA4, 0x25, 0x15, 0x20, 0xA0, 0x02, 0x61, 0x0C, 0x02, 0x20, 0x42, 0x08, 0x20, 0x2C,
0x30, 0x14, 0x02, 0x02, 0x28, 0x82, 0x00, 0x03, 0xAC, 0xC1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x12, 0x00, 0x08, 0x00, 0x28, 0x00, 0x0A, 0xCF, 0xEE, 0x20, 0x0B, 0x62, 0x2E, 0x20, 0x02, 0x10, 0x82,
0x40, 0x01, 0x44, 0xE4, 0x40, 0x03, 0x00, 0x0E, 0x00, 0x8D, 0xEA, 0xAC, 0x00, 0x02, 0x10, 0x0A, 0x00, 0x01, 0xE0,
0x24, 0x00, 0x0C, 0x21, 0x02, 0x00, 0x09, 0x42, 0x21, 0x00, 0x00, 0xCC, 0xF4, 0x40, 0x02, 0xBF, 0xD4, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x0C, 0xCC, 0xC4, 0x40, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x02, 0xA0,
0x40, 0x00, 0x0C, 0xC0, 0x00, 0x04, 0xCE, 0x64, 0x40, 0x02, 0x08, 0x80, 0x00, 0x00, 0x90, 0x00, 0x40, 0x28, 0xA8,
0x80, 0x00, 0x08, 0x01, 0x04, 0x00, 0x0A, 0x88, 0x80, 0x00, 0x04, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x54, 0x44, 0x00,
0xEE, 0xFE, 0xE0, 0x00, 0x09, 0x3B, 0x3F, 0x00, 0x21, 0xD8, 0x20, 0x00, 0x00, 0x54, 0x4F, 0x00, 0x18, 0x58, 0x20,
0x00, 0x00, 0x01, 0x86, 0x00, 0xC6, 0x7E, 0x40, 0x00, 0x00, 0xEF, 0x66, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0xC0, 0x20, 0x00, 0xAA, 0xAA, 0xEA, 0x20, 0xEF, 0xFF, 0xFF, 0x00, 0x80,
0x44, 0x19, 0x30, 0x00, 0x49, 0x24, 0x00, 0xC5, 0x35, 0x1B, 0x10, 0x00, 0x4B, 0x24, 0x00, 0x01, 0x35, 0xA0, 0x00,
0x8C, 0xA9, 0xAC, 0x80, 0x00, 0x2C, 0x00, 0x00, 0x04, 0x21, 0xA4, 0x00, 0x2A, 0x84, 0x00, 0x00, 0x73, 0x11, 0xF1,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x11, 0x19, 0x00, 0x00, 0x40, 0x00, 0x00, 0x8F, 0xEE,
0xEF, 0xE0, 0x0B, 0x76, 0x66, 0xD0, 0x1A, 0x00, 0x0B, 0x40, 0x4C, 0x40, 0x02, 0xD0, 0x28, 0x00, 0x1A, 0x40, 0x01,
0xD0, 0x2C, 0x10, 0x00, 0x00, 0x38, 0x40, 0x00, 0x40, 0x28, 0x10, 0x00, 0x01, 0xA0, 0x40, 0x00, 0x42, 0x83, 0x00,
0x05, 0xFE, 0x44, 0x40, 0x03, 0xFD, 0x54, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x99, 0x9B,
0x00, 0x00, 0x10, 0x20, 0x00, 0x07, 0x26, 0x21, 0x40, 0x2A, 0xFE, 0xEE, 0xA0, 0x8D, 0x8C, 0xA9, 0xC0, 0x00, 0x10,
0x20, 0x80, 0x32, 0x33, 0xB3, 0x60, 0x00, 0x19, 0x28, 0x00, 0x00, 0x00, 0xA1, 0x40, 0x00, 0x10, 0xB1, 0x00, 0x00,
0x08, 0x34, 0x00, 0x00, 0x1A, 0x08, 0x00, 0x05, 0xF7, 0x40, 0x00, 0x8E, 0xF4, 0x44, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x02, 0x80, 0x00, 0x04, 0x00, 0x00, 0x1D, 0x11, 0xDB, 0x00, 0xDD, 0xFD, 0xDD,
0xD0, 0x0C, 0x88, 0x07, 0x00, 0x02, 0x06, 0x00, 0x90, 0x48, 0x00, 0x34, 0x00, 0x2C, 0x04, 0x2C, 0x10, 0x48, 0x11,
0x21, 0x40, 0x04, 0x84, 0x83, 0x40, 0x59, 0x03, 0x00, 0x50, 0x40, 0x0C, 0x10, 0x60, 0x42, 0xA9, 0x88, 0xC0, 0x40,
0x15, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x40, 0x08, 0x98, 0x88, 0x80,
0x08, 0xF9, 0x98, 0xC0, 0x06, 0x77, 0x75, 0x50, 0x02, 0x0C, 0x05, 0x00, 0x19, 0x98, 0xA8, 0xD0, 0x0B, 0x99, 0xCA,
0x80, 0x04, 0x54, 0x65, 0xC0, 0x20, 0x08, 0x50, 0x20, 0x00, 0x10, 0x20, 0xC0, 0x31, 0x1C, 0x04, 0x20, 0x00, 0x01,
0x28, 0x40, 0x26, 0x63, 0xBB, 0xE0, 0x26, 0xEF, 0xE6, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x02, 0x01, 0x00, 0xC8, 0xC0, 0x00, 0x00, 0x0F, 0x8A, 0x89, 0x80, 0xC3, 0xF3, 0x11, 0x30, 0x0F, 0x02, 0x01, 0x80,
0xC9, 0xC0, 0x00, 0x30, 0x0F, 0x02, 0x05, 0xA0, 0x00, 0x00, 0x00, 0x30, 0x0E, 0x02, 0x05, 0xA0, 0x00, 0x00, 0x00,
0x30, 0x0E, 0x02, 0x52, 0x80, 0x00, 0x00, 0x03, 0x00, 0x2C, 0xDF, 0xA8, 0x80, 0x02, 0x33, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x00, 0x01, 0x02, 0x80, 0x00, 0x03, 0xFF, 0xF7, 0x00, 0x0F,
0x26, 0xE4, 0x72, 0xCC, 0x38, 0x00, 0x40, 0x0C, 0x38, 0x99, 0x00, 0x03, 0x0A, 0x31, 0x50, 0x0C, 0xB1, 0x82, 0x80,
0x03, 0x28, 0x06, 0x00, 0x87, 0x88, 0x2A, 0xA0, 0x01, 0x05, 0xC2, 0x00, 0x85, 0x82, 0xC2, 0x80, 0x10, 0x00, 0x39,
0x10, 0x08, 0x51, 0xBF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x48, 0x9D,
0xCC, 0x40, 0xC9, 0xE6, 0x7F, 0x40, 0x40, 0x00, 0x94, 0x00, 0x5B, 0x21, 0x0C, 0xB0, 0x48, 0xAE, 0xCC, 0x40, 0xE1,
0x30, 0x0C, 0x30, 0x43, 0x01, 0xA4, 0x00, 0xE1, 0x24, 0x5D, 0x30, 0x78, 0x8C, 0xD6, 0x10, 0xF1, 0x60, 0x94, 0x70,
0xD0, 0x40, 0x9C, 0x70, 0x0B, 0x8C, 0x53, 0x00, 0x0C, 0x9D, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x39, 0x50, 0x00, 0x00, 0x88, 0xF0, 0x00, 0x2E, 0xAF, 0xC6, 0x00, 0x03, 0x01, 0x77, 0x60, 0x04, 0xF0,
0x41, 0x60, 0x03, 0x92, 0xF8, 0x12, 0x0F, 0xBD, 0x91, 0x40, 0x1B, 0x28, 0x60, 0x92, 0x70, 0xF4, 0x01, 0xF0, 0x0A,
0xD4, 0x65, 0x82, 0x53, 0xE0, 0x01, 0xE0, 0x04, 0x10, 0x68, 0x60, 0x04, 0x2A, 0xBE, 0x00, 0x00, 0x4F, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3A, 0xEE, 0x00, 0xC8, 0xC0, 0x00, 0x00, 0x0D, 0x84, 0xA5,
0x00, 0xC1, 0xC2, 0x11, 0x00, 0x45, 0x0E, 0x27, 0x00, 0xD9, 0xC3, 0x00, 0x10, 0x07, 0xF8, 0x8D, 0x20, 0x01, 0x30,
0x00, 0x10, 0xAC, 0x02, 0x25, 0xA0, 0x01, 0x22, 0x00, 0x10, 0x44, 0x20, 0x16, 0xA0, 0x13, 0x02, 0x00, 0x30, 0x04,
0x1B, 0xAA, 0x40, 0x21, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// Can be used to set GFXP_FLAG_ENLARGE by default
static u8 sDefaultSpecialFlags;
void GfxPrint_Setup(GfxPrint* this) {
s32 width = 16;
s32 height = 256;
s32 i;
gDPPipeSync(this->dList++);
gDPSetOtherMode(this->dList++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_IA16 | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_XLU_SURF | G_RM_XLU_SURF2);
gDPSetCombineMode(this->dList++, G_CC_DECALRGBA, G_CC_DECALRGBA);
gDPLoadTextureBlock_4b(this->dList++, sGfxPrintFontData, G_IM_FMT_CI, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPLoadTLUT(this->dList++, 64, 256, sGfxPrintFontTLUT);
for (i = 1; i < 4; i++) {
gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2, i, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD);
gDPSetTileSize(this->dList++, i * 2, 0, 0, 60, 1020);
}
gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba);
/*gDPLoadMultiTile_4b(this->dList++, sGfxPrintRainbowData, 0, 1, G_IM_FMT_CI, 2, 8, 0, 0, 1, 7, 4,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 1, 3, G_TX_NOLOD, G_TX_NOLOD);
gDPLoadTLUT(this->dList++, 16, 320, sGfxPrintRainbowTLUT);
for (i = 1; i < 4; i++) {
gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2 + 1, 4, G_TX_NOMIRROR | G_TX_WRAP, 3,
G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 1, G_TX_NOLOD);
gDPSetTileSize(this->dList++, i * 2 + 1, 0, 0, 4, 28);
}*/
}
void GfxPrint_SetColor(GfxPrint* this, u32 r, u32 g, u32 b, u32 a) {
this->color.r = r;
this->color.g = g;
this->color.b = b;
this->color.a = a;
gDPPipeSync(this->dList++);
gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba);
}
void GfxPrint_SetPosPx(GfxPrint* this, s32 x, s32 y) {
this->posX = this->baseX + (x * 4);
this->posY = this->baseY + (y * 4);
}
void GfxPrint_SetPos(GfxPrint* this, s32 x, s32 y) {
GfxPrint_SetPosPx(this, x * 8, y * 8);
}
void GfxPrint_SetBasePosPx(GfxPrint* this, s32 x, s32 y) {
this->baseX = x * 4;
this->baseY = y * 4;
}
void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c) {
u32 tile = (c & 0xFF) * 2;
if (this->flags & GFXP_FLAG_UPDATE) {
this->flags &= ~GFXP_FLAG_UPDATE;
gDPPipeSync(this->dList++);
if (this->flags & GFXP_FLAG_RAINBOW) {
gDPSetTextureLUT(this->dList++, G_TT_RGBA16);
gDPSetCycleType(this->dList++, G_CYC_2CYCLE);
gDPSetRenderMode(this->dList++, G_RM_OPA_CI, G_RM_XLU_SURF2);
gDPSetCombineMode(this->dList++, G_CC_INTERFERENCE, G_CC_PASS2);
} else {
gDPSetTextureLUT(this->dList++, G_TT_IA16);
gDPSetCycleType(this->dList++, G_CYC_1CYCLE);
gDPSetRenderMode(this->dList++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
gDPSetCombineMode(this->dList++, G_CC_MODULATEIDECALA_PRIM, G_CC_MODULATEIDECALA_PRIM);
}
}
if (this->flags & GFXP_FLAG_SHADOW) {
gDPSetColor(this->dList++, G_SETPRIMCOLOR, 0);
if (this->flags & GFXP_FLAG_ENLARGE) {
gSPTextureRectangle(this->dList++, (this->posX + 4) << 1, (this->posY + 4) << 1, (this->posX + 4 + 32) << 1,
(this->posY + 4 + 32) << 1, tile, (u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 9,
1 << 9);
} else {
gSPTextureRectangle(this->dList++, this->posX + 4, this->posY + 4, this->posX + 4 + 32, this->posY + 4 + 32,
tile, (u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 10, 1 << 10);
}
gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba);
}
if (this->flags & GFXP_FLAG_ENLARGE) {
gSPTextureRectangle(this->dList++, (this->posX) << 1, (this->posY) << 1, (this->posX + 32) << 1,
(this->posY + 32) << 1, tile, (u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 9, 1 << 9);
} else {
gSPTextureRectangle(this->dList++, this->posX, this->posY, this->posX + 32, this->posY + 32, tile,
(u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 10, 1 << 10);
}
this->posX += 32;
}
void GfxPrint_PrintStringWithSize(GfxPrint* this, const void* buffer, u32 charSize, u32 charCount) {
OTRGfxPrint((const char*)buffer, this, GfxPrint_PrintCharImpl);
}
void GfxPrint_PrintString(GfxPrint* this, const char* str) {
OTRGfxPrint(str, this, GfxPrint_PrintCharImpl);
}
void* GfxPrint_Callback(void* arg, const char* str, size_t size) {
GfxPrint* this = arg;
GfxPrint_PrintStringWithSize(this, str, sizeof(char), size);
return this;
}
void GfxPrint_Init(GfxPrint* this) {
this->flags &= ~GFXP_FLAG_OPEN;
this->callback = GfxPrint_Callback;
this->dList = NULL;
this->posX = 0;
this->posY = 0;
this->baseX = 0;
this->baseY = 0;
this->color.rgba = 0;
this->flags &= ~GFXP_FLAG_HIRAGANA;
this->flags &= ~GFXP_FLAG_RAINBOW;
this->flags |= GFXP_FLAG_SHADOW;
this->flags |= GFXP_FLAG_UPDATE;
if (sDefaultSpecialFlags & GFXP_FLAG_ENLARGE) {
this->flags |= GFXP_FLAG_ENLARGE;
} else {
this->flags &= ~GFXP_FLAG_ENLARGE;
}
}
void GfxPrint_Destroy(GfxPrint* this) {
}
void GfxPrint_Open(GfxPrint* this, Gfx* dList) {
if (!(this->flags & GFXP_FLAG_OPEN)) {
this->flags |= GFXP_FLAG_OPEN;
this->dList = dList;
GfxPrint_Setup(this);
} else {
osSyncPrintf("gfxprint_open:2重オープンです\n");
}
}
Gfx* GfxPrint_Close(GfxPrint* this) {
Gfx* ret;
this->flags &= ~GFXP_FLAG_OPEN;
gDPPipeSync(this->dList++);
ret = this->dList;
this->dList = NULL;
return ret;
}
s32 GfxPrint_VPrintf(GfxPrint* this, const char* fmt, va_list args) {
return PrintUtils_VPrintf(&this->callback, fmt, args);
}
s32 GfxPrint_Printf(GfxPrint* this, const char* fmt, ...) {
s32 ret;
va_list args;
va_start(args, fmt);
ret = GfxPrint_VPrintf(this, fmt, args);
va_end(args);
return ret;
}

610
soh/src/code/graph.c Normal file
View file

@ -0,0 +1,610 @@
#include "global.h"
#include "vt.h"
#include "regs.h"
#include <string.h>
#include "soh/Enhancements/gameconsole.h"
#define GFXPOOL_HEAD_MAGIC 0x1234
#define GFXPOOL_TAIL_MAGIC 0x5678
OSTime sGraphUpdateTime;
OSTime sGraphSetTaskTime;
FaultClient sGraphFaultClient;
CfbInfo sGraphCfbInfos[3];
FaultClient sGraphUcodeFaultClient;
// clang-format off
UCodeInfo D_8012D230[3] = {
//{ UCODE_F3DZEX, D_80155F50 },
{ UCODE_UNK, NULL },
//{ UCODE_S2DEX, D_80113070 },
};
UCodeInfo D_8012D248[3] = {
//{ UCODE_F3DZEX, D_80155F50 },
{ UCODE_UNK, NULL },
//{ UCODE_S2DEX, D_80113070 },
};
// clang-format on
void Graph_FaultClient() {
void* nextFb = osViGetNextFramebuffer();
void* newFb = ((uintptr_t)SysCfb_GetFbPtr(0) != (uintptr_t)nextFb) ? SysCfb_GetFbPtr(0) : SysCfb_GetFbPtr(1);
osViSwapBuffer(newFb);
Fault_WaitForInput();
osViSwapBuffer(nextFb);
}
void Graph_DisassembleUCode(Gfx* workBuf) {
#if 0
UCodeDisas disassembler;
if (HREG(80) == 7 && HREG(81) != 0) {
UCodeDisas_Init(&disassembler);
disassembler.enableLog = HREG(83);
UCodeDisas_RegisterUCode(&disassembler, ARRAY_COUNT(D_8012D230), D_8012D230);
//UCodeDisas_SetCurUCode(&disassembler, D_80155F50);
UCodeDisas_Disassemble(&disassembler, workBuf);
HREG(93) = disassembler.dlCnt;
HREG(84) = disassembler.tri2Cnt * 2 + disassembler.tri1Cnt + (disassembler.quadCnt * 2) + disassembler.lineCnt;
HREG(85) = disassembler.vtxCnt;
HREG(86) = disassembler.spvtxCnt;
HREG(87) = disassembler.tri1Cnt;
HREG(88) = disassembler.tri2Cnt;
HREG(89) = disassembler.quadCnt;
HREG(90) = disassembler.lineCnt;
HREG(91) = disassembler.syncErr;
HREG(92) = disassembler.loaducodeCnt;
if (HREG(82) == 1 || HREG(82) == 2) {
osSyncPrintf("vtx_cnt=%d\n", disassembler.vtxCnt);
osSyncPrintf("spvtx_cnt=%d\n", disassembler.spvtxCnt);
osSyncPrintf("tri1_cnt=%d\n", disassembler.tri1Cnt);
osSyncPrintf("tri2_cnt=%d\n", disassembler.tri2Cnt);
osSyncPrintf("quad_cnt=%d\n", disassembler.quadCnt);
osSyncPrintf("line_cnt=%d\n", disassembler.lineCnt);
osSyncPrintf("sync_err=%d\n", disassembler.syncErr);
osSyncPrintf("loaducode_cnt=%d\n", disassembler.loaducodeCnt);
osSyncPrintf("dl_depth=%d\n", disassembler.dlDepth);
osSyncPrintf("dl_cnt=%d\n", disassembler.dlCnt);
}
UCodeDisas_Destroy(&disassembler);
}
#endif
}
void Graph_UCodeFaultClient(Gfx* workBuf) {
#if 0
UCodeDisas disassembler;
UCodeDisas_Init(&disassembler);
disassembler.enableLog = true;
UCodeDisas_RegisterUCode(&disassembler, ARRAY_COUNT(D_8012D248), D_8012D248);
//UCodeDisas_SetCurUCode(&disassembler, D_80155F50);
UCodeDisas_Disassemble(&disassembler, workBuf);
UCodeDisas_Destroy(&disassembler);
#endif
}
void Graph_InitTHGA(GraphicsContext* gfxCtx) {
GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx & 1];
pool->headMagic = GFXPOOL_HEAD_MAGIC;
pool->tailMagic = GFXPOOL_TAIL_MAGIC;
THGA_Ct(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer));
THGA_Ct(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer));
THGA_Ct(&gfxCtx->polyKal, pool->polyKalBuffer, sizeof(pool->polyKalBuffer));
THGA_Ct(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer));
THGA_Ct(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer));
gfxCtx->polyOpaBuffer = pool->polyOpaBuffer;
gfxCtx->polyXluBuffer = pool->polyXluBuffer;
gfxCtx->polyKalBuffer = pool->polyKalBuffer;
gfxCtx->overlayBuffer = pool->overlayBuffer;
gfxCtx->workBuffer = pool->workBuffer;
gfxCtx->curFrameBuffer = (u16*)SysCfb_GetFbPtr(gfxCtx->fbIdx % 2);
gfxCtx->unk_014 = 0;
}
GameStateOverlay* Graph_GetNextGameState(GameState* gameState) {
void* gameStateInitFunc = GameState_GetInit(gameState);
if (gameStateInitFunc == TitleSetup_Init) {
return &gGameStateOverlayTable[0];
}
if (gameStateInitFunc == Select_Init) {
return &gGameStateOverlayTable[1];
}
if (gameStateInitFunc == Title_Init) {
return &gGameStateOverlayTable[2];
}
if (gameStateInitFunc == Gameplay_Init) {
return &gGameStateOverlayTable[3];
}
if (gameStateInitFunc == Opening_Init) {
return &gGameStateOverlayTable[4];
}
if (gameStateInitFunc == FileChoose_Init) {
return &gGameStateOverlayTable[5];
}
LOG_ADDRESS("game_init_func", gameStateInitFunc, "../graph.c", 696);
return NULL;
}
void Graph_Init(GraphicsContext* gfxCtx) {
memset(gfxCtx,0, sizeof(GraphicsContext));
gfxCtx->gfxPoolIdx = 0;
gfxCtx->fbIdx = 0;
gfxCtx->viMode = NULL;
gfxCtx->viFeatures = gViConfigFeatures;
gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale;
osCreateMesgQueue(&gfxCtx->queue, gfxCtx->msgBuff, ARRAY_COUNT(gfxCtx->msgBuff));
func_800D31F0();
Fault_AddClient(&sGraphFaultClient, Graph_FaultClient, 0, 0);
}
void Graph_Destroy(GraphicsContext* gfxCtx) {
func_800D3210();
Fault_RemoveClient(&sGraphFaultClient);
}
void Graph_TaskSet00(GraphicsContext* gfxCtx) {
static Gfx* D_8012D260 = NULL;
static s32 sGraphCfbInfoIdx = 0;
OSTime time;
OSTimer timer;
OSMesg msg;
OSTask_t* task = &gfxCtx->task.list.t;
OSScTask* scTask = &gfxCtx->task;
CfbInfo* cfb;
s32 pad1;
D_8016A528 = osGetTime() - sGraphSetTaskTime - D_8016A558;
osSetTimer(&timer, OS_USEC_TO_CYCLES(3000000), 0, &gfxCtx->queue, (OSMesg)666);
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK);
osStopTimer(&timer);
//OTRTODO - Proper GFX crash handler
#if 0
if (msg == (OSMesg)666) {
osSyncPrintf(VT_FGCOL(RED));
osSyncPrintf("RCPが帰ってきませんでした。"); // "RCP did not return."
osSyncPrintf(VT_RST);
LogUtils_LogHexDump((void*)&HW_REG(SP_MEM_ADDR_REG, u32), 0x20);
LogUtils_LogHexDump((void*)&DPC_START_REG, 0x20);
LogUtils_LogHexDump(gGfxSPTaskYieldBuffer, sizeof(gGfxSPTaskYieldBuffer));
SREG(6) = -1;
if (D_8012D260 != NULL) {
HREG(80) = 7;
HREG(81) = 1;
HREG(83) = 2;
D_8012D260 = D_8012D260;
Graph_DisassembleUCode(D_8012D260);
}
Fault_AddHungupAndCrashImpl("RCP is HUNG UP!!", "Oh! MY GOD!!");
}
#endif
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_NOBLOCK);
D_8012D260 = gfxCtx->workBuffer;
if (gfxCtx->callback != NULL) {
gfxCtx->callback(gfxCtx, gfxCtx->callbackParam);
}
time = osGetTime();
if (D_8016A550 != 0) {
D_8016A558 = (D_8016A558 + time) - D_8016A550;
D_8016A550 = time;
}
D_8016A520 = D_8016A558;
D_8016A558 = 0;
sGraphSetTaskTime = osGetTime();
task->type = M_GFXTASK;
task->flags = OS_SC_DRAM_DLIST;
task->ucode_boot = SysUcode_GetUCodeBoot();
task->ucode_boot_size = SysUcode_GetUCodeBootSize();
task->ucode = SysUcode_GetUCode();
task->ucode_data = SysUcode_GetUCodeData();
task->ucode_size = 0x1000;
task->ucode_data_size = 0x800;
task->dram_stack = (u64*)gGfxSPTaskStack;
task->dram_stack_size = sizeof(gGfxSPTaskStack);
task->output_buff = gGfxSPTaskOutputBuffer;
task->output_buff_size = (u64*)((u8*)gGfxSPTaskOutputBuffer + sizeof(gGfxSPTaskOutputBuffer));
task->data_ptr = (u64*)gfxCtx->workBuffer;
OPEN_DISPS(gfxCtx, "../graph.c", 828);
task->data_size = (uintptr_t)WORK_DISP - (uintptr_t)gfxCtx->workBuffer;
CLOSE_DISPS(gfxCtx, "../graph.c", 830);
{ s32 pad2; } // Necessary to match stack usage
task->yield_data_ptr = (u64*)gGfxSPTaskYieldBuffer;
task->yield_data_size = sizeof(gGfxSPTaskYieldBuffer);
scTask->next = NULL;
scTask->flags = OS_SC_RCP_MASK | OS_SC_SWAPBUFFER | OS_SC_LAST_TASK;
if (SREG(33) & 1) {
SREG(33) &= ~1;
scTask->flags &= ~OS_SC_SWAPBUFFER;
gfxCtx->fbIdx--;
}
scTask->msgQ = &gfxCtx->queue;
scTask->msg = NULL;
cfb = &sGraphCfbInfos[sGraphCfbInfoIdx++];
cfb->fb1 = gfxCtx->curFrameBuffer;
cfb->swapBuffer = gfxCtx->curFrameBuffer;
cfb->viMode = gfxCtx->viMode;
cfb->features = gfxCtx->viFeatures;
cfb->xScale = gfxCtx->xScale;
cfb->yScale = gfxCtx->yScale;
cfb->unk_10 = 0;
cfb->updateRate = R_UPDATE_RATE;
scTask->framebuffer = cfb;
sGraphCfbInfoIdx = sGraphCfbInfoIdx % ARRAY_COUNT(sGraphCfbInfos);
if (1) {}
gfxCtx->schedMsgQ = &gSchedContext.cmdQ;
osSendMesg(&gSchedContext.cmdQ, scTask, OS_MESG_BLOCK);
Sched_SendEntryMsg(&gSchedContext);
}
void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
u32 problem;
gameState->unk_A0 = 0;
Graph_InitTHGA(gfxCtx);
OPEN_DISPS(gfxCtx, "../graph.c", 966);
gDPNoOpString(WORK_DISP++, "WORK_DISP 開始", 0);
gDPNoOpString(POLY_OPA_DISP++, "POLY_OPA_DISP 開始", 0);
gDPNoOpString(POLY_XLU_DISP++, "POLY_XLU_DISP 開始", 0);
gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 開始", 0);
CLOSE_DISPS(gfxCtx, "../graph.c", 975);
GameState_ReqPadData(gameState);
GameState_Update(gameState);
OPEN_DISPS(gfxCtx, "../graph.c", 987);
gDPNoOpString(WORK_DISP++, "WORK_DISP 終了", 0);
gDPNoOpString(POLY_OPA_DISP++, "POLY_OPA_DISP 終了", 0);
gDPNoOpString(POLY_XLU_DISP++, "POLY_XLU_DISP 終了", 0);
gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 終了", 0);
CLOSE_DISPS(gfxCtx, "../graph.c", 996);
OPEN_DISPS(gfxCtx, "../graph.c", 999);
gSPBranchList(WORK_DISP++, gfxCtx->polyOpaBuffer);
gSPBranchList(POLY_OPA_DISP++, gfxCtx->polyXluBuffer);
gSPBranchList(POLY_XLU_DISP++, gfxCtx->polyKalBuffer);
gSPBranchList(POLY_KAL_DISP++, gfxCtx->overlayBuffer);
gDPPipeSync(OVERLAY_DISP++);
gDPFullSync(OVERLAY_DISP++);
gSPEndDisplayList(OVERLAY_DISP++);
CLOSE_DISPS(gfxCtx, "../graph.c", 1028);
if (HREG(80) == 10 && HREG(93) == 2) {
HREG(80) = 7;
HREG(81) = -1;
HREG(83) = HREG(92);
}
if (HREG(80) == 7 && HREG(81) != 0) {
if (HREG(82) == 3) {
Fault_AddClient(&sGraphUcodeFaultClient, Graph_UCodeFaultClient, gfxCtx->workBuffer, "do_count_fault");
}
Graph_DisassembleUCode(gfxCtx->workBuffer);
if (HREG(82) == 3) {
Fault_RemoveClient(&sGraphUcodeFaultClient);
}
if (HREG(81) < 0) {
LogUtils_LogHexDump((void*)&HW_REG(SP_MEM_ADDR_REG, u32), 0x20);
LogUtils_LogHexDump((void*)&DPC_START_REG, 0x20);
}
if (HREG(81) < 0) {
HREG(81) = 0;
}
}
problem = false;
{
GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx & 1];
if (pool->headMagic != GFXPOOL_HEAD_MAGIC) {
//! @bug (?) : "problem = true;" may be missing
osSyncPrintf("%c", 7);
// "Dynamic area head is destroyed"
osSyncPrintf(VT_COL(RED, WHITE) "ダイナミック領域先頭が破壊されています\n" VT_RST);
Fault_AddHungupAndCrash("../graph.c", 1070);
}
if (pool->tailMagic != GFXPOOL_TAIL_MAGIC) {
problem = true;
osSyncPrintf("%c", 7);
// "Dynamic region tail is destroyed"
osSyncPrintf(VT_COL(RED, WHITE) "ダイナミック領域末尾が破壊されています\n" VT_RST);
Fault_AddHungupAndCrash("../graph.c", 1076);
}
}
if (THGA_IsCrash(&gfxCtx->polyOpa)) {
problem = true;
osSyncPrintf("%c", 7);
// "Zelda 0 is dead"
osSyncPrintf(VT_COL(RED, WHITE) "ゼルダ0は死んでしまった(graph_alloc is empty)\n" VT_RST);
}
if (THGA_IsCrash(&gfxCtx->polyXlu)) {
problem = true;
osSyncPrintf("%c", 7);
// "Zelda 1 is dead"
osSyncPrintf(VT_COL(RED, WHITE) "ゼルダ1は死んでしまった(graph_alloc is empty)\n" VT_RST);
}
if (THGA_IsCrash(&gfxCtx->overlay)) {
problem = true;
osSyncPrintf("%c", 7);
// "Zelda 4 is dead"
osSyncPrintf(VT_COL(RED, WHITE) "ゼルダ4は死んでしまった(graph_alloc is empty)\n" VT_RST);
}
if (!problem) {
Graph_TaskSet00(gfxCtx);
gfxCtx->gfxPoolIdx++;
gfxCtx->fbIdx++;
}
func_800F3054();
{
OSTime time = osGetTime();
s32 pad[4];
D_8016A538 = gRSPGFXTotalTime;
D_8016A530 = gRSPAudioTotalTime;
D_8016A540 = gRDPTotalTime;
gRSPGFXTotalTime = 0;
gRSPAudioTotalTime = 0;
gRDPTotalTime = 0;
if (sGraphUpdateTime != 0) {
D_8016A548 = time - sGraphUpdateTime;
}
sGraphUpdateTime = time;
}
if (CVar_GetS32("gDebugEnabled", 0))
{
if (CHECK_BTN_ALL(gameState->input[0].press.button, BTN_Z) &&
CHECK_BTN_ALL(gameState->input[0].cur.button, BTN_L | BTN_R)) {
gSaveContext.gameMode = 0;
SET_NEXT_GAMESTATE(gameState, Select_Init, SelectContext);
gameState->running = false;
}
}
if (gIsCtrlr2Valid && PreNmiBuff_IsResetting(gAppNmiBufferPtr) && !gameState->unk_A0) {
// "To reset mode"
osSyncPrintf(VT_COL(YELLOW, BLACK) "PRE-NMIによりリセットモードに移行します\n" VT_RST);
SET_NEXT_GAMESTATE(gameState, PreNMI_Init, PreNMIContext);
gameState->running = false;
}
}
uint64_t GetFrequency();
uint64_t GetPerfCounter();
static struct RunFrameContext {
GraphicsContext gfxCtx;
GameState* gameState;
GameStateOverlay* nextOvl;
GameStateOverlay* ovl;
int state;
} runFrameContext;
extern AudioMgr gAudioMgr;
static void RunFrame()
{
u32 size;
char faultMsg[0x50];
switch (runFrameContext.state) {
case 0:
break;
case 1:
goto nextFrame;
}
runFrameContext.nextOvl = &gGameStateOverlayTable[0];
osSyncPrintf("グラフィックスレッド実行開始\n"); // "Start graphic thread execution"
Graph_Init(&runFrameContext.gfxCtx);
while (runFrameContext.nextOvl)
{
runFrameContext.ovl = runFrameContext.nextOvl;
Overlay_LoadGameState(runFrameContext.ovl);
size = runFrameContext.ovl->instanceSize;
osSyncPrintf("クラスサイズ=%dバイト\n", size); // "Class size = %d bytes"
runFrameContext.gameState = SystemArena_MallocDebug(size, "../graph.c", 1196);
if (!runFrameContext.gameState)
{
osSyncPrintf("確保失敗\n"); // "Failure to secure"
sprintf(faultMsg, "CLASS SIZE= %d bytes", size);
Fault_AddHungupAndCrashImpl("GAME CLASS MALLOC FAILED", faultMsg);
}
GameState_Init(runFrameContext.gameState, runFrameContext.ovl->init, &runFrameContext.gfxCtx);
uint64_t freq = GetFrequency();
while (GameState_IsRunning(runFrameContext.gameState))
{
uint64_t ticksA, ticksB;
ticksA = GetPerfCounter();
OTRSetFrameDivisor(R_UPDATE_RATE);
//OTRSetFrameDivisor(0);
//AudioMgr_ThreadEntry(&gAudioMgr);
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
#define SAMPLES_HIGH 560
#define SAMPLES_LOW 528
// PAL values
//#define SAMPLES_HIGH 656
//#define SAMPLES_LOW 624
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
// printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
// 3 is the maximum authentic frame divisor.
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
//for (uint32_t i = 0; i < 2 * num_audio_samples; i++) {
// audio_buffer[i] = Rand_Next() & 0xFF;
//}
// printf("Audio samples before submitting: %d\n", audio_api->buffered());
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
PadMgr_ThreadEntry(&gPadMgr);
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
ticksB = GetPerfCounter();
Graph_ProcessGfxCommands(runFrameContext.gfxCtx.workBuffer);
//uint64_t diff = (ticksB - ticksA) / (freq / 1000);
//printf("Frame simulated in %ims\n", diff);
runFrameContext.state = 1;
return;
nextFrame:;
}
runFrameContext.nextOvl = Graph_GetNextGameState(runFrameContext.gameState);
GameState_Destroy(runFrameContext.gameState);
SystemArena_FreeDebug(runFrameContext.gameState, "../graph.c", 1227);
Overlay_FreeGameState(runFrameContext.ovl);
}
Graph_Destroy(&runFrameContext.gfxCtx);
osSyncPrintf("グラフィックスレッド実行終了\n"); // "End of graphic thread execution"
//Graph_Update(gfxCtxTest, gameStateTest);
exit(0);
}
void Graph_ThreadEntry(void* arg0) {
Graph_ProcessFrame(RunFrame);
}
void* Graph_Alloc(GraphicsContext* gfxCtx, size_t size) {
TwoHeadGfxArena* thga = &gfxCtx->polyOpa;
if (HREG(59) == 1) {
osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->bufp,
thga->p, thga->d);
}
return THGA_AllocEnd(&gfxCtx->polyOpa, ALIGN16(size));
}
void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size) {
TwoHeadGfxArena* thga = &gfxCtx->polyOpa;
if (HREG(59) == 1) {
osSyncPrintf("graph_alloc siz=%d thga size=%08x bufp=%08x head=%08x tail=%08x\n", size, thga->size, thga->bufp,
thga->p, thga->d);
}
return THGA_AllocEnd(&gfxCtx->polyOpa, ALIGN16(size));
}
void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) {
if (HREG(80) == 7 && HREG(82) != 4) {
dispRefs[0] = gfxCtx->polyOpa.p;
dispRefs[1] = gfxCtx->polyXlu.p;
dispRefs[2] = gfxCtx->overlay.p;
gDPNoOpOpenDisp(gfxCtx->polyOpa.p++, file, line);
gDPNoOpOpenDisp(gfxCtx->polyXlu.p++, file, line);
gDPNoOpOpenDisp(gfxCtx->overlay.p++, file, line);
}
}
void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) {
if (HREG(80) == 7 && HREG(82) != 4) {
if (dispRefs[0] + 1 == gfxCtx->polyOpa.p) {
gfxCtx->polyOpa.p = dispRefs[0];
} else {
gDPNoOpCloseDisp(gfxCtx->polyOpa.p++, file, line);
}
if (dispRefs[1] + 1 == gfxCtx->polyXlu.p) {
gfxCtx->polyXlu.p = dispRefs[1];
} else {
gDPNoOpCloseDisp(gfxCtx->polyXlu.p++, file, line);
}
if (dispRefs[2] + 1 == gfxCtx->overlay.p) {
gfxCtx->overlay.p = dispRefs[2];
} else {
gDPNoOpCloseDisp(gfxCtx->overlay.p++, file, line);
}
}
}
Gfx* Graph_GfxPlusOne(Gfx* gfx) {
return gfx + 1;
}
Gfx* Graph_BranchDlist(Gfx* gfx, Gfx* dst) {
gSPBranchList(gfx, dst);
return dst;
}
void* Graph_DlistAlloc(Gfx** gfx, size_t size) {
u8* ptr;
Gfx* dst;
size = ((size + 7) & ~7),
ptr = (u8*)(*gfx + 1);
dst = (Gfx*)(ptr + size);
gSPBranchList(*gfx, dst);
*gfx = dst;
return ptr;
}

232
soh/src/code/irqmgr.c Normal file
View file

@ -0,0 +1,232 @@
#include "global.h"
#include "vt.h"
vu32 gIrqMgrResetStatus = 0;
volatile OSTime sIrqMgrResetTime = 0;
volatile OSTime gIrqMgrRetraceTime = 0;
u32 sIrqMgrRetraceCount = 0;
#define RETRACE_MSG 666
#define PRE_NMI_MSG 669
#define PRENMI450_MSG 671
#define PRENMI480_MSG 672
#define PRENMI500_MSG 673
#define STATUS_IDLE 0
#define STATUS_PRENMI 1
#define STATUS_NMI 2
void IrqMgr_AddClient(IrqMgr* this, IrqMgrClient* c, OSMesgQueue* msgQ) {
OSIntMask prevInt;
LogUtils_CheckNullPointer("this", this, "../irqmgr.c", 96);
LogUtils_CheckNullPointer("c", c, "../irqmgr.c", 97);
LogUtils_CheckNullPointer("msgQ", msgQ, "../irqmgr.c", 98);
prevInt = osSetIntMask(1);
c->queue = msgQ;
c->prev = this->clients;
this->clients = c;
osSetIntMask(prevInt);
if (this->resetStatus > STATUS_IDLE) {
osSendMesg(c->queue, (OSMesg) & this->prenmiMsg, OS_MESG_NOBLOCK);
}
if (this->resetStatus >= STATUS_NMI) {
osSendMesg(c->queue, (OSMesg) & this->nmiMsg, OS_MESG_NOBLOCK);
}
}
void IrqMgr_RemoveClient(IrqMgr* this, IrqMgrClient* c) {
IrqMgrClient* iter = this->clients;
IrqMgrClient* lastIter = NULL;
OSIntMask prevInt;
LogUtils_CheckNullPointer("this", this, "../irqmgr.c", 129);
LogUtils_CheckNullPointer("c", c, "../irqmgr.c", 130);
prevInt = osSetIntMask(1);
while (iter != NULL) {
if (iter == c) {
if (lastIter) {
lastIter->prev = c->prev;
} else {
this->clients = c->prev;
}
break;
}
lastIter = iter;
iter = iter->prev;
}
osSetIntMask(prevInt);
}
void IrqMgr_SendMesgForClient(IrqMgr* this, OSMesg msg) {
IrqMgrClient* iter = this->clients;
while (iter != NULL) {
if (iter->queue->validCount >= iter->queue->msgCount) {
// "irqmgr_SendMesgForClient: Message queue is overflowing mq=%08x cnt=%d"
osSyncPrintf(
VT_COL(RED, WHITE) "irqmgr_SendMesgForClient:メッセージキューがあふれています mq=%08x cnt=%d\n" VT_RST,
iter->queue, iter->queue->validCount);
} else {
osSendMesg(iter->queue, msg, OS_MESG_NOBLOCK);
}
iter = iter->prev;
}
}
void IrqMgr_JamMesgForClient(IrqMgr* this, OSMesg msg) {
IrqMgrClient* iter = this->clients;
while (iter != NULL) {
if (iter->queue->validCount >= iter->queue->msgCount) {
// "irqmgr_JamMesgForClient: Message queue is overflowing mq=%08x cnt=%d"
osSyncPrintf(
VT_COL(RED, WHITE) "irqmgr_JamMesgForClient:メッセージキューがあふれています mq=%08x cnt=%d\n" VT_RST,
iter->queue, iter->queue->validCount);
} else {
// mistake? the function's name suggests it would use osJamMesg
osSendMesg(iter->queue, msg, OS_MESG_NOBLOCK);
}
iter = iter->prev;
}
}
void IrqMgr_HandlePreNMI(IrqMgr* this) {
u64 temp = STATUS_PRENMI; // required to match
gIrqMgrResetStatus = temp;
this->resetStatus = STATUS_PRENMI;
sIrqMgrResetTime = this->resetTime = osGetTime();
osSetTimer(&this->timer, OS_USEC_TO_CYCLES(450000), 0ull, &this->queue, (OSMesg)PRENMI450_MSG);
IrqMgr_JamMesgForClient(this, (OSMesg) & this->prenmiMsg);
}
void IrqMgr_CheckStack() {
osSyncPrintf("irqmgr.c: PRENMIから0.5秒経過\n"); // "0.5 seconds after PRENMI"
if (StackCheck_Check(NULL) == 0) {
osSyncPrintf("スタックは大丈夫みたいです\n"); // "The stack looks ok"
} else {
osSyncPrintf("%c", 7);
osSyncPrintf(VT_FGCOL(RED));
// "Stack overflow or dangerous"
osSyncPrintf("スタックがオーバーフローしたか危険な状態です\n");
// "Increase stack size early or don't consume stack"
osSyncPrintf("早々にスタックサイズを増やすか、スタックを消費しないようにしてください\n");
osSyncPrintf(VT_RST);
}
}
void IrqMgr_HandlePRENMI450(IrqMgr* this) {
u64 temp = STATUS_NMI; // required to match
gIrqMgrResetStatus = temp;
this->resetStatus = STATUS_NMI;
osSetTimer(&this->timer, OS_USEC_TO_CYCLES(30000), 0ull, &this->queue, (OSMesg)PRENMI480_MSG);
IrqMgr_SendMesgForClient(this, (OSMesg) & this->nmiMsg);
}
void IrqMgr_HandlePRENMI480(IrqMgr* this) {
u32 ret;
osSetTimer(&this->timer, OS_USEC_TO_CYCLES(20000), 0ull, &this->queue, (OSMesg)PRENMI500_MSG);
ret = osAfterPreNMI();
if (ret) {
// "osAfterPreNMI returned %d !?"
osSyncPrintf("osAfterPreNMIが %d を返しました!?\n", ret);
osSetTimer(&this->timer, OS_USEC_TO_CYCLES(1000), 0ull, &this->queue, (OSMesg)PRENMI480_MSG);
}
}
void IrqMgr_HandlePRENMI500(IrqMgr* this) {
IrqMgr_CheckStack();
}
void IrqMgr_HandleRetrace(IrqMgr* this) {
if (gIrqMgrRetraceTime == 0ull) {
if (this->retraceTime == 0) {
this->retraceTime = osGetTime();
} else {
gIrqMgrRetraceTime = osGetTime() - this->retraceTime;
}
}
sIrqMgrRetraceCount++;
IrqMgr_SendMesgForClient(this, (OSMesg) & this->retraceMsg);
}
void IrqMgr_ThreadEntry(void* arg0) {
OSMesg msg;
IrqMgr* this = (IrqMgr*)arg0;
u8 exit;
msg = 0;
osSyncPrintf("IRQマネージャスレッド実行開始\n"); // "Start IRQ manager thread execution"
exit = false;
while (!exit) {
osRecvMesg(&this->queue, &msg, OS_MESG_BLOCK);
switch ((u32)msg) {
case RETRACE_MSG:
IrqMgr_HandleRetrace(this);
break;
case PRE_NMI_MSG:
osSyncPrintf("PRE_NMI_MSG\n");
// "Scheduler: Receives PRE_NMI message"
osSyncPrintf("スケジューラPRE_NMIメッセージを受信\n");
IrqMgr_HandlePreNMI(this);
break;
case PRENMI450_MSG:
osSyncPrintf("PRENMI450_MSG\n");
// "Scheduler: Receives PRENMI450 message"
osSyncPrintf("スケジューラPRENMI450メッセージを受信\n");
IrqMgr_HandlePRENMI450(this);
break;
case PRENMI480_MSG:
osSyncPrintf("PRENMI480_MSG\n");
// "Scheduler: Receives PRENMI480 message"
osSyncPrintf("スケジューラPRENMI480メッセージを受信\n");
IrqMgr_HandlePRENMI480(this);
break;
case PRENMI500_MSG:
osSyncPrintf("PRENMI500_MSG\n");
// "Scheduler: Receives PRENMI500 message"
osSyncPrintf("スケジューラPRENMI500メッセージを受信\n");
exit = true;
IrqMgr_HandlePRENMI500(this);
break;
default:
// "Unexpected message received"
osSyncPrintf("irqmgr.c:予期しないメッセージを受け取りました(%08x)\n", msg);
break;
}
}
osSyncPrintf("IRQマネージャスレッド実行終了\n"); // "End of IRQ manager thread execution"
}
void IrqMgr_Init(IrqMgr* this, void* stack, OSPri pri, u8 retraceCount) {
LogUtils_CheckNullPointer("this", this, "../irqmgr.c", 346);
LogUtils_CheckNullPointer("stack", stack, "../irqmgr.c", 347);
this->clients = NULL;
this->retraceMsg.type = OS_SC_RETRACE_MSG;
this->prenmiMsg.type = OS_SC_PRE_NMI_MSG;
this->nmiMsg.type = OS_SC_NMI_MSG;
this->resetStatus = STATUS_IDLE;
this->resetTime = 0;
osCreateMesgQueue(&this->queue, this->msgBuf, ARRAY_COUNT(this->msgBuf));
osSetEventMesg(OS_EVENT_PRENMI, &this->queue, (OSMesg)PRE_NMI_MSG);
osViSetEvent(&this->queue, (OSMesg)RETRACE_MSG, retraceCount);
osCreateThread(&this->thread, 0x13, IrqMgr_ThreadEntry, this, stack, pri);
osStartThread(&this->thread);
}

192
soh/src/code/jpegdecoder.c Normal file
View file

@ -0,0 +1,192 @@
#include "global.h"
u8* sJpegBitStreamPtr;
u32 sJpegBitStreamByteIdx;
u8 sJpegBitStreamBitIdx;
u8 sJpegBitStreamDontSkip;
u32 sJpegBitStreamCurWord;
s32 JpegDecoder_Decode(JpegDecoder* decoder, u16* mcuBuff, s32 count, u8 isFollowing, JpegDecoderState* state) {
s16 pad;
s16 unk0;
s16 unk1;
s16 unk2;
u32 idx;
s32 inc;
u16 unkCount;
JpegHuffmanTable* hTable0;
JpegHuffmanTable* hTable1;
JpegHuffmanTable* hTable2;
JpegHuffmanTable* hTable3;
inc = 0;
sJpegBitStreamPtr = decoder->imageData;
if (decoder->mode == 0) {
unkCount = 2;
} else {
unkCount = 4;
if (decoder->unk_05 == 1) {
inc = 8 * 8 * 2;
}
}
hTable0 = decoder->hTablePtrs[0];
hTable1 = decoder->hTablePtrs[1];
hTable2 = decoder->hTablePtrs[2];
hTable3 = decoder->hTablePtrs[3];
if (!isFollowing) {
sJpegBitStreamByteIdx = 0;
sJpegBitStreamBitIdx = 32;
sJpegBitStreamCurWord = 0;
sJpegBitStreamDontSkip = 0;
unk0 = 0;
unk1 = 0;
unk2 = 0;
} else {
sJpegBitStreamByteIdx = state->byteIdx;
sJpegBitStreamBitIdx = state->bitIdx;
sJpegBitStreamCurWord = state->curWord;
sJpegBitStreamDontSkip = state->dontSkip;
unk0 = state->unk_0C;
unk1 = state->unk_0E;
unk2 = state->unk_10;
}
while (count != 0) {
for (idx = 0; idx < unkCount; idx++) {
if (JpegDecoder_ProcessMcu(hTable0, hTable1, mcuBuff, &unk0)) {
return 2;
}
mcuBuff += 8 * 8;
}
if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk1)) {
return 2;
}
mcuBuff += 8 * 8;
if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk2)) {
return 2;
}
count--;
mcuBuff += 8 * 8;
mcuBuff += inc;
}
state->byteIdx = sJpegBitStreamByteIdx;
state->bitIdx = sJpegBitStreamBitIdx;
state->curWord = sJpegBitStreamCurWord;
state->dontSkip = sJpegBitStreamDontSkip;
state->unk_0C = unk0;
state->unk_0E = unk1;
state->unk_10 = unk2;
return 0;
}
s32 JpegDecoder_ProcessMcu(JpegHuffmanTable* hTable0, JpegHuffmanTable* hTable1, u16* mcu, s16* unk) {
s8 i = 0;
s8 zeroCount;
s16 coeff;
if (JpegDecoder_ParseNextSymbol(hTable0, &coeff, &zeroCount)) {
return 1;
}
*unk += coeff;
mcu[i++] = *unk;
while (i < 8 * 8) {
if (JpegDecoder_ParseNextSymbol(hTable1, &coeff, &zeroCount) != 0) {
return 1;
}
if (coeff == 0) {
if (zeroCount == 0xF) {
while (zeroCount-- >= 0) {
mcu[i++] = 0;
}
} else {
while (i < 8 * 8) {
mcu[i++] = 0;
}
break;
}
} else {
while (0 < zeroCount--) {
mcu[i++] = 0;
}
mcu[i++] = coeff;
}
}
return 0;
}
s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, s8* outZeroCount) {
u8 codeIdx;
u8 sym;
u16 codeOff = 0;
u16 buff = JpegDecoder_ReadBits(16);
for (codeIdx = 0; codeIdx < 16; codeIdx++) {
if (hTable->codesB[codeIdx] == 0xFFFF) {
continue;
}
codeOff = buff >> (15 - codeIdx);
if (codeOff <= hTable->codesB[codeIdx]) {
break;
}
}
if (codeIdx >= 16) {
return 1;
}
sym = hTable->symbols[hTable->codeOffs[codeIdx] + codeOff - hTable->codesA[codeIdx]];
*outZeroCount = sym >> 4;
sym &= 0xF;
sJpegBitStreamBitIdx += codeIdx - 15;
*outCoeff = 0;
if (sym) {
*outCoeff = JpegDecoder_ReadBits(sym);
if (*outCoeff < (1 << (sym - 1))) {
*outCoeff += (-1 << sym) + 1;
}
}
return 0;
}
u16 JpegDecoder_ReadBits(u8 len) {
u8 byteCount;
u8 data;
s32 ret;
u32 temp;
ret = 0; // this is required for some reason
for (byteCount = sJpegBitStreamBitIdx >> 3; byteCount > 0; byteCount--) {
data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++];
if (sJpegBitStreamDontSkip) {
if (data == 0) {
data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++];
}
}
sJpegBitStreamDontSkip = (data == 0xFF) ? 1 : 0;
sJpegBitStreamCurWord <<= 8;
sJpegBitStreamCurWord |= data;
sJpegBitStreamBitIdx -= 8;
}
ret = (sJpegBitStreamCurWord << (sJpegBitStreamBitIdx));
temp = ret;
ret = temp >> -len;
sJpegBitStreamBitIdx += len;
return ret;
}

153
soh/src/code/jpegutils.c Normal file
View file

@ -0,0 +1,153 @@
#include "global.h"
void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 count) {
u8 i;
for (i = 0; i < count; i++) {
u8 j;
dqt++;
for (j = 0; j < 64; j++) {
qt[i].table[j] = *dqt++;
}
}
}
s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) {
u8 off = 1;
s16 count = 0;
s16 idx = 1;
while (off < 0x11) {
while (idx <= ptr[off - 1]) {
codesLengths[count++] = off;
idx++;
}
idx = 1;
off++;
}
codesLengths[count] = 0;
return count;
}
s32 JpegUtils_GetHuffmanCodes(u8* codesLengths, u16* codes) {
s16 idx = 0;
u16 code = 0;
u8 lastLen = codesLengths[0];
while (true) {
while (true) {
codes[idx++] = code++;
if (codesLengths[idx] != lastLen) {
break;
}
}
if (codesLengths[idx] == 0) {
break;
}
while (true) {
if (code <<= 1, codesLengths[idx] == ++lastLen) {
break;
}
}
}
return idx;
}
s32 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) {
u8 idx;
u16 codeOff = 0;
for (idx = 0; idx < 0x10; idx++) {
if (data[idx]) {
ht->codeOffs[idx] = codeOff;
ht->codesA[idx] = codes[codeOff];
codeOff += data[idx] - 1;
ht->codesB[idx] = codes[codeOff];
codeOff++;
} else {
ht->codesB[idx] = 0xFFFF;
}
}
return codeOff;
}
u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 isAc) {
s16 ret;
s32 count = JpegUtils_ParseHuffmanCodesLengths(data, codesLengths);
s32 temp;
ret = count;
if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) {
return 0;
}
if (ret != JpegUtils_GetHuffmanCodes(codesLengths, codes)) {
return 0;
}
if (temp = JpegUtils_SetHuffmanTable(data, ht, codes), temp != ret) {
return 0;
}
return ret;
}
u32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count) {
u8 idx;
u32 codeCount;
for (idx = 0; idx < count; idx++) {
u32 ac = (*dht++ >> 4);
codeCount = JpegUtils_ProcessHuffmanTableImpl(dht, &ht[idx], codesLengths, codes, ac);
if (codeCount == 0) {
return 1;
}
dht += 0x10;
ht[idx].symbols = dht;
dht += codeCount;
}
return 0;
}
void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes, s16 count, u8 isAc) {
s16 idx;
u8 a;
for (idx = 0; idx < count; idx++) {
a = data[idx];
if (isAc) {
ht->acCodes[a] = codes[idx];
ht->codeOffs[a] = codesLengths[idx];
} else {
ht->dcCodes[a] = codes[idx];
ht->codeOffs[a] = codesLengths[idx];
}
}
}
u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes) {
u8 isAc = *dht++ >> 4;
s16 count2;
s32 count;
count2 = count = JpegUtils_ParseHuffmanCodesLengths(dht, codesLengths);
if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) {
return 1;
}
if (JpegUtils_GetHuffmanCodes(codesLengths, codes) != count2) {
return 1;
}
JpegUtils_SetHuffmanTableOld(dht + 0x10, ht, codesLengths, codes, count2, isAc);
return 0;
}

62
soh/src/code/listalloc.c Normal file
View file

@ -0,0 +1,62 @@
#include "global.h"
ListAlloc* ListAlloc_Init(ListAlloc* this) {
this->prev = NULL;
this->next = NULL;
return this;
}
void* ListAlloc_Alloc(ListAlloc* this, size_t size) {
ListAlloc* ptr = SystemArena_MallocDebug(size + sizeof(ListAlloc), "../listalloc.c", 40);
ListAlloc* next;
if (ptr == NULL) {
return NULL;
}
next = this->next;
if (next != NULL) {
next->next = ptr;
}
ptr->prev = next;
ptr->next = NULL;
this->next = ptr;
if (this->prev == NULL) {
this->prev = ptr;
}
return (u8*)ptr + sizeof(ListAlloc);
}
void ListAlloc_Free(ListAlloc* this, void* data) {
ListAlloc* ptr = &((ListAlloc*)data)[-1];
if (ptr->prev != NULL) {
ptr->prev->next = ptr->next;
}
if (ptr->next != NULL) {
ptr->next->prev = ptr->prev;
}
if (this->prev == ptr) {
this->prev = ptr->next;
}
if (this->next == ptr) {
this->next = ptr->prev;
}
SystemArena_FreeDebug(ptr, "../listalloc.c", 72);
}
void ListAlloc_FreeAll(ListAlloc* this) {
ListAlloc* iter = this->prev;
while (iter != NULL) {
ListAlloc_Free(this, (u8*)iter + sizeof(ListAlloc));
iter = this->prev;
}
}

View file

@ -0,0 +1,16 @@
#include "global.h"
void* Overlay_AllocateAndLoad(uintptr_t vRomStart, uintptr_t vRomEnd, void* vRamStart, void* vRamEnd) {
void* allocatedVRamAddr = SystemArena_MallocRDebug((intptr_t)vRamEnd - (intptr_t)vRamStart, "../loadfragment2.c", 31);
if (gOverlayLogSeverity >= 3) {
osSyncPrintf("OVL:SPEC(%08x-%08x) REAL(%08x-%08x) OFFSET(%08x)\n", vRamStart, vRamEnd, allocatedVRamAddr,
((uintptr_t)vRamEnd - (uintptr_t)vRamStart) + (uintptr_t)allocatedVRamAddr, (uintptr_t)vRamStart - (uintptr_t)allocatedVRamAddr);
}
if (allocatedVRamAddr != NULL) {
Overlay_Load(vRomStart, vRomEnd, vRamStart, vRamEnd, allocatedVRamAddr);
}
return allocatedVRamAddr;
}

View file

@ -0,0 +1,3 @@
#include "global.h"
s32 gOverlayLogSeverity = 2;

134
soh/src/code/main.c Normal file
View file

@ -0,0 +1,134 @@
#include "global.h"
#include "vt.h"
#include <soh/Enhancements/bootcommands.h>
#include "soh/OTRGlobals.h"
s32 gScreenWidth = SCREEN_WIDTH;
s32 gScreenHeight = SCREEN_HEIGHT;
u32 gSystemHeapSize = 0;
PreNmiBuff* gAppNmiBufferPtr;
SchedContext gSchedContext;
PadMgr gPadMgr;
IrqMgr gIrqMgr;
uintptr_t gSegments[NUM_SEGMENTS];
OSThread sGraphThread;
u8 sGraphStack[0x1800];
u8 sSchedStack[0x600];
u8 sAudioStack[0x800];
u8 sPadMgrStack[0x500];
u8 sIrqMgrStack[0x500];
StackEntry sGraphStackInfo;
StackEntry sSchedStackInfo;
StackEntry sAudioStackInfo;
StackEntry sPadMgrStackInfo;
StackEntry sIrqMgrStackInfo;
AudioMgr gAudioMgr;
OSMesgQueue sSiIntMsgQ;
OSMesg sSiIntMsgBuf[1];
void Main_LogSystemHeap(void) {
osSyncPrintf(VT_FGCOL(GREEN));
// "System heap size% 08x (% dKB) Start address% 08x"
osSyncPrintf("システムヒープサイズ %08x(%dKB) 開始アドレス %08x\n", gSystemHeapSize, gSystemHeapSize / 1024,
gSystemHeap);
osSyncPrintf(VT_RST);
}
void main(int argc, char** argv)
{
GameConsole_Init();
InitOTR();
BootCommands_Init();
BootCommands_ParseBootArgs(argc - 1, (char**)&argv[1]);
Main(0);
}
void Main(void* arg) {
IrqMgrClient irqClient;
OSMesgQueue irqMgrMsgQ;
OSMesg irqMgrMsgBuf[60];
uintptr_t sysHeap;
uintptr_t fb;
void* debugHeap;
s32 debugHeapSize;
s16* msg;
osSyncPrintf("mainproc 実行開始\n"); // "Start running"
gScreenWidth = SCREEN_WIDTH;
gScreenHeight = SCREEN_HEIGHT;
gAppNmiBufferPtr = (PreNmiBuff*)osAppNmiBuffer;
PreNmiBuff_Init(gAppNmiBufferPtr);
Fault_Init();
SysCfb_Init(0);
sysHeap = gSystemHeap;
fb = SysCfb_GetFbPtr(0);
gSystemHeapSize = 1024 * 1024 * 4;
// "System heap initalization"
osSyncPrintf("システムヒープ初期化 %08x-%08x %08x\n", sysHeap, fb, gSystemHeapSize);
SystemHeap_Init(sysHeap, gSystemHeapSize); // initializes the system heap
if (osMemSize >= 0x800000) {
debugHeap = SysCfb_GetFbEnd();
debugHeapSize = (0x80600000 - (uintptr_t)debugHeap);
} else {
debugHeapSize = 0x400;
debugHeap = SystemArena_MallocDebug(debugHeapSize, "../main.c", 565);
}
debugHeapSize = 1024 * 64;
osSyncPrintf("debug_InitArena(%08x, %08x)\n", debugHeap, debugHeapSize);
DebugArena_Init(debugHeap, debugHeapSize);
func_800636C0();
R_ENABLE_ARENA_DBG = 0;
osCreateMesgQueue(&sSiIntMsgQ, sSiIntMsgBuf, 1);
osSetEventMesg(5, &sSiIntMsgQ, 0);
Main_LogSystemHeap();
osCreateMesgQueue(&irqMgrMsgQ, irqMgrMsgBuf, 0x3C);
StackCheck_Init(&sIrqMgrStackInfo, sIrqMgrStack, sIrqMgrStack + sizeof(sIrqMgrStack), 0, 0x100, "irqmgr");
IrqMgr_Init(&gIrqMgr, &sGraphStackInfo, Z_PRIORITY_IRQMGR, 1);
osSyncPrintf("タスクスケジューラの初期化\n"); // "Initialize the task scheduler"
StackCheck_Init(&sSchedStackInfo, sSchedStack, sSchedStack + sizeof(sSchedStack), 0, 0x100, "sched");
Sched_Init(&gSchedContext, &sAudioStack, Z_PRIORITY_SCHED, D_80013960, 1, &gIrqMgr);
IrqMgr_AddClient(&gIrqMgr, &irqClient, &irqMgrMsgQ);
StackCheck_Init(&sAudioStackInfo, sAudioStack, sAudioStack + sizeof(sAudioStack), 0, 0x100, "audio");
AudioMgr_Init(&gAudioMgr, sAudioStack + sizeof(sAudioStack), Z_PRIORITY_AUDIOMGR, 0xA, &gSchedContext, &gIrqMgr);
StackCheck_Init(&sPadMgrStackInfo, sPadMgrStack, sPadMgrStack + sizeof(sPadMgrStack), 0, 0x100, "padmgr");
PadMgr_Init(&gPadMgr, &sSiIntMsgQ, &gIrqMgr, 7, Z_PRIORITY_PADMGR, &sIrqMgrStack);
AudioMgr_Unlock(&gAudioMgr);
StackCheck_Init(&sGraphStackInfo, sGraphStack, sGraphStack + sizeof(sGraphStack), 0, 0x100, "graph");
osCreateThread(&sGraphThread, 4, Graph_ThreadEntry, arg, sGraphStack + sizeof(sGraphStack), Z_PRIORITY_GRAPH);
osStartThread(&sGraphThread);
osSetThreadPri(0, Z_PRIORITY_SCHED);
Graph_ThreadEntry(0);
while (true) {
msg = NULL;
osRecvMesg(&irqMgrMsgQ, (OSMesg)&msg, OS_MESG_BLOCK);
if (msg == NULL) {
break;
}
if (*msg == OS_SC_PRE_NMI_MSG) {
osSyncPrintf("main.c: リセットされたみたいだよ\n"); // "Looks like it's been reset"
PreNmiBuff_SetReset(gAppNmiBufferPtr);
}
}
osSyncPrintf("mainproc 後始末\n"); // "Cleanup"
osDestroyThread(&sGraphThread);
func_800FBFD8();
osSyncPrintf("mainproc 実行終了\n"); // "End of execution"
}

187
soh/src/code/mempak.c Normal file
View file

@ -0,0 +1,187 @@
#include "global.h"
OSPfs sMempakPfsHandle;
s32 sMempakFreeBytes;
s32 sMempakFiles[10];
u16 sMempakCompanyCode = 1;
u32 sMempakGameCode = 1;
// "ZELDA DEMO TOOL "
u8 sMempakGameName[0x10] = { 0x33, 0x1E, 0x25, 0x1D, 0x1A, 0x0F, 0x1D, 0x1E,
0x26, 0x28, 0x0F, 0x2D, 0x28, 0x28, 0x25, 0x0F };
u8 sMempakExtName[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
s32 Mempak_Init(s32 controllerNb) {
OSMesgQueue* mq;
s32 pad;
s32 ret = false;
mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
if (!osPfsInitPak(mq, &sMempakPfsHandle, controllerNb)) {
ret = true;
}
osPfsFreeBlocks(&sMempakPfsHandle, &sMempakFreeBytes);
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
return ret;
}
s32 Mempak_GetFreeBytes(s32 controllerNb) {
return sMempakFreeBytes;
}
s32 Mempak_FindFile(s32 controllerNb, char start, char end) {
OSMesgQueue* mq;
s32 error;
char idx;
u32 bit = 1;
s32 flag = 0;
mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
for (idx = start; idx <= end; idx++) {
sMempakExtName[0] = idx - 0x27;
error = osPfsFindFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName,
&sMempakFiles[idx - 'A']);
if (error == 0) {
flag |= bit;
} else {
sMempakFiles[idx - 'A'] = -1;
}
bit <<= 1;
osSyncPrintf("mempak: find '%c' (%d)\n", idx, error);
}
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
osSyncPrintf("mempak: find '%c' - '%c' %02x\n", start, end, flag);
return flag;
}
s32 Mempak_Write(s32 controllerNb, char idx, void* buffer, s32 offset, ptrdiff_t size) {
OSMesgQueue* mq;
s32 error;
s32 ret = false;
s32 pad;
mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
if (size < sMempakFreeBytes) {
error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[idx - 'A'], 1, offset, size, buffer);
if (error == 0) {
ret = true;
}
osSyncPrintf("mempak: write %d byte '%c' (%d)->%d\n", size, idx, sMempakFiles[idx - 'A'], error);
}
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
return ret;
}
s32 Mempak_Read(s32 controllerNb, char idx, void* buffer, s32 offset, ptrdiff_t size) {
OSMesgQueue* mq;
s32 error;
s32 ret = false;
s32 pad;
mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
if (size < sMempakFreeBytes) {
error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[idx - 'A'], 0, offset, size, buffer);
if (error == 0) {
ret = true;
}
osSyncPrintf("mempak: read %d byte '%c' (%d)<-%d\n", size, idx, sMempakFiles[idx - 'A'], error);
}
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
return ret;
}
s32 Mempak_Alloc(s32 controllerNb, char* idx, ptrdiff_t size) {
OSMesgQueue* mq;
s32 error;
s32 ret = 0;
s32 i;
s32 pad;
mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
if (*idx >= 'A' && *idx < 'L') {
sMempakExtName[0] = *idx - 0x27;
if (-1 == sMempakFiles[*idx - 'A']) {
error = osPfsAllocateFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName,
sMempakExtName, size, &sMempakFiles[*idx - 'A']);
if (error == 0) {
ret = 1;
}
osSyncPrintf("mempak: alloc %d byte '%c' (%d)\n", size, *idx, error);
} else {
sMempakExtName[0] = *idx - 0x27;
if (osPfsDeleteFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName,
sMempakExtName) == 0) {
ret = 1;
}
error = osPfsAllocateFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName,
sMempakExtName, size, &sMempakFiles[*idx - 'A']);
if (error == 0) {
ret |= 1;
}
osSyncPrintf("mempak: resize %d byte '%c' (%d)\n", size, *idx, error);
}
} else {
for (i = 0; i < ARRAY_COUNT(sMempakFiles); i++) {
if (sMempakFiles[i] == -1) {
break;
}
}
*idx = i + 'A';
sMempakExtName[0] = *idx - 0x27;
error = osPfsAllocateFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName,
sMempakExtName, size, &sMempakFiles[i]);
osSyncPrintf("mempak: alloc %d byte '%c' (%d) with search\n", size, *idx, error);
if (error == 0) {
ret = 1;
}
}
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
return ret;
}
s32 Mempak_DeleteFile(s32 controllerNb, char idx) {
OSMesgQueue* mq;
s32 error;
s32 ret = false;
mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
sMempakExtName[0] = idx - 0x27;
error = osPfsDeleteFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName);
if (error == 0) {
ret = true;
}
osSyncPrintf("mempak: delete '%c' (%d)\n", idx, error);
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
return ret;
}
s32 Mempak_GetFileSize(s32 controllerNb, char idx) {
OSMesgQueue* mq = PadMgr_LockSerialMesgQueue(&gPadMgr);
OSPfsState state;
s32 error = osPfsFileState(&sMempakPfsHandle, sMempakFiles[idx - 'A'], &state);
s32 pad;
PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq);
if (error != 0) {
return 0;
}
return state.file_size;
}

24
soh/src/code/mtxuty-cvt.c Normal file
View file

@ -0,0 +1,24 @@
#include "global.h"
void MtxConv_F2L(Mtx* m1, MtxF* m2) {
s32 i;
s32 j;
LogUtils_CheckNullPointer("m1", m1, "../mtxuty-cvt.c", 31);
LogUtils_CheckNullPointer("m2", m2, "../mtxuty-cvt.c", 32);
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
s32 value = (m2->mf[i][j] * 0x10000);
m1->intPart[i][j] = value >> 16;
m1->fracPart[i][j] = value;
}
}
}
void MtxConv_L2F(MtxF* m1, Mtx* m2) {
LogUtils_CheckNullPointer("m1", m1, "../mtxuty-cvt.c", 55);
LogUtils_CheckNullPointer("m2", m2, "../mtxuty-cvt.c", 56);
guMtxL2F(m1, m2);
}

441
soh/src/code/padmgr.c Normal file
View file

@ -0,0 +1,441 @@
#include "global.h"
#include "vt.h"
//#include <string.h>
extern void* __cdecl memset(_Out_writes_bytes_all_(_Size) void* _Dst, _In_ int _Val, _In_ size_t _Size);
s32 D_8012D280 = 1;
static ControllerCallback controllerCallback;
OSMesgQueue* PadMgr_LockSerialMesgQueue(PadMgr* padMgr) {
OSMesgQueue* ctrlrQ = NULL;
if (D_8012D280 > 2) {
// "serialMsgQ Waiting for lock"
osSyncPrintf("%2d %d serialMsgQロック待ち %08x %08x %08x\n", osGetThreadId(NULL),
padMgr->serialMsgQ.validCount, padMgr, &padMgr->serialMsgQ, &ctrlrQ);
}
osRecvMesg(&padMgr->serialMsgQ, (OSMesg)&ctrlrQ, OS_MESG_BLOCK);
if (D_8012D280 > 2) {
// "serialMsgQ Locked"
osSyncPrintf("%2d %d serialMsgQをロックしました %08x\n", osGetThreadId(NULL),
padMgr->serialMsgQ.validCount, ctrlrQ);
}
return ctrlrQ;
}
void PadMgr_UnlockSerialMesgQueue(PadMgr* padMgr, OSMesgQueue* ctrlrQ) {
if (D_8012D280 > 2) {
// "serialMsgQ Unlock"
osSyncPrintf("%2d %d serialMsgQロック解除します %08x %08x %08x\n", osGetThreadId(NULL),
padMgr->serialMsgQ.validCount, padMgr, &padMgr->serialMsgQ, ctrlrQ);
}
osSendMesg(&padMgr->serialMsgQ, ctrlrQ, OS_MESG_BLOCK);
if (D_8012D280 > 2) {
// "serialMsgQ Unlocked"
osSyncPrintf("%2d %d serialMsgQロック解除しました %08x %08x %08x\n", osGetThreadId(NULL),
padMgr->serialMsgQ.validCount, padMgr, &padMgr->serialMsgQ, ctrlrQ);
}
}
void PadMgr_LockPadData(PadMgr* padMgr) {
osRecvMesg(&padMgr->lockMsgQ, NULL, OS_MESG_BLOCK);
}
void PadMgr_UnlockPadData(PadMgr* padMgr) {
osSendMesg(&padMgr->lockMsgQ, NULL, OS_MESG_BLOCK);
}
void PadMgr_RumbleControl(PadMgr* padMgr) {
static u32 errcnt = 0;
static u32 frame;
s32 temp = 1;
s32 triedRumbleComm;
OSMesgQueue* ctrlrQ = PadMgr_LockSerialMesgQueue(padMgr);
s32 var4;
s32 i;
triedRumbleComm = 0;
for (i = 0; i < 4; i++) {
if (padMgr->ctrlrIsConnected[i]) {
if (padMgr->padStatus[i].status & 1) {
if (padMgr->pakType[i] == temp) {
if (padMgr->rumbleEnable[i] != 0) {
if (padMgr->rumbleCounter[i] < 3) {
// clang-format off
if (1) {} osSyncPrintf(VT_FGCOL(YELLOW));
// clang-format on
// "Vibration pack jumble jumble"?
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック ぶるぶるぶるぶる");
osSyncPrintf(VT_RST);
if (__osMotorAccess(&padMgr->pfs[i], temp) != 0) {
padMgr->pakType[i] = 0;
osSyncPrintf(VT_FGCOL(YELLOW));
// "A communication error has occurred with the vibration pack"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックで通信エラーが発生しました");
osSyncPrintf(VT_RST);
} else {
padMgr->rumbleCounter[i] = 3;
}
triedRumbleComm = 1;
}
} else {
if (padMgr->rumbleCounter[i] != 0) {
// clang-format off
if (1) {} osSyncPrintf(VT_FGCOL(YELLOW));
// clang-format on
// "Stop vibration pack"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック 停止");
osSyncPrintf(VT_RST);
if (osMotorStop(&padMgr->pfs[i]) != 0) {
padMgr->pakType[i] = 0;
osSyncPrintf(VT_FGCOL(YELLOW));
// "A communication error has occurred with the vibration pack"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックで通信エラーが発生しました");
osSyncPrintf(VT_RST);
} else {
padMgr->rumbleCounter[i]--;
}
triedRumbleComm = 1;
}
}
}
} else {
if (padMgr->pakType[i] != 0) {
if (padMgr->pakType[i] == 1) {
osSyncPrintf(VT_FGCOL(YELLOW));
// "It seems that a vibration pack was pulled out"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックが抜かれたようです");
osSyncPrintf(VT_RST);
padMgr->pakType[i] = 0;
} else {
osSyncPrintf(VT_FGCOL(YELLOW));
// "It seems that a controller pack that is not a vibration pack was pulled out"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1,
"振動パックではないコントローラパックが抜かれたようです");
osSyncPrintf(VT_RST);
padMgr->pakType[i] = 0;
}
}
}
}
}
if (!triedRumbleComm) {
i = frame % 4;
if (padMgr->ctrlrIsConnected[i] && (padMgr->padStatus[i].status & 1) && (padMgr->pakType[i] != 1)) {
var4 = osMotorInit(ctrlrQ, &padMgr->pfs[i], i);
if (var4 == 0) {
padMgr->pakType[i] = 1;
osMotorStart(&padMgr->pfs[i]);
osMotorStop(&padMgr->pfs[i]);
osSyncPrintf(VT_FGCOL(YELLOW));
// "Recognized vibration pack"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックを認識しました");
osSyncPrintf(VT_RST);
} else if (var4 == 11) {
padMgr->pakType[i] = 2;
} else if (var4 == 4) {
LOG_NUM("++errcnt", ++errcnt, "../padmgr.c", 282);
osSyncPrintf(VT_FGCOL(YELLOW));
// "Controller pack communication error"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "コントローラパックの通信エラー");
osSyncPrintf(VT_RST);
}
}
}
frame++;
PadMgr_UnlockSerialMesgQueue(padMgr, ctrlrQ);
}
void PadMgr_RumbleStop(PadMgr* padMgr) {
s32 i;
OSMesgQueue* ctrlrQ = PadMgr_LockSerialMesgQueue(padMgr);
for (i = 0; i < 4; i++) {
if (osMotorInit(ctrlrQ, &padMgr->pfs[i], i) == 0) {
#if 0
if ((gFaultStruct.msgId == 0) && (padMgr->rumbleOnFrames != 0))
{
osSyncPrintf(VT_FGCOL(YELLOW));
// "Stop vibration pack"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック 停止");
osSyncPrintf(VT_RST);
}
#endif
osMotorStop(&padMgr->pfs[i]);
}
}
PadMgr_UnlockSerialMesgQueue(padMgr, ctrlrQ);
}
void PadMgr_RumbleReset(PadMgr* padMgr) {
padMgr->rumbleOffFrames = 3;
}
void PadMgr_RumbleSetSingle(PadMgr* padMgr, u32 ctrlr, u32 rumble) {
padMgr->rumbleEnable[ctrlr] = rumble;
padMgr->rumbleOnFrames = 240;
}
void PadMgr_RumbleSet(PadMgr* padMgr, u8* ctrlrRumbles) {
s32 i;
for (i = 0; i < 4; i++) {
padMgr->rumbleEnable[i] = ctrlrRumbles[i];
}
padMgr->rumbleOnFrames = 240;
}
void PadMgr_ProcessInputs(PadMgr* padMgr) {
s32 i;
Input* input;
OSContPad* padnow1; // original name
s32 buttonDiff;
PadMgr_LockPadData(padMgr);
input = &padMgr->inputs[0];
padnow1 = &padMgr->pads[0];
for (i = 0; i < padMgr->nControllers; i++, input++, padnow1++) {
input->prev = input->cur;
if (1) {} // Necessary to match
switch (padnow1->err_no) {
case 0:
input->cur = *padnow1;
if (!padMgr->ctrlrIsConnected[i]) {
padMgr->ctrlrIsConnected[i] = true;
osSyncPrintf(VT_FGCOL(YELLOW));
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "認識しました"); // "Recognized"
osSyncPrintf(VT_RST);
}
break;
case 4:
input->cur = input->prev;
LOG_NUM("this->Key_switch[i]", padMgr->ctrlrIsConnected[i], "../padmgr.c", 380);
osSyncPrintf(VT_FGCOL(YELLOW));
// "Overrun error occurred"
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "オーバーランエラーが発生");
osSyncPrintf(VT_RST);
break;
case 8:
input->cur.button = 0;
input->cur.stick_x = 0;
input->cur.stick_y = 0;
input->cur.err_no = padnow1->err_no;
if (padMgr->ctrlrIsConnected[i]) {
padMgr->ctrlrIsConnected[i] = false;
padMgr->pakType[i] = 0;
padMgr->rumbleCounter[i] = 0xFF;
osSyncPrintf(VT_FGCOL(YELLOW));
// "Do not respond"?
osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "応答しません");
osSyncPrintf(VT_RST);
}
break;
default:
LOG_HEX("padnow1->errno", padnow1->err_no, "../padmgr.c", 396);
Fault_AddHungupAndCrash("../padmgr.c", 397);
}
buttonDiff = input->prev.button ^ input->cur.button;
input->press.button |= (u16)(buttonDiff & input->cur.button);
input->rel.button |= (u16)(buttonDiff & input->prev.button);
PadUtils_UpdateRelXY(input);
input->press.stick_x += (s8)(input->cur.stick_x - input->prev.stick_x);
input->press.stick_y += (s8)(input->cur.stick_y - input->prev.stick_y);
}
controllerCallback.rumble = padMgr->rumbleEnable[0] > 0 ? 1 : 0;
if (HealthMeter_IsCritical()) {
controllerCallback.ledColor = 1;
} else {
controllerCallback.ledColor = 0;
}
OTRControllerCallback(&controllerCallback);
PadMgr_UnlockPadData(padMgr);
}
void PadMgr_HandleRetraceMsg(PadMgr* padMgr) {
s32 i;
OSMesgQueue* queue = PadMgr_LockSerialMesgQueue(padMgr);
u32 mask;
osContStartReadData(queue);
if (padMgr->retraceCallback) {
padMgr->retraceCallback(padMgr, padMgr->retraceCallbackValue);
}
osRecvMesg(queue, NULL, OS_MESG_BLOCK);
osContGetReadData(padMgr->pads);
if (padMgr->preNMIShutdown) {
memset(padMgr->pads, 0, sizeof(padMgr->pads));
}
PadMgr_ProcessInputs(padMgr);
osContStartQuery(queue);
osRecvMesg(queue, NULL, OS_MESG_BLOCK);
osContGetQuery(padMgr->padStatus);
PadMgr_UnlockSerialMesgQueue(padMgr, queue);
mask = 0;
for (i = 0; i < 4; i++) {
if (padMgr->padStatus[i].err_no == 0) {
if (padMgr->padStatus[i].type == CONT_TYPE_NORMAL) {
mask |= 1 << i;
} else {
//LOG_HEX("this->pad_status[i].type", padMgr->padStatus[i].type, "../padmgr.c", 458);
// "An unknown type of controller is connected"
//osSyncPrintf("知らない種類のコントローラが接続されています\n");
}
}
}
padMgr->validCtrlrsMask = mask;
/* if (gFaultStruct.msgId) {
PadMgr_RumbleStop(padMgr);
} else */ if (padMgr->rumbleOffFrames > 0) {
--padMgr->rumbleOffFrames;
PadMgr_RumbleStop(padMgr);
} else if (padMgr->rumbleOnFrames == 0) {
PadMgr_RumbleStop(padMgr);
} else if (!padMgr->preNMIShutdown) {
PadMgr_RumbleControl(padMgr);
--padMgr->rumbleOnFrames;
}
}
void PadMgr_HandlePreNMI(PadMgr* padMgr) {
osSyncPrintf("padmgr_HandlePreNMI()\n");
padMgr->preNMIShutdown = true;
PadMgr_RumbleReset(padMgr);
}
void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 mode) {
s32 i;
Input* ogInput;
Input* newInput;
s32 buttonDiff;
PadMgr_LockPadData(padMgr);
ogInput = &padMgr->inputs[0];
newInput = &inputs[0];
for (i = 0; i < 4; i++) {
if (mode != 0) {
*newInput = *ogInput;
ogInput->press.button = 0;
ogInput->press.stick_x = 0;
ogInput->press.stick_y = 0;
ogInput->rel.button = 0;
} else {
newInput->prev = newInput->cur;
newInput->cur = ogInput->cur;
buttonDiff = newInput->prev.button ^ newInput->cur.button;
newInput->press.button = newInput->cur.button & buttonDiff;
newInput->rel.button = newInput->prev.button & buttonDiff;
PadUtils_UpdateRelXY(newInput);
newInput->press.stick_x += (s8)(newInput->cur.stick_x - newInput->prev.stick_x);
newInput->press.stick_y += (s8)(newInput->cur.stick_y - newInput->prev.stick_y);
}
ogInput++;
newInput++;
}
PadMgr_UnlockPadData(padMgr);
}
void PadMgr_ThreadEntry(PadMgr* padMgr) {
s16* mesg = NULL;
s32 exit;
//osSyncPrintf("コントローラスレッド実行開始\n"); // "Controller thread execution start"
exit = false;
while (!exit) {
if ((D_8012D280 > 2) && (padMgr->interruptMsgQ.validCount == 0)) {
// "Waiting for controller thread event"
osSyncPrintf("コントローラスレッドイベント待ち %lld\n", OS_CYCLES_TO_USEC(osGetTime()));
}
osRecvMesg(&padMgr->interruptMsgQ, (OSMesg)&mesg, OS_MESG_BLOCK);
//LogUtils_CheckNullPointer("msg", mesg, "../padmgr.c", 563);
PadMgr_HandleRetraceMsg(padMgr);
break;
#if 0
switch (*mesg) {
case OS_SC_RETRACE_MSG:
if (D_8012D280 > 2) {
osSyncPrintf("padmgr_HandleRetraceMsg START %lld\n", OS_CYCLES_TO_USEC(osGetTime()));
}
PadMgr_HandleRetraceMsg(padMgr);
if (D_8012D280 > 2) {
osSyncPrintf("padmgr_HandleRetraceMsg END %lld\n", OS_CYCLES_TO_USEC(osGetTime()));
}
break;
case OS_SC_PRE_NMI_MSG:
PadMgr_HandlePreNMI(padMgr);
break;
case OS_SC_NMI_MSG:
exit = true;
break;
}
#endif
}
// OTRTODO: Removed due to crash
//IrqMgr_RemoveClient(padMgr->irqMgr, &padMgr->irqClient);
//osSyncPrintf("コントローラスレッド実行終了\n"); // "Controller thread execution end"
}
void PadMgr_Init(PadMgr* padMgr, OSMesgQueue* siIntMsgQ, IrqMgr* irqMgr, OSId id, OSPri priority, void* stack) {
osSyncPrintf("パッドマネージャ作成 padmgr_Create()\n"); // "Pad Manager creation"
memset(padMgr, 0, sizeof(PadMgr));
padMgr->irqMgr = irqMgr;
osCreateMesgQueue(&padMgr->interruptMsgQ, padMgr->interruptMsgBuf, 4);
// OTRTODO: Removed due to crash
//IrqMgr_AddClient(padMgr->irqMgr, &padMgr->irqClient, &padMgr->interruptMsgQ);
osCreateMesgQueue(&padMgr->serialMsgQ, padMgr->serialMsgBuf, 1);
PadMgr_UnlockSerialMesgQueue(padMgr, siIntMsgQ);
osCreateMesgQueue(&padMgr->lockMsgQ, padMgr->lockMsgBuf, 1);
PadMgr_UnlockPadData(padMgr);
PadSetup_Init(siIntMsgQ, (u8*)&padMgr->validCtrlrsMask, padMgr->padStatus);
padMgr->nControllers = 4;
osContSetCh(padMgr->nControllers);
osCreateThread(&padMgr->thread, id, (void (*)(void*))PadMgr_ThreadEntry, padMgr, stack, priority);
osStartThread(&padMgr->thread);
}

34
soh/src/code/padsetup.c Normal file
View file

@ -0,0 +1,34 @@
#include "global.h"
s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status) {
s32 ret;
s32 i;
*outMask = 0xFF;
ret = osContInit(mq, outMask, status);
if (ret != 0) {
return ret;
}
if (*outMask == 0xFF) {
if (osContStartQuery(mq) != 0) {
return 1;
}
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
osContGetQuery(status);
*outMask = 0;
for (i = 0; i < 4; i++) {
switch (status[i].err_no) {
case 0:
if (status[i].type == CONT_TYPE_NORMAL) {
*outMask |= 1 << i;
}
break;
default:
break;
}
}
}
return 0;
}

94
soh/src/code/padutils.c Normal file
View file

@ -0,0 +1,94 @@
#include "global.h"
#include <string.h>
void PadUtils_Init(Input* input) {
memset(input,0, sizeof(Input));
}
void func_800FCB70(void) {
}
void PadUtils_ResetPressRel(Input* input) {
input->press.button = 0;
input->rel.button = 0;
}
u32 PadUtils_CheckCurExact(Input* input, u16 value) {
return value == input->cur.button;
}
u32 PadUtils_CheckCur(Input* input, u16 key) {
return key == (input->cur.button & key);
}
u32 PadUtils_CheckPressed(Input* input, u16 key) {
return key == (input->press.button & key);
}
u32 PadUtils_CheckReleased(Input* input, u16 key) {
return key == (input->rel.button & key);
}
u16 PadUtils_GetCurButton(Input* input) {
return input->cur.button;
}
u16 PadUtils_GetPressButton(Input* input) {
return input->press.button;
}
s8 PadUtils_GetCurX(Input* input) {
return input->cur.stick_x;
}
s8 PadUtils_GetCurY(Input* input) {
return input->cur.stick_y;
}
void PadUtils_SetRelXY(Input* input, s32 x, s32 y) {
input->rel.stick_x = x;
input->rel.stick_y = y;
}
s8 PadUtils_GetRelXImpl(Input* input) {
return input->rel.stick_x;
}
s8 PadUtils_GetRelYImpl(Input* input) {
return input->rel.stick_y;
}
s8 PadUtils_GetRelX(Input* input) {
return PadUtils_GetRelXImpl(input);
}
s8 PadUtils_GetRelY(Input* input) {
return PadUtils_GetRelYImpl(input);
}
void PadUtils_UpdateRelXY(Input* input) {
s32 curX = PadUtils_GetCurX(input);
s32 curY = PadUtils_GetCurY(input);
s32 relX;
s32 relY;
if (curX > 7) {
relX = (curX < 0x43) ? curX - 7 : 0x43 - 7;
} else if (curX < -7) {
relX = (curX > -0x43) ? curX + 7 : -0x43 + 7;
} else {
relX = 0;
}
if (curY > 7) {
relY = (curY < 0x43) ? curY - 7 : 0x43 - 7;
} else if (curY < -7) {
relY = (curY > -0x43) ? curY + 7 : -0x43 + 7;
} else {
relY = 0;
}
PadUtils_SetRelXY(input, relX, relY);
}

17
soh/src/code/printutils.c Normal file
View file

@ -0,0 +1,17 @@
#include "global.h"
s32 PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args) {
return _Printf(*pfn, pfn, fmt, args);
}
s32 PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...) {
s32 ret;
va_list args;
va_start(args, fmt);
ret = PrintUtils_VPrintf(pfn, fmt, args);
va_end(args);
return ret;
}

113
soh/src/code/relocation.c Normal file
View file

@ -0,0 +1,113 @@
#include "global.h"
void Overlay_Relocate(void* allocatedVRamAddress, OverlayRelocationSection* overlayInfo, void* vRamAddress) {
u32 sections[4];
u32 relocatedValue;
u32 dbg;
u32 relocOffset;
u32 relocData;
uintptr_t unrelocatedAddress;
u32 i;
uintptr_t* relocDataP;
u32* luiRefs[32];
u32 luiVals[32];
uintptr_t relocatedAddress;
u32 reloc;
uintptr_t vaddr;
u32* luiInstRef;
uintptr_t allocu32 = (uintptr_t)allocatedVRamAddress;
u32* regValP;
u32 isLoNeg;
relocOffset = 0;
relocatedValue = 0;
unrelocatedAddress = 0;
relocatedAddress = 0;
if (gOverlayLogSeverity >= 3) {
osSyncPrintf("DoRelocation(%08x, %08x, %08x)\n", allocatedVRamAddress, overlayInfo, vRamAddress);
osSyncPrintf("text=%08x, data=%08x, rodata=%08x, bss=%08x\n", overlayInfo->textSize, overlayInfo->dataSize,
overlayInfo->rodataSize, overlayInfo->bssSize);
}
sections[0] = 0;
sections[1] = allocu32;
sections[2] = allocu32 + overlayInfo->textSize;
sections[3] = sections[2] + overlayInfo->dataSize;
for (i = 0; i < overlayInfo->nRelocations; i++) {
reloc = overlayInfo->relocations[i];
relocDataP = (u32*)(sections[reloc >> 0x1E] + (reloc & 0xFFFFFF));
relocData = *relocDataP;
switch (reloc & 0x3F000000) {
case 0x2000000:
/* R_MIPS_32
* Handles 32-bit address relocation. Used in things such as
* jump tables.
*/
if ((*relocDataP & 0xF000000) == 0) {
luiInstRef = vRamAddress;
relocOffset = *relocDataP - (uintptr_t)luiInstRef;
relocatedValue = relocOffset + allocu32;
relocatedAddress = relocatedValue;
unrelocatedAddress = relocData;
*relocDataP = relocatedAddress;
}
break;
case 0x4000000:
/* R_MIPS_26
* Handles 26-bit address relocation, used for jumps and jals
*/
unrelocatedAddress = ((*relocDataP & 0x3FFFFFF) << 2) | 0x80000000;
relocOffset = unrelocatedAddress - (uintptr_t)vRamAddress;
relocatedValue = (*relocDataP & 0xFC000000) | (((allocu32 + relocOffset) & 0xFFFFFFF) >> 2);
relocatedAddress = ((relocatedValue & 0x3FFFFFF) << 2) | 0x80000000;
*relocDataP = relocatedValue;
break;
case 0x5000000:
/* R_MIPS_HI16
* Handles relocation for a lui instruciton, store the reference to
* the instruction, and will update it in the R_MIPS_LO16 section.
*/
luiRefs[(*relocDataP >> 0x10) & 0x1F] = relocDataP;
luiVals[(*relocDataP >> 0x10) & 0x1F] = *relocDataP;
break;
case 0x6000000:
/* R_MIPS_LO16
* Updates the LUI instruction to reflect the relocated address.
* The full address is calculated from the LUI and lo parts, and then updated.
* if the lo part is negative, add 1 to the lui.
*/
regValP = &luiVals[((*relocDataP >> 0x15) & 0x1F)];
vaddr = (*regValP << 0x10) + (s16)*relocDataP;
luiInstRef = luiRefs[((*relocDataP >> 0x15) & 0x1F)];
if ((vaddr & 0xF000000) == 0) {
relocOffset = vaddr - (uintptr_t)vRamAddress;
vaddr = (s16)relocData;
isLoNeg = (((relocOffset + allocu32) & 0x8000) ? 1 : 0);
unrelocatedAddress = (*luiInstRef << 0x10) + vaddr;
*luiInstRef =
(*luiInstRef & 0xFFFF0000) | ((((relocOffset + allocu32) >> 0x10) & 0xFFFF) + isLoNeg);
relocatedValue = (*relocDataP & 0xFFFF0000) | ((relocOffset + allocu32) & 0xFFFF);
relocatedAddress = (*luiInstRef << 0x10) + (s16)relocatedValue;
*relocDataP = relocatedValue;
}
break;
}
dbg = 0x10;
switch (reloc & 0x3F000000) {
case 0x2000000:
dbg = 0x16;
case 0x4000000:
dbg += 0xA;
case 0x6000000:
if (gOverlayLogSeverity >= 3) {
osSyncPrintf("%02d %08x %08x %08x ", dbg, relocDataP, relocatedValue, relocatedAddress);
osSyncPrintf(" %08x %08x %08x %08x\n", ((uintptr_t)relocDataP + (uintptr_t)vRamAddress) - allocu32, relocData,
unrelocatedAddress, relocOffset);
}
}
}
}

493
soh/src/code/sched.c Normal file
View file

@ -0,0 +1,493 @@
#include "global.h"
#include <string.h>
#define RSP_DONE_MSG 667
#define RDP_DONE_MSG 668
#define ENTRY_MSG 670
// data
vs32 sLogScheduler = false;
// bss
OSTime sRSPGFXStartTime;
OSTime sRSPAudioStartTime;
OSTime sRSPOtherStartTime;
OSTime sRDPStartTime;
void Sched_SwapFrameBuffer(CfbInfo* cfbInfo) {
u16 width;
LogUtils_CheckValidPointer("cfbinfo->swapbuffer", cfbInfo->swapBuffer, "../sched.c", 340);
if (cfbInfo->swapBuffer != NULL) {
osViSwapBuffer(cfbInfo->swapBuffer);
cfbInfo->updateRate2 = cfbInfo->updateRate;
if (sLogScheduler) {
osSyncPrintf("osViSwapBuffer %08x %08x %08x\n", osViGetCurrentFramebuffer(), osViGetNextFramebuffer(),
(cfbInfo != NULL ? cfbInfo->swapBuffer : NULL));
}
width = cfbInfo->viMode != NULL ? cfbInfo->viMode->comRegs.width : (u32)gScreenWidth;
Fault_SetFB(cfbInfo->swapBuffer, width, 0x10);
if (HREG(80) == 0xD && HREG(95) != 0xD) {
HREG(81) = 0;
HREG(82) = 0;
HREG(83) = 1;
HREG(84) = 0;
HREG(85) = 1;
HREG(86) = 0;
HREG(87) = 0;
HREG(88) = 0;
HREG(89) = 0;
HREG(90) = 0;
HREG(91) = 0;
HREG(92) = 0;
HREG(93) = 0;
HREG(94) = 0;
HREG(95) = 0xD;
}
if (HREG(80) == 0xD && HREG(81) == 2) {
osViSetSpecialFeatures(HREG(82) != 0 ? OS_VI_GAMMA_ON : OS_VI_GAMMA_OFF);
osViSetSpecialFeatures(HREG(83) != 0 ? OS_VI_DITHER_FILTER_ON : OS_VI_DITHER_FILTER_OFF);
osViSetSpecialFeatures(HREG(84) != 0 ? OS_VI_GAMMA_DITHER_ON : OS_VI_GAMMA_DITHER_OFF);
osViSetSpecialFeatures(HREG(85) != 0 ? OS_VI_DIVOT_ON : OS_VI_DIVOT_OFF);
}
}
cfbInfo->unk_10 = 0;
}
void func_800C84E4(SchedContext* sc, CfbInfo* cfbInfo) {
if (sc->unk_24C != 0) {
sc->unk_24C = 0;
if (gIrqMgrResetStatus == 0) {
ViConfig_UpdateVi(0);
}
}
Sched_SwapFrameBuffer(cfbInfo);
}
void Sched_HandleReset(SchedContext* sc) {
OSTime now;
if (sc->curRSPTask != NULL) {
now = osGetTime();
if (sc->curRSPTask->framebuffer == NULL) {
LOG_TIME("(((u64)(now - audio_rsp_start_time)*(1000000LL/15625LL))/((62500000LL*3/4)/15625LL))",
OS_CYCLES_TO_USEC(now - sRSPAudioStartTime), "../sched.c", 421);
} else if (OS_CYCLES_TO_USEC(now - sRSPGFXStartTime) > 1000000 ||
OS_CYCLES_TO_USEC(now - sRDPStartTime) > 1000000) {
func_800FBFD8();
if (sc->curRSPTask != NULL) {
LOG_TIME("(((u64)(now - graph_rsp_start_time)*(1000000LL/15625LL))/((62500000LL*3/4)/15625LL))",
OS_CYCLES_TO_USEC(now - sRSPGFXStartTime), "../sched.c", 427);
osSendMesg(&sc->interruptQ, RSP_DONE_MSG, OS_MESG_NOBLOCK);
}
if (sc->curRDPTask != NULL) {
LOG_TIME("(((u64)(now - rdp_start_time)*(1000000LL/15625LL))/((62500000LL*3/4)/15625LL))",
OS_CYCLES_TO_USEC(now - sRDPStartTime), "../sched.c", 431);
osSendMesg(&sc->interruptQ, RDP_DONE_MSG, OS_MESG_NOBLOCK);
}
}
}
}
void Sched_HandleStart(SchedContext* sc) {
ViConfig_UpdateVi(1);
}
void Sched_QueueTask(SchedContext* sc, OSScTask* task) {
s32 type = task->list.t.type;
ASSERT((type == M_AUDTASK) || (type == M_GFXTASK) || (type == M_NJPEGTASK) || (type == M_NULTASK),
"(type == M_AUDTASK) || (type == M_GFXTASK) || (type == M_NJPEGTASK) || (type == M_NULTASK)", "../sched.c",
463);
if (type == M_AUDTASK) {
if (sLogScheduler) {
// "You have entered an audio task"
osSyncPrintf("オーディオタスクをエントリしました\n");
}
if (sc->audioListTail != NULL) {
sc->audioListTail->next = task;
} else {
sc->audioListHead = task;
}
sc->audioListTail = task;
sc->doAudio = 1;
} else {
if (sLogScheduler) {
osSyncPrintf("グラフタスクをエントリしました\n"); // "Entered graph task"
}
if (sc->gfxListTail != NULL) {
sc->gfxListTail->next = task;
} else {
sc->gfxListHead = task;
}
sc->gfxListTail = task;
}
task->next = NULL;
task->state = task->flags & (OS_SC_NEEDS_RDP | OS_SC_NEEDS_RSP);
}
void Sched_Yield(SchedContext* sc) {
if (!(sc->curRSPTask->state & OS_SC_YIELD)) {
ASSERT(sc->curRSPTask->list.t.type != M_AUDTASK, "sc->curRSPTask->list.t.type != M_AUDTASK", "../sched.c", 496);
sc->curRSPTask->state |= OS_SC_YIELD;
osSpTaskYield();
if (sLogScheduler) {
osSyncPrintf("%08d:osSpTaskYield\n", (u32)(OS_CYCLES_TO_USEC(osGetTime())));
}
}
}
OSScTask* func_800C89D4(SchedContext* sc, OSScTask* task) {
if (task == NULL) {
return NULL;
}
if (sc->pendingSwapBuf1 != NULL) {
if (0) {
ASSERT(sc->pendingSwapBuf1 != NULL, "sc->pending_swapbuffer1", "../sched.c", UNK_LINE);
}
return NULL;
}
if (sc->pendingSwapBuf2 != NULL) {
if (0) {
ASSERT(sc->pendingSwapBuf2 != NULL, "sc->pending_swapbuffer2", "../sched.c", UNK_LINE);
}
return NULL;
}
if ((sc->pendingSwapBuf2 != NULL ? sc->pendingSwapBuf2->swapBuffer : NULL) == task->framebuffer->fb1) {
return NULL;
}
if ((sc->pendingSwapBuf1 != NULL ? sc->pendingSwapBuf1->swapBuffer : NULL) == task->framebuffer->fb1) {
return NULL;
}
if (osViGetCurrentFramebuffer() == (u32*)task->framebuffer->fb1) {
return NULL;
}
return task;
}
s32 Sched_Schedule(SchedContext* sc, OSScTask** sp, OSScTask** dp, s32 state) {
s32 ret = state;
OSScTask* gfxTask = sc->gfxListHead;
OSScTask* audioTask = sc->audioListHead;
if (sc->doAudio && (ret & OS_SC_SP)) {
*sp = audioTask;
ret &= ~OS_SC_SP;
sc->doAudio = 0;
sc->audioListHead = sc->audioListHead->next;
if (sc->audioListHead == NULL) {
sc->audioListTail = NULL;
}
} else if (gfxTask != NULL) {
if (gfxTask->state & OS_SC_YIELDED || !(gfxTask->flags & OS_SC_NEEDS_RDP)) {
if (ret & OS_SC_SP) {
*sp = gfxTask;
ret &= ~OS_SC_SP;
sc->gfxListHead = sc->gfxListHead->next;
if (sc->gfxListHead == NULL) {
sc->gfxListTail = NULL;
}
}
} else if (ret == (OS_SC_SP | OS_SC_DP)) {
if (gfxTask->framebuffer == NULL || func_800C89D4(sc, gfxTask) != NULL) {
*sp = *dp = gfxTask;
ret &= ~(OS_SC_SP | OS_SC_DP);
sc->gfxListHead = sc->gfxListHead->next;
if (sc->gfxListHead == NULL) {
sc->gfxListTail = NULL;
}
}
}
}
return ret;
}
void func_800C8BC4(SchedContext* sc, OSScTask* task) {
if (sc->pendingSwapBuf1 == NULL) {
sc->pendingSwapBuf1 = task->framebuffer;
LogUtils_CheckValidPointer("sc->pending_swapbuffer1", sc->pendingSwapBuf1, "../sched.c", 618);
if ((sc->curBuf == NULL) || (sc->curBuf->updateRate2 < 1)) {
func_800C84E4(sc, task->framebuffer);
}
}
}
u32 Sched_IsComplete(SchedContext* sc, OSScTask* task) {
if (!(task->state & (OS_SC_DP | OS_SC_SP))) {
if (task->msgQ != NULL) {
osSendMesg(task->msgQ, task->msg, OS_MESG_BLOCK);
}
if (task->flags & OS_SC_SWAPBUFFER) {
func_800C8BC4(sc, task);
}
return 1;
}
return 0;
}
void Sched_RunTask(SchedContext* sc, OSScTask* spTask, OSScTask* dpTask) {
ASSERT(sc->curRSPTask == NULL, "sc->curRSPTask == NULL", "../sched.c", 663);
if (spTask != NULL) {
if (spTask->list.t.type == M_NULTASK) {
if (spTask->flags & OS_SC_NEEDS_RSP) {
spTask->state &= ~OS_SC_SP;
sc->curRSPTask = NULL;
}
if (spTask->flags & OS_SC_NEEDS_RDP) {
spTask->state &= ~OS_SC_DP;
sc->curRDPTask = NULL;
}
Sched_IsComplete(sc, spTask);
return;
}
spTask->state &= ~(OS_SC_YIELD | OS_SC_YIELDED);
osWritebackDCacheAll();
osSpTaskLoad(&spTask->list);
if (spTask->list.t.type == M_AUDTASK) {
sRSPAudioStartTime = osGetTime();
} else if (spTask->list.t.type == M_GFXTASK) {
sRSPGFXStartTime = osGetTime();
} else {
sRSPOtherStartTime = osGetTime();
}
osSpTaskStartGo(&spTask->list);
if (sLogScheduler) {
osSyncPrintf(
"%08d:osSpTaskStartGo(%08x) %s\n", (u32)OS_CYCLES_TO_USEC(osGetTime()), &spTask->list,
(spTask->list.t.type == M_AUDTASK ? "AUDIO" : (spTask->list.t.type == M_GFXTASK ? "GRAPH" : "OTHER")));
}
sc->curRSPTask = spTask;
if (spTask == dpTask && sc->curRDPTask == NULL) {
sc->curRDPTask = dpTask;
sRDPStartTime = sRSPGFXStartTime;
}
}
}
void Sched_HandleEntry(SchedContext* sc) {
OSScTask* nextRSP = NULL;
OSScTask* nextRDP = NULL;
s32 state;
OSMesg msg = NULL;
while (osRecvMesg(&sc->cmdQ, &msg, OS_MESG_NOBLOCK) != -1) {
Sched_QueueTask(sc, msg);
}
if (sc->doAudio != 0 && sc->curRSPTask != NULL) {
if (sLogScheduler) {
osSyncPrintf("[YIELD B]");
}
Sched_Yield(sc);
return;
}
state = ((sc->curRSPTask == 0) * 2) | (sc->curRDPTask == 0);
if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) {
Sched_RunTask(sc, nextRSP, nextRDP);
}
if (sLogScheduler) {
osSyncPrintf("EN sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
}
}
void Sched_HandleRetrace(SchedContext* sc) {
if (sLogScheduler) {
osSyncPrintf("%08d:scHandleRetrace %08x\n", (u32)OS_CYCLES_TO_USEC(osGetTime()), osViGetCurrentFramebuffer());
}
ViConfig_UpdateBlack();
sc->retraceCnt++;
if (osViGetCurrentFramebuffer() == (u32*)(sc->pendingSwapBuf1 != NULL ? sc->pendingSwapBuf1->swapBuffer : NULL)) {
if (sc->curBuf != NULL) {
sc->curBuf->unk_10 = 0;
}
if (sc->pendingSwapBuf1 != NULL) {
sc->pendingSwapBuf1->unk_10 = 0;
}
sc->curBuf = sc->pendingSwapBuf1;
sc->pendingSwapBuf1 = sc->pendingSwapBuf2;
sc->pendingSwapBuf2 = NULL;
}
if (sc->curBuf != NULL) {
if (sc->curBuf->updateRate2 > 0) {
sc->curBuf->updateRate2--;
}
if ((sc->curBuf->updateRate2 <= 0) && (sc->pendingSwapBuf1 != NULL)) {
func_800C84E4(sc, sc->pendingSwapBuf1);
}
}
if (sLogScheduler) {
osSyncPrintf("%08x %08x %08x %d\n", osViGetCurrentFramebuffer(), osViGetNextFramebuffer(),
sc->pendingSwapBuf1 != NULL ? sc->pendingSwapBuf1->swapBuffer : NULL,
sc->curBuf != NULL ? sc->curBuf->updateRate2 : 0);
}
Sched_HandleEntry(sc);
}
void Sched_HandleRSPDone(SchedContext* sc) {
OSScTask* curRSPTask;
OSScTask* nextRSP = NULL;
OSScTask* nextRDP = NULL;
s32 state;
ASSERT(sc->curRSPTask != NULL, "sc->curRSPTask", "../sched.c", 819);
if (sc->curRSPTask->list.t.type == M_AUDTASK) {
gRSPAudioTotalTime += osGetTime() - sRSPAudioStartTime;
} else if (sc->curRSPTask->list.t.type == M_GFXTASK) {
gRSPGFXTotalTime += osGetTime() - sRSPGFXStartTime;
} else {
gRSPOtherTotalTime += osGetTime() - sRSPOtherStartTime;
}
curRSPTask = sc->curRSPTask;
sc->curRSPTask = NULL;
if (sLogScheduler) {
osSyncPrintf("RSP DONE %d %d", curRSPTask->state & 0x10, osSpTaskYielded(&curRSPTask->list));
}
if (curRSPTask->state & OS_SC_YIELD && osSpTaskYielded(&curRSPTask->list)) {
if (sLogScheduler) {
osSyncPrintf("[YIELDED]\n");
}
curRSPTask->state |= OS_SC_YIELDED;
curRSPTask->next = sc->gfxListHead;
sc->gfxListHead = curRSPTask;
if (sc->gfxListTail == NULL) {
sc->gfxListTail = curRSPTask;
}
} else {
if (sLogScheduler) {
osSyncPrintf("[NOT YIELDED]\n");
}
curRSPTask->state &= ~OS_SC_SP;
Sched_IsComplete(sc, curRSPTask);
}
state = ((sc->curRSPTask == NULL) << 1) | (sc->curRDPTask == NULL);
if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) {
Sched_RunTask(sc, nextRSP, nextRDP);
}
if (sLogScheduler) {
osSyncPrintf("SP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
}
}
void Sched_HandleRDPDone(SchedContext* sc) {
OSScTask* curTask;
OSScTask* nextRSP = NULL;
OSScTask* nextRDP = NULL;
s32 state;
gRDPTotalTime = osGetTime() - sRDPStartTime;
ASSERT(sc->curRDPTask != NULL, "sc->curRDPTask", "../sched.c", 878);
ASSERT(sc->curRDPTask->list.t.type == M_GFXTASK, "sc->curRDPTask->list.t.type == M_GFXTASK", "../sched.c", 879);
curTask = sc->curRDPTask;
sc->curRDPTask = NULL;
curTask->state &= ~OS_SC_DP;
Sched_IsComplete(sc, curTask);
state = ((sc->curRSPTask == NULL) << 1) | (sc->curRDPTask == NULL);
if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) {
Sched_RunTask(sc, nextRSP, nextRDP);
}
if (sLogScheduler) {
osSyncPrintf("DP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
}
}
void Sched_SendEntryMsg(SchedContext* sc) {
if (sLogScheduler) {
osSyncPrintf("osScKickEntryMsg\n");
}
osSendMesg(&sc->interruptQ, ENTRY_MSG, OS_MESG_BLOCK);
}
void Sched_ThreadEntry(void* arg) {
void* msg;
SchedContext* sc = (SchedContext*)arg;
msg = NULL;
while (true) {
if (sLogScheduler) {
// "%08d: standby"
osSyncPrintf("%08d:待機中\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
osRecvMesg(&sc->interruptQ, &msg, OS_MESG_BLOCK);
switch ((s32)msg) {
case ENTRY_MSG:
if (sLogScheduler) {
osSyncPrintf("%08d:ENTRY_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
Sched_HandleEntry(sc);
continue;
case RSP_DONE_MSG:
if (sLogScheduler) {
osSyncPrintf("%08d:RSP_DONE_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
Sched_HandleRSPDone(sc);
continue;
case RDP_DONE_MSG:
if (sLogScheduler) {
osSyncPrintf("%08d:RDP_DONE_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
Sched_HandleRDPDone(sc);
continue;
default:
break;
}
switch (((OSScMsg*)msg)->type) {
case 1:
Sched_HandleRetrace(sc);
continue;
case 4:
Sched_HandleReset(sc);
continue;
case 3:
Sched_HandleStart(sc);
continue;
}
}
}
void Sched_Init(SchedContext* sc, void* stack, OSPri priority, UNK_TYPE arg3, UNK_TYPE arg4, IrqMgr* irqMgr) {
memset(sc,0, sizeof(SchedContext));
sc->unk_24C = 1;
osCreateMesgQueue(&sc->interruptQ, sc->intBuf, 8);
osCreateMesgQueue(&sc->cmdQ, sc->cmdMsgBuf, 8);
osSetEventMesg(OS_EVENT_SP, &sc->interruptQ, RSP_DONE_MSG);
osSetEventMesg(OS_EVENT_DP, &sc->interruptQ, RDP_DONE_MSG);
IrqMgr_AddClient(irqMgr, &sc->irqClient, &sc->interruptQ);
osCreateThread(&sc->thread, 5, Sched_ThreadEntry, sc, stack, priority);
osStartThread(&sc->thread);
}

View file

@ -0,0 +1,97 @@
#include "global.h"
s32 D_8012CED0 = 0;
s32 sShrinkWindowVal = 0;
s32 sShrinkWindowCurrentVal = 0;
void ShrinkWindow_SetVal(s32 value) {
if (HREG(80) == 0x13 && HREG(81) == 1) {
osSyncPrintf("shrink_window_setval(%d)\n", value);
}
sShrinkWindowVal = value;
}
u32 ShrinkWindow_GetVal(void) {
return sShrinkWindowVal;
}
void ShrinkWindow_SetCurrentVal(s32 currentVal) {
if (HREG(80) == 0x13 && HREG(81) == 1) {
osSyncPrintf("shrink_window_setnowval(%d)\n", currentVal);
}
sShrinkWindowCurrentVal = currentVal;
}
u32 ShrinkWindow_GetCurrentVal(void) {
return sShrinkWindowCurrentVal;
}
void ShrinkWindow_Init(void) {
if (HREG(80) == 0x13 && HREG(81) == 1) {
osSyncPrintf("shrink_window_init()\n");
}
D_8012CED0 = 0;
sShrinkWindowVal = 0;
sShrinkWindowCurrentVal = 0;
}
void ShrinkWindow_Destroy(void) {
if (HREG(80) == 0x13 && HREG(81) == 1) {
osSyncPrintf("shrink_window_cleanup()\n");
}
sShrinkWindowCurrentVal = 0;
}
void ShrinkWindow_Update(s32 updateRate) {
s32 off;
if (updateRate == 3) {
off = 10;
} else {
off = 30 / updateRate;
}
if (sShrinkWindowCurrentVal < sShrinkWindowVal) {
if (D_8012CED0 != 1) {
D_8012CED0 = 1;
}
if (sShrinkWindowCurrentVal + off < sShrinkWindowVal) {
sShrinkWindowCurrentVal += off;
} else {
sShrinkWindowCurrentVal = sShrinkWindowVal;
}
} else if (sShrinkWindowVal < sShrinkWindowCurrentVal) {
if (D_8012CED0 != 2) {
D_8012CED0 = 2;
}
if (sShrinkWindowVal < sShrinkWindowCurrentVal - off) {
sShrinkWindowCurrentVal -= off;
} else {
sShrinkWindowCurrentVal = sShrinkWindowVal;
}
} else {
D_8012CED0 = 0;
}
if (HREG(80) == 0x13) {
if (HREG(94) != 0x13) {
HREG(94) = 0x13;
HREG(81) = 0;
HREG(82) = 0;
HREG(83) = 0;
HREG(84) = 0;
HREG(85) = 0;
HREG(86) = 0;
HREG(87) = 0;
HREG(88) = 0;
HREG(89) = 0;
}
HREG(83) = D_8012CED0;
HREG(84) = sShrinkWindowCurrentVal;
HREG(85) = sShrinkWindowVal;
HREG(86) = off;
}
}

28
soh/src/code/sleep.c Normal file
View file

@ -0,0 +1,28 @@
#include "global.h"
void Sleep_Cycles(OSTime cycles) {
OSMesgQueue mq;
OSMesg msg;
OSTimer timer;
osCreateMesgQueue(&mq, &msg, OS_MESG_BLOCK);
osSetTimer(&timer, cycles, 0, &mq, NULL);
osRecvMesg(&mq, NULL, OS_MESG_BLOCK);
}
void Sleep_Nsec(u32 nsec) {
Sleep_Cycles(OS_NSEC_TO_CYCLES(nsec));
}
void Sleep_Usec(u32 usec) {
Sleep_Cycles(OS_USEC_TO_CYCLES(usec));
}
// originally "msleep"
void Sleep_Msec(u32 ms) {
Sleep_Cycles((ms * OS_CPU_COUNTER) / 1000ull);
}
void Sleep_Sec(u32 sec) {
Sleep_Cycles(sec * OS_CPU_COUNTER);
}

211
soh/src/code/speed_meter.c Normal file
View file

@ -0,0 +1,211 @@
#include "global.h"
#include "vt.h"
volatile OSTime D_8016A520;
volatile OSTime D_8016A528;
volatile OSTime D_8016A530;
volatile OSTime D_8016A538;
volatile OSTime D_8016A540;
volatile OSTime D_8016A548;
volatile OSTime D_8016A550;
volatile OSTime D_8016A558;
volatile OSTime gRSPAudioTotalTime;
volatile OSTime gRSPGFXTotalTime;
volatile OSTime gRSPOtherTotalTime;
volatile OSTime D_8016A578;
volatile OSTime gRDPTotalTime;
SpeedMeterTimeEntry* sSpeedMeterTimeEntryPtr;
SpeedMeterTimeEntry sSpeedMeterTimeEntryArray[] = {
{ &D_8016A520, 0, 0, GPACK_RGBA5551(255, 0, 0, 1) }, { &D_8016A528, 0, 2, GPACK_RGBA5551(255, 255, 0, 1) },
{ &D_8016A530, 0, 4, GPACK_RGBA5551(0, 0, 255, 1) }, { &D_8016A538, 0, 6, GPACK_RGBA5551(255, 128, 128, 1) },
{ &D_8016A540, 0, 8, GPACK_RGBA5551(0, 255, 0, 1) }, { &D_8016A548, 0, 10, GPACK_RGBA5551(255, 0, 255, 1) },
};
#define DrawRec(gfx, color, ulx, uly, lrx, lry) \
gDPPipeSync(gfx); \
gDPSetFillColor(gfx, ((color) << 16) | (color)); \
gDPFillRectangle(gfx, (ulx), (uly), (lrx), (lry)); \
gDPPipeSync(gfx);
void SpeedMeter_InitImpl(SpeedMeter* this, u32 arg1, u32 y) {
LogUtils_CheckNullPointer("this", this, "../speed_meter.c", 181);
this->unk_18 = arg1;
this->y = y;
}
void SpeedMeter_Init(SpeedMeter* this) {
SpeedMeter_InitImpl(this, 32, 22);
}
void SpeedMeter_Destroy(SpeedMeter* this) {
}
void SpeedMeter_DrawTimeEntries(SpeedMeter* this, GraphicsContext* gfxCtx) {
s32 pad[2];
u32 baseX = 32;
s32 temp;
s32 i;
s32 uly;
s32 lry;
View view;
u32 pad2[3];
Gfx* gfx;
uly = this->y;
lry = this->y + 2;
OPEN_DISPS(gfxCtx, "../speed_meter.c", 225);
/*! @bug if gIrqMgrRetraceTime is 0, CLOSE_DISPS will never be reached */
if (gIrqMgrRetraceTime == 0) {
return;
}
sSpeedMeterTimeEntryPtr = &sSpeedMeterTimeEntryArray[0];
for (i = 0; i < ARRAY_COUNT(sSpeedMeterTimeEntryArray); i++) {
temp = ((f64) * (sSpeedMeterTimeEntryPtr->time) / gIrqMgrRetraceTime) * 64.0;
sSpeedMeterTimeEntryPtr->x = temp + baseX;
sSpeedMeterTimeEntryPtr++;
}
View_Init(&view, gfxCtx);
view.flags = 0xA;
SET_FULLSCREEN_VIEWPORT(&view);
gfx = OVERLAY_DISP;
func_800AB9EC(&view, 0xF, &gfx);
gDPPipeSync(gfx++);
gDPSetOtherMode(gfx++,
G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_FILL | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
DrawRec(gfx++, GPACK_RGBA5551(0, 0, 255, 1), baseX + 64 * 0, uly, baseX + 64 * 1, lry);
DrawRec(gfx++, GPACK_RGBA5551(0, 255, 0, 1), baseX + 64 * 1, uly, baseX + 64 * 2, lry);
DrawRec(gfx++, GPACK_RGBA5551(255, 0, 0, 1), baseX + 64 * 2, uly, baseX + 64 * 3, lry);
DrawRec(gfx++, GPACK_RGBA5551(255, 0, 255, 1), baseX + 64 * 3, uly, baseX + 64 * 4, lry);
sSpeedMeterTimeEntryPtr = &sSpeedMeterTimeEntryArray[0];
for (i = 0; i < ARRAY_COUNT(sSpeedMeterTimeEntryArray); i++) {
DrawRec(gfx++, sSpeedMeterTimeEntryPtr->color, baseX, lry + sSpeedMeterTimeEntryPtr->y,
sSpeedMeterTimeEntryPtr->x, lry + sSpeedMeterTimeEntryPtr->y + 1);
sSpeedMeterTimeEntryPtr++;
}
gDPPipeSync(gfx++);
OVERLAY_DISP = gfx;
CLOSE_DISPS(gfxCtx, "../speed_meter.c", 276);
}
void SpeedMeter_InitAllocEntry(SpeedMeterAllocEntry* this, u32 maxval, u32 val, u16 backColor, u16 foreColor, u32 ulx,
u32 lrx, u32 uly, u32 lry) {
this->maxval = maxval;
this->val = val;
this->backColor = backColor;
this->foreColor = foreColor;
this->ulx = ulx;
this->lrx = lrx;
this->uly = uly;
this->lry = lry;
}
void SpeedMeter_DrawAllocEntry(SpeedMeterAllocEntry* this, GraphicsContext* gfxCtx) {
s32 usedOff;
View view;
Gfx* gfx;
if (this->maxval == 0) {
osSyncPrintf(VT_FGCOL(RED));
LOG_NUM("this->maxval", this->maxval, "../speed_meter.c", 313);
osSyncPrintf(VT_RST);
} else {
OPEN_DISPS(gfxCtx, "../speed_meter.c", 318);
View_Init(&view, gfxCtx);
view.flags = 0xA;
SET_FULLSCREEN_VIEWPORT(&view);
gfx = OVERLAY_DISP;
func_800AB9EC(&view, 0xF, &gfx);
gDPPipeSync(gfx++);
gDPSetOtherMode(gfx++,
G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_FILL | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
usedOff = ((this->lrx - this->ulx) * this->val) / this->maxval + this->ulx;
DrawRec(gfx++, this->backColor, usedOff, this->uly, this->lrx, this->lry);
DrawRec(gfx++, this->foreColor, this->ulx, this->uly, usedOff, this->lry);
gDPPipeSync(gfx++);
OVERLAY_DISP = gfx;
CLOSE_DISPS(gfxCtx, "../speed_meter.c", 339);
}
}
void SpeedMeter_DrawAllocEntries(SpeedMeter* meter, GraphicsContext* gfxCtx, GameState* state) {
s32 pad[2];
u32 ulx = 30;
u32 lrx = 290;
SpeedMeterAllocEntry entry;
u32 temp;
s32 y;
TwoHeadGfxArena* thga;
u32 zeldaFreeMax;
u32 zeldaFree;
u32 zeldaAlloc;
s32 sysFreeMax;
s32 sysFree;
s32 sysAlloc;
y = 212;
if (SREG(0) > 2) {
if (ZeldaArena_IsInitalized()) {
ZeldaArena_GetSizes(&zeldaFreeMax, &zeldaFree, &zeldaAlloc);
SpeedMeter_InitAllocEntry(&entry, zeldaFree + zeldaAlloc, zeldaAlloc, GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 255, 255, 1), ulx, lrx, y, y + 1);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
y++;
}
}
if (SREG(0) > 1) {
SystemArena_GetSizes((u32*)&sysFreeMax, (u32*)&sysFree, (u32*)&sysAlloc);
SpeedMeter_InitAllocEntry(&entry, sysFree + sysAlloc - state->tha.size, sysAlloc - state->tha.size,
GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(255, 128, 128, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
}
thga = (TwoHeadGfxArena*)&state->tha;
SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THA_GetSize((TwoHeadArena*)thga),
GPACK_RGBA5551(0, 0, 255, 1), GPACK_RGBA5551(0, 255, 0, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
thga = &gfxCtx->polyOpa;
SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 0, 255, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
thga = &gfxCtx->polyXlu;
SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 255, 0, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
thga = &gfxCtx->overlay;
SpeedMeter_InitAllocEntry(&entry, thga->size, thga->size - THGA_GetSize(thga), GPACK_RGBA5551(0, 0, 255, 1),
GPACK_RGBA5551(255, 0, 0, 1), ulx, lrx, y, y);
SpeedMeter_DrawAllocEntry(&entry, gfxCtx);
y++;
}

60
soh/src/code/sys_cfb.c Normal file
View file

@ -0,0 +1,60 @@
#include "global.h"
#include <stdlib.h>
uintptr_t sSysCfbFbPtr[2];
uintptr_t sSysCfbEnd;
void SysCfb_Init(s32 n64dd) {
u32 screenSize;
uintptr_t tmpFbEnd;
/*
if (osMemSize >= 0x800000) {
// "8MB or more memory is installed"
osSyncPrintf("8Mバイト以上のメモリが搭載されています\n");
tmpFbEnd = 0x8044BE80;
if (n64dd == 1) {
osSyncPrintf("RAM 8M mode (N64DD対応)\n"); // "RAM 8M mode (N64DD compatible)"
sSysCfbEnd = 0x805FB000;
} else {
// "The margin for this version is %dK bytes"
osSyncPrintf("このバージョンのマージンは %dK バイトです\n", (0x4BC00 / 1024));
sSysCfbEnd = tmpFbEnd;
}
} else if (osMemSize >= 0x400000) {
osSyncPrintf("RAM4M mode\n");
sSysCfbEnd = 0x80400000;
} else {
LogUtils_HungupThread("../sys_cfb.c", 354);
}
*/
screenSize = SCREEN_WIDTH * SCREEN_HEIGHT;
//sSysCfbEnd &= ~0x3F;
// "The final address used by the system is %08x"
osSyncPrintf("システムが使用する最終アドレスは %08x です\n", sSysCfbEnd);
//sSysCfbFbPtr[0] = sSysCfbEnd - (screenSize * 4);
//sSysCfbFbPtr[1] = sSysCfbEnd - (screenSize * 2);
sSysCfbFbPtr[0] = malloc(screenSize * 4);
sSysCfbFbPtr[1] = malloc(screenSize * 4);
// "Frame buffer addresses are %08x and %08x"
//osSyncPrintf("フレームバッファのアドレスは %08x と %08x です\n", sSysCfbFbPtr[0], sSysCfbFbPtr[1]);
}
void SysCfb_Reset() {
sSysCfbFbPtr[0] = 0;
sSysCfbFbPtr[1] = 0;
sSysCfbEnd = 0;
}
uintptr_t SysCfb_GetFbPtr(s32 idx) {
if (idx < 2) {
return sSysCfbFbPtr[idx];
}
return 0;
}
uintptr_t SysCfb_GetFbEnd() {
return sSysCfbEnd;
}

47
soh/src/code/sys_math.c Normal file
View file

@ -0,0 +1,47 @@
#include "global.h"
f32 sFactorialTbl[] = { 1.0f, 1.0f, 2.0f, 6.0f, 24.0f, 120.0f, 720.0f,
5040.0f, 40320.0f, 362880.0f, 3628800.0f, 39916800.0f, 479001600.0f };
f32 Math_FactorialF(f32 n) {
f32 ret = 1.0f;
s32 i;
for (i = n; i > 1; i--) {
ret *= i;
}
return ret;
}
f32 Math_Factorial(s32 n) {
f32 ret;
s32 i;
if ((u32)n > 12U) {
ret = sFactorialTbl[12];
for (i = 13; i <= n; i++) {
ret *= i;
}
} else {
ret = sFactorialTbl[n];
}
return ret;
}
f32 Math_PowF(f32 base, s32 exp) {
f32 ret = 1.0f;
while (exp > 0) {
exp--;
ret *= base;
}
return ret;
}
f32 Math_SinF(f32 angle) {
return sins((s16)(angle * (32767.0f / M_PI))) * SHT_MINV;
}
f32 Math_CosF(f32 angle) {
return coss((s16)(angle * (32767.0f / M_PI))) * SHT_MINV;
}

2154
soh/src/code/sys_math3d.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,131 @@
#include "global.h"
static u16 sATan2Tbl[] = {
0x0000, 0x000A, 0x0014, 0x001F, 0x0029, 0x0033, 0x003D, 0x0047, 0x0051, 0x005C, 0x0066, 0x0070, 0x007A, 0x0084,
0x008F, 0x0099, 0x00A3, 0x00AD, 0x00B7, 0x00C2, 0x00CC, 0x00D6, 0x00E0, 0x00EA, 0x00F4, 0x00FF, 0x0109, 0x0113,
0x011D, 0x0127, 0x0131, 0x013C, 0x0146, 0x0150, 0x015A, 0x0164, 0x016F, 0x0179, 0x0183, 0x018D, 0x0197, 0x01A1,
0x01AC, 0x01B6, 0x01C0, 0x01CA, 0x01D4, 0x01DE, 0x01E9, 0x01F3, 0x01FD, 0x0207, 0x0211, 0x021B, 0x0226, 0x0230,
0x023A, 0x0244, 0x024E, 0x0258, 0x0262, 0x026D, 0x0277, 0x0281, 0x028B, 0x0295, 0x029F, 0x02A9, 0x02B4, 0x02BE,
0x02C8, 0x02D2, 0x02DC, 0x02E6, 0x02F0, 0x02FB, 0x0305, 0x030F, 0x0319, 0x0323, 0x032D, 0x0337, 0x0341, 0x034C,
0x0356, 0x0360, 0x036A, 0x0374, 0x037E, 0x0388, 0x0392, 0x039C, 0x03A7, 0x03B1, 0x03BB, 0x03C5, 0x03CF, 0x03D9,
0x03E3, 0x03ED, 0x03F7, 0x0401, 0x040C, 0x0416, 0x0420, 0x042A, 0x0434, 0x043E, 0x0448, 0x0452, 0x045C, 0x0466,
0x0470, 0x047A, 0x0484, 0x048E, 0x0499, 0x04A3, 0x04AD, 0x04B7, 0x04C1, 0x04CB, 0x04D5, 0x04DF, 0x04E9, 0x04F3,
0x04FD, 0x0507, 0x0511, 0x051B, 0x0525, 0x052F, 0x0539, 0x0543, 0x054D, 0x0557, 0x0561, 0x056B, 0x0575, 0x057F,
0x0589, 0x0593, 0x059D, 0x05A7, 0x05B1, 0x05BB, 0x05C5, 0x05CF, 0x05D9, 0x05E3, 0x05ED, 0x05F7, 0x0601, 0x060B,
0x0615, 0x061F, 0x0629, 0x0633, 0x063D, 0x0647, 0x0651, 0x065B, 0x0665, 0x066E, 0x0678, 0x0682, 0x068C, 0x0696,
0x06A0, 0x06AA, 0x06B4, 0x06BE, 0x06C8, 0x06D2, 0x06DC, 0x06E5, 0x06EF, 0x06F9, 0x0703, 0x070D, 0x0717, 0x0721,
0x072B, 0x0735, 0x073E, 0x0748, 0x0752, 0x075C, 0x0766, 0x0770, 0x077A, 0x0783, 0x078D, 0x0797, 0x07A1, 0x07AB,
0x07B5, 0x07BE, 0x07C8, 0x07D2, 0x07DC, 0x07E6, 0x07EF, 0x07F9, 0x0803, 0x080D, 0x0817, 0x0820, 0x082A, 0x0834,
0x083E, 0x0848, 0x0851, 0x085B, 0x0865, 0x086F, 0x0878, 0x0882, 0x088C, 0x0896, 0x089F, 0x08A9, 0x08B3, 0x08BD,
0x08C6, 0x08D0, 0x08DA, 0x08E3, 0x08ED, 0x08F7, 0x0901, 0x090A, 0x0914, 0x091E, 0x0927, 0x0931, 0x093B, 0x0944,
0x094E, 0x0958, 0x0961, 0x096B, 0x0975, 0x097E, 0x0988, 0x0992, 0x099B, 0x09A5, 0x09AE, 0x09B8, 0x09C2, 0x09CB,
0x09D5, 0x09DE, 0x09E8, 0x09F2, 0x09FB, 0x0A05, 0x0A0E, 0x0A18, 0x0A22, 0x0A2B, 0x0A35, 0x0A3E, 0x0A48, 0x0A51,
0x0A5B, 0x0A64, 0x0A6E, 0x0A77, 0x0A81, 0x0A8B, 0x0A94, 0x0A9E, 0x0AA7, 0x0AB1, 0x0ABA, 0x0AC4, 0x0ACD, 0x0AD7,
0x0AE0, 0x0AE9, 0x0AF3, 0x0AFC, 0x0B06, 0x0B0F, 0x0B19, 0x0B22, 0x0B2C, 0x0B35, 0x0B3F, 0x0B48, 0x0B51, 0x0B5B,
0x0B64, 0x0B6E, 0x0B77, 0x0B80, 0x0B8A, 0x0B93, 0x0B9D, 0x0BA6, 0x0BAF, 0x0BB9, 0x0BC2, 0x0BCB, 0x0BD5, 0x0BDE,
0x0BE7, 0x0BF1, 0x0BFA, 0x0C03, 0x0C0D, 0x0C16, 0x0C1F, 0x0C29, 0x0C32, 0x0C3B, 0x0C45, 0x0C4E, 0x0C57, 0x0C60,
0x0C6A, 0x0C73, 0x0C7C, 0x0C86, 0x0C8F, 0x0C98, 0x0CA1, 0x0CAB, 0x0CB4, 0x0CBD, 0x0CC6, 0x0CCF, 0x0CD9, 0x0CE2,
0x0CEB, 0x0CF4, 0x0CFD, 0x0D07, 0x0D10, 0x0D19, 0x0D22, 0x0D2B, 0x0D34, 0x0D3E, 0x0D47, 0x0D50, 0x0D59, 0x0D62,
0x0D6B, 0x0D74, 0x0D7D, 0x0D87, 0x0D90, 0x0D99, 0x0DA2, 0x0DAB, 0x0DB4, 0x0DBD, 0x0DC6, 0x0DCF, 0x0DD8, 0x0DE1,
0x0DEA, 0x0DF3, 0x0DFC, 0x0E05, 0x0E0F, 0x0E18, 0x0E21, 0x0E2A, 0x0E33, 0x0E3C, 0x0E45, 0x0E4E, 0x0E56, 0x0E5F,
0x0E68, 0x0E71, 0x0E7A, 0x0E83, 0x0E8C, 0x0E95, 0x0E9E, 0x0EA7, 0x0EB0, 0x0EB9, 0x0EC2, 0x0ECB, 0x0ED4, 0x0EDC,
0x0EE5, 0x0EEE, 0x0EF7, 0x0F00, 0x0F09, 0x0F12, 0x0F1B, 0x0F23, 0x0F2C, 0x0F35, 0x0F3E, 0x0F47, 0x0F50, 0x0F58,
0x0F61, 0x0F6A, 0x0F73, 0x0F7C, 0x0F84, 0x0F8D, 0x0F96, 0x0F9F, 0x0FA7, 0x0FB0, 0x0FB9, 0x0FC2, 0x0FCA, 0x0FD3,
0x0FDC, 0x0FE5, 0x0FED, 0x0FF6, 0x0FFF, 0x1007, 0x1010, 0x1019, 0x1021, 0x102A, 0x1033, 0x103B, 0x1044, 0x104D,
0x1055, 0x105E, 0x1067, 0x106F, 0x1078, 0x1080, 0x1089, 0x1092, 0x109A, 0x10A3, 0x10AB, 0x10B4, 0x10BC, 0x10C5,
0x10CE, 0x10D6, 0x10DF, 0x10E7, 0x10F0, 0x10F8, 0x1101, 0x1109, 0x1112, 0x111A, 0x1123, 0x112B, 0x1134, 0x113C,
0x1145, 0x114D, 0x1156, 0x115E, 0x1166, 0x116F, 0x1177, 0x1180, 0x1188, 0x1191, 0x1199, 0x11A1, 0x11AA, 0x11B2,
0x11BB, 0x11C3, 0x11CB, 0x11D4, 0x11DC, 0x11E4, 0x11ED, 0x11F5, 0x11FD, 0x1206, 0x120E, 0x1216, 0x121F, 0x1227,
0x122F, 0x1237, 0x1240, 0x1248, 0x1250, 0x1259, 0x1261, 0x1269, 0x1271, 0x127A, 0x1282, 0x128A, 0x1292, 0x129A,
0x12A3, 0x12AB, 0x12B3, 0x12BB, 0x12C3, 0x12CC, 0x12D4, 0x12DC, 0x12E4, 0x12EC, 0x12F4, 0x12FC, 0x1305, 0x130D,
0x1315, 0x131D, 0x1325, 0x132D, 0x1335, 0x133D, 0x1345, 0x134D, 0x1355, 0x135E, 0x1366, 0x136E, 0x1376, 0x137E,
0x1386, 0x138E, 0x1396, 0x139E, 0x13A6, 0x13AE, 0x13B6, 0x13BE, 0x13C6, 0x13CE, 0x13D6, 0x13DE, 0x13E6, 0x13ED,
0x13F5, 0x13FD, 0x1405, 0x140D, 0x1415, 0x141D, 0x1425, 0x142D, 0x1435, 0x143D, 0x1444, 0x144C, 0x1454, 0x145C,
0x1464, 0x146C, 0x1473, 0x147B, 0x1483, 0x148B, 0x1493, 0x149B, 0x14A2, 0x14AA, 0x14B2, 0x14BA, 0x14C1, 0x14C9,
0x14D1, 0x14D9, 0x14E0, 0x14E8, 0x14F0, 0x14F8, 0x14FF, 0x1507, 0x150F, 0x1516, 0x151E, 0x1526, 0x152D, 0x1535,
0x153D, 0x1544, 0x154C, 0x1554, 0x155B, 0x1563, 0x156B, 0x1572, 0x157A, 0x1581, 0x1589, 0x1591, 0x1598, 0x15A0,
0x15A7, 0x15AF, 0x15B7, 0x15BE, 0x15C6, 0x15CD, 0x15D5, 0x15DC, 0x15E4, 0x15EB, 0x15F3, 0x15FA, 0x1602, 0x1609,
0x1611, 0x1618, 0x1620, 0x1627, 0x162F, 0x1636, 0x163E, 0x1645, 0x164C, 0x1654, 0x165B, 0x1663, 0x166A, 0x1671,
0x1679, 0x1680, 0x1688, 0x168F, 0x1696, 0x169E, 0x16A5, 0x16AC, 0x16B4, 0x16BB, 0x16C2, 0x16CA, 0x16D1, 0x16D8,
0x16E0, 0x16E7, 0x16EE, 0x16F6, 0x16FD, 0x1704, 0x170B, 0x1713, 0x171A, 0x1721, 0x1728, 0x1730, 0x1737, 0x173E,
0x1745, 0x174C, 0x1754, 0x175B, 0x1762, 0x1769, 0x1770, 0x1778, 0x177F, 0x1786, 0x178D, 0x1794, 0x179B, 0x17A2,
0x17AA, 0x17B1, 0x17B8, 0x17BF, 0x17C6, 0x17CD, 0x17D4, 0x17DB, 0x17E2, 0x17E9, 0x17F0, 0x17F7, 0x17FE, 0x1806,
0x180D, 0x1814, 0x181B, 0x1822, 0x1829, 0x1830, 0x1837, 0x183E, 0x1845, 0x184C, 0x1853, 0x185A, 0x1860, 0x1867,
0x186E, 0x1875, 0x187C, 0x1883, 0x188A, 0x1891, 0x1898, 0x189F, 0x18A6, 0x18AD, 0x18B3, 0x18BA, 0x18C1, 0x18C8,
0x18CF, 0x18D6, 0x18DD, 0x18E3, 0x18EA, 0x18F1, 0x18F8, 0x18FF, 0x1906, 0x190C, 0x1913, 0x191A, 0x1921, 0x1928,
0x192E, 0x1935, 0x193C, 0x1943, 0x1949, 0x1950, 0x1957, 0x195D, 0x1964, 0x196B, 0x1972, 0x1978, 0x197F, 0x1986,
0x198C, 0x1993, 0x199A, 0x19A0, 0x19A7, 0x19AE, 0x19B4, 0x19BB, 0x19C2, 0x19C8, 0x19CF, 0x19D5, 0x19DC, 0x19E3,
0x19E9, 0x19F0, 0x19F6, 0x19FD, 0x1A04, 0x1A0A, 0x1A11, 0x1A17, 0x1A1E, 0x1A24, 0x1A2B, 0x1A31, 0x1A38, 0x1A3E,
0x1A45, 0x1A4B, 0x1A52, 0x1A58, 0x1A5F, 0x1A65, 0x1A6C, 0x1A72, 0x1A79, 0x1A7F, 0x1A86, 0x1A8C, 0x1A93, 0x1A99,
0x1A9F, 0x1AA6, 0x1AAC, 0x1AB3, 0x1AB9, 0x1AC0, 0x1AC6, 0x1ACC, 0x1AD3, 0x1AD9, 0x1ADF, 0x1AE6, 0x1AEC, 0x1AF2,
0x1AF9, 0x1AFF, 0x1B05, 0x1B0C, 0x1B12, 0x1B18, 0x1B1F, 0x1B25, 0x1B2B, 0x1B32, 0x1B38, 0x1B3E, 0x1B44, 0x1B4B,
0x1B51, 0x1B57, 0x1B5D, 0x1B64, 0x1B6A, 0x1B70, 0x1B76, 0x1B7D, 0x1B83, 0x1B89, 0x1B8F, 0x1B95, 0x1B9C, 0x1BA2,
0x1BA8, 0x1BAE, 0x1BB4, 0x1BBA, 0x1BC1, 0x1BC7, 0x1BCD, 0x1BD3, 0x1BD9, 0x1BDF, 0x1BE5, 0x1BEB, 0x1BF2, 0x1BF8,
0x1BFE, 0x1C04, 0x1C0A, 0x1C10, 0x1C16, 0x1C1C, 0x1C22, 0x1C28, 0x1C2E, 0x1C34, 0x1C3A, 0x1C40, 0x1C46, 0x1C4C,
0x1C52, 0x1C58, 0x1C5E, 0x1C64, 0x1C6A, 0x1C70, 0x1C76, 0x1C7C, 0x1C82, 0x1C88, 0x1C8E, 0x1C94, 0x1C9A, 0x1CA0,
0x1CA6, 0x1CAC, 0x1CB2, 0x1CB8, 0x1CBE, 0x1CC3, 0x1CC9, 0x1CCF, 0x1CD5, 0x1CDB, 0x1CE1, 0x1CE7, 0x1CED, 0x1CF3,
0x1CF8, 0x1CFE, 0x1D04, 0x1D0A, 0x1D10, 0x1D16, 0x1D1B, 0x1D21, 0x1D27, 0x1D2D, 0x1D33, 0x1D38, 0x1D3E, 0x1D44,
0x1D4A, 0x1D4F, 0x1D55, 0x1D5B, 0x1D61, 0x1D66, 0x1D6C, 0x1D72, 0x1D78, 0x1D7D, 0x1D83, 0x1D89, 0x1D8E, 0x1D94,
0x1D9A, 0x1DA0, 0x1DA5, 0x1DAB, 0x1DB1, 0x1DB6, 0x1DBC, 0x1DC2, 0x1DC7, 0x1DCD, 0x1DD3, 0x1DD8, 0x1DDE, 0x1DE3,
0x1DE9, 0x1DEF, 0x1DF4, 0x1DFA, 0x1DFF, 0x1E05, 0x1E0B, 0x1E10, 0x1E16, 0x1E1B, 0x1E21, 0x1E26, 0x1E2C, 0x1E32,
0x1E37, 0x1E3D, 0x1E42, 0x1E48, 0x1E4D, 0x1E53, 0x1E58, 0x1E5E, 0x1E63, 0x1E69, 0x1E6E, 0x1E74, 0x1E79, 0x1E7F,
0x1E84, 0x1E8A, 0x1E8F, 0x1E94, 0x1E9A, 0x1E9F, 0x1EA5, 0x1EAA, 0x1EB0, 0x1EB5, 0x1EBA, 0x1EC0, 0x1EC5, 0x1ECB,
0x1ED0, 0x1ED5, 0x1EDB, 0x1EE0, 0x1EE6, 0x1EEB, 0x1EF0, 0x1EF6, 0x1EFB, 0x1F00, 0x1F06, 0x1F0B, 0x1F10, 0x1F16,
0x1F1B, 0x1F20, 0x1F26, 0x1F2B, 0x1F30, 0x1F36, 0x1F3B, 0x1F40, 0x1F45, 0x1F4B, 0x1F50, 0x1F55, 0x1F5A, 0x1F60,
0x1F65, 0x1F6A, 0x1F6F, 0x1F75, 0x1F7A, 0x1F7F, 0x1F84, 0x1F8A, 0x1F8F, 0x1F94, 0x1F99, 0x1F9E, 0x1FA4, 0x1FA9,
0x1FAE, 0x1FB3, 0x1FB8, 0x1FBD, 0x1FC3, 0x1FC8, 0x1FCD, 0x1FD2, 0x1FD7, 0x1FDC, 0x1FE1, 0x1FE6, 0x1FEC, 0x1FF1,
0x1FF6, 0x1FFB, 0x2000,
};
u16 Math_GetAtan2Tbl(f32 x, f32 y) {
s32 tblIdx = ((x / y) * 1024.0f) + 0.5f;
u16 ret;
if (y == 0.0f) {
ret = sATan2Tbl[0];
} else if (tblIdx >= ARRAY_COUNT(sATan2Tbl)) {
ret = sATan2Tbl[0];
} else {
ret = sATan2Tbl[tblIdx];
}
return ret;
}
s16 Math_Atan2S(f32 x, f32 y) {
s32 ret;
if (y >= 0.0f) {
if (x >= 0.0f) {
if (y <= x) {
ret = Math_GetAtan2Tbl(y, x);
} else {
ret = 0x4000 - Math_GetAtan2Tbl(x, y);
}
} else {
if (-x < y) {
ret = Math_GetAtan2Tbl(-x, y) + 0x4000;
} else {
ret = 0x8000 - Math_GetAtan2Tbl(y, -x);
}
}
} else {
if (x < 0.0f) {
if (-y <= -x) {
ret = Math_GetAtan2Tbl(-y, -x) + 0x8000;
} else {
ret = 0xC000 - Math_GetAtan2Tbl(-x, -y);
}
} else {
if (x < -y) {
ret = Math_GetAtan2Tbl(x, -y) + 0xC000;
} else {
ret = -Math_GetAtan2Tbl(-y, x);
}
}
}
return ret;
}
f32 Math_Atan2F(f32 x, f32 y) {
return Math_Atan2S(x, y) * (M_PI / 32768.0f);
}

1035
soh/src/code/sys_matrix.c Normal file

File diff suppressed because it is too large Load diff

20
soh/src/code/sys_ucode.c Normal file
View file

@ -0,0 +1,20 @@
#include "global.h"
//uintptr_t D_8012DBA0 = (uintptr_t)&D_80155F50;
//uintptr_t D_8012DBA4 = (uintptr_t)&D_80157580;
uintptr_t SysUcode_GetUCodeBoot(void) {
//return &D_80009320;
}
uintptr_t SysUcode_GetUCodeBootSize(void) {
//return (uintptr_t)&D_800093F0 - (uintptr_t)&D_80009320;
}
uintptr_t SysUcode_GetUCode(void) {
//return D_8012DBA0;
}
uintptr_t SysUcode_GetUCodeData(void) {
//return D_8012DBA4;
}

View file

@ -0,0 +1,111 @@
#include "global.h"
#include <string.h>
#define LOG_SEVERITY_NOLOG 0
#define LOG_SEVERITY_ERROR 2
#define LOG_SEVERITY_VERBOSE 3
s32 gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
Arena gSystemArena;
void SystemArena_CheckPointer(void* ptr, size_t size, const char* name, const char* action) {
if (ptr == NULL) {
if (gSystemArenaLogSeverity >= LOG_SEVERITY_ERROR) {
// "%s: %u bytes %s failed\n"
osSyncPrintf("%s: %u バイトの%sに失敗しました\n", name, size, action);
__osDisplayArena(&gSystemArena);
return;
}
} else if (gSystemArenaLogSeverity >= LOG_SEVERITY_VERBOSE) {
// "%s: %u bytes %s succeeded\n"
osSyncPrintf("%s: %u バイトの%sに成功しました\n", name, size, action);
}
}
void* SystemArena_Malloc(size_t size) {
void* ptr = __osMalloc(&gSystemArena, size);
SystemArena_CheckPointer(ptr, size, "malloc", "確保"); // "Secure"
return ptr;
}
void* SystemArena_MallocDebug(size_t size, const char* file, s32 line) {
void* ptr = __osMallocDebug(&gSystemArena, size, file, line);
SystemArena_CheckPointer(ptr, size, "malloc_DEBUG", "確保"); // "Secure"
return ptr;
}
void* SystemArena_MallocR(size_t size) {
void* ptr = __osMallocR(&gSystemArena, size);
SystemArena_CheckPointer(ptr, size, "malloc_r", "確保"); // "Secure"
return ptr;
}
void* SystemArena_MallocRDebug(size_t size, const char* file, s32 line) {
void* ptr = __osMallocRDebug(&gSystemArena, size, file, line);
SystemArena_CheckPointer(ptr, size, "malloc_r_DEBUG", "確保"); // "Secure"
return ptr;
}
void* SystemArena_Realloc(void* ptr, size_t newSize) {
ptr = __osRealloc(&gSystemArena, ptr, newSize);
SystemArena_CheckPointer(ptr, newSize, "realloc", "再確保"); // "Re-securing"
return ptr;
}
void* SystemArena_ReallocDebug(void* ptr, size_t newSize, const char* file, s32 line) {
ptr = __osReallocDebug(&gSystemArena, ptr, newSize, file, line);
SystemArena_CheckPointer(ptr, newSize, "realloc_DEBUG", "再確保"); // "Re-securing"
return ptr;
}
void SystemArena_Free(void* ptr) {
__osFree(&gSystemArena, ptr);
}
void SystemArena_FreeDebug(void* ptr, const char* file, s32 line) {
__osFreeDebug(&gSystemArena, ptr, file, line);
}
void* SystemArena_Calloc(size_t num, size_t size) {
void* ret;
size_t n = num * size;
ret = __osMalloc(&gSystemArena, n);
if (ret != NULL) {
memset(ret, 0, n);
}
SystemArena_CheckPointer(ret, n, "calloc", "確保");
return ret;
}
void SystemArena_Display(void) {
osSyncPrintf("システムヒープ表示\n"); // "System heap display"
__osDisplayArena(&gSystemArena);
}
void SystemArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc) {
ArenaImpl_GetSizes(&gSystemArena, outMaxFree, outFree, outAlloc);
}
void SystemArena_Check(void) {
__osCheckArena(&gSystemArena);
}
void SystemArena_Init(void* start, size_t size) {
gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
__osMallocInit(&gSystemArena, start, size);
}
void SystemArena_Cleanup(void) {
gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
__osMallocCleanup(&gSystemArena);
}
u8 SystemArena_IsInitalized(void) {
return __osMallocIsInitalized(&gSystemArena);
}

View file

@ -0,0 +1,16 @@
#include "global.h"
void TitleSetup_InitImpl(GameState* gameState) {
osSyncPrintf("ゼルダ共通データ初期化\n"); // "Zelda common data initalization"
SaveContext_Init();
gameState->running = false;
SET_NEXT_GAMESTATE(gameState, Title_Init, TitleContext);
}
void TitleSetup_Destroy(GameState* gameState) {
}
void TitleSetup_Init(GameState* gameState) {
gameState->destroy = TitleSetup_Destroy;
TitleSetup_InitImpl(gameState);
}

1365
soh/src/code/ucode_disas.c Normal file

File diff suppressed because it is too large Load diff

111
soh/src/code/z_DLF.c Normal file
View file

@ -0,0 +1,111 @@
#include "global.h"
#include "vt.h"
void Overlay_LoadGameState(GameStateOverlay* overlayEntry) {
if (overlayEntry->loadedRamAddr != NULL) {
osSyncPrintf("既にリンクされています\n"); // "Already linked"
return;
}
if (overlayEntry->vramStart == 0) {
overlayEntry->unk_28 = 0;
} else {
overlayEntry->loadedRamAddr = Overlay_AllocateAndLoad(overlayEntry->vromStart, overlayEntry->vromEnd,
overlayEntry->vramStart, overlayEntry->vramEnd);
if (overlayEntry->loadedRamAddr == NULL) {
osSyncPrintf("ロードに失敗しました\n"); // "Loading failed"
return;
}
osSyncPrintf(VT_FGCOL(GREEN));
osSyncPrintf("OVL(d):Seg:%08x-%08x Ram:%08x-%08x Off:%08x %s\n", overlayEntry->vramStart, overlayEntry->vramEnd,
overlayEntry->loadedRamAddr,
(uintptr_t)overlayEntry->loadedRamAddr + (uintptr_t)overlayEntry->vramEnd - (uintptr_t)overlayEntry->vramStart,
(uintptr_t)overlayEntry->vramStart - (uintptr_t)overlayEntry->loadedRamAddr, "");
osSyncPrintf(VT_RST);
if (overlayEntry->unk_14 != NULL) {
overlayEntry->unk_14 = (void*)((uintptr_t)overlayEntry->unk_14 -
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->unk_14 = NULL;
}
if (overlayEntry->init != NULL) {
overlayEntry->init = (void*)((uintptr_t)overlayEntry->init -
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->init = NULL;
}
if (overlayEntry->destroy != NULL) {
overlayEntry->destroy = (void*)((uintptr_t)overlayEntry->destroy -
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->destroy = NULL;
}
if (overlayEntry->unk_20 != NULL) {
overlayEntry->unk_20 = (void*)((uintptr_t)overlayEntry->unk_20 -
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->unk_20 = NULL;
}
if (overlayEntry->unk_24 != NULL) {
overlayEntry->unk_24 = (void*)((uintptr_t)overlayEntry->unk_24 -
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->unk_24 = NULL;
}
overlayEntry->unk_28 = 0;
}
}
void Overlay_FreeGameState(GameStateOverlay* overlayEntry) {
if (overlayEntry->loadedRamAddr != NULL) {
s32 temp = overlayEntry->unk_28 != 0 ? -1 : 0;
if (temp == 0) {
if (overlayEntry->unk_14 != NULL) {
overlayEntry->unk_14 = (void*)((uintptr_t)overlayEntry->unk_14 +
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->unk_14 = NULL;
}
if (overlayEntry->init != NULL) {
overlayEntry->init = (void*)((uintptr_t)overlayEntry->init +
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->init = NULL;
}
if (overlayEntry->destroy != NULL) {
overlayEntry->destroy = (void*)((uintptr_t)overlayEntry->destroy +
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->destroy = NULL;
}
if (overlayEntry->unk_20 != NULL) {
overlayEntry->unk_20 = (void*)((uintptr_t)overlayEntry->unk_20 +
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->unk_20 = NULL;
}
if (overlayEntry->unk_24 != NULL) {
overlayEntry->unk_24 = (void*)((uintptr_t)overlayEntry->unk_24 +
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr));
} else {
overlayEntry->unk_24 = NULL;
}
SystemArena_FreeDebug(overlayEntry->loadedRamAddr, "../z_DLF.c", 149);
overlayEntry->loadedRamAddr = NULL;
}
}
}

5833
soh/src/code/z_actor.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
#include "global.h"
// Linker symbol declarations (used in the table below)
#define DEFINE_ACTOR(name, _1, _2) DECLARE_OVERLAY_SEGMENT(name)
#define DEFINE_ACTOR_INTERNAL(_0, _1, _2)
#define DEFINE_ACTOR_UNSET(_0)
#include "tables/actor_table.h"
#undef DEFINE_ACTOR
#undef DEFINE_ACTOR_INTERNAL
#undef DEFINE_ACTOR_UNSET
// Init Vars declarations (also used in the table below)
#define DEFINE_ACTOR(name, _1, _2) extern ActorInit name##_InitVars;
#define DEFINE_ACTOR_INTERNAL(name, _1, _2) extern ActorInit name##_InitVars;
#define DEFINE_ACTOR_UNSET(_0)
#include "tables/actor_table.h"
#undef DEFINE_ACTOR
#undef DEFINE_ACTOR_INTERNAL
#undef DEFINE_ACTOR_UNSET
// Actor Overlay Table definition
//#define DEFINE_ACTOR(name, _1, allocType) \
// { (uintptr_t)_ovl_##name##SegmentRomStart, \
// (uintptr_t)_ovl_##name##SegmentRomEnd, \
// _ovl_##name##SegmentStart, \
// _ovl_##name##SegmentEnd, \
// NULL, \
// &name##_InitVars, \
// #name, \
// allocType, \
// 0 },
#define DEFINE_ACTOR_INTERNAL(name, _1, allocType) { 0, 0, NULL, NULL, NULL, &name##_InitVars, #name, allocType, 0 },
#define DEFINE_ACTOR_UNSET(_0) { 0 },
#define DEFINE_ACTOR(name, _1, allocType) { 0, 0, NULL, NULL, NULL, &name##_InitVars, #name, allocType, 0 },
ActorOverlay gActorOverlayTable[] = {
#include "tables/actor_table.h"
};
#undef DEFINE_ACTOR
#undef DEFINE_ACTOR_INTERNAL
#undef DEFINE_ACTOR_UNSET
s32 gMaxActorId = 0;
static FaultClient sFaultClient;
void ActorOverlayTable_LogPrint(void) {
ActorOverlay* overlayEntry;
u32 i;
osSyncPrintf("actor_dlftbls %u\n", gMaxActorId);
osSyncPrintf("RomStart RomEnd SegStart SegEnd allocp profile segname\n");
for (i = 0, overlayEntry = &gActorOverlayTable[0]; i < (u32)gMaxActorId; i++, overlayEntry++) {
osSyncPrintf("%08x %08x %08x %08x %08x %08x %s\n", overlayEntry->vromStart, overlayEntry->vromEnd,
overlayEntry->vramStart, overlayEntry->vramEnd, overlayEntry->loadedRamAddr,
&overlayEntry->initInfo->id, overlayEntry->name != NULL ? overlayEntry->name : "?");
}
}
void ActorOverlayTable_FaultPrint(void* arg0, void* arg1) {
ActorOverlay* overlayEntry;
u32 overlaySize;
s32 i;
FaultDrawer_SetCharPad(-2, 0);
FaultDrawer_Printf("actor_dlftbls %u\n", gMaxActorId);
FaultDrawer_Printf("No. RamStart- RamEnd cn Name\n");
for (i = 0, overlayEntry = &gActorOverlayTable[0]; i < gMaxActorId; i++, overlayEntry++) {
overlaySize = (uintptr_t)overlayEntry->vramEnd - (uintptr_t)overlayEntry->vramStart;
if (overlayEntry->loadedRamAddr != NULL) {
FaultDrawer_Printf("%3d %08x-%08x %3d %s\n", i, overlayEntry->loadedRamAddr,
(uintptr_t)overlayEntry->loadedRamAddr + overlaySize, overlayEntry->numLoaded,
overlayEntry->name != NULL ? overlayEntry->name : "");
}
}
}
void ActorOverlayTable_Init(void) {
gMaxActorId = ACTOR_ID_MAX;
Fault_AddClient(&sFaultClient, ActorOverlayTable_FaultPrint, NULL, NULL);
}
void ActorOverlayTable_Cleanup(void) {
Fault_RemoveClient(&sFaultClient);
gMaxActorId = 0;
}

4522
soh/src/code/z_bgcheck.c Normal file

File diff suppressed because it is too large Load diff

8131
soh/src/code/z_camera.c Normal file

File diff suppressed because it is too large Load diff

2403
soh/src/code/z_camera_data.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,23 @@
#include "global.h"
void Gfx_DrawDListOpa(GlobalContext* globalCtx, Gfx* dlist) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_cheap_proc.c", 214);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_cheap_proc.c", 216),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, dlist);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_cheap_proc.c", 219);
}
void Gfx_DrawDListXlu(GlobalContext* globalCtx, Gfx* dlist) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_cheap_proc.c", 228);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_cheap_proc.c", 230),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, dlist);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_cheap_proc.c", 233);
}

View file

@ -0,0 +1,826 @@
#include "global.h"
static DamageTable sDamageTablePresets[] = {
{ {
// 0
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0xE),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0xF),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0xF),
/* Master sword */ DMG_ENTRY(2, 0xF),
/* Giant's Knife */ DMG_ENTRY(2, 0xF),
/* Fire arrow */ DMG_ENTRY(2, 0x2),
/* Ice arrow */ DMG_ENTRY(1, 0x0),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(2, 0x2),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(2, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 1 Used by En_Karebaba
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0xE),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0xF),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0xF),
/* Master sword */ DMG_ENTRY(2, 0xF),
/* Giant's Knife */ DMG_ENTRY(2, 0xF),
/* Fire arrow */ DMG_ENTRY(2, 0x2),
/* Ice arrow */ DMG_ENTRY(1, 0x0),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(2, 0x2),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(2, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 2 Used by En_St, En_Ssh
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(2, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x1),
/* Normal arrow */ DMG_ENTRY(2, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(2, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(4, 0x0),
/* Fire arrow */ DMG_ENTRY(4, 0x0),
/* Ice arrow */ DMG_ENTRY(4, 0x0),
/* Light arrow */ DMG_ENTRY(4, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(3, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(4, 0x0),
/* Kokiri jump */ DMG_ENTRY(2, 0x0),
/* Giant jump */ DMG_ENTRY(4, 0x0),
/* Master jump */ DMG_ENTRY(8, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 3
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(1, 0x0),
/* Hookshot */ DMG_ENTRY(1, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(1, 0x0),
/* Giant's Knife */ DMG_ENTRY(1, 0x0),
/* Fire arrow */ DMG_ENTRY(1, 0x0),
/* Ice arrow */ DMG_ENTRY(1, 0x0),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(1, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(1, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(1, 0x0),
/* Fire magic */ DMG_ENTRY(1, 0x0),
/* Ice magic */ DMG_ENTRY(1, 0x0),
/* Light magic */ DMG_ENTRY(1, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(2, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(2, 0x0),
/* Kokiri jump */ DMG_ENTRY(2, 0x0),
/* Giant jump */ DMG_ENTRY(2, 0x0),
/* Master jump */ DMG_ENTRY(2, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 4 Used by En_Dodojr
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(2, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(2, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(2, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(4, 0x0),
/* Fire arrow */ DMG_ENTRY(4, 0x0),
/* Ice arrow */ DMG_ENTRY(4, 0x0),
/* Light arrow */ DMG_ENTRY(4, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(4, 0x0),
/* Kokiri jump */ DMG_ENTRY(2, 0x0),
/* Giant jump */ DMG_ENTRY(4, 0x0),
/* Master jump */ DMG_ENTRY(8, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 5
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x1),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(1, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(1, 0x0),
/* Giant's Knife */ DMG_ENTRY(1, 0x0),
/* Fire arrow */ DMG_ENTRY(1, 0x0),
/* Ice arrow */ DMG_ENTRY(1, 0x3),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(1, 0x3),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(1, 0x0),
/* Master spin */ DMG_ENTRY(1, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 6
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(3, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(6, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(4, 0x0),
/* Hammer swing */ DMG_ENTRY(4, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(2, 0x0),
/* Master sword */ DMG_ENTRY(6, 0x0),
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(6, 0x0),
/* Ice arrow */ DMG_ENTRY(0, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 7
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(3, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(6, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(4, 0x0),
/* Hammer swing */ DMG_ENTRY(4, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(2, 0x0),
/* Master sword */ DMG_ENTRY(6, 0x0),
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(6, 0x0),
/* Ice arrow */ DMG_ENTRY(6, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(4, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 8
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(3, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(4, 0x0),
/* Hammer swing */ DMG_ENTRY(4, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(2, 0x0),
/* Master sword */ DMG_ENTRY(0, 0x0),
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(0, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(4, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 9 Used by En_Bubble
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(2, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(0, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(2, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(4, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(4, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(4, 0x0),
/* Kokiri jump */ DMG_ENTRY(2, 0x0),
/* Giant jump */ DMG_ENTRY(4, 0x0),
/* Master jump */ DMG_ENTRY(8, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 10
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(2, 0xE),
/* Boomerang */ DMG_ENTRY(0, 0x1),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0xF),
/* Master sword */ DMG_ENTRY(2, 0xF),
/* Giant's Knife */ DMG_ENTRY(2, 0xF),
/* Fire arrow */ DMG_ENTRY(2, 0x2),
/* Ice arrow */ DMG_ENTRY(2, 0x3),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(2, 0x2),
/* Ice magic */ DMG_ENTRY(2, 0x3),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(2, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 11 Used by En_Horse
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(0, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(0, 0x0),
/* Hammer swing */ DMG_ENTRY(0, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(9, 0x0),
/* Master sword */ DMG_ENTRY(0, 0x0),
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(0, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 12
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(4, 0x0),
/* Hammer swing */ DMG_ENTRY(4, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(2, 0x0),
/* Master sword */ DMG_ENTRY(4, 0x0),
/* Giant's Knife */ DMG_ENTRY(4, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(0, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(4, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 13
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x1),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(2, 0x0),
/* Fire arrow */ DMG_ENTRY(2, 0x2),
/* Ice arrow */ DMG_ENTRY(1, 0x0),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(2, 0x2),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(1, 0x0),
/* Master spin */ DMG_ENTRY(1, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 14 Used by En_Sw
/* Deku nut */ DMG_ENTRY(1, 0x0),
/* Deku stick */ DMG_ENTRY(2, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(2, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(2, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(4, 0x0),
/* Fire arrow */ DMG_ENTRY(4, 0x0),
/* Ice arrow */ DMG_ENTRY(4, 0x0),
/* Light arrow */ DMG_ENTRY(4, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(4, 0x0),
/* Kokiri jump */ DMG_ENTRY(2, 0x0),
/* Giant jump */ DMG_ENTRY(4, 0x0),
/* Master jump */ DMG_ENTRY(8, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 15 Used by En_Fd
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(0, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(0, 0x0),
/* Hammer swing */ DMG_ENTRY(0, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(0, 0x0),
/* Master sword */ DMG_ENTRY(0, 0x0),
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(0, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 16 Used by En_Fw
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(2, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(2, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(2, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(4, 0x0),
/* Fire arrow */ DMG_ENTRY(4, 0x0),
/* Ice arrow */ DMG_ENTRY(4, 0x0),
/* Light arrow */ DMG_ENTRY(4, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(4, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(4, 0x0),
/* Kokiri jump */ DMG_ENTRY(2, 0x0),
/* Giant jump */ DMG_ENTRY(4, 0x0),
/* Master jump */ DMG_ENTRY(8, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 17
/* Deku nut */ DMG_ENTRY(1, 0x0),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(1, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(1, 0x0),
/* Hookshot */ DMG_ENTRY(1, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(1, 0x0),
/* Giant's Knife */ DMG_ENTRY(1, 0x0),
/* Fire arrow */ DMG_ENTRY(1, 0x0),
/* Ice arrow */ DMG_ENTRY(1, 0x0),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(1, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(1, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(1, 0x0),
/* Fire magic */ DMG_ENTRY(1, 0x0),
/* Ice magic */ DMG_ENTRY(1, 0x0),
/* Light magic */ DMG_ENTRY(1, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 18
/* Deku nut */ DMG_ENTRY(1, 0x0),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(1, 0x0),
/* Boomerang */ DMG_ENTRY(1, 0x0),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(1, 0x0),
/* Hookshot */ DMG_ENTRY(1, 0x0),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(1, 0x0),
/* Giant's Knife */ DMG_ENTRY(1, 0x0),
/* Fire arrow */ DMG_ENTRY(1, 0x0),
/* Ice arrow */ DMG_ENTRY(1, 0x0),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(1, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(1, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(1, 0x0),
/* Fire magic */ DMG_ENTRY(1, 0x0),
/* Ice magic */ DMG_ENTRY(1, 0x0),
/* Light magic */ DMG_ENTRY(1, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 19
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(2, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x1),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0xF),
/* Master sword */ DMG_ENTRY(2, 0xF),
/* Giant's Knife */ DMG_ENTRY(2, 0xF),
/* Fire arrow */ DMG_ENTRY(2, 0x2),
/* Ice arrow */ DMG_ENTRY(2, 0x3),
/* Light arrow */ DMG_ENTRY(1, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(2, 0x2),
/* Ice magic */ DMG_ENTRY(2, 0x3),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(2, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 20
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(1, 0x0),
/* Explosive */ DMG_ENTRY(2, 0xF),
/* Boomerang */ DMG_ENTRY(0, 0xE),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(2, 0xD),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(2, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(2, 0x3),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(2, 0x3),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(2, 0x0),
/* Master spin */ DMG_ENTRY(2, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 21
/* Deku nut */ DMG_ENTRY(0, 0x1),
/* Deku stick */ DMG_ENTRY(1, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0xF),
/* Boomerang */ DMG_ENTRY(0, 0x1),
/* Normal arrow */ DMG_ENTRY(1, 0x0),
/* Hammer swing */ DMG_ENTRY(0, 0xF),
/* Hookshot */ DMG_ENTRY(0, 0x1),
/* Kokiri sword */ DMG_ENTRY(1, 0x0),
/* Master sword */ DMG_ENTRY(2, 0x0),
/* Giant's Knife */ DMG_ENTRY(2, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(2, 0x1),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(2, 0x1),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(1, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
{ {
// 22 Used by En_Du, En_Go, En_Ma1, En_Ma2, En_Ma3
/* Deku nut */ DMG_ENTRY(0, 0x0),
/* Deku stick */ DMG_ENTRY(0, 0x0),
/* Slingshot */ DMG_ENTRY(0, 0x0),
/* Explosive */ DMG_ENTRY(0, 0x0),
/* Boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(0, 0x0),
/* Hammer swing */ DMG_ENTRY(0, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Kokiri sword */ DMG_ENTRY(0, 0x0),
/* Master sword */ DMG_ENTRY(0, 0x0),
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(0, 0x0),
/* Ice arrow */ DMG_ENTRY(0, 0x0),
/* Light arrow */ DMG_ENTRY(0, 0x0),
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
/* Fire magic */ DMG_ENTRY(0, 0x0),
/* Ice magic */ DMG_ENTRY(0, 0x0),
/* Light magic */ DMG_ENTRY(0, 0x0),
/* Shield */ DMG_ENTRY(0, 0x0),
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
/* Giant spin */ DMG_ENTRY(0, 0x0),
/* Master spin */ DMG_ENTRY(0, 0x0),
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
/* Giant jump */ DMG_ENTRY(0, 0x0),
/* Master jump */ DMG_ENTRY(0, 0x0),
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* Hammer jump */ DMG_ENTRY(0, 0x0),
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
} },
};
// Gets the pointer to one of the 23 preset damage tables. Returns NULL if index is out of range.
DamageTable* DamageTable_Get(s32 index) {
if (!(0 <= index && index < ARRAY_COUNT(sDamageTablePresets))) {
osSyncPrintf("CollisionBtlTbl_get():インデックスオーバー\n"); // "Index over"
return NULL;
}
return &sDamageTablePresets[index];
}
// Sets all entries in the damage table to 0x00
void DamageTable_Clear(DamageTable* table) {
s32 i;
for (i = 0; i < 32; i++) {
table->table[i] = 0;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,23 @@
#include "global.h"
#include <string.h>
SaveContext gSaveContext;
u32 D_8015FA88;
u32 D_8015FA8C;
void SaveContext_Init(void) {
memset(&gSaveContext, 0, sizeof(gSaveContext));
D_8015FA88 = 0;
D_8015FA8C = 0;
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
gSaveContext.nextCutsceneIndex = 0xFFEF;
gSaveContext.cutsceneTrigger = 0;
gSaveContext.chamberCutsceneNum = 0;
gSaveContext.nextDayTime = 0xFFFF;
gSaveContext.skyboxTime = 0;
gSaveContext.dogIsLost = true;
gSaveContext.nextTransition = 0xFF;
gSaveContext.unk_13EE = 50;
}

608
soh/src/code/z_construct.c Normal file
View file

@ -0,0 +1,608 @@
#include "global.h"
#include <textures/do_action_static/do_action_static.h>
void func_80110990(GlobalContext* globalCtx) {
Map_Destroy(globalCtx);
}
void func_801109B0(GlobalContext* globalCtx) {
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
u32 parameterSize;
u16 doActionOffset;
u8 temp;
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
gSaveContext.unk_13E8 = gSaveContext.unk_13EA = 0;
View_Init(&interfaceCtx->view, globalCtx->state.gfxCtx);
interfaceCtx->unk_1FA = interfaceCtx->unk_261 = interfaceCtx->unk_1FC = 0;
interfaceCtx->unk_1EC = interfaceCtx->unk_1EE = interfaceCtx->unk_1F0 = 0;
interfaceCtx->unk_22E = 0;
interfaceCtx->unk_230 = 16;
interfaceCtx->unk_1F4 = 0.0f;
interfaceCtx->unk_228 = XREG(95);
interfaceCtx->minimapAlpha = 0;
interfaceCtx->unk_260 = 0;
interfaceCtx->unk_244 = interfaceCtx->aAlpha = interfaceCtx->bAlpha = interfaceCtx->cLeftAlpha =
interfaceCtx->cDownAlpha = interfaceCtx->cRightAlpha = interfaceCtx->healthAlpha = interfaceCtx->startAlpha =
interfaceCtx->magicAlpha = 0;
parameterSize = (uintptr_t)_parameter_staticSegmentRomEnd - (uintptr_t)_parameter_staticSegmentRomStart;
// "Permanent PARAMETER Segment = %x"
osSyncPrintf("常駐PARAMETERセグメント=%x\n", parameterSize);
interfaceCtx->parameterSegment = GameState_Alloc(&globalCtx->state, parameterSize, "../z_construct.c", 159);
osSyncPrintf("parameter->parameterSegment=%x\n", interfaceCtx->parameterSegment);
ASSERT(interfaceCtx->parameterSegment != NULL, "parameter->parameterSegment != NULL", "../z_construct.c", 161);
DmaMgr_SendRequest1(interfaceCtx->parameterSegment, (uintptr_t)_parameter_staticSegmentRomStart, parameterSize,
"../z_construct.c", 162);
interfaceCtx->doActionSegment = GameState_Alloc(&globalCtx->state, 0x480, "../z_construct.c", 166);
osSyncPrintf("DOアクション テクスチャ初期=%x\n", 0x480); // "DO Action Texture Initialization"
osSyncPrintf("parameter->do_actionSegment=%x\n", interfaceCtx->doActionSegment);
ASSERT(interfaceCtx->doActionSegment != NULL, "parameter->do_actionSegment != NULL", "../z_construct.c", 169);
if (gSaveContext.language == LANGUAGE_ENG) {
doActionOffset = 0;
} else if (gSaveContext.language == LANGUAGE_GER) {
doActionOffset = 0x2B80;
} else {
doActionOffset = 0x5700;
}
memcpy(interfaceCtx->doActionSegment, ResourceMgr_LoadTexByName(gAttackDoActionENGTex), 0x300);
//DmaMgr_SendRequest1(interfaceCtx->doActionSegment, (uintptr_t)_do_action_staticSegmentRomStart + doActionOffset, 0x300,
//"../z_construct.c", 174);
if (gSaveContext.language == LANGUAGE_ENG) {
doActionOffset = 0x480;
} else if (gSaveContext.language == LANGUAGE_GER) {
doActionOffset = 0x3000;
} else {
doActionOffset = 0x5B80;
}
memcpy(interfaceCtx->doActionSegment + 0x300, ResourceMgr_LoadTexByName(gReturnDoActionENGTex), 0x180);
//DmaMgr_SendRequest1(interfaceCtx->doActionSegment + 0x300, (uintptr_t)_do_action_staticSegmentRomStart + doActionOffset,
//0x180, "../z_construct.c", 178);
interfaceCtx->iconItemSegment = GameState_Alloc(&globalCtx->state, 0x4000, "../z_construct.c", 190);
// "Icon Item Texture Initialization = %x"
osSyncPrintf("アイコンアイテム テクスチャ初期=%x\n", 0x4000);
osSyncPrintf("parameter->icon_itemSegment=%x\n", interfaceCtx->iconItemSegment);
ASSERT(interfaceCtx->iconItemSegment != NULL, "parameter->icon_itemSegment != NULL", "../z_construct.c", 193);
osSyncPrintf("Register_Item[%x, %x, %x, %x]\n", gSaveContext.equips.buttonItems[0],
gSaveContext.equips.buttonItems[1], gSaveContext.equips.buttonItems[2],
gSaveContext.equips.buttonItems[3]);
if (gSaveContext.equips.buttonItems[0] < 0xF0) {
DmaMgr_SendRequest1(interfaceCtx->iconItemSegment,
_icon_item_staticSegmentRomStart + gSaveContext.equips.buttonItems[0] * 0x1000, 0x1000,
"../z_construct.c", 198);
} else if (gSaveContext.equips.buttonItems[0] != 0xFF) {
DmaMgr_SendRequest1(interfaceCtx->iconItemSegment,
_icon_item_staticSegmentRomStart + gSaveContext.equips.buttonItems[0] * 0x1000, 0x1000,
"../z_construct.c", 203);
}
if (gSaveContext.equips.buttonItems[1] < 0xF0) {
DmaMgr_SendRequest1(interfaceCtx->iconItemSegment + 0x1000,
_icon_item_staticSegmentRomStart + gSaveContext.equips.buttonItems[1] * 0x1000, 0x1000,
"../z_construct.c", 209);
}
if (gSaveContext.equips.buttonItems[2] < 0xF0) {
DmaMgr_SendRequest1(interfaceCtx->iconItemSegment + 0x2000,
_icon_item_staticSegmentRomStart + gSaveContext.equips.buttonItems[2] * 0x1000, 0x1000,
"../z_construct.c", 214);
}
if (gSaveContext.equips.buttonItems[3] < 0xF0) {
DmaMgr_SendRequest1(interfaceCtx->iconItemSegment + 0x3000,
_icon_item_staticSegmentRomStart + gSaveContext.equips.buttonItems[3] * 0x1000, 0x1000,
"../z_construct.c", 219);
}
osSyncPrintf("%d\n", ((void)0, gSaveContext.timer1State));
if ((gSaveContext.timer1State == 4) || (gSaveContext.timer1State == 8) || (gSaveContext.timer2State == 4) ||
(gSaveContext.timer2State == 10)) {
osSyncPrintf("restart_flag=%d\n", ((void)0, gSaveContext.respawnFlag));
if ((gSaveContext.respawnFlag == -1) || (gSaveContext.respawnFlag == 1)) {
if (gSaveContext.timer1State == 4) {
gSaveContext.timer1State = 1;
gSaveContext.timerX[0] = 140;
gSaveContext.timerY[0] = 80;
}
}
if ((gSaveContext.timer1State == 4) || (gSaveContext.timer1State == 8)) {
temp = 0;
} else {
temp = 1;
}
gSaveContext.timerX[temp] = 26;
if (gSaveContext.healthCapacity > 0xA0) {
gSaveContext.timerY[temp] = 54;
} else {
gSaveContext.timerY[temp] = 46;
}
}
if ((gSaveContext.timer1State >= 11) && (gSaveContext.timer1State < 16)) {
gSaveContext.timer1State = 0;
// "Timer Stop!!!!!!!!!!!!!!!!!!!!!!"
osSyncPrintf("タイマー停止!!!!!!!!!!!!!!!!!!!!! = %d\n", gSaveContext.timer1State);
}
osSyncPrintf("PARAMETER領域=%x\n", parameterSize + 0x5300); // "Parameter Area = %x"
HealthMeter_Init(globalCtx);
Map_Init(globalCtx);
interfaceCtx->unk_23C = interfaceCtx->unk_242 = 0;
R_ITEM_BTN_X(0) = B_BUTTON_X;
R_B_BTN_COLOR(0) = 255;
R_B_BTN_COLOR(1) = 30;
R_B_BTN_COLOR(2) = 30;
R_ITEM_ICON_X(0) = B_BUTTON_X;
R_ITEM_AMMO_X(0) = B_BUTTON_X + 2;
R_A_BTN_X = A_BUTTON_X;
R_A_ICON_X = A_BUTTON_X;
R_A_BTN_COLOR(0) = 0;
R_A_BTN_COLOR(1) = 200;
R_A_BTN_COLOR(2) = 50;
}
void Message_Init(GlobalContext* globalCtx) {
MessageContext* msgCtx = &globalCtx->msgCtx;
s32 pad;
Message_SetTables();
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_00;
msgCtx->msgMode = MSGMODE_NONE;
msgCtx->msgLength = 0;
msgCtx->textId = msgCtx->textboxEndType = msgCtx->choiceIndex = msgCtx->ocarinaAction = msgCtx->textUnskippable = 0;
msgCtx->textColorAlpha = 255;
View_Init(&msgCtx->view, globalCtx->state.gfxCtx);
msgCtx->textboxSegment = GameState_Alloc(&globalCtx->state, 0x2200, "../z_construct.c", 349);
osSyncPrintf("message->fukidashiSegment=%x\n", msgCtx->textboxSegment);
osSyncPrintf("吹き出しgame_alloc=%x\n", 0x2200); // "Textbox game_alloc=%x"
ASSERT(msgCtx->textboxSegment != NULL, "message->fukidashiSegment != NULL", "../z_construct.c", 352);
Font_LoadOrderedFont(&globalCtx->msgCtx.font);
YREG(31) = 0;
}
void func_80111070(void) {
YREG(8) = 10;
YREG(14) = 0;
YREG(15) = 0;
R_TEXTBOX_TEXWIDTH = 0;
R_TEXTBOX_TEXHEIGHT = 0;
R_TEXTBOX_WIDTH = 50;
R_TEXTBOX_HEIGHT = 0;
YREG(24) = -60;
YREG(25) = 13;
YREG(26) = 15;
YREG(27) = 41;
YREG(28) = 15;
YREG(32) = 265;
YREG(33) = 55;
YREG(34) = 0;
YREG(35) = 20;
YREG(36) = 0;
YREG(37) = 0;
YREG(38) = 0;
YREG(40) = 2;
YREG(41) = 1;
YREG(42) = 2;
YREG(43) = 1;
YREG(44) = 0;
YREG(45) = 236;
YREG(46) = 36;
YREG(47) = 0;
YREG(48) = -45;
YREG(49) = -48;
YREG(50) = 16;
YREG(51) = 22;
YREG(52) = -55;
YREG(53) = -53;
YREG(54) = 43;
YREG(55) = 47;
YREG(56) = -33;
YREG(57) = -42;
YREG(58) = -33;
YREG(59) = -37;
YREG(60) = 14;
YREG(61) = -2;
YREG(62) = -2;
YREG(63) = -18;
YREG(64) = -18;
YREG(67) = 0;
YREG(68) = 0;
YREG(69) = 0;
YREG(70) = 0;
R_TEXTBOX_ICON_XPOS = -6;
R_TEXTBOX_ICON_YPOS = 10;
YREG(73) = -8;
YREG(74) = 8;
R_TEXTBOX_ICON_SIZE = 24;
YREG(76) = 32;
YREG(77) = 0;
R_MESSAGE_DEBUGGER_SELECT = 0;
R_MESSAGE_DEBUGGER_TEXTID = 48;
YREG(80) = 450;
YREG(81) = 0;
YREG(82) = -15;
YREG(83) = 500;
YREG(84) = 600;
YREG(85) = 0;
YREG(86) = -21;
YREG(87) = 510;
R_C_UP_ICON_X = C_UP_BUTTON_X - 7;
R_C_UP_ICON_Y = C_UP_BUTTON_Y + 4;
YREG(92) = 8;
YREG(93) = 6;
YREG(94) = 3;
YREG(95) = 1;
R_MAGIC_FILL_COLOR(0) = 0;
R_MAGIC_FILL_COLOR(1) = 200;
R_MAGIC_FILL_COLOR(2) = 0;
ZREG(9) = 140;
ZREG(10) = 200;
ZREG(11) = 0;
ZREG(12) = 200;
ZREG(13) = 0;
ZREG(14) = 110;
ZREG(15) = 56;
ZREG(16) = 1;
ZREG(17) = -50;
ZREG(18) = -200;
ZREG(19) = 0;
ZREG(20) = 0;
ZREG(21) = 50;
ZREG(22) = -50;
ZREG(23) = 20;
ZREG(24) = 20;
ZREG(25) = 4;
ZREG(26) = 20;
ZREG(27) = 10;
ZREG(28) = 20;
ZREG(29) = 4;
ZREG(30) = 20;
ZREG(31) = 10;
ZREG(32) = 0;
ZREG(33) = 0;
ZREG(34) = 0;
ZREG(36) = 0;
ZREG(37) = 0;
ZREG(38) = 0;
R_C_BTN_COLOR(0) = 255;
R_C_BTN_COLOR(1) = 160;
R_C_BTN_COLOR(2) = 0;
ZREG(46) = 1;
ZREG(47) = 1;
R_START_LABEL_DD(0) = 100;
R_START_LABEL_DD(1) = 89;
R_START_LABEL_DD(2) = 92;
R_START_LABEL_Y(0) = 20;
R_START_LABEL_Y(1) = 20;
R_START_LABEL_Y(2) = 20;
R_START_LABEL_X(0) = 120;
R_START_LABEL_X(1) = 119;
R_START_LABEL_X(2) = 119;
ZREG(61) = 1;
R_C_UP_BTN_X = C_UP_BUTTON_X;
R_C_UP_BTN_Y = C_UP_BUTTON_Y;
ZREG(64) = 20;
ZREG(65) = 21;
ZREG(66) = 122;
R_ITEM_BTN_X(1) = C_LEFT_BUTTON_X;
R_ITEM_BTN_X(2) = C_DOWN_BUTTON_X;
R_ITEM_BTN_X(3) = C_RIGHT_BUTTON_X;
R_ITEM_BTN_Y(0) = B_BUTTON_Y;
R_ITEM_BTN_Y(1) = C_LEFT_BUTTON_Y;
R_ITEM_BTN_Y(2) = C_DOWN_BUTTON_Y;
R_ITEM_BTN_Y(3) = C_RIGHT_BUTTON_Y;
R_ITEM_BTN_DD(0) = 565;
R_ITEM_BTN_DD(1) = 606;
R_ITEM_BTN_DD(2) = 606;
R_ITEM_BTN_DD(3) = 606;
R_ITEM_ICON_X(1) = C_LEFT_BUTTON_X;
R_ITEM_ICON_X(2) = C_DOWN_BUTTON_X;
R_ITEM_ICON_X(3) = C_RIGHT_BUTTON_X;
R_ITEM_ICON_Y(0) = B_BUTTON_Y;
R_ITEM_ICON_Y(1) = C_LEFT_BUTTON_Y;
R_ITEM_ICON_Y(2) = C_DOWN_BUTTON_Y;
R_ITEM_ICON_Y(3) = C_RIGHT_BUTTON_Y;
R_ITEM_ICON_DD(0) = 550;
R_ITEM_ICON_DD(1) = 680;
R_ITEM_ICON_DD(2) = 680;
R_ITEM_ICON_DD(3) = 680;
ZREG(94) = 1;
ZREG(95) = 0;
XREG(0) = 26;
XREG(1) = 22;
XREG(2) = -11;
XREG(3) = -4;
XREG(4) = 3;
XREG(5) = 0;
XREG(6) = 2;
XREG(7) = 30;
XREG(8) = 10;
XREG(9) = 0;
XREG(10) = -9550;
XREG(11) = 9950;
XREG(12) = 68;
XREG(13) = 36;
XREG(14) = 4;
XREG(15) = 1;
R_A_BTN_Y = A_BUTTON_Y;
XREG(18) = -380;
R_A_ICON_Y = A_BUTTON_Y;
XREG(21) = 48;
XREG(25) = 0;
XREG(26) = 0;
XREG(27) = 0;
XREG(28) = 16;
XREG(29) = 50;
XREG(30) = 15;
XREG(31) = 8;
XREG(32) = 4;
XREG(33) = 2;
XREG(34) = 100;
XREG(35) = 7;
XREG(36) = 20;
XREG(37) = 10;
XREG(38) = 2;
XREG(39) = 140;
XREG(40) = 20;
XREG(41) = 300;
XREG(42) = 100;
XREG(43) = 70;
XREG(44) = 50;
XREG(45) = 36;
XREG(46) = 16;
XREG(47) = 8;
R_MAGIC_BAR_SMALL_Y = 34;
R_MAGIC_BAR_X = 18;
R_MAGIC_BAR_LARGE_Y = 42;
R_MAGIC_FILL_X = 26;
XREG(52) = 0;
XREG(53) = 1;
R_TEXT_INIT_XPOS = 65;
R_TEXT_INIT_YPOS = 60;
R_TEXT_LINE_SPACING = 16;
R_TEXT_CHAR_SCALE = 80;
XREG(58) = 80;
XREG(59) = 12;
R_TEXT_DROP_SHADOW_OFFSET = 1;
R_TEXTBOX_BG_YPOS = 3;
XREG(62) = 0;
XREG(63) = 100;
R_TEXTBOX_END_XPOS = 158;
R_TEXTBOX_END_YPOS = 102;
R_TEXT_CHOICE_XPOS = 48;
R_TEXT_CHOICE_YPOS(0) = 54;
R_TEXT_CHOICE_YPOS(1) = 70;
R_TEXT_CHOICE_YPOS(2) = 86;
XREG(70) = -300;
XREG(71) = 0;
R_TEXTBOX_X_TARGET = 54;
R_TEXTBOX_Y_TARGET = 48;
R_TEXTBOX_WIDTH_TARGET = 128;
R_TEXTBOX_HEIGHT_TARGET = 64;
R_TEXTBOX_TEXWIDTH_TARGET = 2048;
R_TEXTBOX_TEXHEIGHT_TARGET = 512;
XREG(78) = 96;
XREG(79) = 98;
XREG(80) = 0;
XREG(81) = 50;
XREG(82) = 25;
XREG(83) = 100;
XREG(84) = 100;
XREG(85) = 0;
XREG(86) = 0;
XREG(87) = 0;
XREG(88) = -50;
XREG(89) = -100;
XREG(90) = -500;
XREG(91) = 0;
XREG(92) = 100;
XREG(93) = 100;
XREG(94) = 160;
XREG(95) = 200;
WREG(2) = -6080;
WREG(3) = 9355;
WREG(4) = 8;
WREG(5) = 3;
WREG(6) = 8;
WREG(7) = 0;
WREG(8) = 100;
WREG(9) = 109;
WREG(10) = 151;
WREG(11) = 148;
WREG(12) = 23;
WREG(13) = 22;
WREG(14) = -380;
WREG(15) = -350;
WREG(16) = -175;
WREG(17) = 155;
WREG(18) = 10;
WREG(19) = 10;
WREG(20) = -50;
WREG(21) = -54;
WREG(22) = -32;
WREG(23) = -38;
WREG(24) = -36;
WREG(25) = 40;
WREG(26) = -40;
WREG(27) = 0;
WREG(28) = 0;
R_OW_MINIMAP_X = 238;
R_OW_MINIMAP_Y = 164;
R_MINIMAP_DISABLED = false;
WREG(32) = 122;
WREG(33) = 60;
WREG(35) = 0;
WREG(36) = 0;
WREG(37) = 100;
WREG(38) = 99;
WREG(39) = 109;
R_B_LABEL_X(0) = B_BUTTON_X - 9;
R_B_LABEL_X(1) = B_BUTTON_X - 11;
R_B_LABEL_X(2) = B_BUTTON_X - 12;
R_B_LABEL_Y(0) = B_BUTTON_Y + 6;
R_B_LABEL_Y(1) = B_BUTTON_Y + 5;
R_B_LABEL_Y(2) = B_BUTTON_Y + 5;
WREG(46) = -380;
WREG(47) = -360;
WREG(48) = -350;
WREG(49) = -48;
WREG(50) = 16;
WREG(51) = -62;
WREG(52) = 22;
WREG(53) = -84;
WREG(54) = 20;
WREG(55) = -53;
WREG(56) = 40;
WREG(57) = -64;
WREG(58) = 47;
WREG(59) = -84;
WREG(60) = 44;
WREG(61) = -42;
WREG(62) = 32;
WREG(63) = -45;
WREG(64) = -37;
WREG(65) = 30;
WREG(66) = -50;
R_DGN_MINIMAP_X = 204;
R_DGN_MINIMAP_Y = 140;
WREG(87) = 80;
WREG(88) = 70;
WREG(89) = 40;
WREG(90) = 320;
WREG(91) = 40;
WREG(92) = 3;
WREG(93) = 6;
WREG(94) = 3;
WREG(95) = 6;
if (gSaveContext.gameMode == 0) {
R_TEXTBOX_X = 52;
R_TEXTBOX_Y = 36;
VREG(2) = 214;
VREG(3) = 76;
VREG(4) = 304;
VREG(5) = 430;
VREG(6) = 1;
R_TEXTBOX_CLEF_XPOS = 78;
R_TEXTBOX_CLEF_YPOS = 166;
VREG(9) = 40;
R_COMPASS_SCALE_X = 32;
R_COMPASS_SCALE_Y = 32;
R_COMPASS_OFFSET_X = 110;
R_COMPASS_OFFSET_Y = -740;
R_MINIMAP_COLOR(0) = 0;
R_MINIMAP_COLOR(1) = 255;
R_MINIMAP_COLOR(2) = 255;
}
VREG(21) = 0;
VREG(22) = 0;
VREG(23) = 0;
VREG(24) = 0;
VREG(25) = 0;
VREG(26) = 0;
VREG(27) = 0;
R_OCARINA_NOTES_XPOS = 98;
R_OCARINA_NOTES_XPOS_OFFSET = 18;
VREG(30) = 0;
VREG(31) = 0;
VREG(32) = 0;
R_TEXT_ADJUST_COLOR_1_R = 70;
R_TEXT_ADJUST_COLOR_1_G = 255;
R_TEXT_ADJUST_COLOR_1_B = 80;
R_TEXT_ADJUST_COLOR_2_R = 70;
R_TEXT_ADJUST_COLOR_2_G = 255;
R_TEXT_ADJUST_COLOR_2_B = 80;
VREG(40) = 9;
VREG(42) = 250;
VREG(43) = 440;
VREG(44) = 10;
R_OCARINA_NOTES_YPOS(0) = 190;
R_OCARINA_NOTES_YPOS(1) = 184;
R_OCARINA_NOTES_YPOS(2) = 176;
R_OCARINA_NOTES_YPOS(3) = 172;
R_OCARINA_NOTES_YPOS(4) = 170;
VREG(50) = 30;
R_OCARINA_NOTES_YPOS_OFFSET = 0;
VREG(52) = -16;
VREG(53) = 230;
VREG(54) = 230;
VREG(55) = 120;
VREG(56) = -720;
VREG(57) = 255;
VREG(58) = 255;
VREG(59) = 255;
VREG(60) = 20;
VREG(61) = 100;
VREG(62) = 0;
VREG(63) = 10;
R_ITEM_AMMO_X(1) = C_LEFT_BUTTON_X + 1;
R_ITEM_AMMO_X(2) = C_DOWN_BUTTON_X + 1;
R_ITEM_AMMO_X(3) = C_RIGHT_BUTTON_X + 1;
R_ITEM_AMMO_Y(0) = B_BUTTON_Y + 18;
R_ITEM_AMMO_Y(1) = C_LEFT_BUTTON_Y + 17;
R_ITEM_AMMO_Y(2) = C_DOWN_BUTTON_Y + 17;
R_ITEM_AMMO_Y(3) = C_RIGHT_BUTTON_Y + 17;
VREG(72) = 0;
VREG(73) = 0;
VREG(74) = 0;
VREG(75) = 0;
R_ITEM_ICON_WIDTH(0) = 30;
R_ITEM_ICON_WIDTH(1) = 24;
R_ITEM_ICON_WIDTH(2) = 24;
R_ITEM_ICON_WIDTH(3) = 24;
R_ITEM_BTN_WIDTH(0) = 29;
R_ITEM_BTN_WIDTH(1) = 27;
R_ITEM_BTN_WIDTH(2) = 27;
R_ITEM_BTN_WIDTH(3) = 27;
VREG(84) = 0;
VREG(85) = 50;
VREG(86) = 0;
VREG(87) = 64;
VREG(88) = 66;
VREG(89) = 0;
VREG(90) = 126;
VREG(91) = 124;
VREG(92) = -63;
}
void func_80112098(GlobalContext* globalCtx) {
func_80111070();
}

252
soh/src/code/z_debug.c Normal file
View file

@ -0,0 +1,252 @@
#include "global.h"
typedef struct {
u8 x;
u8 y;
u8 colorId;
char text[0x15];
} PrintTextBuffer;
typedef struct {
u16 push;
u16 held;
} InputCombo;
GameInfo* gGameInfo;
s32 D_8015FA94; // no known symbols
PrintTextBuffer D_8015FA98[0x16];
s16 D_8011E0B0 = 0; // PrintTextBuffer index
Color_RGBA8 printTextColors[] = {
{ 255, 255, 32, 192 }, { 255, 150, 128, 192 }, { 128, 96, 0, 64 }, { 192, 128, 16, 128 },
{ 255, 192, 32, 128 }, { 230, 230, 220, 64 }, { 128, 150, 255, 128 }, { 128, 255, 32, 128 },
};
InputCombo inputCombos[REG_GROUPS] = {
{ BTN_L, BTN_CUP }, { BTN_L, BTN_CLEFT }, { BTN_L, BTN_CDOWN }, { BTN_L, BTN_A }, { BTN_R, BTN_CDOWN },
{ BTN_L, BTN_CRIGHT }, { BTN_L, BTN_R }, { BTN_L, BTN_DLEFT }, { BTN_L, BTN_DRIGHT }, { BTN_L, BTN_DUP },
{ BTN_L, BTN_B }, { BTN_L, BTN_Z }, { BTN_L, BTN_DDOWN }, { BTN_R, BTN_A }, { BTN_R, BTN_B },
{ BTN_R, BTN_Z }, { BTN_R, BTN_L }, { BTN_R, BTN_CUP }, { BTN_R, BTN_CRIGHT }, { BTN_R, BTN_DLEFT },
{ BTN_R, BTN_CLEFT }, { BTN_R, BTN_START }, { BTN_L, BTN_START }, { BTN_R, BTN_DRIGHT }, { BTN_R, BTN_DUP },
{ BTN_START, BTN_R }, { BTN_START, BTN_A }, { BTN_START, BTN_B }, { BTN_START, BTN_CRIGHT },
};
char regChar[] = " SOPQMYDUIZCNKXcsiWAVHGmnBdkb";
// initialize GameInfo
void func_800636C0(void) {
s32 i;
gGameInfo = (GameInfo*)SystemArena_MallocDebug(sizeof(GameInfo), "../z_debug.c", 260);
gGameInfo->regPage = 0;
gGameInfo->regGroup = 0;
gGameInfo->regCur = 0;
gGameInfo->dpadLast = 0;
gGameInfo->repeat = 0;
for (i = 0; i < ARRAY_COUNT(gGameInfo->data); i++) {
gGameInfo->data[i] = 0;
}
}
// Called when free movement is active.
// 8011D394 to enable camera debugger
void func_8006375C(s32 arg0, s32 arg1, const char* text) {
}
// Copy Camera Debugger Text
void func_8006376C(u8 x, u8 y, u8 colorId, const char* text) {
PrintTextBuffer* buf;
char* bufText;
s16 i;
buf = &D_8015FA98[D_8011E0B0];
if (D_8011E0B0 < 0x16) {
buf->x = x;
buf->y = y;
buf->colorId = colorId;
i = 0;
bufText = buf->text;
while ((*bufText++ = *text++)) {
if (i++ > 0x14) {
break;
}
}
*bufText = '\0';
D_8011E0B0++;
}
}
// Draw Text
void func_80063828(GfxPrint* printer) {
s32 i;
Color_RGBA8* color;
PrintTextBuffer* buffer;
char* text;
i = 0;
if (D_8011E0B0 > 0) {
do {
buffer = &D_8015FA98[i];
text = buffer->text;
color = &printTextColors[buffer->colorId];
GfxPrint_SetColor(printer, color->r, color->g, color->b, color->a);
GfxPrint_SetPos(printer, buffer->x, buffer->y);
GfxPrint_Printf(printer, "%s", text);
i += 1;
} while (i < D_8011E0B0);
}
}
// Edit REG
void func_8006390C(Input* input) {
s32 dpad;
s32 regGroup;
s32 increment;
InputCombo* input_combo;
s32 i;
if (!CVar_GetS32("gDebugEnabled", 0))
return;
regGroup = (gGameInfo->regGroup * REG_PAGES + gGameInfo->regPage) * REG_PER_PAGE - REG_PER_PAGE;
dpad = input->cur.button & (BTN_DUP | BTN_DLEFT | BTN_DRIGHT | BTN_DDOWN);
if (CHECK_BTN_ALL(input->cur.button, BTN_L) || CHECK_BTN_ALL(input->cur.button, BTN_R) ||
CHECK_BTN_ALL(input->cur.button, BTN_START)) {
input_combo = inputCombos;
for (i = 0; i < REG_GROUPS; i++) {
if (~(~input_combo->push | input->cur.button) || ~(~input_combo->held | input->press.button)) {
input_combo++;
} else {
break;
}
}
if (i < REG_GROUPS) {
if (i == gGameInfo->regGroup) {
gGameInfo->regPage = (gGameInfo->regPage + 1) % (REG_PAGES + 1);
return;
}
gGameInfo->regGroup = i;
gGameInfo->regPage = 0;
}
} else {
switch (gGameInfo->regPage - 1) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
if (dpad == gGameInfo->dpadLast) {
gGameInfo->repeat--;
if (gGameInfo->repeat < 0) {
gGameInfo->repeat = 1;
} else {
dpad ^= gGameInfo->dpadLast;
}
} else {
gGameInfo->repeat = 0x10;
gGameInfo->dpadLast = dpad;
}
increment = CHECK_BTN_ANY(dpad, BTN_DRIGHT) ? (CHECK_BTN_ALL(input->cur.button, BTN_A | BTN_B) ? 1000
: CHECK_BTN_ALL(input->cur.button, BTN_A) ? 100
: CHECK_BTN_ALL(input->cur.button, BTN_B) ? 10
: 1)
: CHECK_BTN_ANY(dpad, BTN_DLEFT) ? (CHECK_BTN_ALL(input->cur.button, BTN_A | BTN_B) ? -1000
: CHECK_BTN_ALL(input->cur.button, BTN_A) ? -100
: CHECK_BTN_ALL(input->cur.button, BTN_B) ? -10
: -1)
: 0;
gGameInfo->data[gGameInfo->regCur + regGroup] += increment;
if (CHECK_BTN_ANY(dpad, BTN_DUP)) {
gGameInfo->regCur--;
if (gGameInfo->regCur < 0) {
gGameInfo->regCur = REG_PER_PAGE - 1;
}
} else if (CHECK_BTN_ANY(dpad, BTN_DDOWN)) {
gGameInfo->regCur++;
if (gGameInfo->regCur >= REG_PER_PAGE) {
gGameInfo->regCur = 0;
}
}
if (iREG(0)) {
iREG(0) = 0;
func_800AA000(0, iREG(1), iREG(2), iREG(3));
}
}
}
}
// Draw Memory Viewer
void func_80063C04(GfxPrint* printer) {
s32 i;
s32 page = (gGameInfo->regPage * REG_PER_PAGE) - REG_PER_PAGE;
s32 regGroup = (gGameInfo->regGroup * REG_PAGES + gGameInfo->regPage) * REG_PER_PAGE - REG_PER_PAGE;
s32 pad;
char name[3];
if (!CVar_GetS32("gDebugEnabled", 0))
return;
// set up register name string
name[0] = 'R';
name[1] = regChar[gGameInfo->regGroup]; // r_group type char
name[2] = '\0';
GfxPrint_SetColor(printer, 0, 128, 128, 128);
for (i = 0; i != REG_PER_PAGE; i++) {
if (i == gGameInfo->regCur) {
GfxPrint_SetColor(printer, 0, 255, 255, 255);
}
GfxPrint_SetPos(printer, 3, i + 5);
GfxPrint_Printf(printer, "%s%02d%6d", &name, page + i, gGameInfo->data[i + regGroup]);
if (i == gGameInfo->regCur) {
GfxPrint_SetColor(printer, 0, 128, 128, 128);
}
}
}
void func_80063D7C(GraphicsContext* gfxCtx) {
Gfx* sp7C;
Gfx* sp78;
GfxPrint printer;
Gfx* tempRet;
if (!CVar_GetS32("gDebugEnabled", 0))
return;
OPEN_DISPS(gfxCtx, "../z_debug.c", 628);
GfxPrint_Init(&printer);
sp78 = POLY_OPA_DISP;
tempRet = Graph_GfxPlusOne(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, tempRet);
GfxPrint_Open(&printer, tempRet);
if ((OREG(0) == 1) || (OREG(0) == 8)) {
func_80063828(&printer);
}
if (gGameInfo->regPage != 0) {
func_80063C04(&printer);
}
D_8011E0B0 = 0;
sp7C = GfxPrint_Close(&printer);
gSPEndDisplayList(sp7C++);
Graph_BranchDlist(sp78, sp7C);
POLY_OPA_DISP = sp7C;
if (1) {}
CLOSE_DISPS(gfxCtx, "../z_debug.c", 664);
GfxPrint_Destroy(&printer);
}

View file

@ -0,0 +1,108 @@
#include "global.h"
#include "objects/gameplay_keep/gameplay_keep.h"
typedef struct {
/* 0x00 */ s16 drawType; // indicates which draw function to use when displaying the object
/* 0x04 */ void* drawArg; // segment address (display list or texture) passed to the draw function when called
} DebugDispObjectInfo; // size = 0x8
typedef void (*DebugDispObject_DrawFunc)(DebugDispObject*, void*, GlobalContext*);
void DebugDisplay_DrawSpriteI8(DebugDispObject* dispObj, void* texture, GlobalContext* globalCtx);
void DebugDisplay_DrawPolygon(DebugDispObject* dispObj, void* dlist, GlobalContext* globalCtx);
static DebugDispObject_DrawFunc sDebugObjectDrawFuncTable[] = {
DebugDisplay_DrawSpriteI8,
DebugDisplay_DrawPolygon,
};
static DebugDispObjectInfo sDebugObjectInfoTable[] = {
{ 0, gDebugCircleTex }, { 0, gDebugCrossTex }, { 0, gDebugBallTex },
{ 0, gDebugCursorTex }, { 1, gDebugArrowDL }, { 1, gDebugCameraDL },
};
static Lights1 sDebugObjectLights = gdSPDefLights1(0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49);
static DebugDispObject* sDebugObjectListHead;
void DebugDisplay_Init(void) {
sDebugObjectListHead = NULL;
}
DebugDispObject* DebugDisplay_AddObject(f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, f32 scaleX,
f32 scaleY, f32 scaleZ, u8 red, u8 green, u8 blue, u8 alpha, s16 type,
GraphicsContext* gfxCtx) {
DebugDispObject* prevHead = sDebugObjectListHead;
sDebugObjectListHead = Graph_Alloc(gfxCtx, sizeof(DebugDispObject));
sDebugObjectListHead->pos.x = posX;
sDebugObjectListHead->pos.y = posY;
sDebugObjectListHead->pos.z = posZ;
sDebugObjectListHead->rot.x = rotX;
sDebugObjectListHead->rot.y = rotY;
sDebugObjectListHead->rot.z = rotZ;
sDebugObjectListHead->scale.x = scaleX;
sDebugObjectListHead->scale.y = scaleY;
sDebugObjectListHead->scale.z = scaleZ;
sDebugObjectListHead->color.r = red;
sDebugObjectListHead->color.g = green;
sDebugObjectListHead->color.b = blue;
sDebugObjectListHead->color.a = alpha;
sDebugObjectListHead->type = type;
sDebugObjectListHead->next = prevHead;
return sDebugObjectListHead;
}
void DebugDisplay_DrawObjects(GlobalContext* globalCtx) {
DebugDispObject* dispObj = sDebugObjectListHead;
DebugDispObjectInfo* objInfo;
while (dispObj != NULL) {
objInfo = &sDebugObjectInfoTable[dispObj->type];
sDebugObjectDrawFuncTable[objInfo->drawType](dispObj, objInfo->drawArg, globalCtx);
dispObj = dispObj->next;
}
}
void DebugDisplay_DrawSpriteI8(DebugDispObject* dispObj, void* texture, GlobalContext* globalCtx) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_debug_display.c", 169);
func_80094678(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a);
Matrix_Translate(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, MTXMODE_NEW);
Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, MTXMODE_APPLY);
Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY);
Matrix_RotateZYX(dispObj->rot.x, dispObj->rot.y, dispObj->rot.z, MTXMODE_APPLY);
gDPLoadTextureBlock(POLY_XLU_DISP++, texture, G_IM_FMT_I, G_IM_SIZ_8b, 16, 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_debug_display.c", 189),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, gDebugSpriteDL);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_debug_display.c", 192);
}
void DebugDisplay_DrawPolygon(DebugDispObject* dispObj, void* dlist, GlobalContext* globalCtx) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_debug_display.c", 211);
func_8009435C(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a);
gSPSetLights1(POLY_XLU_DISP++, sDebugObjectLights);
Matrix_SetTranslateRotateYXZ(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, &dispObj->rot);
Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_debug_display.c", 228),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, dlist);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_debug_display.c", 231);
}

2114
soh/src/code/z_demo.c Normal file

File diff suppressed because it is too large Load diff

881
soh/src/code/z_draw.c Normal file
View file

@ -0,0 +1,881 @@
#include "global.h"
#include "objects/object_gi_key/object_gi_key.h"
#include "objects/object_gi_jewel/object_gi_jewel.h"
#include "objects/object_gi_melody/object_gi_melody.h"
#include "objects/object_gi_heart/object_gi_heart.h"
#include "objects/object_gi_compass/object_gi_compass.h"
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
#include "objects/object_gi_medal/object_gi_medal.h"
#include "objects/object_gi_nuts/object_gi_nuts.h"
#include "objects/object_gi_hearts/object_gi_hearts.h"
#include "objects/object_gi_arrowcase/object_gi_arrowcase.h"
#include "objects/object_gi_bombpouch/object_gi_bombpouch.h"
#include "objects/object_gi_bottle/object_gi_bottle.h"
#include "objects/object_gi_stick/object_gi_stick.h"
#include "objects/object_gi_map/object_gi_map.h"
#include "objects/object_gi_shield_1/object_gi_shield_1.h"
#include "objects/object_gi_magicpot/object_gi_magicpot.h"
#include "objects/object_gi_bomb_1/object_gi_bomb_1.h"
#include "objects/object_gi_purse/object_gi_purse.h"
#include "objects/object_gi_gerudo/object_gi_gerudo.h"
#include "objects/object_gi_arrow/object_gi_arrow.h"
#include "objects/object_gi_bomb_2/object_gi_bomb_2.h"
#include "objects/object_gi_egg/object_gi_egg.h"
#include "objects/object_gi_scale/object_gi_scale.h"
#include "objects/object_gi_shield_2/object_gi_shield_2.h"
#include "objects/object_gi_hookshot/object_gi_hookshot.h"
#include "objects/object_gi_ocarina/object_gi_ocarina.h"
#include "objects/object_gi_milk/object_gi_milk.h"
#include "objects/object_gi_pachinko/object_gi_pachinko.h"
#include "objects/object_gi_boomerang/object_gi_boomerang.h"
#include "objects/object_gi_bow/object_gi_bow.h"
#include "objects/object_gi_glasses/object_gi_glasses.h"
#include "objects/object_gi_liquid/object_gi_liquid.h"
#include "objects/object_gi_shield_3/object_gi_shield_3.h"
#include "objects/object_gi_letter/object_gi_letter.h"
#include "objects/object_gi_clothes/object_gi_clothes.h"
#include "objects/object_gi_bean/object_gi_bean.h"
#include "objects/object_gi_fish/object_gi_fish.h"
#include "objects/object_gi_saw/object_gi_saw.h"
#include "objects/object_gi_hammer/object_gi_hammer.h"
#include "objects/object_gi_grass/object_gi_grass.h"
#include "objects/object_gi_longsword/object_gi_longsword.h"
#include "objects/object_gi_niwatori/object_gi_niwatori.h"
#include "objects/object_gi_bottle_letter/object_gi_bottle_letter.h"
#include "objects/object_gi_ocarina_0/object_gi_ocarina_0.h"
#include "objects/object_gi_boots_2/object_gi_boots_2.h"
#include "objects/object_gi_seed/object_gi_seed.h"
#include "objects/object_gi_gloves/object_gi_gloves.h"
#include "objects/object_gi_coin/object_gi_coin.h"
#include "objects/object_gi_ki_tan_mask/object_gi_ki_tan_mask.h"
#include "objects/object_gi_redead_mask/object_gi_redead_mask.h"
#include "objects/object_gi_skj_mask/object_gi_skj_mask.h"
#include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h"
#include "objects/object_gi_truth_mask/object_gi_truth_mask.h"
#include "objects/object_gi_eye_lotion/object_gi_eye_lotion.h"
#include "objects/object_gi_powder/object_gi_powder.h"
#include "objects/object_gi_mushroom/object_gi_mushroom.h"
#include "objects/object_gi_ticketstone/object_gi_ticketstone.h"
#include "objects/object_gi_brokensword/object_gi_brokensword.h"
#include "objects/object_gi_prescription/object_gi_prescription.h"
#include "objects/object_gi_bracelet/object_gi_bracelet.h"
#include "objects/object_gi_soldout/object_gi_soldout.h"
#include "objects/object_gi_frog/object_gi_frog.h"
#include "objects/object_gi_golonmask/object_gi_golonmask.h"
#include "objects/object_gi_zoramask/object_gi_zoramask.h"
#include "objects/object_gi_gerudomask/object_gi_gerudomask.h"
#include "objects/object_gi_hoverboots/object_gi_hoverboots.h"
#include "objects/object_gi_m_arrow/object_gi_m_arrow.h"
#include "objects/object_gi_sutaru/object_gi_sutaru.h"
#include "objects/object_gi_goddess/object_gi_goddess.h"
#include "objects/object_gi_fire/object_gi_fire.h"
#include "objects/object_gi_insect/object_gi_insect.h"
#include "objects/object_gi_butterfly/object_gi_butterfly.h"
#include "objects/object_gi_ghost/object_gi_ghost.h"
#include "objects/object_gi_soul/object_gi_soul.h"
#include "objects/object_gi_dekupouch/object_gi_dekupouch.h"
#include "objects/object_gi_rupy/object_gi_rupy.h"
#include "objects/object_gi_sword_1/object_gi_sword_1.h"
#include "objects/object_st/object_st.h"
// "Get Item" Model Draw Functions
void GetItem_DrawMaskOrBombchu(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawSoldOut(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawBlueFire(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawPoes(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawFairy(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawMirrorShield(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawSkullToken(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawEggOrMedallion(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawCompass(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawPotion(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawGoronSword(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawDekuNuts(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawRecoveryHeart(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawFish(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawOpa0(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawOpa0Xlu1(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawXlu01(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawOpa10Xlu2(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawMagicArrow(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawMagicSpell(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawOpa1023(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawOpa10Xlu32(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawSmallRupee(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawScale(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawBulletBag(GlobalContext* globalCtx, s16 drawId);
void GetItem_DrawWallet(GlobalContext* globalCtx, s16 drawId);
typedef struct {
/* 0x00 */ void (*drawFunc)(GlobalContext*, s16);
/* 0x04 */ Gfx* dlists[8];
} DrawItemTableEntry; // size = 0x24
DrawItemTableEntry sDrawItemTable[] = {
// bottle, OBJECT_GI_BOTTLE
{ GetItem_DrawOpa0Xlu1, { gGiBottleStopperDL, gGiBottleDL } },
// small key, OBJECT_GI_KEY
{ GetItem_DrawOpa0, { gGiSmallKeyDL } },
// minuet of forest, OBJECT_GI_MELODY
{ GetItem_DrawXlu01, { gGiMinuetColorDL, gGiSongNoteDL } },
// bolero of fire, OBJECT_GI_MELODY
{ GetItem_DrawXlu01, { gGiBoleroColorDL, gGiSongNoteDL } },
// serenade of water, OBJECT_GI_MELODY
{ GetItem_DrawXlu01, { gGiSerenadeColorDL, gGiSongNoteDL } },
// requiem of spirit, OBJECT_GI_MELODY
{ GetItem_DrawXlu01, { gGiRequiemColorDL, gGiSongNoteDL } },
// nocturne of shadow, OBJECT_GI_MELODY
{ GetItem_DrawXlu01, { gGiNocturneColorDL, gGiSongNoteDL } },
// prelude of light, OBJECT_GI_MELODY
{ GetItem_DrawXlu01, { gGiPreludeColorDL, gGiSongNoteDL } },
// recovery heart, OBJECT_GI_HEART
{ GetItem_DrawRecoveryHeart, { gGiRecoveryHeartDL } },
// boss key, OBJECT_GI_BOSSKEY
{ GetItem_DrawOpa0Xlu1, { gGiBossKeyDL, gGiBossKeyGemDL } },
// compass, OBJECT_GI_COMPASS
{ GetItem_DrawCompass, { gGiCompassDL, gGiCompassGlassDL } },
// forest medallion, OBJECT_GI_MEDAL
{ GetItem_DrawEggOrMedallion, { gGiForestMedallionFaceDL, gGiMedallionDL } },
// fire medallion, OBJECT_GI_MEDAL
{ GetItem_DrawEggOrMedallion, { gGiFireMedallionFaceDL, gGiMedallionDL } },
// water medallion, OBJECT_GI_MEDAL
{ GetItem_DrawEggOrMedallion, { gGiWaterMedallionFaceDL, gGiMedallionDL } },
// spirit medallion, OBJECT_GI_MEDAL
{ GetItem_DrawEggOrMedallion, { gGiSpiritMedallionFaceDL, gGiMedallionDL } },
// shadow medallion, OBJECT_GI_MEDAL
{ GetItem_DrawEggOrMedallion, { gGiShadowMedallionFaceDL, gGiMedallionDL } },
// light medallion, OBJECT_GI_MEDAL
{ GetItem_DrawEggOrMedallion, { gGiLightMedallionFaceDL, gGiMedallionDL } },
// deku nuts, OBJECT_GI_NUTS
{ GetItem_DrawDekuNuts, { gGiNutDL } },
// heart container, OBJECT_GI_HEARTS
{ GetItem_DrawXlu01, { gGiHeartBorderDL, gGiHeartContainerDL } },
// heart piece, OBJECT_GI_HEARTS
{ GetItem_DrawXlu01, { gGiHeartBorderDL, gGiHeartPieceDL } },
// quiver 30, OBJECT_GI_ARROWCASE
{ GetItem_DrawOpa1023, { gGiQuiverInnerDL, gGiQuiver30InnerColorDL, gGiQuiver30OuterColorDL, gGiQuiverOuterDL } },
// quiver 40, OBJECT_GI_ARROWCASE
{ GetItem_DrawOpa1023, { gGiQuiverInnerDL, gGiQuiver40InnerColorDL, gGiQuiver40OuterColorDL, gGiQuiverOuterDL } },
// quiver 50, OBJECT_GI_ARROWCASE
{ GetItem_DrawOpa1023, { gGiQuiverInnerDL, gGiQuiver50InnerColorDL, gGiQuiver50OuterColorDL, gGiQuiverOuterDL } },
// bomb bag 20, OBJECT_GI_BOMBPOUCH
{ GetItem_DrawOpa1023, { gGiBombBagDL, gGiBombBag20BagColorDL, gGiBombBag20RingColorDL, gGiBombBagRingDL } },
// bomb bag 30, OBJECT_GI_BOMBPOUCH
{ GetItem_DrawOpa1023, { gGiBombBagDL, gGiBombBag30BagColorDL, gGiBombBag30RingColorDL, gGiBombBagRingDL } },
// bomb bag 40, OBJECT_GI_BOMBPOUCH
{ GetItem_DrawOpa1023, { gGiBombBagDL, gGiBombBag40BagColorDL, gGiBombBag40RingColorDL, gGiBombBagRingDL } },
// stick, OBJECT_GI_STICK
{ GetItem_DrawOpa0, { gGiStickDL } },
// dungeon map, OBJECT_GI_MAP
{ GetItem_DrawOpa0, { gGiDungeonMapDL } },
// deku shield, OBJECT_GI_SHIELD_1
{ GetItem_DrawOpa0, { gGiDekuShieldDL } },
// small magic jar, OBJECT_GI_MAGICPOT
{ GetItem_DrawOpa0, { gGiMagicJarSmallDL } },
// large magic jar, OBJECT_GI_MAGICPOT
{ GetItem_DrawOpa0, { gGiMagicJarLargeDL } },
// bombs, OBJECT_GI_BOMB_1
{ GetItem_DrawOpa0, { gGiBombDL } },
// stone of agony, OBJECT_GI_MAP
{ GetItem_DrawOpa0, { gGiStoneOfAgonyDL } },
// adult's wallet, OBJECT_GI_PURSE
{ GetItem_DrawWallet,
{ gGiWalletDL, gGiAdultWalletColorDL, gGiAdultWalletRupeeOuterColorDL, gGiWalletRupeeOuterDL,
gGiAdultWalletStringColorDL, gGiWalletStringDL, gGiAdultWalletRupeeInnerColorDL, gGiWalletRupeeInnerDL } },
// giant's wallet, OBJECT_GI_PURSE
{ GetItem_DrawWallet,
{ gGiWalletDL, gGiGiantsWalletColorDL, gGiGiantsWalletRupeeOuterColorDL, gGiWalletRupeeOuterDL,
gGiGiantsWalletStringColorDL, gGiWalletStringDL, gGiGiantsWalletRupeeInnerColorDL, gGiWalletRupeeInnerDL } },
// gerudo card, OBJECT_GI_GERUDO
{ GetItem_DrawOpa0, { gGiGerudoCardDL } },
// arrows (small), OBJECT_GI_ARROW
{ GetItem_DrawOpa0, { gGiArrowSmallDL } },
// arrows (medium), OBJECT_GI_ARROW
{ GetItem_DrawOpa0, { gGiArrowMediumDL } },
// arrows (large), OBJECT_GI_ARROW
{ GetItem_DrawOpa0, { gGiArrowLargeDL } },
// bombchus, OBJECT_GI_BOMB_2
{ GetItem_DrawMaskOrBombchu, { gGiBombchuDL } },
// egg, OBJECT_GI_EGG
{ GetItem_DrawEggOrMedallion, { gGiEggMaterialDL, gGiEggDL } },
// silver scale, OBJECT_GI_SCALE
{ GetItem_DrawScale, { gGiScaleWaterDL, gGiSilverScaleWaterColorDL, gGiSilverScaleColorDL, gGiScaleDL } },
// gold scale, OBJECT_GI_SCALE
{ GetItem_DrawScale, { gGiScaleWaterDL, gGiGoldenScaleWaterColorDL, gGiGoldenScaleColorDL, gGiScaleDL } },
// hylian shield, OBJECT_GI_SHIELD_2
{ GetItem_DrawOpa0, { gGiHylianShieldDL } },
// hookshot, OBJECT_GI_HOOKSHOT
{ GetItem_DrawOpa0, { gGiHookshotDL } },
// longshot, OBJECT_GI_HOOKSHOT
{ GetItem_DrawOpa0, { gGiLongshotDL } },
// ocarina of time, OBJECT_GI_OCARINA
{ GetItem_DrawOpa0Xlu1, { gGiOcarinaTimeDL, gGiOcarinaTimeHolesDL } },
// milk, OBJECT_GI_MILK
{ GetItem_DrawOpa0Xlu1, { gGiMilkBottleContentsDL, gGiMilkBottleDL } },
// keaton mask, OBJECT_GI_KI_TAN_MASK
{ GetItem_DrawOpa0Xlu1, { gGiKeatonMaskDL, gGiKeatonMaskEyesDL } },
// spooky mask, OBJECT_GI_REDEAD_MASK
{ GetItem_DrawOpa0, { gGiSpookyMaskDL } },
// slingshot, OBJECT_GI_PACHINKO
{ GetItem_DrawOpa0, { gGiSlingshotDL } },
// boomerang, OBJECT_GI_BOOMERANG
{ GetItem_DrawOpa0, { gGiBoomerangDL } },
// bow, OBJECT_GI_BOW
{ GetItem_DrawOpa0, { gGiBowDL } },
// lens, OBJECT_GI_GLASSES
{ GetItem_DrawOpa0Xlu1, { gGiLensDL, gGiLensGlassDL } },
// green potion, OBJECT_GI_LIQUID
{ GetItem_DrawPotion,
{ gGiPotionPotDL, gGiGreenPotColorDL, gGiGreenLiquidColorDL, gGiPotionLiquidDL, gGiGreenPatternColorDL,
gGiPotionPatternDL } },
// red potion, OBJECT_GI_LIQUID
{ GetItem_DrawPotion,
{ gGiPotionPotDL, gGiRedPotColorDL, gGiRedLiquidColorDL, gGiPotionLiquidDL, gGiRedPatternColorDL,
gGiPotionPatternDL } },
// blue potion, OBJECT_GI_LIQUID
{ GetItem_DrawPotion,
{ gGiPotionPotDL, gGiBluePotColorDL, gGiBlueLiquidColorDL, gGiPotionLiquidDL, gGiBluePatternColorDL,
gGiPotionPatternDL } },
// mirror shield, OBJECT_GI_SHIELD_3
{ GetItem_DrawMirrorShield, { gGiMirrorShieldDL, gGiMirrorShieldSymbolDL } },
// zelda's letter, OBJECT_GI_LETTER
{ GetItem_DrawOpa0Xlu1, { gGiLetterDL, gGiLetterWritingDL } },
// goron tunic, OBJECT_GI_CLOTHES
{ GetItem_DrawOpa1023, { gGiTunicCollarDL, gGiGoronCollarColorDL, gGiGoronTunicColorDL, gGiTunicDL } },
// zora tunic, OBJECT_GI_CLOTHES
{ GetItem_DrawOpa1023, { gGiTunicCollarDL, gGiZoraCollarColorDL, gGiZoraTunicColorDL, gGiTunicDL } },
// beans, OBJECT_GI_BEAN
{ GetItem_DrawOpa0, { gGiBeanDL } },
// fish, OBJECT_GI_FISH
{ GetItem_DrawFish, { gGiFishDL } },
// saw, OBJECT_GI_SAW
{ GetItem_DrawOpa0, { gGiSawDL } },
// hammer, OBJECT_GI_HAMMER
{ GetItem_DrawOpa0, { gGiHammerDL } },
// grass, OBJECT_GI_GRASS
{ GetItem_DrawOpa0, { gGiGrassDL } },
// biggorons sword, OBJECT_GI_LONGSWORD
{ GetItem_DrawGoronSword, { gGiBiggoronSwordDL } },
// chicken, OBJECT_GI_NIWATORI
{ GetItem_DrawOpa10Xlu2, { gGiChickenDL, gGiChickenColorDL, gGiChickenEyesDL } },
// ruto's letter, OBJECT_GI_BOTTLE_LETTER
{ GetItem_DrawOpa0Xlu1, { gGiLetterBottleContentsDL, gGiLetterBottleDL } },
// fairy ocarina, OBJECT_GI_OCARINA_0
{ GetItem_DrawOpa0Xlu1, { gGiOcarinaFairyDL, gGiOcarinaFairyHolesDL } },
// iron boots, OBJECT_GI_BOOTS_2
{ GetItem_DrawOpa0Xlu1, { gGiIronBootsDL, gGiIronBootsRivetsDL } },
// seeds, OBJECT_GI_SEED
{ GetItem_DrawOpa0, { gGiSeedDL } },
// silver gauntlets, OBJECT_GI_GLOVES
{ GetItem_DrawOpa10Xlu32,
{ gGiGauntletsDL, gGiSilverGauntletsColorDL, gGiGauntletsPlateDL, gGiSilverGauntletsPlateColorDL } },
// golden gauntlets, OBJECT_GI_GLOVES
{ GetItem_DrawOpa10Xlu32,
{ gGiGauntletsDL, gGiGoldenGauntletsColorDL, gGiGauntletsPlateDL, gGiGoldenGauntletsPlateColorDL } },
// yellow n coin, OBJECT_GI_COIN
{ GetItem_DrawOpa10Xlu2, { gGiCoinDL, gGiYellowCoinColorDL, gGiNDL } },
// red n coin, OBJECT_GI_COIN
{ GetItem_DrawOpa10Xlu2, { gGiCoinDL, gGiRedCoinColorDL, gGiNDL } },
// green n coin, OBJECT_GI_COIN
{ GetItem_DrawOpa10Xlu2, { gGiCoinDL, gGiGreenCoinColorDL, gGiNDL } },
// blue n coin, OBJECT_GI_COIN
{ GetItem_DrawOpa10Xlu2, { gGiCoinDL, gGiBlueCoinColorDL, gGiNDL } },
// skull mask, OBJECT_GI_SKJ_MASK
{ GetItem_DrawOpa0, { gGiSkullMaskDL } },
// bunny hood OBJECT_GI_RABIT_MASK
{ GetItem_DrawOpa0Xlu1, { gGiBunnyHoodDL, gGiBunnyHoodEyesDL } },
// mask of truth, OBJECT_GI_TRUTH_MASK
{ GetItem_DrawOpa0Xlu1, { gGiMaskOfTruthDL, gGiMaskOfTruthAccentsDL } },
// eyedrops, OBJECT_GI_EYE_LOTION
{ GetItem_DrawOpa0Xlu1, { gGiEyeDropsCapDL, gGiEyeDropsBottleDL } },
// odd potion, OBJECT_GI_POWDER
{ GetItem_DrawOpa0, { gGiOddPotionDL } },
// odd mushroom, OBJECT_GI_MUSHROOM
{ GetItem_DrawOpa0, { gGiOddMushroomDL } },
// claim check, OBJECT_GI_TICKETSTONE
{ GetItem_DrawOpa0Xlu1, { gGiClaimCheckDL, gGiClaimCheckWritingDL } },
// broken goron's sword, OBJECT_GI_BROKENSWORD
{ GetItem_DrawGoronSword, { gGiBrokenGoronSwordDL } },
// prescription, OBJECT_GI_PRESCRIPTION
{ GetItem_DrawOpa0Xlu1, { gGiPrescriptionDL, gGiPrescriptionWritingDL } },
// goron bracelet, OBJECT_GI_BRACELET
{ GetItem_DrawOpa0, { gGiGoronBraceletDL } },
// sold out, OBJECT_GI_SOLDOUT
{ GetItem_DrawSoldOut, { gGiSoldOutDL } },
// frog, OBJECT_GI_FROG
{ GetItem_DrawOpa0Xlu1, { gGiFrogDL, gGiFrogEyesDL } },
// goron mask, OBJECT_GI_GOLONMASK
{ GetItem_DrawMaskOrBombchu, { gGiGoronMaskDL } },
// zora mask, OBJECT_GI_ZORAMASK
{ GetItem_DrawMaskOrBombchu, { gGiZoraMaskDL } },
// gerudo mask, OBJECT_GI_GERUDOMASK
{ GetItem_DrawMaskOrBombchu, { gGiGerudoMaskDL } },
// cojiro, OBJECT_GI_NIWATORI
{ GetItem_DrawOpa10Xlu2, { gGiChickenDL, gGiCojiroColorDL, gGiChickenEyesDL } },
// hover boots, OBJECT_GI_HOVERBOOTS
{ GetItem_DrawOpa0, { gGiHoverBootsDL } },
// fire arrows, OBJECT_GI_M_ARROW
{ GetItem_DrawMagicArrow, { gGiMagicArrowDL, gGiFireArrowColorDL, gGiArrowMagicDL } },
// ice arrows, OBJECT_GI_M_ARROW
{ GetItem_DrawMagicArrow, { gGiMagicArrowDL, gGiIceArrowColorDL, gGiArrowMagicDL } },
// light arrows, OBJECT_GI_M_ARROW
{ GetItem_DrawMagicArrow, { gGiMagicArrowDL, gGiLightArrowColorDL, gGiArrowMagicDL } },
// skulltula token, OBJECT_GI_SUTARU
{ GetItem_DrawSkullToken, { gGiSkulltulaTokenDL, gGiSkulltulaTokenFlameDL } },
// din's fire, OBJECT_GI_GODDESS
{ GetItem_DrawMagicSpell, { gGiMagicSpellDiamondDL, gGiDinsFireColorDL, gGiMagicSpellOrbDL } },
// farore's wind, OBJECT_GI_GODDESS
{ GetItem_DrawMagicSpell, { gGiMagicSpellDiamondDL, gGiFaroresWindColorDL, gGiMagicSpellOrbDL } },
// nayru's Love, OBJECT_GI_GODDESS
{ GetItem_DrawMagicSpell, { gGiMagicSpellDiamondDL, gGiNayrusLoveColorDL, gGiMagicSpellOrbDL } },
// blue fire, OBJECT_GI_FIRE
{ GetItem_DrawBlueFire, { gGiBlueFireChamberstickDL, gGiBlueFireFlameDL } },
// bugs, OBJECT_GI_INSECT
{ GetItem_DrawOpa0Xlu1, { gGiBugsContainerDL, gGiBugsGlassDL } },
// butterfly, OBJECT_GI_BUTTERFLY
{ GetItem_DrawOpa0Xlu1, { gGiButterflyContainerDL, gGiButterflyGlassDL } },
// poe, OBJECT_GI_GHOST
{ GetItem_DrawPoes,
{ gGiGhostContainerLidDL, gGiGhostContainerGlassDL, gGiGhostContainerContentsDL, gGiPoeColorDL } },
// fairy, OBJECT_GI_SOUL
{ GetItem_DrawFairy, { gGiFairyContainerBaseCapDL, gGiFairyContainerGlassDL, gGiFairyContainerContentsDL } },
// bullet bag 40, OBJECT_GI_DEKUPOUCH
{ GetItem_DrawBulletBag,
{ gGiBulletBagDL, gGiBulletBagColorDL, gGiBulletBagStringDL, gGiBulletBagStringColorDL, gGiBulletBagWritingDL } },
// green rupee, OBJECT_GI_RUPY
{ GetItem_DrawSmallRupee,
{ gGiRupeeInnerDL, gGiGreenRupeeInnerColorDL, gGiRupeeOuterDL, gGiGreenRupeeOuterColorDL } },
// blue rupee, OBJECT_GI_RUPY
{ GetItem_DrawSmallRupee,
{ gGiRupeeInnerDL, gGiBlueRupeeInnerColorDL, gGiRupeeOuterDL, gGiBlueRupeeOuterColorDL } },
// red rupee, OBJECT_GI_RUPY
{ GetItem_DrawSmallRupee, { gGiRupeeInnerDL, gGiRedRupeeInnerColorDL, gGiRupeeOuterDL, gGiRedRupeeOuterColorDL } },
// big poe, OBJECT_GI_GHOST
{ GetItem_DrawPoes,
{ gGiGhostContainerLidDL, gGiGhostContainerGlassDL, gGiGhostContainerContentsDL, gGiBigPoeColorDL } },
// purple rupee, OBJECT_GI_RUPY
{ GetItem_DrawOpa10Xlu32,
{ gGiRupeeInnerDL, gGiPurpleRupeeInnerColorDL, gGiRupeeOuterDL, gGiPurpleRupeeOuterColorDL } },
// gold rupee, OBJECT_GI_RUPY
{ GetItem_DrawOpa10Xlu32,
{ gGiRupeeInnerDL, gGiGoldRupeeInnerColorDL, gGiRupeeOuterDL, gGiGoldRupeeOuterColorDL } },
// bullet bag 50, OBJECT_GI_DEKUPOUCH
{ GetItem_DrawBulletBag,
{ gGiBulletBagDL, gGiBulletBag50ColorDL, gGiBulletBagStringDL, gGiBulletBag50StringColorDL,
gGiBulletBagWritingDL } },
// kokiri sword, OBJECT_GI_SWORD_1
{ GetItem_DrawOpa0, { gGiKokiriSwordDL } },
// gold skulltula token, OBJECT_ST
{ GetItem_DrawSkullToken, { object_st_DL_004DB0, object_st_DL_004EB8 } },
};
/**
* Draw "Get Item" Model
* Calls the corresponding draw function for the given draw ID
*/
void GetItem_Draw(GlobalContext* globalCtx, s16 drawId) {
sDrawItemTable[drawId].drawFunc(globalCtx, drawId);
}
// All remaining functions in this file are draw functions referenced in the table and called by the function above
void GetItem_DrawMaskOrBombchu(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 556);
func_80093BA8(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 560),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 565);
}
void GetItem_DrawSoldOut(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 572);
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 5);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 576),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 581);
}
void GetItem_DrawBlueFire(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 588);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 592),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 0),
0 * (globalCtx->state.frames * 0), 16, 32, 1, 1 * (globalCtx->state.frames * 1),
1 * -(globalCtx->state.frames * 8), 16, 32));
Matrix_Push();
Matrix_Translate(-8.0f, -2.0f, 0.0f, MTXMODE_APPLY);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 615),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
Matrix_Pop();
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 621);
}
void GetItem_DrawPoes(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 628);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 632),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 641),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 0),
0 * (globalCtx->state.frames * 0), 16, 32, 1, 1 * (globalCtx->state.frames * 1),
1 * -(globalCtx->state.frames * 6), 16, 32));
Matrix_Push();
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 656),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[3]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
Matrix_Pop();
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 663);
}
void GetItem_DrawFairy(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 670);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 674),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 683),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 0),
0 * (globalCtx->state.frames * 0), 32, 32, 1, 1 * (globalCtx->state.frames * 1),
1 * -(globalCtx->state.frames * 6), 32, 32));
Matrix_Push();
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 698),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
Matrix_Pop();
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 704);
}
void GetItem_DrawMirrorShield(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 712);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 0) % 256,
1 * (globalCtx->state.frames * 2) % 256, 64, 64, 1,
0 * (globalCtx->state.frames * 0) % 128, 1 * (globalCtx->state.frames * 1) % 128, 32,
32));
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 723),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 730),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 735);
}
void GetItem_DrawSkullToken(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 742);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 746),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 0),
1 * -(globalCtx->state.frames * 5), 32, 32, 1, 0 * (globalCtx->state.frames * 0),
0 * (globalCtx->state.frames * 0), 32, 64));
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 760),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 765);
}
void GetItem_DrawEggOrMedallion(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 772);
func_80093BA8(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 776),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 783);
}
void GetItem_DrawCompass(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 811);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 815),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 5);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 822),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 827);
}
void GetItem_DrawPotion(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 834);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -1 * (globalCtx->state.frames * 1),
1 * (globalCtx->state.frames * 1), 32, 32, 1, -1 * (globalCtx->state.frames * 1),
1 * (globalCtx->state.frames * 1), 32, 32));
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 845),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[2]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[3]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 855),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[4]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[5]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 861);
}
void GetItem_DrawGoronSword(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 868);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 1 * (globalCtx->state.frames * 1),
0 * (globalCtx->state.frames * 1), 32, 32, 1, 0 * (globalCtx->state.frames * 1),
0 * (globalCtx->state.frames * 1), 32, 32));
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 878),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 883);
}
void GetItem_DrawDekuNuts(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 890);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 1 * (globalCtx->state.frames * 6),
1 * (globalCtx->state.frames * 6), 32, 32, 1, 1 * (globalCtx->state.frames * 6),
1 * (globalCtx->state.frames * 6), 32, 32));
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 901),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 906);
}
void GetItem_DrawRecoveryHeart(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 913);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 1),
1 * -(globalCtx->state.frames * 3), 32, 32, 1, 0 * (globalCtx->state.frames * 1),
1 * -(globalCtx->state.frames * 2), 32, 32));
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 924),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 929);
}
void GetItem_DrawFish(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 936);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0 * (globalCtx->state.frames * 0),
1 * (globalCtx->state.frames * 1), 32, 32, 1, 0 * (globalCtx->state.frames * 0),
1 * (globalCtx->state.frames * 1), 32, 32));
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 947),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 952);
}
void GetItem_DrawOpa0(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 959);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 963),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 968);
}
void GetItem_DrawOpa0Xlu1(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 975);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 979),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 986),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 991);
}
void GetItem_DrawXlu01(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 998);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1002),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1008);
}
void GetItem_DrawOpa10Xlu2(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1015);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1019),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1027),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1032);
}
void GetItem_DrawMagicArrow(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1039);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1043),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1050),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1056);
}
void GetItem_DrawMagicSpell(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1063);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 1 * (globalCtx->state.frames * 2),
1 * -(globalCtx->state.frames * 6), 32, 32, 1, 1 * (globalCtx->state.frames * 1),
-1 * (globalCtx->state.frames * 2), 32, 32));
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1074),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1081);
}
void GetItem_DrawOpa1023(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1088);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1092),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[2]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[3]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1100);
}
void GetItem_DrawOpa10Xlu32(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1108);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1112),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1120),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[3]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1126);
}
void GetItem_DrawSmallRupee(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1133);
Matrix_Scale(0.7f, 0.7f, 0.7f, MTXMODE_APPLY);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1140),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1148),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[3]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1154);
}
void GetItem_DrawScale(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1162);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 1 * (globalCtx->state.frames * 2),
-1 * (globalCtx->state.frames * 2), 64, 64, 1, 1 * (globalCtx->state.frames * 4),
1 * -(globalCtx->state.frames * 4), 32, 32));
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1173),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[3]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1181);
}
void GetItem_DrawBulletBag(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1188);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1192),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1200),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[2]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[3]);
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[4]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1207);
}
void GetItem_DrawWallet(GlobalContext* globalCtx, s16 drawId) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1214);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_draw.c", 1218),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[2]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[3]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[4]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[5]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[6]);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[7]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_draw.c", 1230);
}

1062
soh/src/code/z_eff_blure.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,216 @@
#include "global.h"
#include "vt.h"
#include "objects/gameplay_keep/gameplay_keep.h"
static Vtx sVertices[5] = {
VTX(-32, -32, 0, 0, 1024, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(32, 32, 0, 1024, 0, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(-32, 32, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(32, -32, 0, 1024, 1024, 0xFF, 0xFF, 0xFF, 0xFF),
};
// original name: "EffectShieldParticle_ct"
void EffectShieldParticle_Init(void* thisx, void* initParamsx) {
EffectShieldParticle* this = (EffectShieldParticle*)thisx;
EffectShieldParticleInit* initParams = (EffectShieldParticleInit*)initParamsx;
EffectShieldParticleElement* elem;
if ((this != NULL) && (initParams != NULL)) {
this->numElements = initParams->numElements;
if (this->numElements > ARRAY_COUNT(this->elements)) {
osSyncPrintf(VT_FGCOL(RED));
osSyncPrintf("EffectShieldParticle_ct():パーティクル数がオーバしてます。\n");
osSyncPrintf(VT_RST);
return;
}
this->position = initParams->position;
this->primColorStart = initParams->primColorStart;
this->envColorStart = initParams->envColorStart;
this->primColorMid = initParams->primColorMid;
this->envColorMid = initParams->envColorMid;
this->primColorEnd = initParams->primColorEnd;
this->envColorEnd = initParams->envColorEnd;
this->deceleration = initParams->deceleration;
this->maxInitialSpeed = initParams->maxInitialSpeed;
this->lengthCutoff = initParams->lengthCutoff;
this->duration = initParams->duration;
this->timer = 0;
for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) {
elem->initialSpeed = (Rand_ZeroOne() * (this->maxInitialSpeed * 0.5f)) + (this->maxInitialSpeed * 0.5f);
elem->endX = 0.0f;
elem->startXChange = 0.0f;
elem->startX = 0.0f;
elem->endXChange = elem->initialSpeed;
elem->yaw = Rand_ZeroOne() * 65534.0f;
elem->pitch = Rand_ZeroOne() * 65534.0f;
}
this->lightDecay = initParams->lightDecay;
if (this->lightDecay == true) {
this->lightInfo.type = LIGHT_POINT_NOGLOW;
this->lightInfo.params.point = initParams->lightPoint;
this->lightNode =
LightContext_InsertLight(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, &this->lightInfo);
} else {
this->lightNode = NULL;
}
}
}
void EffectShieldParticle_Destroy(void* thisx) {
EffectShieldParticle* this = (EffectShieldParticle*)thisx;
if ((this != NULL) && (this->lightDecay == true)) {
if (this->lightNode == Effect_GetGlobalCtx()->lightCtx.listHead) {
Effect_GetGlobalCtx()->lightCtx.listHead = this->lightNode->next;
}
LightContext_RemoveLight(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, this->lightNode);
}
}
s32 EffectShieldParticle_Update(void* thisx) {
EffectShieldParticle* this = (EffectShieldParticle*)thisx;
EffectShieldParticleElement* elem;
if (this == NULL) {
return 0;
}
for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) {
elem->endXChange -= this->deceleration;
if (elem->endXChange < 0.0f) {
elem->endXChange = 0.0f;
}
if (elem->startXChange > 0.0f) {
elem->startXChange -= this->deceleration;
if (elem->startXChange < 0.0f) {
elem->startXChange = 0.0f;
}
}
elem->endX += elem->endXChange;
elem->startX += elem->startXChange;
if ((elem->startXChange == 0.0f) && (this->lengthCutoff < (elem->endX - elem->startX))) {
elem->startXChange = elem->initialSpeed;
}
}
if (this->lightDecay == true) {
this->lightInfo.params.point.radius /= 2;
}
this->timer++;
if (this->duration < this->timer) {
return 1;
}
return 0;
}
void EffectShieldParticle_GetColors(EffectShieldParticle* this, Color_RGBA8* primColor, Color_RGBA8* envColor) {
s32 halfDuration = this->duration * 0.5f;
f32 ratio;
if (halfDuration == 0) {
primColor->r = this->primColorStart.r;
primColor->g = this->primColorStart.g;
primColor->b = this->primColorStart.b;
primColor->a = this->primColorStart.a;
envColor->r = this->envColorStart.r;
envColor->g = this->envColorStart.g;
envColor->b = this->envColorStart.b;
envColor->a = this->envColorStart.a;
} else if (this->timer < halfDuration) {
ratio = this->timer / (f32)halfDuration;
primColor->r = this->primColorStart.r + (this->primColorMid.r - this->primColorStart.r) * ratio;
primColor->g = this->primColorStart.g + (this->primColorMid.g - this->primColorStart.g) * ratio;
primColor->b = this->primColorStart.b + (this->primColorMid.b - this->primColorStart.b) * ratio;
primColor->a = this->primColorStart.a + (this->primColorMid.a - this->primColorStart.a) * ratio;
envColor->r = this->envColorStart.r + (this->envColorMid.r - this->envColorStart.r) * ratio;
envColor->g = this->envColorStart.g + (this->envColorMid.g - this->envColorStart.g) * ratio;
envColor->b = this->envColorStart.b + (this->envColorMid.b - this->envColorStart.b) * ratio;
envColor->a = this->envColorStart.a + (this->envColorMid.a - this->envColorStart.a) * ratio;
} else {
ratio = (this->timer - halfDuration) / (f32)halfDuration;
primColor->r = this->primColorMid.r + (this->primColorEnd.r - this->primColorMid.r) * ratio;
primColor->g = this->primColorMid.g + (this->primColorEnd.g - this->primColorMid.g) * ratio;
primColor->b = this->primColorMid.b + (this->primColorEnd.b - this->primColorMid.b) * ratio;
primColor->a = this->primColorMid.a + (this->primColorEnd.a - this->primColorMid.a) * ratio;
envColor->r = this->envColorMid.r + (this->envColorEnd.r - this->envColorMid.r) * ratio;
envColor->g = this->envColorMid.g + (this->envColorEnd.g - this->envColorMid.g) * ratio;
envColor->b = this->envColorMid.b + (this->envColorEnd.b - this->envColorMid.b) * ratio;
envColor->a = this->envColorMid.a + (this->envColorEnd.a - this->envColorMid.a) * ratio;
}
}
void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
EffectShieldParticle* this = (EffectShieldParticle*)thisx;
EffectShieldParticleElement* elem;
Color_RGBA8 primColor;
Color_RGBA8 envColor;
OPEN_DISPS(gfxCtx, "../z_eff_shield_particle.c", 272);
if (this != NULL) {
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26);
gDPSetCycleType(POLY_XLU_DISP++, G_CYC_2CYCLE);
gDPPipeSync(POLY_XLU_DISP++);
gSPTexture(POLY_XLU_DISP++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
gDPLoadTextureBlock(POLY_XLU_DISP++, gUnknownCircle6Tex, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
gDPSetCombineLERP(POLY_XLU_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, 0, TEXEL0, 0, 0, 0,
0, COMBINED, 0, 0, 0, COMBINED);
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2);
gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR);
gSPSetGeometryMode(POLY_XLU_DISP++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH);
EffectShieldParticle_GetColors(this, &primColor, &envColor);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, primColor.r, primColor.g, primColor.b, primColor.a);
gDPSetEnvColor(POLY_XLU_DISP++, envColor.r, envColor.g, envColor.b, envColor.a);
gDPPipeSync(POLY_XLU_DISP++);
for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) {
Mtx* mtx;
MtxF sp104;
MtxF spC4;
MtxF sp84;
f32 temp1 = (s16)((elem->endX + elem->startX) * 0.5f);
f32 temp2 = elem->endX - elem->startX;
f32 temp3 = (s16)((temp2 * (1.0f / 64.0f)) / 0.02f);
if (temp3 < 1.0f) {
temp3 = 1.0f;
}
SkinMatrix_SetTranslate(&spC4, this->position.x, this->position.y, this->position.z);
SkinMatrix_SetRotateZYX(&sp104, 0, elem->yaw, 0);
SkinMatrix_MtxFMtxFMult(&spC4, &sp104, &sp84);
SkinMatrix_SetRotateZYX(&sp104, 0, 0, elem->pitch);
SkinMatrix_MtxFMtxFMult(&sp84, &sp104, &spC4);
SkinMatrix_SetTranslate(&sp104, temp1, 0.0f, 0.0f);
SkinMatrix_MtxFMtxFMult(&spC4, &sp104, &sp84);
SkinMatrix_SetScale(&sp104, temp3 * 0.02f, 0.02f, 0.02f);
SkinMatrix_MtxFMtxFMult(&sp84, &sp104, &spC4);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &spC4);
if (mtx == NULL) {
break;
}
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPVertex(POLY_XLU_DISP++, sVertices, 4, 0);
gSP2Triangles(POLY_XLU_DISP++, 0, 1, 2, 0, 0, 3, 1, 0);
}
}
CLOSE_DISPS(gfxCtx, "../z_eff_shield_particle.c", 359);
}

277
soh/src/code/z_eff_spark.c Normal file
View file

@ -0,0 +1,277 @@
#include "global.h"
#include "objects/gameplay_keep/gameplay_keep.h"
// original name: "spark"
void EffectSpark_Init(void* thisx, void* initParamsx) {
EffectSpark* this = (EffectSpark*)thisx;
EffectSparkInit* initParams = (EffectSparkInit*)initParamsx;
EffectSparkElement* elem;
f32 velocityNorm;
s32 i;
if ((this != NULL) && (initParams != NULL)) {
if ((initParams->uDiv == 0) || (initParams->vDiv == 0)) {
osSyncPrintf("spark():u_div,v_div 0では困る。\n"); // "u_div,v_div 0 is not good."
return;
}
this->position = initParams->position;
this->speed = initParams->speed;
this->gravity = initParams->gravity;
this->uDiv = initParams->uDiv;
this->vDiv = initParams->vDiv;
this->colorStart[0].r = initParams->colorStart[0].r;
this->colorStart[0].g = initParams->colorStart[0].g;
this->colorStart[0].b = initParams->colorStart[0].b;
this->colorStart[0].a = initParams->colorStart[0].a;
this->colorStart[1].r = initParams->colorStart[1].r;
this->colorStart[1].g = initParams->colorStart[1].g;
this->colorStart[1].b = initParams->colorStart[1].b;
this->colorStart[1].a = initParams->colorStart[1].a;
this->colorStart[2].r = initParams->colorStart[2].r;
this->colorStart[2].g = initParams->colorStart[2].g;
this->colorStart[2].b = initParams->colorStart[2].b;
this->colorStart[2].a = initParams->colorStart[2].a;
this->colorStart[3].r = initParams->colorStart[3].r;
this->colorStart[3].g = initParams->colorStart[3].g;
this->colorStart[3].b = initParams->colorStart[3].b;
this->colorStart[3].a = initParams->colorStart[3].a;
this->colorEnd[0].r = initParams->colorEnd[0].r;
this->colorEnd[0].g = initParams->colorEnd[0].g;
this->colorEnd[0].b = initParams->colorEnd[0].b;
this->colorEnd[0].a = initParams->colorEnd[0].a;
this->colorEnd[1].r = initParams->colorEnd[1].r;
this->colorEnd[1].g = initParams->colorEnd[1].g;
this->colorEnd[1].b = initParams->colorEnd[1].b;
this->colorEnd[1].a = initParams->colorEnd[1].a;
this->colorEnd[2].r = initParams->colorEnd[2].r;
this->colorEnd[2].g = initParams->colorEnd[2].g;
this->colorEnd[2].b = initParams->colorEnd[2].b;
this->colorEnd[2].a = initParams->colorEnd[2].a;
this->colorEnd[3].r = initParams->colorEnd[3].r;
this->colorEnd[3].g = initParams->colorEnd[3].g;
this->colorEnd[3].b = initParams->colorEnd[3].b;
this->colorEnd[3].a = initParams->colorEnd[3].a;
this->duration = initParams->duration;
this->numElements = (this->uDiv * this->vDiv) + 2;
if (this->numElements > ARRAY_COUNT(this->elements)) {
osSyncPrintf("table_sizeオーバー\n"); // "over table_size"
return;
}
for (i = 0; i < this->numElements; i++) {
elem = &this->elements[i];
elem->position.x = this->position.x;
elem->position.y = this->position.y;
elem->position.z = this->position.z;
elem->velocity.x = Rand_ZeroOne() - 0.5f;
elem->velocity.y = Rand_ZeroOne() - 0.5f;
elem->velocity.z = Rand_ZeroOne() - 0.5f;
velocityNorm = sqrtf(SQ(elem->velocity.x) + SQ(elem->velocity.y) + SQ(elem->velocity.z));
if (!(fabsf(velocityNorm) < 0.008f)) {
elem->velocity.x *= this->speed * (1.0f / velocityNorm);
elem->velocity.y *= this->speed * (1.0f / velocityNorm);
elem->velocity.z *= this->speed * (1.0f / velocityNorm);
} else {
elem->velocity.x = elem->velocity.z = 0.0f;
elem->velocity.y = this->speed;
}
elem->unkVelocity.x = 30000.0f - Rand_ZeroOne() * 15000.0f;
elem->unkVelocity.y = 30000.0f - Rand_ZeroOne() * 15000.0f;
elem->unkVelocity.z = 30000.0f - Rand_ZeroOne() * 15000.0f;
elem->unkPosition.x = Rand_ZeroOne() * 65534.0f;
elem->unkPosition.y = Rand_ZeroOne() * 65534.0f;
elem->unkPosition.z = Rand_ZeroOne() * 65534.0f;
}
this->timer = 0;
}
}
void EffectSpark_Destroy(void* thisx) {
}
// original name: "EffectSparkInfo_proc"
s32 EffectSpark_Update(void* thisx) {
EffectSpark* this = (EffectSpark*)thisx;
EffectSparkElement* elem;
s32 i;
if (this == NULL) {
osSyncPrintf("EffectSparkInfo_proc():Spark Pointer is NULL\n");
}
for (i = 0; i < this->numElements; i++) {
elem = &this->elements[i];
elem->position.x += elem->velocity.x;
elem->position.y += elem->velocity.y;
elem->position.z += elem->velocity.z;
elem->velocity.y += this->gravity;
elem->unkPosition.x += elem->unkVelocity.x;
elem->unkPosition.y += elem->unkVelocity.y;
elem->unkPosition.z += elem->unkVelocity.z;
}
this->timer++;
if (this->duration < this->timer) {
return 1;
} else {
return 0;
}
}
// original name: "EffectSparkInfo_disp"
void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
Vtx* vertices;
EffectSpark* this = (EffectSpark*)thisx;
GlobalContext* globalCtx = Effect_GetGlobalCtx();
s32 i;
s32 j;
u8 sp1D3;
u8 sp1D2;
u8 sp1D1;
u8 sp1D0;
u8 sp1CF;
u8 sp1CE;
u8 sp1CD;
u8 sp1CC;
u8 sp1CB;
u8 sp1CA;
u8 sp1C9;
u8 sp1C8;
u8 sp1C7;
u8 sp1C6;
u8 sp1C5;
u8 sp1C4;
f32 ratio;
OPEN_DISPS(gfxCtx, "../z_eff_spark.c", 293);
if (this != NULL) {
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26);
gDPSetCycleType(POLY_XLU_DISP++, G_CYC_2CYCLE);
gDPPipeSync(POLY_XLU_DISP++);
gSPTexture(POLY_XLU_DISP++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
gDPLoadTextureBlock(POLY_XLU_DISP++, gUnknownCircle6Tex, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
gDPSetCombineMode(POLY_XLU_DISP++, G_CC_SHADEDECALA, G_CC_PASS2);
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2);
gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR);
gSPSetGeometryMode(POLY_XLU_DISP++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH);
gDPPipeSync(POLY_XLU_DISP++);
vertices = Graph_Alloc(gfxCtx, this->numElements * sizeof(Vtx[4]));
if (vertices == NULL) {
// "Memory Allocation Failure graph_malloc"
osSyncPrintf("EffectSparkInfo_disp():メモリー確保失敗 graph_malloc\n");
goto end;
}
j = 0;
ratio = (f32)this->timer / (f32)this->duration;
sp1D3 = this->colorStart[0].r + ((f32)this->colorEnd[0].r - (f32)this->colorStart[0].r) * ratio;
sp1D2 = this->colorStart[0].g + ((f32)this->colorEnd[0].g - (f32)this->colorStart[0].g) * ratio;
sp1D1 = this->colorStart[0].b + ((f32)this->colorEnd[0].b - (f32)this->colorStart[0].b) * ratio;
sp1D0 = this->colorStart[0].a + ((f32)this->colorEnd[0].a - (f32)this->colorStart[0].a) * ratio;
sp1CF = this->colorStart[1].r + ((f32)this->colorEnd[1].r - (f32)this->colorStart[1].r) * ratio;
sp1CE = this->colorStart[1].g + ((f32)this->colorEnd[1].g - (f32)this->colorStart[1].g) * ratio;
sp1CD = this->colorStart[1].b + ((f32)this->colorEnd[1].b - (f32)this->colorStart[1].b) * ratio;
sp1CC = this->colorStart[1].a + ((f32)this->colorEnd[1].a - (f32)this->colorStart[1].a) * ratio;
sp1CB = this->colorStart[2].r + ((f32)this->colorEnd[2].r - (f32)this->colorStart[2].r) * ratio;
sp1CA = this->colorStart[2].g + ((f32)this->colorEnd[2].g - (f32)this->colorStart[2].g) * ratio;
sp1C9 = this->colorStart[2].b + ((f32)this->colorEnd[2].b - (f32)this->colorStart[2].b) * ratio;
sp1C8 = this->colorStart[2].a + ((f32)this->colorEnd[2].a - (f32)this->colorStart[2].a) * ratio;
sp1C7 = this->colorStart[3].r + ((f32)this->colorEnd[3].r - (f32)this->colorStart[3].r) * ratio;
sp1C6 = this->colorStart[3].g + ((f32)this->colorEnd[3].g - (f32)this->colorStart[3].g) * ratio;
sp1C5 = this->colorStart[3].b + ((f32)this->colorEnd[3].b - (f32)this->colorStart[3].b) * ratio;
sp1C4 = this->colorStart[3].a + ((f32)this->colorEnd[3].a - (f32)this->colorStart[3].a) * ratio;
for (i = 0; i < this->numElements; i++) {
MtxF sp12C;
MtxF spEC;
MtxF spAC;
MtxF sp6C;
EffectSparkElement* elem = &this->elements[i];
Mtx* mtx;
f32 temp;
SkinMatrix_SetTranslate(&spEC, elem->position.x, elem->position.y, elem->position.z);
temp = ((Rand_ZeroOne() * 2.5f) + 1.5f) / 64.0f;
SkinMatrix_SetScale(&spAC, temp, temp, 1.0f);
SkinMatrix_MtxFMtxFMult(&spEC, &globalCtx->billboardMtxF, &sp6C);
SkinMatrix_MtxFMtxFMult(&sp6C, &spAC, &sp12C);
vertices[j].v.ob[0] = -32;
vertices[j].v.ob[1] = -32;
vertices[j].v.ob[2] = 0;
vertices[j].v.cn[0] = sp1D3;
vertices[j].v.cn[1] = sp1D2;
vertices[j].v.cn[2] = sp1D1;
vertices[j].v.cn[3] = sp1D0;
vertices[j].v.tc[0] = 0;
vertices[j].v.tc[1] = 1024;
vertices[j].v.flag = 0;
vertices[j + 1].v.ob[0] = 32;
vertices[j + 1].v.ob[1] = 32;
vertices[j + 1].v.ob[2] = 0;
vertices[j + 1].v.cn[0] = sp1CF;
vertices[j + 1].v.cn[1] = sp1CE;
vertices[j + 1].v.cn[2] = sp1CD;
vertices[j + 1].v.cn[3] = sp1CC;
vertices[j + 1].v.tc[0] = 1024;
vertices[j + 1].v.tc[1] = 0;
vertices[j + 1].v.flag = 0;
vertices[j + 2].v.ob[0] = -32;
vertices[j + 2].v.ob[1] = 32;
vertices[j + 2].v.ob[2] = 0;
vertices[j + 2].v.cn[0] = sp1CB;
vertices[j + 2].v.cn[1] = sp1CA;
vertices[j + 2].v.cn[2] = sp1C9;
vertices[j + 2].v.cn[3] = sp1C8;
vertices[j + 2].v.tc[0] = 0;
vertices[j + 2].v.tc[1] = 0;
vertices[j + 2].v.flag = 0;
vertices[j + 3].v.ob[0] = 32;
vertices[j + 3].v.ob[1] = -32;
vertices[j + 3].v.ob[2] = 0;
vertices[j + 3].v.cn[0] = sp1C7;
vertices[j + 3].v.cn[1] = sp1C6;
vertices[j + 3].v.cn[2] = sp1C5;
vertices[j + 3].v.cn[3] = sp1C4;
vertices[j + 3].v.tc[0] = 1024;
vertices[j + 3].v.tc[1] = 1024;
vertices[j + 3].v.flag = 0;
j += 4;
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp12C);
if (mtx == NULL) {
goto end;
}
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPVertex(POLY_XLU_DISP++, &vertices[4 * i], 4, 0);
gSP2Triangles(POLY_XLU_DISP++, 2, 0, 3, 0, 2, 3, 1, 0);
}
gDPPipeSync(POLY_XLU_DISP++);
}
end:
CLOSE_DISPS(gfxCtx, "../z_eff_spark.c", 498);
}

View file

@ -0,0 +1,121 @@
#include "global.h"
void func_80026230(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) {
f32 cos;
Gfx* displayListHead;
f32 absCos;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 113);
displayListHead = POLY_OPA_DISP;
cos = Math_CosS((0x8000 / arg3) * arg2);
absCos = ABS(cos);
gDPPipeSync(displayListHead++);
if (color == NULL) {
gDPSetFogColor(displayListHead++, 255, 0, 0, 0);
} else {
gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a);
}
gSPFogPosition(displayListHead++, 0, (s16)(absCos * 3000.0f) + 1500);
POLY_OPA_DISP = displayListHead;
if (1) {} // Necessary to match
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 129);
}
void func_80026400(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) {
Gfx* displayListHead;
f32 cos;
if (arg3 != 0) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 141);
cos = Math_CosS((0x4000 / arg3) * arg2);
displayListHead = POLY_OPA_DISP;
gDPPipeSync(displayListHead++);
gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a);
gSPFogPosition(displayListHead++, 0, (s16)(2800.0f * ABS(cos)) + 1700);
POLY_OPA_DISP = displayListHead;
if (1) {} // Necessary to match
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 153);
}
}
void func_80026608(GlobalContext* globalCtx) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 159);
gDPPipeSync(POLY_OPA_DISP++);
POLY_OPA_DISP = Gameplay_SetFog(globalCtx, POLY_OPA_DISP);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 164);
}
void func_80026690(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) {
f32 cos;
Gfx* displayListHead;
f32 absCos;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 178);
displayListHead = POLY_XLU_DISP;
cos = Math_CosS((0x8000 / arg3) * arg2);
absCos = ABS(cos);
gDPPipeSync(displayListHead++);
if (color == NULL) {
gDPSetFogColor(displayListHead++, 255, 0, 0, 0);
} else {
gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a);
}
gSPFogPosition(displayListHead++, 0, (s16)(absCos * 3000.0f) + 1500);
POLY_XLU_DISP = displayListHead;
if (1) {} // Necessary to match
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 194);
}
void func_80026860(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) {
f32 cos;
Gfx* displayListHead;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 201);
displayListHead = POLY_XLU_DISP;
cos = Math_CosS((0x4000 / arg3) * arg2);
gDPPipeSync(displayListHead++);
gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a);
gSPFogPosition(displayListHead++, 0, (s16)(2800.0f * ABS(cos)) + 1700);
POLY_XLU_DISP = displayListHead;
if (1) {} // Necessary to match
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 212);
}
void func_80026A6C(GlobalContext* globalCtx) {
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 217);
gDPPipeSync(POLY_XLU_DISP++);
POLY_XLU_DISP = Gameplay_SetFog(globalCtx, POLY_XLU_DISP);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_eff_ss_dead.c", 222);
}

259
soh/src/code/z_effect.c Normal file
View file

@ -0,0 +1,259 @@
#include "global.h"
EffectContext sEffectContext;
EffectInfo sEffectInfoTable[] = {
{
sizeof(EffectSpark),
EffectSpark_Init,
EffectSpark_Destroy,
EffectSpark_Update,
EffectSpark_Draw,
},
{
sizeof(EffectBlure),
EffectBlure_Init1,
EffectBlure_Destroy,
EffectBlure_Update,
EffectBlure_Draw,
},
{
sizeof(EffectBlure),
EffectBlure_Init2,
EffectBlure_Destroy,
EffectBlure_Update,
EffectBlure_Draw,
},
{
sizeof(EffectShieldParticle),
EffectShieldParticle_Init,
EffectShieldParticle_Destroy,
EffectShieldParticle_Update,
EffectShieldParticle_Draw,
},
};
GlobalContext* Effect_GetGlobalCtx(void) {
return sEffectContext.globalCtx;
}
void* Effect_GetByIndex(s32 index) {
if (index == TOTAL_EFFECT_COUNT) {
return NULL;
}
if (index < SPARK_COUNT) {
if (sEffectContext.sparks[index].status.active == true) {
return &sEffectContext.sparks[index].effect;
} else {
return NULL;
}
}
index -= SPARK_COUNT;
if (index < BLURE_COUNT) {
if (sEffectContext.blures[index].status.active == true) {
return &sEffectContext.blures[index].effect;
} else {
return NULL;
}
}
index -= BLURE_COUNT;
if (index < SHIELD_PARTICLE_COUNT) {
if (sEffectContext.shieldParticles[index].status.active == true) {
return &sEffectContext.shieldParticles[index].effect;
} else {
return NULL;
}
}
return NULL;
}
void Effect_InitStatus(EffectStatus* status) {
status->active = false;
status->unk_01 = 0;
status->unk_02 = 0;
}
void Effect_InitContext(GlobalContext* globalCtx) {
s32 i;
for (i = 0; i < SPARK_COUNT; i++) {
Effect_InitStatus(&sEffectContext.sparks[i].status);
}
for (i = 0; i < BLURE_COUNT; i++) {
Effect_InitStatus(&sEffectContext.blures[i].status);
}
for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) {
//! @bug This is supposed to initialize shieldParticles, not blures again
Effect_InitStatus(&sEffectContext.blures[i].status);
}
sEffectContext.globalCtx = globalCtx;
}
void Effect_Add(GlobalContext* globalCtx, s32* pIndex, s32 type, u8 arg3, u8 arg4, void* initParams) {
s32 i;
u32 slotFound;
void* effect = NULL;
EffectStatus* status = NULL;
*pIndex = TOTAL_EFFECT_COUNT;
if (FrameAdvance_IsEnabled(globalCtx) != true) {
slotFound = false;
switch (type) {
case EFFECT_SPARK:
for (i = 0; i < SPARK_COUNT; i++) {
if (sEffectContext.sparks[i].status.active == false) {
slotFound = true;
*pIndex = i;
effect = &sEffectContext.sparks[i].effect;
status = &sEffectContext.sparks[i].status;
break;
}
}
break;
case EFFECT_BLURE1:
case EFFECT_BLURE2:
for (i = 0; i < BLURE_COUNT; i++) {
if (sEffectContext.blures[i].status.active == false) {
slotFound = true;
*pIndex = i + SPARK_COUNT;
effect = &sEffectContext.blures[i].effect;
status = &sEffectContext.blures[i].status;
break;
}
}
break;
case EFFECT_SHIELD_PARTICLE:
for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) {
if (sEffectContext.shieldParticles[i].status.active == false) {
slotFound = true;
*pIndex = i + SPARK_COUNT + BLURE_COUNT;
effect = &sEffectContext.shieldParticles[i].effect;
status = &sEffectContext.shieldParticles[i].status;
break;
}
}
break;
}
if (!slotFound) {
// "EffectAdd(): I cannot secure it. Be careful. Type %d"
osSyncPrintf("EffectAdd():確保できません。注意してください。Type%d\n", type);
osSyncPrintf("エフェクト追加せずに終了します。\n"); // "Exit without adding the effect."
} else {
sEffectInfoTable[type].init(effect, initParams);
status->unk_02 = arg3;
status->unk_01 = arg4;
status->active = true;
}
}
}
void Effect_DrawAll(GraphicsContext* gfxCtx) {
s32 i;
for (i = 0; i < SPARK_COUNT; i++) {
if (sEffectContext.sparks[i].status.active) {
sEffectInfoTable[EFFECT_SPARK].draw(&sEffectContext.sparks[i].effect, gfxCtx);
}
}
for (i = 0; i < BLURE_COUNT; i++) {
if (sEffectContext.blures[i].status.active) {
sEffectInfoTable[EFFECT_BLURE1].draw(&sEffectContext.blures[i].effect, gfxCtx);
}
if (1) {} // Necessary to match
if (1) {}
}
for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) {
if (sEffectContext.shieldParticles[i].status.active) {
if (gfxCtx) {} // Necessary to match
sEffectInfoTable[EFFECT_SHIELD_PARTICLE].draw(&sEffectContext.shieldParticles[i].effect, gfxCtx);
}
}
}
void Effect_UpdateAll(GlobalContext* globalCtx) {
s32 i;
for (i = 0; i < SPARK_COUNT; i++) {
if (sEffectContext.sparks[i].status.active) {
if (sEffectInfoTable[EFFECT_SPARK].update(&sEffectContext.sparks[i].effect) == 1) {
Effect_Delete(globalCtx, i);
}
}
}
for (i = 0; i < BLURE_COUNT; i++) {
if (sEffectContext.blures[i].status.active) {
if (sEffectInfoTable[EFFECT_BLURE1].update(&sEffectContext.blures[i].effect) == 1) {
Effect_Delete(globalCtx, i + SPARK_COUNT);
}
}
}
for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) {
if (sEffectContext.shieldParticles[i].status.active) {
if (sEffectInfoTable[EFFECT_SHIELD_PARTICLE].update(&sEffectContext.shieldParticles[i].effect) == 1) {
Effect_Delete(globalCtx, i + SPARK_COUNT + BLURE_COUNT);
}
}
}
}
void Effect_Delete(GlobalContext* globalCtx, s32 index) {
if (index == TOTAL_EFFECT_COUNT) {
return;
}
if (index < SPARK_COUNT) {
sEffectContext.sparks[index].status.active = false;
sEffectInfoTable[EFFECT_SPARK].destroy(&sEffectContext.sparks[index].effect);
return;
}
index -= SPARK_COUNT;
if (index < BLURE_COUNT) {
sEffectContext.blures[index].status.active = false;
sEffectInfoTable[EFFECT_BLURE1].destroy(&sEffectContext.blures[index].effect);
return;
}
index -= BLURE_COUNT;
if (index < SHIELD_PARTICLE_COUNT) {
sEffectContext.shieldParticles[index].status.active = false;
sEffectInfoTable[EFFECT_SHIELD_PARTICLE].destroy(&sEffectContext.shieldParticles[index].effect);
return;
}
}
void Effect_DeleteAll(GlobalContext* globalCtx) {
s32 i;
osSyncPrintf("エフェクト総て解放\n"); // "All effect release"
for (i = 0; i < SPARK_COUNT; i++) {
sEffectContext.sparks[i].status.active = false;
sEffectInfoTable[EFFECT_SPARK].destroy(&sEffectContext.sparks[i].effect);
}
for (i = 0; i < BLURE_COUNT; i++) {
sEffectContext.blures[i].status.active = false;
sEffectInfoTable[EFFECT_BLURE1].destroy(&sEffectContext.blures[i].effect);
}
for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) {
sEffectContext.shieldParticles[i].status.active = false;
sEffectInfoTable[EFFECT_SHIELD_PARTICLE].destroy(&sEffectContext.shieldParticles[i].effect);
}
osSyncPrintf("エフェクト総て解放 終了\n"); // "All effects release End"
}

View file

@ -0,0 +1,338 @@
#include "global.h"
#include "vt.h"
EffectSsInfo sEffectSsInfo = { 0 }; // "EffectSS2Info"
void EffectSs_InitInfo(GlobalContext* globalCtx, s32 tableSize) {
u32 i;
EffectSs* effectSs;
EffectSsOverlay* overlay;
for (i = 0; i < ARRAY_COUNT(gEffectSsOverlayTable); i++) {
overlay = &gEffectSsOverlayTable[i];
osSyncPrintf("effect index %3d:size=%6dbyte romsize=%6dbyte\n", i,
(uintptr_t)overlay->vramEnd - (uintptr_t)overlay->vramStart, overlay->vromEnd - overlay->vromStart);
}
sEffectSsInfo.table =
GameState_Alloc(&globalCtx->state, tableSize * sizeof(EffectSs), "../z_effect_soft_sprite.c", 289);
ASSERT(sEffectSsInfo.table != NULL, "EffectSS2Info.data_table != NULL", "../z_effect_soft_sprite.c", 290);
sEffectSsInfo.searchStartIndex = 0;
sEffectSsInfo.tableSize = tableSize;
for (effectSs = &sEffectSsInfo.table[0]; effectSs < &sEffectSsInfo.table[sEffectSsInfo.tableSize]; effectSs++) {
EffectSs_Reset(effectSs);
}
overlay = &gEffectSsOverlayTable[0];
for (i = 0; i < ARRAY_COUNT(gEffectSsOverlayTable); i++) {
overlay->loadedRamAddr = NULL;
overlay++;
}
}
void EffectSs_ClearAll(GlobalContext* globalCtx) {
u32 i;
EffectSs* effectSs;
EffectSsOverlay* overlay;
void* addr;
sEffectSsInfo.table = NULL;
sEffectSsInfo.searchStartIndex = 0;
sEffectSsInfo.tableSize = 0;
// This code doesn't actually work, since table was just set to NULL and tableSize to 0
for (effectSs = &sEffectSsInfo.table[0]; effectSs < &sEffectSsInfo.table[sEffectSsInfo.tableSize]; effectSs++) {
EffectSs_Delete(effectSs);
}
overlay = &gEffectSsOverlayTable[0];
for (i = 0; i < ARRAY_COUNT(gEffectSsOverlayTable); i++) {
addr = overlay->loadedRamAddr;
if (addr != NULL) {
ZeldaArena_FreeDebug(addr, "../z_effect_soft_sprite.c", 337);
}
overlay->loadedRamAddr = NULL;
overlay++;
}
}
void EffectSs_Delete(EffectSs* effectSs) {
if (effectSs->flags & 2) {
Audio_StopSfxByPos(&effectSs->pos);
}
if (effectSs->flags & 4) {
Audio_StopSfxByPos(&effectSs->vec);
}
EffectSs_Reset(effectSs);
}
void EffectSs_Reset(EffectSs* effectSs) {
u32 i;
effectSs->type = EFFECT_SS_TYPE_MAX;
effectSs->accel.x = effectSs->accel.y = effectSs->accel.z = 0;
effectSs->velocity.x = effectSs->velocity.y = effectSs->velocity.z = 0;
effectSs->vec.x = effectSs->vec.y = effectSs->vec.z = 0;
effectSs->pos.x = effectSs->pos.y = effectSs->pos.z = 0;
effectSs->life = -1;
effectSs->flags = 0;
effectSs->priority = 128;
effectSs->draw = NULL;
effectSs->update = NULL;
effectSs->gfx = NULL;
effectSs->actor = NULL;
for (i = 0; i < ARRAY_COUNT(effectSs->regs); i++) {
effectSs->regs[i] = 0;
}
}
s32 EffectSs_FindSlot(s32 priority, s32* pIndex) {
s32 foundFree;
s32 i;
if (sEffectSsInfo.searchStartIndex >= sEffectSsInfo.tableSize) {
sEffectSsInfo.searchStartIndex = 0;
}
// Search for a free slot
i = sEffectSsInfo.searchStartIndex;
foundFree = false;
while (true) {
if (sEffectSsInfo.table[i].life == -1) {
foundFree = true;
break;
}
i++;
if (i >= sEffectSsInfo.tableSize) {
i = 0; // Loop around the whole table
}
// After a full loop, break out
if (i == sEffectSsInfo.searchStartIndex) {
break;
}
}
if (foundFree == true) {
*pIndex = i;
return 0;
}
// If all slots are in use, search for a slot with a lower priority
// Note that a lower priority is representend by a higher value
i = sEffectSsInfo.searchStartIndex;
while (true) {
// Equal priority should only be considered "lower" if flag 0 is set
if ((priority <= sEffectSsInfo.table[i].priority) &&
!((priority == sEffectSsInfo.table[i].priority) && (sEffectSsInfo.table[i].flags & 1))) {
break;
}
i++;
if (i >= sEffectSsInfo.tableSize) {
i = 0; // Loop around the whole table
}
// After a full loop, return 1 to indicate that we failed to find a suitable slot
if (i == sEffectSsInfo.searchStartIndex) {
return 1;
}
}
*pIndex = i;
return 0;
}
void EffectSs_Insert(GlobalContext* globalCtx, EffectSs* effectSs) {
s32 index;
if (FrameAdvance_IsEnabled(globalCtx) != true) {
if (EffectSs_FindSlot(effectSs->priority, &index) == 0) {
sEffectSsInfo.searchStartIndex = index + 1;
sEffectSsInfo.table[index] = *effectSs;
}
}
}
// original name: "EffectSoftSprite2_makeEffect"
void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* initParams) {
s32 index;
u32 overlaySize;
EffectSsOverlay* overlayEntry;
EffectSsInit* initInfo;
overlayEntry = &gEffectSsOverlayTable[type];
ASSERT(type < EFFECT_SS_TYPE_MAX, "type < EFFECT_SS2_TYPE_LAST_LABEL", "../z_effect_soft_sprite.c", 556);
if (EffectSs_FindSlot(priority, &index) != 0) {
// Abort because we couldn't find a suitable slot to add this effect in
return;
}
sEffectSsInfo.searchStartIndex = index + 1;
overlaySize = (uintptr_t)overlayEntry->vramEnd - (uintptr_t)overlayEntry->vramStart;
if (overlayEntry->vramStart == NULL) {
// "Not an overlay"
osSyncPrintf("EffectSoftSprite2_makeEffect():オーバーレイではありません。\n");
initInfo = overlayEntry->initInfo;
} else {
if (overlayEntry->loadedRamAddr == NULL) {
overlayEntry->loadedRamAddr = ZeldaArena_MallocRDebug(overlaySize, "../z_effect_soft_sprite.c", 585);
if (overlayEntry->loadedRamAddr == NULL) {
osSyncPrintf(VT_FGCOL(RED));
// "The memory of %d byte cannot be secured. Therefore, the program cannot be loaded.
// What a dangerous situation! Naturally, effects will not produced either."
osSyncPrintf("EffectSoftSprite2_makeEffect():zelda_malloc_r()により,%"
"dbyteのメモリ確保ができま\nせん。そのため、プログラムのロードも\n出来ません。ただいま危険"
"な状態です!\nもちろん,エフェクトも出ません。\n",
overlaySize);
osSyncPrintf(VT_RST);
return;
}
Overlay_Load(overlayEntry->vromStart, overlayEntry->vromEnd, overlayEntry->vramStart, overlayEntry->vramEnd,
overlayEntry->loadedRamAddr);
osSyncPrintf(VT_FGCOL(GREEN));
osSyncPrintf("EFFECT SS OVL:SegRom %08x %08x, Seg %08x %08x, RamStart %08x, type: %d\n",
overlayEntry->vromStart, overlayEntry->vromEnd, overlayEntry->vramStart, overlayEntry->vramEnd,
overlayEntry->loadedRamAddr, type);
osSyncPrintf(VT_RST);
}
initInfo = (void*)(uintptr_t)((overlayEntry->initInfo != NULL)
? (void*)((uintptr_t)overlayEntry->initInfo -
((intptr_t)overlayEntry->vramStart - (intptr_t)overlayEntry->loadedRamAddr))
: NULL);
}
if (initInfo->init == NULL) {
// "Effects have already been loaded, but the constructor is NULL so the addition will not occur.
// Please fix this. (Waste of memory) %08x %d"
osSyncPrintf("EffectSoftSprite2_makeEffect():すでにエフェクトはロード済みで\nすが,"
"コンストラクターがNULLなので追加をやめます。\n直してください。(メモリーの無駄) %08x %d\n",
initInfo, type);
return;
}
// Delete the previous effect in the slot, in case the slot wasn't free
EffectSs_Delete(&sEffectSsInfo.table[index]);
sEffectSsInfo.table[index].type = type;
sEffectSsInfo.table[index].priority = priority;
if (initInfo->init(globalCtx, index, &sEffectSsInfo.table[index], initParams) == 0) {
osSyncPrintf(VT_FGCOL(GREEN));
// "Construction failed for some reason. The constructor returned an error.
// Ceasing effect addition."
osSyncPrintf("EffectSoftSprite2_makeEffect():"
"何らかの理由でコンストラクト失敗。コンストラクターがエラーを返しました。エフェクトの追加を中"
"止します。\n");
osSyncPrintf(VT_RST);
EffectSs_Reset(&sEffectSsInfo.table[index]);
}
}
void EffectSs_Update(GlobalContext* globalCtx, s32 index) {
EffectSs* effectSs = &sEffectSsInfo.table[index];
if (effectSs->update != NULL) {
effectSs->velocity.x += effectSs->accel.x;
effectSs->velocity.y += effectSs->accel.y;
effectSs->velocity.z += effectSs->accel.z;
effectSs->pos.x += effectSs->velocity.x;
effectSs->pos.y += effectSs->velocity.y;
effectSs->pos.z += effectSs->velocity.z;
effectSs->update(globalCtx, index, effectSs);
}
}
void EffectSs_UpdateAll(GlobalContext* globalCtx) {
s32 i;
for (i = 0; i < sEffectSsInfo.tableSize; i++) {
if (sEffectSsInfo.table[i].life > -1) {
sEffectSsInfo.table[i].life--;
if (sEffectSsInfo.table[i].life < 0) {
EffectSs_Delete(&sEffectSsInfo.table[i]);
}
}
if (sEffectSsInfo.table[i].life > -1) {
EffectSs_Update(globalCtx, i);
}
}
}
void EffectSs_Draw(GlobalContext* globalCtx, s32 index) {
EffectSs* effectSs = &sEffectSsInfo.table[index];
if (effectSs->draw != NULL) {
effectSs->draw(globalCtx, index, effectSs);
}
}
// original name: "EffectSoftSprite2_disp"
void EffectSs_DrawAll(GlobalContext* globalCtx) {
Lights* lights = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx);
s32 i;
Lights_BindAll(lights, globalCtx->lightCtx.listHead, NULL);
Lights_Draw(lights, globalCtx->state.gfxCtx);
for (i = 0; i < sEffectSsInfo.tableSize; i++) {
if (sEffectSsInfo.table[i].life > -1) {
if ((sEffectSsInfo.table[i].pos.x > 32000.0f) || (sEffectSsInfo.table[i].pos.x < -32000.0f) ||
(sEffectSsInfo.table[i].pos.y > 32000.0f) || (sEffectSsInfo.table[i].pos.y < -32000.0f) ||
(sEffectSsInfo.table[i].pos.z > 32000.0f) || (sEffectSsInfo.table[i].pos.z < -32000.0f)) {
osSyncPrintf(VT_FGCOL(RED));
// "Since the position is outside the area, delete it.
// Effect label No. %d: Please respond by the program.
// Here is ==> pos (%f, %f, %f) and the label is in z_effect_soft_sprite_dlftbls.decl."
osSyncPrintf("EffectSoftSprite2_disp():位置が領域外のため "
"削除します。エフェクトラベルNo.%d:プログラムの方で対応をお願いします。ここです ==> "
"pos(%f, %f, %f)で、ラベルはz_effect_soft_sprite_dlftbls.declにあります。\n",
sEffectSsInfo.table[i].type, sEffectSsInfo.table[i].pos.x, sEffectSsInfo.table[i].pos.y,
sEffectSsInfo.table[i].pos.z);
osSyncPrintf(VT_FGCOL(GREEN));
// "If you are using pos for something else, consult me."
osSyncPrintf("もし、posを別のことに使っている場合相談に応じます。\n");
osSyncPrintf(VT_RST);
EffectSs_Delete(&sEffectSsInfo.table[i]);
} else {
EffectSs_Draw(globalCtx, i);
}
}
}
}
s16 func_80027DD4(s16 arg0, s16 arg1, s32 arg2) {
s16 ret = (arg2 == 0) ? arg1 : (arg0 + (s32)((arg1 - arg0) / (f32)arg2));
return ret;
}
s16 func_80027E34(s16 arg0, s16 arg1, f32 arg2) {
return (arg1 - arg0) * arg2 + arg0;
}
u8 func_80027E84(u8 arg0, u8 arg1, f32 arg2) {
return arg2 * ((f32)arg1 - (f32)arg0) + arg0;
}

View file

@ -0,0 +1,51 @@
#include "global.h"
// Linker symbol declarations (used in the table below)
#define DEFINE_EFFECT_SS(name, _1) DECLARE_OVERLAY_SEGMENT(name)
#define DEFINE_EFFECT_SS_UNSET(_0)
#include "tables/effect_ss_table.h"
#undef DEFINE_EFFECT_SS
#undef DEFINE_EFFECT_SS_UNSET
// Init Vars declarations (also used in the table below)
#define DEFINE_EFFECT_SS(name, _1) extern EffectSsInit name##_InitVars;
#define DEFINE_EFFECT_SS_UNSET(_0)
#include "tables/effect_ss_table.h"
#undef DEFINE_EFFECT_SS
#undef DEFINE_EFFECT_SS_UNSET
// Effect SS Overlay Table definition
//#define DEFINE_EFFECT_SS(name, _1) \
// { \
// (uintptr_t)_ovl_##name##SegmentRomStart, \
// (uintptr_t)_ovl_##name##SegmentRomEnd, \
// _ovl_##name##SegmentStart, \
// _ovl_##name##SegmentEnd, \
// NULL, \
// &name##_InitVars, \
// 1, \
// },
#define DEFINE_EFFECT_SS(name, _1) \
{ \
(uintptr_t)0, \
(uintptr_t)0, \
0, \
0, \
NULL, \
&name##_InitVars, \
1, \
},
#define DEFINE_EFFECT_SS_UNSET(_0) { 0 },
EffectSsOverlay gEffectSsOverlayTable[] = {
#include "tables/effect_ss_table.h"
};
#undef DEFINE_EFFECT_SS
#undef DEFINE_EFFECT_SS_UNSET

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,174 @@
#include "global.h"
#include "z64elf_message.h"
ElfMessage sChildSariaMsgs[] = {
ELF_MSG_STRENGTH_UPG(SKIP, 3, false, 0),
ELF_MSG_FLAG(CHECK, 0x61, false, 0x37), /* eventChkInf[3] & 0x80 */
ELF_MSG_END(0x64),
ELF_MSG_FLAG(CHECK, 0x62, false, 0x25), /* eventChkInf[2] & 0x20 */
ELF_MSG_FLAG(CHECK, 0x63, false, 0x37), /* eventChkInf[3] & 0x80 */
ELF_MSG_FLAG(CHECK, 0x65, false, 0x43), /* eventChkInf[4] & 0x8 */
ELF_MSG_MEDALLION(CHECK, 0x66, false, ITEM_MEDALLION_FOREST),
ELF_MSG_MEDALLION(CHECK, 0x66, false, ITEM_MEDALLION_FIRE),
ELF_MSG_MEDALLION(CHECK, 0x66, false, ITEM_MEDALLION_WATER),
ELF_MSG_SONG(CHECK, 0x67, false, ITEM_SONG_STORMS),
ELF_MSG_MEDALLION(CHECK, 0x68, false, ITEM_MEDALLION_SPIRIT),
ELF_MSG_MEDALLION(CHECK, 0x68, false, ITEM_MEDALLION_SHADOW),
ELF_MSG_END(0x69),
};
ElfMessage sAdultSariaMsgs[] = {
ELF_MSG_MEDALLION(CHECK, 0x6A, false, ITEM_MEDALLION_FOREST),
ELF_MSG_MEDALLION(CHECK, 0x6B, false, ITEM_MEDALLION_FIRE),
ELF_MSG_MEDALLION(CHECK, 0x6B, false, ITEM_MEDALLION_WATER),
ELF_MSG_MEDALLION(CHECK, 0x6C, false, ITEM_MEDALLION_SPIRIT),
ELF_MSG_MEDALLION(CHECK, 0x6C, false, ITEM_MEDALLION_SHADOW),
ELF_MSG_END(0x6D),
};
u32 ElfMessage_CheckCondition(ElfMessage* msg) {
s32 type = msg->byte0 & 0x1E;
u16 flag;
switch (type) {
case (ELF_MSG_CONDITION_FLAG << 1):
flag = 1 << (msg->byte1 & 0x0F);
return ((msg->byte0 & 1) == 1) == ((flag & gSaveContext.eventChkInf[(msg->byte1 & 0xF0) >> 4]) != 0);
case (ELF_MSG_CONDITION_DUNGEON_ITEM << 1):
return ((msg->byte0 & 1) == 1) ==
(CHECK_DUNGEON_ITEM(msg->byte1 - ITEM_KEY_BOSS, gSaveContext.mapIndex) != 0);
case (ELF_MSG_CONDITION_ITEM << 1):
return ((msg->byte0 & 1) == 1) == (msg->byte3 == INV_CONTENT(msg->byte1));
case (ELF_MSG_CONDITION_OTHER << 1):
switch (msg->byte1 & 0xF0) {
case (ELF_MSG_CONDITION_STRENGTH_UPG << 4):
return ((msg->byte0 & 1) == 1) == ((msg->byte1 & 0x0F) == CUR_UPG_VALUE(UPG_STRENGTH));
case (ELF_MSG_CONDITION_BOOTS << 4):
return ((msg->byte0 & 1) == 1) ==
(((gBitFlags[msg->byte3 - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]) &
gSaveContext.inventory.equipment) != 0);
case (ELF_MSG_CONDITION_SONG << 4):
return ((msg->byte0 & 1) == 1) ==
(CHECK_QUEST_ITEM(msg->byte3 - ITEM_SONG_MINUET + QUEST_SONG_MINUET) != 0);
case (ELF_MSG_CONDITION_MEDALLION << 4):
return ((msg->byte0 & 1) == 1) ==
(CHECK_QUEST_ITEM(msg->byte3 - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST) != 0);
case (ELF_MSG_CONDITION_MAGIC << 4):
return ((msg->byte0 & 1) == 1) == (((void)0, gSaveContext.magicAcquired) != 0);
}
}
LOG_STRING("企画外 条件", "../z_elf_message.c", 156); // "Unplanned conditions"
ASSERT(0, "0", "../z_elf_message.c", 157);
return false;
}
u32 func_8006BE88(ElfMessage** msgp) {
u32 temp = true;
while (((*msgp)->byte0 & 0xE0) == (ELF_MSG_TYPE_UNK_1 << 5)) {
if (!ElfMessage_CheckCondition(*msgp)) {
temp = false;
}
*msgp += 1;
}
if (temp) {
return ElfMessage_CheckCondition(*msgp);
} else {
return false;
}
}
u32 func_8006BF1C(ElfMessage** msgp) {
ElfMessage* msg = *msgp;
u32 sp44[10];
s32 temp1 = 0;
s32 temp2 = 0;
s32 temp3;
do {
sp44[temp2] = ElfMessage_CheckCondition(msg);
temp1 += sp44[temp2];
temp2++;
msg++;
} while ((msg->byte0 & 0xE0) == (ELF_MSG_TYPE_UNK_2 << 5));
if (temp1 == 0) {
return false;
}
temp3 = Rand_ZeroFloat(temp1);
for (temp1 = 0; temp1 < temp2; temp1++) {
if (sp44[temp1]) {
if (temp3 > 0) {
temp3--;
} else {
return true;
}
}
*msgp += 1;
}
return false;
}
u16 ElfMessage_GetTextFromMsgs(ElfMessage* msg) {
while (true) {
switch (msg->byte0 & 0xE0) {
case (ELF_MSG_TYPE_CHECK << 5):
if (ElfMessage_CheckCondition(msg)) {
return msg->byte2 | 0x100;
}
break;
case (ELF_MSG_TYPE_UNK_1 << 5):
if (func_8006BE88(&msg)) {
return msg->byte2 | 0x100;
}
break;
case (ELF_MSG_TYPE_UNK_2 << 5):
if (func_8006BF1C(&msg)) {
return msg->byte2 | 0x100;
}
break;
case (ELF_MSG_TYPE_SKIP << 5):
if (ElfMessage_CheckCondition(msg)) {
msg += msg->byte2;
msg--;
}
break;
case (ELF_MSG_TYPE_END << 5):
return msg->byte2 | 0x100;
default:
LOG_STRING("企画外 条件", "../z_elf_message.c", 281); // "Unplanned conditions"
ASSERT(0, "0", "../z_elf_message.c", 282);
}
msg++;
}
}
u16 ElfMessage_GetSariaText(GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
ElfMessage* msgs;
if (!LINK_IS_ADULT) {
if (Actor_FindNearby(globalCtx, &player->actor, ACTOR_EN_SA, 4, 800.0f) == NULL) {
msgs = sChildSariaMsgs;
} else {
return 0x0160; // Special text about Saria preferring to talk to you face-to-face
}
} else {
msgs = sAdultSariaMsgs;
}
return ElfMessage_GetTextFromMsgs(msgs);
}
u16 ElfMessage_GetCUpText(GlobalContext* globalCtx) {
if (globalCtx->cUpElfMsgs == NULL) {
return 0;
} else {
return ElfMessage_GetTextFromMsgs(globalCtx->cUpElfMsgs);
}
}

368
soh/src/code/z_en_a_keep.c Normal file
View file

@ -0,0 +1,368 @@
#include "global.h"
#include "vt.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include <objects/object_d_hsblock/object_d_hsblock.h>
#define FLAGS ACTOR_FLAG_4
void EnAObj_Init(Actor* thisx, GlobalContext* globalCtx);
void EnAObj_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnAObj_Update(Actor* thisx, GlobalContext* globalCtx);
void EnAObj_Draw(Actor* thisx, GlobalContext* globalCtx);
void EnAObj_WaitFinishedTalking(EnAObj* this, GlobalContext* globalCtx);
void EnAObj_WaitTalk(EnAObj* this, GlobalContext* globalCtx);
void EnAObj_BlockRot(EnAObj* this, GlobalContext* globalCtx);
void EnAObj_BoulderFragment(EnAObj* this, GlobalContext* globalCtx);
void EnAObj_Block(EnAObj* this, GlobalContext* globalCtx);
void EnAObj_SetupWaitTalk(EnAObj* this, s16 type);
void EnAObj_SetupBlockRot(EnAObj* this, s16 type);
void EnAObj_SetupBoulderFragment(EnAObj* this, s16 type);
void EnAObj_SetupBlock(EnAObj* this, s16 type);
const ActorInit En_A_Obj_InitVars = {
ACTOR_EN_A_OBJ,
ACTORCAT_PROP,
FLAGS,
OBJECT_GAMEPLAY_KEEP,
sizeof(EnAObj),
(ActorFunc)EnAObj_Init,
(ActorFunc)EnAObj_Destroy,
(ActorFunc)EnAObj_Update,
(ActorFunc)EnAObj_Draw,
NULL,
};
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_ALL,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_2,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK2,
{ 0x00000000, 0x00, 0x00 },
{ 0xFFCFFFFF, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_ON,
},
{ 25, 60, 0, { 0, 0, 0 } },
};
//extern CollisionHeader D_06000730; // gHookshotTargetCol ?
static CollisionHeader* sColHeaders[] = {
&gLargerCubeCol, // A_OBJ_GRASS_CLUMP, A_OBJ_TREE_STUMP
&gLargerCubeCol, // A_OBJ_BLOCK_LARGE, A_OBJ_BLOCK_HUGE
&gSmallerFlatBlockCol, // unused
&gLargerFlatBlockCol, // A_OBJ_BLOCK_SMALL_ROT, A_OBJ_BLOCK_LARGE_ROT
&gSmallerCubeCol, // unused
//&D_06000730, // A_OBJ_UNKNOWN_6 // OTRTODO
};
static Gfx* sDLists[] = {
gFlatBlockDL,
gFlatBlockDL,
gFlatBlockDL,
gFlatRotBlockDL,
gFlatRotBlockDL,
gSmallCubeDL,
gHookshotPostDL, /* gHookshotPostDL ? */ // 0x06000210, // OTRTODO!
gGrassBladesDL,
gTreeStumpDL,
gSignRectangularDL,
gSignDirectionalDL,
gBoulderFragmentsDL,
};
void EnAObj_SetupAction(EnAObj* this, EnAObjActionFunc actionFunc) {
this->actionFunc = actionFunc;
}
void EnAObj_Init(Actor* thisx, GlobalContext* globalCtx) {
CollisionHeader* colHeader = NULL;
s32 pad;
EnAObj* this = (EnAObj*)thisx;
f32 shadowScale = 6.0f;
this->textId = (thisx->params >> 8) & 0xFF;
thisx->params &= 0xFF;
switch (thisx->params) {
case A_OBJ_BLOCK_SMALL:
Actor_SetScale(thisx, 0.025f);
break;
case A_OBJ_BLOCK_LARGE:
Actor_SetScale(thisx, 0.05f);
break;
case A_OBJ_BLOCK_HUGE:
case A_OBJ_CUBE_SMALL:
case A_OBJ_UNKNOWN_6:
Actor_SetScale(thisx, 0.1f);
break;
case A_OBJ_BLOCK_SMALL_ROT:
Actor_SetScale(thisx, 0.005f);
break;
case A_OBJ_BLOCK_LARGE_ROT:
default:
Actor_SetScale(thisx, 0.01f);
break;
}
if (thisx->params >= A_OBJ_SIGNPOST_OBLONG) {
shadowScale = 12.0f;
}
ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, shadowScale);
thisx->focus.pos = thisx->world.pos;
this->dyna.bgId = BGACTOR_NEG_ONE;
this->dyna.unk_160 = 0;
this->dyna.unk_15C = DPM_UNK;
thisx->uncullZoneDownward = 1200.0f;
thisx->uncullZoneScale = 200.0f;
switch (thisx->params) {
case A_OBJ_BLOCK_LARGE:
case A_OBJ_BLOCK_HUGE:
this->dyna.bgId = 1;
Actor_ChangeCategory(globalCtx, &globalCtx->actorCtx, thisx, ACTORCAT_BG);
EnAObj_SetupBlock(this, thisx->params);
break;
case A_OBJ_BLOCK_SMALL_ROT:
case A_OBJ_BLOCK_LARGE_ROT:
this->dyna.bgId = 3;
Actor_ChangeCategory(globalCtx, &globalCtx->actorCtx, thisx, ACTORCAT_BG);
EnAObj_SetupBlockRot(this, thisx->params);
break;
case A_OBJ_UNKNOWN_6:
// clang-format off
thisx->flags |= ACTOR_FLAG_0; this->dyna.bgId = 5; this->focusYoffset = 10.0f;
// clang-format on
thisx->gravity = -2.0f;
EnAObj_SetupWaitTalk(this, thisx->params);
break;
case A_OBJ_GRASS_CLUMP:
case A_OBJ_TREE_STUMP:
this->dyna.bgId = 0;
EnAObj_SetupWaitTalk(this, thisx->params);
break;
case A_OBJ_SIGNPOST_OBLONG:
case A_OBJ_SIGNPOST_ARROW:
thisx->textId = (this->textId & 0xFF) | 0x300;
// clang-format off
thisx->flags |= ACTOR_FLAG_0 | ACTOR_FLAG_3; thisx->targetArrowOffset = 500.0f;
// clang-format on
this->focusYoffset = 45.0f;
EnAObj_SetupWaitTalk(this, thisx->params);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, thisx, &sCylinderInit);
thisx->colChkInfo.mass = MASS_IMMOVABLE;
thisx->targetMode = 0;
break;
case A_OBJ_BOULDER_FRAGMENT:
thisx->gravity = -1.5f;
EnAObj_SetupBoulderFragment(this, thisx->params);
break;
default:
thisx->gravity = -2.0f;
EnAObj_SetupWaitTalk(this, thisx->params);
break;
}
if (thisx->params <= A_OBJ_BLOCK_LARGE_ROT) { // A_OBJ_BLOCK_*
thisx->colChkInfo.mass = MASS_IMMOVABLE;
}
if (this->dyna.bgId != BGACTOR_NEG_ONE) {
CollisionHeader_GetVirtual(sColHeaders[this->dyna.bgId], &colHeader);
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader);
}
}
void EnAObj_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnAObj* this = (EnAObj*)thisx;
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
switch (this->dyna.actor.params) {
case A_OBJ_SIGNPOST_OBLONG:
case A_OBJ_SIGNPOST_ARROW:
Collider_DestroyCylinder(globalCtx, &this->collider);
break;
}
}
void EnAObj_WaitFinishedTalking(EnAObj* this, GlobalContext* globalCtx) {
if (Actor_TextboxIsClosing(&this->dyna.actor, globalCtx)) {
EnAObj_SetupWaitTalk(this, this->dyna.actor.params);
}
}
void EnAObj_SetupWaitTalk(EnAObj* this, s16 type) {
EnAObj_SetupAction(this, EnAObj_WaitTalk);
}
void EnAObj_WaitTalk(EnAObj* this, GlobalContext* globalCtx) {
s16 relYawTowardsPlayer;
if (this->dyna.actor.textId != 0) {
relYawTowardsPlayer = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.shape.rot.y;
if (ABS(relYawTowardsPlayer) < 0x2800 ||
(this->dyna.actor.params == A_OBJ_SIGNPOST_ARROW && ABS(relYawTowardsPlayer) > 0x5800)) {
if (Actor_ProcessTalkRequest(&this->dyna.actor, globalCtx)) {
EnAObj_SetupAction(this, EnAObj_WaitFinishedTalking);
} else {
func_8002F2F4(&this->dyna.actor, globalCtx);
}
}
}
}
void EnAObj_SetupBlockRot(EnAObj* this, s16 type) {
this->rotateState = 0;
this->rotateWaitTimer = 10;
this->dyna.actor.world.rot.y = 0;
this->dyna.actor.shape.rot = this->dyna.actor.world.rot;
EnAObj_SetupAction(this, EnAObj_BlockRot);
}
void EnAObj_BlockRot(EnAObj* this, GlobalContext* globalCtx) {
if (this->rotateState == 0) {
if (this->dyna.unk_160 != 0) {
this->rotateState++;
this->rotateForTimer = 20;
if ((s16)(this->dyna.actor.yawTowardsPlayer + 0x4000) < 0) {
this->rotSpeedX = -0x3E8;
} else {
this->rotSpeedX = 0x3E8;
}
if (this->dyna.actor.yawTowardsPlayer < 0) {
this->rotSpeedY = -this->rotSpeedX;
} else {
this->rotSpeedY = this->rotSpeedX;
}
}
} else {
if (this->rotateWaitTimer != 0) {
this->rotateWaitTimer--;
} else {
this->dyna.actor.shape.rot.y += this->rotSpeedY;
this->dyna.actor.shape.rot.x += this->rotSpeedX;
this->rotateForTimer--;
this->dyna.actor.gravity = -1.0f;
if (this->rotateForTimer == 0) {
this->dyna.actor.world.pos = this->dyna.actor.home.pos;
this->rotateState = 0;
this->rotateWaitTimer = 10;
this->dyna.actor.velocity.y = 0.0f;
this->dyna.actor.gravity = 0.0f;
this->dyna.actor.shape.rot = this->dyna.actor.world.rot;
}
}
}
}
void EnAObj_SetupBoulderFragment(EnAObj* this, s16 type) {
EnAObj_SetupAction(this, EnAObj_BoulderFragment);
}
void EnAObj_BoulderFragment(EnAObj* this, GlobalContext* globalCtx) {
Math_SmoothStepToF(&this->dyna.actor.speedXZ, 1.0f, 1.0f, 0.5f, 0.0f);
this->dyna.actor.shape.rot.x += this->dyna.actor.world.rot.x >> 1;
this->dyna.actor.shape.rot.z += this->dyna.actor.world.rot.z >> 1;
if (this->dyna.actor.speedXZ != 0.0f && this->dyna.actor.bgCheckFlags & 0x8) {
this->dyna.actor.world.rot.y =
this->dyna.actor.wallYaw - this->dyna.actor.world.rot.y + this->dyna.actor.wallYaw - 0x8000;
if (1) {}
this->dyna.actor.bgCheckFlags &= ~0x8;
}
if (this->dyna.actor.bgCheckFlags & 0x2) {
if (this->dyna.actor.velocity.y < -8.0f) {
this->dyna.actor.velocity.y *= -0.6f;
this->dyna.actor.speedXZ *= 0.6f;
this->dyna.actor.bgCheckFlags &= ~0x3;
} else {
Actor_Kill(&this->dyna.actor);
}
}
}
void EnAObj_SetupBlock(EnAObj* this, s16 type) {
this->dyna.actor.uncullZoneDownward = 1200.0f;
this->dyna.actor.uncullZoneScale = 720.0f;
EnAObj_SetupAction(this, EnAObj_Block);
}
void EnAObj_Block(EnAObj* this, GlobalContext* globalCtx) {
this->dyna.actor.speedXZ += this->dyna.unk_150;
this->dyna.actor.world.rot.y = this->dyna.unk_158;
this->dyna.actor.speedXZ = CLAMP(this->dyna.actor.speedXZ, -2.5f, 2.5f);
Math_SmoothStepToF(&this->dyna.actor.speedXZ, 0.0f, 1.0f, 1.0f, 0.0f);
if (this->dyna.actor.speedXZ != 0.0f) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG);
}
this->dyna.unk_154 = 0.0f;
this->dyna.unk_150 = 0.0f;
}
void EnAObj_Update(Actor* thisx, GlobalContext* globalCtx) {
EnAObj* this = (EnAObj*)thisx;
this->actionFunc(this, globalCtx);
Actor_MoveForward(&this->dyna.actor);
if (this->dyna.actor.gravity != 0.0f) {
if (this->dyna.actor.params != A_OBJ_BOULDER_FRAGMENT) {
Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 5.0f, 40.0f, 0.0f, 0x1D);
} else {
Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 5.0f, 20.0f, 0.0f, 0x1D);
}
}
this->dyna.actor.focus.pos = this->dyna.actor.world.pos;
this->dyna.actor.focus.pos.y += this->focusYoffset;
switch (this->dyna.actor.params) {
case A_OBJ_SIGNPOST_OBLONG:
case A_OBJ_SIGNPOST_ARROW:
Collider_UpdateCylinder(&this->dyna.actor, &this->collider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
break;
}
}
void EnAObj_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 type = thisx->params;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_a_keep.c", 701);
func_80093D18(globalCtx->state.gfxCtx);
if (type >= A_OBJ_MAX) {
type = A_OBJ_BOULDER_FRAGMENT;
}
if (thisx->params == A_OBJ_BOULDER_FRAGMENT) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 1, 60, 60, 60, 50);
}
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_a_keep.c", 712),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDLists[type]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_a_keep.c", 715);
}

1329
soh/src/code/z_en_item00.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,70 @@
#include "global.h"
u16 sReactionTextIds[][PLAYER_MASK_MAX] = {
{ 0x0000, 0x7124, 0x7127, 0x7126, 0x7125, 0x7127, 0x7124, 0x7125, 0x7127 },
{ 0x0000, 0x7128, 0x7129, 0x7128, 0x7128, 0x7128, 0x7128, 0x712A, 0x712B },
{ 0x0000, 0x7128, 0x712B, 0x7128, 0x7128, 0x7129, 0x7128, 0x712B, 0x7128 },
{ 0x0000, 0x7128, 0x7129, 0x7128, 0x7128, 0x7128, 0x7128, 0x712A, 0x712B },
{ 0x0000, 0x7128, 0x7129, 0x712B, 0x7128, 0x7128, 0x7128, 0x7129, 0x7128 },
{ 0x0000, 0x712D, 0x712D, 0x712D, 0x712D, 0x712D, 0x712D, 0x712D, 0x712F },
{ 0x0000, 0x712C, 0x712C, 0x712C, 0x712E, 0x712C, 0x712C, 0x712F, 0x712F },
{ 0x0000, 0x712C, 0x712C, 0x712C, 0x712F, 0x712C, 0x712C, 0x712F, 0x712F },
{ 0x0000, 0x7130, 0x7132, 0x7133, 0x7130, 0x7130, 0x7131, 0x7132, 0x7131 },
{ 0x0000, 0x7134, 0x7137, 0x7135, 0x7134, 0x7136, 0x7135, 0x7134, 0x7135 },
{ 0x0000, 0x7138, 0x713A, 0x7138, 0x7139, 0x713A, 0x7138, 0x7139, 0x713B },
{ 0x0000, 0x7144, 0x7146, 0x7144, 0x7146, 0x7147, 0x7145, 0x7145, 0x7147 },
{ 0x0000, 0x7148, 0x7149, 0x7149, 0x714A, 0x714A, 0x714B, 0x7149, 0x714B },
{ 0x0000, 0x714C, 0x714D, 0x714C, 0x714C, 0x714E, 0x714C, 0x714E, 0x714F },
{ 0x0000, 0x7150, 0x7153, 0x7152, 0x7150, 0x7151, 0x7153, 0x7153, 0x7151 },
{ 0x0000, 0x7155, 0x7156, 0x7157, 0x7154, 0x7156, 0x7156, 0x7156, 0x7156 },
{ 0x0000, 0x715A, 0x7159, 0x715B, 0x715A, 0x715A, 0x7158, 0x7158, 0x715B },
{ 0x0000, 0x715E, 0x715D, 0x715D, 0x715F, 0x715E, 0x715C, 0x715C, 0x715D },
{ 0x0000, 0x7163, 0x7162, 0x7160, 0x7163, 0x7160, 0x7161, 0x7161, 0x7160 },
{ 0x0000, 0x7164, 0x7166, 0x7164, 0x7167, 0x7164, 0x7164, 0x7164, 0x7167 },
{ 0x0000, 0x716B, 0x7169, 0x7168, 0x716B, 0x716A, 0x716B, 0x716B, 0x716A },
{ 0x0000, 0x716C, 0x716D, 0x716F, 0x716C, 0x716E, 0x716E, 0x716E, 0x716F },
{ 0x0000, 0x7171, 0x7173, 0x7170, 0x7172, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0x0000, 0x7176, 0x7177, 0x7174, 0x7174, 0x7175, 0x7174, 0x7174, 0x7177 },
{ 0x0000, 0x7178, 0x7179, 0x7179, 0x717B, 0x717A, 0x717B, 0x717A, 0x717B },
{ 0x0000, 0x717D, 0x717C, 0x717C, 0x717D, 0x717F, 0x717C, 0x717E, 0x717D },
{ 0x0000, 0x7183, 0x7181, 0x7180, 0x7183, 0x7182, 0x7183, 0x7181, 0x7183 },
{ 0x0000, 0x7184, 0x7186, 0x7185, 0x7186, 0x7184, 0x7187, 0x7186, 0x7184 },
{ 0x0000, 0x71A4, 0x71A6, 0x71A5, 0x0000, 0x71A6, 0x71A6, 0x71A6, 0x71A7 },
{ 0x0000, 0x7188, 0x7188, 0x7189, 0x7188, 0x7189, 0x718B, 0x718A, 0x7189 },
{ 0x0000, 0x718C, 0x718C, 0x718D, 0x718C, 0x718E, 0x718F, 0x718D, 0x718C },
{ 0x0000, 0x7190, 0x7190, 0x7191, 0x7192, 0x7191, 0x7193, 0x7190, 0x7191 },
{ 0x0000, 0x7196, 0x7194, 0x7195, 0x7196, 0x7197, 0x7194, 0x7196, 0x7195 },
{ 0x0000, 0x7199, 0x719A, 0x7198, 0x7198, 0x719A, 0x719A, 0x719B, 0x7198 },
{ 0x0000, 0x719D, 0x719C, 0x719E, 0x719D, 0x719D, 0x719C, 0x719F, 0x719E },
{ 0x0000, 0x71A1, 0x71A0, 0x71A1, 0x71A2, 0x71A1, 0x71A2, 0x71A3, 0x71A2 },
{ 0x0000, 0x711C, 0x711E, 0x711C, 0x711F, 0x711E, 0x711C, 0x711D, 0x711F },
{ 0x0000, 0x7104, 0x7105, 0x7107, 0x7107, 0x7105, 0x7106, 0x7107, 0x7107 },
{ 0x0000, 0x7107, 0x7105, 0x7107, 0x7107, 0x7106, 0x7107, 0x7107, 0x7105 },
{ 0x0000, 0x7113, 0x7117, 0x7113, 0x7110, 0x7112, 0x7112, 0x7116, 0x7112 },
{ 0x0000, 0x7113, 0x7113, 0x7113, 0x7113, 0x7113, 0x7113, 0x7111, 0x7113 },
{ 0x0000, 0x7113, 0x7117, 0x7113, 0x7110, 0x7112, 0x7112, 0x7116, 0x7112 },
{ 0x0000, 0x7117, 0x7117, 0x7117, 0x7117, 0x7117, 0x7117, 0x7117, 0x7113 },
{ 0x0000, 0x7101, 0x7100, 0x7102, 0x7103, 0x7101, 0x7100, 0x7102, 0x7103 },
{ 0x0000, 0x7100, 0x7102, 0x7100, 0x7100, 0x7100, 0x7100, 0x7100, 0x7102 },
{ 0x0000, 0x710A, 0x7109, 0x7109, 0x710A, 0x710B, 0x7108, 0x7109, 0x710B },
{ 0x0000, 0x7117, 0x7112, 0x7113, 0x7110, 0x710C, 0x7117, 0x710E, 0x7112 },
{ 0x0000, 0x710D, 0x710F, 0x710C, 0x7112, 0x710D, 0x710C, 0x710C, 0x710F },
{ 0x0000, 0x710A, 0x7109, 0x711A, 0x710A, 0x7109, 0x7108, 0x710B, 0x7109 },
{ 0x0000, 0x710C, 0x710F, 0x7113, 0x7110, 0x710D, 0x7112, 0x7116, 0x710D },
{ 0x0000, 0x7115, 0x7114, 0x7114, 0x7115, 0x7114, 0x7114, 0x7116, 0x7117 },
{ 0x0000, 0x7113, 0x710F, 0x7113, 0x7110, 0x710C, 0x711A, 0x710D, 0x7112 },
{ 0x0000, 0x7101, 0x7102, 0x7103, 0x7101, 0x7100, 0x7100, 0x7102, 0x7100 },
{ 0x0000, 0x7112, 0x710E, 0x7112, 0x710E, 0x710D, 0x7112, 0x710E, 0x710F },
{ 0x0000, 0x7142, 0x7141, 0x7142, 0x7143, 0x7140, 0x7140, 0x7141, 0x7143 },
{ 0x0000, 0x713C, 0x713D, 0x713D, 0x713E, 0x713E, 0x713F, 0x713D, 0x713F },
{ 0x0000, 0x7101, 0x7102, 0x7103, 0x7101, 0x7100, 0x7100, 0x7102, 0x7100 },
{ 0x0000, 0x7113, 0x7117, 0x7113, 0x7110, 0x7112, 0x7112, 0x7116, 0x7112 },
{ 0x0000, 0x7104, 0x7105, 0x7107, 0x7105, 0x7105, 0x7105, 0x7107, 0x7107 },
{ 0x0000, 0x7104, 0x7105, 0x7107, 0x7105, 0x710C, 0x7105, 0x7107, 0x7107 },
};
u16 Text_GetFaceReaction(GlobalContext* globalCtx, u32 reactionSet) {
u8 currentMask = Player_GetMask(globalCtx);
return sReactionTextIds[reactionSet][currentMask];
}

231
soh/src/code/z_fbdemo.c Normal file
View file

@ -0,0 +1,231 @@
#include "global.h"
#include <string.h>
Gfx D_8012AFB0[] = {
gsDPPipeSync(),
gsDPSetCycleType(G_CYC_FILL),
gsDPSetColorImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, 0x0F000000),
gsDPSetFillColor((GPACK_RGBA5551(65, 65, 65, 1) << 16) | GPACK_RGBA5551(65, 65, 65, 1)),
gsDPFillRectangle(0, 0, 319, 239),
gsDPPipeSync(),
gsDPSetFillColor((GPACK_RGBA5551(65, 65, 255, 1) << 16) | GPACK_RGBA5551(65, 65, 255, 1)),
gsDPFillRectangle(20, 20, 300, 220),
gsDPPipeSync(),
gsSPEndDisplayList(),
};
Gfx D_8012B000[] = {
gsDPPipeSync(),
gsSPTexture(0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON),
gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
gsDPSetCombineMode(G_CC_DECALRGB, G_CC_DECALRGB),
gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_1PRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | G_RM_AA_OPA_SURF | G_RM_AA_OPA_SURF2),
gsSPEndDisplayList(),
};
void TransitionUnk_InitGraphics(TransitionUnk* this) {
s32 row2;
s32 pad2;
s32 pad3;
Vtx_t* vtx2;
s32 frame;
s32 rowTex;
s32 row;
Gfx* gfx;
Vtx* vtx;
s32 col;
s32 colTex;
guMtxIdent(&this->modelView);
guMtxIdent(&this->unk_98);
guOrtho(&this->projection, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, -1000.0f, 1000.0f, 1.0f);
for (frame = 0; frame < 2; frame++) {
this->frame = frame;
vtx = (this->frame == 0) ? this->vtxFrame1 : this->vtxFrame2;
for (colTex = 0, col = 0; col < this->col + 1; colTex += 0x20, col++) {
for (rowTex = 0, row = 0; row < this->row + 1; row++) {
vtx2 = &vtx->v;
vtx++;
vtx2->tc[0] = rowTex << 6;
vtx2->ob[0] = row * 0x20;
vtx2->ob[1] = col * 0x20;
vtx2->ob[2] = -5;
vtx2->flag = 0;
vtx2->tc[1] = colTex << 6;
vtx2->cn[0] = 0;
vtx2->cn[1] = 0;
vtx2->cn[2] = 120;
vtx2->cn[3] = 255;
rowTex += 0x20;
}
}
}
gfx = this->gfx;
for (colTex = 0, col = 0; col < this->col; colTex += 0x20, col++) {
gSPVertex(gfx++, SEGMENT_ADDR(0xA, (u32)col * (this->row + 1) * sizeof(Vtx)), 2 * (this->row + 1), 0);
for (rowTex = 0, row = 0, row2 = 0; row < this->row;) {
gDPPipeSync(gfx++);
gDPLoadTextureTile(gfx++, SEGMENT_ADDR(0xB, 0), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, SCREEN_HEIGHT,
rowTex, colTex, rowTex + 0x20, colTex + 0x20, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSP1Quadrangle(gfx++, row, row + 1, row2 + this->row + 2, this->row + row2 + 1, 0);
rowTex += 0x20;
row2++;
row++;
}
}
gDPPipeSync(gfx++);
gSPEndDisplayList(gfx++);
LOG_NUM("this->col * (1 + this->row * (1 + 7 + 1)) + 1 + 1", this->col * (1 + this->row * 9) + 2, "../z_fbdemo.c",
144);
LOG_NUM("gp - this->gfxtbl", gfx - this->gfx, "../z_fbdemo.c", 145);
}
void TransitionUnk_InitData(TransitionUnk* this) {
s32 col;
s32 row;
for (col = 0; col < this->col + 1; col++) {
for (row = 0; row < this->row + 1; row++) {
(this->unk_0C + row + col * (this->row + 1))->unk_0 = row * 32;
(this->unk_0C + row + col * (this->row + 1))->unk_4 = col * 32;
}
}
}
void TransitionUnk_Destroy(TransitionUnk* this) {
osSyncPrintf("fbdemo_cleanup(%08x)\n", this);
osSyncPrintf("msleep(100);\n");
Sleep_Msec(100);
if (this->unk_0C != NULL) {
SystemArena_FreeDebug(this->unk_0C, "../z_fbdemo.c", 180);
this->unk_0C = NULL;
}
if (this->vtxFrame1 != NULL) {
SystemArena_FreeDebug(this->vtxFrame1, "../z_fbdemo.c", 181);
this->vtxFrame1 = NULL;
}
if (this->vtxFrame2 != NULL) {
SystemArena_FreeDebug(this->vtxFrame2, "../z_fbdemo.c", 182);
this->vtxFrame2 = NULL;
}
if (this->gfx != NULL) {
SystemArena_FreeDebug(this->gfx, "../z_fbdemo.c", 183);
this->gfx = NULL;
}
}
TransitionUnk* TransitionUnk_Init(TransitionUnk* this, s32 row, s32 col) {
osSyncPrintf("fbdemo_init(%08x, %d, %d)\n", this, row, col);
memset(this, 0, sizeof(*this));
this->frame = 0;
this->row = row;
this->col = col;
this->unk_0C = SystemArena_MallocDebug((row + 1) * sizeof(TransitionUnkData) * (col + 1), "../z_fbdemo.c", 195);
this->vtxFrame1 = SystemArena_MallocDebug((row + 1) * sizeof(Vtx) * (col + 1), "../z_fbdemo.c", 196);
this->vtxFrame2 = SystemArena_MallocDebug((row + 1) * sizeof(Vtx) * (col + 1), "../z_fbdemo.c", 197);
this->gfx = SystemArena_MallocDebug((this->col * (1 + this->row * 9) + 2) * sizeof(Gfx), "../z_fbdemo.c", 198);
if (this->unk_0C == NULL || this->vtxFrame1 == NULL || this->vtxFrame2 == NULL || this->gfx == NULL) {
osSyncPrintf("fbdemo_init allocation error\n");
if (this->unk_0C != NULL) {
SystemArena_FreeDebug(this->unk_0C, "../z_fbdemo.c", 202);
this->unk_0C = NULL;
}
if (this->vtxFrame1 != NULL) {
SystemArena_FreeDebug(this->vtxFrame1, "../z_fbdemo.c", 203);
this->vtxFrame1 = NULL;
}
if (this->vtxFrame2 != NULL) {
SystemArena_FreeDebug(this->vtxFrame2, "../z_fbdemo.c", 204);
this->vtxFrame2 = NULL;
}
if (this->gfx != NULL) {
SystemArena_FreeDebug(this->gfx, "../z_fbdemo.c", 205);
this->gfx = NULL;
}
return NULL;
}
TransitionUnk_InitGraphics(this);
TransitionUnk_InitData(this);
this->frame = 0;
return this;
}
void TransitionUnk_SetData(TransitionUnk* this) {
s32 col;
Vtx* vtx;
s32 row;
for (col = 0; col < this->col + 1; col++) {
for (row = 0; row < this->row + 1; row++) {
vtx = (this->frame == 0) ? this->vtxFrame1 : this->vtxFrame2;
(vtx + row + col * (this->row + 1))->v.ob[0] = (this->unk_0C + row + col * (this->row + 1))->unk_0;
vtx = (this->frame == 0) ? this->vtxFrame1 : this->vtxFrame2;
(vtx + row + col * (this->row + 1))->v.ob[1] = (this->unk_0C + row + col * (this->row + 1))->unk_4;
}
}
}
void TransitionUnk_Draw(TransitionUnk* this, Gfx** gfxP) {
Gfx* gfx = *gfxP;
gSPDisplayList(gfx++, D_8012B000);
TransitionUnk_SetData(this);
gSPMatrix(gfx++, &this->projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
gSPMatrix(gfx++, &this->modelView, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(gfx++, 0xA, this->frame == 0 ? this->vtxFrame1 : this->vtxFrame2);
gSPSegment(gfx++, 0xB, this->zBuffer);
gSPDisplayList(gfx++, D_8012B000);
gSPDisplayList(gfx++, this->gfx);
gDPPipeSync(gfx++);
this->frame ^= 1;
*gfxP = gfx;
}
void TransitionUnk_Update(TransitionUnk* this) {
f32 temp_f00;
f32 temp_f12;
s32 col;
f32 phi_f14;
s32 row;
for (col = 0; col < this->col + 1; col++) {
for (row = 0; row < this->row + 1; row++) {
temp_f00 =
(this->unk_0C + row + col * (this->row + 1))->unk_0 - (this->unk_0C + 5 + 4 * (this->row + 1))->unk_0;
temp_f12 =
(this->unk_0C + row + col * (this->row + 1))->unk_4 - (this->unk_0C + 5 + 4 * (this->row + 1))->unk_4;
phi_f14 = (SQ(temp_f00) + SQ(temp_f12)) / 100.0f;
if (phi_f14 != 0.0f) {
if (phi_f14 < 1.0f) {
phi_f14 = 1.0f;
}
(this->unk_0C + row + col * (this->row + 1))->unk_0 -= temp_f00 / phi_f14;
(this->unk_0C + row + col * (this->row + 1))->unk_4 -= temp_f12 / phi_f14;
}
}
}
}
void func_800B23E8(TransitionUnk* this) {
}
s32 func_800B23F0(TransitionUnk* this) {
return 0;
}

Some files were not shown because too many files have changed in this diff Show more