mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-23 14:41:33 -04:00
Frame interp: Initial presentation sync implementation
This commit is contained in:
@@ -20,6 +20,11 @@ void begin_record();
|
||||
void end_record();
|
||||
void interpolate(float step);
|
||||
float get_interpolation_step();
|
||||
|
||||
void notify_presentation_frame();
|
||||
void request_presentation_sync();
|
||||
bool presentation_sync_active();
|
||||
|
||||
void notify_sim_tick_complete();
|
||||
uint32_t begin_presentation_ui_pass();
|
||||
uint32_t get_presentation_ui_advance_ticks();
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
#include "JSystem/JStudio/JStudio/jstudio-object.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/audio.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
namespace JStudio {
|
||||
namespace {
|
||||
@@ -650,10 +654,25 @@ value_or_fun:
|
||||
return;
|
||||
|
||||
value:
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation && u <= 5 &&
|
||||
(operation == data::UNK_0x2 || operation == data::UNK_0x3 || operation == data::UNK_0x12))
|
||||
{
|
||||
dusk::frame_interp::request_presentation_sync();
|
||||
}
|
||||
#endif
|
||||
adaptor->adaptor_setVariableValue(control, u, operation, param_2, param_3);
|
||||
return;
|
||||
|
||||
value_n:
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation &&
|
||||
(pN == TAdaptor_camera::sauVariableValue_3_POSITION_XYZ || pN == TAdaptor_camera::sauVariableValue_3_TARGET_POSITION_XYZ) &&
|
||||
(operation == data::UNK_0x2 || operation == data::UNK_0x3 || operation == data::UNK_0x12))
|
||||
{
|
||||
dusk::frame_interp::request_presentation_sync();
|
||||
}
|
||||
#endif
|
||||
adaptor->adaptor_setVariableValue_n(control, pN, u, operation, param_2, param_3);
|
||||
return;
|
||||
|
||||
|
||||
+37
-1
@@ -20,7 +20,6 @@
|
||||
#include "m_Do/m_Do_controller_pad.h"
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
#include "m_Do/m_Do_lib.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
@@ -29,6 +28,11 @@
|
||||
#include "d/d_debug_camera.h"
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/logging.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
static f32 limitf(f32 value, f32 min, f32 max) {
|
||||
@@ -2048,6 +2052,18 @@ s32 dCamera_c::nextType(s32 i_curType) {
|
||||
bool dCamera_c::onTypeChange(s32 i_curType, s32 i_nextType) {
|
||||
daAlink_c* unusedPlayer = daAlink_getAlinkActorClass();
|
||||
|
||||
#if TARGET_PC
|
||||
const s32 event_type_id = specialType[CAM_TYPE_EVENT];
|
||||
DuskLog.debug(
|
||||
"frameInterp: onTypeChange {} -> {} (event_type_id={}, leaving_event={}, entering_event={})",
|
||||
static_cast<int>(i_curType),
|
||||
static_cast<int>(i_nextType),
|
||||
static_cast<int>(event_type_id),
|
||||
i_curType == event_type_id,
|
||||
i_nextType == event_type_id
|
||||
);
|
||||
#endif
|
||||
|
||||
if (i_curType == specialType[CAM_TYPE_EVENT]) {
|
||||
if (mCamSetup.CheckFlag(0x4000)) {
|
||||
mGear = 0;
|
||||
@@ -10161,6 +10177,26 @@ bool dCamera_c::eventCamera(s32 param_0) {
|
||||
ActionNames[var_r29]);
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
switch (var_r29) {
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 12:
|
||||
dusk::frame_interp::request_presentation_sync();
|
||||
break;
|
||||
default:
|
||||
DuskLog.debug(
|
||||
"frameInterp: presentation sync not requested for ZEV event [{}] (staff idx {})",
|
||||
static_cast<const char*>(ActionNames[var_r29]),
|
||||
static_cast<int>(mEventData.mStaffIdx)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getEvFloatData(&sp28, "KeepDist") != 0 && mViewCache.mDirection.R() < sp28)
|
||||
{
|
||||
mViewCache.mDirection.R(sp28);
|
||||
|
||||
@@ -63,6 +63,10 @@ bool s_initialized = false;
|
||||
bool g_enabled = false;
|
||||
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;
|
||||
uint32_t g_current_presentation_ui_ticks = 0;
|
||||
@@ -235,7 +239,7 @@ void interpolate_branch(const Path& old_path, const Path& new_path, float step)
|
||||
}
|
||||
|
||||
const Mtx* resolve_replacement(const Mtx* source, Mtx* scratch) {
|
||||
if (!g_interpolating || source == nullptr) {
|
||||
if (!g_interpolating || source == nullptr || dusk::frame_interp::presentation_sync_active()) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -268,6 +272,7 @@ void begin_record() {
|
||||
ensure_initialized();
|
||||
if (!g_enabled) {
|
||||
g_interpolating = false;
|
||||
g_sync_presentation = false;
|
||||
g_previous_recording = {};
|
||||
g_current_recording = {};
|
||||
g_current_path.clear();
|
||||
@@ -275,6 +280,10 @@ void begin_record() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_sync_presentation && g_presentation_counter > g_presentation_sync_end) {
|
||||
g_sync_presentation = false;
|
||||
}
|
||||
|
||||
g_previous_recording = std::move(g_current_recording);
|
||||
g_current_recording = {};
|
||||
g_current_path.clear();
|
||||
@@ -292,21 +301,38 @@ void interpolate(float step) {
|
||||
ensure_initialized();
|
||||
clear_replacements();
|
||||
g_step = std::clamp(step, 0.0f, 1.0f);
|
||||
g_interpolating = g_enabled && !g_recording && has_recording_data(g_current_recording);
|
||||
g_interpolating = g_enabled && !g_recording && !g_sync_presentation && has_recording_data(g_current_recording);
|
||||
if (!g_interpolating) {
|
||||
return;
|
||||
}
|
||||
const Path& old_root = has_recording_data(g_previous_recording) ? g_previous_recording.root : g_current_recording.root;
|
||||
interpolate_branch(old_root, g_current_recording.root, g_step);
|
||||
}
|
||||
|
||||
if (!has_recording_data(g_previous_recording)) {
|
||||
interpolate_branch(g_current_recording.root, g_current_recording.root, g_step);
|
||||
void notify_presentation_frame() {
|
||||
ensure_initialized();
|
||||
++g_presentation_counter;
|
||||
}
|
||||
|
||||
void request_presentation_sync() {
|
||||
ensure_initialized();
|
||||
if (!g_enabled) {
|
||||
return;
|
||||
}
|
||||
g_sync_presentation = true;
|
||||
g_presentation_sync_end = g_presentation_counter + 1;
|
||||
}
|
||||
|
||||
interpolate_branch(g_previous_recording.root, g_current_recording.root, g_step);
|
||||
bool presentation_sync_active() {
|
||||
if (!s_initialized || !g_enabled) {
|
||||
return false;
|
||||
}
|
||||
return g_sync_presentation;
|
||||
}
|
||||
|
||||
float get_interpolation_step() {
|
||||
return g_step;
|
||||
ensure_initialized();
|
||||
return presentation_sync_active() ? 1.0f : g_step;
|
||||
}
|
||||
|
||||
void notify_sim_tick_complete() {
|
||||
@@ -371,7 +397,7 @@ void record_final_mtx_raw(const Mtx* dest, const Mtx src) {
|
||||
}
|
||||
|
||||
bool lookup_replacement(const void* source, Mtx out) {
|
||||
if (!s_initialized || !g_interpolating || source == nullptr) {
|
||||
if (presentation_sync_active() || !g_interpolating || source == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -385,7 +411,7 @@ bool lookup_replacement(const void* source, Mtx out) {
|
||||
}
|
||||
|
||||
bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out) {
|
||||
if (!s_initialized || !g_interpolating || lhs == nullptr || rhs == nullptr) {
|
||||
if (presentation_sync_active() || !g_interpolating || lhs == nullptr || rhs == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -393,9 +419,7 @@ bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out) {
|
||||
Mtx rhs_scratch;
|
||||
const Mtx* resolved_lhs = resolve_replacement(reinterpret_cast<const Mtx*>(lhs), &lhs_scratch);
|
||||
const Mtx* resolved_rhs = resolve_replacement(reinterpret_cast<const Mtx*>(rhs), &rhs_scratch);
|
||||
if (resolved_lhs == reinterpret_cast<const Mtx*>(lhs) &&
|
||||
resolved_rhs == reinterpret_cast<const Mtx*>(rhs))
|
||||
{
|
||||
if (resolved_lhs == reinterpret_cast<const Mtx*>(lhs) && resolved_rhs == reinterpret_cast<const Mtx*>(rhs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,6 +240,8 @@ void main01(void) {
|
||||
}
|
||||
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
dusk::frame_interp::notify_presentation_frame();
|
||||
|
||||
while (accumulator >= kSimStepSeconds) {
|
||||
mDoCPd_c::read();
|
||||
if (dusk::getSettings().game.enableGyroAim) {
|
||||
|
||||
Reference in New Issue
Block a user