# Makefile for Atari 800 Taipan, by B. Watson
# Written for GNU make, but seems to work with BSD make (though
# I don't test BSD make every time I change anything).

# cl65 binary:
CC=cl65

# System cl65 will compile for. Don't expect this to work if you change it
# (though possibly atarixl might work, with newer cc65s)
SYS=atari

# Optimization flags for cc65.
#COPT=-Oirs
COPT=-O

# This is used for embedding the date and git info in the game binary.
# It'll appear on the title screen.
VER=0.99alpha
TODAY=`date +%Y%m%d`
#BRANCH=`( git branch 2> /dev/null || echo ' NOGIT' )| cut -d' ' -f2`
REV=`git rev-parse --short HEAD 2>/dev/null || echo UNKNOWN`
#VERSION="v$(VER)-$(TODAY)-$(BRANCH)-$(REV)"
VERSION="v$(VER)-$(TODAY)-$(REV)"

# Memory layout. Controlled by the Makefile from now on, no longer
# hardcoded addresses in various scripts. These are in hex. If any
# of them are changed, you *must* run 'make clean'.

# Font.
FONT_ADDR=0x2000

# Title screen data will be decompressed to this address.
TITLE_DATA_ADDR=0x2400

# Title display list, decompression code, and menu code. Should be
# TITLE_DATA_ADDR plus 0x1744.
TITLE_CODE_ADDR=0x3b44

# Main game start address. All the code in TAIMAIN_C_SRC and
# TAIMAIN_ASM_SRC loads here. We get this address by looking for
# 'C code can load at' message when making newtitle.xex. It's the
# next byte after the end of the display list.
#TAIMAIN_ADDR=0x3d00
TAIMAIN_ADDR=0x3cc7

# Size of cc65 parameter stack in bytes.
STACK_SIZE=0x200

# for older cc65, we need a custom linker file.
#CFLAGS=-t $(SYS) -C custom.cfg -I. -L. $(COPT)

# for recent git cc65, we can reserve memory on the command line.
# -D__RESERVED_MEMORY__=1056 because cc65's default end of memory
# is $BC20, and we want it to end just below our font, which starts
# at $B800. cc65's runtime stack starts just below this, and is
# 2K in size (bottom is at 0xb000).
# -D__SYSTEM_CHECK__=1 stops cl65 from prepending a bit of code that
# checks to make sure there's enough memory. Older cc65 didn't do this,
# and I never missed it.
# The meaning of the -l flag is different between cc65-2.13.3
# and the later github cc65, so it's been removed here.
#CFLAGS=-t $(SYS) -T -I. -L. -Wl -D__SYSTEM_CHECK__=1 -Wl -D__RESERVED_MEMORY__=1056 $(COPT)

CFLAGS=-t $(SYS) -T -I. -L. -Wl -D__SYSTEM_CHECK__=1 -DFONT_ADDR=$(FONT_ADDR) --start-addr $(TAIMAIN_ADDR) -Wl -D__STACKSIZE__=$(STACK_SIZE) $(COPT)

AS=ca65
ASFLAGS=
AR=ar65

# C compiler for host system. Currently only used for building convfont.
HOSTCC=gcc
HOSTCFLAGS=-Wall

# A few files have no make rules here. LORCHA.DAT is generated as a
# side-effect of generating taifont.xex. It's a 49-byte (7x7) blob of
# Atari "internal" screen codes.

# LORCHA.DAT, and PORTSTAT.DAT aren't deleted by a
# 'make clean'.

# romfont is the 1K font extracted from the Atari 800 OS, with a
# command like:
# dd if=atariosb.rom of=1 bs=256 skip=8 count=4
# ...where atariosb.rom comes from e.g. the PC-Xformer 2.5 zip file.

# The game binary:
XEX=taipan.xex

