190 lines
5.7 KiB
Text
190 lines
5.7 KiB
Text
== Adding Your Program to the Build
|
|
|
|
JoeyLib does not install as a system library. Programs are built from inside
|
|
the repository by the same makefiles that build the library, because each
|
|
target needs its own cross compiler, link script, packaging step and disk
|
|
image. Adding a program means adding it to each port's makefile.
|
|
|
|
=== The Shape of a Program Directory
|
|
|
|
Put your sources under `examples/`, one directory per program:
|
|
|
|
----
|
|
examples/mygame/
|
|
mygame.c
|
|
mygame.h
|
|
assets/
|
|
tiles.png
|
|
sprites.png
|
|
music.song
|
|
----
|
|
|
|
Keep the authoring assets next to the code and let the makefiles bake them into
|
|
`DATA/`, as described in <<_creating_assets>>.
|
|
|
|
=== Adding It to One Port
|
|
|
|
Each port's makefile declares programs explicitly. The pattern in
|
|
`make/atarist.mk`, for a single-source program:
|
|
|
|
[source,makefile]
|
|
----
|
|
MYGAME_SRC := $(EXAMPLES)/mygame/mygame.c
|
|
MYGAME_BIN := $(BINDIR)/MYGAME.PRG
|
|
----
|
|
|
|
Add the binary to the port's `all` target so it gets built:
|
|
|
|
[source,makefile]
|
|
----
|
|
all atarist: $(LIB) ... $(MYGAME_BIN) $(DATA_FILES)
|
|
----
|
|
|
|
And give it a build rule, copying the shape of an existing example in that
|
|
file. Do not invent your own compiler invocation: the flags, include paths and
|
|
link order in those rules encode real constraints, several of them the result
|
|
of long debugging.
|
|
|
|
For a multi-file program, list the sources:
|
|
|
|
[source,makefile]
|
|
----
|
|
MYGAME_SRCS := $(EXAMPLES)/mygame/mygame.c \
|
|
$(EXAMPLES)/mygame/world.c \
|
|
$(EXAMPLES)/mygame/render.c
|
|
----
|
|
|
|
Repeat for each port you want to support: `make/iigs.mk`, `make/amiga.mk`,
|
|
`make/atarist.mk`, `make/dos.mk` and `make/x68000.mk`.
|
|
|
|
[NOTE]
|
|
====
|
|
Yes, that is five makefile edits for one program. The ports genuinely differ:
|
|
the IIgs needs OMF segmentation and a disk image, the Amiga a startup-sequence
|
|
entry, DOS a DPMI stub, and the X68000 a Human68k floppy layout. There is no
|
|
single rule that covers all five.
|
|
====
|
|
|
|
=== Naming
|
|
|
|
File naming conventions differ per platform and the makefiles reflect that:
|
|
|
|
[cols="2,2,4", options="header"]
|
|
|===
|
|
|Platform |Convention |Example
|
|
|
|
|Apple IIgs |Uppercase, 8 characters |`MYGAME`
|
|
|Atari ST |Uppercase 8.3, `.PRG` |`MYGAME.PRG`
|
|
|MS-DOS |Uppercase 8.3, `.EXE` |`MYGAME.EXE`
|
|
|Amiga |Mixed case, no extension |`MyGame`
|
|
|Sharp X68000 |Uppercase 8.3, `.X` |`MYGAME.X`
|
|
|===
|
|
|
|
Keep the base name to 8 characters and letters and digits only, so the same
|
|
name works everywhere.
|
|
|
|
=== Disk Images and Packaging
|
|
|
|
Some ports need a packaging step beyond compiling.
|
|
|
|
*Apple IIgs.* Programs are placed on an 800 KB ProDOS disk image:
|
|
|
|
[source,console]
|
|
----
|
|
$ make iigs-disk
|
|
$ JOEY_DISK_EXAMPLES="MYGAME" make iigs-disk # just yours
|
|
----
|
|
|
|
The floppy cannot hold every example at once, so the packager drops some. If
|
|
your program is missing from the image, build it with `JOEY_DISK_EXAMPLES`
|
|
naming it explicitly, and check the `added:` line the packager prints. A
|
|
program plus large assets may not fit 800 KB at all, in which case use the
|
|
bigger game-disk image on a CFFA2 card:
|
|
|
|
[source,console]
|
|
----
|
|
$ JOEY_GAME_DISK_SIZE=2048KB scripts/make-iigs-game-disk.sh \
|
|
build/iigs/bin/mygame.2mg MYGAME
|
|
----
|
|
|
|
*Sharp X68000.* Programs ship on a Human68k floppy. Be aware that a stale image
|
|
can hide hundreds of kilobytes in subdirectories that a directory listing does
|
|
not show; rebuild from empty rather than deleting files if space seems to
|
|
vanish.
|
|
|
|
*Amiga.* `joey-run` writes an `s/startup-sequence` that invokes your binary.
|
|
|
|
=== Verifying It Actually Runs
|
|
|
|
Build success is weak evidence on retro targets. Run it with `joey-run` (see
|
|
<<Running What You Built>>), on every machine:
|
|
|
|
[source,console]
|
|
----
|
|
$ ./joey-run --port iigs mygame
|
|
$ ./joey-run --port amiga mygame
|
|
$ ./joey-run --port atarist mygame
|
|
$ ./joey-run --port dos mygame
|
|
$ ./joey-run --port x68000 mygame
|
|
----
|
|
|
|
Without a window, which is what you want while iterating, run it headless and
|
|
look at the snapshot; the program's log lands next to it as usual:
|
|
|
|
[source,console]
|
|
----
|
|
$ ./joey-run --headless --seconds 90 --snapshot mygame.png --port atarist mygame
|
|
----
|
|
|
|
=== The Gates
|
|
|
|
The repository carries automated checks. They exist because several classes of
|
|
bug on these machines are invisible until measured, and they are worth running
|
|
against your own program too.
|
|
|
|
[cols="2,4", options="header"]
|
|
|===
|
|
|Command |What it proves
|
|
|
|
|`make verify-audio`
|
|
|Every port's audio gate: the IIgs DOC and X68000 chips are read directly,
|
|
the ST's YM2149 register writes are traced, and the Amiga and DOS output is
|
|
recorded and graded. Exits 3, not 0, if a gate had to be skipped.
|
|
|
|
|`make iigs-verify`
|
|
|The IIgs actually reached the program and drew something.
|
|
|
|
|`scripts/bench-<port>.sh`
|
|
|Per-operation throughput for that port.
|
|
|
|
|`tools/diff-uber-hashes`
|
|
|Compares a port's rendered output against the IIgs golden reference,
|
|
operation by operation, by surface hash.
|
|
|===
|
|
|
|
That last one is the strongest tool in the repository. `jlSurfaceHash` produces
|
|
the same value for the same logical pixels on every platform regardless of
|
|
internal storage format, so a hash mismatch means one port is genuinely drawing
|
|
different pixels from the others.
|
|
|
|
=== Logging from the Target
|
|
|
|
Debugging a program running on an emulated 1988 machine is awkward. JoeyLib
|
|
provides a logger that writes to a file next to the executable:
|
|
|
|
[source,c]
|
|
----
|
|
jlLogReset();
|
|
jlLogF("level %d loaded, %u cels", levelNum, celCount);
|
|
jlLogFlush();
|
|
----
|
|
|
|
The headless runners retrieve that file automatically.
|
|
|
|
[NOTE]
|
|
====
|
|
The logger needs a multi-kilobyte ring buffer, which some targets cannot
|
|
afford. Space Taxi compiles it out entirely on the IIgs and X68000 for that
|
|
reason. If you are debugging a memory-tight program, expect to do the same, and
|
|
fall back to observing hardware state through an emulator instead.
|
|
====
|