Skip to content

Commit

Permalink
- rewrote the default translation handling to be compatible with lumi…
Browse files Browse the repository at this point in the history
…nosity translations.
  • Loading branch information
coelckers committed May 25, 2021
1 parent 8b1757e commit 4ff4fa6
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 185 deletions.
2 changes: 1 addition & 1 deletion source/common/engine/palettecontainer.h
Expand Up @@ -32,7 +32,7 @@ struct FRemapTable
PalEntry Palette[256]; // The ideal palette this maps to
int crc32;
int Index;
int NumEntries; // # of elements in this table (usually 256), if this is -1 it is a luminosity translation.
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-
Expand Down
123 changes: 20 additions & 103 deletions source/common/fonts/font.cpp
Expand Up @@ -83,7 +83,6 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
Next = FirstFont;
FirstFont = this;
Cursor = '_';
ActiveColors = 0;
SpaceWidth = 0;
FontHeight = 0;
uint8_t pp = 0;
Expand Down Expand Up @@ -590,61 +589,6 @@ void FFont::RecordAllTextureColors(uint32_t *usedcolors)
}
}

//==========================================================================
//
// SetDefaultTranslation
//
// Builds a translation to map the stock font to a mod provided replacement.
//
//==========================================================================

void FFont::SetDefaultTranslation(uint32_t *othercolors)
{
uint32_t mycolors[256] = {};
RecordAllTextureColors(mycolors);

uint8_t mytranslation[256], othertranslation[256], myreverse[256], otherreverse[256];
TArray<double> myluminosity, otherluminosity;

SimpleTranslation(mycolors, mytranslation, myreverse, myluminosity);
SimpleTranslation(othercolors, othertranslation, otherreverse, otherluminosity);

FRemapTable remap(ActiveColors);
remap.Remap[0] = 0;
remap.Palette[0] = 0;
remap.ForFont = true;

for (unsigned l = 1; l < myluminosity.Size(); l++)
{
for (unsigned o = 1; o < otherluminosity.Size()-1; o++) // luminosity[0] is for the transparent color
{
if (myluminosity[l] >= otherluminosity[o] && myluminosity[l] <= otherluminosity[o+1])
{
PalEntry color1 = GPalette.BaseColors[otherreverse[o]];
PalEntry color2 = GPalette.BaseColors[otherreverse[o+1]];
double weight = 0;
if (otherluminosity[o] != otherluminosity[o + 1])
{
weight = (myluminosity[l] - otherluminosity[o]) / (otherluminosity[o + 1] - otherluminosity[o]);
}
int r = int(color1.r + weight * (color2.r - color1.r));
int g = int(color1.g + weight * (color2.g - color1.g));
int b = int(color1.b + weight * (color2.b - color1.b));

r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
remap.Remap[l] = ColorMatcher.Pick(r, g, b);
remap.Palette[l] = PalEntry(255, r, g, b);
break;
}
}
}
Translations[CR_UNTRANSLATED] = GPalette.StoreTranslation(TRANSLATION_Internal, &remap);
forceremap = true;
}


//==========================================================================
//
// compare
Expand All @@ -668,66 +612,40 @@ static int compare (const void *arg1, const void *arg2)

//==========================================================================
//
// FFont :: SimpleTranslation
//
// Colorsused, translation, and reverse must all be 256 entry buffers.
// Colorsused must already be filled out.
// Translation be set to remap the source colors to a new range of
// consecutive colors based at 1 (0 is transparent).
// Reverse will be just the opposite of translation: It maps the new color
// range to the original colors.
// *Luminosity will be an array just large enough to hold the brightness
// levels of all the used colors, in consecutive order. It is sorted from
// darkest to lightest and scaled such that the darkest color is 0.0 and
// the brightest color is 1.0.
// The return value is the number of used colors and thus the number of
// entries in *luminosity.
// FFont :: GetLuminosity
//
//==========================================================================

int FFont::SimpleTranslation (uint32_t *colorsused, uint8_t *translation, uint8_t *reverse, TArray<double> &Luminosity, int* minlum, int* maxlum)
int FFont::GetLuminosity (uint32_t *colorsused, TArray<double> &Luminosity, int* minlum, int* maxlum)
{
double min, max, diver;
int i, j;

memset (translation, 0, 256);

reverse[0] = 0;
for (i = 1, j = 1; i < 256; i++)
{
if (colorsused[i])
{
reverse[j++] = i;
}
}

qsort (reverse+1, j-1, 1, compare);

Luminosity.Resize(j);
Luminosity.Resize(256);
Luminosity[0] = 0.0; // [BL] Prevent uninitalized memory
max = 0.0;
min = 100000000.0;
for (i = 1; i < j; i++)
for (int i = 1; i < 256; i++)
{
translation[reverse[i]] = i;

Luminosity[i] = RPART(GPalette.BaseColors[reverse[i]]) * 0.299 +
GPART(GPalette.BaseColors[reverse[i]]) * 0.587 +
BPART(GPalette.BaseColors[reverse[i]]) * 0.114;
if (Luminosity[i] > max)
max = Luminosity[i];
if (Luminosity[i] < min)
min = Luminosity[i];
if (colorsused[i])
{
Luminosity[i] = GPalette.BaseColors[i].r * 0.299 + GPalette.BaseColors[i].g * 0.587 + GPalette.BaseColors[i].b * 0.114;
if (Luminosity[i] > max) max = Luminosity[i];
if (Luminosity[i] < min) min = Luminosity[i];
}
else Luminosity[i] = -1; // this color is not of interest.
}
diver = 1.0 / (max - min);
for (i = 1; i < j; i++)
for (int i = 1; i < 256; i++)
{
Luminosity[i] = (Luminosity[i] - min) * diver;
if (colorsused[i])
{
Luminosity[i] = (Luminosity[i] - min) * diver;
}
}
if (minlum) *minlum = int(min);
if (maxlum) *maxlum = int(max);

return j;
return 256;
}

