#
# tngp/Makefile
#
# Copyright (C) 2022 bzt
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# @brief The main Makefile
#

# --- set these according to your configuration ---
#USE_MINGWSDL = ../../SDL2-mingw
#USE_DYNLUBS = 1
#USE_DYNSDL = 1
DEBUG = 1
# -------------------------------------------------

TARGET = tngp
ifneq ($(USE_EMCC),)
SRCS = $(filter-out tngs.c tngstui.c tngswin.c tngd.c bin2h.c data.c ogg.c,$(wildcard *.c))
else
SRCS = $(filter-out tngs.c tngstui.c tngswin.c tngd.c bin2h.c data.c,$(wildcard *.c))
endif
OBJS = $(SRCS:.c=.o)
PREFIX ?= usr/
INSTDIR=$(DESTDIR:/=)/$(PREFIX:/=)
LINKAGE = static
ARCH = $(shell uname -m)
TMP = $(ARCH:x86_64=amd64)
TMP2 = $(TMP:aarch64=arm64)
DEBARCH = $(TMP2:armv7l=armhf)
VERSION = $(shell cat version.h|grep tngpver|head -1|cut -d '"' -f 2)

# Emscripten
ifneq ($(USE_EMCC),)
 PACKAGE = emscripten
 LINKAGE = dyn
 CFLAGS = -s USE_SDL=2 -s USE_SDL_MIXER=2 -s USE_OGG=1 -s USE_VORBIS=1 -I/usr/include/SDL2 -I/usr/include/SDL -Wno-unknown-warning-option
# wasm crashes in browser if compiled with -g
 DEBUG=
else
 # MacOS
 ifneq ("$(wildcard /Library/Frameworks/SDL*)","")
  PACKAGE = MacOS
  THEOASM = --enable-asm
  ifneq ($(USE_DYNSDL),)
   CFLAGS = -I/Library/Frameworks/SDL2.framework/Headers -I/Library/Frameworks/SDL2.framework/Versions/A/Headers
   LIBS = -F/Library/Frameworks -framework SDL2
   LINKAGE = static
  else
   # known to have issues and not working properly
   CFLAGS += -I./SDL2/include
   EXTRA += ./SDL2/build/.libs/libSDL2.a
   LINKAGE = static
  endif
 else
  # Windows MinGW
  ifneq ("$(wildcard /bin/*.exe)","")
   PACKAGE = Win
   THEOASM = --disable-asm
   EXTRA = resource.o
   LIBDIRS = -mwindows -static-libgcc
   ifneq ($(USE_DYNLIBS),)
    ifneq ("$(wildcard $(USE_MINGWSDL)/i686-w64-mingw32/include/SDL2/*)","")
     CFLAGS += -I$(USE_MINGWSDL)/i686-w64-mingw32/include/SDL2
     LIBDIRS += -L$(USE_MINGWSDL)/i686-w64-mingw32/lib -L$(USE_MINGWSDL)/i686-w64-mingw32/bin
     LIBS += -lSDL2_mixer -lSDL2 -ltheoradec -ltheora -lvorbisfile -lvorbis -luser32 -lshlwapi -lws2_32
     LINKAGE = dyn
    endif
   else
    LIBS += -Wl,--nxcompat -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive -luser32 -lole32 -lshlwapi -lws2_32 \
     -loleaut32 -lwinmm -limm32 -lsetupapi -luuid -lversion -lm
    LINKAGE = static
    ifeq ($(USE_DYNSDL),)
     ifneq ("$(wildcard $(USE_MINGWSDL)/build/.libs/libSDL2.a)","")
      CFLAGS += -I$(USE_MINGWSDL)/include
      EXTRA += $(USE_MINGWSDL)/build/.libs/libSDL2.a
     else
      CFLAGS += -I./SDL2/include
      EXTRA += ./SDL2/build/.libs/libSDL2.a
     endif
    else
      CFLAGS += -I./SDL2/include
      LIBS += -lSDL2
    endif
   endif
  else
   # Linux
   PACKAGE = Linux
   THEOASM = --enable-asm
   ifneq ($(USE_DYNLIBS),)
    CFLAGS = -I/usr/include/SDL2
    LIBS = -lSDL2_mixer -lSDL2 -ltheoradec -ltheora -lvorbisfile -lvorbis -lm -lpthread
    LINKAGE = dyn
   else
    ifneq ($(USE_DYNSDL),)
     CFLAGS = -I/usr/include/SDL2
     LIBS = -lSDL2 -ldl -lpthread -lm -lmvec
    else
     CFLAGS = -I./SDL2/include
     LIBS = -ldl -lpthread -lm -lmvec
     EXTRA += ./SDL2/build/.libs/libSDL2.a
    endif
    LINKAGE = static
   endif
  endif
 endif
 ifeq ("$(LINKAGE)","static")
  EXTRA += ./SDL2_mixer/build/.libs/libSDL2_mixer.a ./libvorbis/lib/.libs/libvorbisfile.a ./libvorbis/lib/.libs/libvorbis.a \
   ./libtheora/lib/.libs/libtheoradec.a ./libtheora/lib/.libs/libtheora.a
 endif
 CFLAGS += -Wall -Wextra -Wno-pragmas -ansi -pedantic
