Replaced binary resource index files by textual ones.

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2003 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
meep-eep
2005-11-20 05:56:46 +00:00
parent a1796afa51
commit 816b362f12
114 changed files with 1552 additions and 925 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
uqm_SUBDIRS="decomp file graphics input math memory resource sound strings
task threads time uio video"
uqm_SUBDIRS="decomp file graphics input list math memory resource sound
strings task threads time uio video"
#if [ "$DEBUG" = 1 ]; then
# uqm_SUBDIRS="$UQM_SUBDIRS debug"
#fi
+13 -14
View File
@@ -24,8 +24,8 @@
#include "memlib.h"
#include "libs/uio.h"
typedef DWORD RESOURCE;
typedef RESOURCE *PRESOURCE;
typedef BYTE RES_TYPE;
typedef COUNT RES_INSTANCE;
@@ -35,10 +35,6 @@ typedef COUNT RES_PACKAGE;
#define INSTANCE_BITS 13
#define PACKAGE_BITS 11
#define MAX_TYPES ((1 << TYPE_BITS) - 1) /* zero is invalid */
#define MAX_INSTANCES (1 << INSTANCE_BITS)
#define MAX_PACKAGES ((1 << PACKAGE_BITS) - 1) /* zero is invalid */
#define GET_TYPE(res) \
((RES_TYPE)(res) & (RES_TYPE)((1 << TYPE_BITS) - 1))
#define GET_INSTANCE(res) \
@@ -51,8 +47,12 @@ typedef COUNT RES_PACKAGE;
((RESOURCE)(i) << TYPE_BITS) | \
((RESOURCE)(t)))
extern const char *_cur_resfile_name;
typedef MEM_HANDLE (ResourceLoadFun) (uio_Stream *fp, DWORD len);
typedef BOOLEAN (ResourceFreeFun) (MEM_HANDLE handle);
extern uio_Stream *res_OpenResFile (uio_DirHandle *dir, const char *filename,
const char *mode);
extern int ReadResFile (PVOID lpBuf, COUNT size, COUNT count, uio_Stream *fp);
@@ -66,21 +66,20 @@ extern long LengthResFile (uio_Stream *fp);
extern BOOLEAN res_CloseResFile (uio_Stream *fp);
extern BOOLEAN DeleteResFile (uio_DirHandle *dir, const char *filename);
extern MEM_HANDLE InitResourceSystem (const char *resfile,
COUNT resindex_type, BOOLEAN (*FileErrorFunc) (const char *filename));
extern BOOLEAN UninitResourceSystem (void);
extern BOOLEAN InstallResTypeVectors (COUNT res_type,
MEM_HANDLE (*load_func) (uio_Stream *fp, DWORD len),
BOOLEAN (*free_func) (MEM_HANDLE handle));
extern MEM_HANDLE InitResourceSystem (const char *resfile, RES_TYPE resType,
BOOLEAN (*FileErrorFun) (const char *filename));
extern void UninitResourceSystem (void);
extern BOOLEAN InstallResTypeVectors (RES_TYPE res_type,
ResourceLoadFun *loadFun, ResourceFreeFun *freeFun);
extern MEM_HANDLE res_GetResource (RESOURCE res);
extern MEM_HANDLE res_DetachResource (RESOURCE res);
extern BOOLEAN FreeResource (RESOURCE res);
extern COUNT CountResourceTypes (void);
extern MEM_HANDLE OpenResourceIndexFile (const char *resfile);
extern MEM_HANDLE OpenResourceIndexInstance (DWORD res);
extern MEM_HANDLE SetResourceIndex (MEM_HANDLE hRH);
extern BOOLEAN CloseResourceIndex (MEM_HANDLE hRH);
extern MEM_HANDLE OpenResourceIndexInstance (RESOURCE res);
extern MEM_HANDLE SetResourceIndex (MEM_HANDLE newIndexHandle);
extern BOOLEAN CloseResourceIndex (MEM_HANDLE newIndexHandle);
extern MEM_HANDLE GetResourceData (uio_Stream *fp, DWORD length,
MEM_FLAGS mem_flags);
+162 -460
View File
@@ -16,508 +16,210 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "resintrn.h"
#include "port.h"
#include "options.h"
#include "port.h"
#include "resintrn.h"
#include "libs/misc.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.
static BOOLEAN
ValidResource (INDEX_HEADERPTR ResHeaderPtr, RESOURCE res)
{
if (ResHeaderPtr != NULL_PTR)
static ResourceDesc *
lookupResourceDesc (ResourceIndex *idx, RESOURCE res) {
// Binary search through the resources.
COUNT l, h;
if (idx->numRes == 0)
return NULL;
l = 0;
h = idx->numRes;
while (l + 1 != h)
{
RES_PACKAGE res_package;
res_package = GET_PACKAGE (res);
if (ValidResPackage (ResHeaderPtr, res_package))
{
RES_TYPE res_type;
res_type = GET_TYPE (res);
if (ValidResType (ResHeaderPtr, res_type))
{
COUNT res_instance;
res_instance = GET_INSTANCE (res);
if (GetInstanceCount (ResHeaderPtr, res_type) > res_instance)
return (TRUE);
}
}
}
return (FALSE);
}
static void
dword_convert (PDWORD dword_array, COUNT num_dwords)
{
PBYTE p = (PBYTE)dword_array;
do
{
*dword_array++ = MAKE_DWORD (
MAKE_WORD (p[0], p[1]),
MAKE_WORD (p[2], p[3])
);
p += 4;
} while (--num_dwords);
}
#define PATHLEN 256
void
get_resource_filename (INDEX_HEADERPTR ResHeaderPtr, char *pbuf, COUNT
file_index)
{
UWORD path_offs;
long file_offs;
FILE_INFO file_info;
file_offs = (long)ResHeaderPtr->file_list_offs +
(long)file_index * FILE_LIST_SIZE;
if (ResHeaderPtr->res_flags & IS_PACKAGED)
memcpy ((PSTR)&file_info,
(PSTR)ResHeaderPtr + (COUNT)file_offs, FILE_LIST_SIZE);
else
{
SeekResFile (ResHeaderPtr->res_fp, file_offs, SEEK_SET);
ReadResFile (&file_info, FILE_LIST_SIZE, 1, ResHeaderPtr->res_fp);
}
path_offs = MAKE_WORD (file_info.path_offset[0], file_info.path_offset[1]);
if (path_offs != NO_PATH)
{
file_offs = (long)ResHeaderPtr->path_list_offs + path_offs;
if (ResHeaderPtr->res_flags & IS_PACKAGED)
memcpy (pbuf,
(PSTR)ResHeaderPtr + (COUNT)file_offs, PATHLEN);
COUNT m = (l + h) / 2;
if (idx->res[m]->res <= res)
l = m;
else
{
SeekResFile (ResHeaderPtr->res_fp, file_offs, SEEK_SET);
ReadResFile (pbuf, PATHLEN, 1, ResHeaderPtr->res_fp);
}
pbuf += strlen (pbuf);
*pbuf++ = '/';
h = m;
}
{
COUNT i;
char *pstr;
pstr = file_info.filename;
for (i = 0; i < FILE_NAME_SIZE; ++i)
{
if ((*pbuf++ = *pstr++) == '\0')
{
--pbuf;
if (i == 0)
{
#ifndef PACKAGING
strcpy (pbuf, ResHeaderPtr->index_file_name);
#endif /* PACKAGING */
return;
}
break;
}
}
*pbuf++ = '.';
pstr = file_info.extension;
for (i = 0; i < EXTENSION_SIZE && (*pbuf++ = *pstr++); ++i)
;
*pbuf++ = '\0';
}
if (idx->res[l]->res == res)
return idx->res[l];
return NULL;
}
DWORD
get_packmem_offs (INDEX_HEADERPTR ResHeaderPtr, RES_PACKAGE res_package)
{
DWORD file_offs;
RES_PACKAGE package;
// Load every resource in a package.
static void
loadPackage (ResourceIndex *idx, RES_PACKAGE pkg) {
COUNT i;
file_offs = ResHeaderPtr->packmem_list_offs;
for (package = 1; package < res_package; ++package)
{
file_offs += (DWORD)PACKMEM_LIST_SIZE
* GET_TYPE (ResHeaderPtr->PackageList[package - 1].packmem_info)
+ (DWORD)INSTANCE_LIST_SIZE
* GET_INSTANCE (ResHeaderPtr->PackageList[package - 1].packmem_info);
for (i = 0; i < idx->numRes; i++) {
if (GET_PACKAGE (idx->res[i]->res) != pkg)
continue;
if (idx->res[i]->handle != NULL_HANDLE)
continue; // Already loaded
loadResourceDesc (idx, idx->res[i]);
}
return (file_offs);
}
//#define DEBUG
MEM_HANDLE
load_package (INDEX_HEADERPTR ResHeaderPtr, RES_PACKAGE res_package)
loadResourceDesc (ResourceIndex *idx, ResourceDesc *desc)
{
BOOLEAN DanglingOpen;
MEM_HANDLE hList;
uio_Stream *fp;
COUNT t, num_types, num_instances;
DWORD file_offs, data_len;
RES_HANDLE_LISTPTR ResourceHandleListPtr;
ENCODEPTR TypeEncodePtr;
DATAPTR DataPtr;
#ifdef PACKAGING
extern
#endif /* PACKAGING */
char file_buf[PATHLEN];
num_types = CountPackageTypes (ResHeaderPtr, res_package);
num_instances = CountPackageInstances (ResHeaderPtr, res_package);
if ((hList = AllocResourceHandleList (
num_types, num_instances
)) == NULL_HANDLE)
RES_TYPE resType = GET_TYPE (desc->res);
if (resType >= idx->typeInfo.numTypes ||
idx->typeInfo.handlers[resType].loadFun == NULL)
{
#ifdef DEBUG
fprintf (stderr, "Unable to allocate resource handle list <%d, %d>\n",
num_types, num_instances);
#endif /* DEBUG */
return (NULL_HANDLE);
fprintf (stderr, "Warning: Unable to load '%s'; no handler "
"for type %d defined.\n", desc->path, resType);
return NULL_HANDLE;
}
LockResourceHandleList (ResHeaderPtr, hList, res_package,
&ResourceHandleListPtr, &TypeEncodePtr, &DataPtr);
ResourceHandleListPtr->flags_and_data_loc =
ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc;
DanglingOpen = FALSE;
file_offs = get_packmem_offs (ResHeaderPtr, res_package);
if (!(ResHeaderPtr->res_flags & IS_PACKAGED))
{
SeekResFile (ResHeaderPtr->res_fp, (long)file_offs, SEEK_SET);
if (ReadResFile ((PSTR)TypeEncodePtr,
(PACKMEM_LIST_SIZE * num_types)
+ (INSTANCE_LIST_SIZE * num_instances),
1, ResHeaderPtr->res_fp) != 1)
{
UnlockResourceHandleList (hList);
FreeResourceHandleList (hList);
return (NULL_HANDLE);
}
dword_convert (TypeEncodePtr, num_types);
}
else
{
COUNT file_index;
memcpy (TypeEncodePtr,
(PSTR)((PSTR)ResHeaderPtr + (COUNT)file_offs),
(PACKMEM_LIST_SIZE * num_types)
+ (INSTANCE_LIST_SIZE * num_instances));
dword_convert (TypeEncodePtr, num_types);
file_index = GET_PACKAGE (
ResHeaderPtr->PackageList[res_package - 1].packmem_info
);
get_resource_filename (ResHeaderPtr, file_buf, file_index);
if (!stricmp (ResHeaderPtr->index_file_name, file_buf))
fp = ResHeaderPtr->res_fp;
else
{
fp = res_OpenResFile (contentDir, file_buf, "rb");
if (fp)
DanglingOpen = TRUE;
}
if (fp == NULL)
num_types = 0;
else
{
file_offs = ResourceHandleListPtr->flags_and_data_loc & ~0xFF000000;
if (file_offs)
SeekResFile (fp, (long)file_offs, SEEK_SET);
else if (num_types == 1 && GET_PACKAGE (*TypeEncodePtr) == 1)
{ /* if only one thing in this package which is only
* package in its file, let file length be determined
* by the current length of package rather than the
* length at package time.
*/
RES_PACKAGE p;
for (p = 1; p <= ResHeaderPtr->num_packages; ++p)
{
if (p != res_package
&& GET_PACKAGE (
ResHeaderPtr->PackageList[p - 1].packmem_info)
== file_index)
break;
}
if (p > ResHeaderPtr->num_packages)
{
data_len = (LengthResFile (fp) + 3) >> 2;
DataPtr[0] = LOBYTE (data_len);
DataPtr[1] = HIBYTE (data_len);
}
}
}
}
for (t = 0; t < num_types; ++t)
{
RES_TYPE type;
type = GET_TYPE (*TypeEncodePtr);
num_instances = GET_PACKAGE (*TypeEncodePtr);
while (num_instances--)
{
MEM_HANDLE hData;
_cur_resfile_name = file_buf;
hData = NULL_HANDLE;
data_len = MAKE_WORD (DataPtr[0], DataPtr[1]);
if (ResHeaderPtr->res_flags & IS_PACKAGED)
{
if ((data_len <<= 2) == 0)
;
else if (SeekResFile (fp, (long)file_offs, SEEK_SET))
;
else
{
hData = DoLoad (ResHeaderPtr, type, fp, data_len);
if (hData && IsIndexType (ResHeaderPtr, type))
DanglingOpen = FALSE;
#ifdef DEBUG
if (hData == 0)
fprintf (stderr, "fp = 0x%08lx(%d), type = %u, "
"file_offs = %lu, len = %lu\n",
(unsigned long) fp,
DanglingOpen, type, file_offs, data_len);
#endif /* DEBUG */
}
file_offs += data_len;
}
else
{
get_resource_filename (ResHeaderPtr, file_buf, (COUNT)data_len);
fp = res_OpenResFile (contentDir, file_buf, "rb");
if (fp == NULL)
{
#if 1 // def DEBUG
// HACK: added the 'if' here as not to scare people
// with the warning for this workaround.
// It will go with the new resource system.
// (together with the rest of this file)
if (strcmp(file_buf, "ignored.key") != 0) {
fprintf (stderr, "Can't open '%s'\n", file_buf);
}
#endif /* DEBUG */
}
else
{
data_len = LengthResFile (fp);
#ifndef PACKAGING
fprintf (stderr, "\t'%s' -- %lu bytes\n", file_buf,
data_len);
#endif /* PACKAGING */
if (data_len == 0)
hData = NULL_HANDLE;
else
hData = DoLoad (ResHeaderPtr, type, fp, data_len);
if (hData == 0 || !IsIndexType (ResHeaderPtr, type))
res_CloseResFile (fp);
}
}
#ifdef DEBUG
if (hData == 0)
fprintf (stderr, "Can't create data for '%s' <%lu>\n",
file_buf, data_len);
#endif /* DEBUG */
DataPtr[0] = LOBYTE (hData);
DataPtr[1] = HIBYTE (hData);
DataPtr += 2;
if (hData)
++ResourceHandleListPtr->num_valid_handles;
_cur_resfile_name = 0;
}
++TypeEncodePtr;
}
if (DanglingOpen)
res_CloseResFile (fp);
num_instances = ResourceHandleListPtr->num_valid_handles;
UnlockResourceHandleList (hList);
if (num_instances == 0)
{
#ifdef DEBUG
fprintf (stderr, "Nothing in package!\n");
#endif /* DEBUG */
FreeResourceHandleList (hList);
hList = NULL_HANDLE;
}
return (hList);
desc->handle = loadResource (desc->path,
idx->typeInfo.handlers[resType].loadFun);
return desc->handle;
}
MEM_HANDLE
loadResource(const char *path, ResourceLoadFun *loadFun)
{
uio_Stream *stream;
long dataLen;
MEM_HANDLE handle;
stream = res_OpenResFile (contentDir, path, "rb");
if (stream == NULL)
{
fprintf (stderr, "Warning: Can't open '%s'\n", path);
return NULL_HANDLE;
}
dataLen = LengthResFile (stream);
//#ifdef DEBUG
#if 1
fprintf (stderr, "\t'%s' -- %lu bytes\n", path, dataLen);
#endif
if (dataLen == 0)
{
fprintf (stderr, "Warning: Trying to load empty file '%s'.\n", path);
goto err;
}
_cur_resfile_name = path;
handle = (*loadFun) (stream, dataLen);
_cur_resfile_name = NULL;
res_CloseResFile (stream);
return handle;
err:
res_CloseResFile (stream);
return NULL_HANDLE;
}
// Get a resource by its resource ID.
// For historical reasons, if the resource is not already loaded,
// the *entire* package will be (pre-)loaded.
// NB. It may be better to add an extra flag to res_GetResource() to
// indicate whether you really want this, or add a separate function
// for preloading the entire package.
MEM_HANDLE
res_GetResource (RESOURCE res)
{
MEM_HANDLE hData, hList;
RES_PACKAGE res_package;
RES_TYPE res_type;
RES_INSTANCE res_instance;
RES_HANDLE_LISTPTR ResourceHandleListPtr;
ENCODEPTR TypeEncodePtr;
DATAPTR DataPtr;
INDEX_HEADERPTR ResHeaderPtr;
UWORD hi;
ResourceIndex *resourceIndex;
ResourceDesc *desc;
resourceIndex = _get_current_index_header ();
ResHeaderPtr = _get_current_index_header ();
if (!ValidResource (ResHeaderPtr, res))
desc = lookupResourceDesc (resourceIndex, res);
if (desc == NULL)
{
#ifdef DEBUG
if (res)
fprintf (stderr, "0x%08lx is not a valid resource!\n", res);
#endif /* DEBUG */
return (NULL_HANDLE);
fprintf (stderr, "Trying to get undefined resource %08lx\n",
(DWORD) res);
return NULL_HANDLE;
}
res_package = GET_PACKAGE (res);
if (desc->handle != NULL_HANDLE)
return desc->handle;
hi = HIWORD (ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc);
if (HIBYTE (hi) == 0)
// Package is loaded.
hList = (MEM_HANDLE)LOWORD (
ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc);
else
{
// Package is not loaded. Load now.
hList = load_package (ResHeaderPtr, res_package);
if (hList == NULL_HANDLE)
{
#ifdef DEBUG
fprintf (stderr, "Unable to load package %u\n", res_package);
#endif /* DEBUG */
return (NULL_HANDLE);
}
// Load the entire package, for historical reasons.
loadPackage (resourceIndex, GET_PACKAGE (res));
ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc =
MAKE_DWORD (hList, 0);
}
res_type = GET_TYPE (res);
res_instance = GET_INSTANCE (res);
LockResourceHandleList (ResHeaderPtr, hList, res_package,
&ResourceHandleListPtr, &TypeEncodePtr, &DataPtr);
while (GET_TYPE (*TypeEncodePtr) != res_type)
{
DataPtr += (GET_PACKAGE (*TypeEncodePtr) << 1);
++TypeEncodePtr;
}
DataPtr += (res_instance - GET_INSTANCE (*TypeEncodePtr)) << 1;
hData = MAKE_WORD (DataPtr[0], DataPtr[1]);
UnlockResourceHandleList (hList);
#ifdef DEBUG
if (hData == 0)
fprintf (stderr, "No data for res 0x%08lx\n", res);
#endif /* DEBUG */
return (hData);
return desc->handle;
// May still be NULL_HANDLE, if the load failed.
}
static MEM_HANDLE
get_res_handle (RESOURCE res, BOOLEAN DoDetach)
// NB: this function appears to be never called!
void
res_FreeResource (RESOURCE res)
{
MEM_HANDLE hData = NULL_HANDLE;
RES_PACKAGE res_package;
RES_TYPE res_type;
RES_INSTANCE res_instance;
INDEX_HEADERPTR ResHeaderPtr;
UWORD hi;
ResourceDesc *desc;
ResourceFreeFun *freeFun;
ResHeaderPtr = _get_current_index_header ();
if (!ValidResource (ResHeaderPtr, res))
return (hData);
res_package = GET_PACKAGE (res);
res_type = GET_TYPE (res);
res_instance = GET_INSTANCE (res);
hi = HIWORD (ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc);
if (HIBYTE (hi) == 0)
desc = lookupResourceDesc (_get_current_index_header(), res);
if (desc == NULL)
{
MEM_HANDLE hList;
COUNT num_instances;
RES_HANDLE_LISTPTR ResourceHandleListPtr;
ENCODEPTR TypeEncodePtr;
DATAPTR DataPtr;
DWORD flags_and_data_loc;
hList = LOWORD (ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc);
LockResourceHandleList (ResHeaderPtr, hList, res_package,
&ResourceHandleListPtr, &TypeEncodePtr, &DataPtr);
while (GET_TYPE (*TypeEncodePtr) != res_type)
{
DataPtr += (GET_PACKAGE (*TypeEncodePtr) << 1);
++TypeEncodePtr;
}
DataPtr += (res_instance - GET_INSTANCE (*TypeEncodePtr)) << 1;
hData = MAKE_WORD (DataPtr[0], DataPtr[1]);
if (hData && DoDetach)
{
DataPtr[0] = DataPtr[1] = 0;
--ResourceHandleListPtr->num_valid_handles;
flags_and_data_loc = ResourceHandleListPtr->flags_and_data_loc;
}
num_instances = ResourceHandleListPtr->num_valid_handles;
UnlockResourceHandleList (hList);
if (num_instances == 0)
{
FreeResourceHandleList (hList);
ResHeaderPtr->PackageList[res_package - 1].flags_and_data_loc =
flags_and_data_loc;
}
#ifdef DEBUG
fprintf (stderr, "Warning: trying to free an unrecognised "
"resource.\n");
#endif
return;
}
if (desc->handle == NULL_HANDLE)
{
#ifdef DEBUG
fprintf (stderr, "Warning: trying to free not loaded "
"resource.\n");
#endif
return;
}
return (hData);
}
BOOLEAN
FreeResource (RESOURCE res)
{
MEM_HANDLE hData;
hData = get_res_handle (res, FALSE);
if (hData)
{
RES_TYPE res_type;
INDEX_HEADERPTR ResHeaderPtr;
res_type = GET_TYPE (res);
ResHeaderPtr = _get_current_index_header ();
if (DoFree (ResHeaderPtr, res_type, hData)
&& get_res_handle (res, TRUE))
return (TRUE);
}
return (FALSE);
ResourceIndex *idx = _get_current_index_header ();
freeFun = idx->typeInfo.handlers[GET_TYPE (res)].freeFun;
(*freeFun) (desc->handle);
desc->handle = NULL_HANDLE;
}
// 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.
MEM_HANDLE
res_DetachResource (RESOURCE res)
{
return (get_res_handle (res, TRUE));
ResourceDesc *desc;
MEM_HANDLE result;
desc = lookupResourceDesc (_get_current_index_header(), res);
if (desc == NULL)
{
#ifdef DEBUG
fprintf (stderr, "Warning: trying to detach from an unrecognised "
"resource.\n");
#endif
return NULL_HANDLE;
}
if (desc->handle == NULL_HANDLE)
{
#ifdef DEBUG
fprintf (stderr, "Warning: trying to detach from a not loaded "
"resource.\n");
#endif
return NULL_HANDLE;
}
result = desc->handle;
desc->handle = NULL_HANDLE;
return result;
}
+32 -72
View File
@@ -23,95 +23,55 @@
typedef struct
{
MEM_HANDLE (*load_func) (uio_Stream *fp, DWORD len);
BOOLEAN (*free_func) (MEM_HANDLE handle);
} RES_VECTORS;
RESOURCE res;
char *path;
MEM_HANDLE handle;
//COUNT ref;
} ResourceDesc;
typedef struct
{
RES_INSTANCE instance_count;
RES_VECTORS func_vectors;
} TYPE_DESC;
typedef TYPE_DESC *PTYPE_DESC;
ResourceLoadFun *loadFun;
ResourceFreeFun *freeFun;
} ResourceHandlers;
typedef struct
{
RESOURCE packmem_info;
DWORD flags_and_data_loc;
/* data_loc doubles as 3 byte offset into package file or 2 byte
* MEM_HANDLE to package member array with the offset stored in
* the MEM_HANDLE (cuts down on use of near memory).
} ResourceType;
typedef struct
{
RES_TYPE numTypes;
/* Number of types in the handlers array (whether NULL or not).
* == the highest stored vector number + 1.
*/
} PACKAGE_DESC;
typedef PACKAGE_DESC *PPACKAGE_DESC;
typedef BYTE RES_FLAGS;
#define IS_PACKAGED ((RES_FLAGS)(1 << 0))
ResourceHandlers *handlers;
} ResourceTypeInfo;
typedef struct
{
uio_Stream *res_fp;
ResourceDesc **res;
ResourceTypeInfo typeInfo;
size_t numRes;
} ResourceIndex;
DWORD packmem_list_offs;
DWORD path_list_offs;
DWORD file_list_offs;
RES_PACKAGE num_packages;
RES_TYPE num_types;
RES_FLAGS res_flags;
void
forAllResourceIndices(
void (*callback) (ResourceIndex *idx, void *extra), void *extra);
union
{
DWORD header_len;
struct
{
PPACKAGE_DESC package_list;
PTYPE_DESC type_list;
} lists;
} index_info;
#ifndef PACKAGING
char index_file_name[36];
DWORD data_offs;
MEM_HANDLE hPredHeader, hSuccHeader;
#endif /* PACKAGING */
} INDEX_HEADER;
typedef INDEX_HEADER *PINDEX_HEADER;
typedef PINDEX_HEADER INDEX_HEADERPTR;
void forAllResourceIndices(
void (*callback)(INDEX_HEADERPTR ResHeaderPtr, void *extra),
void *extra);
#define PackageList index_info.lists.package_list
#define TypeList index_info.lists.type_list
#define INDEX_HEADER_PRIORITY DEFAULT_MEM_PRIORITY
#define AllocResourceHeader(s) \
mem_allocate ((s), MEM_ZEROINIT | MEM_PRIMARY, \
INDEX_HEADER_PRIORITY, MEM_SIMPLE)
#define LockResourceHeader (INDEX_HEADERPTR)mem_lock
#define UnlockResourceHeader mem_unlock
#define FreeResourceHeader mem_release
typedef struct
{
BYTE path_offset[2];
char filename[8];
char extension[3];
} FILE_INFO;
static inline ResourceIndex *
lockResourceIndex (MEM_HANDLE h) {
return (ResourceIndex *) mem_lock (h);
}
static inline void
unlockResourceIndex (MEM_HANDLE h) {
mem_unlock (h);
}
#define FILE_NAME_SIZE 8
#define EXTENSION_SIZE 3
#define NO_PATH 0xFFFF
#define FILE_LIST_SIZE \
((sizeof (BYTE) * 2) + FILE_NAME_SIZE + EXTENSION_SIZE)
#define PACKMEM_LIST_SIZE \
(sizeof (DWORD))
#define INSTANCE_LIST_SIZE \
(sizeof (BYTE) * 2)
#endif /* _INDEX_H */
+5 -5
View File
@@ -18,17 +18,17 @@
#include "resintrn.h"
static INDEX_HEADERPTR CurResHeaderPtr;
static ResourceIndex *curResourceIndex;
void
_set_current_index_header (INDEX_HEADERPTR ResHeaderPtr)
_set_current_index_header (ResourceIndex *newResourceIndex)
{
CurResHeaderPtr = ResHeaderPtr;
curResourceIndex = newResourceIndex;
}
INDEX_HEADERPTR
ResourceIndex *
_get_current_index_header (void)
{
return (CurResHeaderPtr);
return curResourceIndex;
}
+375 -321
View File
@@ -17,277 +17,347 @@
*/
#include "resintrn.h"
#include "misc.h"
#include "options.h"
#include "types.h"
#include "libs/list.h"
#include <ctype.h>
#include <stdlib.h>
static bool copyResTypeHandlers (ResourceIndex *dest,
const ResourceIndex *src);
static bool setResTypeHandlers (ResourceIndex *idx, RES_TYPE resType,
const ResourceHandlers *handlers);
static MEM_HANDLE allocResourceIndex(void);
static void freeResourceIndex (MEM_HANDLE h);
static List_List *indexList;
static MEM_HANDLE hIndexList;
// Add a package index to the global list of package indices.
static void
_add_index_list (MEM_HANDLE hRH)
initIndexList (void)
{
#ifndef PACKAGING
INDEX_HEADERPTR ResHeaderPtr;
ResHeaderPtr = LockResourceHeader (hRH);
strncpy (ResHeaderPtr->index_file_name, _cur_resfile_name,
sizeof (ResHeaderPtr->index_file_name) - 1);
ResHeaderPtr->hPredHeader = 0;
ResHeaderPtr->hSuccHeader = hIndexList;
if (ResHeaderPtr->hSuccHeader)
{
INDEX_HEADERPTR SuccResHeaderPtr;
SuccResHeaderPtr = LockResourceHeader (hIndexList);
SuccResHeaderPtr->hPredHeader = hRH;
UnlockResourceHeader (hIndexList);
}
UnlockResourceHeader (hRH);
#endif /* PACKAGING */
hIndexList = hRH;
indexList = List_newList ();
}
// Remove a package index from the global list of package indices.
static void
_sub_index_list (MEM_HANDLE hRH)
uninitIndexList (void)
{
#ifdef PACKAGING
hIndexList = 0;
#else /* !PACKAGING */
INDEX_HEADERPTR ResHeaderPtr;
MEM_HANDLE hPred, hSucc;
ResHeaderPtr = LockResourceHeader (hRH);
hPred = ResHeaderPtr->hPredHeader;
hSucc = ResHeaderPtr->hSuccHeader;
if (hRH == hIndexList)
hIndexList = hSucc;
if (hPred)
{
INDEX_HEADERPTR PredResHeaderPtr;
PredResHeaderPtr = LockResourceHeader (hPred);
PredResHeaderPtr->hSuccHeader = hSucc;
UnlockResourceHeader (hPred);
}
if (hSucc)
{
INDEX_HEADERPTR SuccResHeaderPtr;
SuccResHeaderPtr = LockResourceHeader (hSucc);
SuccResHeaderPtr->hPredHeader = hPred;
UnlockResourceHeader (hSucc);
}
UnlockResourceHeader (hRH);
#endif /* PACKAGING */
List_deleteList (indexList);
indexList = NULL;
}
MEM_HANDLE
_GetResFileData (uio_Stream *res_fp, DWORD flen)
{
UWORD lo_word, hi_word;
DWORD res_offs;
DWORD remainder = 0;
// Initialisation is to keep the compiler quiet.
MEM_SIZE HeaderSize;
INDEX_HEADER h;
INDEX_HEADERPTR ResHeaderPtr;
MEM_HANDLE hRH;
char buf[32];
void
forAllResourceIndices(
void (*callback) (ResourceIndex *idx, void *extra),
void *extra) {
List_Link *link;
res_offs = TellResFile (res_fp);
ReadResFile (buf, 1, 22, res_fp);
h.res_fp = res_fp;
h.res_flags = MAKE_WORD (buf[0], buf[1]) ? IS_PACKAGED : 0;
lo_word = MAKE_WORD (buf[2], buf[3]);
hi_word = MAKE_WORD (buf[4], buf[5]);
h.packmem_list_offs = MAKE_DWORD (lo_word, hi_word);
lo_word = MAKE_WORD (buf[6], buf[7]);
hi_word = MAKE_WORD (buf[8], buf[9]);
h.path_list_offs = MAKE_DWORD (lo_word, hi_word);
lo_word = MAKE_WORD (buf[10], buf[11]);
hi_word = MAKE_WORD (buf[12], buf[13]);
h.file_list_offs = MAKE_DWORD (lo_word, hi_word);
h.num_packages = (RES_PACKAGE)MAKE_WORD (buf[14], buf[15]);
h.num_types = (RES_TYPE)MAKE_WORD (buf[16], buf[17]);
lo_word = MAKE_WORD (buf[18], buf[19]);
hi_word = MAKE_WORD (buf[20], buf[21]);
h.index_info.header_len = MAKE_DWORD (lo_word, hi_word);
HeaderSize = (MEM_SIZE)(sizeof (INDEX_HEADER)
+ (sizeof (PACKAGE_DESC) * h.num_packages)
+ (sizeof (TYPE_DESC) * h.num_types));
if (h.res_flags & IS_PACKAGED)
for (link = indexList->first; link != NULL; link = link->next)
{
DWORD offs;
ResourceIndex *idx = (ResourceIndex *) link->entry;
(*callback) (idx, extra);
}
}
remainder = h.index_info.header_len - h.packmem_list_offs;
offs = HeaderSize - h.packmem_list_offs;
HeaderSize += remainder;
h.packmem_list_offs += offs;
h.file_list_offs += offs;
h.path_list_offs += offs;
#if 0
static ResourceDesc *
lookupResourceIndex (const char *path)
{
List_Link *link;
for (link = indexList->first; link != NULL; link = link->next)
{
ResourceDesc *desc = (ResourceDesc *) link->entry;
if (strcmp (desc->path, path) == 0)
return link->entry;
}
#ifndef PACKAGING
{
MEM_HANDLE hNextRH;
return NULL;
}
#endif
h.data_offs = res_offs;
for (hRH = hIndexList; hRH != 0; hRH = hNextRH)
static ResourceDesc *
newResourceDesc (RESOURCE res, char *path)
{
ResourceDesc *result;
result = HMalloc (sizeof (ResourceDesc));
if (result == NULL)
return NULL;
result->res = res;
result->path = path;
result->handle = NULL_HANDLE;
//result->ref = 0;
return result;
}
static MEM_HANDLE
loadResourceIndex (uio_Stream *stream, const char *fileName) {
size_t lineNum;
ResourceDesc **descs = NULL;
COUNT numRes;
int numDescsAlloced = 0;
MEM_HANDLE indexHandle = NULL_HANDLE;
ResourceIndex *ndx = NULL;
#ifdef DEBUG
RESOURCE lastResource = 0x00000000;
#endif
// This loop parses lines of the format "<resnum> <path>".
// Resnum is in hex. '#' can be used to add comments.
lineNum = 0;
numRes = 0;
for (;;)
{
char lineBuf[PATH_MAX + 80];
char *ptr;
char *endResPtr;
char *endPtr;
char *path;
char *newPath;
RESOURCE res;
ResourceDesc *desc;
if (uio_fgets (lineBuf, sizeof lineBuf, stream) == NULL)
{
ResHeaderPtr = LockResourceHeader (hRH);
if (h.data_offs == ResHeaderPtr->data_offs
&& strncmp (ResHeaderPtr->index_file_name,
_cur_resfile_name,
sizeof (ResHeaderPtr->index_file_name) - 1) == 0)
return (hRH); /* DON'T UNLOCK IT */
hNextRH = ResHeaderPtr->hSuccHeader;
UnlockResourceHeader (hRH);
if (uio_ferror (stream))
goto err;
else
break; // EOF
}
}
#endif /* PACKAGING */
if ((hRH = AllocResourceHeader (HeaderSize))
&& (ResHeaderPtr = LockResourceHeader (hRH)))
{
*ResHeaderPtr = h;
lineNum++;
// Skip comments.
ptr = strchr (lineBuf, '#');
if (ptr != NULL)
*ptr = '\0';
// Omit leading whitespace.
ptr = lineBuf;
while (isspace (*ptr))
ptr++;
// Omit trailing whitespace.
endPtr = ptr + strlen(ptr);
while (endPtr != ptr && isspace (endPtr[-1]))
{
RES_PACKAGE p;
endPtr--;
*endPtr = '\0';
}
ResHeaderPtr->PackageList = (PPACKAGE_DESC)&ResHeaderPtr[1];
for (p = 0; p < ResHeaderPtr->num_packages; ++p)
// If the line is empty (apart from comments and whitespace)
// go to the next one.
if (*ptr == 0)
continue;
// Find the separator between the resource number and the path.
endResPtr = ptr;
do {
endResPtr++;
} while (*endResPtr != '\0' && !isspace (*endResPtr));
// Skip the separator
path = endResPtr;
while (isspace (*path))
path++;
if (*path == 0)
{
// No path present after the line number.
fprintf (stderr, "Resource index '%s': Invalid line %d.\n",
fileName, lineNum);
continue;
}
// Parse the resource number.
{
*endResPtr = '\0';
res = strtoul (ptr, &endResPtr, 16);
if (*endResPtr != '\0')
{
ReadResFile (buf, 1, 8, res_fp);
lo_word = MAKE_WORD (buf[0], buf[1]);
hi_word = MAKE_WORD (buf[2], buf[3]);
ResHeaderPtr->PackageList[p].packmem_info =
(RESOURCE)MAKE_DWORD (lo_word, hi_word);
lo_word = MAKE_WORD (buf[4], buf[5]);
hi_word = MAKE_WORD (buf[6], buf[7]);
ResHeaderPtr->PackageList[p].flags_and_data_loc =
MAKE_DWORD (lo_word, hi_word) + res_offs;
// Invalid characters in the resource number.
fprintf (stderr, "Resource index '%s': Invalid line %d.\n",
fileName, lineNum);
continue;
}
}
#ifdef DEBUG
// We need the list to be sorted, as we binary search through it.
if (res <= lastResource)
{
RES_TYPE t;
INDEX_HEADERPTR CurResHeaderPtr;
fprintf (stderr, "Fatal: resource index '%s' is not sorted "
"on the resource number, or contains a double entry. "
"Problem encountered on line %d.\n", fileName, lineNum);
abort ();
}
lastResource = res;
#endif
CurResHeaderPtr = _get_current_index_header ();
ResHeaderPtr->TypeList =
(PTYPE_DESC)&ResHeaderPtr->PackageList[ResHeaderPtr->num_packages];
for (t = 0; t < ResHeaderPtr->num_types; ++t)
{
ReadResFile (buf, 1, 2, res_fp);
ResHeaderPtr->TypeList[t].instance_count =
MAKE_WORD (buf[0], buf[1]);
if (CurResHeaderPtr)
ResHeaderPtr->TypeList[t].func_vectors =
CurResHeaderPtr->TypeList[t].func_vectors;
}
#define DESC_NUM_INCREMENT 80
if (numDescsAlloced <= numRes)
{
// Need to enlarge the array of resource descs.
ResourceDesc **newDescs = HRealloc (descs,
sizeof (ResourceDesc *) *
(numDescsAlloced + DESC_NUM_INCREMENT));
if (newDescs == NULL)
goto err; // Original descs is untouched.
descs = newDescs;
numDescsAlloced += DESC_NUM_INCREMENT;
}
if (h.res_flags & IS_PACKAGED)
ReadResFile (&ResHeaderPtr->TypeList[ResHeaderPtr->num_types],
1, (COUNT)remainder, res_fp);
// Can't use strdup; it doesn't use HMalloc.
newPath = HMalloc (endPtr - path + 1);
if (newPath == NULL)
goto err;
strcpy (newPath, path);
_add_index_list (hRH);
desc = newResourceDesc (res, newPath);
if (desc == NULL)
goto err;
return (hRH); /* DON'T UNLOCK IT */
descs[numRes] = desc;
numRes++;
}
FreeResourceHeader (hRH);
(void) flen; /* Satisfy compiler (unused parameter) */
return (NULL_HANDLE);
{
ResourceDesc **newDescs = HRealloc (descs,
sizeof (ResourceDesc *) * numRes);
if (newDescs == NULL && numRes != 0)
goto err; // Original descs is untouched.
descs = newDescs;
}
#ifdef DEBUG
if (numRes == 0)
fprintf (stderr, "Warning: Resource index '%s' contains no valid "
"entries.\n", fileName);
#endif
indexHandle = allocResourceIndex ();
if (indexHandle == NULL_HANDLE)
goto err;
ndx = lockResourceIndex (indexHandle);
ndx->res = descs;
ndx->numRes = numRes;
ndx->typeInfo.numTypes = 0;
ndx->typeInfo.handlers = NULL;
List_add (indexList, (void *) ndx);
unlockResourceIndex (indexHandle);
return indexHandle;
err:
if (indexHandle != NULL_HANDLE)
freeResourceIndex (indexHandle);
HFree (descs);
return NULL_HANDLE;
}
// Get the data associated with a resource of type RES_INDEX
// (In other words, a ResourceIndex)
MEM_HANDLE
InitResourceSystem (const char *resfile, COUNT resindex_type, BOOLEAN
(*FileErrorFunc) (const char *filename))
_GetResFileData (uio_Stream *res_fp, DWORD fileLength)
{
MEM_HANDLE h;
MEM_HANDLE handle;
ResourceIndex *ndx;
ResourceIndex *parentNdx;
h = OpenResourceIndexFile (resfile);
if (h)
{
SetResourceIndex (h);
#if 0
ResourceDesc *desc;
InstallResTypeVectors (resindex_type,
_GetResFileData, FreeResourceHeader);
}
desc = lookupResourceIndex (_cur_resfile_name);
assert(desc != NULL);
(void) FileErrorFunc; /* Satisfy compiler (unused parameter) */
return (h);
if (desc->handle != NULL_HANDLE)
return desc->handle;
#endif
handle = loadResourceIndex (res_fp, _cur_resfile_name);
if (handle == NULL_HANDLE)
return NULL_HANDLE;
ndx = lockResourceIndex (handle);
parentNdx = _get_current_index_header ();
if (parentNdx != NULL)
copyResTypeHandlers (ndx, parentNdx);
unlockResourceIndex (handle);
(void) fileLength;
return handle;
}
BOOLEAN
_ReleaseResFileData (MEM_HANDLE handle)
{
ResourceIndex *ndx;
ndx = lockResourceIndex (handle);
if (ndx->typeInfo.handlers != NULL)
HFree (ndx->typeInfo.handlers);
unlockResourceIndex (handle);
mem_release (handle);
return TRUE;
}
MEM_HANDLE
InitResourceSystem (const char *resfile, RES_TYPE resType, BOOLEAN
(*FileErrorFun) (const char *filename))
{
MEM_HANDLE handle;
ResourceIndex *ndx;
initIndexList ();
ResourceHandlers handlers;
handlers.loadFun = _GetResFileData;
handlers.freeFun = _ReleaseResFileData;
SetResourceIndex (NULL_HANDLE);
handle = loadResource (resfile, handlers.loadFun);
if (handle == NULL_HANDLE)
return NULL_HANDLE;
ndx = lockResourceIndex (handle);
setResTypeHandlers (ndx, resType, &handlers);
unlockResourceIndex (handle);
SetResourceIndex (handle);
(void) FileErrorFun;
return handle;
}
void
UninitResourceSystem (void)
{
if (hIndexList)
#if 0
List_Link *link;
for (link = indexList->first; link != NULL; link = link->next)
{
do
CloseResourceIndex (hIndexList);
while (hIndexList);
return (TRUE);
ResourceIndex *ndx = (ResourceIndex *) link->entry;
}
return (FALSE);
#endif
uninitIndexList ();
SetResourceIndex (NULL_HANDLE);
}
MEM_HANDLE
OpenResourceIndexFile (const char *resfile)
{
uio_Stream *res_fp;
char fullname[256];
strcpy (fullname, resfile);
res_fp = res_OpenResFile (contentDir, fullname, "rb");
if (res_fp == 0)
{
sprintf (fullname, "%s.pkg", resfile);
res_fp = res_OpenResFile (contentDir, fullname, "rb");
if (res_fp == 0)
{
sprintf (fullname, "%s.ndx", resfile);
res_fp = res_OpenResFile (contentDir, fullname, "rb");
}
}
if (res_fp)
{
MEM_HANDLE hRH;
_cur_resfile_name = fullname;
hRH = _GetResFileData (res_fp, LengthResFile (res_fp));
/* DO NOT res_CloseResFile!!! */
return (hRH);
}
return (0);
}
MEM_HANDLE
OpenResourceIndexInstance (DWORD res)
OpenResourceIndexInstance (RESOURCE res)
{
MEM_HANDLE hRH;
@@ -298,135 +368,119 @@ OpenResourceIndexInstance (DWORD res)
return (hRH);
}
// Sets the current global resource index.
// This is the index res_GetResource() calls will use.
MEM_HANDLE
SetResourceIndex (MEM_HANDLE hRH)
SetResourceIndex (MEM_HANDLE newIndexHandle)
{
MEM_HANDLE hOldRH;
static MEM_HANDLE hCurResHeader;
static MEM_HANDLE currentIndexHandle;
// NB: currentIndexHandle is locked.
MEM_HANDLE oldIndexHandle;
if (currentIndexHandle != NULL_HANDLE)
unlockResourceIndex (currentIndexHandle);
if ((hOldRH = hCurResHeader) != hRH)
{
INDEX_HEADERPTR ResHeaderPtr;
oldIndexHandle = currentIndexHandle;
currentIndexHandle = newIndexHandle;
ResHeaderPtr = LockResourceHeader (hRH);
UnlockResourceHeader (hRH);
_set_current_index_header (ResHeaderPtr);
hCurResHeader = hRH;
}
if (currentIndexHandle != NULL_HANDLE) {
ResourceIndex *ndx;
return (hOldRH);
ndx = lockResourceIndex (currentIndexHandle);
_set_current_index_header (ndx);
} else
_set_current_index_header (NULL);
return oldIndexHandle;
}
BOOLEAN
CloseResourceIndex (MEM_HANDLE hRH)
CloseResourceIndex (MEM_HANDLE handle)
{
if (UnlockResourceHeader (hRH))
{
uio_Stream *res_fp;
INDEX_HEADERPTR ResHeaderPtr;
ResourceIndex *ndx;
unlockResourceIndex (handle);
ResHeaderPtr = LockResourceHeader (hRH);
#ifdef DEBUG
{
COUNT i;
ndx = lockResourceIndex (handle);
if (ndx == _get_current_index_header ())
SetResourceIndex (NULL_HANDLE);
for (i = 0; i < ResHeaderPtr->num_packages; ++i)
{
UWORD hi;
List_remove ((void *) indexList, ndx);
unlockResourceIndex (handle);
hi = HIWORD (ResHeaderPtr->PackageList[i].flags_and_data_loc);
if (HIBYTE (hi) == 0)
{
MEM_HANDLE hList;
RES_HANDLE_LISTPTR ResourceHandleListPtr;
ENCODEPTR TypeEncodePtr;
DATAPTR DataPtr;
_ReleaseResFileData (handle);
hList = (MEM_HANDLE)LOWORD (
ResHeaderPtr->PackageList[i].flags_and_data_loc);
LockResourceHandleList (ResHeaderPtr, hList, i + 1,
&ResourceHandleListPtr, &TypeEncodePtr, &DataPtr);
fprintf (stderr, "Package %u has %u instances left\n",
i + 1, ResourceHandleListPtr->num_valid_handles);
UnlockResourceHandleList (hList);
}
}
}
#endif /* DEBUG */
_sub_index_list (hRH);
res_fp = ResHeaderPtr->res_fp;
if (ResHeaderPtr == _get_current_index_header ())
SetResourceIndex (hIndexList);
UnlockResourceHeader (hRH);
FreeResourceHeader (hRH);
if (res_fp)
{
MEM_HANDLE hNextRH;
for (hRH = hIndexList; hRH && res_fp; hRH = hNextRH)
{
ResHeaderPtr = LockResourceHeader (hRH);
if (res_fp == ResHeaderPtr->res_fp)
res_fp = 0;
hNextRH = ResHeaderPtr->hSuccHeader;
UnlockResourceHeader (hRH);
}
if (res_fp)
res_CloseResFile (res_fp);
}
return (TRUE);
}
return (FALSE);
return TRUE;
}
BOOLEAN
InstallResTypeVectors (COUNT res_type,
MEM_HANDLE (*load_func) (uio_Stream *fp, DWORD len),
BOOLEAN (*free_func) (MEM_HANDLE handle))
InstallResTypeVectors (RES_TYPE resType, ResourceLoadFun *loadFun,
ResourceFreeFun *freeFun)
{
INDEX_HEADERPTR ResHeaderPtr;
ResourceHandlers handlers;
handlers.loadFun = loadFun;
handlers.freeFun = freeFun;
ResHeaderPtr = _get_current_index_header ();
if (ValidResType (ResHeaderPtr, res_type))
{
ResHeaderPtr->TypeList[res_type - 1].func_vectors.load_func = load_func;
ResHeaderPtr->TypeList[res_type - 1].func_vectors.free_func = free_func;
setResTypeHandlers(_get_current_index_header (), resType, &handlers);
return TRUE;
}
return (TRUE);
static bool
setResTypeHandlers (ResourceIndex *idx, RES_TYPE resType,
const ResourceHandlers *handlers)
{
if (resType >= idx->typeInfo.numTypes) {
// Have to enlarge the handler array.
ResourceHandlers *newHandlers = HRealloc (idx->typeInfo.handlers,
(resType + 1) * sizeof (ResourceHandlers));
if (newHandlers == NULL)
return false; // idx->typeInfo.handlers is untouched
// Clear the space for new entries. No need to init the last one;
// it's going to be used immediately.
memset (&newHandlers[idx->typeInfo.numTypes], 0,
(resType - idx->typeInfo.numTypes /* + 1 - 1 */)
* sizeof (ResourceHandlers));
idx->typeInfo.handlers = newHandlers;
idx->typeInfo.numTypes = resType + 1;
}
return (FALSE);
idx->typeInfo.handlers[resType] = *handlers;
return true;
}
COUNT
CountResourceTypes (void)
static bool
copyResTypeHandlers (ResourceIndex *dest, const ResourceIndex *src)
{
INDEX_HEADERPTR ResHeaderPtr;
assert (src != dest);
ResHeaderPtr = _get_current_index_header ();
return ((COUNT)ResHeaderPtr->num_types);
}
if (dest->typeInfo.handlers != NULL)
HFree (dest->typeInfo.handlers);
void
forAllResourceIndices(
void (*callback) (INDEX_HEADERPTR ResHeaderPtr, void *extra),
void *extra) {
MEM_HANDLE hRH;
MEM_HANDLE hNextRH;
INDEX_HEADERPTR ResHeaderPtr;
dest->typeInfo.handlers = HMalloc (src->typeInfo.numTypes *
sizeof (ResourceHandlers));
if (dest->typeInfo.handlers == NULL)
return false;
memcpy (dest->typeInfo.handlers, src->typeInfo.handlers,
src->typeInfo.numTypes * sizeof (ResourceHandlers));
dest->typeInfo.numTypes = src->typeInfo.numTypes;
return true;
}
for (hRH = hIndexList; hRH != 0; hRH = hNextRH)
{
ResHeaderPtr = LockResourceHeader (hRH);
hNextRH = ResHeaderPtr->hSuccHeader;
(*callback) (ResHeaderPtr, extra);
UnlockResourceHeader (hRH);
}
static MEM_HANDLE
allocResourceIndex (void) {
return mem_allocate (sizeof (ResourceIndex), MEM_PRIMARY,
INDEX_HEADER_PRIORITY, MEM_SIMPLE);
}
static void
freeResourceIndex (MEM_HANDLE h) {
mem_release (h);
}
+5 -50
View File
@@ -20,59 +20,14 @@
#define _RESINTRN_H
#include <string.h>
#include "reslib.h"
#include "libs/reslib.h"
#include "index.h"
typedef struct
{
DWORD flags_and_data_loc;
COUNT num_valid_handles;
} RES_HANDLE_LIST;
typedef RES_HANDLE_LIST *PRES_HANDLE_LIST;
typedef PRES_HANDLE_LIST RES_HANDLE_LISTPTR;
MEM_HANDLE loadResourceDesc (ResourceIndex *idx, ResourceDesc *desc);
MEM_HANDLE loadResource(const char *path, ResourceLoadFun *loadFun);
typedef PDWORD ENCODEPTR;
typedef PBYTE DATAPTR;
#define RES_HANDLE_LIST_PRIORITY DEFAULT_MEM_PRIORITY
#define AllocResourceHandleList(nt,ni) \
mem_allocate ((MEM_SIZE)(sizeof (RES_HANDLE_LIST) \
+ (PACKMEM_LIST_SIZE * (nt)) \
+ (INSTANCE_LIST_SIZE * (ni))), MEM_ZEROINIT | MEM_PRIMARY, \
RES_HANDLE_LIST_PRIORITY, MEM_SIMPLE)
#define LockResourceHandleList(pRH,h,p,rp,tp,dp) \
do \
{ \
*(rp) = (RES_HANDLE_LISTPTR)mem_lock ((MEM_HANDLE)h); \
*(tp) = (ENCODEPTR)&(*(rp))[1]; \
*(dp) = (DATAPTR)&(*(tp))[CountPackageTypes (pRH,p)]; \
} while (0)
#define UnlockResourceHandleList(h) mem_unlock((MEM_HANDLE)h)
#define FreeResourceHandleList(h) mem_release((MEM_HANDLE)h)
#define DoLoad(pRH, t,fp,len) (*(pRH)->TypeList[t-1].func_vectors.load_func)(fp,len)
#define DoFree(pRH, t,h) (*(pRH)->TypeList[t-1].func_vectors.free_func)(h)
extern MEM_HANDLE _GetResFileData (uio_Stream *res_fp, DWORD flen);
#define IsIndexType(pRH, t) ((pRH)->TypeList[t-1].func_vectors.load_func \
==_GetResFileData)
#define LastResPackage(pRH) ((pRH)->num_packages)
#define LastResType(pRH) ((pRH)->num_types)
#define GetInstanceCount(pRH,t) \
((pRH)->TypeList[(t)-1].instance_count)
#define ValidResPackage(pRH,p) ((p)<=LastResPackage(pRH))
#define ValidResType(pRH,t) ((t)!=0&&(t)<=LastResType(pRH))
#define CountPackageTypes(pRH,p) \
(COUNT)GET_TYPE ((pRH)->PackageList[(p)-1].packmem_info)
#define CountPackageInstances(pRH,p) \
(COUNT)GET_INSTANCE ((pRH)->PackageList[(p)-1].packmem_info)
extern void _set_current_index_header (INDEX_HEADERPTR ResHeaderPtr);
extern INDEX_HEADERPTR _get_current_index_header (void);
void _set_current_index_header (ResourceIndex *newResourceIndex);
ResourceIndex *_get_current_index_header (void);
#endif /* _RESINTRN_H */
+1 -1
View File
@@ -105,7 +105,7 @@ LoadKernel (int argc, char *argv[])
SetContextFGFrame (Screen);
SetFrameHot (Screen, MAKE_HOT_SPOT (0, 0));
hResIndex = InitResourceSystem ("starcon", RES_INDEX, NULL);
hResIndex = InitResourceSystem ("starcon.lst", RES_INDEX, NULL);
if (hResIndex == 0)
return FALSE;
INIT_INSTANCES ();