#!/bin/sh
# SPDX-License-Identifier: ACSL
# SPDX-FileCopyrightText: © 2016 Antoine Le Gonidec <vv221@dotslashplay.it>
set -o errexit

###
# Neverwinter Nights
# send your bug reports to bugs@dotslashplay.it
###

script_version=20260528.1

PLAYIT_COMPATIBILITY_LEVEL='2.35'

GAME_ID='neverwinter-nights-1'
GAME_NAME='Neverwinter Nights'

ARCHIVE_BASE_DE_0_NAME='setup_nwn_diamond_german_2.1.0.21.exe'
ARCHIVE_BASE_DE_0_MD5='63a32f4fdb2939e73ac40d80f5798e28'
ARCHIVE_BASE_DE_0_EXTRACTOR='innoextract'
ARCHIVE_BASE_DE_0_EXTRACTOR_OPTIONS='--gog'
ARCHIVE_BASE_DE_0_PART1_NAME='setup_nwn_diamond_german_2.1.0.21-1.bin'
ARCHIVE_BASE_DE_0_PART1_MD5='e6c50d030b046c05ccf87601844ccc23'
ARCHIVE_BASE_DE_0_PART1_TYPE='rar'
ARCHIVE_BASE_DE_0_SIZE='4400000'
ARCHIVE_BASE_DE_0_VERSION='1.68-gog2.1.0.21'

ARCHIVE_BASE_EN_0_NAME='setup_nwn_diamond_2.1.0.21.exe'
ARCHIVE_BASE_EN_0_MD5='cd809b9d22022adb01b0d1d70c5afa8e'
ARCHIVE_BASE_EN_0_EXTRACTOR='innoextract'
ARCHIVE_BASE_EN_0_EXTRACTOR_OPTIONS='--gog'
ARCHIVE_BASE_EN_0_PART1_NAME='setup_nwn_diamond_2.1.0.21-1.bin'
ARCHIVE_BASE_EN_0_PART1_MD5='ce60bf104cc6082fe79d6f0bd7b48f51'
ARCHIVE_BASE_EN_0_PART1_TYPE='rar'
ARCHIVE_BASE_EN_0_SIZE='5100000'
ARCHIVE_BASE_EN_0_VERSION='1.69-gog2.1.0.21'

ARCHIVE_BASE_ES_0_NAME='setup_nwn_diamond_spanish_2.1.0.21.exe'
ARCHIVE_BASE_ES_0_MD5='70448f984b66a814bda712ecfef5977e'
ARCHIVE_BASE_ES_0_EXTRACTOR='innoextract'
ARCHIVE_BASE_ES_0_EXTRACTOR_OPTIONS='--gog'
ARCHIVE_BASE_ES_0_PART1_NAME='setup_nwn_diamond_spanish_2.1.0.21-1.bin'
ARCHIVE_BASE_ES_0_PART1_MD5='3b6dee19655a1280273c5d0652f74ab5'
ARCHIVE_BASE_ES_0_PART1_TYPE='rar'
ARCHIVE_BASE_ES_0_SIZE='4400000'
ARCHIVE_BASE_ES_0_VERSION='1.68-gog2.1.0.21'

ARCHIVE_BASE_FR_0_NAME='setup_nwn_diamond_french_2.1.0.21.exe'
ARCHIVE_BASE_FR_0_MD5='caadc0f809e10ddf781cacbebd1b25d9'
ARCHIVE_BASE_FR_0_EXTRACTOR='innoextract'
ARCHIVE_BASE_FR_0_EXTRACTOR_OPTIONS='--gog'
ARCHIVE_BASE_FR_0_PART1_NAME='setup_nwn_diamond_french_2.1.0.21-1.bin'
ARCHIVE_BASE_FR_0_PART1_MD5='aeb4b99635bdc046560477b2b11307e3'
ARCHIVE_BASE_FR_0_PART1_TYPE='rar'
ARCHIVE_BASE_FR_0_SIZE='4300000'
ARCHIVE_BASE_FR_0_VERSION='1.68-gog2.1.0.21'

ARCHIVE_BASE_PL_0_NAME='setup_nwn_diamond_polish_2.1.0.21.exe'
ARCHIVE_BASE_PL_0_MD5='5779b5c690984a79c617efc7649e66a3'
ARCHIVE_BASE_PL_0_EXTRACTOR='innoextract'
ARCHIVE_BASE_PL_0_EXTRACTOR_OPTIONS='--gog'
ARCHIVE_BASE_PL_0_PART1_NAME='setup_nwn_diamond_polish_2.1.0.21-1.bin'
ARCHIVE_BASE_PL_0_PART1_MD5='540c20cd68079c7a214af65296b4a8b1'
ARCHIVE_BASE_PL_0_PART1_TYPE='rar'
ARCHIVE_BASE_PL_0_SIZE='4400000'
ARCHIVE_BASE_PL_0_VERSION='1.68-gog2.1.0.21'

