blob: 7d674bc5819d2693d41f9d6dfe27b687e20c1f02 [file] [log] [blame]
static char RCSId[] = "$Id: resource.c,v 1.3 1993/06/30 14:24:33 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
#include <stdlib.h>
#include "prototypes.h"
#include "neexe.h"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
typedef struct resource_data_s
{
int resource_type;
void *resource_data;
} RSCD;
RSCD *Resources;
int ResourceArraySize;
/**********************************************************************
* AddResource
*/
int
AddResource(int type, void *data)
{
RSCD *r;
int i;
int j;
/*
* Find free resource id.
*/
r = Resources;
for (i = 0; i < ResourceArraySize; i++, r++)
if (r->resource_type == 0)
break;
/*
* Do we need to add more resource slots?
*/
if (i == ResourceArraySize)
{
if (ResourceArraySize > 0)
r = realloc(Resources, (ResourceArraySize + 32) * sizeof(RSCD));
else
r = malloc(32 * sizeof(RSCD));
if (r == NULL)
return 0;
for (j = ResourceArraySize; j < ResourceArraySize + 32; j++)
r[j].resource_type = 0;
ResourceArraySize += 32;
Resources = r;
r = &Resources[i];
}
/*
* Add new resource to list.
*/
r->resource_type = type;
r->resource_data = data;
/*
* Return a unique handle.
*/
return i + 1;
}
/**********************************************************************
* FindResourceByNumber
*/
int
FindResourceByNumber(struct resource_nameinfo_s *result_p,
int type_id, int resource_id)
{
struct resource_typeinfo_s typeinfo;
struct resource_nameinfo_s nameinfo;
unsigned short size_shift;
int i;
/*
* Move to beginning of resource table.
*/
lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
CurrentNEHeader->resource_tab_offset), SEEK_SET);
/*
* Read block size.
*/
if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) !=
sizeof(size_shift))
{
return -1;
}
/*
* Find resource.
*/
typeinfo.type_id = 0xffff;
while (typeinfo.type_id != 0)
{
if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
sizeof(typeinfo))
{
return -1;
}
if (typeinfo.type_id != 0)
{
for (i = 0; i < typeinfo.count; i++)
{
if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) !=
sizeof(nameinfo))
{
return -1;
}
#if defined(DEBUG_RESOURCE) && defined(VERBOSE_DEBUG)
if (type_id == typeinfo.type_id)
{
printf("FindResource: type id = %d, resource id = %x\n",
type_id, nameinfo.id);
}
#endif
if ((type_id == -1 || typeinfo.type_id == type_id) &&
nameinfo.id == resource_id)
{
memcpy(result_p, &nameinfo, sizeof(nameinfo));
return size_shift;
}
}
}
}
return -1;
}
/**********************************************************************
* RSC_LoadString
*/
int
RSC_LoadString(int instance, int resource_id, char *buffer, int buflen)
{
struct resource_nameinfo_s nameinfo;
unsigned short target_id;
unsigned char string_length;
int size_shift;
int string_num;
int i;
#ifdef DEBUG_RESOURCE
printf("LoadString: instance = %04x, id = %d, "
"buffer = %08x, length = %d\n",
instance, resource_id, buffer, buflen);
#endif
/*
* Find string entry.
*/
target_id = (resource_id >> 4) + 0x8001;
string_num = resource_id & 0x000f;
size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_STRING, target_id);
if (size_shift == -1)
return 0;
lseek(CurrentNEFile, (int) nameinfo.offset << size_shift, SEEK_SET);
for (i = 0; i < string_num; i++)
{
read(CurrentNEFile, &string_length, 1);
lseek(CurrentNEFile, string_length, SEEK_CUR);
}
read(CurrentNEFile, &string_length, 1);
i = MIN(string_length, buflen - 1);
read(CurrentNEFile, buffer, i);
buffer[i] = '\0';
#ifdef DEBUG_RESOURCE
printf(" '%s'\n", buffer);
#endif
return i;
}
/**********************************************************************
* RSC_LoadBitmap
*/
int
RSC_LoadBitmap(int instance, char *bmp_name)
{
struct resource_nameinfo_s nameinfo;
void *image;
int image_size;
int size_shift;
#ifdef DEBUG_RESOURCE
printf("LoadBitmap: instance = %04x, name = %08x\n",
instance, bmp_name);
#endif
/*
* Built-in bitmaps
*/
if (instance == 0)
{
return 0;
}
/*
* Get bitmap by ordinal
*/
else if (((int) bmp_name & 0xffff0000) == 0)
{
size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_BITMAP,
(int) bmp_name | 0x8000);
}
/*
* Get bitmap by name
*/
else
{
size_shift = -1;
}
if (size_shift == -1)
return 0;
/*
* Read bitmap.
*/
lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
image_size = nameinfo.length << size_shift;
image = malloc(image_size);
if (image == NULL || read(CurrentNEFile, image, image_size) != image_size)
{
free(image);
return 0;
}
/*
* Add to resource list.
*/
return AddResource(NE_RSCTYPE_BITMAP, image);
}