# Package metadata.
TITLE       := NP2kai PS4
RELEASE_VERSION := 1.0
VERSION         := 01.00
TITLE_ID    := BREW00984
CONTENT_ID  := IV0000-BREW00984_00-NP2KAIBOOTSTRAP0

# NP2kai and libretro-common static libraries.
CORE_DIR     := third_party/NP2kai/sdl
CORE_LIB     := $(CORE_DIR)/np2kai_libretro_ps4.a
COMMON_LIB   := build/ps4-libretro-common/libretro_common_ps4.a
CORE_INCLUDE := $(CORE_DIR)/libretro/libretro-common/include

# Libraries linked into the ELF.
LIBS        := -lc -lkernel -lc++ -lSceUserService -lSceVideoOut -lSceAudioOut -lScePad -lSceSysmodule -lSceKeyboard -lSceFreeType -lSDL2 -lSDL2_image

# Additional compile flags.
EXTRAFLAGS  := -Ithird_party/NP2kai/sdl/libretro/libretro-common/include -O3 -DNDEBUG -march=btver2 -mtune=btver2 -fomit-frame-pointer

# Asset and module directories.
ASSETS      := $(shell find assets -type f ! -path 'assets/games/*' ! -path 'assets/system/np2kai/*.rom' ! -path 'assets/system/np2kai/*.ROM' ! -path 'assets/system/np2kai/font.bmp')
LIBMODULES  := sce_module/libc.prx sce_module/libSceFios2.prx
OPENORBIS_MODULE_DIR = $(TOOLCHAIN)/src/modules

# Root vars.
TOOLCHAIN   := $(OO_PS4_TOOLCHAIN)
PROJDIR     := SDL2
COMMONDIR   := $(TOOLCHAIN)/samples/_common
INTDIR      := $(PROJDIR)/x64/Debug