# All the C and asm sources for taimain.xex:
TAIMAIN_HDRS=sounds.h
TAIMAIN_C_SRC=taipan.c
TAIMAIN_ASM_SRC=rand.s draw_lorcha.s timed_getch.s jsleep.s portstat.s clrtobot.s ultostr.s soundasm.s

# Comment these lines out to build without big number support.
# This will stop being possible at some point.
BIGNUM_SRC=bigfloat.s
BIGNUM_HDRS=bignum.h bigfloat.h
BIGNUM_CFLAGS=-DBIGNUM=BIGFLOAT

# Uncomment these for experimental int48 big numbers
#BIGNUM_SRC=bigint48.c
#BIGNUM_HDRS=bignum.h bigint48.h
#BIGNUM_CFLAGS=-DBIGNUM=BIGINT48

# Default rule for plain 'make' command is to build the binary.
all: $(XEX)

# I have F10 in my editor bound to 'make test', so:
test: all
	atari800 -nobasic $(XEX)

# The above is fast & easy, but from time to time it's necessary
# to test slow loading, make sure the title screen stuff works OK.
testatr: taipan.atr
	atari800 -nobasic -nopatch taipan.atr

taipan.atr: all
	cp ~/dos_20s.atr taipan.atr
	cp taipan.xex AUTORUN.SYS
	axe -w AUTORUN.SYS taipan.atr
	rm -f AUTORUN.SYS

# The game binary is a multi-part binary load file. This rule
# depends on all the pieces, and just concatenates them.
$(XEX): taimain.xex taifont.xex newtitle.xex comptitle.xex
	cat comptitle.xex newtitle.xex taifont.xex taimain.xex > $(XEX)
	perl size.pl $(TAIMAIN_ADDR) $(STACK_SIZE)

# Bitmap data for the title screen, 256x184 = 47104 pixels, 8 bits
# per pixel, or 5888 bytes. Displayed in ANTIC mode F (aka GR.8),
# using GTIA narrow playfield. The original title screen for the Apple
# is a 280x192 bitmap with a few blank lines at the top & bottom. I
# squished it horizontally to 256 pixels and got rid of the blank lines,
# to save load time. Note that titledata.dat is not built into
# the game binary as-is: it's now used as input for creating
# comptitle.xex, the compressed title screen.
titledata.dat: newtitle.pl newtitle.png
	perl newtitle.pl > titledata.dat

# compressed title, for faster loading. see titlecompression.txt
# for gory details.
comptitle.xex: titledata.dat titlecomp.pl comptitle.s.in
	perl titlecomp.pl 133 < titledata.dat
	cl65 -l comptitle.lst -o comptitle.xex -t none --asm-define destination=$(TITLE_DATA_ADDR) comptitle.s

# Init segment that loads after the title screen data. It sets up
# a custom display list and sets the GTIA for narrow playfield,
# then waits for a keypress. Afterwards, it restores the OS's
# display list and sets the GTIA back to normal, then exits.
# Notice this is built with "-t none" instead of "-t atari",
# since it's a lot easier to homebrew an init segment than it is
# to get cc65 to build an init segment (would need a custom linker
# script at least).
newtitle.xex: newtitle.s ver.dat help.dat
	cl65 -l newtitle.lst -m newtitle.map -o newtitle.xex -t none --asm-define screendata=$(TITLE_DATA_ADDR) --asm-define origin=$(TITLE_CODE_ADDR) newtitle.s

# Version number in Atari screen-data form
ver.dat: text2screen.pl
	echo "$(VERSION)" | perl text2screen.pl > ver.dat

# Help text for the title screen
help.dat: help.txt text2screen.pl
	perl text2screen.pl < help.txt > help.dat

#ver.dat: mkver.pl
#	perl mkver.pl $(VERSION) > ver.dat

# The main executable. All the C and asm code goes here, except the init
# segment in newtitle.s.
taimain.xex: $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) $(TAIMAIN_HDRS) $(BIGNUM_SRC) $(BIGNUM_HDRS)
	cl65 -m taipan.map $(CFLAGS) $(BIGNUM_CFLAGS) -o taimain.xex $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) $(BIGNUM_SRC)

