mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- made the translation container a class.
This also splits off some Doom-specific implementation details into higher level headers.
This commit is contained in:
parent
520a96033b
commit
cf757ba834
32 changed files with 293 additions and 375 deletions
|
@ -2979,7 +2979,6 @@ void D_Cleanup()
|
||||||
V_ClearFonts(); // must clear global font pointers
|
V_ClearFonts(); // must clear global font pointers
|
||||||
ColorSets.Clear();
|
ColorSets.Clear();
|
||||||
PainFlashes.Clear();
|
PainFlashes.Clear();
|
||||||
R_DeinitTranslationTables(); // some tables are initialized from outside the translation code.
|
|
||||||
gameinfo.~gameinfo_t();
|
gameinfo.~gameinfo_t();
|
||||||
new (&gameinfo) gameinfo_t; // Reset gameinfo
|
new (&gameinfo) gameinfo_t; // Reset gameinfo
|
||||||
S_Shutdown(); // free all channels and delete playlist
|
S_Shutdown(); // free all channels and delete playlist
|
||||||
|
|
|
@ -1614,7 +1614,7 @@ void FLevelLocals::QueueBody (AActor *body)
|
||||||
GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra)
|
GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra)
|
||||||
{
|
{
|
||||||
// This needs to be able to handle multiple levels, in case a level with dead players is used as a secondary one later.
|
// This needs to be able to handle multiple levels, in case a level with dead players is used as a secondary one later.
|
||||||
CopyTranslation(TRANSLATION(TRANSLATION_PlayerCorpses, modslot), body->Translation);
|
palMgr.CopyTranslation(TRANSLATION(TRANSLATION_PlayerCorpses, modslot), body->Translation);
|
||||||
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses, modslot);
|
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses, modslot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -666,7 +666,7 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Translations[CR_UNTRANSLATED] = remap.StoreTranslation(TRANSLATION_Font);
|
Translations[CR_UNTRANSLATED] = palMgr.StoreTranslation(TRANSLATION_Font, &remap);
|
||||||
forceremap = true;
|
forceremap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,7 +797,7 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
||||||
remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255, 0, 0, 0);
|
remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Translations.Push(remap.StoreTranslation(TRANSLATION_Font));
|
Translations.Push(palMgr.StoreTranslation(TRANSLATION_Font, &remap));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -837,7 +837,7 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
||||||
remap.Palette[j] = PalEntry(255,r,g,b);
|
remap.Palette[j] = PalEntry(255,r,g,b);
|
||||||
}
|
}
|
||||||
if (post) post(&remap);
|
if (post) post(&remap);
|
||||||
Translations.Push(remap.StoreTranslation(TRANSLATION_Font));
|
Translations.Push(palMgr.StoreTranslation(TRANSLATION_Font, &remap));
|
||||||
|
|
||||||
// Advance to the next color range.
|
// Advance to the next color range.
|
||||||
while (parmstart[1].RangeStart > parmstart[0].RangeEnd)
|
while (parmstart[1].RangeStart > parmstart[0].RangeEnd)
|
||||||
|
|
|
@ -417,7 +417,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Translations[CR_UNTRANSLATED] = remap.StoreTranslation(TRANSLATION_Font);
|
Translations[CR_UNTRANSLATED] = palMgr.StoreTranslation(TRANSLATION_Font, &remap);
|
||||||
forceremap = true;
|
forceremap = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8
|
||||||
TArray<uint8_t> FBuildTexture::CreatePalettedPixels(int conversion)
|
TArray<uint8_t> FBuildTexture::CreatePalettedPixels(int conversion)
|
||||||
{
|
{
|
||||||
TArray<uint8_t> Pixels(Width * Height, true);
|
TArray<uint8_t> Pixels(Width * Height, true);
|
||||||
FRemapTable *Remap = GetTranslation(TRANSLATION_Standard, Translation);
|
FRemapTable *Remap = palMgr.GetTranslation(TRANSLATION_Standard, Translation);
|
||||||
for (int i = 0; i < Width*Height; i++)
|
for (int i = 0; i < Width*Height; i++)
|
||||||
{
|
{
|
||||||
auto c = RawPixels[i];
|
auto c = RawPixels[i];
|
||||||
|
@ -95,7 +95,7 @@ TArray<uint8_t> FBuildTexture::CreatePalettedPixels(int conversion)
|
||||||
|
|
||||||
int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion)
|
int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
PalEntry *Remap = GetTranslation(TRANSLATION_Standard, Translation)->Palette;
|
PalEntry *Remap = palMgr.GetTranslation(TRANSLATION_Standard, Translation)->Palette;
|
||||||
bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap);
|
bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ static int BuildPaletteTranslation(int lump)
|
||||||
opal.Remap[255] = 0;
|
opal.Remap[255] = 0;
|
||||||
// Store the remap table in the translation manager so that we do not need to keep track of it ourselves.
|
// Store the remap table in the translation manager so that we do not need to keep track of it ourselves.
|
||||||
// Slot 0 for internal translations is a convenient location because normally it only contains a small number of translations.
|
// Slot 0 for internal translations is a convenient location because normally it only contains a small number of translations.
|
||||||
return GetTranslationIndex(opal.StoreTranslation(TRANSLATION_Standard));
|
return GetTranslationIndex(palMgr.StoreTranslation(TRANSLATION_Standard, &opal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,6 @@ TArray<uint8_t> FIMGZTexture::CreatePalettedPixels(int conversion)
|
||||||
int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion)
|
int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
if (!isalpha) return FImageSource::CopyPixels(bmp, conversion);
|
if (!isalpha) return FImageSource::CopyPixels(bmp, conversion);
|
||||||
else return CopyTranslatedPixels(bmp, GetTranslation(TRANSLATION_Standard, STD_Grayscale)->Palette);
|
else return CopyTranslatedPixels(bmp, palMgr.GetTranslation(TRANSLATION_Standard, STD_Grayscale)->Palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ static uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork)
|
||||||
switch (blend.a==0 ? int(blend) : -1)
|
switch (blend.a==0 ? int(blend) : -1)
|
||||||
{
|
{
|
||||||
case BLEND_ICEMAP:
|
case BLEND_ICEMAP:
|
||||||
return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap;
|
return palMgr.TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size())
|
if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size())
|
||||||
|
|
|
@ -263,7 +263,7 @@ TArray<uint8_t> FPatchTexture::CreatePalettedPixels(int conversion)
|
||||||
int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion)
|
int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion)
|
||||||
{
|
{
|
||||||
if (!isalpha) return FImageSource::CopyPixels(bmp, conversion);
|
if (!isalpha) return FImageSource::CopyPixels(bmp, conversion);
|
||||||
else return CopyTranslatedPixels(bmp, GetTranslation(TRANSLATION_Standard, STD_Grayscale)->Palette);
|
else return CopyTranslatedPixels(bmp, palMgr.GetTranslation(TRANSLATION_Standard, STD_Grayscale)->Palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -122,7 +122,7 @@ public:
|
||||||
|
|
||||||
int CopyPixels(FBitmap *bmp, int conversion) override
|
int CopyPixels(FBitmap *bmp, int conversion) override
|
||||||
{
|
{
|
||||||
bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, GetTranslation(TRANSLATION_Standard, STD_Gray)->Palette);
|
bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, palMgr.GetTranslation(TRANSLATION_Standard, STD_Gray)->Palette);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace ImageHelpers
|
||||||
{
|
{
|
||||||
if (wantluminance)
|
if (wantluminance)
|
||||||
{
|
{
|
||||||
return GetTranslation(TRANSLATION_Standard, srcisgrayscale ? STD_Gray : STD_Grayscale)->Remap;
|
return palMgr.GetTranslation(TRANSLATION_Standard, srcisgrayscale ? STD_Gray : STD_Grayscale)->Remap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -701,11 +701,11 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
||||||
buffer = new unsigned char[W*(H + 1) * 4];
|
buffer = new unsigned char[W*(H + 1) * 4];
|
||||||
memset(buffer, 0, W * (H + 1) * 4);
|
memset(buffer, 0, W * (H + 1) * 4);
|
||||||
|
|
||||||
auto remap = translation <= 0 ? nullptr : FUniquePalette::GetPalette(translation);
|
auto remap = translation <= 0 ? nullptr : palMgr.TranslationToTable(translation);
|
||||||
FBitmap bmp(buffer, W * 4, W, H);
|
FBitmap bmp(buffer, W * 4, W, H);
|
||||||
|
|
||||||
int trans;
|
int trans;
|
||||||
auto Pixels = GetBgraBitmap(remap, &trans);
|
auto Pixels = GetBgraBitmap(remap? remap->Palette : nullptr, &trans);
|
||||||
bmp.Blit(exx, exx, Pixels);
|
bmp.Blit(exx, exx, Pixels);
|
||||||
|
|
||||||
if (remap == nullptr)
|
if (remap == nullptr)
|
||||||
|
|
|
@ -1025,7 +1025,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
arc("polyobjs", Polyobjects);
|
arc("polyobjs", Polyobjects);
|
||||||
SerializeSubsectors(arc, "subsectors");
|
SerializeSubsectors(arc, "subsectors");
|
||||||
StatusBar->SerializeMessages(arc);
|
StatusBar->SerializeMessages(arc);
|
||||||
FRemapTable::StaticSerializeTranslations(arc);
|
StaticSerializeTranslations(arc);
|
||||||
canvasTextureInfo.Serialize(arc);
|
canvasTextureInfo.Serialize(arc);
|
||||||
SerializePlayers(arc, hubload);
|
SerializePlayers(arc, hubload);
|
||||||
SerializeSounds(arc);
|
SerializeSounds(arc);
|
||||||
|
|
|
@ -406,7 +406,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
||||||
{
|
{
|
||||||
Level->Players[i]->mo = nullptr;
|
Level->Players[i]->mo = nullptr;
|
||||||
}
|
}
|
||||||
ClearTranslationSlot(TRANSLATION_LevelScripted);
|
palMgr.ClearTranslationSlot(TRANSLATION_LevelScripted);
|
||||||
|
|
||||||
|
|
||||||
// Initial height of PointOfView will be set by player think.
|
// Initial height of PointOfView will be set by player think.
|
||||||
|
|
|
@ -9590,7 +9590,7 @@ scriptwait:
|
||||||
case PCD_ENDTRANSLATION:
|
case PCD_ENDTRANSLATION:
|
||||||
if (translation != NULL)
|
if (translation != NULL)
|
||||||
{
|
{
|
||||||
UpdateTranslation(TRANSLATION(TRANSLATION_LevelScripted, transi), translation);
|
palMgr.UpdateTranslation(TRANSLATION(TRANSLATION_LevelScripted, transi), translation);
|
||||||
delete translation;
|
delete translation;
|
||||||
translation = NULL;
|
translation = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,57 +50,103 @@
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "m_crc32.h"
|
#include "m_crc32.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "palutil.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
static FMemArena remapArena;
|
PaletteContainer palMgr;
|
||||||
static TAutoGrowArray<FRemapTablePtr, FRemapTable *> TranslationTables[NUM_TRANSLATION_TABLES];
|
|
||||||
|
|
||||||
inline FRemapTable* AllocRemap(FRemapTable *remap)
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void PaletteContainer::Init() // This cannot be a constructor!!!
|
||||||
{
|
{
|
||||||
|
Clear();
|
||||||
|
// Make sure that index 0 is always the identity translation.
|
||||||
|
FRemapTable remap;
|
||||||
|
remap.MakeIdentity();
|
||||||
|
remap.Inactive = true;
|
||||||
|
AddRemap(&remap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void PaletteContainer::Clear()
|
||||||
|
{
|
||||||
|
remapArena.FreeAllBlocks();
|
||||||
|
uniqueRemaps.Reset();
|
||||||
|
for (auto& slot : TranslationTables) slot.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FRemapTable* PaletteContainer::AddRemap(FRemapTable* remap)
|
||||||
|
{
|
||||||
|
if (!remap) return uniqueRemaps[0];
|
||||||
|
|
||||||
|
remap->crc32 = CalcCRC32((uint8_t*)remap->Palette, sizeof(remap->Palette));
|
||||||
|
|
||||||
|
for (auto uremap : uniqueRemaps)
|
||||||
|
{
|
||||||
|
if (uremap->crc32 == remap->crc32 && uremap->NumEntries == remap->NumEntries && *uremap == *remap)
|
||||||
|
return uremap;
|
||||||
|
}
|
||||||
auto newremap = (FRemapTable*)remapArena.Alloc(sizeof(FRemapTable));
|
auto newremap = (FRemapTable*)remapArena.Alloc(sizeof(FRemapTable));
|
||||||
if (remap) *newremap = *remap;
|
*newremap = *remap;
|
||||||
else newremap->MakeIdentity();
|
auto index = uniqueRemaps.Push(newremap);
|
||||||
|
newremap->Index = index;
|
||||||
return newremap;
|
return newremap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateTranslation(int trans, FRemapTable* remap)
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void PaletteContainer::UpdateTranslation(int trans, FRemapTable* remap)
|
||||||
{
|
{
|
||||||
auto newremap = AllocRemap(remap);
|
auto newremap = AddRemap(remap);
|
||||||
TranslationTables[GetTranslationType(trans)].SetVal(GetTranslationIndex(trans), newremap);
|
TranslationTables[GetTranslationType(trans)].SetVal(GetTranslationIndex(trans), newremap);
|
||||||
remap->UpdateNative();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AddTranslation(int slot, FRemapTable* remap, int count)
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int PaletteContainer::AddTranslation(int slot, FRemapTable* remap, int count)
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
auto newremap = AllocRemap(&remap[i]);
|
auto newremap = AddRemap(&remap[i]);
|
||||||
id = TranslationTables[slot].Push(newremap);
|
id = TranslationTables[slot].Push(newremap);
|
||||||
}
|
}
|
||||||
return TRANSLATION(slot, id);
|
return TRANSLATION(slot, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
FRemapTable* GetTranslation(int slot, int index)
|
//----------------------------------------------------------------------------
|
||||||
{
|
//
|
||||||
return TranslationTables[slot].GetVal(index);
|
//
|
||||||
}
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void CopyTranslation(int dest, int src)
|
void PaletteContainer::CopyTranslation(int dest, int src)
|
||||||
{
|
{
|
||||||
*TranslationTables[GetTranslationType(dest)][GetTranslationType(src)] = *TranslationToTable(src);
|
TranslationTables[GetTranslationType(dest)][GetTranslationType(src)] = TranslationToTable(src);
|
||||||
TranslationTables[GetTranslationType(dest)][GetTranslationType(src)]->UpdateNative();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearTranslationSlot(int slot)
|
|
||||||
{
|
|
||||||
TranslationTables[slot].Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned NumTranslations(int slot)
|
|
||||||
{
|
|
||||||
return TranslationTables[slot].Size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -109,7 +155,7 @@ unsigned NumTranslations(int slot)
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
FRemapTable *TranslationToTable(int translation)
|
FRemapTable *PaletteContainer::TranslationToTable(int translation)
|
||||||
{
|
{
|
||||||
unsigned int type = GetTranslationType(translation);
|
unsigned int type = GetTranslationType(translation);
|
||||||
unsigned int index = GetTranslationIndex(translation);
|
unsigned int index = GetTranslationIndex(translation);
|
||||||
|
@ -121,6 +167,34 @@ FRemapTable *TranslationToTable(int translation)
|
||||||
return GetTranslation(type, index);
|
return GetTranslation(type, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Stores a copy of this translation in the DECORATE translation table
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int PaletteContainer::StoreTranslation(int slot, FRemapTable *remap)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
auto size = NumTranslations(slot);
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (*remap == *palMgr.TranslationToTable(TRANSLATION(slot, i)))
|
||||||
|
{
|
||||||
|
// A duplicate of this translation already exists
|
||||||
|
return TRANSLATION(slot, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size >= MAX_DECORATE_TRANSLATIONS)
|
||||||
|
{
|
||||||
|
I_Error("Too many DECORATE translations");
|
||||||
|
}
|
||||||
|
return AddTranslation(slot, remap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint8_t IcePalette[16][3] =
|
const uint8_t IcePalette[16][3] =
|
||||||
{
|
{
|
||||||
|
@ -166,58 +240,6 @@ static bool IndexOutOfRange(const int start1, const int end1, const int start2,
|
||||||
return IndexOutOfRange(start2, end2) || outOfRange;
|
return IndexOutOfRange(start2, end2) || outOfRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TArray<FUniquePalette::PalData> FUniquePalette::AllPalettes;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Helper class to deal with frequently changing translations from ACS
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool FUniquePalette::Update()
|
|
||||||
{
|
|
||||||
PalData pd;
|
|
||||||
|
|
||||||
memset(pd.pe, 0, sizeof(pd.pe));
|
|
||||||
memcpy(pd.pe, remap->Palette, remap->NumEntries * sizeof(*remap->Palette));
|
|
||||||
pd.crc32 = CalcCRC32((uint8_t*)pd.pe, sizeof(pd.pe));
|
|
||||||
for (unsigned int i = 0; i< AllPalettes.Size(); i++)
|
|
||||||
{
|
|
||||||
if (pd.crc32 == AllPalettes[i].crc32)
|
|
||||||
{
|
|
||||||
if (!memcmp(pd.pe, AllPalettes[i].pe, sizeof(pd.pe)))
|
|
||||||
{
|
|
||||||
Index = 1 + i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Index = 1 + AllPalettes.Push(pd);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************/
|
|
||||||
/****************************************************/
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int FRemapTable::GetUniqueIndex()
|
|
||||||
{
|
|
||||||
if (Inactive) return 0;
|
|
||||||
if (Native == nullptr)
|
|
||||||
{
|
|
||||||
Native = new FUniquePalette(this);
|
|
||||||
Native->Update();
|
|
||||||
}
|
|
||||||
return Native->GetIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -239,16 +261,14 @@ bool FRemapTable::operator==(const FRemapTable &o)
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FRemapTable::Serialize(FSerializer &arc)
|
static void SerializeRemap(FSerializer &arc, FRemapTable &remap)
|
||||||
{
|
{
|
||||||
int n = NumEntries;
|
arc("numentries", remap.NumEntries);
|
||||||
|
arc.Array("remap", remap.Remap, remap.NumEntries);
|
||||||
arc("numentries", NumEntries);
|
arc.Array("palette", remap.Palette, remap.NumEntries);
|
||||||
arc.Array("remap", Remap, NumEntries);
|
|
||||||
arc.Array("palette", Palette, NumEntries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FRemapTable::StaticSerializeTranslations(FSerializer &arc)
|
void StaticSerializeTranslations(FSerializer &arc)
|
||||||
{
|
{
|
||||||
if (arc.BeginArray("translations"))
|
if (arc.BeginArray("translations"))
|
||||||
{
|
{
|
||||||
|
@ -257,16 +277,16 @@ void FRemapTable::StaticSerializeTranslations(FSerializer &arc)
|
||||||
int w;
|
int w;
|
||||||
if (arc.isWriting())
|
if (arc.isWriting())
|
||||||
{
|
{
|
||||||
auto size = NumTranslations(TRANSLATION_LevelScripted);
|
auto size = palMgr.NumTranslations(TRANSLATION_LevelScripted);
|
||||||
for (unsigned int i = 0; i < size; ++i)
|
for (unsigned int i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
trans = TranslationToTable(TRANSLATION(TRANSLATION_LevelScripted, i));
|
trans = palMgr.TranslationToTable(TRANSLATION(TRANSLATION_LevelScripted, i));
|
||||||
if (trans != NULL && !trans->IsIdentity())
|
if (trans != NULL && !trans->IsIdentity())
|
||||||
{
|
{
|
||||||
if (arc.BeginObject(nullptr))
|
if (arc.BeginObject(nullptr))
|
||||||
{
|
{
|
||||||
arc("index", i);
|
arc("index", i);
|
||||||
trans->Serialize(arc);
|
SerializeRemap(arc, *trans);
|
||||||
arc.EndObject();
|
arc.EndObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,8 +298,8 @@ void FRemapTable::StaticSerializeTranslations(FSerializer &arc)
|
||||||
{
|
{
|
||||||
arc("index", w);
|
arc("index", w);
|
||||||
FRemapTable remap;
|
FRemapTable remap;
|
||||||
remap.Serialize(arc);
|
SerializeRemap(arc, remap);
|
||||||
UpdateTranslation(TRANSLATION(TRANSLATION_LevelScripted, w), &remap);
|
palMgr.UpdateTranslation(TRANSLATION(TRANSLATION_LevelScripted, w), &remap);
|
||||||
arc.EndObject();
|
arc.EndObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,35 +355,6 @@ bool FRemapTable::IsIdentity() const
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FRemapTable::KillNative()
|
|
||||||
{
|
|
||||||
if (Native != NULL)
|
|
||||||
{
|
|
||||||
delete Native;
|
|
||||||
Native = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void FRemapTable::UpdateNative()
|
|
||||||
{
|
|
||||||
if (Native != NULL)
|
|
||||||
{
|
|
||||||
Native->Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
|
bool FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
|
||||||
{
|
{
|
||||||
if (IndexOutOfRange(start, end, pal1, pal2))
|
if (IndexOutOfRange(start, end, pal1, pal2))
|
||||||
|
@ -761,46 +752,6 @@ bool FRemapTable::AddColors(int start, int count, const uint8_t*colors)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Stores a copy of this translation in the DECORATE translation table
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int FRemapTable::StoreTranslation(int slot)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
auto size = NumTranslations(slot);
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
if (*this == *TranslationToTable(TRANSLATION(slot, i)))
|
|
||||||
{
|
|
||||||
// A duplicate of this translation already exists
|
|
||||||
return TRANSLATION(slot, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (size >= MAX_DECORATE_TRANSLATIONS)
|
|
||||||
{
|
|
||||||
I_Error("Too many DECORATE translations");
|
|
||||||
}
|
|
||||||
return AddTranslation(slot, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void PushIdentityTable(int slot)
|
|
||||||
{
|
|
||||||
FRemapTable table;
|
|
||||||
table.MakeIdentity();
|
|
||||||
AddTranslation(slot, &table);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -816,7 +767,7 @@ int CreateBloodTranslation(PalEntry color)
|
||||||
if (BloodTranslationColors.Size() == 0)
|
if (BloodTranslationColors.Size() == 0)
|
||||||
{
|
{
|
||||||
// Don't use the first slot.
|
// Don't use the first slot.
|
||||||
PushIdentityTable(TRANSLATION_Blood);
|
palMgr.PushIdentityTable(TRANSLATION_Blood);
|
||||||
BloodTranslationColors.Push(0);
|
BloodTranslationColors.Push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,7 +797,7 @@ int CreateBloodTranslation(PalEntry color)
|
||||||
trans.Palette[i] = pe;
|
trans.Palette[i] = pe;
|
||||||
trans.Remap[i] = entry;
|
trans.Remap[i] = entry;
|
||||||
}
|
}
|
||||||
AddTranslation(TRANSLATION_Blood, &trans);
|
palMgr.AddTranslation(TRANSLATION_Blood, &trans);
|
||||||
return BloodTranslationColors.Push(color);
|
return BloodTranslationColors.Push(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,12 +819,12 @@ void R_InitTranslationTables ()
|
||||||
// maps until then so they won't be invalid.
|
// maps until then so they won't be invalid.
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
PushIdentityTable(TRANSLATION_Players);
|
palMgr.PushIdentityTable(TRANSLATION_Players);
|
||||||
PushIdentityTable(TRANSLATION_PlayersExtra);
|
palMgr.PushIdentityTable(TRANSLATION_PlayersExtra);
|
||||||
PushIdentityTable(TRANSLATION_RainPillar);
|
palMgr.PushIdentityTable(TRANSLATION_RainPillar);
|
||||||
}
|
}
|
||||||
// The menu player also gets a separate translation table
|
// The menu player also gets a separate translation table
|
||||||
PushIdentityTable(TRANSLATION_Players);
|
palMgr.PushIdentityTable(TRANSLATION_Players);
|
||||||
|
|
||||||
// The three standard translations from Doom or Heretic (seven for Strife),
|
// The three standard translations from Doom or Heretic (seven for Strife),
|
||||||
// plus the generic ice translation.
|
// plus the generic ice translation.
|
||||||
|
@ -887,7 +838,7 @@ void R_InitTranslationTables ()
|
||||||
// color if the player who created them changes theirs.
|
// color if the player who created them changes theirs.
|
||||||
for (i = 0; i < FLevelLocals::BODYQUESIZE; ++i)
|
for (i = 0; i < FLevelLocals::BODYQUESIZE; ++i)
|
||||||
{
|
{
|
||||||
PushIdentityTable(TRANSLATION_PlayerCorpses);
|
palMgr.PushIdentityTable(TRANSLATION_PlayerCorpses);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the standard translation tables
|
// Create the standard translation tables
|
||||||
|
@ -1023,26 +974,10 @@ void R_InitTranslationTables ()
|
||||||
remap->Remap[i] = v;
|
remap->Remap[i] = v;
|
||||||
remap->Palette[i] = PalEntry(255, v, v, v);
|
remap->Palette[i] = PalEntry(255, v, v, v);
|
||||||
}
|
}
|
||||||
AddTranslation(TRANSLATION_Standard, stdremaps, 10);
|
palMgr.AddTranslation(TRANSLATION_Standard, stdremaps, 10);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void R_DeinitTranslationTables()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NUM_TRANSLATION_TABLES; ++i)
|
|
||||||
{
|
|
||||||
ClearTranslationSlot(i);
|
|
||||||
}
|
|
||||||
BloodTranslationColors.Clear();
|
|
||||||
remapArena.FreeAllBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// [RH] Create a player's translation table based on a given mid-range color.
|
// [RH] Create a player's translation table based on a given mid-range color.
|
||||||
|
@ -1153,7 +1088,6 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC
|
||||||
if (start == 0 && end == 0)
|
if (start == 0 && end == 0)
|
||||||
{
|
{
|
||||||
table->Inactive = true;
|
table->Inactive = true;
|
||||||
table->UpdateNative();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,7 +1176,6 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC
|
||||||
SetRemap(alttable, i, r, g, b);
|
SetRemap(alttable, i, r, g, b);
|
||||||
SetPillarRemap(pillartable, i, h, s, v);
|
SetPillarRemap(pillartable, i, h, s, v);
|
||||||
}
|
}
|
||||||
alttable->UpdateNative();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gameinfo.gametype == GAME_Hexen)
|
else if (gameinfo.gametype == GAME_Hexen)
|
||||||
|
@ -1300,10 +1233,8 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC
|
||||||
SetRemap(alttable, i, r, g, b);
|
SetRemap(alttable, i, r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alttable->UpdateNative();
|
|
||||||
}
|
}
|
||||||
table->UpdateNative();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -1321,9 +1252,9 @@ void R_BuildPlayerTranslation (int player)
|
||||||
FRemapTable remaps[3];
|
FRemapTable remaps[3];
|
||||||
R_CreatePlayerTranslation (h, s, v, colorset, &Skins[players[player].userinfo.GetSkin()], &remaps[0], &remaps[1], &remaps[2]);
|
R_CreatePlayerTranslation (h, s, v, colorset, &Skins[players[player].userinfo.GetSkin()], &remaps[0], &remaps[1], &remaps[2]);
|
||||||
|
|
||||||
UpdateTranslation(TRANSLATION(TRANSLATION_Players, player), &remaps[0]);
|
palMgr.UpdateTranslation(TRANSLATION(TRANSLATION_Players, player), &remaps[0]);
|
||||||
UpdateTranslation(TRANSLATION(TRANSLATION_PlayersExtra, player), &remaps[1]);
|
palMgr.UpdateTranslation(TRANSLATION(TRANSLATION_PlayersExtra, player), &remaps[1]);
|
||||||
UpdateTranslation(TRANSLATION(TRANSLATION_RainPillar, player), &remaps[2]);
|
palMgr.UpdateTranslation(TRANSLATION(TRANSLATION_RainPillar, player), &remaps[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -1370,7 +1301,7 @@ DEFINE_ACTION_FUNCTION(_Translation, SetPlayerTranslation)
|
||||||
FRemapTable remap;
|
FRemapTable remap;
|
||||||
R_GetPlayerTranslation(PlayerColor, GetColorSet(cls->Type, PlayerColorset),
|
R_GetPlayerTranslation(PlayerColor, GetColorSet(cls->Type, PlayerColorset),
|
||||||
&Skins[PlayerSkin], &remap);
|
&Skins[PlayerSkin], &remap);
|
||||||
UpdateTranslation(TRANSLATION(tgroup, tnum), &remap);
|
palMgr.UpdateTranslation(TRANSLATION(tgroup, tnum), &remap);
|
||||||
}
|
}
|
||||||
ACTION_RETURN_BOOL(true);
|
ACTION_RETURN_BOOL(true);
|
||||||
}
|
}
|
||||||
|
@ -1434,7 +1365,7 @@ DEFINE_ACTION_FUNCTION(_Translation, GetID)
|
||||||
void R_ParseTrnslate()
|
void R_ParseTrnslate()
|
||||||
{
|
{
|
||||||
customTranslationMap.Clear();
|
customTranslationMap.Clear();
|
||||||
ClearTranslationSlot(TRANSLATION_Custom);
|
palMgr.ClearTranslationSlot(TRANSLATION_Custom);
|
||||||
|
|
||||||
int lump;
|
int lump;
|
||||||
int lastlump = 0;
|
int lastlump = 0;
|
||||||
|
@ -1457,7 +1388,7 @@ void R_ParseTrnslate()
|
||||||
{
|
{
|
||||||
sc.ScriptError("Translation must be in the range [0,%d]", max);
|
sc.ScriptError("Translation must be in the range [0,%d]", max);
|
||||||
}
|
}
|
||||||
NewTranslation = *TranslationToTable(TRANSLATION(TRANSLATION_Standard, sc.Number));
|
NewTranslation = *palMgr.TranslationToTable(TRANSLATION(TRANSLATION_Standard, sc.Number));
|
||||||
}
|
}
|
||||||
else if (sc.TokenType == TK_Identifier)
|
else if (sc.TokenType == TK_Identifier)
|
||||||
{
|
{
|
||||||
|
@ -1466,7 +1397,7 @@ void R_ParseTrnslate()
|
||||||
{
|
{
|
||||||
sc.ScriptError("Base translation '%s' not found in '%s'", sc.String, newtrans.GetChars());
|
sc.ScriptError("Base translation '%s' not found in '%s'", sc.String, newtrans.GetChars());
|
||||||
}
|
}
|
||||||
NewTranslation = *TranslationToTable(tnum);
|
NewTranslation = *palMgr.TranslationToTable(tnum);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1505,7 +1436,7 @@ void R_ParseTrnslate()
|
||||||
}
|
}
|
||||||
} while (sc.CheckToken(','));
|
} while (sc.CheckToken(','));
|
||||||
|
|
||||||
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);
|
int trans = palMgr.StoreTranslation(TRANSLATION_Custom, &NewTranslation);
|
||||||
customTranslationMap[newtrans] = trans;
|
customTranslationMap[newtrans] = trans;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1532,7 +1463,7 @@ DEFINE_ACTION_FUNCTION(_Translation, AddTranslation)
|
||||||
{
|
{
|
||||||
NewTranslation.Remap[i] = ColorMatcher.Pick(self->colors[i]);
|
NewTranslation.Remap[i] = ColorMatcher.Pick(self->colors[i]);
|
||||||
}
|
}
|
||||||
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);
|
int trans = palMgr.StoreTranslation(TRANSLATION_Custom, &NewTranslation);
|
||||||
ACTION_RETURN_INT(trans);
|
ACTION_RETURN_INT(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,27 +3,10 @@
|
||||||
|
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
#include "palutil.h"
|
||||||
|
|
||||||
class FSerializer;
|
class FSerializer;
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TRANSLATION_Invalid,
|
|
||||||
TRANSLATION_Players,
|
|
||||||
TRANSLATION_PlayersExtra,
|
|
||||||
TRANSLATION_Standard,
|
|
||||||
TRANSLATION_LevelScripted,
|
|
||||||
TRANSLATION_Decals,
|
|
||||||
TRANSLATION_PlayerCorpses,
|
|
||||||
TRANSLATION_Decorate,
|
|
||||||
TRANSLATION_Blood,
|
|
||||||
TRANSLATION_RainPillar,
|
|
||||||
TRANSLATION_Custom,
|
|
||||||
TRANSLATION_Font,
|
|
||||||
|
|
||||||
NUM_TRANSLATION_TABLES
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EStandardTranslations
|
enum EStandardTranslations
|
||||||
{
|
{
|
||||||
STD_Ice = 7,
|
STD_Ice = 7,
|
||||||
|
@ -31,115 +14,11 @@ enum EStandardTranslations
|
||||||
STD_Grayscale = 9, // desaturated version of the palette.
|
STD_Grayscale = 9, // desaturated version of the palette.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FRemapTable;
|
|
||||||
|
|
||||||
class FUniquePalette
|
|
||||||
{
|
|
||||||
friend struct FRemapTable;
|
|
||||||
struct PalData
|
|
||||||
{
|
|
||||||
int crc32;
|
|
||||||
PalEntry pe[256];
|
|
||||||
};
|
|
||||||
static TArray<PalData> AllPalettes;
|
|
||||||
|
|
||||||
int Index;
|
|
||||||
FRemapTable *remap;
|
|
||||||
|
|
||||||
FUniquePalette(FRemapTable *r) { remap = r; Index = -1; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static PalEntry *GetPalette(unsigned int index)
|
|
||||||
{
|
|
||||||
return index > 0 && index <= AllPalettes.Size() ? AllPalettes[index - 1].pe : NULL;
|
|
||||||
}
|
|
||||||
bool Update();
|
|
||||||
int GetIndex() const { return Index; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct FRemapTable
|
|
||||||
{
|
|
||||||
FRemapTable(int count = 256) { NumEntries = count; }
|
|
||||||
FRemapTable(const FRemapTable& o) = default;
|
|
||||||
|
|
||||||
bool operator==(const FRemapTable &o);
|
|
||||||
void MakeIdentity();
|
|
||||||
void KillNative();
|
|
||||||
void UpdateNative();
|
|
||||||
bool IsIdentity() const;
|
|
||||||
void Serialize(FSerializer &arc);
|
|
||||||
static void StaticSerializeTranslations(FSerializer &arc);
|
|
||||||
bool AddIndexRange(int start, int end, int pal1, int pal2);
|
|
||||||
bool AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2);
|
|
||||||
bool AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
|
|
||||||
bool AddColourisation(int start, int end, int r, int g, int b);
|
|
||||||
bool AddTint(int start, int end, int r, int g, int b, int amount);
|
|
||||||
bool AddToTranslation(const char * range);
|
|
||||||
bool AddColors(int start, int count, const uint8_t*);
|
|
||||||
int StoreTranslation(int slot);
|
|
||||||
int GetUniqueIndex();
|
|
||||||
|
|
||||||
uint8_t Remap[256]; // For the software renderer
|
|
||||||
PalEntry Palette[256]; // The ideal palette this maps to
|
|
||||||
FUniquePalette *Native = nullptr; // The index into the list of unique palettes (this is to avoid frequent texture recreation with changing ACS translations)
|
|
||||||
//int crc32;
|
|
||||||
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
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
// A class that initializes unusued pointers to NULL. This is used so that when
|
|
||||||
// the TAutoGrowArray below is expanded, the new elements will be NULLed.
|
|
||||||
class FRemapTablePtr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FRemapTablePtr() throw() : Ptr(0) {}
|
|
||||||
FRemapTablePtr(FRemapTable *p) throw() : Ptr(p) {}
|
|
||||||
FRemapTablePtr(const FRemapTablePtr &p) throw() : Ptr(p.Ptr) {}
|
|
||||||
operator FRemapTable *() const throw() { return Ptr; }
|
|
||||||
FRemapTablePtr &operator= (FRemapTable *p) throw() { Ptr = p; return *this; }
|
|
||||||
FRemapTablePtr &operator= (FRemapTablePtr &p) throw() { Ptr = p.Ptr; return *this; }
|
|
||||||
FRemapTable &operator*() const throw() { return *Ptr; }
|
|
||||||
FRemapTable *operator->() const throw() { return Ptr; }
|
|
||||||
private:
|
|
||||||
FRemapTable *Ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define TRANSLATION_SHIFT 16
|
|
||||||
#define TRANSLATION_MASK ((1<<TRANSLATION_SHIFT)-1)
|
|
||||||
#define TRANSLATIONTYPE_MASK (255<<TRANSLATION_SHIFT)
|
|
||||||
|
|
||||||
inline uint32_t TRANSLATION(uint8_t a, uint32_t b)
|
|
||||||
{
|
|
||||||
return (a<<TRANSLATION_SHIFT) | b;
|
|
||||||
}
|
|
||||||
inline int GetTranslationType(uint32_t trans)
|
|
||||||
{
|
|
||||||
return (trans&TRANSLATIONTYPE_MASK) >> TRANSLATION_SHIFT;
|
|
||||||
}
|
|
||||||
inline int GetTranslationIndex(uint32_t trans)
|
|
||||||
{
|
|
||||||
return (trans&TRANSLATION_MASK);
|
|
||||||
}
|
|
||||||
// Retrieve the FRemapTable that an actor's translation value maps to.
|
|
||||||
FRemapTable *TranslationToTable(int translation);
|
|
||||||
void UpdateTranslation(int trans, FRemapTable* remap);
|
|
||||||
int AddTranslation(int slot, FRemapTable* remap, int count = 1);
|
|
||||||
FRemapTable* GetTranslation(int slot, int index);
|
|
||||||
void CopyTranslation(int dest, int src);
|
|
||||||
void ClearTranslationSlot(int slot);
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_ACS_TRANSLATIONS 65535
|
#define MAX_ACS_TRANSLATIONS 65535
|
||||||
#define MAX_DECORATE_TRANSLATIONS 65535
|
#define MAX_DECORATE_TRANSLATIONS 65535
|
||||||
|
|
||||||
// Initialize color translation tables, for player rendering etc.
|
// Initialize color translation tables, for player rendering etc.
|
||||||
void R_InitTranslationTables (void);
|
void R_InitTranslationTables (void);
|
||||||
void R_DeinitTranslationTables();
|
|
||||||
|
|
||||||
void R_BuildPlayerTranslation (int player); // [RH] Actually create a player's translation table.
|
void R_BuildPlayerTranslation (int player); // [RH] Actually create a player's translation table.
|
||||||
void R_GetPlayerTranslation (int color, const struct FPlayerColorSet *colorset, class FPlayerSkin *skin, struct FRemapTable *table);
|
void R_GetPlayerTranslation (int color, const struct FPlayerColorSet *colorset, class FPlayerSkin *skin, struct FRemapTable *table);
|
||||||
|
@ -150,6 +29,7 @@ int CreateBloodTranslation(PalEntry color);
|
||||||
|
|
||||||
int R_FindCustomTranslation(FName name);
|
int R_FindCustomTranslation(FName name);
|
||||||
void R_ParseTrnslate();
|
void R_ParseTrnslate();
|
||||||
|
void StaticSerializeTranslations(FSerializer& arc);
|
||||||
|
|
||||||
struct TextureManipulation
|
struct TextureManipulation
|
||||||
{
|
{
|
||||||
|
|
|
@ -475,7 +475,7 @@ FTexture *OpenGLFrameBuffer::WipeStartScreen()
|
||||||
const auto &viewport = screen->mScreenViewport;
|
const auto &viewport = screen->mScreenViewport;
|
||||||
|
|
||||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||||
tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen");
|
tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, "WipeStartScreen");
|
||||||
glFinish();
|
glFinish();
|
||||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||||
|
|
||||||
|
@ -497,7 +497,7 @@ FTexture *OpenGLFrameBuffer::WipeEndScreen()
|
||||||
GLRenderer->Flush();
|
GLRenderer->Flush();
|
||||||
const auto &viewport = screen->mScreenViewport;
|
const auto &viewport = screen->mScreenViewport;
|
||||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||||
tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen");
|
tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, "WipeEndScreen");
|
||||||
glFinish();
|
glFinish();
|
||||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||||
GLRenderer->mBuffers->BindCurrentFB();
|
GLRenderer->mBuffers->BindCurrentFB();
|
||||||
|
|
|
@ -85,7 +85,7 @@ unsigned int FHardwareTexture::lastbound[FHardwareTexture::MAX_TEXTURES];
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name)
|
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name)
|
||||||
{
|
{
|
||||||
int rh,rw;
|
int rh,rw;
|
||||||
int texformat = GL_RGBA8;// TexFormat[gl_texture_format];
|
int texformat = GL_RGBA8;// TexFormat[gl_texture_format];
|
||||||
|
@ -317,9 +317,6 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
|
||||||
{
|
{
|
||||||
int usebright = false;
|
int usebright = false;
|
||||||
|
|
||||||
auto remap = TranslationToTable(translation);
|
|
||||||
translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
|
|
||||||
|
|
||||||
bool needmipmap = (clampmode <= CLAMP_XY);
|
bool needmipmap = (clampmode <= CLAMP_XY);
|
||||||
|
|
||||||
// Bind it to the system.
|
// Bind it to the system.
|
||||||
|
@ -343,7 +340,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
|
||||||
w = tex->GetWidth();
|
w = tex->GetWidth();
|
||||||
h = tex->GetHeight();
|
h = tex->GetHeight();
|
||||||
}
|
}
|
||||||
if (!CreateTexture(texbuffer.mBuffer, w, h, texunit, needmipmap, translation, "FHardwareTexture.BindOrCreate"))
|
if (!CreateTexture(texbuffer.mBuffer, w, h, texunit, needmipmap, "FHardwareTexture.BindOrCreate"))
|
||||||
{
|
{
|
||||||
// could not create texture
|
// could not create texture
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
void AllocateBuffer(int w, int h, int texelsize);
|
void AllocateBuffer(int w, int h, int texelsize);
|
||||||
uint8_t *MapBuffer();
|
uint8_t *MapBuffer();
|
||||||
|
|
||||||
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name);
|
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name);
|
||||||
unsigned int GetTextureHandle(int translation);
|
unsigned int GetTextureHandle(int translation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
|
|
||||||
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
||||||
virtual uint8_t *MapBuffer() = 0;
|
virtual uint8_t *MapBuffer() = 0;
|
||||||
virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) = 0;
|
virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) = 0;
|
||||||
|
|
||||||
void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data);
|
void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data);
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,8 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
||||||
while (it.NextPair(pair))
|
while (it.NextPair(pair))
|
||||||
{
|
{
|
||||||
PClassActor *cls = pair->Key;
|
PClassActor *cls = pair->Key;
|
||||||
auto remap = TranslationToTable(GetDefaultByType(cls)->Translation);
|
auto remap = palMgr.TranslationToTable(GetDefaultByType(cls)->Translation);
|
||||||
int gltrans = remap == nullptr ? 0 : remap->GetUniqueIndex();
|
int gltrans = remap == nullptr ? 0 : remap->Index;
|
||||||
|
|
||||||
for (unsigned i = 0; i < cls->GetStateCount(); i++)
|
for (unsigned i = 0; i < cls->GetStateCount(); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,9 @@ private:
|
||||||
|
|
||||||
TranslatedTexture * GetTexID(int translation, bool expanded)
|
TranslatedTexture * GetTexID(int translation, bool expanded)
|
||||||
{
|
{
|
||||||
translation = TranslationToIndex(translation);
|
auto remap = palMgr.TranslationToTable(translation);
|
||||||
|
translation = remap == nullptr ? 0 : remap->Index;
|
||||||
|
|
||||||
if (translation == 0)
|
if (translation == 0)
|
||||||
{
|
{
|
||||||
return &hwDefTex[expanded];
|
return &hwDefTex[expanded];
|
||||||
|
@ -122,12 +124,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int TranslationToIndex(int translation)
|
|
||||||
{
|
|
||||||
auto remap = TranslationToTable(translation);
|
|
||||||
return remap == nullptr ? 0 : remap->GetUniqueIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Iterate(T callback)
|
void Iterate(T callback)
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,7 +130,7 @@ uint8_t *PolyHardwareTexture::MapBuffer()
|
||||||
return mCanvas->GetPixels();
|
return mCanvas->GetPixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int PolyHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name)
|
unsigned int PolyHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -166,9 +166,6 @@ void PolyHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||||
|
|
||||||
if (!tex->isHardwareCanvas())
|
if (!tex->isHardwareCanvas())
|
||||||
{
|
{
|
||||||
auto remap = TranslationToTable(translation);
|
|
||||||
translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
|
|
||||||
|
|
||||||
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
||||||
mCanvas->Resize(texbuffer.mWidth, texbuffer.mHeight, false);
|
mCanvas->Resize(texbuffer.mWidth, texbuffer.mHeight, false);
|
||||||
memcpy(mCanvas->GetPixels(), texbuffer.mBuffer, texbuffer.mWidth * texbuffer.mHeight * 4);
|
memcpy(mCanvas->GetPixels(), texbuffer.mBuffer, texbuffer.mWidth * texbuffer.mHeight * 4);
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
// Software renderer stuff
|
// Software renderer stuff
|
||||||
void AllocateBuffer(int w, int h, int texelsize) override;
|
void AllocateBuffer(int w, int h, int texelsize) override;
|
||||||
uint8_t *MapBuffer() override;
|
uint8_t *MapBuffer() override;
|
||||||
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) override;
|
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) override;
|
||||||
|
|
||||||
// Wipe screen
|
// Wipe screen
|
||||||
void CreateWipeTexture(int w, int h, const char *name);
|
void CreateWipeTexture(int w, int h, const char *name);
|
||||||
|
|
|
@ -112,7 +112,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player)
|
||||||
auto buf = systemTexture->MapBuffer();
|
auto buf = systemTexture->MapBuffer();
|
||||||
if (!buf) I_FatalError("Unable to map buffer for software rendering");
|
if (!buf) I_FatalError("Unable to map buffer for software rendering");
|
||||||
SWRenderer->RenderView(player, Canvas.get(), buf, systemTexture->GetBufferPitch());
|
SWRenderer->RenderView(player, Canvas.get(), buf, systemTexture->GetBufferPitch());
|
||||||
systemTexture->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer");
|
systemTexture->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, "swbuffer");
|
||||||
|
|
||||||
auto map = swrenderer::CameraLight::Instance()->ShaderColormap();
|
auto map = swrenderer::CameraLight::Instance()->ShaderColormap();
|
||||||
screen->DrawTexture(fbtex.get(), 0, 0, DTA_SpecialColormap, map, TAG_DONE);
|
screen->DrawTexture(fbtex.get(), 0, 0, DTA_SpecialColormap, map, TAG_DONE);
|
||||||
|
|
|
@ -474,7 +474,7 @@ namespace swrenderer
|
||||||
SetTranslationMap(nullptr);
|
SetTranslationMap(nullptr);
|
||||||
if (translation != 0)
|
if (translation != 0)
|
||||||
{
|
{
|
||||||
FRemapTable *table = TranslationToTable(translation);
|
FRemapTable *table = palMgr.TranslationToTable(translation);
|
||||||
if (table != NULL && !table->Inactive)
|
if (table != NULL && !table->Inactive)
|
||||||
{
|
{
|
||||||
if (viewport->RenderTarget->IsBgra())
|
if (viewport->RenderTarget->IsBgra())
|
||||||
|
|
|
@ -132,7 +132,7 @@ void V_DrawPaletteTester(int paletteno)
|
||||||
PalEntry pe;
|
PalEntry pe;
|
||||||
if (t > 1)
|
if (t > 1)
|
||||||
{
|
{
|
||||||
auto palette = GetTranslation(TRANSLATION_Standard, t - 2)->Palette;
|
auto palette = palMgr.GetTranslation(TRANSLATION_Standard, t - 2)->Palette;
|
||||||
pe = palette[k];
|
pe = palette[k];
|
||||||
}
|
}
|
||||||
else GPalette.BaseColors[k];
|
else GPalette.BaseColors[k];
|
||||||
|
|
|
@ -350,7 +350,6 @@ protected:
|
||||||
bool Bgra;
|
bool Bgra;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FUniquePalette;
|
|
||||||
class IHardwareTexture;
|
class IHardwareTexture;
|
||||||
class FTexture;
|
class FTexture;
|
||||||
|
|
||||||
|
|
|
@ -207,9 +207,6 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||||
{
|
{
|
||||||
if (!tex->isHardwareCanvas())
|
if (!tex->isHardwareCanvas())
|
||||||
{
|
{
|
||||||
auto remap = TranslationToTable(translation);
|
|
||||||
translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
|
|
||||||
|
|
||||||
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
||||||
CreateTexture(texbuffer.mWidth, texbuffer.mHeight, 4, VK_FORMAT_B8G8R8A8_UNORM, texbuffer.mBuffer);
|
CreateTexture(texbuffer.mWidth, texbuffer.mHeight, 4, VK_FORMAT_B8G8R8A8_UNORM, texbuffer.mBuffer);
|
||||||
}
|
}
|
||||||
|
@ -348,7 +345,7 @@ uint8_t *VkHardwareTexture::MapBuffer()
|
||||||
return mappedSWFB;
|
return mappedSWFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int VkHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name)
|
unsigned int VkHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
// Software renderer stuff
|
// Software renderer stuff
|
||||||
void AllocateBuffer(int w, int h, int texelsize) override;
|
void AllocateBuffer(int w, int h, int texelsize) override;
|
||||||
uint8_t *MapBuffer() override;
|
uint8_t *MapBuffer() override;
|
||||||
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) override;
|
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) override;
|
||||||
|
|
||||||
// Wipe screen
|
// Wipe screen
|
||||||
void CreateWipeTexture(int w, int h, const char *name);
|
void CreateWipeTexture(int w, int h, const char *name);
|
||||||
|
|
|
@ -756,7 +756,7 @@ DEFINE_PROPERTY(translation, L, Actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate);
|
defaults->Translation = palMgr.StoreTranslation (TRANSLATION_Decorate, &CurrentTranslation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
struct PalEntry;
|
#include "memarena.h"
|
||||||
|
#include "palentry.h"
|
||||||
|
|
||||||
int BestColor(const uint32_t* pal, int r, int g, int b, int first = 1, int num = 255);
|
int BestColor(const uint32_t* pal, int r, int g, int b, int first = 1, int num = 255);
|
||||||
int PTM_BestColor(const uint32_t* pal_in, int r, int g, int b, bool reverselookup, float powtable, int first = 1, int num = 255);
|
int PTM_BestColor(const uint32_t* pal_in, int r, int g, int b, bool reverselookup, float powtable, int first = 1, int num = 255);
|
||||||
|
@ -9,3 +10,124 @@ void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int
|
||||||
// Colorspace conversion RGB <-> HSV
|
// Colorspace conversion RGB <-> HSV
|
||||||
void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v);
|
void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v);
|
||||||
void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v);
|
void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v);
|
||||||
|
|
||||||
|
struct FRemapTable
|
||||||
|
{
|
||||||
|
FRemapTable(int count = 256) { NumEntries = count; }
|
||||||
|
FRemapTable(const FRemapTable& o) = default;
|
||||||
|
|
||||||
|
bool operator==(const FRemapTable& o);
|
||||||
|
void MakeIdentity();
|
||||||
|
bool IsIdentity() const;
|
||||||
|
bool AddIndexRange(int start, int end, int pal1, int pal2);
|
||||||
|
bool AddColorRange(int start, int end, int r1, int g1, int b1, int r2, int g2, int b2);
|
||||||
|
bool AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
|
||||||
|
bool AddColourisation(int start, int end, int r, int g, int b);
|
||||||
|
bool AddTint(int start, int end, int r, int g, int b, int amount);
|
||||||
|
bool AddToTranslation(const char* range);
|
||||||
|
bool AddColors(int start, int count, const uint8_t*);
|
||||||
|
|
||||||
|
uint8_t Remap[256]; // For the software renderer
|
||||||
|
PalEntry Palette[256]; // The ideal palette this maps to
|
||||||
|
int crc32;
|
||||||
|
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
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
// A class that initializes unusued pointers to NULL. This is used so that when
|
||||||
|
// the TAutoGrowArray below is expanded, the new elements will be NULLed.
|
||||||
|
class FRemapTablePtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FRemapTablePtr() throw() : Ptr(0) {}
|
||||||
|
FRemapTablePtr(FRemapTable* p) throw() : Ptr(p) {}
|
||||||
|
FRemapTablePtr(const FRemapTablePtr& p) throw() : Ptr(p.Ptr) {}
|
||||||
|
operator FRemapTable* () const throw() { return Ptr; }
|
||||||
|
FRemapTablePtr& operator= (FRemapTable* p) throw() { Ptr = p; return *this; }
|
||||||
|
FRemapTablePtr& operator= (FRemapTablePtr& p) throw() { Ptr = p.Ptr; return *this; }
|
||||||
|
FRemapTable& operator*() const throw() { return *Ptr; }
|
||||||
|
FRemapTable* operator->() const throw() { return Ptr; }
|
||||||
|
private:
|
||||||
|
FRemapTable* Ptr = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define TRANSLATION_SHIFT 16
|
||||||
|
#define TRANSLATION_MASK ((1<<TRANSLATION_SHIFT)-1)
|
||||||
|
#define TRANSLATIONTYPE_MASK (255<<TRANSLATION_SHIFT)
|
||||||
|
|
||||||
|
inline uint32_t TRANSLATION(uint8_t a, uint32_t b)
|
||||||
|
{
|
||||||
|
return (a << TRANSLATION_SHIFT) | b;
|
||||||
|
}
|
||||||
|
inline int GetTranslationType(uint32_t trans)
|
||||||
|
{
|
||||||
|
return (trans & TRANSLATIONTYPE_MASK) >> TRANSLATION_SHIFT;
|
||||||
|
}
|
||||||
|
inline int GetTranslationIndex(uint32_t trans)
|
||||||
|
{
|
||||||
|
return (trans & TRANSLATION_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixme: This should avoid hard game content dependencies!
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TRANSLATION_Invalid,
|
||||||
|
TRANSLATION_Players,
|
||||||
|
TRANSLATION_PlayersExtra,
|
||||||
|
TRANSLATION_Standard,
|
||||||
|
TRANSLATION_LevelScripted,
|
||||||
|
TRANSLATION_Decals,
|
||||||
|
TRANSLATION_PlayerCorpses,
|
||||||
|
TRANSLATION_Decorate,
|
||||||
|
TRANSLATION_Blood,
|
||||||
|
TRANSLATION_RainPillar,
|
||||||
|
TRANSLATION_Custom,
|
||||||
|
TRANSLATION_Font,
|
||||||
|
|
||||||
|
NUM_TRANSLATION_TABLES
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PaletteContainer
|
||||||
|
{
|
||||||
|
FMemArena remapArena;
|
||||||
|
TArray<FRemapTable*> uniqueRemaps;
|
||||||
|
TAutoGrowArray<FRemapTablePtr, FRemapTable*> TranslationTables[NUM_TRANSLATION_TABLES];
|
||||||
|
public:
|
||||||
|
void Init(); // This cannot be a constructor!!!
|
||||||
|
void Clear();
|
||||||
|
FRemapTable* AddRemap(FRemapTable* remap);
|
||||||
|
void UpdateTranslation(int trans, FRemapTable* remap);
|
||||||
|
int AddTranslation(int slot, FRemapTable* remap, int count = 1);
|
||||||
|
void CopyTranslation(int dest, int src);
|
||||||
|
int StoreTranslation(int slot, FRemapTable* remap);
|
||||||
|
FRemapTable* TranslationToTable(int translation);
|
||||||
|
|
||||||
|
void PushIdentityTable(int slot)
|
||||||
|
{
|
||||||
|
AddTranslation(slot, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
FRemapTable* GetTranslation(int slot, int index)
|
||||||
|
{
|
||||||
|
return TranslationTables[slot].GetVal(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearTranslationSlot(int slot)
|
||||||
|
{
|
||||||
|
TranslationTables[slot].Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned NumTranslations(int slot) const
|
||||||
|
{
|
||||||
|
return TranslationTables[slot].Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PaletteContainer palMgr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue