mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-16 17:21:10 +00:00
- Backend update from Raze.
Mainly optimizations for the sound system and texture manager.
This commit is contained in:
parent
79a38f1f3a
commit
941c0850ba
30 changed files with 323 additions and 261 deletions
|
@ -193,7 +193,7 @@ public:
|
|||
TArray<RenderCommand> mData;
|
||||
int Width, Height;
|
||||
bool isIn2D;
|
||||
bool locked; // prevents clearing of the data so it can be reused multiple times (useful for screen fades)
|
||||
bool locked = false; // prevents clearing of the data so it can be reused multiple times (useful for screen fades)
|
||||
float screenFade = 1.f;
|
||||
DVector2 offset;
|
||||
DMatrix3x3 transform;
|
||||
|
|
|
@ -1465,21 +1465,11 @@ void SoundEngine::Reset()
|
|||
|
||||
FSoundID SoundEngine::FindSound(const char* logicalname)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (logicalname != NULL)
|
||||
{
|
||||
i = S_sfx[MakeKey(logicalname) % S_sfx.Size()].index;
|
||||
|
||||
while ((i != 0) && stricmp(S_sfx[i].name, logicalname))
|
||||
i = S_sfx[i].next;
|
||||
|
||||
return FSoundID::fromInt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO_SOUND;
|
||||
}
|
||||
if (!logicalname) return NO_SOUND;
|
||||
FName name(logicalname, true);
|
||||
if (name == NAME_None) return NO_SOUND;
|
||||
auto p = SoundMap.CheckKey(name);
|
||||
return p ? *p : NO_SOUND;
|
||||
}
|
||||
|
||||
FSoundID SoundEngine::FindSoundByResID(int resid)
|
||||
|
@ -1497,12 +1487,35 @@ FSoundID SoundEngine::FindSoundByResID(int resid)
|
|||
//==========================================================================
|
||||
|
||||
FSoundID SoundEngine::FindSoundNoHash(const char* logicalname)
|
||||
{
|
||||
if (!logicalname) return NO_SOUND;
|
||||
FName name(logicalname, true);
|
||||
if (name == NAME_None) return NO_SOUND;
|
||||
|
||||
for (unsigned i = 1; i < S_sfx.Size(); i++)
|
||||
{
|
||||
if (S_sfx[i].name == name)
|
||||
{
|
||||
return FSoundID::fromInt(i);
|
||||
}
|
||||
}
|
||||
return NO_SOUND;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_FindSoundByResIDNoHash
|
||||
//
|
||||
// same with resource IDs.
|
||||
//==========================================================================
|
||||
|
||||
FSoundID SoundEngine::FindSoundByResIDNoHash(int resid)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < S_sfx.Size(); i++)
|
||||
{
|
||||
if (stricmp(S_sfx[i].name, logicalname) == 0)
|
||||
if (S_sfx[i].ResourceId == resid)
|
||||
{
|
||||
return FSoundID::fromInt(i);
|
||||
}
|
||||
|
@ -1544,14 +1557,11 @@ FSoundID SoundEngine::AddSoundLump(const char* logicalname, int lump, int Curren
|
|||
|
||||
newsfx.name = logicalname;
|
||||
newsfx.lumpnum = lump;
|
||||
newsfx.next = 0;
|
||||
newsfx.PitchMask = CurrentPitchMask;
|
||||
newsfx.NearLimit = nearlimit;
|
||||
newsfx.ResourceId = resid;
|
||||
newsfx.bTentative = false;
|
||||
auto id = FSoundID::fromInt(S_sfx.Size() - 1);
|
||||
|
||||
if (resid >= 0) ResIdMap[resid] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -1565,12 +1575,12 @@ FSoundID SoundEngine::AddSoundLump(const char* logicalname, int lump, int Curren
|
|||
// an associated lump is created.
|
||||
//==========================================================================
|
||||
|
||||
FSoundID SoundEngine::FindSoundTentative(const char* name)
|
||||
FSoundID SoundEngine::FindSoundTentative(const char* name, int nearlimit)
|
||||
{
|
||||
auto id = FindSoundNoHash(name);
|
||||
if (id == NO_SOUND)
|
||||
{
|
||||
id = AddSoundLump(name, -1, 0);
|
||||
id = AddSoundLump(name, -1, 0, -1, nearlimit);
|
||||
S_sfx[id.index()].bTentative = true;
|
||||
}
|
||||
return id;
|
||||
|
@ -1675,25 +1685,21 @@ FSoundID SoundEngine::PickReplacement(FSoundID refid)
|
|||
|
||||
void SoundEngine::HashSounds()
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
unsigned int size;
|
||||
|
||||
S_sfx.ShrinkToFit();
|
||||
size = S_sfx.Size();
|
||||
SoundMap.Clear();
|
||||
ResIdMap.Clear();
|
||||
|
||||
// Mark all buckets as empty
|
||||
for (i = 0; i < size; i++)
|
||||
S_sfx[i].index = 0;
|
||||
|
||||
// Now set up the chains
|
||||
for (i = 1; i < size; i++)
|
||||
for (unsigned i = 1; i < S_sfx.Size(); i++)
|
||||
{
|
||||
j = MakeKey(S_sfx[i].name) % size;
|
||||
S_sfx[i].next = S_sfx[j].index;
|
||||
S_sfx[j].index = i;
|
||||
SoundMap.Insert(S_sfx[i].name, FSoundID::fromInt(i));
|
||||
if (S_sfx[i].ResourceId != -1)
|
||||
{
|
||||
ResIdMap.Insert(S_sfx[i].ResourceId, FSoundID::fromInt(i));
|
||||
}
|
||||
}
|
||||
S_rnd.ShrinkToFit();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SoundEngine::AddRandomSound(FSoundID Owner, TArray<FSoundID> list)
|
||||
|
@ -1824,26 +1830,20 @@ void S_SetSoundPaused(int state)
|
|||
|
||||
if ((state || i_soundinbackground) && !pauseext)
|
||||
{
|
||||
if (paused == 0)
|
||||
S_ResumeSound(true);
|
||||
if (GSnd != nullptr)
|
||||
{
|
||||
S_ResumeSound(true);
|
||||
if (GSnd != nullptr)
|
||||
{
|
||||
GSnd->SetInactive(SoundRenderer::INACTIVE_Active);
|
||||
}
|
||||
GSnd->SetInactive(SoundRenderer::INACTIVE_Active);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paused == 0)
|
||||
S_PauseSound(false, true);
|
||||
if (GSnd != nullptr)
|
||||
{
|
||||
S_PauseSound(false, true);
|
||||
if (GSnd != nullptr)
|
||||
{
|
||||
GSnd->SetInactive(gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL ?
|
||||
SoundRenderer::INACTIVE_Complete :
|
||||
SoundRenderer::INACTIVE_Mute);
|
||||
}
|
||||
GSnd->SetInactive(gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL ?
|
||||
SoundRenderer::INACTIVE_Complete :
|
||||
SoundRenderer::INACTIVE_Mute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "i_sound.h"
|
||||
#include "name.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -78,10 +79,9 @@ constexpr FSoundID INVALID_SOUND = FSoundID::fromInt(-1);
|
|||
// A non-null data means the sound has been loaded.
|
||||
SoundHandle data{};
|
||||
|
||||
FString name; // [RH] Sound name defined in SNDINFO
|
||||
FName name; // [RH] Sound name defined in SNDINFO
|
||||
int lumpnum = sfx_empty; // lump number of sfx
|
||||
|
||||
unsigned int next = -1, index = 0; // [RH] For hashing
|
||||
float Volume = 1.f;
|
||||
|
||||
int ResourceId = -1; // Resource ID as implemented by Blood. Not used by Doom but added for completeness.
|
||||
|
@ -192,6 +192,7 @@ protected:
|
|||
TArray<sfxinfo_t> S_sfx;
|
||||
FRolloffInfo S_Rolloff{};
|
||||
TArray<uint8_t> S_SoundCurve;
|
||||
TMap<FName, FSoundID> SoundMap;
|
||||
TMap<int, FSoundID> ResIdMap;
|
||||
TArray<FRandomSoundList> S_rnd;
|
||||
bool blockNewSounds = false;
|
||||
|
@ -390,9 +391,10 @@ public:
|
|||
FSoundID FindSound(const char* logicalname);
|
||||
FSoundID FindSoundByResID(int rid);
|
||||
FSoundID FindSoundNoHash(const char* logicalname);
|
||||
FSoundID FindSoundByResIDNoHash(int rid);
|
||||
FSoundID FindSoundByLump(int lump);
|
||||
virtual FSoundID AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2);
|
||||
FSoundID FindSoundTentative(const char* name);
|
||||
FSoundID FindSoundTentative(const char* name, int nearlimit = 2);
|
||||
void CacheRandomSound(sfxinfo_t* sfx);
|
||||
unsigned int GetMSLength(FSoundID sound);
|
||||
FSoundID PickReplacement(FSoundID refid);
|
||||
|
|
|
@ -44,8 +44,6 @@
|
|||
#include "gamestate.h"
|
||||
#include "i_interface.h"
|
||||
|
||||
bool G_Responder(event_t* ev);
|
||||
|
||||
int eventhead;
|
||||
int eventtail;
|
||||
event_t events[MAXEVENTS];
|
||||
|
@ -86,12 +84,16 @@ void D_ProcessEvents (void)
|
|||
if (ev->type == EV_DeviceChange)
|
||||
UpdateJoystickMenu(I_UpdateDeviceList());
|
||||
|
||||
if (gamestate != GS_INTRO) // GS_INTRO blocks the UI.
|
||||
// allow the game to intercept Escape before dispatching it.
|
||||
if (ev->type != EV_KeyDown || ev->data1 != KEY_ESCAPE || !sysCallbacks.WantEscape || !sysCallbacks.WantEscape())
|
||||
{
|
||||
if (C_Responder(ev))
|
||||
continue; // console ate the event
|
||||
if (M_Responder(ev))
|
||||
continue; // menu ate the event
|
||||
if (gamestate != GS_INTRO) // GS_INTRO blocks the UI.
|
||||
{
|
||||
if (C_Responder(ev))
|
||||
continue; // console ate the event
|
||||
if (M_Responder(ev))
|
||||
continue; // menu ate the event
|
||||
}
|
||||
}
|
||||
|
||||
if (sysCallbacks.G_Responder(ev) && ev->type == EV_KeyDown) keywasdown.Set(ev->data1);
|
||||
|
|
|
@ -46,6 +46,7 @@ struct SystemCallbacks
|
|||
void (*LanguageChanged)(const char*);
|
||||
bool (*OkForLocalization)(FTextureID, const char*);
|
||||
FConfigFile* (*GetConfig)();
|
||||
bool (*WantEscape)();
|
||||
};
|
||||
|
||||
extern SystemCallbacks sysCallbacks;
|
||||
|
|
|
@ -184,6 +184,7 @@ xx(IsNull)
|
|||
xx(Exists)
|
||||
xx(SetInvalid)
|
||||
xx(SetNull)
|
||||
xx(Key)
|
||||
|
||||
// color channels
|
||||
xx(a)
|
||||
|
|
|
@ -99,106 +99,23 @@ void VersionInfo::operator=(const char *string)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FScanner::FScanner()
|
||||
FScanner::FScanner(TMap<FName, Symbol>* extsymbols) : symbols(extsymbols? *extsymbols : mysymbols)
|
||||
{
|
||||
ScriptOpen = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FScanner Destructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FScanner::~FScanner()
|
||||
{
|
||||
// Humm... Nothing to do in here.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FScanner Copy Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FScanner::FScanner(const FScanner &other)
|
||||
{
|
||||
ScriptOpen = false;
|
||||
*this = other;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FScanner OpenLumpNum Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FScanner::FScanner(int lumpnum)
|
||||
FScanner::FScanner(int lumpnum, TMap<FName, Symbol>* extsymbols) : symbols(extsymbols ? *extsymbols : mysymbols)
|
||||
{
|
||||
ScriptOpen = false;
|
||||
OpenLumpNum(lumpnum);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FScanner :: operator =
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FScanner &FScanner::operator=(const FScanner &other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
if (!other.ScriptOpen)
|
||||
{
|
||||
Close();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy protected members
|
||||
ScriptOpen = true;
|
||||
ScriptName = other.ScriptName;
|
||||
ScriptBuffer = other.ScriptBuffer;
|
||||
ScriptPtr = other.ScriptPtr;
|
||||
ScriptEndPtr = other.ScriptEndPtr;
|
||||
AlreadyGot = other.AlreadyGot;
|
||||
AlreadyGotLine = other.AlreadyGotLine;
|
||||
LastGotToken = other.LastGotToken;
|
||||
LastGotPtr = other.LastGotPtr;
|
||||
LastGotLine = other.LastGotLine;
|
||||
CMode = other.CMode;
|
||||
Escape = other.Escape;
|
||||
StateMode = other.StateMode;
|
||||
StateOptions = other.StateOptions;
|
||||
|
||||
// Copy public members
|
||||
if (other.String == other.StringBuffer)
|
||||
{
|
||||
memcpy(StringBuffer, other.StringBuffer, sizeof(StringBuffer));
|
||||
BigStringBuffer = "";
|
||||
String = StringBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Past practice means the string buffer must be writeable, which
|
||||
// removes some of the benefit from using an FString to store
|
||||
// the big string buffer.
|
||||
BigStringBuffer = other.BigStringBuffer;
|
||||
String = BigStringBuffer.LockBuffer();
|
||||
}
|
||||
StringLen = other.StringLen;
|
||||
TokenType = other.TokenType;
|
||||
Number = other.Number;
|
||||
Float = other.Float;
|
||||
Line = other.Line;
|
||||
End = other.End;
|
||||
Crossed = other.Crossed;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FScanner :: Open
|
||||
|
@ -1229,7 +1146,7 @@ void FScanner::AddSymbol(const char *name, int64_t value)
|
|||
{
|
||||
Symbol sym;
|
||||
sym.tokenType = TK_IntConst;
|
||||
sym.Number = int(value);
|
||||
sym.Number = value;
|
||||
sym.Float = double(value);
|
||||
symbols.Insert(name, sym);
|
||||
}
|
||||
|
|
|
@ -54,16 +54,18 @@ public:
|
|||
double Float;
|
||||
};
|
||||
|
||||
using SymbolMap = TMap<FName, Symbol>;
|
||||
|
||||
TMap<FName, Symbol> symbols;
|
||||
SymbolMap mysymbols;
|
||||
SymbolMap& symbols;
|
||||
TMap<FName, Symbol>& GetSymbols() { return symbols; }
|
||||
|
||||
// Methods ------------------------------------------------------
|
||||
FScanner();
|
||||
FScanner(const FScanner &other);
|
||||
FScanner(int lumpnum);
|
||||
~FScanner();
|
||||
|
||||
FScanner &operator=(const FScanner &other);
|
||||
FScanner(TMap<FName, Symbol>* extsymbols = nullptr);
|
||||
FScanner(const FScanner& other) = delete;
|
||||
FScanner& operator=(const FScanner& other) = delete;
|
||||
FScanner(int lumpnum, TMap<FName, Symbol>* extsymbols = nullptr);
|
||||
~FScanner() = default;
|
||||
|
||||
void Open(const char *lumpname);
|
||||
bool OpenFile(const char *filename);
|
||||
|
@ -115,6 +117,13 @@ public:
|
|||
void MustGetNumber(bool evaluate = false);
|
||||
bool CheckNumber(bool evaluate = false);
|
||||
|
||||
bool GetNumber(int16_t& var, bool evaluate = false)
|
||||
{
|
||||
if (!GetNumber(evaluate)) return false;
|
||||
var = Number;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetNumber(int& var, bool evaluate = false)
|
||||
{
|
||||
if (!GetNumber(evaluate)) return false;
|
||||
|
@ -155,9 +164,9 @@ public:
|
|||
void MustGetFloat(bool evaluate = false);
|
||||
bool CheckFloat(bool evaluate = false);
|
||||
|
||||
double *LookupConstant(FName name)
|
||||
Symbol *LookupSymbol(FName name)
|
||||
{
|
||||
return constants.CheckKey(name);
|
||||
return symbols.CheckKey(name);
|
||||
}
|
||||
|
||||
// Token based variant
|
||||
|
|
|
@ -121,7 +121,7 @@ FTextureID LoadSkin(const char * path, const char * fn)
|
|||
|
||||
int texlump = FindGFXFile(buffer);
|
||||
const char * const texname = texlump < 0 ? fn : fileSystem.GetFileFullName(texlump);
|
||||
return TexMan.CheckForTexture(texname, ETextureType::Any, FTextureManager::TEXMAN_TryAny);
|
||||
return TexMan.CheckForTexture(texname, ETextureType::Any, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ForceLookup);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -625,6 +625,7 @@ private:
|
|||
public:
|
||||
void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader)
|
||||
{
|
||||
tex->setSeen();
|
||||
if (!sysCallbacks.PreBindTexture || !sysCallbacks.PreBindTexture(this, tex, upscalemask, scaleflags, clampmode, translation, overrideshader))
|
||||
{
|
||||
if (shouldUpscale(tex, upscalemask)) scaleflags |= CTF_Upscale;
|
||||
|
|
|
@ -560,14 +560,12 @@ public:
|
|||
class FxVectorValue : public FxExpression
|
||||
{
|
||||
constexpr static int maxVectorDimensions = 4;
|
||||
|
||||
FxExpression *xyzw[maxVectorDimensions];
|
||||
bool isConst; // gets set to true if all element are const (used by function defaults parser)
|
||||
|
||||
public:
|
||||
FxExpression *xyzw[maxVectorDimensions];
|
||||
|
||||
friend class ZCCCompiler;
|
||||
friend class ZCCDoomCompiler;
|
||||
|
||||
FxVectorValue(FxExpression *x, FxExpression *y, FxExpression *z, FxExpression* w, const FScriptPosition &sc);
|
||||
~FxVectorValue();
|
||||
|
|
|
@ -638,7 +638,8 @@ struct DirectNativeDesc
|
|||
template<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); }
|
||||
template<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12), TP(13)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13); }
|
||||
template<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12), TP(13), TP(14)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13), VP(14); }
|
||||
#undef TP
|
||||
template<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12), TP(13), TP(14), TP(15)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13), VP(14), VP(15); }
|
||||
#undef TP
|
||||
#undef VP
|
||||
|
||||
template<typename T> void ValidateType() { static_assert(native_is_valid<T>::value, "Argument type is not valid as a direct native parameter or return type"); }
|
||||
|
|
|
@ -124,7 +124,7 @@ void ST_UnloadCrosshair()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale)
|
||||
void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale, DAngle angle)
|
||||
{
|
||||
uint32_t color;
|
||||
double size;
|
||||
|
@ -207,6 +207,7 @@ void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale)
|
|||
xpos, ypos,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_Rotate, angle.Degrees(),
|
||||
DTA_AlphaChannel, true,
|
||||
DTA_FillColor, color & 0xFFFFFF,
|
||||
TAG_DONE);
|
||||
|
|
|
@ -10,7 +10,7 @@ class FFont;
|
|||
extern FGameTexture* CrosshairImage;
|
||||
void ST_LoadCrosshair(int num, bool alwaysload);
|
||||
void ST_UnloadCrosshair();
|
||||
void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale);
|
||||
void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale, DAngle angle = nullAngle);
|
||||
|
||||
|
||||
enum DI_Flags
|
||||
|
|
|
@ -140,16 +140,27 @@ void FGameTexture::AddAutoMaterials()
|
|||
const char* path;
|
||||
RefCountedPtr<FTexture> FGameTexture::* pointer;
|
||||
};
|
||||
struct AutoTextureSearchPath2
|
||||
{
|
||||
const char* path;
|
||||
RefCountedPtr<FTexture> FMaterialLayers::* pointer;
|
||||
};
|
||||
|
||||
static AutoTextureSearchPath autosearchpaths[] =
|
||||
{
|
||||
{ "brightmaps/", &FGameTexture::Brightmap }, // For backwards compatibility, only for short names
|
||||
{ "materials/brightmaps/", &FGameTexture::Brightmap },
|
||||
{ "materials/normalmaps/", &FGameTexture::Normal },
|
||||
{ "materials/specular/", &FGameTexture::Specular },
|
||||
{ "materials/metallic/", &FGameTexture::Metallic },
|
||||
{ "materials/roughness/", &FGameTexture::Roughness },
|
||||
{ "materials/ao/", &FGameTexture::AmbientOcclusion }
|
||||
};
|
||||
|
||||
static AutoTextureSearchPath2 autosearchpaths2[] =
|
||||
{
|
||||
{ "materials/detailmaps/", &FMaterialLayers::Detailmap },
|
||||
{ "materials/glowmaps/", &FMaterialLayers::Glowmap },
|
||||
{ "materials/normalmaps/", &FMaterialLayers::Normal },
|
||||
{ "materials/specular/", &FMaterialLayers::Specular },
|
||||
{ "materials/metallic/", &FMaterialLayers::Metallic },
|
||||
{ "materials/roughness/", &FMaterialLayers::Roughness },
|
||||
{ "materials/ao/", &FMaterialLayers::AmbientOcclusion }
|
||||
};
|
||||
|
||||
if (flags & GTexf_AutoMaterialsAdded) return; // do this only once
|
||||
|
@ -181,6 +192,24 @@ void FGameTexture::AddAutoMaterials()
|
|||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < countof(autosearchpaths2); i++)
|
||||
{
|
||||
auto& layer = autosearchpaths2[i];
|
||||
if (!this->Layers || this->Layers.get()->*(layer.pointer) == nullptr) // only if no explicit assignment had been done.
|
||||
{
|
||||
FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars());
|
||||
auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true);
|
||||
if (lump != -1)
|
||||
{
|
||||
auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny);
|
||||
if (bmtex != nullptr)
|
||||
{
|
||||
if (this->Layers == nullptr) this->Layers = std::make_unique<FMaterialLayers>();
|
||||
this->Layers.get()->* (layer.pointer) = bmtex->GetTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flags |= GTexf_AutoMaterialsAdded;
|
||||
}
|
||||
|
||||
|
@ -283,7 +312,7 @@ bool FGameTexture::ShouldExpandSprite()
|
|||
expandSprite = false;
|
||||
return false;
|
||||
}
|
||||
if (Glowmap != NULL && (Base->GetWidth() != Glowmap->GetWidth() || Base->GetHeight() != Glowmap->GetHeight()))
|
||||
if (Layers && Layers->Glowmap != NULL && (Base->GetWidth() != Layers->Glowmap->GetWidth() || Base->GetHeight() != Layers->Glowmap->GetHeight()))
|
||||
{
|
||||
// same restriction for the glow map
|
||||
expandSprite = false;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include "vectors.h"
|
||||
#include "floatrect.h"
|
||||
#include "refcounted.h"
|
||||
|
@ -60,6 +61,19 @@ enum EGameTexFlags
|
|||
GTexf_AutoMaterialsAdded = 256, // AddAutoMaterials has been called on this texture.
|
||||
GTexf_OffsetsNotForFont = 512, // The offsets must be ignored when using this texture in a font.
|
||||
GTexf_NoTrim = 1024, // Don't perform trimming on this texture.
|
||||
GTexf_Seen = 2048, // Set to true when the texture is being used for rendering. Must be cleared manually if the check is needed.
|
||||
};
|
||||
|
||||
struct FMaterialLayers
|
||||
{
|
||||
RefCountedPtr<FTexture> Detailmap;
|
||||
RefCountedPtr<FTexture> Glowmap;
|
||||
RefCountedPtr<FTexture> Normal; // Normal map texture
|
||||
RefCountedPtr<FTexture> Specular; // Specular light texture for the diffuse+normal+specular light model
|
||||
RefCountedPtr<FTexture> Metallic; // Metalness texture for the physically based rendering (PBR) light model
|
||||
RefCountedPtr<FTexture> Roughness; // Roughness texture for PBR
|
||||
RefCountedPtr<FTexture> AmbientOcclusion; // Ambient occlusion texture for PBR
|
||||
RefCountedPtr<FTexture> CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES]; // Custom texture maps for custom hardware shaders
|
||||
};
|
||||
|
||||
// Refactoring helper to allow piece by piece adjustment of the API
|
||||
|
@ -71,14 +85,7 @@ class FGameTexture
|
|||
// Material layers. These are shared so reference counting is used.
|
||||
RefCountedPtr<FTexture> Base;
|
||||
RefCountedPtr<FTexture> Brightmap;
|
||||
RefCountedPtr<FTexture> Detailmap;
|
||||
RefCountedPtr<FTexture> Glowmap;
|
||||
RefCountedPtr<FTexture> Normal; // Normal map texture
|
||||
RefCountedPtr<FTexture> Specular; // Specular light texture for the diffuse+normal+specular light model
|
||||
RefCountedPtr<FTexture> Metallic; // Metalness texture for the physically based rendering (PBR) light model
|
||||
RefCountedPtr<FTexture> Roughness; // Roughness texture for PBR
|
||||
RefCountedPtr<FTexture> AmbientOcclusion; // Ambient occlusion texture for PBR
|
||||
RefCountedPtr<FTexture> CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES]; // Custom texture maps for custom hardware shaders
|
||||
std::unique_ptr<FMaterialLayers> Layers;
|
||||
|
||||
FString Name;
|
||||
FTextureID id;
|
||||
|
@ -179,6 +186,13 @@ public:
|
|||
void SetRotations(int rot) { Rotations = int16_t(rot); }
|
||||
void SetSkyOffset(int offs) { SkyOffset = offs; }
|
||||
int GetSkyOffset() const { return SkyOffset; }
|
||||
void setSeen() { flags |= GTexf_Seen; }
|
||||
bool isSeen(bool reset)
|
||||
{
|
||||
int v = flags & GTexf_Seen;
|
||||
if (reset) flags &= ~GTexf_Seen;
|
||||
return v;
|
||||
}
|
||||
|
||||
ISoftwareTexture* GetSoftwareTexture()
|
||||
{
|
||||
|
@ -204,14 +218,25 @@ public:
|
|||
if (lay.Glossiness > -1000) Glossiness = lay.Glossiness;
|
||||
if (lay.SpecularLevel > -1000) SpecularLevel = lay.SpecularLevel;
|
||||
if (lay.Brightmap) Brightmap = lay.Brightmap->GetTexture();
|
||||
if (lay.Normal) Normal = lay.Normal->GetTexture();
|
||||
if (lay.Specular) Specular = lay.Specular->GetTexture();
|
||||
if (lay.Metallic) Metallic = lay.Metallic->GetTexture();
|
||||
if (lay.Roughness) Roughness = lay.Roughness->GetTexture();
|
||||
if (lay.AmbientOcclusion) AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
|
||||
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
|
||||
|
||||
bool needlayers = (lay.Normal || lay.Specular || lay.Metallic || lay.Roughness || lay.AmbientOcclusion);
|
||||
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES && !needlayers; i++)
|
||||
{
|
||||
if (lay.CustomShaderTextures[i]) CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
|
||||
if (lay.CustomShaderTextures[i]) needlayers = true;
|
||||
}
|
||||
if (needlayers)
|
||||
{
|
||||
Layers = std::make_unique<FMaterialLayers>();
|
||||
|
||||
if (lay.Normal) Layers->Normal = lay.Normal->GetTexture();
|
||||
if (lay.Specular) Layers->Specular = lay.Specular->GetTexture();
|
||||
if (lay.Metallic) Layers->Metallic = lay.Metallic->GetTexture();
|
||||
if (lay.Roughness) Layers->Roughness = lay.Roughness->GetTexture();
|
||||
if (lay.AmbientOcclusion) Layers->AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
|
||||
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
|
||||
{
|
||||
if (lay.CustomShaderTextures[i]) Layers->CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
float GetGlossiness() const { return Glossiness; }
|
||||
|
@ -306,13 +331,20 @@ public:
|
|||
void GetLayers(TArray<FTexture*>& layers)
|
||||
{
|
||||
layers.Clear();
|
||||
for (auto tex : { Base.get(), Brightmap.get(), Detailmap.get(), Glowmap.get(), Normal.get(), Specular.get(), Metallic.get(), Roughness.get(), AmbientOcclusion.get() })
|
||||
for (auto tex : { Base.get(), Brightmap.get() })
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex);
|
||||
}
|
||||
for (auto& tex : CustomShaderTextures)
|
||||
if (Layers)
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex.get());
|
||||
for (auto tex : { Layers->Detailmap.get(), Layers->Glowmap.get(), Layers->Normal.get(), Layers->Specular.get(), Layers->Metallic.get(), Layers->Roughness.get(), Layers->AmbientOcclusion.get() })
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex);
|
||||
}
|
||||
for (auto& tex : Layers->CustomShaderTextures)
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,28 +367,59 @@ public:
|
|||
}
|
||||
FTexture* GetGlowmap()
|
||||
{
|
||||
return Glowmap.get();
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->Glowmap.get();
|
||||
}
|
||||
FTexture* GetDetailmap()
|
||||
{
|
||||
return Detailmap.get();
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->Detailmap.get();
|
||||
}
|
||||
FTexture* GetNormalmap()
|
||||
{
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->Normal.get();
|
||||
}
|
||||
FTexture* GetSpecularmap()
|
||||
{
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->Specular.get();
|
||||
}
|
||||
FTexture* GetMetallic()
|
||||
{
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->Metallic.get();
|
||||
}
|
||||
FTexture* GetRoughness()
|
||||
{
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->Roughness.get();
|
||||
}
|
||||
FTexture* GetAmbientOcclusion()
|
||||
{
|
||||
if (!Layers) return nullptr;
|
||||
return Layers->AmbientOcclusion.get();
|
||||
}
|
||||
|
||||
void SetGlowmap(FTexture *T)
|
||||
{
|
||||
Glowmap = T;
|
||||
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||
Layers->Glowmap = T;
|
||||
}
|
||||
void SetDetailmap(FTexture* T)
|
||||
{
|
||||
Detailmap = T;
|
||||
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||
Layers->Detailmap = T;
|
||||
}
|
||||
void SetNormalmap(FTexture* T)
|
||||
{
|
||||
Normal = T;
|
||||
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||
Layers->Normal = T;
|
||||
}
|
||||
void SetSpecularmap(FTexture* T)
|
||||
{
|
||||
Specular = T;
|
||||
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||
Layers->Specular = T;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -79,17 +79,17 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
|
||||
}
|
||||
// Note that the material takes no ownership of the texture!
|
||||
else if (tx->Normal.get() && tx->Specular.get())
|
||||
else if (tx->Layers && tx->Layers->Normal.get() && tx->Layers->Specular.get())
|
||||
{
|
||||
for (auto &texture : { tx->Normal.get(), tx->Specular.get() })
|
||||
for (auto &texture : { tx->Layers->Normal.get(), tx->Layers->Specular.get() })
|
||||
{
|
||||
mTextureLayers.Push({ texture, 0, -1 });
|
||||
}
|
||||
mShaderIndex = SHADER_Specular;
|
||||
}
|
||||
else if (tx->Normal.get() && tx->Metallic.get() && tx->Roughness.get() && tx->AmbientOcclusion.get())
|
||||
else if (tx->Layers && tx->Layers->Normal.get() && tx->Layers->Metallic.get() && tx->Layers->Roughness.get() && tx->Layers->AmbientOcclusion.get())
|
||||
{
|
||||
for (auto &texture : { tx->Normal.get(), tx->Metallic.get(), tx->Roughness.get(), tx->AmbientOcclusion.get() })
|
||||
for (auto &texture : { tx->Layers->Normal.get(), tx->Layers->Metallic.get(), tx->Layers->Roughness.get(), tx->Layers->AmbientOcclusion.get() })
|
||||
{
|
||||
mTextureLayers.Push({ texture, 0, -1 });
|
||||
}
|
||||
|
@ -108,18 +108,18 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
{
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
|
||||
}
|
||||
if (tx->Detailmap.get())
|
||||
if (tx->Layers && tx->Layers->Detailmap.get())
|
||||
{
|
||||
mTextureLayers.Push({ tx->Detailmap.get(), 0, CLAMP_NONE });
|
||||
mTextureLayers.Push({ tx->Layers->Detailmap.get(), 0, CLAMP_NONE });
|
||||
mLayerFlags |= TEXF_Detailmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
|
||||
}
|
||||
if (tx->Glowmap.get())
|
||||
if (tx->Layers && tx->Layers->Glowmap.get())
|
||||
{
|
||||
mTextureLayers.Push({ tx->Glowmap.get(), scaleflags, -1 });
|
||||
mTextureLayers.Push({ tx->Layers->Glowmap.get(), scaleflags, -1 });
|
||||
mLayerFlags |= TEXF_Glowmap;
|
||||
}
|
||||
else
|
||||
|
@ -133,9 +133,9 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
if (index >= FIRST_USER_SHADER)
|
||||
{
|
||||
const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER];
|
||||
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||
if (tx->Layers && usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||
{
|
||||
for (auto& texture : tx->CustomShaderTextures)
|
||||
for (auto& texture : tx->Layers->CustomShaderTextures)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
|
|
|
@ -82,9 +82,6 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion)
|
|||
{
|
||||
PalettedPixels ret;
|
||||
|
||||
FString name;
|
||||
fileSystem.GetFileShortName(name, SourceLump);
|
||||
|
||||
auto imageID = ImageID;
|
||||
|
||||
// Do we have this image in the cache?
|
||||
|
@ -196,10 +193,7 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int
|
|||
{
|
||||
FBitmap ret;
|
||||
|
||||
FString name;
|
||||
int trans = -1;
|
||||
fileSystem.GetFileShortName(name, SourceLump);
|
||||
|
||||
auto imageID = ImageID;
|
||||
|
||||
if (remap != nullptr)
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
virtual bool SupportRemap0() { return false; } // Unfortunate hackery that's needed for Hexen's skies. Only the image can know about the needed parameters
|
||||
virtual bool IsRawCompatible() { return true; } // Same thing for mid texture compatibility handling. Can only be determined by looking at the composition data which is private to the image.
|
||||
|
||||
void CopySize(FImageSource &other)
|
||||
void CopySize(FImageSource &other) noexcept
|
||||
{
|
||||
Width = other.Width;
|
||||
Height = other.Height;
|
||||
|
@ -71,6 +71,7 @@ public:
|
|||
|
||||
// Images are statically allocated and freed in bulk. None of the subclasses may hold any destructible data.
|
||||
void *operator new(size_t block) { return ImageArena.Alloc(block); }
|
||||
void* operator new(size_t block, void* mem) { return mem; }
|
||||
void operator delete(void *block) {}
|
||||
|
||||
bool bMasked = true; // Image (might) have holes (Assume true unless proven otherwise!)
|
||||
|
@ -86,7 +87,6 @@ public:
|
|||
// tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy.
|
||||
TArray<uint8_t> GetPalettedPixels(int conversion);
|
||||
|
||||
|
||||
// Unlile for paletted images there is no variant here that returns a persistent bitmap, because all users have to process the returned image into another format.
|
||||
FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr);
|
||||
|
||||
|
@ -103,8 +103,8 @@ public:
|
|||
noremap0 = 2
|
||||
};
|
||||
|
||||
FImageSource(int sourcelump = -1) : SourceLump(sourcelump) { ImageID = ++NextID; }
|
||||
virtual ~FImageSource() {}
|
||||
FImageSource(int sourcelump = -1) noexcept : SourceLump(sourcelump) { ImageID = ++NextID; }
|
||||
virtual ~FImageSource() = default;
|
||||
|
||||
int GetWidth() const
|
||||
{
|
||||
|
|
|
@ -186,6 +186,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
|
|||
// The name matches, so check the texture type
|
||||
if (usetype == ETextureType::Any)
|
||||
{
|
||||
if (flags & TEXMAN_ReturnAll) return FTextureID(i); // user asked to skip all checks, including null textures.
|
||||
// All NULL textures should actually return 0
|
||||
if (texUseType == ETextureType::FirstDefined && !(flags & TEXMAN_ReturnFirst)) return 0;
|
||||
if (texUseType == ETextureType::SkinGraphic && !(flags & TEXMAN_AllowSkins)) return 0;
|
||||
|
@ -229,6 +230,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
|
|||
// Never return the index of NULL textures.
|
||||
if (firstfound != -1)
|
||||
{
|
||||
if (flags & TEXMAN_ReturnAll) return FTextureID(i); // user asked to skip all checks, including null textures.
|
||||
if (firsttype == ETextureType::Null) return FTextureID(0);
|
||||
if (firsttype == ETextureType::FirstDefined && !(flags & TEXMAN_ReturnFirst)) return FTextureID(0);
|
||||
return FTextureID(firstfound);
|
||||
|
@ -426,7 +428,7 @@ FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohas
|
|||
hash = -1;
|
||||
}
|
||||
|
||||
TextureHash hasher = { texture, -1, -1, -1, hash };
|
||||
TextureDescriptor hasher = { texture, -1, -1, -1, hash };
|
||||
int trans = Textures.Push (hasher);
|
||||
Translation.Push (trans);
|
||||
if (bucket >= 0) HashFirst[bucket] = trans;
|
||||
|
@ -1150,7 +1152,7 @@ void FTextureManager::AddLocalizedVariants()
|
|||
uint32_t langid = MAKE_ID(lang[0], lang[1], lang[2], 0);
|
||||
uint64_t comboid = (uint64_t(langid) << 32) | origTex.GetIndex();
|
||||
LocalizedTextures.Insert(comboid, tex.GetIndex());
|
||||
Textures[origTex.GetIndex()].HasLocalization = true;
|
||||
Textures[origTex.GetIndex()].Flags |= TEXFLAG_HASLOCALIZATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1601,11 +1603,28 @@ void FTextureManager::SetTranslation(FTextureID fromtexnum, FTextureID totexnum)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FTextureManager::AddAlias(const char* name, FGameTexture* tex)
|
||||
void FTextureManager::AddAlias(const char* name, int texindex)
|
||||
{
|
||||
FTextureID id = tex->GetID();
|
||||
if (tex != Textures[id.GetIndex()].Texture || !tex->isValid()) return; // Whatever got passed in here was not valid, so ignore the alias.
|
||||
aliases.Insert(name, id.GetIndex());
|
||||
if (texindex < 0 || texindex >= NumTextures()) return; // Whatever got passed in here was not valid, so ignore the alias.
|
||||
aliases.Insert(name, texindex);
|
||||
}
|
||||
|
||||
void FTextureManager::Listaliases()
|
||||
{
|
||||
decltype(aliases)::Iterator it(aliases);
|
||||
decltype(aliases)::Pair* pair;
|
||||
|
||||
TArray<FString> list;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto tex = GetGameTexture(pair->Value);
|
||||
list.Push(FStringf("%s -> %s%s", pair->Key.GetChars(), tex ? tex->GetName().GetChars() : "(null)", ((tex && tex->GetUseType() == ETextureType::Null) ? ", null" : "")));
|
||||
}
|
||||
std::sort(list.begin(), list.end(), [](const FString& l, const FString& r) { return l.CompareNoCase(r) < 0; });
|
||||
for (auto& s : list)
|
||||
{
|
||||
Printf("%s\n", s.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1627,3 +1646,7 @@ CCMD(flushtextures)
|
|||
TexMan.FlushAll();
|
||||
}
|
||||
|
||||
CCMD(listtexturealiases)
|
||||
{
|
||||
TexMan.Listaliases();
|
||||
}
|
||||
|
|
|
@ -25,50 +25,50 @@ public:
|
|||
private:
|
||||
int ResolveLocalizedTexture(int texnum);
|
||||
|
||||
int ResolveTextureIndex(int texnum, bool animate, bool localize)
|
||||
int ResolveTextureIndex(int texnum, bool animate) const
|
||||
{
|
||||
if ((unsigned)texnum >= Textures.Size()) return -1;
|
||||
if (animate) texnum = Translation[texnum];
|
||||
if (localize && Textures[texnum].HasLocalization) texnum = ResolveLocalizedTexture(texnum);
|
||||
//if (localize && Textures[texnum].Flags & TEXFLAG_HASLOCALIZATION) texnum = ResolveLocalizedTexture(texnum);
|
||||
return texnum;
|
||||
}
|
||||
|
||||
FGameTexture *InternalGetTexture(int texnum, bool animate, bool localize)
|
||||
FGameTexture *InternalGetTexture(int texnum, bool animate) const
|
||||
{
|
||||
texnum = ResolveTextureIndex(texnum, animate, localize);
|
||||
texnum = ResolveTextureIndex(texnum, animate);
|
||||
if (texnum == -1) return nullptr;
|
||||
return Textures[texnum].Texture;
|
||||
}
|
||||
|
||||
public:
|
||||
FTextureID ResolveTextureIndex(FTextureID texid, bool animate, bool localize)
|
||||
FTextureID ResolveTextureIndex(FTextureID texid, bool animate) const
|
||||
{
|
||||
return FSetTextureID(ResolveTextureIndex(texid.GetIndex(), animate, localize));
|
||||
return FSetTextureID(ResolveTextureIndex(texid.GetIndex(), animate));
|
||||
}
|
||||
|
||||
public:
|
||||
// This only gets used in UI code so we do not need PALVERS handling.
|
||||
FGameTexture* GetGameTextureByName(const char *name, bool animate = false, int flags = 0)
|
||||
{
|
||||
FTextureID texnum = GetTextureID(name, ETextureType::MiscPatch, flags);
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true);
|
||||
return InternalGetTexture(texnum.GetIndex(), animate);
|
||||
}
|
||||
|
||||
FGameTexture* GetGameTexture(FTextureID texnum, bool animate = false)
|
||||
FGameTexture* GetGameTexture(FTextureID texnum, bool animate = false) const
|
||||
{
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true);
|
||||
return InternalGetTexture(texnum.GetIndex(), animate);
|
||||
}
|
||||
|
||||
FGameTexture* GetPalettedTexture(FTextureID texnum, bool animate = false, bool allowsubstitute = true)
|
||||
FGameTexture* GetPalettedTexture(FTextureID texnum, bool animate = false, bool allowsubstitute = true) const
|
||||
{
|
||||
auto texid = ResolveTextureIndex(texnum.GetIndex(), animate, true);
|
||||
auto texid = ResolveTextureIndex(texnum.GetIndex(), animate);
|
||||
if (texid == -1) return nullptr;
|
||||
if (allowsubstitute && Textures[texid].Paletted > 0) texid = Textures[texid].Paletted;
|
||||
return Textures[texid].Texture;
|
||||
}
|
||||
|
||||
FGameTexture* GameByIndex(int i, bool animate = false)
|
||||
FGameTexture* GameByIndex(int i, bool animate = false) const
|
||||
{
|
||||
return InternalGetTexture(i, animate, true);
|
||||
return InternalGetTexture(i, animate);
|
||||
}
|
||||
|
||||
FGameTexture* FindGameTexture(const char* texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny);
|
||||
|
@ -76,6 +76,7 @@ public:
|
|||
bool OkForLocalization(FTextureID texnum, const char *substitute, int locnum);
|
||||
|
||||
void FlushAll();
|
||||
void Listaliases();
|
||||
FTextureID GetFrontSkyLayer(FTextureID);
|
||||
FTextureID GetRawTexture(FTextureID tex, bool dontlookup = false);
|
||||
void SetRawTexture(FTextureID texid)
|
||||
|
@ -99,6 +100,7 @@ public:
|
|||
TEXMAN_Localize = 64,
|
||||
TEXMAN_ForceLookup = 128,
|
||||
TEXMAN_NoAlias = 256,
|
||||
TEXMAN_ReturnAll = 512,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -154,7 +156,11 @@ public:
|
|||
tmanips.Remove(cname);
|
||||
}
|
||||
|
||||
void AddAlias(const char* name, FGameTexture* tex);
|
||||
void AddAlias(const char* name, int texindex);
|
||||
void AddAlias(const char* name, FTextureID texindex)
|
||||
{
|
||||
AddAlias(name, texindex.GetIndex());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
@ -173,6 +179,10 @@ public:
|
|||
BuildTileData.Reserve(1);
|
||||
return BuildTileData.Last();
|
||||
}
|
||||
TArray<TArray<uint8_t>>& GetBuildTileDataStore()
|
||||
{
|
||||
return BuildTileData;
|
||||
}
|
||||
|
||||
FGameTexture* GameTexture(FTextureID id) { return Textures[id.GetIndex()].Texture; }
|
||||
void SetTranslation(FTextureID fromtexnum, FTextureID totexnum);
|
||||
|
@ -183,17 +193,26 @@ private:
|
|||
|
||||
// Switches
|
||||
|
||||
struct TextureHash
|
||||
struct TextureDescriptor
|
||||
{
|
||||
FGameTexture* Texture;
|
||||
int Paletted; // redirection to paletted variant
|
||||
int FrontSkyLayer; // and front sky layer,
|
||||
int RawTexture;
|
||||
int HashNext;
|
||||
bool HasLocalization;
|
||||
uint64_t Flags;
|
||||
};
|
||||
|
||||
enum : uint64_t
|
||||
{
|
||||
TEXFLAG_HASLOCALIZATION = 1,
|
||||
};
|
||||
public:
|
||||
constexpr static int TEXFLAG_FIRSTUSER = 65536; // this leaves 16 flags to the texture manager and 48 flags to the user
|
||||
private:
|
||||
|
||||
enum { HASH_END = -1, HASH_SIZE = 1027 };
|
||||
TArray<TextureHash> Textures;
|
||||
TArray<TextureDescriptor> Textures;
|
||||
TMap<uint64_t, int> LocalizedTextures;
|
||||
int HashFirst[HASH_SIZE];
|
||||
FTextureID DefaultTexture;
|
||||
|
|
|
@ -213,7 +213,7 @@ public:
|
|||
{
|
||||
}
|
||||
////////
|
||||
TArray ()
|
||||
constexpr TArray ()
|
||||
{
|
||||
Most = 0;
|
||||
Count = 0;
|
||||
|
|
|
@ -1428,11 +1428,6 @@ public:
|
|||
return int(Degrees_ * (512 / 90.0));
|
||||
}
|
||||
|
||||
constexpr double Buildfang() const
|
||||
{
|
||||
return Degrees_ * (512 / 90.0);
|
||||
}
|
||||
|
||||
constexpr int Q16() const
|
||||
{
|
||||
return int(Degrees_ * (16384 / 90.0));
|
||||
|
@ -1455,7 +1450,8 @@ public:
|
|||
|
||||
double Tan() const
|
||||
{
|
||||
return vec_t(g_tan(Radians()));
|
||||
auto bam = BAMs();
|
||||
return g_sinbam(bam) / g_cosbam(bam);
|
||||
}
|
||||
|
||||
// This is for calculating vertical velocity. For high pitches the tangent will become too large to be useful.
|
||||
|
|
|
@ -2299,9 +2299,11 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i
|
|||
fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(inclump)), sc.String);
|
||||
}
|
||||
}
|
||||
FScanner saved_sc = sc;
|
||||
ParseMapInfo(inclump, gamedefaults, defaultinfo);
|
||||
sc = saved_sc;
|
||||
// use a new parser object to parse the include. Otherwise we'd have to save the entire FScanner in a local variable which is a lot more messy.
|
||||
FMapInfoParser includer(&sc);
|
||||
includer.format_type = format_type;
|
||||
includer.HexenHack = HexenHack;
|
||||
includer.ParseMapInfo(inclump, gamedefaults, defaultinfo);
|
||||
}
|
||||
else if (sc.Compare("gamedefaults"))
|
||||
{
|
||||
|
|
|
@ -78,6 +78,10 @@ struct CutsceneDef;
|
|||
|
||||
struct FMapInfoParser
|
||||
{
|
||||
FMapInfoParser(FScanner* parent)
|
||||
: sc(parent ? &parent->GetSymbols() : nullptr)
|
||||
{
|
||||
}
|
||||
enum EFormatType
|
||||
{
|
||||
FMT_Unknown,
|
||||
|
|
|
@ -472,7 +472,6 @@ xx(Strength)
|
|||
xx(Mode)
|
||||
xx(PowerupType)
|
||||
xx(PlayerPawn)
|
||||
xx(Key)
|
||||
xx(RipSound)
|
||||
xx(Archvile)
|
||||
|
||||
|
|
|
@ -1445,12 +1445,12 @@ class GLDefsParser
|
|||
if (usershader.shader.IsNotEmpty())
|
||||
{
|
||||
int firstUserTexture;
|
||||
if ((mlay.Normal || tex->Normal.get()) && (mlay.Specular || tex->Specular.get()))
|
||||
if ((mlay.Normal || tex->GetNormalmap()) && (mlay.Specular || tex->GetSpecularmap()))
|
||||
{
|
||||
usershader.shaderType = SHADER_Specular;
|
||||
firstUserTexture = 7;
|
||||
}
|
||||
else if ((mlay.Normal || tex->Normal.get()) && (mlay.Metallic || tex->Metallic.get()) && (mlay.Roughness || tex->Roughness.get()) && (mlay.AmbientOcclusion || tex->AmbientOcclusion.get()))
|
||||
else if ((mlay.Normal || tex->GetNormalmap()) && (mlay.Metallic || tex->GetMetallic()) && (mlay.Roughness || tex->GetRoughness()) && (mlay.AmbientOcclusion || tex->GetAmbientOcclusion()))
|
||||
{
|
||||
usershader.shaderType = SHADER_PBR;
|
||||
firstUserTexture = 9;
|
||||
|
|
|
@ -2428,7 +2428,7 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GetDisplacement)
|
|||
DVector2 ofs(0, 0);
|
||||
if (pg1 != pg2)
|
||||
{
|
||||
int i = pg1 + self->Displacements.size * pg2;
|
||||
unsigned i = pg1 + self->Displacements.size * pg2;
|
||||
if (i < self->Displacements.data.Size())
|
||||
ofs = self->Displacements.data[i].pos;
|
||||
}
|
||||
|
|
|
@ -476,8 +476,8 @@ void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *
|
|||
return;
|
||||
}
|
||||
(*(FVector2*)addr) = FVector2(
|
||||
static_cast<FxConstant *>(v->xyzw[0])->GetValue().GetFloat(),
|
||||
static_cast<FxConstant *>(v->xyzw[1])->GetValue().GetFloat()
|
||||
float(static_cast<FxConstant *>(v->xyzw[0])->GetValue().GetFloat()),
|
||||
float(static_cast<FxConstant *>(v->xyzw[1])->GetValue().GetFloat())
|
||||
);
|
||||
goto vector_ok;
|
||||
}
|
||||
|
@ -503,9 +503,9 @@ void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *
|
|||
return;
|
||||
}
|
||||
(*(FVector3*)addr) = FVector3(
|
||||
static_cast<FxConstant *>(v->xyzw[0])->GetValue().GetFloat(),
|
||||
static_cast<FxConstant *>(v->xyzw[1])->GetValue().GetFloat(),
|
||||
static_cast<FxConstant *>(v->xyzw[2])->GetValue().GetFloat()
|
||||
float(static_cast<FxConstant*>(v->xyzw[0])->GetValue().GetFloat()),
|
||||
float(static_cast<FxConstant*>(v->xyzw[1])->GetValue().GetFloat()),
|
||||
float(static_cast<FxConstant*>(v->xyzw[2])->GetValue().GetFloat())
|
||||
);
|
||||
goto vector_ok;
|
||||
}
|
||||
|
@ -532,10 +532,10 @@ void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *
|
|||
return;
|
||||
}
|
||||
(*(FVector4*)addr) = FVector4(
|
||||
static_cast<FxConstant *>(v->xyzw[0])->GetValue().GetFloat(),
|
||||
static_cast<FxConstant *>(v->xyzw[1])->GetValue().GetFloat(),
|
||||
static_cast<FxConstant *>(v->xyzw[2])->GetValue().GetFloat(),
|
||||
static_cast<FxConstant *>(v->xyzw[3])->GetValue().GetFloat()
|
||||
float(static_cast<FxConstant*>(v->xyzw[0])->GetValue().GetFloat()),
|
||||
float(static_cast<FxConstant*>(v->xyzw[1])->GetValue().GetFloat()),
|
||||
float(static_cast<FxConstant*>(v->xyzw[2])->GetValue().GetFloat()),
|
||||
float(static_cast<FxConstant *>(v->xyzw[3])->GetValue().GetFloat())
|
||||
);
|
||||
goto vector_ok;
|
||||
}
|
||||
|
|
|
@ -492,7 +492,7 @@ FSoundID S_AddPlayerSound (const char *pclass, int gender, FSoundID refid, int l
|
|||
fakename += '"';
|
||||
fakename += '0' + gender;
|
||||
fakename += '"';
|
||||
fakename += sfx->name;
|
||||
fakename += sfx->name.GetChars();
|
||||
|
||||
id = soundEngine->AddSoundLump (fakename, lumpnum, CurrentPitchMask);
|
||||
int classnum = S_AddPlayerClass (pclass);
|
||||
|
@ -1593,7 +1593,7 @@ CCMD (playersounds)
|
|||
if (sfx->UserData[0] & SND_PlayerReserve)
|
||||
{
|
||||
++j;
|
||||
reserveNames[sfx->link.index()] = sfx->name;
|
||||
reserveNames[sfx->link.index()] = sfx->name.GetChars();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue