mirror of
				https://github.com/Zelda64Recomp/Zelda64Recomp.git
				synced 2025-10-30 08:03:03 +00:00 
			
		
		
		
	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
					
				
					 7 changed files with 114 additions and 16 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		
		Reference in a new issue