From 3fd4d08004c3bc8cc0e4e0ba77163111b07d4fcb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 4 May 2020 20:06:54 +0200 Subject: [PATCH] - fixed startup and font init crashes. --- src/CMakeLists.txt | 2 +- src/common/2d/v_2ddrawer.cpp | 96 +++++++++++++--- src/common/2d/v_2ddrawer.h | 4 +- src/common/engine/palettecontainer.h | 1 + src/common/fonts/font.cpp | 11 +- src/common/fonts/hexfont.cpp | 65 ++++++----- src/common/fonts/singlelumpfont.cpp | 9 +- src/common/fonts/specialfont.cpp | 4 - src/common/fonts/v_font.cpp | 36 +++--- src/common/fonts/v_font.h | 6 +- src/common/rendering/gl/gl_shader.h | 2 +- .../rendering/hwrenderer/hw_draw2d.cpp | 55 ++++----- src/common/textures/animtexture.cpp | 2 + src/common/textures/formats/pngtexture.cpp | 106 ++++++++++++++---- src/d_main.cpp | 4 + 15 files changed, 271 insertions(+), 132 deletions(-) rename src/{ => common}/rendering/hwrenderer/hw_draw2d.cpp (76%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 126a5fe32..661214bf1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -931,7 +931,6 @@ set (PCH_SOURCES rendering/hwrenderer/hw_models.cpp rendering/hwrenderer/hw_postprocessshader.cpp rendering/hwrenderer/hw_precache.cpp - rendering/hwrenderer/hw_draw2d.cpp rendering/hwrenderer/scene/hw_lighting.cpp rendering/hwrenderer/scene/hw_drawlistadd.cpp rendering/hwrenderer/scene/hw_setcolor.cpp @@ -1114,6 +1113,7 @@ set (PCH_SOURCES common/rendering/v_video.cpp common/rendering/r_thread.cpp common/rendering/r_videoscale.cpp + common/rendering/hwrenderer/hw_draw2d.cpp common/rendering/hwrenderer/data/hw_clock.cpp common/rendering/hwrenderer/data/hw_skydome.cpp common/rendering/hwrenderer/data/flatvertices.cpp diff --git a/src/common/2d/v_2ddrawer.cpp b/src/common/2d/v_2ddrawer.cpp index 08560c35c..665ea3d8c 100644 --- a/src/common/2d/v_2ddrawer.cpp +++ b/src/common/2d/v_2ddrawer.cpp @@ -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) diff --git a/src/common/2d/v_2ddrawer.h b/src/common/2d/v_2ddrawer.h index 93712a8f8..f7a31ac79 100644 --- a/src/common/2d/v_2ddrawer.h +++ b/src/common/2d/v_2ddrawer.h @@ -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); diff --git a/src/common/engine/palettecontainer.h b/src/common/engine/palettecontainer.h index c8c5499d3..f858eefb0 100644 --- a/src/common/engine/palettecontainer.h +++ b/src/common/engine/palettecontainer.h @@ -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: diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index 985ba4981..c8964accf 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -372,10 +372,6 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla FixXMoves(); } - - if (!noTranslate) LoadTranslations(); - - } void FFont::ReadSheetFont(TArray &folderdata, int width, int height, const DVector2 &Scale) @@ -443,16 +439,13 @@ void FFont::ReadSheetFont(TArray &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; diff --git a/src/common/fonts/hexfont.cpp b/src/common/fonts/hexfont.cpp index 812973bba..1c23d3bd0 100644 --- a/src/common/fonts/hexfont.cpp +++ b/src/common/fonts/hexfont.cpp @@ -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); } diff --git a/src/common/fonts/singlelumpfont.cpp b/src/common/fonts/singlelumpfont.cpp index ed69aea80..a9cd6ee04 100644 --- a/src/common/fonts/singlelumpfont.cpp +++ b/src/common/fonts/singlelumpfont.cpp @@ -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); } diff --git a/src/common/fonts/specialfont.cpp b/src/common/fonts/specialfont.cpp index 6bd544c9e..4dca54d3f 100644 --- a/src/common/fonts/specialfont.cpp +++ b/src/common/fonts/specialfont.cpp @@ -140,10 +140,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture { ActiveColors = 0; } - else - { - LoadTranslations(); - } } //========================================================================== diff --git a/src/common/fonts/v_font.cpp b/src/common/fonts/v_font.cpp index 4057bc878..4d0937d84 100644 --- a/src/common/fonts/v_font.cpp +++ b/src/common/fonts/v_font.cpp @@ -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) diff --git a/src/common/fonts/v_font.h b/src/common/fonts/v_font.h index 779137b61..6de1dae86 100644 --- a/src/common/fonts/v_font.h +++ b/src/common/fonts/v_font.h @@ -80,6 +80,7 @@ using GlyphSet = TMap; 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 Chars; - int ActiveColors; + int ActiveColors = -1; TArray 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(); diff --git a/src/common/rendering/gl/gl_shader.h b/src/common/rendering/gl/gl_shader.h index 3027376d5..fef8372cd 100644 --- a/src/common/rendering/gl/gl_shader.h +++ b/src/common/rendering/gl/gl_shader.h @@ -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 mPassShaders; diff --git a/src/rendering/hwrenderer/hw_draw2d.cpp b/src/common/rendering/hwrenderer/hw_draw2d.cpp similarity index 76% rename from src/rendering/hwrenderer/hw_draw2d.cpp rename to src/common/rendering/hwrenderer/hw_draw2d.cpp index 25f330c62..fc0b850a9 100644 --- a/src/rendering/hwrenderer/hw_draw2d.cpp +++ b/src/common/rendering/hwrenderer/hw_draw2d.cpp @@ -1,34 +1,39 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2018 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// /* -** 2d drawer -** Renderer interface +** 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 "doomstat.h" #include "v_video.h" #include "cmdlib.h" -#include "r_defs.h" #include "hwrenderer/data/buffers.h" #include "flatvertices.h" #include "hwrenderer/data/hw_viewpointbuffer.h" diff --git a/src/common/textures/animtexture.cpp b/src/common/textures/animtexture.cpp index a39624498..387464fd0 100644 --- a/src/common/textures/animtexture.cpp +++ b/src/common/textures/animtexture.cpp @@ -102,6 +102,8 @@ void AnimTextures::SetSize(int width, int height) { static_cast(tex[0]->GetTexture())->SetFrameSize(width, height); static_cast(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) diff --git a/src/common/textures/formats/pngtexture.cpp b/src/common/textures/formats/pngtexture.cpp index 790984d2e..f8ba8648f 100644 --- a/src/common/textures/formats/pngtexture.cpp +++ b/src/common/textures/formats/pngtexture.cpp @@ -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 (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 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 FPNGTexture::CreatePalettedPixels(int conversion) TArray 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 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) diff --git a/src/d_main.cpp b/src/d_main.cpp index e86b83c38..78225f582 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -3385,6 +3385,7 @@ static int D_DoomMain_Internal (void) StartScreen->Progress(); V_InitFonts(); + V_LoadTranslations(); UpdateGenericUI(false); // [CW] Parse any TEAMINFO lumps. @@ -3545,6 +3546,9 @@ static int D_DoomMain_Internal (void) V_Init2(); twod->fullscreenautoaspect = gameinfo.fullscreenautoaspect; + // Initialize the size of the 2D drawer so that an attempt to access it outside the draw code won't crash. + twod->Begin(screen->GetWidth(), screen->GetHeight()); + twod->End(); UpdateJoystickMenu(NULL); UpdateVRModes();