endif
CFLAGS += -ISDL2_mixer/include -Ilibtheora/include -Ilibvorbis/include -I. -D_$(PACKAGE)_=1 -ffunction-sections -fdata-sections
ifeq ($(DEBUG),)
 CFLAGS += -O3
else
 CFLAGS += -g -DDEBUG=1
endif

ASSETS = misc/logo.png misc/default.sfn misc/err.ogg misc/chime.ogg
DOBJS = ogg.o theora.o tng.o zlib.o tngd.o
SOBJS = tngs.o tng.o files.o world.o script.o map.o jsonc.o zlib.o

all: configure todo mbed objs $(TARGET)

objs: $(EXTRA) data.c data.o $(OBJS)

configure:
ifeq ("$(LINKAGE)","")
	@echo "No SDL2 library found. Install libsdl2-dev, or do not set USE_DYNLIBS nor USE_DYNSDL."
	@false
endif

todo:
	@grep -n -e 'TODO:' -e 'FIXME:' $(SRCS) tngs.c tngstui.c tngswin.c tngd.c *.h > ../TODO.txt || true

SDL2/build/.libs/libSDL2.a:
ifeq ($(wildcard SDL2/configure),)
	@cd SDL2 && ./autogen.sh
endif
ifeq ($(wildcard SDL2/Makefile),)
	@#dbus call in SDL2/src/core/linux/SDL_dbus.c:140 is leaking pretty badly. We don't need dbus anyway
	@#can't compile SDL2 with the latest wayland, the wl tools are buggy. Remove --disable-video-wayland once wl gets fixed
	@cd SDL2 && ./configure --disable-shared --enable-static --disable-dbus --disable-video-wayland
endif
	@make --no-print-directory -s -C SDL2 all

libvorbis/lib/.libs/libvorbisfile.a:

libvorbis/lib/.libs/libvorbis.a:
ifeq ($(wildcard libvorbis/Makefile),)
	@cd libvorbis && ./configure --disable-shared --enable-static --disable-docs --disable-examples --disable-oggtest \
	--with-ogg-includes=$(abspath .)
endif
	@make --no-print-directory -s -C libvorbis all

SDL2_mixer/build/.libs/libSDL2_mixer.a: SDL2/build/.libs/libSDL2.a libvorbis/lib/.libs/libvorbis.a
ifeq ($(wildcard SDL2_mixer/Makefile),)
	@cd SDL2_mixer && SDL2_CONFIG=$(abspath ../SDL2/sdl2-config) ./configure --disable-shared --enable-static --disable-sdltest \
	--disable-music-cmd --disable-music-wave --disable-music-mod --disable-music-mod-xmp-lite \
	--disable-music-mod-xmp --disable-music-mod-xmp-shared --disable-music-mod-modplug --disable-music-mod-mikmod --disable-music-midi \
	--enable-music-ogg --disable-music-ogg-shared --disable-music-flac --disable-music-flac-shared --disable-music-mp3 \
	--disable-music-mp3-mpg123 --disable-music-mp3-mpg123-shared --disable-music-mp3-mad-gpl --disable-music-opus \
	--disable-music-opus-shared --includedir=$(abspath ./libvorbis/include) --includedir=$(abspath ./SDL2/include)