# Define objects to build.
CFILES      := $(wildcard $(PROJDIR)/*.c)
CPPFILES    := $(wildcard $(PROJDIR)/*.cpp)
COMMONFILES :=
OBJS        := $(patsubst $(PROJDIR)/%.c, $(INTDIR)/%.o, $(CFILES)) $(patsubst $(PROJDIR)/%.cpp, $(INTDIR)/%.o, $(CPPFILES)) $(patsubst $(COMMONDIR)/%.cpp, $(INTDIR)/%.o, $(COMMONFILES))

# Define final C/C++ flags.
CFLAGS      := --target=x86_64-pc-freebsd12-elf -fPIC -funwind-tables -c $(EXTRAFLAGS) -isysroot $(TOOLCHAIN) -isystem $(TOOLCHAIN)/include
CXXFLAGS    := $(CFLAGS) -isystem $(TOOLCHAIN)/include/c++/v1
LDFLAGS     := -m elf_x86_64 -pie --script $(TOOLCHAIN)/link.x --eh-frame-hdr -L$(TOOLCHAIN)/lib $(LIBS) $(TOOLCHAIN)/lib/crt1.o

# Create the intermediate directory.
_unused     := $(shell mkdir -p $(INTDIR))

# Check for Linux vs macOS and account for clang/ld path.
UNAME_S     := $(shell uname -s)

ifeq ($(UNAME_S),Linux)
	CC      := clang
	CCX     := clang++
	LD      := ld.lld
	CDIR    := linux
endif

ifeq ($(UNAME_S),Darwin)
	CC      := /usr/local/opt/llvm/bin/clang
	CCX     := /usr/local/opt/llvm/bin/clang++
	LD      := /usr/local/opt/llvm/bin/ld.lld
	CDIR    := macos
endif

all: $(CONTENT_ID).pkg

.PHONY: prepare-openorbis-modules
prepare-openorbis-modules: sce_sys/about/right.sprx $(LIBMODULES)

sce_sys/about/right.sprx:
	@mkdir -p $(@D)
	@test -f "$(OPENORBIS_MODULE_DIR)/right.sprx" || \
		(echo "ERROR: falta $(OPENORBIS_MODULE_DIR)/right.sprx" >&2; exit 1)
	cp "$(OPENORBIS_MODULE_DIR)/right.sprx" "$@"

sce_module/libc.prx:
	@mkdir -p $(@D)
	@test -f "$(OPENORBIS_MODULE_DIR)/libc.prx" || \
		(echo "ERROR: falta $(OPENORBIS_MODULE_DIR)/libc.prx" >&2; exit 1)
	cp "$(OPENORBIS_MODULE_DIR)/libc.prx" "$@"

sce_module/libSceFios2.prx:
	@mkdir -p $(@D)
	@test -f "$(OPENORBIS_MODULE_DIR)/libSceFios2.prx" || \
		(echo "ERROR: falta $(OPENORBIS_MODULE_DIR)/libSceFios2.prx" >&2; exit 1)
	cp "$(OPENORBIS_MODULE_DIR)/libSceFios2.prx" "$@"

.PHONY: validate-package-metadata
validate-package-metadata: prepare-openorbis-modules
	python3 tools/validate-ps4-package-metadata.py \
		--version "$(VERSION)" \
		--title-id "$(TITLE_ID)" \
		--content-id "$(CONTENT_ID)" \
		--right-sprx sce_sys/about/right.sprx \
		--icon sce_sys/icon0.png

$(CONTENT_ID).pkg: pkg.gp4
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core pkg_build $< .

pkg.gp4: eboot.bin sce_sys/about/right.sprx sce_sys/param.sfo sce_sys/icon0.png $(LIBMODULES) $(ASSETS) | validate-package-metadata
	$(TOOLCHAIN)/bin/$(CDIR)/create-gp4 -out $@ --content-id=$(CONTENT_ID) --files "$^"
	./repair-gp4-rootdir.py $@

sce_sys/param.sfo: Makefile
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_new $@
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ APP_TYPE --type Integer --maxsize 4 --value 1
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ APP_VER --type Utf8 --maxsize 8 --value '$(VERSION)'
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ ATTRIBUTE --type Integer --maxsize 4 --value 0
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ CATEGORY --type Utf8 --maxsize 4 --value 'gd'
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ CONTENT_ID --type Utf8 --maxsize 48 --value '$(CONTENT_ID)'
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ DOWNLOAD_DATA_SIZE --type Integer --maxsize 4 --value 0
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ SYSTEM_VER --type Integer --maxsize 4 --value 0
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ TITLE --type Utf8 --maxsize 128 --value '$(TITLE)'
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ TITLE_ID --type Utf8 --maxsize 12 --value '$(TITLE_ID)'
	$(TOOLCHAIN)/bin/$(CDIR)/PkgTool.Core sfo_setentry $@ VERSION --type Utf8 --maxsize 8 --value '$(VERSION)'

$(CORE_LIB):
	./build-ps4-core.sh

$(COMMON_LIB):
	./build-libretro-common-ps4.sh

eboot.bin: $(INTDIR) $(OBJS) $(CORE_LIB) $(COMMON_LIB)
	$(LD) $(INTDIR)/*.o \
		--whole-archive $(CORE_LIB) --no-whole-archive \
		--start-group $(COMMON_LIB) --end-group \
		-o $(INTDIR)/$(PROJDIR).elf $(LDFLAGS)
	$(TOOLCHAIN)/bin/$(CDIR)/create-fself -in=$(INTDIR)/$(PROJDIR).elf -out=$(INTDIR)/$(PROJDIR).oelf --eboot "eboot.bin" --paid 0x3800000000000011

$(INTDIR)/%.o: $(PROJDIR)/%.c
	$(CC) $(CFLAGS) -o $@ $<

$(INTDIR)/%.o: $(PROJDIR)/%.cpp
	$(CCX) $(CXXFLAGS) -o $@ $<

$(INTDIR)/%.o: $(COMMONDIR)/%.c
	$(CCX) $(CXXFLAGS) -o $@ $<

$(INTDIR)/%.o: $(COMMONDIR)/%.cpp
	$(CCX) $(CXXFLAGS) -o $@ $<

clean:
	rm -f $(CONTENT_ID).pkg pkg.gp4 pkg/sce_sys/param.sfo eboot.bin \
		$(INTDIR)/$(PROJDIR).elf $(INTDIR)/$(PROJDIR).oelf $(OBJS)

clean-common:
	rm -rf build/ps4-libretro-common

.PHONY: clean-openorbis-modules
clean-openorbis-modules:
	rm -f sce_module/libc.prx sce_module/libSceFios2.prx sce_sys/about/right.sprx

# v0.37 downloaded external sources into these directories. Nothing writes
# them any more; the rule stays so an upgraded tree can be cleaned in place.
.PHONY: clean-native-keyboard
clean-native-keyboard:
	rm -rf build/native-keyboard third_party/native-keyboard-src
