joeylib2/make/amiga.mk

251 lines
10 KiB
Makefile

# Amiga (Bebbo m68k-amigaos-gcc) build rules.
include $(dir $(lastword $(MAKEFILE_LIST)))/common.mk
PLATFORM := amiga
BUILD := $(REPO_DIR)/build/$(PLATFORM)
LIBDIR := $(BUILD)/lib
BINDIR := $(BUILD)/bin
# PTPlayer is staged by toolchains/install.sh into PTPLAYER_DIR; we
# reference its ptplayer.asm + header from there rather than copying
# them into the source tree, so install.sh can refresh / version it
# independently. -I on $(SRC_PORT)/amiga lets ptplayer.h resolve
# <SDI_compiler.h> from the port-local shim alongside our HAL code.
PTPLAYER_DIR := $(REPO_DIR)/toolchains/amiga/ptplayer
CFLAGS := $(COMMON_CFLAGS) -m68000 -fomit-frame-pointer -noixemul -D__OSCOMPAT -I$(SRC_PORT)/amiga -I$(SRC_68K) -I$(PTPLAYER_DIR) -MMD -MP $(CFLAGS_EXTRA)
# OSCOMPAT=1 selects PTPlayer's audio.device-friendly variant (uses
# CIA-B + audio.device interrupts via the OS rather than taking over
# Paula directly), matching the way our HAL cooperates with Intuition.
# vasm is only invoked for ptplayer.asm here -- Frank Wille's source
# is written in Devpac/vasm syntax and there is no maintained GAS-
# syntax port. JoeyLib's own .s files are GAS syntax and assembled by
# the bundled m68k-amigaos-as via the gcc driver.
# -Fhunk matches Bebbo gcc-amigaos's AmigaOS HUNK object format. ELF
# objects from vasm cannot be linked into a HUNK libjoey.a (the ar
# "file format not recognized" failure mode is silent at archive time
# and surfaces as undefined references at every binary's link step).
PTPLAYER_ASFLAGS := -Fhunk -m68000 -quiet -DOSCOMPAT=1
# --allow-multiple-definition lets our user-space tzset stub
# (src/port/amiga/libinit.c) win over libnix's version in
# __gmtoffset.o. libnix's tzset dereferences a possibly-NULL
# LocaleBase; our no-op skips the deref.
LDFLAGS := -noixemul -Wl,--allow-multiple-definition
PORT_C_SRCS := $(wildcard $(SRC_PORT)/amiga/*.c)
PORT_S_SRCS := $(wildcard $(SRC_PORT)/amiga/*.s)
SHARED_S := $(wildcard $(SRC_68K)/*.s)
# Amiga uses PTPlayer's mt_playfx for SFX, not the libxmp+overlay
# combo that DOS and ST share, so the shared SFX overlay mixer in
# src/core/audioSfxMix.c is unused here. Filter it out to keep dead
# code out of every Amiga binary.
CORE_C_SRCS_AMIGA := $(filter-out %/audioSfxMix.c, $(CORE_C_SRCS))
# Sprite codegen: 68k emitter shared with the ST port.
CODEGEN_DIR := $(REPO_DIR)/src/codegen
LIB_OBJS := \
$(patsubst $(SRC_CORE)/%.c,$(BUILD)/obj/core/%.o,$(CORE_C_SRCS_AMIGA)) \
$(patsubst $(SRC_PORT)/amiga/%.c,$(BUILD)/obj/port/%.o,$(PORT_C_SRCS)) \
$(patsubst $(SRC_PORT)/amiga/%.s,$(BUILD)/obj/port/%.o,$(PORT_S_SRCS)) \
$(patsubst $(SRC_68K)/%.s,$(BUILD)/obj/68k/%.o,$(SHARED_S)) \
$(BUILD)/obj/port/ptplayer.o \
$(BUILD)/obj/codegen/spriteEmit68k.o \
$(BUILD)/obj/codegen/spriteEmitPlanar68k.o \
$(BUILD)/obj/codegen/spriteCompile.o
LIB := $(LIBDIR)/libjoey.a
HELLO_SRC := $(EXAMPLES)/hello/hello.c
HELLO_BIN := $(BINDIR)/Hello
PATTERN_SRC := $(EXAMPLES)/pattern/pattern.c
PATTERN_BIN := $(BINDIR)/Pattern
DRAW_SRC := $(EXAMPLES)/draw/draw.c
DRAW_BIN := $(BINDIR)/Draw
KEYS_SRC := $(EXAMPLES)/keys/keys.c
KEYS_BIN := $(BINDIR)/Keys
JOY_SRC := $(EXAMPLES)/joy/joy.c
JOY_BIN := $(BINDIR)/Joy
SPRITE_SRC := $(EXAMPLES)/sprite/sprite.c
SPRITE_BIN := $(BINDIR)/Sprite
AUDIO_SRC := $(EXAMPLES)/audio/audio.c
AUDIO_BIN := $(BINDIR)/Audio
UBER_SRC := $(EXAMPLES)/uber/uber.c
UBER_BIN := $(BINDIR)/Uber
ADV_SRC := $(EXAMPLES)/adventure/adventure.c
ADV_BIN := $(BINDIR)/Adv
ADV2_SRC := $(EXAMPLES)/adventure2/adventure2.c
ADV2_BIN := $(BINDIR)/Adv2
AGI_SRCS := $(EXAMPLES)/agi/agi.c $(EXAMPLES)/agi/agiRes.c $(EXAMPLES)/agi/agiPic.c $(EXAMPLES)/agi/agiView.c $(EXAMPLES)/agi/agiVm.c $(EXAMPLES)/agi/agiObj.c $(EXAMPLES)/agi/agiText.c
AGI_BIN := $(BINDIR)/Agi
STAXI_SRCS := $(EXAMPLES)/spacetaxi/spacetaxi.c $(EXAMPLES)/spacetaxi/stLevel.c $(EXAMPLES)/spacetaxi/stRender.c $(EXAMPLES)/spacetaxi/stEngine.c $(EXAMPLES)/spacetaxi/stPassenger.c $(EXAMPLES)/spacetaxi/stHud.c $(EXAMPLES)/spacetaxi/stAudio.c
STAXI_INSTALL_DIR := $(BINDIR)/Taxi
STAXI_BIN := $(STAXI_INSTALL_DIR)/Taxi
# Space Taxi asset staging: same pattern as the DOS port -- sources
# under examples/spacetaxi/assets, generated artifacts under
# examples/spacetaxi/generated (nukeable), runtime tree under
# bin/assets/. Mirrors the dos.mk wiring exactly.
STAXI_SRC_DIR := $(EXAMPLES)/spacetaxi/assets
STAXI_GEN_DIR := $(EXAMPLES)/spacetaxi/generated/amiga
STAXI_RUN_DIR := $(STAXI_INSTALL_DIR)/DATA
# Level data is extracted from the C64 ROM (see dos.mk for the long
# explanation): 24 lettered levels A..X from scenes 0..23 plus the
# title from scene 24, via stuff/spacetaxi/romToLevel.py.
STAXI_RAW_DUMP := $(REPO_DIR)/stuff/spacetaxi/raw.bin
ROMTOLEVEL_BIN := $(REPO_DIR)/stuff/spacetaxi/romToLevel.py
STAXI_LEVEL_NUMS := 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
STAXI_ROM_LEVEL_GEN := $(foreach n,$(STAXI_LEVEL_NUMS),$(STAXI_GEN_DIR)/levels/level$(n).dat) \
$(STAXI_GEN_DIR)/levels/title.dat
STAXI_LEVEL_GEN := $(STAXI_ROM_LEVEL_GEN)
# Tile-bank PNGs (font.png and any tiles/*.png) bake to .tbk with
# Amiga plane-major bytes. Sprite-sheet PNGs bake to cross-target
# chunky 4bpp .spr (the Phase 11 walker reads chunky). The runtime
# loader (jlTileBankLoad / jlSpriteBankLoad) refuses .tbk files
# baked for the wrong target byte, so a stale build won't silently
# render garbage.
STAXI_TILE_PNGS := $(STAXI_SRC_DIR)/font.png $(wildcard $(STAXI_SRC_DIR)/tiles/*.png)
STAXI_SPRITE_PNGS := $(wildcard $(STAXI_SRC_DIR)/sprites/*.png)
STAXI_TBK_GEN := $(patsubst $(STAXI_SRC_DIR)/%.png,$(STAXI_GEN_DIR)/%.tbk,$(STAXI_TILE_PNGS))
STAXI_SPR_GEN := $(patsubst $(STAXI_SRC_DIR)/%.png,$(STAXI_GEN_DIR)/%.spr,$(STAXI_SPRITE_PNGS))
STAXI_LEVEL_RUN := $(patsubst $(STAXI_GEN_DIR)/%,$(STAXI_RUN_DIR)/%,$(STAXI_LEVEL_GEN))
STAXI_TBK_RUN := $(patsubst $(STAXI_GEN_DIR)/%,$(STAXI_RUN_DIR)/%,$(STAXI_TBK_GEN))
STAXI_SPR_RUN := $(patsubst $(STAXI_GEN_DIR)/%,$(STAXI_RUN_DIR)/%,$(STAXI_SPR_GEN))
STAXI_ASSET_DSTS := $(STAXI_LEVEL_RUN) $(STAXI_TBK_RUN) $(STAXI_SPR_RUN)
ASSETBAKE_BIN := $(REPO_DIR)/tools/assetbake/assetbake.py
ASSETBAKE_TARGET := amiga
# Game data lives under bin/DATA/, ready to be copied into the
# scratch JOEYLIB hard-drive dir staged by scripts/run-amiga.sh.
# audio.c fopens "DATA/test.mod" etc. relative to the boot volume.
DATA_DIR := $(BINDIR)/DATA
DATA_FILES := $(DATA_DIR)/test.mod $(DATA_DIR)/test.sfx
.PHONY: all amiga clean-amiga
all amiga: $(LIB) $(HELLO_BIN) $(PATTERN_BIN) $(DRAW_BIN) $(KEYS_BIN) $(JOY_BIN) $(SPRITE_BIN) $(AUDIO_BIN) $(UBER_BIN) $(ADV_BIN) $(ADV2_BIN) $(AGI_BIN) $(STAXI_BIN) $(DATA_FILES) $(STAXI_ASSET_DSTS)
$(BUILD)/obj/core/%.o: $(SRC_CORE)/%.c
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/port/%.o: $(SRC_PORT)/amiga/%.c
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) -c $< -o $@
# Hand-written 68k assembly: GAS syntax, fed through the gcc driver
# so the bundled m68k-amigaos-as (binutils) does the work.
$(BUILD)/obj/port/%.o: $(SRC_PORT)/amiga/%.s
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) -c $< -o $@
# PTPlayer is third-party Devpac/vasm-syntax assembly with no
# maintained GAS port; vasm is invoked only here.
$(BUILD)/obj/port/ptplayer.o: $(PTPLAYER_DIR)/ptplayer.asm
@mkdir -p $(dir $@)
$(AMIGA_AS) $(PTPLAYER_ASFLAGS) $< -o $@
$(BUILD)/obj/codegen/%.o: $(CODEGEN_DIR)/%.c
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) -I$(CODEGEN_DIR) -c $< -o $@
$(BUILD)/obj/68k/%.o: $(SRC_68K)/%.s
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) -c $< -o $@
$(LIB): $(LIB_OBJS)
@mkdir -p $(dir $@)
$(AMIGA_AR) rcs $@ $^
$(HELLO_BIN): $(HELLO_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(PATTERN_BIN): $(PATTERN_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(DRAW_BIN): $(DRAW_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(KEYS_BIN): $(KEYS_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(JOY_BIN): $(JOY_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(SPRITE_BIN): $(SPRITE_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(AUDIO_BIN): $(AUDIO_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(UBER_BIN): $(UBER_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(ADV_BIN): $(ADV_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(ADV2_BIN): $(ADV2_SRC) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $< $(LIB) -o $@ $(LDFLAGS)
$(AGI_BIN): $(AGI_SRCS) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $(AGI_SRCS) $(LIB) -o $@ $(LDFLAGS)
$(STAXI_BIN): $(STAXI_SRCS) $(LIB)
@mkdir -p $(dir $@)
$(AMIGA_CC) $(CFLAGS) $(STAXI_SRCS) $(LIB) -o $@ $(LDFLAGS)
# Space Taxi asset pipeline. .SECONDARY keeps the generated/ artifacts
# from being auto-deleted after staging.
.SECONDARY: $(STAXI_LEVEL_GEN) $(STAXI_TBK_GEN) $(STAXI_SPR_GEN)
$(STAXI_ROM_LEVEL_GEN) &: $(STAXI_RAW_DUMP) $(ROMTOLEVEL_BIN)
@mkdir -p $(STAXI_GEN_DIR)/levels
python3 $(ROMTOLEVEL_BIN) $(STAXI_RAW_DUMP) $(STAXI_GEN_DIR)/levels
$(STAXI_GEN_DIR)/%.tbk: $(STAXI_SRC_DIR)/%.png $(ASSETBAKE_BIN)
@mkdir -p $(dir $@)
python3 $(ASSETBAKE_BIN) --type tile --target $(ASSETBAKE_TARGET) $< $@
$(STAXI_GEN_DIR)/%.spr: $(STAXI_SRC_DIR)/%.png $(ASSETBAKE_BIN)
@mkdir -p $(dir $@)
python3 $(ASSETBAKE_BIN) --type sprite --cell 3x3 $< $@
$(STAXI_RUN_DIR)/levels/%.dat: $(STAXI_GEN_DIR)/levels/%.dat
@mkdir -p $(dir $@)
cp $< $@
$(STAXI_RUN_DIR)/%.tbk: $(STAXI_GEN_DIR)/%.tbk
@mkdir -p $(dir $@)
cp $< $@
$(STAXI_RUN_DIR)/%.spr: $(STAXI_GEN_DIR)/%.spr
@mkdir -p $(dir $@)
cp $< $@
$(DATA_DIR)/test.mod: $(REPO_DIR)/assets/test.mod
@mkdir -p $(DATA_DIR)
cp $< $@
$(DATA_DIR)/test.sfx: $(REPO_DIR)/assets/test.sfx
@mkdir -p $(DATA_DIR)
cp $< $@
clean-amiga:
rm -rf $(BUILD)
# Pull in per-object header-dependency files generated by gcc -MMD/-MP.
# Without this, editing a header (e.g. surfaceInternal.h) doesn't rebuild
# the .c files that include it, leaving a frankenstein binary where
# different TUs see different struct layouts.
-include $(LIB_OBJS:.o=.d)