mirror of
https://github.com/ctm/executor.git
synced 2024-06-05 23:29:33 +00:00
531 lines
12 KiB
C
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);
|
|
}
|