mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- 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.
This commit is contained in:
parent
0d402618a3
commit
65e1589543
10 changed files with 144 additions and 121 deletions
|
@ -338,6 +338,7 @@ struct level_info_t
|
|||
|
||||
TArray<FSoundID> PrecacheSounds;
|
||||
TArray<FString> PrecacheTextures;
|
||||
TArray<FName> PrecacheClasses;
|
||||
|
||||
level_info_t()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -3366,6 +3366,83 @@ void P_GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &spots, TAr
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// P_PrecacheLevel
|
||||
//
|
||||
// Preloads all relevant graphics for the level.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void P_PrecacheLevel()
|
||||
{
|
||||
int i;
|
||||
BYTE *hitlist;
|
||||
TMap<PClassActor *, bool> actorhitlist;
|
||||
int cnt = TexMan.NumTextures();
|
||||
|
||||
if (demoplayback)
|
||||
return;
|
||||
|
||||
hitlist = new BYTE[cnt];
|
||||
memset(hitlist, 0, cnt);
|
||||
|
||||
AActor *actor;
|
||||
TThinkerIterator<AActor> 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();
|
||||
|
|
|
@ -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<PClassActor*, bool> &actorhitlist) = 0;
|
||||
|
||||
// render 3D view
|
||||
virtual void RenderView(player_t *player) = 0;
|
||||
|
|
|
@ -98,6 +98,55 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache)
|
|||
}
|
||||
}
|
||||
|
||||
void FSoftwareRenderer::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
|
||||
{
|
||||
BYTE *spritelist = new BYTE[sprites.Size()];
|
||||
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
|
||||
TMap<PClassActor*, bool>::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
|
||||
|
|
|
@ -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<PClassActor*, bool> &actorhitlist);
|
||||
|
||||
// render 3D view
|
||||
virtual void RenderView(player_t *player);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<AActor> 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
|
||||
|
|
|
@ -395,7 +395,6 @@ public:
|
|||
virtual FNativePalette *CreatePalette(FRemapTable *remap);
|
||||
|
||||
// Precaches or unloads a texture
|
||||
virtual void GetHitlist(BYTE *hitlist);
|
||||
|
||||
// Report a game restart
|
||||
virtual void GameRestart();
|
||||
|
|
Loading…
Reference in a new issue