1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-06 06:10:21 +00:00

En_Changer OK (#501)

* decomped most functions, 2 left

* all functions decomped except for Init

* just regalloc left in Init(?)

* Init finally matched, translation, some naming

* most other variables named

* Delete asm

* Whoops, actually deleted asm this time

* review

* review 2

Co-authored-by: fig02 <fig02srl@gmail.com>
This commit is contained in:
EllipticEllipsis 2020-12-06 07:38:16 +00:00 committed by GitHub
parent 6b6c30cded
commit 9d63626343
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 314 additions and 880 deletions

View file

@ -1,14 +1,30 @@
/*
* File: z_en_changer.c
* Overlay: ovl_En_Changer
* Description: Treasure Box Shop Minigame
*/
#include "z_en_changer.h"
#include "vt.h"
#include "overlays/actors/ovl_Item_Etcetera/z_item_etcetera.h"
#define FLAGS 0x00000000
#define THIS ((EnChanger*)thisx)
typedef enum {
/* 0 */ CHEST_LEFT,
/* 1 */ CHEST_RIGHT
} ChangerChestSide;
void EnChanger_Init(Actor* thisx, GlobalContext* globalCtx);
void EnChanger_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnChanger_Update(Actor* thisx, GlobalContext* globalCtx);
/*
void EnChanger_Wait(EnChanger* this, GlobalContext* globalCtx);
void EnChanger_OpenChests(EnChanger* this, GlobalContext* globalCtx);
void EnChanger_SetHeartPieceFlag(EnChanger* this, GlobalContext* globalCtx);
const ActorInit En_Changer_InitVars = {
ACTOR_EN_CHANGER,
ACTORTYPE_PROP,
@ -20,15 +36,266 @@ const ActorInit En_Changer_InitVars = {
(ActorFunc)EnChanger_Update,
NULL,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Changer/EnChanger_Destroy.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Changer/EnChanger_Init.s")
static Vec3f sLeftChestPos[] = {
{ 0.0f, 0.0f, 0.0f }, { -100.0f, 20.0f, -245.0f }, { -100.0f, 20.0f, -685.0f },
{ -100.0f, 20.0f, -1125.0f }, { -100.0f, 20.0f, -1565.0f }, { -100.0f, 20.0f, -2005.0f },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Changer/func_809D2CCC.s")
static Vec3f sRightChestPos[] = {
{ 0.0f, 0.0f, 0.0f }, { 140.0f, 20.0f, -245.0f }, { 140.0f, 20.0f, -685.0f },
{ 140.0f, 20.0f, -1125.0f }, { 140.0f, 20.0f, -1565.0f }, { 140.0f, 20.0f, -2005.0f },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Changer/func_809D2D70.s")
static s32 sLoserGetItemIds[] = {
GI_NONE, GI_RUPEE_GREEN_LOSE, GI_RUPEE_GREEN_LOSE, GI_RUPEE_BLUE_LOSE, GI_RUPEE_BLUE_LOSE, GI_RUPEE_RED_LOSE,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Changer/func_809D2F74.s")
static s32 sItemEtcTypes[] = {
0,
ITEM_ETC_RUPEE_GREEN_CHEST_GAME,
ITEM_ETC_RUPEE_GREEN_CHEST_GAME,
ITEM_ETC_RUPEE_BLUE_CHEST_GAME,
ITEM_ETC_RUPEE_BLUE_CHEST_GAME,
ITEM_ETC_RUPEE_RED_CHEST_GAME,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Changer/EnChanger_Update.s")
static s32 sTreasureFlags[] = { 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A };
void EnChanger_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
void EnChanger_Init(Actor* thisx, GlobalContext* globalCtx2) {
EnChanger* this = THIS;
GlobalContext* globalCtx = globalCtx2;
s16 leftChestParams;
s16 rightChestParams;
s16 rewardChestParams;
s16 minigameRoomNum;
s16 rightChestItem;
s16 leftChestItem;
s16 temp_v1_3;
s16 new_var;
s32 rewardParams;
if (1) {}
minigameRoomNum = globalCtx->roomCtx.curRoom.num - 1;
if (minigameRoomNum < 0) {
minigameRoomNum = 0;
}
if (Flags_GetTreasure(globalCtx, sTreasureFlags[minigameRoomNum])) {
this->roomChestsOpened = true;
}
osSyncPrintf("\n\n");
// Treasure generation (which room is it?)
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 宝発生(部屋はどれ?) %d\n" VT_RST, globalCtx->roomCtx.curRoom.num);
// How is the Bit?
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ビットは? \t %x\n" VT_RST, globalCtx->actorCtx.flags.chest);
// How is the Save BIT?
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ セーブBITは? %x\n" VT_RST, sTreasureFlags[minigameRoomNum]);
// Is it already a zombie?
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ もう、ゾンビ?\t %d\n" VT_RST, this->roomChestsOpened);
osSyncPrintf("\n\n");
minigameRoomNum *= 2;
// Spawn Heart Piece in chest (or Purple Rupee if won Heart Piece)
if (globalCtx->roomCtx.curRoom.num >= 6) {
rewardChestParams = ((gSaveContext.itemGetInf[1] & 0x800) ? (0x4EA0) : (0x4EC0));
rewardChestParams = sTreasureFlags[5] | rewardChestParams;
this->finalChest = (EnBox*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BOX,
20.0f, 20.0f, -2500.0f, 0, 0x7FFF, 0, rewardChestParams);
if (this->finalChest != NULL) {
if (this->roomChestsOpened) {
Flags_SetTreasure(globalCtx, rewardChestParams & 0x1F);
Actor_Kill(&this->actor);
return;
} else {
rewardParams = ((gSaveContext.itemGetInf[1] & 0x800) ? (ITEM_ETC_RUPEE_PURPLE_CHEST_GAME)
: (ITEM_ETC_HEART_PIECE_CHEST_GAME)) &
0xFF;
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_ETCETERA, 20.0f, 20.0f, -2500.0f, 0, 0, 0,
((sTreasureFlags[5] & 0x1F) << 8) + rewardParams);
// Central treasure instance/occurrence (GREAT)
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 中央宝発生() ☆☆☆☆☆ %x\n" VT_RST, rewardChestParams);
this->actionFunc = EnChanger_SetHeartPieceFlag;
return;
}
}
}
temp_v1_3 = minigameRoomNum;
// Set up items in chests, swap them round with probability 1/2
leftChestParams = (sLoserGetItemIds[globalCtx->roomCtx.curRoom.num] << 5) | 0x4000;
new_var = temp_v1_3;
this->leftChestNum = new_var;
this->leftChestGetItemId = sLoserGetItemIds[globalCtx->roomCtx.curRoom.num];
leftChestItem = sItemEtcTypes[globalCtx->roomCtx.curRoom.num];
leftChestParams |= new_var;
rightChestParams = new_var | 0x4E21;
this->rightChestNum = new_var | 1;
this->rightChestGetItemId = GI_DOOR_KEY;
rightChestItem = ITEM_ETC_KEY_SMALL_CHEST_GAME;
if (Math_Rand_ZeroFloat(1.99f) < 1.0f) {
rightChestParams = (sLoserGetItemIds[globalCtx->roomCtx.curRoom.num] << 5) | 0x4000;
this->rightChestNum = new_var;
this->rightChestGetItemId = sLoserGetItemIds[globalCtx->roomCtx.curRoom.num];
rightChestItem = sItemEtcTypes[globalCtx->roomCtx.curRoom.num];
leftChestParams = new_var | 0x4E21;
rightChestParams |= new_var;
this->leftChestNum = temp_v1_3 | 1;
this->leftChestGetItemId = GI_DOOR_KEY;
leftChestItem = ITEM_ETC_KEY_SMALL_CHEST_GAME;
}
this->leftChest = (EnBox*)Actor_SpawnAsChild(
&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BOX, sLeftChestPos[globalCtx->roomCtx.curRoom.num].x,
sLeftChestPos[globalCtx->roomCtx.curRoom.num].y, sLeftChestPos[globalCtx->roomCtx.curRoom.num].z, 0, -0x3FFF, 0,
leftChestParams);
if (this->leftChest != NULL) {
// Left treasure generation (what does it contain?)
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 左宝発生(ナニがはいってるの?) ☆☆☆☆☆ %x\n" VT_RST, leftChestParams);
// What is the room number?
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 部屋番号は? %x\n" VT_RST, globalCtx->roomCtx.curRoom.num);
// What is the bit?
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ビットはなぁに? %x\n" VT_RST, this->rightChestNum);
// Sukesuke-kun (something to do with being invisible)
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ すけすけ君? %x\n" VT_RST, rightChestItem);
osSyncPrintf("\n\n");
if (this->roomChestsOpened) {
Flags_SetTreasure(globalCtx, this->leftChestNum & 0x1F);
} else {
Actor_Spawn(
&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_ETCETERA, sLeftChestPos[globalCtx->roomCtx.curRoom.num].x,
sLeftChestPos[globalCtx->roomCtx.curRoom.num].y, sLeftChestPos[globalCtx->roomCtx.curRoom.num].z, 0, 0,
0, ((this->leftChestNum & 0x1F) << 8) + (leftChestItem & 0xFF));
}
}
this->rightChest = (EnBox*)Actor_SpawnAsChild(
&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BOX, sRightChestPos[globalCtx->roomCtx.curRoom.num].x,
sRightChestPos[globalCtx->roomCtx.curRoom.num].y, sRightChestPos[globalCtx->roomCtx.curRoom.num].z, 0, 0x3FFF,
0, rightChestParams);
if (this->rightChest != NULL) {
// Right treasure generation (what does it contain?)
osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 右宝発生(ナニがはいってるの?) ☆☆☆☆☆ %x\n" VT_RST, rightChestParams);
// What is the room number?
osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 部屋番号は? %d\n" VT_RST, globalCtx->roomCtx.curRoom.num);
// What is the bit?
osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ ビットはなぁに? %x\n" VT_RST, this->leftChestNum);
// Sukesuke-kun (something to do with being invisible)
osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ すけすけ君? %x\n" VT_RST, leftChestItem);
osSyncPrintf("\n\n");
if (this->roomChestsOpened) {
Flags_SetTreasure(globalCtx, this->rightChestNum & 0x1F);
Actor_Kill(&this->actor);
return;
}
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_ETCETERA,
sRightChestPos[globalCtx->roomCtx.curRoom.num].x, sRightChestPos[globalCtx->roomCtx.curRoom.num].y,
sRightChestPos[globalCtx->roomCtx.curRoom.num].z, 0, 0, 0,
((this->rightChestNum & 0x1F) << 8) + (rightChestItem & 0xFF));
}
this->actor.flags &= ~1;
this->actionFunc = EnChanger_Wait;
}
void EnChanger_Wait(EnChanger* this, GlobalContext* globalCtx) {
if (this->leftChest->unk_1F4 != 0) {
this->timer = 80;
Flags_SetTreasure(globalCtx, this->rightChestNum & 0x1F);
this->actionFunc = EnChanger_OpenChests;
} else if (this->rightChest->unk_1F4 != 0) {
this->chestOpened = CHEST_RIGHT;
this->timer = 80;
Flags_SetTreasure(globalCtx, this->leftChestNum & 0x1F);
this->actionFunc = EnChanger_OpenChests;
}
}
// Spawns the EnExItem showing what was in the other chest
void EnChanger_OpenChests(EnChanger* this, GlobalContext* globalCtx) {
f32 zPos;
f32 yPos;
f32 xPos;
s16 temp_s0;
s16 temp_s0_2;
EnBox* left;
EnBox* right;
left = this->leftChest;
right = this->rightChest;
if (this->timer == 0) {
temp_s0_2 = temp_s0 = this->chestOpened; // Required to use the right registers
switch (temp_s0_2) {
case CHEST_LEFT:
xPos = right->dyna.actor.posRot.pos.x;
yPos = right->dyna.actor.posRot.pos.y;
zPos = right->dyna.actor.posRot.pos.z;
if (this->rightChestGetItemId == GI_DOOR_KEY) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_EX_ITEM, xPos, yPos, zPos, 0, 0, 0, 0xF);
Flags_SetSwitch(globalCtx, 0x32);
} else {
temp_s0_2 = (s16)(this->rightChestGetItemId - 0x72) + 0xA;
// Open right treasure (chest)
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 右宝開く ☆☆☆☆☆ %d\n" VT_RST, temp_s0_2);
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_EX_ITEM, xPos, yPos, zPos, 0, 0, 0,
temp_s0_2);
}
break;
case CHEST_RIGHT:
xPos = left->dyna.actor.posRot.pos.x;
yPos = left->dyna.actor.posRot.pos.y;
zPos = left->dyna.actor.posRot.pos.z;
if (this->leftChestGetItemId == GI_DOOR_KEY) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_EX_ITEM, xPos, yPos, zPos, 0, 0, 0, 0xF);
Flags_SetSwitch(globalCtx, 0x32);
} else {
temp_s0_2 = (s16)(this->leftChestGetItemId - 0x72) + 0xA;
// Open left treasure (chest)
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 左宝開く ☆☆☆☆☆ %d\n" VT_RST, temp_s0_2);
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_EX_ITEM, xPos, yPos, zPos, 0, 0, 0,
temp_s0_2);
}
break;
}
Actor_Kill(&this->actor);
}
}
void EnChanger_SetHeartPieceFlag(EnChanger* this, GlobalContext* globalCtx) {
if (this->finalChest->unk_1F4 != 0) {
if (!(gSaveContext.itemGetInf[1] & 0x800)) {
gSaveContext.itemGetInf[1] |= 0x800;
}
Actor_Kill(&this->actor);
}
}
void EnChanger_Update(Actor* thisx, GlobalContext* globalCtx) {
EnChanger* this = THIS;
this->actionFunc(this, globalCtx);
if (this->timer != 0) {
this->timer--;
}
if (BREG(0)) {
DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z,
this->actor.posRot.rot.x, this->actor.posRot.rot.y, this->actor.posRot.rot.z, 1.0f, 1.0f,
1.0f, 255, 0, 255, 255, 4, globalCtx->state.gfxCtx);
}
}

View file

@ -3,12 +3,25 @@
#include "ultra64.h"
#include "global.h"
#include "overlays/actors/ovl_En_Box/z_en_box.h"
struct EnChanger;
typedef void (*EnChangerActionFunc)(struct EnChanger*, GlobalContext*);
typedef struct EnChanger {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x20];
/* 0x014C */ EnChangerActionFunc actionFunc;
/* 0x0150 */ EnBox* leftChest;
/* 0x0154 */ EnBox* rightChest;
/* 0x0158 */ EnBox* finalChest;
/* 0x015C */ s16 leftChestNum;
/* 0x015E */ s16 rightChestNum;
/* 0x0160 */ s16 leftChestGetItemId;
/* 0x0162 */ s16 rightChestGetItemId;
/* 0x0164 */ s16 chestOpened;
/* 0x0166 */ s16 timer;
/* 0x0168 */ s16 roomChestsOpened;
} EnChanger; // size = 0x016C
extern const ActorInit En_Changer_InitVars;

