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 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) {
|
||||
}
|
||||
|
||||
|
@ -126,15 +140,13 @@ bool should_interpolate_perspective(Vec3f* eye, Vec3f* at) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (velocity_diff > 50.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (at_dist > 50.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eye_dist > 300.0f) {
|
||||
if (velocity_diff > 50.0f || at_dist > 50.0f || eye_dist > 300.0f) {
|
||||
eye_velocity.x = 0.0f;
|
||||
eye_velocity.y = 0.0f;
|
||||
eye_velocity.z = 0.0f;
|
||||
at_velocity.x = 0.0f;
|
||||
at_velocity.y = 0.0f;
|
||||
at_velocity.z = 0.0f;
|
||||
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);
|
||||
}
|
||||
|
||||
// Record whether the camera was skipped for later use.
|
||||
set_camera_skipped(!interpolate_camera);
|
||||
|
||||
camera_interpolation_forced = false;
|
||||
camera_skip_interpolation_forced = false;
|
||||
|
||||
|
|
|
@ -3,14 +3,83 @@
|
|||
|
||||
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
|
||||
void EffectSS_DrawParticle(PlayState* play, s32 index) {
|
||||
EffectSs* entry = &sEffectSsInfo.dataTable[index];
|
||||
|
||||
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);
|
||||
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 If this particle was just reset then skip interpolation.
|
||||
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) {
|
||||
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 set_camera_skipped(bool skipped);
|
||||
void clear_camera_skipped();
|
||||
bool camera_was_skipped();
|
||||
|
||||
void recomp_crash(const char* err);
|
||||
|
||||
#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);
|
||||
|
||||
// @recomp Tag the skybox's matrix.
|
||||
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);
|
||||
// @recomp Tag the skybox's matrix, skipping interpolation if the camera's interpolation was also skipped.
|
||||
if (camera_was_skipped()) {
|
||||
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);
|
||||
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.
|
||||
gEXSetRefreshRate(POLY_OPA_DISP++, 60 / (gameState->framerateDivisor + extra_vis));
|
||||
|
||||
// @recomp Clear the camera skip state.
|
||||
clear_camera_skipped();
|
||||
|
||||
gSPEndDisplayList(WORK_DISP++);
|
||||
gSPEndDisplayList(POLY_OPA_DISP++);
|
||||
gSPEndDisplayList(POLY_XLU_DISP++);
|
||||
|
|
|
@ -274,7 +274,6 @@ uint32_t ultramodern::get_target_framerate(uint32_t original) {
|
|||
|
||||
switch (graphics_config.rr_option) {
|
||||
case RT64::UserConfiguration::RefreshRate::Original:
|
||||
case RT64::UserConfiguration::RefreshRate::OriginalDelay:
|
||||
default:
|
||||
return original;
|
||||
case RT64::UserConfiguration::RefreshRate::Manual:
|
||||
|
|
Loading…
Reference in New Issue