From c786f40a23a099f3f5fc843815107e30d3a1f6bc Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 28 Feb 2026 15:43:37 -0700 Subject: [PATCH] Some MULTI_CHAR fixes --- CMakeLists.txt | 12 ++++----- include/global.h | 22 +++++++-------- src/d/actor/d_a_npc_bouS.cpp | 52 ++++++++++++++++++------------------ src/d/actor/d_a_npc_theB.cpp | 52 ++++++++++++++++++------------------ src/d/d_com_inf_game.cpp | 6 ++--- 5 files changed, 72 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41f61c8df9..6f9284539a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,11 @@ add_subdirectory(extern/aurora EXCLUDE_FROM_ALL) option(DUSK_BUILD_WARNINGS "If off, compiler warnings will be suppressed") if (CMAKE_SYSTEM_NAME STREQUAL Linux) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas -Wno-unused-variable -Wno-unused-parameter") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register") + # Multi-character constants ('ABCD') are implementation-defined but all compilers + # (CW, GCC, Clang, MSVC) encode them identically in big-endian order. + # For >4-char literals (which GCC/Clang truncate to int), use the MULTI_CHAR() macro. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar -Wno-unused-variable -Wno-unused-parameter") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar") set(CMAKE_INSTALL_RPATH "$ORIGIN") set(CMAKE_BUILD_RPATH "$ORIGIN") elseif (APPLE) @@ -38,10 +41,7 @@ elseif (MSVC) endif () add_compile_options(/utf-8) endif () -if (NOT MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error -Wno-c++11-narrowing") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error -Wno-c++11-narrowing") -endif () + include(files.cmake) diff --git a/include/global.h b/include/global.h index 8c9cfe3d7d..375b92de1a 100644 --- a/include/global.h +++ b/include/global.h @@ -169,22 +169,22 @@ static const float INF = 2000000000.0f; #define UNSET_FLAG(var, flag, type) (var) &= ~(flag) #endif -#ifdef TARGET_PC +// Macro for multi-character literals that exceed 4 bytes (e.g. 'ari_os'). +// CW encodes all characters in big-endian order into the full integer, but GCC/Clang +// truncate multi-char constants to int (4 bytes). This macro produces matching u64 +// values on all compilers. For <=4-char literals, raw constants like 'ABCD' are fine. +#ifdef __MWERKS__ + #define MULTI_CHAR(x) (x) +#else template - inline constexpr auto MultiCharLiteral(const char (&buf)[N]) { - // static_assert(buf[0] == '\'' && buf[N - 2] == '\''); // can't constexpr strings, just pray - constexpr int len = N - 1; - static_assert(len >= 2 && len <= 10); - + inline constexpr unsigned long long MultiCharLiteral(const char (&buf)[N]) { + static_assert(N - 1 >= 3 && N - 1 <= 10, "MULTI_CHAR literal must be 1-8 characters"); unsigned long long out = 0; - for (int i = 1; i < len - 1; i++) { - out = (out << 8) | ((unsigned long long)buf[i]); + for (int i = 1; i < N - 2; i++) { + out = (out << 8) | static_cast(buf[i]); } return out; } - - #define MULTI_CHAR(x) MultiCharLiteral(#x) -#else #define MULTI_CHAR(x) MultiCharLiteral(#x) #endif diff --git a/src/d/actor/d_a_npc_bouS.cpp b/src/d/actor/d_a_npc_bouS.cpp index a782634f37..6d807edacd 100644 --- a/src/d/actor/d_a_npc_bouS.cpp +++ b/src/d/actor/d_a_npc_bouS.cpp @@ -1361,22 +1361,22 @@ int daNpcBouS_c::EvCut_BousIntroSumo1(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': setLookMode(LOOK_PLAYER_TALK); mActorMngrs[0].entry(daPy_getPlayerActorClass()); break; - case MULTI_CHAR('0002'): - case MULTI_CHAR('0003'): - case MULTI_CHAR('0005'): - case MULTI_CHAR('0006'): - case MULTI_CHAR('0007'): - case MULTI_CHAR('0008'): - case MULTI_CHAR('0009'): + case '0002': + case '0003': + case '0005': + case '0006': + case '0007': + case '0008': + case '0009': initTalk(9, NULL); break; - case MULTI_CHAR('0004'): + case '0004': setExpressionAnm(ANM_FH_TALK_B, true); break; @@ -1397,17 +1397,17 @@ int daNpcBouS_c::EvCut_BousIntroSumo1(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): - case MULTI_CHAR('0004'): + case '0001': + case '0004': return 1; - case MULTI_CHAR('0002'): - case MULTI_CHAR('0003'): - case MULTI_CHAR('0005'): - case MULTI_CHAR('0006'): - case MULTI_CHAR('0007'): - case MULTI_CHAR('0008'): - case MULTI_CHAR('0009'): + case '0002': + case '0003': + case '0005': + case '0006': + case '0007': + case '0008': + case '0009': if (talkProc(NULL, TRUE, NULL)) { s32 choiceNo = mFlow.getChoiceNo(); OS_REPORT("二択分岐 %s\n", choiceNo == 0 ? "はい" : "いいえ"); @@ -1435,7 +1435,7 @@ int daNpcBouS_c::EvCut_BousIntroSumo2(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': initTalk(9, NULL); setLookMode(LOOK_PLAYER_TALK); mActorMngrs[0].entry(daPy_getPlayerActorClass()); @@ -1457,7 +1457,7 @@ int daNpcBouS_c::EvCut_BousIntroSumo2(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': if (mCurAngle.y == fopAcM_searchPlayerAngleY(this)) { if (talkProc(NULL, TRUE, NULL)) { int choiceNo = mFlow.getChoiceNo(); @@ -1490,15 +1490,15 @@ int daNpcBouS_c::EvCut_BousIntroSumo3(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': setLookMode(LOOK_PLAYER_TALK); mActorMngrs[0].entry(daPy_getPlayerActorClass()); break; - case MULTI_CHAR('0003'): + case '0003': setMotion(MOT_WALK, -1.0f, 0); // fallthrough - case MULTI_CHAR('0002'): + case '0002': setAngle(-0x2AAA); initTalk(9, NULL); break; @@ -1522,16 +1522,16 @@ int daNpcBouS_c::EvCut_BousIntroSumo3(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': return 1; - case MULTI_CHAR('0002'): + case '0002': if (talkProc(NULL, TRUE, NULL)) { return 1; } break; - case MULTI_CHAR('0003'): { + case '0003': { cXyz* pos = dComIfGp_evmng_getMyXyzP(i_staffId, "pos"); if (pos != NULL) { if (cLib_chaseAngleS(&shape_angle.y, cLib_targetAngleY(¤t.pos, pos), 0x100)) { diff --git a/src/d/actor/d_a_npc_theB.cpp b/src/d/actor/d_a_npc_theB.cpp index a0e6ffb701..5cde34a632 100644 --- a/src/d/actor/d_a_npc_theB.cpp +++ b/src/d/actor/d_a_npc_theB.cpp @@ -1177,10 +1177,10 @@ int daNpcTheB_c::EvCut_PersonalCombatIntro(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': break; - case MULTI_CHAR('0002'): + case '0002': initTalk(0x16, NULL); setLookMode(LOOK_PLAYER); mActorMngrs[0].entry(daPy_getPlayerActorClass()); @@ -1205,10 +1205,10 @@ int daNpcTheB_c::EvCut_PersonalCombatIntro(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': return 1; - case MULTI_CHAR('0002'): + case '0002': if (talkProc(NULL, TRUE, NULL)) { dComIfGs_onSaveDunSwitch(52); dComIfGs_onSaveDunSwitch(53); @@ -1230,7 +1230,7 @@ int daNpcTheB_c::EvCut_PersonalCombatRevenge(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): { + case '0001': { fopAc_ac_c* actor_p = getEvtAreaTagP(5, 0); cXyz* pos = dComIfGp_evmng_getMyXyzP(i_staffId, "pos"); int* angle = dComIfGp_evmng_getMyIntegerP(i_staffId, "angle"); @@ -1249,13 +1249,13 @@ int daNpcTheB_c::EvCut_PersonalCombatRevenge(int i_staffId) { break; } - case MULTI_CHAR('0002'): + case '0002': initTalk(0x17, NULL); setLookMode(LOOK_PLAYER); mActorMngrs[0].entry(daPy_getPlayerActorClass()); break; - case MULTI_CHAR('0003'): + case '0003': break; default: @@ -1283,19 +1283,19 @@ int daNpcTheB_c::EvCut_PersonalCombatRevenge(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': if (getCoachSpeed() == 0.0f) { return 1; } break; - case MULTI_CHAR('0002'): + case '0002': if (talkProc(NULL, TRUE, NULL)) { return 1; } break; - case MULTI_CHAR('0003'): + case '0003': return 1; default: @@ -1412,7 +1412,7 @@ int daNpcTheB_c::EvCut_AnnulationFieldRace(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': if (startAndGoal_p != NULL) { startAndGoal_p->readyStartTimer(); } @@ -1425,7 +1425,7 @@ int daNpcTheB_c::EvCut_AnnulationFieldRace(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': if (startAndGoal_p != NULL && startAndGoal_p->isStartCheck()) { return 1; } @@ -1445,15 +1445,15 @@ int daNpcTheB_c::EvCut_TheBHint(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': setMotionAnm(ANM_SIT, 0.0f); break; - case MULTI_CHAR('0002'): + case '0002': initTalk(mHintMsgNo, NULL); break; - case MULTI_CHAR('0003'): { + case '0003': { cXyz pos; csXyz angle; daNpcF_getPlayerInfoFromPlayerList(field_0xe04, mRoomNo, pos, angle); @@ -1480,11 +1480,11 @@ int daNpcTheB_c::EvCut_TheBHint(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): - case MULTI_CHAR('0003'): + case '0001': + case '0003': return 1; - case MULTI_CHAR('0002'): + case '0002': if (talkProc(NULL, TRUE, NULL)) { mHintEvtFlag = 0; return 1; @@ -1505,22 +1505,22 @@ int daNpcTheB_c::EvCut_CoachGuardGameOver(int i_staffId) { if (eventManager.getIsAddvance(i_staffId)) { switch (*cutName) { - case MULTI_CHAR('0001'): + case '0001': Z2GetAudioMgr()->bgmStart(Z2BGM_GAME_OVER, 0, 0); break; - case MULTI_CHAR('0002'): { + case '0002': { daNpcCoach_c* coach_p = (daNpcCoach_c*)fopAcM_SearchByID(parentActorID); cXyz pos(0.0f, -30000.0f, 0.0f); coach_p->setPosAngle(pos, shape_angle); break; } - case MULTI_CHAR('0003'): + case '0003': ((daCoach2D_c*)fpcM_SearchByName(PROC_COACH2D))->hide(); break; - case MULTI_CHAR('0004'): + case '0004': break; default: @@ -1530,12 +1530,12 @@ int daNpcTheB_c::EvCut_CoachGuardGameOver(int i_staffId) { } switch (*cutName) { - case MULTI_CHAR('0001'): - case MULTI_CHAR('0002'): - case MULTI_CHAR('0003'): + case '0001': + case '0002': + case '0003': return 1; - case MULTI_CHAR('0004'): + case '0004': daPy_getPlayerActorClass()->onForceGameOver(); return 1; diff --git a/src/d/d_com_inf_game.cpp b/src/d/d_com_inf_game.cpp index 2e5791f870..b7180656db 100644 --- a/src/d/d_com_inf_game.cpp +++ b/src/d/d_com_inf_game.cpp @@ -1114,7 +1114,7 @@ void dComIfG_inf_c::baseCsr_c::draw(f32 param_1, f32 param_2) { r28 = 0xFF; } - J2DPicture* picture = field_0x8.getPicture('cursor00'); + J2DPicture* picture = field_0x8.getPicture(MULTI_CHAR('cursor00')); JUT_ASSERT(1450, picture != NULL); picture->scale(1.3f, 1.3f); JUtility::TColor color = picture->getWhite(); @@ -1148,7 +1148,7 @@ void dComIfG_inf_c::baseCsr_c::create() { int rt = field_0x8.create(resInfo->getArchive(), "zelda_pointing_cursor_navi.blo"); JUT_ASSERT(1498, rt); - J2DPicture* picture = field_0x8.getPicture('cursor00'); + J2DPicture* picture = field_0x8.getPicture(MULTI_CHAR('cursor00')); JUT_ASSERT(1500, picture != NULL); JUtility::TColor color = picture->getWhite(); color.a = 0; @@ -1172,7 +1172,7 @@ void dComIfG_inf_c::baseCsr_c::particleExecute() { } void dComIfG_inf_c::anmCsr_c::draw(f32 param_1, f32 param_2) { - field_0x8.setPos('lock_n', param_1, param_2); + field_0x8.setPos(MULTI_CHAR('lock_n'), param_1, param_2); dComIfGd_set2DXlu(&field_0x8); } #endif