endif
	@make --no-print-directory -s -C SDL2_mixer all

./libtheora/lib/.libs/libtheoradec.a:

./libtheora/lib/.libs/libtheora.a:
ifeq ($(wildcard libtheora/Makefile),)
	@#using --enable-asm under mingw32 makes th_decode_packetin() crash...
	@cd libtheora && ./configure --disable-shared --enable-static --disable-telemetry --disable-doc --disable-spec \
	--disable-valgrind-testing $(THEOASM) --disable-encode --disable-oggtest --disable-examples \
	--includedir=$(abspath ./libvorbis/include) --includedir=$(abspath .) --with-ogg-includes=$(abspath .)
endif
	@make --no-print-directory -s -C libtheora all

mbed:
	@make --no-print-directory -s -C mbedtls all

data.c: bin2h.c $(ASSETS) misc/gamecontrollerdb.txt
ifneq ($(USE_EMCC),)
	@cc bin2h.c -o bin2h
else
	@$(CC) bin2h.c -o bin2h
endif
	@cat misc/gamecontrollerdb.txt | grep "platform:" | gzip >gamecontrollerdb
	./bin2h $(ASSETS) gamecontrollerdb
	@rm bin2h bin2h.exe gamecontrollerdb 2>/dev/null || true

resource.o:
	windres -i misc/tngp.rc -o resource.o

zlib.o: zlib.c
	$(CC) $(CFLAGS) -Wno-implicit-fallthrough -c -o $@ $<

theora.o: theora.c theora.h
	$(CC) $(CFLAGS) -Ilibtheora/include -Ilibvorbis/include -c -o $@ $<

tngp.o: tngp.c world.h lang.h $(wildcard lang_*.h)
ifneq ($(USE_DYNSDL),)
	$(CC) $(CFLAGS) -DBUILD="$(shell date +"%Y%j")" -D_DYNSDLFIX_ -c -o $@ $<
else
	$(CC) $(CFLAGS) -DBUILD="$(shell date +"%Y%j")" -c -o $@ $<
endif

tngd.o: tngd.c world.h
ifneq ($(USE_DYNSDL),)
	$(CC) $(CFLAGS) -DBUILD="$(shell date +"%Y%j")" -D_DYNSDLFIX_ -c -o $@ $<
else
	$(CC) $(CFLAGS) -DBUILD="$(shell date +"%Y%j")" -c -o $@ $<
endif

%: %.c data.c world.h
	$(CC) $(CFLAGS) $< -c $@

