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:
Meep-Eep
2009-11-29 23:32:02 +00:00
parent 85a10c006c
commit 75c11e7822
4 changed files with 197 additions and 3 deletions
+1
View File
@@ -1,4 +1,5 @@
Changes towards version 0.7:
- Added 'COLOR' resource type - SvdB
- All graphics operations use 24-bits colors at the game level too now,
instead of 16 bits colors. - SvdB
- Cross-platform safemode (ignores uqm.cfg, bug #946) - Michael
+5 -2
View File
@@ -20,6 +20,9 @@
#define _GFXLIB_H
#include "libs/compiler.h"
typedef struct Color Color;
#include "libs/reslib.h"
typedef struct context_desc CONTEXT_DESC;
@@ -39,12 +42,12 @@ typedef UWORD TIME_VALUE;
typedef SWORD COORD;
typedef struct Color {
struct Color {
BYTE r;
BYTE g;
BYTE b;
BYTE a; // Currently unused
} Color;
};
static inline bool
sameColor(Color c1, Color c2)
+6
View File
@@ -79,6 +79,8 @@ void *GetResourceData (uio_Stream *fp, DWORD length);
BOOLEAN FreeResourceData (void *);
#include "strlib.h"
#include "gfxlib.h"
// For Color
typedef STRING_TABLE DIRENTRY_REF;
typedef STRING DIRENTRY;
@@ -114,6 +116,10 @@ BOOLEAN res_IsBoolean (const char *key);
BOOLEAN res_GetBoolean (const char *key);
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);
#endif /* _RESLIB_H */
+185 -1
View File
@@ -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
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");
}
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;
void
@@ -201,7 +342,9 @@ InitResourceSystem (void)
InstallResTypeVectors ("UNKNOWNRES", UseDescriptorAsRes, NULL, NULL);
InstallResTypeVectors ("STRING", UseDescriptorAsRes, NULL, RawDescriptor);
InstallResTypeVectors ("INT32", DescriptorToInt, NULL, IntToString);
InstallResTypeVectors ("BOOLEAN", DescriptorToBoolean, NULL, BooleanToString);
InstallResTypeVectors ("BOOLEAN", DescriptorToBoolean, NULL,
BooleanToString);
InstallResTypeVectors ("COLOR", DescriptorToColor, NULL, ColorToString);
InstallGraphicResTypes ();
InstallStringTableResType ();
InstallAudioResTypes ();
@@ -436,6 +579,47 @@ res_PutBoolean (const char *key, BOOLEAN 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
res_HasKey (const char *key)
{