diff --git a/src/g_level.h b/src/g_level.h index a5b3006ac..8360bd45e 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -338,6 +338,7 @@ struct level_info_t TArray PrecacheSounds; TArray PrecacheTextures; + TArray PrecacheClasses; level_info_t() { diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index b6c3a376a..78ba9142b 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1083,6 +1083,18 @@ DEFINE_MAP_OPTION(PrecacheTextures, true) } while (parse.sc.CheckString(",")); } +DEFINE_MAP_OPTION(PrecacheClasses, true) +{ + parse.ParseAssign(); + + do + { + parse.sc.MustGetString(); + //the class list is not initialized here so all we can do is store the class's name. + info->PrecacheClasses.Push(parse.sc.String); + } while (parse.sc.CheckString(",")); +} + DEFINE_MAP_OPTION(redirect, true) { parse.ParseAssign(); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 762f4b794..cdb180e60 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3366,6 +3366,83 @@ void P_GetPolySpots (MapData * map, TArray &spots, TAr } } + +//=========================================================================== +// +// P_PrecacheLevel +// +// Preloads all relevant graphics for the level. +// +//=========================================================================== + +static void P_PrecacheLevel() +{ + int i; + BYTE *hitlist; + TMap actorhitlist; + int cnt = TexMan.NumTextures(); + + if (demoplayback) + return; + + hitlist = new BYTE[cnt]; + memset(hitlist, 0, cnt); + + AActor *actor; + TThinkerIterator iterator; + + while ((actor = iterator.Next())) + { + actorhitlist[actor->GetClass()] = true; + } + + for (unsigned i = 0; i < level.info->PrecacheClasses.Size(); i++) + { + // level.info can only store names, no class pointers. + PClassActor *cls = PClass::FindActor(level.info->PrecacheClasses[i]); + if (cls != NULL) actorhitlist[cls] = true; + } + + for (i = numsectors - 1; i >= 0; i--) + { + hitlist[sectors[i].GetTexture(sector_t::floor).GetIndex()] |= FTextureManager::HIT_Flat; + hitlist[sectors[i].GetTexture(sector_t::ceiling).GetIndex()] |= FTextureManager::HIT_Flat; + } + + for (i = numsides - 1; i >= 0; i--) + { + hitlist[sides[i].GetTexture(side_t::top).GetIndex()] |= FTextureManager::HIT_Wall; + hitlist[sides[i].GetTexture(side_t::mid).GetIndex()] |= FTextureManager::HIT_Wall; + hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= FTextureManager::HIT_Wall; + } + + // 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 an episode dependant + // name. + + if (sky1texture.isValid()) + { + hitlist[sky1texture.GetIndex()] |= FTextureManager::HIT_Sky; + } + if (sky2texture.isValid()) + { + hitlist[sky2texture.GetIndex()] |= FTextureManager::HIT_Sky; + } + + for (unsigned i = 0; i < level.info->PrecacheTextures.Size(); i++) + { + FTextureID tex = TexMan.CheckForTexture(level.info->PrecacheTextures[i], FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ReturnFirst); + if (tex.Exists()) hitlist[tex.GetIndex()] |= FTextureManager::HIT_Wall; + } + + Renderer->Precache(hitlist, actorhitlist); + + delete[] hitlist; +} + extern polyblock_t **PolyBlockMap; void P_FreeLevelData () @@ -4094,7 +4171,7 @@ void P_SetupLevel (const char *lumpname, int position) // preload graphics and sounds if (precache) { - TexMan.PrecacheLevel (); + P_PrecacheLevel (); S_PrecacheLevel (); } times[17].Unclock(); diff --git a/src/r_renderer.h b/src/r_renderer.h index 115ac64c9..6c65fc12f 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -28,7 +28,7 @@ struct FRenderer virtual bool UsesColormap() const = 0; // precache one texture - virtual void PrecacheTexture(FTexture *tex, int cache) = 0; + virtual void Precache(BYTE *texhitlist, TMap &actorhitlist) = 0; // render 3D view virtual void RenderView(player_t *player) = 0; diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index d563986f7..07edf25e9 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -98,6 +98,55 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) } } +void FSoftwareRenderer::Precache(BYTE *texhitlist, TMap &actorhitlist) +{ + BYTE *spritelist = new BYTE[sprites.Size()]; + TMap::Iterator it(actorhitlist); + TMap::Pair *pair; + + memset(spritelist, 0, sprites.Size()); + + while (it.NextPair(pair)) + { + PClassActor *cls = pair->Key; + + for (int i = 0; i < cls->NumOwnedStates; i++) + { + spritelist[cls->OwnedStates[i].sprite] = true; + } + } + + // Precache textures (and sprites). + + for (int i = (int)(sprites.Size() - 1); i >= 0; i--) + { + if (spritelist[i]) + { + int j, k; + for (j = 0; j < sprites[i].numframes; j++) + { + const spriteframe_t *frame = &SpriteFrames[sprites[i].spriteframes + j]; + + for (k = 0; k < 16; k++) + { + FTextureID pic = frame->Texture[k]; + if (pic.isValid()) + { + texhitlist[pic.GetIndex()] = FTextureManager::HIT_Sprite; + } + } + } + } + } + delete[] spritelist; + + int cnt = TexMan.NumTextures(); + for (int i = cnt - 1; i >= 0; i--) + { + PrecacheTexture(TexMan.ByIndex(i), texhitlist[i]); + } +} + //=========================================================================== // // Render the view diff --git a/src/r_swrenderer.h b/src/r_swrenderer.h index 939547797..3e5fed9bc 100644 --- a/src/r_swrenderer.h +++ b/src/r_swrenderer.h @@ -9,7 +9,8 @@ struct FSoftwareRenderer : public FRenderer virtual bool UsesColormap() const; // precache one texture - virtual void PrecacheTexture(FTexture *tex, int cache); + void PrecacheTexture(FTexture *tex, int cache); + virtual void Precache(BYTE *texhitlist, TMap &actorhitlist); // render 3D view virtual void RenderView(player_t *player); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 1147f5168..95c976f8c 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1226,44 +1226,6 @@ int FTextureManager::CountLumpTextures (int lumpnum) return 0; } -//=========================================================================== -// -// R_PrecacheLevel -// - -// Preloads all relevant graphics for the level. -// -//=========================================================================== - -void FTextureManager::PrecacheLevel (void) -{ - BYTE *hitlist; - int cnt = NumTextures(); - - if (demoplayback) - return; - - hitlist = new BYTE[cnt]; - memset (hitlist, 0, cnt); - - screen->GetHitlist(hitlist); - - for (unsigned i = 0; i < level.info->PrecacheTextures.Size(); i++) - { - FTextureID tex = TexMan.CheckForTexture(level.info->PrecacheTextures[i], FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_ReturnFirst); - if (tex.Exists()) hitlist[tex.GetIndex()] |= FTextureManager::HIT_Wall; - } - - for (int i = cnt - 1; i >= 0; i--) - { - Renderer->PrecacheTexture(ByIndex(i), hitlist[i]); - } - - delete[] hitlist; -} - - - //========================================================================== // diff --git a/src/textures/textures.h b/src/textures/textures.h index 55ad583ff..14667093c 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -379,7 +379,6 @@ public: void UnloadAll (); int NumTextures () const { return (int)Textures.Size(); } - void PrecacheLevel (void); void WriteTexture (FArchive &arc, int picnum); int ReadTexture (FArchive &arc); diff --git a/src/v_video.cpp b/src/v_video.cpp index 52b8fdc86..01a73950b 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1207,83 +1207,6 @@ void DFrameBuffer::WipeCleanup() wipe_Cleanup(); } -//=========================================================================== -// -// Create texture hitlist -// -//=========================================================================== - -void DFrameBuffer::GetHitlist(BYTE *hitlist) -{ - BYTE *spritelist; - int i; - - spritelist = new BYTE[sprites.Size()]; - - // Precache textures (and sprites). - memset (spritelist, 0, sprites.Size()); - - { - AActor *actor; - TThinkerIterator iterator; - - while ( (actor = iterator.Next ()) ) - spritelist[actor->sprite] = 1; - } - - for (i = (int)(sprites.Size () - 1); i >= 0; i--) - { - if (spritelist[i]) - { - int j, k; - for (j = 0; j < sprites[i].numframes; j++) - { - const spriteframe_t *frame = &SpriteFrames[sprites[i].spriteframes + j]; - - for (k = 0; k < 16; k++) - { - FTextureID pic = frame->Texture[k]; - if (pic.isValid()) - { - hitlist[pic.GetIndex()] = FTextureManager::HIT_Sprite; - } - } - } - } - } - - delete[] spritelist; - - for (i = numsectors - 1; i >= 0; i--) - { - hitlist[sectors[i].GetTexture(sector_t::floor).GetIndex()] = - hitlist[sectors[i].GetTexture(sector_t::ceiling).GetIndex()] |= FTextureManager::HIT_Flat; - } - - for (i = numsides - 1; i >= 0; i--) - { - hitlist[sides[i].GetTexture(side_t::top).GetIndex()] = - hitlist[sides[i].GetTexture(side_t::mid).GetIndex()] = - hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= FTextureManager::HIT_Wall; - } - - // 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 an episode dependant - // name. - - if (sky1texture.isValid()) - { - hitlist[sky1texture.GetIndex()] |= FTextureManager::HIT_Sky; - } - if (sky2texture.isValid()) - { - hitlist[sky2texture.GetIndex()] |= FTextureManager::HIT_Sky; - } -} - //========================================================================== // // DFrameBuffer :: GameRestart diff --git a/src/v_video.h b/src/v_video.h index 693bfa687..fa1ce83df 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -395,8 +395,7 @@ public: virtual FNativePalette *CreatePalette(FRemapTable *remap); // Precaches or unloads a texture - virtual void GetHitlist(BYTE *hitlist); - + // Report a game restart virtual void GameRestart();