//==========================================================================
Expand All @@ -748,7 +666,7 @@ int FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
}
if (color != nullptr) *color = retcolor;
}
if (ActiveColors == 0 || range == CR_UNDEFINED)
if (range == CR_UNDEFINED)
return -1;
else if (range >= NumTextColors)
range = CR_UNTRANSLATED;
Expand Down Expand Up @@ -1046,7 +964,6 @@ void FFont::LoadTranslations()
{
unsigned int count = LastChar - FirstChar + 1;
uint32_t usedcolors[256] = {};
uint8_t identity[256];
TArray<double> Luminosity;

for (unsigned int i = 0; i < count; i++)
Expand All @@ -1059,7 +976,7 @@ void FFont::LoadTranslations()
}

int minlum = 0, maxlum = 0;
ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, Luminosity, &minlum, &maxlum);
GetLuminosity (usedcolors, Luminosity, &minlum, &maxlum);

// Here we can set everything to a luminosity translation.

Expand All @@ -1068,7 +985,7 @@ void FFont::LoadTranslations()
for (int i = 0; i < NumTextColors; i++)
{
if (i == CR_UNTRANSLATED) Translations[i] = 0;
else Translations[i] = LuminosityTranslation(i*2, minlum, maxlum);
else Translations[i] = LuminosityTranslation(i*2 + TranslationType, minlum, maxlum);
}
}

Expand Down
52 changes: 0 additions & 52 deletions source/common/fonts/hexfont.cpp
Expand Up @@ -395,58 +395,6 @@ class FHexFont2 : public FFont
else Translations[i] = LuminosityTranslation(i * 2, minlum, maxlum);
}
}

void SetDefaultTranslation(uint32_t *colors) override
{
double myluminosity[18];

myluminosity[0] = 0;
for (int i = 1; i < 18; i++)
{
myluminosity[i] = (i - 1) / 16.;
}

uint8_t othertranslation[256], otherreverse[256];
TArray<double> otherluminosity;

SimpleTranslation(colors, othertranslation, otherreverse, otherluminosity);

FRemapTable remap(ActiveColors);
remap.Remap[0] = 0;
remap.Palette[0] = 0;
remap.ForFont = true;

for (unsigned l = 1; l < 18; l++)
{
for (unsigned o = 1; o < otherluminosity.Size() - 1; o++) // luminosity[0] is for the transparent color
{
if (myluminosity[l] >= otherluminosity[o] && myluminosity[l] <= otherluminosity[o + 1])
{
PalEntry color1 = GPalette.BaseColors[otherreverse[o]];
PalEntry color2 = GPalette.BaseColors[otherreverse[o + 1]];
double weight = 0;
if (otherluminosity[o] != otherluminosity[o + 1])
{
weight = (myluminosity[l] - otherluminosity[o]) / (otherluminosity[o + 1] - otherluminosity[o]);
}
int r = int(color1.r + weight * (color2.r - color1.r));
int g = int(color1.g + weight * (color2.g - color1.g));
int b = int(color1.b + weight * (color2.b - color1.b));

r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
remap.Remap[l] = ColorMatcher.Pick(r, g, b);
remap.Palette[l] = PalEntry(255, r, g, b);
break;
}
}
}
Translations[CR_UNTRANSLATED] = GPalette.StoreTranslation(TRANSLATION_Internal, &remap);
forceremap = true;

}

};


Expand Down
3 changes: 2 additions & 1 deletion source/common/fonts/singlelumpfont.cpp
Expand Up @@ -105,6 +105,7 @@ class FSingleLumpFont : public FFont
} FontType;
PalEntry Palette[256];
bool RescalePalette;
int ActiveColors = -1;
};


Expand Down Expand Up @@ -468,7 +469,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
// FSingleLumpFont :: CheckFON1Chars
//
// Scans a FON1 resource for all the color values it uses and sets up
// some tables like SimpleTranslation. Data points to the RLE data for
// some tables. Data points to the RLE data for
// the characters. Also sets up the character textures.
//
//==========================================================================
Expand Down
1 change: 0 additions & 1 deletion source/common/fonts/singlepicfont.cpp
Expand Up @@ -79,7 +79,6 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
SpaceWidth = (int)pic->GetDisplayWidth();
GlobalKerning = 0;
FirstChar = LastChar = 'A';
ActiveColors = 0;
PicNum = picnum;

Next = FirstFont;
Expand Down
5 changes: 0 additions & 5 deletions source/common/fonts/specialfont.cpp
Expand Up @@ -129,11 +129,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture
}

FixXMoves();

if (noTranslate)
{
ActiveColors = 0;
}
}

//==========================================================================
Expand Down

0 comments on commit 4ff4fa6

Please sign in to comment.