executor/src/resGet.c
2009-06-14 20:58:21 -06:00

531 lines
12 KiB
C

/* Copyright 1986, 1989, 1990, 1995 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_resGet[] =
"$Id: resGet.c 63 2004-12-24 18:19:43Z ctm $";
#endif
/* Forward declarations in ResourceMgr.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "ResourceMgr.h"
#include "FileMgr.h"
#include "rsys/resource.h"
#include "MemoryMgr.h"
#include "OSUtil.h"
#include "rsys/glue.h"
#include "rsys/mman.h"
#include "rsys/ctl.h"
#include "rsys/list.h"
#include "rsys/menu.h"
#include "rsys/wind.h"
#include "rsys/soundopts.h"
#include "rsys/file.h"
#include "rsys/pstuff.h"
#include "rsys/aboutbox.h"
#include <ctype.h>
P1(PUBLIC pascal trap, void, SetResLoad, BOOLEAN, load)
{
ResLoad = load;
}
A2(PRIVATE, INTEGER, countmapresources, resmaphand, map, ResType, typ)
{
INTEGER i, retval;
typref *tr;
retval = 0;
WALKTR(map, i, tr)
if (CL(tr->rtyp) == typ) {
retval += 1 + Cx(tr->nres);
break;
}
EWALKTR(tr)
return(retval);
}
P1(PUBLIC pascal trap, INTEGER, CountResources, ResType, typ)
{
resmaphand map;
INTEGER n;
ROMlib_setreserr(noErr);
n = 0;
WALKMAPTOP(map)
n += countmapresources(map, typ);
EWALKMAP()
return(n);
}
P1(PUBLIC pascal trap, INTEGER, Count1Resources, /* IMIV-15 */
ResType, typ)
{
resmaphand map;
map = ROMlib_rntohandl(Cx(CurMap), (Handle *)0);
if (!map) {
ROMlib_setreserr(resFNotFound);
/*-->*/ return 0;
}
return(countmapresources(map, typ));
}
A3(PRIVATE, Handle, getindmapresource, resmaphand, map, ResType, typ,
INTEGER *, indx)
{
INTEGER i, j, nr;
typref *tr;
resref *rr;
WALKTR(map, i, tr)
if (CL(tr->rtyp) == typ) {
nr = Cx(tr->nres) + 1;
WALKRR(map, tr, j, rr)
if (--*indx == 0)
/*-->*/ return ROMlib_mgetres(map, rr);
EWALKRR(rr)
}
EWALKTR(tr)
return((Handle)0);
}
P2(PUBLIC pascal trap, Handle, GetIndResource, ResType, typ, INTEGER, indx)
{
resmaphand map;
Handle retval;
if (indx <= 0) {
ROMlib_setreserr(resNotFound);
/*-->*/ return 0;
}
WALKMAPTOP(map)
retval = getindmapresource(map, typ, &indx);
if (retval) {
ROMlib_setreserr(noErr);
/*-->*/ return retval;
}
EWALKMAP()
ROMlib_setreserr(resNotFound);
return 0;
}
P2(PUBLIC pascal trap, Handle, Get1IndResource, ResType, typ, /* IMIV-15 */
INTEGER, i)
{
resmaphand map;
Handle retval;
INTEGER tempi;
map = ROMlib_rntohandl(Cx(CurMap), (Handle *)0);
if (!map) {
ROMlib_setreserr(resFNotFound);
/*-->*/ return 0;
}
tempi = i;
if (i <= 0 || !(retval = getindmapresource(map, typ, &tempi))) {
ROMlib_setreserr(resNotFound);
/*-->*/ return 0;
} else {
ROMlib_setreserr(noErr);
return retval;
}
}
/* ROMlib_maptypidtop: given a map, typ and an id,
*ptr is filled in appropriately */
A4(PUBLIC, OSErr, ROMlib_maptypidtop, resmaphand, map, /* INTERNAL */
ResType, typ, INTEGER, id, resref **, ptr)
{
INTEGER i, j;
typref *tr;
resref *rr;
WALKTR(map, i, tr)
if (CL(tr->rtyp) == typ) {
WALKRR(map, tr, j, rr)
if (Cx(rr->rid) == id) {
*ptr = rr;
return(noErr);
}
EWALKRR(rr)
}
EWALKTR(tr)
return resNotFound;
}
/* ROMlib_typidtop: given a type and an id,
ROMlib_typidtop fills in *pth and *ptr
with a resmap handle and a resref pointer */
A4(PUBLIC, OSErr, ROMlib_typidtop, ResType, typ, INTEGER, id, /* INTERNAL */
resmaphand *, pth, resref **, ptr)
{
resmaphand map;
WALKMAPCUR (map)
if (ROMlib_maptypidtop(map, typ, id, ptr) == noErr)
{
*pth = map;
return noErr;
}
EWALKMAP ()
warn_resource_not_found (typ, id);
return resNotFound;
}
#define MAELSTROM_HACK
#define NUM_ROMLIB_DEFS 10
#if !defined(MAELSTROM_HACK)
PRIVATE LONGINT ROMlib_defs[NUM_ROMLIB_DEFS];
#endif
/*
* Don't change the order of the routines below.
* We have made stubs of the form:
*
* 0x20780058 movel 0x58:w, a0
* 0x206800nn movel a0@(nn), a0
* 0x4ED0 jmp a0@
*
* nn is the offset into ROMlib_defs (0, 4, 8, ...)
*/
PRIVATE BOOLEAN acceptable( unsigned long addr )
{
return ! (islower( addr & 0xFF ) ||
islower ( (addr >> 8) & 0xFF ) ||
islower ( (addr >> 16) & 0xFF ) ||
islower ( (addr >> 24) & 0xFF ));
}
PRIVATE void ROMlib_init_xdefs( void )
{
#if !defined(MAELSTROM_HACK)
ROMlib_defs[0] = RM((long) P_cdef0);
ROMlib_defs[1] = RM((long) P_cdef16);
ROMlib_defs[2] = RM((long) P_wdef0);
ROMlib_defs[3] = RM((long) P_wdef16);
ROMlib_defs[4] = RM((long) P_mdef0);
ROMlib_defs[5] = RM((long) P_ldef0);
ROMlib_defs[6] = RM((long) P_mbdf0);
ROMlib_defs[7] = RM((long) P_snth5);
ROMlib_defs[8] = RM((long) P_unixmount);
ROMlib_defs[9] = RM((long) P_cdef1008);
*(LONGINT *)SYN68K_TO_US(0x58) = RM((LONGINT) ROMlib_defs);
#else
THz save_zone;
Handle oldhandle, newhandle;
long timeout;
LONGINT *ROMlib_defs;
save_zone = TheZone;
TheZone = SysZone;
newhandle = 0;
timeout = 64000;
do {
oldhandle = newhandle;
newhandle = NewHandle(NUM_ROMLIB_DEFS * sizeof(ROMlib_defs[0]));
if (oldhandle)
DisposHandle(oldhandle);
} while (!acceptable((unsigned long) newhandle->p) && --timeout);
#if !defined(NDEBUG)
if (!timeout)
warning_unexpected("Maelstrom hack didn't work");
#endif
HLock(newhandle);
ROMlib_defs = (LONGINT *) STARH(newhandle);
ROMlib_defs[0] = RM((long) P_cdef0);
ROMlib_defs[1] = RM((long) P_cdef16);
ROMlib_defs[2] = RM((long) P_wdef0);
ROMlib_defs[3] = RM((long) P_wdef16);
ROMlib_defs[4] = RM((long) P_mdef0);
ROMlib_defs[5] = RM((long) P_ldef0);
ROMlib_defs[6] = RM((long) P_mbdf0);
ROMlib_defs[7] = RM((long) P_snth5);
ROMlib_defs[8] = RM((long) P_unixmount);
ROMlib_defs[9] = RM((long) P_cdef1008);
*(LONGINT *)SYN68K_TO_US(0x58) = (LONGINT) newhandle->p;
TheZone = save_zone;
#endif
}
typedef struct
{
ResType type;
INTEGER id;
}
pseudo_rom_entry_t;
PRIVATE Handle
pseudo_get_rom_resource (ResType typ, INTEGER id)
{
Handle retval;
int i;
static pseudo_rom_entry_t pseudo_rom_table[] =
{
{ T ('F', 'O', 'N', 'D'), 3 }
};
for (i = 0; (i < (int) NELEM (pseudo_rom_table) &&
(pseudo_rom_table[i].type != typ
|| pseudo_rom_table[i].id != id)); ++i)
;
if (i < (int) NELEM (pseudo_rom_table))
{
INTEGER save_map;
save_map = CurMap;
CurMap = SysMap;
retval = C_Get1Resource (typ, id);
CurMap = save_map;
}
else
retval = 0;
return retval;
}
#if defined (ULTIMA_III_HACK)
PUBLIC boolean_t ROMlib_ultima_iii_hack;
#endif
P2(PUBLIC pascal trap, Handle, GetResource, ResType, typ, INTEGER, id)
{
resmaphand map;
resref *rr;
static int beenhere = 0;
Handle retval;
if (!beenhere) {
beenhere = 1;
ROMlib_init_xdefs();
}
retval = pseudo_get_rom_resource (typ, id);
if (retval)
/*-->*/return retval;
#define BOBSEYESHACK
#if defined(BOBSEYESHACK)
/*
* This gets around a bug in Bob's Eyes that references stray memory.
* I'm trying to find the author of the program and get him to fix it.
* --Cliff Sat Sep 3 08:02:51 MDT 1994
*/
if (typ == TICK("rAnd") && id == 128)
return 0;
#endif
#if !defined(MAC)
switch (typ) { /* fake out code resources */
#define ICKYHACK
#if defined (ICKYHACK)
case T('P','A','C','K'):
return GetResource(TICK("ALRT"), -3995);
#endif /* ICKYHACK */
}
#endif /* !defined(MAC) */
ROMlib_setreserr(ROMlib_typidtop(typ, id, &map, &rr));
if (Cx(ResErr) == resNotFound) {
ROMlib_setreserr(noErr);
retval = 0; /* IMIV */
} else {
if (ResErr == noErr)
retval = ROMlib_mgetres(map, rr);
else
retval = 0;
}
#if defined (ULTIMA_III_HACK)
if (ROMlib_ultima_iii_hack && typ == TICK("PREF") && retval)
{
*((char *) STARH (retval) + 1) = 0; /* turn off Music prefs */
}
#endif
return retval;
}
P2(PUBLIC pascal trap, Handle, Get1Resource, ResType, typ, /* IMIV-16 */
INTEGER, id)
{
Handle retval;
resmaphand map;
resref *rr;
map = ROMlib_rntohandl (Cx (CurMap), NULL);
if (!map)
{
ROMlib_setreserr (resFNotFound);
return NULL;
}
ROMlib_setreserr (ROMlib_maptypidtop (map, typ, id, &rr));
if (ResErr == noErr)
retval = ROMlib_mgetres (map, rr);
else
{
warn_resource_not_found (typ, id);
retval = NULL;
}
if (ResErr == CWC (resNotFound))
/* IMIV */
ResErr = CWC (noErr);
return retval;
}
A3(PRIVATE, Handle, getnamedmapresource, resmaphand, map, ResType, typ,
StringPtr, nam)
{
INTEGER i, j;
typref *tr;
resref *rr;
WALKTR(map, i, tr)
if (CL(tr->rtyp) == typ) {
WALKRR(map, tr, j, rr)
if (Cx(rr->noff) != -1 && EqualString((StringPtr) (
(char *)STARH(map) + Hx(map, namoff) + Cx(rr->noff)),
(StringPtr) nam, 0, 1))
/*-->*/ return ROMlib_mgetres(map, rr);
EWALKRR(rr)
}
EWALKTR(tr)
ROMlib_setreserr(resNotFound);
return(0);
}
P2(PUBLIC pascal trap, Handle, GetNamedResource, ResType, typ, StringPtr, nam)
{
Handle retval;
retval = NULL;
if (EqualString (nam, about_box_menu_name_pstr, TRUE, TRUE))
{
static Handle phoney_hand;
if (!phoney_hand)
phoney_hand = NewHandleSys (0);
retval = phoney_hand;
}
else
{
resmaphand map;
WALKMAPCUR(map)
if ((retval = getnamedmapresource(map, typ, nam))) {
ROMlib_setreserr(noErr);
goto DONE;
}
EWALKMAP()
warn_resource_not_found_name (typ, nam);
ROMlib_setreserr(resNotFound);
}
DONE:
return retval;
}
P2(PUBLIC pascal trap, Handle, Get1NamedResource, ResType, typ, /* IMIV-16 */
StringPtr, s)
{
resmaphand map;
map = ROMlib_rntohandl(Cx(CurMap), (Handle *)0);
if (!map) {
ROMlib_setreserr(resFNotFound);
/*-->*/ return 0;
}
return(getnamedmapresource(map, typ, s));
}
P1 (PUBLIC pascal trap, void, LoadResource, Handle volatile, res)
{
resmaphand map;
typref *tr;
resref *rr;
int16 savemap;
volatile LONGINT savea0d0[2];
savea0d0[0] = EM_D0;
savea0d0[1] = EM_A0;
if (!res)
{
ROMlib_setreserr (nilHandleErr);
return;
}
if (res->p)
{
ROMlib_setreserr (noErr);
}
else
{
savemap = CurMap;
CurMap = ((resmap *) STARH (MR (TopMapHndl)))->resfn;
ROMlib_setreserr (ROMlib_findres (res, &map, &tr, &rr));
CurMap = savemap;
if (ResErr == CWC (noErr))
{
BOOLEAN save_resload;
save_resload = ResLoad;
SetResLoad (TRUE);
ROMlib_mgetres (map, rr);
ResLoad = save_resload;
}
}
EM_D0 = savea0d0[0];
EM_A0 = savea0d0[1];
}
P1(PUBLIC pascal trap, void, ReleaseResource, Handle, res)
{
resmaphand map;
typref *tr;
resref *rr;
Handle h;
if (ROMlib_setreserr(ROMlib_findres(res, &map, &tr, &rr)))
/*-->*/ return;
if (Cx(rr->ratr) & resChanged)
ROMlib_wr(map, rr);
if (ResErr != CWC (noErr) || !rr->rhand)
return;
h = MR (rr->rhand);
if ((*h).p)
HClrRBit(h);
DisposHandle(h);
rr->rhand = 0;
}
P1(PUBLIC pascal trap, void, DetachResource, Handle, res)
{
resmaphand map;
typref *tr;
resref *rr;
Handle h;
if (ROMlib_setreserr(ROMlib_findres(res, &map, &tr, &rr)))
/*-->*/ return;
if (ResErr != noErr || !(h = (Handle) MR(rr->rhand)))
return;
if (Cx(rr->ratr) & resChanged) {
ROMlib_setreserr(resAttrErr); /* IV-18 */
return;
}
rr->rhand = 0;
if ((*h).p)
HClrRBit(h);
}