From 65e1589543edd9d1d86628cd5c1616bada75e149 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 May 2016 22:47:36 +0200 Subject: [PATCH] - allow specifying actor classes whose graphics to precache through MAPINFO. - some reorganization of texture precaching so that the renderer can decide what to do with actors. Just marking the sprite textures loses too much info if more is needed than just loading the images into memory. --- src/g_level.h | 1 + src/g_mapinfo.cpp | 12 +++++ src/p_setup.cpp | 79 ++++++++++++++++++++++++++++++++- src/r_renderer.h | 2 +- src/r_swrenderer.cpp | 49 ++++++++++++++++++++ src/r_swrenderer.h | 3 +- src/textures/texturemanager.cpp | 38 ---------------- src/textures/textures.h | 1 - src/v_video.cpp | 77 -------------------------------- src/v_video.h | 3 +- 10 files changed, 144 insertions(+), 121 deletions(-) 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();