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

This commit is contained in:
gymnast86
2026-04-14 15:27:08 -07:00
19 changed files with 272 additions and 133 deletions
+11
View File
@@ -18,6 +18,11 @@
#include "JSystem/J2DGraph/J2DTextBox.h"
#include "m_Do/m_Do_graphic.h"
#ifdef TARGET_PC
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#endif
class daTit_HIO_c : public JORReflexible {
public:
daTit_HIO_c();
@@ -343,6 +348,12 @@ void daTitle_c::fastLogoDispInit() {
field_0x604 = 0;
mWaitTimer = 30;
mProcID = 5;
#ifdef TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
dusk::frame_interp::request_presentation_sync();
}
#endif
}
void daTitle_c::fastLogoDisp() {
+19 -12
View File
@@ -1,28 +1,29 @@
#include "d/dolzel.h" // IWYU pragma: keep
#include <cstdio>
#include "JSystem/J2DGraph/J2DAnimation.h"
#include "JSystem/J2DGraph/J2DGrafContext.h"
#include "JSystem/J2DGraph/J2DScreen.h"
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "SSystem/SComponent/c_bg_s_shdw_draw.h"
#include "SSystem/SComponent/c_math.h"
#include "d/d_com_inf_game.h"
#include "d/d_drawlist.h"
#include <typeindex>
#include "absl/container/flat_hash_map.h"
#include "client/TracyScoped.hpp"
#include "d/d_s_play.h"
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#include "m_Do/m_Do_graphic.h"
#include "m_Do/m_Do_lib.h"
#include "m_Do/m_Do_mtx.h"
#if TARGET_PC
#include <cstdio>
#include <typeindex>
#include "JSystem/JKernel/JKRHeap.h"
#include "absl/container/flat_hash_map.h"
#include "client/TracyScoped.hpp"
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#endif
class dDlst_2Dm_c {
public:
virtual void draw();
@@ -1432,8 +1433,14 @@ void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* pa
mDoMtx_stack_c::scaleM(param_2, 1.0f, param_2 * param_5);
cMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(), mMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mVolumeMtx, mVolumeMtx);
dusk::frame_interp::record_final_mtx_raw(&mMtx, mMtx);
const uint64_t shadow_tag_base = dusk::frame_interp::alloc_simple_shadow_pair_base();
if (shadow_tag_base != 0) {
dusk::frame_interp::record_final_mtx_raw_tagged(&mVolumeMtx, mVolumeMtx, shadow_tag_base);
dusk::frame_interp::record_final_mtx_raw_tagged(&mMtx, mMtx, shadow_tag_base + 1u);
} else {
dusk::frame_interp::record_final_mtx_raw(&mVolumeMtx, mVolumeMtx);
dusk::frame_interp::record_final_mtx_raw(&mMtx, mMtx);
}
#endif
mpTexObj = param_6;
}
+24 -1
View File
@@ -19,6 +19,10 @@
#include "JSystem/J2DGraph/J2DScreen.h"
#include "Z2AudioLib/Z2WolfHowlMgr.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
// POSIX already defines a macro with this name, but we know that this specific name is
// used in TP based on assertion messages. This redefinition is scoped to this TU which
// is unlikely to ever actually need the POSIX define, so we can just redefine it.
@@ -307,6 +311,17 @@ void dMsgScrnHowl_c::exec() {
mpButtonIcon[1]->setAlphaRate(field_0x1994 * alphaRate);
mpButtonText[0]->setAlphaRate(field_0x1998 * alphaRate);
mpButtonText[1]->setAlphaRate(field_0x1998 * alphaRate);
#if TARGET_PC
showCursor = true;
if (field_0x2798 == 0) {
if (mPlotTime != field_0x212c) {
field_0x212c = mPlotTime;
} else {
showCursor = false;
}
}
#endif
}
void dMsgScrnHowl_c::drawSelf() {
@@ -490,6 +505,7 @@ void dMsgScrnHowl_c::drawWave() {
grafContext->setScissor();
#endif
#if !TARGET_PC
bool bVar5 = true;
if (field_0x2798 == 0) {
if (mPlotTime != field_0x212c) {
@@ -498,7 +514,14 @@ void dMsgScrnHowl_c::drawWave() {
bVar5 = false;
}
}
if (bVar5) {
#endif
#if TARGET_PC
if (showCursor)
#else
if (bVar5)
#endif
{
for (int iVar10 = 0; iVar10 < field_0x2128 - 1; iVar10++) {
f32 local_54 = local_e0;
f32 local_c8 = field_0x180[sVar14];
+28 -10
View File
@@ -23,6 +23,10 @@
#include "m_Do/m_Do_lib.h"
#include <cstring>
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
static int dTimer_createStart2D(s32 param_0, u16 param_1);
int dTimer_c::_create() {
@@ -1336,29 +1340,44 @@ void dDlst_TimerScrnDraw_c::draw() {
f32 temp = (f32)g_drawHIO.mMiniGame.mGetInTextAlphaFrames +
((f32)g_drawHIO.mMiniGame.mGetInTextWaitFrames + 60.0f);
#if TARGET_PC
const u32 pending_ui_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
#else
const u32 pending_ui_ticks = 1u;
#endif
for (int i = 0; i < 51; i++) {
if (m_getin_info[i].bck_frame > 0.0f && m_getin_info[i].bck_frame < temp) {
f32 var_f29 = 1.0f;
for (u32 tick = 0; tick < pending_ui_ticks; tick++) {
if (!(m_getin_info[i].bck_frame > 0.0f && m_getin_info[i].bck_frame < temp)) {
break;
}
if (m_getin_info[i].bck_frame < 60.0f) {
m_getin_info[i].bck_frame += g_drawHIO.mMiniGame.mGetInTextAnimSpeed;
if (m_getin_info[i].bck_frame > 60.0f) {
m_getin_info[i].bck_frame = 60.0f;
}
playBckAnimation(m_getin_info[i].bck_frame);
} else if (m_getin_info[i].bck_frame < g_drawHIO.mMiniGame.mGetInTextWaitFrames + 60.0f)
{
} else if (m_getin_info[i].bck_frame < g_drawHIO.mMiniGame.mGetInTextWaitFrames + 60.0f) {
m_getin_info[i].bck_frame++;
playBckAnimation(60.0f);
} else if (m_getin_info[i].bck_frame < temp) {
m_getin_info[i].bck_frame++;
playBckAnimation(60.0f);
}
}
if (m_getin_info[i].bck_frame > 0.0f && m_getin_info[i].bck_frame < temp) {
f32 var_f29 = 1.0f;
if (m_getin_info[i].bck_frame >= g_drawHIO.mMiniGame.mGetInTextWaitFrames + 60.0f &&
m_getin_info[i].bck_frame < temp) {
var_f29 = acc(g_drawHIO.mMiniGame.mGetInTextAlphaFrames,
temp - m_getin_info[i].bck_frame, 0);
}
if (m_getin_info[i].bck_frame < 60.0f) {
playBckAnimation(m_getin_info[i].bck_frame);
} else {
playBckAnimation(60.0f);
}
mpGetInParent->setAlphaRate(var_f29);
if (g_drawHIO.mMiniGame.mGetInTextLocation == 1) {
@@ -1388,8 +1407,7 @@ void dDlst_TimerScrnDraw_c::draw() {
m_getin_info[i].pikari_frame =
18.0f - g_drawHIO.mMiniGame.mGetInPikariAnimSpeed;
}
} else if (m_getin_info[i].bck_frame > g_drawHIO.mMiniGame.mStartPikariAppearFrames)
{
} else if (m_getin_info[i].bck_frame > g_drawHIO.mMiniGame.mStartPikariAppearFrames) {
m_getin_info[i].pikari_frame =
18.0f - g_drawHIO.mMiniGame.mStartPikariAnimSpeed;
}
+57 -14
View File
@@ -28,6 +28,7 @@ struct Data {
size_t child_index = 0;
Mtx matrix{};
const Mtx* dest = nullptr;
uint64_t stable_tag = 0;
};
struct Path;
@@ -46,6 +47,8 @@ struct Path {
std::vector<ChildBucket> children;
std::vector<OpBucket> ops;
std::vector<std::pair<Op, size_t>> items;
Label draw_scope{};
uint32_t simple_shadow_pair_seq = 0;
};
struct Recording {
@@ -57,6 +60,7 @@ struct MatrixValue {
};
using FinalMtxLookup = std::unordered_map<const Mtx*, const Data*>;
using FinalMtxLookupTagged = std::unordered_map<uint64_t, const Data*>;
bool s_initialized = false;
@@ -65,7 +69,6 @@ bool g_recording = false;
bool g_interpolating = false;
bool g_sync_presentation = false;
uint32_t g_presentation_counter = 0;
uint32_t g_presentation_sync_end = 0;
float g_step = 0.0f;
uint32_t g_pending_presentation_ui_ticks = 0;
@@ -143,8 +146,9 @@ const OpBucket* find_op_bucket(const Path& path, Op op) {
return &*it;
}
void build_final_mtx_lookup(const Path& path, FinalMtxLookup& lookup) {
lookup.clear();
void build_final_mtx_lookups(const Path& path, FinalMtxLookup& dest_lookup, FinalMtxLookupTagged& tag_lookup) {
dest_lookup.clear();
tag_lookup.clear();
const OpBucket* bucket = find_op_bucket(path, Op::FinalMtx);
if (bucket == nullptr) {
@@ -152,10 +156,12 @@ void build_final_mtx_lookup(const Path& path, FinalMtxLookup& lookup) {
}
for (const Data& data : bucket->values) {
if (data.dest == nullptr) {
continue;
if (data.dest != nullptr) {
dest_lookup[data.dest] = &data;
}
if (data.stable_tag != 0) {
tag_lookup[data.stable_tag] = &data;
}
lookup[data.dest] = &data;
}
}
@@ -202,7 +208,8 @@ void store_replacement(const Data& old_data, const Data& new_data, float step) {
void interpolate_branch(const Path& old_path, const Path& new_path, float step) {
FinalMtxLookup old_final_mtx_lookup;
build_final_mtx_lookup(old_path, old_final_mtx_lookup);
FinalMtxLookupTagged old_final_mtx_lookup_tagged;
build_final_mtx_lookups(old_path, old_final_mtx_lookup, old_final_mtx_lookup_tagged);
for (const auto& item : new_path.items) {
const Op op = item.first;
@@ -231,7 +238,17 @@ void interpolate_branch(const Path& old_path, const Path& new_path, float step)
}
const Data* indexed_old_data = find_matching_data(old_path, op, index);
const Data* old_data = op == Op::FinalMtx ? find_matching_final_mtx(old_final_mtx_lookup, *new_data) : indexed_old_data;
const Data* old_data = nullptr;
if (op == Op::FinalMtx) {
if (new_data->stable_tag != 0) {
const auto it = old_final_mtx_lookup_tagged.find(new_data->stable_tag);
old_data = it != old_final_mtx_lookup_tagged.end() ? it->second : nullptr;
} else {
old_data = find_matching_final_mtx(old_final_mtx_lookup, *new_data);
}
} else {
old_data = indexed_old_data;
}
if (op == Op::FinalMtx) {
store_replacement(old_data != nullptr ? *old_data : *new_data, *new_data, step);
}
@@ -280,10 +297,7 @@ void begin_record() {
return;
}
if (g_sync_presentation && g_presentation_counter > g_presentation_sync_end) {
g_sync_presentation = false;
}
g_sync_presentation = false;
g_previous_recording = std::move(g_current_recording);
g_current_recording = {};
g_current_path.clear();
@@ -320,7 +334,6 @@ void request_presentation_sync() {
return;
}
g_sync_presentation = true;
g_presentation_sync_end = g_presentation_counter + 1;
}
bool presentation_sync_active() {
@@ -375,7 +388,9 @@ void open_child(const void* key, int32_t id) {
data.child_label = label;
data.child_index = siblings.size();
siblings.emplace_back(std::make_unique<Path>());
g_current_path.push_back(siblings.back().get());
Path* const child = siblings.back().get();
child->draw_scope = label;
g_current_path.push_back(child);
}
void close_child() {
@@ -393,6 +408,18 @@ void record_final_mtx_raw(const Mtx* dest, const Mtx src) {
Data& data = append_op(Op::FinalMtx);
data.dest = dest;
data.stable_tag = 0;
copy_matrix(src, data.matrix);
}
void record_final_mtx_raw_tagged(const Mtx* dest, const Mtx src, uint64_t stable_tag) {
if (!s_initialized || !g_recording || dest == nullptr) {
return;
}
Data& data = append_op(Op::FinalMtx);
data.dest = dest;
data.stable_tag = stable_tag;
copy_matrix(src, data.matrix);
}
@@ -506,4 +533,20 @@ bool build_star_view(Mtx o_view, Mtx o_cam_billboard_base, cXyz* o_anchor_eye, f
*o_fovy = s_star_prev.fovy + (s_star_curr.fovy - s_star_prev.fovy) * step;
return true;
}
uint64_t alloc_simple_shadow_pair_base() {
if (!s_initialized || !g_recording || g_current_path.size() <= 1) {
return 0;
}
Path* const scope = g_current_path.back();
const uint64_t h = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(scope->draw_scope.key));
const uint32_t lo = scope->simple_shadow_pair_seq;
scope->simple_shadow_pair_seq += 2;
uint64_t tag0 = (h << 17) ^ (static_cast<uint64_t>(lo) << 1u);
if (tag0 == 0) {
tag0 = 2;
}
return tag0;
}
} // namespace dusk::frame_interp
+4 -3
View File
@@ -209,7 +209,7 @@ static void ShowAllJAISeqs() {
}
void dusk::ImGuiMenuTools::ShowAudioDebug() {
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F7, m_showAudioDebug)) {
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F10, m_showAudioDebug)) {
return;
}
@@ -255,7 +255,8 @@ void dusk::ImGuiMenuTools::ShowAudioDebug() {
}
void dusk::ImGuiMenuTools::ShowSaveEditor() {
if (m_showSaveEditor) {
m_saveEditor.draw(m_showSaveEditor);
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F6, m_showSaveEditor)) {
return;
}
m_saveEditor.draw(m_showSaveEditor);
}
+1 -1
View File
@@ -7,7 +7,7 @@
namespace dusk {
void ImGuiMenuTools::ShowCameraOverlay() {
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F6, m_showCameraOverlay)) {
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F9, m_showCameraOverlay)) {
return;
}
+1 -1
View File
@@ -9,7 +9,7 @@
namespace dusk {
void ImGuiMenuTools::ShowMapLoader() {
if (!m_showMapLoader) {
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F7, m_showMapLoader)) {
return;
}
+7 -6
View File
@@ -48,13 +48,14 @@ namespace dusk {
ImGui::MenuItem("Process Management", hotkeys::SHOW_PROCESS_MANAGEMENT, &m_showProcessManagement);
ImGui::MenuItem("Debug Overlay", hotkeys::SHOW_DEBUG_OVERLAY, &m_showDebugOverlay);
ImGui::MenuItem("Heap Viewer", hotkeys::SHOW_HEAP_VIEWER, &m_showHeapOverlay);
ImGui::MenuItem("Stub Log", hotkeys::SHOW_STUB_LOG, &m_showStubLog);
ImGui::MenuItem("Debug Camera", hotkeys::SHOW_CAMERA_DEBUG, &m_showCameraOverlay);
ImGui::MenuItem("Map Loader", nullptr, &m_showMapLoader);
ImGui::MenuItem("Player Info", nullptr, &m_showPlayerInfo);
ImGui::MenuItem("Save Editor", nullptr, &m_showSaveEditor);
ImGui::MenuItem("Player Info", hotkeys::SHOW_PLAYER_INFO, &m_showPlayerInfo);
ImGui::MenuItem("Save Editor", hotkeys::SHOW_SAVE_EDITOR, &m_showSaveEditor);
ImGui::MenuItem("Map Loader", hotkeys::SHOW_MAP_LOADER, &m_showMapLoader);
ImGui::MenuItem("State Share", hotkeys::SHOW_STATE_SHARE, &m_showStateShare);
ImGui::MenuItem("Debug Camera", hotkeys::SHOW_DEBUG_CAMERA, &m_showCameraOverlay);
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog);
if (!dusk::IsGameLaunched) {
ImGui::EndDisabled();
@@ -128,7 +129,7 @@ namespace dusk {
}
void ImGuiMenuTools::ShowPlayerInfo() {
if (!m_showPlayerInfo) {
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F5, m_showPlayerInfo)) {
return;
}
+1 -2
View File
@@ -3,7 +3,6 @@
#include "dusk/logging.h"
#include "imgui.h"
#include "ImGuiConsole.hpp"
#include "ImGuiMenuTools.hpp"
namespace dusk {
@@ -49,7 +48,7 @@ namespace dusk {
void ImGuiMenuTools::ShowStubLog() {
std::lock_guard lock(StubLogMutex);
if (!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F5, m_showStubLog)) {
if (!m_showStubLog) {
return;
}
+17 -18
View File
@@ -28,10 +28,6 @@
#include "d/d_menu_collect.h"
#include "d/d_meter2_info.h"
#include "d/d_s_play.h"
#include "dusk/endian.h"
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#include "f_ap/f_ap_game.h"
#include "f_op/f_op_actor_mng.h"
#include "f_op/f_op_camera_mng.h"
@@ -52,8 +48,12 @@
#if TARGET_PC
#include "d/actor/d_a_horse.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/dusk.h"
#include "dusk/endian.h"
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/logging.h"
#endif
class mDoGph_HIO_c : public JORReflexible {
@@ -1989,12 +1989,13 @@ static void captureScreenPerspDrawInfo(JPADrawInfo& info) {
static void drawItem3D() {
ZoneScoped;
#ifdef TARGET_PC
// Frame interpolation: Title screen needs 0.0f while everything else that runs through this is -100.0f.
// Running presentation faster than logic revealed the problem. Thanks, Nintendo.
if (fopAcM_SearchByName(fpcNm_TITLE_e) != nullptr) {
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
} else {
dMenu_Collect3D_c::setViewPortOffsetY(-100.0f);
if (dusk::getSettings().game.enableFrameInterpolation) {
// FRAME INTERP NOTE: Title screen needs 0.0f while everything else that runs through this is -100.0f.
if (fopAcM_SearchByName(fpcNm_TITLE_e) != nullptr) {
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
} else {
dMenu_Collect3D_c::setViewPortOffsetY(-100.0f);
}
}
#endif
Mtx item_mtx;
@@ -2033,12 +2034,11 @@ int mDoGph_Painter() {
#endif
#ifdef TARGET_PC
for (u32 i = 0; i < pending_ui_ticks; ++i) {
for (u32 i = 0; i < pending_ui_ticks; ++i)
#endif
{
dComIfGp_particle_calcMenu();
#ifdef TARGET_PC
}
#endif
JFWDisplay::getManager()->setFader(mDoGph_gInf_c::getFader());
mDoGph_gInf_c::setClearColor(mDoGph_gInf_c::getBackColor());
@@ -2598,13 +2598,12 @@ int mDoGph_Painter() {
#endif
GXSetClipMode(GX_CLIP_ENABLE);
#ifdef TARGET_PC
for (u32 i = 0; i < pending_ui_ticks; ++i) {
#if TARGET_PC
for (u32 i = 0; i < pending_ui_ticks; ++i)
#endif
{
dDlst_list_c::calcWipe();
#ifdef TARGET_PC
}
#endif
j3dSys.reinitGX();
ortho.setOrtho(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(),