$(TARGET): $(OBJS)
ifeq ($(USE_EMCC),)
	$(CC) $(LIBDIRS) $(OBJS) data.o mbedtls/*.o $(EXTRA) -o $(TARGET) $(LIBS) -Wl,--gc-sections
ifeq ($(DEBUG),)
ifeq ("$(PACKAGE)","Win")
	@strip $(TARGET).exe
else
	@strip $(TARGET)
endif
endif
endif

ddata:
	@cc bin2h.c -o bin2h
	./bin2h misc/tngd.png misc/default.sfn
	$(CC) $(CFLAGS) -c -o data.o data.c
	@rm bin2h bin2h.exe data.c 2>/dev/null || true

tngd: ddata $(EXTRA) $(DOBJS)
ifeq ($(USE_EMCC),)
ifeq ("$(PACKAGE)","Win")
	windres -i misc/tngd.rc -o resource.o
endif
	$(CC) $(LIBDIRS) $(DOBJS) data.o mbedtls/*.o $(EXTRA) -o tngd $(LIBS) -Wl,--gc-sections
ifeq ($(DEBUG),)
ifeq ("$(PACKAGE)","Win")
	@strip tngd.exe
else
	@strip tngd
endif
endif
else
	@echo "Not available with emscripten."
endif

certs.h:
	@# workaround an openssl bug: req -newkey doesn't care about -outform
	openssl genrsa -out key.pem 2048
	openssl rsa -in key.pem -outform DER -out key.der
	openssl req -outform DER -keyform DER -key key.der -sha256 -x509 -days 36500 -subj '/C=EU/O=TirNanoG/CN=localhost' -out crt.der
	@cc bin2h.c -o bin2h
	./bin2h -o certs.h crt.der key.der
	@rm bin2h bin2h.exe crt.der key.der key.pem 2>/dev/null || true

tngs: mbed certs.h world.h tngs.c tngs.h tngp.h tngstui.c tngswin.c $(OBJS)
ifeq ($(USE_EMCC),)
	$(CC) $(CFLAGS) -Wno-format -DBUILD="$(shell date +"%Y%j")" -c tngs.c -o tngs.o
ifeq ("$(PACKAGE)","Win")
	$(CC) $(CFLAGS) -c tngswin.c -o tngswin.o
	@windres -i misc/tngs.rc -o tngsrc.o
	$(CC) $(LIBDIRS) tngswin.o tngsrc.o $(SOBJS) mbedtls/*.o -o tngs -Wl,--nxcompat -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive -luser32 -lws2_32 -liphlpapi
	@rm tngsrc.o 2>/dev/null || true
else
	$(CC) $(CFLAGS) -c tngstui.c -o tngstui.o
	$(CC) $(LIBDIRS) tngstui.o $(SOBJS) mbedtls/*.o -o tngs -lpthread
endif
ifeq ($(DEBUG),)
ifeq ("$(PACKAGE)","Win")
	@strip tngs.exe
else
	@strip tngs
endif
endif
else
	@echo "Not available with emscripten."
endif

test:
	valgrind --suppressions=libSDL.supp --leak-check=full --show-leak-kinds=all --num-callers=20 ./tngp -vvTTT ~/TirNanoG/base/game.tng

install: $(TARGET)
ifneq ("$(INSTDIR)","")
	@strip $(TARGET)
	install -m 755 -g bin $(TARGET) $(INSTDIR)/bin
	@mkdir -p $(INSTDIR)/share/games 2>/dev/null || true
	@chmod 777 $(INSTDIR)/share/games 2>/dev/null || true
	@mkdir -p $(INSTDIR)/share/man/man1 $(INSTDIR)/share/icons/hicolor/32x32/apps 2>/dev/null || true
	cp misc/tngp.1.gz $(INSTDIR)/share/man/man1
	cp misc/tngp.png $(INSTDIR)/share/icons/hicolor/32x32/apps
else
	@echo "INSTDIR variable not set, not installing."
	@false
endif

package:
ifeq ("$(PACKAGE)","Linux")
	@strip $(TARGET)
	@mkdir -p bin share/man/man1 share/icons/hicolor/32x32/apps
	@cp $(TARGET) bin
	@cp misc/tngp.1.gz share/man/man1
	@cp misc/tngp.png share/icons/hicolor/32x32/apps
	tar -czvf ../$(TARGET)-$(ARCH)-linux-$(LINKAGE).tgz bin share
	@rm -rf bin share
ifneq ($(wildcard tngs),)
	@strip tngs
	@mkdir -p bin share/man/man1
	@cp tngs bin
	@cp misc/tngs.1.gz share/man/man1
	tar -czvf ../tngs-$(ARCH)-linux-$(LINKAGE).tgz bin share
	@rm -rf bin share
endif
else
ifeq ("$(PACKAGE)","Win")
	@strip $(TARGET).exe
	@mkdir TirNanoG
	@cp $(TARGET).exe TirNanoG/$(TARGET).exe
	@rm ../$(TARGET)-i686-win-$(LINKAGE).zip 2>/dev/null || true
	zip -r ../$(TARGET)-i686-win-$(LINKAGE).zip TirNanoG
	@rm -rf TirNanoG
ifneq ($(wildcard tngs.exe),)
	@strip tngs.exe
	@mkdir TirNanoG
	@cp tngs.exe TirNanoG/tngs.exe
	@rm ../tngs-i686-win-$(LINKAGE).zip 2>/dev/null || true
	zip -r ../tngs-i686-win-$(LINKAGE).zip TirNanoG
	@rm -rf TirNanoG
endif
else
ifeq ("$(PACKAGE)","MacOS")
	@strip $(TARGET)
	@mkdir TirNanoG.app TirNanoG.app/Contents TirNanoG.app/Contents/MacOS TirNanoG.app/Contents/Resources
	@cp $(TARGET) TirNanoG.app/Contents/MacOS
	@cp misc/tngp.icns TirNanoG.app/Contents/Resources
	@rm ../$(TARGET)-intel-macos-$(LINKAGE).zip
	zip -r ../$(TARGET)-intel-macos-$(LINKAGE).zip TirNanoG.app
	@rm -rf TirNanoG.app
else
endif
endif
endif

deb:
ifeq ("$(PACKAGE)$(USE_DYNSDL)","Linux1")
ifneq ($(wildcard tngp),)
	@strip $(TARGET)
	@rm -rf DEBIAN usr 2>/dev/null || true
	@mkdir -p DEBIAN usr/bin usr/share/applications usr/share/man/man1 usr/share/icons/hicolor/32x32/apps
	@cp $(TARGET) usr/bin
	@cp misc/tngp.1.gz usr/share/man/man1
	@cp misc/tngp.png usr/share/icons/hicolor/32x32/apps
	@cat misc/tngp_control | sed s/ARCH/$(DEBARCH)/g | sed s/VERSION/$(VERSION)/g | sed s/SIZE/`du -s usr|cut -f 1`/g >DEBIAN/control
	@md5sum `find usr -type f` >DEBIAN/md5sums
	@cp ../LICENSE DEBIAN/copyright
	@echo "2.0" >debian-binary
	@tar -czvf data.tar.gz usr
	@tar -C DEBIAN -czvf control.tar.gz control copyright md5sums
	@ar r ../tngp_$(VERSION)-$(DEBARCH).deb debian-binary control.tar.gz data.tar.gz
	@rm -rf debian-binary control.tar.gz data.tar.gz DEBIAN usr
	@echo "deb     tngp_$(VERSION)-$(DEBARCH).deb"
endif
ifneq ($(wildcard tngs),)
	@strip tngs
	@rm -rf DEBIAN usr 2>/dev/null || true
	@mkdir -p DEBIAN usr/bin usr/share/man/man1
	@cp tngs usr/bin
	@cp misc/tngs.1.gz usr/share/man/man1
	@cat misc/tngs_control | sed s/ARCH/$(DEBARCH)/g | sed s/VERSION/$(VERSION)/g | sed s/SIZE/`du -s usr|cut -f 1`/g >DEBIAN/control
	@md5sum `find usr -type f` >DEBIAN/md5sums
	@cp ../LICENSE DEBIAN/copyright
	@echo "2.0" >debian-binary
	@tar -czvf data.tar.gz usr
	@tar -C DEBIAN -czvf control.tar.gz control copyright md5sums
	@ar r ../tngs_$(VERSION)-$(DEBARCH).deb debian-binary control.tar.gz data.tar.gz
	@rm -rf debian-binary control.tar.gz data.tar.gz DEBIAN usr
	@echo "deb     tngs_$(VERSION)-$(DEBARCH).deb"
endif
else
	@echo "Only available under Linux with USE_DYNSDL=1."
	@false
endif

clean:
	@rm $(TARGET) $(TARGET).exe tngs tngs.exe tngd tngd.exe data.c data.h *.o 2>/dev/null || true

distclean: clean
	@make -C mbedtls clean || true
	@make -C SDL2_mixer distclean || true
	@make -C libvorbis distclean || true
	@rm -rf libvorbis/auto*cache libvorbis/lib/.deps 2>/dev/null || true
	@make -C libtheora distclean || true
	@make -C SDL2 distclean || true
	@rm SDL2/sdl2-config-version.cmake SDL2/sdl2-config.cmake SDL2/sdl2.pc 2>/dev/null || true
