#FlexSID Makefile

#RELEASE values:  0: only normal-player build for testing,  1: build everything including packages
RELEASE=1
#RELEASE=0
VERSION=1.4
STATIC=0

ARCHITECTURE = $(shell uname -m)

CC=gcc
#TinyCC can't handle nested/local functions :(
#CC=tcc
CCFLAGS = -Wno-unused
#Turn off PIE/PIC (position-independent) code, for working incbin, and because PIE/PIC code might be slower and program-icon of them may disappear, and doesn't support absolute-address computed gotos
CCFLAGS += -fno-PIC -fno-PIE 
ifeq ($(ARCHITECTURE),x86_64)  # '-no-pie' seems not supported by GCC-4.9.2 and TinyCC-0.9.27,
 ifeq ($(CC),gcc)              # assuming newer GCC with x86_64 architecture that supports it  (but from which version? checking GCC version here would be more adequate)
  CCFLAGS += -no-pie 
 endif
endif

LD=ld

DEBUGGER=gdb -ex run --args


ifeq ($(CC),gcc)  #GCC
 ASM_INCBIN_SUPPORTED = 1
else  #Unfortunately on ARM TinyCC 0.9.27 doesn't even support __asm__ yet, and doesn't have '.incbin' directive (and in reality fails with 'incbin' library for C too)
 ASM_INCBIN_SUPPORTED = 0
endif

ifneq ($(STATIC),1)
 DEPENDS=libsdl1.2debian
else
 DEPENDS=
endif

PC_DEFINES = -D_PC=1 -D_LINUX=1 -DVERSION=\"$(VERSION)\" -DZOOM_DEFAULT=$(ZOOM_DEFAULT) -DASM_INCBIN_SUPPORTED=$(ASM_INCBIN_SUPPORTED)

SYMDEF=resources/tools/symdef
BIN2ARRAY=resources/tools/bin2array
COMPRESS=resources/tools/compress64k

