From 6ae28a789ac6a5a3c4cac69f7ecabc82b0d150e5 Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Tue, 7 Dec 2021 13:13:18 +1100 Subject: [PATCH 01/27] Macro Clean up (#454) * Add OS macros * MTXMODE cleanup * format * More matrix mode macros missed --- src/boot_O2_g3/fault.c | 4 ++-- src/boot_O2_g3/idle.c | 2 +- src/boot_O2_g3/irqmgr.c | 12 ++++++------ src/boot_O2_g3/z_std_dma.c | 4 ++-- src/code/z_debug_display.c | 10 +++++----- src/code/z_view.c | 8 ++++---- src/code/z_vr_box.c | 6 +++--- src/libultra/io/contquery.c | 4 ++-- src/libultra/io/contreaddata.c | 6 +++--- src/libultra/io/controller.c | 10 +++++----- src/libultra/io/epidma.c | 4 ++-- src/libultra/io/piacs.c | 4 ++-- src/libultra/io/pimgr.c | 2 +- src/libultra/io/siacs.c | 8 ++++---- src/libultra/os/seteventmesg.c | 2 +- src/libultra/os/timerintr.c | 2 +- .../actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c | 12 ++++++------ src/overlays/actors/ovl_Boss_02/z_boss_02.c | 2 +- src/overlays/actors/ovl_En_Bu/z_en_bu.c | 6 +++--- src/overlays/actors/ovl_En_Cha/z_en_cha.c | 2 +- .../actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 4 ++-- src/overlays/actors/ovl_En_Dno/z_en_dno.c | 4 ++-- src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c | 10 +++++----- src/overlays/actors/ovl_En_Elforg/z_en_elforg.c | 2 +- .../actors/ovl_En_Ginko_Man/z_en_ginko_man.c | 8 ++++---- src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c | 4 ++-- src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c | 2 +- src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c | 4 ++-- src/overlays/actors/ovl_En_Ot/z_en_ot.c | 4 ++-- src/overlays/actors/ovl_En_Owl/z_en_owl.c | 6 +++--- .../actors/ovl_En_Pametfrog/z_en_pametfrog.c | 2 +- src/overlays/actors/ovl_En_Pm/z_en_pm.c | 2 +- src/overlays/actors/ovl_En_Poh/z_en_poh.c | 3 ++- src/overlays/actors/ovl_En_Rsn/z_en_rsn.c | 2 +- src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c | 2 +- src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c | 10 +++++----- src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c | 2 +- .../actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c | 2 +- 38 files changed, 92 insertions(+), 91 deletions(-) diff --git a/src/boot_O2_g3/fault.c b/src/boot_O2_g3/fault.c index c5af62f825..1f55034453 100644 --- a/src/boot_O2_g3/fault.c +++ b/src/boot_O2_g3/fault.c @@ -796,7 +796,7 @@ void Fault_ThreadEntry(void* arg) { osSetEventMesg(12, &sFaultContext->queue, (OSMesg)2); while (1) { do { - osRecvMesg(&sFaultContext->queue, &msg, 1); + osRecvMesg(&sFaultContext->queue, &msg, OS_MESG_BLOCK); if (msg == (OSMesg)1) { sFaultContext->msgId = 1; @@ -887,7 +887,7 @@ void Fault_Start(void) { sFaultContext->clients = NULL; sFaultContext->faultActive = 0; gFaultStruct.faultHandlerEnabled = 1; - osCreateMesgQueue(&sFaultContext->queue, sFaultContext->msg, 1); + osCreateMesgQueue(&sFaultContext->queue, sFaultContext->msg, ARRAY_COUNT(sFaultContext->msg)); StackCheck_Init(&sFaultThreadInfo, sFaultStack, sFaultStack + sizeof(sFaultStack), 0, 0x100, "fault"); osCreateThread(&sFaultContext->thread, 2, Fault_ThreadEntry, NULL, sFaultStack + sizeof(sFaultStack), 0x7F); osStartThread(&sFaultContext->thread); diff --git a/src/boot_O2_g3/idle.c b/src/boot_O2_g3/idle.c index 7a1d636431..da93f13fdb 100644 --- a/src/boot_O2_g3/idle.c +++ b/src/boot_O2_g3/idle.c @@ -63,7 +63,7 @@ void Idle_InitCodeAndMemory(void) { SEGMENT_ROM_END(code) - SEGMENT_ROM_START(code), 0, &queue, 0); Idle_InitScreen(); Idle_InitMemory(); - osRecvMesg(&queue, NULL, 1); + osRecvMesg(&queue, NULL, OS_MESG_BLOCK); sDmaMgrDmaBuffSize = oldSize; diff --git a/src/boot_O2_g3/irqmgr.c b/src/boot_O2_g3/irqmgr.c index 3f4ca04aed..f605dc3270 100644 --- a/src/boot_O2_g3/irqmgr.c +++ b/src/boot_O2_g3/irqmgr.c @@ -17,10 +17,10 @@ void IrqMgr_AddClient(IrqMgr* irqmgr, IrqMgrClient* param_2, OSMesgQueue* param_ osSetIntMask(saveMask); if (irqmgr->prenmiStage > 0) { - osSendMesg(param_2->queue, &irqmgr->prenmiMsg.type, 0); + osSendMesg(param_2->queue, &irqmgr->prenmiMsg.type, OS_MESG_NOBLOCK); } if (irqmgr->prenmiStage > 1) { - osSendMesg(param_2->queue, &irqmgr->nmiMsg.type, 0); + osSendMesg(param_2->queue, &irqmgr->nmiMsg.type, OS_MESG_NOBLOCK); } } @@ -54,7 +54,7 @@ void IrqMgr_SendMesgForClient(IrqMgr* irqmgr, OSMesg msg) { IrqMgrClient* iter = irqmgr->callbacks; while (iter != NULL) { - osSendMesg(iter->queue, msg, 0); + osSendMesg(iter->queue, msg, OS_MESG_NOBLOCK); iter = iter->next; } } @@ -64,7 +64,7 @@ void IrqMgr_JamMesgForClient(IrqMgr* irqmgr, OSMesg msg) { while (iter != NULL) { if (iter->queue->validCount < iter->queue->msgCount) { - osSendMesg(iter->queue, msg, 0); + osSendMesg(iter->queue, msg, OS_MESG_NOBLOCK); } iter = iter->next; } @@ -130,7 +130,7 @@ void IrqMgr_ThreadEntry(IrqMgr* irqmgr) { ; } - osRecvMesg(&irqmgr->irqQueue, (OSMesg*)&interrupt, 1); + osRecvMesg(&irqmgr->irqQueue, (OSMesg*)&interrupt, OS_MESG_BLOCK); switch (interrupt) { case 0x29A: IrqMgr_HandleRetrace(irqmgr); @@ -159,7 +159,7 @@ void IrqMgr_Init(IrqMgr* irqmgr, void* stack, OSPri pri, u8 retraceCount) { irqmgr->prenmiStage = 0; irqmgr->lastPrenmiTime = 0; - osCreateMesgQueue(&irqmgr->irqQueue, (OSMesg*)irqmgr->irqBuffer, 8); + osCreateMesgQueue(&irqmgr->irqQueue, (OSMesg*)irqmgr->irqBuffer, ARRAY_COUNT(irqmgr->irqBuffer)); osSetEventMesg(0xE, &irqmgr->irqQueue, (OSMesg)0x29D); osViSetEvent(&irqmgr->irqQueue, (OSMesg)0x29A, retraceCount); diff --git a/src/boot_O2_g3/z_std_dma.c b/src/boot_O2_g3/z_std_dma.c index 25fc8fbb08..ebf3909249 100644 --- a/src/boot_O2_g3/z_std_dma.c +++ b/src/boot_O2_g3/z_std_dma.c @@ -31,7 +31,7 @@ s32 DmaMgr_DMARomToRam(uintptr_t rom, void* ram, size_t size) { goto END; } - osRecvMesg(&queue, NULL, 1); + osRecvMesg(&queue, NULL, OS_MESG_BLOCK); size -= buffSize; rom = rom + buffSize; ram = (u8*)ram + buffSize; @@ -47,7 +47,7 @@ s32 DmaMgr_DMARomToRam(uintptr_t rom, void* ram, size_t size) { goto END; } - osRecvMesg(&queue, NULL, 1); + osRecvMesg(&queue, NULL, OS_MESG_BLOCK); osInvalDCache(ram, size); diff --git a/src/code/z_debug_display.c b/src/code/z_debug_display.c index 2fe6b79778..f9c9f60b40 100644 --- a/src/code/z_debug_display.c +++ b/src/code/z_debug_display.c @@ -68,10 +68,10 @@ void DebugDisplay_DrawSpriteI8(DebugDispObject* dispObj, void* texture, GlobalCo func_8012C6FC(globalCtx->state.gfxCtx); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a); - Matrix_InsertTranslation(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, 0); - Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, 1); - Matrix_InsertMatrix(&globalCtx->mf_187FC, 1); - Matrix_InsertRotation(dispObj->rot.x, dispObj->rot.y, dispObj->rot.z, 1); + Matrix_InsertTranslation(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_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertRotation(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); @@ -95,7 +95,7 @@ void DebugDisplay_DrawPolygon(DebugDispObject* dispObj, void* arg1, GlobalContex gSPSetLights1(POLY_XLU_DISP++, sDebugDisplayLight1); Matrix_SetStateRotationAndTranslation(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, &dispObj->rot); - Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, 1); + Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, arg1); diff --git a/src/code/z_view.c b/src/code/z_view.c index c325fd5637..da2e3593b3 100644 --- a/src/code/z_view.c +++ b/src/code/z_view.c @@ -259,11 +259,11 @@ s32 View_StepQuake(View* view, Mtx* matrix) { Matrix_FromRSPMatrix(matrix, &mf); Matrix_SetCurrentState(&mf); Matrix_RotateStateAroundXAxis(view->currQuakeRot.x); - Matrix_InsertYRotation_f(view->currQuakeRot.y, 1); - Matrix_InsertZRotation_f(view->currQuakeRot.z, 1); + Matrix_InsertYRotation_f(view->currQuakeRot.y, MTXMODE_APPLY); + Matrix_InsertZRotation_f(view->currQuakeRot.z, MTXMODE_APPLY); Matrix_Scale(view->currQuakeScale.x, view->currQuakeScale.y, view->currQuakeScale.z, MTXMODE_APPLY); - Matrix_InsertZRotation_f(-view->currQuakeRot.z, 1); - Matrix_InsertYRotation_f(-view->currQuakeRot.y, 1); + Matrix_InsertZRotation_f(-view->currQuakeRot.z, MTXMODE_APPLY); + Matrix_InsertYRotation_f(-view->currQuakeRot.y, MTXMODE_APPLY); Matrix_RotateStateAroundXAxis(-view->currQuakeRot.x); Matrix_ToMtx(matrix); diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index 9e949beac9..724bc59711 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -103,7 +103,7 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } - osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); + osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); if (globalCtx->envCtx.unk_11 == 0) { @@ -120,7 +120,7 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } - osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); + osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); size = SEGMENT_ROM_SIZE(d2_fine_pal_static); @@ -129,7 +129,7 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy DmaMgr_SendRequestImpl(&skyboxCtx->unk1C8, skyboxCtx->skyboxPaletteStaticSegment, SEGMENT_ROM_START(d2_fine_pal_static), size, 0, &skyboxCtx->loadQueue, NULL); - osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); + osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); } } diff --git a/src/libultra/io/contquery.c b/src/libultra/io/contquery.c index 7cb681fdeb..a9a944f54b 100644 --- a/src/libultra/io/contquery.c +++ b/src/libultra/io/contquery.c @@ -7,11 +7,11 @@ s32 osContStartQuery(OSMesgQueue* mq) { if (__osContLastPoll != 0) { __osPackRequestData(0); - __osSiRawStartDma(1, &__osContPifRam); + __osSiRawStartDma(OS_WRITE, &__osContPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); } - ret = __osSiRawStartDma(0, &__osContPifRam); + ret = __osSiRawStartDma(OS_READ, &__osContPifRam); __osContLastPoll = 0; diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c index 0017a42226..47b7968d38 100644 --- a/src/libultra/io/contreaddata.c +++ b/src/libultra/io/contreaddata.c @@ -8,11 +8,11 @@ s32 osContStartReadData(OSMesgQueue* mq) { if (__osContLastPoll != 1) { __osPackReadData(); - __osSiRawStartDma(1, &__osContPifRam); - osRecvMesg(mq, NULL, 1); + __osSiRawStartDma(OS_WRITE, &__osContPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); } - ret = __osSiRawStartDma(0, &__osContPifRam); + ret = __osSiRawStartDma(OS_READ, &__osContPifRam); __osContLastPoll = 1; __osSiRelAccess(); diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c index a048575a72..d84ba2d711 100644 --- a/src/libultra/io/controller.c +++ b/src/libultra/io/controller.c @@ -34,16 +34,16 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) { __osPackRequestData(0); - ret = __osSiRawStartDma(1, &__osContPifRam); - osRecvMesg(mq, &dummy, 1); + ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); - ret = __osSiRawStartDma(0, &__osContPifRam); - osRecvMesg(mq, &dummy, 1); + ret = __osSiRawStartDma(OS_READ, &__osContPifRam); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); __osContGetInitData(bitpattern, data); __osContLastPoll = 0; __osSiCreateAccessQueue(); - osCreateMesgQueue(&D_8009CF38, D_8009CF50, 1); + osCreateMesgQueue(&D_8009CF38, D_8009CF50, ARRAY_COUNT(D_8009CF50)); return ret; } diff --git a/src/libultra/io/epidma.c b/src/libultra/io/epidma.c index d3e0e36d2f..0b8c847d6a 100644 --- a/src/libultra/io/epidma.c +++ b/src/libultra/io/epidma.c @@ -16,9 +16,9 @@ s32 osEPiStartDma(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) { } if (mb->hdr.pri == 1) { - result = osJamMesg(osPiGetCmdQueue(), mb, 0); + result = osJamMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); } else { - result = osSendMesg(osPiGetCmdQueue(), mb, 0); + result = osSendMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); } return result; } diff --git a/src/libultra/io/piacs.c b/src/libultra/io/piacs.c index 8e6f830c0f..532b149e23 100644 --- a/src/libultra/io/piacs.c +++ b/src/libultra/io/piacs.c @@ -7,8 +7,8 @@ OSMesgQueue __osPiAccessQueue; void __osPiCreateAccessQueue(void) { __osPiAccessQueueEnabled = 1; - osCreateMesgQueue(&__osPiAccessQueue, D_8009E3F0, 1); - osSendMesg(&__osPiAccessQueue, NULL, 0); + osCreateMesgQueue(&__osPiAccessQueue, D_8009E3F0, ARRAY_COUNT(D_8009E3F0)); + osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK); } void __osPiGetAccess(void) { diff --git a/src/libultra/io/pimgr.c b/src/libultra/io/pimgr.c index 74b1075a16..3d618de746 100644 --- a/src/libultra/io/pimgr.c +++ b/src/libultra/io/pimgr.c @@ -14,7 +14,7 @@ void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQ, OSMesg* cmdBuf, s32 cmdMsgC if (!__osPiDevMgr.active) { osCreateMesgQueue(cmdQ, cmdBuf, cmdMsgCnt); - osCreateMesgQueue(&D_8009E3D0, D_8009E3E8, 1); + osCreateMesgQueue(&D_8009E3D0, D_8009E3E8, ARRAY_COUNT(D_8009E3E8)); if (!__osPiAccessQueueEnabled) { __osPiCreateAccessQueue(); } diff --git a/src/libultra/io/siacs.c b/src/libultra/io/siacs.c index 590f048adf..7a221408e5 100644 --- a/src/libultra/io/siacs.c +++ b/src/libultra/io/siacs.c @@ -7,8 +7,8 @@ OSMesgQueue __osSiAccessQueue; void __osSiCreateAccessQueue() { __osSiAccessQueueEnabled = 1; - osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, 1); - osSendMesg(&__osSiAccessQueue, NULL, 0); + osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, ARRAY_COUNT(siAccessBuf)); + osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); } void __osSiGetAccess(void) { @@ -16,9 +16,9 @@ void __osSiGetAccess(void) { if (!__osSiAccessQueueEnabled) { __osSiCreateAccessQueue(); } - osRecvMesg(&__osSiAccessQueue, &dummyMesg, 1); + osRecvMesg(&__osSiAccessQueue, &dummyMesg, OS_MESG_BLOCK); } void __osSiRelAccess(void) { - osSendMesg(&__osSiAccessQueue, NULL, 0); + osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); } diff --git a/src/libultra/os/seteventmesg.c b/src/libultra/os/seteventmesg.c index 723d1dafc6..8be2ff9e2b 100644 --- a/src/libultra/os/seteventmesg.c +++ b/src/libultra/os/seteventmesg.c @@ -17,7 +17,7 @@ void osSetEventMesg(OSEvent e, OSMesgQueue* mq, OSMesg m) { if (e == 14) { if (__osShutdown != 0 && D_80097F10 == 0) { - osSendMesg(mq, m, 0); + osSendMesg(mq, m, OS_MESG_NOBLOCK); } D_80097F10 = 1; } diff --git a/src/libultra/os/timerintr.c b/src/libultra/os/timerintr.c index 4c00831399..87f7129dfd 100644 --- a/src/libultra/os/timerintr.c +++ b/src/libultra/os/timerintr.c @@ -49,7 +49,7 @@ void __osTimerInterrupt(void) { t->next = NULL; t->prev = NULL; if (t->mq != NULL) { - osSendMesg(t->mq, t->msg, 0); + osSendMesg(t->mq, t->msg, OS_MESG_NOBLOCK); } if (t->interval != 0) { t->value = t->interval; diff --git a/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c b/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c index ff11631ef1..5b47f8e4ed 100644 --- a/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c +++ b/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c @@ -89,9 +89,9 @@ void BgCtowerGear_Splash(BgCtowerGear* this, GlobalContext* globalCtx) { flags = this->dyna.actor.flags & 0x40; rotZ = this->dyna.actor.shape.rot.z & 0x1FFF; if ((flags != 0) && (rotZ < 0x1B58) && (rotZ >= 0x1388)) { - Matrix_RotateY(this->dyna.actor.home.rot.y, 0); - Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, 1); - Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, 1); + Matrix_RotateY(this->dyna.actor.home.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, MTXMODE_APPLY); for (i = 0; i < 4; i++) { if ((u32)Rand_Next() >= 0x40000000) { splashOffset.x = D_80AD3270[i].x - (Rand_ZeroOne() * 30.0f); @@ -107,9 +107,9 @@ void BgCtowerGear_Splash(BgCtowerGear* this, GlobalContext* globalCtx) { } if ((rotZ < 0x1F4) && (rotZ >= 0)) { if (flags != 0) { - Matrix_RotateY(this->dyna.actor.home.rot.y, 0); - Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, 1); - Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, 1); + Matrix_RotateY(this->dyna.actor.home.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, MTXMODE_APPLY); for (i = 0; i < 3; i++) { for (j = 0; j < 2; j++) { splashOffset.x = D_80AD32A0[i].x + (Rand_ZeroOne() * 10.0f); diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 32d75abba3..7d4361f84a 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -1051,7 +1051,7 @@ void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { sp9C = Rand_ZeroFloat(M_PI); for (i = 0; i < 15; i++) { - Matrix_InsertYRotation_f(((2.0f * (i * M_PI)) / 15.0f) + sp9C, 0); + Matrix_InsertYRotation_f(((2.0f * (i * M_PI)) / 15.0f) + sp9C, MTXMODE_NEW); Matrix_GetStateTranslationAndScaledZ((10 - this->unk_0146[0]) * (D_809DF5B0 * 300.0f) * 0.1f, &sp90); spD0.x = this->unk_0170.x + sp90.x; diff --git a/src/overlays/actors/ovl_En_Bu/z_en_bu.c b/src/overlays/actors/ovl_En_Bu/z_en_bu.c index cb61799b9e..3c56535256 100644 --- a/src/overlays/actors/ovl_En_Bu/z_en_bu.c +++ b/src/overlays/actors/ovl_En_Bu/z_en_bu.c @@ -54,9 +54,9 @@ void EnBu_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); - Matrix_InsertZRotation_s(this->actor.shape.rot.z, 1); - Matrix_RotateY(this->actor.shape.rot.y, 1); - Matrix_InsertXRotation_s(this->actor.shape.rot.x, 1); + Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, this->displayListPtr); diff --git a/src/overlays/actors/ovl_En_Cha/z_en_cha.c b/src/overlays/actors/ovl_En_Cha/z_en_cha.c index 9a1280c293..d8f32613f4 100644 --- a/src/overlays/actors/ovl_En_Cha/z_en_cha.c +++ b/src/overlays/actors/ovl_En_Cha/z_en_cha.c @@ -119,6 +119,6 @@ void EnCha_Draw(Actor* thisx, GlobalContext* globalCtx) { func_800BDFC0(globalCtx, D_06000710); Matrix_InsertTranslation(-1094.0f, 4950.0f, 9.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->actor.home.rot.x, 1); + Matrix_InsertXRotation_s(this->actor.home.rot.x, MTXMODE_APPLY); func_800BDFC0(globalCtx, D_06000958); } diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index ee13a00974..26759e2bf7 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -416,7 +416,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { for (i = 0; i < 54; i++) { lightRayMaxScale = sLightRayMaxScale[thisx->params] + Rand_ZeroFloat(sLightRayMaxScale[thisx->params]); - Matrix_InsertYRotation_f(Rand_ZeroFloat(M_PI * 2), 0); + Matrix_InsertYRotation_f(Rand_ZeroFloat(M_PI * 2), MTXMODE_NEW); Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(M_PI * 2)); Matrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); accel.x = vel.x * -0.03f; @@ -489,7 +489,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { pos = this->actor.world.pos; for (i = 0; i < 44; i++) { lightRayMaxScale = sLightRayMaxScale[thisx->params] + Rand_ZeroFloat(sLightRayMaxScale[thisx->params]); - Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), 0); + Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(2 * M_PI)); Matrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); accel.x = vel.x * -0.03f; diff --git a/src/overlays/actors/ovl_En_Dno/z_en_dno.c b/src/overlays/actors/ovl_En_Dno/z_en_dno.c index a21f7df865..ea2900fb43 100644 --- a/src/overlays/actors/ovl_En_Dno/z_en_dno.c +++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.c @@ -171,7 +171,7 @@ void func_80A715DC(EnDno* this, GlobalContext* globalCtx) { if (func_8013E5CC(&crace->actor.home.pos, &crace->actor.home.rot, &D_80A73B2C, &this->actor.prevPos, &this->actor.world.pos, &sp88)) { Math_Vec3f_Diff(&this->actor.world.pos, &crace->actor.home.pos, &sp7C); - Matrix_RotateY(-crace->actor.home.rot.y, 0); + Matrix_RotateY(-crace->actor.home.rot.y, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&sp7C, &sp70); if ((fabsf(sp70.x) < 100.0f) && (sp70.y >= -10.0f) && (sp70.y <= 180.0f) && (sp70.z < 0.0f)) { crace->unk_170 |= 1; @@ -985,7 +985,7 @@ void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve func_8012C28C(globalCtx->state.gfxCtx); if (limbIndex == 13) { Matrix_Scale(this->unk_454, this->unk_454, this->unk_454, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_45C, 1); + Matrix_InsertXRotation_s(this->unk_45C, MTXMODE_APPLY); } gfxOpa = POLY_OPA_DISP; diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c index 1e87473cdc..2bd0a5512c 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -154,12 +154,12 @@ void EnElfbub_Draw(Actor* thisx, GlobalContext* globalCtx2) { func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(0.0f, 0.0f, 1.0f, 1); + Matrix_InsertTranslation(0.0f, 0.0f, 1.0f, MTXMODE_APPLY); Matrix_NormalizeXYZ(&globalCtx->mf_187FC); - Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, 1); - Matrix_InsertZRotation_s(this->zRot, 1); - Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, 1); - Matrix_InsertZRotation_s(this->zRot * -1, 1); + Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->zRot, MTXMODE_APPLY); + Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->zRot * -1, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, D_06001000); diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c index 1efecd2574..285ed462ca 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c @@ -607,7 +607,7 @@ void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) { AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C818)); break; } - Matrix_InsertMatrix(&globalCtx->mf_187FC, 1); + Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, diff --git a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c index 393106e4cc..6946f58ec6 100644 --- a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c +++ b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c @@ -642,12 +642,12 @@ s32 EnGinkoMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d if (limbIndex == 15) { Matrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->limb15Rot.y, 1); - Matrix_InsertZRotation_s(this->limb15Rot.x, 1); + Matrix_InsertXRotation_s(this->limb15Rot.y, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->limb15Rot.x, MTXMODE_APPLY); Matrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); } else if (limbIndex == 8) { - Matrix_InsertXRotation_s(-this->limb8Rot.y, 1); - Matrix_InsertZRotation_s(-this->limb8Rot.x, 1); + Matrix_InsertXRotation_s(-this->limb8Rot.y, MTXMODE_APPLY); + Matrix_InsertZRotation_s(-this->limb8Rot.x, MTXMODE_APPLY); } return 0; diff --git a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c index 22ea6a953e..92a2270197 100644 --- a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c +++ b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c @@ -1591,7 +1591,7 @@ void func_80942B1C(EnGoroiwa* this, GlobalContext* globalCtx) { sp80.z = ptr->unk_20; Matrix_SetStateRotationAndTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &sp80); - Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); func_800BDFC0(globalCtx, phi_fp); if ((ptr->unk_28 != 0) && (ptr->unk_2C > 0)) { @@ -1605,7 +1605,7 @@ void func_80942B1C(EnGoroiwa* this, GlobalContext* globalCtx) { func_800C0094(ptr->unk_28, ptr->unk_00.x, ptr->unk_18, ptr->unk_00.z, &sp88); Matrix_SetCurrentState(&sp88); - Matrix_Scale(this->actor.scale.x * 7.5f, 1.0f, this->actor.scale.z * 7.5f, 1); + Matrix_Scale(this->actor.scale.x * 7.5f, 1.0f, this->actor.scale.z * 7.5f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c index 167180dabe..0a0dccef71 100644 --- a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c +++ b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c @@ -351,7 +351,7 @@ void func_80B228F4(Actor* thisx, GlobalContext* globalCtx) { void EnHakurock_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(-100.0f, 0.0f, 0.0f, 1); + Matrix_InsertTranslation(-100.0f, 0.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_06011100); gSPDisplayList(POLY_OPA_DISP++, D_06011178); diff --git a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c index 0969c123ab..b2792ec129 100644 --- a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c +++ b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c @@ -321,7 +321,7 @@ s32 func_80A68F9C(EnMushi2* this, s16 arg1) { matrix->mf[3][2] = 0.0f; matrix->mf[3][3] = 0.0f; - Matrix_RotateY(arg1, 1); + Matrix_RotateY(arg1, MTXMODE_APPLY); this->unk_310.x = matrix->mf[0][0]; this->unk_310.y = matrix->mf[0][1]; @@ -368,7 +368,7 @@ s32 func_80A690C4(EnMushi2* this, s16 arg1) { matrix->mf[3][2] = 0.0f; matrix->mf[3][3] = 0.0f; - Matrix_InsertXRotation_s(arg1, 1); + Matrix_InsertXRotation_s(arg1, MTXMODE_APPLY); this->unk_310.x = matrix->mf[0][0]; this->unk_310.y = matrix->mf[0][1]; diff --git a/src/overlays/actors/ovl_En_Ot/z_en_ot.c b/src/overlays/actors/ovl_En_Ot/z_en_ot.c index d6c95bad6e..65fd93e867 100644 --- a/src/overlays/actors/ovl_En_Ot/z_en_ot.c +++ b/src/overlays/actors/ovl_En_Ot/z_en_ot.c @@ -506,7 +506,7 @@ void func_80B5C6DC(EnOt* this, GlobalContext* globalCtx) { Vec3f sp30; sp3E = Actor_YawToPoint(&player->actor, &this->unk_394); - Matrix_RotateY(BINANG_ADD(sp3E, 0x4000), 0); + Matrix_RotateY(BINANG_ADD(sp3E, 0x4000), MTXMODE_NEW); if (this->unk_33C == 2) { Matrix_GetStateTranslationAndScaledZ(26.259998f, &sp30); } else { @@ -1132,7 +1132,7 @@ void func_80B5E078(GlobalContext* globalCtx, EnOtUnkStruct* arg1, s32 arg2) { sp54.x = arg1->unk_30; sp54.y = arg1->unk_34; sp54.z = 0.0f; - Matrix_RotateY(temp, 0); + Matrix_RotateY(temp, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&sp54, &arg1->unk_0C); Math_Vec3f_Sum(&arg1->unk_0C, &arg1->unk_50, &arg1->unk_0C); arg1->unk_4C--; diff --git a/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 514245a327..ab5e2520a1 100644 --- a/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -1172,9 +1172,9 @@ void func_8095D074(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(0.0f, 500.0f, 0.0f, 1); - Matrix_InsertXRotation_s(this->unk_3D8 - 0x4000, 1); - Matrix_InsertTranslation(0.0f, 0.0f, -500.0f, 1); + Matrix_InsertTranslation(0.0f, 500.0f, 0.0f, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_3D8 - 0x4000, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, -500.0f, MTXMODE_APPLY); if (this->unk_3DC >= 0x20) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c index 8993cb14a4..9d15d2df31 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -335,7 +335,7 @@ s32 func_8086A2CC(EnPametfrog* this, CollisionPoly* floorPoly) { Math3D_CrossProduct(&this->unk_2DC, &floorNorm, &vec2); EnPametfrog_Vec3fNormalize(&vec2); - Matrix_InsertRotationAroundUnitVector_f(rotation, &vec2, 0); + Matrix_InsertRotationAroundUnitVector_f(rotation, &vec2, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&this->unk_2E8, &vec2); Math_Vec3f_Copy(&this->unk_2E8, &vec2); Math3D_CrossProduct(&this->unk_2E8, &floorNorm, &this->unk_2D0); diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.c b/src/overlays/actors/ovl_En_Pm/z_en_pm.c index 2cf6b353fa..a1658c915e 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c @@ -861,7 +861,7 @@ void func_80AF8C68(EnPm* this, GlobalContext* globalCtx) { this->unk_360 = 0.0f; } Math_SmoothStepToF(&this->unk_364, this->unk_360, 0.8f, 40.0f, 10.0f); - Matrix_InsertTranslation(this->unk_364, 0.0f, 0.0f, 1); + Matrix_InsertTranslation(this->unk_364, 0.0f, 0.0f, MTXMODE_APPLY); this->unk_388 = sp28; } diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c index 08fbedeaf1..4042aecac7 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -893,7 +893,8 @@ void EnPoh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve if (limbIndex == 18) { if ((this->actionFunc == func_80B2D300) && (this->unk_18E >= 19) && (this->actor.scale.x != 0.0f)) { - Matrix_Scale(0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, 1); + Matrix_Scale(0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, + MTXMODE_APPLY); } Matrix_CopyCurrentState(&this->unk_3D8); func_80B2C910(&sp60, globalCtx); diff --git a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c index 7b4b928b7c..3adecaad3f 100644 --- a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c +++ b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c @@ -72,7 +72,7 @@ s32 EnRsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, EnRsn* this = (EnRsn*)arg; if (limbIndex == 14) { - Matrix_InsertXRotation_s(this->unk1D8.y, 1); + Matrix_InsertXRotation_s(this->unk1D8.y, MTXMODE_APPLY); } return 0; } diff --git a/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c b/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c index 8dd30eec23..2031127f7c 100644 --- a/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c +++ b/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c @@ -81,7 +81,7 @@ void func_80A66208(EnWarpUzu* this, GlobalContext* globalCtx) { Vec3f sp24; this->actor.textId = 0; - Matrix_RotateY(this->actor.shape.rot.y, 0); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&D_80A664FC, &sp24); Math_Vec3f_Sum(&this->actor.world.pos, &sp24, &this->actor.focus.pos); Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.shape.rot); diff --git a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c index 2b3a3189fc..a3073a7e0e 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c @@ -285,12 +285,12 @@ void ObjAqua_Draw(Actor* thisx, GlobalContext* globalCtx) { if (actionFuncTemp) { s16 rotation = Math_SinS(this->unk_198) * 8000.0f; - Matrix_InsertZRotation_s(rotation, 1); - Matrix_Scale(1.3f, 1.0f, 1.0f, 1); - Matrix_InsertZRotation_s(rotation * -1, 1); - Matrix_Scale(10.0f / 13.0f, 1.0f, 1.0f, 1); + Matrix_InsertZRotation_s(rotation, MTXMODE_APPLY); + Matrix_Scale(1.3f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(rotation * -1, MTXMODE_APPLY); + Matrix_Scale(10.0f / 13.0f, 1.0f, 1.0f, MTXMODE_APPLY); } - Matrix_RotateY(yaw, 1); + Matrix_RotateY(yaw, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, D_0407D590); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c b/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c index b4f05d8ab3..30d0b2f0ab 100644 --- a/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c +++ b/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c @@ -36,7 +36,7 @@ void ObjFunen_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_RotateY((s16)(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - 0x8000), 1); + Matrix_RotateY((s16)(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - 0x8000), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); diff --git a/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c b/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c index 837c05ae9f..a62ce6cf6c 100644 --- a/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c +++ b/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c @@ -79,7 +79,7 @@ void ObjTokeiStep_SpawnDust(ObjTokeiStep* this, ObjTokeiStepPanel* panel, Global Vec3f dustSpawnOffset; Vec3f dustSpawnPos; - Matrix_RotateY(this->dyna.actor.shape.rot.y, 0); + Matrix_RotateY(this->dyna.actor.shape.rot.y, MTXMODE_NEW); dustSpawnOffset.y = 115.0f; dustSpawnOffset.z = -10.0f; From ad02db9b8271184eaa30cc60c3897ea1ab930cde Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Tue, 7 Dec 2021 14:18:25 +1100 Subject: [PATCH 02/27] Match func_809DAB78 (#495) --- src/overlays/actors/ovl_Boss_02/z_boss_02.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 7d4361f84a..090a1c3613 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -680,8 +680,6 @@ void func_809DAAA8(Boss02* this, GlobalContext* globalCtx) { this->actor.world.pos.y = -500.0f; } -#ifdef NON_MATCHING -// Saving to spC8 rather than spC4 at line 18dc void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { static Color_RGBA8 D_809DFA98 = { 185, 140, 70, 255 }; s32 pad; @@ -992,15 +990,15 @@ void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { this->actor.minVelocityY = -1000.0f * D_809DF5B0; this->unk_0164 = randPlusMinusPoint5Scaled(0.05f); - spC4 = player->actor.world.pos.x - this->actor.world.pos.x; - spC8 = player->actor.world.pos.z - this->actor.world.pos.z; - if (sqrtf(SQ(spC4) + SQ(spC8)) < (400.0f * D_809DF5B0)) { + spCC = player->actor.world.pos.x - this->actor.world.pos.x; + spC4 = player->actor.world.pos.z - this->actor.world.pos.z; + if (sqrtf(SQ(spCC) + SQ(spC4)) < (400.0f * D_809DF5B0)) { this->actor.speedXZ = 15.0f * D_809DF5B0; } - spC4 = this->actor.world.pos.x; - spC8 = this->actor.world.pos.z; - if (sqrtf(SQ(spC4) + SQ(spC8)) < (400.0f * D_809DF5B0)) { + spCC = this->actor.world.pos.x; + spC4 = this->actor.world.pos.z; + if (sqrtf(SQ(spCC) + SQ(spC4)) < (400.0f * D_809DF5B0)) { this->actor.speedXZ = 15.0f * D_809DF5B0; } @@ -1081,10 +1079,6 @@ void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); } -#else -static Color_RGBA8 D_809DFA98 = { 185, 140, 70, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DAB78.s") -#endif void func_809DBFB4(Boss02* this, GlobalContext* globalCtx) { Boss02* temp_s6 = this->unk_1674; From ff231e093a2fb34ca85eff71115ff777719cdb6d Mon Sep 17 00:00:00 2001 From: Lucas Shaw <49287729+shawlucas@users.noreply.github.com> Date: Mon, 6 Dec 2021 23:36:02 -0500 Subject: [PATCH 03/27] z_vr_box_draw OK (#481) * z_vr_box_draw OK * ok * Removed z_vr_box_draw.data.s, its actually z_sram_NES.data.s * Added enum SkyboxId --- include/functions.h | 10 +++--- include/variables.h | 2 +- include/z64.h | 11 ++++--- spec | 2 -- src/code/z_vr_box.c | 2 +- src/code/z_vr_box_draw.c | 66 +++++++++++++++++++++++++++++++++++--- tools/disasm/files.txt | 3 +- tools/disasm/functions.txt | 8 ++--- tools/disasm/variables.txt | 2 +- 9 files changed, 82 insertions(+), 24 deletions(-) diff --git a/include/functions.h b/include/functions.h index b1e71383f8..c29dc246d7 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2758,11 +2758,11 @@ s32 func_80142440(SkyboxContext* skyboxCtx, Vtx* vtx, s32 arg2, s32 arg3, s32 ar void func_80143148(SkyboxContext* skyboxCtx, s32 arg1); void func_801431E8(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyType); -void func_801434E4(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); -// void func_801435A0(void); -// void func_80143624(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6, UNK_TYPE1 param_7); -// void func_80143668(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); -// void func_80143A04(void); +void func_801434E4(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); +Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z); +void SkyboxDraw_SetColors(SkyboxContext* skyboxCtx, u8 primR, u8 primG, u8 primB, u8 envR, u8 envG, u8 envB); +void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z); +void SkyboxDraw_Noop(SkyboxContext* skyboxCtx); void func_80143A10(u8 owlId); // void func_80143A54(void); void func_80143AC4(void); diff --git a/include/variables.h b/include/variables.h index baf145e0f8..12e739c72e 100644 --- a/include/variables.h +++ b/include/variables.h @@ -3317,7 +3317,7 @@ extern Arena sZeldaArena; // extern UNK_TYPE1 D_801F6AD4; // extern UNK_TYPE1 D_801F6AD5; // extern UNK_TYPE1 D_801F6ADA; -// extern UNK_TYPE1 D_801F6AE0; +// extern UNK_TYPE1 sSkyboxDrawMatrix; // extern UNK_TYPE1 D_801F6AF0; // extern UNK_TYPE1 D_801F6AF2; // extern UNK_TYPE4 D_801F6B00; diff --git a/include/z64.h b/include/z64.h index 23f8c7df84..9e7341d965 100644 --- a/include/z64.h +++ b/include/z64.h @@ -766,11 +766,10 @@ typedef struct { typedef struct { /* 0x00000 */ View view; - /* 0x00168 */ void* skyboxStaticSegment[2]; - /* 0x00170 */ char unk170[8]; // more static segments? + /* 0x00168 */ void* skyboxStaticSegment[4]; /* 0x00178 */ void* skyboxPaletteStaticSegment; - /* 0x0017C */ Gfx* unk17C; - /* 0x00180 */ Gfx* unk180; + /* 0x0017C */ Gfx* dListBuf; + /* 0x00180 */ Gfx* roomDL; /* 0x00184 */ Vtx* roomVtx; /* 0x00188 */ DmaRequest unk188; /* 0x001A8 */ DmaRequest unk1A8; @@ -791,6 +790,10 @@ typedef struct { /* 0x00227 */ u8 envB; } SkyboxContext; // size = 0x228 +typedef enum { + /* 0x05 */ SKYBOX_CUTSCENE_MAP = 5 +} SkyboxId; + typedef struct ListAlloc { /* 0x00 */ struct ListAlloc* prev; /* 0x04 */ struct ListAlloc* next; diff --git a/spec b/spec index f4c8de05cd..94967bb0d3 100644 --- a/spec +++ b/spec @@ -553,8 +553,6 @@ beginseg include "build/src/code/code_801420C0.o" include "build/src/code/z_vr_box.o" include "build/src/code/z_vr_box_draw.o" - include "build/data/code/z_vr_box_draw.data.o" - include "build/data/code/z_vr_box_draw.bss.o" include "build/src/code/z_sram_NES.o" include "build/data/code/z_sram_NES.data.o" include "build/data/code/z_sram_NES.bss.o" diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index 724bc59711..29d1a1acad 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -140,7 +140,7 @@ void func_801434E4(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType) func_801431E8(gameState, skyboxCtx, skyType); if (skyType != 0) { - skyboxCtx->unk17C = THA_AllocEndAlign16(&gameState->heap, 0x3840); + skyboxCtx->dListBuf = THA_AllocEndAlign16(&gameState->heap, 0x3840); if (skyType == 5) { // Allocate enough space for the vertices for a 6 sided skybox (cube) diff --git a/src/code/z_vr_box_draw.c b/src/code/z_vr_box_draw.c index 27142c944a..d7f99eed9d 100644 --- a/src/code/z_vr_box_draw.c +++ b/src/code/z_vr_box_draw.c @@ -1,9 +1,67 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_801435A0.s") +Mtx* sSkyboxDrawMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_80143624.s") +Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) { + Matrix_InsertTranslation(x, y, z, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(skyboxCtx->rotX); + Matrix_InsertYRotation_f(skyboxCtx->rotY, MTXMODE_APPLY); + Matrix_InsertZRotation_f(skyboxCtx->rotZ, MTXMODE_APPLY); + return Matrix_ToMtx(sSkyboxDrawMatrix); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_80143668.s") +void SkyboxDraw_SetColors(SkyboxContext* skyboxCtx, u8 primR, u8 primG, u8 primB, u8 envR, u8 envG, u8 envB) { + skyboxCtx->primR = primR; + skyboxCtx->primG = primG; + skyboxCtx->primB = primB; + skyboxCtx->envR = envR; + skyboxCtx->envG = envG; + skyboxCtx->envB = envB; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_80143A04.s") +void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z) { + OPEN_DISPS(gfxCtx); + + func_8012C6AC(gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x0B, skyboxCtx->skyboxPaletteStaticSegment); + gSPTexture(POLY_OPA_DISP++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON); + + sSkyboxDrawMatrix = GRAPH_ALLOC(gfxCtx, sizeof(Mtx)); + + Matrix_InsertTranslation(x, y, z, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(skyboxCtx->rotX); + Matrix_InsertYRotation_f(skyboxCtx->rotY, MTXMODE_APPLY); + Matrix_InsertZRotation_f(skyboxCtx->rotZ, MTXMODE_APPLY); + Matrix_ToMtx(sSkyboxDrawMatrix); + + gSPMatrix(POLY_OPA_DISP++, sSkyboxDrawMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetColorDither(POLY_OPA_DISP++, G_CD_MAGICSQ); + gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP); + gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->skyboxPaletteStaticSegment); + gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16); + gDPSetTextureConvert(POLY_OPA_DISP++, G_TC_FILT); + gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, TEXEL0, PRIMITIVE_ALPHA, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0, + PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0, 0, 0, COMBINED); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, skyboxCtx->primR, skyboxCtx->primG, skyboxCtx->primB, blend); + gDPSetEnvColor(POLY_OPA_DISP++, skyboxCtx->envR, skyboxCtx->envG, skyboxCtx->envB, 0); + + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[0]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[300]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[600]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[900]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[1200]); + + if (skyboxId == SKYBOX_CUTSCENE_MAP) { + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[1500]); + } + + gDPPipeSync(POLY_OPA_DISP++); + + CLOSE_DISPS(gfxCtx); +} + +void SkyboxDraw_Noop(SkyboxContext* skyboxCtx) { +} diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt index 86f3f7f74f..2a4e77715b 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -556,8 +556,7 @@ 0x801C5D10 : "z_sub_s", 0x801C5DD0 : "z_vimode", 0x801C5E30 : "z_vr_box", - 0x801C5FC0 : "z_vr_box_draw", - 0x801C67B0 : "z_sram_NES", + 0x801C5FC0 : "z_sram_NES", 0x801D0470 : "z_message_nes", 0x801D0B50 : "", 0x801D0B70 : "z_kaleido_manager", diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 5d062ebb9c..d2f0f432b6 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2783,10 +2783,10 @@ 0x801431E8:("func_801431E8",), 0x80143324:("func_80143324",), 0x801434E4:("func_801434E4",), - 0x801435A0:("func_801435A0",), - 0x80143624:("func_80143624",), - 0x80143668:("func_80143668",), - 0x80143A04:("func_80143A04",), + 0x801435A0:("SkyboxDraw_UpdateMatrix",), + 0x80143624:("SkyboxDraw_SetColors",), + 0x80143668:("SkyboxDraw_Draw",), + 0x80143A04:("SkyboxDraw_Noop",), 0x80143A10:("func_80143A10",), 0x80143A54:("func_80143A54",), 0x80143AC4:("func_80143AC4",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 870579debc..e5a3e6e463 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -4094,7 +4094,7 @@ 0x801F6AD4:("D_801F6AD4","UNK_TYPE1","",0x1), 0x801F6AD5:("D_801F6AD5","UNK_TYPE1","",0x1), 0x801F6ADA:("D_801F6ADA","UNK_TYPE1","",0x1), - 0x801F6AE0:("D_801F6AE0","UNK_TYPE1","",0x1), + 0x801F6AE0:("sSkyboxDrawMatrix","Mtx*","",0x4), 0x801F6AF0:("D_801F6AF0","UNK_TYPE1","",0x1), 0x801F6AF2:("D_801F6AF2","UNK_TYPE1","",0x1), 0x801F6B00:("D_801F6B00","UNK_TYPE4","",0x4), From 9ca4ec7604bada9f26d7500ba5e4c508b4afd283 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Thu, 16 Dec 2021 04:05:29 +0000 Subject: [PATCH 04/27] ZAPD fixes in `sys_initial_check`, update subrepos (#507) * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "a3363333d" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "a3363333d" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/asm-differ --force subrepo: subdir: "tools/asm-differ" merged: "70c33cc12" upstream: origin: "https://github.com/simonlindholm/asm-differ.git" branch: "main" commit: "70c33cc12" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull (merge) tools/z64compress --force subrepo: subdir: "tools/z64compress" merged: "ac5b1a0d0" upstream: origin: "https://github.com/z64me/z64compress.git" branch: "main" commit: "ac5b1a0d0" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Use defines for texture sizes in sys_initial_check * Update extract_assets.py * Add null check * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "50242eca9" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "50242eca9" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" --- extract_assets.py | 31 +- src/code/sys_initial_check.c | 21 +- tools/ZAPD/.gitrepo | 4 +- tools/ZAPD/ExporterTest/ExporterTest.vcxproj | 5 +- tools/ZAPD/ExporterTest/Main.cpp | 8 +- tools/ZAPD/ExporterTest/Makefile | 2 +- tools/ZAPD/ExporterTest/RoomExporter.cpp | 40 +- tools/ZAPD/ExporterTest/TextureExporter.h | 2 +- tools/ZAPD/Jenkinsfile | 58 +-- tools/ZAPD/Makefile | 24 +- tools/ZAPD/README.md | 54 ++- tools/ZAPD/ZAPD/Declaration.cpp | 34 +- tools/ZAPD/ZAPD/Declaration.h | 4 +- tools/ZAPD/ZAPD/GameConfig.cpp | 4 +- tools/ZAPD/ZAPD/Globals.cpp | 5 +- tools/ZAPD/ZAPD/Globals.h | 5 +- tools/ZAPD/ZAPD/ImageBackend.cpp | 52 +- tools/ZAPD/ZAPD/Main.cpp | 56 ++- tools/ZAPD/ZAPD/NuGet/libpng.static.txt | 0 tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp | 18 +- tools/ZAPD/ZAPD/WarningHandler.cpp | 443 ++++++++++++++++++ tools/ZAPD/ZAPD/WarningHandler.h | 145 ++++++ tools/ZAPD/ZAPD/ZAPD.vcxproj | 35 +- tools/ZAPD/ZAPD/ZAPD.vcxproj.filters | 51 +- tools/ZAPD/ZAPD/ZAnimation.cpp | 9 +- tools/ZAPD/ZAPD/ZAnimation.h | 2 +- tools/ZAPD/ZAPD/ZArray.cpp | 23 +- tools/ZAPD/ZAPD/ZArray.h | 2 +- tools/ZAPD/ZAPD/ZBackground.cpp | 52 +- tools/ZAPD/ZAPD/ZBlob.cpp | 5 - tools/ZAPD/ZAPD/ZBlob.h | 1 - tools/ZAPD/ZAPD/ZCollision.cpp | 4 +- tools/ZAPD/ZAPD/ZCutscene.cpp | 12 +- tools/ZAPD/ZAPD/ZCutscene.h | 2 +- tools/ZAPD/ZAPD/ZCutsceneMM.h | 2 +- tools/ZAPD/ZAPD/ZDisplayList.cpp | 59 +-- tools/ZAPD/ZAPD/ZDisplayList.h | 3 +- tools/ZAPD/ZAPD/ZFile.cpp | 169 +++---- tools/ZAPD/ZAPD/ZFile.h | 2 +- tools/ZAPD/ZAPD/ZLimb.cpp | 20 +- tools/ZAPD/ZAPD/ZPath.cpp | 13 +- tools/ZAPD/ZAPD/ZResource.cpp | 72 +-- tools/ZAPD/ZAPD/ZResource.h | 9 +- tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp | 43 +- tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h | 2 +- .../ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp | 4 +- tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h | 2 +- tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp | 27 +- tools/ZAPD/ZAPD/ZRoom/ZRoom.h | 2 +- tools/ZAPD/ZAPD/ZScalar.cpp | 5 +- tools/ZAPD/ZAPD/ZScalar.h | 2 +- tools/ZAPD/ZAPD/ZSkeleton.cpp | 22 +- tools/ZAPD/ZAPD/ZSymbol.cpp | 19 +- tools/ZAPD/ZAPD/ZTexture.cpp | 63 +-- tools/ZAPD/ZAPD/ZTextureAnimation.cpp | 124 ++--- tools/ZAPD/ZAPD/ZVector.cpp | 13 +- tools/ZAPD/ZAPD/ZVector.h | 2 +- tools/ZAPD/ZAPD/ZVtx.h | 2 +- tools/ZAPD/ZAPD/any/any/zlib.static.txt | 0 tools/ZAPD/ZAPD/packages.config | 5 +- tools/ZAPD/ZAPDUtils/Color3b.h | 2 +- tools/ZAPD/ZAPDUtils/Makefile | 2 +- tools/ZAPD/ZAPDUtils/StrHash.h | 6 +- tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp | 6 +- tools/ZAPD/ZAPDUtils/Utils/BitConverter.h | 2 +- tools/ZAPD/ZAPDUtils/Utils/File.h | 2 +- tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp | 2 +- tools/ZAPD/ZAPDUtils/Utils/Path.h | 4 +- tools/ZAPD/ZAPDUtils/Utils/Stream.h | 2 +- tools/ZAPD/ZAPDUtils/Utils/StringHelper.h | 14 +- tools/ZAPD/ZAPDUtils/Utils/vt.h | 45 ++ tools/ZAPD/ZAPDUtils/Vec2f.h | 2 +- tools/ZAPD/ZAPDUtils/Vec3f.h | 2 +- tools/ZAPD/ZAPDUtils/Vec3s.h | 2 +- tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj | 5 +- .../ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters | 6 + tools/ZAPD/docs/zapd_warning_example.png | Bin 0 -> 47521 bytes tools/asm-differ/.gitrepo | 4 +- tools/asm-differ/diff.py | 304 +++++++----- tools/z64compress/.gitrepo | 4 +- tools/z64compress/src/main.c | 3 +- tools/z64compress/src/rom.c | 85 ++-- 82 files changed, 1646 insertions(+), 757 deletions(-) create mode 100644 tools/ZAPD/ZAPD/NuGet/libpng.static.txt create mode 100644 tools/ZAPD/ZAPD/WarningHandler.cpp create mode 100644 tools/ZAPD/ZAPD/WarningHandler.h create mode 100644 tools/ZAPD/ZAPD/any/any/zlib.static.txt create mode 100644 tools/ZAPD/ZAPDUtils/Utils/vt.h create mode 100644 tools/ZAPD/docs/zapd_warning_example.png diff --git a/extract_assets.py b/extract_assets.py index 066c1de3cd..a7825af1fe 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 -import argparse, json, os, signal, time +import argparse, json, os, signal, time, colorama from multiprocessing import Pool, Event, Manager +colorama.init(); + EXTRACTED_ASSETS_NAMEFILE = ".extracted-assets.json" def SignalHandler(sig, frame): @@ -15,10 +17,10 @@ def ExtractFile(xmlPath, outputPath, outputSourcePath): # Don't extract if another file wasn't extracted properly. return - execStr = "tools/ZAPD/ZAPD.out e -eh -i %s -b baserom/ -o %s -osf %s -gsf 1 -rconf tools/ZAPDConfigs/MM/Config.xml" % (xmlPath, outputPath, outputSourcePath) + execStr = f"tools/ZAPD/ZAPD.out e -eh -i {xmlPath} -b baserom/ -o {outputPath} -osf {outputSourcePath} -gsf 1 -rconf tools/ZAPDConfigs/MM/Config.xml {ZAPDArgs}" if globalUnaccounted: - execStr += " -wu" + execStr += " -Wunaccounted" print(execStr) exitValue = os.system(execStr) @@ -72,8 +74,27 @@ def main(): parser.add_argument("-t", "--threads", help="Number of cpu cores to extract with.") parser.add_argument("-f", "--force", help="Force the extraction of every xml instead of checking the touched ones.", action="store_true") parser.add_argument("-u", "--unaccounted", help="Enables ZAPD unaccounted detector warning system.", action="store_true") + parser.add_argument("-Z", help="Pass the argument on to ZAPD, e.g. `-ZWunaccounted` to warn about unaccounted blocks in XMLs. Each argument should be passed separately, *without* the leading dash.", metavar="ZAPD_ARG", action="append") args = parser.parse_args() + global ZAPDArgs; + ZAPDArgs = ""; + if args.Z is not None: + badZAPDArg = False; + for i in range(len(args.Z)): + z = args.Z[i] + if z[0] == '-': + print(f"{colorama.Fore.LIGHTRED_EX}error{colorama.Fore.RESET}: argument \"{z}\" starts with \"-\", which is not supported.", file=os.sys.stderr); + badZAPDArg = True; + else: + args.Z[i] = "-" + z; + + if badZAPDArg: + exit(1); + + ZAPDArgs = " ".join(args.Z); + print("Using extra ZAPD arguments: " + ZAPDArgs); + global mainAbort mainAbort = Event() manager = Manager() @@ -88,7 +109,7 @@ def main(): if asset_path is not None: fullPath = os.path.join("assets", "xml", asset_path + ".xml") if not os.path.exists(fullPath): - print(f"Error. File {fullPath} doesn't exists.", file=os.sys.stderr) + print(f"Error. File {fullPath} does not exist.", file=os.sys.stderr) exit(1) initializeWorker(mainAbort, args.unaccounted, extractedAssetsTracker, manager) @@ -107,7 +128,7 @@ def main(): numCores = int(args.threads or 0) if numCores <= 0: numCores = 1 - print("Extracting assets with " + str(numCores) + " CPU cores.") + print("Extracting assets with " + str(numCores) + " CPU core" + ("s" if numCores > 1 else "") + ".") with Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, args.unaccounted, extractedAssetsTracker, manager)) as p: p.map(ExtractFunc, xmlFiles) diff --git a/src/code/sys_initial_check.c b/src/code/sys_initial_check.c index 84871255b8..ec61d07b56 100644 --- a/src/code/sys_initial_check.c +++ b/src/code/sys_initial_check.c @@ -10,8 +10,16 @@ #include "misc/locerrmsg/locerrmsg.h" #include "misc/memerrmsg/memerrmsg.h" -#define SIZEOF_LOCERRMSG (sizeof(gNotDesignedForSystemErrorTex)) -#define SIZEOF_MEMERRMSG (sizeof(gExpansionPakNotInstalledErrorTex) + sizeof(gSeeInstructionBookletErrorTex)) +#define LOCERRMSG_WIDTH 208 +#define LOCERRMSG_HEIGHT 16 +#define NUMBEROF_LOCERRMSGS 1 + +#define MEMERRMSG_WIDTH 128 +#define MEMERRMSG_HEIGHT 37 +#define NUMBEROF_MEMERRMSGS 2 + +#define SIZEOF_LOCERRMSG (LOCERRMSG_WIDTH * LOCERRMSG_HEIGHT / 2 * NUMBEROF_LOCERRMSGS) +#define SIZEOF_MEMERRMSG (MEMERRMSG_WIDTH * MEMERRMSG_HEIGHT / 2 * NUMBEROF_MEMERRMSGS) // Address with enough room after to load either of the error message image files before the fault screen buffer at the // end of RDRAM @@ -64,9 +72,9 @@ void Check_ClearRGBA16(u16* buffer) { void Check_DrawExpansionPakErrorMessage(void) { DmaMgr_SendRequest0(CHECK_ERRMSG_STATIC_SEGMENT, SEGMENT_ROM_START(memerrmsg), SEGMENT_SIZE(memerrmsg)); Check_ClearRGBA16((u16*)FAULT_FB_ADDRESS); - Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 71, 128, 37, CHECK_ERRMSG_STATIC_SEGMENT); - Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 127, 128, 37, - CHECK_ERRMSG_STATIC_SEGMENT + sizeof(gExpansionPakNotInstalledErrorTex)); + Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 71, MEMERRMSG_WIDTH, MEMERRMSG_HEIGHT, CHECK_ERRMSG_STATIC_SEGMENT); + Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 127, MEMERRMSG_WIDTH, MEMERRMSG_HEIGHT, + CHECK_ERRMSG_STATIC_SEGMENT + MEMERRMSG_WIDTH * MEMERRMSG_HEIGHT / 2); osWritebackDCacheAll(); osViSwapBuffer((u16*)FAULT_FB_ADDRESS); osViBlack(false); @@ -78,7 +86,8 @@ void Check_DrawExpansionPakErrorMessage(void) { void Check_DrawRegionLockErrorMessage(void) { DmaMgr_SendRequest0(CHECK_ERRMSG_STATIC_SEGMENT, SEGMENT_ROM_START(locerrmsg), SEGMENT_SIZE(locerrmsg)); Check_ClearRGBA16((u16*)FAULT_FB_ADDRESS); - Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 56, 112, 208, 16, CHECK_ERRMSG_STATIC_SEGMENT); + Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 56, 112, LOCERRMSG_WIDTH, LOCERRMSG_HEIGHT, + CHECK_ERRMSG_STATIC_SEGMENT); osWritebackDCacheAll(); osViSwapBuffer((u16*)FAULT_FB_ADDRESS); osViBlack(false); diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo index 94da913d0d..a942638a2e 100644 --- a/tools/ZAPD/.gitrepo +++ b/tools/ZAPD/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/zeldaret/ZAPD.git branch = master - commit = 4f7b8393ec8a3abd59649c2ba669e951fb61f3d2 - parent = 346df1bbc8ca21673fe63d884b6734c23a4d9f4b + commit = 50242eca96a9c36fd84f438bab24548e73b42303 + parent = 744955732b1fc9e8a835c62440aa97799cfe8940 method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/ExporterTest/ExporterTest.vcxproj b/tools/ZAPD/ExporterTest/ExporterTest.vcxproj index a709a35091..839d451023 100644 --- a/tools/ZAPD/ExporterTest/ExporterTest.vcxproj +++ b/tools/ZAPD/ExporterTest/ExporterTest.vcxproj @@ -79,7 +79,7 @@ true - $(SolutionDir)\ZAPD\;$(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath) + $(ProjectDir)..\ZAPD\;$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) false @@ -120,6 +120,7 @@ true stdcpp17 stdc11 + MultiThreadedDebug Console @@ -156,4 +157,4 @@ - + \ No newline at end of file diff --git a/tools/ZAPD/ExporterTest/Main.cpp b/tools/ZAPD/ExporterTest/Main.cpp index 4f683a1ba3..07fdbeeced 100644 --- a/tools/ZAPD/ExporterTest/Main.cpp +++ b/tools/ZAPD/ExporterTest/Main.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "CollisionExporter.h" +#include "Globals.h" +#include "RoomExporter.h" +#include "TextureExporter.h" enum class ExporterFileMode { diff --git a/tools/ZAPD/ExporterTest/Makefile b/tools/ZAPD/ExporterTest/Makefile index a2bfa9a814..42033b7c0c 100644 --- a/tools/ZAPD/ExporterTest/Makefile +++ b/tools/ZAPD/ExporterTest/Makefile @@ -1,7 +1,7 @@ # Only used for standalone compilation, usually inherits these from the main makefile CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17 -SRC_DIRS := $(shell find -type d -not -path "*build*") +SRC_DIRS := $(shell find . -type d -not -path "*build*") CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) diff --git a/tools/ZAPD/ExporterTest/RoomExporter.cpp b/tools/ZAPD/ExporterTest/RoomExporter.cpp index c4a6844fb5..6c5552d8f8 100644 --- a/tools/ZAPD/ExporterTest/RoomExporter.cpp +++ b/tools/ZAPD/ExporterTest/RoomExporter.cpp @@ -1,24 +1,24 @@ #include "RoomExporter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "CollisionExporter.h" +#include "Utils/BinaryWriter.h" +#include "Utils/File.h" +#include "Utils/MemoryStream.h" +#include "ZRoom/Commands/SetCameraSettings.h" +#include "ZRoom/Commands/SetCollisionHeader.h" +#include "ZRoom/Commands/SetCsCamera.h" +#include "ZRoom/Commands/SetEchoSettings.h" +#include "ZRoom/Commands/SetEntranceList.h" +#include "ZRoom/Commands/SetLightingSettings.h" +#include "ZRoom/Commands/SetMesh.h" +#include "ZRoom/Commands/SetRoomBehavior.h" +#include "ZRoom/Commands/SetRoomList.h" +#include "ZRoom/Commands/SetSkyboxModifier.h" +#include "ZRoom/Commands/SetSkyboxSettings.h" +#include "ZRoom/Commands/SetSoundSettings.h" +#include "ZRoom/Commands/SetSpecialObjects.h" +#include "ZRoom/Commands/SetStartPositionList.h" +#include "ZRoom/Commands/SetTimeSettings.h" +#include "ZRoom/Commands/SetWind.h" void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer) { diff --git a/tools/ZAPD/ExporterTest/TextureExporter.h b/tools/ZAPD/ExporterTest/TextureExporter.h index ffe6001dca..41c4e79be2 100644 --- a/tools/ZAPD/ExporterTest/TextureExporter.h +++ b/tools/ZAPD/ExporterTest/TextureExporter.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "Utils/BinaryWriter.h" #include "ZResource.h" #include "ZTexture.h" diff --git a/tools/ZAPD/Jenkinsfile b/tools/ZAPD/Jenkinsfile index 051e5f9982..8db69a1e30 100644 --- a/tools/ZAPD/Jenkinsfile +++ b/tools/ZAPD/Jenkinsfile @@ -7,7 +7,7 @@ pipeline { // Non-parallel ZAPD stage stage('Build ZAPD') { steps { - sh 'make -j' + sh 'make -j WERROR=1' } } @@ -22,13 +22,13 @@ pipeline { } } - stage('Checkout mm') { - steps{ - dir('mm') { - git url: 'https://github.com/zeldaret/mm.git' - } - } - } + // stage('Checkout mm') { + // steps{ + // dir('mm') { + // git url: 'https://github.com/zeldaret/mm.git' + // } + // } + // } } } @@ -51,20 +51,20 @@ pipeline { } } - stage('Setup MM') { - steps { - dir('mm') { - sh 'cp /usr/local/etc/roms/mm.us.rev1.z64 baserom.mm.us.rev1.z64' + // stage('Setup MM') { + // steps { + // dir('mm') { + // sh 'cp /usr/local/etc/roms/mm.us.rev1.z64 baserom.mm.us.rev1.z64' - // Identical to `make setup` except for copying our newer ZAPD.out into mm - sh 'make -C tools' - sh 'cp ../ZAPD.out tools/ZAPD/' - sh 'python3 tools/fixbaserom.py' - sh 'python3 tools/extract_baserom.py' - sh 'python3 extract_assets.py -t 4' - } - } - } + // // Identical to `make setup` except for copying our newer ZAPD.out into mm + // sh 'make -C tools' + // sh 'cp ../ZAPD.out tools/ZAPD/' + // sh 'python3 tools/fixbaserom.py' + // sh 'python3 tools/extract_baserom.py' + // sh 'python3 extract_assets.py -t 4' + // } + // } + // } } } @@ -78,14 +78,14 @@ pipeline { } } } - stage('Build mm') { - steps { - dir('mm') { - sh 'make -j disasm' - sh 'make -j all' - } - } - } + // stage('Build mm') { + // steps { + // dir('mm') { + // sh 'make -j disasm' + // sh 'make -j all' + // } + // } + // } } } } diff --git a/tools/ZAPD/Makefile b/tools/ZAPD/Makefile index 737b85ecf7..2b47a8039b 100644 --- a/tools/ZAPD/Makefile +++ b/tools/ZAPD/Makefile @@ -6,6 +6,7 @@ DEPRECATION_ON ?= 1 DEBUG ?= 0 COPYCHECK_ARGS ?= LLD ?= 0 +WERROR ?= 0 # Use clang++ if available, else use g++ ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0) @@ -23,14 +24,16 @@ ifneq ($(DEBUG),0) CXXFLAGS += -g3 -DDEVELOPMENT -D_DEBUG COPYCHECK_ARGS += --devel DEPRECATION_ON = 0 -else +endif + +ifneq ($(WERROR),0) CXXFLAGS += -Werror endif ifeq ($(OPTIMIZATION_ON),0) OPTFLAGS := -O0 else - OPTFLAGS := -O2 -march=native -mtune=native + OPTFLAGS := -O2 endif ifneq ($(ASAN),0) @@ -53,10 +56,23 @@ ifneq ($(LLD),0) endif UNAME := $(shell uname) +UNAMEM := $(shell uname -m) ifneq ($(UNAME), Darwin) - LDFLAGS += -Wl,-export-dynamic -lstdc++fs + LDFLAGS += -Wl,-export-dynamic -lstdc++fs + EXPORTERS := -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive +else + EXPORTERS := -Wl,-force_load ExporterTest/ExporterTest.a + ifeq ($(UNAMEM),arm64) + ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0) + LDFLAGS += -L $(shell brew --prefix)/lib + INC += -I $(shell brew --prefix)/include + else + $(error Please install libpng via Homebrew) + endif + endif endif + ZAPD_SRC_DIRS := $(shell find ZAPD -type d) SRC_DIRS = $(ZAPD_SRC_DIRS) lib/tinyxml2 @@ -115,4 +131,4 @@ ZAPDUtils: # Linking ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils - $(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive $(LDFLAGS) $(OUTPUT_OPTION) + $(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION) diff --git a/tools/ZAPD/README.md b/tools/ZAPD/README.md index e2764b6277..44d26b8b3e 100644 --- a/tools/ZAPD/README.md +++ b/tools/ZAPD/README.md @@ -16,6 +16,14 @@ In a Debian/Ubuntu based environment, those could be installed with the followin sudo apt install libpng-dev ``` +On a Mac, you will need to install libpng with Homebrew or MacPorts; we currently only support Homebrew. You can run + +```bash +brew install libpng +``` + +to install it via Homebrew. + ### Building #### Linux / *nix @@ -109,11 +117,51 @@ ZAPD also accepts the following list of extra parameters: - Could be useful for looking at raw data or testing. - Can be used only in `e` or `bsf` modes. - `-tm MODE`: Test Mode (enables certain experimental features). To enable it, set `MODE` to `1`. -- `-wno` / `--warn-no-offsets` : Enable warnings for nodes that dont have offsets specified. Takes priority over `-eno`/ `--error-no-offsets`. -- `-eno` / `--error-no-offsets` : Enable errors for nodes that dont have offsets specified. - `-se` / `--set-exporter` : Sets which exporter to use. -- `--gcc-compat` : Enables GCC compatible mode. Slower. +- `--gcc-compat` : Enables GCC compatibly mode. Slower. - `-s` / `--static` : Mark every asset as `static`. - This behaviour can be overridden per asset using `Static=` in the respective XML node. +- `-W...`: warning flags, see below Additionally, you can pass the flag `--version` to see the current ZAPD version. If that flag is passed, ZAPD will ignore any other parameter passed. + +### Warning flags + +ZAPD contains a variety of warning types, with similar syntax to GCC or Clang's compiler warnings. Warnings can have three levels: + +- Off (does not display anything) +- Warn (print a warning but continue processing) +- Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs) + +Each warning type uses one of these by default, but can be modified with flags, similarly to GCC or Clang: + +- `-Wfoo` enables warnings of type `foo` +- `-Wno-foo` disables warnings of type `foo` +- `-Werror=foo` escalates `foo` to behave like an error +- `-Weverything` enables all warnings (they may be turned off using `-Wno-` flags afterwards) +- `-Werror` escalates all enabled warnings to errors + +All warning types currently implemented, with their default levels: + +| Warning type | Default level | Description | +| --------------------------- | ------------- | ------------------------------------------------------------------------ | +| `-Wdeprecated` | Warn | Deprecated features | +| `-Whardcoded-pointer` | Warn | ZAPD lacks the info to make a symbol, so must output a hardcoded pointer | +| `-Wintersection` | Warn | Two assets intersect | +| `-Winvalid-attribute-value` | Err | Attribute declared in XML is wrong | +| `-Winvalid-extracted-data` | Err | Extracted data does not have correct form | +| `-Winvalid-jpeg` | Err | JPEG file does not conform to the game's format requirements | +| `-Winvalid-png` | Err | Issues arising when processing PNG data | +| `-Winvalid-xml` | Err | XML has syntax errors | +| `-Wmissing-attribute` | Warn | Required attribute missing in XML tag | +| `-Wmissing-offsets` | Warn | Offset attribute missing in XML tag | +| `-Wmissing-segment` | Warn | Segment not given in File tag in XML | +| `-Wnot-implemented` | Warn | ZAPD does not currently support this feature | +| `-Wunaccounted` | Off | Large blocks of unaccounted | +| `-Wunknown-attribute` | Warn | Unknown attribute in XML entry tag | + +There are also errors that do not have a type, and cannot be disabled. + +For example, here we have invoked ZAPD in the usual way to extract using a (rather badly-written) XML, but escalating `-Wintersection` to an error: + +![ZAPD warnings example](docs/zapd_warning_example.png?raw=true) diff --git a/tools/ZAPD/ZAPD/Declaration.cpp b/tools/ZAPD/ZAPD/Declaration.cpp index d2a86ffcc5..be06b0bea7 100644 --- a/tools/ZAPD/ZAPD/Declaration.cpp +++ b/tools/ZAPD/ZAPD/Declaration.cpp @@ -92,20 +92,20 @@ std::string Declaration::GetNormalDeclarationStr() const if (isArray) { - if (arrayItemCntStr != "") + if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt)) { output += StringHelper::Sprintf("%s %s[%s];\n", varType.c_str(), varName.c_str(), arrayItemCntStr.c_str()); } - else if (arrayItemCnt == 0) - { - output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str()); - } - else + else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt)) { output += StringHelper::Sprintf("%s %s[%i] = {\n", varType.c_str(), varName.c_str(), arrayItemCnt); } + else + { + output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str()); + } output += text + "\n"; } @@ -145,16 +145,16 @@ std::string Declaration::GetExternalDeclarationStr() const output += "static "; } - if (arrayItemCntStr != "") + if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt)) + output += StringHelper::Sprintf("%s %s[%s] = ", varType.c_str(), varName.c_str(), + arrayItemCntStr.c_str()); + else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt)) output += - StringHelper::Sprintf("%s %s[%s] = {\n#include \"%s\"\n};", varType.c_str(), - varName.c_str(), arrayItemCntStr.c_str(), includePath.c_str()); - else if (arrayItemCnt != 0) - output += StringHelper::Sprintf("%s %s[%i] = {\n#include \"%s\"\n};", varType.c_str(), - varName.c_str(), arrayItemCnt, includePath.c_str()); + StringHelper::Sprintf("%s %s[%i] = ", varType.c_str(), varName.c_str(), arrayItemCnt); else - output += StringHelper::Sprintf("%s %s[] = {\n#include \"%s\"\n};", varType.c_str(), - varName.c_str(), includePath.c_str()); + output += StringHelper::Sprintf("%s %s[] = ", varType.c_str(), varName.c_str()); + + output += StringHelper::Sprintf("{\n#include \"%s\"\n};", includePath.c_str()); if (rightText != "") output += " " + rightText + ""; @@ -178,14 +178,16 @@ std::string Declaration::GetExternStr() const if (isArray) { - if (arrayItemCntStr != "") + if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt)) { return StringHelper::Sprintf("extern %s %s[%s];\n", varType.c_str(), varName.c_str(), arrayItemCntStr.c_str()); } - else if (arrayItemCnt != 0) + else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt)) + { return StringHelper::Sprintf("extern %s %s[%i];\n", varType.c_str(), varName.c_str(), arrayItemCnt); + } else return StringHelper::Sprintf("extern %s %s[];\n", varType.c_str(), varName.c_str()); } diff --git a/tools/ZAPD/ZAPD/Declaration.h b/tools/ZAPD/ZAPD/Declaration.h index 138524a4c2..b7bb0d30d2 100644 --- a/tools/ZAPD/ZAPD/Declaration.h +++ b/tools/ZAPD/ZAPD/Declaration.h @@ -38,10 +38,12 @@ public: std::string varType; std::string varName; std::string includePath; + bool isExternal = false; bool isArray = false; + bool forceArrayCnt = false; size_t arrayItemCnt = 0; - std::string arrayItemCntStr; + std::string arrayItemCntStr = ""; std::vector references; bool isUnaccounted = false; bool isPlaceholder = false; diff --git a/tools/ZAPD/ZAPD/GameConfig.cpp b/tools/ZAPD/ZAPD/GameConfig.cpp index f197493a4a..ae29ba28fa 100644 --- a/tools/ZAPD/ZAPD/GameConfig.cpp +++ b/tools/ZAPD/ZAPD/GameConfig.cpp @@ -25,7 +25,7 @@ GameConfig::~GameConfig() void GameConfig::ReadTexturePool(const fs::path& texturePoolXmlPath) { tinyxml2::XMLDocument doc; - tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.c_str()); + tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.string().c_str()); if (eResult != tinyxml2::XML_SUCCESS) { @@ -155,7 +155,7 @@ void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath) {"ExternalFile", &GameConfig::ConfigFunc_ExternalFile}, }; - configFilePath = argConfigFilePath; + configFilePath = argConfigFilePath.string(); tinyxml2::XMLDocument doc; tinyxml2::XMLError eResult = doc.LoadFile(configFilePath.c_str()); diff --git a/tools/ZAPD/ZAPD/Globals.cpp b/tools/ZAPD/ZAPD/Globals.cpp index 036e4a5cbf..528a09d256 100644 --- a/tools/ZAPD/ZAPD/Globals.cpp +++ b/tools/ZAPD/ZAPD/Globals.cpp @@ -3,8 +3,9 @@ #include #include -#include -#include +#include "Utils/File.h" +#include "Utils/Path.h" +#include "WarningHandler.h" #include "tinyxml2.h" Globals* Globals::Instance; diff --git a/tools/ZAPD/ZAPD/Globals.h b/tools/ZAPD/ZAPD/Globals.h index 265f1af241..19e193f123 100644 --- a/tools/ZAPD/ZAPD/Globals.h +++ b/tools/ZAPD/ZAPD/Globals.h @@ -20,6 +20,7 @@ typedef bool (*ExporterSetFuncBool)(ZFileMode fileMode); typedef void (*ExporterSetFuncVoid)(int argc, char* argv[], int& i); typedef void (*ExporterSetFuncVoid2)(const std::string& buildMode, ZFileMode& fileMode); typedef void (*ExporterSetFuncVoid3)(); +typedef void (*ExporterSetResSave)(ZResource* res, BinaryWriter& writer); class ExporterSet { @@ -34,6 +35,7 @@ public: ExporterSetFunc endFileFunc = nullptr; ExporterSetFuncVoid3 beginXMLFunc = nullptr; ExporterSetFuncVoid3 endXMLFunc = nullptr; + ExporterSetResSave resSaveFunc = nullptr; }; class Globals @@ -53,9 +55,6 @@ public: TextureType texType; ZGame game; GameConfig cfg; - bool warnUnaccounted = false; - bool warnNoOffset = false; - bool errorNoOffset = false; bool verboseUnaccounted = false; bool gccCompat = false; bool forceStatic = false; diff --git a/tools/ZAPD/ZAPD/ImageBackend.cpp b/tools/ZAPD/ZAPD/ImageBackend.cpp index 137e326c33..8accb6b4e1 100644 --- a/tools/ZAPD/ZAPD/ImageBackend.cpp +++ b/tools/ZAPD/ZAPD/ImageBackend.cpp @@ -6,6 +6,7 @@ #include #include "Utils/StringHelper.h" +#include "WarningHandler.h" /* ImageBackend */ @@ -20,19 +21,28 @@ void ImageBackend::ReadPng(const char* filename) FILE* fp = fopen(filename, "rb"); if (fp == nullptr) - throw std::runtime_error(StringHelper::Sprintf( - "ImageBackend::ReadPng: Error.\n\t Couldn't open file '%s'.", filename)); + { + std::string errorHeader = StringHelper::Sprintf("could not open file '%s'", filename); + HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, ""); + } png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png) - throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png struct."); + if (png == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", ""); + } png_infop info = png_create_info_struct(png); - if (!info) - throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png info."); + if (info == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", ""); + } if (setjmp(png_jmpbuf(png))) - throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t setjmp(png_jmpbuf(png))."); + { + // TODO: better warning explanation + HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", ""); + } png_init_io(png, fp); @@ -145,20 +155,30 @@ void ImageBackend::WritePng(const char* filename) assert(hasImageData); FILE* fp = fopen(filename, "wb"); - if (!fp) - throw std::runtime_error(StringHelper::Sprintf( - "ImageBackend::WritePng: Error.\n\t Couldn't open file '%s' in write mode.", filename)); + if (fp == nullptr) + { + std::string errorHeader = + StringHelper::Sprintf("could not open file '%s' in write mode", filename); + HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, ""); + } png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png) - throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png struct."); + if (png == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", ""); + } png_infop info = png_create_info_struct(png); - if (!info) - throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png info."); + if (info == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", ""); + } if (setjmp(png_jmpbuf(png))) - throw std::runtime_error("ImageBackend::WritePng: Error.\n\t setjmp(png_jmpbuf(png))."); + { + // TODO: better warning description + HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", ""); + } png_init_io(png, fp); @@ -441,7 +461,7 @@ double ImageBackend::GetBytesPerPixel() const return 1 * bitDepth / 8; default: - throw std::invalid_argument("ImageBackend::GetBytesPerPixel():\n\t Invalid color type."); + HANDLE_ERROR(WarningType::InvalidPNG, "invalid color type", ""); } } diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp index 298ca02629..fd2ed06dc0 100644 --- a/tools/ZAPD/ZAPD/Main.cpp +++ b/tools/ZAPD/ZAPD/Main.cpp @@ -1,8 +1,9 @@ -#include -#include -#include #include "Globals.h" #include "Overlays/ZOverlay.h" +#include "Utils/Directory.h" +#include "Utils/File.h" +#include "Utils/Path.h" +#include "WarningHandler.h" #include "ZAnimation.h" #include "ZBackground.h" #include "ZBlob.h" @@ -12,10 +13,10 @@ #if !defined(_MSC_VER) && !defined(__CYGWIN__) #include #include +#include #include // for __cxa_demangle #include // for dladdr #include -#include #include #endif @@ -47,6 +48,7 @@ void ErrorHandler(int sig) const char* crashEasterEgg[] = { "\tYou've met with a terrible fate, haven't you?", "\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!", + "ZAPD has fallen and cannot get up." }; srand(time(nullptr)); @@ -97,6 +99,9 @@ int main(int argc, char* argv[]) return 1; } + Globals* g = new Globals(); + WarningHandler::Init(argc, argv); + for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--version")) @@ -109,12 +114,12 @@ int main(int argc, char* argv[]) printf("Congratulations!\n"); printf("You just found the (unimplemented and undocumented) ZAPD's help message.\n"); printf("Feel free to implement it if you want :D\n"); + + WarningHandler::PrintHelp(); return 0; } } - Globals* g = new Globals; - // Parse other "commands" for (int32_t i = 2; i < argc; i++) { @@ -186,26 +191,15 @@ int main(int argc, char* argv[]) signal(SIGSEGV, ErrorHandler); signal(SIGABRT, ErrorHandler); #else - fprintf(stderr, - "Warning: Tried to set error handler, but this build lacks support for one.\n"); + HANDLE_WARNING(WarningType::Always, + "tried to set error handler, but this ZAPD build lacks support for one", + ""); #endif } else if (arg == "-v") // Verbose { Globals::Instance->verbosity = static_cast(strtol(argv[++i], NULL, 16)); } - else if (arg == "-wu" || arg == "--warn-unaccounted") // Warn unaccounted - { - Globals::Instance->warnUnaccounted = true; - } - else if (arg == "-wno" || arg == "--warn-no-offset") - { - Globals::Instance->warnNoOffset = true; - } - else if (arg == "-eno" || arg == "--error-no-offset") - { - Globals::Instance->errorNoOffset = true; - } else if (arg == "-vu" || arg == "--verbose-unaccounted") // Verbose unaccounted { Globals::Instance->verboseUnaccounted = true; @@ -262,6 +256,11 @@ int main(int argc, char* argv[]) if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) + { + WarningHandler::PrintWarningsDebugInfo(); + } + // TODO: switch if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) { @@ -334,7 +333,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path if (eResult != tinyxml2::XML_SUCCESS) { - fprintf(stderr, "Invalid xml file: '%s'\n", xmlFilePath.c_str()); + // TODO: use XMLDocument::ErrorIDToName to get more specific error messages here + HANDLE_ERROR(WarningType::InvalidXML, + StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), ""); return false; } @@ -342,7 +343,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path if (root == nullptr) { - fprintf(stderr, "Missing Root tag in xml file: '%s'\n", xmlFilePath.c_str()); + HANDLE_WARNING( + WarningType::InvalidXML, + StringHelper::Sprintf("missing Root tag in xml file: '%s'", xmlFilePath.c_str()), ""); return false; } @@ -392,10 +395,11 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path } else { - throw std::runtime_error(StringHelper::Sprintf( - "Parse: Fatal error in '%s'.\n\t A resource was found outside of " - "a File element: '%s'\n", - xmlFilePath.c_str(), child->Name())); + std::string errorHeader = + StringHelper::Sprintf("when parsing file '%s'", xmlFilePath.c_str()); + std::string errorBody = StringHelper::Sprintf( + "Found a resource outside a File element: '%s'", child->Name()); + HANDLE_ERROR(WarningType::InvalidXML, errorHeader, errorBody); } } diff --git a/tools/ZAPD/ZAPD/NuGet/libpng.static.txt b/tools/ZAPD/ZAPD/NuGet/libpng.static.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp index a842a7e7d9..510de19aba 100644 --- a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp +++ b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp @@ -1,13 +1,13 @@ #include "ZOverlay.h" -#include +#include #include - -#include -#include -#include -#include #include "Globals.h" +#include "Utils/Directory.h" +#include "Utils/File.h" +#include "Utils/Path.h" +#include "Utils/StringHelper.h" +#include "WarningHandler.h" using namespace ELFIO; @@ -90,7 +90,7 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath) std::vector readers; for (size_t i = 1; i < cfgLines.size(); i++) { - std::string elfPath = buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o"); + std::string elfPath = (buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string(); elfio* reader = new elfio(); if (!reader->load(elfPath)) @@ -128,7 +128,9 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath) SectionType sectionType = GetSectionTypeFromStr(pSec->get_name()); if (sectionType == SectionType::ERROR) - fprintf(stderr, "WARNING: One of the section types returned ERROR\n"); + { + HANDLE_WARNING(WarningType::Always, "one of the section types returned ERROR", ""); + } relocation_section_accessor relocs(*curReader, pSec); for (Elf_Xword j = 0; j < relocs.get_entries_num(); j++) diff --git a/tools/ZAPD/ZAPD/WarningHandler.cpp b/tools/ZAPD/ZAPD/WarningHandler.cpp new file mode 100644 index 0000000000..29f8352a71 --- /dev/null +++ b/tools/ZAPD/ZAPD/WarningHandler.cpp @@ -0,0 +1,443 @@ +/** + * ZAPD Warning- and Error-handling system + * ======================================= + * + * This provides a common standard way to write ZAPD warnings/errors, which should be used for all + * such. It will pretty-print them in a uniform way, with styles defined in the header. + * + * Warnings/errors should be constructed using the macros given in the header; there are now plenty + * of examples in the codebase of how to do this. Their purposes are noted above each category in + * the header. Each warning has a type, one of the ones in warningStringToInitMap, or + * WarningType::Always, which is used for warnings that cannot be disabled and do not display a + * type. + * + * Currently there are three levels of alert a warning can have: + * - Off (does not display anything) + * - Warn (print a warning but continue processing) + * - Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs) + * + * Flag use: + * - -Wfoo enables warnings of type foo + * - -Wno-foo disables warnings of type foo + * - -Werror=foo escalates foo to behave like an error + * - -Weverything enables all warnings + * - -Werror escalates all enabled warnings to errors + * + * Errors do not have types, and will always throw an exception; they cannot be disabled. + * + * Format + * === + * Each printed warning/error contains the same three sections: + * - Preamble: automatically generated; the content varies depending on category. It will print the + * file and function that the warning is from, and information about the files being processed + * or extracted. + * - Header: begins with 'warning: ' or 'error:', should contain essential information about the + * warning/error, ends with the warning type if applicable. Printed with emphasis to make it + * stand out. Does not start with a capital letter or end with a '.' + * - Body (optional): indented, should contain further diagnostic information useful for identifying + * and fixing the warning/error. Can be a sentence with captialisation and '.' on the end. + * + * Please think of what the end user will find most useful when writing the header and body, and try + * to keep it brief without sacrificing important information! Also remember that if the user is + * only looking at stderr, they will normally have no other context. + * + * Warning vs error + * === + * The principle that we have operated on so far is + * - issue a warning if ZAPD will still be able to produce a valid, compilable C file that will + * match + * - if this cannot happen, use an error. + * but at the end of the day, it is up to the programmer's discretion what it should be possible to + * disable. + * + * Documentation + * === + * Remember that all warnings also need to be documented in the README.md. The help is generated + * automatically. + */ +#include "WarningHandler.h" + +#include +#include "Globals.h" +#include "Utils/StringHelper.h" + +typedef struct +{ + WarningType type; + WarningLevel defaultLevel; + std::string description; +} WarningInfoInit; + +typedef struct +{ + WarningLevel level; + std::string name; + std::string description; +} WarningInfo; + +/** + * Master list of all default warning types and features + * + * To add a warning type, fill in a new row of this map. Think carefully about what its default + * level should be, and try and make the description both brief and informative: it is used in the + * help message, so again, think about what the end user needs to know. + */ +// clang-format off +static const std::unordered_map warningStringToInitMap = { + {"deprecated", {WarningType::Deprecated, +#ifdef DEPRECATION_ON + WarningLevel::Warn, +#else + WarningLevel::Off, +#endif + "Deprecated features"}}, + {"unaccounted", {WarningType::Unaccounted, WarningLevel::Off, "Large blocks of unaccounted"}}, + {"missing-offsets", {WarningType::MissingOffsets, WarningLevel::Warn, "Offset attribute missing in XML tag"}}, + {"intersection", {WarningType::Intersection, WarningLevel::Warn, "Two assets intersect"}}, + {"missing-attribute", {WarningType::MissingAttribute, WarningLevel::Warn, "Required attribute missing in XML tag"}}, + {"invalid-attribute-value", {WarningType::InvalidAttributeValue, WarningLevel::Err, "Attribute declared in XML is wrong"}}, + {"unknown-attribute", {WarningType::UnknownAttribute, WarningLevel::Warn, "Unknown attribute in XML entry tag"}}, + {"invalid-xml", {WarningType::InvalidXML, WarningLevel::Err, "XML has syntax errors"}}, + {"invalid-jpeg", {WarningType::InvalidJPEG, WarningLevel::Err, "JPEG file does not conform to the game's format requirements"}}, + {"invalid-png", {WarningType::InvalidPNG, WarningLevel::Err, "Issues arising when processing PNG data"}}, + {"invalid-extracted-data", {WarningType::InvalidExtractedData, WarningLevel::Err, "Extracted data does not have correct form"}}, + {"missing-segment", {WarningType::MissingSegment, WarningLevel::Warn, "Segment not given in File tag in XML"}}, + {"hardcoded-pointer", {WarningType::HardcodedPointer, WarningLevel::Warn, "ZAPD lacks the info to make a symbol, so must output a hardcoded pointer"}}, + {"not-implemented", {WarningType::NotImplemented, WarningLevel::Warn, "ZAPD does not currently support this feature"}}, +}; + +/** + * Map constructed at runtime to contain the warning features as set by the user using -W flags. + */ +static std::unordered_map warningTypeToInfoMap; + +void WarningHandler::ConstructTypeToInfoMap() { + for (auto& entry : warningStringToInitMap) { + warningTypeToInfoMap[entry.second.type] = {entry.second.defaultLevel, entry.first, entry.second.description}; + } + warningTypeToInfoMap[WarningType::Always] = {WarningLevel::Warn, "always", "you shouldn't be reading this"}; + assert(warningTypeToInfoMap.size() == static_cast(WarningType::Max)); +} + +/** + * Initialises the main warning type map and reads flags passed to set each warning type's level. + */ +void WarningHandler::Init(int argc, char* argv[]) { + ConstructTypeToInfoMap(); + + bool werror = false; + for (int i = 1; i < argc; i++) { + // If it doesn't start with "-W" skip it. + if (argv[i][0] != '-' || argv[i][1] != 'W' || argv[i][2] == '\0') { + continue; + } + + WarningLevel warningTypeOn = WarningLevel::Warn; + size_t startingIndex = 2; + + // "-Wno-" + if (argv[i][2] == 'n' && argv[i][3] == 'o' && argv[i][4] == '-' && argv[i][5] != '\0') { + warningTypeOn = WarningLevel::Off; + startingIndex = 5; + } + + // Read starting after the "-W" or "-Wno-" + std::string_view currentArgv = &argv[i][startingIndex]; + + if (currentArgv == "error") { + werror = warningTypeOn != WarningLevel::Off; + } else if (currentArgv == "everything") { + for (auto& it: warningTypeToInfoMap) { + if (it.second.level <= WarningLevel::Warn) { + it.second.level = warningTypeOn; + } + } + } else { + // "-Werror=" / "-Wno-error=" parser + if (currentArgv.rfind("error=", 0) == 0) { + // Read starting after the "error=" part + currentArgv = &argv[i][startingIndex + 6]; + warningTypeOn = warningTypeOn != WarningLevel::Off ? WarningLevel::Err : WarningLevel::Warn; + } + + auto it = warningStringToInitMap.find(std::string(currentArgv)); + if (it != warningStringToInitMap.end()) { + warningTypeToInfoMap[it->second.type].level = warningTypeOn; + } + else { + HANDLE_WARNING(WarningType::Always, StringHelper::Sprintf("unknown warning flag '%s'", argv[i]), ""); + } + } + } + + if (werror) { + for (auto& it: warningTypeToInfoMap) { + if (it.second.level >= WarningLevel::Warn) { + it.second.level = WarningLevel::Err; + } + } + } +} + +bool WarningHandler::IsWarningEnabled(WarningType warnType) { + assert(static_cast(warnType) >= 0 && warnType < WarningType::Max); + + return warningTypeToInfoMap.at(warnType).level != WarningLevel::Off; +} + +bool WarningHandler::WasElevatedToError(WarningType warnType) { + assert(static_cast(warnType) >= 0 && warnType < WarningType::Max); + + if (!IsWarningEnabled(warnType)) { + return false; + } + + return warningTypeToInfoMap.at(warnType).level >= WarningLevel::Err; +} + +/** + * Print file/line/function info for debugging + */ +void WarningHandler::FunctionPreamble(const char* filename, int32_t line, const char* function) { + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) { + fprintf(stderr, "%s:%i: in function %s:\n", filename, line, function); + } +} + +/** + * Print the information about the file(s) being processed (XML for extraction, png etc. for building) + */ +void WarningHandler::ProcessedFilePreamble() { + if (Globals::Instance->inputPath != "") { + fprintf(stderr, "When processing file %s: ", Globals::Instance->inputPath.c_str()); + } +} + +/** + * Print information about the binary file being extracted + */ +void WarningHandler::ExtractedFilePreamble(const ZFile *parent, const ZResource* res, const uint32_t offset) { + fprintf(stderr, "in input binary file %s, ", parent->GetName().c_str()); + if (res != nullptr) { + fprintf(stderr, "resource '%s' at ", res->GetName().c_str()); + } + fprintf(stderr, "offset 0x%06X: \n\t", offset); +} + +/** + * Construct the rest of the message, after warning:/error. The message is filled in one character at a time, with indents added after newlines + */ +std::string WarningHandler::ConstructMessage(std::string message, const std::string& header, const std::string& body) { + message.reserve(message.size() + header.size() + body.size() + 10 * (sizeof(HANG_INDT) - 1)); + message += StringHelper::Sprintf(HILITE("%s"), header.c_str()); + message += "\n"; + + if (body == "") { + return message; + } + + message += HANG_INDT; + for (const char* ptr = body.c_str(); *ptr != '\0'; ptr++) { + message += *ptr; + if (*ptr == '\n') { + message += HANG_INDT; + } + } + message += "\n"; + + return message; +} + +/* Error module functions */ + +void WarningHandler::PrintErrorAndThrow(const std::string& header, const std::string& body) { + std::string errorMsg = ERR_FMT("error: "); + throw std::runtime_error(ConstructMessage(errorMsg, header, body)); +} + +/* Error types, to be used via the macros */ + +void WarningHandler::ErrorType(WarningType warnType, const std::string& header, const std::string& body) { + std::string headerMsg = header; + + for (const auto& iter: warningStringToInitMap) { + if (iter.second.type == warnType) { + headerMsg += StringHelper::Sprintf(" [%s]", iter.first.c_str()); + } + } + + PrintErrorAndThrow(headerMsg, body); +} + +void WarningHandler::Error_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + FunctionPreamble(filename, line, function); + + ErrorType(warnType, header, body); +} + +void WarningHandler::Error_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + + ErrorType(warnType, header, body); +} + +void WarningHandler::Error_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) { + assert(parent != nullptr); + + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + ExtractedFilePreamble(parent, res, offset); + + ErrorType(warnType, header, body); +} + +/* Warning module functions */ + +void WarningHandler::PrintWarningBody(const std::string& header, const std::string& body) { + std::string errorMsg = WARN_FMT("warning: "); + fprintf(stderr, "%s", ConstructMessage(errorMsg, header, body).c_str()); +} + +void WarningHandler::WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, const std::string& body) { + std::string headerMsg = header; + + for (const auto& iter: warningStringToInitMap) { + if (iter.second.type == warnType) { + headerMsg += StringHelper::Sprintf(" [-W%s]", iter.first.c_str()); + } + } + + if (WasElevatedToError(warnType)) { + PrintErrorAndThrow(headerMsg, body); + } else { + PrintWarningBody(headerMsg, body); + } +} + + +/* Warning types, to be used via the macros */ + +void WarningHandler::Warning_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + if (!IsWarningEnabled(warnType)) { + return; + } + + FunctionPreamble(filename, line, function); + + WarningTypeAndChooseEscalate(warnType, header, body); +} + +void WarningHandler::Warning_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + if (!IsWarningEnabled(warnType)) { + return; + } + + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + + WarningTypeAndChooseEscalate(warnType, header, body); +} + +void WarningHandler::Warning_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) { + assert(parent != nullptr); + + if (!IsWarningEnabled(warnType)) { + return; + } + + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + ExtractedFilePreamble(parent, res, offset); + + WarningTypeAndChooseEscalate(warnType, header, body); +} + + +/* Help-related functions */ + +#include + +/** + * Print each warning name, default status, and description using the init map + */ +void WarningHandler::PrintHelp() { + std::set sortedKeys; + WarningInfoInit warningInfo; + uint32_t columnWidth = 25; + std::string dt; + + // Sort keys through the magic of `set`, to print in alphabetical order + for (auto& it : warningStringToInitMap) { + sortedKeys.insert(it.first); + } + + printf("\nWarning types ( * means enabled by default)\n"); + for (auto& key : sortedKeys) { + warningInfo = warningStringToInitMap.at(key); + if (warningInfo.defaultLevel <= WarningLevel::Warn) { + dt = "-W"; + dt += key; + if (warningInfo.defaultLevel == WarningLevel::Warn) { + dt += " *"; + } + printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str()); + + if (dt.length() + 2 > columnWidth) { + printf("\n" HELP_DT_INDT "%-*s", columnWidth, ""); + } + printf("%s\n", warningInfo.description.c_str()); + } + } + + printf("\nDefault errors\n"); + for (auto& key : sortedKeys) { + if (warningInfo.defaultLevel > WarningLevel::Warn) { + dt = "-W"; + dt += key; + printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str()); + + if (dt.length() + 2 > columnWidth) { + printf("\n" HELP_DT_INDT "%*s", columnWidth, ""); + } + printf("%s\n", warningInfo.description.c_str()); + } + } + + printf("\n"); + printf("Other\n" HELP_DT_INDT "-Weverything will enable all existing warnings.\n" HELP_DT_INDT "-Werror will promote all warnings to errors.\n"); + + printf("\n"); + printf("Warnings can be disabled using -Wno-... instead of -W...; -Weverything will override any -Wno-... flags passed before it.\n"); +} + +/** + * Print which warnings are currently enabled + */ +void WarningHandler::PrintWarningsDebugInfo() +{ + std::string dt; + + printf("Warnings status:\n"); + for (auto& it: warningTypeToInfoMap) { + dt = it.second.name; + dt += ": "; + + printf(HELP_DT_INDT "%-25s", dt.c_str()); + switch (it.second.level) + { + case WarningLevel::Off: + printf(VT_FGCOL(LIGHTGRAY) "Off" VT_RST); + break; + case WarningLevel::Warn: + printf(VT_FGCOL(YELLOW) "Warn" VT_RST); + break; + case WarningLevel::Err: + printf(VT_FGCOL(RED) "Err" VT_RST); + break; + + } + printf("\n"); + } + printf("\n"); +} diff --git a/tools/ZAPD/ZAPD/WarningHandler.h b/tools/ZAPD/ZAPD/WarningHandler.h new file mode 100644 index 0000000000..bb0360a813 --- /dev/null +++ b/tools/ZAPD/ZAPD/WarningHandler.h @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include +#include + +#include "Utils/vt.h" +#include "ZFile.h" + +#ifdef _MSC_VER +#define __PRETTY_FUNCTION__ __FUNCSIG__ +#elif not defined(__GNUC__) +#define __PRETTY_FUNCTION__ __func__ +#endif + +// ======================================= +/* Formatting macros */ + +// TODO: move this somewhere else so it can be used by other help +#define HELP_DT_INDT " " + +/* Macros for formatting warnings/errors */ +#define VT_HILITE VT_BOLD_FGCOL(WHITE) +#define VT_WARN VT_BOLD_FGCOL(PURPLE) +#define VT_ERR VT_BOLD_FGCOL(RED) + +#define HILITE(string) (VT_HILITE string VT_RST) +#define WARN_FMT(string) (VT_WARN string VT_RST) +#define ERR_FMT(string) (VT_ERR string VT_RST) + +// Maybe make WARN_LF instead +// Currently 8 spaces +#define WARN_INDT " " +// Currently 16 spaces +#define HANG_INDT " " + +// ======================================= +/* Warning and error macros */ +// TODO: better names + +// General-purpose, plain style (only prints function,file,line in the preamble) +#define HANDLE_ERROR(warningType, header, body) \ + WarningHandler::Error_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, body) +#define HANDLE_WARNING(warningType, header, body) \ + WarningHandler::Warning_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \ + body) + +// For processing XMLs or textures/blobs (preamble contains function,file,line; processed file) +#define HANDLE_ERROR_PROCESS(warningType, header, body) \ + WarningHandler::Error_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \ + body) +#define HANDLE_WARNING_PROCESS(warningType, header, body) \ + WarningHandler::Warning_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \ + body) + +// For ZResource-related stuff (preamble contains function,file,line; processed file; extracted file +// and offset) +#define HANDLE_ERROR_RESOURCE(warningType, parent, resource, offset, header, body) \ + WarningHandler::Error_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \ + resource, offset, header, body) +#define HANDLE_WARNING_RESOURCE(warningType, parent, resource, offset, header, body) \ + WarningHandler::Warning_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \ + resource, offset, header, body) + +// ======================================= + +enum class WarningType +{ + Always, // Warnings of this type are always printed, cannot be disabled. + Deprecated, + Unaccounted, + MissingOffsets, + Intersection, + MissingAttribute, + InvalidAttributeValue, + UnknownAttribute, + InvalidXML, + InvalidJPEG, + InvalidPNG, + InvalidExtractedData, + MissingSegment, + HardcodedPointer, + NotImplemented, + Max, +}; + +enum class WarningLevel +{ + Off, + Warn, + Err, +}; + +class WarningHandler +{ +public: + static void ConstructTypeToInfoMap(); + + static void Init(int argc, char* argv[]); + + static bool IsWarningEnabled(WarningType warnType); + static bool WasElevatedToError(WarningType warnType); + + static void FunctionPreamble(const char* filename, int32_t line, const char* function); + static void ProcessedFilePreamble(); + static void ExtractedFilePreamble(const ZFile* parent, const ZResource* res, + const uint32_t offset); + static std::string ConstructMessage(std::string message, const std::string& header, + const std::string& body); + + [[noreturn]] static void PrintErrorAndThrow(const std::string& header, const std::string& body); + static void PrintWarningBody(const std::string& header, const std::string& body); + + [[noreturn]] static void ErrorType(WarningType warnType, const std::string& header, + const std::string& body); + [[noreturn]] static void Error_Plain(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + [[noreturn]] static void Error_Process(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + [[noreturn]] static void Error_Resource(const char* filename, int32_t line, + const char* function, WarningType warnType, + const ZFile* parent, const ZResource* res, + const uint32_t offset, const std::string& header, + const std::string& body); + + static void WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, + const std::string& body); + + static void Warning_Plain(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + static void Warning_Process(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + static void Warning_Resource(const char* filename, int32_t line, const char* function, + WarningType warnType, const ZFile* parent, const ZResource* res, + const uint32_t offset, const std::string& header, + const std::string& body); + + static void PrintHelp(); + static void PrintWarningsDebugInfo(); +}; diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj b/tools/ZAPD/ZAPD/ZAPD.vcxproj index c74d28cbec..431abb73b9 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj @@ -1,5 +1,6 @@ + Debug @@ -71,8 +72,8 @@ - $(SolutionDir)lib\libgfxd;$(SolutionDir)x64\Debug;$(SolutionDir)packages\libpng.1.6.28.1\build\native\lib\x64\v140\dynamic\Debug;$(LibraryPath) - $(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath) + $(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(LibraryPath) + $(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) $(IncludePath) @@ -105,13 +106,16 @@ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks stdc11 + MultiThreadedDebug true - libpng16.lib;ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies) + ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies) + false cd .. +mkdir build\ZAPD python3 ZAPD/genbuildinfo.py @@ -146,6 +150,7 @@ python3 ZAPD/genbuildinfo.py + @@ -153,19 +158,22 @@ python3 ZAPD/genbuildinfo.py - + + + + @@ -213,6 +221,7 @@ python3 ZAPD/genbuildinfo.py + @@ -237,10 +246,13 @@ python3 ZAPD/genbuildinfo.py + + + @@ -253,6 +265,7 @@ python3 ZAPD/genbuildinfo.py + @@ -294,6 +307,7 @@ python3 ZAPD/genbuildinfo.py + @@ -301,24 +315,29 @@ python3 ZAPD/genbuildinfo.py true + + - - + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters index 2d3050ed42..b8a7daaacf 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters @@ -49,6 +49,15 @@ {85600275-99fe-491d-8189-bcc3dc1a8903} + + {ba9990b0-1082-48bb-874c-6108534b5455} + + + {ce9d91b0-ba20-4296-bc2d-8630965bb392} + + + {730beb67-6d59-4849-9d9b-702c4a565fc0} + @@ -135,9 +144,6 @@ Source Files\Z64\ZRoom\Commands - - Source Files\Libraries - Source Files\Z64 @@ -258,6 +264,24 @@ Source Files\Z64 + + Source Files + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files + + + Source Files\Z64 + + + Source Files + @@ -497,11 +521,32 @@ Header Files\Z64 + + Header Files + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files + Resource Files + + any\any + + + NuGet + diff --git a/tools/ZAPD/ZAPD/ZAnimation.cpp b/tools/ZAPD/ZAPD/ZAnimation.cpp index 9242f657a8..adb0ae7c9a 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZAnimation.cpp @@ -6,6 +6,7 @@ #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Animation, ZNormalAnimation); @@ -218,11 +219,9 @@ void ZCurveAnimation::ParseXML(tinyxml2::XMLElement* reader) std::string skelOffsetXml = registeredAttributes.at("SkelOffset").value; if (skelOffsetXml == "") { - throw std::runtime_error( - StringHelper::Sprintf("ZCurveAnimation::ParseXML: Fatal error in '%s'.\n" - "\t Missing 'SkelOffset' attribute in ZCurveAnimation.\n" - "\t You need to provide the offset of the curve skeleton.", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'SkelOffset' attribute in ", + "You need to provide the offset of the curve skeleton."); } skelOffset = StringHelper::StrToL(skelOffsetXml, 0); } diff --git a/tools/ZAPD/ZAPD/ZAnimation.h b/tools/ZAPD/ZAPD/ZAnimation.h index e5b69d3ef8..2c04b4ff81 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.h +++ b/tools/ZAPD/ZAPD/ZAnimation.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "Vec3s.h" diff --git a/tools/ZAPD/ZAPD/ZArray.cpp b/tools/ZAPD/ZAPD/ZArray.cpp index b1ba3a6693..ebfb13ee74 100644 --- a/tools/ZAPD/ZAPD/ZArray.cpp +++ b/tools/ZAPD/ZAPD/ZArray.cpp @@ -4,6 +4,7 @@ #include "Globals.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Array, ZArray); @@ -25,13 +26,18 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader) ZResource::ParseXML(reader); arrayCnt = reader->IntAttribute("Count", 0); - // TODO: do a better check. - assert(arrayCnt > 0); + if (arrayCnt <= 0) + { + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Count' attribute", ""); + } tinyxml2::XMLElement* child = reader->FirstChildElement(); if (child == nullptr) - throw std::runtime_error( - StringHelper::Sprintf("Error! Array needs at least one sub-element.\n")); + { + HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, + " needs one sub-element", ""); + } childName = child->Name(); @@ -42,9 +48,10 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader) ZResource* res = nodeMap->at(childName)(parent); if (!res->DoesSupportArray()) { - throw std::runtime_error(StringHelper::Sprintf( - "Error! Resource %s does not support being wrapped in an array!\n", - childName.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "resource <%s> does not support being wrapped in an ", childName.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, errorHeader, + ""); } res->parent = parent; res->SetInnerNode(true); @@ -87,7 +94,7 @@ Declaration* ZArray::DeclareVar(const std::string& prefix, const std::string& bo std::string ZArray::GetBodySourceCode() const { - std::string output; + std::string output = ""; for (size_t i = 0; i < arrayCnt; i++) { diff --git a/tools/ZAPD/ZAPD/ZArray.h b/tools/ZAPD/ZAPD/ZArray.h index 46a04d7329..b78a8edfd8 100644 --- a/tools/ZAPD/ZAPD/ZArray.h +++ b/tools/ZAPD/ZAPD/ZArray.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/ZBackground.cpp b/tools/ZAPD/ZAPD/ZBackground.cpp index 4125f239f3..0ed1eb7471 100644 --- a/tools/ZAPD/ZAPD/ZBackground.cpp +++ b/tools/ZAPD/ZAPD/ZBackground.cpp @@ -5,6 +5,7 @@ #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Background, ZBackground); @@ -63,52 +64,46 @@ void ZBackground::CheckValidJpeg(const std::string& filepath) uint32_t jpegMarker = BitConverter::ToUInt32BE(data, 0); if (jpegMarker != JPEG_MARKER) { - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t Missing jpeg marker at the beginning of file: '%s'.\n" - "\t The game will skip this jpeg.\n", - filename.c_str()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, + StringHelper::Sprintf("missing jpeg marker at beginning of file: '%s'", + filename.c_str()), + "The game will skip this jpeg."); } if (data.at(6) != 'J' || data.at(7) != 'F' || data.at(8) != 'I' || data.at(9) != 'F' || data.at(10) != '\0') { std::string jfifIdentifier(data.begin() + 6, data.begin() + 6 + 5); - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t Missing 'JFIF' identifier. File: '%s'.\n" - "\t This image may be corrupted or not be a jpeg iamge.\n" - "\t The identifier found was '%s'.\n", - filename.c_str(), jfifIdentifier.c_str()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, "missing 'JFIF' identifier", + StringHelper::Sprintf( + "This image may be corrupted, or not a jpeg. The identifier found was: '%s'", + jfifIdentifier.c_str())); } uint8_t majorVersion = data.at(11); uint8_t minorVersion = data.at(12); if (majorVersion != 0x01 || minorVersion != 0x01) { - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t Wrong JFIF version '%i.%02i'. File: '%s'.\n" - "\t The expected version is '1.01'. The game may not be able to decode this image " - "properly.\n", - majorVersion, minorVersion, filename.c_str()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, + StringHelper::Sprintf("wrong JFIF version '%i.%02i'", majorVersion, minorVersion), + "The expected version is '1.01'. The game may be unable to decode this image " + "correctly."); } if (BitConverter::ToUInt16BE(data, 20) != MARKER_DQT) { // This may happen when creating a custom image with Exif, XMP, thumbnail, progressive, etc. // enabled. - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t There seems to be extra data before the image data in file: '%s'.\n" - "\t The game may not be able to decode this image properly.\n", - filename.c_str()); + HANDLE_WARNING_PROCESS(WarningType::InvalidJPEG, + "there seems to be extra data before the image data in this file", + "The game may not be able to decode this image correctly."); } if (data.size() > GetRawDataSize()) { - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t The image is bigger than the screen buffer. File: '%s'.\n" - "\t Image size: %zu bytes.\n" - "\t Screen buffer size: %zu bytes.\n", - filename.c_str(), data.size(), GetRawDataSize()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, "the image is bigger than the screen buffer", + StringHelper::Sprintf("Image size: %zu bytes\nScreen buffer size: %zu bytes", + data.size(), GetRawDataSize())); } } @@ -138,6 +133,7 @@ Declaration* ZBackground::DeclareVar(const std::string& prefix, Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, 0); decl->arrayItemCntStr = "SCREEN_WIDTH * SCREEN_HEIGHT / 4"; + decl->forceArrayCnt = true; decl->staticConf = staticConf; return decl; } diff --git a/tools/ZAPD/ZAPD/ZBlob.cpp b/tools/ZAPD/ZAPD/ZBlob.cpp index c1f0788206..6812bfaee9 100644 --- a/tools/ZAPD/ZAPD/ZBlob.cpp +++ b/tools/ZAPD/ZAPD/ZBlob.cpp @@ -83,11 +83,6 @@ std::string ZBlob::GetBodySourceCode() const return sourceOutput; } -std::string ZBlob::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) -{ - return StringHelper::Sprintf("extern u8 %s[];\n", name.c_str()); -} - void ZBlob::Save(const fs::path& outFolder) { File::WriteAllBytes((outFolder / (name + ".bin")).string(), blobData); diff --git a/tools/ZAPD/ZAPD/ZBlob.h b/tools/ZAPD/ZAPD/ZBlob.h index 86623b5119..d7a7feff12 100644 --- a/tools/ZAPD/ZAPD/ZBlob.h +++ b/tools/ZAPD/ZAPD/ZBlob.h @@ -16,7 +16,6 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputHeader(const std::string& prefix) override; void Save(const fs::path& outFolder) override; bool IsExternalResource() const override; diff --git a/tools/ZAPD/ZAPD/ZCollision.cpp b/tools/ZAPD/ZAPD/ZCollision.cpp index f9c0bf7d62..1dfa46b1dd 100644 --- a/tools/ZAPD/ZAPD/ZCollision.cpp +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -88,7 +88,7 @@ void ZCollisionHeader::ParseRawData() void ZCollisionHeader::DeclareReferences(const std::string& prefix) { - std::string declaration; + std::string declaration = ""; std::string auxName = name; if (name == "") @@ -174,7 +174,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) std::string ZCollisionHeader::GetBodySourceCode() const { - std::string declaration; + std::string declaration = ""; declaration += "\n"; diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp index 237481079f..ba8fe89638 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.cpp +++ b/tools/ZAPD/ZAPD/ZCutscene.cpp @@ -2,6 +2,7 @@ #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZResource.h" REGISTER_ZFILENODE(Cutscene, ZCutscene); @@ -87,7 +88,7 @@ CutsceneCommandSceneTransFX::~CutsceneCommandSceneTransFX() std::string ZCutscene::GetBodySourceCode() const { - std::string output; + std::string output = ""; uint32_t curPtr = 0; output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame); @@ -225,8 +226,9 @@ void ZCutscene::ParseRawData() cmd = new CutsceneCommandEnd(rawData, currentPtr); break; case CutsceneCommands::Error: - fprintf(stderr, "Cutscene command error %d %s %d\n", (int32_t)cmdID, __FILE__, - __LINE__); + HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, + StringHelper::Sprintf("cutscene command error %d", cmdID), + ""); break; } @@ -404,7 +406,9 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) return CutsceneCommands::Unknown; } - fprintf(stderr, "WARNING: Could not identify cutscene command ID 0x%04X\n", id); + HANDLE_WARNING_RESOURCE( + WarningType::NotImplemented, parent, this, rawDataIndex, + StringHelper::Sprintf("could not identify cutscene command. ID 0x%04X", id), ""); return CutsceneCommands::Error; } diff --git a/tools/ZAPD/ZAPD/ZCutscene.h b/tools/ZAPD/ZAPD/ZCutscene.h index cbb6a78b02..8e901e3075 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.h +++ b/tools/ZAPD/ZAPD/ZCutscene.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZFile.h" diff --git a/tools/ZAPD/ZAPD/ZCutsceneMM.h b/tools/ZAPD/ZAPD/ZCutsceneMM.h index 41b7de37f3..44b108d6c1 100644 --- a/tools/ZAPD/ZAPD/ZCutsceneMM.h +++ b/tools/ZAPD/ZAPD/ZCutsceneMM.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZCutscene.h" diff --git a/tools/ZAPD/ZAPD/ZDisplayList.cpp b/tools/ZAPD/ZAPD/ZDisplayList.cpp index 63c5684228..bdb7374fe1 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.cpp +++ b/tools/ZAPD/ZAPD/ZDisplayList.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "Globals.h" @@ -11,6 +12,7 @@ #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "gfxd.h" REGISTER_ZFILENODE(DList, ZDisplayList); @@ -105,7 +107,7 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, switch (opcode) { case F3DZEXOpcode::G_NOOP: - sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsDPNoOpTag(0x%08" PRIX64 "),", data & 0xFFFFFFFF); break; case F3DZEXOpcode::G_DL: Opcode_G_DL(data, prefix, line); @@ -220,7 +222,7 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, break; case F3DZEXOpcode::G_POPMTX: { - sprintf(line, "gsSPPopMatrix(%li),", data); + sprintf(line, "gsSPPopMatrix(%" PRIi64 "),", data); } break; case F3DZEXOpcode::G_LOADTLUT: @@ -297,7 +299,7 @@ void ZDisplayList::ParseF3DEX(F3DEXOpcode opcode, uint64_t data, const std::stri switch (opcode) { case F3DEXOpcode::G_NOOP: - sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsDPNoOpTag(0x%08" PRIX64 "),", data & 0xFFFFFFFF); break; case F3DEXOpcode::G_VTX: Opcode_G_VTX(data, line); @@ -445,11 +447,12 @@ int32_t ZDisplayList::GetDListLength(const std::vector& rawData, uint32 { if (ptr >= rawDataSize) { - throw std::runtime_error(StringHelper::Sprintf( - "%s: Fatal error.\n" - "\t End of file found when trying to find the end of the " - "DisplayList at offset: '0x%X'.\n", - "Raw data size: 0x%zX.\n", __PRETTY_FUNCTION__, rawDataIndex, rawDataSize)); + std::string errorHeader = + StringHelper::Sprintf("reached end of file when trying to find the end of the " + "DisplayList starting at offset 0x%X", + rawDataIndex); + std::string errorBody = StringHelper::Sprintf("Raw data size: 0x%zX.", rawDataSize); + HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, errorBody); } uint8_t opcode = rawData.at(ptr); @@ -686,20 +689,20 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l if (pp != 0) { if (!Globals::Instance->HasSegment(segNum)) - sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); else if (dListDecl != nullptr) sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str()); else - sprintf(line, "gsSPBranchList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data)); + sprintf(line, "gsSPBranchList(%sDlist0x%06" PRIX64 "),", prefix.c_str(), GETSEGOFFSET(data)); } else { if (!Globals::Instance->HasSegment(segNum)) - sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); else if (dListDecl != nullptr) sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str()); else - sprintf(line, "gsSPDisplayList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data)); + sprintf(line, "gsSPDisplayList(%sDlist0x%06" PRIX64 "),", prefix.c_str(), GETSEGOFFSET(data)); } // if (segNum == 8 || segNum == 9 || segNum == 10 || segNum == 11 || segNum == 12 || segNum == @@ -707,9 +710,9 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l if (!Globals::Instance->HasSegment(segNum)) { if (pp != 0) - sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); else - sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); } else { @@ -941,7 +944,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress); else { - sprintf(texStr, "0x%08lX", data & 0xFFFFFFFF); + sprintf(texStr, "0x%08" PRIX64, data & 0xFFFFFFFF); } sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1, @@ -1522,11 +1525,6 @@ void ZDisplayList::Opcode_G_ENDDL([[maybe_unused]] const std::string& prefix, ch TextureGenCheck(); } -std::string ZDisplayList::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) -{ - return ""; -} - static int32_t GfxdCallback_FormatSingleEntry() { ZDisplayList* self = static_cast(gfxd_udata_get()); @@ -1737,7 +1735,7 @@ static int32_t GfxdCallback_Matrix(uint32_t seg) return 1; } -std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) +void ZDisplayList::DeclareReferences(const std::string& prefix) { std::string sourceOutput; @@ -1750,7 +1748,7 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) if (vertices.size() > 0) { std::vector>> verticesSorted(vertices.begin(), - vertices.end()); + vertices.end()); for (size_t i = 0; i < verticesSorted.size() - 1; i++) { @@ -1775,15 +1773,13 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) // Generate Vertex Declarations for (auto& item : vertices) { - std::string declaration; + std::string declaration = ""; offset_t curAddr = item.first; auto& firstVtx = item.second.at(0); for (auto vtx : item.second) - { declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str()); - } Declaration* decl = parent->AddDeclarationArray( curAddr, firstVtx.GetDeclarationAlignment(), @@ -1800,7 +1796,7 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) if (vertices.size() > 0) { std::vector>> verticesSorted(vertices.begin(), - vertices.end()); + vertices.end()); for (size_t i = 0; i < verticesSorted.size() - 1; i++) { @@ -1863,11 +1859,6 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) } } } - - if (parent != nullptr) - return ""; - - return sourceOutput; } std::string ZDisplayList::ProcessLegacy(const std::string& prefix) @@ -1899,10 +1890,10 @@ std::string ZDisplayList::ProcessLegacy(const std::string& prefix) } auto end = std::chrono::steady_clock::now(); - auto diff = std::chrono::duration_cast(end - start).count(); + int64_t diff = std::chrono::duration_cast(end - start).count(); if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG && diff > 5) - printf("F3DOP: 0x%02X, TIME: %lims\n", opcode, diff); + printf("F3DOP: 0x%02X, TIME: %" PRIi64 "ms\n", opcode, diff); sourceOutput += line; @@ -1983,7 +1974,7 @@ bool ZDisplayList::TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t } else { - // Try to find a non-external file (ie, one we are actually extracting) + // Try to find a non-external file (i.e., one we are actually extracting) // which has the same segment number we are looking for. for (auto& otherFile : Globals::Instance->cfg.segmentRefFiles[segmentNumber]) { diff --git a/tools/ZAPD/ZAPD/ZDisplayList.h b/tools/ZAPD/ZAPD/ZDisplayList.h index d538666750..96808315dc 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.h +++ b/tools/ZAPD/ZAPD/ZDisplayList.h @@ -363,8 +363,7 @@ public: size_t GetRawDataSize() const override; DeclarationAlignment GetDeclarationAlignment() const override; - std::string GetSourceOutputHeader(const std::string& prefix) override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void DeclareReferences(const std::string& prefix) override; std::string ProcessLegacy(const std::string& prefix); std::string ProcessGfxDis(const std::string& prefix); diff --git a/tools/ZAPD/ZAPD/ZFile.cpp b/tools/ZAPD/ZAPD/ZFile.cpp index 7cbfeba886..77387fc72c 100644 --- a/tools/ZAPD/ZAPD/ZFile.cpp +++ b/tools/ZAPD/ZAPD/ZFile.cpp @@ -13,6 +13,7 @@ #include "Utils/MemoryStream.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZAnimation.h" #include "ZArray.h" #include "ZBackground.h" @@ -73,19 +74,13 @@ ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBas ZFile::~ZFile() { for (ZResource* res : resources) - { delete res; - } for (auto d : declarations) - { delete d.second; - } for (auto sym : symbolResources) - { delete sym.second; - } } void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) @@ -114,8 +109,11 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) else if (std::string_view(gameStr) == "OOT") Globals::Instance->game = ZGame::OOT_RETAIL; else - throw std::runtime_error( - StringHelper::Sprintf("Error: Game type %s not supported.", gameStr)); + { + std::string errorHeader = + StringHelper::Sprintf("'Game' type '%s' is not supported.", gameStr); + HANDLE_ERROR_PROCESS(WarningType::InvalidAttributeValue, errorHeader, ""); + } } if (reader->Attribute("BaseAddress") != nullptr) @@ -128,16 +126,22 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) rangeEnd = StringHelper::StrToL(reader->Attribute("RangeEnd"), 16); if (rangeStart > rangeEnd) - throw std::runtime_error("Error: RangeStart must be before than RangeEnd."); + HANDLE_ERROR_PROCESS( + WarningType::Always, + StringHelper::Sprintf("'RangeStart' 0x%06X must be before 'RangeEnd' 0x%06X", + rangeStart, rangeEnd), + ""); const char* segmentXml = reader->Attribute("Segment"); if (segmentXml != nullptr) { if (!StringHelper::HasOnlyDigits(segmentXml)) { - throw std::runtime_error(StringHelper::Sprintf( - "error: Invalid segment value '%s': must be a decimal between 0 and 15 inclusive", - segmentXml)); + HANDLE_ERROR_PROCESS(WarningType::Always, + StringHelper::Sprintf("error: Invalid segment value '%s': must be " + "a decimal between 0 and 15 inclusive", + segmentXml), + ""); } segment = StringHelper::StrToL(segmentXml, 10); @@ -146,16 +150,19 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (segment == 128) { #ifdef DEPRECATION_ON - fprintf(stderr, "warning: segment 128 is deprecated.\n\tRemove " - "'Segment=\"128\"' from the xml to use virtual addresses\n"); + HANDLE_WARNING_PROCESS( + WarningType::Always, "warning: segment 128 is deprecated.", + "Remove 'Segment=\"128\"' from the xml to use virtual addresses\n"); #endif } else { - throw std::runtime_error( + HANDLE_ERROR_PROCESS( + WarningType::Always, StringHelper::Sprintf("error: invalid segment value '%s': must be a decimal " "number between 0 and 15 inclusive", - segmentXml)); + segmentXml), + ""); } } } @@ -176,18 +183,16 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile) { if (!File::Exists((basePath / name).string())) - throw std::runtime_error( - StringHelper::Sprintf("Error! File %s does not exist.", (basePath / name).c_str())); + { + std::string errorHeader = StringHelper::Sprintf("binary file '%s' does not exist.", + (basePath / name).c_str()); + HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, ""); + } rawData = File::ReadAllBytes((basePath / name).string()); - /* - * TODO: In OoT repo ovl_Boss_Sst has a wrong RangeEnd (0xAD40 instead of 0xAD70), - * so uncommenting the following produces wrong behavior. - * If somebody fixes that in OoT repo, uncomment this. I'm too tired of fixing XMLs. - */ - // if (reader->Attribute("RangeEnd") == nullptr) - // rangeEnd = rawData.size(); + if (reader->Attribute("RangeEnd") == nullptr) + rangeEnd = rawData.size(); } std::unordered_set nameSet; @@ -211,20 +216,17 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (offsetSet.find(offsetXml) != offsetSet.end()) { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Offset' attribute: %s \n", - name.c_str(), offsetXml)); + std::string errorHeader = + StringHelper::Sprintf("repeated 'Offset' attribute: %s", offsetXml); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } offsetSet.insert(offsetXml); } - else if (Globals::Instance->warnNoOffset) + else { - fprintf(stderr, "Warning No offset specified for: %s", nameXml); - } - else if (Globals::Instance->errorNoOffset) - { - throw std::runtime_error( - StringHelper::Sprintf("Error no offset specified for %s", nameXml)); + HANDLE_WARNING_RESOURCE(WarningType::MissingOffsets, this, nullptr, rawDataIndex, + StringHelper::Sprintf("no offset specified for %s.", nameXml), + ""); } if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) @@ -234,9 +236,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) { if (outNameSet.find(outNameXml) != outNameSet.end()) { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Repeated 'OutName' attribute: %s \n", - name.c_str(), outNameXml)); + std::string errorHeader = + StringHelper::Sprintf("repeated 'OutName' attribute: %s", outNameXml); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } outNameSet.insert(outNameXml); } @@ -244,9 +246,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) { if (nameSet.find(nameXml) != nameSet.end()) { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Name' attribute: %s \n", - name.c_str(), nameXml)); + std::string errorHeader = + StringHelper::Sprintf("repeated 'Name' attribute: %s", nameXml); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } nameSet.insert(nameXml); } @@ -279,16 +281,14 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) } else if (std::string_view(child->Name()) == "File") { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Can't declare a File inside a File.\n", - name.c_str())); + std::string errorHeader = "Can't declare a inside a "; + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } else { - throw std::runtime_error( - StringHelper::Sprintf("ZFile::ParseXML: Error in '%s'.\n\t Unknown element found " - "inside a File element: '%s'.\n", - name.c_str(), nodeName.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "Unknown element found inside a element: %s", nodeName.c_str()); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } } } @@ -307,7 +307,7 @@ void ZFile::BuildSourceFile() return; if (!Directory::Exists(outputPath)) - Directory::CreateDirectory(outputPath); + Directory::CreateDirectory(outputPath.string()); GenerateSourceFiles(); } @@ -317,6 +317,11 @@ std::string ZFile::GetName() const return name; } +std::string ZFile::GetOutName() const +{ + return outName.string(); +} + ZFileMode ZFile::GetMode() const { return mode; @@ -338,10 +343,10 @@ void ZFile::ExtractResources() return; if (!Directory::Exists(outputPath)) - Directory::CreateDirectory(outputPath); + Directory::CreateDirectory(outputPath.string()); if (!Directory::Exists(GetSourceOutputFolderPath())) - Directory::CreateDirectory(GetSourceOutputFolderPath()); + Directory::CreateDirectory(GetSourceOutputFolderPath().string()); for (size_t i = 0; i < resources.size(); i++) resources[i]->ParseRawDataLate(); @@ -351,8 +356,8 @@ void ZFile::ExtractResources() if (Globals::Instance->genSourceFile) GenerateSourceFiles(); - MemoryStream* memStream = new MemoryStream(); - BinaryWriter writer = BinaryWriter(memStream); + auto memStreamFile = std::shared_ptr(new MemoryStream()); + BinaryWriter writerFile = BinaryWriter(memStreamFile); ExporterSet* exporterSet = Globals::Instance->GetExporterSet(); @@ -361,6 +366,9 @@ void ZFile::ExtractResources() for (ZResource* res : resources) { + auto memStreamRes = std::shared_ptr(new MemoryStream()); + BinaryWriter writerRes = BinaryWriter(memStreamRes); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("Saving resource %s\n", res->GetName().c_str()); @@ -369,18 +377,24 @@ void ZFile::ExtractResources() // Check if we have an exporter "registered" for this resource type ZResourceExporter* exporter = Globals::Instance->GetExporter(res->GetResourceType()); if (exporter != nullptr) - exporter->Save(res, Globals::Instance->outputPath.string(), &writer); + { + //exporter->Save(res, Globals::Instance->outputPath.string(), &writerFile); + exporter->Save(res, Globals::Instance->outputPath.string(), &writerRes); + } + + if (exporterSet != nullptr && exporterSet->resSaveFunc != nullptr) + exporterSet->resSaveFunc(res, writerRes); } - if (memStream->GetLength() > 0) + if (memStreamFile->GetLength() > 0) { File::WriteAllBytes(StringHelper::Sprintf("%s%s.bin", Globals::Instance->outputPath.string().c_str(), GetName().c_str()), - memStream->ToVector()); + memStreamFile->ToVector()); } - writer.Close(); + writerFile.Close(); if (exporterSet != nullptr && exporterSet->endFileFunc != nullptr) exporterSet->endFileFunc(this); @@ -1070,8 +1084,6 @@ std::string ZFile::ProcessDeclarations() } } - output += "\n"; - return output; } @@ -1234,11 +1246,12 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, { Declaration* currentDecl = declarations.at(currentAddress); - fprintf(stderr, - "WARNING: Intersection detected from 0x%06X:0x%06X (%s), conflicts with " - "0x%06X (%s)\n", - lastAddr, lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress, - currentDecl->varName.c_str()); + std::string intersectionInfo = StringHelper::Sprintf( + "Resource from 0x%06X:0x%06X (%s) conflicts with 0x%06X (%s).", lastAddr, + lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress, + currentDecl->varName.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::Intersection, this, nullptr, currentAddress, + "intersection detected", intersectionInfo); } } @@ -1309,25 +1322,17 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, diff, src); decl->isUnaccounted = true; - if (Globals::Instance->warnUnaccounted) + if (nonZeroUnaccounted) { - if (nonZeroUnaccounted) - { - fprintf(stderr, - "Warning in file: %s (%s)\n" - "\t A non-zero unaccounted block was found at offset '0x%06X'.\n" - "\t Block size: '0x%X'.\n", - xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); - } - else if (diff >= 16) - { - fprintf(stderr, - "Warning in file: %s (%s)\n" - "\t A big (size>=0x10) zero-only unaccounted block was found " - "at offset '0x%06X'.\n" - "\t Block size: '0x%X'.\n", - xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); - } + HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress, + "a non-zero unaccounted block was found", + StringHelper::Sprintf("Block size: '0x%X'", diff)); + } + else if (diff >= 16) + { + HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress, + "a big (size>=0x10) zero-only unaccounted block was found", + StringHelper::Sprintf("Block size: '0x%X'", diff)); } } } diff --git a/tools/ZAPD/ZAPD/ZFile.h b/tools/ZAPD/ZAPD/ZFile.h index 9de6950e4a..7918d5f595 100644 --- a/tools/ZAPD/ZAPD/ZFile.h +++ b/tools/ZAPD/ZAPD/ZFile.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -46,6 +45,7 @@ public: ~ZFile(); std::string GetName() const; + std::string GetOutName() const; ZFileMode GetMode() const; const fs::path& GetXmlFilePath() const; const std::vector& GetRawData() const; diff --git a/tools/ZAPD/ZAPD/ZLimb.cpp b/tools/ZAPD/ZAPD/ZLimb.cpp index 77c66871fe..a47615d6c6 100644 --- a/tools/ZAPD/ZAPD/ZLimb.cpp +++ b/tools/ZAPD/ZAPD/ZLimb.cpp @@ -4,7 +4,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" -#include "Utils/StringHelper.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Limb, ZLimb); @@ -37,17 +37,15 @@ void ZLimb::ParseXML(tinyxml2::XMLElement* reader) if (limbType == "") { - throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n" - "\t Missing 'LimbType' attribute in xml.\n", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'LimbType' attribute in ", ""); } type = GetTypeByAttributeName(limbType); if (type == ZLimbType::Invalid) { - throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n" - "\t Invalid 'LimbType' found: '%s'.\n", - name.c_str(), limbType.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'LimbType' attribute", ""); } } @@ -109,8 +107,12 @@ void ZLimb::ParseRawData() } break; - default: - throw std::runtime_error("Invalid ZLimb type"); + case ZLimbType::Curve: + case ZLimbType::Legacy: + break; + + case ZLimbType::Invalid: + assert(!"whoops"); break; } } diff --git a/tools/ZAPD/ZAPD/ZPath.cpp b/tools/ZAPD/ZAPD/ZPath.cpp index 4a95c5b91e..e19513db34 100644 --- a/tools/ZAPD/ZAPD/ZPath.cpp +++ b/tools/ZAPD/ZAPD/ZPath.cpp @@ -3,6 +3,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Path, ZPath); @@ -20,10 +21,12 @@ void ZPath::ParseXML(tinyxml2::XMLElement* reader) numPaths = StringHelper::StrToL(registeredAttributes.at("NumPaths").value); if (numPaths < 1) - throw std::runtime_error( - StringHelper::Sprintf("ZPath::ParseXML: Fatal error in '%s'.\n" - "\t Invalid value for attribute 'NumPaths': '%i'\n", - name.c_str(), numPaths)); + { + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numPaths), + "Should be at least '1'"); + } } void ZPath::ParseRawData() @@ -144,7 +147,7 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) if (addressFound) return; - std::string declaration; + std::string declaration = ""; size_t index = 0; for (const auto& point : points) diff --git a/tools/ZAPD/ZAPD/ZResource.cpp b/tools/ZAPD/ZAPD/ZResource.cpp index cb811f4c3b..2dfe6d5eaa 100644 --- a/tools/ZAPD/ZAPD/ZResource.cpp +++ b/tools/ZAPD/ZAPD/ZResource.cpp @@ -4,6 +4,7 @@ #include #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" ZResource::ZResource(ZFile* nParent) @@ -85,29 +86,33 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) } if (!attrDeclared) - fprintf(stderr, - "ZResource::ParseXML: Warning while parsing '%s'.\n" - "\t Unexpected '%s' attribute in resource '%s'.\n", - parent->GetName().c_str(), attrName.c_str(), reader->Name()); + { + HANDLE_WARNING_RESOURCE( + WarningType::UnknownAttribute, parent, this, rawDataIndex, + StringHelper::Sprintf("unexpected '%s' attribute in resource <%s>", + attrName.c_str(), reader->Name()), + ""); + } attrs = attrs->Next(); } if (!canHaveInner && !reader->NoChildren()) { - throw std::runtime_error( - StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n" - "\t Resource '%s' with inner element/child detected.\n", - name.c_str(), reader->Name())); + std::string errorHeader = StringHelper::Sprintf( + "resource '%s' with inner element/child detected", reader->Name()); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } for (const auto& attr : registeredAttributes) { if (attr.second.isRequired && attr.second.value == "") - throw std::runtime_error(StringHelper::Sprintf( - "ZResource::ParseXML: Fatal error while parsing '%s'.\n" - "\t Missing required attribute '%s' in resource '%s'.\n" - "\t Aborting...", - parent->GetName().c_str(), attr.first.c_str(), reader->Name())); + { + std::string headerMsg = + StringHelper::Sprintf("missing required attribute '%s' in resource <%s>", + attr.first.c_str(), reader->Name()); + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + headerMsg, ""); + } } name = registeredAttributes.at("Name").value; @@ -118,10 +123,8 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) { if (!std::regex_match(name, r)) { - throw std::domain_error( - StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n" - "\t Resource with invalid 'Name' attribute.\n", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, + rawDataIndex, "invalid value found for 'Name' attribute", ""); } } @@ -146,7 +149,9 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) } else { - throw std::runtime_error("Invalid value for 'Static' attribute."); + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("invalid value '%s' for 'Static' attribute", staticConf), ""); } declaredInXml = true; @@ -253,18 +258,21 @@ std::string ZResource::GetDefaultName(const std::string& prefix) const rawDataIndex); } -std::string ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +void ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { std::string bodyStr = GetBodySourceCode(); - Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr || decl->isPlaceholder) - decl = DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - decl->staticConf = staticConf; + if (bodyStr != "ERROR") + { + Declaration* decl = parent->GetDeclaration(rawDataIndex); - return ""; + if (decl == nullptr || decl->isPlaceholder) + decl = DeclareVar(prefix, bodyStr); + else + decl->text = bodyStr; + + decl->staticConf = staticConf; + } } std::string ZResource::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) @@ -312,13 +320,13 @@ offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) uint32_t parentBaseOffset = GETSEGOFFSET(parentBaseAddress); if (parentBaseOffset > currentPtr) { - throw std::runtime_error( - StringHelper::Sprintf("\nSeg2Filespace: Segmented address is smaller than " - "'BaseAddress'. Maybe your 'BaseAddress' is wrong?\n" - "\t SegmentedAddress: 0x%08X\n" - "\t BaseAddress: 0x%08X\n", - segmentedAddress, parentBaseAddress)); + HANDLE_ERROR(WarningType::Always, + StringHelper::Sprintf( + "resource address 0x%08X is smaller than 'BaseAddress' 0x%08X", + segmentedAddress, parentBaseAddress), + "Maybe your 'BaseAddress' is wrong?"); } + currentPtr -= parentBaseOffset; } diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h index ff35786fac..4dad398955 100644 --- a/tools/ZAPD/ZAPD/ZResource.h +++ b/tools/ZAPD/ZAPD/ZResource.h @@ -1,16 +1,15 @@ #pragma once -#include +#include #include #include -#include #include #include #include "Declaration.h" +#include "Utils/BinaryWriter.h" +#include "Utils/Directory.h" #include "tinyxml2.h" -#include - #define SEGMENT_SCENE 2 #define SEGMENT_ROOM 3 #define SEGMENT_KEEP 4 @@ -113,7 +112,7 @@ public: */ [[nodiscard]] virtual std::string GetDefaultName(const std::string& prefix) const; - virtual std::string GetSourceOutputCode(const std::string& prefix); + virtual void GetSourceOutputCode(const std::string& prefix); virtual std::string GetSourceOutputHeader(const std::string& prefix); virtual void CalcHash(); /** diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp index d1c8abd5c5..69668c49c1 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp @@ -1,8 +1,10 @@ #include "SetMesh.h" -#include -#include + +#include "Globals.h" #include "Utils/BitConverter.h" +#include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZBackground.h" #include "ZFile.h" #include "ZRoom/ZRoom.h" @@ -34,9 +36,8 @@ void SetMesh::ParseRawData() break; default: - throw std::runtime_error(StringHelper::Sprintf("Error in SetMesh::ParseRawData\n" - "\t Unknown meshHeaderType: %i\n", - meshHeaderType)); + HANDLE_ERROR(WarningType::InvalidExtractedData, + StringHelper::Sprintf("unknown meshHeaderType: %i", meshHeaderType), ""); } polyType->ParseRawData(); @@ -53,11 +54,9 @@ void SetMesh::DeclareReferences(const std::string& prefix) void GenDListDeclarations(ZRoom* zRoom, ZFile* parent, ZDisplayList* dList) { if (dList == nullptr) - { return; - } - std::string sourceOutput = dList->GetSourceOutputCode(zRoom->GetName()); + dList->DeclareReferences(zRoom->GetName()); for (ZDisplayList* otherDList : dList->otherDLists) GenDListDeclarations(zRoom, parent, otherDList); @@ -143,21 +142,17 @@ std::string PolygonDlist::GetBodySourceCode() const return bodyStr; } -std::string PolygonDlist::GetSourceOutputCode(const std::string& prefix) +void PolygonDlist::GetSourceOutputCode(const std::string& prefix) { std::string bodyStr = StringHelper::Sprintf("\n\t%s\n", GetBodySourceCode().c_str()); Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr) - { - DeclareVar(prefix, bodyStr); - } - else - { - decl->text = bodyStr; - } - return ""; + if (decl == nullptr) + DeclareVar(prefix, bodyStr); + else + decl->text = bodyStr; + } std::string PolygonDlist::GetSourceTypeName() const @@ -472,8 +467,8 @@ void PolygonType1::DeclareReferences(const std::string& prefix) break; default: - throw std::runtime_error(StringHelper::Sprintf( - "Error in PolygonType1::PolygonType1\n\t Unknown format: %i\n", format)); + HANDLE_ERROR(WarningType::InvalidExtractedData, + StringHelper::Sprintf("unknown format: %i", format), ""); break; } } @@ -582,9 +577,11 @@ void PolygonType2::DeclareReferences(const std::string& prefix) polyDListName = StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), polyDlistType.c_str(), GETSEGOFFSET(start)); - parent->AddDeclarationArray(GETSEGOFFSET(start), DeclarationAlignment::Align4, - polyDLists.size() * polyDLists.at(0).GetRawDataSize(), - polyDlistType, polyDListName, polyDLists.size(), declaration); + Declaration* decl = parent->AddDeclarationArray( + GETSEGOFFSET(start), DeclarationAlignment::Align4, + polyDLists.size() * polyDLists.at(0).GetRawDataSize(), polyDlistType, polyDListName, + polyDLists.size(), declaration); + decl->forceArrayCnt = true; } parent->AddDeclaration(GETSEGOFFSET(end), DeclarationAlignment::Align4, 4, "s32", diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h index 566711a9a7..9d9037417b 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h @@ -28,7 +28,7 @@ public: std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp index 43c3968221..7027fa1f98 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp @@ -115,11 +115,9 @@ std::string RomFile::GetBodySourceCode() const return declaration; } -std::string RomFile::GetSourceOutputCode(const std::string& prefix) +void RomFile::GetSourceOutputCode(const std::string& prefix) { DeclareVar(prefix, GetBodySourceCode()); - - return ""; } std::string RomFile::GetSourceTypeName() const diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h index 4fb2ced176..2ae48b68df 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h @@ -24,7 +24,7 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; virtual ZResourceType GetResourceType() const override; diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp index edc0cad029..d47a2e75cb 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp @@ -2,7 +2,9 @@ #include #include #include +#include #include + #include "Commands/EndMarker.h" #include "Commands/SetActorCutsceneList.h" #include "Commands/SetActorList.h" @@ -40,6 +42,7 @@ #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZBlob.h" #include "ZCutscene.h" #include "ZFile.h" @@ -123,10 +126,12 @@ void ZRoom::ParseXML(tinyxml2::XMLElement* reader) { hackMode = std::string(reader->Attribute("HackMode")); if (hackMode != "syotes_room") - throw std::runtime_error( - StringHelper::Sprintf("ZRoom::ParseXML: Fatal error in '%s'.\n" - "\t Invalid value for attribute 'HackMode': '%s'\n", - name.c_str(), hackMode.c_str())); + { + std::string headerError = StringHelper::Sprintf( + "invalid value found for 'HackMode' attribute: '%s'", hackMode.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + headerError, ""); + } } } @@ -256,9 +261,9 @@ void ZRoom::ParseRawData() if (Globals::Instance->profile) { auto end = std::chrono::steady_clock::now(); - auto diff = std::chrono::duration_cast(end - start).count(); + int64_t diff = std::chrono::duration_cast(end - start).count(); if (diff > 50) - printf("OP: %s, TIME: %lims\n", cmd->GetCommandCName().c_str(), diff); + printf("OP: %s, TIME: %" PRIi64 "ms\n", cmd->GetCommandCName().c_str(), diff); } cmd->cmdIndex = currentIndex; @@ -392,14 +397,10 @@ size_t ZRoom::GetCommandSizeFromNeighbor(ZRoomCommand* cmd) return 0; } -std::string ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +void ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { - if (hackMode == "syotes_room") - return ""; - - DeclareVar(prefix, GetBodySourceCode()); - - return ""; + if (hackMode != "syotes_room") + DeclareVar(prefix, GetBodySourceCode()); } size_t ZRoom::GetRawDataSize() const diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h index 0993a9d302..e837ec70ac 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h @@ -34,7 +34,7 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void GetSourceOutputCode(const std::string& prefix) override; std::string GetDefaultName(const std::string& prefix) const override; size_t GetDeclarationSizeFromNeighbor(uint32_t declarationAddress); diff --git a/tools/ZAPD/ZAPD/ZScalar.cpp b/tools/ZAPD/ZAPD/ZScalar.cpp index 062fb0e079..7e4be4d57f 100644 --- a/tools/ZAPD/ZAPD/ZScalar.cpp +++ b/tools/ZAPD/ZAPD/ZScalar.cpp @@ -4,6 +4,7 @@ #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Scalar, ZScalar); @@ -207,8 +208,8 @@ void ZScalar::ParseRawData() scalarData.f64 = BitConverter::ToDoubleBE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_NONE: - fprintf(stderr, "Warning in ZScalar: Invalid type. %d %s %d\n", (int32_t)scalarType, - __FILE__, __LINE__); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Type' attribute", "Defaulting to ''"); break; } } diff --git a/tools/ZAPD/ZAPD/ZScalar.h b/tools/ZAPD/ZAPD/ZScalar.h index d269995cca..8f98f261d7 100644 --- a/tools/ZAPD/ZAPD/ZScalar.h +++ b/tools/ZAPD/ZAPD/ZScalar.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/ZSkeleton.cpp b/tools/ZAPD/ZAPD/ZSkeleton.cpp index 84f00c8187..1a2f93ff7b 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.cpp +++ b/tools/ZAPD/ZAPD/ZSkeleton.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Skeleton, ZSkeleton); REGISTER_ZFILENODE(LimbTable, ZLimbTable); @@ -27,18 +28,19 @@ void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) type = ZSkeletonType::Curve; else if (skelTypeXml != "Normal") { - throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n" - "\t Invalid Type found: '%s'.\n", - name.c_str(), skelTypeXml.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Type' attribute", ""); } std::string limbTypeXml = registeredAttributes.at("LimbType").value; limbType = ZLimb::GetTypeByAttributeName(limbTypeXml); if (limbType == ZLimbType::Invalid) { - throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n" - "\t Invalid LimbType found: '%s'.\n", - name.c_str(), limbTypeXml.c_str())); + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("invalid value '%s' found for 'LimbType' attribute", + limbTypeXml.c_str()), + "Defaulting to 'Standard'."); } } @@ -170,11 +172,9 @@ void ZLimbTable::ParseXML(tinyxml2::XMLElement* reader) limbType = ZLimb::GetTypeByAttributeName(limbTypeXml); if (limbType == ZLimbType::Invalid) { - fprintf(stderr, - "ZLimbTable::ParseXML: Warning in '%s'.\n" - "\t Invalid LimbType found: '%s'.\n" - "\t Defaulting to 'Standard'.\n", - name.c_str(), limbTypeXml.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'LimbType' attribute.", + "Defaulting to 'Standard'."); limbType = ZLimbType::Standard; } diff --git a/tools/ZAPD/ZAPD/ZSymbol.cpp b/tools/ZAPD/ZAPD/ZSymbol.cpp index b24c3de4b0..eabfc2faae 100644 --- a/tools/ZAPD/ZAPD/ZSymbol.cpp +++ b/tools/ZAPD/ZAPD/ZSymbol.cpp @@ -1,6 +1,7 @@ #include "ZSymbol.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Symbol, ZSymbol); @@ -20,11 +21,8 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) if (typeXml == "") { - fprintf(stderr, - "ZSymbol::ParseXML: Warning in '%s'.\n" - "\t Missing 'Type' attribute in xml.\n" - "\t Defaulting to 'void*'.\n", - name.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'Type' attribute in ", "Defaulting to 'void*'."); type = "void*"; } else @@ -35,11 +33,8 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) std::string typeSizeXml = registeredAttributes.at("TypeSize").value; if (typeSizeXml == "") { - fprintf(stderr, - "ZSymbol::ParseXML: Warning in '%s'.\n" - "\t Missing 'TypeSize' attribute in xml.\n" - "\t Defaulting to '4'.\n", - name.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'TypeSize' attribute in ", "Defaulting to '4'."); typeSize = 4; // Size of a word. } else @@ -58,7 +53,9 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) if (registeredAttributes.at("Static").value == "On") { - fprintf(stderr, "A can't be marked as static.\n\t Disabling static\n"); + HANDLE_WARNING_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "a cannot be marked as static", + "Disabling static for this resource."); } staticConf = StaticConfig::Off; } diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp index 33ee54d1bc..7bd31438b4 100644 --- a/tools/ZAPD/ZAPD/ZTexture.cpp +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -8,6 +8,7 @@ #include "Utils/Directory.h" #include "Utils/File.h" #include "Utils/Path.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Texture, ZTexture); @@ -57,17 +58,17 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) if (!StringHelper::HasOnlyDigits(widthXml)) { - throw std::runtime_error( - StringHelper::Sprintf("ZTexture::ParseXML: Error in %s\n" - "\t Value of 'Width' attribute has non-decimal digits: '%s'.\n", - name.c_str(), widthXml.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "value of 'Width' attribute has non-decimal digits: '%s'", widthXml.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + errorHeader, ""); } if (!StringHelper::HasOnlyDigits(heightXml)) { - throw std::runtime_error( - StringHelper::Sprintf("ZTexture::ParseXML: Error in %s\n" - "\t Value of 'Height' attribute has non-decimal digits: '%s'.\n", - name.c_str(), heightXml.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "value of 'Height' attribute has non-decimal digits: '%s'", heightXml.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + errorHeader, ""); } width = StringHelper::StrToL(widthXml); @@ -77,7 +78,10 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) format = GetTextureTypeFromString(formatStr); if (format == TextureType::Error) - throw std::runtime_error("Format " + formatStr + " is not supported!"); + { + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Format' attribute", ""); + } const auto& tlutOffsetAttr = registeredAttributes.at("TlutOffset"); if (tlutOffsetAttr.wasSet) @@ -90,10 +94,9 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) break; default: - throw std::runtime_error(StringHelper::Sprintf( - "ZTexture::ParseXML: Error in %s\n" - "\t 'TlutOffset' declared in non color-indexed (ci4 or ci8) texture.\n", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, + "'TlutOffset' declared in non color-indexed (ci4 or ci8) texture", + ""); break; } } @@ -102,10 +105,10 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) void ZTexture::ParseRawData() { if (rawDataIndex % 8 != 0) - fprintf(stderr, - "ZTexture::ParseXML: Warning in '%s'.\n" - "\t This texture is not 64-bit aligned.\n", - name.c_str()); + { + HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, + "this texture is not 64-bit aligned", ""); + } switch (format) { @@ -136,8 +139,11 @@ void ZTexture::ParseRawData() case TextureType::Palette8bpp: PrepareBitmapPalette8(); break; - default: - throw std::runtime_error("Format is not supported!"); + case TextureType::Error: + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("Invalid texture format", format), ""); + assert(!"TODO"); + break; } } @@ -375,8 +381,9 @@ void ZTexture::PrepareRawDataFromFile(const fs::path& pngFilePath) case TextureType::Palette8bpp: PrepareRawDataPalette8(pngFilePath); break; - default: - throw std::runtime_error("Format is not supported!"); + case TextureType::Error: + HANDLE_ERROR_PROCESS(WarningType::InvalidPNG, "Input PNG file has invalid format type", ""); + break; } } @@ -860,13 +867,9 @@ TextureType ZTexture::GetTextureTypeFromString(const std::string& str) else if (str == "rgb5a1") { texType = TextureType::RGBA16bpp; -#ifdef DEPRECATION_ON - fprintf(stderr, "ZTexture::GetTextureTypeFromString: Deprecation warning.\n" - "\t The texture format 'rgb5a1' is currently deprecated, and will be " - "removed in a future " - "version.\n" - "\t Use the format 'rgba16' instead.\n"); -#endif + HANDLE_WARNING(WarningType::Deprecated, + "the texture format 'rgb5a1' is currently deprecated", + "It will be removed in a future version. Use the format 'rgba16' instead."); } else if (str == "i4") texType = TextureType::Grayscale4bpp; @@ -883,7 +886,9 @@ TextureType ZTexture::GetTextureTypeFromString(const std::string& str) else if (str == "ci8") texType = TextureType::Palette8bpp; else - fprintf(stderr, "Encountered Unknown Texture format %s \n", str.c_str()); + // TODO: handle this case in a more coherent way + HANDLE_WARNING(WarningType::InvalidAttributeValue, + "invalid value found for 'Type' attribute", "Defaulting to ''."); return texType; } diff --git a/tools/ZAPD/ZAPD/ZTextureAnimation.cpp b/tools/ZAPD/ZAPD/ZTextureAnimation.cpp index 4332fcf1e5..698054fa87 100644 --- a/tools/ZAPD/ZAPD/ZTextureAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZTextureAnimation.cpp @@ -2,8 +2,8 @@ * File: ZTextureAnimation.cpp * ZResources defined: ZTextureAnimation, ZTextureAnimationParams (XML declaration not supported for * the latter) - * Purpose: extracting texture animating structures from asset files Note: data type is exclusive to - * Majora's Mask + * Purpose: extracting texture animating structures from asset files + * Note: data type is exclusive to Majora's Mask * * Structure of data: * A texture animation consists of a main array of data of the form @@ -82,6 +82,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" +#include "WarningHandler.h" #include "ZFile.h" #include "ZResource.h" #include "tinyxml2.h" @@ -115,7 +116,7 @@ void ZTextureAnimationParams::ExtractFromBinary(uint32_t nRawDataIndex) ParseRawData(); } -// Implemented by TextureScrollingParams only[ +// Implemented by TextureScrollingParams only void ZTextureAnimationParams::ExtractFromBinary([[maybe_unused]] uint32_t nRawDataIndex, [[maybe_unused]] int count) { @@ -217,19 +218,8 @@ void TextureColorChangingParams::ParseRawData() ((type == TextureAnimationParamsType::ColorChange) ? animLength : colorListCount); if (listLength == 0) - throw std::runtime_error(StringHelper::Sprintf( - "When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "TextureColorChangingParams::ParseRawData:" - "\033[0m" - "\033[91m" - " error: " - "\033[0m" - "\033[97m" - "color list length cannot be 0\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex)); + HANDLE_ERROR_RESOURCE(WarningType::Always, parent, this, rawDataIndex, + "color list length cannot be 0", ""); primColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4); envColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); @@ -378,20 +368,8 @@ void TextureCyclingParams::ParseRawData() cycleLength = BitConverter::ToUInt16BE(rawData, rawDataIndex); if (cycleLength == 0) - throw std::runtime_error( - StringHelper::Sprintf("When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "TextureCyclingParams::ParseRawData:" - "\033[0m" - "\033[91m" - " error: " - "\033[0m" - "\033[97m" - "cycleLength cannot be 0\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), - Seg2Filespace(rawDataIndex, 0))); + HANDLE_ERROR_RESOURCE(WarningType::Always, parent, this, rawDataIndex, + "cycle length cannot be 0", ""); textureListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4); textureIndexListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); @@ -454,21 +432,12 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& { comment = " // Raw pointer, declare texture in XML to use proper symbol"; - fprintf(stderr, - "When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "TextureCyclingParams::DeclareReferences:" - "\033[0m" - "\033[95m" - " warning: " - "\033[0m" - "\033[97m" - "TexCycle declared here points to unknown texture at address %s. " - "Please declare the texture in the XML to use the proper symbol.\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), - Seg2Filespace(textureListAddress, parent->baseAddress), texName.c_str()); + auto msgHeader = StringHelper::Sprintf( + "TexCycle texture array declared here points to unknown texture at address %s", + texName.c_str()); + HANDLE_WARNING_RESOURCE( + WarningType::HardcodedPointer, parent, this, rawDataIndex, msgHeader, + "Please declare the texture in the XML to use the proper symbol."); } texturesBodyStr += StringHelper::Sprintf("\t%s,%s\n", texName.c_str(), comment.c_str()); } @@ -546,22 +515,14 @@ void ZTextureAnimation::ParseRawData() if ((type < 0) || (type > 6)) { - throw std::runtime_error(StringHelper::Sprintf( - "When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "ZTextureAnimation::ParseRawData:" - "\033[0m" - "\033[91m" - " error: " - "\033[0m" - "\033[97m" - "unknown TextureAnimationParams type 0x%02X in TextureAnimation: entry reads\n\t{ " - "0x%02X, 0x%02X, 0x%08X }\n(type should be between " - "0x00 and 0x06)\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex, type, - currentEntry.segment, type, currentEntry.paramsPtr)); + HANDLE_ERROR_RESOURCE( + WarningType::Always, parent, this, rawDataIndex, + StringHelper::Sprintf( + "unknown TextureAnimationParams type 0x%02X in TextureAnimation", type), + StringHelper::Sprintf( + "Entry reads { 0x%02X, 0x%02X, 0x%08X } , but type should be " + "between 0x00 and 0x06 inclusive.", + currentEntry.segment, type, currentEntry.paramsPtr)); } if (currentEntry.segment <= 0) @@ -589,13 +550,24 @@ void ZTextureAnimation::DeclareReferences(const std::string& prefix) if (!parent->HasDeclaration(paramsOffset)) { ZTextureAnimationParams* params; - int count = 2; + int count; switch (entry.type) { case TextureAnimationParamsType::SingleScroll: - count = 1; - [[fallthrough]]; - case TextureAnimationParamsType::DualScroll: + if (true) + { + count = 1; + // The else now allows SingleScroll to fall through to params = ... without + // touching the code in the else block + } + else + { + // The contents of this block can only be run by jumping into it with the + // case label + [[fallthrough]]; + case TextureAnimationParamsType::DualScroll: + count = 2; + } params = new TextureScrollingParams(parent); params->ExtractFromBinary(paramsOffset, count); break; @@ -614,22 +586,12 @@ void ZTextureAnimation::DeclareReferences(const std::string& prefix) break; case TextureAnimationParamsType::Empty: - fprintf(stderr, - "When processing file %s: in input binary file %s: offset 0x%06X:" - "\n\t" - "\033[97m" - "ZTextureAnimation::DeclareReferences:" - "\033[0m" - "\033[95m" - " warning: " - "\033[0m" - "\033[97m" - "TextureAnimationParams entry has empty type (6), but params pointer " - "is not NULL. Params read\n\t\t" - "{ 0x%02X, 0x%02X, 0x%08X }\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), - rawDataIndex, entry.segment, (int)entry.type, entry.paramsPtr); + HANDLE_WARNING_RESOURCE( + WarningType::InvalidExtractedData, parent, this, rawDataIndex, + "TextureAnimationParams entry has empty type (6), but params pointer is " + "not NULL", + StringHelper::Sprintf("Params read { 0x%02X, 0x%02X, 0x%08X } .", + entry.segment, (int)entry.type, entry.paramsPtr)); return; default: // Because GCC is worried this could happen diff --git a/tools/ZAPD/ZAPD/ZVector.cpp b/tools/ZAPD/ZAPD/ZVector.cpp index c940b0b0de..a5a059e354 100644 --- a/tools/ZAPD/ZAPD/ZVector.cpp +++ b/tools/ZAPD/ZAPD/ZVector.cpp @@ -6,6 +6,7 @@ #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Vector, ZVector); @@ -86,20 +87,18 @@ std::string ZVector::GetSourceTypeName() const return "Vec3i"; else { - std::string output = StringHelper::Sprintf( - "Encountered unsupported vector type: %d dimensions, %s type", dimensions, + std::string msgHeader = StringHelper::Sprintf( + "encountered unsupported vector type: %d dimensions, %s type", dimensions, ZScalar::MapScalarTypeToOutputType(scalarType).c_str()); - if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) - printf("%s\n", output.c_str()); - - throw std::runtime_error(output); + HANDLE_ERROR_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, msgHeader, + ""); } } std::string ZVector::GetBodySourceCode() const { - std::string body; + std::string body = ""; for (size_t i = 0; i < scalars.size(); i++) { diff --git a/tools/ZAPD/ZAPD/ZVector.h b/tools/ZAPD/ZAPD/ZVector.h index d1a738968d..a50d3e8083 100644 --- a/tools/ZAPD/ZAPD/ZVector.h +++ b/tools/ZAPD/ZAPD/ZVector.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/ZVtx.h b/tools/ZAPD/ZAPD/ZVtx.h index 018a1d4a9a..511048791d 100644 --- a/tools/ZAPD/ZAPD/ZVtx.h +++ b/tools/ZAPD/ZAPD/ZVtx.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/any/any/zlib.static.txt b/tools/ZAPD/ZAPD/any/any/zlib.static.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/ZAPD/ZAPD/packages.config b/tools/ZAPD/ZAPD/packages.config index a7f2abbd29..c387aaed70 100644 --- a/tools/ZAPD/ZAPD/packages.config +++ b/tools/ZAPD/ZAPD/packages.config @@ -1,8 +1,9 @@  - - + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPDUtils/Color3b.h b/tools/ZAPD/ZAPDUtils/Color3b.h index 7e59f6b7f7..507c099f52 100644 --- a/tools/ZAPD/ZAPDUtils/Color3b.h +++ b/tools/ZAPD/ZAPDUtils/Color3b.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Color3b { diff --git a/tools/ZAPD/ZAPDUtils/Makefile b/tools/ZAPD/ZAPDUtils/Makefile index aef6780313..e8941ed773 100644 --- a/tools/ZAPD/ZAPDUtils/Makefile +++ b/tools/ZAPD/ZAPDUtils/Makefile @@ -1,7 +1,7 @@ # Only used for standalone compilation, usually inherits these from the main makefile CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17 -SRC_DIRS := $(shell find -type d -not -path "*build*") +SRC_DIRS := $(shell find . -type d -not -path "*build*") CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) diff --git a/tools/ZAPD/ZAPDUtils/StrHash.h b/tools/ZAPD/ZAPDUtils/StrHash.h index 68d22b9cd6..c611bdddad 100644 --- a/tools/ZAPD/ZAPDUtils/StrHash.h +++ b/tools/ZAPD/ZAPDUtils/StrHash.h @@ -1,8 +1,8 @@ #pragma once -#include -#include -#include +#include +#include +#include typedef uint32_t strhash; diff --git a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp index a4cf782294..35412781cc 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp +++ b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp @@ -1,5 +1,5 @@ #include "BinaryReader.h" -#include +#include #include #include "Stream.h" @@ -89,7 +89,7 @@ float BinaryReader::ReadSingle() stream->Read((char*)&result, sizeof(float)); - if (isnan(result)) + if (std::isnan(result)) throw std::runtime_error("BinaryReader::ReadSingle(): Error reading stream"); return result; @@ -100,7 +100,7 @@ double BinaryReader::ReadDouble() double result = NAN; stream->Read((char*)&result, sizeof(double)); - if (isnan(result)) + if (std::isnan(result)) throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream"); return result; diff --git a/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h b/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h index 5cca35b319..e672b97c23 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h +++ b/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h @@ -1,7 +1,7 @@ #pragma once +#include #include -#include #include class BitConverter diff --git a/tools/ZAPD/ZAPDUtils/Utils/File.h b/tools/ZAPD/ZAPDUtils/Utils/File.h index e3f8880cb6..084152f794 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/File.h +++ b/tools/ZAPD/ZAPDUtils/Utils/File.h @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include #include #include #include "Directory.h" diff --git a/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp b/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp index 6c27399d6c..6e85c59a04 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp +++ b/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp @@ -1,5 +1,5 @@ #include "MemoryStream.h" -#include +#include #ifndef _MSC_VER #define memcpy_s(dest, destSize, source, sourceSize) memcpy(dest, source, destSize) diff --git a/tools/ZAPD/ZAPDUtils/Utils/Path.h b/tools/ZAPD/ZAPDUtils/Utils/Path.h index 496a0ae13c..0f7ef27431 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/Path.h +++ b/tools/ZAPD/ZAPDUtils/Utils/Path.h @@ -18,13 +18,13 @@ public: static std::string GetFileName(const fs::path& input) { // https://en.cppreference.com/w/cpp/filesystem/path/filename - return input.filename(); + return input.filename().string(); }; static std::string GetFileNameWithoutExtension(const fs::path& input) { // https://en.cppreference.com/w/cpp/filesystem/path/stem - return input.stem(); + return input.stem().string(); }; static std::string GetFileNameExtension(const std::string& input) diff --git a/tools/ZAPD/ZAPDUtils/Utils/Stream.h b/tools/ZAPD/ZAPDUtils/Utils/Stream.h index 060e23cd27..e73a9a70d0 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/Stream.h +++ b/tools/ZAPD/ZAPDUtils/Utils/Stream.h @@ -1,7 +1,7 @@ #pragma once +#include #include -#include enum class SeekOffsetType { diff --git a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h index 74607ce3a2..0b0d676429 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h +++ b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h @@ -1,18 +1,12 @@ #pragma once #include +#include #include #include -#include #include #include -#ifdef _MSC_VER -#define __PRETTY_FUNCTION__ __FUNCSIG__ -#elif not defined(__GNUC__) -#define __PRETTY_FUNCTION__ __func__ -#endif - class StringHelper { public: @@ -111,4 +105,10 @@ public: { return std::all_of(str.begin(), str.end(), ::isdigit); } + + static bool IEquals(const std::string& a, const std::string& b) + { + return std::equal(a.begin(), a.end(), b.begin(), b.end(), + [](char a, char b) { return tolower(a) == tolower(b); }); + } }; diff --git a/tools/ZAPD/ZAPDUtils/Utils/vt.h b/tools/ZAPD/ZAPDUtils/Utils/vt.h new file mode 100644 index 0000000000..23f424442b --- /dev/null +++ b/tools/ZAPD/ZAPDUtils/Utils/vt.h @@ -0,0 +1,45 @@ +#ifndef VT_H +#define VT_H + +// clang-format off +#define VT_COLOR_BLACK 0 +#define VT_COLOR_RED 1 +#define VT_COLOR_GREEN 2 +#define VT_COLOR_YELLOW 3 +#define VT_COLOR_BLUE 4 +#define VT_COLOR_PURPLE 5 +#define VT_COLOR_CYAN 6 +#define VT_COLOR_WHITE 7 +#define VT_COLOR_LIGHTGRAY 8 +#define VT_COLOR_DARKGRAY 9 + +#define VT_COLOR_FOREGROUND 3 +#define VT_COLOR_BACKGROUND 4 +// clang-format on + +#define VT_COLOR_EXPAND0(type, color) #type #color +#define VT_COLOR_EXPAND1(type, color) VT_COLOR_EXPAND0(type, color) +#define VT_COLOR(type, color) VT_COLOR_EXPAND1(VT_COLOR_##type, VT_COLOR_##color) + +#define VT_ESC "\x1b" +#define VT_CSI "[" +#define VT_CUP(x, y) VT_ESC VT_CSI y ";" x "H" +#define VT_ED(n) VT_ESC VT_CSI #n "J" +#define VT_SGR(n) VT_ESC VT_CSI n "m" + +// Add more macros if necessary +#define VT_COL(back, fore) VT_SGR(VT_COLOR(BACKGROUND, back) ";" VT_COLOR(FOREGROUND, fore)) +#define VT_FGCOL(color) VT_SGR(VT_COLOR(FOREGROUND, color)) +#define VT_BGCOL(color) VT_SGR(VT_COLOR(BACKGROUND, color)) + +// Bold +#define VT_BOLD "1" + +// Bold color support +#define VT_BOLD_FGCOL(color) VT_SGR(VT_BOLD ";" VT_COLOR(FOREGROUND, color)) +#define VT_BOLD_BGCOL(color) VT_SGR(VT_BOLD ";" VT_COLOR(BACKGROUND, color)) + +#define VT_RST VT_SGR("") +#define VT_CLS VT_ED(2) + +#endif diff --git a/tools/ZAPD/ZAPDUtils/Vec2f.h b/tools/ZAPD/ZAPDUtils/Vec2f.h index 9d4beeb465..73e9259a89 100644 --- a/tools/ZAPD/ZAPDUtils/Vec2f.h +++ b/tools/ZAPD/ZAPDUtils/Vec2f.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Vec2f { diff --git a/tools/ZAPD/ZAPDUtils/Vec3f.h b/tools/ZAPD/ZAPDUtils/Vec3f.h index 4bfbb3c254..d6e9c5568f 100644 --- a/tools/ZAPD/ZAPDUtils/Vec3f.h +++ b/tools/ZAPD/ZAPDUtils/Vec3f.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Vec3f { diff --git a/tools/ZAPD/ZAPDUtils/Vec3s.h b/tools/ZAPD/ZAPDUtils/Vec3s.h index 23e4673b84..05816eddb5 100644 --- a/tools/ZAPD/ZAPDUtils/Vec3s.h +++ b/tools/ZAPD/ZAPDUtils/Vec3s.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Vec3s { diff --git a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj index 803cdb5f01..0a09666e03 100644 --- a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj +++ b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj @@ -43,7 +43,7 @@ StaticLibrary true v142 - Unicode + MultiByte Application @@ -116,6 +116,8 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreadedDebug + Default Console @@ -155,6 +157,7 @@ + diff --git a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters index 48117c845f..4765ad5d45 100644 --- a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters +++ b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters @@ -19,6 +19,9 @@ {e047919d-7186-49ca-b115-e48fbb5c8743} + + {3de9dd46-0dfd-4d48-9f20-9f24e5b80fe0} + @@ -74,5 +77,8 @@ Source Files\Utils + + Source Files\Libraries + \ No newline at end of file diff --git a/tools/ZAPD/docs/zapd_warning_example.png b/tools/ZAPD/docs/zapd_warning_example.png new file mode 100644 index 0000000000000000000000000000000000000000..a001c64d6a51428bed50d6b599e8082d8effa3ee GIT binary patch literal 47521 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 OFgtn5sOW_2t^Wa$9d#Z6 literal 0 HcmV?d00001 diff --git a/tools/asm-differ/.gitrepo b/tools/asm-differ/.gitrepo index d3e4418c9e..241c0ad6b6 100644 --- a/tools/asm-differ/.gitrepo +++ b/tools/asm-differ/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/simonlindholm/asm-differ.git branch = main - commit = f30d43aceba6291aa3c08b7317b0458b6d734321 - parent = e977dfeb374c6de4076ca9a0f44ba5a6a701d849 + commit = 70c33cc125666495f84f8c7bee60d3158b4b1164 + parent = 62341d8db0c29d1d4f0c360196e428309ac373b6 method = merge cmdver = 0.4.3 diff --git a/tools/asm-differ/diff.py b/tools/asm-differ/diff.py index d7ac3f3440..2ec117a126 100755 --- a/tools/asm-differ/diff.py +++ b/tools/asm-differ/diff.py @@ -640,6 +640,7 @@ class Text: class TableMetadata: headers: Tuple[Text, ...] current_score: int + max_score: int previous_score: Optional[int] @@ -832,6 +833,7 @@ class JsonFormatter(Formatter): for h, name in zip(meta.headers, ("base", "current", "previous")) } output["current_score"] = meta.current_score + output["max_score"] = meta.max_score if meta.previous_score is not None: output["previous_score"] = meta.previous_score output_rows: List[Dict[str, Any]] = [] @@ -1184,8 +1186,9 @@ def parse_elf_data_references(data: bytes) -> List[Tuple[int, int, str]]: assert len(symtab_sections) == 1 symtab = sections[symtab_sections[0]] - text_sections = [i for i in range(e_shnum) if sec_names[i] == b".text"] - assert len(text_sections) == 1 + text_sections = [i for i in range(e_shnum) if sec_names[i] == b".text" and sections[i].sh_size != 0] + if len(text_sections) != 1: + return [] text_section = text_sections[0] ret: List[Tuple[int, int, str]] = [] @@ -1327,11 +1330,23 @@ def dump_binary( (objdump_flags + flags2, project.myimg, None), ) +DATA_POOL_PLACEHOLDER = "DATA_POOL_PLACEHOLDER-OFFSET_{}" +DATA_POOL_PLACEHOLDER_PATTERN = re.compile( + r"DATA_POOL_PLACEHOLDER-OFFSET_([a-zA-z0-9]+)" +) -class DifferenceNormalizer: +# Example: "ldr r4, [pc, #56] ; (4c )" +ARM32_LOAD_POOL_PATTERN = r"(ldr\s+r([0-9]|1[0-3]),\s+\[pc,.*;\s*)(\([a-fA-F0-9]+.*\))" + + +# The base class is a no-op. +class AsmProcessor: def __init__(self, config: Config) -> None: self.config = config + def process_reloc(self, row: str, prev: str) -> str: + return prev + def normalize(self, mnemonic: str, row: str) -> str: """This should be called exactly once for each line.""" arch = self.config.arch @@ -1342,9 +1357,143 @@ class DifferenceNormalizer: def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: return row + + def post_process(self, lines: List["Line"]) -> None: + return -class DifferenceNormalizerAArch64(DifferenceNormalizer): +class AsmProcessorMIPS(AsmProcessor): + def process_reloc(self, row: str, prev: str) -> str: + arch = self.config.arch + if "R_MIPS_NONE" in row: + # GNU as emits no-op relocations immediately after real ones when + # assembling with -mabi=64. Return without trying to parse 'imm' as an + # integer. + return prev + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + if imm != "0": + # MIPS uses relocations with addends embedded in the code as immediates. + # If there is an immediate, show it as part of the relocation. Ideally + # we'd show this addend in both %lo/%hi, but annoyingly objdump's output + # doesn't include enough information to pair up %lo's and %hi's... + # TODO: handle unambiguous cases where all addends for a symbol are the + # same, or show "+???". + mnemonic = prev.split()[0] + if ( + mnemonic in arch.instructions_with_address_immediates + and not imm.startswith("0x") + ): + imm = "0x" + imm + repl += "+" + imm if int(imm, 0) > 0 else imm + if "R_MIPS_LO16" in row: + repl = f"%lo({repl})" + elif "R_MIPS_HI16" in row: + # Ideally we'd pair up R_MIPS_LO16 and R_MIPS_HI16 to generate a + # correct addend for each, but objdump doesn't give us the order of + # the relocations, so we can't find the right LO16. :( + repl = f"%hi({repl})" + elif "R_MIPS_26" in row: + # Function calls + pass + elif "R_MIPS_PC16" in row: + # Branch to glabel. This gives confusing output, but there's not much + # we can do here. + pass + else: + assert False, f"unknown relocation type '{row}' for line '{prev}'" + return before + repl + after + + +class AsmProcessorPPC(AsmProcessor): + def process_reloc(self, row: str, prev: str) -> str: + arch = self.config.arch + assert any( + r in row for r in ["R_PPC_REL24", "R_PPC_ADDR16", "R_PPC_EMB_SDA21"] + ), f"unknown relocation type '{row}' for line '{prev}'" + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + if "R_PPC_REL24" in row: + # function calls + pass + elif "R_PPC_ADDR16_HI" in row: + # absolute hi of addr + repl = f"{repl}@h" + elif "R_PPC_ADDR16_HA" in row: + # adjusted hi of addr + repl = f"{repl}@ha" + elif "R_PPC_ADDR16_LO" in row: + # lo of addr + repl = f"{repl}@l" + elif "R_PPC_ADDR16" in row: + # 16-bit absolute addr + if "+0x7" in repl: + # remove the very large addends as they are an artifact of (label-_SDA(2)_BASE_) + # computations and are unimportant in a diff setting. + if int(repl.split("+")[1], 16) > 0x70000000: + repl = repl.split("+")[0] + elif "R_PPC_EMB_SDA21" in row: + # small data area + pass + return before + repl + after + + +class AsmProcessorARM32(AsmProcessor): + def process_reloc(self, row: str, prev: str) -> str: + arch = self.config.arch + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + return before + repl + after + + def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: + if self.config.ignore_addr_diffs: + row = self._normalize_bl(mnemonic, row) + row = self._normalize_data_pool(row) + return row + + def _normalize_bl(self, mnemonic: str, row: str) -> str: + if mnemonic != "bl": + return row + + row, _ = split_off_address(row) + return row + "" + + def _normalize_data_pool(self, row: str) -> str: + pool_match = re.search(ARM32_LOAD_POOL_PATTERN, row) + if pool_match: + offset = pool_match.group(3).split(" ")[0][1:] + repl = DATA_POOL_PLACEHOLDER.format(offset) + return pool_match.group(1) + repl + return row + + def post_process(self, lines: List["Line"]) -> None: + lines_by_line_number = {} + for line in lines: + lines_by_line_number[line.line_num] = line + for line in lines: + reloc_match = re.search( + DATA_POOL_PLACEHOLDER_PATTERN, line.normalized_original + ) + if reloc_match is None: + continue + + # Get value at relocation + reloc = reloc_match.group(0) + line_number = re.search( + DATA_POOL_PLACEHOLDER_PATTERN, reloc).group(1) + line_original = lines_by_line_number[int(line_number, 16)].original + value = line_original.split()[1] + + # Replace relocation placeholder with value + replaced = re.sub( + DATA_POOL_PLACEHOLDER_PATTERN, + f"={value} ({line_number})", + line.normalized_original, + ) + line.original = replaced + + +class AsmProcessorAArch64(AsmProcessor): def __init__(self, config: Config) -> None: super().__init__(config) self._adrp_pair_registers: Set[str] = set() @@ -1394,23 +1543,6 @@ class DifferenceNormalizerAArch64(DifferenceNormalizer): return row -class DifferenceNormalizerARM32(DifferenceNormalizer): - def __init__(self, config: Config) -> None: - super().__init__(config) - - def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: - if self.config.ignore_addr_diffs: - row = self._normalize_bl(mnemonic, row) - return row - - def _normalize_bl(self, mnemonic: str, row: str) -> str: - if mnemonic != "bl": - return row - - row, _ = split_off_address(row) - return row + "" - - @dataclass class ArchSettings: name: str @@ -1420,14 +1552,15 @@ class ArchSettings: re_sprel: Pattern[str] re_large_imm: Pattern[str] re_imm: Pattern[str] + re_reloc: Pattern[str] branch_instructions: Set[str] instructions_with_address_immediates: Set[str] forbidden: Set[str] = field(default_factory=lambda: set(string.ascii_letters + "_")) arch_flags: List[str] = field(default_factory=list) branch_likely_instructions: Set[str] = field(default_factory=set) - difference_normalizer: Type[DifferenceNormalizer] = DifferenceNormalizer + proc: Type[AsmProcessor] = AsmProcessor big_endian: Optional[bool] = True - + delay_slot_instructions: Set[str] = field(default_factory=set) MIPS_BRANCH_LIKELY_INSTRUCTIONS = { "beql", @@ -1543,10 +1676,13 @@ MIPS_SETTINGS = ArchSettings( re_sprel=re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\(sp\)"), re_large_imm=re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}"), re_imm=re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)"), + re_reloc=re.compile(r"R_MIPS_"), arch_flags=["-m", "mips:4300"], branch_likely_instructions=MIPS_BRANCH_LIKELY_INSTRUCTIONS, branch_instructions=MIPS_BRANCH_INSTRUCTIONS, instructions_with_address_immediates=MIPS_BRANCH_INSTRUCTIONS.union({"jal", "j"}), + delay_slot_instructions=MIPS_BRANCH_INSTRUCTIONS.union({"j", "jal", "jr", "jalr"}), + proc=AsmProcessorMIPS, ) MIPSEL_SETTINGS = replace(MIPS_SETTINGS, name="mipsel", big_endian=False) @@ -1566,9 +1702,10 @@ ARM32_SETTINGS = ArchSettings( re_sprel=re.compile(r"sp, #-?(0x[0-9a-fA-F]+|[0-9]+)\b"), re_large_imm=re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}"), re_imm=re.compile(r"(? Tuple[str, str, str]: return before, imm, after -def process_mips_reloc(row: str, prev: str, arch: ArchSettings) -> str: - if "R_MIPS_NONE" in row: - # GNU as emits no-op relocations immediately after real ones when - # assembling with -mabi=64. Return without trying to parse 'imm' as an - # integer. - return prev - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - if imm != "0": - # MIPS uses relocations with addends embedded in the code as immediates. - # If there is an immediate, show it as part of the relocation. Ideally - # we'd show this addend in both %lo/%hi, but annoyingly objdump's output - # doesn't include enough information to pair up %lo's and %hi's... - # TODO: handle unambiguous cases where all addends for a symbol are the - # same, or show "+???". - mnemonic = prev.split()[0] - if ( - mnemonic in arch.instructions_with_address_immediates - and not imm.startswith("0x") - ): - imm = "0x" + imm - repl += "+" + imm if int(imm, 0) > 0 else imm - if "R_MIPS_LO16" in row: - repl = f"%lo({repl})" - elif "R_MIPS_HI16" in row: - # Ideally we'd pair up R_MIPS_LO16 and R_MIPS_HI16 to generate a - # correct addend for each, but objdump doesn't give us the order of - # the relocations, so we can't find the right LO16. :( - repl = f"%hi({repl})" - elif "R_MIPS_26" in row: - # Function calls - pass - elif "R_MIPS_PC16" in row: - # Branch to glabel. This gives confusing output, but there's not much - # we can do here. - pass - else: - assert False, f"unknown relocation type '{row}' for line '{prev}'" - return before + repl + after - - -def process_ppc_reloc(row: str, prev: str) -> str: - assert any( - r in row for r in ["R_PPC_REL24", "R_PPC_ADDR16", "R_PPC_EMB_SDA21"] - ), f"unknown relocation type '{row}' for line '{prev}'" - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - if "R_PPC_REL24" in row: - # function calls - pass - elif "R_PPC_ADDR16_HI" in row: - # absolute hi of addr - repl = f"{repl}@h" - elif "R_PPC_ADDR16_HA" in row: - # adjusted hi of addr - repl = f"{repl}@ha" - elif "R_PPC_ADDR16_LO" in row: - # lo of addr - repl = f"{repl}@l" - elif "R_PPC_ADDR16" in row: - # 16-bit absolute addr - if "+0x7" in repl: - # remove the very large addends as they are an artifact of (label-_SDA(2)_BASE_) - # computations and are unimportant in a diff setting. - if int(repl.split("+")[1], 16) > 0x70000000: - repl = repl.split("+")[0] - elif "R_PPC_EMB_SDA21" in row: - # small data area - pass - return before + repl + after - - -def process_arm_reloc(row: str, prev: str, arch: ArchSettings) -> str: - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - return before + repl + after - - def pad_mnemonic(line: str) -> str: if "\t" not in line: return line @@ -1741,7 +1803,7 @@ class Line: def process(dump: str, config: Config) -> List[Line]: arch = config.arch - normalizer = arch.difference_normalizer(config) + processor = arch.proc(config) skip_next = False source_lines = [] source_filename = None @@ -1783,7 +1845,7 @@ def process(dump: str, config: Config) -> List[Line]: ) break - if not re.match(r"^ +[0-9a-f]+:\t", row): + if not re.match(r"^\s+[0-9a-f]+:\s+", row): # This regex is conservative, and assumes the file path does not contain "weird" # characters like colons, tabs, or angle brackets. if re.match( @@ -1797,10 +1859,11 @@ def process(dump: str, config: Config) -> List[Line]: m_comment = re.search(arch.re_comment, row) comment = m_comment[0] if m_comment else None row = re.sub(arch.re_comment, "", row) + line_num_str = row.split(":")[0] row = row.rstrip() tabs = row.split("\t") row = "\t".join(tabs[2:]) - line_num = eval_line_num(tabs[0].strip()) + line_num = eval_line_num(line_num_str.strip()) if line_num in data_refs: refs = data_refs[line_num] @@ -1835,20 +1898,13 @@ def process(dump: str, config: Config) -> List[Line]: while i < len(lines): reloc_row = lines[i] - if "R_AARCH64_" in reloc_row: - # TODO: handle relocation - pass - elif "R_MIPS_" in reloc_row: - original = process_mips_reloc(reloc_row, original, arch) - elif "R_PPC_" in reloc_row: - original = process_ppc_reloc(reloc_row, original) - elif "R_ARM_" in reloc_row: - original = process_arm_reloc(reloc_row, original, arch) + if re.search(arch.re_reloc, reloc_row): + original = processor.process_reloc(reloc_row, original) else: break i += 1 - normalized_original = normalizer.normalize(mnemonic, original) + normalized_original = processor.normalize(mnemonic, original) scorable_line = normalized_original if not config.score_stack_differences: @@ -1904,6 +1960,7 @@ def process(dump: str, config: Config) -> List[Line]: elif stop_after_delay_slot: break + processor.post_process(output) return output @@ -2123,8 +2180,15 @@ class OutputLine: class Diff: lines: List[OutputLine] score: int + max_score: int +def trim_nops(lines: List[Line], arch: ArchSettings) -> List[Line]: + lines = lines[:] + while lines and lines[-1].mnemonic == "nop" and (len(lines) == 1 or lines[-2].mnemonic not in arch.delay_slot_instructions): + lines.pop() + return lines + def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: if config.show_source: import cxxfilt @@ -2152,8 +2216,12 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: btset.add(bt) sc(str(bt)) + lines1 = trim_nops(lines1, arch) + lines2 = trim_nops(lines2, arch) + diffed_lines = diff_lines(lines1, lines2, config.algorithm) score = score_diff_lines(diffed_lines, config) + max_score = len(lines1) * config.penalty_deletion line_num_base = -1 line_num_offset = 0 @@ -2385,7 +2453,7 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: ) output = output[config.skip_lines :] - return Diff(lines=output, score=score) + return Diff(lines=output, score=score, max_score=max_score) def chunk_diff_lines( @@ -2461,6 +2529,7 @@ def align_diffs( Text(f"{padding}PREVIOUS ({old_diff.score})"), ), current_score=new_diff.score, + max_score=new_diff.max_score, previous_score=old_diff.score, ) old_chunks = chunk_diff_lines(old_diff.lines) @@ -2504,6 +2573,7 @@ def align_diffs( Text(f"{padding}CURRENT ({new_diff.score})"), ), current_score=new_diff.score, + max_score=new_diff.max_score, previous_score=None, ) diff_lines = [(line, line) for line in new_diff.lines] diff --git a/tools/z64compress/.gitrepo b/tools/z64compress/.gitrepo index 9507f81ce9..905b330d9c 100644 --- a/tools/z64compress/.gitrepo +++ b/tools/z64compress/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/z64me/z64compress.git branch = main - commit = 98ef0ac25f7adb47235c839838e29496d3546917 - parent = 69cc19eea8c30e50e280f400e8cf06fe66efca60 + commit = ac5b1a0d0b23346362a68a107da3478227f8e703 + parent = 33e3aa92181a0543826adc10a5f3304d60b391dd method = merge cmdver = 0.4.3 diff --git a/tools/z64compress/src/main.c b/tools/z64compress/src/main.c index 71d1d20400..bd044059d1 100644 --- a/tools/z64compress/src/main.c +++ b/tools/z64compress/src/main.c @@ -221,7 +221,7 @@ wow_main } } - fprintf(printer, "welcome to z64compress 1.0.1 \n"); + fprintf(printer, "welcome to z64compress 1.0.2 \n"); if (argc <= 1) { @@ -356,7 +356,6 @@ wow_main ARG_ZERO_TEST(Ain , "--in" ); ARG_ZERO_TEST(Aout , "--out" ); - ARG_ZERO_TEST(Amb , "--mb" ); ARG_ZERO_TEST(Acodec, "--codec"); #undef ARG_ZERO_TEST diff --git a/tools/z64compress/src/rom.c b/tools/z64compress/src/rom.c index decf8ca1d0..008597b524 100644 --- a/tools/z64compress/src/rom.c +++ b/tools/z64compress/src/rom.c @@ -68,7 +68,9 @@ for (dma = rom->dma; (unsigned)(dma - rom->dma) < rom->dma_num; ++dma) #define PROGRESS_A_B (int)(dma - rom->dma), rom->dma_num -#define ALIGN16(x) (((x) + 0xF) & ~0xF) +#define ALIGN(x, n) (((x) + ((n)-1)) & ~((n)-1)) +#define ALIGN16(x) ALIGN(x, 16) +#define ALIGN8MB(x) ALIGN(x, 8 * 0x100000) /* * @@ -936,7 +938,7 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) cache = rom->cache; - if (compsz > rom->data_sz || mb <= 0) + if (compsz > rom->data_sz || mb < 0) die("invalid mb argument %d", mb); /* get encoding functions */ @@ -1057,31 +1059,13 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) /* sort by original start, ascending */ DMASORT(rom, sortfunc_dma_start_ascend); - if (matching) - { - /* fill the entire (compressed) rom space with 00010203...FF... - in order to match retail rom padding */ - unsigned char n = 0; // will intentionally overflow - for (unsigned int j = 0; j < compsz; j++, n++) - { - rom->data[j] = n; - } - } - else - { - /* zero the entire (compressed) rom space */ - memset(rom->data, 0, compsz); - } - - /* go through dma table, injecting compressed files */ + /* determine physical addresses for each segment */ comp_total = 0; DMA_FOR_EACH { - unsigned char *dst; char *fn = dma->compname; unsigned int sz; unsigned int sz16; - fprintf(printer, "\r""injecting file %d/%d: ", PROGRESS_A_B); if (dma->deleted) continue; @@ -1114,9 +1098,6 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) if (sz16 & 15) sz16 += 16 - (sz16 & 15); - /* put the files in */ - dst = rom->data + comp_total; - dma->Pstart = comp_total; if (dma->compress) { @@ -1130,26 +1111,66 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) dma->Pend = 0; comp_total += sz16; - if (dma->Pend > compsz) + if (mb != 0 && dma->Pend > compsz) die("ran out of compressed rom space"); + } + + /* adaptive final size */ + if (mb == 0) + compsz = ALIGN8MB(comp_total); + + if (matching) + { + /* fill the entire (compressed) rom space with 00010203...FF... + in order to match retail rom padding */ + unsigned char n = 0; /* will intentionally overflow */ + for (unsigned int j = 0; j < compsz; j++, n++) + { + rom->data[j] = n; + } + } + else + { + /* zero the entire (compressed) rom space */ + memset(rom->data, 0, compsz); + } + + /* inject compressed files */ + comp_total = 0; + DMA_FOR_EACH + { + unsigned char *dst; + char *fn = dma->compname; + unsigned int sz; + fprintf(printer, "\r""injecting file %d/%d: ", PROGRESS_A_B); + + if (dma->deleted) + continue; + + dst = rom->data + dma->Pstart; /* external cached file logic */ if (cache) { + /* skip entries that don't reference compressed files */ + if (!fn) + continue; + /* load file into rom at offset */ dst = file_load_into(cache_codec, fn, &sz, dst); } - /* otherwise, a simple memcpy */ else { memcpy(dst, dma->compbuf, dma->compSz); - if (matching) - { - // since matching rom padding is not zero but file padding is zero, - // fill file padding space with zeros - memset(dst + dma->compSz, 0, ALIGN16(dma->compSz) - dma->compSz); - } + sz = dma->compSz; + } + + if (matching) + { + /* since matching rom padding is not zero but file padding is zero, + fill file padding space with zeros */ + memset(dst + sz, 0, ALIGN16(sz) - sz); } } fprintf(printer, "\r""injecting file %d/%d: ", dma_num, dma_num); From a6cd0e442703f98820fcecb70c178fe6e7d84a6f Mon Sep 17 00:00:00 2001 From: Parker Burnett Date: Wed, 15 Dec 2021 22:56:38 -0600 Subject: [PATCH 05/27] Adding tools.md (#344) * Filling in what I could * Organise, add most of the other tools, etc. * removing redundant file and filling in TOC * addressing comments * Merge branch 'master' into contributing_update_tools * hopefully adding pngs and missing tools * quick fix * applying feedback * adding clarity to the sheet section * Update docs/tools.md Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Update tools.md * Update docs/tools.md Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: Elliptic Ellipsis Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> --- .gitignore | 3 + docs/images/En_Firefly.png | Bin 0 -> 220901 bytes docs/images/diff.png | Bin 0 -> 85896 bytes docs/tools.md | 291 +++++++++++++++++++++++++++++++++++++ 4 files changed, 294 insertions(+) create mode 100644 docs/images/En_Firefly.png create mode 100644 docs/images/diff.png create mode 100644 docs/tools.md diff --git a/.gitignore b/.gitignore index ce16eaafbf..b09a0acd3f 100644 --- a/.gitignore +++ b/.gitignore @@ -42,5 +42,8 @@ tools/mips_to_c/ !*_custom* .extracted-assets.json +# Docs +!docs/**/*.png + # Per-user configuration .python-version diff --git a/docs/images/En_Firefly.png b/docs/images/En_Firefly.png new file mode 100644 index 0000000000000000000000000000000000000000..ed3258592615a532f5cb2ec800eea65cce6bc83d GIT binary patch literal 220901 zcmZ^L1z41A*DZ>INJ)c~jsi+cgMdLQDJb2HAPqyeh?GbRLnBfmodXQr-Q6&RbPS#6 z<~`T@e|+cq&%9o*H8aoi-1pvV@3r>24N#Pq!oPd}E(Qh${u^m=B@B$a5f~UZC+=W@ zKcSgkEeAhg8OTV9V_aVS_p>Sk{PhEjH{!3}JH@Y0Ifl}#I4>VtMIC~ znyE`o;SV7H%WEiwGxLA>NGo~z|L4z_emmT__C0Yy4f-u62$Y>b{=|lp7CRoMIUgos zz=A;gBwD17} zN~g);_`eQ91!Lb?sy$E*gF1&L=)XcF5wZu(Xg&6%3^nE(ir}+LxERpFvE7kCQkf=A z7ZC_VGhoW7VbM;nXv|tLA+iNtvsAfxSgtK^?rSrZ_Yo#2iymL}F$i<3yPpx5MqKXZ zW#FuytoFxEPF#GG*5{3c_`ffxOu@wZQI+LQQ4Y}%?7R-27F0b7HfN9AF3a&$wX~!l zK;nl?1a)y*BXd15_H~#^zbynxu<$4se@S04kCNq6V1zRybVPJ5NiV~oT;=T}Br7}t z(Aao_&TsyA-YUEUdn6YpWUiovgsrpy9Ij9>wuKf760hK`$V#5RfI#@$ z^m@cb+AhJ?{rfU!mq#X8bG{UqWun<8x_fKeHM{py?OM~;{=IGIycH*-SjL!m`+OUb zd*N-l*qpXdnDaNEn=4wuN^OtfJ*otzOS`wfrTrQbDW0@6t~woyv>beASJkj`S{^TN z&PT0x+uhuEXsXMoXwE^%dUQj8M#Y%lZ_2A>v2o1-Wh1y#Hsv(g{r284*es_RpBRxwD%h#7S^|1w3BKu73uB#QC%=LjI!X4$EWJumI`i4>4Z?DgtQlSC0O!{=(^h|vbW_cXwp03-ok4MOWA_?;>n7simWp}7xbmgS2d2GN&2B^)wVfkdW`iMC@0Zu&3kgUmvC6j_ZbNQ(Ji2|z9 zb}mGRvxL)dK#PTsQ33&zWd>Qg{Wz^a?uf}G&l}^SRPHfYEsu;4oFTF;ylp}HV@^3= z;@gO~#sL{hcYl6s#fBl{zn+PH@t}X0lvk;Ms$1Uq;hjQvrnBZy6*0AY+bp|#DO(fl zU_?(?hdRnN{j9{GKsr}12zk7F6qhx*oL3!QkNth-c$a3|W0=zIJYr`!Zx>^@I-ZyB zxwX)GiPy3)%O`wmOchk@{{sRItX0EfKL`pu)QE{jlc7gGLjMf`wEk*vn*1kzN@55lFCQJ2m%Es z+fVBJs4B7D7TpBtb1HQE*?ZUOF*g-)8&ANV%V#bzu83)3c#z}xhEqq~_|Klep0%s} zA@m4|`#Iw`gL?S)a1O0SFu$;Sdzct!cpk?ffV59MJW}m@S_x%G-)PjR0|YX(gm$@e znnS_>sl)Kd^9!9(#UaWGSyoLH(2Gqc`_Tq{V{9Aw)6i68yR4ek%!gh%=DR(Y1bc{c zl^Kytlgswt+QIC889TPUh^1R(?PlbhHic*ibxn)y2PcH$lkiTcKU2<({-O8>wN2g~_hNQx`&VMLpXyxqhfVfM9DoSKpQp6+yn;F3wpyJXC6bXnYvy~{}E zP)$~{H>v&NBv0qtcnaQ!J3*REh1*PpyG>bh3)IComG4G;`!_xPTd_#?PCsP_C{p0O zqX$0-lqqnCaj*&^#V8A)-%6a~KMBrK$~{&OWXf)7dz@*P-kxWGh6&M#fAOgI!qBe? zvF23tFrNY|cmNw26ld=0*Z8sc>HA^{rA!}XV3t|7I7;&Zqtw5(E1wE$?sL+(wZHXG z;iagS3B_8e$CQc>Kb3==rR-l_`8Gqux>klvkAGxznHS*~&;_8Sqa zz1mVZvP~mla75um4bDNT7R2Nq`C>~g$vOKp65OY7=1fT|7U{N&$!{EGlDmo|gnn@N(W{a(C5#=-l;8|`Yfe29OweoTC z7Ug(Y0}p-i^2u!0dWey&vx>XE=(i9W9kz{Ypo6uEoKTs2U#lVJKWkgL)U0JG=xd<$V-sf?}(AZG>88x$W zf=6{2zWR!+Wa`1qG3r`I`X7UuhIkp5Dc&$Ius}3>_nW(76+^-MePcPhVTa`)MsSFm z!dKd9qNURU7?fi#OYiwjS!$1uZ!!Euf0*W|+eKAa|L&K_Q)4EQdEAi%CsuX0)X)fG z?tKh{-#*v5Z)W-%=QeXvK%A)=^C{1o;pyq6q^f~U&{|yQiQC0R!Et*zEqh4E+G*a} zVIYgyLSPef&0V4}!e7^m|0Jfbe(yb;f$71Q#g#`nli@sUni+9iuoMb$FG;2yLt|BbMf1GI53u(0ZFZ3?aMvaj4CKXtB6WH)<7=_U<_Xpm zclEgO-ln&K`&gf6E((KR1pb;^re>9g9i(Fk#ZqsV zX)WO1PN#^9(NcpN>Bk%|ez<+V^mFKpl&w1(n|;afX>#U`nh~*r_fQ9$$TlAdMq>)f zgqTNR!#5m>#*S|4a99M{^9&93zc;%rMQvI?YT*Fx(WqN{sMNKhVZG4aqd<{PpSqsZd?K|RhbqpLyWa9;&!rwCoFC}>u1KzdKWc3%v0TgFSzc&0=*Bmh$1*xUQIg~LS3g<&ZqY{+-4Emz=Iz)X#Dg;$ z4`xb<|LI<|>s8VyK?F9BxAG=&$m*G}wKuNcMA@Rh%l8n;JgUpoTEz6LpMe8f}5v`i!p?{1b>3O+ki=ka>eQQj`d6HN>Phg zbb$mgM2z_}5`XXN1~aZH^orOc=GaQHPYgn z53V=-3t|E^4hMU7w!dpaa)%keH9@>d2IA?dmgkQik7-qpGqk&R8&TRJ_=++RfftGL zpy!e?dnd0|*|>uXmrfnLp(<{f*v0wR(k#6O8ByKMw_5-3ZWBZq9r(So^O=xH$KV;U zk3qqB+Bb7b0>6adbSxLmxD^w#w5m)3WLNk6_%o;_Fr=JM%l-Hyqw&+C$o2)1@kJfS%1(W0EV z^XH}NTU`Zjrk}rP-5&hTF2M{LS%eAvT{AaSRbYCK6xy!P?qth@*|>#=t*8UMYGn~- zh7D*DU?;EzfnCinLV7pH-pRD{#YHJ=QBp7WH-5iJPh|!<=2~iBl$Qt3jbh{~7haZX zF5~2DYaL`2+-PZaujj-YzrQv*HdHrlAu=fSnl-0Mz}@8QfcGO-DZ?T5cjA2i#n2Yq zOG^;Dd&%x#Pe8r3wbKhFq42Y(QXaD&MlR8f6?ucJsGxAB1)QS{F~wG&Jb{ejd4r81 z*x&k@mx3QR)eI7vqM1?Pg;1TTEbWT;=8p<%|0xjHt1GD~nO?68TAK>q1Zz_oIGL(2 zxwdML^bNKeo;nm|Au&nH1o+xklJ$KVjrPhFOTU&jyButcHe*gyfLsJwy?ZcrqZ>cu z9c$zt?L>d`yVrq2THQ($m;MFpGe|jK#&l=&o*?ZRTrMS8fg1ZnChYvU(*&g)lb#+CC3HYm(IZ(BG6!9!fm z_OK=-gw`!o?A-ma5|zi^@Vjn;5EUdVQ8~8Dc&xL*rOt`axU>;he3^AX3Z{3q_>kB8 zRE_%(B7%LZ<=XBICt*vhmJFx!1*&G_eRXBaBz?;DiM|eQzr%MVcrbnQaDMp&LpO)& z@w5Q*Ct*L6r07Q*z=~i@3qG&SV(NZk&IaNCd96`tjrxcfbK0%N6m~y)WkjyxG?$Yi z+c|ZPnO}3dpEm~+uv{(oJj>bQt}3$|89^r`Rkam()lF#hND<+j93RbL?v)|{Uj-dr zWM0+YCXR>0`k=P@)_!SM$h2F?h(ZFAWi89sy0(W~>cG}|*#S$E$?0MU@g{X(h+Rf} z^UL%Bx#&*s4WZckR0)Zwgd$8W%DBp9xZTj1!V{oXg0S{hJJLZicfY^5WzMl{rf=+AHpc?fYMWTE7N$eetD%*I3 zd{TxTA>rea!I53v^LYv?%7g`Kj!L_!<+E-pkH{C7(;-%;80%fR%ltKaCh`Qq*5-Qm z-~)A@=YhHgHf-&>m$OWWs_D47L#HDvj}@86{Z!S5t8txdIpG|n0J3Kh)o0~M7YuSs z%ZbVFuH{{pQdX|Gx*n@GTI@_cH7Df8el35r!~FpzPQI7qK7R)w3uS!tys?ymYE@C` z5+aDdW(*HAsYOi6RwP6;-!HM$NM5U~5uH~hSFKoPX5SiQkKo(soI3}YV{HkIr?1|j z>l6Pq{;>^f*{0lSv#)_>bqhp|m#4=$?NXHLAEm%%m!SQ)$R5+?))1iF&62;Lb zi&a5>p~^;~IJALtx~zPF@?Q~1TzsLrpeiL&_hOKnH9L3r^6cDk%Y-Q@sGAcH4-*fy znYY%vDGDT_nX|SmkoD8&WYY}v#a$kUYr2M(CNVFL4+yv1^*=sRE;>8)JR(T)Sif^Q z#+3A{fU#a7Br#h<1hU&lbR3BMNn`*2)*2M89kR7V+t=xwpcvQfyO@WHvz$Q zwKvKkbW3gLt~)N1ZYZCm>HS=DYJK*}Pt8V4$CuTIk3gwKue1bj&s_AwkLIYiVC(gY zB{C8Cf6}U>bUijrviPFbpHtyfLAs=%X2`eUK+<>~~D$ct7A(StjetIIEX z4t3lEBPjf`v}66v?_CEj^M@1Tn#V&u!X4#d&#KY8airfsov{4lfv-CdrjQhv)xq@^_eLc2V!iaeG%7fD-sc{uC;_q?@EfCY7X3@$#YPL zz^G{mp6hy?*c@1H%|#k!I4_Qxd`k;@4%ZG@Lae&%Y#8np^8noS#x8ZVb@^00&S0TV z(UL)#n7D|NBG^vLpifCj3tQH8b{#mE>zEpv8t)ttMYD1TcAPZ?=7maUWNG)y^{MG< z-(Pz%y54{Ha%JMh0!awXJWG%8tI@6HNECQSl)pJfsVT)ZY4lK1Tc9yd_z-W|x8 zt}~PWsz1;3n44y_ zq`CnUUmyn*#AC7C_^P_`dmItJaNlZ7znfs{4#iY7R{B?NAqr!w<;3&2Kq(ZG2JHf{D_>zpkIW3TslGVhX-9dU z^3TkdgZQgT!5`p>iPl`e&a3Ho%j(cFymRWgt4eye$t>z}ZpI_dm|mzBbn=xznY=tr zx}?pt!>Va%81OqR$U;W^oRQ&+Gc>nMOrjNOTJLYSA3?k7Uh-lvE-mGi-^y)SoOkp< zXQ{Heu1t}ft&cu6_pRHy%(|>BJezD4@H|X`Tb=If=9Lmobn}lJDXdR4*oM&F_*qmQ z@ZxAg7dsm>s^+l8b0^I7?6T z1Vz!KMAerk&xhFG{OMe=-X2;`)Q4GmSydn1O_M9VgfRr|!#~(&&-4v>C{I8l+6pre zabn2Rt8N=*S3nbFW3Cs9=+XJTF5|gB(9=IN@b1`I)zTYO5f2n@&kp|!w*Xwj2n@G_ z06*tFua3ImnNw8F=)JAA!*1Qi4cP9ap;UCVuAZq!<~T!uG})Mm`6>Sp`|JPU*k*2m zHmz`hC!y!LH{72=d5GQbXHQ3%$aA2bpm!df=2iG$-oR>Rj7CC=3yR4X7gLx_GV?%7 zA}hz)O3l=>gF*yz3Dz_!gBpWOyDH)QRfz}9E`XX)#zt3f3h4-X#45E_8aV^TnU^Ho zfony#Sbua2+i`!VInx&O;TMZNo{38*_p49a;{fDnf>t*lfrv9E*fIumMUBh3tLOCm z#W9PH%i*mS4y~IHXtr&Cdt#>y*lNYb&Vl;@TB8kjGlGgT4x{##j;Kp`b+?Mg z*}*gLp+<{yf~aAG_;MZ>&52{l33CIFFnCDfLI9>~jE>sEG%KfKS~&ju7`W|MT?<3N`=IP~@SjD(O|NTfwWcqiF*uFKLB z(a~0OcHA>CuGoRjtL{3~b&cbOORiX2EJYB~1A&TLu*Q0%bh(ODCS5J4>3HywA7xD9 z5DvZOq%t=B&x|Uc7pI%J3%fq1a9c7^y==3Sbkr&`E&2w=>+{@BsDknFb~lo$yW@

VMKE>zkmx;f7|)+il>V&dNTG5jzDN+mufgPfdrN-Fr5< zd)Fhx?+UP`_YG6wa-D3wQ~lzejub7^hoYomIgQcp{|iTE>#B7mjhAv)|CA8neV5-2 zqR^=@9UG}Riy=I(HpKLn?dHJX6y|N19VG?5{v6r`G^zY0i9IilTP=pp#siAJM|sOC zqh%uH<8+UYNPwzXeH@|6a-+#7lK0}GN%e@n<^b32qRsC(#Y)6ebIlDkC|K%PymM4N zC44zP5xJPqCHEEcs<)mR?m6c~R3z{R8f3OUH^w>|t;0TE9+@7yN9!fN;4N}6YsoGr zuUg@1VHZ1NDPOY0j}mIQV4@dw8pta`R7HXd`etOmd?%W)BxP0IlA9ZB=D96bF?Zm( zgk$>U#>HHdYMFp#)n!q+@KxPBBdj^Wb=z$7D;MB<14+moKd6l8*1EqqSA}%i^Ah>q z!~PyglS$mbDNtsHy%k^e5{BuyG^plj%h#{wnMQ4a`?)VhP)EcgefJ2!eKG$K`Y+}= zh{iXC<-!=ozLLl5D5=pJL+T7aNet`p4ZuO54EK#y9l^M!X!q>=Il{(ZyFbA##<3H$ z-A!P@sbbem0kO_;5QHc({CC}Q)CGD@3O9O)9Tgm-Q+Cqtx|WdjT69ZW_i(U&-X4B< zXlD>>#PGL(J?w2!K5<$}a&YL3qvl#AXzI_}?_)byv@F}GM!hKTBjHUH7AX?arn0ORTZXB~I<|5RXKYYHvhATfq|%qvoS~AGNa?k`MVBrLCvwT?S*!H9kWL~ zKvco`;pvHV5sHb`T>vdN_+p1cyBo8BCYxByowXiGd003$ES%kp(F#6D_cet>ARkh@ zuZdNfpTQ(3uImHxd)zM5%*C9aC{skuNeQWpMD419T~W2CglfEI7>kx`jGW(8aLeM& zSut zs?zA&8kp2>>Yb|pxqUo^pYT{y6N{}hO96+@Z5M>d){@nr1@ zXTmEjS*)X{AD?olf(Ue{*3b5=S+l^+KOm%=LBw4ove&=5jj4P4sJbe? z(#gb-9y(Kd9I_vrS}?dldygW_HA9g#T>9gu-vOMQ6@u)xo;79k%lrU)ownEk-*dfD zwm)JL%gBW7CnzZJeaa{WSrWr^u(hZvdXC3Yc}!;&FXY%1VO2A{Um?ss@&W!v2k>JI z|BQjik8!)``cs}^3AMl$vd2^PU__K|0<_Y?tL`7R>8klLyGC92biK%~glETlWM&cE zai%%>0FU!}-IUwXjvr^4(4MP}+cyw!)wB}=&Nk7(OIR11QXCN+)DFaLzzIb?=;+X&I1)#qoC~5xEWGh^U|B*>GYg_m5&P8Y=JMt~DYR++W zXT3H=K=!65&{MSl)u~j=RehL=P`LJT&#dMs3~avI!c-B(wyTJ6wG|=Z=HJCG?&TM6 z+Z?s46>BY#ljY00m+h(om9A1`EEVRCRus5dW{p-wNI0euu&GZZqY-llKWf>B1w1ps<|=A(ySWmtc#;}qTR{2kgMEuU zho=ZR!}B4&cC|}=bKh6SwvPhd$0EApnPS@Bf7u{t*?-{;at(lL8lWr+!fv5neQ$Op zvL@Cu>%jZ#S_rq8{vJN#5;+aiotP?gbmjNew>E(-H6*b@4%x12d8MC0B@+Mg>R@ZK z5*x~2L0{wk9ZUlAgwX=eg(h~&w4A0agV)E}fV{9%A1Cz!22XPA)_$zZy1OohO_><~ zk>P%g*w73u;16KH^A*zr@c2x8Y@mq(vNCuJ^GYs3F0-p3Nr}qefNlrO9~UD+X#O}n z)$BG(n!#(R-P-S+8K|>z+YwBhtbwB_e2<0$^K^!ecU5$kLEG?ksp38$`(OsiL?HTE zpYpq`HZAGNZ`-+$8Np^#;X1%7{6WK3rY*nv=%L3B3H_s4^frjdhc*(%N~3N`6uEmb zE%fy(`RJvUE|SlYNK}xr@z~VF8wE4l5}7gL(yJu~V}ie(G+@dIvZD!D0E#Do+_;o1 z^4#jkorxnD1Mpu0d7aAl>Y|)nulV50+ncoU_i3i{Y2j6t6o5*EqAcf=d6fl(f?Bk1^3L&312`^&t|C1@C8R(EdkSx!j&-0iD=e0RA=mi#^)=C91(m zOH5ld%Y+`MBY7GgAc<-&>J)O3iQ+TVwhjzO|3Z7?wK4xI~IWJH8m<{7^ zBR%()M_ADnQ^NLtUjaBLzI)WR0PAGW-9Bk6!c*vSn{}z)?>9R;tT`bw6-&;lKJdI) zd~px?%XJB!=<>Y*>A0OSbNgc{i_R?K*E=aKv@&yDgsSWg8gCEcr#tOhmV zZ7#qSqp9Jv`=It$(spj&z;wpr5?0z*cTB2~?XdI(t58B<-Ql7m=@d^i&+l?? zgI>#CQGqYS8(E6pp1v?6&}sJrlh2yH%#1NG1oAvPcu|yJxI?f6tP8FH&qWU#8?IOv z;j|O{^*gWaQ=cWob2DxWg^a0giX@Nk*rzVXn?2JDM?T4>@W<3&J62|a7DWXV7tfuu z5Ps-A1ZtM~ElNd%YRQOA*LOqgvK`U(QL{HJeBv_Ue0@z}r=RVtcx8*BU z8IsF++oZ<}hdUHAm(M`I4VbC8=ojFH$lwU-ofxiXq7#)iw7?(01y%ak6wZiviJnL( z87nnz-9in7(9YQ^2zPeQb9o-0Q;goO+#h3PqF zen!BlGU!F>fdt$g^c{V!I>VSb>(%Psz=?OIngA`0Xz%o@J}1#W2S$`^2NM_xPtBA% zqEIC3De)e9v|5B_x+>zmP}fx+XVwwPDi_>7ww}uA0@Oq5cgR<#!^zuMOjJEVIzQPY zdq&N{-f_E}iLMUiush(Wu-!d|`-A7=o3zi4@AVnWAr)b-#gD&SKPNa>xMV9V7%IFZ z8%{XpAe@19->2G|S`xob(*-BeFAR}n1TYPJ$ktg%u@zXS*_^3sArSWOGTJ^fv$C;N zgLjdY>*ic`U3K8VrU2?7_z)E8qH=>b3?E22fDzd^Ino2c6ma=Uhk3jfZ1#7oWLesY z=3IOYvtigL&P%NxyT>;H5vc{0D!khW$a$^4P;R^f^R=a&bJtHfd8i|whdOSjW%7k2 zVQY%l+c;$y2Al7jj2pC)0iq31 zr101RnE8clOmqS9qF~HCzS25?Um@wL06CaIsJ{S}$=Z`XM0ix8cWe1S&ecU%7hlZY$&HueVK`2Cl6(V-sIP8lgYh` zY5K>dI zj5^CWg%ZT_msh}axv43EKMVkfY5(+f@G^*LMUwiTqM887jcqF-ks z#skE;BQsea=)J8=yH}%~L@>Ppv*h))wU3~Q!)Rg0+Zm2QXEzal$dwo86TRN^@ZF-w z&zaP=%eXP|o%p#qBkdx4igUK*FSx9CU3gt9SzX`rDYLG*d|SO12fA@QRElIpP2 z)|rI7HVtD$$JAU&z$9Iq{#DTcRkMF&Op-ZbuF*%P(tfE@=pG352Foit3Rr#LNS|-V zik^{83_1m+MVSEAx6c`8_-5|XWzP$E>n||>9QM`VDyQ*A4S;<^%^#&!gtm+5bK^Pe z+rjjf9ZrNapT=10+kF`jdxR$^yXOAnumpU9ZhfNJd%_jxq)L{9-DY*3lc|`H1A-9O zzb0h5wi6WJSMlo;ZCK^2nBpAM|6zSYLa&*Jl6i(bGW+z^fFv)$jS~JLTj-%Y5R>aT z@vvIb1^Bs|XB&SAowte@bK_NL#ElM2bZsWegF5nPpy;Xq)&70lq*MSNq7`c?e`3YL zDj7V4wg~O5N*xu0XObDqK$0=EGm@tblCXT;x|M>+@kuNt2NT?YuQwYbOt6}pK~>hX zbJ4Lad>=WoVYF3h33$_$8Y#=((%Z-bX32PR^1!(FNBdW+)I7KZnACyE?Q`UKCa#}a zK$8HkK>JEEQPl9SeWS(_jvI2Oyt zl){4+48N-;kYmW4IB;Wcn~34*MglLmx_t`X^pBaB$ox3{F=dpIkrN|QrM-9PFn{O- zM)6=MFTjK?r53OfUJik+;WhjOW6$bf6_*LkPiE$|mPG|+rOki$Xi^5y-@7}*-_J^a z1^tATCbviq+g>rRG6liAC**)_8`!x-)diRU_W`Gz1R)d^aO-@1VMYfZ*( z7}ZN-L4k@EmBP&+VqUE1+OHH_Rto-B;b>w6<@KafAuz|n-_Qzja4&~oV=8hg2Z88q5BYh z+23x{anYK3AV{=VKMttVuQ@s(ijWzB*0l(?gNe+6)+%IB)J>TLP{BzXz1kPyEArs zDM|&XghT8f`0~N98_?I%67{W=pEFWIafVYCA6`ce4C|Xn3xc%SmcD_38%wvIk; zRPB4G?P_9RxBQcpoR;gGexd<}QlEa~s7_-7ooX?3hqy?lzva=X4gn@AvS|48b|XqKfB_~x;FmFNcnJOvD6i@3 zSKt-^S+e2PAP~({Kg=>)yLB7kwz2GuD9V_*)0QMZ@YN5MH3ll^(@VJ=Ft_-q zZyy8|Qr;;1=xr@X%Oef}_QVdv9XWd<(=YHDG493ByX(Kmlyrj3gvrB9uS-{@za>FZ z>BCx8=JWM^q^Eq})PD_(3{Dw7_c!_JKapVbQMDaJB+y)c<7;ZG!H#dDJ5*E=<%?us z=)l@yAdY(DBg-$4G$Q6MAg=vb95e)g2E?wK-f^nJ02Km^pTTYFn|cJa-L}sl3p<4a z<%*r=SHa|Y0r-jC;P#m?I|W9QQdp$g|2!Be6pP@*RoP@_&4 zC4NY=t^dROtfNmL5PWZT?lWZZugy|O;j8QDtoeC{bA?})AhIFl)SS^in$)WgX1({R zZC0(VIp5@GVC$47Fh7Gh=(1NSD=yFV1z6!m$N$-WJBNl<8+aFWf(mH@3&<7j$)u8g zE0Y36`N}q|7r{S4+ZQq-RPkr<$kA$y|b-YRn z$)Aw|#}tV1?%h?pB)|rO@j?6H;{hs_Up6Z9&(>^}cyv}g;<}l?v%>PO9JHn&oPgIC zXW(7{aOMGq!QAu4h$~x?B)b`v-3(00YVl4GIi9cws*0m_Dd7Cb;`vXQ{|nMoMp7`j zN@b*cOu7x4APk`R%k(_~PeVQeb|SYhpZFs$`G{zizd7+W-q-5>dxBH&6StuG4*@7k zpIJ0z?GF>{{$iUyQ0qTX6ip~^kSUynA9w*-yqZp=qbn5iiFND*X)%Bm5ZJOcgu69_ zC5mY()Cnga_diuyVQmVB)YCU^?aUrJXJg3JDx}ir;b5PAZ4aR(V5tQp65bG4Xdpmf`-;ch$eEGLWUuH1ux*euM@Kb zbHc-@w_&nrZ&JA%l}-A`Sb>9GmQkwux9Hko_<&{0nhgq^opBKcrxniDyx!Fif>`d| zVwl~ZJ9K8&fBac1Sy9x4QGG=PNv=RF#~2XV(B$*QBMB1cHDH;+Xnvc}OzagTdH%#jY)9Dw%Pm`C@t4|XKw>mqhjFTDH%UOz%Ga0>pCERAi^}{@ zeb}hVe5k&XRWwx2n>)Sk*}$w*+w2b$!#8z(r;@!}EZF8Zzj`lrRAGG){~}uNart3t z3PUM|HNYu8ewrpMan-!mwES5cYVTmoYOyAPikbf4sF5ag@XMUtBB2=pB-b~~+R zKY}RHu1&FEPQxDbtuf9Pz2+3niwm6znL#ygp>=pmy@y1E652En=D~KQZb@xF=$8Sx z018v#u`rNk-I8DCDn8J>7+0aX+~A{T&%gv{g9cV=7p>x%^fHeFGWr{dpU!963HHWKbD@9wn}4{TRE(&Gh5W7xt#cyH0Bk%Gj(pR4n}P1W zaL_(A$Ao(kG+1c^w6d-ZnOSSz+9BR{#c>ios-nB;!Ql}yauPeDSuTEhx`+!-UJ0*g zMZHdz=1aRA$4wMXRz;>#$3FVO~ z#4pufyfj6O*$Cz=5+L`jkX^nl8-<(Nmco{6KUem_`4!NwGgOAZH9j6`nWkL@w5fX8{A_In`(yTNEu-w3@49EYBK#-u;s(T^Biw`Q z7mxYi@T1-}DEq~o8cY_N6$jLz2I}Y}z(7<%kY~jnWurs=NmrGXtj!1wgw_5rVMYe7 zMT}FI(5hVlIOf1(Wx9bIok{_n_RXIL7Aj6(uAOphEf-JNXc7I@qA!|~XDZ!|HorOs zNHe-ox_c1tkiBeXp`Nk>OZ+q16YwzB27%cX zFZ`ycA$(`#S;ijH?4{c`Y911Wokm`3IScD<;|Ul5tFj+{L{%xVgI@8Z4JdleAdEo6 zaJl|tV$r6&U0;?(O?hQ?1vbA^2F^o7V#d+I?YG#mE#nEK1iu?#*4ju=+9l{)PyNgw zD}1V5k`0Y&jcgD|#{rpXP#~Tg%B1^5>50a}D5bW$^FQ7)aK*5$XjS*?^CnbHn(#(+ zX(PPlDI+e&-Yvk_C3M)wj;g+RtJ`mp5smE*D?rrqQ4Sxzyjb(<+}|ct z6nxjPXl;O)VAk)lKiEBU76CZ9jDIr+h>Z28OI<8ADy%x2We7S4wy1BB57t~1nc*DZ ztY!P$=xc`c*tW&i#k;DG#$6PxWV=w?W457$58|65$mcIpFHzzrNlp2J{@N}=X1aWFNL?B>W)vM36Jat<%ERmaK9$js> zKB{h_F`ykN7<*ElThEDm=KDYKqwp^ESEDRj17ob^Zi%wa@!b@;+B1I7%pJan5WYih z*_M3?dYsXd?>6rWjcTzvHV*JN*SVhcSRm^^hcoCOFF&TB7#|>W+YFLHJJY=Q*nQU(IAelbdL#EJgI+emoypjs}wuzg} z3&+zeM11i*Pca8KE+L5(>`L6r>O#k~T)2;ha%IIA=&mbje>(lz8u%hw%o*tT-mVwN zjDCJK(EOai+ffEIqu<{CERKq{ckb(HWWLS|LzADtaGB7kW>xPJV2 zj#lAayRjN_n=5NsC-n!IJ@DLc%Ry$&T-rL_cYVWwR{&eO9UhVK2RPYUwNtOjU6Y2F zFI*347nj^;jxWwhi*ImJ%0BYr&W1cy2_t5B=M$Ap9ze|YJebWm!D(bnpxZ^JyGoGX z_;9q_WomxI(H`+wJ&&X%n3l=GAWQ9+3;g%%z$!(I0q=(BA+(VDFutl?NXL^K_OQq+v4V|eROuGERq${EY*80+cnF>%I8t_IXZ zX~WxrW!K!MhG4mZafyFMOtO!>oVfS1Hd7qhas zh5}}M8u zN1zC+*$+rXqViAFY$16Q3^erBbED=5*;kVh@Zwqt(xnp_u?_V~h--@kj zRDGWG66rp-L_MKMw`Q1g9rtmp;Xo#P+SL^y#$0&6EJk{*yBO=`a25Qd6)f`{KEixP z`>25v_B>yhR!jD9ib_T;}(2`#ocb{(LWQB)r&LUt~B1sHioGsKO?#kMMXDLN~;npI%CU5=V1PAi2dyqctLMQJNP&D z<6nI{S#X5t2_NQjx(tCq?TvnDI49;qVi~?rtr8*@8kQQ#(if68Wf{O>?;r1dZPmFG zak4puH+kGQi-lEGqVhZ&xSglDork$sls~^0@2P=8H%o-UI^LMg0hyH{5<%xv0Rm_8(~%pC;;*)C=h1>AFEi8!#}R$sYO ze%npLB-Q10n@V`rW|mzm?SqnKD*INlFq~@#O+IFZ)kmnX!hDO@!E@t?=RBLxM_mzO@ns2c_o!KNB5kLk>$y&Kk^ zO6<=YuI0>sg}-FBU@v{^M0)0sv9U}L)i2jFG9vLtHn#|03?0CAEH{TEtPnt&%NVtv zykv$bOU2Ehl9-Sx{8V$OdsR;f%F8pQ}oV4Dl5Rth90l^wb3Vn!S+EcObvQKr7dHx0yau zRYusmZ0qk8A03qt^OkrG(4*cgymcpHCjR#T_MsZrnkT4I0Op}4U5#Z0c<2*1Z;%z9 z)^Z2O8Uz~R>G1!z(&Yc&r^WI$A<=ch+&2@I`1-g%t)=%?}PdL=R>VNd0*fx#bcuQ<6RU4+&quQu!Khn|Jy#3t_C0OgIF z65_e})c8qOx8L$mi4s01e_?G=X-dIx1qRCDCVtYaQ!imdlHdUWz)_7}P&Umag4Kkn zCwSz{033$vuKkO`;?TF(@-fwvoO%&sg-I@ivB4N_wTnA4OOYt?HsM$t>WhP^TdY+L zeZIbpS3Q4AAk{tjpM8D6O_{v88WOH$&*4k<+szDVS@ zrRxuaKPdp(TYp?T&fWU;8`bvDxm~Ib!?YEfdj2CH<6Ya4`PA3S5Xk?NAf#E^Kdvq( ztD*8leror*bZ!|nr}TzrSe>@Q9J%BlFkEirlATBArRZ;X-y&gyjyv|&oZIYHNo8rr z_{&~DC@br4hM(kT4wp;Et&PZSQxFMs6ecRI;`IbGo^NhW*4gK-D^|AaN>bN&dy@+uJ4t*O`k*_u`|5^TDBEsqYEy5$kgF22X6 z##xTBDU~Zx7;dl8k=ua7sGf`Pyt-RQLGdLi2;G>un>&mkBOnEP4wGk`0LmCkF3H?f z&(|fUS^fv*Y=z#tm|`D&3k+y=y#_t7u^cX8kAdBzvPA<7jxxp zD@MZl!ZMV;KQftM7h8)d zOrxdFS5E_abfq2+)y?L1rG``nY`KE;fVSfd^)Qt0j{MfP`#)@bcRbZ^|9_=OL`L=~ zTUps#g($12?3IcI;#PF8BSt?@zzq@9W`@9_XC& zzOL7JzFx2A^}NV(VhnKIY|W3F3r@UAN&W&O$DiLOGc?(H`t-PPUX8Ay@LSVaf7AS2 zZYiv0VEg#(H@Ub4OsUBZ&e$_X?@R3oWf^25nrAP=$OujLJ=*>ayL=4d-W~f~-x0_# z&y0T@HA^Mh()HwS(#~IRQv3euyd455q7tI3lEDmZiPn#6a^`luf0rcbit&7S0wU2S zgg(7RGxbUc`QjzRB#FXmx$v9g2K!ABUZ(#m>*ePBl`6lmS8m;|4flH~9g z?9eM^YeUE7!q7H}<~{~{%IDpco-+c!WhUh0*k=FtYNe|~Ksn2{z)}l)Zz1^DRN~-w z^#noRsPo8D zo%RSF$5;<#UKECYdY$&amnlwH|366Mclc`e40g%$h%gO$H_Y7>SBG*p{wfSGkg*Xu zPILlrsMwe^Q~!$S7I&{p+tvBZ9@I>3dyI)3Wm;ptTdV(cb7W%Lm9`D;7qJbwoeN`5 z@2I8=|6>38-_TBspzYSn`Xh6i;)#!UpMRD(y|0X)D4Ib+He=w!1%-bKq3$pgV zn~;vFJ&!MA>%(V%#a4k~YUvCiDQSyZ@Q>&^HkoZMw*o}kr>-xh{~N|q&-7338g?3; zKRhs0r`!AqxE@Xue|g-s%VH0cfRIfHUu&E5rkHc(s(Yy^K@yYC_P=_7;>i0|o0$Aw zKJG;V`|rNJIM%CB{(O#V_o5P9aTlmDq9pkXonXm5Q46 zd?X~tzwHElpm#Y2OphejwN9HWclw;Y3HYv91pFbpG|0_Dhg6W{KI?fBL(#F5SV>?4 z3l#j9xRWQy7~mw8wn;pEkskJ`vJj|k)4e(8@0Xz~)e!QKJH$1&->!cN zTMW-m57OOO1g8_rZ~fm%!6k|(r^%%D7tJ;|EP0&ivH;4x)^_Ehm5J?x77j4N&sts* z2ApbEa|DE&zPKe{>RaW*x<2y#t1K%$x!T$r-nCC>YJ@iDXRp?*=O?K({l_=D2uZI? z+t!{IqXx~7B+R5wsf`cMY;={U*|1trA$JdV(5)hPJiQ;W& zi}VgdQ3_b!K$0q00(LTwE~n%2jX`9aCVdKbJpPS2;x9Guz0wa%+wgb(5a_jk)u)kT z7r6Tc!i%Q3qPrD-kWqiF|FsjKw&wS#hdeXbbGQVWadhfRu1-(5IoY!v!)-BR0dgPL z(Z2n>X^7}?dz0ojQ0)JOWpc}YEMP2$P>0;nUl%a$#T^%JTy?KLy_Pd&`@1DDyF&=t z118ylYqBNArTJ9%azgO{wBQdEGPs}}E}6cGJ1>iVIL8WE>MdJi{(pJ~`Od*GIaBkS zth&#O>qru^5T^e(|Kg7eO~2$?c{8%E#d zq|+qpfr7`MKYfb8I1VABaagZ?sn?3$lKpeV-WxZA_r@z3?n~=$fV*mOp2 zY0#{qR%CqQ6){<5W<}0_0o$;yua6r-m%{2V3l$NWp83tZ=No?15A_hOY7o3O4#p41 z>EW7G3+-eVAJpsey5EHN{B3rEgZ};Y+6))NP8?TdTx`#~g{alp0VPN*@q;zl$}LQ+v!1_SA$$N7qH{<5i|W;z_-xd%I(Ll!qPE|8O_k=8KxEIFuosA?(y71+fx`M4{zJ3U~oA}EU zdvcDu`Pcs8ADDLkXh9!xC!z!8r7grxdB+wHo_>~b=LXG*ORxNL28GYnv9bH$Wb8T} z$T#_%7zj&aR5C8^IIz{cxLlFY0hcyeN(z=6eB4YG33n_FoI2J>V^*{6I%bR@4zGLp zlzWU`12*9UJ}uAeQL}$75Lr``u2A;Mq-(mWC%XQEAci+#yI)ALDFj*fB~<`sHpd%{LE0lD>U%q;FD3+Mw(r32Ho2YO z%SSI_4QjK$z4D!l6|0OpuwaBPZG?687~?W?oeul8-}>0%zH_zhS3gz&ie9`ckm|8G zr$Mt>Yf~8^Q(Ueb{E8ZBbpG1aU zrr-fMFCq##myNp0lt*3im*K~~y>fILfgyIGwbG-)5Em{FU*G!a(g{l-E_u6$F;h5hmhff0Hx5I38EzXRb%6A|c zK4qs@%`!=)d+&yUW4O0iL$WloUUJ0n#sf+cxf0Q(Fk`0N0A~#Em&@S-<_2I{q)Y!M zCrNS)xSHZ`Mn;Hx^TxI7HsMD1_$a2!9^~a3litGZyJ;RA_=K>Hs$TN_lvcv?Z~W;| zj7lm)EL1mB%k*m5P!Z`%SA)r03}^nZ$rrJ_ENqB8gd|{Er>KM?aNT%Y5C+DMn7OqDm4|A%JuL=|1LW zJ54FG>-YeRTVc%OLWX*_(7R!2(6TKYo+I3^6uEIZ=fBnP6N2$^ZEU94`0VuXH9I2} zIX+s_e0+eEZLTUSbb3Er#eHowN9|VXgHAO*E^?(KXb2ih9+uO6H2=EOf7i1g({(re zC|wPz)sAV{m7Z~Rq)W`wNcaEBOTkI5M4q<$=o=fes^(ugn#J^5lX2bYhmBZ4AKxXd z(^_kRmm96XdAkenLq3hjU4AQAeH!_gj~@cQKYf%%4ZS@6#YWy*#Z5TJ{z&w(hC5~C zjDCBFx+Eq>f~pi}DIE3EOw2($>m^r0U}AhJY6Z^?iq_zW4@|CoT3ex&NxI1)MijMn zbsozQ^lr7VGTQg1hp;)TkMqHrasaaUq5IgQo8!V&X2!Z~SEo7!Bg>3bS;$-Yx?9p; zf_+S&zx^BcnsDZe_ilS_Q-|G@;a~*He=J$+6JsN-R{WAhm*aCUrDC)xH5{dAQ66FH z{AHSW^EWeSyJ`L)Jt4#k{20(ucIG2Wevgze0T$-3FU`miBHq?=rn_35A zu*@CRXfx^KZV#=^UvHt)7^yH;%CUzbT6AOdYr|sDI5*F0?KP@t@l#PW^wuBB$~<0| zy>8v_i+G-De=3#YR76QpSu>8$nw^H|Zy-i;Eldn${!ru)b(^i?T6awAVQ#tix^wj< zpT8KzaHZmyfr_|r#^`FW=A`fk{~$9R6Ijr~%R57SH}L{Z;)I?>ll13F z?vy&6>bh`zc|dmiA*{1w0OC^yR7=4~{7cjB4X2<*YGjQv#oyLi(Xw|WQiULGL$U)f z^H3bQ4^M{NsW|)q$sFdTUB>ji@S11|8lFkFFR5$?nhK_*%`RwWatQZHe@3i9d zgOMKt<(Q4L7PhGmUvVT*^_h2>5)fK+KN*TqPRP8JUTiZG?^P5oVWpFo>n!6AR}}T= zJa>0tq$7$7mczL;ILyM!etIkZ13G~JX#wzuaHZ)985+5$xYVQx@c^SGn~Vfe&8_wlKgyMnvHuY9 z(0GYJzC6h1SkREgkmECL+Sjj$I5=R%I+^a)c0*?h2D2ZL{Z-b+wZ94Ozc3TC`6X$9 zAv|v{o7l2WdP+jVS)m+$A{TKosq<$M)%;%na-UV1-pWeq2)IqXgB!nRX;b8ZZ7T*V z7e5w{GiFI-PwS28GY266zP$V9G_swaJ1gc+595-J?a)&B`2PE#n8fSVRQg+_ z`7VRS)DpMTgt`PKsl_#^DC-{HX2X9}=&MP%H$^_l*5((-P^k`oZ+9L$F8+;B1?x{^!*`;eeY*Z|PQki+Y-IRO zN$8z|(1sH0L}U%>5pRkV{Uj%OS2Pc$E>~>d(t|O|uH~>>s$CIxOS#?+&{$>1l$ljC zw>a@}(lOlTNIOp{2>n>vBOv=?>nueH2p%6b>CGj1Sn56qOL<03?(9<^=rf+5GBjMuL;)|JUpME%hoeUkm1IfRC5)zCs z%s1wad$>gwJ^K6er=ib^zqK@#WU~@F>#pyIj%z8h#36>H_!KoS?g1Gqmwn>j0(>8l z4{m}y$VOF~AKvjJa^xj#Wb7w}=j~a;qr;y+$%l@}{lE|DJ4%X0^2GxGS?*feMG@&t zNHQNwt}552j4D<&d?^T!WYRR?pt?s9dM8q@duAY;Bx}J5wx^|XyDa(Tu^_3hA-Ypp z8puGi$1@m<#+ix6-4}{A_W17O3j!VXZ7mCsF{R}Wk&D~eHT^k+HfgtFG9lZzBssQC z(8)3N%VGeAv;weKv3Hg~L+&tCVyC3SYWW8D}+hqxq69ldsEGH>`;D_g* zh2;Cv$M;n=j)uYbo>Z%mnfl_qL$XhqR>$1?tiK>CSNIBKjsW3#w8;)S{dtRs z^tOe(oT-&nVS$;d26F`rU0=` zl`8}v_*vGVii_Z5aVSz3?g*4F2*HHg;*!(`4!;1hUyNRQj9x;FvT6%|3?~=ZrO44c zksm{!F`3W@t-X6>l`S;<_TVm3_65*S&2$OQjOkfzwnSk+xFj#Q;HuH@Td+)3y)RV$ z_@dK3SRKw-tF6uzVsg(MO74)6K?})??2?ez zUUJCruIm-bag$nmkS!AHhu9rcTe>S_&Z~?sh6Fypa}ZVOHwsJtKn@9%)o{7?*9imu zt2%@kyt+i7dyke3-vXVb;ZV@D(E(_>=BF)DxQ@k;aDgRPgveKh1yfDlygF~Oi6L2w zt#7R!{Hr5!tv$AO-)-NLIa>$~j84mOP<>kwb=lji{uUYVA1;7%LqSSgp1A15NI3G( zJ{SMp@hW)@{eaFoIkASgAFN3nc+Z$KcS-l4TOfz=@d>s*7Vn+^U2{)OyvS|>^g`v^ zjAKJzJmzG`lYXTHu`MKh`;&U@Q(`YA6%~WIgU3hcFkd4Mrf5Wn{Ae%Gk+oPm!`8-cF z_@9&uM_E!GLDj5SWasAZ%mi}Qo#3vlZ{+a`3Bv1Nfm6bu4f3xq&Cj<_t5Dm1x(sK{ zBJ?Sg{~m#Mh1~gNOYy63`RAyZo{&2cAbq88IhGehlj%#Pu5T{9c4uU+)vHvxd;A-m zNCIY5mHTYDO0eRa8O7~ToflDUJAHOU8SC>7-t78kfq$r2)y-P`RW$VJRrc|d<6H$< z5%lwatW3TJe^~P*BqSb^5PeM){x*S=+s}-A2{Z@Vs<;5^FtUU&sX`j2NlL(@Nxvd` z;0ZO{3=sL85x$NH_ zoRN8KIjBtZS7WgFbBaoI3Fx{6_q)@l$Q&x)`t$4o6F=+7Gixm{20>8vn#``VaSdhF z`+WvxA~rqSQg%?xS@$uetD~SG@=fb7x1La5P_p7zWuE>PvW<0VrwG|Rafej+uJO07 zz1Orw#;O`P&dD@ML&MF5ru3m6* zolgqZSEy*HGqc@47ejr;vDnoWdeir&-@EUIcbS?bvGwjh*P)5~B`ExRaJ+dvm?hKb zO8?<1z2d;^6s)YzPSxe$w~U}(&WpSMRf~^7*a%Bss5PU=auJwxxCmW}#;usJPs(DU zS`qP@y(Xxv8$D?wa%D@U7e|~#bTS<=QL2!8+)rzrEtO1S3v|$>HVb;oeOAS%MX9ET zF-ST|Un^4AB$A}$#ethe;ImuW7^yll7pdF^nd=DJ-|UbaHS1eUN^WLIZI%}R@VVJ){dELaNSulKQ$-r~1+ z6Tp~@2sD`qgI5O5EFOpQ&?MfFg18*q{yj0KCT#e_troN+se_+DY#T^GVLF!An92}_q#_ImlRa@f6ztUtTcAB{{fJ{vM<@a1^GW?S==T*eJ z{aAUuCLd1Q3L4HYFV-cz)MqH;(k9Q04Hvr0r=CB0e!yto6o6&^`;lwf z_KvEnWCO2Ww3Qtxjb**w$O7Y!03jBuT4U6RUbPMW)v0%f3nn%)9$%RA#2uw>D9ZE5 zbCDW%WF6~O`#b{s3?S3?axr9G)Zt?m@-@&teGY<}k+C&F`0}sPZ>|&r4qtuBy2_&L zqTJmy#aH(qiaua+N|Jl}WLZ#XaB{k`ZqTi*EXuj_P5|{_v#>5g3o2X{SN!El!HOS6sED(X zbMP0UZn4O;nZz>d{C}o$yY~fYqzxNb zaJO3>`BJu`6rrVFJJ;TF8$6yWH20Z9YAJ|dqxDx+{eXYKj#Rr5%hdx~iT4b-oaQ|w zB#0Ome#71L`muL({|a5i4(8$Wfu9?;T6%!m}5bYywbZLKd< zZq$$aosyql$8|qHI`mEXW^4G{_F~;4dT4gay`vfvPHAYdHj9(^D~&jthXK{MR$}%_ zSM0S}QXXs=J?oW7S#8(EG}Sl`VgA`>vWwPYn9o~Zi!pD8I0jYvG^6l9x#4w z&yj0y^(*~vIGdYL;ljl0L|w`Qv+2`7I#-+A{?S=5^i#+na%^(A>tqC>C7Ktcr9uUB zU1g*(zbK1qC^OmmwQ1yCytDmIe_hmvRli%yx9S8km-q5P%nJ+Afsx+PM!eOPjV30c z{_DBMzbB{LvqmQ_lO#she8H1JVXA)I^@z$liY|lS&pOw*)TTvpl-sa%(X;5w3nK66 zG^4pPGCJ{zNBP&vY3x-~Y+wq|tvCdw= zJz68y+i~dYkQTmjv6zVmdY3YtM8_R=Yk$N%77O}|=pK>r$T2KcD zC3Mx*(yej)s!fUZ1r2&K@%tN3g95IOmgw|FK1@`njda>Jm6#%?GvA6Ki}NCl?o9a; zEn?wq)7o+mc(TX#K?;6I!0C2kzthoc*xiB!bt_5AjW&y@x=AW)3f{#!GbI33L?>rE z)+F32E{^iUYbcSG1mVg5xvZxv!s2R11>O1Y15s3qY|fP_Nmph-t$0Aulhm8HIq7ev zBY7}L+faY;`}@WYf5XpC`f?GzV@I0&!uW}n--0%Iqvup#} zd)`qD>~~6!hxHj3&UNjVnl3hYi^mWC6`KIafnqW2GJ6n9Mrr5o!3rL$ni3wzGihAu zQ{5^B2|K#9TUh`hpl5v(1KB5eSA72}xrl%DY#+t>x7}*{H~+nNc$FD&v&Xn~djhNH zT7g4(F6D^)OABH(0D|?FN&mdzvlY{8f+px7z1Uaqles^Y_QsI-vHQjRN1HA62tS*p zT^jhZ$6k)exaSH-M%|h)^azf3w7{G3X8uVo3qnx4`W>fxp)Qy|Ot{VS>AG#^@Vas; z*{Djz-}Pf)3+K+spfu23 zgJcA?(Ietd!D#AVUwxc}ryo$e7^Bcw zVq)^ZQ}!F+RE7zr*~znF{i>rddy63jyT$X{Yb8f+ zeXK@_SYPr~_*hZNWOT2x)33&GnX?HK@-TVmc4*}ANGFi2?ve*U5E-7~mhsdQ)tE@@JEADJIbXEpxHoKkhrvmm*!BK8Ia81L{C3?*WwBwiYQuR&O<>Y_>c( z$Ex|Z09Q*PebN-3xs!WB$mZzXZz+e}M&wnLWH3q{)6IFC3Pif%pO08bx9kQvgBjtU ze=0Hy*R%yp#x>SIfV`MsbKY6;JL@UnEFwU4e;H6b&(mxhwhzDsahObQ;KBW~?&$Hu z3zUKkayDhO%){;>bPE8-M0Nwnnyjm<&z3Ose1>sRbQ8wN%fKV8bFUMthJ;ERkukpE`1}8 zBxYHHQhzE)k~j{oC=4@{J|H(dYJcYIjhs1MRby=1|JkHh*oCKE`(8Su4l4|h`q72& zE&*=v;0RCtA3=jOH?huw8$}gYSL*yB?iPMBJMU=$mTBZAbiH4x*KOid1v{eTh4!&a zdm-d!%=g6TT+5IP@l=OAd#(qD=O=m7-k5!^G!e=%XEBFG@+KdY3YZ_K2p3u`q=K$4 zDKio?eKzvon65)Mjfx@It)EWIRvgLAm7G zQEf|un=#|TPN1uMRG(+~4!w{x(()47Yf0wl^Q*M-hJX5pVJ)p%HoC=wwb4?a1wAX1 zS0FaPiwz7Ws^YRY^i5=}bt$S1tCQb^Q^tORInX7N>CZG&ps(OXWwc@-!iC!K#_H)S zU!qY>$2t8tD6{#d0}DUbfqg5+V#v`C6MFs2Z9=s~&$imndb3|_pBC82I2;vLSH8D9 zb0^bHzhs_Xekq$@ohRl_l)?WpzL0XN`ly-0kYF18SSZ+dyB52ZRZ*RxVBpm_iAsIb zz}9;EVM#7$(tIE7X!=h4r;c&&^>*r(7|?I!ZK#M$=)_Hq#gE+)EwP>I9kOp|gKtXP z8M@yl&@tcXo5i7QNUK_YrnZC&ai`NnPx;%AwD0Mp4}huN}X_+%glX6YUqD!{j# z4^LbLS*-AJaTo4B--jE`Wi(K=f6Cdc?SSxPXmsEAxe_hWKgV7Ohiu7}t zOKYg~W|V;}o0T6wtyHRG5;S<@-cW}*sr(plwQ7AD;lSoSJH?YW*S#L>73J!NIfJE} zZx*us>DNU_m{jVmj62?s-r)snkvHdo&ax9Yp=<4k4xyCTOtYr*Eg^uUjdZ+gINelD zpD2$9(>D6C60^6mu^qNWk{1W{z@Ohb1u?nnHBn5Ji@EHcZGmYIA81~9ETnBnR-$YV z7$rLXbP!CGy4`?@dn@KB@ci_JxgM|734#2r>wPdZJLLYvkCp)aYddz7{pZ;BbZ;WjbGNb@Rt168RsIqjHTjBLPt1rn zKOgD_dI6t;+fK(A&(40O7N+!4dbrQsCoQ9DavO35u50Enjd5eOnJ!JgOMu2CMoV{O zYHTo`;>4wProf$j1br_6OQFVVR!At;mx;9*)P|jl#W8shR8%-djOgP1zE^!CQH+S-+dosPF>kV z0oy5Cn0)i=aBnxm??}MF!-5t>*fSh!N!pFJN@B)-3HA|&E3aYNvzpZG z`<(v&b}B&f(zZD|<$Ae@scLhl3+MfE&BYp@9q^GXTT-=qtQ2>LX({Ih9J4m0ykcd} zhqf|yT<^~)Rc%T&!#5eiqS^p<1$AuL=<+iwrUio8zLfd{ef8dwhWc=T^S;o9Xv{!- zHu}%QYpuaw;7Pg%IFOU^=bM((3WMSfF>k|DE}GhTui_<)L(c77 z1rO&jX*<1I!nWU7zNChLs@}lrnVu*d1&_s%>fG1vxk@=Ze_HkOce zk1os+)@du2&9kl@hArtu?{v(XH-ys@7f69yQQSX+eh_%hDx8p2YQ-{8JCtmV%UjG{ z0jPJX{!rj6gYoL=XvM68DAiI@b(K?ALCQOLW@B}9h7^`G!E&cLn3lJW4T)pGgZ5U9 za&x(?DS;*rm}J^a)F#r0L^)vopgsnCD8r6>ZgUi)%iUJrm?Yld3O6G_KjQmhJ`vz) zG3~oCqPesAL6-8YUYRw03$uc-FWp+4z5cE;*dk%BGBB}dc|MYII;~c3VQ0NvWqV2MGpSS7{zNDIQgIm);K|7R4lWV~T zZh9*IdXNqkfHKl>x=;Tss@?v*kRv{ZH;SO_YdeI1kL1~jVxFLr!jbK(xrAIQgebd^;^1>KH=D+|WeS8LR{6AP+Xoe_+x3_fbrDK2aZ7xG+b5Y~*4(9**$ zASw2Wv<$AB-PMrbL}ibmwfEbOv=EKdG)ojW$f*$X7ua0WdzM&7ztQTs^qL)veJqMl z`}E#@H=h{(F>$(ozbgE8o&LIq)`sI&W66$-ux@R`MFb*5p}gI?&maU@lln&*<6DQP z{#`)KTx6K6sq4ffeyTqG@S?(fZXq)5FzK)fPZTfSi2YWGnODp+n#k@S3cV_Jj!I=| z?T)c36E<)*-x8a0c;{-0sZzH!?D?#XjeS^LBvQ1>45m{4Jx0h%Al6(ko-W`vi`HY( z>#vCXG3Qr5%l0`W3(}QNXRIyC@7_V--I46Snt?q{Hw&z%#HOW25N|g%9aR!kMMtPC zy4Btk5#qK%EMro`h|7v9((3-qVK%w-38SJMS5_Rks#9pITyWyYmJ<%BO7=TT{x}xO zM7UUBOkmQnGDYb|O>tlUGG&WE3?8dk&=?h|>my^+w`4&sVn2Lo3>t zOX~ZqpJ2BmD~a9dLh_>MawI6U55~I-pQ!xLJb|e^%!Z%Nx1Y-?q@agAj4gwsmUE;I z982?T0~%2iryUXoMQ(mOK_vzU{9^T`OIY<<{s4Uy5g4z`{`$z>w{JKoc*o7_W{xBo zuK1#0GCl)qRf402Zb`G@p35kchQmy6u~K(pwFZZeqn%z=c450gunaH#YIjae>~zDx z;v+S?s4wc?R?y znSXm!Hdu=pq|q~EHWmeGStDA@5tL-smic-XD|&cMfxJzfcnr0E&$&~kn0?Nt)Ohrk zBPH1pQZRIVEP|^TW!2d>!ncXC^@bltAz!-Dtz#IfkzXF^A(}SPyPm0L;&lDy6(0k9 z1Ed*O3w|_7P~aLFnc7S|p6KvpmyQncKAdSz=bjP#7(md!A&JnLw8V7584he#-_1o8 z(fJ%xRj*HX#%Nfq(9&E-u)`|sJ}GPSq{?iAwi%)P?w z{~);jH7P~+z_o(GvO#-x-^cIQ_^HW53Z*52gBvm#MGTBVKhvH!oetjzf^OqY))I`6 zG2N@5*q?cxk8>JG=uY`(9W2n=GfHdRP7VpUy6kk!D)SFh!4$`PSbw>?hslJfp}$J> z?I_SaVp{6}+GG%k>P7yD+hu#(Rxi2YyYAld;0iaqsOT^5!kl-n8qE5P6-`&Vi>NXB z#(N)bpt|4!rkEgvp=VIzz$Bp5$rX;7ER^*Su>Coe?w2q2T-Yew+cM4xN}+M2Q+T4T zJ@TxReaBPMMZRq>n#Ec_N-wBV*r0KH^7$t87}svPE{WaH3ze0)78L}fWKvgXjlA64 zjIjlI-kz8=C2P-xqkPtdj1fUMy$z3=WGg@BKH}4!6hkJjbGh(`K;p%HbLO_gh?3jI z?uq4_f@kJ^% z)jMxA+tZdSSa(}AZHPhLPo2^7qLg=Eb5q)n+EKix;*lz0dt);? zwD!fFrzRLrNe`*f8y^P6n~42gss{C^9OPU=*4r z=3ABFKUQD5H>sil8&&X0@{yRfCJHMqSGD4&w< zd)J>dMFRuv>XoS8?I|c}jEOBtvVJwS`k|XNMxsubdxBvb``*^3W^qb;b*}A2{aJ8Y zI~kmyuKiOXo2&^kb(3*Xig;G(H@d)8Oek;1Djzsnq+0Lx5k}#?z4dYwtvk0jHA2u6 z+vv`ph`@}upc76DLFe^w1W8ai{R=|S4|Ou;F0fp$ncQ(;wYu2PIKOEd8L8=-Cemt> zB&VC4XcI0dLVD|jI_Yb}&nP#0=$f#2t8Igua9`Oh^dU4I!M73?oRo&xozXO8jze&} zObVzRmXC49D>Zm6bCr#n&$^(C=wu}P^?$kq`W(L|=4qQ>n6kf5PWW5mOU)wK#g}}| z^-X9y0|{F8q-32ktk~!fxXl|g>TPFOhSiD`oaK6hI8=anW3PhCgUU?nSKTUXHN06r zkIN7?`yKBPbFXVCq4=c&+fFw$n}U#{>+1$ykb1554e{#!<7h@7#_G9J%ulN!X+7+A zcs>T}xm^Wm*q#LUD-n#b4-tO&9~9Vy>zq;0W0HPNgoa4QRQL470E_P0<&Y&=DaXPS zrOX>W>+J8}ue;_X98n^JWr`CJXxPg1o|qW<(2s1{+INCQ)_bfR0H~KlIqRU1E(=qA zm-s@`$w)>D2cIo(Xza&{$Y$i|L8Jw7Trc`^L&}S?>7&g^?W~rt47C?O6UZAFnnL2s z-KWgm++4TY!+FQ*$YT&EXm%oywT^ZUC12vA$>BVwmv^wQBCW+TCZMY}s5YuW6`n$I-KM1V*iBMTrLxHY zFpk}4{V3^U-b&`ebF1D;Z|CB1#4GurR?$43`fYqSPax|PgK&kpv$vZ~X1u&48W zfYxnyH$VM$8J+j9oX`x9{wa z;&iX|1rO{j1od5!S6|hh^_{y4#E2L7wSEbYVj%V>41cakGkBleshDuSaD^P=xRcmg zwz|~gpFpPF*HpkQsax}dpBJ~suX9K43l85{jreG3cauad!XOd0=Vi$V6&}8EdfFv1 zC)dKWyMZR=^`;J_B`!Qu`0o@y5rummSKqFdEDu$8!xYHJX`fjr%9-jDocNsXVdvmI z({vffyJIB}BB}>{_vcRUFbp+hARah|{?^_m|ys$HCwA68l@Q8Ic>wJB9K`uq$5CZy*ucctkhF9T|nGPj2M zFlDzK%&k8>b_47vODCJ>N!Kec+z?(*nTw;Mydx0#8GHBlm3$BIGR{I+TN1Y*^9*)P z#_WE_9VLSzrzdO_B?q;&_H&U9`{@!1HYtARl=XVHh?%V>X^fNIE9(!1I+xomrbgMsg)6mYKJF2tw3S7nIbBY_7;I z0e0V+&q`7B9ZTEAsebz93C(EUDb)L-L60}s9jh`G+oEaDA-k$yu$wm^9 zQ~jCQ>|J+xpoKfSThKJD-2{UDd?7qS`FlbmK=15`GhgFXXCKzY+F@q`O=*U63=*%T z#;vAqY)^!!u{~w0VLyN-(K`)-&e0SFucqcVpGGSjl;l=bBVR(l z>GIK32_&U@)>R^{M$sA@L8rSKcMmL?G z#x@UN8S0|X>Z>vA8Cdk)jX`begsI-f>U9(-XU!d4Qk$@oNX^Q^eOkx0P5K7xhk7w; z#`$nH$qI9cdh3S#GmnaCX8~!UUdFQ-N**tuVUNJ6-Z1G;;Q14Hb^TpT%fO>_aUYlG z?1=YD0(f@Q9m@wCk(u{8)I)cM33<~+dzIK#c_-|D2@7wh<89p^1rQ<;4R0&i)pMd`&Fi+%RD5InJ%4!z)(GpzmMhpEGuB*e}UL5Sz^u=WeoKG}o#F$I%=t`qZQJ8)w~ zUtslC8+w2H$T>vpsM~t1G0@PRtM#zy_^NVZxF6&|J}Ol*+a&+?Gh}4fF1T*wG9}r~ zRHnu4JdwUA%Hwg|jdc92;xPm(vH0+xlfC;H5NC!yXBd2GUd z3}W(w(|guYIPGNFbkdH&!FBhDXQ9zJBAcz&+7W7MB|rPdogkLVceFET{sc@nU9f@3 zy0s8oq~GB4GqL|{jVv|))#2gl1R*bjjC}JJG6tvGX(*}}ocZWf*I4;sW%ApDx%_q7 zT)!;d0p^1UggCNA{QNl7;%L;FSKs``Rg=g6Jxdzn+I{=f+dXuy%m%tpbIdu#@}Xc9 zC@m=71_ud<7-dxW=8;A2bA8KNUrZm!d-3S54KCf9sj^@vo`FWk?OX+$7YN)Ny0_%6 z*|BtFRctFHKp3d&W{Yf#hK6eC3K)8v-cw@~`-xT={ncRW%rD&x>&XU zAgLubBhy}x*FQM;vR@XAdu+YkjFQ-p8bjkk#cIXeks?fpwTNF}&Fzuij13{6B1!ky zF_XU7$h!n10oJrQI?D$CGxac~w-T8rF1jW{Mbz|0@L2EpjH0~U_bleY?x{^^VDbB} zV4I=m>*3$c2P=7$c#u_65}y5mhoG8>jnnX1*vX?}(DmhC5%F7A;Pv*7mht;&-{i1V zH^z2%N_^6DO3MBB=y3A_+2#6&B=tU+=3a{iIKPxXKpBtZdCcxpT_{Mn{&D>M=!TIw!Ry)hdF zD+hI9J19d$sex1KHM%0=2RxXaR3UuL(6p%Czgccdl4tYxGyEm`M%W5mE&8dDAKVesmcRpw16z>%0JefT!&C=lVhdd@nbs1_ zk}okJfaWTNl}Te>*yGMj%A~L9`QVphL33+n{RygW_M7J3ni9E)j;?kVi;!nx5~<(p zJ-z_F$~As@Ibp%3v9{%do4Uf46**EbzSok}zg|?nxC1L-zgAcYsYJOsw~h8rms`{7 zO1v9)ixI$S1NAtlia#q0Yp#(39SI%q&fuz-^*@{6nFn7KznmWtun==92b%w7W1a>7 zaEl9R*|wF;W1?%6P9g9PdkXHoEeCL-jl3Gsaapl}WlWjW0fw>kd*H=kSU{24J^A7w zU^AOF#v)jEdl>&r!ze8}Nz=fDL(E`pP|m88U!}^meSFf9r*P>?=ng)(uy;`8%QxOf zFQ7(ab+1WcTzk>^!3t9*VDIiv4iYwZ$%TO;9T3HaB)-;k_qi2la;%^`i&7>=X5e56 z>=MH>m#(v4ay(@e-|5Zl%bU6;%lOWM8!wA{(}wYIz6&^~(oij$8p`BhLpY%ekjj5J zFKbT)wlBPHO`D3ImfP;;lqXbDlEf4Yk=P-dBkOA{u@o;*{4ngv<^CnL7<1!rI>m!r zU^hP58>uTYL{A`)*0+7SqtW1T`lZe=l#6-(u#A<$Sjqbfcgnk8LPGObvdQ8IqgD6> zgO9`TnHl%9vdWNzV9!J*$w{yRNO+Yz z?j4@WakgpTQnpPa3r)OCBYzh*CBt_gj}&8%wmIN%ax;ap2PC!U4GiIZinRIzH$g}c z&$9i>L)m6Rmb%Wk^m^`I8_!SeYMkTps-1YEVB=hT9A;ctNoz-G{`{$N)TI=$n^Cs-9vPs&Bxfj7k}ihG zKhLz5gtM1JZ=6X3h_Mp!YhZTtX<;RG2`uY1kAV22j_q+#P%>Svf_M!0(O8`+Nz9uL zm-^6Of&;UYt+|R1H;TAFrqDXp>n+{7L5hqcj8x$hja{;N_oeo>Z+W;eRl82g#6WE* z2q(o_RN!9T;+Nn2Sf2YaJ@+yFk~!em$VeJBvVV=$}eVnO@5tWexq*CGObwfN6!*0MMo3lx)6 z59s&b6>)oT#i`e}Ygr|iG}mhq(3P$2SfpGJaMef(=^X%RLRrPgQxMMJkor)pF=$&{`oE{IjT!g7N(gns8U+lj@0?ZH8#@S>V zASfwDsKrucn3}$e4bU%ig)@~019NW&Y^%!3I|aBGv}G!V<3UEZ45aCTYgQ+GCFaxr-_al9>3{l-m^m4}$F2z(}1So!1SF~GpaB2A;ZeaOH1S?`IgVvHAd!FA_B6<6iql3-ML@-{YM|IgG%0nvR z0pOC>=P|E>JJ~oW?vBS)!q>`HZdMP_-yUMH%X~=FxwRh)Ulx^+eA++HXMr31 z^@W9%{?AWbptyW*S;#&;tf&F`sR}@6pFWWRG1=1I zHs2)}5WtJdz}b6>&gA2{fzvT$zGXL!h1}@fYJ`fC$w~mSA1pN2(D!xG2sIS}N#R#B z7HR`B;+=YKl|g;~kYTkos%VHZ%54I0Pj#mjQU8vUfOQ-Pe6kOGJ3OS15eDMc9q&RH zcJOhZ!Ki5H*&jWEFYQIJshN%JXtBjCo4ZwFJ=R7UXih17qdzQ+liQ>`HBL}Bj%u(q z5%p{^H(Rxdu8)A}drIkU^5-HJ4l|}ZF|v`BKB7$Jgw+UnC0VJVCzx{O`se_tIUXrrr!EdDyNg|K#l8`FXzPH(RK8HD0>T_s@JG*R7F5(0RfSakd|%`1O%j0Lb|)V8>B_L zyQQVOyK~ds9n$bU=sBV@PhvYqm?<1=Uo?Y2x_daA4l5|p}v*Ct!c&IO$t+ehj$Ifchk zYJx7bUo~X!@RPw735kB%s0YHw0lWZqdWNnpd1Nn>E3ujPUrlb*GFT&Wlc2b2CSvMZ zrl0213!0A$=;lmY`Vj#c{h3+NObiI8r|VFLVv`=Or>hCzdFvHPR@STJBn|e&VeJ}a zCICMMIoV*jhJq3NS@WZU;K=7rMV&1cI6xkQg0it?cxRo93W)(Qlei#AhVo|fTnh6L z4esLkmGc-h)cB*^&?|M6(RxNQb_V(93GyxLR-*j_^b8!GqPihlr&PbFet1u9WB5#M=fYoLJTbPa=9Jlj^z7(YIBN2N_NZ{3EJsVPC)tFU^ax%x?#Wjl z+$D!3_*9B5pL{4ry(lVzAHvF0nu?ZZ|EL!u44NACgv8{z<-O*ts-1)JhlT&nKh^#W zR`2P&bV$x`GeduOmz6;+5BRzPqzTgA^@F&kf4LmjKyq7bOq_;hO)2^+&;z*;Ahczo z{krHakS2g3h&DEizMhOe+W;Q3%Tqm~I)->BV@g*R=@CFt3t&#)PLc)fTA9PO3<#+C-g$;qv+m4n; zWk}FStCcspd;Q9hGpgGBb>#CDwyY6@th~getdTO&LEV`C^_aQh@DE1uYqm0&V0Xb& zeFSKI1RwpJeD5-BzR1uMHCVJ!0}@@`m`|T;rb7T)CJv0eFwn4~;4X;!pQVS(V7esk24`HZ!Ai*JMVi-A-+iHoMC7{iaS_$#oV>Y22|H`GtbGo1 z>wWXs^R9iV+$xz87scg*6LVhzu3hu3@)yK7xt1)4^}LzV%O_TsJ?EFsVF`(($(7{j zkKFqUgkj+V!?=sDY}v66lA7RD)UYN#OV) z;4rEUtDFi^8{)gQyH`uu{e|QT!15sgPXw|+3R6<24d~EwV7BrIYTJQxUnFX67XLIl8inSoy+w%9v6#UgJ}wN~2DgdAbe+5`n?IHd3o9SjhlDOJdKJQ*ka zz=2WnwAQ?Nd|&N9Qo8ajHedAXfOe^NX=HagL^{1v@5G{jJ&w`~`SfAp9 zN^$9!`p`jU1GRz*^+Y4_htIY+x+AZ$bQwf5^(dQ{w$J5fQYUnr&m5-HT8s;Gu7xLUH{F^e!rcKS+erhL3D4Gq#!SlDnTTz2v;) zEun9iV)pSY7?^(jbyDjy?|qcdWZv!ql&aZUSrImR0p6r+!>`Y+=}9_jc2)p?lwDJ; zoOHQv68h!6h9EvgRzAFlct?(Z2Pbyrm9?5*h~&EmH;2w(xWEwr9>5-##ZTkF$l}0u z;9DBb*NN4&A+PO0%>+!ATJwgW(Jd8f)^g6_5#UH_v+*Gw4XMdW!)Mv3dAZ)^a1~Lg~oX4N@_WnF{_~B!6cLF65*udqcSu9H(*1aB^>+3jbWd$$N zk;P!uH?S7dtsRrtTc|Ju{1afQgLKqZ2>*ah*E-dYSE#`r&CzR5SU%MP;J0L2aKy503T3+LaI1$6^^-G^F^&fo@&;oR0YCl zn#IL$gENtX6=K!9lEr}$J()cwk-`zekuy}0z39e1az&&-q3d8NWcknRb>UMX4$sn!g`yDB)NR48kU!M85e# zt@efm-@VW^k!EUj&+vjRTK-%m%&1Q*?&*!{&Aj2z;6^Uq*sr5mVBK`hB_uj2Uvq436XOtihPGo7TGh^PH0>5sYI5<43jJx*U}-LUg!AI zvm=lN%vy5BgOBd@=`02L9?`O6*TFqYnjmD0^qJUg?p8 zm>j<5IC=#735m!=@)D1_)-AQ+efVeATYI4CDKAtdqy7$Z?8>vO1Vs&0@pzq!q$bGZ zw;N!_@5HyaOTz8zz1+FQKivB`gXy8!u)wAI$UIFObrg{$&a zghh0`knb06GfpDAPb$35M{Y>+Mrdu|OXK(v`juTv%Rs|wR;c9j5rQ5E(@H0Z&eW3f z6dJ`GbbVk8JGi#WduFFg$9cU^t~oI}=vBCAIxKK316@g>YmYg)`t1te zz3krDdpiTx*z?yaY>6u%`mVt1y3p7mpt@{3X)W5l3;nZ!>d71tUx9w zZmQ5?(WTn#YIv97A4r$)(Jx{l-S|(cLeBB1Z~ExfEs<{uL8`^#^8ZiW`B#G;T18kx7Ro2_)eXok0ExnH3eJ zi^kPt1A3APVG1*TNo=O0Dx1;=-jB~q%=tu=k_L%IQV!Pf1;m|#l)=68c+v8eeV#^_ z@UxCK>spK&4M!@gRQPpg%yI|3-Y?H4unK!F*o){pk~p5XsDU{+&XOA~786ZPPCg!! zm)J!gQ^BFsw746lKI*krSHdy1#PBg%YSD6cPAxV^i!5~6=-9f{a=$eHtkEE1TrNqAX`SADsc)*UIv047f>s|B{E zg9YveIr(6W$nf~)I0!1k_!;}ptZ$~Z zCtRj4FCWYMt5u5KRXA^z&4Q_vh1r2Vg4crIPf5SSH?#Q&7IFIs$%n#LiZQGiXI592 zjnp$@G+WmS>8*baCEk(;XHS1<*B zlivkZh{~;{#98nLkZi0evnBl`QSjPVkUa7wo{EWoqxb&5wE$zW)_WlIFbsAkrfbw_ zz5pTnL#O&xcxJEe5}(F$^&^CXDYm}3Ir1zk5;cyO>%F9eq8sC{f6s^i_)#t{>VH-* zSMPH+;VUtpSK+w!Fkcov_#&2xR7jzwbLi<@Sd#YE!O}6-d%*7mfvB3arMEn$wF<;^ zTs($12y^>xYpWzw@IHAgt>C-~Gc3Fg0tBpMk(4s%qr z)fv0Xitw`Cv?H2_pM$%~#exVU_<*X6N6(;dBh?Llgzs+-mJmf~8g))y-cCsg9Pc@o znQ?^TTG74dkYDNf=f&#(2C7%t^_!PQ@#0}{xb&S^cd&k^PbWMs4>v19Y%3}RpI^B2 zdJA@fXh=Er=Z}TFpxIkr0$Jg|Qu@Z(j4|gf6Rd$Is_jhfAJ*k008YR&8oz?N7I&L&-TQO2u_b z*~Cu~&C`(Y0t9S-?yV422A6Q(uviOBW6j){j!Zm^q=EbY%O>fk~Ho@IA(-tqTJprBW6JsCb z8J&j@bJ(8;bVYszH^i4PTZ1p+zuYWO&q5Qz*Wa6iVNdaYZ$@~SJZY4JcflPcmbi4tGefxbhfm}l zM{5k#ka5-&5cw`RQFBf+#7Nr97EV1Ri0=gVHzv8xV!uQa<_|S&BH-7XxbOA9!sDLl zxo0c&U;Sa%trNG+XWiLiEl6bjzm2P{A{f!KOXpxbpFc0J%-zBBx9++yl^u%9=%qds zm%b7L#U~2FQVqa0ltLQP)i|y0PPL?$UGKcScaAx2Df;w~?Y@=Ifhs`sQ<|qDwdpT3 z3;J1`F2)#d{fR;H=1;nz@Br!$s)p?}vF7OP|B(`a36xoG-0_G{5b_ec_Bfga4@rW1B1&UN|Ik<^9# zpKRW1?Z1|5dmwOy*2ad)if zDP5jy)PCBa;nq5^SYohauM0XS(_%{oN=P!YHnCmS^m6!SN}rY9{;E(nd2A`R*cF*xb}kusHZ!G9H+uZ84a zoSN)@bXRL|f?*enU;e&MLGGa(^qq{o>;$Th&>9G83*QXA^QtqNBr6J;IPuqGVPIXU zC8;#Qf-wPGcKKUDLe1D9bVL%fjrzf3l|9dWeub7k1sDBCWsb%CMUkSJ&RKrf7OEq( ziuO?*`GQ^`arqgCIX`sZ!h6cCwOIQH=f?#ZBR0zXI4+it$S6x@jPj6&ap6aCgNI(i zqnR2$d92JUX||ylC}O!V*`D zr_MY9i6rm|N!We-=3f!ppRR?4#Y&FLdY~}9@PWE#Y~L(X0pA}phWhXNuCC9HLn`Ym zqVe3+)tAmfK&gg}3ol854LkBwuW#mh9tKWF>;KjfCzD3V$a?I*mKwLKx_zcm7rwV0#;JFf-@X5ZYjXt5l6u^^tbRw7tl zXOZ7+G#3!-)l<4IfB-I<3lyl3e$=ED3z8?+f~^3#>Q)*!Ko(#mmTj3x2psTq(Vsqa zWg-|Byde(Ce=Ro3Ar00Wwce~wx{DkWjmerfFTxP_Zw@!t70`=1HEpRu-d&b}NO971 zz9jOT+mgHSSMK0g4Z31yMY;BckCT%DBKk%6f$37Ny_MKbiD>w*3f-EtFnDonEa4C| z3F56+I1{dFzlpq>_X_rJX07@O!Qw%|lSka@PM;<#aKK%KmZZY0&`Bb9+E=JghG$^x zCkv$>fSELTk3`9OvW9ALwn}nK8Cye1@c$|=<2A~^Un=ag=wD&!Ep@*)ff(DcIj5+H znFoCVySPdT9;~pPufs0`)!%)YuhKJ*xeFr(sl+eQ6qa*f;@RYkN+P-Ieo~p}hM4Pp z_ui=}jG@X1G#HLlkn2&XpJ}ue^@|K7*Z%J+D)6s^XDI}8xbQAsFo>R8Un#*{`N53Q zo|CqhUF`w4DIdZnJ1n_&g3QIO4<;R~=V!N+Q*V|2zo?%Ak(a;UGM8W_MR5o95Bmbk zvn({0e}13hL<{bFz*l9f4L?DkS42;g?N3Xxk%1-xy&OS<4i{@h2g`gc$R}lXze@6% zT1k;@WXKBUS62UPvq3#@&}XPDyS+ItD3JXdP5$&C!FIIGqPm3@KL7BM-hYh4w)2|a zn~d5v8jN=hN~-l}tDthvXJ(CXWW;*-a8n+M;^F?&k+@!st`2CVq@K>Z4XPDPdKVyR zM9aQYU}GRpoEW?EUlVTncU;W}(&)qi3SGd{f!Ysy&4?rq4e2e&GzRr==_zgb*;oHB zD$|=se*)*76-_>m z6B%e#vG<+$;IZIl_?iZhWvnKHrSG>CZPY|}5XS6VY00~3Mu3~QT@Z()8_4~py&}zj z?h8GQ;KyASP^Vyf1pAxzB|sxLS{{C@srCQ*gQ(R2pZk6a@n(i&<>rbg`=W0N>F!AX z$AnHj0d%dxdx!?sBanPEGs>dG25k!KOHkJ!0@J5khVZu2pOk`BkWBecVX#r+UtA8f z2UU_xf!eqi$QAs#6VTv3nt@QvK;?cl7WMfa$nC5PuP5Vr*S~k$wteh;EXne=GsnhY z(p!ZJ6-1^1Z4>uh|?p@aw2?h|57?{$5W!WWg(!L_qL9fbX>xR5k z!+F2QG1EP@Q`GAQv3RKOus8NRXmG@7rPVhwOrgXErM*iN?>X!@LzIdG`B7KU#s@P0 ztCPAYbj?>D7gWCaM;$(KZmexHi|2QpsJL*1eBQDA_|b4*b7^=?)G>7@4tSK5MXA(X zeha^zQBPKjhpLA1lcA_P8#;FDfa-{g?9Swd`L_X7Q;@i&MlS0BU@8>3Igx6;k|+?V z+5i74egCapeX>i3b61qzq!uZ9CunhNBMAncf<{C+_I#ji+gpHD0{c((LznLfzT06v zsFZDbD~ANSuFP;8{j-r89dF^#6a}iN2RrfE`G=I2`}$tz0)E=?uP5P9-OD2cTvAJ_^RXI#L)J2AYRrt)(oC9)rIW?$OhfV|vd={^H z?+Z5G`#J8u(;qFAg!y7xWL<-97f@Io#~RYGe$B%ccQ?rmmWh;T)vQIeeLxoDUK5qw z{92h|OVH1;5z7DGNxv1OY;P&Z&LHRvN}v9UVy?;`QT)5=s0-#Cl=N`xVO&Z!w`y#l z?sNov{lNo-;s*`)?VVjoZh;OYbH6vFRX&Nm4OAs6-?x0EZnkE-X>oZ!I~Tiro;*Fk za4S|$Z7>cBJbvr37d2qa3#ctMX6}`=1k1*S1{aI}aYZZ<{}TQ66jyZXf)eyyiuQ3d zzukkKtS*b5#S6FZ6_3n~DWujNl zN9ukZ)(4QNbGXK8JkNNNDc}1$xs<=+1k7qWP^Nb2*{^OHbobG6i5P4Vmff-ZeGb}U zfA?82=Qu8^)j>P^L)StI|@SwE12BJP?%IUYSbL3 zNQe)e8|ea({>n)jO%ii2Hii?0T+caX9Be;$j7;|aljD%9i8B4K(Z~@^vMCXyN%;>r z$+xlUPt-j9eImd{{BnVq|8>wqjVcZRVpp7nhW$^(%HDDmJeRw28Biq^)7>`?DjpRd z1Jk8p=>>D8VDwXAL`)nuh*B${#Gu6@(1#s>9wShC7l{YP8{eK}76q=bf=I?Eaq*)T zqwGie|Js?wMpmTf2aW!vE41`n4~21ehE0s|gOgQ`fB2)|f9Agcqp@|LKD0*o=Bo+a zK2~(2=hv>!dGHqwljpPTpd;a-#ir=m79E(EC%A0me0EL|?Siyx-&_6d-TDnttEEGr z+^%MI5ujWzJs56&p>f!o7MD!u6u{@kGJ=nw_^(GOpcoG%1M^@+5B`_AnWy#a&(r+f zeF%}Pc#YJkJ?)&PZ<({3XTwHVIsm%q3u-G)eqHakX~iaNzpl%p%>`#>$=2z(0?PKC zD2#le)+}RJj$DtSYdgS^z3TLkz?%;0{Jb8G$J*+4yDqMZTTo=9xFZfKw1$(oLVle- zMmfEHC{BEd2+B6g+|GabXa)UOml|2#gRUvvGPV(R-9OLB@E?k`K6PCvW!uAYE?q7B z{fLYclSlKg2Rb57=m=hx5Dg>2AWVsbhD{q#iy2}*!{3^|;IhVA-%8Y{V>Njc_O;6} zie?H_AeZLXLV-k%23DPAUN$HfSAN;)!F{!lQKuWL=5oOZ`eolggcVgLYN9~V*f2{I z@Cz4bpHrR8i7Z$wB*vJsfO>(WFydQ(DPYfnVoBBztMPNYnSI>dg?g{fB(63Q(!sjI zncogY*v{Xu4ulqrNzwFMI^6g4(<}%CWws!1XF5{`2L3obvSXTpRc7r2t)FZuG^U}@NHdifV=rJylS;AOhGvLP&Rk|-Wh+cSMe>i|{5SrU5*vorJ?ZIKyz;)C40z*Br zBh5#GPsMgZREDzU+THx6la`tswh3((`*XD{klMld+1-wv+W3B5mRccZe>5{xd5D~L zcWIswQ^03*CnzEJO;9VY?wEYL(ueT)2{F&Jrbnv>C!F?=64+u+2H0Q^90ncS4i3h* ztP^UcdPELz`)tCzW0(R7nv=OkJcXiHk>{1$?E#um!C>>J{>XWgSp74?H_x(9fGA8q zXkG(z4yx4}%nfFu{m2;>b6TmJ?%{SlzENtD{*hh?&K}G=LrP*7lrD{cBk)GyeOB^} z9QJLD>@)BSgC^tVFd3XbbM{K<_kY54*g@%L~j zcvI3?;|z)2y4S&JDZ|S5NrDUnC!3M;uG7~r#P+gZXA*d_`SL&Soc5KWOL~2K zBQU$wmkDK!j4&*z(rgv_o;A}{BvTq8H27qs_Ik^%+UiuulJq1?n zArcwybUMu=EO1ihi~_`2cR0cAUq5Pj6G>?vRb4q!36tRvV1=Ltc$Xm$Jg|br^+n}0 zYw|G3#m7E(N}CgPL<>E-R|uPDUl3~Y_jC#b0=rWL)1^vzk_77U3IxLU565*mT+bX; zDrDrd$1@w%_EyKUCt-&SnXs(wR4WR)J;cacwthJg#u8!&hJ7OT@6dvT?0zH++j|4)1yC)~t^J`Wef2(X6VW`R>7A z`|*{>&j?JZPDI;MCbj7E&g#VT#U^*Q)fJh#WTFdZ!~~$=;7HOR2d8NlA;Q!nC5o%y zkEP(h#XSvwj#@J(hU1+w(Yb9EA^OIU43!{KI=Nqa`$WM}-JCJ$P1vW5oh{;}PmHyN zR|zDyvn1Gw=QYYyTucrGce^DRT-!FsYRHVMHLRL20Vl^fjCx>7-^@r&ZtRq3T6pph(hRgiD3;WD6FJYSLqm>^b3* zcwLq86!oe~AUNU*)IUz#H~f}Ep6IMm!=owEKkj&M$iamZoVjCj265sngvk-mq+8x{ zmll-(9ccyG_nCLgg=gyS z;P*s6@c0UK*b(SOuhVWyM9tikh7Etl1Z}^e2p@LuR&O(=RToCiqQ^env|$IlPoh=x zE=Oj@PdEMXt@nZ%G1}sH;mofe(;*1&W2q8jZ7nQ$Q8K0>c`$vCAdfz|k1_3S`oCHn zOA)fEH)3#olJV(9tcKrCf9VSy<#^mP0TSJb-k2%2!iLH5W_>iTJnOATN^f4rz^9BG z(ry0SIxxg&6m?Q7s>M!;uQuz7Xik|FcUoYO;>4{(5BccdwhU?31uu3ei}4e zb-fugcA1w>up?iE>mUL`7eY?`urYZP6VL9EG0cGI99~GpZOW|s#-f_}-C9yx_^XgXr#64R5C0PykYpP(rl$Ui;y{RYwbQJ&2uL4@$geALW z1^S!<#Hd6#fiJ|kXW;n9np;vuze%(5lHqi#dbN)fr?&J~+NmukgKB}1%Ti@b!CAuW z{*KaPX}lUIA_wLf#7QxdaC;~oRmX!zxGr8+axnGce(l;Vy387M@x^gL3Vi~iFiaoD zjA^qD@DXByu6B=Kj|(p8%bF;4tZXHR%XpHdm)P5WL;F^*_bCfjqIo=}Z_GQTukTTA zP@A_=hqdl^I$0M1*A*AW5*2Pbjy#9BHwre3-t@V+X7roG1~xLDhKTI%*%R4mX&5&5 zb+4ImLQq3;O%5c91z53#U=ur@2@*c#ec>5K>mm8+mJL0sM&&`AG*v&*<^oU*V+cr7 zFN^6agLIcET1*v8z0)T=?_+cFwo)vTrhAVz2lJoSRWR z)SsErex1Z`TRCUgM_z`1YIREffd3pb+}m2{Vaua*P$P3cFR)J8f9NvEmA%LZa-Cs& z6~};E2lJjJ{mAf8vZl8kI|PT3RV-uJMInOm@5tJ^NdE*VDU8omAAZ9Vh>C$O7wr%&4L zE*DHp8RZRoS>)GZyWg z-Fzr0Qs=?>`z^X{LUC1+(Ajgs9*U*A#FW`iZ|)>@6%T#Wzqhy0ZCX$L&}DiwW!#}#uFmkPWah_IABnLpgKa)^ZF|Dr zMF1&k&^1)h^%MJ>$DFR*c*)5YYVJ}+(H3r!>=Z!5e`T|6WbU@Jp=&@HwW4CP3E-zY z2Y`wc{}%U69#TkYR@oE9Am9An{_QtOMhxwp%NCwX=FAM*Bn)CCy$bfcq~>I!kk?XW zLi1F7p(rfrlZJG$BZ{V^)~4~@$JFpJ510y8D+rn7A3R*6 z7)gSQyo9)-6$IP{TzxD$6-8;O1C5Sa zOi)}}g@Ht-Jba&_)h<_wDsSwT^dnA85b6meTCV1){1{{v$1lSl={+Wkl3urJ;rR-_hgh|(oQR}6fEyh=_gLrGj763ehWHL8GBV~y1tP8V||+11H#LYBo~^}Gqgb}iN3M5IfQwe6Azc#dnQ zH5sI5yh-Mae_1=8hx9=NRuZ;VqvO_N_dcNAxJR56Zu|BFt@W8(JEr6TF6mveJrqHQ zi|f`V27HS#V+O3y7m~ToX;NiaV>B2^&o3L-p3TNC$!wtv9%+VIv}bm1v{dKSno_Y- z6LhbGA-jIDkH$nfI*n;X+0OaG^lQMJr}Z<5yvFgS%#@!NreQqstBsr!p5o!lz*pjD z1s_-t~S7&Y(=+;7j7l;a0?HCx9#!1WNN`%5E?}xvrqZMi^YoL##gpV%;~O4{Q;w< z?Hc8xan$r-qNvY&#*LN1Hn3Zi`47+BXmebVeV%>Fq9!oy(xlJQW0!=A+QleipYdq- zZq*dCbBxcvy+65dws+>?37t2WAZJy(k0NkLW$MZ2QU#=*y!5=kp9-xBYu%-E#csZ?$AW79ZE z`Nc`k%~V5Mbz@7#DIWaHTqxrwJRP@>edq9eJ36qiUbW*R2z|>@ko>KWyDMk9%4SLz zid+@T&g=$|Aa}OMRah%wr3oim+(0^tgN=Lulymv;we6)<*0|iBQ4qnDboYY4gw*7M8by6tb zzSNb9sj}9}@#1H2M33&gxCW5kcDG7F**PNF2d6FmoFTJjANxQMkC@&69SOTsEBTuW zC7wiv*T~q`9e5GWyASO4jPBf6Bq&kFA9$&V(|JN$4Tbc&%QP!v%%=)gXZBVh1*|5_ zeI5BSUtwFrcJGTj@tao8mX4sY&hnt}wfsLKaR)1qIVOtZ{@k?Adz=o~!Jcu@lpmOG zM9cn9@siaL^-pp)0w(dbIZ>LDkuZXV+)Gi)G?`+HmHJst$Tc}-iVo8u}WH63s+W z^jJwo6eV4w4PL((WF^v4RmMX$4UK+$PNt2HxT!-LWKvTu6uPLS4yuiW=w%(ND>E6B>}lD-3r`PHrx(D*IJ6n+Q9Q zVbgYW!*cY%auoFZ#0)0y5W<7&!}lOK>jxcgSRgKlY?{{G?GcU&kPQr`H)+T-^t0^( z#wd$LWRO9TNGPRYINQ#d^y?(WRpq7PXHR72Ky+wm&C+Er&*NEvM&b~!MeNUTe~bSQ zni_DbXsw_!Ry|cwI*&$QmHM76m^5cA_AO2#%jBhI7;t4+jpcXtMX%p6KwGWfvxbQ- zp23!#ReaHN!m^1f^42?vr5Sf!D{t=v7T=OeO4LKvCnXgZ7`oookJC0HLP ziX*<4!PjycYx*SIZDX+>0sgwjDo^n=5RR-zzHHzn`|hT-A?Orh3~-taoLOnzd)2vj zw)D&1A~X~&pbI^Zch=wf%R6Xs4j=K(@gmN%+SWXA{&>+$tn*8YP$vtAj#qeRw5;?U zhnq3hjx(8K*a4kw+}OU|!2zAs1hU(*a_7#zcRa-kMU;+EGlx*!DMV~mL^XE5KF>T6adokt zZ*=5)kkG6N&jVmi2t!yThl)I_F2~*354#H|L;$R|(i(c-v)DxjwJ+t{$=SA2IeGcE zO?kwqJOX`PMpgEMqQ*KUemai?MP$qSeI0Y{2-WELq-G6(Bg^zwe~tzE&#}OERnFuT zQDryed0yqw1Dh`OllQ!y`DLTgWj=rDD-DnaVTFbd z-+tXaE<8mVn&;@MQlpOsA%Lp-8-FhG^zW;XoTYV28co}LpAk>a9v~*~s8W7P_H$;B z8VY4e8%BjoF-dm42TKe9E}`O(& z=XV?78&&j%OZRSW4uyeb8Eii=fJvD{O_`eY)BAY&$xm!V@Z$4JFJMMI(!Ge%>1V=F ztUgMiAMaKeyBj!2Js!_&SLi1Jka)Y*G_p^C`JRtDmO$bGXxIpUTUe%iAb47l7BOy9 z&Nwa?c2JBK*tvy`l~rGvOz8rJ5ELZr7hOeUfbJ8pOt_ujqo4C5CF{r2MDakU+1|`T zRqCI1!|z$C?(qTdM=>Ir5237G3n4D}(r8Bp(t5zzW^g z6eloz0BCwV@Yda`gx)do0cqdNDrLUJ2pVYcuou4%eUc3ooCa)5!0Djol6SB;a6a|L z?22l2auq*d;kaW|!=ACCeoYKr9hM-K_CUuDcT=%**`N-lxoSKzTb z@`SOCD01@2+6~IWfaF<*f|nE>{1&+HLGT>sB_S+af~_Ht0&<$vnxEbvLdO`;5;G{F zxA3Omy^HeJ>o;Uxz7Ixh$(!FQx6On%dt6%W^FZF!mpG&Rk{B@{VpUV)t&vHtj=stx z!_;kz*6iyVP`q1#}qbeIQpps zy8g;qn3`=3r}VvuE-FZ!H0rUjz<66Az$d2oJb3&iqnx~yYJ>!RWCl15r-e6jUSRk^ z^(r<|8=*GiW-bMJR+h4hu9}LR=abXg*`L2ohry7&!4xAQ#HSA!-X{Hrd84ZGMhGhk zzH|e^g5cpTHOt0KEeMhNIL*fIEI%(<1?o)kvwUyfm5wYrCQ86ZHn+_1P-^A0g|z{j zBXB}rUtJ=ac$#f48wX-psYFl#uKE0><#^k2JD(zljQV4?7_16n%_gqxFaskYk34{d z9m8+V&p&4Z@WBW_D9-0OURkj|MI4zJm2g^UN<)^7GXe~{HXh0NEkRV&Xu)q#p#2 ztCCPXE3S9HnD+Y7n+Hb86!@Kkpdw%njCEou&>0O_(`UjSP}y4Dyc9V_K-{R&=bil( z^*N%{W*km#d=k{juuhEh+=c5s2g}Doz!lo{LJ4}5gb>~ECf{w^zT{8M%ZOn@?A6aJ zNFy8MVZ_T$H*>E@a-DX(0_mJ*7J_9lVh?bjpwfN3Eeve%W^-@w^#dYIkJn~EQBej4 zDon~sSg9ah+P((ypk4qy`@5Ot*%I^;@B~p2%g&^fhI!!fSrvq6=-hpmzr+VBY*#ts zkI^W7FB45vZsOILtTd*gMoX!FKFLlr$(Ju}$i<6?h#m|*)B93n{!5tjPMvJB9gUX? z#c#Z2dhP6o(U0u3sz+*Xy0#{4Ly~H{9?Z(+=Rlii3Vm0XelTA_oLarpcidR5G0vR0 zCv|j#&7ve&lDITw?IOMC9vfz^?+I$d$+8iElyw)5Mtd-NNr`&UkOLnWi#=XS%m5}s z`ZWdehqcw5Ha3Okxm_IxDz}QiTuiE6%|@&ZHl9(x!<~aH;MW+Totu1NF-UB@>83Gv z;IxtsDG#=B-e0?J$yjoP4#FHmN8`(4$VYJHhxdixFN|;#B zfG1&IQWhT`U1*+J=_aI2RURj1Y^plo`w|g-V-0xMmixk_(d#{WeUT=Tlygg~qcveAG~yLfhptkYsz13q|?%o@s3GvITQ44=ACjXD7bR&hKIN z-rgToDdK*moT&}9^4|I!i0$rlRa91-aEHs|5H;g9Q6t#&`B_AT@SWbzc31W71wVy0 zP8@0FqrN1nL~Ll!9Xm3!&~)n3S>=}bA&V!a+L75!z6XZ`91c`b5USIBF-it!S7fr@ z(7z*vKIOJdB{)#A$|xcPY@5dGU74TOr-wI62coqD_^x|w4d=b@%Uo%hNB5lfwmMmD zsuNeRaL zwppAc#_GPi3~W2Pso4>m`kZsVFB@uwX?GLr~ZC@Rb%N18?Xo>B`Jw>Xu zRQb8{y@vbT=HB`mh@-Uh;%c{wos^7RkB7|0#rTreiJY(U)%r%#^6g4C(5sZSySYvW z8avxBZx+w$f7+hwM7!;WU1QlgnQqyOR=SD7KmlKi(`Mm)Oc0Fg#np`R)?RWgG86pZ z`-=GWnr(jk80+_ri6QGXh7&AI#Xz~4z3Bohe6&;@2%qFp-G;Gbmc-sEve9dQXT9cW z>O}B4665GlB|aB;3uSKK`1GjFbIbIG5fr}di0l{91a8f1l9-HKHsJMTX3FV-Y!E7;5dLq?Ef-M=__|j(>>4 z+Cc@RrI2lZy}7J#h-5E4OJ2BhPik(T5voAH8J=_tZhpbC;BwiojJX!Yzhdz#k+oG2 zliK1S%f?x=lX+r{W@Y1GUvCz_>$lM{+nmQlzTDKr3H^QB`b$NDYV$9f{1U}J<;~4y zr=tDTdb1BOpZh#GGF6lmrQ2%OY;bDLV{fwubfQBY>+5cpp7+5(8DZ}L#=%fhVu%%9 zLiW+$+Dy$%_Y>TQv=ky5(Z&aH-cQs*?vs5uVGA?K;9koy($X#ikL_DReJrx`*T&kXzvPkxou3PW{n~+Umh+_1pmk> z&{WqBlILdagG_`ZAUUgS??=?!JEC?!1%6{)@i~<1{bZ8H_0_nu`SR`$z16TQy;5_= z9-k0ufEy<(o|KNN1=zt-BM)b<}QApO-WP` z$J$jX$~lJS)~77#gxZnrYRW`L+0VsJGcc~#Wy!1dy*j^exTtT9!FhXEk^go#OE#(U z$=2XQxw@*jo9tZgu=zyZl#PD8Kf+H^`?hz}N@=F!7V=T+<}%c+;mypucaqu3iiVy1 zeWB{CElPe|%c4dc$#eCA3zxg$Hx~tV+E+LLyVzt>Gq6O-`vgA?ZeM-Dn`?NP4{1A! zk^|)?gH>(@;(T0aBZZ0FZ=oF?f!+r0w_6a(#7Y;xgL$G(VAyD_l^Oy_SOJtNF5YM= z2l)GmM5gZePQ!I0mJ~81J2>Cki6J&o#L@j#FF_6W>Z@I7lD3Ey8VBwRU&)-k z9^o67s8t4xn~-`FG`j-DZuj2)&;@5d5tVv))sRaP8@GLsAGz=(z>$O3;lH##opXJx z<#yXbqgS^N|9_}@>$obL?t2&z=?3W%5m3635RjIV?(Xg`0Z9n~r9)aky1PN7rMslN zoAaB4&-1+B_x|v?{X;xwu9-c1uf5iqYrHN7w`=BZ$E|a~2tffr&PxJJ6@?cDh0)US z*nFkyv$?5K!_z{VMV_mboQS~F?QijH2c;zIZZ$5)kOPf+$~kQ$muDvYwaMh zjnPhOyiPhf(PAacr)IAfwf>%X+SAtmnFEj+W|w%^!}=CKUQO+I*zPdf%bsUS3>OOV zsq*?3>ZzWPH>|~W(0q^>G>Kdyq#}NFZH`|0Chd}a-Y9`*Y<7sX^F?u(D|0j zj`~+gZv!^8(A>;Nm9Q8XkBgF^{E zoiFaz!A)Hxh;N&0o=D~D@Il~&U49?*6rNb<9qv(R|52JB7JdC~_16qOOii)vkb{MC ziYn9Q-)_|#?H6bby=6&*pnYC%Ph^bKp4h^jQYCvG{emseCxZ2i7Y zH`KpYD|kvx0`A7yT~>gi0J}yZ#e!P`#FuFr0_5@=b=0*KCg~NEs4CRNYap{;9|}Ia z*_`9MzU#a^9S~`(fH-x*C7{a~yq= z{2c9`+fsjf@6d3L;&=Vvv!*1P*_ z;%YZ1DWdYmG#mS);Ps+Ba&QL#Uk6JS>EHS-0qrVErNE0A;trX%08~f*!cZ&Zru4~( z01t=B4o6&j8>rv)QvHi>JYz4TGXP}w-gRq9)$wg<{+#i!)2!k5kTm;$u+nwy;(AOY zw~~rtM3w^RUymDu?=-qcYWKhB(CNFLlz%FKU3 zspq{1`>+$Fc7!NW&lC^Bl20ZG&c}(6L7y|_YIZEzh>Q5@!O9CnHMk9``Kx5(MPa@9 zlq&|>DrPX~#r{gm^ACV#V4IY%VOwBC=IzqpY%<{ahYxH>^1V0KIW0AW2H$3E+o#*` zdD1ilkGB>u(Sx!(qO8TaPC8;yRmqD`I~&hM68ZCIvFWfub+O-xA$|1WbWh$lS?#^O zz7n^}d%n1u2bn_>HU^p(02+hNfDA*AWzDn+~vu?=HLiQ8xD?s6qORwK_VQ18V7>Umpy(Ay>b(u0*8mAcOJa z_iBt??10-39yA2<1S>z6hrJ8a4kU>*P_GGGSGLe9&^Y9s`XX*uh`!uCHC>qCRz9sc zcdyvxo8^~@qaU;>-<-KNha!i%wTeq^@J~|@OSMtOvYH&0>1+h<`73XATkdiq4_h0| z7TMqHInTJ4W`~yAZEvXCk;ioX8O*J0Xo)v-Jv4;$If1nWgakYD-y6pX!`9lw!G@{i zBCc(j5=2EaJv|n@jb6K!{x!auf$_trlujj%^Eh;Er< zme=jOUQ#p!W(Ww4-2;;o^q@aKS)N3XYf0rIVN6>c%$l>>-O1|SxQ`-6!lZzHTE>>(Ln_enC!1?ih1@NX9X zu+lO9GIQx+6#+QQzamiyt>Zd6#B%@e4hJO$sist86leI1({&n zf~k@Xr=I&BY*elG#=0A({gyRqm~pK9-gI#L_s#e6kemu=g>Nw+fSiXgpDdOuHTmtG zO*pk#CXG61SSz;W4v~XyARnk1sQakwxk&(-#T;|$#KwQ^$o$)TC^Tuw;k~aEojGQ4 zeVd?XW{+$#*h*wEwNay!B1y9iNSY5S!eS23Nz}M1Y|h^UIdXKnD#G(#=^)H>_HC1f zR;80Z-ED&);cwrAQ3nd>JpDGA04soz%8NKqLMCuL9qrzfYO|Z@D%gdKe6Z9+E~dca zxq<_#gVK;cNCwd9*3pz{M~`kV-(yXb)$#;oFv3$HWLOubZU4O7XW@1DNt(Cw15UZS z_n(K2j!LutdI9PdAJU|>{PHf*zq@KeF3d7=vVMF7SgOP7HrhTb7yWbJFI>JuD#EA{ z_P=oYb34zV?P}Uv%#T(Bz|TmFAAOoepl321vnFbEOq7=W8Co93bGgD#Pu=Zz#hF}P zagl;HZM-mwf|k5*9C#6fuU2-w!n*LyxcZZzFn*XLuZX0Y7#&2R_l^HPke7Vx4_UyI zsX=HY&LJ{U?aUWshQljHwcb%ORarI3zhkN7YHQee4^qxFYcLpEG!fHncJ(#Hh%lF` ziR>u9`W!el-&=8PX(%WS#x)+iE1Ebub-Q5SI3ILx9XiwIAUd&$Czbg3j2!?zb3feV%!{Tbe$a6yZ+ zJ0elfG!)TyzJAeMTQ}iiaAEVOzK&cn&BqD!qIlE$&~_8_LKT;9ps)_>b*|Yq#vlL? z4qAOq)9Upi%M5-A2?!;~U(ja#-mOI*WRsOft{Ai0la2Q1y7>ud4tz8B@lIgIeDXAX zp7VCwA0z#3bQay7daLE16QJ0Ew6W>LAr=Q3#tFtShg6}tl7 zQ>H+;up_DPNXXj*((=b59NJTnI>B!8vgZ-q(QS_1o#>UhQ%jbv`|5D@TWq z{dBZspO|pNj~{{~=;tQLNG7mVr3o6Xqdk$!W5m`61}hR;d4W2@*${RciQ%t~sBsFU zJU#~vy=?~7_9eyajn-VZmVoq1t(#817a&A&DkwsX%qlbJo|hlw9RshzIGB}bS?JkC zjB+d}3X$Xp7Q}-#hL!C&W57ClcY}+WIck2@Zsmn6mgV$791#HBZ&m?(cwDn9)3l_AzQ+-&~Z2rvXV&)8`FM?hD zg{r%zn%+qV?~%@U_m9p{_`yj3GDc?cV$4!zfB}}}Kuuzg7oT#u#BG{$|74?qSg`;P zu$eTBmxv;0(NRhY+M%76NfTUio;O6q=VcBiFYx178@)G!IZ36=mg-fKwmt9$BU4zz zvz~uTez?y*zWTcD1_B9quAs7hzThDs4`DRDXat2$p1!LqB_cz&2kYbKyY3Mk$Ywq;B>D|1}*Lw)Bv>^j_xO9&#T_8si{5>5Umzf)7H<2#Qkfh0n zr`9QIcKhg$eOcAJJd%VO2X}AlqWA6DhSFA*(?jx43)(TFT&_U}mhIwsZt%)Qn2}lb zbKPsi(!+J|+e+~S>u;|2hu=!EeOrxuLb0eS{Dr7bIoyXo~;z-iT#XJL5$X?~&u>UtX4U zN&DPVie^=5BiZh+ttoYWkOjAv;f%X6`K#lULz&l0)|b03!`&L=Q&R`bc9cjA1Ca4| z7W)S#K=l0GkoTuE*EE6$2^;weC9u254$LUeG85rY&+_}fC-0dGv>gG0x$ieodTWCY2NN9qd190 zn%JE{VX-8Si=R^$6!p~sxnlX-cffj>h-TS42f3_f*1fbtJtdt9c~QGFvV98DJDIiC z*uX6)R$n*2w^T$VEX@fPUG~fP8~s`0>Cf-`PK%S~i_&rAA}(|*@*Gghs&Qc-cmhVh z1IMcj-@Y6rVb;hSkKYUcl}DWynU@rGThy9f+63#CHX9_d&kgK{NFPdNo=^9f9nvJA3m$)3R-AwN&70H0(TXLcXEy7PO_Y^P(@9jnBK)`}-T%*tEw*`t|1`uGPFcQ~L6 z@@ciJabF(2mnJG{yF=$m#8jCGOweCsFWv_o4$XmX zW$Y8$;R?`T%IR39xR@=4_M!?&`JXoIg4B+ZhB3dkXrWh27)ci%>$4melY~Nxg@G&o z12YcD=LpTV?}Z9xIL-~uN_`Bu0dEV%-)5R~$l_E$MXV{+>IS$u(|#~8cX#g~h==KP z(4bnMjgatEc5oSLp&TH1$`V6mzt8CwkFY=vZPAyzlHPa-viikqHrC|*{JKf*^$~K{ zoFRAX2?V}Iu987h?bM0Q#=h4D#wf+6JNmS7$2WmBrhlT+Ux_KySw->|ugc`V6quU@ zRHp1(gkDW1`5pL{2_InRQ(sc=1sfvppnc_4sbGr{$=p=2p_0?uU;RHRWC0{iZ$SYX zfF98xv|~}X%`#@|zVxjR0o;?F&xX`n7l^BPPj9}lVguQ@T0E{awY?XhEnfiQjGQ9B zrYYi7t-=J{Aqg-efZ5OqnkC<=jo)dE@MQ zf%!$E8R{)k$$bgn`B+J1o&k}+ePX7E9vnDVW(J<08{_3>lWZxnmG*$X7<5by{ z=lG`qzcMVVsjvMf@B{#r-;bpWFd0anI%niu(`;`dasaATL>y|p>oBW;JUR8z-k1Y@ z68L-PbNT%*(9;(ipRvz{d$re3-Z*cN0-g7#mad@0VO^DEqiaRI_0;S4C{P(t$x=YXAxaU z$z|f}l<(zCzPopCjZ{BXIpLzv7l7xZ7rj%=8F~mP<|2Jy^V)PJpJE_lTI*({qqsig z!95)9iPdm%E2yfo*v+Y1=Nx2Mmt%i+HBN^C_ma#;{gMl+WJi z6h(TgC_{|?Wlf~^Hj%#b-I__1$LX>J*!18=9g&}frQOyXSqgZdD$Gs(gi`*e8=2Wk zY&0gHvK7c%tZ*lCUlKa=f)H}w$OOhB+$P^;bJyl(2|0jOuezcd&3_cOeV+pEuinZ= zH`zYrWSQKpEs8Ev)=H;NVg^%O;6!Nn%?4O+R+~3K_(eG-1%A9jX=yt9S>QW?!{4YI zNPtQbw(6Y^xMrKxMru&HR`tDcrJ@mN1plPK%`5OWLU`}E`QZ=v9JUIS0nPAgRb z37W}xfbLcL_MT8KB?xlscGlsfnX`BTP9>*PD}PZ~6Tke%HW0 zY}vJPni+>;xq#8e1tDUMQdY zx-NC^pJhy!M*`u9LlfOcgz3W9J@%lz&xHQB)6uU5EnruZ$ev)?BVPmD&~%F}=ef!{ z3~B51Z{|h5&~EG1%wiIY!r~57R@`t=^ZlJp0yIaU41Js}IIU%FN%pm)&1mrBTkj6~ z)Pen$$0I%)H}5L74-g`tgtuIr8P)alTmxni-=?hyREW7aj5_m(qsY4S=CFDq!6G`8 z==tU(vRyT&RYQ6^GG1|>hAK8v9qHNXdb_FD;qP25kO$8>8R+SOmC3L=F|>O%A|l!; zv-xwUnPzA=EvA0Mw~H0PMFQ7KZ;hP--zQn|n~;SjaIv-gf*ab5qB6FY8$!?@FKbf4aT4>-~Qu zZ<=Naur&|;j+3PN**1^BPKku>6a>J2_@qn$>r-H-<#R%mu{SJTfV)~HzXa7UYFNN~ zDaWw|3`wA~K z!OkPKka64K*WlxH@g9+RZ-(1q#?E&KcRW4;1}t?KfEDbt=YG;=m$K3A)Tl0NN0u$!{uv3n%(2KD#NS)p)CU1oG?QysaVv+4Pg;g`*_;}m&8ITq55 z5WA*G=CU&Xy4v?8%=N7;3|-CLGLvaGDb7r#fW}->2fm0>!DAL6jUKk#-DH*OL0g6x z)ZfDY6s#YKk>V{kXW7#Ors;mWI-s?!XNpaHk)q1wIF-C%9b#T$%-asxLuCG2MOvHP z5YG0{osG$|bAHmSc8LW{w>s2d3%e0A+V>HzTpIE&z8|tdXaS9AdW#<)%ptizH&Cwn z+I&JZ8TMy`0BVnshRV2}!>Yf-Pu|#{kRFl>lz)FR1)PY$$MAc>O7+hociS%F+b&M7 z7X3Mbdbj+^`*-swVhZY0>ciQW*5cWZMA6vnLPF(9;yH2)WZ;#rXI^Z=P{R68(#jYx zGr6?n9hMx&C%1_8(=&0qRAC-eQv~H7COO8B$9*mV%D)CYLSEX6Fti%NeGSxn{~E$G z)eQwwY{2RWP%I$NS27#9GR^V8b(3}$vm)g@0zi2t<#qDU9NlI|Wc&);F5joNd7N*& z<@z1?MlGuM7HeYi50>Pt+$ey_ z{&mVJB*9%##Q$Z_fhTvVF2l?2`9+F>eBiO^leWRjGn0AE{QA4wuj;>Ml2}T8=VAl3 zS^S7lZPJUoWPLoB{_afe5IbB_hYCbb=&pk2f0_+&;{46rq`x4cApiu{wzgFG(d;a2 zo~MHNpL;eoXaEbHF0CVAty!OXQ|PFBzkC$ncB3QB+rAlz0zRot&QG%!+oI5|rppb`!Eu6i`$Pvn z{h``dj&|iWRs_ja+1>B@Dz#=n2F;jh{>(TidlnsWa^i(}z5G`LZpB`%e*+z!$907b zY(Ho$w8f)?U5pdfO-OdR=y2Y#F9S@rwnLU&4#N$mZyRrQxwyEY!HDX0=>VAXORrNM!9DvgMSASsPUv^?s+GT%63koI5K}M}%80 z`&2g$ds%&b7?4ELj9+&j{Rjb_xO}VC&BtXZqs8shdij>OyRlbpuz{a%s&r#?UyGJ; z&TSRV&d=R&^3a3U>PO-7s27)#s(Rb?1(UDKUqbRyLGY>I%XthUj`UV}eUlUCEDrLG z*a+2^l!w8J0p^A9-1E)UWOqG185`CPSH<*fHLC3FsNr+qol~8fs>sU(oR%S6CJQZd zwL??xv&%Z}sqU2cEINkLg1;pb^cuQKQj~ZbGFpiF%(XhTQCQNwX}XuF4&dl${I}|f zpLUk|9MrCmezSqDGH=3sdStxKM{9DeOw-)r zaP?^Bvoj{fdV~2Y{$p^0JanKtHSpVn6WG(I-Bvlwm};f5phvNun@YZ+d$cCUe*$i8 z@)j>tdds3MGUAnNR00sIQVdK=7O3SPpzg)^sY>9s1CI>+4;%ZK@~bEAjyfD50I94p zp8t-<)qL=U4UnP*jh4QRk$@HP4mhL^fR)AWL3VL%#>FCRQmi7 z=9^t#s=Vw*i}vIhn;lB3!RTpf(I${big^LH2Y9-2R}V6vXM&k?`YVG9RN$APk1wdG z{r5ry23FuKns2U2QaR`BT1A%AwOpIN?njH3VoAX|&Hc%eQCy@}=IikUe3{dJ8eoy% zEgbFqOQq+=r z`R(^{Z#+bj)T**ZO(W$5yVx8xhwlA%A!N!n*papYXL&dI;Zb&^>nO4fkExge)~Ogu^jUr zPFUz-0wq#ndUBVN)6>)xdP?p$7;`QTZq?!4>uk33I>JR`=#2xtdGDDXO7$87O7+ru zGMZA*8&hfXz9e;3%BQvW4h_7>v!E-rS>D-itkZ1z?3z%@DcZXr$sderb_cV4Hcmae zKwg4>xSG~Y^?EnOAVC7WXioyaGe=a^S+qMFo8Rq$!FM&Ol8}N(*u&<@;i5*zIUjw< z#rv08*~X66@WZL;y}fe7&jmUCBll^T^z^#Ebh)=JBckBp^LyD8@w!^PzYe-#R z!F*H~?cCnx9~#(j$otZ3PKB|+QLb2&t-T~vP!n}B%gdL5Gg?j+hU2L8Y9MEf&Nz=H zMb?OcD8xXsu2Qpe|Kzo8f@*oSQ&Z!QNE#e>OIPB}4OAY1v_J-_AKb2G+QkOBHBsx9 z=ySz#(2Ekc4~U|W>GXQJsU59pxjED-u63|uW0N66 z8VxhoU?FX9Q`OYva>b#+^v)E8edbk8EV6rg2$=NWR=ac)QwoI>3QMya;#k;ZMA>2R zrtC`X(_CTmf8mX#-VL*S&^#46b))C}YPl=1b8|y06+=BBzgfnT)@{ucc{dJEt?;gL ztlQBAoxYkkzR2aLjjh8SZI(}N0g7p*#eiuZOTuv0m-J6m{aahSs)f7iCB-Wj?}@B> z&2`Slf^6=lO6R+luGi!ZvWtRshFTP;k>v*o>}@AoUp^;_&dlDWi!ZFx(d;h%^SUt} zhwS-_W5S^UnYBF`a#VH?QBL$hIfB~v&}CVf{QcT`bIa`lyplJo^OJ!h6&0_zsBl}s zHkcxT&-t5XF%i9G)no66M5fmw(RA8nx$+G82Y}Q%yWGaTC<~_LFegp zQY2xlFGLim0p??ggSpScs3uAH=!z%GwZSHuYwH=p&?^eVfEC7K;p7TW8o)DkA{qdj z=o@j+I*)qEPjt8y>+kQt_P+i6II(%~!fi4%k@*{WLJOFWX|85i3_5eOJWKUuy+H!rEn+~u&`3Q@BeY56j>qvzZc_S!}>i{EEG$!WagjyYmpt?(< zUNA9wkoFVf8{}wxF7!3V!)WbLkj{HLWsROYXZ+LapMIf?0I&CDYSnAt{IN{rWZ$gC(zd}pD4jDbHkz_E9U8qcHM`Z)2k#I9Zki} zi7XZia|P?~X+#ofN}@H0Pdtdf6KP}3;W}-R8cP1Uus|{rylg*Kl$SHO;FvWcnws?u z7m7*@>|PY}c@Gyz`OsNxsUD=~#QaEyL?|md%6|D@F96LKYsELbY#%Ea_w;5K_?kVa=70X(10GgZnTxBup(RW; zpTu!}<+fuR{ch6ia8(VGu{pw;Th@=PI zgWcXoe_b1Q(oJZj0R|2`y{5(&)4mlQ$?UrWQ0K5?aIi8Yb$ zeV(k}AiTE%N$n>{RR#$%qM}uHzM9TQeso-KZOwTOO5J1W4B0rt`^vFpBBJyio$)}d zCK8ee^W(t6@RS6KS4M&~%vI}FHe;PRYHgIi(BoP;h(Rmb3+f4>R2NIKB;_|5eM640 zuyO^Nh?_NWL3iU>F0R^?>G_%a^2O;MPb0)&i=eyw?_QBzM!#etUZfFs|4oGOvT(lT zBD`hnZ5KB}B;n(mo<0%eO19z9w5e*OEy8_1sz4ovBOb?^6Dt)FO~d+zH@sk+jz%e) zP`c|m5}fw1NcKzz_-K+jzG?HlE3)j`8h6|=5o%5nzoUM&qhTh-Wj^UOg9InKNSakJ zdogK}&-vc??{)F?#QM6;$;nIDIH69Uw|4IL)Ie@JJm5x4LJJKIt>Kjl6pVY70&Pdj zL;c1ivnRxDjQS6`TI+)xeaMP2Hcdf}aZY5Bc`qso-?pURFB6gdCA~|=6eVZ?kEU0g z5(!SG|DrSwwd7C>EKSXf&@f8}Q;OVob&dd#V3UqnjcF8r$we4hdZQIGbe{8rVE#~2 znq3722?#q{=&m`>sj_g_*8)D<{lIV0FH}GN1j0$y54RsPDGKdv23Q%FBjhWNg*U1Nlh6>1tVxai-du1&8=l##n&ik zS3Sb+?(}rj7u0-E-g;t@bHs5#u*JNm`SPA7hB)kys1bdvqvrx+GO%q6`UeT$^t?s8 zg9qJK;LQSabI4$NfS;?y^F76=h#z@Wd~c%WyLbRR_$8P3g`6Ug`od0f%fQErB!y4b znj@gKXij#oYF0Zg$4CkfKH_B@NGAH01A^1+tQ&rdhvasA7&}^gp!{Ujj0(AoVSYIY zW&s<9_l}U}B^8w?ol5*;MT>c7YKWHPAXqmgC^oz23_@{ne;&uWgEQHNr-a1u-1)0i z)~9hv!x0l}uO+^`4M0M2$6kB5Z_zTJvP zPt?#FQ$=276*l@;8pDA+FOCRX)usOg?WpmYZSAbNOM|(Kr@2ex!{)-nCa-21245Dn9d?M(|D3$Zxs$bU5a8$V*;& zQrsVVabQcZ;de?>1;@Cf^|_;EgE6i>TrFU(&O`<7tIlCM*Up*mRgIWeBMLS&uPs_Z z^zVPusvUO+q2Go0o%EGSzxe~ccUrOo^G|LM%NyQRw?4VZ=j7*`G&O7bPK`u&I=0tN zUriAs@iCc4RzS)3T^39NzmHP@0`3KJM0A9{HwPpQuoC62_uG^=JO%Z+wE~E%pLLlJ+XWTAQd7mjP?ZDosm|11`k@CFJT3P z0YeO-^BYpxF4pAG=j4&#z6*7{<1O1Gq@zv=0L%8}Fb8c3_H8kXC0_ooljZC9weK?rSALj$HdVX=U}c=0$-p;}=}6=kWf$$DDUOt9 zO5zxTm+^^Pg^IlhEQ6R+`5W^GjJm@es~eZ)J-O0ZzW?9~S(2GLM43O~gR5;2K)A;o zsjMfvtJTx)YK2H-bf~KNoDqy5;wz}gLs=xzCq8~qIJNrOT8EiV~wEFD!=L8#?xs={D(Wf6v~=j36O z_@iG!#jrn%VtxJ*Dn=D5ksWI3B|@LRnQ2A1<$NwIjHH*;)abo74eqwAEQ`F9e8hG5tQ79!HDC)oukAeH{e zdrl0#NE|!bJhV3pV2e-*D&b|p08tLtCEh5LIrGavyEIC=S&WW}1q{~!5w1HvpSmt( zM98Wg1PgM%l-iy`Ur^Tn#^EMp(iM}1`VLF4L-3dVp+T~(yhPDlr(AxZoZ2NM^4ytY zj;so?^cC-vJn~1ulHM0!6Jmog#|W|2c&QgHG4d8#1ePB2WA57yV{&lcHz)hjE{KoW zVRSg8f<{gb9}4M0$x}cV{yx$Wpp|#equD{vqWo-M7gPEhCtm+EynYpqFWCURAya8BO_K2m3pw0MJ~(rw#ViUaS4?G440 z{jz!RBPp>X(RiJ@vtuYlSL~Rm*G2`%v`D8w%Nm&GO2Ee`DB3gzvR@rr+1#!HS4R8H zj793JzcIv89W0D^YV>u@itYP-+r$xcP(qVwoX14vxid)+Jo6yC_nS%a z=wmhdn)uFRhEvS5B1+HbD$rC^u}1OC!vjL|4v<5|12b+9pK^#QKOGGX4$XV_?GUqQ zu4XMn#OvmR`mAVe{%!QO@Ar~9_JCpZhvpokUd&}Ntj`E5O}=!@SQ{rd3C z?=DJQSybiOs3bMg=Zh!V?Y)%zyrkX;FugAK$DTZU{8#f7t@oU7{Jb}XkFt0D?t_Z1 z+II+jAtCGr3GXhyh+>2Ml^u2^()kh8fb!6q&0W_`{q|Nh5sLZnk%R56o#u7}&Sr?N zKO`8FQzZsl!EJM+T;De)^d>~jFge`4Oq?S6CZyij;_!LTCHf0D7Y;tMszw1<1?Z(R zvw_e?E9>$bv6Nxvmrf8nLGLgWWJM&V0EZL&ZHGAC%0-#G=Isf>cYsX0r~;$pE)kyL zwsUHRxu3PjN>81RjNR{wcr~>4{h5ed7)F1Rw{7>6F#hQRM_?pAVxCEQXrzlU7M8*@ zkeyUizrTLid>A%qB@rv@!y=j04;8yZ5B}i_p$W8@d*JkKcQM(wwUb}2o!QP@IDOJi z@wfHxXsO;;zkbv@Q@tchy=2+7paY!^j9B8T)EF@XTgQ9QIPr`w_T?+20P|3D;;iI= z&<(_^tR4GlW~8g9t&4tp1`NIaCNnHDg5Jh6Tr&OQ!z>0fH4v-#r=4ekQt@kT6=Xb7 zPdY1B8kl7I1K6*&+RGT+OT4Hy#t~(eo`nX$$SOS-5>i%zK?;<6=ZhpOB&rl36cZ3y z_)Z~5KdSVd%3u8l<`-GlhflxiKR{USg*4?apY#j7Kw?DHalDVJ-=GX#hBPecBxJ&8 zVT$9t?8@>L%JKU+=7;$f?*_H!QW)#QdB%(RQ}X6vLQMz@q7~%@rTr{>#6kvQ>64P( zciggd>4*y~D+p_iYdjCTf%|3jGZG^d!!HU^gwF&odTlgfzyHF)6APve554HM6+`c_ zeU`jhx^~r0Wx~?3L_)k%Ns8!MMzaB73F-LNv)GGnG^|OShSqw$sv{GW(-{w$aE z+%W~o&3p}+>laMASa^+itkJ5>VHLVqyn*)nCmP9lR9UYZLuvvp-LYkbMbDQm7aH*~ zVHzwjI_`Cv{VIc^q83pxto9K?`2<{pq3>9}v44bqv)L4XQ~FJyL!4{d?dK90o z)4>&>*`RMdPHd&yKqLqqvxjE*vfx)QIY%S-+?cS#twlaF%LFqGj`942m=@_3)xJM=_V zKv$wH7EBi&I2iIUg%kiGRXOJ-{TgD;0`mZZRMV@YPGCXQt!(8xVhYN`hDa-Jx3D$d z=YWrUe|hjxJW?~5^=aaQ5x>`z2X*J-ENU?YJzT~Bl*DqQGTQFzDEv(Y!64fbRumGHr66- z1tViVG!0gf@|3jJ&t#ZAdEorqi5PPC=K9_Vp!3Ei7DfS!g0N&K#1BR&e!boE_fg{FA(H3eCAJuBa+VOvJCSe(0gfXN=6(nL zISjP10D}Wpf*&g717$b;3miBYUuDQK(!r*PV z2_d+XJG~z|ZEWujEktV=kqE#zPo{ZMXc^5PI?jz0KYOt(;7>;S9>%rTXX;!Z!Km3{ z#$KD&9ka~s&P^LJ@BHZ8%xdettNCwc`JHf;{-VIoB}VPo9AS1;KVPOjjRZAg!GR^a z#qaPd50`wv+KRb(g6)>$m%9eW}YdX^RNo8PJ8vTS*8F0;idNx**`GJY%5| zpM}dr6m7_q(hjn3Wu-?14GxP9Nv`Jo$R~-6uMb(#lZQK$hqm!W_e_`-{OUZO%KEs| zI>vA?@H#Z)qOo0wx=)a=$lj7|wv*J{jEMIincl6z>)fLwT9v_OlHj8iwLUlKWC8cr z4N<59G@O5`0azb*%aV^^cP*qx@qHr>2aG>c!swoJClg>H>71FvnI7c3J3i-yyF`<8 zosA0olr}X!I$dB&dUtenlviXwtgS(UqK^?`b0F|x0^-~GDFpuG0VnB2Sc8fCm(0&I zx9Mh>K^jZZHhg7ix7=0t`b7lZ%(v($)e7HZz zMSFS@f(%C~^l7)=tLGxb;{)BcFo=)MeVyoXGB+%5M^b{keZLIfTGcka4Ax)_@OFvT z?EKxQM%BBBcl-L@ho!e?Q;wd&$jnH~H?4?`ykqUW-*#60u7j+u8X-4u@wM3o2_h1o z{E&oa_oEmPbhrcSy<4B;^H;SjV(P**qCdN_+G{(2E%Ie?N?a?3Ya>)p19oSnc^wBo;WuEFk9jG;XU5Px#avR7y+e!-=bp9+MS=_tGZAxCsWXt`iGYUekVl<$4mEv8cp@FD2=39(Gk1* zppg(g`-^1P1i@AXgMPt89=WXi7PJw>PBUmHO1Sm{nAMSt+KoO0-HzY<`FJY;*SFZ@ z`NU4Q8CEPFN>2U*83fGy>`3n~8~0QvxjUJXK!Oyqc8BA7zWl1ao5a0oS0yZ}@{{SB z?F)QYBJhpRQ&UpfBXbp}O|ZyF@?IEL=2K;igK<9IiL*6g0BuC0p2@0wkd#MeuEMSv|8;wDPYj>}!xUjahaq6Wh| zJa}W;-trH>pmW0fFd+X9>yz-W2K5rd0>!|!27?4y@Z?<#o>WZX{6eDeFj5oZ{l*Ep zAXGN)?iifMx*V&?U0;dzzRx9UKcnl+fv%0H=;dQq9`*G>WzlJd!_>)QV6zfn$VgMv zZpUW{CE6yvVp(2w=^;?IcQ>WZdHpr$>9)5?hXx0ian0mca?O~(7m)xpOAH7Y#otg| zXZOqcL3O^7#MfC~isP4rA$*k^Cxge|g@s2( z-yYlJ+Js_|l~Cbgk7l~sNpwHPCwfPALa863+iOl|FMcVxvpSjn9xv&aO|{B!FgfC} zfd?&ux2yTb6A9niTgwgW1GI8g2=ksfPJlXany6?NbzU5T^U{1Br9!s zz_%^_X_&u&+^C#olnr*z$vHlgUMsRjJWIkLT1PHH##_{0hjMK#l26h_Bw9!O%zG7} z;aZ$Rm;Z>oyoMI{2RT9621W>~SY*9e-`nF5Rp=@{v7FAuBI8RTdlmo_At9@*83RTP zP5D&39FGx_xf3FBZ?((L!^e&;t1`0Ve1Eh>Vz&b1*?pSQc^Y0MATy|!fFBrl63_tT zpFC#m3%dpd6~SP7fXb?wW;<78(`nSux8a=#Se5`}%QG zZf$w^Jpt}h7X=N7g05C?F1?zE4c934iU&DV2l#2X3ii_f)Qi-NjBe>+-H#S?;Mt(s zTyriCF{A4<8mg=#?Q{4$s=IDXTih|JZ{ybLQ81kbA<)fZ2;>n_4j@k}LRUyS??s2b zXoUDrXd--E9_7c9Oj|-hp7uWwnrD(-rP{lDsBPr_bt{p@hHpz!vt7^Ua9^PPn3*5K z&~kT8Fk)Wwfk6$3KujSnAh)`mBdA(h0kyo%!K0gQ)M3)R z#{Sw9HKBCr6CKhoxu~_fd9KfWP5)^2lwj(4 zkPe0dU2I`se0wVdB&)vbYmIqzLp8;$`*9AF2+>Cv4km-R2b$G<^ux^YPCW$q8$SF3 zg!HF%o*yN4K&gKw-4m7=i1h@R24e0iYg791^(nd@v!nTgyBL+vB4j^$q>#ydV=IYEAJ<|t5 zb@eI^h*=mIAlwWMKeM;>MbNvxL%rJR&kzHugIE7c2BvT2+B$*z_A;OdMjwQvfAmu` z4)Nx#7Y73g{5KFVHCuUM>y`q0ilI@Qo%osWy)%R!2f`6S-v^$7;<4-)Jl3^VT7FFi zwWHZ}H~U(}Km$#Kg!iHn%HYdV)a;fAi@3l4Vl%DWZcjX24KmZ8;R5>$P&0s_QT|UA zjQY`E61w!2^e;T7iaa!4o+ON0TRTsb^;1%1^*a0dA^;J(={UqZBMGB3=W!JON%-G? zvzZ15XoJ!R({^)#p<3vo-Qf7FR{Ggi9+6|Ns57ZXO(aMchV^jEHq>jZ40w(_+}wc) z>CGRReKx3wi@CyILf()@gF+lww;EmstBt39m(*Kyu>Ducoa=zg&>%rrR5V)n|DR=t zokhFwf@?rF1pfuI0yV`M?z|CZ$ONkWvSthe0gfY?5j-MvEMRp6I*}Tcsd)VXn+WP3 z)XyO*EClpr)F6JKMc%Cr-%$e%&G|i3d{JGaX3(z3<0cAG#%yzuZxb8s%qTy`N)u|@ zNDtlG;^E^%SHN>9Y9fZ#!1QgD5#tu&f49;R_k1%3pn7?cWm22ziN-8?bc<7EDBt?) zWRNLyaj^GSJpWHN2^Hf=O}}WQ^IP3}1qB1nE>GN49|g{8ML=zlJqGG8ZC5dGxxejC zc#~oaBjfu@nm~}Y1NiXO(#6@!6Pii9;s>n`{!PU}H`q6$tj>1s&RhxpR8l}oP%oJ{ z-r2QdwHFhWP*mdviS(0I_e&TdOX{$o01Br283Mt`(w3iS0Ve={aI5`hVdR_73IkYt z$w}<4!Pr3YsB8rpU{Pm%(RL9ThY?dVP;EryvEYHlqle_Mi3H37ZNPTuhyU)~*+6J? z_6iB|@91e|v?nF;Qx%50)`sNn5Vu_40BrQyyo!+gW!75m|5x(FVp&r9|5NhjT*?)7 z{#)`~^IlN#S}dNx^T6n0@i+Zud6h^N&{RRst+V5h_>-(&1E z{u_^z(^C+5Kke*7bWr|{13T@5wiFE&FI8}7Ht2x5vakvBpjzM~A`+m=@~ZL@(57cv z0cj+F5}26C;g6iIX61eGvnaC~%Adi1_;0EMSSZWqL`S}D_;XWFtX%wmiYyG6hQ`y= z%DQr8lt#2HToIUM$5&~O8^av)aS9Yc8rpEQ7%%}PpDz+fdjBaZf}RO03IKz*o$`Y; z0A{2M6unHaohvL-Q<#@KIv%4EsKAQFQGimgWk@Jnuny7T0y$9Fu7T>I> zRX=S#7F#%gQ3n7<&FSqu0wEWqgEAWS9ErRw*X3We7pRMs5p|XXSzy3qOr7p8)af)W z2^Vi;l&ji{X*b^i?KR$`NA=qRb(G?p#hkFj9~2NXmzU0d58Im=oe6>vIDqTJ*Iz>$ z$8V|ziK?QHr`7p@pWTq}|nhoeg``*NQ`{&bv9N zf65LZXoUVX@&9@O0Gf92wME$6Ftb12t~`Pn=c)k_15NZ$eu*~#O};IqBveflQ*RS5 zMGg!u+l204UbFv~S?#su6hkq>+erUYhkc-%iI?(N5+0bD1`rk`oZ{BJI;57o?{9&< zsJ*7%Tt*a+X6h8UKtxS^aF<%{Fjixb^Z(bC=BB?8hQ zB^{gY4(X7P?(Rk!1Vp5yC8fJVT1rYvx~2OrzVDoS&*jwU-oMVhR-nDKB zPiE3YVu1M~M*gLHD)`GkhAxnMbz)D$6UQhMHGb$MY*NMK;Q$CEVjkeL$h^q6n={Wv zR~4=c_WOT|jE@s{M&u5%D)5cyiU{(j$(!*D!OP-J{)2g(c7Hq2uy%HvF%qCp+{ar^GqOI&Q#90cf?FJMXt)AXNl z`lW$d-6T)ry)+nztjtWY5-sV5A`ruqQ8dUDWNC;a|BOUr_&--8p+<{*a}M|JJ29wc z>Eo7EQ9r2!Z@1zdR>y4c4VIrv4b1}mN4xz0!srrn7+~fC;>Y#SHtVWG@ggxvilEGPv zb-KA7y))$X-;H5|edelSP<7EQWtxo?Y?>g|%2ayM_`~uLz+p-nx+xFni+^`&z(#FB z1By}P|Cejm8In+k*Y2SIjcgONWE^avUPmM=*0g?KR@8rZ1@H)M%<%s12CbL+x6e=w z)Q!Q5|H(DjF;>8$_$>V^e-?^;h6EM%&qD|b5ik~3Pi?(N0a52OfM0b8E%LI7Vc|Kp z56iGerDEomKyKID-a-LWuCwwR*02lK7gT7(IiLEM%1*cFT^)LG$_)jIO zi~xGZw&nwHrh>K8w~1q)##CiT z|6Cp8s1Z9o^sy_ESRdaI(G_g4lq^_f-1{g&Ty?SlHTYLB$dWmDwt0XbR}m0FI}lQg zzhJ>c+K_;VX({9Oy}Q${0zRtdYWR3l7HSJd# zo+I17s)gtri$SXloQ3cY4*2ww->*HgBX@E@2k`{c|Bw(GDsJBtkkBtCs|O=o{#REW z7z3N-co4+HY~MAyPvIX{d^TJGFcRXaXaMXKd-4(IxAA)z8vfa&Q--Y?5VU{!1Tulg z7J8~4I73g{%6I`DS+Lx!LpL`f4p^=1qghyW89!4gEvMAbg+v&(%=P@cHh??FIe8<5 zb;0PaWLz8z0`ffI72s8^QPSnK{47`SbJhz%YwKehVHt$W?*8)hal!9-jO7>i3A!=QDWjIuy1=vGOGcH$MWbvGu6T-G(@)%Z+pB7fSTRhUL z8#VfuXBhP>)N#m>o<8}w(-q{0{VRvnu7E0$XZ8|1##9)b^iBBgugpu_DqB)uQ}y@U z-~s(JX3bg8h3uWcY0^dDWCO-2_;4lp<2C4+SVdcIuOa5i5a5#iA3a95Ux6pqy?=~m4uQGzqI9Ddyy)&Vf13e?1+>;Md-$9vTOXCl>ji5qYI>gfW6h9*S_dQK49=;L!5>T-wIe=EPP-b5aW z`AfT=96I3A5CK8J5hOUi@iSuq47?lax11D!06y-#O}qAw-3ctNK}|jb5as{7?rEUR zDbPK1p6oc=p#z}W_gtr}!$GDL>IFS_U`I#EkVU%s{Lx(qb2yb`VcAe-2AiA>z^0n^ zD6pQ|{cgy6UtoX!GzMC`1D33UvCmwOUx*yItiiPdKs~W{vOT+QU2LNvm|#)dxW$-_iV_C7foSb4+%vLI|l^v<83w1nXg z3Gch3FgX4b=KjwDBnJM!YAA*c-u8V~!PgeU+aIHwO=P{{*4;eB)K;aH?5 z@eD&4vHjrYqUEoDY#TKmJB^pvnA|&{i`m zkB8oM882Ie3P?(YuUHj8IoY*Z|DS8!sTKmyJ%AN*Rq^|JVr8TKFM?< zwVc5*(dSjU`S2g5l<^r1ilN2H`&7id9k$q^6F|oe>#DH>3jw^K9A0oIk-^Ca{B1&g z78o%wJiu?4ST%*uJG3=Fp8hBj2@5z2VZuD@mw@1X6!C!E4?(jWlR}nWG z+@u{Nw_|TnYk}zf3&>z9Hg=Y6xW)2S`nK0~PscqE^KUFM*Hw+lFq1P;Vsgd*rkZEv zTNt>52GraRVZ&ta)>NMsZqdfZ6o8$hmft``@V5UgIQrbUW&Zbo2sAc1 zf=IJ&uQ+wXT_D4H*4tL+h@C2sR{p~bj^5lm`L_rD8?Asu{G*iOXxZ$a2p(6rUja9D z_S5vh>G?hLW8c#iZ?S#V21s}mmHagRZxIa5J-`H2Xh@&_*o_s6f0%4(iV%F}oYB^Y z=vN?Di?p2skGKG}CdAblq#Q9Qw1~3+{^tJ%?{g=|n?VfgWU1-(_22F62-=$%Mqn&8 z*Y&p2<^bOJR1)-x(NQ4#OKYf49$i#v==K=3-oSpF-UG{s@(*Pg01l+`OpXSGNwm;V zwu}9v1EPhAU|0 zy03C|#rFxtu)`Vs$ShnHtU`5Sn2Ht}e)jQIE7{^Bv@o%;Z(Pk9 zUYG29>*%wt9g^}&e2d)qqxO;z%DCqBD{_;JZ-P_mZqlO^wK;-ERd#H4gLZBd;PO!9>6NGF~rUS^#1OtqIYZ1o(+w?@0TLu zA_3?GF?T<13`4d=K zvmRAVQ-V7p7}%43k4w0xluQrvbnwif-PW9 zj|R_5fvgJ5h&h(&KmuK>Wa|hKDASxK6+nx}ne_8_-Nz8FXU7~rJK0$D=wXeB6#fd} z>+l>{o)2_*vfZ|PzIHhRz>a>jrxq*y@*#@ zE-ALrA$X5&oX!aX)Qo~w15qU@}y{gObdwp zViIbAGZ}@Scx$4zhCNQpzx1EQsZ7%IwYHL`6ouN8t%4DyH|IqvjeNo}GUM&I-#Mv= zqAFE%{1rlnWqSOD;6E0M)$K3aV!R%eq z*+&K=Emp62KQ=y{hTU{k5`ToB^E&vgfN@|PSDs0L8HhDmO*Q;;m8z|@7)ufw1`bl&=5j0@+m%Eso=Vv^ z`t!8{Bp(|Is$!`XR`MeNOPK!4PFX_liQ+ao(faL%Yt|Ycx5*-+zMvVpC`W`b%c__o zCoza2&wiLT7FssK^*$l-eG=*nnO!`*%DBTkj<|gVv?)p0Q=!@>g zZ+Ms&gEsisnNjOEI@wuv3XzB1jrC@YlLJJ+N&vaJFHPi1kXF^(Txae=|NcniNn&UA z5p?<<#gj^bl?ngT9%5YHr;edqM!BkAv=WIHgGoeiN0JaOx2iWRQIABzt*UwG@YfNr zUk6f2KXgH@HnF0;cW^AFtof;kYIrh<{$-A`@_}Q8GW*V~Pv>R?dr!T($_>HKH>0-)h6>iXj3Tt zqCVsIGc^xRDwH1*d0eMN$E$Kkw~YN2T!|i<|ExC9lCpgwiPNsl5@rs-sG!OF0ZeSb zfKn4*%U!PAuj_9S^44auNVh6D(7&7bjsppcA!m@i?KgE#nqdq<01WLD9I{c2Wm$_TaE?&*#D6L+@};{5mp zCg?+P%@`p@Sut|;Wrs*}<2$o&N#VgK(Ju39A0s-0e`DLF{IORVgcflf-@NAZ3u9~b zVc?r_mLBEE3OP|BGQCdaQKj^LIQ&4JiQbrT#c#@prh2h~<)#uI|Ksh7jk%{k$;AyT zB3w$YY>JwoFN7Ua8d*$2Q;O62?&keX2)Cai`lUH=2cl?R&i#EUOVS$8_u=;J@^L@L zT7X>vHhg#d!tL2O!){Aj*aY^z%A|Ac5tp8uoN*i5f0o4g5kiHT~Q5su}3 z3b(3SBS)r)DQ3j$Ga^#QhX+qWl>#H?Q+~(k>5gLbV_}7TdWa+t3r!YgSK;0k741NxG^&arRM)59yN_=+ z0S>hEk3vYFNeaPJnG;i^#v8vO<0m4QycZF%FE_5=8hIk0-7r&lFv;UV@M_e7Z9s5K z8!Jn&l=%fPLQ8T%ZZ{g9oyox*Zz-4=tfOHRQ#~Y}K9Sh+i`<+029S|6@96N5d3b!7 zMMsU>2Exj5_%Ay|Ep~+SY(!(McUK|}CIT(-R}z0Q`A2Or{Nk@%9Ogbug^}4VcFC0s zdyY`Pr)^ZNyDxzM*D+atU}%8Q398D0mcqDtA(M73!!7AIw0*okS#9`SfYR zXvb&TbNQI==L%N9YNMSVm?j~E74o8s$8UZA=gjgQC#`OY5+{QX| z-cnV&6PP%}2>i`K6&3kqq&s^E{6blCfj`^t=Hen(5`(e{$nP_J_;@dNLewpYtBb=u zxuSJwgFPXrhD=hcp0O%elfiS?nqE7HuO46_QjSor%8|e8fyc^t@zF%}b^803 z9>h<<1NUL!R7npSAxbvR)O>`&RV4JP;re05Q zySn-yEC`XeJ!Q9DVZ`mX|Ml%?a2dmXlS~D@MFvqzVTj7Jmj6ihhyBv?pxW}?%E9ze zdufSo<(xpBfWz;D)&<@1k3wY^I!Z~*Lnt31YNj|YbkM<6&bCllE@Q{>i_0?THP|G} z==Z{!#R&Giw_kh$uD+}^ZF`6_gd$bvBZuY%<}sXj=_57jBY6rUdDaF%Iyc`PxY{pB zZBIb+w7v=$F9?|Oj~(hQ+^zTK!wF(z7jnc&H!KjzG!UL~$WkhmJL4lq6KoeC$oezf z+h6F77MrV7icCOcn;fDfU={BgELA_x|8OTTdAO>wB@JK~X9!BsiEL721R!Ux$&h zhl3KvBNCKFe35Ph`3ED@FmMWBW5Ka?yOOaPU(0d}vUXjm*35ZyXh|e!r4TFOde#(j zOlS$@+muB{dQDI9muuQI)|~jxB}gLBh10T1%#$z_yX!q~NX3tO@f{If7_G|R)ZL$` z>#r}^vaH9(Y~>L#ER%$F&hPXwNbfbm$}+$)D*TOHIARQBQdAJOS-2P2a1zvT-PqT# zV%Nc9;FwkZ9Y!L?PF*T23dK~VnB(@7rPfFK3^;HaGwX6&yeOZ-{&EUNAz_Yn7W1F8 zcbfQebje_oy^OCUdPP!nWe4V^hhLd;!qmYdoq5`Eo zJ7bUEbvr>vR&&loO}00=Z#gJ1vvj)GY{~^TP2z5#QGY>8N!#nwn}CTZ@9z&3lb(X# zMGr9xw<1%74pHI2@t}zG`*WG-^EDgjR1KsQ4|#ki=PpaDB>wz=5JYgOmoJr zLRjDV&m*^Rymjszx?T=H-Ny+u@MHR32TAPqR=FnWP~im+PzJJLh0=?5;Iw3^Al0X~ zoNn|8dG216BlXMB%*%!MnTk^rNYG)6u@Z>UCfV< zup}t)(U@-|fRVOu-9dSAKN-5QBs3{S8ElhcztF%tV~7MNae@$hf&laUehmv=j^4hG zUcQdEt>$C@hKT5(z*o-QJg~ne)?crLXh;c^Dg^{a815DQrvznzIj~&ee29s9LDjd3Y9-Jf>sGt`=0FOOTo5dh|jPni&E2ZRQ*mg>ok)ibZgSZxGc|J5))r zG=n!obg)ck1mDGr)iWvrq@5g9=)>up3tmET=m0(VY;(>Gn<<&N6&6|#B}z9TQg<3k#b0=slQ8jDmSp5so2Us}ZK0dFxiuf^DSwhCiQ>pM|HPEs z-^kEHl!T@c#vDIf4ua5#8GY}9A{QmX=sEgJgM~6V=UI4*Zl{gdy%sDmhMYXXGP#pe z9@c5fsea2!E;=#_NB=duNki>bsq4b@+1v+7;65-6p!$xLs9Spp5B8Q?J->|0ol}~soTqJPu%}<}<#0hrG`t`ynB!}G zia$8maDulP4mLD$G#Q~HSaO;WlqZ%ML~vlF3N>MbFN*ODs-i=a^cNsjfT zNz@Gp^e|cBs9QeM5K_>FD|(t`{8JKW#tQL$tbM`^-)&mj&PHQbTs)-+fU@tPq^Jz& zyG};xgHDs&|0?rYgU$e1CKRUFTy3zAX0X8Y`MuZmq*#Yx(3ceprH2%$`|zS`1JiiK zHi(xfcwjq%&4Tb2rYmWRw~xkwAGvok%OFUAG}pqH@}!X(ikzPQQ$|FonBhT?kexJz1888zlTVNEHN?4QzOjLs3QelPEp#HpvIN}*Nb{GE*ao+f6je~85-UHMuO_=VXAAVwRdiOS~DW8xUi=_E3J4} ztc zMdc8G#>|4NSBl33@Aj4PBX?zJtf{@+N^l}k)h980B`USkRT&DAq2~__X_0D`>(=f* zp9X}qyTSJr9`^(8YL&~|| zpF|nBd|45lqxf7#$EVxW?ec2_%=f&O#rvTXBu#7ee}a-#Re?dsp3^Pzvf(3ppS z62Xci!HTaqwdNd!q?U^X^Z3W@ql}TIFeUlm@l{c2VnM^CCMM0-Ppl^RouE$tfeM0B z%S|x+j6K;g6~pD)e>ELO62K1EFpgO?fLJsqusMU8HW#n+d1rS9A-OA1pC(+7HAsyy zOirqUv0&XAT69f@OLH`)-Tr4sORIlloBwt2S2d_yM|NTbnb7-@vup*LV0}o(k6s#? z&|rn1vdk0_!}}4-hvB2U;iHE^%bP*qeXgU5(K~c~8<>@?a&h=5HU%GhLUkSA*cN|P zW3a#}w!mT7R4e|9!$6y4tx4VX2&Hc*qVG@nuy@+Ed1hfKtA?7J0RCD=Qhcz_bg)<4 zyB!PpwM*Z0srPwaox>0PweZnR>LA5X3rQM0(O3D&-Km^<$BYFygS0eN8MWD&mwjQY z=iY0VH?LxGRcSDP&Wq_wh%Q8Y0$Y^x3H?rKI|^Ig z3}03}=b#plCi!;#J5IIr{B~A6Mtm?ha3IXE0FogG-KK|}C5KUA!B z#HrcXrO5=m+?v-g!%H?F$lmDN+c>?2$$+4F{W#4W>mFmq=wAm_+|kRbC<6@g!1lPg zZi}CPO`sSRGd43FZl1<_asHmqm>D`~8IW`v0h%w96*N$31;OMd&O)5r{;oMEGT55ll5uKf_q2Ph;QM{K5^wNYSX~_*9-<%yqFw=- zO%obp2^?cniajA6wk1s5vT%S+Vw_=)i`RY0S1d~60CCx#9EQj+@xk71ji1p-jKt(b zMM-kt;L$ail=eph3LOKAUs?9)SxUb?+pCS%_Rf#VtfIT)4ba%S(#tLmH-XADwS{s^ zk!YTT3djMOee-e-SZzIrxgk<*u2l@O6tpRvwsfy?br^A@auT9*lP05hKnmILIKPIi zZTpiKq5v*>#GPJ{mO7{k>K8KsmoxD+$^wtJT(3%@EgnV;ym6_YxVDX}cWa5L>cY4p zzXi4yi690&?l~KNOb%Aet{Zg*9A`B{e!O20mF@28PYvhv`L)ogjTh}bnm^7I34G1Y zh}!?Qu!Ip<%m84cQlKeOsU=>ik*B~Cp+O5Hx~L|VNiLNMOVARdwBXc?{Sx^ol+5_M zj>_;$m7yKEdhY@l3!9e^7=DhC%~O+Z`-sV{&`Fz~;vqTTPya3zqyh?sALi^-*vLh7 zTWmE9U%d(uK^3Rw%_VesA zNf;VQldTfD(!x(Hq`t2F^IADN_y|Qd)568^f(zGM4;*t%-^eiElrl{Q^;fxCg8<#- ze3S*t!t|7H8H15K+`RoI7Tw#vLc6qDjOjrODe$X5$ojcZFXE=~et#FAZKJz52=1%wOO!JS|sj?kZVd(w-!{EbqGv*RAkw z&#VuR)R2+D;)uRwQQr1Sb8tIT(X*s4(xJ7jX(I0%f3LW3shgh0E_d;)b*}a+QB}Ow zM<_d7UGU-aLv1pHq`s^X^_3cODb^a`>Rz|26b-~+C&RyxdM%|$pp#{9`WE}2IMuO8 zkzs!ol9!Vt4?ZSW^G9ytFlWZ&?neZQ4oaRh`iqS*jdn*L*$Z(Plb6)1XE}0pGnxep zFH8S`OlQhY?7GNWDUx1tYf{T^Tq9uO&L@+)21A373_dIeyfhhdlBQS^bw`FczBlV< zxN~XIFB420p5f~_!vwKY0=%q28z@H?rUzcsA##jidaR@7z5}MG3i#09d*Jh9-LZTg zdf$9@0Dmb*Cl;m^D;G=Ror*(JfJR0DPD;XYZyX?Z5*H}QGN&a7={pJ@IvTuBKV(f>m82Sh1z-BT%TEw1N|4A;kpS;yNfLwkb{>@?qIb*(7#}jqiC({z)!fDJmuHb8v#VK+Us=|% zQq>YfDItp0#4l!JlSqwIl8fozAmUwQH|6Xxt}&iAr)C*IhL`Nz$dfA)E6|FyX~WpG zd8xxp2M7w7bhHn|la@pgQyVO`#s3LAuR^2{S?eOkLxq_Vya^_Jb;j0S6Q@Ry^*Mv2 z+<715IIoaHXTU8{B}amA$(5_q)fg_AVBB1F;v+_E1tU7NHOTx2mwxpp*jyM81Xsp4 z=Qb~YsCnymZc}F{bnjkto4a&x{heqQ#J^WAUBpIWq6FiZs-I*XR`zi?NBtEQ;gnt3 zeHRwFj*Vg+LCyTyiRTc_E)7sjiYJOy3)H8ezv`i1>tlfPKj@fwK=5R&s>bxl>V;w> zd5HrM2NMpy(?C~2PP?_LNf3;h3Hw_Po0`sb$0WHpNpbYlUTY<|mAD$GH`UH>mxp`B zHEg(xr>%D&uyrutB%yX=EVFl{3OoV|81!H+Gt!Vl1-o(>7``Tr2KEcilS!Lpq;!r|W8orx0TQ{Ax=xNd z%+nwDCv-G}`b#+(XmLQ^K#L>gu=#qJfm}v@3dx(u!$EQZo2IK)sOHI)Nx5ZU)LHNY zRPjrn;+(jDl9xYx%?bCk24#MM0PZ=`KQz#cLP>N+NC$J!~pv$2Gw9m?|Grhvo z#HD-BH8BDeM54nVQ|xobmu-=iY6_@^D52dYVZ^9XqdY_k1ZujL6i8lz8oM(f)u@(C zi595^_Lx$Ck?GuXeI6F8x~b-+E!ypmqEsW#q@hylYbha9t~O(i)?jB2L+A_Dbg-g7 zl@oD);xMfR-%hCaCoin$9oU&JK0KOpI%O9mW01e}DJZ2z35e97-_vD={F;Un4_b3+ zdJahtlyXIqO;Yfz5wYNqB#!U+up3h6r2QtfZ)8pkp>N0qU|f>ApYY8H^-^9+Fya9A zi-wNxt+8K+g$gf2o6J5>#-7g1u47BYtt(T950i_eBKNXb0iIlIj|;5j4CBHz|a^X zB&=!#?D9$xk3lwLtx}L5B0aA_cb}{B!|9!3-LxyvD%jF=;9yMflPZG0X*1?(GpUr! zh`vmw0+G1x*kxQ_sP|3B#KQ-L#eNb%3DxqcJU!)or#gMP?AJx4`E;-QS=>P$(;;L1 z866L}BN0Iia=AE0n_Q4{9f~GD`n2;aC@|?}y;l9jL%}A=#H{0cc0FS`3@Ig=#g!BJ zxiw^|{MsYZdcnz+Ziaz;0=CPrytEIWM?^}og&t|4a5tRPGeeV3HWu% zcQ8+>_+ipBxp|U-azZ0@(QrJ&pZo2K6!^;jEn^vh%%zj1LmsqHi!6QgRS0aA|zZ zt*b^*)Wiq!;mK{tjxziw^bd;QSYv!W1(={J8BlDssEe3nv_2{#puN%eTi9Hb+oVrh&i!nP6D!R zSZf(xMi>@!9?iPxtf;^eBu7E_!13Si{`kPO%qC4`9x}dZY+%RD!!?^*s2^d)6(09U zt-tSy6cci7|1W7tA@M?@)0BH@Rmv!>?)K8=T#r2i4HTUnUIlQ`)GS|-;lzhJLH;e& z0!3EJPm@gQIS2vem{j1+6nr#%!dP3=6nN-@ri-pI+%lN-2N zq`Gj_SV-^@eWrQ(<>Il1G2uTrHFoQW{bmF>!@pqnM9b=!s^Ec-{57Ex7Qtz;9e!T?)f;!40%kb^&k%Hfis}BlXWD!T9?~{2pj2n1~l- zc;9EnHykJQwZqWS>x#=5B$z3ruM(hzULYh{iBf&T0Wum1_zQ-pVKsF1d6!g$w$%S(Bg z^F4s*5zA|q3hO7Jm9?{Tratnx06riL#5Q_AQQt}pBIkNOv-Xfev;Dd<(G=GNsB zjB$oFt1^UDXJD9Z#3IwrS3p_$eKQKlJGSn53Z(iE=8CqDqo zFCRCOUhegvTBVw)nL7FGjFuQH_6sbu+&T8RFKaWZyCB)62&*%_;?+t8Yoz<=a&>Kj zVZrCtgtd#=F;yY>aDUcR!i)us8QnJwaExepK&OfuWhGEHQ{orW=eQQ@ik6DT@1B+Q#lMM7x)&x+S`#q073<}Po8S5 zrU%tF(_v|GfOg3H_oWjHDj{HH&?W&70dxb!rLol#grJ5HDZZy`iyQq{Z6UOU4Ls<4 zfB;$*dtwi#S72hDPX`Gb-ItYcw60dEf@SVSqC%d7Ia))D_j6g}ZxX%FT$Y$X?zzr< zO`CqM3W&Sn`#mSeeFUIJoX5p&EIdRIk?|(IPZRY7GX_d1nGer53BNE3_Xfmmhlc$8 zfXF3*e}*F zXSc80^b&?xVs*J^fQZT3j|ELAx3P z_az*HGb)q8v0si}4@BG>a)mJHi1)Xi-)=fUE1@GXkalA*}a z<#}#?K=Ep-R+R9UuPV2mP5s7oQ~Gbiw7>Xqo?XQoJ-AKQ!&$1}0j%=tmrnf0TasQJ zC-6xFsr87UXA(x>(076%fC9^KugTSL$F>4OI*dhvwq*k8lS$vIEsz*ji!IUoIMErg!&M*qf2Sh0NE4X*m9 z8?7|Z8!qkj;%CG4XmMmg8t4YO2rZtFCopAaSvInRR%C?xa>yK~ONHnK9TV%49a}MF zZHlc&;N<|%oR*ooI(g}ZUSq59(#}Cw`ItQ0T9X$0%3)?%uo{Ydvr%$WtAxaxg>XDKClWvh9mv z;*~c=Py7cwb=z1#cYWoy&^!2Dg#ls=3oUH&w?O3GLx`lq`Hm*a{rvF2B)56ze$m*w zhmjTEZT!~D2xY>$olnF5?PoWZld}Sm0tRgWdt9HTiC~ru$F6+l`@Z_H6`U~8W8`~t zb^s(>B5{<1J<^#Nm&G{6`Nz;hM7Y&8OXK4!Q(AFo9pR>o*+;L8u16GhD5l#@++fSq? zy<1vvJ=pilY`+H=AI}u)t1UUxCm6o+)d$d*y6WlM`vfXiEE}E(Ki#4e(3gd3;#56!gn}Nm9;F$urIuaZlZGCJyPS($Jg6oaw*jn-T7K>wFaA@p#1-C-Bt0$Y&ZLp6_{`Dr=T3z>c)T+hm92Gbb92sw0H1| z(dT>m1f#j9^T0ch3cB{3H>9L_!8wc3r9#}3En#ylWs^qT8;&a46$7WREnOSVC;Rc^ z#>TdJInEzH9b!P)G~q4IRd&tRDMr$-H_lFmG1+0tsO)l{YWpBiZ%Ci!f2U1%rK1t1 zd~UMMhLZs5=Ja=u1=Q`}LGi7o?s1o<&zZg|JKM>=KpJs!J;u=3=eF7>?<^^601X#Z z7Jvhvdz;;8#Y}I~W{R2SHiix}Rm$f~d#$>T#|?XXx>S?8+5tL)k%Y!eee$z2m_teo zjBgm%5A8A^eZtUY7r8&0GpU(B-SeSOyKliAqV?^fY7R%+A>mvdJhJ=MQ3CHvK?pLd zc5Rn`89B&I!-rXoOTVKSvj_zAJ~`fZ+LJBR6B8c)9>}Wr9n3aXY>xB%i*j`Cs^%p= zuNyirT#+Hp*xv}q4J%YlKuxq4Ip`~>N6a|Hh)1-vUxLr>5tElV%)3lfZfjNng60Pv z#NYgW*iT3MY$oIV7mc0`uwCp-==I*fIs}{;b?$8J*u3CQY%K-kd>k!IqgiJEnF?p)Wz_{5+@F1Yrarr(T;*13A z{UP@HO;=Fu##K}`DKuqXUj}CeRAkyR?6YlZ=Yfh<-PDAgt>2b<@jc$ho}qs`+O*r; zV>JX-+v(Ar^wQ40>$^|Ane?!pukS7bz%OA0l~!0MUY_0q1h&@pp+j4pnc2SK6>F;N z$(e{{lE)QV0kRA@T|K$jRrAcPuAU-sN6SIk_eT%nF`CXmm;2o4i@WVmXEqo9?!ew4 z;&4=v&*hBu=mHHZE7_6(MTS;;64opZs01f}*XXh2X;1p;w&jhKY#>e^0Y-jw%h2mpSDvly~*D>l1OKfWq}JTC(B^dbVpI zLtnFxb*2$J-7}@@C^3B+HD8|>TCDbaAaTV&+o;1730u@&*pS(Z>gG&~&rR_D4g`lN z2o9yMJNin%E)fs+%-VU~A}x||yyrdi^MuYFdu%kdEuNN-lXuPBVLEN~FKZg{J(D>$ ziiHRWXB2QJOZluA58VOp*eGS$vJoerl1PUQ9w!hELTM6Vfvj`Q%A?I6Q=*_z*OeOf_tOfGx*mrYyr^Tbz~jFP6!?MJLl18 zv=2w9<0fYd;jPEpza9h`A2pIBQV zi`zZYX%!pv4*sBb6E7nC$Q*aDfYQ(T(Hlr-*JIn+eeI(xd>&=!Py6MVC&tFbe+b13 z#a%rgPZ7nT0>e@KX0IaX6<#jaun;m#T-h;yWT>JIEuaFRw#@@d#OuuObGtjKvh94} zahoTeTB4Qi=C6(>d?S8msO27n`|~VJdEtbVosI7A`evdG=s-LiTe0a;Ub)3$CV&<3 zyy0W4`vd~6rj^(-H%`tJ(d@<+8f-P_KrRv-t9aqLeIR*%bRL$3LHqIy;-vCHIGp7@ zsZ(VO=7tujf;&CLSNKyY6AH_0Y3JJMY6JcFdifL~z=zlYt_RkRZw|mGv%5F&Y>bT)8**T+RZl7K? zI|G$!Go$~IuJ+s5G>qecx;WNWw_9;pxTGYnIF%o8;wJZ(f8IPJp|p51h=he#t|ZOB z5k1ImY4P)Le{R*~&STA9Swy(mmAv}b-VZs4it=uzap8=cJIa7Nj4$(b_~@ydGGG^E zZe6GKzlwZ<^WWnLYvL(8Zr=mjnC{}!ZtRt#=fJyZ?VYY|XK1K^tA$M9$-(;T$=7K2 zVs=(TjQP(CvN+>k=KYopi$I90Iog(9c|d?__Ff+$fC9a4;n2^}2Y2kaf+N4{5VuC&Hlx;sdy zYrX`D!CQLZT+_tvk3mIVBkpcxX81az_N3 zI>&dywSKr5;JdHJjQW?49$SwqRj~X7Wpi!!fd7sRn1M!C4%=Wsw7m4aa~U^3;0Ubv zQ(fM4n#liV&ZUiN`7hGj$<0$1xw(Q(I4GdTz`oU+{HcOkq7$ma9H*L0+(3Dm=V8uV z=0}Hfl6K#0pah78q2Co;`~3*@{bY5~>E0c^mVsn)K@O8_E=yM@Z#wdlj36hQhb(B% zUC*Arz&iE1o<9}|9^D+f6Gny3pr_Lv^D-@r&n;;-oqc10jjC+F)O zThDUrcD2^jCQxNzhua)MzgQ}K)I?1fFzV|^GIi(#ec#1ytHir-i*S-%-gA}r-^6_Dn(OudtligG@;LxPHW z5$0MxuaJM}kNN3i(t`8Cy9Pe}jLz?2AC~hg!fy7~)f$$ejYmxT#(&=+RSI6ww)@@d z-VcLY@r&DQ2o3AWN%}hKhtdT3koILEe$k-q`p;guc+7W(K|$UjXF;Psdvm+QJR|S* zxA+Ib^zugu0h*#TY{tOIjAf&I6PVq4BP{qRn%noEya0v!>F<-EipF5Vr-P|-mPXIJTPj>5CuKz56Eo9@L zb)`F=@}8g))Bt9t>3WVhkmD9L)8n8HPCBkL2s z<8NP?*1iD>a{n56X6N>4Vb)?n_^9b*(AP&Q|Hnt!>)^f?t5j4-1ff>M050+e-EYN} z3=$c7QKRoktIQtsKob?TMfn7UY2Pt(ZFz%}H!CqnM>DScf{eEs$?e(3R_uEgKFOUl zk^%Y%Wo+WoKV6+&8k2#B;41gVkgpaIXyXBmj_4Z%i>>h-qj4ASss5a)6l$&CAG-TG z``KpzIqmU0W&r$ZwI^oobh2O{9C|FSn1KOE9SU&V=8u9K{GQ-r*6w2S3I{1{0`PS} zt8DeA0$U9HywI;JXWyT$=lWgm{B&E|-5Xx?{|h}i5Y|w#Er8(BatCD7Xg~l#GxMas zbX;nB{|e8a*2me}<4+RV+lV%uA+c@w*S-PFxMPYH_8-PPL*3kf`v%Ch4x%q6SPoXU9Pf*h2TJ&k=l`(%=N9M20=uAC%V z`iG~$iw*HF`wbQEVbVtX>oE8|$B#};$HU!Jh6);I=0mKQ5mrwh)AjGU&rYq)51eMc z3i&sbQNmCVjvp^Zi87#t%%cR>pMj=xMZE_M6fiFE+4AI76Zv0`MO>fXl0)*Uy<*L% zPY@-5oIB8EN80tSnw?L$;n==FwM27cvj}rF83&E_rFYu3Jjxo|n)5FmbPU=CTx)x?X?G$PE;9itnmqZ zm26~7s3>@bB5oBsUvP&6wOhvt&rbJ8Jf0KRjZQub0%&dgswu<<+!`}N3Y7)p9||0* ziD{9psT3ln3c#iSKVpQ_n!Pn5f_eV?!9dE#^EzvhCiBJLyL(|>wqmpdJ^zQSw~VUl z`QJbhl`f@Q6zT3pK}4my8|m&wxcdfH{!(Myu znfc`NJhP{D=9x!Gw|t4h`&QUyV>&5zJt6f;jwkjbd%{J~o-`XwdAFMg>K8W;7y*!8 zr8YXC1Ec~l34i#sFBf;v5uTIHw;WcZtIY`lH22&_o7dViUKTz7Q{a%_>T}-cO zziao*PakDku->l47pFlh1va_HNVzUHcy!y0137TIFle)oq$Uv8IzRwoljH&hyR-YJ zMAldzGT8xY;WrK!S329RMyuQBoF@X*T%-5(YrdjciP#f&VM1I$+TGi&lDJgyh%+Z{ zS&KIC76p7CZnu?7lb}|;jZm!vHMPx#ct{Kp^JC_V44{z_GI7b!3rYBU1o<>xUUL5}6 zFa_5Xq?141i^+}q@R91M$EHNpR8IFIPA*hrD9Q^+jESED1`+f`!Ls?SgxCkj5(&p^@-k9PP+q9Z_L)%(oJhWjku9q9EBmjrm=+IK8n7rr5w7p5pJ#W|P&udwU zI!s;XIQ^c@0@miT>qO4)ul|Y}CG;bk_ARqvo}qoc-T9Wzu7x#HdOv+7Uw>DIbqbpy zSEBZ-9c9q;VXm=eXcV<<*xp~_gXWF`kYA10OQ>LUO#f!K>In!kBhmIaPuE~EstrSnXB_)s* zYbaFz_LT(tcWIM{`%g?fh0pzFSN*3c17-8S@i{j}#XI2`FGu#p==$Qg)VNMvoJSHJ zmQtoBS1lSlf9utM_a;$PaVvkrNc%(nFi20&{4*qag-$fjkr4Cu&dukAn-MzvcN~UH z(;cJyMDhG5`90rrrB6GSjV|$my&5r9+$!$#-E+xkm1n1kUJ_$D{@ZrRo!fTbO2S8` zIKNHHK|6hKrl*f0M7{h04G56P#?uMhk;0$-4qkOX;Hm8K`B?3bxcxRjwCm?AthAQ7 z;1%fnU7&PjKRJc7r$`SvSNZ_fFXjH>h!5Cis|m-byh_44Bq>FEKk8~IKPPe?)(yb$ zqT=F#c@c2JwMC!PTeVoH{8!gWCS})dR6<0*;+{`Ws;tX_a{8Ijeq*7+MxUWmzjpPS z;-i*>0g99^`Um+xPQA(PQqHz9A_G-v>H*>|w3A@eZ@PC+q{AD@iXtrU(~CsvU@?st$TL!@lJG z6sO0}a5pAqa*dt4r5jjH!F-}%OS4;+ll~JMZg+J90GOwhB= znop02#aItn8a%0Ydpo<20N55bJ{}-;nU$afEG(jYrqbCD#S8^M#1TP`8xbwk@9xnw zl*5D(NAL|t?QnxM9Ted#BYk!VptjMN(f$XQBAVnNJJnKJc<0dQj=3CJyQKs+(I1BgES4j7~7| za%sS1fIM^F6liq4AMzzqfS0+8X?0c2aqZd-vOe}KZC87jK{Fd zZHmY6{vFPje77zU{+R}QazJHM;iGfHcra52y|M?)kGWX@Yl6_KUv5HiPQc*ECvdkw z6Ze_=N3S%zws#LzK5}Q;wdBT_9TGzpAkQbXcd%KT77+&2sX*dvPr-N{c7<5$U6@6V zG`c#gVL>hu2Oy)r_HRIxvvc=;1U}&KLW9cLh^@4tuS16-h7VvX!a-U?q(jxq8=ewL z(+9S$;>s+`jBX;7kc#SvWd4{VJ~Ghg7oB9VR;{q=`uAnWH1Ja74Oa~2=S0uL#p6}u zY7Subd_byl_*_-@kLYOkY;TQ7THkutW2yb0{!BIiB$J;t=gtw6%$(MpIU8A0y!vb! zW$rRhoA2sO5fA{p3oy2|)savCnJk35&Rx5vGmsT0HJwd;*N+Dlk)o5&?CXL{)mefH%8SQNCt5|%}x{fWTo%#1q z;95xcD%kJy)7X`hWB98ne;O+Rd|D&i9wJp@m}E*QM)#qV6ztghzmVz&LMlNXF6hZ7 zJ(%l5FlX;W= zbM{AeS4&%hIMf_v#0EjnspN0{&m|Np2%5)>eeN=F4DILsc5MFnYfxb#+;iw&fq7I) zDI96hL;yUqQoY;RsMr7DiEst7Rax}W3Rr%x{pT;H$M zqTcY45`MW*@{q?;+^@z`~j89gtCFHRSebZ3AMo8%+W~;YC zG^G7!h(_tU!JQ1NR^uhphkOa0gP(ov==`E}f4=iqP2^8m0^#BD`5mCFz)pp)7MrOm zIH>)S`8(^Kib}c96Z`#VSKDA|GnjFMsBw$zHv#TEom-ZSCLNlHI*HOWfS&tSz2qmI zv*HaJ@yFh5Vp6MiY>B@mfc|~xy#^T;0__hBuN2~LK~xi68^VzJr%%$60e(_5oERdE z#gG+6%aCV#g5S}_vXIRZBYQjitwApNvApHv6qD%=|qR zD}6}upI!JDu^w24V&2fTPhGOjG*6YpoL9_&f(JfAqu(oPvDM0h7hqdt_y@;6C>$6j zcnk=U3ThdWcR#CJ(TT;eQl3K*J(pD!4oxK|WL3(L~7K0m3#_sbb|euPGUCG;YU>_L&cXb!J?D;{rJP~tY= zn_28?H%$#J%oc#L#sp~bZfxG5V?tZ@KCm| z1BoMGBjaPs0FW_VQAvN*$Ru9!P%~v1dp4&7WPZn^ydm^na#Y!CYKi;#?NR^Eq0d!}$WCWzkZue}@ z3bS(*=#O{K1OcS#b~K{PrK0k!d-dD!rs2&sH(#ao8(E#ErtP9aQmAlf*E(OL5hoJH zN4|w63Gd}z#+vWaG)IF*at1m&+?U!cfNC%M9z)J-X>awwlG^CuIFyhALJjEP{J#_< z0X6xi1-`DwKLmgPi!^(2p40&ji;4(qeR~NCfRU#mgZ@C()gN*(-1l9IIu58O-czp_ zE$0%TTnar(j}qVjG)XRU0Bk+j5%4`c@b`oT5LvPtay?bQt(C`n4iKfSxi4NfmzTDgluVqI)6BUS;^ z^LwO#f_^-YcfWP#Y<0VtTwO^Al_dld2%-|xJrG|%!3O!}o9&mcV?n9u+K}N?&Ath> zpQ|}}=j))KTVg!d0eGM^60V+?gJ@D@(H5TpF};MhkRG2Efv)>Lo2+*8lZf%>iQOT* zB6k?z?eyHYMvCBv_5$woNu|XoOwbZRAALdqCV_4>(2L^S+8iW7A~LPnNuLQ0Vt_DV zU)0}#VG?Sl{>bJ0+qy^{WLthb9xRgfX$3_8nYjh^v50!cAjNcAha>ilw!IKx6p7c5 zMglao71cqh!*z4z)lY!E!WPnJ_dAk0A6t3nGj7P<|K}%_!uJbHdtl&Cz`(=gzYPnQ zp@Uadn}_Lsmm97?6d}|Tc0ge=@%iC%@)so7NBS*JZR>on_yfyALyR#;7|LCN^+PRf> zj72fQYbr{-=a&Hnk;zQ8E)T1zD)j%SJ~^BVNnhDsA_pGSs?Pxgp=+m6oNKaFY3`Gdbpmjh$NFZ6)D?L4s$8?3)7<$<&79r7%RJ)H_)m6y zdA2z+KJRrb0H+h>31LUHFj2KC@sWL`L?v>P9ED z%cSyMdbjW$UsK<@-QjMUb>-90?#{r@=r}c-wM)N6Iw_UwTBp*d>AEdX^?e*aR+k-s zR#q!rH>r9Lyf@xsO9D2HbQK;z2X=@qthHlI&#jOV0A=0i^N$R0gqWKo_;g6zFd>>1 zdwYHON1)$%{~GTVNrb_GRVRSgOsaVM&u*PCV}@>)es$AcfHDpUNdbBmljmanSV%1i zySi(nx_}2YU){dIkVyi@iT-x9JO&W6@b#d`zh!p~9D9*ZR??TR5tiQJ_}&$lO5fbh zrd%A(LR}CX;Tu<}aCdkDnN_E@GxV<&)Un9v%X60^y?|s6a-a(k3ozEssdbi-p7A7clsEl6efWKNTSF_<*Ew*9IFT-lLp6Z0Wd@ zjrbHc^`eTBVk=lh63~ExDtaxSJjH%%OIW+nvt{Hpvmi)7_uGz=;QKU3TeL93i7n4M zDvz2&4_EGMDX`b*9+0wILbP>cTGeoz9v@~QS;Eo}^W?v9bz6=H-bZR#0n)J|wDTmc zqcZs_2KfdjjPvk8w}7>h?on~P=E*9A4d?+FWvcd=%XWm{fMZZPtQ?y1Klz+2Lfwt? zmLLnzXi{Ezl`C6Tc76lOHdj5N@ONyH>ArR^AGe>p{=ZFQXYy)W7&On#jNlO=7a92l zh}KO{AC128enp#-wn)CZ$hvhXVJnieNj{rg=i#uh28{vP;OKT!O%EZZv%~k{>|uBb zirj0T=9>0kvZ>&DrXabz*x}9f$)ESDPWFe{sjvM%tY$M0$n`1&Idx;Y8`yE-(5R!X zU7LYm+O~7IriAVnSeDHFWS@Uphy9RNtp3#d(+rh*B&xzsq!8XbT+~-^_of03^X02| zXz!e}(&e6Ik_5r65$;U3Ztl}y-WDU`b(>r=o1;dOZnuBemH%;z+)VoFuk%nSWzeA= z)F0ST_-^wZ{Um2ekX3HzcY(Cq^46JzlCpCWY>FRvks7U1HJ^`NxE*!m&tJpjx-*5Y z{4Pc;s@(t0+G3iR=Z1LkSju;A6hs&?V%V3zrREi7;(Zk1(QXgoO()w*z93`y%z)Lw=VCE}DvS>$y zY&-;qmtp1P*w*(bu2hi6nGa9jiLRsbOv^Ly@E37?*Zct##w&8gzI1Zv-DtN)-ExsA zw>swcbGw_$fUD z29hm3@8hh-z5O?(H}x-Ek?Lea=Vg>smfUZN9{$n#M)rIPmGi!rY7qE@_Pr1PGN9%9 zHR05n(AE9LaRsFpW!dQJdu*wN*Bl4odmj|=fH{}%7C0@6FS;{=HeyejKnj?S>Wovc{? zRVEWHRR`&6dn0teVlQ%@=34G*;eU|U)N0yt?L1UmG`@qeU-(Y~Px1Ok;s!-WjW9aU+>ZS4v4`U*u0BrS~-UVOmIxk|ozw+jL8B z#qt$J)e{$Y%c}WCkNem8UVb6b6k9sj3jxb;D#+ltRTUBs%h6rj)n(M)lxOF>!NKV> zO7B~8q4SldqPOE-*ZsrxHqPE7?e%Yk`^tM;vU(dW`Pfm4-gh+AJ@h=0)luJKO>@_k zWvRnla#q7CEIeHMxBV-m+?s2UfObgtm4HA8w(#{Ur82g{-b$gA1Du*00b00#?Vx3;nc9$8JmZ z2STE!PqB55mX>`lRPOh44w^TYl@=&G^Jv{RW(;WB4g8<5p5^wAX{N%OPtfWV%}3fB z%>8{>FLsyvg^|zMiOJt8(H$MHX*7FoA)c8yjTQp&_tKwD+FG$Xk7emJ-H~U{X1p4|+e%P|68W@LUfsJM{Z#w(H16t!W!4bo*{iF$dW(-9X;{;m6{y_B?#rw49HvGU)2y_{oP9`*~l zWavGXhLG(43$&(YBnNyxk&mMc`V!CTdorJ@72Bo<+*-^^vM<6`K)PPVn6IM=c^6@F zTmHLO{y^O%=1_5oqxqZnQqd#0Vhes?UkwMz*2*p(vZ-lOc#wIuCX=@IYJ7zhlP!&_ zblz~ryKgsGd+SR9o?#f+v8?g@73E!Z@y-eBpXU;+qEV<^2xOFIIr)cH>xi+2WI4$| z>>_mAT#%4WZTjOiBiVv%@sJlBKe_R%Is zvx2_-oUivs8|L&l^-*n3SDrP!zE+lAbBea}>7=Kg?i({NDEJ%@(!1M%A;l50*k6w^ zU@FxoqflAt*8Ck6c3kk*$M(#n`8`GAWqO3MtidOl!=l5p9O*qCCnV$>3T)k+ONM~8 z#LmJTB1M`q_ErMS!D?A&7n1yI$?RAzZ}@00$PtfmjQrXqj&0{GpC!I# z(J`=_qBc>rVNfb>=nxuIp^WU-7K0-w1DN8~t9EdEl*IndlV$$DAcE>U3j|Ok|CjK% zz0wWFigS$=unr)rtpi-Ru`lMJSpB4^k85D#4An04;=CuK3M4{F?;gB|e8w7(b<{UO zYnc`YQT+BF5=?cPuZ3j!=x_gy`p-9>Cj5N7gKlomDkitu=Du8_mI9kJAA^=vd#$7HZGrRb1Zm*IuPXPD!gk!;zk5EfN0j5= zxDGm8_%)FwL7%OFSA4v7;5ZrY3at#i4inn$Sh3)}!g4+=J+{|cH|eY^>>JD3Z&_}C z=Z$vdz2K?OdUA7M$Uu^zYWv5{T*W^}EVR(W`rE`mC%%^Qp-&&d&^b3+&LFK%54-o&zHr zuSiH3UBx;(&1-}DMV7)aJeb<<_giSAItLz#otaItxa0UPB<-DJ-KVYNqK>#Ct6cTZ z)UF>~MX5TV=5#BjHinUPM?~PfpN@~gAk0g_Q&OGl8JEo+e@ZFTT3V!freXzx7f2g& zFc2OJs=}OlX^x77VjptsDYTmc(O*8rLpGs7z4oRqcbC7ccxNX$sETRCp9tg|EjCZ_YSi z&aFAEK~*xcX)PU)coqJHa{^-2=ls^p3 zg@i2Sb_N>t@o0X~m|D+eiv6XQ5Xcc-m{rDiu*H7SWC$<1hn{NX%rTApYtiH1)uPcR0S|GCN?b zA(O2hO$$QxK_4cO&iITV_ur*_)GZoA=@0F-ctKuuZ6M4}eh7~rq&BC2i6gdv7@mnk zN^EFjm^ynz=PDD;j)wxgvqMQk758%j4^JJQ+-|Z2|71?NuZh37>nv1VQk-f)H6?=d zCDF?@*qwmuo3SeZCbm-F-I%AwdR5hs6S5*qkGJ>cdRcyvg&9;<*M zleNU9A(gG}+-#lAk>tR%0VhiCI(4gD#Mal&qC-a$^!!!ZDANst=YdD)S4_-g8hfXg}9xI+`(TK@U3qU%M%p=nC~ zwcNj}9@%S_bkswKyUO;yh47n0)mETX1qdoHXUS&8J`+d=;Y{Nn-w?$_a!^q0Ajh?d zQvrO)y!zU)&qSbKlS8KdRm7!j5OC1YKnQUR#|u=>7sPLQ1S0=Aj9S!uHbJ*CspuHj z;Nj#~oNW}6MyFy4xoJ0`$vR(P=MnJF%~vOnFs|+~;pqo=vv@7TkrH>)LaL7(Y`6<0 zIk2_5YNVJ;kXWc&Dt?^iv7ZH1@3GZFb-HutB7-C!pT}w9i;f+%?b2WzE-{5mtoo9k zrKGzzano!8x`kaup!6k?(wcZaQ*fus4WpgkSw9kTgn}E(mRz7%$g3`u1B^~XCO0&% z;-w*hA;LoNkP}nifLkO)JrKkr-I^3otf%$B@%K;B_QvjC^*pt-2RB8#K5#2zYH2H{z?p5FxY$r!wr%+W z<=*(d?BnO4l)6$3Qf_{y!P6NuqoSPng>J>j$|-5Phb=4PRoN(2*GEZvQUU#tv2_Sj zzP2B@QV1Hqk6oi~TjtDR5z=A!#)Vfsy&H4pfhNC^(-n4{eJtUS!*QkP-ui}6Y~it@ z`b75$+;OJI?qPlVP+oK)ePHv`W_Y%P`x=CabZ57Ozx>_><+^DgDu!L~g%JaZ2?N1< z=X@^dIAxaMk8{l*b5EYH532p_FE=(>>ePA#-&xhN*TZq0NIWNsw1cD!PZStMV_(Lxx%GtXR% zkA0O0E#!2H>ahzw9Kl&%RRF!b^oNhASKbK9q?j)usdvnYiEK;c`@mb{(7dv9Y~lOa z)40cA3MF>o9os1Du`fRQzXw6bAep-2>i#qKc~#RV6~s|7ZKYQDTMolg16e-W->2dF z4T~&wijWUo_sL(39j&q}6xmw(fzzkCw!i84D7mW!qi6z+Df7=yCXOJ!c`h*%^y2qd z=HN(&@^-@Pab2dEyFLaJyUKn>z1)pEE;tM3B!qq5Jbp}F74Gg7%}+lkot__i3hzQw z^<7?f?OqarSJMs`D^WId9v2}tcoR<*&)8EXv!I%s%fTbirp(p0`{8F@8GEq!6M;pR z6ylqXqWHmQi99bSNPcksmpX0!w6|qXXVRgGKcQTuqD|d+CjF+JO3X(zJQHDrOKYPa zA8ixu$^qh!E6?zgaYG6pH5HZp6}bIN6b`auPBIKOvO~_7XdGlHY%kGH2~S$FNaqZw z1)0+9c~~ksIaDPHh+PW4FH1TZCxQ6~o+)ZIhi-r{@ek8sljF)E$ZOP{dG^G;Ogqlk zm&%4pMrH4cpGY5=mNA`KOE6;Ovw*vjc7)C^@nG#~^r$x*bJ3sosqmNB3p&!H#ja-f zpx7`8wYgn75DooP-w4Ma3qqVVgcMcyL3?|XrktyXVh1CIx5wluLtR>1gJ z;zylOm~`}@RhlsitHCcFlROvNrWZEirXX;YjlQ7C%#s~3&(0BJh+G&wC>sBf;)8NbkV%2QpL! z=`Dv0g1?`$Q0 z_Q^}M8Arzv*c)*3;~SK#CJf|&XWmOb_Ok6vcpBxLxp5Gu( zvFb~Su^weL!8t)6{+G#Quf0(6_s(@F&u@o%>3#ALrgXt4iP6p@(1F)oDbAv*680qY z4LN7gJqO>%9^s0&qx&=i@nl`j3PEw(^S3G-2XiJ*mv{qTZ1Oxc%n{31jQf*6Q-&c^ zap5WUB>488`9{>|V@S!Z0NqbU{Z#uGV+4B*ZbRU9)lR~4}C{Q_f z0`I&ico%IFz4FC4)LtpkeP_Y@3_~|Qeml$hQfBXscO1BQ`EC~fSJCx|p(>xcqHpvn9J?B}321ccvsbA`4?KwFX@eY$% zkSP+(f-{=0Fr%GDs(s~x{-9y_-vj&g3y&i~$`C{!TDE_*+b0}&hgpK}alci6oz>%w zC)u=!S1gt-Q_PSr5J(C8`cKCFl8|=@?lQlsNUJXZmKyC6ALgZUvffC+Q57Vs6nE2Vn4J2Dc^r=x zRNmyL!=!c-qzQ)irI<=GDNJj~hzRsOh(4@TrWCu*e<>Xhvy)9iBs?V;nhbNj@}+al zTyOjEBF0`wXiw|r^e1A(E!$XnO(`M^r}`=AFl33#N-k%}i#qX=)elW;*E!Vn)M#dD z7b+F=8XL(iD1uh+&>i(!=$ZHVT$g-nOAgy2OW>ZcUNuvMSH4$WXs+@OA<2f+SJY1t zezSA2WrVv2LFph;CwpuzXxXJ*gvS@$k*OCdICP~cm%xL3Sby+-E6LM;=uwXo=_w*rI8Tt>E4ck5PEx&(F+FZy9NW(yRy^CP} zS@!#j$Fkn-Dd-KTf^$LB%7;!QtIo1QyK(a3)Dz|EDOgXZvp$*E6^ps5mh$<$zj^*m z{F7mbLYmZs7T^jMbCZDTl0+uXWBljf3w9hE@oqTJVf~`p0@C|*!t`#`h-(i61=hdc z5~$Hm%iY9(fz`==beP>8j^<)8zHmr#iR5S2uK44QA zGm8W_I3UOgF5ZJ=CXR4w>f=<=?e<$IZ4VO6kG z-V5HK`H{WW@3>Q>SeJX4t-o59pZojqj&(NztYIjP-QM02D*IC)9 zf^~k!z29-|xR`w|`}f;HxM@}OSB3m3==X~8w`GPc1gUI613_yyXY-mV*ahTEmL$p> zE#oTBy>uIJsPtV4<~<4q>|WV*3VW2Uyz|5p&3sCjO$(hnQ4O8Jc9(CU(Ui=>d$!vi>U+>_ zn^F@|;~k#KecJ&uqzsn{k4Kx-3{Wion4_8pCcR`9{B?i>EeeLi}HnPfyDNtyC z2p0Pw861WYQbLzp%0uFEB$w}6@Z-*c7q#H?-&-D-a|0By^xZ>8{pwP$vmZh;^TSlU z2UL2AW%mmqTDF4(N9XHK2bJ^1$J|D>#DyBSq#T^Pdf|a`>hHG1tV0UL9Qrmb*$Vp$ zbGcxIRa+#v{H|PLGv`V23&6t<$ZunTv+ z3vMH4fphIeD@9xFv@Cd&d*f=O?Of?#LfEVY==Hb;5}3?(UxsI{usbc-Jgq4)G7}Jq z@$0r*KbbkH=r&q8sfAvo@-INTOV1xll;jRkTErU)%{EBp7~aQ8&RrYD6tY=Nd)joquzjJ8HF6^a9H-rV>UhPuq4ZMNBkz+H zW=g!}na_5Ha@lez5B2UVnPq+n;*mg8n{LbSVhc;)?Y&Qi?ZLG{ zWA(RO5GiaGi!adHlP6LQm%bFs7SI0Dtchp?Q6kvfusYjvRCa~OX`w!PdcDhN`ws56 z3|zFR;Y!HH(|QR07j~pw)morlC2sG6ywE=#W|;GF5|zH+9N(~JOl1=F@@iMM$%pbu z`r>SpYx6Z9|7`YlL!!C!8*@N_!sc{m6)3qpo>r2*J-<9Je4RbgyVIJc#Lm47;KZ& z7Z`5WH?hHZb}zUvYxceL#=*gsF&TPgZVmCX7J66}{C}%Ivd&C#LBAhwQrhyp-y)sW zr$l`YNeN{q#^l7uW&dwGxC`Q*v=XF1?iIk@*+ZwduZab)?yT&yTR~M{`ofA!&pkEk{6%%~e*9mUt{e zp!9@5@x880ARRY#&ubTo$(*?$^`<|e(*eWQrws}=i+^^5uu5I@j6*K=^vzlMCd_zl zGJG0-6@D)KI=WwJ&b4<{=_+SET)1~HT>gi6NNC5Nbi2R;Squt?X3RQflvuhsk;imf zw+K9!J4dRV$BOyarGmbvIdrRDJRc-8$^3rJqG|MiqJ#>A`~TGfEX}XPve+9oTuDr> z=@k-CTAQct)t5Y=cW4=Ile|wa)tj(fF7(`0;z?zT81}vrIG%flKJz?YCNH#R$!hk! z(s=f4n(q(5_(!@Ne2ON&{vn8&*R$64I;A<;QmsU-=8xTK0s zt+OXo+%dm)@!Y#&UIYE)6!A;2-#pu4y)y`z+|we-CjBfdJLw3<$TJ01^-5-IUM&Xc zLR8&QG<(P2ENU(8Vh6fSgcwJ4i&|U8c_=;WK8yLf?|jMYcevF59Lx^h-!%w7RGTNe zD3pA41~iK4U=}Z})?F~VL-rM1XD@BhdfRNsBc#M~yI@KbvvZxt4nE|yJ7rI5BNS{h zJl-{V@s=dle7UeCH#BR`OtF~vw_p&N%dc91cQ+3DqKh@Afr^N>bpDTAnp61O;9D1a zM>?E8f^U&`FZ8q~^lW+Zr&1vz3}mYO_m zS;vcaY8O2omVVWQjIjzFdg!{6mkEFmegTYqvoCX{fc%(Q#quWuw|m#i$HJ+$m|D8t zXck@2W$eZQ)R_SW3BOJY%%}ew3@})gBgw75JoDsp$8jSbA#e=Dfh1|Vn>X$(7Y1RF6XE;$AG7BZ+EkEEwilW4;7 z$`$G9T;75@-D6=$Xzy89&Cqx-IP3f7Xi0ksJ-)%Yedj|_X1$G-?yM%+NQw~xt(V1c z@A>WSz@(EoPpOEl-rhE4e|bp*Rl}L4-CzqT?VqbIQAy85*kX#K=kBlOyPMiY0krUw z`^`bq8k^GxrWk`?wW;5JXKHh6+i_d>W9{nh<1GCfo*iU9INRD-^1O3jK*gB0eNUU9 zkls70oB~EYn&26E^ z9?vzvSHu`?E-)8KFSZmLi29dWkx~!lFLyC3u~!&Ps$ZPQ_Pm?GFF#Mef@*(#Y? z^Rcwt8}y9I{hT$KIchd$R<-;6+bsIk994;C6TKg0*?N9!`VRBQ?c=h9_ueB;9h&zWcv{CiFsa$`#SxfG#_ewg-|1bd#F_qxnRQ2|D zf{~#7psdu(#HNN>a|+a(!~a%NXjaf9a%NJJ-^3kh(vNk*b2I&{0VjLOO5pieVks_Wg+%evuAWv9&U|_k z&DvihvpfE2YofcgtK#=v#ZXq^V4aRxP$YhHj^3Gqsk8ee)LWK6n4V7Y&h7O-d9Wd5 zDh!z2U#!v79k&q>UD|QEhQB@cy4l*&x9s=0oYc03&Sk;rN*K}QJfcwW647I9mOX8C zQuc@2=@Jjtq0VMCt9WiZ)2s~K^VW04=L!5%yM)R!7yo2Pm~YaW39p;9i%bbU7R}$& zmkEAKQq~47^qm-2>3o#0C11Ik&?vlh_o&fe6?bMBDR(w=XP`oBdchMejtQ%>NnTla za{-&Onf7^LNFKT#x9s*U=1wW5Z9JW7t63VpD4}i2{YX)>s%`3Yb6o_VZtOnL34oWv zm6y<$c%W?o{i3SQX)%wKFHo1g28Y*fGk48mW3e>a+)VB_=dMh7u70X&>D4#05H+rI z#?>63@VRJWL`-BMv}w9P$XaRY%dK&VvV*BMv7}8KRnMzWk%rJWkT(SMz0-!wufjwfb zfr+645EcLg7a(my(63)Pdo5l|2)MU2^T_L<1(#&ylho&)Kh3i-rSP>@ zS9GrL@*_u@KI^Bv;32IZnlHt)J|~jx*^b)QDnXwfOL?>WDR2HSm!7EU1y9H?!n7*b zy-A@&p3y_=)a$@vKk)rR?IuuT9PE3XU0qlCEkN4}waCI%Au$R3B+Q(msvp%FHvS1j z^uCJNK|t?)CFL&4fr)N#Qjf_c1HM_)kd<8V!qWB7{tUgA>&)Tzaeam~ZI4gY)v3ot z>onu*T3y0iuzd4Px9d|0-yfoa^>6&rs~4X%m?z(jWBwa7@!hxL8YE@l!ZEBN%Ieo^ zkeL!dYnkHt)LV5PJ)#9?b9$=d$RDJC&fR82bl0W`;tQMv*(5h9GMK-rGSa-dgtTwL z<8IsDmOi;YnRl*rNmIyWlCq_5u4n3xN|yQ9<~7xfZfLcu&Ni|I)PFX2)i3Qu`bcX^*1`S4skL9=CMx%PG7PEjnM&eY2B zj-r;1E!NUp(uze%jqKvm*zb(In%vQxd2C{9os?!n3YRv?CK~K>FUvDICQGezZx5hS zn=MZv-mN^tq_UwwjSEjHo@Q#>D=wmQGntVVaCktWG5;-nRmwz=}QJWv`m>tq?F zDZl>=dY|Ye4ZbTvV&-AX-M`@@LOu7i&IrZ;is;&CK=mzL5>?=`=Vltvym`STlVe`} zY0Ck?R9ujW!}=x#@)8oj0%Ob=tn~EY z0FA{KP1hqyoz)!;BvP9eQEoI+Lh)bU#u{?R*6(z`N2ltr8L!l4%Jv68q0VP4IsF6j z0dLAUPRh^@=F_+0E^J1?zrT7j<@$qP>X+yF$+imysvz;>l-A6tT%sz$E>3xT4Jt2r znWIbv9AuitqXPYJPj8kZrmYWY<$NJ$#wH`;FU3O1B^6eLJvnaMo?32OB+9jLbP^JD zo4aNoDm>oov6R4BQ~l1Ck7M`?fRB$nT1jhv1PtNE?Dx?jO2xVnAjsV=XAB-izW+aG z&t`;ifU#&z?JyMKHG-dzBMVZi+pk`)qJdHMppZOtFDsuo7Bsj7c0~TGWvM{EI^xWk zpIV-%Eh<~53O-nSyR1m3hAd1C zM1A&H5{$RU0fl6t%2#t&biU_J=I%)N{|({sPi?31nFNr<0NEg83cV_ilGnQDx##+ekpG-9trOO&2*@}hO=eRgvnphO<<9^q=pBp~=_QEzI zV3k4A=xcOWpHP`-)YiWrziTz5pKE-2&Id&+S3JaW+W-&jIG;qipRVrW6=b=0EgsAQ zq$so*?dtbU*jXC^|5y0B{P|S{`Of+7{db>dJ^Y~dnrn{nj(3dlj=3N}K!|Zp3LaFSu`?0d z^11fUQ@20mb)@`4%7{1lJ)Zf^9>*pp%XQ@HI{q?l)Sl6SZ5nA_CrC!AMh@25|a9lgMln=T$y2%;C;rK$}`mKV7&;Z;n0fhPq7il2eO zHk|Kb2GSCxH4rYy>!xK43}A?`{O#i6K{_%nJO23Z%N;8E64%Mh;>J+U)|voVMGrm$ zm*bL=u=^%BUrC{GG{~$JsE2@gF(*r{%Q`lue*mf`;Tg7ndHDDKW%K;zznmP8T6*Y} zLEV}G2az!c(Y!I!o4iG;-8JwGgQl#iV7q0ksp*PB=j0V_9-ncq%(PY#!v)tef;T|t zdnw2J#9lg<%;&JGAzM8c+x-pbGSPnWq7(DE5{%gCe8)+;sCVAW!M5V%M|FeZH=EL0 zNN=D>(^@!$bdg#CmApH0DHRb^+)iP^KN+GUpGBA4?ZDeX?9JN)KuZ*lbQJ{HOOw`F zn$~0JoR8`Q%)aDc*%BQX?SAt<14>I8ao}SW;Oi7&v2KPwWW6I#)y6a+=o%0V^*87m zU1vxa3}M%6#3J56Nw3sCPc_-qa!;Nco~oTj?h3_qiFfd2?d+msT-Q#e zO4QFIJE3=snDW97V%LIO61kK`D|WB=Lgjj3l;nyxzM@y_6GkH++RqBvRm-7!#>$xR zR|vUw{c*W#?7~+A-9G^(ou!_AGJU&;um8d>0AC>iZa_nyCj;6nWs!aO@+QG%rTKJ< zzsPz~ebB*{lyOh8fqDqI(hP5@AWO}%+RxP!GY2uLg{r02E_uT$Lqi3Cw}3E$U6O$P z6Fm!9m{1=xrN4XvI`uo}6V`&>z%X2&!MCTh-LI;dGlpL5RpW^6`9*L5ahFoRw;vE6 zQ`|)OsVOndm3V6174!0*gZRhiV?IeVdSm}~m%H{vfS8B}kq`W1V>-7Q2e_|$y~jg$ zfxz<`ztFz0$7)Dr1?6zIa%u1?YD~uQ{FHwIHii%edq;yni1+mm=WHFfqsgvbM-wJt zVV(J<4&MK#{&UO(nfqix&A&qA;*5YQZmy+H{R}qK+|K$i}aMPyZ9#!OqP3ZkAt1Y2(VN zYf%3tQp(f99vrvE zlcOb#V!ay=TLPmPLM{%7mB3b^%C!c*QJzMlssd)PH(K$bU!6&>SlL^;;)G~qv10`H z+Ff$9qoNd$tZ<{ z%(xRD1_6F9B!_mQB(uU5*A;DN&g$Q>9iQ(_a~Al`&=nbz{cKM9J~q^^ z|1O9C(T$X#XygzjM1yD0EU1D_vV_j5du zfGN)Nu~GRy>yV&4iOJqGi))uu4%Jg+6)n{CELd8MV2vf9 zytg%t&Gu>m&CVwwFoJS*gT0~o;Oa0WK<$!{s+ul)Ue(93ky-V9dz(x#nBE!rk~)-RsNEfi|c*@te};g^FzNTle`8~ zM3vxq(&#E948J8^%l#Z=; zGb9+t7ZStD zptxNNtQa5!T$J*?t(i0u^;2XW!Be*@(_SXPiYiX2c|vnoNYX307ZpQYT7XvZ#>WSo zFPD+mQz~Gt2>`1Lw^}?NmGu7bv8{p~>>NRIygQwJSMiMHzdl}4CIuo0O=T_!?_k70 zj+GS+*cNyjNzaYMY-vD;t9I#xZpWOq`7xy1GZw!LBHNA_? zyslQ8q>ZP)c60^+aGi!^-Aa+WqrvEkA?$D+3y0ZnWJV!0J>llAt2)AEv z=G1e&yu;W>ARaW9K$>?TgIDNqWgJPO_WBgAmrSE#kM}=jMt5UooBF`afSw#!lAUM2 zH~ZQ#Cs7zbCB&#_rv^($#UhC{s)~Xf$pTOe44)v&X@N7o{r{oD<6Dq0tVqsYFdS1(_K)d#`y+HkIo4T zu$PRW1V;qkly~D?nYyJPw}Ao?Y=-Ju5Qsk&Kce#E%Yh>ZlE~rT9-u+eK_A-F!BqQR zFF<~_<^%X?%yCHqX7Lxy{VvlW2PNA&z$mf%6x9~QG|8?yhg`+CcJIZv?I2mZ7(6>2 z_WZ-U-V0&YtB>*?_;p{?!_K( z2tvW=oq%Q&_Z4}_sD(T+bwAkz8v^Bu`~clJy&!l zv(TOEAP^jq46wj;RU6y)ref@W3MfnoCbeixR%o;PV9O1*HFhd1gnuFwzsrHoI^P`^ z%C5!MzP3+m85r@M(p#EGV}r@FNztu($*>BB?fxD9OWpMo{oIxAn#*Zs{{>F2w!vTE zwsc|~tmpR5e@{P}JqzC zBs-1z$PW`1-iuy4k7K(Ju0#%mN8FA6T8)9=ulaP5A6*i|cR;zNr@?3Ykrd;{e~|#5 z8xn8}=)M0+V74+Tbwb3Aje~$1ylRi*dQ^3-gq9&hyh@Wct@FVRzhvo%=7#*0!C1@t z2lRo=7$nHpzLFcocIAJ?&knxb4Px*k5I_BuzYOQ1m~o*_rV26F0^c({6P#1wx63{M zki8!SYr)VV7K2ru#*@_!y**J>Tj`FI_6#Huy`FZhz1qS%nBhX4Zuq#~gBjsmGaHU~ zFWx5uTW-R@%U16@Jt-)nFrXo&I4u4zYJ&hu2QnGJnMeMIX43skqWjfA;A%E}4O7Mk+_x6e4R$;S`n?-n0TEtLQi=g6l4*nO0 z2a(g>EQ~MzU#2IIhJWah81g#B*W&ZB$RCtys6pk_6HX1@Aq^qpq&_f#iGGte|2Fz> z-aMJ63Hqh~imTL9t?NwMU1#c$I{=d0c=oQ!-Xj+5r;k$+a}9a*>?t!pnh1nZq@TQc zTk5R-;ORtE1b_He39C>rm;E9ISN|rL+iK#BSyZpFiwh#Lr;n~|B9TIl&V_?9`$4E%yT{SuRAcytM9L)W1dGYj-Z@)iO7r1FmP9U-{H>l)@hLU@me({?_T-zUE{|lKN|A zMdFUgk*5tWIv_=fTWi|$WADQTN4_9(a>PA7inZ8u|FQcYothV!*NQLJNu1EDWqc&BDn~@e)gwb#`G7o19>}(7?%Y-xIFsH zZw+j+4bH{o-GPWzxDjXPBXC}wQ-q#8OtICc+sb$B2Jo7%`gFc6q&?Ie<&ZI2lE+V^ zx=GF1k773^qp(0Er!G5~U2OjmI=au^iP-(bXsl^4*#a+oo>nv?+DADf zHJfI=ELK}AB`Wz365V}%O?_z!Ia;`bpG3WUAcZa;jxt|7wPtPuEvxYFQ(zY2wVVGi zBZQKm^@f9&z(DYUksz@d(}NssjY6KVPx#+N9|#B)h4UV)n{%PqdieJ?VWTw>UNjLl zlz3p**hc-FAWb^rB0RFU9_{~`LNc81xOBZB=@zKrk8cN8s!r9hogzt1RK4?8rSXFd zT;>dEd`@W`+vME7EN^wGABHF;((|_ELFIRO^ zhv0S8ug;k5{ij@q-yL*a=n~g{-=>&Y^6pc~yR6Ed9p_;p>jHF$maG1;+_W49QHwsW zXvcUD%kUsSxCX1-AW{c102@m1m*ACEGyV(5L&&}KB1vnSBCEGnS-Y@!rYeYIq;wG9aTJvo9HtgGZQQhg6*KD_Lav6pbo*Y5~43Jq6 zL-rLCy&TyBw_X{n+0nn+Gf4AXk!1?7M;is%d3Qu1glaoHS8ni& zagF`PbsK!1{QO%BaPy5g_M4LT_fTcJj^Li#^snhr24cQd_$#9)+Xf7aW(C%KQ zvP$eFWw?$E2zZ6HKzMZ!!^bmi1<9ian_3vIEAx?7fBt}-i`raMpSOZX3=e-<0zP%V z)nv>06nXV8e9FGz%dMsQ33QP!quxC3obSAkLcvQ;*|chTG^C2oTexyD(QIwTkH7?`6cMZ^hd`g_`% z>%cYE{3-Xu`xWAB&HQ--=MOEeDjC>r!-mOaX0LmnRY1EHw7omvv14Ma%#>ErX;;Uw zLT-ZR(q8%lS-PT~b`Xs?mn&6H{6CP2HrOOhe2$)*t4Z`y!a1`2r`q>Po#rO;8@`e< zb4+=dI^VkX(ndq6u|Fvs|1S&N9Ir)9E{tX;P7G;%h$op4-jwc)P*1Mz(W0oQD3jtK41g=1p5)}`R}>* z<+prv2lw&he>kz<2z?rk=d}y=3C$ml3HeSjf)qTpk@<- z-z`bJyR@JIH3Ed!zH3FgE*WHn-Qk6hQ63Xga~ZJGvN|KwhB8QDz9Z+N3Bx)<{a61$ zeuUvG*n7uoh~%U(afkrx%iA^ReUb%nXrz%?0^uq>_aV2l%hq^%%lp~(%cU0K)2?J? z?95qNP*WjaAN_sD+v}KL1VJM5Fbvo2#gQTi8(G`5NWA_d9J1j&k69R(-2LY& zk+shKI-iT?-XO#H7^y_U=aipBGI@fJkr>cgj(3qOHS_x1ghaVoiM9Fsbmo7}vnh)+ zSKU4d4fQgZc2AMO@X3cI=cd>7-Gi^834Ze#fsF4CG5&dXc0wU9pagc3TG;!qc z0`bE9h8@S4k0Kj}=Us*OHmf_|<2vtUX1H_(d|Lg-x}qZh7|ZB=eI47rC}tK&b?%_Ut)VqhGuOYl<(oX%X}`=%4xQ zZ+2Q^ru$frMfb2u*Q8V?adQ-6tAq|Wr=x;!LKlN_^WWv>@*6XKQ>;_I`&RP(QQzLd z1=smh4qW%}BdoWHyTSX6->ZN$jS_dC52GfL{Y@&^zaNVK+DG7J&vMlx&vo&xR!PJf zmX(j87W+%_bNX`wxq{`8yY^f_i|%ws3q}NyaJsEkvLWbi7(DUvW3GA1-n&nOyDUiS z!r5MsT9`$No8{JJxWl61vAubkl7hTWM9@A0q@cbqxJCkjDD?#g{a~;#z z$^{Zu@x)vxl1=y1^=2EpGg(PI8%C6te~2TtD4h289Rsh)?FSC8?j;?uJMdSYc+JCm>1C>A3QT=z)d6zgoM42;Gi3k z0prN($wiGmXRRE<;h1D}owcbxmnSYEL^wINyHz#@qHtCS%hEi+&|1Ms?HxK$sn4Ui zNuI7(svhDl``WlIgoj^P+)i@sqe*~;gS)5n$1H%tUC(462R{Myr74;gg`d)8QY&fA z+9m^@88$P;d(gN|`4B3_BGB)|-RJbAeH`-X9m|JPRAy#S;IZV0cHxY6DLsZTqx5b+ zxUk99Y&=v-HhbIUKC95$UlJ72ghV$T>Jx-(1Jpbs-gQ6O&%_%7$7>a&3wKW-69LU) zoL7-pQbEg~%*I!wn~LdV>z#Ko*}c=-Xu&0w{BB4Y>~=WW=tWTOvqFnd@bIvT>Y9CA zcb`ys+|kiMpxx@@OrIh)^_=Y;a|v52Q9J3&U`qq%TjxIh;PMwNU1O8|g_Mb6iD6YL z?&X$RLr|ebg$XceKZNe;Ph^?1bs|8_-oN>_#9?J%@su^8jEU*ubuhekS*Tf}O!mf% zHh7T4)4ws3{YcS2GXC*n{4+HKg8%=GLTq|~W<{h`K8g@24TP}uzxS?$+g=#ua3V3# zx&3UqjGuFjXF;4E*)-#a7zL{lkTE6easH&MuE2&Ak8j#VHy;??#{KtS*9)h?22_l&p`t;5yfiP%f={q3> zanh6K!7oI#iqT&WsdwEvYl?^IGvVICV0O1j#8Ja&6il-8D@2(Raz>}c-z1VHiKTesiAs<1ucU+$$ba$?oLY3pOd1Z!iK%De==HpJ`o@-BC^^2 zb=S+P8ub}=bOu)@VfTt49H1&&gh3KW4}o3#(MzJd8@F*P=N+Dy6gT@Go0`nG|9=^^ z6HDK+bxMf6vvb7uL{%8h45jeiA~`_m!ZuUz7@bvk33CW^<>+hA(J0NkvT|tpM-@Uo zC?o~)y>_!cBlHhxe>2?z3?5vALFtgU4TqSsfr`6DJEARcjGCaV)G>2ly5cN~(tC}C zTf)U2735jp*TOas`5tvkRu z=E>l}drT{syvgB;?_5tHb;$sN)Uwr?ZkW9&$>!l-SPrPt@97eP_?8zX+NN|MXC{M- zLkIaIU+$w7*a6m&0i~<|eGuWWyL?x^p(?_f&8L75)Cdd7Ta*En0hh2d)9vSf17I&m z;6;V-+h1}B?BoT=cu}O`;P>*24pdj4yZz3Ous=?^J$I8dR+eCM$$_NdvA`y;=<&Sd z+Q!!69*OSCeDLs*?GT1ybDp?6V9hv>z@`xa3JkhLO%S-OT&yURLWZM{(?7xw5 zidZnTL)u1k*g)tl+}0vNgu>-?xZhO&d`8sZhIn|j-)S>61`4Hr0|H;nClJ3?nc@XR z1=}mbHW*{NQqt~@)kp!P=*{L7kTa&^=MY5og%TFX;y9setzlOV5LqvTf9PFHl4FWC z0VM^&2WH?a3k8iD1IuZ3HFS7%=(f7b*GfCh{>DE%n_g!qc2puIEU@RmepV8sgc7BM zCOn`-zOU7SdkaYaNPsktk!tc`8#EE5O4v6g6n?5bF3}zDIn*;78%AuUgOmrOrBdD0FnE;>d4ec3utYXVr?i3M^U`Vwi1@p%#j{4}o_w&&mO|p^H8I zB3SitjQpDTCbp!?q3i z&WO-#8FWva;jap{yC-TavAGXlAKBl_{QX0`?Mt=V;_8>4DL1RqNH`ri>bof>Yh06u zccFl>oc!6gr>Jhy?(2Iu-CYutzI30O-bl2oz3OV|LuCvRugX_O^|_Q4c~Q3*YAP#) z9iFpN-gL?f>YSEvC}DM>5nSW!75qSZL@n92#kR(E&U+8R4plBxDAe}!i7om)x6tfe zH!{b^etIAt^k>}$Z!cSt>QQR%K~992lmm^<4xP^X`%3pY7I>^#;%JaqW*E3#dbxIXqt4idhl=ZPRr4=1yaJhgIjDn49XUq_=_i;K-r@Zi)yN5BA=kf zHisZtwxe)^1e-z6@{6lL8T$7OLuH28F2E%+)W4}Sy=78ki0Knyi<1T^jC3p~D13=$ zyqsWAVudn3StKsNI-6M^v8Oo*Gq2Nv*_$x*l=0c>{hVZ*%boeHIMM1@4OuzPG zCb&})aXwAW&=8Y&OWk35ab9$s3Z1x^y~r?N`lf;5b3Q4E+kZPwUE;z*dcj4|zJ}sQ z3T}!EhHVa7P46U$Af*dPBwS_!T5OMYNRFe~0?}%8;2#fo$*T)98U2Ut-3(4v3`_9v z6j)fd=elB~O+r>4oEiozPW%znV^L&LV~Fi03~95}n_C}7VEV5Y{IHIQ5YH!s|1Lmq z9nbatR8F84K8`w*jbim z#`CskjB(P-n0GKo9DUjhgFTPz>&=g_@;mO7p5B_!Mh%oc=t$?64$TR=#T0PsPIakV zXGbZn+^f3l#9Rom0BM$B*>FtY)@V*Bng?;?m=jC3zp{{SOnE8S4#mm1@yaIqSgahdh4k%h|zXwkR#Y?2W&xhGW2dp2CdY|VMHS}gEnH3^0J8a8TA|!FA*>Z>+9Dv=V@NcDR$PRnwLHVoWEo?={ka?f&Q9&6GtU-f21uF!6&cuR#$dy;?#@b?-VvlF^G-K1^FVmph6bPFs!vh&U-*$Er+PiiNuSIHS`k|c&X9F(?|D5cP;;1b~JYM*K9MV zu~kh{6m~+`OxGL`&+>D&_Un2`iXyz9{~d?Ff0ZXaw4&QyKSsPw;ng26Z_aLk_Ss8B zez$_PIpkP@DcVr<>q&Fj#*LD`r`0L0(}nA&uSlqJ&?2U)jPG)*F(|SSF%ovGrZ;Gp zvNe7WV8aR}v5V=BfqD5lWGmLV_Exj&DcGC?q$f$XZ(7G1;DhrAi(uT@RRkQ00CtHA zPEZ7nWB><_yDZrYl+-Z~yk&^{Nu2-ebv;>Mah?hB+>tZ#qpwkkvgRl~7f&`DX=^S$ z^R#Bc@AdLA^dl?O*@L(mOTQ~s74?W=w-@SN+_KEdnmF-LM}g7_VGt$U7X`XK1tpl0 zpGJ3&*~9$tyJs3MyAbC4XKbg!!`yGBIjF*STV;v}5@qTU0=P9e4IO@CTa_PWN3ck> zJ68Bf9y$wJ(p(;}s@ivwbXTChVRlug{G9KP7fOiv6sYZAB@9&|V!LBa zyn3oh!D}6@U0{~^RwZPSGrBeN%`5Nb%ctJ)=lhPH_B)Pmju?G|5d+lCRisI0kLpGA z-;u@gw>&9-Q>g$#dQ_(diE&n$K*&=!u^`wnvY_mIa=S!Ej!v6{2>Gq=>bPA{m)fp+ zb4*Qoq?sJGC?35Cqo^ZnZmBQ;yf3kis@4|ak@u7&0opi%$!zt&AL~jjFCsMi zn{wBcuaj&CvUnuiq_7R^ab8D7TPSTG-k!U5;Zw1A6A}ri08A{sbM@!)0gJH%i!oG=1tBbQ*Z|>(=lv;6Bvp8CXahTqBKLi?Dh|$?DxFu?S9!m%F5^tjiLakEe{yRV z7`s=x6xoj|f0Bg_<*L^?$!0boG8y$}z$uwHqIjb4WZ(W!u;~aFyP;u08qd?felq3&4EWo&7tLGMn0)6^AS?fzmr0%QjHW&Y?VCrAN`-QGKhO#F+6a zG_ox0Ns6kzjZ4i-`KoDosvr3q9>jKRweIZwVtR%Oc&B0_3szzZ(X#?vNKUE1>afPD zBID46HYHr{?pt=-9KWkAwfe*QSdn-`LqKN}<;`~abx!Koz|5&f-rH5oJDdU=i~iar z?s~9ir`!1RRrArxmIR1lo;tEVhk2K3%Lpsfm4lC3R5@7iZUg@WN)kCN4W{@`u_Z{H4$D@hR(+PA3<}~jxiC}ofP(qy-w~IjIL&Rkz#H}tb6%H+}4;U z7Kf+#jo;^F8kaJf5CysntA%&&L5A}Kun)4zRC&4~qnOe;2X3WR!bs~hWnLLxy{{}p z9`PdaEpN9vg!ZbZPij@uXEz)c^fu>eQn_8dNNyvs+8!JvVq+n(u@YGha~_)MQb`^xO_#fClB9*B>`JGb50;$-Y3Vj*-$ks?;U5Rw$O^viSb`jbo#R zggtQ^sl?Lfdu9qLJcJW6y3#apSn%N&Rz_&OIH*bIBlF+qSsCmPZ zWf`&5d1rMvQP4IF)cYv@r`~r65}Gg|hj47PQ$gKTrx}F$My&d#ziucZ-eint&MMV- zfW@ddp?!4QE>4+OO~=&#r3n+iy(l2GJA3%M)q5VoCnDSH9zA+mqw~ij==j8FIid9F z1s)s5PKKhd>KTY&pVY%D^O39F)IMuoX$H+T=wY(OP%@U-H&D*c{jYznV6qq&pmu0y z=&LBpn3)W`{S_-a218Yban3L94Qx3r9&7rQhIXTg?%av>&ANKZw%RZ1m5>&Ir*KqP zP0pIcCU?NNUw@`CU9^h%N>O8@jtBmwlI^lnmD;TA3CWP6{W_iLm@^ow>qTuKV%V$Q zu=l(AIN({Rkbg9XAXa?2dfhrlc88ke!0W;~sN8&&dAsK>58YOWk?wp_D7}s7z51z~ z8aa?rX7wU$_n1z@axe5Y(w00^cc{CN6+<&a)|ehOuzm$c+9v30@!qgcNo4H&Md}>b z#6yW#f65W*$5POtp>!Ps>+0}^NilWdh-q*#DaEed03U-I(-UwH52U_)H#Ls;jt5ilt%m_pCE9ta-#Vib8xGWp_08`R+deM9)?7E26yB0GPuDP<4a8b!iyuKWF5=~0b!Kit^@ zRgjfcO_Gj}^zTUJ!F}hn&UzAiNrL+O333CZ9^c!j{L(qv*s~@#?Pq@QpI@ro_VXsyR!ocjstecIf5z zDnE6a!@sov!TLsxf^Wxu1x+Du=Qo;L+kW_|9i{GYSsTJ(;ovWxs>R+qWX+pu+R#A8 zdo&ET-pa^VUy1gEB^YBX#7|By!qI$5aM06^2ZyjsLov@X086eUFjV?~QmZUQUag-h^RGg9^_b@fN7u?=P4sda`eFkLM$Z-c+P%d7Drs&W-N zNmzAi7-`OSmPNM0dJ_6l~z($p$5=AtK8RT2SD% z;>uX11MwL&?+Ik^!=EMu)8`*N>ja>Wr@*5#9ka`!2Xq(D!J$_mH4)STC9#TuiAhD+d;&9J za9{6zsh+XsTV=sn5b~$0l;8==_^Dhl{QC8#cp^!f_1AQe>{#wYqQwJ7P)&!@0);jB zYM)!q+)6YQ^DTqy0S*rjzNPKsU)DIcSXDCxd^ES)EU-w}bwQg;nf(MQ9z}GH4W{p+YBj>bV0vxjNsTDu=OspZ@sG5sN7?fpmp;b-6@_}yURN~ zHQNrf1XhBRp!)PzUlw!^Hm0Sy<*aRWnZiP>x^|oiEG-}Z0;;R;u|W9J)Q%2$6qjNq zOkrSc8drh@+ydb5HOCS7ACBYx7SO9%@UJJQt}BtVlb^a58gJT(&4c_4Cn?U~n@lG)lkCT>m9hQaJeJ}ozWx|bI%)32{P)rR>MmrSx-jWC z!2RRsKFZ>hbDs?IP!4k^%9{Y!B9Q7KkfjTLN)kjDWxW4jAK$R*pjroDyoHVRqw(oC z#U&r~m3-0D@q9zx((uBcvs5)&KW=j3e!)*1pZmRtAg85oGMsnRseF(UbLhTx;n5N8 zJ(zeV(R>gGL3*Zk+}9%Y8BbfdbCWTT!VHmRZtt6C0L>|bxkS0T&0PZ$$5U=6wLay+ zxaGOBgtzFxf6}J}1b?kyk4ms_^OJDu@cE}Dd($PU+~-ePO@NVSb3B)X@x0PfEB4=3V0K9k zgNXLK@^=9}*R|{-)1E2dEoj==OE6@cW1fKiTXtqeaGyRi*hY|3K`o-x-*6Bl!_XxW zK~E9Ey{rl`OA+|6@D|&$ThOqu+sWj2d3gs0C$(V@68cu|N)kXi^05-2nfF$S6`gI5 zx-J6a8Wb*(0Vnmxqn z=OhZ2`k}0?FDpr|=MG+uF+^H_P=){;_j)64@yAN>4P+)B>JMe+pV{_ik?b;Ai7BB% zVJZ-MNWyat3kE18jFB*sd7RQqr)amx+Js`Hh(yf!!sr!3zDtlx+wFUKHccaR)|UDC zK>!`r6( zgy{l>rZwcrKTXaqSqi!%w`uG3t#3u}Warc^*BLhH6;7qdhnWi+Kp_D-It+v|N49zR zu#iHF5sPVJX3FxB%PYWIu_NRiEIp$pJ}I*i!2*X38j7nyYy|Z#pfse5`m}VfdC--I zCGLw+1pY11Bas})Q=SIcDOv14+K$eh{S)ZcB$qx1nvvp2CM1L@ut<%cdnPG@p7MAt zG_ZcwR$LYbrH3x+vt0i(vNQuHchx+mdwZx1*?{5{SHk=%C~fk$tXmK+N-XiDc>N9z z)=|-!1e`?MvfIBeWj*(2@$Aog9!50mCTV|WE=)8f_Jh7=)t@W?2kA!RLJrptLKbrtty84Ww{Tf3m9c6V5&J+4xNOI6`;gLHX&@WBngcoXRVLBNU?>|R7^{I566Z^*#G!$cB8TR| z9gS+DU4Cg^RUMwgOy;9p!cqG2dwEq;e}NbI59cL80I`6WQ;-UD=k7_hx7^R2W>C%6 zS3*m6uR-cH1b|*~mFI^{v)2N`o&kHLNVK~&aW^BwH-(l~MOC*1WyZEYg}B%KrML=_ zAE|P{u~YKUfAz`rzKO-Ai6hM>1S&S(BbSm~cwnIdR)EDj7t1(_7Fr51AvP8Aw$e;1 z!Hw$4@lt3Yj)+bmA4PwEaCO>4!WHUINadPDg?LIw=olvW&~~H6fz*D8^2w$EMAw)&?+l2<^+oJ zC2lr&TBAifWYSdJluaG($o=~`GQ zgS>w7hTfJf43!#gtK9(}H@ItK(bUycqa0Vn31cZIxi7vU>A%RSNo;`BlxEU+y#?CT z*(f+aHX$X<-gp^1ryUBQbz?@DrWIq}zGiI$`OU|R9c&PXEa)s7QILtY{A?{(KE`)m zvacEcHPsf!Q)j)2Yz1aSApg$NI%IGc8;C*fi2_>6AKzl2@_O6a%+Zby1myj;$2kDB zI4orgl6s5I*Hc7nUf50zbyS8~l}uTukR>m!{Uimj_LC^&$TkiC7664(6CL*J+q1NN z!Wq9jzh{6R*#D)k>kcpMm5hWhyN@THT#et(xi$OnpzHP1!{A+Gn6IfN-L!(}=feUC z;9ILJr`#BF*p8;0EC_~AD3eL#6D4lo4bi_1$|m@o96pWVQPT?2BUV8DEbw0}55@qo zginl@SfJHl@LtnH2b$jb-MfKuVQ*eNrcu2IAMUKgu>$`J4J-mwuQBAqc1I(ZdUCkH zt^c^^s>5cB)at0j*;uo{Gkl1iIm|^tojSj~_T&KR1nlDzJ_#t)jh9wlt6wyxCIS@6 zmKN?xO7=M{A5IVvu~bZ1Pghn%2w_y>TU%ZWo|~d`NQHUCU*}QYE6H~b{J1$?`a$b# zbg6hsfQPqpBQPAq4Ct&ZftrDlJiXq@+671uJdcrxr%zZ^pYXkFbwge%+<`UcqQ`8y zm`d1eN+LQF1$4WJ)l+%q{eKAJCWldK@$N5Z{jspv|AXJ3fc|-JQgX~ zBgndo;18=al=s-y;FYfSCx;riX%wa`6uDDQiVeqBdf=NnqmEab)M>^{?k2+*USE#R z*V@J=e9nIn6(B6R|I}?(dC_mw2<^H}uO+FT&CbH{_7^WD#%yMi6gMZUgHyG5@hvTz zZQ+rft9LsHQpn&?FL3UC&-~cYpQ*VrFW-on3UXh6NZi#vpU+i&_eQP&zJ3SvXnMAR zG-9f=B$7i{@LkZG#~M4(V3pU5Z6LDR?##W^vm;q?@Lw|P0L|_`WH4h$Hc%_w{aJ$W zbl9x&Rz3TzQ=kR>DqX~r8f8V=U+g5*ZmjAR382V_M@}WqI_z4bN8hYMqK%?!9XAPS zqldd)m{bF2+I6PjdkZ#N#X_6dY5cvHz`b9sbD30b+V$s-UH-oC<^%ui#53f5c1@|D@*Ox zo_NfO{`kgbO(32x`Y&>qKmROOXROMjgLiwD!}l$R>(bi2SpoNt5N|i-r|af6t8mdP zM*y%*@6#u1mK`r=ibUJ_e9n7_(&y`@kIvU~s10_1k%GRYe~axBTp^D{f(a1RnV*h$aZ?v@3~lw;VybL;5A)p&)Q#Kl`hd@_LCU% zwy>`4RCQ#;X05+=#!sI=8#_AiBRxCnL%XXN=fB0y1ccefJka~tD{Ir7WX+}mDyGXE z$!&VWD5ykR9POwdB}PeSFRqU}r%s*m?PX}ehn9~WO__Rt>I*xSG*elZ3U%mxv{3|w zMSp`!A}uxOS|^CDG#BwkXtXL8ExmP zgGJtNHbOUQ?N9jaCDw?4ySe=kYV^L$(AhtU-AwS^##aYlhcLp#=k z+s|%N=ApWZq$3@664}l}GBB&aGTxqcw*7dVa6YW1!_EGR2D433XOih6VrAkA+^{1vuA8Mes)*Gj-MfNdT?Ita8UdDQn2A3C!63DsTe|;%)7gr3O6W23LlTYm?f<) z4fO#ds+Knz|G!!u-*jtgWqRWiLCG9cV5pln91bQkGHbnEzuVF~sF7t8N`Fus^UPUH2?vDs_6egeod_<7G_4;7izzWt%s z(-^@Dn#Q=m2a_e`@MWb(rkJ00q>b2bRt;@MFRkn=v&0Ix?sH?vr$GyP4HAi2vA-I*RO>lktjt!8&DVYT+mPwC|2vkZIk7X& zhJ)CC`?24sx}xtsX}_2i>K<&hj@c2dh)=7;r#{==^1LWZUp$iN7(eT4G9mK3j{q#C z{;&iC^zHZSa`fg;CiXyeF$iXgK~-c8swB)he%Ot^w~htPWpl(B#A{HHN|-6U{^e{0VAPmc}=OeM_PPmxygC7_m8qoKBWbq?E^1xP(Y zAU{F{8Z4LTJLgL{8g^QaTqtFGRph1h2mVRqs6jf*FRvma2VuB}`L_|E=r065pVJ|3 zDRXJM?0}eRx-PnYmdzWy=P#?Q%AHR>AAcs}QF{FqnmXs&;;U9+VsYTr+}IXT%uz+Mj$>4t?Z((&Q|J=b~NZ;n!z zhZtg}yd|71=fJJfPn`mkc_kY+GU_UV%alOijdGxaIvXF8Qc12jtyL_XMYYCHMEdRh8HDt z1rJ?)Pv=rnD!#p}$pCK=1p! z=1?gPLudH3S#k%_0zW(es^R&w{@P+gzpRGeiIM<7mYnta>31&hsT&Y|8}(_SB~$tN z4jGSB_ItdAR2vxP#c;C9U6UNiX>MD0kB?9>ZUSsz94}efojD0A$#BZh-Of zklOoWuj$g5&x=31-JR`eZ1tBD@=?7cC&Sd|FF$4(j-0jDy?5Av;&|@lBHS)^2SV;f zNnd4N5}#2m?uP-j_Cd$hz2w4!5qWRIoEF_3x|^f!Z|bDehpG^hq5jRPP@I|6^CS5* z15eY++1{$ve*#v~+$o0W?+hJa+|Asw?PlN34@clqEZV0rnmf83)SgRIG2OApELV1O zXEb=TCDA~-2)qvEa+t3{o;SW@!@>S)Yigpjk_4RioS|UsWEw|uO!=5XhNUWP?y5rX zw!Ww7ZxN;GY6{%z;N{X(T4zVS+;$N-5VMHqy%cZN9g#}9bSB^MPGd@tEbY1xT#^&2 z_oua`)?xQ<=E8&wE{b;F@0q{J$?R|5%ZRyiCX@h+{WG86K$KFEim@|(nr5@TQ89Vz zOD~D#hvWl2JDTW~8hMd^NwMy3+1t;v7G{I|>&1eOt{}MZuT*LKkd- z%SWha^Kzh$>nspFGK|a+?8nsifY{fo07J6V-JSaEJAa#c`E!f~^yr^}?J$hq^Q=pr z2>oz;O*k)s(>rrnz&QQo{90FcYVshu7e8cRfSrfGePpRRo`G;L*OUC5^FCGo?eQkZ z!c8x`$1R~?Tfu%~c#HR0J_y$TFeaBje#G6nIzP4U%(t4Yj1*{eK1eS(vv+bckyG9{ zubURAOa|SoyVHK%;*Z5+I}eAnp$ENq>6rV){>e|hHFxT)5x@CEYh)+yYqh1J~&q zM_jW4Qyu}{0o3b<0HqrRZ)EOSxTWfm>VakTB|JkPot*7ux7jlT>Seh;*JncmWhs|~ z^XMZh!}Sjkus1RA>;oOBTRTOGJL)QBV-~jSOLs{!AxF^I4JgA!(((7#v-hoFc~`py zDj3O*>YDw6>iQX{Cu^!rl{V4O-n!fJk~Q(U;ANe;-EO-dx(hfwOm$s@!1LdBzepoZ z{{@KCb!JjRxl2gBYFA-*XQ@9<4get#YW~nl*!A`szzExV_M72@I|jdXo;+v?fANsZ zxOUp*cDSlvt63+Z4?i-UY<=*ZHWC-7?adCfFZ_@Vx{9Nb7tV*E(_Tx@R!zL~HIa)H z0HuFMPX=a#=VZeG#mTK3?f!oMtvd_{_r)b-==OeR-prQNEQ9XiNy(>AO|U3G{V9bN zhePu=zDmc~TUj(rY(?(XTNKQOPR-UgViK~wXmlqbv8%malIu(#pC98M6PPdC{9q%S zN23xi9hMWb@eFC-)755Qj35jKnJ-#6r#M3&!9P$G_EZt?U`;z&@ovGBb<5G^`kNgo zzw1L?c>k#?Q`#MMR2mt7eHMC}6VJs6+XwUeYK0A_qmlU|O-@$VWmbCUBczgqaKbo5? zoXjpAj$~>68lb4S;2y#8=;Y$k`7FDXl>#v`vs>zk!iwz67nXgpmG1{+U2a59q9PQo zrx4%VUEqcH*yWa?DsnRi47?FlHLD$^U8Sj!g%H-3_N*nmwEOklmGtV0ga)VHt_^>c z8A87t?C!kSK0x5%dD$?!Iv02xHO+fJEKB^oq`0#g@-|DoNC%h1<`=N+HIw zyqI<32es?O>o%WTv&M|}gE)}_+Be8aAHpytzgRDyY<^=1{>KKW((als>PR` zfhC*6)aY+M(i9f-U#Xy#^ai{wBa6BbcyS$k;C*)}z?7lwA6Ubgq^jrF9mL1M zHBNh1}lMOQRwii;7OExXn)MwV3ko)x^@A~bx*<-)BhPPtC-EyZV3_3RZqWo+EWSbubO8g7eSB86SKCWIX5=Pcy zn(=kdvY}csj-^NSfIsWJzx@&H>^Ps&msAo*Ln`QwF%NIgv!ZAGtDKWD#*AxeC^#y= zBWg(+4=URh_g#~n`MQVlWb+3P{8fLdFB^@{A@!FTn#?u~;`vuWP{v2z|M;x~@F3-a;tFFtQj^v_CsprY!tfV57tys59N~|?)7@-V+r38@KU}SUS;+7-<@4ZSg{!uWPzqmT)n~6k0sZ&1 zoX)3NZw-)22)MFxS+3P-A5;H1`tYg+_BQx{MARt_(Il?y3hs+L_<5k7;6u>5Oe^=DSCvGp}Bu03=Sb^IF?kJ8U}-8Ex0 zcgj~e5y_ZcZbjm!jt#kp7t`C1xgDJpXGY8nrhL1v`0!R&^D&vta<|`+g>+5keksKx zOwo#G4mOQBqJHsR5?zwKFTc z%e-~(RMAjI_nG9po`+M9`?n%1VSi>go15roaJP_C_b}rm=1of{4q;`lb2Y ztMe#oobY+a%tCdsCo(WTE%&LDdzUp%sV05Ci4`om9WS*fjZcm0RZWY3`9c2X0{9O2 z@vhRk+=t_;UU@mo(!`l>?@9q1)6t{gV%GPQaGZc@GiKMFDEr_SEQ&rWQnfNBcxs-K z;phu}_jDRV&lORo!m^+VD><8OB8a5GX%4$EHLz(sKjnf~4R|Rg-`(JGdTBg-d$w^t zAlL0Dlb#Di)$Z3XoXOWheS3I?V)Yb6RuGCijqJp8obUIp;M*dQ-wL4BE=0X~jvOb# z{cgx`*pe-Y)|WQ2HZFDVkRTc!XP@jAWi`;r%3LSl?K83svJYZ-s`K5#JP~h>_VT~> zM8&iz5%I~0G7)5co^4?{)%#I8DfHtE7L)sfN&f{Nqzfyw+hAB>VM+{lLgUq9g_CuA zbVsO=*O7!eSum9wk(-PtWqdN>7u!3w`s5^Uxiz~lyIw*i?gN~AtAmpsRtm@T6_;`- z0Ug6{U3Vh?(v!3d@Vc#|%V=pjWuu{v*20xGec>@`f~d!Mp~9o)2bo@%FKFm^v#;uy zxoZvAXYe%}T?CsOY#(fs5Uv=hqWYa9)z2xul3{CZac8`%^}d^w5nA~1!UxiyC|r?% zxuallO@0vlh8nqMYcKkvLP`DlB++LrBtP3p)Tn16U=&zFsZ5KoA2>gfDauFG?X25;_n z)HNFzTT<4KvZX;O%k#~{-bb<8bQ~3EW?+AnfG2{5fW}+Eva@+|p_FEm`ek47Jkerh z_ZDc6RL~Q4VZP>3bBDI&j z8oHY``7=0I;s%WT)JI#FR!P0+_`kk^JuB6R9CN4IEnXx$e2bt@th@D6!y{zSl^p!` z@v!Q#2t0ahLW)(jJlq))}x+OGcSP}L0>jm@o zX^~`zPWjY6$a&#pH4S6H;C?vu9N!J^Ho{eaxu4ZIH=bw@I_dc-j75-Z*M83S=%g}5 z?z~hR4?IqqDalsft{L4lmmEGf^64|X3LFHr1iUsvq~-C1?So*^&DLmoQ)j7BwryfU zDm;|j{F3uF%#Uf$H*B-3y|Ef6%ThRoV<5m?LasA{7tZBOu0NKnZ648A^h_Pap1xYe zB{v)1Rx+qo@UCJP&sASZt|=KFoktCJzk<`%(3(}&)r$Dkeq-StncRKol=Fo5r{K4m zFBqVHGE$Iuy2a2pdah_fLJJAOx$ay54fQvYce*e>LB(OnQTP*<;|YmW#8KdySUm3? zB0Z;{3zlg&Ad!2+qpyk$vBnT&A%YKML zE+3X}jB}FHyyrG$Y_#3Vm0#OUuHRj2fO7Y=q(E+<=w3wTVFhIsr24<<4}7g3~cCajf>?7zm@Jph+^~ISyjbnq4#CT zBQB(~8Z1(8o$rl<37Q+O1j9+{6z1sLa&iY(a2jdS)KAS~-gIC4um0$hTU}O6QKPYi4|+FmX_QqNouNir`4Z z6A~=0lBHrRb{-yTm=&C`OM{5HPvX;?)e~eAZaBQ1rCg${t>-rpz9zrvZW`MV_S{Od znJClyJ@yEXV%X?BMj8(!2V{w#&9FIq+;I8H0oNJRwfnB|yQ$?V1^pna1uNtj5OFs^~DACn6U{5^&r~i0buhnopJS`NmZ#9ch#!;-g|;8g*>6DDn-cLWO2(QBmKP z9QKGw*)6x@=f9*@Q5zaY;=4wya=z6neD%og8^?;t*v*Q9qT6iu8nOEip+MIOd=TA1 zVZmQ(@eFhU&CML_RMVTET)R}vIf>K0I;n1|{1rh%>{EOsO4ygbe;>W#b#c9xOlxvL z&rBC|o>VEV?rpi>#H0*e785uFb=eZ=3>aRb99AcuDO}7|9VbF-{+snlZ~mpbkAvhl zcZ)GHnLUJP%ij0vLh@HSsFo!MxAU`fbIzOUjDtFju9NTKTU)$WGWQ!4D<+JN`|>q4 zwI77{hA7ea-5DY_H@M)J33#4+W;hE9`Ffwvc>U65!WBGU@H#hh>2{p+Fg)ff)td5I z@NhvQQ{54Lj0DFJ9$smnfNv=qX2|)-kYfW2(#^W;wBn}yL_xRN*L)|^go488x*Kn* z)Wxo!FP>lq8!gc8rX4@+tJ}3tfkJGh`#i&?PnAM=bG9-mpDV$TjTf;=(cZf!%sOpm z1w*hfcLVwYnEndE-hu~DGjv;s6S^dnie7Dyk#;Y!6Ap9QUYi{jR(uty=!h)%kel5A zN9Rx8W=k}X{`KG?+|*~Ir!c%b@AK=?hf3Wo+b79ict6Tkav8mjO5?q6ofMTppTNKP z$*yfzRs+B9OZ!v+K?yJ?TL9V(0a1x{;|PRv3QMy zOgHM}+HL11U+V7G>twRSPxq~cp@QpEHB0;;$@Gim*>KHT2kbSqcsQ8Bd8=+j{WS59 zRoc%k_R0r9yu7$=8yXSd;n*Fr;7mTKz8z{`JzY9SjFP)P%2n+;RKGlQ`jk14@Wbim zvf3E5NWI}hISrqYV1_waL-bp`H?qIjiLK8!I#OtB-Q6nQXzWEwt(+GGC9UKh}3YpXMNttCL}hR4G&Tljk;B~OGOa53t6nlc_S(RmyW zNTfB`!?QV64?LPXw_Ol>4$*>~_7fN%hvgGF)gSyQ&~M*NPTrIE;U~C1JszSYh*~OB zZ0>9=H15twHI*!ntUWRCqg>piMXlW4dKsYBPU@BNy`;PqJo3xfVBEJ>@DlD0 zE2<0&!VOxT1$R?M=6TDN!vLnX%buN@(rgSCYuzZDa!&bcOC)je6*f89KW*`&rC%Mo zqk=DWEUmjjW+D5#bAH~}TV9}`z*zWM$N9DaVL0w^Jja#Cbu(quL@B74`C0q>)E{lu zY}L820(2Gl_9TCi7PEGam;IQ zBE84$Lt6!h8On~BhGY9j0z((gJvPUOWf!;Y-wc+@!INBE^w%+Z2P zP{^Ge_~GjHjRhqV92b*zMEYCx#W{$nhr=?*a%jM)3HAUV_lt(ZU@@t~uV!DeT20$B zF)4y)6J1L*hTo-me;3Rt?B1&>sWk0{BNg&~BsHj~)IjrB=A(wol2pF*R%-~6S~^8M z*o9~-p~5+p>-y%uU#BF67!5C}G;pNkB!D|`eDxUG{~37+0FPR3JyiWxqZ(X7IN&dd zcgTrpttg}1jDF2k-o>t1(Ox+Q5hCRaTiXL~C(S{NlcO6M;r2n5f5y6bI@M(VG((F6 zQwtJ+U5glFuC|G@iM-Sdb?(;@53RJS@IcN9ah*u0o0r2vcNBhi0ppNEtqpHy1YC$9=51*oOteGb}cDxYe=H zVzKSU|J8v?koOWjGEHEpm3hRIXO4W%d|Py-iO)*61`pWqyjX`c&4qIuGS7X|Jg8F+ zX7+y9v)B3_fvSl%^tw3Mt6B1#7@cu&3Qntxx+vJtV}yy?!EF5bxidrM>#E%%6HOfr zf5SwQ0%rZ5F72|AuBm$ZxKf>AAAk;tQ73mscLbid@c1?_^(J!M4prP=_%7^++b}P0 z)DmXeCXAVZa)G~kuL${^48%yO!8DD+obS&Ia`3hjnMFNc@m@)#@mvkKayXvR>k^nC zhmZJ7gs+2I@Zm;{7KiicqLC`2wUa~jOTD0#=HTlLosY^TRUj{X;QTJ3Yx3yEm$JFu z4s}82tse`PT0;{ulO+5Xff}^_^~sKkH~GkCTZ?=>))IcgS7 z-7%L#r^yDHfbQ%rjX1czi?EWm<$qL9v$1T$(s)AIM+6K5ePUHpumTqRbMU|qdPM&frp^`9Z9ofO4SJ78Z|-?GX$pIbNO-2-6@eW1;aEK7Ij_C z*vpaDvOk;(iNOIAExRa}g!@G!+l~XHE;TkbOcu{VkSk|GlD=waSdM7t3i9W3^hHxM z?($lvcEU7WU1^FS08{h@qH7A;FatQ~1Ou{oGe7`NBgRUq+`vzrA`V&%#x?G&Dnkr3 zzGpM;h_-vC?Bz91lo`_Wx_au`Y8ntw8iowsQ2{841v|_(jmAv}R1H&g9&BrqYVE7X zD<=utJkGg~mZa4-M?*~U6DSS5-r@gvrW*q82`z%p_Gpw-r+K0qiwk=I1uYKex4X&H z^|$A(B;c>*R(Uah_%YcIU|bs)yjnhY+maH(uN{wf^rYiq!4;2dXk=vNl^PLr;}r_VsW9>7A>SvE+{;dqjj-$)q4w0ZXg3C^-F3>ps!28x1UV4n$ins4n$ zs+w^(-F-*x!!bbxtLSO^xN_n{1&!k_m`2V5H9JvNR2@CwG^PR~Se1s;MmsvyaO>6_ zE4jD@mp?-{ko!Rg;I!#cnxugV15I`>2i}?Q@0uw^+G_##c)9i?2PA0qI9T~~0UpOo zK2TC5FhfGj;eupBe;2cKab1R^YyckvK2I>NmYv-|svd`Yr-bxu{%hUDv_HVtm=)zX zUKYNx9FND(Z7wDSwoU(e8Y@zKY$+P_V>=(ksz1nLDJkoO0NfVbzodj6EJqHKJ}XqA z4rl0D?+vivA1h?&(B$-d1bsZg3~2iTQbuvq5(wG~$Ea{1+3vPT>9_vodwUZ5!{$Hq z#q$$5G&u^0K`pGTp^TzjCb{s9K84SHczh)A4%_UQ4(v|< z6UpD$Q_8s&7`c;gG4_urz49#{rAG4exrM-Emraz3$E8sgm$0KM zei^O=y4}8IYH4C@0DW6Ko-V3uU^ZL@Pe}wnkJZW-eQhXmb>0YyMz=Bo0Oj63&fOrf z%kq8$zQaI!p@Wu$Ga^ug01KQPDnfvmeu8@;i@FodK@Hc2#ix2a1;l-V9`)@qv+n-E4N+wr5HzyCPCZD$ODWiyq9o4ucKA3md zRp+A0r_U1+IWp*)4ziJ)y1YAg`lUVKvOUH!{PRVYgN!(D7YNQ4p3gpvPv#7p`uDGN zlAoP~66Bk_Hs>FlBieh20SG;{FyGTKg>wf(3eOWsL3gOO6;GJ&&dM9E> z-U@IqkUo`E)g!iIapLiQiO?e1)_vU|B@#Eg$7*=^kZt+s0ETD;*WmevvaU)%@u-nn zB3}0AVT=UI*44x8_qJGMp8n>Wd#j^~@d*KHM5V=bNB|y=$DdJ-w*jd7W8x@d+s@Ft z5oI8n9PcS#kpkQ*O`Xk8q2@sr12I ztwbT{(bJAph#a7)8Z9C+$5|8ODVL>2L;lDu{i2h(S=u z;K!ce;EGu&tz(Ug#q~oFO%@e1$;9Y!ltEES+>#Rne-f%;(n+(L zpUfACCbsU zZJp(KtL=TB;^q&_$TkdkteoFZmr{cu;xlh4QZ*kWnu;Fi%7wS~8c5P#vg{#cuw1aN zbp+2mk$wG=tvi_L0lhxrc$^{uU@NX_WLE^ARTQFZ?c`w*V1L`ISn1b6q|N*Sfc28|1{$HE#I3rP;-CB%rROtQL(DMbKu& zK}isv>+FJ;eha@rOeE^Q4?_(tfpD+|u>UdDAj46qkFw8Hb+inmEV9Y+op|{R5;$Od zgjoYXP28ct4eSt&SC`1HVd?1d5mHu!DL@kA%_Mx~?=<4g#IgraN~V!Su&@+qSa%$< zZKixd@Pz`02IIYp^dq>`NN`qkkHNhvv;=aYq8yjfS56xY_omCm_0sU)!2k;bhD)kP zk!H=3rUyP0O?N)++9L6u0Qot3X8J36;9GSHn633vXn$uVIRQbSwUc+bvOf^apB`It z&*=?fo8f{o7RQ~uFYFg;UtjnRecup}y(o2Z0EmlO9f3<~lN*KwxE&bWIcP^?OlG6o ztCwOKoTn}5U9Mb2CwwpfKoeOwKmwr`M2?PJTh}Q^2d+4A?1kwn?Bim_gGA#3+dI>6 zP%)3-f$Soh`U>M9AMT^8DK1Rw3MNPm4()aXiIWw!UGbX^vGJBE22w==nE5Mw(TE+` zAQ9z&*)LFm&LiKDPsIPV@zAQ2h|Rr-K-V8?+`No(59_zpILLcK#?nzPTvmOedJq$P z5DO;z;os-+h+rA85yzOZQ7ssWW=zMUbR{VpRDbNS1R3fvvoizM%I_I_0jfe2;i0(b zQW<5R{E_`M9q)Hjwt~CJfl8ehnd4RCz1cjP>VdnIN_;nJ=*a=g9$M+g*kIsKGtp10U?Z^CfX!&Y~MU#Q`L= zZ?#&{Hqbi~X?9%J5hTJe{zf&l5=^Rq#tYn$Z|Ssp#hk8+2;Jq~kkb^HZ*CXpXMMF1 z2Elp*`T2$;ea(7-h73c^ESTg`LR(i*<&cbDG#z=3ZXULi zAbsjEk5op6+fio>J6f%8p0|`iydIDgyRswqUUaG(-}RkcPwdg~hOutRG*opnf0#}H z;4SqyeudT7KnHVo++T#Eo-EtC-PpSD+q!vd;lGBc}YJ^&CU0712vFar;R{iPO9 zKKU~#GXroIjAxbA4HTV|n7=n(w=Yl?pgv~CB(-*>SUhoaZ8IPk3o*L#^vdW85KYB@ z;Hr){Q@VLsIJejuXjp(KhVkT~B-sYZqt!qf@%UpRI@;f;MhaR-Uf8J2=q|jMadxv^ zn;?Y#BLxYhOJylA>!w8rra~yGd593LodS&-2lBK|A`d~iEJ&mvP`M(wt1$6J!6UTF zBna#FX=RE$2osyQXfPlmEuJE-=2xgv5t$YHr*y2W%9!SmKDOvoYgNNY)*7JGjJQ%W z=t7DU0VB#py>gQ1o)}?PG;eyO3LzwKdIWDuBz^D!-zZ_EJrt!v=)l&)6B(0zBE!1j zFuYAeblTvcIsRt2|9;z%^${BD)@N4Y6D7#Ct^!>gnAw2TYW-9)@hqikN^?DsDL|VjLED-Fv`Zz_qD`WWwHA zeN-B(}Y!k>D<0NE2(e)c3{VDT;q~klfC)$c3{u8l;6@> z>E}1r&-7-#!0vv%b-6yU8>|RH0%*L1>yL3unJ?q-NSNrv+y+S^#Z`Mee%WqLF~}H~ zs9v~cFP3uNeQg-9YVahTwi3;lK#0@J^ePp?YcK4F7#5IpFk=G4h~Uw+y}W7K0No4D zf3wJI`6n`!Nxx`c4M=*ry`HGDer=j-*e)U_+&sgNg(lB)xPuv}O3~j>c#gn8Y z6#-vaNhMivBtg=p#{;N=2qnz|AzC1Iq$GA^Cst@*X6_Ch5}ZTqLoFG2nOtA>$8A}0 z=l*W*w!C$>z9^vjt7AlN(O#|`ikJy!U|zx(T`JKdd9$L~P{Mdqy147%p|nv%uglIo z8I@z-JgrPRsU(8f`z&MyPgupjSV;jtM&Ndjh(Axhx<#MII6xFDf(f~Kv4{C^^}vhg zyPc|`WrEw>6m7m=&ch@XLuXf^;+F&a=)-UGk@YFif|m{vLEQbt>p_WBJDHd=c@2KT zHfa?o02!$afYzr)COnR-d>H9BLD$UG4JNXojK?=eqaa-?2MPdZ_*idQaPoINGhAw^|K%SjMw# zd`^jo=BVYF+o}DV3qXP{o>MhT=9Ayt1VcvZe9blr)>kA}NVt;03`iVl>gRZ4m(e zKB7sQExqN$A8E_uC(RM*LhYQmL5kXDE{+XiutF@Qg?NbN*H1i?1*vU z1I@-~t&JLD=vSHnUEd_}=b^%uuPyF131`NAZ>l0c-x(nIDq)d(`yfVznyZ6&M&!Up zq#}~yK%_*B3LhB=UxO>^yG(QaR9MiCKw&ouRPLfnNbMs;)Ky6BG3IXi1d-iXQ9alw zQebqC9Vw0--lKY5K?DG$_7VEnP=pS3)x1erC1eKa*oQe<41?K z=%BLHf{czDw^oz4KvMFBn|Ed}D8^Y`a?jC01%>SE~qd{!Xi`;Faer!%u6&X>j(qioMWW+6fP z_WnW`saY82PD#31fEjD&5RnKkADIRcl2~ga>G|prl#~Ym5h%230xN@O$Vpt~ zZzUH)0^fd_k6sih1`NX_J}i_K86cuh z6=i_@Z=4kW8#gh3-rn0gG^g4f0y5b3FIqN=pge5oWHr$`b4L!5l=iZ-P~nM4MO?HQ zTLDEbc2^_c+MET`XLf=qWT_mOXg-59Vg3wh7HmdD*VvGrmD>Hrl~#LdDnze6S{w*< zOwx_;XZ2WHDLQs}wUX@m6@&`rQSsdt>o<-)^`J1s96VZ5rhOy#o0_GzoJ~ z9ETaT4W-;^wqY@r7bOWCtXn6W^^IOS(fS2n=MM!JjDi&2Dh5-oQr2x{EI3<5M2N4ldUFsf z-a`6UW~S;ArD;Z~_P~(z&GS%m{z%OoCnC;dX-bF8DrSc$pBB)dOR`_;xZfmknp)|x zgc)6l^674QMu5|oyec}BzvJ^)@GJb#)9~WO-NI9xa4H=UqIbpmw=XlX|=Qvw)m9cM*R(i^lZ|4OIQL^WPlEez{j42(d>Oj_9EEL07 z2vS{|t-`XlY<6D1mi~KyL!Hkmmtsr}B8oDF&Vl^qHm4;g@J}rnKbqof?4A#K37Dm_ z#OR-kd{#ACX~|ki2^&5qN5Di2Qli2%sJXD;>J%OHy+MFo!I+~nRN$bZiGR$H1WP&Z zY5lxc#!tYQD!U4PdSyRc+!(;$N1oXAW4cTk!W>SG{&91>@_UQ%%|gUt99}QfUW$uj z5`=bP9SS7FWXob@C2(xw`Wt5#RqZ9amBnMc>LYv@f(sXCe9dzC<)N{KLik7$hLeKF z_j%u;>)rm*DA$m19HT0p984tYf$-ahNQw4Lc7V)5`MhjVmL9J*^ zHk#u|M}IVAQ{kGphL7`0-?8mG23BedV1$lXlzINC#1P`;I&0G$t)_KNZozS{f*1ZY z&L|SpM_C_mBD{(5i#(BBOEosp|45fyzl?%>oZHe$qEb*nFKz{E1 zAXbb@7H7{d&O@r$`-!4Y8NmHh04DK#iJ6j?+AY>Y#5FKYip?oasbEA@woI1Q$v2D3 zan5#!T39B2A=g5syco@UJP}pT_$2vPUMqS;O(cRf<9g!$YNz5b__bg}5yq`;;JudwscoJ^mp9B(K$I z{_saavn_;x6?n7euV{OyUIH5Ye-C90qu(ipKD^293$esURy|EtFhv&^f7G>&xkw?z z9{{ZAW}`kGa9+ztX_YYmkFI^_d|!e;qm^ahMF;?&0Nv%^BZrihK^F$Pz5s8B7xKQ& zv#t_|=f$V_$Pu4B0O^W9dQ1?$l0Fn=JU$VU_@z|JLPQW+%=JUYK5N!g!a}FCkTd2c z=MzS8W48adboXE$R9mmtc1uib5jZY-i+>ZP`gnTZ;D9M$2%uy1sG_bdxi@|h#&IR1 z6X0bKX)Ui|JiPf>aCn;k_TqTS7%leCxaPMAVwV3jW_`~`>U_9|)QwdK=!swQ%O;A6 z$Hzd4teF@dVPNKS<8WUMXc+*~e=W>tad0azdvFpP=yJZHaj|p4>(u;Tt-tm)Q~~nH zVRC353S*ylb@7ycB91S{ATF*t!pRz--+ayn5|vl8H%lKXYCLo3bIs<72q=l-lONp8 zN^me3bpEf3u=D>g0^;+3@@PY-Rf$-bh?E-efDx^pxEz*%U<~FJUPsI1Ov&0M4l?n+ z&~{2ELwcYi z$A1rVl|QYQNtL-yYpPjERZ+KZH%`>=D{Zo=SZHtY@E`)jzl-hl3}596)drfBz!R-! zUY~6U)tSv(TfDAlBfZ?Qd*7&Re)@OSkdVF5zjWmMUmf`~f$a$;`Hh$@UiXxMXARX+ z*pU^u|LTx=%QnUHeG!oi{Fci_tnylCXwLoj7=iywNAUkoN2RR4Y?lU{FUrRwZb$=t_`@w0SP>W zo)JOR@a8Oc$Ts&Y>cT=b+1o@WK$=h)2E>DlrJw2Mds|&Xo)=F&e6#+?)3F6O{=(W zbB*wPGAcktumGA7^4fdEl*vtKn|eoZvw|25WCNXc{O9->@kiyP$KBJG zc**T9hHXBh`M~1S@30ZQF88EDp5VB6-V1`UBcm>ky#H0P{mspbYb>O|gYH?xVWH>6 z|9gp1fq$*XzLR(`IHA%sGlkelmGk=&djRcMEk2S10reX)S)Yvs?y~GYMD-BAcH!*ubC^Y$Jkq zs?di#HXB^=XHlTe2w~JE_}4VCM{wKzl4jW7d5Ba~c}*Rfhf3q+=G&g5QI4Y5A6r_W`Tg=hR}7%)zs`wQA+pN>-4UtZhEBbf2FGU7u$e$ z2U0yzNkZ-7b@xY0HPCVW*1Z3)r9=~;F4Hr9hpvYNrRRbDK}%2xjPgf)SdkCIcI_ z4i&vG5$+76|DPqH|7Gxd=_Mvahc7R-@pZl=hL|@z=)k@?Yc&H@Ge3>Y>7aKdAAs8D zMbt_T)8CO)x!+on3ce?&AipLC(DncN&`12gmSq0NhYTc=wSS9J4{&p!d%lKytDylD zaK$id!fb}j;QjT2DTDy=6i_(-C7%A9iK$bt`L)4@D{*n2KTdRGtwaK!!BFqN$h z|8%!7FuyAW#;&*hZpv>^7y$`Td63AV?x5sc2q0SR(7^l7H56=SLj$Y?yGtAo=Sc#< zzXKC$MCef+VymLofRH0Ku{~n=a(6@boRFjgSJ2v-m+XGOsL@z3n)9 z&K;4$qvq#yX||_)$*iz8!){>s=YiVPB+tB@sHxE8a#c zz3C9(^?qSF?a1e-e$eeH&951CqJAnLkP>WI+>hr3A#P?)M(jS z7WW2S!0t%_Fkrkp^cMrW54#lgrr5JlXFnvotg0&~&e4L*Z>uwEuI_;T!l2_wLaAip zVySv|3|3oNZDn$wNz-vq@(K#`064SY>n#SR4 z7ifbop$&6{>^I0k-O8T!Ne`E+kYf$KRgY)3XMa#Frqb4{Yy-|l!gOZmL$+^W& zhB~zT&Ja*~b$$CnLd?I+s;vm~KV5u7m>P@q+o9*_9IDx$n&cVpIu!==x?|E%ErP8y zPpGNg-h8ztqqdvyY`lgM&JYaa_jHhiO8+$ozkp}Hl#6Rtd08ac^vN?W?SSIigW7kU zyTacxR#=`{6EMmej#LU&G(-zuG2l&ET}#O4vxX4GNdJ5h z5ibXa?!@exjvL~NW+C{3{cvP<)KHHrD~WY9@uk0JeN$bQi8DIh-2+^ z+6t(7s-)Q1@+1{PKIL~*G;z)plyY!@zQz0dG=Bn}32TtdQ)9AsjIHTrsJJq)>(`|R zK@uimPy@96Ss8M_TK#}$#o z=tX!=By-DrqYce{=S15F_QCWKR|WXoulyptxte95iK~0-%~%|lr2k9xBM-2qd>jO5 zKA0*aD13G9#aN*nK2>kJil+XN2~27Mm0OXxoDA$kII~#@Im+>SR2l)g==Pc)7&Ln> z9n>&&F57$2e^^$~tC*+g$cwM?z{Uo*9}=Y<#Qi~O$qMt2f#3)>Df`{qI*_;9;V*~I zUeD6_JbclSCoaxzalN%_URdlSTX#R}k|5g}7I;d}@*T4H3pF(}BadQpew+bcZ}uxX z-B+)fx1d={#zm7Fo|)&SQX*EQ85tibGkEp4J%}fR)}+r|YIa8n`KWE#MWuC8*A=Pj z;w{L-CwXbxHOu=L&-~a6We{Z_z(_ugG{Q}U&`_s5?P1YrYm`#V%Jqf;&G4c4az>Oq zU95{?KOfTh=8t4_g2{=jkEIC3?hcmnG;z|@p_=@WFKe|9&(?du+|#s97KCbRz~lUQ z?h1m_gq2flOSt|KB zN-EJ&CdXU0OQzv|uM{c3uJq~Cw{*8U{HMnoB;;-NBm;G$qmi~Wd>#0}+vVz~M<6at z7|Lp5SU&v&@BU4tC(swAx7mF>H(YPAp|DwibdS{SlQh}boAR)yykvh2k^I1KpHsD? zY4=9TshCSUwQQ!ibGuGunr2(R?`AR)Tmf?0IFLZ>(>gdwLJ;V;iZCs%oCuRO^Db;4vnv7xtm6 z?xNr-Y+TwDSW4&DI-QY$XVFlT7|D?JxS`n2=8Ufe3BxM3b_R~5SrN)3QIYdxOUM6= zVN=j+ki0KMe8s7_z*II6|lT)FI4I z2yc0;gzVZnNg1IL%VTrZaP%+2+`c3Z^541 zsoJuLwFtz8cb#Sq`}4j&Q7g*6tT%M{Bte#}S(DqW$!ZQ8tf>(&8;)*jD`mmOBUym| zG)AKCnzo{oQJz!(F-VQ?>zg0RZy02l%F*rcqn^m*#fq=ksr2H-Xj;9~Pyi3;nCg@( z#!k-x%Uz~2HYSIl9Zl?}?=VA@_@bjm48TBh;p~h6QOGf zlud545q~~r^jC-)sjIu=D%rYGYOBp1dzuu{ZIZx-6TZNi^(0+k!CryOdGOn;cktx9o10C~J@#MDJxkTDL#`e9--qoLerOUNb zHr-ui-8emdHzNw>iVuj+ z5+a@>zRcDhL)2!QWI!X!N*a^;0X%K$lPo83Wzu&|IR=92uwHXhBQ{x6J)8}PF!T8P?{0V2y?kqLP!^~lyN|=a{EXjLJEr$YMnIo|rooXjesN8HcHF0>1YymiL zp6XNTLx2l1j4{)I?TF$zTC-R$X+pYK)4GPWt5j$M6zoXu_g0%oR!9-C>9|5;&=+wbLA z5#GoJWbub4zsU0ht?@Q$0>xN4S{W9k07&;ro=TBK`qt-G^>W`mH|-qF(rSo)MSgjV3C#B&J~R_&&2#??u7nx#{vrloYarqyBKccqqOJV55* zy#ZZsL|eqwGwTO&-owTnic{mt6**=A98`hzG01l%15ey$En=vKGVd@ zg)GzK%|FdbDK?Xsp05nme^vBI!`Rjn?S;xE3jfgp0I7QTOaQnlDT<1@6xf3{o%&zE zM=MUoJR?!sPc3s}N~R);jHMKzBBDu<1p6Uw_;}qv`)Qx_D?@IlwRy7@Q#1!(>h(aR zWEpC8o<`ORh`#w_zZpAcTn)x08mScHDS8w&=IPLwMivJx32&x1 zNNy*QZsOGO$K#vYtoXM1j2a?YW;CV7tjH})3Y)O^n_n9Txt22!b8CN*l`%$ku|_{D zLlj~lqal(Tbdgp4L#L;AP4TEm$kNN9&0>feyI3&VT#+@SrB*C=l+&k0qHtVKUg?Be zi<(oBxU9!=tYBg5qwY_*&162qU@KvGk9hu=6bh;FWB7R9;T7U>`=vw52mHGNnFXAa zWbGXI&r6O`Xf6c4D;sB? zeOm-y zf=CxvxuzR#G>E))*zJ6uahg-b8TxJN9WZ>@a;8?g4CQq`hlBT3MmJzW{eL?|5yu-+ zdwrz~6N*}p^p?fA(24n1c>B{H@{Vr=Z1J*Q9Z1jf#&k_$CqXa2< zsBz2B?iG$P`*)*vxCu1fi90U;`)*Eo?_k=^++YSjMP(S4>9kAF*> zZ@fEhljyR1Z`R&S&4&HacjM87;OU(bQcQOmP+c$MZTAJ2mQa`H^UNd<(AcSO za50>R_LKDuc{tFFJQXo`B1G{x`)RiAw~w4uq&NYpG{`MvHO0fxc?Ox+w@KULmdcaT z^*$Y*Vvlm$S+ewI)1TpKU0mN9qw+Y5=&J|yip<2bwkNJ6IoSci`%0%OFYRU`-s_ z^;9h96BX;v7y6MB#t)O}AI_C(7&uX{fGZWbg#6{n_}i5JcayWvWj$u!QMcFd08Pxm z_14=Mk)oTraBGWv!jBa3kujp+P5VJmD{af7Z{ByLvw+`Nfc(d1t#R>cSum&QG43#H zSgoF`v#h`%Hrn%ao=^s70)a8S)ACjCx9OgV(rCJh=)M^>YU5_t+x9wbM(`--z&iIi zaQ9Vd*m3Rt{bR*x#jc5AQIH#C#a}Y=g_Nz^qhjEv2y>3ma^^<2BLpb<(cKk5OaOm#?!NGX@s9?+0J8 z`qVubj$1HhMj1;B@X&!LvMA$$RX2VzW=wdOjp1!{mqF)h-=$@zgRi55aAJ5Jjc*>u zU>&N(4F3;N#A3mLZfkbJO~lejWH>}ZiB-*g)32H}S46c8HItYnO-9NaGd|@zOuPWm z2$=S`ZAGr>STR)oNUTt^aiB%Y4l#U!|6hBf%Gf8}7`TNKND`cp!;259Ilkd-C?vyv zuUF>MJ`Xi~>BACW(j9IxJ5URSMli>?otQLTVDh%eMvq(P(?SDzrbRNx1M~}~L7>pFRR!~l`4LjK&fCK2?G414qx7iD-F1j8ifme9{@I3sY4>K)#l6>}zGr{`jy%h8*}?#shNAPQdr9~t}`pt+lNmb=fU{G33~%L>C3 ze-YN(2r-z~AM>*!QAWj!pV9-(rUy+1w0BgeqYhuR4j#fWgHjGJHw*jTF|lLkYDdqM zdSRxsmn1TNi03=m*!LGv0(I}_ETw17zo;H)Q(whv~wNn&=BkA`a_}iB+sB+^K>>nvUrPz}PJ_Kx;T_&na z0miTk*JkjsR6*R}g`YI^D*5a(CG(VZ{rDXptcUn%jJP--gYvNMNW6thOw!sb0WnnN z;Q_n2q+BF==mJ$_r@pki31QaR`*(07Pj_T!t%~=4s0>uECJtsBvsoJt13!*2uo1sA zxbi^GN8gXCO^5qw_v3!+o++;$>9A1EEO#cd`GU{uLqcYtRn^)%P=JxW#L-C(7Z3OgU;ydR#>7Xi%3dQ2?e`46)Xj5l`XC`r`5kxh0b@D{C)X zzA;!76!E+vi8OBd0miEDopAF3cA_{8m5!0&`$R_cT!McN?I-GZSRfNe(2|1qld-KvC9m~UWnl*Qo8GBDQmSSFGj{_wTLz23s5%`v75|ls)6EKLE zYhxLkp#0V^^!Ml=Pti`|Xmx}lv>wLJtEvZssm{Jj9PRL^&>2UBB1IAuWgZT?9!h(p zfV-M}_@0|fhJgv*rwrLLg*d z^l+r5>gYwKV8`_rtT1}gpl)aEw~?VtkCBEOJoH|Gxkpc|;nmvq@1-UnK=xs2-hxa7 z3K>TK-%~GaH(Odep*W_hB>PZ4HVUdJ^GsX=GFRS#MWgyIQkp!f`@J|Xr19vb`G6!H zUGE$82x;jtHclbXl?<%H3{wG^B^at1oUv1_Un~_y=digp?2xU117we{vE$L)s0mY& z4gavd>F^I{r0cQH9n|`0rpIrz_qhN0aaFQ(-k2HhI4hb5^)@kKp^IU}%tw~FF5I*j zS$W${2rXT2E|owQ*a0La8ZKuZgg(VMx{9pO6g6rSlZS;naZgD<#ESoFOu^1OY5EIp zFTdR1o{{7aHWU~};MZGZ#kez!r^pTMos|cI_}DtOI&tC`)t)_Fq5_dV7X~qa7HYxfsxsg zQ49Q8bzD8MMJjOiQseO(m_g_hZJ)0XvFJxzZ>n!aYH)dPX4EQYs$^iW|FJcRl_fD|qWsv33*|C?PR?UvflIo>I5HB{GJ2l~<^!wcu!*23kXZgV1RLw$v zdzVM~B1qqwP-&SPW4oGN4AU25<*!7$53b()RAew_*`n(o$j^Hf4JrmD=iPv^0Z97+ z-4`JTW#L~pvhN-Ua8VBG#?way@9f5fF%MB!-hG@DpVQ16cH}SuI{~~)H?;{tM!LSC zed=f*U3XzKmBLF?P+OCcsacqDL(=2-T^1TrF1FrI3v!8n-~1`pUBH(9Xl^pXYIXDGtzy4$~BDJ(H4)OhDq zxh7733K^2|1LN5KK|f#+n{+BJdrb=8(CMyOX)dQg(q}43kEK`B?pNDnWE8P6Y4rMD zv|&O;JXuz336>>gIlmHwU*T-nyO5hyI4!4~88?N1NxovDEt!pBUs8+T{-~hsSg*vA zqb4Lu`|e`+z>o%Y(@2O1QBhbA{FqkI-YqDo1=ZcF#O?Wa4`tA`=a^%xyl>m&$v-j` zX6&p|f)ZL<;Q5pL_DCYT2-8ya4DI7a`^-dX3cziTlg_W!GNkyFxb4LKeA91u;Sv-D z%WK92o3q47=O0LW5R#ma2<&9r7)rnISTZSY|H=auk=JGlbYluTcIb2Aw&S)uew6EL z>nb?KBcM>zdf6k+khsnUmP2m@>V#lx%#AR=^)$wyO+E`0$rTuTxfZm5pOh#q)+euD zUNCpsi?bB{&*BL&i1LeBZ=b$<K!=KgaoH7 zD;Wt_MugzEmrOJw5C{(L-!I9q9NHz3@($k|+Rk_h>i51P@ryIkl|QmTRPlc18AT^` zfl+F`8DT*N#&b=s#UBEfL*mpQJ zaN)mVi7y9?$onEu5Ng#lKz#f4IYJddF)h~YHL}@0G1ZH>Mv0KR)mk;P;^Oc51#zj> z`i|VBx4CPYru(brE?JJ8Go6-rtTIZtAC!_56x1WS3<3MN)Jw$4-FJAz9!{vdqPUvgBP1piaAy^{ zhrUf08s(-<`2}?s8YdrK=8spu5aQJ(VTXBc`T-Xhc4Tk22?1bfZ2QCF#~5(ugSx2+ zPNZ3OQ{t|%SAD75^ZpG;s&JlBYq28xXM#20ZFHdl0(u9lX)dq2jL?)Bkb4NhtxA>I zwJP3RS(vLzmG+#SYCl9(G2|4Y=xqGKz@+aZ#mBQ_K0^0=+Wi_bwjegW95R3Mf)Z6R z*EgvDJy^W)^le*vNJ)}|RR(Z0)mpq&XkC|(4@ycSnpzT|+Pu#&EOSM^5jl99oY=(D zUi5KHzzdjcA?>%H$3<`H^0IT%cg85e(h9GUabML9{>e16sSk%RfwjdIvF;C_SI1Lv z;isMyXUNnAbHFH|Q~-#%7ML7JL*t|+ezk!>C?9Y;n}t?ObW z3kkDQjajfYxdCL)n@)mLqE=b|UmtLukwXh^(^`t~^}95sVeO{j9(*PVcCo7MA)^^D z%Oxg2S(=nPA1oGbhIYM4mU?RELwM?bR`tyiq)%2 zp3&0jxJwiTrWt%ckbAHLs!u|kdH_9tA_KbD&0RmKxMKeYwD)v8!5kYE5T9QD@njQt z6Ou{O@7XyK1;x*aN(KPQJ9vSp3EM8L%T22)+P1_$Yy~J`Lh0KV6>TAr*fie4ct`G` zzq<^=Yw_wa(2FOTX3x$*6l&-5lY|{~o2V=TUWF+Se@KNDzX zW*(h*Z~o5-X{peZ<{us_)))G)_dBN~Gj)+586&0?SzGS{T8nbO z##Vr7;S8{dWtk#@{M z(xL|dH_ne2NQS|k%&RYb0zw0pm)Rz!-=bP6$}!Qbi|ZvqnqvPCU|-}2cK&d@8;j_Q z_(+?_*{}WZlysv8n16wb{_xsUjHCXvea6dFpW7zpM+oR!8h$yn6t${%yr?cX8v!)z*W_}ce7d#JgtuF z4aFJzo}E*^{!6822qpGgamPJk_OJC3iZb#}xGmomwkjJrA; zK7~v2ZaLNbW1@HKS zi`}jzEQp(iaTvPxQ3{cV*c=3YS7JR}XJ+(PEr`V27f$rCjh?Wn^&-dAkDSsP`>(88 z{5{XI5qTR;Q1EI(RTe#c_))KKIg#0C8<~6Dt+OW8C9Yi?yebLLM@1853kd<#1`o7W zrULS%kxE9jiYiAluTfm@V*PkGji7XWjAr7ux}zDC0@|B4S3)0ZfihQb7r+ zqWO@Y^wxidX^iyty3O54EAd!Gz{BD0-jre3=dvlQbih9R=m>!zD^)FN9W)TLs!;;Y zz{F8MtitQg%=AKHJHc@_ zAPC9nr;J?p_AX0&OE2&(K>N?b@$+a0@Q}=WhfkMo`tdK?(|QPw#DlZ00l4F>_27{s zoA(zWSS{Qq1t$-)h|yVCWoNGL^=X+gBXknLONsokn_Yjoi%sU1Uzy$NiO& zBes_&n7xi^^n{CRVeF@Ki^)hl*v;M2ij6NO%$2P@zeMY?8lr2X)5NIo*1)flxIN?} zk%2*}YADJ~%JPUSQWKzI($22S)rhnFZ`McSE7Kg(pTSK2>a2}a$=3VsCSvZG6EH3| zvt{ViqBR|#jPLhm6q)w%`h3*r_byQ}?8DN873b;}tEpMQkhyrDQTHi^Rq)+^KyKlm z6L~3QX$x9*-3+5b0VrN&_C6|+!54pP1)D_;qC}WTN@Cz@voW+(z#PB)zC}v7)^^_k zB|MV`5@I-)xny{aRvu%QIs4%pGj9iL@VVWUJ@GwUOkhplmNouqLTh;#}v#s00}S8WbbaoD(sKIW%AlWXuG{EtV*76VwUob zieI{#ANRaPh2{{Q-YgLBAKu>`u<`TyZ2MwRC4iOX+j8PEO~H}VvPN7UIZI?nGG3br znG>7s8KT3J8<`y)(z(B3yxUDs*(M=bbr8cmX4biT?~!Ww)Arwt#|!q z*YBLRVQ1u2w$!KI&JlqwDP5L|DXFJ+z@HUXrwba@0kUh!XHDyFIUnC`^%vP9mlxAN z+xr7F9GyvrG$VHPbeREp;l4sSj;$2(jl?&2Xdf>$_;81}M01?MIxV`7r*0=WH zyw?YU2%v++h0D?n=|@zS%Qc%@^sJe-v_cGcixD5u+d3%9Q<0owjv19k0hOlvq#A*Z zpIS_rT-8~#4-rLRY^WJ{1ZTB5)-;gK6!3(3wH^(w-E17o9p2w|Fz;=9y!yZ%p0ad3 zwmC}o{2vsSmfCuqR{ylf#->-)i^qfu=F$e+2+Z0<4RT!{I=|eFz5RyYDDU_jfWBtX z`x?<;Z9x5ey)ntk=3Rwn|GCtQo7`X!L0=9`FMjtqxg!hKh@4pG5ZCg)-#NOogY)5bSp&Bf zskAOdhKK;rP0u;pP|ORR3xfw_8-1(n9>DnN9mSXJlhiDO`RzYxYt9hYy%j_do@S53 zraZ3+9Iuo}bLqJ%eAgSIUFJ|+(lF`UFf7>8Ts@bp)y?19&Xzstkf$~=HiPeONSZJo z&KWMvFMRHik`rh&o%Oj&BgcAbwSbjg;Ki>k;2pGvUw*JFjB;^=EoSzEc5M<UU2R}aSesD=R2p|Q5(!jAYJham1?}2x_ z{s&%riq2BM{CgqKCDFh{12A_z8EL}h9qpl0CC#^eYREk_Zl3o{fU@J9bM~4Upkrpx z?PZnN{B;mFaB*<+=1b8D<9PV71J|N^ActILev8jnuOamGpRTwy66@zaw@6{A_Lnok zG?!gsStC;%zoKT%GdU}R0deTrzRZ|)PP25UvB=}#dkoh?0K^&ylk;3$Bg(U}qB5-V ztN+N9kGE&F9KE&jLPW^(1rKQUgJB)6u<5!#7%rXJn6H!75B*dhP8IOy zYwH=L5QIC;N8Q)J1}n}^?beq8+e!g_0xasc#^aeeO=vcJ2sDh+XW2?QLlV#ba$G@9 zkhT10MmcJ4p}o???|#$9XRxZK3}72d1h3q+<733^gPTTx8n~S669DHiNSy$@v2vY& zO3ghfJFNN)<)e0#zt7zmDv*uctt>>l-gcTHcXzv89e5u(r2i<6#e{09pPgyhn0;?? ziGe#QfwpJ%*}3#{BC``XA}d+V2WpDBv2CuWDuWj{z)kbTUO78VHdNkR!Mvx39I_h9 z>R$#ANfz-$HwbV+HL^S<#g<+GcgNXiLhO}G)_nJ?`0O@4a8o_h(0+2x`@UXOTJ&|6 zW-IcqZ%}AQQ@wmlT1TM@Pl(BI3X{v}%ZN{=#cwys7jHv2WaocQ9dzFD0g5Gi3#Z)q z9C3t;Wf1TmfLXf-Lk1~^j)qzHjkMTNeONjZ%C#}}O>+QAIR#s=XdR@%+*_XsK6BWe zf8%|$*b^Srh7vfj{w1kGMT>v?)DBYO(gz3q94-g%7HGqMr&y2z);Eb48A00<;K#ZT z2jk~*2PM(6cI9R9H}fRgobJhsEAPO|JY2%PKjAblNoE%VhV%j^IXLzJ~y(+^~u>T&{z2H3pyHZ+k5>zX^e zGhbd)hm>vp|L7Re9NL}(rdsJuAc@Ta!6Q%9IuPxM-LEx;-zAPK+-lA_A@}fgzI+DQ z^`DCzp8)To9PTzVz~z@f+7&40Kv}i54k$)U$L&3=;JZkqU@)BeApWTYN%P zd3{0pHhS^$1&-^==p?3=^XjS+I5e>fb9gcp3`~?g)|=)oOT_{nkhucDr$-O#P?JQ0 zP8ys}kVq*lKHl0IqufFDEeEc2!nUS<`Afxvo`|um@dl_I`7{meO(k zuH!C* zU6w%wB4rELJlZ@>7OM4aK7en#fo9!>0h&~fd@%{W`d_T6j|)e`LfVWTe>o)z2h4%DzD%OWrZ{%4`&Rfi-ic_1xw>A0wIAO(KIzIuR$tk(L5 zF1VvHipLecOj}H!X2X7g zZi?-P{?j|Xowt%zCQ(ZOjROuJ#0coQ+R%EUvhmC=!yLfkTcGlLyxB~d;iu8Y?7)sc ziHaE2RDcu=%uH*_osVqge5b9l2S*@}sjZ=LKGV$$=q+)+LB0+9QoIdEyzifY~AYbAoHJR?uo9?+bQJ+~F`xBBl3fU zIJQocm2kiM95=PO&7E&FrC<1ED>0t`?JDuy4i)39%?-pHt_KS6FB-~&B|ZGwlbZ{D zLv!7w#k|!X#2{bwm(%hX#@%B&v2^~vv{3wm`vCVdiYH$uEvX5@jGG9~rDvz|%bey? zB@4F+$?{EHaVi9U<$AbOx0HvC_JQN5y?xg_2UDpQ5Q_bAcFh{AX`kGwODpXiWsqVK z=jCflP~x`DV4&{?G^PqQup~D6G+-0d*+GD!+O{4tPrat{ilkew28`S|WHz{@UpS|q zIlERTdRHWR2et9E>Vv)=bdcBH(#DaVm>rdol6liaY|dqO_|}66251x!=m-In-!o<* zvQBerOJ7A89hi>r*}#NMlk!b2yLyl{=VY)Tj!1^tvbZLFtwhO~SeJ@#yt$iPcPN&8 z{)m7i?We`ZJ!S#^As`CyNZYvtG!Rm4lw6i}%W&P|9Z&1Ix7yAh4O*PYIBiN6JHC3% zU!mdCuG>Xo_@ud$`656pAHAVdlWJhb248DYwZ7(TU;?1il%cg0TA!?_?S1#mv;7rt zG`rS69wIa^x^rW8em;LSrK)5Z7j#X$f2nnf&Tf!LECF(xcRQybR(rf+TOVHY=1rUg zsMjqX?ajLBI-klDJI@~`19(6BHBTy+_saX|-9>6|GYMPxO?rQhB z*~3gqUt;C$1{CrolZomJbu3+Y}3Dv07yTd9vlUCnOX zwgji{00yO>m01(0XQw2mJah#SkxxWpc`;Kr37bVn*vx{en1vVz!1vx4Q|~|) zSIfU+Lgm{^rP|D#B9x~P%6v5lw%YhO-IWhG4AA8pWL%~kx%@MqrIx&P-9Nc(LJkTY z65cs_V|mc1DUSp24f66yLeu?}bm4fd_I|;sJBNEl6zIzkwKvnQlI7vYA?Mv68m@xh ze8H4eC%Q?{0Q=EGHixooZ-NOW(e{kUv}$Ul9kI{v88e^jX@dLn4C(x{>BbM@;3VA7 zsgn7Zd(b87m*IyVI^MoI*Ml9>!^4YlR+oY`CD}nmYFSU>{#B_2yhw|AfES1cWB{kk znU?^ohWeIYfAWlnoBhoPF;kYk*H)-Q#lpNc(aRU2Sg}^8|fDJ+0wv;wgYZlABh&%+4zx?9D&nKMwP@|!b*f=#F zJ(E{mQpG+e0%6Vrt+2i8%fjNijo$&gr)}?@qCuQ})ML(pL0U^HxiW zT7oP@YVSWICzHSQGVwwey^XYrmwp48pOlgiBm*u}3=nOHd5PJFtEbkEVZY;1&Xz0H zwh3G9hU-#~2Q4$OE0SLGX!JVGUY@A;q%v)~!f>UjUo-RF5{UYr%(P+`4d6eRfvI&U z$&8#^cA7=YttNcC2?o1A-EWPUTYp@ux6~9Y>bf3z4j70J$_dQwR`tX0K&EQ-rdecs z%HsNK;=)<{fYou&7DyGyGQJzUmW;}u{0FEuq_vHmRh5bH$eESWwizvwd#;OQ`urWq zF#}_ibXYzyWG-LZG)pm%ZE|FJJO@hOzgK)uqjoLzbQ}+gDi#s_KwY+-G&P2`&1xuOliTs% z8INH!yDM{)L&G>gAb{St-?r86z21URzGG$plvZjmk}T99mUKnPR}_N0rtn4ydoFn0o~8w=QmO_S*GG*inOB>c11A|K-Z? zyxXGiQ|nExj=Mb^Ewl)LTV8t&ou=Es8sR1pARYWSd)zdwZlpAG_%#=un)ziw7>_iiC{@&}X`tnQeOMeP&w>1K#uE3ib9gob_n|U^^ zOjUs|NjAF=rUoP(8QE|>Z@Wy~9HAJ)4K7D(F8u1w8)x|B0-!*e322wox&}wVR^qHD zVvNmj_k_H8`Hks_|DLZy`1oe>;Xgd_2c-mq zFOi&9%B=@~u)q@2FfZ~i&%sa+{2K&*nZG-ng!20ewq3>}mx3aRRVg`=b%$t@RS=w; z!bk_5V*`G^4u2=Xd8q3p_aF5I7fwBSoE?@5NW~p6-;LsL6A^6C?2|)x4&r=HA}g|) zSg*U5+Kwrbn%s+MosT_qu5NPNK%%d+sStX+-+IXtUf^0qLk->5{IDR~3^q zO$u=m<=6NS_|SG5TsuFS6&V@G-~$X>yU6}6U_&Tlx8lZ^TFjC=PV0eLPRewT08D+> z89zjqHb6BM#46C%6JBGbbshm9Y|u&-PPrfi$cBb8Nn_JlproSI$PK)3-%wOZ-k4Uj=R=@vBmYJkRlM4k2O~pb2(}Y=wcVr=N?gj;`)*cfIO% zt3ad2b@gzabpt$uo&NsX=Dz#pIQvlIZndyY^F%voeE9w>jd`I;`XQ%jFao=PF5UO# zz|et3qV-6FT~-KqqC+EGMok#bd5?W=F7OA`lZM1A#*Zhm`GEEDkH@b#+MqF+wweK2 zVjZ_D`Tpk%=`FME!JEvCgpPH%5?V}7T%|r*nX-kU-D`u$LMPEt5A^G6>~Jy0pX04` zAT2X;M*Xj9Do%ph#53Ju|F5UVW=^9EBlMl_VO2vV=@F7}^U=mNug6~mqd+8DZli^I zs1TIj@oTP!^TE>noe9Xe&VTX#d0pjL0bg4tYRgOM!(+$<2c1FEPQ zWTb(F+IedFfEdc#`Xk*YowMV+$!g+l)5O`ld4xOPbv@hBUtd0|cnOfyq_NjhwS0bm z+eM#FWP8|9)?iHeFWw75NwNoe;(bAoztFj!A5U+b2dz=khs-|~skQ(UMY1?*KY-3w z^&XI#o~JVpAx;K|TtADbPzXaL(tkwPpI*Kt<7dbYcJ^ zrqK0kZ>q@mjO;FVc608I%$?E6TAwvcwo+v8juP4@l zejG?ONi5A)M~021kzW^9)Y|RNivU$ueK>VzwddvlzT2%kg+S|yQ3r4poy`Yh24m(Q*rta!J6z2d5SDAqr_`1`u0@l1*x*}6bj{t}l}++=DkegS z{U%nGxosk%jjkTD)ra&A3{jZm`h-$AGZd&-N)d}}YE0;@u7_Hgzzi2&CtJ+A^)~>B z9)dV7d>X%3QVl3%@MoKTI<_QfMY54BwD{Y!o*;p67DOUL0Cl5KYZR%r4&9OB2=Q_% z`ul?L6y#CmHMAwEUak)&ILm68(GWx#Hn|Fwh6u~N2L-|Fz$rJf}!x#FIP7Z4l5E(_+(cJ$c%+V{x%OF9K3$G;f^x3Mj2gRKX>zYJg+{ zWFR8AQrHtUK0BHL*S9irP}70YOS&EX()PZe7J&Zx!&%5w=TO#=W%xD$P8oLnX=iSC zMsm)ZzBF90!UTMNunW5aP%rp6rtjbE4xz`x`BNnAK|&A}t_5Z~Ru@)9^_;<1YsAhT zz=6g-0w9QiY;A_AxYw`j;GdNOo^oh10f?$Tt0;%bR^&S9hWNN{3IixFAs#GP^$ap- zS85(7-$pklg7rV)QV6_mO(tc9s$>kv|T; zr`dhiK$N;5$rIjoy|F)kdK~37+kb7MvF|{~(F$3v0DPkbd1ju6Db+uT8-3tGXwLRG zmd~h-Zw2|STcj<-8s@+Kp~|zuMF7Glz?kzkdZ0L`1&$}pJ+SJ(Z0nHQO|EB2D!Ef^u4FbRc{AVOmkQK{Xlu$u=2L-%X^Xasx`h#QIFh zK;R1(lL=T616@ve4oJGZ3_Cs+&->zt83j5;fXOMZ+Cyqp^d07u3Bc%yrtbY4LriQz zwz;nVuHh#xiuSzoSa8FEWb0B4<7H&m#lgH0fGV-l60aiua07v`D@bdBK$*)SKcm4& z)g0)-zim1mZ7q^M2nSz=kAi&PWjzyhb6lN7NMtb!w5xRk`Rv1FHc=!%S$|z&M$LD+ z_2Fl~2CC*BsCkg!1)(CSVgs#4N8Yh~y6^pI=!++0=?au;K)RJ$OmABLmS%ce_ctsb zh?S_Yt(k-@i`#%q2 z|K?s95&1`NkS>8-iMm*_h8AUWv-@C!`t)jSEAvBJ zhR}gb3giR0z#&Z7)8}C27ucL@;`D%X``QBa1Gdz|W9HY# z0WB~9x&gWGfT9iP1oIqplWjkw!YQ9qJo#=^YE#OPTU6`^I5p|w*ux@1?kf~C7^z_| zYb=~{(FLg3fW8~7#@q1cfPDq{50KEJyr7Oam^c1{!wjJeEXl4yBy#^e5*Y6LMf(R* z^lTX(V4&6%#*g7L`v(LykG4r@>&urGc{*dm2=A6Rc|hXn-z4oHT|h(1a9Jsn%{9dX z;{zUYxX#J8yhWkP5jvJECJa?Cy#ncTZ6PeJUaUd=ZdP0LsVPHL@$QZUTbi7h&SIMKAQd{tOy}nWRNbbOnIie(Azrq!`xvj|393 z$k7`i5ChjQr_adwoV?j@7)qZ9=2SM&qln0ZyF-w6w3?Es=c(>-A`R{T!3pfh#{ZW3 zJ?KimrAY}|V}PPcax_*@_`%8E9s{yPSuGxz(ey(w#CtxcopgosI7ycx! zaZ#>enQ{B(9INB*_8g`}*ml+JUGeW&-&uVEYA?#1l~=>00)FGcVlOa|VvYb+)nXNSj2@<)B>JgI^|L$+cQvNiIlO)Gj_j!) zrbCL6^bnJ-IerjYNM^t%-mur#LAI{6p?qF^Kc->HEj1B+Gj7uJss6?+BP|O^hJ+}{ z*Ht#(@r7IXwq$D`Axs^K3^G^fdYj=o5IR#+=E%uuF!;5!@Dc1d2yoBoBYaKJd~}>* zG(XJnI$`)DhjcXkg8Jj?2tzrVt0wM|c=7Lrxuh9Z@*(_KPCbJ4pMUokeBHKZ5B4nj z-9`546OSep&L_DXQa(~E@NKyqqfzCbhz;Awqt?EEF4BLK)?;4&HUE?WPi4y0O0Fq& zX>-}7?f(7ULX+^tahjGk=*9W)r?!hl`s!0CKRE_E`s!dT7Reu01f^-awX?_6CYyFV zErYsrZp9Tfh+^ma?W15^jI~XNBzyD#hxO{tAfxl$>l{X!R|5ouB)?X?JZx=E5gw^^ zo40<2@C+mmmFhCp43^c0@&}o6hIrk2{h3}0Z@F#RvJ4lTbQ)yHvommh)PP60H?!>* z=9k^NC)!&=e5;l5!iyh=UdeFEUbWx2sy0!?m@)iigF1B%CRX&Pk)?!>IwmMr+}K6<^#nqXkPtpk zekd*7tcr8-&!wN?RX#>qY{ObuvsFR5pTnm)bZK*c>>~N70yNfr`15f7PNjKYcK7*T z+d1C9xZ>gYotGWqvxjWSLmxS-a)JNEu9TaZ-fo>SYw z53P!|;bP(gNJ6Xs<>2!jw6tCII55jzjt1GIab$YN_pbcOY_2?L0aaX3=a(-9<1(D8 z+4U2vmAZWLDAX0rE92RTlhgOMarBs=$InT61j`kjqw!%}4CSS(!~NXSX{hGp_%r)r zDmmzUq0StRIMEzJ;_|fBPY@~@h#_AHXY>gn`lDV939*a`pWmvu?a@%W|E6sJ?ok>g zHi{Kai4~punoNX}O!#x`BLwG`D9<84&8h&+qKH%dXBKW8oa#z!(LRrJ;429RQm*S4 zFXh!-!~UZM@IE+~^-tpY=bU~z*H3no3K9EFFvI$_!vp1AHO(^wRc$Cm!tkpE?cbWl zfm%}A3ZrD<`kXVtD~1ARm?soqQ<+s**c!gVintgUD(sH3LhAWu_Iq?~ID*`pstQN7 zpv+;kDi*z^Cb4Qmlr@=Mzx#>I(=D^LKE=K{ajwm6t3kY7*kgw*z^#7p$iikF^xSYA zQgEGvbAxAZnkF(##at+(?#g8^M6jF}MC(<%!IkqYikS3#R04SnZhx{Si&!ljTrT}s z7WbD{Tjn;xE;;Dn)4%~0KD(B8At}WV>n$}RzCS}%Rn-=e8E;|AAo2@~I7=pGSa6N_ zPBR)MPW#6_tC+YqY5uDjL|GV8ym;!AUto9hHDn9xQUq(%_Gy*vi_yg{mq4rj=-|hzis9;UUcMX$Z`_= z>dkzFhIwM(Q;k_=`?OI{pS>nxZX0bQNu?@osH1$kg(;!l_Y*@r6 z5O}V7t z;5pX!j85W-xp)xI>SJ9zc?1k%wqiT5G<8B)uuCBezjO^oY%4~;SFi9ea{2HC#Ta(( z(yTpeMRLo0#xK7RmOv<{P_1=6*;IZ>GGT_3iZzsdX8HPw!S75Q=TQ7#yw0kp_ z<+pESnXb%$P`0K>)fbVf9ezAXTt!9Pd`Vm-B{3y~R*{33}jPy?|rkY1n$Km0@o zjN(PUB6~(bhVdF_p3|EsF;EEN_a)yBtxQp#Rz?1YVhp|V=VE2IT`G5J{YR+xD^e;4 zP$smsG>2#ZH5`5f)C)(Av$K@~GvT*={JXGyaAEXj+25C_<*6uF{cH?6>E{khD4x!b z>%mbIs%}E{=hG5DbEKRZ543%S&}99(r8;UN6Q#3f9^x$~fBbEL|-PM=W_`><(qnub%Q-W2Eux1XrpvWTxMf10N zrDbcw>Ub{7({?6K8FS=g*z5Qrj-9#S5L*O{&W_CBiJ5qi#L+%RV3-pH%hjqV+Nvqq zstW!FHbk&h(YR1Er|0`jMm5+DN+J;t-mo*%C-5rT*&MwPFxtG(OigtlsZyI(pHb(R z`fJWq#%~b+ekQ6=%Gn(GPRhvdic}GbQ_7TBOd+)G7;$Onxp` zlpl5cM$ZN|XWbk@gtvO7dhb?&;R;Jq<7Md zWx#}%*Z(BO0T4ph2EP#-e(>zEEni$nWEL$r|#UdBXhAI zfqTA2c7O2mZ?z{|`})-Y z!q>23eLkH}^@^h90HmvmmMaR?s|Hyolc~t@sC`U~4SBGu6j;%~v{GP&=QQyx?%3w; za4S0mDnE5+OX@MN|61I=OlzezYWo5{nmmWZj3?;vVfJ}L*KZ2o1b^M$4ks1UvQe)M zD7omjD%v$@F)6;?EtjedWw^wO4!}YU)>s$?7)pPIWfiMo&Gh)HV2_hlr6lse8R@c` zc-6UM0ry)8u-Zhk)&Q*l-)_qiqRJT{&NA{`Q$$!0ywa!N?M;p8kG~od(5fg+d_Y%{ z5iT2@shzrLE`a?g;(nVNmRj7-;x_%2GtMd7P14R3l3&C7ccL(6H_LWC z&Gqfp{$8i93ynJu&q%zfFgT?-P?UlCs#JRYH=wMsd>L6c?9E>(T;~@v$f+8r&b1<= zSkc)uE7rubkGfPi#Km&72_Al)I|t%P()NO<<>`@Y}z94EYm#RLDnL?rV{zV* zNaaL0t4gp^$}kW*cNMMUc18u6&<4r^9S>CrX5448YKKBwh=G>#kakViE`2Sn@G{$y zA3}Cz$RnJ&yF!|+CpJ4@-4dg5BI=%wZ$E#QjHhaWMDze&TJo6(O&7cXW)mK{7A|(v zy1VY_>QBEPv4~o(&-X_9tRn6zV+Z-LfY&0&QAsTt(Oazj_W$m8d%D-9CN5OpkY2zuw#74g41g#}UyT0l#3-$T|K+L_?M|2?Q6Uk(yD%mTDhdKB@={+Qy~KGW z&6SwPa#$I~S2x6Th$N5OrF~am+3r_Ng0jlzlQA=AVYZ!|Y@|hKBb@W@?{)}OEzoKh zBu=AI`)hpI9YQ36qk;li={_*WRF~`{OIxCK1m0xsUk0rC2*o0fa0<9{&!|o=nY`AT zRMVm`jOFX{a|juYwDG*I>YKQliRZihN|PC4>Kg6y2S(@Jn5VjF$1{GR&|JD5-|}}@ zG5T1v%dAz-{Jxwy`3dvOjP(@sva+yOF;srkp{pEC1WUQNAYy^N?|yh_;VD8cqt6f} zYhymd03Zsxc}%-(-Hu0sA;){wy9mV0ns0sgZ^S6c$-Cclz}HH5aVla&KPgYm*6)tF zmL`->>N_zfz*Bn;vLY+KN8H^w>PC#Rw?kn$>9dR{BUYi^$nvO$ zmRe=0sykKLma>=YNw@&RmoIp?@pza>xb_Z{L2{zTf-{Xw=s3B^GD&#zdkT?OLd?~C$Ev*y<-$ds6moWrn`~uPXJ%_wxx6vfIT7+ zeXp!KGW_-_%~TKau6bH(uC>n2g9!5AO9o9C{50nWTjZ+7h#e3`gI9gOv)o%WQGB_( z51a*~wqXxPQ_Mtl5P8Olu^v)KHe}V1Q~ATd!$VW4u8wA=Ce|StEqi36rRk;bdKFN< zcft{~lyml2$GeN3CRI<@8ehMXi2wewFWOnv_JOSA8``|wHA8(2glC0C{6X|ugirVg z2fx1zZ!#;q(5WwWjFW~13g;S{hrx)z`~j#eJ;w*(0>Wk`cq}h<9)cG1b%(d8LEjr0 z1mfU|1N(;^y%(Q5;3PZXd}Df0l#(r*-!SEqy?Q0gJnh!XcU_dhq&R68qT-mEOabA> z1kq)=PAiA?n(lgeK+!W#Bjnqq6Ve+7vNwTm>uiv~=I#)X!y^fx5~_Y{?#vBbJZaUl zcjNsyL%v84tgEanH?OQ@N>fu4prIe*D#}uEWsPihCK~m!0wR^X2!Rk>PD1A+EXkdzGJ{kFm?zvlghz?mk!%GldugLCX@?eRfus7nL_Vjo{$MV_uuz!#S@y* z-?q_O6nru328QieY>M(JEzVpHO9`tz^QgkI{1ULKrxs7%A&B?XUTM^fyQn}ws5o`WN~TRk4V-@ zq_2F%m=loX2-h#8RTMAw)grI$LJBj5aJhG z_DDwbxp18l0=#6{$as!O#*z|+c>ZYgCH)l=!#<7c>YjYBT_tN*NRR6>5Vz~Fh89wJ zA1qGoZFLqwGqnwb#x$M4-^v^TH;_Un zXcCoszGOCQMyl41G;p)MmR0AXH+k=;cPrl;zp9add!rhLj_u~(-y@wM6RAzH)!U`|lg2TWLYIJT;DFLJp=A^?UlwKRCAwOkoag=U-t!&b z=PdcrEAyhWmtNk3j3LiQE^khVgf~thYCl%4F*OW#vRw$=3@3$Q z2!EaS!sA7Za76fhik%)1QBlGZB0`^+l#)ZNljG&BIeBtqcDX#17y+TcK|6H#t=8Di zq3a1>(^uJ;LwWyx|I3qHi4mp5?8`9ML(fV`>r5)#mz zM4umpkPKnzQb0Jv@uJ$?druVSX`KLH+zGu~cb4t95CR&nu`Tx3O0mH+(CZb*$BM(O zOQgi~?NIN{E2qUepQU<-xjLVZRkO=S-`lJN4&f_qknJKP>dLoV440;$HLtO4JS^I7 zo_anx8|k?9sro69BamKobJ#?Jd-P-NOQSy18auL=jv!Cs)Hl6L*y}WE=4L@7=6ONbi;c56sEJ->)D-ke z>t~Y`Ac{@xM1wL}*5^A!x(dML@KU*6-WLAZb$2qrq)WGo)P%K_gyjUdckikH9r0a< z1?IW$yipvIWXY0X$%1z#i&w=3#{@1mHn`h;GAE~vJS8P8Tij1lvyHpY4Vpf;GT`Bj zD?{;EvbyHhOn@wX`PF8^*O!DvcLPY5yH>(+od$2)jHqkAJEhP zqSgJldGmtj>QlyY|9iy$w#pHvc@*~%j8k?O3N4>}4Cu4}DSR${FP?%QDC{-Lz`3IV za&yjoajyo*T8R;PEcX@;kQt=Oo9-WTig|iqf_q^43MqKJ?pj?m?fzU7EeXluNl$S3 zPUMbGDf6FKTr}XWgom4WfE*GLu@ij%>x5B?kmAcwkHcRYmj)(lbPk=OLP`6~%5AS} z(7=tYdum=?Oc8#;#3j^%16IXUhnP4;J6@i{)D8k~f1NjL32H(=vk}!@us_OF>}#)z zu*UWWcwjo=Iddk8&znHb^fE*P7snU`cYEjRn))Q<_=SMis>GiKI#+`!Uc~`A4JWJ6ZG&SiPSGzBq2KugGvR50VfI(E8c=?D13Q@6 z9e*e&?m?+SCH&U2Qf2+;WpATbP(;c4hNQ6nmM=OqFf^fe9TnKiRe}rAE`B|bX~=8# z+v{hE{rUa`=ZgoS`-@|k*MUc#WB4Zlsq?w%f48f}dzS^^*^A3dz_Z6CqJ+EnI}q|| zbsY?I!=Nzxk_1%!XOjc?%eZcEMGf4s^^YKHyPGeZ!S7keQFrUlLe@s?6ETzU$15)( zLfBx1cn}}>icask17)k)7_45t+v^ebsv+>E*b0R6Hp5joHgKHI>65U0U|R|v<8|FY zcuCX+ysVTRHbLoAxMx1BQR@~o*hf^|o+6jLw;WOZDT9EnfvwV~cVVV_E5xul{}Gsz zSV>0dnZ2JL#cs?e_8p&}ba`zqxVMOMJy_;!Wsi^OCn#gwxGN;hCL8{B78Gvib< z^JzdXR!^#X_naF1w_nfjrT2IDI{pbZPq`7wjruw#*`BkSw$U<+O;pTnoj}1JwTa zf7U5*Je#}C%@^&<#Raa_8Qp&r_YBYk%wwy_D@&CfF{S52k-+^ro7N7pf7gJR@Ah@^ zi6MswP?<4!7}yljIE=pEbnw^9K2R{R8<6!0&lZ#CPHcMpm|K@AaYHDp^f9Ez8#mYf z%Ai;gdNOR14bxEirGvalo;-xEsDBJp^5{=>0J#((nA6z;Ln3ADGA2tqWp< z2xKu+)8K4LS+g3~u>t{fkh9kjbtVl(sHv`wfsyoIuOHT%`4bcmCoq%RL|qWAvE$Z4 zc^&}+de|Vs7d*R4@uINE`_BcryW~;@__?9wt+jiQBEcMiiA=k(M-&fFf_U#L$EYbX z{d?D!riQUSAm{~qcp%{|BN|^cq2{Rot(F$I3qmG!SDhgeu(a8<%|zRp)ZS8&%XsEdB^XPU>IGYVvIlw_j#%J~?fi$(N~;)_((K6;w9CtX zUl5cZ$)8@67VZ8yT$GkbJSp5%AT^FOEzJ8HCwau3>4QsuqE@o^w6cdrM2OI%wyTJG zQiKbYUp4+d;;iAD-}^`Q%>&LfK1(jrrVqGS1FtSDMf{ggT)dp{tz+M|!vi|}IV|C| zhRh2qlnBSdBKSDFbt*9|BY&q5fJMyFxEOHY9Nge*j!aVdHs8RqSe<@BH+c|!>r6s~ zC$;Zphzn*rd5%)Jf%mCl;w|Hwuv4pVxkutIDBG7?$13-yxQFi%{>yXbuskQMzU=Z& zcZmK|a!=@!P1Fa7bE~V-;5<&;#>@E0}raCc@is_3Py z>@?ajy+*|GR_MhNkWw+rQ~9hY93=8*Kn>!KMPkhlg7*R|7`InYrIblH-TI zdY4B7V-nmR8Z>#KG<6(=0)lzqlLJKxleIHQ*BaqrClm7;q{1QqCBcH`sEZ4T3t+d_ zFIXVoJO8HKZW9AUIFDR_dJ4r7S=WlQn`5e0c6xG#-TsT2u`top19|XTDNI8RyiXD3 z2%*JQ#YF6)t`Pe!twn71&1yqS-+zYA z5Zi<|UTM9+|A%D73>=C;3Z7eB4F=njO(q%y%d=Y3oEf?@ELk1rxAcQr(|@)nrFxGd zcVaxg)oXWO?zS7p7pK>0WSt_Vl3v@Q9?&}&!( zeLhVEf5cnYWSyFVCEopSF91luVv3s3uf&}3><|9LsO&(*NEZKf{UR=H)Qu;`;;7U3 zt^bI9+VsH$-ggN8FChxX;ia^Fmxcq}Mnnp0ALT z9bte0kDa}ClSV{1y4oS%F5-`+>ra^&NH>w5H(`R8Rct%D!oRDfe&nF8A(ZPa4MsU$DmC}|ab=3><_WkyK+WzjH75h9 zr9KTczNJ*d_8XphJWOV=Y-pKcA_#)mVBMzn+^ZBA@(dk5m#u+@nA9N@E@RZ!e@Yp( z-``7x8|o;#uH=Vd)#Z-HHv-DrxyIMNt3a1wvHo(yvl7eeANAaEc1G439qU!V~Yn@3hvi{;1=l{kskP6TzYk<>5 zX?mlTx*?~5iF=FyKJcr5)I9#|)D}F;ZrC;1hqIZM_~K-Lz}(B}7nq{&LucY?~KK+y=342 z&p)YQ{;8j7tNSl{&KD)`I5rUvOS}^l=l@d+78Y&16bjyLlrET1P<3DalcOj~?8uE; z-H4nFnqw!!vDZQ;A31OJOBl3q1v?p~JuB5a19@|SaV68KFD^5yFLH&OeL3<^a(3hj z<|2wkT!MLr%?mFU-FB566;m;qZjM&|pcaa!jK$(3U+#FItzLlL8YOe3Q27c^hZo_T7uP%ULbIQx-jHK-_`5j^hSr{ zeG901JQ^I7dMgY_$1u0ZfY;^WkiNCoDP`F=Qj)42K|=s}i}CgVDh=u~$n7uT=hZ)g zX8(}}RYQa=*P_n<#$4dA2Q*);fBi};gYyS-krsvaBxxy*v2FC;(xVqf{Q-l-mO6jH zpzy3UV1h_Evc)0;j_+2Z_v*J#02c%f>%D-x9+-d{Wvi^95c37~$!4F=R zD|XWaoEo)WD%2@WMhbeO zVk{a0kj=j+K#GQz6 zY{47QCp2u8?6N+H1YuiQe;phlruBRK(xA)iG3v*{NJee|qm)!I#*CG?Y?(0*tUs;EYD^Z}-g$04L#WopRT?{ApO`uH!NQT+b&!;Ntpu=Aa?;YM||CygTBLik=^ z-SXDXOgCnh5?P~d7D2Xvg%^@Or)Q@((BgUukX=A|<8rYhky;lMS_nu6g}+sWi@iBL zNNkMS?KHl32=})ej3VymxYq?s!r(N&A-oDhI3{7GP7dvR15bTos@s;T>RtQ>*Eua}ZHivNC)1+5){8 zf?y@raAf|~F!VWSU<5r5paZDd!Gn#Fejx^PveUte?8qP|sAx~n=N#8ageNMtPOv5v zzbqZrxmz1*IM{u%(MBn$ewUk@``fJ*M=N;GG%~^iaq?n)5vPKldHU$adl~QeX7?9nPB$_GNloyuxxpnSV=8nkRW03UOzb=S zGTn;UabLGkzwEBrbd6t5GmD4_*k|mtUpjwi|Sf^9%e@vH9y4Oa`YWnJhVR+ zWl;QeLvW|c=D`clJDc)((m2iZVe{8#pQLU%s;B}xDgkiT52Bwr>9Qt1*&G`-Gh+-3 z_>~g=Zlmr3<^&)+fELqQC9W+DX;*EzD{sFWer60nIn)49B*x>ID)L<8SC%lP) z!L@j8F#zr_#Bxz*gsA;HvQ(|EM4~Dm7vzssKi^w{gTa(23Mb32+l z3*7rUDnf-Dd^d~2fdR4qX=#27db^!neDOi?&`%6{v7VC(`@)T7iNr#mcY)sg=fH-v z?5p?VXfDK_a$}BgexTSYzS00tWE1p1uD6!zH~2jY26hA^k-<%9;czC5885O7KSq|A zT8Rd&OJVtO-L+B42i)Aj&y7CUO9AmT7GHz4rCPufyd=sqxx`~&Hm{Xw0pq1pbCR#Z zwsz!iMJ+IscXc|8V`|3u!(I39W}HW&MuXcWXn!?S7H=JAZI4MT@s_c|H3%i1Rx;B| z{>Nhee_3Z5I>qzGVr6=KU*v%EU(zjO0Y_k~|CR$UL64#fa341aXIlJ6~ zCMK$nk*HVG0vDUJ_X~mx&zYo5H-CL~f%`Oi2)v+qz(MT%4cj3V%GISd@_cD}M8CPp zBaADktLyO%*g14@=Ogl2%@A|iMCdz?3wJtHviB}0Q#x4rl}WPc&Q`T&QxL~ z2>k?WoN&B_@f-ZC(TaYa2xoz{PR##-41xTh4>;`pLx}=9?WL>qPT0CjsMI&c$qUn0 zd{HScX84;Dg$|Q@zqmTKPcDGyG*CwB-}1^A%|EBP;lm-SPASrH6~|#Hq6Z@*{i&p< zRG+x72jGlOu~!Ua*I*d=+`D_P=8w?H8Xq(|miP9H#DG8?v@`k?;_GZ0RD|>VV zH8^wsxP<{bGRinI?wd{{1Z6hpFZcR2hbIDhHI~rg=k=p@qnfai-;ZvF=C|%IYiZ%fw=XElScJ5Z2uUhuOpd40` zzh)>ORAs{}zKMdo5Q67qrSW&lTiu%ge~ab=QNfP<+8Z<(aIz)FN*ql6666_S(67Tm zW!yQ|mKtR226~+-+qIp}YczQOmYOgs%F*>&{lQp{2y)ICRqfSK{p$0&{%2(49=W^7 zutTBdr_lndUt;Hn(ODOJRgG~*W2iem6~~$z2XN%AVQ#-joyg)+$U6bR8 zH=qyOW3=WPEf6%NgFC*lttRRjtS<2$1d0tC%4lSjl2D`*d8tQ~dQVQ}&8RJB{M` zx^~-ZxHR?l|Mm)M0wP4CcWZ2REI%l+ax;kUcRtsz2?E*^RC}tPl;0FAK^_FGTkvHO zgf4@Fo)~R&D%VuRb%PoI1XXHv`N>L#p}dbUKH&L+gv;%jUzSnd5rR;FQ`L5;E@41t1 z_3jnfc9ktUX9}J7=1gJ{xFc&s)`4~$ll^0O-!bbPpPid@(^IFm04n2v8^HA6F%0@R zfQF))S{GJKW(or9sBcd0mXKEVp^C~1oV&I>oYUvA&`Wjq&G;2-J$}~3rklpz6CyZ= z#W35(Dq-voWN{aMpq=o?k^EX3L7y{Vm!gtb00$le5YpM4MD2*2zxZt)j#vkZuE!BP zV$D=j7&uVe`(^FK8lEHK3jbO(qN?SZ8}3;=!<8>i+X@#OMzY^;<)7G;HW`)ntV3b8 zXJYRnb|jX}Yvz9G#WSJ?`Oy3Ty-@tE$Z+6ErIU|Kf}(D}&R+J+oaEF~c8Ersd? zsB9d zxRzdhj+m#PL?PndrP5^D6g*P&V6xUkhsmug#8#J+jiSu7otrJS4ohox88^vMf@kTn zvff8k)a-^y>&cC@_#!BH5xp0d<~( z?n8ftdHP)HvqUNJTYtO+<|c{PU*-h)qYjZWS65M8-XtfBfu~qWiEb^N`sL!TG}vgczR=lV@S{a_?^MdqqF^ ztUkJtMj|S7X9NF7C>O@iSQVK;j0VAe>rW`UWlV3{8cflVb5k489bV%=QDljjfl!iB z#Rxi7AnBY+mwPkzMGuyFbIF)6Ke^zPkX6{@)91aIZXt2+n@{i4K@-b4%H|TFrIo|= zg}j@5gc@_B0(BQ(Xc=>0Um=#pt66P5B0SRlx_nEm{{|K7QJHuQc(vfIy#TY{%T1e0 z1iXA|PDo1buy!^lR-C@`>N}6!Va6ewN1%gQ_PM^r!S-E_Gu2i7ye0Z!rRlf5nD#WUrWWjWr^2FK z_3{p{ZhK++1#*io!pg9KWI-ms$@M`Nbu?p5Dg3(xVoRSwDcg67_|baMq9a+QUT zjm%YK9uDli_J`!-B3n(D zAvmSmAz&qZLXm>3_LaJI@-HO8J0QeNgy@52C0;@)R(wejd>LLsaJP_@AgOa#UI!ci ze3Bh&D9C#5T~bPu{7jYUrZV|tc5cGOyuq;$o8CZ(j(%NYlnQR0Lu&E7oMhvZmOW&T z;5RbGIWp~RA9#g2ke6m9qh4v3)E^3#%xF%zAtvcn5OG(`XudDwgMF0q5waw`lufZ| z#^~o3+EBage-d!e))5$k+jN}!RHJ#kV}f(|)h1(lH{d+upB?CC#a(wcqt*zObz><^ zD9iJW-7ll#m>dPSy>F9eG|sGKRo_X_%>>JrcA8C@bCJn$rEyaHgi5Ie6Xz?_P|*CS zCB^#1NVG-VODGVBLXtoh%)^63(ig>p^n4P^wc+;B$*n3R=VzX3yVZ?1hbFE8<(Vzt zPA!ycr8AZDLgiCxzx~u6WY1|htm_JK(hISp$3nx2b|%O9#<#%_UZf2Ot#B&avvkko zPcxWK?Q-q#k-7aigk?u*2}6waY6YjpXPr<@VOE*Gp^+-fd87FsYA3f*yF5XniU zF=|os@%BhQ-e=`m*Gaf{U{DmKOrxon*?L0XhmZQuHJ*`2*uh<1`hDZhOlefT^QUi; z38jE**GsDX){FF+#iPsHA(@$Ifl+{`J0X6Wg(&^{PPMA_OoxwK-~}@;PmY05v)8=< zFVAl;etsWy6YsG0+Yzk$U0a07$yaU9BOK{Dp7z&YV!jd#h)M%c*5vN@Yy0C?-N%tuN@aTl+>IAnPgZx{|cd_C*aL4?!C#r_3vA` zX8|T{gWu0<8LAxU4lXxO zu1~Il8~pr5{KbKe9MIi;Tz^?f@#tKhPxh{x1+-k z$GfC;!HS~i~^uUKc z3r>^tD&A&V%E+~o2gg@;4ZintS7RjY2WOk7*Un8M-1h{F33?TsC6ne{Keqcaq1~#j z%F$}YT_0x6zOwt>&v4lYQqpk-h87 zDITS~>}`DvuU8z&C=NJ6JIK;hWm_Ssgax}KEh&AqbMQAeo0H!D_FFG^y6dUExaDuS zRT;`5xKFGFMvq?|;KrpWe%+op8%z@U5tgt?mHdz7MnprR#YDrnJ)aKSR!?*w5WWOc z^G3{iAqu*R=$J3)k&2&tAxdOYbF4grs}k>@x*ekqz^$LHcPzt;XjV`!gD3yB5-%qwRHu&V?1hpR_ZaU*DZzD@8Qx zk&+ZGs>{|FvBsilB(fiZ|R-CPvBEd9F28@(yESF!ml*k3MS1G4$$ zah$-Y{lo6TozLXMGSBya>-XjehN&I0A&1+j-S&&3lMF z&%Ct6jU^T>zM6B9LSBpUTixZI31gVgnAk8~WSycMBOzQNNCf4+%N!!6A01xc^n_*Xv-(=G`wXI?x&y?`0vD27jcF(H^aw7=<35(6OIFO6_4jC1`6~wsu}f(i)qrM zWlpXTpcqe$I5Z9^NZg8Aj7rHL&SWyl#Y~&^+VQg)IU6+CIPztvmTwcJb>U?i0Z~>+ zZ?S=3COeY>q}LEq3TehFeb16Gf~>B{q&^HS)zn}GUzrk=kcVY969yZgKXfLeiHJnS z#M{<*Azx?$obO#|U-Bui)1taq%drpvAp(m;Qz*h`xvGcrHr+N~;~ltrSl;iZD2o%P zenIQ`{&VB>%K7@Xp~c@oj00i}Ob54^58v!=_cQs0cG6ip)XNJ$@OQ8s#3^gAdnfpe#slmP^CO1ez zp-`%7!cQ*8ML}%62Tgq|(3_2nDANj&3jz`TW!C&24on*Q*WFc7v6DB1JWgEJ#5-L# ztpd#9$yY1qB6UmsiL8jsW)+N=XcRtB(&skhim^>W=OMO4g9?P?U2YH>e2qkm#32E+ z7jt_(B&hPgUqtW~XpEgmPBR;qlbL!b4{%gkocS%jBHI{1ZXh>M>ezT&Fx#2Mi<4#RJYf}PXfTQrq#V8s6g`NxeZy z{93Xk^#KFksG+@{^|y@4u_}$E8E)MCyY$=wBu84f zMywRWC`k6K9>(hgrO%RN@K5e_ZQ`t9Ae;XlQ^{uunImN>M9();s2PYD_|Rp>YsOD5 z3(MCTP(8&|Oz-z+tLx5!+~Ri!N|8m>92!O(1nhB3{q%K6N$PS+a_}!arr#xI_r5a^ za-G#{Sebs}=LD^EAjX*YSTyUjX<`eVBE$fRs?p}XTs=kKx7&uV2OYZ?Yi>S;M+_Tg z>&QC#HE0<6p+Ats-lytv+9NV9sxaib*{b2OZ$erg`P;z_Y%LjwIAz zm6$S%WsE6GO}WtD&Qojg7iV|+i120csBbS?OYj^S@d}Yn1io~bquc7kqz!-_q(6m* z!{%ZVfS{2@{u_%#@PYPey!zYCQN|a!i35za3(%dn%JB62$-0|QTKqR>x^=jbZx@KCQJd^6f`)#;I`cr@|!t)?JD< z?_@c>E5gn*>eeMUs+W^%badTJ^=kBsTMbh67Qg=-APkUn;ASbr4>oGHAU9Z4(pWDl zWXP9OM-*Vu5YDV*)L4ssT73K<$OUMazGPp_9$Yt^-e+Z_Cq-9VT^P9TB^FUH)Ltsq z?+a}t^LX1tvDvvEIdIJqcV_;)IC?&UfhT%IqIldyfgix@k|K(mRXZ+3fr}H#qbTv&$5Kx6_V0Y>pY8(ge0Z@9HX;se!2?NJbXNI1-~QzmYlT{~rB; z?c)K9!ombc6~;x#L!OZ^<$P0ia!cRAk>e|*yL@aQ%SoE^s!#YEn@XwbJ1ZroE-OZ! zY58=%wAybL4g*$GXF$W_E2eUNxLkcW8u*-&A(xUOSO2066Ag;>m=GPj8GtL)HCPMu zh6{=q64UXUufA|%xzY-b6!djOnrVE3 zr+vO$3258(3G+hH7)mw2SuH#s9Aw~_RIU@n3Rb3Q&b1pH`Fe%awV8b?ivU90?HKt|iFiL{+7(t-0lmuNRE`C{FUA!dAtE>by$xxx3 zwlj-liEr#TdmvHVM^WCpf3o3rlX~inrl9{gM2GIPUg)#~J>RuVhPe{|n6?N%d#vGq zftLUxfW1wKU7UfIqQ5{5Eo5VeZ)>q9P2?ZGq4MybPaV-zO_2R((yAnDI78w}uN{|0 zYLbMh2l90qSwW#rYP1ZvbTb=Yk(cf+zOVe{ot~aBbZ0RWqB{_u`39B7WS;ZB;@P*E zvb&v}1jA3q1w>?4BZA{2(J~aN zS}ra;P|=(%M5icpa0(-`$aa8uLY=i>@uSXLWZGm4p&yxM!@FhGcPH7VcO4%q=1|(AaBL`Pow;M~YQmy?kIyv6vH#-O6NrH8H7LuGt_W_N%uS zgdLc^eSd>Skq*&fc8?A1BT=@Cv1}QCE1`4-zBZG0Kn=t@{KYO=EMtm%Qp3oL3ibHp z1jQz{G`9?*o7V6;!?G5QKH`lbj8*sC)4NHWruMf(yhvD;qqMCnp&Enm3Z z=W;2q#Q!^qTZc}LNxEuUH9h6Iv?+Vf{5*(Co$IJDsY{?8AixcV@;xsqCD{-Ic%$aP zHaf{4gZqH=Tu74V6Y%Jr9h$rfC*0ybf+JOeWVNb?99_zgu&kwX-WqjB(sK-rQe-k$ zA(+sc!>cIhH4xgNH$a7EpX;%u+0N*2H;>3$r6++m9iykjOWw140$bs=IYFRO0;IX+ ziAdvB(Q77Nn^^Nr_dK{ll=zXp_%xtZy2x&&h+7?KrF>J*&UpcmAqO$7xbHa_>?Yck z4cRS z?U9k>rq5kEFu+WNzLlrOWJoRZC<{0rarx-j@SxIjdMFtmUYo(wUW}xCn<>{!8C^ByfFyaVbY z!<6~scJAI)BsB~kjYyxxUUpwheI$@CVJIt!Yi73FU#zV;}UmTF>24;ppYtZqAO7k(k{ zQd8zydm+V%;~sH_&YgpBs%u+HxMiW9oT6mv!Gs z^ed@!mCUk@UVVCJAoMNO!foR5ES8j{>`d6}%2#hm%4F17)`BZ}(?*T{9l1(ACo@n$ zR{GLI`+ZG*!#l!HcmdAo7x%yj!geT0&AhFcR_M^76~M;PYq*&?`U_iVQ{3#)bJKKT zmuz!XU~l53pdwnX$=okjuL0hYoDuQ7t!>FPOAt7n>7~RJVj?A_vUYYbSa?F$U1R}L zAlMBf8S=(74-k$@-pd0m1iy#aLMUc_+@-%BZOE0&nR!Y-#@R2S=bKjq5;G)~^%FC~ z)rB{7i;!B?;F>in@TZv# zTwG|rnmn*5F3y{@i5MQ?651{Bw0VDcJ@`|-RnwsWQzL?;{Ke}Uhs^emQN{w+r;8VE z2s~w8;Y|NbWj9lp+ZZT7ZjD`-FaxWa;8@S~{in<4*66ww39yOZ=yP$=hVA&(j8gk5 zCnQg~Cr%y|H7?*aH|#h!ZBVVG%krl&4~-S^3WO)Lu)2|BL2}}NK*}!}O3YX#&UFt3 zea4Wvgal2Nnn`mlh3Ho`%!30Aaursc-;2ymA}ZgQdWXrRp$&yTg`NA(O2=@S>FIy&xV0paXI^LheUXx5hNhW z0>{#lzMe`Z&Y!dev)?!5?NKU3gQd0#el6NDf;4McsF9f{?czcFl+2bn5NJe$S0;0N z%kwSuJ-;d{U9v>3>brCYrp0U-;Cwyvx&@2s5eUKN*i9%ecBsiMO&knZQli||l7DQM z^F5?wOEv4PTGwVvYgvU@Gv&SYwE0&CqwYOhx}x6u#DVp!>Gvex@UdUm{5ULZt4M6a z3umxIgQCqRjO?>>SgO26drV9Kvb;gV%HU@(Ce$;CUtn2T$(D}j!P7Yn^;E2Im|n@J zfQZpIc)f=D57l0x(!G=iDJCaL+13c#^7TB(j#67&J2dWJmnKy-v^m>pFyp3BYx*TqehzHaw|L|YF;b+=w&Ub=3! zDHfun(AWE=tcAQB;k&!I+6&Eso}cAdEZGyM9rDTqbE1MoPI)HO%C!`mM9<`uAG+bh z;iC>JfpM%*VnuIJ>8EM$zgekeCWcO%S@BaA1x!f*je`-6Qe!lv z%f+wnk8;(@Q+}>|@xG%1_BrGC^vnGfD}X85pEGab&G=7u?nMc=txUOh)E+x6aryi( z6Qwb3Yk~~DWFg!yXR%hXMB9D&L{84`_6_aBMCFB>aGO1f_V4qVk1h^t5Aw&EbLVvp zjKuHq%?%*CCSJbW%6OF(bF~Fz`{k_W*1B{ZyJVw$bR~_J{0qEWSrg_44%2l$*WHaaQ9Bv zv6DA@Td+t#*Qe}=gu!Inn)0xZyc94?vV&~e`FJk%Qfx$jw=6i@d9(a}%M$iS*S#go?T3dGxrYn5_`xyD5DOeD;PzCTj51^G%kLjqeAgNJ zNj)|uPL^aS_AG!s<*jvhX*x`2_`W0&HQ#@Ds$Le2(f@zQdh4htxUPK|K?z9_0ZBo+ zyF;X;rMtVkOQfU)1f;vAq&tW1?(Xi6-{F4l=lR~XzFGV+tbv(1wfD8JeeJWw%Nco@ z1;Jgt$-eF2;$E_SV=~J%CMcq zjg2%ZaXk?6{+C>gw_F64ij$6X1P!948*zh*bHwwpDD;eWH zOa#Wfe#HuUwEf8kP6H-lX=vios@VC0ktxyz3&)DoGOj}Nq$&1YZ*6m^#;h-$zfHrY^)H30s@7q_A?c}3Zd}4@Jwx&|K*BuH8AmWJs_KOT zydGbj0%$(D|fE^Co(6ooUSzA&{$H?iWjra(oRTwOAw(@3 z^y2%ycITwahRxyK=s)I&JolJ`9>e71+ul^b^tzlG-tRMuxp9T+PG~Wl@FZ(x22JBfiBy7iH{P3gYh|webpA@4m{*eN)OzcenAQrp0HuI=4)4 zQnR2*^okXgAaiN53pH4v*}5xgSo|g2mBqN2{$Iv?nhnD^*4f1&(kLNm6J+=5Y zHuh>@N%KIrpQLgP-fMqoe`pL`2Hf7JT_(U*Jsq#)B87&RJV9GW0e++SFEIeFH-A=c zSI?v)0#WHT1WHCqGb^^6Vo%7Io_Iyb$!*+(J_7p>Fb zSF^B*wz#Ch-5P%3k3?Lzfi7F+hzb~+e}M^(OL2h*eZBnmiZm?DNLiS1kG={+Q&ir# zrn`j(z9v5z$h#?J4s)Jm!oD*9Kjy^JWQ;7@XwLF}FghYbj_T&-j&N*#4D0Bp(!tWh zfI05pq-NK>j@2OmARq5@tu4Ckm@U|#I>~a`3|!eIsjSsLi)DM;=~8bn;^{8(XLSzHna{ zdwCbi$-!32@;JneugH4-*V0uCfcSW`s;wuD zl@u5@`T1dpQ|i@_Up=F2ol{Euxem?fCufmsQmaAz!X}4@nYHy180C?0P6{W(i^)7H z>g_vqu;7es1bnmnl9{lk;uDQ!E<*VicH05xW(5Mxw=1sy47ObU2e!(jIH_p6dzalo z8FJs=THw?1WsVfd!()g{dG23_g}Af%GB}sb?Q}=&K`b%3F1uL4m9XY9aDxbJ8Vmbg zc*zw?gw>8|22pH-LsQwSZ@#RGw&6w(961{I1L{X7vYIgTc>Mjq0#@txDHSU6*q?uR z+Mel(cW}S<_I@O5zFD7-l_H6$GJg=8i%~hO8luKf?FeXYK7%%1p7nu_iN|+Hd?~k;%0Fsu$=W9U)o;5yy5`+$HUt&2soUc%h zcO{VT$J%+3Y8~&-t_p69kH&2>cs0?*{!0yYEaVhQCPbQT%nk7hm>)rvcwg_t))&?l zP^8ACx;dPjct7s!@!YiViJ#g15Xl6sQO*vxu#Tw34kiuncOtw#bKun;+&rC@v%Bsu z6NuZD51Us)-QOvDNq^u7lg(XQd8kyt+|*~=MesM;#>Zb*4b@ZSr`R{kb*uam|{ZZwa7>p(XytKaL0Z?*V}?mk`&^?{F(0~M1-r0Hf;p{y!{+k+(wt4j|!yD z->)?BDW!{Wx$-UHNjBVNWTKU5x&pX`eJ~JfcZU#PeX?%pk2TFDw`;tUf;cHyEa!PR zrN56s6gXk0s-7Pomszx3ui>q{zagHHUrdEaXRg!_@dr)ltyaFxHQ9NuGPOZUWm<3b zLv*e(;ZiXF>sNV=Zs4gvFufhc0x-FTmFd>KR1gO}{{^<9uxm)O^V!zdq(q2w^F0Z_ z=MhFxW0~hud}bg=!&#?rMQSR~z>&vJB&5r{%o^K44WQEO0t(cSo^SlvdU}BN5XG9} zcKaRHFpAdfw6>8r&jxPdW@XR%YG(1G?mL{o71fTRU#{MKfWYKD1`Jf7kXDsm$J^8+u+l?qYtqX>0gh5^=;X>I2*f?whUf} zD;F5@NqD_KX+XeR>fY0A5FHe|=p|y!b;G`5XJ1$B^QS@qy!gk6*%&8*!?ifvrwk$d zXiivH3D&V%a>cWHV?8IAar<{#ruTMu-}QPg>*i)gHE(LX*~VGGUJ{48sJS*jusIy| zl?cg7?Sx(joJ?bX8ZLTN7az~@Xd55)Dd+$$uLo^DAZu4kmsgMHqWml1)D>4aLI1R1 z`dd!_>Zd^*vo$6jUmTk@}*4o}b6cMTEY1sxwZsR4=tD{&6nPIBIsP^IUV{BI-z zxhw{cmk#Pwy&J+J)5E!1P^Fl5n;z5glyy^I%k*^}4LL#9!K{Yml-X>=DQNh7l`r~i zdJ_pf2WL7lK?;NCY*~OMfus&L;DyQlek(t(l&}EZGx7wjnnqXc2xqDjL3H;z`+H8Y zO3X0;K7gCVb_A9=*P4OP(fh8m$TAUR7*Lxp@n%ffz(VjGc{rs|(oxERgra!k&tAOw zfHN=V3m)%#2KU0=>j_cg>x0}a5IG4Hu*PqN6J!{hIP@?YGAAa6fOq-9j<%ft5$^cf z7tp<(+%#oj!o>DvFGq9O0PR+ajf^)}?)$OctW>SP#*@!Oo#KX(0PN7f(RquUcFj6jK1dzc5rs5@j2g7=KI?K{zWY?@Z{kbMgKPA|WeHw&ZqeTU_CA+=t3X zgq;xN{KZ^)wzI<&cWO6j)UK1j+>_6;b`J0rn>tdjL>j{_+^KT+iccSJ!Z^3sm~l73 zZUR)Sh4VsyW5}Eh>(*ARdqeFMTg}v7>An5y(tBGT8s1B2khdKsA!WoxIa3DVM9*1V z^>~(?K*lPDl%89_KNF?38}rLC9h{I1VPEBM{x*_n>O4o?3G{*K1pu8te48 zN^(d}Ei)W6`mSf?>JIP4HYNewrTp&9_+ko>NQP{9Mm84Tz0Z{S$hJPT{V)-Dw@vu>1@xi;m?*)Ycg@Ga&d(c6T*TmiBRNkFiP~ zg4y|QLt|530JaD;mwLA5_aRG9T-*|I(t-6Ud(|2^l?m1Syv;QSft}5GQxQw_N~mQ z6Riw!g(jlXsMk4C#OY3q2ne>JTTKVqt89wO6Wh59hs~lem!_si1VNhR@H7gt1tMLl zkW<^bMgR@yU7rqv(Rb&#kFb}-ufo(lcZT`?7`<(NxF-f(ocxT8PG0$Xc--tpz5F?0 zbu@8!hE^Dk7bX%PA`&!6%Y#+8$i)6ME553BShpx)YsH3=8&ce=YxMCAV1bWP8$0~W zFWx1ht7_VFr%te+uCIXbD#0c2<4Y(&#yp$F$5g_nsJB~mfU+AT^jv%8bvzpP4;L@~ z?g))N88GL*tT7&HOF#PRUFm8hmdsoyGp#F^z4#L+I;yHOLaB@JLn2`Q;pM*q`l?uk zE9^?`ygqiWOMPg_H50^s-^UKrr);%(@_tdJcyGfOfhx1J8-FQh6pQREON|s4Ph({} zY05X91lkprnA=aOS(TzpkBv$wI*TL*|QZ8;VU=H$z;kqgy~wptiKO4Xf8f^oYdWQY*- zE;~DOt|<}WKu=FE3Yn5lT77z)o4T%FYLL-4Mukm|jU({>@uy-OS+#j10U^*jvDmDC zr)>{4D&DNUp=~2^a|w7Dbvx(>X>{F(sWuH3aqw>tPSw4t(1g{`fXc(RubZ@dpBPi2 z$%s4SLr}JNGxHqjKJ{F)sX3 z;FNjHb>;dEAf7_7avuAJyo862w;%pUx7`AF%pxX+u~odp`02;Q@09rT;@afqdx-jT z91f&gL-_9Bo*uZD*5fnb%2a7iP;AG#CCk&N%uM#T!<{K`Ki?`bUd>gjAyS9Yf_%5x z-}oH$Tak;in9Iw>sCj!}Nn_4W&~NOuicLU=@<9TSeptirP3ZlrE+$cCbLz2RDK8v? zn`IfQdUUieK1fO0HoX>7HSpbrqiuP5)YCX~u+|YZoPmkawae1wQtd3N<0R%#f|_@6 zz9a_ET8X(zN7dHmHgYX<`$fpN)a~t6 z7k|pa&tE*WG4}*u^^phBL-7Sa+kd$nG;;y`BPgY|w24(jvdeRS>XS_NrTQ)R9OJk} zTm1MCsIr~PxV_||!4jHMSLT(uTqL9BHD($DPtELP8=EMZO)-}{WX0^s8Y$vN9 zQSEF*-w{r+{*2X2=OB+}m+`JDXm&0Hk`=Js>jFh=Ts?skiw5Ma2pJi>!9%S6E#hIt z)hl0+mk8y;UwlW?{DB((o6pEey_Uw8Ul-ccO*&|6Qsi4x2@sPsa}$GwN3V>is=dM0 z8K(t{+JisUfV7LY^ciaHuHAdFU2o{7~@J}l-sY@pphv~B62Q#%C z$cF`!M+DYEgTf#aky@vaD^=HCuaBg5fPZBl&F2JH?(KGiHSq5BvoZvF-u|{KY`O`T zl6s;u%l#oImC#;V_E$2IKTQPbDe_(G$J3lgAt#ta^p{It9(kw-l3<4t zeaK?$p%+x|nVq%!L8`}tYl_$Lhf=;dciPLFe>|LjJz>b>#g$fP3VI?LJy z91J#|YwLlxd$~N|*q(;pfbf3@pCH7U<1@|N=gLv-r2F5^*E_h+EOJ$YAHUa)aMRfa zeOY-HeC6(-<+&3J--c2D&g${tu1nxwKnqlkt6dgN&f4i0QuMbICN$~mp|-?KqCh#t zVn#ZQUAb326i@ue*P&!ecNPEDD|WUlGTW1`j>{?LOW}5cAA^;gN$Ca%$_%uVqUO!5 zh$`!HOOjDXk%~&_SD1_1V%tr^?J&aUoSObygX|oOY5RyW)=*-gt#ntj zs;~ZSc%O#A`&;}BgZI;7V1NJMX;CggyTyDRvkXaMD2V-D6jwQ02hXHcWs)fV%Ji3h zTv#h=IIV=$%EQ?x*TP-$w#RzfPsWk1$dw?@{~rgSD<5V>zCb`%?QlFV2x>*US%^;T zK;)c6fU51eE&zz(5mOex^`nd{9CtseNhcN6AMGMyCCvT~6LJAmS{BBko0>B9$BsS@`7SF<=bA{F|E8Gb)aXPg%QoL;?9`57|f8_dC;31LtA$U$j6o z?KX>XdlTb#KnKMZ;%^*5(6IL_3Gm81wkGu84}q==NFo9KVGGD&ue%#aeQ_bszvN8; z_txc{>Kz60AvW2SzEk|y4yqH(?0R>_>@ji>i3nalcC>XniMu*lV}rIHQLH`J!)+pz zNrmD$yN=oEUCXKO8x@2AKmdUd5T=5r?LGn}AH}jWD9EFIoy9;|&mOD}utdm~$st44 z4p(mz;tj#CAf-B4DRxsDYgkTnmd+UhD})-?$E`3S|DRsK4&p=4l{adbTH~Lq$5US!Kzlrw4G}h6??+AX)!K!DsajcjT;`TYvEIX7 zKU#V?4(|hj+I^R@mu;7!;=7HrQ~3xw*F&I|!AelGR%dHTy+4kbOBpk-#9OKk+0F2v zA^Qk6V`wP%O~VS8rf<8m=HOl~->pO^D5kM;OoaAX#RK}F2 zz*slTl2=TU(KUhvJ6^;$d}f9Lh#?0SJVC70X2H?0dZGR^HmVXG0P4=WcF}t zUB&O=VxpezudHcmRW2t)!~f>~{q=NvroHyt zj+U=k>8|t6nEvGE{?`u>Qmx&Y9L@}OOJ6gb>@d$NY+_PzG|GWvS7WtPriKn zt=a3W+GFF|7qB$4R2U$Z%lKq2!_V*jbRN8_)>F55pz2yczIb`X%Ueg@lIlyJ8ro|=0xqffnM>L}sZz8KZiS2Jx!R9fm%4;ga(2tgN%kdxPFp|(!FZ!_~qOa>I2 zx(u&~NJ0!M;BVV5lmK;if?_W9W$yQH%e99Td9|Kt{i4C#%Ja)5`?>k~V)y$OTHGgZ zWcW%`fz}m691@UXuYSC~^6=bs`{}Z;8ap|uj@GN@s>z|bE79H3x4yAybZwxqvx*yF zqt3ToaUC~c7a?(UTF*5(-}113tQ3a;o`lCuhg~onK?_W14u5Wq;`Dhr9(B_CNfbh` z=~L8*(^Q#|>X>g?mqogvfRMYXZ`px=%E zWP2Uwgo}%;h~DoHX+0P=2+lYFvfJaVCy){M{C<4_6&r7^Mkpg{-lFMpn-M6wk^pO{ zCy%>gW6&N;k1onHM`z04;bc(x+jZ5a5fH&ynchFNlOOM!3g00_b_3@0Cf*68p5@fF z`sX!%0nmgq%e{j;lhC8!ocWc)IYm=wJz=zYZOsm+mBU0{-p>k|oS1>t8)R9p34>|s*e(fa6RmtYCol+*C z#{92Gz_pSmi-rcr-RrD}6C}rv+fLf=Px`d8i?fqu=(MBF6cWdq3hby}+qpiB=Z?q5 zq)nOCF3!9?DiwkThIt$V>lg%IjJQZ1N=x13%Eb`N*=7K%2(@b3Kt%(}(VtZyY~yM0 zW|z`z1c|U*>kgurzf~Vh>;0xVfHas}Ja}4L@mW}#87<#nyUSeceEH=aRvE3-Q2*Dd zd1=7mfiwe(g7P!Z56J1n$;D@AHnPZGL)%0M^e|(r9Q`2?cpDK-H#`?b;Or_y(4zs} zpPoN@t#wRyS<$$WdRzk%w+z9e3=oLNsdI7I9-^nm&$t9urfU!og52kOLQS*f<3Te5 z?$S7Nl*7#I>eSmRI>7u_3A;CIT2>wXK_eCcs@&Mr_QPN~FcS#R%88w2km}bU&~9j- zs}i^LBA`xQPXA2aGpnlBDb=8s+Sj#US|gZv85RF8I)pDHW7}Z4s+KEM#4E^OPv_;9 z%~u$&tgt^+L$pdw`Z*(csTgw>6BxmO6$S*lE@$V)NDs;Rd}i=xoD9!677T_3l_a0vgZ0o?qhQmkE8RRYK_-A+nNPqC8BC*MEMv4p;u z4Cjt1kk1!8UyTBR!11*~L;G8Ek~g!@)G$&R1is zETEV-$oYpJGO67hg`Wx)K#(B#+s%NcdVMx*8num2klEB2ol~s!Px{eTy;lao?oUh4 zN61@)c)|1fbB{&iH3emyOg>96y#LYleyjblU&u6pJl!^}AgR5Q6+l!#u|MmMi=2Pj z2uWukmdyZRUU_}S@8oO#BBe!g0U zPt~Xuc~*G|N~kE62jP?YE4+L6GcmFgXo!}Mu@?k^>@$pkY2_ELjUSp`GKd#JIRQ{y z0^O$=m}Ik`=ffrST+quuBXEZZov-zz3Q(V4HL3&uPpU$P_}RG;c9<7h^Ax&)H{ zt3m!ul13XVS@#KSeNBy)lwdjW)4vD<{a|oXg6ixr`r*%issbvuf)>CREv6u)g|tnt zkLx+oKAk%>w5tONJkGmUwZArvqob|hbWAM154P%poGLaRZX5|5QAbtAlo@5ufSTk7 zDYp1$;?&&6Z_tNG%^l95z>Mh77wEJ($U_$1kt$$er3nd`FFk88O^$HqM;}l?R1zNb z`BE`X_IHdAJ%f~|I^2b&=07-A2A&aACVT~_b+MO;>a{&W;1(!;YtPPc0>V_Fjn2_y z!~q)gFj7`SW8LvRpxZe|3Zo;73zreQ14A#&{z?HH@zN+F5F=H#YQK{jKjGz5nHEHBt7=H8pIEH=l*O-(n>_;(x~-w#tNQXP{q%7i64) zvY6=OMDW;JdZqKv%O(MEwtn=BLF9hLv zl#L`M3Y%J?WV><#NG3Vd&%nSn_*}mcKK&%;F9Tl|18P&izeOkNk^|*oKMOS!NVam_ z1@2&D8+8)}U3~rnmn`D=rcEhRNxx5j2c<&Zy zO|lCL<6HvkEVJJmaYXU6YWs}$IjBIg(=qrC%WPdK{Ew4BI^%!NDzSs@3t6LT)k0@@ z6fuaVd%jenC&Xu)+x!M|ItvHNMqy4+WPeyviWTLMu!lSgbP?^u*xm!)1c>TJN5^DD zpV0o1Gu9FT7=^KA7#Wu$qLqUW${bm64BHNjY#hG7=;8nbEhu4&G5{iZ3}D&-Wy2mN zIyMHxa6+5JNZd(C;WESQ-Y=xlxBRD7oXnZrsrsfhl|q3m*t$aiY(=RBPrpa+%R?HG zVj3CLJLk2|1^p!^W;@boiFZ8(#D#^0aq)*KiepSPp)cW?vBL~n0v<>jXOE-Pv6`pp z-AYsMby|k8(f_o<$ELl1U+(01<#6GEWlnD;##G%M>e=Wnq`^Or+bS6){8xqKW84v( zfv|yr!MK>nW*Enn$JW!;y(;Qa_M4Y4_9P57RJ9?H2}2SGhRrA3aD^h?zc1nAyuo=MEjG6gEVvfrX) zF;Gwy?w44_;l(kiH1DkNIMmi;g>dMWUU zEWX8q&$m_s#r}q7^YlH&s3~Y(D!tUuZATkAa`IOGkIk$z(h{JY4DAWV2da5{bZdH{M+db`OC-qt^v|fFItykhQFmJ#uL8 zbHciCiqrJ^u{|BqC5*vric$W)f8#HO(b(@k!$>L85Ae{pIlM*l{jUc_MJZQSx%&=G zzm1;?H#A2>B969>TeWZ=f4utwS`a-yno{KP$aue?3nyu+wZubS{h|Byl@1f_?Mtwx z^Gk(#<#LcsFXS+3=Se|Qu2>`~$nHI!QlGtwCWUVLPfPCc)59+bEJ?hQU1Vv(M$Rshc?5YV3c^z!H~VXP`;w z)8k8R*WmM&V?zYpzhAzXec%J@QZRr?6^7|#hOG3BoQsS_xHaa2wZTyrpZZK#r8q>! zYN=hcn!Qxsvfs^xUXv}p#lO-piE>E4hzCwkam5X6j=~yk1b(WE&LEU&bWi-c0v$(P z6k|-R(yFg*9(-_6d6itU)XSdpGmD0ZcOU7J8A?@Xbof$*DdWJ809~>lc8D(COA|-; zyeh7|YVJH%?!3x56Q{d*a9^ybv<8N3f6ns{7Y2?LF&R8|SeJ>DTVCaCUS&J-Tzw@O zI~N|2Jp$GeAKC|SSEg4}bnEl<_lYOa?*BXaS`-0dgc9LhWncSs4f&9ois)Y-cVW{&gcBd67Vz`KvEYqdQZBDovw5^S2lb)NV3e)uq{p-aQ|er+sH8 zFDJ@lePD>EDGdhVPoXzZ!|b%J<7$@Rr0lb*9ecnE{gD3d07>$_{;w9GttFe8y5@4$l?KCZ z`&`PyZi|ku#uhhB+Iq6xo%C-$$z&X6n~jDm%8n2*6261`N>b_Mr|gjq>B^n~Ziiip zzkW9!myxxpXqJNu0C9FozjCI&E4475Y|kzc3x)g?#~!;1$ku?(-ew{g;I^C+te+As zoDyxE5GYy@08a|%0@unyVBa+2oz(oudc3YR=ZgO%iN=5e?QjPJMmV0aHnwiZvF=`z zX~eg(sxJHOT+Z}c6K>bi0n?}d+!-u%e#$6$E7_rfw4qnQAqOV3KmGT>r%=eU8{cJS zfx7zznOPCaZZe7>hQli4<%?Q}*We4C-Qe{?@Ou5BqXJ-|Os?Sa#uKLt*=0>x${Mw| zR!6AGI`t?F2_Wv_x156Z1GZ!eL+DV7V~==;e)h3U}Il%cB~OMtf1Y6kvZ+rDwrWFsDmZP zzy32SO754Q4{QTtT%V3D9a1>vsIHBJ&dhWX``3KdGIeV`^XAuc8}mmMX!^v#Gsh45 zbTOalVua|Dg}@W8bV0PXmIzaBlM6SKi(9b!O`Pw*2)0pZ&ZR;WrGmC4Ai{4b+domI ze~f0y(3c`^=qJ(5Tj4CWMN6AvZ%1=4iBMwa*<`8Xecphv{B18^s0<}sPujs9(K*}D z8E0&DoP@lF$@=GhL?NLP%=WAyTDsuhea7uSO^G7>^-%0I z5VgV(w|ba4M`K=xj1m$8EZP1n+3qaaUT_`*Xwy&QNjg-n?-qf{G-Z*^_ir6(bc+rN z6iv$M?#><4ZDH~J@F`YWAToRB0X7z&?)ZY%;nvdu4ii`%F3-0Mt>1>2N8Vt*eF^+y zya9TA)*DZfpKM45atH=d2;C>w=a0N&pUcNWK4)sOxPwux5aSgdyczNP0Iw2Hzq;#h z@3J=k{)-&mmDAPnN)fV$m-E@UWkCqSXBK)Iow8q|wZFSO_z)S%^zdG8pTp)=&E{3t zj~K!Mqn=L5_18fvS;;9;%ZPbwz$Eq{Z4_QGv%V76$sE~=E}i}zmN57Z>zOvDZ211o zqX-7kJ*L9)ANF%bm}woP-Y)p~AGQdUSZA0gY@fqntFYCZp(TF;_IPwSQkvwa^!68A zE;%uncp>O~zwip(59#J(cc`M7d3(~R16JN@4>b#W=?l!9&b%Vy*Vt3NnjYr)zRq!T zU#JBYZmGPgVp@ls{$4l4zC^wI?`q++XVEK2qWzR2mF*Swsh7loXy8C3VgF(Tu)AA;9hc%gVylSSr4h{-NU=5xmTp`hKB*6?w$YN5WpOt@(Ba^Va1MfCEteZzQDz+BceAZ-| zj;ly}n1Jc_P--tt|2qEc{^lfBDZs_J46G#Ab*CIw0Y{t2T+2{3vx_&kFE_3Jq#((E zuJh*Fz$WuFWD7e9QTt&G()oc@hM(h(2J%5LD~F{N8_;2+YDkD zkz%AjrAaa_r&m@}(+j_lqcgC)LXhG<=Z#$>K#3QL%K;s4+fn;$bvWr@EFH`!|GpHI z2g7qv^e1?rB@LsXDcJjhLlqV9V&~Jl+z}Ut<)dB!Yn=>Z)oqlv;I;z-YR)$!ea0qK ziyY3d)+yW}*|pFXQ|(w+Y$rX*0DaYW>7zk0Vj>FW%pe8VBAw>1%g>dw)$=;Qp%$DY z(}W!L?Bp9z@)d2zG9ejcDz)4=)aZVd$ADTnQqNryEyPuH**pJg>G;*WdW8M`WcrMI zmYyyK3#-CAN7$uxtTL3dVHrSD|g>9*qM>Ip+luKAZ;oYA0{QFQ?d z3IiYW_r8#$28L@4i5lxj3-%RxVQ3v*j2xn>wEAknGm^CpV`P!Xpof)03sV6*V)}*D zfrJIQE=QXBt7J_I>R6es8Xe7)k6}H7CRUE23`}m$L7Oe_bP8hE*|ocbXgIONSHo8c z#Da)@_*cgfvFxC0P3O8R9WuT4&1%JoBRl4@%2<279W^ez>_GUyjN*cSy z!RVFpV3DqC@yo6=8+&`WRLl9Uq5=GXmjr^5*`|A29$fg2ui^P+a5~Q)*2>6xWKHT;}z3sQ(Txcm(Mvmarxan4!Z`-$g#5u>D zsUorIaa-M)mHBa7PmU(It`nC-aN(s?WI6>Ci)sLI-?77 z+7z(WbBIP#OhLzOaAaQF$XMCe*j{4#%}gIm%v)u-G@dv=rJut!G*$9>5x z`{~!`aQ|6z;*9q?zt6ivLi8|DLJP!kWc%m^MSJ1fec|R_ywLS$8gt4eKl-!nrt)ey zSqZvgfg*In?N6JH5a{0xz8U3f7E%oo7KK+L6@5!T+C&kgeACT;t_5NVNOlR(t9?0) z$8^gH19c85rv8>0l5dN*hPHD*y75TK>X<~^BqM3c>TZv072we6n7l?$K+%*ZxM_rg z@@DzIRs(wEhVKb?v0;U8$c|BJHdWuS z!ux`ZPtomZ+awG)Uc3#d$6vqTK+(+k>~NJ@piX8{m8|(yiz1G1uGg)#7^D68A^lBq zv}Mm+x75MV3ndoBc$aj14YfY?_3lZ5Jifm_2o6P9#x43r3aSAGy~FQZ>v}qVup#0k;8ebx%sp!p96B?> z7`%dA(I}ZCOv4>`;DUME=z}n~ai@{tyP5$n6_ZZgTY>v6-Ap$IV*1VM?+cow5IzlE z+qRPi2A$p75krFVf#8)0tMGSp&qt0b+(G&F;|g5GBVM!uK9`-kQv8S)vI*k(f(?zs$a7Ql zPLV$Yr}s^OIS;vVW~!O_^3D40-vA>VCO}Na@Arq6VMXj+pO$n2SQPS@r?y@s90w_G zg>1XF3y6gY2=@BDaeww~7?1IpH2@Z@+$BW*L18mq-FEp^!!K2Ey4&l9g;zs!nr)zlB8W7sEm$epf zz|=k^ORuJInIX(sHAF((OZL{q((=7BeF^|-fhr<$KepdtEsu zg!VG;?@QIFw%TQbkK!!s3Yo*bQn`}?Tq#*Xafa)tLLN7@NJHn~hsYCd!VcU%X#}gh( zyS;e|e}@fA=w=4$W`6NjJ0bGQjbNyV{&hQ%$l4noZ@&>2q@gQD0yrB_LIH;G&BCOJ zCMs|g(V&DQi9UFQf%rR^CB8nuUW&3#frK)tL}UwnZEOl1!IrVE_{&crgp-=<>E1NB z87pjqDqhs$E&oI_a-U6@)cUcTUEhJKs3FN~ zrv+9rR^f}cT5-b}aKbX)&aJd%ynR&?09QaiZB+wx`9(P3!?y>&w~Jup*Ai-{`7#`> zI4KRDXnDzgQEeq+X!?vDde8=x4VHGN%Ar9cL-e2I+g`Q1U`V<}t(aiYR`9`Z6QB_K z*WaK9MB)wkZ@86ORMC;SMe2QrQjE-e^$9_a2g%z!x_}_+B_}~DEQ|pqifU9&E0k)2 z-y6~nziD|adlVeF7aBud9N6t=_auHU7zmXwVU3JjF_-ks&lJ4 zcy!2zCy$+k!niy}Q@=xm3y+W?7D*rM0!j);L3siilI|$5y^&-j+ft#>-s-_UrmmbQ zeFMvbieHi{>~fDU98wa^U{k}f7ZG5i>3!?AamTlBQr^Krv*sqtVf3=gUUeq^$M&m) zK4V)$Ph{oEp|qc3>0`Ld(e+m+JIU@Kek~_h3<4p}cEW2-*&JMZ7FG+#Ldum*JWD(G zaYiDKlJoPMv^Ce`%qi6_WNmixBX6>jK8|C8&I`}buC;C6!SbP3?Ok5y3IW)b46b;x z7=-yY{I2xmU2ABl?Ih z1C2OVmWOH9YNd^EFSPoc-ro{)rIWoF6I<4h|Fv@>teCY!W@v~bhm~2o?W3d1LLb%z z$@{!fUL6D~`yDdQY%YED^S1(9$B&x=Ve;U%veqcFxEMLFu1Zf_kgh1t27-FX2FP6} zYbl{9{(9sEp9yJ%3UD2BrHQ1=K%o)d&bHP*8jR_2gdf-XeUKc2^NKlx{#0Yy5;6Gh zwp~}HY!a1vvaX4Lq5lZE9T~4(*M*?PHgn)1v*&_{#~b67=*_GEy|y_1>c9;_@xayb zp&c&gfM{3bu>fhi650=+^;%N`)Lw{kt+5 z^0-tr68wnu%L1t)g#-e85miy!cGG=*TsA&!+x?w}*SW1h4dEx9XCM+*+wT{@KO1Yzdk@ z6kqkFLyo>f{0=3CPSn{Uc%=Kw#CNbYjI$}XX#%Xq`hLU`E?1}K*Nc_xz+K$mm*ZZKz@;+0 z6cQS;M5jr{V_#!@gCGb|$C^CpynX)?{&-{n8StH-BiqB=%oN_K^4icO_p83Zdp!w* z%BBhvVMUUZbm#utWBDXyz0d;NW3qOqed~c>-pfUB!vF_F($`q&vJl%?(_>D4yOk4VhvSwe$-o&r98^t_wH)SHCqP; zET0MPuNUSSYd=5(O1C!-imlZp4dF)(jtFbE->&#?p!pxJ?Fl4)Z0E0*L1Bf!cx28) zxHsqqHzkp}p!o{Po}p~>pRBTp5hGs7e{rmvAvRg|+i%Zpra@QdXxeBNo1K0tx@1jA zuLnZ=2z+(5)5%RE?R-P?KnoJS`E#@0Go2s5ex!7Hv_U59u%ZJL!e5>Hg5I^xonO(#8?NGwv&xKj%5L z=jVhn#}Y5lf>IC#vxUxS9Hb!C^v#$7UqtmAo_3G}z5vQ=!vXdAHhnHBaz_4lA%B^?B`ERmM)-KYuiQF;w}$8>kIj6`2KDH(`tUM zE$ogPrhBlvyyZpsO8-ry6Nd4x`h!)PQP zt(w&aUi=ASd^vBvcU>CQcJaW%w;-d(foa66@b83j+5MjhB@RY_j@=3YnVnDxW93Mh zTpcbHz}T;rhyAmrHY^Dj3_&UH!H8c%1r)5RE4QKT*zmLs@#}&qCisEyV$g_IgZ9eC zvMGf6%(FxP#U)&C#VLjQ)Z6E=f%z;44Hl)Lp4%0J$F?q_KaZBWdYid9wF<@h@{Qp9 zO!0E(1MU3mtj|VGIRWtqGZ^Z&1CzqLX1fcfriaeG;{d_?_4c9Ta+#)Y{CIG@8rO#ctdDoRZBHi5$(j_2W(jeVP3kXOZknZk~Mv(3nB%}otq@|^$L`u5b7H_P6k?pycjD8z2?M0r?fN&=JD8opw;aNn3V=oT>P`U9Bc zn8p~Z^26NTq<^vXfICKLS3(knvb|tE@>c`dCbmd9jejVljc)kDN$?e3?RS7|*@Y+7K{E7$^zj{FDE>IK zz`T3AXe7@ECfPcnKqeQw9FV&xCGsTc<0v4dR>)dw=dPv|F+e8G)X9_Rmuuaz$aiV? ztsVsl*yug|J(8p(SMPuHaHKy;k=DW69CJMx-@(NS#!)cZy)a-_5BJ;rO!ss1tnu#~ zGDbi)E#>I3P7_O$b1;gdvOED>4U8E}1K$u!z6h!c{Z3x`jK{{GsDq{dZVCaors#hf zpyA%|VpE(lWXUzMyoC`6KvlJxSpIy*5&PzA)7!^?qCxdMDepgB%Z~skh4(ooQykVC z8ePx82wLpq2xI%h(Ql9%KB?Ix`(~@fTHSctt-k}M{C6PBB-P+(U{8Rs2Oh27FRF=D zvh$r4Xl|(0=$M-mf&z9vU`3 ze;S(>`nO0S!^mrmFm)skjBC9*cRM_%yIwo*Jzb2LB{(=$g4$T_V-Bt=-i{6~ zX~JaB(yfyv|R=XYlh+WXVvfLC0p_YvGk1ZRK@Ac}!g zYwhAwk+77XuZJyZ)+AQL82g?MOW2hk=ho66Z-qGk`R{7e1CWy4@RPAuapY0{{j$V$ ziXKS-cmG-K+1X}$A)g6}d~6T_1@oO)*GYk1X_P(}n63dbj7fO`3 ziu|I>m@ltMzxyAlq5|tG`FCBFs2-E`{_?caZG>jWNx}rizZ9+WpVB6I`~F(SJ`^$5_Xa! zPFWH*s61Vakb>oXfymA5HqrIR%u(^@{2!S{1@+LQ?)w>0o%s(XLRQ=w-s^Suyu5$n za;&@y#blq7WP<=RL|WwEhdv%mHN<-=VU6NvXg6O|ainYgzRNePto?e^dn;`Cr=# zodLELxm$3e@8FhSpzDTK!rbMkZ?mJ}&{h-Uk;n)t>jBD#`rs__F%#CT?#gE^{=7q3 zPg=%1Vnohgg9X*1DLre5<#k{^cP(cZl_NF5L73VuX&B=KQsc+=Le|Fl(cVz}Z><2{ z{t39k@t@@jMFY3)blVUy9nhAsB|6j#q8q3I0K!JgdI}VMC%kb5#_6P1M!?*A5hU`V zsspQ>r{mUki{%FvD%P*|SI|W|q~GtW&*SpeS<-!ogI{YB|(q zwr>~srANW-)I(8vZM6Pc`9sJ5u7Tv!WJTIrTQMH=7;rR1`-YcLL#E~{jjbz#2d;q9 zmJmdPRWAg}qZAIR;cdr*8v4S`;kwNcZP(o)r$2Y-fW>EvrHiuXv3`Op&63fds;xAO z0r%EizF~~JfIMpwd!u<@2R-%gD&YK|RcLLpVGJ7&!qQw{xA)GEgi^uy@O^xi8#d5V z<-WP*joU@pm4CPjc3|a&a8@^Z>pmW9mcf&{@s5SdU({gZpZUsmj~oQCbGx(Jwj5yI_=<{j}*_dy&PZ@c^>+D^LS*lGda9-WFe%^4-3{d*Tk(Nl-zSg z5s-&EmFoP+4Q>c{d0!Dw(YpI*>=@Io7(KGBUS{}fb&EUxV|6iG+)J2EtJT{9p@<2Y zwrp^Sk_?}t%J%03(bTt6W9zo?IbH0o5lg^cAOx}Ob91+fKrj^QZ9wBv7fkN8hxqc_ zLgrCbX!Pq83?q)!MVrA+ckpN8<8(&QYkoM0`U4~$UH+Z=$PHDCZk4}A13ThBMuRG? zC56JMH8!F%--)l54_!iogD3_NfvO2L*jn_aL(Bz$(`Ye4NgOS$0oa9d3#}G`>#HEnI;#3BM;nR% zjVwc>3+{v%I9njcRmz{lFm8!KV3Df;>1V`z!pa@|GlR@xov zSWoyeL*{hv>3P(#n>87B+w-Lz*>BRC6uo}-8Yp7xt8I|HZK{X&!h)ot%$zyn^E6*V zT~$(b?6@aH6vSEY^H*N#^-7Jk&(%lE8Qwp!!}u#0xxXis^`S08#MAnu_@sGqVxR50 zD^ZL6&#t+XnJ9cTc^I>Lrb@v6hOJ{*9VLWXod^}I6yS(-yVUvlnGd-)9AW_t7_xTG z4m9*xXPijxo0_RyX1m#;w)v_4T!=X*nT`^@I<4A))oxjTz7vE;ax=lq(HtbmMTcnb zi`(Y7hie)?|ACYM27n9n0)>Uf;FA1ij~e0W#s_Y&Mj|5GJ#9Ch*W;*n_Zx?{)_d{? zB{FC?)hLT|BmgcM0Ap+>UrZHGRIAyVRL=W~m>i8J_-CuSYnCF@UiJt~+JmrI??U6U zd%-KTS-_)~3~vM(JLbN&!ehQ**;W59hh<>xRZZ<}RueaX6r|coSIzokAJaEUl>B?#m4v4#x1CTjzb2H;11Dc01 z*h0r_UswIWt+S$f-8+L2ynV&5(3=W`?y=z0qQlW?jSn7YRM$sY*WFwXaI9Qzvs{o3 z@6r1lCD6~?fk!M{uFV3qjw!!lyuMtYbg+AMgBumU(ak_arpd)K!HK6?%cD8Qlf-2l zaZUj_hG*oN)g>U?-e_1DRoP@Bc<^*a?yvWgJfs5lxK~~2VBhCzWh=(kSp*I4a#uvJ zD{GFm_1y2zD=^_>!{O9yGU)S%IC8|8(4mT90IJxnLf2_M0bH$@EuY^mar`RFRu#k8 zWAnawrPBA@-oqN-=djQxY$RpqK;>wlAAcXc^~4qqay?Fd#W8c$L4BfQz_7%-;6-fF zrxJR2wbh^nV1wxTK*5hM=upBdp4*h=*<^gy14I%?h~8H_7jBzZ+&1q}_$2C!=>OV1 z9e|KVSKq9@YHi=j7dAn^FDGpZ<8ykWZ`yzNJ2`3!iRR2nNZN1Mvi18+8`T3Vihq;t zJZ`g5kn+m4gt<3IP%Li7<^HtF9tAkZ{)4uIEr_oJ#^S^p&-H-MwKZUX=%A&Ot!z&Y zu8?1!SBgT|$zt{aXY=y2p-7QZ6S$$-uH}L!X$=X)^ov72*Dx+6QPZd?ppmK%gUO1x z-|7JqA#o`ovb7E|;rIi{;T+%2E2xdjJFD)I3sTYo`a#$4f23Pd(l8j9@*Z#3)@YyW z?Tb)Ebnl>EKVQS0f_=7|U!5q@Qg^>89YuivIAgcD4YyYNFMUj>GZK(y`PrHl&a}U5 z2?I7QQTHCWJJ|ixAwdjsV(Y6bwafQ68@su&vebBW?1VAB4b_bSJ{MUxNT%>XF_BDL z7JD9TS6&DZy6xvZV!l2{(ms*;{6P!n6OWh^!;NpZXsUSJg8x~L|Bmrvq$pMkx}}i^ ziBh(PA6>M(82CzZ&E>hs9^c6f0C%*yfqs}Gx`p0coK#3elAc}88Fug999P2l`vwesbrlR=ZDLo)1+IHftL+pc z(cMY2D^HEF&_nw(pSGf&b{K4~H6d}6AS_0G;Q~3s)DO$C35TmO=zfr;_=yTk* z8-cdtsdWT|tU{kFpgsUMsdP1irUCQ}sVQVUGHNw43VbGlZ{DFkA-M;rUV5asdZeU! z2Drd4>e)smO8s-pI2hhoSw|S5tdj(9$POj^t_i0c`+jC*Y23i=IQd-5WSKVlwx8q9ku>C0(%aOMbdSJkL$d|9d zjBnAhg$oan_9geckf;DiWjPBlC~Sc=@C@`_^@pWa#7vv)+)b}tFtA}GVPTxrdc2=@ ztk=O^A8KOGlA^wv<+m}+INJL=;n3%|!ao6ueVxSJZ$nK#Vk}nf*0lUVw_CKq41F#> z<3oJ&vW=^?Lm5-n_6L~oan#|fktmNj7xw)@}>Bhqw@$luaYN=!j& z4TSeBP@tTh|15<|9|4w~1ldxXv!0*mmY3Uh!TmyIVSF*Vf$;89dJxiY7y~%5dM(=I zbQ;_uu5H~(7T(aB3_|X^aDM}5Bc11E%4~zfjTmjW!YIPMf^I=P`TLhW&698YIDt67 zsEq>12#66q2IxwncrHgaf@0(`;BGM=*PAgmc9Pc9UJ(AobSQ)G9@|>4v>;h%w_MwtJ~r#PX-2@#f?K8iW#!lT47bsY<*VvR8xUuR z=VLzO&pfH?iIu0_@7nzku-oc}c(d8NOHR};d(d;XN8(F>%!Cph00Bh=z_-Km;1;Dr zfc4%xPA7 zzpuQ7<{oHGhRiw}Zn$o2cr^5FfYO3zU$^5-Fja6{;XSr!0GO0>H_ah3MQJMD7u$P% z1M}BLVhSbt_V4~uC-$-h`G^)SAdfbch-v|n1d4{n+deG704nKQvUPM#XMWm{q zlRj&`tsh#$7jCuNr)P5)4O+$G;k}gd4x!Zq+)w-nBE;gCV^9dvC~?3#kt+W)Xwpg%-z0{+d#AX19jwF?svmaV$l zUoAAjao|Z{z=d2#=`TpXx67H{&K}>+=3*b&L?7NkAKpY?6qXQ8imsG3f(oyaAw{#& zky@&{J{tfi&sHfg_fx>=6EjSa7fsn%Th5L~`oR7PD?lYl;S{ke?@$uFVz#vmJ=6>f zF%OGBKG-j?M0^q_4}~1VehZcs&&2xJ?N`=XQ?M8cj@@sp(^4O(@`FA-R z_S}IYB%~EdOKwX!Loh28DXg5A9eT~DyyR?D2oPBu%$Nw*6e@X)ocrX8ahMT^$~11e zOX}fxG3v77f@C3#@+t(HXkAs|D2j+|8am!)9iJTaQEZ3-!`EVlos_s>^{sVqqE*u^ zwWxdecZCWQQ%GFR?6qSmgORRiV~X_e(7nn4{m6y5`G}5jM7m|p%PbQG(soq-e!tYt zz>h&{oWB<)FvT~<&USI=`WT-;`?&OaBr_ebt2A(dFshk@Mhu~}LZ%uVTkS-Oek^rx z(K!>)|8Qn8wagDz&Vp!*XTmmi6 z9EBkVNK7Rek@wJPnCU@Cu9Zb18+J@Y>__P#FA|y_Ntw~50?DPb$i1cl1_(r~9hzXr z{DbHo0c$u-(7Fl^VGe_Mbc8YvVo9E8=#qSCsnWH9{$#+)#hxeI z<+qciCSjYQbngKdeeGz#vooGXW1ci$JPb|v2yq+edePJ4*wZ5p^t3Y-UIxa94{x~2 z?B_}6+YL>v?&n&)-cOAa|K`?IIjJDMg>0mSi}MGG(*-GTmMz995dopdL%Fwa=|F`5 z3rMYA{o)Hq5(!@YJ?%9{{H(tTxJFX+C*<#oj%q^1eO2~el==bsoP=83Fq9z8KQEg) zyM!HzD{ByvT?|N+@xj-h+KerRZ{^rjcjNHf66$Vw448xiTIaieL%!tSnNK0im?}>| zqbIzH!kp;dh{0W2%_Az2 zVd!gvX}9FjZ0q5i9lA7NZdNy(aMMZzYpk5Pfs*O-W#Zc!9W6Epf0HE`IaqQtM&S7N zm1utLeCbL^R2x)Y{c8M00aw95{#*oXj*_-9x4EhCs>z^z zq2Fo}i*aeWvCms6Tq)e!kpGoNq~X4s;9uROawh`(w5Sw{w<-N^Q)H>Ll(J)GZ-d$_ zStTZw(_GA%IblHGY`W)kK0=5xOqjBP&YbD#qa-UK4Jds|KV;}p%;IJ9u$PW(I1vp{ zvjUdv1EoOs#P0?QsrR5qAV9bD-VpiVX(7d3bf=TB?C@p17Gz=7%Abt0Q@Zq7BN`Y? z_((vb&sbl43>R69F+b~dThy+Nyhpr@H9SdOFPU%@c^$XWLd4+=TcFwU7M!Q)Gr z4gT+^OKmV?4o12v?O*G221a=l`lS|XMtE7E@b@x3++@Vbgw>6?ZB*Lg>nS6a9(VfT z_g;&3Xi9fI|C;9AR%p~*+Ckd={1W>wH~~tprYVP#s^)}FXDH#*C;&mmivTS;zs4ra zfExg3jCKKH9t8rR5uL{DUZKp6pC=1eAQ&XXeLdRr zd}L)gHbg(iM;DxnY113D?Y5CV!JRkBTfR|WrD|qp)Up2o{~|^dDk{h-uGYCQ_c~i5 zs^Y1)k6JLih6?DjV5s4~Y6Tk!=>6kcPkns!T7+j>V9t|*ly1!KE75YaXDpdet_F&Y zg^!#$LIpgEmSSVu#;tdWCdhHWh@;x2L&qY^F}UE0wh~>U1H*$X}5Laf9=1)5$Gw z)hf`y919*$xj}c0z9&Ws-~)p8lyYzMawYPCm*nNo$je`%gRF3m-t9x6U`DV6efCHY z1GnyQiSLl zV$zOBkUwL#FoOPt83c)f%|JgJ{-3M~^7J4&r0nUeD&9I%X?Pc+$%~T0(|=6W-ojQXyO$=x-_i~h{~Q6G&@UR5kA0mapdYOYB=i7q zhKS~lJpuc+_6!%mqxAyxfIynBidlL<`&!+2W{;HZ-UE}aVqFKS8`TRoLTbtaWXQ_HEes?-E^oHytn5in-01cSE!^GR zcVO7L+Kue*!NK^4$n3?-%oWm3bCN!;IQ_Jmh;66ZT-W=)jA_5XrB-i#u1|Bj$K`cd zrKBvgPR$d&39+&t$~O+JQaViTzNCkOf{U#GgN}<`r7nUvvy}Bp}jw6!){u zaBg`vp7mCV$_jIcRCzEPhU9J)aZB#Y!zlMyh5SU;1Wmp~ink@-qI-VGacewQ(b(~Y zv~z9t)=~2EU%)ROD=`|--ATzDwHSu-bB?ans_fBc!QrD=Q}WF0gok58vV~j--ODK` z@JpE~k_#II!GhSI)*O*El@1rH38L&@>ncAp32OO@BwdW_QtHfaMikz&_y(zc<)BMs z)lYH!UM+!WV|5iy%h+ql)SZOYjeCfS4utM3J>tI(;}1=ZSqhek?#J9!b8j_4lQ&pa z3#Ih4Z+$TTyGIi_ea6z9Z+hyoRrJYSa$kLnGNLJghP~^vqDB3|#5Am~5mr|>UX>P= zf+RgWE#NyiFBa+UmGSbf2=@+FXF#gqr@8&(pZ3%J%2uEsSr*KlAS=V)Vl*afIh+=> zkb?{F<&qU7Ux6lFX1aSnHJSP%#uS)r@{3qM8%ZpSP(OT4@tV_=s-(+EG-?am?NIUi zQuL?L{05Rgc{5l(mixi7xcQ0PQ^V>p$4So{NX%vOMjQCq1Hp6-qZ{HrKTl+h+c9Nr zMzxKqv$QUfDDDmvU zm);k=RgksjqI?w zcX3~lvNzrTU-EA`!mdyfD(CUAzP_Tn=Mk!MvBt&+Vc&?!i(zob)#{oIrjp*n3Em0Q zgBd!4BhCucn4A?k-lhjquEzeqO_U{KF&vDN9^ntBewB5{oIxG5@;osbGU>M2fTe20 zNcXF~Q@Xf5v)8Q2p-G@aPelhMNi$hMd7UvtEGbSVpM4Shst3wd?#iCRdE+w5zbuUf z(v{a=l3zg-^WIJ}u?uZi9ivd7a@q4K+w$kvqxqOH4Ei5!iYq(novlZ-S0(xIdPk6x z9nKwjM>AX`ey`g*2BU6QfG)%yvp1cE}HrXSgfd4+MOED`D-$GBG~+ zc79coHCX}-0`AKj-aT#?!2PZ+M%85DPtmSoA{J1JHBhHf^hyKrDc9#~0MnJk#t(9F z8a%D0zYIJoD&2iB6IEPu+S8w=0xD`M(U~2XKSjLIUhd|Nnq$sk=PHFrzqe^WcDBY; zq}f{vL(~5-Q3=(#dlRNiB_?B2Cu*KYkAM*fR_70}mY{AJ6$#AD#-vfR%9p3fxrk(z z)z;ICaz=fmt+wJ{q-pBv35yR-ec#t5r%(DzM8F)eWmjmT0V390Z}SmbkJkihg0)L7 z5Vhp68^3#^SLuZt&oH>zxZtssOmK9bJ^ErTf^7VVaPRBHfMtYN;bk z*CSeDc<3iZO+^%8YBL%G?oWWCqfujoGf!V9kG6Op^UDUTlTX7#5T2Nx4#xO2SzcT% zPFayO4nN*H;N>1)d7tG)0*U?ne1E&`3K3#-Qc(Y-SlWuHj!5wlE3i%`23{hzpI}4}+DbwOWLrvM4ZW8ho)(Core|Hlwu;JZ#%rPgzlz{X!F<&^GgO){~)#bXgRPK71eKh=8_rw0RT|rk*zgsk34p6t7 z12&OfWOTc(Gh8I%@F~StEW=K!#&{)kW}TkLRoU)QAwDf7``bB?li*1yrYW zG+5JEk7zu`#KFZmiQc9Cr%U;B0u)8+rwuC~fF=3; z#ljS&8&&wqrh}Sz(%8s`#OLDJgCJG;x}c}K^SWcy;k7Odq;>HpFO}gBQf>Pb=%a?S z+QL z3x~P*{CQ7Eb*sfjCyzbh)AiDT*g1NDd||8UXag-v6A zW3>6i6cHk-mgqFm``}xqM$5;mIfkogwT{IpxMx1=leZ6ZDYNS!_ujb=?gz>5|CbL_ z1=(|MQcWFvXAR7CxU{)3{vIx$REbx9^yu^#@>9i|OOcy>7Qwb!Qs6AUAGo2oeQ@3V z^zc-o_Gw?rkT9UUJ&pZrW;cD^cC$$;*y6=SRGKktRR{5HJ6{r^#(UaM(eG-qMfdLO zc)Qs!WvYU4J6Cj!0ISiL^(Q>VIVIU`}UI;F1;Y4tXaKTKD*McIbPVA^Q~t|rq9&Wita;9 z!oEXOj@C|)pP0I?TrDg%zS%BvoT4m(i;VQB-u?a<#jR%@`qQZnXMO%<-SYICZA*I% z(R{4M)b;+4MZ8Haio;Mb4;)1E_P2B%BOZWK; zK7F5TC}ycnc`eD1&4Rzr`6A?!X>mDDwz8|fzOE`+d+%#~$a7DfNGT{PN{5r0+AKc8 zvS_axpRGCgp|T0*(#DyRr|XA%T`R(Z^R1Z9gN{((#@s|S(1@kzJR5kp`L~48GFw9R zS$+DC!)vfe9{UjPl5e$-cTn0`=>+8B^HW;WUXIwcL?Y=SdOPe990NfFUaZWns4GE_ zTzsMELAK>#(#gf~mPp67+PeMm4`)aaV$F8>zy|rz;&~|X1OCC>g3f5HT120#9)S%a z0$9j*7?KUXm`9HiPxn3&{uFV3`7Fzi4Wl!E>#A0mK4D-v>{t=>h!s{qO`)BKdsLZ9AalQXbS~A4Qyz2|$2|nVdS%Ng3O5nvt%4);n#d({v;8Dzm=(E= zj#Kw?s!OmEk2!5#T6G@Rc};;N^)^eV&&QGbmr10!Eg~b`w8#u z->wJ>?=(Ol1O&uc-hx;WPs!hl5cK#(A6OQH3sw{Dzh9a|QoP$hlmU{8qIb#5T`Ly* z9s6S&WCR_-1@1q+ElJ^f=r9nZ*N&zas#YIdWt`n~9Crd+ZC)AL3{LC3tkh1`DCO))?05R$$ zZ*TL2V%#j1RxYnfzgldz+kP`C9P?~LQmqcTnWwyKzKg!#{iOQqE)(vY+E+%;c0G7I zg;1)zTzZpe1+Kf}`^<(%rlUe8Dmq%#)_3@2|7=~|i;80L@-e^N)}#Il6G!rk2Trv( zR{h?hsicBWoxq#)|d?$Gd49Eh6w`YlwOD$I~fn1dRn5$pV3JcG$@Hul&UuXKy> zhq_&g>qGghUis$tD>v7Nb9&EehljkY2d`=cW+>&cyuBA0+@-&PLcI^fj+`&j=O$5W zU4KaKlq5-xhO8It!E&7tTTaL7chs(bQ8PLLuhB{=7hC^p@MwXO*j9Eb%_DQ*Sd?VFgrNcK>>cfb!PbX-A7|BU~`|5r&*W2X1&{z zTa`*8q)%Xt)f}Zrm3wH=lkwqtuyXf2L(+Y%+RRA@5@de4_9K~BF{}Z&CTdBa0>N0uRuJwyxH4CN?1u z6ps(DK5SHz^tNeZ6?aOKmD5nBH8_ca&Mxp}S;zSUicmh9zr7xQ6)?@>d_$2ulxqh? z@yazt2&8s}9>Cwmt6z8Ux3!n6%R1gq{RMw&;5sG?j`$Y5NcU&;DRdabFse+wkRglTS4&@c z?l_X%m{g}J04E>%Z5?0Zcgniav4#qF8*MU*X^-4UdkmM=UyCU|dE9#0nQ&?+a=ETU zzDs!_wq$(j5nKxJMR zP8gs{m6KqyqOkg?2b<5YlXh@XmLxpjS**bb(ssVN>2m19fAak9OT(8d*rTY(?8br@ z6KfZ8M*~_S5vYnsa>*PPTIcZDSa4tY`t96)f?4d5w;ewz+A;q1xzM~uC!@&|7yeD8 zLHbNpbt6nKtAUQp=U0b62VK-3{{;D0=wPc~v#?Kbj8Ao$by3G&!>b8Ij=Nz`B5JiN zJ6>=aZ#C7)CD(kP5=pV*xOm_n8zM%Z+tew%wZiIQ>~@i!{JL#&Mc#sw>s;gJ_*JWK z`Bqw?4_fasJ248^d~eZYhslR4#j%{C;Qp8C)#V?)B7w~w%JWfDlU+CE7`&=m!i2P^ z5lu#JyT3t6ALm>@(P8mQJDX{AAU&+XTW_jlGC=xYGQ$OunGO9DXV3(@Z9DMFhjXAm zgnqD{9BB#p>5jOQBCeUNzfx&8aImh9TXY|M%1k>FD3n}WsNW1MZ*HfL2nfRauz!#l z$ES-Uf^zC^mF_>t@*s;5en)0e`K(KioV3Y2zSkycY+EhlKs2tci>`Hz-PO;h(9NV$`QEXW@WR2P(hr<@s`# zrmyU|b|kzyfFNFQ7~9);p6|~usidIr|C|~|lBLf1YSRO3A2m_i6?8?1j((G6oO(g%(6xf;i%E6sAq+f^iAyr%1N2k}bZJnpzUz<34 zZq-$aV|70kIw>S4{RrH7QAO1XvB$Ht{V9-*fapl)a+TM|r{{R51M{-W%AgRHVVQBD+R9+>MN{!7H*a&3G8D`g`W%X zo_Ugeh7xtipahtbWo-WNo88LV&kz_Fo?Ouimn!eEHgv_D)<>&syP7X)F%thRz}#B? z6h=b{%~i#Xn7gEp!_?l)IW_6n=NsLKo?ZKa3I*${w{_X@&bX`KYCHA~^Sm*_Q-3l2 zO=57EhJlRFi=!BiP4uZUJkRSe>BV=+l$kQi!;SKM&SyUkS88aMf~4#5VB>1=01$S0 zzVXm=XFo(mCnM7R^c$_G>oN*t@u~NP6UcwT(ct$!G*}Ci^pgUhi-7cGIX7XQ{rlN> z{cph5d8iR*`k2i|+VXn0y>xl+Br@wQ!skLH%?iaE3L_la{uU0OjLlewgq@(qH|#(b zV`C#Bk%$ekU;FXs^wLjYqBj15`v6oP$fmyrue;Re=GGE>pl2yJ{pmsjTd(WVsRES7 zPYz=*r1FC=h~+A8E`{L4G4thf+@?lH14*~^_UGOoGaB@jWNQ}h3$O`>r6CElo=j9O zq6fWZy@Ty6b-*cy^fSE6Vdd!Ac4jEMWP-uP>=!WT{txPW?5P#b-;m#^R}+zab!vNU zqsjHm?Gh6hr2UaFEF78m-8zdR76raE6A_wTP5dVQq0D|-tm|2h*ygX*_0v>brzTJBvB?EdVqaIpoz zULtE$62ZlTzNJP(LAn64EH4}S+pr>}EOGBDYuh~bAF#UtQyAQJgfEBhAo9tqw!yv} z{n4PKV67K2z;L8`S{A1!6H5VN^YrCh;7*6}Z6qDcNDo5i!66$oqEg2FW;T&~0ZJj{ zS3khXrwV@|i#RIr5d!{-Lkgm&ChO;Tf-|j{c)2jGq6qtDs++$oF{^x({|1x&1Z&?L z4Lzf=m@>T@NIf#A?njJ-qDQ~!nU|o)2=4(e^4pQ#e&B#8G4d;#83^y$ZxK8z4(#Lw_U69jDyH{M$C<;EGX)gK#I%fOuBfgy$BL;L`H2&-Xz{RnP>J z&m=p%?$}YZb-j+W<*FwY^uPodgTXJah5p9E*|DN=OY1TT4{NR$Z_t1Oku=-iU-xi7 zv-?*fz{EwACZsc0fN&)WN=46EBIWH~GlaT8|6V9fF0xY<~2tT3^Xn)XF7Gqw|4^jG>O7 zt*!Nlu3;1aZ=L2^_`IvJ{n#b)?w%8|*@N{pN<-;uGb5MrCb?;`bGh-Zkbt6QtlXrE()GSDramF)2#_VeDWJN(M>aSG~r zC$ytPT&C=+jTBvacgiIC`^gZMT^gwt;nM>DPpi{?luZkuj&O{HtdB+vp2$dQZa*Uj zOyCl7Ap0U~;NZpF3WBt$T=L&ODoM#wvaY;vu1}mi<+h@F5~L;l+cNoF8)PI>7P}M` zs8RN?h%EeIsaC6U%d7EhkLrGxgMu6y?J)4&-8qCG=R?Ep-V$9fV#F8hjQV4nqIa{4 z?-Ipv#=)Zq4irtGIT)&4?4td&{L;HbpsX?$oCF7F z96yeX0s8Hg`w}2R`SNss1wH2itt*cyTr8=&U?S)!%2``YEl8gyL~Mu;+@(7#u-ua} zG!!Ah%_j8*%{g(^vaCeX$rkquybx?Q0=VJ%wt7Vwlia3vH&vz-ISeDFhk*l(+vdM( zSG8g|GSJxdSp+XxNY>?+zmQ+Xr?*^|U#hu9jFAre&{Z4!Y zP#7#%1|ckPNBMj6sziPggz!?vvjR%Q( zdsS~l_C8{y(rK)m1*kqHrOII_Khq2cGcRHKS;YE27s#S;R&Rq3(&X(%2!;a#G5SIK zu3-hbkU(qYzMP%=HT+jR7N1->JAh++L5gZb17cP<9|ja3_Q21|1lLAO7wW++_j8&@ z@ zuwn}E;wVHFMmf4ssu74lgFs!9(T28&f#pf+I7%V~MdBb%vdDqySAnpleMHwn|4-{@ zlYjbCcIF299h1`(tH2+EqbdRv5Fn1JDZ)@B3@AO24_LCKgc3zjl0;DwJ*5DjSP@Rn zD7tanIS2{Q&~u+X$W;mkYVi4ONVlc$xMg5>QOI;rh;BZ-GD3uu$$saq2TiaMO}Hon ztPexrXCnf&Y=q>3|9OWCNLSv;qugg90MX;?M_L*UuThjlHn=K$kd3ffI!XTTsnMRn3>P4=3IY zuFA?3WsZ|%jx!?n$CE5fe49`=+^-AZX#!}FZ;{GGr{!>0(HL->z(-PsEk{oFEF%W4 zAi{MT!%>fjEAwMLp}-Pj$C6;cGS&VUhlP@X(=UYW)&0Tb1362<9^L99hS581BaR=1 z$?xO~Mgd-cAen=Jm%i?257!|B7pD!oq#fB0o%1Wwlwh+4qZ#vTL}aUAGZ%C|sek&^ z89;8g{D5?%4tx}oUj@Ew^o@75x{((kJ!9YazWi0%Z9+6ljK0feSYq@G%HirSw~yGL zO&YkvTx(9fIKy12{46gMY(J|bg{c#TnPGiaCwe?@<7TLg2>UJ`PKQY>2^_%moS&j3 zxo+4Rtb(J%Y}8&6${S5&jp{6C3C=_*KD=hz*vD8A_~cJH8UCCs3}hD$oL-U!Oee#m zR3x=03PJ6;<7R zyzt9sn|L%8CBB$Dev=z~E_cUnMr9>{??2-#7vpeFGjpaggCEs2l3;zt0iUXyD5{&> zj*TSCvP!Zo#GoW5PgJDw!jhYcMg_GF;7m-Q+$vT&B1#>uT&e-;4glZzM1)Est9IFn zK{Sr%Ga-k?{o<(XLM~4=wA(H)0=rw;0cl^-MC!BwgHMTqNPe$J|F3_e%JBd#@N@SP zDR9ISy4eDhSXr?(5!BNT-GS*qaVG?;QTJma0y3?S2Ucv~45=7Osh{>4k9GOGqZ?S! z@4p^{nzLC=b^-RT(v8VRNW*-+Pp&;|K_|T7b3XP%ESn?E{q*aO(I1y9{OHclwQ#nCE zY@juGHR=eIeY%J>1$!;(C`>PCQ2|RJZ~3Gq&oA%cwig1zdz? zwK~9Fe?Lgs(SeBaq)U`cy>Gx&z3;2O{|NH@O-9;hv$(m7;jw-L zDsbL8MDM4Bs?G=lmRrNYKM1HKHQv3qU=#5@pfh@f@i?qA-=Ev`uhqyDa&_+>$mEZG zGUJl5r~!e_*qBT~Kv`;MP>w63Mn;WpLoDV~Ji4+$Je$9#jf`hwgsO{8$c@3M$>#bs zxz-jpO(ie{GL4U2J*bnrlBG~957z#vXDNx9(}dCa^#x6ldQerqU_WZ*jET&F%S$w` z`N61XJ=@=%9@C6%63#lFT^9OR1?}3krt*5JJ*Cyj_^R8G%@bwAs+X~tmYTWfZmP%s z<_TT$6ROk(v1I&>ZR3t4I4DdN_a^{>e=A58FFPD6WFi1*rZ%Y+%W-2i1BmPTp zF-Q8|sy0FX$?AW;Q3YWcumu0#7dkje;(v?%&q;@p8BxJ~D28JGfBymeL!Pf-(~XGc X(gWH;tu|Z;_>z61Bv~PD;_44keN^fHVREg3>J_EiEz9r8H8?(A^!w z@b2*!|L1z*{ov(*!kn|u-fP{pCPGI`uRb>k1#N>qcJdWaPhIgcT(KG zJ_dhbx<67;z$oo!SOZ_+*vV_kV_;Oo5+N;d!Pf*Xs!!Z8Fi6_ae=xfspKLHNuJYBC zXv8ES~Bfp0T=9u`T^bjlDO_?J>Ckjh6e%d$+$p(XE3&#sm zRcjj0rdqX?Fx!t^i&_qv{us^e>a5Ezh2SQAT-V`tE&g~Z)SXAhPZPMxxsvtwFwmvQ$zP7@N^IS{wA^~|ZRt|n&_vB&u6SHa{Rh2Y16$=KeUqWH&lcU|1w zE7k7YlaY}T7FP20@SuYE`uKd<+}!-tI67X*T^g9 z`zqke66VX2-B7)5EqK1ue6hWf;Y*TiO0h_IeDmf_i@KW3&j}h#;%>p$%DwknUdd3K zM+jgHzIgYchEMe2+CBWrz~f_2s&p;7RpRfF9EaEmT0swjxlVmU$Z}ZZ-jlIEvXnD7 z&wMf$+w)Z)5wQ316tNfc>H~Gu`Gc=tzrLvs_t3^Ce>0XqeAMNYpaWwO$jZ+Txq)G& z7n=BvrAXGmj||@b{X0kPkglQO%CBawiJMkd%Xn#n-xCD%EE~}t~o53;j>D~bJu$x*e1BVjX-_x@1Gj* z^z?j?t1DT%PJlJ}8jo~1BQ4Fz**SlUfQvuf+Re8|n%V7*p6-CPniM^eu!x8iA8|hi zo+x-`R0&cqd)8BlWZ_X26%`isv*u?@3G*=nJNcL!$8vpPuG%5{Dk(GM1f=qcPO|Dk>O_;gd%}V zL7!|`blq6^=6$e*@bOZ#f4uvxhJMC8`0K_~%$MMKuqC`qo0^<-fVRFQU#Uxzr6xMe zz2uGjb?gg+$;!;9<^SAce;9SBnaAc&nGdH6?rk%H?$hD+!ra_khO7Jc@85X;y1&0aG&B?& zk3?{CW=2Ltv0v`EWG!4%;LE6cu}^XG6M?{ijek4N_SHuy})XB6JMPo_dz zp#tSOojb~EtFLH!VilabNa2?;BDKz~4m=lI7A`J>NBJ#Xv1GVi+IXr4=bk%FCk6q{ zlNWlt+6cGiBZG5JB?p2?Jy#}BW?Yct6BG80B(t>($~-ClJ6EHl`e2uCJ;F?$sI(*P z8{oKv9_=6G<_2|%-{Z%!*Cy`LwN1jijNB5!zvQ;ty_E;vJ~rS|Mo>^tR(9aW_OE(( z8=H2|Gnbsgtpd4kp20>Wc@UeB)#)yo{8%ExlUs1M{1h>IhaxLi-HY3{&Nwwlu=!mrr-__ijU zsG2c=KQJ|CG-&pcM7Ejyk&Kv_z4U2RY^AKd_B{!Sn~jXDgz8fVrsp-kvQ+Oh9%|x~ z%MHGSr9Jic_phpTo__H9@Z`jr%%RNVZA3)G_V$Y@F<&k&E(glABD#{4_WgwvS(hY4 znHlDhX2{pdXMHrBBg+Fc+&69BALqX}d)PLAXJvEqj&qRbHBQ~SEgZ6PME3Zqd{}5G zOYfb|x%>gWh03gg0=y!u8g``?u%^^!;yi2gJ?@gpQYO^ph zcDA-}LmgHG7|;twH3kli9OogQLc}(Qepl=# zuRKV5A%s-sl*Q?sR|6q)kUT&)&NeK{+8bo=>|AnJS$y!5n>05!7jV*Iqku9dW5dgXug&Z< zjLYRgrGh{p>(eGm*%o*`$6c#ZCF{=;nH$PL#Yx7ycCDOu$laZ~ioPMS=&i@m$kx`@ z2?7RJTWncepMhUnF1+5gZ#IjLrO-;?tB@8>Sb>nh8JUml7 zv6hdI@Cy3~aiT)-3>tNac{OkpciCv~C`$E_W_b9m(xWk1z zTFVAUFneW~4~s6Y7+-*$r+-b}m8bt8Ir&D606jf@^f)H6)En2HO@<=$#7~as^s8MG z^Cj6BW=CbKl8Dm;#^ZYtgR_QER5hQ}{rkAy`CDpo(A6U(QmX9T)?Y=w37r;7c7 zMOG64P=>ibe*Cz>8)1INceqgJX8KtYima;$Hqy$2+-fgFB6B$DHz1>iHOi3RRhh> zA`a^2x5;w4sSFUFn-i@5eGKq@fz0Mfe`k4AL59ymQ0%++qV-I3+w^N7h#1z7?$0q- z*8dmUubaC6WRvnrLXdRbHBx!q=5qbeH1CJ3j7$v8F4f-G zuM*H;x$V@Hl=u-G#^1kxuj2oRD;<sMX84nhXC z7n@pjs2N@k%B_S-ScV)fBv@@g+XfFFU=eT- z)r?0T%^5AtzoT7LF#_8co!-#2QABzpM%!j9W2J>=;v1BBBqk3S__6^`ji*V^d#xQg#| zjk7Sm2bo>FEUVhO=h&zWiEV6!Q;-)fx@ z&A&OY`bg8d5{oVYyfnE_VI|J}clAuYbsrurlYV}@rVUHc0##>8Stl)0sJ@~i?f?&9 z&dyYv0_J|>1pHg8hMPYgG|v4lR+Z_CfOqeL$CfKfIQPStB@4-L=stFO>b35lUrOF+ z4&|tzOm1&}0fBVY%E2s!xiX*LIxdRCyOm9O8CaQc&84QMCPm5OjKFZN&TR%SbO*Qa zK1I%~D&nE)-qCf;9Pr58IG!3CJ8I~nMroGojyN|YZ+iJ4_>8^5`aGY zg3H?8t8~uUPN?MiTzLqAK>Yl9Em3%Fm%MmE0e>zG{2FRi(4KTX8N^&zzO(TMlZmtY zQ(EEXoc+TKg){#LRlFCicX4rH3V+HKOqLi3>N9I=#Ijxp8s90=^&EOX zdU$&7ze?l-mF<`-E|x)D!P>{?DXA?#b6Z>6kDm9Z(Xp{B2abN|!u>4zkWU|!RuV!5O9Kb8(W#bFWR>^P!ulIRwudgf6s>5oio=Ym|6A#zMgUeMAQ==@1 ziHYGfzw*p0EbOUc0Pib-2r@M{hpf=s+SzTauiH~P5h_3^`ba~ExQYAVj^m|Dj4=#z z6E`P(#3kuDblIm)!z-)Gli?p82bAxt2kO~OPfvGscG}0r#@1F>50QNPIsOF20J`ce zT{(Z={foDddEu@CxSR+u>s>TZ8zcP>P%EZuP4VFP0#KQCSB$Gk zRABK2G%F(`V;(W|5_!5u$))xE$B!17m+MsNr9Sds9C9ZB4ikKfIpIyE?~Z8puVUQ> zm(x1FJqg8iRv-ANnYt?PFxet3EIhanc6mqcZ1UDhIU_3%!F!UyatmjJ^BV9zgoCvz zOx|Ft1>;jUyYd8oHPNTR_Ly147 zP|GZ*06nj_12NlnBX=jVr@6<1 z8D;uncMRFt4OrY+yixx43(d#b2>4;C8y2DF}2pnxGcIr;7k$6M@A0cv-GkYI(rlbUi*)kztf9J$Tdb@usfCfuPb z8y_3Hdo??om9F>1K!?Ith~eqjq<1-n$$c4_?M=6E_hpQiH*VZ$QTcE+q{4ik_a4|t z)Nc->(WlLla|Cfl`wW1OgWX+0rA)?nK*opxd@x{Q&RBlrcd0ztpyh-FWJUlcshm70$^+7BC3;-&lJjhZwC}o74 z8)8Shb8S7ex9I`DOM|q~um|~g%PX$iFvl)YBhS&c7} zxNc$~)%AlrRQ-b>j(}UsJv>~+Jq^aBpFtTK4@p88>FIN&Wn^AFrpT;zS5AA-dVKd+ znBPdx5KLX2DB&CA>Wf-jvfBJ4YL)A4)wCt^!XlUK8NvRCV6r|n%%hUios$zOcphZ1 z)?S#9J`;V+G114|5CC?uLnkLEVKcm4NkmYz`L9AwxlqGptrI&Ki zX{|T_K?zDqI#SH#78Mb-_C77|Q_4TyoKz%D=y@|!{`2@cKd3NAM@Ll^lYsb`-JY&@ zU+L~vUFR*2yTP2z*a!o(>rG;N*(DlGSz+Gkie(l}BI}Dd<4$}E z-8~6h(bf26mgH~NqQ~(XR0Qk7KD4@M62FO!&Bc{cZUjrpjOlPvR_V)v^ExoT+nz3-k1;l#&1#yl?KHLT9DZi1iE>P)$d9Ecg$3d zDgGeZs2Z@#g`>dg%G%=Us;aD?RhUTo8>(mE1iRkK4p$7=0`nH&AiE}3g$IlI5{o8j0Qb&K{IHCbfrY?4wkN*$a2@| z{ZmxN(lz#3&_F5#(ZDHOiJRdc+;s56xG>8-WIw0y$^C)ML-**}xEru!n4jOTZQ6g~ zlM1gq%u?=SGV{boq8a$#u<3%bwDnrLY3nI1R#PsiEfgl7HulHXp@1mgp$sH%3jwcW6j z)J!m^($QZq^KwTSzCSlLeNuAYL6_zH{JgWPOHxAOo?lir0O-xlG6R`blYp^)qc;yW za!^GiMZ~X8XI`CUsw0AT*}KHXNS0(zhG?UC3E~f}>mVj6~-3ont$J z%zYQ*s0>%!AaYqQf_pcrfvhhi(S zxt&BmFf2ewRMk+wd>yvmx@E*9e!|!O#WsYL%3$^Ow@=bW*Z;2F-WC>FwY9bGd%q`J zW?y%wozr9`s5AeU;PSK1Rn;dao_Utv~5>Gpg4@&3gaf6>={Qgc_k6Xl(d zABDKRqH=G~1?=Ej7Zo8pR@qy4?>wBG-W;Ev);(^Uo3p(5=oEh6j#jX^mbOu>7vkVx z8J|FN{rdGmM>^GE?Q4Ll3tbQJ#}H}d2$XYwgc+q*>`0IB*^h%4_^->7jGI-5h@ACk zLxW0NIf8ew2p1Y%g`Byc$obQsqJ8l_%)KvF`*?!}+aJJ{6h;HjVhR0opB;-VAIB?dh}ID3A{to!u5J?BL;$DeEA zJ6u;ATK&Am^~D5C=X+X0QKqXy`Q`jH`44orjYOP)3y6AG#9kFLnd4Wt-~4j+6R(AdLz@`G1okX>n6L(1Tw-BpPGrUs~} zC$V{u$-7Ov{{4w;A|3nb?pK7V=hrr=^Jc~FyZcLe?Pl%q2O+hkkKTc&`F4T6V2W3% z&<|{5WGnUEm~q%rsC(no(E_Edo{Pe&<@d~oCVm96teLc~drq5nr+xL0cf0E$O`PJ` zb771hUwL@wJU6ApSXfxl@zf?SD=O+!N{_RO(P1T?`Z1JI{(#adA&51L80gYMgMAXl>rK+-Nc4wO##2FlA_XD+Dn4N z>t7zwJ38a5-y0I8_m?=@8p%Wnrvtd%8*8l~*~XpA z!3|^CBf@iW0{N@cR|dGU?K;BE!p$l9)v?VKNt8$Pmv-Nl+xNQ{)FrYX?P+W}d=i0a z4$g%6fa>t$K4jKieuqtA~aE6rQPmTE7~L*;b9qY|emDbYke$ofRg;tA9SotY|9JSs{m2jH@0 z8rCeraaon>^$O2DPkz5*mW7%C;>s1N#~TTx3n0A^3pfCa>;~%}DdZnlD=zEeFOdVt zzmfmQ9sjkvKZn8K8-^S0y?NeyT&95bM5~A2Q#t2EbCdGyGyOP5U;=;x2Gn4mbpw1| zOR)d(>BTz>8CcLT`d_VOO396JiPSdU^@2%4~od93N%?lcuOB zR}-`&X_d4I{kuD-bIuR$z|#c-5}+$Z$7%T?ns#@i*74M>);2eVdE-rQru=VKbu7ct5p;fCCKJ2uKYs5H)6+{UuSY zALluEeh$fN;<@B#=eRpLeLwiDbJtQ0L!Y{%reyt&6mgaJu(RAVAfneL3B2*#QZa;T z17+8?c#(E!))o+*Pdoh=wXHRX5Y?!|Xw;*Yc#OZOzZkXR0os9=@mM9hjxpEfok7>c zB#zZo3Axo7P*+_&)|(TRk-@Z*Y|an^w$Xe$fhy^yUV+xonu@Ql&%+9g|k=s+3Stj6IAt^=iC{sS11zz9mvQrQKolJ>7m9Jn-CJKNv{g!6Z_ zKvL0yTIT~TWomTv9bJ>B$E;KBxQYv>wV$?Rn$tvii_z`!=0Sf>MXZOoYD+lSmf}Op zn<^DGpbZ!OAv}p3FJ-^(7X*1SXYiauKnGzo_$6yNzmqS?rrPVr8NgX`4zwjU_eoj{nNM zva%9Q-90)=)qK;myT*C?O<$B7V#n$kn?DgY*j!3agGw(Hu>e%HpH4{rYSEPiw3o(p zoRYg=<89a?^sHQ7OeaUgw|V1^8!_O{)Vp&z7eAEjH+wN?!u@D{NnC7;7^inFEqb@T znmPSs8grBO{ia011iW*fb?fg%i$pR!7UV^D7_kI^nU(4({}EE$7{rBytQ*y2%RU5v zbb_0d1FQ2}di-0TEnbqnw$)EKy2-#$g+(YIhWGe|y?wykqo!wASl0zTwQ0C8RgN*1 ziopq>T&i-Hh1MPCHX-`wQv$z{C~G;1}t(U63aKL9rOH8eU2_?I&b z`TgUT|6hd$<_ay#)7hM=j)LoBrRdE(q4+k#!KquHr5R+*nZ*c-kC1nSCvGmyC&4@j z^@Gs!<+ISo>A#<2lJoF*%Dl9<|CF0+&2l07Vn@r0f|m~N`H$HZ*Gk>d?0*4rFaS8` zu>1E>*1SH5#!xy3n}kh&k*>gvfmCq!UMU9%fY65E{^;}6l3ZVE#Nr<1AoS@{VfG*8 zi2u^RMY*6EW`4GHCvM|(uWx5{bxm!~;z4IEwer!R&r zxIRCv%l1Z19KRA_d`ERph5lxGY>Lz5myl_^evxdhYQ|3ybkBv>=7DB4D0xxpEQ{_cH|sgwoHrv67`9um_nFJbG1qqU<*peVK~>ZB2FeMnB86DzK$7y?vN!T~bVcq2^4 zSr%6BGW!klo$O1SCp;|7zQ>ztRn6868e8QzMSt3;+w7F;__mWIPS~;Q zh0(-r=_cO_6goUIlF(*)#e1WQE3~f)80m$vXh4n^ zt??`jIkZ4f^OkD8{pHW{n=Ntj!XR<}vkj15!~#msrjD<%**$#0qP=KN(^HYZRq83w$A zDzc;zUmF^>ZqduayRWa}ci5Z6nOvI z90KWQaOyPX(`sxbpg8rvAp2G`{yXiIvG#lBxsqT7;~Q=j;9J_A9sW2N|9Fo>>iogd zo@1E88vT|&IEhl=y*=|bu)YQeO=d8OAwHc#p>aa?8sX$e&unahwYF(hr4m4mrArw( zer>$Evr|@978b~QTI!)ably_o`z<4c#p;4{4y?sxOzkWZx+O>csvmNfE9G6&Q(p@1 zI)v-Sd)Z{(7N9+?8`_dXk;mzXz1bC7@zH1;HxARZRp^INBP%TZCVddGD%;)F;e(`8wA_lruf|>Lj*uEGR7E={C*8&tW5X>dWkmAvDS^%GIFg7^C0|rkkdPFnNXTwJvj1OUk$O1KS>MU;>N=P-yY{lH!iXA#4kV zS^=IP2itbOYV&8MpWR-is%c9PaWd#0d~7pJLbj1E`D!Yj#Q|@FrH$r*7k>GiCSGgy zz3kWy4{7pldr-fdLhe$(@~@J2FSf6~dPu{AK=qHlm5SgZffMIX=eE3N$d#@TsozXU@<{fY3eTTR_ban!MqDz2w1bDF5jb(OnDHMXQ|LX_DTc<^4 zOT8cPKU7|z==(+nIk6Gkm@+I%O&tDW+~1cp>W61 zfC|4kHIH4*(9rN|Uh*W^hybkw{BWcYD9mYYdO3CkF+S=$q$Mn9e(C9nmTSd99T$ME zT}qLLLNi! z`)ux)ZuAeqi%kq(E-^RH_isnd5T)u7y@Ld>9GUk+(~qr*5FHAV0YgK&{mjB3MP^8` z!R*;+RMynw|CjpXWo%5pRV*iXd9iT}^nPW`f&*tsvzh|5Hh7=ck2|Y5+V9bM662t- zWM`M=b1LS!+<6C-&wwaEdkTA{U7g$3wt?(=@$M$|r$=w@5}k|yV* z*O|AfxU)U8aQYb>Rr1(DGGgAMFP7vD({qVS!D2*N^PxquSMhRBK@sXK?y+r$+rGx; znymNSam9N$F}RnLCSff4y^ZtLTeK=0bd9z-iG!;^y9Ku+B61VrW@b5%A$=$m0ryL< z^5>iTJB?QCHM@ym|KO=Sp>Rjk6e9WRqPbei62AZK`NEOH`GeJ#M;iXvBP;N$l+WYC zP|YLi5u(_ZfabX}M&B#3W5sSpXW4tBwc4QJo^A}+?)dNc0@SFW^^aaNY5()Ijkeu! zH{<@*g>2FH(+lIG?XM?n=hKMt01oHy^rD2iBfYZIZoBbhr3#lMW>XU9cL$K>=e@}8 zp_>~gMFR4*!K5^BLVmL+M?A=;;&Z}lWd#cZ`H$694_aR1IWS9jgkPHg-r(V(@D?aY z50Pl!Q`~J4pM4yy>>#s@tSy-jLQ`s8QgG6vZ`*9HeAn4ErV4fmwAhGP;QT`TvHbk! zg-T);g!$5B@3Y_^-9|yQ+;8O{Dmz4Djy&Syw+AnblwcvAuZudR7RPU~=$ea^cF=%05 zX+BEH^Eq!h!`22GQ^I&V#o=*^#R)nk2h!Cnhl0QXTisg(YVO&z5KO*ld4zPlTzLhb$Bd05FH5f0h^V${_gPT-f!Ofg{dw}PY1BzAF9qpI)TEs+3GMHyix9X+OX zPdqdY##u{Ec(gVRG(C3JYT8T8j&?1LW}xo1xIWJ~KmI7%qy~;aH$e)M*Z$h)RK&CG z!ksBA;`Q_<(IRg>C)B&-Zy&%W|LNRGTL0=d{HTLMT16RqsrDo}JFPK6Nbg&NC`e?oh0_em`;Ev&3^fQ9R6XgCfM zSKtT}AnMNzxe=bnhT*$9M*h5G?)t*L`iPIT%~wAkk55OTaL%ti$&IcS3BCn3v%$@w zsj2p+V<<~qahbXaVbI$q)cyfOisFSJN~=^mfVH6_zIL}3Zi#uVJw2Ikg6aWMxgjJf zM5*El6P;%aj$Dek<~)zxbAQuB+{}x8<&HG3I&V#g`w_jRTyqHv3iVaG(RsrISuYE7 zeXE5<4l>!ybaaAi94`AJckDet3?T(^6GA;5&Ua^<-_O`3M;E1|~ur)7Cbp|hg* zR4EHejb7C6IgKZ|mzHuP<@{J%K>nbbv%DD(5{>yyi#-T-;=(()jR?WyWM z4mY+dK78_kLq4ZsZvTdh?FK+1PP5NO-SW%IAmEO3bK8#ef-H0Ywn&(7{{j|?q2YTq zz`xR|^C2+Q3Jly$YpltVy9CS~H&DC-hM?(^MdfpIul*577@E;u}2+3XI zIPMjHhElluVPxJZI$$fS!257WMU#yYI-RUFKS`oMm6TWv8T#aXW-#=&8567p<|0J_ z2?>c?9?|;x`sSqaTo!X~Tcr4gpuvOaP5PWD0xIW|?cYGT5q!hTxcV#(W@XiyciHnC z#t0J4;yu59{mNDhtK;#K{3ij3L(!Pt)6-K^Ba%R7HTkxg`ubWbP%DF(9p?4l+|Fjn zDlCj(>Q+)zeBJc@F5p80{Am@c!=Zx>{Sr=uxoQdAgk)GWOh&qLcLhB@Y6@0WZUumcln?fMD$he1ZlP|YCLJD$LNUkjdH}~ z=*Y;32F1W7R#0pvItnOu3`nGcj+}qP$&7E*otwk87HBKzPY!SeDF2JQWw~fhqW7t+ ztjj#Z`dE_{n9_&u3E$z}!&A0C8zQX;{-g^m^Mkiwm;wNvR=H)6a$63|s%tOeV373u zZqySf79ALfIYGClhe$txWNRzn3VEBWe?zri1MuGa+4GhD^ivw%NgVU%D?-EDuilLq zsUeTmr?wbmp}&k2sIb=Ph2Fi5-L`4{~E|M z#L|{%o0^H3%{8et3jv77f_~aksI|#o7B^mR9Y`S3t>zmMdFbj~r|aM2$LY9b)?o+u zWqcTo$eM?R3u0<2G9|@>rR9Ri_w!#qK~qo>ql)Yk?mKs(2HBsTljHYA!D_S zlAfxFFKoo;$Nw?7dAeX3APt1aCEhO@5GR56&QmO0o+H2g{@@)MD)yuiPbpGaWO>O= zeNvG_tk0TupRQGt=?HT^rF$O3lb3!aSGj`#+jlt569$4;xzC(bUQ7b{%xx+nuxeT@ z(R$!A-c!dQXt32?z##7`Qv)r?*2JuQDLY`a>zLzMq*y=bgcfOk z_b}fp+%p|LXBMHQkHunhLzH8>=^Zg4lO#sV8B(o z{EJ2I8vHT@g^}I`6x69+5q7y$VX+KB7R+hPzpe0J0xi=Hj*jl$!QEl4>&9`Jx$(`I zs~{y{7y9dP%TD$p8MM&1|7ua3VPz^}g>o)FBLt?M;tm3FyKdJEEkCVGOh*wve7QMs zm*(2%Eh=_G(R)(J-8P+DAj_x&)lXo)0VJxWFfUj3ZsNB5&^|nUI`gncb4A&X{aHey zChT6|Dmge3)flirQK&f@+_I#0R^Nq&RRW2U1M5Wno9AE&)_77#H{KfkrIx=hnA|aZ z*L?XCa+&n!@&Mhr{}KNdU6!>;MnSMVj%oUfyDf&fJ5}(b1ne`2JU+QX9%L4H&@#Y& z1BpLvs)Eq;pj9sz3}$RREmwz-opL4<9c%Gj9CJOHkXT`gZ#++ryGMFO;FGaPS zJ%QK@?6=L2>27SKb~$22x_Fvog_gc!=%xBdhN<@@Q?Q8es{)W z0;ySh#~YU@{!r2m*NM7Z%+Yo7=#`PI(}L!_$+H!GtbJqniW83PDsp{9`>IdZs|4qX2?%OlU^xo2Qo6m3D#=&UDxQchOh!kFiUu$#HTAu2xy0IBL@^gITb)$I=GQ zWqv2p#aKxx)z=RfjLQelM#sO>L-$@eZ;?5^ux}12DtGehQwcgSZ*c!<>j@QTDR_GW zS7c3j@RmiQS~#J?xxoVy&&y02c|ro2f#bot=P} z+f#mOT+zT5xo^^bVt&!mLxFrY>}`ItKuyle_My|o^hfJ6@1>Zc{o7mTy!;xEpT1Pg zdZ4{dh3ku@%9_Bx{1J6?k71z|F?N-s| zGclVi=4WEZ)b6vcG?rUMKcfsXv@@tUs@~aSLV%PNZ~G2=YrZZJSw|v zftTOnl0UBAb4BlPdP7~OK4}^Xot&oZVl@;OeO9~hl?fN@zkU2jy=+EME7J_^L0W5u z3W$Z#iH!}+%(r{`HuhJ(1!8}40JqOF2t+r_3&5s8=TseD{yf|8!>fye>N+{yysDW| zEhVXrVn4f83H1}dU?xt}J85Uh6^&v-Cr$T{##4ex1%5C$c^!yMIc}6Get73t-bbL1@Wk*R`#g+1(c|Un6wuoA{Wof9&*d=Yz+rrE)!KiIy}IEVl&A2 zx?vUbw!U}fW%~E4!2B}-rRm{Yy51lbMmNPI<@NSBThSJaSmK_jC|;B8mxhLh?3V9g zfP@2k?Y!q9NO8|NzNfZVs}ccpt0$mTI3RE47W%%akl?{uOn-}NB_vBb>j=Tc3yLaJ zv@~MsPb{6Z;H;X>do*6`PmRh!u8J4`gzu-Aou{+NN?;iDzTm>JgJO~Pz3!}V4zh<{ zQty1YaRJfzuPWZ1g62!=aj6Xl%#5x;%6^U~+6P=Q|j@u}O!n_Je4?LlknZ4JWU*cHFDd=5pTs+S{FWzGDb; z@4<=AqqcS@dCZ?8jS)>m^IB$Kzl>nGxGjIva+12#W}baVkR)`VVoJ$`f7kJ+$V5+Q zmDjRL{8EeI#0NU(#75Y+OC`Y`4i=hhW#Dcm=^><`&OC}=#%kRKG6W4M-gOy83Cd_4 z84EJKsNY&CR&EnOmF}G^?cf5z+8F z-XovU?6`sDtJpeaSj&IM6T_&3$3lL%-v3(qai`ulim9zS)gL=n+lZ_91Lj{?U!{-n zs^3F8=85+V$IN1&LmW!=tYGGJAVeZ*y;ja9<7~O>3DIgS`tsp@ z0&r07m_R$v9{-DV35il+`RWz}oKHzwPRcB!(ZNco=HtVUOrjTVIvu!CE;{w)8OTyD zx&GwUuUqytS(1Vx#ZW%|1lj57zY7XvN_!V5CJtnM>=h5nfR;!$&HABoyhh5>d$XxL z!pp-IN@WaPx^MgR87PP~iz1&NTw%ifuk{J6N`aEv`BPRf!bZd~Z&@YT`C34kkyye9 zS;g3ni~yqE(2lcqYPV~L(ridz);-*3NIWdDKM%djQ-;jLwaoEP@=!eBYrJBrLkgSR ztvI4Id*-%G&`*jk3*kS1{=7Lt#Ek_R2;vqM5qWC*(G#0ETso6yHhP!tt`I?a;n~^Q zJfd|Bff$H-_zA1eTH4|-ws!O-u{ulfp26*1UM_he5QAzfKVrk&B2G8egI%9jXg7Xa zIes}cp=Z8P6UfdH>q;4c@2l!kcE&gQrnV{xll2X#qGuO=CSa}8 z&yU(=`Wt{zJ@8n|jA2Uxv`UCOr=zV=Tqg4Y5GA^l^G6sL)LOb&T30FOj%R#YmukrV z9_k$zsN_4m*D$&apXv`+FB_%Rz=n+%cKysPkdm4Th8Qj-#uerY`g!rH1IRj5&S~DD zJK(>ryomIxJHel%0D&l$qbi7e)?!xps@0eTJthk1BbWsH>&2V@L(K&4{FVKa%TF&s z)H#k_MG6*J#&Emgm^SAP+WG;=zm@bq3Z{BmZ?@Fjj;ZmRlkT{Ac#1MU>ppPugURMt z-;2F;adGkUlR7*976WWDz^Ko&e}h5fL-w_JFA!js1ws}Rs$YZ2hILPfK!8IfkM~}IF?mT~_KQfXjZrJ>4 zHAOomom=Ud9vD05L603wq99$H3&dga?K@=`gVLS6N*&;o^34s_etH6~ zombxVIasBCbg@n_>G|td+F1Mc_BPPMra+`u#&eUdt6`8_l1msrPzznLLdi+I2uWez0f=syC~Wpc_)+M_3^uN4QOGCzJV-v8 z9(R+WYo$G?m67-5+`yDHESnwV@8}4*Dmk_{2z7Ge!MrS_*o`IYa;O`q0naXg?>*Rq z1O}7UJw9!i_c#a_DW*P0End|{^n})4U0Y#&{&O6yUg^^f*A7$M^!Kg&gRVh3cX;rh zai)MK?rZtW?buH1;Z1g*^7A|T72gj1rB0FdT-qcrOrlC>hU(4#N$*a&HNZA{Pe|?~ z_qBK~^fIpk_6T)d(S_%T0Wf{z(7aXSU&UbDJn_#gWs{ss&va!Ld31ENw6yf0UIXT} z<}gy`kJq{zl6QJH3z+6oU z>zhxZ4Yt1@`2ET=Z}AWNich;_)3|tE(d1 zK!#K!-p31k1ctH?_dTxn=sw#5qBPO9ZWVg8w~}33&Nk1M69MK06E+`|C~U0716Nei zisAd|Y5Luk`#lL!q7cc;OwtskM?be3acO`<{v$T9&h?gjJalFCmjPx}CCz(NSlCgU z$P7pSV^5J=Ebt@We!|_?{be$jhww(>t2#$^9O-TF`2o)<)@FJ8HCtOe;;SSL7uz2G z1d{^K8#{6|j!LR@Of}g^rCyH3Vx)7tH@zw_x+P783oaPct+(u^I>0K~Qz0ne-%R}& zMWEIHyWti1%nqN7e67Lyn(AuT0%Bs~S$4779})stj9i%v>0cfFx0Z~veL7R|Ci;8U zt{f<$EG~>d_vT+UoGNl6`>_H$B$Exw8z6U<@AWL;sA*-J|@u;oSEUUTl6P>{nkqyJM8Zfv1 zM2_sMtJGG!)N>k+2sK)F&|fdDOz7kQYn08DR=W6()D6z48d8+Hs9RGSI?*}$?+irF zO&ESWR-&O0r7d-CSA|(dg10F96$bLW`(@5v32Gej@80}Z`Vpb*)oocI=uolpUV26> zx$BjMTcYE`oxevyTmoW#9?TMF1)LkipIj8M`S*qWI^?6CdEcXHS;3lxI4=8rMg=HI z#o5-;txpW`@0+Au{oEeA>DkiwIiQ5~7BapP?mlq}6XD4?{kpM(Kd2Tzsu(MJlHrT$ z8di+s0t0L@iD)qnzvf>tt^n{8^khl)&RklUT(k*REtuPyoNRZv(Ynu!mfd1bA{5Ik z2Y&p}MU?nSwrC}%q}(GA@Z!29jE|-+_LQ5m5qOK<4k+%hQNXZXn({mqI}oz=cD3F1 zJq=eo4Tv^x^rqjcJ{o7!50O7oB1qWoPR^8xbV;fq(w0p-#U~#3M3$eK%8lsaf&{^j zoWFQWi0LxUMW0dBtk-m9vb)$e%*z>Ba;A#!~kSif#kmfF1JOiuyW4A^|yU_fz zD_Yb!c~()l3ayz`%e=GG3azvAg0}M`<_nck5tM7o4+K&ca5|Aw3&eU%*>com8;ni z_doYA{1l|-E8o->gilNu6L^1fR*&gTaRR|6}Z}qoVxUwttY2l1}Lm5D*ZQkQfOGl?Le+k&;Ff7?73} z5D*y}B_*U07&@hqR2qhqjvWUOp%$LO@vNfswpO#+rv#O{r|qS6j=UImj&!W?Mr!^qIVaBHs=^ z={vn@bd1v~^0U;9lbM)hysbSsN+nr@?$P3#{V$8!l?^Fg&Rue5;AbBgdiJI~`m>W- zNJ@h{`r$YWQ%~YaVY$V_yj>`DD&JICX>eU6D?cJ>+eHhlV^nzb;$ePjejLG-Zu5@E zB-i^A?^9$%|M5nfcgY!|^78V4%O`iQ(qZ|dCkEvX5yCxJpVm#2 z6KgAj;nnB-SJdriIO-a$S;PO@a{XxCs-W2zZK(YL6?jrgp!d%0MVf`JW9}8cj9*dV zBWL`}sB;1Fi>6!mKTa?^B{Waq6y?`5oM$TYHPU@&xjF`&h)drOto3G{su zR)iMYr3ouCkkr!<+a@!gKYO-xE7IbTj2a4Pmd`9pMsoOqmpw9m?8DsMk>P}&hxb+> zvsL|ONSu^+zaqc*g8qj6s8VmV&=e7dX{i(E?c!jja4AfhK25Q-YFX9(%C^A@w0lWu z@VPEm?<)aarlHZ%;Du2Rd8WU&alNqx4aT11+@d~mkK1`6Hak<$p$qfL?O~_3)=@Pv z`nB&Auo()7F;1ui*{bw;^p@iG^}@IzISuSfQ_=nvYiR_+S^KVt$l?Bn8NsSau(W%?JN=MfuC*uK5&Q zdSm-T|3gW)m3Q@Bg=J;K?zg^=CSsRE+&omy?}ielocOV;nY{Ua;p$nQL&U6&@a8sH z4Y8(UB2$tE6FvJXHCs0i^>O;UEv~XYbYc?kTd=*{c>bsvWeV#%?_?i!=fJZdQGGO- zRpfUPEOszq4UCCa50GogILtDF2=c4m?9J*qnq=@z({Fn>1N{VNO|^V)!I!?SUzE?$ z_zKiWBPCJ)ZUVbh&a0F-evcH4oTYlM@yP$sm*n)7_Ts*;duvFplmWOeA9OV#y;naa zE+YrzY@;g}j`Q}qS*vkM2!W-0?-kA?w4)SQ#(8L0Gq}Nas6|!AjX~}Q=r7Hy9Re#l z2KqozFih)#Myc*vN;Q8MK6nAXt(Zo=RQh%x1D3bDebgmJ6OK$17rSLLVoD^G)xWNcBFt497h^XLyhZ^n_{W0Jp-u}~uhwm_r_ zvh8_wu#uSTf`S70$kq}C$J99h&2)cfi8}*!s<-&dibEzkBRecS_>BE?9Lzp)_xb*E zuR1?;ts5U1d1|CwI3wO*@94-(FT7RHz|8DuXSmBF?%jHqwl|Dk7mhd@+r0f&a&}Yk zFp58vkl>lalWrc3E@cPngfxMuh5YhQ2U7y$pT9_O336BT6{L|q|F#~({0flRz;?@g zobAWh7`rl16<2~4gU9v`i+oopLKk(CfI#n7_kqGMbFkI$v{VJ`AE^FTcn2@E0Rqi} zN)-DM@T5ZGjvrZ-7k>fhisn_7Z!D5dhg%m*8)FySR4*-RUiAi5Y0$g_hm7e8>ilv1 zcT+bdrKBP`9Ex1(4<{cqLg{E}KcuB0s0x4-D=H!)yMYSVz#E*UOm;>W1M8TaD(&H> zfTYrMwCqun*s>=2D(kL1u!Nyy&yT^I6lH}z zgzOMiUGf~HFp*=euYb1Udv@%6-2*$~%}ptN=Y_SSv&|%Ux(VEOb4#YM*w7t|@@Jum zvS+1hW%e%tu!mFE%L&B--|bhddK!vR`v&OBmbZTYUOxCL%Sa;2clE|d6_zzh^91)V z5D3G`Ve!RDF&HkgQI0TM#oD~t@>aZ9#AatFUJ76%nScHC$qG2RJf5JR3(y0oB-=)n z#CM5~)CCO_trzew=Xa03?DyzPm_5JpuO%nJf9qGB_)72T%GTgD^}MF>aawl2KUV;_ z4O&mpCRYB2<2HdySr+;rkLM5^jT|GOde~4zJlsrK6?X!^ zzRvZaSiND(>!y}Q)}@*jhziAen0c;D(mCDP>XsYmYvhQ<-k@0#cpaLN!5Yd}Y$Ef@ z<{hXDK$xEtNMo-iosN+{=3&Bm>`9tg4r>3dZ`8w+XI)w|8zXsIGt%d)YAp*xRqI9H zRM8p}?+jMW%F+GZ-0aG&?WopJ@q8i#Vq~w zfJ%(-kQe@?5C_Z0GTz_M16O?t;0S3eOg$(^9hz#p^P|^{cN1vd4C3==n^de%D2J*ZqFqll zS;&!iRa4U$z%K!g_#NL94LsHaDsVwdeP3JAG&frKJ=0S%k$Z8)2_kRZfGV9=oCQLj zN|#vJt+q|JK?AmRmsyLJo>rm}@`>mTI4wqhkvGCyzt7c*2zh%d%-6Jg#vDAU4pY?eG~q~fUjo>{3l0_R$|dt&_2Vx z_4pueJ0NxD0$PWiXy2dNL8RtwqN)|_zqHfG#JX6oHBS4G49@Ya5x4&~EBA)RzB~8@ z*pzYRjb$mW&unc8=$mkX=J=TrO1(840^yK%1`S=<(r{Hd+`#PM%LmZ~0#+CHm0C#l zm*V2+%4;u-_DDy4kGIWvh?A7&z1Q$Q{;rj22y`-O(xIXB1agt`(){uxM`VTY4j)8D z;#;knH7I~>dMIusD&99>=Tv_*4ccK0;QeQlL*t~nK(7r30SfyJiuow>f)rg(pa5DG z5Kt$~6*-~O#{Bw#izmqTs|h&BJw)BYyC(^>J)qGjXv98hH!s8^C&RnsTD# zrgjFfUQX0}9-5c{(7`AsHe?09W|e?E4vSCL%q2w444_{c`SL(#@hf}pmgd{tD<_1` zA-kWY88F@~Z&iLMCzX9q1)j-&6FgGQsQ%Sl{qGAy8?v4p2!@5g=LO<%eN_AFFS8q+ z^O38I?25s1d$xeG!HuWz3(Tf?8hiwFIkMllI603^WH=5|Nm%9ESOBXfbUuz#75Ltk z&Mw_$H%g(1I$1z5ltg#HFY!Fy*&pIay@i=f@s(z8uQM!FrCi%%U)?2S<%tK1?wFY^ z0q`+}q~Lyc{{H@*2tjfk5X3~qV@m#vrnIC>Q-h}Jx4`m>ic%Qp#{-K<$g0~9&}cN? z2eehv%-DAgbcvu*`T+p&ej1pVP%gypKt~L zp^|O=GO$)vP@;dp&zJ^)x*)ZZ0i9PRlfQ8fPI+YqTFijRlw@yXla!pCrJ@ji%AkW$ z^jdsNcn^FXPsAT#3IUic0&_Y1=SSYWc>`8oCKn&k?<|{`kPx5+y*Od^+1EJ1+(i?7 zXMX(nf!4qT66w|(9VH==L1^?)Z#6h*X_dFLvx}_xYV+a+6BAQ#tLwb{Uk0Yk$M}E0 zAeq|#$Ux-B&i_I~{SU6Dt~;vrdA6I0`D>3e{n0qk3ksbIy~nbAyG<*#SM%3v>ZA=U z>ymaR)*fv;$LYo7;(#T5D8`+%k2hborgm76Tf_*on%3={ojH^u9^bQk5n41&8$G|k zS2@HuQ^pxXWLV?F z-=0hi-(^>Z2+``2!_QJt$@!y0Z*eMj?wR3Q2aKN;ZQaO2`jVQ8UDx0KS&imhQRXBt z6S=*RghVeb=U0d;it9Tds`5>oO*e>KUPPJ%ei-uH!V@*Cb+ zceI|Xo!i}W)5w(4PY1vs)lsz&;5JR|^;>Sxy~uza3r5mrDzf^tB%A}{&mn53+^g0= z1u=YgND01^C;E=_8n|O(kP(JFks^-Kt&gIzGaIW{k3$h0TERxh=?pvRSFIdE?Zq&g z^`(7wr;K5`S5DBucFoR!{vm!A0PG74*$x-6=y;q7lXc)S+&HTB7lDqE%o9GYy}uId zS;SS_p6#>E3-KSBYn#F^xye_4zUOtUQ5l^oDk|(Wy0_LDTaAnxG-w^>jCpD)c@o*S z^_tD&x6a^=kSDfK7d9wr@{=JovSrv+oEQ*YN!vKMRUbUw^L+YdPi{=CR>oRsYDf(XBJpQ6GO(S8&mFsUV7-n^@ z<0$uaZWI0nr~Rks#cwZWyQZ&BuT$w(j#`RgXhv%yLH{oNwR2*I@UzypB@s*zg0GDB zZ^*a~g`}Iu84ZOC>YXaMWJM=&nu^c%MHRn$uFBu(t7t;X0MF4@gb-PZV`P!4PcAW2 z;Mh1Zz_qe1Cz?`{Mqu0bxQ%zMgcsm~#6WQjORcyb}{% z(D0p=Ws;wfW^OI+TQY&RPpswci)-QM0(lD`+`)XmmB`1Ri&I9XGT?BI`rXCzr{-!u zPG(OTG^d8|swIik5x0ZOno1|tAY9m;J!>pxluoUCXeNrM{?g0z4aJ?%$Y{rWgVTvN zL%y?J3VLodA-Flnk(o}A{tfgcI9NX4LC{E;E%(EReNKA5sX~y9lMzqS&X`4SqfZ29 z@7VU9ye=Y$GR5jndWdIj3K)I^aa{%Mceyg1C!qlN_VWsxpgc^FDVndEe@Q~wK@D*z zE=ngTa=$TTGdYk3x^y%Z-Gn@!oC7r^G$&;Y^8{`iOw9 zkgk8^pl$0pC#y>kJi2`$PKB{KCI{3Ndwc@kL7z!${TE?I@-3fGqa;jWaLL&Zm2SV% z!Wt&}1eY4)w-{}Ymr{t-(oW8@7-Cjy*6*FhB*I-F*8kedoY8r)dO#NLkbHD+;dR+`|JUcFR^yL zPROzwcnr=j`0Dj>?C40Go2*Og1U$lSnNT{SJay9HeFq>A8W)(QV!;2WnaEaW8`ub?i zw74>Nh#WO;;bAWA7bd37+`F}cwCY3YOwyg47OwB(i$21hX1zoC|S?9?%MQOteBv~p5{Hn@_qFFI5va%)K zSX04}n2=a=D=-U$#w&aj(|J!5;e~6Nvj@xM9r5s&aXXgZfbmM3X#7>&(Hrnd8 ztGRympqBm6d#yk85|2*_yV8-D_N5_E>m{b+2xXFGj%+EdZU%B_=twm_A(`6r_1mRj zA`{L3nE;=&{0Ix!Y7b7|uSMQFVeKW<+Nl5hC^P&Jzm+pS=<-NT!sZIIM=SokOn#RGr zHOavsK!cMvHFvc8ZC|-+{m2P2i)M!5U}j>5oDuPB{nXj?a(V^t{02lP}#H-Nekt(k5B~rjp?K{ zA|Jea$B-}xDE7*}xn_@qJa({qqZ;vaN=o^7E!Nx4$-n>5DfrBeC~Xuh;#irjNeP)3 zxOnn|ccqnPuqB(K)tWY`L=xOI#u$0;cRH_(I-)81H_up7#e`~HYj|3|J=5r%vgqGo zx3BeEVBLF-^M1yi$?B`A<`e{RQglZwu)1K4e8Z~$7bsqt5ui6z961uvZkl=iqce7; zb=5j_Z>>#bA}KX^CHCg{QJZSeq7-apb~DIq|7jkpr_y~sf04ySI&ii-L}6TZm#+JR zTkMy?@ZVAO_vsH@f>QHX%A5I7&@%>V+KBSdU&ONGkK5@Xk*&*FJ2l6z#vzYTIQsD& zOc0D1hJx>GR)zw8YvUfS?I{>BY3m|>msc#_v(*ePSrcVHWjbydoOP40sGbj8EW^&G zQHsVR!41X1EMXh#*W=$pND=24%-v=#1%V|UZ7z4d&epY_*s`3lRJ!gl(C7@XEhrE;0S-)zTL)Yp(?JQ^h0r}*tP`ClC z#;!d4O_V>55)o^OJ-l{2uJ18T7X0fa4(rrzy8m&qK`_Hw{4IS(66g{>KRj+AmB#9t zukW?+`U+9^K=5Um8{3guO@p2OKF^S!J0IK$9lns?VAupte~PXFRNJqJO7FatevMc2 zYxPD47TOw(No_D0@s!>mj83W<@4Ftj*M5Hw$gXdXjFu>V=`~7Nnitt`#$xk?GSqL^ z)5Ub-yWg1GvqlfG@U6)l{kfCEb0xbkRxC48Ns#2seQI*{d$L8)RtI4L(T%iA?1MQ=&z!tOC)*jAz#kTl>o}e z9J`I_^)A0y=9(H?he>Wy^LxTx%STgNhFLU>Zz*RLo4{&4xl#dr121j6-a4EK%S!Vh zO1HqT+s{$`2o*Arpp|eSCoaijn^EpsmEsr4mA!2=*LO8*-M&ekaaq7cLrR8@^f2Q# z85{c@`Mg4A54rM>JG|j10muIJn0{r^x;b8^5H_XL7gMJe*7jv)0Upb=s@^z;{YZ)& z?hotlwtsH@;a}YuD`&XspRr$F5c|2zocZ@KN*+(C70!|{xd^=yv&cTxVM7vWMlRbJrzMAJJ===10z;qs>iF*n9s zQ&0s3PX-%UYhT;B9Wa(6lH7J0#`7$scUr_H>0>js_gQK!-VCPQCYM!eeb*-r4`t%N zE5<9tjU`*l&}@bM(?*f7*yQJd$8PM_Z?>+ZMuSGcJq4;<8V1kr*HezPdx$S)c>1)y_Fxm)HodGzu8xDN0|p>o zL?HzxorQF(FE^4tt00P#OG|%-6jx47o?4pOmrSSnrb~=7vW4Yt+$+1$vFXN_?%Bbo zF^$pGa=9m6xu?<^{%p<-!k%zf)v>$F;MK?z>%kIHD5%K^R0<-IuxQHbmAkzc1JX-E z2goTCSov1o7G-P_#KNG{Ki`H1o?|D1f@|q4{VHHQNbQXBYO7iu>>BC(01KX(pB#5#`%4wdo{5$X=@R?!_t&E{sG$dy?5>J`#3O?3EbPFxc~F55~UAhGOTyS zUd?Z@KX$L!=13xzF@`X@40P__y*AR{ma)bU+Q#mHM74kc_e;keKZ{W86**@6G&Gy#F#^n34c&WJHZ3b=P5 zd_RQxl<9%4P0y#ZjG$|wH}*_hDvEP^lg_Hpvv=s%EDMAd{GB%hEOqxCpONbiQW(3M z?gkYx_s)LNW!d>=u=6}sZGDE(i*>eF=dze75isPqe7;rCB|?VbFL~#)GDk*7&C}g! z%njmaeNUeZHM}B!wDzc`=&}l%`UNq&)tk;HW)?7aA0L&Rbt40gn+H2(ZOy^g<7qTe z3aLJLx1)ZxL?5@+FE4c9qr~RhP_Zxd$#rMXG_uZq6xqnwbSA3%6=y}KPsli^HqUcYOC-T0-Qq#@!@v3qYk;l} zt7iGD-{C2xgG?SFU)W*C1S2O`cW}I9(#k&QDn3qj`bseq>PZ=F=LqU~@(H;%G;y6v zW9L>O8GO+5yhmBJwcqrc9yzQ3-0H%;KyYF28G+d9N=yg)+p(vXHJmr(OQ2qFsgrzd zN-e8vZK+JNm<=?+Nfzl;hG)c?-pI(&DwjZBPSRtmMTZ&r1No zLM#Y;4z5ENSp_JiB|nr&++1u+txciiNNVO~&>83`?`~J13MtzmeCGGXyVTfkTjI}= zC~A3I2O=mI)>lyw^X3=5Rz~ZcVOWK z_c)Zw-*F}lY2W&Gad;-wjx1)pWVxVJc*#YSwa3)M9&}Jnv8iUE<)UlGjCszZG|<2Z zJRJy~vCAHBz{ulec#TzHeuM;iv1Q@tWktJreJ@>!;X6^g>cSMDhM#xigK`cMdw!%|{3gSQqp=Mi*kWJ(C0iKl2J3p5z-h!KprKDmnoEgx4L@<|b zlz{vc`6O~ciP$NA`yr7;Dpe@n>ikez8x=uz9x4oLdWbK>(5^YL9h#jmv)mesRD<&K zhNhC$XLPv7Gn?Nz1L#LP&e*u0g=3(BAX2OHWY3DTv>1JBbkprZoHys89rLzT_DF@Z zjVFrLetN^xt>3Taez-a>Nywi48%{TKg5LWBZu!6K%m3Q)-$Z(- z&=yB?LQ8YKedVSaOb2y98ro%ZfE%Cph4cYo*U{)tYF7x^7Uob>F_)>Dy%r#`W2~l;;&&1&_Hf@T{=-*WDvhspe|L_GFmd_ z&GxnAHWNBW1r?p@`x`VDTg+H$fA8(kV41Y0Z5|QCP^sUN&;8Q?t%0f0f!o8%%B@;2 zqA7gc_wAuByTCAbuVtAh`(6p{lNOmR`IKt4d8Z*j=lIxep-jS}e^^Vwn;q(5=OT+& z%6RzT{x(en!UI%{^}#$>%{tcFr`d&7e><(Uz;M+_qh}6m9t*M z_$_B3i#;^tHVs5An#*PnG(Q3yOR;DnU%_XCicqNcpW9TAN4M2bSAZJkvc z7;|Js%dUfI*)Kv)d;VH74MxwNZD$3M6 z0*gY1FPIgQRyoEg{XbYtXNH-r$b~!anQfHwGJUl(*4f@m3T@Kqa(g zDk(~QA+J$26oX=HX5(O!l@<+u-ZG%w>;VfUz{(H8I{*`blLx}P8{8T^d>QApikOds z$B)Y4pnHJp)EAP$m3|I7S{ZR>fn%h`LO7@Bx9ARM>Dd`egCAT(`WyS9q!hKhBY(6o z$=VW8@1thXdFv`pko+=bZi}W>*;h^jVSc7oh8Vz8&g2@~K8eXp-wmFo_Z?{f|m-(nJ&;RDx{&+W$InU(X>+b~{*Ue4xLfsQbOCw=A)9Cas#xfkF1+be-vr)0 zZ0txX8qRqu7DV5n z-9Ld?U`FP}Ts5>}VWi019ry=!*+ZT)?XsXBad70#(pxb7z#zXk++<(((IJ^spVa~5 zb$f958FEy7UXMoA>%A~KXIe181$2IpEcEr|mI;XM42*3K5z}?NchOK(MiITbG}+UP zR0IuT)$jZ}2sQ-s(CJPPDOGc?-RqqrHIr(_9z$K@i%K2%V_$P{p8b~q$%a*45B)sQ zzu>_AtstH=VqE~@yPjhra{;*ZBdA~;S~Y3ogP493Pf^ZB#Rkvk2MMA#Ucj!`Szk-R zKq1olsWhie=TVB%;w88D24 zgip6;4|=1X|47cVhQu`3gH$}&7yz05emy153BS{D!b^f(KR=^3Q#kX91hZCjw~HoK zD&<=P`aE!QtV#-{$jF%z@t z+uK0iK}mPNHF9i*#2E;LvV86B3juehuroNwYXQ+QPjh4IvED&)t*{IwK6YN!mSGQt zh?vr~fhsj-BOoOm-OBMo?)_iK$YwC(>++ zwuBfl*9TTIi?56W-S2ixO9)A_+aXZka$lF>qE%QtIxib6+zAl~rBT>^XERB9cZ#lV zz1DTixNMeTRHA8I3egn|b54LeYkbr|!I5hZ%9+ItEWyvcv68UeG_Ttfy|S#N^N8b+ z`R#p?4*<^fkN#v90eq4ng~P$`nZ=y^Dw!$m__)b)8~DR;g6ki!Lc0N|M3#>kuQFB4 z#DVv%&NRk55!K!&9e;53!fA5o$Qc8$2!oqSW?Xb|NlG8b95tM^ z$;nXAe)@!(msjf8ok7kCo6a0bCLFn^xSyOi8Z4guOpH7Ud9zlfKp~nV9m}a26iRP* zv*|BC=10cCvX>u|t#oHnDc7T(Pio?qK8BsWQYe*eL`Ln1w7ogGZ|(Qnstp{me*ASY z6`_dsZDME97kQDeX_wt2A;@&xVN0!!zU57Go11M!bo4CI+Cps@3263rP>VrRTV6KU z?KYh-i1-RE+Xy=JQ~n;%B)w-aoj6F2OTV~F|7$Fr_4jeOdi+UfhIoQN@G2KRB94)^ z$5FuDd``un$yIRRTp+TT_{TYsj$_obUF;tq`lvL4d}9W!H?z^N7G+AiEAr!P!}@!v zM*ZV`^yglVr*n!*0s!65f`I2!?+8MEfLV+48I{AaW=c%L9 z^@?XcQo2@D@Pw=em9z_Ke{HWpWH$(XDn2is&CdYd4$kU~LWiw~M!ty&|8WPJ4tAs*jHKP|4I2 z>w)aCXN_=ws7DYjRaKh$Xn?Nnu}PH`n@A$5w27mOrjO;F*UF1$SWI8>dfmJDIlcjD z+#!&$KgWPvw6?aQxj3Stq6iOPTTouyt75iBBvd%;od#Iw_oYBOoIRnjdgn3u~OkuvQGHoB?Tz5u;3i2CzmUh1t zAf2?BU-WLix~QqCVURZpjrH5RJ~wH6^z5~7R89jcMn&Rj2fS>p){a_euwF9ls6QcW zunIk0fba?rslf|W1-#>GK5Fx46*C~uxy1sB?UyK4EY$LL9S~SO2OBtDzLkR7N|>wr zgSniVnpd8lwDZaRS%u)x0kAX!xoLKN`0fXWq1nx9YL7tjOZ;VuUg)w`{mo${E?9tq z5Mn$H{{KP$^q;KwHDIT5-t23ek>I~t^k2T$C#1QQc4KZm+0H>!?@7P4Tyo7qsbnpW zAd619dOiy_I=92-a;Ea2<@5?-H~=E6VV1yY z>9X6UF|sqRI~l?I{xA5=I4JuRf1IyF{nZ4eM&BdOc@mUb7k;qvCc#c){8vnB*nd&u zWB{2Tl%;TCMx3iIF|b3qrDF4A%E+?zLzzDcQ#CxMvC}tDM=8~np2}62pEZt1>UW#~h#Io>H zn&y%h9h1#W7Xbo10pxWO#irBm03ADu9XT6v&>#i6!ufF@lp=}w{#%?b*_7=YA#!VI zUtSzPo7kp+*Qq)%aPbo@>|)*v4~mQ)gh*epy0h**OFXYAxTaFTi8q`yAq;6?G!4UQ z%%;h!_g=rWvcAITYSBewIJu_w9xN(kOo|t5n%xpmlPMnJvF7w#VkFFB+`vefl6sCaTD$LUbHRjob}JA0*3EEH?V}h~27VtmpB?=) za9=n@3~e#!{wSO}-kXps@BhyHML*dyCIu&Xmm!dfjYHu}J) zdiU2+dM*g^O}@Tl9&2Vd&Pl`j`PhTQ;q;q4=|7|!R)RNa4GsYAqZus+-wQJOwwE^_ z9()VFUU0s)v|5F*{Q7knrJWjG8P#cdH^a{}0aBfUj&J_j1}%P6Ea~1aBziD5pvGXy zxfuZNNcJUS$5Ko0`RUTpe$J+V=7D6j@6m`a%P(rQM{*wK3p}75YQO_}clxPdh~;}I z3`1n({xUE_XVq7t3>do0HEqme0}sqFMhX8A*gqO zW9oM*g-;$8`d(2 zoN@}j;S0&0G&u>HrxJB>;f0*twKJ{A zKXhsD@Yp7O$Lu>?i3QWMBA0$m9Bq2RlzuVf5CZ`lz+f4!hEwrLt{k{5mRN_i*c}H_ zVd299v2#xpOTaqyZq})&mxA^K+#9XpxL7=LR&PwUDGv&C^BM(dSby;ruijmac%ylm z7i`rV%z1rWU)!UTSqj68ApaU!s|Re;5B3xO?%8_CN6XMOZ#;G>m}Q9^j(4~C`mE%1 zH84KTXT;(cO0-vw7&ur9 zOA#cQyx9KF9()ixPa_p_rMqHH6OtqL0BcQ$hZHaK#%=qhgL5LpOV)dL?dXT{gTLHt z@J|Ae`ZO_RsJajBj#7RJB{ZLoWnr zjeXlBG9K%lsb_fTAZj&2F+p^`hpqO-3UaA5-JphY(42EazvNRS+_KBH~aorIRqy@wb}2n?2j z){2(llUu4WwFUt|;Q2|H|Cj5PYx07KTJ88SQ{-F~<{hDNPf-?l&P*A6d)O7)JqW*` zIoz^2Fs;3{%k>BQ?Zmlvfe{h3eoMcRJNIB z94Ffy3)1|?ITlqHSP?f9VMM7|2)wb(#DlQ4#Pwa9OjTz1fdM9c6;9F_CfC}rW>gX4fBkLe0#$VYH)W0&rBS9I19Et zq$K6ny(hVwddD{t`=%V7naKMN-I%xgqJ1H!-Ve`CthRQ8Sb7~@&2Bfe4rk9+Cq*tC&<%I2K zs^5FUAoboh4@X`G4`kf&;7$h{#YaxR4R} zBS0Wd=C0H9gw@UEFIKXF%>URdfjQ~2{f@`}pN;y>tu1Co#=CD_%z!*!ks55iMW%_y zlUqSEgcqa0aUjf|Dhr*oPRbh?mZHXZ{rcL<3N0hbiS>qM z?tg1fghKsPKHUo^S;TKEd+8=)wBb`#qVHKCf1{%k?r<+5P4{;-kAn>$t#q`1Km84I z`lcqo7hEY-F?^|NCick#L|0WiPRUs{ ztVI7}8+>3_Ozr>v-KlOIosZLHMv34#7t`46+Cm7>5HpDR#fDga#@?&}wunluxMPVw zMoEH(sR*gjxt5S5*vF6l8$(S0?U+o*sU}d}czt@4w1km~<4@pD2-!Q+P{G+8$JUdS zL^rMea3Nr11>_+H^cDPvVGX6bWW>OK&hgD6t#p?Q!+&|;_ahr!nRn@mFZwy3Bg2^}+YNb_VA9m^EJ zw5eFc03t8_b6eYokA2+S++M!iBR84cqRI>e_m{^b_4{7kW#F~!Q~yijBmYWOmU4KS z=_1i03A_8+LT6{_&NKWY!dh%jLjwa~#IV6S{#IMdvIML=qXF<^+e79}<@6Egl#Flm z3%`fgfQ^?H6Wh0#^ixoWHRpEqfrLP;zC1tr!6lKRGdeB)Hf>-4gNnq<-`SCIqthX4 z2(E!EQS#yVKc4m^+{e^!4)*(oVt7?#=cZ$Rm!71fN-7Dh> zei?A{28!O8?SE=@IHZE*r zq(m+!nTEc5m+vU~A!c8)hOcPv3d`S-2k6-Dr?Qt~;P=|0TXVbK96*-#pUIm4!ww6y zlEH}r?Z0ive=5pW{%D3&0r-#9U}EOv;qQB(l$js4voToHU_JW4?3}xkKncuY&6=HJ@mq(Dom6h_ z?yvF{#D(tM3B0~^hPx(+@c@8>UOGAofc;92=1~?Y(r@;eg@r!?CstC02LpKdWJ8@m z|D+9%-dY;Gy&!HU6$PR$OG|H00)sEGo|fZFYkpV8n@(tTnZ(BuTSbKLuDBhFmaGzW zdB1hAHcXw}^=d{@O$<=UeB2@XD|oBQl&p?9D3|tZAMJ#LBD!=;O-V>Lfzu2?l_#@1 zw~lg%m1Zyi?1>`NA3e-1K%wCXNnr#AxAyggkOpvGp@j~4dYa;aKLK)T-s1&4qjU#G zLST5luhC{DW&&8w6$CPYMiGAH=!g z+|OuPN(P7z`>3P9wLhup?Ao7<0c;lSuE#-dAl^%RZnJF4g%A&7q@n=8W3YtXjOghq zE1+Ao!Q;*W@SaN*=BNE9&>Sk(F+utjIK>C}ss5u3$!!BK-DSuYF~=r&T0&q0FncL? z*dyB^?IXmu?Qb<> zFmtkyS}gQ3xhaj`1a`_g6qRJOCiSTXdSz3pz2QBzvhrL@i=vOvFSpY~k(gvi)czs( zJwbD5c1TgU86-QTD7d-U3NGP!9-#I{A8$nr_e=M6AxumxJ=ce4A-QSbeZWnz* z;lxz4Ja-wXHB<$X$w34eI6G==yl-jAUflEj`*+%6cv{@G{pjfE#4}V5#=!dhF9XHt zxpj~5)6a5=dmv(B&wEH@LUMq46m+kHAKggAfA944DfWYh)QC9u?L>y+3iZA3?ww`SIA3sLhGVwIh?q81FzCBEUNDpQHQNdLwk*}0!{Agg($RJWFsUki4%6iU2My?qhWCu?CRPCzt$9CBVbqnyQLETwKilLUXnvZ6nt` z+_3f$a1;&(uX8wt7PVhlFx)8r_yNJlmM>wz;UwtX3R~j22$T0AOf4z-UAwns4k#W5$_!!{W8z9 z`Yl)Rtgl!*mwqDEv@Iug|5m*HDGitisN~RoO@)7^{!|qDaH0BUmppl}I`&5)qc8-~ z^K=*}B;`Fg@I%FxNiKW<#QbvY5>MWeHg)dG98p9cT9oBIL*_N@8I&t_)+aEVN8g0d z%}dS7)KET2FuaImMNeK)>0<66B^iJU7RJzl+XqJ>6o!2OgRsCuaW?r11PcJ((mn|> zF`LbK=d*L0EwzJ1!W|kQnXn?4)#h)y_w4+MD1i%e4UN_0uN@iKow~a&f^K<= zuEIQ*r_#oqbVj%MNG*cYXT{>#XSYfGS^2rMm9w$fji2yv2=mv(U)5>YIFWeV+yuy^ zG$zLo&eG6x0+p`>=1r@OdzrD%;13HN^;b13H`5%T&klQ{T`Y7!=M~sE{-O63!JsFm zCLeu&mN5pB0zVHc0h+EI;aAGCdM~YqCL&%V>rY?uuK4?_yRRpvLaqa{wmEGgWMJh$ zw=Upx2LO%-Vm?sG7MgKCmlO~&`k{4O;{pD`Eneg9%JZ_`Xu*^usl8$V4&>&#Cl+Ut zeYpFDE9W9dc@a}q$2$l}B+zsm=QUZGl0tx!bH1^&KlY!^#i{$rv+Qj!*utg?U(RJx zXDIvbz-mN}`LO=?%#$}3PxBI5hXCAd zLI+kJB8bo42&Oy-?f;?dt)rse-nV~J5RfiKIweFGV1@O;ka`+e54p0$2|o^{UR%*=bg_rCXaU-#>(ACrdvDds6{ z0OV`2?A*pcnaI#i%V6&By+T!PDoVviH*9)UQi4EYJuomaJ&h2aCNOLJDFLu|nHadP z^yK=j7Yvj?*r+YESv#%YdhO7hNYo=UGl|7c5ph4in^}Qz13Vy=4X>uG#J%!uEJQs8 zi?_pjf5owG;-?vC+IU=-ZN?34|4pml2h`*nLoi~sK(#Ils%PE)NvXN?;UCvSz8Xf{ zp}PLj*PX|)u1NJp?c(6C)99pfp%^Q(=fN$`E4EvlUW~Lylv16g(*q?%dZVG>m314` z#-m-H6qrHt=Pbm~MhvFt;MnR6{89tC@4b=N3_rbO{UGXaeywJl9Wm65#6GYJCgjih zorDC`sQ@Q$up@=>#)a>)G$dGB6eQ9yE{({{U>uv~!tf zJF9lt87P7qzgLyMzHv?8zu`9OZZD=-rjubAln4cy`olYhqW6`G7>D;o*zV{yM-GnI zl6(ZR^SvB5yTgouU<{gZc)$H?HSu^My0kr-0~M*zoFZamXfejsH}NvXkhmGPa9irn z8ft<{dtUU#C+0hKDGXfqy6f(dhTaGM_z+q*2HkdyCWWv}nyD;=#n z;Qg__#9gmNg(c625znkgnLsV01@Zj^_T-UZFdRj$#9?ChY12d#ICnj8%(t0KAp{~2HQ zMHUUR4?NwphW6tj6S_1ffxG+%mn_Wf8da?yHZYJUKSzMPZUO}5ZLL5Sfnt@6?@_Q9 zIGk95XzlMwJ9ujo9~#46CuNko-8noV876@|CHjYsmW(#kCmP8V_czpn_tao(_6aS< z?@If@rA9L?mn0}qUEq%uf!P^dr#-LT=VQ#>rXXD^77ftN)!H{XZiXgDN)kpl*@p{Sn5ZzO+tjg}57OpR$7ZGyQU-xfgYTuDWDjnHcCxYiEN7mZpX$!>gN52Kv@38y3x*pi#z#%m+9{dyO<2 z4KHI)JG6TOiik1f^O_&K0gY`!pGn=s%cbJ|=VEd9->FVJi@zAYGErFERCj%m$t=6bf%*O& zeKY+>HcLL>AkD4&;}h;zb7LQ)6m{F=Jx-Z_yuFM z0k{D`b=2AevtfS#5@xfP1=O6~>6ku=pe<#IOZt@l@F8eC8Zd)<#m4C96D6gduU`Wm z*$(coaiC35fB)s$7pNgXhIoTpcw%qB!h(f*3;1IL4T3o!&w#PImfwS*N9eHA0jGYS zqi@?M6#sq&kiyUmllK21g}r+8k@0V8G>|7aT0}$d3kq6}KZ*ylVli|eO$u}edYpA% z&hyB>eXMSahPP*MmyPkbz(NeYG<4*Ti#KkzyF_*_iB_s-r1k*?M$!u8KLhp!VAeFq^) z&&G*?&*fy1)nRmeyuD!llz@!<)u;gMaBz1DHGIP_ARZf^7qd# zT&5>}{1}U)n7l&(uXT1pAPf+Bu+sLL4UrU^TW279fy*0YFN|iPvln~>BVeQ|Y|mYF z_hz4MRTDEx5B~X^Y3I1M3qs~A4Yq$Zx`LYv-&b8{OPU!C8)D(u$^f!GASVXicH><= zL?>6Ff5${7+0GKLzeG^_JWK>)c%NO}oQDADVm-ujyz!PX#1Yr+OCo_}CsrH-fi0F(m28_uV{uh%>M zfSmb&Zv51S!Jan|&te}RZ{J-v!UCUyg#zq@u{7G(Pe2@XMqftB6q%Hdtz3C^d8^c& zpY)ob5N>(<`xE#0%#3}rq2+0KW-17B&3^+@*&kXszPS;Eqs+dJfYM zCx06pyX;}wpu9G78Q;nt4?>Ow+t7R-6Ph-EiT=S<;L6!Iw9+0L@#pBaK6ckszc0U; zXRJGQP7DtgmBS0%+(8X4_{*kz{ZHx}#=nrT*LyT(L#TYIh?b!NlE?;E={x8z#s|LG z%T)#LagnR%d;Nd2!G5o1zkfdoBBHlfR-R2DOGdGLYJG{nZ-wi5(!r%qMHHvL$q7yU zlMRpz`I`;!$8OG59e;c4t;tpjNOPKgf)4qc#&{jWUgh5PfiQC7dvdt+u6vKN8!*y0|MVy^QJ2_W zyb699Mw9eJr#JZ<_Py^f9UW~n9Y64r3R)#$!CsNie7}N$jRk8RRnr#>XM!uHi~r9g zHphRc{RfBa({>L@=dhWhI9L@(T%A5c9P9tTWR`(}uF9Vkwt%a4NNJsF_)!eHMPZJ{QH}o>`n5FX zcX2Y7m5~u*-7yI~Oj2lwAg>hIk&4bdYrqbH_>2B3QqRo$MzShOC+7k3pr=28`12oy zF(4=YgJIwZ&>cNIJ=5Koo&zl^Nj9L>djn%wsq>*IKZYO>p~o~lwkAPp(iI;5YWI=Q z&dpBI!N3Vx(&T#f%Fj}Cfb8Cn`#S%m)SK2*TLh3$kk-}iKO+%m+j=)OWoUXykfn4d z3dtp(g|i8M=jhm2&}3O?#t4txa{sf(M#5Xr6KlMP0fOJ@;5LwU4_xd0loRE+*@o0AqI-V<_->n z{Npz`$3_0;DFCjmHd=eBKm4<*wpqsv*s$}azMwypmXT5L7pZjbwrM|!{hds{;EGmzfJ+zE1eDapb= zxnpfIGBSd&%1||nKTqq78lDhQUNie_Ge8~AM9}9oJsi#iR7_%QT~&ASO%DrK{O7?Gh z$Cb_rPHzS8wmCvT6#Q37V~2WyG6fLt{|~reCif!Huy(*oGYI_GpHKGR-Q_=9$^V*2 zJOQTPyT~8nU=*4NJVbmlb)e4ut%G|1(gVTnH`R2O#f>%@<1^QM*h8mJxH>sqwd1ZP z%kdMW{>HDfKDv_3`u6tjA@4=oC$zQ6j-={1a0?wC1UldBS{l5&5Oom#F@=x&A9xrQ z#IIKT_gh{F1buFGz9Ri!A{p?k?x*ft^vCILtfe~eze#k-v#t(OML%-kNoMGnbYkVC7)NXULCFs)k%PC zcq1cV*BvT|`WGZtp8ZyYm_nbp<~MlIKIS&A^ku*_;8K!PL4lct;r8b!GunYfvwB zKP5mmd&vVy?)UoER;L*lXfvBhj1Jr7yso_|gbua%a0ZB8%j#9Fjv&(zbi5!A=(CMV z@qdBE&^@XXVPB&8=Zw<6lbs(Q#pB%zVOQ`UX2Q^K0Sw;fXdic8JO1crz+D{=Yn{4y zfhcE10e%RaD^_DAx9v+bVFweu- zkfS0#jHUm4jwJc38wXE1IE6qdtL(cGdLJ<603;9%x%tn^3)lKD0Or48q5pSf*Ybn5 zpB1P?87$XUX$I8XT>o4Zgy&WkPSAH%&y>FZO%K&FnWI$YK| zmM@T>&a%H6?bwIbbVdgK;hO5@Pmj}8pO$P4jZH%TP!$B7Ik2HRI#1M|;xAlX6AIp7 z_M_`Ut(G4WU$~X1chnvm-Sy?0H|N14C$n&>TbUr=&vt<)I$qeOGhRUl;$Ft)WK`ct ztkd}tg2jV*^A&FOw36zWr2*V%tDIxe-D0%r;o$_p}jIWfa z&U!Z%=N?7;BjixBy0A~n=GjmahKBYaH2^?wkEo@{o;!(GL zp-Rq{d#-Kg2GzIgR~--gFSg&fhIXJC9Jg`*m3Vq=Qw4#FTV(|MXb|m$p|Eu~_14dfhL`GlX!1aHobhMs&J{`FyCE28$ubF} z9se5UzBY%s`w;J!@K)iPJq-?F@ypRruC{MxKg@+~mVU3XyU`B&=M`%poQX%m3V>B# zktDCIR4pQpW%?Ogh-3uUkPz%FT*+C_dRU{2Y+Tn9XPZ@Z`oxnggVCq-wY?>lG?}0H zG^UvMpWj?H{GE;Xw|dU@v;t1b|=rq z;kR-;1-x1`y{=H?wg2GfS*;G65#(aqINY4hfRNc3y*_lXnkPtA>+bg3bsWm^xy)+Y zT|b$*KHV8IbtjD-TftI@Mse{U zc7$kzNKueHyh#mC_B08B(xKbN^vRVBINF9C$$kkygiBDg?YBfc$r@@XkVR0DX*G+F;O=Jlw%+mU`@(96KHK z>>Q%kRkpFpsG=xFOfEZK^5?#I7giw0qUJPsD2IX}ZT#t%@t-p>Zpul6N26JG))Q)VQ}r-gf8RSEW%PrS1-10|^!9%xMayPl z=XQQ~@cceynRO9*fo0Zt;z^C+{ILw64zGq>!^h(rs#-1jIv$I~-%6mNkngBo+G&`= zRrNXnoNNasHc0jlV$#GVhBZ8lknB^X9rEA%vS z;g)%usH7>BT!P{Im`PESFnqs)k zHc9#PY0fhPeh22KDRy~hcMj`0S2~5a%ha}uN@?ajH+)O(9QI^Kz% z#BoM6{927ML<6-rjH4#C*olwTG)F3zd_Ec|o2TDBMq`#_mpwE1c?<00avb-mMB@FBW#64!dIbRqC zI7;L|^TO{R1Ci)OHZCh_PELA?b_!)c%_cd2=>j$Y?a!kce*m`F#u{Aqiz zIvU>Ue17jOi}SGTHRz=&92EpTjB2|r$mCY$Z*OUDn1ts-yC?Zd@^kR$jYm7i75(?@ zR6~M2IS#BWzTw^`NuA)yK~x;FCnDcYqr@ik%W>}Bt^s9Z>%Es~y#wp#@3NM$2}NpD z-%;q=$LAOjNWI?iO0n6g_X$OH-TfCKZCuF{O7`(!SojuUv{To}oR>etfU#sZ(UC2o zO7A0HXMgS;f=?aTCpt%O2|pL#a(W9+>)eurwt__TAsBOaC*_XkS}K7Y&sP6rq6_am z+UI0V^dVIV;%Ty-D~n(b%s|H1rC*}#Ku5^fAWAt__gO;CM;aM-hbFNl^?=@y9Y1ns zNo!MnTewNXaLVKUY{!czs@T69^UY79`-j14b8B#cICw$%nYr66Adk|<%>h73&=}x_ zvd9UQ5n?Vrr|X<7D_aOzitHR+d=v3pY^lq%Sk*YLqIF+xq0vlley3Rf%UKvdQYk#y z!2i8+8kIN2$EcMj3g`?XP!C-E~LPv~ddDgr64J@0RVICG0|2XvYTr_nWhgp^ z>$&K@+~*-^yk}XMOw*d|WNvbMSc5NBUqU2}tMPvEqQAw5hJqHF#xLwIR_QI!c&s3Y zfsTg>N(qVogU@wIUenO^G(7qV_#|9DFFfSSn$*0~7BU_8896HWzg3v}9^rVMZ>!-N zTWUuTmJi2c36!}i-ZKJSY!OnEp1q^k$;0k+sR}rsZ3{+zB-SwR3Q_;MLxntP{Q4_o3cE_^~?hmA%Z0O+{1$tSdGGs49$Qah~}Gn}Fr zMbv+Nt>sE|~mzg%(epN3{Uzh2L!6`8>2#j+r%$T>-J0msD(jkvKm$EKx zK0o1}BwE3$4=sy;3FGE8HgKmRYLE01MtSL-@JAZcwM zVrzgm=cZjR3!wfETsv$AU>+Sdbo({@paa!#9yC%}8MWw|Ffofot4xVl=VI0){FYqrAR%4Zzw!Ho%5K3yPpmj_*R;o63c)1uW zY>bLRm6opP=NXjFlS*A~6L@#F0v-5=6X%AmU$7D(uSob|=^Say$oqm1E0;7e^iiV7 zh{o->w3E0Dvzq?6PRV5-3V8mfgh|aMqOUt<`ltY;=^>Bq{?h(qVTR5U{QBD^L&aKh zX!b16XXwVZy%JexkB5-g9Hpj$SIiXM2gw$j<8J9TEe8@<3< zvYY1FM&B8y;}mlZ7EMsznje{J0uMg*(N+C}fKlbFgVK$HKaNVSAP3xMHBY{8^)4%F z`Qng~Cznp#y-wDQbSJww@0r~9s*5eeWR#V$B3Hl+q$G@3mV4r^l*ALDS~qCfMrtJh zO^DjKz61+R5S6nI2|y=}#hQ{^Ao}yVZTXuGs5}sF64p2heILokD-EJln$!IS2s-~Q zsxu%ikwGSt$Eb@;wU`6Ze;{749;Q`mw)3Y}1k4%lOg{n}tOhwhBjbI3##4N(W|?Mk z$jg0TwCV>p(XE%5{B)= zVsi3}g-~JnE07mG^zMF;7wz0>(NFdlw=j%4T2V|1-U6+U9rkoseBYSN(szB%fPQV^ zAzPZR!QJ(o82E}fi3;`KVx0)qt`_sW`L}4vBbRy7&cx*3k5k^35|&>X!;46a2popE zF{|tyW?!V!TGG6{>5{cMmRg(5wLt;N=%{7B)2~RP5^g|nEzeO=uD2upWglXZm7&cr zK@38rVcfclKdqF-^jk3|$gE8l)Z_L&e7>GEZCRyrY3~Cx9D2rx(Zd7zz30KFO@uI{ zTt*L-XCeqJM86L_#1p(JpmRz3Q>W$UFP4b4$ccQ_-YHNgQZI2zh|%~6zT{`rZxItn zeRD>{Ob;5Gk0fw{?E1hqQWwc>EeabjwCIF_iI;!o6|%!A|28E1ked$UzmYpc(1=z4 zee-ocR^cjYxd!yUSd8OU$((GL8NrQJ_{;c|@+ksAbmrjYhUyJDhjm6=a89y@2{rDFK|(#!qO zWjxx!)MOj>yteDfU|vxj1OC@v0T+voTx6DjSqptU{C89KsEJ|XE%yFQCSxnPurA^f z=g0dj(Z~O#yGwSyTtU~s)OF$amtoowMr;)Nbw%VZZ(Fhjg_9cS6NTl<0Kn@7<1?%i zId6*bgFLxkF7{KuHXPrDWl8m=)!XX+#t@* z{5o*^@Hh}9t8r2b+2XBorIITyO%4e(AJF^x-vYbz`-vpDrKQ`ET{1Tms8!i#V3UuW z^z;UP%btAKQb}pHfhY%!KujyDrjp;ttoLc#vEoL9t}tiTGnRT-*`D#{bPZ|H)wrJK zEz(s5VP5a|ckr}W4=jW1L_H*j4t04KrX*4%^=$gA2?0ywE)fNg2*PWEKQAP+DdXBg zCV;Six$ixVLCG6Y@edvG-v32?fBQV+^+1d*?5u?5v78R+ zN2e*t%cT)3csFEM;4ZTst^Ya4ERSbiIt5HJ^uv4DOP&xeCUJLt@k>AbQ$OgXGSXi9 zNOkwtgS$Xo!+!zn1@u2tpqzzxAHit{P+k6h^M}ULU?wz%=N)=l8Eu7Gs;B3#)nZOH zgoD}z`^T|CtInq*sv%)@Cg+11>S>)U*)aPe4#Q9`?f$3pUoR$5 zbBwKv>bzh;JkI3<>%Py0snev2Uod6yl!a+^*&{vBQD+{}>MR8FsfhkJ_SH;{tJwTw zW;?&!cNL1qQo8li-Adqch%UO35vX)lmof&~>MCkW#DDj*Q;3Bzib)yyVKaTh?2wrk zWZVSfI}Z^6k&R5)uL(rkp-_E51H&WI~Fvx7xoEG_>+>0Jy#3|8r60V$- zg0f|KjRgQkeF5BrJGyFf6KsfYFpiE>vSG*Cl{t*e>$>_Jck?CTZar-yP+Q%Jnc+6?i`GwPgiygKOkFxK z>F?P2bKA)vV4<9*5#SC?jE1MExv&6yfuvg<%HvOc0`3ujE`B_ANb~I4%hIPl+JEv+ zyWTqG691vQY_|1B!C|n=d10ryGbQM`Zb&J<%sT93V;~jpw%?*s^U-A|47&0Sdh&_i zA8rKFaqr5cJoDEXN~C8xIq%1oT}a7pg~PFrWY3fNpl6X1J*KDwE5i9uKXgD&;dvxX z>W~K0AEE~>=l16&zlal^w+Ebaex}fDel_+J-Qoz5n%JZjKy?ehjepBe?g+Y<|6({! zt~|!mCGVX-E&ij#9ehD2@5H_^CMx=C+vGtFsVuR1a%uD4v+Wc;6hh~}Quy1S>b2cj ztZWulT%CY@B4}5GmUscp>_@__X?(4lRV&?4-`zLek@B*?$ILB`kIbnXG;r7F@`RMd*6?U1%O`*&}n`!Dr z)NP}yzsMh~v$r%!GNHtuOD_ZTpCI*%WMA;dmqrw*TRj#~-@%Z*r4Jo7W5t(;Aa?*? zLe>^M^6s6B)y_X$w9rXf4Auh}{DmA|8>^B%>D%!zCe-d_`Qk_Q(YB@?A#Z%e4TW@v zD#V%m4}|L&TswkCVgw}_!>6|)Q8>Z!s!LD=dcJ!(ALpDzx?sCleXH{Y2U&P_EAE_jm_(Yiy#&~zhYSE$)jQZnF@7jT%?n4%% zANE7;m%SyurSm$)-15cyQVNxGZWb(U*O6%2#L^fT#{USLjJ82 z0#H#0?c1j<53rWpHmshgf_mQa3lQ(fJ_449F8Xg`P74h1J=C zLv-_kkad6KBS^V6J^=AXWDlDC57tZ5=WVi-*QPCr?(G}gaMHxZ*Lbdtw=JbHly2F4 z%Lcw!WQspR#Is6e?8;d@@p0xcyqcTnG~18W{{%!o0H+Qk$cTHCar)l$vYx{Vei-AV z21Qk5)}dF#V+fpL8f|Vpr_S-gJZJJ72wV@{g}MJYKFNc~?!BJnKBQwcuzzUqw$y3Z z=kfj2+c9eF4Dce8Su%wHo)G-|zOU-=>riF5)u-SeR2w#@7!KFtJXU%BQ_DSN^KZdI? z1C{C>{ol^EI+Y8!&3S@uK)KAny(BPz|Ic{Hzq26!%Vxvhgo?HIO#Y_9W(GIAtY5DG zX8h9(uD&!B(7glwYDu0%IL+2zgEgJIp8V)RB}kqAj+Kjx=SbZ2YrhTAL*QKfw+br56fd4!xAImpJHS-2Zwox@Rp39$6I)2XU7B7`G z&_1OX@V1h7SJqWxoavtD5z_;o^HlH6Nq+TESHILqG{BkZIY1A?_kS}Dwf@=@=YS4- zzJDHuHnpN`fy?NhC=;vP!;(sO5yax|mlrXgoTV@G-#iwdN@ebgV_J_^l6~PHRDoOe zSgsrc5!>;KlSk?fZ+sLO_zgKE40C}8xZWV7n?Gz;XP-fa0wXNAnjN=kleo&fW(h&Z zJ!gEmtyFR4daYj4nK&a~ttw(P*De_z1m%p$2BDlQ#?ydBLxlj^DMOq|-e%PZm2k&P z-?X~{$NKN5^mvDbb2&fJPm0KBrMd}#Np{ks7$`}AIve^CGyN8arOOQ?Z6p7 zmcY8%JOZxqSylv6fO$84nv^L+Pan=!;PGSX8I%%WEdt?Qz?NMWqB5RKWK<$nu3P@x2NlCTS zD8^bxy_FSLM1|^%n185DgE&O7EGsgRC|J|CB2tH?k-6qJBkdb2Tc@nl_El?#jI}cr=O3G9W~ps1_@XR zY}s&T&6R1&N8oslQSm$DBA#h((+%gJINN3jjR^8RiNZ8vYw6h=h{1fktzMW=<#y@_Lu)f-fX&{|1tfk<$Ocs|EU6{(B65IS6u`{9S&t z2>c(srYd_G?;LHHhDaS~k};NJ%t|j~XFW;>(ZFp>9QcQ3cW z0|%Vin2TQ7#PE@t&u+Wps*f@WOLuEh;CY>|9`w9-vmgn{qwUj~*V=JnULb*W2mH*C z?&cya3nq?=zpH%HP1iRo~hlsj+ELP^|i248t|7I?9A#~Swv4p%thZUct+!qy1jEEH+6fjd0r>^FWVcB9l5`{L4>#T-ABML)x) z?5@%;C-S^W{JHr_n=_Y<^m!CD!xIf0>$NT5NbZQLIHTD4P!7cp&b<#4y9GH!&3~?Z ziHHZi;a`3W8j1SzE!eGq>8E zu_d+ra6IAGBA);cOw$A`9h?>Jcp zo+s0n2W!t`VCAGiP$S`&Rg{}Hl|}MM>?5&DQ5yo}umQ^J#6C*(ROahR`x!;TS|#e3 ze^l>R>*(F4T+C_P^T9{72;CZKgFSwADYxX{(ZsN>Mp$EoYf={ef|B)*(j1?+qlez6 z*exy!$Dd9_Zz!x(k!Sw&-czJeD8T9fEOUaq_~9p_pJgn)#&4H>wWvN0IP=TVZ;sOa z#A7cTU|BBrTVJDyu^~-7C$sU#d&ZhGrCoZ&vZr`C=|k~v&++gDVm(e66GGO$U3*^t zeim9~I=tDkW!9wE&kwDc*JU*S+(f~kx@N1*_RB?5zb%zuDui=VYt>Ym%$F>; zYscw1c>4bMSm(2OZ_Ax%x0rc5hWlC`_&-Gc`jC-ze!HAAN+og0MWq@fW=p+Ssmg)e{i?VtV;In)CZDyrxzOo5F4--!DH8mkEB_D4$gHv%%cPL+t#YAU(*-er9KEl z-hMSkcZtI&d;oSO&BLC{n{rOcaBOcsq=X0SeK0D_+;k9Xz>?#cquqS=%ZkGULHT5U ze1biGeV_ds;tFsCoA)pSJ4#VEiZRgu17CNa26)7s!BbY42o3sOTeI?dDUGf`ufmt_ z828cnm=*N&(0{rpi^2I=oYKa11rs5$(S1I19b2!j5(RFb8SwHK81+a;KPKA~d0M4~ zJ7zI4^Kzz3{PytAmxSceL?W%M;%X5lPd;4N(m+on{XJ1YVVnADJ9$<1`e;xK#j z>&LZJgh{Qr#Os^n_|mOxODT-Fc}aHpANOd89%aUPD0Ue)g{*qmYCq&mW#hVG1Ey)TWXFBgeXD z5I7>zLm;;5s6m6+Q|*gS!HEwBX!6#;e6YuZa|=-o%#Lmig5$Y-H<@E&>;ap#c5RJz z{PfnqBlkPtA>25 z80^d|Xy2HZ=OX9nH)-&~-tsRun3d@urWRl-d}Cg>aq~JK_Zs3GKN9-x?fQMr^`j0k zR2UoIUeY&0Ti?A|j{@QjZ!UJbRkzr*Groeuzh`%WVJm4DkQHR{9Ojkg4aFvQ!TLs5 z19Fwt;|j7zd^hFw%kSkmE6R=DAQtK|m(k#qVFG({t>A>*M$fJF1 zS&=z0rjjHc`*BST{JX;asU@7=417c0?~eZYLC-JOT7v86r@R{`U{REqH|J6_u|$4@wBoG3xuX1tpw@%Cg&1`r4l~8SNHisyiPpy2ec zimE1@8tX=;P;Iho(^KweZX6~P72bJFy1cjm;v^n$SB7pjUYLcPu5mF~@=SEM`A&GN zrWIMV;3HCuABcUZBI3;l1AfyC0=W-POxh-L$ly5syR(G7aSi|DYz$Z0R>ZSoH04Zw z)x_F2!w_D3J0$A?FDUI^(gZ=>J|>U`fh$J1j-HO$fXg4ALy06#$(D8mZ7DV4yy&qk zvO29Cir5)$JbyU45Rr{(41Y>{SIC$x$MA`kMC|9dwP0dP8Cc%=(9zP;JN?C5B@cBI zZYWq#T7tc`>+FV(BGDv(T!#9Zy;dALiTjXbM4Y zMwYo>zXlKR@bFwP?h%F+UbwvdyX+txt-8dF0}?ZySner@X8 zx1|y$uKuL^Bsm-r8zW_GZ}oz6)Qmd^l9*mpQNWa?7zdwQEs9xt2L157o{hAJR8fA3 zegVKe55@QSf09TvBFoCk9J3-KB1%iSr~R#;O3V8KphO)BM-HES!eWV2fCsM*Xi2lE|qc$CH~*TV84O`R))k13f)pNcEUG{Aw6$X#O48R#JOXMfNyt+4c(rpX?dp z#P)ouvTtQ5eWC9Ql#jf;=!lOUEZ4})oI}*w7a%0&(*Nqi3>&5t!pg;Y=N0r`XyiU= z@z7^0rD1JYSmK}KP+u!+lG)BS?CtBa zB80xqitq}1*xTIUX?J=5+roAf?^bw8t#zbje5Ri#0no$#zRR>6m`XSgL;mt`RL0zP zJ5M=M13u|qF(5&MbZ9?6Kg-ugPXs)k618eN{)B;nu{%?e%nIACSR~&G&ZDvoQcrN$ zC!;>(47a6T52b_nBKCXiU%X&iJGuzuVhpw7dmb>j5;_clZ8-1NeVqHPFpb z)y&9r)&YpwV@m^X`#(WYu2oJ;)2%e>0TfU|61hx9IokLrMgcxVH+DrRf<5A?Ob7uQ zB&KQo7<&I?1DYn~vs?bCXsEGraM6lfl@{hvY(RIXEK;QM5&xs%8-sekibZupaA$Y< zLku=_e%)>hgl`o^@diYF2knKX+hZ?yyPC2iBl?Y&X0Q~uLTla`h45imc|2fvJ$}9B zWvUI-kU@gJ)`h$MXaDda8D00aZUSp~Q9rAGcT8%}Fb(c-<#er$EzG%<3#3E)Z>b@Q0ZI2@6GHFITwiFvbKR^FV0zPDy* zIeZ}=)_g~R>Wlf4;la3BXw1Qq?nc}P*Cbqi&fglONh|~fjIuA_H^|OyiMt#eksuXz zf0s(FkW_vloZrMghKNXN~?v<~0O_nsi3%Bs>IzJ$+ zyqaUa`Nreif>s~v_L3A5LxEl5kffbhXQW#T|D{9i*JsNn2`ZS?+c0G{eg98Ay3Lr| zU*C^75qPX96YU!>XBQT~kQ|q?W-;j;6`p<=FMeNi6++(erryb)AF}a`6XX+S@kMA-*0toz@`%~~;pt!mhYbyvQ>4Zvt6bL?rh_aRM$QWH;{ir9MZF$=e<~ItbcIAI zg|Egf{@80H!z5zV&#sIZ zSTe4BvJi>;tdRAJnDWv2hN-MYoop9 zOS1tW-u({~6;u1l@Cb>26iJu?$6V%&KH2Uo)1OxoTx8+lC6~O#*dcn~dUqD0y(q~~ zJT4kCv-E&PU0q@!XGhYDRbHk5%h;ckBum{#GUHXXEPi|9iUIDmwV&9}7^0Hq&9eyY z^?wFobQy$xt;|w~I19PUNVt{>Ko-qc54ANpc^OoIQ* zYb@}YyL>2;9aACUc_CFPuwGMR|H5`>*5g|DHyAhUu$6F~h{W^P`3pCs*tF+qh3|`+ zpn98CCDS&~kzk(plyba=;7|ZlUZ6tF4KDI$^!}Yr^WKeXp{-lHCzLb@J!iy{VGW(T zEFG{dG<|>i)nX4hM+0xXtVoGbNX%+P;sePL{g=@8BfEyx4W#J&$+F(b}?=_mZ$Jc;@82vl1Nue|-Z<$cebDVrE2)!RpUx6K>0EMf~P(@K!5G%&9op3faC-%DbY_%mB@ zT)4OQ4{Z5kbjMDtz|dGXHxC^H!%I86d)Jv&2)PEqSM8sR(dd67$m(a`^78!RP0AR< z`B=@T3H5IrAPcF1TMMqNa6EhvW$wCh^lf>C-~mpFpTM`bpslcpm}fXm7s>hR`1aCJ*Zu)UVkV zo|30)>)o3Qisv3`j*=buN{=(dg$-i?TBSbyocx(h1c|NB*LVzYo+-duKPUl@hYs-S*{e>5+ zcgo6Ex=O}BXY76HWG<;L4{FZU5j*xd9n#3ME_E8ozNdBFWvL^p zP`&6_iG|f)o0^ft`6ZR4q|eHbO$lch8tH$p)#XJYiFn|SzJAx%(s?V?YwCwnhNoX? z?{)p5@20oPY9=sl8=p+3KdUInBt{~U0NcdD+^NM5=Gai_Khuxn&9^d6irgmmr-1Xd zlBEk?&nkJ}d0JR2A`qbfi^?ceyGH(A-p~->7(fQbQksvDjtQ@Boa(tnT;$M(k^EG%RFDjQc+V$o~)M z*NXkWj)VUfkTSdixV3rRxnIWW{Gt`RSU;@fh(K4P64KFeQbrypgk7ioZ!IgK6;CAa zHMh|FH?RBKrSE@B(R9>GGhPBUS(oXhajpkx-sG4!6zI7WC45mW<_iyuy*; zpjW}#*v&imdA9Mp7IBzsz$(lSsfrPyqOxbrN==+W>&B#^a%d1qfoefT`9Vv$ zhg(?jzP}6d-RC@kTNa+Uqcia|Mg7ote>EaT_O1T05iOcgMR@iV&-K9Z@rCGTaqeFw zijBwg1k>k#nmq3B@QJ1@mxv#CswEHI^1rHWv|o>-kkRhUKE8I?;jK-QVxk@_1usFS36r$f?2H=9R<^qdn)znuQ;o%8vGMBJzupEuuoAzWHQ z(G15+t=})-AAS;;eX|~iqA&*-#UT~e^5(-iDAKE`!$nBY=&TmVfY7d5l@GnFDT2A8 z>nyt+6(^CH5tq`Y(Ze6d0n?4%iL4ihyN4cjEu7wp8CY;M+%{tj)eIy-o2N)0RO`0H~BnJ)bR^P{Yx-5JH*l}tU zD>XR*|GFzQ1;u@#tBZ~=?{aI}0uGnBxB8{A%|f$9}_C3@VBx_veGRHt2mk=yoCkj=wQhSik!KP#c{8YS;fxX^5Wa zzw5jI8JQwj@Hq#kK3_Q6)a0-a^pBj+K6J-&g;+U_R-*A_fWZD~c!{nDwv0vKscJsL zj#0YTPvQ(!FoO~t)}RMz1dS7DZ%p6b9llT9j+Aigp-C8yXaeTj1kI4|N?4jg`H=Q- zP*!B(eAB%^z0~5le;m!C9Qc3ehj?SMylw|B@}HzC&{+9x!&*!XPA=z0nrW4xH#`8x z5BlTaHAisQ^B7=Gd6Fp}$Hf~OElN0=bYf@GPfAiPhDa$H255_m1h6pyw2LJv@kiUh z%pef4r80H(eRC8zeX6*&iK*j@Ld$gE#T?47<@gPD_}B*w`o;0IP38p7en-l&pHF>K zVXyy$$HL$p9p)_JJ)(mAw<|h##sGM_+rw19?Q1H1icK$rYBsUN$^n_Fy+_OB?zc*M zCHGePqnEkG<)2MM#XuYZWmQ`()}M$pFYgo{yOb2R#jSz zZX>ER3?8}!2Tu>~5LN!Ulx0$QabTvFy96myBWVEw>h%4;? z_JKunPe!yIZx=x)9937cJABO@V!iFUYWHlwbb6)&yZPIv zd7~_J{&{9BIkpC6L-&G9!xeI+*-cR z*56H~*`Fnk+<(O%VFWXq5FAlC8@xqETnNc)2K&ykr*RPj45YY5&{vsegxsL#S_M|a zWqvEWbu@W{Oww^u{3(?B8u}MjO^G`p5ti6@~jeX_kQh%w|i0MxWC78+LwSR&jDdGFffti6eTjpG@ll54qoQ!3#4;i^qs~}*1aQ#>O4NX?#07fBUvCxxhmup!erX<~DN&&9qY6H_j4VxacW7blP=EQmWy~Pqo}Rm5R_ewz?%UVi z!@oc3SBc06OSM2EGpW1XK4b640adV`==_&MP5ja9M!n=6H zk1IsarBo7lF5OYS6tJBH^Bpy;$4Xj~vEHub`5!@3Wo7<21b(!7m^5O4kbTrfPz_+* zgX+Gl=AGBpc%iyXeB*-MHLoTf+F29fkApFdYjJl=JI?b-L2Q@NjZLS4^wI5cq9jim zdBbzyrSb;g7Vf{@m$Z}9k}Jg$-cN%F9h8~RcV%_W#6Bb)W+$6*mgi=Cza34;nD&2m z3G%^Db>-e^a}AP1=sCn+2+z8#b8p<-it7CSlT&rDc2+Ey<-O5kd?I+NUrwy_uYzn%Ywmo^z3WN zo0%%O7UE|Pw#k{R)4EHDG+lmwH)Z7F+0WS*qAQfLJqJd;9Hv29Py)`qjm*jJ2N93e zP4nlDWA^hn{XVz@!yQCLOoudUz>LTnF96_8o$(BnZ?s3Xw{z=l?Cp1VcIImArrLrr zqd8+cY0;jXAE+6sVLZR-b$6eKXBrOA;d5<$q6^VY1qD+VNOT^tg8+fouU{j&e-R(F z9pLPIK@SX{v0tbpPe*>*U1$;PrFb5ay39T?n@0j~8dx$;AxbG?Z`rd?-u&T(c#zncZ z2SoM9wLB<8-Acp4p6M)}CmJI_mREM;IX#J-Z>RV32lmO<%JOUWbG6YE%D~)j)L_LB ziOm{e{q|VFXUf*DBL?kAxElf=daiLHDiyUfM~;{*Xl=ti|pC7FYn>pdzD ztM$&w$}-W|5ysMgd05zYhWQIN>UgW|0X#rrR12%DbM@QJYcM>=AJkY!7~ec$)>*TN zxG_#H(j<92X*J#jo|qhW0O35grG=jhhFxTeuSfH+^|v&#I`O=9#IQVeqkKl>lz_Y#Rlwn>}dib(-OTZ7Qa)+^ke-+KO9!F6xm!Jlb^d~SUO2=hKAJn=>ms? z>MX3R(agt@#{NA=lr+0pU^l?KyF^8e*|RQtej!G-@#S8aF*K=VEQ<)?ONjLdnCf<$ zZvLoNke4sFYcKl#{R?JBNJPNfV2C8t60DqF9i4Ol%$HXsKl)1FP-<$S4nn(!u+T^H zyOmkexl`#=5@rjGi28w&M$uzCo!M^TRKxlw%K&5v2=Mcl*8;zKgVZxWoJIGqyfH?= zKC(|RqcymLpdZ%fL&OTS=MHd#syJfW8Pkn2AO$t~f{ zz!*Q5WI3(l`RL3{pVMb*nw$j3snyo85o4)Qe_hXjtBJm|=iT7n#CEdKh1oIpI*7}C zbGD{C-PjJ4oV^>nkNTWbh}y1mNL8sI9`pTP(9kd)ZS5HpWP9)5L)Z^HX(UBNL`K~= z{|u<_2Fk7`s9cMl%>7`-RfL6|;>l;8IRM*5#Dj`(Pt<78iXTc7)R)Ys&nzw}DK5r- zCi3@2-v+Do_RoFW(i;JD5_)IVt=`9P&bl%Hf4~0#N2>wm2RZO)2=0bL`#T)7`BLaZ{Ln-CODe_7m&pQa8cUqN0`z zI%^(phPHoxv#tLduH-3B()v3{xWKq|4`P6VY#=VTiaB+w#E4{H|6RXsT)xiPFe_r1!B?4fOJ8$m z?rh4K$Ct#DvGUDN4iG!C_Jz=-&~@MEmn1*GMVS^d@O0N~Rpib}cFfV5nUE?1-u_jF z=r7-ISdJEN@9YHM{IZq)(CIF9Dcn}(1IU&Fs?MStU#W2FDmkH#@KmioEDWDltD#hM zYr>KO@}HpU3o-j$r`^Cx{^;xYN*!|`;s4%Lz-D7zidkv6Hw+JuRC2MD8+O{yQlm!F zbp?)hQ*uSqK4H8j_2-;~qsC;|P(M8QuYn0j2H6&+NWm$dB21P-k*F|YIj9k-Vllk1 zq)%J8ZIOqCg(cmqaZ&?BI!TPzEz3Nja}HXbj7JH+1>p{%>f5Vdses!FB2OZTE<#JL zNO<)urfs#V6abp8;7C&p|Icw0wEu_v?VL5IUBvR@|$-6n)|5bX=ib{@#NK$5Q(sl zhk>RBQDXQhz2@r`Cu6}`S&OiY&{bqKl@c)t0S}p{%TGSxFF$&s^EkwyZ%3a^1G6(@ z;^uM4dn{y4PGDu#kRNrlbNTgE;?V76_1&%o*9*A`kQEh*vR4XRt&Gt=lq1h&s8Xl> zG4nszBZkhO)Al=Dd!x-1_6u2ZhB#_^)Bq29biSLR=|Pi0L9D}eVRa1DBdQi6^?(#c z7VdD>?heMq4W9c&1noj-o+bX5iA28$Nh2p&oCk@DBj~;c2cF5<_rS55gMzEzyw@eR z>aE|AhW+S`I;L?fqm1`1eM??n;uQ?9)mVK2FQU;AihA0R;TTaH6fNCByoCEA`yZWDET5OfvVQ)EjhvZ$iQrX zF4huay_tJ|vF81S>{k_jbM+~f4n1zGl@E0u6A)Ij6%zBpmG@cDfb8cbm#+S}2;u!l znL%>NM}CbZ@NLCiy}!bHvxK9Q>tXG~5M)6{IbN4dAEAAv!}B0o{|_4PW)!rjkb?)7 z@YhAE4jK%_9QP!@tq?pWlwtY{ou0n@{jhkGcd0nqDkz2eX>t)t$U|TunHd$M0C30Y zvy%idm_lf8-zy6GVKKEHp17#2F`DQerE`&Cj~mhT zlxp@phdi!FpmE$L-r8>6Jj&6=!j4yPw?B*?O+DZ=@KMHaAcr4hrOFNO$#A63Gvm;Q zWde6a-CVlL)oQ9BnhnM$-+^zzMqzhw{)DagaK`h9O{a&c`Ixm1x^do~#ZX@z z{2&e22BdeW{Hue%sfZ$1#)!&(;VsZ7daAp5|V?-A<+9E=3=!?(A737N4lzuX%I z5ILuBitu$z&kxhuyC8n=l$cmkTMPWH$7voud;>aaRp8Y)y<})Iy2ZsLxu~A7Lr?JrGaXm$sCsWJ6^Mz?+~Ofr`ZYvTS37l5L~}k>VMP$kvuxV ziE}C6sWi@qLGvNPphp3xPe?+xP~t-PiZX>5smz)P$Wv-*0|`a%-aT~)5CeQUH(OKb z8;}oVy94=&+!*|P+}PMyo%Qep2s6nu;jsbYJGAq+eRPuV4=x@Jv>k;rTWI39h@SxF z65#qd{h4ljXXo!P`8p~RemJKtQ*#$K{+>GG2Ic+fQ2t4%^-a|%$XfxxsYZIlktGPd z+KY>e1MbokH8nM-Cb~+N#l^)rnC3%(s|1Za5`_GY!iNxhB0qgVNtp*aQrq`TU^I(8 z4@AWT;ne;);MbSB_HHKzMxdXoEv;UwIr`bp*zg0pNhDG=_GQ0orNdiB*|%{mq+}yk z%HYN$k^y3P9-}Eh(Lt=2kFck5aWL7EmM|R0&uaZDy8~9P<^qb9h!1vTk!U4DE zJD$IS0;a?1@3=T33WVRUF5xQjC%+(xndF{pT!Rx#O2N1MuVmtD?Pp{}siCZsH2}SO zoWkc{fHn!Mx_M+{T?m(^-FvTJWrc?quPIDNCwWS)kP4!Fp3U#UJeTXT^5^|SdLK=< zfw$!nm1PJa*Q+qAPya^h9vS$!XvYxBtRkF=mH$6Yu;YJ7yaQooV-404;PH-Sror3{86jJ$ zQUstv7=i(pgvIPfOPVFQT)YC>xJg81VOCGtxS@|ZDx??vU8u5&)@x#5M#TF)ee%}t z!hwfg7Kjep&0gyv2!GsaYY&)P?jHT+9E=fEP|(m6&?;Gx2wR(&1VrPe?;U)AofFG2 zfyayM?~8jMI35>@Y!HAbQ^38oCBVb0sjeOc6;57l7TB|DYin0yPxk03A_snS`qJ*7 zzr=|bShbZ73GEK70tJN0=WxzQhRZ1*0ty&Qh@z4Ppvo7vFR~{BdY{jnpeJxz2EavA_`Ubp$Bk0{;TN>=t4 zW%k<4@JA1-q^POLfIa5U7xMp9*f3W>3>8+Z+2|4x6%|&?NKaSciXC}&n8V7do|zA> z6W|%sONhL++u7X2>eDM<{_^8TMl`|bZFd^dqY=06+(ms%l-guMWl(h65Jh(!nANW- zCYwon%n<&4Ln|x6TCBL3onq7%*P{5oiKF931(dj_HiH28tvCXC4AJfqhb}a|1kitd zEJyJChq(d@za$74eZr2EYwvI&Dk5T|kT-^S|0Z#~%a~8wpO!xA^~EUp+4yefGZ%w_ zLK_&s#se7U@Q}fTq?RS&K#V;)40zujZ+YmGgvRSo5Jc~MrHBpqGf#FlLdy+@&;JZW z6G1)2lN8L9oXDN%j0KxL;LexR2^`)lH+E1CLQ&FpdNAeTFz=>GY#BWOC zb2Bd9*cF|i>Jfscoq_r}-1nt29?f(2y;)000O-iarNH`)m}#>a$|eFxu7UyrEJWlo zpJ>2Smh}G_j2594nfMQ~vEpLf#oSH$N~0rIo}2$4k9+?ehgpAYl5i{b-r)1-@1Kp#Hro16_sE-KqX> zQJk@K!`>ix;C#KZzgTgQY28HpNXaGsY2F^iC_eI9^OH(=#k3v(x2(-3)RR=bYl9J* zvge8R%aiKKJ+zkZP6qEw(6Slp9glTLb{lo4`gxi@37QG)g;-z8(JG^bb*~Wwb@iB) zIXBVu4c(V2m>Vmj4jO29?A(@98QNXE=(x)z;|BT!Ec#AjI=S>W8-3{~E@5Icnc~l` z^{cGY$53UGR^h95YubIoa_Gn;oWZepnHqRH^(SM!p|xhnXCsnDsLR8dGm>=tvRGlS z^(1#w71398^nVVR#nBEA8Av?!-mi(fHw)^6!hIWSm8H(V6UQ~`9{811h)4F?2OJ!( zpPavQW)N_3&;wVC2+N&SM;*+Fny%ob8}{U*5c?8|iqt|d=TT(;aEZuaRl&X!j%5%O zoYsYLCQI>wF80ip>zm1tzmb6N5ZtklVCGyZ&S+#IzB^b|}l#J+wgGKzL`?F=~O*PhV76K@8e_oEr%DH&;WM!?a30 zbL=Go1t)?}#?C#vIBs=dP}R%_pG{Dn`vPihoQv0`u!*|z&PB2!!RV>WiQBN}(^YqL z!MdT$;SK7)hF=IhX+CBgtqxkx6L}e|a6-d2tWy75X==jpFSOj|)D>>&v9fEy5W{=Z zF-ZE`sB4_iS4N@Jg7x5LDRo1dJ_b&6^3!m8C#ETdxk?$=dP{r|Db@1<4^~$gB)wm+ z6tjQG(;rPGowaJ>wGc7g-}z&m;Aj36b=A>oey1i9lDfT;tn^Eh$g{cxm%Ar!!M7nT>Vb^tp++t5wYFxC)b#0 z^1s5R?wL|8OHRTc#aXJeuxLHg^*??&bDC_vn?PkjzKDl(&uR*%#GOOXa}xU_1$&xg&5zfp`klPrR5QzS7cwk(E#tJFA5oAw6^Q+=eQ<-thG}A}KXW;! zhf<3(O{FK@(O`(>x5=RgKFirT(1MF;_=QtTAnX@kFnoK3E=M26CH&|^_J@<=&MWBC zI}ybYIzjp63BOV}k~DEprjJo>#3J?)+a7p%rr9>~;&6!6mQ3E8+y|0rhLJ1L0pz}K zwH{*29#o_p_9bXGBOeBg-WiGY|9p&H2JhQDXrMkS1ghl85><@qVAw4ZAt&9Hd+p~9 zH`BEvpnA1NM@nw|rHCj#2qK^MeX35+WI2u?h}CnYeU!P)~+FaBEgg0EvS0@BdG z#IFBY^E{VSbAUh)#{5bbRe;lI!3Y|eZb}J_x~MmwPtIn+xI&htGF7*@+ThzstZ>zx zh$5_4CiVx0_*%IyL!2iM&V4h@v9scn0Hf2hvv;6HiH?4t)7xA6e#w|eGNNu>CIoLw ze;RZuaq;%+T6=_UKxcBWfvD4Rn8mQINE&kOX({svita3X>9ip0DuuPpb|~Y&WZ>L zDSF%36n*&;DiDbKMN1K18fLy0=rk1AKbp0{@r5AN{NVQwl_0Q#rL@CWvlorcd*Hw` zIyuRoiG(3eu~wy$gt}V~6Y->D9UM8g@C~?8l0TDHDF>0)32dBm73Lo*`uo8d*W(=E zLc`!GiZMw$4cA2nW+}!aU2kbMb;atu17b`ESTOx@BC zdQQZ^3M$!dDHXh})#$UMcZcE0Vq35Z&~m)e$?_NUm6o#9a4Fm*^l$@1(-f!hGYS)B zk(zFF0n8ABZzeSod3$moEFgwCz|;WS(cVh9qoZT4)*+9?UzQ+2EgLG7TP0y`Zk{IK z5adFC9g8z^g=ViX0w1+u_Vw#$+CVP+xl{6cTl($P zA*Xm~lUi3S5kc8PV1}vz(U<2SsoGA*O;cZA8MTAmEh;tjp%>QsfrW(y7EKM_k2U1q z&3~jDioDDo$-@(tLGMm80YTGXRo`nej?Fh~gfxy#qb@ba#l~5+Ce=Rv0HUI%mMP@4 zyxNyguAU{KYVCF%%bIzHJsp#ISrG*K<2+xmHGK#;&GrdhcK^Pj^w11zxmME^RtDbz z5P;lOB>|cXL?!<5E0bq)cNh1!aYf;HK>cA9#-CZjWijLTXMDdkg1VUqxi;9-fW}L) z*+rgpVhP@n0@y*7lk-8CUjL13Anunt-)h*n(MqTcW^D_D} zjtdfMsDo#W49t1E^%nvh@pPA0^x)C>79*vlH38y^_W-MZ1TY%wU-Y>Lhmu4EXNZIy zalhHWU#3z=Zewd37@-L@p|d4h4N}?Zcw**ur}QDJmT@ORMM|8!##h$#Xm0nS_|H`B9zbcm5`&xZfrR*ovhv0qjot1gi_^K`va zUIlTv&W58!%G094ss=iS(t3aJeA_r$X9n!8H5d&(I|^EQlMh1hKkIH_ZnG!G=bL7G8cXg93nwcqPlHUVFwni?Re`l$4dJ4AryMDlyQGrZEtT;FP8UFERSSm;y}c@jPpw5U--5UtlZg&__JO=L_lKI z?yliJD0>*y^vhuAsSaf`%7*|Zxoq)^{u6}w(5GM!+}>SmeDH3AX-z8axHK$1Ks=|W zhO`@u%p?BTn)!+_nJ`e-(zUKOZvJtKdi>(Qf6VNDa{2CE#;{)eC@D3>O{He4=t`S{OTtrNN{{H#1mh zw%QZ7-#SlnYv{^sgoc#!c#DB`?TVXYRQkG_h!wzuAh?=0T$s+S2C}*x1bq0AB#R35KKd z^6`!53Ti}l^*|&?s-gFB{$}9-b1tx@^5FNR+EM_yx8GPva9>RDFtJK~*7Y=zyZ5sd zD^sA2clH(TQ|ntXou4F=$X8(;(jxS6MZn^=6zpNl$VSKe*5_NWE(aFvOl#yD#N<7vExe zZ=3FK^41{$U@eWG<1((S^zy4`fWWd3OF0wizq&ZeZ}IT(ULwCND=rTA>;;I{ zdyL1DXxzHZ#~py1{)F1i0L3X=yh`!4)8%i9^kAkz(q(z#BP&PjQ?=5}%RfU8~26Z35 z`K%3ez6c$ukmI6M|BY%`=*PI0FT2L$b$|jsMka%{LRsj1zgLSFDJb6g7RlEcNM>1x zP}t;4pw!J0w-+mJ0g*)y1x|6ks#+Ie)DUV!H9z)ISTP6L5t8;pM0*qs`2}V~>uq?2Xn8U+DOw4NUCa@GNQVf$?x^hM%H-rEn3U@a;P^SZ zU<(0ag3L(;-p<=Zr!?0xtvwuRH_8X0s%Zb76F;jf48A z`HV2OA5Qvs?B}0Pi49+7%htAkM0$vZ5=bO=>I8EBmTk%eWkT!TEOLlvIvl|J zz`@&aqX*$srB8{?=uJjcjA2s!KzciXRY;|T*r;8^Eeqdi7~zwR2|J92tKm@R7PfFVv3rnt6AGLtrLN@bUxM1j>P4$P9f)scka=u&XHpbA%=k*8%^2_}>SH*$ zb)QjLiK+X2(F!8W-2~ZZVB3HU&Ove@3f1Ba3qvhBL1Fd)%X|9gq~Na*pd_L>hJdkX z86i0T^>?KY+GbPPf0tp3{}}cu_H`EnY0>r{Z{yXC)L9T46r4fpiH=Z)fZ^oY?XHJ?H+h-#DZY!|%WT1c-+E5AT=gLH*!MA8ghA4!q0s1MZdR*Tn>zBjx0f zpeV$;Sg5dBQ!qSH5*h}lQJ`9z6tUVTj5$4)p0(3CD3Sm{tK@i}Oi=N^cc>q&W`)La z0T%PV`~~w7Pf?Dz!w1|`b3;0qD+|V*`LIrO2aWpT<*idSM!(95wun#!Qyr_2AH2Q_ zy;CNjU5IC1HdX+~r&kfyYYg#RyDc*|A;!;#JQ#!jYAoJ>`T+i>u)SKwtVeahRW9V< z?(rV5=lRhna?LrB577ky@oa8@3*4WQLED8)w{*Uivcd7o5OP{^d;9=I`$dLA#44%m z9>%A{!^Dp|TW4z&B>xBlg0pzD10`V7USxizJi2ppb?vevl5k| znmlWp2bev&jgK@X0(i$d@^PZdqn~2B5?(GH92|TwwS0^;au+%%9l7;kSY~JI59)D5 zdiBosHr*O;QTX`~e_meRNAFo~u^Y!_R+c!nb6pgQ?lq*l{Wr`4PaPM;1DM|IT(+cx zAWidd1HylZz%L)2+N_*0X!)Y{q9%Hu_VOiga{wdT z!y(Tq{5sf4s^~$}D3ffh!3$&cj^XmslH!~m65MQ(b_z)z4BtSB_Sztn#6sla|~^!rU*${amzyW`TVS)`m;3^FTemX2n;wY zl=MzYC?W7W!vswESiQy2)9-Xw7^>jWN06M32giQQ4fF0dKk}-*TBabsJOYIGA6pT6 z!|L;uO9m9fL5VaxQLz){PfD!gS&-7D0NdOh>k8#jaH>#Q>PV2q1BcR4g%_bFID)zr_M{vEBe#OGOnt~u-;#-tp z2*z-svsyb^M)=6ypXT?GV*g0jEII&Xx9KYS1jw9(m)zCG0uMmB{OsePHNgqJdE_8j zV?^QtNbvg=u{KTO5BPe3NmgAEri%Pg zR&N}iS&v8dlvxn;wxXN z!;iNQX}z}!dr5~N-uEDaVr38RoFptI`0br(loy!#x}p)aU-W#UjB=1@9mZ! zPB|5BZri8L;n6|!)~&A>02whVbAZHsWlo^rcIS_6I^ zqcQS%j4pfTu|{m^Bm^p65kgV|T)F!lQsZ2TaGn^3;V15+b~=|JBrrIdkye?mh|*Ca zgXjaM{L4?g1t{;Oz$r z#I@vrd}rMkU?>zPD6KzT)*GgUpC#$+8n7QwMrQ%rgtqd8dqBb)l5m-~GlD*%z8YPI z_sIJDu2Zkqq44p^i94x@+~Sf7c5*6u=nCTA7M-fMTxkQYvDm`M2P73xeeX_`jdNjU z3e#$IB8ShK0rt1YyFfyPvD-_5!HYvo7oJnAgf^B`-pK4bh5BJ%1zfB8P5hR6C${n3~%hyT~pK#%)O5t z+Htv%*UT5Re$g)aON$804Fey@b|uXn%G_}Jt^|OA!tJe=v4|#bHionfi|cxAor+ z)?)7v!2u6J|CGDh$D&sA?6Pk}4H{Utl1s|Y2_ILcrs^T?lPK@nG zE_`z|1&>y;2tw#@=+btyXo0q&&R+klCTET1(eVI!7JC{^1ZLUM#k+Sim7ZTSk^iAP z?;IQm+R}$WTNeDM20#OH{G(VA18S{p(X-T_ho!%VDZR}&;AfL$i5R)Z0futVcAfHk z+~?iX>Ny^N>EHf)*s#bj_0O^VYY_IPL*o^YOok!Bc{_Z;n4FaHL-K9#)7U1GL1QU6KdPMJiMfs_LmJ!Dc^WM{8a}44@o0m~cgO8~<+!Gq zfR9j&U<1VnsQ+Qk%OpN_k|)rmO3x|#@UDPlv_n)gsGG#rznVvYmyTi(FFt+ddvcCm@~ zb^bZ5a#1i2wtW3HO5Keo7~2Cx_V2BgOZIx!ev7^hGA;Xe03Bv6?@A2Q=K#i>7~ zCfFwQLii2j%hkAY){R_ORiFDS#N?zLP3%wm^94{HRDf9RsZv8sg5g-BP{Q0^09;p~ zjX9_@cYz@p$dZ|s0fdVP->`Yth^O`GTWEnZw)-2R>h*m+5I z{s5@QFqo`{ht;e(_2wP|@{Wa-^YLmQSfx4=m9L?$q@wzVv}>9sWSWC*1Sv0e1rkDV zrcn;gWhtCw`h|iG`TB?j7CQ!Hd7$c3#0;LyN_ZPUkMoH_r6K zrk2_S6Z)pSAAM9VYkGSU$2gRAiEFRs$yb7A_p6N7|H5=O0e1a+2gMsw+TVvCl_PB9 zh985xhWpHd1-oYk(04}JDHPlL+QeH@FmwBygl`m=)279c{1sSnunQU+9||Mn7*eUW zD~eA57)06rJh2m+{r=pQhHo_XT?OkgaqwM5LBYiw9ro@Knpz?H_dq_-9N3KqF0w7Z zQE`S}I9cOxsg4fq*|SNof9UVKBE!Ak$^$)p#0WI0f@kpLgS%_V4@2zglnTFI8lUdn zNEX~oPD6EcFvXWdftut4A}_r&m-s&5)+m^IWcHV}2nh&0;0cL1-y|X_Y!8>K#zEh{ zGd}-bepbhUtLncFG@xaT^H`4$PyAQn)(&wI{urK!hWBx~+uqoSFTOyb7y)DsgVKq$ zg>_wi8%j-Wcr-gTe$J$`c6g6|lUlx!f>X<7Z*zuZHPG2<)WF#IpplS<(cXLrnOauu z0?GB|@1d~k=WUTo}A(b%g0m7W3Fz%aN-;*JrJXy`G#Zi|` zzX(@iiV#midhaCM3T;{^n4WC?X``51n|ZL3lAg~0Yn;QNNMBj*m807E)@3p ze~C~$o=>B+jfG+`jc*sbWFkFP5sraXm}B~>Ep!qHCu`{I4}5WS_AySdp{+)Z;eTZW zXgQniL2$JiInjU~lF@=Jx;~btTMa7@0+z&RKjc{f&di&E{6n;(q`kAY{7FIb;S)JR zaUDV~-vLrAe*dc~YhmH5MIHY`paA@g{s2(p0LF5%-oF4hEvO0@XB)pba9T6tJk(5M z%XXdfhZAJs2*qtZ7O&#FVOn13kHW8DHsbh!+P&hQiPfu}!?=V0T*VO;$=vG-=hZYpD==*b-X(2I<;h&;L)bB(YDJ$dj=kIqco*5+p zcIXB*hF>{L5$k}h>Y~`EQh*CJ429ByFdE#Gxhi?nY^JmCK%tmy=oT*Seh2QM#SWSFIAnJ^T+2O?~?FX)S^oz-B5j0oNxN zSC5h)CsJj5aOD22&CP7;XnBS8*&do78bYizpHFdLAXl0ay`#m5w~}7=ce?MC*$`~h z)Gz6_OJPrSsf!}L&QpfuO8d@mNUbCzYT) z$?$KTFu(52@wq9%bfF^@hvjkR%0p)ayOiiPf}F8{j=lEdD*A{$q3m^@&-Y!1P}B=#2Jx`hV{s?V{LynLTLl6$OUC_%DY zr#A2?oRS=+e}taW%X_NCm;lw3S$#A(?dn>`*aa`D@4)wq+{Dawn$A(yMMV*xq$-{L6l{93D7e+r?y-BE@nGt zZ8hGD$nbFNLWzi74dsY0pe?e^O)^+UXjyq19c*on(wTb03=$au=mj|Gf9FeG;^`-P zYU9FoEFpySVCZ~K@gHxlkWHrm#AHb*qx&D5iptgH$?i^)@FRzDvpCb>V2Pe8%^+#D z>!=^Q2t$hdjN^4;2t8~CaH-KX0EA$Ksce!*T9p&}IM@~%8vbZi_z2p!S%p(<`c4J} zjkW>|oj_{3j79ucYuc)C7GZ|A^6o9nRerDS`q{svre^r}2jG1Pgc|TXh1gVC4*0fk zQmf0xeTL5gH^O;-^fHluv6mI0n#V`LLs=kz$imv16(h__55*$D#lvGdU#_AJ8AI?f z_@-|@JNqkQq|O14*(|V%Z9J~4t=)$~VN594r5nAySR4pli9+jbx+at`2Z19v#WASW ztO$#8ck&KrE-n^el;IM`t0ubY{e(0MvG6lI%N9k>4MoBFPAO%`(Tnp+DhobHv} zY={-_#zwIFI`3%fXr7-tJO883?6YUjUg2p9_2)$Qm%{^Y0uzDgFR;F&Tst)E0MNtF z+t8|!r-(v%mEg5`#^MP5=(8qEImJcpd%MHoz9SHS{NLc#r=foy@=ML z$A#CRkVf&{yR*&BA|)U=jg1xcw#t#BeeYvJs(S}Ec-Cd|S%qLx?lCt%u-}1UhozyU znC9?vaW5!NFeFj=a@zunP2iq502ean#@b(1-i1a-s;W?S0l@NT1HjH_K2NJ${7s&! zWr~HT^RoS6qwR088hW^0DbB0=5vGd`uQitv?^|8XuLwD0VDwdPfUZ4&`bh&)H(;EA z0c44ZO|8qL^dAO^B9NFm;CLlJ;pj3Ude#SUWZo?^AQ0W{y9_jcC3-IRJv~pi$q1~b zICqa&m?=!np9!ULdo*dBsxlxmL0~Pu)dW;RADgK&fNAk~K<{w?^2`^^?1w^XQa%+6 z33Br_k{<2H^gWZ7R1_CHfcx09=yfkH9>6whw=BK`_*;}Mz#0o}5iA2n_iitNqu+qU4{(V*|GW3@_!6@~zXw=6*$JYc%0xBRe0sQ1=j3axc? zl<@up4Fy-F5rSb!=cscr-C}z}0v=1(V1J zA!Vc;Qm_vMg7-|PDIS6ANj?sZe{$gruQH+U9}S zQ@Uo>-%4$bjlIv;I@r<(T=zh{0khL^Zmc|QDPYaLbikpO$r!)&EXQt{q zJ8-=6)0MIl|DZ%1oE+Q#2fdM}XRCV9Sn=0?F-=e;e!>rT}_vJ#GI z1Bvv@!Y4WZ6t%<|&k^PW^4dpC_H^h8k`!eSf>1f%`@AR3kbn-FGC^b3wRlj*gZC1n z{s0yz=OaKjlD|7Au6C{gN*1|18TYA(;0y}+JB~E@)R^@L?en6r`RT_p#X?NRcHz}Y zz0u7_h{5t2;oJ}r)a7*N!DJwE7X(yrZ2)HO!La<$pNsT0QU?dGhDyi=^1yw5r5{vu z+nsHuXG~_uipE`o7&$b&1>(B6A7Ei;%wD3OJ zyHLk4JRZ*=pcdD_#$VFMN5Z%}+m*&25%gyF$Jl(ea8L)Uw50la6Fr}{LSOpte8?I}93;at-CfrTy0XN? zM6A>q51De{hT|Cc?krh6u(JAI4N^gp6-7>0)QI%vO@>RiE)-VpNF}EyBV$5i0N9PA zQmjdijQS!o!eap^!ablFxiI4x(Gz}hGxhfL9}ZAZXVmHe2Mdh3 z8ye<#WA|ErmRpm6WNKOEv#6;6P|5O}(hbU)BE5ujcRaMeIjAMpah4S>ENt7ds-R19 zcw$N~EBzLw+!poS8N6U1mqUB>K9g`xi9m%|i?zAAab(nCC|yyGGhbxE8x>h7z|WtZ zoozSdzvBvTSMo!hVD7^UahiNlOIyq zovBT!-Z!JII~^N#a|4^>0NXLZjWAF}2Hs??XE0B8w;F|_(d5~AjElK>kZDWt!|#J5 zBgtEJW+ori&3MtexSU+-G0t-o zomdhxu{nv}&AgIZaJJgx<)g0|g})<=!0&3ayn4C$(SJ<=*&1`LJ8r5VpErljG71Kw z!zISFOt*X0F0f~v8=pXsdXWNxYB0jVpP+s5+=o|PiwBc#<<%*1t9-xxS$3p}Qy*J% zVWv$SDNz=#$a6TEi*OtrDnoq<oo8zPWGS^F$ND zJMM*)8Kh7wWw`73Z1{46P^D9E)*xUd>HXK(nnqyQm(<~X6j3P5;veT!&zLAhto)d1 zIi5Cc>^Wf2P~S_iAYA$OEsZx-y(ppZxpO4~FQU;Qvhf=3At7NPD+n z*i8V7KgI+8w1M46i!`zNUi$`{L4qBSL+;tya!D9%U8heVeMiBfm`#}a&D_#Tcw=+N zaSa}KLzHn-wW|=xck$&rt6|cnkERawsaA^#5rDKObY5JTyMSNQed7B~id#pRiuEsq z(ke{r{ex1zHPSrvDo@>+{LnrpXm74Z@1n|T^tvcYp6&Yj;?&mf{;=gF6m@LcmVOpm zOjFN=gg4!`%C}BEX<);qOK-(=70lK1D+%Mt`6CRSoJ!Nue9qr=1)Rcp&mGVufmoAu z{NUoNv+i`{U$k7qPlYk$;;6Sap#WFmN&Ov7wjffrjpQzD_=`z0{vpF`CF zHMD|4neudYH=03rq)DnWKI9U3mR1Hwevr*Zf59&@ai(r?`sYQieTC!q3g`Dq0zU)X z7bPC1xo?%P54uv-d_}Jb3r&h|_xM!f@i;~96(PN&RAWRgqC0wi^DP?$074Q7p}V6k zr3CHyTGL2fwA%gH7%W@2MPU&4=a#$RUS()~9^FFSs zqCzr)Mz#J8@d!oXTF`!oKerd+>GoWI|M%?eue=EMfkqqw!F>QdrVTB0jiC8ciKS^9 z^3wyO5m_bchj3++kNe`zm>u4mk;y`Fq%Kt{C?49qFN37h1JJ;3&Rmz?g=(K9`ro_Q zT;2(MS53bRfBo9nT2mF+c*DQ|J>EbW6~~+67P!=vc1*w9stljU;ZVu+BIM}R+z`}7 z0hy5;>Eyhm<9m2O(2Q8p9~_;W2?+mrE>{LQk-|rskmMw%(ji`m7Cz@Gfa1BW7B#a% zb-gV0&f(N0qz9pUX~!17-5=v*#D!tJlGbG?+R$7D?dIoz>wyIyLo>sPi;6b5Kk`qR zjjGF4EagA^v3=DuQJ5&OvfXUu^VMM^!qDW;{bGpG^G$cR%4$CKUs9fLt}oq@^EL>D zE_Yil&Icq`3+04H$gJ_>;6^YxW#N!@6?ex{HCfUs&ujk^@2VzxwO94>?Mg8p=0Qo- zz4g4KX8Oyqdd+wDxADsXoUf#Cl}nYUV?O*xga$a&d+Qc|oyQJ@^)8#tR$(hI;>WE; zNfK_p-mA@IB0Z{C2*U{leU*s3rqhWospae6+AY>ptWw>?r~~NOh20A26SLh_k);so zjOa>?a;@ZS?nuxgB*MJKkM~bV2UmwMhU{VcX6)e;7I_KXBh3ypZl`+p@g70YOm$5j zm{@lQ)kC*k?d^jQ!H#V7c>wANP%mr|Vor}Gkr%pJb~Ac!bv~Tl-5I-gjFvvQMYQNF zl34*xO(*%noikLlTOE?xW7Ijde_(wZ-x<`YbMCle9w+;N8V0-pwF+B7OHaz^wyYHu zwJWeig;J^5fj;Uz!+~~>zdrb^msNT}7Y}XXMC&5{=8)u0g`MK!V%UnoBS78aE`uY% zg~p7&eA8ErWiMgh{aKlyt+R|LbDC``ac9ClH;~pS`*CB?WKYAo@gLMald@%(h^(s1 z;=Ok``%u@>I29xLwEnflS#|#G5$J+SA6Z&T5O)VoUI&5!Lyx>F>8g6QyawcFP;~9X z`~GXTNh(Ww+YN3!{s_*oV^(5!$e#eLIW+NgGqJkr$BY4G2VgnR;u`Zlm+>UHc-aE% z5__G|<8)SDrje9!Cib>C|bJI!IRJwCeyBly>!nai~e*d}=D1~g}Rqgr>j zo}ehlVR8>jiToXhg2~LL>L|W1UF)nPtG&Y?lfhy4m#_%4y*rav2JzQUeHuUIWqSM zCB6*kC-z4XLMyjH#|r>?qmb&l^cjEJ4p)C^^r5~(L!2YzUU(suG43mJDFw$RR}ZP! z;Qk+hd}Gbra4(W?NDP{^#f#?7*Z4NatE`0*Ce!F59B&$ODtVtYuAO>i)jfB@+CYy1?Isk*aj_S8nW$IacH^`2b!^>XxC5!n~ie8Nviz>fop z>%!DQ-moojD$g!0ja0f`Xn1B?B!lNsBWfYn`S9R$HraLaBrMVA>>VbS$;M^QJpIi} zgPrS4$sP&kA3S(q8*{Qj7DRu{egCLhE}Y85i@WnlfKJGDzkKkFew-D|%f!@0EetAh0)*SbSIVfO$~FR5RQ5U~e%POs9R zX1kfvSBQL6*vURXoU(wvF4pRejm-y`Ezi6}6{MCpw&6EKHz?GdUvk16wHhC9VTed_ zq<0of=lD>zfd$w6Ht~3|Sxy#~g79~jAO*hCn}jo_AIW`e)GkRd#VKY}W1s)b6qhbF zcdZ$Y}O2Ox;0ME zlAus`k3Oxs*Hp4Q)$aH(@LCfsZMZGVA)|TT5h)?DuTL^Hk&OT+MKPDMBfVWpEc$Xs zUl6ZQXP-NBW~_TX1Zh(K71x+6b-`@8yE}5{*eMXu97ewJ^50hH4V4n_14scMnBnu+ zQ}^#z3v7R27l&xuY88V58(-z+gxX4%q)|6l$m`{zlo{m=%&2UC$n+);y=k* z@9ruRk+ut?6@J2llu5gv`Q`8PQ!3xRZ)g!VK@wTa#&I`+P1-}RZ|KRE=l8hH)bGjp zw5IvH!~l0s0dgPr6=8^Wo6G@8!jkG)GQ1$3B=d3asA_*`XIJ>)L%hRlW=>AW0}MKq zE^DAXRPqgngx_dNYg8Ayb6}2BqK$eIGE8F0#3%u~sM_YBfT9@O{seyE_`-777s<6)2)iwaf}$H(sMZ~_Sp>GgyF zjN**hzbuhKg6*gYc{_QB9YoVv;M0s4;F@7BvM5vR$(21FWFtsRe8V{7xGyy=ZTZJ# zIP~v0ESbI}7sJA1QeBd!CqRs08;+D`!;O_R5zJJOCVavrzVpXEoy$4f53|Tn7|)BX zpWt3m@T`gm!J_AM9pE+D+k?!;F1s+^HJd8OEHP+%T&85wi7xoHze5~_Kx~~2jf`B~ zM7Z=r@+xR}y-T&w%9d@;(##AICGRkzvt*iBn^X>6CqM4DdWx(=vyMr_Lvf$BpgfTrI(P#1V znnoON*S%b1n}L=Ih_dVT@YF9h)yfkV9^&~N>W#gi&*@!4we|F$tIpu>u|1j+C@~YD z6PDb(B4bATltkL-s0PbUqf?a4q5$+Qk9|1B6Lj$B-EY!QG)F|f@75FlIOd*4gG3qv zSRV}SpDyADX~EqJ9VKd=-QADymb#8b(1$QD zwVn7VY)}ysa_xi$`fi(-0~vn=mtpznQ%~Mnz(sWNJG`&6c_McCB6PSjLd{EaN9wvk zga5o?Yn!B7r5=!)hgm)?hD)^+%~0esJN;m7ez^OrYKjETPMti`vJBg4U1ebo=b;o( zh=q1_8iTMdPx+bICe-;2d{PBrqPKaPvX+)0n@&U%C%OVo2cT4s`tUOJQmD2$VBOM_ zEl8G1?mYF~5TX3~(8@}l;WFAt=GAk~eh0aWpkK5zM%!2!h=IjN)p*Cl8(ZS1Q%XT9 z&Y2jxOUga)_{syH?TfcZ3Wj&7{4k-cVK}5C!0`uNf~p18O(4I?m(mrA9hRo%QSIV) z{$iF+Nn6T*Lu%*-u@y1~`g;?)DW8!157a5W-LL^8J6P{%-Um`~U+G1Hiub=tpnrkp ze++FAaOc4e^mYLs&yTo{NrvDnBj4VzyuS|~jeJJvT5!TsBTY4#__8nYnR~fe(el-N0WoyF1K-biC5EnGggrc^RzJL;35^aW1a%IHQX zT6S5lkD}yZ@kz8(?Sc6uxo|^v#8paWRhtYhUD-P}v4CoT184V-cUS70KGE~%9UL4E z($YfTRg{fjqX;c>WU6V};=u!>X%LlJwqVN~P36k-ZN` zAURsv0H)-&8i+bnDaQDK*U*&JzB~noKQzW^-d0Y|M~QECZq9bihGrY*B&wyY%}cxZdlR9j zYEUac8t@ZhUVK;-KFTp>qA7gdMIwR|G&rLk0(+{i_)WP|s-*RpWJM^YZc>7qz3JqCV0ap8@Bj$fBbkbe|y} zHGnfMwF_vp2>r9u{sA#YJ&dXAkkw36%KNf1XE+-wANrxNXKy}?VzV#hVYbq|%ym>N zyN~4p{3_o1$P>EYE)Pj3p6io>fbcr5rS?Y`8CdPE3s1?V6Xt z_NOZMO*1w~EXoWhBQC)6h~8Gi$0F9rEAa>_3GT{%>oX2^VHRDd80s6(pDdV=7h7K# zkdr8sM7(LEh&RoyP5IVqpf7D(@eYlNv2fBHtQYNcj1U2pFzTP018+!q^l#m2Ohz@k zLkHgYeTluDU8x#BKc^bdK|?I68aSMMbtFZ;mZ)srNqq|9bzi|V2m|Wiz=J2N1*fh7 ztEwru!khei(sr?^SEZz&q+unO3Ao{5qyQ3hc;Ju2eB?-ve~b-Cmqh`f2}_UI(GKt1 z(Ukq8*D)B_rxqmU+n>(RWDotUHRxx#ijhd7#HDK9?|dr#QGLHHzVjiShKLR4#Ez2p z+NmB7Z9#A;vs&%VB=%7sj~NmnMF^gdc6#g@{S@SA8BK)J_=FV>vXVc zot{F`)O2QccDA{>8KmWMPRoaFiqEEpl3lJhE>&m62NtEMcDCn^U4}PCB&-2}kG<%x z_8FtMt%)rxp&E4>{nwZ_Pm2(tc+0l)70Y_B1~wA7=6sje{K0y4U@6^t4#va)q%rxL zed{BJsO9rzKJm9S;$6>EeG0oO@31Gmqa7MM=2ORp(d!JnQb>Cq9* z;mT%dUo~!baJbd|@EMHg`|NKfEiOFY?M#&`R<)!bX@5&*$#I@3k$}c5hXnN#D52tt z{7Gx3+=B06sHC(9W>7wC9Pw_ON7a3GK@qrD$B?&1d~ck7nf>IK2uidRq>SRZrG_-N zabqO@!FI|h*^{cjb3_npkAqly5`9C!-5U{5Z$Xm+cDH=EbnE}`zRcjrgoRLLNgov> zx6A1vGn4h@fIAYFueh0iSh#9P510cgdhM}Y1{T*6YVe*&Pzhz*Ei{?byE!%_(lqDU^0Vi+3N9?G!4uReAh(?qH~Hj z#PyABd>(Czm$(W;mkI_f{by9fhaUMh(|X_)BL94|0QAWuPWu|^-MiQB*p!L}2Je6K zphj+A^{7ea@8i^|ehZ>LIkQkpt&M238bhS`H}4j^DK5|5oq*Y&!n znInv|C;jJMpPl!a2$H&w!fSMlYF@i|l6(Yf?+3mk=GaaUNhZa|k9UBN0)`dghbMT% zy3*U9v5`gdUbzGlT$z;}J?M^c1x$_VLTI7@k@erJ4&~BK)=3(s$xT??^RqvnI9^Sf zEIPM@*?PF*Vn-hRW%q^8^ViWQ+MY)K*~m%*v`&f~XH89psCIk8b{FxIYa;Mu;QAvw ze>yx6=0X^PKb*O*#hY?aJAfl)emZ0nJ|NcTKVHo2SOU@57h+HZKcr?&e$3tilX%p} zoOWAoaZ}^CL4SFNgrJ8ZV<)$v_S`tN?dLsXM)5;kpzp*HfMTYK73>g35gu!rzj(~_ z(W6NCTQhLLU%)(t!z2jvd;*i9_om@Wtq}!m+$%DN@zZ6}OsF|lWVAQ92chFH92~8% z{EV0_Y>(TazQ;*1z(C`$-Vu!>A!fIozeK6cm<>JIM_@|!63JRtD5!)yg$?NNZUx8RCCqhr%R*-9vvc^V+AO*C6YRD z15)ZYmX0K`u#5ODLt$ZI!X{k6X@&TJ(0l6Pus=aFBVCT7}1PieQ2EcZtr+TS$muQEWlrbkR6R5X?^2 z`iz!%rpm}%l%1qm2q?Bl|5D-!@82CazP{TYYH;1|G&(Qv>G`^R z$R#Fgr*q3~A^g_ax`!|Bk)`i$8s~bJ@XMw)V~<>i19~*fptX^^5bh2){O5t)3VlF_MM`Jk z$a@LqioYOoe(F#^47S`x^^qL3rKQS+5XdJvnx`vvYic~5b@g<0!4>|~SvmEX{$*w5cdd|s z!&JQ%#>PbC-2BkGtj9S>RJ*)91G{St&GZ!mb0AsioWm{*)Cbgqexwre8XN$^4x!)ZI(&uwMWSwDhlsTmY zlZsBttSmq1n*cf!U~VD_QoY&_O1^QEE^vL+yS%#tm)8R-?rs6ta8fPTsx0l>Zhxl= zR*NAI*ATLcq=WGOq@8wjaDZI#F`Z{LpMSZPPJ=VWG^|xtIVnW6r&Y0u(o?_m#NV)- zIS<8SCGz!xu&{6^C_WK%h{rXw7@THqW!TFc!~0K=$UuejS*D9~pjne7S?%lX<^N_( zS9{qGYy#f|&CnBvWYbk&;r&aC0bqY8dRE`s&B~gCd#CUT=9Iwxn>l_n!~!Z) zr=5(<%z(#~Z~zOL9uVHYW)jW{#Sn%U9Vav_q;FHPu(YJ8`92Y8jU1+cpQq_Qzh@y% zmu3ldX|E0+3p6M)r7SF+p&#nC8 zMv{6FZSXL%BBG(E3|tX=e;!Mef&TsKGxGk&Z~uC&{&U`gyz#Kp=`bS_(%HrBnsNBU zn^l&ZH!R^`oE9{e5eJc--_cF6BCue*f4`?nV+dEQbsR5hwSo-}Ys0WAlR_GTHRBmB zb_Uoy774nu)wEA}xj&(#XixWs_3ZHE5d|4|6$_P;M$nR(T5b_l~N`z_i&R+)^4vg?&uQRB+IsBcq zkX!{>sq;4&f=|V)q@)D)IKZUaN9hJYg6a?U;&K^3LyZKpAypoOe*A>t-HH3YU;eOt z%JplIzv2w+jFzbtTMB&o5T>AZ;vGyzG7q<*MD;}ldjZ)8r$OD8)d#7H7CBuiLQ*Zh zhs3VvL~cv55%IRQN8=ZkSp9K^+zrMc{2(|G8|PqI&(kg;0>b1@^nX8WV z`aZJ)l+gsMxSG4QDx8a&ExiK(d4*B3S-^qbo+k!U^|#U74Ry;s7noq_L4u=+hik83 zA@YtM{SCxVswHQB)pN<|S4!6!Ni(tFvM^Bp=?6Z)?1JQ(!YUGW#SnQ$TMrcYVIh+S zd50OXbT#T_gQxz{c~*tNUPK86q()U%+@5(8X*2_N6lHt{$|%Q$exQ~#I`_a%iKI4K z&m(aFg>AOq)^eKt`7<{!&r}LzrO;foI?VTL6+UlDb@zI)Ex5Ami1v=kQ&M~cu={;c z&RlyK{L@yyBf|10fp&Q5Un6HfC_3dg)0q2!-`^JJ|9RE#r>iv7)N#H(CcC*L{P51F zB2iG#0Wt7M>}9agC?uB_yA92e%eYjzfJntL4-bv({`K_Ld$YAR>s+uc&}*4PoH0^+ zGcZG?AnaaYa&RPoY_1S~x};|HmvTIJack@4%`vZprLItgw9^k9yuPRXo-pRWDJ&^@ zOjpQSPQ%2VWg8~Q^+`Oo%j2{%8N85w={XC# ObjTree_Init +``` + +`diff.py` reads the respective `mm.map` files to find the function. If the function has been renamed, it will not be able to find it. You should not edit map files yourself, but instead rerun `make diff-init` (it is possible to copy the build folder manually, but it's better not to, since `make diff-init` guarantees an OK `expected` folder). + +The recommended flags used are `-mwo`, `-mwo3`, or `-mwob`: + +- `-m` ("make") builds the file used for diffing automatically when `diff.py` is run. +- `-w` ("watch") will watch the C file containing the function (and only the C file!) and automatically recompile when it changes. +- `-o` ("object file") uses only the `.o` file. This is faster than without, and means you can see symbol names, but obscures the data behind relative addresses: if you have differences in the .text section that are invisible with `-o`, or you suspect the data is shifted in some way, try without +- `-3` creates a three-way diff: TARGET/CURRENT/PREVIOUS, which is particularly useful for seeing changes. +- `-b` creates a three-way diff: TARGET/CURRENT/BASE, where BASE is the version from when the program was started. +- `-s` ("stop") stops diffing at the next `jr $ra`, commonly the end of the function. Beware that some functions with conditionals may have multiple `jr $ra`s, so this feature can chop the bottom off the diff. + +There are numerous other options that are not used as often (changing the diffing algorithm, viewing the source code in the diff, ...), and the various flags have dependencies among themselves, so check its documentation with `-h` to get fuller information. + +Colour explanations (sadly GitHub markdown does not allow for fancy colouring here): + +- white/grey is matching instructions +- red is missing instructions +- green is extra instructions +- blue means something in the instruction is wrong, be it numerical differences in the immediates, or the whole thing. Not all blue is meaningful: using `-o` to get symbols, the addresses of imported data will be blue since the relative address looks different from the absolute one. +- yellow means the instruction itself is correct, but the registers used are not (*regalloc*, register allocation) +- Each register gets its own colour when the regalloc is wrong, which makes it much easier to follow their usage. +- a branch is indicated by coloured `~>`s on the right of the instruction, and their targets by the same colour `~>` on the left of the instruction (remember delay slots!). The colours matching is a good indication that the branches are correct, although not infallible, since there are only so many colours it will use. +- occasionally instructions will be coloured a dark grey. You should consider this the same as blue. + +Example Diff: + +![Diff](images/diff.png) + +### `tools/m2ctx.py` + +Pass it the path to a C file to generate the context for that C file, to help [mips_to_c](#mips_to_c). Writes to a file called `ctx.c` in the root directory of the repo. + +### `tools/overlayhelpers/actor_symbols.py` + +Takes a VRAM or VROM address to get overlay file and offset for an Actor. + +### `first_diff.py` + +Gives you the addresses of first difference in the ROM, the difference, and a count of how many bytes differ, or if the whole ROM is shifted. + +### `sym_info.py` + +Can be given a symbol (function or variable name, for example), and will find its ROM, VRAM, and file using the map file. E.g. + +```bash +$ ./sym_info.py ObjTree_Init +Symbol ObjTree_Init (RAM: 0x80B9A0B0, ROM: 0xFFF210, build/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.o) +``` + +### `extract_assets.py` + +A tool that will use ZAPD to extract assets from the baserom. + +### `tools/assist.py` + +Searches for similar functions to the one you are passing, and it tells you which one are decompiled. You can pass the name of an overlay and it will search for similar functions for every function in said overlay. + +(Still a little broken) + +### `tools/get_actor_sizes.py` + +Generates a list of actors with various statistics about their function sizes. Run with `-h` for information on flags. + +(nonmatching does not work currently: we need to adapt it to MM's assembly files) + +### `tools/progress.py` + +Gives the progress output that the website uses. Run for that warm glow. + +### `tools/regconvert.py` + +Convert `mips2c`'s `gGameInfo->data[n]` output (or a raw offset) into the appropriate variable in the REG pages. Can also be run on a file to mass-convert them: run with `-h` for details. + +### `tools/rename_global_asm.py` + +Will rename the single-function assembly files in `asm/non_matchings` when the function they contain has been renamed. Should mean you have to run `make disasm` far less frequently. + +### `tools/rename_sym.sh` + +Will rename a symbol throughout the codebase. **Be very careful with this script**: it has no sanity checks, so you can do a lot of damage if you're not careful. Best to commit before using it. + +### `tools/actorfixer.py` + +Provided it is kept up-to-date with function renames, you can run this to automatically update your branch with the new names. `.` will cause it to replace in the whole repo, or you can pass it a specific file path to run it on only that file. + +### `tools/timeconv.py` + +Changes a raw `u16` value into a macro for clock time in-game: + +```bash +$ ./tools/timeconv.py 0x4800 +6,45 -> 0x4800 +CLOCK_TIME(6, 45) +``` + +Either dec or hex input will work. It will warn if the macro output will not match: + +```bash +$ ./tools/timeconv.py 44102 +16,09 -> 0xAC44 +CLOCK_TIME(16, 9) +Warning: Result does not match as-is +``` + +### `tools/sfx_convert.py` + +Replaces sfx ids by their corresponding defines from `sfx.h`. Run on a single file to replace all of them. + +### `tools/vt_fmt.py` + +Replaces VT symbols by their corresponding macros. Not many files in MM need this; ask if you need help with it. + +### `tools/graphovl.py` + +Creates a graph of action functions (black and green arrows) and function calls (blue arrows) for a given overlay file. For best results, run this from the root directory + +Example: `./tools/graphovl/graphovl.py En_Firefly` + +This will save a `.png` of the overlay in the `/graphs` directory. + +See Example below. + +![Graph](images/En_Firefly.png) + +### `tools/warnings_count/check_new_warnings.sh` + +Runs a make from clean and checks if new warnings have been produced: we use Jenkins to check this as well, but you should run this before opening a PR. + +You can specify how many threads you would like this to run with by adding the `-jN` flag. Where N is the number of threads. By default this will run using 1 thread (i.e. `-j1`). + +Run `check_new_warnings.sh -h` for more information. + +### `tools/warnings_count/update_current_warnings.sh` + +If you have to add new warnings, **and have permission from the leads**, run this to update the file used for warnings comparison. + +### `fixle.sh` + +Fixes line endings in the repo to Linux style (LF), which is required for the build process to work. (You may be better off creating a new clone directly in Linux/WSL, though) + +### `format.sh` + +Formats all C files in the repo using `clang-format-11` (instructions on how to install this version are pinned in Discord if you can't get it from your package manager in the usual way). This will touch all files in the repo, so the next `make` will take longer. + +## External tools + +### mips_to_c + +mips_to_c (or mips2c) is a tool that takes MIPS assembly and will attempt to convert it to C. + +There are different ways you can run mips2c: + +- Clone the repo and run it loclly on your own machine. Follow set up instructions at +- An online version is available at . + +mips_to_c's accuracy can be improved when some context to what the existing C source code is like. See more on how to generate this in [m2ctx](#m2ctx.py) + +### Permuter + +Use when you're low on ideas for matching a function. This goes through a series of heuristic random replacements known to help improve matching, although often at the expense of clarity. + +To set up the permuter, clone the repository in a directory of your choice. Follow the usage section of the README and ensure you have all the prerequisites installed. + +```bash +./import.py +``` + +on the files to import the code on which to run the permuter to `nonmatchings/func`, and then + +```bash +./permuter.py +``` + +will run the permuter + +Flags: + +- `-jN` for multithreading +- `-J` for using permuter@home (ask in Discord for someone to vouch for you to use this). (Can be combined with `-jN`.) +- `--better-only` only report improvements on base score (and not ties) +- `--best-only` only report improvements on current best score +- `--stack-diffs` take into account differences in placement on the stack (ignored by default) + +More information on these can be found in the permuter's own documentation. There are macros that can be added to the C to get the permuter to run particular types of transformation; these are also detailed in its manual. + +### vbindiff + +Your fallback for anything that you need to correct that is not visible in `diff.py`. Typically you use it to open the nonmatching uncompressed ROM and the uncompressed baserom and look at the differences highlighted in red. `first_diff.py` will usually tell you where to look. Controls are detailed in the program itself. + +### Texture64 + +Probably the best of the Nintendo 64 texture viewing programs. It is quite simple, but very good for the one thing that it does. + +### Z64Utils + +Basically essential for convenient analysis of object files. Can analyse and display DisplayLists, some textures, skeletons, animations, and a few other resources. Download from . + +## Retired tools + +The following tools are hopefully rendered obsolete by the data extraction that has already been done. + +### `tools/overlayhelpers/ichaindis.py` + +Used for extracting the InitChain information automatically from the ROM. + +### `tools/overlayhelpers/colliderinit.py` + +Used for decompliling the Collider struct of an actor. To use colliderinit, you will need to know the address (VRAM or VROM) of the struct, and the type of collider. There are different types of colliderinits: `ColliderJntSph, ColliderTrisInit, ColliderQuadInit, ColliderSphereInit`. + +### `tools/overlayhelpers/colchkinfoinit.py` + +Similar to `colliderinit.py` but for `CollisionCheckInfoInit`s. + +### `tools/overlayhelpers/damage_table.py` + +Extracts a damagetable from its address. Can also reconvert existing damagetables should the format change. + +### `tools/vtxdis` + +Extracts vertex data from a file. Essentially irrelevant since MM requires extracting this data with ZAPD anyway. + +### Reservation Tracking + +We use a [Google Sheet](https://docs.google.com/spreadsheets/d/1X83YCPRa532v-Zo0WgUsJ2kB1X9RxBta5_p9aWA8uro/edit#gid=0) to keep track of all the files' decompilation statuses and their function statistics. On this board one can reserve a file to work on. The columns are + +- **Actor Id**: The enum that uniquely identifies the actor for spawning etc., useful for looking in KZ/VerboseOcarina/Spectrum. For `boot`/`code`, the VRAM of the file's .text start is given instead. +- **Overlay/File name**: Name of the Overlay or File in the codebase. +- **Function size statistics**: Intended as a crude estimate of how hard a file will be. Beginners should look for small largest function size and total size; the columns give a rough estimate of the distribution of function sizes without getting unnecessarily statistically descriptive. As you become more experienced, you should work on larger files to leave the smaller ones for other beginners. +- **Description**: What the file is. It's helpful if you can fill this in if you know! They should be synchronised with the short top-of-file descriptions. +- **Status**: (Free)/Reserved/PR/Merged. To be kept up-to-date by the reserver. +- **Reserved**: To reserve a file, put your Discord name in the "Reserved" column. It is common courtesy to not work on a file that is being worked on by another contributor, so ensure the "Reserved" column is blank before working on a file. If it is not, you can ask the reserver(s) if they want to release it or collaborate on it, but don't expect them to agree. More information on what is expected when you reserve a file is available in the [CONTRIBUTING.md](../CONTRIBUTING.md). +- **Interested**: If you would like to work on a file, but don't want to reserve it, or would be interested in collaboration, etc. You should talk to any Interested people if you want to work on the file. +- **Notes**: Any other useful information: partial progress by someone unable to finish the file, other files it works with, etc. From d5b71bd0f531986d2a6a63f0a90d8e1233e01a7f Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Thu, 16 Dec 2021 23:47:18 +0000 Subject: [PATCH 06/27] Tutorial (#362) * ObjTree OK, data imported * EnMs OK, data imported * And the spec * OK * Some minor edits * A lot of preliminary stuff * Mostly complete beginning * First draft of other functions doc * Whoops, forgot the GlobalContext pad * Draw functions (minus colour), create Data * Data * gitignore, some progress on documenting * Review comments, continue documenting * spec * Finish off documentation * undefined_syms * Add a couple of todos * One more * At least add tools for object decomp * Start conversion table stuff * Document ObjTree * Document EnMs * Add more tables to conversions * Maide's review * Review * Review * Typos and incomplete thoughts * Update vscode.md * Correct function/variable names * Review suggestions * Format * Missed one * Rename functions and format * Fix ObjTree * Update actorfixer.py, fix some variable names * Some review * Review suggestions * More review * Hopefully fix all the thisx references * Missed one --- .gitignore | 1 + docs/tutorial/advanced_control_flow.md | 747 ++++++++++++++++++ docs/tutorial/beginning_decomp.md | 675 ++++++++++++++++ docs/tutorial/contents.md | 56 ++ docs/tutorial/data.md | 171 ++++ docs/tutorial/diff_and_permuter.md | 145 ++++ docs/tutorial/disassembly_quirks.md | 36 + docs/tutorial/documenting.md | 601 ++++++++++++++ docs/tutorial/draw_functions.md | 303 +++++++ .../images/EnRecepgirl_Init_diff_matching.png | Bin 0 -> 115482 bytes .../images/EnRecepgirl_stack_diff.png | Bin 0 -> 14017 bytes docs/tutorial/images/En_Recepgirl.gv.png | Bin 0 -> 64180 bytes docs/tutorial/images/fresh_actor_data.png | Bin 0 -> 43984 bytes docs/tutorial/images/func_80C100DC_diff1.png | Bin 0 -> 48501 bytes docs/tutorial/images/func_80C100DC_diff2.png | Bin 0 -> 52908 bytes docs/tutorial/images/func_80C100DC_diff3.png | Bin 0 -> 54359 bytes docs/tutorial/images/func_80C102D4_diff1.png | Bin 0 -> 100966 bytes docs/tutorial/images/func_80C102D4_diff2.png | Bin 0 -> 112959 bytes docs/tutorial/images/z64utils_main.png | Bin 0 -> 31423 bytes .../images/z64utils_object_analyzed.png | Bin 0 -> 70998 bytes .../images/z64utils_object_analyzer.png | Bin 0 -> 11211 bytes .../images/z64utils_skeleton_error.png | Bin 0 -> 18512 bytes .../images/z64utils_skeleton_head.png | Bin 0 -> 95083 bytes docs/tutorial/introduction.md | 87 ++ docs/tutorial/merging.md | 97 +++ docs/tutorial/object_decomp.md | 14 + docs/tutorial/other_functions.md | 605 ++++++++++++++ docs/tutorial/types_structs_padding.md | 159 ++++ docs/tutorial/vscode.md | 84 ++ docs/useful_conversions.md | 275 +++++++ include/z64item.h | 13 +- include/z64object.h | 2 +- include/z64player.h | 8 +- spec | 9 +- src/code/code_8012EC80.c | 14 +- src/code/z_face_reaction.c | 2 +- .../actors/ovl_En_Bji_01/z_en_bji_01.c | 2 +- src/overlays/actors/ovl_En_Daiku/z_en_daiku.c | 2 +- src/overlays/actors/ovl_En_Fsn/z_en_fsn.c | 2 +- .../actors/ovl_En_Ma_Yto/z_en_ma_yto.c | 4 +- src/overlays/actors/ovl_En_Ms/z_en_ms.c | 162 +++- src/overlays/actors/ovl_En_Ms/z_en_ms.h | 10 +- src/overlays/actors/ovl_En_Muto/z_en_muto.c | 2 +- src/overlays/actors/ovl_En_Pm/z_en_pm.c | 2 +- .../actors/ovl_En_Recepgirl/z_en_recepgirl.c | 197 ++++- .../actors/ovl_En_Recepgirl/z_en_recepgirl.h | 11 +- src/overlays/actors/ovl_En_Sob1/z_en_sob1.c | 2 +- src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c | 148 +++- src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h | 13 +- tools/actorfixer.py | 162 ++++ tools/disasm/functions.txt | 32 +- tools/disasm/variables.txt | 6 +- tools/sizes/code_functions.csv | 284 +++---- undefined_syms.txt | 3 + 54 files changed, 4878 insertions(+), 270 deletions(-) create mode 100644 docs/tutorial/advanced_control_flow.md create mode 100644 docs/tutorial/beginning_decomp.md create mode 100644 docs/tutorial/contents.md create mode 100644 docs/tutorial/data.md create mode 100644 docs/tutorial/diff_and_permuter.md create mode 100644 docs/tutorial/disassembly_quirks.md create mode 100644 docs/tutorial/documenting.md create mode 100644 docs/tutorial/draw_functions.md create mode 100644 docs/tutorial/images/EnRecepgirl_Init_diff_matching.png create mode 100644 docs/tutorial/images/EnRecepgirl_stack_diff.png create mode 100644 docs/tutorial/images/En_Recepgirl.gv.png create mode 100644 docs/tutorial/images/fresh_actor_data.png create mode 100644 docs/tutorial/images/func_80C100DC_diff1.png create mode 100644 docs/tutorial/images/func_80C100DC_diff2.png create mode 100644 docs/tutorial/images/func_80C100DC_diff3.png create mode 100644 docs/tutorial/images/func_80C102D4_diff1.png create mode 100644 docs/tutorial/images/func_80C102D4_diff2.png create mode 100644 docs/tutorial/images/z64utils_main.png create mode 100644 docs/tutorial/images/z64utils_object_analyzed.png create mode 100644 docs/tutorial/images/z64utils_object_analyzer.png create mode 100644 docs/tutorial/images/z64utils_skeleton_error.png create mode 100644 docs/tutorial/images/z64utils_skeleton_head.png create mode 100644 docs/tutorial/introduction.md create mode 100644 docs/tutorial/merging.md create mode 100644 docs/tutorial/object_decomp.md create mode 100644 docs/tutorial/other_functions.md create mode 100644 docs/tutorial/types_structs_padding.md create mode 100644 docs/tutorial/vscode.md create mode 100644 docs/useful_conversions.md diff --git a/.gitignore b/.gitignore index b09a0acd3f..a6d3f3b8f5 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ tools/mips_to_c/ # Docs !docs/**/*.png +!.vscode/extensions.json # Per-user configuration .python-version diff --git a/docs/tutorial/advanced_control_flow.md b/docs/tutorial/advanced_control_flow.md new file mode 100644 index 0000000000..953e3e44d7 --- /dev/null +++ b/docs/tutorial/advanced_control_flow.md @@ -0,0 +1,747 @@ +# Advanced control flow + +Nice as `EnRecepgirl` was, she was somewhat lacking in complexity. In this document, we'll look at something rather more complicated than any of the functions she had. + +Again our example will be taken from a small NPC: this time, `EnMs` (Bean Seller). Most of its functions are even simpler than `EnRecepgirl`'s, and fairly quickly we can get to + +

+ + Large code block, click to show. + + +```C +#include "z_en_ms.h" + +#define FLAGS 0x00000009 + +#define THIS ((EnMs*)thisx) + +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx); +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnMs_Update(Actor* thisx, GlobalContext* globalCtx); +void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx); + +void func_80952734(EnMs* this, GlobalContext* globalCtx); +void func_809527F8(EnMs* this, GlobalContext* globalCtx); +void func_809529AC(EnMs* this, GlobalContext* globalCtx); +void func_80952A1C(EnMs *this, GlobalContext *globalCtx); + +const ActorInit En_Ms_InitVars = { + ACTOR_EN_MS, + ACTORCAT_NPC, + FLAGS, + OBJECT_MS, + sizeof(EnMs), + (ActorFunc)EnMs_Init, + (ActorFunc)EnMs_Destroy, + (ActorFunc)EnMs_Update, + (ActorFunc)EnMs_Draw, +}; + +static ColliderCylinderInitType1 D_80952BA0 = { + { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, + { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { 22, 37, 0, { 0, 0, 0 } }, +}; + +static InitChainEntry D_80952BCC[] = { + ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP), +}; + + +extern ColliderCylinderInitType1 D_80952BA0; +extern InitChainEntry D_80952BCC[]; + +extern AnimationHeader D_060005EC; +extern FlexSkeletonHeader D_06003DC0; + +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + Actor_ProcessInitChain(thisx, D_80952BCC); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06003DC0, &D_060005EC, this->jointTable, this->morphTable, 9); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &D_80952BA0); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); + Actor_SetScale(&this->actor, 0.015f); + this->actor.colChkInfo.mass = 0xFF; + this->actionFunc = func_80952734; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.gravity = -1.0f; +} + +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80952734(EnMs* this, GlobalContext* globalCtx) { + s16 temp_v1 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + + if (gSaveContext.inventory.items[10] == ITEM_NONE) { + this->actor.textId = 0x92E; + } else { + this->actor.textId = 0x932; + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + this->actionFunc = func_809527F8; + return; + } + + if (this->actor.xzDistToPlayer < 90.0f) { + if (ABS_ALT(temp_v1) < 0x2000) { + func_800B8614(&this->actor, globalCtx, 90.0f); + } + } +} + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s") + +void func_809529AC(EnMs *this, GlobalContext *globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.textId = 0; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = func_80952A1C; + } else { + func_800B8A1C(&this->actor, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +void func_80952A1C(EnMs *this, GlobalContext *globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_80151938(globalCtx, 0x936U); + this->actionFunc = func_809527F8; + } else { + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, -1); + } +} + +void EnMs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMs* this = THIS; + + Actor_SetHeight(&this->actor, 20.0f); + this->actor.targetArrowOffset = 500.0f; + Actor_SetScale(&this->actor, 0.015f); + SkelAnime_Update(&this->skelAnime); + this->actionFunc(this, globalCtx); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, + NULL, &this->actor); +} + +``` + +
+ +(Skipping any documentation we might have done.) Indeed, this actor is so simple so far that you can see why it wasn't worth using most of it for the rest of the tutorial. `func_809527F8` is a different story, however. We know it's an action function since it's set to the `actionFunc` in `func_80952A1C`. But mips2c gives us + +```bash +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s --context ctx.c --gotos-only +``` + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 != 4) { + if (temp_v0 != 5) { + if ((temp_v0 == 6) && (func_80147624(globalCtx) != 0)) { + this->actionFunc = func_80952734; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + if (func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + if (func_80147624(globalCtx) != 0) { + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 != 0) { + if (temp_v0_2 != 1) { + + } + func_8019F230(); + func_80151938(globalCtx, 0x934U); + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + func_801477B4(globalCtx); + if ((s32) gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if ((s32) gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } +} +``` + +which is long, messy, and contains some rather nasty-looking control flow, including horrors like + +```C + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 != 4) { + if (temp_v0 != 5) { + if ((temp_v0 == 6) && (func_80147624(globalCtx) != 0)) { + this->actionFunc = func_80952734; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } +``` + +If you read the OoT tutorial, you'll know these nested negated ifs all using the same variable are a good indicator that there's a switch. The problem is working out how to write it. + + +## Goto-only mode + +For didactic purposes, we'll use a feature of mips2c called goto-only mode to examine this. *This is not the only way of doing it*, but it is good practice for a beginner to this sort of control flow. Running + +```bash +../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s --context ctx.c --gotos-only +``` + +instead will produce + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + goto block_17; + } + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +block_11: + func_801477B4(globalCtx); + if ((s32) gSaveContext.rupees >= 0xA) { + goto block_13; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; +block_13: + if ((s32) gSaveContext.inventory.ammo[gItemSlots[0xA]] < 0x14) { + goto block_15; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; +block_15: + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; +block_16: + func_8019F230(); + func_80151938(globalCtx, 0x934U); +block_17: + return; +} +``` + +which in many ways looks worse: you can see why the use of gotos in code is strongly discouraged. However, if you throw this in `diff.py`, you'll find it's rather closer than you'd have thought. Goto-only mode has the advantages that +- code is always in the right order: mips2c has not had to reorder anything to get the ifs to work out +- it is often possible to get quite close with gotos, then start removing them, checking the matching status at each point. This is usually easier than trying to puzzle out the way it's trying to jump out of an `if ( || )` or similar. +- if you're trying to keep track of where you are in the code, the gotos mean that it is closer to the assembly in the first place. + +## Eliminating the gotos + +The simplest sort of block label to eliminate is one that is only used once, and where the corresponding goto jumps over a simple block of code with no extra internal control flow structure. There are two obvious examples of this here, the first being + +```C + if ((s32) gSaveContext.rupees >= 0xA) { + goto block_13; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; +block_13: +``` + +Currently, this says to jump over the code block `play_sound...` if the condition in the if is satisfied. In non-goto terms, this means that the block should be run if the condition is *not* satisfied. This also illustrates a general property of goto-only mode: you have to reverse the senses of all of the ifs. Therefore the appropriate approach is to swap the if round, put the code block inside, and remove the goto and the label: + +```C + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } +``` + +Likewise, one can do this with `block_15`. + +If you examine appropriate part of the diff, you will usually find that such eliminations make no, or very little, difference to the compiled code. + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + goto block_17; + } + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +block_11: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; +block_16: + func_8019F230(); + func_80151938(globalCtx, 0x934U); +block_17: + return; +} +``` + +We can't apply this rule any more, so we need to move on to the next: `block_17` just contains a `return`. So we can replace it by `return` everywhere it appears. + + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } + if (func_80147624(globalCtx) == 0) { + return; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) == 0) { + return; + } + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +block_11: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; +block_16: + func_8019F230(); + func_80151938(globalCtx, 0x934U); +} +``` + +Our next rule is about non-crossing blocks. If two code blocks do not contain any jumps between them, we can treat them separately. This is *almost* true for the code after `block_7`, were it not for the returns; of course returns are a special case because they can be used to be escape from a function at any point. This doesn't get us very far in this case, unfortunately, but it *does* tell us we can look at the second half of the function separately. + +Now let's start thinking about switches. A good indicator of a switch in goto-only mode is something like + +```C + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +``` + +because +- there are multiple ifs that are simple numeric comparisons of the same argument +- the goto blocks are in the same order as the ifs +- there is one last goto at the end that triggers if none of the ifs does: this sounds an awful lot like a `default`! + +So let us rewrite the entire second half as a switch: + +```C + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } +``` + +There's a couple of other obvious things here: +- the last `return` in `case 0` is unnecessary since there is no other code after the switch, so breaking is equivalent to the return` +- a common pattern everywhere, a sequence of ifs with returns as the last thing inside is the same as an if-else chain, so we can rewrite these as + +```C + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } +``` + +Well, at least the bottom half looks respectable now. Again, there is no code after the switch, so the next thing up, namely + +```C + if (func_80147624(globalCtx) == 0) { + return; + } +``` + +can be swapped round and made to wrap the switch. This leaves us with + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } + if (func_80147624(globalCtx) == 0) { + return; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } + } +} +``` + +Now, the top of the function also looks like a switch: +```C + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } +``` + +Interestingly, this time the blocks are the other way round. Also, the last statement is a `!=` rather than an `==`: this should be the default this time. The code order takes priority over the check order, because the compiler likes to put those in numerical order. There will be cases 4,5,6, but in the order 6,5,4, because that's how the code ordering goes. Also, notice that every case returns at the end: this means there's nothing else in the function after this switch, so everything after `block_7` is actually part of `case 4`. + +Putting all this together, we write down a function with no gotos in it: + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 6: + this->actionFunc = func_80952734; + break; + + case 5: + if (func_80147624(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + break; + + case 4: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } + } + break; + + default: + break; + } +} +``` + +Lastly, we can simplify `case 5` to replace the return in the if by the rest of the code, and we end up with + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 6: + this->actionFunc = func_80952734; + break; + + case 5: + if (func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + } + break; + + case 4: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } + } + break; + + default: + break; + } +} +``` + +And this matches! + +We will not document this now, although even with so few function named it seems pretty clear that it's to do with buying beans (and indeed, Magic Beans cost 10 Rupees and have Get Item ID `0x35`) You might like to try to match this function without using goto-only mode, to compare. It is also an interesting exercise to see what each elimination does to the diff: sometimes it will stray surprisingly far for a small change. diff --git a/docs/tutorial/beginning_decomp.md b/docs/tutorial/beginning_decomp.md new file mode 100644 index 0000000000..01cc21cf3b --- /dev/null +++ b/docs/tutorial/beginning_decomp.md @@ -0,0 +1,675 @@ +# Beginning decompilation: the Init function and the Actor struct + +Up: [Contents](contents.md) + +Open the C file and the H file with your actor's name from the appropriate directory in `src/overlays/actors/`. These will be the main files we work with. We will be using EnRecepgirl (the rather forward Mayor's receptionist in the Mayor's residence in East Clock Town) as our example: it is a nice simple NPC with most of the common features of an NPC. + +Each actor has associated to it a data file and one assembly file per function. During the process, we will transfer the contents of all or most of these into the main C file. VSCode's search feature usually makes it quite easy to find the appropriate files without troubling the directory tree. + + +## Anatomy of the C file + +The actor file starts off looking like: + +```C +// --------------- 1 --------------- +// --------------- 2 --------------- +#include "z_en_recepgirl.h" + +#define FLAGS 0x00000009 + +#define THIS ((EnRecepgirl*)thisx) + +// --------------- 3 --------------- +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); + +// --------------- 4 --------------- +#if 0 +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +#endif + +// --------------- 5 --------------- +extern InitChainEntry D_80C106C0[]; + +extern UNK_TYPE D_06001384; +extern UNK_TYPE D_06009890; +extern UNK_TYPE D_0600A280; + +// --------------- 6 --------------- +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") + +``` + +It is currently divided into six sections as follows: + +1. Description of the actor. This is not present for all actors, (and indeed, is not present here) but gives a short description based on what we know about the actor already. It may be inaccurate, so feel free to correct it after you understand the actor better, or add it. It currently has the form + +```C +/* + * File: z_en_recepgirl.c + * Overlay: ovl_En_Recepgirl + * Description: Mayor's receptionist + */ +``` + +2. Specific `include`s and `define`s for the actor. You may need to add more header files, but otherwise this section is unlikely to change. + +3. These are prototypes for the "main four" functions that almost every actor has. You add more functions here if they need to be declared above their first use. + +5. `if`'d-out section containing the `InitVars` and a few other common pieces of data. This can be ignored until we import the data. + +4. A set of `extern`s. These refer to the data in the previous section, and, data that comes from other files, usually in the actor's corresponding object file. The latter point to addresses in the ROM where assets are stored (usually collision data, animations or display lists). Once the corresponding object files have been decompiled, these will simply be replaced by including the object file (see [Object Decompilation](object_decomp.md) for how this process works). These symbols have been automatically extracted from the MIPS code. There may turn out to be some that were not caught by the script, in which case they need to be placed in the file called `undefined_syms.txt` in the root directory of the project. Ask in Discord for how to do this: it is simple, but rare enough to not be worth covering here. + +6. List of functions. Each `#pragma GLOBAL_ASM` is letting the compiler use the corresponding assembly file while we do not have decompiled C code for that function. The majority of the decompilation work is converting these functions into C that it looks like a human wrote. + + +## Header file + +The header file looks like this at the moment: + +```C +#ifndef Z_EN_RECEPGIRL_H +#define Z_EN_RECEPGIRL_H + +#include "global.h" + +struct EnRecepgirl; + +typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*); + +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ char unk_144[0x164]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ char unk_2AC[0x8]; +} EnRecepgirl; // size = 0x2B4 + +extern const ActorInit En_Recepgirl_InitVars; + +#endif // Z_EN_RECEPGIRL_H +``` + +The struct currently contains a variable that is the `Actor` struct, which all actors use one way or another, plus other items. Currently we don't know what most of those items are, so we have arrays of chars as padding instead, just so the struct is the right size. As we understand the actor better, we will be able to gradually replace this padding with the actual variables that the actor uses. + +The header file is also used to declare structs and other information about the actor that is needed by other files (e.g. by other actors): one can simply `#include` the header rather than `extern`ing it. + + +## Order of decompilation + +The general rule for order of decompilation is +- Start with `Init`, because it usually contains the most information about the structure of the actor. You can also do `Destroy`, which is generally simpler than `Init`. +- Next, decompile any other functions from the actor you have found in `Init`. You generally start with the action functions, because they return nothing and all take the same arguments, + +```C +void func_80whatever(EnRecepgirl* this, GlobalContext* globalCtx); +``` + +- Decompile each action function in turn until you run out. Along the way, do any other functions in the actor for which you have discovered the argument types. (You are probably better doing depth-first on action functions than breadth-first: it's normally easier to follow along one branch of the actions than be thinking about several at once.) + +- After you've run out, do `Update`. This usually provides the rest of the function tree, apart from possibly some draw functions. + +- Finally, do the draw functions. + +The above is a rough ordering for the beginner. As you become more experienced, you can deviate from this scheme, but the general principle remains that you should work on functions that you already know something about. (This is why it's good to start on actors: they are self-contained, we already know a lot about some of the functions, and the function flow tends to be both logical and provide information about every function.) + +## Data + +![Fresh actor data](images/fresh_actor_data.png) + +Associated to each actor is a `.data` file, containing data that the actor uses. This ranges from spawn positions, to animation information, to even assets that we have to extract from the ROM. Since the structure of the data is very inconsistent between actors, automatic importing has been very limited, so the vast majority must be done manually. + +There are two ways of transfering the data into an actor: we can either +- import it all naively as words (`s32`s), which will still allow it to compile, and sort out the actual types later, or +- we can extern each piece of data as we come across it, and come back to it later when we have a better idea of what it is. + +We will concentrate on the second here; the other is covered in [the document about data](data.md). Thankfully this means we essentially don't have to do anything to the data yet. Nevertheless, it is often quite helpful to copy over at least some of the data and leave it commented out for later replacement. *Data must go in the same order as in the data file, and data is "all or nothing": you cannot only import some of it*. + + +**WARNING** The way in which the data was extracted from the ROM means that there are sometimes "fake symbols" in the data, which have to be removed to avoid confusing the compiler. Thankfully it will turn out that this is not the case here. + +(Sometimes it is useful to import the data in the middle of doing functions: you just have to choose an appropriate moment.) + +Some actors also have a `.bss` file. This is just data that is initialised to 0, and can be imported immediately once you know what type it is, by declaring it without giving it a value. (bss is a significant problem for code files, but not *usually* for actors.) + + +## Init + +The Init function sets up the various components of the actor when it is first loaded. It is hence usually very useful for finding out what is in the actor struct, and so we usually start with it. (Some people like starting with Destroy, which is usually shorter and simpler, but gives some basic information about the actor, but Init is probably best for beginners.) + +### mips2c + +The first stage of decompilation is done by a program called mips_to_c, often referred to as mips2c, which constructs a C interpretation of the assembly code based on reading it very literally. This means that considerable cleanup will be required to turn it into something that firstly compiles at all, and secondly looks like a human wrote it, let alone a Zelda developer from the late '90s. + +The web version of mips2c can be found [here](https://simonsoftware.se/other/mips_to_c.py). This was [covered in the OoT tutorial](https://github.com/zeldaret/oot/blob/master/docs/tutorial/beginning_decomp.md). We shall instead use the repository. Clone [the mips_to_c repository](https://github.com/matt-kempster/mips_to_c) into a separate directory (we will assume on the same level as the `mm/` directory). Since it's Python, we don't have to do any compilation or anything in the mips_to_c directory. + +Since the actor depends on the rest of the codebase, we can't expect to get much intelligible out of mips2c without giving it some context. We make this using a Python script in the `tools` directory called `m2ctx.py`, so run +``` +$ ./tools/m2ctx.py +``` +from the main directory of the repository. In this case, the C file is `src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c`. This generates a file called `ctx.c` in the main directory of the repository. + +To get mips_to_c to decompile a function, the bare minimum is to run +``` +$ ../mips_to_c/mips_to_c.py +``` +(from the root directory of `mm`). We can tell mips2c to use the context file we just generated by adding `--context ctx.c`. If we have data, mips2c may be able to assist with that as well. + +In this case, we want the assembly file for `EnRecepgirl_Init`. You can copy the path to the file in VSCode or similar, or just tab-complete it once you know the directory structure well enough: it turns out to be `asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s`. + +**N.B.** You want the file in `nonmatchings`! the files in the other directories in `asm/` are the *unsplit* asm, which can be used, but is less convenient (you would need to include the rodata, for example, and it will do the whole file at once. This is sometimes useful, but we'll go one function at a time today to keep things simple). + +We shall also include the data file, which is located at `data/overlays/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s`. Hence the whole command will be +``` +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s --context ctx.c +? func_80C10148(EnRecepgirl *); // extern +extern FlexSkeletonHeader D_06011B60; +static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; +static s32 D_80C106C8 = 0; +InitChainEntry D_80C106C0[2]; // unable to generate initializer + +void EnRecepgirl_Init(EnRecepgirl *this, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain((Actor *) this, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +``` +Comment out the `GLOBAL_ASM` line for `Init`, and paste all of this into the file just underneath it: + +```C +[...] +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") +? func_80C10148(EnRecepgirl *); // extern +extern FlexSkeletonHeader D_06011B60; +static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; +static s32 D_80C106C8 = 0; +InitChainEntry D_80C106C0[2]; // unable to generate initializer + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain((Actor *) this, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +[...] +``` + + +Typically for all but the simplest functions, there is a lot that needs fixing before we are anywhere near seeing how close we are to the original code. You will notice that mips2c creates a lot of temporary variables. Usually most of these will turn out to not be real, and we need to remove the right ones to get the code to match. + +To allow the function to find the variables, we need another correction. Half of this has already been done at the top of the file, where we have + +```C +#define THIS ((EnRecepgirl*)thisx) +``` + +To do the other half, replace the recast at the beginning of the function, before any declarations: + +```C +EnRecepgirl* this = THIS; +``` + +Now everything points to the right place, even though the argument of the function seems inconsistent with the contents. + +(Again: this step is only necessary for the "main four" functions, and sometimes functions that are used by these: it relates to how such functions are used outside the actor.) + +While we are carrying out initial changes, you can also find-and-replace any instances of `(Actor *) this` by `&this->actor`. The function now looks like this: + +```C +? func_80C10148(EnRecepgirl *); // extern +extern FlexSkeletonHeader D_06011B60; +static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; +static s32 D_80C106C8 = 0; +InitChainEntry D_80C106C0[2]; // unable to generate initializer + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +``` + +### (Not) dealing with Data + +For now, we do not want to consider the data that mips2c has kindly imported for us: it will only get in the way when we want to rebuild the file to check for OK (`diff.py` will not care, but `make` will complain if it notices a symbol defined twice, and if some data is included twice the ROM will not match anyway). Therefore, put it in the `#if`'d out section and add some externs with the types: + +```C +#if 0 +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +static void* D_80C106B0[4] = { (void*)0x600F8F0, (void*)0x600FCF0, (void*)0x60100F0, (void*)0x600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +#endif + +extern void* D_80C106B0[]; +extern InitChainEntry D_80C106C0[]; +extern s32 D_80C106C8; +``` + +**N.B.** As is covered in more detail in [the document about data](data.md), the data *must* be declared in the same order in C as it was in the data assembly file: notice that the order in this example is `En_Recepgirl_InitVars`, `D_80C106B0`, `D_80C106C0`, `D_80C106C8`, the same as in `data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s`. + + +In the next sections, we shall sort out the various initialisation functions that occur in Init. This actor contains several of the most common ones, but it does not have, for example, a collider. The process is similar to what we discuss below, or you can check the OoT tutorial. + + + +### Init chains + +Almost always, one of the first items in `Init` is a function that looks like + +```C +Actor_ProcessInitChain(&this->actor, D_80C106C0); +``` + +which initialises common properties of actor using an InitChain, which is usually somewhere near the top of the data, in this case in the variable `D_80C106C0`. This is already included in the `#if`'d out data at the top if the file, so we don't have to do anything for now. We can correct the mips2c output for the extern, though: I actually did this when moving the rest of the data in the previous section. + + +### SkelAnime + +This is the combined system that handles actors' skeletons and their animations. It is the other significant part of most actor structs. We see its initialisation in this part of the code: +```C + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; +``` + +An actor with SkelAnime has three structs in the Actor struct that handle it: one called SkelAnime, and two arrays of `Vec3s`, called `jointTable` and `morphTable`. Usually, although not always, they are next to one another. + +There are two different sorts of SkelAnime, although for decompilation purposes there is not much difference between them. Looking at the prototype of `SkelAnime_InitFlex` from `functions.h` (or even the definition in `z_skelanime.c`), +```C +void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount); +``` +we can read off the types of the various arguments: +- The `SkelAnime` struct is at `this + 0x144` +- The `jointTable` is at `this + 0x188` +- The `morphTable` is at `this + 0x218` +- The number of limbs is `0x18 = 24` (we use dec for the number of limbs) +- Because of how SkelAnime works, this means that the `jointTable` and `morphTable` both have `24` elements + +Looking in `z64animation.h`, we find that `SkelAnime` has size `0x44`, and looking in `z64math.h`, that `Vec3s` has size `0x6`. Since ` 0x144 + 0x44 = 0x188 `, `jointTable` is immediately after the `SkelAnime`, and since `0x188 + 0x6 * 0x18 = 0x218`, `morphTable` is immediately after the `jointTable`. Finally, `0x218 + 0x6 * 0x18 = 0x2A8`, and we have filled all the space between the `actor` and `actionFunc`. Therefore the struct now looks like +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ char unk_2AC[0x8]; +} EnRecepgirl; // size = 0x2B4 +``` + +The last information we get from the SkelAnime function is the types of two of the externed symbols: `D_06011B60` is a `FlexSkeletonHeader`, and `D_06009890` is an `AnimationHeader`. So we can change/add these at the top of the C file: + +```C +extern InitChainEntry D_80C106C0[]; + +extern UNK_TYPE D_06001384; +extern AnimationHeader D_06009890; +extern UNK_TYPE D_0600A280; +extern FlexSkeletonHeader D_06011B60; +``` +As with the data, these externed symbols should be kept in increasing address order. + +They are both passed to the function as pointers, so need `&` to pass the address instead of the actual data. Hence we end up with +```C + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); +``` +note that `this->jointTable` and `this->morphTable` are arrays, so are already effectively pointers and don't need a `&`. + +### More struct variables: a brief detour into reading some assembly + +This function also gives us information about other things in the struct. The only other reference to `this` (rather than `this->actor` or similar) is in +```C +this->unk_2AC = 2; +``` +This doesn't tell us much except that at `this + 0x2AC` is a number of some kind. What sort of number? For that we will have to look in the assembly code. This will probably look quite intimidating the first time, but it's usually not too bad if you use functions as signposts: IDO will never change the order of function calls, and tends to keep code between functions in roughly the same place, so you can usually guess where you are. + +In this case, we are looking for `this + 0x2AC`. `0x2AC` is not a very common number, so hopefully the only mention of it is in referring to this struct variable. Indeed, if we search the file, we find that the only instruction mentioning `0x2AC` is here: +```mips +/* 0000B0 80C10080 24090002 */ addiu $t1, $zero, 2 +/* 0000B4 80C10084 A24902AC */ sb $t1, 0x2ac($s2) +``` +`addiu` ("add unsigned immediate") adds the last two things and puts the result in the register in the first position. So this says `$t1 = 0 + 2`. The next instruction, `sb` ("store byte") puts the value in the register in the first position in the memory location in the second, which in this case says `$s2 + 0x2ac = $t1`. We can go and find out what is in `$s2` is: it is set *all* the way at the top of the function, in this line: +```mips +/* 000008 80C0FFD8 00809025 */ move $s2, $a0 +``` +This simply copies the contents of the second register into the first one. In this case, it is copying the contents of the function's first argument into `$s2` (because it wants to use it later, and the `$a` registers are assumed to be cleared after a function call). In this case, the first argument is a pointer to `this` (well, `thisx`, but the struct starts with an `Actor`, so it's the same address). So line `B4` of the asm really is saving `2` into the memory location `this + 0x2AC`. + +Anyway, this tells us that the variable is a byte of some kind, so `s8` or `u8`: if it was an `s16/u16` it would have said `sh`, and if it was an `s32/u32` it would have said `sw`. Unfortunately this is all we can determine from this function: MIPS does not have separate instructions for saving signed and unsigned bytes. + +At this point you have two options: guess based on statistics/heuristics, or go and look in the other functions in the actor to find out more information. The useful statistic here is that `u8` is far more common than `s8`, but let's look in the other functions, since we're pretty confident after finding `0x2ac` so easily in `Init`. So, let us grep the actor's assembly folder: +``` +$ grep -r '0x2ac' asm/non_matchings/overlays/ovl_En_Recepgirl/ +asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s:/* 00065C 80C1062C 921902AC */ lbu $t9, 0x2ac($s0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 000114 80C100E4 908202AC */ lbu $v0, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 00012C 80C100FC A08E02AC */ sb $t6, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 000134 80C10104 A08002AC */ sb $zero, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 00015C 80C1012C 909802AC */ lbu $t8, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 000164 80C10134 A09902AC */ sb $t9, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s:/* 0000B4 80C10084 A24902AC */ sb $t1, 0x2ac($s2) +``` +in which we clearly see `lbu` ("load byte unsigned"), and hence this variable really is a `u8`. Hence we can add this to the actor struct too: +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AD */ char unk_2AD[0x7]; +} EnRecepgirl; // size = 0x2B4 +``` + +You might think that was a lot of work for one variable, but it's pretty quick when you know what to do. Obviously this would be more difficult with a more common number, but it's often still worth trying. + +Removing some of the declarations for data that we have accounted for, the function now looks like this: +```C +? func_80C10148(EnRecepgirl *); // extern + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); + + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +``` + +We have one significant problem and a few minor ones left. + +### Casts and boolean functions + +mips2c likes casting a lot: this is useful for getting types, less so when the type is changed automatically, such as in `Flags_GetSwitch(globalCtx, (s32) this->actor.params)`. Also, if we look at this function's definition, we discover it will only return `true` or `false`, so we can remove the `!= 0`. + +### Functions called + +One minor problem is what `func_80C10148` is: C needs a prototype to compile it properly. mips2c has offered us `? func_80C10148(EnRecepgirl *); // extern`, but this is obviously incomplete: there's no `?` type in C! We shall guess for now that this function returns `void`, for two reasons: +1. It's not used as a condition in a conditional or anything +2. It's not used to assign a value + +To this experience will add a third reason: +3. This is probably a setup function for an actionFunc, which are usually either `void (*)(ActorType*)` or `void (*)(ActorType*, GlobalContext*)`. + +The upshot of all this is to remove mips2c's `? func_80C10148(EnRecepgirl *); // extern`, and add a `void func_80C10148(EnRecepgirl* this);` underneath the declarations for the main four functions: +```C +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); + +void func_80C10148(EnRecepgirl* this); +``` + +(we usually leave a blank line after the main four, and put all further declarations in address order). + + +### Loops + +Loops are often some of the hardest things to decompile, because there are many ways to write a loop, only some of which will generate the same assembly. mips2c has had a go at the one in this function, but it usually struggles with loops: don't expect it to get a loop correct, well, at all. + +The code in question is +```C + void **temp_s0; + void **phi_s0; + +[...] + + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } +``` + +`D_80C106B0` is the array that mips2c has declared above the function, a set of 8-digit hex numbers starting `0x06`. These are likely to be *segmented pointers*, but this is not a very useful piece of information yet. `D_80C106C0` is the InitChain, though, and it seems pretty unlikely that it would be seriously involved in any sort of loop. Indeed, if you tried to compile this now, you would get an error: +``` +cfe: Error: src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c, line 61: Unacceptable operand of == or != + } while (temp_s0 != D_80C106C0); + -------------------------^ +``` +so this can't possibly be right. + +So what on earth is this loop doing? Probably the best thing to do is manually unroll it and see what it's doing each time. + +0. `phi_s0 = D_80C106B0`, aka `&D_80C106B0[0]`, to `temp_s0 = D_80C106B0 + 4`, i.e. `&D_80C106B0[1]`. But then `temp_s0->unk-4` is 4 backwards from `&D_80C106B0[1]`, which is back at `&D_80C106B0[0]`; the `->` means to look at what is at this address, so `temp_s0->unk-4` is `D_80C106B0[0]`. Equally, `*phi_s0` is the thing at `&D_80C106B0[0]`, i.e. `D_80C106B0[0]`. So the actual thing the first pass does is +```C + D_80C106B0[0] = Lib_SegmentedToVirtual(D_80C106B0[0]); +``` +it then proceeds to set `phi_s0 = &D_80C106B0[1]` for the next iteration. + +1. We go through the same reasoning and find the inside of the loop is +```C + temp_s0 = &D_80C106B0[2]; + D_80C106B0[1] = Lib_SegmentedToVirtual(D_80C106B0[1]); + phi_s0 = &D_80C106B0[2]; +``` + +2. +```C + temp_s0 = &D_80C106B0[3]; + D_80C106B0[2] = Lib_SegmentedToVirtual(D_80C106B0[2]); + phi_s0 = &D_80C106B0[3]; +``` + +3. +```C + temp_s0 = &D_80C106B0[4]; + D_80C106B0[3] = Lib_SegmentedToVirtual(D_80C106B0[3]); + phi_s0 = &D_80C106B0[4]; +``` +But now, `&D_80C106B0[4] = D_80C106B0 + 4 * 4 = D_80C106B0 + 0x10`, and `0x10` after this array's starting address is `D_80C106C0`, i.e. the InitChhain. Hence at this point the looping ends. + +So what this loop actually does is run `Lib_SegmentedToVirtual` on each element of the array `D_80C106B0`. + +At this point, I confess that I guessed what this loop does, and rewrote it how I would have written it, namely how one usually iterates over an array: +```C + s32 i; +[...] + for (i = 0; i < 4; i++) { + D_80C106B0[i] = Lib_SegmentedToVirtual(D_80C106B0[i]); + } +``` + +This is a dangerous game, since there is no guarantee that what you think is the right way to write something bears any relation to either what the original was like, or more importantly, what will give the same codegen as the original. This is a significant leap, since the original appears to be using a pointer iterator! + +However, this is certainly at least equivalent to the original (or at least, to what mips2c gave us: it's not infallible): we can be certain of this because we wrote the thing out in its entirety to understand it! This also allows us to eliminate one of the temps: you'll find with even simple loops mips2c will usually make two temps for the loop variable. + +Hence we end up with + +```C +void func_80C10148(EnRecepgirl* this); +[...] + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); + + if (D_80C106C8 == 0) { + for (i = 0; i < 4; i++) { + D_80C106B0[i] = Lib_SegmentedToVirtual(D_80C106B0[i]); + } + D_80C106C8 = 1; + } + + this->unk_2AC = 2; + + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + + func_80C10148(this); +} +``` +as our first guess. This doesn't look unreasonable... the question is, does it match? + +## Diff + +Once preliminary cleanup and struct filling is done, most time spent matching functions is done by comparing the original code with the code you have compiled. This is aided by a program called `diff.py`. + +In order to use `diff.py` with the symbol names, we need a copy of the code to compare against. In MM this is done as part of `make init`, and you can regenerate the `expected` directory (which is simply a known-good copy of `build` directory) by running `make diff-init`, which will check for an OK ROM and copy the build directory over. (Of course you need an OK ROM to do this; worst-case, you can checkout master and do a complete rebuild to get it). (You need to remake `expected` if you want to diff a function you have renamed: `diff.py` looks in the mapfiles for the function name, which won't work if the name has changed!) + +Now, we run diff on the function name: in the main directory, +``` +$ ./diff.py -mwo3 EnRecepgirl_Init +``` +(To see what these arguments do, run it with `./diff.py -h` or look in the scripts documentation.) + +![FeelsOKMan completely white diff](images/EnRecepgirl_Init_diff_matching.png) + +And err, well, everything is white, so it matches. Whoops. Guess we'll cover `diff.py` properly next time! (Notice that even though the diff is completely white, there are some differences in the `%hi`s and `%lo`s that access data, because it is now accessed with a relative address rather than an absolute one. If you have the data in the file in the right order, this shouldn't matter.) + +And with that, we have successfully matched our first function. + +**N.B** Notice that we don't yet have much idea of what this code actually does: this should be clarified by going through the rest of the actor's functions, which is discussed in the next document. + +Next: [Other functions in the actor](other_functions.md) diff --git a/docs/tutorial/contents.md b/docs/tutorial/contents.md new file mode 100644 index 0000000000..227f4fc7d4 --- /dev/null +++ b/docs/tutorial/contents.md @@ -0,0 +1,56 @@ +# Getting started + +## [Introduction to decomp](introduction.md) +- What we are doing +- Structure of the code + +## Pre-decompilation +- Building the repo (follow the instructions in the [README.md](../../README.md)) +- Most of us use VSCode. Some useful information is [here](vscode.md). + +- Choosing a first actor (You want something small that has simple interactions with the environment. A simple NPC can also work, and is what we will use as an illustration for most of the tutorial. There is a collection of actors we think are suitable for beginners on the spreadsheet or Trello) + +## Decompilation + +- [Begining decompilation: order, Init and the actor struct](beginning_decomp.md) + - Order of decompilation + - Init and common actor features + - Initchains + - Actors and dynapoly actors + - Colliders + - Skelanime + +- [The rest of the functions in the actor](other_functions.md) + - Order of decompilation + - Action Functions and other functions + +- [Draw functions](draw_functions.md) + +- [Data, migration and non-migration](data.md) + - Importing the data: early and late + - Segmented pointers + - Fake symbols + - Inlining + +## [Object Decompilation](object_decomp.md) (TODO) +- Object files +- How we decompile objects + +## After Decompilation + +- See the [CONTRIBUTING.md](../../CONTRIBUTING.md) for most of the details for submitting PRs. Remember to format again after making adjustments from reviews! +- More information about specific preparations is in [this document](merging.md). + +## Appendices +- [Types, Structs and Padding](types_structs_padding.md) (a miscellany of useful stuff) +- [Advanced control flow](advanced_control_flow.md) (an example of a more complex function which mips2c is not so good at) +- [Using the diff script and the permuter](diff_and_permuter.md) (using the diff script and the permuter to match something) + - control flow (branches) -> instruction ordering -> register allocation -> stack +- [Helper scripts] TODO: link when merged + +To be written, maybe + +- How we use git and GitHub +- Some notes on the basic structure of N64 MIPS +- Glossary +- Conventions diff --git a/docs/tutorial/data.md b/docs/tutorial/data.md new file mode 100644 index 0000000000..ae856123e9 --- /dev/null +++ b/docs/tutorial/data.md @@ -0,0 +1,171 @@ +# Data + +Up: [Contents](contents.md) +Previous: [Draw functions](draw_functions.md) + +## Table of Contents + +- [Data first](#data-first) +- [Extern and data last](#extern-and-data-last) +- [Segmented pointers](#segmented-pointers) +- [Fake symbols](#fake-symbols) +- [Inlining](#inlining) + +Each actor's data is stored in a separate file. EnRecepgirl's data is in `data/overlays/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s`, for example. At some point in the decompilation process we need to convert this raw data into recognisable information for the C to use. + +There are two main ways to do this: either +1. import the data first and type it later, or +2. wait until the data appears in functions, extern it, then import it at the end + +Sometimes something between these two is appropriate: wait until the largest or strangest bits of data appear in functions, get some typing information out of that, and then import it, but for now, let's stick to both of these. + +Both approaches have their advantages and disadvantages. + +## Data first + +This way is good for smaller actors with little data. The OoT tutorial [covers this in plenty of detail](https://github.com/zeldaret/oot/blob/master/docs/tutorial/data.md), and the process in MM is essentially identical, so we won't go over it here. + + +## Extern and data last + +Externing is explained in detail in the document about the [Init function](beginning_decomp.md). To summarize, every time a `D_address` appears that is in the data file, we put a +```C +extern UNK_TYPE D_address; +``` +at the top of the file, in the same order that the data appears in the data file. We can also give it a type if we know what the type actually is (e.g. for colliders, initchains, etc.), and convert the actual data and place it commented-out under the corresponding line. This means we don't have to do everything at once at the end. + +Once we have decompiled enough things to know what the data is, we can import it. The advantage of doing it this way is we should know what type everything is already: in our work on EnRecepgirl, for example, we ended up with the following data at the top of the file +```C +#if 0 +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +static void* D_80C106B0[4] = { (void*)0x600F8F0, (void*)0x600FCF0, (void*)0x60100F0, (void*)0x600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +#endif +``` +and the main thing we need to understand is `D_80C106B0` + +*Before doing anything else, make sure `make` gives `OK`.* + +First, we tell the compiler to ignore the original data file. To do this, open the file called `spec` in the main directory of the repository, and search for the actor name. You will find a section that looks like +``` +beginseg + name "ovl_En_Recepgirl" + compress + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.o" + include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.reloc.o" +endseg +``` +We will eventually remove both of the bottom two lines and replace them with our own reloc file, but for now, just comment out the data line: +``` +beginseg + name "ovl_En_Recepgirl" + compress + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + //include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.o" + include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.reloc.o" +endseg +``` + +Next remove all the externs, and uncomment their corresponding commented data: +```C +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +static void* D_80C106B0[4] = { (void*)0x600F8F0, (void*)0x600FCF0, (void*)0x60100F0, (void*)0x600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; +``` + +That should be everything, and we should now be able to `make` without the data file with no issues. + + +## Segmented pointers + +The game has a convenient system that allows it to sometimes effectively use offsets into a file instead of raw memory addresses to reference things. This is done by setting a file address to a *segment*. A segmented address is of the form `0x0XYYYYYY`, where `X` is the segment number. There are 16 available segments, and actors always set segment 6 to their object file, which is a file containing assets (skeleton, animations, textures, etc.) that they use. This is what all those `D_06...` are, and it is also what the entries in `D_80C106B0` are: they are currently raw numbers instead of symbols, though, and we would like to replace them. + +There is an obvious problem here, which is that is that these symbols have to be defined *somewhere*, or the linker will complain (indeed, if we change the ones in the array to `D_...`, even if we extern them, we get +``` +mips-linux-gnu-ld: build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o:(.data+0x20): undefined reference to `D_0600F8F0' +```` +As we'd expect, of course: we didn't fulfil our promise that they were defined elsewhere.) + +This is mitigated by use of the file `undefined_syms.txt`, which feeds the linker the raw addresses to use as the symbol definitions. If you find a segmented address that is not in already externed, `extern` it at the top of the file and add it to the actor's section in undefined_syms: +```C +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; +extern void* D_0600FCF0; + +static void* D_80C106B0[4] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; +``` +and in undefined_syms.txt: +``` +// ovl_En_Recepgirl +D_06000968 = 0x06000968; +D_06001384 = 0x06001384; +D_06009890 = 0x06009890; +D_0600A280 = 0x0600A280; +D_0600AD98 = 0x0600AD98; +D_0600F8F0 = 0x0600F8F0; +D_0600FCF0 = 0x0600FCF0; +D_060100F0 = 0x060100F0; +D_06011B60 = 0x06011B60; +``` + +We will come back and name these later when we do the object. + + +## Fake symbols + +Some symbols in the data have been decompiled wrongly, being incorrectly separated from the previous symbol due to how it was accessed by the actor's functions. However, most of these have now been fixed. Some more detail is given in [Types, structs and padding](types_structs_padding.md) If you are unsure, ask! + + +## Inlining + +After the file is finished, it is possible to move some static data into functions. This requires that: +1. The data is used in only one function +2. The ordering of the data can be maintained + +Additionally, we prefer to keep larger data (more than a line or two) out of functions anyway. + + +# Finally: .bss + +A .bss contains data that is uninitialised (actually initialised to `0`). For most actors all you need to do is declare it at the top of the actor file without giving it a value, once you find out what type it is. In `code`, it's much more of a problem. + +Next: [Documenting](documenting.md) \ No newline at end of file diff --git a/docs/tutorial/diff_and_permuter.md b/docs/tutorial/diff_and_permuter.md new file mode 100644 index 0000000000..aa72999d15 --- /dev/null +++ b/docs/tutorial/diff_and_permuter.md @@ -0,0 +1,145 @@ +# `diff.py` and the permuter + +This document is intended as a step-by-step demonstration of matching a reasonably complex function using the diff script `diff.py` and the decomp permuter, both included in the repo. For general information on both see [the tools documentation](../tools.md). + +Until such time as someone finds a suitable function, you can look at the OoT tutorial: [here for diff.py](https://github.com/zeldaret/oot/blob/master/docs/tutorial/beginning_decomp.md#diff) and [here for the permuter](https://github.com/zeldaret/oot/blob/master/docs/tutorial/other_functions.md#the-permuter). + + + + diff --git a/docs/tutorial/disassembly_quirks.md b/docs/tutorial/disassembly_quirks.md new file mode 100644 index 0000000000..dacfb78d81 --- /dev/null +++ b/docs/tutorial/disassembly_quirks.md @@ -0,0 +1,36 @@ +# Disassembly quirks + +As MM's disassembly is automatic, there are certain unique problems it has. + +## Renaming functions and variables + +A function must be renamed in `tools/disasm/functions.txt` in addition to the source code, for the disassembler to know what to call the symbol at that address when it sees it. + +Variables must be renamed in `tools/disasm/variables.txt`. It may also be necessary to change their type, count or size to stop the disassembler misusing them. + +You can avoid having to redisassemble every time by running `rename_global_asm.py`, which will rename the individual functions' assembly files in `asm/nonmatchings/` to the name of the function they contain. + + +## Fake and incorrect symbols + +TODO + + +## Resplitting a file + +The files `boot` and `code` are each divided up into dozens of separate files, that are all joined together into one text, data, rodata and bss section when building the ROM. As such, it has been necessary to guess where the file boundaries are, and not every file contains the correct functions or the correct data (rodata is mostly the exception since it is automatically split). + +To change a split for a file, find its entry in `tools/disasm/files.txt`, and change or create entries to accurately reflect where the file(s) should start. For example, it was found that the last function in `z_nmi_buff.c` had nothing to do with the rest, so it should be split into its own file. Looking up the address of the last function, it was found to be at `0x8010C1B0`, so adding the line: + +```diff + 0x8010C0C0 : "z_nmi_buff", ++++ 0x8010C1B0 : "code_8010C1B0", + 0x8010C230 : "z_olib", +``` + +to the file will extract it correctly as a separate file. It also is necessary to make a new C file and move the `GLOBAL_ASM` declaration into it. + +Unfortunately you essentially have to redisassemble after telling the disassembler to resplit a file. + + +## diff --git a/docs/tutorial/documenting.md b/docs/tutorial/documenting.md new file mode 100644 index 0000000000..9b2c8e177e --- /dev/null +++ b/docs/tutorial/documenting.md @@ -0,0 +1,601 @@ +# Documenting + +Up: [Contents](contents.md) +Previous: [Data](data.md) + +Decompilation is only the first step: since the point of this project is to understand the game better than ever before, the code needs documentation. In this document, we will go through the basic stuff that it's good to do for any actor: we will not try to understand every single thing the actor does in full detail, but try to name the functions and variables usefully for a full documentation pass later to take advantage of. + +It is helpful to document the functions and variables in the actor before you Pull Request it. The aim is to provide code that is sufficiently clear to be self-documenting, but it is worth leaving a comment on anything you find obscure or confusing. (Pull Request reviews will let you know if you are leaving too many comments.) Useful things to do documentation-wise: + +- Name all (or most) of the functions. +- Name all the variables in the actor struct. +- Create enums for params, and any other numbers that would benefit from that sort of clarity. + +You can test things using the practice rom for a retail version (watches and memory view is especially helpful), as well as the generated rom with Project 64 and something like Spectrum. + +If you want to use `diff.py` after renaming anything, particularly functions, remember to rerun `make diff-init` so it can use the correct symbols. + +Finally, *if you are not sure what something does, either ask or leave it unnamed: it will be less confusing later if things are unnamed than if they are wrongly named* + + +## Renaming things + +Because MM needs to regenerate the assembly code, it is necessary to tell the disassembler the names of functions and variables, so it knows what symbols to assign in the code. This is done via `functions.txt` and `variables.txt`. The best way to rename functions and symbols is via global rename in an editor like VSCode. The next best way is to run `tools/rename_sym.sh`. You should be careful with this script: it has no error-checking! + +Renaming symbols in theory requires re-disassembly. This can often be avoided in the case of functions by running `tools/rename_global_asm.py`, which will rename any individual functions' assembly files with the wrong names, so that the `GLOBAL_ASM`s can spot them. Renaming variables *may* require redisassembly (and if fake symbols are removed, it *will*). + + +## EnRecepgirl + +Currently, the file looks like this: +
+ +Large code block, click to show + + +```C +#include "z_en_recepgirl.h" + +#define FLAGS 0x00000009 + +#define THIS ((EnRecepgirl*)thisx) + +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); + +void func_80C10148(EnRecepgirl* this); +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); +void func_80C10290(EnRecepgirl* this); +void func_80C102D4(EnRecepgirl * this, GlobalContext * globalCtx); + +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; + +static void* D_80C106B0[4] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +extern AnimationHeader D_06000968; +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern AnimationHeader D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; + + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + s32 i; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); + + if (D_80C106C8 == 0) { + for (i = 0; i < 4; i++) { + D_80C106B0[i] = Lib_SegmentedToVirtual(D_80C106B0[i]); + } + D_80C106C8 = 1; + } + + this->unk_2AC = 2; + + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + + func_80C10148(this); +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s") +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") +void func_80C100DC(EnRecepgirl *this) { + if (this->unk_2AC != 0) { + this->unk_2AC++; + if (this->unk_2AC == 4) { + this->unk_2AC = 0; + return; + } + return; + } + if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC++; + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s") +void func_80C10148(EnRecepgirl *this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.s") +void func_80C10290(EnRecepgirl *this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = func_80C102D4; +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s") +void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if ((temp_v0_2 == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + if ((gSaveContext.weekEventReg[63] & 0x80)) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (this->actor.textId == 0x2ADC) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + if (this->actor.textId == 0x2ADD) { + this->actor.textId = 0x2ADE; + } else if (this->actor.textId == 0x2ADA) { + this->actor.textId = 0x2ADB; + } else { + this->actor.textId = 0x2AE0; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + s32 pad; + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos); + func_80C100DC(this); +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->unk_2AE.y; + } + return false; +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +``` + +
+ +(We can delete the `GLOBAL_ASM` lines now.) + +The worst part of documentation is finding somewhere to start. We have a decent place to start here, though, in that we already know the function (or rather, the use) of a couple of the functions, namely the LimbDraws. So we can rename `func_80C10558` to `EnRecepgirl_OverrideLimbDraw` and `func_80C10590` to `EnRecepgirl_UnkLimbDraw`. Remember to do a global rename so that the functions in the assembly are renamed, use `rename_global_asm`, +``` +$ ./tools/rename_global_asm.py +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s --> asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_OverrideLimbDraw.s +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s --> asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_UnkLimbDraw.s +``` +as well as the mentions in this chunk of `functions.txt`: +``` + 0x80C0FFD0:("EnRecepgirl_Init",), + 0x80C100CC:("EnRecepgirl_Destroy",), + 0x80C100DC:("func_80C100DC",), + 0x80C10148:("func_80C10148",), + 0x80C1019C:("func_80C1019C",), + 0x80C10290:("func_80C10290",), + 0x80C102D4:("func_80C102D4",), + 0x80C104E8:("EnRecepgirl_Update",), + 0x80C10558:("func_80C10558",), + 0x80C10590:("func_80C10590",), + 0x80C105EC:("EnRecepgirl_Draw",), +``` + +That's probably as much as we can do on functions for now. Next let's think about some of the variables. We have essentially 3 sorts of variable here +- struct variables +- data/bss +- intrafunction/stack variables + +and this is roughly the order of preference for naming them (although not necessarily the logical order to determine what they do). This actor is quite limited in the last category: only `sp30` is unnamed at the moment. Even though `func_800E9250` is decomped, the purpose of the argument in which `sp30` is placed is not clear (and, indeed, is not named), so it's probably best to leave it unnamed for now. (With greater experience, you might analyse `func_800E9250` to work out what this argument is for, but let's not worry about that for now.) + +As for the struct, there are two unnamed variables at the moment: +```C +typedef struct EnRecepgirl { + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[24]; + /* 0x218 */ Vec3s morphTable[24]; + /* 0x2A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x2AC */ u8 unk_2AC; + /* 0x2AE */ Vec3s unk_2AE; +} EnRecepgirl; // size = 0x2B4 +``` + +Let's start with `unk_2AC`. This is set to `2` in `Init`, something interesting happens to it in `func_80C100DC`, but it is used in the `Draw`, here: +```C + gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); +``` +So it is used as an index into the array `D_80C106B0`, and the element with that index is placed on segment `8`. So we need to work out what this array is to name `unk_2AC`. + +As we discussed last time, `D_80C106B0` is an array of [segmented pointers](data.md#segmented-pointers). Since they are in segment `6`, they are in the actor's object file. Which object? The InitVars tell us: namely, +```C +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, +``` +the fourth element is the object (it is actually an enum, but the file itself has the same name as the object enum). So, we need to look at the object file. We are very lucky that a custom tool has been written for such a thing: Z64Utils. + + +## Z64Utils + +The latest release of Z64Utils can be downloaded from [https://github.com/Random06457/Z64Utils/releases]. To use it with MM, you also need a json file to fill in the file names: the latest version can be obtained from [https://github.com/Random06457/Z64Utils-Config]. It should work on Wine. Some graphics cards don't love it, but the 3D graphical part is only required for skeleton and animations. + +Having downloaded and unzipped it, open the baserom file. This will populate the main window with a list: + +![Z64Utils' main window](images/z64utils_main.png) + +Search for the object file, right-click and select "Open in Object Analyzer". It will ask you to choose a segment: this is the segment that the file is put on, and allows Z64Utils to resolve the segmented addresses it references into symbols. The json already knows it should be segment `6`, so just click okay. This will open this window: + +![Z64Utils' object analyzer window](images/z64utils_object_analyzer.png) + +Go to "Analysis -> Find Dlists" and press OK (the defaults are usually fine). This will automatically search for displaylists in the object, which are a sufficiently distinctive format to be easy to find. We want to see the other stuff in the object too, so also do "Analysis -> Analyze Dlists". This will populate the window with even more stuff: + +![Z64Utils, with an analyzed object](images/z64utils_object_analyzed.png) + +We will talk about what all these types of data are next time, but for now, all we want to know is what +```C +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; +``` +actually are. We know they are set on segment 8, so we need to find where the skeleton uses them. We know from `extern FlexSkeletonHeader D_06011B60;` that this is at `0x06011B60`, so scroll down to it, right-click on it, and choose "Open in Skeleton Viewer". Pick an animation that we know it uses (sometimes Z64Utils misidentifies other things for animations), such as `extern AnimationHeader D_06000968;`, and you will get this error: + +![Z64Utils, error when viewing skeleton](images/z64utils_skeleton_error.png) + +It needs something to be set to segment `8`. Well, that's good, we know that the code does that! Let's find out what. Z64Utils tells you the address, so we can look up the displaylist that wants it: the relevant block is +```C +[...] +// Multi Command Macro Found (6 instructions) +0600DE70: gsDPLoadTLUT(256, 0x100, D_0600F6F0), +// Multi Command Macro Found (7 instructions) +0600DEA0: gsDPLoadTextureBlock(D_08000000, G_IM_FMT_CI, G_IM_SIZ_8b, 32, 32, 0, G_TX_MIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 5, 5, 0, 0), +0600DED8: gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, (63<<2), (31<<2)), +0600DEE0: gsSPVertex(D_0600B3F0, 19, 0), +0600DEE8: gsSP2Triangles(0, 1, 2, 0, 3, 4, 5, 0), +0600DEF0: gsSP2Triangles(6, 7, 5, 0, 8, 4, 3, 0), +0600DEF8: gsSP2Triangles(7, 6, 9, 0, 5, 10, 3, 0), +0600DF00: gsSP2Triangles(5, 7, 10, 0, 11, 9, 6, 0), +0600DF08: gsSP2Triangles(11, 12, 9, 0, 4, 1, 13, 0), +0600DF10: gsSP2Triangles(6, 14, 11, 0, 13, 5, 4, 0), +0600DF18: gsSP2Triangles(5, 14, 6, 0, 15, 14, 5, 0), +0600DF20: gsSP2Triangles(8, 1, 4, 0, 2, 1, 8, 0), +0600DF28: gsSP2Triangles(13, 16, 5, 0, 13, 14, 17, 0), +0600DF30: gsSP2Triangles(18, 11, 14, 0, 12, 11, 18, 0), +0600DF38: gsSP1Triangle(13, 1, 0, 0), +0600DF40: gsDPPipeSync(), +[...] + +``` +so we see that segment `8` is expecting a texture (we'll go into more detail about precisely what when we talk about making the XML file to extract the object). Therefore, `D_80C106B0` is a set of textures. We have a special type for textures, namely `TexturePtr`. + +## Back to the data + +But what sort of textures? This is an NPC, so what textures on the model would it want to change? The answer is of course the eyes: most NPCs have eye textures, with some sort of routine for changing them to appear to blink. We can set the different textures onto segment `8` and see which is which, but this is enough to know that `D_80C106B0` can be `sEyeTextures` (`s` for `static`: they essentially have to be static so that we can name them like this without the names clashing), and that `unk_2AC` is `eyeTexIndex` (these names are not completely standard, but it's best to be as consistent as possible). + +**N.B.** static data should not be renamed in the assembly or `variables.txt`, since assembly has no notion of file locality and there can be symbol clashes. Therefore it should only be renamed in its respective file, not globally. +```C +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; + +static TexturePtr sEyeTextures[] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; +``` + +And now it's rather more obvious what +```C +void func_80C100DC(EnRecepgirl* this) { + if (this->eyeTexIndex != 0) { + this->eyeTexIndex++; + if (this->eyeTexIndex == 4) { + this->eyeTexIndex = 0; + } + } else if (Rand_ZeroOne() < 0.02f) { + this->eyeTexIndex++; + } +} +``` +is doing: it's running a kind of blink routine. This is slightly nonstandard: usually there is a separate timer, but this one simply perturbs the index away from `0` every frame with a 2% chance. This sort of function is usually called `Blink` or `UpdateEyes`. Since it is explicitly called in `Update`, we'll call it `UpdateEyes`, but either is fine; we'll standardise later. + +We have two other pieces of data. There is a suggested name for the InitChain in the code already; just replace it and replace the first line in the definition. + +This leaves one piece of data unnamed, `D_80C106C8`. This is initially set to `0`, checked in `Init` to decide whether to run the loop, and then set to `1` after the loop is finished: +```C + if (D_80C106C8 == 0) { + for (i = 0; i < 4; i++) { + sEyeTextures[i] = Lib_SegmentedToVirtual(sEyeTextures[i]); + } + D_80C106C8 = 1; + } +``` +What is this doing? We need to understand that to name this variable. + +The N64's processors cannot use segmented addresses: they need actual RAM addresses. Therefore the segmented addresses have to be converted before being placed on a segment: this is what `Lib_SegmentedToVirtual` does. So (somewhat unusually) this loop is modifying the addresses in the actor's actual data in RAM. Having converted the addresses once, it wouldn't make any sense to convert them again, but `Init` would run every time an instantiation of the actor is created. Therefore `D_80C106C8` is present to ensure that the addresses only get converted once: it is really a boolean that indicates if the addresses have been converted. So let's call it `texturesDesegmented`, and replace its values by `true` and `false`. + +Finally, clearly `4` is linked to the data over which we're iterating: namely it's the size of the array. We have a macro for this, `ARRAY_COUNT(sEyeTextures)`. + +We've got one struct variable left. To find out what it does, we can look at a function that uses it, for example +```C +s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->unk_2AE.y; + } + return false; +} + +void EnRecepgirl_UnkLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} +``` +It is used to do a rotation of whatever limb `5` is. (The `+=` is because `rot->x` is the base rotation of the limb, and we have to add the same thing to it every frame to keep the angle changed and constant.) We can use Z64Utils to : setting segment `8` to one of what we know now are the eye textures, we can view the model in the skeleton viewer. The limb numbers in the object are one smaller than those in the actor (the root limb is only a concept for the code, not the object), so we find limb 4: + +![Z64Utils highlighting a limb](images/z64utils_skeleton_head.png) + +Hence this is changing the head rotation. An obvious name is `headRot`. + +## Functions + +Finally, we have to name the rest of the functions. Setup functions are usually named as `_Setup`, so we really only have to name two functions. They are both related to text. if we annotate all the textIds (do not quote the whole message, just give an unambiguous summary), the flow becomes a bit clearer: + +```C +void func_80C10148(EnRecepgirl* this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} + +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + this->actor.textId = 0x2367; // "... doesn't Kafei want to break off his engagement ... ?" + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; // hear directions again? + } else { + this->actor.textId = 0x2AD9; // "Welcome..." + } + } +} + +void func_80C10290(EnRecepgirl* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = func_80C102D4; +} + +void func_80C102D4(EnRecepgirl* this, GlobalContext* globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; // hear directions again? + func_80C10148(this); + } else if ((temp_v0_2 == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { // "Welcome..." + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + if (gSaveContext.weekEventReg[63] & 0x80) { // showed Couple's Mask to meeting + this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended) + } else { + this->actor.textId = 0x2ADA; // Mayor's office is on the left (meeting ongoing) + } + } else if (this->actor.textId == 0x2ADC) { // hear directions again? + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; // "So..." + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + + if (this->actor.textId == 0x2ADD) { // "So..." + this->actor.textId = 0x2ADE; // Mayor's office is on the left, drawing room on the right + } else if (this->actor.textId == + 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + this->actor.textId = 0x2ADB; // drawing room on the right + } else { + this->actor.textId = 0x2AE0; // drawing room on the right, don't go in without an appointment + } + } + func_80151938(globalCtx, this->actor.textId); + } +} +``` +All this branching is to make the conversation look more diverse and interesting. Notably, though, `func_80C1019C` is set to start with, and is only changed when `func_800B84D0(&this->actor, globalCtx) != 0`. This is something to do with talking. The other function handles the rest of the conversation, and hands back to the first if `func_80152498(&globalCtx->msgCtx) == 2`. This function is *something* to do with the text state, which will require `z_message` to be decomped. However, observation in-game will reveal this is something to do with ending dialogue. So we can conclude that the action functions are `EnRecepgirl_Wait` and `EnRecepgirl_Talk`. The setup functions are thus `EnRecepgirl_SetupWait` and `EnRecepgirl_SetupTalk`. + +For more complex actors, we have a tool called `graphovl.py` that can produce function flow graphs for actors: running +``` +$ ./tools/graphovl/graphovl.py En_Recepgirl +``` +produces + +![EnRecepgirl's function flow graph](images/En_Recepgirl.gv.png) + + +## Miscellaneous other documentation + +We like to make macros for reading an actor's `params` (indeed, this is required even if you don't know what the params are for). A simple example is `ObjTree`, which has the following code in its `Init` function: + +```c + if (this->dyna.actor.params & 0x8000) { + Actor_SetScale(&this->dyna.actor, 0.15f); + this->dyna.actor.uncullZoneForward = 4000.0f; + } else { + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } +``` + +Looking through the rest of the actor, it becomes apparent that `params & 0x8000` is only used for changing the size of the tree: ones with this bit set are larger. So we make a macro in the header: + +```c +#define OBJTREE_ISLARGE(thisx) ((thisx)->params & 0x8000) +``` + +Notice that we use `thisx`: this makes the form of every one of these macros the same. However, we only use `thisx` if required for matching, so when we add it to the actor, we use `&this->dyna.actor` (in this case, since `ObjTree` is a dynapoly actor). + +```c + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + Actor_SetScale(&this->dyna.actor, 0.15f); + this->dyna.actor.uncullZoneForward = 4000.0f; + } else { + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } +``` + +Much clearer! + + +We have now essentially documented this as far as we can without the object, so we'd better do that next. + +Next: [Analysing object files](object_decomp.md) diff --git a/docs/tutorial/draw_functions.md b/docs/tutorial/draw_functions.md new file mode 100644 index 0000000000..319d5efbb0 --- /dev/null +++ b/docs/tutorial/draw_functions.md @@ -0,0 +1,303 @@ +# Draw functions + +Up: [Contents](contents.md) +Previous: [The rest of the functions in the actor](other_functions.md) + +Draw functions behave completely differently from the other functions in an actor. They often use a lot of macros. + +This document will be a bit different: we will look at the draw functions in EnRecepgirl, then consider some more complicated examples. + +## A first example + +Unless it is completely invisible, an actor usually has a draw function as one of the main four actor functions. Hence its prototype looks like + +```C +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); +``` + +From now on, the process is rather different from the decompilation process used for the other functions. Here is the output of mips2c after sorting out the actor struct from Init, and with the arguments set back to `Actor* thisx`: +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor); // extern +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor); // extern +void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; + +void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + GraphicsContext *sp30; + Gfx *temp_v1; + GraphicsContext *temp_a0; + + temp_a0 = globalCtx->state.gfxCtx; + sp30 = temp_a0; + func_8012C28C(temp_a0); + temp_v1 = sp30->polyOpa.p; + sp30->polyOpa.p = temp_v1 + 8; + temp_v1->words.w0 = 0xDB060020; + temp_v1->words.w1 = (u32) D_80C106B0[this->unk_2AC]; + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, (Actor *) this); +} +``` + + +Notable features are the GraphicsContext temps, and blocks of the form + +```C + temp_v1 = sp30->polyOpa.p; + sp30->polyOpa.p = temp_v1 + 8; + temp_v1->words.w0 = 0xDB060020; + temp_v1->words.w1 = (u32) D_80C106B0[this->unk_2AC]; +``` + +(This is a particularly simple example, since there's only one of these blocks. We will give a more involved example later.) + +Each of these blocks converts into a graphics macro. They are usually (but not always) straightforward, but manually converting them is a pain, and there are sometimes special cases. To deal with them easily, we will use a tool from glank's N64 tools. To install these, follow the instructions [here](https://practicerom.com/public/packages/debian/howto.txt). + +For our purposes, we only need one of the programs this provides: `gfxdis.f3dex2`. + + +Graphics are actually 64-bit on the Nintendo 64. This code block is a result of instructions telling the processor what to do with the graphics pointer. There are two main types of graphics pointer (there are a couple of others used in `code`, but actors will only use these two), +- polyOpa ("opaque") for solid textures +- polyXlu ("Xlucent" i.e. "translucent") for translucent textures + +Our example is polyOpa, not surprisingly since our receptionist is solid. + +`words.w0` and `words.w1` contain the actual graphics instruction, in hex format. Usually, `w0` is constant and `w1` contains the arguments. To find out what sort of macro we are dealing with, we use `gfxdis.f3dex2`. `w1` is variable, but we need to give the program a constant placeholder. A common word to use is 12345678, so in this case we run +``` +gfxdis.f3dex2 -x -g "POLY_OPA_DISP++" -d DB06002012345678 +``` + +- `-x` uses hex instead of the default qu macros (never mind what those are, MM doesn't use them) +- `-g` is used to specify which graphics pointer macro to use +- `-d` is for the graphics dword + +Our standard now is to use decimal colors. If you have a constant second argument rather than a variable one, you can also use `-dc` to get decimal colors instead of the default hex. + +The output looks like +``` +gSPSegment(POLY_OPA_DISP++, 0x08, 0x12345678); +``` + +We can now replace the `0x12345678` by the actual second word, namely `D_80C106B0[this->unk_2AC]`. We can see mips2c has pulled in this data again: we saw it before in the `Init`. + +The words look like pointers to assets in the actor's object segment, which would make sense if we're looking for textures to draw. Because this data is used in a graphics macro, it will be either a displaylist or a texture; it may as well stay as `void*` until we come back to it later. + +```C +gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); +``` + +You repeat this for every block in the function. + +If you have worked on OoT, you will be aware of the functions `Graph_OpenDisps` and `Graph_CloseDisps`, and might be surprised to see them missing here. These functions are actually a debug feature: the `OPEN_DISPS` and `CLOSE_DISPS` macros still exist, but they don't expand to functions. Of course this means you have to guess where they go. A sensible guess for `OPEN_DISPS` is where the `gfxCtx` temp assignment first happens; `CLOSE_DISPS` is a bit harder, although it's basically just a `}`, so it *shouldn't* matter as much. + +It's sensible to eliminate all the `gfxCtx` temps and reintroduce as needed. Also remember to change the prototype and function definition back! +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") + +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +``` + +And this matches. + +The last two functions in the actor are used as arguments in `func_801343C0`. This is a `SkelAnime` function, except unlike the OoT ones, it has three function callback arguments instead of two: in `functions.h` or `z_skelanime.c`, we find +```C +void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor) +``` +The typedefs of the callbacks it uses are in `z64animation.h`: +```C +typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* actor); + +typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* actor); + +[...] + +typedef void (*UnkActorDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor); +``` +which is where mips2c got them from. + +In this case, only two of them are used, and it is these that are the last functions standing between us and a decompiled actor. + +## OverrideLimbDraw, PostLimbDraw, UnkActorDraw + +Well, we don't have a PostLimbDraw here, but as we see from the prototype, it's much the same as the OverrideLimbDraw but without the `pos` argument and no return value. +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor) { + if (limbIndex == 5) { + rot->x += actor->unk2B0; + } + return 0; +} +``` +Only two things to do here: we need to use `EnRecepgirl` to get to `actor + 0x2B0`, and the return value is used as a boolean, so we replace `0` by `false` (`true` means "don't draw the limb", and is hardly ever used). +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->unk_2AE.y; + } + return false; +} +``` + +As for the UnkActorDraw, it has a much simpler prototype. mips2c gives +```C +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor) { + if (limbIndex == 5) { + Matrix_RotateY((s16) (0x400 - actor->unk2AE), 1); + Matrix_GetStateTranslationAndScaledX(500.0f, (Vec3f *) &actor->focus); + } +} +``` +There is only minor cleanup needed here: +- recasting the last argument, +- replacing the last argument of `Matrix_RotateY` by the enum `MTXMODE_APPLY` (which means "use the current matrix instead of starting from a new identity matrix"), and the first argument by `0x400 - this->unk_2AE.x`. +- `(Vec3f *) &actor->focus` to `&actor->focus.pos` (this is the same issue as `(Actor*)this`, where mips2c doesn't climb deep enough into the struct). +```C +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} +``` + +## Some more examples: ObjTree + +Since EnRecepgirl was a bit light on graphics macros, we will look at an example that has a few more. A nice simple one is `ObjTree_Draw`: the original mips2c output is +```C +void ObjTree_Draw(Actor *thisx, GlobalContext *globalCtx) { + s16 sp36; + s16 sp34; + Gfx *sp28; + Gfx *sp20; + Gfx *temp_v0; + Gfx *temp_v0_2; + Gfx *temp_v0_3; + Gfx *temp_v0_4; + GraphicsContext *temp_a0; + GraphicsContext *temp_s0; + + sp36 = (s16) (s32) (f32) thisx->shape.rot.x; + sp34 = (s16) (s32) (f32) thisx->shape.rot.z; + temp_a0 = globalCtx->state.gfxCtx; + temp_s0 = temp_a0; + func_8012C28C(temp_a0); + temp_v0 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0 + 8; + temp_v0->words.w0 = 0xDA380003; + sp28 = temp_v0; + sp28->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); + temp_v0_2 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_2 + 8; + temp_v0_2->words.w1 = (u32) &D_06000680; + temp_v0_2->words.w0 = 0xDE000000; + Matrix_InsertRotation(sp36, 0, sp34, 1); + temp_v0_3 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_3 + 8; + temp_v0_3->words.w0 = 0xDA380003; + sp20 = temp_v0_3; + sp20->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); + temp_v0_4 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_4 + 8; + temp_v0_4->words.w1 = (u32) &D_060007C8; + temp_v0_4->words.w0 = 0xDE000000; +} +``` +We can see there are four blocks here, although only two different macros: +```C + temp_v0 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0 + 8; + temp_v0->words.w0 = 0xDA380003; + sp28 = temp_v0; + sp28->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); +``` +gfxdis gives +``` +$ gfxdis.f3dex2 -x -g POLY_OPA_DISP++ -d DA38000312345678 +gSPMatrix(POLY_OPA_DISP++, 0x12345678, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +``` +so it becomes +```C +gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +``` + +```C + temp_v0_2 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_2 + 8; + temp_v0_2->words.w1 = (u32) &D_06000680; + temp_v0_2->words.w0 = 0xDE000000; +``` +``` +$ gfxdis.f3dex2 -x -g POLY_OPA_DISP++ -d DE00000012345678 +gSPDisplayList(POLY_OPA_DISP++, 0x12345678); +``` +so this one is +```C +gSPDisplayList(POLY_OPA_DISP++, D_06000680); +``` + +```C + temp_v0_3 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_3 + 8; + temp_v0_3->words.w0 = 0xDA380003; + sp20 = temp_v0_3; + sp20->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); +``` +This is the same as the first one. Indeed, it's identical. +```C + temp_v0_4 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_4 + 8; + temp_v0_4->words.w1 = (u32) &D_060007C8; + temp_v0_4->words.w0 = 0xDE000000; +``` +This is the same as the second one, but with a different second word. + +Tidying up and inserting `OPEN_DISPS` and `CLOSE_DISPS`, we end up with +```C +void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx) { + s16 sp36 = (f32) thisx->shape.rot.x; + s16 sp34 = (f32) thisx->shape.rot.z; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06000680); + + Matrix_InsertRotation(sp36, 0, sp34, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_060007C8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +``` + +## RGB macros and bitpacking + +TODO: find some examples for this one. + +For even more examples, you can consult [the OoT tutorial](https://github.com/zeldaret/oot/blob/master/docs/tutorial/draw_functions.md) + +Next: [Data](data.md) diff --git a/docs/tutorial/images/EnRecepgirl_Init_diff_matching.png b/docs/tutorial/images/EnRecepgirl_Init_diff_matching.png new file mode 100644 index 0000000000000000000000000000000000000000..9fc473019221e4a0b4a4cde94efefe8982ed6bab GIT binary patch literal 115482 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⁣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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/func_80C100DC_diff1.png b/docs/tutorial/images/func_80C100DC_diff1.png new file mode 100644 index 0000000000000000000000000000000000000000..1f899b1b51460d6dcc5f0caa1ac6d5107f7999bb GIT binary patch literal 48501 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 G;Qs-mu=||= literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/func_80C100DC_diff3.png b/docs/tutorial/images/func_80C100DC_diff3.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d25c693e6050a14a568219c0f35d9a8f533e92 GIT binary patch literal 54359 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 XKVA41kn46020mv_8tLaAw+{JV!VOIV literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/func_80C102D4_diff2.png b/docs/tutorial/images/func_80C102D4_diff2.png new file mode 100644 index 0000000000000000000000000000000000000000..0fefcb43ced7e661bdaad3e7fb4fa927d2c01076 GIT binary patch literal 112959 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%0DXDfxF+VI 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/z64utils_object_analyzed.png b/docs/tutorial/images/z64utils_object_analyzed.png new file mode 100644 index 0000000000000000000000000000000000000000..9a2de8dac6b019bcd6c411fcd0f17186b52e2ec9 GIT binary patch literal 70998 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

lgN3#?wpdoP&~J^-nnC8oasX^k|JVi69-M zuJvZ$PXSgkdhf^N@CjsTl1>z)=!d;&h7IK7Dtz>O{o2sIdGoS}-A5KZXb&nxJo3f;Cu3>>QEYWJ2A_aUNhdRM-PHTWcEZBu9u)Bh+&kaTpu%o4+7OjE zz4my4E&HdFZ#psVTVzYJn_HbFT@jVHI)dU44(|&9os<;yOJS3D1a(@=@##(8jF}o(BRO1vC ze#rHs$@R;roD(}Zs}fQ7f;&2RZvx2T;~9NF32}0gfB7<}q$U*e@hJtQDp_LhG4TVR zSwkXWvy^r`F%0|tJNJ^^GYWk93%R*y11&E%L6w=_WC*&X-1{>VrteQMw(^HsCK=$i z7!3B|hXb{iWyX>oVcF@qdT5~qsi2=uejpLHl8XvZk<;EX_1DXvNw`XOey9KH@yTOa z-FGiL?(*EkiK!DYZHk$F#L4v6@At9wOf}q*W23qTxW4e9OtH3;-sO`6A$~78d;3pH z4t0M(S}8FxUN{i7-!FcCk{OZKxs{V(! zdNhp3YBxOfK)!g^W-L<+;Nm9`{ZK)0u^qY(mT!fdM{a?Epk&+e1$%Y%&W;7gN{Qh# zy=IgUp06*n7e$)eN;crDz`twyKPIGqyw8k`hq+3owd1DMpmZlD(#B5Vqmbd?IRz#Hc7bi}rw`>=REs}___v~Titn7%o=HoF3-ok>4O*baBdFmLealjInmjMxy$GwVV zy&3s3Pc6%Lm5-lLEPAS|8?d&>L0(_gu~W*Q$x~7UCm!c4kMj$k;WK~u>r?ZXvf~;< z)qmO_Kdt@r9-|h2E&dD<4>Fh2o;Sk(IaX4vR@%XXc~3K%L^I0nyXN3NDQn=&{VXCM z_j1C`J)dBNbBVa*4rTG(lTLm#dXJ0h{l3WXK3f(P(a>xkzpsJ<@1LFZ8Dvc94l`K8 zHdlXkt4M?P?0QBt&St@b)BYSw$}II17L zlA>i8UB7R1LZ>+s{7JU-G~*=DlOu?Hf92tnZO^Z}xtU9XTBKyQe;pBanGSum&WjVkL@ z&DzrKz9S789&szXekZIkYM5|GZU<$CoTBd;0lZ7OEhZHUh!1B&2JZWhcZ`tF`bG z7OIwZHB=DNMowh`+pYaZnTJmfgrNeBQOtW&<_CsxL8rS}QLSc{X3g)Ds5BNA|P{oTT z)3D7#M*2+}$|mv0ObZz^vs@JOgmKpx6wl8n_Pr>cP2&%pV9)HDp42pEaMV1GA%AT6n*5X#eCU{`Bd~%{DQ# zw`ZPn)6Bf1@rn=BjTuG4*=e&{Tqz%aa1id(y}Mg1G&nkS1!tG3Cp~cquhBwIvR~Dc z@@l&zDxDg=hf(i?L(P4wJRZ9BaBH8pMI>d*f@65L)NKMfwEd;Eti&Yh+XQ8&SSm&_ z^aaWM{E1FDP@Pl`+XUo$$34geIupveh+xGqnDx?bFKd z7VYak&D2d>Bt5+=ta&*GXb#lJ_SN8L(*73|zGsB^l z(Bjbq=MaCwO}3)y%fV-cQ!UxL=+Q=}N2oo@#fif#LCOjO`uQ^#AGL=GmxNK~6AQ#1 zZ{P>voENI+7bUAQ6vNhf{F>{)JOYTy-D6E}&52!oFqvd1%-meX `h<9Bta$Yxx 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, globalCtx)) { + this->actor.textId = 0; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = func_80952A1C; + } else { + func_800B8A1C(&this->actor, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} +``` + +which is intended to be as close to the original code as we can get just by looking at the assembly. We are doing *matching* decomp: in the right context, and with the right compiler settings, the above C compiles into *precisely* the assembly code above, not just equivalent code. + +N.B. We are using only publicly available code. In particular, we are not looking at any of the recent Nintendo source code leaks. + +Progress of the project can be found at [https://zelda64.dev]. The long-term goal of this project is to obtain a complete compilable version of the code for every publicly released version of Majora's Mask (in the same way as the Ocarina of Time project and many other Zelda games). *We are not working on a PC Port, and neither this project nor the ZeldaRET organisation will not be making one*, although the resulting code will be very useful if someone does intend to make such a port. + +Most of the discussion on the project takes place on the Zelda Decompilation Discord (linked in the [README.md](../../README.md)). We are very welcoming to newcomers and are happy to help you with any problems you might have with the decompilation process. + +## What do I need to know to take part? + +Basic knowledge of C, particularly arrays and pointers, is extremely useful. Knowledge of MIPS is not required initially, but if you are serious about decompilation you will soon pick up a lot of it. + +Knowledge of the fundamentals of git and GitHub is required. There are a number of tutorials available online, and a later document in this tutorial describes how you contribute to this project outside the actual decompilation process. + +The most useful knowledge to have is a general understanding of how the game works. An afternoon of constructive mucking about in the [Practice Rom](https://kz.zeldacodes.org/) (aka KZ) will be very beneficial if you have not looked at the game's subsurface workings before. + +## Structure of the code + +A lot of work has already been done on the code to bring it into a format that is easy to decompile. I will discuss actors, since this is where the majority of new people should begin. + +An *actor* is any thing in the game that moves or performs actions or interactions: Link is an actor, enemies are actors, NPCs are actors, props like grass are actors. The vast majority of actors are *overlays*, which means they are loaded only when the game needs them. + +In the code, each actor is associated to several files: there is +- the main .c file, e.g. `src/overlays/actors/ovl_En_Ms/z_en_ms.c` +- the actor's Header file, e.g. `src/overlays/actors/ovl_En_Ms/z_en_ms.h` +- various .o files that tell the `make` script how to incorporate it into building the ROM, + +and then for undecompiled actors, various assembly (.s) files, generally including: +- one for the actor's *data* (this usually includes things like its collision information about how to draw it, and various other stuff that is used in it), e.g. `data/overlays/actors/ovl_En_Ms.data.s` +- one for each function in the actor, e.g. `asm/non_matchings/overlays/actors/ovl_En_Ms/func_809529AC.s` + +(In this project, all assembly code and asset files are extracted from a user-provided ROM: if you look in the GitHub repository, you will see that only decompiled source code is present.) + +The basic process of decomp is to take one or more of the .s files, run it through a decompilation program (mips_to_c) that reads the ASM very literally, and then, through human ingenuity, reshape it into code that not only compiles in the first place, but completely matches the assembly generation of the original code (well-written or otherwise; it's also very likely that our constructed code differs significantly from the original, even if it still compiles to the same thing). diff --git a/docs/tutorial/merging.md b/docs/tutorial/merging.md new file mode 100644 index 0000000000..1d8c6ad1c2 --- /dev/null +++ b/docs/tutorial/merging.md @@ -0,0 +1,97 @@ +# The merging process + +Up: [Contents](contents.md) +Previous: [Documenting](documenting.md) + + +## Preparing to PR + +### Change the `spec` + +Specifically, to use the automatically generated reloc, rather than the original. In the case of an entirely matched actor, you find the section relating to the actor that you edited before: + +``` +beginseg + name "ovl_En_Recepgirl" + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + //include "build/data/overlays/actors/ovl_En_Recepgirl.data.o" + include "build/data/overlays/actors/ovl_En_Recepgirl.reloc.o" +endseg +``` + +and change to use our reloc: + +``` +beginseg + name "ovl_En_Recepgirl" + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + include "build/src/overlays/actors/ovl_En_Recepgirl/ovl_En_Recepgirl_reloc.o" +endseg +``` + +(copy the path, then copy the directory name and put `_reloc.o` after it). + +### Non-matchings + +If you can't match a function even with everyone's help in the `mm-decomp-help` discord channel, don't worry overlong about it. Hopefully you can get it to do the same thing as the original (non-matching), and then you set it up to use the original asm for the matching build, and your code for the non-matching. This looks like + +```c +#ifdef NON_MATCHING +// Helpful comment about the nature of the nonmatching +void function() { + // ... +} +#else +#pragma GLOBAL_ASM(asm/.../function.s) +#endif +``` + +in the C file. Also, due to the way `GLOBAL_ASM` works, we also cannot use generated reloc for overlays with nonmatchings, so we have to do the same thing for the reloc file in the spec: + +``` +beginseg + name "ovl_En_Recepgirl" + compress + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Recepgirl/ovl_En_Recepgirl_reloc.o" +#else + include "build/data/overlays/actors/ovl_En_Recepgirl.reloc.o" +#endif +endseg +``` + +Ideally you should at least be able to get a function to have equivalent behaviour; if not, and you have exhausted all other avenues of getting help, it should be marked in the C file as `NON_EQUIVALENT`, in the same way as a nonmatching. We do not change the spec for non-equivalents: they are treated the same as undecompiled code from a building perspective, lest they break things. + +### Format + +Run the formatting script `format.sh`, to format the C files in the standard way we use. If you have some arrays or struct definitions in your file, check that they have not been obnoxiously padded out: you can usually get a better format without a final comma for short things. + +**N.B.** this is now essential: the CI will fail immediately if it detects files that change when formatted. + +### Merge master + +To make sure the PR builds correctly with the current master, you need to merge `upstream/master` before you make the PR. This tends to break things, that you have to fix to get it to compile correctly again. + + +## Pull Requests + +Push commits to your fork of the repository on GitHub, and then open a pull request. Name the PR something sensible, like + +- `EnRecepgirl OK and documented` (if all the functions match and your documentation is fairly complete) +- `EnRecepgirl OK` (if all the functions match) +- `EnRecepgirl (n nonmatching)` (if you couldn't get one or more functions to match, but to the best of your knowledge they are equivalent code) +- `EnRecepgirl (n nonequivalent)` (if you couldn't get one or more functions to match, and do not believe the code in them has the same effect) + +and so on, although these four tend to cover most cases. Feel free to add a comment describing anything interesting you had to do or issues in non-matchings. + +Please also update the status of the file on Trello/the spreadsheet. + + +### Reviews + +Pull requests may be reviewed by anyone (who knows enough about the conventions of the project), and all must be reviewed and approved by two leads and one extra contributor. + +To implement suggestions made in reviews, it is generally easier to be consistent if you push more commits from your local branch. It is also quite possible that in the meantime some other PR has gone in, and git will ask you to merge master before you add more commits. This is normally fairly painless, although often you have to resolve merge conflicts. If in doubt, backup your work before doing anything, and ask in Discord before doing anything drastic, or if you don't understand what git is telling you. + +There is no need to wait for your PR to be approved and committed before working on your next file. diff --git a/docs/tutorial/object_decomp.md b/docs/tutorial/object_decomp.md new file mode 100644 index 0000000000..88fe89eca0 --- /dev/null +++ b/docs/tutorial/object_decomp.md @@ -0,0 +1,14 @@ +# Analysing object files + +Up: [Contents](contents.md) +Previous: [Documenting](documenting.md) + +TODO: To be written once automated objects are present. + +## Useful tools + +We are very fortunate that several nice tools have been written recently that are excellent for documenting asset files: +- [Z64Utils](https://github.com/Random06457/Z64Utils/releases), for looking at displaylists, textures they reference, the skeleton, animations, etc. +- [Texture64](https://github.com/queueRAM/Texture64/releases), for looking at textures in all the common N64 formats (needed since Z64Utils cannot interpret textures not explicitly referenced in displaylists currently) + +Next: [The merging process](merging.md) \ No newline at end of file diff --git a/docs/tutorial/other_functions.md b/docs/tutorial/other_functions.md new file mode 100644 index 0000000000..bdc49036da --- /dev/null +++ b/docs/tutorial/other_functions.md @@ -0,0 +1,605 @@ +# The rest of the functions in the actor + +Up: [Contents](contents.md) +Previous: [Beginning decompilation: the Init function and the Actor struct](beginning_decomp.md) + +## Now what? + +At this point we have a choice to make. Either we could follow the main function flow and decompile `func_80C10148`, or take a look at `Destroy`, which for smaller actors can often be done straight after Init, since it usually just removes colliders and deallocates dynapoly. + +## Destroy + +Destroy will be a dead end, but we might as well do it now. Usually we would regenerate the context first and apply it to mips2c as with `Init`, but if we look at the assembly... +```mips +glabel EnRecepgirl_Destroy +/* 0000FC 80C100CC AFA40000 */ sw $a0, ($sp) +/* 000100 80C100D0 AFA50004 */ sw $a1, 4($sp) +/* 000104 80C100D4 03E00008 */ jr $ra +/* 000108 80C100D8 00000000 */ nop +``` +It doesn't seem to do anything. Indeed, chucking it in mips2c, +``` +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s +void EnRecepgirl_Destroy(s32 arg0, ? arg1) { + +} +``` +so it really does do nothing. It is worth staying on this briefly to understand what is is doing, though. Even with no context, mips2c knows it takes two arguments because it does two saves onto the stack: the calling convention the N64 uses requires the first four arguments be saved from the registers onto the stack, since the registers are expected to be cleared when a function call happens. It's done a bad job of guessing what they are, but that's to be expected: the assembly only tells us they're words. Thankfully we already know in this case, so we can just replace the `GLOBAL_ASM` by +```C +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { + +} +``` +and cross this function off. + +## `func_80C10148` + +We don't really have a choice now, we have to look at this function. Remake the context (no need to change the function type this time), and run mips2c on the function's assembly file: +``` +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s --context ctx.c +extern AnimationHeader D_0600AD98; +extern ? func_80C1019C; + +void func_80C10148(EnRecepgirl *this) { + SkelAnime *temp_a0; + + temp_a0 = &this->skelAnime; + if (&D_06001384 == this->skelAnime.animation) { + this = this; + Animation_MorphToPlayOnce(temp_a0, &D_0600AD98, 5.0f); + } + this->actionFunc = &func_80C1019C; +} +``` + +This gives us some information immediately: `D_0600AD98` is an `AnimationHeader`, and `func_80C1019C` is set as the action function. This means that we know its type, even though mips2c does not: looking in the header, we see the typedef is +```C +typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*); +``` +and so we prototype `func_80C1019C` as +```C +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); +``` +at the top (were it above the function we're currently working on, the prototype could eventually be replaced by the function definition itself, but since it isn't, it goes at the top with the others). + +There are several rather odd things going on here: +- `temp_a0` is only used once. As such it's probably fake. +- There's a weird `this = this` that does nothing +- `if (&D_06001384 == this->skelAnime.animation)` is a bit of a funny way to write the condition: it seems more likely it would be the other way round. +- Also, if we look up `animation`, we find it is an `AnimationHeader*`, so `D_06001384` can be externed as `AnimationHeader`. +- `func_80C1019C` is already a pointer, so the `&` is ineffectual. Our style is to not use `&` on function pointers. + +If we tackle these, we end up with +```C + +void func_80C10148(EnRecepgirl* this); +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); + +[...] + +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern UNK_TYPE D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; + +[...] + +void func_80C10148(EnRecepgirl *this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} +``` +This is a common type of function called a setup (action) function. It runs once and prepares the ground for its corresponding actionfunction to run, whereas the actionfunction is usually run every frame by `Update` (but more on that later). Running `make`, we get OK again. + +Again we have only one way to go + + +## `func_80C1019C` + +Remake the context and run mips2c on this function's assembly file. We get +```C +? func_80C10290(EnRecepgirl *); // extern + +void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) { + SkelAnime *sp24; + SkelAnime *temp_a0; + + temp_a0 = &this->skelAnime; + sp24 = temp_a0; + if (SkelAnime_Update(temp_a0) != 0) { + if (&D_0600A280 == this->skelAnime.animation) { + Animation_MorphToPlayOnce(temp_a0, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(temp_a0, &D_06009890, -4.0f); + } + } + if (func_800B84D0((Actor *) this, globalCtx) != 0) { + func_80C10290(this); + return; + } + if (Actor_IsActorFacingLink((Actor *) this, 0x2000) != 0) { + func_800B8614((Actor *) this, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + return; + } + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + return; + } + this->actor.textId = 0x2AD9; + // Duplicate return node #12. Try simplifying control flow for better match + } +} +``` +This is a bit juicier! We can do some preliminary cleanup, then worry about the control flow. +- `sp24` does nothing, so is almost certainly fake. +- `temp_a0` is used in 3 different places, but they're all right next to one another and are unlikely to be required since there's no nontrivial calculation or anything happening. Let's remove it too and see what happens. +- We've got another reversed comparison, `&D_0600A280 == this->skelAnime.animation`. +- `D_0600A280` is an `AnimationHeader`. +- `(Actor *) this` should be replaced by `&this->actor`. +- `Flags_GetSwitch is a boolean and we don't need to cast the argument, as we have discussed before. (We don't know about the other functions in the conditions, so leave them for now.) +- Prototype `func_80C10290`: it is reasonable to guess it's another setup function, so `void func_80C10290(EnRecepgirl* this);`. + +Changing all these, we end up with +```C +void func_80C10148(EnRecepgirl* this); +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); +void func_80C10290(EnRecepgirl* this); + +[...] + +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern AnimationHeader D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; + +[...] + +void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (&D_0600A280 == this->skelAnime.animation) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + return; + } + if (Actor_IsActorFacingLink(&this->actor, 0x2000) != 0) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + return; + } + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + return; + } + this->actor.textId = 0x2AD9; + // Duplicate return node #12. Try simplifying control flow for better match + } +} +``` +If we look with diff.py, we find this matches. But we can replace some of the `return`s by `else`s: generally, we use elses unless +- After an `Actor_Kill` +- Sometimes after setting an actionfunction +- There's no way to avoid an early return + +Here, it's debatable whether to keep the first, since `func_80C10290` is likely a setup function. The latter two should be changed to elses, though. For now, let's replace all of them. This leaves us with +```C +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + } +} +``` +which still matches. Lastly, we have an enum for the output of `Player_GetMask` and other mask-related things: in `z64player.h` we find +```C +typedef enum { + /* 0x00 */ PLAYER_MASK_NONE, + /* 0x01 */ PLAYER_MASK_MASK_OF_TRUTH, + /* 0x02 */ PLAYER_MASK_KAFEIS_MASK, +[...] + /* 0x19 */ PLAYER_MASK_MAX +} PlayerMask; +``` +and so we can write the last if as `Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK`. + +Again, we have no choice in what to do next. + + +## `func_80C10290` + +Remaking the context and running mips2c gives +```C +void func_80C102D4(EnRecepgirl *, GlobalContext *); // extern + +void func_80C10290(EnRecepgirl *this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = func_80C102D4; +} +``` +so all we have to do is add the function prototype for the newest action function. Not surprisingly, this matches without changing anything. + + +## `func_80C102D4` + +
+ +Large code block, click to show + + +```C +extern AnimationHeader D_06000968; + +void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) { + SkelAnime *sp20; + AnimationHeader *temp_v0; + SkelAnime *temp_a0; + u16 temp_v0_3; + u16 temp_v0_4; + u8 temp_v0_2; + + temp_a0 = &this->skelAnime; + sp20 = temp_a0; + if (SkelAnime_Update(temp_a0) != 0) { + temp_v0 = this->skelAnime.animation; + if (&D_0600A280 == temp_v0) { + Animation_ChangeDefaultRepeat(sp20, &D_06001384); + } else if (&D_0600AD98 == temp_v0) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(sp20, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(sp20, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(sp20, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(sp20, &D_0600A280, -4.0f); + } + } + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + if (((temp_v0_2 & 0xFF) == 5) && (func_80147624(globalCtx) != 0)) { + temp_v0_3 = this->actor.textId; + if (temp_v0_3 == 0x2AD9) { + Actor_SetSwitchFlag(globalCtx, (s32) this->actor.params); + Animation_MorphToPlayOnce(sp20, &D_0600AD98, 10.0f); + if ((*(&gSaveContext + 0xF37) & 0x80) != 0) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (temp_v0_3 == 0x2ADC) { + Animation_MorphToPlayOnce(sp20, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(sp20, &D_06000968, 10.0f); + temp_v0_4 = this->actor.textId; + if (temp_v0_4 == 0x2ADD) { + this->actor.textId = 0x2ADE; + } else if (temp_v0_4 == 0x2ADA) { + this->actor.textId = 0x2ADB; + } else { + this->actor.textId = 0x2AE0; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} +``` + +
+ +Well, this is a big one! We get one more extern, for `D_06000968`. A lot of the temps used in the conditionals look fake, with the exception of `temp_v0_2`: because the function is only called once but the temp is used twice, the temp must be real. Removing the others and switching the `animation` conditionals, +```C +void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if (((temp_v0_2 & 0xFF) == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + if ((*(&gSaveContext + 0xF37) & 0x80) != 0) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (this->actor.textId == 0x2ADC) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + if (this->actor.textId == 0x2ADD) { + this->actor.textId = 0x2ADE; + } else if (this->actor.textId == 0x2ADA) { + this->actor.textId = 0x2ADB; + } else { + this->actor.textId = 0x2AE0; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} +``` +There remains one thing we need to fix before trying to compile it, namely `*(&gSaveContext + 0xF37) & 0x80`. This is really a funny way of writing an array access, because mips2c will get confused about arrays in structs. Opening up `z64save.h`, we find in the `SaveContext` struct that +```C + /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" + /* 0x0F5C */ u32 mapsVisited; // "area_arrival" +``` +so it's somewhere in `weekEventReg`. `0xF37 - 0xEF8 = 0x3F = 63`, and it's a byte array, so the access is actually `gSaveContext.weekEventReg[63] & 0x80`. Now it will compile. We also don't use `!= 0` for flag comparisons: just `if (gSaveContext.weekEventReg[63] & 0x80)` will do. + +Running `./diff.py -mwo3 func_80C102D4` and scrolling down, we discover that this doesn't match! + +![First run of diff.py on func_80C102D4](images/func_80C102D4_diff1.png) + +The yellow shows registers that don't match, the different colours on the registers help you to estimate where the problems are. Usually it's best to start at the top and work down if possible: any regalloc problems at the top tend to propagate most of the way down. In our case, the first problem is +``` +3f0: andi t0,v0,0xff r 153 3f0: andi t1,v0,0xff +``` +somehow we skipped over `t0`. Where is this in the code? The `153` in the middle is the line number in the C file (the `3f0`s are the offsets into the assembly file), we have `--source` if you want to see the code explicitly, or you can do it the old-fashioned way, and work it out from nearby function calls. In this case, `func_80C10148` is run straight after, and the only place that is called is +```C + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if (((temp_v0_2 & 0xFF) == 5) && (func_80147624(globalCtx) != 0)) { +``` + +If you look at the conditionals and the declaration of `temp_v0_2`, you may notice something odd: `temp_v0_2` is a `u8`. Therefore the `& 0xFF` does nothing! It's surprisingly common for this to happen, be it leaving out a `& 0xFF` or adding an extraneous one. If we remove it, we get a match: + +![func_80C102D4 now matching](images/func_80C102D4_diff2.png) + +Notice that indeed the subsequent regalloc, which might have looked like a bigger problem than the initial part, was also fixed: skipping a register in one place will throw the registers off below too. + +And now we've run out of functions. Time for `Update`. + + +## Update + +Update runs every frame and usually is responsible for the actor's common logic updates: for example, updating timers, blinking, updating collision, running the `actionFunc`, and so on, either directly or through other functions it calls. A lot of subsidiary functions that are not common to every state (e.g. updating position, or the text when talking, etc.) are carried out by one of the action functions we have already decomped. + +Remake the context and run mips2c: +```C +? func_80C100DC(EnRecepgirl *); // extern + +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + ? sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, (Actor *) this, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z); + func_80C100DC(this); +} +``` +If we search for `func_80C100DC`, we find that this is the only time it is used. Hence we can be almost certain that its prototype is `void func_80C100DC(EnRecepgirl* this);`. This function occurs above `Update`, so you can put the prototype next to the `GLOBAL_ASM` and remove it when we decompile that function. + +Change the function and the prototype back to `Actor* thisx`, and add the casting temp: +```C +void func_80C100DC(EnRecepgirl *); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") + +[...] + +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + ? sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z); + func_80C100DC(this); +} +``` +Now, our problem is `func_800E9250`. The arguments all look terrible! Indeed, if we look at the actual function in `src/code/code_800E8EA0.c` (found by searching), we find that it should be +```C +s32 func_800E9250(GlobalContext* globalCtx, Actor* actor, Vec3s* param_3, Vec3s* param_4, Vec3f param_5) +``` +So mips2c has made a bit of a mess here: +- the third argument should be a `Vec3s`. Hence `this + 0x2AE` is a `Vec3s*`, and so `this->unk_2AE` is a `Vec3s` +- `&sp30` is a `Vec3s*`, so `sp30` is a `Vec3s` (it's clearly not used for anything, just used to "dump" a side-effect of the function) +- The last argument is supposed to be an actual `Vec3f` + +Fixing all of this, we end up with +```C +void EnRecepgirl_Update(EnRecepgirl *this, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos); + func_80C100DC(this); +} +``` +and can fill in the top end of the struct: +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AD */ char unk_2AD[0x1]; + /* 0x02AE */ Vec3s unk_2AE; +} EnRecepgirl; // size = 0x2B4 +``` + +It's entirely possible that `unk_2AD` is not real, and is just padding: see [Types, structs, and padding](types_structs_padding.md) for the details. We'll find out once we've finished all the functions. If we look at the diff, we find that one line is different: + +![EnRecepgirl_Update's stack difference](images/EnRecepgirl_stack_diff.png) + +So `sp30` is in the wrong place: it's `4` too high on the stack in ours. This is because the main four functions do not actually take `GlobalContext`: they really take `Gamestate` and recast it with a temp, just like `EnRecepgirl* this = THIS;`. We haven't implemented this in the repo yet, though, so for now, it suffices to put a pad on the stack where it would go instead: experience has shown when it matters, it goes above the actor recast, so we end up with +```C +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + s32 pad; + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos); + func_80C100DC(this); +} +``` +and this now matches. + +**N.B.** sometimes using an actual `GlobalContext* globalCtx` temp is required for matching: add it to your bag o' matching memes. + +### *Some remarks about the function stack + +(Feel free to skip this if you'd rather finish the actor first.) + +The (function) stack is used to store variables. It has rather more space and is somewhat less volatile than registers (it still can't be used outside a function, except by a called function accessing its arguments). The stack a function sets up for itself to use is called its *stack frame* or *function frame* (or just *function stack* or *the stack*, although strictly speaking the frame itself is not a stack, since not just the top variable is accessed), and the function frames themselves form an (genuine) stack called the *call stack*. In MIPS this stack grows downwards, and its size is always a multiple of 0x8 (in case you want to put a 64-bit value on it, although almost no N64 game functions do this). The compiler uses the stack in a single function frame in the following way: + +| user-defined variables | +| compiler-defined varibles | +| saved registers | +| argument registers/stack | + +where sp is at the very bottom of this table, and the function that called the current function would have its frame above this one. We have seen a couple of aspects of this stack behaviour already: saving the function arguments onto it in [`EnRecepgirl_Destroy`](#destroy), and here, requiring an extre user stack variable to be the correct size. + +Anyway, back to EnRecepgirl. 4 functions to go... + +## `func_80C100DC` + +This is the final non-draw function. You know what to do now: remake the context and run mips2c: +```C +void func_80C100DC(EnRecepgirl *this) { + u8 temp_t6; + u8 temp_v0; + + temp_v0 = this->unk_2AC; + temp_t6 = temp_v0 + 1; + if (temp_v0 != 0) { + this->unk_2AC = temp_t6; + if ((temp_t6 & 0xFF) == 4) { + this->unk_2AC = 0; + return; + } + // Duplicate return node #5. Try simplifying control flow for better match + return; + } + if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC += 1; + } +} +``` + +Well, hmm. It's pretty hard to tell what's going on here. Finally it's time to really use `diff.py`. this function is a bit more typical of what to expect: this actor has been very easy so far! + +![func_80C100DC, first diff](images/func_80C100DC_diff1.png) + +Well, it's still *pretty* close. But the registers are all wrong. Firstly, `temp_t6` is already `u8`, so the `& 0xFF` is again ineffective, so let's try removing it... + +![func_80C100DC, second diff](images/func_80C100DC_diff2.png) + +It's not obvious that did much: it even looks a bit worse. +```C + temp_v0 = this->unk_2AC; + temp_t6 = temp_v0 + 1; + if (temp_v0 != 0) { + this->unk_2AC = temp_t6; +``` +may remind you of that loop we decompiled, where mips2c unnecessarily made two temps. Let's walk through what this does. +- First, it saves the value of `this->unk_2AC` into `v0` +- Then, it adds one to it and stores it in `t6`. +- It checks if the first saved value is zero +- If it is, it sets `this->unk_2AC` to the incremented value and carries on. + +Well, if we allow ourselves to bend the order of operations a little, there's a much simpler way to write this with no temps, namely +```C + if (this->unk_2AC != 0) { + this->unk_2AC++; +``` +So let's try removing both temps: +```C +void func_80C100DC(EnRecepgirl *this) { + if (this->unk_2AC != 0) { + this->unk_2AC++; + if (this->unk_2AC == 4) { + this->unk_2AC = 0; + return; + } + return; + } + if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC++; + } +} +``` + +![func_80C100DC, matching](images/func_80C100DC_diff3.png) + +There we go. + +Even though this matches, it is not quite according to our style: remember what was said earlier about early returns. Here, both of them can be removed and replaced by a single else without affecting matching: +```C +void func_80C100DC(EnRecepgirl *this) { + if (this->unk_2AC != 0) { + this->unk_2AC++; + if (this->unk_2AC == 4) { + this->unk_2AC = 0; + } + } else if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC++; + } +} +``` +and this is how we prefer it to be written. + +With that, the last remaining function is `EnJj_Draw`. Draw functions have an extra layer of macroing that is required, so we shall cover them separately. + +Next: [Draw functions](draw_functions.md) diff --git a/docs/tutorial/types_structs_padding.md b/docs/tutorial/types_structs_padding.md new file mode 100644 index 0000000000..dc72e0100b --- /dev/null +++ b/docs/tutorial/types_structs_padding.md @@ -0,0 +1,159 @@ +# Types, structs, and padding + +Reminders: +- In N64 MIPS, 1 word is 4 bytes (yes, the N64 is meant to be 64-bit, but it mostly isn't used like it in MM or OoT) +- A byte is 8 bits, or 2 hex digits + + +## Types + +The following are the common data types used everywhere: + +| Name | Size | Comment | +| ---- | ----- | -------- | +| char | 1 byte | character | +| u8 | 1 byte | unsigned byte | +| s8 | 1 byte | signed byte | +| u16 | 2 bytes | unsigned short | +| s16 | 2 bytes | signed short | +| u32 | 4 bytes/1 word | unsigned int | +| s32 | 4 bytes/1 word | signed int | +| void* | 4 bytes/1 word | pointer | +| uintptr_t | 4 bytes/1 word | pointer^ | +| intptr_t | 4 bytes/1 word | pointer^ | + +A pointer is sometimes mistaken for an `s32`. The last two, marked with `^`, are special types allowing for arithmetic on generic pointers, and are to be used over `u32`. + +`s32` is the default thing to use in the absence of any other information about the data. + +Useful data for guessing types: +- `u8` is about 7 times more common than `s8` +- `s16` is about 16 times more common than `u16` +- `s32` is about 8 times more common than `u32` + +Another useful thing to put here: the typedef for an action function is +```C +typedef void (*ActorNameActionFunc)(struct ActorName*, GlobalContext*); +``` +where you replace `ActorName` by the actual actor name as used elsewhere in the actor, e.g. `EnRecepgirl`. In MM these typedefs have been automatically generated, so you don't need to constantly copy from here or another actor any more. + + +## Some Common Structs + +Here are the usual names and the sizes of some of the most common structs used in actors and their structs: +| Type | Usual name | Size | +| ----------------------- | --------------------- | --------------- | +| `Actor` | `actor` | 0x144 | +| `DynaPolyActor` | `dyna` | 0x15C | +| `Vec3f` | | 0xC | +| `Vec3s` | | 0x6 | +| `SkelAnime` | `skelAnime` | 0x44 | +| `Vec3s[limbCount]` | `jointTable` | 0x6 * limbCount | +| `Vec3s[limbCount]` | `morphTable` | 0x6 * limbCount | +| `ColliderCylinder` | `collider` | 0x4C | +| `ColliderQuad` | `collider` | 0x80 | +| `ColliderJntSph` | `collider` | 0x20 | +| `ColliderJntSphElement` | `colliderElements[n]` | 0x40 * n | +| `ColliderTris` | `collider` | 0x20 | +| `ColliderTrisElement` | `colliderElements[n]` | 0x5C * n | + +Note that `Actor` and `DynaPolyActor` have changed size from OoT. + + +## Padding + +### Alignment + +A stored variable or piece of data does not always start immediately after the previous one: there may be padding in between: `0`s that are never written or referred to, and so ignored. This is to do with how the processor accesses memory: it reads 1 word at a time, so multibyte objects are aligned so they cross as few word boundaries as possible. + +The clearest example of this is that variables with types that are 1 word in size (`s32`s and pointers, for example) are automatically shifted so that they start at the beginning of the next word, i.e. at an offset ending with one of `0,4,8,C`: this is called 4-alignment. This will also happen to `s16`s, but with 2-alignment + +### Struct padding + +In actor structs, this manifests as some of the char arrays not being completely replaced by actual variables. + +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AE */ Vec3s unk_2AE; +} EnRecepgirl; // size = 0x2B4 +``` + +Notice that even though `unk_2AC` is a `u8`, `unk_2AE` is at `this + 0x2AE`, rather than `0x2AD`: we removed the extra char of padding while working on this actor. + +How do structs themselves align? A struct has the same alignment properties as its longest constituent (that is not itself a struct). For example, a `Vec3f` has 4-alignment, while a `Vec3s` has 2-alignment. + +A struct may also pad at the end: it will pad to the size of its largest non-struct element. Notably, every actor struct has size a whole number of words as well, so this phenomenon also occurs at the ends of structs. For example, ObjTree has the following actor struct: + +```C +typedef struct ObjTree { + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; + /* 0x01A8 */ ObjTreeActionFunc actionFunc; + /* 0x01AC */ f32 unk_1AC; + /* 0x01B0 */ s16 unk_1B0; + /* 0x01B2 */ s16 unk_1B2; + /* 0x01B4 */ s16 unk_1B4; +} ObjTree; // size = 0x1B8 +``` + +The struct pads to be `0x1B8` in size even though the last actual variable ends at `0x1B6`. + +For more information on this topic, there are plenty of guides elsewhere on the Internet, for example [The Lost Art of Structure Packing](http://www.catb.org/esr/structure-packing/). *The main thing to bear in mind for decomp purposes is that after finishing the functions, there may be some small parts of the actor struct that are just not used, because they were originally just struct padding.* + +### Padding at the end of sections + +In the ROM, each actor is layed out in the following order: + +- .text (Function instructions, separated into .s files, aka .text) +- .data (contents of the .data.s file) +- .rodata (read-only data, includes strings, floats, jumptables etc., almost entirely moved to the appropriate function files in the MM repo) +- .bss (varibles initialised to 0, not assigned a value when declared) +- .reloc (relocation information: you can ignore this) + +Each section is 0x10/16-aligned (qword aligned), i.e. each new section begins at an address with last digit `0`. This means that there can occur up to three words of padding at the end of each section. + +(The same occurs with any object divided into multiple .c files: each new file becomes 0x10 aligned.) + +#### Padding at the end of .text (function instructions) + +In function instructions, this manifests as a set of `nop`s at the end of the last function: for example, in EnRecepGirl, +``` +/* 0006B0 80C10680 27BD0038 */ addiu $sp, $sp, 0x38 +/* 0006B4 80C10684 03E00008 */ jr $ra +/* 0006B8 80C10688 00000000 */ nop +/* 0006BC 80C1068C 00000000 */ nop +``` + +the second `nop` is just extra `0`s of padding, as you can see in the machine code (third column in the comment) + +Once the rest of the functions match, this is automatic. So you never need to worry about these. + +#### Padding at the end of .data + +In data, the last entry may contain up to 3 words of 0s as padding. These can safely be removed when migrating data, but make sure that you don't remove something that actually is accessed by the function and happens to be 0! + +For example, in `ObjTree` we found that the last symbol in the data, +``` +glabel D_80B9A5BC +/* 00006C 80B9A5BC */ .word 0x08000000 +/* 000070 80B9A5C0 */ .word 0x00000000 +/* 000074 80B9A5C4 */ .word 0xFE000000 +/* 000078 80B9A5C8 */ .word 0x00000000 +/* 00007C 80B9A5CC */ .word 0x00000000 +``` +had 2 words of padding: only the first 3 words are actually used in the `CollisionCheckInfoInit2`. + +### Padding within the .data section + +Every distinct symbol in data is 4-aligned (word-aligned). So in the data, even if you have two `u8`s, they will be stored in addresses starting successive words: + +```C +u8 byte1 = 1 // will go to address ending in 0 +u8 byte2 = 2 // Will go to address ending in 4 +``` diff --git a/docs/tutorial/vscode.md b/docs/tutorial/vscode.md new file mode 100644 index 0000000000..91f2f659c4 --- /dev/null +++ b/docs/tutorial/vscode.md @@ -0,0 +1,84 @@ +# VSCode + +A lot of people on this project use VSCode as their coding environment. + +## Extensions + +There are a number of useful extensions available to make work more efficient: + +- C/C++ IntelliSense +- Clang-Format +- HexInspector (hover on numbers for float and other info) +- NumberMonger (convert hex to decimal and vice versa) +- ~~bracket pair colorizer 2~~ (now obsolete due to VSCode's built-in bracket colouring) +- Better MIPS Support + + + + +## Useful stuff to know: + +- Ctrl + Alt + Up/Down (on Windows, on Linux it's Ctrl + Shift + Up/Down or Shift + Alt + Up/Down) gives multicursors across consecutive lines. If you want several cursors in a more diverse arrangement, middle clicking works, at least on Windows. +- Alt + Up/Down moves lines up/down. +- Shift + Alt + Up/Down (Linux: Ctrl + Shift + Alt + Up/Down) copies lines up/down. +- Ctrl + P offers a box to use to search for and open files. +- Ctrl + Shift + P offers a box for commands like editing settings or reloading the window. + +- Make use of VSCode's search/search-and-replace features. + - Ctrl + Click goes to a definition. + - Ctrl + F for search in current file + - Ctrl + H for replace in current file + - Ctrl + Shift + F for search in all files + - Ctrl + Shift + H for replace in all files + - F2 for Rename symbol + +Many of VS Code's other shortcuts can be found on [its getting started page](https://code.visualstudio.com/docs/getstarted/keybindings), which also has links to OS-specific PDFs. + +## C/C++ configuration + +You can create a `.vscode/c_cpp_properties.json` file with `C/C++: Edit Configurations (JSON)` in the command box to customise how IntelliSense reads the repository (stuff like where to look for includes, flags, compiler defines, etc.) to make VSCode's IntelliSense plugin better able to understand the structure of the repository. This is a good default one to use for this project's repository: + +```jsonc +{ + "configurations": [ + { + "name": "Linux", + "compilerPath": "${default}", // Needs to not be "" for -m32 to work + "compilerArgs": [ + "-m32" // Removes integer truncation warnings with gbi macros + ], + "intelliSenseMode": "${default}", // Shouldn't matter + "includePath": [ // Matches makefile's includes + "${workspaceFolder}/**", + "src", + "assets", + "build", + "include" + ], + "defines": [ + "_LANGUAGE_C" // For gbi.h + ], + "cStandard": "gnu89", // C89 + some GNU extensions from C99 like C++ comments + "cppStandard": "${default}" // Only ZAPD uses C++, so doesn't really matter + } + ], + "version": 4 +} +``` + +## Settings + +Add the following to (or create) the `.vscode/settings.json` file for VSCode to search the gitignored asset and assembly files by default: + +```jsonc +{ + "search.useIgnoreFiles": false, + "search.exclude": { + "**/.git": true, + "baserom/**": true, + "build/**": true, + "expected/**": true, + "nonmatchings/**": true, + }, +} +``` diff --git a/docs/useful_conversions.md b/docs/useful_conversions.md new file mode 100644 index 0000000000..102c20daa0 --- /dev/null +++ b/docs/useful_conversions.md @@ -0,0 +1,275 @@ +# Useful conversions + +This article contains some useful conversion tables. Beware that we will omit the `0x` prefix on hex numbers: it will be evident from context which base is intended. + +- [Degrees and hex/binary angles](#degrees-and-hex-binary-angles) + * [Small angles](#small-angles) + * [Larger angles](#larger-angles) +- [Round decimal numbers in hex](#round-decimal-numbers-in-hex) + * [Small](#small) + * [Medium](#medium) + * [Large](#large) +- [Extra large](#extra-large) +- [Shifts/powers of 2 in dec and hex](#shifts-powers-of-2-in-dec-and-hex) + +## Degrees and hex/binary angles + +Conversion of degrees to binary angles in the two common ways, that give different answers. Table is produced using this script: + +```bash +$ printf "%s\t%s\t%s\n" "d" "d * 2^16/360" "2^16/360 * d" ; for i in {0..360..5} ; do printf "%d\t%X\t\t%X\n" "$i" $(( "$i" * 0x10000 / 360 )) $(( 0x10000 / 360 * "$i" )) ; done +``` + +### Small angles + +| `d` | `d * 2^16/360` | `2^16/360 * d` | +| ----: | -------------: | -------------: | +| 0 | 0 | 0 | +| 1 | B6 | B6 | +| 2 | 16C | 16C | +| 3 | 222 | 222 | +| 4 | 2D8 | 2D8 | +| 5 | 38E | 38E | +| 6 | 444 | 444 | +| 7 | 4FA | 4FA | +| 8 | 5B0 | 5B0 | +| 9 | 666 | 666 | +| 10 | 71C | 71C | +| 11 | 7D2 | 7D2 | +| 12 | 888 | 888 | +| 13 | 93E | 93E | +| 14 | 9F4 | 9F4 | +| 15 | AAA | AAA | +| 16 | B60 | B60 | +| 17 | C16 | C16 | +| 18 | CCC | CCC | +| 19 | D82 | D82 | +| 20 | E38 | E38 | +| 21 | EEE | EEE | +| 22 | FA4 | FA4 | +| 23 | 105B | 105A | +| 24 | 1111 | 1110 | +| 25 | 11C7 | 11C6 | +| 26 | 127D | 127C | +| 27 | 1333 | 1332 | +| 28 | 13E9 | 13E8 | +| 29 | 149F | 149E | +| 30 | 1555 | 1554 | + +### Larger angles + +| `d` | `d * 2^16/360` | `2^16/360 * d` | +| -----: | -------------: | -------------: | +| 0 | 0 | 0 | +| 5 | 38E | 38E | +| 10 | 71C | 71C | +| 15 | AAA | AAA | +| 20 | E38 | E38 | +| 25 | 11C7 | 11C6 | +| 30 | 1555 | 1554 | +| 35 | 18E3 | 18E2 | +| 40 | 1C71 | 1C70 | +| 45 | 2000 | 1FFE | +| 50 | 238E | 238C | +| 55 | 271C | 271A | +| 60 | 2AAA | 2AA8 | +| 65 | 2E38 | 2E36 | +| 70 | 31C7 | 31C4 | +| 75 | 3555 | 3552 | +| 80 | 38E3 | 38E0 | +| 85 | 3C71 | 3C6E | +| 90 | 4000 | 3FFC | +| 95 | 438E | 438A | +| 100 | 471C | 4718 | +| 105 | 4AAA | 4AA6 | +| 110 | 4E38 | 4E34 | +| 115 | 51C7 | 51C2 | +| 120 | 5555 | 5550 | +| 125 | 58E3 | 58DE | +| 130 | 5C71 | 5C6C | +| 135 | 6000 | 5FFA | +| 140 | 638E | 6388 | +| 145 | 671C | 6716 | +| 150 | 6AAA | 6AA4 | +| 155 | 6E38 | 6E32 | +| 160 | 71C7 | 71C0 | +| 165 | 7555 | 754E | +| 170 | 78E3 | 78DC | +| 175 | 7C71 | 7C6A | +| 180 | 8000 | 7FF8 | +| 185 | 838E | 8386 | +| 190 | 871C | 8714 | +| 195 | 8AAA | 8AA2 | +| 200 | 8E38 | 8E30 | +| 205 | 91C7 | 91BE | +| 210 | 9555 | 954C | +| 215 | 98E3 | 98DA | +| 220 | 9C71 | 9C68 | +| 225 | A000 | 9FF6 | +| 230 | A38E | A384 | +| 235 | A71C | A712 | +| 240 | AAAA | AAA0 | +| 245 | AE38 | AE2E | +| 250 | B1C7 | B1BC | +| 255 | B555 | B54A | +| 260 | B8E3 | B8D8 | +| 265 | BC71 | BC66 | +| 270 | C000 | BFF4 | +| 275 | C38E | C382 | +| 280 | C71C | C710 | +| 285 | CAAA | CA9E | +| 290 | CE38 | CE2C | +| 295 | D1C7 | D1BA | +| 300 | D555 | D548 | +| 305 | D8E3 | D8D6 | +| 310 | DC71 | DC64 | +| 315 | E000 | DFF2 | +| 320 | E38E | E380 | +| 325 | E71C | E70E | +| 330 | EAAA | EA9C | +| 335 | EE38 | EE2A | +| 340 | F1C7 | F1B8 | +| 345 | F555 | F546 | +| 350 | F8E3 | F8D4 | +| 355 | FC71 | FC62 | +| 360 | 10000 | FFF0 | + +Similarly for small angles with a smaller increment: + + + +## Round decimal numbers in hex + +```bash +printf "%s\t%s\n" "dec" "hex" ; for i in {0..100..5} ; do printf "%d\t%X\n" "$i" "$i" ; done +``` + +### Small + +| dec | hex | +| -----: | --: | +| 0 | 0 | +| 5 | 5 | +| 10 | A | +| 15 | F | +| 20 | 14 | +| 25 | 19 | +| 30 | 1E | +| 35 | 23 | +| 40 | 28 | +| 45 | 2D | +| 50 | 32 | +| 55 | 37 | +| 60 | 3C | +| 65 | 41 | +| 70 | 46 | +| 75 | 4B | +| 80 | 50 | +| 85 | 55 | +| 90 | 5A | +| 95 | 5F | +| 100 | 64 | + + +### Medium + +| dec | hex | +| -----: | ---: | +| 100 | 64 | +| 150 | 96 | +| 200 | C8 | +| 250 | FA | +| 300 | 12C | +| 350 | 15E | +| 400 | 190 | +| 450 | 1C2 | +| 500 | 1F4 | +| 550 | 226 | +| 600 | 258 | +| 650 | 28A | +| 700 | 2BC | +| 750 | 2EE | +| 800 | 320 | +| 850 | 352 | +| 900 | 384 | +| 950 | 3B6 | +| 1000 | 3E8 | + + +### Large + +| dec | hex | +| -----: | ----: | +| 1000 | 3E8 | +| 1500 | 5DC | +| 2000 | 7D0 | +| 2500 | 9C4 | +| 3000 | BB8 | +| 3500 | DAC | +| 4000 | FA0 | +| 4500 | 1194 | +| 5000 | 1388 | +| 5500 | 157C | +| 6000 | 1770 | +| 6500 | 1964 | +| 7000 | 1B58 | +| 7500 | 1D4C | +| 8000 | 1F40 | +| 8500 | 2134 | +| 9000 | 2328 | +| 9500 | 251C | +| 10000 | 2710 | + + +## Extra large +| dec | hex | +| -----: | ----: | +| 10000 | 2710 | +| 11000 | 2AF8 | +| 12000 | 2EE0 | +| 13000 | 32C8 | +| 14000 | 36B0 | +| 15000 | 3A98 | +| 16000 | 3E80 | +| 17000 | 4268 | +| 18000 | 4650 | +| 19000 | 4A38 | +| 20000 | 4E20 | +| 21000 | 5208 | +| 22000 | 55F0 | +| 23000 | 59D8 | +| 24000 | 5DC0 | +| 25000 | 61A8 | +| 26000 | 6590 | +| 27000 | 6978 | +| 28000 | 6D60 | +| 29000 | 7148 | +| 30000 | 7530 | + +## Shifts/powers of 2 in dec and hex + +```bash +$ printf "%s\t%s\t%s\n" "n" "1 << n (hex)" "1 << n (dec)" ; for i in {0..15..1} ; do printf "%d\t%X\t\t%d\n" "$i" $(( 1 << "$i" )) $(( 1 << "$i" )) ; done +``` +`1 << n` is the same as `2^n`. + +| `n` | `1 << n` (hex) | `1 << n` (dec) | +| -----: | -------------: | -------------: | +| 0 | 1 | 1 | +| 1 | 2 | 2 | +| 2 | 4 | 4 | +| 3 | 8 | 8 | +| 4 | 10 | 16 | +| 5 | 20 | 32 | +| 6 | 40 | 64 | +| 7 | 80 | 128 | +| 8 | 100 | 256 | +| 9 | 200 | 512 | +| 10 | 400 | 1024 | +| 11 | 800 | 2048 | +| 12 | 1000 | 4096 | +| 13 | 2000 | 8192 | +| 14 | 4000 | 16384 | +| 15 | 8000 | 32768 | + + diff --git a/include/z64item.h b/include/z64item.h index 82dc6e352f..d912169f2a 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -57,7 +57,7 @@ typedef enum { /* 0x07 */ SLOT_BOMBCHU, /* 0x08 */ SLOT_STICK, /* 0x09 */ SLOT_NUT, - /* 0x0A */ SLOT_BEAN, + /* 0x0A */ SLOT_MAGIC_BEANS, /* 0x0B */ SLOT_TRADE_KEY_MAMA, /* 0x0C */ SLOT_POWDER_KEG, /* 0x0D */ SLOT_PICTO_BOX, @@ -85,7 +85,7 @@ typedef enum { /* 0x23 */ SLOT_MASK_GORON, /* 0x24 */ SLOT_MASK_ROMANI, /* 0x25 */ SLOT_MASK_CIRCUS_LEADER, - /* 0x26 */ SLOT_MASK_KAFEI, + /* 0x26 */ SLOT_MASK_KAFEIS_MASK, /* 0x27 */ SLOT_MASK_COUPLE, /* 0x28 */ SLOT_MASK_TRUTH, /* 0x29 */ SLOT_MASK_ZORA, @@ -109,7 +109,7 @@ typedef enum { /* 0x07 */ ITEM_BOMBCHU, /* 0x08 */ ITEM_STICK, /* 0x09 */ ITEM_NUT, - /* 0x0A */ ITEM_BEAN, + /* 0x0A */ ITEM_MAGIC_BEANS, /* 0x0B */ ITEM_SLINGSHOT, /* 0x0C */ ITEM_POWDER_KEG, /* 0x0D */ ITEM_PICTO_BOX, @@ -146,7 +146,7 @@ typedef enum { /* 0x2C */ ITEM_DEED_OCEAN, /* 0x2D */ ITEM_ROOM_KEY, /* 0x2E */ ITEM_LETTER_MAMA, - /* 0x2F */ ITEM_LETTER_KAFEI, + /* 0x2F */ ITEM_LETTER_TO_KAFEI, /* 0x30 */ ITEM_PENDANT_MEMORIES, /* 0x31 */ ITEM_TINGLE_MAP, /* 0x32 */ ITEM_MASK_DEKU, @@ -154,7 +154,7 @@ typedef enum { /* 0x34 */ ITEM_MASK_ZORA, /* 0x35 */ ITEM_MASK_FIERCE_DEITY, /* 0x36 */ ITEM_MASK_TRUTH, - /* 0x37 */ ITEM_MASK_KAFEI, + /* 0x37 */ ITEM_MASK_KAFEIS_MASK, /* 0x38 */ ITEM_MASK_ALL_NIGHT, /* 0x39 */ ITEM_MASK_BUNNY, /* 0x3A */ ITEM_MASK_KEATON, @@ -294,6 +294,7 @@ typedef enum { /* 0x2A */ GI_NUTS_10 = 0x2A, /* 0x32 */ GI_SHIELD_HERO = 0x32, /* 0x33 */ GI_SHIELD_MIRROR, + /* 0x35 */ GI_MAGIC_BEANS = 0x35, /* 0x3C */ GI_KEY_SMALL = 0x3C, /* 0x3E */ GI_MAP = 0x3E, /* 0x3F */ GI_COMPASS, @@ -308,7 +309,7 @@ typedef enum { /* 0x7A */ GI_MASK_ZORA, /* 0x7B */ GI_MASK_FIERCE_DEITY, /* 0x7C */ GI_MASK_TRUTH, - /* 0x7D */ GI_MASK_KAFEI, + /* 0x7D */ GI_MASK_KAFEIS_MASK, /* 0x7E */ GI_MASK_ALL_NIGHT, /* 0x7F */ GI_MASK_BUNNY, /* 0x80 */ GI_MASK_KEATON, diff --git a/include/z64object.h b/include/z64object.h index 920a9e5dde..08423ab6c7 100644 --- a/include/z64object.h +++ b/include/z64object.h @@ -207,7 +207,7 @@ typedef enum { /* 0x0C3 */ OBJECT_GI_SHIELD_3, /* 0x0C4 */ OBJECT_UNSET_C4, /* 0x0C5 */ OBJECT_UNSET_C5, - /* 0x0C6 */ OBJECT_GI_BEAN, + /* 0x0C6 */ OBJECT_GI_MAGIC_BEANS, /* 0x0C7 */ OBJECT_GI_FISH, /* 0x0C8 */ OBJECT_UNSET_C8, /* 0x0C9 */ OBJECT_UNSET_C9, diff --git a/include/z64player.h b/include/z64player.h index e20b26ca7c..6b156372eb 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -36,7 +36,7 @@ typedef enum { typedef enum { /* 0x00 */ PLAYER_MASK_NONE, /* 0x01 */ PLAYER_MASK_TRUTH, - /* 0x02 */ PLAYER_MASK_KAFEI, + /* 0x02 */ PLAYER_MASK_KAFEIS_MASK, /* 0x03 */ PLAYER_MASK_ALL_NIGHT, /* 0x04 */ PLAYER_MASK_BUNNY, /* 0x05 */ PLAYER_MASK_KEATON, @@ -106,15 +106,15 @@ typedef enum { /* 0x2A */ PLAYER_AP_MOON_TEAR, /* 0x2B */ PLAYER_AP_DEED_LAND, /* 0x2C */ PLAYER_AP_ROOM_KEY, - /* 0x2D */ PLAYER_AP_LETTER_KAFEI, - /* 0x2E */ PLAYER_AP_BEAN, + /* 0x2D */ PLAYER_AP_LETTER_TO_KAFEI, + /* 0x2E */ PLAYER_AP_MAGIC_BEANS, /* 0x2F */ PLAYER_AP_DEED_SWAMP, /* 0x30 */ PLAYER_AP_DEED_MOUNTAIN, /* 0x31 */ PLAYER_AP_DEED_OCEAN, /* 0x33 */ PLAYER_AP_LETTER_MAMA = 0x33, /* 0x36 */ PLAYER_AP_PENDANT_MEMORIES = 0x36, /* 0x3A */ PLAYER_AP_MASK_TRUTH = 0x3A, - /* 0x3B */ PLAYER_AP_MASK_KAFEI, + /* 0x3B */ PLAYER_AP_MASK_KAFEIS_MASK, /* 0x3C */ PLAYER_AP_MASK_ALL_NIGHT, /* 0x3D */ PLAYER_AP_MASK_BUNNY, /* 0x3E */ PLAYER_AP_MASK_KEATON, diff --git a/spec b/spec index 94967bb0d3..ff445e731d 100644 --- a/spec +++ b/spec @@ -1627,8 +1627,7 @@ beginseg name "ovl_En_Ms" compress include "build/src/overlays/actors/ovl_En_Ms/z_en_ms.o" - include "build/data/ovl_En_Ms/ovl_En_Ms.data.o" - include "build/data/ovl_En_Ms/ovl_En_Ms.reloc.o" + include "build/src/overlays/actors/ovl_En_Ms/ovl_En_Ms_reloc.o" endseg beginseg @@ -4457,8 +4456,7 @@ beginseg name "ovl_Obj_Tree" compress include "build/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.o" - include "build/data/ovl_Obj_Tree/ovl_Obj_Tree.data.o" - include "build/data/ovl_Obj_Tree/ovl_Obj_Tree.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Tree/ovl_Obj_Tree_reloc.o" endseg beginseg @@ -5264,8 +5262,7 @@ beginseg name "ovl_En_Recepgirl" compress include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" - include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.o" - include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.reloc.o" + include "build/src/overlays/actors/ovl_En_Recepgirl/ovl_En_Recepgirl_reloc.o" endseg beginseg diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c index 3bd5aac928..34ad973f6d 100644 --- a/src/code/code_8012EC80.c +++ b/src/code/code_8012EC80.c @@ -45,7 +45,7 @@ void* gItemIcons[] = { 0x08007000, // ITEM_BOMBCHU 0x08008000, // ITEM_STICK 0x08009000, // ITEM_NUT - 0x0800A000, // ITEM_BEAN + 0x0800A000, // ITEM_MAGIC_BEANS 0x0800B000, // ITEM_SLINGSHOT 0x0800C000, // ITEM_POWDER_KEG 0x0800D000, // ITEM_PICTO_BOX @@ -82,7 +82,7 @@ void* gItemIcons[] = { 0x0802C000, // ITEM_DEED_OCEAN 0x0802D000, // ITEM_ROOM_KEY 0x0802E000, // ITEM_LETTER_MAMA - 0x0802F000, // ITEM_LETTER_KAFEI + 0x0802F000, // ITEM_LETTER_TO_KAFEI 0x08030000, // ITEM_PENDANT_MEMORIES 0x08031000, // ITEM_TINGLE_MAP 0x08032000, // ITEM_MASK_DEKU @@ -90,7 +90,7 @@ void* gItemIcons[] = { 0x08034000, // ITEM_MASK_ZORA 0x08035000, // ITEM_MASK_FIERCE_DEITY 0x08036000, // ITEM_MASK_TRUTH - 0x08037000, // ITEM_MASK_KAFEI + 0x08037000, // ITEM_MASK_KAFEIS_MASK 0x08038000, // ITEM_MASK_ALL_NIGHT 0x08039000, // ITEM_MASK_BUNNY 0x0803A000, // ITEM_MASK_KEATON @@ -180,7 +180,7 @@ u8 gItemSlots[] = { SLOT_BOMBCHU, // ITEM_BOMBCHU SLOT_STICK, // ITEM_STICK SLOT_NUT, // ITEM_NUT - SLOT_BEAN, // ITEM_BEAN + SLOT_MAGIC_BEANS, // ITEM_MAGIC_BEANS SLOT_TRADE_KEY_MAMA, // ITEM_SLINGSHOT SLOT_POWDER_KEG, // ITEM_POWDER_KEG SLOT_PICTO_BOX, // ITEM_PICTO_BOX @@ -217,7 +217,7 @@ u8 gItemSlots[] = { SLOT_TRADE_DEED, // ITEM_DEED_OCEAN SLOT_TRADE_KEY_MAMA, // ITEM_ROOM_KEY SLOT_TRADE_KEY_MAMA, // ITEM_LETTER_MAMA - SLOT_TRADE_COUPLE, // ITEM_LETTER_KAFEI + SLOT_TRADE_COUPLE, // ITEM_LETTER_TO_KAFEI SLOT_TRADE_COUPLE, // ITEM_PENDANT_MEMORIES SLOT_TRADE_COUPLE, // ITEM_TINGLE_MAP SLOT_MASK_DEKU, // ITEM_MASK_DEKU @@ -225,7 +225,7 @@ u8 gItemSlots[] = { SLOT_MASK_ZORA, // ITEM_MASK_ZORA SLOT_MASK_FIERCE_DEITY, // ITEM_MASK_FIERCE_DEITY SLOT_MASK_TRUTH, // ITEM_MASK_TRUTH - SLOT_MASK_KAFEI, // ITEM_MASK_KAFEI + SLOT_MASK_KAFEIS_MASK, // ITEM_MASK_KAFEIS_MASK SLOT_MASK_ALL_NIGHT, // ITEM_MASK_ALL_NIGHT SLOT_MASK_BUNNY, // ITEM_MASK_BUNNY SLOT_MASK_KEATON, // ITEM_MASK_KEATON @@ -260,7 +260,7 @@ s16 gItemPrices[] = { 0, // ITEM_BOMBCHU 0, // ITEM_STICK 0, // ITEM_NUT - 0, // ITEM_BEAN + 0, // ITEM_MAGIC_BEANS 0, // ITEM_SLINGSHOT 0, // ITEM_POWDER_KEG 0, // ITEM_PICTO_BOX diff --git a/src/code/z_face_reaction.c b/src/code/z_face_reaction.c index a6a6da5b39..d54561fdd5 100644 --- a/src/code/z_face_reaction.c +++ b/src/code/z_face_reaction.c @@ -3,7 +3,7 @@ /** * Indices of the columns of this array: * - index 0x00: PLAYER_MASK_TRUTH - * - index 0x01: PLAYER_MASK_KAFEI + * - index 0x01: PLAYER_MASK_KAFEIS_MASK * - index 0x02: PLAYER_MASK_ALL_NIGHT * - index 0x03: PLAYER_MASK_BUNNY * - index 0x04: PLAYER_MASK_KEATON diff --git a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c index fa8eb472fc..ee51c74444 100644 --- a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c +++ b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c @@ -144,7 +144,7 @@ void func_809CD028(EnBji01* this, GlobalContext* globalCtx) { } break; case PLAYER_FORM_HUMAN: - if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { this->textId = 0x236A; } else if (gSaveContext.weekEventReg[74] & 0x10) { this->textId = 0x5F6; diff --git a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 413dbdac65..40eac8099a 100644 --- a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -184,7 +184,7 @@ void func_809438F8(EnDaiku* this, GlobalContext* globalCtx) { s32 day = gSaveContext.day - 1; s32 pad2; - if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { if (this->unk_278 == ENDAIKU_PARAMS_FF_1) { this->actor.textId = 0x2365; } else { diff --git a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c index b25f19222a..bf159f7de6 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c @@ -130,7 +130,7 @@ u16 EnFsn_GetWelcome(GlobalContext* globalCtx) { case PLAYER_MASK_GORON: case PLAYER_MASK_ZORA: return 0x29FD; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: return 0x2364; default: return 0x29FE; diff --git a/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c b/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c index d89ed45821..6b55a48a74 100644 --- a/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c +++ b/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c @@ -1140,7 +1140,7 @@ void EnMaYto_DefaultStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { this->textId = 0x235E; break; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: EnMaYto_SetFaceExpression(this, 1, 2); func_801518B0(globalCtx, 0x235F, &this->actor); this->textId = 0x235F; @@ -1198,7 +1198,7 @@ void EnMaYto_DinnerStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { this->textId = 0x235E; break; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: func_801518B0(globalCtx, 0x235F, &this->actor); this->textId = 0x235F; break; diff --git a/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/src/overlays/actors/ovl_En_Ms/z_en_ms.c index e9a7793767..efc0ea175b 100644 --- a/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -1,7 +1,7 @@ /* * File: z_en_ms.c * Overlay: ovl_En_Ms - * Description: Bean salesman + * Description: Bean Seller */ #include "z_en_ms.h" @@ -15,7 +15,11 @@ void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMs_Update(Actor* thisx, GlobalContext* globalCtx); void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnMs_Wait(EnMs* this, GlobalContext* globalCtx); +void EnMs_Talk(EnMs* this, GlobalContext* globalCtx); +void EnMs_Sell(EnMs* this, GlobalContext* globalCtx); +void EnMs_TalkAfterPurchase(EnMs* this, GlobalContext* globalCtx); + const ActorInit En_Ms_InitVars = { ACTOR_EN_MS, ACTORCAT_NPC, @@ -28,38 +32,156 @@ const ActorInit En_Ms_InitVars = { (ActorFunc)EnMs_Draw, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80952BA0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInitType1 sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 22, 37, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80952BCC[] = { +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP), }; -#endif +extern AnimationHeader D_060005EC; +extern FlexSkeletonHeader D_06003DC0; -extern ColliderCylinderInit D_80952BA0; -extern InitChainEntry D_80952BCC[]; +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; -extern UNK_TYPE D_060005EC; + Actor_ProcessInitChain(thisx, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06003DC0, &D_060005EC, this->jointTable, this->morphTable, 9); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); + Actor_SetScale(&this->actor, 0.015f); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; // Eating Magic Beans all day will do that to you + this->actionFunc = EnMs_Wait; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.gravity = -1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Init.s") +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_80952734.s") +void EnMs_Wait(EnMs* this, GlobalContext* globalCtx) { + s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s") + if (gSaveContext.inventory.items[SLOT_MAGIC_BEANS] == ITEM_NONE) { + this->actor.textId = 0x92E; // "[...] You're the first customer [...]" + } else { + this->actor.textId = 0x932; // "[...] So you liked my Magic Beans [...]" + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_809529AC.s") + if (func_800B84D0(&this->actor, globalCtx) != 0) { + this->actionFunc = EnMs_Talk; + } else if ((this->actor.xzDistToPlayer < 90.0f) && (ABS_ALT(yawDiff) < 0x2000)) { + func_800B8614(&this->actor, globalCtx, 90.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_80952A1C.s") +void EnMs_Talk(EnMs* this, GlobalContext* globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 6: + if (func_80147624(globalCtx) != 0) { + this->actionFunc = EnMs_Wait; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Update.s") + case 5: + if (func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + func_800B8A1C(&this->actor, globalCtx, GI_MAGIC_BEANS, this->actor.xzDistToPlayer, + this->actor.playerHeightRel); + this->actionFunc = EnMs_Sell; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Draw.s") + case 4: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: // yes + func_801477B4(globalCtx); + if (gSaveContext.rupees < 10) { + play_sound(NA_SE_SY_ERROR); + func_80151938(globalCtx, 0x935); // "[...] You don't have enough Rupees." + } else if (AMMO(ITEM_MAGIC_BEANS) >= 20) { + play_sound(NA_SE_SY_ERROR); + func_80151938(globalCtx, 0x937); // "[...] You can't carry anymore." + } else { + func_8019F208(); + func_800B8A1C(&this->actor, globalCtx, GI_MAGIC_BEANS, 90.0f, 10.0f); + func_801159EC(-10); + this->actionFunc = EnMs_Sell; + } + break; + + case 1: // no + default: + func_8019F230(); + func_80151938(globalCtx, 0x934); // "[...] Well, if your mood changes [...]" + break; + } + } + break; + default: + break; + } +} + +void EnMs_Sell(EnMs* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.textId = 0; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = EnMs_TalkAfterPurchase; + } else { + func_800B8A1C(&this->actor, globalCtx, GI_MAGIC_BEANS, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +void EnMs_TalkAfterPurchase(EnMs* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_80151938(globalCtx, 0x936); // "You can plant 'em whenever you want [...]" + this->actionFunc = EnMs_Talk; + } else { + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, -1); + } +} + +void EnMs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMs* this = THIS; + + Actor_SetHeight(&this->actor, 20.0f); + this->actor.targetArrowOffset = 500.0f; + Actor_SetScale(&this->actor, 0.015f); + SkelAnime_Update(&this->skelAnime); + this->actionFunc(this, globalCtx); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Ms/z_en_ms.h b/src/overlays/actors/ovl_En_Ms/z_en_ms.h index cfacb7f60e..2efbdea458 100644 --- a/src/overlays/actors/ovl_En_Ms/z_en_ms.h +++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.h @@ -8,10 +8,12 @@ struct EnMs; typedef void (*EnMsActionFunc)(struct EnMs*, GlobalContext*); typedef struct EnMs { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xB0]; - /* 0x01F4 */ EnMsActionFunc actionFunc; - /* 0x01F8 */ char unk_1F8[0x4C]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[9]; + /* 0x1BE */ Vec3s morphTable[9]; + /* 0x1F4 */ EnMsActionFunc actionFunc; + /* 0x1F8 */ ColliderCylinder collider; } EnMs; // size = 0x244 extern const ActorInit En_Ms_InitVars; diff --git a/src/overlays/actors/ovl_En_Muto/z_en_muto.c b/src/overlays/actors/ovl_En_Muto/z_en_muto.c index e2fba46080..131fbebcc3 100644 --- a/src/overlays/actors/ovl_En_Muto/z_en_muto.c +++ b/src/overlays/actors/ovl_En_Muto/z_en_muto.c @@ -144,7 +144,7 @@ void EnMuto_Idle(EnMuto* this, GlobalContext* globalCtx) { if (1) {} // Needed to match - if (!this->isInMayorsRoom && Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (!this->isInMayorsRoom && Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { this->actor.textId = 0x2363; } diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.c b/src/overlays/actors/ovl_En_Pm/z_en_pm.c index a1658c915e..5cb68e3df7 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c @@ -671,7 +671,7 @@ UNK_TYPE* func_80AF8540(EnPm* this, GlobalContext* globalCtx) { return D_80AFB650; default: - if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { return D_80AFB744; } diff --git a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c index 6c3afaa6f0..07f3ca850a 100644 --- a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c +++ b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c @@ -15,7 +15,11 @@ void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnRecepgirl_SetupWait(EnRecepgirl* this); +void EnRecepgirl_Wait(EnRecepgirl* this, GlobalContext* globalCtx); +void EnRecepgirl_SetupTalk(EnRecepgirl* this); +void EnRecepgirl_Talk(EnRecepgirl* this, GlobalContext* globalCtx); + const ActorInit En_Recepgirl_InitVars = { ACTOR_EN_RECEPGIRL, ACTORCAT_NPC, @@ -28,38 +32,193 @@ const ActorInit En_Recepgirl_InitVars = { (ActorFunc)EnRecepgirl_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C106C0[] = { +extern TexturePtr D_0600F8F0; +extern TexturePtr D_0600FCF0; +extern TexturePtr D_060100F0; + +static TexturePtr sEyeTextures[] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), }; -#endif +static s32 texturesDesegmented = false; -extern InitChainEntry D_80C106C0[]; +extern AnimationHeader D_06000968; +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern AnimationHeader D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; -extern UNK_TYPE D_06001384; -extern UNK_TYPE D_06009890; -extern UNK_TYPE D_0600A280; +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s") + if (!texturesDesegmented) { + for (i = 0; i < ARRAY_COUNT(sEyeTextures); i++) { + sEyeTextures[i] = Lib_SegmentedToVirtual(sEyeTextures[i]); + } + texturesDesegmented = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") + this->eyeTexIndex = 2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s") + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; // hear directions again? + } else { + this->actor.textId = 0x2AD9; // "Welcome..." + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") + EnRecepgirl_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.s") +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s") +void EnRecepgirl_UpdateEyes(EnRecepgirl* this) { + if (this->eyeTexIndex != 0) { + this->eyeTexIndex++; + if (this->eyeTexIndex == 4) { + this->eyeTexIndex = 0; + } + } else if (Rand_ZeroOne() < 0.02f) { + this->eyeTexIndex++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") +void EnRecepgirl_SetupWait(EnRecepgirl* this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = EnRecepgirl_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") +void EnRecepgirl_Wait(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_MorphToLoop(&this->skelAnime, &D_06009890, -4.0f); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") + if (func_800B84D0(&this->actor, globalCtx) != 0) { + EnRecepgirl_SetupTalk(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + this->actor.textId = 0x2367; // "... doesn't Kafei want to break off his engagement ... ?" + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; // hear directions again? + } else { + this->actor.textId = 0x2AD9; // "Welcome..." + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_SetupTalk(EnRecepgirl* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = EnRecepgirl_Talk; +} + +void EnRecepgirl_Talk(EnRecepgirl* this, GlobalContext* globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_PlayLoop(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_MorphToLoop(&this->skelAnime, &D_06009890, 10.0f); + } + } else { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToLoop(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; // hear directions again? + EnRecepgirl_SetupWait(this); + } else if ((temp_v0_2 == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { // "Welcome..." + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + + if (gSaveContext.weekEventReg[63] & 0x80) { // showed Couple's Mask to meeting + this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended) + } else { + this->actor.textId = 0x2ADA; // Mayor's office is on the left (meeting ongoing) + } + } else if (this->actor.textId == 0x2ADC) { // hear directions again? + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; // "So..." + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + + if (this->actor.textId == 0x2ADD) { // "So..." + this->actor.textId = 0x2ADE; // Mayor's office is on the left, drawing room on the right + } else if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + this->actor.textId = 0x2ADB; // drawing room on the right + } else { + this->actor.textId = 0x2AE0; // drawing room on the right, don't go in without an appointment + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->headRot, &sp30, this->actor.focus.pos); + EnRecepgirl_UpdateEyes(this); +} + +s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->headRot.y; + } + return false; +} + +void EnRecepgirl_UnkLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->headRot.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} + +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, sEyeTextures[this->eyeTexIndex]); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnRecepgirl_OverrideLimbDraw, NULL, EnRecepgirl_UnkLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h index 0b7cbe0737..a6b858192b 100644 --- a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h +++ b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h @@ -8,10 +8,13 @@ struct EnRecepgirl; typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*); typedef struct EnRecepgirl { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x164]; - /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; - /* 0x02AC */ char unk_2AC[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[24]; + /* 0x218 */ Vec3s morphTable[24]; + /* 0x2A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x2AC */ u8 eyeTexIndex; + /* 0x2AE */ Vec3s headRot; } EnRecepgirl; // size = 0x2B4 extern const ActorInit En_Recepgirl_InitVars; diff --git a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c index 53212d0bfb..93504249ed 100644 --- a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c +++ b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c @@ -264,7 +264,7 @@ u16 EnSob1_GetWelcome(EnSob1* this, GlobalContext* globalCtx) { return 0x688; case PLAYER_MASK_BLAST: return 0x689; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: return 0x68A; } } else if (this->shopType == ZORA_SHOP) { diff --git a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c index 6eedfd5005..0ffa733316 100644 --- a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c +++ b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c @@ -1,7 +1,7 @@ /* * File: z_obj_tree.c * Overlay: ovl_Obj_Tree - * Description: Single tree (e.g. North Clock Town) + * Description: Single branching tree (e.g. North Clock Town) */ #include "z_obj_tree.h" @@ -15,7 +15,10 @@ void ObjTree_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjTree_Update(Actor* thisx, GlobalContext* globalCtx); void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void ObTree_DoNothing(ObjTree* this, GlobalContext* globalCtx); +void ObTree_SetupDoNothing(ObjTree* this); +void ObTree_Sway(ObjTree* this, GlobalContext* globalCtx); + const ActorInit Obj_Tree_InitVars = { ACTOR_OBJ_TREE, ACTORCAT_PROP, @@ -28,15 +31,27 @@ const ActorInit Obj_Tree_InitVars = { (ActorFunc)ObjTree_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B9A570 = { - { COLTYPE_TREE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x0100020A, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_TREE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x0100020A, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 28, 120, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B9A59C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -71,32 +86,115 @@ static DamageTable D_80B9A59C = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B9A5BC = { 8, 0, 0, 0, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColchkInfoInit = { 8, 0, 0, 0, MASS_HEAVY }; -#endif +extern Gfx D_06000680[]; +extern Gfx D_060007C8[]; +extern CollisionHeader D_06001B2C; -extern ColliderCylinderInit D_80B9A570; -extern DamageTable D_80B9A59C; -extern CollisionCheckInfoInit2 D_80B9A5BC; +void ObjTree_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjTree* this = THIS; + CollisionHeader* colHeader = NULL; -extern UNK_TYPE D_06000680; -extern UNK_TYPE D_06001B2C; + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + Actor_SetScale(&this->dyna.actor, 0.15f); + this->dyna.actor.uncullZoneForward = 4000.0f; + } else { + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Init.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->dyna.actor.colChkInfo, &sDamageTable, &sColchkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Destroy.s") + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + this->collider.dim.height = 220; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A20C.s") + this->swayAmplitude = 0.0f; + this->swayAngle = 0; + this->swayVelocity = 0; + ObTree_SetupDoNothing(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A220.s") +void ObjTree_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjTree* this = THIS; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A230.s") + if (!OBJTREE_ISLARGE(&this->dyna.actor)) { + bgId = this->dyna.bgId; + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, bgId); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A27C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A348.s") +void ObTree_SetupDoNothing(ObjTree* this) { + this->actionFunc = ObTree_DoNothing; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Update.s") +void ObTree_DoNothing(ObjTree* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Draw.s") +void ObTree_SetupSway(ObjTree* this) { + this->timer = 0; + this->swayAmplitude = 546.0f; + this->swayVelocity = 35 * 0x10000 / 360; + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_TREE_SWING); + this->actionFunc = ObTree_Sway; +} + +void ObTree_Sway(ObjTree* this, GlobalContext* globalCtx) { + if (this->timer > 80) { + ObTree_SetupDoNothing(this); + return; + } + + Math_SmoothStepToF(&this->swayAmplitude, 0.0f, 0.1f, 91.0f, 18.0f); + this->swayVelocity += 1 * 0x10000 / 360; + this->swayAngle += this->swayVelocity; + this->dyna.actor.shape.rot.x = Math_SinS(this->swayAngle) * this->swayAmplitude; + this->dyna.actor.shape.rot.z = Math_CosS(this->swayAngle) * this->swayAmplitude; + this->timer++; +} + +void ObTree_UpdateCollision(ObjTree* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->dyna.actor.xzDistToPlayer < 600.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->dyna.actor.home.rot.y == 1) { + this->dyna.actor.home.rot.y = 0; + ObTree_SetupSway(this); + } + } +} + +void ObjTree_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjTree* this = THIS; + + this->actionFunc(this, globalCtx); + ObTree_UpdateCollision(this, globalCtx); +} + +void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx) { + s16 xRot = (f32)thisx->shape.rot.x; + s16 zRot = (f32)thisx->shape.rot.z; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06000680); + + Matrix_InsertRotation(xRot, 0, zRot, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_060007C8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h index 5c8f08ca0c..b50e3eb408 100644 --- a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h +++ b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h @@ -7,11 +7,16 @@ struct ObjTree; typedef void (*ObjTreeActionFunc)(struct ObjTree*, GlobalContext*); +#define OBJTREE_ISLARGE(thisx) ((thisx)->params & 0x8000) + typedef struct ObjTree { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; - /* 0x01A8 */ ObjTreeActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0xC]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ ObjTreeActionFunc actionFunc; + /* 0x1AC */ f32 swayAmplitude; + /* 0x1B0 */ s16 swayAngle; + /* 0x1B2 */ s16 swayVelocity; + /* 0x1B4 */ s16 timer; } ObjTree; // size = 0x1B8 extern const ActorInit Obj_Tree_InitVars; diff --git a/tools/actorfixer.py b/tools/actorfixer.py index e89303ba56..7f0b7bf5f5 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -154,6 +154,154 @@ animdict = { "MainHeap_Init": "ZeldaArena_Init", "MainHeap_Cleanup": "ZeldaArena_Cleanup", "MainHeap_IsInitialized": "ZeldaArena_IsInitialized", + # "BgCheck_RelocateMeshHeader": "CollisionHeader_GetVirtual", + # "BgCheck_AddActorMesh": "DynaPoly_SetBgActor", + # "BgCheck_RemoveActorMesh": "DynaPoly_DeleteBgActor", + "BgCheck_PolygonLinkedListNodeInit": "SSNode_SetValue", + "BgCheck_PolygonLinkedListResetHead": "SSList_SetNull", + "BgCheck_ScenePolygonListsNodeInsert": "SSNodeList_SetSSListHead", + "BgCheck_PolygonLinkedListNodeInsert": "DynaSSNodeList_SetSSListHead", + "BgCheck_PolygonLinkedListInit": "DynaSSNodeList_Init", + "BgCheck_PolygonLinkedListAlloc": "DynaSSNodeList_Alloc", + "BgCheck_PolygonLinkedListReset": "DynaSSNodeList_ResetCount", + "BgCheck_AllocPolygonLinkedListNode": "DynaSSNodeList_GetNextNodeIdx", + "BgCheck_CreateVec3fFromVertex": "BgCheck_Vec3sToVec3f", + "BgCheck_CreateVertexFromVec3f": "BgCheck_Vec3fToVec3s", + "BgCheck_PolygonGetMinY": "CollisionPoly_GetMinY", + "BgCheck_PolygonGetNormal": "CollisionPoly_GetNormalF", + "func_800C01B8": "CollisionPoly_GetPointDistanceFromPlane", + "BgCheck_CreateTriNormFromPolygon": "CollisionPoly_GetVertices", + "func_800C02C0": "CollisionPoly_GetVerticesByBgId", + "BgCheck_PolygonCollidesWithSphere": "CollisionPoly_SphVsPoly", + "BgCheck_ScenePolygonListsInsertSorted": "StaticLookup_AddPolyToSSList", + "BgCheck_ScenePolygonListsInsert": "StaticLookup_AddPoly", + "BgCheck_GetPolyMinSubdivisions": "BgCheck_GetSubdivisionMinBounds", + "BgCheck_GetPolyMaxSubdivisions": "BgCheck_GetSubdivisionMaxBounds", + "BgCheck_GetPolyMinMaxSubdivisions": "BgCheck_GetPolySubdivisionBounds", + "func_800C2BE0": "BgCheck_PolyIntersectsSubdivision", + "BgCheck_SplitScenePolygonsIntoSubdivisions": "BgCheck_InitStaticLookup", + "BgCheck_GetIsDefaultSpecialScene": "BgCheck_IsSmallMemScene", + "BgCheck_GetSpecialSceneMaxMemory": "BgCheck_TryGetCustomMemsize", + "BgCheck_CalcSubdivisionSize": "BgCheck_SetSubdivisionDimension", + "BgCheck_Init(": "BgCheck_Allocate(", + "func_800C3C00": "BgCheck_SetContextFlags", + "func_800C3C14": "BgCheck_UnsetContextFlags", + "BgCheck_GetActorMeshHeader": "BgCheck_GetCollisionHeader", + "func_800C3D50": "BgCheck_RaycastFloorImpl", + "func_800C3F40": "BgCheck_CameraRaycastFloor1", + "func_800C3FA0": "BgCheck_EntityRaycastFloor1", + "func_800C4000": "BgCheck_EntityRaycastFloor2", + "func_800C4058": "BgCheck_EntityRaycastFloor2_1", + "func_800C40B4": "BgCheck_EntityRaycastFloor3", + "func_800C411C": "BgCheck_EntityRaycastFloor5", + "func_800C4188": "BgCheck_EntityRaycastFloor5_2", + "func_800C41E4": "BgCheck_EntityRaycastFloor5_3", + "func_800C4240": "BgCheck_EntityRaycastFloor6", + "func_800C42A8": "BgCheck_EntityRaycastFloor7", + "func_800C4314": "BgCheck_AnyRaycastFloor1", + "func_800C43CC": "BgCheck_AnyRaycastFloor2", + "func_800C4488": "BgCheck_CameraRaycastFloor2", + "func_800C44F0": "BgCheck_EntityRaycastFloor8", + "func_800C455C": "BgCheck_EntityRaycastFloor9", + "func_800C45C4": "BgCheck_CheckWallImpl", + "func_800C4C74": "BgCheck_EntitySphVsWall1", + "func_800C4CD8": "BgCheck_EntitySphVsWall2", + "func_800C4D3C": "BgCheck_EntitySphVsWall3", + "func_800C4DA4": "BgCheck_EntitySphVsWall4", + "func_800C4E10": "BgCheck_CheckCeilingImpl", + "func_800C4F38": "BgCheck_AnyCheckCeiling", + "func_800C4F84": "BgCheck_EntityCheckCeiling", + "func_800C54AC": "BgCheck_CameraLineTest1", + "func_800C5538": "BgCheck_CameraLineTest2", + "func_800C55C4": "BgCheck_EntityLineTest1", + "func_800C5650": "BgCheck_EntityLineTest2", + "func_800C56E0": "BgCheck_EntityLineTest3", + "func_800C576C": "BgCheck_ProjectileLineTest", + "func_800C57F8": "BgCheck_AnyLineTest1", + "func_800C583C": "BgCheck_AnyLineTest2", + "func_800C58C8": "BgCheck_AnyLineTest3", + "func_800C5954": "BgCheck_SphVsFirstPolyImpl", + "func_800C5A20": "BgCheck_SphVsFirstPoly", + "func_800C5A64": "BgCheck_SphVsFirstWall", + "BgCheck_ScenePolygonListsInit": "SSNodeList_Init", + "BgCheck_ScenePolygonListsAlloc": "SSNodeList_Alloc", + "func_800C5B80": "SSNodeList_GetNextNode", + "BgCheck_ScenePolygonListsReserveNode": "SSNodeList_GetNextNodeIdx", + "BgCheck_ActorMeshParamsInit": "ScaleRotPos_Init", + "BgCheck_SetActorMeshParams": "ScaleRotPos_SetValue", + "BgCheck_ActorMeshPolyListsHeadsInit": "DynaLookup_ResetLists", + "BgCheck_ActorMeshPolyListsInit": "DynaLookup_Reset", + "BgCheck_ActorMeshVerticesIndexInit": "DynaLookup_ResetVtxStartIndex", + "BgCheck_ActorMeshWaterboxesIndexInit": "DynaLookup_ResetWaterBoxStartIndex", + "BgCheck_ActorMeshInit": "BgActor_Init", + "BgCheck_ActorMeshInitFromActor": "BgActor_SetActor", + "BgCheck_HasActorMeshChanged": "BgActor_IsTransformUnchanged", + "BgCheck_PolygonsInit": "DynaPoly_NullPolyList", + "BgCheck_PolygonsAlloc": "DynaPoly_AllocPolyList", + "BgCheck_VerticesInit": "DynaPoly_NullVtxList", + "BgCheck_VerticesListAlloc": "DynaPoly_AllocVtxList", + "BgCheck_WaterboxListInit": "DynaPoly_InitWaterBoxList", + "BgCheck_WaterboxListAlloc": "DynaPoly_AllocWaterBoxList", + "BgCheck_ActorMeshUpdateParams": "DynaPoly_SetBgActorPrevTransform", + "BgCheck_IsActorMeshIndexValid": "DynaPoly_IsBgIdBgActor", + "BgCheck_DynaInit": "DynaPoly_Init", + "BgCheck_DynaAlloc": "DynaPoly_Alloc", + "BgCheck_AddActorMesh": "DynaPoly_SetBgActor", + "BgCheck_GetActorOfMesh": "DynaPoly_GetActor", + "BgCheck_RemoveActorMesh": "DynaPoly_DeleteBgActor", + "BgCheck_AddActorMeshToLists": "DynaPoly_ExpandSRT", + "BgCheck_Update": "DynaPoly_Setup", + "BgCheck_UpdateAllActorMeshes": "DynaPoly_UpdateBgActorTransforms", + "BgCheck_RelocateMeshHeaderPointers": "CollisionHeader_SegmentedToVirtual", + "BgCheck_RelocateMeshHeader": "CollisionHeader_GetVirtual", + "BgCheck_RelocateAllMeshHeaders": "BgCheck_InitCollisionHeaders", + "BgCheck_GetPolygonAttributes": "SurfaceType_GetData", + "func_800C9704": "SurfaceType_GetCamDataIndex", + "func_800C9924": "SurfaceType_GetCamPosData", + "func_800C99AC": "SurfaceType_GetSceneExitIndex", + "func_800C9B90": "SurfaceType_IsHorseBlocked", + "func_800C9BDC": "SurfaceType_GetSfx", + "func_800C9C74": "SurfaceType_GetSlope", + "func_800C9C9C": "SurfaceType_GetLightSettingIndex", + "func_800C9CC4": "SurfaceType_GetEcho", + "func_800C9CEC": "SurfaceType_IsHookshotSurface", + "func_800C9D14": "SurfaceType_IsIgnoredByEntities", + "func_800C9D50": "SurfaceType_IsIgnoredByProjectiles", + "func_800C9D8C": "SurfaceType_IsConveyor", + "func_800C9E18": "SurfaceType_GetConveyorSpeed", + "func_800C9E40": "SurfaceType_GetConveyorDirection", + "func_800C9E88": "SurfaceType_IsWallDamage", + "func_800C9EBC": "WaterBox_GetSurfaceImpl", + "func_800CA1AC": "WaterBox_GetSurface1", + "func_800CA1E8": "WaterBox_GetSurface1_2", + "func_800CA22C": "WaterBox_GetSurface2", + "func_800CA6D8": "WaterBox_GetLightSettingIndex", + "func_80179678": "Math3D_PlaneVsLineSegClosestPoint", + "Math3D_DistanceSquared": "Math3D_Vec3fDistSq", + "Math3D_NormalVector": "Math3D_SurfaceNorm", + "func_8017A954": "Math3D_PointRelativeToCubeFaces", + "func_8017AA0C": "Math3D_PointRelativeToCubeEdges", + "func_8017ABBC": "Math3D_PointRelativeToCubeVertices", + "func_8017AD38": "Math3D_LineVsCube", + "Math3D_NormalizedDistanceFromPlane": "Math3D_UDistPlaneToPos", + "Math3D_NormalizedSignedDistanceFromPlane": "Math3D_DistPlaneToPos", + "func_8017BAD0": "Math3D_TriChkPointParaYDist", + "func_8017BE30": "Math3D_TriChkPointParaYIntersectDist", + "func_8017BEE0": "Math3D_TriChkPointParaYIntersectInsideTri", + "func_8017C008": "Math3D_TriChkLineSegParaYIntersect", + "func_8017C494": "Math3D_TriChkPointParaYIntersectInsideTri2", + "func_8017C540": "Math3D_TriChkPointParaXDist", + "func_8017C850": "Math3D_TriChkPointParaXIntersect", + "func_8017C980": "Math3D_TriChkLineSegParaXIntersect", + "func_8017CB7C": "Math3D_TriChkLineSegParaZDist", + "func_8017CEF0": "Math3D_TriChkPointParaZIntersect", + "func_8017D020": "Math3D_TriChkLineSegParaZIntersect", + "Math3D_ColSphereLineSeg": "Math3D_LineVsSph", + "Math3D_ColSphereSphere(": "Math3D_SphVsSph(", + "func_8017F9C0": "Math3D_XZInSphere", + "func_8017FA34": "Math3D_XYInSphere", + "func_8017FAA8": "Math3D_YZInSphere", + "skelanime.unk03": "skelanime.taper", "skelanime.animCurrentSeg": "skelanime.animation", @@ -220,11 +368,25 @@ def replace_anim_all(repo): if(filename.endswith('.c')): file = subdir + os.sep + filename replace_anim(file) + for subdir, dirs, files in os.walk(repo + os.sep + 'asm'): + for filename in files: + if(filename.endswith('.s')): + file = subdir + os.sep + filename + replace_anim(file) + + for subdir, dirs, files in os.walk(repo + os.sep + 'data'): for filename in files: if(filename.endswith('.s')): file = subdir + os.sep + filename replace_anim(file) + + for subdir, dirs, files in os.walk(repo + os.sep + 'docs'): + for filename in files: + if(filename.endswith('.md')): + file = subdir + os.sep + filename + replace_anim(file) + for subdir, dirs, files in os.walk(repo + os.sep + 'tools' + os.sep + 'sizes'): for filename in files: if(filename.endswith('.csv')): diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index d2f0f432b6..f4745004a9 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -7631,10 +7631,10 @@ 0x80951748:("EnGm_Draw",), 0x80952620:("EnMs_Init",), 0x80952708:("EnMs_Destroy",), - 0x80952734:("func_80952734",), - 0x809527F8:("func_809527F8",), - 0x809529AC:("func_809529AC",), - 0x80952A1C:("func_80952A1C",), + 0x80952734:("EnMs_Wait",), + 0x809527F8:("EnMs_Talk",), + 0x809529AC:("EnMs_Sell",), + 0x80952A1C:("EnMs_TalkAfterPurchase",), 0x80952A8C:("EnMs_Update",), 0x80952B24:("EnMs_Draw",), 0x80952C50:("func_80952C50",), @@ -14941,11 +14941,11 @@ 0x80B99798:("EnZot_Draw",), 0x80B9A0B0:("ObjTree_Init",), 0x80B9A1BC:("ObjTree_Destroy",), - 0x80B9A20C:("func_80B9A20C",), - 0x80B9A220:("func_80B9A220",), - 0x80B9A230:("func_80B9A230",), - 0x80B9A27C:("func_80B9A27C",), - 0x80B9A348:("func_80B9A348",), + 0x80B9A20C:("ObTree_SetupDoNothing",), + 0x80B9A220:("ObTree_DoNothing",), + 0x80B9A230:("ObTree_SetupSway",), + 0x80B9A27C:("ObTree_Sway",), + 0x80B9A348:("ObTree_UpdateCollision",), 0x80B9A3E8:("ObjTree_Update",), 0x80B9A424:("ObjTree_Draw",), 0x80B9A650:("ObjY2lift_Init",), @@ -16738,14 +16738,14 @@ 0x80C0F758:("func_80C0F758",), 0x80C0FFD0:("EnRecepgirl_Init",), 0x80C100CC:("EnRecepgirl_Destroy",), - 0x80C100DC:("func_80C100DC",), - 0x80C10148:("func_80C10148",), - 0x80C1019C:("func_80C1019C",), - 0x80C10290:("func_80C10290",), - 0x80C102D4:("func_80C102D4",), + 0x80C100DC:("EnRecepgirl_UpdateEyes",), + 0x80C10148:("EnRecepgirl_SetupWait",), + 0x80C1019C:("EnRecepgirl_Wait",), + 0x80C10290:("EnRecepgirl_SetupTalk",), + 0x80C102D4:("EnRecepgirl_Talk",), 0x80C104E8:("EnRecepgirl_Update",), - 0x80C10558:("func_80C10558",), - 0x80C10590:("func_80C10590",), + 0x80C10558:("EnRecepgirl_OverrideLimbDraw",), + 0x80C10590:("EnRecepgirl_UnkLimbDraw",), 0x80C105EC:("EnRecepgirl_Draw",), 0x80C10770:("EnThiefbird_Init",), 0x80C10958:("EnThiefbird_Destroy",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index e5a3e6e463..39a9ab6021 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -3691,7 +3691,7 @@ 0x801E0148:("D_801E0148","f32","",0x4), 0x801E014C:("D_801E014C","f32","",0x4), 0x801E0150:("Math3D_UnitNormalVector_min_length","f32","",0x4), - 0x801E0154:("Math3D_NormalizedDistanceFromPlane_min_length","f32","",0x4), + 0x801E0154:("Math3D_UDistPlaneToPos_min_length","f32","",0x4), 0x801E0158:("D_801E0158","f32","",0x4), 0x801E015C:("D_801E015C","f32","",0x4), 0x801E0160:("D_801E0160","f32","",0x4), @@ -4228,8 +4228,8 @@ 0x801FBC46:("D_801FBC46","UNK_TYPE1","",0x1), 0x801FBC48:("D_801FBC48","UNK_TYPE1","",0x1), 0x801FBC58:("D_801FBC58","UNK_TYPE1","",0x1), - 0x801FBC68:("Math3D_NormalVector_temp1","Vec3f","",0xc), - 0x801FBC78:("Math3D_NormalVector_temp2","Vec3f","",0xc), + 0x801FBC68:("Math3D_SurfaceNorm_temp1","Vec3f","",0xc), + 0x801FBC78:("Math3D_SurfaceNorm_temp2","Vec3f","",0xc), 0x801FBC8C:("D_801FBC8C","f32","",0x4), 0x801FBC90:("D_801FBC90","f32","",0x4), 0x801FBC98:("D_801FBC98","f32","",0x4), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index fba05738ec..1b7b3fbdc2 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -413,33 +413,33 @@ asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_FaultPrint.s,ActorOverl asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_FaultAddrConv.s,ActorOverlayTable_FaultAddrConv,0x800BFA78,0x1C asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_Init.s,ActorOverlayTable_Init,0x800BFAE8,0x16 asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_Cleanup.s,ActorOverlayTable_Cleanup,0x800BFB40,0x10 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListNodeInit.s,BgCheck_PolygonLinkedListNodeInit,0x800BFB80,0x7 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListResetHead.s,BgCheck_PolygonLinkedListResetHead,0x800BFB9C,0x4 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsNodeInsert.s,BgCheck_ScenePolygonListsNodeInsert,0x800BFBAC,0x16 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListNodeInsert.s,BgCheck_PolygonLinkedListNodeInsert,0x800BFC04,0x16 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListInit.s,BgCheck_PolygonLinkedListInit,0x800BFC5C,0x5 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListAlloc.s,BgCheck_PolygonLinkedListAlloc,0x800BFC70,0x14 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListReset.s,BgCheck_PolygonLinkedListReset,0x800BFCC0,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_AllocPolygonLinkedListNode.s,BgCheck_AllocPolygonLinkedListNode,0x800BFCCC,0xC -asm/non_matchings/code/z_bgcheck/BgCheck_CreateVec3fFromVertex.s,BgCheck_CreateVec3fFromVertex,0x800BFCFC,0x11 -asm/non_matchings/code/z_bgcheck/BgCheck_CreateVertexFromVec3f.s,BgCheck_CreateVertexFromVec3f,0x800BFD40,0x11 +asm/non_matchings/code/z_bgcheck/SSNode_SetValue.s,SSNode_SetValue,0x800BFB80,0x7 +asm/non_matchings/code/z_bgcheck/SSList_SetNull.s,SSList_SetNull,0x800BFB9C,0x4 +asm/non_matchings/code/z_bgcheck/SSNodeList_SetSSListHead.s,SSNodeList_SetSSListHead,0x800BFBAC,0x16 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_SetSSListHead.s,DynaSSNodeList_SetSSListHead,0x800BFC04,0x16 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_Init.s,DynaSSNodeList_Init,0x800BFC5C,0x5 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_Alloc.s,DynaSSNodeList_Alloc,0x800BFC70,0x14 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_ResetCount.s,DynaSSNodeList_ResetCount,0x800BFCC0,0x3 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_GetNextNodeIdx.s,DynaSSNodeList_GetNextNodeIdx,0x800BFCCC,0xC +asm/non_matchings/code/z_bgcheck/BgCheck_Vec3sToVec3f.s,BgCheck_Vec3sToVec3f,0x800BFCFC,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_Vec3fToVec3s.s,BgCheck_Vec3fToVec3s,0x800BFD40,0x11 asm/non_matchings/code/z_bgcheck/func_800BFD84.s,func_800BFD84,0x800BFD84,0x1A asm/non_matchings/code/z_bgcheck/func_800BFDEC.s,func_800BFDEC,0x800BFDEC,0x76 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonGetMinY.s,BgCheck_PolygonGetMinY,0x800BFFC4,0x1E -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonGetNormal.s,BgCheck_PolygonGetNormal,0x800C003C,0x16 +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetMinY.s,CollisionPoly_GetMinY,0x800BFFC4,0x1E +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetNormalF.s,CollisionPoly_GetNormalF,0x800C003C,0x16 asm/non_matchings/code/z_bgcheck/func_800C0094.s,func_800C0094,0x800C0094,0x49 -asm/non_matchings/code/z_bgcheck/func_800C01B8.s,func_800C01B8,0x800C01B8,0x1A -asm/non_matchings/code/z_bgcheck/BgCheck_CreateTriNormFromPolygon.s,BgCheck_CreateTriNormFromPolygon,0x800C0220,0x28 -asm/non_matchings/code/z_bgcheck/func_800C02C0.s,func_800C02C0,0x800C02C0,0x20 +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetPointDistanceFromPlane.s,CollisionPoly_GetPointDistanceFromPlane,0x800C01B8,0x1A +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetVertices.s,CollisionPoly_GetVertices,0x800C0220,0x28 +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetVerticesByBgId.s,CollisionPoly_GetVerticesByBgId,0x800C02C0,0x20 asm/non_matchings/code/z_bgcheck/func_800C0340.s,func_800C0340,0x800C0340,0x4D asm/non_matchings/code/z_bgcheck/func_800C0474.s,func_800C0474,0x800C0474,0x7D asm/non_matchings/code/z_bgcheck/func_800C0668.s,func_800C0668,0x800C0668,0x10 asm/non_matchings/code/z_bgcheck/func_800C06A8.s,func_800C06A8,0x800C06A8,0x29 asm/non_matchings/code/z_bgcheck/func_800C074C.s,func_800C074C,0x800C074C,0x29 asm/non_matchings/code/z_bgcheck/func_800C07F0.s,func_800C07F0,0x800C07F0,0xC0 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonCollidesWithSphere.s,BgCheck_PolygonCollidesWithSphere,0x800C0AF0,0x34 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInsertSorted.s,BgCheck_ScenePolygonListsInsertSorted,0x800C0BC0,0x88 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInsert.s,BgCheck_ScenePolygonListsInsert,0x800C0DE0,0x25 +asm/non_matchings/code/z_bgcheck/CollisionPoly_SphVsPoly.s,CollisionPoly_SphVsPoly,0x800C0AF0,0x34 +asm/non_matchings/code/z_bgcheck/StaticLookup_AddPolyToSSList.s,StaticLookup_AddPolyToSSList,0x800C0BC0,0x88 +asm/non_matchings/code/z_bgcheck/StaticLookup_AddPoly.s,StaticLookup_AddPoly,0x800C0DE0,0x25 asm/non_matchings/code/z_bgcheck/func_800C0E74.s,func_800C0E74,0x800C0E74,0xA2 asm/non_matchings/code/z_bgcheck/func_800C10FC.s,func_800C10FC,0x800C10FC,0x4F asm/non_matchings/code/z_bgcheck/func_800C1238.s,func_800C1238,0x800C1238,0x1B @@ -452,98 +452,98 @@ asm/non_matchings/code/z_bgcheck/func_800C2310.s,func_800C2310,0x800C2310,0x54 asm/non_matchings/code/z_bgcheck/func_800C2460.s,func_800C2460,0x800C2460,0x2D asm/non_matchings/code/z_bgcheck/func_800C2514.s,func_800C2514,0x800C2514,0x33 asm/non_matchings/code/z_bgcheck/func_800C25E0.s,func_800C25E0,0x800C25E0,0x38 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMinSubdivisions.s,BgCheck_GetPolyMinSubdivisions,0x800C26C0,0x69 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMaxSubdivisions.s,BgCheck_GetPolyMaxSubdivisions,0x800C2864,0x73 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMinMaxSubdivisions.s,BgCheck_GetPolyMinMaxSubdivisions,0x800C2A30,0x6C -asm/non_matchings/code/z_bgcheck/func_800C2BE0.s,func_800C2BE0,0x800C2BE0,0x1D5 -asm/non_matchings/code/z_bgcheck/BgCheck_SplitScenePolygonsIntoSubdivisions.s,BgCheck_SplitScenePolygonsIntoSubdivisions,0x800C3334,0x100 -asm/non_matchings/code/z_bgcheck/BgCheck_GetIsDefaultSpecialScene.s,BgCheck_GetIsDefaultSpecialScene,0x800C3734,0x11 -asm/non_matchings/code/z_bgcheck/BgCheck_GetSpecialSceneMaxMemory.s,BgCheck_GetSpecialSceneMaxMemory,0x800C3778,0x11 -asm/non_matchings/code/z_bgcheck/BgCheck_CalcSubdivisionSize.s,BgCheck_CalcSubdivisionSize,0x800C37BC,0x22 +asm/non_matchings/code/z_bgcheck/BgCheck_GetSubdivisionMinBounds.s,BgCheck_GetSubdivisionMinBounds,0x800C26C0,0x69 +asm/non_matchings/code/z_bgcheck/BgCheck_GetSubdivisionMaxBounds.s,BgCheck_GetSubdivisionMaxBounds,0x800C2864,0x73 +asm/non_matchings/code/z_bgcheck/BgCheck_GetPolySubdivisionBounds.s,BgCheck_GetPolySubdivisionBounds,0x800C2A30,0x6C +asm/non_matchings/code/z_bgcheck/BgCheck_PolyIntersectsSubdivision.s,BgCheck_PolyIntersectsSubdivision,0x800C2BE0,0x1D5 +asm/non_matchings/code/z_bgcheck/BgCheck_InitStaticLookup.s,BgCheck_InitStaticLookup,0x800C3334,0x100 +asm/non_matchings/code/z_bgcheck/BgCheck_IsSmallMemScene.s,BgCheck_IsSmallMemScene,0x800C3734,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_TryGetCustomMemsize.s,BgCheck_TryGetCustomMemsize,0x800C3778,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_SetSubdivisionDimension.s,BgCheck_SetSubdivisionDimension,0x800C37BC,0x22 asm/non_matchings/code/z_bgcheck/BgCheck_GetSpecialSceneMaxObjects.s,BgCheck_GetSpecialSceneMaxObjects,0x800C3844,0x16 asm/non_matchings/code/z_bgcheck/BgCheck_Init.s,BgCheck_Init,0x800C389C,0xD9 -asm/non_matchings/code/z_bgcheck/func_800C3C00.s,func_800C3C00,0x800C3C00,0x5 -asm/non_matchings/code/z_bgcheck/func_800C3C14.s,func_800C3C14,0x800C3C14,0x6 -asm/non_matchings/code/z_bgcheck/BgCheck_GetActorMeshHeader.s,BgCheck_GetActorMeshHeader,0x800C3C2C,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_SetContextFlags.s,BgCheck_SetContextFlags,0x800C3C00,0x5 +asm/non_matchings/code/z_bgcheck/BgCheck_UnsetContextFlags.s,BgCheck_UnsetContextFlags,0x800C3C14,0x6 +asm/non_matchings/code/z_bgcheck/BgCheck_GetCollisionHeader.s,BgCheck_GetCollisionHeader,0x800C3C2C,0x1A asm/non_matchings/code/z_bgcheck/func_800C3C94.s,func_800C3C94,0x800C3C94,0x2F -asm/non_matchings/code/z_bgcheck/func_800C3D50.s,func_800C3D50,0x800C3D50,0x7C -asm/non_matchings/code/z_bgcheck/func_800C3F40.s,func_800C3F40,0x800C3F40,0x18 -asm/non_matchings/code/z_bgcheck/func_800C3FA0.s,func_800C3FA0,0x800C3FA0,0x18 -asm/non_matchings/code/z_bgcheck/func_800C4000.s,func_800C4000,0x800C4000,0x16 -asm/non_matchings/code/z_bgcheck/func_800C4058.s,func_800C4058,0x800C4058,0x17 -asm/non_matchings/code/z_bgcheck/func_800C40B4.s,func_800C40B4,0x800C40B4,0x1A -asm/non_matchings/code/z_bgcheck/func_800C411C.s,func_800C411C,0x800C411C,0x1B -asm/non_matchings/code/z_bgcheck/func_800C4188.s,func_800C4188,0x800C4188,0x17 -asm/non_matchings/code/z_bgcheck/func_800C41E4.s,func_800C41E4,0x800C41E4,0x17 -asm/non_matchings/code/z_bgcheck/func_800C4240.s,func_800C4240,0x800C4240,0x1A -asm/non_matchings/code/z_bgcheck/func_800C42A8.s,func_800C42A8,0x800C42A8,0x1B -asm/non_matchings/code/z_bgcheck/func_800C4314.s,func_800C4314,0x800C4314,0x2E -asm/non_matchings/code/z_bgcheck/func_800C43CC.s,func_800C43CC,0x800C43CC,0x2F -asm/non_matchings/code/z_bgcheck/func_800C4488.s,func_800C4488,0x800C4488,0x1A -asm/non_matchings/code/z_bgcheck/func_800C44F0.s,func_800C44F0,0x800C44F0,0x1B -asm/non_matchings/code/z_bgcheck/func_800C455C.s,func_800C455C,0x800C455C,0x1A -asm/non_matchings/code/z_bgcheck/func_800C45C4.s,func_800C45C4,0x800C45C4,0x1AC -asm/non_matchings/code/z_bgcheck/func_800C4C74.s,func_800C4C74,0x800C4C74,0x19 -asm/non_matchings/code/z_bgcheck/func_800C4CD8.s,func_800C4CD8,0x800C4CD8,0x19 -asm/non_matchings/code/z_bgcheck/func_800C4D3C.s,func_800C4D3C,0x800C4D3C,0x1A -asm/non_matchings/code/z_bgcheck/func_800C4DA4.s,func_800C4DA4,0x800C4DA4,0x1B -asm/non_matchings/code/z_bgcheck/func_800C4E10.s,func_800C4E10,0x800C4E10,0x4A -asm/non_matchings/code/z_bgcheck/func_800C4F38.s,func_800C4F38,0x800C4F38,0x13 -asm/non_matchings/code/z_bgcheck/func_800C4F84.s,func_800C4F84,0x800C4F84,0x14 +asm/non_matchings/code/z_bgcheck/BgCheck_RaycastFloorImpl.s,BgCheck_RaycastFloorImpl,0x800C3D50,0x7C +asm/non_matchings/code/z_bgcheck/BgCheck_CameraRaycastFloor1.s,BgCheck_CameraRaycastFloor1,0x800C3F40,0x18 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor1.s,BgCheck_EntityRaycastFloor1,0x800C3FA0,0x18 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor2.s,BgCheck_EntityRaycastFloor2,0x800C4000,0x16 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor2_1.s,BgCheck_EntityRaycastFloor2_1,0x800C4058,0x17 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor3.s,BgCheck_EntityRaycastFloor3,0x800C40B4,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor5.s,BgCheck_EntityRaycastFloor5,0x800C411C,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor5_2.s,BgCheck_EntityRaycastFloor5_2,0x800C4188,0x17 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor5_3.s,BgCheck_EntityRaycastFloor5_3,0x800C41E4,0x17 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor6.s,BgCheck_EntityRaycastFloor6,0x800C4240,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor7.s,BgCheck_EntityRaycastFloor7,0x800C42A8,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_AnyRaycastFloor1.s,BgCheck_AnyRaycastFloor1,0x800C4314,0x2E +asm/non_matchings/code/z_bgcheck/BgCheck_AnyRaycastFloor2.s,BgCheck_AnyRaycastFloor2,0x800C43CC,0x2F +asm/non_matchings/code/z_bgcheck/BgCheck_CameraRaycastFloor2.s,BgCheck_CameraRaycastFloor2,0x800C4488,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor8.s,BgCheck_EntityRaycastFloor8,0x800C44F0,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor9.s,BgCheck_EntityRaycastFloor9,0x800C455C,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_CheckWallImpl.s,BgCheck_CheckWallImpl,0x800C45C4,0x1AC +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall1.s,BgCheck_EntitySphVsWall1,0x800C4C74,0x19 +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall2.s,BgCheck_EntitySphVsWall2,0x800C4CD8,0x19 +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall3.s,BgCheck_EntitySphVsWall3,0x800C4D3C,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall4.s,BgCheck_EntitySphVsWall4,0x800C4DA4,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_CheckCeilingImpl.s,BgCheck_CheckCeilingImpl,0x800C4E10,0x4A +asm/non_matchings/code/z_bgcheck/BgCheck_AnyCheckCeiling.s,BgCheck_AnyCheckCeiling,0x800C4F38,0x13 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityCheckCeiling.s,BgCheck_EntityCheckCeiling,0x800C4F84,0x14 asm/non_matchings/code/z_bgcheck/func_800C4FD4.s,func_800C4FD4,0x800C4FD4,0x124 asm/non_matchings/code/z_bgcheck/func_800C5464.s,func_800C5464,0x800C5464,0x12 -asm/non_matchings/code/z_bgcheck/func_800C54AC.s,func_800C54AC,0x800C54AC,0x23 -asm/non_matchings/code/z_bgcheck/func_800C5538.s,func_800C5538,0x800C5538,0x23 -asm/non_matchings/code/z_bgcheck/func_800C55C4.s,func_800C55C4,0x800C55C4,0x23 -asm/non_matchings/code/z_bgcheck/func_800C5650.s,func_800C5650,0x800C5650,0x24 -asm/non_matchings/code/z_bgcheck/func_800C56E0.s,func_800C56E0,0x800C56E0,0x23 -asm/non_matchings/code/z_bgcheck/func_800C576C.s,func_800C576C,0x800C576C,0x23 -asm/non_matchings/code/z_bgcheck/func_800C57F8.s,func_800C57F8,0x800C57F8,0x11 -asm/non_matchings/code/z_bgcheck/func_800C583C.s,func_800C583C,0x800C583C,0x23 -asm/non_matchings/code/z_bgcheck/func_800C58C8.s,func_800C58C8,0x800C58C8,0x23 -asm/non_matchings/code/z_bgcheck/func_800C5954.s,func_800C5954,0x800C5954,0x33 -asm/non_matchings/code/z_bgcheck/func_800C5A20.s,func_800C5A20,0x800C5A20,0x11 -asm/non_matchings/code/z_bgcheck/func_800C5A64.s,func_800C5A64,0x800C5A64,0x12 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInit.s,BgCheck_ScenePolygonListsInit,0x800C5AAC,0x6 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsAlloc.s,BgCheck_ScenePolygonListsAlloc,0x800C5AC4,0x2F -asm/non_matchings/code/z_bgcheck/func_800C5B80.s,func_800C5B80,0x800C5B80,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsReserveNode.s,BgCheck_ScenePolygonListsReserveNode,0x800C5BBC,0x5 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshParamsInit.s,BgCheck_ActorMeshParamsInit,0x800C5BD0,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_SetActorMeshParams.s,BgCheck_SetActorMeshParams,0x800C5C0C,0x14 +asm/non_matchings/code/z_bgcheck/BgCheck_CameraLineTest1.s,BgCheck_CameraLineTest1,0x800C54AC,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_CameraLineTest2.s,BgCheck_CameraLineTest2,0x800C5538,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityLineTest1.s,BgCheck_EntityLineTest1,0x800C55C4,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityLineTest2.s,BgCheck_EntityLineTest2,0x800C5650,0x24 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityLineTest3.s,BgCheck_EntityLineTest3,0x800C56E0,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_ProjectileLineTest.s,BgCheck_ProjectileLineTest,0x800C576C,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_AnyLineTest1.s,BgCheck_AnyLineTest1,0x800C57F8,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_AnyLineTest2.s,BgCheck_AnyLineTest2,0x800C583C,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_AnyLineTest3.s,BgCheck_AnyLineTest3,0x800C58C8,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstPolyImpl.s,BgCheck_SphVsFirstPolyImpl,0x800C5954,0x33 +asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstPoly.s,BgCheck_SphVsFirstPoly,0x800C5A20,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstWall.s,BgCheck_SphVsFirstWall,0x800C5A64,0x12 +asm/non_matchings/code/z_bgcheck/SSNodeList_Init.s,SSNodeList_Init,0x800C5AAC,0x6 +asm/non_matchings/code/z_bgcheck/SSNodeList_Alloc.s,SSNodeList_Alloc,0x800C5AC4,0x2F +asm/non_matchings/code/z_bgcheck/SSNodeList_GetNextNode.s,SSNodeList_GetNextNode,0x800C5B80,0xF +asm/non_matchings/code/z_bgcheck/SSNodeList_GetNextNodeIdx.s,SSNodeList_GetNextNodeIdx,0x800C5BBC,0x5 +asm/non_matchings/code/z_bgcheck/ScaleRotPos_Init.s,ScaleRotPos_Init,0x800C5BD0,0xF +asm/non_matchings/code/z_bgcheck/ScaleRotPos_SetValue.s,ScaleRotPos_SetValue,0x800C5C0C,0x14 asm/non_matchings/code/z_bgcheck/BgCheck_AreActorMeshParamsEqual.s,BgCheck_AreActorMeshParamsEqual,0x800C5C5C,0x35 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshPolyListsHeadsInit.s,BgCheck_ActorMeshPolyListsHeadsInit,0x800C5D30,0x10 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshPolyListsInit.s,BgCheck_ActorMeshPolyListsInit,0x800C5D70,0x8 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshVerticesIndexInit.s,BgCheck_ActorMeshVerticesIndexInit,0x800C5D90,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshWaterboxesIndexInit.s,BgCheck_ActorMeshWaterboxesIndexInit,0x800C5D9C,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshInit.s,BgCheck_ActorMeshInit,0x800C5DA8,0x1A -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshInitFromActor.s,BgCheck_ActorMeshInitFromActor,0x800C5E10,0x2E -asm/non_matchings/code/z_bgcheck/BgCheck_HasActorMeshChanged.s,BgCheck_HasActorMeshChanged,0x800C5EC8,0xA -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonsInit.s,BgCheck_PolygonsInit,0x800C5EF0,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonsAlloc.s,BgCheck_PolygonsAlloc,0x800C5EFC,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_VerticesInit.s,BgCheck_VerticesInit,0x800C5F38,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_VerticesListAlloc.s,BgCheck_VerticesListAlloc,0x800C5F44,0x12 -asm/non_matchings/code/z_bgcheck/BgCheck_WaterboxListInit.s,BgCheck_WaterboxListInit,0x800C5F8C,0x4 -asm/non_matchings/code/z_bgcheck/BgCheck_WaterboxListAlloc.s,BgCheck_WaterboxListAlloc,0x800C5F9C,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshUpdateParams.s,BgCheck_ActorMeshUpdateParams,0x800C5FD8,0x13 -asm/non_matchings/code/z_bgcheck/BgCheck_IsActorMeshIndexValid.s,BgCheck_IsActorMeshIndexValid,0x800C6024,0x8 -asm/non_matchings/code/z_bgcheck/BgCheck_DynaInit.s,BgCheck_DynaInit,0x800C6044,0x15 -asm/non_matchings/code/z_bgcheck/BgCheck_DynaAlloc.s,BgCheck_DynaAlloc,0x800C6098,0x3C -asm/non_matchings/code/z_bgcheck/BgCheck_AddActorMesh.s,BgCheck_AddActorMesh,0x800C6188,0x30 -asm/non_matchings/code/z_bgcheck/BgCheck_GetActorOfMesh.s,BgCheck_GetActorOfMesh,0x800C6248,0x1D +asm/non_matchings/code/z_bgcheck/DynaLookup_ResetLists.s,DynaLookup_ResetLists,0x800C5D30,0x10 +asm/non_matchings/code/z_bgcheck/DynaLookup_Reset.s,DynaLookup_Reset,0x800C5D70,0x8 +asm/non_matchings/code/z_bgcheck/DynaLookup_ResetVtxStartIndex.s,DynaLookup_ResetVtxStartIndex,0x800C5D90,0x3 +asm/non_matchings/code/z_bgcheck/DynaLookup_ResetWaterBoxStartIndex.s,DynaLookup_ResetWaterBoxStartIndex,0x800C5D9C,0x3 +asm/non_matchings/code/z_bgcheck/BgActor_Init.s,BgActor_Init,0x800C5DA8,0x1A +asm/non_matchings/code/z_bgcheck/BgActor_InitFromActor.s,BgActor_InitFromActor,0x800C5E10,0x2E +asm/non_matchings/code/z_bgcheck/BgActor_IsTransformUnchanged.s,BgActor_IsTransformUnchanged,0x800C5EC8,0xA +asm/non_matchings/code/z_bgcheck/DynaPoly_NullPolyList.s,DynaPoly_NullPolyList,0x800C5EF0,0x3 +asm/non_matchings/code/z_bgcheck/DynaPoly_AllocPolyList.s,DynaPoly_AllocPolyList,0x800C5EFC,0xF +asm/non_matchings/code/z_bgcheck/DynaPoly_NullVtxList.s,DynaPoly_NullVtxList,0x800C5F38,0x3 +asm/non_matchings/code/z_bgcheck/DynaPoly_AllocVtxList.s,DynaPoly_AllocVtxList,0x800C5F44,0x12 +asm/non_matchings/code/z_bgcheck/DynaPoly_InitWaterBoxList.s,DynaPoly_InitWaterBoxList,0x800C5F8C,0x4 +asm/non_matchings/code/z_bgcheck/DynaPoly_AllocWaterBoxList.s,DynaPoly_AllocWaterBoxList,0x800C5F9C,0xF +asm/non_matchings/code/z_bgcheck/DynaPoly_SetBgActorPrevTransform.s,DynaPoly_SetBgActorPrevTransform,0x800C5FD8,0x13 +asm/non_matchings/code/z_bgcheck/DynaPoly_IsBgIdBgActor.s,DynaPoly_IsBgIdBgActor,0x800C6024,0x8 +asm/non_matchings/code/z_bgcheck/DynaPoly_Init.s,DynaPoly_Init,0x800C6044,0x15 +asm/non_matchings/code/z_bgcheck/DynaPoly_Alloc.s,DynaPoly_Alloc,0x800C6098,0x3C +asm/non_matchings/code/z_bgcheck/DynaPoly_SetBgActor.s,DynaPoly_SetBgActor,0x800C6188,0x30 +asm/non_matchings/code/z_bgcheck/DynaPoly_GetActor.s,DynaPoly_GetActor,0x800C6248,0x1D asm/non_matchings/code/z_bgcheck/func_800C62BC.s,func_800C62BC,0x800C62BC,0x16 asm/non_matchings/code/z_bgcheck/func_800C6314.s,func_800C6314,0x800C6314,0x16 asm/non_matchings/code/z_bgcheck/func_800C636C.s,func_800C636C,0x800C636C,0x16 asm/non_matchings/code/z_bgcheck/func_800C63C4.s,func_800C63C4,0x800C63C4,0x16 asm/non_matchings/code/z_bgcheck/func_800C641C.s,func_800C641C,0x800C641C,0x16 asm/non_matchings/code/z_bgcheck/func_800C6474.s,func_800C6474,0x800C6474,0x16 -asm/non_matchings/code/z_bgcheck/BgCheck_RemoveActorMesh.s,BgCheck_RemoveActorMesh,0x800C64CC,0x22 +asm/non_matchings/code/z_bgcheck/DynaPoly_DeleteBgActor.s,DynaPoly_DeleteBgActor,0x800C64CC,0x22 asm/non_matchings/code/z_bgcheck/func_800C6554.s,func_800C6554,0x800C6554,0x6 asm/non_matchings/code/z_bgcheck/BgCheck_CalcWaterboxDimensions.s,BgCheck_CalcWaterboxDimensions,0x800C656C,0xB3 -asm/non_matchings/code/z_bgcheck/BgCheck_AddActorMeshToLists.s,BgCheck_AddActorMeshToLists,0x800C6838,0x2C5 +asm/non_matchings/code/z_bgcheck/DynaPoly_SetBgActorToLists.s,DynaPoly_SetBgActorToLists,0x800C6838,0x2C5 asm/non_matchings/code/z_bgcheck/BgCheck_ResetFlagsIfLoadedActor.s,BgCheck_ResetFlagsIfLoadedActor,0x800C734C,0x26 -asm/non_matchings/code/z_bgcheck/BgCheck_Update.s,BgCheck_Update,0x800C73E4,0x62 +asm/non_matchings/code/z_bgcheck/DynaPoly_Setup.s,DynaPoly_Setup,0x800C73E4,0x62 asm/non_matchings/code/z_bgcheck/func_800C756C.s,func_800C756C,0x800C756C,0x3C -asm/non_matchings/code/z_bgcheck/BgCheck_UpdateAllActorMeshes.s,BgCheck_UpdateAllActorMeshes,0x800C765C,0x24 +asm/non_matchings/code/z_bgcheck/DynaPoly_SetupAllActorMeshes.s,DynaPoly_SetupAllActorMeshes,0x800C765C,0x24 asm/non_matchings/code/z_bgcheck/func_800C76EC.s,func_800C76EC,0x800C76EC,0xA2 asm/non_matchings/code/z_bgcheck/func_800C7974.s,func_800C7974,0x800C7974,0x133 asm/non_matchings/code/z_bgcheck/func_800C7E40.s,func_800C7E40,0x800C7E40,0x1D0 @@ -556,19 +556,19 @@ asm/non_matchings/code/z_bgcheck/func_800C8EEC.s,func_800C8EEC,0x800C8EEC,0x70 asm/non_matchings/code/z_bgcheck/func_800C90AC.s,func_800C90AC,0x800C90AC,0x5C asm/non_matchings/code/z_bgcheck/func_800C921C.s,func_800C921C,0x800C921C,0x59 asm/non_matchings/code/z_bgcheck/func_800C9380.s,func_800C9380,0x800C9380,0x58 -asm/non_matchings/code/z_bgcheck/BgCheck_RelocateMeshHeaderPointers.s,BgCheck_RelocateMeshHeaderPointers,0x800C94E0,0x21 -asm/non_matchings/code/z_bgcheck/BgCheck_RelocateMeshHeader.s,BgCheck_RelocateMeshHeader,0x800C9564,0xD -asm/non_matchings/code/z_bgcheck/BgCheck_RelocateAllMeshHeaders.s,BgCheck_RelocateAllMeshHeaders,0x800C9598,0x2A +asm/non_matchings/code/z_bgcheck/CollisionHeader_GetVirtualPointers.s,CollisionHeader_GetVirtualPointers,0x800C94E0,0x21 +asm/non_matchings/code/z_bgcheck/CollisionHeader_GetVirtual.s,CollisionHeader_GetVirtual,0x800C9564,0xD +asm/non_matchings/code/z_bgcheck/BgCheck_InitCollisionHeaders.s,BgCheck_InitCollisionHeaders,0x800C9598,0x2A asm/non_matchings/code/z_bgcheck/func_800C9640.s,func_800C9640,0x800C9640,0x15 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolygonAttributes.s,BgCheck_GetPolygonAttributes,0x800C9694,0x1C -asm/non_matchings/code/z_bgcheck/func_800C9704.s,func_800C9704,0x800C9704,0x9 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetData.s,SurfaceType_GetData,0x800C9694,0x1C +asm/non_matchings/code/z_bgcheck/SurfaceType_GetCamDataIndex.s,SurfaceType_GetCamDataIndex,0x800C9704,0x9 asm/non_matchings/code/z_bgcheck/func_800C9728.s,func_800C9728,0x800C9728,0x12 asm/non_matchings/code/z_bgcheck/func_800C9770.s,func_800C9770,0x800C9770,0x22 asm/non_matchings/code/z_bgcheck/func_800C97F8.s,func_800C97F8,0x800C97F8,0x13 asm/non_matchings/code/z_bgcheck/func_800C9844.s,func_800C9844,0x800C9844,0x22 asm/non_matchings/code/z_bgcheck/func_800C98CC.s,func_800C98CC,0x800C98CC,0x16 -asm/non_matchings/code/z_bgcheck/func_800C9924.s,func_800C9924,0x800C9924,0x22 -asm/non_matchings/code/z_bgcheck/func_800C99AC.s,func_800C99AC,0x800C99AC,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetCamPosData.s,SurfaceType_GetCamPosData,0x800C9924,0x22 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetSceneExitIndex.s,SurfaceType_GetSceneExitIndex,0x800C99AC,0xA asm/non_matchings/code/z_bgcheck/func_800C99D4.s,func_800C99D4,0x800C99D4,0xA asm/non_matchings/code/z_bgcheck/func_800C99FC.s,func_800C99FC,0x800C99FC,0xA asm/non_matchings/code/z_bgcheck/func_800C9A24.s,func_800C9A24,0x800C9A24,0xA @@ -579,30 +579,30 @@ asm/non_matchings/code/z_bgcheck/func_800C9AE4.s,func_800C9AE4,0x800C9AE4,0xD asm/non_matchings/code/z_bgcheck/func_800C9B18.s,func_800C9B18,0x800C9B18,0xA asm/non_matchings/code/z_bgcheck/func_800C9B40.s,func_800C9B40,0x800C9B40,0xA asm/non_matchings/code/z_bgcheck/func_800C9B68.s,func_800C9B68,0x800C9B68,0xA -asm/non_matchings/code/z_bgcheck/func_800C9B90.s,func_800C9B90,0x800C9B90,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_IsHorseBlocked.s,SurfaceType_IsHorseBlocked,0x800C9B90,0xA asm/non_matchings/code/z_bgcheck/func_800C9BB8.s,func_800C9BB8,0x800C9BB8,0x9 -asm/non_matchings/code/z_bgcheck/func_800C9BDC.s,func_800C9BDC,0x800C9BDC,0x12 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetSfx.s,SurfaceType_GetSfx,0x800C9BDC,0x12 asm/non_matchings/code/z_bgcheck/func_800C9C24.s,func_800C9C24,0x800C9C24,0x14 -asm/non_matchings/code/z_bgcheck/func_800C9C74.s,func_800C9C74,0x800C9C74,0xA -asm/non_matchings/code/z_bgcheck/func_800C9C9C.s,func_800C9C9C,0x800C9C9C,0xA -asm/non_matchings/code/z_bgcheck/func_800C9CC4.s,func_800C9CC4,0x800C9CC4,0xA -asm/non_matchings/code/z_bgcheck/func_800C9CEC.s,func_800C9CEC,0x800C9CEC,0xA -asm/non_matchings/code/z_bgcheck/func_800C9D14.s,func_800C9D14,0x800C9D14,0xF -asm/non_matchings/code/z_bgcheck/func_800C9D50.s,func_800C9D50,0x800C9D50,0xF -asm/non_matchings/code/z_bgcheck/func_800C9D8C.s,func_800C9D8C,0x800C9D8C,0x14 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetSlope.s,SurfaceType_GetSlope,0x800C9C74,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetLightSettingIndex.s,SurfaceType_GetLightSettingIndex,0x800C9C9C,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetEcho.s,SurfaceType_GetEcho,0x800C9CC4,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_IsHookshotSurface.s,SurfaceType_IsHookshotSurface,0x800C9CEC,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_IsIgnoredByEntities.s,SurfaceType_IsIgnoredByEntities,0x800C9D14,0xF +asm/non_matchings/code/z_bgcheck/SurfaceType_IsIgnoredByProjectiles.s,SurfaceType_IsIgnoredByProjectiles,0x800C9D50,0xF +asm/non_matchings/code/z_bgcheck/SurfaceType_IsConveyor.s,SurfaceType_IsConveyor,0x800C9D8C,0x14 asm/non_matchings/code/z_bgcheck/func_800C9DDC.s,func_800C9DDC,0x800C9DDC,0xF -asm/non_matchings/code/z_bgcheck/func_800C9E18.s,func_800C9E18,0x800C9E18,0xA -asm/non_matchings/code/z_bgcheck/func_800C9E40.s,func_800C9E40,0x800C9E40,0x12 -asm/non_matchings/code/z_bgcheck/func_800C9E88.s,func_800C9E88,0x800C9E88,0xD -asm/non_matchings/code/z_bgcheck/func_800C9EBC.s,func_800C9EBC,0x800C9EBC,0xBC -asm/non_matchings/code/z_bgcheck/func_800CA1AC.s,func_800CA1AC,0x800CA1AC,0xF -asm/non_matchings/code/z_bgcheck/func_800CA1E8.s,func_800CA1E8,0x800CA1E8,0x11 -asm/non_matchings/code/z_bgcheck/func_800CA22C.s,func_800CA22C,0x800CA22C,0xCF +asm/non_matchings/code/z_bgcheck/SurfaceType_GetConveyorSpeed.s,SurfaceType_GetConveyorSpeed,0x800C9E18,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetConveyorDirection.s,SurfaceType_GetConveyorDirection,0x800C9E40,0x12 +asm/non_matchings/code/z_bgcheck/SurfaceType_IsWallDamage.s,SurfaceType_IsWallDamage,0x800C9E88,0xD +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurfaceImpl.s,WaterBox_GetSurfaceImpl,0x800C9EBC,0xBC +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface1.s,WaterBox_GetSurface1,0x800CA1AC,0xF +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface1_2.s,WaterBox_GetSurface1_2,0x800CA1E8,0x11 +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface2.s,WaterBox_GetSurface2,0x800CA22C,0xCF asm/non_matchings/code/z_bgcheck/func_800CA568.s,func_800CA568,0x800CA568,0x33 asm/non_matchings/code/z_bgcheck/func_800CA634.s,func_800CA634,0x800CA634,0x5 asm/non_matchings/code/z_bgcheck/func_800CA648.s,func_800CA648,0x800CA648,0x1C asm/non_matchings/code/z_bgcheck/func_800CA6B8.s,func_800CA6B8,0x800CA6B8,0x8 -asm/non_matchings/code/z_bgcheck/func_800CA6D8.s,func_800CA6D8,0x800CA6D8,0x6 +asm/non_matchings/code/z_bgcheck/WaterBox_GetLightSettingIndex.s,WaterBox_GetLightSettingIndex,0x800CA6D8,0x6 asm/non_matchings/code/z_bgcheck/func_800CA6F0.s,func_800CA6F0,0x800CA6F0,0xB8 asm/non_matchings/code/z_bgcheck/func_800CA9D0.s,func_800CA9D0,0x800CA9D0,0x11 asm/non_matchings/code/z_bgcheck/func_800CAA14.s,func_800CAA14,0x800CAA14,0x2F @@ -2770,7 +2770,7 @@ asm/non_matchings/code/sys_math/cos_rad.s,cos_rad,0x80179540,0x15 asm/non_matchings/code/sys_math/Rand_ZeroFloat.s,Rand_ZeroFloat,0x80179594,0xB asm/non_matchings/code/sys_math/randPlusMinusPoint5Scaled.s,randPlusMinusPoint5Scaled,0x801795C0,0xC asm/non_matchings/code/sys_math3d/Math3D_Normalize.s,Math3D_Normalize,0x801795F0,0x22 -asm/non_matchings/code/sys_math3d/func_80179678.s,func_80179678,0x80179678,0x48 +asm/non_matchings/code/sys_math3d/Math3D_PlaneVsLineSegClosestPoint.s,Math3D_PlaneVsLineSegClosestPoint,0x80179678,0x48 asm/non_matchings/code/sys_math3d/func_80179798.s,func_80179798,0x80179798,0xAB asm/non_matchings/code/sys_math3d/func_80179A44.s,func_80179A44,0x80179A44,0x3C asm/non_matchings/code/sys_math3d/func_80179B34.s,func_80179B34,0x80179B34,0x18 @@ -2792,46 +2792,46 @@ asm/non_matchings/code/sys_math3d/Math3D_XZDistanceSquared.s,Math3D_XZDistanceSq asm/non_matchings/code/sys_math3d/Math3D_XZDistance.s,Math3D_XZDistance,0x8017A678,0xC asm/non_matchings/code/sys_math3d/Math3D_LengthSquared.s,Math3D_LengthSquared,0x8017A6A8,0xB asm/non_matchings/code/sys_math3d/Math3D_Vec3fMagnitude.s,Math3D_Vec3fMagnitude,0x8017A6D4,0x9 -asm/non_matchings/code/sys_math3d/Math3D_DistanceSquared.s,Math3D_DistanceSquared,0x8017A6F8,0xA +asm/non_matchings/code/sys_math3d/Math3D_Vec3fDistSq.s,Math3D_Vec3fDistSq,0x8017A6F8,0xA asm/non_matchings/code/sys_math3d/Math3D_Distance.s,Math3D_Distance,0x8017A720,0x8 asm/non_matchings/code/sys_math3d/Math3D_DistanceS.s,Math3D_DistanceS,0x8017A740,0x1E asm/non_matchings/code/sys_math3d/func_8017A7B8.s,func_8017A7B8,0x8017A7B8,0x10 asm/non_matchings/code/sys_math3d/func_8017A7F8.s,func_8017A7F8,0x8017A7F8,0x10 asm/non_matchings/code/sys_math3d/func_8017A838.s,func_8017A838,0x8017A838,0x10 asm/non_matchings/code/sys_math3d/Math3D_CrossProduct.s,Math3D_CrossProduct,0x8017A878,0x1D -asm/non_matchings/code/sys_math3d/Math3D_NormalVector.s,Math3D_NormalVector,0x8017A8EC,0x1A -asm/non_matchings/code/sys_math3d/func_8017A954.s,func_8017A954,0x8017A954,0x2E -asm/non_matchings/code/sys_math3d/func_8017AA0C.s,func_8017AA0C,0x8017AA0C,0x6C -asm/non_matchings/code/sys_math3d/func_8017ABBC.s,func_8017ABBC,0x8017ABBC,0x5F -asm/non_matchings/code/sys_math3d/func_8017AD38.s,func_8017AD38,0x8017AD38,0x255 +asm/non_matchings/code/sys_math3d/Math3D_SurfaceNorm.s,Math3D_SurfaceNorm,0x8017A8EC,0x1A +asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeFaces.s,Math3D_PointRelativeToCubeFaces,0x8017A954,0x2E +asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeEdges.s,Math3D_PointRelativeToCubeEdges,0x8017AA0C,0x6C +asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeVertices.s,Math3D_PointRelativeToCubeVertices,0x8017ABBC,0x5F +asm/non_matchings/code/sys_math3d/Math3D_LineVsCube.s,Math3D_LineVsCube,0x8017AD38,0x255 asm/non_matchings/code/sys_math3d/func_8017B68C.s,func_8017B68C,0x8017B68C,0x5B asm/non_matchings/code/sys_math3d/func_8017B7F8.s,func_8017B7F8,0x8017B7F8,0x23 asm/non_matchings/code/sys_math3d/Math3D_UnitNormalVector.s,Math3D_UnitNormalVector,0x8017B884,0x45 asm/non_matchings/code/sys_math3d/Math3D_SignedDistanceFromPlane.s,Math3D_SignedDistanceFromPlane,0x8017B998,0x10 asm/non_matchings/code/sys_math3d/func_8017B9D8.s,func_8017B9D8,0x8017B9D8,0xF -asm/non_matchings/code/sys_math3d/Math3D_NormalizedDistanceFromPlane.s,Math3D_NormalizedDistanceFromPlane,0x8017BA14,0xE -asm/non_matchings/code/sys_math3d/Math3D_NormalizedSignedDistanceFromPlane.s,Math3D_NormalizedSignedDistanceFromPlane,0x8017BA4C,0x21 -asm/non_matchings/code/sys_math3d/func_8017BAD0.s,func_8017BAD0,0x8017BAD0,0xB2 +asm/non_matchings/code/sys_math3d/Math3D_UDistPlaneToPos.s,Math3D_UDistPlaneToPos,0x8017BA14,0xE +asm/non_matchings/code/sys_math3d/Math3D_DistPlaneToPos.s,Math3D_DistPlaneToPos,0x8017BA4C,0x21 +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYDist.s,Math3D_TriChkPointParaYDist,0x8017BAD0,0xB2 asm/non_matchings/code/sys_math3d/func_8017BD98.s,func_8017BD98,0x8017BD98,0x12 asm/non_matchings/code/sys_math3d/func_8017BDE0.s,func_8017BDE0,0x8017BDE0,0x14 -asm/non_matchings/code/sys_math3d/func_8017BE30.s,func_8017BE30,0x8017BE30,0x2C -asm/non_matchings/code/sys_math3d/func_8017BEE0.s,func_8017BEE0,0x8017BEE0,0x2B +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectDist.s,Math3D_TriChkPointParaYIntersectDist,0x8017BE30,0x2C +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri.s,Math3D_TriChkPointParaYIntersectInsideTri,0x8017BEE0,0x2B asm/non_matchings/code/sys_math3d/func_8017BF8C.s,func_8017BF8C,0x8017BF8C,0x1F -asm/non_matchings/code/sys_math3d/func_8017C008.s,func_8017C008,0x8017C008,0x5D +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaYIntersect.s,Math3D_TriChkLineSegParaYIntersect,0x8017C008,0x5D asm/non_matchings/code/sys_math3d/func_8017C17C.s,func_8017C17C,0x8017C17C,0x1D asm/non_matchings/code/sys_math3d/func_8017C1F0.s,func_8017C1F0,0x8017C1F0,0xA9 -asm/non_matchings/code/sys_math3d/func_8017C494.s,func_8017C494,0x8017C494,0x2B -asm/non_matchings/code/sys_math3d/func_8017C540.s,func_8017C540,0x8017C540,0xB2 +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri2.s,Math3D_TriChkPointParaYIntersectInsideTri2,0x8017C494,0x2B +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXDist.s,Math3D_TriChkPointParaXDist,0x8017C540,0xB2 asm/non_matchings/code/sys_math3d/func_8017C808.s,func_8017C808,0x8017C808,0x12 -asm/non_matchings/code/sys_math3d/func_8017C850.s,func_8017C850,0x8017C850,0x2D +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXIntersect.s,Math3D_TriChkPointParaXIntersect,0x8017C850,0x2D asm/non_matchings/code/sys_math3d/func_8017C904.s,func_8017C904,0x8017C904,0x1F -asm/non_matchings/code/sys_math3d/func_8017C980.s,func_8017C980,0x8017C980,0x62 +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaXIntersect.s,Math3D_TriChkLineSegParaXIntersect,0x8017C980,0x62 asm/non_matchings/code/sys_math3d/func_8017CB08.s,func_8017CB08,0x8017CB08,0x1D -asm/non_matchings/code/sys_math3d/func_8017CB7C.s,func_8017CB7C,0x8017CB7C,0xCB +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZDist.s,Math3D_TriChkLineSegParaZDist,0x8017CB7C,0xCB asm/non_matchings/code/sys_math3d/func_8017CEA8.s,func_8017CEA8,0x8017CEA8,0x12 -asm/non_matchings/code/sys_math3d/func_8017CEF0.s,func_8017CEF0,0x8017CEF0,0x2D +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaZIntersect.s,Math3D_TriChkPointParaZIntersect,0x8017CEF0,0x2D asm/non_matchings/code/sys_math3d/func_8017CFA4.s,func_8017CFA4,0x8017CFA4,0x1F -asm/non_matchings/code/sys_math3d/func_8017D020.s,func_8017D020,0x8017D020,0x63 +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZIntersect.s,Math3D_TriChkLineSegParaZIntersect,0x8017D020,0x63 asm/non_matchings/code/sys_math3d/func_8017D1AC.s,func_8017D1AC,0x8017D1AC,0x1D asm/non_matchings/code/sys_math3d/func_8017D220.s,func_8017D220,0x8017D220,0x37 asm/non_matchings/code/sys_math3d/func_8017D2FC.s,func_8017D2FC,0x8017D2FC,0x42 @@ -2843,7 +2843,7 @@ asm/non_matchings/code/sys_math3d/func_8017D7C0.s,func_8017D7C0,0x8017D7C0,0x15 asm/non_matchings/code/sys_math3d/func_8017D814.s,func_8017D814,0x8017D814,0x42 asm/non_matchings/code/sys_math3d/func_8017D91C.s,func_8017D91C,0x8017D91C,0x42 asm/non_matchings/code/sys_math3d/func_8017DA24.s,func_8017DA24,0x8017DA24,0x42 -asm/non_matchings/code/sys_math3d/Math3D_ColSphereLineSeg.s,Math3D_ColSphereLineSeg,0x8017DB2C,0x82 +asm/non_matchings/code/sys_math3d/Math3D_LineVsSph.s,Math3D_LineVsSph,0x8017DB2C,0x82 asm/non_matchings/code/sys_math3d/func_8017DD34.s,func_8017DD34,0x8017DD34,0x50 asm/non_matchings/code/sys_math3d/Math3D_ColSphereTri.s,Math3D_ColSphereTri,0x8017DE74,0x108 asm/non_matchings/code/sys_math3d/func_8017E294.s,func_8017E294,0x8017E294,0x2F @@ -2858,9 +2858,9 @@ asm/non_matchings/code/sys_math3d/Math3D_ColSphereCylinderDistanceAndAmount.s,Ma asm/non_matchings/code/sys_math3d/Math3D_ColCylinderCylinderAmount.s,Math3D_ColCylinderCylinderAmount,0x8017F45C,0x8 asm/non_matchings/code/sys_math3d/Math3D_ColCylinderCylinderAmountAndDistance.s,Math3D_ColCylinderCylinderAmountAndDistance,0x8017F47C,0x74 asm/non_matchings/code/sys_math3d/Math3d_ColTriTri.s,Math3d_ColTriTri,0x8017F64C,0xDD -asm/non_matchings/code/sys_math3d/func_8017F9C0.s,func_8017F9C0,0x8017F9C0,0x1D -asm/non_matchings/code/sys_math3d/func_8017FA34.s,func_8017FA34,0x8017FA34,0x1D -asm/non_matchings/code/sys_math3d/func_8017FAA8.s,func_8017FAA8,0x8017FAA8,0x1D +asm/non_matchings/code/sys_math3d/Math3D_XZInSphere.s,Math3D_XZInSphere,0x8017F9C0,0x1D +asm/non_matchings/code/sys_math3d/Math3D_XYInSphere.s,Math3D_XYInSphere,0x8017FA34,0x1D +asm/non_matchings/code/sys_math3d/Math3D_YZInSphere.s,Math3D_YZInSphere,0x8017FAA8,0x1D asm/non_matchings/code/sys_math3d/func_8017FB1C.s,func_8017FB1C,0x8017FB1C,0x8A asm/non_matchings/code/sys_math3d/func_8017FD44.s,func_8017FD44,0x8017FD44,0x5B asm/non_matchings/code/sys_math_atan/Math_GetAtan2Tbl.s,Math_GetAtan2Tbl,0x8017FEB0,0xD diff --git a/undefined_syms.txt b/undefined_syms.txt index e3cb90acdc..0d60359e11 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -3444,6 +3444,9 @@ D_06001384 = 0x06001384; D_06009890 = 0x06009890; D_0600A280 = 0x0600A280; D_0600AD98 = 0x0600AD98; +D_0600F8F0 = 0x0600F8F0; +D_0600FCF0 = 0x0600FCF0; +D_060100F0 = 0x060100F0; D_06011B60 = 0x06011B60; // ovl_En_Rg From d4dc34ee716b372d81ff8c4d166e70ecdd11e7ef Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 18 Dec 2021 13:37:37 -0300 Subject: [PATCH 07/27] Update progress script with new assets categories and update csv output format (#510) * Reorganize csvs and progress.py * Put stuff in the correct folders * Reduce lots of repeated code * Change csv output format * Filter out automaticaly named variables in "Matching" progress calculation for assets * Address Elliptic's review * Don't count handwritten files in progress and add a way to fix files detected in the wrong section * Add missing "total" * More fixing * Add two missing columns * Update paths in Jenkinsfile * Update progress shield in readme * Update progress link --- Jenkinsfile | 12 +- README.md | 4 +- .../icon_item_gameover_static.xml | 0 .../xml/{static => misc}/daytelop_static.xml | 0 .../{static => misc}/esp_daytelop_static.xml | 0 .../{static => misc}/fra_daytelop_static.xml | 0 .../{static => misc}/ger_daytelop_static.xml | 0 .../{static => misc}/nintendo_rogo_static.xml | 0 spec | 12 +- .../gamestates/ovl_daytelop/z_daytelop.c | 4 +- src/overlays/gamestates/ovl_title/z_title.c | 2 +- tools/filelists/mm.us.rev1/all.csv | 13 + tools/filelists/mm.us.rev1/archives.csv | 7 + tools/filelists/mm.us.rev1/asm.csv | 2 + tools/filelists/mm.us.rev1/deleted.csv | 3 + tools/filelists/mm.us.rev1/interface.csv | 11 + tools/filelists/mm.us.rev1/misc.csv | 22 +- .../mm.us.rev1/{object.csv => objects.csv} | 0 .../mm.us.rev1/{scene.csv => scenes.csv} | 0 tools/filelists/mm.us.rev1/segments.csv | 13 + tools/filelists/mm.us.rev1/text.csv | 2 + tools/filelists/mm.us.rev1/texture.csv | 43 ---- tools/progress.py | 241 +++++++++++++----- 23 files changed, 259 insertions(+), 132 deletions(-) rename assets/xml/{static => interface}/icon_item_gameover_static.xml (100%) rename assets/xml/{static => misc}/daytelop_static.xml (100%) rename assets/xml/{static => misc}/esp_daytelop_static.xml (100%) rename assets/xml/{static => misc}/fra_daytelop_static.xml (100%) rename assets/xml/{static => misc}/ger_daytelop_static.xml (100%) rename assets/xml/{static => misc}/nintendo_rogo_static.xml (100%) create mode 100644 tools/filelists/mm.us.rev1/archives.csv create mode 100644 tools/filelists/mm.us.rev1/deleted.csv create mode 100644 tools/filelists/mm.us.rev1/interface.csv rename tools/filelists/mm.us.rev1/{object.csv => objects.csv} (100%) rename tools/filelists/mm.us.rev1/{scene.csv => scenes.csv} (100%) create mode 100644 tools/filelists/mm.us.rev1/segments.csv create mode 100644 tools/filelists/mm.us.rev1/text.csv delete mode 100644 tools/filelists/mm.us.rev1/texture.csv diff --git a/Jenkinsfile b/Jenkinsfile index df06c6a096..cf5d8f3b63 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -52,9 +52,9 @@ pipeline { } steps { sh 'mkdir reports' - sh 'python3 ./tools/progress.py csv >> reports/progress_mm.us.rev1.csv' - sh 'python3 ./tools/progress.py csv -m >> reports/progress_matching_mm.us.rev1.csv' - sh 'python3 ./tools/progress.py shield-json > reports/progress_shield_mm.us.rev1.json' + sh 'python3 ./tools/progress.py csv >> reports/progress-mm-nonmatching.csv' + sh 'python3 ./tools/progress.py csv -m >> reports/progress-mm-matching.csv' + sh 'python3 ./tools/progress.py shield-json > reports/progress-mm-shield.json' stash includes: 'reports/*', name: 'reports' } } @@ -67,9 +67,9 @@ pipeline { } steps { unstash 'reports' - sh 'cat reports/progress_mm.us.rev1.csv >> /var/www/html/reports/progress_mm.us.rev1.csv' - sh 'cat reports/progress_matching_mm.us.rev1.csv >> /var/www/html/reports/progress_matching_mm.us.rev1.csv' - sh 'cat reports/progress_shield_mm.us.rev1.json > /var/www/html/reports/progress_shield_mm.us.rev1.json' + sh 'cat reports/progress-mm-nonmatching.csv >> /var/www/zelda64.dev/assets/csv/progress-mm-nonmatching.csv' + sh 'cat reports/progress-mm-matching.csv >> /var/www/zelda64.dev/assets/csv/progress-mm-matching.csv' + sh 'cat reports/progress-mm-shield.json > /var/www/zelda64.dev/assets/csv/progress-mm-shield.json' } } } diff --git a/README.md b/README.md index 99ae2355ab..3768ef1d99 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ [jenkins]: https://jenkins.deco.mp/job/MM/job/master [jenkins-badge]: https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins.deco.mp%2Fjob%2FMM%2Fjob%2Fmaster -[progress]: https://zelda64.dev/progress.html -[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/reports/progress_shield_mm.us.rev1.json +[progress]: https://zelda64.dev/games/mm +[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/reports/progress-mm-shield.json [contributors]: https://github.com/zeldaret/mm/graphs/contributors [contributors-badge]: https://img.shields.io/github/contributors/zeldaret/mm diff --git a/assets/xml/static/icon_item_gameover_static.xml b/assets/xml/interface/icon_item_gameover_static.xml similarity index 100% rename from assets/xml/static/icon_item_gameover_static.xml rename to assets/xml/interface/icon_item_gameover_static.xml diff --git a/assets/xml/static/daytelop_static.xml b/assets/xml/misc/daytelop_static.xml similarity index 100% rename from assets/xml/static/daytelop_static.xml rename to assets/xml/misc/daytelop_static.xml diff --git a/assets/xml/static/esp_daytelop_static.xml b/assets/xml/misc/esp_daytelop_static.xml similarity index 100% rename from assets/xml/static/esp_daytelop_static.xml rename to assets/xml/misc/esp_daytelop_static.xml diff --git a/assets/xml/static/fra_daytelop_static.xml b/assets/xml/misc/fra_daytelop_static.xml similarity index 100% rename from assets/xml/static/fra_daytelop_static.xml rename to assets/xml/misc/fra_daytelop_static.xml diff --git a/assets/xml/static/ger_daytelop_static.xml b/assets/xml/misc/ger_daytelop_static.xml similarity index 100% rename from assets/xml/static/ger_daytelop_static.xml rename to assets/xml/misc/ger_daytelop_static.xml diff --git a/assets/xml/static/nintendo_rogo_static.xml b/assets/xml/misc/nintendo_rogo_static.xml similarity index 100% rename from assets/xml/static/nintendo_rogo_static.xml rename to assets/xml/misc/nintendo_rogo_static.xml diff --git a/spec b/spec index ff445e731d..48b1055db8 100644 --- a/spec +++ b/spec @@ -312,7 +312,7 @@ beginseg name "icon_item_gameover_static" compress romalign 0x1000 - include "build/assets/static/icon_item_gameover_static/icon_item_gameover_static.o" + include "build/assets/interface/icon_item_gameover_static/icon_item_gameover_static.o" number 12 endseg @@ -8835,7 +8835,7 @@ beginseg name "nintendo_rogo_static" compress romalign 0x1000 - include "build/assets/static/nintendo_rogo_static/nintendo_rogo_static.o" + include "build/assets/misc/nintendo_rogo_static/nintendo_rogo_static.o" number 1 endseg @@ -8879,7 +8879,7 @@ beginseg name "daytelop_static" compress romalign 0x1000 - include "build/assets/static/daytelop_static/daytelop_static.o" + include "build/assets/misc/daytelop_static/daytelop_static.o" number 9 endseg @@ -8887,7 +8887,7 @@ beginseg name "ger_daytelop_static" compress romalign 0x1000 - include "build/assets/static/ger_daytelop_static/ger_daytelop_static.o" + include "build/assets/misc/ger_daytelop_static/ger_daytelop_static.o" number 9 endseg @@ -8895,7 +8895,7 @@ beginseg name "fra_daytelop_static" compress romalign 0x1000 - include "build/assets/static/fra_daytelop_static/fra_daytelop_static.o" + include "build/assets/misc/fra_daytelop_static/fra_daytelop_static.o" number 9 endseg @@ -8903,7 +8903,7 @@ beginseg name "esp_daytelop_static" compress romalign 0x1000 - include "build/assets/static/esp_daytelop_static/esp_daytelop_static.o" + include "build/assets/misc/esp_daytelop_static/esp_daytelop_static.o" number 9 endseg diff --git a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c index 9069a6aca8..1637e19781 100644 --- a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c +++ b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c @@ -5,8 +5,8 @@ */ #include "z_daytelop.h" -#include "static/daytelop_static/daytelop_static.h" -#include "static/icon_item_gameover_static/icon_item_gameover_static.h" +#include "misc/daytelop_static/daytelop_static.h" +#include "interface/icon_item_gameover_static/icon_item_gameover_static.h" // unused UNK_TYPE D_808158E0[] = { diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index 62a85c8633..a98b8e24a5 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -6,7 +6,7 @@ #include "z_title.h" #include "overlays/gamestates/ovl_opening/z_opening.h" -#include "static/nintendo_rogo_static/nintendo_rogo_static.h" +#include "misc/nintendo_rogo_static/nintendo_rogo_static.h" void Title_UpdateCounters(TitleContext* this) { if ((this->coverAlpha == 0) && (this->visibleDuration != 0)) { diff --git a/tools/filelists/mm.us.rev1/all.csv b/tools/filelists/mm.us.rev1/all.csv index b722e4938d..836f6d1722 100644 --- a/tools/filelists/mm.us.rev1/all.csv +++ b/tools/filelists/mm.us.rev1/all.csv @@ -1537,3 +1537,16 @@ 1536,KAKUSIANA_room_13 1537,KAKUSIANA_room_14 1538,bump_texture_static +1539,anime_model_1_static +1540,anime_model_2_static +1541,anime_model_3_static +1542,anime_model_4_static +1543,anime_model_5_static +1544,anime_model_6_static +1545,anime_texture_1_static +1546,anime_texture_2_static +1547,anime_texture_3_static +1548,anime_texture_4_static +1549,anime_texture_5_static +1550,anime_texture_6_static +1551,softsprite_matrix_static diff --git a/tools/filelists/mm.us.rev1/archives.csv b/tools/filelists/mm.us.rev1/archives.csv new file mode 100644 index 0000000000..a0b758dfd0 --- /dev/null +++ b/tools/filelists/mm.us.rev1/archives.csv @@ -0,0 +1,7 @@ +15,map_i_static +16,map_grand_static +17,item_name_static +18,map_name_static +19,icon_item_static_test +20,icon_item_24_static_test +22,schedule_dma_static_test diff --git a/tools/filelists/mm.us.rev1/asm.csv b/tools/filelists/mm.us.rev1/asm.csv index f3364252f0..0bc9311e9c 100644 --- a/tools/filelists/mm.us.rev1/asm.csv +++ b/tools/filelists/mm.us.rev1/asm.csv @@ -2,3 +2,5 @@ 1,boot 2,dmadata 31,code +1135,elf_message_field +1136,elf_message_ydan diff --git a/tools/filelists/mm.us.rev1/deleted.csv b/tools/filelists/mm.us.rev1/deleted.csv new file mode 100644 index 0000000000..12e60f6ee3 --- /dev/null +++ b/tools/filelists/mm.us.rev1/deleted.csv @@ -0,0 +1,3 @@ +8,icon_item_static_old +9,icon_item_24_static_old +21,schedule_dma_static_old diff --git a/tools/filelists/mm.us.rev1/interface.csv b/tools/filelists/mm.us.rev1/interface.csv new file mode 100644 index 0000000000..db78965de0 --- /dev/null +++ b/tools/filelists/mm.us.rev1/interface.csv @@ -0,0 +1,11 @@ +6,kanji +10,icon_item_field_static +11,icon_item_dungeon_static +12,icon_item_gameover_static +13,icon_item_jpn_static +14,icon_item_vtx_static +23,schedule_static +25,do_action_static +26,message_static +27,message_texture_static +28,nes_font_static diff --git a/tools/filelists/mm.us.rev1/misc.csv b/tools/filelists/mm.us.rev1/misc.csv index 60a33ac1b2..caebc3bb1b 100644 --- a/tools/filelists/mm.us.rev1/misc.csv +++ b/tools/filelists/mm.us.rev1/misc.csv @@ -1,6 +1,24 @@ 7,link_animetion +24,story_static +1114,scene_texture_01 +1115,scene_texture_02 +1116,scene_texture_03 +1117,scene_texture_04 +1118,scene_texture_05 +1119,scene_texture_06 +1120,scene_texture_07 +1121,scene_texture_08 1122,nintendo_rogo_static +1123,title_static 1124,memerrmsg 1125,locerrmsg -1135,elf_message_field -1136,elf_message_ydan +1126,parameter_static +1127,week_static +1128,daytelop_static +1129,ger_daytelop_static +1130,fra_daytelop_static +1131,esp_daytelop_static +1132,d2_fine_static +1133,d2_cloud_static +1134,d2_fine_pal_static +1538,bump_texture_static diff --git a/tools/filelists/mm.us.rev1/object.csv b/tools/filelists/mm.us.rev1/objects.csv similarity index 100% rename from tools/filelists/mm.us.rev1/object.csv rename to tools/filelists/mm.us.rev1/objects.csv diff --git a/tools/filelists/mm.us.rev1/scene.csv b/tools/filelists/mm.us.rev1/scenes.csv similarity index 100% rename from tools/filelists/mm.us.rev1/scene.csv rename to tools/filelists/mm.us.rev1/scenes.csv diff --git a/tools/filelists/mm.us.rev1/segments.csv b/tools/filelists/mm.us.rev1/segments.csv new file mode 100644 index 0000000000..f397c8e1cf --- /dev/null +++ b/tools/filelists/mm.us.rev1/segments.csv @@ -0,0 +1,13 @@ +1539,anime_model_1_static +1540,anime_model_2_static +1541,anime_model_3_static +1542,anime_model_4_static +1543,anime_model_5_static +1544,anime_model_6_static +1545,anime_texture_1_static +1546,anime_texture_2_static +1547,anime_texture_3_static +1548,anime_texture_4_static +1549,anime_texture_5_static +1550,anime_texture_6_static +1551,softsprite_matrix_static diff --git a/tools/filelists/mm.us.rev1/text.csv b/tools/filelists/mm.us.rev1/text.csv new file mode 100644 index 0000000000..82e09e4dd3 --- /dev/null +++ b/tools/filelists/mm.us.rev1/text.csv @@ -0,0 +1,2 @@ +29,message_data_static +30,staff_message_data_static diff --git a/tools/filelists/mm.us.rev1/texture.csv b/tools/filelists/mm.us.rev1/texture.csv deleted file mode 100644 index 17e4a9cf79..0000000000 --- a/tools/filelists/mm.us.rev1/texture.csv +++ /dev/null @@ -1,43 +0,0 @@ -6,kanji -8,icon_item_static_old -9,icon_item_24_static_old -10,icon_item_field_static -11,icon_item_dungeon_static -12,icon_item_gameover_static -13,icon_item_jpn_static -14,icon_item_vtx_static -15,map_i_static -16,map_grand_static -17,item_name_static -18,map_name_static -19,icon_item_static_test -20,icon_item_24_static_test -21,schedule_dma_static_old -22,schedule_dma_static_test -23,schedule_static -24,story_static -25,do_action_static -26,message_static -27,message_texture_static -28,nes_font_static -29,message_data_static -30,staff_message_data_static -1114,scene_texture_01 -1115,scene_texture_02 -1116,scene_texture_03 -1117,scene_texture_04 -1118,scene_texture_05 -1119,scene_texture_06 -1120,scene_texture_07 -1121,scene_texture_08 -1123,title_static -1126,parameter_static -1127,week_static -1128,daytelop_static -1129,ger_daytelop_static -1130,fra_daytelop_static -1131,esp_daytelop_static -1132,d2_fine_static -1133,d2_cloud_static -1134,d2_fine_pal_static -1538,bump_texture_static diff --git a/tools/progress.py b/tools/progress.py index a5068f792b..2ac68a076b 100755 --- a/tools/progress.py +++ b/tools/progress.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import argparse, csv, git, json, os, re +import argparse, csv, git, json, os, re, sys parser = argparse.ArgumentParser() @@ -12,9 +12,16 @@ args = parser.parse_args() NON_MATCHING_PATTERN = r'#ifdef\s+NON_MATCHING.*?#pragma\s+GLOBAL_ASM\s*\(\s*"(.*?)"\s*\).*?#endif' NOT_ATTEMPTED_PATTERN = r'#pragma\s+GLOBAL_ASM\s*\(\s*"(.*?)"\s*\)' +# This is the format ZAPD uses to autogenerate variable names +# It should not be used for properly documented variables +AUTOGENERATED_ASSET_NAME = re.compile(r".+[0-9A-Fa-f]{6}$") + # TODO: consider making this a parameter of this script GAME_VERSION = "mm.us.rev1" +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + def GetFunctionsByPattern(pattern, files): functions = [] @@ -71,6 +78,52 @@ def GetRemovableSize(functions_to_count): return size +def CalculateMapSizes(mapFileList): + for mapFile in mapFileList: + accumulatedSize = 0 + + if mapFile["section"] != ".data": + continue + if not mapFile["name"].startswith("build/assets/"): + continue + + symbolCount = len(mapFile["symbols"]) + if symbolCount == 0: + continue + + # Calculate size of each symbol + for index in range(symbolCount - 1): + symbol = mapFile["symbols"][index] + nextSymbol = mapFile["symbols"][index+1] + + size = nextSymbol["vram"] - symbol["vram"] + accumulatedSize += size + + mapFile["symbols"][index]["size"] = size + + # Calculate size of last symbol of the file + symbol = mapFile["symbols"][-1] + size = mapFile["size"] - accumulatedSize + mapFile["symbols"][-1]["size"] = size + return mapFileList + +def CalculateNonNamedAssets(mapFileList, assetsTracker): + for mapFile in mapFileList: + if mapFile["section"] != ".data": + continue + if not mapFile["name"].startswith("build/assets/"): + continue + + assetCat = mapFile["name"].split("/")[2] + + for symbol in mapFile["symbols"]: + symbolName = symbol["name"] + if AUTOGENERATED_ASSET_NAME.search(symbolName) is not None: + if assetCat in assetsTracker: + assetsTracker[assetCat]["removableSize"] += symbol["size"] + return assetsTracker + + map_file = ReadAllLines('build/mm.map') # Get list of Non-Matchings @@ -86,12 +139,36 @@ not_attempted_functions = list(set(not_attempted_functions).difference(non_match if not args.matching: non_matching_functions = [] -# Get asset files -audio_files = GetCsvFilelist(GAME_VERSION, "audio.csv") -misc_files = GetCsvFilelist(GAME_VERSION, "misc.csv") -object_files = GetCsvFilelist(GAME_VERSION, "object.csv") -scene_files = GetCsvFilelist(GAME_VERSION, "scene.csv") -texture_files = GetCsvFilelist(GAME_VERSION, "texture.csv") +# The order of this list should not change to prevent breaking the graph of the website +# New stuff shall be appended at the end of the list +assetsCategories = [ + "archives", + "audio", + "interface", + "misc", + "objects", + "scenes", + "text", + # "deleted", + # "segments", +] +assetsTracker = dict() + +# Manual fixer for files that would be counted in wrong categories +# "filename": "correctSection" +fileSectionFixer = { + "osFlash": "code" # Currently in `src/libultra` (would be counted as boot) +} + +for assetCat in assetsCategories: + assetsTracker[assetCat] = dict() + # Get asset files + assetsTracker[assetCat]["files"] = GetCsvFilelist(GAME_VERSION, f"{assetCat}.csv") + assetsTracker[assetCat]["currentSize"] = 0 + assetsTracker[assetCat]["removableSize"] = 0 + assetsTracker[assetCat]["totalSize"] = 0 + assetsTracker[assetCat]["percent"] = 0 + # Initialize all the code values src = 0 @@ -104,22 +181,36 @@ asm_code = 0 asm_boot = 0 asm_ovl = 0 asm_libultra = 0 -audio = 0 -misc = 0 -object_ = 0 -scene = 0 -texture = 0 + +mapFileList = [] for line in map_file: line_split = list(filter(None, line.split(" "))) if (len(line_split) == 4 and line_split[0].startswith(".")): section = line_split[0] + obj_vram = int(line_split[1], 16) file_size = int(line_split[2], 16) - obj_file = line_split[3] + obj_file = line_split[3].strip() + objFileSplit = obj_file.split("/") + + fileData = {"name": obj_file, "vram": obj_vram, "size": file_size, "section": section, "symbols": []} + mapFileList.append(fileData) if (section == ".text"): - if (obj_file.startswith("build/src")): + objFileName = objFileSplit[-1].split(".o")[0] + + if objFileName in fileSectionFixer: + correctSection = fileSectionFixer[objFileName] + if correctSection == "code": + src_code += file_size + elif correctSection == "libultra": + src_libultra += file_size + elif correctSection == "boot": + src_boot += file_size + elif correctSection == "overlays": + src_ovl += file_size + elif (obj_file.startswith("build/src")): if (obj_file.startswith("build/src/code")): src_code += file_size elif (obj_file.startswith("build/src/libultra")): @@ -138,17 +229,29 @@ for line in map_file: elif (obj_file.startswith("build/asm/overlays")): asm_ovl += file_size - if (section == ".data"): - if (obj_file.startswith("build/assets/audio")): - audio += file_size - elif (obj_file.startswith("build/assets/misc")): - misc += file_size - elif (obj_file.startswith("build/assets/objects")): - object_ += file_size - elif (obj_file.startswith("build/assets/scenes")): - scene += file_size - elif (obj_file.startswith("build/assets/textures")): - texture += file_size + if section == ".data": + if obj_file.startswith("build/assets/"): + assetCat = obj_file.split("/")[2] + if assetCat in assetsTracker: + assetsTracker[assetCat]["currentSize"] += file_size + else: + eprint(f"Found file '{obj_file}' in unknown asset category '{assetCat}'") + eprint("I'll ignore this for now, but please fix it!") + + elif len(line_split) == 2 and line_split[0].startswith("0x00000000"): + varVramStr, varName = line_split + varVram = int(varVramStr, 16) + varName = varName.strip() + if varName == "0x0": + continue + #print(varVram, varName) + symbolData = {"name": varName, "vram": varVram, "size": 0} + mapFileList[-1]["symbols"].append(symbolData) + +mapFileList = CalculateMapSizes(mapFileList) + +assetsTracker = CalculateNonNamedAssets(mapFileList, assetsTracker) + # Add libultra to boot. src_boot += src_libultra @@ -184,27 +287,22 @@ boot = src_boot - (non_matching_asm_boot + not_attempted_asm_boot) ovl = src_ovl - (non_matching_asm_ovl + not_attempted_asm_ovl) # Total code bucket sizes -code_size = src_code + asm_code -boot_size = src_boot + asm_boot -ovl_size = src_ovl + asm_ovl -handwritten = 0 # Currently unsure of any handwritten asm in MM +code_size = src_code # + asm_code +boot_size = src_boot # + asm_boot +ovl_size = src_ovl # + asm_ovl +handwritten = asm_code + asm_boot + asm_ovl + +# Calculate the total amount of decompilable code +total = code_size + boot_size + ovl_size # Calculate size of all assets -audio_size = 0 -misc_size = 0 -object_size = 0 -scene_size = 0 -texture_size = 0 -for index, f in audio_files: - audio_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in misc_files: - misc_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in object_files: - object_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in scene_files: - scene_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in texture_files: - texture_size += os.stat(os.path.join("baserom", f)).st_size +for assetCat in assetsTracker: + for index, f in assetsTracker[assetCat]["files"]: + assetsTracker[assetCat]["totalSize"] += os.stat(os.path.join("baserom", f)).st_size + +if args.matching: + for assetCat in assetsTracker: + assetsTracker[assetCat]["currentSize"] -= assetsTracker[assetCat]["removableSize"] # Calculate asm and src totals src = src_code + src_boot + src_ovl @@ -214,12 +312,9 @@ asm = asm_code + asm_boot + asm_ovl src -= non_matching_asm + not_attempted_asm asm += non_matching_asm + not_attempted_asm -# Calculate the total amount of decompilable code -total = src + asm - # Calculate assets totals -assets = audio + misc + object_ + scene + texture -assets_total = audio_size + misc_size + object_size + scene_size + texture_size +assets = sum(x["currentSize"] for x in assetsTracker.values()) +assets_total = sum(x["totalSize"] for x in assetsTracker.values()) # Convert vaules to percentages src_percent = 100 * src / total @@ -227,12 +322,11 @@ asm_percent = 100 * asm / total code_percent = 100 * code / code_size boot_percent = 100 * boot / boot_size ovl_percent = 100 * ovl / ovl_size + assets_percent = 100 * assets / assets_total -audio_percent = 100 * audio / audio_size -misc_percent = 100 * misc / misc_size -object_percent = 100 * object_ / object_size -scene_percent = 100 * scene / scene_size -texture_percent = 100 * texture / texture_size + +for assetCat in assetsTracker: + assetsTracker[assetCat]["percent"] = 100 * assetsTracker[assetCat]["currentSize"] / assetsTracker[assetCat]["totalSize"] # convert bytes to masks and rupees num_masks = 24 @@ -273,16 +367,22 @@ rupees = int((src % bytes_per_mask) / bytes_per_rupee) #print("") if args.format == 'csv': - version = 1 + version = 2 git_object = git.Repo().head.object timestamp = str(git_object.committed_date) git_hash = git_object.hexsha - csv_list = [str(version), timestamp, git_hash, str(code), str(code_size), str(boot), str(boot_size), - str(ovl), str(ovl_size), str(src), str(asm), str(len(non_matching_functions)), - str(audio), str(audio_size), str(misc), str(misc_size), str(object_), str(object_size), - str(scene), str(scene_size), str(texture), str(texture_size)] + csv_list = [ + version, timestamp, git_hash, src, total, + boot, boot_size, code, code_size, ovl, ovl_size, + asm, len(non_matching_functions), + ] + csv_list += [ + assets, assets_total, + ] + for assetCat in assetsCategories: + csv_list += [assetsTracker[assetCat]["currentSize"], assetsTracker[assetCat]["totalSize"]] - print(",".join(csv_list)) + print(",".join(map(str, csv_list))) elif args.format == 'shield-json': # https://shields.io/endpoint print(json.dumps({ @@ -293,18 +393,19 @@ elif args.format == 'shield-json': })) elif args.format == 'text': adjective = "decompiled" if not args.matching else "matched" + assetsAdjective = "debinarized" if not args.matching else "identified" - print("src: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(src, total, adjective, round(src_percent, 4))) - print(" boot: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(boot, boot_size, adjective, round(boot_percent, 4))) - print(" code: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(code, code_size, adjective, round(code_percent, 4))) - print(" overlays: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(ovl, ovl_size, adjective, round(ovl_percent, 4))) + print("src: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(src, total, adjective, round(src_percent, 4))) + print(" boot: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(boot, boot_size, adjective, round(boot_percent, 4))) + print(" code: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(code, code_size, adjective, round(code_percent, 4))) + print(" overlays: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(ovl, ovl_size, adjective, round(ovl_percent, 4))) print() - print("assets: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(assets, assets_total, round(assets_percent, 4))) - print(" audio: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(audio, audio_size, round(audio_percent, 4))) - print(" misc: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(misc, misc_size, round(misc_percent, 4))) - print(" objects: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(object_, object_size, round(object_percent, 4))) - print(" scenes: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(scene, scene_size, round(scene_percent, 4))) - print(" textures: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(texture, texture_size, round(texture_percent, 4))) + + print("assets: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(assets, assets_total, assetsAdjective, round(assets_percent, 4))) + for assetCat in assetsTracker: + data = assetsTracker[assetCat] + print(" {:<10} {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(f"{assetCat}:", data["currentSize"], data["totalSize"], assetsAdjective, round(data["percent"], 4))) + print() print("------------------------------------\n") From d62fb2b689c2689cc6c8bef4de334a39d8b7ab69 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sat, 18 Dec 2021 19:37:05 +0000 Subject: [PATCH 08/27] Initial object file xmls (#312) * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "3c00dcb3" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "3c00dcb3" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * Object xmls * Fix bss reordering * Setup has warnings now * Fix object_gi_reserve01 dlist names * rm xml -> c make rule * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "ba947126" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "ba947126" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * SPBranchList related warnings gone * Remove some mis-detected animations * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "405fc13e" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "405fc13e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * scene related setup warning gone * Fix * Newlines --- Makefile | 38 +- assets/xml/objects/gameplay_dangeon_keep.xml | 89 ++ assets/xml/objects/gameplay_field_keep.xml | 50 + assets/xml/objects/gameplay_keep.xml | 1415 +++++++++++++++++ assets/xml/objects/object_ah.xml | 58 + assets/xml/objects/object_ahg.xml | 53 + assets/xml/objects/object_al.xml | 75 + assets/xml/objects/object_am.xml | 41 + assets/xml/objects/object_an1.xml | 81 + assets/xml/objects/object_an2.xml | 12 + assets/xml/objects/object_an3.xml | 12 + assets/xml/objects/object_an4.xml | 15 + assets/xml/objects/object_and.xml | 79 + assets/xml/objects/object_ani.xml | 61 + assets/xml/objects/object_aob.xml | 53 + assets/xml/objects/object_astr_obj.xml | 13 + assets/xml/objects/object_az.xml | 145 ++ assets/xml/objects/object_b_heart.xml | 8 + assets/xml/objects/object_bai.xml | 53 + assets/xml/objects/object_bal.xml | 81 + assets/xml/objects/object_bat.xml | 17 + assets/xml/objects/object_bb.xml | 37 + assets/xml/objects/object_bba.xml | 56 + assets/xml/objects/object_bdoor.xml | 18 + assets/xml/objects/object_bee.xml | 28 + assets/xml/objects/object_bg.xml | 110 ++ assets/xml/objects/object_bh.xml | 18 + assets/xml/objects/object_big_fwall.xml | 6 + assets/xml/objects/object_bigicicle.xml | 15 + assets/xml/objects/object_bigokuta.xml | 58 + assets/xml/objects/object_bigpo.xml | 46 + assets/xml/objects/object_bigslime.xml | 114 ++ assets/xml/objects/object_bji.xml | 56 + assets/xml/objects/object_bjt.xml | 23 + assets/xml/objects/object_bob.xml | 47 + assets/xml/objects/object_boj.xml | 92 ++ assets/xml/objects/object_bombf.xml | 11 + assets/xml/objects/object_bombiwa.xml | 28 + assets/xml/objects/object_boss01.xml | 189 +++ assets/xml/objects/object_boss02.xml | 99 ++ assets/xml/objects/object_boss03.xml | 93 ++ assets/xml/objects/object_boss04.xml | 30 + assets/xml/objects/object_boss05.xml | 81 + assets/xml/objects/object_boss07.xml | 216 +++ assets/xml/objects/object_boss_hakugin.xml | 82 + assets/xml/objects/object_botihasira.xml | 11 + assets/xml/objects/object_box.xml | 52 + assets/xml/objects/object_boyo.xml | 8 + assets/xml/objects/object_bsb.xml | 80 + assets/xml/objects/object_bsmask.xml | 28 + assets/xml/objects/object_bubble.xml | 6 + assets/xml/objects/object_cha.xml | 12 + assets/xml/objects/object_cne.xml | 47 + assets/xml/objects/object_comb.xml | 8 + assets/xml/objects/object_cow.xml | 38 + assets/xml/objects/object_crace_object.xml | 8 + assets/xml/objects/object_crow.xml | 24 + assets/xml/objects/object_cs.xml | 90 ++ assets/xml/objects/object_ctower_rot.xml | 63 + assets/xml/objects/object_d_hsblock.xml | 10 + assets/xml/objects/object_d_lift.xml | 11 + assets/xml/objects/object_dai.xml | 86 + assets/xml/objects/object_daiku.xml | 76 + assets/xml/objects/object_danpei_object.xml | 15 + assets/xml/objects/object_dblue_object.xml | 78 + assets/xml/objects/object_death.xml | 85 + assets/xml/objects/object_dekubaba.xml | 27 + .../xml/objects/object_dekucity_ana_obj.xml | 7 + assets/xml/objects/object_dekucity_obj.xml | 23 + assets/xml/objects/object_dekunuts.xml | 42 + assets/xml/objects/object_delf.xml | 82 + assets/xml/objects/object_dhouse.xml | 33 + assets/xml/objects/object_dinofos.xml | 71 + assets/xml/objects/object_dkjail_obj.xml | 9 + assets/xml/objects/object_dmask.xml | 24 + assets/xml/objects/object_dnk.xml | 48 + assets/xml/objects/object_dno.xml | 86 + assets/xml/objects/object_dnp.xml | 85 + assets/xml/objects/object_dnq.xml | 94 ++ assets/xml/objects/object_dns.xml | 42 + assets/xml/objects/object_dnt.xml | 91 ++ assets/xml/objects/object_dodongo.xml | 68 + assets/xml/objects/object_dog.xml | 53 + assets/xml/objects/object_dor01.xml | 7 + assets/xml/objects/object_dor02.xml | 7 + assets/xml/objects/object_dor03.xml | 6 + assets/xml/objects/object_dor04.xml | 7 + assets/xml/objects/object_dora.xml | 17 + assets/xml/objects/object_driftice.xml | 11 + assets/xml/objects/object_drs.xml | 20 + assets/xml/objects/object_ds2.xml | 32 + assets/xml/objects/object_ds2n.xml | 55 + assets/xml/objects/object_dt.xml | 67 + assets/xml/objects/object_dy_obj.xml | 93 ++ assets/xml/objects/object_efc_star_field.xml | 8 + assets/xml/objects/object_efc_tw.xml | 10 + assets/xml/objects/object_eg.xml | 106 ++ assets/xml/objects/object_ending_obj.xml | 23 + assets/xml/objects/object_f40_obj.xml | 17 + assets/xml/objects/object_f40_switch.xml | 9 + assets/xml/objects/object_f52_obj.xml | 16 + assets/xml/objects/object_f53_obj.xml | 25 + assets/xml/objects/object_fall.xml | 28 + assets/xml/objects/object_fall2.xml | 25 + assets/xml/objects/object_famos.xml | 28 + assets/xml/objects/object_fb.xml | 63 + assets/xml/objects/object_firefly.xml | 54 + assets/xml/objects/object_fish.xml | 157 ++ assets/xml/objects/object_flowerpot.xml | 11 + assets/xml/objects/object_fr.xml | 66 + assets/xml/objects/object_fsn.xml | 60 + assets/xml/objects/object_fu.xml | 49 + assets/xml/objects/object_fu_kaiten.xml | 17 + assets/xml/objects/object_fu_mato.xml | 22 + assets/xml/objects/object_funen.xml | 6 + assets/xml/objects/object_fusen.xml | 8 + assets/xml/objects/object_fwall.xml | 6 + assets/xml/objects/object_fz.xml | 12 + assets/xml/objects/object_ge1.xml | 63 + assets/xml/objects/object_geldb.xml | 78 + assets/xml/objects/object_gg.xml | 77 + assets/xml/objects/object_ghaka.xml | 12 + assets/xml/objects/object_gi_arrow.xml | 7 + assets/xml/objects/object_gi_arrowcase.xml | 12 + assets/xml/objects/object_gi_bean.xml | 5 + assets/xml/objects/object_gi_bigbomb.xml | 10 + assets/xml/objects/object_gi_bomb_1.xml | 5 + assets/xml/objects/object_gi_bomb_2.xml | 5 + assets/xml/objects/object_gi_bombpouch.xml | 12 + assets/xml/objects/object_gi_bosskey.xml | 6 + assets/xml/objects/object_gi_bottle.xml | 6 + assets/xml/objects/object_gi_bottle_04.xml | 12 + assets/xml/objects/object_gi_bottle_15.xml | 10 + assets/xml/objects/object_gi_bottle_16.xml | 8 + assets/xml/objects/object_gi_bottle_21.xml | 9 + assets/xml/objects/object_gi_bottle_22.xml | 10 + assets/xml/objects/object_gi_bottle_red.xml | 8 + assets/xml/objects/object_gi_bow.xml | 8 + assets/xml/objects/object_gi_camera.xml | 9 + assets/xml/objects/object_gi_compass.xml | 6 + assets/xml/objects/object_gi_fieldmap.xml | 9 + assets/xml/objects/object_gi_fish.xml | 5 + assets/xml/objects/object_gi_ghost.xml | 11 + assets/xml/objects/object_gi_glasses.xml | 6 + assets/xml/objects/object_gi_gold_dust.xml | 8 + assets/xml/objects/object_gi_golonmask.xml | 9 + assets/xml/objects/object_gi_heart.xml | 5 + assets/xml/objects/object_gi_hearts.xml | 7 + assets/xml/objects/object_gi_hookshot.xml | 8 + assets/xml/objects/object_gi_insect.xml | 6 + assets/xml/objects/object_gi_key.xml | 5 + assets/xml/objects/object_gi_ki_tan_mask.xml | 7 + assets/xml/objects/object_gi_liquid.xml | 19 + assets/xml/objects/object_gi_loach.xml | 10 + assets/xml/objects/object_gi_longsword.xml | 5 + assets/xml/objects/object_gi_m_arrow.xml | 9 + .../xml/objects/object_gi_magicmushroom.xml | 9 + assets/xml/objects/object_gi_magicpot.xml | 6 + assets/xml/objects/object_gi_map.xml | 7 + assets/xml/objects/object_gi_mask03.xml | 13 + assets/xml/objects/object_gi_mask05.xml | 11 + assets/xml/objects/object_gi_mask06.xml | 10 + assets/xml/objects/object_gi_mask09.xml | 12 + assets/xml/objects/object_gi_mask10.xml | 10 + assets/xml/objects/object_gi_mask11.xml | 14 + assets/xml/objects/object_gi_mask12.xml | 8 + assets/xml/objects/object_gi_mask13.xml | 9 + assets/xml/objects/object_gi_mask14.xml | 10 + assets/xml/objects/object_gi_mask15.xml | 9 + assets/xml/objects/object_gi_mask16.xml | 11 + assets/xml/objects/object_gi_mask17.xml | 13 + assets/xml/objects/object_gi_mask18.xml | 12 + assets/xml/objects/object_gi_mask20.xml | 11 + assets/xml/objects/object_gi_mask21.xml | 8 + assets/xml/objects/object_gi_mask22.xml | 13 + assets/xml/objects/object_gi_mask23.xml | 8 + assets/xml/objects/object_gi_melody.xml | 11 + assets/xml/objects/object_gi_milk.xml | 7 + assets/xml/objects/object_gi_mssa.xml | 10 + assets/xml/objects/object_gi_nuts.xml | 6 + assets/xml/objects/object_gi_nutsmask.xml | 9 + assets/xml/objects/object_gi_ocarina.xml | 7 + assets/xml/objects/object_gi_purse.xml | 17 + assets/xml/objects/object_gi_rabit_mask.xml | 7 + assets/xml/objects/object_gi_reserve00.xml | 11 + assets/xml/objects/object_gi_reserve01.xml | 14 + assets/xml/objects/object_gi_reserve_b_00.xml | 8 + assets/xml/objects/object_gi_reserve_b_01.xml | 10 + assets/xml/objects/object_gi_reserve_c_00.xml | 9 + assets/xml/objects/object_gi_reserve_c_01.xml | 8 + assets/xml/objects/object_gi_rupy.xml | 18 + assets/xml/objects/object_gi_schedule.xml | 11 + assets/xml/objects/object_gi_seahorse.xml | 12 + assets/xml/objects/object_gi_shield_2.xml | 10 + assets/xml/objects/object_gi_shield_3.xml | 10 + assets/xml/objects/object_gi_soldout.xml | 6 + assets/xml/objects/object_gi_soul.xml | 8 + assets/xml/objects/object_gi_stick.xml | 5 + assets/xml/objects/object_gi_stonemask.xml | 8 + assets/xml/objects/object_gi_sutaru.xml | 6 + assets/xml/objects/object_gi_sword_1.xml | 9 + assets/xml/objects/object_gi_sword_2.xml | 9 + assets/xml/objects/object_gi_sword_3.xml | 9 + assets/xml/objects/object_gi_sword_4.xml | 9 + assets/xml/objects/object_gi_truth_mask.xml | 8 + assets/xml/objects/object_gi_zoramask.xml | 11 + assets/xml/objects/object_giant.xml | 63 + assets/xml/objects/object_gk.xml | 75 + assets/xml/objects/object_gla.xml | 73 + assets/xml/objects/object_gm.xml | 6 + assets/xml/objects/object_gmo.xml | 13 + assets/xml/objects/object_goroiwa.xml | 28 + assets/xml/objects/object_goronswitch.xml | 14 + assets/xml/objects/object_grasshopper.xml | 67 + assets/xml/objects/object_gs.xml | 8 + assets/xml/objects/object_ha.xml | 135 ++ assets/xml/objects/object_haka_obj.xml | 32 + assets/xml/objects/object_hakaisi.xml | 15 + assets/xml/objects/object_hakugin_demo.xml | 8 + assets/xml/objects/object_hakugin_obj.xml | 91 ++ assets/xml/objects/object_hana.xml | 13 + assets/xml/objects/object_hanareyama_obj.xml | 65 + assets/xml/objects/object_harfgibud.xml | 120 ++ assets/xml/objects/object_hariko.xml | 8 + assets/xml/objects/object_hata.xml | 39 + assets/xml/objects/object_hgdoor.xml | 13 + assets/xml/objects/object_hintnuts.xml | 40 + .../xml/objects/object_horse_game_check.xml | 16 + .../xml/objects/object_horse_link_child.xml | 88 + assets/xml/objects/object_hs.xml | 47 + assets/xml/objects/object_hsstump.xml | 10 + assets/xml/objects/object_hunsui.xml | 12 + assets/xml/objects/object_ice_block.xml | 15 + assets/xml/objects/object_icefloe.xml | 7 + assets/xml/objects/object_icicle.xml | 7 + assets/xml/objects/object_ik.xml | 106 ++ assets/xml/objects/object_ikana_obj.xml | 67 + assets/xml/objects/object_ikn_demo.xml | 118 ++ assets/xml/objects/object_ikninside_obj.xml | 48 + assets/xml/objects/object_iknv_obj.xml | 69 + assets/xml/objects/object_in.xml | 139 ++ assets/xml/objects/object_in2.xml | 82 + assets/xml/objects/object_inibs_object.xml | 35 + assets/xml/objects/object_ishi.xml | 6 + assets/xml/objects/object_jg.xml | 100 ++ assets/xml/objects/object_js.xml | 45 + assets/xml/objects/object_jso.xml | 122 ++ assets/xml/objects/object_ka.xml | 69 + assets/xml/objects/object_kaizoku_obj.xml | 41 + assets/xml/objects/object_kamejima.xml | 78 + assets/xml/objects/object_kanban.xml | 18 + assets/xml/objects/object_kbt.xml | 69 + assets/xml/objects/object_keikoku_demo.xml | 21 + assets/xml/objects/object_keikoku_obj.xml | 27 + assets/xml/objects/object_kepn_koya.xml | 18 + assets/xml/objects/object_kgy.xml | 74 + assets/xml/objects/object_kibako.xml | 8 + assets/xml/objects/object_kibako2.xml | 13 + assets/xml/objects/object_kin2_obj.xml | 34 + assets/xml/objects/object_kinsta1_obj.xml | 7 + assets/xml/objects/object_kinsta2_obj.xml | 6 + assets/xml/objects/object_kitan.xml | 54 + assets/xml/objects/object_knight.xml | 208 +++ assets/xml/objects/object_kujiya.xml | 25 + assets/xml/objects/object_kumo30.xml | 14 + assets/xml/objects/object_kusa.xml | 6 + assets/xml/objects/object_kz.xml | 87 + assets/xml/objects/object_kzsaku.xml | 7 + assets/xml/objects/object_ladder.xml | 13 + assets/xml/objects/object_last_obj.xml | 21 + assets/xml/objects/object_lastday.xml | 17 + assets/xml/objects/object_lbfshot.xml | 9 + assets/xml/objects/object_lightblock.xml | 9 + assets/xml/objects/object_lightswitch.xml | 9 + assets/xml/objects/object_link_boy.xml | 81 + assets/xml/objects/object_link_child.xml | 156 ++ assets/xml/objects/object_link_goron.xml | 108 ++ assets/xml/objects/object_link_nuts.xml | 79 + assets/xml/objects/object_link_zora.xml | 89 ++ assets/xml/objects/object_lodmoon.xml | 12 + assets/xml/objects/object_lotus.xml | 8 + assets/xml/objects/object_ma1.xml | 88 + assets/xml/objects/object_ma2.xml | 76 + assets/xml/objects/object_mag.xml | 28 + assets/xml/objects/object_mamenoki.xml | 16 + assets/xml/objects/object_market_obj.xml | 65 + assets/xml/objects/object_maruta.xml | 16 + assets/xml/objects/object_mask_bakuretu.xml | 11 + assets/xml/objects/object_mask_bigelf.xml | 12 + assets/xml/objects/object_mask_boy.xml | 11 + assets/xml/objects/object_mask_bree.xml | 10 + assets/xml/objects/object_mask_bu_san.xml | 12 + assets/xml/objects/object_mask_dancer.xml | 12 + assets/xml/objects/object_mask_gero.xml | 13 + assets/xml/objects/object_mask_gibudo.xml | 7 + assets/xml/objects/object_mask_goron.xml | 10 + assets/xml/objects/object_mask_json.xml | 11 + assets/xml/objects/object_mask_kerfay.xml | 10 + assets/xml/objects/object_mask_ki_tan.xml | 8 + assets/xml/objects/object_mask_kyojin.xml | 6 + assets/xml/objects/object_mask_meoto.xml | 9 + assets/xml/objects/object_mask_nuts.xml | 8 + assets/xml/objects/object_mask_posthat.xml | 9 + assets/xml/objects/object_mask_rabit.xml | 8 + assets/xml/objects/object_mask_romerny.xml | 11 + assets/xml/objects/object_mask_skj.xml | 13 + assets/xml/objects/object_mask_stone.xml | 7 + assets/xml/objects/object_mask_truth.xml | 6 + assets/xml/objects/object_mask_yofukasi.xml | 8 + assets/xml/objects/object_mask_zacho.xml | 13 + assets/xml/objects/object_mask_zora.xml | 10 + assets/xml/objects/object_mastergolon.xml | 5 + assets/xml/objects/object_masterzoora.xml | 5 + assets/xml/objects/object_mbar_obj.xml | 10 + assets/xml/objects/object_meganeana_obj.xml | 9 + assets/xml/objects/object_milkbar.xml | 64 + assets/xml/objects/object_mir_ray.xml | 12 + assets/xml/objects/object_mk.xml | 45 + assets/xml/objects/object_mkk.xml | 15 + assets/xml/objects/object_mm.xml | 67 + assets/xml/objects/object_mnk.xml | 126 ++ assets/xml/objects/object_moonend.xml | 40 + assets/xml/objects/object_moonston.xml | 9 + assets/xml/objects/object_ms.xml | 32 + assets/xml/objects/object_msmo.xml | 9 + assets/xml/objects/object_mtoride.xml | 49 + assets/xml/objects/object_mu.xml | 62 + assets/xml/objects/object_nb.xml | 46 + assets/xml/objects/object_niw.xml | 38 + assets/xml/objects/object_nnh.xml | 10 + assets/xml/objects/object_numa_obj.xml | 57 + assets/xml/objects/object_nwc.xml | 29 + assets/xml/objects/object_ny.xml | 13 + assets/xml/objects/object_oF1d_map.xml | 105 ++ assets/xml/objects/object_ob.xml | 84 + assets/xml/objects/object_obj_chan.xml | 13 + assets/xml/objects/object_obj_danpeilift.xml | 7 + assets/xml/objects/object_obj_dinner.xml | 11 + assets/xml/objects/object_obj_milk_bin.xml | 9 + assets/xml/objects/object_obj_tokeidai.xml | 59 + assets/xml/objects/object_obj_usiyane.xml | 13 + assets/xml/objects/object_obj_yasi.xml | 11 + assets/xml/objects/object_okuta.xml | 59 + assets/xml/objects/object_omoya_obj.xml | 8 + assets/xml/objects/object_open_obj.xml | 27 + assets/xml/objects/object_os_anime.xml | 26 + assets/xml/objects/object_osn.xml | 117 ++ assets/xml/objects/object_ot.xml | 54 + assets/xml/objects/object_owl.xml | 93 ++ assets/xml/objects/object_oyu.xml | 9 + assets/xml/objects/object_pamera.xml | 71 + assets/xml/objects/object_ph.xml | 44 + assets/xml/objects/object_po.xml | 53 + assets/xml/objects/object_po_composer.xml | 58 + assets/xml/objects/object_po_fusen.xml | 32 + assets/xml/objects/object_po_sisters.xml | 53 + assets/xml/objects/object_posthouse_obj.xml | 11 + assets/xml/objects/object_pp.xml | 131 ++ assets/xml/objects/object_pr.xml | 62 + assets/xml/objects/object_ps.xml | 40 + assets/xml/objects/object_pst.xml | 14 + assets/xml/objects/object_racetsubo.xml | 11 + assets/xml/objects/object_raf.xml | 42 + assets/xml/objects/object_raillift.xml | 26 + assets/xml/objects/object_random_obj.xml | 6 + assets/xml/objects/object_rat.xml | 28 + assets/xml/objects/object_rb.xml | 44 + assets/xml/objects/object_rd.xml | 114 ++ assets/xml/objects/object_redead_obj.xml | 7 + assets/xml/objects/object_rotlift.xml | 16 + assets/xml/objects/object_rr.xml | 8 + assets/xml/objects/object_rs.xml | 53 + assets/xml/objects/object_ru2.xml | 78 + assets/xml/objects/object_rz.xml | 71 + assets/xml/objects/object_sb.xml | 30 + assets/xml/objects/object_sdn.xml | 66 + assets/xml/objects/object_secom_obj.xml | 15 + assets/xml/objects/object_sek.xml | 18 + assets/xml/objects/object_sekihig.xml | 16 + assets/xml/objects/object_sekihil.xml | 16 + assets/xml/objects/object_sekihin.xml | 17 + assets/xml/objects/object_sekihiz.xml | 9 + assets/xml/objects/object_shn.xml | 94 ++ assets/xml/objects/object_sichitai_obj.xml | 11 + assets/xml/objects/object_sinkai_kabe.xml | 5 + assets/xml/objects/object_skb.xml | 64 + assets/xml/objects/object_slime.xml | 14 + assets/xml/objects/object_smtower.xml | 8 + assets/xml/objects/object_snowman.xml | 49 + assets/xml/objects/object_snowwd.xml | 9 + assets/xml/objects/object_spdweb.xml | 13 + assets/xml/objects/object_spidertent.xml | 12 + assets/xml/objects/object_spinyroll.xml | 8 + assets/xml/objects/object_spot11_obj.xml | 13 + assets/xml/objects/object_ssh.xml | 63 + assets/xml/objects/object_st.xml | 71 + assets/xml/objects/object_sth.xml | 42 + assets/xml/objects/object_stk.xml | 110 ++ assets/xml/objects/object_stk2.xml | 86 + assets/xml/objects/object_stk3.xml | 11 + assets/xml/objects/object_stream.xml | 6 + assets/xml/objects/object_syokudai.xml | 12 + assets/xml/objects/object_syoten.xml | 34 + assets/xml/objects/object_tab.xml | 62 + assets/xml/objects/object_taisou.xml | 12 + .../xml/objects/object_takaraya_objects.xml | 9 + assets/xml/objects/object_tanron1.xml | 6 + assets/xml/objects/object_tanron2.xml | 17 + assets/xml/objects/object_tanron3.xml | 17 + assets/xml/objects/object_tanron4.xml | 24 + assets/xml/objects/object_tanron5.xml | 17 + assets/xml/objects/object_taru.xml | 12 + assets/xml/objects/object_test3.xml | 68 + assets/xml/objects/object_thiefbird.xml | 66 + assets/xml/objects/object_tite.xml | 50 + assets/xml/objects/object_tk.xml | 63 + assets/xml/objects/object_tl.xml | 61 + assets/xml/objects/object_tokei_step.xml | 8 + assets/xml/objects/object_tokei_tobira.xml | 12 + assets/xml/objects/object_tokei_turret.xml | 17 + assets/xml/objects/object_toryo.xml | 53 + assets/xml/objects/object_trap.xml | 11 + assets/xml/objects/object_tree.xml | 9 + assets/xml/objects/object_tro.xml | 14 + assets/xml/objects/object_trt.xml | 94 ++ assets/xml/objects/object_tru.xml | 106 ++ assets/xml/objects/object_tsn.xml | 53 + assets/xml/objects/object_tsubo.xml | 9 + assets/xml/objects/object_twig.xml | 13 + assets/xml/objects/object_uch.xml | 46 + assets/xml/objects/object_um.xml | 105 ++ assets/xml/objects/object_umajump.xml | 9 + assets/xml/objects/object_utubo.xml | 42 + assets/xml/objects/object_visiblock.xml | 8 + assets/xml/objects/object_vm.xml | 30 + assets/xml/objects/object_wallmaster.xml | 63 + assets/xml/objects/object_warp1.xml | 59 + assets/xml/objects/object_warp_uzu.xml | 10 + assets/xml/objects/object_water_effect.xml | 26 + assets/xml/objects/object_wdhand.xml | 28 + assets/xml/objects/object_wdor01.xml | 7 + assets/xml/objects/object_wdor02.xml | 7 + assets/xml/objects/object_wdor03.xml | 7 + assets/xml/objects/object_wdor04.xml | 7 + assets/xml/objects/object_wdor05.xml | 7 + assets/xml/objects/object_wf.xml | 108 ++ assets/xml/objects/object_wiz.xml | 102 ++ assets/xml/objects/object_wood02.xml | 36 + assets/xml/objects/object_yabusame_point.xml | 6 + assets/xml/objects/object_yado_obj.xml | 11 + assets/xml/objects/object_yb.xml | 57 + assets/xml/objects/object_yukimura_obj.xml | 16 + assets/xml/objects/object_yukiyama.xml | 16 + assets/xml/objects/object_zg.xml | 8 + assets/xml/objects/object_zl1.xml | 90 ++ assets/xml/objects/object_zl4.xml | 125 ++ assets/xml/objects/object_zm.xml | 63 + assets/xml/objects/object_zo.xml | 76 + assets/xml/objects/object_zob.xml | 73 + assets/xml/objects/object_zod.xml | 50 + assets/xml/objects/object_zog.xml | 107 ++ assets/xml/objects/object_zoraband.xml | 10 + assets/xml/objects/object_zoraegg.xml | 33 + assets/xml/objects/object_zos.xml | 66 + assets/xml/objects/object_zov.xml | 79 + include/z64animation.h | 45 + spec | 1396 ++++++++++------ src/boot_O2_g3/idle.c | 1 + src/buffers/gfxpools.c | 3 + src/buffers/gfxstack.c | 3 + src/buffers/{gfxbuffers.c => gfxyield.c} | 4 - 471 files changed, 18843 insertions(+), 486 deletions(-) create mode 100644 assets/xml/objects/gameplay_dangeon_keep.xml create mode 100644 assets/xml/objects/gameplay_field_keep.xml create mode 100644 assets/xml/objects/gameplay_keep.xml create mode 100644 assets/xml/objects/object_ah.xml create mode 100644 assets/xml/objects/object_ahg.xml create mode 100644 assets/xml/objects/object_al.xml create mode 100644 assets/xml/objects/object_am.xml create mode 100644 assets/xml/objects/object_an1.xml create mode 100644 assets/xml/objects/object_an2.xml create mode 100644 assets/xml/objects/object_an3.xml create mode 100644 assets/xml/objects/object_an4.xml create mode 100644 assets/xml/objects/object_and.xml create mode 100644 assets/xml/objects/object_ani.xml create mode 100644 assets/xml/objects/object_aob.xml create mode 100644 assets/xml/objects/object_astr_obj.xml create mode 100644 assets/xml/objects/object_az.xml create mode 100644 assets/xml/objects/object_b_heart.xml create mode 100644 assets/xml/objects/object_bai.xml create mode 100644 assets/xml/objects/object_bal.xml create mode 100644 assets/xml/objects/object_bat.xml create mode 100644 assets/xml/objects/object_bb.xml create mode 100644 assets/xml/objects/object_bba.xml create mode 100644 assets/xml/objects/object_bdoor.xml create mode 100644 assets/xml/objects/object_bee.xml create mode 100644 assets/xml/objects/object_bg.xml create mode 100644 assets/xml/objects/object_bh.xml create mode 100644 assets/xml/objects/object_big_fwall.xml create mode 100644 assets/xml/objects/object_bigicicle.xml create mode 100644 assets/xml/objects/object_bigokuta.xml create mode 100644 assets/xml/objects/object_bigpo.xml create mode 100644 assets/xml/objects/object_bigslime.xml create mode 100644 assets/xml/objects/object_bji.xml create mode 100644 assets/xml/objects/object_bjt.xml create mode 100644 assets/xml/objects/object_bob.xml create mode 100644 assets/xml/objects/object_boj.xml create mode 100644 assets/xml/objects/object_bombf.xml create mode 100644 assets/xml/objects/object_bombiwa.xml create mode 100644 assets/xml/objects/object_boss01.xml create mode 100644 assets/xml/objects/object_boss02.xml create mode 100644 assets/xml/objects/object_boss03.xml create mode 100644 assets/xml/objects/object_boss04.xml create mode 100644 assets/xml/objects/object_boss05.xml create mode 100644 assets/xml/objects/object_boss07.xml create mode 100644 assets/xml/objects/object_boss_hakugin.xml create mode 100644 assets/xml/objects/object_botihasira.xml create mode 100644 assets/xml/objects/object_box.xml create mode 100644 assets/xml/objects/object_boyo.xml create mode 100644 assets/xml/objects/object_bsb.xml create mode 100644 assets/xml/objects/object_bsmask.xml create mode 100644 assets/xml/objects/object_bubble.xml create mode 100644 assets/xml/objects/object_cha.xml create mode 100644 assets/xml/objects/object_cne.xml create mode 100644 assets/xml/objects/object_comb.xml create mode 100644 assets/xml/objects/object_cow.xml create mode 100644 assets/xml/objects/object_crace_object.xml create mode 100644 assets/xml/objects/object_crow.xml create mode 100644 assets/xml/objects/object_cs.xml create mode 100644 assets/xml/objects/object_ctower_rot.xml create mode 100644 assets/xml/objects/object_d_hsblock.xml create mode 100644 assets/xml/objects/object_d_lift.xml create mode 100644 assets/xml/objects/object_dai.xml create mode 100644 assets/xml/objects/object_daiku.xml create mode 100644 assets/xml/objects/object_danpei_object.xml create mode 100644 assets/xml/objects/object_dblue_object.xml create mode 100644 assets/xml/objects/object_death.xml create mode 100644 assets/xml/objects/object_dekubaba.xml create mode 100644 assets/xml/objects/object_dekucity_ana_obj.xml create mode 100644 assets/xml/objects/object_dekucity_obj.xml create mode 100644 assets/xml/objects/object_dekunuts.xml create mode 100644 assets/xml/objects/object_delf.xml create mode 100644 assets/xml/objects/object_dhouse.xml create mode 100644 assets/xml/objects/object_dinofos.xml create mode 100644 assets/xml/objects/object_dkjail_obj.xml create mode 100644 assets/xml/objects/object_dmask.xml create mode 100644 assets/xml/objects/object_dnk.xml create mode 100644 assets/xml/objects/object_dno.xml create mode 100644 assets/xml/objects/object_dnp.xml create mode 100644 assets/xml/objects/object_dnq.xml create mode 100644 assets/xml/objects/object_dns.xml create mode 100644 assets/xml/objects/object_dnt.xml create mode 100644 assets/xml/objects/object_dodongo.xml create mode 100644 assets/xml/objects/object_dog.xml create mode 100644 assets/xml/objects/object_dor01.xml create mode 100644 assets/xml/objects/object_dor02.xml create mode 100644 assets/xml/objects/object_dor03.xml create mode 100644 assets/xml/objects/object_dor04.xml create mode 100644 assets/xml/objects/object_dora.xml create mode 100644 assets/xml/objects/object_driftice.xml create mode 100644 assets/xml/objects/object_drs.xml create mode 100644 assets/xml/objects/object_ds2.xml create mode 100644 assets/xml/objects/object_ds2n.xml create mode 100644 assets/xml/objects/object_dt.xml create mode 100644 assets/xml/objects/object_dy_obj.xml create mode 100644 assets/xml/objects/object_efc_star_field.xml create mode 100644 assets/xml/objects/object_efc_tw.xml create mode 100644 assets/xml/objects/object_eg.xml create mode 100644 assets/xml/objects/object_ending_obj.xml create mode 100644 assets/xml/objects/object_f40_obj.xml create mode 100644 assets/xml/objects/object_f40_switch.xml create mode 100644 assets/xml/objects/object_f52_obj.xml create mode 100644 assets/xml/objects/object_f53_obj.xml create mode 100644 assets/xml/objects/object_fall.xml create mode 100644 assets/xml/objects/object_fall2.xml create mode 100644 assets/xml/objects/object_famos.xml create mode 100644 assets/xml/objects/object_fb.xml create mode 100644 assets/xml/objects/object_firefly.xml create mode 100644 assets/xml/objects/object_fish.xml create mode 100644 assets/xml/objects/object_flowerpot.xml create mode 100644 assets/xml/objects/object_fr.xml create mode 100644 assets/xml/objects/object_fsn.xml create mode 100644 assets/xml/objects/object_fu.xml create mode 100644 assets/xml/objects/object_fu_kaiten.xml create mode 100644 assets/xml/objects/object_fu_mato.xml create mode 100644 assets/xml/objects/object_funen.xml create mode 100644 assets/xml/objects/object_fusen.xml create mode 100644 assets/xml/objects/object_fwall.xml create mode 100644 assets/xml/objects/object_fz.xml create mode 100644 assets/xml/objects/object_ge1.xml create mode 100644 assets/xml/objects/object_geldb.xml create mode 100644 assets/xml/objects/object_gg.xml create mode 100644 assets/xml/objects/object_ghaka.xml create mode 100644 assets/xml/objects/object_gi_arrow.xml create mode 100644 assets/xml/objects/object_gi_arrowcase.xml create mode 100644 assets/xml/objects/object_gi_bean.xml create mode 100644 assets/xml/objects/object_gi_bigbomb.xml create mode 100644 assets/xml/objects/object_gi_bomb_1.xml create mode 100644 assets/xml/objects/object_gi_bomb_2.xml create mode 100644 assets/xml/objects/object_gi_bombpouch.xml create mode 100644 assets/xml/objects/object_gi_bosskey.xml create mode 100644 assets/xml/objects/object_gi_bottle.xml create mode 100644 assets/xml/objects/object_gi_bottle_04.xml create mode 100644 assets/xml/objects/object_gi_bottle_15.xml create mode 100644 assets/xml/objects/object_gi_bottle_16.xml create mode 100644 assets/xml/objects/object_gi_bottle_21.xml create mode 100644 assets/xml/objects/object_gi_bottle_22.xml create mode 100644 assets/xml/objects/object_gi_bottle_red.xml create mode 100644 assets/xml/objects/object_gi_bow.xml create mode 100644 assets/xml/objects/object_gi_camera.xml create mode 100644 assets/xml/objects/object_gi_compass.xml create mode 100644 assets/xml/objects/object_gi_fieldmap.xml create mode 100644 assets/xml/objects/object_gi_fish.xml create mode 100644 assets/xml/objects/object_gi_ghost.xml create mode 100644 assets/xml/objects/object_gi_glasses.xml create mode 100644 assets/xml/objects/object_gi_gold_dust.xml create mode 100644 assets/xml/objects/object_gi_golonmask.xml create mode 100644 assets/xml/objects/object_gi_heart.xml create mode 100644 assets/xml/objects/object_gi_hearts.xml create mode 100644 assets/xml/objects/object_gi_hookshot.xml create mode 100644 assets/xml/objects/object_gi_insect.xml create mode 100644 assets/xml/objects/object_gi_key.xml create mode 100644 assets/xml/objects/object_gi_ki_tan_mask.xml create mode 100644 assets/xml/objects/object_gi_liquid.xml create mode 100644 assets/xml/objects/object_gi_loach.xml create mode 100644 assets/xml/objects/object_gi_longsword.xml create mode 100644 assets/xml/objects/object_gi_m_arrow.xml create mode 100644 assets/xml/objects/object_gi_magicmushroom.xml create mode 100644 assets/xml/objects/object_gi_magicpot.xml create mode 100644 assets/xml/objects/object_gi_map.xml create mode 100644 assets/xml/objects/object_gi_mask03.xml create mode 100644 assets/xml/objects/object_gi_mask05.xml create mode 100644 assets/xml/objects/object_gi_mask06.xml create mode 100644 assets/xml/objects/object_gi_mask09.xml create mode 100644 assets/xml/objects/object_gi_mask10.xml create mode 100644 assets/xml/objects/object_gi_mask11.xml create mode 100644 assets/xml/objects/object_gi_mask12.xml create mode 100644 assets/xml/objects/object_gi_mask13.xml create mode 100644 assets/xml/objects/object_gi_mask14.xml create mode 100644 assets/xml/objects/object_gi_mask15.xml create mode 100644 assets/xml/objects/object_gi_mask16.xml create mode 100644 assets/xml/objects/object_gi_mask17.xml create mode 100644 assets/xml/objects/object_gi_mask18.xml create mode 100644 assets/xml/objects/object_gi_mask20.xml create mode 100644 assets/xml/objects/object_gi_mask21.xml create mode 100644 assets/xml/objects/object_gi_mask22.xml create mode 100644 assets/xml/objects/object_gi_mask23.xml create mode 100644 assets/xml/objects/object_gi_melody.xml create mode 100644 assets/xml/objects/object_gi_milk.xml create mode 100644 assets/xml/objects/object_gi_mssa.xml create mode 100644 assets/xml/objects/object_gi_nuts.xml create mode 100644 assets/xml/objects/object_gi_nutsmask.xml create mode 100644 assets/xml/objects/object_gi_ocarina.xml create mode 100644 assets/xml/objects/object_gi_purse.xml create mode 100644 assets/xml/objects/object_gi_rabit_mask.xml create mode 100644 assets/xml/objects/object_gi_reserve00.xml create mode 100644 assets/xml/objects/object_gi_reserve01.xml create mode 100644 assets/xml/objects/object_gi_reserve_b_00.xml create mode 100644 assets/xml/objects/object_gi_reserve_b_01.xml create mode 100644 assets/xml/objects/object_gi_reserve_c_00.xml create mode 100644 assets/xml/objects/object_gi_reserve_c_01.xml create mode 100644 assets/xml/objects/object_gi_rupy.xml create mode 100644 assets/xml/objects/object_gi_schedule.xml create mode 100644 assets/xml/objects/object_gi_seahorse.xml create mode 100644 assets/xml/objects/object_gi_shield_2.xml create mode 100644 assets/xml/objects/object_gi_shield_3.xml create mode 100644 assets/xml/objects/object_gi_soldout.xml create mode 100644 assets/xml/objects/object_gi_soul.xml create mode 100644 assets/xml/objects/object_gi_stick.xml create mode 100644 assets/xml/objects/object_gi_stonemask.xml create mode 100644 assets/xml/objects/object_gi_sutaru.xml create mode 100644 assets/xml/objects/object_gi_sword_1.xml create mode 100644 assets/xml/objects/object_gi_sword_2.xml create mode 100644 assets/xml/objects/object_gi_sword_3.xml create mode 100644 assets/xml/objects/object_gi_sword_4.xml create mode 100644 assets/xml/objects/object_gi_truth_mask.xml create mode 100644 assets/xml/objects/object_gi_zoramask.xml create mode 100644 assets/xml/objects/object_giant.xml create mode 100644 assets/xml/objects/object_gk.xml create mode 100644 assets/xml/objects/object_gla.xml create mode 100644 assets/xml/objects/object_gm.xml create mode 100644 assets/xml/objects/object_gmo.xml create mode 100644 assets/xml/objects/object_goroiwa.xml create mode 100644 assets/xml/objects/object_goronswitch.xml create mode 100644 assets/xml/objects/object_grasshopper.xml create mode 100644 assets/xml/objects/object_gs.xml create mode 100644 assets/xml/objects/object_ha.xml create mode 100644 assets/xml/objects/object_haka_obj.xml create mode 100644 assets/xml/objects/object_hakaisi.xml create mode 100644 assets/xml/objects/object_hakugin_demo.xml create mode 100644 assets/xml/objects/object_hakugin_obj.xml create mode 100644 assets/xml/objects/object_hana.xml create mode 100644 assets/xml/objects/object_hanareyama_obj.xml create mode 100644 assets/xml/objects/object_harfgibud.xml create mode 100644 assets/xml/objects/object_hariko.xml create mode 100644 assets/xml/objects/object_hata.xml create mode 100644 assets/xml/objects/object_hgdoor.xml create mode 100644 assets/xml/objects/object_hintnuts.xml create mode 100644 assets/xml/objects/object_horse_game_check.xml create mode 100644 assets/xml/objects/object_horse_link_child.xml create mode 100644 assets/xml/objects/object_hs.xml create mode 100644 assets/xml/objects/object_hsstump.xml create mode 100644 assets/xml/objects/object_hunsui.xml create mode 100644 assets/xml/objects/object_ice_block.xml create mode 100644 assets/xml/objects/object_icefloe.xml create mode 100644 assets/xml/objects/object_icicle.xml create mode 100644 assets/xml/objects/object_ik.xml create mode 100644 assets/xml/objects/object_ikana_obj.xml create mode 100644 assets/xml/objects/object_ikn_demo.xml create mode 100644 assets/xml/objects/object_ikninside_obj.xml create mode 100644 assets/xml/objects/object_iknv_obj.xml create mode 100644 assets/xml/objects/object_in.xml create mode 100644 assets/xml/objects/object_in2.xml create mode 100644 assets/xml/objects/object_inibs_object.xml create mode 100644 assets/xml/objects/object_ishi.xml create mode 100644 assets/xml/objects/object_jg.xml create mode 100644 assets/xml/objects/object_js.xml create mode 100644 assets/xml/objects/object_jso.xml create mode 100644 assets/xml/objects/object_ka.xml create mode 100644 assets/xml/objects/object_kaizoku_obj.xml create mode 100644 assets/xml/objects/object_kamejima.xml create mode 100644 assets/xml/objects/object_kanban.xml create mode 100644 assets/xml/objects/object_kbt.xml create mode 100644 assets/xml/objects/object_keikoku_demo.xml create mode 100644 assets/xml/objects/object_keikoku_obj.xml create mode 100644 assets/xml/objects/object_kepn_koya.xml create mode 100644 assets/xml/objects/object_kgy.xml create mode 100644 assets/xml/objects/object_kibako.xml create mode 100644 assets/xml/objects/object_kibako2.xml create mode 100644 assets/xml/objects/object_kin2_obj.xml create mode 100644 assets/xml/objects/object_kinsta1_obj.xml create mode 100644 assets/xml/objects/object_kinsta2_obj.xml create mode 100644 assets/xml/objects/object_kitan.xml create mode 100644 assets/xml/objects/object_knight.xml create mode 100644 assets/xml/objects/object_kujiya.xml create mode 100644 assets/xml/objects/object_kumo30.xml create mode 100644 assets/xml/objects/object_kusa.xml create mode 100644 assets/xml/objects/object_kz.xml create mode 100644 assets/xml/objects/object_kzsaku.xml create mode 100644 assets/xml/objects/object_ladder.xml create mode 100644 assets/xml/objects/object_last_obj.xml create mode 100644 assets/xml/objects/object_lastday.xml create mode 100644 assets/xml/objects/object_lbfshot.xml create mode 100644 assets/xml/objects/object_lightblock.xml create mode 100644 assets/xml/objects/object_lightswitch.xml create mode 100644 assets/xml/objects/object_link_boy.xml create mode 100644 assets/xml/objects/object_link_child.xml create mode 100644 assets/xml/objects/object_link_goron.xml create mode 100644 assets/xml/objects/object_link_nuts.xml create mode 100644 assets/xml/objects/object_link_zora.xml create mode 100644 assets/xml/objects/object_lodmoon.xml create mode 100644 assets/xml/objects/object_lotus.xml create mode 100644 assets/xml/objects/object_ma1.xml create mode 100644 assets/xml/objects/object_ma2.xml create mode 100644 assets/xml/objects/object_mag.xml create mode 100644 assets/xml/objects/object_mamenoki.xml create mode 100644 assets/xml/objects/object_market_obj.xml create mode 100644 assets/xml/objects/object_maruta.xml create mode 100644 assets/xml/objects/object_mask_bakuretu.xml create mode 100644 assets/xml/objects/object_mask_bigelf.xml create mode 100644 assets/xml/objects/object_mask_boy.xml create mode 100644 assets/xml/objects/object_mask_bree.xml create mode 100644 assets/xml/objects/object_mask_bu_san.xml create mode 100644 assets/xml/objects/object_mask_dancer.xml create mode 100644 assets/xml/objects/object_mask_gero.xml create mode 100644 assets/xml/objects/object_mask_gibudo.xml create mode 100644 assets/xml/objects/object_mask_goron.xml create mode 100644 assets/xml/objects/object_mask_json.xml create mode 100644 assets/xml/objects/object_mask_kerfay.xml create mode 100644 assets/xml/objects/object_mask_ki_tan.xml create mode 100644 assets/xml/objects/object_mask_kyojin.xml create mode 100644 assets/xml/objects/object_mask_meoto.xml create mode 100644 assets/xml/objects/object_mask_nuts.xml create mode 100644 assets/xml/objects/object_mask_posthat.xml create mode 100644 assets/xml/objects/object_mask_rabit.xml create mode 100644 assets/xml/objects/object_mask_romerny.xml create mode 100644 assets/xml/objects/object_mask_skj.xml create mode 100644 assets/xml/objects/object_mask_stone.xml create mode 100644 assets/xml/objects/object_mask_truth.xml create mode 100644 assets/xml/objects/object_mask_yofukasi.xml create mode 100644 assets/xml/objects/object_mask_zacho.xml create mode 100644 assets/xml/objects/object_mask_zora.xml create mode 100644 assets/xml/objects/object_mastergolon.xml create mode 100644 assets/xml/objects/object_masterzoora.xml create mode 100644 assets/xml/objects/object_mbar_obj.xml create mode 100644 assets/xml/objects/object_meganeana_obj.xml create mode 100644 assets/xml/objects/object_milkbar.xml create mode 100644 assets/xml/objects/object_mir_ray.xml create mode 100644 assets/xml/objects/object_mk.xml create mode 100644 assets/xml/objects/object_mkk.xml create mode 100644 assets/xml/objects/object_mm.xml create mode 100644 assets/xml/objects/object_mnk.xml create mode 100644 assets/xml/objects/object_moonend.xml create mode 100644 assets/xml/objects/object_moonston.xml create mode 100644 assets/xml/objects/object_ms.xml create mode 100644 assets/xml/objects/object_msmo.xml create mode 100644 assets/xml/objects/object_mtoride.xml create mode 100644 assets/xml/objects/object_mu.xml create mode 100644 assets/xml/objects/object_nb.xml create mode 100644 assets/xml/objects/object_niw.xml create mode 100644 assets/xml/objects/object_nnh.xml create mode 100644 assets/xml/objects/object_numa_obj.xml create mode 100644 assets/xml/objects/object_nwc.xml create mode 100644 assets/xml/objects/object_ny.xml create mode 100644 assets/xml/objects/object_oF1d_map.xml create mode 100644 assets/xml/objects/object_ob.xml create mode 100644 assets/xml/objects/object_obj_chan.xml create mode 100644 assets/xml/objects/object_obj_danpeilift.xml create mode 100644 assets/xml/objects/object_obj_dinner.xml create mode 100644 assets/xml/objects/object_obj_milk_bin.xml create mode 100644 assets/xml/objects/object_obj_tokeidai.xml create mode 100644 assets/xml/objects/object_obj_usiyane.xml create mode 100644 assets/xml/objects/object_obj_yasi.xml create mode 100644 assets/xml/objects/object_okuta.xml create mode 100644 assets/xml/objects/object_omoya_obj.xml create mode 100644 assets/xml/objects/object_open_obj.xml create mode 100644 assets/xml/objects/object_os_anime.xml create mode 100644 assets/xml/objects/object_osn.xml create mode 100644 assets/xml/objects/object_ot.xml create mode 100644 assets/xml/objects/object_owl.xml create mode 100644 assets/xml/objects/object_oyu.xml create mode 100644 assets/xml/objects/object_pamera.xml create mode 100644 assets/xml/objects/object_ph.xml create mode 100644 assets/xml/objects/object_po.xml create mode 100644 assets/xml/objects/object_po_composer.xml create mode 100644 assets/xml/objects/object_po_fusen.xml create mode 100644 assets/xml/objects/object_po_sisters.xml create mode 100644 assets/xml/objects/object_posthouse_obj.xml create mode 100644 assets/xml/objects/object_pp.xml create mode 100644 assets/xml/objects/object_pr.xml create mode 100644 assets/xml/objects/object_ps.xml create mode 100644 assets/xml/objects/object_pst.xml create mode 100644 assets/xml/objects/object_racetsubo.xml create mode 100644 assets/xml/objects/object_raf.xml create mode 100644 assets/xml/objects/object_raillift.xml create mode 100644 assets/xml/objects/object_random_obj.xml create mode 100644 assets/xml/objects/object_rat.xml create mode 100644 assets/xml/objects/object_rb.xml create mode 100644 assets/xml/objects/object_rd.xml create mode 100644 assets/xml/objects/object_redead_obj.xml create mode 100644 assets/xml/objects/object_rotlift.xml create mode 100644 assets/xml/objects/object_rr.xml create mode 100644 assets/xml/objects/object_rs.xml create mode 100644 assets/xml/objects/object_ru2.xml create mode 100644 assets/xml/objects/object_rz.xml create mode 100644 assets/xml/objects/object_sb.xml create mode 100644 assets/xml/objects/object_sdn.xml create mode 100644 assets/xml/objects/object_secom_obj.xml create mode 100644 assets/xml/objects/object_sek.xml create mode 100644 assets/xml/objects/object_sekihig.xml create mode 100644 assets/xml/objects/object_sekihil.xml create mode 100644 assets/xml/objects/object_sekihin.xml create mode 100644 assets/xml/objects/object_sekihiz.xml create mode 100644 assets/xml/objects/object_shn.xml create mode 100644 assets/xml/objects/object_sichitai_obj.xml create mode 100644 assets/xml/objects/object_sinkai_kabe.xml create mode 100644 assets/xml/objects/object_skb.xml create mode 100644 assets/xml/objects/object_slime.xml create mode 100644 assets/xml/objects/object_smtower.xml create mode 100644 assets/xml/objects/object_snowman.xml create mode 100644 assets/xml/objects/object_snowwd.xml create mode 100644 assets/xml/objects/object_spdweb.xml create mode 100644 assets/xml/objects/object_spidertent.xml create mode 100644 assets/xml/objects/object_spinyroll.xml create mode 100644 assets/xml/objects/object_spot11_obj.xml create mode 100644 assets/xml/objects/object_ssh.xml create mode 100644 assets/xml/objects/object_st.xml create mode 100644 assets/xml/objects/object_sth.xml create mode 100644 assets/xml/objects/object_stk.xml create mode 100644 assets/xml/objects/object_stk2.xml create mode 100644 assets/xml/objects/object_stk3.xml create mode 100644 assets/xml/objects/object_stream.xml create mode 100644 assets/xml/objects/object_syokudai.xml create mode 100644 assets/xml/objects/object_syoten.xml create mode 100644 assets/xml/objects/object_tab.xml create mode 100644 assets/xml/objects/object_taisou.xml create mode 100644 assets/xml/objects/object_takaraya_objects.xml create mode 100644 assets/xml/objects/object_tanron1.xml create mode 100644 assets/xml/objects/object_tanron2.xml create mode 100644 assets/xml/objects/object_tanron3.xml create mode 100644 assets/xml/objects/object_tanron4.xml create mode 100644 assets/xml/objects/object_tanron5.xml create mode 100644 assets/xml/objects/object_taru.xml create mode 100644 assets/xml/objects/object_test3.xml create mode 100644 assets/xml/objects/object_thiefbird.xml create mode 100644 assets/xml/objects/object_tite.xml create mode 100644 assets/xml/objects/object_tk.xml create mode 100644 assets/xml/objects/object_tl.xml create mode 100644 assets/xml/objects/object_tokei_step.xml create mode 100644 assets/xml/objects/object_tokei_tobira.xml create mode 100644 assets/xml/objects/object_tokei_turret.xml create mode 100644 assets/xml/objects/object_toryo.xml create mode 100644 assets/xml/objects/object_trap.xml create mode 100644 assets/xml/objects/object_tree.xml create mode 100644 assets/xml/objects/object_tro.xml create mode 100644 assets/xml/objects/object_trt.xml create mode 100644 assets/xml/objects/object_tru.xml create mode 100644 assets/xml/objects/object_tsn.xml create mode 100644 assets/xml/objects/object_tsubo.xml create mode 100644 assets/xml/objects/object_twig.xml create mode 100644 assets/xml/objects/object_uch.xml create mode 100644 assets/xml/objects/object_um.xml create mode 100644 assets/xml/objects/object_umajump.xml create mode 100644 assets/xml/objects/object_utubo.xml create mode 100644 assets/xml/objects/object_visiblock.xml create mode 100644 assets/xml/objects/object_vm.xml create mode 100644 assets/xml/objects/object_wallmaster.xml create mode 100644 assets/xml/objects/object_warp1.xml create mode 100644 assets/xml/objects/object_warp_uzu.xml create mode 100644 assets/xml/objects/object_water_effect.xml create mode 100644 assets/xml/objects/object_wdhand.xml create mode 100644 assets/xml/objects/object_wdor01.xml create mode 100644 assets/xml/objects/object_wdor02.xml create mode 100644 assets/xml/objects/object_wdor03.xml create mode 100644 assets/xml/objects/object_wdor04.xml create mode 100644 assets/xml/objects/object_wdor05.xml create mode 100644 assets/xml/objects/object_wf.xml create mode 100644 assets/xml/objects/object_wiz.xml create mode 100644 assets/xml/objects/object_wood02.xml create mode 100644 assets/xml/objects/object_yabusame_point.xml create mode 100644 assets/xml/objects/object_yado_obj.xml create mode 100644 assets/xml/objects/object_yb.xml create mode 100644 assets/xml/objects/object_yukimura_obj.xml create mode 100644 assets/xml/objects/object_yukiyama.xml create mode 100644 assets/xml/objects/object_zg.xml create mode 100644 assets/xml/objects/object_zl1.xml create mode 100644 assets/xml/objects/object_zl4.xml create mode 100644 assets/xml/objects/object_zm.xml create mode 100644 assets/xml/objects/object_zo.xml create mode 100644 assets/xml/objects/object_zob.xml create mode 100644 assets/xml/objects/object_zod.xml create mode 100644 assets/xml/objects/object_zog.xml create mode 100644 assets/xml/objects/object_zoraband.xml create mode 100644 assets/xml/objects/object_zoraegg.xml create mode 100644 assets/xml/objects/object_zos.xml create mode 100644 assets/xml/objects/object_zov.xml create mode 100644 src/buffers/gfxpools.c create mode 100644 src/buffers/gfxstack.c rename src/buffers/{gfxbuffers.c => gfxyield.c} (56%) diff --git a/Makefile b/Makefile index a65a8713d2..2578a59301 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,7 @@ OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump IINC := -Iinclude -Isrc -Iassets -Ibuild -I. + ifeq ($(KEEP_MDEBUG),0) RM_MDEBUG = $(OBJCOPY) --remove-section .mdebug $@ else @@ -116,25 +117,26 @@ $(shell mkdir -p asm data) SRC_DIRS := $(shell find src -type d) ASM_DIRS := $(shell find asm -type d -not -path "asm/non_matchings*") $(shell find data -type d) -ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*") -BASEROM_DIRS := $(shell find baserom -type d 2>/dev/null) -ASSET_C_FILES := $(shell find assets/ -type f -name "*.c") -ASSET_FILES_BIN := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.bin)) -ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_BIN:.bin=.bin.inc.c),build/$f) ## Assets binaries (PNGs, JPGs, etc) +ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*") + +ASSET_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml)) +ASSET_FILES_BIN := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.bin)) +ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_XML:.xml=.c),$f) \ + $(foreach f,$(ASSET_FILES_BIN:.bin=.bin.inc.c),build/$f) + TEXTURE_FILES_PNG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.png)) TEXTURE_FILES_JPG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.jpg)) TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),build/$f) \ $(foreach f,$(TEXTURE_FILES_JPG:.jpg=.jpg.inc.c),build/$f) \ -C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) +C_FILES := $(foreach dir,$(SRC_DIRS) $(ASSET_BIN_DIRS),$(wildcard $(dir)/*.c)) S_FILES := $(shell grep -F "build/asm" spec | sed 's/.*build\/// ; s/\.o\".*/.s/') \ $(shell grep -F "build/data" spec | sed 's/.*build\/// ; s/\.o\".*/.s/') O_FILES := $(foreach f,$(S_FILES:.s=.o),build/$f) \ - $(foreach f,$(wildcard baserom/*),build/$f.o) \ $(foreach f,$(C_FILES:.c=.o),build/$f) \ - $(foreach f,$(ASSET_C_FILES:.c=.o),build/$f) + $(foreach f,$(wildcard baserom/*),build/$f.o) # Automatic dependency files # (Only asm_processor dependencies are handled for now) @@ -211,7 +213,7 @@ $(ROM): $(ELF) $(ROMC): uncompressed python3 tools/z64compress_wrapper.py --mb 32 --matching --threads $(N_THREADS) $(ROM) $@ $(ELF) build/$(SPEC) -$(ELF): $(TEXTURE_FILES_OUT) $(OVERLAY_RELOC_FILES) $(O_FILES) build/ldscript.txt build/undefined_syms.txt +$(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) build/ldscript.txt build/undefined_syms.txt $(LD) -T build/undefined_syms.txt -T build/ldscript.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map build/mm.map -o $@ @@ -254,10 +256,6 @@ init: $(MAKE) all $(MAKE) diff-init -build/assets/%.o: assets/%.c - $(CC) -I build/ -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< - $(RM_MDEBUG) - #### Various Recipes #### build/undefined_syms.txt: undefined_syms.txt @@ -267,12 +265,17 @@ build/ldscript.txt: $(SPEC) $(CPP) $(CPPFLAGS) $< > build/spec $(MKLDSCRIPT) build/spec $@ -build/baserom/%.o: baserom/% - $(OBJCOPY) -I binary -O elf32-big $< $@ - build/asm/%.o: asm/%.s $(AS) $(ASFLAGS) $< -o $@ +build/assets/%.o: assets/%.c + $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< + $(OBJCOPY) -O binary $@ $@.bin + $(RM_MDEBUG) + +build/baserom/%.o: baserom/% + $(OBJCOPY) -I binary -O elf32-big $< $@ + build/data/%.o: data/%.s iconv --from UTF-8 --to EUC-JP $< | $(AS) $(ASFLAGS) -o $@ @@ -307,8 +310,9 @@ build/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c $(RM_MDEBUG) # Build C files from assets + build/%.inc.c: %.png - $(ZAPD) btex -eh -tt $(lastword ,$(subst ., ,$(basename $<))) -i $< -o $@ + $(ZAPD) btex -eh -tt $(subst .,,$(suffix $*)) -i $< -o $@ build/assets/%.bin.inc.c: assets/%.bin $(ZAPD) bblb -eh -i $< -o $@ diff --git a/assets/xml/objects/gameplay_dangeon_keep.xml b/assets/xml/objects/gameplay_dangeon_keep.xml new file mode 100644 index 0000000000..19fabad2b3 --- /dev/null +++ b/assets/xml/objects/gameplay_dangeon_keep.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/gameplay_field_keep.xml b/assets/xml/objects/gameplay_field_keep.xml new file mode 100644 index 0000000000..537d596a6b --- /dev/null +++ b/assets/xml/objects/gameplay_field_keep.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml new file mode 100644 index 0000000000..892749e732 --- /dev/null +++ b/assets/xml/objects/gameplay_keep.xml @@ -0,0 +1,1415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ah.xml b/assets/xml/objects/object_ah.xml new file mode 100644 index 0000000000..296347dacb --- /dev/null +++ b/assets/xml/objects/object_ah.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ahg.xml b/assets/xml/objects/object_ahg.xml new file mode 100644 index 0000000000..c636f0baa3 --- /dev/null +++ b/assets/xml/objects/object_ahg.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_al.xml b/assets/xml/objects/object_al.xml new file mode 100644 index 0000000000..7a2ff1a52a --- /dev/null +++ b/assets/xml/objects/object_al.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_am.xml b/assets/xml/objects/object_am.xml new file mode 100644 index 0000000000..c135b7b0b6 --- /dev/null +++ b/assets/xml/objects/object_am.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an1.xml b/assets/xml/objects/object_an1.xml new file mode 100644 index 0000000000..c2ae65d8b2 --- /dev/null +++ b/assets/xml/objects/object_an1.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an2.xml b/assets/xml/objects/object_an2.xml new file mode 100644 index 0000000000..3adcc27f70 --- /dev/null +++ b/assets/xml/objects/object_an2.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an3.xml b/assets/xml/objects/object_an3.xml new file mode 100644 index 0000000000..2d94b81b79 --- /dev/null +++ b/assets/xml/objects/object_an3.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an4.xml b/assets/xml/objects/object_an4.xml new file mode 100644 index 0000000000..57088a072a --- /dev/null +++ b/assets/xml/objects/object_an4.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_and.xml b/assets/xml/objects/object_and.xml new file mode 100644 index 0000000000..269e2a73fe --- /dev/null +++ b/assets/xml/objects/object_and.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ani.xml b/assets/xml/objects/object_ani.xml new file mode 100644 index 0000000000..85fd13cecd --- /dev/null +++ b/assets/xml/objects/object_ani.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_aob.xml b/assets/xml/objects/object_aob.xml new file mode 100644 index 0000000000..f44ec32463 --- /dev/null +++ b/assets/xml/objects/object_aob.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_astr_obj.xml b/assets/xml/objects/object_astr_obj.xml new file mode 100644 index 0000000000..7a87bd61b7 --- /dev/null +++ b/assets/xml/objects/object_astr_obj.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_az.xml b/assets/xml/objects/object_az.xml new file mode 100644 index 0000000000..c192f6914f --- /dev/null +++ b/assets/xml/objects/object_az.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_b_heart.xml b/assets/xml/objects/object_b_heart.xml new file mode 100644 index 0000000000..789f05b379 --- /dev/null +++ b/assets/xml/objects/object_b_heart.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_bai.xml b/assets/xml/objects/object_bai.xml new file mode 100644 index 0000000000..ad8d8445bf --- /dev/null +++ b/assets/xml/objects/object_bai.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bal.xml b/assets/xml/objects/object_bal.xml new file mode 100644 index 0000000000..e564a4798d --- /dev/null +++ b/assets/xml/objects/object_bal.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bat.xml b/assets/xml/objects/object_bat.xml new file mode 100644 index 0000000000..35a5c158d9 --- /dev/null +++ b/assets/xml/objects/object_bat.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bb.xml b/assets/xml/objects/object_bb.xml new file mode 100644 index 0000000000..ba3e4cb94a --- /dev/null +++ b/assets/xml/objects/object_bb.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bba.xml b/assets/xml/objects/object_bba.xml new file mode 100644 index 0000000000..b172e9f770 --- /dev/null +++ b/assets/xml/objects/object_bba.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bdoor.xml b/assets/xml/objects/object_bdoor.xml new file mode 100644 index 0000000000..d74f4aa575 --- /dev/null +++ b/assets/xml/objects/object_bdoor.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bee.xml b/assets/xml/objects/object_bee.xml new file mode 100644 index 0000000000..b2c90324b0 --- /dev/null +++ b/assets/xml/objects/object_bee.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bg.xml b/assets/xml/objects/object_bg.xml new file mode 100644 index 0000000000..d623f9455a --- /dev/null +++ b/assets/xml/objects/object_bg.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bh.xml b/assets/xml/objects/object_bh.xml new file mode 100644 index 0000000000..d54e99e23c --- /dev/null +++ b/assets/xml/objects/object_bh.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_big_fwall.xml b/assets/xml/objects/object_big_fwall.xml new file mode 100644 index 0000000000..f3f51a4883 --- /dev/null +++ b/assets/xml/objects/object_big_fwall.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_bigicicle.xml b/assets/xml/objects/object_bigicicle.xml new file mode 100644 index 0000000000..3e1a7fd7eb --- /dev/null +++ b/assets/xml/objects/object_bigicicle.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigokuta.xml b/assets/xml/objects/object_bigokuta.xml new file mode 100644 index 0000000000..b6783c15d4 --- /dev/null +++ b/assets/xml/objects/object_bigokuta.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigpo.xml b/assets/xml/objects/object_bigpo.xml new file mode 100644 index 0000000000..5a930c9ac5 --- /dev/null +++ b/assets/xml/objects/object_bigpo.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigslime.xml b/assets/xml/objects/object_bigslime.xml new file mode 100644 index 0000000000..d0238adef4 --- /dev/null +++ b/assets/xml/objects/object_bigslime.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bji.xml b/assets/xml/objects/object_bji.xml new file mode 100644 index 0000000000..e8c7fe9496 --- /dev/null +++ b/assets/xml/objects/object_bji.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bjt.xml b/assets/xml/objects/object_bjt.xml new file mode 100644 index 0000000000..9f0c0edc23 --- /dev/null +++ b/assets/xml/objects/object_bjt.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bob.xml b/assets/xml/objects/object_bob.xml new file mode 100644 index 0000000000..968a838d2f --- /dev/null +++ b/assets/xml/objects/object_bob.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boj.xml b/assets/xml/objects/object_boj.xml new file mode 100644 index 0000000000..d948ff5464 --- /dev/null +++ b/assets/xml/objects/object_boj.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bombf.xml b/assets/xml/objects/object_bombf.xml new file mode 100644 index 0000000000..a0e5cdef35 --- /dev/null +++ b/assets/xml/objects/object_bombf.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_bombiwa.xml b/assets/xml/objects/object_bombiwa.xml new file mode 100644 index 0000000000..6dbcaf2b59 --- /dev/null +++ b/assets/xml/objects/object_bombiwa.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss01.xml b/assets/xml/objects/object_boss01.xml new file mode 100644 index 0000000000..a9865a0962 --- /dev/null +++ b/assets/xml/objects/object_boss01.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss02.xml b/assets/xml/objects/object_boss02.xml new file mode 100644 index 0000000000..f944de2421 --- /dev/null +++ b/assets/xml/objects/object_boss02.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss03.xml b/assets/xml/objects/object_boss03.xml new file mode 100644 index 0000000000..14d7d3498e --- /dev/null +++ b/assets/xml/objects/object_boss03.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss04.xml b/assets/xml/objects/object_boss04.xml new file mode 100644 index 0000000000..d24ad986a9 --- /dev/null +++ b/assets/xml/objects/object_boss04.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss05.xml b/assets/xml/objects/object_boss05.xml new file mode 100644 index 0000000000..ec994d8242 --- /dev/null +++ b/assets/xml/objects/object_boss05.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss07.xml b/assets/xml/objects/object_boss07.xml new file mode 100644 index 0000000000..aa0ef8c886 --- /dev/null +++ b/assets/xml/objects/object_boss07.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss_hakugin.xml b/assets/xml/objects/object_boss_hakugin.xml new file mode 100644 index 0000000000..05302db78d --- /dev/null +++ b/assets/xml/objects/object_boss_hakugin.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_botihasira.xml b/assets/xml/objects/object_botihasira.xml new file mode 100644 index 0000000000..93c59f42fb --- /dev/null +++ b/assets/xml/objects/object_botihasira.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_box.xml b/assets/xml/objects/object_box.xml new file mode 100644 index 0000000000..39d21765f7 --- /dev/null +++ b/assets/xml/objects/object_box.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boyo.xml b/assets/xml/objects/object_boyo.xml new file mode 100644 index 0000000000..0084c4825f --- /dev/null +++ b/assets/xml/objects/object_boyo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_bsb.xml b/assets/xml/objects/object_bsb.xml new file mode 100644 index 0000000000..ddaadc33d9 --- /dev/null +++ b/assets/xml/objects/object_bsb.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bsmask.xml b/assets/xml/objects/object_bsmask.xml new file mode 100644 index 0000000000..e776cde1ac --- /dev/null +++ b/assets/xml/objects/object_bsmask.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bubble.xml b/assets/xml/objects/object_bubble.xml new file mode 100644 index 0000000000..4397a017f5 --- /dev/null +++ b/assets/xml/objects/object_bubble.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_cha.xml b/assets/xml/objects/object_cha.xml new file mode 100644 index 0000000000..12835da1f6 --- /dev/null +++ b/assets/xml/objects/object_cha.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_cne.xml b/assets/xml/objects/object_cne.xml new file mode 100644 index 0000000000..72447ceec5 --- /dev/null +++ b/assets/xml/objects/object_cne.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_comb.xml b/assets/xml/objects/object_comb.xml new file mode 100644 index 0000000000..df9359acc8 --- /dev/null +++ b/assets/xml/objects/object_comb.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_cow.xml b/assets/xml/objects/object_cow.xml new file mode 100644 index 0000000000..b440573447 --- /dev/null +++ b/assets/xml/objects/object_cow.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_crace_object.xml b/assets/xml/objects/object_crace_object.xml new file mode 100644 index 0000000000..06c007989d --- /dev/null +++ b/assets/xml/objects/object_crace_object.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_crow.xml b/assets/xml/objects/object_crow.xml new file mode 100644 index 0000000000..b3b004cd7b --- /dev/null +++ b/assets/xml/objects/object_crow.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_cs.xml b/assets/xml/objects/object_cs.xml new file mode 100644 index 0000000000..d55f866caf --- /dev/null +++ b/assets/xml/objects/object_cs.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ctower_rot.xml b/assets/xml/objects/object_ctower_rot.xml new file mode 100644 index 0000000000..515b4fa65e --- /dev/null +++ b/assets/xml/objects/object_ctower_rot.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_d_hsblock.xml b/assets/xml/objects/object_d_hsblock.xml new file mode 100644 index 0000000000..e9f90c011b --- /dev/null +++ b/assets/xml/objects/object_d_hsblock.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_d_lift.xml b/assets/xml/objects/object_d_lift.xml new file mode 100644 index 0000000000..bcd707d686 --- /dev/null +++ b/assets/xml/objects/object_d_lift.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_dai.xml b/assets/xml/objects/object_dai.xml new file mode 100644 index 0000000000..c39ef9a6df --- /dev/null +++ b/assets/xml/objects/object_dai.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_daiku.xml b/assets/xml/objects/object_daiku.xml new file mode 100644 index 0000000000..0c42532ecd --- /dev/null +++ b/assets/xml/objects/object_daiku.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_danpei_object.xml b/assets/xml/objects/object_danpei_object.xml new file mode 100644 index 0000000000..3f373a8ceb --- /dev/null +++ b/assets/xml/objects/object_danpei_object.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dblue_object.xml b/assets/xml/objects/object_dblue_object.xml new file mode 100644 index 0000000000..d49b368e14 --- /dev/null +++ b/assets/xml/objects/object_dblue_object.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_death.xml b/assets/xml/objects/object_death.xml new file mode 100644 index 0000000000..2aba9582d1 --- /dev/null +++ b/assets/xml/objects/object_death.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dekubaba.xml b/assets/xml/objects/object_dekubaba.xml new file mode 100644 index 0000000000..bd59555c48 --- /dev/null +++ b/assets/xml/objects/object_dekubaba.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dekucity_ana_obj.xml b/assets/xml/objects/object_dekucity_ana_obj.xml new file mode 100644 index 0000000000..620c34a046 --- /dev/null +++ b/assets/xml/objects/object_dekucity_ana_obj.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dekucity_obj.xml b/assets/xml/objects/object_dekucity_obj.xml new file mode 100644 index 0000000000..1d680965e4 --- /dev/null +++ b/assets/xml/objects/object_dekucity_obj.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dekunuts.xml b/assets/xml/objects/object_dekunuts.xml new file mode 100644 index 0000000000..442dc756d8 --- /dev/null +++ b/assets/xml/objects/object_dekunuts.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_delf.xml b/assets/xml/objects/object_delf.xml new file mode 100644 index 0000000000..39996c0f09 --- /dev/null +++ b/assets/xml/objects/object_delf.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dhouse.xml b/assets/xml/objects/object_dhouse.xml new file mode 100644 index 0000000000..dd95b8b98f --- /dev/null +++ b/assets/xml/objects/object_dhouse.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dinofos.xml b/assets/xml/objects/object_dinofos.xml new file mode 100644 index 0000000000..83eade0dad --- /dev/null +++ b/assets/xml/objects/object_dinofos.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dkjail_obj.xml b/assets/xml/objects/object_dkjail_obj.xml new file mode 100644 index 0000000000..219181c6db --- /dev/null +++ b/assets/xml/objects/object_dkjail_obj.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_dmask.xml b/assets/xml/objects/object_dmask.xml new file mode 100644 index 0000000000..f2411c147c --- /dev/null +++ b/assets/xml/objects/object_dmask.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnk.xml b/assets/xml/objects/object_dnk.xml new file mode 100644 index 0000000000..209742fe18 --- /dev/null +++ b/assets/xml/objects/object_dnk.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dno.xml b/assets/xml/objects/object_dno.xml new file mode 100644 index 0000000000..16fa904c5b --- /dev/null +++ b/assets/xml/objects/object_dno.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnp.xml b/assets/xml/objects/object_dnp.xml new file mode 100644 index 0000000000..0f5655e9b6 --- /dev/null +++ b/assets/xml/objects/object_dnp.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnq.xml b/assets/xml/objects/object_dnq.xml new file mode 100644 index 0000000000..d286082bf8 --- /dev/null +++ b/assets/xml/objects/object_dnq.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dns.xml b/assets/xml/objects/object_dns.xml new file mode 100644 index 0000000000..64939670e3 --- /dev/null +++ b/assets/xml/objects/object_dns.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnt.xml b/assets/xml/objects/object_dnt.xml new file mode 100644 index 0000000000..d75f29cfc0 --- /dev/null +++ b/assets/xml/objects/object_dnt.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dodongo.xml b/assets/xml/objects/object_dodongo.xml new file mode 100644 index 0000000000..cf0fa37256 --- /dev/null +++ b/assets/xml/objects/object_dodongo.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dog.xml b/assets/xml/objects/object_dog.xml new file mode 100644 index 0000000000..7e9cd3e992 --- /dev/null +++ b/assets/xml/objects/object_dog.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dor01.xml b/assets/xml/objects/object_dor01.xml new file mode 100644 index 0000000000..39c950680f --- /dev/null +++ b/assets/xml/objects/object_dor01.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dor02.xml b/assets/xml/objects/object_dor02.xml new file mode 100644 index 0000000000..0b64a9b1bd --- /dev/null +++ b/assets/xml/objects/object_dor02.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dor03.xml b/assets/xml/objects/object_dor03.xml new file mode 100644 index 0000000000..c374837eaf --- /dev/null +++ b/assets/xml/objects/object_dor03.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_dor04.xml b/assets/xml/objects/object_dor04.xml new file mode 100644 index 0000000000..2d1ac5611d --- /dev/null +++ b/assets/xml/objects/object_dor04.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dora.xml b/assets/xml/objects/object_dora.xml new file mode 100644 index 0000000000..6a09726665 --- /dev/null +++ b/assets/xml/objects/object_dora.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_driftice.xml b/assets/xml/objects/object_driftice.xml new file mode 100644 index 0000000000..0ddb6e2048 --- /dev/null +++ b/assets/xml/objects/object_driftice.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_drs.xml b/assets/xml/objects/object_drs.xml new file mode 100644 index 0000000000..35202d17bf --- /dev/null +++ b/assets/xml/objects/object_drs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ds2.xml b/assets/xml/objects/object_ds2.xml new file mode 100644 index 0000000000..0745fad580 --- /dev/null +++ b/assets/xml/objects/object_ds2.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ds2n.xml b/assets/xml/objects/object_ds2n.xml new file mode 100644 index 0000000000..63ccca136b --- /dev/null +++ b/assets/xml/objects/object_ds2n.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dt.xml b/assets/xml/objects/object_dt.xml new file mode 100644 index 0000000000..a4df244adb --- /dev/null +++ b/assets/xml/objects/object_dt.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dy_obj.xml b/assets/xml/objects/object_dy_obj.xml new file mode 100644 index 0000000000..dc2ab5ed41 --- /dev/null +++ b/assets/xml/objects/object_dy_obj.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_efc_star_field.xml b/assets/xml/objects/object_efc_star_field.xml new file mode 100644 index 0000000000..72b7ef6367 --- /dev/null +++ b/assets/xml/objects/object_efc_star_field.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_efc_tw.xml b/assets/xml/objects/object_efc_tw.xml new file mode 100644 index 0000000000..f251f9607b --- /dev/null +++ b/assets/xml/objects/object_efc_tw.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_eg.xml b/assets/xml/objects/object_eg.xml new file mode 100644 index 0000000000..1458afaec0 --- /dev/null +++ b/assets/xml/objects/object_eg.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ending_obj.xml b/assets/xml/objects/object_ending_obj.xml new file mode 100644 index 0000000000..ad13ce7b89 --- /dev/null +++ b/assets/xml/objects/object_ending_obj.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_f40_obj.xml b/assets/xml/objects/object_f40_obj.xml new file mode 100644 index 0000000000..59bff9d05e --- /dev/null +++ b/assets/xml/objects/object_f40_obj.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_f40_switch.xml b/assets/xml/objects/object_f40_switch.xml new file mode 100644 index 0000000000..a5c823baaa --- /dev/null +++ b/assets/xml/objects/object_f40_switch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_f52_obj.xml b/assets/xml/objects/object_f52_obj.xml new file mode 100644 index 0000000000..7f35d8b1bb --- /dev/null +++ b/assets/xml/objects/object_f52_obj.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_f53_obj.xml b/assets/xml/objects/object_f53_obj.xml new file mode 100644 index 0000000000..8fef96ac8a --- /dev/null +++ b/assets/xml/objects/object_f53_obj.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fall.xml b/assets/xml/objects/object_fall.xml new file mode 100644 index 0000000000..f84ecffc5f --- /dev/null +++ b/assets/xml/objects/object_fall.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fall2.xml b/assets/xml/objects/object_fall2.xml new file mode 100644 index 0000000000..e616de260d --- /dev/null +++ b/assets/xml/objects/object_fall2.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_famos.xml b/assets/xml/objects/object_famos.xml new file mode 100644 index 0000000000..7cec70be54 --- /dev/null +++ b/assets/xml/objects/object_famos.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fb.xml b/assets/xml/objects/object_fb.xml new file mode 100644 index 0000000000..101ddbc5a7 --- /dev/null +++ b/assets/xml/objects/object_fb.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_firefly.xml b/assets/xml/objects/object_firefly.xml new file mode 100644 index 0000000000..f6d8f1bc71 --- /dev/null +++ b/assets/xml/objects/object_firefly.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fish.xml b/assets/xml/objects/object_fish.xml new file mode 100644 index 0000000000..3d02127c6d --- /dev/null +++ b/assets/xml/objects/object_fish.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_flowerpot.xml b/assets/xml/objects/object_flowerpot.xml new file mode 100644 index 0000000000..b6adc70d4c --- /dev/null +++ b/assets/xml/objects/object_flowerpot.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_fr.xml b/assets/xml/objects/object_fr.xml new file mode 100644 index 0000000000..b1d284de9f --- /dev/null +++ b/assets/xml/objects/object_fr.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fsn.xml b/assets/xml/objects/object_fsn.xml new file mode 100644 index 0000000000..f2d4b36485 --- /dev/null +++ b/assets/xml/objects/object_fsn.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu.xml b/assets/xml/objects/object_fu.xml new file mode 100644 index 0000000000..83d2f9eff9 --- /dev/null +++ b/assets/xml/objects/object_fu.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu_kaiten.xml b/assets/xml/objects/object_fu_kaiten.xml new file mode 100644 index 0000000000..bce80f68c1 --- /dev/null +++ b/assets/xml/objects/object_fu_kaiten.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu_mato.xml b/assets/xml/objects/object_fu_mato.xml new file mode 100644 index 0000000000..b28899f3c9 --- /dev/null +++ b/assets/xml/objects/object_fu_mato.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_funen.xml b/assets/xml/objects/object_funen.xml new file mode 100644 index 0000000000..5f8c18c3d3 --- /dev/null +++ b/assets/xml/objects/object_funen.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_fusen.xml b/assets/xml/objects/object_fusen.xml new file mode 100644 index 0000000000..0ff9e9f6c1 --- /dev/null +++ b/assets/xml/objects/object_fusen.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_fwall.xml b/assets/xml/objects/object_fwall.xml new file mode 100644 index 0000000000..1f7fb575bb --- /dev/null +++ b/assets/xml/objects/object_fwall.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_fz.xml b/assets/xml/objects/object_fz.xml new file mode 100644 index 0000000000..0c0b2ce2b4 --- /dev/null +++ b/assets/xml/objects/object_fz.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ge1.xml b/assets/xml/objects/object_ge1.xml new file mode 100644 index 0000000000..e401fd0888 --- /dev/null +++ b/assets/xml/objects/object_ge1.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_geldb.xml b/assets/xml/objects/object_geldb.xml new file mode 100644 index 0000000000..357b832843 --- /dev/null +++ b/assets/xml/objects/object_geldb.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gg.xml b/assets/xml/objects/object_gg.xml new file mode 100644 index 0000000000..e1ac1c779b --- /dev/null +++ b/assets/xml/objects/object_gg.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ghaka.xml b/assets/xml/objects/object_ghaka.xml new file mode 100644 index 0000000000..6ca9a32b0a --- /dev/null +++ b/assets/xml/objects/object_ghaka.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_arrow.xml b/assets/xml/objects/object_gi_arrow.xml new file mode 100644 index 0000000000..ab3bcbde9f --- /dev/null +++ b/assets/xml/objects/object_gi_arrow.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_arrowcase.xml b/assets/xml/objects/object_gi_arrowcase.xml new file mode 100644 index 0000000000..ae10b4faae --- /dev/null +++ b/assets/xml/objects/object_gi_arrowcase.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bean.xml b/assets/xml/objects/object_gi_bean.xml new file mode 100644 index 0000000000..e19b48d14b --- /dev/null +++ b/assets/xml/objects/object_gi_bean.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_bigbomb.xml b/assets/xml/objects/object_gi_bigbomb.xml new file mode 100644 index 0000000000..27d2a07416 --- /dev/null +++ b/assets/xml/objects/object_gi_bigbomb.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bomb_1.xml b/assets/xml/objects/object_gi_bomb_1.xml new file mode 100644 index 0000000000..98af218735 --- /dev/null +++ b/assets/xml/objects/object_gi_bomb_1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_bomb_2.xml b/assets/xml/objects/object_gi_bomb_2.xml new file mode 100644 index 0000000000..ecd07c048f --- /dev/null +++ b/assets/xml/objects/object_gi_bomb_2.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_bombpouch.xml b/assets/xml/objects/object_gi_bombpouch.xml new file mode 100644 index 0000000000..06eff7cedb --- /dev/null +++ b/assets/xml/objects/object_gi_bombpouch.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bosskey.xml b/assets/xml/objects/object_gi_bosskey.xml new file mode 100644 index 0000000000..ae5ac2e750 --- /dev/null +++ b/assets/xml/objects/object_gi_bosskey.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_bottle.xml b/assets/xml/objects/object_gi_bottle.xml new file mode 100644 index 0000000000..95a7b8bce4 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_04.xml b/assets/xml/objects/object_gi_bottle_04.xml new file mode 100644 index 0000000000..f215d40599 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_04.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_15.xml b/assets/xml/objects/object_gi_bottle_15.xml new file mode 100644 index 0000000000..afea0f6ca2 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_15.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_16.xml b/assets/xml/objects/object_gi_bottle_16.xml new file mode 100644 index 0000000000..7ee7f36408 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_16.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_21.xml b/assets/xml/objects/object_gi_bottle_21.xml new file mode 100644 index 0000000000..779b474cd0 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_21.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_22.xml b/assets/xml/objects/object_gi_bottle_22.xml new file mode 100644 index 0000000000..d613970143 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_22.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_red.xml b/assets/xml/objects/object_gi_bottle_red.xml new file mode 100644 index 0000000000..c2f189dcef --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_red.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_bow.xml b/assets/xml/objects/object_gi_bow.xml new file mode 100644 index 0000000000..b7d62e12d3 --- /dev/null +++ b/assets/xml/objects/object_gi_bow.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_camera.xml b/assets/xml/objects/object_gi_camera.xml new file mode 100644 index 0000000000..81641ca309 --- /dev/null +++ b/assets/xml/objects/object_gi_camera.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_compass.xml b/assets/xml/objects/object_gi_compass.xml new file mode 100644 index 0000000000..49f7cf87e7 --- /dev/null +++ b/assets/xml/objects/object_gi_compass.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_fieldmap.xml b/assets/xml/objects/object_gi_fieldmap.xml new file mode 100644 index 0000000000..bdb77ad0b1 --- /dev/null +++ b/assets/xml/objects/object_gi_fieldmap.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_fish.xml b/assets/xml/objects/object_gi_fish.xml new file mode 100644 index 0000000000..339f2d1445 --- /dev/null +++ b/assets/xml/objects/object_gi_fish.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_ghost.xml b/assets/xml/objects/object_gi_ghost.xml new file mode 100644 index 0000000000..813ba7d4ea --- /dev/null +++ b/assets/xml/objects/object_gi_ghost.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_glasses.xml b/assets/xml/objects/object_gi_glasses.xml new file mode 100644 index 0000000000..571f0ea6df --- /dev/null +++ b/assets/xml/objects/object_gi_glasses.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_gold_dust.xml b/assets/xml/objects/object_gi_gold_dust.xml new file mode 100644 index 0000000000..ed787b2b2e --- /dev/null +++ b/assets/xml/objects/object_gi_gold_dust.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_golonmask.xml b/assets/xml/objects/object_gi_golonmask.xml new file mode 100644 index 0000000000..c845fd0bdf --- /dev/null +++ b/assets/xml/objects/object_gi_golonmask.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_heart.xml b/assets/xml/objects/object_gi_heart.xml new file mode 100644 index 0000000000..0917876aa7 --- /dev/null +++ b/assets/xml/objects/object_gi_heart.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_hearts.xml b/assets/xml/objects/object_gi_hearts.xml new file mode 100644 index 0000000000..442ba21c73 --- /dev/null +++ b/assets/xml/objects/object_gi_hearts.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_hookshot.xml b/assets/xml/objects/object_gi_hookshot.xml new file mode 100644 index 0000000000..37a0b46426 --- /dev/null +++ b/assets/xml/objects/object_gi_hookshot.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_insect.xml b/assets/xml/objects/object_gi_insect.xml new file mode 100644 index 0000000000..a7c3107ea5 --- /dev/null +++ b/assets/xml/objects/object_gi_insect.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_key.xml b/assets/xml/objects/object_gi_key.xml new file mode 100644 index 0000000000..bf4cdb7271 --- /dev/null +++ b/assets/xml/objects/object_gi_key.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_ki_tan_mask.xml b/assets/xml/objects/object_gi_ki_tan_mask.xml new file mode 100644 index 0000000000..3135766315 --- /dev/null +++ b/assets/xml/objects/object_gi_ki_tan_mask.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_liquid.xml b/assets/xml/objects/object_gi_liquid.xml new file mode 100644 index 0000000000..bec768cfe0 --- /dev/null +++ b/assets/xml/objects/object_gi_liquid.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_loach.xml b/assets/xml/objects/object_gi_loach.xml new file mode 100644 index 0000000000..c9c81f0b9a --- /dev/null +++ b/assets/xml/objects/object_gi_loach.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_longsword.xml b/assets/xml/objects/object_gi_longsword.xml new file mode 100644 index 0000000000..6be60d411d --- /dev/null +++ b/assets/xml/objects/object_gi_longsword.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_m_arrow.xml b/assets/xml/objects/object_gi_m_arrow.xml new file mode 100644 index 0000000000..6351783b54 --- /dev/null +++ b/assets/xml/objects/object_gi_m_arrow.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_magicmushroom.xml b/assets/xml/objects/object_gi_magicmushroom.xml new file mode 100644 index 0000000000..ae6cbeb49c --- /dev/null +++ b/assets/xml/objects/object_gi_magicmushroom.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_magicpot.xml b/assets/xml/objects/object_gi_magicpot.xml new file mode 100644 index 0000000000..2abd48eeff --- /dev/null +++ b/assets/xml/objects/object_gi_magicpot.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_map.xml b/assets/xml/objects/object_gi_map.xml new file mode 100644 index 0000000000..250bb4613a --- /dev/null +++ b/assets/xml/objects/object_gi_map.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_mask03.xml b/assets/xml/objects/object_gi_mask03.xml new file mode 100644 index 0000000000..561ddef83a --- /dev/null +++ b/assets/xml/objects/object_gi_mask03.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask05.xml b/assets/xml/objects/object_gi_mask05.xml new file mode 100644 index 0000000000..307a3b2f43 --- /dev/null +++ b/assets/xml/objects/object_gi_mask05.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask06.xml b/assets/xml/objects/object_gi_mask06.xml new file mode 100644 index 0000000000..256d9a91eb --- /dev/null +++ b/assets/xml/objects/object_gi_mask06.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask09.xml b/assets/xml/objects/object_gi_mask09.xml new file mode 100644 index 0000000000..d6db047d57 --- /dev/null +++ b/assets/xml/objects/object_gi_mask09.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask10.xml b/assets/xml/objects/object_gi_mask10.xml new file mode 100644 index 0000000000..adb3ee1d22 --- /dev/null +++ b/assets/xml/objects/object_gi_mask10.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask11.xml b/assets/xml/objects/object_gi_mask11.xml new file mode 100644 index 0000000000..46de5c2cdb --- /dev/null +++ b/assets/xml/objects/object_gi_mask11.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask12.xml b/assets/xml/objects/object_gi_mask12.xml new file mode 100644 index 0000000000..dced8d8eb6 --- /dev/null +++ b/assets/xml/objects/object_gi_mask12.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask13.xml b/assets/xml/objects/object_gi_mask13.xml new file mode 100644 index 0000000000..b6d2c77336 --- /dev/null +++ b/assets/xml/objects/object_gi_mask13.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask14.xml b/assets/xml/objects/object_gi_mask14.xml new file mode 100644 index 0000000000..a3c96bb9d6 --- /dev/null +++ b/assets/xml/objects/object_gi_mask14.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask15.xml b/assets/xml/objects/object_gi_mask15.xml new file mode 100644 index 0000000000..bc612c0755 --- /dev/null +++ b/assets/xml/objects/object_gi_mask15.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask16.xml b/assets/xml/objects/object_gi_mask16.xml new file mode 100644 index 0000000000..57124d4d43 --- /dev/null +++ b/assets/xml/objects/object_gi_mask16.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask17.xml b/assets/xml/objects/object_gi_mask17.xml new file mode 100644 index 0000000000..a509ca27ed --- /dev/null +++ b/assets/xml/objects/object_gi_mask17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask18.xml b/assets/xml/objects/object_gi_mask18.xml new file mode 100644 index 0000000000..8e1c8ca547 --- /dev/null +++ b/assets/xml/objects/object_gi_mask18.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask20.xml b/assets/xml/objects/object_gi_mask20.xml new file mode 100644 index 0000000000..8b87c44fa0 --- /dev/null +++ b/assets/xml/objects/object_gi_mask20.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask21.xml b/assets/xml/objects/object_gi_mask21.xml new file mode 100644 index 0000000000..175d22b85f --- /dev/null +++ b/assets/xml/objects/object_gi_mask21.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask22.xml b/assets/xml/objects/object_gi_mask22.xml new file mode 100644 index 0000000000..7b3a49e537 --- /dev/null +++ b/assets/xml/objects/object_gi_mask22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask23.xml b/assets/xml/objects/object_gi_mask23.xml new file mode 100644 index 0000000000..458b7c825a --- /dev/null +++ b/assets/xml/objects/object_gi_mask23.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_melody.xml b/assets/xml/objects/object_gi_melody.xml new file mode 100644 index 0000000000..d7617e7a69 --- /dev/null +++ b/assets/xml/objects/object_gi_melody.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_milk.xml b/assets/xml/objects/object_gi_milk.xml new file mode 100644 index 0000000000..137dae7779 --- /dev/null +++ b/assets/xml/objects/object_gi_milk.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_mssa.xml b/assets/xml/objects/object_gi_mssa.xml new file mode 100644 index 0000000000..6b61b00f5f --- /dev/null +++ b/assets/xml/objects/object_gi_mssa.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_nuts.xml b/assets/xml/objects/object_gi_nuts.xml new file mode 100644 index 0000000000..073e7db8f6 --- /dev/null +++ b/assets/xml/objects/object_gi_nuts.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_nutsmask.xml b/assets/xml/objects/object_gi_nutsmask.xml new file mode 100644 index 0000000000..e34a593f22 --- /dev/null +++ b/assets/xml/objects/object_gi_nutsmask.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_ocarina.xml b/assets/xml/objects/object_gi_ocarina.xml new file mode 100644 index 0000000000..7b968a4912 --- /dev/null +++ b/assets/xml/objects/object_gi_ocarina.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_purse.xml b/assets/xml/objects/object_gi_purse.xml new file mode 100644 index 0000000000..49cf9fd370 --- /dev/null +++ b/assets/xml/objects/object_gi_purse.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_rabit_mask.xml b/assets/xml/objects/object_gi_rabit_mask.xml new file mode 100644 index 0000000000..172c080f11 --- /dev/null +++ b/assets/xml/objects/object_gi_rabit_mask.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve00.xml b/assets/xml/objects/object_gi_reserve00.xml new file mode 100644 index 0000000000..1527a26303 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve00.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve01.xml b/assets/xml/objects/object_gi_reserve01.xml new file mode 100644 index 0000000000..c31c76698f --- /dev/null +++ b/assets/xml/objects/object_gi_reserve01.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_b_00.xml b/assets/xml/objects/object_gi_reserve_b_00.xml new file mode 100644 index 0000000000..1c1e543905 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_b_00.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_b_01.xml b/assets/xml/objects/object_gi_reserve_b_01.xml new file mode 100644 index 0000000000..574763ee91 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_b_01.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_c_00.xml b/assets/xml/objects/object_gi_reserve_c_00.xml new file mode 100644 index 0000000000..86c6b15fbd --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_c_00.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_c_01.xml b/assets/xml/objects/object_gi_reserve_c_01.xml new file mode 100644 index 0000000000..da15309709 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_c_01.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_rupy.xml b/assets/xml/objects/object_gi_rupy.xml new file mode 100644 index 0000000000..69cd8bf5c8 --- /dev/null +++ b/assets/xml/objects/object_gi_rupy.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_schedule.xml b/assets/xml/objects/object_gi_schedule.xml new file mode 100644 index 0000000000..e5025a9938 --- /dev/null +++ b/assets/xml/objects/object_gi_schedule.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_seahorse.xml b/assets/xml/objects/object_gi_seahorse.xml new file mode 100644 index 0000000000..f35e2edc97 --- /dev/null +++ b/assets/xml/objects/object_gi_seahorse.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_shield_2.xml b/assets/xml/objects/object_gi_shield_2.xml new file mode 100644 index 0000000000..eb9fec8d2f --- /dev/null +++ b/assets/xml/objects/object_gi_shield_2.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_shield_3.xml b/assets/xml/objects/object_gi_shield_3.xml new file mode 100644 index 0000000000..8e011bb92a --- /dev/null +++ b/assets/xml/objects/object_gi_shield_3.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_soldout.xml b/assets/xml/objects/object_gi_soldout.xml new file mode 100644 index 0000000000..8a733af02e --- /dev/null +++ b/assets/xml/objects/object_gi_soldout.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_soul.xml b/assets/xml/objects/object_gi_soul.xml new file mode 100644 index 0000000000..945670888b --- /dev/null +++ b/assets/xml/objects/object_gi_soul.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_stick.xml b/assets/xml/objects/object_gi_stick.xml new file mode 100644 index 0000000000..c038af3571 --- /dev/null +++ b/assets/xml/objects/object_gi_stick.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_stonemask.xml b/assets/xml/objects/object_gi_stonemask.xml new file mode 100644 index 0000000000..9d3b62b8c2 --- /dev/null +++ b/assets/xml/objects/object_gi_stonemask.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_sutaru.xml b/assets/xml/objects/object_gi_sutaru.xml new file mode 100644 index 0000000000..3b991123e8 --- /dev/null +++ b/assets/xml/objects/object_gi_sutaru.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_sword_1.xml b/assets/xml/objects/object_gi_sword_1.xml new file mode 100644 index 0000000000..a03de82d51 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_1.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_sword_2.xml b/assets/xml/objects/object_gi_sword_2.xml new file mode 100644 index 0000000000..045936ef2a --- /dev/null +++ b/assets/xml/objects/object_gi_sword_2.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_sword_3.xml b/assets/xml/objects/object_gi_sword_3.xml new file mode 100644 index 0000000000..79a2079916 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_3.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_sword_4.xml b/assets/xml/objects/object_gi_sword_4.xml new file mode 100644 index 0000000000..b5c826dc36 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_4.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_truth_mask.xml b/assets/xml/objects/object_gi_truth_mask.xml new file mode 100644 index 0000000000..52fdaaf65a --- /dev/null +++ b/assets/xml/objects/object_gi_truth_mask.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_zoramask.xml b/assets/xml/objects/object_gi_zoramask.xml new file mode 100644 index 0000000000..c5ba218b41 --- /dev/null +++ b/assets/xml/objects/object_gi_zoramask.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_giant.xml b/assets/xml/objects/object_giant.xml new file mode 100644 index 0000000000..9e1815528e --- /dev/null +++ b/assets/xml/objects/object_giant.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gk.xml b/assets/xml/objects/object_gk.xml new file mode 100644 index 0000000000..420f544f19 --- /dev/null +++ b/assets/xml/objects/object_gk.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gla.xml b/assets/xml/objects/object_gla.xml new file mode 100644 index 0000000000..ee793c256a --- /dev/null +++ b/assets/xml/objects/object_gla.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gm.xml b/assets/xml/objects/object_gm.xml new file mode 100644 index 0000000000..50c852ade8 --- /dev/null +++ b/assets/xml/objects/object_gm.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gmo.xml b/assets/xml/objects/object_gmo.xml new file mode 100644 index 0000000000..732634d761 --- /dev/null +++ b/assets/xml/objects/object_gmo.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_goroiwa.xml b/assets/xml/objects/object_goroiwa.xml new file mode 100644 index 0000000000..e6ddfe7c16 --- /dev/null +++ b/assets/xml/objects/object_goroiwa.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_goronswitch.xml b/assets/xml/objects/object_goronswitch.xml new file mode 100644 index 0000000000..a6a0f996f1 --- /dev/null +++ b/assets/xml/objects/object_goronswitch.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_grasshopper.xml b/assets/xml/objects/object_grasshopper.xml new file mode 100644 index 0000000000..5b8ee82af2 --- /dev/null +++ b/assets/xml/objects/object_grasshopper.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gs.xml b/assets/xml/objects/object_gs.xml new file mode 100644 index 0000000000..1e9b159dfe --- /dev/null +++ b/assets/xml/objects/object_gs.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_ha.xml b/assets/xml/objects/object_ha.xml new file mode 100644 index 0000000000..f3d3f10290 --- /dev/null +++ b/assets/xml/objects/object_ha.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_haka_obj.xml b/assets/xml/objects/object_haka_obj.xml new file mode 100644 index 0000000000..57f34f0d11 --- /dev/null +++ b/assets/xml/objects/object_haka_obj.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hakaisi.xml b/assets/xml/objects/object_hakaisi.xml new file mode 100644 index 0000000000..82e80242e6 --- /dev/null +++ b/assets/xml/objects/object_hakaisi.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hakugin_demo.xml b/assets/xml/objects/object_hakugin_demo.xml new file mode 100644 index 0000000000..24c7a2ba2a --- /dev/null +++ b/assets/xml/objects/object_hakugin_demo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_hakugin_obj.xml b/assets/xml/objects/object_hakugin_obj.xml new file mode 100644 index 0000000000..412d0bdd3e --- /dev/null +++ b/assets/xml/objects/object_hakugin_obj.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hana.xml b/assets/xml/objects/object_hana.xml new file mode 100644 index 0000000000..3812a4ff59 --- /dev/null +++ b/assets/xml/objects/object_hana.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hanareyama_obj.xml b/assets/xml/objects/object_hanareyama_obj.xml new file mode 100644 index 0000000000..ba213a5856 --- /dev/null +++ b/assets/xml/objects/object_hanareyama_obj.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_harfgibud.xml b/assets/xml/objects/object_harfgibud.xml new file mode 100644 index 0000000000..9a9bf4745c --- /dev/null +++ b/assets/xml/objects/object_harfgibud.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hariko.xml b/assets/xml/objects/object_hariko.xml new file mode 100644 index 0000000000..e0f139b883 --- /dev/null +++ b/assets/xml/objects/object_hariko.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_hata.xml b/assets/xml/objects/object_hata.xml new file mode 100644 index 0000000000..3131a6628d --- /dev/null +++ b/assets/xml/objects/object_hata.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hgdoor.xml b/assets/xml/objects/object_hgdoor.xml new file mode 100644 index 0000000000..e897103bf6 --- /dev/null +++ b/assets/xml/objects/object_hgdoor.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hintnuts.xml b/assets/xml/objects/object_hintnuts.xml new file mode 100644 index 0000000000..655c8ae3c4 --- /dev/null +++ b/assets/xml/objects/object_hintnuts.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_horse_game_check.xml b/assets/xml/objects/object_horse_game_check.xml new file mode 100644 index 0000000000..1ea72ac57c --- /dev/null +++ b/assets/xml/objects/object_horse_game_check.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_horse_link_child.xml b/assets/xml/objects/object_horse_link_child.xml new file mode 100644 index 0000000000..f844224fa5 --- /dev/null +++ b/assets/xml/objects/object_horse_link_child.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hs.xml b/assets/xml/objects/object_hs.xml new file mode 100644 index 0000000000..3151288155 --- /dev/null +++ b/assets/xml/objects/object_hs.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hsstump.xml b/assets/xml/objects/object_hsstump.xml new file mode 100644 index 0000000000..f94f0ed4e2 --- /dev/null +++ b/assets/xml/objects/object_hsstump.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_hunsui.xml b/assets/xml/objects/object_hunsui.xml new file mode 100644 index 0000000000..878bf704d6 --- /dev/null +++ b/assets/xml/objects/object_hunsui.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ice_block.xml b/assets/xml/objects/object_ice_block.xml new file mode 100644 index 0000000000..1e14ea5b5f --- /dev/null +++ b/assets/xml/objects/object_ice_block.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_icefloe.xml b/assets/xml/objects/object_icefloe.xml new file mode 100644 index 0000000000..cb9b321a31 --- /dev/null +++ b/assets/xml/objects/object_icefloe.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_icicle.xml b/assets/xml/objects/object_icicle.xml new file mode 100644 index 0000000000..4f7bab8a24 --- /dev/null +++ b/assets/xml/objects/object_icicle.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_ik.xml b/assets/xml/objects/object_ik.xml new file mode 100644 index 0000000000..34dcac8f2c --- /dev/null +++ b/assets/xml/objects/object_ik.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ikana_obj.xml b/assets/xml/objects/object_ikana_obj.xml new file mode 100644 index 0000000000..66398991b9 --- /dev/null +++ b/assets/xml/objects/object_ikana_obj.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ikn_demo.xml b/assets/xml/objects/object_ikn_demo.xml new file mode 100644 index 0000000000..69d225933c --- /dev/null +++ b/assets/xml/objects/object_ikn_demo.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ikninside_obj.xml b/assets/xml/objects/object_ikninside_obj.xml new file mode 100644 index 0000000000..98ae6d34f0 --- /dev/null +++ b/assets/xml/objects/object_ikninside_obj.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_iknv_obj.xml b/assets/xml/objects/object_iknv_obj.xml new file mode 100644 index 0000000000..1e10d813c0 --- /dev/null +++ b/assets/xml/objects/object_iknv_obj.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_in.xml b/assets/xml/objects/object_in.xml new file mode 100644 index 0000000000..07969fe80f --- /dev/null +++ b/assets/xml/objects/object_in.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_in2.xml b/assets/xml/objects/object_in2.xml new file mode 100644 index 0000000000..34a942882a --- /dev/null +++ b/assets/xml/objects/object_in2.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_inibs_object.xml b/assets/xml/objects/object_inibs_object.xml new file mode 100644 index 0000000000..e1d454ae71 --- /dev/null +++ b/assets/xml/objects/object_inibs_object.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ishi.xml b/assets/xml/objects/object_ishi.xml new file mode 100644 index 0000000000..6e48cf5f4e --- /dev/null +++ b/assets/xml/objects/object_ishi.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_jg.xml b/assets/xml/objects/object_jg.xml new file mode 100644 index 0000000000..10253e155d --- /dev/null +++ b/assets/xml/objects/object_jg.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_js.xml b/assets/xml/objects/object_js.xml new file mode 100644 index 0000000000..be9246ab66 --- /dev/null +++ b/assets/xml/objects/object_js.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_jso.xml b/assets/xml/objects/object_jso.xml new file mode 100644 index 0000000000..777c6e53c3 --- /dev/null +++ b/assets/xml/objects/object_jso.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ka.xml b/assets/xml/objects/object_ka.xml new file mode 100644 index 0000000000..2944a00b24 --- /dev/null +++ b/assets/xml/objects/object_ka.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kaizoku_obj.xml b/assets/xml/objects/object_kaizoku_obj.xml new file mode 100644 index 0000000000..a38d16827b --- /dev/null +++ b/assets/xml/objects/object_kaizoku_obj.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kamejima.xml b/assets/xml/objects/object_kamejima.xml new file mode 100644 index 0000000000..8bdb54d06c --- /dev/null +++ b/assets/xml/objects/object_kamejima.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kanban.xml b/assets/xml/objects/object_kanban.xml new file mode 100644 index 0000000000..b821aa2883 --- /dev/null +++ b/assets/xml/objects/object_kanban.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kbt.xml b/assets/xml/objects/object_kbt.xml new file mode 100644 index 0000000000..b3ab0baaf8 --- /dev/null +++ b/assets/xml/objects/object_kbt.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_keikoku_demo.xml b/assets/xml/objects/object_keikoku_demo.xml new file mode 100644 index 0000000000..994b682f3b --- /dev/null +++ b/assets/xml/objects/object_keikoku_demo.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_keikoku_obj.xml b/assets/xml/objects/object_keikoku_obj.xml new file mode 100644 index 0000000000..ff5a6899cb --- /dev/null +++ b/assets/xml/objects/object_keikoku_obj.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kepn_koya.xml b/assets/xml/objects/object_kepn_koya.xml new file mode 100644 index 0000000000..893892d25c --- /dev/null +++ b/assets/xml/objects/object_kepn_koya.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kgy.xml b/assets/xml/objects/object_kgy.xml new file mode 100644 index 0000000000..856c5883d9 --- /dev/null +++ b/assets/xml/objects/object_kgy.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kibako.xml b/assets/xml/objects/object_kibako.xml new file mode 100644 index 0000000000..138894b0fb --- /dev/null +++ b/assets/xml/objects/object_kibako.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_kibako2.xml b/assets/xml/objects/object_kibako2.xml new file mode 100644 index 0000000000..098a5318d0 --- /dev/null +++ b/assets/xml/objects/object_kibako2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kin2_obj.xml b/assets/xml/objects/object_kin2_obj.xml new file mode 100644 index 0000000000..93e55786cc --- /dev/null +++ b/assets/xml/objects/object_kin2_obj.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kinsta1_obj.xml b/assets/xml/objects/object_kinsta1_obj.xml new file mode 100644 index 0000000000..48d40c5271 --- /dev/null +++ b/assets/xml/objects/object_kinsta1_obj.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_kinsta2_obj.xml b/assets/xml/objects/object_kinsta2_obj.xml new file mode 100644 index 0000000000..f27778b1ac --- /dev/null +++ b/assets/xml/objects/object_kinsta2_obj.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_kitan.xml b/assets/xml/objects/object_kitan.xml new file mode 100644 index 0000000000..3884470f94 --- /dev/null +++ b/assets/xml/objects/object_kitan.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_knight.xml b/assets/xml/objects/object_knight.xml new file mode 100644 index 0000000000..bbd2d7b939 --- /dev/null +++ b/assets/xml/objects/object_knight.xml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kujiya.xml b/assets/xml/objects/object_kujiya.xml new file mode 100644 index 0000000000..3b17d43c08 --- /dev/null +++ b/assets/xml/objects/object_kujiya.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kumo30.xml b/assets/xml/objects/object_kumo30.xml new file mode 100644 index 0000000000..24e8d39742 --- /dev/null +++ b/assets/xml/objects/object_kumo30.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kusa.xml b/assets/xml/objects/object_kusa.xml new file mode 100644 index 0000000000..0d36569a55 --- /dev/null +++ b/assets/xml/objects/object_kusa.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_kz.xml b/assets/xml/objects/object_kz.xml new file mode 100644 index 0000000000..24c16e1fcb --- /dev/null +++ b/assets/xml/objects/object_kz.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kzsaku.xml b/assets/xml/objects/object_kzsaku.xml new file mode 100644 index 0000000000..4cfce2de2b --- /dev/null +++ b/assets/xml/objects/object_kzsaku.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_ladder.xml b/assets/xml/objects/object_ladder.xml new file mode 100644 index 0000000000..6e42412eca --- /dev/null +++ b/assets/xml/objects/object_ladder.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_last_obj.xml b/assets/xml/objects/object_last_obj.xml new file mode 100644 index 0000000000..03dbddcf22 --- /dev/null +++ b/assets/xml/objects/object_last_obj.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lastday.xml b/assets/xml/objects/object_lastday.xml new file mode 100644 index 0000000000..9988ec1f84 --- /dev/null +++ b/assets/xml/objects/object_lastday.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lbfshot.xml b/assets/xml/objects/object_lbfshot.xml new file mode 100644 index 0000000000..325ddf49ee --- /dev/null +++ b/assets/xml/objects/object_lbfshot.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_lightblock.xml b/assets/xml/objects/object_lightblock.xml new file mode 100644 index 0000000000..207b03020f --- /dev/null +++ b/assets/xml/objects/object_lightblock.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_lightswitch.xml b/assets/xml/objects/object_lightswitch.xml new file mode 100644 index 0000000000..3d5c3aee2b --- /dev/null +++ b/assets/xml/objects/object_lightswitch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_link_boy.xml b/assets/xml/objects/object_link_boy.xml new file mode 100644 index 0000000000..8bfd17e988 --- /dev/null +++ b/assets/xml/objects/object_link_boy.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_child.xml b/assets/xml/objects/object_link_child.xml new file mode 100644 index 0000000000..86c5969095 --- /dev/null +++ b/assets/xml/objects/object_link_child.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_goron.xml b/assets/xml/objects/object_link_goron.xml new file mode 100644 index 0000000000..05336d6dbe --- /dev/null +++ b/assets/xml/objects/object_link_goron.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_nuts.xml b/assets/xml/objects/object_link_nuts.xml new file mode 100644 index 0000000000..169dc848aa --- /dev/null +++ b/assets/xml/objects/object_link_nuts.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_zora.xml b/assets/xml/objects/object_link_zora.xml new file mode 100644 index 0000000000..e3bbaba951 --- /dev/null +++ b/assets/xml/objects/object_link_zora.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lodmoon.xml b/assets/xml/objects/object_lodmoon.xml new file mode 100644 index 0000000000..46d9f8e72b --- /dev/null +++ b/assets/xml/objects/object_lodmoon.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lotus.xml b/assets/xml/objects/object_lotus.xml new file mode 100644 index 0000000000..a9835b81b4 --- /dev/null +++ b/assets/xml/objects/object_lotus.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_ma1.xml b/assets/xml/objects/object_ma1.xml new file mode 100644 index 0000000000..98444a884c --- /dev/null +++ b/assets/xml/objects/object_ma1.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ma2.xml b/assets/xml/objects/object_ma2.xml new file mode 100644 index 0000000000..523dfe212c --- /dev/null +++ b/assets/xml/objects/object_ma2.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mag.xml b/assets/xml/objects/object_mag.xml new file mode 100644 index 0000000000..061ff6bca9 --- /dev/null +++ b/assets/xml/objects/object_mag.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mamenoki.xml b/assets/xml/objects/object_mamenoki.xml new file mode 100644 index 0000000000..9ce4644c39 --- /dev/null +++ b/assets/xml/objects/object_mamenoki.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_market_obj.xml b/assets/xml/objects/object_market_obj.xml new file mode 100644 index 0000000000..81ab838f1f --- /dev/null +++ b/assets/xml/objects/object_market_obj.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_maruta.xml b/assets/xml/objects/object_maruta.xml new file mode 100644 index 0000000000..e61e1162b0 --- /dev/null +++ b/assets/xml/objects/object_maruta.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bakuretu.xml b/assets/xml/objects/object_mask_bakuretu.xml new file mode 100644 index 0000000000..2eed781718 --- /dev/null +++ b/assets/xml/objects/object_mask_bakuretu.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bigelf.xml b/assets/xml/objects/object_mask_bigelf.xml new file mode 100644 index 0000000000..762d118089 --- /dev/null +++ b/assets/xml/objects/object_mask_bigelf.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_boy.xml b/assets/xml/objects/object_mask_boy.xml new file mode 100644 index 0000000000..e0f93797e1 --- /dev/null +++ b/assets/xml/objects/object_mask_boy.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bree.xml b/assets/xml/objects/object_mask_bree.xml new file mode 100644 index 0000000000..9fda443c83 --- /dev/null +++ b/assets/xml/objects/object_mask_bree.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bu_san.xml b/assets/xml/objects/object_mask_bu_san.xml new file mode 100644 index 0000000000..621e748ed6 --- /dev/null +++ b/assets/xml/objects/object_mask_bu_san.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_dancer.xml b/assets/xml/objects/object_mask_dancer.xml new file mode 100644 index 0000000000..a2a37c958b --- /dev/null +++ b/assets/xml/objects/object_mask_dancer.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_gero.xml b/assets/xml/objects/object_mask_gero.xml new file mode 100644 index 0000000000..b6acf6c173 --- /dev/null +++ b/assets/xml/objects/object_mask_gero.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_gibudo.xml b/assets/xml/objects/object_mask_gibudo.xml new file mode 100644 index 0000000000..76bf2b3dea --- /dev/null +++ b/assets/xml/objects/object_mask_gibudo.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_mask_goron.xml b/assets/xml/objects/object_mask_goron.xml new file mode 100644 index 0000000000..56a67218e5 --- /dev/null +++ b/assets/xml/objects/object_mask_goron.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_json.xml b/assets/xml/objects/object_mask_json.xml new file mode 100644 index 0000000000..1a5c10eb1b --- /dev/null +++ b/assets/xml/objects/object_mask_json.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_kerfay.xml b/assets/xml/objects/object_mask_kerfay.xml new file mode 100644 index 0000000000..282aa8029f --- /dev/null +++ b/assets/xml/objects/object_mask_kerfay.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_ki_tan.xml b/assets/xml/objects/object_mask_ki_tan.xml new file mode 100644 index 0000000000..f0322cc83e --- /dev/null +++ b/assets/xml/objects/object_mask_ki_tan.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_kyojin.xml b/assets/xml/objects/object_mask_kyojin.xml new file mode 100644 index 0000000000..cd07a57fd2 --- /dev/null +++ b/assets/xml/objects/object_mask_kyojin.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_mask_meoto.xml b/assets/xml/objects/object_mask_meoto.xml new file mode 100644 index 0000000000..069e521e05 --- /dev/null +++ b/assets/xml/objects/object_mask_meoto.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_mask_nuts.xml b/assets/xml/objects/object_mask_nuts.xml new file mode 100644 index 0000000000..6a0eaf26dc --- /dev/null +++ b/assets/xml/objects/object_mask_nuts.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_posthat.xml b/assets/xml/objects/object_mask_posthat.xml new file mode 100644 index 0000000000..bccbfb3018 --- /dev/null +++ b/assets/xml/objects/object_mask_posthat.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_mask_rabit.xml b/assets/xml/objects/object_mask_rabit.xml new file mode 100644 index 0000000000..a4a1f5c0cf --- /dev/null +++ b/assets/xml/objects/object_mask_rabit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_romerny.xml b/assets/xml/objects/object_mask_romerny.xml new file mode 100644 index 0000000000..603feef0df --- /dev/null +++ b/assets/xml/objects/object_mask_romerny.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_skj.xml b/assets/xml/objects/object_mask_skj.xml new file mode 100644 index 0000000000..457cd94f25 --- /dev/null +++ b/assets/xml/objects/object_mask_skj.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_stone.xml b/assets/xml/objects/object_mask_stone.xml new file mode 100644 index 0000000000..24f67d1dfe --- /dev/null +++ b/assets/xml/objects/object_mask_stone.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_mask_truth.xml b/assets/xml/objects/object_mask_truth.xml new file mode 100644 index 0000000000..3fed737a21 --- /dev/null +++ b/assets/xml/objects/object_mask_truth.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_mask_yofukasi.xml b/assets/xml/objects/object_mask_yofukasi.xml new file mode 100644 index 0000000000..990543e1b8 --- /dev/null +++ b/assets/xml/objects/object_mask_yofukasi.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_zacho.xml b/assets/xml/objects/object_mask_zacho.xml new file mode 100644 index 0000000000..ae63753de1 --- /dev/null +++ b/assets/xml/objects/object_mask_zacho.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_zora.xml b/assets/xml/objects/object_mask_zora.xml new file mode 100644 index 0000000000..c2e07cde24 --- /dev/null +++ b/assets/xml/objects/object_mask_zora.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mastergolon.xml b/assets/xml/objects/object_mastergolon.xml new file mode 100644 index 0000000000..ae481332cc --- /dev/null +++ b/assets/xml/objects/object_mastergolon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_masterzoora.xml b/assets/xml/objects/object_masterzoora.xml new file mode 100644 index 0000000000..c4f8735d75 --- /dev/null +++ b/assets/xml/objects/object_masterzoora.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_mbar_obj.xml b/assets/xml/objects/object_mbar_obj.xml new file mode 100644 index 0000000000..d69d7ce3b1 --- /dev/null +++ b/assets/xml/objects/object_mbar_obj.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_meganeana_obj.xml b/assets/xml/objects/object_meganeana_obj.xml new file mode 100644 index 0000000000..457c937bd7 --- /dev/null +++ b/assets/xml/objects/object_meganeana_obj.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_milkbar.xml b/assets/xml/objects/object_milkbar.xml new file mode 100644 index 0000000000..38bec140b1 --- /dev/null +++ b/assets/xml/objects/object_milkbar.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mir_ray.xml b/assets/xml/objects/object_mir_ray.xml new file mode 100644 index 0000000000..9629823223 --- /dev/null +++ b/assets/xml/objects/object_mir_ray.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mk.xml b/assets/xml/objects/object_mk.xml new file mode 100644 index 0000000000..c927f33de2 --- /dev/null +++ b/assets/xml/objects/object_mk.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mkk.xml b/assets/xml/objects/object_mkk.xml new file mode 100644 index 0000000000..17f36f3232 --- /dev/null +++ b/assets/xml/objects/object_mkk.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mm.xml b/assets/xml/objects/object_mm.xml new file mode 100644 index 0000000000..3ce9c1925c --- /dev/null +++ b/assets/xml/objects/object_mm.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mnk.xml b/assets/xml/objects/object_mnk.xml new file mode 100644 index 0000000000..8f813ba002 --- /dev/null +++ b/assets/xml/objects/object_mnk.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_moonend.xml b/assets/xml/objects/object_moonend.xml new file mode 100644 index 0000000000..e677f9c3f1 --- /dev/null +++ b/assets/xml/objects/object_moonend.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_moonston.xml b/assets/xml/objects/object_moonston.xml new file mode 100644 index 0000000000..cc06a96323 --- /dev/null +++ b/assets/xml/objects/object_moonston.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_ms.xml b/assets/xml/objects/object_ms.xml new file mode 100644 index 0000000000..9d7df53ad2 --- /dev/null +++ b/assets/xml/objects/object_ms.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_msmo.xml b/assets/xml/objects/object_msmo.xml new file mode 100644 index 0000000000..cb08f53ef6 --- /dev/null +++ b/assets/xml/objects/object_msmo.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_mtoride.xml b/assets/xml/objects/object_mtoride.xml new file mode 100644 index 0000000000..ab07928391 --- /dev/null +++ b/assets/xml/objects/object_mtoride.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mu.xml b/assets/xml/objects/object_mu.xml new file mode 100644 index 0000000000..a1c11fed2f --- /dev/null +++ b/assets/xml/objects/object_mu.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nb.xml b/assets/xml/objects/object_nb.xml new file mode 100644 index 0000000000..e0f557f981 --- /dev/null +++ b/assets/xml/objects/object_nb.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_niw.xml b/assets/xml/objects/object_niw.xml new file mode 100644 index 0000000000..f97b5d7261 --- /dev/null +++ b/assets/xml/objects/object_niw.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nnh.xml b/assets/xml/objects/object_nnh.xml new file mode 100644 index 0000000000..1bb833cf07 --- /dev/null +++ b/assets/xml/objects/object_nnh.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_numa_obj.xml b/assets/xml/objects/object_numa_obj.xml new file mode 100644 index 0000000000..cc36fa1b80 --- /dev/null +++ b/assets/xml/objects/object_numa_obj.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nwc.xml b/assets/xml/objects/object_nwc.xml new file mode 100644 index 0000000000..77b395b581 --- /dev/null +++ b/assets/xml/objects/object_nwc.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ny.xml b/assets/xml/objects/object_ny.xml new file mode 100644 index 0000000000..186dd91c3c --- /dev/null +++ b/assets/xml/objects/object_ny.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_oF1d_map.xml b/assets/xml/objects/object_oF1d_map.xml new file mode 100644 index 0000000000..9eac29aaad --- /dev/null +++ b/assets/xml/objects/object_oF1d_map.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ob.xml b/assets/xml/objects/object_ob.xml new file mode 100644 index 0000000000..7a75a59f28 --- /dev/null +++ b/assets/xml/objects/object_ob.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_chan.xml b/assets/xml/objects/object_obj_chan.xml new file mode 100644 index 0000000000..8469110e47 --- /dev/null +++ b/assets/xml/objects/object_obj_chan.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_danpeilift.xml b/assets/xml/objects/object_obj_danpeilift.xml new file mode 100644 index 0000000000..2d3c265670 --- /dev/null +++ b/assets/xml/objects/object_obj_danpeilift.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_obj_dinner.xml b/assets/xml/objects/object_obj_dinner.xml new file mode 100644 index 0000000000..6ca440035e --- /dev/null +++ b/assets/xml/objects/object_obj_dinner.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_milk_bin.xml b/assets/xml/objects/object_obj_milk_bin.xml new file mode 100644 index 0000000000..4a0ca700bb --- /dev/null +++ b/assets/xml/objects/object_obj_milk_bin.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_obj_tokeidai.xml b/assets/xml/objects/object_obj_tokeidai.xml new file mode 100644 index 0000000000..9141b67ff3 --- /dev/null +++ b/assets/xml/objects/object_obj_tokeidai.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_usiyane.xml b/assets/xml/objects/object_obj_usiyane.xml new file mode 100644 index 0000000000..339b25df9c --- /dev/null +++ b/assets/xml/objects/object_obj_usiyane.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_yasi.xml b/assets/xml/objects/object_obj_yasi.xml new file mode 100644 index 0000000000..b7d2c1fd13 --- /dev/null +++ b/assets/xml/objects/object_obj_yasi.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_okuta.xml b/assets/xml/objects/object_okuta.xml new file mode 100644 index 0000000000..0eebb587e1 --- /dev/null +++ b/assets/xml/objects/object_okuta.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_omoya_obj.xml b/assets/xml/objects/object_omoya_obj.xml new file mode 100644 index 0000000000..85389f314f --- /dev/null +++ b/assets/xml/objects/object_omoya_obj.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_open_obj.xml b/assets/xml/objects/object_open_obj.xml new file mode 100644 index 0000000000..ea1664a884 --- /dev/null +++ b/assets/xml/objects/object_open_obj.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_os_anime.xml b/assets/xml/objects/object_os_anime.xml new file mode 100644 index 0000000000..7957dd58d5 --- /dev/null +++ b/assets/xml/objects/object_os_anime.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_osn.xml b/assets/xml/objects/object_osn.xml new file mode 100644 index 0000000000..0994d057fd --- /dev/null +++ b/assets/xml/objects/object_osn.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ot.xml b/assets/xml/objects/object_ot.xml new file mode 100644 index 0000000000..1fb04a34a7 --- /dev/null +++ b/assets/xml/objects/object_ot.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_owl.xml b/assets/xml/objects/object_owl.xml new file mode 100644 index 0000000000..b35f38b0f9 --- /dev/null +++ b/assets/xml/objects/object_owl.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_oyu.xml b/assets/xml/objects/object_oyu.xml new file mode 100644 index 0000000000..aa762ce592 --- /dev/null +++ b/assets/xml/objects/object_oyu.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_pamera.xml b/assets/xml/objects/object_pamera.xml new file mode 100644 index 0000000000..901a7523bc --- /dev/null +++ b/assets/xml/objects/object_pamera.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ph.xml b/assets/xml/objects/object_ph.xml new file mode 100644 index 0000000000..df0cff73d3 --- /dev/null +++ b/assets/xml/objects/object_ph.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po.xml b/assets/xml/objects/object_po.xml new file mode 100644 index 0000000000..5d66d380cd --- /dev/null +++ b/assets/xml/objects/object_po.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po_composer.xml b/assets/xml/objects/object_po_composer.xml new file mode 100644 index 0000000000..288dd41c31 --- /dev/null +++ b/assets/xml/objects/object_po_composer.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po_fusen.xml b/assets/xml/objects/object_po_fusen.xml new file mode 100644 index 0000000000..6dd6d1f9bb --- /dev/null +++ b/assets/xml/objects/object_po_fusen.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po_sisters.xml b/assets/xml/objects/object_po_sisters.xml new file mode 100644 index 0000000000..6004d6cbfa --- /dev/null +++ b/assets/xml/objects/object_po_sisters.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_posthouse_obj.xml b/assets/xml/objects/object_posthouse_obj.xml new file mode 100644 index 0000000000..8a324672be --- /dev/null +++ b/assets/xml/objects/object_posthouse_obj.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_pp.xml b/assets/xml/objects/object_pp.xml new file mode 100644 index 0000000000..63bf541cd0 --- /dev/null +++ b/assets/xml/objects/object_pp.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_pr.xml b/assets/xml/objects/object_pr.xml new file mode 100644 index 0000000000..27a03fdcf5 --- /dev/null +++ b/assets/xml/objects/object_pr.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ps.xml b/assets/xml/objects/object_ps.xml new file mode 100644 index 0000000000..9febc56609 --- /dev/null +++ b/assets/xml/objects/object_ps.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_pst.xml b/assets/xml/objects/object_pst.xml new file mode 100644 index 0000000000..9d62acba78 --- /dev/null +++ b/assets/xml/objects/object_pst.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_racetsubo.xml b/assets/xml/objects/object_racetsubo.xml new file mode 100644 index 0000000000..6558fcbe53 --- /dev/null +++ b/assets/xml/objects/object_racetsubo.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_raf.xml b/assets/xml/objects/object_raf.xml new file mode 100644 index 0000000000..df3d619d1c --- /dev/null +++ b/assets/xml/objects/object_raf.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_raillift.xml b/assets/xml/objects/object_raillift.xml new file mode 100644 index 0000000000..241a7346be --- /dev/null +++ b/assets/xml/objects/object_raillift.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_random_obj.xml b/assets/xml/objects/object_random_obj.xml new file mode 100644 index 0000000000..9b9986ca15 --- /dev/null +++ b/assets/xml/objects/object_random_obj.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_rat.xml b/assets/xml/objects/object_rat.xml new file mode 100644 index 0000000000..5c979b098c --- /dev/null +++ b/assets/xml/objects/object_rat.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rb.xml b/assets/xml/objects/object_rb.xml new file mode 100644 index 0000000000..3898e84176 --- /dev/null +++ b/assets/xml/objects/object_rb.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rd.xml b/assets/xml/objects/object_rd.xml new file mode 100644 index 0000000000..d9087282aa --- /dev/null +++ b/assets/xml/objects/object_rd.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_redead_obj.xml b/assets/xml/objects/object_redead_obj.xml new file mode 100644 index 0000000000..fd286d6e7b --- /dev/null +++ b/assets/xml/objects/object_redead_obj.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_rotlift.xml b/assets/xml/objects/object_rotlift.xml new file mode 100644 index 0000000000..403f7d3dd9 --- /dev/null +++ b/assets/xml/objects/object_rotlift.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rr.xml b/assets/xml/objects/object_rr.xml new file mode 100644 index 0000000000..dbdba55c54 --- /dev/null +++ b/assets/xml/objects/object_rr.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_rs.xml b/assets/xml/objects/object_rs.xml new file mode 100644 index 0000000000..5019d9631f --- /dev/null +++ b/assets/xml/objects/object_rs.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ru2.xml b/assets/xml/objects/object_ru2.xml new file mode 100644 index 0000000000..016a610e82 --- /dev/null +++ b/assets/xml/objects/object_ru2.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rz.xml b/assets/xml/objects/object_rz.xml new file mode 100644 index 0000000000..323393f87e --- /dev/null +++ b/assets/xml/objects/object_rz.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sb.xml b/assets/xml/objects/object_sb.xml new file mode 100644 index 0000000000..9fcd76a8f4 --- /dev/null +++ b/assets/xml/objects/object_sb.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sdn.xml b/assets/xml/objects/object_sdn.xml new file mode 100644 index 0000000000..9cc607047c --- /dev/null +++ b/assets/xml/objects/object_sdn.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_secom_obj.xml b/assets/xml/objects/object_secom_obj.xml new file mode 100644 index 0000000000..7b21783a33 --- /dev/null +++ b/assets/xml/objects/object_secom_obj.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sek.xml b/assets/xml/objects/object_sek.xml new file mode 100644 index 0000000000..e37af43802 --- /dev/null +++ b/assets/xml/objects/object_sek.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihig.xml b/assets/xml/objects/object_sekihig.xml new file mode 100644 index 0000000000..dab91d71b2 --- /dev/null +++ b/assets/xml/objects/object_sekihig.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihil.xml b/assets/xml/objects/object_sekihil.xml new file mode 100644 index 0000000000..e3c7bcc42d --- /dev/null +++ b/assets/xml/objects/object_sekihil.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihin.xml b/assets/xml/objects/object_sekihin.xml new file mode 100644 index 0000000000..f2982169bb --- /dev/null +++ b/assets/xml/objects/object_sekihin.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihiz.xml b/assets/xml/objects/object_sekihiz.xml new file mode 100644 index 0000000000..0f8ef7c43e --- /dev/null +++ b/assets/xml/objects/object_sekihiz.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_shn.xml b/assets/xml/objects/object_shn.xml new file mode 100644 index 0000000000..78cc77ca71 --- /dev/null +++ b/assets/xml/objects/object_shn.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sichitai_obj.xml b/assets/xml/objects/object_sichitai_obj.xml new file mode 100644 index 0000000000..f093778abd --- /dev/null +++ b/assets/xml/objects/object_sichitai_obj.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_sinkai_kabe.xml b/assets/xml/objects/object_sinkai_kabe.xml new file mode 100644 index 0000000000..96f8531ad0 --- /dev/null +++ b/assets/xml/objects/object_sinkai_kabe.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_skb.xml b/assets/xml/objects/object_skb.xml new file mode 100644 index 0000000000..cafba559ed --- /dev/null +++ b/assets/xml/objects/object_skb.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_slime.xml b/assets/xml/objects/object_slime.xml new file mode 100644 index 0000000000..f17633eff1 --- /dev/null +++ b/assets/xml/objects/object_slime.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_smtower.xml b/assets/xml/objects/object_smtower.xml new file mode 100644 index 0000000000..90ee5a13df --- /dev/null +++ b/assets/xml/objects/object_smtower.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_snowman.xml b/assets/xml/objects/object_snowman.xml new file mode 100644 index 0000000000..f92110b3ed --- /dev/null +++ b/assets/xml/objects/object_snowman.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_snowwd.xml b/assets/xml/objects/object_snowwd.xml new file mode 100644 index 0000000000..c61d07bebe --- /dev/null +++ b/assets/xml/objects/object_snowwd.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_spdweb.xml b/assets/xml/objects/object_spdweb.xml new file mode 100644 index 0000000000..6f54a482d2 --- /dev/null +++ b/assets/xml/objects/object_spdweb.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_spidertent.xml b/assets/xml/objects/object_spidertent.xml new file mode 100644 index 0000000000..d90bede678 --- /dev/null +++ b/assets/xml/objects/object_spidertent.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_spinyroll.xml b/assets/xml/objects/object_spinyroll.xml new file mode 100644 index 0000000000..d27386945a --- /dev/null +++ b/assets/xml/objects/object_spinyroll.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_spot11_obj.xml b/assets/xml/objects/object_spot11_obj.xml new file mode 100644 index 0000000000..c049bb3379 --- /dev/null +++ b/assets/xml/objects/object_spot11_obj.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ssh.xml b/assets/xml/objects/object_ssh.xml new file mode 100644 index 0000000000..e4072d79e4 --- /dev/null +++ b/assets/xml/objects/object_ssh.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_st.xml b/assets/xml/objects/object_st.xml new file mode 100644 index 0000000000..a7ce1418df --- /dev/null +++ b/assets/xml/objects/object_st.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sth.xml b/assets/xml/objects/object_sth.xml new file mode 100644 index 0000000000..7b6947b07c --- /dev/null +++ b/assets/xml/objects/object_sth.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_stk.xml b/assets/xml/objects/object_stk.xml new file mode 100644 index 0000000000..44a311dfbd --- /dev/null +++ b/assets/xml/objects/object_stk.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_stk2.xml b/assets/xml/objects/object_stk2.xml new file mode 100644 index 0000000000..fe62266a84 --- /dev/null +++ b/assets/xml/objects/object_stk2.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_stk3.xml b/assets/xml/objects/object_stk3.xml new file mode 100644 index 0000000000..dbd5da6523 --- /dev/null +++ b/assets/xml/objects/object_stk3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_stream.xml b/assets/xml/objects/object_stream.xml new file mode 100644 index 0000000000..ac73120799 --- /dev/null +++ b/assets/xml/objects/object_stream.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_syokudai.xml b/assets/xml/objects/object_syokudai.xml new file mode 100644 index 0000000000..83e4c34f33 --- /dev/null +++ b/assets/xml/objects/object_syokudai.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_syoten.xml b/assets/xml/objects/object_syoten.xml new file mode 100644 index 0000000000..9802f7701b --- /dev/null +++ b/assets/xml/objects/object_syoten.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tab.xml b/assets/xml/objects/object_tab.xml new file mode 100644 index 0000000000..52c3156a3c --- /dev/null +++ b/assets/xml/objects/object_tab.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_taisou.xml b/assets/xml/objects/object_taisou.xml new file mode 100644 index 0000000000..696285927f --- /dev/null +++ b/assets/xml/objects/object_taisou.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_takaraya_objects.xml b/assets/xml/objects/object_takaraya_objects.xml new file mode 100644 index 0000000000..4ce448c86a --- /dev/null +++ b/assets/xml/objects/object_takaraya_objects.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_tanron1.xml b/assets/xml/objects/object_tanron1.xml new file mode 100644 index 0000000000..99a39e534c --- /dev/null +++ b/assets/xml/objects/object_tanron1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_tanron2.xml b/assets/xml/objects/object_tanron2.xml new file mode 100644 index 0000000000..950621c192 --- /dev/null +++ b/assets/xml/objects/object_tanron2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tanron3.xml b/assets/xml/objects/object_tanron3.xml new file mode 100644 index 0000000000..05ef078d7c --- /dev/null +++ b/assets/xml/objects/object_tanron3.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tanron4.xml b/assets/xml/objects/object_tanron4.xml new file mode 100644 index 0000000000..7e48cdf0ec --- /dev/null +++ b/assets/xml/objects/object_tanron4.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tanron5.xml b/assets/xml/objects/object_tanron5.xml new file mode 100644 index 0000000000..e64a11d5db --- /dev/null +++ b/assets/xml/objects/object_tanron5.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_taru.xml b/assets/xml/objects/object_taru.xml new file mode 100644 index 0000000000..763fe1b2ec --- /dev/null +++ b/assets/xml/objects/object_taru.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_test3.xml b/assets/xml/objects/object_test3.xml new file mode 100644 index 0000000000..fc6e026a94 --- /dev/null +++ b/assets/xml/objects/object_test3.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_thiefbird.xml b/assets/xml/objects/object_thiefbird.xml new file mode 100644 index 0000000000..31f0213c54 --- /dev/null +++ b/assets/xml/objects/object_thiefbird.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tite.xml b/assets/xml/objects/object_tite.xml new file mode 100644 index 0000000000..2d57d1b47d --- /dev/null +++ b/assets/xml/objects/object_tite.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tk.xml b/assets/xml/objects/object_tk.xml new file mode 100644 index 0000000000..506f9b00af --- /dev/null +++ b/assets/xml/objects/object_tk.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tl.xml b/assets/xml/objects/object_tl.xml new file mode 100644 index 0000000000..656d707433 --- /dev/null +++ b/assets/xml/objects/object_tl.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tokei_step.xml b/assets/xml/objects/object_tokei_step.xml new file mode 100644 index 0000000000..fad13984a3 --- /dev/null +++ b/assets/xml/objects/object_tokei_step.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_tokei_tobira.xml b/assets/xml/objects/object_tokei_tobira.xml new file mode 100644 index 0000000000..cfa6175511 --- /dev/null +++ b/assets/xml/objects/object_tokei_tobira.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tokei_turret.xml b/assets/xml/objects/object_tokei_turret.xml new file mode 100644 index 0000000000..edca7c5c24 --- /dev/null +++ b/assets/xml/objects/object_tokei_turret.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_toryo.xml b/assets/xml/objects/object_toryo.xml new file mode 100644 index 0000000000..101db58395 --- /dev/null +++ b/assets/xml/objects/object_toryo.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_trap.xml b/assets/xml/objects/object_trap.xml new file mode 100644 index 0000000000..3afdf61d46 --- /dev/null +++ b/assets/xml/objects/object_trap.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_tree.xml b/assets/xml/objects/object_tree.xml new file mode 100644 index 0000000000..9d5fb66dd8 --- /dev/null +++ b/assets/xml/objects/object_tree.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_tro.xml b/assets/xml/objects/object_tro.xml new file mode 100644 index 0000000000..773182c588 --- /dev/null +++ b/assets/xml/objects/object_tro.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_trt.xml b/assets/xml/objects/object_trt.xml new file mode 100644 index 0000000000..ecde36e182 --- /dev/null +++ b/assets/xml/objects/object_trt.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tru.xml b/assets/xml/objects/object_tru.xml new file mode 100644 index 0000000000..34bc82f39b --- /dev/null +++ b/assets/xml/objects/object_tru.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tsn.xml b/assets/xml/objects/object_tsn.xml new file mode 100644 index 0000000000..63c03c84c3 --- /dev/null +++ b/assets/xml/objects/object_tsn.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tsubo.xml b/assets/xml/objects/object_tsubo.xml new file mode 100644 index 0000000000..46aacd873d --- /dev/null +++ b/assets/xml/objects/object_tsubo.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_twig.xml b/assets/xml/objects/object_twig.xml new file mode 100644 index 0000000000..7b9c6c1918 --- /dev/null +++ b/assets/xml/objects/object_twig.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_uch.xml b/assets/xml/objects/object_uch.xml new file mode 100644 index 0000000000..de16b0d7b8 --- /dev/null +++ b/assets/xml/objects/object_uch.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_um.xml b/assets/xml/objects/object_um.xml new file mode 100644 index 0000000000..693c704d33 --- /dev/null +++ b/assets/xml/objects/object_um.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_umajump.xml b/assets/xml/objects/object_umajump.xml new file mode 100644 index 0000000000..6d86b4298b --- /dev/null +++ b/assets/xml/objects/object_umajump.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_utubo.xml b/assets/xml/objects/object_utubo.xml new file mode 100644 index 0000000000..97a7095c9b --- /dev/null +++ b/assets/xml/objects/object_utubo.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_visiblock.xml b/assets/xml/objects/object_visiblock.xml new file mode 100644 index 0000000000..d714338fcd --- /dev/null +++ b/assets/xml/objects/object_visiblock.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_vm.xml b/assets/xml/objects/object_vm.xml new file mode 100644 index 0000000000..b07534c65c --- /dev/null +++ b/assets/xml/objects/object_vm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wallmaster.xml b/assets/xml/objects/object_wallmaster.xml new file mode 100644 index 0000000000..249af61eec --- /dev/null +++ b/assets/xml/objects/object_wallmaster.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_warp1.xml b/assets/xml/objects/object_warp1.xml new file mode 100644 index 0000000000..9324f1301c --- /dev/null +++ b/assets/xml/objects/object_warp1.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_warp_uzu.xml b/assets/xml/objects/object_warp_uzu.xml new file mode 100644 index 0000000000..4924c86ca3 --- /dev/null +++ b/assets/xml/objects/object_warp_uzu.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_water_effect.xml b/assets/xml/objects/object_water_effect.xml new file mode 100644 index 0000000000..e3cd9ec27b --- /dev/null +++ b/assets/xml/objects/object_water_effect.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wdhand.xml b/assets/xml/objects/object_wdhand.xml new file mode 100644 index 0000000000..22e12cfa08 --- /dev/null +++ b/assets/xml/objects/object_wdhand.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wdor01.xml b/assets/xml/objects/object_wdor01.xml new file mode 100644 index 0000000000..ffc3327bba --- /dev/null +++ b/assets/xml/objects/object_wdor01.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor02.xml b/assets/xml/objects/object_wdor02.xml new file mode 100644 index 0000000000..9cb35ddb82 --- /dev/null +++ b/assets/xml/objects/object_wdor02.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor03.xml b/assets/xml/objects/object_wdor03.xml new file mode 100644 index 0000000000..c23f870377 --- /dev/null +++ b/assets/xml/objects/object_wdor03.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor04.xml b/assets/xml/objects/object_wdor04.xml new file mode 100644 index 0000000000..040df15980 --- /dev/null +++ b/assets/xml/objects/object_wdor04.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor05.xml b/assets/xml/objects/object_wdor05.xml new file mode 100644 index 0000000000..f8fda23221 --- /dev/null +++ b/assets/xml/objects/object_wdor05.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wf.xml b/assets/xml/objects/object_wf.xml new file mode 100644 index 0000000000..98dd21ed58 --- /dev/null +++ b/assets/xml/objects/object_wf.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wiz.xml b/assets/xml/objects/object_wiz.xml new file mode 100644 index 0000000000..6a27c2ba9e --- /dev/null +++ b/assets/xml/objects/object_wiz.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wood02.xml b/assets/xml/objects/object_wood02.xml new file mode 100644 index 0000000000..6ef693f349 --- /dev/null +++ b/assets/xml/objects/object_wood02.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_yabusame_point.xml b/assets/xml/objects/object_yabusame_point.xml new file mode 100644 index 0000000000..856d94cfed --- /dev/null +++ b/assets/xml/objects/object_yabusame_point.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_yado_obj.xml b/assets/xml/objects/object_yado_obj.xml new file mode 100644 index 0000000000..d5d0467d49 --- /dev/null +++ b/assets/xml/objects/object_yado_obj.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_yb.xml b/assets/xml/objects/object_yb.xml new file mode 100644 index 0000000000..8cf61e347c --- /dev/null +++ b/assets/xml/objects/object_yb.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_yukimura_obj.xml b/assets/xml/objects/object_yukimura_obj.xml new file mode 100644 index 0000000000..2099f807ae --- /dev/null +++ b/assets/xml/objects/object_yukimura_obj.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_yukiyama.xml b/assets/xml/objects/object_yukiyama.xml new file mode 100644 index 0000000000..5e7215f82d --- /dev/null +++ b/assets/xml/objects/object_yukiyama.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zg.xml b/assets/xml/objects/object_zg.xml new file mode 100644 index 0000000000..e5cb1dd5d5 --- /dev/null +++ b/assets/xml/objects/object_zg.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_zl1.xml b/assets/xml/objects/object_zl1.xml new file mode 100644 index 0000000000..759b358678 --- /dev/null +++ b/assets/xml/objects/object_zl1.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zl4.xml b/assets/xml/objects/object_zl4.xml new file mode 100644 index 0000000000..f13487f981 --- /dev/null +++ b/assets/xml/objects/object_zl4.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zm.xml b/assets/xml/objects/object_zm.xml new file mode 100644 index 0000000000..c5511f6b2e --- /dev/null +++ b/assets/xml/objects/object_zm.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zo.xml b/assets/xml/objects/object_zo.xml new file mode 100644 index 0000000000..4462024438 --- /dev/null +++ b/assets/xml/objects/object_zo.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zob.xml b/assets/xml/objects/object_zob.xml new file mode 100644 index 0000000000..22400d46ef --- /dev/null +++ b/assets/xml/objects/object_zob.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zod.xml b/assets/xml/objects/object_zod.xml new file mode 100644 index 0000000000..f1152e2ac1 --- /dev/null +++ b/assets/xml/objects/object_zod.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zog.xml b/assets/xml/objects/object_zog.xml new file mode 100644 index 0000000000..aae7b0381f --- /dev/null +++ b/assets/xml/objects/object_zog.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zoraband.xml b/assets/xml/objects/object_zoraband.xml new file mode 100644 index 0000000000..53a3d5a7b8 --- /dev/null +++ b/assets/xml/objects/object_zoraband.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_zoraegg.xml b/assets/xml/objects/object_zoraegg.xml new file mode 100644 index 0000000000..c527fe618a --- /dev/null +++ b/assets/xml/objects/object_zoraegg.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zos.xml b/assets/xml/objects/object_zos.xml new file mode 100644 index 0000000000..7a25eb338d --- /dev/null +++ b/assets/xml/objects/object_zos.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zov.xml b/assets/xml/objects/object_zov.xml new file mode 100644 index 0000000000..17d6382a95 --- /dev/null +++ b/assets/xml/objects/object_zov.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/z64animation.h b/include/z64animation.h index abd95423bd..8d6df14c84 100644 --- a/include/z64animation.h +++ b/include/z64animation.h @@ -49,6 +49,14 @@ typedef struct { /* 0x08 */ Gfx* dLists[2]; // Near and far } LodLimb; // size = 0x10 +typedef struct { + /* 0x00 */ Vec3s jointPos; // Root is position in model space, children are relative to parent + /* 0x06 */ u8 child; + /* 0x07 */ u8 sibling; + /* 0x08 */ s32 unk_8; // Type of data contained in segment + /* 0x0C */ void* segment; // Segment address of data. Currently unclear what. +} SkinLimb; // size = 0x10 + // Model has limbs with only rigid meshes typedef struct { /* 0x00 */ void** segment; @@ -271,6 +279,43 @@ typedef s32 (*OverrideCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeC typedef void (*PostCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeCurve* skelCuve, s32 limbIndex, struct Actor* actor); +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u16 unk_0; + /* 0x002 */ s16 unk_2; + /* 0x004 */ s16 unk_4; + /* 0x006 */ s8 unk_6; + /* 0x007 */ s8 unk_7; + /* 0x008 */ s8 unk_8; + /* 0x009 */ u8 unk_9; +} Struct_800A57C0; // size = 0xA + +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u8 unk_0; + /* 0x002 */ s16 x; + /* 0x004 */ s16 y; + /* 0x006 */ s16 z; + /* 0x008 */ u8 unk_8; +} Struct_800A598C_2; // size = 0xA + +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u16 unk_0; + /* 0x002 */ u16 unk_2; + /* 0x004 */ u16 unk_4; + /* 0x008 */ Struct_800A57C0* unk_8; + /* 0x00C */ Struct_800A598C_2* unk_C; +} Struct_800A598C; // size = 0x10 + +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u16 unk_0; + /* 0x002 */ u16 unk_2; + /* 0x004 */ Struct_800A598C* unk_4; + /* 0x008 */ Gfx* unk_8; +} Struct_800A5E28; // size = 0xC + typedef struct struct_80B8E1A8 { /* 0x00 */ AnimationHeader* animationSeg; /* 0x04 */ f32 playbackSpeed; diff --git a/spec b/spec index 48b1055db8..debfa85bf8 100644 --- a/spec +++ b/spec @@ -681,7 +681,9 @@ endseg beginseg name "buffers" flags NOLOAD - include "build/src/buffers/gfxbuffers.o" + include "build/src/buffers/gfxyield.o" + include "build/src/buffers/gfxstack.o" + include "build/src/buffers/gfxpools.o" include "build/data/code/buffers.bss.o" endseg @@ -5524,21 +5526,24 @@ beginseg name "gameplay_keep" compress romalign 0x1000 - include "build/baserom/gameplay_keep.o" + number 4 + include "build/assets/objects/gameplay_keep/gameplay_keep.o" endseg beginseg name "gameplay_field_keep" compress romalign 0x1000 - include "build/baserom/gameplay_field_keep.o" + number 5 + include "build/assets/objects/gameplay_field_keep/gameplay_field_keep.o" endseg beginseg name "gameplay_dangeon_keep" compress romalign 0x1000 - include "build/baserom/gameplay_dangeon_keep.o" + number 5 + include "build/assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.o" endseg beginseg @@ -5552,3227 +5557,3688 @@ beginseg name "object_link_boy" compress romalign 0x1000 - include "build/baserom/object_link_boy.o" + number 6 + include "build/assets/objects/object_link_boy/object_link_boy.o" endseg beginseg name "object_link_child" compress romalign 0x1000 - include "build/baserom/object_link_child.o" + number 6 + include "build/assets/objects/object_link_child/object_link_child.o" endseg beginseg name "object_link_goron" compress romalign 0x1000 - include "build/baserom/object_link_goron.o" + number 6 + include "build/assets/objects/object_link_goron/object_link_goron.o" endseg beginseg name "object_link_zora" compress romalign 0x1000 - include "build/baserom/object_link_zora.o" + number 6 + include "build/assets/objects/object_link_zora/object_link_zora.o" endseg beginseg name "object_link_nuts" compress romalign 0x1000 - include "build/baserom/object_link_nuts.o" + number 6 + include "build/assets/objects/object_link_nuts/object_link_nuts.o" endseg beginseg name "object_mask_ki_tan" compress romalign 0x1000 - include "build/baserom/object_mask_ki_tan.o" + number 10 + include "build/assets/objects/object_mask_ki_tan/object_mask_ki_tan.o" endseg beginseg name "object_mask_rabit" compress romalign 0x1000 - include "build/baserom/object_mask_rabit.o" + number 10 + include "build/assets/objects/object_mask_rabit/object_mask_rabit.o" endseg beginseg name "object_mask_skj" compress romalign 0x1000 - include "build/baserom/object_mask_skj.o" + number 10 + include "build/assets/objects/object_mask_skj/object_mask_skj.o" endseg beginseg name "object_mask_truth" compress romalign 0x1000 - include "build/baserom/object_mask_truth.o" + number 10 + include "build/assets/objects/object_mask_truth/object_mask_truth.o" endseg beginseg name "object_mask_gibudo" compress romalign 0x1000 - include "build/baserom/object_mask_gibudo.o" + number 10 + include "build/assets/objects/object_mask_gibudo/object_mask_gibudo.o" endseg beginseg name "object_mask_json" compress romalign 0x1000 - include "build/baserom/object_mask_json.o" + number 10 + include "build/assets/objects/object_mask_json/object_mask_json.o" endseg beginseg name "object_mask_kerfay" compress romalign 0x1000 - include "build/baserom/object_mask_kerfay.o" + number 10 + include "build/assets/objects/object_mask_kerfay/object_mask_kerfay.o" endseg beginseg name "object_mask_bigelf" compress romalign 0x1000 - include "build/baserom/object_mask_bigelf.o" + number 10 + include "build/assets/objects/object_mask_bigelf/object_mask_bigelf.o" endseg beginseg name "object_mask_kyojin" compress romalign 0x1000 - include "build/baserom/object_mask_kyojin.o" + number 10 + include "build/assets/objects/object_mask_kyojin/object_mask_kyojin.o" endseg beginseg name "object_mask_romerny" compress romalign 0x1000 - include "build/baserom/object_mask_romerny.o" + number 10 + include "build/assets/objects/object_mask_romerny/object_mask_romerny.o" endseg beginseg name "object_mask_posthat" compress romalign 0x1000 - include "build/baserom/object_mask_posthat.o" + number 10 + include "build/assets/objects/object_mask_posthat/object_mask_posthat.o" endseg beginseg name "object_mask_zacho" compress romalign 0x1000 - include "build/baserom/object_mask_zacho.o" + number 10 + include "build/assets/objects/object_mask_zacho/object_mask_zacho.o" endseg beginseg name "object_mask_stone" compress romalign 0x1000 - include "build/baserom/object_mask_stone.o" + number 10 + include "build/assets/objects/object_mask_stone/object_mask_stone.o" endseg beginseg name "object_mask_bree" compress romalign 0x1000 - include "build/baserom/object_mask_bree.o" + number 10 + include "build/assets/objects/object_mask_bree/object_mask_bree.o" endseg beginseg name "object_mask_gero" compress romalign 0x1000 - include "build/baserom/object_mask_gero.o" + number 10 + include "build/assets/objects/object_mask_gero/object_mask_gero.o" endseg beginseg name "object_mask_yofukasi" compress romalign 0x1000 - include "build/baserom/object_mask_yofukasi.o" + number 10 + include "build/assets/objects/object_mask_yofukasi/object_mask_yofukasi.o" endseg beginseg name "object_mask_meoto" compress romalign 0x1000 - include "build/baserom/object_mask_meoto.o" + number 10 + include "build/assets/objects/object_mask_meoto/object_mask_meoto.o" endseg beginseg name "object_mask_dancer" compress romalign 0x1000 - include "build/baserom/object_mask_dancer.o" + number 10 + include "build/assets/objects/object_mask_dancer/object_mask_dancer.o" endseg beginseg name "object_mask_bakuretu" compress romalign 0x1000 - include "build/baserom/object_mask_bakuretu.o" + number 10 + include "build/assets/objects/object_mask_bakuretu/object_mask_bakuretu.o" endseg beginseg name "object_mask_bu_san" compress romalign 0x1000 - include "build/baserom/object_mask_bu_san.o" + number 10 + include "build/assets/objects/object_mask_bu_san/object_mask_bu_san.o" endseg beginseg name "object_mask_goron" compress romalign 0x1000 - include "build/baserom/object_mask_goron.o" + number 10 + include "build/assets/objects/object_mask_goron/object_mask_goron.o" endseg beginseg name "object_mask_zora" compress romalign 0x1000 - include "build/baserom/object_mask_zora.o" + number 10 + include "build/assets/objects/object_mask_zora/object_mask_zora.o" endseg beginseg name "object_mask_nuts" compress romalign 0x1000 - include "build/baserom/object_mask_nuts.o" + number 10 + include "build/assets/objects/object_mask_nuts/object_mask_nuts.o" endseg beginseg name "object_mask_boy" compress romalign 0x1000 - include "build/baserom/object_mask_boy.o" + number 10 + include "build/assets/objects/object_mask_boy/object_mask_boy.o" endseg beginseg name "object_box" compress romalign 0x1000 - include "build/baserom/object_box.o" + number 6 + include "build/assets/objects/object_box/object_box.o" endseg beginseg name "object_okuta" compress romalign 0x1000 - include "build/baserom/object_okuta.o" + number 6 + include "build/assets/objects/object_okuta/object_okuta.o" endseg beginseg name "object_wallmaster" compress romalign 0x1000 - include "build/baserom/object_wallmaster.o" + number 6 + include "build/assets/objects/object_wallmaster/object_wallmaster.o" endseg beginseg name "object_dy_obj" compress romalign 0x1000 - include "build/baserom/object_dy_obj.o" + number 6 + include "build/assets/objects/object_dy_obj/object_dy_obj.o" endseg beginseg name "object_firefly" compress romalign 0x1000 - include "build/baserom/object_firefly.o" + number 6 + include "build/assets/objects/object_firefly/object_firefly.o" endseg beginseg name "object_dodongo" compress romalign 0x1000 - include "build/baserom/object_dodongo.o" + number 6 + include "build/assets/objects/object_dodongo/object_dodongo.o" endseg beginseg name "object_niw" compress romalign 0x1000 - include "build/baserom/object_niw.o" + number 6 + include "build/assets/objects/object_niw/object_niw.o" endseg beginseg name "object_tite" compress romalign 0x1000 - include "build/baserom/object_tite.o" + number 6 + include "build/assets/objects/object_tite/object_tite.o" endseg beginseg name "object_ph" compress romalign 0x1000 - include "build/baserom/object_ph.o" + number 6 + include "build/assets/objects/object_ph/object_ph.o" endseg beginseg name "object_dinofos" compress romalign 0x1000 - include "build/baserom/object_dinofos.o" + number 6 + include "build/assets/objects/object_dinofos/object_dinofos.o" endseg beginseg name "object_zl1" compress romalign 0x1000 - include "build/baserom/object_zl1.o" + number 6 + include "build/assets/objects/object_zl1/object_zl1.o" endseg beginseg name "object_bubble" compress romalign 0x1000 - include "build/baserom/object_bubble.o" + number 6 + include "build/assets/objects/object_bubble/object_bubble.o" endseg beginseg name "object_test3" compress romalign 0x1000 - include "build/baserom/object_test3.o" + number 6 + include "build/assets/objects/object_test3/object_test3.o" endseg beginseg name "object_famos" compress romalign 0x1000 - include "build/baserom/object_famos.o" + number 6 + include "build/assets/objects/object_famos/object_famos.o" endseg beginseg name "object_st" compress romalign 0x1000 - include "build/baserom/object_st.o" + number 6 + include "build/assets/objects/object_st/object_st.o" endseg beginseg name "object_thiefbird" compress romalign 0x1000 - include "build/baserom/object_thiefbird.o" + number 6 + include "build/assets/objects/object_thiefbird/object_thiefbird.o" endseg beginseg name "object_bombf" compress romalign 0x1000 - include "build/baserom/object_bombf.o" + number 6 + include "build/assets/objects/object_bombf/object_bombf.o" endseg beginseg name "object_am" compress romalign 0x1000 - include "build/baserom/object_am.o" + number 6 + include "build/assets/objects/object_am/object_am.o" endseg beginseg name "object_dekubaba" compress romalign 0x1000 - include "build/baserom/object_dekubaba.o" + number 6 + include "build/assets/objects/object_dekubaba/object_dekubaba.o" endseg beginseg name "object_warp1" compress romalign 0x1000 - include "build/baserom/object_warp1.o" + number 6 + include "build/assets/objects/object_warp1/object_warp1.o" endseg beginseg name "object_b_heart" compress romalign 0x1000 - include "build/baserom/object_b_heart.o" + number 6 + include "build/assets/objects/object_b_heart/object_b_heart.o" endseg beginseg name "object_dekunuts" compress romalign 0x1000 - include "build/baserom/object_dekunuts.o" + number 6 + include "build/assets/objects/object_dekunuts/object_dekunuts.o" endseg beginseg name "object_bb" compress romalign 0x1000 - include "build/baserom/object_bb.o" + number 6 + include "build/assets/objects/object_bb/object_bb.o" endseg beginseg name "object_death" compress romalign 0x1000 - include "build/baserom/object_death.o" + number 6 + include "build/assets/objects/object_death/object_death.o" endseg beginseg name "object_hata" compress romalign 0x1000 - include "build/baserom/object_hata.o" + number 6 + include "build/assets/objects/object_hata/object_hata.o" endseg beginseg name "object_wood02" compress romalign 0x1000 - include "build/baserom/object_wood02.o" + number 6 + include "build/assets/objects/object_wood02/object_wood02.o" endseg beginseg name "object_trap" compress romalign 0x1000 - include "build/baserom/object_trap.o" + number 6 + include "build/assets/objects/object_trap/object_trap.o" endseg beginseg name "object_vm" compress romalign 0x1000 - include "build/baserom/object_vm.o" + number 6 + include "build/assets/objects/object_vm/object_vm.o" endseg beginseg name "object_efc_star_field" compress romalign 0x1000 - include "build/baserom/object_efc_star_field.o" + number 6 + include "build/assets/objects/object_efc_star_field/object_efc_star_field.o" endseg beginseg name "object_rd" compress romalign 0x1000 - include "build/baserom/object_rd.o" + number 6 + include "build/assets/objects/object_rd/object_rd.o" endseg beginseg name "object_yukimura_obj" compress romalign 0x1000 - include "build/baserom/object_yukimura_obj.o" + number 6 + include "build/assets/objects/object_yukimura_obj/object_yukimura_obj.o" endseg beginseg name "object_horse_link_child" compress romalign 0x1000 - include "build/baserom/object_horse_link_child.o" + number 6 + include "build/assets/objects/object_horse_link_child/object_horse_link_child.o" endseg beginseg name "object_syokudai" compress romalign 0x1000 - include "build/baserom/object_syokudai.o" + number 6 + include "build/assets/objects/object_syokudai/object_syokudai.o" endseg beginseg name "object_efc_tw" compress romalign 0x1000 - include "build/baserom/object_efc_tw.o" + number 6 + include "build/assets/objects/object_efc_tw/object_efc_tw.o" endseg beginseg name "object_gi_key" compress romalign 0x1000 - include "build/baserom/object_gi_key.o" + number 6 + include "build/assets/objects/object_gi_key/object_gi_key.o" endseg beginseg name "object_mir_ray" compress romalign 0x1000 - include "build/baserom/object_mir_ray.o" + number 6 + include "build/assets/objects/object_mir_ray/object_mir_ray.o" endseg beginseg name "object_ctower_rot" compress romalign 0x1000 - include "build/baserom/object_ctower_rot.o" + number 6 + include "build/assets/objects/object_ctower_rot/object_ctower_rot.o" endseg beginseg name "object_bdoor" compress romalign 0x1000 - include "build/baserom/object_bdoor.o" + number 6 + include "build/assets/objects/object_bdoor/object_bdoor.o" endseg beginseg name "object_sb" compress romalign 0x1000 - include "build/baserom/object_sb.o" + number 6 + include "build/assets/objects/object_sb/object_sb.o" endseg beginseg name "object_gi_melody" compress romalign 0x1000 - include "build/baserom/object_gi_melody.o" + number 6 + include "build/assets/objects/object_gi_melody/object_gi_melody.o" endseg beginseg name "object_gi_heart" compress romalign 0x1000 - include "build/baserom/object_gi_heart.o" + number 6 + include "build/assets/objects/object_gi_heart/object_gi_heart.o" endseg beginseg name "object_gi_compass" compress romalign 0x1000 - include "build/baserom/object_gi_compass.o" + number 6 + include "build/assets/objects/object_gi_compass/object_gi_compass.o" endseg beginseg name "object_gi_bosskey" compress romalign 0x1000 - include "build/baserom/object_gi_bosskey.o" + number 6 + include "build/assets/objects/object_gi_bosskey/object_gi_bosskey.o" endseg beginseg name "object_gi_nuts" compress romalign 0x1000 - include "build/baserom/object_gi_nuts.o" + number 6 + include "build/assets/objects/object_gi_nuts/object_gi_nuts.o" endseg beginseg name "object_gi_hearts" compress romalign 0x1000 - include "build/baserom/object_gi_hearts.o" + number 6 + include "build/assets/objects/object_gi_hearts/object_gi_hearts.o" endseg beginseg name "object_gi_arrowcase" compress romalign 0x1000 - include "build/baserom/object_gi_arrowcase.o" + number 6 + include "build/assets/objects/object_gi_arrowcase/object_gi_arrowcase.o" endseg beginseg name "object_gi_bombpouch" compress romalign 0x1000 - include "build/baserom/object_gi_bombpouch.o" + number 6 + include "build/assets/objects/object_gi_bombpouch/object_gi_bombpouch.o" endseg beginseg name "object_in" compress romalign 0x1000 - include "build/baserom/object_in.o" + number 6 + include "build/assets/objects/object_in/object_in.o" endseg beginseg name "object_os_anime" compress romalign 0x1000 - include "build/baserom/object_os_anime.o" + number 6 + include "build/assets/objects/object_os_anime/object_os_anime.o" endseg beginseg name "object_gi_bottle" compress romalign 0x1000 - include "build/baserom/object_gi_bottle.o" + number 6 + include "build/assets/objects/object_gi_bottle/object_gi_bottle.o" endseg beginseg name "object_gi_stick" compress romalign 0x1000 - include "build/baserom/object_gi_stick.o" + number 6 + include "build/assets/objects/object_gi_stick/object_gi_stick.o" endseg beginseg name "object_gi_map" compress romalign 0x1000 - include "build/baserom/object_gi_map.o" + number 6 + include "build/assets/objects/object_gi_map/object_gi_map.o" endseg beginseg name "object_oF1d_map" compress romalign 0x1000 - include "build/baserom/object_oF1d_map.o" + number 6 + include "build/assets/objects/object_oF1d_map/object_oF1d_map.o" endseg beginseg name "object_ru2" compress romalign 0x1000 - include "build/baserom/object_ru2.o" + number 6 + include "build/assets/objects/object_ru2/object_ru2.o" endseg beginseg name "object_gi_magicpot" compress romalign 0x1000 - include "build/baserom/object_gi_magicpot.o" + number 6 + include "build/assets/objects/object_gi_magicpot/object_gi_magicpot.o" endseg beginseg name "object_gi_bomb_1" compress romalign 0x1000 - include "build/baserom/object_gi_bomb_1.o" + number 6 + include "build/assets/objects/object_gi_bomb_1/object_gi_bomb_1.o" endseg beginseg name "object_ma2" compress romalign 0x1000 - include "build/baserom/object_ma2.o" + number 6 + include "build/assets/objects/object_ma2/object_ma2.o" endseg beginseg name "object_gi_purse" compress romalign 0x1000 - include "build/baserom/object_gi_purse.o" + number 6 + include "build/assets/objects/object_gi_purse/object_gi_purse.o" endseg beginseg name "object_rr" compress romalign 0x1000 - include "build/baserom/object_rr.o" + number 6 + include "build/assets/objects/object_rr/object_rr.o" endseg beginseg name "object_gi_arrow" compress romalign 0x1000 - include "build/baserom/object_gi_arrow.o" + number 6 + include "build/assets/objects/object_gi_arrow/object_gi_arrow.o" endseg beginseg name "object_gi_bomb_2" compress romalign 0x1000 - include "build/baserom/object_gi_bomb_2.o" + number 6 + include "build/assets/objects/object_gi_bomb_2/object_gi_bomb_2.o" endseg beginseg name "object_gi_shield_2" compress romalign 0x1000 - include "build/baserom/object_gi_shield_2.o" + number 6 + include "build/assets/objects/object_gi_shield_2/object_gi_shield_2.o" endseg beginseg name "object_gi_hookshot" compress romalign 0x1000 - include "build/baserom/object_gi_hookshot.o" + number 6 + include "build/assets/objects/object_gi_hookshot/object_gi_hookshot.o" endseg beginseg name "object_gi_ocarina" compress romalign 0x1000 - include "build/baserom/object_gi_ocarina.o" + number 6 + include "build/assets/objects/object_gi_ocarina/object_gi_ocarina.o" endseg beginseg name "object_gi_milk" compress romalign 0x1000 - include "build/baserom/object_gi_milk.o" + number 6 + include "build/assets/objects/object_gi_milk/object_gi_milk.o" endseg beginseg name "object_ma1" compress romalign 0x1000 - include "build/baserom/object_ma1.o" + number 6 + include "build/assets/objects/object_ma1/object_ma1.o" endseg beginseg name "object_ny" compress romalign 0x1000 - include "build/baserom/object_ny.o" + number 6 + include "build/assets/objects/object_ny/object_ny.o" endseg beginseg name "object_fr" compress romalign 0x1000 - include "build/baserom/object_fr.o" + number 6 + include "build/assets/objects/object_fr/object_fr.o" endseg beginseg name "object_gi_bow" compress romalign 0x1000 - include "build/baserom/object_gi_bow.o" + number 6 + include "build/assets/objects/object_gi_bow/object_gi_bow.o" endseg beginseg name "object_gi_glasses" compress romalign 0x1000 - include "build/baserom/object_gi_glasses.o" + number 6 + include "build/assets/objects/object_gi_glasses/object_gi_glasses.o" endseg beginseg name "object_gi_liquid" compress romalign 0x1000 - include "build/baserom/object_gi_liquid.o" + number 6 + include "build/assets/objects/object_gi_liquid/object_gi_liquid.o" endseg beginseg name "object_ani" compress romalign 0x1000 - include "build/baserom/object_ani.o" + number 6 + include "build/assets/objects/object_ani/object_ani.o" endseg beginseg name "object_gi_shield_3" compress romalign 0x1000 - include "build/baserom/object_gi_shield_3.o" + number 6 + include "build/assets/objects/object_gi_shield_3/object_gi_shield_3.o" endseg beginseg name "object_gi_bean" compress romalign 0x1000 - include "build/baserom/object_gi_bean.o" + number 6 + include "build/assets/objects/object_gi_bean/object_gi_bean.o" endseg beginseg name "object_gi_fish" compress romalign 0x1000 - include "build/baserom/object_gi_fish.o" + number 6 + include "build/assets/objects/object_gi_fish/object_gi_fish.o" endseg beginseg name "object_gi_longsword" compress romalign 0x1000 - include "build/baserom/object_gi_longsword.o" + number 6 + include "build/assets/objects/object_gi_longsword/object_gi_longsword.o" endseg beginseg name "object_zo" compress romalign 0x1000 - include "build/baserom/object_zo.o" + number 6 + include "build/assets/objects/object_zo/object_zo.o" endseg beginseg name "object_umajump" compress romalign 0x1000 - include "build/baserom/object_umajump.o" + number 6 + include "build/assets/objects/object_umajump/object_umajump.o" endseg beginseg name "object_mastergolon" compress romalign 0x1000 - include "build/baserom/object_mastergolon.o" + number 6 + include "build/assets/objects/object_mastergolon/object_mastergolon.o" endseg beginseg name "object_masterzoora" compress romalign 0x1000 - include "build/baserom/object_masterzoora.o" + number 6 + include "build/assets/objects/object_masterzoora/object_masterzoora.o" endseg beginseg name "object_aob" compress romalign 0x1000 - include "build/baserom/object_aob.o" + number 6 + include "build/assets/objects/object_aob/object_aob.o" endseg beginseg name "object_ik" compress romalign 0x1000 - include "build/baserom/object_ik.o" + number 6 + include "build/assets/objects/object_ik/object_ik.o" endseg beginseg name "object_ahg" compress romalign 0x1000 - include "build/baserom/object_ahg.o" + number 6 + include "build/assets/objects/object_ahg/object_ahg.o" endseg beginseg name "object_cne" compress romalign 0x1000 - include "build/baserom/object_cne.o" + number 6 + include "build/assets/objects/object_cne/object_cne.o" endseg beginseg name "object_bji" compress romalign 0x1000 - include "build/baserom/object_bji.o" + number 6 + include "build/assets/objects/object_bji/object_bji.o" endseg beginseg name "object_bba" compress romalign 0x1000 - include "build/baserom/object_bba.o" + number 6 + include "build/assets/objects/object_bba/object_bba.o" endseg beginseg name "object_an1" compress romalign 0x1000 - include "build/baserom/object_an1.o" + number 6 + include "build/assets/objects/object_an1/object_an1.o" endseg beginseg name "object_boj" compress romalign 0x1000 - include "build/baserom/object_boj.o" + number 6 + include "build/assets/objects/object_boj/object_boj.o" endseg beginseg name "object_fz" compress romalign 0x1000 - include "build/baserom/object_fz.o" + number 6 + include "build/assets/objects/object_fz/object_fz.o" endseg beginseg name "object_bob" compress romalign 0x1000 - include "build/baserom/object_bob.o" + number 6 + include "build/assets/objects/object_bob/object_bob.o" endseg beginseg name "object_ge1" compress romalign 0x1000 - include "build/baserom/object_ge1.o" + number 6 + include "build/assets/objects/object_ge1/object_ge1.o" endseg beginseg name "object_yabusame_point" compress romalign 0x1000 - include "build/baserom/object_yabusame_point.o" + number 6 + include "build/assets/objects/object_yabusame_point/object_yabusame_point.o" endseg beginseg name "object_d_hsblock" compress romalign 0x1000 - include "build/baserom/object_d_hsblock.o" + number 6 + include "build/assets/objects/object_d_hsblock/object_d_hsblock.o" endseg beginseg name "object_d_lift" compress romalign 0x1000 - include "build/baserom/object_d_lift.o" + number 6 + include "build/assets/objects/object_d_lift/object_d_lift.o" endseg beginseg name "object_mamenoki" compress romalign 0x1000 - include "build/baserom/object_mamenoki.o" + number 6 + include "build/assets/objects/object_mamenoki/object_mamenoki.o" endseg beginseg name "object_goroiwa" compress romalign 0x1000 - include "build/baserom/object_goroiwa.o" + number 6 + include "build/assets/objects/object_goroiwa/object_goroiwa.o" endseg beginseg name "object_toryo" compress romalign 0x1000 - include "build/baserom/object_toryo.o" + number 6 + include "build/assets/objects/object_toryo/object_toryo.o" endseg beginseg name "object_daiku" compress romalign 0x1000 - include "build/baserom/object_daiku.o" + number 6 + include "build/assets/objects/object_daiku/object_daiku.o" endseg beginseg name "object_nwc" compress romalign 0x1000 - include "build/baserom/object_nwc.o" + number 6 + include "build/assets/objects/object_nwc/object_nwc.o" endseg beginseg name "object_gm" compress romalign 0x1000 - include "build/baserom/object_gm.o" + number 6 + include "build/assets/objects/object_gm/object_gm.o" endseg beginseg name "object_ms" compress romalign 0x1000 - include "build/baserom/object_ms.o" + number 6 + include "build/assets/objects/object_ms/object_ms.o" endseg beginseg name "object_hs" compress romalign 0x1000 - include "build/baserom/object_hs.o" + number 6 + include "build/assets/objects/object_hs/object_hs.o" endseg beginseg name "object_lightswitch" compress romalign 0x1000 - include "build/baserom/object_lightswitch.o" + number 6 + include "build/assets/objects/object_lightswitch/object_lightswitch.o" endseg beginseg name "object_kusa" compress romalign 0x1000 - include "build/baserom/object_kusa.o" + number 6 + include "build/assets/objects/object_kusa/object_kusa.o" endseg beginseg name "object_tsubo" compress romalign 0x1000 - include "build/baserom/object_tsubo.o" + number 6 + include "build/assets/objects/object_tsubo/object_tsubo.o" endseg beginseg name "object_kanban" compress romalign 0x1000 - include "build/baserom/object_kanban.o" + number 6 + include "build/assets/objects/object_kanban/object_kanban.o" endseg beginseg name "object_owl" compress romalign 0x1000 - include "build/baserom/object_owl.o" + number 6 + include "build/assets/objects/object_owl/object_owl.o" endseg beginseg name "object_mk" compress romalign 0x1000 - include "build/baserom/object_mk.o" + number 6 + include "build/assets/objects/object_mk/object_mk.o" endseg beginseg name "object_fu" compress romalign 0x1000 - include "build/baserom/object_fu.o" + number 6 + include "build/assets/objects/object_fu/object_fu.o" endseg beginseg name "object_gi_ki_tan_mask" compress romalign 0x1000 - include "build/baserom/object_gi_ki_tan_mask.o" + number 6 + include "build/assets/objects/object_gi_ki_tan_mask/object_gi_ki_tan_mask.o" endseg beginseg name "object_gi_mask18" compress romalign 0x1000 - include "build/baserom/object_gi_mask18.o" + number 6 + include "build/assets/objects/object_gi_mask18/object_gi_mask18.o" endseg beginseg name "object_gi_rabit_mask" compress romalign 0x1000 - include "build/baserom/object_gi_rabit_mask.o" + number 6 + include "build/assets/objects/object_gi_rabit_mask/object_gi_rabit_mask.o" endseg beginseg name "object_gi_truth_mask" compress romalign 0x1000 - include "build/baserom/object_gi_truth_mask.o" + number 6 + include "build/assets/objects/object_gi_truth_mask/object_gi_truth_mask.o" endseg beginseg name "object_stream" compress romalign 0x1000 - include "build/baserom/object_stream.o" + number 6 + include "build/assets/objects/object_stream/object_stream.o" endseg beginseg name "object_mm" compress romalign 0x1000 - include "build/baserom/object_mm.o" + number 6 + include "build/assets/objects/object_mm/object_mm.o" endseg beginseg name "object_js" compress romalign 0x1000 - include "build/baserom/object_js.o" + number 6 + include "build/assets/objects/object_js/object_js.o" endseg beginseg name "object_cs" compress romalign 0x1000 - include "build/baserom/object_cs.o" + number 6 + include "build/assets/objects/object_cs/object_cs.o" endseg beginseg name "object_gi_soldout" compress romalign 0x1000 - include "build/baserom/object_gi_soldout.o" + number 6 + include "build/assets/objects/object_gi_soldout/object_gi_soldout.o" endseg beginseg name "object_mag" compress romalign 0x1000 - include "build/baserom/object_mag.o" + number 6 + include "build/assets/objects/object_mag/object_mag.o" endseg beginseg name "object_gi_golonmask" compress romalign 0x1000 - include "build/baserom/object_gi_golonmask.o" + number 6 + include "build/assets/objects/object_gi_golonmask/object_gi_golonmask.o" endseg beginseg name "object_gi_zoramask" compress romalign 0x1000 - include "build/baserom/object_gi_zoramask.o" + number 6 + include "build/assets/objects/object_gi_zoramask/object_gi_zoramask.o" endseg beginseg name "object_ka" compress romalign 0x1000 - include "build/baserom/object_ka.o" + number 6 + include "build/assets/objects/object_ka/object_ka.o" endseg beginseg name "object_zg" compress romalign 0x1000 - include "build/baserom/object_zg.o" + number 6 + include "build/assets/objects/object_zg/object_zg.o" endseg beginseg name "object_gi_m_arrow" compress romalign 0x1000 - include "build/baserom/object_gi_m_arrow.o" + number 6 + include "build/assets/objects/object_gi_m_arrow/object_gi_m_arrow.o" endseg beginseg name "object_ds2" compress romalign 0x1000 - include "build/baserom/object_ds2.o" + number 6 + include "build/assets/objects/object_ds2/object_ds2.o" endseg beginseg name "object_fish" compress romalign 0x1000 - include "build/baserom/object_fish.o" + number 6 + include "build/assets/objects/object_fish/object_fish.o" endseg beginseg name "object_gi_sutaru" compress romalign 0x1000 - include "build/baserom/object_gi_sutaru.o" + number 6 + include "build/assets/objects/object_gi_sutaru/object_gi_sutaru.o" endseg beginseg name "object_ssh" compress romalign 0x1000 - include "build/baserom/object_ssh.o" + number 6 + include "build/assets/objects/object_ssh/object_ssh.o" endseg beginseg name "object_bigslime" compress romalign 0x1000 - include "build/baserom/object_bigslime.o" + number 6 + include "build/assets/objects/object_bigslime/object_bigslime.o" endseg beginseg name "object_bg" compress romalign 0x1000 - include "build/baserom/object_bg.o" + number 6 + include "build/assets/objects/object_bg/object_bg.o" endseg beginseg name "object_bombiwa" compress romalign 0x1000 - include "build/baserom/object_bombiwa.o" + number 6 + include "build/assets/objects/object_bombiwa/object_bombiwa.o" endseg beginseg name "object_hintnuts" compress romalign 0x1000 - include "build/baserom/object_hintnuts.o" + number 6 + include "build/assets/objects/object_hintnuts/object_hintnuts.o" endseg beginseg name "object_rs" compress romalign 0x1000 - include "build/baserom/object_rs.o" + number 6 + include "build/assets/objects/object_rs/object_rs.o" endseg beginseg name "object_gla" compress romalign 0x1000 - include "build/baserom/object_gla.o" + number 6 + include "build/assets/objects/object_gla/object_gla.o" endseg beginseg name "object_geldb" compress romalign 0x1000 - include "build/baserom/object_geldb.o" + number 6 + include "build/assets/objects/object_geldb/object_geldb.o" endseg beginseg name "object_dog" compress romalign 0x1000 - include "build/baserom/object_dog.o" + number 6 + include "build/assets/objects/object_dog/object_dog.o" endseg beginseg name "object_kibako2" compress romalign 0x1000 - include "build/baserom/object_kibako2.o" + number 6 + include "build/assets/objects/object_kibako2/object_kibako2.o" endseg beginseg name "object_dns" compress romalign 0x1000 - include "build/baserom/object_dns.o" + number 6 + include "build/assets/objects/object_dns/object_dns.o" endseg beginseg name "object_dnk" compress romalign 0x1000 - include "build/baserom/object_dnk.o" + number 6 + include "build/assets/objects/object_dnk/object_dnk.o" endseg beginseg name "object_gi_insect" compress romalign 0x1000 - include "build/baserom/object_gi_insect.o" + number 6 + include "build/assets/objects/object_gi_insect/object_gi_insect.o" endseg beginseg name "object_gi_ghost" compress romalign 0x1000 - include "build/baserom/object_gi_ghost.o" + number 6 + include "build/assets/objects/object_gi_ghost/object_gi_ghost.o" endseg beginseg name "object_gi_soul" compress romalign 0x1000 - include "build/baserom/object_gi_soul.o" + number 6 + include "build/assets/objects/object_gi_soul/object_gi_soul.o" endseg beginseg name "object_f40_obj" compress romalign 0x1000 - include "build/baserom/object_f40_obj.o" + number 6 + include "build/assets/objects/object_f40_obj/object_f40_obj.o" endseg beginseg name "object_gi_rupy" compress romalign 0x1000 - include "build/baserom/object_gi_rupy.o" + number 6 + include "build/assets/objects/object_gi_rupy/object_gi_rupy.o" endseg beginseg name "object_po_composer" compress romalign 0x1000 - include "build/baserom/object_po_composer.o" + number 6 + include "build/assets/objects/object_po_composer/object_po_composer.o" endseg beginseg name "object_mu" compress romalign 0x1000 - include "build/baserom/object_mu.o" + number 6 + include "build/assets/objects/object_mu/object_mu.o" endseg beginseg name "object_wf" compress romalign 0x1000 - include "build/baserom/object_wf.o" + number 6 + include "build/assets/objects/object_wf/object_wf.o" endseg beginseg name "object_skb" compress romalign 0x1000 - include "build/baserom/object_skb.o" + number 6 + include "build/assets/objects/object_skb/object_skb.o" endseg beginseg name "object_gs" compress romalign 0x1000 - include "build/baserom/object_gs.o" + number 6 + include "build/assets/objects/object_gs/object_gs.o" endseg beginseg name "object_ps" compress romalign 0x1000 - include "build/baserom/object_ps.o" + number 6 + include "build/assets/objects/object_ps/object_ps.o" endseg beginseg name "object_omoya_obj" compress romalign 0x1000 - include "build/baserom/object_omoya_obj.o" + number 6 + include "build/assets/objects/object_omoya_obj/object_omoya_obj.o" endseg beginseg name "object_crow" compress romalign 0x1000 - include "build/baserom/object_crow.o" + number 6 + include "build/assets/objects/object_crow/object_crow.o" endseg beginseg name "object_cow" compress romalign 0x1000 - include "build/baserom/object_cow.o" + number 6 + include "build/assets/objects/object_cow/object_cow.o" endseg beginseg name "object_gi_sword_1" compress romalign 0x1000 - include "build/baserom/object_gi_sword_1.o" + number 6 + include "build/assets/objects/object_gi_sword_1/object_gi_sword_1.o" endseg beginseg name "object_zl4" compress romalign 0x1000 - include "build/baserom/object_zl4.o" + number 6 + include "build/assets/objects/object_zl4/object_zl4.o" endseg beginseg name "object_grasshopper" compress romalign 0x1000 - include "build/baserom/object_grasshopper.o" + number 6 + include "build/assets/objects/object_grasshopper/object_grasshopper.o" endseg beginseg name "object_boyo" compress romalign 0x1000 - include "build/baserom/object_boyo.o" + number 6 + include "build/assets/objects/object_boyo/object_boyo.o" endseg beginseg name "object_fwall" compress romalign 0x1000 - include "build/baserom/object_fwall.o" + number 6 + include "build/assets/objects/object_fwall/object_fwall.o" endseg beginseg name "object_jso" compress romalign 0x1000 - include "build/baserom/object_jso.o" + number 6 + include "build/assets/objects/object_jso/object_jso.o" endseg beginseg name "object_knight" compress romalign 0x1000 - include "build/baserom/object_knight.o" + number 6 + include "build/assets/objects/object_knight/object_knight.o" endseg beginseg name "object_icicle" compress romalign 0x1000 - include "build/baserom/object_icicle.o" + number 6 + include "build/assets/objects/object_icicle/object_icicle.o" endseg beginseg name "object_spdweb" compress romalign 0x1000 - include "build/baserom/object_spdweb.o" + number 6 + include "build/assets/objects/object_spdweb/object_spdweb.o" endseg beginseg name "object_boss01" compress romalign 0x1000 - include "build/baserom/object_boss01.o" + number 6 + include "build/assets/objects/object_boss01/object_boss01.o" endseg beginseg name "object_boss02" compress romalign 0x1000 - include "build/baserom/object_boss02.o" + number 6 + include "build/assets/objects/object_boss02/object_boss02.o" endseg beginseg name "object_boss03" compress romalign 0x1000 - include "build/baserom/object_boss03.o" + number 6 + include "build/assets/objects/object_boss03/object_boss03.o" endseg beginseg name "object_boss04" compress romalign 0x1000 - include "build/baserom/object_boss04.o" + number 6 + include "build/assets/objects/object_boss04/object_boss04.o" endseg beginseg name "object_boss05" compress romalign 0x1000 - include "build/baserom/object_boss05.o" + number 6 + include "build/assets/objects/object_boss05/object_boss05.o" endseg beginseg name "object_boss07" compress romalign 0x1000 - include "build/baserom/object_boss07.o" + number 6 + include "build/assets/objects/object_boss07/object_boss07.o" endseg beginseg name "object_raf" compress romalign 0x1000 - include "build/baserom/object_raf.o" + number 6 + include "build/assets/objects/object_raf/object_raf.o" endseg beginseg name "object_funen" compress romalign 0x1000 - include "build/baserom/object_funen.o" + number 6 + include "build/assets/objects/object_funen/object_funen.o" endseg beginseg name "object_raillift" compress romalign 0x1000 - include "build/baserom/object_raillift.o" + number 6 + include "build/assets/objects/object_raillift/object_raillift.o" endseg beginseg name "object_numa_obj" compress romalign 0x1000 - include "build/baserom/object_numa_obj.o" + number 6 + include "build/assets/objects/object_numa_obj/object_numa_obj.o" endseg beginseg name "object_flowerpot" compress romalign 0x1000 - include "build/baserom/object_flowerpot.o" + number 6 + include "build/assets/objects/object_flowerpot/object_flowerpot.o" endseg beginseg name "object_spinyroll" compress romalign 0x1000 - include "build/baserom/object_spinyroll.o" + number 6 + include "build/assets/objects/object_spinyroll/object_spinyroll.o" endseg beginseg name "object_ice_block" compress romalign 0x1000 - include "build/baserom/object_ice_block.o" + number 6 + include "build/assets/objects/object_ice_block/object_ice_block.o" endseg beginseg name "object_keikoku_demo" compress romalign 0x1000 - include "build/baserom/object_keikoku_demo.o" + number 6 + include "build/assets/objects/object_keikoku_demo/object_keikoku_demo.o" endseg beginseg name "object_slime" compress romalign 0x1000 - include "build/baserom/object_slime.o" + number 6 + include "build/assets/objects/object_slime/object_slime.o" endseg beginseg name "object_pr" compress romalign 0x1000 - include "build/baserom/object_pr.o" + number 6 + include "build/assets/objects/object_pr/object_pr.o" endseg beginseg name "object_f52_obj" compress romalign 0x1000 - include "build/baserom/object_f52_obj.o" + number 6 + include "build/assets/objects/object_f52_obj/object_f52_obj.o" endseg beginseg name "object_f53_obj" compress romalign 0x1000 - include "build/baserom/object_f53_obj.o" + number 6 + include "build/assets/objects/object_f53_obj/object_f53_obj.o" endseg beginseg name "object_kibako" compress romalign 0x1000 - include "build/baserom/object_kibako.o" + number 6 + include "build/assets/objects/object_kibako/object_kibako.o" endseg beginseg name "object_sek" compress romalign 0x1000 - include "build/baserom/object_sek.o" + number 6 + include "build/assets/objects/object_sek/object_sek.o" endseg beginseg name "object_gmo" compress romalign 0x1000 - include "build/baserom/object_gmo.o" + number 6 + include "build/assets/objects/object_gmo/object_gmo.o" endseg beginseg name "object_bat" compress romalign 0x1000 - include "build/baserom/object_bat.o" + number 6 + include "build/assets/objects/object_bat/object_bat.o" endseg beginseg name "object_sekihil" compress romalign 0x1000 - include "build/baserom/object_sekihil.o" + number 6 + include "build/assets/objects/object_sekihil/object_sekihil.o" endseg beginseg name "object_sekihig" compress romalign 0x1000 - include "build/baserom/object_sekihig.o" + number 6 + include "build/assets/objects/object_sekihig/object_sekihig.o" endseg beginseg name "object_sekihin" compress romalign 0x1000 - include "build/baserom/object_sekihin.o" + number 6 + include "build/assets/objects/object_sekihin/object_sekihin.o" endseg beginseg name "object_sekihiz" compress romalign 0x1000 - include "build/baserom/object_sekihiz.o" + number 6 + include "build/assets/objects/object_sekihiz/object_sekihiz.o" endseg beginseg name "object_wiz" compress romalign 0x1000 - include "build/baserom/object_wiz.o" + number 6 + include "build/assets/objects/object_wiz/object_wiz.o" endseg beginseg name "object_ladder" compress romalign 0x1000 - include "build/baserom/object_ladder.o" + number 6 + include "build/assets/objects/object_ladder/object_ladder.o" endseg beginseg name "object_mkk" compress romalign 0x1000 - include "build/baserom/object_mkk.o" + number 6 + include "build/assets/objects/object_mkk/object_mkk.o" endseg beginseg name "object_keikoku_obj" compress romalign 0x1000 - include "build/baserom/object_keikoku_obj.o" + number 6 + include "build/assets/objects/object_keikoku_obj/object_keikoku_obj.o" endseg beginseg name "object_sichitai_obj" compress romalign 0x1000 - include "build/baserom/object_sichitai_obj.o" + number 6 + include "build/assets/objects/object_sichitai_obj/object_sichitai_obj.o" endseg beginseg name "object_dekucity_ana_obj" compress romalign 0x1000 - include "build/baserom/object_dekucity_ana_obj.o" + number 6 + include "build/assets/objects/object_dekucity_ana_obj/object_dekucity_ana_obj.o" endseg beginseg name "object_rat" compress romalign 0x1000 - include "build/baserom/object_rat.o" + number 6 + include "build/assets/objects/object_rat/object_rat.o" endseg beginseg name "object_water_effect" compress romalign 0x1000 - include "build/baserom/object_water_effect.o" + number 6 + include "build/assets/objects/object_water_effect/object_water_effect.o" endseg beginseg name "object_dblue_object" compress romalign 0x1000 - include "build/baserom/object_dblue_object.o" + number 6 + include "build/assets/objects/object_dblue_object/object_dblue_object.o" endseg beginseg name "object_bal" compress romalign 0x1000 - include "build/baserom/object_bal.o" + number 6 + include "build/assets/objects/object_bal/object_bal.o" endseg beginseg name "object_warp_uzu" compress romalign 0x1000 - include "build/baserom/object_warp_uzu.o" + number 6 + include "build/assets/objects/object_warp_uzu/object_warp_uzu.o" endseg beginseg name "object_driftice" compress romalign 0x1000 - include "build/baserom/object_driftice.o" + number 6 + include "build/assets/objects/object_driftice/object_driftice.o" endseg beginseg name "object_fall" compress romalign 0x1000 - include "build/baserom/object_fall.o" + number 6 + include "build/assets/objects/object_fall/object_fall.o" endseg beginseg name "object_hanareyama_obj" compress romalign 0x1000 - include "build/baserom/object_hanareyama_obj.o" + number 6 + include "build/assets/objects/object_hanareyama_obj/object_hanareyama_obj.o" endseg beginseg name "object_crace_object" compress romalign 0x1000 - include "build/baserom/object_crace_object.o" + number 6 + include "build/assets/objects/object_crace_object/object_crace_object.o" endseg beginseg name "object_dnq" compress romalign 0x1000 - include "build/baserom/object_dnq.o" + number 6 + include "build/assets/objects/object_dnq/object_dnq.o" endseg beginseg name "object_obj_tokeidai" compress romalign 0x1000 - include "build/baserom/object_obj_tokeidai.o" + number 6 + include "build/assets/objects/object_obj_tokeidai/object_obj_tokeidai.o" endseg beginseg name "object_eg" compress romalign 0x1000 - include "build/baserom/object_eg.o" + number 6 + include "build/assets/objects/object_eg/object_eg.o" endseg beginseg name "object_tru" compress romalign 0x1000 - include "build/baserom/object_tru.o" + number 6 + include "build/assets/objects/object_tru/object_tru.o" endseg beginseg name "object_trt" compress romalign 0x1000 - include "build/baserom/object_trt.o" + number 6 + include "build/assets/objects/object_trt/object_trt.o" endseg beginseg name "object_hakugin_obj" compress romalign 0x1000 - include "build/baserom/object_hakugin_obj.o" + number 6 + include "build/assets/objects/object_hakugin_obj/object_hakugin_obj.o" endseg beginseg name "object_horse_game_check" compress romalign 0x1000 - include "build/baserom/object_horse_game_check.o" + number 6 + include "build/assets/objects/object_horse_game_check/object_horse_game_check.o" endseg beginseg name "object_stk" compress romalign 0x1000 - include "build/baserom/object_stk.o" + number 6 + include "build/assets/objects/object_stk/object_stk.o" endseg beginseg name "object_mnk" compress romalign 0x1000 - include "build/baserom/object_mnk.o" + number 6 + include "build/assets/objects/object_mnk/object_mnk.o" endseg beginseg name "object_gi_bottle_red" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_red.o" + number 6 + include "build/assets/objects/object_gi_bottle_red/object_gi_bottle_red.o" endseg beginseg name "object_tokei_tobira" compress romalign 0x1000 - include "build/baserom/object_tokei_tobira.o" + number 6 + include "build/assets/objects/object_tokei_tobira/object_tokei_tobira.o" endseg beginseg name "object_az" compress romalign 0x1000 - include "build/baserom/object_az.o" + number 6 + include "build/assets/objects/object_az/object_az.o" endseg beginseg name "object_twig" compress romalign 0x1000 - include "build/baserom/object_twig.o" + number 6 + include "build/assets/objects/object_twig/object_twig.o" endseg beginseg name "object_dekucity_obj" compress romalign 0x1000 - include "build/baserom/object_dekucity_obj.o" + number 6 + include "build/assets/objects/object_dekucity_obj/object_dekucity_obj.o" endseg beginseg name "object_po_fusen" compress romalign 0x1000 - include "build/baserom/object_po_fusen.o" + number 6 + include "build/assets/objects/object_po_fusen/object_po_fusen.o" endseg beginseg name "object_racetsubo" compress romalign 0x1000 - include "build/baserom/object_racetsubo.o" + number 6 + include "build/assets/objects/object_racetsubo/object_racetsubo.o" endseg beginseg name "object_ha" compress romalign 0x1000 - include "build/baserom/object_ha.o" + number 6 + include "build/assets/objects/object_ha/object_ha.o" endseg beginseg name "object_bigokuta" compress romalign 0x1000 - include "build/baserom/object_bigokuta.o" + number 6 + include "build/assets/objects/object_bigokuta/object_bigokuta.o" endseg beginseg name "object_open_obj" compress romalign 0x1000 - include "build/baserom/object_open_obj.o" + number 6 + include "build/assets/objects/object_open_obj/object_open_obj.o" endseg beginseg name "object_fu_kaiten" compress romalign 0x1000 - include "build/baserom/object_fu_kaiten.o" + number 6 + include "build/assets/objects/object_fu_kaiten/object_fu_kaiten.o" endseg beginseg name "object_fu_mato" compress romalign 0x1000 - include "build/baserom/object_fu_mato.o" + number 6 + include "build/assets/objects/object_fu_mato/object_fu_mato.o" endseg beginseg name "object_mtoride" compress romalign 0x1000 - include "build/baserom/object_mtoride.o" + number 6 + include "build/assets/objects/object_mtoride/object_mtoride.o" endseg beginseg name "object_osn" compress romalign 0x1000 - include "build/baserom/object_osn.o" + number 6 + include "build/assets/objects/object_osn/object_osn.o" endseg beginseg name "object_tokei_step" compress romalign 0x1000 - include "build/baserom/object_tokei_step.o" + number 6 + include "build/assets/objects/object_tokei_step/object_tokei_step.o" endseg beginseg name "object_lotus" compress romalign 0x1000 - include "build/baserom/object_lotus.o" + number 6 + include "build/assets/objects/object_lotus/object_lotus.o" endseg beginseg name "object_tl" compress romalign 0x1000 - include "build/baserom/object_tl.o" + number 6 + include "build/assets/objects/object_tl/object_tl.o" endseg beginseg name "object_dkjail_obj" compress romalign 0x1000 - include "build/baserom/object_dkjail_obj.o" + number 6 + include "build/assets/objects/object_dkjail_obj/object_dkjail_obj.o" endseg beginseg name "object_visiblock" compress romalign 0x1000 - include "build/baserom/object_visiblock.o" + number 6 + include "build/assets/objects/object_visiblock/object_visiblock.o" endseg beginseg name "object_tsn" compress romalign 0x1000 - include "build/baserom/object_tsn.o" + number 6 + include "build/assets/objects/object_tsn/object_tsn.o" endseg beginseg name "object_ds2n" compress romalign 0x1000 - include "build/baserom/object_ds2n.o" + number 6 + include "build/assets/objects/object_ds2n/object_ds2n.o" endseg beginseg name "object_fsn" compress romalign 0x1000 - include "build/baserom/object_fsn.o" + number 6 + include "build/assets/objects/object_fsn/object_fsn.o" endseg beginseg name "object_shn" compress romalign 0x1000 - include "build/baserom/object_shn.o" + number 6 + include "build/assets/objects/object_shn/object_shn.o" endseg beginseg name "object_bigicicle" compress romalign 0x1000 - include "build/baserom/object_bigicicle.o" + number 6 + include "build/assets/objects/object_bigicicle/object_bigicicle.o" endseg beginseg name "object_gi_bottle_15" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_15.o" + number 6 + include "build/assets/objects/object_gi_bottle_15/object_gi_bottle_15.o" endseg beginseg name "object_tk" compress romalign 0x1000 - include "build/baserom/object_tk.o" + number 6 + include "build/assets/objects/object_tk/object_tk.o" endseg beginseg name "object_market_obj" compress romalign 0x1000 - include "build/baserom/object_market_obj.o" + number 6 + include "build/assets/objects/object_market_obj/object_market_obj.o" endseg beginseg name "object_gi_reserve00" compress romalign 0x1000 - include "build/baserom/object_gi_reserve00.o" + number 6 + include "build/assets/objects/object_gi_reserve00/object_gi_reserve00.o" endseg beginseg name "object_gi_reserve01" compress romalign 0x1000 - include "build/baserom/object_gi_reserve01.o" + number 6 + include "build/assets/objects/object_gi_reserve01/object_gi_reserve01.o" endseg beginseg name "object_lightblock" compress romalign 0x1000 - include "build/baserom/object_lightblock.o" + number 6 + include "build/assets/objects/object_lightblock/object_lightblock.o" endseg beginseg name "object_takaraya_objects" compress romalign 0x1000 - include "build/baserom/object_takaraya_objects.o" + number 6 + include "build/assets/objects/object_takaraya_objects/object_takaraya_objects.o" endseg beginseg name "object_wdhand" compress romalign 0x1000 - include "build/baserom/object_wdhand.o" + number 6 + include "build/assets/objects/object_wdhand/object_wdhand.o" endseg beginseg name "object_sdn" compress romalign 0x1000 - include "build/baserom/object_sdn.o" + number 6 + include "build/assets/objects/object_sdn/object_sdn.o" endseg beginseg name "object_snowwd" compress romalign 0x1000 - include "build/baserom/object_snowwd.o" + number 6 + include "build/assets/objects/object_snowwd/object_snowwd.o" endseg beginseg name "object_giant" compress romalign 0x1000 - include "build/baserom/object_giant.o" + number 6 + include "build/assets/objects/object_giant/object_giant.o" endseg beginseg name "object_comb" compress romalign 0x1000 - include "build/baserom/object_comb.o" + number 6 + include "build/assets/objects/object_comb/object_comb.o" endseg beginseg name "object_hana" compress romalign 0x1000 - include "build/baserom/object_hana.o" + number 6 + include "build/assets/objects/object_hana/object_hana.o" endseg beginseg name "object_boss_hakugin" compress romalign 0x1000 - include "build/baserom/object_boss_hakugin.o" + number 6 + include "build/assets/objects/object_boss_hakugin/object_boss_hakugin.o" endseg beginseg name "object_meganeana_obj" compress romalign 0x1000 - include "build/baserom/object_meganeana_obj.o" + number 6 + include "build/assets/objects/object_meganeana_obj/object_meganeana_obj.o" endseg beginseg name "object_gi_nutsmask" compress romalign 0x1000 - include "build/baserom/object_gi_nutsmask.o" + number 6 + include "build/assets/objects/object_gi_nutsmask/object_gi_nutsmask.o" endseg beginseg name "object_stk2" compress romalign 0x1000 - include "build/baserom/object_stk2.o" + number 6 + include "build/assets/objects/object_stk2/object_stk2.o" endseg beginseg name "object_spot11_obj" compress romalign 0x1000 - include "build/baserom/object_spot11_obj.o" + number 6 + include "build/assets/objects/object_spot11_obj/object_spot11_obj.o" endseg beginseg name "object_danpei_object" compress romalign 0x1000 - include "build/baserom/object_danpei_object.o" + number 6 + include "build/assets/objects/object_danpei_object/object_danpei_object.o" endseg beginseg name "object_dhouse" compress romalign 0x1000 - include "build/baserom/object_dhouse.o" + number 6 + include "build/assets/objects/object_dhouse/object_dhouse.o" endseg beginseg name "object_hakaisi" compress romalign 0x1000 - include "build/baserom/object_hakaisi.o" + number 6 + include "build/assets/objects/object_hakaisi/object_hakaisi.o" endseg beginseg name "object_po" compress romalign 0x1000 - include "build/baserom/object_po.o" + number 6 + include "build/assets/objects/object_po/object_po.o" endseg beginseg name "object_snowman" compress romalign 0x1000 - include "build/baserom/object_snowman.o" + number 6 + include "build/assets/objects/object_snowman/object_snowman.o" endseg beginseg name "object_po_sisters" compress romalign 0x1000 - include "build/baserom/object_po_sisters.o" + number 6 + include "build/assets/objects/object_po_sisters/object_po_sisters.o" endseg beginseg name "object_pp" compress romalign 0x1000 - include "build/baserom/object_pp.o" + number 6 + include "build/assets/objects/object_pp/object_pp.o" endseg beginseg name "object_goronswitch" compress romalign 0x1000 - include "build/baserom/object_goronswitch.o" + number 6 + include "build/assets/objects/object_goronswitch/object_goronswitch.o" endseg beginseg name "object_delf" compress romalign 0x1000 - include "build/baserom/object_delf.o" + number 6 + include "build/assets/objects/object_delf/object_delf.o" endseg beginseg name "object_botihasira" compress romalign 0x1000 - include "build/baserom/object_botihasira.o" + number 6 + include "build/assets/objects/object_botihasira/object_botihasira.o" endseg beginseg name "object_gi_bigbomb" compress romalign 0x1000 - include "build/baserom/object_gi_bigbomb.o" + number 6 + include "build/assets/objects/object_gi_bigbomb/object_gi_bigbomb.o" endseg beginseg name "object_pst" compress romalign 0x1000 - include "build/baserom/object_pst.o" + number 6 + include "build/assets/objects/object_pst/object_pst.o" endseg beginseg name "object_bsmask" compress romalign 0x1000 - include "build/baserom/object_bsmask.o" + number 6 + include "build/assets/objects/object_bsmask/object_bsmask.o" endseg beginseg name "object_spidertent" compress romalign 0x1000 - include "build/baserom/object_spidertent.o" + number 6 + include "build/assets/objects/object_spidertent/object_spidertent.o" endseg beginseg name "object_zoraegg" compress romalign 0x1000 - include "build/baserom/object_zoraegg.o" + number 6 + include "build/assets/objects/object_zoraegg/object_zoraegg.o" endseg beginseg name "object_kbt" compress romalign 0x1000 - include "build/baserom/object_kbt.o" + number 6 + include "build/assets/objects/object_kbt/object_kbt.o" endseg beginseg name "object_gg" compress romalign 0x1000 - include "build/baserom/object_gg.o" + number 6 + include "build/assets/objects/object_gg/object_gg.o" endseg beginseg name "object_maruta" compress romalign 0x1000 - include "build/baserom/object_maruta.o" + number 6 + include "build/assets/objects/object_maruta/object_maruta.o" endseg beginseg name "object_ghaka" compress romalign 0x1000 - include "build/baserom/object_ghaka.o" + number 6 + include "build/assets/objects/object_ghaka/object_ghaka.o" endseg beginseg name "object_oyu" compress romalign 0x1000 - include "build/baserom/object_oyu.o" + number 6 + include "build/assets/objects/object_oyu/object_oyu.o" endseg beginseg name "object_dnp" compress romalign 0x1000 - include "build/baserom/object_dnp.o" + number 6 + include "build/assets/objects/object_dnp/object_dnp.o" endseg beginseg name "object_dai" compress romalign 0x1000 - include "build/baserom/object_dai.o" + number 6 + include "build/assets/objects/object_dai/object_dai.o" endseg beginseg name "object_kgy" compress romalign 0x1000 - include "build/baserom/object_kgy.o" + number 6 + include "build/assets/objects/object_kgy/object_kgy.o" endseg beginseg name "object_fb" compress romalign 0x1000 - include "build/baserom/object_fb.o" + number 6 + include "build/assets/objects/object_fb/object_fb.o" endseg beginseg name "object_taisou" compress romalign 0x1000 - include "build/baserom/object_taisou.o" + number 6 + include "build/assets/objects/object_taisou/object_taisou.o" endseg beginseg name "object_gk" compress romalign 0x1000 - include "build/baserom/object_gk.o" + number 6 + include "build/assets/objects/object_gk/object_gk.o" endseg beginseg name "object_haka_obj" compress romalign 0x1000 - include "build/baserom/object_haka_obj.o" + number 6 + include "build/assets/objects/object_haka_obj/object_haka_obj.o" endseg beginseg name "object_dnt" compress romalign 0x1000 - include "build/baserom/object_dnt.o" + number 6 + include "build/assets/objects/object_dnt/object_dnt.o" endseg beginseg name "object_yukiyama" compress romalign 0x1000 - include "build/baserom/object_yukiyama.o" + number 6 + include "build/assets/objects/object_yukiyama/object_yukiyama.o" endseg beginseg name "object_icefloe" compress romalign 0x1000 - include "build/baserom/object_icefloe.o" + number 6 + include "build/assets/objects/object_icefloe/object_icefloe.o" endseg beginseg name "object_gi_gold_dust" compress romalign 0x1000 - include "build/baserom/object_gi_gold_dust.o" + number 6 + include "build/assets/objects/object_gi_gold_dust/object_gi_gold_dust.o" endseg beginseg name "object_gi_bottle_16" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_16.o" + number 6 + include "build/assets/objects/object_gi_bottle_16/object_gi_bottle_16.o" endseg beginseg name "object_gi_bottle_22" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_22.o" + number 6 + include "build/assets/objects/object_gi_bottle_22/object_gi_bottle_22.o" endseg beginseg name "object_bee" compress romalign 0x1000 - include "build/baserom/object_bee.o" + number 6 + include "build/assets/objects/object_bee/object_bee.o" endseg beginseg name "object_ot" compress romalign 0x1000 - include "build/baserom/object_ot.o" + number 6 + include "build/assets/objects/object_ot/object_ot.o" endseg beginseg name "object_utubo" compress romalign 0x1000 - include "build/baserom/object_utubo.o" + number 6 + include "build/assets/objects/object_utubo/object_utubo.o" endseg beginseg name "object_dora" compress romalign 0x1000 - include "build/baserom/object_dora.o" + number 6 + include "build/assets/objects/object_dora/object_dora.o" endseg beginseg name "object_gi_loach" compress romalign 0x1000 - include "build/baserom/object_gi_loach.o" + number 6 + include "build/assets/objects/object_gi_loach/object_gi_loach.o" endseg beginseg name "object_gi_seahorse" compress romalign 0x1000 - include "build/baserom/object_gi_seahorse.o" + number 6 + include "build/assets/objects/object_gi_seahorse/object_gi_seahorse.o" endseg beginseg name "object_bigpo" compress romalign 0x1000 - include "build/baserom/object_bigpo.o" + number 6 + include "build/assets/objects/object_bigpo/object_bigpo.o" endseg beginseg name "object_hariko" compress romalign 0x1000 - include "build/baserom/object_hariko.o" + number 6 + include "build/assets/objects/object_hariko/object_hariko.o" endseg beginseg name "object_dno" compress romalign 0x1000 - include "build/baserom/object_dno.o" + number 6 + include "build/assets/objects/object_dno/object_dno.o" endseg beginseg name "object_sinkai_kabe" compress romalign 0x1000 - include "build/baserom/object_sinkai_kabe.o" + number 6 + include "build/assets/objects/object_sinkai_kabe/object_sinkai_kabe.o" endseg beginseg name "object_kin2_obj" compress romalign 0x1000 - include "build/baserom/object_kin2_obj.o" + number 6 + include "build/assets/objects/object_kin2_obj/object_kin2_obj.o" endseg beginseg name "object_ishi" compress romalign 0x1000 - include "build/baserom/object_ishi.o" + number 6 + include "build/assets/objects/object_ishi/object_ishi.o" endseg beginseg name "object_hakugin_demo" compress romalign 0x1000 - include "build/baserom/object_hakugin_demo.o" + number 6 + include "build/assets/objects/object_hakugin_demo/object_hakugin_demo.o" endseg beginseg name "object_jg" compress romalign 0x1000 - include "build/baserom/object_jg.o" + number 6 + include "build/assets/objects/object_jg/object_jg.o" endseg beginseg name "object_gi_sword_2" compress romalign 0x1000 - include "build/baserom/object_gi_sword_2.o" + number 6 + include "build/assets/objects/object_gi_sword_2/object_gi_sword_2.o" endseg beginseg name "object_gi_sword_3" compress romalign 0x1000 - include "build/baserom/object_gi_sword_3.o" + number 6 + include "build/assets/objects/object_gi_sword_3/object_gi_sword_3.o" endseg beginseg name "object_gi_sword_4" compress romalign 0x1000 - include "build/baserom/object_gi_sword_4.o" + number 6 + include "build/assets/objects/object_gi_sword_4/object_gi_sword_4.o" endseg beginseg name "object_um" compress romalign 0x1000 - include "build/baserom/object_um.o" + number 6 + include "build/assets/objects/object_um/object_um.o" endseg beginseg name "object_rb" compress romalign 0x1000 - include "build/baserom/object_rb.o" + number 6 + include "build/assets/objects/object_rb/object_rb.o" endseg beginseg name "object_mbar_obj" compress romalign 0x1000 - include "build/baserom/object_mbar_obj.o" + number 6 + include "build/assets/objects/object_mbar_obj/object_mbar_obj.o" endseg beginseg name "object_ikana_obj" compress romalign 0x1000 - include "build/baserom/object_ikana_obj.o" + number 6 + include "build/assets/objects/object_ikana_obj/object_ikana_obj.o" endseg beginseg name "object_kz" compress romalign 0x1000 - include "build/baserom/object_kz.o" + number 6 + include "build/assets/objects/object_kz/object_kz.o" endseg beginseg name "object_tokei_turret" compress romalign 0x1000 - include "build/baserom/object_tokei_turret.o" + number 6 + include "build/assets/objects/object_tokei_turret/object_tokei_turret.o" endseg beginseg name "object_zog" compress romalign 0x1000 - include "build/baserom/object_zog.o" + number 6 + include "build/assets/objects/object_zog/object_zog.o" endseg beginseg name "object_rotlift" compress romalign 0x1000 - include "build/baserom/object_rotlift.o" + number 6 + include "build/assets/objects/object_rotlift/object_rotlift.o" endseg beginseg name "object_posthouse_obj" compress romalign 0x1000 - include "build/baserom/object_posthouse_obj.o" + number 6 + include "build/assets/objects/object_posthouse_obj/object_posthouse_obj.o" endseg beginseg name "object_gi_mask09" compress romalign 0x1000 - include "build/baserom/object_gi_mask09.o" + number 6 + include "build/assets/objects/object_gi_mask09/object_gi_mask09.o" endseg beginseg name "object_gi_mask14" compress romalign 0x1000 - include "build/baserom/object_gi_mask14.o" + number 6 + include "build/assets/objects/object_gi_mask14/object_gi_mask14.o" endseg beginseg name "object_gi_mask15" compress romalign 0x1000 - include "build/baserom/object_gi_mask15.o" + number 6 + include "build/assets/objects/object_gi_mask15/object_gi_mask15.o" endseg beginseg name "object_inibs_object" compress romalign 0x1000 - include "build/baserom/object_inibs_object.o" + number 6 + include "build/assets/objects/object_inibs_object/object_inibs_object.o" endseg beginseg name "object_tree" compress romalign 0x1000 - include "build/baserom/object_tree.o" + number 6 + include "build/assets/objects/object_tree/object_tree.o" endseg beginseg name "object_kaizoku_obj" compress romalign 0x1000 - include "build/baserom/object_kaizoku_obj.o" + number 6 + include "build/assets/objects/object_kaizoku_obj/object_kaizoku_obj.o" endseg beginseg name "object_gi_reserve_b_00" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_b_00.o" + number 6 + include "build/assets/objects/object_gi_reserve_b_00/object_gi_reserve_b_00.o" endseg beginseg name "object_gi_reserve_c_00" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_c_00.o" + number 6 + include "build/assets/objects/object_gi_reserve_c_00/object_gi_reserve_c_00.o" endseg beginseg name "object_zob" compress romalign 0x1000 - include "build/baserom/object_zob.o" + number 6 + include "build/assets/objects/object_zob/object_zob.o" endseg beginseg name "object_milkbar" compress romalign 0x1000 - include "build/baserom/object_milkbar.o" + number 6 + include "build/assets/objects/object_milkbar/object_milkbar.o" endseg beginseg name "object_dmask" compress romalign 0x1000 - include "build/baserom/object_dmask.o" + number 6 + include "build/assets/objects/object_dmask/object_dmask.o" endseg beginseg name "object_gi_reserve_c_01" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_c_01.o" + number 6 + include "build/assets/objects/object_gi_reserve_c_01/object_gi_reserve_c_01.o" endseg beginseg name "object_zod" compress romalign 0x1000 - include "build/baserom/object_zod.o" + number 6 + include "build/assets/objects/object_zod/object_zod.o" endseg beginseg name "object_kumo30" compress romalign 0x1000 - include "build/baserom/object_kumo30.o" + number 6 + include "build/assets/objects/object_kumo30/object_kumo30.o" endseg beginseg name "object_obj_yasi" compress romalign 0x1000 - include "build/baserom/object_obj_yasi.o" + number 6 + include "build/assets/objects/object_obj_yasi/object_obj_yasi.o" endseg beginseg name "object_tanron1" compress romalign 0x1000 - include "build/baserom/object_tanron1.o" + number 6 + include "build/assets/objects/object_tanron1/object_tanron1.o" endseg beginseg name "object_tanron2" compress romalign 0x1000 - include "build/baserom/object_tanron2.o" + number 6 + include "build/assets/objects/object_tanron2/object_tanron2.o" endseg beginseg name "object_tanron3" compress romalign 0x1000 - include "build/baserom/object_tanron3.o" + number 6 + include "build/assets/objects/object_tanron3/object_tanron3.o" endseg beginseg name "object_gi_magicmushroom" compress romalign 0x1000 - include "build/baserom/object_gi_magicmushroom.o" + number 6 + include "build/assets/objects/object_gi_magicmushroom/object_gi_magicmushroom.o" endseg beginseg name "object_obj_chan" compress romalign 0x1000 - include "build/baserom/object_obj_chan.o" + number 6 + include "build/assets/objects/object_obj_chan/object_obj_chan.o" endseg beginseg name "object_gi_mask10" compress romalign 0x1000 - include "build/baserom/object_gi_mask10.o" + number 6 + include "build/assets/objects/object_gi_mask10/object_gi_mask10.o" endseg beginseg name "object_zos" compress romalign 0x1000 - include "build/baserom/object_zos.o" + number 6 + include "build/assets/objects/object_zos/object_zos.o" endseg beginseg name "object_an2" compress romalign 0x1000 - include "build/baserom/object_an2.o" + number 6 + include "build/assets/objects/object_an2/object_an2.o" endseg beginseg name "object_an3" compress romalign 0x1000 - include "build/baserom/object_an3.o" + number 6 + include "build/assets/objects/object_an3/object_an3.o" endseg beginseg name "object_f40_switch" compress romalign 0x1000 - include "build/baserom/object_f40_switch.o" + number 6 + include "build/assets/objects/object_f40_switch/object_f40_switch.o" endseg beginseg name "object_lodmoon" compress romalign 0x1000 - include "build/baserom/object_lodmoon.o" + number 6 + include "build/assets/objects/object_lodmoon/object_lodmoon.o" endseg beginseg name "object_tro" compress romalign 0x1000 - include "build/baserom/object_tro.o" + number 6 + include "build/assets/objects/object_tro/object_tro.o" endseg beginseg name "object_gi_mask12" compress romalign 0x1000 - include "build/baserom/object_gi_mask12.o" + number 6 + include "build/assets/objects/object_gi_mask12/object_gi_mask12.o" endseg beginseg name "object_gi_mask23" compress romalign 0x1000 - include "build/baserom/object_gi_mask23.o" + number 6 + include "build/assets/objects/object_gi_mask23/object_gi_mask23.o" endseg beginseg name "object_gi_bottle_21" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_21.o" + number 6 + include "build/assets/objects/object_gi_bottle_21/object_gi_bottle_21.o" endseg beginseg name "object_gi_camera" compress romalign 0x1000 - include "build/baserom/object_gi_camera.o" + number 6 + include "build/assets/objects/object_gi_camera/object_gi_camera.o" endseg beginseg name "object_kamejima" compress romalign 0x1000 - include "build/baserom/object_kamejima.o" + number 6 + include "build/assets/objects/object_kamejima/object_kamejima.o" endseg beginseg name "object_nb" compress romalign 0x1000 - include "build/baserom/object_nb.o" + number 6 + include "build/assets/objects/object_nb/object_nb.o" endseg beginseg name "object_harfgibud" compress romalign 0x1000 - include "build/baserom/object_harfgibud.o" + number 6 + include "build/assets/objects/object_harfgibud/object_harfgibud.o" endseg beginseg name "object_zov" compress romalign 0x1000 - include "build/baserom/object_zov.o" + number 6 + include "build/assets/objects/object_zov/object_zov.o" endseg beginseg name "object_ah" compress romalign 0x1000 - include "build/baserom/object_ah.o" + number 6 + include "build/assets/objects/object_ah/object_ah.o" endseg beginseg name "object_hgdoor" compress romalign 0x1000 - include "build/baserom/object_hgdoor.o" + number 6 + include "build/assets/objects/object_hgdoor/object_hgdoor.o" endseg beginseg name "object_dor01" compress romalign 0x1000 - include "build/baserom/object_dor01.o" + number 6 + include "build/assets/objects/object_dor01/object_dor01.o" endseg beginseg name "object_dor02" compress romalign 0x1000 - include "build/baserom/object_dor02.o" + number 6 + include "build/assets/objects/object_dor02/object_dor02.o" endseg beginseg name "object_dor03" compress romalign 0x1000 - include "build/baserom/object_dor03.o" + number 6 + include "build/assets/objects/object_dor03/object_dor03.o" endseg beginseg name "object_dor04" compress romalign 0x1000 - include "build/baserom/object_dor04.o" + number 6 + include "build/assets/objects/object_dor04/object_dor04.o" endseg beginseg name "object_last_obj" compress romalign 0x1000 - include "build/baserom/object_last_obj.o" + number 6 + include "build/assets/objects/object_last_obj/object_last_obj.o" endseg beginseg name "object_redead_obj" compress romalign 0x1000 - include "build/baserom/object_redead_obj.o" + number 6 + include "build/assets/objects/object_redead_obj/object_redead_obj.o" endseg beginseg name "object_ikninside_obj" compress romalign 0x1000 - include "build/baserom/object_ikninside_obj.o" + number 6 + include "build/assets/objects/object_ikninside_obj/object_ikninside_obj.o" endseg beginseg name "object_iknv_obj" compress romalign 0x1000 - include "build/baserom/object_iknv_obj.o" + number 6 + include "build/assets/objects/object_iknv_obj/object_iknv_obj.o" endseg beginseg name "object_pamera" compress romalign 0x1000 - include "build/baserom/object_pamera.o" + number 6 + include "build/assets/objects/object_pamera/object_pamera.o" endseg beginseg name "object_hsstump" compress romalign 0x1000 - include "build/baserom/object_hsstump.o" + number 6 + include "build/assets/objects/object_hsstump/object_hsstump.o" endseg beginseg name "object_zm" compress romalign 0x1000 - include "build/baserom/object_zm.o" + number 6 + include "build/assets/objects/object_zm/object_zm.o" endseg beginseg name "object_al" compress romalign 0x1000 - include "build/baserom/object_al.o" + number 6 + include "build/assets/objects/object_al/object_al.o" endseg beginseg name "object_tab" compress romalign 0x1000 - include "build/baserom/object_tab.o" + number 6 + include "build/assets/objects/object_tab/object_tab.o" endseg beginseg name "object_secom_obj" compress romalign 0x1000 - include "build/baserom/object_secom_obj.o" + number 6 + include "build/assets/objects/object_secom_obj/object_secom_obj.o" endseg beginseg name "object_dt" compress romalign 0x1000 - include "build/baserom/object_dt.o" + number 6 + include "build/assets/objects/object_dt/object_dt.o" endseg beginseg name "object_gi_mask03" compress romalign 0x1000 - include "build/baserom/object_gi_mask03.o" + number 6 + include "build/assets/objects/object_gi_mask03/object_gi_mask03.o" endseg beginseg name "object_cha" compress romalign 0x1000 - include "build/baserom/object_cha.o" + number 6 + include "build/assets/objects/object_cha/object_cha.o" endseg beginseg name "object_obj_dinner" compress romalign 0x1000 - include "build/baserom/object_obj_dinner.o" + number 6 + include "build/assets/objects/object_obj_dinner/object_obj_dinner.o" endseg beginseg name "object_gi_reserve_b_01" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_b_01.o" + number 6 + include "build/assets/objects/object_gi_reserve_b_01/object_gi_reserve_b_01.o" endseg beginseg name "object_lastday" compress romalign 0x1000 - include "build/baserom/object_lastday.o" + number 6 + include "build/assets/objects/object_lastday/object_lastday.o" endseg beginseg name "object_bai" compress romalign 0x1000 - include "build/baserom/object_bai.o" + number 6 + include "build/assets/objects/object_bai/object_bai.o" endseg beginseg name "object_ikn_demo" compress romalign 0x1000 - include "build/baserom/object_ikn_demo.o" + number 6 + include "build/assets/objects/object_ikn_demo/object_ikn_demo.o" endseg beginseg name "object_gi_fieldmap" compress romalign 0x1000 - include "build/baserom/object_gi_fieldmap.o" + number 6 + include "build/assets/objects/object_gi_fieldmap/object_gi_fieldmap.o" endseg beginseg name "object_big_fwall" compress romalign 0x1000 - include "build/baserom/object_big_fwall.o" + number 6 + include "build/assets/objects/object_big_fwall/object_big_fwall.o" endseg beginseg name "object_hunsui" compress romalign 0x1000 - include "build/baserom/object_hunsui.o" + number 6 + include "build/assets/objects/object_hunsui/object_hunsui.o" endseg beginseg name "object_uch" compress romalign 0x1000 - include "build/baserom/object_uch.o" + number 6 + include "build/assets/objects/object_uch/object_uch.o" endseg beginseg name "object_tanron4" compress romalign 0x1000 - include "build/baserom/object_tanron4.o" + number 6 + include "build/assets/objects/object_tanron4/object_tanron4.o" endseg beginseg name "object_tanron5" compress romalign 0x1000 - include "build/baserom/object_tanron5.o" + number 6 + include "build/assets/objects/object_tanron5/object_tanron5.o" endseg beginseg name "object_in2" compress romalign 0x1000 - include "build/baserom/object_in2.o" + number 6 + include "build/assets/objects/object_in2/object_in2.o" endseg beginseg name "object_yb" compress romalign 0x1000 - include "build/baserom/object_yb.o" + number 6 + include "build/assets/objects/object_yb/object_yb.o" endseg beginseg name "object_rz" compress romalign 0x1000 - include "build/baserom/object_rz.o" + number 6 + include "build/assets/objects/object_rz/object_rz.o" endseg beginseg name "object_bjt" compress romalign 0x1000 - include "build/baserom/object_bjt.o" + number 6 + include "build/assets/objects/object_bjt/object_bjt.o" endseg beginseg name "object_taru" compress romalign 0x1000 - include "build/baserom/object_taru.o" + number 6 + include "build/assets/objects/object_taru/object_taru.o" endseg beginseg name "object_moonston" compress romalign 0x1000 - include "build/baserom/object_moonston.o" + number 6 + include "build/assets/objects/object_moonston/object_moonston.o" endseg beginseg name "object_gi_schedule" compress romalign 0x1000 - include "build/baserom/object_gi_schedule.o" + number 6 + include "build/assets/objects/object_gi_schedule/object_gi_schedule.o" endseg beginseg name "object_gi_stonemask" compress romalign 0x1000 - include "build/baserom/object_gi_stonemask.o" + number 6 + include "build/assets/objects/object_gi_stonemask/object_gi_stonemask.o" endseg beginseg name "object_zoraband" compress romalign 0x1000 - include "build/baserom/object_zoraband.o" + number 6 + include "build/assets/objects/object_zoraband/object_zoraband.o" endseg beginseg name "object_kepn_koya" compress romalign 0x1000 - include "build/baserom/object_kepn_koya.o" + number 6 + include "build/assets/objects/object_kepn_koya/object_kepn_koya.o" endseg beginseg name "object_obj_usiyane" compress romalign 0x1000 - include "build/baserom/object_obj_usiyane.o" + number 6 + include "build/assets/objects/object_obj_usiyane/object_obj_usiyane.o" endseg beginseg name "object_gi_mask05" compress romalign 0x1000 - include "build/baserom/object_gi_mask05.o" + number 6 + include "build/assets/objects/object_gi_mask05/object_gi_mask05.o" endseg beginseg name "object_gi_mask11" compress romalign 0x1000 - include "build/baserom/object_gi_mask11.o" + number 6 + include "build/assets/objects/object_gi_mask11/object_gi_mask11.o" endseg beginseg name "object_gi_mask20" compress romalign 0x1000 - include "build/baserom/object_gi_mask20.o" + number 6 + include "build/assets/objects/object_gi_mask20/object_gi_mask20.o" endseg beginseg name "object_nnh" compress romalign 0x1000 - include "build/baserom/object_nnh.o" + number 6 + include "build/assets/objects/object_nnh/object_nnh.o" endseg beginseg name "object_kzsaku" compress romalign 0x1000 - include "build/baserom/object_kzsaku.o" + number 6 + include "build/assets/objects/object_kzsaku/object_kzsaku.o" endseg beginseg name "object_obj_milk_bin" compress romalign 0x1000 - include "build/baserom/object_obj_milk_bin.o" + number 6 + include "build/assets/objects/object_obj_milk_bin/object_obj_milk_bin.o" endseg beginseg name "object_random_obj" compress romalign 0x1000 - include "build/baserom/object_random_obj.o" + number 6 + include "build/assets/objects/object_random_obj/object_random_obj.o" endseg beginseg name "object_kujiya" compress romalign 0x1000 - include "build/baserom/object_kujiya.o" + number 6 + include "build/assets/objects/object_kujiya/object_kujiya.o" endseg beginseg name "object_kitan" compress romalign 0x1000 - include "build/baserom/object_kitan.o" + number 6 + include "build/assets/objects/object_kitan/object_kitan.o" endseg beginseg name "object_gi_mask06" compress romalign 0x1000 - include "build/baserom/object_gi_mask06.o" + number 6 + include "build/assets/objects/object_gi_mask06/object_gi_mask06.o" endseg beginseg name "object_gi_mask16" compress romalign 0x1000 - include "build/baserom/object_gi_mask16.o" + number 6 + include "build/assets/objects/object_gi_mask16/object_gi_mask16.o" endseg beginseg name "object_astr_obj" compress romalign 0x1000 - include "build/baserom/object_astr_obj.o" + number 6 + include "build/assets/objects/object_astr_obj/object_astr_obj.o" endseg beginseg name "object_bsb" compress romalign 0x1000 - include "build/baserom/object_bsb.o" + number 6 + include "build/assets/objects/object_bsb/object_bsb.o" endseg beginseg name "object_fall2" compress romalign 0x1000 - include "build/baserom/object_fall2.o" + number 6 + include "build/assets/objects/object_fall2/object_fall2.o" endseg beginseg name "object_sth" compress romalign 0x1000 - include "build/baserom/object_sth.o" + number 6 + include "build/assets/objects/object_sth/object_sth.o" endseg beginseg name "object_gi_mssa" compress romalign 0x1000 - include "build/baserom/object_gi_mssa.o" + number 6 + include "build/assets/objects/object_gi_mssa/object_gi_mssa.o" endseg beginseg name "object_smtower" compress romalign 0x1000 - include "build/baserom/object_smtower.o" + number 6 + include "build/assets/objects/object_smtower/object_smtower.o" endseg beginseg name "object_gi_mask21" compress romalign 0x1000 - include "build/baserom/object_gi_mask21.o" + number 6 + include "build/assets/objects/object_gi_mask21/object_gi_mask21.o" endseg beginseg name "object_yado_obj" compress romalign 0x1000 - include "build/baserom/object_yado_obj.o" + number 6 + include "build/assets/objects/object_yado_obj/object_yado_obj.o" endseg beginseg name "object_syoten" compress romalign 0x1000 - include "build/baserom/object_syoten.o" + number 6 + include "build/assets/objects/object_syoten/object_syoten.o" endseg beginseg name "object_moonend" compress romalign 0x1000 - include "build/baserom/object_moonend.o" + number 6 + include "build/assets/objects/object_moonend/object_moonend.o" endseg beginseg name "object_ob" compress romalign 0x1000 - include "build/baserom/object_ob.o" + number 6 + include "build/assets/objects/object_ob/object_ob.o" endseg beginseg name "object_gi_bottle_04" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_04.o" + number 6 + include "build/assets/objects/object_gi_bottle_04/object_gi_bottle_04.o" endseg beginseg name "object_and" compress romalign 0x1000 - include "build/baserom/object_and.o" + number 6 + include "build/assets/objects/object_and/object_and.o" endseg beginseg name "object_obj_danpeilift" compress romalign 0x1000 - include "build/baserom/object_obj_danpeilift.o" + number 6 + include "build/assets/objects/object_obj_danpeilift/object_obj_danpeilift.o" endseg beginseg name "object_drs" compress romalign 0x1000 - include "build/baserom/object_drs.o" + number 6 + include "build/assets/objects/object_drs/object_drs.o" endseg beginseg name "object_msmo" compress romalign 0x1000 - include "build/baserom/object_msmo.o" + number 6 + include "build/assets/objects/object_msmo/object_msmo.o" endseg beginseg name "object_an4" compress romalign 0x1000 - include "build/baserom/object_an4.o" + number 6 + include "build/assets/objects/object_an4/object_an4.o" endseg beginseg name "object_wdor01" compress romalign 0x1000 - include "build/baserom/object_wdor01.o" + number 6 + include "build/assets/objects/object_wdor01/object_wdor01.o" endseg beginseg name "object_wdor02" compress romalign 0x1000 - include "build/baserom/object_wdor02.o" + number 6 + include "build/assets/objects/object_wdor02/object_wdor02.o" endseg beginseg name "object_wdor03" compress romalign 0x1000 - include "build/baserom/object_wdor03.o" + number 6 + include "build/assets/objects/object_wdor03/object_wdor03.o" endseg beginseg name "object_wdor04" compress romalign 0x1000 - include "build/baserom/object_wdor04.o" + number 6 + include "build/assets/objects/object_wdor04/object_wdor04.o" endseg beginseg name "object_wdor05" compress romalign 0x1000 - include "build/baserom/object_wdor05.o" + number 6 + include "build/assets/objects/object_wdor05/object_wdor05.o" endseg beginseg name "object_stk3" compress romalign 0x1000 - include "build/baserom/object_stk3.o" + number 6 + include "build/assets/objects/object_stk3/object_stk3.o" endseg beginseg name "object_kinsta1_obj" compress romalign 0x1000 - include "build/baserom/object_kinsta1_obj.o" + number 6 + include "build/assets/objects/object_kinsta1_obj/object_kinsta1_obj.o" endseg beginseg name "object_kinsta2_obj" compress romalign 0x1000 - include "build/baserom/object_kinsta2_obj.o" + number 6 + include "build/assets/objects/object_kinsta2_obj/object_kinsta2_obj.o" endseg beginseg name "object_bh" compress romalign 0x1000 - include "build/baserom/object_bh.o" + number 6 + include "build/assets/objects/object_bh/object_bh.o" endseg beginseg name "object_gi_mask17" compress romalign 0x1000 - include "build/baserom/object_gi_mask17.o" + number 6 + include "build/assets/objects/object_gi_mask17/object_gi_mask17.o" endseg beginseg name "object_gi_mask22" compress romalign 0x1000 - include "build/baserom/object_gi_mask22.o" + number 6 + include "build/assets/objects/object_gi_mask22/object_gi_mask22.o" endseg beginseg name "object_lbfshot" compress romalign 0x1000 - include "build/baserom/object_lbfshot.o" + number 6 + include "build/assets/objects/object_lbfshot/object_lbfshot.o" endseg beginseg name "object_fusen" compress romalign 0x1000 - include "build/baserom/object_fusen.o" + number 6 + include "build/assets/objects/object_fusen/object_fusen.o" endseg beginseg name "object_ending_obj" compress romalign 0x1000 - include "build/baserom/object_ending_obj.o" + number 6 + include "build/assets/objects/object_ending_obj/object_ending_obj.o" endseg beginseg name "object_gi_mask13" compress romalign 0x1000 - include "build/baserom/object_gi_mask13.o" + number 6 + include "build/assets/objects/object_gi_mask13/object_gi_mask13.o" endseg beginseg diff --git a/src/boot_O2_g3/idle.c b/src/boot_O2_g3/idle.c index da93f13fdb..2a52e7dcec 100644 --- a/src/boot_O2_g3/idle.c +++ b/src/boot_O2_g3/idle.c @@ -1,5 +1,6 @@ #include "prevent_bss_reordering.h" #include "global.h" +#include "prevent_bss_reordering.h" u8 D_80096B20 = 1; vu8 gViConfigUseDefault = 1; diff --git a/src/buffers/gfxpools.c b/src/buffers/gfxpools.c new file mode 100644 index 0000000000..a91c87bed9 --- /dev/null +++ b/src/buffers/gfxpools.c @@ -0,0 +1,3 @@ +#include "global.h" + +GfxPool gGfxPools[2]; diff --git a/src/buffers/gfxstack.c b/src/buffers/gfxstack.c new file mode 100644 index 0000000000..2b158d1414 --- /dev/null +++ b/src/buffers/gfxstack.c @@ -0,0 +1,3 @@ +#include "global.h" + +u8 gGfxSPTaskStack[0x400]; diff --git a/src/buffers/gfxbuffers.c b/src/buffers/gfxyield.c similarity index 56% rename from src/buffers/gfxbuffers.c rename to src/buffers/gfxyield.c index ed0d12b6c2..73810d4acd 100644 --- a/src/buffers/gfxbuffers.c +++ b/src/buffers/gfxyield.c @@ -1,7 +1,3 @@ #include "global.h" u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE]; - -u8 gGfxSPTaskStack[0x400]; - -GfxPool gGfxPools[2]; From a0370e38b4451809f6dbf41bc3f4e1f423c91631 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sun, 19 Dec 2021 13:52:06 -0300 Subject: [PATCH 09/27] Fix bug in progress.py (#518) * Fix autogenarted names regex * Use sizes from map file instead of reading the asm directly * Speed up * Fix gameplay_object_exchange_static being in the wrong category * Fix regex again --- tools/filelists/mm.us.rev1/objects.csv | 1 - tools/filelists/mm.us.rev1/segments.csv | 1 + tools/progress.py | 227 +++++++++++------------- 3 files changed, 102 insertions(+), 127 deletions(-) diff --git a/tools/filelists/mm.us.rev1/objects.csv b/tools/filelists/mm.us.rev1/objects.csv index 15d1f4ac26..187ec1c11a 100644 --- a/tools/filelists/mm.us.rev1/objects.csv +++ b/tools/filelists/mm.us.rev1/objects.csv @@ -1,7 +1,6 @@ 649,gameplay_keep 650,gameplay_field_keep 651,gameplay_dangeon_keep -652,gameplay_object_exchange_static 653,object_link_boy 654,object_link_child 655,object_link_goron diff --git a/tools/filelists/mm.us.rev1/segments.csv b/tools/filelists/mm.us.rev1/segments.csv index f397c8e1cf..b22534d94e 100644 --- a/tools/filelists/mm.us.rev1/segments.csv +++ b/tools/filelists/mm.us.rev1/segments.csv @@ -1,3 +1,4 @@ +652,gameplay_object_exchange_static 1539,anime_model_1_static 1540,anime_model_2_static 1541,anime_model_3_static diff --git a/tools/progress.py b/tools/progress.py index 2ac68a076b..dccd743d78 100755 --- a/tools/progress.py +++ b/tools/progress.py @@ -14,7 +14,9 @@ NOT_ATTEMPTED_PATTERN = r'#pragma\s+GLOBAL_ASM\s*\(\s*"(.*?)"\s*\)' # This is the format ZAPD uses to autogenerate variable names # It should not be used for properly documented variables -AUTOGENERATED_ASSET_NAME = re.compile(r".+[0-9A-Fa-f]{6}$") +AUTOGENERATED_ASSET_NAME = re.compile(r".+0[0-9A-Fa-f]{5}") + +ASM_JMP_LABEL = re.compile(r"^(?PL[0-9A-F]{8})$") # TODO: consider making this a parameter of this script GAME_VERSION = "mm.us.rev1" @@ -53,28 +55,12 @@ def GetCsvFilelist(version, filelist): with open(path, newline='') as f: return list(csv.reader(f, delimiter=',')) -def GetRemovableSize(functions_to_count): +def GetRemovableSize(functionSizes, functions_to_count): size = 0 - for asm_file_path in functions_to_count: - if "//" in asm_file_path: - raise RuntimeError(f"Invalid file path: {asm_file_path}") - file_size = 0 - asm_lines = ReadAllLines(asm_file_path) - shouldCount = True - - for asm_line in asm_lines: - if asm_line[0] == ".": - if asm_line.startswith(".text") or asm_line.startswith(".section .text"): - shouldCount = True - elif ".rdata" in asm_line or ".late_rodata" in asm_line: - shouldCount = False - - if shouldCount: - if (asm_line[0:2] == "/*" and asm_line[28:30] == "*/"): - file_size += 4 - - size += file_size + for func in functions_to_count: + if func in functionSizes: + size += functionSizes[func] return size @@ -82,11 +68,6 @@ def CalculateMapSizes(mapFileList): for mapFile in mapFileList: accumulatedSize = 0 - if mapFile["section"] != ".data": - continue - if not mapFile["name"].startswith("build/assets/"): - continue - symbolCount = len(mapFile["symbols"]) if symbolCount == 0: continue @@ -107,6 +88,19 @@ def CalculateMapSizes(mapFileList): mapFile["symbols"][-1]["size"] = size return mapFileList +def GetFunctionSizes(mapFileList): + functionSizes = dict() + + for mapFile in mapFileList: + if mapFile["section"] != ".text": + continue + + for symbol in mapFile["symbols"]: + symbolName = symbol["name"] + functionSizes[symbolName] = symbol["size"] + + return functionSizes + def CalculateNonNamedAssets(mapFileList, assetsTracker): for mapFile in mapFileList: if mapFile["section"] != ".data": @@ -171,16 +165,31 @@ for assetCat in assetsCategories: # Initialize all the code values -src = 0 -src_code = 0 -src_boot = 0 -src_ovl = 0 -src_libultra = 0 -asm = 0 -asm_code = 0 -asm_boot = 0 -asm_ovl = 0 -asm_libultra = 0 +srcCategories = [ + "boot", + "libultra", + "code", + "overlays", +] + +srcCategoriesFixer = { + "boot_O2": "boot", + "boot_O2_g3": "boot", +} + +srcTracker = dict() +asmTracker = dict() + +for srcCat in srcCategories: + srcTracker[srcCat] = dict() + srcTracker[srcCat]["currentSize"] = 0 + srcTracker[srcCat]["totalSize"] = 0 + srcTracker[srcCat]["percent"] = 0 + + asmTracker[srcCat] = dict() + asmTracker[srcCat]["currentSize"] = 0 + asmTracker[srcCat]["totalSize"] = 0 + asmTracker[srcCat]["percent"] = 0 mapFileList = [] @@ -199,35 +208,20 @@ for line in map_file: if (section == ".text"): objFileName = objFileSplit[-1].split(".o")[0] + srcCat = obj_file.split("/")[2] + if srcCat in srcCategoriesFixer: + srcCat = srcCategoriesFixer[srcCat] if objFileName in fileSectionFixer: correctSection = fileSectionFixer[objFileName] - if correctSection == "code": - src_code += file_size - elif correctSection == "libultra": - src_libultra += file_size - elif correctSection == "boot": - src_boot += file_size - elif correctSection == "overlays": - src_ovl += file_size - elif (obj_file.startswith("build/src")): - if (obj_file.startswith("build/src/code")): - src_code += file_size - elif (obj_file.startswith("build/src/libultra")): - src_libultra += file_size - elif (obj_file.startswith("build/src/boot")): - src_boot += file_size - elif (obj_file.startswith("build/src/overlays")): - src_ovl += file_size + if correctSection in srcTracker: + srcTracker[correctSection]["totalSize"] += file_size + elif obj_file.startswith("build/src"): + if srcCat in srcTracker: + srcTracker[srcCat]["totalSize"] += file_size elif (obj_file.startswith("build/asm")): - if (obj_file.startswith("build/asm/code")): - asm_code += file_size - elif (obj_file.startswith("build/asm/libultra")): - asm_libultra += file_size - elif (obj_file.startswith("build/asm/boot")): - asm_boot += file_size - elif (obj_file.startswith("build/asm/overlays")): - asm_ovl += file_size + if srcCat in asmTracker: + asmTracker[srcCat]["totalSize"] += file_size if section == ".data": if obj_file.startswith("build/assets/"): @@ -244,36 +238,41 @@ for line in map_file: varName = varName.strip() if varName == "0x0": continue - #print(varVram, varName) + if ASM_JMP_LABEL.search(varName) is not None: + # Filter out jump table's labels + continue symbolData = {"name": varName, "vram": varVram, "size": 0} mapFileList[-1]["symbols"].append(symbolData) mapFileList = CalculateMapSizes(mapFileList) +functionSizes = GetFunctionSizes(mapFileList) assetsTracker = CalculateNonNamedAssets(mapFileList, assetsTracker) # Add libultra to boot. -src_boot += src_libultra -asm_boot += asm_libultra +srcTracker["boot"]["totalSize"] += srcTracker["libultra"]["totalSize"] +asmTracker["boot"]["totalSize"] += asmTracker["libultra"]["totalSize"] +del srcTracker["libultra"] +del asmTracker["libultra"] # Calculate Non-Matching -non_matching_functions_ovl = list(filter(lambda x: "/overlays/" in x, non_matching_functions)) -non_matching_functions_code = list(filter(lambda x: "/code/" in x, non_matching_functions)) -non_matching_functions_boot = list(filter(lambda x: "/boot/" in x, non_matching_functions)) +non_matching_functions_ovl = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/overlays/" in x, non_matching_functions))) +non_matching_functions_code = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/code/" in x, non_matching_functions))) +non_matching_functions_boot = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/boot/" in x, non_matching_functions))) -non_matching_asm_ovl = GetRemovableSize(non_matching_functions_ovl) -non_matching_asm_code = GetRemovableSize(non_matching_functions_code) -non_matching_asm_boot = GetRemovableSize(non_matching_functions_boot) +non_matching_asm_ovl = GetRemovableSize(functionSizes, non_matching_functions_ovl) +non_matching_asm_code = GetRemovableSize(functionSizes, non_matching_functions_code) +non_matching_asm_boot = GetRemovableSize(functionSizes, non_matching_functions_boot) # Calculate Not Attempted -not_attempted_functions_ovl = list(filter(lambda x: "/overlays/" in x, not_attempted_functions)) -not_attempted_functions_code = list(filter(lambda x: "/code/" in x, not_attempted_functions)) -not_attempted_functions_boot = list(filter(lambda x: "/boot/" in x, not_attempted_functions)) +not_attempted_functions_ovl = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/overlays/" in x, not_attempted_functions))) +not_attempted_functions_code = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/code/" in x, not_attempted_functions))) +not_attempted_functions_boot = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/boot/" in x, not_attempted_functions))) -not_attempted_asm_ovl = GetRemovableSize(not_attempted_functions_ovl) -not_attempted_asm_code = GetRemovableSize(not_attempted_functions_code) -not_attempted_asm_boot = GetRemovableSize(not_attempted_functions_boot) +not_attempted_asm_ovl = GetRemovableSize(functionSizes, not_attempted_functions_ovl) +not_attempted_asm_code = GetRemovableSize(functionSizes, not_attempted_functions_code) +not_attempted_asm_boot = GetRemovableSize(functionSizes, not_attempted_functions_boot) # All the non matching asm is the sum of non-matching code non_matching_asm = non_matching_asm_ovl + non_matching_asm_code + non_matching_asm_boot @@ -282,18 +281,19 @@ non_matching_asm = non_matching_asm_ovl + non_matching_asm_code + non_matching_a not_attempted_asm = not_attempted_asm_ovl + not_attempted_asm_code + not_attempted_asm_boot # Calculate total decompiled for each bucket by taking out the non-matching and not attempted in ovl/code/boot buckets. -code = src_code - (non_matching_asm_code + not_attempted_asm_code) -boot = src_boot - (non_matching_asm_boot + not_attempted_asm_boot) -ovl = src_ovl - (non_matching_asm_ovl + not_attempted_asm_ovl) +srcTracker["code"]["currentSize"] = srcTracker["code"]["totalSize"] - (non_matching_asm_code + not_attempted_asm_code) +srcTracker["boot"]["currentSize"] = srcTracker["boot"]["totalSize"] - (non_matching_asm_boot + not_attempted_asm_boot) +srcTracker["overlays"]["currentSize"] = srcTracker["overlays"]["totalSize"] - (non_matching_asm_ovl + not_attempted_asm_ovl) # Total code bucket sizes -code_size = src_code # + asm_code -boot_size = src_boot # + asm_boot -ovl_size = src_ovl # + asm_ovl -handwritten = asm_code + asm_boot + asm_ovl +handwritten = 0 +for srcCat in asmTracker: + handwritten += asmTracker[srcCat]["totalSize"] # Calculate the total amount of decompilable code -total = code_size + boot_size + ovl_size +total = 0 +for srcCat in asmTracker: + total += srcTracker[srcCat]["totalSize"] # Calculate size of all assets for assetCat in assetsTracker: @@ -305,11 +305,12 @@ if args.matching: assetsTracker[assetCat]["currentSize"] -= assetsTracker[assetCat]["removableSize"] # Calculate asm and src totals -src = src_code + src_boot + src_ovl -asm = asm_code + asm_boot + asm_ovl - -# Take out the non-matchings and not attempted in grand totals -src -= non_matching_asm + not_attempted_asm +src = 0 +for srcCat in srcTracker: + src += srcTracker[srcCat]["currentSize"] +asm = 0 +for srcCat in asmTracker: + asm += asmTracker[srcCat]["totalSize"] asm += non_matching_asm + not_attempted_asm # Calculate assets totals @@ -319,9 +320,8 @@ assets_total = sum(x["totalSize"] for x in assetsTracker.values()) # Convert vaules to percentages src_percent = 100 * src / total asm_percent = 100 * asm / total -code_percent = 100 * code / code_size -boot_percent = 100 * boot / boot_size -ovl_percent = 100 * ovl / ovl_size +for srcCat in ["boot", "code", "overlays"]: + srcTracker[srcCat]["percent"] = 100 * srcTracker[srcCat]["currentSize"] / srcTracker[srcCat]["totalSize"] assets_percent = 100 * assets / assets_total @@ -336,36 +336,6 @@ bytes_per_rupee = bytes_per_mask / max_rupees masks = int(src / bytes_per_mask) rupees = int((src % bytes_per_mask) / bytes_per_rupee) -# Debug print statements for the values -#print("Total: ", total) -#print("src: ", src) -#print("asm: ", asm) -#print("") -#print("src_code: ", src_code) -#print("src_boot: ", src_boot) -#print("src_ovl: ", src_ovl) -#print("") -#print("asm_code: ", asm_code) -#print("asm_boot: ", asm_boot) -#print("asm_ovl: ", asm_ovl) -#print("") -#print("Nonmatching code: ", non_matching_asm_code) -#print("Nonmatching boot: ", non_matching_asm_boot) -#print("Nonmatching ovl: ", non_matching_asm_ovl) -#print("") -#print("Not attempted code: ", not_attempted_asm_code) -#print("Not attempted boot: ", not_attempted_asm_boot) -#print("Not attempted ovl: ", not_attempted_asm_ovl) -#print("") -#print("code_size: ", code_size) -#print("boot_size: ", boot_size) -#print("ovl_size: ", ovl_size) -#print("") -#print("code: ", code) -#print("boot: ", boot) -#print("ovl: ", ovl) -#print("") - if args.format == 'csv': version = 2 git_object = git.Repo().head.object @@ -373,7 +343,11 @@ if args.format == 'csv': git_hash = git_object.hexsha csv_list = [ version, timestamp, git_hash, src, total, - boot, boot_size, code, code_size, ovl, ovl_size, + ] + for srcCat in ["boot", "code", "overlays"]: + csv_list += [srcTracker[srcCat]["currentSize"], srcTracker[srcCat]["totalSize"]] + + csv_list += [ asm, len(non_matching_functions), ] csv_list += [ @@ -396,9 +370,10 @@ elif args.format == 'text': assetsAdjective = "debinarized" if not args.matching else "identified" print("src: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(src, total, adjective, round(src_percent, 4))) - print(" boot: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(boot, boot_size, adjective, round(boot_percent, 4))) - print(" code: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(code, code_size, adjective, round(code_percent, 4))) - print(" overlays: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(ovl, ovl_size, adjective, round(ovl_percent, 4))) + + for srcCat in ["boot", "code", "overlays"]: + src = srcTracker[srcCat] + print(" {:<10} {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(f"{srcCat}:", src["currentSize"], src["totalSize"], adjective, round(src["percent"], 4))) print() print("assets: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(assets, assets_total, assetsAdjective, round(assets_percent, 4))) From d998e8d8c51d1956249eb97429623f81b21ebf90 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sun, 19 Dec 2021 15:27:14 -0300 Subject: [PATCH 10/27] Fix readme badge (#515) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3768ef1d99..80d1e5d549 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [jenkins-badge]: https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins.deco.mp%2Fjob%2FMM%2Fjob%2Fmaster [progress]: https://zelda64.dev/games/mm -[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/reports/progress-mm-shield.json +[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/assets/csv/progress-mm-shield.json [contributors]: https://github.com/zeldaret/mm/graphs/contributors [contributors-badge]: https://img.shields.io/github/contributors/zeldaret/mm From 8662b35a698555be7ff762b87ebecf8a7bb2c516 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sun, 19 Dec 2021 18:34:50 +0000 Subject: [PATCH 11/27] Update z64compress (#516) * git subrepo pull (merge) --force tools/z64compress subrepo: subdir: "tools/z64compress" merged: "5da31326" upstream: origin: "https://github.com/z64me/z64compress.git" branch: "main" commit: "5da31326" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * Update wrapper * If building with NON_MATCHING, do not pass --matching to z64compress --- Makefile | 8 +++++++- tools/z64compress/.gitrepo | 4 ++-- tools/z64compress/Makefile | 17 +++++++++++------ tools/z64compress_wrapper.py | 37 +++++++++++++++++++++++------------- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 2578a59301..0ee73f25eb 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,12 @@ else CC_CHECK += -m32 endif +# rom compression flags +COMPFLAGS := --threads $(N_THREADS) +ifneq ($(NON_MATCHING),1) + COMPFLAGS += --matching +endif + #### Files #### # ROM image @@ -211,7 +217,7 @@ $(ROM): $(ELF) $(ELF2ROM) -cic 6105 $< $@ $(ROMC): uncompressed - python3 tools/z64compress_wrapper.py --mb 32 --matching --threads $(N_THREADS) $(ROM) $@ $(ELF) build/$(SPEC) + python3 tools/z64compress_wrapper.py $(COMPFLAGS) $(ROM) $@ $(ELF) build/$(SPEC) $(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) build/ldscript.txt build/undefined_syms.txt $(LD) -T build/undefined_syms.txt -T build/ldscript.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map build/mm.map -o $@ diff --git a/tools/z64compress/.gitrepo b/tools/z64compress/.gitrepo index 905b330d9c..183bfc3267 100644 --- a/tools/z64compress/.gitrepo +++ b/tools/z64compress/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/z64me/z64compress.git branch = main - commit = ac5b1a0d0b23346362a68a107da3478227f8e703 - parent = 33e3aa92181a0543826adc10a5f3304d60b391dd + commit = 5da3132606e4fd427a8d72b8428e4f921cd6e56f + parent = 837eb1c80687fe9b57a3c7b841547c33feeed6c7 method = merge cmdver = 0.4.3 diff --git a/tools/z64compress/Makefile b/tools/z64compress/Makefile index bb80891b13..f16167ccd2 100644 --- a/tools/z64compress/Makefile +++ b/tools/z64compress/Makefile @@ -1,23 +1,28 @@ CC := gcc -CFLAGS := -DNDEBUG -s -Os -flto -Wall -Wextra -march=native -mtune=native +CFLAGS := -DNDEBUG -s -Os -flto -Wall -Wextra -OBJ_DIR := o - -# Target platform, specify with TARGET= on the command line, linux64 is default +# Target platform, specify with TARGET= on the command line, linux64 is default. # Currently supported: linux64, linux32, win32 TARGET ?= linux64 ifeq ($(TARGET),linux32) TARGET_CFLAGS := -m32 else ifeq ($(TARGET),win32) -# If using a cross compiler, specify the compiler executable on the command line +# If using a cross compiler, specify the compiler executable on the command line. # make TARGET=win32 CC=~/c/mxe/usr/bin/i686-w64-mingw32.static-gcc TARGET_LIBS := -mconsole -municode else ifneq ($(TARGET),linux64) $(error Supported targets: linux64, linux32, win32) endif -OBJ_DIR := $(OBJ_DIR)/$(TARGET) +# Whether to use native optimizations, specify with NATIVE_OPT=0/1 on the command line, default is 0. +# This is not supported by all compilers which is particularly an issue on Mac, and may inhibit tests. +NATIVE_OPT ?= 0 +ifeq ($(NATIVE_OPT),1) + TARGET_CFLAGS += -march=native -mtune=native +endif + +OBJ_DIR := o/$(TARGET) $(OBJ_DIR)/src/enc/%.o: CFLAGS := -DNDEBUG -s -Ofast -flto -Wall diff --git a/tools/z64compress_wrapper.py b/tools/z64compress_wrapper.py index d70db84265..ff2bf1bb6c 100644 --- a/tools/z64compress_wrapper.py +++ b/tools/z64compress_wrapper.py @@ -1,15 +1,19 @@ #!/usr/bin/env python3 # # z64compress wrapper for decomp projects -# Arguments: [cache directory] [num threads] +# https://github.com/z64me/z64compress +# Arguments: [--cache [cache directory]] [--threads [num threads]] [--mb [target rom size]] [--matching] +# Example Makefile usage: +# python3 tools/z64compress_wrapper.py --matching --threads $(shell nproc) $< $@ $(ELF) build/$(SPEC) # import argparse, itertools, subprocess, sys + from elftools.elf.elffile import ELFFile from elftools.elf.sections import SymbolTableSection # Args from command line -parser = argparse.ArgumentParser(description="Compress rom produced by the OoT Decomp project") +parser = argparse.ArgumentParser(description="Compress rom produced by the OoT and MM Decomp projects") parser.add_argument("in_rom", help="uncompressed input rom filename") parser.add_argument("out_rom", help="compressed output rom filename") @@ -17,7 +21,7 @@ parser.add_argument("elf", help="path to the uncompressed rom elf file") parser.add_argument("spec", help="path to processed spec file") parser.add_argument("--cache", help="cache directory") parser.add_argument("--threads", help="number of threads to run compression on, 0 disables multithreading") -parser.add_argument("--mb", help="compressed rom size in MB, default 32") +parser.add_argument("--mb", help="compressed rom size in MB, default is the smallest multiple of 8mb fitting the whole rom") parser.add_argument("--matching", help="matching compression, forfeits some useful optimizations", action="store_true") parser.add_argument("--stderr", help="z64compress will write its output messages to stderr instead of stdout", action="store_true") @@ -26,14 +30,13 @@ args = parser.parse_args() IN_ROM = args.in_rom OUT_ROM = args.out_rom -STDOUT = not args.stderr - elf_path = args.elf CACHE_DIR = args.cache N_THREADS = int(args.threads or 0) -MB = int(args.mb or 32) -matching = args.matching +MB = args.mb +MATCHING = args.matching +STDOUT = not args.stderr # Get segments to compress @@ -83,8 +86,8 @@ def get_dmadata_start_len(): if dmadata_start != -1 and dmadata_end != -1: break - assert dmadata_start != -1 - assert dmadata_end != -1 + assert dmadata_start != -1, "_dmadataSegmentRomStart symbol not found in supplied ELF" + assert dmadata_end != -1, "_dmadataSegmentRomEnd symbol not found in supplied ELF" return dmadata_start, (dmadata_end - dmadata_start)//0x10 @@ -92,13 +95,21 @@ DMADATA_ADDR, DMADATA_COUNT = get_dmadata_start_len() # Run -cmd = f"./tools/z64compress/z64compress --in {IN_ROM} --out {OUT_ROM}{' --matching' if matching else ''} \ ---mb {MB} --codec yaz{f' --cache {CACHE_DIR}' if CACHE_DIR is not None else ''} --dma 0x{DMADATA_ADDR:X},{DMADATA_COUNT} \ ---compress {COMPRESS_INDICES}{f' --threads {N_THREADS}' if N_THREADS > 0 else ''}{f' --only-stdout' if STDOUT else ''}" +cmd = f"./tools/z64compress/z64compress \ +--in {IN_ROM} \ +--out {OUT_ROM}\ +{' --matching' if MATCHING else ''}\ +{f' --mb {MB}' if MB is not None else ''} \ +--codec yaz\ +{f' --cache {CACHE_DIR}' if CACHE_DIR is not None else ''} \ +--dma 0x{DMADATA_ADDR:X},{DMADATA_COUNT} \ +--compress {COMPRESS_INDICES}\ +{f' --threads {N_THREADS}' if N_THREADS > 0 else ''}\ +{f' --only-stdout' if STDOUT else ''}" print(cmd) - try: subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as e: + # Return the same error code for the wrapper if z64compress fails sys.exit(e.returncode) From 89829b99052c0aa083010906e8b6bfa1addb1696 Mon Sep 17 00:00:00 2001 From: Electrk Date: Sun, 19 Dec 2021 10:47:08 -0800 Subject: [PATCH 12/27] EnInvisibleRuppe OK (#508) * EnInvisibleRuppe OK * Style changes as per review * Update reloc * Apply feedback --- spec | 3 +- .../z_en_invisible_ruppe.c | 96 ++++++++++++++++--- .../z_en_invisible_ruppe.h | 7 +- 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/spec b/spec index debfa85bf8..5c84ef301a 100644 --- a/spec +++ b/spec @@ -5504,8 +5504,7 @@ beginseg name "ovl_En_Invisible_Ruppe" compress include "build/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.o" - include "build/data/ovl_En_Invisible_Ruppe/ovl_En_Invisible_Ruppe.data.o" - include "build/data/ovl_En_Invisible_Ruppe/ovl_En_Invisible_Ruppe.reloc.o" + include "build/src/overlays/actors/ovl_En_Invisible_Ruppe/ovl_En_Invisible_Ruppe_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c index 24aa7d33bc..f459fbf53a 100644 --- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c +++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c @@ -14,10 +14,10 @@ void EnInvisibleRuppe_Init(Actor* thisx, GlobalContext* globalCtx); void EnInvisibleRuppe_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnInvisibleRuppe_Update(Actor* thisx, GlobalContext* globalCtx); +void func_80C258A0(EnInvisibleRuppe* this, GlobalContext* globalCtx); void func_80C2590C(EnInvisibleRuppe* this, GlobalContext* globalCtx); void func_80C259E8(EnInvisibleRuppe* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Invisible_Ruppe_InitVars = { ACTOR_EN_INVISIBLE_RUPPE, ACTORCAT_NPC, @@ -30,25 +30,95 @@ const ActorInit En_Invisible_Ruppe_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C25B50 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_NO_PUSH | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, + { 10, 30, 0, { 0, 0, 0 } }, }; -#endif +void func_80C258A0(EnInvisibleRuppe* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 32.0f, 30.0f, 0.0f, 4); +} -extern ColliderCylinderInit D_80C25B50; +void func_80C2590C(EnInvisibleRuppe* this, GlobalContext* globalCtx) { + if (this->collider.base.ocFlags1 & OC1_HIT) { + switch (INVISIBLERUPPE_GET_3(this)) { + case 0: + play_sound(NA_SE_SY_GET_RUPY); + Item_DropCollectible(globalCtx, &this->actor.world.pos, 0x8000 | ITEM00_RUPEE_GREEN); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/func_80C258A0.s") + case 1: + play_sound(NA_SE_SY_GET_RUPY); + Item_DropCollectible(globalCtx, &this->actor.world.pos, 0x8000 | ITEM00_RUPEE_BLUE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/func_80C2590C.s") + case 2: + play_sound(NA_SE_SY_GET_RUPY); + Item_DropCollectible(globalCtx, &this->actor.world.pos, 0x8000 | ITEM00_RUPEE_RED); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/func_80C259E8.s") + if (this->unk_190 >= 0) { + Actor_SetSwitchFlag(globalCtx, this->unk_190); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/EnInvisibleRuppe_Init.s") + this->actionFunc = func_80C259E8; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/EnInvisibleRuppe_Destroy.s") +void func_80C259E8(EnInvisibleRuppe* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/EnInvisibleRuppe_Update.s") +void EnInvisibleRuppe_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnInvisibleRuppe* this = THIS; + + this->unk_190 = INVISIBLERUPPE_GET_1FC(this); + + if (this->unk_190 == 0x7F) { + this->unk_190 = -1; + } + + if ((this->unk_190 >= 0) && Flags_GetSwitch(globalCtx, this->unk_190)) { + Actor_MarkForDeath(&this->actor); + return; + } + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + + this->actionFunc = func_80C2590C; +} + +void EnInvisibleRuppe_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnInvisibleRuppe* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnInvisibleRuppe_Update(Actor* thisx, GlobalContext* globalCtx) { + EnInvisibleRuppe* this = THIS; + + this->actionFunc(this, globalCtx); + func_80C258A0(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h index 66b42d520c..eef1acbfe3 100644 --- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h +++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h @@ -7,9 +7,14 @@ struct EnInvisibleRuppe; typedef void (*EnInvisibleRuppeActionFunc)(struct EnInvisibleRuppe*, GlobalContext*); +#define INVISIBLERUPPE_GET_3(thisx) ((thisx)->actor.params & 3) +#define INVISIBLERUPPE_GET_1FC(thisx) (((thisx)->actor.params & 0x1FC) >> 2) + typedef struct EnInvisibleRuppe { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x50]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ s16 unk_190; + /* 0x0192 */ s16 unk_192; /* 0x0194 */ EnInvisibleRuppeActionFunc actionFunc; } EnInvisibleRuppe; // size = 0x198 From c6c37680224af6407c0157c5fb902e6951b623d6 Mon Sep 17 00:00:00 2001 From: Lucas Shaw <49287729+shawlucas@users.noreply.github.com> Date: Sun, 19 Dec 2021 14:14:18 -0500 Subject: [PATCH 13/27] ovl_Obj_Yado ok (#500) * ovl_Obj_Yado OK * rename struct member * rename colorFlag to isNight --- spec | 4 +- src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c | 49 ++++++++++++++----- src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h | 2 +- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/spec b/spec index 5c84ef301a..35a9011c8f 100644 --- a/spec +++ b/spec @@ -5294,9 +5294,7 @@ beginseg name "ovl_Obj_Yado" compress include "build/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.o" - include "build/data/ovl_Obj_Yado/ovl_Obj_Yado.data.o" - include "build/data/ovl_Obj_Yado/ovl_Obj_Yado.bss.o" - include "build/data/ovl_Obj_Yado/ovl_Obj_Yado.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Yado/ovl_Obj_Yado_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c index 73ebea007b..2d8689d4fd 100644 --- a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c +++ b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c @@ -15,7 +15,6 @@ void ObjYado_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjYado_Update(Actor* thisx, GlobalContext* globalCtx); void ObjYado_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Yado_InitVars = { ACTOR_OBJ_YADO, ACTORCAT_BG, @@ -28,22 +27,50 @@ const ActorInit Obj_Yado_InitVars = { (ActorFunc)ObjYado_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C16420[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +AnimatedMaterial* D_80C16470; -extern InitChainEntry D_80C16420[]; +extern Gfx D_06000320[]; +extern Gfx D_06000430[]; +extern AnimatedMaterial D_060012E8; -extern UNK_TYPE D_06000430; -extern UNK_TYPE D_060012E8; +void ObjYado_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjYado* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + D_80C16470 = (AnimatedMaterial*)Lib_SegmentedToVirtual(&D_060012E8); + this->isNight = gSaveContext.isNight; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Destroy.s") +void ObjYado_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Update.s") +void ObjYado_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjYado* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Draw.s") + this->isNight = gSaveContext.isNight; +} + +void ObjYado_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjYado* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->isNight) { + gSPSegment(POLY_XLU_DISP++, 0x09, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 95, 95, 70, 155)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 0, 40, 40, 255)); + } else { + gSPSegment(POLY_XLU_DISP++, 0x09, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 255, 255, 215, 110)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 255, 255, 215, 255)); + } + + AnimatedMat_Draw(globalCtx, D_80C16470); + func_800BDFC0(globalCtx, D_06000430); + func_800BE03C(globalCtx, D_06000320); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h index ee79705a27..28ffd63dc5 100644 --- a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h +++ b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h @@ -7,7 +7,7 @@ struct ObjYado; typedef struct ObjYado { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ u8 isNight; } ObjYado; // size = 0x148 extern const ActorInit Obj_Yado_InitVars; From 9bf0a5904416944c4fc3c93bc5b62405b19ed198 Mon Sep 17 00:00:00 2001 From: mzxrules Date: Sun, 19 Dec 2021 14:20:45 -0500 Subject: [PATCH 14/27] z_bg_goron_oyu OK (#487) * Initial Decomp of `z_bg_goron_oyu` Note: Waterbox instead of ColHeader would make sense here, confirm and change accordingly. Just to not break the match until its settled for func_800CA1AC... * implement suggested changes, fix other style issues * z_bg_goron_oyu OK * minor improvements * fix clear_tag issue, restore THIS * missed this * format.sh * implement final changes Co-authored-by: MMDecomp --- spec | 3 +- .../actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c | 170 ++++++++++++++++-- .../actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h | 15 +- 3 files changed, 164 insertions(+), 24 deletions(-) diff --git a/spec b/spec index 35a9011c8f..7e3dbfcdbe 100644 --- a/spec +++ b/spec @@ -4131,8 +4131,7 @@ beginseg name "ovl_Bg_Goron_Oyu" compress include "build/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.o" - include "build/data/ovl_Bg_Goron_Oyu/ovl_Bg_Goron_Oyu.data.o" - include "build/data/ovl_Bg_Goron_Oyu/ovl_Bg_Goron_Oyu.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Goron_Oyu/ovl_Bg_Goron_Oyu_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c index b0e79b3db0..e32492e9c0 100644 --- a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c +++ b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c @@ -15,7 +15,13 @@ void BgGoronOyu_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgGoronOyu_Update(Actor* thisx, GlobalContext* globalCtx); void BgGoronOyu_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B40100(BgGoronOyu* this, GlobalContext* globalCtx); +void func_80B400C8(BgGoronOyu* this, GlobalContext* globalCtx); +void func_80B401F8(BgGoronOyu* this, GlobalContext* globalCtx); +void BgGoronOyu_UpdateWaterBoxInfo(BgGoronOyu* this, GlobalContext* globalCtx); +void BgGoronOyu_SpawnParticles(BgGoronOyu* this, GlobalContext* globalCtx); +void func_80B40160(BgGoronOyu* this, GlobalContext* globalCtx); + const ActorInit Bg_Goron_Oyu_InitVars = { ACTOR_BG_GORON_OYU, ACTORCAT_BG, @@ -28,31 +34,163 @@ const ActorInit Bg_Goron_Oyu_InitVars = { (ActorFunc)BgGoronOyu_Draw, }; -#endif +extern Gfx D_06000080; +extern Gfx D_06000158; +extern AnimatedMaterial D_06000968; +extern CollisionHeader D_06000988; -extern UNK_TYPE D_06000968; -extern UNK_TYPE D_06000988; +void func_80B40080(BgGoronOyu* this) { + this->unk_17E = 1; + this->actionFunc = func_80B400C8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40080.s") +void func_80B4009C(BgGoronOyu* this) { + this->unk_17E = 0; + this->initialActorCutscene = this->dyna.actor.cutscene; + this->actionFunc = func_80B40100; + this->unk_164 = 20.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B4009C.s") +void func_80B400C8(BgGoronOyu* this, GlobalContext* globalCtx) { + BgGoronOyu_UpdateWaterBoxInfo(this, globalCtx); + func_80B401F8(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B400C8.s") +void func_80B40100(BgGoronOyu* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->initialActorCutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->initialActorCutscene, &this->dyna.actor); + this->actionFunc = func_80B40160; + } else { + ActorCutscene_SetIntentToPlay(this->initialActorCutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40100.s") +void func_80B40160(BgGoronOyu* this, GlobalContext* globalCtx) { + static Vec3f D_80B40780 = { 0, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40160.s") + Math_StepToF(&this->unk_164, 0.0f, 0.2f); + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y - this->unk_164; + BgGoronOyu_UpdateWaterBoxInfo(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B401F8.s") + if (this->unk_164 <= 0.0f) { + ActorCutscene_Stop(this->initialActorCutscene); + this->unk_164 = 0.0f; + func_80B40080(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40308.s") + func_8019F1C0(&D_80B40780, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40394.s") +void func_80B401F8(BgGoronOyu* this, GlobalContext* globalCtx) { + Player* player; + Vec3f dist; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Init.s") + if (Actor_HasParent(&this->dyna.actor, globalCtx)) { + this->dyna.actor.parent = NULL; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Destroy.s") + player = GET_PLAYER(globalCtx); + Math_Vec3f_DistXYZAndStoreDiff(&this->waterBoxPos, &player->actor.world.pos, &dist); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Update.s") + if (dist.x >= 0.0f && dist.x <= this->waterBoxXLength && dist.z >= 0.0f && dist.z <= this->waterBoxZLength && + fabsf(dist.y) < 100.0f && player->actor.depthInWater > 12.0f) { + func_800B8A1C(&this->dyna.actor, globalCtx, 0xBA, this->dyna.actor.xzDistToPlayer, + fabsf(this->dyna.actor.playerHeightRel)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Draw.s") +void BgGoronOyu_UpdateWaterBoxInfo(BgGoronOyu* this, GlobalContext* globalCtx) { + WaterBox* waterBox; + f32 ySurface; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.z, + &ySurface, &waterBox)) { + Math_Vec3s_ToVec3f(&this->waterBoxPos, &waterBox->minPos); + this->waterBoxXLength = waterBox->xLength; + this->waterBoxZLength = waterBox->zLength; + } +} + +void BgGoronOyu_SpawnParticles(BgGoronOyu* this, GlobalContext* globalCtx) { + s16 scale; + Vec3f pos1; + Vec3f pos2; + CollisionPoly* poly; + s32 pad; + + if ((globalCtx->state.frames % 4) == 0) { + Vec3f vel1; + Vec3f vel2; + + pos1.x = this->dyna.actor.world.pos.x; + pos1.y = this->dyna.actor.world.pos.y + 100.0f; + pos1.z = this->dyna.actor.world.pos.z; + vel1.x = 0.0f; + vel1.y = 2.5f; + vel1.z = 0.0f; + scale = -200 - (s32)(Rand_ZeroOne() * 50.0f); + + if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos1) < this->waterBoxPos.y) { + pos1.y = this->waterBoxPos.y + 10.0f; + EffectSsIceSmoke_Spawn(globalCtx, &pos1, &vel1, &D_801D15B0, scale); + } + pos2.x = (Rand_ZeroOne() * this->waterBoxXLength) + this->waterBoxPos.x; + pos2.y = this->waterBoxPos.y + 100.0f; + pos2.z = (Rand_ZeroOne() * this->waterBoxZLength) + this->waterBoxPos.z; + vel2.x = 0.0f; + vel2.y = 0.5f; + vel2.z = 0.0f; + scale = -200 - (s32)(Rand_ZeroOne() * 50.0f); + + if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos2) < this->waterBoxPos.y) { + pos2.y = this->waterBoxPos.y + 10.0f; + EffectSsIceSmoke_Spawn(globalCtx, &pos2, &vel2, &D_801D15B0, scale); + } + } +} + +void BgGoronOyu_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgGoronOyu* this = THIS; + CollisionHeader* colHeader = NULL; + + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06000988, &colHeader); + + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + + BgGoronOyu_UpdateWaterBoxInfo(this, globalCtx); + + if (thisx->params != 0) { + thisx->world.pos.y = thisx->home.pos.y; + func_80B40080(this); + } else { + thisx->world.pos.y = thisx->home.pos.y - 20.0f; + func_80B4009C(this); + } +} + +void BgGoronOyu_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgGoronOyu* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void BgGoronOyu_Update(Actor* thisx, GlobalContext* globalCtx) { + BgGoronOyu* this = THIS; + + this->actionFunc(this, globalCtx); + BgGoronOyu_SpawnParticles(this, globalCtx); +} + +void BgGoronOyu_Draw(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06000968)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &D_06000158); + gSPDisplayList(POLY_XLU_DISP++, &D_06000080); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h index e60a42af28..dba8bb044a 100644 --- a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h +++ b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h @@ -8,12 +8,15 @@ struct BgGoronOyu; typedef void (*BgGoronOyuActionFunc)(struct BgGoronOyu*, GlobalContext*); typedef struct BgGoronOyu { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; - /* 0x015C */ BgGoronOyuActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x20]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ BgGoronOyuActionFunc actionFunc; + /* 0x160 */ UNK_TYPE unk_160; + /* 0x164 */ f32 unk_164; + /* 0x168 */ Vec3f waterBoxPos; + /* 0x174 */ f32 waterBoxXLength; + /* 0x178 */ f32 waterBoxZLength; + /* 0x17C */ s16 initialActorCutscene; + /* 0x17E */ u16 unk_17E; } BgGoronOyu; // size = 0x180 -extern const ActorInit Bg_Goron_Oyu_InitVars; - #endif // Z_BG_GORON_OYU_H From 70990bf43f073c4c8f57c57b6539b86c922edb4e Mon Sep 17 00:00:00 2001 From: Nick Sturgeon Date: Sun, 19 Dec 2021 14:34:28 -0500 Subject: [PATCH 15/27] ovl_En_Test5 (Spring Water Modifier) OK with attempted documentation (#483) * Implement asm functions in C * Clean up code with documentation * Apply styling suggestions * Apply feedback --- spec | 3 +- src/overlays/actors/ovl_En_Test5/z_en_test5.c | 87 ++++++++++++++++--- src/overlays/actors/ovl_En_Test5/z_en_test5.h | 10 ++- tools/disasm/functions.txt | 2 +- 4 files changed, 85 insertions(+), 17 deletions(-) diff --git a/spec b/spec index 7e3dbfcdbe..0afddf622a 100644 --- a/spec +++ b/spec @@ -3233,8 +3233,7 @@ beginseg name "ovl_En_Test5" compress include "build/src/overlays/actors/ovl_En_Test5/z_en_test5.o" - include "build/data/ovl_En_Test5/ovl_En_Test5.data.o" - include "build/data/ovl_En_Test5/ovl_En_Test5.reloc.o" + include "build/src/overlays/actors/ovl_En_Test5/ovl_En_Test5_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Test5/z_en_test5.c b/src/overlays/actors/ovl_En_Test5/z_en_test5.c index 69d550c8af..4da30599cb 100644 --- a/src/overlays/actors/ovl_En_Test5/z_en_test5.c +++ b/src/overlays/actors/ovl_En_Test5/z_en_test5.c @@ -1,7 +1,7 @@ /* * File: z_en_test5.c * Overlay: ovl_En_Test5 - * Description: Spring Water + * Description: Spring Water Modifier */ #include "z_en_test5.h" @@ -13,12 +13,9 @@ void EnTest5_Init(Actor* thisx, GlobalContext* globalCtx); void EnTest5_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTest5_Update(Actor* thisx, GlobalContext* globalCtx); - -void func_80A90478(EnTest5* this, GlobalContext* globalCtx); - +void EnTest5_HandleBottleAction(EnTest5* this, GlobalContext* globalCtx); void EnTest5_SetupAction(EnTest5* this, EnTest5ActionFunc actionFunc); -#if 0 const ActorInit En_Test5_InitVars = { ACTOR_EN_TEST5, ACTORCAT_ITEMACTION, @@ -31,14 +28,82 @@ const ActorInit En_Test5_InitVars = { (ActorFunc)NULL, }; -#endif +void EnTest5_SetupAction(EnTest5* this, EnTest5ActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_SetupAction.s") +void EnTest5_Init(Actor* thisx, GlobalContext* globalCtx2) { + EnTest5* this = THIS; + GlobalContext* globalCtx = globalCtx2; + WaterBox* water; + f32 ySurface; // Unused -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_Init.s") + // If not spawned above a water source, immediately despawn + if (!WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &ySurface, &water)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_Destroy.s") + Math_Vec3s_ToVec3f(&this->minPos, &water->minPos); + this->xLength = (f32)water->xLength; + this->zLength = (f32)water->zLength; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/func_80A90478.s") + EnTest5_SetupAction(this, EnTest5_HandleBottleAction); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_Update.s") +void EnTest5_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnTest5_HandleBottleAction(EnTest5* this, GlobalContext* globalCtx) { + Player* player; + Vec3f playerPosRelativeToWater; + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + return; + } + + player = GET_PLAYER(globalCtx); + + if (player->unk_388 == NULL || player->unk_384 != GI_MAX) { + Math_Vec3f_DistXYZAndStoreDiff(&this->minPos, &player->actor.world.pos, &playerPosRelativeToWater); + + // Make sure that the player is within the bounds of the water and deep enough to grab some + if (playerPosRelativeToWater.x >= 0.0f && playerPosRelativeToWater.x <= this->xLength && + playerPosRelativeToWater.z >= 0.0f && playerPosRelativeToWater.z <= this->zLength && + fabsf(playerPosRelativeToWater.y) < 100.0f && player->actor.depthInWater > 12.0f) { + func_800B8A1C(&this->actor, globalCtx, GI_MAX, this->actor.xzDistToPlayer, + fabsf(this->actor.playerHeightRel)); + } + } +} + +void EnTest5_Update(Actor* thisx, GlobalContext* globalCtx2) { + EnTest5* this = THIS; + GlobalContext* globalCtx = globalCtx2; + Vec3f steamPos; + CollisionPoly* poly; // Unused + s32 pad; // Unused + + this->actionFunc(this, globalCtx); + + // If it's the hot spring variant, generate steam clouds + if (ENTEST5_IS_HOT_SPRING(&this->actor) && (globalCtx->state.frames % 4) == 0) { + steamPos.x = (Rand_ZeroOne() * this->xLength) + this->minPos.x; + steamPos.y = this->minPos.y + 100.0f; + steamPos.z = (Rand_ZeroOne() * this->zLength) + this->minPos.z; + + if ((BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &steamPos) + 10.0f) < this->minPos.y) { + Vec3f steamVel; + + steamPos.y = this->minPos.y + 10.0f; + steamVel.y = 0.5f; + steamVel.x = 0.0f; + steamVel.z = 0.0f; + + EffectSsIceSmoke_Spawn(globalCtx, &steamPos, &steamVel, &D_801D15B0, + (s16)((-200) - (s32)(Rand_ZeroOne() * 50.0f))); + } + } +} diff --git a/src/overlays/actors/ovl_En_Test5/z_en_test5.h b/src/overlays/actors/ovl_En_Test5/z_en_test5.h index 79ea87356b..539f5b3c26 100644 --- a/src/overlays/actors/ovl_En_Test5/z_en_test5.h +++ b/src/overlays/actors/ovl_En_Test5/z_en_test5.h @@ -3,14 +3,18 @@ #include "global.h" -struct EnTest5; +#define ENTEST5_IS_HOT_SPRING(thisx) ((thisx)->params != 0) + +struct EnTest5; // SpringWaterModifier typedef void (*EnTest5ActionFunc)(struct EnTest5*, GlobalContext*); typedef struct EnTest5 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x14]; - /* 0x0158 */ EnTest5ActionFunc actionFunc; + /* 0x0144 */ Vec3f minPos; + /* 0x0150 */ f32 xLength; + /* 0x0154 */ f32 zLength; + /* 0x0158 */ EnTest5ActionFunc actionFunc; } EnTest5; // size = 0x15C extern const ActorInit En_Test5_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index f4745004a9..de56d79015 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -11336,7 +11336,7 @@ 0x80A903B0:("EnTest5_SetupAction",), 0x80A903BC:("EnTest5_Init",), 0x80A90468:("EnTest5_Destroy",), - 0x80A90478:("func_80A90478",), + 0x80A90478:("EnTest5_HandleBottleAction",), 0x80A905A4:("EnTest5_Update",), 0x80A90730:("func_80A90730",), 0x80A90C08:("func_80A90C08",), From 038eb997d0de6e51871f6fc5ba3422c6eefcee3d Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Sun, 19 Dec 2021 11:40:39 -0800 Subject: [PATCH 16/27] En_Tanron3 (Gyorg's fishes) OK and somewhat documented (#376) * Import data to C * EnTanron3_Init OK * EnTanron3_Destroy OK * func_80BB897C OK * func_80BB91D4 OK * func_80BB9288 OK * EnTanron3_Draw OK * func_80BB95FC OK * EnTanron3_Update OK * func_80BB9308 OK * func_80BB87D4 OK * func_80BB85A0 OK * func_80BB8A48 OK * Update spec with compiled reloc * Name most of the functions * Name a few more things * Merge animation system changes * Name remaining unnamed variables * Finish documentation * Use modulo for fogTimer * Move enum/structs to .h * boss03Parent -> sGyorg * D_80BB9720 -> sZeroVec * Move initialization of effectPtr up * Use 2 * M_PI * Use MTXMODE_NEW * 65536.0f -> 0x10000 * timer += 1 -> timer++ * Timer cleanup * Remove unneccesary parentheses * When performing bitwise operations on timer, use hex * Lowercase "fish" in the comment at the top * Respond to jpburnett's feedback * Respond to Elliptic and Kenix's reviews * Undo renaming the Gyorg var, but keep the comment * Add a little bit more documentation * Variable renames * Remove a comment that no longer applies * Document some swimming behavior * PICK_DIRECTION -> PICK_NEW_DEVIATION * Minor comment tweak * Respond to Elliptic's review * Remove timer inconsistency --- spec | 3 +- src/overlays/actors/ovl_Boss_03/z_boss_03.h | 8 +- .../actors/ovl_En_Tanron3/z_en_tanron3.c | 430 +++++++++++++++++- .../actors/ovl_En_Tanron3/z_en_tanron3.h | 49 +- tools/disasm/functions.txt | 16 +- 5 files changed, 470 insertions(+), 36 deletions(-) diff --git a/spec b/spec index 0afddf622a..2302f03771 100644 --- a/spec +++ b/spec @@ -4630,8 +4630,7 @@ beginseg name "ovl_En_Tanron3" compress include "build/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.o" - include "build/data/ovl_En_Tanron3/ovl_En_Tanron3.data.o" - include "build/data/ovl_En_Tanron3/ovl_En_Tanron3.reloc.o" + include "build/src/overlays/actors/ovl_En_Tanron3/ovl_En_Tanron3_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Boss_03/z_boss_03.h b/src/overlays/actors/ovl_Boss_03/z_boss_03.h index e93baca0bf..ca8a92328a 100644 --- a/src/overlays/actors/ovl_Boss_03/z_boss_03.h +++ b/src/overlays/actors/ovl_Boss_03/z_boss_03.h @@ -9,9 +9,13 @@ typedef void (*Boss03ActionFunc)(struct Boss03*, GlobalContext*); typedef struct Boss03 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1E4]; + /* 0x0144 */ UNK_TYPE1 unk_144[0x10E]; + /* 0x0252 */ s8 unk_252; // number of Tanron3 fish that are currently alive, maybe "numSmallFishAlive"? + /* 0x0253 */ UNK_TYPE1 unk_253[0xD1]; + /* 0x0324 */ s16 unk_324; + /* 0x0326 */ UNK_TYPE1 unk_326[0x2]; /* 0x0328 */ Boss03ActionFunc actionFunc; - /* 0x032C */ char unk_32C[0x250]; + /* 0x032C */ UNK_TYPE1 unk_32C[0x250]; } Boss03; // size = 0x57C extern const ActorInit Boss_03_InitVars; diff --git a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c index 2de774191f..313a0a1fdb 100644 --- a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c +++ b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c @@ -1,10 +1,11 @@ /* * File: z_en_tanron3.c * Overlay: ovl_En_Tanron3 - * Description: Small Fish summoned by Gyorg + * Description: Small fish summoned by Gyorg */ #include "z_en_tanron3.h" +#include "overlays/actors/ovl_Boss_03/z_boss_03.h" #define FLAGS 0x00000035 @@ -15,7 +16,14 @@ void EnTanron3_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTanron3_Update(Actor* thisx, GlobalContext* globalCtx); void EnTanron3_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnTanron3_SetupLive(EnTanron3* this, GlobalContext* globalCtx); +void EnTanron3_Live(EnTanron3* this, GlobalContext* globalCtx); +void EnTanron3_Die(EnTanron3* this, GlobalContext* globalCtx); + +static Vec3f sZeroVec[] = { 0.0f, 0.0f, 0.0f }; + +static Boss03* sGyorg = NULL; + const ActorInit En_Tanron3_InitVars = { ACTOR_EN_TANRON3, ACTORCAT_BOSS, @@ -28,39 +36,419 @@ const ActorInit En_Tanron3_InitVars = { (ActorFunc)EnTanron3_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BB9750 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x02 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 7, 10, -5, { 0, 0, 0 } }, }; -#endif +// This actor has two colliders (one for AC and one for AT), but uses the same +// ColliderCylinderInit for both of them, leaving this one totally unused. +static ColliderCylinderInit sUnusedCylinderInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { 20, 20, -10, { 0, 0, 0 } }, +}; -extern ColliderCylinderInit D_80BB9750; +extern FlexSkeletonHeader D_0600DA20; +extern AnimationHeader D_0600DAAC; -extern UNK_TYPE D_0600DAAC; +void EnTanron3_CreateEffect(GlobalContext* globalCtx, Vec3f* effectPos) { + UnkTanron3Effect* effectPtr = (UnkTanron3Effect*)globalCtx->specialEffects; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB85A0.s") + for (i = 0; i < 150; i++, effectPtr++) { + if ((effectPtr->type == 0) || (effectPtr->type == 1)) { + effectPtr->type = 2; + effectPtr->pos = *effectPos; + effectPtr->velocity = *sZeroVec; + effectPtr->accel = *sZeroVec; + effectPtr->accel.y = -2.0f; + effectPtr->unk_34.x = 0.1f; + effectPtr->unk_34.y = 0.0f; + effectPtr->unk_34.z = Rand_ZeroFloat(2 * M_PI); + effectPtr->unk_02 = Rand_ZeroFloat(100.0f); + effectPtr->velocity.x = randPlusMinusPoint5Scaled(25.0f); + effectPtr->velocity.z = randPlusMinusPoint5Scaled(25.0f); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Init.s") +void EnTanron3_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTanron3* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Destroy.s") + this->actor.gravity = -1.0f; + Collider_InitAndSetCylinder(globalCtx, &this->atCollider, &this->actor, &sCylinderInit); + Collider_InitAndSetCylinder(globalCtx, &this->acCollider, &this->actor, &sCylinderInit); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600DA20, &D_0600DAAC, this->jointTable, this->morphTable, 10); + Actor_SetScale(&this->actor, 0.02f); + EnTanron3_SetupLive(this, globalCtx); + this->actor.flags &= ~1; + this->currentRotationAngle = Rand_ZeroFloat(500000.0f); + this->waterSurfaceYPos = 430.0f; + sGyorg = (Boss03*)this->actor.parent; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB87D4.s") +void EnTanron3_Destroy(Actor* thisx, GlobalContext* globalCtx) { + sGyorg->unk_252--; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB897C.s") +void EnTanron3_SpawnBubbles(EnTanron3* this, GlobalContext* globalCtx) { + static Color_RGBA8 sPrimColor = { 100, 55, 55, 255 }; + static Color_RGBA8 sEnvColor = { 50, 10, 10, 255 }; + s32 i; + Vec3f velocity; + Vec3f acceleration; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB8A48.s") + for (i = 0; i < 20; i++) { + Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(2 * M_PI)); + Matrix_GetStateTranslationAndScaledZ(Rand_ZeroFloat(3.0f) + 2.0f, &velocity); + acceleration.x = velocity.x * -0.05f; + acceleration.y = velocity.y * -0.05f; + acceleration.z = velocity.z * -0.05f; + EffectSsDtBubble_SpawnCustomColor(globalCtx, &this->actor.world.pos, &velocity, &acceleration, &sPrimColor, + &sEnvColor, Rand_ZeroFloat(30.0f) + 70.0f, Rand_ZeroFloat(5.0f) + 15.0f, 0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB91D4.s") +void EnTanron3_SetupLive(EnTanron3* this, GlobalContext* globalCtx) { + this->actionFunc = EnTanron3_Live; + Animation_MorphToLoop(&this->skelAnime, &D_0600DAAC, -10.0f); + this->rotationStep = 0; + this->rotationScale = 5; + this->workTimer[TANRON3_WORK_TIMER_PICK_NEW_DEVIATION] = 50; + this->actor.speedXZ = 5.0f; + this->speedMaxStep = 0.5f; + this->deviation.x = randPlusMinusPoint5Scaled(500.0f); + this->deviation.y = randPlusMinusPoint5Scaled(100.0f); + this->deviation.z = randPlusMinusPoint5Scaled(500.0f); + Math_Vec3f_Copy(&this->targetPos, &this->actor.world.pos); + this->timer = Rand_ZeroFloat(100.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB9288.s") +/** + * This controls the vast majority of the fish's behavior while it's alive, including: + * - deciding whether to be hostile or not + * - determing whether the fish is beached or not + * - swimming towards the player to attack them + * - swimming around idly if the player is out of range + * - flopping around on land if it beaches itself + */ +void EnTanron3_Live(EnTanron3* this, GlobalContext* globalCtx) { + s32 atanTemp; + f32 xDistance; + f32 yDistance; + f32 zDistance; + f32 xzDistance; + f32 extraScaleY = 0.0f; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB9308.s") + this->skelAnime.curFrame = 4.0f; + if ((player->actor.bgCheckFlags & 1) && player->actor.shape.feetPos[0].y >= 438.0f) { + // Player is standing on the central platform, so stop chasing them + this->isNonHostile = true; + } else if (this->isNonHostile && this->workTimer[TANRON3_WORK_TIMER_WAIT] == 0 && !(this->timer & 0x1F)) { + xDistance = this->targetPos.x - player->actor.world.pos.x; + zDistance = this->targetPos.z - player->actor.world.pos.z; + if (sqrtf(SQ(xDistance) + SQ(zDistance)) < 500.0f) { + // Player is in the water and close enough, so start chasing them + this->isNonHostile = false; + this->workTimer[TANRON3_WORK_TIMER_ATTACK] = 150; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Update.s") + if (this->actor.world.pos.y < this->waterSurfaceYPos) { + // The fish is below the water's surface, so it's no longer beached if it was before + this->isBeached = false; + switch (this->isNonHostile) { + case false: + this->targetSpeedXZ = 5.0f; + this->targetRotationStep = 0x1000; + this->nextRotationAngle = 0x3A98; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB95FC.s") + Math_Vec3f_Copy(&this->targetPos, &player->actor.world.pos); + if (!(this->timer & 0xF)) { + if (Rand_ZeroOne() < 0.5f && this->actor.xzDistToPlayer <= 200.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIRANHA_ATTACK); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Draw.s") + // If the player gets eaten by Gyorg, or if the attack timer ran out, + // stop chasing the player for a little bit. + if (this->workTimer[TANRON3_WORK_TIMER_ATTACK] == 0 || (player->stateFlags2 & 0x80)) { + this->workTimer[TANRON3_WORK_TIMER_WAIT] = 150; + this->isNonHostile = true; + } + break; + case true: + if (sGyorg->unk_324 != 0 && !(this->timer & 0x7)) { + this->nextRotationAngle = 0x4E20; + this->actor.speedXZ = 6.0f; + } else { + this->nextRotationAngle = 0x1F40; + } + this->targetRotationStep = 0x200; + this->targetSpeedXZ = 2.0f; + + // If the fish is idly swimming around, this code will make it spin in a circle. + // Its target is constantly updated, so it constantly rotates to face it, and its + // momentum keeps it spinning. This code can also be reached when the fish "give up" + // on attacking the player; in that case, this code will make it turn in the + // opposite direction and swim away. In both cases, the fish's target y-position + // will be slightly above the halfway point of the water. + atanTemp = Math_FAtan2F(this->targetPos.z, this->targetPos.x); + Matrix_RotateY(atanTemp, MTXMODE_NEW); + Matrix_GetStateTranslationAndScaledZ(700.0f, &this->targetPos); + this->targetPos.y = 250.0f; + + extraScaleY = 150.0f; + break; + } + + if (this->workTimer[TANRON3_WORK_TIMER_OUT_OF_WATER] == 0) { + if (this->workTimer[TANRON3_WORK_TIMER_PICK_NEW_DEVIATION] == 0 && this->actor.speedXZ > 1.0f) { + this->workTimer[TANRON3_WORK_TIMER_PICK_NEW_DEVIATION] = Rand_ZeroFloat(20.0f); + this->deviation.x = randPlusMinusPoint5Scaled(100.0f); + this->deviation.y = randPlusMinusPoint5Scaled(50.0f + extraScaleY); + this->deviation.z = randPlusMinusPoint5Scaled(100.0f); + } + this->targetPosWithDeviation.y = this->targetPos.y + this->deviation.y + 50.0f; + } + + this->targetPosWithDeviation.x = this->targetPos.x + this->deviation.x; + this->targetPosWithDeviation.z = this->targetPos.z + this->deviation.z; + xDistance = this->targetPosWithDeviation.x - this->actor.world.pos.x; + yDistance = this->targetPosWithDeviation.y - this->actor.world.pos.y; + zDistance = this->targetPosWithDeviation.z - this->actor.world.pos.z; + + // Rotate the fish to look towards its target + xzDistance = sqrtf(SQ(xDistance) + SQ(zDistance)); + atanTemp = Math_FAtan2F(xzDistance, -yDistance); + Math_ApproachS(&this->actor.world.rot.x, atanTemp, this->rotationScale, this->rotationStep); + atanTemp = Math_FAtan2F(zDistance, xDistance); + Math_SmoothStepToS(&this->actor.world.rot.y, atanTemp, this->rotationScale, this->rotationStep, 0); + Math_ApproachS(&this->rotationStep, this->targetRotationStep, 1, 0x100); + + Math_ApproachF(&this->actor.speedXZ, this->targetSpeedXZ, 1.0f, this->speedMaxStep); + Actor_SetVelocityAndMoveXYRotationReverse(&this->actor); + } else { + switch (this->isBeached) { + case false: + // Fish is above water but hasn't touched land before + this->actor.gravity = -1.0f; + this->targetPosWithDeviation.y = this->waterSurfaceYPos - 50.0f; + this->workTimer[TANRON3_WORK_TIMER_OUT_OF_WATER] = 25; + Math_ApproachS(&this->actor.world.rot.x, 0x3000, 5, 0xBD0); + if (this->actor.bgCheckFlags & 8) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = -1.0f; + } + } + if (this->actor.bgCheckFlags & 1) { + // Fish has touched land + this->isBeached = true; + } + break; + case true: + this->nextRotationAngle = 0x3A98; + this->actor.gravity = -1.5f; + if (this->actor.bgCheckFlags & 1) { + // Fish is still touching land, so it's still beached. Randomly flop around + this->actor.velocity.y = Rand_ZeroFloat(5.0f) + 5.0f; + this->actor.speedXZ = Rand_ZeroFloat(2.0f) + 2.0f; + if (Rand_ZeroOne() < 0.5f) { + this->targetShapeRotation.x = + (s16)randPlusMinusPoint5Scaled(500.0f) + this->targetShapeRotation.x + 0x8000; + } + if (Rand_ZeroOne() < 0.5f) { + this->targetShapeRotation.z = + (s16)randPlusMinusPoint5Scaled(500.0f) + this->targetShapeRotation.z + 0x8000; + } + if (Rand_ZeroOne() < 0.5f) { + this->targetShapeRotation.y = (s16)Rand_ZeroFloat(0x10000); + } + this->actor.world.rot.y = Math_FAtan2F(this->actor.world.pos.z, this->actor.world.pos.x) + + (s16)randPlusMinusPoint5Scaled(0xCE20); + } + + Math_ApproachS(&this->actor.shape.rot.y, this->targetShapeRotation.y, 3, 0x500); + Math_ApproachS(&this->actor.shape.rot.x, this->targetShapeRotation.x, 3, 0xC00); + Math_ApproachS(&this->actor.shape.rot.z, this->targetShapeRotation.z, 3, 0xC00); + if ((Rand_ZeroOne() < 0.5f) & !(this->timer & 0x3)) { + Vec3f effectPos; + + effectPos.x = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.x; + effectPos.y = this->actor.world.pos.y; + effectPos.z = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.z; + EnTanron3_CreateEffect(globalCtx, &effectPos); + } + break; + } + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + + this->currentRotationAngle += this->nextRotationAngle; + this->trunkRotation = Math_SinS(this->currentRotationAngle) * 5000.0f; + this->bodyRotation = Math_SinS(this->currentRotationAngle + 0x6978) * 5000.0f; + this->tailRotation = Math_SinS(this->currentRotationAngle) * 5000.0f; + if (!this->isBeached) { + this->actor.shape.rot = this->actor.world.rot; + } +} + +void EnTanron3_SetupDie(EnTanron3* this, GlobalContext* globalCtx) { + f32 xDistance; + f32 yDistance; + f32 zDistance; + Player* player = GET_PLAYER(globalCtx); + + this->actionFunc = EnTanron3_Die; + xDistance = this->actor.world.pos.x - player->actor.world.pos.x; + yDistance = this->actor.world.pos.y - player->actor.world.pos.y + 30.0f; + zDistance = this->actor.world.pos.z - player->actor.world.pos.z; + this->actor.world.rot.x = Math_FAtan2F(sqrtf(SQ(xDistance) + SQ(zDistance)), -yDistance); + this->actor.world.rot.y = Math_FAtan2F(zDistance, xDistance); + this->workTimer[TANRON3_WORK_TIMER_DIE] = 6; + this->actor.speedXZ = 10.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KONB_MINI_DEAD); +} + +void EnTanron3_Die(EnTanron3* this, GlobalContext* globalCtx) { + Actor_SetVelocityAndMoveXYRotationReverse(&this->actor); + if (this->workTimer[TANRON3_WORK_TIMER_DIE] == 0) { + EnTanron3_SpawnBubbles(this, globalCtx); + Actor_MarkForDeath(&this->actor); + if (Rand_ZeroOne() < 0.3f) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0x60); + } + } +} + +void EnTanron3_CheckCollisions(EnTanron3* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->actor.world.pos.y > 350.0f) { + if (this->atCollider.base.atFlags & AT_HIT) { + this->atCollider.base.atFlags &= ~AT_HIT; + func_800B8D50(globalCtx, NULL, 3.0f, Math_FAtan2F(-player->actor.world.pos.z, -player->actor.world.pos.x), + 5.0f, 0); + } + } + if (this->acCollider.base.acFlags & AC_HIT) { + this->acCollider.base.acFlags &= ~AC_HIT; + if (this->deathTimer == 0) { + this->deathTimer = 15; + this->fogTimer = 15; + EnTanron3_SetupDie(this, globalCtx); + sGyorg->unk_324 = 20; + } + } +} + +void EnTanron3_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTanron3* this = THIS; + s16 i; + Vec3f splashPos; + + if (KREG(63) == 0) { + this->timer++; + + for (i = 0; i < TANRON3_WORK_TIMER_MAX; i++) { + if (this->workTimer[i] != 0) { + this->workTimer[i]--; + } + } + if (this->deathTimer != 0) { + this->deathTimer--; + } + if (this->fogTimer != 0) { + this->fogTimer--; + } + + this->actionFunc(this, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 20.0f, 5); + + // The fish has either just entered or just exited the water, so create a splash effect + if (((this->actor.prevPos.y < this->waterSurfaceYPos) && (this->waterSurfaceYPos <= this->actor.world.pos.y)) || + ((this->actor.prevPos.y > this->waterSurfaceYPos) && (this->waterSurfaceYPos >= this->actor.world.pos.y))) { + splashPos.x = this->actor.world.pos.x; + splashPos.y = this->waterSurfaceYPos + 10.0f; + splashPos.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &splashPos, NULL, NULL, 1, 500); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_OUT_OF_WATER); + } + } + + EnTanron3_CheckCollisions(this, globalCtx); + Collider_UpdateCylinder(&this->actor, &this->atCollider); + Collider_UpdateCylinder(&this->actor, &this->acCollider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->atCollider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->acCollider.base); + + if ((s8)sGyorg->actor.colChkInfo.health <= 0 && this->actionFunc != EnTanron3_Die) { + EnTanron3_SetupDie(this, globalCtx); + this->workTimer[TANRON3_WORK_TIMER_DIE] = 0; + } +} + +s32 EnTanron3_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnTanron3* this = THIS; + + if (limbIndex == 1) { + rot->y += this->bodyRotation; + } + if (limbIndex == 3) { + rot->y += this->tailRotation; + } + if (limbIndex == 4) { + rot->y += this->trunkRotation; + } + return false; +} + +void EnTanron3_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTanron3* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + if ((this->fogTimer % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTanron3_OverrideLimbDraw, NULL, &this->actor); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h index 885d65af9d..9a2cb25da7 100644 --- a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h +++ b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h @@ -7,10 +7,53 @@ struct EnTanron3; typedef void (*EnTanron3ActionFunc)(struct EnTanron3*, GlobalContext*); +#define TANRON3_WORK_TIMER_PICK_NEW_DEVIATION 0 +#define TANRON3_WORK_TIMER_DIE 0 +#define TANRON3_WORK_TIMER_OUT_OF_WATER 1 +#define TANRON3_WORK_TIMER_ATTACK 2 +#define TANRON3_WORK_TIMER_WAIT 2 +#define TANRON3_WORK_TIMER_MAX 3 + +typedef struct { + /* 0x00 */ u8 type; + /* 0x02 */ s16 unk_02; + /* 0x04 */ Vec3f pos; + /* 0x10 */ Vec3f velocity; + /* 0x1C */ Vec3f accel; + /* 0x28 */ char unk_28[0xC]; + /* 0x34 */ Vec3f unk_34; + /* 0x40 */ char unk_40[0x4]; +} UnkTanron3Effect; + typedef struct EnTanron3 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1B4]; - /* 0x02F8 */ EnTanron3ActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[10]; + /* 0x1C4 */ Vec3s morphTable[10]; + /* 0x200 */ s16 timer; + /* 0x202 */ u8 isNonHostile; // If true, the fish will not move towards the player to attack them + /* 0x203 */ u8 isBeached; // If true, the fish is on the central platform flopping around + /* 0x204 */ s16 workTimer[TANRON3_WORK_TIMER_MAX]; + /* 0x20A */ s16 deathTimer; + /* 0x20C */ s16 fogTimer; + /* 0x210 */ Vec3f targetPosWithDeviation; // The destination that the fish actually ends up moving towards + /* 0x21C */ Vec3f targetPos; // The exact destination where the fish wants to be located + /* 0x228 */ Vec3f deviation; // A random amount of "noise" added to targetPos + /* 0x234 */ s16 rotationStep; + /* 0x236 */ s16 targetRotationStep; + /* 0x238 */ s16 rotationScale; + /* 0x23C */ f32 targetSpeedXZ; + /* 0x240 */ f32 speedMaxStep; + /* 0x244 */ f32 waterSurfaceYPos; + /* 0x248 */ Vec3s targetShapeRotation; + /* 0x250 */ s32 currentRotationAngle; + /* 0x254 */ s32 nextRotationAngle; + /* 0x258 */ s16 tailRotation; + /* 0x25A */ s16 trunkRotation; + /* 0x25C */ s16 bodyRotation; + /* 0x260 */ ColliderCylinder atCollider; + /* 0x2AC */ ColliderCylinder acCollider; + /* 0x2F8 */ EnTanron3ActionFunc actionFunc; } EnTanron3; // size = 0x2FC extern const ActorInit En_Tanron3_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index de56d79015..79a254d428 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -15360,17 +15360,17 @@ 0x80BB7800:("EnTanron2_Update",), 0x80BB7B90:("func_80BB7B90",), 0x80BB7C14:("EnTanron2_Draw",), - 0x80BB85A0:("func_80BB85A0",), + 0x80BB85A0:("EnTanron3_CreateEffect",), 0x80BB86BC:("EnTanron3_Init",), 0x80BB87B0:("EnTanron3_Destroy",), - 0x80BB87D4:("func_80BB87D4",), - 0x80BB897C:("func_80BB897C",), - 0x80BB8A48:("func_80BB8A48",), - 0x80BB91D4:("func_80BB91D4",), - 0x80BB9288:("func_80BB9288",), - 0x80BB9308:("func_80BB9308",), + 0x80BB87D4:("EnTanron3_SpawnBubbles",), + 0x80BB897C:("EnTanron3_SetupLive",), + 0x80BB8A48:("EnTanron3_Live",), + 0x80BB91D4:("EnTanron3_SetupDie",), + 0x80BB9288:("EnTanron3_Die",), + 0x80BB9308:("EnTanron3_CheckCollisions",), 0x80BB93EC:("EnTanron3_Update",), - 0x80BB95FC:("func_80BB95FC",), + 0x80BB95FC:("EnTanron3_OverrideLimbDraw",), 0x80BB9670:("EnTanron3_Draw",), 0x80BB98E0:("ObjChan_Init",), 0x80BB99F0:("ObjChan_Destroy",), From e579bf558708c8b3768be5954b01f59bd4fed1aa Mon Sep 17 00:00:00 2001 From: LtPeriwinkle <62761190+LtPeriwinkle@users.noreply.github.com> Date: Sun, 19 Dec 2021 12:47:47 -0700 Subject: [PATCH 17/27] Effect_Ss_Kakera (#469) * Effect_Ss_Kakera OK * fix variable naming and formatting * GAMEPLAY_KEEP, assign Vec together, angles in hex * rename bgcheck functions * address style changes * move/format data; use shift instead of multiply --- spec | 3 +- .../ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c | 342 ++++++++++++++++-- .../ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h | 6 +- 3 files changed, 327 insertions(+), 24 deletions(-) diff --git a/spec b/spec index 2302f03771..b409e53075 100644 --- a/spec +++ b/spec @@ -2011,8 +2011,7 @@ beginseg name "ovl_Effect_Ss_Kakera" compress include "build/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.o" - include "build/data/ovl_Effect_Ss_Kakera/ovl_Effect_Ss_Kakera.data.o" - include "build/data/ovl_Effect_Ss_Kakera/ovl_Effect_Ss_Kakera.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Kakera/ovl_Effect_Ss_Kakera_reloc.o" endseg beginseg diff --git a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c index e4b3e791d3..fe070b28de 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c +++ b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c @@ -8,50 +8,350 @@ #define PARAMS ((EffectSsKakeraInitParams*)initParamsx) -s32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsKakera_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsKakera_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 +void func_8097E130(EffectSs* this, GlobalContext* globalCtx); + const EffectSsInit Effect_Ss_Kakera_InitVars = { EFFECT_SS_KAKERA, EffectSsKakera_Init, }; +KakeraColorStruct D_8097EAD8[] = { + { 0, { 255, 255, 255 } }, + { 0, { 235, 170, 130 } }, + { 1, { 210, 190, 170 } }, +}; +f32 D_8097EAE4[] = { 1.0f, 100.0f, 40.0f, 5.0f, 100.0f, 40.0f, 5.0f, 100.0f, 40.0f, 5.0f }; -#endif +u32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsKakeraInitParams* params = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Init.s") + this->pos = params->pos; + this->velocity = params->velocity; + this->life = params->life; + this->priority = 101; + if (params->dList != NULL) { + this->gfx = params->dList; + switch (params->objId) { + case GAMEPLAY_KEEP: + case GAMEPLAY_FIELD_KEEP: + case GAMEPLAY_DANGEON_KEEP: + this->regs[10] = KAKERA_OBJECT_DEFAULT; + break; + default: + this->regs[10] = params->objId; + func_8097E130(this, globalCtx); + break; + } + } else { + __assert("../z_eff_kakera.c", 193); + } + this->draw = EffectSsKakera_Draw; + this->update = EffectSsKakera_Update; + this->vec = params->unk_18; + this->regs[0] = params->unk_2C; + this->regs[1] = params->gravity; + this->regs[2] = Rand_ZeroOne() * 0x8000; + this->regs[3] = Rand_ZeroOne() * 0x8000; + this->regs[4] = params->unk_26; + this->regs[5] = params->unk_28; + this->regs[6] = params->unk_2A; + this->regs[7] = params->scale; + this->regs[8] = params->unk_30; + this->regs[9] = params->unk_32; + this->regs[12] = params->colorIdx; + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097DE30.s") +f32 func_8097DE30(f32 center, f32 range) { + return (2.0f * (Rand_ZeroOne() * range) - range) + center; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Draw.s") +void EffectSsKakera_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s16 pad; + f32 scale = this->regs[7] / 256.0f; + s32 colorIndex = this->regs[12]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E130.s") + OPEN_DISPS(gfxCtx); + if (this->regs[10] != KAKERA_OBJECT_DEFAULT) { + if ((((this->regs[4] >> 7) & 1) << 7) == 0x80) { + gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[this->regs[11]].segment); + } else { + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->regs[11]].segment); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E19C.s") + Matrix_InsertTranslation(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_RotateY(this->regs[3], MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->regs[2], MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E34C.s") + if ((((this->regs[4] >> 7) & 1) << 7) == 0x80) { + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + if (colorIndex >= 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, D_8097EAD8[colorIndex].lod, D_8097EAD8[colorIndex].color.r, + D_8097EAD8[colorIndex].color.g, D_8097EAD8[colorIndex].color.b, 255); + } + gSPDisplayList(POLY_XLU_DISP++, this->gfx); + } else { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + if (colorIndex >= 0) { + gDPSetPrimColor(POLY_OPA_DISP++, 0, D_8097EAD8[colorIndex].lod, D_8097EAD8[colorIndex].color.r, + D_8097EAD8[colorIndex].color.g, D_8097EAD8[colorIndex].color.b, 255); + } + gSPDisplayList(POLY_OPA_DISP++, this->gfx); + } + CLOSE_DISPS(gfxCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E368.s") +void func_8097E130(EffectSs* this, GlobalContext* globalCtx) { + this->regs[11] = Object_GetIndex(&globalCtx->objectCtx, this->regs[10]); + if ((this->regs[11] < 0) || (!Object_IsLoaded(&globalCtx->objectCtx, this->regs[11]))) { + this->life = 0; + this->draw = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E384.s") +void func_8097E19C(EffectSs* this) { + f32 range; + f32 temp_f12; + f32 temp_f16; + f32 temp_f2; + f32 temp_f18; + f32 temp_f0; + f32 temp_f20; + f32 temp_f2_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E3C0.s") + temp_f18 = this->regs[5] / 1024.0f; + temp_f20 = this->regs[6] / 1024.0f; + range = (this->regs[9] / 1024.0f) * 4.0f; + temp_f2 = this->velocity.x - func_8097DE30(0.0f, range); + temp_f16 = this->velocity.y - func_8097DE30(0.0f, range); + temp_f12 = this->velocity.z - func_8097DE30(0.0f, range); + temp_f0 = temp_f2 * temp_f18; + temp_f2_2 = SQ(temp_f2) * temp_f20; + if (temp_f2 > 0.0f) { + this->velocity.x -= (temp_f0 + temp_f2_2); + } else { + this->velocity.x -= (temp_f0 - temp_f2_2); + } + temp_f0 = temp_f16 * temp_f18; + temp_f2_2 = SQ(temp_f16) * temp_f20; + if (temp_f16 > 0.0f) { + this->velocity.y -= (temp_f0 + temp_f2_2); + } else { + this->velocity.y -= (temp_f0 - temp_f2_2); + } + if (temp_f12 > 0.0f) { + this->velocity.z -= (temp_f0 + temp_f2_2); + } else { + this->velocity.z -= (temp_f0 - temp_f2_2); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E400.s") +void func_8097E34C(EffectSs* this) { + this->accel.x = this->accel.y = this->accel.z = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E420.s") +f32 func_8097E368(f32 arg0, s32 arg1) { + return 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E4B0.s") +f32 func_8097E384(f32 arg0, s32 index) { + if (D_8097EAE4[index] < arg0) { + return D_8097EAE4[index] / arg0; + } else { + return 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E4F0.s") +f32 func_8097E3C0(f32 arg0, s32 index) { + f32 square = SQ(arg0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E584.s") + if (D_8097EAE4[index] < square) { + return D_8097EAE4[index] / square; + } else { + return 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E660.s") +f32 func_8097E400(f32 arg0, s32 index) { + return func_8097E3C0(arg0, index); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E698.s") +s32 func_8097E420(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB0C[] = { 0.05f, 1.0f }; + f32 phi_f0; + s32 index = this->regs[0] & 3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E7E0.s") + if (index != 0) { + if (distance > 1.0f) { + phi_f0 = 1.0f / distance; + } else { + phi_f0 = 1.0f; + } + this->accel.x += D_8097EB0C[index - 1] * diff->z * phi_f0; + this->accel.z -= D_8097EB0C[index - 1] * diff->x * phi_f0; + } + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Update.s") +s32 func_8097E4B0(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB14[] = { 4.0f, 0.1f, 0.3f, 0.9f, -0.1f, -0.3f, -0.9f }; + s32 index = (this->regs[0] >> 2) & 7; + + if (index != 0) { + this->accel.y += D_8097EB14[index]; + } + return 1; +} + +s32 func_8097E4F0(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB30[] = { 0.1f, 1.0f, 6.0f }; + f32 phi_f0; + s32 index = (this->regs[0] >> 5) & 3; + + if (index != 0) { + if (distance > 1.0f) { + phi_f0 = 1.0f / distance; + } else { + phi_f0 = 1.0f; + } + this->accel.x -= diff->x * D_8097EB30[index - 1] * phi_f0; + this->accel.z -= diff->z * D_8097EB30[index - 1] * phi_f0; + } + return 1; +} + +s32 func_8097E584(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 (*D_8097EB3C[])(f32, + s32) = { func_8097E368, func_8097E384, func_8097E384, func_8097E384, func_8097E3C0, + func_8097E3C0, func_8097E3C0, func_8097E400, func_8097E400, func_8097E400 }; + f32 center; + f32 rand; + s32 index; + + index = (this->regs[0] >> 7) & 0xF; + center = D_8097EB3C[index](distance, index); + rand = func_8097DE30(center, (this->regs[9] * center) / 1024.0f); + this->accel.x *= rand; + this->accel.y *= rand; + this->accel.z *= rand; + this->accel.x += rand * 0.01f; + this->accel.y += rand * 0.01f; + this->accel.z += rand * 0.01f; + return 1; +} + +s32 func_8097E660(EffectSs* this, Vec3f* diff, f32 distance) { + this->accel.y += this->regs[1] / 256.0f; + return 1; +} + +s32 func_8097E698(EffectSs* this) { + Vec3f diff; + f32 distance; + + func_8097E34C(this); + diff.x = this->pos.x - this->vec.x; + diff.y = this->pos.y - this->vec.y; + diff.z = this->pos.z - this->vec.z; + distance = sqrtf(SQXYZ(diff)); + if (distance > 1000.0f) { + return false; + } + if (this->regs[0] != 0) { + if (func_8097E420(this, &diff, distance) == 0) { + return false; + } + if (func_8097E4B0(this, &diff, distance) == 0) { + return false; + } + if (func_8097E4F0(this, &diff, distance) == 0) { + return false; + } + if (func_8097E584(this, &diff, distance) == 0) { + return false; + } + } + if (func_8097E660(this, &diff, distance) == 0) { + return false; + } else { + return true; + } +} + +void func_8097E7E0(EffectSs* this, GlobalContext* globalCtx) { + static f32 D_8097EB64[] = { 10.0f, 20.0f, 40.0f }; + Player* player = GET_PLAYER(globalCtx); + + if (this->regs[8] == 0) { + if ((((this->regs[4] >> 4) & 1) << 4) == (1 << 4)) { + if (this->pos.y <= (player->actor.floorHeight - ((this->regs[4] >> 2) & 3))) { + this->regs[9] = 0; + this->regs[0] = 0; + this->regs[4] &= ~0x60; + this->accel.x = this->accel.y = this->accel.z = 0.0f; + this->velocity.x = this->velocity.y = this->velocity.z = 0.0f; + this->regs[5] = this->regs[9]; + this->regs[1] = this->regs[9]; + } + } else { + if (this->pos.y <= ((player->actor.floorHeight - ((this->regs[4] >> 2) & 3)) - 600.0f)) { + this->life = 0; + } + } + } else { + switch (this->regs[4] & 3) { + case 0: + this->regs[8] = 0; + break; + case 1: + if ((this->velocity.y < 0.0f) && + (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &this->pos, D_8097EB64[(this->regs[4] >> 2) & 3]))) { + this->velocity.x *= func_8097DE30(0.9f, 0.2f); + this->velocity.y *= -0.8f; + this->velocity.z *= func_8097DE30(0.9f, 0.2f); + if (this->regs[8] > 0) { + this->regs[8]--; + } + } + break; + case 2: + if (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &this->pos, D_8097EB64[(this->regs[4] >> 2) & 3])) { + this->regs[8] = 0; + } + break; + } + } +} + +void EffectSsKakera_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + switch (((this->regs[4] >> 5) & 3) << 5) { + case 0x20: + this->regs[2] += 0x47B; + this->regs[3] += 0x139; + break; + case 0x40: + this->regs[2] += 0x1A7C; + this->regs[3] += 0x47B; + break; + case 0x60: + this->regs[2] += 0x3F27; + this->regs[3] += 0xCA1; + break; + } + func_8097E19C(this); + if (!func_8097E698(this)) { + this->life = 0; + } + func_8097E7E0(this, globalCtx); + if (this->regs[10] != KAKERA_OBJECT_DEFAULT) { + func_8097E130(this, globalCtx); + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h index 12135eb7b6..d55a683cd2 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h +++ b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h @@ -11,6 +11,11 @@ typedef enum { /* 1 */ KAKERA_COLOR_BROWN } KakeraColorIndex; +typedef struct { + /* 0x0 */ u8 lod; + /* 0x1 */ Color_RGB8 color; +} KakeraColorStruct; // size = 0x4 + typedef struct { /* 0x00 */ Vec3f pos; /* 0x0C */ Vec3f velocity; @@ -29,6 +34,5 @@ typedef struct { /* 0x3C */ Gfx* dList; } EffectSsKakeraInitParams; // size = 0x40 -extern const EffectSsInit Effect_Ss_Kakera_InitVars; #endif From 98ba231fb016a7158cc14af52c96ab408644d317 Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Sun, 19 Dec 2021 11:54:52 -0800 Subject: [PATCH 18/27] pause (Frame Advance) OK (#455) * Matched * Rename and format * typo * Missed renames * Revert "Missed renames" This reverts commit 64d9f7046407eac71b849420457968e3b38fc4d8. * Revert "typo" This reverts commit 81696364d3db71b6085fda1aa99855def390628e. * Revert "Rename and format" This reverts commit aec7d245e896777d70eb7024c336f76ed2a32c7f. * Rename functions * Add header explaining frame advance * Header * Format --- include/functions.h | 4 ++-- src/code/z_pause.c | 38 ++++++++++++++++++++++++++++++++++++-- tools/disasm/functions.txt | 4 ++-- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/functions.h b/include/functions.h index c29dc246d7..364073459b 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2129,8 +2129,8 @@ void func_80121FC4(GlobalContext* globalCtx); Path* Path_GetByIndex(GlobalContext* globalCtx, s16 index, s16 max); f32 Path_OrientAndGetDistSq(Actor* actor, Path* path, s16 waypoint, s16* yaw); void Path_CopyLastPoint(Path* path, Vec3f* dest); -// void func_80122660(void); -// UNK_TYPE4 func_80122670(s32* param_1, Input* input); +void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx); +s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input); // void func_801226E0(void); void func_80122744(GlobalContext* globalCtx, UNK_PTR arg1, u32 arg2, Vec3s* arg3); s32 func_80122760(GlobalContext* globalCtx, UNK_PTR arg1, f32 arg2); diff --git a/src/code/z_pause.c b/src/code/z_pause.c index 44be6238af..bb5b33cf2f 100644 --- a/src/code/z_pause.c +++ b/src/code/z_pause.c @@ -1,5 +1,39 @@ +/* + * File: z_pause.c + * Description: Frame Advance debug feature + * + * This allows you to advance through the game one frame at a time on command. + * To advance a frame, hold Z and press R on the specified controller (see z_play). + * Holding Z and R will advance a frame every half second. + * + * Note: While the system is fully hooked up, there is no way to enable it in game + * Instead one would have to add something like: + * + * if (CHECK_BTN_ALL(input->cur.button, BTN_R) && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { + * frameAdvCtx->enabled = !frameAdvCtx->enabled; + * } + * + * to the start of FrameAdvance_Update, which would allow the system to be toggled on and off by holding R + * and pressing Dpad Down on the specified controller. + * + * Note2: Controllers 2-4's inputs are normally zeroed out, so this would also need to be fixed to use frame advance + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_pause/func_80122660.s") +void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) { + frameAdvCtx->timer = 0; + frameAdvCtx->enabled = false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_pause/func_80122670.s") +/* + * Returns true when frame advance is not active (game will run normally) + */ +s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input) { + if (!frameAdvCtx->enabled || (CHECK_BTN_ALL(input->cur.button, BTN_Z) && + (CHECK_BTN_ALL(input->press.button, BTN_R) || + (CHECK_BTN_ALL(input->cur.button, BTN_R) && (++frameAdvCtx->timer >= 9))))) { + frameAdvCtx->timer = 0; + return true; + } + return false; +} diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 79a254d428..642970ff4e 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2170,8 +2170,8 @@ 0x801224E0:("Path_GetByIndex",), 0x80122524:("Path_OrientAndGetDistSq",), 0x801225CC:("Path_CopyLastPoint",), - 0x80122660:("func_80122660",), - 0x80122670:("func_80122670",), + 0x80122660:("FrameAdvance_Init",), + 0x80122670:("FrameAdvance_Update",), 0x801226E0:("func_801226E0",), 0x80122744:("func_80122744",), 0x80122760:("func_80122760",), From 9b1fe6e91b5568e5261b6d03430554b5e91ea44d Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Mon, 20 Dec 2021 07:01:47 +1100 Subject: [PATCH 19/27] Importing Audio Init Params (#471) * Import audio init params * Add comments describing what these sizes represents * Fix variables.txt * Remove leading zero's from gTatumsPerBeat * Name variables --- include/variables.h | 4 ++-- spec | 2 +- src/code/audio/audio_init_params.c | 12 ++++++++++++ tools/disasm/variables.txt | 7 ++----- 4 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 src/code/audio/audio_init_params.c diff --git a/include/variables.h b/include/variables.h index 12e739c72e..cefacad574 100644 --- a/include/variables.h +++ b/include/variables.h @@ -3090,8 +3090,8 @@ extern f32 D_801E0E24; extern f64 D_801E0EB0; // extern UNK_TYPE4 D_801E1068; extern UNK_PTR D_801E10B0; -// extern UNK_TYPE2 D_801E1102; -// extern UNK_TYPE4 D_801E1104; +extern const s16 gAudioTatumInit[]; +extern const AudioContextInitSizes gAudioContextInitSizes; // extern UNK_TYPE4 D_801E1108; // extern UNK_TYPE4 D_801E110C; // extern UNK_TYPE2 D_801E1180; diff --git a/spec b/spec index b409e53075..59c3e7e02e 100644 --- a/spec +++ b/spec @@ -670,7 +670,7 @@ beginseg include "build/src/code/audio/code_801A7B10.o" include "build/data/code/code_801A7B10.data.o" include "build/data/code/code_801A7B10.bss.o" - include "build/data/code/audio_init_params.rodata.o" + include "build/src/code/audio/audio_init_params.o" include "build/src/code/jpegutils.o" include "build/src/code/jpegdecoder.o" include_readonly "build/src/code/z_game_over.o" diff --git a/src/code/audio/audio_init_params.c b/src/code/audio/audio_init_params.c new file mode 100644 index 0000000000..4e6ef9dfbb --- /dev/null +++ b/src/code/audio/audio_init_params.c @@ -0,0 +1,12 @@ +#include "global.h" + +const s16 gAudioTatumInit[] = { + 0x1C00, // unused + 0x30, // gTatumsPerBeat +}; + +const AudioContextInitSizes gAudioContextInitSizes = { + 0x137F00, // heapSize + 0x1C480, // initPoolSize + 0x1A000, // permanentPoolSize +}; diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 39a9ab6021..fcb848c18e 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -3873,11 +3873,8 @@ 0x801E1070:("jtbl_801E1070","UNK_PTR","",0x4), 0x801E10B0:("jtbl_801E10B0","UNK_PTR","",0x4), 0x801E10C4:("jtbl_801E10C4","UNK_PTR","",0x4), - 0x801E1100:("D_801E1100","UNK_TYPE2","",0x2), - 0x801E1102:("D_801E1102","UNK_TYPE2","",0x2), - 0x801E1104:("D_801E1104","UNK_TYPE4","",0x4), - 0x801E1108:("D_801E1108","UNK_TYPE4","",0x4), - 0x801E110C:("D_801E110C","UNK_TYPE4","",0x4), + 0x801E1100:("gAudioTatumInit","s16","[2]",0x4), + 0x801E1104:("gAudioContextInitSizes","AudioContextInitSizes","",0xC), 0x801E1110:("sGameOverTimer","UNK_TYPE2","",0x2), 0x801E1120:("jtbl_801E1120","UNK_PTR","",0x4), 0x801E1180:("D_801E1180","UNK_TYPE2","",0x2), From 1274b81c5e53c026678f5ace6f144e904633e4e2 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Sun, 19 Dec 2021 20:08:31 +0000 Subject: [PATCH 20/27] sys_ucode OK (#432) * sys_ucode OK * Update file split of data * Format * Name symbols, sizes -> u32 * Correct undefined_syms * Format --- include/functions.h | 2 +- include/ultra64/sptask.h | 6 +++--- include/variables.h | 12 ++++++------ src/code/sys_ucode.c | 26 ++++++++++++++++++++++---- src/libultra/io/sptask.c | 26 ++++++++++---------------- tools/disasm/files.txt | 1 + tools/disasm/variables.txt | 10 +++++----- undefined_syms.txt | 5 +++++ 8 files changed, 53 insertions(+), 35 deletions(-) diff --git a/include/functions.h b/include/functions.h index 364073459b..9986f26148 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3371,7 +3371,7 @@ void Matrix_InsertRotationAroundUnitVector_f(f32 rotation, Vec3f* vector, s32 ap void Matrix_InsertRotationAroundUnitVector_s(s16 rotation, Vec3f* vector, s32 appendToState); u64* SysUcode_GetUCodeBoot(void); -u32 SysUcode_GetUCodeBootSize(void); +size_t SysUcode_GetUCodeBootSize(void); u64* SysUcode_GetUCode(void); u64* SysUcode_GetUCodeData(void); diff --git a/include/ultra64/sptask.h b/include/ultra64/sptask.h index e89557267a..ef4aa4d04a 100644 --- a/include/ultra64/sptask.h +++ b/include/ultra64/sptask.h @@ -2,6 +2,7 @@ #define _SPTASK_H_ #include "PR/ultratypes.h" +#include "libc/stddef.h" /* Task Types */ #define M_NULTASK 0 @@ -80,7 +81,7 @@ typedef struct { /* 0x04 */ u32 flags; /* 0x08 */ u64* ucodeBoot; - /* 0x0C */ u32 ucodeBootSize; + /* 0x0C */ u32 ucodeBootSize; // ucode will load these sizes with lw, so need to be 32-bit /* 0x10 */ u64* ucode; /* 0x14 */ u32 ucodeSize; @@ -101,8 +102,7 @@ typedef struct { /* 0x3C */ u32 yieldDataSize; } OSTask_t; // size = 0x40 -typedef union -{ +typedef union { OSTask_t t; long long int force_structure_alignment; } OSTask; diff --git a/include/variables.h b/include/variables.h index cefacad574..078d300192 100644 --- a/include/variables.h +++ b/include/variables.h @@ -18,7 +18,7 @@ extern u16 gFramebuffer1[SCREEN_HEIGHT][SCREEN_WIDTH]; // at 0x80000500 extern u8 D_80025D00[]; // data -extern UNK_TYPE1 D_800969C0; +extern u64 rspbootTextStart[]; extern u8 D_80096B20; extern vu8 gViConfigUseDefault; extern u8 gViConfigAdditionalScanLines; @@ -1636,8 +1636,8 @@ extern Vec3f D_801D15B0; extern Vec3s D_801D15BC; extern Mtx D_801D1DE0; extern MtxF D_801D1E20; -extern UNK_PTR D_801D1E60; -extern UNK_PTR D_801D1E64; +// extern u64* initialgspUcodeText; +// extern u64* initialgspUcodeData; // extern UNK_TYPE1 D_801D1E70; // extern UNK_TYPE1 D_801D2E80; // extern UNK_TYPE1 D_801D2F80; @@ -3099,8 +3099,8 @@ extern const AudioContextInitSizes gAudioContextInitSizes; // extern UNK_TYPE2 D_801E1630; // extern UNK_TYPE1 D_801E1E40; // extern UNK_TYPE1 D_801E1E80; -// extern UNK_TYPE1 D_801E2160; -// extern UNK_TYPE1 D_801E3790; +extern u64 gspF3DEX2_NoN_fifoTextStart[]; +extern u64 gspF3DEX2_NoN_fifoDataStart[]; extern u64 gJpegUCodeData[]; // extern UNK_TYPE1 D_801E3FA0; @@ -3413,7 +3413,7 @@ extern OSViMode* D_801FBB88; extern u16* gZBufferPtr; extern void* D_801FBB90; extern u64* gGfxSPTaskOutputBufferPtr; -extern u32 gGfxSPTaskOutputBufferSize; +extern size_t gGfxSPTaskOutputBufferSize; // extern UNK_TYPE1 D_801FBB9C; // extern UNK_TYPE1 D_801FBBA0; extern u16 (*gZBuffer)[SCREEN_WIDTH * SCREEN_HEIGHT]; diff --git a/src/code/sys_ucode.c b/src/code/sys_ucode.c index a832f9d386..9bde9e6df3 100644 --- a/src/code/sys_ucode.c +++ b/src/code/sys_ucode.c @@ -1,9 +1,27 @@ +/* + * File: sys_ucode.c + * Description: Functions for obtaining locations and sizes of microcode + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeBoot.s") +extern u64 rspbootTextStart[]; +extern u64 rspbootTextEnd[]; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeBootSize.s") +u64* initialgspUcodeText = gspF3DEX2_NoN_fifoTextStart; +u64* initialgspUcodeData = gspF3DEX2_NoN_fifoDataStart; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCode.s") +u64* SysUcode_GetUCodeBoot(void) { + return rspbootTextStart; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeData.s") +size_t SysUcode_GetUCodeBootSize(void) { + return (uintptr_t)rspbootTextEnd - (uintptr_t)rspbootTextStart; +} + +u64* SysUcode_GetUCode(void) { + return initialgspUcodeText; +} + +u64* SysUcode_GetUCodeData(void) { + return initialgspUcodeData; +} diff --git a/src/libultra/io/sptask.c b/src/libultra/io/sptask.c index 0ec16a4c3c..aeaaf0f82e 100644 --- a/src/libultra/io/sptask.c +++ b/src/libultra/io/sptask.c @@ -32,29 +32,23 @@ void osSpTaskLoad(OSTask* intp) { intp->t.flags &= ~OS_TASK_YIELDED; if (tp->t.flags & OS_TASK_LOADABLE) { - tp->t.ucode = HW_REG((u32)intp->t.yieldDataPtr + OS_YIELD_DATA_SIZE - 4, u32); + tp->t.ucode = HW_REG((uintptr_t)intp->t.yieldDataPtr + OS_YIELD_DATA_SIZE - 4, u32); } } osWritebackDCache(tp, sizeof(OSTask)); __osSpSetStatus(SP_CLR_SIG0 | SP_CLR_SIG1 | SP_CLR_SIG2 | SP_SET_INTR_BREAK); - while (__osSpSetPc((void*)SP_IMEM_START) == -1) { - ; - } - while (__osSpRawStartDma(1, (void*)(SP_IMEM_START - sizeof(*tp)), tp, sizeof(OSTask)) == -1) { - ; - } - while (__osSpDeviceBusy()) { - ; - } - while (__osSpRawStartDma(1, (void*)SP_IMEM_START, tp->t.ucodeBoot, tp->t.ucodeBootSize) == -1) { - ; - } + while (__osSpSetPc((void*)SP_IMEM_START) == -1) {} + + while (__osSpRawStartDma(1, (void*)(SP_IMEM_START - sizeof(*tp)), tp, sizeof(OSTask)) == -1) {} + + while (__osSpDeviceBusy()) {} + + while (__osSpRawStartDma(1, (void*)SP_IMEM_START, tp->t.ucodeBoot, tp->t.ucodeBootSize) == -1) {} } void osSpTaskStartGo(OSTask* tp) { - while (__osSpDeviceBusy()) { - ; - } + while (__osSpDeviceBusy()) {} + __osSpSetStatus(SP_SET_INTR_BREAK | SP_CLR_SSTEP | SP_CLR_BROKE | SP_CLR_HALT); } diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt index 2a4e77715b..7c6bc1e614 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -575,6 +575,7 @@ 0x801D15B0 : "", 0x801D15D0 : "sys_math_atan", 0x801D1DE0 : "sys_matrix", + 0x801D1E60 : "sys_ucode", 0x801D1E70 : "", 0x801D2E80 : "audio_data", 0x801D5FB0 : "audio_synthesis", diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index fcb848c18e..be96bdd280 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -10,7 +10,7 @@ 0x8000031C:("osAppNmiBuffer","s32","[0x10]",0x40), 0x80000500:("gFramebuffer1","u16","[SCREEN_HEIGHT][SCREEN_WIDTH]",0x25800), 0x80025D00:("D_80025D00","u8","[]",0x1), # TODO size - 0x800969C0:("D_800969C0","UNK_TYPE1","",0x1), + 0x800969C0:("rspbootTextStart","u64","[]",0x160), 0x80096B20:("D_80096B20","u8","",0x1), 0x80096B24:("gViConfigUseDefault","vu8","",0x1), 0x80096B28:("gViConfigAdditionalScanLines","u8","",0x1), @@ -2250,8 +2250,8 @@ 0x801D15D0:("sATan2Tbl","s16","[1025]",0x802), 0x801D1DE0:("D_801D1DE0","Mtx","",0x40), 0x801D1E20:("D_801D1E20","MtxF","",0x40), - 0x801D1E60:("D_801D1E60","UNK_PTR","",0x4), - 0x801D1E64:("D_801D1E64","UNK_PTR","",0x4), + 0x801D1E60:("initialgspUcodeText","UNK_PTR","",0x4), + 0x801D1E64:("initialgspUcodeData","UNK_PTR","",0x4), 0x801D1E70:("D_801D1E70","UNK_TYPE1","",0x1), 0x801D2E80:("D_801D2E80","UNK_TYPE1","",0x1), 0x801D2F80:("D_801D2F80","UNK_TYPE1","",0x1), @@ -3882,8 +3882,8 @@ 0x801E1630:("D_801E1630","UNK_TYPE2","",0x2), 0x801E1E40:("D_801E1E40","UNK_TYPE1","",0x1), 0x801E1E80:("D_801E1E80","UNK_TYPE1","",0x1), - 0x801E2160:("D_801E2160","UNK_TYPE1","",0x1), - 0x801E3790:("D_801E3790","UNK_TYPE1","",0x1), + 0x801E2160:("gspF3DEX2_NoN_fifoTextStart","UNK_TYPE1","",0x1), + 0x801E3790:("gspF3DEX2_NoN_fifoDataStart","UNK_TYPE1","",0x1), 0x801E3BB0:("D_801E3BB0","UNK_TYPE1","",0x1), 0x801E3F40:("gJpegUCodeData","UNK_TYPE1","",0x1), 0x801E3FA0:("D_801E3FA0","UNK_TYPE1","",0x1), diff --git a/undefined_syms.txt b/undefined_syms.txt index 0d60359e11..bd5e4e6136 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -127,6 +127,11 @@ D_A4800018 = 0xA4800018; // SI_STATUS_REG gFramebuffer1 = 0x80000500; D_80025D00 = 0x80025D00; +// Ucode symbols + +rspbootTextSize = 0x160; +rspbootTextEnd = rspbootTextStart + rspbootTextSize; + // Segmented Addresses // segment 0x01 From a7cece0fca6804f9c6869f7ca672f25b37127c9b Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Sun, 19 Dec 2021 12:14:36 -0800 Subject: [PATCH 21/27] Code_800f07c0 OK with some documentation (#373) * Matched func_800F07C0 * Matched func_800F0888 * Matched func_800F0944 * Matched func_800F09B4 * Matched func_800F0A94 * Matched func_800F0E94 * Matched func_800F0EEC * Matched func_800F0F28 * Matched func_800F0FF0 * Matched func_800F10AC * Matched func_800F112C * Matched func_800F0DD4 * Matched func_800F0CE4 * Matched func_800F0A20 * Matched func_800F0BB4 * Fix functions.h * Migrated data and add some doc comments, having BSS issues * BSS fix * Fix merge conflict * Document * Run Formatter * Actually save functions.h * Rename UnusedNPC to EnHy * Change some rets and run format * PR review * Fix merge conflict * Minor touchups * Fix renamed func * Change char to UNK_TYPE1 * Add header * Rename two functions * Fix capital X's in undefined_syms * Convert char to UNK_TYPE1 in EnDoor * Change huge ternary into if else for readability * Fix up EnIn * Better whitespace * Format * Revert UNK_TYPE1s in EnDoor * Rename file * Missed rename in undefined_syms --- include/functions.h | 32 +-- include/variables.h | 1 - include/z64.h | 24 ++ spec | 3 +- src/code/code_800F07C0.c | 31 --- src/code/z_en_hy.c | 271 ++++++++++++++++++++ src/overlays/actors/ovl_En_Door/z_en_door.h | 13 +- src/overlays/actors/ovl_En_In/z_en_in.c | 4 +- tools/disasm/files.txt | 2 +- tools/disasm/functions.txt | 24 +- tools/disasm/variables.txt | 2 +- undefined_syms.txt | 18 ++ 12 files changed, 354 insertions(+), 71 deletions(-) delete mode 100644 src/code/code_800F07C0.c create mode 100644 src/code/z_en_hy.c diff --git a/include/functions.h b/include/functions.h index 9986f26148..a3cb3c441b 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1584,21 +1584,21 @@ void func_800F048C(GlobalContext* globalCtx, Vec3f* param_2, u8 param_3, u16 par void Audio_PlaySoundAtPosition(GlobalContext* globalCtx, Vec3f* position, s32 param_3, u16 sfxId); void func_800F0590(GlobalContext* globalCtx, Vec3f* arg1, s32 arg2, s32 arg3); u16 ElfMessage_GetFirstCycleHint(GlobalContext* globalCtx); -// void func_800F07C0(void); -// void func_800F0888(void); -// void func_800F0944(void); -// void func_800F09B4(void); -// void func_800F0A20(void); -// void func_800F0A94(void); -// void func_800F0BB4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); -// void func_800F0CE4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6); -// void func_800F0DD4(void); -// void func_800F0E94(void); -// void func_800F0EEC(void); -// void func_800F0F28(void); -// void func_800F0FF0(void); -// void func_800F10AC(void); -// void func_800F112C(void); +s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex); +Actor* EnHy_FindNearestDoor(Actor* actor, GlobalContext* globalCtx); +void EnHy_ChangeObjectAndAnim(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex); +s32 EnHy_UpdateSkelAnime(EnHy* enHy, GlobalContext* globalCtx); +void EnHy_Blink(EnHy* enHy, s32 arg1); +s32 EnHy_Init(EnHy* enHy, GlobalContext* globalCtx, FlexSkeletonHeader* skeletonHeaderSeg, s16 animIndex); +void func_800F0BB4(EnHy* enHy, GlobalContext* globalCtx, Actor* arg2, s16 arg3, s16 arg4); +s32 func_800F0CE4(EnHy* enHy, GlobalContext* globalCtx, ActorFunc draw, s16 arg3, s16 arg4, f32 arg5); +s32 func_800F0DD4(EnHy* enHy, GlobalContext* globalCtx, s16 arg2, s16 arg3); +s32 EnHy_SetPointFowards(EnHy* enHy, GlobalContext* globalCtx, f32 gravity, s16 animIndex); +s32 EnHy_SetPointBackwards(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex); +s32 EnHy_MoveForwards(EnHy* enHy, f32 arg1); +s32 EnHy_MoveBackwards(EnHy* enHy, f32 arg1); +void EnHy_UpdateCollider(EnHy* enHy, GlobalContext* globalCtx); +s32 EnHy_PlayWalkingSound(EnHy* enHy, GlobalContext* globalCtx, f32 arg2); u16 Text_GetFaceReaction(GlobalContext* globalCtx, u32 reactionSet); void EnvFlags_UnsetAll(GlobalContext* globalCtx); void EnvFlags_Set(GlobalContext* globalCtx, s16 flag); @@ -2667,7 +2667,7 @@ s8 func_8013D8DC(s8 arg0, GlobalContext* globalCtx); s8 func_8013D924(s16 arg0, GlobalContext* globalCtx); Actor* func_ActorCategoryIterateById(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId); s32 func_8013D9C8(GlobalContext* globalCtx, s16* arg1, s16* arg2, s32 arg3); -u8 func_8013DB90(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2); +s32 func_8013DB90(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2); s32 func_8013DC40(Path* arg0, s32 arg1, s32 arg2, Vec3f* arg3); void func_8013DCE0(GlobalContext* globalCtx, Vec3f* arg1, Actor* arg2, struct_8013DF3C_arg1* arg3, Path* arg4, s32 arg5, s32 arg6, s32 arg7, s32 arg8, u8 arg9); s32 func_8013DE04(GlobalContext* globalCtx, struct_8013DF3C_arg1* arg1, struct_8013DF3C_arg1_unk_func1 arg2, struct_8013DF3C_arg1_unk_func2 arg3, struct_8013DF3C_arg1_unk_func2 arg4, struct_8013DF3C_arg1_unk_func2 arg5); diff --git a/include/variables.h b/include/variables.h index 078d300192..35277bb802 100644 --- a/include/variables.h +++ b/include/variables.h @@ -889,7 +889,6 @@ extern s801BB170 D_801BB170[118]; // extern UNK_TYPE1 D_801BC210; extern Gfx D_801BC240[9]; extern Gfx D_801BC288[3]; -// extern UNK_TYPE1 D_801BC2A0; // extern UNK_TYPE1 D_801BC3F0; // extern UNK_TYPE1 D_801BC400; // extern UNK_TYPE1 D_801BC410; diff --git a/include/z64.h b/include/z64.h index 9e7341d965..36982550f4 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1462,6 +1462,30 @@ typedef struct { /* 0x24 */ s16 unk_24; } struct_800BD888_arg1; // size = 0x28 +typedef struct EnHy { + /* 0x000 */ Actor actor; + /* 0x144 */ UNK_TYPE1 unk_144[0x8]; + /* 0x14C */ SkelAnime skelAnime; + /* 0x190 */ s8 unk190; + /* 0x191 */ s8 unk191; + /* 0x192 */ s8 unk192; + /* 0x193 */ s8 animObjIndex; + /* 0x194 */ ColliderCylinder collider; + /* 0x1E0 */ UNK_TYPE1 unk_1E0[0x4]; + /* 0x1E4 */ Path* path; + /* 0x1E8 */ s16 curPoint; + /* 0x1EA */ UNK_TYPE1 unk_1EA[0x2]; + /* 0x1EC */ Vec3f leftFootPos; + /* 0x1F8 */ Vec3f rightFootPos; + /* 0x204 */ u8 isLeftFootOnGround; + /* 0x205 */ u8 isRightFootOnGround; + /* 0x206 */ Vec3s jointTable[16]; + /* 0x266 */ Vec3s morphTable[16]; + /* 0x2C6 */ UNK_TYPE1 unk_2C6[0x120]; + /* 0x3E6 */ s16 eyeTexIndex; + /* 0x3E8 */ s16 blinkTimer; +} EnHy; + typedef struct { /* 0x0 */ u8 unk0; /* 0x4 */ s32 unk4; diff --git a/spec b/spec index 59c3e7e02e..eb3864f26e 100644 --- a/spec +++ b/spec @@ -473,8 +473,7 @@ beginseg include "build/data/code/z_eff_footmark.data.o" include "build/src/code/code_800F0390.o" include "build/src/code/z_elf_message.o" - include "build/src/code/code_800F07C0.o" - include "build/data/code/code_801BC2A0.data.o" + include "build/src/code/z_en_hy.o" include "build/src/code/z_face_reaction.o" include "build/src/code/z_env_flags.o" include "build/src/code/z_eventmgr.o" diff --git a/src/code/code_800F07C0.c b/src/code/code_800F07C0.c deleted file mode 100644 index 9255dcfcbf..0000000000 --- a/src/code/code_800F07C0.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F07C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0888.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0944.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F09B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0A20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0A94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0BB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0CE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0DD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0E94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0EEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0F28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0FF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F10AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F112C.s") diff --git a/src/code/z_en_hy.c b/src/code/z_en_hy.c new file mode 100644 index 0000000000..73adc5fa58 --- /dev/null +++ b/src/code/z_en_hy.c @@ -0,0 +1,271 @@ +/* + * File: z_en_hy.c + * Description: Unused System for NPCs (includes animation, door interaction, blinking, pathing, and collider helpers) + */ + +#include "global.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" + +extern AnimationHeader D_0600007C; +extern AnimationHeader D_0600066C; +extern AnimationHeader D_0600071C; +extern AnimationHeader D_060008C0; +extern AnimationHeader D_06000AB0; +extern AnimationHeader D_06000FDC; +extern AnimationHeader D_06001494; +extern AnimationHeader D_06001908; +extern AnimationHeader D_06001EE0; +extern AnimationHeader D_06005DC4; +extern AnimationHeader D_06005D9C; +extern AnimationHeader D_0600DED8; +extern AnimationHeader D_0600F920; +extern AnimationHeader D_0600FC1C; +extern AnimationHeader D_0600FEE4; +extern AnimationHeader D_06010330; + +static ActorAnimationEntryS animations[] = { + { &D_0600007C, 1.0f, 0, -1, 0, 0 }, { &D_06001494, 1.0f, 0, -1, 0, 0 }, { &D_06001494, 1.0f, 0, -1, 0, -8 }, + { &D_06001908, 1.0f, 0, -1, 0, 0 }, { &D_06001908, 1.0f, 0, -1, 0, -8 }, { &D_060008C0, 1.0f, 0, -1, 0, 0 }, + { &D_06005DC4, 1.0f, 0, -1, 0, 0 }, { &D_06000FDC, 1.0f, 0, -1, 0, 0 }, { &D_06000AB0, 1.0f, 0, -1, 0, -8 }, + { &D_0600066C, 1.0f, 0, -1, 0, 0 }, { &D_0600071C, 1.0f, 0, -1, 0, 0 }, { &D_06001EE0, 1.0f, 0, -1, 0, 0 }, + { &D_0600DED8, 1.5f, 0, -1, 2, 0 }, { &D_0600F920, 1.5f, 0, -1, 2, 0 }, { &D_0600FC1C, 1.0f, 0, -1, 0, 0 }, + { &D_0600FEE4, 1.0f, 0, -1, 0, 0 }, { &D_06010330, 1.0f, 0, -1, 0, 0 }, { &D_0600FC1C, 1.0f, 0, -1, 0, -8 }, + { &D_0600FEE4, 1.0f, 0, -1, 0, -8 }, { &D_06010330, 1.0f, 0, -1, 0, -8 }, { &D_06005D9C, 1.0f, 0, -1, 0, -8 }, +}; + +s8 D_801BC3F0[] = { -1, 1, 12, 13, 14, 9, 10, 11, 0, 6, 7, 8, 3, 4, 5, 2 }; + +s8 D_801BC400[] = { 0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13, 0 }; + +u8 D_801BC410[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex) { + s16 frameCount; + s32 isChanged = false; + + if (animIndex >= 0 && animIndex <= 20) { + isChanged = true; + frameCount = animations[animIndex].frameCount; + if (frameCount < 0) { + frameCount = Animation_GetLastFrame(&animations[animIndex].animationSeg->common); + } + Animation_Change(skelAnime, animations[animIndex].animationSeg, animations[animIndex].playbackSpeed, + animations[animIndex].frame, frameCount, animations[animIndex].mode, + animations[animIndex].transitionRate); + } + return isChanged; +} + +//! @TODO: Return Door instance when c and h files are split +Actor* EnHy_FindNearestDoor(Actor* actor, GlobalContext* globalCtx) { + Actor* nearestDoor = NULL; + Actor* doorIter = NULL; + Actor* door; + f32 dist; + s32 isSetup = false; + f32 minDist = 0.0f; + + do { + doorIter = func_ActorCategoryIterateById(globalCtx, doorIter, ACTORCAT_DOOR, ACTOR_EN_DOOR); + door = doorIter; + dist = Actor_DistanceBetweenActors(actor, door); + if (!isSetup || (dist < minDist)) { + nearestDoor = door; + minDist = dist; + isSetup = true; + } + doorIter = door->next; + } while (doorIter != NULL); + + if (1) {} + + return nearestDoor; +} + +void EnHy_ChangeObjectAndAnim(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex) { + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[enHy->animObjIndex].segment); + EnHy_ChangeAnim(&enHy->skelAnime, animIndex); +} + +s32 EnHy_UpdateSkelAnime(EnHy* enHy, GlobalContext* globalCtx) { + s32 isUpdated = false; + + if (enHy->actor.draw != NULL) { + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[enHy->animObjIndex].segment); + SkelAnime_Update(&enHy->skelAnime); + isUpdated = true; + } + return isUpdated; +} + +void EnHy_Blink(EnHy* enHy, s32 eyeTexMaxIndex) { + if (DECR(enHy->blinkTimer) == 0) { + enHy->eyeTexIndex++; + if (enHy->eyeTexIndex >= eyeTexMaxIndex) { + enHy->eyeTexIndex = 0; + enHy->blinkTimer = Rand_S16Offset(30, 30); + } + } +} + +s32 EnHy_Init(EnHy* enHy, GlobalContext* globalCtx, FlexSkeletonHeader* skeletonHeaderSeg, s16 animIndex) { + s32 isInitialized = false; + + if ((func_8013D8DC(enHy->animObjIndex, globalCtx) == 1) && (func_8013D8DC(enHy->unk190, globalCtx) == 1) && + (func_8013D8DC(enHy->unk191, globalCtx) == 1) && (func_8013D8DC(enHy->unk192, globalCtx) == 1)) { + enHy->actor.objBankIndex = enHy->unk192; + isInitialized = true; + ActorShape_Init(&enHy->actor.shape, 0.0f, NULL, 0.0f); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[enHy->actor.objBankIndex].segment); + SkelAnime_InitFlex(globalCtx, &enHy->skelAnime, skeletonHeaderSeg, NULL, enHy->jointTable, enHy->morphTable, + 16); + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + } + return isInitialized; +} + +//! @TODO: Should just take EnDoor instead of actor when c and h are split +void func_800F0BB4(EnHy* enHy, GlobalContext* globalCtx, Actor* door, s16 arg3, s16 arg4) { + s32 pad; + s8 sp3B; + Vec3f offset; + f32 phi_f0; + + Actor_CalcOffsetOrientedToDrawRotation(door, &offset, &enHy->actor.world.pos); + phi_f0 = (offset.z >= 0.0f) ? 1.0f : -1.0f; + sp3B = ((s8)phi_f0 < 0) ? 0 : 2; + EnHy_ChangeObjectAndAnim(enHy, globalCtx, (sp3B == 0) ? arg3 : arg4); + enHy->skelAnime.baseTransl = *enHy->skelAnime.jointTable; + enHy->skelAnime.prevTransl = *enHy->skelAnime.jointTable; + enHy->skelAnime.moveFlags |= 3; + AnimationContext_SetMoveActor(globalCtx, &enHy->actor, &enHy->skelAnime, 1.0f); + ((EnDoor*)door)->unk_1A1 = 1; + ((EnDoor*)door)->unk_1A0 = sp3B; +} + +s32 func_800F0CE4(EnHy* enHy, GlobalContext* globalCtx, ActorFunc draw, s16 arg3, s16 arg4, f32 arg5) { + s32 ret = false; + s16 yaw; + Actor* door; + s32 pad; + + if (func_8013D68C(enHy->path, enHy->curPoint, &enHy->actor.world.pos)) { + door = EnHy_FindNearestDoor(&enHy->actor, globalCtx); + if (door != NULL) { + ret = true; + func_800F0BB4(enHy, globalCtx, door, arg3, arg4); + yaw = Math_Vec3f_Yaw(&enHy->actor.world.pos, &door->world.pos); + enHy->actor.world.pos.x += arg5 * Math_SinS(yaw); + enHy->actor.world.pos.z += arg5 * Math_CosS(yaw); + enHy->actor.world.rot.y = -yaw; + enHy->actor.shape.rot.y = -yaw; + enHy->actor.draw = draw; + } + } + return ret; +} + +s32 func_800F0DD4(EnHy* enHy, GlobalContext* globalCtx, s16 arg2, s16 arg3) { + s32 ret = false; + s32 pad; + Actor* door; + + enHy->curPoint = 0; + if (func_8013D68C(enHy->path, enHy->curPoint, &enHy->actor.world.pos)) { + door = EnHy_FindNearestDoor(&enHy->actor, globalCtx); + if (door != NULL) { + ret = true; + func_800F0BB4(enHy, globalCtx, door, arg2, arg3); + enHy->actor.shape.rot.y = Math_Vec3f_Yaw(&enHy->actor.world.pos, &door->world.pos); + enHy->actor.world.rot.y = enHy->actor.shape.rot.y; + enHy->actor.gravity = 0.0f; + enHy->actor.flags &= ~1; + } + } + return ret; +} + +s32 EnHy_SetPointFowards(EnHy* enHy, GlobalContext* globalCtx, f32 gravity, s16 animIndex) { + enHy->actor.gravity = gravity; + enHy->actor.flags |= 1; + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + enHy->curPoint++; + return 0; +} + +s32 EnHy_SetPointBackwards(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex) { + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + enHy->curPoint--; + return 0; +} + +s32 EnHy_MoveForwards(EnHy* enHy, f32 speedTarget) { + s16 rotStep; + s32 reachedEnd = false; + Vec3f curPointPos; + + Math_SmoothStepToF(&enHy->actor.speedXZ, speedTarget, 0.4f, 1000.0f, 0.0f); + rotStep = enHy->actor.speedXZ * 400.0f; + if (func_8013D68C(enHy->path, enHy->curPoint, &curPointPos) && func_8013D768(&enHy->actor, &curPointPos, rotStep)) { + enHy->curPoint++; + if (enHy->curPoint >= enHy->path->count) { + reachedEnd = true; + } + } + return reachedEnd; +} + +s32 EnHy_MoveBackwards(EnHy* enHy, f32 speedTarget) { + s16 rotStep; + s32 reachedEnd = false; + Vec3f curPointPos; + + Math_SmoothStepToF(&enHy->actor.speedXZ, speedTarget, 0.4f, 1000.0f, 0.0f); + rotStep = enHy->actor.speedXZ * 400.0f; + if (func_8013D68C(enHy->path, enHy->curPoint, &curPointPos) && func_8013D768(&enHy->actor, &curPointPos, rotStep)) { + enHy->curPoint--; + if (enHy->curPoint < 0) { + reachedEnd = true; + } + } + return reachedEnd; +} + +void EnHy_UpdateCollider(EnHy* enHy, GlobalContext* globalCtx) { + enHy->collider.dim.pos.x = enHy->actor.world.pos.x; + enHy->collider.dim.pos.y = enHy->actor.world.pos.y; + enHy->collider.dim.pos.z = enHy->actor.world.pos.z; + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &enHy->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &enHy->collider.base); +} + +s32 EnHy_PlayWalkingSound(EnHy* enHy, GlobalContext* globalCtx, f32 distAboveThreshold) { + u8 wasLeftFootOnGround = enHy->isLeftFootOnGround; + u8 wasRightFootOnGround = enHy->isRightFootOnGround; + s32 waterSfxId; + u16 sfxId; + u8 isFootOnGround; + + if (enHy->actor.bgCheckFlags & 0x20) { + if (enHy->actor.depthInWater < 20.0f) { + waterSfxId = NA_SE_PL_WALK_WATER0 - SFX_FLAG; + } else { + waterSfxId = NA_SE_PL_WALK_WATER1 - SFX_FLAG; + } + sfxId = waterSfxId + SFX_FLAG; + } else { + sfxId = SurfaceType_GetSfx(&globalCtx->colCtx, enHy->actor.floorPoly, enHy->actor.floorBgId) + SFX_FLAG; + } + + enHy->isLeftFootOnGround = isFootOnGround = func_8013DB90(globalCtx, &enHy->leftFootPos, distAboveThreshold); + if (enHy->isLeftFootOnGround && !wasLeftFootOnGround && isFootOnGround) { + Audio_PlayActorSound2(&enHy->actor, sfxId); + } + + enHy->isRightFootOnGround = isFootOnGround = func_8013DB90(globalCtx, &enHy->rightFootPos, distAboveThreshold); + if (enHy->isRightFootOnGround && !wasRightFootOnGround && isFootOnGround) { + Audio_PlayActorSound2(&enHy->actor, sfxId); + } + return 0; +} diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.h b/src/overlays/actors/ovl_En_Door/z_en_door.h index 1dbc470dc7..7331339fcf 100644 --- a/src/overlays/actors/ovl_En_Door/z_en_door.h +++ b/src/overlays/actors/ovl_En_Door/z_en_door.h @@ -8,11 +8,14 @@ struct EnDoor; typedef void (*EnDoorActionFunc)(struct EnDoor*, GlobalContext*); typedef struct EnDoor { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x63]; - /* 0x01A7 */ s8 unk_1A7; - /* 0x01A8 */ char unk_1A8[0x20]; - /* 0x01C8 */ EnDoorActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ char unk_144[0x5C]; + /* 0x1A0 */ s8 unk_1A0; + /* 0x1A1 */ s8 unk_1A1; + /* 0x1A2 */ char unk_1A2[0x5]; + /* 0x1A7 */ s8 unk_1A7; + /* 0x1A8 */ char unk_1A8[0x20]; + /* 0x1C8 */ EnDoorActionFunc actionFunc; } EnDoor; // size = 0x1CC extern const ActorInit En_Door_InitVars; diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c index 910f7fc7bf..800e44c6fb 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/src/overlays/actors/ovl_En_In/z_en_in.c @@ -214,11 +214,11 @@ s32 func_808F3178(EnIn* this, GlobalContext* globalCtx) { u8 tmp; this->unk260 = tmp = func_8013DB90(globalCtx, &this->unk248, -6.0f); - if (this->unk260 != 0 && prevUnk260 == 0 && tmp & 0xFF) { + if (this->unk260 != 0 && prevUnk260 == 0 && tmp) { Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_CONCRETE); } this->unk261 = tmp = func_8013DB90(globalCtx, &this->unk254, -6.0f); - if (this->unk261 != 0 && prevUnk261 == 0 && tmp & 0xFF) { + if (this->unk261 != 0 && prevUnk261 == 0 && tmp) { Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_CONCRETE); } return 0; diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt index 7c6bc1e614..52d498397e 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -380,7 +380,7 @@ 0x800EFE60 : "z_eff_footmark", 0x800F0390 : "code_800F0390", 0x800F05C0 : "z_elf_message", - 0x800F07C0 : "code_800F07C0", + 0x800F07C0 : "z_en_hy", 0x800F1250 : "z_face_reaction", 0x800F12D0 : "z_env_flags", 0x800F1460 : "z_eventmgr", diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 642970ff4e..5919ceb7a6 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -1616,21 +1616,21 @@ 0x800F0568:("Audio_PlaySoundAtPosition",), 0x800F0590:("func_800F0590",), 0x800F05C0:("ElfMessage_GetFirstCycleHint",), - 0x800F07C0:("func_800F07C0",), - 0x800F0888:("func_800F0888",), - 0x800F0944:("func_800F0944",), - 0x800F09B4:("func_800F09B4",), - 0x800F0A20:("func_800F0A20",), - 0x800F0A94:("func_800F0A94",), + 0x800F07C0:("EnHy_ChangeAnim",), + 0x800F0888:("EnHy_FindNearestDoor",), + 0x800F0944:("EnHy_ChangeObjectAndAnim",), + 0x800F09B4:("EnHy_UpdateSkelAnime",), + 0x800F0A20:("EnHy_Blink",), + 0x800F0A94:("EnHy_Init",), 0x800F0BB4:("func_800F0BB4",), 0x800F0CE4:("func_800F0CE4",), 0x800F0DD4:("func_800F0DD4",), - 0x800F0E94:("func_800F0E94",), - 0x800F0EEC:("func_800F0EEC",), - 0x800F0F28:("func_800F0F28",), - 0x800F0FF0:("func_800F0FF0",), - 0x800F10AC:("func_800F10AC",), - 0x800F112C:("func_800F112C",), + 0x800F0E94:("EnHy_SetPointFowards",), + 0x800F0EEC:("EnHy_SetPointBackwards",), + 0x800F0F28:("EnHy_MoveForwards",), + 0x800F0FF0:("EnHy_MoveBackwards",), + 0x800F10AC:("EnHy_UpdateCollider",), + 0x800F112C:("EnHy_PlayWalkingSound",), 0x800F1250:("Text_GetFaceReaction",), 0x800F12D0:("EnvFlags_UnsetAll",), 0x800F1304:("EnvFlags_Set",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index be96bdd280..d5d2eb0e7f 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -923,7 +923,7 @@ 0x801BC2A0:("D_801BC2A0","UNK_TYPE1","",0x1), 0x801BC3F0:("D_801BC3F0","UNK_TYPE1","",0x1), 0x801BC400:("D_801BC400","UNK_TYPE1","",0x1), - 0x801BC410:("D_801BC410","UNK_TYPE1","",0x1), + 0x801BC410:("D_801BC410","s32",[],0x10), 0x801BC420:("sReactionTextIds","u16","[]",0x140A), 0x801BD830:("actorCutscenesGlobalCutscenes","ActorCutscene","[8]",0x80), 0x801BD8B0:("actorCutsceneCurrent","s16","",0x2), diff --git a/undefined_syms.txt b/undefined_syms.txt index bd5e4e6136..ff66eaa8a4 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -608,6 +608,24 @@ D_06011AB8 = 0x06011AB8; D_06012A80 = 0x06012A80; D_06013138 = 0x06013138; +// z_en_hy.c +D_0600007C = 0x0600007C; +D_0600066C = 0x0600066C; +D_0600071C = 0x0600071C; +D_060008C0 = 0x060008C0; +D_06000AB0 = 0x06000AB0; +D_06000FDC = 0x06000FDC; +D_06001494 = 0x06001494; +D_06001908 = 0x06001908; +D_06001EE0 = 0x06001EE0; +D_06005DC4 = 0x06005DC4; +D_06005D9C = 0x06005D9C; +D_0600DED8 = 0x0600DED8; +D_0600F920 = 0x0600F920; +D_0600FC1C = 0x0600FC1C; +D_0600FEE4 = 0x0600FEE4; +D_06010330 = 0x06010330; + // ovl_Arms_Hook D_0601D960 = 0x0601D960; From 985852f8376c295553899bd570015a4c6aee2b79 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Sun, 19 Dec 2021 20:21:27 +0000 Subject: [PATCH 22/27] Fix actor struct offsets (#463) * Fix offsets * Bell Co-authored-by: Anghelo Carvajal --- src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h | 2 +- src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h | 2 +- src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h | 2 +- src/overlays/actors/ovl_Boss_02/z_boss_02.h | 4 ++-- src/overlays/actors/ovl_Boss_07/z_boss_07.h | 2 +- src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h | 8 ++++---- src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h | 2 +- src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h | 2 +- src/overlays/actors/ovl_En_Az/z_en_az.h | 2 +- src/overlays/actors/ovl_En_Bat/z_en_bat.h | 2 +- src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h | 2 +- src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h | 2 +- src/overlays/actors/ovl_En_Bombal/z_en_bombal.h | 2 +- src/overlays/actors/ovl_En_Bubble/z_en_bubble.h | 2 +- src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h | 2 +- src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h | 2 +- src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h | 2 +- src/overlays/actors/ovl_En_Dnh/z_en_dnh.h | 2 +- src/overlays/actors/ovl_En_Encount1/z_en_encount1.h | 2 +- src/overlays/actors/ovl_En_Encount3/z_en_encount3.h | 2 +- src/overlays/actors/ovl_En_Estone/z_en_estone.h | 2 +- src/overlays/actors/ovl_En_Firefly/z_en_firefly.h | 2 +- src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h | 2 +- .../actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h | 2 +- src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h | 2 +- src/overlays/actors/ovl_En_Kusa/z_en_kusa.h | 2 +- src/overlays/actors/ovl_En_Maruta/z_en_maruta.h | 2 +- src/overlays/actors/ovl_En_Minideath/z_en_minideath.h | 2 +- src/overlays/actors/ovl_En_Mkk/z_en_mkk.h | 2 +- src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h | 2 +- src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h | 2 +- src/overlays/actors/ovl_En_Paper/z_en_paper.h | 2 +- src/overlays/actors/ovl_En_Pm/z_en_pm.h | 4 ++-- src/overlays/actors/ovl_En_Racedog/z_en_racedog.h | 2 +- src/overlays/actors/ovl_En_Ru/z_en_ru.h | 2 +- src/overlays/actors/ovl_En_Shn/z_en_shn.h | 2 +- src/overlays/actors/ovl_En_Si/z_en_si.h | 2 +- src/overlays/actors/ovl_En_Slime/z_en_slime.h | 2 +- src/overlays/actors/ovl_En_Sw/z_en_sw.h | 2 +- src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h | 2 +- src/overlays/actors/ovl_En_Test6/z_en_test6.h | 2 +- src/overlays/actors/ovl_En_Tg/z_en_tg.h | 2 +- src/overlays/actors/ovl_En_Trt2/z_en_trt2.h | 2 +- src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h | 2 +- src/overlays/actors/ovl_En_Viewer/z_en_viewer.h | 2 +- src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h | 2 +- src/overlays/actors/ovl_En_Zo/z_en_zo.h | 2 +- src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h | 2 +- src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h | 2 +- src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h | 2 +- src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h | 2 +- src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h | 2 +- src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h | 2 +- src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h | 2 +- src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h | 2 +- src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h | 2 +- src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h | 2 +- .../actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h | 2 +- src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h | 2 +- src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h | 2 +- 60 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h index 5eac10d0b0..4a0e14d2fd 100644 --- a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h +++ b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h @@ -10,7 +10,7 @@ typedef void (*BgDyYoseizoActionFunc)(struct BgDyYoseizo*, GlobalContext*); typedef struct BgDyYoseizo { /* 0x0000 */ Actor actor; /* 0x0144 */ BgDyYoseizoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x33BC]; + /* 0x0148 */ char unk_148[0x33BC]; } BgDyYoseizo; // size = 0x3504 extern const ActorInit Bg_Dy_Yoseizo_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h b/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h index 8bbcb45bfb..b4d176d9e9 100644 --- a/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h +++ b/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h @@ -10,7 +10,7 @@ typedef void (*BgFireWallActionFunc)(struct BgFireWall*, GlobalContext*); typedef struct BgFireWall { /* 0x0000 */ Actor actor; /* 0x0144 */ BgFireWallActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x68]; + /* 0x0148 */ char unk_148[0x68]; } BgFireWall; // size = 0x1B0 extern const ActorInit Bg_Fire_Wall_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h b/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h index e2ae361122..6fc19e4ca0 100644 --- a/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h +++ b/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h @@ -10,7 +10,7 @@ typedef void (*BgSpoutFireActionFunc)(struct BgSpoutFire*, GlobalContext*); typedef struct BgSpoutFire { /* 0x0000 */ Actor actor; /* 0x0144 */ BgSpoutFireActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x50]; + /* 0x0148 */ char unk_148[0x50]; } BgSpoutFire; // size = 0x198 extern const ActorInit Bg_Spout_Fire_InitVars; diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.h b/src/overlays/actors/ovl_Boss_02/z_boss_02.h index d630acb8f5..babf40b769 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.h +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.h @@ -40,7 +40,7 @@ typedef struct Boss02 { /* 0x016C */ s16 unk_016C; /* 0x0170 */ Vec3f unk_0170; /* 0x017C */ Vec3f unk_017C; - /* 0x018C */ Vec3f unk_0188; + /* 0x0188 */ Vec3f unk_0188; /* 0x0194 */ u8 unk_0194; /* 0x0195 */ u8 unk_0195; /* 0x0196 */ s16 unk_0196; @@ -53,7 +53,7 @@ typedef struct Boss02 { /* 0x01AC */ f32 unk_01AC; /* 0x01B0 */ Vec3f unk_01B0; /* 0x01BC */ Vec3f unk_01BC[200]; - /* 0x0B1c */ Vec3f unk_0B1C[200]; + /* 0x0B1C */ Vec3f unk_0B1C[200]; /* 0x147C */ Vec3f unk_147C[23]; /* 0x1590 */ SkelAnime skelAnime; /* 0x15D4 */ Vec3s jointTable[13]; diff --git a/src/overlays/actors/ovl_Boss_07/z_boss_07.h b/src/overlays/actors/ovl_Boss_07/z_boss_07.h index 21e30eb920..b8ace3f9ce 100644 --- a/src/overlays/actors/ovl_Boss_07/z_boss_07.h +++ b/src/overlays/actors/ovl_Boss_07/z_boss_07.h @@ -10,7 +10,7 @@ typedef void (*Boss07ActionFunc)(struct Boss07*, GlobalContext*); typedef struct Boss07 { /* 0x0000 */ Actor actor; /* 0x0144 */ Boss07ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xAAD8]; + /* 0x0148 */ char unk_148[0xAAD8]; } Boss07; // size = 0xAC20 extern const ActorInit Boss_07_InitVars; diff --git a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h index 5e29a38156..3b5882692f 100644 --- a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h +++ b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h @@ -13,16 +13,16 @@ typedef struct BossHakuginParticle { /* 0x18 */ s16 unk_18; /* 0x1A */ s16 unk_1A; /* 0x1C */ Vec3s unk_1C; - /* 0x22 */ f32 unk_24; + /* 0x24 */ f32 unk_24; } BossHakuginParticle; // size = 0x28 typedef struct BossHakugin { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ char unk_0144[0x44]; /* 0x0188 */ BossHakuginActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x86C]; + /* 0x018C */ char unk_018C[0x86C]; /* 0x09F8 */ BossHakuginParticle unk_9F8[180]; - /* 0x0A14 */ char unk_A04[0x2DFC]; + /* 0x2618 */ char unk_2618[0x11F8]; } BossHakugin; // size = 0x3810 extern const ActorInit Boss_Hakugin_InitVars; diff --git a/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h b/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h index 958608c653..4ce31a8a17 100644 --- a/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h +++ b/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h @@ -10,7 +10,7 @@ typedef void (*DmHinaActionFunc)(struct DmHina*, GlobalContext*); typedef struct DmHina { /* 0x0000 */ Actor actor; /* 0x0144 */ DmHinaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x3C]; + /* 0x0148 */ char unk_148[0x3C]; } DmHina; // size = 0x184 extern const ActorInit Dm_Hina_InitVars; diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h index e0418f3057..5f30ef196e 100644 --- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h +++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h @@ -10,7 +10,7 @@ typedef void (*EnAob01ActionFunc)(struct EnAob01*, GlobalContext*); typedef struct EnAob01 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnAob01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2FC]; + /* 0x0148 */ char unk_148[0x2FC]; } EnAob01; // size = 0x444 extern const ActorInit En_Aob_01_InitVars; diff --git a/src/overlays/actors/ovl_En_Az/z_en_az.h b/src/overlays/actors/ovl_En_Az/z_en_az.h index 17b2b85fa3..89d7c1a09b 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.h +++ b/src/overlays/actors/ovl_En_Az/z_en_az.h @@ -10,7 +10,7 @@ typedef void (*EnAzActionFunc)(struct EnAz*, GlobalContext*); typedef struct EnAz { /* 0x0000 */ Actor actor; /* 0x0144 */ EnAzActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x290]; + /* 0x0148 */ char unk_148[0x290]; } EnAz; // size = 0x3D8 extern const ActorInit En_Az_InitVars; diff --git a/src/overlays/actors/ovl_En_Bat/z_en_bat.h b/src/overlays/actors/ovl_En_Bat/z_en_bat.h index d1f949f441..2ccaaa8928 100644 --- a/src/overlays/actors/ovl_En_Bat/z_en_bat.h +++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.h @@ -10,7 +10,7 @@ typedef void (*EnBatActionFunc)(struct EnBat*, GlobalContext*); typedef struct EnBat { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBatActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x94]; + /* 0x0148 */ char unk_148[0x94]; } EnBat; // size = 0x1DC extern const ActorInit En_Bat_InitVars; diff --git a/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h b/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h index 157ac7eaf2..20416b4f9f 100644 --- a/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h +++ b/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h @@ -10,7 +10,7 @@ typedef void (*EnBba01ActionFunc)(struct EnBba01*, GlobalContext*); typedef struct EnBba01 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBba01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4D4]; + /* 0x0148 */ char unk_148[0x4D4]; } EnBba01; // size = 0x61C extern const ActorInit En_Bba_01_InitVars; diff --git a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h index 13172b1808..910ad51745 100644 --- a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h +++ b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h @@ -10,7 +10,7 @@ typedef void (*EnBomChuActionFunc)(struct EnBomChu*, GlobalContext*); typedef struct EnBomChu { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBomChuActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x98]; + /* 0x0148 */ char unk_148[0x98]; } EnBomChu; // size = 0x1E0 extern const ActorInit En_Bom_Chu_InitVars; diff --git a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h index ea538d5ce1..ce6fd67244 100644 --- a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h +++ b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h @@ -10,7 +10,7 @@ typedef void (*EnBombalActionFunc)(struct EnBombal*, GlobalContext*); typedef struct EnBombal { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBombalActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x28FC]; + /* 0x0148 */ char unk_148[0x28FC]; } EnBombal; // size = 0x2A44 extern const ActorInit En_Bombal_InitVars; diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h index c78b9df693..f2901b3249 100644 --- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h +++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h @@ -10,7 +10,7 @@ typedef void (*EnBubbleActionFunc)(struct EnBubble*, GlobalContext*); typedef struct EnBubble { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBubbleActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x110]; + /* 0x0148 */ char unk_148[0x110]; } EnBubble; // size = 0x258 extern const ActorInit En_Bubble_InitVars; diff --git a/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h b/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h index 4211550ecd..db0e797e96 100644 --- a/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h +++ b/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h @@ -10,7 +10,7 @@ typedef void (*EnCne01ActionFunc)(struct EnCne01*, GlobalContext*); typedef struct EnCne01 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnCne01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4D4]; + /* 0x0148 */ char unk_148[0x4D4]; } EnCne01; // size = 0x61C extern const ActorInit En_Cne_01_InitVars; diff --git a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h index 31d1b980e7..6bab3c11a6 100644 --- a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h +++ b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h @@ -10,7 +10,7 @@ typedef void (*EnColManActionFunc)(struct EnColMan*, GlobalContext*); typedef struct EnColMan { /* 0x0000 */ Actor actor; /* 0x0144 */ EnColManActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x58]; + /* 0x0148 */ char unk_148[0x58]; } EnColMan; // size = 0x1A0 extern const ActorInit En_Col_Man_InitVars; diff --git a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h index 4ed2a76ab8..e6a00853e1 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h @@ -20,7 +20,7 @@ typedef struct EnDinofos { /* 0x28C */ s16 unk_28C; /* 0x28E */ s16 unk_28E; /* 0x290 */ s16 unk_290; - /* 0x290 */ s16 unk_292; + /* 0x292 */ s16 unk_292; /* 0x294 */ UNK_TYPE1 unk_294[4]; /* 0x298 */ s16 camId; /* 0x29A */ Vec3s unk_29A; diff --git a/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h b/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h index 9edb339d46..21336aa912 100644 --- a/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h +++ b/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h @@ -10,7 +10,7 @@ typedef void (*EnDnhActionFunc)(struct EnDnh*, GlobalContext*); typedef struct EnDnh { /* 0x0000 */ Actor actor; /* 0x0144 */ EnDnhActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x74]; + /* 0x0148 */ char unk_148[0x74]; } EnDnh; // size = 0x1BC extern const ActorInit En_Dnh_InitVars; diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h index e473615cbe..72638d9a6a 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h @@ -10,7 +10,7 @@ typedef void (*EnEncount1ActionFunc)(struct EnEncount1*, GlobalContext*); typedef struct EnEncount1 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEncount1ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x1C]; + /* 0x0148 */ char unk_148[0x1C]; } EnEncount1; // size = 0x164 extern const ActorInit En_Encount1_InitVars; diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h index 49c7ccef43..dbfe780527 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h @@ -10,7 +10,7 @@ typedef void (*EnEncount3ActionFunc)(struct EnEncount3*, GlobalContext*); typedef struct EnEncount3 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEncount3ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x84]; + /* 0x0148 */ char unk_148[0x84]; } EnEncount3; // size = 0x1CC extern const ActorInit En_Encount3_InitVars; diff --git a/src/overlays/actors/ovl_En_Estone/z_en_estone.h b/src/overlays/actors/ovl_En_Estone/z_en_estone.h index eec7f2d24b..848d41f8b7 100644 --- a/src/overlays/actors/ovl_En_Estone/z_en_estone.h +++ b/src/overlays/actors/ovl_En_Estone/z_en_estone.h @@ -10,7 +10,7 @@ typedef void (*EnEstoneActionFunc)(struct EnEstone*, GlobalContext*); typedef struct EnEstone { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEstoneActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2C2C]; + /* 0x0148 */ char unk_148[0x2C2C]; } EnEstone; // size = 0x2D74 extern const ActorInit En_Estone_InitVars; diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h index 72a4739cbf..e4439ec36b 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h @@ -34,7 +34,7 @@ typedef struct EnFirefly { /* 0x2F4 */ u32 unk_2F4; /* 0x2F8 */ Vec3f unk_2F8; /* 0x304 */ Vec3f unk_304; - /* 0x304 */ Vec3f unk_310; + /* 0x310 */ Vec3f unk_310; /* 0x31C */ ColliderSphere collider; } EnFirefly; // size = 0x374 diff --git a/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h b/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h index 6207c5fc34..f9983e26a3 100644 --- a/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h +++ b/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h @@ -10,7 +10,7 @@ typedef void (*EnHonotrapActionFunc)(struct EnHonotrap*, GlobalContext*); typedef struct EnHonotrap { /* 0x0000 */ Actor actor; /* 0x0144 */ EnHonotrapActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x17C]; + /* 0x0148 */ char unk_148[0x17C]; } EnHonotrap; // size = 0x2C4 extern const ActorInit En_Honotrap_InitVars; diff --git a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h index d565469742..df29dbc602 100644 --- a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h +++ b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h @@ -10,7 +10,7 @@ typedef void (*EnInvadepohDemoActionFunc)(struct EnInvadepohDemo*, GlobalContext typedef struct EnInvadepohDemo { /* 0x0000 */ Actor actor; /* 0x0144 */ EnInvadepohDemoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x180]; + /* 0x0148 */ char unk_148[0x180]; } EnInvadepohDemo; // size = 0x2C8 extern const ActorInit En_Invadepoh_Demo_InitVars; diff --git a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h index b34679bd3e..72aeb93b7c 100644 --- a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h +++ b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h @@ -10,7 +10,7 @@ typedef void (*EnKujiyaActionFunc)(struct EnKujiya*, GlobalContext*); typedef struct EnKujiya { /* 0x0000 */ Actor actor; /* 0x0144 */ EnKujiyaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } EnKujiya; // size = 0x14C extern const ActorInit En_Kujiya_InitVars; diff --git a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h index e3756a4d28..612f7b2eff 100644 --- a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h +++ b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h @@ -10,7 +10,7 @@ typedef void (*EnKusaActionFunc)(struct EnKusa*, GlobalContext*); typedef struct EnKusa { /* 0x0000 */ Actor actor; /* 0x0144 */ EnKusaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x54]; + /* 0x0148 */ char unk_148[0x54]; } EnKusa; // size = 0x19C extern const ActorInit En_Kusa_InitVars; diff --git a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h index 4ed2d7f6ea..df53fbe499 100644 --- a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h +++ b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h @@ -10,7 +10,7 @@ typedef void (*EnMarutaActionFunc)(struct EnMaruta*, GlobalContext*); typedef struct EnMaruta { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMarutaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xDC]; + /* 0x0148 */ char unk_148[0xDC]; } EnMaruta; // size = 0x224 extern const ActorInit En_Maruta_InitVars; diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h index 854589854a..7ac4dee6cc 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h @@ -10,7 +10,7 @@ typedef void (*EnMinideathActionFunc)(struct EnMinideath*, GlobalContext*); typedef struct EnMinideath { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMinideathActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x164]; + /* 0x0148 */ char unk_148[0x164]; } EnMinideath; // size = 0x2AC extern const ActorInit En_Minideath_InitVars; diff --git a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h index 0bc6037484..c80fc7a20e 100644 --- a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h +++ b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h @@ -10,7 +10,7 @@ typedef void (*EnMkkActionFunc)(struct EnMkk*, GlobalContext*); typedef struct EnMkk { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMkkActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x8C]; + /* 0x0148 */ char unk_148[0x8C]; } EnMkk; // size = 0x1D4 extern const ActorInit En_Mkk_InitVars; diff --git a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h index 58c625b361..796482b141 100644 --- a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h +++ b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h @@ -10,7 +10,7 @@ typedef void (*EnMttagActionFunc)(struct EnMttag*, GlobalContext*); typedef struct EnMttag { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMttagActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x20]; + /* 0x0148 */ char unk_148[0x20]; } EnMttag; // size = 0x168 extern const ActorInit En_Mt_tag_InitVars; diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h index 0c6cfe423d..53b63236e1 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h @@ -10,7 +10,7 @@ typedef void (*EnOkarinaTagActionFunc)(struct EnOkarinaTag*, GlobalContext*); typedef struct EnOkarinaTag { /* 0x0000 */ Actor actor; /* 0x0144 */ EnOkarinaTagActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x14]; + /* 0x0148 */ char unk_148[0x14]; } EnOkarinaTag; // size = 0x15C extern const ActorInit En_Okarina_Tag_InitVars; diff --git a/src/overlays/actors/ovl_En_Paper/z_en_paper.h b/src/overlays/actors/ovl_En_Paper/z_en_paper.h index d2e12e137d..0147442a92 100644 --- a/src/overlays/actors/ovl_En_Paper/z_en_paper.h +++ b/src/overlays/actors/ovl_En_Paper/z_en_paper.h @@ -10,7 +10,7 @@ typedef void (*EnPaperActionFunc)(struct EnPaper*, GlobalContext*); typedef struct EnPaper { /* 0x0000 */ Actor actor; /* 0x0144 */ EnPaperActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xC40]; + /* 0x0148 */ char unk_148[0xC40]; } EnPaper; // size = 0xD88 extern const ActorInit En_Paper_InitVars; diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.h b/src/overlays/actors/ovl_En_Pm/z_en_pm.h index d571f43bd6..6d545373b8 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.h +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.h @@ -24,11 +24,11 @@ typedef struct EnPm { /* 0x0250 */ s32 unk_250; /* 0x0254 */ s32 unk_254; /* 0x0258 */ u8 unk_258; - /* 0x026C */ UNK_TYPE* unk_25C; + /* 0x025C */ UNK_TYPE* unk_25C; /* 0x0260 */ s8 unk_260; /* 0x0264 */ s32 unk_264; /* 0x0268 */ Actor* unk_268; - /* 0x0268 */ Vec3f unk_26C; + /* 0x026C */ Vec3f unk_26C; /* 0x0278 */ Vec3f unk_278; /* 0x0284 */ Vec3f unk_284; /* 0x0290 */ Vec3s unk_290; diff --git a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h index da4ced9ddf..a4b721f5de 100644 --- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h +++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h @@ -10,7 +10,7 @@ typedef void (*EnRacedogActionFunc)(struct EnRacedog*, GlobalContext*); typedef struct EnRacedog { /* 0x0000 */ Actor actor; /* 0x0144 */ EnRacedogActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x180]; + /* 0x0148 */ char unk_148[0x180]; } EnRacedog; // size = 0x2C8 extern const ActorInit En_Racedog_InitVars; diff --git a/src/overlays/actors/ovl_En_Ru/z_en_ru.h b/src/overlays/actors/ovl_En_Ru/z_en_ru.h index 9b1037ed4d..b368fb584f 100644 --- a/src/overlays/actors/ovl_En_Ru/z_en_ru.h +++ b/src/overlays/actors/ovl_En_Ru/z_en_ru.h @@ -10,7 +10,7 @@ typedef void (*EnRuActionFunc)(struct EnRu*, GlobalContext*); typedef struct EnRu { /* 0x0000 */ Actor actor; /* 0x0144 */ EnRuActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x30C]; + /* 0x0148 */ char unk_148[0x30C]; } EnRu; // size = 0x454 extern const ActorInit En_Ru_InitVars; diff --git a/src/overlays/actors/ovl_En_Shn/z_en_shn.h b/src/overlays/actors/ovl_En_Shn/z_en_shn.h index 8f02bd8c57..b5d98919d9 100644 --- a/src/overlays/actors/ovl_En_Shn/z_en_shn.h +++ b/src/overlays/actors/ovl_En_Shn/z_en_shn.h @@ -10,7 +10,7 @@ typedef void (*EnShnActionFunc)(struct EnShn*, GlobalContext*); typedef struct EnShn { /* 0x0000 */ Actor actor; /* 0x0144 */ EnShnActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x1A8]; + /* 0x0148 */ char unk_148[0x1A8]; } EnShn; // size = 0x2F0 extern const ActorInit En_Shn_InitVars; diff --git a/src/overlays/actors/ovl_En_Si/z_en_si.h b/src/overlays/actors/ovl_En_Si/z_en_si.h index 60a7937a98..26e33e728a 100644 --- a/src/overlays/actors/ovl_En_Si/z_en_si.h +++ b/src/overlays/actors/ovl_En_Si/z_en_si.h @@ -10,7 +10,7 @@ typedef void (*EnSiActionFunc)(struct EnSi*, GlobalContext*); typedef struct EnSi { /* 0x0000 */ Actor actor; /* 0x0144 */ EnSiActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x58]; + /* 0x0148 */ char unk_148[0x58]; } EnSi; // size = 0x1A0 extern const ActorInit En_Si_InitVars; diff --git a/src/overlays/actors/ovl_En_Slime/z_en_slime.h b/src/overlays/actors/ovl_En_Slime/z_en_slime.h index 6269f331e6..c24cae04e1 100644 --- a/src/overlays/actors/ovl_En_Slime/z_en_slime.h +++ b/src/overlays/actors/ovl_En_Slime/z_en_slime.h @@ -10,7 +10,7 @@ typedef void (*EnSlimeActionFunc)(struct EnSlime*, GlobalContext*); typedef struct EnSlime { /* 0x0000 */ Actor actor; /* 0x0144 */ EnSlimeActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xC0]; + /* 0x0148 */ char unk_148[0xC0]; } EnSlime; // size = 0x208 extern const ActorInit En_Slime_InitVars; diff --git a/src/overlays/actors/ovl_En_Sw/z_en_sw.h b/src/overlays/actors/ovl_En_Sw/z_en_sw.h index 975e4e36d8..4c30b49655 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.h +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.h @@ -43,7 +43,7 @@ typedef struct EnSw { /* 0x047C */ s16 unk_47C[12]; /* 0x0494 */ s16 unk_494; /* 0x0496 */ s16 unk_496; - /* 0x0468 */ s16 unk_498; + /* 0x0498 */ s16 unk_498; /* 0x049C */ s32 unk_49C; /* 0x04A0 */ s32 unk_4A0; } EnSw; // size = 0x4A4 diff --git a/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h b/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h index 22dd08e893..5e9512c7cf 100644 --- a/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h +++ b/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h @@ -10,7 +10,7 @@ typedef void (*EnTanron2ActionFunc)(struct EnTanron2*, GlobalContext*); typedef struct EnTanron2 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTanron2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xB4]; + /* 0x0148 */ char unk_148[0xB4]; } EnTanron2; // size = 0x1FC extern const ActorInit En_Tanron2_InitVars; diff --git a/src/overlays/actors/ovl_En_Test6/z_en_test6.h b/src/overlays/actors/ovl_En_Test6/z_en_test6.h index 94f2556228..9cee7cf1d2 100644 --- a/src/overlays/actors/ovl_En_Test6/z_en_test6.h +++ b/src/overlays/actors/ovl_En_Test6/z_en_test6.h @@ -10,7 +10,7 @@ typedef void (*EnTest6ActionFunc)(struct EnTest6*, GlobalContext*); typedef struct EnTest6 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTest6ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x140]; + /* 0x0148 */ char unk_148[0x140]; } EnTest6; // size = 0x288 extern const ActorInit En_Test6_InitVars; diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.h b/src/overlays/actors/ovl_En_Tg/z_en_tg.h index 706618774e..de0c6fd2e3 100644 --- a/src/overlays/actors/ovl_En_Tg/z_en_tg.h +++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.h @@ -10,7 +10,7 @@ typedef void (*EnTgActionFunc)(struct EnTg*, GlobalContext*); typedef struct EnTg { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTgActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x400]; + /* 0x0148 */ char unk_148[0x400]; } EnTg; // size = 0x548 extern const ActorInit En_Tg_InitVars; diff --git a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h index 69fb439fd9..11320af0cb 100644 --- a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h +++ b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h @@ -10,7 +10,7 @@ typedef void (*EnTrt2ActionFunc)(struct EnTrt2*, GlobalContext*); typedef struct EnTrt2 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTrt2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x294]; + /* 0x0148 */ char unk_148[0x294]; } EnTrt2; // size = 0x3DC extern const ActorInit En_Trt2_InitVars; diff --git a/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h b/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h index ed083ec50e..793958ed74 100644 --- a/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h +++ b/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h @@ -10,7 +10,7 @@ typedef void (*EnTruMtActionFunc)(struct EnTruMt*, GlobalContext*); typedef struct EnTruMt { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTruMtActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x260]; + /* 0x0148 */ char unk_148[0x260]; } EnTruMt; // size = 0x3A8 extern const ActorInit En_Tru_Mt_InitVars; diff --git a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h index 6b145b0c55..566c21f3ce 100644 --- a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h +++ b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h @@ -10,7 +10,7 @@ typedef void (*EnViewerActionFunc)(struct EnViewer*, GlobalContext*); typedef struct EnViewer { /* 0x0000 */ Actor actor; /* 0x0144 */ EnViewerActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x10]; + /* 0x0148 */ char unk_148[0x10]; } EnViewer; // size = 0x158 extern const ActorInit En_Viewer_InitVars; diff --git a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h index 0ff444fcec..0f5b705f5c 100644 --- a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h +++ b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h @@ -10,7 +10,7 @@ typedef void (*EnWizFireActionFunc)(struct EnWizFire*, GlobalContext*); typedef struct EnWizFire { /* 0x0000 */ Actor actor; /* 0x0144 */ EnWizFireActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x29AC]; + /* 0x0148 */ char unk_148[0x29AC]; } EnWizFire; // size = 0x2AF4 extern const ActorInit En_Wiz_Fire_InitVars; diff --git a/src/overlays/actors/ovl_En_Zo/z_en_zo.h b/src/overlays/actors/ovl_En_Zo/z_en_zo.h index b876205f5f..a823a1ec07 100644 --- a/src/overlays/actors/ovl_En_Zo/z_en_zo.h +++ b/src/overlays/actors/ovl_En_Zo/z_en_zo.h @@ -10,7 +10,7 @@ typedef void (*EnZoActionFunc)(struct EnZo*, GlobalContext*); typedef struct EnZo { /* 0x0000 */ Actor actor; /* 0x0144 */ EnZoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2DC]; + /* 0x0148 */ char unk_148[0x2DC]; } EnZo; // size = 0x424 extern const ActorInit En_Zo_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h b/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h index 2f2dd7b132..76265bcec2 100644 --- a/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h +++ b/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h @@ -11,7 +11,7 @@ typedef struct ObjBell { /* 0x1B4 */ ColliderSphere collider2; /* 0x20C */ s16 unk_20C; // bell rotation angle? /* 0x20E */ s16 unk_20E; - /* 0x20E */ s16 unk_20F; + /* 0x210 */ s16 unk_210; /* 0x212 */ s16 unk_212; /* 0x214 */ s16 unk_214; /* 0x216 */ char unk_216[0x06]; diff --git a/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h index 79fb22868c..5c3235ef2a 100644 --- a/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h +++ b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h @@ -10,7 +10,7 @@ typedef void (*ObjBigicicleActionFunc)(struct ObjBigicicle*, GlobalContext*); typedef struct ObjBigicicle { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjBigicicleActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x9C]; + /* 0x0148 */ char unk_148[0x9C]; } ObjBigicicle; // size = 0x1E4 extern const ActorInit Obj_Bigicicle_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h index a00ad595b0..8b498f39e5 100644 --- a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h +++ b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h @@ -10,7 +10,7 @@ typedef void (*ObjChanActionFunc)(struct ObjChan*, GlobalContext*); typedef struct ObjChan { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjChanActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x9C]; + /* 0x0148 */ char unk_148[0x9C]; } ObjChan; // size = 0x1E4 extern const ActorInit Obj_Chan_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h index 9ca91823e8..303a3ed5e5 100644 --- a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h +++ b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h @@ -10,7 +10,7 @@ typedef void (*ObjCombActionFunc)(struct ObjComb*, GlobalContext*); typedef struct ObjComb { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjCombActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x74]; + /* 0x0148 */ char unk_148[0x74]; } ObjComb; // size = 0x1BC extern const ActorInit Obj_Comb_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h index b2ffc1121b..2631e91bef 100644 --- a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h +++ b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h @@ -10,7 +10,7 @@ typedef void (*ObjDemoActionFunc)(struct ObjDemo*, GlobalContext*); typedef struct ObjDemo { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjDemoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xC]; + /* 0x0148 */ char unk_148[0xC]; } ObjDemo; // size = 0x154 extern const ActorInit Obj_Demo_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h b/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h index f77913d881..d9ac284bdc 100644 --- a/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h +++ b/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h @@ -10,7 +10,7 @@ typedef void (*ObjHarikoActionFunc)(struct ObjHariko*, GlobalContext*); typedef struct ObjHariko { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjHarikoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x10]; + /* 0x0148 */ char unk_148[0x10]; } ObjHariko; // size = 0x158 extern const ActorInit Obj_Hariko_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h index 4ee73ecbe3..b306e2552c 100644 --- a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h +++ b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h @@ -10,7 +10,7 @@ typedef void (*ObjMure2ActionFunc)(struct ObjMure2*, GlobalContext*); typedef struct ObjMure2 { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjMure2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x38]; + /* 0x0148 */ char unk_148[0x38]; } ObjMure2; // size = 0x180 extern const ActorInit Obj_Mure2_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h b/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h index c000b1e6f5..67252a147d 100644 --- a/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h +++ b/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h @@ -10,7 +10,7 @@ typedef void (*ObjMure3ActionFunc)(struct ObjMure3*, GlobalContext*); typedef struct ObjMure3 { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjMure3ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x20]; + /* 0x0148 */ char unk_148[0x20]; } ObjMure3; // size = 0x168 extern const ActorInit Obj_Mure3_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h index 0a98759d03..db43c5c16b 100644 --- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h +++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h @@ -10,7 +10,7 @@ typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, GlobalContext*); typedef struct ObjRoomtimer { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjRoomtimerActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } ObjRoomtimer; // size = 0x14C extern const ActorInit Obj_Roomtimer_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h index 148c8deb6c..680417d506 100644 --- a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h +++ b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h @@ -10,7 +10,7 @@ typedef void (*ObjSwprizeActionFunc)(struct ObjSwprize*, GlobalContext*); typedef struct ObjSwprize { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjSwprizeActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } ObjSwprize; // size = 0x14C extern const ActorInit Obj_Swprize_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h index 0d734b85e5..83f267d37f 100644 --- a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h +++ b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h @@ -10,7 +10,7 @@ typedef void (*ObjTakarayaWallActionFunc)(struct ObjTakarayaWall*, GlobalContext typedef struct ObjTakarayaWall { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjTakarayaWallActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x98]; + /* 0x0148 */ char unk_148[0x98]; } ObjTakarayaWall; // size = 0x1E0 extern const ActorInit Obj_Takaraya_Wall_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h index 31b7df5836..d3a188e41d 100644 --- a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h +++ b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h @@ -10,7 +10,7 @@ typedef void (*ObjTsuboActionFunc)(struct ObjTsubo*, GlobalContext*); typedef struct ObjTsubo { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjTsuboActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x54]; + /* 0x0148 */ char unk_148[0x54]; } ObjTsubo; // size = 0x19C extern const ActorInit Obj_Tsubo_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h b/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h index e7e4073a33..0b0b8b3752 100644 --- a/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h +++ b/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h @@ -10,7 +10,7 @@ typedef void (*ObjWturnActionFunc)(struct ObjWturn*, GlobalContext*); typedef struct ObjWturn { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjWturnActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } ObjWturn; // size = 0x14C extern const ActorInit Obj_Wturn_InitVars; From 51ee1c2c704074895bb88254e8c43cedf5d437e2 Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Mon, 20 Dec 2021 07:32:41 +1100 Subject: [PATCH 23/27] Name coordinate transformation matrix similar to OoT (#499) * name coordiante transformation names similar to OoT * update actorfixer --- include/functions.h | 2 +- include/z64.h | 4 ++-- src/code/z_debug_display.c | 2 +- src/code/z_effect_soft_sprite_old_init.c | 2 +- src/code/z_lights.c | 2 +- src/code/z_play.c | 2 +- src/overlays/actors/ovl_Boss_02/z_boss_02.c | 8 ++++---- src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 4 ++-- src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c | 4 ++-- src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 6 +++--- src/overlays/actors/ovl_En_Dai/z_en_dai.c | 2 +- src/overlays/actors/ovl_En_Dnb/z_en_dnb.c | 2 +- src/overlays/actors/ovl_En_Dno/z_en_dno.c | 2 +- src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c | 2 +- src/overlays/actors/ovl_En_Elforg/z_en_elforg.c | 2 +- src/overlays/actors/ovl_En_Encount2/z_en_encount2.c | 2 +- src/overlays/actors/ovl_En_Fg/z_en_fg.c | 4 ++-- src/overlays/actors/ovl_En_Fish2/z_en_fish2.c | 2 +- src/overlays/actors/ovl_En_Fu/z_en_fu.c | 2 +- src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c | 6 +++--- src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c | 2 +- src/overlays/actors/ovl_En_Niw/z_en_niw.c | 2 +- src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c | 2 +- src/overlays/actors/ovl_En_Sob1/z_en_sob1.c | 2 +- src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c | 4 ++-- src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c | 2 +- src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c | 2 +- tools/actorfixer.py | 3 +++ tools/disasm/functions.txt | 2 +- tools/sizes/code_functions.csv | 2 +- 30 files changed, 44 insertions(+), 41 deletions(-) diff --git a/include/functions.h b/include/functions.h index a3cb3c441b..4663c59e40 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2970,7 +2970,7 @@ void func_80166B30(GlobalContext* globalCtx); void func_80167814(GlobalContext* globalCtx); void func_80167DE4(GlobalContext* globalCtx); // void func_80167F0C(void); -void func_80168090(GlobalContext* globalCtx); +void Play_Draw(GlobalContext* globalCtx); void func_80168DAC(GlobalContext* globalCtx); void Play_Update(GlobalContext* globalCtx); s32 func_801690CC(GlobalContext* globalCtx); diff --git a/include/z64.h b/include/z64.h index 36982550f4..f094c7cfc4 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1401,9 +1401,9 @@ struct GlobalContext { /* 0x18794 */ void* unk_18794; //! @TODO: Determine function prototype /* 0x18798 */ s32 (*setPlayerTalkAnim)(struct GlobalContext* globalCtx, void* talkAnim, s32 arg2); /* 0x1879C */ s16 unk_1879C[10]; - /* 0x187B0 */ MtxF projectionMatrix; + /* 0x187B0 */ MtxF viewProjectionMtxF; /* 0x187F0 */ Vec3f unk_187F0; - /* 0x187FC */ MtxF mf_187FC; + /* 0x187FC */ MtxF billboardMtxF; /* 0x1883C */ Mtx* unk_1883C; /* 0x18840 */ u32 gameplayFrames; /* 0x18844 */ u8 unk_18844; diff --git a/src/code/z_debug_display.c b/src/code/z_debug_display.c index f9c9f60b40..a62d4ddb9e 100644 --- a/src/code/z_debug_display.c +++ b/src/code/z_debug_display.c @@ -70,7 +70,7 @@ void DebugDisplay_DrawSpriteI8(DebugDispObject* dispObj, void* texture, GlobalCo gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a); Matrix_InsertTranslation(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_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertRotation(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, diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c index f293c81c2f..6deeb79434 100644 --- a/src/code/z_effect_soft_sprite_old_init.c +++ b/src/code/z_effect_soft_sprite_old_init.c @@ -48,7 +48,7 @@ void EffectSs_DrawGEffect(GlobalContext* globalCtx, EffectSs* this, void* textur scale = this->rgScale * 0.0025f; SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z); SkinMatrix_SetScale(&mfScale, scale, scale, scale); - SkinMatrix_MtxFMtxFMult(&mfTrans, &globalCtx->mf_187FC, &mfTrans11DA0); + SkinMatrix_MtxFMtxFMult(&mfTrans, &globalCtx->billboardMtxF, &mfTrans11DA0); SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult); gSegments[0x06] = PHYSICAL_TO_VIRTUAL(object); gSPSegment(POLY_XLU_DISP++, 0x06, object); diff --git a/src/code/z_lights.c b/src/code/z_lights.c index fb88fbc773..4d649da2d7 100644 --- a/src/code/z_lights.c +++ b/src/code/z_lights.c @@ -131,7 +131,7 @@ void Lights_BindPoint(Lights* lights, LightParams* params, GlobalContext* global posF.x = params->point.x; posF.y = params->point.y; posF.z = params->point.z; - SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->projectionMatrix, &posF, &adjustedPos); + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &posF, &adjustedPos); if ((adjustedPos.z > -radiusF) && (600 + radiusF > adjustedPos.z) && (400 > fabsf(adjustedPos.x) - radiusF) && (400 > fabsf(adjustedPos.y) - radiusF)) { light = Lights_FindSlot(lights); diff --git a/src/code/z_play.c b/src/code/z_play.c index 8f15c577a2..7e0e018c74 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -52,7 +52,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80167F0C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80168090.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Draw.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80168DAC.s") diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 090a1c3613..03c1733153 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -1471,7 +1471,7 @@ void Boss02_Draw(Actor* thisx, GlobalContext* globalCtx2) { } func_809DA50C(1, &this->colliderSphere2, &this->unk_147C[i + 1]); - SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->projectionMatrix, &this->unk_147C[i + 1], &this->unk_167C, + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &this->unk_147C[i + 1], &this->unk_167C, &this->actor.projectedW); } else { func_809DA50C(i, &this->colliderSphere1, &this->unk_147C[i + 1]); @@ -1578,7 +1578,7 @@ void func_809DD2F8(GlobalContext* globalCtx) { (effect->unk_26 + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -1619,7 +1619,7 @@ void func_809DD2F8(GlobalContext* globalCtx) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)effect->unk_2C); Matrix_InsertTranslation(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -1643,7 +1643,7 @@ void func_809DD2F8(GlobalContext* globalCtx) { (effect->unk_26 + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, 0); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 6ff4f90965..9cc359c9e6 100644 --- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -588,7 +588,7 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, GlobalContext* globalCtx2) { break; } - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_f(DEGF_TO_RADF(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -659,7 +659,7 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, GlobalContext* globalCtx2) { gSPDisplayList(POLY_XLU_DISP++, &D_04023348); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_f(DEGF_TO_RADF(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c index bf72f3721e..296d6e429f 100644 --- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c +++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c @@ -288,7 +288,7 @@ void func_80919768(Actor* thisx, GlobalContext* globalCtx2) { initialPositions->z * ((this->dz * aux) + (1.0f - this->dz)), MTXMODE_APPLY); Matrix_Scale(this->scalingFactor, this->scalingFactor, this->scalingFactor, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -345,7 +345,7 @@ void func_809199FC(Actor* thisx, GlobalContext* globalCtx2) { Matrix_Scale(*distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index 26759e2bf7..f76b22296c 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -871,7 +871,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -effect->actionTimer * 5, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->smokeScaleX * effect->scale, effect->smokeScaleY * effect->scale, 1.0f, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, 20.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -897,7 +897,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -effect->actionTimer * 15, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->scale, effect->scale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectDL); @@ -919,7 +919,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { // Draw the flash billboard effect. gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (s8)effect->primColor.a); Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(2.0f * effect->scale, 2.0f * effect->scale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagFlashEffectDL); diff --git a/src/overlays/actors/ovl_En_Dai/z_en_dai.c b/src/overlays/actors/ovl_En_Dai/z_en_dai.c index fb917742c8..8f14b6c678 100644 --- a/src/overlays/actors/ovl_En_Dai/z_en_dai.c +++ b/src/overlays/actors/ovl_En_Dai/z_en_dai.c @@ -103,7 +103,7 @@ void func_80B3E168(EnDaiParticle* particle, GlobalContext* globalCtx2) { (particle->unk_02 + (i * 3)) * 15, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); Matrix_InsertTranslation(particle->unk_10.x, particle->unk_10.y, particle->unk_10.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(particle->unk_34, particle->unk_34, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), diff --git a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c index c6e7eb942b..be0f95eb93 100644 --- a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c +++ b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c @@ -288,7 +288,7 @@ s32 func_80A50950(EnDnbUnkStruct* arg0, GlobalContext* globalCtx2) { Matrix_InsertTranslation(arg0->unk_0C.x, arg0->unk_0C.y, arg0->unk_0C.z, MTXMODE_NEW); Matrix_Scale(arg0->unk_04, arg0->unk_04, 1.0f, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Dno/z_en_dno.c b/src/overlays/actors/ovl_En_Dno/z_en_dno.c index ea2900fb43..5a6b883685 100644 --- a/src/overlays/actors/ovl_En_Dno/z_en_dno.c +++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.c @@ -1005,7 +1005,7 @@ void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve frames = globalCtx->gameplayFrames; Matrix_MultiplyVector3fByState(&D_80A73B40, &sp84); func_80A711D0(this, globalCtx, &sp84); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(0.15f, 0.15f, 1.0f, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, -3200.0f, 0.0f, MTXMODE_APPLY); gfxXlu = func_8012C2B4(POLY_XLU_DISP); diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c index 2bd0a5512c..cd574fb318 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -155,7 +155,7 @@ void EnElfbub_Draw(Actor* thisx, GlobalContext* globalCtx2) { func_8012C2DC(globalCtx->state.gfxCtx); Matrix_InsertTranslation(0.0f, 0.0f, 1.0f, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, MTXMODE_APPLY); Matrix_InsertZRotation_s(this->zRot, MTXMODE_APPLY); Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c index 285ed462ca..6ca10601cd 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c @@ -607,7 +607,7 @@ void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) { AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C818)); break; } - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c index a5f6b1d7af..f196fa54bb 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -284,7 +284,7 @@ void EnEncount2_DrawParticles(EnEncount2* this, GlobalContext* globalCtx) { gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(POLY_XLU_DISP++, 250, 180, 255, sPtr->alpha); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_f(DEGTORAD(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Fg/z_en_fg.c b/src/overlays/actors/ovl_En_Fg/z_en_fg.c index 197f076067..f91ee7a312 100644 --- a/src/overlays/actors/ovl_En_Fg/z_en_fg.c +++ b/src/overlays/actors/ovl_En_Fg/z_en_fg.c @@ -383,7 +383,7 @@ void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_StatePush(); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); Matrix_StatePop(); @@ -477,7 +477,7 @@ void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, alpha); gDPPipeSync(POLY_XLU_DISP++); Matrix_InsertTranslation(dustEffect->pos.x, dustEffect->pos.y, dustEffect->pos.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(dustEffect->xyScale, dustEffect->xyScale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c index 7b52e0a30b..f9dfa048d6 100644 --- a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c +++ b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c @@ -1058,7 +1058,7 @@ void EnFish2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_StatePush(); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); diff --git a/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 558e1cf990..7dcf097d79 100644 --- a/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -1463,7 +1463,7 @@ void func_80964950(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len) { flag = true; } Matrix_InsertTranslation(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(ptr->unk_00, ptr->unk_00, ptr->unk_00, MTXMODE_APPLY); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&D_0405E6F0)); diff --git a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c index 2d29831022..b71a44a342 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -4480,7 +4480,7 @@ void func_80B4DB14(Actor* thisx, GlobalContext* globalCtx) { gSPSetOtherMode(gfx++, G_SETOTHERMODE_H, 4, 4, 0x00000080); gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_NEW); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_NEW); Matrix_GetStateTranslationAndScaledZ(60.0f, &sp80); sp74.x = thisx->world.pos.x + sp80.x; sp74.y = thisx->world.pos.y + sp80.y + 68.0f; @@ -4572,14 +4572,14 @@ void func_80B4E3F0(Actor* thisx, GlobalContext* globalCtx) { Vec3f sp5C; Matrix_StatePush(); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_NEW); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_NEW); Matrix_GetStateTranslationAndScaledZ(200.0f, &sp5C); Matrix_StatePop(); sp5C.x += thisx->world.pos.x; sp5C.y += thisx->world.pos.y; sp5C.z += thisx->world.pos.z; EnInvadepoh_SetSysMatrix(&sp5C); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_InsertZRotation_s(((EnInvadepoh*)thisx)->unk304, MTXMODE_APPLY); OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c index 9095d702b3..4b5585086d 100644 --- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c +++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c @@ -622,7 +622,7 @@ void EnMinifrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/src/overlays/actors/ovl_En_Niw/z_en_niw.c index 3eadcc15ec..c65d794bb6 100644 --- a/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -1007,7 +1007,7 @@ void EnNiw_DrawFeathers(EnNiw* this, GlobalContext* globalCtx) { } Matrix_InsertTranslation(feather->pos.x, feather->pos.y, feather->pos.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(feather->scale, feather->scale, 1.0f, MTXMODE_APPLY); Matrix_InsertZRotation_f(feather->zRot, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, -1000.0f, 0.0f, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c index d2140a16e3..10f9a1783e 100644 --- a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c +++ b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c @@ -171,7 +171,7 @@ void EnNutsball_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_s(this->actor.home.rot.z, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_04058BA0); diff --git a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c index 93504249ed..140fc2c710 100644 --- a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c +++ b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c @@ -1695,7 +1695,7 @@ void EnSob1_DrawBombShopkeeper(Actor* thisx, GlobalContext* globalCtx) { EnSob1_DrawStickDirectionPrompt(globalCtx, this); frames = globalCtx->gameplayFrames; func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPSegment(POLY_XLU_DISP++, 0x08, diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c index 64374e36c5..89973ff694 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c @@ -1078,7 +1078,7 @@ void EnThiefbird_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi OPEN_DISPS(globalCtx->state.gfxCtx); gfx = POLY_OPA_DISP; - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(&gfx[1], this->unk_3E4); POLY_OPA_DISP = &gfx[2]; @@ -1136,7 +1136,7 @@ void func_80C13354(EnThiefbird* this, GlobalContext* globalCtx2) { for (i = 0; i < ARRAY_COUNT(this->unk_3F0); i++, ptr++) { if (ptr->unk_22 != 0) { Matrix_InsertTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_RotateY(ptr->unk_1E, MTXMODE_APPLY); Matrix_InsertZRotation_s(ptr->unk_20, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, -10.0f, 0.0f, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c b/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c index 9b7582f85a..153a4a914b 100644 --- a/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c +++ b/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c @@ -156,7 +156,7 @@ void ObjMoonStone_Draw(Actor* thisx, GlobalContext* globalCtx) { AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06001C60)); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_06000D78); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, D_06000C80); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c index 4962598534..6e66c9cabe 100644 --- a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c +++ b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c @@ -172,7 +172,7 @@ void ObjWarpstone_Draw(Actor* thisx, GlobalContext* globalCtx2) { func_8012C2DC(globalCtx->state.gfxCtx); Matrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 34.0f, this->dyna.actor.world.pos.z, MTXMODE_NEW); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, 0.0f, 30.0f, MTXMODE_APPLY); Matrix_Scale(this->dyna.actor.velocity.x, this->dyna.actor.velocity.x, this->dyna.actor.velocity.x, MTXMODE_APPLY); diff --git a/tools/actorfixer.py b/tools/actorfixer.py index 7f0b7bf5f5..428c6dee5b 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -338,6 +338,9 @@ animdict = { "skelAnime.unk3E": "skelAnime.baseTransl", "actor.yDistToWater" : "actor.depthInWater", "actor.yDistToPlayer" : "actor.playerHeightRel", + + "globalCtx->mf_187FC" : "globalCtx->billboardMtxF", + "globalCtx->projectionMatrix" : "globalCtx->viewProjectionMtxF", } def replace_anim(file): diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 5919ceb7a6..537d9b2ecf 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2995,7 +2995,7 @@ 0x80167814:("func_80167814",), 0x80167DE4:("func_80167DE4",), 0x80167F0C:("func_80167F0C",), - 0x80168090:("func_80168090",), + 0x80168090:("Play_Draw",), 0x80168DAC:("func_80168DAC",), 0x80168F64:("Play_Update",), 0x801690CC:("func_801690CC",), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 1b7b3fbdc2..8a0090f845 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -2509,7 +2509,7 @@ asm/non_matchings/code/z_play/func_80166B30.s,func_80166B30,0x80166B30,0x339 asm/non_matchings/code/z_play/func_80167814.s,func_80167814,0x80167814,0x174 asm/non_matchings/code/z_play/func_80167DE4.s,func_80167DE4,0x80167DE4,0x4A asm/non_matchings/code/z_play/func_80167F0C.s,func_80167F0C,0x80167F0C,0x61 -asm/non_matchings/code/z_play/func_80168090.s,func_80168090,0x80168090,0x347 +asm/non_matchings/code/z_play/Play_Draw.s,Play_Draw,0x80168090,0x347 asm/non_matchings/code/z_play/func_80168DAC.s,func_80168DAC,0x80168DAC,0x6E asm/non_matchings/code/z_play/Play_Update.s,Play_Update,0x80168F64,0x5A asm/non_matchings/code/z_play/func_801690CC.s,func_801690CC,0x801690CC,0xD From aad8f64c650764ac87fe385413b6dac962a5e1ad Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Tue, 21 Dec 2021 15:57:41 +0000 Subject: [PATCH 24/27] En_Gs (#431) * En_Gs * PR * PR * PR * Update src/overlays/actors/ovl_En_Gs/z_en_gs.h Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: Anghelo Carvajal Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> --- include/functions.h | 9 +- spec | 3 +- src/overlays/actors/ovl_En_Gs/z_en_gs.c | 1055 +++++++++++++++++++++-- src/overlays/actors/ovl_En_Gs/z_en_gs.h | 50 +- 4 files changed, 1062 insertions(+), 55 deletions(-) diff --git a/include/functions.h b/include/functions.h index 4663c59e40..9e4809bb81 100644 --- a/include/functions.h +++ b/include/functions.h @@ -603,7 +603,8 @@ void EffectSsGSpk_SpawnSmall(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, void EffectSsKiraKira_SpawnDispersed(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s32 life); // void EffectSsKiraKira_SpawnFocused(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE2 param_7, UNK_TYPE4 param_8); // void EffectSsBomb2_SpawnFade(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4); -// void EffectSsBomb2_SpawnLayered(UNK_TYPE4 param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); +void EffectSsBomb2_SpawnLayered(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, + s16 scaleStep); // void EffectSsBlast_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, Color_RGBA8* param_5, Color_RGBA8* param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10); // void EffectSsBlast_SpawnWhiteCustomScale(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7); // void EffectSsBlast_SpawnShockwave(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE2 param_7); @@ -875,7 +876,7 @@ s32 func_800BC5EC(GlobalContext* globalCtx, Actor* actor); void func_800BC620(Vec3f* arg0, Vec3f* arg1, u8 arg2, GlobalContext* globalCtx); // void func_800BC770(void); // void func_800BC7D8(void); -// void func_800BC848(void); +void func_800BC848(Actor* actor, GlobalContext* globalCtx, s16 arg2, s16 arg3); // void func_800BC8B8(void); // void func_800BCB50(void); void func_800BCB70(Actor* actor, u16 arg1, u16 arg2, s16 arg3, s16 arg4); @@ -2950,8 +2951,8 @@ void func_80165438(UNK_PTR param_1); // void func_80165460(void); // void func_80165608(void); // void func_80165630(void); -// void func_80165658(void); -void func_8016566C(s32 arg0); +void func_80165658(u32 arg0); +void func_8016566C(u32 arg0); void func_80165690(void); // void func_801656A4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8); // void func_80165DCC(void); diff --git a/spec b/spec index eb3864f26e..7e142f3bba 100644 --- a/spec +++ b/spec @@ -2196,8 +2196,7 @@ beginseg name "ovl_En_Gs" compress include "build/src/overlays/actors/ovl_En_Gs/z_en_gs.o" - include "build/data/ovl_En_Gs/ovl_En_Gs.data.o" - include "build/data/ovl_En_Gs/ovl_En_Gs.reloc.o" + include "build/src/overlays/actors/ovl_En_Gs/ovl_En_Gs_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.c b/src/overlays/actors/ovl_En_Gs/z_en_gs.c index 4b96987f7c..8e50b07947 100644 --- a/src/overlays/actors/ovl_En_Gs/z_en_gs.c +++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.c @@ -15,7 +15,31 @@ void EnGs_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGs_Update(Actor* thisx, GlobalContext* globalCtx); void EnGs_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80997D14(EnGs* this, GlobalContext* globalCtx); +void func_80997D38(EnGs* this, GlobalContext* globalCtx); +void func_80997E4C(EnGs* this, GlobalContext* globalCtx); +void func_80998040(EnGs* this, GlobalContext* globalCtx); +void func_8099807C(EnGs* this, GlobalContext* globalCtx); +void func_80998300(EnGs* this, GlobalContext* globalCtx); +void func_809984F4(EnGs* this, GlobalContext* globalCtx); +void func_809985B8(EnGs* this, GlobalContext* globalCtx); +void func_80998704(EnGs* this, GlobalContext* globalCtx); +void func_8099874C(EnGs* this, GlobalContext* globalCtx); +void func_809989B4(EnGs* this, GlobalContext* globalCtx); +void func_809989F4(EnGs* this, GlobalContext* globalCtx); +s32 func_80998A48(EnGs* this, GlobalContext* globalCtx); +s32 func_80998BBC(EnGs* this, GlobalContext* globalCtx); +s32 func_80998D44(EnGs* this, GlobalContext* globalCtx); +s32 func_80998F9C(EnGs* this, GlobalContext* globalCtx); +s32 func_809995A4(EnGs* this, GlobalContext* globalCtx); +void func_80999A8C(EnGs* this, GlobalContext* globalCtx); +void func_80999AC0(EnGs* this); + +extern Gfx D_0407D590[]; +extern Gfx D_06000950[]; +extern Gfx D_060009D0[]; +extern Gfx D_06000A60[]; + const ActorInit En_Gs_InitVars = { ACTOR_EN_GS, ACTORCAT_PROP, @@ -28,18 +52,29 @@ const ActorInit En_Gs_InitVars = { (ActorFunc)EnGs_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8099A3A0 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 21, 48, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_8099A3CC = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_8099A3D8 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xE), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -74,78 +109,1002 @@ static DamageTable D_8099A3D8 = { /* Powder Keg */ DMG_ENTRY(0, 0xC), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8099A404[] = { +s8 func_80997A90(s16 arg0, s16 arg1) { + s8 phi_v1; + + if ((arg0 == 0) || ((arg0 != 1) && (arg0 != 2) && (arg0 == 3))) { + phi_v1 = 0; + } else { + phi_v1 = (gSaveContext.roomInf[126][1] >> (arg1 * 3)) & 7; + } + return phi_v1; +} + +void func_80997AFC(s32 idx, Color_RGB8* arg1) { + static Color_RGB8 D_8099A3F8[] = { + { 255, 255, 255 }, + { 150, 255, 100 }, + { 255, 80, 40 }, + { 100, 150, 255 }, + }; + + *arg1 = D_8099A3F8[idx]; +} + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void EnGs_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGs* this = THIS; -extern ColliderCylinderInit D_8099A3A0; -extern CollisionCheckInfoInit2 D_8099A3CC; -extern DamageTable D_8099A3D8; -extern InitChainEntry D_8099A404[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk_208 = -1; + this->unk_204 = 1; + this->unk_198 = this->actor.world.rot.z; + this->unk_195 = ENGS_GET_1F(thisx); + this->unk_196 = ENGS_GET_FE0(thisx); + this->actor.params = ENGS_GET_F000(thisx); + this->actor.world.rot.z = 0; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->actor.targetMode = 6; + this->unk_216 = 0; + this->unk_218 = 0; + this->unk_200 = 1.0f; + this->unk_194 = func_80997A90(this->actor.params, this->unk_198); -extern UNK_TYPE D_06000950; + func_80997AFC(this->unk_194, &this->unk_1FA); + this->unk_1F4 = this->unk_1FA; + Math_Vec3f_Copy(&this->unk_1B0[0], &D_801C5DB0); + Math_Vec3f_Copy(&this->unk_1B0[1], &D_801C5DB0); + func_8013E3B8(&this->actor, &this->unk_212, 2); + func_801A5080(0); + if (this->actor.params == ENGS_1) { + Actor_SetScale(&this->actor, 0.15f); + this->collider.dim.radius *= 1.5f; + this->collider.dim.height *= 1.5f; + } + func_80997D14(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997A90.s") +void EnGs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997AFC.s") + Collider_DestroyCylinder(globalCtx, &this->collider); + func_80165690(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Init.s") +void func_80997D14(EnGs* this, GlobalContext* globalCtx) { + this->unk_19A &= ~0x200; + this->actionFunc = func_80997D38; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Destroy.s") +void func_80997D38(EnGs* this, GlobalContext* globalCtx) { + static f32 D_8099A408[] = { 40.0f, 60.0f, 40.0f, 40.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997D14.s") + if (!func_80152498(&globalCtx->msgCtx)) { + if (this->actor.xzDistToPlayer <= D_8099A408[this->actor.params]) { + func_8013E8F8(&this->actor, globalCtx, D_8099A408[this->actor.params], D_8099A408[this->actor.params], 0, + 0x2000, 0x2000); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997D38.s") + if (this->actor.params != ENGS_2) { + func_800B874C(&this->actor, globalCtx, 100.0f, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997DEC.s") +void func_80997DEC(EnGs* this, GlobalContext* globalCtx) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_TRUTH) { + this->unk_210 = 0x20D1; + } else { + this->unk_210 = 0x20D0; + } + this->unk_19A |= 0x200; + this->actionFunc = func_80997E4C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997E4C.s") +void func_80997E4C(EnGs* this, GlobalContext* globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 0: + func_801518B0(globalCtx, this->unk_210, &this->actor); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997FF0.s") + case 1: + case 2: + case 3: + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998040.s") + case 4: + case 5: + case 6: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x20D0: + func_80997D14(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_8099807C.s") + case 0x20D1: + switch (this->actor.params) { + case ENGS_0: + this->unk_210 = this->unk_195 + 0x20D3; + if (this->unk_210 >= 0x20D4) { + s32 temp_v1 = this->unk_210 - 0x20D4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998300.s") + if ((this->unk_210 < 0x20E8) && + ((temp_v1 + ITEM_MASK_TRUTH) == INV_CONTENT(temp_v1 + ITEM_MASK_TRUTH))) { + this->unk_210 = temp_v1 + 0x2103; + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998334.s") + case ENGS_3: + this->unk_210 = this->unk_195 + 0x20B0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809984F4.s") + case ENGS_1: + this->unk_210 = this->unk_195 + 0x20F3; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809985B8.s") + case ENGS_2: + this->unk_210 = this->unk_195 + 0x20F7; + break; + } + func_80151938(globalCtx, this->unk_210); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998704.s") + default: + func_80997D14(this, globalCtx); + break; + } + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_8099874C.s") +void func_80997FF0(EnGs* this, GlobalContext* globalCtx) { + if (func_8013E2D4(&this->actor, globalCtx->unk_1879C[0], -1, 1)) { + func_80998040(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809989B4.s") +void func_80998040(EnGs* this, GlobalContext* globalCtx) { + func_80152434(globalCtx, 1); + this->actionFunc = func_8099807C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809989F4.s") +void func_8099807C(EnGs* this, GlobalContext* globalCtx) { + switch (globalCtx->msgCtx.unk1202A) { + case 3: + switch (globalCtx->msgCtx.unk1202E) { + case 7: + case 8: + if (!Flags_GetSwitch(globalCtx, this->unk_196)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, this->actor.world.pos.x, + this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, 0, 0, 0, 2); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Actor_SetSwitchFlag(globalCtx, this->unk_196); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998A48.s") + case 10: + if (!Flags_GetSwitch(globalCtx, this->unk_196)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, this->actor.world.pos.x, + this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, 0, 0, 0, 7); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Actor_SetSwitchFlag(globalCtx, this->unk_196); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998BBC.s") + case 0: + if ((this->actor.params == ENGS_1) && (gSaveContext.playerForm == PLAYER_FORM_DEKU)) { + this->unk_194 = 1; + this->unk_19C = 5; + this->unk_19A |= 1; + func_80999AC0(this); + func_809984F4(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998D44.s") + case 2: + if ((this->actor.params == ENGS_1) && (gSaveContext.playerForm == PLAYER_FORM_ZORA)) { + this->unk_194 = 3; + this->unk_19C = 5; + this->unk_19A |= 1; + func_80999AC0(this); + func_809984F4(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998F9C.s") + case 1: + if ((this->actor.params == ENGS_1) && (gSaveContext.playerForm == PLAYER_FORM_GORON)) { + this->unk_194 = 2; + this->unk_19C = 5; + this->unk_19A |= 1; + func_80999AC0(this); + func_809984F4(this, globalCtx); + } + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999584.s") + case 0: + case 4: + func_80998300(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809995A4.s") + case 26: + func_80997D14(this, globalCtx); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999A8C.s") +void func_80998300(EnGs* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + ActorCutscene_Stop(globalCtx->unk_1879C[0]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999AC0.s") +f32 func_80998334(EnGs* this, GlobalContext* globalCtx, f32* arg2, f32* arg3, s16* arg4, f32 arg5, f32 arg6, f32 arg7, + s32 arg8, s32 arg9) { + f32 sp2C = Math_SmoothStepToF(arg2, *arg3, arg5, arg6, arg7); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999B34.s") + if (arg9 == 0) { + sp2C = Math_SmoothStepToF(arg2, *arg3, arg5, arg6, arg7); + this->unk_1B0[0].x = (__sinf(DEGF_TO_RADF((*arg4 % arg8) * (1.0f / arg8) * 360.0f)) * *arg2) + 1.0f; + this->unk_1B0[0].y = 1.0f - (__sinf(DEGF_TO_RADF((*arg4 % arg8) * (1.0f / arg8) * 360.0f)) * *arg2); + (*arg4)++; + } + return sp2C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999BC8.s") +void func_809984F4(EnGs* this, GlobalContext* globalCtx) { + EnGs* gossipStone = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Update.s") + do { + gossipStone = (EnGs*)func_ActorCategoryIterateById(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS); + if (gossipStone != NULL) { + if ((this != gossipStone) && (this->unk_194 == gossipStone->unk_194)) { + gossipStone->unk_19A |= 1; + func_80999AC0(gossipStone); + gossipStone->unk_19C = 3; + func_80998704(gossipStone, globalCtx); + } + gossipStone = (EnGs*)gossipStone->actor.next; + } + } while (gossipStone != NULL); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Draw.s") + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = func_809985B8; +} + +void func_809985B8(EnGs* this, GlobalContext* globalCtx) { + EnGs* gossipStone; + Vec3f sp38; + + if (func_8013E2D4(&this->actor, this->unk_212, -1, 0)) { + Player* player = GET_PLAYER(globalCtx); + + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_GetStateTranslationAndScaledZ(160.0f, &sp38); + Math_Vec3f_Sum(&player->actor.world.pos, &sp38, &player->actor.world.pos); + Math_Vec3f_Copy(&player->actor.prevPos, &player->actor.world.pos); + this->unk_200 = 0.0f; + gSaveContext.roomInf[126][1] = + (gSaveContext.roomInf[126][1] & ~(7 << (this->unk_198 * 3))) | ((this->unk_194 & 7) << (this->unk_198 * 3)); + gossipStone = NULL; + + do { + gossipStone = + (EnGs*)func_ActorCategoryIterateById(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS); + if (gossipStone != NULL) { + if ((gossipStone != this) && (gossipStone->actor.params == ENGS_2) && + (gossipStone->unk_198 == this->unk_198)) { + gossipStone->unk_194 = this->unk_194; + gossipStone->unk_200 = 0.0f; + } + gossipStone = (EnGs*)gossipStone->actor.next; + } + } while (gossipStone != NULL); + + func_80998704(this, globalCtx); + } +} + +void func_80998704(EnGs* this, GlobalContext* globalCtx) { + this->unk_19D = 0; + this->unk_19A &= ~(0x100 | 0x4); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_G_STONE_CHANGE_COLOR); + this->actionFunc = func_8099874C; +} + +void func_8099874C(EnGs* this, GlobalContext* globalCtx) { + s32 phi_v0 = 0; + + switch (this->unk_19C) { + case 0: + phi_v0 = func_80998A48(this, globalCtx); + break; + + case 1: + phi_v0 = func_80998BBC(this, globalCtx); + break; + + case 2: + phi_v0 = func_80998D44(this, globalCtx); + break; + + case 3: + case 5: + phi_v0 = func_80998F9C(this, globalCtx); + break; + + case 4: + phi_v0 = func_809995A4(this, globalCtx); + break; + } + + if (phi_v0 == 0) { + this->unk_216 = 0; + if ((this->unk_19C == 5) && (this->unk_194 != 0)) { + s32 i; + + ActorCutscene_Stop(this->unk_212); + phi_v0 = 1; + + for (i = 0; i < 4; i++) { + if (((gSaveContext.roomInf[126][1] >> (i * 3)) & 7) != (u32)this->unk_194) { + phi_v0 = 0; + } + } + + if (phi_v0 != 0) { + this->unk_20C = -1; + switch (this->unk_194) { + case 1: + if (!(gSaveContext.weekEventReg[77] & 8)) { + this->unk_20C = 6; + gSaveContext.weekEventReg[77] |= 8; + } + break; + + case 3: + if (!(gSaveContext.weekEventReg[77] & 0x10)) { + this->unk_20C = 6; + gSaveContext.weekEventReg[77] |= 0x10; + } + break; + + case 2: + if (!(gSaveContext.weekEventReg[77] & 0x20)) { + this->unk_20C = 6; + gSaveContext.weekEventReg[77] |= 0x20; + } + break; + } + + if (!(gSaveContext.weekEventReg[90] & 0x10)) { + gSaveContext.weekEventReg[90] |= 0x10; + this->unk_20C = 12; + } + + if (this->unk_20C > 0) { + func_809989B4(this, globalCtx); + } else { + func_80997D14(this, globalCtx); + } + } else { + func_80997D14(this, globalCtx); + } + } else { + func_80997D14(this, globalCtx); + } + } +} + +void func_809989B4(EnGs* this, GlobalContext* globalCtx) { + func_800B8A1C(&this->actor, globalCtx, this->unk_20C, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809989F4; +} + +void func_809989F4(EnGs* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + func_80997D14(this, globalCtx); + } else { + func_800B8A1C(&this->actor, globalCtx, this->unk_20C, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +s32 func_80998A48(EnGs* this, GlobalContext* globalCtx) { + s32 sp3C = -1; + + if (this->unk_19D == 0) { + this->unk_216 = 200; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + + this->unk_1D4 = 0; + this->unk_19A |= 1; + this->unk_21C = 5; + this->unk_21E = 40; + this->unk_197++; + this->unk_197 &= 0xF; + this->unk_19D = 1; + + this->unk_1DC = 0.5f; + this->unk_1E0 = 0.0f; + } else if (this->unk_19D == 1) { + if (func_80998334(this, globalCtx, &this->unk_1DC, &this->unk_1E0, &this->unk_1D4, 0.8f, 0.007f, 0.001f, 7, + 0) == 0.0f) { + if ((this->actor.params != ENGS_0) && !func_801690CC(globalCtx) && !func_80152498(&globalCtx->msgCtx)) { + this->unk_216 = 0; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIVE_LUPY_COUNT); + func_801518B0(globalCtx, 0x20D2, NULL); + } + this->unk_19A &= ~1; + sp3C = 0; + } + } + return sp3C; +} + +s32 func_80998BBC(EnGs* this, GlobalContext* globalCtx) { + s32 sp34 = -1; + + if (this->unk_19D == 0) { + this->unk_216 = 200; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + this->unk_1DC = 0.3f; + this->unk_1E0 = 0.0f; + + this->unk_1D4 = 0; + this->unk_19A |= 1; + this->unk_21C = 5; + this->unk_21E = 40; + this->unk_197--; + this->unk_197 &= 0xF; + this->unk_19D = 1; + } else if (this->unk_19D == 1) { + this->unk_19E[0].z = (this->unk_1D4 % 8) * 0.125f * 360.0f * (0x10000 / 360.0f); + this->unk_19E[1].z = -this->unk_19E[0].z; + if (func_80998334(this, globalCtx, &this->unk_1DC, &this->unk_1E0, &this->unk_1D4, 0.8f, 0.005f, 0.001f, 7, + 0) == 0.0f) { + this->unk_19A &= ~1; + sp34 = 0; + } + } + return sp34; +} + +s32 func_80998D44(EnGs* this, GlobalContext* globalCtx) { + s32 sp3C = -1; + f32 step; + + if (this->unk_19D == 0) { + this->unk_216 = 200; + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = -0.8f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_G_STONE_CRUSH); + this->unk_19A |= 1; + this->unk_21C = 40; + this->unk_21E = 11; + this->unk_19D++; + } else if (this->unk_19D == 1) { + step = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 1.0f, 0.4f, 0.001f); + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + if (step == 0.0f) { + this->unk_216 = 0; + this->unk_1D4 = 0; + this->unk_19D++; + } + } else if (this->unk_19D == 2) { + this->unk_1D4++; + if (this->unk_1D4 >= 100) { + this->unk_216 = 200; + this->unk_19D++; + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = 0.0f; + } + } else if (this->unk_19D == 3) { + step = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 1.0f, 0.5f, 0.001f); + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + if (step == 0.0f) { + this->unk_216 = 0; + this->unk_1E0 = 0.0f; + this->unk_1D4 = 0; + this->unk_21C = 10; + this->unk_21E = 10; + this->unk_1DC = 0.5f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + this->unk_19D += 1; + } + } else if ((this->unk_19D == 4) && (func_80998334(this, globalCtx, &this->unk_1DC, &this->unk_1E0, &this->unk_1D4, + 1.0f, 0.03f, 0.001f, 5, 0) == 0.0f)) { + this->unk_19A &= ~1; + sp3C = 0; + } + return sp3C; +} + +s32 func_80998F9C(EnGs* this, GlobalContext* globalCtx) { + s32 sp4C = -1; + f32 sp48; + f32 sp44; + f32 sp40; + s32 phi_v0_2; + u16 sp3A = this->unk_19E[0].y; + + if (this->unk_19D == 0) { + this->unk_1DC = 0; + this->unk_1E0 = 90.0f; + this->unk_1E4 = 0.1f; + this->unk_1E8 = 2.0f; + this->unk_1EC = 0.0f; + + this->unk_19D = 1; + this->unk_21C = 2; + this->unk_21E = 40; + this->unk_216 = 200; + } + + if (this->unk_19D == 1) { + Math_SmoothStepToF(&this->unk_1E4, this->unk_1E8, 1.0f, 0.1f, 0.001f); + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 1.0f, this->unk_1E4, 0.001f); + this->unk_19E[0].y += (s32)(this->unk_1DC * (0x10000 / 360.0f)); + if (sp48 == 0.0f) { + this->unk_1D4 = 0; + this->unk_19D = 2; + } + } + + if (this->unk_19D == 2) { + this->unk_19E[0].y += (s32)(this->unk_1DC * (0x10000 / 360.0f)); + if ((this->unk_1D4++ <= 40) ^ 1) { + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = 1.5f; + this->unk_1E4 = this->unk_1B0[1].y - 1.0f; + this->unk_1E8 = -0.3f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_STONE_GROW_UP); + this->unk_19D = 3; + } + } + + if (this->unk_19D == 3) { + this->unk_19E[0].y += 0x4000; + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 0.2f, 0.001f); + Math_SmoothStepToF(&this->unk_1E4, this->unk_1E8, 0.8f, 0.2f, 0.001f); + this->unk_1B0[0].x = this->unk_1E4 + 1.0f; + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + if (sp48 == 0.0f) { + this->unk_1DC = 2.0f * M_PI / 9.0000002; + this->unk_1E0 = M_PI / 9.0000002; + this->unk_19D = 4; + } + } + + if (this->unk_19D == 4) { + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 16384.0f, 3640.0f); + this->unk_19E[0].y += (s16)this->unk_1DC; + if (sp48 == 0.0f) { + phi_v0_2 = this->unk_19E[0].y; + if (phi_v0_2 > 0) { + phi_v0_2 += 0xFFFF0000; + } + this->unk_1DC = phi_v0_2; + this->unk_1E0 = 0; + this->unk_19D = 5; + } + } + + if (this->unk_19D == 5) { + phi_v0_2 = this->unk_19E[0].y; + if (phi_v0_2 > 0) { + phi_v0_2 += 0xFFFF0001; + } + this->unk_1DC = phi_v0_2; + + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 3640.0f, 0.001f); + this->unk_19E[0].y = (s32)this->unk_1DC; + if (sp48 == 0.0f) { + this->unk_19E[0].y = 0; + this->unk_1D4 = 0; + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = 0.0f; + this->unk_1E4 = this->unk_1B0[0].x - 1.0f; + this->unk_1E8 = 0.0f; + this->unk_1F0 = 0.0f; + this->unk_1EC = 0.5f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + this->unk_21C = 20; + this->unk_21E = 2; + this->unk_19D = 6; + } + } + + if (this->unk_19D == 6) { + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 0.1f, 0.001f); + sp44 = Math_SmoothStepToF(&this->unk_1E4, this->unk_1E8, 0.8f, 0.1f, 0.001f); + sp40 = Math_SmoothStepToF(&this->unk_1EC, this->unk_1F0, 0.8f, 0.02f, 0.001f); + this->unk_1B0[0].x = this->unk_1E4 + 1.0f; + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + this->unk_1B0[0].x += __sinf(DEGF_TO_RADF((this->unk_1D4 % 10) * 0.1f * 360.0f)) * this->unk_1EC; + this->unk_1B0[0].y += __sinf(DEGF_TO_RADF((this->unk_1D4 % 10) * 0.1f * 360.0f)) * this->unk_1EC; + this->unk_1D4++; + if ((sp48 == 0.0f) && (sp44 == 0.0f) && (sp40 == 0.0f)) { + this->unk_216 = 0; + sp4C = 0; + } + } + + if ((u16)this->unk_19E[0].y < sp3A) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_STONE_ROLLING); + } + + return sp4C; +} + +void func_80999584(Color_RGB8* arg0, Color_RGB8* arg1) { + arg0->r = arg1->r; + arg0->g = arg1->g; + arg0->b = arg1->b; +} + +s32 func_809995A4(EnGs* this, GlobalContext* globalCtx) { + static Color_RGB8 flashColours[] = { + { 255, 50, 50 }, + { 50, 50, 255 }, + { 255, 255, 255 }, + }; + static Vec3f dustAccel = { 0.0f, -0.3f, 0.0f }; + static Color_RGBA8 dustPrim = { 200, 200, 200, 128 }; + static Color_RGBA8 dustEnv = { 100, 100, 100, 0 }; + static Vec3f bomb2Velocity = { 0.0f, 0.0f, 0.0f }; + static Vec3f bomb2Accel = { 0.0f, 0.0f, 0.0f }; + s32 sp7C = -1; + + if (this->unk_19D == 0) { + this->unk_19A |= 0x100; + this->unk_1D4 = 40; + this->unk_19D++; + } + + if (this->unk_19D == 1) { + if (this->unk_1D4-- == 0) { + this->unk_1D4 = 80; + this->unk_19A |= 4; + this->unk_19D++; + } + } + + if (this->unk_19D == 2) { + u8 pad; + + this->unk_1D4--; + func_80999584(&this->unk_1FA, &flashColours[2]); + if (this->unk_1D4 < 80) { + if ((this->unk_1D4 % 20) < 8) { + if (this->unk_1D4 < 20) { + if ((this->unk_1D4 % 20) == 7) { + func_80999584(&this->unk_1FA, &flashColours[0]); + this->unk_1F4 = this->unk_1FA; + play_sound(NA_SE_SY_WARNING_COUNT_E); + this->unk_200 = 0.0f; + } + } else if ((this->unk_1D4 % 20) == 7) { + func_80999584(&this->unk_1FA, &flashColours[1]); + this->unk_1F4 = this->unk_1FA; + play_sound(NA_SE_SY_WARNING_COUNT_N); + this->unk_200 = 0.0f; + } + } + } + + if (this->unk_1D4 <= 0) { + this->unk_19A &= ~4; + this->unk_21C = 3; + this->unk_21E = 40; + this->unk_1D4 = 0; + this->unk_19D++; + } + } + + if (this->unk_19D == 3) { + u8 i; + Vec3f sp6C; + Vec3f sp60; + + for (i = 0; i < 3; i++) { + sp60.x = randPlusMinusPoint5Scaled(15.0f); + sp60.y = Rand_ZeroFloat(-1.0f); + sp60.z = randPlusMinusPoint5Scaled(15.0f); + + sp6C.x = this->actor.world.pos.x + (2.0f * sp60.x); + sp6C.y = this->actor.world.pos.y + 7.0f; + sp6C.z = this->actor.world.pos.z + (2.0f * sp60.z); + + func_800B0EB0(globalCtx, &sp6C, &sp60, &dustAccel, &dustPrim, &dustEnv, Rand_ZeroFloat(50.0f) + 200.0f, 40, + 15); + } + + func_800B9010(&this->actor, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); + + if ((this->unk_1D4++ < 40) ^ 1) { + this->unk_19A |= 0x10; + + this->actor.uncullZoneForward = 12000.0f; + this->actor.gravity = 0.3f; + this->unk_1DC = 0.0f; + + this->unk_19D++; + this->unk_21C = 5; + this->unk_21E = 20; + this->unk_19A |= 1; + this->unk_216 = 200; + this->unk_1E0 = (this->unk_197 >> 2) * 0x444; + } + } + + if (this->unk_19D == 4) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 3); + if (this->actor.bgCheckFlags & (0x10 | 0x8)) { + Vec3f sp54; + + sp54.x = this->actor.world.pos.x; + sp54.y = this->actor.world.pos.y; + sp54.z = this->actor.world.pos.z; + Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + EffectSsBomb2_SpawnLayered(globalCtx, &sp54, &bomb2Velocity, &bomb2Accel, 100, 20); + this->unk_1D4 = 10; + this->unk_19A |= 8; + this->unk_216 = 0; + this->actionFunc = func_80999A8C; + } else { + func_800B9010(&this->actor, NA_SE_EV_STONE_LAUNCH - SFX_FLAG); + } + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.5f, 364.0f, 0.0f); + + this->unk_19E[1].y += (s16)this->unk_1DC; + + if ((this->actor.world.pos.y - this->actor.home.pos.y) >= 4000.0f) { + this->unk_216 = 0; + } + + if (this->actor.playerHeightRel < -12000.0f) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, 0); + Actor_MarkForDeath(&this->actor); + sp7C = 0; + } + } + + return sp7C; +} + +void func_80999A8C(EnGs* this, GlobalContext* globalCtx) { + if (this->unk_1D4-- <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80999AC0(EnGs* this) { + static Vec3s D_8099A450 = { 0, 0, 0 }; + static Vec3f D_8099A458 = { 1.0f, 1.0f, 1.0f }; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_19E); i++) { + this->unk_19E[i] = D_8099A450; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_1B0); i++) { + this->unk_1B0[i] = D_8099A458; + } +} + +void func_80999B34(EnGs* this) { + if (this->unk_216 > 0) { + if (this->unk_218 == 0) { + func_8016566C(this->unk_216); + this->unk_218 = this->unk_216; + } else { + func_80165658(this->unk_218); + } + } else if (this->unk_218 > 0) { + Math_StepToS(&this->unk_218, this->unk_216, 20); + func_80165658(this->unk_218); + if (this->unk_218 <= 0) { + func_80165690(); + } + } +} + +void func_80999BC8(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnGs* this = THIS; + s32 pad; + + if (this->actor.isTargeted && !func_801A5100()) { + this->unk_19D = 0; + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 0; + func_80998704(this, globalCtx); + this->unk_208 = 0; + } + + if (this->actor.params == ENGS_1) { + Actor_SetHeight(&this->actor, 34.5f); + } else { + Actor_SetHeight(&this->actor, 23.0f); + } + + if (this->unk_21A > 0) { + this->unk_21A--; + if (this->unk_21A <= 0) { + this->unk_21A = 0; + } + } + + if (!(this->unk_19A & (0x200 | 0x10)) && (this->unk_21A == 0)) { + if (this->collider.base.acFlags & AC_HIT) { + this->unk_19D = 0; + this->collider.base.acFlags &= ~AC_HIT; + + switch (this->actor.colChkInfo.damageEffect) { + case 15: + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 0; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 14: + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 1; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 13: + func_80999AC0(this); + this->unk_19C = 2; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 12: + this->unk_19A |= 2; + func_80999AC0(this); + this->unk_19C = 4; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 11: + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 3; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.acFlags &= ~AC_HIT; + } + + this->actionFunc(this, globalCtx); +} + +void EnGs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGs* this = THIS; + + if (func_800B84D0(&this->actor, globalCtx)) { + globalCtx->msgCtx.unk11F22 = 0; + globalCtx->msgCtx.unk11F10 = 0; + this->collider.base.acFlags &= ~AC_HIT; + func_80997DEC(this, globalCtx); + } else if (func_800B8718(&this->actor, globalCtx)) { + this->unk_19A |= 0x200; + this->collider.base.acFlags &= ~AC_HIT; + if (this->actor.cutscene != -1) { + this->actionFunc = func_80997FF0; + } else { + func_80998040(this, globalCtx); + } + } else { + s16 sp2E; + s16 sp2C; + + if ((this->actor.flags & 0x40) || (this->unk_19A & 0x100) || (this->unk_19A & 0x200)) { + func_80999BC8(&this->actor, globalCtx); + func_800B8898(globalCtx, &this->actor, &sp2E, &sp2C); + if ((this->actor.xyzDistToPlayerSq > SQ(400.0f)) || (sp2E < 0) || (sp2E > 320) || (sp2C < 0) || + (sp2C > 240)) { + this->unk_216 = 0; + } else if (this->unk_21C > 0) { + func_800BC848(&this->actor, globalCtx, this->unk_21C, this->unk_21E); + } + } else { + this->unk_216 = 0; + } + + if (this->unk_200 < 1.0f) { + if (this->unk_19A & 4) { + Math_StepToF(&this->unk_200, 1.0f, 0.06f); + } else { + Math_StepToF(&this->unk_200, 1.0f, 0.02f); + } + func_80997AFC(this->unk_194, &this->unk_1F7); + Lib_LerpRGB(&this->unk_1F4, &this->unk_1F7, this->unk_200, &this->unk_1FA); + if (this->unk_200 >= 1.0f) { + this->unk_1F4 = this->unk_1FA; + } + } + + if (this->unk_21C > 0) { + this->unk_21C = 0; + } + + func_80999B34(this); + } +} + +void EnGs_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGs* this = THIS; + u32 frames; + + if (this->unk_19A & 8) { + return; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + frames = globalCtx->gameplayFrames; + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_StatePush(); + + if (this->unk_19A & 1) { + Matrix_RotateY(this->unk_19E[0].y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_19E[0].x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_19E[0].z, MTXMODE_APPLY); + Matrix_Scale(this->unk_1B0[0].x, this->unk_1B0[0].y, this->unk_1B0[0].z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_19E[1].y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_19E[1].x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_19E[1].z, MTXMODE_APPLY); + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06000950); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_1FA.r, this->unk_1FA.g, this->unk_1FA.b, 255); + gSPDisplayList(POLY_OPA_DISP++, D_060009D0); + gSPDisplayList(POLY_OPA_DISP++, D_06000A60); + + Matrix_StatePop(); + + if (this->unk_19A & 2) { + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(0.05f, -0.05f, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, -frames * 20, 0x20, 0x80)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.h b/src/overlays/actors/ovl_En_Gs/z_en_gs.h index 7b01d2c0a2..8b10cb68dc 100644 --- a/src/overlays/actors/ovl_En_Gs/z_en_gs.h +++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.h @@ -5,9 +5,57 @@ struct EnGs; +typedef void (*EnGsActionFunc)(struct EnGs*, GlobalContext*); + +#define ENGS_GET_1F(thisx) ((thisx)->params & 0x1F) +#define ENGS_GET_FE0(thisx) (((thisx)->params >> 5) & 0x7F) +#define ENGS_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF) + +enum { + /* 0 */ ENGS_0, + /* 1 */ ENGS_1, + /* 2 */ ENGS_2, + /* 3 */ ENGS_3, +}; + typedef struct EnGs { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xDC]; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ EnGsActionFunc actionFunc; + /* 0x194 */ s8 unk_194; + /* 0x195 */ u8 unk_195; + /* 0x196 */ u8 unk_196; + /* 0x197 */ s8 unk_197; + /* 0x198 */ s16 unk_198; + /* 0x19A */ s16 unk_19A; + /* 0x19C */ s8 unk_19C; + /* 0x19D */ u8 unk_19D; + /* 0x19E */ Vec3s unk_19E[3]; + /* 0x1B0 */ Vec3f unk_1B0[2]; + /* 0x1C8 */ UNK_TYPE1 unk1C8[0xC]; + /* 0x1D4 */ s16 unk_1D4; + /* 0x1D6 */ UNK_TYPE1 unk1D6[0x6]; + /* 0x1DC */ f32 unk_1DC; + /* 0x1E0 */ f32 unk_1E0; + /* 0x1E4 */ f32 unk_1E4; + /* 0x1E8 */ f32 unk_1E8; + /* 0x1EC */ f32 unk_1EC; + /* 0x1F0 */ f32 unk_1F0; + /* 0x1F4 */ Color_RGB8 unk_1F4; + /* 0x1F7 */ Color_RGB8 unk_1F7; + /* 0x1FA */ Color_RGB8 unk_1FA; + /* 0x200 */ f32 unk_200; + /* 0x204 */ s32 unk_204; + /* 0x208 */ s32 unk_208; + /* 0x20C */ s32 unk_20C; + /* 0x210 */ u16 unk_210; + /* 0x212 */ s16 unk_212; + /* 0x214 */ UNK_TYPE1 unk214[2]; + /* 0x216 */ s16 unk_216; + /* 0x218 */ s16 unk_218; + /* 0x21A */ s16 unk_21A; + /* 0x21C */ s16 unk_21C; + /* 0x21E */ s16 unk_21E; } EnGs; // size = 0x220 extern const ActorInit En_Gs_InitVars; From a3478c4056dfeb73a7f777b26c73b9e16771b5d9 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Wed, 22 Dec 2021 16:25:00 +0000 Subject: [PATCH 25/27] En_Tru (1 non-matching) (#325) * En_Tru * Fixups * PR * The meme * I rebased by accident sorry * Add object memes * Type --- assets/xml/objects/object_tru.xml | 4 +- assets/xml/overlays/ovl_En_Tru.xml | 24 + include/functions.h | 6 +- spec | 7 +- src/overlays/actors/ovl_En_Tru/z_en_tru.c | 1233 ++++++++++++++++++++- src/overlays/actors/ovl_En_Tru/z_en_tru.h | 47 +- tools/disasm/functions.txt | 4 +- tools/disasm/variables.txt | 3 +- undefined_syms.txt | 16 + 9 files changed, 1285 insertions(+), 59 deletions(-) create mode 100644 assets/xml/overlays/ovl_En_Tru.xml diff --git a/assets/xml/objects/object_tru.xml b/assets/xml/objects/object_tru.xml index 34bc82f39b..0ca1acff45 100644 --- a/assets/xml/objects/object_tru.xml +++ b/assets/xml/objects/object_tru.xml @@ -70,7 +70,9 @@ - + + + diff --git a/assets/xml/overlays/ovl_En_Tru.xml b/assets/xml/overlays/ovl_En_Tru.xml new file mode 100644 index 0000000000..e242db4c34 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Tru.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/functions.h b/include/functions.h index 9e4809bb81..1b0ee74c73 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2162,7 +2162,7 @@ s32 func_80123590(GlobalContext* globalCtx, Actor* actor); s32 func_80123810(GlobalContext* globalCtx); // void func_80123960(void); // void func_801239AC(void); -// void func_80123AA4(void); +void func_80123AA4(Player* player, s32 arg1); // void func_80123BD4(void); // void func_80123C58(void); // void func_80123C90(void); @@ -3012,7 +3012,7 @@ s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); // void func_8016A0AC(void); s32 func_8016A168(void); // void func_8016A178(void); -// void func_8016A268(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6); +void func_8016A268(GlobalContext* globalCtx, s32 param_2, s32 param_3, s32 param_4, s32 param_5, s32 param_6); void Play_Init(GameState* gameState); // void func_8016AC10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); // void func_8016AE1C(void); @@ -3963,7 +3963,7 @@ void func_801A5CFC(u16 sfxId, Vec3f* param_2, u8 param_3, f32* param_4, f32* par void func_801A72CC(Vec3f* uParm1); void func_801A7328(Vec3f* pos, u16 sfxId); // void func_801A7484(void); -// void func_801A75E8(void); +void func_801A75E8(u16 sfxId); // void func_801A7720(void); void func_801A7794(u32 param_1, u32 param_2, u32 param_3); // void func_801A7828(void); diff --git a/spec b/spec index 7e142f3bba..3cbed2222b 100644 --- a/spec +++ b/spec @@ -3215,8 +3215,11 @@ beginseg name "ovl_En_Tru" compress include "build/src/overlays/actors/ovl_En_Tru/z_en_tru.o" - include "build/data/ovl_En_Tru/ovl_En_Tru.data.o" - include "build/data/ovl_En_Tru/ovl_En_Tru.reloc.o" + #ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Tru/ovl_En_Tru_reloc.o" + #else + include "build/data/ovl_En_Tru/ovl_En_Tru.reloc.o" + #endif endseg beginseg diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.c b/src/overlays/actors/ovl_En_Tru/z_en_tru.c index 240a4f2363..4874ac2496 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c @@ -5,6 +5,7 @@ */ #include "z_en_tru.h" +#include "objects/object_tru/object_tru.h" #define FLAGS 0x00000039 @@ -15,10 +16,46 @@ void EnTru_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTru_Update(Actor* thisx, GlobalContext* globalCtx); void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A875AC(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A8777C(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A87880(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A87DC0(Actor* thisx, GlobalContext* globalCtx); void func_80A87FD0(EnTru* this, GlobalContext* globalCtx); void func_80A881E0(EnTru* this, GlobalContext* globalCtx); -#if 0 +static UNK_TYPE D_80A88910[] = { + 0x0E08520C, + 0x16100000, +}; + +static UNK_TYPE D_80A88918[] = { + 0x0900000E, + 0x08630C12, + 0x16100000, +}; + +static UNK_TYPE D_80A88924[] = { + 0x0E08660C, + 0x10000000, +}; + +static UNK_TYPE D_80A8892C[] = { + 0x09000004, 0x00050E08, 0x650C1000, 0x1010000B, 0x0E08530C, 0x0F08540C, 0x1900040E, 0x08560C11, + 0x10100E00, 0xFF2B0000, 0x001E0027, 0x2C08640C, 0x2F00000C, 0x15090000, 0x0E08570C, 0x15090000, + 0x0E08580C, 0x15090000, 0x12102C08, 0x550C2F00, 0x000C100E, 0x08550C10, +}; + +static UNK_TYPE D_80A88984[] = { + 0x2CFFFF09, 0x00000E08, 0x640C1509, 0x00000E08, 0x570C1509, 0x00000E08, 0x580C1509, 0x00001210, +}; + +static UNK_TYPE D_80A889A4[] = { + 0x2CFFFF09, + 0x00000E08, + 0x550C1000, +}; + const ActorInit En_Tru_InitVars = { ACTOR_EN_TRU, ACTORCAT_NPC, @@ -31,91 +68,1193 @@ const ActorInit En_Tru_InitVars = { (ActorFunc)EnTru_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80A8B2A0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +#include "overlays/ovl_En_Tru/ovl_En_Tru.c" + +static Vec3f D_80A8B250 = { 0.0f, 0.02f, 0.0f }; + +static Color_RGBA8 D_80A8B25C[] = { + { 255, 20, 60, 0 }, { 255, 235, 160, 0 }, { 20, 60, 255, 0 }, + { 100, 100, 100, 0 }, { 255, 255, 200, 0 }, { 100, 100, 100, 0 }, +}; + +static f32 D_80A8B274[] = { 60.0f, 255.0f, 60.0f }; + +static UNK_TYPE D_80A8B280[] = { + &D_0408F7E0, &D_0408F3E0, &D_0408EFE0, &D_0408EBE0, &D_0408E7E0, &D_0408E3E0, &D_0408DFE0, &D_0408DBE0, +}; + +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 32 }, 100 }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80A8B2CC = { 1, 20, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 20, 0, 0, MASS_IMMOVABLE }; +static ActorAnimationEntryS D_80A8B2D8[] = { + { &object_tru_Anim_00F9A0, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_00F9A0, 1.0f, 0, -1, 0, -4 }, + { &object_tru_Anim_0108AC, 1.0f, 0, -1, 2, -4 }, { &object_tru_Anim_009348, 1.0f, 0, -1, 2, 0 }, + { &object_tru_Anim_00EEDC, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_015CA0, 1.0f, 0, -1, 0, 0 }, + { &object_tru_Anim_015CA0, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_014728, 1.0f, 0, -1, 2, 0 }, + { &object_tru_Anim_01B5C4, 1.0f, 0, -1, 2, 0 }, { &object_tru_Anim_007FA0, 1.0f, 0, -1, 2, -4 }, + { &object_tru_Anim_016B4C, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_011F88, 1.0f, 0, -1, 2, -4 }, + { &object_tru_Anim_00446C, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_003698, 1.0f, 0, -1, 2, -4 }, + { &object_tru_Anim_002BD8, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_00446C, 1.0f, 0, -1, 0, 0 }, +}; + +static Vec3f D_80A8B3D8 = { 0.0f, 24.0f, 16.0f }; +static Vec3f D_80A8B3E4 = { 0.0f, -3.0f, 3.0f }; +static Vec3f D_80A8B3F0 = { 0.0f, 0.5f, 0.0f }; +static Vec3f D_80A8B3FC = { 3000.0f, -800.0f, 0.0f }; + +void func_80A85620(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { + s16 i; + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 0) { + arg0->unk_02 = Rand_ZeroFloat(20.0f) + arg4; + arg0->unk_01 = arg0->unk_02; + arg0->unk_00 = 1; + arg0->unk_04 = *arg1; + arg0->unk_1C = D_801D15B0; + arg0->unk_10 = D_80A8B250; + arg0->unk_28 = arg2; + arg0->unk_2C = arg3; + break; + } + } +} + +void func_80A85788(EnTruUnkStruct* arg0, GlobalContext* globalCtx) { + s32 i; + s32 flag = false; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 1) { + f32 alpha; + + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, D_80A89000); + flag = true; + } + + do { + alpha = (f32)arg0->unk_02 / arg0->unk_01; + alpha *= 255.0f; + } while (0); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 128); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)alpha); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -arg0->unk_02 * 5, 32, 64, 1, 0, 0, 32, 32)); + + Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 14.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_80A890A8); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A85AA4(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { + s16 i; + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 0) { + arg0->unk_02 = arg4; + arg0->unk_01 = arg0->unk_02; + arg0->unk_00 = 2; + arg0->unk_04 = *arg1; + arg0->unk_1C = D_801D15B0; + arg0->unk_10 = D_801D15B0; + arg0->unk_28 = arg2; + arg0->unk_2C = arg3; + break; + } + } +} + +void func_80A85BCC(EnTruUnkStruct* arg0, GlobalContext* globalCtx) { + s32 i; + s32 flag = false; + + OPEN_DISPS(globalCtx->state.gfxCtx); + if (globalCtx) {} + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 2) { + f32 alpha; + + if (!flag) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 200, 0); + flag = true; + } + + do { + alpha = (f32)arg0->unk_02 / arg0->unk_01; + alpha *= 255.0f; + } while (0); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)alpha); + + Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_80A8A108); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A85E2C(EnTruUnkStruct* arg0, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, f32 arg5, f32 arg6, u8 arg7) { + s32 i; + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 0) { + arg0->unk_02 = Rand_ZeroFloat(4.0f) + arg6; + arg0->unk_01 = arg0->unk_02; + arg0->unk_00 = arg7; + arg0->unk_04 = *arg1; + arg0->unk_1C = *arg3; + arg0->unk_10 = *arg2; + arg0->unk_28 = arg4; + arg0->unk_2C = arg5; + break; + } + } +} + +#ifdef NON_MATCHING +// s8/s6 flipped, same deal as above functions but the same fixes don't work +void func_80A85F84(EnTruUnkStruct* arg0, GlobalContext* globalCtx) { + u8 flag = false; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 30; i++, arg0++) { + f32 alpha; + s32 idx; + + if ((arg0->unk_00 == 3) || (arg0->unk_00 == 4) || (arg0->unk_00 == 5)) { + if (!flag) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, sizeof(Gfx) * 0); + gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_01A820); + flag = true; + } + + Matrix_StatePush(); + + do { + alpha = (f32)arg0->unk_02 / arg0->unk_01; + alpha *= D_80A8B274[arg0->unk_00 - 3]; + } while (0); + + gDPSetCombineLERP(POLY_XLU_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, 0, TEXEL0, 0, + COMBINED, 0, SHADE, 0, 0, 0, 0, COMBINED); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80A8B25C[arg0->unk_00 - 3].r, D_80A8B25C[arg0->unk_00 - 3].g, + D_80A8B25C[arg0->unk_00 - 3].b, (u8)alpha); + gDPSetEnvColor(POLY_XLU_DISP++, D_80A8B25C[arg0->unk_00 - 3].r, D_80A8B25C[arg0->unk_00 - 3].g, + D_80A8B25C[arg0->unk_00 - 3].b, 0); + + Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + idx = ((f32)arg0->unk_02 / arg0->unk_01) * 8.0f; + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B280[idx])); + gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_01A830); + + Matrix_StatePop(); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85F84.s") #endif -extern ColliderSphereInit D_80A8B2A0; -extern CollisionCheckInfoInit2 D_80A8B2CC; +s32 func_80A86384(EnTruUnkStruct* arg0, Vec3f* arg1) { + s32 i; -extern UNK_TYPE D_060020C8; -extern UNK_TYPE D_0601A830; -extern UNK_TYPE D_0601AA60; + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_02 != 0) { + if (arg0->unk_00 == 2) { + arg0->unk_04 = *arg1; + } else { + arg0->unk_04.x += arg0->unk_1C.x; + arg0->unk_04.y += arg0->unk_1C.y; + arg0->unk_04.z += arg0->unk_1C.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85620.s") + arg0->unk_1C.x += arg0->unk_10.x; + arg0->unk_1C.y += arg0->unk_10.y; + arg0->unk_1C.z += arg0->unk_10.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85788.s") + arg0->unk_02--; + arg0->unk_28 += arg0->unk_2C; + } else { + arg0->unk_00 = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85AA4.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85BCC.s") +s32 func_80A86460(EnTru* this) { + s32 i; + Vec3f spB0; + Vec3f spA4; + Vec3f sp98; + Vec3f sp8C; + f32 temp_f6; + s16 phi_s1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85E2C.s") + Math_Vec3f_Copy(&spB0, &D_801D15B0); + Math_Vec3f_Copy(&sp8C, &D_801D15B0); + Math_Vec3f_Copy(&spA4, &D_801D15B0); + Math_Vec3f_Copy(&sp98, &D_801D15B0); + phi_s1 = (Rand_ZeroOne() * 360.0f) * 182.0f; + spB0.z = 20.0f; + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &spB0, &sp8C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85F84.s") + for (i = 0; i < 8; i++, phi_s1 += 0x1FFE) { + Math_Vec3f_Copy(&spB0, &D_801D15B0); + spB0.y = 1.0f; + spB0.z = Rand_ZeroOne() + 3.0f; + Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, phi_s1, &spB0, &sp98); + Math_Vec3f_Copy(&spB0, &D_801D15B0); + spB0.z = (Rand_ZeroOne() * 4.0f) + 12.0f; + Lib_Vec3f_TranslateAndRotateY(&sp8C, phi_s1, &spB0, &spA4); + func_80A85E2C(this->unk_394, &spA4, &D_801D15B0, &sp98, 0.4f, 0.06f, 12.0f, 4); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86384.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86460.s") +s32 func_80A86674(EnTru* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86674.s") + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &D_80A8B3D8, &sp40); + Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, this->actor.world.rot.y, &D_80A8B3E4, &sp34); + if (this->unk_390 == 1) { + func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 3); + } else if (this->unk_390 == 2) { + func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 5); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86770.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A868F8.s") +s32 func_80A86770(EnTru* this) { + s32 pad; + Vec3f sp98; + Vec3f sp8C; + s32 i; + s16 phi_s0 = Rand_ZeroOne() * 360.0f * 182.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86924.s") + for (i = 0; i < 4; i++, phi_s0 += 0x3FFC) { + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, phi_s0, &D_801D15B0, &sp98); + sp98.y = this->actor.floorHeight + 1.0f; + sp8C.x = Rand_ZeroOne() - 0.5f; + sp8C.z = Rand_ZeroOne() - 0.5f; + sp8C.y = Rand_ZeroOne() * 0.2f; + func_80A85E2C(this->unk_394, &sp98, &sp8C, &D_801D15B0, 1.0f, 0.04f, 28.0f, 4); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A8697C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A869DC.s") +void func_80A868F8(EnTru* this) { + this->skelAnime.playSpeed = this->unk_358; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86B0C.s") +s32 func_80A86924(EnTru* this, s32 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86BAC.s") + if (arg1 != this->unk_37C) { + this->unk_37C = arg1; + ret = func_8013BC6C(&this->skelAnime, D_80A8B2D8, arg1); + this->unk_358 = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86DB8.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A871E0.s") +void func_80A8697C(EnTru* this, GlobalContext* globalCtx) { + this->collider.dim.worldSphere.radius = this->collider.dim.modelSphere.radius * this->collider.dim.scale; + if (this->actor.draw != NULL) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A872AC.s") +s32 func_80A869DC(EnTru* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp38; + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A873B8.s") + Math_ApproachS(&this->unk_368, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_368 = CLAMP(this->unk_368, -0x1FFE, 0x1FFE); + Math_Vec3f_Copy(&sp38, &player->actor.world.pos); + sp38.y = player->bodyPartsPos[7].y + 3.0f; + Math_Vec3f_Copy(&sp2C, &this->actor.focus.pos); + sp2C.y -= 30.0f; + Math_ApproachS(&this->unk_366, Math_Vec3f_Pitch(&sp2C, &sp38), 4, 0x2AA8); + this->unk_366 = CLAMP(this->unk_366, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87400.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A875AC.s") +s32 func_80A86B0C(EnTru* this, GlobalContext* globalCtx) { + if (this->unk_34E & 8) { + this->unk_34E &= ~0x10; + this->unk_34E |= 0x20; + func_80A869DC(this, globalCtx); + } else if (this->unk_34E & 0x20) { + this->unk_34E &= ~0x20; + this->unk_366 = 0; + this->unk_368 = 0; + this->unk_36A = 20; + } else if (DECR(this->unk_36A) == 0) { + this->unk_34E |= 0x10; + this->unk_36A = 20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A8777C.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87880.s") +s32 func_80A86BAC(EnTru* this, GlobalContext* globalCtx) { + if (this->unk_34E & 0x400) { + Matrix_StatePush(); + func_8012C28C(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87B48.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87DC0.s") + switch (this->unk_390) { + case 1: + gDPSetEnvColor(POLY_OPA_DISP++, 200, 0, 0, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87FD0.s") + case 2: + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 200, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A881E0.s") + default: + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 0); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Init.s") + Matrix_InsertXRotation_s(-0x4000, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Destroy.s") + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_tru_DL_0020C8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Update.s") + Matrix_StatePop(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A885B8.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A88698.s") + if (this->unk_34E & 0x800) { + Matrix_StatePush(); + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A886D4.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Draw.s") + gDPPipeSync(POLY_XLU_DISP++); + + Matrix_InsertXRotation_s(-0x4000, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_001F90); + + Matrix_StatePop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + return false; +} + +s32 func_80A86DB8(EnTru* this) { + if (this->unk_34E & 0x80) { + this->unk_36E = 2; + return false; + } + + switch (this->unk_37C) { + case 0: + case 1: + if (DECR(this->unk_36C) == 0) { + s16 rand = Rand_S16Offset(40, 20); + if (this->unk_36E == 2) { + this->unk_36C = 8; + } else { + this->unk_36C = rand; + } + + if (this->unk_36E == 2) { + this->unk_36E = 1; + } else { + this->unk_36E = 2; + } + } + return false; + + case 2: + if (Animation_OnFrame(&this->skelAnime, 10.0f)) { + this->unk_36E = 1; + } else if ((this->skelAnime.curFrame >= 11.0f) && (this->skelAnime.curFrame <= 32.0f)) { + this->unk_36E = 0; + } else { + this->unk_36E = 2; + } + return false; + + case 3: + if (Animation_OnFrame(&this->skelAnime, 31.0f)) { + this->unk_36E = 1; + } else if (this->skelAnime.curFrame <= 32.0f) { + this->unk_36E = 2; + } else { + this->unk_36E = 0; + } + return false; + + case 9: + if (Animation_OnFrame(&this->skelAnime, 57.0f)) { + this->unk_36C = 0; + this->unk_36E = 0; + } + + if (this->skelAnime.curFrame < 57.0f) { + if (DECR(this->unk_36C) == 0) { + this = this; + this->unk_36C = Rand_S16Offset(8, 8); + this->unk_36E = 2; + } else { + this->unk_36E = 1; + } + } else if (DECR(this->unk_36C) == 0) { + this->unk_36E++; + if (this->unk_36E >= 4) { + this->unk_36C = Rand_S16Offset(20, 10); + this->unk_36E = 0; + } + } + return false; + + case 10: + this->unk_36E = 0; + return false; + + case 11: + if (Animation_OnFrame(&this->skelAnime, 19.0f) || Animation_OnFrame(&this->skelAnime, 45.0f)) { + this->unk_36E = 1; + } else if ((this->skelAnime.curFrame >= 19.0f) && (this->skelAnime.curFrame <= 45.0f)) { + this->unk_36E = 2; + } else { + this->unk_36E = 3; + } + return false; + + case 13: + if (Animation_OnFrame(&this->skelAnime, 19.0f)) { + this->unk_36E = 1; + } else if (this->skelAnime.curFrame >= 19.0f) { + this->unk_36E = 2; + } else { + this->unk_36E = 0; + } + return false; + + default: + if (DECR(this->unk_36C) == 0) { + if ((this->unk_36E != 2) || !(this->unk_34E & 0x80)) { + this->unk_36E++; + } + + if (this->unk_36E >= 4) { + this->unk_36C = Rand_S16Offset(30, 30); + this->unk_36E = 0; + } + } + return false; + } + + return false; +} + +UNK_TYPE* func_80A871E0(EnTru* this, GlobalContext* globalCtx) { + if (this->unk_34E & 0x2000) { + if (this->unk_38C == 35) { + this->unk_390 = 1; + } else { + this->unk_390 = 2; + } + return D_80A88984; + } + + if (this->unk_34E & 0x4000) { + return D_80A889A4; + } + + if (this->unk_34E & 0x80) { + return D_80A88924; + } + + if (!(this->unk_34E & 0x40) && !(gSaveContext.weekEventReg[16] & 0x10)) { + return D_80A88918; + } + + if ((this->unk_34E & 0x1000) && !(gSaveContext.weekEventReg[16] & 0x10)) { + return D_80A88910; + } + + return D_80A8892C; +} + +s32 func_80A872AC(EnTru* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; + + if (this->unk_34E & 7) { + if (func_800B84D0(&this->actor, globalCtx)) { + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_34E &= ~0x80; + } + this->unk_34E &= ~(0x4000 | 0x2000); + + if ((player->unk_A87 == 35) || (player->unk_A87 == 36)) { + this->unk_34E |= 0x2000; + this->unk_38C = player->unk_A87; + } else if (player->unk_A87 != 0) { + this->unk_34E |= 0x4000; + } + + this->unk_378 = func_80A875AC; + this->unk_390 = 0; + this->unk_364 = 0; + this->unk_354 = func_80A871E0(this, globalCtx); + func_8013AED4(&this->unk_34E, 0, 7); + this->actionFunc = func_80A881E0; + ret = true; + } + } + + return ret; +} + +s32 func_80A873B8(EnTru* this) { + s16 yDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + s32 ret; + + if ((u16)ABS_ALT(yDiff) < 0x1600) { + ret = true; + } else { + ret = false; + } + return ret; +} + +s32 func_80A87400(EnTru* this, GlobalContext* globalCtx) { + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s16 phi_a1; + s32 ret = false; + + this->actor.velocity.y = Math_SinS(this->unk_360) * this->unk_35C; + this->unk_360 = CLAMP(this->unk_360 + 2000, 0, 0x4000); + + Math_ApproachF(&this->unk_35C, 30.0f, 0.08f, 1000.0f); + Math_ApproachF(&this->actor.speedXZ, 30.0f, 0.2f, 1000.0f); + + if (this->path != NULL) { + sp4C = (Vec3s*)Lib_SegmentedToVirtual(this->path->points); + if (func_8013BD40(&this->actor, this->path, this->unk_384)) { + if (this->unk_384 > this->unk_384 + 1) { + this->unk_384 = this->path->count - 2; + ret = true; + } + this->unk_384++; + } + Math_Vec3s_ToVec3f(&sp34, &sp4C[this->unk_384]); + Math_Vec3f_Copy(&sp40, &this->actor.world.pos); + phi_a1 = Math_Vec3f_Yaw(&sp40, &sp34); + } else { + phi_a1 = this->actor.world.rot.y; + } + + Math_ApproachS(&this->actor.world.rot.y, phi_a1, 4, 3640); + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if ((s32)(this->actor.floorHeight + 80.0f) >= (s32)this->actor.world.pos.y) { + func_80A86770(this); + } + + return ret; +} + +s32 func_80A875AC(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + s32 ret = false; + + switch (this->unk_364) { + case 0: + if ((this->unk_34E & 0x40) || (gSaveContext.weekEventReg[16] & 0x10)) { + this->unk_374 = this->actor.cutscene; + this->unk_364++; + } else { + this->unk_364++; + this->unk_364++; + break; + } + + case 1: + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_374); + } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor); + this->unk_364++; + } else { + ActorCutscene_SetIntentToPlay(this->unk_374); + } + break; + + case 2: + if ((this->unk_37C != 5) && (this->unk_37C != 6)) { + func_80A86924(this, 3); + this->unk_364++; + } else { + func_80A86924(this, 4); + ret = true; + } + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_364++; + func_80A86924(this, 4); + ret = true; + } + break; + } + + if (ret == true) { + if (this->unk_390 != 0) { + this->unk_34E |= 8; + this->unk_378 = func_80A87880; + } else { + this->unk_378 = func_80A8777C; + } + this->unk_364 = 0; + } + + return ret; +} + +s32 func_80A8777C(Actor* thisx, GlobalContext* globalCtx) { + s32 temp_v0; + s32 ret = 0; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + + switch (temp_v0) { + default: + if (temp_v0 != 0x10) { + break; + } + if (0) { + + case 4: + case 5: + if (!func_80147624(globalCtx)) { + break; + } + } + + temp_v0 = func_80123810(globalCtx); + if ((temp_v0 == 35) || (temp_v0 == 36)) { + ((EnTru*)thisx)->unk_34E |= 8; + if (temp_v0 == 35) { + ((EnTru*)thisx)->unk_390 = 1; + } else { + ((EnTru*)thisx)->unk_390 = 2; + } + ((EnTru*)thisx)->unk_378 = func_80A87880; + ((EnTru*)thisx)->unk_364 = 0; + ret = 1; + } else if (temp_v0 < 0) { + ret = 3; + } else if (temp_v0 != 0) { + ret = 2; + } + break; + } + + return ret; +} + +s32 func_80A87880(Actor* thisx, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnTru* this = THIS; + s32 ret = false; + + switch (this->unk_364) { + case 0: + ActorCutscene_Stop(this->unk_374); + this->unk_374 = ActorCutscene_GetAdditionalCutscene(this->unk_374); + this->unk_364++; + + case 1: + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_374); + } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor); + this->unk_364++; + } else { + ActorCutscene_SetIntentToPlay(this->unk_374); + } + break; + + case 2: + this->unk_34E |= 0x10; + this->unk_34E &= ~0x8; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80A86924(this, 7); + this->unk_364++; + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_364++; + func_80A86924(this, 9); + this->actor.world.rot.y += 0x4000; + } else if (Animation_OnFrame(&this->skelAnime, 12.0f) && !(this->unk_34E & 0x800)) { + this->unk_34E |= 0x400; + this->unk_34E |= 0x800; + func_80123AA4(player, 3); + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_364++; + func_80A86924(this, 10); + ret = true; + } else if (Animation_OnFrame(&this->skelAnime, 18.0f) || Animation_OnFrame(&this->skelAnime, 32.0f) || + Animation_OnFrame(&this->skelAnime, 52.0f)) { + if (Animation_OnFrame(&this->skelAnime, 52.0f)) { + this->unk_34E &= ~0x400; + func_80123D50(globalCtx, player, 18, 21); + } + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_DRINK); + } else if (Animation_OnFrame(&this->skelAnime, 90.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_REGAIN); + } + + if ((this->skelAnime.curFrame > 90.0f) && (this->skelAnime.curFrame < 95.0f)) { + func_80A86674(this); + } + break; + } + + if (ret == true) { + this->unk_378 = func_80A87B48; + this->unk_364 = 0; + } + + return ret; +} + +s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp4C; + Vec3f sp40; + s16 sp3E; + s32 pad2; + s32 ret = false; + + switch (this->unk_364) { + case 0: + func_80A86924(this, 11); + this->unk_364++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + sp3E = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))); + Math_Vec3f_Copy(&sp4C, &D_801D15B0); + sp4C.z = 40.0f; + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp3E, &sp4C, &sp40); + func_80A85620(this->unk_394, &sp40, 2.0f, 0.08f, 60.0f); + func_8016A268(globalCtx, 1, 160, 160, 160, 0); + this->unk_370 = 20; + this->unk_372 = 10; + this->unk_364++; + } else if (Animation_OnFrame(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_MAGIC); + func_80A85AA4(this->unk_394, &this->unk_1F8, 1.0f, 0.1f, 40.0f); + } + break; + + case 2: + if (DECR(this->unk_370) != 0) { + MREG(68) = 255.0f - ((fabsf(10.0f - this->unk_370) / 10) * 255.0f); + if (this->unk_370 == 9) { + this->actor.shape.shadowDraw = NULL; + this->unk_34E |= (0x200 | 0x8); + this->unk_34E &= ~0x800; + if (player->unk_A87 != 0) { + player->unk_A87 = 0; + } + func_80A86924(this, 12); + } + } else { + MREG(64) = 0; + ret = true; + } + break; + } + + if (ret == true) { + this->unk_378 = func_80A87DC0; + this->unk_364 = 0; + } + + return ret; +} + +s32 func_80A87DC0(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + s32 ret = false; + + switch (this->unk_364) { + case 0: + ActorCutscene_Stop(this->unk_374); + this->unk_374 = ActorCutscene_GetAdditionalCutscene(this->unk_374); + this->unk_364++; + + case 1: + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_374); + } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor); + this->unk_364++; + } else { + ActorCutscene_SetIntentToPlay(this->unk_374); + } + break; + + case 2: + func_801A75E8(NA_SE_EN_KOUME_MAGIC); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_AWAY); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_LAUGH); + func_80A86924(this, 13); + this->skelAnime.baseTransl.y = 0; + this->skelAnime.moveFlags = 2; + this->unk_34E &= ~0x8; + this->unk_34E |= 0x10; + this->unk_364++; + break; + + case 3: + if (!Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + AnimationContext_SetMoveActor(globalCtx, &this->actor, &this->skelAnime, 1.0f); + break; + } else { + func_80A86924(this, 14); + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_362 = 20; + this->unk_364++; + } + + case 4: + if (func_80A87400(this, globalCtx) || (DECR(this->unk_362) == 0)) { + ret = true; + gSaveContext.weekEventReg[12] |= 8; + } + break; + } + + if (ret == true) { + this->actor.flags &= ~1; + this->actor.draw = NULL; + this->unk_378 = NULL; + this->unk_34E = 0; + this->unk_364 = 0; + } + return ret; +} + +void func_80A87FD0(EnTru* this, GlobalContext* globalCtx) { + if (this->actor.draw != NULL) { + if ((this->unk_34E & 0x80) || (gSaveContext.weekEventReg[16] & 0x10)) { + if (func_80A873B8(this)) { + func_8013AED4(&this->unk_34E, 3, 7); + } else { + func_8013AED4(&this->unk_34E, 0, 7); + } + } else if (this->unk_34E & 0x40) { + if (func_80A873B8(this)) { + func_8013AED4(&this->unk_34E, 3, 7); + } else { + func_8013AED4(&this->unk_34E, 0, 7); + } + + if ((this->unk_37C == 2) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_362 = Rand_S16Offset(40, 20); + func_80A86924(this, 1); + func_80A86460(this); + } else if (this->unk_37C != 2) { + if (DECR(this->unk_362) == 0) { + func_80A86924(this, 2); + } + } + } else if (!(gSaveContext.weekEventReg[16] & 0x10) && (fabsf(this->actor.playerHeightRel) < 10.0f) && + (this->actor.xzDistToPlayer < 140.0f)) { + func_8013AED4(&this->unk_34E, 4, 7); + this->unk_34E |= 0x1040; + this->unk_362 = Rand_S16Offset(40, 20); + } else if (func_80A873B8(this)) { + func_8013AED4(&this->unk_34E, 3, 7); + } else { + func_8013AED4(&this->unk_34E, 0, 7); + } + } +} + +void func_80A881E0(EnTru* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_8010BF58(&this->actor, globalCtx, this->unk_354, this->unk_378, &this->unk_1E8)) { + if (player->transformation != PLAYER_FORM_HUMAN) { + this->unk_34E |= 0x80; + } + + if (ActorCutscene_GetCurrentIndex() != -1) { + ActorCutscene_Stop(ActorCutscene_GetCurrentIndex()); + } + + if (!(this->unk_34E & 0x40) && !(gSaveContext.weekEventReg[16] & 0x10)) { + func_80A86924(this, 0); + } else if (this->unk_34E & 0x80) { + func_80A86924(this, 0); + func_80A86460(this); + } else if (gSaveContext.weekEventReg[16] & 0x10) { + func_80A86924(this, 6); + } + + func_8013AED4(&this->unk_34E, 0, 7); + this->unk_34E &= ~(0x1000 | 0x8); + this->unk_34E |= 0x10; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.flags &= ~0x100; + this->unk_1E8 = 0; + this->actionFunc = func_80A87FD0; + } +} + +void EnTru_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + + if ((gSaveContext.entranceIndex != 0xC200) || (gSaveContext.weekEventReg[12] & 8)) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tru_Skel_01AA60, NULL, this->jointTable, this->morphTable, + 27); + Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + this->unk_37C = -1; + func_80A86924(this, 0); + this->path = func_8013BEDC(globalCtx, this->actor.params & 0xFF, 255, &this->unk_384); + if (this->path != NULL) { + this->unk_384 = 1; + } + + this->actor.targetMode = 0; + Actor_SetScale(&this->actor, 0.008f); + this->unk_34E = 0; + + if (gSaveContext.weekEventReg[16] & 0x10) { + func_80A86924(this, 5); + } else { + this->unk_388 = 0; + } + + this->actionFunc = func_80A87FD0; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); +} + +void EnTru_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + + Collider_DestroySphere(globalCtx, &this->collider); +} + +void EnTru_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + f32 radius; + + func_80A872AC(this, globalCtx); + + this->actionFunc(this, globalCtx); + + func_80A868F8(this); + func_80A86B0C(this, globalCtx); + func_80A86DB8(this); + + radius = this->collider.dim.worldSphere.radius + 30; + this->unk_388 = !(this->unk_34E & 0x80) ? 0 : 0; + + func_8013C964(&this->actor, globalCtx, radius, 20.0f, this->unk_388, this->unk_34E & 7); + func_80A8697C(this, globalCtx); + func_80A86384(this->unk_394, &this->unk_1F8); +} + +s32 EnTru_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + s32 pad; + EnTru* this = THIS; + + if (limbIndex == 21) { + Matrix_GetStateTranslation(&this->actor.focus.pos); + Math_Vec3f_ToVec3s(&this->collider.dim.worldSphere.center, &this->actor.focus.pos); + this->actor.focus.pos.x = (this->actor.focus.pos.x / 10.0f) * 10.0f; + this->actor.focus.pos.y = ((this->actor.focus.pos.y + 10.0f) / 10.0f) * 10.0f; + this->actor.focus.pos.z = (this->actor.focus.pos.z / 10.0f) * 10.0f; + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + Matrix_MultiplyVector3fByState(&D_80A8B3FC, &this->unk_1F8); + } + + if (!(this->unk_34E & 0x200) && (limbIndex == 14)) { + *dList = NULL; + } + + return false; +} + +void EnTru_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnTru* this = THIS; + + if (limbIndex == 19) { + func_80A86BAC(this, globalCtx); + } +} + +void func_80A886D4(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnTru* this = THIS; + s32 pad[3]; + s32 sp2C; + s32 phi_v1; + + if (this->unk_34E & 0x10) { + phi_v1 = false; + } else { + phi_v1 = true; + } + + if (this->unk_34E & 0x20) { + sp2C = true; + } else { + sp2C = false; + } + + if (!phi_v1) { + sp2C = false; + } + + if (limbIndex == 21) { + func_8013AD9C(this->unk_366, this->unk_368 + this->actor.shape.rot.y, &this->unk_1EC, &this->unk_204, phi_v1, + sp2C); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_1EC.x, this->unk_1EC.y, this->unk_1EC.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + if (sp2C) { + s16 oldZ = this->unk_204.z; + + this->unk_204.z = this->unk_204.x; + this->unk_204.x = oldZ; + } + Matrix_RotateY(this->unk_204.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_204.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_204.z, MTXMODE_APPLY); + Matrix_StatePush(); + } +} + +void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80A8B408[] = { + &object_tru_Tex_018FA0, + &object_tru_Tex_0197A0, + &object_tru_Tex_019FA0, + &object_tru_Tex_0197A0, + }; + s32 pad; + EnTru* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E])); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTru_OverrideLimbDraw, EnTru_PostLimbDraw, func_80A886D4, &this->actor); + func_80A85788(this->unk_394, globalCtx); + func_80A85BCC(this->unk_394, globalCtx); + func_80A85F84(this->unk_394, globalCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.h b/src/overlays/actors/ovl_En_Tru/z_en_tru.h index 7c21a43a33..4127fcdff8 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.h +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.h @@ -6,12 +6,55 @@ struct EnTru; typedef void (*EnTruActionFunc)(struct EnTru*, GlobalContext*); +typedef s32 (*EnTruUnkFunc)(Actor*, GlobalContext*); + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ u8 unk_02; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ f32 unk_28; + /* 0x2C */ f32 unk_2C; +} EnTruUnkStruct; // size = 0x30 typedef struct EnTru { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnTruActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x7A8]; + /* 0x018C */ ColliderSphere collider; + /* 0x01E4 */ Path* path; + /* 0x01E8 */ s32 unk_1E8; + /* 0x01EC */ Vec3f unk_1EC; + /* 0x01F8 */ Vec3f unk_1F8; + /* 0x0204 */ Vec3s unk_204; + /* 0x020A */ Vec3s jointTable[27]; + /* 0x02AC */ Vec3s morphTable[27]; + /* 0x034E */ u16 unk_34E; + /* 0x0350 */ UNK_TYPE1 unk350[0x4]; + /* 0x0354 */ s32* unk_354; + /* 0x0358 */ f32 unk_358; + /* 0x035C */ f32 unk_35C; + /* 0x0360 */ s16 unk_360; + /* 0x0362 */ s16 unk_362; + /* 0x0364 */ s16 unk_364; + /* 0x0366 */ s16 unk_366; + /* 0x0368 */ s16 unk_368; + /* 0x036A */ s16 unk_36A; + /* 0x036C */ s16 unk_36C; + /* 0x036E */ s16 unk_36E; + /* 0x0370 */ s16 unk_370; + /* 0x0372 */ s16 unk_372; + /* 0x0374 */ s16 unk_374; + /* 0x0378 */ EnTruUnkFunc unk_378; + /* 0x037C */ s32 unk_37C; + /* 0x0380 */ UNK_TYPE1 unk380[0x4]; + /* 0x0384 */ s32 unk_384; + /* 0x0388 */ s32 unk_388; + /* 0x038C */ s32 unk_38C; + /* 0x0390 */ s32 unk_390; + /* 0x0394 */ EnTruUnkStruct unk_394[30]; } EnTru; // size = 0x934 extern const ActorInit En_Tru_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 537d9b2ecf..60f5b896ac 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -11247,8 +11247,8 @@ 0x80A88334:("EnTru_Init",), 0x80A884BC:("EnTru_Destroy",), 0x80A884E8:("EnTru_Update",), - 0x80A885B8:("func_80A885B8",), - 0x80A88698:("func_80A88698",), + 0x80A885B8:("EnTru_OverrideLimbDraw",), + 0x80A88698:("EnTru_PostLimbDraw",), 0x80A886D4:("func_80A886D4",), 0x80A887E4:("EnTru_Draw",), 0x80A8B770:("EnTrt_ChangeAnim",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index d5d2eb0e7f..8e75b9cbd4 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -12593,8 +12593,7 @@ 0x80A8A188:("D_80A8A188","UNK_TYPE1","",0x1), 0x80A8B188:("D_80A8B188","UNK_TYPE1","",0x1), 0x80A8B250:("D_80A8B250","UNK_TYPE4","",0x4), - 0x80A8B25C:("D_80A8B25C","UNK_TYPE1","",0x1), - 0x80A8B268:("D_80A8B268","UNK_TYPE1","",0x1), + 0x80A8B25C:("D_80A8B25C","Color_RGBA8","[6]",0x18), 0x80A8B280:("D_80A8B280","UNK_TYPE1","",0x1), 0x80A8B2A0:("D_80A8B2A0","UNK_TYPE1","",0x1), 0x80A8B2CC:("D_80A8B2CC","UNK_TYPE1","",0x1), diff --git a/undefined_syms.txt b/undefined_syms.txt index ff66eaa8a4..ba74050c01 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -3872,9 +3872,25 @@ D_0600FEF0 = 0x0600FEF0; D_06001F90 = 0x06001F90; D_060020C8 = 0x060020C8; +D_06002BD8 = 0x06002BD8; +D_06003698 = 0x06003698; +D_0600446C = 0x0600446C; +D_06007FA0 = 0x06007FA0; +D_06009348 = 0x06009348; +D_0600EEDC = 0x0600EEDC; +D_0600F9A0 = 0x0600F9A0; +D_060108AC = 0x060108AC; +D_06011F88 = 0x06011F88; +D_06014728 = 0x06014728; +D_06015CA0 = 0x06015CA0; +D_06016B4C = 0x06016B4C; +D_06018FA0 = 0x06018FA0; +D_060197A0 = 0x060197A0; +D_06019FA0 = 0x06019FA0; D_0601A820 = 0x0601A820; D_0601A830 = 0x0601A830; D_0601AA60 = 0x0601AA60; +D_0601B5C4 = 0x0601B5C4; // ovl_En_Tru_Mt From 161c6ce24aca185dea604b05e7fbc47852118218 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Sun, 26 Dec 2021 23:37:26 +0000 Subject: [PATCH 26/27] viswapcontext OK (#427) --- src/libultra/io/viswapcontext.c | 65 ++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/libultra/io/viswapcontext.c b/src/libultra/io/viswapcontext.c index 014fbbfeb7..514e3aa1df 100644 --- a/src/libultra/io/viswapcontext.c +++ b/src/libultra/io/viswapcontext.c @@ -1,3 +1,66 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/viswapcontext/__osViSwapContext.s") +void __osViSwapContext(void) { + register OSViMode* viMode; + register __OSViContext* viNext; + u32 origin; + u32 hStart; + u32 vstart; + u32 sp34; + u32 field; + register u32 s2; + + field = 0; + viNext = __osViNext; + viMode = viNext->modep; + field = HW_REG(VI_V_CURRENT_LINE_REG, u32) & 1; + s2 = osVirtualToPhysical(viNext->buffer); + origin = (viMode->fldRegs[field].origin) + s2; + if (viNext->state & 2) { + viNext->x.scale |= viMode->comRegs.xScale & ~0xFFF; + } else { + viNext->x.scale = viMode->comRegs.xScale; + } + if (viNext->state & 4) { + sp34 = (u32)(viMode->fldRegs[field].yScale & 0xFFF); + viNext->y.scale = viNext->y.factor * sp34; + viNext->y.scale |= viMode->fldRegs[field].yScale & ~0xFFF; + } else { + viNext->y.scale = viMode->fldRegs[field].yScale; + } + + vstart = (viMode->fldRegs[field].vStart - (__additional_scanline << 0x10)) + __additional_scanline; + hStart = viMode->comRegs.hStart; + + if (viNext->state & 0x20) { + hStart = 0; + } + + if (viNext->state & 0x40) { + viNext->y.scale = 0; + origin = osVirtualToPhysical(viNext->buffer); + } + + if (viNext->state & 0x80) { + viNext->y.scale = (viNext->y.offset << 0x10) & 0x3FF0000; + origin = osVirtualToPhysical(viNext->buffer); + } + + HW_REG(VI_ORIGIN_REG, u32) = origin; + HW_REG(VI_WIDTH_REG, u32) = viMode->comRegs.width; + HW_REG(VI_BURST_REG, u32) = viMode->comRegs.burst; + HW_REG(VI_V_SYNC_REG, u32) = viMode->comRegs.vSync; + HW_REG(VI_H_SYNC_REG, u32) = viMode->comRegs.hSync; + HW_REG(VI_LEAP_REG, u32) = viMode->comRegs.leap; + HW_REG(VI_H_START_REG, u32) = hStart; + HW_REG(VI_V_START_REG, u32) = vstart; + HW_REG(VI_V_BURST_REG, u32) = viMode->fldRegs[field].vBurst; + HW_REG(VI_INTR_REG, u32) = viMode->fldRegs[field].vIntr; + HW_REG(VI_X_SCALE_REG, u32) = viNext->x.scale; + HW_REG(VI_Y_SCALE_REG, u32) = viNext->y.scale; + HW_REG(VI_CONTROL_REG, u32) = viNext->features; + + __osViNext = __osViCurr; + __osViCurr = viNext; + *__osViNext = *__osViCurr; +} From 56101f9dc9d68e249c8f9235e2329b8765862e42 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Mon, 27 Dec 2021 01:18:04 +0000 Subject: [PATCH 27/27] Stop iconving data, remove optimisation flags from assets, only copy required baserom files (#522) --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0ee73f25eb..082203bae0 100644 --- a/Makefile +++ b/Makefile @@ -140,9 +140,10 @@ TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),build/$f) \ C_FILES := $(foreach dir,$(SRC_DIRS) $(ASSET_BIN_DIRS),$(wildcard $(dir)/*.c)) S_FILES := $(shell grep -F "build/asm" spec | sed 's/.*build\/// ; s/\.o\".*/.s/') \ $(shell grep -F "build/data" spec | sed 's/.*build\/// ; s/\.o\".*/.s/') +BASEROM_FILES := $(shell grep -F "build/baserom" spec | sed 's/.*build\/// ; s/\.o\".*//') O_FILES := $(foreach f,$(S_FILES:.s=.o),build/$f) \ $(foreach f,$(C_FILES:.c=.o),build/$f) \ - $(foreach f,$(wildcard baserom/*),build/$f.o) + $(foreach f,$(BASEROM_FILES),build/$f.o) # Automatic dependency files # (Only asm_processor dependencies are handled for now) @@ -166,6 +167,8 @@ build/src/libultra/flash/%.o: MIPS_VERSION := -mips1 build/src/code/audio/%.o: OPTFLAGS := -O2 +build/assets/%.o: OPTFLAGS := + # file flags build/src/boot_O2_g3/fault.o: CFLAGS += -trapuv build/src/boot_O2_g3/fault_drawer.o: CFLAGS += -trapuv @@ -283,7 +286,7 @@ build/baserom/%.o: baserom/% $(OBJCOPY) -I binary -O elf32-big $< $@ build/data/%.o: data/%.s - iconv --from UTF-8 --to EUC-JP $< | $(AS) $(ASFLAGS) -o $@ + $(AS) $(ASFLAGS) $< -o $@ build/src/overlays/%.o: src/overlays/%.c $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<

Md*{b&w+%iG|^2 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/z64utils_skeleton_head.png b/docs/tutorial/images/z64utils_skeleton_head.png new file mode 100644 index 0000000000000000000000000000000000000000..263f06642596fdec62aedf5ad59f07f12dfe8d30 GIT binary patch literal 95083 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