diff --git a/include/gfx.h b/include/gfx.h index 950f96e0..78a27d68 100644 --- a/include/gfx.h +++ b/include/gfx.h @@ -310,6 +310,7 @@ typedef enum SetupDL { /* 0x55 */ SETUPDL_85, /* 0x56 */ SETUPDL_86, /* 0x57 */ SETUPDL_87, + SETUPDL_29_POINT, SETUPDL_36_POINT, SETUPDL_62_POINT, SETUPDL_63_POINT, diff --git a/src/engine/fox_rcp_setup.c b/src/engine/fox_rcp_setup.c index b9851a36..c642e885 100644 --- a/src/engine/fox_rcp_setup.c +++ b/src/engine/fox_rcp_setup.c @@ -1265,6 +1265,20 @@ Gfx gRcpSetupDLs[][9] = { G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_NPRIMITIVE), gsSPEndDisplayList(), }, + { + /* SETUPDL_29_POINT */ + gsDPPipeSync(), + gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | + G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH), + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), + gsDPSetCombineMode(G_CC_MODULATEIDECALA, G_CC_PASS2), + gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH), + gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 3, G_AC_NONE | G_ZS_PIXEL), + gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2), + gsSPSetOtherModeHi(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_NPRIMITIVE), + gsSPEndDisplayList(), + }, { /* SETUPDL_36_POINT */ gsDPPipeSync(), diff --git a/src/port/mods/PortEnhancements.c b/src/port/mods/PortEnhancements.c index f52644e8..bf730873 100644 --- a/src/port/mods/PortEnhancements.c +++ b/src/port/mods/PortEnhancements.c @@ -193,6 +193,65 @@ void OnPlayerShootPost(PlayerActionPostShootEvent* event) { event->shot->timer *= CVarGetInteger("gLaserRangeMult", 100) / 100.0f; } +void OnItemGoldRingDraw(ObjectDrawPostSetupEvent* event) { + if (event->type != OBJECT_TYPE_ITEM) { + return; + } + + Item* item = (Item*) event->object; + if (item->obj.id != OBJ_ITEM_GOLD_RING || CVarGetInteger("gRestoreBetaCoin", 0) != 1) { + return; + } + + event->event.cancelled = true; + RCP_SetupDL(&gMasterDisp, SETUPDL_29_POINT); + Graphics_SetScaleMtx(item->width * 1.5f); + gSPDisplayList(gMasterDisp++, D_101D870); +} + +void OnItemGoldRingUpdate(ObjectUpdateEvent* event){ + if (event->type != OBJECT_TYPE_ITEM) { + return; + } + + Item* item = (Item*) event->object; + if (item->obj.id != OBJ_ITEM_GOLD_RING || CVarGetInteger("gRestoreBetaCoin", 0) != 1) { + return; + } + + Item_CheckBounds(item); + switch (item->state) { + case 0: + if (item->collected) { + item->state = 1; + gGoldRingCount[0]++; + if (gGoldRingCount[0] == 3) { + Object_PlayerSfx(gPlayer[item->playerNum].sfxSource, NA_SE_SHIELD_UPGRADE, item->playerNum); + } else if (gGoldRingCount[0] == 6) { + Object_PlayerSfx(gPlayer[item->playerNum].sfxSource, NA_SE_ONE_UP, item->playerNum); + if (gCurrentLevel != LEVEL_TRAINING) { + gLifeCount[item->playerNum]++; + } + gPlayer[item->playerNum].heal += 32; + BonusText_Display(gPlayer[item->playerNum].pos.x, gPlayer[item->playerNum].pos.y, + gPlayer[item->playerNum].trueZpos, BONUS_TEXT_1UP); + } else { + gPlayer[item->playerNum].heal += 32; + Object_PlayerSfx(gPlayer[item->playerNum].sfxSource, NA_SE_GOLD_RING, item->playerNum); + } + } + + if (item->timer_48 == 1) { + Object_Kill(&item->obj, item->sfxSource); + } + break; + + case 1: + ItemSupplyRing_Update(item); + break; + } +} + void PortEnhancements_Init() { PortEnhancements_Register(); @@ -201,6 +260,9 @@ void PortEnhancements_Init() { REGISTER_LISTENER(GamePostUpdateEvent, OnGameUpdatePost, EVENT_PRIORITY_NORMAL); REGISTER_LISTENER(PlayerPostUpdateEvent, OnPlayerUpdatePost, EVENT_PRIORITY_NORMAL); + REGISTER_LISTENER(ObjectUpdateEvent, OnItemGoldRingUpdate, EVENT_PRIORITY_NORMAL); + REGISTER_LISTENER(ObjectDrawPostSetupEvent, OnItemGoldRingDraw, EVENT_PRIORITY_NORMAL); + // Register Action listeners REGISTER_LISTENER(PlayerActionBoostEvent, OnPlayerBoost, EVENT_PRIORITY_NORMAL); REGISTER_LISTENER(PlayerActionBrakeEvent, OnPlayerBrake, EVENT_PRIORITY_NORMAL); @@ -236,7 +298,8 @@ void PortEnhancements_Register() { // Register actor events REGISTER_EVENT(ObjectInitEvent); REGISTER_EVENT(ObjectUpdateEvent); - REGISTER_EVENT(ObjectDrawEvent); + REGISTER_EVENT(ObjectDrawPreSetupEvent); + REGISTER_EVENT(ObjectDrawPostSetupEvent); REGISTER_EVENT(ObjectDestroyEvent); // Register player action events diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index f2d11a21..5cb3133e 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -469,6 +469,10 @@ void DrawEnhancementsMenu() { .tooltip = "Restores the missile cutscene bug present in JP 1.0" }); + UIWidgets::CVarCheckbox("Beta: Restore beta coin", "gRestoreBetaCoin", { + .tooltip = "Restores the beta coin that got replaced with the gold ring" + }); + ImGui::EndMenu(); }