Added Uq-Ruan Masters game - it compiles but does not work (renders too slowly? Another problem?)
This commit is contained in:
2
project/jni/application/sc2/src/libs/resource/Makeinfo
Normal file
2
project/jni/application/sc2/src/libs/resource/Makeinfo
Normal file
@@ -0,0 +1,2 @@
|
||||
uqm_CFILES="direct.c filecntl.c getres.c loadres.c stringbank.c
|
||||
propfile.c resinit.c"
|
||||
101
project/jni/application/sc2/src/libs/resource/direct.c
Normal file
101
project/jni/application/sc2/src/libs/resource/direct.c
Normal file
@@ -0,0 +1,101 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/strings/strintrn.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "port.h"
|
||||
#include "libs/uio.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
DIRENTRY_REF
|
||||
LoadDirEntryTable (uio_DirHandle *dirHandle, const char *path,
|
||||
const char *pattern, match_MatchType matchType)
|
||||
{
|
||||
uio_DirList *dirList;
|
||||
COUNT num_entries;
|
||||
COUNT i;
|
||||
uio_DirHandle *dir;
|
||||
STRING_TABLE StringTable;
|
||||
STRING_TABLE_DESC *lpST;
|
||||
STRING lpLastString;
|
||||
|
||||
dir = uio_openDirRelative (dirHandle, path, 0);
|
||||
assert(dir != NULL);
|
||||
dirList = uio_getDirList (dir, "", pattern, matchType);
|
||||
assert(dirList != NULL);
|
||||
num_entries = 0;
|
||||
|
||||
// First, count the amount of space needed
|
||||
for (i = 0; i < dirList->numNames; i++)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (dirList->names[i][0] == '.')
|
||||
{
|
||||
dirList->names[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
if (uio_stat (dir, dirList->names[i], &sb) == -1)
|
||||
{
|
||||
dirList->names[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
if (!S_ISREG (sb.st_mode))
|
||||
{
|
||||
dirList->names[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
num_entries++;
|
||||
}
|
||||
uio_closeDir (dir);
|
||||
|
||||
if (num_entries == 0) {
|
||||
uio_DirList_free(dirList);
|
||||
return ((DIRENTRY_REF) 0);
|
||||
}
|
||||
|
||||
StringTable = AllocStringTable (num_entries, 0);
|
||||
lpST = StringTable;
|
||||
if (lpST == 0)
|
||||
{
|
||||
FreeStringTable (StringTable);
|
||||
uio_DirList_free(dirList);
|
||||
return ((DIRENTRY_REF) 0);
|
||||
}
|
||||
lpST->size = num_entries;
|
||||
lpLastString = lpST->strings;
|
||||
|
||||
for (i = 0; i < dirList->numNames; i++)
|
||||
{
|
||||
int size;
|
||||
STRINGPTR target;
|
||||
if (dirList->names[i] == NULL)
|
||||
continue;
|
||||
size = strlen (dirList->names[i]) + 1;
|
||||
target = HMalloc (size);
|
||||
memcpy (target, dirList->names[i], size);
|
||||
lpLastString->data = target;
|
||||
lpLastString->length = size;
|
||||
lpLastString++;
|
||||
}
|
||||
|
||||
uio_DirList_free(dirList);
|
||||
return StringTable;
|
||||
}
|
||||
|
||||
|
||||
146
project/jni/application/sc2/src/libs/resource/filecntl.c
Normal file
146
project/jni/application/sc2/src/libs/resource/filecntl.c
Normal file
@@ -0,0 +1,146 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "port.h"
|
||||
#include "resintrn.h"
|
||||
#include "libs/uio.h"
|
||||
|
||||
uio_Stream *
|
||||
res_OpenResFile (uio_DirHandle *dir, const char *filename, const char *mode)
|
||||
{
|
||||
uio_Stream *fp;
|
||||
struct stat sb;
|
||||
|
||||
if (uio_stat (dir, filename, &sb) == 0 && S_ISDIR(sb.st_mode))
|
||||
return ((uio_Stream *) ~0);
|
||||
|
||||
fp = uio_fopen (dir, filename, mode);
|
||||
|
||||
return (fp);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_CloseResFile (uio_Stream *fp)
|
||||
{
|
||||
if (fp)
|
||||
{
|
||||
if (fp != (uio_Stream *)~0)
|
||||
uio_fclose (fp);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DeleteResFile (uio_DirHandle *dir, const char *filename)
|
||||
{
|
||||
return (uio_unlink (dir, filename) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
ReadResFile (void *lpBuf, COUNT size, COUNT count, uio_Stream *fp)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = uio_fread (lpBuf, size, count, fp);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
WriteResFile (const void *lpBuf, COUNT size, COUNT count, uio_Stream *fp)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = uio_fwrite (lpBuf, size, count, fp);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
GetResFileChar (uio_Stream *fp)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = uio_getc (fp);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
PutResFileChar (char ch, uio_Stream *fp)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = uio_putc (ch, fp);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
PutResFileNewline (uio_Stream *fp)
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef WIN32
|
||||
PutResFileChar ('\r', fp);
|
||||
#endif
|
||||
retval = PutResFileChar ('\n', fp);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
long
|
||||
SeekResFile (uio_Stream *fp, long offset, int whence)
|
||||
{
|
||||
long retval;
|
||||
|
||||
retval = uio_fseek (fp, offset, whence);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
long
|
||||
TellResFile (uio_Stream *fp)
|
||||
{
|
||||
long retval;
|
||||
|
||||
retval = uio_ftell (fp);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
long
|
||||
LengthResFile (uio_Stream *fp)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (fp == (uio_Stream *)~0)
|
||||
return (1);
|
||||
if (uio_fstat(uio_streamHandle(fp), &sb) == -1)
|
||||
return 1;
|
||||
return sb.st_size;
|
||||
}
|
||||
|
||||
|
||||
257
project/jni/application/sc2/src/libs/resource/getres.c
Normal file
257
project/jni/application/sc2/src/libs/resource/getres.c
Normal file
@@ -0,0 +1,257 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "options.h"
|
||||
#include "port.h"
|
||||
#include "resintrn.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/uio/charhashtable.h"
|
||||
|
||||
const char *_cur_resfile_name;
|
||||
// When a file is being loaded, _cur_resfile_name is set to its name.
|
||||
// At other times, it is NULL.
|
||||
|
||||
ResourceDesc *
|
||||
lookupResourceDesc (RESOURCE_INDEX idx, RESOURCE res)
|
||||
{
|
||||
return (ResourceDesc *) CharHashTable_find (idx->map, res);
|
||||
}
|
||||
|
||||
void
|
||||
loadResourceDesc (ResourceDesc *desc)
|
||||
{
|
||||
desc->vtable->loadFun (desc->fname, &desc->resdata);
|
||||
}
|
||||
|
||||
void *
|
||||
LoadResourceFromPath (const char *path, ResourceLoadFileFun *loadFun)
|
||||
{
|
||||
uio_Stream *stream;
|
||||
long dataLen;
|
||||
void *resdata;
|
||||
|
||||
stream = res_OpenResFile (contentDir, path, "rb");
|
||||
if (stream == NULL)
|
||||
{
|
||||
log_add (log_Warning, "Warning: Can't open '%s'", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dataLen = LengthResFile (stream);
|
||||
log_add (log_Info, "\t'%s' -- %lu bytes", path, dataLen);
|
||||
|
||||
if (dataLen == 0)
|
||||
{
|
||||
log_add (log_Warning, "Warning: Trying to load empty file '%s'.", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
_cur_resfile_name = path;
|
||||
resdata = (*loadFun) (stream, dataLen);
|
||||
_cur_resfile_name = NULL;
|
||||
res_CloseResFile (stream);
|
||||
|
||||
return resdata;
|
||||
|
||||
err:
|
||||
res_CloseResFile (stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
res_GetResourceType (RESOURCE res)
|
||||
{
|
||||
RESOURCE_INDEX resourceIndex;
|
||||
ResourceDesc *desc;
|
||||
|
||||
if (res == NULL_RESOURCE)
|
||||
{
|
||||
log_add (log_Warning, "Trying to get type of null resource");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
resourceIndex = _get_current_index_header ();
|
||||
desc = lookupResourceDesc (resourceIndex, res);
|
||||
if (desc == NULL)
|
||||
{
|
||||
log_add (log_Warning, "Trying to get type of undefined resource '%s'",
|
||||
res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return desc->vtable->resType;
|
||||
}
|
||||
|
||||
|
||||
// Get a resource by its resource ID.
|
||||
void *
|
||||
res_GetResource (RESOURCE res)
|
||||
{
|
||||
RESOURCE_INDEX resourceIndex;
|
||||
ResourceDesc *desc;
|
||||
|
||||
if (res == NULL_RESOURCE)
|
||||
{
|
||||
log_add (log_Warning, "Trying to get null resource");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
resourceIndex = _get_current_index_header ();
|
||||
|
||||
desc = lookupResourceDesc (resourceIndex, res);
|
||||
if (desc == NULL)
|
||||
{
|
||||
log_add (log_Warning, "Trying to get undefined resource '%s'",
|
||||
res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (desc->resdata.ptr == NULL)
|
||||
loadResourceDesc (desc);
|
||||
if (desc->resdata.ptr != NULL)
|
||||
++desc->refcount;
|
||||
|
||||
return desc->resdata.ptr;
|
||||
// May still be NULL, if the load failed.
|
||||
}
|
||||
|
||||
DWORD
|
||||
res_GetIntResource (RESOURCE res)
|
||||
{
|
||||
RESOURCE_INDEX resourceIndex;
|
||||
ResourceDesc *desc;
|
||||
|
||||
if (res == NULL_RESOURCE)
|
||||
{
|
||||
log_add (log_Warning, "Trying to get null resource");
|
||||
return 0;
|
||||
}
|
||||
|
||||
resourceIndex = _get_current_index_header ();
|
||||
|
||||
desc = lookupResourceDesc (resourceIndex, res);
|
||||
if (desc == NULL)
|
||||
{
|
||||
log_add (log_Warning, "Trying to get undefined resource '%s'",
|
||||
res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return desc->resdata.num;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_GetBooleanResource (RESOURCE res)
|
||||
{
|
||||
return (res_GetIntResource (res) != 0);
|
||||
}
|
||||
|
||||
// NB: this function appears to be never called!
|
||||
void
|
||||
res_FreeResource (RESOURCE res)
|
||||
{
|
||||
ResourceDesc *desc;
|
||||
ResourceFreeFun *freeFun;
|
||||
|
||||
desc = lookupResourceDesc (_get_current_index_header(), res);
|
||||
if (desc == NULL)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to free an unrecognised "
|
||||
"resource.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (desc->refcount > 0)
|
||||
--desc->refcount;
|
||||
else
|
||||
log_add (log_Debug, "Warning: freeing an unreferenced resource.");
|
||||
if (desc->refcount > 0)
|
||||
return; // Still references left
|
||||
|
||||
freeFun = desc->vtable->freeFun;
|
||||
if (freeFun == NULL)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to free a non-heap resource.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (desc->resdata.ptr == NULL)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to free not loaded "
|
||||
"resource.");
|
||||
return;
|
||||
}
|
||||
|
||||
(*freeFun) (desc->resdata.ptr);
|
||||
desc->resdata.ptr = NULL;
|
||||
}
|
||||
|
||||
// By calling this function the caller will be responsible of unloading
|
||||
// the resource. If res_GetResource() get called again for this
|
||||
// resource, a NEW copy will be loaded, regardless of whether a detached
|
||||
// copy still exists.
|
||||
void *
|
||||
res_DetachResource (RESOURCE res)
|
||||
{
|
||||
ResourceDesc *desc;
|
||||
ResourceFreeFun *freeFun;
|
||||
void *result;
|
||||
|
||||
desc = lookupResourceDesc (_get_current_index_header(), res);
|
||||
if (desc == NULL)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to detach from an unrecognised "
|
||||
"resource.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
freeFun = desc->vtable->freeFun;
|
||||
if (freeFun == NULL)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to detach from a non-heap resource.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (desc->resdata.ptr == NULL)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to detach from a not loaded "
|
||||
"resource.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (desc->refcount > 1)
|
||||
{
|
||||
log_add (log_Debug, "Warning: trying to detach a resource referenced "
|
||||
"%u times", desc->refcount);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = desc->resdata.ptr;
|
||||
desc->resdata.ptr = NULL;
|
||||
desc->refcount = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FreeResourceData (void *data)
|
||||
{
|
||||
HFree (data);
|
||||
return TRUE;
|
||||
}
|
||||
51
project/jni/application/sc2/src/libs/resource/index.h
Normal file
51
project/jni/application/sc2/src/libs/resource/index.h
Normal file
@@ -0,0 +1,51 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _INDEX_H
|
||||
#define _INDEX_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "libs/reslib.h"
|
||||
#include "libs/uio/charhashtable.h"
|
||||
|
||||
typedef struct resource_handlers
|
||||
{
|
||||
const char *resType;
|
||||
ResourceLoadFun *loadFun;
|
||||
ResourceFreeFun *freeFun;
|
||||
ResourceStringFun *toString;
|
||||
} ResourceHandlers;
|
||||
|
||||
typedef struct resource_desc
|
||||
{
|
||||
RESOURCE res_id;
|
||||
char *fname;
|
||||
ResourceHandlers *vtable;
|
||||
RESOURCE_DATA resdata;
|
||||
// refcount is rudimentary as nothing really frees the descriptors
|
||||
unsigned refcount;
|
||||
} ResourceDesc;
|
||||
|
||||
struct resource_index_desc
|
||||
{
|
||||
CharHashTable_HashTable *map;
|
||||
size_t numRes;
|
||||
};
|
||||
|
||||
#endif /* _INDEX_H */
|
||||
|
||||
72
project/jni/application/sc2/src/libs/resource/loadres.c
Normal file
72
project/jni/application/sc2/src/libs/resource/loadres.c
Normal file
@@ -0,0 +1,72 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "resintrn.h"
|
||||
#include "libs/declib.h"
|
||||
#include "libs/memlib.h"
|
||||
|
||||
|
||||
void *
|
||||
GetResourceData (uio_Stream *fp, DWORD length)
|
||||
{
|
||||
BYTE *RDPtr;
|
||||
void *result;
|
||||
DECODE_REF fh = 0;
|
||||
|
||||
if (length == ~(DWORD)0)
|
||||
length = LengthResFile (fp);
|
||||
else if ((fh = copen (fp, FILE_STREAM, STREAM_READ)))
|
||||
cfilelength (fh, &length);
|
||||
else
|
||||
length -= sizeof (DWORD);
|
||||
|
||||
result = AllocResourceData (length);
|
||||
RDPtr = result;
|
||||
if (RDPtr)
|
||||
{
|
||||
COUNT num_read;
|
||||
|
||||
do
|
||||
{
|
||||
#define READ_LENGTH 0x00007FFFL
|
||||
num_read = length >= READ_LENGTH ?
|
||||
(COUNT)READ_LENGTH : (COUNT)length;
|
||||
if (fh)
|
||||
{
|
||||
if (cread (RDPtr, 1, num_read, fh) != num_read)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)(ReadResFile (RDPtr, 1, num_read, fp)) != (int)num_read)
|
||||
break;
|
||||
}
|
||||
RDPtr += num_read;
|
||||
} while (length -= num_read);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
FreeResourceData (result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cclose (fh);
|
||||
|
||||
return result;
|
||||
}
|
||||
127
project/jni/application/sc2/src/libs/resource/propfile.c
Normal file
127
project/jni/application/sc2/src/libs/resource/propfile.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/* propfile.c, Copyright (c) 2008 Michael C. Martin */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope thta it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "libs/log.h"
|
||||
#include "propfile.h"
|
||||
#include "libs/reslib.h"
|
||||
|
||||
void
|
||||
PropFile_from_string (char *d, PROPERTY_HANDLER handler, const char *prefix)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
len = strlen(d);
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
int key_start, key_end, value_start, value_end;
|
||||
/* Starting a line: search for non-whitespace */
|
||||
while ((i < len) && isspace (d[i])) i++;
|
||||
if (i >= len) break; /* Done parsing! */
|
||||
/* If it was a comment, skip to end of comment/file */
|
||||
if (d[i] == '#') {
|
||||
while ((i < len) && (d[i] != '\n')) i++;
|
||||
if (i >= len) break;
|
||||
continue; /* Back to keyword search */
|
||||
}
|
||||
key_start = i;
|
||||
/* Find the = on this line */
|
||||
while ((i < len) && (d[i] != '=') &&
|
||||
(d[i] != '\n') && (d[i] != '#')) i++;
|
||||
if (i >= len) { /* Bare key at EOF */
|
||||
log_add (log_Warning, "Warning: Bare keyword at EOF");
|
||||
break;
|
||||
}
|
||||
/* Comments here mean incomplete line too */
|
||||
if (d[i] != '=') {
|
||||
log_add (log_Warning, "Warning: Key without value");
|
||||
while ((i < len) && (d[i] != '\n')) i++;
|
||||
if (i >= len) break;
|
||||
continue; /* Back to keyword search */
|
||||
}
|
||||
/* Key ends at first whitespace before = , or at key_start*/
|
||||
key_end = i;
|
||||
while ((key_end > key_start) && isspace (d[key_end-1]))
|
||||
key_end--;
|
||||
|
||||
/* Consume the = */
|
||||
i++;
|
||||
/* Value starts at first non-whitespace after = on line... */
|
||||
while ((i < len) && (d[i] != '#') && (d[i] != '\n') &&
|
||||
isspace (d[i]))
|
||||
i++;
|
||||
value_start = i;
|
||||
/* Until first non-whitespace before terminator */
|
||||
while ((i < len) && (d[i] != '#') && (d[i] != '\n'))
|
||||
i++;
|
||||
value_end = i;
|
||||
while ((value_end > value_start) && isspace (d[value_end-1]))
|
||||
value_end--;
|
||||
/* Skip past EOL or EOF */
|
||||
while ((i < len) && (d[i] != '\n'))
|
||||
i++;
|
||||
i++;
|
||||
|
||||
/* We now have start and end values for key and value.
|
||||
We terminate the strings for both by writing \0s, then
|
||||
make a new map entry. */
|
||||
d[key_end] = '\0';
|
||||
d[value_end] = '\0';
|
||||
if (prefix) {
|
||||
char buf[256];
|
||||
snprintf(buf, 255, "%s%s", prefix, d+key_start);
|
||||
buf[255]=0;
|
||||
handler(buf, d+value_start);
|
||||
} else {
|
||||
handler (d+key_start, d+value_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PropFile_from_file (uio_Stream *f, PROPERTY_HANDLER handler, const char *prefix)
|
||||
{
|
||||
long flen;
|
||||
char *data;
|
||||
|
||||
flen = LengthResFile (f);
|
||||
|
||||
data = malloc (flen + 1);
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
flen = ReadResFile (data, 1, flen, f);
|
||||
data[flen] = '\0';
|
||||
|
||||
PropFile_from_string (data, handler, prefix);
|
||||
free (data);
|
||||
}
|
||||
|
||||
void
|
||||
PropFile_from_filename (uio_DirHandle *path, const char *fname, PROPERTY_HANDLER handler, const char *prefix)
|
||||
{
|
||||
uio_Stream *f = res_OpenResFile (path, fname, "rt");
|
||||
if (!f) {
|
||||
return;
|
||||
}
|
||||
PropFile_from_file (f, handler, prefix);
|
||||
res_CloseResFile(f);
|
||||
}
|
||||
30
project/jni/application/sc2/src/libs/resource/propfile.h
Normal file
30
project/jni/application/sc2/src/libs/resource/propfile.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* propfile.h, Copyright (c) 2008 Michael C. Martin */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope thta it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PROPFILE_H_
|
||||
#define PROPFILE_H_
|
||||
|
||||
#include "libs/uio.h"
|
||||
|
||||
typedef void (*PROPERTY_HANDLER) (const char *, const char *);
|
||||
|
||||
void PropFile_from_string (char *d, PROPERTY_HANDLER handler, const char *prefix);
|
||||
void PropFile_from_file (uio_Stream *f, PROPERTY_HANDLER handler, const char *prefix);
|
||||
void PropFile_from_filename (uio_DirHandle *path, const char *fname, PROPERTY_HANDLER handler, const char *prefix);
|
||||
|
||||
#endif
|
||||
650
project/jni/application/sc2/src/libs/resource/resinit.c
Normal file
650
project/jni/application/sc2/src/libs/resource/resinit.c
Normal file
@@ -0,0 +1,650 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "resintrn.h"
|
||||
#include "libs/memlib.h"
|
||||
#include "options.h"
|
||||
#include "types.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/gfxlib.h"
|
||||
#include "libs/reslib.h"
|
||||
#include "libs/sndlib.h"
|
||||
#include "libs/vidlib.h"
|
||||
#include "propfile.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
// XXX: we should not include anything from uqm/ inside libs/
|
||||
#include "uqm/coderes.h"
|
||||
|
||||
static RESOURCE_INDEX
|
||||
allocResourceIndex (void) {
|
||||
RESOURCE_INDEX ndx = HMalloc (sizeof (RESOURCE_INDEX_DESC));
|
||||
ndx->map = CharHashTable_newHashTable (NULL, NULL, NULL, NULL, 0, 0.85, 0.9);
|
||||
return ndx;
|
||||
}
|
||||
|
||||
static void
|
||||
freeResourceIndex (RESOURCE_INDEX h) {
|
||||
if (h != NULL)
|
||||
{
|
||||
/* TODO: This leaks the contents of h->map */
|
||||
CharHashTable_deleteHashTable (h->map);
|
||||
HFree (h);
|
||||
}
|
||||
}
|
||||
|
||||
#define TYPESIZ 32
|
||||
|
||||
static ResourceDesc *
|
||||
newResourceDesc (const char *res_id, const char *resval)
|
||||
{
|
||||
const char *path;
|
||||
int pathlen;
|
||||
ResourceHandlers *vtable;
|
||||
ResourceDesc *result, *handlerdesc;
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
char typestr[TYPESIZ];
|
||||
|
||||
path = strchr (resval, ':');
|
||||
if (path == NULL)
|
||||
{
|
||||
log_add (log_Warning, "Could not find type information for resource '%s'", res_id);
|
||||
strncpy(typestr, "sys.UNKNOWNRES", TYPESIZ);
|
||||
path = resval;
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = path - resval;
|
||||
|
||||
if (n >= TYPESIZ - 4)
|
||||
{
|
||||
n = TYPESIZ - 5;
|
||||
}
|
||||
strncpy (typestr, "sys.", TYPESIZ);
|
||||
strncat (typestr+1, resval, n);
|
||||
typestr[n+4] = '\0';
|
||||
path++;
|
||||
}
|
||||
pathlen = strlen (path);
|
||||
|
||||
handlerdesc = lookupResourceDesc(idx, typestr);
|
||||
if (handlerdesc == NULL) {
|
||||
path = resval;
|
||||
log_add (log_Warning, "Illegal type '%s' for resource '%s'; treating as UNKNOWNRES", typestr, res_id);
|
||||
handlerdesc = lookupResourceDesc(idx, "sys.UNKNOWNRES");
|
||||
}
|
||||
|
||||
vtable = (ResourceHandlers *)handlerdesc->resdata.ptr;
|
||||
|
||||
if (vtable->loadFun == NULL)
|
||||
{
|
||||
log_add (log_Warning, "Warning: Unable to load '%s'; no handler "
|
||||
"for type %s defined.", res_id, typestr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = HMalloc (sizeof (ResourceDesc));
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
result->fname = HMalloc (pathlen + 1);
|
||||
strncpy (result->fname, path, pathlen);
|
||||
result->fname[pathlen] = '\0';
|
||||
result->vtable = vtable;
|
||||
result->refcount = 0;
|
||||
|
||||
if (vtable->freeFun == NULL)
|
||||
{
|
||||
/* Non-heap resources are raw values. Work those out at load time. */
|
||||
vtable->loadFun (result->fname, &result->resdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
result->resdata.ptr = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
process_resource_desc (const char *key, const char *value)
|
||||
{
|
||||
CharHashTable_HashTable *map = _get_current_index_header ()->map;
|
||||
ResourceDesc *newDesc = newResourceDesc (key, value);
|
||||
if (newDesc != NULL)
|
||||
{
|
||||
if (!CharHashTable_add (map, key, newDesc))
|
||||
{
|
||||
res_Remove (key);
|
||||
CharHashTable_add (map, key, newDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
UseDescriptorAsRes (const char *descriptor, RESOURCE_DATA *resdata)
|
||||
{
|
||||
resdata->ptr = (void *)descriptor;
|
||||
}
|
||||
|
||||
static void
|
||||
DescriptorToInt (const char *descriptor, RESOURCE_DATA *resdata)
|
||||
{
|
||||
resdata->num = atoi (descriptor);
|
||||
}
|
||||
|
||||
static void
|
||||
DescriptorToBoolean (const char *descriptor, RESOURCE_DATA *resdata)
|
||||
{
|
||||
if (!strcasecmp (descriptor, "true"))
|
||||
{
|
||||
resdata->num = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
resdata->num = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
snprintf (buf, size, "%s", (char *)resdata->ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
IntToString (RESOURCE_DATA *resdata, char *buf, unsigned int size)
|
||||
{
|
||||
snprintf (buf, size, "%d", resdata->num);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
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
|
||||
_set_current_index_header (RESOURCE_INDEX newResourceIndex)
|
||||
{
|
||||
curResourceIndex = newResourceIndex;
|
||||
}
|
||||
|
||||
RESOURCE_INDEX
|
||||
InitResourceSystem (void)
|
||||
{
|
||||
RESOURCE_INDEX ndx;
|
||||
if (curResourceIndex) {
|
||||
return curResourceIndex;
|
||||
}
|
||||
ndx = allocResourceIndex ();
|
||||
|
||||
_set_current_index_header (ndx);
|
||||
|
||||
InstallResTypeVectors ("UNKNOWNRES", UseDescriptorAsRes, NULL, NULL);
|
||||
InstallResTypeVectors ("STRING", UseDescriptorAsRes, NULL, RawDescriptor);
|
||||
InstallResTypeVectors ("INT32", DescriptorToInt, NULL, IntToString);
|
||||
InstallResTypeVectors ("BOOLEAN", DescriptorToBoolean, NULL,
|
||||
BooleanToString);
|
||||
InstallResTypeVectors ("COLOR", DescriptorToColor, NULL, ColorToString);
|
||||
InstallGraphicResTypes ();
|
||||
InstallStringTableResType ();
|
||||
InstallAudioResTypes ();
|
||||
InstallVideoResType ();
|
||||
InstallCodeResType ();
|
||||
|
||||
return ndx;
|
||||
}
|
||||
|
||||
RESOURCE_INDEX
|
||||
_get_current_index_header (void)
|
||||
{
|
||||
if (!curResourceIndex) {
|
||||
InitResourceSystem ();
|
||||
}
|
||||
return curResourceIndex;
|
||||
}
|
||||
|
||||
void
|
||||
LoadResourceIndex (uio_DirHandle *dir, const char *rmpfile, const char *prefix)
|
||||
{
|
||||
PropFile_from_filename (dir, rmpfile, process_resource_desc, prefix);
|
||||
}
|
||||
|
||||
void
|
||||
SaveResourceIndex (uio_DirHandle *dir, const char *rmpfile, const char *root, BOOLEAN strip_root)
|
||||
{
|
||||
uio_Stream *f;
|
||||
CharHashTable_Iterator *it;
|
||||
unsigned int prefix_len;
|
||||
|
||||
f = res_OpenResFile (dir, rmpfile, "wb");
|
||||
if (!f) {
|
||||
/* TODO: Warning message */
|
||||
return;
|
||||
}
|
||||
prefix_len = root ? strlen (root) : 0;
|
||||
for (it = CharHashTable_getIterator (_get_current_index_header ()->map);
|
||||
!CharHashTable_iteratorDone (it);
|
||||
it = CharHashTable_iteratorNext (it)) {
|
||||
char *key = CharHashTable_iteratorKey (it);
|
||||
if (!root || !strncmp (root, key, prefix_len)) {
|
||||
ResourceDesc *value = CharHashTable_iteratorValue (it);
|
||||
if (!value) {
|
||||
log_add(log_Warning, "Resource %s had no value", key);
|
||||
} else if (!value->vtable) {
|
||||
log_add(log_Warning, "Resource %s had no type", key);
|
||||
} else if (value->vtable->toString) {
|
||||
char buf[256];
|
||||
value->vtable->toString (&value->resdata, buf, 256);
|
||||
buf[255]=0;
|
||||
if (root && strip_root) {
|
||||
WriteResFile (key+prefix_len, 1, strlen (key) - prefix_len, f);
|
||||
} else {
|
||||
WriteResFile (key, 1, strlen (key), f);
|
||||
}
|
||||
PutResFileChar(' ', f);
|
||||
PutResFileChar('=', f);
|
||||
PutResFileChar(' ', f);
|
||||
WriteResFile (value->vtable->resType, 1, strlen (value->vtable->resType), f);
|
||||
PutResFileChar(':', f);
|
||||
WriteResFile (buf, 1, strlen (buf), f);
|
||||
PutResFileNewline(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
res_CloseResFile (f);
|
||||
CharHashTable_freeIterator (it);
|
||||
}
|
||||
|
||||
void
|
||||
UninitResourceSystem (void)
|
||||
{
|
||||
freeResourceIndex (_get_current_index_header ());
|
||||
_set_current_index_header (NULL);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
InstallResTypeVectors (const char *resType, ResourceLoadFun *loadFun,
|
||||
ResourceFreeFun *freeFun, ResourceStringFun *stringFun)
|
||||
{
|
||||
ResourceHandlers *handlers;
|
||||
ResourceDesc *result;
|
||||
char key[TYPESIZ];
|
||||
int typelen;
|
||||
CharHashTable_HashTable *map;
|
||||
|
||||
snprintf(key, TYPESIZ, "sys.%s", resType);
|
||||
key[TYPESIZ-1] = '\0';
|
||||
typelen = strlen(resType);
|
||||
|
||||
handlers = HMalloc (sizeof (ResourceHandlers));
|
||||
if (handlers == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
handlers->loadFun = loadFun;
|
||||
handlers->freeFun = freeFun;
|
||||
handlers->toString = stringFun;
|
||||
handlers->resType = resType;
|
||||
|
||||
result = HMalloc (sizeof (ResourceDesc));
|
||||
if (result == NULL)
|
||||
return FALSE;
|
||||
|
||||
result->fname = HMalloc (strlen(resType) + 1);
|
||||
strncpy (result->fname, resType, typelen);
|
||||
result->fname[typelen] = '\0';
|
||||
result->vtable = NULL;
|
||||
result->resdata.ptr = handlers;
|
||||
|
||||
map = _get_current_index_header ()->map;
|
||||
return CharHashTable_add (map, key, result) != 0;
|
||||
}
|
||||
|
||||
/* These replace the mapres.c calls and probably should be split out at some point. */
|
||||
BOOLEAN
|
||||
res_IsString (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
return desc && !strcmp(desc->vtable->resType, "STRING");
|
||||
}
|
||||
|
||||
const char *
|
||||
res_GetString (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
if (!desc || !desc->resdata.ptr || strcmp(desc->vtable->resType, "STRING"))
|
||||
return "";
|
||||
/* TODO: Work out exact STRING semantics, specifically, the lifetime of
|
||||
* the returned value. If caller is allowed to reference the returned
|
||||
* value forever, STRING has to be ref-counted. */
|
||||
return (const char *)desc->resdata.ptr;
|
||||
}
|
||||
|
||||
void
|
||||
res_PutString (const char *key, const char *value)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
int srclen, dstlen;
|
||||
if (!desc || !desc->resdata.ptr || strcmp(desc->vtable->resType, "STRING"))
|
||||
{
|
||||
/* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */
|
||||
process_resource_desc(key, "STRING:undefined");
|
||||
desc = lookupResourceDesc (idx, key);
|
||||
}
|
||||
srclen = strlen (value);
|
||||
dstlen = strlen (desc->resdata.ptr);
|
||||
if (srclen > dstlen) {
|
||||
char *newValue = HMalloc(srclen + 1);
|
||||
char *oldValue = desc->fname;
|
||||
log_add(log_Warning, "Reallocating string space for '%s'", key);
|
||||
strncpy (newValue, value, srclen + 1);
|
||||
desc->resdata.ptr = newValue;
|
||||
desc->fname = newValue;
|
||||
HFree (oldValue);
|
||||
} else {
|
||||
strncpy (desc->resdata.ptr, value, srclen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_IsInteger (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
return desc && !strcmp(desc->vtable->resType, "INT32");
|
||||
}
|
||||
|
||||
int
|
||||
res_GetInteger (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
if (!desc || strcmp(desc->vtable->resType, "INT32"))
|
||||
{
|
||||
// TODO: Better error handling
|
||||
return 0;
|
||||
}
|
||||
return desc->resdata.num;
|
||||
}
|
||||
|
||||
void
|
||||
res_PutInteger (const char *key, int value)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
if (!desc || strcmp(desc->vtable->resType, "INT32"))
|
||||
{
|
||||
/* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */
|
||||
process_resource_desc(key, "INT32:0");
|
||||
desc = lookupResourceDesc (idx, key);
|
||||
}
|
||||
desc->resdata.num = value;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_IsBoolean (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
return desc && !strcmp(desc->vtable->resType, "BOOLEAN");
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_GetBoolean (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
if (!desc || strcmp(desc->vtable->resType, "BOOLEAN"))
|
||||
{
|
||||
// TODO: Better error handling
|
||||
return FALSE;
|
||||
}
|
||||
return desc->resdata.num ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
res_PutBoolean (const char *key, BOOLEAN value)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
ResourceDesc *desc = lookupResourceDesc (idx, key);
|
||||
if (!desc || strcmp(desc->vtable->resType, "BOOLEAN"))
|
||||
{
|
||||
/* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */
|
||||
process_resource_desc(key, "BOOLEAN:false");
|
||||
desc = lookupResourceDesc (idx, key);
|
||||
}
|
||||
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:rgb(0, 0, 0)");
|
||||
desc = lookupResourceDesc (idx, key);
|
||||
}
|
||||
desc->resdata.num =
|
||||
(value.r << 24) | (value.g << 16) | (value.b << 8) | value.a;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_HasKey (const char *key)
|
||||
{
|
||||
RESOURCE_INDEX idx = _get_current_index_header ();
|
||||
return (lookupResourceDesc(idx, key) != NULL);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
res_Remove (const char *key)
|
||||
{
|
||||
CharHashTable_HashTable *map = _get_current_index_header ()->map;
|
||||
ResourceDesc *oldDesc = (ResourceDesc *)CharHashTable_find (map, key);
|
||||
if (oldDesc != NULL)
|
||||
{
|
||||
if (oldDesc->resdata.ptr != NULL)
|
||||
{
|
||||
if (oldDesc->refcount > 0)
|
||||
log_add (log_Warning, "WARNING: Replacing '%s' while it is live", key);
|
||||
if (oldDesc->vtable && oldDesc->vtable->freeFun)
|
||||
{
|
||||
oldDesc->vtable->freeFun(oldDesc->resdata.ptr);
|
||||
}
|
||||
}
|
||||
HFree (oldDesc->fname);
|
||||
HFree (oldDesc);
|
||||
}
|
||||
return CharHashTable_remove (map, key);
|
||||
}
|
||||
34
project/jni/application/sc2/src/libs/resource/resintrn.h
Normal file
34
project/jni/application/sc2/src/libs/resource/resintrn.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _RESINTRN_H
|
||||
#define _RESINTRN_H
|
||||
|
||||
#include <string.h>
|
||||
#include "libs/reslib.h"
|
||||
#include "index.h"
|
||||
|
||||
ResourceDesc *lookupResourceDesc (RESOURCE_INDEX idx, RESOURCE res);
|
||||
void loadResourceDesc (ResourceDesc *desc);
|
||||
|
||||
void _set_current_index_header (RESOURCE_INDEX newResourceIndex);
|
||||
RESOURCE_INDEX _get_current_index_header (void);
|
||||
|
||||
|
||||
#endif /* _RESINTRN_H */
|
||||
|
||||
181
project/jni/application/sc2/src/libs/resource/stringbank.c
Normal file
181
project/jni/application/sc2/src/libs/resource/stringbank.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/* stringbank.c, Copyright (c) 2005 Michael C. Martin */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope thta it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stringbank.h"
|
||||
|
||||
typedef stringbank chunk;
|
||||
|
||||
static stringbank *
|
||||
add_chunk (stringbank *bank)
|
||||
{
|
||||
stringbank *n = malloc (sizeof (stringbank));
|
||||
n->len = 0;
|
||||
n->next = NULL;
|
||||
if (bank)
|
||||
{
|
||||
while (bank->next)
|
||||
bank = bank->next;
|
||||
bank->next = n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
stringbank *
|
||||
StringBank_Create (void)
|
||||
{
|
||||
return add_chunk (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
StringBank_Free (stringbank *bank)
|
||||
{
|
||||
if (bank)
|
||||
{
|
||||
StringBank_Free (bank->next);
|
||||
free (bank);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
StringBank_AddString (stringbank *bank, const char *str)
|
||||
{
|
||||
unsigned int len = strlen (str) + 1;
|
||||
stringbank *x = bank;
|
||||
if (len > STRBANK_CHUNK_SIZE)
|
||||
return NULL;
|
||||
while (x) {
|
||||
unsigned int remaining = STRBANK_CHUNK_SIZE - x->len;
|
||||
if (len < remaining) {
|
||||
char *result = x->data + x->len;
|
||||
strcpy (result, str);
|
||||
x->len += len;
|
||||
return result;
|
||||
}
|
||||
x = x->next;
|
||||
}
|
||||
/* No room in any currently existing chunk */
|
||||
x = add_chunk (bank);
|
||||
strcpy (x->data, str);
|
||||
x->len += len;
|
||||
return x->data;
|
||||
}
|
||||
|
||||
const char *
|
||||
StringBank_AddOrFindString (stringbank *bank, const char *str)
|
||||
{
|
||||
unsigned int len = strlen (str) + 1;
|
||||
stringbank *x = bank;
|
||||
if (len > STRBANK_CHUNK_SIZE)
|
||||
return NULL;
|
||||
while (x) {
|
||||
int i = 0;
|
||||
while (i < x->len) {
|
||||
if (!strcmp (x->data + i, str))
|
||||
return x->data + i;
|
||||
while (x->data[i]) i++;
|
||||
i++;
|
||||
}
|
||||
x = x->next;
|
||||
}
|
||||
/* We didn't find it, so add it */
|
||||
return StringBank_AddString (bank, str);
|
||||
}
|
||||
|
||||
static char buffer[STRBANK_CHUNK_SIZE];
|
||||
|
||||
const char *
|
||||
StringBank_AddSubstring (stringbank *bank, const char *str, unsigned int n)
|
||||
{
|
||||
unsigned int len = strlen (str);
|
||||
if (n > len)
|
||||
{
|
||||
return StringBank_AddString (bank, str);
|
||||
}
|
||||
if (n >= STRBANK_CHUNK_SIZE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
strncpy (buffer, str, n);
|
||||
buffer[n] = '\0';
|
||||
return StringBank_AddString(bank, buffer);
|
||||
}
|
||||
|
||||
const char *
|
||||
StringBank_AddOrFindSubstring (stringbank *bank, const char *str, unsigned int n)
|
||||
{
|
||||
unsigned int len = strlen (str);
|
||||
if (n > len)
|
||||
{
|
||||
return StringBank_AddOrFindString (bank, str);
|
||||
}
|
||||
if (n >= STRBANK_CHUNK_SIZE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
strncpy (buffer, str, n);
|
||||
buffer[n] = '\0';
|
||||
return StringBank_AddOrFindString(bank, buffer);
|
||||
}
|
||||
|
||||
int
|
||||
SplitString (const char *s, char splitchar, int n, const char **result, stringbank *bank)
|
||||
{
|
||||
int i;
|
||||
const char *index = s;
|
||||
|
||||
for (i = 0; i < n-1; i++)
|
||||
{
|
||||
const char *next;
|
||||
int len;
|
||||
|
||||
next = strchr (index, splitchar);
|
||||
if (!next)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len = next - index;
|
||||
result[i] = StringBank_AddOrFindSubstring (bank, index, len);
|
||||
index = next+1;
|
||||
}
|
||||
result[i] = StringBank_AddOrFindString (bank, index);
|
||||
return i+1;
|
||||
}
|
||||
|
||||
#ifdef SB_DEBUG
|
||||
|
||||
void
|
||||
StringBank_Dump (stringbank *bank, FILE *s)
|
||||
{
|
||||
stringbank *x = bank;
|
||||
while (x) {
|
||||
int i = 0;
|
||||
while (i < x->len) {
|
||||
fprintf (s, "\"%s\"\n", x->data + i);
|
||||
while (x->data[i]) i++;
|
||||
i++;
|
||||
}
|
||||
x = x->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
57
project/jni/application/sc2/src/libs/resource/stringbank.h
Normal file
57
project/jni/application/sc2/src/libs/resource/stringbank.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* stringbank.h, Copyright (c) 2005 Michael C. Martin */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope thta it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _STRINGBANK_H_
|
||||
#define _STRINGBANK_H_
|
||||
|
||||
#ifdef SB_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define STRBANK_CHUNK_SIZE (1024 - sizeof (void *) - sizeof (int))
|
||||
|
||||
typedef struct _stringbank_chunk {
|
||||
char data[STRBANK_CHUNK_SIZE];
|
||||
int len;
|
||||
struct _stringbank_chunk *next;
|
||||
} stringbank;
|
||||
|
||||
/* Constructors and destructors */
|
||||
stringbank *StringBank_Create (void);
|
||||
void StringBank_Free (stringbank *bank);
|
||||
|
||||
/* Put str or n chars after str into the string bank. */
|
||||
const char *StringBank_AddString (stringbank *bank, const char *str);
|
||||
const char *StringBank_AddSubstring (stringbank *bank, const char *str, unsigned int n);
|
||||
|
||||
/* Put str or n chars after str into the string bank if it's not already
|
||||
there. Much slower. */
|
||||
const char *StringBank_AddOrFindString (stringbank *bank, const char *str);
|
||||
const char *StringBank_AddOrFindSubstring (stringbank *bank, const char *str, unsigned int n);
|
||||
|
||||
/* Split a string s into at most n substrings, separated by splitchar.
|
||||
Pointers to these substrings will be stored in result; the
|
||||
substrings themselves will be filed in the specified stringbank. */
|
||||
int SplitString (const char *s, char splitchar, int n, const char **result, stringbank *bank);
|
||||
|
||||
#ifdef SB_DEBUG
|
||||
/* Print out a list of the contents of the string bank to the named stream. */
|
||||
void StringBank_Dump (stringbank *bank, FILE *s);
|
||||
#endif /* SB_DEBUG */
|
||||
|
||||
#endif /* _STRINGBANK_H_ */
|
||||
Reference in New Issue
Block a user