diff --git a/src/d_main.c b/src/d_main.c index d2d796fda..adfc82d06 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -513,7 +513,10 @@ static void D_Display(void) D_RenderView(1); for (INT32 wi = 0; wi < numworlds; wi++) + { + R_RestoreLevelInterpolators(worldlist[wi]); worldlist[wi]->interpolated_level_this_frame = false; + } // Image postprocessing effect if (rendermode == render_soft) @@ -527,7 +530,6 @@ static void D_Display(void) V_DoPostProcessor(1, postimgtype2, postimgparam2); } PS_STOP_TIMING(ps_rendercalltime); - R_RestoreLevelInterpolators(); } if (lastdraw) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6d80cac43..d304b6416 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5569,7 +5569,7 @@ void HWR_BuildSkyDome(void) gl_sky_t *sky = &gl_sky; gl_skyvertex_t *vertex_p; - texture_t *texture = textures[texturetranslation[skytexture]]; + texture_t *texture = textures[texturetranslation[viewworld->skytexture]]; sky->detail = 16; col_count *= sky->detail; @@ -5588,7 +5588,7 @@ void HWR_BuildSkyDome(void) if (!sky->data) sky->data = malloc(sky->vertex_count * sizeof(sky->data[0])); - sky->texture = texturetranslation[skytexture]; + sky->texture = texturetranslation[viewworld->skytexture]; sky->width = texture->width; sky->height = texture->height; @@ -5674,9 +5674,9 @@ static void HWR_DrawSkyBackground(player_t *player) } dometransform.splitscreen = splitscreen; - HWR_GetTexture(texturetranslation[skytexture]); + HWR_GetTexture(texturetranslation[viewworld->skytexture]); - if (gl_sky.texture != texturetranslation[skytexture]) + if (gl_sky.texture != texturetranslation[viewworld->skytexture]) { HWR_ClearSkyDome(); HWR_BuildSkyDome(); @@ -5694,7 +5694,7 @@ static void HWR_DrawSkyBackground(player_t *player) float aspectratio; float angleturn; - HWR_GetTexture(texturetranslation[skytexture]); + HWR_GetTexture(texturetranslation[viewworld->skytexture]); aspectratio = (float)vid.width/(float)vid.height; //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 @@ -5721,7 +5721,7 @@ static void HWR_DrawSkyBackground(player_t *player) angle = (dup_viewangle + gl_xtoviewangle[0]); - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); + dimensionmultiply = ((float)textures[texturetranslation[viewworld->skytexture]]->width/256.0f); v[0].s = v[3].s = (-1.0f * angle) / (((float)ANGLE_90-1.0f)*dimensionmultiply); // left v[2].s = v[1].s = v[0].s + (1.0f/dimensionmultiply); // right (or left + 1.0f) @@ -5729,7 +5729,7 @@ static void HWR_DrawSkyBackground(player_t *player) // Y angle = aimingangle; - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); + dimensionmultiply = ((float)textures[texturetranslation[viewworld->skytexture]]->height/(128.0f*aspectratio)); if (splitscreen) { diff --git a/src/p_floor.c b/src/p_floor.c index 9c24f5851..ce983095d 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -525,7 +525,7 @@ void T_ContinuousFalling(continuousfall_t *faller) faller->sector->ceilingheight = faller->ceilingstartheight; faller->sector->floorheight = faller->floorstartheight; - R_ClearLevelInterpolatorState(&faller->thinker); + R_ClearLevelInterpolatorState(world, &faller->thinker); } P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong diff --git a/src/p_mobj.c b/src/p_mobj.c index 7be2d860f..6ab222c68 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11158,14 +11158,14 @@ void P_RemoveMobj(mobj_t *mobj) P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); + R_RemoveMobjInterpolator(mobj); + // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. #ifdef SCRAMBLE_REMOVED // Invalidate mobj_t data to cause crashes if accessed! memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); #endif - R_RemoveMobjInterpolator(mobj); - // free block if (!mobj->thinker.next) { // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through! diff --git a/src/p_saveg.c b/src/p_saveg.c index 15ec215a8..565783cff 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3088,8 +3088,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function - R_AddMobjInterpolator(mobj); - return &mobj->thinker; } @@ -3712,7 +3710,7 @@ static void P_NetUnArchiveThinkers(void) else { (next->prev = currentthinker->prev)->next = next; - R_DestroyLevelInterpolators(currentthinker); + R_DestroyLevelInterpolators(unarchiveworld, currentthinker); Z_Free(currentthinker); } } @@ -4871,6 +4869,8 @@ static void RelinkWorldsToEntities(void) I_Error("RelinkWorldsToEntities: Mobj type %d has a world mismatch (mobj: %d, set: %d)", mo->type, mo->worldnum, i); mo->world = worldlist[mo->worldnum]; + + R_AddMobjInterpolator(mo); } } @@ -4892,7 +4892,10 @@ static void RelinkWorldsToEntities(void) w = worldlist[player->worldnum]; player->world = w; if (player->mo) + { player->mo->world = w; + R_AddMobjInterpolator(player->mo); + } } } diff --git a/src/p_setup.c b/src/p_setup.c index 78c8659ee..ae18386f9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6886,10 +6886,6 @@ static void P_InitLevelSky(INT32 skynum, player_t *player) P_SetupWorldSky(skynum, world); levelskynum = skynum; - - // scale up the old skies, if needed - if (!dedicated) - R_SetupSkyDraw(); } /** Sets up a sky texture to use for the level. @@ -6903,26 +6899,18 @@ void P_SetupLevelSky(INT32 skynum, boolean global) // Global change if (global) P_SetupWorldSky(skynum, world); - - // scale up the old skies, if needed - if (!dedicated) - R_SetupSkyDraw(); } void P_SetupWorldSky(INT32 skynum, world_t *w) { w->skynum = skynum; - - // scale up the old skies, if needed - if (!dedicated) - R_SetupSkyDraw(); } void P_SetupSkyTexture(INT32 skynum) { char skytexname[12]; sprintf(skytexname, "SKY%d", skynum); - skytexture = R_TextureNumForName(skytexname); + world->skytexture = R_TextureNumForName(skytexname); } static const char *maplumpname; @@ -7784,7 +7772,7 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo if (!addworld || player == &players[consoleplayer]) localworld = world; - R_InitializeLevelInterpolators(); + R_InitializeLevelInterpolators(world); P_InitThinkers(); R_InitMobjInterpolators(); diff --git a/src/p_tick.c b/src/p_tick.c index 705a483a6..ef205e223 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -262,7 +262,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker) * thinker->prev->next = thinker->next */ (next->prev = currentthinker = thinker->prev)->next = next; - R_DestroyLevelInterpolators(thinker); + R_DestroyLevelInterpolators(world, thinker); Z_Free(thinker); } @@ -762,7 +762,7 @@ void P_Ticker(boolean run) if (OP_FreezeObjectplace()) { P_MapStart(); - R_UpdateMobjInterpolators(world); + R_UpdateAllMobjInterpolators(); OP_ObjectplaceMovement(&players[0]); P_MoveChaseCamera(&players[0], &camera, false); R_UpdateViewInterpolation(); @@ -788,7 +788,7 @@ void P_Ticker(boolean run) if (run) { - R_UpdateMobjInterpolators(world); + R_UpdateAllMobjInterpolators(); if (demorecording) G_WriteDemoTiccmd(&players[consoleplayer].cmd, 0); @@ -935,8 +935,8 @@ void P_Ticker(boolean run) if (rendermode != render_none) { player_t *player1 = &players[displayplayer]; - world_t *world1 = (world_t*)player1->world; - if (player1->mo && world1 && world1->skyboxmo[0] && cv_skybox.value) + R_PrepareViewWorld(player1); + if (player1->mo && viewworld && viewworld->skyboxmo[0] && cv_skybox.value) { R_SkyboxFrame(player1); } @@ -948,8 +948,8 @@ void P_Ticker(boolean run) if (splitscreen) { player_t *player2 = &players[secondarydisplayplayer]; - world_t *world2 = (world_t*)player2->world; - if (player2->mo && world2 && world2->skyboxmo[0] && cv_skybox.value) + R_PrepareViewWorld(player2); + if (player2->mo && viewworld && viewworld->skyboxmo[0] && cv_skybox.value) { R_SkyboxFrame(player2); } @@ -979,7 +979,7 @@ void P_PreTicker(INT32 frames) { P_MapStart(); - R_UpdateMobjInterpolators(world); + R_UpdateAllMobjInterpolators(); RunLuaHookForWorld(HOOK(PreThinkFrame)); diff --git a/src/p_world.c b/src/p_world.c index 8289a5832..8fd02abc3 100644 --- a/src/p_world.c +++ b/src/p_world.c @@ -29,6 +29,7 @@ #include "r_draw.h" #include "r_sky.h" #include "r_patch.h" +#include "r_fps.h" #include "s_sound.h" #include "w_wad.h" @@ -158,7 +159,10 @@ void P_DetachPlayerWorld(player_t *player) player->world = NULL; if (player->mo && !P_MobjWasRemoved(player->mo)) + { + R_RemoveMobjInterpolator(player->mo); player->mo->world = NULL; + } } // @@ -170,7 +174,10 @@ void P_SwitchPlayerWorld(player_t *player, world_t *newworld) player->world = newworld; if (player->mo && !P_MobjWasRemoved(player->mo)) + { player->mo->world = newworld; + R_AddMobjInterpolator(player->mo); + } newworld->players++; } @@ -267,26 +274,19 @@ void P_SwitchWorld(player_t *player, world_t *w) P_SwitchPlayerWorld(player, w); - if (!splitscreen) - { - P_SetWorld(w); - if (local) - P_InitSpecials(); - } + P_SetWorld(w); + if (local || splitscreen) + P_InitSpecials(); P_UnsetThingPosition(player->mo); - P_MoveThinkerToWorld(w, THINK_MAIN, (thinker_t *)(player->mo)); + P_MoveThinkerToWorld(w, THINK_MOBJ, (thinker_t *)(player->mo)); G_MovePlayerToSpawnOrStarpost(playernum); - if (local) + if (local && !splitscreen) { localworld = world; S_Start(); - if (!dedicated) - { - P_SetupSkyTexture(w->skynum); - R_SetupSkyDraw(); - } + P_SetupSkyTexture(w->skynum); } if (player == &players[displayplayer]) diff --git a/src/p_world.h b/src/p_world.h index 219e27573..0a1c59039 100644 --- a/src/p_world.h +++ b/src/p_world.h @@ -70,6 +70,9 @@ typedef struct INT32 skynum; // used for keeping track of the current sky UINT8 weather; + // the texture number of the sky texture + INT32 skytexture; + // Needed to store the number of the dummy sky flat. // Used for rendering, as well as tracking projectiles etc. INT32 skyflatnum; diff --git a/src/r_data.c b/src/r_data.c index 0efb1b3fb..0dbcf1c20 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1265,7 +1265,7 @@ void R_PrecacheLevel(void) // Sky texture is always present. // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, // while the sky texture is stored like a wall texture, with a skynum dependent name. - texturepresent[skytexture] = 1; + texturepresent[world->skytexture] = 1; texturememory = 0; for (j = 0; j < (unsigned)numtextures; j++) diff --git a/src/r_fps.c b/src/r_fps.c index c358fb369..9b16e9252 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -467,11 +467,12 @@ void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope) interp->dynslope.oldzdelta = interp->dynslope.bakzdelta = slope->zdelta; } -void R_InitializeLevelInterpolators(void) +void R_InitializeLevelInterpolators(void *wptr) { - world->interpolators_len = 0; - world->interpolators_size = 0; - world->interpolators = NULL; + world_t *w = (world_t *)wptr; + w->interpolators_len = 0; + w->interpolators_size = 0; + w->interpolators = NULL; } static void UpdateLevelInterpolatorState(levelinterpolator_t *interp) @@ -536,13 +537,14 @@ void R_UpdateLevelInterpolators(void) } } -void R_ClearLevelInterpolatorState(thinker_t *thinker) +void R_ClearLevelInterpolatorState(void *wptr, thinker_t *thinker) { + world_t *w = (world_t *)wptr; size_t i; - for (i = 0; i < world->interpolators_len; i++) + for (i = 0; i < w->interpolators_len; i++) { - levelinterpolator_t *interp = world->interpolators[i]; + levelinterpolator_t *interp = w->interpolators[i]; if (interp->thinker == thinker) { @@ -614,8 +616,9 @@ void R_ApplyLevelInterpolators(void *wptr, fixed_t frac) w->interpolated_level_this_frame = true; } -static void R_RestoreLevelInterpolatorsForWorld(world_t *w) +void R_RestoreLevelInterpolators(void *wptr) { + world_t *w = (world_t *)wptr; size_t i, ii; for (i = 0; i < w->interpolators_len; i++) @@ -669,31 +672,22 @@ static void R_RestoreLevelInterpolatorsForWorld(world_t *w) } } -void R_RestoreLevelInterpolators(void) +void R_DestroyLevelInterpolators(void *wptr, thinker_t *thinker) { - for (INT32 wi = 0; wi < numworlds; wi++) - { - world_t *w = worldlist[wi]; - R_RestoreLevelInterpolatorsForWorld(w); - } -} + world_t *w = (world_t *)wptr; -void R_DestroyLevelInterpolators(thinker_t *thinker) -{ - size_t i; - - for (i = 0; i < world->interpolators_len; i++) + for (size_t i = 0; i < w->interpolators_len; i++) { - levelinterpolator_t *interp = world->interpolators[i]; + levelinterpolator_t *interp = w->interpolators[i]; if (interp->thinker == thinker) { // Swap the tail of the level interpolators to this spot - world->interpolators[i] = world->interpolators[world->interpolators_len - 1]; - world->interpolators_len -= 1; + w->interpolators[i] = w->interpolators[w->interpolators_len - 1]; + w->interpolators_len--; Z_Free(interp); - i -= 1; + i--; } } } @@ -702,28 +696,32 @@ void R_DestroyLevelInterpolators(thinker_t *thinker) // reasons. void R_AddMobjInterpolator(mobj_t *mobj) { - if (world->interpolated_mobjs_len >= world->interpolated_mobjs_capacity) + world_t *w = (world_t *)mobj->world; + if (!w) + return; + + if (w->interpolated_mobjs_len >= w->interpolated_mobjs_capacity) { - if (world->interpolated_mobjs_capacity == 0) + if (w->interpolated_mobjs_capacity == 0) { - world->interpolated_mobjs_capacity = 256; + w->interpolated_mobjs_capacity = 256; } else { - world->interpolated_mobjs_capacity *= 2; + w->interpolated_mobjs_capacity *= 2; } - world->interpolated_mobjs = Z_ReallocAlign( - world->interpolated_mobjs, - sizeof(mobj_t *) * world->interpolated_mobjs_capacity, + w->interpolated_mobjs = Z_ReallocAlign( + w->interpolated_mobjs, + sizeof(mobj_t *) * w->interpolated_mobjs_capacity, PU_LEVEL, NULL, 64 ); } - world->interpolated_mobjs[world->interpolated_mobjs_len] = mobj; - world->interpolated_mobjs_len++; + w->interpolated_mobjs[w->interpolated_mobjs_len] = mobj; + w->interpolated_mobjs_len++; R_ResetMobjInterpolationState(mobj); mobj->resetinterp = true; @@ -731,18 +729,20 @@ void R_AddMobjInterpolator(mobj_t *mobj) void R_RemoveMobjInterpolator(mobj_t *mobj) { - size_t i; + world_t *w = (world_t *)mobj->world; + if (!w) + return; - if (world->interpolated_mobjs_len == 0) return; + if (w->interpolated_mobjs_len == 0) return; - for (i = 0; i < world->interpolated_mobjs_len; i++) + for (size_t i = 0; i < w->interpolated_mobjs_len; i++) { - if (world->interpolated_mobjs[i] == mobj) + if (w->interpolated_mobjs[i] == mobj) { - world->interpolated_mobjs[i] = world->interpolated_mobjs[ - world->interpolated_mobjs_len - 1 + w->interpolated_mobjs[i] = w->interpolated_mobjs[ + w->interpolated_mobjs_len - 1 ]; - world->interpolated_mobjs_len--; + w->interpolated_mobjs_len--; return; } } @@ -774,7 +774,10 @@ void R_UpdateAllMobjInterpolators(void) for (INT32 wi = 0; wi < numworlds; wi++) { world_t *w = worldlist[wi]; - R_UpdateMobjInterpolators(w); + + // Don't care about updating if nobody is there + if (w->players) + R_UpdateMobjInterpolators(w); } } diff --git a/src/r_fps.h b/src/r_fps.h index 0252922c5..9e074cd71 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -137,17 +137,17 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj); void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope); // Initialize level interpolators after a level change -void R_InitializeLevelInterpolators(void); +void R_InitializeLevelInterpolators(void *wptr); // Update level interpolators, storing the previous and current states. void R_UpdateLevelInterpolators(void); // Clear states for all level interpolators for the thinker -void R_ClearLevelInterpolatorState(thinker_t *thinker); +void R_ClearLevelInterpolatorState(void *wptr, thinker_t *thinker); // Apply level interpolators to the actual game state void R_ApplyLevelInterpolators(void *wptr, fixed_t frac); // Restore level interpolators to the real game state -void R_RestoreLevelInterpolators(void); +void R_RestoreLevelInterpolators(void *wptr); // Destroy interpolators associated with a thinker -void R_DestroyLevelInterpolators(thinker_t *thinker); +void R_DestroyLevelInterpolators(void *wptr, thinker_t *thinker); // Initialize internal mobj interpolator list (e.g. during level loading) void R_InitMobjInterpolators(void); diff --git a/src/r_main.c b/src/r_main.c index 4205534ad..205142ea5 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1141,6 +1141,9 @@ static boolean R_SetViewMobj(player_t *player) // void R_SetupFrame(player_t *player) { + if (viewworld == NULL) + return; + camera_t *thiscam = r_viewcam; boolean chasecam = R_ViewpointHasChasecam(player); @@ -1211,14 +1214,18 @@ void R_SetupFrame(player_t *player) newview->sector = R_PointInWorldSubsector(viewworld, newview->x, newview->y)->sector; } - // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT); - // newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT); + + // scale up the old skies, if needed + if (!dedicated) + R_SetupSkyDraw(); } void R_SkyboxFrame(player_t *player) { + if (viewworld == NULL) + return; + camera_t *thiscam = r_viewcam; if (splitscreen && player == &players[secondarydisplayplayer] @@ -1353,10 +1360,11 @@ void R_SkyboxFrame(player_t *player) else newview->sector = R_PointInWorldSubsector(viewworld, newview->x, newview->y)->sector; - // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT); - // newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT); + + // scale up the old skies, if needed + if (!dedicated) + R_SetupSkyDraw(); } boolean R_ViewpointHasChasecam(player_t *player) @@ -1380,7 +1388,7 @@ boolean R_ViewpointHasChasecam(player_t *player) chasecam = true; // force chasecam on else if (player->spectator) // no spectator chasecam chasecam = false; // force chasecam off - + if (chasecam && !thiscam->chase) { P_ResetCamera(player, thiscam); @@ -1391,7 +1399,7 @@ boolean R_ViewpointHasChasecam(player_t *player) P_ResetCamera(player, thiscam); thiscam->chase = false; } - + if (isplayer2) { R_SetViewContext(VIEWCONTEXT_PLAYER2); diff --git a/src/r_plane.c b/src/r_plane.c index 119be8d60..a87737715 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -657,8 +657,7 @@ static void R_DrawSkyPlane(visplane_t *pl) // by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant). dc_colormap = colormaps; dc_texturemid = skytexturemid; - dc_texheight = textureheight[skytexture] - >>FRACBITS; + dc_texheight = textureheight[viewworld->skytexture]>>FRACBITS; for (x = pl->minx; x <= pl->maxx; x++) { dc_yl = pl->top[x]; @@ -669,9 +668,7 @@ static void R_DrawSkyPlane(visplane_t *pl) angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); dc_x = x; - dc_source = - R_GetColumn(texturetranslation[skytexture], - -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 + dc_source = R_GetColumn(texturetranslation[viewworld->skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 colfunc(); } } diff --git a/src/r_sky.c b/src/r_sky.c index 0be5b9335..4ce37e215 100644 --- a/src/r_sky.c +++ b/src/r_sky.c @@ -32,10 +32,6 @@ */ INT32 levelskynum; -/** \brief the lump number of the sky texture -*/ -INT32 skytexture; - /** \brief the horizon line in a 256x128 sky texture */ INT32 skytexturemid; @@ -56,7 +52,7 @@ fixed_t skyscale; void R_SetupSkyDraw(void) { // the horizon line in a 256x128 sky texture - skytexturemid = (textures[skytexture]->height/2)<skytexture]->height/2)<