== Getting Started === Setting Up the Toolchains JoeyLib cross-compiles for five machines, and every cross toolchain lives under `toolchains/` in the repository. They are fetched and built once: [source,console] ---- $ ./toolchains/install.sh ---- Then, *in every shell session before you build anything*: [source,console] ---- $ source toolchains/env.sh ---- [WARNING] ==== Forgetting `source toolchains/env.sh` is the single most common build problem. The makefiles reference the cross compilers only through the variables that script sets, so without it a build can appear to succeed while producing stale or missing binaries, and errors are reported as `Error 127 (ignored)`. If a build behaves strangely, source the script and try again. ==== Check what the build can see: [source,console] ---- $ make status Toolchain availability: iigs: yes amiga: yes atarist: yes dos: yes ---- === Building [source,console] ---- $ make # every target whose toolchain is present $ make iigs # Apple IIgs only $ make amiga # Commodore Amiga only $ make atarist # Atari ST only $ make dos # MS-DOS only $ make clean # remove all build outputs ---- The X68000 port has its own makefile: [source,console] ---- $ make -f make/x68000.mk ---- Built programs land under `build//bin/`. The IIgs additionally produces a bootable disk image: [source,console] ---- $ make iigs-disk # build/iigs/bin/joey.2mg ---- [TIP] ==== Never judge a retro build by its exit status alone. Check that the file you expect actually appeared and has a recent timestamp. `make iigs` builds the library but *no examples* -- `make iigs-disk` is what builds and packages them. ==== === Hello, JoeyLib The smallest complete program. This is `examples/hello/hello.c`: [source,c] ---- #include #include int main(void) { jlConfigT config; config.codegenBytes = 8 * 1024; config.audioBytes = 64UL * 1024; if (!jlInit(&config)) { fprintf(stderr, "jlInit failed: %s\n", jlLastError()); return 1; } printf("JoeyLib %s\n", jlVersionString()); printf("Platform: %s\n", jlPlatformName()); printf("Hello from JoeyLib.\n"); jlShutdown(); return 0; } ---- Three things to notice, because they apply to every JoeyLib program: . *One header.* `#include ` pulls in everything except the optional serial add-on. . *`jlInit` can fail*, and when it does `jlLastError()` tells you why. Always check it. . *`jlShutdown` is not optional.* It restores the display mode, releases the Memory Manager blocks or DOS memory the library took, and on several ports un-hooks interrupt vectors. Skipping it can leave the machine in an unusable state. === Something on the Screen `hello.c` prints text but never draws. Here is the smallest program that puts graphics on screen and waits for a keypress: [source,c] ---- #include int main(void) { jlConfigT config; jlSurfaceT *stage; uint16_t colors[SURFACE_COLORS_PER_PALETTE]; uint8_t i; config.codegenBytes = 8 * 1024; config.audioBytes = 0; if (!jlInit(&config)) { return 1; } stage = jlStageGet(); // the library-owned back buffer // Build palette 0. Entry 0 is forced black whatever we put here. for (i = 0; i < SURFACE_COLORS_PER_PALETTE; i++) { colors[i] = 0x000; } colors[1] = 0xFFF; // white colors[2] = 0xF00; // red colors[3] = 0x00F; // blue jlPaletteSet(stage, 0, colors); // Every scanline uses palette 0 (this is also the default). jlScbSetRange(stage, 0, SURFACE_HEIGHT - 1, 0); jlSurfaceClear(stage, 0); jlFillRect(stage, 40, 30, 240, 140, 3); jlDrawRect(stage, 40, 30, 240, 140, 1); jlDrawLine(stage, 0, 0, SURFACE_WIDTH - 1, SURFACE_HEIGHT - 1, 2); jlStagePresent(); // nothing is visible until this runs jlWaitForAnyKey(); jlShutdown(); return 0; } ---- The critical line is `jlStagePresent()`. All drawing goes to an off-screen back buffer called the *stage*; nothing reaches the display until you present. === Running What You Built Helper scripts boot each target in an emulator: [source,console] ---- $ scripts/run-iigs.sh DRAW $ scripts/run-amiga.sh Draw $ scripts/run-atarist.sh DRAW $ scripts/run-dos.sh DRAW $ scripts/run-x68000.sh DRAW ---- Note the capitalisation differences: the IIgs, ST and DOS use uppercase names (ProDOS, GEMDOS and DOS 8.3 conventions), while the Amiga keeps mixed case. === The Example Programs The `examples/` directory is the best available reference, and every example is built for every platform: [cols="1,4", options="header"] |=== |Example |What it shows |`hello` |Minimal init, version query, shutdown. |`draw` |Every drawing primitive, laid out in four quadrants. |`pattern` |Palette and per-scanline palette (SCB) work. |`keys` |Typed-character input and the key predicates. |`joy` |Joystick axes, buttons and recalibration. |`sprite` |Sprite loading, compiling, save-under and restore. |`audio` |Tracker music, `.MOD` playback and digital sound effects. |`save` |Save files and the disk-space query. |`serial` |The optional RS-232 add-on. |`adventure` |A small complete game. |`agi` |A Sierra AGI interpreter, showing the library under real load. |`spacetaxi` |A full port of Space Taxi: the largest example. |`uber` |The validation and benchmark harness. |===