Fixed camera interpolation double skips, made the skybox skip interpolation with the camera, fixed particles getting incorrectly matched
This commit is contained in:
parent
447689afd5
commit
d1d00e164c
2
lib/rt64
2
lib/rt64
|
@ -1 +1 @@
|
||||||
Subproject commit 482b9c9e48e97627b374a997dc8e21116af712e7
|
Subproject commit 8cced1f560a5513595b0d32335ac36244b82a411
|
|
@ -10,6 +10,20 @@ static bool camera_ignore_tracking = false;
|
||||||
static bool in_kaleido = false;
|
static bool in_kaleido = false;
|
||||||
static bool prev_in_kaleido = false;
|
static bool prev_in_kaleido = false;
|
||||||
|
|
||||||
|
static bool camera_skipped = false;
|
||||||
|
|
||||||
|
void set_camera_skipped(bool skipped) {
|
||||||
|
camera_skipped = skipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_camera_skipped() {
|
||||||
|
camera_skipped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool camera_was_skipped() {
|
||||||
|
return camera_skipped;
|
||||||
|
}
|
||||||
|
|
||||||
void camera_pre_play_update(PlayState* play) {
|
void camera_pre_play_update(PlayState* play) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,15 +140,13 @@ bool should_interpolate_perspective(Vec3f* eye, Vec3f* at) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (velocity_diff > 50.0f) {
|
if (velocity_diff > 50.0f || at_dist > 50.0f || eye_dist > 300.0f) {
|
||||||
return false;
|
eye_velocity.x = 0.0f;
|
||||||
}
|
eye_velocity.y = 0.0f;
|
||||||
|
eye_velocity.z = 0.0f;
|
||||||
if (at_dist > 50.0f) {
|
at_velocity.x = 0.0f;
|
||||||
return false;
|
at_velocity.y = 0.0f;
|
||||||
}
|
at_velocity.z = 0.0f;
|
||||||
|
|
||||||
if (eye_dist > 300.0f) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +206,9 @@ void View_Apply(View* view, s32 mask) {
|
||||||
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Record whether the camera was skipped for later use.
|
||||||
|
set_camera_skipped(!interpolate_camera);
|
||||||
|
|
||||||
camera_interpolation_forced = false;
|
camera_interpolation_forced = false;
|
||||||
camera_skip_interpolation_forced = false;
|
camera_skip_interpolation_forced = false;
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,83 @@
|
||||||
|
|
||||||
extern EffectSsInfo sEffectSsInfo;
|
extern EffectSsInfo sEffectSsInfo;
|
||||||
|
|
||||||
|
#define MAX_PARTICLES 256
|
||||||
|
u8 particle_reset_list[MAX_PARTICLES];
|
||||||
|
|
||||||
|
// @recomp Patched to track that the particle has been reset.
|
||||||
|
void EffectSS_ResetEntry(EffectSs* particle) {
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
particle->type = EFFECT_SS_MAX;
|
||||||
|
particle->accel.x = particle->accel.y = particle->accel.z = 0;
|
||||||
|
particle->velocity.x = particle->velocity.y = particle->velocity.z = 0;
|
||||||
|
particle->vec.x = particle->vec.y = particle->vec.z = 0;
|
||||||
|
particle->pos.x = particle->pos.y = particle->pos.z = 0;
|
||||||
|
particle->life = -1;
|
||||||
|
particle->flags = 0;
|
||||||
|
particle->priority = 128;
|
||||||
|
particle->draw = NULL;
|
||||||
|
particle->update = NULL;
|
||||||
|
particle->gfx = NULL;
|
||||||
|
particle->actor = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_COUNT(particle->regs); i++) {
|
||||||
|
particle->regs[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @recomp Get this particle's index and mark it as being reset.
|
||||||
|
u32 particle_index = particle - &sEffectSsInfo.dataTable[0];
|
||||||
|
if (particle_index >= sEffectSsInfo.size) {
|
||||||
|
recomp_crash("Invalid particle was reset!\n");
|
||||||
|
}
|
||||||
|
particle_reset_list[particle_index] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @recomp Check numEntries to be sure enough space has been allocated for tracking particle statuses.
|
||||||
|
void EffectSS_Init(PlayState* play, s32 numEntries) {
|
||||||
|
u32 i;
|
||||||
|
EffectSs* effectsSs;
|
||||||
|
EffectSsOverlay* overlay;
|
||||||
|
|
||||||
|
// @recomp Perform the numEntries check.
|
||||||
|
if (numEntries > MAX_PARTICLES) {
|
||||||
|
recomp_crash("Particle reset list too small!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sEffectSsInfo.dataTable = (EffectSs*)THA_AllocTailAlign16(&play->state.tha, numEntries * sizeof(EffectSs));
|
||||||
|
sEffectSsInfo.searchIndex = 0;
|
||||||
|
sEffectSsInfo.size = numEntries;
|
||||||
|
|
||||||
|
for (effectsSs = &sEffectSsInfo.dataTable[0]; effectsSs < &sEffectSsInfo.dataTable[sEffectSsInfo.size];
|
||||||
|
effectsSs++) {
|
||||||
|
EffectSS_ResetEntry(effectsSs);
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay = &gParticleOverlayTable[0];
|
||||||
|
for (i = 0; i < EFFECT_SS_MAX; i++) {
|
||||||
|
overlay->loadedRamAddr = NULL;
|
||||||
|
overlay++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @recomp Add transform tags to particles
|
// @recomp Add transform tags to particles
|
||||||
void EffectSS_DrawParticle(PlayState* play, s32 index) {
|
void EffectSS_DrawParticle(PlayState* play, s32 index) {
|
||||||
EffectSs* entry = &sEffectSsInfo.dataTable[index];
|
EffectSs* entry = &sEffectSsInfo.dataTable[index];
|
||||||
|
|
||||||
OPEN_DISPS(play->state.gfxCtx);
|
OPEN_DISPS(play->state.gfxCtx);
|
||||||
|
|
||||||
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
// @recomp If this particle was just reset then skip interpolation.
|
||||||
gEXMatrixGroupDecomposed(POLY_XLU_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
if (particle_reset_list[index]) {
|
||||||
|
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_ORDER_LINEAR);
|
||||||
|
gEXMatrixGroupDecomposed(POLY_XLU_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_ORDER_LINEAR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
gEXMatrixGroupDecomposed(POLY_XLU_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @recomp Clear this particle's reset state.
|
||||||
|
particle_reset_list[index] = false;
|
||||||
|
|
||||||
if (entry->draw != NULL) {
|
if (entry->draw != NULL) {
|
||||||
entry->draw(play, index, entry);
|
entry->draw(play, index, entry);
|
||||||
|
|
|
@ -48,4 +48,10 @@ void draw_dpad_icons(PlayState* play);
|
||||||
|
|
||||||
void View_ApplyInterpolate(View* view, s32 mask, bool reset_interpolation_state);
|
void View_ApplyInterpolate(View* view, s32 mask, bool reset_interpolation_state);
|
||||||
|
|
||||||
|
void set_camera_skipped(bool skipped);
|
||||||
|
void clear_camera_skipped();
|
||||||
|
bool camera_was_skipped();
|
||||||
|
|
||||||
|
void recomp_crash(const char* err);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,9 +30,15 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId
|
||||||
|
|
||||||
gSPMatrix(POLY_OPA_DISP++, sSkyboxDrawMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
gSPMatrix(POLY_OPA_DISP++, sSkyboxDrawMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||||
|
|
||||||
// @recomp Tag the skybox's matrix.
|
// @recomp Tag the skybox's matrix, skipping interpolation if the camera's interpolation was also skipped.
|
||||||
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, SKYBOX_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW,
|
if (camera_was_skipped()) {
|
||||||
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, SKYBOX_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, SKYBOX_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
gDPSetColorDither(POLY_OPA_DISP++, G_CD_MAGICSQ);
|
gDPSetColorDither(POLY_OPA_DISP++, G_CD_MAGICSQ);
|
||||||
gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP);
|
gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP);
|
||||||
|
|
|
@ -97,6 +97,9 @@ void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState) {
|
||||||
// @recomp Send the current framerate to RT64, including any extra VI interrupt periods.
|
// @recomp Send the current framerate to RT64, including any extra VI interrupt periods.
|
||||||
gEXSetRefreshRate(POLY_OPA_DISP++, 60 / (gameState->framerateDivisor + extra_vis));
|
gEXSetRefreshRate(POLY_OPA_DISP++, 60 / (gameState->framerateDivisor + extra_vis));
|
||||||
|
|
||||||
|
// @recomp Clear the camera skip state.
|
||||||
|
clear_camera_skipped();
|
||||||
|
|
||||||
gSPEndDisplayList(WORK_DISP++);
|
gSPEndDisplayList(WORK_DISP++);
|
||||||
gSPEndDisplayList(POLY_OPA_DISP++);
|
gSPEndDisplayList(POLY_OPA_DISP++);
|
||||||
gSPEndDisplayList(POLY_XLU_DISP++);
|
gSPEndDisplayList(POLY_XLU_DISP++);
|
||||||
|
|
|
@ -274,7 +274,6 @@ uint32_t ultramodern::get_target_framerate(uint32_t original) {
|
||||||
|
|
||||||
switch (graphics_config.rr_option) {
|
switch (graphics_config.rr_option) {
|
||||||
case RT64::UserConfiguration::RefreshRate::Original:
|
case RT64::UserConfiguration::RefreshRate::Original:
|
||||||
case RT64::UserConfiguration::RefreshRate::OriginalDelay:
|
|
||||||
default:
|
default:
|
||||||
return original;
|
return original;
|
||||||
case RT64::UserConfiguration::RefreshRate::Manual:
|
case RT64::UserConfiguration::RefreshRate::Manual:
|
||||||
|
|
Loading…
Reference in New Issue