# Print the snippet starting pulseaudio if it is available
# USAGE: launcher_unity3d_pulseaudio_start
launcher_unity3d_pulseaudio_start() {
	cat <<- 'EOF'
	# Start pulseaudio if it is available
	pulseaudio_is_available() {
	    command -v pulseaudio >/dev/null 2>&1
	}
	if pulseaudio_is_available; then
	    if ! pulseaudio --check; then
	        touch .stop_pulseaudio_on_exit
	    fi
	    pulseaudio --start
	fi

	EOF
}

# Print the snippet stopping pulseaudio if it has been started for this game session
# USAGE: launcher_unity3d_pulseaudio_stop
launcher_unity3d_pulseaudio_stop() {
	cat <<- 'EOF'
	# Stop pulseaudio if it has been started for this game session
	if [ -e .stop_pulseaudio_on_exit ]; then
	    pulseaudio --kill
	    rm .stop_pulseaudio_on_exit
	fi

	EOF
}

# Print the snippet hiding libpulse-simple.so.0 if pulseaudio is not available
# USAGE: launcher_unity3d_pulseaudio_hide_libpulse
launcher_unity3d_pulseaudio_hide_libpulse() {
	cat <<- 'EOF'
	# Work around crash on launch related to libpulse
	# Some Unity3D games crash on launch if libpulse-simple.so.0 is available but pulseaudio is not running
	libpulse_null_link="${PATH_LIBRARIES_USER}/libpulse-simple.so.0"
	if pulseaudio_is_available; then
	    rm --force "$libpulse_null_link"
	else
	    mkdir --parents "$PATH_LIBRARIES_USER"
	    ln --force --symbolic /dev/null "$libpulse_null_link"
	fi
	unset libpulse_null_link

	EOF
}

# Print the snippet setting forcing the use of a US-like locale
# USAGE: launcher_unity3d_force_locale
# RETURN: the code snippet, a multi-lines string
launcher_unity3d_force_locale() {
	cat <<- 'EOF'
	# Work around Unity3D poor support for non-US locales
	export LANG=C

	EOF
}

# Disable the MAP_32BIT flag to prevent a crash one some Linux versions when running a 64-bit build of Unity3D.
# USAGE: unity3d_disable_map32bit
unity3d_disable_map32bit() {
	# This workaround is specific to native Linux games.
	local application_default_type
	application_default_type=$(application_default_type)
	if [ "$application_default_type" != 'native' ]; then
		return 0
	fi

	local unity3d_version
	unity3d_version=$(unity3d_version)
	case "$unity3d_version" in
		('4.'*|'5.'*)
			local package package_architecture
			package=$(current_package)
			package_architecture=$(package_architecture "$package")
			if [ "$package_architecture" = '32' ]; then
				# This Unity3D build is not affected by the MAP_32BIT flag.
				return 0
			fi
		;;
		(*)
			# This Unity3D build is not affected by the MAP_32BIT flag.
			return 0
		;;
	esac
	cat <<- 'EOF'
	#define _GNU_SOURCE
	#include <stdlib.h>
	#include <dlfcn.h>
	#include <sys/mman.h>

	typedef void *(*orig_mmap_type)(void *addr, size_t length, int prot,
	                                int flags, int fd, off_t offset);

	void *mmap(void *addr, size_t length, int prot, int flags,
	           int fd, off_t offset)
	{
	    static orig_mmap_type orig_mmap = NULL;
	    if (orig_mmap == NULL)
	        orig_mmap = (orig_mmap_type)dlsym(RTLD_NEXT, "mmap");

	    flags &= ~MAP_32BIT;

	    return orig_mmap(addr, length, prot, flags, fd, offset);
	}
	EOF
}

