SHELL = /usr/bin/env bash

USE_WINE = wine

# Multi-argument delimiter ",,"
# Whole expression parentheses legal only for memory access
# Fake instructions disabled
# Keyword labels give error
# Report warnings as errors
SJASMPLUS_OPTIONS = --syntax=abFLw

SYNTH_SRC = src/synth.asm \
            src/banks.asm \
            src/defs.asm \
            src/macros.asm \
            src/notes.asm \
            src/notes_unison.asm \
            src/samplegen.asm \
            src/smc.asm \
            bin/ym_table.asm \
            bin/ay_table.asm \
            bin/ym_table_4bit.asm \
            bin/ay_table_4bit.asm \
            bin/pitch_table.bin \
            bin/unison_pitch_table.bin

SYNTH_WAVES = bin/waves/AKWF_ebass_0001.f.raw \
              bin/waves/AKWF_theremin_0008.f.raw \
              bin/waves/AKWF_epiano_0002.1.raw \
              bin/waves/AKWF_epiano_0002.3.raw \
              bin/waves/AKWF_epiano_0002.5.raw \
              bin/waves/AKWF_epiano_0002.7.raw \
              bin/waves/AKWF_epiano_0002.9.raw \
              bin/waves/AKWF_epiano_0002.b.raw \
              bin/waves/AKWF_epiano_0002.d.raw \
              bin/waves/AKWF_epiano_0002.f.raw \
              bin/mod/AKWF_theremin_0008.0.raw

SONG_SRC = src/song.asm \
           bin/sample/wnd_kick.raw \
           bin/sample/wnd_kick2.raw \
           bin/sample/wnd_snare.raw \
           bin/sample/wnd_snare_light.raw \
           bin/sample/wnd_hat.raw \
           bin/sample/wnd_tom.raw \
           bin/sample/wnd_cymbal.raw

SONG3_SRC = bin/sample/simmons_hat_long.raw

.PHONY: all
all: 128 trd ay

.PHONY: 128
128: build/synth.tap
.PHONY: trd
trd: build/synth.trd
.PHONY: ay
ay: build/synth.ay

build/synth.tap: bin/loader.tap bin/synth_128.tap | build
	cat $^ > $@

bin/synth_128.tap: bin/synth.bin.zx0
	$(USE_WINE) ./tools/GenTape/GenTape.exe $@ data $^

build/synth.ay: bin/ay/header.bin bin/ay/init.bin bin/synth.bin.zx0 | build
	cat $^ > $@

bin/loader.tap: src/loader.asm src/dzx0_standard.asm bin/entry.asm bin/zx0_info.asm
	cd src && sjasmplus $(SJASMPLUS_OPTIONS) loader.asm

build/synth.trd: src/loader_trd.asm src/dzx0_standard.asm bin/entry.asm bin/zx0_info.asm bin/synth.bin.zx0 | build
	cd src && sjasmplus $(SJASMPLUS_OPTIONS) loader_trd.asm

bin/ay/header.bin bin/ay/init.bin bin/ay/synth_ay.list &: src/synth_ay.asm src/dzx0_standard.asm bin/entry.asm | bin/ay
	cd src && $(USE_WINE) ../tools/zeus/zcl.exe synth_ay.asm

bin/synth.bin: bin/bank5.bin bin/bank2.bin bin/bank0.bin
	cat $^ > $@

bin/zx0_info.asm bin/synth.bin.zx0 &: bin/synth.bin
	ZX0_INFO=($$($(USE_WINE) ./tools/zx0/zx0.exe -f $^ | grep -o ' [0-9]\+')) && printf "decompressed_size equ $${ZX0_INFO[0]}\ncompressed_size equ $${ZX0_INFO[1]}\nzx0delta equ $${ZX0_INFO[2]}\n" > bin/zx0_info.asm

bin/bank0.bin bin/bank2.bin bin/bank5.bin bin/synth.list bin/entry.asm &: src/synth_128.asm $(SYNTH_SRC) $(SYNTH_WAVES) $(SONG_SRC) $(SONG3_SRC) | bin
	cd src && $(USE_WINE) ../tools/zeus/zcl.exe synth_128.asm

