diff --git a/source/blood/src/screen.cpp b/source/blood/src/screen.cpp index 303c2c453..8cec4cf7b 100644 --- a/source/blood/src/screen.cpp +++ b/source/blood/src/screen.cpp @@ -120,7 +120,7 @@ void scrLoadPalette(void) ThrowError("TRANS.TLU not found"); paletteloaded |= PALETTE_TRANSLUC; - palettePostLoadTables(); + enginePostInit(); } diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 626208047..f0fad7063 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -2125,6 +2125,7 @@ int32_t enginePostInit(void) if (!(paletteloaded & PALETTE_TRANSLUC)) I_FatalError("No translucency table found."); + V_LoadTranslations(); // loading the translations must be delayed until the palettes have been fully set up. palettePostLoadTables(); TileFiles.SetupReverseTileMap(); return 0; diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index 985ba4981..c8964accf 100644 --- a/source/common/fonts/font.cpp +++ b/source/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/source/common/fonts/hexfont.cpp b/source/common/fonts/hexfont.cpp index 812973bba..1c23d3bd0 100644 --- a/source/common/fonts/hexfont.cpp +++ b/source/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/source/common/fonts/singlelumpfont.cpp b/source/common/fonts/singlelumpfont.cpp index ed69aea80..a9cd6ee04 100644 --- a/source/common/fonts/singlelumpfont.cpp +++ b/source/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/source/common/fonts/specialfont.cpp b/source/common/fonts/specialfont.cpp index 6bd544c9e..4dca54d3f 100644 --- a/source/common/fonts/specialfont.cpp +++ b/source/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/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index 4057bc878..4d221431b 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -828,6 +828,14 @@ void V_InitFonts() AlternativeSmallFont = OriginalSmallFont; } +void V_LoadTranslations() +{ + for (auto font = FFont::FirstFont; font; font = font->Next) + { + if (!font->noTranslate) font->LoadTranslations(); + } +} + void V_ClearFonts() { while (FFont::FirstFont != nullptr) diff --git a/source/common/fonts/v_font.h b/source/common/fonts/v_font.h index 4e78da08f..2fff85888 100644 --- a/source/common/fonts/v_font.h +++ b/source/common/fonts/v_font.h @@ -81,6 +81,7 @@ using GlyphSet = TMap; class FFont { + friend void V_LoadTranslations(); public: enum EFontType @@ -192,5 +193,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/source/common/textures/formats/pngtexture.cpp b/source/common/textures/formats/pngtexture.cpp index 34fab85fa..48eb2437c 100644 --- a/source/common/textures/formats/pngtexture.cpp +++ b/source/common/textures/formats/pngtexture.cpp @@ -60,6 +60,7 @@ public: protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); + void SetupPalette(FileReader &lump); uint8_t BitDepth; uint8_t ColorType; @@ -153,11 +154,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; @@ -211,15 +207,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'): @@ -249,9 +237,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 { @@ -260,14 +245,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; @@ -282,6 +264,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); +} + //========================================================================== // // @@ -337,6 +400,7 @@ TArray FPNGTexture::CreatePalettedPixels(int conversion) { if (conversion != luminance) { + if (!PaletteMap) SetupPalette(lfr); ImageHelpers::FlipSquareBlockRemap (Pixels.Data(), Width, PaletteMap); } else if (ColorType == 0) @@ -355,6 +419,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) @@ -409,6 +474,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)