Finish reimplementation of 2D text renderer
This commit is contained in:
parent
5020d82f68
commit
c30bb4f93c
@ -122,6 +122,33 @@ namespace Components
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextRenderer::GlowColor(Game::GfxColor* result, const Game::GfxColor baseColor, const Game::GfxColor forcedGlowColor, int renderFlags)
|
||||||
|
{
|
||||||
|
if (renderFlags & Game::TEXT_RENDERFLAG_GLOW_FORCE_COLOR)
|
||||||
|
{
|
||||||
|
result->array[0] = forcedGlowColor.array[0];
|
||||||
|
result->array[1] = forcedGlowColor.array[1];
|
||||||
|
result->array[2] = forcedGlowColor.array[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->array[0] = static_cast<char>(std::floor(static_cast<float>(static_cast<uint8_t>(baseColor.array[0])) * 0.06f));
|
||||||
|
result->array[1] = static_cast<char>(std::floor(static_cast<float>(static_cast<uint8_t>(baseColor.array[1])) * 0.06f));
|
||||||
|
result->array[2] = static_cast<char>(std::floor(static_cast<float>(static_cast<uint8_t>(baseColor.array[2])) * 0.06f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned TextRenderer::R_FontGetRandomLetter(const int seed)
|
||||||
|
{
|
||||||
|
static constexpr char RANDOM_CHARACTERS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
|
||||||
|
return RANDOM_CHARACTERS[seed % (std::extent_v<decltype(RANDOM_CHARACTERS)> -1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextRenderer::DrawTextFxExtraCharacter(Game::Material* material, const int charIndex, const float x, const float y, const float w, const float h, const float sinAngle, const float cosAngle, const unsigned color)
|
||||||
|
{
|
||||||
|
Game::RB_DrawStretchPicRotate(material, x, y, w, h, static_cast<float>(charIndex % 16) * 0.0625f, 0.0f, static_cast<float>(charIndex % 16) * 0.0625f + 0.0625f, 1.0f, sinAngle, cosAngle, color);
|
||||||
|
}
|
||||||
|
|
||||||
float TextRenderer::DrawFontIcon(const std::string& fontIconName, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, const float yScale, unsigned color)
|
float TextRenderer::DrawFontIcon(const std::string& fontIconName, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, const float yScale, unsigned color)
|
||||||
{
|
{
|
||||||
auto* material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, fontIconName.data()).material;
|
auto* material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, fontIconName.data()).material;
|
||||||
@ -215,6 +242,7 @@ namespace Components
|
|||||||
|
|
||||||
int randSeed = 1;
|
int randSeed = 1;
|
||||||
bool drawRandomCharAtEnd = false;
|
bool drawRandomCharAtEnd = false;
|
||||||
|
const auto forceMonospace = renderFlags & Game::TEXT_RENDERFLAG_FORCEMONOSPACE;
|
||||||
const auto monospaceWidth = GetMonospaceWidth(font, renderFlags);
|
const auto monospaceWidth = GetMonospaceWidth(font, renderFlags);
|
||||||
auto* material = font->material;
|
auto* material = font->material;
|
||||||
Game::Material* glowMaterial = nullptr;
|
Game::Material* glowMaterial = nullptr;
|
||||||
@ -264,10 +292,14 @@ namespace Components
|
|||||||
|
|
||||||
for(auto passIndex = 0u; passIndex < passCount; passIndex++)
|
for(auto passIndex = 0u; passIndex < passCount; passIndex++)
|
||||||
{
|
{
|
||||||
|
float xRot, yRot;
|
||||||
const char* curText = text;
|
const char* curText = text;
|
||||||
auto maxLengthRemaining = maxLength;
|
auto maxLengthRemaining = maxLength;
|
||||||
auto currentColor = color.packed;
|
auto currentColor = color;
|
||||||
auto subtitleAllowGlow = false;
|
auto subtitleAllowGlow = false;
|
||||||
|
auto extraFxChar = 0;
|
||||||
|
auto drawExtraFxChar = false;
|
||||||
|
auto passRandSeed = randSeed;
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
auto xa = startX;
|
auto xa = startX;
|
||||||
auto xy = startY;
|
auto xy = startY;
|
||||||
@ -282,20 +314,20 @@ namespace Components
|
|||||||
subtitleAllowGlow = false;
|
subtitleAllowGlow = false;
|
||||||
if (colorIndex == TEXT_COLOR_DEFAULT)
|
if (colorIndex == TEXT_COLOR_DEFAULT)
|
||||||
{
|
{
|
||||||
currentColor = color.packed;
|
currentColor = color;
|
||||||
}
|
}
|
||||||
else if (renderFlags & Game::TEXT_RENDERFLAG_SUBTITLETEXT && colorIndex == TEXT_COLOR_GREEN)
|
else if (renderFlags & Game::TEXT_RENDERFLAG_SUBTITLETEXT && colorIndex == TEXT_COLOR_GREEN)
|
||||||
{
|
{
|
||||||
constexpr Game::GfxColor altColor{ MY_ALTCOLOR_TWO };
|
constexpr Game::GfxColor altColor{ MY_ALTCOLOR_TWO };
|
||||||
subtitleAllowGlow = true;
|
subtitleAllowGlow = true;
|
||||||
// Swap r and b for whatever reason
|
// Swap r and b for whatever reason
|
||||||
currentColor = ColorRgba(altColor.array[2], altColor.array[1], altColor.array[0], Game::ModulateByteColors(altColor.array[3], color.array[3]));
|
currentColor.packed = ColorRgba(altColor.array[2], altColor.array[1], altColor.array[0], Game::ModulateByteColors(altColor.array[3], color.array[3]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const Game::GfxColor colorTableColor{ (*currentColorTable)[colorIndex] };
|
const Game::GfxColor colorTableColor{ (*currentColorTable)[colorIndex] };
|
||||||
// Swap r and b for whatever reason
|
// Swap r and b for whatever reason
|
||||||
currentColor = ColorRgba(colorTableColor.array[2], colorTableColor.array[1], colorTableColor.array[0], color.array[3]);
|
currentColor.packed = ColorRgba(colorTableColor.array[2], colorTableColor.array[1], colorTableColor.array[0], color.array[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
curText++;
|
curText++;
|
||||||
@ -303,11 +335,12 @@ namespace Components
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto finalColor = currentColor;
|
||||||
|
|
||||||
if(letter == '^' && (*curText == '\x01' || *curText == '\x02'))
|
if(letter == '^' && (*curText == '\x01' || *curText == '\x02'))
|
||||||
{
|
{
|
||||||
float xRot, yRot;
|
|
||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
||||||
xa += DrawHudIcon(curText, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, currentColor);
|
xa += DrawHudIcon(curText, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, finalColor.packed);
|
||||||
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
xa += xScale * padding;
|
xa += xScale * padding;
|
||||||
@ -321,9 +354,8 @@ namespace Components
|
|||||||
std::string fontIconName;
|
std::string fontIconName;
|
||||||
if(IsFontIcon(curText, fontIconName))
|
if(IsFontIcon(curText, fontIconName))
|
||||||
{
|
{
|
||||||
float xRot, yRot;
|
|
||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
||||||
xa += DrawFontIcon(fontIconName, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, currentColor);
|
xa += DrawFontIcon(fontIconName, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, ColorRgba(255, 255, 255, finalColor.array[3]));
|
||||||
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
xa += xScale * padding;
|
xa += xScale * padding;
|
||||||
@ -335,27 +367,101 @@ namespace Components
|
|||||||
|
|
||||||
if(drawRandomCharAtEnd && maxLengthRemaining == 1)
|
if(drawRandomCharAtEnd && maxLengthRemaining == 1)
|
||||||
{
|
{
|
||||||
|
letter = R_FontGetRandomLetter(Game::RandWithSeed(&passRandSeed));
|
||||||
|
|
||||||
|
if(Game::RandWithSeed(&passRandSeed) % 2)
|
||||||
|
{
|
||||||
|
drawExtraFxChar = true;
|
||||||
|
letter = 'O';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto skipDrawing = false;
|
||||||
|
if(decaying)
|
||||||
|
{
|
||||||
|
char decayAlpha;
|
||||||
|
Game::GetDecayingLetterInfo(letter, &passRandSeed, decayTimeElapsed, fxBirthTime, fxDecayDuration, currentColor.array[3], &skipDrawing, &decayAlpha, &letter, &drawExtraFxChar);
|
||||||
|
finalColor.array[3] = decayAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drawExtraFxChar)
|
||||||
|
{
|
||||||
|
auto tempSeed = passRandSeed;
|
||||||
|
extraFxChar = Game::RandWithSeed(&tempSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto glyph = Game::R_GetCharacterGlyph(font, letter);
|
||||||
|
auto xAdj = static_cast<float>(glyph->x0) * xScale;
|
||||||
|
auto yAdj = static_cast<float>(glyph->y0) * yScale;
|
||||||
|
|
||||||
|
if(!skipDrawing)
|
||||||
|
{
|
||||||
if (passes[passIndex] == Game::FONTPASS_NORMAL)
|
if (passes[passIndex] == Game::FONTPASS_NORMAL)
|
||||||
{
|
{
|
||||||
|
if (renderFlags & Game::TEXT_RENDERFLAG_DROPSHADOW)
|
||||||
|
{
|
||||||
|
auto ofs = 1.0f;
|
||||||
|
if (renderFlags & Game::TEXT_RENDERFLAG_DROPSHADOW_EXTRA)
|
||||||
|
ofs += 1.0f;
|
||||||
|
|
||||||
|
xRot = xa + xAdj + ofs;
|
||||||
|
yRot = xy + yAdj + ofs;
|
||||||
|
RotateXY(cosAngle, sinAngle, startX, startY, xRot, yRot, &xRot, &yRot);
|
||||||
|
if (drawExtraFxChar)
|
||||||
|
DrawTextFxExtraCharacter(fxMaterial, extraFxChar, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, dropShadowColor.packed);
|
||||||
|
else
|
||||||
|
Game::RB_DrawChar(material, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, glyph, dropShadowColor.packed);
|
||||||
|
}
|
||||||
|
|
||||||
|
RotateXY(cosAngle, sinAngle, startX, startY, xa + xAdj, xy + yAdj, &xRot, &yRot);
|
||||||
|
if (drawExtraFxChar)
|
||||||
|
DrawTextFxExtraCharacter(fxMaterial, extraFxChar, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, finalColor.packed);
|
||||||
|
else
|
||||||
|
Game::RB_DrawChar(material, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, glyph, finalColor.packed);
|
||||||
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
if (renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
||||||
{
|
{
|
||||||
float xRot, yRot;
|
|
||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
||||||
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
||||||
}
|
}
|
||||||
|
|
||||||
float xRot, yRot;
|
|
||||||
auto glyph = Game::R_GetCharacterGlyph(font, letter);
|
|
||||||
auto xAdj = glyph->x0 * xScale;
|
|
||||||
auto yAdj = glyph->y0 * yScale;
|
|
||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa + xAdj, xy + yAdj, &xRot, &yRot);
|
|
||||||
Game::RB_DrawChar(material, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale /** 1.75f*/, static_cast<float>(glyph->pixelHeight) * yScale /** 1.125f*/, sinAngle, cosAngle, glyph, currentColor);
|
|
||||||
|
|
||||||
xa += static_cast<float>(glyph->dx) * xScale;
|
|
||||||
}
|
}
|
||||||
|
else if(passes[passIndex] == Game::FONTPASS_OUTLINE)
|
||||||
|
{
|
||||||
|
auto outlineSize = 1.0f;
|
||||||
|
if (renderFlags & Game::TEXT_RENDERFLAG_OUTLINE_EXTRA)
|
||||||
|
outlineSize = 1.3f;
|
||||||
|
|
||||||
|
for (const auto offset : MY_OFFSETS)
|
||||||
|
{
|
||||||
|
RotateXY(cosAngle, sinAngle, startX, startY, xa + xAdj + outlineSize * offset[0], xy + yAdj + outlineSize * offset[1], &xRot, &yRot);
|
||||||
|
if (drawExtraFxChar)
|
||||||
|
DrawTextFxExtraCharacter(fxMaterial, extraFxChar, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, dropShadowColor.packed);
|
||||||
|
else
|
||||||
|
Game::RB_DrawChar(material, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, glyph, dropShadowColor.packed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(passes[passIndex] == Game::FONTPASS_GLOW && ((renderFlags & Game::TEXT_RENDERFLAG_SUBTITLETEXT) == 0 || subtitleAllowGlow))
|
||||||
|
{
|
||||||
|
GlowColor(&finalColor, finalColor, glowForcedColor, renderFlags);
|
||||||
|
|
||||||
|
for (const auto offset : MY_OFFSETS)
|
||||||
|
{
|
||||||
|
RotateXY(cosAngle, sinAngle, startX, startY, xa + xAdj + 2.0f * offset[0] * xScale, xy + yAdj + 2.0f * offset[1] * yScale, &xRot, &yRot);
|
||||||
|
if (drawExtraFxChar)
|
||||||
|
DrawTextFxExtraCharacter(fxMaterialGlow, extraFxChar, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, finalColor.packed);
|
||||||
|
else
|
||||||
|
Game::RB_DrawChar(glowMaterial, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, glyph, finalColor.packed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(forceMonospace)
|
||||||
|
xa += monospaceWidth * xScale;
|
||||||
|
else
|
||||||
|
xa += static_cast<float>(glyph->dx) * xScale;
|
||||||
|
|
||||||
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
|
xa += xScale * padding;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
maxLengthRemaining--;
|
maxLengthRemaining--;
|
||||||
@ -363,7 +469,6 @@ namespace Components
|
|||||||
|
|
||||||
if(renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
if(renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
||||||
{
|
{
|
||||||
float xRot, yRot;
|
|
||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
||||||
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,13 @@ namespace Components
|
|||||||
static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1);
|
static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1);
|
||||||
static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6;
|
static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6;
|
||||||
static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041;
|
static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041;
|
||||||
|
static constexpr float MY_OFFSETS[4][2]
|
||||||
|
{
|
||||||
|
{-1.0f, -1.0f},
|
||||||
|
{-1.0f, 1.0f},
|
||||||
|
{1.0f, -1.0f},
|
||||||
|
{1.0f, 1.0f},
|
||||||
|
};
|
||||||
|
|
||||||
static unsigned colorTableDefault[TEXT_COLOR_COUNT];
|
static unsigned colorTableDefault[TEXT_COLOR_COUNT];
|
||||||
static unsigned colorTableNew[TEXT_COLOR_COUNT];
|
static unsigned colorTableNew[TEXT_COLOR_COUNT];
|
||||||
@ -72,6 +79,9 @@ namespace Components
|
|||||||
static float GetMonospaceWidth(Game::Font_s* font, int rendererFlags);
|
static float GetMonospaceWidth(Game::Font_s* font, int rendererFlags);
|
||||||
static bool IsFontIcon(const char*& text, std::string& fontIconName);
|
static bool IsFontIcon(const char*& text, std::string& fontIconName);
|
||||||
static Game::GfxImage* GetFontIconColorMap(Game::Material* fontIconMaterial);
|
static Game::GfxImage* GetFontIconColorMap(Game::Material* fontIconMaterial);
|
||||||
|
static void GlowColor(Game::GfxColor* result, Game::GfxColor baseColor, Game::GfxColor forcedGlowColor, int renderFlags);
|
||||||
|
static unsigned R_FontGetRandomLetter(int seed);
|
||||||
|
static void DrawTextFxExtraCharacter(Game::Material* material, int charIndex, float x, float y, float w, float h, float sinAngle, float cosAngle, unsigned color);
|
||||||
static float DrawFontIcon(const std::string& fontIconName, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, float yScale, unsigned color);
|
static float DrawFontIcon(const std::string& fontIconName, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, float yScale, unsigned color);
|
||||||
static float DrawHudIcon(const char*& text, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, float yScale, unsigned color);
|
static float DrawHudIcon(const char*& text, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, float yScale, unsigned color);
|
||||||
static void RotateXY(float cosAngle, float sinAngle, float pivotX, float pivotY, float x, float y, float* outX, float* outY);
|
static void RotateXY(float cosAngle, float sinAngle, float pivotX, float pivotY, float x, float y, float* outX, float* outY);
|
||||||
|
@ -336,6 +336,8 @@ namespace Game
|
|||||||
RB_DrawCursor_t RB_DrawCursor = RB_DrawCursor_t(0x534EA0);
|
RB_DrawCursor_t RB_DrawCursor = RB_DrawCursor_t(0x534EA0);
|
||||||
|
|
||||||
Byte4PackRgba_t Byte4PackRgba = Byte4PackRgba_t(0x4FE910);
|
Byte4PackRgba_t Byte4PackRgba = Byte4PackRgba_t(0x4FE910);
|
||||||
|
RandWithSeed_t RandWithSeed = RandWithSeed_t(0x495580);
|
||||||
|
GetDecayingLetterInfo_t GetDecayingLetterInfo = GetDecayingLetterInfo_t(0x5351C0);
|
||||||
|
|
||||||
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
||||||
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
||||||
|
@ -783,6 +783,12 @@ namespace Game
|
|||||||
typedef void(__cdecl* Byte4PackRgba_t)(const float* from, char* to);
|
typedef void(__cdecl* Byte4PackRgba_t)(const float* from, char* to);
|
||||||
extern Byte4PackRgba_t Byte4PackRgba;
|
extern Byte4PackRgba_t Byte4PackRgba;
|
||||||
|
|
||||||
|
typedef int(__cdecl* RandWithSeed_t)(int* seed);
|
||||||
|
extern RandWithSeed_t RandWithSeed;
|
||||||
|
|
||||||
|
typedef void(__cdecl* GetDecayingLetterInfo_t)(unsigned int letter, int* randSeed, int decayTimeElapsed, int fxBirthTime, int fxDecayDuration, unsigned __int8 alpha, bool* resultSkipDrawing, char* resultAlpha, unsigned int* resultLetter, bool* resultDrawExtraFxChar);
|
||||||
|
extern GetDecayingLetterInfo_t GetDecayingLetterInfo;
|
||||||
|
|
||||||
extern XAssetHeader* DB_XAssetPool;
|
extern XAssetHeader* DB_XAssetPool;
|
||||||
extern unsigned int* g_poolSize;
|
extern unsigned int* g_poolSize;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user