# make_table
bin/tools/make_table/main.o: src/tools/make_table/main.cpp src/tools/make_table/make_table.hpp | bin/tools/make_table
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

bin/tools/make_table/make_table.o: src/tools/make_table/make_table.cpp src/tools/make_table/make_table.hpp | bin/tools/make_table
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

bin/tools/make_table/make_table: bin/tools/make_table/main.o bin/tools/make_table/make_table.o
	$(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@

bin/tools/make_table: | bin/tools
	mkdir -p $@

bin/ay_table.asm bin/ym_table.asm bin/ay_table_4bit.asm bin/ym_table_4bit.asm &: bin/tools/make_table/make_table
	cd bin && ./tools/make_table/make_table

# pitch_table
bin/tools/pitch_table/pitch_table: src/tools/pitch_table/main.cpp | bin/tools/pitch_table
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -o $@

bin/tools/pitch_table: | bin/tools
	mkdir -p $@

bin/pitch_table.bin bin/unison_pitch_table.bin &: bin/tools/pitch_table/pitch_table | bin
	cd bin && ./tools/pitch_table/pitch_table

bin/tools: | bin
	mkdir -p $@

# waves
SOX_CMD = sox -R $< -t raw -e unsigned-integer -b 8 -c 1 -r 18816 -
DPCM = src/tools/dpcm/dpcm.py
DCSHIFT = src/tools/dcshift/dcshift.py
bin/waves/%.0.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.015625 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.1.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.031250 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.2.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.046875 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.3.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.062500 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.4.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.078125 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.5.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.093750 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.6.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.109375 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.7.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.125000 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.8.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.140625 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.9.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.156250 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.a.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.171875 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.b.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.187500 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.c.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.203125 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.d.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.218750 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.e.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.234375 | $(DCSHIFT) 128 | $(DPCM) > $@
bin/waves/%.f.raw: src/waves/%.wav $(DCSHIFT) $(DPCM) | bin/waves
	$(SOX_CMD) vol 0.250000 | $(DCSHIFT) 128 | $(DPCM) > $@

PROC_MOD = src/tools/proc_mod/proc_mod.py
bin/mod/%.0.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.0625 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.1.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.1250 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.2.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.1875 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.3.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.2500 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.4.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.3125 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.5.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.3125 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.6.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.4375 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.7.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.5000 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.8.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.5625 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.9.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.6250 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.a.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.6875 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.b.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.7500 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.c.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.8125 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.d.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.8750 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.e.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 0.9375 | $(PROC_MOD) | $(DPCM) > $@
bin/mod/%.f.raw: src/mod/%.wav $(PROC_MOD) $(DPCM) | bin/mod
	$(SOX_CMD) vol 1.0000 | $(PROC_MOD) | $(DPCM) > $@

# samples
bin/sample/%.raw: src/sample/%.wav $(DCSHIFT) | bin/sample
	sox -R $< -t raw -e unsigned-integer -b 8 -c 1 -r 10715.709969788519637462235649547 - | $(DCSHIFT) 160 > $@

# Sox options:
#
# -R          -   use default random numbers
#
# -t raw      -   output raw bytes
#
# -e unsign...-   unsigned integer encoding
#
# -b 8        -   bit depth = 8
#
# -c 1        -   a single output channel
#
# -r 18816    -   waveforms are 600 samples long (but we want 256):
#                 (44100 * 256 / 600 = 18816)
#
# (alternatively):
# -r 10715... -   resample (10715 = 3546900 / 331)
#
# -           -   pipe to stdout
#
# vol 0.25    -   quarter volume (designed for 4 channels)
#             -   volume = ((index + 1) / 16 * 0.25)
#             -          = ((index + 1) / 64)

bin/waves: | bin
	mkdir -p $@

bin/sample: | bin
	mkdir -p $@

bin/mod: | bin
	mkdir -p $@

bin/ay: | bin
	mkdir -p $@

bin:
	mkdir -p $@

build:
	mkdir -p $@

.PHONY: clean
clean:
	-rm -r bin
	-rm -r build
