# DOS (DJGPP) build rules. include $(dir $(lastword $(MAKEFILE_LIST)))/common.mk PLATFORM := dos BUILD := $(REPO_DIR)/build/$(PLATFORM) LIBDIR := $(BUILD)/lib BINDIR := $(BUILD)/bin CFLAGS := $(COMMON_CFLAGS) -march=i386 -m32 -I$(REPO_DIR)/toolchains/audio/libxmp-lite/include -MMD -MP ASFLAGS := -f coff LDFLAGS := # libxmp-lite (MIT, libxmp.org) -- 4-channel-Protracker-and-friends # replayer + SMIX SFX overlay. Staged at toolchains/audio/libxmp-lite/ # (currently checked in; install.sh wiring is a follow-up). Built as # a static archive that the DOS audio HAL links against. LIBXMP_DIR := $(REPO_DIR)/toolchains/audio/libxmp-lite LIBXMP_SRC := $(filter-out %/win32.c, $(wildcard $(LIBXMP_DIR)/src/*.c) $(wildcard $(LIBXMP_DIR)/src/loaders/*.c)) LIBXMP_OBJDIR := $(BUILD)/obj/libxmp-lite LIBXMP_OBJS := $(patsubst $(LIBXMP_DIR)/src/%.c,$(LIBXMP_OBJDIR)/%.o,$(LIBXMP_SRC)) LIBXMP_AR := $(LIBDIR)/libxmplite.a LIBXMP_CFLAGS := -DJOEY_LIBXMP_LITE -DLIBXMP_CORE_PLAYER -DHAVE_FNMATCH=0 -I$(LIBXMP_DIR)/include -I$(LIBXMP_DIR)/include/libxmp-lite -I$(LIBXMP_DIR)/src -Wno-error -w PORT_C_SRCS := $(wildcard $(SRC_PORT)/dos/*.c) PORT_S_SRCS := $(wildcard $(SRC_PORT)/dos/*.asm) CODEGEN_DIR := $(REPO_DIR)/src/codegen LIB_OBJS := \ $(patsubst $(SRC_CORE)/%.c,$(BUILD)/obj/core/%.o,$(CORE_C_SRCS)) \ $(patsubst $(SRC_PORT)/dos/%.c,$(BUILD)/obj/port/%.o,$(PORT_C_SRCS)) \ $(patsubst $(SRC_PORT)/dos/%.asm,$(BUILD)/obj/port/%.o,$(PORT_S_SRCS)) \ $(BUILD)/obj/codegen/spriteEmitX86.o \ $(BUILD)/obj/codegen/spriteCompile.o LIB := $(LIBDIR)/libjoey.a HELLO_SRC := $(EXAMPLES)/hello/hello.c HELLO_BIN := $(BINDIR)/HELLO.EXE PATTERN_SRC := $(EXAMPLES)/pattern/pattern.c PATTERN_BIN := $(BINDIR)/PATTERN.EXE DRAW_SRC := $(EXAMPLES)/draw/draw.c DRAW_BIN := $(BINDIR)/DRAW.EXE KEYS_SRC := $(EXAMPLES)/keys/keys.c KEYS_BIN := $(BINDIR)/KEYS.EXE JOY_SRC := $(EXAMPLES)/joy/joy.c JOY_BIN := $(BINDIR)/JOY.EXE SPRITE_SRC := $(EXAMPLES)/sprite/sprite.c SPRITE_BIN := $(BINDIR)/SPRITE.EXE AUDIO_SRC := $(EXAMPLES)/audio/audio.c AUDIO_BIN := $(BINDIR)/AUDIO.EXE UBER_SRC := $(EXAMPLES)/uber/uber.c UBER_BIN := $(BINDIR)/UBER.EXE ADV_SRC := $(EXAMPLES)/adventure/adventure.c ADV_BIN := $(BINDIR)/ADV.EXE ADV2_SRC := $(EXAMPLES)/adventure2/adventure2.c ADV2_BIN := $(BINDIR)/ADV2.EXE 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.EXE 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 # JoeyLib install convention: each app lives in its own bin subdir # with a DATA/ folder alongside the binary for runtime assets. STAXI_INSTALL_DIR := $(BINDIR)/STAXI STAXI_BIN := $(STAXI_INSTALL_DIR)/STAXI.EXE # Game data lives under bin/DATA/, alongside the binaries DOSBox picks # up when bin/ is mounted as C:. audio.c fopens "DATA/test.mod" etc. DATA_DIR := $(BINDIR)/DATA DATA_FILES := $(DATA_DIR)/test.mod $(DATA_DIR)/test.sfx # Space Taxi asset pipeline. # # Sources live in examples/spacetaxi/assets/ (txt, png, etc. -- the # stuff the user hand-authors). Build artifacts go to # examples/spacetaxi/generated/ (dat, jas) -- safe to nuke; recreated # by this makefile. Runtime files are then copied from generated/ # into the per-target bin/assets/ tree. STAXI_SRC_DIR := $(EXAMPLES)/spacetaxi/assets STAXI_GEN_DIR := $(EXAMPLES)/spacetaxi/generated/dos STAXI_RUN_DIR := $(STAXI_INSTALL_DIR)/DATA # Level data is extracted from the C64 ROM by # stuff/spacetaxi/romToLevel.py: 24 lettered levels (A..X) from scenes # 0..23 plus the title from scene 24. The script runs the captured # decompressor through a Python 6502 emulator and writes STL2 .dat # files directly. Input is the raw RAM dump. mkstlevel + title.txt # is no longer used: the C64 title encodes its screen with the game's # custom charset (extracted into tbank0.png), so a hand-authored tile # layout with a different glyph mapping renders as garbage. 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 # DOS / IIgs chunky 4bpp bytes. Sprite-sheet PNGs bake to cross- # target chunky 4bpp .spr blobs. 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)) ASSETBAKE_BIN := $(REPO_DIR)/tools/assetbake/assetbake.py ASSETBAKE_TARGET := dos # Final runtime tree (mirrors generated/ into bin/assets/). 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) MKSTLEVEL_BIN := $(REPO_DIR)/build/tools/mkstlevel .PHONY: all dos clean-dos all dos: $(LIB) $(LIBXMP_AR) $(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 $@) $(DOS_CC) $(CFLAGS) -c $< -o $@ $(BUILD)/obj/port/%.o: $(SRC_PORT)/dos/%.c @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) -c $< -o $@ $(BUILD)/obj/port/%.o: $(SRC_PORT)/dos/%.asm @mkdir -p $(dir $@) $(DOS_AS) $(ASFLAGS) $< -o $@ $(BUILD)/obj/codegen/%.o: $(CODEGEN_DIR)/%.c @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) -I$(CODEGEN_DIR) -c $< -o $@ $(LIB): $(LIB_OBJS) @mkdir -p $(dir $@) $(DOS_AR) rcs $@ $^ $(LIBXMP_OBJDIR)/%.o: $(LIBXMP_DIR)/src/%.c @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $(LIBXMP_CFLAGS) -c $< -o $@ $(LIBXMP_AR): $(LIBXMP_OBJS) @mkdir -p $(dir $@) $(DOS_AR) rcs $@ $^ $(HELLO_BIN): $(HELLO_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(PATTERN_BIN): $(PATTERN_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(DRAW_BIN): $(DRAW_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(KEYS_BIN): $(KEYS_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(JOY_BIN): $(JOY_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(SPRITE_BIN): $(SPRITE_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(AUDIO_BIN): $(AUDIO_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(UBER_BIN): $(UBER_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(ADV_BIN): $(ADV_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(ADV2_BIN): $(ADV2_SRC) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $< $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(AGI_BIN): $(AGI_SRCS) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $(AGI_SRCS) $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ $(STAXI_BIN): $(STAXI_SRCS) $(LIB) @mkdir -p $(dir $@) $(DOS_CC) $(CFLAGS) $(STAXI_SRCS) $(LIB) $(LIBXMP_AR) -o $@ $(DOS_EMBED_DPMI) $@ # Stage A: generate artifacts into examples/spacetaxi/generated/. # Mark these .SECONDARY so make doesn't auto-delete them after the # stage-B copy into bin/ -- they're the canonical distribution # artifacts. .SECONDARY: $(STAXI_LEVEL_GEN) $(STAXI_TBK_GEN) $(STAXI_SPR_GEN) # Bulk-extract all 24 canonical levels plus the title from the C64 # ROM in one invocation. Grouped target (&:) means make treats the # recipe as producing the whole list together -- it runs once even # though many targets depend on it. Requires GNU Make 4.3+. $(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 $< $@ # Stage B: copy generated/ into the per-target bin/assets/ runtime tree $(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 $< $@ $(MKSTLEVEL_BIN): $(MAKE) -f $(REPO_DIR)/make/tools.mk mkstlevel $(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-dos: rm -rf $(BUILD) # Nuke regenerable Space Taxi artifacts. Sources under # examples/spacetaxi/assets/ are untouched; everything under # generated/ is recreated by the next build. .PHONY: clean-spacetaxi clean-spacetaxi: find $(STAXI_GEN_DIR) -mindepth 1 ! -name '.gitignore' -delete 2>/dev/null || true # 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)