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 a5b3006aca..8360bd45ef 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 b6c3a376a6..78ba9142b8 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 762f4b7941..cdb180e602 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 115ac64c93..6c65fc12fd 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 d563986f78..07edf25e97 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 939547797f..3e5fed9bca 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 1147f51681..95c976f8ca 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 55ad583ff5..14667093c7 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 52b8fdc866..01a73950b2 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 693bfa687c..fa1ce83df0 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();