mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 08:31:45 +00:00
- moved the V_GetColor family of functions to the global palette utilities.
This commit is contained in:
parent
1479e3a1c3
commit
e425615770
5 changed files with 244 additions and 239 deletions
|
@ -37,6 +37,8 @@
|
|||
#include "palentry.h"
|
||||
#include "sc_man.h"
|
||||
#include "files.h"
|
||||
#include "filesystem.h"
|
||||
#include "printf.h"
|
||||
|
||||
/****************************/
|
||||
/* Palette management stuff */
|
||||
|
@ -467,3 +469,228 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
|||
// 256 entries are different. :-)
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColorFromString
|
||||
//
|
||||
// Passed a string of the form "#RGB", "#RRGGBB", "R G B", or "RR GG BB",
|
||||
// returns a number representing that color. If palette is non-NULL, the
|
||||
// index of the best match in the palette is returned, otherwise the
|
||||
// RRGGBB value is returned directly.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int V_GetColorFromString(const uint32_t* palette, const char* cstr, FScriptPosition* sc)
|
||||
{
|
||||
int c[3], i, p;
|
||||
char val[3];
|
||||
|
||||
val[2] = '\0';
|
||||
|
||||
// Check for HTML-style #RRGGBB or #RGB color string
|
||||
if (cstr[0] == '#')
|
||||
{
|
||||
size_t len = strlen(cstr);
|
||||
|
||||
if (len == 7)
|
||||
{
|
||||
// Extract each eight-bit component into c[].
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
val[0] = cstr[1 + i * 2];
|
||||
val[1] = cstr[2 + i * 2];
|
||||
c[i] = ParseHex(val, sc);
|
||||
}
|
||||
}
|
||||
else if (len == 4)
|
||||
{
|
||||
// Extract each four-bit component into c[], expanding to eight bits.
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
val[1] = val[0] = cstr[1 + i];
|
||||
c[i] = ParseHex(val, sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bad HTML-style; pretend it's black.
|
||||
c[2] = c[1] = c[0] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(cstr) == 6)
|
||||
{
|
||||
char* p;
|
||||
int color = strtol(cstr, &p, 16);
|
||||
if (*p == 0)
|
||||
{
|
||||
// RRGGBB string
|
||||
c[0] = (color & 0xff0000) >> 16;
|
||||
c[1] = (color & 0xff00) >> 8;
|
||||
c[2] = (color & 0xff);
|
||||
}
|
||||
else goto normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
normal:
|
||||
// Treat it as a space-delimited hexadecimal string
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
// Skip leading whitespace
|
||||
while (*cstr <= ' ' && *cstr != '\0')
|
||||
{
|
||||
cstr++;
|
||||
}
|
||||
// Extract a component and convert it to eight-bit
|
||||
for (p = 0; *cstr > ' '; ++p, ++cstr)
|
||||
{
|
||||
if (p < 2)
|
||||
{
|
||||
val[p] = *cstr;
|
||||
}
|
||||
}
|
||||
if (p == 0)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p == 1)
|
||||
{
|
||||
val[1] = val[0];
|
||||
}
|
||||
c[i] = ParseHex(val, sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (palette)
|
||||
return BestColor(palette, c[0], c[1], c[2]);
|
||||
else
|
||||
return MAKERGB(c[0], c[1], c[2]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColorStringByName
|
||||
//
|
||||
// Searches for the given color name in x11r6rgb.txt and returns an
|
||||
// HTML-ish "#RRGGBB" string for it if found or the empty string if not.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString V_GetColorStringByName(const char* name, FScriptPosition* sc)
|
||||
{
|
||||
FileData rgbNames;
|
||||
char* rgbEnd;
|
||||
char* rgb, * endp;
|
||||
int rgblump;
|
||||
int c[3], step;
|
||||
size_t namelen;
|
||||
|
||||
if (fileSystem.GetNumEntries() == 0) return FString();
|
||||
|
||||
rgblump = fileSystem.CheckNumForName("X11R6RGB");
|
||||
if (rgblump == -1)
|
||||
{
|
||||
if (!sc) Printf("X11R6RGB lump not found\n");
|
||||
else sc->Message(MSG_WARNING, "X11R6RGB lump not found");
|
||||
return FString();
|
||||
}
|
||||
|
||||
rgbNames = fileSystem.ReadFile(rgblump);
|
||||
rgb = (char*)rgbNames.GetMem();
|
||||
rgbEnd = rgb + fileSystem.FileLength(rgblump);
|
||||
step = 0;
|
||||
namelen = strlen(name);
|
||||
|
||||
while (rgb < rgbEnd)
|
||||
{
|
||||
// Skip white space
|
||||
if (*rgb <= ' ')
|
||||
{
|
||||
do
|
||||
{
|
||||
rgb++;
|
||||
} while (rgb < rgbEnd && *rgb <= ' ');
|
||||
}
|
||||
else if (step == 0 && *rgb == '!')
|
||||
{ // skip comment lines
|
||||
do
|
||||
{
|
||||
rgb++;
|
||||
} while (rgb < rgbEnd && *rgb != '\n');
|
||||
}
|
||||
else if (step < 3)
|
||||
{ // collect RGB values
|
||||
c[step++] = strtoul(rgb, &endp, 10);
|
||||
if (endp == rgb)
|
||||
{
|
||||
break;
|
||||
}
|
||||
rgb = endp;
|
||||
}
|
||||
else
|
||||
{ // Check color name
|
||||
endp = rgb;
|
||||
// Find the end of the line
|
||||
while (endp < rgbEnd && *endp != '\n')
|
||||
endp++;
|
||||
// Back up over any whitespace
|
||||
while (endp > rgb && *endp <= ' ')
|
||||
endp--;
|
||||
if (endp == rgb)
|
||||
{
|
||||
break;
|
||||
}
|
||||
size_t checklen = ++endp - rgb;
|
||||
if (checklen == namelen && strnicmp(rgb, name, checklen) == 0)
|
||||
{
|
||||
FString descr;
|
||||
descr.Format("#%02x%02x%02x", c[0], c[1], c[2]);
|
||||
return descr;
|
||||
}
|
||||
rgb = endp;
|
||||
step = 0;
|
||||
}
|
||||
}
|
||||
if (rgb < rgbEnd)
|
||||
{
|
||||
if (!sc) Printf("X11R6RGB lump is corrupt\n");
|
||||
else sc->Message(MSG_WARNING, "X11R6RGB lump is corrupt");
|
||||
}
|
||||
return FString();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColor
|
||||
//
|
||||
// Works like V_GetColorFromString(), but also understands X11 color names.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int V_GetColor(const uint32_t* palette, const char* str, FScriptPosition* sc)
|
||||
{
|
||||
FString string = V_GetColorStringByName(str, sc);
|
||||
int res;
|
||||
|
||||
if (!string.IsEmpty())
|
||||
{
|
||||
res = V_GetColorFromString(palette, string, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = V_GetColorFromString(palette, str, sc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int V_GetColor(const uint32_t* palette, FScanner& sc)
|
||||
{
|
||||
FScriptPosition scc = sc;
|
||||
return V_GetColor(palette, sc.String, &scc);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <stdint.h>
|
||||
#include "palentry.h"
|
||||
|
||||
struct FScriptPosition;
|
||||
class FScanner;
|
||||
|
||||
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);
|
||||
void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int b, int a);
|
||||
|
@ -16,3 +19,13 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap);
|
|||
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);
|
||||
|
||||
// Returns the closest color to the one desired. String
|
||||
// should be of the form "rr gg bb".
|
||||
int V_GetColorFromString(const uint32_t* palette, const char* colorstring, FScriptPosition* sc = nullptr);
|
||||
// Scans through the X11R6RGB lump for a matching color
|
||||
// and returns a color string suitable for V_GetColorFromString.
|
||||
FString V_GetColorStringByName(const char* name, FScriptPosition* sc = nullptr);
|
||||
|
||||
// Tries to get color by name, then by string
|
||||
int V_GetColor(const uint32_t* palette, const char* str, FScriptPosition* sc = nullptr);
|
||||
int V_GetColor(const uint32_t* palette, FScanner& sc);
|
||||
|
|
|
@ -42,8 +42,7 @@
|
|||
#include "c_cvars.h"
|
||||
#include "engineerrors.h"
|
||||
#include "printf.h"
|
||||
|
||||
#include "v_video.h" // for color lookup - move to utility code!!!
|
||||
#include "palutil.h"
|
||||
|
||||
//#include "version.h"
|
||||
|
||||
|
@ -820,12 +819,13 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type)
|
|||
|
||||
if (type == CVAR_String)
|
||||
{
|
||||
FString string;
|
||||
FString string = V_GetColorStringByName(value.String);
|
||||
// Only allow named colors after the screen exists (i.e. after
|
||||
// we've got some lumps loaded, so X11R6RGB can be read). Since
|
||||
// the only time this might be called before that is when loading
|
||||
// zdoom.ini, this shouldn't be a problem.
|
||||
if (screen && !(string = V_GetColorStringByName (value.String)).IsEmpty() )
|
||||
|
||||
if (string.IsNotEmpty())
|
||||
{
|
||||
ret = V_GetColorFromString (NULL, string);
|
||||
}
|
||||
|
|
|
@ -266,231 +266,6 @@ void DCanvas::Resize(int width, int height, bool optimizepitch)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColorFromString
|
||||
//
|
||||
// Passed a string of the form "#RGB", "#RRGGBB", "R G B", or "RR GG BB",
|
||||
// returns a number representing that color. If palette is non-NULL, the
|
||||
// index of the best match in the palette is returned, otherwise the
|
||||
// RRGGBB value is returned directly.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int V_GetColorFromString (const uint32_t *palette, const char *cstr, FScriptPosition *sc)
|
||||
{
|
||||
int c[3], i, p;
|
||||
char val[3];
|
||||
|
||||
val[2] = '\0';
|
||||
|
||||
// Check for HTML-style #RRGGBB or #RGB color string
|
||||
if (cstr[0] == '#')
|
||||
{
|
||||
size_t len = strlen (cstr);
|
||||
|
||||
if (len == 7)
|
||||
{
|
||||
// Extract each eight-bit component into c[].
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
val[0] = cstr[1 + i*2];
|
||||
val[1] = cstr[2 + i*2];
|
||||
c[i] = ParseHex (val, sc);
|
||||
}
|
||||
}
|
||||
else if (len == 4)
|
||||
{
|
||||
// Extract each four-bit component into c[], expanding to eight bits.
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
val[1] = val[0] = cstr[1 + i];
|
||||
c[i] = ParseHex (val, sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bad HTML-style; pretend it's black.
|
||||
c[2] = c[1] = c[0] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(cstr) == 6)
|
||||
{
|
||||
char *p;
|
||||
int color = strtol(cstr, &p, 16);
|
||||
if (*p == 0)
|
||||
{
|
||||
// RRGGBB string
|
||||
c[0] = (color & 0xff0000) >> 16;
|
||||
c[1] = (color & 0xff00) >> 8;
|
||||
c[2] = (color & 0xff);
|
||||
}
|
||||
else goto normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
normal:
|
||||
// Treat it as a space-delimited hexadecimal string
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
// Skip leading whitespace
|
||||
while (*cstr <= ' ' && *cstr != '\0')
|
||||
{
|
||||
cstr++;
|
||||
}
|
||||
// Extract a component and convert it to eight-bit
|
||||
for (p = 0; *cstr > ' '; ++p, ++cstr)
|
||||
{
|
||||
if (p < 2)
|
||||
{
|
||||
val[p] = *cstr;
|
||||
}
|
||||
}
|
||||
if (p == 0)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p == 1)
|
||||
{
|
||||
val[1] = val[0];
|
||||
}
|
||||
c[i] = ParseHex (val, sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (palette)
|
||||
return ColorMatcher.Pick (c[0], c[1], c[2]);
|
||||
else
|
||||
return MAKERGB(c[0], c[1], c[2]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColorStringByName
|
||||
//
|
||||
// Searches for the given color name in x11r6rgb.txt and returns an
|
||||
// HTML-ish "#RRGGBB" string for it if found or the empty string if not.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString V_GetColorStringByName (const char *name, FScriptPosition *sc)
|
||||
{
|
||||
FileData rgbNames;
|
||||
char *rgbEnd;
|
||||
char *rgb, *endp;
|
||||
int rgblump;
|
||||
int c[3], step;
|
||||
size_t namelen;
|
||||
|
||||
if (fileSystem.GetNumEntries()==0) return FString();
|
||||
|
||||
rgblump = fileSystem.CheckNumForName ("X11R6RGB");
|
||||
if (rgblump == -1)
|
||||
{
|
||||
if (!sc) Printf ("X11R6RGB lump not found\n");
|
||||
else sc->Message(MSG_WARNING, "X11R6RGB lump not found");
|
||||
return FString();
|
||||
}
|
||||
|
||||
rgbNames = fileSystem.ReadFile (rgblump);
|
||||
rgb = (char *)rgbNames.GetMem();
|
||||
rgbEnd = rgb + fileSystem.FileLength (rgblump);
|
||||
step = 0;
|
||||
namelen = strlen (name);
|
||||
|
||||
while (rgb < rgbEnd)
|
||||
{
|
||||
// Skip white space
|
||||
if (*rgb <= ' ')
|
||||
{
|
||||
do
|
||||
{
|
||||
rgb++;
|
||||
} while (rgb < rgbEnd && *rgb <= ' ');
|
||||
}
|
||||
else if (step == 0 && *rgb == '!')
|
||||
{ // skip comment lines
|
||||
do
|
||||
{
|
||||
rgb++;
|
||||
} while (rgb < rgbEnd && *rgb != '\n');
|
||||
}
|
||||
else if (step < 3)
|
||||
{ // collect RGB values
|
||||
c[step++] = strtoul (rgb, &endp, 10);
|
||||
if (endp == rgb)
|
||||
{
|
||||
break;
|
||||
}
|
||||
rgb = endp;
|
||||
}
|
||||
else
|
||||
{ // Check color name
|
||||
endp = rgb;
|
||||
// Find the end of the line
|
||||
while (endp < rgbEnd && *endp != '\n')
|
||||
endp++;
|
||||
// Back up over any whitespace
|
||||
while (endp > rgb && *endp <= ' ')
|
||||
endp--;
|
||||
if (endp == rgb)
|
||||
{
|
||||
break;
|
||||
}
|
||||
size_t checklen = ++endp - rgb;
|
||||
if (checklen == namelen && strnicmp (rgb, name, checklen) == 0)
|
||||
{
|
||||
FString descr;
|
||||
descr.Format ("#%02x%02x%02x", c[0], c[1], c[2]);
|
||||
return descr;
|
||||
}
|
||||
rgb = endp;
|
||||
step = 0;
|
||||
}
|
||||
}
|
||||
if (rgb < rgbEnd)
|
||||
{
|
||||
if (!sc) Printf ("X11R6RGB lump is corrupt\n");
|
||||
else sc->Message(MSG_WARNING, "X11R6RGB lump is corrupt");
|
||||
}
|
||||
return FString();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColor
|
||||
//
|
||||
// Works like V_GetColorFromString(), but also understands X11 color names.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int V_GetColor (const uint32_t *palette, const char *str, FScriptPosition *sc)
|
||||
{
|
||||
FString string = V_GetColorStringByName (str, sc);
|
||||
int res;
|
||||
|
||||
if (!string.IsEmpty())
|
||||
{
|
||||
res = V_GetColorFromString (palette, string, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = V_GetColorFromString (palette, str, sc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int V_GetColor(const uint32_t *palette, FScanner &sc)
|
||||
{
|
||||
FScriptPosition scc = sc;
|
||||
return V_GetColor(palette, sc.String, &scc);
|
||||
}
|
||||
|
||||
CCMD(clean)
|
||||
{
|
||||
Printf ("CleanXfac: %d\nCleanYfac: %d\n", CleanXfac, CleanYfac);
|
||||
|
|
|
@ -613,16 +613,6 @@ void V_Shutdown ();
|
|||
|
||||
class FScanner;
|
||||
struct FScriptPosition;
|
||||
// Returns the closest color to the one desired. String
|
||||
// should be of the form "rr gg bb".
|
||||
int V_GetColorFromString (const uint32_t *palette, const char *colorstring, FScriptPosition *sc = nullptr);
|
||||
// Scans through the X11R6RGB lump for a matching color
|
||||
// and returns a color string suitable for V_GetColorFromString.
|
||||
FString V_GetColorStringByName (const char *name, FScriptPosition *sc = nullptr);
|
||||
|
||||
// Tries to get color by name, then by string
|
||||
int V_GetColor (const uint32_t *palette, const char *str, FScriptPosition *sc = nullptr);
|
||||
int V_GetColor(const uint32_t *palette, FScanner &sc);
|
||||
|
||||
inline bool IsRatioWidescreen(int ratio) { return (ratio & 3) != 0; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue