diff --git a/README.md b/README.md index 649e031..1a0f04a 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,29 @@ Finally, you can build the project by running the following: conan build .. ``` -On Ubuntu, you may now run `../make-appimage.sh .. . /path/to/game/files /some/path/OneShot.AppImage` to create an AppImage. Requires [linuxdeploy](https://github.com/linuxdeploy/linuxdeploy) and [AppImageTool](https://github.com/AppImage/AppImageKit) in your `PATH`. +On Linux, you likely want to generate an AppImage. Please refer to how to build the Journal app below, as this is a prerequisite for building the AppImage. Afterwards, you may run the command, from the root directory of the repository: + +```sh +./make-appimage.sh . build /path/to/game/files /path/to/journal/_______ /some/path/OneShot.AppImage` +``` + +Requires [linuxdeploy](https://github.com/linuxdeploy/linuxdeploy) and [AppImageTool](https://github.com/AppImage/AppImageKit) in your `PATH`. + +## Building the Journal app on Unix systems + +As a prerequisite on Ubuntu, ensure that the following packages are installed. + +```sh +sudo apt install python3-venv libxcb-xinerama +``` + +Then run the script. From the root of the repository: + +```sh +./make-journal-linux.sh . /path/to/journal/parent/directory/ +``` + +This will generate a file called `_______`. ### Supported image/audio formats These depend on the SDL auxiliary libraries. *OneShot* only makes use of bmp/png for images and oggvorbis/wav for audio. diff --git a/assets/journal.png b/assets/journal.png new file mode 100644 index 0000000..1059678 Binary files /dev/null and b/assets/journal.png differ diff --git a/journal/unix/journal-linux.spec b/journal/unix/journal-linux.spec new file mode 100644 index 0000000..5e1123b --- /dev/null +++ b/journal/unix/journal-linux.spec @@ -0,0 +1,33 @@ +# -*- mode: python ; coding: utf-8 -*- + +block_cipher = None + + +a = Analysis(['journal.py'], + pathex=['.'], + binaries=[], + datas=[('images', 'images'), ('qt.conf', '.')], + hiddenimports=[], + hookspath=[], + runtime_hooks=[], + excludes=['libgio-*', 'libglib-*', 'libsystemd.*', 'librt.*'], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='_______', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True ) diff --git a/make-appimage.sh b/make-appimage.sh index f386eb8..51365a1 100755 --- a/make-appimage.sh +++ b/make-appimage.sh @@ -3,14 +3,17 @@ LINUXDEPLOY=linuxdeploy-x86_64.AppImage APPIMAGETOOL=appimagetool-x86_64.AppImage -if [ $# -lt 3 ]; then - echo "usage: linuxdeploy.sh SOURCE_PATH CONAN_INSTALL_PATH GAME_PATH APPIMAGE_FILE" +if [ $# -lt 6 ]; then + echo "usage: make-appimage.sh SOURCE_PATH CONAN_INSTALL_PATH GAME_PATH EXTRA_UNIX_CONTENT_PATH JOURNAL_FILE APPIMAGE_FILE" + exit 1 fi source_path="$1" conan_install_path="$2" game_path="$3" -appimage_file="$4" +unix_content_path="$4" +journal_file="$5" +appimage_file="$6" appdir="$(mktemp -d)" function atexit { @@ -25,15 +28,15 @@ $LINUXDEPLOY -e "$conan_install_path/bin/oneshot" \ -d "$source_path/assets/oneshot.desktop" \ --appdir "$appdir" -# Populate remaining AppImage spec files -# ln -sf bin/oneshot "$appdir/AppRun" -# cp -f "$source_path/assets/oneshot.png" "$appdir/oneshot.png" - # Bundle game data -for dir in Audio Data Fonts Graphics Languages Wallpaper; do +cp -af "$journal_file" "$appdir/usr/bin/_______" +cp -af "$source_path/assets/journal.png" "$appdir/usr/bin/_______.png" +for dir in Audio Data Fonts Graphics Languages Wallpaper testing_saves testing_saves_postgame; do cp -ra "$game_path/$dir" "$appdir/usr/bin/" + [ -d "$unix_content_path/$dir/" ] && rsync -a "$unix_content_path/$dir/" "$appdir/usr/bin/$dir/" done -cp -a "$conan_install_path/bin/Data/xScripts.rxdata" "$appdir/usr/bin/Data/" +find "$appdir/usr/bin" \( -iname '*.bmp' -o -iname 'thumbs.db' -o -iname '*.ini' \) -delete +cp -af "$conan_install_path/bin/Data/xScripts.rxdata" "$appdir/usr/bin/Data/" # Create AppImage ARCH=x86_64 $APPIMAGETOOL "$appdir" "$appimage_file" diff --git a/make-journal-linux.sh b/make-journal-linux.sh new file mode 100755 index 0000000..67ffeb3 --- /dev/null +++ b/make-journal-linux.sh @@ -0,0 +1,33 @@ +#!/bin/bash -eu + +if [ $# -lt 2 ]; then + echo "usage: make-journal-linux.sh SOURCE_PATH OUTPUT_DIR" + exit 1 +fi + +source_path="$1" +output_dir="$2" +venv="$(mktemp -d)" +workpath="$(mktemp -d)" + +function atexit { + [ -n "$venv" ] && rm -rf "$venv" + [ -n "$workpath" ] && rm -rf "$workpath" +} + +trap atexit EXIT + +# Create and initialize venv +python3 -m venv "$venv" +set +u +source "$venv/bin/activate" +set -u +pip install --upgrade pip +pip install pyqt5 pyinstaller + +# Create standalone python distribution +pyinstaller --onefile \ + --distpath "$output_dir" \ + --workpath "$workpath" \ + --specpath="$source_path/journal/unix" \ + "$source_path/journal/unix/journal-linux.spec" diff --git a/scripts/Persistent.rb b/scripts/Persistent.rb index 11427cf..602cec8 100644 --- a/scripts/Persistent.rb +++ b/scripts/Persistent.rb @@ -24,9 +24,12 @@ class Persistent def initialize self.lang = LanguageCode.new(Steam::LANG || Oneshot::LANG) - if File.exists?("zh_CN.ver") - self.lang = LanguageCode.new("zh_CN") - end + if File.exists?("zh_CN.ver") + self.lang = LanguageCode.new("zh_CN") + end + if not Steam.enabled? then + self.lang = LanguageCode.new("en") + end end # Members diff --git a/scripts/Script.rb b/scripts/Script.rb index f17df92..28e32ec 100644 --- a/scripts/Script.rb +++ b/scripts/Script.rb @@ -2,7 +2,8 @@ PROTO_TEXT = "put me in the big portal" CEDRIC_TEXT = "put me in the big portal" RUE_TEXT = "put me in the big portal" -SUPPORTED_DE = ["cinnamon", "gnome", "mate", "kde", "xfce"] +# Gnome 3 does not show desktop entries in Nautilus. +SUPPORTED_DE = ["cinnamon", "mate", "kde", "xfce"] module Script def self.px @@ -374,6 +375,17 @@ module Script $game_temp.bgm_fadein_speed = speed end + def self.copy_file_chmod(src, dest, chmod) + File.open(dest, 'wb') do |output| + File.open(src, 'rb') do |input| + while buff = input.read(4096) + output.write(buff) + end + end + end + File.chmod(chmod, dest) + end + def self.copy_journal # If the required directories don't exist, create them Dir.mkdir(Oneshot::GAME_PATH) unless File.exists?(Oneshot::GAME_PATH) @@ -382,26 +394,22 @@ module Script # If we're on a supported Linux DE, make a .desktop file # so the clover icon can be properly shown if Oneshot::OS == "linux" and SUPPORTED_DE.include? Oneshot::DE + copy_file_chmod("#{Dir.pwd}/#{Oneshot::JOURNAL}", "#{Oneshot::SAVE_PATH}/#{Oneshot::JOURNAL}", 0755) + copy_file_chmod("#{Dir.pwd}/#{Oneshot::JOURNAL}.png", "#{Oneshot::SAVE_PATH}/#{Oneshot::JOURNAL}.png", 0644) path = "#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}.desktop" File.open(path, "wb") do |output| output.write("[Desktop Entry]\n") output.write("Comment=...\n") output.write("Terminal=false\n") output.write("Name=_______\n") - output.write("Exec=#{Dir.pwd}/#{Oneshot::JOURNAL}\n") + output.write("Exec=#{Oneshot::SAVE_PATH}/#{Oneshot::JOURNAL}\n") output.write("Type=Application\n") - output.write("Icon=#{Dir.pwd}/images/icon.png\n") + output.write("Icon=#{Oneshot::SAVE_PATH}/#{Oneshot::JOURNAL}.png\n") end - File.chmod(0777, path) + File.chmod(0755, path) # If the journal is a file, copy it to Documents elsif File.file?(Oneshot::JOURNAL) - File.open(Oneshot::JOURNAL, "rb") do |input| - File.open("#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}", "wb") do |output| - while buff = input.read(4096) - output.write(buff) - end - end - end + copy_file_chmod(Oneshot::JOURNAL, "#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}", 0755) # If the journal isn't a file, symlink it else File.symlink "#{Dir.pwd}/#{Oneshot::JOURNAL}", "#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}" diff --git a/scripts/i18n_Language.rb b/scripts/i18n_Language.rb index ad83990..ced44d2 100644 --- a/scripts/i18n_Language.rb +++ b/scripts/i18n_Language.rb @@ -18,7 +18,7 @@ class Language LANG_CK = [ 'ko', 'zh_CN' ] - LANGUAGES = LANG_WESTERN + LANG_CK + LANG_J + LANGUAGES = Steam.enabled? ? (LANG_WESTERN + LANG_CK + LANG_J) : ['en'] class << self def set(lc)