// Internal platform-override registry (the new joeylib's joey.h equivalent). // // Every overridable operation is a jlp() resolved at COMPILE TIME: a // portable-C default lives in src/generic/ and a machine supplies its own // version when it defines JL_HAS_ in include/joey/platform.h. There is no // runtime dispatch. This header wires the two together (the dispatch tail at // the bottom) and holds the IIgs asm-macro overrides. // // Two flavors of op (both use the same jlp + JL_HAS mechanism): // (A) ops with a genuine portable generic -- draw/tile/sprite primitives, // surface readers, allocation, millisElapsed. A machine overrides only // where it needs native speed/behavior; otherwise it links the generic. // (B) platform SERVICES with no portable behavior -- init/shutdown/present, // input, vbl/frame timing, the audio engine. The "generic" is a no-op/ // zero stub so a blank/template port still links; every real port // overrides via JL_HAS_. // // Included by src/core/*.c, src//*.c, and src/generic/*.c. NOT public. #ifndef JOEYLIB_PORT_H #define JOEYLIB_PORT_H #include #include "joey/audio.h" #include "joey/core.h" #include "joey/input.h" #include "joey/serial.h" #include "joey/sprite.h" #include "joey/surface.h" // Every op's declaration + its generic/override dispatch lives in the "Op // dispatch" section at the bottom of this header. The block immediately below // holds the IIgs's asm-macro overrides: it #define-s jlp directly to the // iigs*Inner asm entry points, so IIgs primitives never pay a function call. #ifdef JOEYLIB_PLATFORM_IIGS // Root the save tree at the APPLICATION directory via the GS/OS "1/" prefix // designator (the Loader sets prefix 1 to the app's directory at launch). // Unrooted paths resolve against prefix 0, which a Finder launch leaves // pointing away from (or nowhere near) the app's volume - measured: every // plain "SAVES/x" open failed under MAME GS/OS 6 while the same file opened // fine through "1/SAVES/x". libc's fopen passes the string verbatim to // GS/OS Open, which accepts prefix-designator syntax. #define JL_SAVE_DIR "1/SAVES" #define JL_SAVE_DIR_PREFIX "1/SAVES/" // ===================================================================== // IIgs direct-dispatch macros. // // IIgs overrides the draw/tile/flood primitives by #define-ing jlp // directly to its asm entry points (iigs*Inner), so each primitive inlines // the asm call at the call site with no function-call plumbing. A C wrapper // would cost ~60-80 cyc/call of pure overhead here (prologue PHB/PHD/TCD, // redundant arg re-push for the inner JSL, then epilogue); the macro form // eliminates it. Cross-platform code in src/core/*.c calls jlp(...) // unchanged and the preprocessor swaps in the asm before compile. // // Ops the IIgs does not accelerate (or only accelerates for the stage) // fall through to the portable-C generic jlpGeneric, like every other // machine. Some macros use comma-expression form to evaluate to a `bool` // (e.g. fillCircle: stage-only, returns false off-stage so the core falls // back to its C span fill). // ===================================================================== extern void iigsDrawPixelInner (uint8_t *pixels, uint16_t x, uint16_t y, uint16_t nibble); extern void iigsDrawPixelMark (uint16_t x, uint16_t y, uint16_t nibble); extern void iigsDrawLineInner (uint8_t *pixels, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t nibble); extern void iigsDrawCircleInner (uint8_t *pixels, uint16_t cx, uint16_t cy, uint16_t r, uint16_t nibble); extern void iigsFillCircleInner (uint8_t *pixels, uint16_t cx, uint16_t cy, uint16_t r, uint16_t nibble); extern void iigsSurfaceClearInner(uint8_t *pixels, uint16_t fillWord); extern void iigsSurfaceClearFastInner(uint8_t *pixels, uint16_t fillWord); extern void iigsTileFillInner (uint8_t *dstRow0, uint16_t nibble); extern void iigsTileFillMark (uint16_t nibble, uint16_t bx, uint16_t by); extern void iigsTileCopyInner (uint8_t *dstRow0, const uint8_t *srcRow0); extern void iigsTileCopyMark (const uint8_t *srcRow0, uint16_t dstBx, uint16_t dstBy); extern void iigsTileCopyMaskedInner(uint8_t *dstRow0, const uint8_t *srcRow0, uint16_t transparent); extern void iigsTilePasteInner (uint8_t *dstRow0, const uint8_t *srcTilePixels); extern void iigsTilePasteMark (const uint8_t *srcTilePixels, uint16_t bx, uint16_t by); extern void iigsTileMapPasteMark (uint16_t bx, uint16_t by, uint16_t wTiles, uint16_t hTiles, const uint8_t *tiles, const uint8_t *map); extern void iigsTilePasteMonoInner(uint8_t *dstRow0, const uint8_t *monoTile, uint16_t fgColor, uint16_t bgColor); extern void iigsTileSnapInner (uint8_t *dstTilePixels, const uint8_t *srcRow0); extern void iigsCopyRectRows (uint8_t *dst, uint16_t srcLo, uint16_t srcBank, uint16_t rowBytes, uint16_t rows); extern void iigsQuitGS (void); extern void iigsFillRectMark (uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t nibble); extern void iigsFillRectNoMark (uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t nibble); extern void iigsFloodWalkAndScansInner(uint8_t *pixels, uint16_t x, uint16_t y, uint16_t matchColor, uint16_t newColor, uint16_t matchEqual, int16_t *stackX, int16_t *stackY, uint16_t *spInOut, uint16_t maxSp); extern uint16_t gFloodSeedMatch; extern uint16_t gFloodLeftX; extern uint16_t gFloodRightX; // Stage identity for the stage-gated macros below: a direct extern // read of surface.c's gStage (also declared in surfaceInternal.h -- // duplicated here because port.h is included by TUs that never pull in // surfaceInternal.h) instead of the jlStageGet() accessor, which costs // a cross-segment JSL per primitive/span (PERF-AUDIT #10/#17). Same // direct-extern precedent as codegenArenaInternal.h's arena globals. // Read-only here. extern jlSurfaceT *gStage; // drawPixel: migrated to jlpDrawPixel. The asm plots into s->pixels for any // IIgs (chunky) surface; no generic defer needed. #define jlpDrawPixel(_s, _x, _y, _c) \ iigsDrawPixelInner((_s)->pixels, (uint16_t)(_x), (uint16_t)(_y), \ (uint16_t)((_c) & 0x0F)) // drawLine / drawCircle migrated to jlp: asm on any IIgs (chunky) surface, // callers gate the on-surface fast path on JL_HAS_DRAW_LINE / _CIRCLE. #define jlpDrawLine(_s, _x0, _y0, _x1, _y1, _c) \ iigsDrawLineInner((_s)->pixels, (uint16_t)(_x0), (uint16_t)(_y0), \ (uint16_t)(_x1), (uint16_t)(_y1), \ (uint16_t)((_c) & 0x0F)) #define jlpDrawCircle(_s, _cx, _cy, _r, _c) \ iigsDrawCircleInner((_s)->pixels, (uint16_t)(_cx), (uint16_t)(_cy), \ (_r), (uint16_t)((_c) & 0x0F)) // fillCircle migrated to jlpFillCircle: stage-only asm, returns bool so the core // falls to the C span fill for non-stage / off-surface. JL_HAS_FILL_CIRCLE-gated. // The asm derives its fill bytes from the raw nibble (PERF-AUDIT #41): the // macro passes (c & 0x0F), never the old * 0x1111 fill word, which lowered // to a software-multiply helper call for a runtime color (the only call // site, draw.c, always passes a variable). The jlp layer owns the & 0x0F. #define jlpFillCircle(_s, _cx, _cy, _r, _c) \ ((_s) == gStage \ ? (iigsFillCircleInner((_s)->pixels, (uint16_t)(_cx), (uint16_t)(_cy), \ (_r), (uint16_t)((_c) & 0x0F)), \ true) \ : false) // surfaceClear: migrated to the jlp override model. The asm clears the // stage surface; non-stage surfaces defer to the portable-C generic default. #define jlpSurfaceClear(_s, _d) \ ((_s) == gStage \ ? iigsSurfaceClearFastInner((_s)->pixels, \ (uint16_t)((uint16_t)(_d) | ((uint16_t)(_d) << 8))) \ : jlpGenericSurfaceClear((_s), (_d))) // fillRect: STAGE-GATED onto the FUSED Mark entry (NATIVE-PERF Phase 6 // W1, the tile Step-D pattern): ONE JSL derives the destination in asm // from the pinned stage base + gRowOffsetLut, fills W x H with the same // leading/middle/trailing nibble handling as the old Inner, and widens // the H-row dirty band via stageRectMark -- replacing the fill JSL plus // the C-side surfaceMarkDirtyRect -> iigsMarkDirtyRowsInner JSL pair // (draw.c compiles that mark out under JL_FILL_RECT_MARK_FUSED below). // Non-stage surfaces defer to the chunky generic and need no mark. The // asm derives the fill word from the raw nibble (PERF-AUDIT #41); the // jlp layer owns the & 0x0F. #define jlpFillRect(_s, _x, _y, _w, _h, _c) \ ((_s) == gStage \ ? iigsFillRectMark((uint16_t)(_x), (uint16_t)(_y), \ (uint16_t)(_w), (uint16_t)(_h), \ (uint16_t)((_c) & 0x0F)) \ : jlpGenericFillRect((_s), (_x), (_y), (_w), (_h), (_c))) // Unfused twin for callers that batch their own mark (jlDrawRect's // on-surface fast path keeps its single whole-outline mark instead of // paying two (h-2)-row fused walks on the vertical edges; jlFillCircle // batches one bounding-square mark over its spans). Same body in asm; // a flag skips the stageRectMark tail. #define jlpFillRectNoMark(_s, _x, _y, _w, _h, _c) \ ((_s) == gStage \ ? iigsFillRectNoMark((uint16_t)(_x), (uint16_t)(_y), \ (uint16_t)(_w), (uint16_t)(_h), \ (uint16_t)((_c) & 0x0F)) \ : jlpGenericFillRect((_s), (_x), (_y), (_w), (_h), (_c))) // The stage arm of jlpFillRect fuses its dirty mark into the asm. #define JL_FILL_RECT_MARK_FUSED 1 // Tile primitives operate on caller-computed row pointers; just // forward the args. by/bx are tile coords -> bx*4 + by*8*160 byte // offset within the surface. Use SURFACE_ROW_OFFSET (LUT lookup) to // dodge a software multiply helper for the *160 multiply. // tileFill / tileCopy / tilePaste are STAGE-GATED onto the FUSED Mark // entries (NATIVE-PERF Phase 2 Step D / R2): for the stage, ONE JSL // derives the destination in asm from the pinned stage base + the // gRowOffsetLut, runs the op, and widens the dirty band -- replacing // C-side pointer math plus two JSLs (op inner + iigsMarkDirtyRowsInner // via tile.c's tileMarkDirty, which is compiled out for these three // ops on IIgs). Non-stage surfaces keep the pointer-based inners. // tileFill: the macro passes the raw nibble (the jlp layer owns the & 0x0F); // the asm derives the $NNNN fill word (PERF-AUDIT #41 -- the old C-side // * 0x1111 lowered to a software-multiply helper for a runtime color). #define jlpTileFill(_s, _bx, _by, _c) \ ((_s) == gStage \ ? iigsTileFillMark((uint16_t)((_c) & 0x0F), (uint16_t)(_bx), (uint16_t)(_by)) \ : iigsTileFillInner(&(_s)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_by) << 3) \ + ((uint16_t)(_bx) << 2)], \ (uint16_t)((_c) & 0x0F))) // tileCopy / tileCopyMasked: take surface+tile-coords; the asm macro derives // row-0 pointers (row = by*8 -> SURFACE_ROW_OFFSET(by<<3); col byte = bx*4 -> bx<<2). // tileCopy's src may be ANY surface, so its row-0 pointer stays C-derived // even on the fused stage-dst arm. #define jlpTileCopy(_d, _dbx, _dby, _s, _sbx, _sby) \ ((_d) == gStage \ ? iigsTileCopyMark(&(_s)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_sby) << 3) + ((uint16_t)(_sbx) << 2)], (uint16_t)(_dbx), (uint16_t)(_dby)) \ : iigsTileCopyInner(&(_d)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_dby) << 3) + ((uint16_t)(_dbx) << 2)], \ &(_s)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_sby) << 3) + ((uint16_t)(_sbx) << 2)])) #define jlpTileCopyMasked(_d, _dbx, _dby, _s, _sbx, _sby, _t) \ iigsTileCopyMaskedInner(&(_d)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_dby) << 3) + ((uint16_t)(_dbx) << 2)], \ &(_s)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_sby) << 3) + ((uint16_t)(_sbx) << 2)], \ (uint16_t)(_t)) // tilePaste / tileSnap: take surface+coords + the chunky tile buffer; the asm // macros derive row-0. #define jlpTilePaste(_d, _bx, _by, _ct) \ ((_d) == gStage \ ? iigsTilePasteMark((_ct), (uint16_t)(_bx), (uint16_t)(_by)) \ : iigsTilePasteInner(&(_d)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_by) << 3) + ((uint16_t)(_bx) << 2)], (_ct))) #define jlpTileSnap(_s, _bx, _by, _out) \ iigsTileSnapInner((_out), &(_s)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_by) << 3) + ((uint16_t)(_bx) << 2)]) // tilePasteMono: fused mono colorize + paste in one asm pass (PERF-AUDIT #3) // -- no intermediate jlTileT and no second paste call. Stage-only like the // other stage-gated macros; non-stage surfaces defer to the portable-C // generic (colorize + jlpTilePaste). fg/bg arrive PRE-MASKED to 4 bits (the // public jlTilePasteMono wrapper owns the & 0x0F, PERF-AUDIT #69), so they // are passed through un-re-masked per the dispatch-stanza contract below. #define jlpTilePasteMono(_d, _bx, _by, _mt, _fg, _bg) \ ((_d) == gStage \ ? iigsTilePasteMonoInner(&(_d)->pixels[SURFACE_ROW_OFFSET((uint16_t)(_by) << 3) + ((uint16_t)(_bx) << 2)], \ (_mt), (uint16_t)(_fg), (uint16_t)(_bg)) \ : jlpGenericTilePasteMono((_d), (_bx), (_by), (_mt), (_fg), (_bg))) // Flood: IIgs overrides only the all-in-one tier (JL_HAS_FLOOD_WALK_AND_SCANS). // The dispatch tail leaves jlpFloodWalkAndScans defined here; the planar flood // hooks (jlpFloodWalkPlanes / jlpFloodScanRowPlanes) belong to the planar 68k // ports (Amiga + Atari ST) and IIgs never declares them (their call sites are // #if'd out on ports without the JL_HAS_FLOOD_*_PLANES flags). // // Tier-1 flood: multi-output. Asm sets gFloodSeedMatch / gFloodLeftX / // gFloodRightX; macro reads those into the caller's out-ptrs. #define jlpFloodWalkAndScans(_pix, _x, _y, _mc, _nc, _me, _sx, _sy, _sp, _ms, _smOut, _lxOut, _rxOut) \ (iigsFloodWalkAndScansInner((_pix), (uint16_t)(_x), (uint16_t)(_y), \ (uint16_t)((_mc) & 0x0F), \ (uint16_t)((_nc) & 0x0F), \ (uint16_t)((_me) ? 1 : 0), \ (_sx), (_sy), \ (uint16_t *)(_sp), \ (uint16_t)(_ms)), \ *(_smOut) = (gFloodSeedMatch != 0), \ *(_lxOut) = (int16_t)gFloodLeftX, \ *(_rxOut) = (int16_t)gFloodRightX, \ true) // ===================================================================== // IIgs planar-hook elision. // // The planar dual-write hooks (surfaceCopyPlanes, the sprite *Planes ops) // let Amiga/ST mirror draws into their bitplanes. IIgs is chunky-native, so // it #define-s them to ((void)0): the call site is deleted at preprocess time // rather than paying a cross-segment JSL/RTL for a no-op. Arg lists match each // op's arity so the preprocessor parses and discards the exact call; all args // are plain lvalues / field reads, so dropping them changes no behavior. (The // other chunky ports get the same elision from the shared chunky block after // the IIgs section -- PERF-AUDIT #42. The tile/fillRect planar work is folded // into each jlp op, so there are no separate planar hooks left to elide // for those.) // ===================================================================== #define jlpSurfaceCopyPlanes(_dst, _src) ((void)0) // sprite planes mirror: no-op on IIgs (chunky -> codegen does the work). #define jlpSpriteDrawPlanes(_s, _sp, _x, _y) ((void)0) #define jlpSpriteSavePlanes(_s, _x, _y, _w, _h, _dst) ((void)0) #define jlpSpriteRestorePlanes(_s, _x, _y, _w, _h, _src) ((void)0) // frameCount: straight to the GetTick asm wrapper (peislam.s). The hal.c // C wrapper this replaces was one of two pure forwarding layers between // jlFrameCount and the Misc Toolset GetTick call -- ~60-80 cycles each on // a clock that game loops (and the UBER bench loop) poll constantly. extern uint16_t iigsGetTickWord(void); #define jlpFrameCount() iigsGetTickWord() // ===================================================================== // JL_HAS registry consistency checks (PERF-AUDIT #26). // // The dispatch stanzas below short-circuit on #if !defined(jlp) // before the JL_HAS_ flag is ever tested, and the core fast-path // gates (JL_HAS_DRAW_LINE / DRAW_CIRCLE / FILL_CIRCLE / // FLOOD_WALK_AND_SCANS in core/draw.c) consult only the flag. So a // macro override above whose flag is missing from the // include/joey/platform.h registry either turns that registry into // false documentation or silently drops a core fast path back to // generic C on the perf-reference machine. These checks make a // missing/removed flag a compile failure instead: one #error per // macro override defined above. (The reverse drift -- flag present, // macro removed -- already fails loudly: the dispatch stanza then // declares a function override that nothing defines.) Extend this // list whenever a new IIgs macro override is added. // // Deliberately unchecked: jlpFrameCount (registry documents it as // macro-only, no JL_HAS_FRAME_COUNT on IIgs) and jlpSurfaceCopyPlanes // (JL_HAS_SURFACE_COPY_PLANES means a real planar function override; // the IIgs elision above pairs with the JL_HAS_SPRITE_* trio instead). // ===================================================================== #if !defined(JL_HAS_DRAW_PIXEL) #error "IIgs jlpDrawPixel macro without JL_HAS_DRAW_PIXEL in platform.h" #endif #if !defined(JL_HAS_DRAW_LINE) #error "IIgs jlpDrawLine macro without JL_HAS_DRAW_LINE in platform.h" #endif #if !defined(JL_HAS_DRAW_CIRCLE) #error "IIgs jlpDrawCircle macro without JL_HAS_DRAW_CIRCLE in platform.h" #endif #if !defined(JL_HAS_FILL_CIRCLE) #error "IIgs jlpFillCircle macro without JL_HAS_FILL_CIRCLE in platform.h" #endif #if !defined(JL_HAS_SURFACE_CLEAR) #error "IIgs jlpSurfaceClear macro without JL_HAS_SURFACE_CLEAR in platform.h" #endif #if !defined(JL_HAS_FILL_RECT) #error "IIgs jlpFillRect macro without JL_HAS_FILL_RECT in platform.h" #endif #if !defined(JL_HAS_TILE_FILL) #error "IIgs jlpTileFill macro without JL_HAS_TILE_FILL in platform.h" #endif #if !defined(JL_HAS_TILE_COPY) #error "IIgs jlpTileCopy macro without JL_HAS_TILE_COPY in platform.h" #endif #if !defined(JL_HAS_TILE_COPY_MASKED) #error "IIgs jlpTileCopyMasked macro without JL_HAS_TILE_COPY_MASKED in platform.h" #endif #if !defined(JL_HAS_TILE_PASTE) #error "IIgs jlpTilePaste macro without JL_HAS_TILE_PASTE in platform.h" #endif #if !defined(JL_HAS_TILE_PASTE_MONO) #error "IIgs jlpTilePasteMono macro without JL_HAS_TILE_PASTE_MONO in platform.h" #endif #if !defined(JL_HAS_TILE_SNAP) #error "IIgs jlpTileSnap macro without JL_HAS_TILE_SNAP in platform.h" #endif #if !defined(JL_HAS_SPRITE_DRAW) #error "IIgs jlpSpriteDrawPlanes elision without JL_HAS_SPRITE_DRAW in platform.h" #endif #if !defined(JL_HAS_SPRITE_SAVE) #error "IIgs jlpSpriteSavePlanes elision without JL_HAS_SPRITE_SAVE in platform.h" #endif #if !defined(JL_HAS_SPRITE_RESTORE) #error "IIgs jlpSpriteRestorePlanes elision without JL_HAS_SPRITE_RESTORE in platform.h" #endif #if !defined(JL_HAS_FLOOD_WALK_AND_SCANS) #error "IIgs jlpFloodWalkAndScans macro without JL_HAS_FLOOD_WALK_AND_SCANS in platform.h" #endif #endif /* JOEYLIB_PLATFORM_IIGS */ // ===================================================================== // 68k tile ops as always-inline headers (NATIVE-PERF Phase 2 R4a). // // The ST/Amiga tile overrides live in stTile.h / amigaTile.h as // static inline functions named stTile* / amigaTile*. Aliasing the // jlpTile* dispatch names to them HERE (before the dispatch tail) // makes the tail's #if !defined(jlpTile*) guards skip their extern // prototypes -- same mechanism as the IIgs macro block above -- and // every caller (tile.c wrappers, genericTile.c fallback routing) // inlines the op instead of paying a second cdecl call. The headers // themselves are #included at the END of this file so their // portData == NULL fallbacks can see the jlpGenericTile* prototypes // declared in the dispatch tail. // ===================================================================== #if defined(JOEYLIB_PLATFORM_ATARIST) #define jlpTileFill stTileFill #define jlpTileCopy stTileCopy #define jlpTileCopyMasked stTileCopyMasked #define jlpTilePaste stTilePaste #define jlpTilePasteMono stTilePasteMono #define jlpTileSnap stTileSnap // Whole-map engine alias (W3 seam): tile.c's jlTileMapPaste // dispatches through this spelling when a port defines it, so the // union-mark stanza lives exactly twice in tile.c (shared arm + // generic) no matter how many ports bring engines. #define jlpTileMapPaste stTileMapPaste #elif defined(JOEYLIB_PLATFORM_AMIGA) #define jlpTileFill amigaTileFill #define jlpTileCopy amigaTileCopy #define jlpTileCopyMasked amigaTileCopyMasked #define jlpTilePaste amigaTilePaste #define jlpTilePasteMono amigaTilePasteMono #define jlpTileSnap amigaTileSnap #define jlpTileMapPaste amigaTileMapPaste #elif defined(JOEYLIB_PLATFORM_X68000) #define jlpTileFill x68kTileFill #define jlpTileCopy x68kTileCopy #define jlpTileCopyMasked x68kTileCopyMasked #define jlpTilePaste x68kTilePaste #define jlpTilePasteMono x68kTilePasteMono #define jlpTileSnap x68kTileSnap #define jlpTileMapPaste x68kTileMapPaste #elif defined(JOEYLIB_PLATFORM_DOS) // DOS overrides only the whole-map walker (dosTile.h, W3); the // single-tile ops stay on the chunky generics. #define jlpTileMapPaste dosTileMapPaste #endif // ===================================================================== // Chunky planar-hook elision for the other chunky ports (PERF-AUDIT #42). // // DOS and the blank template are chunky-native like the IIgs: the planar // dual-write hooks have no bitplanes to mirror into. Elide them to // ((void)0) exactly like the IIgs block above instead of paying a real // call into the empty generic bodies (genericSprite.c and // jlpGenericSurfaceCopyPlanes) on every sprite draw/save/restore and // surface copy. Those generic no-op bodies stay in the build only as the // link-time safety net for a new planar port that has not implemented // its hooks yet. // ===================================================================== #if defined(JOEYLIB_NATIVE_CHUNKY) && !defined(JOEYLIB_PLATFORM_IIGS) #define jlpSurfaceCopyPlanes(_dst, _src) ((void)0) #define jlpSpriteDrawPlanes(_s, _sp, _x, _y) ((void)0) #define jlpSpriteSavePlanes(_s, _x, _y, _w, _h, _dst) ((void)0) #define jlpSpriteRestorePlanes(_s, _x, _y, _w, _h, _src) ((void)0) #endif /* JOEYLIB_NATIVE_CHUNKY && !JOEYLIB_PLATFORM_IIGS */ // ===================================================================== // Migrated-op dispatch (generic default unless a machine overrides). // // jlpGenericSurfaceClear is the portable-C reference (src/generic/genericDraw.c), // always available. Machine overrides are selected at compile time via // JL_HAS_ (include/joey/platform.h): a macro override (IIgs, above) already // #define-d jlp; a function override (Amiga/ST) just declares its prototype // here; otherwise jlp aliases the generic default. No runtime dispatch. // ===================================================================== void jlpGenericSurfaceClear(jlSurfaceT *s, uint8_t doubled); #if !defined(jlpSurfaceClear) #if defined(JL_HAS_SURFACE_CLEAR) void jlpSurfaceClear(jlSurfaceT *s, uint8_t doubled); /* function override */ #else #define jlpSurfaceClear(_s, _d) jlpGenericSurfaceClear((_s), (_d)) #endif #endif void jlpGenericDrawPixel(jlSurfaceT *s, uint16_t x, uint16_t y, uint8_t colorIndex); #if !defined(jlpDrawPixel) #if defined(JL_HAS_DRAW_PIXEL) void jlpDrawPixel(jlSurfaceT *s, uint16_t x, uint16_t y, uint8_t colorIndex); /* function override */ #else #define jlpDrawPixel(_s, _x, _y, _c) jlpGenericDrawPixel((_s), (_x), (_y), (_c)) #endif #endif // drawLine / drawCircle have no generic default: the portable fallback is the // clipping Bresenham in core/draw.c, and the on-surface fast path is gated by // `#if defined(JL_HAS_DRAW_LINE/_CIRCLE)`. So here we only declare the function // override prototype for non-macro overriders (Amiga/ST). #if defined(JL_HAS_DRAW_LINE) && !defined(jlpDrawLine) void jlpDrawLine(jlSurfaceT *s, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t colorIndex); #endif #if defined(JL_HAS_DRAW_CIRCLE) && !defined(jlpDrawCircle) void jlpDrawCircle(jlSurfaceT *s, int16_t cx, int16_t cy, uint16_t r, uint8_t colorIndex); #endif // fillCircle returns bool (stage/portData check is inherent); the platform // dispatch is compile-time via JL_HAS_FILL_CIRCLE. #if defined(JL_HAS_FILL_CIRCLE) && !defined(jlpFillCircle) bool jlpFillCircle(jlSurfaceT *s, int16_t cx, int16_t cy, uint16_t r, uint8_t colorIndex); #endif void jlpGenericFillRect(jlSurfaceT *s, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t colorIndex); #if !defined(jlpFillRect) #if defined(JL_HAS_FILL_RECT) void jlpFillRect(jlSurfaceT *s, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t colorIndex); /* function override (planar) */ #else #define jlpFillRect(_s, _x, _y, _w, _h, _c) jlpGenericFillRect((_s), (_x), (_y), (_w), (_h), (_c)) #endif #endif // jlpFillRectNoMark: fillRect guaranteed not to touch dirty state. On // every port but the IIgs the ops never mark, so it IS jlpFillRect; // the IIgs macro block above overrides it with the unfused asm twin. #if !defined(jlpFillRectNoMark) #define jlpFillRectNoMark(_s, _x, _y, _w, _h, _c) jlpFillRect((_s), (_x), (_y), (_w), (_h), (_c)) #endif void jlpGenericTileFill(jlSurfaceT *s, uint8_t bx, uint8_t by, uint8_t colorIndex); #if !defined(jlpTileFill) #if defined(JL_HAS_TILE_FILL) void jlpTileFill(jlSurfaceT *s, uint8_t bx, uint8_t by, uint8_t colorIndex); /* function override (planar) */ #else #define jlpTileFill(_s, _bx, _by, _c) jlpGenericTileFill((_s), (_bx), (_by), (_c)) #endif #endif void jlpGenericTileCopy(jlSurfaceT *dst, uint8_t dstBx, uint8_t dstBy, const jlSurfaceT *src, uint8_t srcBx, uint8_t srcBy); #if !defined(jlpTileCopy) #if defined(JL_HAS_TILE_COPY) void jlpTileCopy(jlSurfaceT *dst, uint8_t dstBx, uint8_t dstBy, const jlSurfaceT *src, uint8_t srcBx, uint8_t srcBy); #else #define jlpTileCopy(_d, _dbx, _dby, _s, _sbx, _sby) jlpGenericTileCopy((_d), (_dbx), (_dby), (_s), (_sbx), (_sby)) #endif #endif void jlpGenericTileCopyMasked(jlSurfaceT *dst, uint8_t dstBx, uint8_t dstBy, const jlSurfaceT *src, uint8_t srcBx, uint8_t srcBy, uint8_t transparent); #if !defined(jlpTileCopyMasked) #if defined(JL_HAS_TILE_COPY_MASKED) void jlpTileCopyMasked(jlSurfaceT *dst, uint8_t dstBx, uint8_t dstBy, const jlSurfaceT *src, uint8_t srcBx, uint8_t srcBy, uint8_t transparent); #else #define jlpTileCopyMasked(_d, _dbx, _dby, _s, _sbx, _sby, _t) jlpGenericTileCopyMasked((_d), (_dbx), (_dby), (_s), (_sbx), (_sby), (_t)) #endif #endif void jlpGenericTilePaste(jlSurfaceT *dst, uint8_t bx, uint8_t by, const uint8_t *chunkyTile); #if !defined(jlpTilePaste) #if defined(JL_HAS_TILE_PASTE) void jlpTilePaste(jlSurfaceT *dst, uint8_t bx, uint8_t by, const uint8_t *chunkyTile); #else #define jlpTilePaste(_d, _bx, _by, _ct) jlpGenericTilePaste((_d), (_bx), (_by), (_ct)) #endif #endif void jlpGenericTileSnap(const jlSurfaceT *src, uint8_t bx, uint8_t by, uint8_t *chunkyOut); #if !defined(jlpTileSnap) #if defined(JL_HAS_TILE_SNAP) void jlpTileSnap(const jlSurfaceT *src, uint8_t bx, uint8_t by, uint8_t *chunkyOut); #else #define jlpTileSnap(_s, _bx, _by, _out) jlpGenericTileSnap((_s), (_bx), (_by), (_out)) #endif #endif // tilePasteMono color-masking contract (PERF-AUDIT #69): fgColor/bgColor // arrive already masked to 4 bits -- the public jlTilePasteMono wrapper owns // the & 0x0F. Neither the generic nor a machine override may re-mask. // (tileFill is the opposite: its wrapper does NOT mask, so the jlp layer owns // the & 0x0F there -- see the IIgs macro above and the planar overrides.) void jlpGenericTilePasteMono(jlSurfaceT *dst, uint8_t bx, uint8_t by, const uint8_t *monoTile, uint8_t fgColor, uint8_t bgColor); #if !defined(jlpTilePasteMono) #if defined(JL_HAS_TILE_PASTE_MONO) void jlpTilePasteMono(jlSurfaceT *dst, uint8_t bx, uint8_t by, const uint8_t *monoTile, uint8_t fgColor, uint8_t bgColor); #else #define jlpTilePasteMono(_d, _bx, _by, _mt, _fg, _bg) jlpGenericTilePasteMono((_d), (_bx), (_by), (_mt), (_fg), (_bg)) #endif #endif void jlpGenericSpriteDrawPlanes(jlSurfaceT *s, const jlSpriteT *sp, int16_t x, int16_t y); #if !defined(jlpSpriteDrawPlanes) #if defined(JL_HAS_SPRITE_DRAW) void jlpSpriteDrawPlanes(jlSurfaceT *s, const jlSpriteT *sp, int16_t x, int16_t y); #else #define jlpSpriteDrawPlanes(_s, _sp, _x, _y) jlpGenericSpriteDrawPlanes((_s), (_sp), (_x), (_y)) #endif #endif void jlpGenericSpriteSavePlanes(const jlSurfaceT *s, int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t *dstPlaneBytes); #if !defined(jlpSpriteSavePlanes) #if defined(JL_HAS_SPRITE_SAVE) void jlpSpriteSavePlanes(const jlSurfaceT *s, int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t *dstPlaneBytes); #else #define jlpSpriteSavePlanes(_s, _x, _y, _w, _h, _dst) jlpGenericSpriteSavePlanes((_s), (_x), (_y), (_w), (_h), (_dst)) #endif #endif void jlpGenericSpriteRestorePlanes(jlSurfaceT *s, int16_t x, int16_t y, uint16_t w, uint16_t h, const uint8_t *srcPlaneBytes); #if !defined(jlpSpriteRestorePlanes) #if defined(JL_HAS_SPRITE_RESTORE) void jlpSpriteRestorePlanes(jlSurfaceT *s, int16_t x, int16_t y, uint16_t w, uint16_t h, const uint8_t *srcPlaneBytes); #else #define jlpSpriteRestorePlanes(_s, _x, _y, _w, _h, _src) jlpGenericSpriteRestorePlanes((_s), (_x), (_y), (_w), (_h), (_src)) #endif #endif // Flood ops (PATTERN B: no extractable generic -- the portable default is the // inline C scanline fallback in floodFillInternal, gated per-tier by // `#if defined(JL_HAS_FLOOD_*)` at the call site). Each real override is just a // prototype here for the claiming machine. jlpFloodWalkAndScans is a macro on // IIgs (defined above), so its `!defined` guard skips the proto there. #if defined(JL_HAS_FLOOD_WALK_AND_SCANS) && !defined(jlpFloodWalkAndScans) bool jlpFloodWalkAndScans(uint8_t *pixels, int16_t x, int16_t y, uint8_t matchColor, uint8_t newColor, bool matchEqual, int16_t *stackX, int16_t *stackY, int16_t *spInOut, int16_t maxSp, bool *seedMatched, int16_t *leftXOut, int16_t *rightXOut); #endif #if defined(JL_HAS_FLOOD_WALK_PLANES) && !defined(jlpFloodWalkPlanes) bool jlpFloodWalkPlanes(const jlSurfaceT *s, int16_t startX, int16_t y, uint8_t matchColor, uint8_t newColor, bool matchEqual, bool *seedMatched, int16_t *leftXOut, int16_t *rightXOut); #endif #if defined(JL_HAS_FLOOD_SCAN_ROW_PLANES) && !defined(jlpFloodScanRowPlanes) bool jlpFloodScanRowPlanes(const jlSurfaceT *s, int16_t leftX, int16_t rightX, int16_t scanY, uint8_t matchColor, uint8_t newColor, bool matchEqual, uint8_t *markBuf); #endif // ===================================================================== // Category B: structural port services (generic default + JL_HAS override). // // Unlike Category A accelerators these are resolved purely at link/compile // time (no runtime dispatch ever existed). Each op has a portable-C default in // src/generic/ -- a real implementation where one exists, or a no-op/zero stub // for inherently platform-specific services so a blank/template port still // links. A port that supplies its own version defines JL_HAS_ in // include/joey/platform.h. Same jlp stanza as Category A. // ===================================================================== // --- Generic-only surface services (no port overrides them today) --- void jlpGenericSurfaceCopyChunky(jlSurfaceT *dst, const jlSurfaceT *src); #if !defined(jlpSurfaceCopyChunky) #if defined(JL_HAS_SURFACE_COPY_CHUNKY) void jlpSurfaceCopyChunky(jlSurfaceT *dst, const jlSurfaceT *src); #else #define jlpSurfaceCopyChunky(_d, _s) jlpGenericSurfaceCopyChunky((_d), (_s)) #endif #endif // Same-position group-snapped rect copy (jlSurfaceCopyRect payload). // The generic body serves the chunky ports (incl. the IIgs stage -- // its pixels pointer reaches bank $01 through ordinary large-model // stores); the planar ports override with their plane-layout walks. void jlpGenericSurfaceCopyRect(jlSurfaceT *dst, const jlSurfaceT *src, uint16_t x, uint16_t y, uint16_t w, uint16_t h); #if !defined(jlpSurfaceCopyRect) #if defined(JL_HAS_SURFACE_COPY_RECT) void jlpSurfaceCopyRect(jlSurfaceT *dst, const jlSurfaceT *src, uint16_t x, uint16_t y, uint16_t w, uint16_t h); #else #define jlpSurfaceCopyRect(_d, _s, _x, _y, _w, _h) jlpGenericSurfaceCopyRect((_d), (_s), (_x), (_y), (_w), (_h)) #endif #endif void jlpGenericSurfaceFreePixels(uint8_t *pixels); #if !defined(jlpSurfaceFreePixels) #if defined(JL_HAS_SURFACE_FREE_PIXELS) void jlpSurfaceFreePixels(uint8_t *pixels); #else #define jlpSurfaceFreePixels(_p) jlpGenericSurfaceFreePixels((_p)) #endif #endif const char *jlpGenericLastError(void); #if !defined(jlpLastError) #if defined(JL_HAS_LAST_ERROR) const char *jlpLastError(void); #else #define jlpLastError() jlpGenericLastError() #endif #endif // --- Planar dual-write hook (no-op generic default; planar ports override) --- void jlpGenericSurfaceCopyPlanes(jlSurfaceT *dst, const jlSurfaceT *src); #if !defined(jlpSurfaceCopyPlanes) #if defined(JL_HAS_SURFACE_COPY_PLANES) void jlpSurfaceCopyPlanes(jlSurfaceT *dst, const jlSurfaceT *src); #else #define jlpSurfaceCopyPlanes(_d, _s) jlpGenericSurfaceCopyPlanes((_d), (_s)) #endif #endif // --- Surface readers (chunky generic default; planar ports decode portData) --- uint8_t jlpGenericSamplePixel(const jlSurfaceT *s, int16_t x, int16_t y); #if !defined(jlpSamplePixel) #if defined(JL_HAS_SAMPLE_PIXEL) uint8_t jlpSamplePixel(const jlSurfaceT *s, int16_t x, int16_t y); #else #define jlpSamplePixel(_s, _x, _y) jlpGenericSamplePixel((_s), (_x), (_y)) #endif #endif uint32_t jlpGenericSurfaceHash(const jlSurfaceT *s); #if !defined(jlpSurfaceHash) #if defined(JL_HAS_SURFACE_HASH) uint32_t jlpSurfaceHash(const jlSurfaceT *s); #else #define jlpSurfaceHash(_s) jlpGenericSurfaceHash((_s)) #endif #endif bool jlpGenericSurfaceLoadFile(jlSurfaceT *dst, FILE *fp); #if !defined(jlpSurfaceLoadFile) #if defined(JL_HAS_SURFACE_LOAD_FILE) bool jlpSurfaceLoadFile(jlSurfaceT *dst, FILE *fp); #else #define jlpSurfaceLoadFile(_d, _fp) jlpGenericSurfaceLoadFile((_d), (_fp)) #endif #endif bool jlpGenericSurfaceSaveFile(const jlSurfaceT *src, FILE *fp); #if !defined(jlpSurfaceSaveFile) #if defined(JL_HAS_SURFACE_SAVE_FILE) bool jlpSurfaceSaveFile(const jlSurfaceT *src, FILE *fp); #else #define jlpSurfaceSaveFile(_s, _fp) jlpGenericSurfaceSaveFile((_s), (_fp)) #endif #endif // --- Allocation ops (chunky generic defaults; planar/pinned overrides) --- uint8_t *jlpGenericStageAllocPixels(void); #if !defined(jlpStageAllocPixels) #if defined(JL_HAS_STAGE_ALLOC_PIXELS) uint8_t *jlpStageAllocPixels(void); #else #define jlpStageAllocPixels() jlpGenericStageAllocPixels() #endif #endif void jlpGenericStageFreePixels(uint8_t *pixels); #if !defined(jlpStageFreePixels) #if defined(JL_HAS_STAGE_FREE_PIXELS) void jlpStageFreePixels(uint8_t *pixels); #else #define jlpStageFreePixels(_p) jlpGenericStageFreePixels((_p)) #endif #endif uint8_t *jlpGenericSurfaceAllocPixels(void); #if !defined(jlpSurfaceAllocPixels) #if defined(JL_HAS_SURFACE_ALLOC_PIXELS) uint8_t *jlpSurfaceAllocPixels(void); #else #define jlpSurfaceAllocPixels() jlpGenericSurfaceAllocPixels() #endif #endif void *jlpGenericSurfaceAllocPortData(jlSurfaceT *s, bool isStage); #if !defined(jlpSurfaceAllocPortData) #if defined(JL_HAS_SURFACE_ALLOC_PORT_DATA) void *jlpSurfaceAllocPortData(jlSurfaceT *s, bool isStage); #else #define jlpSurfaceAllocPortData(_s, _st) jlpGenericSurfaceAllocPortData((_s), (_st)) #endif #endif void jlpGenericSurfaceFreePortData(jlSurfaceT *s, bool isStage, void *portData); #if !defined(jlpSurfaceFreePortData) #if defined(JL_HAS_SURFACE_FREE_PORT_DATA) void jlpSurfaceFreePortData(jlSurfaceT *s, bool isStage, void *portData); #else #define jlpSurfaceFreePortData(_s, _st, _pd) jlpGenericSurfaceFreePortData((_s), (_st), (_pd)) #endif #endif // (jlpSurfacePlanePtr was retired in NATIVE-PERF Phase 2: its only // callers were spriteCompile.c's 68k dispatchers, which now read // portData directly via the inline accessors in amigaPlanar.h / // stPlanar.h instead of paying a cross-TU call per plane.) // --- Timing services (platform-only stub generics; millisElapsed has a real default) --- uint16_t jlpGenericFrameHz(void); #if !defined(jlpFrameHz) #if defined(JL_HAS_FRAME_HZ) uint16_t jlpFrameHz(void); #else #define jlpFrameHz() jlpGenericFrameHz() #endif #endif uint16_t jlpGenericFrameCount(void); #if !defined(jlpFrameCount) #if defined(JL_HAS_FRAME_COUNT) uint16_t jlpFrameCount(void); #else #define jlpFrameCount() jlpGenericFrameCount() #endif #endif void jlpGenericWaitVBL(void); #if !defined(jlpWaitVBL) #if defined(JL_HAS_WAIT_VBL) void jlpWaitVBL(void); #else #define jlpWaitVBL() jlpGenericWaitVBL() #endif #endif uint32_t jlpGenericMillisElapsed(void); #if !defined(jlpMillisElapsed) #if defined(JL_HAS_MILLIS_ELAPSED) uint32_t jlpMillisElapsed(void); #else #define jlpMillisElapsed() jlpGenericMillisElapsed() #endif #endif // --- Audio services (platform-only; blank-port stub generic + JL_HAS override) --- bool jlpGenericAudioInit(void); #if !defined(jlpAudioInit) #if defined(JL_HAS_AUDIO_INIT) bool jlpAudioInit(void); #else #define jlpAudioInit() jlpGenericAudioInit() #endif #endif void jlpGenericAudioShutdown(void); #if !defined(jlpAudioShutdown) #if defined(JL_HAS_AUDIO_SHUTDOWN) void jlpAudioShutdown(void); #else #define jlpAudioShutdown() jlpGenericAudioShutdown() #endif #endif void jlpGenericAudioPlayMod(const uint8_t *data, uint32_t length, bool loop); #if !defined(jlpAudioPlayMod) #if defined(JL_HAS_AUDIO_PLAY_MOD) void jlpAudioPlayMod(const uint8_t *data, uint32_t length, bool loop); #else #define jlpAudioPlayMod(_a, _b, _c) jlpGenericAudioPlayMod((_a), (_b), (_c)) #endif #endif void jlpGenericAudioStopMod(void); #if !defined(jlpAudioStopMod) #if defined(JL_HAS_AUDIO_STOP_MOD) void jlpAudioStopMod(void); #else #define jlpAudioStopMod() jlpGenericAudioStopMod() #endif #endif bool jlpGenericAudioIsPlayingMod(void); #if !defined(jlpAudioIsPlayingMod) #if defined(JL_HAS_AUDIO_IS_PLAYING_MOD) bool jlpAudioIsPlayingMod(void); #else #define jlpAudioIsPlayingMod() jlpGenericAudioIsPlayingMod() #endif #endif void jlpGenericAudioPlaySfx(uint8_t slot, const uint8_t *sample, uint32_t length, uint16_t rateHz); #if !defined(jlpAudioPlaySfx) #if defined(JL_HAS_AUDIO_PLAY_SFX) void jlpAudioPlaySfx(uint8_t slot, const uint8_t *sample, uint32_t length, uint16_t rateHz); #else #define jlpAudioPlaySfx(_a, _b, _c, _d) jlpGenericAudioPlaySfx((_a), (_b), (_c), (_d)) #endif #endif void jlpGenericAudioPlaySfxStream(uint8_t slot, jlAudioStreamFillT fill, void *ctx, uint16_t rateHz); #if !defined(jlpAudioPlaySfxStream) #if defined(JL_HAS_AUDIO_PLAY_SFX_STREAM) void jlpAudioPlaySfxStream(uint8_t slot, jlAudioStreamFillT fill, void *ctx, uint16_t rateHz); #else #define jlpAudioPlaySfxStream(_a, _b, _c, _d) jlpGenericAudioPlaySfxStream((_a), (_b), (_c), (_d)) #endif #endif void jlpGenericAudioStopSfx(uint8_t slot); #if !defined(jlpAudioStopSfx) #if defined(JL_HAS_AUDIO_STOP_SFX) void jlpAudioStopSfx(uint8_t slot); #else #define jlpAudioStopSfx(_a) jlpGenericAudioStopSfx((_a)) #endif #endif void jlpGenericAudioTone(uint16_t freqHz); #if !defined(jlpAudioTone) #if defined(JL_HAS_AUDIO_TONE) void jlpAudioTone(uint16_t freqHz); #else #define jlpAudioTone(_a) jlpGenericAudioTone((_a)) #endif #endif void jlpGenericAudioVoice(uint8_t voice, uint16_t freqHz, uint8_t atten); #if !defined(jlpAudioVoice) #if defined(JL_HAS_AUDIO_VOICE) void jlpAudioVoice(uint8_t voice, uint16_t freqHz, uint8_t atten); #else #define jlpAudioVoice(_a, _b, _c) jlpGenericAudioVoice((_a), (_b), (_c)) #endif #endif void jlpGenericAudioNoise(uint8_t pitch, uint8_t atten); #if !defined(jlpAudioNoise) #if defined(JL_HAS_AUDIO_NOISE) void jlpAudioNoise(uint8_t pitch, uint8_t atten); #else #define jlpAudioNoise(_a, _b) jlpGenericAudioNoise((_a), (_b)) #endif #endif bool jlpGenericAudioTickRegister(jlAudioTickFnT fn, uint16_t hz); #if !defined(jlpAudioTickRegister) #if defined(JL_HAS_AUDIO_TICK_REGISTER) bool jlpAudioTickRegister(jlAudioTickFnT fn, uint16_t hz); #else #define jlpAudioTickRegister(_a, _b) jlpGenericAudioTickRegister((_a), (_b)) #endif #endif void jlpGenericAudioCriticalEnter(void); #if !defined(jlpAudioCriticalEnter) #if defined(JL_HAS_AUDIO_CRITICAL_ENTER) void jlpAudioCriticalEnter(void); #else #define jlpAudioCriticalEnter() jlpGenericAudioCriticalEnter() #endif #endif void jlpGenericAudioCriticalExit(void); #if !defined(jlpAudioCriticalExit) #if defined(JL_HAS_AUDIO_CRITICAL_EXIT) void jlpAudioCriticalExit(void); #else #define jlpAudioCriticalExit() jlpGenericAudioCriticalExit() #endif #endif void jlpGenericAudioFrameTick(void); #if !defined(jlpAudioFrameTick) #if defined(JL_HAS_AUDIO_FRAME_TICK) void jlpAudioFrameTick(void); #else #define jlpAudioFrameTick() jlpGenericAudioFrameTick() #endif #endif // --- Lifecycle / present / input (platform-only; blank stub generic + JL_HAS) --- bool jlpGenericInit(const jlConfigT *config); #if !defined(jlpInit) #if defined(JL_HAS_INIT) bool jlpInit(const jlConfigT *config); #else #define jlpInit(_a) jlpGenericInit((_a)) #endif #endif void jlpGenericShutdown(void); #if !defined(jlpShutdown) #if defined(JL_HAS_SHUTDOWN) void jlpShutdown(void); #else #define jlpShutdown() jlpGenericShutdown() #endif #endif void jlpGenericPresent(const jlSurfaceT *src); #if !defined(jlpPresent) #if defined(JL_HAS_PRESENT) void jlpPresent(const jlSurfaceT *src); #else #define jlpPresent(_a) jlpGenericPresent((_a)) #endif #endif void jlpGenericInputInit(void); #if !defined(jlpInputInit) #if defined(JL_HAS_INPUT_INIT) void jlpInputInit(void); #else #define jlpInputInit() jlpGenericInputInit() #endif #endif void jlpGenericInputShutdown(void); #if !defined(jlpInputShutdown) #if defined(JL_HAS_INPUT_SHUTDOWN) void jlpInputShutdown(void); #else #define jlpInputShutdown() jlpGenericInputShutdown() #endif #endif void jlpGenericInputPoll(void); #if !defined(jlpInputPoll) #if defined(JL_HAS_INPUT_POLL) void jlpInputPoll(void); #else #define jlpInputPoll() jlpGenericInputPoll() #endif #endif void jlpGenericJoystickReset(jlJoystickE js); #if !defined(jlpJoystickReset) #if defined(JL_HAS_JOYSTICK_RESET) void jlpJoystickReset(jlJoystickE js); #else #define jlpJoystickReset(_a) jlpGenericJoystickReset((_a)) #endif #endif // --- Serial add-on (platform-only; blank-port stub generic + JL_HAS override) --- // Function overrides (not IIgs asm macros), so no entry in the macro-consistency // #error block above. Types come from joey/serial.h (included at the top). bool jlpGenericSerialOpen(jlSerialDeviceE device, const jlSerialConfigT *config); #if !defined(jlpSerialOpen) #if defined(JL_HAS_SERIAL_OPEN) bool jlpSerialOpen(jlSerialDeviceE device, const jlSerialConfigT *config); #else #define jlpSerialOpen(_d, _c) jlpGenericSerialOpen((_d), (_c)) #endif #endif void jlpGenericSerialClose(void); #if !defined(jlpSerialClose) #if defined(JL_HAS_SERIAL_CLOSE) void jlpSerialClose(void); #else #define jlpSerialClose() jlpGenericSerialClose() #endif #endif void jlpGenericSerialPoll(void); #if !defined(jlpSerialPoll) #if defined(JL_HAS_SERIAL_POLL) void jlpSerialPoll(void); #else #define jlpSerialPoll() jlpGenericSerialPoll() #endif #endif uint16_t jlpGenericSerialAvailable(void); #if !defined(jlpSerialAvailable) #if defined(JL_HAS_SERIAL_AVAILABLE) uint16_t jlpSerialAvailable(void); #else #define jlpSerialAvailable() jlpGenericSerialAvailable() #endif #endif uint16_t jlpGenericSerialRead(uint8_t *buf, uint16_t max); #if !defined(jlpSerialRead) #if defined(JL_HAS_SERIAL_READ) uint16_t jlpSerialRead(uint8_t *buf, uint16_t max); #else #define jlpSerialRead(_b, _m) jlpGenericSerialRead((_b), (_m)) #endif #endif uint16_t jlpGenericSerialWrite(const uint8_t *buf, uint16_t len); #if !defined(jlpSerialWrite) #if defined(JL_HAS_SERIAL_WRITE) uint16_t jlpSerialWrite(const uint8_t *buf, uint16_t len); #else #define jlpSerialWrite(_b, _l) jlpGenericSerialWrite((_b), (_l)) #endif #endif void jlpGenericSerialFlush(void); #if !defined(jlpSerialFlush) #if defined(JL_HAS_SERIAL_FLUSH) void jlpSerialFlush(void); #else #define jlpSerialFlush() jlpGenericSerialFlush() #endif #endif // --- Save files + disk space (platform-only; blank-port stub generic + JL_HAS override) --- // Function overrides (not IIgs asm macros), so no entry in the macro-consistency // #error block above. Core layer is src/core/save.c; publics in joey/file.h. bool jlpGenericSaveDirEnsure(const char *dir); #if !defined(jlpSaveDirEnsure) #if defined(JL_HAS_SAVE_DIR_ENSURE) bool jlpSaveDirEnsure(const char *dir); #else #define jlpSaveDirEnsure(_d) jlpGenericSaveDirEnsure((_d)) #endif #endif bool jlpGenericSaveDelete(const char *path); #if !defined(jlpSaveDelete) #if defined(JL_HAS_SAVE_DELETE) bool jlpSaveDelete(const char *path); #else #define jlpSaveDelete(_p) jlpGenericSaveDelete((_p)) #endif #endif uint32_t jlpGenericDiskFree(void); #if !defined(jlpDiskFree) #if defined(JL_HAS_DISK_FREE) uint32_t jlpDiskFree(void); #else #define jlpDiskFree() jlpGenericDiskFree() #endif #endif // --- Large allocation (malloc/free generic default; IIgs Memory Manager override) --- void *jlpGenericBigAlloc(uint32_t bytes); void jlpGenericBigFree(void *p); #if !defined(jlpBigAlloc) #if defined(JL_HAS_BIG_ALLOC) void *jlpBigAlloc(uint32_t bytes); void jlpBigFree(void *p); #else #define jlpBigAlloc(_b) jlpGenericBigAlloc((_b)) #define jlpBigFree(_p) jlpGenericBigFree((_p)) #endif #endif // Per-port tile-op inline bodies (see the alias block above the // dispatch tail). The 68k headers are included LAST so their // portData == NULL fallbacks can call the jlpGenericTile* prototypes // declared above; the DOS header (whole-map engine only, W3) needs // nothing from the tail but sits here for the same one-include-point. #if defined(JOEYLIB_PLATFORM_ATARIST) #include "stTile.h" #elif defined(JOEYLIB_PLATFORM_AMIGA) #include "amigaTile.h" #elif defined(JOEYLIB_PLATFORM_DOS) #include "dosTile.h" #elif defined(JOEYLIB_PLATFORM_X68000) #include "x68kTile.h" #endif #endif