View file

@ -78,25 +78,25 @@ void ItemEtcetera_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_SetScale(&this->actor, 0.25f);
ItemEtcetera_SetupAction(this, func_80B857D0);
switch (type) {
case ITEM_ETCETERA_LETTER:
case ITEM_ETC_LETTER:
Actor_SetScale(&this->actor, 0.5f);
this->futureActionFunc = func_80B858B4;
if (gSaveContext.eventChkInf[3] & 2) {
Actor_Kill(&this->actor);
}
break;
case ITEM_ETCETERA_ARROW_FIRE:
case ITEM_ETC_ARROW_FIRE:
this->futureActionFunc = ItemEtcetera_UpdateFireArrow;
Actor_SetScale(&this->actor, 0.5f);
this->actor.draw = NULL;
this->actor.shape.unk_08 = 50.0f;
break;
case ITEM_ETCETERA_RUPEE_GREEN_CHEST_GAME:
case ITEM_ETCETERA_RUPEE_BLUE_CHEST_GAME:
case ITEM_ETCETERA_RUPEE_RED_CHEST_GAME:
case ITEM_ETCETERA_RUPEE_PURPLE_CHEST_GAME:
case ITEM_ETCETERA_HEART_PIECE_CHEST_GAME:
case ITEM_ETCETERA_KEY_SMALL_CHEST_GAME:
case ITEM_ETC_RUPEE_GREEN_CHEST_GAME:
case ITEM_ETC_RUPEE_BLUE_CHEST_GAME:
case ITEM_ETC_RUPEE_RED_CHEST_GAME:
case ITEM_ETC_RUPEE_PURPLE_CHEST_GAME:
case ITEM_ETC_HEART_PIECE_CHEST_GAME:
case ITEM_ETC_KEY_SMALL_CHEST_GAME:
Actor_SetScale(&this->actor, 0.5f);
this->futureActionFunc = func_80B85B28;
this->drawFunc = ItemEtcetera_DrawThroughLens;

View file

@ -1,5 +1,5 @@
#ifndef _Z_ITEM_ETCETERA_H_
#define _Z_ITEM_ETCETERA_H_
#ifndef _Z_ITEM_ETC_H_
#define _Z_ITEM_ETC_H_
#include "ultra64.h"
#include "global.h"
@ -19,20 +19,20 @@ typedef struct ItemEtcetera {
} ItemEtcetera; // size = 0x0160
typedef enum {
/* 0x00 */ ITEM_ETCETERA_BOTTLE,
/* 0x01 */ ITEM_ETCETERA_LETTER,
/* 0x02 */ ITEM_ETCETERA_SHIELD_HYLIAN,
/* 0x03 */ ITEM_ETCETERA_QUIVER,
/* 0x04 */ ITEM_ETCETERA_SCALE_SILVER,
/* 0x05 */ ITEM_ETCETERA_SCALE_GOLD,
/* 0x06 */ ITEM_ETCETERA_KEY_SMALL,
/* 0x07 */ ITEM_ETCETERA_ARROW_FIRE,
/* 0x08 */ ITEM_ETCETERA_RUPEE_GREEN_CHEST_GAME,
/* 0x09 */ ITEM_ETCETERA_RUPEE_BLUE_CHEST_GAME,
/* 0x0A */ ITEM_ETCETERA_RUPEE_RED_CHEST_GAME,
/* 0x0B */ ITEM_ETCETERA_RUPEE_PURPLE_CHEST_GAME,
/* 0x0C */ ITEM_ETCETERA_HEART_PIECE_CHEST_GAME,
/* 0x0D */ ITEM_ETCETERA_KEY_SMALL_CHEST_GAME
/* 0x00 */ ITEM_ETC_BOTTLE,
/* 0x01 */ ITEM_ETC_LETTER,
/* 0x02 */ ITEM_ETC_SHIELD_HYLIAN,
/* 0x03 */ ITEM_ETC_QUIVER,
/* 0x04 */ ITEM_ETC_SCALE_SILVER,
/* 0x05 */ ITEM_ETC_SCALE_GOLD,
/* 0x06 */ ITEM_ETC_KEY_SMALL,
/* 0x07 */ ITEM_ETC_ARROW_FIRE,
/* 0x08 */ ITEM_ETC_RUPEE_GREEN_CHEST_GAME,
/* 0x09 */ ITEM_ETC_RUPEE_BLUE_CHEST_GAME,
/* 0x0A */ ITEM_ETC_RUPEE_RED_CHEST_GAME,
/* 0x0B */ ITEM_ETC_RUPEE_PURPLE_CHEST_GAME,
/* 0x0C */ ITEM_ETC_HEART_PIECE_CHEST_GAME,
/* 0x0D */ ITEM_ETC_KEY_SMALL_CHEST_GAME
} ItemEtceteraType;
extern const ActorInit Item_Etcetera_InitVars;