CONTENT_PATH_DEFAULT='game'
# TODO: Check if the following fake library is still required.
CONTENT_LIBS_BIN_PATH='lib'
CONTENT_LIBS_BIN_FILES='
libtxc_dxtn.so'
CONTENT_LIBS0_BIN_PATH='miles'
CONTENT_LIBS0_BIN_FILES='
libmss.so
libmss.so.6
libmss.so.6.5.2'
CONTENT_GAME_BIN_FILES='
dmclient
fixinstall
nwmain
nwserver
nwn.ini'
CONTENT_GAME_BIN_PATH='.'
CONTENT_GAME_BIN_FILES='
dmclient
fixinstall
nwmain
nwserver
nwn.ini
miles/mssdsp.flt
miles/mssmp3.asi
miles/msssoft.m3d'
CONTENT_GAME0_BIN_PATH='support/app'
CONTENT_GAME0_BIN_FILES='
nwncdkey.ini'
CONTENT_GAME1_BIN_PATH='.'
CONTENT_GAME1_BIN_FILES='
nwmovies
nwmovies_install.pl'
CONTENT_GAME_L10N_FILES='
*.key
*.tlk
movies/Chap?_Chap?.bik
movies/credits.bik
movies/ending.bik
movies/prelude.bik
movies/prelude_chap1.bik
movies/XP?_*.bik
data/*convo.bif
data/models_??.bif
data/music*.bif
data/templates.bif
data/*voicesets.bif
data/xp1_sounds*.bif
data/xp2_german.bif
data/xp2_french.bif
data/xp2_polish.bif'
CONTENT_DOC_L10N_RELATIVE_PATH='docs'
CONTENT_DOC_L10N_FILES='
*.pdf
*.rtf
*.txt'
CONTENT_GAME_DATA_FILES='
ambient
dmvault
hak
localvault
modules
music
nwm
override
texturepacks
movies/*.bik
data/*.bif'
CONTENT_GAME0_DATA_PATH='.'
CONTENT_GAME0_DATA_FILES='
override'
CONTENT_DOC_DATA_PATH='.'
CONTENT_DOC_DATA_FILES='
*.txt'

USER_PERSISTENT_DIRECTORIES='
portraits
saves
servervault'
USER_PERSISTENT_FILES='
*.ini'
# NWMovies expects the game binary to be writable,
# and it should not be reset to its default state between runs.
USER_PERSISTENT_FILES="$USER_PERSISTENT_FILES
nwmain"

APP_MAIN_EXE='nwmain'
APP_MAIN_ICON='nwn.exe'
# Apply required SDL tweaks.
# TODO: Check if these are still required.
APP_MAIN_PRERUN='
export SDL_MOUSE_RELATIVE=0
export SDL_VIDEO_X11_DGAMOUSE=0
'

PACKAGES_LIST='
PKG_BIN
PKG_L10N
PKG_DATA'
PACKAGES_LIST_NWMOVIES="$PACKAGES_LIST
PKG_NWMOVIES"

PKG_BIN_ARCH='32'
PKG_BIN_DEPENDENCIES_SIBLINGS='
PKG_L10N_BASE
PKG_DATA'
PKG_BIN_DEPENDENCIES_LIBRARIES='
libc.so.6
libGL.so.1
libGLU.so.1
libm.so.6
libpthread.so.0
libSDL-1.2.so.0'

PKG_NWMOVIES_ID="${GAME_ID}-nwmovies"
PKG_NWMOVIES_DESCRIPTION='NWMovies'
PKG_NWMOVIES_ARCH='32'
PKG_NWMOVIES_DEPENDENCIES_SIBLINGS='
PKG_BIN'
# TODO: Check if we can replace mpv with something that is not welcoming AI pollution.
PKG_NWMOVIES_DEPENDENCIES_COMMANDS='
mpv'

PKG_L10N_BASE_ID="${GAME_ID}-l10n"
PKG_L10N_ID_DE="${PKG_L10N_BASE_ID}-de"
PKG_L10N_ID_ES="${PKG_L10N_BASE_ID}-es"
PKG_L10N_ID_EN="${PKG_L10N_BASE_ID}-en"
PKG_L10N_ID_FR="${PKG_L10N_BASE_ID}-fr"
PKG_L10N_ID_PL="${PKG_L10N_BASE_ID}-pl"
PKG_L10N_PROVIDES="
$PKG_L10N_BASE_ID"
PKG_L10N_DESCRIPTION_DE='German localization'
PKG_L10N_DESCRIPTION_ES='Spanish localization'
PKG_L10N_DESCRIPTION_EN='English localization'
PKG_L10N_DESCRIPTION_FR='French localization'
PKG_L10N_DESCRIPTION_PL='Polish localization'

PKG_DATA_ID="${GAME_ID}-data"
PKG_DATA_DESCRIPTION='data'

# Load common functions.

if [ -z "$PLAYIT_LIB2" ]; then
	for playit_lib_dir in \
		"$PWD" \
		"${HOME}/.local/lib/play.it" \
		'/usr/local/lib/play.it' \
		'/usr/lib/play.it'
	do
		playit_lib_path="${playit_lib_dir}/libplayit.sh.2"
		if [ -e "$playit_lib_path" ]; then
			PLAYIT_LIB2="$playit_lib_path"
			break
		fi
	done
fi
if [ -z "$PLAYIT_LIB2" ]; then
	printf '\n\033[1;31mError:\033[0m\n'
	printf 'libplayit.sh.2 not found.\n'
	exit 1
fi
. "$PLAYIT_LIB2"

# Run default initialisation actions.

initialization_default "$@"

# Check for the presence of the game engine archive.

ARCHIVE_REQUIRED_LINUX_COMMON_NAME='nwn-linux-common.tar.gz'
ARCHIVE_REQUIRED_LINUX_COMMON_URL='https://downloads.dotslashplay.it/games/neverwinter-nights-1/'
ARCHIVE_REQUIRED_LINUX_COMMON_MD5='9aa7dae2ba9111c96b10679fa085c66e'
case "$(package_version)" in
	('1.69-'*)
		ARCHIVE_REQUIRED_LINUX_NAME='nwn-linux-1.69.2023-10-07.tar.xz'
		ARCHIVE_REQUIRED_LINUX_URL='https://downloads.dotslashplay.it/games/neverwinter-nights-1/'
		ARCHIVE_REQUIRED_LINUX_MD5='8ea69b40842f9721051d4ddd6510d3b2'
	;;
	('1.68-'*)
		ARCHIVE_REQUIRED_LINUX_NAME='nwn-linux-1.68.2023-10-07.tar.xz'
		ARCHIVE_REQUIRED_LINUX_URL='https://downloads.dotslashplay.it/games/neverwinter-nights-1/'
		ARCHIVE_REQUIRED_LINUX_MD5='12ff7f8604d04194b87cf70832bb86fa'
	;;
esac
archive_initialize_required \
	'ARCHIVE_LINUX_COMMON' \
	'ARCHIVE_REQUIRED_LINUX_COMMON'
archive_initialize_required \
	'ARCHIVE_LINUX' \
	'ARCHIVE_REQUIRED_LINUX'

# Check for the presence of the NWMovies archive.

ARCHIVE_OPTIONAL_NWMOVIES_NAME='nwmovies-mpv.tar.gz'
ARCHIVE_OPTIONAL_NWMOVIES_URL='https://sites.google.com/site/gogdownloader/nwmovies-mpv.tar.gz'
ARCHIVE_OPTIONAL_NWMOVIES_MD5='71f3d88db1cd75665b62b77f7604dce1'
archive_initialize_optional \
	'ARCHIVE_NWMOVIES' \
	'ARCHIVE_OPTIONAL_NWMOVIES'

# Check for the presence of NWMovies build dependencies

if archive_is_available 'ARCHIVE_NWMOVIES'; then
	case "$(messages_language)" in
		('fr')
			message='Contrôle de la présence des dépendances requises pour la compilation de NWMovies…'
		;;
		('en'|*)
			message='Check for the presence of NWMovies build dependencies…'
		;;
	esac
	printf '%s\n' "$message"
	tests_directory="${PLAYIT_WORKDIR}/tests"
	mkdir --parents "$tests_directory"
	test_source="${tests_directory}/build-deps.c"
	test_binary="${tests_directory}/build-deps.so"
	cat > "$test_source" <<-EOF
	#include <dlfcn.h>
	#include <elf.h>
	#include <errno.h>
	#include <fcntl.h>
	#include <libelf.h>
	#include <libgen.h>
	#include <limits.h>
	#include <link.h>
	#include <SDL/SDL.h>
	#include <SDL/SDL_syswm.h>
	#include <SDL/SDL_types.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <string.h>
	#include <sys/mman.h>
	#include <sys/stat.h>
	#include <sys/types.h>
	#include <unistd.h>

	int main () { return 0; }
	EOF
	gcc -shared -Wall -fPIC -ldl -m32 "$test_source" -o "$test_binary"
	rm --recursive "$tests_directory"
fi

# Extract game data.

archive_extraction_default
archive_extraction 'ARCHIVE_LINUX_COMMON'
archive_extraction 'ARCHIVE_LINUX'
if archive_is_available 'ARCHIVE_NWMOVIES'; then
	archive_extraction 'ARCHIVE_NWMOVIES'
fi

# Fix case inconsistencies.

path_archive_contents=$(path_archive_contents)
if [ -e "${path_archive_contents}/dialog.TLK" ]; then
	mv \
		"${path_archive_contents}/dialog.TLK" \
		"${path_archive_contents}/dialog.tlk"
fi
if [ -e "${path_archive_contents}/dialogF.TLK" ]; then
	mv \
		"${path_archive_contents}/dialogF.TLK" \
		"${path_archive_contents}/dialogf.tlk"
fi
for tiles in 'a' 'b' 'c'; do
	if [ -e "${path_archive_contents}/texturepacks/Tiles_TP${tiles}.ERF" ]; then
		mv \
			"${path_archive_contents}/texturepacks/Tiles_TP${tiles}.ERF" \
			"${path_archive_contents}/texturepacks/Tiles_Tp${tiles}.erf"
	fi
done

# Build the NWMovies video player

if archive_is_available 'ARCHIVE_NWMOVIES'; then
	(
		cd "${PLAYIT_WORKDIR}/gamedata/nwmovies"

		case "$(messages_language)" in
			('fr')
				message='Construction du lecteur vidéo NWMovies…'
			;;
			('en'|*)
				message='Building NWMovies video player…'
			;;
		esac
		printf '%s\n' "$message"
		sed --in-place 's/mpv /mpv --fs --no-osc --no-pause /' 'nwplaymovie'
		chmod 755 'nwmovies_install.pl'
		export CFLAGS='-w'
		# TODO: Check if we can byoass this perl script.
		./nwmovies_install.pl build >/dev/null 2>&1
	)
fi

# Include game data.

content_inclusion_icons 'PKG_DATA'
if archive_is_available 'ARCHIVE_NWMOVIES'; then
	PACKAGES_LIST="$PACKAGES_LIST_NWMOVIES"
	# TODO: An identifier more explicit than "GAME1_BIN" should be used.
	path_archive_contents_nwmovies=$(path_archive_contents 'GAME1_BIN')
	# TODO: CONTENT_LIBS_xxx could be used here.
	install -D --mode=644 \
		--target-directory="$(package_path 'PKG_NWMOVIES')$(path_libraries)" \
		"${path_archive_contents_nwmovies}/nwmovies/nwmovies.so" \
		"${path_archive_contents_nwmovies}/nwmovies/libdis/libdisasm.so"
	# TODO: CONTENT_GAME_xxx could be used here.
	install -D --mode=755 \
		"${path_archive_contents_nwmovies}/nwmovies/nwplaymovie" \
		"$(package_path 'PKG_NWMOVIES')$(path_game_data)/nwplaymovie"
	# TODO: CONTENT_DOC_xxx could be used here.
	install -D --mode=644 \
		"${path_archive_contents_nwmovies}/nwmovies/nwmovies.README.txt" \
		"$(package_path 'PKG_NWMOVIES')$(path_documentation)/nwmovies.README.txt"
	rm --recursive \
		"${path_archive_contents_nwmovies}/nwmovies/libdis" \
		"${path_archive_contents_nwmovies}/nwmovies/nwmovies.so" \
		"${path_archive_contents_nwmovies}/nwmovies/nwmovies.README.txt" \
		"${path_archive_contents_nwmovies}/nwmovies/nwplaymovie"
	# NWMovies expects some libraries in hardcoded paths.
	mkdir --parents "$(package_path 'PKG_NWMOVIES')$(path_game_data)/nwmovies/libdis"
	ln --symbolic \
		"$(path_libraries)/libdisasm.so" \
		"$(package_path 'PKG_NWMOVIES')$(path_game_data)/nwmovies/libdis/libdisasm.so"
fi
content_inclusion_default

# Write launchers.

# Play videos using NWMovies, if it is available.
nwmovies_library="$(path_libraries)/nwmovies.so"
APP_MAIN_PRERUN="$(application_prerun 'APP_MAIN')"'
# Play videos using NWMovies, if it is available.
nwmovies_library="'"${nwmovies_library}"'"
if [ -e "$nwmovies_library" ]; then
	export LD_PRELOAD="$nwmovies_library"
fi
'

# Do not copy the game binary into the game prefix,
# as changing it timestamp would cause the initial NWMovies setup to reset.
native_launcher_binary_copy() { return 0; }

launchers_generation

# Build packages.

packages_generation
print_instructions

# Clean up.

working_directory_cleanup

exit 0
