- fixed startup and font init crashes.
This commit is contained in:
parent
028cc6a828
commit
3fd4d08004
15 changed files with 271 additions and 132 deletions
|
|
@ -677,7 +677,7 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, unsigne
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, bool local_origin)
|
||||
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin, double flatscale)
|
||||
{
|
||||
float fU1, fU2, fV1, fV2;
|
||||
|
||||
|
|
@ -690,27 +690,83 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTextu
|
|||
dg.mTexture = src;
|
||||
dg.mFlags = DTF_Wrap;
|
||||
|
||||
// scaling is not used here.
|
||||
if (!local_origin)
|
||||
{
|
||||
fU1 = float(left) / (float)src->GetDisplayWidth();
|
||||
fV1 = float(top) / (float)src->GetDisplayHeight();
|
||||
fU2 = float(right) / (float)src->GetDisplayWidth();
|
||||
fV2 = float(bottom) / (float)src->GetDisplayHeight();
|
||||
}
|
||||
else
|
||||
float fs = 1.f / float(flatscale);
|
||||
bool flipc = false;
|
||||
switch (local_origin)
|
||||
{
|
||||
case 0:
|
||||
fU1 = float(left) / (float)src->GetDisplayWidth() * fs;
|
||||
fV1 = float(top) / (float)src->GetDisplayHeight() * fs;
|
||||
fU2 = float(right) / (float)src->GetDisplayWidth() * fs;
|
||||
fV2 = float(bottom) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fU1 = 0;
|
||||
fV1 = 0;
|
||||
fU2 = float(right - left) / (float)src->GetDisplayWidth();
|
||||
fV2 = float(bottom - top) / (float)src->GetDisplayHeight();
|
||||
fU2 = float(right - left) / (float)src->GetDisplayWidth() * fs;
|
||||
fV2 = float(bottom - top) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
// The following are for drawing frames with elements of pnly one orientation
|
||||
case 2: // flip vertically
|
||||
fU1 = 0;
|
||||
fV2 = 0;
|
||||
fU2 = float(right - left) / (float)src->GetDisplayWidth() * fs;
|
||||
fV1 = float(bottom - top) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
case 3: // flip horizontally
|
||||
fU2 = 0;
|
||||
fV1 = 0;
|
||||
fU1 = float(right - left) / (float)src->GetDisplayWidth() * fs;
|
||||
fV2 = float(bottom - top) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
case 4: // flip vertically and horizontally
|
||||
fU2 = 0;
|
||||
fV2 = 0;
|
||||
fU1 = float(right - left) / (float)src->GetDisplayWidth() * fs;
|
||||
fV1 = float(bottom - top) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
|
||||
case 5: // flip coordinates
|
||||
fU1 = 0;
|
||||
fV1 = 0;
|
||||
fU2 = float(bottom - top) / (float)src->GetDisplayWidth() * fs;
|
||||
fV2 = float(right - left) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
case 6: // flip coordinates and vertically
|
||||
fU2 = 0;
|
||||
fV1 = 0;
|
||||
fU1 = float(bottom - top) / (float)src->GetDisplayWidth() * fs;
|
||||
fV2 = float(right - left) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
case 7: // flip coordinates and horizontally
|
||||
fU1 = 0;
|
||||
fV2 = 0;
|
||||
fU2 = float(bottom - top) / (float)src->GetDisplayWidth() * fs;
|
||||
fV1 = float(right - left) / (float)src->GetDisplayHeight() * fs;
|
||||
break;
|
||||
|
||||
}
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
auto ptr = &mVertices[dg.mVertIndex];
|
||||
|
||||
ptr->Set(left, top, 0, fU1, fV1, 0xffffffff); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++;
|
||||
if (local_origin < 4)
|
||||
{
|
||||
ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->Set(left, bottom, 0, fU2, fV1, 0xffffffff); ptr++;
|
||||
ptr->Set(right, top, 0, fU1, fV2, 0xffffffff); ptr++;
|
||||
}
|
||||
ptr->Set(right, bottom, 0, fU2, fV2, 0xffffffff); ptr++;
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
|
|
@ -721,11 +777,11 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTextu
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, FRenderStyle *style)
|
||||
void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, FRenderStyle *style, bool prepend)
|
||||
{
|
||||
RenderCommand dg;
|
||||
|
||||
|
|
@ -741,7 +797,13 @@ void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, F
|
|||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
|
||||
AddCommand(&dg);
|
||||
if (!prepend) AddCommand(&dg);
|
||||
else
|
||||
{
|
||||
// Only needed by Raze's fullscreen blends because they are being calculated late when half of the 2D content has already been submitted,
|
||||
// This ensures they are below the HUD, not above it.
|
||||
mData.Insert(0, dg);
|
||||
}
|
||||
}
|
||||
|
||||
void F2DDrawer::ClearScreen(PalEntry color)
|
||||
|
|
|
|||
|
|
@ -182,9 +182,9 @@ public:
|
|||
void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2);
|
||||
void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex,
|
||||
int clipx1, int clipy1, int clipx2, int clipy2);
|
||||
void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, bool local_origin = false);
|
||||
void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin = false, double flatscale = 1.0);
|
||||
|
||||
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr);
|
||||
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr, bool prepend = false);
|
||||
void ClearScreen(PalEntry color = 0xff000000);
|
||||
void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h);
|
||||
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ struct FRemapTable
|
|||
int Index;
|
||||
int NumEntries; // # of elements in this table (usually 256)
|
||||
bool Inactive = false; // This table is inactive and should be treated as if it was passed as NULL
|
||||
bool TwodOnly = false; // Only used for 2D rendering
|
||||
bool ForFont = false; // Mark font translations because they may require different handling than the ones for sprites-
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -372,10 +372,6 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
|
||||
FixXMoves();
|
||||
}
|
||||
|
||||
if (!noTranslate) LoadTranslations();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale)
|
||||
|
|
@ -443,16 +439,13 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
|||
if (lump != nullptr)
|
||||
{
|
||||
auto pic = (*lump)->GetTexture();
|
||||
|
||||
auto b = pic->Get8BitPixels(false);
|
||||
|
||||
Chars[i].OriginalPic = MakeGameTexture(pic, nullptr, ETextureType::FontChar);
|
||||
Chars[i].OriginalPic = (*lump)->GetUseType() == ETextureType::FontChar? (*lump) : MakeGameTexture(pic, nullptr, ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(*lump);
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(pic->GetImage())), nullptr, ETextureType::FontChar);
|
||||
Chars[i].TranslatedPic->CopySize(*lump);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||
if (Chars[i].OriginalPic != *lump) TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
Chars[i].XMove = width;
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ public:
|
|||
FHexFont (const char *fontname, int lump)
|
||||
: FFont(lump)
|
||||
{
|
||||
const int spacing = 9;
|
||||
assert(lump >= 0);
|
||||
|
||||
FontName = fontname;
|
||||
|
|
@ -258,8 +259,22 @@ public:
|
|||
SpaceWidth = 9;
|
||||
GlobalKerning = 0;
|
||||
translateUntranslated = true;
|
||||
|
||||
LoadTranslations();
|
||||
|
||||
Chars.Resize(LastChar - FirstChar + 1);
|
||||
for (int i = FirstChar; i <= LastChar; i++)
|
||||
{
|
||||
if (hexdata.glyphmap[i] > 0)
|
||||
{
|
||||
auto offset = hexdata.glyphmap[i];
|
||||
int size = hexdata.glyphdata[offset] / 16;
|
||||
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar(&hexdata.glyphdata[offset + 1], size, size * 9, 16)), nullptr, ETextureType::FontChar);
|
||||
Chars[i - FirstChar].OriginalPic = Chars[i - FirstChar].TranslatedPic;
|
||||
Chars[i - FirstChar].XMove = size * spacing;
|
||||
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
}
|
||||
else Chars[i - FirstChar].XMove = spacing;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -270,7 +285,6 @@ public:
|
|||
|
||||
void LoadTranslations()
|
||||
{
|
||||
const int spacing = 9;
|
||||
double luminosity[256];
|
||||
|
||||
memset (PatchRemap, 0, 256);
|
||||
|
|
@ -282,20 +296,6 @@ public:
|
|||
}
|
||||
ActiveColors = 18;
|
||||
|
||||
Chars.Resize(LastChar - FirstChar + 1);
|
||||
for (int i = FirstChar; i <= LastChar; i++)
|
||||
{
|
||||
if (hexdata.glyphmap[i] > 0)
|
||||
{
|
||||
auto offset = hexdata.glyphmap[i];
|
||||
int size = hexdata.glyphdata[offset] / 16;
|
||||
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16)), nullptr, ETextureType::FontChar);
|
||||
Chars[i - FirstChar].XMove = size * spacing;
|
||||
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
}
|
||||
else Chars[i - FirstChar].XMove = spacing;
|
||||
|
||||
}
|
||||
BuildTranslations (luminosity, nullptr, &TranslationParms[1][0], ActiveColors, nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +317,7 @@ public:
|
|||
FHexFont2(const char *fontname, int lump)
|
||||
: FFont(lump)
|
||||
{
|
||||
const int spacing = 9;
|
||||
assert(lump >= 0);
|
||||
|
||||
FontName = fontname;
|
||||
|
|
@ -330,8 +331,21 @@ public:
|
|||
SpaceWidth = 9;
|
||||
GlobalKerning = -1;
|
||||
translateUntranslated = true;
|
||||
Chars.Resize(LastChar - FirstChar + 1);
|
||||
for (int i = FirstChar; i <= LastChar; i++)
|
||||
{
|
||||
if (hexdata.glyphmap[i] > 0)
|
||||
{
|
||||
auto offset = hexdata.glyphmap[i];
|
||||
int size = hexdata.glyphdata[offset] / 16;
|
||||
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18)), nullptr, ETextureType::FontChar);
|
||||
Chars[i - FirstChar].OriginalPic = Chars[i - FirstChar].TranslatedPic;
|
||||
Chars[i - FirstChar].XMove = size * spacing;
|
||||
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
}
|
||||
else Chars[i - FirstChar].XMove = spacing;
|
||||
|
||||
LoadTranslations();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -342,7 +356,6 @@ public:
|
|||
|
||||
void LoadTranslations() override
|
||||
{
|
||||
const int spacing = 9;
|
||||
double luminosity[256];
|
||||
|
||||
memset(PatchRemap, 0, 256);
|
||||
|
|
@ -354,20 +367,6 @@ public:
|
|||
}
|
||||
ActiveColors = 18;
|
||||
|
||||
Chars.Resize(LastChar - FirstChar + 1);
|
||||
for (int i = FirstChar; i <= LastChar; i++)
|
||||
{
|
||||
if (hexdata.glyphmap[i] > 0)
|
||||
{
|
||||
auto offset = hexdata.glyphmap[i];
|
||||
int size = hexdata.glyphdata[offset] / 16;
|
||||
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18)), nullptr, ETextureType::FontChar);
|
||||
Chars[i - FirstChar].XMove = size * spacing;
|
||||
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
}
|
||||
else Chars[i - FirstChar].XMove = spacing;
|
||||
|
||||
}
|
||||
BuildTranslations(luminosity, nullptr, &TranslationParms[0][0], ActiveColors, nullptr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
|||
FirstChar = LastChar = 'A';
|
||||
Chars.Resize(1);
|
||||
Chars[0].TranslatedPic = pic;
|
||||
Chars[0].OriginalPic = pic;
|
||||
|
||||
// Only one color range. Don't bother with the others.
|
||||
ActiveColors = 0;
|
||||
|
|
@ -255,7 +256,6 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data)
|
|||
LastChar = 255; // This is to allow LoadTranslations to function. The way this is all set up really needs to be changed.
|
||||
GlobalKerning = 0;
|
||||
translateUntranslated = true;
|
||||
LoadTranslations();
|
||||
LastChar = 0x2122;
|
||||
|
||||
// Move the Windows-1252 characters to their proper place.
|
||||
|
|
@ -350,10 +350,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
|
|||
if (destSize <= 0)
|
||||
{
|
||||
Chars[i].TranslatedPic = nullptr;
|
||||
Chars[i].OriginalPic = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)), nullptr, ETextureType::FontChar);
|
||||
Chars[i].OriginalPic = Chars[i].TranslatedPic;
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
do
|
||||
{
|
||||
|
|
@ -376,8 +378,6 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
|
|||
I_Error ("Overflow decompressing char %d (%c) of %s", i, i, FontName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
LoadTranslations();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -489,6 +489,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
|
|||
-(int8_t)chardata[chari+4] // y offset
|
||||
)), nullptr, ETextureType::FontChar);
|
||||
Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
|
||||
Chars[chardata[chari] - FirstChar].OriginalPic = tex;
|
||||
TexMan.AddGameTexture(tex);
|
||||
}
|
||||
|
||||
|
|
@ -506,7 +507,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
|
|||
}
|
||||
|
||||
FixXMoves();
|
||||
LoadTranslations();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -555,6 +555,7 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
|
|||
if(!Chars[i].TranslatedPic)
|
||||
{
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)), nullptr, ETextureType::FontChar);
|
||||
Chars[i].OriginalPic = Chars[i].TranslatedPic;
|
||||
Chars[i].XMove = SpaceWidth;
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,10 +140,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture
|
|||
{
|
||||
ActiveColors = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadTranslations();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
|
|
@ -728,13 +728,6 @@ void V_InitFonts()
|
|||
OriginalSmallFont = new FFont("OriginalSmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, true);
|
||||
}
|
||||
|
||||
if (SmallFont)
|
||||
{
|
||||
uint32_t colors[256] = {};
|
||||
SmallFont->RecordAllTextureColors(colors);
|
||||
if (OriginalSmallFont != nullptr) OriginalSmallFont->SetDefaultTranslation(colors);
|
||||
NewSmallFont->SetDefaultTranslation(colors);
|
||||
}
|
||||
|
||||
if (!(SmallFont2 = V_GetFont("SmallFont2"))) // Only used by Strife
|
||||
{
|
||||
|
|
@ -770,13 +763,6 @@ void V_InitFonts()
|
|||
OriginalBigFont = new FFont("OriginalBigFont", nullptr, "bigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1, -1, false, true);
|
||||
}
|
||||
|
||||
if (BigFont)
|
||||
{
|
||||
uint32_t colors[256] = {};
|
||||
BigFont->RecordAllTextureColors(colors);
|
||||
if (OriginalBigFont != nullptr) OriginalBigFont->SetDefaultTranslation(colors);
|
||||
}
|
||||
|
||||
// let PWAD BIGFONTs override the stock BIGUPPER font. (This check needs to be made smarter.)
|
||||
if (BigUpper && BigFont->Type != FFont::Folder && BigUpper->Type == FFont::Folder)
|
||||
{
|
||||
|
|
@ -828,6 +814,28 @@ void V_InitFonts()
|
|||
AlternativeSmallFont = OriginalSmallFont;
|
||||
}
|
||||
|
||||
void V_LoadTranslations()
|
||||
{
|
||||
for (auto font = FFont::FirstFont; font; font = font->Next)
|
||||
{
|
||||
if (!font->noTranslate) font->LoadTranslations();
|
||||
else font->ActiveColors = 0;
|
||||
}
|
||||
if (BigFont)
|
||||
{
|
||||
uint32_t colors[256] = {};
|
||||
BigFont->RecordAllTextureColors(colors);
|
||||
if (OriginalBigFont != nullptr) OriginalBigFont->SetDefaultTranslation(colors);
|
||||
}
|
||||
if (SmallFont)
|
||||
{
|
||||
uint32_t colors[256] = {};
|
||||
SmallFont->RecordAllTextureColors(colors);
|
||||
if (OriginalSmallFont != nullptr) OriginalSmallFont->SetDefaultTranslation(colors);
|
||||
NewSmallFont->SetDefaultTranslation(colors);
|
||||
}
|
||||
}
|
||||
|
||||
void V_ClearFonts()
|
||||
{
|
||||
while (FFont::FirstFont != nullptr)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ using GlyphSet = TMap<int, FGameTexture*>;
|
|||
|
||||
class FFont
|
||||
{
|
||||
friend void V_LoadTranslations();
|
||||
public:
|
||||
|
||||
enum EFontType
|
||||
|
|
@ -154,7 +155,7 @@ protected:
|
|||
int TranslationType = 0;
|
||||
int Displacement = 0;
|
||||
char Cursor;
|
||||
bool noTranslate;
|
||||
bool noTranslate = false;
|
||||
bool translateUntranslated;
|
||||
bool MixedCase = false;
|
||||
bool forceremap = false;
|
||||
|
|
@ -165,7 +166,7 @@ protected:
|
|||
int XMove = INT_MIN;
|
||||
};
|
||||
TArray<CharData> Chars;
|
||||
int ActiveColors;
|
||||
int ActiveColors = -1;
|
||||
TArray<int> Translations;
|
||||
uint8_t PatchRemap[256];
|
||||
|
||||
|
|
@ -191,5 +192,6 @@ EColorRange V_ParseFontColor (const uint8_t *&color_value, int normalcolor, int
|
|||
FFont *V_GetFont(const char *fontname, const char *fontlumpname = nullptr);
|
||||
void V_InitFontColors();
|
||||
char* CleanseString(char* str);
|
||||
void V_LoadTranslations();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -305,8 +305,8 @@ public:
|
|||
FShader *BindEffect(int effect, EPassType passType);
|
||||
FShader *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||
|
||||
private:
|
||||
void SetActiveShader(FShader *sh);
|
||||
private:
|
||||
|
||||
FShader *mActiveShader = nullptr;
|
||||
TArray<FShaderCollection*> mPassShaders;
|
||||
|
|
|
|||
229
src/common/rendering/hwrenderer/hw_draw2d.cpp
Normal file
229
src/common/rendering/hwrenderer/hw_draw2d.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
** hw_draw2d.cpp
|
||||
** 2d drawer Renderer interface
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2018-2019 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "v_video.h"
|
||||
#include "cmdlib.h"
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "hw_clock.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "r_videoscale.h"
|
||||
#include "v_draw.h"
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer for 2D drawer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
class F2DVertexBuffer
|
||||
{
|
||||
IVertexBuffer *mVertexBuffer;
|
||||
IIndexBuffer *mIndexBuffer;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
F2DVertexBuffer()
|
||||
{
|
||||
mVertexBuffer = screen->CreateVertexBuffer();
|
||||
mIndexBuffer = screen->CreateIndexBuffer();
|
||||
|
||||
static const FVertexBufferAttribute format[] = {
|
||||
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(F2DDrawer::TwoDVertex, x) },
|
||||
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(F2DDrawer::TwoDVertex, u) },
|
||||
{ 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(F2DDrawer::TwoDVertex, color0) }
|
||||
};
|
||||
mVertexBuffer->SetFormat(1, 3, sizeof(F2DDrawer::TwoDVertex), format);
|
||||
}
|
||||
~F2DVertexBuffer()
|
||||
{
|
||||
delete mIndexBuffer;
|
||||
delete mVertexBuffer;
|
||||
}
|
||||
|
||||
void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount)
|
||||
{
|
||||
mVertexBuffer->SetData(vertcount * sizeof(*vertices), vertices, false);
|
||||
mIndexBuffer->SetData(indexcount * sizeof(unsigned int), indices, false);
|
||||
}
|
||||
|
||||
std::pair<IVertexBuffer *, IIndexBuffer *> GetBufferObjects() const
|
||||
{
|
||||
return std::make_pair(mVertexBuffer, mIndexBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Draws the 2D stuff. This is the version for OpenGL 3 and later.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE)
|
||||
|
||||
void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||
{
|
||||
twoD.Clock();
|
||||
|
||||
const auto &mScreenViewport = screen->mScreenViewport;
|
||||
state.SetViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
screen->mViewpoints->Set2D(state, twod->GetWidth(), twod->GetHeight());
|
||||
|
||||
state.EnableDepthTest(false);
|
||||
state.EnableMultisampling(false);
|
||||
state.EnableLineSmooth(gl_aalines);
|
||||
|
||||
auto &vertices = drawer->mVertices;
|
||||
auto &indices = drawer->mIndices;
|
||||
auto &commands = drawer->mData;
|
||||
|
||||
if (commands.Size() == 0)
|
||||
{
|
||||
twoD.Unclock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawer->mIsFirstPass)
|
||||
{
|
||||
for (auto &v : vertices)
|
||||
{
|
||||
// Change from BGRA to RGBA
|
||||
std::swap(v.color0.r, v.color0.b);
|
||||
}
|
||||
}
|
||||
F2DVertexBuffer vb;
|
||||
vb.UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
|
||||
state.SetVertexBuffer(&vb);
|
||||
state.EnableFog(false);
|
||||
|
||||
for(auto &cmd : commands)
|
||||
{
|
||||
|
||||
int gltrans = -1;
|
||||
state.SetRenderStyle(cmd.mRenderStyle);
|
||||
state.EnableBrightmap(!(cmd.mRenderStyle.Flags & STYLEF_ColorIsFixed));
|
||||
state.EnableFog(2); // Special 2D mode 'fog'.
|
||||
|
||||
state.SetTextureMode(cmd.mDrawMode);
|
||||
|
||||
int sciX, sciY, sciW, sciH;
|
||||
if (cmd.mFlags & F2DDrawer::DTF_Scissor)
|
||||
{
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
// Note that the origin here is the lower left corner!
|
||||
sciX = screen->ScreenToWindowX(cmd.mScissor[0]);
|
||||
sciY = screen->ScreenToWindowY(cmd.mScissor[3]);
|
||||
sciW = screen->ScreenToWindowX(cmd.mScissor[2]) - sciX;
|
||||
sciH = screen->ScreenToWindowY(cmd.mScissor[1]) - sciY;
|
||||
}
|
||||
else
|
||||
{
|
||||
sciX = sciY = sciW = sciH = -1;
|
||||
}
|
||||
state.SetScissor(sciX, sciY, sciW, sciH);
|
||||
|
||||
if (cmd.mSpecialColormap[0].a != 0)
|
||||
{
|
||||
state.SetTextureMode(TM_FIXEDCOLORMAP);
|
||||
state.SetObjectColor(cmd.mSpecialColormap[0]);
|
||||
state.SetAddColor(cmd.mSpecialColormap[1]);
|
||||
}
|
||||
state.SetFog(cmd.mColor1, 0);
|
||||
state.SetColor(1, 1, 1, 1, cmd.mDesaturate);
|
||||
|
||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
|
||||
if (cmd.mTexture != nullptr && cmd.mTexture->isValid())
|
||||
{
|
||||
auto flags = cmd.mTexture->GetUseType() >= ETextureType::Special? UF_None : cmd.mTexture->GetUseType() == ETextureType::FontChar? UF_Font : UF_Texture;
|
||||
state.SetMaterial(cmd.mTexture, flags, 0, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1);
|
||||
state.EnableTexture(true);
|
||||
|
||||
// Canvas textures are stored upside down
|
||||
if (cmd.mTexture->isHardwareCanvas())
|
||||
{
|
||||
state.mTextureMatrix.loadIdentity();
|
||||
state.mTextureMatrix.scale(1.f, -1.f, 1.f);
|
||||
state.mTextureMatrix.translate(0.f, 1.f, 0.0f);
|
||||
state.EnableTextureMatrix(true);
|
||||
}
|
||||
if (cmd.mFlags & F2DDrawer::DTF_Burn)
|
||||
{
|
||||
state.SetEffect(EFF_BURN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state.EnableTexture(false);
|
||||
}
|
||||
|
||||
switch (cmd.mType)
|
||||
{
|
||||
default:
|
||||
case F2DDrawer::DrawTypeTriangles:
|
||||
state.DrawIndexed(DT_Triangles, cmd.mIndexIndex, cmd.mIndexCount);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypeLines:
|
||||
state.Draw(DT_Lines, cmd.mVertIndex, cmd.mVertCount);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypePoints:
|
||||
state.Draw(DT_Points, cmd.mVertIndex, cmd.mVertCount);
|
||||
break;
|
||||
|
||||
}
|
||||
state.SetObjectColor(0xffffffff);
|
||||
state.SetObjectColor2(0);
|
||||
state.SetAddColor(0);
|
||||
state.EnableTextureMatrix(false);
|
||||
state.SetEffect(EFF_NONE);
|
||||
|
||||
}
|
||||
state.SetScissor(-1, -1, -1, -1);
|
||||
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.SetVertexBuffer(screen->mVertexData);
|
||||
state.EnableTexture(true);
|
||||
state.EnableBrightmap(true);
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
state.EnableFog(false);
|
||||
state.ResetColor();
|
||||
drawer->mIsFirstPass = false;
|
||||
twoD.Unclock();
|
||||
}
|
||||
|
|
@ -102,6 +102,8 @@ void AnimTextures::SetSize(int width, int height)
|
|||
{
|
||||
static_cast<AnimTexture*>(tex[0]->GetTexture())->SetFrameSize(width, height);
|
||||
static_cast<AnimTexture*>(tex[1]->GetTexture())->SetFrameSize(width, height);
|
||||
tex[0]->SetSize(width, height);
|
||||
tex[1]->SetSize(width, height);
|
||||
}
|
||||
|
||||
void AnimTextures::SetFrame(const uint8_t *palette, const void* data)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public:
|
|||
|
||||
protected:
|
||||
void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap);
|
||||
void SetupPalette(FileReader &lump);
|
||||
|
||||
uint8_t BitDepth;
|
||||
uint8_t ColorType;
|
||||
|
|
@ -152,11 +153,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height,
|
|||
: FImageSource(lumpnum),
|
||||
BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t palette[256];
|
||||
uint8_t pngpal[256][3];
|
||||
} p;
|
||||
uint8_t trans[256];
|
||||
uint32_t len, id;
|
||||
int i;
|
||||
|
|
@ -210,15 +206,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height,
|
|||
case MAKE_ID('P','L','T','E'):
|
||||
PaletteSize = MIN<int> (len / 3, 256);
|
||||
StartOfPalette = (uint32_t)lump.Tell();
|
||||
lump.Read (p.pngpal, PaletteSize * 3);
|
||||
if (PaletteSize * 3 != (int)len)
|
||||
{
|
||||
lump.Seek (len - PaletteSize * 3, FileReader::SeekCur);
|
||||
}
|
||||
for (i = PaletteSize - 1; i >= 0; --i)
|
||||
{
|
||||
p.palette[i] = MAKERGB(p.pngpal[i][0], p.pngpal[i][1], p.pngpal[i][2]);
|
||||
}
|
||||
lump.Seek(len, FileReader::SeekCur);
|
||||
break;
|
||||
|
||||
case MAKE_ID('t','R','N','S'):
|
||||
|
|
@ -248,9 +236,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height,
|
|||
{
|
||||
bMasked = true;
|
||||
PaletteSize = 256;
|
||||
PaletteMap = (uint8_t*)ImageArena.Alloc(PaletteSize);
|
||||
memcpy (PaletteMap, GPalette.GrayMap, 256);
|
||||
PaletteMap[NonPaletteTrans[0]] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -259,14 +244,11 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height,
|
|||
break;
|
||||
|
||||
case 3: // Paletted
|
||||
PaletteMap = (uint8_t*)ImageArena.Alloc(PaletteSize);
|
||||
MakeRemap ((uint32_t*)GPalette.BaseColors, p.palette, PaletteMap, trans, PaletteSize);
|
||||
for (i = 0; i < PaletteSize; ++i)
|
||||
{
|
||||
if (trans[i] == 0)
|
||||
{
|
||||
bMasked = true;
|
||||
PaletteMap[i] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -281,6 +263,87 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height,
|
|||
}
|
||||
}
|
||||
|
||||
void FPNGTexture::SetupPalette(FileReader &lump)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t palette[256];
|
||||
uint8_t pngpal[256][3];
|
||||
} p;
|
||||
uint8_t trans[256];
|
||||
uint32_t len, id;
|
||||
int i;
|
||||
|
||||
auto pos = lump.Tell();
|
||||
|
||||
memset(trans, 255, 256);
|
||||
|
||||
// Parse pre-IDAT chunks. I skip the CRCs. Is that bad?
|
||||
lump.Seek(33, FileReader::SeekSet);
|
||||
|
||||
lump.Read(&len, 4);
|
||||
lump.Read(&id, 4);
|
||||
while (id != MAKE_ID('I', 'D', 'A', 'T') && id != MAKE_ID('I', 'E', 'N', 'D'))
|
||||
{
|
||||
len = BigLong((unsigned int)len);
|
||||
switch (id)
|
||||
{
|
||||
default:
|
||||
lump.Seek(len, FileReader::SeekCur);
|
||||
break;
|
||||
|
||||
case MAKE_ID('P', 'L', 'T', 'E'):
|
||||
lump.Read(p.pngpal, PaletteSize * 3);
|
||||
if (PaletteSize * 3 != (int)len)
|
||||
{
|
||||
lump.Seek(len - PaletteSize * 3, FileReader::SeekCur);
|
||||
}
|
||||
for (i = PaletteSize - 1; i >= 0; --i)
|
||||
{
|
||||
p.palette[i] = MAKERGB(p.pngpal[i][0], p.pngpal[i][1], p.pngpal[i][2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case MAKE_ID('t', 'R', 'N', 'S'):
|
||||
lump.Read(trans, len);
|
||||
break;
|
||||
}
|
||||
lump.Seek(4, FileReader::SeekCur); // Skip CRC
|
||||
lump.Read(&len, 4);
|
||||
id = MAKE_ID('I', 'E', 'N', 'D');
|
||||
lump.Read(&id, 4);
|
||||
}
|
||||
StartOfIDAT = (uint32_t)lump.Tell() - 8;
|
||||
|
||||
switch (ColorType)
|
||||
{
|
||||
case 0: // Grayscale
|
||||
if (HaveTrans && NonPaletteTrans[0] < 256)
|
||||
{
|
||||
PaletteMap = (uint8_t*)ImageArena.Alloc(PaletteSize);
|
||||
memcpy(PaletteMap, GPalette.GrayMap, 256);
|
||||
PaletteMap[NonPaletteTrans[0]] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // Paletted
|
||||
PaletteMap = (uint8_t*)ImageArena.Alloc(PaletteSize);
|
||||
MakeRemap((uint32_t*)GPalette.BaseColors, p.palette, PaletteMap, trans, PaletteSize);
|
||||
for (i = 0; i < PaletteSize; ++i)
|
||||
{
|
||||
if (trans[i] == 0)
|
||||
{
|
||||
PaletteMap[i] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
lump.Seek(pos, FileReader::SeekSet);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -336,6 +399,7 @@ TArray<uint8_t> FPNGTexture::CreatePalettedPixels(int conversion)
|
|||
{
|
||||
if (conversion != luminance)
|
||||
{
|
||||
if (!PaletteMap) SetupPalette(lfr);
|
||||
ImageHelpers::FlipSquareBlockRemap (Pixels.Data(), Width, PaletteMap);
|
||||
}
|
||||
else if (ColorType == 0)
|
||||
|
|
@ -354,6 +418,7 @@ TArray<uint8_t> FPNGTexture::CreatePalettedPixels(int conversion)
|
|||
TArray<uint8_t> newpix(Width*Height, true);
|
||||
if (conversion != luminance)
|
||||
{
|
||||
if (!PaletteMap) SetupPalette(lfr);
|
||||
ImageHelpers::FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap);
|
||||
}
|
||||
else if (ColorType == 0)
|
||||
|
|
@ -408,6 +473,7 @@ TArray<uint8_t> FPNGTexture::CreatePalettedPixels(int conversion)
|
|||
case 4: // Grayscale + Alpha
|
||||
pitch = Width * 2;
|
||||
backstep = Height * pitch - 2;
|
||||
if (!PaletteMap) SetupPalette(lfr);
|
||||
for (x = Width; x > 0; --x)
|
||||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue