65816-llvm-mos/runtime/include/iigs/resource.h
Scott Duensing da095402ec Updated
2026-06-02 23:17:57 -05:00

120 lines
4.6 KiB
C

// iigs/resource.h - typed-C facade over the IIgs Resource Manager.
//
// Phase 3.4 STUB-ONLY landing. The bundler + linker integration ship
// fully (see tools/rsrcBundle/), but the *runtime* path is blocked on
// Phase 1.1 (the GS/OS fopen hang). GS/OS 6.0.2 + ResourceStartUp +
// OpenResourceFile reaches the same path that hangs in fopen today, so
// the LoadResource()/GetResourceSize() entry points below return error
// codes instead of calling the toolbox. When Phase 1.1 lands, flip
// IIGS_RESOURCE_RUNTIME_ENABLED to 1 (or define it at the compiler
// level) and rebuild the runtime - the same C surface stays.
//
// What you GET today:
// - resourceProbeInit() reports whether the runtime path is enabled.
// - LoadResource() / GetResourceSize() return RES_ERR_BLOCKED unless
// IIGS_RESOURCE_RUNTIME_ENABLED is set at compile time.
//
// HLock semantics (IMPORTANT for future Phase 1.1 unblock):
// The toolbox LoadResource() returns a HANDLE (void **) to a master
// pointer in MM-relocatable storage. The application MUST call
// HLock() before dereferencing if it intends to call ANY toolbox
// routine that could trigger a heap compaction (most do). Without
// the HLock, the master pointer can be rewritten under you between
// the LoadResource and the deref. The typed wrappers below DO NOT
// call HLock for you - that is a deliberate choice because over-
// locking is a memory-fragmentation footgun and the right scope is
// workload-specific. Callers should:
// void **h = LoadResourceTyped(0x8014, 1);
// HLock(h);
// const RTextT *t = (const RTextT *)*h;
// ... use t ...
// HUnlock(h);
#ifndef IIGS_RESOURCE_H
#define IIGS_RESOURCE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// Flip to 1 (or pass -DIIGS_RESOURCE_RUNTIME_ENABLED=1 on the build line)
// once Phase 1.1 unblocks GS/OS fopen on 6.0.2. At that point the typed
// wrappers below dispatch into the live toolbox; until then they stub.
#ifndef IIGS_RESOURCE_RUNTIME_ENABLED
#define IIGS_RESOURCE_RUNTIME_ENABLED 0
#endif
// Status codes returned by the typed wrappers. Mirror the runtime's
// existing errno-style convention (negative = error).
enum {
RES_OK = 0,
RES_ERR_BLOCKED = -1, // Phase 1.1 runtime path still blocked
RES_ERR_NOT_STARTED = -2, // resourceProbeInit() not called yet
RES_ERR_NOT_FOUND = -3, // OpenResourceFile / LoadResource failed
RES_ERR_TOOLBOX = -4 // Resource Manager returned non-zero
};
// Resource type codes we expect to bundle. See Apple IIgs Toolbox
// Reference Vol 3 chapter 42 for the canonical list. Defined here as
// constants so callers don't have to use raw hex.
#define RES_TYPE_RICON 0x8005
#define RES_TYPE_RTEXT 0x8014
#define RES_TYPE_RPSTRING 0x8015
#define RES_TYPE_RCSTRING 0x8016
// Resource ID type matching the toolbox (32-bit on disk and in the
// rIndex; the public API uses uint32_t).
typedef uint32_t IigsResIdT;
// Resource type code (16-bit; high bit reserved for system/extended
// types, low 15 bits for the actual code).
typedef uint16_t IigsResTypeT;
// One-shot Resource Manager bring-up. Calls MMStartUp + TLStartUp +
// ResourceStartUp + OpenResourceFile (on our own pathname) when the
// runtime path is enabled. Always callable; safe to call more than
// once (subsequent calls are no-ops).
//
// Returns:
// RES_OK if the resource fork was opened (or the stub
// path "succeeded" with no-op behavior),
// RES_ERR_BLOCKED if compiled with IIGS_RESOURCE_RUNTIME_ENABLED=0
// (the default until Phase 1.1 lands),
// RES_ERR_TOOLBOX if any of the StartUp calls returned non-zero.
int resourceProbeInit(void);
// Read whether the runtime path is live. Cheap; returns 1 iff a
// successful resourceProbeInit() has run AND the build enabled the
// runtime path. Returns 0 in the stub-only landing.
int resourceRuntimeEnabled(void);
// LoadResource typed wrapper. Returns a HANDLE (void **) on success,
// or NULL on failure (and sets *err if non-NULL).
//
// Caller is responsible for HLock/HUnlock pairing around any usage that
// crosses a toolbox call; see HLock semantics block at the top of this
// file.
void **iigsLoadResource(IigsResTypeT resType, IigsResIdT resId, int *err);
// GetResourceSize typed wrapper. Returns the byte size of the resource
// or 0 on failure (and sets *err if non-NULL).
uint32_t iigsGetResourceSize(IigsResTypeT resType, IigsResIdT resId,
int *err);
#ifdef __cplusplus
}
#endif
#endif // IIGS_RESOURCE_H