COMMON_SOURCES = assembly/playerspec.asm assembly/player.asm \
                 assembly/special.asm assembly/runexe.asm resources/tools/symdef.c \
                 maincode/*.c maincode/*.h assembly/*.asm

PC_SOURCES = $(COMMON_SOURCES)
PC_SOURCES += FlexSID.c platform/platform.c  resources/tools/bin2array.c
PC_SOURCES += platform/*.c platform/*.h

CA65_OPTIONS = --cpu 6502x   --feature labels_without_colons  --feature c_comments  --feature underline_in_numbers
CC65_OPTIONS = -D _C64=1  --standard cc65  -Osir  -Cl
CL65_OPTIONS = -t c64


PLAYERTYPE_EXTRA=0
PLAYERTYPE_NORMAL=1
PLAYERTYPE_MEDIUM=2
PLAYERTYPE_LIGHT=3
PLAYERTYPE_BARE=4
PLAYERTYPE_COUNT=5

PLAYERTYPES = -D PLAYERTYPE_EXTRA=$(PLAYERTYPE_EXTRA)  -D PLAYERTYPE_NORMAL=$(PLAYERTYPE_NORMAL) \
              -D PLAYERTYPE_MEDIUM=$(PLAYERTYPE_MEDIUM)  -D PLAYERTYPE_LIGHT=$(PLAYERTYPE_LIGHT) \
              -D PLAYERTYPE_BARE=$(PLAYERTYPE_BARE) -D PLAYERTYPE_COUNT=$(PLAYERTYPE_COUNT)

ZOOM_DEFAULT=2


 all: compressor
ifeq ($(RELEASE),1)
 all: createdisk
 all: natives
 all: PC  selector manual  package
else
# all: normal
# all: PC_DEFINES += -DDEBUG=1
 all: PC test  # disk
endif


natives: normal medium light extra bare

extra: PLAYERTYPE=$(PLAYERTYPE_EXTRA)
extra: PLAYERTYPESTR=PLAYERTYPE_EXTRA
extra: PLAYERTYPE_LETTER=e
extra: PLAYERNAME=extra
extra: FlexSID-extra.prg
extra: EXAMPLETUNE=resources/examples/MSK_cover-XF_End-extraplayer.flx

normal: PLAYERTYPE=$(PLAYERTYPE_NORMAL)
normal: PLAYERTYPESTR=PLAYERTYPE_NORMAL
normal: PLAYERTYPE_LETTER=n
normal: PLAYERNAME=normal
normal: FlexSID-normal.prg
normal: EXAMPLETUNE=resources/examples/GRG_cover-Plaster-normalplayer.flx

medium: PLAYERTYPE=$(PLAYERTYPE_MEDIUM)
medium: PLAYERTYPESTR=PLAYERTYPE_MEDIUM
medium: PLAYERTYPE_LETTER=m
medium: PLAYERNAME=medium
medium: FlexSID-medium.prg
medium: EXAMPLETUNE=resources/examples/4MAT_cover-Empty-mediumplayer.flx

light: PLAYERTYPE=$(PLAYERTYPE_LIGHT)
light: PLAYERTYPESTR=PLAYERTYPE_LIGHT
light: PLAYERTYPE_LETTER=l
light: PLAYERNAME=light
light: FlexSID-light.prg
light: EXAMPLETUNE=resources/examples/Hermit-Lopikula-lightplayer.flx

bare: PLAYERTYPE=$(PLAYERTYPE_BARE)
bare: PLAYERTYPESTR=PLAYERTYPE_BARE
bare: PLAYERTYPE_LETTER=b
bare: PLAYERNAME=bare
bare: FlexSID-bare.prg
bare: EXAMPLETUNE=resources/examples/Hermit-MajomTanc-bareplayer.flx


compressor:
	cd resources/tools && $(LD)  -r  -b binary  selfextract.prg  -o selfextract.prg.o  #make prg linkable by CC
	cd resources/tools && $(LD)  -r  -b binary  selfextract_nomove.prg  -o selfextract_nomove.prg.o  #make prg linkable by CC
	 $(CC) -O0 $(COMPRESS).c resources/tools/selfextract.prg.o resources/tools/selfextract_nomove.prg.o -o $(COMPRESS) -lm
	rm -f  resources/tools/*.prg.o



FlexSID-%.prg: $(COMMON_SOURCES)  # C64 native programs and artefacts included/used by PC-app
#C64 uncompressed executable:
	ca65  assembly/player.asm   $(PLAYERTYPES)  -D PLAYERTYPE=$(PLAYERTYPE)  -o assembly/player.o  $(CA65_OPTIONS)
	ca65  assembly/special.asm  $(PLAYERTYPES)  -D PLAYERTYPE=$(PLAYERTYPE)  -DZOOM_DEFAULT=$(ZOOM_DEFAULT)  -o assembly/special.o  $(CA65_OPTIONS)
#	$(CC) $(BIN2ARRAY).c -o $(BIN2ARRAY)
	cp  $(EXAMPLETUNE)  resources/ExampleTune_$(PLAYERNAME).flx  # $(BIN2ARRAY) $(EXAMPLETUNE) resources/ExampleTune.c
	ca65  assembly/runexe.asm   $(PLAYERTYPES)  -D PLAYERTYPE=$(PLAYERTYPE)  -D VERSION=$(VERSION)  \
          -o assembly/runexe_$(PLAYERNAME).o  $(CA65_OPTIONS)
	cl65  assembly/runexe_$(PLAYERNAME).o  -u  __EXEHDR__  -t c64  -C c64-asm.cfg  -o assembly/runexe_$(PLAYERNAME).prg
	cp  assembly/runexe_$(PLAYERNAME).prg resources/runexe_$(PLAYERNAME).prg  # $(BIN2ARRAY) assembly/runexe_$(PLAYERNAME).prg resources/runexe_$(PLAYERNAME).c
	rm -f resources/FlexSID.h resources/FlexSID-common.h resources/FlexSID-$(PLAYERNAME).h
	$(CC)  $(SYMDEF).c  -DPLAYERTYPESTR=\"$(PLAYERTYPESTR)\" -DPLAYERNAMESTR=\"\"  -o $(SYMDEF) -s  #get symbols of special.asm and player.asm to resources/FlexSID-$(PLAYERNAME).h defines
	 $(SYMDEF) assembly/special.asm resources/FlexSID.h && $(SYMDEF) assembly/playerspec.asm resources/FlexSID.h
	$(CC)  $(SYMDEF).c  -DPLAYERTYPESTR=\"$(PLAYERTYPESTR)\" -DPLAYERNAMESTR=\"_$(PLAYERNAME)\"  -o $(SYMDEF) -s  #get symbols of special.asm and player.asm to resources/FlexSID-$(PLAYERNAME).h defines
	 $(SYMDEF) assembly/special.asm resources/FlexSID-common.h  -playertype-agnostic-only && $(SYMDEF) assembly/playerspec.asm resources/FlexSID-common.h -playertype-agnostic-only
	  $(SYMDEF) assembly/playerspec.asm resources/FlexSID-$(PLAYERNAME).h  -playertype-specific-only
	cc65  FlexSID.c  $(PLAYERTYPES)  -D PLAYERTYPE=$(PLAYERTYPE)  -DPLAYERTYPE_LETTER=\"$(PLAYERTYPE_LETTER)\"  -D PLAYERNAME=\"$(PLAYERNAME)\"  -o FlexSID.asm  $(CC65_OPTIONS)
	cl65  FlexSID.asm  assembly/player.o  assembly/special.o  -o FlexSID-unpacked-$(PLAYERNAME).prg  \
          -m assembly/FlexSIDprg.map   $(CL65_OPTIONS)  -C resources/FlexSID-cc65.cfg
	$(COMPRESS) FlexSID-unpacked-$(PLAYERNAME).prg resources/FlexSID_$(PLAYERNAME).prg_cmp  # $(BIN2ARRAY) FlexSID-unpacked-$(PLAYERNAME).prg FlexSID-unpacked.c
ifeq ($(ASM_INCBIN_SUPPORTED),0)  #GNU-Assembler 'as' supports .incbin directive, no need to link the binaries before compiling source-code
	cd resources/  &&  $(LD)  -r  -b binary  FlexSID_$(PLAYERNAME).prg_cmp  -o FlexSID_$(PLAYERNAME).prg_cmp.o  #make prg linkable by TinyCC
	cd resources/  &&  $(LD)  -r  -b binary  ExampleTune_$(PLAYERNAME).flx  -o ExampleTune_$(PLAYERNAME).flx.o  #make flx linkable by TinyCC
	cd resources/  &&  $(LD)  -r  -b binary  runexe_$(PLAYERNAME).prg  -o runexe_$(PLAYERNAME).prg.o  #make runnable prg linkable by TinyCC
endif
#headers for Linux executable:
	$(SYMDEF) assembly/FlexSIDprg.map resources/FlexSID-$(PLAYERNAME).h  #get exported address-symbols of assembled & linked FlexSID.prg to FlexSID-xx.h defines
#C64 self-extracting executable
ifeq ($(RELEASE),1)
	resources/tools/compress64kSFX FlexSID-unpacked-$(PLAYERNAME).prg  FlexSID-$(PLAYERNAME).prg  &&  \
     rm  -f FlexSID-unpacked-$(PLAYERNAME).prg
	c1541 -attach FlexSID-C64.d64 -write FlexSID-$(PLAYERNAME).prg flexsid-$(PLAYERNAME)
endif
#clean up intermediate files
	-rm -r -f FlexSID.c64 FlexSID.o resources/FlexSID.h FlexSID-unpacked-$(PLAYERNAME).prg assembly/player.o assembly/special.o \
              assembly/runexe*.o assembly/runexe*.prg $(SYMDEF) \
              assembly/FlexSIDprg.map FlexSID.asm  # resources/ExampleTune_$(PLAYERNAME).flx  # $(BIN2ARRAY)
ifneq ($(RELEASE),1)
#	x64 FlexSID-unpacked-extra.prg
endif


exe: FlexSID
bin: FlexSID
app: FlexSID
pc: FlexSID
PC: FlexSID

ifeq ($(ASM_INCBIN_SUPPORTED),1)  #GNU-Assembler 'as' supports .incbin directive, no need to link the binaries before compiling source-code
NATIVE_OBJECTS=
COMBINED_WAVEFORM_OBJECTS =
else
NATIVE_OBJECTS= resources/FlexSID_extra.prg_cmp.o resources/FlexSID_normal.prg_cmp.o resources/FlexSID_medium.prg_cmp.o \
                resources/FlexSID_light.prg_cmp.o resources/FlexSID_bare.prg_cmp.o \
                resources/ExampleTune_extra.flx.o resources/ExampleTune_normal.flx.o resources/ExampleTune_medium.flx.o \
                resources/ExampleTune_light.flx.o resources/ExampleTune_bare.flx.o \
                resources/runexe_extra.prg.o resources/runexe_normal.prg.o resources/runexe_medium.prg.o \
                resources/runexe_light.prg.o resources/runexe_bare.prg.o
COMBINED_WAVEFORM_OBJECTS =  platform/SID_Waveform_SawTriangle.o  platform/SID_Waveform_PulseTriangle.o  platform/SID_Waveform_PulseSaw.o  platform/SID_Waveform_PulseSawTriangle.o

endif

ifeq ($(RELEASE),1)
FlexSID: CCFLAGS += -s
FlexSID: CCFLAGS += -O3
FlexSID: $(PC_SOURCES)
else
#FlexSID: CCFLAGS += -s -O3
#FlexSID: CCFLAGS += -g
FlexSID: $(PC_SOURCES)  FORCE
endif
ifeq ($(ASM_INCBIN_SUPPORTED),0)  #GNU-Assembler 'as' supports .incbin directive, no need to link the binaries before compiling source-code
	cd platform/  &&  $(LD)  -r  -b binary  SID_Waveform_SawTriangle.bin  -o SID_Waveform_SawTriangle.o
	cd platform/  &&  $(LD)  -r  -b binary  SID_Waveform_PulseTriangle.bin  -o SID_Waveform_PulseTriangle.o
	cd platform/  &&  $(LD)  -r  -b binary  SID_Waveform_PulseSaw.bin  -o SID_Waveform_PulseSaw.o
	cd platform/  &&  $(LD)  -r  -b binary  SID_Waveform_PulseSawTriangle.bin  -o SID_Waveform_PulseSawTriangle.o
endif
ifneq ($(STATIC),1)
	$(CC)  FlexSID.c $(NATIVE_OBJECTS) $(COMBINED_WAVEFORM_OBJECTS)  -o FlexSID  -lc  -lm  -lSDL  `sdl-config --cflags --libs`  $(PLAYERTYPES)  $(CCFLAGS)  $(PC_DEFINES)
else
	$(CC)  FlexSID.c $(NATIVE_OBJECTS) $(COMBINED_WAVEFORM_OBJECTS)  -o FlexSID  -s  -lc -lm  -L/usr/lib -L/usr/local/lib  -Wl,-rpath,/usr/local/lib,-Bstatic  \
         -lSDL -lXv -lXi -lpng -lz -lbsd  -Wl,-Bdynamic -lpthread -lX11 -lXext -ldl  $(PLAYERTYPES)  $(CCFLAGS)  $(PC_DEFINES)
endif
	rm -f platform/SID_Waveform*.o


FlexSID-win:  #Windows executable:
	icotool -c -o resources/FlexSID-icon.ico resources/FlexSID-icon.png
	i686-w64-mingw32-windres -O coff -i resources/FlexSID-icon.rc -o resources/FlexSID-icon.res
	i686-w64-mingw32-gcc  -c FlexSID.c  -o FlexSID-win.o  -D_PC=1 -D_WINDOWS=1 -DVERSION=\"$(VERSION)\"  -DZOOM_DEFAULT=$(ZOOM_DEFAULT)  \
                          $(PLAYERTYPES)  -DPLAYERTYPE=$(PLAYERTYPE)  -DPLAYERTYPE_LETTER=\"$(PLAYERTYPE_LETTER)\"  \
                          -DPLAYERNAME=\"$(PLAYERNAME)\"  -I/usr/local/sdlmingw/include
	i686-w64-mingw32-gcc  FlexSID-win.o resources/FlexSID-icon.res  -o FlexSID-$(PLAYERNAME).exe  -s  \
                          -L/usr/local/sdlmingw/lib -lmingw32 -mwindows -lSDLmain -lSDL
	cp resources/SDL.dll ./


#test: DEBUG=$(DEBUGGER)
test:
#ifneq ($(RELEASE),1)
	$(DEBUG)  ./FlexSID-normal  # untitled.flx
#endif

testnative:
#	./FlexSID-extra untitled.flx
	x64 -8 FlexSID-C64.d64 FlexSID-unpacked-normal.prg


manual:
#Linux-version of the user-manual:
	$(CC) $(BIN2ARRAY).c -o $(BIN2ARRAY)  &&  $(BIN2ARRAY) resources/FlexSID-User-Manual.txt
ifneq ($(STATIC),1)
	$(CC)  -O3  maincode/usermanual.c  -o usermanual  -DVERSION=\"$(VERSION)\"  -s  -lc  -lm  -lSDL  `sdl-config --cflags --libs`
else
	$(CC)  -O3  maincode/usermanual.c  -o usermanual  -DVERSION=\"$(VERSION)\"  -s  -lc -lm  -L/usr/lib -L/usr/local/lib  \
         -Wl,-rpath,/usr/local/lib,-Bstatic  -lSDL -lXv -lXi -lpng -lz -lbsd  -Wl,-Bdynamic -lpthread -lX11 -lXext -ldl
endif
	rm -f resources/FlexSID-User-Manual.c
#C64 version of the user-manual (80-column reader):
	$(CC)  resources/tools/textconvert.c  -o resources/tools/textconvert
	resources/tools/textconvert resources/FlexSID-User-Manual.txt resources/FlexSID-User-Manual.vid resources/FlexSID-User-Manual.chr
	ca65  assembly/usermanual.asm  -o assembly/usermanual.o  $(CA65_OPTIONS)
	cl65  assembly/usermanual.o  -u  __EXEHDR__  -t c64  -C assembly/usermanual-ca65.cfg  -o assembly/usermanual.prg
	resources/tools/compress64kSFX  assembly/usermanual.prg  user-manual.prg
	rm -f resources/FlexSID-User-Manual.vid resources/FlexSID-User-Manual.chr assembly/usermanual.o \
      resources/tools/textconvert  # assembly/usermanual.prg


manual-win:  #Windows-version of the user-manual:
	i686-w64-mingw32-gcc  -c maincode/usermanual.c  -o usermanual.o  -DVERSION=\"$(VERSION)\"  -I/usr/local/sdlmingw/include
	i686-w64-mingw32-gcc  usermanual.o resources/FlexSID-icon.res  -o usermanual.exe  -s  \
                          -L/usr/local/sdlmingw/lib -lmingw32 -mwindows -lSDLmain -lSDL
	rm -f resources/FlexSID-User-Manual.c usermanual.o


createdisk:
	c1541 -format "flexsid,hm" d64 FlexSID-C64.d64
	c1541 -attach FlexSID-C64.d64 -write resources/fastload.prg !


disk: createdisk FlexSID-unpacked-normal.prg
	c1541 -attach FlexSID-C64.d64 -write FlexSID-unpacked-normal.prg flexsid
	for inputfile in resources/examples/d64-shortnamed/*.flx ; do outputfile=$${inputfile##*/} ; \
     c1541 -attach FlexSID-C64.d64 -write $$inputfile $${outputfile%} ; done;