#cl65 --mapfile taipan.map $(CFLAGS) -o taimain.xex taipan.c sounds.c rand.s draw_lorcha.s timed_getch.s jsleep.s portstat.s clrtobot.s

# With newer cc65s, I have to do this to get an assembly listing of just
# taipan.c. This rule not used as part of the main build, it's only for
# debugging.
taipan.lst: taipan.c
	cl65 -m taipan.map $(CFLAGS) -c -o /dev/null -l taipan.lst -T taipan.c

# Another such rule for sounds.c:
sounds.lst: sounds.c sounds.h
	cl65 -m sounds.map $(CFLAGS) -c -o /dev/null -l sounds.lst -T sounds.c

# The font gets loaded into RAM, in the area reserved by the
# -D__RESERVED_MEMORY__ option to cl65. To actually use the font,
# taimain.xex contains code that sets CHBAS ($02f4).
# Not mentioned in any make rule: convfont also creates LORCHA.DAT,
# which draw_lorcha.s depends on (so we touch draw_lorcha.s here).
taifont.xex: convfont romfont font
	cat romfont font | ./convfont -x > taifont.xex
	touch draw_lorcha.s

# Not part of the game binary. This just builds the font without the
# Atari 6-byte binary load header, for eyeballing it in bitmapdump.pl
# or converting to other formats.
taifont: convfont romfont font
	cat romfont font | ./convfont > taifont

# PORTSTAT.DAT gets incbin'ed directly in portstat.s. It's screen-code
# data for the static part of the port status screen, which ends up in
# an array that the C code can memcpy() into screen RAM as needed.
# This make rule actually runs atari800. For it to work, you'll need
# the H: device enabled, pointed at the current directory, and set
# to writable.
PORTSTAT.DAT: mkportstats.xex
	atari800 -nobasic mkportstats.xex
	touch portstat.s

# Host tool that builds our custom font from the data ripped out of
# the Apple version, plus the Atari OS ROM. Also, all the custom
# characters for the enemy ships are defined here (as hex data. Yes,
# I converted them manually from eyeballing a screenshot of the Apple
# combat screen).
convfont: convfont.c
	$(HOSTCC) $(HOSTCFLAGS) -DFONT_ADDR=$(FONT_ADDR) -o convfont convfont.c

# Rules for building various file types with the cc65 toolchain.
.s.o:
	$(AS) $(ASFLAGS) -o $@ $<

.c.o:
	$(CC) $(CFLAGS) -c -o $@ $<

%.xex: %.c
	$(CC) --mapfile map $(CFLAGS) -o $@ $<

# Obligatory clean and distclean rules.
clean:
	rm -f *.o *.lst convfont *.xex AUTORUN.SYS taipan.atr ver.dat help.dat

distclean: clean
	rm -f *~ core .*.swp 1.* 2.* 1 2 3 map map.* *.map a b c foo bar baz comptitle.s comptitle.dat

push:
	sh push.sh

size: clean all
	perl size.pl $(TAIMAIN_ADDR) $(STACK_SIZE)

# Cruft. Was used for testing the enemy ship animation.
lorchatest: lorchatest.c draw_lorcha.s taifont.xex
	cl65 -t atari -O -T -o lorchatest1.xex lorchatest.c draw_lorcha.s
	cat taifont.xex lorchatest1.xex > lorchatest.xex
	atari800 -nobasic lorchatest.xex

soundtest: sounds.c
	cl65 -DTESTXEX -t atari -o sounds.xex sounds.c
	atari800 -nobasic sounds.xex

# former textmode title screen, was generated by TITLE.LST. Replaced
# by graphical title screen.
#title.xex: TITLE.DAT
#	perl title.pl TITLE.DAT > title.xex

# old title
#$(XEX): taimain.xex taifont.xex title.xex
#	cat taifont.xex title.xex taimain.xex > $(XEX)