Added 'COLOR' resource type.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3370 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
Changes towards version 0.7:
|
Changes towards version 0.7:
|
||||||
|
- Added 'COLOR' resource type - SvdB
|
||||||
- All graphics operations use 24-bits colors at the game level too now,
|
- All graphics operations use 24-bits colors at the game level too now,
|
||||||
instead of 16 bits colors. - SvdB
|
instead of 16 bits colors. - SvdB
|
||||||
- Cross-platform safemode (ignores uqm.cfg, bug #946) - Michael
|
- Cross-platform safemode (ignores uqm.cfg, bug #946) - Michael
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
#define _GFXLIB_H
|
#define _GFXLIB_H
|
||||||
|
|
||||||
#include "libs/compiler.h"
|
#include "libs/compiler.h"
|
||||||
|
|
||||||
|
typedef struct Color Color;
|
||||||
|
|
||||||
#include "libs/reslib.h"
|
#include "libs/reslib.h"
|
||||||
|
|
||||||
typedef struct context_desc CONTEXT_DESC;
|
typedef struct context_desc CONTEXT_DESC;
|
||||||
@@ -39,12 +42,12 @@ typedef UWORD TIME_VALUE;
|
|||||||
|
|
||||||
typedef SWORD COORD;
|
typedef SWORD COORD;
|
||||||
|
|
||||||
typedef struct Color {
|
struct Color {
|
||||||
BYTE r;
|
BYTE r;
|
||||||
BYTE g;
|
BYTE g;
|
||||||
BYTE b;
|
BYTE b;
|
||||||
BYTE a; // Currently unused
|
BYTE a; // Currently unused
|
||||||
} Color;
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
sameColor(Color c1, Color c2)
|
sameColor(Color c1, Color c2)
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ void *GetResourceData (uio_Stream *fp, DWORD length);
|
|||||||
BOOLEAN FreeResourceData (void *);
|
BOOLEAN FreeResourceData (void *);
|
||||||
|
|
||||||
#include "strlib.h"
|
#include "strlib.h"
|
||||||
|
#include "gfxlib.h"
|
||||||
|
// For Color
|
||||||
|
|
||||||
typedef STRING_TABLE DIRENTRY_REF;
|
typedef STRING_TABLE DIRENTRY_REF;
|
||||||
typedef STRING DIRENTRY;
|
typedef STRING DIRENTRY;
|
||||||
@@ -114,6 +116,10 @@ BOOLEAN res_IsBoolean (const char *key);
|
|||||||
BOOLEAN res_GetBoolean (const char *key);
|
BOOLEAN res_GetBoolean (const char *key);
|
||||||
void res_PutBoolean (const char *key, BOOLEAN value);
|
void res_PutBoolean (const char *key, BOOLEAN value);
|
||||||
|
|
||||||
|
BOOLEAN res_IsColor (const char *key);
|
||||||
|
Color res_GetColor (const char *key);
|
||||||
|
void res_PutColor (const char *key, Color value);
|
||||||
|
|
||||||
BOOLEAN res_Remove (const char *key);
|
BOOLEAN res_Remove (const char *key);
|
||||||
|
|
||||||
#endif /* _RESLIB_H */
|
#endif /* _RESLIB_H */
|
||||||
|
|||||||
@@ -160,6 +160,128 @@ DescriptorToBoolean (const char *descriptor, RESOURCE_DATA *resdata)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
skipWhiteSpace (const char *start)
|
||||||
|
{
|
||||||
|
const char *ptr = start;
|
||||||
|
while (isspace (*ptr))
|
||||||
|
ptr++;
|
||||||
|
return (ptr - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On success, resdata->num will be filled with a 32-bits RGBA value.
|
||||||
|
static void
|
||||||
|
DescriptorToColor (const char *descriptor, RESOURCE_DATA *resdata)
|
||||||
|
{
|
||||||
|
int bytesParsed;
|
||||||
|
int componentBits;
|
||||||
|
int maxComponentValue;
|
||||||
|
size_t componentCount;
|
||||||
|
size_t compI;;
|
||||||
|
int comps[4];
|
||||||
|
// One element for each of r, g, b, a.
|
||||||
|
|
||||||
|
descriptor += skipWhiteSpace (descriptor);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Can't use this; '#' starts a comment.
|
||||||
|
if (*descriptor == '#')
|
||||||
|
{
|
||||||
|
// "#rrggbb"
|
||||||
|
int i;
|
||||||
|
DWORD value = 0;
|
||||||
|
|
||||||
|
descriptor++;
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
BYTE nibbleValue;
|
||||||
|
if (*descriptor >= '0' && *descriptor <= '9')
|
||||||
|
nibbleValue = *descriptor - '0';
|
||||||
|
else if (*descriptor >= 'a' && *descriptor <= 'f')
|
||||||
|
nibbleValue = 0xa + *descriptor - 'a';
|
||||||
|
else if (*descriptor >= 'A' && *descriptor <= 'F')
|
||||||
|
nibbleValue = 0xa + *descriptor - 'A';
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
value = (value * 16) + nibbleValue;
|
||||||
|
descriptor++;
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor += skipWhiteSpace (descriptor);
|
||||||
|
|
||||||
|
if (*descriptor != '\0')
|
||||||
|
log_add (log_Warning, "Junk after color resource string.");
|
||||||
|
|
||||||
|
resdata->num = (value << 8) | 0xff;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Color is of the form "rgb(r, g, b)", "rgba(r, g, b, a)",
|
||||||
|
// or "rgb15(r, g, b)".
|
||||||
|
|
||||||
|
if (sscanf (descriptor, "rgb ( %i , %i , %i ) %n",
|
||||||
|
&comps[0], &comps[1], &comps[2], &bytesParsed) >= 3)
|
||||||
|
{
|
||||||
|
componentBits = 8;
|
||||||
|
componentCount = 3;
|
||||||
|
comps[3] = 0xff;
|
||||||
|
}
|
||||||
|
else if (sscanf (descriptor, "rgba ( %i , %i , %i , %i ) %n",
|
||||||
|
&comps[0], &comps[1], &comps[2], &comps[3], &bytesParsed) >= 4)
|
||||||
|
{
|
||||||
|
componentBits = 8;
|
||||||
|
componentCount = 4;
|
||||||
|
}
|
||||||
|
else if (sscanf (descriptor, "rgb15 ( %i , %i , %i ) %n",
|
||||||
|
&comps[0], &comps[1], &comps[2], &bytesParsed) >= 3)
|
||||||
|
{
|
||||||
|
componentBits = 5;
|
||||||
|
componentCount = 3;
|
||||||
|
comps[3] = 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (descriptor[bytesParsed] != '\0')
|
||||||
|
log_add (log_Warning, "Junk after color resource string.");
|
||||||
|
|
||||||
|
maxComponentValue = (1 << componentBits) - 1;
|
||||||
|
|
||||||
|
// Check the range of the components.
|
||||||
|
for (compI = 0; compI < componentCount; compI++)
|
||||||
|
{
|
||||||
|
if (comps[compI] < 0)
|
||||||
|
{
|
||||||
|
comps[compI] = 0;
|
||||||
|
log_add (log_Warning, "Color component value too small; "
|
||||||
|
"value clipped.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comps[compI] > (long) maxComponentValue)
|
||||||
|
{
|
||||||
|
comps[compI] = maxComponentValue;
|
||||||
|
log_add (log_Warning, "Color component value too large; "
|
||||||
|
"value clipped.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (componentBits == 5)
|
||||||
|
resdata->num = ((CC5TO8 (comps[0]) << 24) |
|
||||||
|
(CC5TO8 (comps[1]) << 16) | (CC5TO8 (comps[2]) << 8) |
|
||||||
|
comps[3]);
|
||||||
|
else
|
||||||
|
resdata->num = ((comps[0] << 24) | (comps[1] << 16) |
|
||||||
|
(comps[2] << 8) | comps[3]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
log_add (log_Error, "Invalid color description string for resource.\n");
|
||||||
|
resdata->num = 0x00000000;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
RawDescriptor (RESOURCE_DATA *resdata, char *buf, unsigned int size)
|
RawDescriptor (RESOURCE_DATA *resdata, char *buf, unsigned int size)
|
||||||
{
|
{
|
||||||
@@ -179,6 +301,25 @@ BooleanToString (RESOURCE_DATA *resdata, char *buf, unsigned int size)
|
|||||||
snprintf (buf, size, "%s", resdata->num ? "true" : "false");
|
snprintf (buf, size, "%s", resdata->num ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ColorToString (RESOURCE_DATA *resdata, char *buf, unsigned int size)
|
||||||
|
{
|
||||||
|
if ((resdata->num & 0xff) == 0xff)
|
||||||
|
{
|
||||||
|
// Opaque color, save as "rgb".
|
||||||
|
snprintf (buf, size, "rgb(0x%02x, 0x%02x, 0x%02x)",
|
||||||
|
(resdata->num >> 24), (resdata->num >> 16) & 0xff,
|
||||||
|
(resdata->num >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// (Partially) transparent color, save as "rgba".
|
||||||
|
snprintf (buf, size, "rgba(0x%02x, 0x%02x, 0x%02x, 0x%02x)",
|
||||||
|
(resdata->num >> 24), (resdata->num >> 16) & 0xff,
|
||||||
|
(resdata->num >> 8) & 0xff, resdata->num & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static RESOURCE_INDEX curResourceIndex;
|
static RESOURCE_INDEX curResourceIndex;
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -201,7 +342,9 @@ InitResourceSystem (void)
|
|||||||
InstallResTypeVectors ("UNKNOWNRES", UseDescriptorAsRes, NULL, NULL);
|
InstallResTypeVectors ("UNKNOWNRES", UseDescriptorAsRes, NULL, NULL);
|
||||||
InstallResTypeVectors ("STRING", UseDescriptorAsRes, NULL, RawDescriptor);
|
InstallResTypeVectors ("STRING", UseDescriptorAsRes, NULL, RawDescriptor);
|
||||||
InstallResTypeVectors ("INT32", DescriptorToInt, NULL, IntToString);
|
InstallResTypeVectors ("INT32", DescriptorToInt, NULL, IntToString);
|
||||||
InstallResTypeVectors ("BOOLEAN", DescriptorToBoolean, NULL, BooleanToString);
|
InstallResTypeVectors ("BOOLEAN", DescriptorToBoolean, NULL,
|
||||||
|
BooleanToString);
|
||||||
|
InstallResTypeVectors ("COLOR", DescriptorToColor, NULL, ColorToString);
|
||||||
InstallGraphicResTypes ();
|
InstallGraphicResTypes ();
|
||||||
InstallStringTableResType ();
|
InstallStringTableResType ();
|
||||||
InstallAudioResTypes ();
|
InstallAudioResTypes ();
|
||||||
@@ -436,6 +579,47 @@ res_PutBoolean (const char *key, BOOLEAN value)
|
|||||||
desc->resdata.num = value;
|
desc->resdata.num = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
res_IsColor (const char *key)
|
||||||
|
{
|
||||||
|
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||||
|
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||||
|
return desc && !strcmp(desc->vtable->resType, "COLOR");
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
res_GetColor (const char *key)
|
||||||
|
{
|
||||||
|
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||||
|
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||||
|
DWORD num;
|
||||||
|
if (!desc || strcmp(desc->vtable->resType, "COLOR"))
|
||||||
|
{
|
||||||
|
// TODO: Better error handling
|
||||||
|
return buildColorRgba (0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
num = desc->resdata.num;
|
||||||
|
return buildColorRgba (num >> 24, (num >> 16) & 0xff,
|
||||||
|
(desc->resdata.num >> 8) & 0xff, num & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_PutColor (const char *key, Color value)
|
||||||
|
{
|
||||||
|
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||||
|
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||||
|
if (!desc || strcmp(desc->vtable->resType, "COLOR"))
|
||||||
|
{
|
||||||
|
/* TODO: This is kind of roundabout. We can do better by refactoring
|
||||||
|
* newResourceDesc */
|
||||||
|
process_resource_desc(key, "COLOR:#000000");
|
||||||
|
desc = lookupResourceDesc (idx, key);
|
||||||
|
}
|
||||||
|
desc->resdata.num =
|
||||||
|
(value.r << 24) | (value.g << 16) | (value.b << 8) | value.a;
|
||||||
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
res_HasKey (const char *key)
|
res_HasKey (const char *key)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user