// JoeyLib lifecycle: configuration, initialization, shutdown. #ifndef JOEYLIB_CORE_H #define JOEYLIB_CORE_H #include "platform.h" #include "types.h" typedef struct { // Runtime compiled-sprite cache size. 0 selects a per-platform // default: 8 KB on IIgs, 32 KB on Amiga/ST/DOS (the 68k/x86 // emitters are ~4-8x less code-dense than the 65816's, so a // 32x32 sprite can need 8-16 KB there). Size against // jlSpriteCompiledSize() when tuning. On the IIgs the cache is one // Memory Manager block allocated with attrNoCross (it may not span // a 64 KB bank boundary), so values above 65536 are clamped to // 65536; even a clamped request can fail if no free bank exists. uint32_t codegenBytes; uint32_t audioBytes; // reserved; not yet consulted by any audio engine } jlConfigT; // Initialize the library. Returns true on success. // On failure, jlLastError() returns a human-readable description. bool jlInit(const jlConfigT *config); // Shut down the library, releasing all resources. void jlShutdown(void); // Returns the most recent error message, or NULL if none. const char *jlLastError(void); // Returns the platform identifier string (e.g., "Apple IIgs", "MS-DOS"). const char *jlPlatformName(void); // Returns the library version string (e.g., "1.0.0"). const char *jlVersionString(void); // Allocate a large or persistent buffer, backed by the platform's // native allocator rather than the small C heap. Use this (not malloc) // for anything that exceeds the per-allocation or total ceiling of the // stock C heap -- on the IIgs the C heap lives in bank 0 and is tiny, // and a single malloc is capped at ~32 KB, so multi-KB caches and frame // buffers must come from the IIgs Memory Manager instead. Returns NULL // on failure. The returned pointer is NOT zero-filled. void *jlAlloc(uint32_t bytes); // Release a buffer returned by jlAlloc. NULL is accepted and ignored. void jlFree(void *p); // Block the calling thread until the next display vertical blank. // Used to pace game loops to the display's native refresh rate // (~70 Hz on VGA mode 13h, ~50 or ~60 Hz on Amiga/ST PAL/NTSC, ~60 Hz // on IIgs SHR). Cheap on every port since the underlying mechanism is // always a hardware-level wait, not a software timer. void jlWaitVBL(void); // Monotonic 16-bit frame counter. Caller must poll faster than // 2 * jlFrameHz() so no edge is missed. Used by benchmarks and // frame-rate-independent animation. (Per-port edge-detect / VBL-ISR // mechanism is documented at jlpFrameCount in src/core/port.h.) uint16_t jlFrameCount(void); // Nominal display frame rate in Hz: 50 (Amiga PAL), 60 (IIgs / ST // NTSC default), 70 (VGA mode 13h). The actual VBL cadence may // drift slightly; the value reported here is what benchmarks divide // by to convert iters-per-N-frames to ops/sec. uint16_t jlFrameHz(void); // Monotonic wall-clock millisecond counter since jlInit. On DOS/ST it // reads a real hardware timer; on IIgs/Amiga the generic implementation // derives it from the frame counter (frame-granularity steps, and the // caller must poll at least once per 65535 frames -- ~18 min at 60Hz -- // or wrapped frames are lost). Two consecutive calls separated by a long // render report the true elapsed time, not the number of VBLs that // fired. (Per-port millisecond timer sources are documented at // jlpMillisElapsed in src/core/port.h.) uint32_t jlMillisElapsed(void); // Deterministic, seedable pseudo-random generator. Bit-identical // output across every JoeyLib port for a given seed, since stdlib // rand() varies wildly between platforms and C libraries. // The underlying algorithm is xorshift32 (Marsaglia): period 2^32-1, // no multiply, suitable for games but not for cryptography. uint32_t jlRandom(void); // Return a value in [0, bound). bound == 0 returns 0. uint16_t jlRandomRange(uint16_t bound); // Seed the generator. Any 32-bit value is accepted; a seed of 0 is // remapped to 1 since xorshift cannot escape the all-zero state. void jlRandomSeed(uint32_t seed); #endif