#	for inputfile in resources/examples/d64-shortnamed/*.exe ; do outputfile=$${inputfile##*/} ; \
#     c1541 -attach FlexSID-C64.d64 -write $$inputfile $${outputfile%} ; done;


selector:
	$(CC)  platform/selector/selector.c  platform/selector/hgui.c  -s  -o flexsid  -lX11 \
         -DHGUI_SELECTWIDGETS  -DHGUI_PICTURES  -DHGUI_BUTTONS  -DHGUI_TEXTLINES
#	./FlexSID


package:
#add manual and examples to d64
	c1541 -attach FlexSID-C64.d64 -write user-manual.prg user-manual
	for inputfile in resources/examples/d64-shortnamed/*.flx ; do outputfile=$${inputfile##*/} ; \
     c1541 -attach FlexSID-C64.d64 -write $$inputfile $${outputfile%} ; done;
#	for inputfile in resources/examples/d64-shortnamed/*.exe ; do outputfile=$${inputfile##*/} ; \
#     c1541 -attach FlexSID-C64.d64 -write $$inputfile $${outputfile%} ; done;
#Linux .deb package
	mkdir -p package/opt/FlexSID package/opt/FlexSID/examples package/opt/FlexSID/tutorials \
             package/usr/local/bin package/usr/share/icons package/usr/share/pixmaps \
             package/usr/share/applications package/usr/share/mime/packages package/DEBIAN
	cp -a FlexSID flexsid  FlexSID-extra.prg FlexSID-normal.prg  FlexSID-medium.prg \
              FlexSID-light.prg FlexSID-bare.prg \
              FlexSID-C64.d64 resources/FlexSID-User-Manual.txt usermanual package/opt/FlexSID/
	cp -a FlexSID-extra FlexSID-normal FlexSID-medium FlexSID-light FlexSID-bare  package/opt/FlexSID/
	ln -s /opt/FlexSID/flexsid package/usr/local/bin
	ln -s /opt/FlexSID/FlexSID package/usr/local/bin
	ln -s /opt/FlexSID/FlexSID package/usr/local/bin/FlexSID-extra
	ln -s /opt/FlexSID/FlexSID package/usr/local/bin/FlexSID-normal
	ln -s /opt/FlexSID/FlexSID package/usr/local/bin/FlexSID-medium
	ln -s /opt/FlexSID/FlexSID package/usr/local/bin/FlexSID-light
	ln -s /opt/FlexSID/FlexSID package/usr/local/bin/FlexSID-bare
	cp resources/FlexSID-icon.png  package/usr/share/icons/
	cp resources/FlexSID-icon.png  package/usr/share/pixmaps/
	cp resources/examples/*.flx resources/examples/*.prg resources/examples/*.sid  package/opt/FlexSID/examples/
	cp resources/tutorials/*.flx  package/opt/FlexSID/tutorials/
	cp resources/FlexSID.desktop resources/FlexSID-C64.desktop  package/usr/share/applications/
	cp resources/x-FlexSID-extension-flx.xml  package/usr/share/mime/packages/
	echo "Package: flexsid\nVersion: $(VERSION)\nSection: custom\nPriority: optional\nArchitecture: \
          all\nEssential: no\nInstalled-Size: $$(du -s --apparent-size package | cut -f 1)\nDepends: $(DEPENDS)\nMaintainer: Hermit\nDescription: FlexSID" \
          > package/DEBIAN/control
	dpkg-deb --build package && mv package.deb flexsid-$(VERSION)-$(ARCHITECTURE).deb
	rm -r -f package

package-win: #Windows zip package
	mkdir -p FlexSID-win-$(VERSION) FlexSID-win-$(VERSION)/examples FlexSID-win-$(VERSION)/tutorials
	cp FlexSID-*.exe FlexSID-*.prg FlexSID-C64.d64 resources/SDL.dll \
           resources/FlexSID-User-Manual.txt usermanual.exe FlexSID-win-$(VERSION)/
	cp resources/examples/*.flx resources/examples/*.prg resources/examples/*.sid  FlexSID-win-$(VERSION)/examples/
	cp resources/tutorials/*.flx  FlexSID-win-$(VERSION)/tutorials/
	zip -r FlexSID-win-$(VERSION).zip FlexSID-win-$(VERSION)
	rm -r -f FlexSID-win-$(VERSION)


cleanpackage:
	-rm -f *.deb FlexSID FlexSID-C64.d64

clean:
	-rm -f FlexSID flexsid \
           FlexSID*.exe FlexSID*.prg FlexSID.c64 FlexSID.asm FlexSID.o FlexSID-win.o \
           assembly/player.o assembly/special.o assembly/runexe*.o assembly/runexe*.prg untitled.disasm SDL.dll
	-rm -r -f FlexSID-unpacked.prg assembly/FlexSIDprg.map $(SYMDEF) $(BIN2ARRAY) $(COMPRESS)  \
              package  resources/FlexSID.h
	rm -f resources/FlexSID-User-Manual.vid resources/FlexSID-User-Manual.chr resources/tools/textconvert assembly/usermanual.o \
          assembly/usermanual.prg user-manual.prg resources/FlexSID-User-Manual.c usermanual usermanual.o usermanual.exe
	rm -f  resources/FlexSID_*.o resources/ExampleTune_*.o resources/runexe_*.o  # resources/FlexSID_*.prg_cmp
	rm -f platform/SID_Waveform*.o
	rm -f  resources/tools/*.prg.o


install:
	#chmod 755 ./FlexSID
	dpkg -r flexsid && dpkg -i flexsid-$(VERSION)-$(ARCHITECTURE).deb  # cp FlexSID FlexSID.prg /usr/local/bin


uninstall:
	dpkg -r flexsid


purge: clean  uninstall  # cleanpackage


FORCE:
