Merge with origin/main

This commit is contained in:
jdflyer
2026-08-17 22:52:28 -07:00
133 changed files with 3076 additions and 886 deletions
+4 -1
View File
@@ -11,7 +11,10 @@
#include "Z2AudioLib/SpotName.h"
#include "os_report.h"
#if TARGET_PC
#include "dusk/audio.h"
#include "dusk/version.hpp"
#endif
Z2SeqMgr::Z2SeqMgr() : JASGlobalInstance<Z2SeqMgr>(true) {
mMainBgmMaster.forceIn();
@@ -584,7 +587,7 @@ void Z2SeqMgr::bgmStreamPlay() {
}
#if !PLATFORM_SHIELD
else if (getStreamBgmID() == 0x2000000) {
else if (getStreamBgmID() == 0x2000000 IF_DUSK(&& dusk::version::isGcn())) {
if (mStreamBgmHandle) {
mStreamBgmHandle->stop();
}
+1 -1
View File
@@ -551,7 +551,7 @@ void daAlink_c::setBowSight() {
getArrowFlyData(&dist, &speed, TRUE);
checkSightLine(dist, &sight_pos);
mSight.setPos(&sight_pos);
mSight.offDrawFlg();
DUSK_IF_ELSE(dusk::getSettings().game.aimingReticle ? mSight.onDrawFlg() : mSight.offDrawFlg(), mSight.offDrawFlg());
} else {
mSight.offDrawFlg();
}
+7 -1
View File
@@ -2263,6 +2263,12 @@ int daAlink_c::procCoGetItemInit() {
s16 var_r22 = 0;
BOOL var_r31 = FALSE;
BOOL var_r30 = FALSE;
#if TARGET_PC
// Queued grants have no event partner, so create the demo item from the event's GtItm.
if (dusk::mods::item_give_queue_dispatching()) {
mDemo.setParam0(0x100);
}
#endif
if (mProcID == PROC_GET_ITEM || mProcID == PROC_INSECT_CATCH ||
(mProcID == PROC_PREACTION_UNEQUIP && !checkNoUpperAnime()))
{
@@ -2302,7 +2308,7 @@ int daAlink_c::procCoGetItemInit() {
}
fpc_ProcID item_partner_id = fopAcM_createItemForPresentDemo(&current.pos, item_no, 0, -1,
fopAcM_GetRoomNo(this), NULL, NULL);
fopAcM_GetRoomNo(this), NULL, NULL IF_DUSK_ARG(dusk::mods::item_give_queue_take_tag()));
if (item_partner_id != fpcM_ERROR_PROCESS_ID_e) {
dComIfGp_event_setItemPartnerId(item_partner_id);
}
+4
View File
@@ -4084,6 +4084,10 @@ void daB_DS_c::executeBattle2Dead() {
camera->mCamera.SetTrimSize(0);
dComIfGp_event_reset();
dComIfGs_onStageBossEnemy(0x13);
#if TARGET_PC
// This reward has no original grant at this point in the cutscene.
dusk::mods::item_check_enqueue("Arbiters Grounds Dungeon Reward", dItemNo_NONE_e);
#endif
/* dSv_event_flag_c::F_0265 - Arbiter's Grounds - Arbiter's Grounds clear */
dComIfGs_onEventBit(0x2010);
fopAcM_delete(this);
+1 -1
View File
@@ -170,7 +170,7 @@ void daDitem_c::actionEvent() {
if (chkDead()) {
if (!chkArgFlag(0x1)) {
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
}
if (m_itemNo == dItemNo_KAKERA_HEART_e) {
+12 -5
View File
@@ -726,11 +726,18 @@ void daE_HP_c::executeDead() {
fopAcM_onSwitch(this, bitSw);
}
dComIfGs_addPohSpiritNum();
#if TARGET_PC
mItemCheckOverridden =
dusk::mods::item_check_poe(bitSw, dItemNo_POU_SPIRIT_e, this) != dItemNo_POU_SPIRIT_e;
if (mItemCheckOverridden) {
dusk::mods::item_check_enqueue_poe(bitSw, dItemNo_POU_SPIRIT_e);
} else
#endif
dComIfGs_addPohSpiritNum();
field_0x784 = -1;
if (dComIfGs_getPohSpiritNum() == 20) {
if (dComIfGs_getPohSpiritNum() == 20 IF_DUSK(&&!mItemCheckOverridden)) {
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[0x1c9]);
}
@@ -752,13 +759,13 @@ void daE_HP_c::executeDead() {
field_0x788 = 1;
}
}
} else if (field_0x788 != 0) {
} else if (field_0x788 != 0 IF_DUSK(|| mItemCheckOverridden)) {
fopAcM_createDisappear(this, &current.pos, 8, 3, 0xff);
fopAcM_delete(this);
} else {
if (field_0x784 == -1) {
field_0x784 = fopAcM_createItemForPresentDemo(&current.pos, dItemNo_POU_SPIRIT_e, 0, -1,
-1, 0, 0);
field_0x784 = fopAcM_createItemForPresentDemo(&current.pos, dItemNo_POU_SPIRIT_e, 0,
-1, -1, 0, 0 IF_DUSK_ARG(dusk::mods::item_give_tag_poe(bitSw)));
}
if (fopAcM_IsExecuting(field_0x784) != FALSE) {
+16 -1
View File
@@ -1132,12 +1132,20 @@ static void e_po_dead(e_po_class* i_this) {
camera_player->mCamera.Start();
camera_player->mCamera.SetTrimSize(0);
dComIfGp_event_reset();
dComIfGs_addPohSpiritNum();
#if TARGET_PC
if (dusk::mods::item_check_poe(i_this->BitSW, dItemNo_POU_SPIRIT_e, a_this) ==
dItemNo_POU_SPIRIT_e)
{
#endif
dComIfGs_addPohSpiritNum();
#if !PLATFORM_SHIELD
if (dComIfGs_getPohSpiritNum() == 0x14) {
/* dSv_event_flag_c::F_0457 - Castle Town - Revived cat */
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[457]);
}
#endif
#if TARGET_PC
}
#endif
daPy_getPlayerActorClass()->cancelOriginalDemo();
} else if (mArg0Check(i_this, 0) != 0) {
@@ -1265,8 +1273,15 @@ static void e_po_dead(e_po_class* i_this) {
}
} else {
if (i_this->field_0x75C == -1) {
#if TARGET_PC
const u8 itemNo =
dusk::mods::item_check_poe(i_this->BitSW, dItemNo_POU_SPIRIT_e, a_this);
i_this->field_0x75C = fopAcM_createItemForPresentDemo(&a_this->current.pos, itemNo,
0, -1, -1, NULL, NULL, dusk::mods::item_give_tag_poe(i_this->BitSW));
#else
i_this->field_0x75C = fopAcM_createItemForPresentDemo(&a_this->current.pos, 0xE0, 0,
-1, -1, NULL, NULL);
#endif
}
if (fopAcM_IsExecuting(i_this->field_0x75C)) {
i_this->field_0x762 =
+3 -1
View File
@@ -1250,7 +1250,9 @@ static void demo_camera(e_rdb_class* i_this) {
}
if (iVar1 != 0) {
daPy_getPlayerActorClass()->changeDemoMode(11, 32, 0, 0);
daPy_getPlayerActorClass()->changeDemoMode(11,
DUSK_ITEM_CHECK_EXPR("bulblin_key:D_MN09", dItemNo_SMALL_KEY_e, &i_this->enemy), 0,
0);
i_this->mDemoMode = 12;
i_this->field_0x10aa = 0;
i_this->field_0xfe5 = 1;
+3 -1
View File
@@ -931,7 +931,9 @@ static void get_demo(e_th_ball_class* i_this) {
case 0:
break;
case 1:
demo_id = fopAcM_createItemForTrBoxDemo(&i_this->current.pos, dItemNo_IRONBALL_e, -1, fopAcM_GetRoomNo(i_this), NULL, NULL);
demo_id = fopAcM_createItemForTrBoxDemo(&i_this->current.pos,
DUSK_ITEM_CHECK_EXPR("ball_and_chain:D_MN11", dItemNo_IRONBALL_e, i_this), -1,
fopAcM_GetRoomNo(i_this), NULL, NULL DUSK_GIVE_TAG("ball_and_chain:D_MN11"));
JUT_ASSERT(1670, demo_id != fpcM_ERROR_PROCESS_ID_e);
i_this->mDemoMode = 2;
break;
+74 -18
View File
@@ -15,12 +15,50 @@
#include "dusk/dvd_asset.hpp"
#include "dusk/frame_interpolation.h"
using GameVersion = dusk::version::GameVersion;
#include <type_traits>
using namespace dusk::version;
#define MANT_REL_PATH platformSelect<const char*>("/rel/Final/Release/d_a_mant.rel", "/rel/Rfinal/Release/d_a_mant.rel")
#define DEFINE_MANT_ASSET(name, type, count, ...) \
static type* name##_get() { \
alignas(32) static std::remove_cv_t<type> buf[count]; \
static bool _ = (dusk::LoadRelAsset(buf, MANT_REL_PATH, __VA_ARGS__), true); \
return buf; \
}
// keep the original version of the cape texture const so we don't need to reload the file
static u8 const * l_Egnd_mantTEX_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x1C00}, {GameVersion::GcnPal, 0x1C00}, {GameVersion::GcnJpn, 0x1C00}}, 0x4000), true); return buf; }
static u8* l_Egnd_mantTEX_U_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x5C00}, {GameVersion::GcnPal, 0x5C00}, {GameVersion::GcnJpn, 0x5C00}}, 0x4000), true); return buf; }
static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C00}, {GameVersion::GcnPal, 0x9C00}, {GameVersion::GcnJpn, 0x9C00}}, 0x60), true); return buf; }
DEFINE_MANT_ASSET(l_Egnd_mantTEX, u8 const, 0x4000, {
{GameVersion::GcnUsa, 0x1C00},
{GameVersion::GcnPal, 0x1C00},
{GameVersion::GcnJpn, 0x1C00},
{GameVersion::WiiUsaRev0, 0x1B00},
{GameVersion::WiiUsa, 0x1900},
{GameVersion::WiiPal, 0x1900},
{GameVersion::WiiJpn, 0x1900},
});
DEFINE_MANT_ASSET(l_Egnd_mantTEX_U, u8, 0x4000, {
{GameVersion::GcnUsa, 0x5C00},
{GameVersion::GcnPal, 0x5C00},
{GameVersion::GcnJpn, 0x5C00},
{GameVersion::WiiUsaRev0, 0x5B00},
{GameVersion::WiiUsa, 0x5900},
{GameVersion::WiiPal, 0x5900},
{GameVersion::WiiJpn, 0x5900},
});
DEFINE_MANT_ASSET(l_Egnd_mantPAL, u8, 0x60, {
{GameVersion::GcnUsa, 0x9C00},
{GameVersion::GcnPal, 0x9C00},
{GameVersion::GcnJpn, 0x9C00},
{GameVersion::WiiUsaRev0, 0x9B00},
{GameVersion::WiiUsa, 0x9900},
{GameVersion::WiiPal, 0x9900},
{GameVersion::WiiJpn, 0x9900},
});
#define l_Egnd_mantTEX (l_Egnd_mantTEX_get())
#define l_Egnd_mantTEX_U (l_Egnd_mantTEX_U_get())
#define l_Egnd_mantPAL (l_Egnd_mantPAL_get())
@@ -35,14 +73,39 @@ static TGXTexObj mainTexObj;
static TGXTexObj undersideTexObj;
// l_pos is unused
//static f32* l_pos_get() { alignas(32) static f32 buf[507]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA44C}, {GameVersion::GcnPal, 0xA44C}}, sizeof(buf)), true); return buf; }
static f32* l_normal_get() { alignas(32) static f32 buf[3]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C60}, {GameVersion::GcnPal, 0x9C60}, {GameVersion::GcnJpn, 0x9C60}}, sizeof(buf)), true); return buf; }
static f32* l_texCoord_get() { alignas(32) static f32 buf[338]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA458}, {GameVersion::GcnPal, 0xA458}, {GameVersion::GcnJpn, 0xA458}}, sizeof(buf)), true); return buf; }
//#define l_pos (l_pos_get())
#define l_normal (l_normal_get())
// DEFINE_MANT_ASSET(l_pos, f32, 507, {
// {GameVersion::GcnUsa, 0x9C60},
// {GameVersion::GcnPal, 0x9C60},
// });
alignas(32) static f32 const l_normal[3] = {0.0f, 1.0f, 0.0f};
DEFINE_MANT_ASSET(l_texCoord, f32, 338, {
{GameVersion::GcnUsa, 0xA458},
{GameVersion::GcnPal, 0xA458},
{GameVersion::GcnJpn, 0xA458},
{GameVersion::WiiUsaRev0, 0x9B60},
{GameVersion::WiiUsa, 0x9960},
{GameVersion::WiiPal, 0x9960},
{GameVersion::WiiJpn, 0x9960},
});
// #define l_pos (l_pos_get())
#define l_texCoord (l_texCoord_get())
static bool l_Egnd_mantTEX_hasReplacement = false;
DEFINE_MANT_ASSET(l_Egnd_mantDL, u8, 0x3EC, {
{GameVersion::GcnUsa, 0xA9A0},
{GameVersion::GcnPal, 0xA9A0},
{GameVersion::GcnJpn, 0xA9A0},
{GameVersion::WiiUsaRev0, 0xA0C0},
{GameVersion::WiiUsa, 0x9EC0},
{GameVersion::WiiPal, 0x9EC0},
{GameVersion::WiiJpn, 0x9EC0},
});
#define l_Egnd_mantDL (l_Egnd_mantDL_get())
#else
#include "assets/l_Egnd_mantTEX.h"
@@ -52,16 +115,9 @@ static bool l_Egnd_mantTEX_hasReplacement = false;
#endif
#include "d/d_s_play.h"
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
static u8* l_Egnd_mantDL_get() { alignas(32) static u8 buf[0x3EC]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA9A0}, {GameVersion::GcnPal, 0xA9A0}, {GameVersion::GcnJpn, 0xA9A0}}, 0x3EC), true); return buf; }
#define l_Egnd_mantDL (l_Egnd_mantDL_get())
#else
#include "assets/l_Egnd_mantDL.h"
#endif
#if !TARGET_PC
#include "assets/l_Egnd_mantDL.h"
static void* pal_d = (void*)&l_Egnd_mantPAL;
static void* tex_d[2] = {
+3 -1
View File
@@ -1744,7 +1744,9 @@ int daNpc_Aru_c::cutSpeakTo(int i_staffID) {
switch (eventId) {
case 1:
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("goats_reward", itemNo, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, itemNo,
0, -1, -1, NULL, NULL DUSK_GIVE_TAG("goats_reward"));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
+3 -2
View File
@@ -1001,8 +1001,9 @@ BOOL daNpcAshB_c::EvCut_Appear(int i_staffID) {
case '0008':
local_30[0] = 0;
if (mFlow.getEventId(local_30) == 1) {
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, local_30[0], 0, -1, -1, 0, 0);
DUSK_ITEM_CHECK("ashei_sketch", local_30[0], this);
mItemPartnerId = fopAcM_createItemForPresentDemo(
&current.pos, local_30[0], 0, -1, -1, 0, 0 DUSK_GIVE_TAG("ashei_sketch"));
dComIfGp_event_setItemPartnerId(mItemPartnerId);
mItemPartnerId = -1;
}
+12 -1
View File
@@ -1804,8 +1804,19 @@ int daNpcChin_c::_Evt_GameSucceed_CutMain(const int& param_0) {
itemId1 = 0;
}
#if TARGET_PC
const char* itemCheckName = nullptr;
if (itemId1 == dItemNo_ARROW_LV2_e) {
itemCheckName = "star_reward_1";
} else if (itemId1 == dItemNo_ARROW_LV3_e) {
itemCheckName = "star_reward_2";
}
if (itemCheckName != nullptr) {
itemId1 = dusk::mods::item_check(itemCheckName, itemId1, this);
}
#endif
fpc_ProcID itemId2 = fopAcM_createItemForPresentDemo(&current.pos, itemId1, 0, -1, -1,
0, 0);
0, 0 IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
if (itemId2 != -1) {
dComIfGp_event_setItemPartnerId(itemId2);
}
+3 -1
View File
@@ -1333,7 +1333,9 @@ void daNpc_Fairy_c::PresentDemoCall() {
item_no = 0;
}
fpc_ProcID id = fopAcM_createItemForPresentDemo(&current.pos, item_no, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("fairy_reward:D_SB01", item_no, this);
fpc_ProcID id = fopAcM_createItemForPresentDemo(&current.pos, item_no, 0, -1, -1, NULL,
NULL DUSK_GIVE_TAG("fairy_reward:D_SB01"));
if (id != fpcM_ERROR_PROCESS_ID_e) {
dComIfGp_event_setItemPartnerId(id);
}
+9 -2
View File
@@ -4018,8 +4018,15 @@ BOOL daNpc_grA_c::talk(void*) {
}
if (r26 && talkProc(NULL, TRUE, NULL)) {
if (mFlow.getEventId(&sp8) == 1) {
field_0x1480 =
fopAcM_createItemForPresentDemo(&current.pos, sp8, 0, -1, -1, NULL, NULL);
#if TARGET_PC
const char* itemCheckName = nullptr;
if (sp8 == dItemNo_BOMB_IN_BAG_e) {
itemCheckName = "goron_reward:F_SP113";
sp8 = dusk::mods::item_check(itemCheckName, sp8, this);
}
#endif
field_0x1480 = fopAcM_createItemForPresentDemo(&current.pos, sp8, 0, -1, -1, NULL,
NULL IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
if (field_0x1480 != fpcM_ERROR_PROCESS_ID_e) {
s16 r25 = dComIfGp_getEventManager().getEventIdx(this, "DEFAULT_GETITEM", 0xff);
dComIfGp_getEvent()->reset(this);
+3 -1
View File
@@ -1681,7 +1681,9 @@ int daNpc_grO_c::talk(void* param_1) {
if (facePlayerFlag && talkProc(NULL, TRUE, NULL)) {
if (mType == TYPE_MINES) {
if (mFlow.getEventId(&itemId) == 1) {
mItemID = fopAcM_createItemForPresentDemo(&current.pos, itemId, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("key_shard_2:D_MN04", itemId, this);
mItemID = fopAcM_createItemForPresentDemo(&current.pos, itemId, 0, -1, -1,
NULL, NULL DUSK_GIVE_TAG("key_shard_2:D_MN04"));
if (mItemID != fpcM_ERROR_PROCESS_ID_e) {
s16 eventIdx = dComIfGp_getEventManager().getEventIdx(this, "DEFAULT_GETITEM", 0xFF);
dComIfGp_getEvent()->reset(this);
+3 -1
View File
@@ -1338,7 +1338,9 @@ int daNpc_grR_c::talk(void* param_1) {
if (bVar1 && talkProc(NULL, TRUE, NULL)) {
if (mType == TYPE_0) {
if (mFlow.getEventId(&i_itemNo) == 1) {
mItemID = fopAcM_createItemForPresentDemo(&current.pos, i_itemNo, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("key_shard_3:D_MN04", i_itemNo, this);
mItemID = fopAcM_createItemForPresentDemo(&current.pos, i_itemNo, 0, -1, -1,
NULL, NULL DUSK_GIVE_TAG("key_shard_3:D_MN04"));
if (mItemID != fpcM_ERROR_PROCESS_ID_e) {
s16 i_eventID = dComIfGp_getEventManager().getEventIdx(this, "DEFAULT_GETITEM", 0xFF);
+3 -2
View File
@@ -1190,8 +1190,9 @@ int daNpc_grS_c::talk(void* param_0) {
if (unkFlag1 && talkProc(NULL, 1, NULL)) {
if (mType == 0) {
if (mFlow.getEventId(&unkInt2) == 1) {
mPresentItemId =
fopAcM_createItemForPresentDemo(&current.pos, unkInt2, 0, -1, -1, 0, 0);
DUSK_ITEM_CHECK("key_shard_1:D_MN04", unkInt2, this);
mPresentItemId = fopAcM_createItemForPresentDemo(&current.pos, unkInt2, 0, -1,
-1, 0, 0 DUSK_GIVE_TAG("key_shard_1:D_MN04"));
if (mPresentItemId != fpcM_ERROR_PROCESS_ID_e) {
s16 eventIdx =
+6 -4
View File
@@ -971,8 +971,9 @@ BOOL daNpcImpal_c::EvCut_ImpalAppear1(int i_cut_index) {
if (talkProc(NULL, 1, NULL)) {
int evt_id = 0;
if (mFlow.getEventId(&evt_id) == 1) {
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, evt_id, 0, -1, -1, 0, 0);
DUSK_ITEM_CHECK("ilia_charm", evt_id, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(
&current.pos, evt_id, 0, -1, -1, 0, 0 DUSK_GIVE_TAG("ilia_charm"));
if (mItemPartnerId != 0xffffffff) {
s16 evt_idx =
dComIfGp_getEventManager().getEventIdx(this, "DEFAULT_GETITEM", 0xff);
@@ -1060,8 +1061,9 @@ BOOL daNpcImpal_c::EvCut_CopyRod(int i_cut_index) {
case '0003':
int evt_id = 0;
if (mFlow.getEventId(&evt_id) == 1) {
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, evt_id, 0, -1, -1, 0, 0);
DUSK_ITEM_CHECK("skybook", evt_id, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(
&current.pos, evt_id, 0, -1, -1, 0, 0 DUSK_GIVE_TAG("skybook"));
dComIfGp_event_setItemPartnerId(mItemPartnerId);
mItemPartnerId = -1;
}
+16 -1
View File
@@ -11,6 +11,10 @@
#include "d/d_msg_object.h"
#include <cstring>
#if TARGET_PC
static u8 s_givenInsectId = dItemNo_NONE_e;
#endif
enum Ins_RES_File_ID {
/* BCK */
/* 0x06 */ BCK_INS_F_HAPPY = 0x6,
@@ -1259,6 +1263,7 @@ int daNpcIns_c::waitPresent(void* param_1) {
daPy_py_c* player = daPy_getPlayerActorClass();
player->changeOriginalDemo();
player->changeDemoMode(0x25, 2, type, 0);
IF_DUSK(s_givenInsectId = type;)
} else {
mInsectMsgNo = 0x719;
}
@@ -1487,7 +1492,17 @@ int daNpcIns_c::talk(void* param_1) {
OS_REPORT("会話終了時 イベントID=%d アイテムNo=%d\n", eventID, itemNo);
if (eventID == 1) {
mItemID = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL, NULL);
#if TARGET_PC
u32 itemGiveTag = 0;
if (s_givenInsectId != dItemNo_NONE_e) {
itemNo = dusk::mods::item_check_bug(
s_givenInsectId, itemNo & 0xFF, this);
itemGiveTag = dusk::mods::item_give_tag_bug(s_givenInsectId);
s_givenInsectId = dItemNo_NONE_e;
}
#endif
mItemID = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1,
-1, NULL, NULL IF_DUSK_ARG(itemGiveTag));
if (mItemID != fpcM_ERROR_PROCESS_ID_e) {
daPy_getPlayerActorClass()->cancelOriginalDemo();
+10 -1
View File
@@ -1181,7 +1181,16 @@ int daNpc_Kkri_c::talk(void*) {
switch (eventId) {
case 1:
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, item_no, 0, -1, -1, NULL, NULL);
#if TARGET_PC
const char* itemCheckName = nullptr;
if (item_no == dItemNo_OIL_BOTTLE3_e) {
itemCheckName = "coro_bottle";
item_no = dusk::mods::item_check(itemCheckName, item_no, this);
}
#endif
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, item_no,
0, -1, -1, NULL,
NULL IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
+2 -1
View File
@@ -1236,8 +1236,9 @@ int daNpc_Len_c::talk(void* param_0) {
switch (evt_id) {
case 1:
if (mItemPartnerId == -1) {
DUSK_ITEM_CHECK("renado_letter", local_18, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, local_18,
0, -1, -1, 0, 0);
0, -1, -1, 0, 0 DUSK_GIVE_TAG("renado_letter"));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
mEvtNo = 1;
+4 -1
View File
@@ -2393,7 +2393,10 @@ int daNpc_Maro_c::cutArrowTutorial(int arg0) {
switch (evt_ret) {
case 1: {
if (mItemPartnerId == -1) {
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, evt_id, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("archery_reward:F_SP109", evt_id, this);
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, evt_id, 0, -1, -1,
NULL, NULL DUSK_GIVE_TAG("archery_reward:F_SP109"));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
+9 -1
View File
@@ -1191,7 +1191,15 @@ int daNpc_myna2_c::ECut_gameGoalSuccess(int i_staffId) {
case 20: {
int itemNo = 0;
if (mFlow.getEventId(&itemNo) == 1) {
mItemPid = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL, NULL);
#if TARGET_PC
const char* itemCheckName = nullptr;
if (itemNo == dItemNo_KAKERA_HEART_e) {
itemCheckName = "plumm_minigame_reward";
itemNo = dusk::mods::item_check(itemCheckName, itemNo, this);
}
#endif
mItemPid = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL,
NULL IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
}
break;
}
+12 -1
View File
@@ -958,8 +958,19 @@ int daNpc_Pouya_c::cutHaveFavorToAsk(int param_0) {
switch (evt_id) {
case 1:
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
#if TARGET_PC
const char* itemCheckName = nullptr;
if (local_64 == dItemNo_DROP_BOTTLE_e) {
itemCheckName = "jovani_reward_1";
} else if (local_64 == dItemNo_SILVER_RUPEE_e) {
itemCheckName = "jovani_reward_2";
}
if (itemCheckName != nullptr) {
local_64 = dusk::mods::item_check(itemCheckName, local_64, this);
}
#endif
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, local_64, 0,
-1, -1, 0, 0);
-1, -1, 0, 0 IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
field_0xfce = 1;
+2 -1
View File
@@ -720,7 +720,8 @@ fpc_ProcID daNpcPray_c::createHeart() {
mDoMtx_stack_c::ZXYrotS(rot);
mDoMtx_stack_c::multVec(&offset, &offset);
pos += offset;
return fopAcM_createItemForBoss(&pos, dItemNo_KAKERA_HEART_e, fopAcM_GetRoomNo(this), &rot, &size, 0.0f, 0.0f, 0);
return fopAcM_createItemForBoss(&pos, dItemNo_KAKERA_HEART_e, fopAcM_GetRoomNo(this), &rot,
&size, 0.0f, 0.0f, 0 IF_DUSK_ARG("prayer_reward"));
}
BOOL daNpcPray_c::_Evt_GetHeart(int i_staffID) {
+6 -2
View File
@@ -1310,7 +1310,9 @@ bool daNpcRafrel_c::talk(void* param_0) {
OS_REPORT("会話終了時 イベントID=%d アイテムNo=%d\n", eventId, itemNo);
if (eventId == 1) {
field_0xe00 = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("auru_memo", itemNo, this);
field_0xe00 = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1,
NULL, NULL DUSK_GIVE_TAG("auru_memo"));
if (field_0xe00 != fpcM_ERROR_PROCESS_ID_e) {
s16 eventIdx = dComIfGp_getEventManager().getEventIdx(this, "DEFAULT_GETITEM", 0xFF);
dComIfGp_getEvent()->reset(this);
@@ -1562,7 +1564,9 @@ int daNpcRafrel_c::EvCut_Appear(int i_staffId) {
int itemNo = 0;
u16 eventId = mFlow.getEventId(&itemNo);
if (eventId == 1) {
field_0xe00 = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("auru_memo", itemNo, this);
field_0xe00 = fopAcM_createItemForPresentDemo(
&current.pos, itemNo, 0, -1, -1, NULL, NULL DUSK_GIVE_TAG("auru_memo"));
dComIfGp_event_setItemPartnerId(field_0xe00);
field_0xe00 = fpcM_ERROR_PROCESS_ID_e;
}
+2 -1
View File
@@ -823,8 +823,9 @@ BOOL daNpcThe_c::talk(void* param_0) {
}
int item_no = 0;
if (mFlow.getEventId(&item_no) == 1) {
DUSK_ITEM_CHECK("telma_invoice", item_no, this);
mItemID = fopAcM_createItemForPresentDemo(&current.pos, item_no, 0, -1, -1,
NULL, NULL);
NULL, NULL DUSK_GIVE_TAG("telma_invoice"));
if (mItemID != -1) {
s16 event_id = dComIfGp_getEventManager().getEventIdx(
this, "DEFAULT_GETITEM", 0xff);
+3 -2
View File
@@ -1165,8 +1165,9 @@ int daNpc_Uri_c::cutEndCarryTutorial(int param_1) {
(s32)mFlow.getEventId(&local_48) == 1)
{
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, local_48, 0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("uli_cradle_reward", local_48, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, local_48, 0, -1, -1,
NULL, NULL DUSK_GIVE_TAG("uli_cradle_reward"));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
/* T_0007 - Ordon Village - During Uli's pick-up tutorial */
+6 -4
View File
@@ -2213,8 +2213,9 @@ int daNpc_ykW_c::cutEndSnowboardRace(int param_0) {
switch (eventId) {
case 1:
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, itemId, 0,
-1, -1, 0, 0);
DUSK_ITEM_CHECK("snowboard_race_reward", itemId, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, itemId, 0, -1,
-1, 0, 0 DUSK_GIVE_TAG("snowboard_race_reward"));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
@@ -2911,8 +2912,9 @@ int daNpc_ykW_c::talk(void* param_0) {
switch (eventId) {
case 1:
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, 0, 0);
DUSK_ITEM_CHECK("dungeon_map:D_MN11", itemNo, this);
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, itemNo,
0, -1, -1, 0, 0 DUSK_GIVE_TAG("dungeon_map:D_MN11"));
}
if (fopAcM_IsExecuting(mItemPartnerId)) {
+13 -2
View File
@@ -2609,8 +2609,19 @@ BOOL daNpc_zrA_c::ECut_thanksBlast(int i_staffID) {
case 31: {
int item_id = 0;
if (mFlow.getEventId(&item_id) == 1) {
mItemID = fopAcM_createItemForPresentDemo(&current.pos, item_id,
0, -1, -1, NULL, NULL);
#if TARGET_PC
const char* itemCheckName = nullptr;
if (item_id == dItemNo_BOMB_IN_BAG_e) {
itemCheckName = "iza_reward_1";
} else if (item_id == dItemNo_BOMB_BAG_LV2_e) {
itemCheckName = "iza_reward_2";
}
if (itemCheckName != nullptr) {
item_id = dusk::mods::item_check(itemCheckName, item_id, this);
}
#endif
mItemID = fopAcM_createItemForPresentDemo(&current.pos, item_id, 0, -1, -1, NULL,
NULL IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
}
field_0x9eb = true;
break;
+3 -2
View File
@@ -1681,8 +1681,9 @@ BOOL daNpc_zrC_c::ECut_earringGet(int i_staffID) {
case 40: {
int item_no = 0;
if (mFlow.getEventId(&item_no) == 1) {
mItemID = fopAcM_createItemForPresentDemo(&current.pos, item_no,
0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("coral_earring", item_no, this);
mItemID = fopAcM_createItemForPresentDemo(
&current.pos, item_no, 0, -1, -1, NULL, NULL DUSK_GIVE_TAG("coral_earring"));
}
break;
}
+3 -2
View File
@@ -1729,8 +1729,9 @@ BOOL daNpc_zrZ_c::ECut_clothesGet(int i_staffID) {
}
item_no = 0;
if (mFlow.getEventId(&item_no) == 1) {
mItemID = fopAcM_createItemForPresentDemo(&current.pos, item_no,
0, -1, -1, NULL, NULL);
DUSK_ITEM_CHECK("zora_armor", item_no, this);
mItemID = fopAcM_createItemForPresentDemo(
&current.pos, item_no, 0, -1, -1, NULL, NULL DUSK_GIVE_TAG("zora_armor"));
}
break;
+65 -14
View File
@@ -206,7 +206,7 @@ void daItem_c::CreateInit() {
initBaseMtx();
animPlay(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
if (m_itemNo == dItemNo_BOOMERANG_e) {
if (m_itemNo == dItemNo_BOOMERANG_e IF_DUSK(&&!mItemOverridden)) {
itemGetNextExecute();
} else if ((m_itemNo == dItemNo_ORANGE_RUPEE_e || m_itemNo == dItemNo_SILVER_RUPEE_e) &&
mSparkleEmtr.getEmitter() == NULL)
@@ -264,6 +264,17 @@ int daItem_c::_daItem_create() {
shape_angle.z = 0;
shape_angle.x = 0;
#if TARGET_PC
const u32 params = fopAcM_GetParam(this);
mOriginalItemNo = params & 0xFF;
const u8 resolvedItem = dusk::mods::item_check_freestanding(
daItem_prm::getItemBitNo(this), mOriginalItemNo, this);
mItemOverridden = resolvedItem != mOriginalItemNo;
mItemGiveTag = dusk::mods::item_give_tag_freestanding(daItem_prm::getItemBitNo(this));
if (mItemOverridden) {
fopAcM_SetParam(this, (params & 0xFFFFFF00) | resolvedItem);
}
#endif
field_0x95d = true;
}
@@ -507,9 +518,18 @@ void daItem_c::procInitGetDemoEvent() {
fopAcM_orderItemEvent(this, 0, 0);
eventInfo.onCondition(dEvtCnd_CANGETITEM_e);
m_item_id = fopAcM_createItemForTrBoxDemo(&current.pos, m_itemNo, -1, fopAcM_GetRoomNo(this),
NULL, NULL);
#if TARGET_PC
const u8 displayItemNo = m_itemNo;
if (mItemOverridden) {
m_itemNo = dusk::mods::item_check_tagged(mItemGiveTag, mOriginalItemNo, this);
}
#endif
m_item_id = fopAcM_createItemForTrBoxDemo(
&current.pos, m_itemNo, -1, fopAcM_GetRoomNo(this), NULL, NULL IF_DUSK_ARG(mItemGiveTag));
JUT_ASSERT(0, m_item_id != fpcM_ERROR_PROCESS_ID_e);
#if TARGET_PC
m_itemNo = displayItemNo;
#endif
setStatus(STATUS_WAIT_GET_DEMO_EVENT_e);
}
@@ -521,7 +541,7 @@ void daItem_c::procWaitGetDemoEvent() {
dComIfGp_event_setItemPartnerId(m_item_id);
}
} else {
if (m_itemNo == dItemNo_BOOMERANG_e) {
if (m_itemNo == dItemNo_BOOMERANG_e IF_DUSK(&&!mItemOverridden)) {
fopAcM_orderItemEvent(this, 0, 0);
eventInfo.onCondition(dEvtCnd_CANGETITEM_e);
return;
@@ -537,7 +557,9 @@ void daItem_c::procWaitGetDemoEvent() {
procInitSimpleGetDemo();
itemGet();
if (!haveItem) {
if (!haveItem IF_DUSK(&&(!mItemOverridden || (m_itemNo >= dItemNo_GREEN_RUPEE_e &&
m_itemNo <= dItemNo_SILVER_RUPEE_e))))
{
dComIfGs_offItemFirstBit(m_itemNo);
}
} else {
@@ -864,6 +886,12 @@ void daItem_c::itemGetNextExecute() {
procInitGetDemoEvent();
break;
default:
#if TARGET_PC
if (mItemOverridden) {
procInitGetDemoEvent();
break;
}
#endif
// "[daItem_c] Get process not defined[%d]\n"
OS_REPORT_ERROR("[daItem_c]ゲット処理が定義されていません[%d]\n", m_itemNo);
}
@@ -877,38 +905,48 @@ void daItem_c::itemGetNextExecute() {
}
void daItem_c::itemGet() {
#if TARGET_PC
const u8 displayItemNo = m_itemNo;
if (mItemOverridden) {
m_itemNo = dusk::mods::item_check_tagged(mItemGiveTag, mOriginalItemNo, this);
}
#endif
switch (m_itemNo) {
#if TARGET_PC
case dItemNo_UTAWA_HEART_e:
case dItemNo_KAKERA_HEART_e:
#endif
case dItemNo_HEART_e:
mDoAud_seStart(Z2SE_HEART_PIECE_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_GREEN_RUPEE_e:
mDoAud_seStart(Z2SE_GREEN_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_BLUE_RUPEE_e:
mDoAud_seStart(Z2SE_BLUE_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_YELLOW_RUPEE_e:
mDoAud_seStart(Z2SE_BLUE_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_RED_RUPEE_e:
mDoAud_seStart(Z2SE_RED_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_PURPLE_RUPEE_e:
mDoAud_seStart(Z2SE_RED_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_ORANGE_RUPEE_e:
mDoAud_seStart(Z2SE_RED_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_SILVER_RUPEE_e:
mDoAud_seStart(Z2SE_RED_LUPY_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
break;
case dItemNo_BOOMERANG_e:
break;
@@ -918,12 +956,25 @@ void daItem_c::itemGet() {
case dItemNo_ARROW_1_e:
case dItemNo_PACHINKO_SHOT_e:
mDoAud_seStart(Z2SE_CONSUMP_ITEM_GET, NULL, 0, 0);
execItemGet(m_itemNo);
execItemGet(m_itemNo IF_DUSK_ARG(mItemGiveTag) IF_DUSK_ARG(this));
#if TARGET_PC
break;
#endif
default:
#if TARGET_PC
if (mItemOverridden) {
mDoAud_seStart(Z2SE_CONSUMP_ITEM_GET, NULL, 0, 0);
execItemGet(m_itemNo, mItemGiveTag, this);
break;
}
#endif
// "[daItem_c] Get process not defined[%d]\n"
OS_REPORT_ERROR("[daItem_c]ゲット処理が定義されていません[%d]\n", m_itemNo);
break;
}
#if TARGET_PC
m_itemNo = displayItemNo;
#endif
}
BOOL daItem_c::checkCountTimer() {
+39 -2
View File
@@ -97,6 +97,12 @@ int daObjLife_c::Create() {
field_0x94c = 0.7f;
mRotateSpeed = 7000;
#if TARGET_PC
if (mOverrideHover) {
fopAcM_SetGravity(this, 0.0f);
mRotateSpeed = 550;
}
#endif
setEffect();
mSound.init(&current.pos, 1);
return 1;
@@ -140,6 +146,27 @@ int daObjLife_c::create() {
home.angle.x = home.angle.z = 0;
current.angle.x = current.angle.z = 0;
shape_angle.x = shape_angle.z = 0;
#if TARGET_PC
const u32 params = fopAcM_GetParam(this);
const u8 parameterItemNo = params & 0xFF;
if (mItemGiveOriginalNo == dItemNo_NONE_e) {
mOriginalItemNo = parameterItemNo;
const u8 resolvedItem =
dusk::mods::item_check_freestanding(getSaveBitNo(), mOriginalItemNo, this);
mItemGiveTag = dusk::mods::item_give_tag_freestanding(getSaveBitNo());
mItemOverridden = resolvedItem != mOriginalItemNo;
if (mItemOverridden) {
fopAcM_SetParam(this, (params & 0xFFFFFF00) | resolvedItem);
}
} else {
mOriginalItemNo = mItemGiveOriginalNo;
mItemOverridden = parameterItemNo != mItemGiveOriginalNo;
}
mOverrideHover =
mItemOverridden &&
(mOriginalItemNo == dItemNo_UTAWA_HEART_e ||
(mOriginalItemNo >= dItemNo_M_BEETLE_e && mOriginalItemNo <= dItemNo_F_MAYFLY_e));
#endif
mIsPrmsInit = true;
}
@@ -153,7 +180,7 @@ int daObjLife_c::create() {
return cPhs_ERROR_e;
}
if (m_itemNo == dItemNo_UTAWA_HEART_e && dComIfGs_isStageLife()) {
if (m_itemNo == dItemNo_UTAWA_HEART_e && dComIfGs_isStageLife() IF_DUSK(&&!mItemOverridden)) {
return cPhs_ERROR_e;
}
@@ -296,8 +323,18 @@ int daObjLife_c::initActionOrderGetDemo() {
fopAcM_orderItemEvent(this, 0, 0);
eventInfo.onCondition(dEvtCnd_CANGETITEM_e);
mItemId = fopAcM_createItemForTrBoxDemo(&current.pos, m_itemNo, -1, fopAcM_GetRoomNo(this), NULL, NULL);
#if TARGET_PC
const u8 displayItemNo = m_itemNo;
if (mItemOverridden) {
m_itemNo = dusk::mods::item_check_tagged(mItemGiveTag, mOriginalItemNo, this);
}
#endif
mItemId = fopAcM_createItemForTrBoxDemo(
&current.pos, m_itemNo, -1, fopAcM_GetRoomNo(this), NULL, NULL IF_DUSK_ARG(mItemGiveTag));
JUT_ASSERT(699, mItemId != fpcM_ERROR_PROCESS_ID_e);
#if TARGET_PC
m_itemNo = displayItemNo;
#endif
setStatus(STATUS_ORDER_GET_DEMO_e);
return 1;
+4 -2
View File
@@ -109,6 +109,7 @@ int daItemShield_c::__CreateHeap() {
int daItemShield_c::create() {
fopAcM_ct(this, daItemShield_c);
m_itemNo = dItemNo_WOOD_SHIELD_e;
DUSK_ITEM_CHECK("ordon_shield", m_itemNo, this);
if (fopAcM_isSwitch(this, getSwBit2())) {
OS_REPORT("木の盾:もう取ったので出ません\n");
return cPhs_ERROR_e;
@@ -240,8 +241,9 @@ int daItemShield_c::initActionOrderGetDemo() {
daItemBase_c::hide();
fopAcM_orderItemEvent(this, 0, 0);
eventInfo.onCondition(dEvtCnd_CANGETITEM_e);
mItemId =
fopAcM_createItemForTrBoxDemo(&current.pos, m_itemNo, -1, fopAcM_GetRoomNo(this), 0, 0);
mItemId = fopAcM_createItemForTrBoxDemo(&current.pos,
DUSK_ITEM_CHECK_EXPR("ordon_shield", dItemNo_WOOD_SHIELD_e, this), -1,
fopAcM_GetRoomNo(this), 0, 0 DUSK_GIVE_TAG("ordon_shield"));
JUT_ASSERT(682, mItemId != fpcM_ERROR_PROCESS_ID_e)
setStatus(STATUS_ORDERGETDEMO);
return 1;
+4 -2
View File
@@ -37,6 +37,7 @@ int daObjSword_c::Create() {
cPhs_Step daObjSword_c::create() {
fopAcM_ct(this, daObjSword_c);
m_itemNo = 0x28;
DUSK_ITEM_CHECK("ordon_sword", m_itemNo, this);
if (fopAcM_isItem(this, getItemBit())) {
return cPhs_ERROR_e;
}
@@ -71,8 +72,9 @@ int daObjSword_c::initActionOrderGetDemo() {
hide();
fopAcM_orderItemEvent(this, 0, 0);
eventInfo.onCondition(8);
mProcID = fopAcM_createItemForTrBoxDemo(&current.pos, m_itemNo, -1, fopAcM_GetRoomNo(this),
NULL, NULL);
mProcID =
fopAcM_createItemForTrBoxDemo(&current.pos, DUSK_ITEM_CHECK_EXPR("ordon_sword", 0x28, this),
-1, fopAcM_GetRoomNo(this), NULL, NULL DUSK_GIVE_TAG("ordon_sword"));
setStatus(1);
return 1;
}
+3 -2
View File
@@ -255,8 +255,9 @@ int daObjWStatue_c::initActionOrderGetDemo() {
s16 eventIdx = dComIfGp_getEventManager().getEventIdx(this, "DEFAULT_GETITEM", 0xff);
dComIfGp_getEvent()->reset(this);
fopAcM_orderChangeEventId(this, eventIdx, 1, 0xffff);
mItemId = fopAcM_createItemForTrBoxDemo(&current.pos, m_itemNo, 0xffffffff,
fopAcM_GetRoomNo(this), 0, 0);
mItemId = fopAcM_createItemForTrBoxDemo(&current.pos,
DUSK_ITEM_CHECK_EXPR("wood_statue", m_itemNo, this), 0xffffffff, fopAcM_GetRoomNo(this),
0, 0 DUSK_GIVE_TAG("wood_statue"));
JUT_ASSERT(544, mItemId != fpcM_ERROR_PROCESS_ID_e);
setStatus(STATUS_ORDER_GET_DEMO);
return 1;
+1
View File
@@ -32,6 +32,7 @@ int daObjZCloth_c::Create() {
int daObjZCloth_c::create() {
fopAcM_ct(this, daObjZCloth_c);
m_itemNo = 0x31;
DUSK_ITEM_CHECK("zora_armor", m_itemNo, this);
int phase = dComIfG_resLoad(&mPhase, dItem_data::getFieldArc(m_itemNo));
if (phase == cPhs_COMPLEATE_e) {
if (!fopAcM_entrySolidHeap(this, (heapCallbackFunc)CheckFieldItemCreateHeap, 0x2fb0)) {
+8 -4
View File
@@ -375,10 +375,14 @@ static const u8* l_sightDL_get() {
static bool _ = (
dusk::LoadDolAsset(
buf,
{
{GameVersion::GcnUsa, 0x803BA0C0},
{GameVersion::GcnPal, 0x803BBDA0},
{GameVersion::GcnJpn, 0x803B4220}
{
{GameVersion::GcnUsa, 0x803BA0C0},
{GameVersion::GcnPal, 0x803BBDA0},
{GameVersion::GcnJpn, 0x803B4220},
{GameVersion::WiiUsaRev0, 0x803F63C0},
{GameVersion::WiiUsa, 0x803E1640},
{GameVersion::WiiPal, 0x803E23A0},
{GameVersion::WiiJpn, 0x803DF600}
},
0x89
),
+59 -16
View File
@@ -11,6 +11,20 @@
#include "m_Do/m_Do_lib.h"
#include <cstring>
#if TARGET_PC
#include "d/d_item_data.h"
const ResourceData& daShopItem_c::getResourceData() const {
if (mItemOverridden) {
return mOverrideData;
}
return mData[mShopItemID];
}
#define SHOP_RESOURCE_DATA getResourceData()
#else
#define SHOP_RESOURCE_DATA mData[mShopItemID]
#endif
const char* daShopItem_c::getShopArcname() {
switch (m_itemNo) {
case dItemNo_NONE_e:
@@ -88,7 +102,29 @@ const char* daShopItem_c::getShopArcname() {
return NULL;
}
return mData[mShopItemID].get_arcName();
#if TARGET_PC
if (m_itemNo != dItemNo_NONE_e && mItemGiveOriginalNo == dItemNo_NONE_e) {
mItemGiveOriginalNo = m_itemNo;
const u8 resolvedItem = dusk::mods::item_check_shop(mItemGiveOriginalNo, this);
mItemOverridden = resolvedItem != mItemGiveOriginalNo;
if (mItemOverridden) {
mOverrideData = mData[mShopItemID];
mOverrideData.mArcName = dItem_data::getArcName(resolvedItem);
mOverrideData.mBmdName = dItem_data::getBmdName(resolvedItem);
mOverrideData.mBtkName = dItem_data::getBtkName(resolvedItem);
mOverrideData.mBckName = dItem_data::getBckName(resolvedItem);
mOverrideData.mBrkName = dItem_data::getBrkName(resolvedItem);
mOverrideData.mBtpName = dItem_data::getBtpName(resolvedItem);
mOverrideData.mTevFrm = dItem_data::getTevFrm(resolvedItem);
mOverrideData.mBtpFrm = -1;
mOverrideData.mFlag = static_cast<u32>(-1);
mOverrideData.mOffsetY = mShopItemID == SHOP_ITEMNO_ARMOR ? 60.0f : 15.0f;
mOverrideData.mScale = 1.0f;
}
}
#endif
return SHOP_RESOURCE_DATA.get_arcName();
}
DUSK_GAME_DATA const f32 daShopItem_c::m_cullfar_max = 5000.0f;
@@ -104,6 +140,11 @@ u16 daShopItem_c::getHeapSize() {
OS_REPORT("ShopItemID [%u]\n", a_ShopItemID);
ASSERT(a_ShopItemID < SHOP_ITEMNO_MAX);
#if TARGET_PC
if (mItemOverridden) {
return 0x8000;
}
#endif
return HeapSizeTbl[a_ShopItemID];
}
@@ -119,11 +160,11 @@ void daShopItem_c::CreateInit() {
if (strcmp("R_SP109", dComIfGp_getStartStageName()) == 0 && dComIfGp_getStartStageRoomNo() == 1)
{
scale.set(mData[mShopItemID].get_scale() * 0.8f, mData[mShopItemID].get_scale() * 0.8f,
mData[mShopItemID].get_scale() * 0.8f);
scale.set(SHOP_RESOURCE_DATA.get_scale() * 0.8f, SHOP_RESOURCE_DATA.get_scale() * 0.8f,
SHOP_RESOURCE_DATA.get_scale() * 0.8f);
} else {
scale.set(mData[mShopItemID].get_scale(), mData[mShopItemID].get_scale(),
mData[mShopItemID].get_scale());
scale.set(SHOP_RESOURCE_DATA.get_scale(), SHOP_RESOURCE_DATA.get_scale(),
SHOP_RESOURCE_DATA.get_scale());
}
home.pos = current.pos;
@@ -137,8 +178,8 @@ void daShopItem_c::set_mtx() {
if (daShopItem_prm::getGroup(this) == 15) {
mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z);
} else {
mDoMtx_stack_c::transS(current.pos.x, current.pos.y + mData[mShopItemID].get_offsetY(),
current.pos.z);
mDoMtx_stack_c::transS(
current.pos.x, current.pos.y + SHOP_RESOURCE_DATA.get_offsetY(), current.pos.z);
}
MTXCopy(mDoMtx_stack_c::get(), mMtx);
@@ -147,8 +188,8 @@ void daShopItem_c::set_mtx() {
if (daShopItem_prm::getGroup(this) == 15) {
mDoMtx_stack_c::ZXYrotM(-11300, 32700, 7300);
} else {
mDoMtx_stack_c::ZXYrotM(mAngleX + mData[mShopItemID].get_angleX(),
mData[mShopItemID].get_angleY(), mData[mShopItemID].get_angleZ());
mDoMtx_stack_c::ZXYrotM(mAngleX + SHOP_RESOURCE_DATA.get_angleX(),
SHOP_RESOURCE_DATA.get_angleY(), SHOP_RESOURCE_DATA.get_angleZ());
}
mDoMtx_stack_c::ZXYrotM(current.angle.x, current.angle.y, current.angle.z);
@@ -156,7 +197,7 @@ void daShopItem_c::set_mtx() {
if (daShopItem_prm::getGroup(this) == 15) {
mDoMtx_stack_c::XrotM(0);
} else {
mDoMtx_stack_c::XrotM(mData[mShopItemID].get_angleOffsetX());
mDoMtx_stack_c::XrotM(SHOP_RESOURCE_DATA.get_angleOffsetX());
}
mpModel->setBaseTRMtx(mDoMtx_stack_c::get());
@@ -190,29 +231,31 @@ void daShopItem_c::setShadow() {
}
BOOL daShopItem_c::chkFlag(int i_flag) {
return mData[mShopItemID].get_flag() & i_flag;
return SHOP_RESOURCE_DATA.get_flag() & i_flag;
}
s8 daShopItem_c::getTevFrm() {
return mData[mShopItemID].get_tevfrm();
return SHOP_RESOURCE_DATA.get_tevfrm();
}
s8 daShopItem_c::getBtpFrm() {
return mData[mShopItemID].get_btpfrm();
return SHOP_RESOURCE_DATA.get_btpfrm();
}
u8 daShopItem_c::getShadowSize() {
return mData[mShopItemID].get_shadowSize();
return SHOP_RESOURCE_DATA.get_shadowSize();
}
u8 daShopItem_c::getCollisionH() {
return mData[mShopItemID].get_collisionH();
return SHOP_RESOURCE_DATA.get_collisionH();
}
u8 daShopItem_c::getCollisionR() {
return mData[mShopItemID].get_collisionR();
return SHOP_RESOURCE_DATA.get_collisionR();
}
#undef SHOP_RESOURCE_DATA
int daShopItem_c::_create() {
fopAcM_ct(this, daShopItem_c);
+5 -3
View File
@@ -362,9 +362,11 @@ int daTagStatue_c::demoProc() {
item = dItemNo_AIR_LETTER_e;
}
mItemId =
fopAcM_createItemForTrBoxDemo(&current.pos, item, -1,
fopAcM_GetRoomNo(this), 0, 0);
#if TARGET_PC
item = dusk::mods::item_check_sky_character(item & 0xFF, this);
#endif
mItemId = fopAcM_createItemForTrBoxDemo(&current.pos, item, -1,
fopAcM_GetRoomNo(this), 0, 0 IF_DUSK_ARG(dusk::mods::item_give_tag_sky_character()));
JUT_ASSERT(580, mItemId != fpcM_ERROR_PROCESS_ID_e);
+13 -2
View File
@@ -1390,6 +1390,10 @@ u8 daTbox_c::getBombItemNoMain(u8 i_itemNo) {
int daTbox_c::setGetDemoItem() {
u8 item_no = getItemNo();
#if TARGET_PC
const u32 giveTag = dusk::mods::item_give_tag_chest(getTboxNo());
item_no = dusk::mods::item_check_tagged(giveTag, mOriginalItemNo, this);
#endif
if (item_no == dItemNo_BOMB_5_e || item_no == dItemNo_BOMB_10_e || item_no == dItemNo_BOMB_20_e || item_no == dItemNo_BOMB_30_e ||
item_no == dItemNo_WATER_BOMB_5_e || item_no == dItemNo_WATER_BOMB_10_e || item_no == dItemNo_WATER_BOMB_20_e || item_no == dItemNo_WATER_BOMB_30_e ||
item_no == dItemNo_BOMB_INSECT_5_e || item_no == dItemNo_BOMB_INSECT_10_e || item_no == dItemNo_BOMB_INSECT_20_e || item_no == dItemNo_BOMB_INSECT_30_e)
@@ -1399,9 +1403,11 @@ int daTbox_c::setGetDemoItem() {
fpc_ProcID item_id;
if (field_0x718) {
item_id = fopAcM_createItemForPresentDemo(&current.pos, item_no, 1, -1, -1, NULL, NULL);
item_id = fopAcM_createItemForPresentDemo(
&current.pos, item_no, 1, -1, -1, NULL, NULL IF_DUSK_ARG(giveTag));
} else {
item_id = fopAcM_createItemForTrBoxDemo(&current.pos, item_no, -1, -1, NULL, NULL);
item_id = fopAcM_createItemForTrBoxDemo(
&current.pos, item_no, -1, -1, NULL, NULL IF_DUSK_ARG(giveTag));
}
if (item_id != fpcM_ERROR_PROCESS_ID_e) {
@@ -1785,6 +1791,11 @@ void daTbox_c::mode_exec() {
cPhs_Step daTbox_c::create1st() {
if (!mParamsInit) {
field_0x980 = home.angle.x;
#if TARGET_PC
mOriginalItemNo = (home.angle.z >> 8) & 0xFF;
const u8 resolvedItem = dusk::mods::item_check_chest(getTboxNo(), mOriginalItemNo, this);
home.angle.z = static_cast<s16>((home.angle.z & ~0xFF00) | (resolvedItem << 8));
#endif
field_0x982 = home.angle.z;
home.angle.z = 0;
home.angle.x = 0;
+18 -2
View File
@@ -138,6 +138,17 @@ int daTbox2_c::create1st() {
fopAcM_ct(this, daTbox2_c);
mModelType = getModelType();
#if TARGET_PC
if (!mParamsInit) {
mOriginalItemNo = getItemNo();
int tboxNo = fopAcM_GetParamBit(this, 16, 8);
const u8 resolvedItem = dusk::mods::item_check_chest(tboxNo, mOriginalItemNo, this);
u32 params = (fopAcM_GetParam(this) & 0xFFFFFF00) | resolvedItem;
fopAcM_SetParam(this, params);
mParamsInit = true;
}
#endif
int phase_state = dComIfG_resLoad(&mPhase, l_arcName);
if (phase_state == cPhs_COMPLEATE_e) {
u32 heap_size;
@@ -370,12 +381,17 @@ void daTbox2_c::actionOpenWait() {
int daTbox2_c::setGetDemoItem() {
u8 item_no = getItemNo();
#if TARGET_PC
int tboxNo = fopAcM_GetParamBit(this, 16, 8);
const u32 giveTag = dusk::mods::item_give_tag_chest(tboxNo);
item_no = dusk::mods::item_check_tagged(giveTag, mOriginalItemNo, this);
#endif
u32 partner_id;
if (mReturnRupee) {
partner_id = fopAcM_createItemForPresentDemo(&current.pos, item_no, 1, -1, -1, NULL, NULL);
partner_id = fopAcM_createItemForPresentDemo(&current.pos, item_no, 1, -1, -1, NULL, NULL IF_DUSK_ARG(giveTag));
} else {
partner_id = fopAcM_createItemForTrBoxDemo(&current.pos, item_no, -1, -1, NULL, NULL);
partner_id = fopAcM_createItemForTrBoxDemo(&current.pos, item_no, -1, -1, NULL, NULL IF_DUSK_ARG(giveTag));
}
if (partner_id != -1) {
+1 -1
View File
@@ -52,7 +52,7 @@ static u8 const lit_3772[12] = {
#if TARGET_PC
using namespace dusk::version;
#define l_arcName versionSelect<const char*>({{GameVersion::GcnPal, "TitlePal"}}, "Title")
#define l_arcName regionSelect<const char*>("Title", "TitlePal", "Title")
#elif VERSION == VERSION_GCN_PAL
static char const l_arcName[] = "TitlePal";
#else
+108 -16
View File
@@ -11,9 +11,16 @@ const u16 l_J_Ohana00_64TEX__width = 63;
const u16 l_J_Ohana00_64TEX__height = 63;
#if TARGET_PC
#include "dusk/dvd_asset.hpp"
using GameVersion = dusk::version::GameVersion;
static u8* l_J_Ohana00_64TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9060}, {GameVersion::GcnPal, 0x9060}, {GameVersion::GcnJpn, 0x9060}}, 0x800), true); return buf; }
DEFINE_GRASS_ASSET(l_J_Ohana00_64TEX, u8, 0x800, {
{GameVersion::GcnUsa, 0x9060},
{GameVersion::GcnPal, 0x9060},
{GameVersion::GcnJpn, 0x9060},
{GameVersion::WiiUsaRev0, 0x7B60},
{GameVersion::WiiUsa, 0x7BC0},
{GameVersion::WiiPal, 0x7BC0},
{GameVersion::WiiJpn, 0x7BC0},
});
#define l_J_Ohana00_64TEX (l_J_Ohana00_64TEX_get())
// from d_grass.inc
@@ -115,12 +122,46 @@ static u8 l_flowerTexCoord[] = {
0x3E, 0xA7, 0x72, 0xD6, 0xBD, 0x2F, 0x46, 0xAA};
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
DEFINE_GRASS_ASSET(l_J_hana00DL, u8, 0x150, {
{GameVersion::GcnUsa, 0x9D20},
{GameVersion::GcnPal, 0x9D20},
{GameVersion::GcnJpn, 0x9D20},
{GameVersion::WiiUsaRev0, 0x8820},
{GameVersion::WiiUsa, 0x8880},
{GameVersion::WiiPal, 0x8880},
{GameVersion::WiiJpn, 0x8880},
});
DEFINE_GRASS_ASSET(l_J_hana00_cDL, u8, 0xDE, {
{GameVersion::GcnUsa, 0x9E80},
{GameVersion::GcnPal, 0x9E80},
{GameVersion::GcnJpn, 0x9E80},
{GameVersion::WiiUsaRev0, 0x8980},
{GameVersion::WiiUsa, 0x89E0},
{GameVersion::WiiPal, 0x89E0},
{GameVersion::WiiJpn, 0x89E0},
});
DEFINE_GRASS_ASSET(l_matDL, u8, 0x99, {
{GameVersion::GcnUsa, 0x9F60},
{GameVersion::GcnPal, 0x9F60},
{GameVersion::GcnJpn, 0x9F60},
{GameVersion::WiiUsaRev0, 0x8A60},
{GameVersion::WiiUsa, 0x8AC0},
{GameVersion::WiiPal, 0x8AC0},
{GameVersion::WiiJpn, 0x8AC0},
});
DEFINE_GRASS_ASSET(l_matLight4DL, u8, 0x99, {
{GameVersion::GcnUsa, 0xA000},
{GameVersion::GcnPal, 0xA000},
{GameVersion::GcnJpn, 0xA000},
{GameVersion::WiiUsaRev0, 0x8B00},
{GameVersion::WiiUsa, 0x8B60},
{GameVersion::WiiPal, 0x8B60},
{GameVersion::WiiJpn, 0x8B60},
});
static u8* l_J_hana00DL_get() { static u8 buf[0x150]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9D20}, {GameVersion::GcnPal, 0x9D20}, {GameVersion::GcnJpn, 0x9D20}}, 0x150), true); return buf; }
static u8* l_J_hana00_cDL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9E80}, {GameVersion::GcnPal, 0x9E80}, {GameVersion::GcnJpn, 0x9E80}}, 0xDE), true); return buf; }
static u8* l_matDL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9F60}, {GameVersion::GcnPal, 0x9F60}, {GameVersion::GcnJpn, 0x9F60}}, 0x99), true); return buf; }
static u8* l_matLight4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xA000}, {GameVersion::GcnPal, 0xA000}, {GameVersion::GcnJpn, 0xA000}}, 0x99), true); return buf; }
#define l_J_hana00DL (l_J_hana00DL_get())
#define l_J_hana00_cDL (l_J_hana00_cDL_get())
#define l_matDL (l_matDL_get())
@@ -141,8 +182,16 @@ const u16 l_J_Ohana01_64128_0419TEX__width = 63;
const u16 l_J_Ohana01_64128_0419TEX__height = 127;
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
static u8* l_J_Ohana01_64128_0419TEX_get() { static u8 buf[0x1000]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xA0A0}, {GameVersion::GcnPal, 0xA0A0}, {GameVersion::GcnJpn, 0xA0A0}}, 0x1000), true); return buf; }
DEFINE_GRASS_ASSET(l_J_Ohana01_64128_0419TEX, u8, 0x1000, {
{GameVersion::GcnUsa, 0xA0A0},
{GameVersion::GcnPal, 0xA0A0},
{GameVersion::GcnJpn, 0xA0A0},
{GameVersion::WiiUsaRev0, 0x8BA0},
{GameVersion::WiiUsa, 0x8C00},
{GameVersion::WiiPal, 0x8C00},
{GameVersion::WiiJpn, 0x8C00},
});
#define l_J_Ohana01_64128_0419TEX (l_J_Ohana01_64128_0419TEX_get())
#else
#include "assets/l_J_Ohana01_64128_0419TEX.h"
@@ -274,13 +323,56 @@ static u8 l_flowerTexCoord2[] = {
0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x80, 0x3F, 0x79, 0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x51, 0x10, 0x6F};
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
DEFINE_GRASS_ASSET(l_J_hana01DL, u8, 0x138, {
{GameVersion::GcnUsa, 0xB7C0},
{GameVersion::GcnPal, 0xB7C0},
{GameVersion::GcnJpn, 0xB7C0},
{GameVersion::WiiUsaRev0, 0xA2C0},
{GameVersion::WiiUsa, 0xA320},
{GameVersion::WiiPal, 0xA320},
{GameVersion::WiiJpn, 0xA320},
});
DEFINE_GRASS_ASSET(l_J_hana01_c_00DL, u8, 0xDE, {
{GameVersion::GcnUsa, 0xB900},
{GameVersion::GcnPal, 0xB900},
{GameVersion::GcnJpn, 0xB900},
{GameVersion::WiiUsaRev0, 0xA400},
{GameVersion::WiiUsa, 0xA460},
{GameVersion::WiiPal, 0xA460},
{GameVersion::WiiJpn, 0xA460},
});
DEFINE_GRASS_ASSET(l_J_hana01_c_01DL, u8, 0x128, {
{GameVersion::GcnUsa, 0xB9E0},
{GameVersion::GcnPal, 0xB9E0},
{GameVersion::GcnJpn, 0xB9E0},
{GameVersion::WiiUsaRev0, 0xA4E0},
{GameVersion::WiiUsa, 0xA540},
{GameVersion::WiiPal, 0xA540},
{GameVersion::WiiJpn, 0xA540},
});
DEFINE_GRASS_ASSET(l_mat2DL, u8, 0x99, {
{GameVersion::GcnUsa, 0xBB20},
{GameVersion::GcnPal, 0xBB20},
{GameVersion::GcnJpn, 0xBB20},
{GameVersion::WiiUsaRev0, 0xA620},
{GameVersion::WiiUsa, 0xA680},
{GameVersion::WiiPal, 0xA680},
{GameVersion::WiiJpn, 0xA680},
});
DEFINE_GRASS_ASSET(l_mat2Light4DL, u8, 0x99, {
{GameVersion::GcnUsa, 0xBBC0},
{GameVersion::GcnPal, 0xBBC0},
{GameVersion::GcnJpn, 0xBBC0},
{GameVersion::WiiUsaRev0, 0xA6C0},
{GameVersion::WiiUsa, 0xA720},
{GameVersion::WiiPal, 0xA720},
{GameVersion::WiiJpn, 0xA720},
});
static u8* l_J_hana01DL_get() { static u8 buf[0x138]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB7C0}, {GameVersion::GcnPal, 0xB7C0}, {GameVersion::GcnJpn, 0xB7C0}}, 0x138), true); return buf; }
static u8* l_J_hana01_c_00DL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB900}, {GameVersion::GcnPal, 0xB900}, {GameVersion::GcnJpn, 0xB900}}, 0xDE), true); return buf; }
static u8* l_J_hana01_c_01DL_get() { static u8 buf[0x128]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB9E0}, {GameVersion::GcnPal, 0xB9E0}, {GameVersion::GcnJpn, 0xB9E0}}, 0x128), true); return buf; }
static u8* l_mat2DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBB20}, {GameVersion::GcnPal, 0xBB20}, {GameVersion::GcnJpn, 0xBB20}}, 0x99), true); return buf; }
static u8* l_mat2Light4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBBC0}, {GameVersion::GcnPal, 0xBBC0}, {GameVersion::GcnJpn, 0xBBC0}}, 0x99), true); return buf; }
#define l_J_hana01DL (l_J_hana01DL_get())
#define l_J_hana01_c_00DL (l_J_hana01_c_00DL_get())
#define l_J_hana01_c_01DL (l_J_hana01_c_01DL_get())
+92 -9
View File
@@ -21,8 +21,39 @@ const u16 l_M_kusa05_RGBATEX__height = 31;
#if TARGET_PC
#include "dusk/dvd_asset.hpp"
using GameVersion = dusk::version::GameVersion;
static u8* l_M_kusa05_RGBATEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7680}, {GameVersion::GcnPal, 0x7680}, {GameVersion::GcnJpn, 0x7680}}, 0x800), true); return buf; }
static u8* l_M_Hijiki00TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7E80}, {GameVersion::GcnPal, 0x7E80}, {GameVersion::GcnJpn, 0x7E80}}, 0x800), true); return buf; }
template <typename T, size_t N>
static bool LoadGrassAsset(T (&dst)[N], std::initializer_list<dusk::OffsetVersion> offset) {
return dusk::LoadArchivedRelAsset(dst, 'AMEM', "d_a_grass.rel", offset);
}
#define DEFINE_GRASS_ASSET(name, type, count, ...) \
static type* name##_get() { \
static type buf[count]; \
static bool _ = (LoadGrassAsset(buf, __VA_ARGS__), true); \
return buf; \
}
DEFINE_GRASS_ASSET(l_M_kusa05_RGBATEX, u8, 0x800, {
{GameVersion::GcnUsa, 0x7680},
{GameVersion::GcnPal, 0x7680},
{GameVersion::GcnJpn, 0x7680},
{GameVersion::WiiUsaRev0, 0x6180},
{GameVersion::WiiUsa, 0x61E0},
{GameVersion::WiiPal, 0x61E0},
{GameVersion::WiiJpn, 0x61E0},
});
DEFINE_GRASS_ASSET(l_M_Hijiki00TEX, u8, 0x800, {
{GameVersion::GcnUsa, 0x7E80},
{GameVersion::GcnPal, 0x7E80},
{GameVersion::GcnJpn, 0x7E80},
{GameVersion::WiiUsaRev0, 0x6980},
{GameVersion::WiiUsa, 0x69E0},
{GameVersion::WiiPal, 0x69E0},
{GameVersion::WiiJpn, 0x69E0},
});
#define l_M_kusa05_RGBATEX (l_M_kusa05_RGBATEX_get())
#define l_M_Hijiki00TEX (l_M_Hijiki00TEX_get())
#else
@@ -114,14 +145,66 @@ static u8 l_texCoord[160] = {
};
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
DEFINE_GRASS_ASSET(l_M_Kusa_9qDL, u8, 0xCB, {
{GameVersion::GcnUsa, 0x8B00},
{GameVersion::GcnPal, 0x8B00},
{GameVersion::GcnJpn, 0x8B00},
{GameVersion::WiiUsaRev0, 0x7600},
{GameVersion::WiiUsa, 0x7660},
{GameVersion::WiiPal, 0x7660},
{GameVersion::WiiJpn, 0x7660},
});
DEFINE_GRASS_ASSET(l_M_Kusa_9q_cDL, u8, 0xCB, {
{GameVersion::GcnUsa, 0x8BE0},
{GameVersion::GcnPal, 0x8BE0},
{GameVersion::GcnJpn, 0x8BE0},
{GameVersion::WiiUsaRev0, 0x76E0},
{GameVersion::WiiUsa, 0x7740},
{GameVersion::WiiPal, 0x7740},
{GameVersion::WiiJpn, 0x7740},
});
DEFINE_GRASS_ASSET(l_M_TenGusaDL, u8, 0xD4, {
{GameVersion::GcnUsa, 0x8CC0},
{GameVersion::GcnPal, 0x8CC0},
{GameVersion::GcnJpn, 0x8CC0},
{GameVersion::WiiUsaRev0, 0x77C0},
{GameVersion::WiiUsa, 0x7820},
{GameVersion::WiiPal, 0x7820},
{GameVersion::WiiJpn, 0x7820},
});
DEFINE_GRASS_ASSET(l_Tengusa_matDL, u8, 0xA8, {
{GameVersion::GcnUsa, 0x8DA0},
{GameVersion::GcnPal, 0x8DA0},
{GameVersion::GcnJpn, 0x8DA0},
{GameVersion::WiiUsaRev0, 0x78A0},
{GameVersion::WiiUsa, 0x7900},
{GameVersion::WiiPal, 0x7900},
{GameVersion::WiiJpn, 0x7900},
});
DEFINE_GRASS_ASSET(l_kusa9q_matDL, u8, 0xA8, {
{GameVersion::GcnUsa, 0x8E60},
{GameVersion::GcnPal, 0x8E60},
{GameVersion::GcnJpn, 0x8E60},
{GameVersion::WiiUsaRev0, 0x7960},
{GameVersion::WiiUsa, 0x79C0},
{GameVersion::WiiPal, 0x79C0},
{GameVersion::WiiJpn, 0x79C0},
});
DEFINE_GRASS_ASSET(l_kusa9q_l4_matDL, u8, 0xA8, {
{GameVersion::GcnUsa, 0x8F20},
{GameVersion::GcnPal, 0x8F20},
{GameVersion::GcnJpn, 0x8F20},
{GameVersion::WiiUsaRev0, 0x7A20},
{GameVersion::WiiUsa, 0x7A80},
{GameVersion::WiiPal, 0x7A80},
{GameVersion::WiiJpn, 0x7A80},
});
static u8* l_M_Kusa_9qDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8B00}, {GameVersion::GcnPal, 0x8B00}, {GameVersion::GcnJpn, 0x8B00}}, 0xCB), true); return buf; }
static u8* l_M_Kusa_9q_cDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8BE0}, {GameVersion::GcnPal, 0x8BE0}, {GameVersion::GcnJpn, 0x8BE0}}, 0xCB), true); return buf; }
static u8* l_M_TenGusaDL_get() { static u8 buf[0xD4]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8CC0}, {GameVersion::GcnPal, 0x8CC0}, {GameVersion::GcnJpn, 0x8CC0}}, 0xD4), true); return buf; }
static u8* l_Tengusa_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8DA0}, {GameVersion::GcnPal, 0x8DA0}, {GameVersion::GcnJpn, 0x8DA0}}, 0xA8), true); return buf; }
static u8* l_kusa9q_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8E60}, {GameVersion::GcnPal, 0x8E60}, {GameVersion::GcnJpn, 0x8E60}}, 0xA8), true); return buf; }
static u8* l_kusa9q_l4_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8F20}, {GameVersion::GcnPal, 0x8F20}, {GameVersion::GcnJpn, 0x8F20}}, 0xA8), true); return buf; }
#define l_M_Kusa_9qDL (l_M_Kusa_9qDL_get())
#define l_M_Kusa_9q_cDL (l_M_Kusa_9q_cDL_get())
#define l_M_TenGusaDL (l_M_TenGusaDL_get())
+7
View File
@@ -45,6 +45,12 @@ int CheckShopItemCreateHeap(fopAc_ac_c* i_this) {
daShopItem_c* a_this1 = static_cast<daShopItem_c*>(i_this);
daShopItem_c* a_this2 = static_cast<daShopItem_c*>(i_this);
#if TARGET_PC
const ResourceData& data = a_this2->getResourceData();
return a_this1->CreateItemHeap(data.get_arcName(), data.get_bmdName(), data.get_btk1Name(),
data.get_bpk1Name(), data.get_bck1Name(), data.get_bxa1Name(), data.get_brk1Name(),
data.get_btp1Name());
#else
u8 a_ShopItemID = a_this2->getShopItemID();
return a_this1->CreateItemHeap(daShopItem_c::mData[a_ShopItemID].get_arcName(),
daShopItem_c::mData[a_ShopItemID].get_bmdName(),
@@ -54,4 +60,5 @@ int CheckShopItemCreateHeap(fopAc_ac_c* i_this) {
daShopItem_c::mData[a_ShopItemID].get_bxa1Name(),
daShopItem_c::mData[a_ShopItemID].get_brk1Name(),
daShopItem_c::mData[a_ShopItemID].get_btp1Name());
#endif
}
+9 -3
View File
@@ -87,7 +87,9 @@ void dBrightCheck_c::screenSet() {
JUT_ASSERT(0, mBrightCheck.Scr != NULL);
mBrightCheck.Scr->setPriority("zelda_option_check.blo", 0x1100000, mArchive);
IF_DUSK_BLOCK(dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn)
mBrightCheck.Scr->search(MULTI_CHAR('g_abtn_n'))->hide();
IF_DUSK_BLOCK_END
#if TARGET_PC
J2DTextBox* settings_text;
@@ -117,9 +119,11 @@ void dBrightCheck_c::screenSet() {
J2DTextBox* btna_text[5];
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
btna_text[i] = (J2DTextBox*)mBrightCheck.Scr->search(tv_btnA[i]);
mBrightCheck.Scr->search(ftv_btnA[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mBrightCheck.Scr->search(ftv_btnA[i])->hide();
}
} else {
btna_text[i] = (J2DTextBox*)mBrightCheck.Scr->search(ftv_btnA[i]);
mBrightCheck.Scr->search(tv_btnA[i])->hide();
@@ -217,7 +221,9 @@ void dBrightCheck_c::brightCheckWide() {
// Confirm A Button
mBrightCheck.Scr->search(MULTI_CHAR('abtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('gcabtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mBrightCheck.Scr->search(MULTI_CHAR('gcabtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
}
// Text
mBrightCheck.Scr->search(MULTI_CHAR('menu_6n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
+8
View File
@@ -335,6 +335,14 @@ bool dEvent_manager_c::setObjectArchive(DUSK_CONST char* arcname) {
if (arcname != NULL) {
rt = dComIfG_getObjectRes(arcname, DataFileName);
#if TARGET_PC
if (rt != nullptr && strcmp(arcname, "Prayer") == 0) {
// pointer to Prayer event `011get_item` prm0 in it's event_list.dat
u8* itemNo = static_cast<u8*>(rt) + 0x927;
*itemNo =
dusk::mods::item_check("prayer_reward", dItemNo_KAKERA_HEART_e, NULL);
}
#endif
int base_status = mEventList[BASE_ACTOR].init((char*)rt, -1);
#if DEBUG
+2 -1
View File
@@ -274,8 +274,9 @@ inline void getItemFunc(u8 i_itemNo) {
item_func_ptr[i_itemNo]();
}
void execItemGet(u8 i_itemNo) {
void execItemGet(u8 i_itemNo IF_DUSK_ARG(u32 i_itemGiveTag) IF_DUSK_ARG(fopAc_ac_c* i_giver)) {
getItemFunc(i_itemNo);
IF_DUSK(dusk::mods::item_granted(i_itemNo, i_itemGiveTag, i_giver);)
}
static int (*item_getcheck_func_ptr[256])() = {
+1 -1
View File
@@ -2346,7 +2346,7 @@ void dScnKy_env_light_c::setLight() {
u8 next_pal_end_id;
#if TARGET_PC
const f32 deltaTime = dusk::game_clock::consume_interval(this);
timeScale = deltaTime / dusk::game_clock::period_for_original_frames(1.0f);
timeScale = deltaTime / dusk::game_clock::kSimPeriod;
#endif
setLight_palno_get(&g_env_light.PrevCol, &g_env_light.UseCol, &g_env_light.wether_pat0,
&g_env_light.wether_pat1, &prev_pal_start_id, &prev_pal_end_id,
+1 -1
View File
@@ -118,7 +118,7 @@ static int dKyeff_Create(kankyo_class* i_this) {
if (strcmp(dComIfGp_getStartStageName(), "Name") == 0) {
camera_process_class* camera = dComIfGp_getCamera(0);
OSTime time = OSGetTime();
OSTime time = DUSK_IF_ELSE(OSGetSystemTime(), OSGetTime());
OSTicksToCalendarTime(time, &calendar);
g_env_light.global_wind_influence.vec.x = 1.0f;
+3 -128
View File
@@ -16,23 +16,14 @@
#ifdef TARGET_PC
#include "dusk/settings.h"
#include "dusk/hq_minimap.hpp"
#include "m_Do/m_Do_graphic.h"
#include <dolphin/gx/GXAurora.h>
#include <aurora/math.hpp>
#include <algorithm>
#include <array>
#include <cmath>
#include <functional>
#include <limits>
#include <numbers>
#include <span>
constexpr u16 kMapIconResolutionMultiplier = 4;
constexpr u16 kMapImageSide = 16 * kMapIconResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
typedef std::function<u8(size_t, size_t)> PaintI8Fn;
u16 scaled_map_axis(u16 value, f32 scale) {
const auto scaledValue =
@@ -59,27 +50,6 @@ aurora::Vec2<u16> map_render_size_for(u16 width, u16 height) {
scaled_map_axis(height, irScaleY * hudScale),
};
}
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
const auto blocksAcross = width >> 3;
for (size_t i = 0; i < dst.size(); i++) {
// 8x4 block swizzling for I8
const auto blockIdx = i >> 5;
const auto localIdx = i & 31;
const auto blockY = blockIdx / blocksAcross;
const auto blockX = blockIdx % blocksAcross;
const auto localY = localIdx >> 3;
const auto localX = localIdx & 7;
const auto x = (blockX << 3) + localX;
const auto y = (blockY << 2) + localY;
dst[i] = paint(x, y);
}
}
#endif
void dMpath_n::dTexObjAggregate_c::create() {
@@ -100,106 +70,11 @@ void dMpath_n::dTexObjAggregate_c::create() {
JUT_ASSERT(72, image != NULL);
JUT_ASSERT(73, image->minFilter == GX_NEAR);
JUT_ASSERT(74, image->magFilter == GX_NEAR);
IF_DUSK(dusk::hq_minimap::register_pointer(data[lp1], reinterpret_cast<u8*>(image) + image->imageOffset));
mDoLib_setResTimgObj(image, mp_texObj[lp1], 0, NULL);
}
#if TARGET_PC
static bool hqTexsDrawn = false;
static u8 hqCircleData[kMapImageTotalPixels];
static u8 hqCircleAltData[kMapImageTotalPixels];
static u8 hqNijumaruData[kMapImageTotalPixels];
static u8 hqEnterData[kMapImageTotalPixels];
static u8 hqTryForceData[kMapImageTotalPixels];
if (!hqTexsDrawn) {
constexpr auto center = kMapImageSide / 2.0f;
constexpr auto radiusSq = center * center;
// 6: map_icon_circle16x16_4i.bti - simple circle
paint_i8(std::span{hqCircleData}, kMapImageSide, [=](auto x, auto y) {
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
return (dx * dx + dy * dy < radiusSq) ? 0x11 : 0;
});
// 4: im_map_icon_circle_4i.bti - outlined circle
paint_i8(std::span{hqCircleAltData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto innerRadius = kMapImageSide * 3.0f / 8.0f;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
return dSq < radiusSq ? (dSq < innerRadiusSq ? 0x22 : 0x11) : 0;
});
// 3: im_map_icon_nijumaru_4i.bti - concentric rings
paint_i8(std::span{hqNijumaruData}, kMapImageSide, [=](auto x, auto y) {
constexpr u8 nijumaruRings[] = {0x11, 0x22, 0x11, 0x11, 0x22, 0x22};
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
if (dSq < radiusSq) {
const auto ringIndex =
static_cast<size_t>(std::trunc(std::sqrt(dSq) / kMapImageSide * 12));
return nijumaruRings[ringIndex];
}
return u8{0};
});
// 2: im_map_icon_enter_4i.bti - outlined octagram
paint_i8(std::span{hqEnterData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto outlineWidth = kMapImageSide / 6.0f;
const auto adx = std::abs((x + 0.5f) - center);
const auto ady = std::abs((y + 0.5f) - center);
const auto dist =
std::min(adx + ady, std::max(adx, ady) * std::numbers::sqrt2_v<float>) -
kMapImageSide / 2.0f;
return dist > 0.0f ? 0 : (dist > -outlineWidth ? 0x22 : 0x33);
});
// 5: im_map_icon_try_force_4i.bti - outlined circle with triangle
paint_i8(std::span{hqTryForceData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto innerRadiusNorm = 5.0f / 12.0f;
constexpr auto innerRadius = kMapImageSide * innerRadiusNorm;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
constexpr auto triRadius = kMapImageSide * innerRadiusNorm / 2.0f;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
const auto triSideDist = (std::numbers::sqrt3_v<float> * std::abs(dx) - dy) * 0.5f;
const auto insideTri = std::max(dy, triSideDist) < triRadius;
return insideTri ? 0x22 : (dSq < radiusSq ? (dSq < innerRadiusSq ? 0x33 : 0x22) : 0);
});
hqTexsDrawn = true;
}
constexpr auto replacements = std::to_array<std::pair<size_t, const u8*> >({
{2, hqEnterData},
{3, hqNijumaruData},
{4, hqCircleAltData},
{5, hqTryForceData},
{6, hqCircleData},
});
for (const auto& [idx, data] : replacements) {
JKR_DELETE(mp_texObj[idx]);
const auto texobj = JKR_NEW TGXTexObj();
GXInitTexObj(
texobj, data, kMapImageSide, kMapImageSide, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(texobj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
mp_texObj[idx] = texobj;
}
#endif
IF_DUSK(dusk::hq_minimap::initialize_if_needed());
}
void dMpath_n::dTexObjAggregate_c::remove() {
+16 -12
View File
@@ -363,13 +363,15 @@ void dMenu_DmapBg_c::buttonIconScreenInit() {
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
((J2DTextBox*)mButtonScreen->search(cont_at[i]))->setFont(mDoExt_getMesgFont());
((J2DTextBox*)mButtonScreen->search(cont_bt[i]))->setFont(mDoExt_getMesgFont());
((J2DTextBox*)mButtonScreen->search(cont_at[i]))->setString(32, "");
((J2DTextBox*)mButtonScreen->search(cont_bt[i]))->setString(32, "");
((J2DTextBox*)mButtonScreen->search(font_at[i]))->hide();
((J2DTextBox*)mButtonScreen->search(font_bt[i]))->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
((J2DTextBox*)mButtonScreen->search(font_at[i]))->hide();
((J2DTextBox*)mButtonScreen->search(font_bt[i]))->hide();
}
} else {
((J2DTextBox*)mButtonScreen->search(font_at[i]))->setFont(mDoExt_getMesgFont());
((J2DTextBox*)mButtonScreen->search(font_bt[i]))->setFont(mDoExt_getMesgFont());
@@ -400,7 +402,7 @@ void dMenu_DmapBg_c::buttonIconScreenInit() {
J2DTextBox* textBox;
for (int i = 0; i < 2; i++) {
textBox = ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])));
textBox = (J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i]));
textBox->setFont(mDoExt_getMesgFont());
textBox->setString(32, "");
}
@@ -436,9 +438,9 @@ void dMenu_DmapBg_c::setAButtonString(u32 i_msgNo) {
for (int i = 0; i < 5; i++) {
if (i_msgNo == 0) {
SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), "");
SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), "");
} else {
dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), NULL);
dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), NULL);
}
}
}
@@ -463,9 +465,9 @@ void dMenu_DmapBg_c::setBButtonString(u32 i_msgNo) {
for (int i = 0; i < 5; i++) {
if (i_msgNo == 0) {
SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), "");
SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), "");
} else {
dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), NULL);
dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), NULL);
}
}
}
@@ -504,12 +506,12 @@ void dMenu_DmapBg_c::setCButtonString(u32 i_msgNo) {
if (msgNo == 0) {
for (i = 0; i < 2; i++) {
SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), "");
SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), "");
}
mpCButton->setAlphaRate(0.5f);
} else {
for (i = 0; i < 2; i++) {
dMeter2Info_getStringKanji(msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), NULL);
dMeter2Info_getStringKanji(msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), NULL);
}
mpCButton->setAlphaRate(1.0f);
}
@@ -979,8 +981,10 @@ void dMenu_DmapBg_c::dMapBgWide() {
mButtonScreen->search(MULTI_CHAR('c_btn'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('c_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('c_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
}
// Decorations
mButtonScreen->search(MULTI_CHAR('kazari_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
+2
View File
@@ -343,7 +343,9 @@ void dMenu_Fishing_c::screenSetBase() {
field_0x19c[1][i]->setString(0x20, "");
mpFishNameString[i] = (J2DTextBox*)mpScreen->search(name_0[i]);
IF_DUSK_BLOCK(dusk::version::isGcn())
mpScreen->search(fname_0[i])->hide();
IF_DUSK_BLOCK_END
mpFishNameString[i]->setFont(mDoExt_getSubFont());
mpFishNameString[i]->setString(0x20, "");
dMeter2Info_getStringKanji(name_id[i], mpFishNameString[i]->getStringPtr(), NULL);
+48 -56
View File
@@ -2420,10 +2420,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
static const u64 farea_name[3] = {MULTI_CHAR('f_name_1'), MULTI_CHAR('f_name3'), MULTI_CHAR('f_name2')};
for (int i = 0; i < 3; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(area_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(area_name[i]))->setString(0x40, "");
mpTitleScreen->search(farea_name[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(farea_name[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(farea_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(farea_name[i]))->setString(0x40, "");
@@ -2458,10 +2460,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
#endif
for (int i = 0; i < 7; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(sfont_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(sfont_name[i]))->setString(0x40, "");
mpTitleScreen->search(ffont_name[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(ffont_name[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(ffont_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(ffont_name[i]))->setString(0x40, "");
@@ -2485,10 +2489,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
static const u64 font_zt[5] = {MULTI_CHAR('font_zt1'), MULTI_CHAR('font_zt2'), MULTI_CHAR('font_zt3'), MULTI_CHAR('font_zt4'), MULTI_CHAR('font_zt5')};
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(cont_zt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(cont_zt[i]))->setString(0x20, "");
mpTitleScreen->search(font_zt[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(font_zt[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(font_zt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(font_zt[i]))->setString(0x20, "");
@@ -2516,10 +2522,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
#endif
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(cont_bt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(cont_bt[i]))->setString(0x20, "");
mpTitleScreen->search(font_bt[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(font_bt[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(font_bt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(font_bt[i]))->setString(0x20, "");
@@ -2543,10 +2551,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
static const u64 font_at[5] = {MULTI_CHAR('font_at1'), MULTI_CHAR('font_at2'), MULTI_CHAR('font_at3'), MULTI_CHAR('font_at4'), MULTI_CHAR('font_at5')};
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(cont_at[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(cont_at[i]))->setString(0x20, "");
mpTitleScreen->search(font_at[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(font_at[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(font_at[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(font_at[i]))->setString(0x20, "");
@@ -2571,10 +2581,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
static const u64 fuji_c[5] = {MULTI_CHAR('fuji_c00'), MULTI_CHAR('fuji_c01'), MULTI_CHAR('fuji_c02'), MULTI_CHAR('fuji_c03'), MULTI_CHAR('fuji_c04')};
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(juji_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(juji_c[i]))->setString(0x20, "");
mpTitleScreen->search(fuji_c[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(fuji_c[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(fuji_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(fuji_c[i]))->setString(0x20, "");
@@ -2598,10 +2610,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
static const u64 fst_c[5] = {MULTI_CHAR('fst_00'), MULTI_CHAR('fst_01'), MULTI_CHAR('fst_02'), MULTI_CHAR('fst_03'), MULTI_CHAR('fst_04')};
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
static_cast<J2DTextBox*>(mpTitleScreen->search(ast_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(ast_c[i]))->setString(0x20, "");
mpTitleScreen->search(fst_c[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTitleScreen->search(fst_c[i])->hide();
}
} else {
static_cast<J2DTextBox*>(mpTitleScreen->search(fst_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(mpTitleScreen->search(fst_c[i]))->setString(0x20, "");
@@ -2863,8 +2877,7 @@ void dMenu_Fmap2DTop_c::setTitleNameString(u32 param_0) {
static const u64 ffont_name[7] = {
MULTI_CHAR('ffont00'), MULTI_CHAR('ffontl0'), MULTI_CHAR('ffontl1'), MULTI_CHAR('ffontl2'), MULTI_CHAR('ffontb0'), MULTI_CHAR('ffontb3'), MULTI_CHAR('ffontb4')
};
auto setTitleNameString_font_name = dusk::version::isRegionJpn() ? sfont_name : ffont_name;
auto setTitleNameString_font_name = dusk::version::isJpnOrLessThanWiiJpn() ? sfont_name : ffont_name;
#elif VERSION == VERSION_GCN_JPN
static const u64 sfont_name[7] = {
MULTI_CHAR('sfont00'), MULTI_CHAR('sfontl0'), MULTI_CHAR('sfontl1'), MULTI_CHAR('sfontl2'), MULTI_CHAR('sfontb0'), MULTI_CHAR('sfontb1'), MULTI_CHAR('sfontb2')
@@ -2883,15 +2896,9 @@ void dMenu_Fmap2DTop_c::setTitleNameString(u32 param_0) {
#endif
for (int i = 0; i < 7; i++) {
if (param_0 == 0) {
SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i])))
->getStringPtr(),
"");
SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i])))->getStringPtr(), "");
} else {
dMeter2Info_getStringKanji(
param_0,
((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i])))
->getStringPtr(),
NULL);
dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i])))->getStringPtr(), NULL);
}
}
}
@@ -2900,7 +2907,7 @@ void dMenu_Fmap2DTop_c::setAreaNameString(u32 param_0) {
#if TARGET_PC
static const u64 iarea_name[3] = {MULTI_CHAR('i_name_s'), MULTI_CHAR('i_name'), MULTI_CHAR('i_name1')};
static const u64 farea_name[3] = {MULTI_CHAR('f_name_1'), MULTI_CHAR('f_name3'), MULTI_CHAR('f_name2')};
auto setAreaNameString_area_name = dusk::version::isRegionJpn() ? iarea_name : farea_name;
auto setAreaNameString_area_name = dusk::version::isJpnOrLessThanWiiJpn() ? iarea_name : farea_name;
#elif VERSION == VERSION_GCN_JPN
static const u64 iarea_name[3] = {MULTI_CHAR('i_name_s'), MULTI_CHAR('i_name'), MULTI_CHAR('i_name1')};
#define setAreaNameString_area_name iarea_name
@@ -2910,15 +2917,9 @@ void dMenu_Fmap2DTop_c::setAreaNameString(u32 param_0) {
#endif
for (int i = 0; i < 3; i++) {
if (param_0 == 0) {
SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i])))
->getStringPtr(),
"");
SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i])))->getStringPtr(), "");
} else {
dMeter2Info_getStringKanji(
param_0,
((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i])))
->getStringPtr(),
NULL);
dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i])))->getStringPtr(), NULL);
}
}
}
@@ -2937,7 +2938,7 @@ void dMenu_Fmap2DTop_c::setZButtonString(u32 param_0, u8 i_alpha) {
#if TARGET_PC
static const u64 cont_zt[5] = {MULTI_CHAR('cont_zt'), MULTI_CHAR('cont_zt1'), MULTI_CHAR('cont_zt2'), MULTI_CHAR('cont_zt3'), MULTI_CHAR('cont_zt4')};
static const u64 font_zt[5] = {MULTI_CHAR('font_zt1'), MULTI_CHAR('font_zt2'), MULTI_CHAR('font_zt3'), MULTI_CHAR('font_zt4'), MULTI_CHAR('font_zt5')};
auto setZButtonString_font_zt = dusk::version::isRegionJpn() ? cont_zt : font_zt;
auto setZButtonString_font_zt = dusk::version::isJpnOrLessThanWiiJpn() ? cont_zt : font_zt;
#elif VERSION == VERSION_GCN_JPN
static const u64 cont_zt[5] = {MULTI_CHAR('cont_zt'), MULTI_CHAR('cont_zt1'), MULTI_CHAR('cont_zt2'), MULTI_CHAR('cont_zt3'), MULTI_CHAR('cont_zt4')};
#define setZButtonString_font_zt cont_zt
@@ -2953,10 +2954,7 @@ void dMenu_Fmap2DTop_c::setZButtonString(u32 param_0, u8 i_alpha) {
#endif
} else {
for (int i = 0; i < 5; i++) {
dMeter2Info_getStringKanji(
param_0,
((J2DTextBox*)(mpTitleScreen->search(setZButtonString_font_zt[i])))->getStringPtr(),
NULL);
dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setZButtonString_font_zt[i])))->getStringPtr(), NULL);
}
if (i_alpha == ALPHA_DEFAULT) {
@@ -2975,7 +2973,7 @@ void dMenu_Fmap2DTop_c::setBButtonString(u32 param_0, u8 i_alpha) {
#if TARGET_PC
static const u64 cont_bt[5] = {MULTI_CHAR('cont_bt1'), MULTI_CHAR('cont_bt2'), MULTI_CHAR('cont_bt3'), MULTI_CHAR('cont_bt4'), MULTI_CHAR('cont_bt')};
static const u64 font_bt[5] = {MULTI_CHAR('font_bt1'), MULTI_CHAR('font_bt2'), MULTI_CHAR('font_bt3'), MULTI_CHAR('font_bt4'), MULTI_CHAR('font_bt5')};
auto setBButtonString_font_bt = dusk::version::isRegionJpn() ? cont_bt : font_bt;
auto setBButtonString_font_bt = dusk::version::isJpnOrLessThanWiiJpn() ? cont_bt : font_bt;
#elif VERSION == VERSION_GCN_JPN
static const u64 cont_bt[5] = {MULTI_CHAR('cont_bt1'), MULTI_CHAR('cont_bt2'), MULTI_CHAR('cont_bt3'), MULTI_CHAR('cont_bt4'), MULTI_CHAR('cont_bt')};
#define setBButtonString_font_bt cont_bt
@@ -2987,10 +2985,7 @@ void dMenu_Fmap2DTop_c::setBButtonString(u32 param_0, u8 i_alpha) {
mAlphaButtonB = ALPHA_MIN;
} else {
for (int i = 0; i < 5; i++) {
dMeter2Info_getStringKanji(
param_0,
((J2DTextBox*)(mpTitleScreen->search(setBButtonString_font_bt[i])))->getStringPtr(),
NULL);
dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setBButtonString_font_bt[i])))->getStringPtr(), NULL);
}
if (i_alpha == ALPHA_DEFAULT) {
@@ -3005,7 +3000,7 @@ void dMenu_Fmap2DTop_c::setAButtonString(u32 param_0, u8 i_alpha) {
#if TARGET_PC
static const u64 cont_at[5] = {MULTI_CHAR('cont_at'), MULTI_CHAR('cont_at1'), MULTI_CHAR('cont_at2'), MULTI_CHAR('cont_at3'), MULTI_CHAR('cont_at4')};
static const u64 font_at[5] = {MULTI_CHAR('font_at1'), MULTI_CHAR('font_at2'), MULTI_CHAR('font_at3'), MULTI_CHAR('font_at4'), MULTI_CHAR('font_at5')};
auto setAButtonString_font_at = dusk::version::isRegionJpn() ? cont_at : font_at;
auto setAButtonString_font_at = dusk::version::isJpnOrLessThanWiiJpn() ? cont_at : font_at;
#elif VERSION == VERSION_GCN_JPN
static const u64 cont_at[5] = {MULTI_CHAR('cont_at'), MULTI_CHAR('cont_at1'), MULTI_CHAR('cont_at2'), MULTI_CHAR('cont_at3'), MULTI_CHAR('cont_at4')};
#define setAButtonString_font_at cont_at
@@ -3017,10 +3012,7 @@ void dMenu_Fmap2DTop_c::setAButtonString(u32 param_0, u8 i_alpha) {
mAlphaButtonA = ALPHA_MIN;
} else {
for (int i = 0; i < 5; i++) {
dMeter2Info_getStringKanji(
param_0,
((J2DTextBox*)(mpTitleScreen->search(setAButtonString_font_at[i])))->getStringPtr(),
NULL);
dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setAButtonString_font_at[i])))->getStringPtr(), NULL);
}
if (i_alpha == ALPHA_DEFAULT) {
@@ -3034,8 +3026,8 @@ void dMenu_Fmap2DTop_c::setAButtonString(u32 param_0, u8 i_alpha) {
void dMenu_Fmap2DTop_c::setCrossLRString(u32 param_0) {
#if PLATFORM_GCN || (VERSION == VERSION_SHIELD)
#if TARGET_PC
static const u64 juji_c_jpn[5] = {MULTI_CHAR('juji_c00'), MULTI_CHAR('juji_c01'), MULTI_CHAR('juji_c02'), MULTI_CHAR('juji_c03'), MULTI_CHAR('juji_c04')};
static const u64 juji_c[5] = {MULTI_CHAR('fuji_c00'), MULTI_CHAR('fuji_c01'), MULTI_CHAR('fuji_c02'), MULTI_CHAR('fuji_c03'), MULTI_CHAR('fuji_c04')};
static const u64 juji_c[5] = {MULTI_CHAR('juji_c00'), MULTI_CHAR('juji_c01'), MULTI_CHAR('juji_c02'), MULTI_CHAR('juji_c03'), MULTI_CHAR('juji_c04')};
static const u64 fuji_c[5] = {MULTI_CHAR('fuji_c00'), MULTI_CHAR('fuji_c01'), MULTI_CHAR('fuji_c02'), MULTI_CHAR('fuji_c03'), MULTI_CHAR('fuji_c04')};
#elif VERSION == VERSION_GCN_JPN
static const u64 juji_c[5] = {MULTI_CHAR('juji_c00'), MULTI_CHAR('juji_c01'), MULTI_CHAR('juji_c02'), MULTI_CHAR('juji_c03'), MULTI_CHAR('juji_c04')};
#else
@@ -3043,14 +3035,14 @@ void dMenu_Fmap2DTop_c::setCrossLRString(u32 param_0) {
#endif
if (param_0 == 0) {
for (int i = 0; i < 5; i++) {
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? juji_c_jpn[i] : juji_c[i], juji_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? juji_c[i] : fuji_c[i], juji_c[i])));
SAFE_STRCPY(text_box->getStringPtr(), "");
}
mpTitleScreen->search(MULTI_CHAR('juy_sha0'))->show();
mAlphaDpad = 1;
} else {
for (int i = 0; i < 5; i++) {
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? juji_c_jpn[i] : juji_c[i], juji_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? juji_c[i] : fuji_c[i], juji_c[i])));
dMeter2Info_getStringKanji(param_0, text_box->getStringPtr(), NULL);
}
mpTitleScreen->search(MULTI_CHAR('juy_sha0'))->show();
@@ -3062,8 +3054,8 @@ void dMenu_Fmap2DTop_c::setCrossLRString(u32 param_0) {
void dMenu_Fmap2DTop_c::set3DStickString(u32 param_0) {
#if PLATFORM_GCN || (VERSION == VERSION_SHIELD)
#if TARGET_PC
static const u64 ast_c_jpn[5] = {MULTI_CHAR('ast_00'), MULTI_CHAR('ast_01'), MULTI_CHAR('ast_02'), MULTI_CHAR('ast_03'), MULTI_CHAR('ast_04')};
static const u64 ast_c[5] = {MULTI_CHAR('fst_00'), MULTI_CHAR('fst_01'), MULTI_CHAR('fst_02'), MULTI_CHAR('fst_03'), MULTI_CHAR('fst_04')};
static const u64 ast_c[5] = {MULTI_CHAR('ast_00'), MULTI_CHAR('ast_01'), MULTI_CHAR('ast_02'), MULTI_CHAR('ast_03'), MULTI_CHAR('ast_04')};
static const u64 fst_c[5] = {MULTI_CHAR('fst_00'), MULTI_CHAR('fst_01'), MULTI_CHAR('fst_02'), MULTI_CHAR('fst_03'), MULTI_CHAR('fst_04')};
#elif VERSION == VERSION_GCN_JPN
static const u64 ast_c[5] = {MULTI_CHAR('ast_00'), MULTI_CHAR('ast_01'), MULTI_CHAR('ast_02'), MULTI_CHAR('ast_03'), MULTI_CHAR('ast_04')};
#else
@@ -3071,14 +3063,14 @@ void dMenu_Fmap2DTop_c::set3DStickString(u32 param_0) {
#endif
if (param_0 == 0) {
for (int i = 0; i < 5; i++) {
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? ast_c_jpn[i] : ast_c[i], ast_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? ast_c[i] : fst_c[i], ast_c[i])));
SAFE_STRCPY(text_box->getStringPtr(), "");
}
mpTitleScreen->search(MULTI_CHAR('as_sha0'))->show();
mAlphaAnalogStick = 1;
} else {
for (int i = 0; i < 5; i++) {
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? ast_c_jpn[i] : ast_c[i], ast_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? ast_c[i] : fst_c[i], ast_c[i])));
dMeter2Info_getStringKanji(param_0, text_box->getStringPtr(), NULL);
}
mpTitleScreen->search(MULTI_CHAR('as_sha0'))->show();
+99 -120
View File
@@ -73,6 +73,26 @@ static calibrationFunc calibration_process[] = {
static dusk::menu_pointer::TargetId option_yes_no_target(u8 index) noexcept {
return static_cast<dusk::menu_pointer::TargetId>(0x100 + index);
}
static u8 option_to_proc(u8 select) noexcept {
if (!dusk::version::isRegionJpn() && select >= 1) {
return static_cast<u8>(select + 1);
}
return select;
}
static u8 option_to_select(u8 proc) noexcept {
if (!dusk::version::isRegionJpn() && proc >= 2) {
return static_cast<u8>(proc - 1);
}
return proc;
}
#define OPTION_SELECT(proc_e) (option_to_select(proc_e))
#define OPTION_PROC(select) (option_to_proc(select))
#else
#define OPTION_SELECT(proc_e) (proc_e)
#define OPTION_PROC(select) (select)
#endif
dMenu_Option_c::dMenu_Option_c(JKRArchive* i_archive, STControl* i_stick) {
@@ -159,7 +179,9 @@ void dMenu_Option_c::_create() {
mpTVButtonText = JKR_NEW CPaneMgr(mpTVScreen, MULTI_CHAR('a_text_n'), 0, NULL);
JUT_ASSERT(298, mpTVButtonText != NULL);
IF_DUSK_BLOCK(dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn)
mpTVScreen->search(MULTI_CHAR('g_abtn_n'))->hide();
IF_DUSK_BLOCK_END
mpScreenIcon = JKR_NEW J2DScreen();
JUT_ASSERT(325, mpScreenIcon != NULL);
@@ -257,11 +279,11 @@ void dMenu_Option_c::_create() {
field_0x3e1 = 10;
field_0x3e2 = 0xff;
field_0x3e3 = 0xc0;
field_0x3ef = PROC_ATTEN_e;
field_0x3ef = OPTION_SELECT(PROC_ATTEN_e);
field_0x3f0 = 0xff;
field_0x3f1 = 0xff;
field_0x3f2 = 0;
field_0x3f5 = PROC_ATTEN_e;
field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e);
field_0x3f3 = 5;
field_0x3f4 = 5;
field_0x334 = 0.0f;
@@ -485,9 +507,9 @@ void dMenu_Option_c::_move() {
}
if (mDoGph_gInf_c::getFader()->getStatus() == 1) {
if (mDoCPd_c::getTrigA(PAD_1) != 0 && field_0x3ef != PROC_CHANGE_MOVE_e && field_0x3f3 == 5) {
if (field_0x3f4 == 5 && field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e &&
field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e)
if (mDoCPd_c::getTrigA(PAD_1) != 0 && field_0x3ef != OPTION_SELECT(PROC_CHANGE_MOVE_e) && field_0x3f3 == 5) {
if (field_0x3f4 == 5 && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) &&
field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e))
{
if (mDoCPd_c::getTrigStart(PAD_1) == 0 && mDoCPd_c::getTrigB(PAD_1) == 0) {
if (mDoCPd_c::getTrigUp(PAD_1) == 0 && mDoCPd_c::getTrigDown(PAD_1) == 0 &&
@@ -495,17 +517,17 @@ void dMenu_Option_c::_move() {
{
field_0x3f7 = 1;
field_0x3f5 = field_0x3ef;
field_0x3ef = PROC_CONFIRM_OPEN_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e);
dMeter2Info_set2DVibration();
(this->*init[field_0x3ef])();
(this->*init[OPTION_PROC(field_0x3ef)])();
goto skip;
}
}
}
}
if (mDoCPd_c::getTrigB(PAD_1) != 0 && field_0x3ef != PROC_CHANGE_MOVE_e && field_0x3f3 == 5 &&
field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e && field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e)
if (mDoCPd_c::getTrigB(PAD_1) != 0 && field_0x3ef != OPTION_SELECT(PROC_CHANGE_MOVE_e) && field_0x3f3 == 5 &&
field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e))
{
if (field_0x3f4 == 5 && mDoCPd_c::getTrigStart(PAD_1) == 0 &&
mDoCPd_c::getTrigA(PAD_1) == 0 && mDoCPd_c::getTrigUp(PAD_1) == 0 &&
@@ -514,16 +536,16 @@ void dMenu_Option_c::_move() {
{
field_0x3f7 = 0;
field_0x3f5 = field_0x3ef;
field_0x3ef = PROC_CONFIRM_OPEN_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e);
dMeter2Info_set2DVibration();
(this->*init[field_0x3ef])();
(this->*init[OPTION_PROC(field_0x3ef)])();
}
}
#if TARGET_PC
if (field_0x3f4 == 5 && field_0x3ef != PROC_CHANGE_MOVE_e && field_0x3f3 == 5 &&
field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e &&
field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e && pointerConfirmSelect())
if (field_0x3f4 == 5 && field_0x3ef != OPTION_SELECT(PROC_CHANGE_MOVE_e) && field_0x3f3 == 5 &&
field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) &&
field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e) && pointerConfirmSelect())
{
goto skip;
}
@@ -531,7 +553,7 @@ void dMenu_Option_c::_move() {
}
skip:
u8 oldValue = field_0x3ef;
if (field_0x3f3 == 5 && oldValue != PROC_CONFIRM_OPEN_MOVE_e && oldValue != PROC_CONFIRM_MOVE_MOVE_e && oldValue != PROC_CONFIRM_SELECT_MOVE_e && oldValue != PROC_CONFIRM_CLOSE_MOVE_e) {
if (field_0x3f3 == 5 && oldValue != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && oldValue != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && oldValue != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && oldValue != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e)) {
dpdMenuMove();
}
@@ -545,10 +567,10 @@ skip:
field_0x3f0 = 0xff;
}
(this->*process[field_0x3ef])();
(this->*process[OPTION_PROC(field_0x3ef)])();
mpSelectScreen->animation();
if (oldValue != field_0x3ef) {
(this->*init[field_0x3ef])();
(this->*init[OPTION_PROC(field_0x3ef)])();
}
setHIO(false);
@@ -610,8 +632,8 @@ void dMenu_Option_c::drawHaihai() {
field_0x3f6 = 0;
field_0x3f6 |= 1;
field_0x3f6 |= 4;
if (selectType < PROC_CONFIRM_OPEN_MOVE_e && field_0x3f6 != 0 && field_0x3f3 == 5 && field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e &&
field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e && field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e)
if (selectType < OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3f6 != 0 && field_0x3f3 == 5 && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) &&
field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e))
{
mpMeterHaihai->_execute(0);
Vec haihaiPosL =
@@ -752,13 +774,7 @@ void dMenu_Option_c::atten_move() {
if (field_0x3f3 != 5) {
(this->*tv_process[field_0x3f3])();
} else if (downTrigger) {
#if TARGET_PC
field_0x3ef = dusk::version::isRegionJpn() ? PROC_RUBY_e : PROC_VIB_e;
#elif VERSION == VERSION_GCN_JPN
field_0x3ef = PROC_RUBY_e;
#else
field_0x3ef = PROC_VIB_e;
#endif
field_0x3ef = 1;
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (leftTrigger) {
if (field_0x3e4 == 0) {
@@ -768,8 +784,8 @@ void dMenu_Option_c::atten_move() {
field_0x3e4 = 0;
field_0x3da = -5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_ATTEN_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (rightTrigger) {
if (field_0x3e4 == 0) {
@@ -779,8 +795,8 @@ void dMenu_Option_c::atten_move() {
field_0x3e4 = 0;
field_0x3da = 5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_ATTEN_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else {
changeTVCheck();
@@ -818,10 +834,10 @@ void dMenu_Option_c::ruby_move() {
if (field_0x3f3 != 5) {
(this->*tv_process[field_0x3f3])();
} else if (upTrigger) {
field_0x3ef = PROC_ATTEN_e;
field_0x3ef = OPTION_SELECT(PROC_ATTEN_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (downTrigger) {
field_0x3ef = PROC_VIB_e;
field_0x3ef = OPTION_SELECT(PROC_VIB_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (leftTrigger) {
if (field_0x3e5_JPN == 0) {
@@ -831,8 +847,8 @@ void dMenu_Option_c::ruby_move() {
field_0x3e5_JPN = 0;
field_0x3da = -5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_RUBY_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_RUBY_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (rightTrigger) {
if (field_0x3e5_JPN == 0) {
@@ -842,8 +858,8 @@ void dMenu_Option_c::ruby_move() {
field_0x3e5_JPN = 0;
field_0x3da = 5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_RUBY_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_RUBY_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else {
changeTVCheck();
@@ -853,7 +869,7 @@ void dMenu_Option_c::ruby_move() {
void dMenu_Option_c::vib_init() {
mpDrawCursor->setAlphaRate(1.0f);
setCursorPos(PROC_VIB_e);
setCursorPos(OPTION_SELECT(PROC_VIB_e));
setAButtonString(0x40C);
setBButtonString(0x3F9);
}
@@ -868,7 +884,7 @@ void dMenu_Option_c::vib_move() {
(this->*tv_process[field_0x3f3])();
} else if (upTrigger) {
#if TARGET_PC
field_0x3ef = dusk::version::isRegionJpn() ? PROC_RUBY_e : PROC_ATTEN_e;
field_0x3ef = OPTION_SELECT(dusk::version::isRegionJpn() ? PROC_RUBY_e : PROC_ATTEN_e);
#elif VERSION == VERSION_GCN_JPN
field_0x3ef = PROC_RUBY_e;
#else
@@ -876,7 +892,7 @@ void dMenu_Option_c::vib_move() {
#endif
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (downTrigger) {
field_0x3ef = PROC_SOUND_e;
field_0x3ef = OPTION_SELECT(PROC_SOUND_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (leftTrigger) {
if (isRumbleSupported()) {
@@ -888,8 +904,8 @@ void dMenu_Option_c::vib_move() {
field_0x3ea = 0;
field_0x3da = -5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_VIB_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_VIB_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f,
0);
}
@@ -903,8 +919,8 @@ void dMenu_Option_c::vib_move() {
field_0x3ea = 0;
field_0x3da = 5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_VIB_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_VIB_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f,
0);
}
@@ -915,7 +931,7 @@ void dMenu_Option_c::vib_move() {
void dMenu_Option_c::sound_init() {
mpDrawCursor->setAlphaRate(1.0f);
setCursorPos(PROC_SOUND_e);
setCursorPos(OPTION_SELECT(PROC_SOUND_e));
setAButtonString(0x40C);
setBButtonString(0x3F9);
}
@@ -929,7 +945,7 @@ void dMenu_Option_c::sound_move() {
if (field_0x3f3 != 5) {
(this->*tv_process[field_0x3f3])();
} else if (upTrigger) {
field_0x3ef = PROC_VIB_e;
field_0x3ef = OPTION_SELECT(PROC_VIB_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (leftTrigger) {
if (field_0x3e9 == 2) {
@@ -954,8 +970,8 @@ void dMenu_Option_c::sound_move() {
}
mDoAud_setOutputMode(dMo_soundMode[field_0x3e9]);
setSoundMode(dMo_soundMode[field_0x3e9]);
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_SOUND_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_SOUND_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else if (rightTrigger) {
if (field_0x3e9 == 0) {
@@ -980,8 +996,8 @@ void dMenu_Option_c::sound_move() {
}
mDoAud_setOutputMode(dMo_soundMode[field_0x3e9]);
setSoundMode(dMo_soundMode[field_0x3e9]);
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_SOUND_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_SOUND_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
} else {
changeTVCheck();
@@ -1002,15 +1018,15 @@ void dMenu_Option_c::change_move() {
field_0x3da++;
}
u8 index;
switch (field_0x3f5) {
switch (OPTION_PROC(field_0x3f5)) {
case PROC_ATTEN_e:
index = PROC_ATTEN_e;
index = field_0x3f5;
if (field_0x3da == 0) {
setAttenString();
}
break;
case PROC_RUBY_e:
index = PROC_RUBY_e;
index = field_0x3f5;
if (field_0x3da == 0) {
IF_DUSK_BLOCK(dusk::version::isRegionJpn())
setRubyString();
@@ -1018,13 +1034,13 @@ void dMenu_Option_c::change_move() {
}
break;
case PROC_VIB_e:
index = DUSK_IF_ELSE(dusk::version::isRegionJpn() ? 2 : 1, PROC_VIB_e);
index = field_0x3f5;
if (field_0x3da == 0) {
setVibString();
}
break;
case PROC_SOUND_e:
index = DUSK_IF_ELSE(dusk::version::isRegionJpn() ? 3 : 2, PROC_SOUND_e);
index = field_0x3f5;
if (field_0x3da == 0) {
setSoundString();
}
@@ -1090,7 +1106,7 @@ void dMenu_Option_c::confirm_open_move() {
}
if (status == 1 && yesNoMenuMove == 1 && field_0x374 == 1.0f) {
yesnoCursorShow();
field_0x3ef = PROC_CONFIRM_MOVE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e);
}
mpWarning->_move();
setAnimation();
@@ -1120,21 +1136,21 @@ void dMenu_Option_c::confirm_move_move() {
field_0x3f9 = i;
if (clicked) {
yesNoSelectStart();
field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e);
dMeter2Info_set2DVibrationM();
mpWarning->_move();
setAnimation();
return;
}
yesnoSelectAnmSet();
field_0x3ef = PROC_CONFIRM_SELECT_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e);
mpWarning->_move();
setAnimation();
return;
}
if (clicked) {
yesNoSelectStart();
field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e);
dMeter2Info_set2DVibrationM();
mpWarning->_move();
setAnimation();
@@ -1145,12 +1161,12 @@ void dMenu_Option_c::confirm_move_move() {
if (mDoCPd_c::getTrigA(PAD_1) != 0) {
yesNoSelectStart();
field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e);
dMeter2Info_set2DVibrationM();
} else if (mDoCPd_c::getTrigB(PAD_1) != 0) {
field_0x3f9 = 0;
yesnoCancelAnmSet();
field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e);
dMeter2Info_set2DVibrationM();
} else if (rightTrigger != 0) {
if (field_0x3f9 != 0) {
@@ -1159,7 +1175,7 @@ void dMenu_Option_c::confirm_move_move() {
field_0x3fa = field_0x3f9;
field_0x3f9 = 0;
yesnoSelectAnmSet();
field_0x3ef = PROC_CONFIRM_SELECT_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e);
}
} else if (leftTrigger != 0) {
if (field_0x3f9 != 1) {
@@ -1168,7 +1184,7 @@ void dMenu_Option_c::confirm_move_move() {
field_0x3fa = field_0x3f9;
field_0x3f9 = 1;
yesnoSelectAnmSet();
field_0x3ef = PROC_CONFIRM_SELECT_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e);
}
}
mpWarning->_move();
@@ -1202,14 +1218,14 @@ void dMenu_Option_c::confirm_select_move() {
dusk::menu_pointer::Context::Options, option_yes_no_target(field_0x3f9)))
{
yesNoSelectStart();
field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e);
dMeter2Info_set2DVibrationM();
mpWarning->_move();
setAnimation();
return;
}
#endif
field_0x3ef = PROC_CONFIRM_MOVE_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e);
}
mpWarning->_move();
setAnimation();
@@ -1353,13 +1369,7 @@ void dMenu_Option_c::calibration_close2_move() {
void dMenu_Option_c::menuVisible() {
for (int i = 0; i < 6; i++) {
#if TARGET_PC
if ((dusk::version::isRegionJpn() && i < 4) || i < 3)
#elif VERSION == VERSION_GCN_JPN
if (i < 4)
#else
if (i < 3)
#endif
if (i < OPTION_SELECT(PROC_CHANGE_MOVE_e))
{
menuShow(i);
} else {
@@ -1710,9 +1720,11 @@ void dMenu_Option_c::screenSet() {
mpString->getString(0x55C, field_0x270[2], NULL, NULL, NULL, 0);
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
field_0x25c[i] = (J2DTextBox*)mpTVScreen->search(tv_btnA[i]);
mpTVScreen->search(ftv_btnA[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpTVScreen->search(ftv_btnA[i])->hide();
}
} else {
field_0x25c[i] = (J2DTextBox*)mpTVScreen->search(ftv_btnA[i]);
mpTVScreen->search(tv_btnA[i])->hide();
@@ -2210,19 +2222,6 @@ void dMenu_Option_c::setSoundString() {
}
void dMenu_Option_c::setCursorPos(u8 i_index) {
#if TARGET_PC
if (!dusk::version::isRegionJpn()) {
switch (i_index) {
case PROC_VIB_e:
i_index = 1;
break;
case PROC_SOUND_e:
i_index = 2;
break;
}
}
#endif
#if TARGET_PC || VERSION != VERSION_GCN_JPN
IF_DUSK_BLOCK(!dusk::version::isRegionJpn())
if (i_index == 4) {
@@ -2279,33 +2278,13 @@ void dMenu_Option_c::setSelectColor(u8 param_0, bool param_1) {
}
u8 dMenu_Option_c::getSelectType() {
#if TARGET_PC
u8 proc = 0;
if (field_0x3ef < PROC_CHANGE_MOVE_e) {
proc = field_0x3ef;
} else if (field_0x3f5 < PROC_CHANGE_MOVE_e) {
proc = field_0x3f5;
}
if (!dusk::version::isRegionJpn()) {
switch (proc) {
case PROC_VIB_e:
return 1;
case PROC_SOUND_e:
return 2;
}
}
return proc;
#else
if (field_0x3ef < PROC_CHANGE_MOVE_e) {
if (field_0x3ef < OPTION_SELECT(PROC_CHANGE_MOVE_e)) {
return field_0x3ef;
}
if (field_0x3f5 < PROC_CHANGE_MOVE_e) {
if (field_0x3f5 < OPTION_SELECT(PROC_CHANGE_MOVE_e)) {
return field_0x3f5;
}
return 0;
#endif
}
void dMenu_Option_c::changeBarColor(bool i_changeColor) {
@@ -2513,9 +2492,9 @@ bool dMenu_Option_c::pointerConfirmSelect() {
field_0x3f7 = 1;
field_0x3f5 = field_0x3ef;
field_0x3ef = PROC_CONFIRM_OPEN_MOVE_e;
field_0x3ef = OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e);
dMeter2Info_set2DVibration();
(this->*init[field_0x3ef])();
(this->*init[OPTION_PROC(field_0x3ef)])();
return true;
}
#endif
@@ -2560,8 +2539,8 @@ bool dMenu_Option_c::dpdMenuMove() {
}
if (getSelectType() != i) {
field_0x3ef = selectProc;
setCursorPos(field_0x3ef);
field_0x3ef = OPTION_SELECT(selectProc);
setCursorPos(i);
Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f,
-1.0f, 0);
}
@@ -2573,8 +2552,8 @@ bool dMenu_Option_c::dpdMenuMove() {
case PROC_ATTEN_e:
field_0x3e4 ^= 1;
field_0x3da = 5;
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_ATTEN_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f,
-1.0f, 0);
return true;
@@ -2586,8 +2565,8 @@ bool dMenu_Option_c::dpdMenuMove() {
field_0x3e5_JPN = 0;
field_0x3da = 5;
}
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_RUBY_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_RUBY_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return true;
case PROC_VIB_e:
@@ -2597,8 +2576,8 @@ bool dMenu_Option_c::dpdMenuMove() {
mDoCPd_c::startMotorWave(0, &field_0x3e0, JUTGamePad::CRumble::VAL_0, 0x3c);
}
field_0x3da = 5;
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_VIB_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_VIB_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f,
-1.0f, 0);
}
@@ -2612,8 +2591,8 @@ bool dMenu_Option_c::dpdMenuMove() {
field_0x3da = 5;
mDoAud_setOutputMode(dMo_soundMode[field_0x3e9]);
setSoundMode(dMo_soundMode[field_0x3e9]);
field_0x3ef = PROC_CHANGE_MOVE_e;
field_0x3f5 = PROC_SOUND_e;
field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e);
field_0x3f5 = OPTION_SELECT(PROC_SOUND_e);
Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f,
-1.0f, 0);
return true;
+45 -33
View File
@@ -333,11 +333,13 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
mpScreen->search(MULTI_CHAR('yx_te_s3'))->hide();
mpScreen->search(MULTI_CHAR('yx_te_s4'))->hide();
mpScreen->search(MULTI_CHAR('yx_text'))->hide();
IF_DUSK_BLOCK(dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn)
mpScreen->search(MULTI_CHAR('fyx_te_1'))->hide();
mpScreen->search(MULTI_CHAR('fyx_te_2'))->hide();
mpScreen->search(MULTI_CHAR('fyx_te_3'))->hide();
mpScreen->search(MULTI_CHAR('fyx_te_4'))->hide();
mpScreen->search(MULTI_CHAR('fyx_tex'))->hide();
IF_DUSK_BLOCK_END
mpScreen->search(MULTI_CHAR('x_btn_n'))->hide();
mpScreen->search(MULTI_CHAR('y_btn_n'))->hide();
}
@@ -345,9 +347,11 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
for (i = 0; i < 5; i++) {
#if TARGET_PC
J2DTextBox* fxy_TextBox;
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
fxy_TextBox = (J2DTextBox*)mpScreen->search(xy_text[i]);
mpScreen->search(fxy_text[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(fxy_text[i])->hide();
}
} else {
fxy_TextBox = (J2DTextBox*)mpScreen->search(fxy_text[i]);
mpScreen->search(xy_text[i])->hide();
@@ -366,13 +370,17 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
for (i = 0; i < 5; i++) {
#if TARGET_PC
J2DTextBox* fc_TextBox;
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
if (dusk::getSettings().game.swapDirectSelect) {
fc_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]);
mpScreen->search(fc_text1[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(fc_text1[i])->hide();
}
} else {
fc_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]);
mpScreen->search(fc_text[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(fc_text[i])->hide();
}
}
} else {
if (dusk::getSettings().game.swapDirectSelect) {
@@ -397,13 +405,17 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
for (i = 0; i < 5; i++) {
#if TARGET_PC
J2DTextBox* fc1_TextBox;
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
if (dusk::getSettings().game.swapDirectSelect) {
fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]);
mpScreen->search(fc_text[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(fc_text[i])->hide();
}
} else {
fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]);
mpScreen->search(fc_text1[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(fc_text1[i])->hide();
}
}
} else {
if (dusk::getSettings().game.swapDirectSelect) {
@@ -427,9 +439,11 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
}
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
mpComboOffString[i] = (J2DTextBox*)mpScreen->search(t_on[i]);
mpScreen->search(ft_on[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(ft_on[i])->hide();
}
} else {
mpComboOffString[i] = (J2DTextBox*)mpScreen->search(ft_on[i]);
mpScreen->search(t_on[i])->hide();
@@ -447,9 +461,11 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
}
for (int i = 0; i < 5; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
mpBowArrowComboString[i] = (J2DTextBox*)mpScreen->search(t_off[i]);
mpScreen->search(ft_off[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpScreen->search(ft_off[i])->hide();
}
} else {
mpBowArrowComboString[i] = (J2DTextBox*)mpScreen->search(ft_off[i]);
mpScreen->search(t_off[i])->hide();
@@ -486,19 +502,21 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
mpCircle = JKR_NEW CPaneMgr(mpCenterScreen, MULTI_CHAR('circle_n'), 2, NULL);
J2DTextBox* textBox[4];
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n04'));
textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n05'));
textBox[2] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n06'));
textBox[3] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n07'));
J2DPane* pane = mpCenterScreen->search(MULTI_CHAR('fitem_n1'));
pane->mVisible = false;
pane = mpCenterScreen->search(MULTI_CHAR('fitem_n2'));
pane->mVisible = false;
pane = mpCenterScreen->search(MULTI_CHAR('fitem_n3'));
pane->mVisible = false;
pane = mpCenterScreen->search(MULTI_CHAR('fitem_n4'));
pane->mVisible = false;
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
J2DPane* pane = mpCenterScreen->search(MULTI_CHAR('fitem_n1'));
pane->mVisible = false;
pane = mpCenterScreen->search(MULTI_CHAR('fitem_n2'));
pane->mVisible = false;
pane = mpCenterScreen->search(MULTI_CHAR('fitem_n3'));
pane->mVisible = false;
pane = mpCenterScreen->search(MULTI_CHAR('fitem_n4'));
pane->mVisible = false;
}
} else {
textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n1'));
textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n2'));
@@ -1292,17 +1310,11 @@ void dMenu_Ring_c::setScale() {
void dMenu_Ring_c::setNameString(u32 i_stringID) {
J2DTextBox* textBox[4];
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n04'));
textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n05'));
textBox[2] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n06'));
textBox[3] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n07'));
} else {
textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n1'));
textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n2'));
textBox[2] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n3'));
textBox[3] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n4'));
}
const bool useDomestic = dusk::version::isJpnOrLessThanWiiJpn();
textBox[0] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n04') : MULTI_CHAR('fitem_n1'));
textBox[1] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n05') : MULTI_CHAR('fitem_n2'));
textBox[2] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n06') : MULTI_CHAR('fitem_n3'));
textBox[3] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n07') : MULTI_CHAR('fitem_n4'));
#elif VERSION == VERSION_GCN_JPN
textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n04'));
textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n05'));
@@ -1798,7 +1810,7 @@ void dMenu_Ring_c::drawSelectItem() {
if (field_0x674[i] != 0) {
#if TARGET_PC
mSelectItemSlideElapsed[i] += dusk::game_clock::consume_interval(this);
const f32 u = std::min(mSelectItemSlideElapsed[i] / dusk::game_clock::period_for_original_frames(10.0f), 1.0f);
const f32 u = std::min(mSelectItemSlideElapsed[i] / (dusk::game_clock::kSimPeriod * 10.0f), 1.0f);
if (u >= 1.0f) {
setSelectItemForce(i);
} else {
+7 -5
View File
@@ -123,7 +123,13 @@ public:
#endif
}
void setCaptureFlag() { mFlag = 1; }
void setCaptureFlag() {
mFlag = 1;
#ifdef TARGET_PC
dusk::frame_interp::request_presentation_sync();
#endif
}
bool checkDraw() { return mFlag; }
u8 getAlpha() { return mAlpha; }
u8 getTopFlag() { return mTopFlag; }
@@ -1092,10 +1098,6 @@ void dMw_c::dMw_ring_create(u8 i_origin) {
}
mpCapture->setCaptureFlag();
#ifdef TARGET_PC
dusk::frame_interp::request_presentation_sync();
#endif
}
bool dMw_c::dMw_ring_delete() {
+16
View File
@@ -1386,6 +1386,22 @@ void dMeter2Draw_c::initButtonCross() {
dMeter2Info_getString(
0x62, static_cast<J2DTextBox*>(mpScreen->search(MULTI_CHAR('cont_ju9')))->getStringPtr(), NULL);
#if TARGET_PC
// These panes are not wide enough for French text (and possibly other languages)
// on Wii PAL. Resize them to always match their counterparts in later releases.
static u64 const juTags[] = {
MULTI_CHAR('cont_ju0'), MULTI_CHAR('cont_ju1'), MULTI_CHAR('cont_ju2'),
MULTI_CHAR('cont_ju3'), MULTI_CHAR('cont_ju4'), MULTI_CHAR('cont_ju5'),
MULTI_CHAR('cont_ju6'), MULTI_CHAR('cont_ju7'), MULTI_CHAR('cont_ju8'),
MULTI_CHAR('cont_ju9'),
};
for (u64 tag : juTags) {
J2DPane* pane = mpScreen->search(tag);
pane->resize(120.0f, pane->getHeight());
}
#endif
mpButtonCrossParent->setAlphaRate(0.0f);
drawButtonCross(g_drawHIO.mButtonCrossOFFPosX, g_drawHIO.mButtonCrossOFFPosY);
}
+4 -2
View File
@@ -1208,9 +1208,11 @@ void dMeterButton_c::screenInitButton() {
for (int i = 0; i < 10; i++) {
#if TARGET_PC
if (dusk::version::isRegionJpn()) {
if (dusk::version::isJpnOrLessThanWiiJpn()) {
mpTextBox[i] = (J2DTextBox*)mpButtonScreen->search(text_tag[i]);
mpButtonScreen->search(ftext_tag[i])->hide();
if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) {
mpButtonScreen->search(ftext_tag[i])->hide();
}
} else {
mpTextBox[i] = (J2DTextBox*)mpButtonScreen->search(ftext_tag[i]);
mpButtonScreen->search(text_tag[i])->hide();
+5 -30
View File
@@ -30,6 +30,7 @@
#include "m_Do/m_Do_lib.h"
#if TARGET_PC
#include "dusk/language.hpp"
#include "dusk/menu_pointer.h"
#include "dusk/settings.h"
#include "dusk/version.hpp"
@@ -1731,7 +1732,9 @@ void dMsgObject_c::readMessageGroupLocal(mDoDvdThd_mountXArchive_c** p_arcMount)
#endif
int msgGroup = dStage_stagInfo_GetMsgGroup(dComIfGp_getStage()->getStagInfo());
#if REGION_PAL
#if TARGET_PC
snprintf(arcName, sizeof(arcName), "/res/%s/bmgres%d.arc", dusk::language::msg_folder(), msgGroup);
#elif REGION_PAL
switch (dComIfGs_getPalLanguage()) {
case dSv_player_config_c::LANGUAGE_GERMAN:
sprintf(arcName, "/res/Msgde/bmgres%d.arc", msgGroup);
@@ -1748,39 +1751,11 @@ void dMsgObject_c::readMessageGroupLocal(mDoDvdThd_mountXArchive_c** p_arcMount)
default:
sprintf(arcName, "/res/Msguk/bmgres%d.arc", msgGroup);
}
#elif REGION_JPN
#elif REGION_JPN
sprintf(arcName, "/res/Msgjp/bmgres%d.arc", msgGroup);
#else
#if TARGET_PC
// Original game UB
if (dusk::version::isRegionPal()) {
switch (dComIfGs_getPalLanguage()) {
case dSv_player_config_c::LANGUAGE_GERMAN:
snprintf(arcName, sizeof(arcName), "/res/Msgde/bmgres%d.arc", msgGroup);
break;
case dSv_player_config_c::LANGUAGE_FRENCH:
snprintf(arcName, sizeof(arcName), "/res/Msgfr/bmgres%d.arc", msgGroup);
break;
case dSv_player_config_c::LANGUAGE_SPANISH:
snprintf(arcName, sizeof(arcName), "/res/Msgsp/bmgres%d.arc", msgGroup);
break;
case dSv_player_config_c::LANGUAGE_ITALIAN:
snprintf(arcName, sizeof(arcName), "/res/Msgit/bmgres%d.arc", msgGroup);
break;
default:
snprintf(arcName, sizeof(arcName), "/res/Msguk/bmgres%d.arc", msgGroup);
}
} else if (dusk::version::isRegionJpn()) {
snprintf(arcName, sizeof(arcName), "/res/Msgjp/bmgres%d.arc", msgGroup);
} else {
snprintf(arcName, sizeof(arcName), "/res/Msgus/bmgres%d.arc", msgGroup);
}
#else
sprintf(arcName, "/res/Msgus/bmgres%d.arc", msgGroup);
#endif
#endif
*p_arcMount = mDoDvdThd_mountXArchive_c::create(arcName, 0, JKRArchive::MOUNT_MEM, NULL);
+55 -49
View File
@@ -24,6 +24,7 @@
#include "JSystem/JUtility/JUTConsole.h"
#ifdef TARGET_PC
#include "dusk/language.hpp"
#include "dusk/logging.h"
#include "dusk/main.h"
#include "dusk/mods/svc/save.hpp"
@@ -54,8 +55,8 @@ struct homeBtnData {
#if TARGET_PC
using namespace dusk::version;
#define LOGO_ARC versionSelect<const char*>({{GameVersion::GcnJpn, "Logo"}, {GameVersion::GcnPal, "LogoPal"}}, "LogoUs")
#define MSG_PATH versionSelect<const char*>({{GameVersion::GcnJpn, "/res/Msgjp/bmgres.arc"}}, "/res/Msgus/bmgres.arc")
#define LOGO_ARC regionSelect<const char*>("LogoUs", "LogoPal", "Logo")
#define MSG_PATH regionSelect<const char*>("/res/Msgus/bmgres.arc", "/res/Msgus/bmgres.arc", "/res/Msgjp/bmgres.arc")
#elif VERSION == VERSION_SHIELD
#define LOGO_ARC "LogoUs"
#define MSG_PATH "/res/Msgcn/bmgres.arc"
@@ -78,7 +79,20 @@ using namespace dusk::version;
#define PROGRESSIVE_MODE_ON OS_PROGRESSIVE_MODE_ON
#endif
#if PLATFORM_WII || VERSION == VERSION_SHIELD_DEBUG
// TODO: Probably shouldn't actually load LayoutRevo, so I disabled it for now
#if TARGET_PC && 0
using namespace dusk::version;
#define FMAP_RES_PATH platformSelect("/res/Layout/fmapres.arc", "/res/LayoutRevo/fmapresR.arc")
#define DMAP_RES_PATH platformSelect("/res/Layout/dmapres.arc", "/res/LayoutRevo/dmapresR.arc")
#define COLLECT_RES_PATH platformSelect("/res/Layout/clctres.arc", "/res/LayoutRevo/clctresR.arc")
#define MSG_COM_PATH platformSelect("/res/Layout/msgcom.arc", "/res/LayoutRevo/msgcomR.arc")
#define MSG_RES0_PATH platformSelect("/res/Layout/msgres00.arc", "/res/LayoutRevo/msgres00R.arc")
#define MSG_RES1_PATH platformSelect("/res/Layout/msgres01.arc", "/res/LayoutRevo/msgres01R.arc")
#define MSG_RES2_PATH platformSelect("/res/Layout/msgres02.arc", "/res/LayoutRevo/msgres02R.arc")
#define MSG_RES3_PATH platformSelect("/res/Layout/msgres03.arc", "/res/LayoutRevo/msgres03R.arc")
#elif PLATFORM_WII || VERSION == VERSION_SHIELD_DEBUG
#define FMAP_RES_PATH "/res/LayoutRevo/fmapresR.arc"
#define DMAP_RES_PATH "/res/LayoutRevo/dmapresR.arc"
#define COLLECT_RES_PATH "/res/LayoutRevo/clctresR.arc"
@@ -100,7 +114,10 @@ using namespace dusk::version;
#define MSG_RES3_PATH "/res/Layout/msgres03.arc"
#endif
#if PLATFORM_WII || PLATFORM_SHIELD
#if TARGET_PC
#define ICON_RES_PATH "/res/CardIcon/cardicon.arc"
#define PARTICLE_COM_PATH platformSelect<const char*>("/res/Particle/common.jpc", "/res/Particle/common-r.jpc")
#elif PLATFORM_WII || PLATFORM_SHIELD
#define ICON_RES_PATH "/res/WiiBannerIcon/bannerIcon.arc"
#define PARTICLE_COM_PATH "/res/Particle/common-r.jpc"
#else
@@ -108,7 +125,13 @@ using namespace dusk::version;
#define PARTICLE_COM_PATH "/res/Particle/common.jpc"
#endif
#if PLATFORM_WII
// TODO: Probably shouldn't actually load LayoutRevo, so I disabled it for now
#if TARGET_PC && 0
#define RING_RES_PATH platformSelect("/res/Layout/ringres.arc", "/res/LayoutRevo/ringresR.arc")
#define ITEM_INF_RES_PATH platformSelect("/res/Layout/itmInfRes.arc", "/res/LayoutRevo/itmInfResR.arc")
#define BUTTON_RES_PATH platformSelect("/res/Layout/button.arc", "/res/LayoutRevo/buttonR.arc")
#define MAIN2D_PATH platformSelect("/res/Layout/main2D.arc", "/res/LayoutRevo/main2DR.arc")
#elif PLATFORM_WII
#define RING_RES_PATH "/res/LayoutRevo/ringresR.arc"
#define ITEM_INF_RES_PATH "/res/LayoutRevo/itmInfResR.arc"
#define BUTTON_RES_PATH "/res/LayoutRevo/buttonR.arc"
@@ -867,7 +890,7 @@ dScnLogo_c::~dScnLogo_c() {
JKR_DELETE(mProgressiveSel);
#if TARGET_PC
if (getGameVersion() == GameVersion::GcnPal) {
if (isRegionPal()) {
mpPalLogoResCommand->getArchive()->removeResourceAll();
mpPalLogoResCommand->getArchive()->unmount();
mpPalLogoResCommand->destroy();
@@ -979,7 +1002,7 @@ dScnLogo_c::~dScnLogo_c() {
mDoExt_setAraCacheSize(free_size - aram_heap->getTotalFreeSize());
#if TARGET_PC
if (getGameVersion() == GameVersion::GcnJpn) {
if (isRegionJpn()) {
if (dComIfGp_getFontArchive() != NULL) {
dComIfGp_getFontArchive()->unmount();
dComIfGp_setFontArchive(NULL);
@@ -1042,7 +1065,7 @@ static int phase_0(dScnLogo_c* i_this) {
JKRHEAP_NAME(i_this->mLogo01Heap, "Logo01");
#if TARGET_PC || VERSION == VERSION_GCN_PAL
IF_DUSK_BLOCK(getGameVersion() == GameVersion::GcnPal)
IF_DUSK_BLOCK(isRegionPal())
switch (i_this->getPalLanguage()) {
case 1:
i_this->mpPalLogoResCommand = mDoDvdThd_mountArchive_c::create("/res/Layout/LogoPalGm.arc", 0, NULL);
@@ -1083,7 +1106,7 @@ static int phase_1(dScnLogo_c* i_this) {
#endif
#if TARGET_PC || VERSION == VERSION_GCN_PAL
IF_DUSK_BLOCK(getGameVersion() == GameVersion::GcnPal)
IF_DUSK_BLOCK(isRegionPal())
if (!mDoDvdThd::SyncWidthSound) {
return cPhs_INIT_e;
}
@@ -1318,7 +1341,7 @@ void dScnLogo_c::logoInitGC() {
mDolbyLogo = JKR_NEW dDlst_2D_c(dolbyImg, 189, 150, 232, 112, 255);
#if TARGET_PC
if (getGameVersion() == GameVersion::GcnPal) {
if (isRegionPal()) {
u8 language = getPalLanguage();
if (language >= 5) {
language = 0;
@@ -1581,30 +1604,15 @@ void dScnLogo_c::dvdDataLoad() {
mpButtonCommand = aramMount(BUTTON_RES_PATH, mDoExt_getJ2dHeap());
mpCardIconCommand = aramMount(ICON_RES_PATH, mDoExt_getJ2dHeap());
#if TARGET_PC
if (getGameVersion() == GameVersion::GcnPal) {
switch (getPalLanguage()) {
case 1:
mpBmgResCommand = onMemMount("/res/Msgde/bmgres.arc");
break;
case 2:
mpBmgResCommand = onMemMount("/res/Msgfr/bmgres.arc");
break;
case 3:
mpBmgResCommand = onMemMount("/res/Msgsp/bmgres.arc");
break;
case 4:
mpBmgResCommand = onMemMount("/res/Msgit/bmgres.arc");
break;
case 0:
default:
mpBmgResCommand = onMemMount("/res/Msguk/bmgres.arc");
break;
}
} else {
mpBmgResCommand = onMemMount(MSG_PATH);
}
#elif VERSION == VERSION_GCN_PAL
#if TARGET_PC
#if AVOID_UB
static char bmgPath[32];
#else
static char bmgPath[22];
#endif
snprintf(bmgPath, sizeof(bmgPath), "/res/%s/bmgres.arc", dusk::language::msg_folder());
mpBmgResCommand = onMemMount(bmgPath);
#elif VERSION == VERSION_GCN_PAL
switch (getPalLanguage()) {
case 1:
mpBmgResCommand = onMemMount("/res/Msgde/bmgres.arc");
@@ -1623,7 +1631,7 @@ void dScnLogo_c::dvdDataLoad() {
mpBmgResCommand = onMemMount("/res/Msguk/bmgres.arc");
break;
}
#elif VERSION == VERSION_SHIELD_DEBUG
#elif VERSION == VERSION_SHIELD_DEBUG
switch (getPalLanguage()) {
case 2:
mpBmgResCommand = onMemMount("/res/Msgfr/bmgres.arc");
@@ -1635,9 +1643,9 @@ void dScnLogo_c::dvdDataLoad() {
mpBmgResCommand = onMemMount("/res/Msgus/bmgres.arc");
break;
}
#else
#else
mpBmgResCommand = onMemMount(MSG_PATH);
#endif
#endif
mpMsgComCommand = aramMount(MSG_COM_PATH, mDoExt_getJ2dHeap());
mpMsgResCommand[0] = aramMount(MSG_RES0_PATH, mDoExt_getJ2dHeap());
@@ -1645,8 +1653,10 @@ void dScnLogo_c::dvdDataLoad() {
mpMsgResCommand[2] = aramMount(MSG_RES2_PATH, mDoExt_getJ2dHeap());
mpMsgResCommand[3] = aramMount(MSG_RES3_PATH, mDoExt_getJ2dHeap());
#if TARGET_PC
const auto res4Path = versionSelect<const char*>({{GameVersion::GcnJpn, "/res/Layout/msgres04.arc"}}, "/res/Layout/msgres04F.arc");
mpMsgResCommand[4] = aramMount( res4Path, mDoExt_getJ2dHeap());
const auto res4Path = regionSelect<const char*>("/res/Layout/msgres04F.arc",
"/res/Layout/msgres04F.arc",
"/res/Layout/msgres04.arc");
mpMsgResCommand[4] = aramMount(res4Path, mDoExt_getJ2dHeap());
#elif VERSION == VERSION_GCN_JPN
mpMsgResCommand[4] = aramMount("/res/Layout/msgres04.arc", mDoExt_getJ2dHeap());
#else
@@ -1658,16 +1668,12 @@ void dScnLogo_c::dvdDataLoad() {
mpMain2DCommand = onMemMount(MAIN2D_PATH);
#if TARGET_PC
const auto fontResPath = versionSelect<const char*>(
{
{GameVersion::GcnJpn, "/res/Fontjp/fontres.arc"},
{GameVersion::GcnPal, "/res/Fonteu/fontres.arc"},
}, "/res/Fontus/fontres.arc");
const auto fontRubyPath = versionSelect<const char*>(
{
{GameVersion::GcnJpn, "/res/Fontjp/rubyres.arc"},
{GameVersion::GcnPal, "/res/Fonteu/rubyres.arc"},
}, "/res/Fontus/rubyres.arc");
const auto fontResPath = regionSelect<const char*>("/res/Fontus/fontres.arc",
"/res/Fonteu/fontres.arc",
"/res/Fontjp/fontres.arc");
const auto fontRubyPath = regionSelect<const char*>("/res/Fontus/rubyres.arc",
"/res/Fonteu/rubyres.arc",
"/res/Fontjp/rubyres.arc");
// Note: GCN_JPN mounts this archive as tail instead of head.
// I'm guessing this is fine since we have more RAM.
+3 -3
View File
@@ -1087,7 +1087,7 @@ void dSv_player_config_c::setVibration(u8 i_status) {
u8 dSv_player_config_c::getPalLanguage() const {
#if TARGET_PC || VERSION == VERSION_GCN_PAL
IF_DUSK_BLOCK(dusk::version::getGameVersion() == dusk::version::GameVersion::GcnPal)
IF_DUSK_BLOCK(dusk::version::isRegionPal())
switch (OSGetLanguage()) {
case 0:
return LANGUAGE_ENGLISH;
@@ -1829,7 +1829,7 @@ int dSv_info_c::memory_to_card(char* card_ptr, int dataNum) {
savedata->getPlayer().getPlayerInfo().setTotalTime(play_time);
}
savedata->getPlayer().getPlayerStatusB().setDateIpl(OSGetTime());
savedata->getPlayer().getPlayerStatusB().setDateIpl(DUSK_IF_ELSE(OSGetSystemTime(), OSGetTime()));
memcpy(card_ptr, savedata, sizeof(dSv_save_c));
card_ptr += 0x958;
@@ -2036,7 +2036,7 @@ void flagFile_c::listenPropertyEvent(const JORPropertyEvent* i_event) {
}
case 102: {
OSCalendarTime time;
OSTicksToCalendarTime(OSGetTime(), &time);
OSTicksToCalendarTime(DUSK_IF_ELSE(OSGetSystemTime(), OSGetTime()), &time);
const char* start_stage_name = dComIfGp_getStartStageName();
char filename[64];
+16 -4
View File
@@ -905,8 +905,16 @@ int dShopSystem_c::seq_start(fopAc_ac_c* actor, dMsgFlow_c* i_flow) {
int itemNo;
if (mFlow.getEventId(&itemNo) == 1) {
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId = fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1,
-1, NULL, NULL);
#if TARGET_PC
const char* itemCheckName = nullptr;
if (itemNo == dItemNo_HALF_MILK_BOTTLE_e) {
itemCheckName = "sera_reward";
itemNo = dusk::mods::item_check(itemCheckName, itemNo, actor);
}
#endif
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL,
NULL IF_DUSK_ARG(dusk::mods::item_give_tag(itemCheckName)));
}
if (fpcEx_IsExist(mItemPartnerId)) {
@@ -1195,8 +1203,12 @@ int dShopSystem_c::seq_decide_yes(fopAc_ac_c* actor, dMsgFlow_c* i_flow) {
if (mFlow.getEventId(&itemNo) == 1) {
if (i_flow->doFlow(actor, NULL, 0)) {
if (mItemPartnerId == fpcM_ERROR_PROCESS_ID_e) {
mItemPartnerId =
fopAcM_createItemForPresentDemo(&current.pos, itemNo, 0, -1, -1, NULL, NULL);
#if TARGET_PC
const u32 itemGiveTag = dusk::mods::item_give_tag_shop(itemNo & 0xFF);
itemNo = dusk::mods::item_check_shop(itemNo & 0xFF, actor);
#endif
mItemPartnerId = fopAcM_createItemForPresentDemo(
&current.pos, itemNo, 0, -1, -1, NULL, NULL IF_DUSK_ARG(itemGiveTag));
}
if (fpcEx_IsExist(mItemPartnerId)) {
+9
View File
@@ -41,6 +41,15 @@ bool isActionBound(ActionBinds action, u32 port) {
return getActionBindButton(action, port) != PAD_NATIVE_BUTTON_INVALID;
}
bool isActionBoundAnyPort(ActionBinds action) {
for (u32 port = 0; port < PAD_CHANMAX; ++port) {
if (isActionBound(action, port)) {
return true;
}
}
return false;
}
void updateActionBindings() {
for (u32 port = 0; port < PAD_CHANMAX; ++port) {
// Move the current press to the previous frame
+1
View File
@@ -31,6 +31,7 @@ using ActionBindsMap = std::unordered_map<ActionBinds, ActionBindData>;
ActionBindsMap& getActionBinds();
bool isActionBound(ActionBinds action, u32 port);
bool isActionBoundAnyPort(ActionBinds action);
void updateActionBindings();
+11
View File
@@ -23,9 +23,20 @@ bool LoadDolAsset(void* dst, std::initializer_list<OffsetVersion> virtualAddress
*/
bool LoadRelAsset(void* dst, const char* dvdPath, std::initializer_list<OffsetVersion> offset, s32 size);
template <typename T, size_t N>
bool LoadRelAsset(T (&dst)[N], const char* dvdPath, std::initializer_list<OffsetVersion> offset) {
return LoadRelAsset(static_cast<void*>(dst), dvdPath, offset, static_cast<s32>(sizeof(dst)));
}
/**
* Load bytes from a REL inside RELS.arc
*/
bool LoadArchivedRelAsset(void* dst, u32 memType, const char* relFileName, std::initializer_list<OffsetVersion> offset, s32 size);
template <typename T, size_t N>
bool LoadArchivedRelAsset(T (&dst)[N], u32 memType, const char* relFileName,
std::initializer_list<OffsetVersion> offset) {
return LoadArchivedRelAsset(static_cast<void*>(dst), memType, relFileName, offset, static_cast<s32>(sizeof(dst)));
}
} // namespace dusk
+4
View File
@@ -147,6 +147,10 @@ void begin_frame(FrameInterpMode mode, bool is_sim_frame, float step) {
g_enabled = mode != FrameInterpMode::Off;
g_is_sim_frame = is_sim_frame;
g_step = std::clamp(step, 0.0f, 1.0f);
if (!g_enabled) {
g_interpolating = false;
clear_replacements();
}
}
bool is_enabled() {
+86 -55
View File
@@ -1,104 +1,135 @@
#include "dusk/game_clock.h"
#include <algorithm>
#include <aurora/time.hpp>
#include <chrono>
#include <cmath>
#include <unordered_map>
#include <dusk/frame_interpolation.h>
#include <unordered_map>
namespace dusk::game_clock {
using clock = std::chrono::steady_clock;
using native_clock = aurora::time::native_clock;
using game_clock = aurora::time::game_clock;
FrameTiming g_frameTiming;
namespace {
bool s_initialized = false;
clock::time_point s_previous_sample{};
clock::time_point s_current_snapshot_time{};
bool s_fixedStepActive = false;
bool s_simTickActive = false;
native_clock::time_point s_previousNativeSample{};
game_clock::time_point s_latestGameSample{};
game_clock::time_point s_currentSnapshotTime{};
game_clock::time_point s_pendingSimTime{};
std::unordered_map<uintptr_t, clock::time_point> s_interval_last_sample;
std::unordered_map<uintptr_t, game_clock::time_point> s_intervalLastSample;
constexpr clock::duration kSimPeriodDuration =
std::chrono::duration_cast<clock::duration>(std::chrono::duration<float>(sim_pace()));
constexpr clock::duration kAbnormalGapResetThreshold = std::chrono::milliseconds(250);
constexpr int kMaxSimTicksPerFrame = 2;
constexpr game_clock::duration kSimPeriodDuration =
std::chrono::duration_cast<game_clock::duration>(std::chrono::duration<float>(kSimPeriod));
constexpr native_clock::duration kAbnormalGapResetThreshold = std::chrono::milliseconds(250);
constexpr int kMaxSimTicksPerFrame = static_cast<int>(aurora::time::kMaximumTimeScale) * 4;
} // namespace
void ensure_initialized() {
void initialize() {
if (s_initialized) {
return;
}
s_previous_sample = clock::now();
s_current_snapshot_time = s_previous_sample;
s_previousNativeSample = native_clock::now();
s_latestGameSample = game_clock::now();
s_currentSnapshotTime = s_latestGameSample;
s_pendingSimTime = s_latestGameSample;
s_initialized = true;
}
void reset_frame_timer() {
s_previous_sample = clock::now();
s_current_snapshot_time = s_previous_sample - kSimPeriodDuration;
void reset() {
s_previousNativeSample = native_clock::now();
s_latestGameSample = game_clock::now();
s_currentSnapshotTime = s_latestGameSample - kSimPeriodDuration;
s_pendingSimTime = s_currentSnapshotTime;
s_simTickActive = false;
}
MainLoopPacer advance_main_loop() {
ensure_initialized();
const FrameTiming& advance() {
const auto nativeNow = native_clock::now();
const auto gameNow = game_clock::now();
const auto nativeFrameGap = nativeNow - s_previousNativeSample;
s_previousNativeSample = nativeNow;
s_latestGameSample = gameNow;
const clock::time_point now = clock::now();
const clock::duration frame_gap = now - s_previous_sample;
const float presentation_dt = std::chrono::duration<float>(frame_gap).count();
s_previous_sample = now;
auto& out = g_frameTiming;
out = {.dt = std::chrono::duration<float>().count()};
MainLoopPacer out{};
out.presentation_dt_seconds = presentation_dt;
const float timeScale = aurora::time::scale();
const bool interpolating =
getSettings().game.enableFrameInterpolation.getValue() != FrameInterpMode::Off;
const bool separatePresentation = interpolating || timeScale != 1.0f;
out.interpolating = interpolating;
out.separatePresentation = separatePresentation;
s_fixedStepActive = separatePresentation;
const bool should_interpolate = dusk::getSettings().game.enableFrameInterpolation.getValue() !=
dusk::FrameInterpMode::Off &&
!dusk::getTransientSettings().skipFrameRateLimit;
out.is_interpolating = should_interpolate;
out.sim_pace = sim_pace();
if (!should_interpolate) {
s_current_snapshot_time = now;
out.sim_ticks_to_run = 1;
if (!separatePresentation) {
s_currentSnapshotTime = gameNow;
out.numSimTicks = 1;
return out;
}
if (frame_gap > kAbnormalGapResetThreshold) {
s_current_snapshot_time = now - kSimPeriodDuration;
out.sim_ticks_to_run = 0;
const auto simulationTarget = interpolating ? gameNow - kSimPeriodDuration : gameNow;
if (timeScale == 0.f || nativeFrameGap > kAbnormalGapResetThreshold) {
s_currentSnapshotTime = simulationTarget;
out.numSimTicks = 0;
return out;
}
int sim_ticks_to_run = 0;
clock::time_point projected_snapshot_time = s_current_snapshot_time;
const clock::time_point render_time = now - kSimPeriodDuration;
while (sim_ticks_to_run < kMaxSimTicksPerFrame && projected_snapshot_time < render_time) {
projected_snapshot_time += kSimPeriodDuration;
sim_ticks_to_run++;
int numSimTicks = 0;
auto projectedSnapshotTime = s_currentSnapshotTime;
while (numSimTicks < kMaxSimTicksPerFrame) {
const bool tickDue = interpolating ?
projectedSnapshotTime < simulationTarget :
projectedSnapshotTime + kSimPeriodDuration <= simulationTarget;
if (!tickDue) {
break;
}
projectedSnapshotTime += kSimPeriodDuration;
numSimTicks++;
}
out.sim_ticks_to_run = sim_ticks_to_run;
out.numSimTicks = numSimTicks;
return out;
}
void begin_sim_tick() {
s_pendingSimTime =
s_fixedStepActive ? s_currentSnapshotTime + kSimPeriodDuration : s_latestGameSample;
s_simTickActive = true;
}
void commit_sim_tick() {
ensure_initialized();
s_current_snapshot_time += kSimPeriodDuration;
if (s_simTickActive) {
s_currentSnapshotTime = s_pendingSimTime;
s_simTickActive = false;
} else {
s_currentSnapshotTime += kSimPeriodDuration;
}
}
float sample_interpolation_step() {
ensure_initialized();
const float step =
std::chrono::duration<float>(clock::now() - s_current_snapshot_time).count() / sim_pace();
std::chrono::duration<float>(game_clock::now() - s_currentSnapshotTime).count() /
kSimPeriod;
return std::clamp(step, 0.0f, 1.0f);
}
float consume_interval(const void* consumer) {
ensure_initialized();
const uintptr_t key = reinterpret_cast<uintptr_t>(consumer);
const clock::time_point now = clock::now();
float dt = ui_initial_dt();
const auto it = s_interval_last_sample.find(key);
if (it != s_interval_last_sample.end()) {
const auto key = reinterpret_cast<uintptr_t>(consumer);
const auto now = s_simTickActive ? s_pendingSimTime : game_clock::now();
const float timeScale = aurora::time::scale();
float dt = kUiInitialDt * timeScale;
if (const auto it = s_intervalLastSample.find(key); it != s_intervalLastSample.end()) {
dt = std::chrono::duration<float>(now - it->second).count();
dt = std::min(dt, ui_maximum_dt());
const float maximumDt = std::max(kUiMaximumDt * timeScale, kSimPeriod);
dt = std::min(dt, maximumDt);
}
s_interval_last_sample[key] = now;
s_intervalLastSample[key] = now;
return dt;
}
+18 -13
View File
@@ -2,22 +2,27 @@
namespace dusk::game_clock {
void ensure_initialized();
void reset_frame_timer();
// Amount of time that a simulation tick advances
constexpr float kSimPeriod = 1.0f / 30.0f;
constexpr float kUiMaximumDt = 0.05f;
constexpr float kUiInitialDt = 1.0f / 60.0f;
constexpr float sim_pace() { return 1.0f / 30.0f; }
constexpr float period_for_original_frames(float frame_count) { return frame_count * sim_pace(); }
constexpr float ui_maximum_dt() { return 0.05f; }
constexpr float ui_initial_dt() { return 1.0f / 60.0f; }
struct MainLoopPacer {
float presentation_dt_seconds;
bool is_interpolating;
int sim_ticks_to_run;
float sim_pace;
struct FrameTiming {
// Amount of time elapsed in seconds since the last advance
float dt;
// Whether interpolation is active
bool interpolating;
// Run simulation and presentation separately (for interpolation or time scaling)
bool separatePresentation;
// Number of simulation ticks to run
int numSimTicks;
};
extern FrameTiming g_frameTiming;
MainLoopPacer advance_main_loop();
void initialize();
void reset();
const FrameTiming& advance();
void begin_sim_tick();
void commit_sim_tick();
float sample_interpolation_step();
+210
View File
@@ -0,0 +1,210 @@
#include "aurora/texture.hpp"
#include "dusk/texture_replacements.hpp"
#include "fmt/format.h"
#include <array>
#include <cassert>
#include <span>
#include <numbers>
namespace {
constexpr u16 kMapIconResolutionMultiplier = 4;
constexpr u16 kMapImageSide = 16 * kMapIconResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
// give higher priority to user and mod replacements
constexpr auto kInternalTextureReplacementPriority = dusk::texture_replacements::kUserTextureReplacementPriority - 1;
typedef std::function<u8(size_t, size_t)> PaintI8Fn;
enum class ArcIndex : int {
Circle16 = 82, // map_icon_circle16x16_4i.bti - simple circle
Circle = 76, // im_map_icon_circle_4i.bti - outlined circle
Nijumaru = 78, // im_map_icon_nijumaru_4i.bti - concentric rings
Enter = 77, // im_map_icon_enter_4i.bti - outlined octagram
TryForce = 81, // im_map_icon_try_force_4i.bti - outlined circle with triangle
};
struct Replacement {
ArcIndex index;
PaintI8Fn painter;
};
struct Icon {
u8* origData = nullptr;
std::unique_ptr<u8[]> newData;
std::string label;
std::optional<aurora::texture::ReplacementRegistration> reg;
};
bool s_initialized = false;
bool s_active = false;
std::unordered_map<int, Icon> s_icons;
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
assert(width % 8 == 0 && dst.size() % 32 == 0);
const auto blocksAcross = width >> 3;
for (size_t i = 0; i < dst.size(); i++) {
// 8x4 block swizzling for I8
const auto blockIdx = i >> 5;
const auto localIdx = i & 31;
const auto blockY = blockIdx / blocksAcross;
const auto blockX = blockIdx % blocksAcross;
const auto localY = localIdx >> 3;
const auto localX = localIdx & 7;
const auto x = (blockX << 3) + localX;
const auto y = (blockY << 2) + localY;
dst[i] = paint(x, y);
}
}
void draw_all_replacements() {
constexpr auto center = kMapImageSide / 2.0f;
constexpr auto radiusSq = center * center;
// clang-format off
const auto replacements = std::to_array<Replacement>({
{
ArcIndex::Circle16,
[=](auto x, auto y) {
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
return (dx * dx + dy * dy < radiusSq) ? 0x11 : 0;
}
},
{
ArcIndex::Circle,
[=](auto x, auto y) {
constexpr auto innerRadius = kMapImageSide * 3.0f / 8.0f;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
return dSq < radiusSq ? (dSq < innerRadiusSq ? 0x22 : 0x11) : 0;
}
},
{
ArcIndex::Nijumaru,
[=](auto x, auto y) {
constexpr u8 nijumaruRings[] = {0x11, 0x22, 0x11, 0x11, 0x22, 0x22};
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
if (dSq < radiusSq) {
auto ringIndex = static_cast<size_t>(std::trunc(std::sqrt(dSq) / kMapImageSide * 12));
ringIndex = std::min(ringIndex, sizeof(nijumaruRings) - 1);
return nijumaruRings[ringIndex];
}
return u8{0};
}
},
{
ArcIndex::Enter,
[=](auto x, auto y) {
constexpr auto outlineWidth = kMapImageSide / 6.0f;
const auto adx = std::abs((x + 0.5f) - center);
const auto ady = std::abs((y + 0.5f) - center);
const auto dist =
std::min(adx + ady, std::max(adx, ady) * std::numbers::sqrt2_v<float>) -
kMapImageSide / 2.0f;
return dist > 0.0f ? 0 : (dist > -outlineWidth ? 0x22 : 0x33);
}
},
{
ArcIndex::TryForce,
[=](auto x, auto y) {
constexpr auto innerRadiusNorm = 5.0f / 12.0f;
constexpr auto innerRadius = kMapImageSide * innerRadiusNorm;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
constexpr auto triRadius = kMapImageSide * innerRadiusNorm / 2.0f;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
const auto triSideDist = (std::numbers::sqrt3_v<float> * std::abs(dx) - dy) * 0.5f;
const auto insideTri = std::max(dy, triSideDist) < triRadius;
return insideTri ? 0x22 : (dSq < radiusSq ? (dSq < innerRadiusSq ? 0x33 : 0x22) : 0);
}
}
});
// clang-format on
for (const auto r : replacements) {
auto pixels = std::make_unique_for_overwrite<u8[]>(kMapImageTotalPixels);
paint_i8(std::span{pixels.get(), kMapImageTotalPixels}, kMapImageSide, r.painter);
auto& icon = s_icons[static_cast<int>(r.index)];
icon.newData = std::move(pixels);
icon.label = fmt::format("hq minimap icon {}", static_cast<int>(r.index));
}
}
} // namespace
namespace dusk::hq_minimap {
void register_pointer(int idx, u8* ptr) {
if (s_initialized) {
return;
}
s_icons[idx].origData = ptr;
}
void set_active(bool active) {
s_active = active;
}
void update() {
if (!s_initialized) {
return;
}
for (auto& [idx, icon] : s_icons) {
const bool shouldBeRegistered = s_active && icon.origData && icon.newData;
if (shouldBeRegistered && !icon.reg) {
aurora::texture::ReplacementKey key{aurora::texture::TexturePointerKey{icon.origData}};
aurora::texture::RawTextureReplacement repl{
.bytes = std::span{icon.newData.get(), kMapImageTotalPixels},
.width = kMapImageSide,
.height = kMapImageSide,
.mipCount = 1,
.gxFormat = GX_TF_I8,
.label = icon.label,
};
icon.reg = aurora::texture::register_replacement(
key, repl, {.priority = kInternalTextureReplacementPriority});
} else if (!shouldBeRegistered && icon.reg) {
aurora::texture::unregister_replacement(*icon.reg);
icon.reg.reset();
}
}
}
void initialize_if_needed() {
if (s_initialized) {
return;
}
draw_all_replacements();
s_initialized = true;
update();
}
} // namespace dusk::hq_minimap
+21
View File
@@ -0,0 +1,21 @@
#pragma once
namespace dusk::hq_minimap {
/// Adds a mapping of an image resource index (into `Always.arc`) to the pointer to its image data.
/// If `initialize_if_needed` has been called, this is a no-op. Pointers are expected to be stable
/// and valid for the program's entire lifetime.
void register_pointer(int idx, u8* ptr);
/// Sets whether HQ minimap texture replacements should be active or not. Does not manage
/// replacement registrations itself; see `update`.
void set_active(bool active);
/// Registers or unregisters texture replacements depending on active state.
void update();
/// Called once after registering image pointers, in which their HQ replacements are procedurally
/// drawn and `update` is called. Further calls are no-ops.
void initialize_if_needed();
}
+31 -5
View File
@@ -1,8 +1,9 @@
#include <algorithm>
#include <array>
#include <aurora/aurora.h>
#include <chrono>
#include <numeric>
#include <string_view>
#include <chrono>
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui.h"
@@ -20,6 +21,7 @@
#include "dusk/frame_interpolation.h"
#include "dusk/livesplit.h"
#include "dusk/main.h"
#include "dusk/presentation.hpp"
#include "dusk/settings.h"
#include "dusk/ui/ui.hpp"
#include "dusk/gamemode.hpp"
@@ -38,6 +40,8 @@ using namespace std::string_literals;
using namespace std::string_view_literals;
namespace {
constexpr float kTurboTimeScale = 4.f;
ImGuiWindow* FindDragScrollWindow(ImGuiWindow* window) {
while (window != nullptr) {
const bool canScrollX = window->ScrollMax.x > 0.0f;
@@ -236,10 +240,32 @@ namespace dusk {
}
void ImGuiConsole::UpdateSettings() {
getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind &&
(ImGui::IsKeyDown(ImGuiKey_Tab) || getActionBindHoldAnyPort(ActionBinds::TURBO_SPEED_BUTTON));
static bool previousTurboActive = false;
static bool previousSlowActive = false;
static float previousTimeScale = 1.0f;
if (dusk::frame_interp::get_ui_tick_pending() && mDoMain::developmentMode == 1 && (mDoCPd_c::getHold(PAD_1) & (PAD_TRIGGER_R | PAD_TRIGGER_L)) == (PAD_TRIGGER_R | PAD_TRIGGER_L) && mDoCPd_c::getTrigY(PAD_1)) {
const bool turboBound = isActionBoundAnyPort(ActionBinds::TURBO_SPEED_BUTTON);
const bool turboActive =
getSettings().game.enableTurboKeybind &&
(turboBound ? getActionBindHoldAnyPort(ActionBinds::TURBO_SPEED_BUTTON) :
ImGui::IsKeyDown(ImGuiKey_Tab));
const bool slowDown = turboActive && ImGui::GetIO().KeyShift;
if (turboActive != previousTurboActive) {
getTransientSettings().turboMode = turboActive;
presentation::update_frame_rate_preference();
if (turboActive) {
previousTimeScale = aurora_get_timescale();
aurora_set_timescale(slowDown ? 1.f / kTurboTimeScale : kTurboTimeScale);
} else {
aurora_set_timescale(previousTimeScale);
}
} else if (turboActive && slowDown != previousSlowActive) {
aurora_set_timescale(slowDown ? 1.f / kTurboTimeScale : kTurboTimeScale);
}
previousTurboActive = turboActive;
previousSlowActive = slowDown;
if (frame_interp::get_ui_tick_pending() && mDoMain::developmentMode == 1 && (mDoCPd_c::getHold(PAD_1) & (PAD_TRIGGER_R | PAD_TRIGGER_L)) == (PAD_TRIGGER_R | PAD_TRIGGER_L) && mDoCPd_c::getTrigY(PAD_1)) {
getTransientSettings().moveLinkActive = !getTransientSettings().moveLinkActive;
}
if (mDoMain::developmentMode != 1) {
@@ -271,7 +297,7 @@ namespace dusk {
m_isHidden = true;
}
}
bool showMenu = !m_isHidden;
// The menu bar renders with ImGuiCol_WindowBg behind it. We just want ImGuiCol_MenuBarBg,
-5
View File
@@ -26,10 +26,6 @@
#include <TargetConditionals.h>
#endif
namespace aurora::gx {
extern bool enableLodBias;
}
namespace dusk {
ImGuiMenuTools::ImGuiMenuTools() {}
@@ -77,7 +73,6 @@ namespace dusk {
getSettings().game.disableWaterRefraction.setValue(disableWaterRefraction);
config::save();
}
ImGui::Checkbox("Enable LOD Bias", &aurora::gx::enableLodBias);
ImGui::EndMenu();
}
+18 -2
View File
@@ -40,10 +40,25 @@ constexpr auto AcceptedDiscs = std::to_array<borealis::disc::AcceptedDisc>({
.gameId = "GZ2P01",
.expectedHash = borealis::disc::parse_xxh3_128("9ef597588b0035ca9e91b333fa9a8a7e"),
},
{
.gameId = "RZDE01", .revision = 0,
.expectedHash = borealis::disc::parse_xxh3_128("b3d91fbea59e5c66934d04c01566728e"),
},
{
.gameId = "RZDE01", .revision = 2,
.expectedHash = borealis::disc::parse_xxh3_128("c3ec420921a1b36d6ae43f576491d25c"),
},
{
.gameId = "RZDJ01",
.expectedHash = borealis::disc::parse_xxh3_128("d3866821c7fc6999e6e8bbef8b6875aa"),
},
{
.gameId = "RZDP01",
.expectedHash = borealis::disc::parse_xxh3_128("6095a924a57e5fb4294ac96fb85a09a1"),
},
});
constexpr auto RecognizedGameIds =
std::to_array<std::string_view>({"RZDE01", "RZDJ01", "RZDK01", "RZDP01"});
constexpr auto RecognizedGameIds = std::to_array<std::string_view>({"RZDK01"});
constexpr borealis::disc::Catalog DiscCatalog{
.acceptedDiscs = AcceptedDiscs,
@@ -92,6 +107,7 @@ void update_info(const borealis::disc::Result& result, DiscInfo& info) noexcept
if (!result.metadata.gameId.empty()) {
info.platform = result.metadata.platform;
info.region = region_from_game_id(result.metadata.gameId);
info.revision = result.metadata.revision;
}
}
+1
View File
@@ -38,6 +38,7 @@ using VerificationStatus = borealis::disc::Progress;
struct DiscInfo {
Platform platform = Platform::Unknown;
Region region = Region::NorthAmerica;
std::uint8_t revision = 0;
};
ValidationError inspect(const char* path, DiscInfo& info);
+79
View File
@@ -0,0 +1,79 @@
#include "dusk/language.hpp"
#include "dusk/version.hpp"
namespace dusk::language {
namespace {
constexpr GameLanguage kEnglishOnly[] = {GameLanguage::English};
constexpr GameLanguage kJapaneseOnly[] = {GameLanguage::Japanese};
constexpr GameLanguage kPalLanguages[] = {
GameLanguage::English,
GameLanguage::German,
GameLanguage::French,
GameLanguage::Spanish,
GameLanguage::Italian,
};
constexpr GameLanguage kWiiUsaLanguages[] = {
GameLanguage::English,
GameLanguage::French,
GameLanguage::Spanish,
};
} // namespace
std::span<const GameLanguage> available_languages(const iso::DiscInfo& info) noexcept {
switch (info.region) {
case iso::Region::Japan:
return kJapaneseOnly;
case iso::Region::Europe:
return kPalLanguages;
case iso::Region::NorthAmerica:
if (info.platform == iso::Platform::Wii && info.revision == 2) {
return kWiiUsaLanguages;
}
return kEnglishOnly;
default:
return kEnglishOnly;
}
}
const char* language_name(GameLanguage language) noexcept {
switch (language) {
case GameLanguage::English:
return "English";
case GameLanguage::German:
return "German";
case GameLanguage::French:
return "French";
case GameLanguage::Spanish:
return "Spanish";
case GameLanguage::Italian:
return "Italian";
case GameLanguage::Japanese:
return "Japanese";
}
return "English";
}
const char* msg_folder() noexcept {
using namespace version;
switch (getSettings().game.language.getValue()) {
case GameLanguage::German:
return "Msgde";
case GameLanguage::French:
return "Msgfr";
case GameLanguage::Spanish:
return "Msgsp";
case GameLanguage::Italian:
return "Msgit";
case GameLanguage::Japanese:
return "Msgjp";
case GameLanguage::English:
default:
return isRegionPal() ? "Msguk" : "Msgus";
}
}
} // namespace dusk::language
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "dusk/iso_validate.hpp"
#include "dusk/settings.h"
#include <span>
namespace dusk::language {
std::span<const GameLanguage> available_languages(const iso::DiscInfo& info) noexcept;
const char* language_name(GameLanguage language) noexcept;
const char* msg_folder() noexcept;
} // namespace dusk::language
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include <cstdint>
class fopAc_ac_c;
namespace dusk::mods {
uint8_t item_check(const char* name, uint8_t itemNo, fopAc_ac_c* giver);
uint8_t item_check_tagged(uint32_t giveTag, uint8_t itemNo, fopAc_ac_c* giver);
uint8_t item_check_chest(uint8_t boxNo, uint8_t itemNo, fopAc_ac_c* chest);
uint8_t item_check_boss(uint8_t itemNo, fopAc_ac_c* boss);
uint8_t item_check_freestanding(uint8_t bitNo, uint8_t itemNo, fopAc_ac_c* item);
uint8_t item_check_poe(uint8_t bitNo, uint8_t itemNo, fopAc_ac_c* poe);
uint8_t item_check_shop(uint8_t itemNo, fopAc_ac_c* giver);
uint8_t item_check_bug(uint8_t insectId, uint8_t itemNo, fopAc_ac_c* agitha);
uint8_t item_check_sky_character(uint8_t itemNo, fopAc_ac_c* statue);
uint32_t item_give_tag(const char* name);
uint32_t item_give_tag_chest(uint8_t boxNo);
uint32_t item_give_tag_boss();
uint32_t item_give_tag_freestanding(uint8_t bitNo);
uint32_t item_give_tag_poe(uint8_t bitNo);
uint32_t item_give_tag_shop(uint8_t itemNo);
uint32_t item_give_tag_bug(uint8_t insectId);
uint32_t item_give_tag_sky_character();
void item_check_enqueue(const char* name, uint8_t itemNo);
void item_check_enqueue_poe(uint8_t bitNo, uint8_t itemNo);
void item_granted(uint8_t itemNo, uint32_t giveTag, fopAc_ac_c* giver);
bool item_give_queue_dispatching();
uint32_t item_give_queue_take_tag();
} // namespace dusk::mods
+294
View File
@@ -0,0 +1,294 @@
#include "item.hpp"
#include "dusk/mod_loader.hpp"
#include "dusk/mods/loader/loader.hpp"
#include "dusk/mods/svc/item.hpp"
#include "aurora/lib/logging.hpp"
#include "d/d_com_inf_game.h"
#include <fmt/format.h>
#include <exception>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace dusk::mods {
namespace {
aurora::Module Log{"dusk::mods::item_checks"};
struct CheckOverride {
std::string name;
uint8_t itemNo = 0;
};
struct CheckResolver {
ItemCheckHandle handle = 0;
std::string name;
ItemCheckResolveFn fn = nullptr;
void* userData = nullptr;
};
struct ModItemChecks {
std::vector<CheckOverride> overrides;
std::vector<CheckResolver> resolvers;
};
struct PendingResolve {
LoadedMod* mod = nullptr;
bool fixedValue = false;
uint8_t itemNo = 0;
ItemCheckResolveFn fn = nullptr;
void* userData = nullptr;
};
std::unordered_map<LoadedMod*, ModItemChecks> s_modChecks;
std::unordered_set<std::string> s_warnedCollisions;
ItemCheckHandle s_nextCheckHandle = 1;
const char* current_stage_name() {
const char* stageName = dComIfGp_getStartStageName();
return stageName != nullptr ? stageName : "";
}
std::string chest_check_name(uint8_t boxNo) {
return fmt::format("chest:{}:{}", current_stage_name(), boxNo);
}
std::string boss_check_name() {
return fmt::format("boss:{}", current_stage_name());
}
std::string freestanding_check_name(uint8_t bitNo) {
return fmt::format("freestanding:{}:{}", current_stage_name(), bitNo);
}
std::string poe_check_name(uint8_t bitNo) {
return fmt::format("poe:{}:{}", current_stage_name(), bitNo);
}
std::string shop_check_name(uint8_t itemNo) {
return fmt::format("shop:{}:{}", current_stage_name(), itemNo);
}
std::string bug_check_name(uint8_t insectId) {
return fmt::format("bug:{}", insectId);
}
std::string sky_character_check_name() {
return fmt::format("skychar:{}:{}", current_stage_name(), dStage_roomControl_c::getStayNo());
}
} // namespace
uint8_t item_check(const char* name, uint8_t itemNo, fopAc_ac_c* giver) {
if (name == nullptr || *name == '\0' || s_modChecks.empty()) {
return itemNo;
}
// Callbacks may change registrations, so copy the applicable chain before invoking one.
std::vector<PendingResolve> resolves;
LoadedMod* previousOverrideOwner = nullptr;
for (auto& mod : ModLoader::instance().mods()) {
if (!mod.active) {
continue;
}
const auto modIt = s_modChecks.find(&mod);
if (modIt == s_modChecks.end()) {
continue;
}
for (const auto& checkOverride : modIt->second.overrides) {
if (checkOverride.name != name) {
continue;
}
if (previousOverrideOwner != nullptr && s_warnedCollisions.emplace(name).second) {
Log.warn("check '{}' is overridden by [{}] and [{}]; [{}] wins by load order", name,
previousOverrideOwner->metadata.id, mod.metadata.id, mod.metadata.id);
}
previousOverrideOwner = &mod;
resolves.push_back({.mod = &mod, .fixedValue = true, .itemNo = checkOverride.itemNo});
}
for (const auto& resolver : modIt->second.resolvers) {
if (resolver.name.empty() || resolver.name == name) {
resolves.push_back({.mod = &mod, .fn = resolver.fn, .userData = resolver.userData});
}
}
}
ItemCheckInfo info{
.name = name,
.giver_actor = giver,
.vanilla_item = itemNo,
.current_item = itemNo,
};
for (const auto& resolve : resolves) {
if (!resolve.mod->active) {
continue;
}
if (resolve.fixedValue) {
info.current_item = resolve.itemNo;
continue;
}
uint8_t resolvedItem = info.current_item;
try {
if (resolve.fn(resolve.mod->context.get(), &info, &resolvedItem, resolve.userData)) {
info.current_item = resolvedItem;
}
} catch (const std::exception& e) {
fail_mod(*resolve.mod, MOD_ERROR,
fmt::format("Exception in item check resolver for '{}': {}", name, e.what()));
} catch (...) {
fail_mod(*resolve.mod, MOD_ERROR,
fmt::format("Unknown exception in item check resolver for '{}'", name));
}
}
return info.current_item;
}
uint8_t item_check_chest(uint8_t boxNo, uint8_t itemNo, fopAc_ac_c* chest) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = chest_check_name(boxNo);
return item_check(name.c_str(), itemNo, chest);
}
uint8_t item_check_boss(uint8_t itemNo, fopAc_ac_c* boss) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = boss_check_name();
return item_check(name.c_str(), itemNo, boss);
}
uint8_t item_check_freestanding(uint8_t bitNo, uint8_t itemNo, fopAc_ac_c* item) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = freestanding_check_name(bitNo);
return item_check(name.c_str(), itemNo, item);
}
uint8_t item_check_poe(uint8_t bitNo, uint8_t itemNo, fopAc_ac_c* poe) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = poe_check_name(bitNo);
return item_check(name.c_str(), itemNo, poe);
}
uint8_t item_check_shop(uint8_t itemNo, fopAc_ac_c* giver) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = shop_check_name(itemNo);
return item_check(name.c_str(), itemNo, giver);
}
uint8_t item_check_bug(uint8_t insectId, uint8_t itemNo, fopAc_ac_c* agitha) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = bug_check_name(insectId);
return item_check(name.c_str(), itemNo, agitha);
}
uint8_t item_check_sky_character(uint8_t itemNo, fopAc_ac_c* statue) {
if (s_modChecks.empty()) {
return itemNo;
}
const auto name = sky_character_check_name();
return item_check(name.c_str(), itemNo, statue);
}
uint32_t item_give_tag_chest(uint8_t boxNo) {
return item_give_tag(chest_check_name(boxNo).c_str());
}
uint32_t item_give_tag_boss() {
return item_give_tag(boss_check_name().c_str());
}
uint32_t item_give_tag_freestanding(uint8_t bitNo) {
return item_give_tag(freestanding_check_name(bitNo).c_str());
}
uint32_t item_give_tag_poe(uint8_t bitNo) {
return item_give_tag(poe_check_name(bitNo).c_str());
}
uint32_t item_give_tag_shop(uint8_t itemNo) {
return item_give_tag(shop_check_name(itemNo).c_str());
}
uint32_t item_give_tag_bug(uint8_t insectId) {
return item_give_tag(bug_check_name(insectId).c_str());
}
uint32_t item_give_tag_sky_character() {
return item_give_tag(sky_character_check_name().c_str());
}
void item_check_enqueue_poe(uint8_t bitNo, uint8_t itemNo) {
item_check_enqueue(poe_check_name(bitNo).c_str(), itemNo);
}
namespace svc {
ModResult item_check_set_override(LoadedMod& mod, const char* name, uint8_t itemNo) {
auto& checks = s_modChecks[&mod];
for (auto& checkOverride : checks.overrides) {
if (checkOverride.name == name) {
checkOverride.itemNo = itemNo;
return MOD_OK;
}
}
checks.overrides.push_back({.name = name, .itemNo = itemNo});
return MOD_OK;
}
ModResult item_check_clear_override(LoadedMod& mod, const char* name) {
const auto modIt = s_modChecks.find(&mod);
if (modIt == s_modChecks.end()) {
return MOD_INVALID_ARGUMENT;
}
const auto removed = std::erase_if(modIt->second.overrides,
[&](const auto& checkOverride) { return checkOverride.name == name; });
return removed != 0 ? MOD_OK : MOD_INVALID_ARGUMENT;
}
ModResult item_check_add_resolver(LoadedMod& mod, const char* name, ItemCheckResolveFn fn,
void* userData, ItemCheckHandle& outHandle) {
auto& resolver = s_modChecks[&mod].resolvers.emplace_back();
resolver.handle = s_nextCheckHandle++;
resolver.name = name != nullptr ? name : "";
resolver.fn = fn;
resolver.userData = userData;
outHandle = resolver.handle;
return MOD_OK;
}
ModResult item_check_remove_resolver(LoadedMod& mod, ItemCheckHandle handle) {
const auto modIt = s_modChecks.find(&mod);
if (modIt == s_modChecks.end()) {
return MOD_INVALID_ARGUMENT;
}
const auto removed = std::erase_if(
modIt->second.resolvers, [&](const auto& resolver) { return resolver.handle == handle; });
return removed != 0 ? MOD_OK : MOD_INVALID_ARGUMENT;
}
void item_checks_remove_mod(LoadedMod& mod) {
s_modChecks.erase(&mod);
s_warnedCollisions.clear();
}
} // namespace svc
} // namespace dusk::mods
+343
View File
@@ -0,0 +1,343 @@
#include "item.hpp"
#include "dusk/mod_loader.hpp"
#include "dusk/mods/loader/loader.hpp"
#include "dusk/mods/svc/item.hpp"
#include "aurora/lib/logging.hpp"
#include "d/actor/d_a_alink.h"
#include "d/d_com_inf_game.h"
#include "d/d_item.h"
#include "d/d_item_data.h"
#include "f_op/f_op_actor_mng.h"
#include <fmt/format.h>
#include <deque>
#include <exception>
#include <string>
#include <unordered_map>
#include <vector>
namespace dusk::mods {
namespace {
aurora::Module Log{"dusk::mods::item_gives"};
// deque keeps previously returned c_str pointers valid if a callback interns another name.
std::deque<std::string> s_giveNames;
std::unordered_map<std::string, uint32_t> s_giveNameIds;
const char* item_give_name(uint32_t tag) {
if (tag == 0 || tag > s_giveNames.size()) {
return nullptr;
}
return s_giveNames[tag - 1].c_str();
}
struct GiveObserver {
ItemGiveHandle handle = 0;
ItemGiveObserveFn fn = nullptr;
void* userData = nullptr;
};
struct PendingObserver {
LoadedMod* mod = nullptr;
ItemGiveObserveFn fn = nullptr;
void* userData = nullptr;
};
std::unordered_map<LoadedMod*, std::vector<GiveObserver>> s_modObservers;
ItemGiveHandle s_nextGiveHandle = 1;
size_t s_observerCount = 0;
void notify_gives(const char* checkName, uint8_t itemNo, fopAc_ac_c* giver, ItemGiveOrigin origin) {
if (s_observerCount == 0) {
return;
}
// Callbacks may change registrations, so copy them before invoking one.
std::vector<PendingObserver> observers;
for (auto& mod : ModLoader::instance().mods()) {
if (!mod.active) {
continue;
}
const auto modIt = s_modObservers.find(&mod);
if (modIt == s_modObservers.end()) {
continue;
}
for (const auto& observer : modIt->second) {
observers.push_back({.mod = &mod, .fn = observer.fn, .userData = observer.userData});
}
}
const ItemGiveInfo info{
.check_name = checkName,
.giver_actor = giver,
.item = itemNo,
.origin = static_cast<uint8_t>(origin),
};
for (const auto& observer : observers) {
if (!observer.mod->active) {
continue;
}
try {
observer.fn(observer.mod->context.get(), &info, observer.userData);
} catch (const std::exception& e) {
fail_mod(*observer.mod, MOD_ERROR,
fmt::format("Exception in item give observer: {}", e.what()));
} catch (...) {
fail_mod(*observer.mod, MOD_ERROR, "Unknown exception in item give observer");
}
}
}
constexpr size_t kGiveQueueLimit = 64;
constexpr int kGiveMaxRetries = 5;
struct QueuedGive {
LoadedMod* owner = nullptr;
uint32_t tag = 0;
uint8_t itemNo = 0;
bool silent = false;
bool resolveAtDispatch = false;
};
std::deque<QueuedGive> s_giveQueue;
QueuedGive s_inFlightGive{};
uint8_t s_inFlightItem = 0;
int s_inFlightRetries = 0;
bool s_inFlight = false;
bool s_inFlightSpawned = false;
bool s_dispatchingSilent = false;
bool safe_to_dispatch() {
daAlink_c* link = daAlink_getAlinkActorClass();
if (link == nullptr) {
return false;
}
// make sure player is in a safe action and not already in an event before dispatching
switch (link->mProcID) {
case daAlink_c::PROC_WAIT:
case daAlink_c::PROC_TIRED_WAIT:
case daAlink_c::PROC_MOVE:
case daAlink_c::PROC_WOLF_WAIT:
case daAlink_c::PROC_WOLF_TIRED_WAIT:
case daAlink_c::PROC_WOLF_MOVE:
case daAlink_c::PROC_ATN_MOVE:
case daAlink_c::PROC_WOLF_ATN_AC_MOVE:
break;
default:
return false;
}
if (link->checkEventRun()) {
return false;
}
int itemId = 0;
return link->mMsgFlow.getEventId(&itemId) == 0;
}
bool resolve_queued_give(const QueuedGive& give, ItemGiveOrigin origin, uint8_t& outItem) {
outItem = give.itemNo;
if (give.resolveAtDispatch) {
outItem = item_check(item_give_name(give.tag), give.itemNo, nullptr);
}
if (outItem != dItemNo_NONE_e) {
return true;
}
notify_gives(item_give_name(give.tag), dItemNo_NONE_e, nullptr, origin);
return false;
}
void dispatch_silent_give(const QueuedGive& give) {
uint8_t itemNo = 0;
if (!resolve_queued_give(give, ITEM_GIVE_ORIGIN_QUEUE_SILENT, itemNo)) {
return;
}
Log.debug("dispatching silent item {:#x} for '{}'", itemNo,
item_give_name(give.tag) != nullptr ? item_give_name(give.tag) : "");
s_dispatchingSilent = true;
execItemGet(itemNo, give.tag, nullptr);
s_dispatchingSilent = false;
}
void dispatch_demo_give() {
Log.debug("dispatching item {:#x} for '{}'", s_inFlightItem,
item_give_name(s_inFlightGive.tag) != nullptr ? item_give_name(s_inFlightGive.tag) : "");
daAlink_c* link = daAlink_getAlinkActorClass();
dComIfGp_getEvent()->setGtItm(s_inFlightItem);
link->procCoGetItemInit();
const s16 eventIndex = dComIfGp_getEventManager().getEventIdx(link, "DEFAULT_GETITEM", 0xFF);
fopAcM_orderChangeEventId(link, eventIndex, 1, 0xFFFF);
}
} // namespace
uint32_t item_give_tag(const char* name) {
if (name == nullptr || *name == '\0') {
return 0;
}
if (const auto it = s_giveNameIds.find(name); it != s_giveNameIds.end()) {
return it->second;
}
s_giveNames.emplace_back(name);
const auto tag = static_cast<uint32_t>(s_giveNames.size());
s_giveNameIds.emplace(s_giveNames.back(), tag);
return tag;
}
uint8_t item_check_tagged(uint32_t giveTag, uint8_t itemNo, fopAc_ac_c* giver) {
const char* name = item_give_name(giveTag);
return name != nullptr ? item_check(name, itemNo, giver) : itemNo;
}
void item_check_enqueue(const char* name, uint8_t itemNo) {
if (s_giveQueue.size() >= kGiveQueueLimit) {
Log.warn("item give queue is full; dropping check '{}'", name != nullptr ? name : "");
return;
}
s_giveQueue.push_back({
.tag = item_give_tag(name),
.itemNo = itemNo,
.resolveAtDispatch = true,
});
}
void item_granted(uint8_t itemNo, uint32_t giveTag, fopAc_ac_c* giver) {
ItemGiveOrigin origin = ITEM_GIVE_ORIGIN_GAME;
if (s_dispatchingSilent) {
origin = ITEM_GIVE_ORIGIN_QUEUE_SILENT;
} else if (s_inFlight && itemNo == s_inFlightItem && giveTag == s_inFlightGive.tag) {
origin = ITEM_GIVE_ORIGIN_QUEUE;
s_inFlight = false;
s_inFlightSpawned = false;
}
notify_gives(item_give_name(giveTag), itemNo, giver, origin);
}
bool item_give_queue_dispatching() {
return s_inFlight && !s_inFlightSpawned;
}
uint32_t item_give_queue_take_tag() {
if (!item_give_queue_dispatching()) {
return 0;
}
s_inFlightSpawned = true;
return s_inFlightGive.tag;
}
namespace svc {
void item_gives_tick() {
if ((!s_inFlight && s_giveQueue.empty()) || !safe_to_dispatch()) {
return;
}
if (s_inFlight) {
if (++s_inFlightRetries > kGiveMaxRetries) {
Log.error("item {:#x} for '{}' did not complete after {} attempts; dropping it",
s_inFlightItem,
item_give_name(s_inFlightGive.tag) != nullptr ? item_give_name(s_inFlightGive.tag) :
"",
kGiveMaxRetries);
s_inFlight = false;
s_inFlightSpawned = false;
return;
}
s_inFlightSpawned = false;
dispatch_demo_give();
return;
}
while (!s_giveQueue.empty() && s_giveQueue.front().silent) {
const QueuedGive give = s_giveQueue.front();
s_giveQueue.pop_front();
dispatch_silent_give(give);
}
if (s_giveQueue.empty()) {
return;
}
const QueuedGive give = s_giveQueue.front();
uint8_t itemNo = 0;
if (!resolve_queued_give(give, ITEM_GIVE_ORIGIN_QUEUE, itemNo)) {
s_giveQueue.pop_front();
return;
}
s_giveQueue.pop_front();
s_inFlightGive = give;
s_inFlightItem = itemNo;
s_inFlightRetries = 0;
s_inFlight = true;
s_inFlightSpawned = false;
dispatch_demo_give();
}
void item_gives_clear() {
if (!s_giveQueue.empty() || s_inFlight) {
Log.info("dropping {} pending item give(s)",
s_giveQueue.size() + static_cast<size_t>(s_inFlight));
}
s_giveQueue.clear();
s_inFlight = false;
s_inFlightSpawned = false;
}
ModResult item_give_enqueue(LoadedMod& mod, const char* checkName, uint8_t itemNo, uint32_t flags) {
if (s_giveQueue.size() >= kGiveQueueLimit) {
return MOD_UNAVAILABLE;
}
s_giveQueue.push_back({
.owner = &mod,
.tag = item_give_tag(checkName),
.itemNo = itemNo,
.silent = (flags & ITEM_GIVE_SILENT) != 0,
.resolveAtDispatch = (flags & ITEM_GIVE_RESOLVE) != 0,
});
return MOD_OK;
}
ModResult item_give_add_observer(
LoadedMod& mod, ItemGiveObserveFn fn, void* userData, ItemGiveHandle& outHandle) {
auto& observer = s_modObservers[&mod].emplace_back();
observer.handle = s_nextGiveHandle++;
observer.fn = fn;
observer.userData = userData;
outHandle = observer.handle;
++s_observerCount;
return MOD_OK;
}
ModResult item_give_remove_observer(LoadedMod& mod, ItemGiveHandle handle) {
const auto modIt = s_modObservers.find(&mod);
if (modIt == s_modObservers.end()) {
return MOD_INVALID_ARGUMENT;
}
const auto removed = std::erase_if(
modIt->second, [&](const auto& observer) { return observer.handle == handle; });
s_observerCount -= removed;
return removed != 0 ? MOD_OK : MOD_INVALID_ARGUMENT;
}
void item_gives_remove_mod(LoadedMod& mod) {
if (const auto modIt = s_modObservers.find(&mod); modIt != s_modObservers.end()) {
s_observerCount -= modIt->second.size();
s_modObservers.erase(modIt);
}
std::erase_if(s_giveQueue, [&](const QueuedGive& give) { return give.owner == &mod; });
if (s_inFlight && s_inFlightGive.owner == &mod) {
// The event system already owns this grant, so it can no longer be canceled safely.
s_inFlightGive.owner = nullptr;
}
}
} // namespace svc
} // namespace dusk::mods
+1
View File
@@ -899,6 +899,7 @@ bool ModLoader::activate_mod(LoadedMod& mod) {
}
void ModLoader::deactivate_mod(LoadedMod& mod) {
svc::modules_mod_deactivating(mod);
if (mod.initialized && mod.native && mod.native->fn_shutdown) {
log::write(mod.metadata.id, LOG_LEVEL_TRACE, "calling mod_shutdown");
try {
+92 -26
View File
@@ -9,8 +9,10 @@
#include <aurora/gfx.hpp>
#include <aurora/webgpu.hpp>
#include <dolphin/gx/GXAurora.h>
#include <fmt/format.h>
#include <algorithm>
#include <atomic>
#include <cstddef>
#include <cstdint>
@@ -126,23 +128,34 @@ GfxSlot* resolve_owned_slot_locked(LoadedMod& mod, uint64_t handle, GfxSlotKind
return &entry->value;
}
void collect_mod_types_locked(LoadedMod& owner, std::vector<aurora::gfx::DrawTypeId>& drawIds,
void take_mod_types_locked(LoadedMod& owner, std::vector<aurora::gfx::DrawTypeId>& drawIds,
std::vector<aurora::gfx::EncoderTaskId>& taskIds) {
s_slots.for_each([&](uint64_t, const auto& entry) {
std::vector<uint64_t> drawHandles;
std::vector<uint64_t> taskHandles;
s_slots.for_each([&](uint64_t handle, const auto& entry) {
if (entry.owner != &owner) {
return;
}
const auto& slot = entry.value;
if (slot.kind == GfxSlotKind::DrawType && slot.auroraDrawId != aurora::gfx::InvalidDrawType)
{
drawIds.push_back(slot.auroraDrawId);
drawHandles.push_back(handle);
} else if ((slot.kind == GfxSlotKind::ComputeType ||
slot.kind == GfxSlotKind::PresentTarget) &&
slot.auroraTaskId != aurora::gfx::InvalidEncoderTask)
{
taskIds.push_back(slot.auroraTaskId);
taskHandles.push_back(handle);
}
});
for (const auto handle : drawHandles) {
auto* entry = s_slots.find(handle);
drawIds.push_back(std::exchange(entry->value.auroraDrawId, aurora::gfx::InvalidDrawType));
}
for (const auto handle : taskHandles) {
auto* entry = s_slots.find(handle);
taskIds.push_back(
std::exchange(entry->value.auroraTaskId, aurora::gfx::InvalidEncoderTask));
}
}
void unregister_aurora_types(const std::vector<aurora::gfx::DrawTypeId>& drawIds,
@@ -155,6 +168,49 @@ void unregister_aurora_types(const std::vector<aurora::gfx::DrawTypeId>& drawIds
}
}
void gfx_mod_deactivating(LoadedMod& mod) {
std::vector<aurora::gfx::DrawTypeId> drawIds;
std::vector<aurora::gfx::EncoderTaskId> taskIds;
{
std::lock_guard lock{s_mutex};
take_mod_types_locked(mod, drawIds, taskIds);
}
unregister_aurora_types(drawIds, taskIds);
if (!drawIds.empty() || !taskIds.empty()) {
aurora::gfx::synchronize();
}
}
GfxAttachmentSemantic gfx_attachment_semantic(aurora::gfx::ColorAttachmentSemantic semantic) {
switch (semantic) {
case aurora::gfx::ColorAttachmentSemantic::SceneColor:
return GFX_ATTACHMENT_SCENE_COLOR;
case aurora::gfx::ColorAttachmentSemantic::Normal:
return GFX_ATTACHMENT_NORMAL;
case aurora::gfx::ColorAttachmentSemantic::Auxiliary:
return GFX_ATTACHMENT_AUXILIARY;
}
return GFX_ATTACHMENT_AUXILIARY;
}
GfxRenderTargetLayout gfx_render_target_layout(const aurora::gfx::RenderTargetLayout& layout) {
GfxRenderTargetLayout result = GFX_RENDER_TARGET_LAYOUT_INIT;
result.key = layout.key;
result.color_attachment_count =
std::min<uint32_t>(layout.colorAttachmentCount, GFX_MAX_COLOR_ATTACHMENTS);
for (uint32_t i = 0; i < result.color_attachment_count; ++i) {
result.color_attachments[i] = {
.semantic = gfx_attachment_semantic(layout.colorAttachments[i].semantic),
.format = static_cast<WGPUTextureFormat>(layout.colorAttachments[i].format),
.width = layout.colorAttachments[i].width,
.height = layout.colorAttachments[i].height,
};
}
result.depth_stencil_format = static_cast<WGPUTextureFormat>(layout.depthStencilFormat);
result.sample_count = layout.sampleCount;
return result;
}
void draw_trampoline(const aurora::gfx::DrawContext& ctx, const wgpu::RenderPassEncoder& pass,
const void* payload, size_t payloadSize, void* userdata) {
const auto handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(userdata));
@@ -184,12 +240,12 @@ void draw_trampoline(const aurora::gfx::DrawContext& ctx, const wgpu::RenderPass
.index_buffer = ctx.indexBuffer.Get(),
.uniform_buffer = ctx.uniformBuffer.Get(),
.storage_buffer = ctx.storageBuffer.Get(),
.color_format = static_cast<WGPUTextureFormat>(ctx.colorFormat),
.depth_format = static_cast<WGPUTextureFormat>(ctx.depthFormat),
.sample_count = ctx.sampleCount,
.target_width = ctx.targetWidth,
.target_height = ctx.targetHeight,
.color_format = static_cast<WGPUTextureFormat>(
ctx.layout.colorAttachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].format),
.depth_format = static_cast<WGPUTextureFormat>(ctx.layout.depthStencilFormat),
.sample_count = ctx.layout.sampleCount,
.uses_reversed_z = aurora::gfx::uses_reversed_z(),
.layout = gfx_render_target_layout(ctx.layout),
};
std::string failure;
@@ -778,8 +834,10 @@ ModResult gfx_unregister_present_target(LoadedMod& mod, uint64_t handle) {
auroraId = slot->auroraTaskId;
}
aurora::gfx::unregister_encoder_task_type(auroraId);
aurora::gfx::synchronize();
if (auroraId != aurora::gfx::InvalidEncoderTask) {
aurora::gfx::unregister_encoder_task_type(auroraId);
aurora::gfx::synchronize();
}
std::optional<GfxSlotMap::Entry> removed;
{
@@ -903,6 +961,7 @@ void gfx_run_stage(
.game_viewport = gameViewport,
};
AuroraGXSync();
for (const auto& entry : entries) {
{
std::lock_guard lock{s_mutex};
@@ -924,6 +983,7 @@ void gfx_run_stage(
fail_mod(*entry.owner, MOD_ERROR, "unknown exception in gfx stage callback");
}
AuroraGXSync();
if (aurora::gfx::is_offscreen() != wasOffscreen) {
aurora::gfx::ResolvedTargets discarded;
aurora::gfx::resolve_pass(
@@ -935,17 +995,8 @@ void gfx_run_stage(
}
}
void gfx_remove_mod(LoadedMod& mod) {
std::vector<aurora::gfx::DrawTypeId> drawIds;
std::vector<aurora::gfx::EncoderTaskId> taskIds;
{
std::lock_guard lock{s_mutex};
collect_mod_types_locked(mod, drawIds, taskIds);
}
unregister_aurora_types(drawIds, taskIds);
if (!drawIds.empty() || !taskIds.empty()) {
aurora::gfx::synchronize();
}
void gfx_mod_detached(LoadedMod& mod) {
gfx_mod_deactivating(mod);
std::vector<GfxSlotMap::Entry> entries;
{
@@ -966,7 +1017,7 @@ void gfx_remove_mod(LoadedMod& mod) {
}
}
void gfx_drain_worker_failures() {
void gfx_frame_begin() {
std::vector<WorkerFailure> failures;
{
std::lock_guard lock{s_mutex};
@@ -979,7 +1030,7 @@ void gfx_drain_worker_failures() {
for (const auto& failure : failures) {
for (auto& mod : ModLoader::instance().mods()) {
if (mod.metadata.id == failure.modId && mod.active) {
gfx_remove_mod(mod);
gfx_mod_detached(mod);
fail_mod(mod, MOD_ERROR, failure.message);
break;
}
@@ -1030,6 +1081,19 @@ ModResult gfx_get_device_info(ModContext* context, GfxDeviceInfo* outInfo) {
return MOD_OK;
}
ModResult gfx_get_scene_target_layout(ModContext* context, GfxRenderTargetLayout* outLayout) {
if (outLayout == nullptr || outLayout->struct_size < sizeof(GfxRenderTargetLayout) ||
mod_from_context(context) == nullptr)
{
return MOD_INVALID_ARGUMENT;
}
const uint32_t structSize = outLayout->struct_size;
*outLayout = gfx_render_target_layout(aurora::gfx::scene_render_target_layout());
outLayout->struct_size = structSize;
return MOD_OK;
}
void* gfx_get_proc_address(ModContext* context, const char* name) {
if (mod_from_context(context) == nullptr || name == nullptr) {
return nullptr;
@@ -1327,6 +1391,7 @@ constexpr GfxService s_gfxService{
.resize_present_target = gfx_resize_present_target_impl,
.unregister_present_target = gfx_unregister_present_target_impl,
.push_present = gfx_push_present_impl,
.get_scene_target_layout = gfx_get_scene_target_layout,
};
} // namespace
@@ -1336,8 +1401,9 @@ constinit const ServiceModule g_gfxModule{
.majorVersion = GFX_SERVICE_MAJOR,
.minorVersion = GFX_SERVICE_MINOR,
.service = &s_gfxService,
.modDetached = gfx_remove_mod,
.frameBegin = gfx_drain_worker_failures,
.modDeactivating = gfx_mod_deactivating,
.modDetached = gfx_mod_detached,
.frameBegin = gfx_frame_begin,
};
} // namespace dusk::mods::svc
+151
View File
@@ -0,0 +1,151 @@
#include "item.hpp"
#include "registry.hpp"
#include "dusk/mods/item.hpp"
#include "dusk/mods/loader/loader.hpp"
#include "d/d_item_data.h"
#include <string_view>
namespace dusk::mods::svc {
namespace {
constexpr size_t kMaxCheckNameLength = 256;
constexpr uint32_t kGiveFlagMask = ITEM_GIVE_SILENT | ITEM_GIVE_RESOLVE;
bool is_valid_check_name(const char* name) {
if (name == nullptr) {
return false;
}
const std::string_view view{name};
return !view.empty() && view.size() <= kMaxCheckNameLength;
}
ModResult item_set_check_override(ModContext* context, const char* name, uint8_t itemNo) {
auto* mod = mod_from_context(context);
if (mod == nullptr || !is_valid_check_name(name)) {
return MOD_INVALID_ARGUMENT;
}
return item_check_set_override(*mod, name, itemNo);
}
ModResult item_clear_check_override(ModContext* context, const char* name) {
auto* mod = mod_from_context(context);
if (mod == nullptr || !is_valid_check_name(name)) {
return MOD_INVALID_ARGUMENT;
}
return item_check_clear_override(*mod, name);
}
ModResult item_set_check_resolver(ModContext* context, const char* name, ItemCheckResolveFn fn,
void* userData, ItemCheckHandle* outHandle) {
if (outHandle != nullptr) {
*outHandle = 0;
}
auto* mod = mod_from_context(context);
if (mod == nullptr || fn == nullptr || (name != nullptr && !is_valid_check_name(name))) {
return MOD_INVALID_ARGUMENT;
}
ItemCheckHandle handle = 0;
const auto result = item_check_add_resolver(*mod, name, fn, userData, handle);
if (outHandle != nullptr) {
*outHandle = handle;
}
return result;
}
ModResult item_clear_check_resolver(ModContext* context, ItemCheckHandle handle) {
auto* mod = mod_from_context(context);
if (mod == nullptr || handle == 0) {
return MOD_INVALID_ARGUMENT;
}
return item_check_remove_resolver(*mod, handle);
}
ModResult item_resolve_check(
ModContext* context, const char* name, uint8_t originalItemNo, uint8_t* outItem) {
if (mod_from_context(context) == nullptr || !is_valid_check_name(name) || outItem == nullptr) {
return MOD_INVALID_ARGUMENT;
}
*outItem = item_check(name, originalItemNo, nullptr);
return MOD_OK;
}
ModResult item_give_item(
ModContext* context, const char* checkName, uint8_t itemNo, uint32_t flags) {
auto* mod = mod_from_context(context);
if (mod == nullptr || (checkName != nullptr && !is_valid_check_name(checkName)) ||
(flags & ~kGiveFlagMask) != 0)
{
return MOD_INVALID_ARGUMENT;
}
if ((flags & ITEM_GIVE_RESOLVE) != 0) {
if (checkName == nullptr) {
return MOD_INVALID_ARGUMENT;
}
} else if (itemNo == dItemNo_NONE_e) {
return MOD_INVALID_ARGUMENT;
}
return item_give_enqueue(*mod, checkName, itemNo, flags);
}
ModResult item_observe_gives(
ModContext* context, ItemGiveObserveFn fn, void* userData, ItemGiveHandle* outHandle) {
if (outHandle != nullptr) {
*outHandle = 0;
}
auto* mod = mod_from_context(context);
if (mod == nullptr || fn == nullptr) {
return MOD_INVALID_ARGUMENT;
}
ItemGiveHandle handle = 0;
const auto result = item_give_add_observer(*mod, fn, userData, handle);
if (outHandle != nullptr) {
*outHandle = handle;
}
return result;
}
ModResult item_unobserve_gives(ModContext* context, ItemGiveHandle handle) {
auto* mod = mod_from_context(context);
if (mod == nullptr || handle == 0) {
return MOD_INVALID_ARGUMENT;
}
return item_give_remove_observer(*mod, handle);
}
constexpr ItemService s_itemService{
.header = SERVICE_HEADER(ItemService, ITEM_SERVICE_MAJOR, ITEM_SERVICE_MINOR),
.set_check_override = item_set_check_override,
.clear_check_override = item_clear_check_override,
.set_check_resolver = item_set_check_resolver,
.clear_check_resolver = item_clear_check_resolver,
.resolve_check = item_resolve_check,
.give_item = item_give_item,
.observe_gives = item_observe_gives,
.unobserve_gives = item_unobserve_gives,
};
} // namespace
constinit const ServiceModule g_itemModule{
.id = ITEM_SERVICE_ID,
.majorVersion = ITEM_SERVICE_MAJOR,
.minorVersion = ITEM_SERVICE_MINOR,
.service = &s_itemService,
.modDetached =
[](LoadedMod& mod) {
item_checks_remove_mod(mod);
item_gives_remove_mod(mod);
},
.frameEnd = item_gives_tick,
.shutdown = item_gives_clear,
};
} // namespace dusk::mods::svc
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include "mods/svc/item.h"
#include <cstdint>
namespace dusk::mods {
struct LoadedMod;
namespace svc {
ModResult item_check_set_override(LoadedMod& mod, const char* name, uint8_t itemNo);
ModResult item_check_clear_override(LoadedMod& mod, const char* name);
ModResult item_check_add_resolver(LoadedMod& mod, const char* name, ItemCheckResolveFn fn,
void* userData, ItemCheckHandle& outHandle);
ModResult item_check_remove_resolver(LoadedMod& mod, ItemCheckHandle handle);
void item_checks_remove_mod(LoadedMod& mod);
ModResult item_give_enqueue(LoadedMod& mod, const char* checkName, uint8_t itemNo, uint32_t flags);
ModResult item_give_add_observer(
LoadedMod& mod, ItemGiveObserveFn fn, void* userData, ItemGiveHandle& outHandle);
ModResult item_give_remove_observer(LoadedMod& mod, ItemGiveHandle handle);
void item_gives_remove_mod(LoadedMod& mod);
void item_gives_tick();
void item_gives_clear();
} // namespace svc
} // namespace dusk::mods
+9
View File
@@ -150,6 +150,14 @@ ModResult register_module(const ServiceModule& module) {
return MOD_OK;
}
void modules_mod_deactivating(LoadedMod& mod) {
for (const auto* module : s_modules | std::views::reverse) {
if (module->modDeactivating != nullptr) {
module->modDeactivating(mod);
}
}
}
void modules_mod_detached(LoadedMod& mod) {
for (const auto* module : s_modules | std::views::reverse) {
if (module->modDetached != nullptr) {
@@ -213,6 +221,7 @@ void ModLoader::init_services() {
&svc::g_gfxModule,
&svc::g_saveModule,
&svc::g_stageModule,
&svc::g_itemModule,
&svc::g_gamemodeModule,
})
{
+6 -1
View File
@@ -19,7 +19,7 @@ struct ServiceRecord {
};
// A host service and its lifecycle hooks. Every hook is optional. Frame and lifecycle hooks run in
// registration order, modDetached in reverse registration order.
// registration order, teardown hooks in reverse registration order.
struct ServiceModule {
const char* id = nullptr;
uint16_t majorVersion = 0;
@@ -28,6 +28,9 @@ struct ServiceModule {
// One-time setup, at registration (ModLoader::init_services).
void (*initialize)() = nullptr;
// A mod is beginning deactivation: stop callbacks that may execute concurrently. Service state
// remains registered so mod_shutdown may release it normally.
void (*modDeactivating)(LoadedMod& mod) = nullptr;
// A mod is going away (deactivation or failed activation): drop all state held for it.
// Runs after the mod's mod_shutdown and before its library unloads, so pointers into
// the mod are still valid but must not be called.
@@ -55,6 +58,7 @@ const ServiceRecord* find_service(
const ServiceRecord* find_service_record(const char* serviceId, uint16_t majorVersion);
ModResult register_module(const ServiceModule& module);
void modules_mod_deactivating(LoadedMod& mod);
void modules_mod_detached(LoadedMod& mod);
void modules_lifecycle_applied();
void modules_frame_begin();
@@ -75,6 +79,7 @@ extern const ServiceModule g_windowModule;
extern const ServiceModule g_gfxModule;
extern const ServiceModule g_saveModule;
extern const ServiceModule g_stageModule;
extern const ServiceModule g_itemModule;
extern const ServiceModule g_gamemodeModule;
} // namespace dusk::mods::svc
+4
View File
@@ -1,5 +1,6 @@
#include "save.hpp"
#include "item.hpp"
#include "registry.hpp"
#include "aurora/lib/logging.hpp"
@@ -164,6 +165,7 @@ void save_slot_new(uint32_t slot) {
store.mods.clear();
store.snapshotValid = false;
s_currentSlot = static_cast<int32_t>(slot);
item_gives_clear();
Log.info("new save in slot {}; mod blob store cleared", slot);
notify(slot, &SaveObserverRecord::onNewSave, "new-save");
}
@@ -183,6 +185,7 @@ void save_slot_loaded(uint32_t slot, const void* slotData) {
}
}
s_currentSlot = static_cast<int32_t>(slot);
item_gives_clear();
notify(slot, &SaveObserverRecord::onLoaded, "save-loaded");
}
@@ -222,6 +225,7 @@ void save_slot_erased(uint32_t slot) {
void save_no_slot() {
s_currentSlot = -1;
item_gives_clear();
}
namespace {
+4
View File
@@ -10,6 +10,10 @@ namespace dusk::presentation {
namespace {
float preferred_frame_rate() {
if (getTransientSettings().turboMode) {
return 0.0f;
}
switch (getSettings().game.enableFrameInterpolation.getValue()) {
case FrameInterpMode::Off:
return 30.0f;
+5 -1
View File
@@ -51,6 +51,7 @@ UserSettings g_userSettings = {
.sunsSong {"game.sunsSong", false},
.autoSave {"game.autoSave", false},
.enhancedMapMenus {"game.enhancedMapMenus", false},
.aimingReticle {"game.aimingReticle", false},
// Preferences
.enableMirrorMode {"game.enableMirrorMode", false},
@@ -75,6 +76,7 @@ UserSettings g_userSettings = {
.resampler {"game.resampler", Resampler::Bilinear},
.enableMapBackground {"game.enableMapBackground", true},
.disableCutscenePillarboxing {"game.disableCutscenePillarboxing", false},
.enableHighQualityMinimapTextures {"game.enableHighQualityMinimapTextures", true},
// Audio
.noLowHpSound {"game.noLowHpSound", false},
@@ -256,6 +258,7 @@ void registerSettings() {
Register(g_userSettings.game.sunsSong);
Register(g_userSettings.game.autoSave);
Register(g_userSettings.game.enhancedMapMenus);
Register(g_userSettings.game.aimingReticle);
Register(g_userSettings.game.enableMirrorMode);
Register(g_userSettings.game.invertCameraXAxis);
Register(g_userSettings.game.invertCameraYAxis);
@@ -282,6 +285,7 @@ void registerSettings() {
Register(g_userSettings.game.shadowResolutionMultiplier);
Register(g_userSettings.game.enableMapBackground);
Register(g_userSettings.game.disableCutscenePillarboxing);
Register(g_userSettings.game.enableHighQualityMinimapTextures);
Register(g_userSettings.game.enableFastIronBoots);
Register(g_userSettings.game.canTransformAnywhere);
Register(g_userSettings.game.fastRoll);
@@ -394,7 +398,7 @@ static TransientSettings g_transientSettings = {
.colliderViewOpacity = 50.0f,
.drawRange = 100.0f,
},
.skipFrameRateLimit = false,
.turboMode = false,
};
TransientSettings& getTransientSettings() {
+5 -2
View File
@@ -33,6 +33,7 @@ enum class GameLanguage : u8 {
French = OS_LANGUAGE_FRENCH,
Spanish = OS_LANGUAGE_SPANISH,
Italian = OS_LANGUAGE_ITALIAN,
Japanese = 6,
};
enum class DiscVerificationState : u8 {
@@ -89,7 +90,7 @@ struct ConfigEnumRange<Resampler> {
template <>
struct ConfigEnumRange<GameLanguage> {
static constexpr auto min = GameLanguage::English;
static constexpr auto max = GameLanguage::Italian;
static constexpr auto max = GameLanguage::Japanese;
};
template <>
@@ -183,6 +184,7 @@ struct UserSettings {
ConfigVar<bool> sunsSong;
ConfigVar<bool> autoSave;
ConfigVar<bool> enhancedMapMenus;
ConfigVar<bool> aimingReticle;
// Preferences
ConfigVar<bool> enableMirrorMode;
@@ -207,6 +209,7 @@ struct UserSettings {
ConfigVar<Resampler> resampler;
ConfigVar<bool> enableMapBackground;
ConfigVar<bool> disableCutscenePillarboxing;
ConfigVar<bool> enableHighQualityMinimapTextures;
// Audio
ConfigVar<bool> noLowHpSound;
@@ -327,7 +330,7 @@ struct CollisionViewSettings {
struct TransientSettings {
CollisionViewSettings collisionView;
bool skipFrameRateLimit;
bool turboMode;
bool moveLinkActive;
bool stateShareLoadActive;
};
+12 -6
View File
@@ -9,18 +9,23 @@ namespace dusk::speedrun {
struct SpeedrunInfo {
void startRun() {
m_isRunStarted = true;
m_startTimestamp = OSGetTime();
m_rtaStartTimestamp = OSGetNativeTime();
m_igtStartTimestamp = OSGetTime();
}
void stopRun() {
m_isRunStarted = false;
m_endTimestamp = OSGetTime() - m_startTimestamp;
m_rtaTimer = OSGetNativeTime() - m_rtaStartTimestamp;
if (!m_isPauseIGT) {
m_igtTimer = OSGetTime() - m_igtStartTimestamp - m_totalLoadTime;
}
}
void reset() {
m_isRunStarted = false;
m_startTimestamp = 0;
m_endTimestamp = 0;
m_rtaStartTimestamp = 0;
m_rtaTimer = 0;
m_igtStartTimestamp = 0;
m_isPauseIGT = false;
m_loadStartTimestamp = 0;
m_totalLoadTime = 0;
@@ -28,8 +33,9 @@ struct SpeedrunInfo {
}
bool m_isRunStarted = false;
OSTime m_startTimestamp = 0;
OSTime m_endTimestamp = 0;
OSTime m_rtaStartTimestamp = 0;
OSTime m_rtaTimer = 0;
OSTime m_igtStartTimestamp = 0;
bool m_isPauseIGT = false;
OSTime m_loadStartTimestamp = 0;
+25 -16
View File
@@ -203,10 +203,19 @@ void remove_element(Rml::Element*& elem) noexcept {
} // namespace
static std::string FormatTime(OSTime ticks) {
OSCalendarTime t;
OSTicksToCalendarTime(ticks, &t);
return fmt::format("{0:02}:{1:02}:{2:02}.{3:03}", t.hour, t.min, t.sec, t.msec);
static std::string FormatElapsedTime(OSTime ticksElapsed) {
using namespace std::chrono;
milliseconds ms{OSTicksToMilliseconds(ticksElapsed)};
const hours hr = duration_cast<hours>(ms);
ms -= hr;
const minutes min = duration_cast<minutes>(ms);
ms -= min;
const seconds sec = duration_cast<seconds>(ms);
ms -= sec;
return fmt::format("{0:02}:{1:02}:{2:02}.{3:03}", hr.count(), min.count(), sec.count(), ms.count());
}
Overlay::Overlay() : Document(kDocumentSource, true, DocumentScope::Overlay) {
@@ -316,34 +325,34 @@ void Overlay::update() {
if (mDoCPd_c::getHoldL(PAD_1) && mDoCPd_c::getHoldR(PAD_1) &&
mDoCPd_c::getHoldA(PAD_1) && mDoCPd_c::getTrigY(PAD_1))
{
if (dusk::speedrun::g_speedrunInfo.m_isRunStarted) {
dusk::speedrun::g_speedrunInfo.m_endTimestamp = OSGetTime() - dusk::speedrun::g_speedrunInfo.m_startTimestamp;
dusk::speedrun::g_speedrunInfo.m_isRunStarted = false;
if (speedrun::g_speedrunInfo.m_isRunStarted) {
speedrun::g_speedrunInfo.stopRun();
}
}
OSTime elapsedTime = 0;
if (dusk::speedrun::g_speedrunInfo.m_isRunStarted) {
elapsedTime = OSGetTime() - dusk::speedrun::g_speedrunInfo.m_startTimestamp;
} else if (dusk::speedrun::g_speedrunInfo.m_endTimestamp != 0) {
elapsedTime = dusk::speedrun::g_speedrunInfo.m_endTimestamp;
OSTime rtaElapsedTime = 0;
if (speedrun::g_speedrunInfo.m_isRunStarted) {
rtaElapsedTime = OSGetNativeTime() - speedrun::g_speedrunInfo.m_rtaStartTimestamp;
} else if (speedrun::g_speedrunInfo.m_rtaTimer != 0) {
rtaElapsedTime = speedrun::g_speedrunInfo.m_rtaTimer;
}
if (!dusk::speedrun::g_speedrunInfo.m_isPauseIGT) {
dusk::speedrun::g_speedrunInfo.m_igtTimer = elapsedTime - dusk::speedrun::g_speedrunInfo.m_totalLoadTime;
if (speedrun::g_speedrunInfo.m_isRunStarted && !speedrun::g_speedrunInfo.m_isRunStarted) {
speedrun::g_speedrunInfo.m_igtTimer = OSGetTime() - speedrun::g_speedrunInfo.m_igtStartTimestamp -
speedrun::g_speedrunInfo.m_totalLoadTime;
}
mSpeedrunTimer->SetAttribute("open", "");
if (getSettings().game.showSpeedrunRTATimer) {
mSpeedrunRta->SetAttribute("open", "");
mSpeedrunRta->SetInnerRML(escape(fmt::format("RTA {}", FormatTime(elapsedTime))));
mSpeedrunRta->SetInnerRML(escape(fmt::format("RTA {}", FormatElapsedTime(rtaElapsedTime))));
} else {
mSpeedrunRta->RemoveAttribute("open");
}
mSpeedrunIgt->SetInnerRML(
escape(fmt::format("IGT {}", FormatTime(dusk::speedrun::g_speedrunInfo.m_igtTimer))));
escape(fmt::format("IGT {}", FormatElapsedTime(speedrun::g_speedrunInfo.m_igtTimer))));
} else {
mSpeedrunTimer->RemoveAttribute("open");
}
+56 -1
View File
@@ -5,6 +5,7 @@
#include "dusk/data.hpp"
#include "dusk/gamemode.hpp"
#include "dusk/iso_validate.hpp"
#include "dusk/language.hpp"
#include "dusk/main.h"
#include "dusk/settings.h"
#include "dusk/ui/menu_bar.hpp"
@@ -293,7 +294,7 @@ std::string get_error_msg(iso::ValidationError error) {
case iso::ValidationError::WrongGame:
return "The selected game is not supported by Dusklight.";
case iso::ValidationError::WrongVersion:
return "Dusklight currently supports GameCube USA and PAL disc images only.";
return "Dusklight does not currently support the Wii's Korean version.";
case iso::ValidationError::Canceled:
return "Disc verification was canceled. Dusklight cannot guarantee the selected disc "
"image is compatible.";
@@ -319,6 +320,24 @@ void persist_disc_choice(const std::string& path, iso::ValidationError validatio
}
}
void apply_language_for_disc(const iso::DiscInfo& info) {
const auto langs = language::available_languages(info);
auto& language = getSettings().game.language;
const GameLanguage previous = language.getValue();
if (std::ranges::find(langs, previous) != langs.end()) {
return;
}
const GameLanguage fallback = langs.front();
language.setValue(fallback);
config::save();
auto& state = prelaunch_state();
state.initialLanguage = fallback;
state.unavailableLanguage = previous;
state.pendingLanguageUnavailableNotice = true;
}
void apply_valid_disc_result(
const std::string& path, const iso::DiscInfo& info, iso::ValidationError validation) {
auto& state = prelaunch_state();
@@ -331,6 +350,7 @@ void apply_valid_disc_result(
state.activeDiscInfo = info;
}
persist_disc_choice(path, validation);
apply_language_for_disc(info);
}
void apply_disc_verification_result(const DiscVerificationResult& result) {
@@ -550,6 +570,7 @@ void refresh_configured_disc_state() noexcept {
if (state.configuredDiscPath == state.activeDiscPath) {
state.activeDiscInfo = info;
}
apply_language_for_disc(info);
return;
}
@@ -634,6 +655,36 @@ void try_push_verification_modal(Document& host) {
}));
}
void try_push_language_unavailable_modal(Document& host) {
auto& state = prelaunch_state();
if (!state.pendingLanguageUnavailableNotice) {
return;
}
state.pendingLanguageUnavailableNotice = false;
const Rml::String bodyRml = fmt::format(
"<b>{}</b> is not available on this disc. Language has been reset to <b>{}</b>.",
language::language_name(state.unavailableLanguage),
language::language_name(getSettings().game.language.getValue()));
auto dismiss = [](Modal& modal) { modal.pop(); };
host.push(std::make_unique<Modal>(Modal::Props{
.title = "Language unavailable",
.bodyRml = bodyRml,
.actions =
{
ModalAction{
.label = "OK",
.onPressed = dismiss,
},
},
.onDismiss = dismiss,
.icon = "warning",
}));
}
void ensure_initialized() noexcept {
auto& state = prelaunch_state();
if (state.initialized) {
@@ -946,6 +997,7 @@ void Prelaunch::update() {
if (top_document() == this) {
try_push_verification_modal(*this);
try_push_language_unavailable_modal(*this);
}
const auto& state = prelaunch_state();
@@ -1019,6 +1071,9 @@ void Prelaunch::update() {
break;
case iso::Region::NorthAmerica:
innerRML += "USA";
if (state.activeDiscInfo.platform == iso::Platform::Wii) {
innerRML += fmt::format(" Rev. {}", state.activeDiscInfo.revision);
}
break;
case iso::Region::Korea:
innerRML += "KOR";
+3
View File
@@ -54,6 +54,8 @@ struct PrelaunchState {
std::string activeDiscPath;
iso::DiscInfo activeDiscInfo{};
GameLanguage initialLanguage = GameLanguage::English;
GameLanguage unavailableLanguage = GameLanguage::English;
bool pendingLanguageUnavailableNotice = false;
std::string initialGraphicsBackend;
int initialCardFileType = 0;
std::string errorString;
@@ -69,5 +71,6 @@ void refresh_configured_disc_state() noexcept;
void open_iso_picker() noexcept;
bool is_restart_pending() noexcept;
void try_push_verification_modal(Document& host);
void try_push_language_unavailable_modal(Document& host);
} // namespace dusk::ui
+33 -28
View File
@@ -11,6 +11,7 @@
#include "dusk/data.hpp"
#include "dusk/imgui/ImGuiEngine.hpp"
#include "dusk/io.hpp"
#include "dusk/language.hpp"
#include "dusk/presentation.hpp"
#include <borealis/io.hpp>
#include <borealis/file_select.hpp>
@@ -53,14 +54,6 @@
namespace dusk::ui {
namespace {
constexpr std::array kLanguageNames = {
"English",
"German",
"French",
"Spanish",
"Italian",
};
constexpr std::array kCardFileTypes = {
"Card Image",
"GCI Folder",
@@ -220,6 +213,18 @@ AuroraBackend configured_backend() {
return configuredBackend;
}
bool is_graphics_backend_restart_pending() {
return getSettings().backend.graphicsBackend.getValue() !=
prelaunch_state().initialGraphicsBackend;
}
Rml::String graphics_backend_display_name() {
if (is_graphics_backend_restart_pending()) {
return Rml::String{backend_name(configured_backend())};
}
return Rml::String{backend_name(aurora_get_backend())};
}
Rml::String configured_data_path_display_name() {
const auto path = data::abbreviated_path_string(data::configured_data_path());
if (path.empty()) {
@@ -562,18 +567,15 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.key = "Language",
.getValue =
[] {
const auto& state = prelaunch_state();
if (!state.configuredDiscCanLaunch || state.configuredDiscInfo.region != iso::Region::Europe) {
return kLanguageNames[0];
}
const u8 idx = static_cast<u8>(getSettings().game.language.getValue());
return kLanguageNames[idx];
return language::language_name(getSettings().game.language.getValue());
},
.isDisabled =
[] {
const auto& state = prelaunch_state();
return !state.configuredDiscCanLaunch ||
state.configuredDiscInfo.region != iso::Region::Europe;
if (!state.configuredDiscCanLaunch) {
return true;
}
return language::available_languages(state.configuredDiscInfo).size() <= 1;
},
.isModified =
[] {
@@ -582,18 +584,22 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
},
}),
rightPane, [](Pane& pane) {
for (int i = 0; i < kLanguageNames.size(); i++) {
const auto& state = prelaunch_state();
const auto languages = state.configuredDiscCanLaunch
? language::available_languages(state.configuredDiscInfo)
: language::available_languages({});
for (const GameLanguage language : languages) {
pane.add_button({
.text = kLanguageNames[i],
.text = language::language_name(language),
.isSelected =
[i] {
[language] {
return getSettings().game.language.getValue() ==
static_cast<GameLanguage>(i);
language;
},
})
.on_pressed([i] {
.on_pressed([language] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().game.language.setValue(static_cast<GameLanguage>(i));
getSettings().game.language.setValue(language);
config::save();
});
}
@@ -602,12 +608,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
leftPane.register_control(
leftPane.add_select_button({
.key = "Graphics Backend",
.getValue = [] { return Rml::String{backend_name(aurora_get_backend())}; },
.isModified =
[] {
return getSettings().backend.graphicsBackend.getValue() !=
prelaunch_state().initialGraphicsBackend;
},
.getValue = [] { return graphics_backend_display_name(); },
.isModified = [] { return is_graphics_backend_restart_pending(); },
}),
rightPane, [](Pane& pane) {
const auto availableBackends = available_backends();
@@ -1225,6 +1227,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Allows Wolf Link to howl and change the time of day.");
addOption("Quick Transform (R+Y)", getSettings().game.enableQuickTransform,
"Transform instantly by pressing R and Y simultaneously.");
addOption("Aiming Reticle", getSettings().game.aimingReticle,
"Shows the aiming reticle for bow and slingshot.");
leftPane.add_section("Speedrunning");
config_bool_select(leftPane, rightPane, getSettings().game.speedrunMode,
@@ -1553,6 +1557,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
void SettingsWindow::update() {
if (mPrelaunch && top_document() == this) {
try_push_verification_modal(*this);
try_push_language_unavailable_modal(*this);
}
Window::update();
+15 -3
View File
@@ -26,10 +26,18 @@ void init() {
if (game == "GZ2E"sv) {
gameVersion = GameVersion::GcnUsa;
} else if (game == "GZ2P") {
} else if (game == "GZ2P"sv) {
gameVersion = GameVersion::GcnPal;
} else if (game == "GZ2J") {
} else if (game == "GZ2J"sv) {
gameVersion = GameVersion::GcnJpn;
} else if (game == "RZDE"sv && diskId.gameVersion == 0) {
gameVersion = GameVersion::WiiUsaRev0;
} else if (game == "RZDE"sv && diskId.gameVersion == 2) {
gameVersion = GameVersion::WiiUsa;
} else if (game == "RZDP"sv) {
gameVersion = GameVersion::WiiPal;
} else if (game == "RZDJ"sv) {
gameVersion = GameVersion::WiiJpn;
} else {
// TODO: Handle remaining valid versions.
DuskLog.fatal("Unknown/unsupported game version in disc: {}", game);
@@ -52,8 +60,12 @@ bool isWii() {
|| getGameVersion() == GameVersion::WiiKor;
}
bool isJpnOrLessThanWiiJpn() {
return isRegionJpn() || getGameVersion() < GameVersion::WiiJpn;
}
bool isPalOrAtLeastWiiR2() {
return getGameVersion() == GameVersion::GcnPal || getGameVersion() >= GameVersion::WiiUsa;
return isRegionPal() || (isWii() && getGameVersion() != GameVersion::WiiUsaRev0);
}
bool isRegionJpn() {
+19 -8
View File
@@ -5,18 +5,19 @@
*/
namespace dusk::version {
enum class GameVersion : u8 {
GcnUsa = VERSION_GCN_USA,
GcnPal = VERSION_GCN_PAL,
GcnJpn = VERSION_GCN_JPN,
WiiUsaRev0 = VERSION_WII_USA_R0,
WiiUsa = VERSION_WII_USA_R2,
WiiPal = VERSION_WII_PAL,
WiiJpn = VERSION_WII_JPN,
WiiKor = VERSION_WII_KOR,
WiiUsaRev0,
WiiPal,
WiiJpn,
GcnUsa,
GcnPal,
GcnJpn,
WiiUsa,
WiiKor,
};
bool isGcn();
bool isWii();
bool isJpnOrLessThanWiiJpn();
bool isPalOrAtLeastWiiR2();
bool isRegionPal();
@@ -61,4 +62,14 @@ namespace dusk::version {
return defaultValue;
}
template<typename T>
T platformSelect(const T& gcn, const T& wii) {
return isGcn() ? gcn : wii;
}
template<typename T>
T regionSelect(const T& usa, const T& pal, const T& jpn) {
return isRegionUsa() ? usa : isRegionPal() ? pal : jpn;
}
} // namespace dusk::version

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