Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer

This commit is contained in:
gymnast86
2026-06-08 18:08:13 -07:00
27 changed files with 490 additions and 2543 deletions
+17 -4
View File
@@ -148,6 +148,7 @@ option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
option(DUSK_ENABLE_UPDATE_CHECKER "Enable update checking support" ON)
option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF)
option(DUSK_PACKAGE_INSTALL "Install Dusklight with a Linux-native file structure" OFF)
option(DUSK_GFX_DEBUG_GROUPS "Report debug groups to the native graphics API" ${DUSK_GFX_DEBUG_GROUPS_DEFAULT})
set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN")
set(DUSK_SENTRY_ENVIRONMENT "development" CACHE STRING "Sentry environment")
@@ -256,7 +257,6 @@ elseif (MSVC)
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/utf-8>)
endif ()
include(FetchContent)
# Declare all dependencies first so CMake can download them in parallel
@@ -427,6 +427,11 @@ if(ANDROID)
list(APPEND GAME_COMPILE_DEFS TARGET_ANDROID=1)
endif ()
if (DUSK_PACKAGE_INSTALL)
include(GNUInstallDirs)
list(APPEND GAME_COMPILE_DEFS DUSK_ASSET_DIR="${CMAKE_INSTALL_FULL_DATADIR}/dusklight/")
endif ()
if (DUSK_GFX_DEBUG_GROUPS)
list(APPEND GAME_COMPILE_DEFS DUSK_GFX_DEBUG_GROUPS=1)
target_compile_definitions(aurora_gx PRIVATE AURORA_GFX_DEBUG_GROUPS)
@@ -666,12 +671,20 @@ set(EXTRA_TARGETS "")
if (TARGET crashpad_handler)
list(APPEND EXTRA_TARGETS crashpad_handler)
endif ()
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX})
if (DUSK_PACKAGE_INSTALL)
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_BINDIR})
else()
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
aurora_install_runtime_dlls(dusklight ${CMAKE_INSTALL_PREFIX})
if (NOT APPLE)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_PREFIX})
if (DUSK_PACKAGE_INSTALL)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/dusklight)
else()
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
endif ()
if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo AND NOT DUSK_PACKAGE_INSTALL)
set(DEBUG_FILES_LIST "")
foreach (target IN LISTS BINARY_TARGETS EXTRA_TARGETS)
get_target_output_name(${target} output_name)
+1 -1
+12
View File
@@ -4574,6 +4574,18 @@ public:
cXyz mIBChainInterpCurrHandRoot;
bool mIBChainInterpPrevValid;
bool mIBChainInterpCurrValid;
cXyz mHsChainInterpPrevTop;
cXyz mHsChainInterpCurrTop;
cXyz mHsChainInterpPrevRoot;
cXyz mHsChainInterpCurrRoot;
cXyz mHsChainInterpPrevSubRoot;
cXyz mHsChainInterpCurrSubRoot;
cXyz mHsChainInterpPrevSubTop;
cXyz mHsChainInterpCurrSubTop;
bool mHsChainInterpPrevValid;
bool mHsChainInterpCurrValid;
bool mIsRollstab = false;
#endif
}; // Size: 0x385C
+7 -2
View File
@@ -299,8 +299,13 @@ public:
/* 0x168C */ u8 field_0x168c;
/* 0x168D */ u8 field_0x168d;
/* 0x168E */ u8 HIOInit;
#if TARGET_PC
cXyz mLineInterpPrev[MG_ROD_LURE_LINE_LEN];
cXyz mLineInterpCurr[MG_ROD_LURE_LINE_LEN];
bool mLineInterpPrevValid;
bool mLineInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(dmg_rod_class) == 0x1690);
#endif /* D_A_MG_ROD_H */
+9
View File
@@ -66,9 +66,18 @@ public:
/* 0x2CA7 */ s8 hide_lock;
/* 0x2CA8 */ cXyz field_0x2ca8;
/* 0x2CB4 */ u8 field_0x2cb4;
#if TARGET_PC
Mtx mChainInterpPrev[6][16];
Mtx mChainInterpCurr[6][16];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
};
#if !TARGET_PC
STATIC_ASSERT(sizeof(obj_keyhole_class) == 0x2CB8);
#endif
class daObj_Keyhole_HIO_c : public JORReflexible {
public:
+15 -1
View File
@@ -57,6 +57,14 @@ enum class MenuScaling : u8 {
Dusklight = 2,
};
enum class MagicArmorMode : u8 {
NORMAL = 0,
ON_DAMAGE = 1,
DOUBLE_DEFENSE = 2,
INVINCIBLE = 3,
COSMETIC = 4,
};
namespace config {
template <>
struct ConfigEnumRange<BloomMode> {
@@ -105,6 +113,12 @@ struct ConfigEnumRange<MenuScaling> {
static constexpr auto min = MenuScaling::GameCube;
static constexpr auto max = MenuScaling::Dusklight;
};
template <>
struct ConfigEnumRange<MagicArmorMode> {
static constexpr auto min = MagicArmorMode::NORMAL;
static constexpr auto max = MagicArmorMode::COSMETIC;
};
} // namespace config
// Persistent user settings
@@ -234,7 +248,7 @@ struct UserSettings {
ConfigVar<bool> canTransformAnywhere;
ConfigVar<bool> fastRoll;
ConfigVar<bool> fastSpinner;
ConfigVar<bool> freeMagicArmor;
ConfigVar<MagicArmorMode> armorRupeeDrain;
ConfigVar<bool> invincibleEnemies;
// Technical
File diff suppressed because it is too large Load Diff
+46 -18
View File
@@ -12764,7 +12764,19 @@ void daAlink_c::setMagicArmorBrk(int i_status) {
BOOL daAlink_c::checkMagicArmorHeavy() const {
#if TARGET_PC
return checkMagicArmorWearAbility() && (dComIfGs_getRupee() == 0 && !dusk::getSettings().game.freeMagicArmor);
if(!checkMagicArmorWearAbility()) {
return false;
}
switch(dusk::getSettings().game.armorRupeeDrain) {
case dusk::MagicArmorMode::NORMAL:
return dComIfGs_getRupee() == 0;
case dusk::MagicArmorMode::ON_DAMAGE:
case dusk::MagicArmorMode::DOUBLE_DEFENSE:
case dusk::MagicArmorMode::INVINCIBLE:
case dusk::MagicArmorMode::COSMETIC:
return false;
}
#else
return checkMagicArmorWearAbility() && dComIfGs_getRupee() == 0;
#endif
@@ -14826,6 +14838,8 @@ void daAlink_c::deleteEquipItem(BOOL i_isPlaySound, BOOL i_isDeleteKantera) {
#if TARGET_PC
mIBChainInterpPrevValid = false;
mIBChainInterpCurrValid = false;
mHsChainInterpPrevValid = false;
mHsChainInterpCurrValid = false;
#endif
field_0x0774 = NULL;
field_0x0778 = NULL;
@@ -18737,7 +18751,7 @@ int daAlink_c::execute() {
#if TARGET_PC
// This handles rupee drain and transitions between rupees/no rupees
// We can skip all of that if the magic armor doesn't use rupees
if (!dusk::getSettings().game.freeMagicArmor && checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) {
if (dusk::getSettings().game.armorRupeeDrain.getValue() == dusk::MagicArmorMode::NORMAL && checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) {
#else
if (checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) {
#endif
@@ -19798,23 +19812,37 @@ int daAlink_c::draw() {
dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0);
#if TARGET_PC
if (dusk::frame_interp::is_enabled() &&
mEquipItem == dItemNo_IRONBALL_e &&
mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
{
if (mIBChainInterpCurrValid) {
memcpy(mIBChainInterpPrevPos, mIBChainInterpCurrPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpPrevAngle, mIBChainInterpCurrAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpPrevHandRoot = mIBChainInterpCurrHandRoot;
mIBChainInterpPrevValid = true;
if (dusk::frame_interp::is_enabled()) {
if (mEquipItem == dItemNo_IRONBALL_e &&
mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
{
if (mIBChainInterpCurrValid) {
memcpy(mIBChainInterpPrevPos, mIBChainInterpCurrPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpPrevAngle, mIBChainInterpCurrAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpPrevHandRoot = mIBChainInterpCurrHandRoot;
mIBChainInterpPrevValid = true;
}
memcpy(mIBChainInterpCurrPos, mIronBallChainPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpCurrAngle, mIronBallChainAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpCurrHandRoot = mHookshotTopPos;
mIBChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&ironBallChainInterpCallback, this);
} else {
if (mHsChainInterpCurrValid) {
mHsChainInterpPrevTop = mHsChainInterpCurrTop;
mHsChainInterpPrevRoot = mHsChainInterpCurrRoot;
mHsChainInterpPrevSubRoot = mHsChainInterpCurrSubRoot;
mHsChainInterpPrevSubTop = mHsChainInterpCurrSubTop;
mHsChainInterpPrevValid = true;
}
mHsChainInterpCurrTop = mHookshotTopPos;
mHsChainInterpCurrRoot = mHeldItemRootPos;
mHsChainInterpCurrSubRoot = field_0x3810;
mHsChainInterpCurrSubTop = mIronBallBgChkPos;
mHsChainInterpCurrValid = true;
}
memcpy(mIBChainInterpCurrPos, mIronBallChainPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpCurrAngle, mIronBallChainAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpCurrHandRoot = mHookshotTopPos;
mIBChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&ironBallChainInterpCallback, this);
}
#endif
}
+25 -1
View File
@@ -192,7 +192,7 @@ int daAlink_c::setDamagePoint(int i_dmgAmount, BOOL i_checkZoraMag, BOOL i_setDm
if (checkMagicArmorNoDamage()) {
#if TARGET_PC
if(dusk::getSettings().game.freeMagicArmor) {
if(dusk::getSettings().game.armorRupeeDrain.getValue() == dusk::MagicArmorMode::INVINCIBLE) {
i_dmgAmount = 0;
}
#endif
@@ -202,6 +202,11 @@ int daAlink_c::setDamagePoint(int i_dmgAmount, BOOL i_checkZoraMag, BOOL i_setDm
if (!mpHIO->mDamage.m.mInvincible && g_debugHpMode == 0)
#endif
{
#if TARGET_PC
if(checkMagicArmorWearAbility() && dusk::getSettings().game.armorRupeeDrain.getValue() == dusk::MagicArmorMode::DOUBLE_DEFENSE) {
i_dmgAmount /= 2;
}
#endif
dComIfGp_setItemLifeCount(-i_dmgAmount, 0);
}
@@ -281,7 +286,26 @@ BOOL daAlink_c::checkIcePolygonDamage(cBgS_PolyInfo* i_poly) {
}
BOOL daAlink_c::checkMagicArmorNoDamage() {
#ifdef TARGET_PC
if (!checkMagicArmorWearAbility()) {
return false;
}
switch(dusk::getSettings().game.armorRupeeDrain) {
case dusk::MagicArmorMode::NORMAL:
return !checkMagicArmorHeavy();
case dusk::MagicArmorMode::ON_DAMAGE:
return dComIfGs_getRupee() != 0;
case dusk::MagicArmorMode::DOUBLE_DEFENSE:
return false;
case dusk::MagicArmorMode::INVINCIBLE:
return true;
case dusk::MagicArmorMode::COSMETIC:
return false;
}
#else
return checkMagicArmorWearAbility() && !checkMagicArmorHeavy();
#endif
}
int daAlink_c::checkPolyDamage() {
+23
View File
@@ -136,8 +136,26 @@ void daAlink_c::hsChainShape_c::draw() {
}
}
} else {
#if TARGET_PC
cXyz hsInterpTop, hsInterpRoot, hsInterpSubRoot, hsInterpSubTop;
if (dusk::frame_interp::is_enabled() && alink->mHsChainInterpPrevValid && alink->mHsChainInterpCurrValid) {
const f32 alpha = dusk::frame_interp::get_interpolation_step();
hsInterpTop = alink->mHsChainInterpPrevTop + (alink->mHsChainInterpCurrTop - alink->mHsChainInterpPrevTop) * alpha;
hsInterpRoot = alink->mHsChainInterpPrevRoot + (alink->mHsChainInterpCurrRoot - alink->mHsChainInterpPrevRoot) * alpha;
hsInterpSubRoot = alink->mHsChainInterpPrevSubRoot + (alink->mHsChainInterpCurrSubRoot - alink->mHsChainInterpPrevSubRoot) * alpha;
hsInterpSubTop = alink->mHsChainInterpPrevSubTop + (alink->mHsChainInterpCurrSubTop - alink->mHsChainInterpPrevSubTop) * alpha;
} else {
hsInterpTop = alink->getHsChainTopPos();
hsInterpRoot = alink->getHsChainRootPos();
hsInterpSubRoot = alink->getHsSubChainRootPos();
hsInterpSubTop = alink->getHsSubChainTopPos();
}
const cXyz& chainRootPos = hsInterpRoot;
const cXyz& chainTopPos = hsInterpTop;
#else
const cXyz& chainRootPos = alink->getHsChainRootPos();
const cXyz& chainTopPos = alink->getHsChainTopPos();
#endif
cXyz maxDistance = chainRootPos - chainTopPos;
f32 maxDistanceF = maxDistance.abs();
@@ -200,8 +218,13 @@ void daAlink_c::hsChainShape_c::draw() {
}
}
#if TARGET_PC
const cXyz& subChainRootPos = hsInterpSubRoot;
const cXyz& subChainTopPos = hsInterpSubTop;
#else
const cXyz& subChainRootPos = alink->getHsSubChainRootPos();
const cXyz& subChainTopPos = alink->getHsSubChainTopPos();
#endif
maxDistance = subChainRootPos - subChainTopPos;
maxDistanceF = maxDistance.abs();
+2 -2
View File
@@ -348,7 +348,7 @@ void daAlink_c::changeLink(int param_0) {
initModel(static_cast<J3DModelData*>(dComIfG_getObjectRes(l_mArcName, "al_hands.bmd")), 0);
#if TARGET_PC
if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.freeMagicArmor)
if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.armorRupeeDrain.getValue() != dusk::MagicArmorMode::NORMAL)
#else
if (dComIfGs_getRupee() != 0)
#endif
@@ -458,7 +458,7 @@ void daAlink_c::changeLink(int param_0) {
field_0x06f0 = field_0x064C->getMaterialNodePointer(2)->getShape();
#if TARGET_PC
if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.freeMagicArmor) {
if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.armorRupeeDrain.getValue() != dusk::MagicArmorMode::NORMAL) {
#else
if (dComIfGs_getRupee() != 0) {
#endif
+9
View File
@@ -5472,6 +5472,15 @@ int daB_ZANT_c::create() {
fopAcM_ct(this, daB_ZANT_c);
OS_REPORT("B_ZANT PARAM %x\n", fopAcM_GetParam(this));
#if TARGET_PC
// Due to our loads being so much faster, Zant can initialize *before* the player
// This breaks respawning in the final phase of the fight when it tries
// to load the player's position
if (daPy_getPlayerActorClass() == NULL) {
return cPhs_INIT_e;
}
#endif
mSwbit = fopAcM_GetParam(this);
if (mSwbit != 0xFF) {
if (dComIfGs_isSwitch(mSwbit, fopAcM_GetRoomNo(this))) {
+8
View File
@@ -923,6 +923,14 @@ static void damage_check(e_sm2_class* i_this) {
sm_hit_actor->mode = 10;
u8 new_color_type = new_col_d[(sm_hit_actor->type * 7) + i_this->type];
#if TARGET_PC
if (dusk::getSettings().game.restoreWiiGlitches &&
((sm_hit_actor->type == TYPE_BLUE && i_this->type == TYPE_YELLOW) ||
(sm_hit_actor->type == TYPE_YELLOW && i_this->type == TYPE_BLUE)))
{
new_color_type = TYPE_GREEN;
}
#endif
i_this->type = new_color_type;
sm_hit_actor->type = new_color_type;
+37 -231
View File
@@ -16,12 +16,30 @@
using GameVersion = dusk::version::GameVersion;
static u8* 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}}, 0x4000), 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}}, 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}}, 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}}, 0x60), true); return buf; }
#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())
// make a copy of the cape texture that can be overwritten with the tears
static u8 l_Egnd_mantTEX_copy[0x4000];
// keep our cached texture objects out here so that we can update them from multiple places
static bool textureObjsInitialized = false;
static TGXTlutObj tlutObj;
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}}, 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}}, sizeof(buf)), true); return buf; }
//#define l_pos (l_pos_get())
#define l_normal (l_normal_get())
#define l_texCoord (l_texCoord_get())
#else
#include "assets/l_Egnd_mantTEX.h"
@@ -31,228 +49,6 @@ static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bo
#endif
#include "d/d_s_play.h"
static u32 l_pos[507] = {
0x42480000, 0x3F5CFC93, 0xC365BD9C, 0x4226AAAA,
0x3F5CFC93, 0xC365BD9C, 0x42055556, 0x3F5CFC93,
0xC365BD9C, 0x41C80000, 0x3F5CFC93, 0xC365BD9C,
0x41855556, 0x3F5CFC93, 0xC365BD9C, 0x41055556,
0x3F5CFC93, 0xC365BD9C, 0x358637BD, 0x3F5CFC93,
0xC365BD9C, 0xC1055554, 0x3F5CFC93, 0xC365BD9C,
0xC1855554, 0x3F5CFC93, 0xC365BD9C, 0xC1C7FFFF,
0x3F5CFC93, 0xC365BD9C, 0xC2055554, 0x3F5CFC93,
0xC365BD9C, 0xC226AAAA, 0x3F5CFC93, 0xC365BD9C,
0xC2480000, 0x3F5CFC93, 0xC365BD9C, 0x42480000,
0x3F5CFC93, 0xC35292F0, 0x4226AAAA, 0x3F5CFC93,
0xC35292F0, 0x42055556, 0x3F5CFC93, 0xC35292F0,
0x41C80000, 0x3F5CFC93, 0xC35292F0, 0x41855556,
0x3F5CFC93, 0xC35292F0, 0x41055556, 0x3F5CFC93,
0xC35292F0, 0x358637BD, 0x3F5CFC93, 0xC35292F0,
0xC1055554, 0x3F5CFC93, 0xC35292F0, 0xC1855554,
0x3F5CFC93, 0xC35292F0, 0xC1C7FFFF, 0x3F5CFC93,
0xC35292F0, 0xC2055554, 0x3F5CFC93, 0xC35292F0,
0xC226AAAA, 0x3F5CFC93, 0xC35292F0, 0xC2480000,
0x3F5CFC93, 0xC35292F0, 0x42480000, 0x3F5CFC93,
0xC33F6846, 0x4226AAAA, 0x3F5CFC93, 0xC33F6846,
0x42055556, 0x3F5CFC93, 0xC33F6846, 0x41C80000,
0x3F5CFC93, 0xC33F6846, 0x41855556, 0x3F5CFC93,
0xC33F6846, 0x41055556, 0x3F5CFC93, 0xC33F6846,
0x358637BD, 0x3F5CFC93, 0xC33F6846, 0xC1055554,
0x3F5CFC93, 0xC33F6846, 0xC1855554, 0x3F5CFC93,
0xC33F6846, 0xC1C7FFFF, 0x3F5CFC93, 0xC33F6846,
0xC2055554, 0x3F5CFC93, 0xC33F6846, 0xC226AAAA,
0x3F5CFC93, 0xC33F6846, 0xC2480000, 0x3F5CFC93,
0xC33F6846, 0x42480000, 0x3F5CFC93, 0xC32C3D9C,
0x4226AAAA, 0x3F5CFC93, 0xC32C3D9C, 0x42055556,
0x3F5CFC93, 0xC32C3D9C, 0x41C80000, 0x3F5CFC93,
0xC32C3D9C, 0x41855556, 0x3F5CFC93, 0xC32C3D9C,
0x41055556, 0x3F5CFC93, 0xC32C3D9C, 0x358637BD,
0x3F5CFC93, 0xC32C3D9C, 0xC1055554, 0x3F5CFC93,
0xC32C3D9C, 0xC1855554, 0x3F5CFC93, 0xC32C3D9C,
0xC1C7FFFF, 0x3F5CFC93, 0xC32C3D9C, 0xC2055554,
0x3F5CFC93, 0xC32C3D9C, 0xC226AAAA, 0x3F5CFC93,
0xC32C3D9C, 0xC2480000, 0x3F5CFC93, 0xC32C3D9C,
0x42480000, 0x3F5CFC93, 0xC31912F1, 0x4226AAAA,
0x3F5CFC93, 0xC31912F1, 0x42055556, 0x3F5CFC93,
0xC31912F1, 0x41C80000, 0x3F5CFC93, 0xC31912F1,
0x41855556, 0x3F5CFC93, 0xC31912F1, 0x41055556,
0x3F5CFC93, 0xC31912F1, 0x358637BD, 0x3F5CFC93,
0xC31912F1, 0xC1055554, 0x3F5CFC93, 0xC31912F1,
0xC1855554, 0x3F5CFC93, 0xC31912F1, 0xC1C7FFFF,
0x3F5CFC93, 0xC31912F1, 0xC2055554, 0x3F5CFC93,
0xC31912F1, 0xC226AAAA, 0x3F5CFC93, 0xC31912F1,
0xC2480000, 0x3F5CFC93, 0xC31912F1, 0x42480000,
0x3F5CFC93, 0xC305E846, 0x4226AAAA, 0x3F5CFC93,
0xC305E846, 0x42055556, 0x3F5CFC93, 0xC305E846,
0x41C80000, 0x3F5CFC93, 0xC305E846, 0x41855556,
0x3F5CFC93, 0xC305E846, 0x41055556, 0x3F5CFC93,
0xC305E846, 0x358637BD, 0x3F5CFC93, 0xC305E846,
0xC1055554, 0x3F5CFC93, 0xC305E846, 0xC1855554,
0x3F5CFC93, 0xC305E846, 0xC1C7FFFF, 0x3F5CFC93,
0xC305E846, 0xC2055554, 0x3F5CFC93, 0xC305E846,
0xC226AAAA, 0x3F5CFC93, 0xC305E846, 0xC2480000,
0x3F5CFC93, 0xC305E846, 0x42480000, 0x3F5CFC93,
0xC2E57B38, 0x4226AAAA, 0x3F5CFC93, 0xC2E57B38,
0x42055556, 0x3F5CFC93, 0xC2E57B38, 0x41C80000,
0x3F5CFC93, 0xC2E57B38, 0x41855556, 0x3F5CFC93,
0xC2E57B38, 0x41055556, 0x3F5CFC93, 0xC2E57B38,
0x358637BD, 0x3F5CFC93, 0xC2E57B38, 0xC1055554,
0x3F5CFC93, 0xC2E57B38, 0xC1855554, 0x3F5CFC93,
0xC2E57B38, 0xC1C7FFFF, 0x3F5CFC93, 0xC2E57B38,
0xC2055554, 0x3F5CFC93, 0xC2E57B38, 0xC226AAAA,
0x3F5CFC93, 0xC2E57B38, 0xC2480000, 0x3F5CFC93,
0xC2E57B38, 0x42480000, 0x3F5CFC93, 0xC2BF25E2,
0x4226AAAA, 0x3F5CFC93, 0xC2BF25E2, 0x42055556,
0x3F5CFC93, 0xC2BF25E2, 0x41C80000, 0x3F5CFC93,
0xC2BF25E2, 0x41855556, 0x3F5CFC93, 0xC2BF25E2,
0x41055556, 0x3F5CFC93, 0xC2BF25E2, 0x358637BD,
0x3F5CFC93, 0xC2BF25E2, 0xC1055554, 0x3F5CFC93,
0xC2BF25E2, 0xC1855554, 0x3F5CFC93, 0xC2BF25E2,
0xC1C7FFFF, 0x3F5CFC93, 0xC2BF25E2, 0xC2055554,
0x3F5CFC93, 0xC2BF25E2, 0xC226AAAA, 0x3F5CFC93,
0xC2BF25E2, 0xC2480000, 0x3F5CFC93, 0xC2BF25E2,
0x42480000, 0x3F5CFC93, 0xC298D08D, 0x4226AAAA,
0x3F5CFC93, 0xC298D08D, 0x42055556, 0x3F5CFC93,
0xC298D08D, 0x41C80000, 0x3F5CFC93, 0xC298D08D,
0x41855556, 0x3F5CFC93, 0xC298D08D, 0x41055556,
0x3F5CFC93, 0xC298D08D, 0x358637BD, 0x3F5CFC93,
0xC298D08D, 0xC1055554, 0x3F5CFC93, 0xC298D08D,
0xC1855554, 0x3F5CFC93, 0xC298D08D, 0xC1C7FFFF,
0x3F5CFC93, 0xC298D08D, 0xC2055554, 0x3F5CFC93,
0xC298D08D, 0xC226AAAA, 0x3F5CFC93, 0xC298D08D,
0xC2480000, 0x3F5CFC93, 0xC298D08D, 0x42480000,
0x3F5CFC93, 0xC264F66F, 0x4226AAAA, 0x3F5CFC93,
0xC264F66F, 0x42055556, 0x3F5CFC93, 0xC264F66F,
0x41C80000, 0x3F5CFC93, 0xC264F66F, 0x41855556,
0x3F5CFC93, 0xC264F66F, 0x41055556, 0x3F5CFC93,
0xC264F66F, 0x358637BD, 0x3F5CFC93, 0xC264F66F,
0xC1055554, 0x3F5CFC93, 0xC264F66F, 0xC1855554,
0x3F5CFC93, 0xC264F66F, 0xC1C7FFFF, 0x3F5CFC93,
0xC264F66F, 0xC2055554, 0x3F5CFC93, 0xC264F66F,
0xC226AAAA, 0x3F5CFC93, 0xC264F66F, 0xC2480000,
0x3F5CFC93, 0xC264F66F, 0x42480000, 0x3F5CFC93,
0xC2184BC4, 0x4226AAAA, 0x3F5CFC93, 0xC2184BC4,
0x42055556, 0x3F5CFC93, 0xC2184BC4, 0x41C80000,
0x3F5CFC93, 0xC2184BC4, 0x41855556, 0x3F5CFC93,
0xC2184BC4, 0x41055556, 0x3F5CFC93, 0xC2184BC4,
0x358637BD, 0x3F5CFC93, 0xC2184BC4, 0xC1055554,
0x3F5CFC93, 0xC2184BC4, 0xC1855554, 0x3F5CFC93,
0xC2184BC4, 0xC1C7FFFF, 0x3F5CFC93, 0xC2184BC4,
0xC2055554, 0x3F5CFC93, 0xC2184BC4, 0xC226AAAA,
0x3F5CFC93, 0xC2184BC4, 0xC2480000, 0x3F5CFC93,
0xC2184BC4, 0x42480000, 0x3F5CFC93, 0xC1974231,
0x4226AAAA, 0x3F5CFC93, 0xC1974231, 0x42055556,
0x3F5CFC93, 0xC1974231, 0x41C80000, 0x3F5CFC93,
0xC1974231, 0x41855556, 0x3F5CFC93, 0xC1974231,
0x41055556, 0x3F5CFC93, 0xC1974231, 0x358637BD,
0x3F5CFC93, 0xC1974231, 0xC1055554, 0x3F5CFC93,
0xC1974231, 0xC1855554, 0x3F5CFC93, 0xC1974231,
0xC1C7FFFF, 0x3F5CFC93, 0xC1974231, 0xC2055554,
0x3F5CFC93, 0xC1974231, 0xC226AAAA, 0x3F5CFC93,
0xC1974231, 0xC2480000, 0x3F5CFC93, 0xC1974231,
0x42480000, 0x3F5CFC93, 0x3E84C964, 0x4226AAAA,
0x3F5CFC93, 0x3E84C964, 0x42055556, 0x3F5CFC93,
0x3E84C964, 0x41C80000, 0x3F5CFC93, 0x3E84C964,
0x41855556, 0x3F5CFC93, 0x3E84C964, 0x41055556,
0x3F5CFC93, 0x3E84C964, 0x358637BD, 0x3F5CFC93,
0x3E84C964, 0xC1055554, 0x3F5CFC93, 0x3E84C964,
0xC1855554, 0x3F5CFC93, 0x3E84C964, 0xC1C7FFFF,
0x3F5CFC93, 0x3E84C964, 0xC2055554, 0x3F5CFC93,
0x3E84C964, 0xC226AAAA, 0x3F5CFC93, 0x3E84C964,
0xC2480000, 0x3F5CFC93, 0x3E84C964,
};
static u32 l_normal[3] = {
0x00000000, 0x3F800000, 0x00000000,
};
static u32 l_texCoord[338] = {
0x00000000, 0x3F6AAAB0, 0x3DAAAA7E, 0x3F6AAAB0,
0x3DAAAA7E, 0x3F800000, 0x00000000, 0x3F800000,
0x3E2AAAC1, 0x3F6AAAB0, 0x3E2AAAC1, 0x3F800000,
0x3E800000, 0x3F6AAAB0, 0x3E800000, 0x3F800000,
0x3EAAAA9F, 0x3F6AAAB0, 0x3EAAAA9F, 0x3F800000,
0x3ED55561, 0x3F6AAAB0, 0x3ED55561, 0x3F800000,
0x3F000000, 0x3F6AAAB0, 0x3F000000, 0x3F800000,
0x3F155550, 0x3F6AAAB0, 0x3F155550, 0x3F800000,
0x3F2AAAB0, 0x3F6AAAB0, 0x3F2AAAB0, 0x3F800000,
0x3F400000, 0x3F6AAAB0, 0x3F400000, 0x3F800000,
0x3F555550, 0x3F6AAAB0, 0x3F555550, 0x3F800000,
0x3F6AAAB0, 0x3F6AAAB0, 0x3F6AAAB0, 0x3F800000,
0x3F800000, 0x3F6AAAB0, 0x3F800000, 0x3F800000,
0x00000000, 0x3F555550, 0x3DAAAA7E, 0x3F555550,
0x3E2AAAC1, 0x3F555550, 0x3E800000, 0x3F555550,
0x3EAAAA9F, 0x3F555550, 0x3ED55561, 0x3F555550,
0x3F000000, 0x3F555550, 0x3F155550, 0x3F555550,
0x3F2AAAB0, 0x3F555550, 0x3F400000, 0x3F555550,
0x3F555550, 0x3F555550, 0x3F6AAAB0, 0x3F555550,
0x3F800000, 0x3F555550, 0x00000000, 0x3F400000,
0x3DAAAA7E, 0x3F400000, 0x3E2AAAC1, 0x3F400000,
0x3E800000, 0x3F400000, 0x3EAAAA9F, 0x3F400000,
0x3ED55561, 0x3F400000, 0x3F000000, 0x3F400000,
0x3F155550, 0x3F400000, 0x3F2AAAB0, 0x3F400000,
0x3F400000, 0x3F400000, 0x3F555550, 0x3F400000,
0x3F6AAAB0, 0x3F400000, 0x3F800000, 0x3F400000,
0x00000000, 0x3F2AAAB0, 0x3DAAAA7E, 0x3F2AAAB0,
0x3E2AAAC1, 0x3F2AAAB0, 0x3E800000, 0x3F2AAAB0,
0x3EAAAA9F, 0x3F2AAAB0, 0x3ED55561, 0x3F2AAAB0,
0x3F000000, 0x3F2AAAB0, 0x3F155550, 0x3F2AAAB0,
0x3F2AAAB0, 0x3F2AAAB0, 0x3F400000, 0x3F2AAAB0,
0x3F555550, 0x3F2AAAB0, 0x3F6AAAB0, 0x3F2AAAB0,
0x3F800000, 0x3F2AAAB0, 0x00000000, 0x3F155550,
0x3DAAAA7E, 0x3F155550, 0x3E2AAAC1, 0x3F155550,
0x3E800000, 0x3F155550, 0x3EAAAA9F, 0x3F155550,
0x3ED55561, 0x3F155550, 0x3F000000, 0x3F155550,
0x3F155550, 0x3F155550, 0x3F2AAAB0, 0x3F155550,
0x3F400000, 0x3F155550, 0x3F555550, 0x3F155550,
0x3F6AAAB0, 0x3F155550, 0x3F800000, 0x3F155550,
0x00000000, 0x3F000000, 0x3DAAAA7E, 0x3F000000,
0x3E2AAAC1, 0x3F000000, 0x3E800000, 0x3F000000,
0x3EAAAA9F, 0x3F000000, 0x3ED55561, 0x3F000000,
0x3F000000, 0x3F000000, 0x3F155550, 0x3F000000,
0x3F2AAAB0, 0x3F000000, 0x3F400000, 0x3F000000,
0x3F555550, 0x3F000000, 0x3F6AAAB0, 0x3F000000,
0x3F800000, 0x3F000000, 0x00000000, 0x3ED55561,
0x3DAAAA7E, 0x3ED55561, 0x3E2AAAC1, 0x3ED55561,
0x3E800000, 0x3ED55561, 0x3EAAAA9F, 0x3ED55561,
0x3ED55561, 0x3ED55561, 0x3F000000, 0x3ED55561,
0x3F155550, 0x3ED55561, 0x3F2AAAB0, 0x3ED55561,
0x3F400000, 0x3ED55561, 0x3F555550, 0x3ED55561,
0x3F6AAAB0, 0x3ED55561, 0x3F800000, 0x3ED55561,
0x00000000, 0x3EAAAA9F, 0x3DAAAA7E, 0x3EAAAA9F,
0x3E2AAAC1, 0x3EAAAA9F, 0x3E800000, 0x3EAAAA9F,
0x3EAAAA9F, 0x3EAAAA9F, 0x3ED55561, 0x3EAAAA9F,
0x3F000000, 0x3EAAAA9F, 0x3F155550, 0x3EAAAA9F,
0x3F2AAAB0, 0x3EAAAA9F, 0x3F400000, 0x3EAAAA9F,
0x3F555550, 0x3EAAAA9F, 0x3F6AAAB0, 0x3EAAAA9F,
0x3F800000, 0x3EAAAA9F, 0x00000000, 0x3E800000,
0x3DAAAA7E, 0x3E800000, 0x3E2AAAC1, 0x3E800000,
0x3E800000, 0x3E800000, 0x3EAAAA9F, 0x3E800000,
0x3ED55561, 0x3E800000, 0x3F000000, 0x3E800000,
0x3F155550, 0x3E800000, 0x3F2AAAB0, 0x3E800000,
0x3F400000, 0x3E800000, 0x3F555550, 0x3E800000,
0x3F6AAAB0, 0x3E800000, 0x3F800000, 0x3E800000,
0x00000000, 0x3E2AAAC1, 0x3DAAAA7E, 0x3E2AAAC1,
0x3E2AAAC1, 0x3E2AAAC1, 0x3E800000, 0x3E2AAAC1,
0x3EAAAA9F, 0x3E2AAAC1, 0x3ED55561, 0x3E2AAAC1,
0x3F000000, 0x3E2AAAC1, 0x3F155550, 0x3E2AAAC1,
0x3F2AAAB0, 0x3E2AAAC1, 0x3F400000, 0x3E2AAAC1,
0x3F555550, 0x3E2AAAC1, 0x3F6AAAB0, 0x3E2AAAC1,
0x3F800000, 0x3E2AAAC1, 0x00000000, 0x3DAAAA7E,
0x3DAAAA7E, 0x3DAAAA7E, 0x3E2AAAC1, 0x3DAAAA7E,
0x3E800000, 0x3DAAAA7E, 0x3EAAAA9F, 0x3DAAAA7E,
0x3ED55561, 0x3DAAAA7E, 0x3F000000, 0x3DAAAA7E,
0x3F155550, 0x3DAAAA7E, 0x3F2AAAB0, 0x3DAAAA7E,
0x3F400000, 0x3DAAAA7E, 0x3F555550, 0x3DAAAA7E,
0x3F6AAAB0, 0x3DAAAA7E, 0x3F800000, 0x3DAAAA7E,
0x00000000, 0x00000000, 0x3DAAAA7E, 0x00000000,
0x3E2AAAC1, 0x00000000, 0x3E800000, 0x00000000,
0x3EAAAA9F, 0x00000000, 0x3ED55561, 0x00000000,
0x3F000000, 0x00000000, 0x3F155550, 0x00000000,
0x3F2AAAB0, 0x00000000, 0x3F400000, 0x00000000,
0x3F555550, 0x00000000, 0x3F6AAAB0, 0x00000000,
0x3F800000, 0x00000000,
};
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
@@ -307,7 +103,7 @@ static void mant_build_anchor_frame(const cXyz& anchor_a, const cXyz& anchor_b,
void daMant_packet_c::draw() {
ZoneScoped;
#if TARGET_PC
void* image = l_Egnd_mantTEX;
void* image = l_Egnd_mantTEX_copy;
void* lut = l_Egnd_mantPAL;
#else
void* image = tex_d[0];
@@ -389,12 +185,12 @@ void daMant_packet_c::draw() {
}
}
GXSETARRAY(GX_VA_POS, draw_pos, sizeof(mNrm[0]), 12, true);
GXSETARRAY(GX_VA_NRM, &l_normal, sizeof(l_normal), 12, false);
GXSETARRAY(GX_VA_NRM, l_normal, sizeof(f32) * 3, 12, false);
#else
GXSETARRAY(GX_VA_POS, this->getPos(), sizeof(mPos[0]), 12, true);
GXSETARRAY(GX_VA_NRM, this->getNrm(), sizeof(mNrm[0]), 12, true);
#endif
GXSETARRAY(GX_VA_TEX0, &l_texCoord, sizeof(l_texCoord), 8, false); // TODO: set to true when converted to float literals
GXSETARRAY(GX_VA_TEX0, l_texCoord, sizeof(f32) * 338, 8, false);
GXSetZCompLoc(0);
GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE);
@@ -420,10 +216,6 @@ void daMant_packet_c::draw() {
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
#if TARGET_PC
static bool textureObjsInitialized = false;
static TGXTlutObj tlutObj;
static TGXTexObj mainTexObj;
static TGXTexObj undersideTexObj;
if (!textureObjsInitialized) {
GXInitTlutObj(&tlutObj, lut, GX_TL_RGB5A3, 0x100);
GXInitTexObjCI(&mainTexObj, image, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
@@ -917,8 +709,14 @@ static int daMant_Execute(mant_class* i_this) {
if (0 <= uVar1 && uVar1 < 0x4000) {
int iVar5 = (uVar1 & 7) + (uVar1 & 0x78) * 4 + (uVar1 >> 4 & 0x18) + (uVar1 & 0x3e00);
l_Egnd_mantTEX[iVar5] = l_Egnd_mantTEX_U[iVar5] = 0;
DUSK_IF_ELSE(l_Egnd_mantTEX_copy[iVar5], l_Egnd_mantTEX[iVar5]) = l_Egnd_mantTEX_U[iVar5] = 0;
}
#if TARGET_PC
if(textureObjsInitialized) {
GXInitTlutObjData(&tlutObj, l_Egnd_mantPAL); // make sure the cached textures are updated
}
#endif
}
}
@@ -956,6 +754,14 @@ static int daMant_Create(fopAc_ac_c* i_this) {
l_Egnd_mantTEX_U[i] = 6;
}
#if TARGET_PC
memcpy(l_Egnd_mantTEX_copy, l_Egnd_mantTEX, sizeof(l_Egnd_mantTEX_copy));
if(textureObjsInitialized) {
GXInitTlutObjData(&tlutObj, l_Egnd_mantPAL); // make sure the cached textures are updated
}
#endif
lbl_277_bss_0 = 0;
daMant_Execute(m_this);
return 4;
+49
View File
@@ -26,6 +26,7 @@
#include <cstring>
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#include "dusk/version.hpp"
#include "dusk/randomizer/game/randomizer_context.hpp"
@@ -181,6 +182,25 @@ static int Worm_nodeCallBack(J3DJoint* i_joint, int param_1) {
return 1;
}
#if TARGET_PC
static void dmg_rod_interp_callback(bool isSimFrame, void* pUserWork) {
dmg_rod_class* i_this = (dmg_rod_class*)pUserWork;
if (!i_this->mLineInterpPrevValid || !i_this->mLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
const int count = i_this->kind == MG_ROD_KIND_LURE ? MG_ROD_LURE_LINE_LEN : MG_ROD_UKI_LINE_LEN;
cXyz* dst = i_this->linemat.getPos(0);
for (int i = 0; i < count; i++) {
const cXyz& p0 = i_this->mLineInterpPrev[i];
const cXyz& p1 = i_this->mLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
static GXColor l_color = {0xFF, 0xFF, 0x96, 0xFF};
i_this->linemat.update(count, l_color, &i_this->actor.tevStr);
}
#endif
static int dmg_rod_Draw(dmg_rod_class* i_this) {
int unused;
fopAc_ac_c* actor = &i_this->actor;
@@ -221,6 +241,18 @@ static int dmg_rod_Draw(dmg_rod_class* i_this) {
i_this->linemat.update(MG_ROD_LURE_LINE_LEN, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->linemat);
#if TARGET_PC
if (dusk::frame_interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, MG_ROD_LURE_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->linemat.getPos(0), MG_ROD_LURE_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&dmg_rod_interp_callback, i_this);
}
#endif
model = i_this->rod_modelMorf->getModel();
g_env_light.setLightTevColorType_MAJI(model, &i_this->actor.tevStr);
i_this->rod_modelMorf->entryDL();
@@ -245,6 +277,18 @@ static int dmg_rod_Draw(dmg_rod_class* i_this) {
i_this->linemat.update(MG_ROD_UKI_LINE_LEN, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->linemat);
#if TARGET_PC
if (dusk::frame_interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, MG_ROD_UKI_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->linemat.getPos(0), MG_ROD_UKI_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&dmg_rod_interp_callback, i_this);
}
#endif
for (int i = 0; i < 15; i++) {
g_env_light.setLightTevColorType_MAJI(i_this->rod_uki_model[i], &actor->tevStr);
mDoExt_modelUpdateDL(i_this->rod_uki_model[i]);
@@ -6415,6 +6459,11 @@ static int dmg_rod_Create(fopAc_ac_c* i_this) {
return cPhs_ERROR_e;
}
#if TARGET_PC
rod->mLineInterpPrevValid = false;
rod->mLineInterpCurrValid = false;
#endif
OS_REPORT("//////////////MG_ROD SET 2 !!\n");
if (!hio_set) {
rod->HIOInit = TRUE;
+4 -4
View File
@@ -332,13 +332,13 @@ int daNpcImpal_c::step(s16 i_angle, int i_animate) {
}
void daNpcImpal_c::playExpression() {
daNpcF_anmPlayData dat0 = {ANM_1, mpHIO->m.common.morf_frame, 1};
daNpcF_anmPlayData dat0 = {ANM_1, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat0[1] = {&dat0};
daNpcF_anmPlayData dat1 = {ANM_5, mpHIO->m.common.morf_frame, 1};
daNpcF_anmPlayData dat1 = {ANM_5, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat1[1] = {&dat1};
daNpcF_anmPlayData dat2 = {ANM_4, mpHIO->m.common.morf_frame, 1};
daNpcF_anmPlayData dat2 = {ANM_4, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat2[1] = {&dat2};
daNpcF_anmPlayData dat3 = {ANM_6, mpHIO->m.common.morf_frame, 1};
daNpcF_anmPlayData dat3 = {ANM_6, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat3[1] = {&dat3};
daNpcF_anmPlayData dat4 = {ANM_8, mpHIO->m.common.morf_frame, 0};
daNpcF_anmPlayData* pDat4[1] = {&dat4};
+38
View File
@@ -10,6 +10,9 @@
#include "d/d_s_play.h"
#include "d/actor/d_a_player.h"
#include "Z2AudioLib/Z2Instances.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
daObj_Keyhole_HIO_c::daObj_Keyhole_HIO_c() {
id = -1;
@@ -53,6 +56,21 @@ static int daObj_Keyhole_Draw(obj_keyhole_class* i_this) {
for (int i = 0; i < 6; i++) {
kh_chain_s* chain_s = &i_this->chain_s[i];
for (int j = 0; j < i_this->chain_num; j++) {
#if TARGET_PC
if (dusk::frame_interp::is_enabled() && i_this->mChainInterpPrevValid && i_this->mChainInterpCurrValid) {
const f32 alpha = dusk::frame_interp::get_interpolation_step();
Mtx mtx;
const f32* p0 = (const f32*)i_this->mChainInterpPrev[i][j];
const f32* p1 = (const f32*)i_this->mChainInterpCurr[i][j];
f32* dst = (f32*)mtx;
for (int k = 0; k < 12; k++) {
dst[k] = p0[k] + (p1[k] - p0[k]) * alpha;
}
chain_s->model[j]->setBaseTRMtx(mtx);
g_env_light.setLightTevColorType_MAJI(chain_s->model[j], &actor->tevStr);
mDoExt_modelUpdateDL(chain_s->model[j]);
} else
#endif
dComIfGp_entrySimpleModel(chain_s->model[j], fopAcM_GetRoomNo(actor));
}
}
@@ -370,6 +388,21 @@ static void chain_move(obj_keyhole_class* i_this) {
ANGLE_ADD(sp8, TREG_S(0) + 0x3D00);
}
}
#if TARGET_PC
if (dusk::frame_interp::is_enabled()) {
if (i_this->mChainInterpCurrValid) {
memcpy(i_this->mChainInterpPrev, i_this->mChainInterpCurr, sizeof(i_this->mChainInterpCurr));
i_this->mChainInterpPrevValid = true;
}
for (int i = 0; i < 6; i++) {
for (int j = 0; j < i_this->chain_num; j++) {
MTXCopy(i_this->chain_s[i].model[j]->getBaseTRMtx(), i_this->mChainInterpCurr[i][j]);
}
}
i_this->mChainInterpCurrValid = true;
}
#endif
}
static void open(obj_keyhole_class* i_this) {
@@ -750,6 +783,11 @@ static int daObj_Keyhole_Create(fopAc_ac_c* a_this) {
return cPhs_ERROR_e;
}
#if TARGET_PC
i_this->mChainInterpPrevValid = false;
i_this->mChainInterpCurrValid = false;
#endif
OS_REPORT("//////////////OBJ_KEYHOLE SET 2 !!\n");
if (i_this->arg0 == 3) {
+29 -11
View File
@@ -19,12 +19,30 @@
#include <numbers>
#include <array>
constexpr u16 kMapResolutionMultiplier = 4;
constexpr u16 kMapImageSide = 16 * kMapResolutionMultiplier;
constexpr u16 kPreferredMapResolutionMultiplier = 4;
constexpr u32 kMaxMapRenderPixels = 4096 * 4096;
constexpr u16 kMapImageSide = 16 * kPreferredMapResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
typedef std::function<u8(size_t, size_t)> PaintI8Fn;
u16 map_resolution_multiplier(u16 width, u16 height) {
const u32 basePixels = static_cast<u32>(width) * height;
if (basePixels == 0) {
return 1;
}
u16 scale = kPreferredMapResolutionMultiplier;
while (scale > 1) {
const u32 scalePixels = static_cast<u32>(scale) * scale;
if (basePixels <= kMaxMapRenderPixels / scalePixels) {
break;
}
scale--;
}
return scale;
}
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
const auto blocksAcross = width >> 3;
@@ -478,9 +496,9 @@ void dRenderingMap_c::makeResTIMG(ResTIMG* p_image, u16 width, u16 height, u8* p
p_image->format = GX_TF_C8;
p_image->alphaEnabled = 2;
#ifdef TARGET_PC
// Increase map render resolution
p_image->width = width * kMapResolutionMultiplier;
p_image->height = height * kMapResolutionMultiplier;
const u16 scale = map_resolution_multiplier(width, height);
p_image->width = width * scale;
p_image->height = height * scale;
#else
p_image->width = width;
p_image->height = height;
@@ -563,9 +581,9 @@ void dRenderingFDAmap_c::drawBack() const {
void dRenderingFDAmap_c::preRenderingMap() {
#ifdef TARGET_PC
// Increase map render resolution
const u16 w = mTexWidth * kMapResolutionMultiplier;
const u16 h = mTexHeight * kMapResolutionMultiplier;
const u16 scale = map_resolution_multiplier(mTexWidth, mTexHeight);
const u16 w = mTexWidth * scale;
const u16 h = mTexHeight * scale;
GXCreateFrameBuffer(w, h);
// Set logical viewport dimensions
GXSetViewport(0.0f, 0.0f, mTexWidth, mTexHeight, 0.0f, 1.0f);
@@ -610,9 +628,9 @@ void dRenderingFDAmap_c::preRenderingMap() {
void dRenderingFDAmap_c::postRenderingMap() {
GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
#ifdef TARGET_PC
// Increase map render resolution
const u16 w = mTexWidth * kMapResolutionMultiplier;
const u16 h = mTexHeight * kMapResolutionMultiplier;
const u16 scale = map_resolution_multiplier(mTexWidth, mTexHeight);
const u16 w = mTexWidth * scale;
const u16 h = mTexHeight * scale;
GXSetTexCopySrc(0, 0, w, h);
GXSetTexCopyDst(w, h, GX_CTF_R8, GX_FALSE);
GXCopyTex(field_0x4, GX_TRUE);
+6
View File
@@ -1943,6 +1943,12 @@ void dMenu_Fmap2DBack_c::regionMapMove(STControl* i_stick) {
calcAllMapPos2D(mArrowPos3DX + control_xpos - mStageTransX,
mArrowPos3DZ + control_ypos - mStageTransZ, &pos_x, &pos_y);
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
pos_x = getMirrorPosX(pos_x, 0.0f);
}
#endif
mSelectRegion = 0xff;
int region = mRegionCursor;
if (region != 0xff && region != 7) {
+72 -3
View File
@@ -609,6 +609,70 @@ int dMsgObject_c::_delete() {
return 1;
}
#if TARGET_PC
struct MirrorMsgOverride {
u32 gcMsgId;
u32 wiiMsgId;
};
static const MirrorMsgOverride mirrorMsgOverrides[] = {
{0x153a, 0x3c4a},
{0x1553, 0x3c63},
{0x1558, 0x3c68},
{0x155c, 0x3c6c},
{0x1569, 0x3c79},
{0x156f, 0x3c7f},
{0x1f81, 0x4691},
{0x232a, 0x4a3a},
{0x13f2, 0x3b02},
{0x1416, 0x3b26},
{0x1417, 0x3b27},
{0x1419, 0x3b29},
{0x1521, 0x3c31},
{0x1614, 0x3d24},
{0x1626, 0x3d36},
{0x1628, 0x3d38},
{0x16aa, 0x3dba},
{0x16b8, 0x3dc8},
{0x16b9, 0x3dc9},
{0x1904, 0x4014},
{0x1919, 0x4029},
{0x19cd, 0x40dd},
{0x19d3, 0x40e3},
{0x19d6, 0x40e6},
{0x19e6, 0x40f6},
{0x19eb, 0x40fb},
{0x14b6, 0x3bc6},
{0x151a, 0x3c2a},
{0x1530, 0x3c40},
{0x1532, 0x3c42},
{0x2726, 0x4e36},
{0x2736, 0x4e46},
{0x2739, 0x4e49},
{0x274c, 0x4e5c},
{0x24da, 0x4bea},
{0x24db, 0x4beb},
{0x13d8, 0x3ae8},
{0x13dc, 0x3aec},
{0x13eb, 0x3afb},
{0x17df, 0x3eef},
{0x17e2, 0x3ef2},
{0x1dae, 0x44be},
{0x14ca, 0x3bda},
{0x470, 0x493},
{0x473, 0x492},
};
static u32 getMirrorMsgOverride(u32 msgId) {
for (size_t i = 0; i < sizeof(mirrorMsgOverrides) / sizeof(mirrorMsgOverrides[0]); i++) {
if (mirrorMsgOverrides[i].gcMsgId == msgId) {
return mirrorMsgOverrides[i].wiiMsgId;
}
}
return msgId;
}
#endif
void dMsgObject_c::setMessageIndex(u32 revoIndex, u32 param_2, bool param_3) {
field_0x158 = revoIndex;
revoIndex = getRevoMessageIndex(revoIndex);
@@ -735,9 +799,14 @@ u32 dMsgObject_c::getRevoMessageIndex(u32 param_1) {
}
#endif
if (!g_MsgObject_HIO_c.mMessageDisplay) {
return param_1;
}
#if TARGET_PC
if (!dusk::getSettings().game.enableMirrorMode) {
if (!g_MsgObject_HIO_c.mMessageDisplay) { return param_1; } }
if (param_1 == getMirrorMsgOverride(param_1)) { return param_1; }
#else
if (!g_MsgObject_HIO_c.mMessageDisplay) { return param_1; }
#endif
u32 msgIndexCount;
JMSMesgInfo_c* pMsg;
int i = 0;
+17 -6
View File
@@ -80,15 +80,12 @@ template<ConfigValue T>
void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) {
if constexpr (std::is_enum_v<T>) {
if (jsonValue.is_boolean()) {
DuskConfigLog.error("Doing default migration of CVar {} from bool, enum values may not be what is expected!", cVar.getName());
using Underlying = std::underlying_type_t<T>;
const bool b = jsonValue.get<bool>();
Underlying raw;
if constexpr (std::is_same_v<T, dusk::FrameInterpMode>) {
raw = b ? static_cast<Underlying>(2) : static_cast<Underlying>(0);
} else {
raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
}
const Underlying raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
cVar.setValue(sanitizeEnumValue(cVar, static_cast<T>(raw)), false);
return;
@@ -198,9 +195,23 @@ namespace dusk::config {
template class ConfigImpl<dusk::DiscVerificationState>;
template class ConfigImpl<dusk::GameLanguage>;
template class ConfigImpl<dusk::GyroMode>;
template<> void ConfigImpl<FrameInterpMode>::loadFromJson(ConfigVar<FrameInterpMode>& cVar, const json& jsonValue) {
if (jsonValue.is_boolean()) {
const bool b = jsonValue.get<bool>();
const FrameInterpMode mode = b ? FrameInterpMode::Unlimited : FrameInterpMode::Off;
cVar.setValue(sanitizeEnumValue(cVar, mode), false);
return;
}
cVar.setValue(sanitizeEnumValue(cVar, jsonValue.get<FrameInterpMode>()), false);
}
template class ConfigImpl<dusk::FrameInterpMode>;
template class ConfigImpl<dusk::MenuScaling>;
template class ConfigImpl<dusk::Resampler>;
template class ConfigImpl<dusk::MagicArmorMode>;
}
void dusk::config::Register(ConfigVarBase& configVar) {
+2 -1
View File
@@ -34,10 +34,11 @@ constexpr std::array<std::string_view, 4> kUserDataDirectories = {
"EUR",
"JAP",
};
constexpr std::array<std::string_view, 6> kUserDataFiles = {
constexpr std::array<std::string_view, 7> kUserDataFiles = {
"achievements.json",
"config.json",
"controller_ports.dat",
"gamecontrollerdb.txt",
"imgui.ini",
"keyboard_bindings.dat",
"states.json",
+4
View File
@@ -20,7 +20,11 @@
namespace dusk {
namespace {
std::string GetAssetPath(const char* assetName) {
#ifdef DUSK_ASSET_DIR
const char* basePath = DUSK_ASSET_DIR;
#else
const char* basePath = SDL_GetBasePath();
#endif
if (basePath != nullptr && basePath[0] != '\0') {
return std::string(basePath) + "res/" + assetName;
}
+2 -2
View File
@@ -127,7 +127,7 @@ UserSettings g_userSettings = {
.canTransformAnywhere {"game.canTransformAnywhere", false},
.fastRoll {"game.fastRoll", false},
.fastSpinner {"game.fastSpinner", false},
.freeMagicArmor {"game.freeMagicArmor", false},
.armorRupeeDrain {"game.armorRupeeDrain", MagicArmorMode::NORMAL},
.invincibleEnemies {"game.invincibleEnemies", false},
// Technical
@@ -257,7 +257,7 @@ void registerSettings() {
Register(g_userSettings.game.enableFastIronBoots);
Register(g_userSettings.game.canTransformAnywhere);
Register(g_userSettings.game.fastRoll);
Register(g_userSettings.game.freeMagicArmor);
Register(g_userSettings.game.armorRupeeDrain);
Register(g_userSettings.game.restoreWiiGlitches);
Register(g_userSettings.game.enableLinkDollRotation);
Register(g_userSettings.game.enableAchievementToasts);
+1 -1
View File
@@ -33,7 +33,7 @@ void resetForSpeedrunMode() {
getSettings().game.canTransformAnywhere.setSpeedrunValue(false);
getSettings().game.fastRoll.setSpeedrunValue(false);
getSettings().game.fastSpinner.setSpeedrunValue(false);
getSettings().game.freeMagicArmor.setSpeedrunValue(false);
getSettings().game.armorRupeeDrain.setSpeedrunValue(MagicArmorMode::NORMAL);
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
aurora_set_pause_on_focus_lost(false);
+41 -3
View File
@@ -75,6 +75,14 @@ constexpr std::array kMenuScalingModeLabels = {
"Dusklight",
};
constexpr std::array kMagicArmorModes = {
"Normal",
"On Damage",
"Double Defense",
"Invincible",
"Cosmetic",
};
bool try_parse_backend(std::string_view backend, AuroraBackend& outBackend) {
if (backend == "auto") {
outBackend = BACKEND_AUTO;
@@ -211,7 +219,7 @@ void reset_for_speedrun_mode() {
getSettings().game.canTransformAnywhere.setSpeedrunValue(false);
getSettings().game.fastRoll.setSpeedrunValue(false);
getSettings().game.fastSpinner.setSpeedrunValue(false);
getSettings().game.freeMagicArmor.setSpeedrunValue(false);
getSettings().game.armorRupeeDrain.setSpeedrunValue(MagicArmorMode::NORMAL);
getSettings().game.invincibleEnemies.setSpeedrunValue(false);
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
@@ -1272,8 +1280,38 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Makes Link's roll animation and movement twice as fast.");
addCheat("Fast Spinner", getSettings().game.fastSpinner,
"Speeds up Spinner movement while holding R.");
addCheat("Free Magic Armor", getSettings().game.freeMagicArmor,
"Lets the magic armor work without consuming rupees.");
leftPane.register_control(
leftPane.add_select_button({
.key = "Magic Armor Behavior",
.getValue =
[] {
return kMagicArmorModes[static_cast<u8>(getSettings().game.armorRupeeDrain.getValue())];
},
.isDisabled = [] { return getSettings().game.speedrunMode; },
.isModified =
[] {
return getSettings().game.armorRupeeDrain.getValue() !=
getSettings().game.armorRupeeDrain.getDefaultValue();
},
}),
rightPane, [](Pane& pane) {
for (int i = 0; i < kMagicArmorModes.size(); i++) {
pane.add_button({
.text = kMagicArmorModes[i],
.isSelected =
[i] {
return getSettings().game.armorRupeeDrain.getValue() == static_cast<MagicArmorMode>(i);
},
})
.on_pressed([i] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().game.armorRupeeDrain.setValue(static_cast<MagicArmorMode>(i));
config::Save();
});
}
pane.add_rml(
"<br/>Control the behavior of the Magic Armor.");
});
addCheat("Invincible Enemies", getSettings().game.invincibleEnemies,
"Prevents enemies from taking damage.");
});
+14 -13
View File
@@ -76,7 +76,6 @@
#include <dolphin/dvd.h>
#include "SDL3/SDL_init.h"
#include "SDL3/SDL_filesystem.h"
#include "SDL3/SDL_iostream.h"
#include "SDL3/SDL_misc.h"
#include "cxxopts.hpp"
@@ -491,14 +490,6 @@ static void LanguageInit() {
selectedLanguage = static_cast<u8>(dusk::getSettings().game.language.getValue());
}
static std::string asset_path(const char* assetName) {
const char* basePath = SDL_GetBasePath();
if (basePath != nullptr && basePath[0] != '\0') {
return std::string(basePath) + "res/" + assetName;
}
return std::string("res/") + assetName;
}
static void log_build_info() {
DuskLog.info("Build: {} (rev {}, built {}, type {})", DUSK_WC_DESCRIBE, DUSK_WC_REVISION, DUSK_WC_DATE, DUSK_BUILD_TYPE);
DuskLog.info("Platform: {}", DUSK_PLATFORM_NAME);
@@ -579,10 +570,17 @@ int game_main(int argc, char* argv[]) {
// PADSetDefaultMapping(&defaultPadMapping, PAD_TYPE_STANDARD);
{
// Load mappings from https://github.com/mdqinc/SDL_GameControllerDB
const auto mappingsPath = asset_path("gamecontrollerdb.txt");
if (SDL_AddGamepadMappingsFromFile(mappingsPath.c_str()) < 0) {
DuskLog.warn("Failed to load gamecontrollerdb.txt: {}", SDL_GetError());
const auto mappingsPath = dusk::ConfigPath / "gamecontrollerdb.txt";
std::error_code ec;
if (std::filesystem::exists(mappingsPath, ec)) {
const auto mappingsPathString = dusk::io::fs_path_to_string(mappingsPath);
if (SDL_AddGamepadMappingsFromFile(mappingsPathString.c_str()) < 0) {
DuskLog.warn("Failed to load gamecontrollerdb.txt from '{}': {}",
mappingsPathString, SDL_GetError());
}
} else if (ec) {
DuskLog.warn("Failed to inspect gamecontrollerdb.txt in data folder '{}': {}",
dusk::io::fs_path_to_string(mappingsPath), ec.message());
}
}
@@ -596,6 +594,9 @@ int game_main(int argc, char* argv[]) {
config.appName = dusk::AppName;
config.userPath = reinterpret_cast<const char*>(userPathString.c_str());
config.cachePath = reinterpret_cast<const char*>(cachePathString.c_str());
#ifdef DUSK_ASSET_DIR
config.resourcesPath = DUSK_ASSET_DIR;
#endif
config.vsync = dusk::getSettings().video.enableVsync;
config.startFullscreen = dusk::getSettings().video.enableFullscreen;
config.windowPosX = -1;