mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-11 04:37:55 -04:00
Merge remote-tracking branch 'origin/randomizer' into rando-archi
This commit is contained in:
+48
-7
@@ -126,6 +126,33 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "_cmake")
|
||||
|
||||
option(ENABLE_ASAN "Enable AddressSanitizer" OFF)
|
||||
if (ENABLE_ASAN)
|
||||
if (CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC" AND
|
||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/fsanitize=address>)
|
||||
add_link_options(/fsanitize=address /INCREMENTAL:NO)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "ProgramDatabase")
|
||||
foreach (_lang C CXX)
|
||||
foreach (_rtc_flag /RTC1 /RTCc /RTCs /RTCu)
|
||||
string(REPLACE "${_rtc_flag}" "" CMAKE_${_lang}_FLAGS_DEBUG "${CMAKE_${_lang}_FLAGS_DEBUG}")
|
||||
endforeach ()
|
||||
endforeach ()
|
||||
elseif (CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" AND
|
||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
add_compile_options(
|
||||
$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-fsanitize=address>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-fno-omit-frame-pointer>
|
||||
)
|
||||
add_link_options(-fsanitize=address)
|
||||
else ()
|
||||
message(FATAL_ERROR "ENABLE_ASAN requires GNU-like or MSVC-like C/C++ compiler frontends")
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(NDEBUG_SANITIZER) # Avoids absl issue with SwissTable debug code
|
||||
message(STATUS "dusklight: Enabled AddressSanitizer")
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
set(DAWN_USE_WAYLAND ON CACHE BOOL "Enable support for Wayland surface" FORCE)
|
||||
endif ()
|
||||
@@ -148,6 +175,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 +284,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
|
||||
@@ -351,9 +378,7 @@ set(GAME_INCLUDE_DIRS
|
||||
find_package(Threads REQUIRED)
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
|
||||
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
|
||||
Threads::Threads)
|
||||
|
||||
list(APPEND GAME_LIBS zstd::libzstd)
|
||||
Threads::Threads zstd::libzstd)
|
||||
|
||||
if (DUSK_ENABLE_SENTRY_NATIVE)
|
||||
list(APPEND GAME_LIBS sentry)
|
||||
@@ -427,6 +452,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)
|
||||
@@ -488,6 +518,9 @@ if(ANDROID)
|
||||
else ()
|
||||
add_executable(dusklight ${DUSK_FILES})
|
||||
endif ()
|
||||
if (ENABLE_ASAN)
|
||||
target_sources(dusklight PRIVATE src/dusk/asan_options.c)
|
||||
endif ()
|
||||
|
||||
# Add embedded data to target
|
||||
|
||||
@@ -666,12 +699,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)
|
||||
|
||||
@@ -52,6 +52,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "asan",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"ENABLE_ASAN": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-default",
|
||||
"displayName": "Linux (default)",
|
||||
@@ -83,6 +93,15 @@
|
||||
"linux-default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "linux-default-debug-asan",
|
||||
"displayName": "Linux (default) Debug ASan",
|
||||
"inherits": [
|
||||
"debug",
|
||||
"linux-default",
|
||||
"asan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "linux-default-relwithdebinfo",
|
||||
"displayName": "Linux (default) RelWithDebInfo",
|
||||
@@ -110,6 +129,15 @@
|
||||
"linux-clang"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "linux-clang-debug-asan",
|
||||
"displayName": "Linux (Clang) Debug ASan",
|
||||
"inherits": [
|
||||
"debug",
|
||||
"linux-clang",
|
||||
"asan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "linux-clang-relwithdebinfo",
|
||||
"displayName": "Linux (Clang) RelWithDebInfo",
|
||||
@@ -148,6 +176,15 @@
|
||||
"windows-msvc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc-debug-asan",
|
||||
"displayName": "Windows (MSVC) Debug ASan",
|
||||
"inherits": [
|
||||
"debug",
|
||||
"windows-msvc",
|
||||
"asan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc-relwithdebinfo",
|
||||
"displayName": "Windows (MSVC) RelWithDebInfo",
|
||||
@@ -239,6 +276,15 @@
|
||||
"macos-default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "macos-default-debug-asan",
|
||||
"displayName": "macOS (default) Debug ASan",
|
||||
"inherits": [
|
||||
"debug",
|
||||
"macos-default",
|
||||
"asan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "macos-default-relwithdebinfo",
|
||||
"displayName": "macOS (default) RelWithDebInfo",
|
||||
@@ -529,6 +575,12 @@
|
||||
"description": "Linux (default) debug build",
|
||||
"displayName": "Linux (default) Debug"
|
||||
},
|
||||
{
|
||||
"name": "linux-default-debug-asan",
|
||||
"configurePreset": "linux-default-debug-asan",
|
||||
"description": "Linux (default) debug build with AddressSanitizer",
|
||||
"displayName": "Linux (default) Debug ASan"
|
||||
},
|
||||
{
|
||||
"name": "linux-default-relwithdebinfo",
|
||||
"configurePreset": "linux-default-relwithdebinfo",
|
||||
@@ -541,6 +593,12 @@
|
||||
"description": "Linux (Clang) debug build",
|
||||
"displayName": "Linux (Clang) Debug"
|
||||
},
|
||||
{
|
||||
"name": "linux-clang-debug-asan",
|
||||
"configurePreset": "linux-clang-debug-asan",
|
||||
"description": "Linux (Clang) debug build with AddressSanitizer",
|
||||
"displayName": "Linux (Clang) Debug ASan"
|
||||
},
|
||||
{
|
||||
"name": "linux-clang-relwithdebinfo",
|
||||
"configurePreset": "linux-clang-relwithdebinfo",
|
||||
@@ -553,6 +611,12 @@
|
||||
"description": "macOS debug build",
|
||||
"displayName": "macOS Debug"
|
||||
},
|
||||
{
|
||||
"name": "macos-default-debug-asan",
|
||||
"configurePreset": "macos-default-debug-asan",
|
||||
"description": "macOS debug build with AddressSanitizer",
|
||||
"displayName": "macOS Debug ASan"
|
||||
},
|
||||
{
|
||||
"name": "macos-default-relwithdebinfo",
|
||||
"configurePreset": "macos-default-relwithdebinfo",
|
||||
@@ -610,6 +674,12 @@
|
||||
"description": "Windows (MSVC) debug build",
|
||||
"displayName": "Windows (MSVC) Debug"
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc-debug-asan",
|
||||
"configurePreset": "windows-msvc-debug-asan",
|
||||
"description": "Windows (MSVC) debug build with AddressSanitizer",
|
||||
"displayName": "Windows (MSVC) Debug ASan"
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc-relwithdebinfo",
|
||||
"configurePreset": "windows-msvc-relwithdebinfo",
|
||||
|
||||
@@ -180,6 +180,7 @@ cmake --build --preset macos-default-relwithdebinfo
|
||||
Alternate presets available:
|
||||
|
||||
* `macos-default-debug`: Clang, Debug
|
||||
* `macos-default-debug-asan`: Clang, Debug, AddressSanitizer
|
||||
|
||||
**ninja (Linux)**
|
||||
|
||||
@@ -191,8 +192,10 @@ cmake --build --preset linux-default-relwithdebinfo
|
||||
Alternate presets available:
|
||||
|
||||
* `linux-default-debug`: GCC, Debug
|
||||
* `linux-default-debug-asan`: GCC, Debug, AddressSanitizer
|
||||
* `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo
|
||||
* `linux-clang-debug`: Clang, Debug
|
||||
* `linux-clang-debug-asan`: Clang, Debug, AddressSanitizer
|
||||
|
||||
**ninja (Windows)**
|
||||
|
||||
@@ -204,6 +207,7 @@ cmake --build --preset windows-msvc-relwithdebinfo
|
||||
Alternate presets available:
|
||||
|
||||
* `windows-msvc-debug`: MSVC, Debug
|
||||
* `windows-msvc-debug-asan`: MSVC, Debug, AddressSanitizer
|
||||
* `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo
|
||||
* `windows-clang-debug`: Clang-cl, Debug
|
||||
|
||||
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: 19479a53e4...6fa2cbb961
@@ -1522,6 +1522,8 @@ set(DUSK_FILES
|
||||
src/dusk/ui/window.hpp
|
||||
src/dusk/ui/rando_config.cpp
|
||||
src/dusk/ui/rando_config.hpp
|
||||
src/dusk/ui/rando_seed_generation.cpp
|
||||
src/dusk/ui/rando_seed_generation.hpp
|
||||
src/dusk/achievements.cpp
|
||||
src/dusk/iso_validate.cpp
|
||||
src/dusk/livesplit.cpp
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -542,8 +542,11 @@ void J3DModel::viewCalc() {
|
||||
}
|
||||
|
||||
#ifdef TARGET_PC
|
||||
for (u16 i = 0; i < mModelData->getDrawMtxNum(); ++i) {
|
||||
dusk::frame_interp::record_final_mtx(getDrawMtxPtr()[i]);
|
||||
Mtx* drawMtx = getDrawMtxPtr();
|
||||
if (drawMtx != J3DMtxBuffer::sNoUseDrawMtxPtr) {
|
||||
for (u16 i = 0; i < mModelData->getDrawMtxNum(); ++i) {
|
||||
dusk::frame_interp::record_final_mtx(drawMtx[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+46
-18
@@ -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
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -499,7 +499,16 @@ int daObjLife_c::initActionOrderGetDemo() {
|
||||
int daObjLife_c::actionOrderGetDemo() {
|
||||
if (eventInfo.checkCommandItem()) {
|
||||
setStatus(STATUS_GET_DEMO_e);
|
||||
|
||||
|
||||
#if TARGET_PC
|
||||
// Set the tracker flag for rando now. The flag doesn't normally
|
||||
// get set until after execItemGive runs
|
||||
if (randomizer_IsActive()) {
|
||||
g_randomizerState.mTrackerTempItemFlag.flag = getSaveBitNo();
|
||||
g_randomizerState.mTrackerTempItemFlag.stage = getStageSaveId(getStageID());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mItemId != fpcM_ERROR_PROCESS_ID_e) {
|
||||
dComIfGp_event_setItemPartnerId(mItemId);
|
||||
}
|
||||
|
||||
+29
-11
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
const char* __asan_default_options(void) {
|
||||
return "abort_on_error=1:symbolize=1:intercept_memcmp=0:detect_leaks=0";
|
||||
}
|
||||
+26
-22
@@ -23,13 +23,9 @@ using json = nlohmann::json;
|
||||
|
||||
aurora::Module DuskConfigLog("dusk::config");
|
||||
|
||||
static absl::flat_hash_map<std::string_view, ConfigVarBase*> RegisteredConfigVars;
|
||||
static bool RegistrationDone = false;
|
||||
|
||||
static absl::flat_hash_map<std::string_view, ConfigVarBase*>& registered_config_vars() {
|
||||
static absl::flat_hash_map<std::string_view, ConfigVarBase*> vars;
|
||||
return vars;
|
||||
}
|
||||
|
||||
static std::filesystem::path GetConfigJsonPath() {
|
||||
return dusk::ConfigPath / ConfigFileName;
|
||||
}
|
||||
@@ -80,15 +76,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,23 +191,36 @@ 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) {
|
||||
auto& registeredConfigVars = registered_config_vars();
|
||||
const auto& name = configVar.getName();
|
||||
if (RegistrationDone) {
|
||||
DuskConfigLog.fatal("Tried to register CVar {} after registrations closed!", name);
|
||||
}
|
||||
|
||||
if (registeredConfigVars.contains(name)) {
|
||||
if (RegisteredConfigVars.contains(name)) {
|
||||
DuskConfigLog.fatal("Tried to register CVar {} twice!", name);
|
||||
}
|
||||
|
||||
registeredConfigVars[name] = &configVar;
|
||||
RegisteredConfigVars[name] = &configVar;
|
||||
configVar.markRegistered();
|
||||
}
|
||||
|
||||
@@ -239,7 +245,6 @@ void dusk::config::LoadFromUserPreferences() {
|
||||
}
|
||||
|
||||
static void LoadFromPath(const char* path) {
|
||||
auto& registeredConfigVars = registered_config_vars();
|
||||
auto data = dusk::io::FileStream::ReadAllBytes(path);
|
||||
|
||||
json j = json::parse(data);
|
||||
@@ -250,8 +255,8 @@ static void LoadFromPath(const char* path) {
|
||||
|
||||
for (const auto& el : j.items()) {
|
||||
const auto& key = el.key();
|
||||
auto configVar = registeredConfigVars.find(key);
|
||||
if (configVar == registeredConfigVars.end()) {
|
||||
auto configVar = RegisteredConfigVars.find(key);
|
||||
if (configVar == RegisteredConfigVars.end()) {
|
||||
DuskConfigLog.error("Unknown key '{}' found in config!", key);
|
||||
continue;
|
||||
}
|
||||
@@ -299,7 +304,7 @@ void dusk::config::Save() {
|
||||
|
||||
json j;
|
||||
|
||||
for (const auto& pair : registered_config_vars()) {
|
||||
for (const auto& pair : RegisteredConfigVars) {
|
||||
const auto layer = pair.second->getLayer();
|
||||
if (layer == ConfigVarLayer::Value || layer == ConfigVarLayer::Speedrun) {
|
||||
j[pair.first] = pair.second->getImpl()->dumpToJson(*pair.second);
|
||||
@@ -323,9 +328,8 @@ void dusk::config::ClearAllActionBindings(int port) {
|
||||
}
|
||||
|
||||
ConfigVarBase* dusk::config::GetConfigVar(std::string_view name) {
|
||||
auto& registeredConfigVars = registered_config_vars();
|
||||
const auto configVar = registeredConfigVars.find(name);
|
||||
if (configVar != registeredConfigVars.end()) {
|
||||
const auto configVar = RegisteredConfigVars.find(name);
|
||||
if (configVar != RegisteredConfigVars.end()) {
|
||||
return configVar->second;
|
||||
}
|
||||
|
||||
@@ -333,7 +337,7 @@ ConfigVarBase* dusk::config::GetConfigVar(std::string_view name) {
|
||||
}
|
||||
|
||||
void dusk::config::EnumerateRegistered(std::function<void(ConfigVarBase&)> callback) {
|
||||
for (auto& pair : registered_config_vars()) {
|
||||
for (auto& pair : RegisteredConfigVars) {
|
||||
callback(*pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ std::optional<std::string> RandomizerContext::WriteToFile() {
|
||||
const std::unordered_map<u16, u16> u16ShopOverrides(this->mShopOverrides.begin(), this->mShopOverrides.end());
|
||||
out["mShopOverrides"] = u16ShopOverrides;
|
||||
|
||||
out["mTwilitInsectOverrides"] = mTwilitInsectOverrides;
|
||||
|
||||
for (const auto& [key, data] : this->mFlowItemMessageOverrides) {
|
||||
auto node = out["mFlowItemMessageOverrides"][key];
|
||||
node["itemId"] = data.itemId;
|
||||
@@ -210,6 +212,12 @@ std::optional<std::string> RandomizerContext::LoadFromHash(const std::string& ha
|
||||
this->mShopOverrides[key] = itemId;
|
||||
}
|
||||
|
||||
for (const auto& twilitInsectNode : in["mTwilitInsectOverrides"]) {
|
||||
u16 key = twilitInsectNode.first.as<u16>();
|
||||
u16 itemId = twilitInsectNode.second.as<u16>();
|
||||
this->mTwilitInsectOverrides[key] = itemId;
|
||||
}
|
||||
|
||||
// Helper function for getting the item data out of a YAML node
|
||||
auto retrieveItemData = [](auto& itemData, const YAML::Node& node) {
|
||||
itemData.itemId = node["itemId"].as<int>();
|
||||
@@ -1071,6 +1079,18 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) {
|
||||
}
|
||||
}
|
||||
|
||||
// Twilit Insect Overrides
|
||||
// Keyed by u16 of 0xFF00 (stage index) and 0x00FF (flag, which is a tbox id)
|
||||
if (location->HasCategories("Twilit Insect")) {
|
||||
for (const auto& twilitInsectNode : metaData["Twilit Insect"]) {
|
||||
u8 stage = twilitInsectNode["Stage"].as<u8>();
|
||||
u8 tboxId = twilitInsectNode["Flag"].as<u8>();
|
||||
u16 itemId = location->GetCurrentItem()->GetID();
|
||||
u16 key = (stage << 8) | tboxId;
|
||||
randoData.mTwilitInsectOverrides[key] = itemId;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for getting flag values
|
||||
auto getNodeFlags = [](auto& itemData, const YAML::Node& metaData) {
|
||||
if (metaData["Event Flag"]) {
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
std::unordered_map<u16, u8> mSkyCharacterOverrides{};
|
||||
std::unordered_map<u16, u8> mGoldenWolfOverrides{};
|
||||
std::unordered_map<u16, u8> mShopOverrides{};
|
||||
std::unordered_map<u16, u16> mTwilitInsectOverrides{}; // Just used in tracker for now
|
||||
std::unordered_map<u32, itemLocationData> mFlowItemMessageOverrides{};
|
||||
std::unordered_map<std::string, itemLocationData> mItemLocations{};
|
||||
|
||||
@@ -190,6 +191,10 @@ public:
|
||||
int stage{-1};
|
||||
int flag{-1};
|
||||
} mTrackerTempSwitchFlag;
|
||||
struct {
|
||||
int stage{-1};
|
||||
int flag{-1};
|
||||
} mTrackerTempItemFlag;
|
||||
};
|
||||
|
||||
extern RandomizerState g_randomizerState;
|
||||
|
||||
@@ -477,6 +477,17 @@ randomizer::logic::item_pool::ItemPool getSaveItemPool(randomizer::logic::world:
|
||||
break;
|
||||
}
|
||||
|
||||
// Twilight Tears
|
||||
for (int i = 0; i < dComIfGs_getLightDropNum(0); ++i) {
|
||||
pool.push_back(world->GetItem("Faron Twilight Tear", true));
|
||||
}
|
||||
for (int i = 0; i < dComIfGs_getLightDropNum(1); ++i) {
|
||||
pool.push_back(world->GetItem("Eldin Twilight Tear", true));
|
||||
}
|
||||
for (int i = 0; i < dComIfGs_getLightDropNum(2); ++i) {
|
||||
pool.push_back(world->GetItem("Lanayru Twilight Tear", true));
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
@@ -520,6 +531,11 @@ bool isLocationObtained(randomizer::logic::location::Location* location) {
|
||||
auto stageId = getStageSaveId(itemFlagNode["Stage"].as<u8>());
|
||||
return tracker_isStageItem(stageId, flag);
|
||||
}
|
||||
if (auto& twilitInsectNode = locationMeta["Twilit Insect"]) {
|
||||
auto flag = twilitInsectNode[0]["Flag"].as<u8>();
|
||||
auto stageId = getStageSaveId(twilitInsectNode[0]["Stage"].as<u8>());
|
||||
return dComIfGs_isStageTbox(stageId, flag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -545,6 +561,16 @@ int getLocationItem(randomizer::logic::location::Location* location) {
|
||||
auto key = (stage << 8) | flag;
|
||||
return context.mFreestandingItemOverrides[key];
|
||||
}
|
||||
if (auto& bugRewardNode = locationMeta["Bug Reward"]) {
|
||||
u8 bugItemId = bugRewardNode[0]["Item Id"].as<u8>();
|
||||
return context.mBugRewardOverrides[bugItemId];
|
||||
}
|
||||
if (auto& skyCharacterNode = locationMeta["Sky Character"]) {
|
||||
u8 stageIdx = skyCharacterNode[0]["Stage"].as<u8>();
|
||||
u8 roomNo = skyCharacterNode[0]["Room"].as<u8>();
|
||||
u16 key = (stageIdx << 8) | roomNo;
|
||||
return context.mSkyCharacterOverrides[key];
|
||||
}
|
||||
if (auto& wolfNode = locationMeta["Golden Wolf"]) {
|
||||
auto flag = wolfNode[0]["Flag"].as<u16>();
|
||||
return context.mGoldenWolfOverrides[flag];
|
||||
@@ -555,17 +581,12 @@ int getLocationItem(randomizer::logic::location::Location* location) {
|
||||
u16 key = (stage << 8) | originalItem;
|
||||
return context.mShopOverrides[key];
|
||||
}
|
||||
if (auto& skyCharacterNode = locationMeta["Sky Character"]) {
|
||||
u8 stageIdx = skyCharacterNode[0]["Stage"].as<u8>();
|
||||
u8 roomNo = skyCharacterNode[0]["Room"].as<u8>();
|
||||
u16 key = (stageIdx << 8) | roomNo;
|
||||
return context.mSkyCharacterOverrides[key];
|
||||
if (auto& twilitInsectNode = locationMeta["Twilit Insect"]) {
|
||||
auto flag = twilitInsectNode[0]["Flag"].as<u8>();
|
||||
auto stage = twilitInsectNode[0]["Stage"].as<u8>();
|
||||
auto key = (stage << 8) | flag;
|
||||
return context.mTwilitInsectOverrides[key];
|
||||
}
|
||||
if (auto& bugRewardNode = locationMeta["Bug Reward"]) {
|
||||
u8 bugItemId = bugRewardNode[0]["Item Id"].as<u8>();
|
||||
return context.mBugRewardOverrides[bugItemId];
|
||||
}
|
||||
|
||||
if (auto& flwNode = locationMeta["FLW Message"]) {
|
||||
auto group = flwNode[0]["Group"].as<u16>();
|
||||
auto messageId = flwNode[0]["Message Id"].as<u16>();
|
||||
@@ -703,6 +724,11 @@ bool tracker_isStageSwitch(int stage, int flag) {
|
||||
}
|
||||
|
||||
bool tracker_isStageItem(int stage, int flag) {
|
||||
if (g_randomizerState.mTrackerTempItemFlag.flag == flag &&
|
||||
g_randomizerState.mTrackerTempItemFlag.stage == stage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dComIfGp_getStageStagInfo() && stage == dStage_stagInfo_GetSaveTbl(dComIfGp_getStageStagInfo())) {
|
||||
return dComIfGs_isItem(flag, -1);
|
||||
} else {
|
||||
|
||||
@@ -319,126 +319,140 @@
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x1
|
||||
|
||||
- Name: South Faron Woods Twilit Insect in Tunnel 2
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x6
|
||||
|
||||
- Name: Faron Woods Coros House Interior Twilit Insect 1
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 67
|
||||
Flag: 0x9
|
||||
|
||||
- Name: Faron Woods Coros House Interior Twilit Insect 2
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 67
|
||||
Flag: 0x4
|
||||
|
||||
- Name: South Faron Woods Coros House Exterior Twilit Insect
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x0
|
||||
|
||||
- Name: South Faron Woods Twilit Insect Behind Gate 1
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0xB
|
||||
|
||||
- Name: South Faron Woods Twilit Insect Behind Gate 2
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x5
|
||||
|
||||
- Name: Faron Mist Twilit Insect on Wall 1
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x12
|
||||
|
||||
- Name: Faron Mist Twilit Insect on Wall 2
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x11
|
||||
|
||||
- Name: Faron Mist Twilit Insect on Center Stump 1
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0xE
|
||||
|
||||
- Name: Faron Mist Twilit Insect on Center Stump 2
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0xD
|
||||
|
||||
- Name: Faron Mist Twilit Insect on Center Stump 3
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0xC
|
||||
|
||||
- Name: Faron Mist Burrowing Twilit Insect 1
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x17
|
||||
|
||||
- Name: Faron Mist Burrowing Twilit Insect 2
|
||||
Original Item: Faron Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x8
|
||||
|
||||
- Name: North Faron Woods Twilit Insect 1
|
||||
Original Item: Faron Twilight Tear
|
||||
@@ -447,7 +461,9 @@
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x15
|
||||
|
||||
- Name: North Faron Woods Twilit Insect 2
|
||||
Original Item: Faron Twilight Tear
|
||||
@@ -456,7 +472,9 @@
|
||||
- Faron Woods
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 45
|
||||
Flag: 0x14
|
||||
|
||||
- Name: South Faron Warp Portal
|
||||
Original Item: South Faron Portal
|
||||
@@ -713,7 +731,7 @@
|
||||
Metadata:
|
||||
Freestanding Item:
|
||||
- Stage: 56
|
||||
Flag: 0x9F
|
||||
Flag: 0x9E
|
||||
|
||||
- Name: Faron Field Male Beetle
|
||||
Original Item: Male Beetle
|
||||
@@ -725,7 +743,7 @@
|
||||
Metadata:
|
||||
Freestanding Item:
|
||||
- Stage: 56
|
||||
Flag: 0x9E
|
||||
Flag: 0x9F
|
||||
|
||||
- Name: Faron Field Poe
|
||||
Original Item: Poe Soul
|
||||
@@ -900,144 +918,160 @@
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 75
|
||||
Flag: 0x2
|
||||
|
||||
- Name: Sanctuary Basement Twilit Insect 2
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 75
|
||||
Flag: 0x3
|
||||
|
||||
- Name: Sanctuary Basement Twilit Insect 3
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 75
|
||||
Flag: 0xC
|
||||
|
||||
- Name: Kakariko Graveyard Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 48
|
||||
Flag: 0x6
|
||||
|
||||
- Name: Kakariko Malo Mart Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 68
|
||||
Flag: 0x9
|
||||
|
||||
- Name: Kakariko Inn Pipe Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 68
|
||||
Flag: 0x8
|
||||
|
||||
- Name: Kakariko Inn Bedroom Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 68
|
||||
Flag: 0x0
|
||||
|
||||
- Name: Kakariko Bug House Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 68
|
||||
Flag: 0x1
|
||||
|
||||
- Name: Barnes Bomb Shop Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 68
|
||||
Flag: 0x7
|
||||
|
||||
- Name: Kakariko Destroyed Building Twilit Insect 1
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 46
|
||||
Flag: 0x4
|
||||
|
||||
- Name: Kakariko Destroyed Building Twilit Insect 2
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 46
|
||||
Flag: 0x5
|
||||
|
||||
- Name: Kakariko Destroyed Building Twilit Insect 3
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 46
|
||||
Flag: 0xB
|
||||
|
||||
- Name: Kakariko Watchtower Twilit Insect
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 68
|
||||
Flag: 0xA
|
||||
|
||||
- Name: Death Mountain Trail Twilit Insect Near Howling Stone
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 47
|
||||
Flag: 0xF
|
||||
|
||||
- Name: Death Mountain Trail Twilit Insect on Wall
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 47
|
||||
Flag: 0xE
|
||||
|
||||
- Name: Death Mountain Trail Twilit Insect in Hot Spring
|
||||
Original Item: Eldin Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Eldin Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 47
|
||||
Flag: 0x10
|
||||
|
||||
- Name: Kakariko Gorge Warp Portal
|
||||
Original Item: Kakariko Gorge Portal
|
||||
@@ -1895,135 +1929,150 @@
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 53
|
||||
Flag: 0x2C
|
||||
|
||||
- Name: Lake Hylia Twilit Insect Between Bridges
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 52
|
||||
Flag: 0x2F
|
||||
|
||||
- Name: Lake Hylia Burrowing Twilit Insect
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 52
|
||||
Flag: 0x30
|
||||
|
||||
- Name: Lake Hylia Twilit Insect Behind Canon
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 52
|
||||
Flag: 0x32
|
||||
|
||||
- Name: Lake Hylia Twilit Insect on Docks
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 52
|
||||
Flag: 0x31
|
||||
|
||||
- Name: Lake Hylia Twilit Bloat
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 52
|
||||
Flag: 0x35
|
||||
|
||||
- Name: Zoras River Twilit Insect 1
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 49
|
||||
Flag: 0x3D
|
||||
|
||||
- Name: Zoras River Twilit Insect 2
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 49
|
||||
Flag: 0x36
|
||||
|
||||
- Name: Zoras River Twilit Insect 3
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 49
|
||||
Flag: 0x3A
|
||||
|
||||
- Name: Zoras River Twilit Insect 4
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 49
|
||||
Flag: 0x39
|
||||
|
||||
- Name: Upper Zoras River Twilit Insect
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 61
|
||||
Flag: 0x37
|
||||
|
||||
- Name: Zoras Domain Twilit Insect near Lilypads 1
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 50
|
||||
Flag: 0x3B
|
||||
|
||||
- Name: Zoras Domain Twilit Insect near Lilypads 2
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 50
|
||||
Flag: 0x2E
|
||||
|
||||
- Name: Zoras Domain Burrowing Twilit Insect
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 50
|
||||
Flag: 0x2D
|
||||
|
||||
- Name: Zoras Domain Twilit Insect on West Ledge
|
||||
Original Item: Lanayru Twilight Tear
|
||||
Categories:
|
||||
- Overworld
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 50
|
||||
Flag: 0x3C
|
||||
|
||||
- Name: Zoras Domain Throne Room Twilit Insect
|
||||
Original Item: Lanayru Twilight Tear
|
||||
@@ -2032,7 +2081,9 @@
|
||||
- Lanayru Province
|
||||
- Twilit Insect
|
||||
Metadata:
|
||||
- None
|
||||
Twilit Insect:
|
||||
- Stage: 50
|
||||
Flag: 0x3E
|
||||
|
||||
- Name: Lanayru Field Behind Gate Underwater Chest
|
||||
Original Item: Orange Rupee
|
||||
|
||||
@@ -1107,7 +1107,7 @@ namespace randomizer::logic::world
|
||||
return this->_itemTable.at(name).get();
|
||||
}
|
||||
|
||||
item::Item* World::GetItem(uint8_t id, const bool& ignoreError /*= false*/) {
|
||||
item::Item* World::GetItem(uint16_t id, const bool& ignoreError /*= false*/) {
|
||||
if (!this->_itemIdTable.contains(id))
|
||||
{
|
||||
if (!ignoreError)
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace randomizer::logic::world
|
||||
dungeon::Dungeon* GetDungeon(const std::string& name);
|
||||
const std::map<std::string, std::unique_ptr<dungeon::Dungeon>>& GetDungeonTable() const;
|
||||
item::Item* GetItem(const std::string& name, const bool& ignoreError = false);
|
||||
item::Item* GetItem(uint8_t id, const bool& ignoreError = false);
|
||||
item::Item* GetItem(uint16_t id, const bool& ignoreError = false);
|
||||
item::Item* GetShadowCrystal();
|
||||
item::Item* GetGameWinningItem() const;
|
||||
item_pool::ItemPool& GetItemPool();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace randomizer::seedgen::seed
|
||||
{
|
||||
static constexpr std::array nouns = {
|
||||
static constexpr const char* nouns[] = {
|
||||
"Aeralfos", "Agitha", "Ant", "Argorok", "Armos", "Ashei", "Auru", "BackSlice", "Bari",
|
||||
"Barnes", "Beamos", "Beth", "BigBaba", "Blizzeta", "Bo", "Bokoblin", "Bombfish", "Borville",
|
||||
"Bulblin", "Butterfly", "CastleTown", "Charlo", "Cheese", "Chilfos", "Chu", "Chudley", "Clawshot",
|
||||
@@ -21,9 +21,10 @@ namespace randomizer::seedgen::seed
|
||||
"Rutela", "Sage", "Sera", "Shad", "ShellBlade", "Sketch", "SkullKid", "Skulltula", "SkyBook",
|
||||
"Snail", "Snowpeak", "Soal", "Soldier", "Spinner", "Stalfos", "Stallord", "Talo", "Tektite",
|
||||
"Telma", "Temple", "TileWorm", "Toadpoli", "Trill", "Twilight", "Uli", "WolfLink", "Zant",
|
||||
"Zelda", "Zora"};
|
||||
"Zelda", "Zora"
|
||||
};
|
||||
|
||||
static constexpr std::array adjectives = {
|
||||
static constexpr const char* adjectives[] = {
|
||||
"Abnormal", "Absent", "Absolute", "Abstract", "Absurd", "Accurate", "Active", "Actual",
|
||||
"Adjacent", "Aesthetic", "Aggressive", "Alert", "Alien", "Alternate", "Amazing", "Ambitious",
|
||||
"Amusing", "Ancient", "Angry", "Anxious", "Apparent", "Artistic", "Astute", "Atomic",
|
||||
@@ -87,7 +88,8 @@ namespace randomizer::seedgen::seed
|
||||
"Unlikely", "Unreal", "Upbeat", "Upset", "Urban", "Useful", "Usual", "Vague",
|
||||
"Valid", "Verbal", "Vertical", "Vicious", "Vigorous", "Villainous", "Virtual", "Visible",
|
||||
"Vital", "Vivid", "Warm", "Weekly", "Weird", "Wholesome", "Wicked", "Wise",
|
||||
"Wistful", "Witty", "Wonderful", "Wooden", "Worried", "Wrong", "Young", "Zany"};
|
||||
"Wistful", "Witty", "Wonderful", "Wooden", "Worried", "Wrong", "Young", "Zany"
|
||||
};
|
||||
|
||||
int GetRandValue(int min, int max) {
|
||||
std::uniform_int_distribution<int> distribution(min, max);
|
||||
@@ -98,9 +100,9 @@ namespace randomizer::seedgen::seed
|
||||
|
||||
std::string GenerateSeed()
|
||||
{
|
||||
const std::string adjective1 = adjectives[GetRandValue(0, adjectives.size() - 1)];
|
||||
const std::string adjective2 = adjectives[GetRandValue(0, adjectives.size() - 1)];
|
||||
const std::string noun = nouns[GetRandValue(0, nouns.size() - 1)];
|
||||
const std::string adjective1 = adjectives[GetRandValue(0, std::size(adjectives) - 1)];
|
||||
const std::string adjective2 = adjectives[GetRandValue(0, std::size(adjectives) - 1)];
|
||||
const std::string noun = nouns[GetRandValue(0, std::size(nouns) - 1)];
|
||||
|
||||
return adjective1 + adjective2 + noun;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#include "../utility/log.hpp"
|
||||
#include "../utility/path.hpp"
|
||||
#include "../utility/platform.hpp"
|
||||
#ifdef DEVKITPRO
|
||||
#include "../utility/thread_local.hpp"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
@@ -31,6 +33,7 @@ namespace randomizer::utility::file
|
||||
return false;
|
||||
};
|
||||
|
||||
#ifdef DEVKITPRO
|
||||
static constexpr int FILE_BUF_SIZE = 25 * 1024 * 1024;
|
||||
class AlignedBufferWrapper
|
||||
{
|
||||
@@ -41,6 +44,7 @@ namespace randomizer::utility::file
|
||||
char* getBuffer() { return buffer; }
|
||||
};
|
||||
static ThreadLocal<AlignedBufferWrapper, DataIDs::FILE_OP_BUFFER> buf;
|
||||
#endif
|
||||
|
||||
bool copy_file(const fspath& from, const fspath& to)
|
||||
{
|
||||
@@ -189,11 +193,15 @@ namespace randomizer::utility::file
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEVKITPRO
|
||||
while (file)
|
||||
{
|
||||
file.read(buf.get().getBuffer(), FILE_BUF_SIZE);
|
||||
fileContents.write(buf.get().getBuffer(), file.gcount());
|
||||
}
|
||||
#else
|
||||
fileContents << file.rdbuf();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "modal.hpp"
|
||||
#include "number_button.hpp"
|
||||
#include "pane.hpp"
|
||||
#include "rando_seed_generation.hpp"
|
||||
#include "string_button.hpp"
|
||||
|
||||
namespace dusk::ui {
|
||||
@@ -24,18 +25,7 @@ struct ConfigBoolProps {
|
||||
std::function<bool()> isDisabled;
|
||||
};
|
||||
|
||||
static std::atomic seedGenStatus = SeedGenerateStatus::Ready;
|
||||
static std::string generationStatusMsg{};
|
||||
|
||||
static void StartSeedGeneration() {
|
||||
if (GenerateAndWriteSeed(generationStatusMsg)) {
|
||||
seedGenStatus.store(SeedGenerateStatus::Success);
|
||||
} else {
|
||||
seedGenStatus.store(SeedGenerateStatus::Error);
|
||||
}
|
||||
|
||||
DuskLog.debug("{}", generationStatusMsg);
|
||||
}
|
||||
|
||||
randomizer::seedgen::settings::Setting* FindSetting(const std::string& key) {
|
||||
if (key.empty()) {
|
||||
@@ -410,27 +400,6 @@ void rando_starting_item_number_toggle(Pane& leftPane, Pane& rightPane, std::str
|
||||
});
|
||||
}
|
||||
|
||||
Modal* RandomizerWindow::show_seed_gen_modal(std::string_view message) {
|
||||
auto* modal = dynamic_cast<Modal*>(&push_document(std::make_unique<Modal>(Modal::Props{
|
||||
.title = "Randomizer",
|
||||
.bodyRml = escape(message),
|
||||
.onDismiss = [this](Modal& modal) {
|
||||
mDoAud_seStartMenu(kSoundWindowClose);
|
||||
modal.pop();
|
||||
m_genSeedModal = nullptr;
|
||||
},
|
||||
.icon = "verifying",
|
||||
})));
|
||||
// Allow manual line breaks in this modal for error messages
|
||||
modal->root()->SetProperty("white-space", "pre-line");
|
||||
|
||||
if (auto* doc = top_document()) {
|
||||
doc->focus();
|
||||
}
|
||||
|
||||
return modal;
|
||||
}
|
||||
|
||||
struct ExcludedTabLocData {
|
||||
std::string name {};
|
||||
std::string lowercaseName{};
|
||||
@@ -822,11 +791,7 @@ RandomizerWindow::RandomizerWindow() {
|
||||
DuskLog.info("Created new Seed for generator.");
|
||||
}
|
||||
|
||||
seedGenStatus.store(SeedGenerateStatus::Generating);
|
||||
std::thread randoGenerationThread(StartSeedGeneration);
|
||||
randoGenerationThread.detach();
|
||||
|
||||
m_genSeedModal = show_seed_gen_modal("Generating Seed...");
|
||||
GenerateRandomizerSeed();
|
||||
|
||||
}),rightPane, [](Pane& pane) {
|
||||
pane.clear();
|
||||
@@ -1176,36 +1141,6 @@ RandomizerWindow::RandomizerWindow() {
|
||||
}
|
||||
}
|
||||
|
||||
void RandomizerWindow::update() {
|
||||
Window::update();
|
||||
|
||||
auto curSeedGenStatus = seedGenStatus.load();
|
||||
if (curSeedGenStatus == SeedGenerateStatus::Success ||
|
||||
curSeedGenStatus == SeedGenerateStatus::Error)
|
||||
{
|
||||
if (curSeedGenStatus == SeedGenerateStatus::Success) {
|
||||
mDoAud_seStartMenu(kSoundSeedGenerateSuccess);
|
||||
m_genSeedModal->set_icon("celebration");
|
||||
} else {
|
||||
mDoAud_seStartMenu(kSoundSeedGenerateError);
|
||||
m_genSeedModal->set_icon("error");
|
||||
}
|
||||
|
||||
m_genSeedModal->set_body(escape(generationStatusMsg));
|
||||
m_genSeedModal->add_action({
|
||||
.label = "OK",
|
||||
.onPressed = [this](Modal& modal) {
|
||||
mDoAud_seStartMenu(kSoundWindowClose);
|
||||
modal.pop();
|
||||
m_genSeedModal = nullptr;
|
||||
}
|
||||
});
|
||||
m_genSeedModal->focus();
|
||||
|
||||
seedGenStatus.store(SeedGenerateStatus::Ready);
|
||||
}
|
||||
}
|
||||
|
||||
std::filesystem::path GetRandomizerPath() {
|
||||
return data::configured_data_path() / "randomizer";
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace randomizer::seedgen::config {
|
||||
}
|
||||
|
||||
namespace dusk::ui {
|
||||
class Modal;
|
||||
class Pane;
|
||||
|
||||
std::filesystem::path GetRandomizerPath();
|
||||
@@ -16,24 +15,14 @@ class Pane;
|
||||
std::filesystem::path GetRandomizerSeedsPath();
|
||||
randomizer::seedgen::config::Config& GetRandomizerConfig();
|
||||
|
||||
enum class SeedGenerateStatus {
|
||||
Ready,
|
||||
Generating,
|
||||
Success,
|
||||
Error,
|
||||
};
|
||||
|
||||
class RandomizerWindow : public Window {
|
||||
public:
|
||||
|
||||
|
||||
RandomizerWindow();
|
||||
void update() override;
|
||||
Modal* show_seed_gen_modal(std::string_view message);
|
||||
void rando_excluded_locations_update_left_pane(Pane& innerLeftPane, Pane& rightPane, bool forceUpdate = false);
|
||||
auto& get_locations_for_left_pane();
|
||||
private:
|
||||
Modal* m_genSeedModal = nullptr;
|
||||
std::string m_excludedLocationsFilter{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "rando_seed_generation.hpp"
|
||||
|
||||
#include "modal.hpp"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/randomizer/game/randomizer_context.hpp"
|
||||
#include "m_Do/m_Do_audio.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
enum class SeedGenerateStatus {
|
||||
Ready,
|
||||
Generating,
|
||||
Success,
|
||||
Error,
|
||||
};
|
||||
|
||||
static std::atomic seedGenStatus = SeedGenerateStatus::Ready;
|
||||
static std::string generationStatusMsg{};
|
||||
|
||||
RandomizerGenerationModal::RandomizerGenerationModal() :
|
||||
Modal({
|
||||
.title = "Randomizer",
|
||||
.bodyRml = "Generating Seed...",
|
||||
.onDismiss = [this](Modal& modal) {
|
||||
mDoAud_seStartMenu(kSoundWindowClose);
|
||||
modal.pop();
|
||||
},
|
||||
.icon = "verifying",
|
||||
}) {
|
||||
mRoot->SetProperty("white-space", "pre-line");
|
||||
}
|
||||
|
||||
void RandomizerGenerationModal::update() {
|
||||
Document::update();
|
||||
|
||||
auto curSeedGenStatus = seedGenStatus.load();
|
||||
|
||||
// Change the modal text if we've finished attempting to generate
|
||||
if (curSeedGenStatus == SeedGenerateStatus::Success ||
|
||||
curSeedGenStatus == SeedGenerateStatus::Error)
|
||||
{
|
||||
if (curSeedGenStatus == SeedGenerateStatus::Success) {
|
||||
mDoAud_seStartMenu(kSoundSeedGenerateSuccess);
|
||||
set_icon("celebration");
|
||||
} else {
|
||||
mDoAud_seStartMenu(kSoundSeedGenerateError);
|
||||
set_icon("error");
|
||||
}
|
||||
|
||||
set_body(escape(generationStatusMsg));
|
||||
add_action({
|
||||
.label = "OK",
|
||||
.onPressed = [this](Modal& modal) {
|
||||
mDoAud_seStartMenu(kSoundWindowClose);
|
||||
modal.pop();
|
||||
}
|
||||
});
|
||||
|
||||
// Refocus so that we focus the new button
|
||||
focus();
|
||||
|
||||
seedGenStatus.store(SeedGenerateStatus::Ready);
|
||||
}
|
||||
}
|
||||
|
||||
static void StartSeedGeneration() {
|
||||
if (GenerateAndWriteSeed(generationStatusMsg)) {
|
||||
seedGenStatus.store(SeedGenerateStatus::Success);
|
||||
} else {
|
||||
seedGenStatus.store(SeedGenerateStatus::Error);
|
||||
}
|
||||
|
||||
DuskLog.debug("{}", generationStatusMsg);
|
||||
}
|
||||
|
||||
void GenerateRandomizerSeed() {
|
||||
// Start Generation Thread
|
||||
seedGenStatus.store(SeedGenerateStatus::Generating);
|
||||
std::thread randoGenerationThread(StartSeedGeneration);
|
||||
randoGenerationThread.detach();
|
||||
|
||||
// Create Seed Generation Modal
|
||||
push_document(std::make_unique<RandomizerGenerationModal>());
|
||||
|
||||
// Focus Modal
|
||||
if (auto* doc = top_document()) {
|
||||
doc->focus();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "modal.hpp"
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
class RandomizerGenerationModal : public Modal {
|
||||
public:
|
||||
explicit RandomizerGenerationModal();
|
||||
|
||||
void update() override;
|
||||
};
|
||||
|
||||
void GenerateRandomizerSeed();
|
||||
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user