Compare commits

..
26 Commits
Author SHA1 Message Date
ScreamAngel 4f6c6788d0 feat: add AppImage & Windows portable single executable build workflow 2026-10-21 01:04:50 +03:00
ScreamAngel 47437d280b fix(ui): immediately update top status message when selecting game directory 2026-10-20 20:14:10 +03:00
ScreamAngel e82257aa27 chore(build): sync newly built Windows binaries with scanner fix 2026-10-20 20:06:58 +03:00
ScreamAngel 5991b03cd0 fix(scanner): show dedicated modal and warning banner when game is not found 2026-10-20 19:55:37 +03:00
ScreamAngel dc3df87384 ci: remove automated GitHub Actions workflow 2026-10-19 19:52:36 +03:00
ScreamAngel a9e5233ae7 chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-19 00:57:25 +00:00
ScreamAngel 410c5fc0b7 Update README.md 2026-10-19 03:50:19 +03:00
ScreamAngel e6cec74c96 Update README.md 2026-10-19 03:49:09 +03:00
ScreamAngel c65f1acb1b Update README.md 2026-10-19 03:46:23 +03:00
ScreamAngel f1b3cfae29 Update README.md 2026-10-19 03:45:14 +03:00
ScreamAngel 0614038175 chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-18 23:38:27 +00:00
ScreamAngel 66efe4ec0e Update README.md 2026-10-19 02:32:43 +03:00
ScreamAngel 0a7fb20aa9 chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-17 15:21:09 +00:00
ScreamAngel 709845f472 Merge branch 'origin/main' and resolve binary conflicts 2026-10-17 18:12:16 +03:00
ScreamAngel f90f25f033 feat(engine): add cross-platform auto engine downloader & standalone deployment support 2026-10-17 16:13:11 +03:00
ScreamAngel 08e46e6675 chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-17 12:08:20 +00:00
EgEhE 29e57c38e5 Delete gow3_launcher_win.exe
This file should be in relases
2026-10-17 15:00:55 +03:00
EgEhE 1ade24e88c Delete gow3-launcher
This file should be in relases
2026-10-17 14:59:02 +03:00
EgEhE b7e366e893 Delete gow3-launcher-win.exe
This file should be in relases
2026-10-17 14:58:19 +03:00
ScreamAngel 1179c01ddf fix(launcher): resolve Win32 os error 193 & UI stutter, add Windows engine downloader 2026-10-17 14:41:00 +03:00
ScreamAngel 765fa79ecd chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-17 10:41:23 +00:00
ScreamAngel 01771af1d7 fix(windows): resolve VRAM detection cap and add portable Python dependency downloader 2026-10-17 13:34:54 +03:00
ScreamAngel 5d1de303af chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-17 09:45:12 +00:00
ScreamAngel 4326563b9d README.md 2026-10-17 12:39:50 +03:00
ScreamAngel bc48a858f0 README.md 2026-10-17 12:38:20 +03:00
ScreamAngel d96f683944 chore(build): sync gow3-launcher-win.exe to repo root [skip ci] 2026-10-17 09:34:26 +00:00
11 changed files with 380 additions and 179 deletions

No files matched your search

-122
View File
@@ -1,122 +0,0 @@
name: Build Cross-Platform Launchers
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
permissions:
contents: write
jobs:
build-linux:
name: Build Linux Launcher
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install Linux build dependencies
run: |
sudo apt-get update
sudo apt-get install -y libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev libx11-dev libxcursor-dev libxi-dev libxrandr-dev libgl1-mesa-dev
- name: Build Linux Launcher (Release)
working-directory: launcher
run: cargo build --release
- name: Prepare binary
run: |
cp launcher/target/release/launcher ./gow3-launcher
chmod +x ./gow3-launcher
- name: Upload Linux Artifact
uses: actions/upload-artifact@v4
with:
name: gow3-launcher-linux
path: ./gow3-launcher
build-windows:
name: Build Windows Launcher
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build Windows Launcher (Release)
working-directory: launcher
run: cargo build --release
- name: Prepare binary
run: |
Copy-Item launcher/target/release/launcher.exe -Destination ./gow3-launcher-win.exe
- name: Upload Windows Artifact
uses: actions/upload-artifact@v4
with:
name: gow3-launcher-windows
path: ./gow3-launcher-win.exe
publish-release:
name: Publish Release & Sync Windows Binary
needs: [build-linux, build-windows]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download Linux binary
uses: actions/download-artifact@v4
with:
name: gow3-launcher-linux
path: ./artifacts/
- name: Download Windows binary
uses: actions/download-artifact@v4
with:
name: gow3-launcher-windows
path: ./artifacts/
- name: Commit Windows launcher to repo root
run: |
cp ./artifacts/gow3-launcher-win.exe ./gow3-launcher-win.exe
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add gow3-launcher-win.exe
git diff --quiet && git diff --staged --quiet || (git commit -m "chore(build): sync gow3-launcher-win.exe to repo root [skip ci]" && git push origin main)
- name: Create or Update GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: latest
name: "God of War III Native Launcher (Dual-Boot & Cross-Platform)"
body: |
## 🚀 God of War III Remastered - Native Launcher (Linux & Windows)
Aynı klasörde yan yana çalışabilen yerel ikili dosyalar:
- 🐧 **Linux**: `gow3-launcher`
- 🪟 **Windows / Dual-Boot**: `gow3-launcher-win.exe`
### ✨ Özellikler
- **Dual-Boot Desteği:** Aynı klasörde hem Windows hem Linux için yan yana bağımsız launcher'lar!
- **Modern Kayan Anahtarlar:** Klasik kutucuklar yerine animasyonlu Switch teması
- **Kararlı 60 FPS / 120 FPS / 144 FPS / 240 FPS Pacing:** Fizik hızlanma sorunu olmadan akıcı oynanış
- **Sinematikleri 'X' Tuşuyla Atlama Yaması:** Ara sahneleri kumandanızın X tuşuyla geçebilme seçeneği
- **Sarı Doku Hatası Önleme Yaması (Instant Readbacks):** Karlı ve parlak sahnelerdeki renk bozulmasını engeller
- **Dahili Donanım ve Ekran Hz Tespiti:** GPU, VRAM, RAM ve ekran yenileme hızına göre otomatik yapılandırma
- **4 Farklı Dil Desteği:** Türkçe 🇹🇷, English 🇬🇧, Deutsch 🇩🇪, Español 🇪🇸
- **%100 Rust Uyumlu Self-Updater:** Doğrudan GitHub üzerinden en son sürüme tek tıkla güncelleme
files: |
./artifacts/gow3-launcher
./artifacts/gow3-launcher-win.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+153
View File
@@ -0,0 +1,153 @@
name: Build & Release Single Executables (AppImage & Portable Exe)
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: write
jobs:
build-linux:
name: Build Linux AppImage & Binary
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install Linux build dependencies
run: |
sudo apt-get update
sudo apt-get install -y libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev libx11-dev libxcursor-dev libxi-dev libxrandr-dev libgl1-mesa-dev wget
- name: Build Linux Launcher (Release)
working-directory: launcher
run: cargo build --release
- name: Build AppImage
run: |
mkdir -p AppDir/usr/bin
mkdir -p AppDir/usr/share/applications
mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
cp launcher/target/release/launcher AppDir/usr/bin/gow3-launcher
cp gow3.png AppDir/usr/share/icons/hicolor/256x256/apps/gow3.png
cp gow3.png AppDir/gow3.png
cat << 'EOF' > AppDir/gow3-launcher.desktop
[Desktop Entry]
Name=God of War III Launcher
Exec=gow3-launcher
Icon=gow3
Type=Application
Categories=Game;
Terminal=false
EOF
cp AppDir/gow3-launcher.desktop AppDir/usr/share/applications/
cat << 'EOF' > AppDir/AppRun
#!/bin/bash
HERE="$(dirname "$(readlink -f "${0}")")"
export PATH="${HERE}/usr/bin:${PATH}"
exec "${HERE}/usr/bin/gow3-launcher" "$@"
EOF
chmod +x AppDir/AppRun
wget -q https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage -O appimagetool
chmod +x appimagetool
./appimagetool --appimage-extract
ARCH=x86_64 ./squashfs-root/AppRun AppDir God_of_War_III_Launcher-x86_64.AppImage
cp launcher/target/release/launcher ./gow3-launcher
- name: Upload Linux Artifacts
uses: actions/upload-artifact@v4
with:
name: linux-artifacts
path: |
God_of_War_III_Launcher-x86_64.AppImage
gow3-launcher
build-windows:
name: Build Windows Portable Exe
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build Windows Launcher (Release)
working-directory: launcher
run: cargo build --release
- name: Prepare Windows Executables
run: |
Copy-Item launcher/target/release/launcher.exe -Destination ./gow3-launcher-win.exe
Copy-Item launcher/target/release/launcher.exe -Destination ./God_of_War_III_Launcher-Windows.exe
- name: Upload Windows Artifacts
uses: actions/upload-artifact@v4
with:
name: windows-artifacts
path: |
gow3-launcher-win.exe
God_of_War_III_Launcher-Windows.exe
publish-release:
name: Publish Release with Assets
needs: [build-linux, build-windows]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download Linux artifacts
uses: actions/download-artifact@v4
with:
name: linux-artifacts
path: ./dist/
- name: Download Windows artifacts
uses: actions/download-artifact@v4
with:
name: windows-artifacts
path: ./dist/
- name: Create or Update GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: "God of War III Launcher ${{ github.ref_name }}"
draft: false
prerelease: false
make_latest: true
body: |
## 🚀 God of War III Remastered - Single Executable Release
Tek tıkla çalışan taşınabilir yürütülebilir dosyalar (Single Executables):
### 📦 İndirme Seçenekleri:
- 🐧 **Linux (AppImage - Tek Dosya Kurulumsuz):** [`God_of_War_III_Launcher-x86_64.AppImage`](./God_of_War_III_Launcher-x86_64.AppImage)
- *Kullanım:* İndirin, sağ tıklayıp özelliklerden "Çalıştırılabilir yap" (veya `chmod +x`) deyin ve çift tıklayın!
- 🪟 **Windows (Portable Exe - Kurulumsuz):** [`God_of_War_III_Launcher-Windows.exe`](./God_of_War_III_Launcher-Windows.exe) / [`gow3-launcher-win.exe`](./gow3-launcher-win.exe)
- 🐧 **Linux (Native ELF):** [`gow3-launcher`](./gow3-launcher)
### ✨ Yenilikler (${{ github.ref_name }})
- **AppImage Desteği:** Linux üzerinde bağımlılık derdi olmadan tek tıkla çalışan resmi AppImage paketi.
- **Windows Portable Exe:** Harici dosyalara ihtiyaç duymadan kendi simgesi ve arayüzüyle açılan taşınabilir Windows sürümü.
- **Akıllı Konum & Donanım Tespiti:** Launcher artık doğrudan kendi bulunduğu dizini tanır, taşınabilir çalışır.
- **Gelişmiş Oyun Arama:** Disklerde oyun bulunamadığında açıklayıcı modal uyarı penceresi ve anlık doğrulama.
- **Otomatik Yama & FPS Ayarları:** 60/120/144/240 Hz pacing, sarı doku önleme ve sinematik atlama.
files: |
./dist/God_of_War_III_Launcher-x86_64.AppImage
./dist/God_of_War_III_Launcher-Windows.exe
./dist/gow3-launcher-win.exe
./dist/gow3-launcher
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+19 -3
View File
@@ -24,8 +24,8 @@ Launcher for God Of War 3 PC on Linux and Windows
directories.
- 🚨 **Crash & Error Diagnostic Assistant:** Automatically analyzes `gow3_log.txt` on exit. If an unexpected crash occurs, it displays a plain-language diagnosis and recommended fix.
- 🔄 **GitHub Upstream Sync & Auto-Updater:** Checks upstream ([R-V-L/gow3_pc](https://github.com/R-V-L/gow3_pc)) for updates and re-applies all your custom directory paths, 144Hz patches, and VRAM budgets seamlessly.
- 🌐 **Multi-Language Support:** Available in **Turkish 🇹🇷**, **English 🇬🇧**, **German 🇩🇪**, and **Spanish 🇪🇸**.
- 🌐 **Multi-Language Support:** Available in **Turkish 🇹🇷**, **English 🇬🇧**, **German 🇩🇪**, and **Spanish 🇪🇸**.
## 📋 System Requirements
@@ -36,7 +36,16 @@ Launcher for God Of War 3 PC on Linux and Windows
| **CPU** | 6-core x86_64 processor | 8-core / 16-thread modern CPU |
| **GPU** | Vulkan 1.3 compatible (4 GB VRAM) | Vulkan 1.3+ (6 GB+ VRAM, Nvidia / AMD) |
| **RAM** | 8 GB | 16 GB+ |
| **Dependencies** | Python 3, Vulkan drivers | `gamemode` (optional) |
| **Dependencies** | Python 3, Vulkan drivers | `gamemode` (optional) |
## Video
You can watch the video for details.
<p align="center">
<a href="https://www.youtube.com/watch?v=-yGAEjdQGzE"><img width="1920" height="1080" alt="vlc_ie5PhePn2o" src="https://github.com/user-attachments/assets/190f531e-55b0-4a4a-b883-440cd615a18a" /></a>
</p>
@@ -58,6 +67,10 @@ Launcher for God Of War 3 PC on Linux and Windows
- **Windows**: `gow3-launcher-win.exe`
The launcher is completely standalone: it automatically detects your hardware, verifies the game dump, configures settings files, and applies all required patches without requiring external bash scripts.
<img width="1920" height="1016" alt="gow3_launcher_win_BJ42UCuIvf" src="https://github.com/user-attachments/assets/3d57aaed-8869-446e-bdb7-89491275039d" />
### 2. Add Your Game Dump
@@ -75,6 +88,9 @@ Launcher for God Of War 3 PC on Linux and Windows
.\gow3-launcher-win.exe --play
```
<img width="1920" height="1080" alt="gow3-probe_Hz51yYBACH" src="https://github.com/user-attachments/assets/651de8e7-15b9-454c-ab6d-a09dbd71f44e" />
### 🔄 Dual-Boot Ready
Both `gow3-launcher` and `gow3-launcher-win.exe` live side-by-side in the same directory. If you dual-boot between Linux and Windows, you can play on either operating system seamlessly while sharing the same game dumps and configurations!
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+134 -26
View File
@@ -67,6 +67,8 @@ pub struct LauncherApp {
is_scanning: bool,
scan_rx: Option<Receiver<Vec<GameCandidate>>>,
found_candidates_modal: Option<Vec<GameCandidate>>,
show_game_not_found_modal: bool,
scan_failed_empty: bool,
// Updater state
is_checking_update: bool,
@@ -127,6 +129,8 @@ impl LauncherApp {
is_scanning: false,
scan_rx: None,
found_candidates_modal: None,
show_game_not_found_modal: false,
scan_failed_empty: false,
is_checking_update: false,
update_rx: None,
update_modal: None,
@@ -193,21 +197,46 @@ impl LauncherApp {
}
}
// Remastered title logo: gow3-remastered.png
// Remastered title logo: gow3-remastered.png (checks base_dir, then embedded fallback)
let logo_path = self.base_dir.join("gow3-remastered.png");
if logo_path.is_file() {
if let Ok(img) = image::open(&logo_path) {
let size = [img.width() as _, img.height() as _];
let img_buffer = img.to_rgba8();
let pixels = img_buffer.as_flat_samples();
let color_img = egui::ColorImage::from_rgba_unmultiplied(size, pixels.as_slice());
self.logo_texture = Some(ctx.load_texture("gow3_remastered_logo", color_img, Default::default()));
}
let logo_img = if logo_path.is_file() {
image::open(&logo_path).ok()
} else {
image::load_from_memory(include_bytes!("../../gow3-remastered.png")).ok()
};
if let Some(img) = logo_img {
let size = [img.width() as _, img.height() as _];
let img_buffer = img.to_rgba8();
let pixels = img_buffer.as_flat_samples();
let color_img = egui::ColorImage::from_rgba_unmultiplied(size, pixels.as_slice());
self.logo_texture = Some(ctx.load_texture("gow3_remastered_logo", color_img, Default::default()));
}
}
fn check_game_validity(&mut self) {
self.is_game_valid = is_valid_game_dir(Path::new(&self.config.game_dir));
if self.is_game_valid {
self.scan_failed_empty = false;
if let Some((_, is_err)) = self.status_message {
if is_err {
self.status_message = Some((self.t("game_valid").to_string(), false));
}
}
}
}
fn set_game_directory(&mut self, path: &Path, ctx: &egui::Context) {
self.config.game_dir = path.to_string_lossy().to_string();
let _ = update_launch_scripts(&self.base_dir, path);
let _ = self.config.save(&self.base_dir);
self.check_game_validity();
self.load_textures(ctx);
self.scan_failed_empty = false;
if self.is_game_valid {
self.status_message = Some((self.t("game_valid").to_string(), false));
} else {
self.status_message = Some((self.t("game_invalid").to_string(), true));
}
}
fn apply_all_optimizations(&mut self) {
@@ -239,6 +268,7 @@ impl LauncherApp {
fn start_game_scan(&mut self) {
self.is_scanning = true;
self.scan_failed_empty = false;
let (tx, rx): (Sender<Vec<GameCandidate>>, Receiver<Vec<GameCandidate>>) = channel();
self.scan_rx = Some(rx);
@@ -335,14 +365,12 @@ impl eframe::App for LauncherApp {
self.is_scanning = false;
self.scan_rx = None;
if candidates.is_empty() {
let msg = match self.current_lang {
Language::Turkish => "⚠️ Disklerde eksiksiz ve geçerli God of War III klasörü bulunamadı.",
Language::English => "⚠️ No complete and valid God of War III directory found on drives.",
Language::German => "⚠️ Kein vollständiger God of War III Ordner auf den Laufwerken gefunden.",
Language::Spanish => "⚠️ No se encontró ninguna carpeta completa y válida en los discos.",
};
let msg = self.t("scan_not_found_inline");
self.status_message = Some((msg.to_string(), true));
self.scan_failed_empty = true;
self.show_game_not_found_modal = true;
} else {
self.scan_failed_empty = false;
// Open the candidates selection modal so the user chooses the exact one
self.found_candidates_modal = Some(candidates);
}
@@ -683,11 +711,7 @@ impl eframe::App for LauncherApp {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
if ui.button(egui::RichText::new(self.t("manual_select")).strong()).clicked() {
if let Some(folder) = rfd::FileDialog::new().pick_folder() {
self.config.game_dir = folder.to_string_lossy().to_string();
let _ = update_launch_scripts(&self.base_dir, &folder);
let _ = self.config.save(&self.base_dir);
self.check_game_validity();
self.load_textures(&ctx);
self.set_game_directory(&folder, &ctx);
}
}
@@ -700,7 +724,7 @@ impl eframe::App for LauncherApp {
});
});
// Validation badge
// Validation badge & Scan status
ui.add_space(4.0);
if self.is_game_valid {
ui.label(
@@ -715,6 +739,25 @@ impl eframe::App for LauncherApp {
.strong(),
);
}
if self.scan_failed_empty {
ui.add_space(6.0);
egui::Frame::group(ui.style())
.fill(egui::Color32::from_rgba_unmultiplied(65, 20, 20, 215))
.stroke(egui::Stroke::new(1.0, egui::Color32::from_rgb(245, 80, 80)))
.inner_margin(10.0)
.corner_radius(egui::CornerRadius::same(6))
.show(ui, |ui| {
ui.horizontal(|ui| {
ui.label(egui::RichText::new("⚠️").size(18.0));
ui.label(
egui::RichText::new(self.t("scan_not_found_inline"))
.color(egui::Color32::from_rgb(255, 140, 140))
.strong(),
);
});
});
}
});
// --- 3. PATCHES & OPTIMIZATIONS CARD ---
@@ -901,11 +944,7 @@ impl eframe::App for LauncherApp {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
if ui.button(egui::RichText::new(self.t("select_this")).color(egui::Color32::from_rgb(105, 225, 110)).strong()).clicked() {
self.config.game_dir = c.path.to_string_lossy().to_string();
let _ = update_launch_scripts(&self.base_dir, &c.path);
let _ = self.config.save(&self.base_dir);
self.check_game_validity();
self.load_textures(&ctx);
self.set_game_directory(&c.path, &ctx);
self.found_candidates_modal = None;
let selected_name = c.title.clone();
self.status_message = Some((format!("✅ {} seçildi ve kaydedildi!", selected_name), false));
@@ -926,6 +965,75 @@ impl eframe::App for LauncherApp {
});
}
// --- MODAL: GAME NOT FOUND WARNING ---
if self.show_game_not_found_modal {
egui::Window::new(self.t("game_not_found_modal_title"))
.collapsible(false)
.resizable(false)
.default_width(520.0)
.anchor(egui::Align2::CENTER_CENTER, egui::vec2(0.0, 0.0))
.show(&ctx, |ui| {
ui.vertical_centered(|ui| {
ui.add_space(6.0);
ui.label(
egui::RichText::new("⚠️")
.size(36.0)
.color(egui::Color32::from_rgb(255, 175, 50)),
);
ui.add_space(4.0);
ui.label(
egui::RichText::new(self.t("game_not_found_title"))
.size(17.0)
.strong()
.color(egui::Color32::from_rgb(255, 105, 105)),
);
ui.add_space(6.0);
});
let box_frame = egui::Frame::group(ui.style())
.fill(egui::Color32::from_rgba_unmultiplied(35, 22, 22, 225))
.stroke(egui::Stroke::new(1.0, egui::Color32::from_rgba_unmultiplied(230, 60, 60, 110)))
.inner_margin(12.0)
.corner_radius(egui::CornerRadius::same(8));
box_frame.show(ui, |ui| {
ui.label(
egui::RichText::new(self.t("game_not_found_desc"))
.size(13.0)
.color(egui::Color32::from_rgb(225, 225, 230)),
);
});
ui.add_space(10.0);
ui.horizontal(|ui| {
let manual_btn = egui::Button::new(
egui::RichText::new(self.t("manual_select"))
.strong()
.color(egui::Color32::WHITE),
)
.fill(egui::Color32::from_rgb(45, 105, 205))
.corner_radius(egui::CornerRadius::same(6))
.min_size(egui::vec2(130.0, 32.0));
if ui.add(manual_btn).clicked() {
if let Some(folder) = rfd::FileDialog::new().pick_folder() {
self.set_game_directory(&folder, &ctx);
self.show_game_not_found_modal = false;
}
}
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
let close_btn = egui::Button::new(self.t("close"))
.min_size(egui::vec2(90.0, 32.0));
if ui.add(close_btn).clicked() {
self.show_game_not_found_modal = false;
}
});
});
ui.add_space(4.0);
});
}
// --- MODAL 2: FIRST LAUNCH SETUP ---
if self.show_first_launch_modal {
egui::Window::new(self.t("first_launch_title"))
+16
View File
@@ -86,6 +86,10 @@ pub fn text(lang: Language, key: &str) -> &'static str {
(Language::Turkish, "first_launch_auto") => "⚡ Otomatik Tara ve Yapılandır",
(Language::Turkish, "first_launch_manual") => "🔧 Manuel Olarak Kendim Ayarlayacağım",
(Language::Turkish, "candidates_modal_title") => "🎮 Bulunan God of War III Klasörleri",
(Language::Turkish, "game_not_found_modal_title") => "⚠️ Oyun Bulunamadı",
(Language::Turkish, "game_not_found_title") => "Sistemde God of War III Yüklü Değil!",
(Language::Turkish, "game_not_found_desc") => "Diskleriniz tarandı ancak geçerli bir God of War III Remastered (CUSA01623 / CUSA01715) kurulumu tespit edilemedi.\n\n• Oyun henüz sisteminizde yüklü olmayabilir.\n• Oyun harici bir diskte veya özel bir klasördeyse, lütfen aşağıdaki 'Manuel Seç' butonunu kullanarak 'eboot.bin' dosyasının bulunduğu ana oyun klasörünü seçin.",
(Language::Turkish, "scan_not_found_inline") => "⚠️ Sistemde oyun yüklü değil veya klasör bulunamadı! Lütfen oyunu kurun veya 'Manuel Seç' butonunu kullanın.",
(Language::Turkish, "select_this") => "Bu Klasörü Kullan",
(Language::Turkish, "close") => "Kapat",
(Language::Turkish, "diagnosis_title") => "🚨 Oyun Kapanma & Hata Teşhis Raporu",
@@ -161,6 +165,10 @@ pub fn text(lang: Language, key: &str) -> &'static str {
(Language::English, "first_launch_auto") => "⚡ Auto Scan & Configure",
(Language::English, "first_launch_manual") => "🔧 I will configure manually",
(Language::English, "candidates_modal_title") => "🎮 Found God of War III Directories",
(Language::English, "game_not_found_modal_title") => "⚠️ Game Not Found",
(Language::English, "game_not_found_title") => "God of War III Is Not Installed!",
(Language::English, "game_not_found_desc") => "All drives were scanned, but a valid God of War III Remastered (CUSA01623 / CUSA01715) installation was not found.\n\n• The game might not be installed on your system yet.\n• If the game is on an external drive or custom folder, use the 'Browse Folder' button below to select the directory containing 'eboot.bin'.",
(Language::English, "scan_not_found_inline") => "⚠️ Game is not installed on the system or folder not found! Please install the game or use 'Browse Folder'.",
(Language::English, "select_this") => "Use This Folder",
(Language::English, "close") => "Close",
(Language::English, "diagnosis_title") => "🚨 Game Crash & Error Diagnosis Report",
@@ -236,6 +244,10 @@ pub fn text(lang: Language, key: &str) -> &'static str {
(Language::German, "first_launch_auto") => "⚡ Automatisch scannen & konfigurieren",
(Language::German, "first_launch_manual") => "🔧 Manuell konfigurieren",
(Language::German, "candidates_modal_title") => "🎮 Gefundene Spielordner",
(Language::German, "game_not_found_modal_title") => "⚠️ Spiel nicht gefunden",
(Language::German, "game_not_found_title") => "God of War III ist nicht installiert!",
(Language::German, "game_not_found_desc") => "Alle Laufwerke wurden durchsucht, aber es wurde keine gültige God of War III Remastered (CUSA01623 / CUSA01715) Installation gefunden.\n\n• Das Spiel ist möglicherweise noch nicht installiert.\n• Wenn sich das Spiel auf einem externen Laufwerk befindet, wählen Sie den Ordner bitte mit 'Durchsuchen' aus.",
(Language::German, "scan_not_found_inline") => "⚠️ Das Spiel ist nicht auf dem System installiert oder der Ordner wurde nicht gefunden! Bitte installieren Sie das Spiel oder nutzen Sie 'Durchsuchen'.",
(Language::German, "select_this") => "Diesen Ordner wählen",
(Language::German, "close") => "Schließen",
(Language::German, "diagnosis_title") => "🚨 Fehlerdiagnose-Bericht",
@@ -311,6 +323,10 @@ pub fn text(lang: Language, key: &str) -> &'static str {
(Language::Spanish, "first_launch_auto") => "⚡ Escanear y Configurar",
(Language::Spanish, "first_launch_manual") => "🔧 Configurar Manualmente",
(Language::Spanish, "candidates_modal_title") => "🎮 Carpetas Encontradas",
(Language::Spanish, "game_not_found_modal_title") => "⚠️ Juego no encontrado",
(Language::Spanish, "game_not_found_title") => "¡God of War III no está instalado!",
(Language::Spanish, "game_not_found_desc") => "Se escanearon todas las unidades pero no se encontró una instalación válida de God of War III Remastered (CUSA01623 / CUSA01715).\n\n• Es posible que el juego aún no esté instalado en su sistema.\n• Si el juego está en una unidad externa o carpeta personalizada, use el botón 'Explorar' para seleccionar la carpeta que contiene 'eboot.bin'.",
(Language::Spanish, "scan_not_found_inline") => "⚠️ ¡El juego no está instalado en el sistema o no se encontró la carpeta! Por favor instale el juego o use 'Explorar'.",
(Language::Spanish, "select_this") => "Usar Esta Carpeta",
(Language::Spanish, "close") => "Cerrar",
(Language::Spanish, "diagnosis_title") => "🚨 Informe de Diagnóstico de Error",
+34 -18
View File
@@ -13,12 +13,24 @@ use eframe::egui;
use std::path::PathBuf;
fn main() -> eframe::Result<()> {
// Determine base_dir: If running inside 'launcher' folder, go up to parent, else use current dir
let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
let base_dir = if current_dir.ends_with("launcher") {
current_dir.parent().unwrap_or(&current_dir).to_path_buf()
// Determine base_dir:
// 1. If running as an AppImage, use the directory where the .AppImage file is located
// 2. If running as standalone executable, use the folder containing the binary
// 3. Fallback to current working directory
let base_dir = if let Ok(appimage) = std::env::var("APPIMAGE") {
PathBuf::from(appimage).parent().unwrap_or(&PathBuf::from(".")).to_path_buf()
} else if let Ok(exe_path) = std::env::current_exe() {
let exe_dir = exe_path.parent().unwrap_or(&PathBuf::from(".")).to_path_buf();
let cur = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
if cur.ends_with("launcher") {
cur.parent().unwrap_or(&cur).to_path_buf()
} else if exe_dir.ends_with("target/release") || exe_dir.ends_with("target/debug") {
cur
} else {
exe_dir
}
} else {
current_dir
std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."))
};
let args: Vec<String> = std::env::args().collect();
@@ -49,19 +61,23 @@ fn main() -> eframe::Result<()> {
.with_min_inner_size([650.0, 550.0])
.with_resizable(true);
// Try load window icon
let icon_path = base_dir.join("gow3.png");
if icon_path.is_file() {
if let Ok(img) = image::open(&icon_path) {
let width = img.width();
let height = img.height();
let rgba = img.to_rgba8().into_raw();
viewport = viewport.with_icon(egui::IconData {
rgba,
width,
height,
});
}
// Try load window icon: check base_dir first, then fallback to embedded asset
let icon_data = if let Ok(img) = image::open(base_dir.join("gow3.png")) {
let width = img.width();
let height = img.height();
let rgba = img.to_rgba8().into_raw();
Some(egui::IconData { rgba, width, height })
} else if let Ok(img) = image::load_from_memory(include_bytes!("../../gow3.png")) {
let width = img.width();
let height = img.height();
let rgba = img.to_rgba8().into_raw();
Some(egui::IconData { rgba, width, height })
} else {
None
};
if let Some(icon) = icon_data {
viewport = viewport.with_icon(icon);
}
let native_options = eframe::NativeOptions {
+23 -9
View File
@@ -15,10 +15,13 @@ pub fn is_valid_game_dir(path: &Path) -> bool {
return false;
}
let eboot = path.join("eboot.bin");
if !eboot.is_file() {
let eboot = if path.join("eboot.bin").is_file() {
path.join("eboot.bin")
} else if path.join("EBOOT.BIN").is_file() {
path.join("EBOOT.BIN")
} else {
return false;
}
};
// 1. Verify eboot.bin size (genuine God of War III eboot is > 1MB, typically ~4.5MB)
if let Ok(meta) = fs::metadata(&eboot) {
@@ -30,10 +33,17 @@ pub fn is_valid_game_dir(path: &Path) -> bool {
}
// 2. Verify sce_sys/param.sfo exists and has data
let sfo = path.join("sce_sys/param.sfo");
if !sfo.is_file() {
let sfo = if path.join("sce_sys/param.sfo").is_file() {
path.join("sce_sys/param.sfo")
} else if path.join("sce_sys/PARAM.SFO").is_file() {
path.join("sce_sys/PARAM.SFO")
} else if path.join("SCE_SYS/param.sfo").is_file() {
path.join("SCE_SYS/param.sfo")
} else if path.join("SCE_SYS/PARAM.SFO").is_file() {
path.join("SCE_SYS/PARAM.SFO")
} else {
return false;
}
};
if let Ok(meta) = fs::metadata(&sfo) {
if meta.len() < 100 {
return false;
@@ -43,13 +53,13 @@ pub fn is_valid_game_dir(path: &Path) -> bool {
}
// 3. Verify at least one essential game directory exists (sce_module, EXEC, or language packs)
let has_modules = path.join("sce_module").is_dir();
let has_exec = path.join("EXEC").is_dir();
let has_modules = path.join("sce_module").is_dir() || path.join("SCE_MODULE").is_dir();
let has_exec = path.join("EXEC").is_dir() || path.join("exec").is_dir();
let has_lang = [
"ENGLISH", "DUTCH", "FRENCH", "GERMAN", "ITALIAN", "POLISH", "PORTUGUESE", "RUSSIAN", "SPANISH", "data",
]
.iter()
.any(|lang| path.join(lang).is_dir());
.any(|lang| path.join(lang).is_dir() || path.join(lang.to_lowercase()).is_dir());
has_modules || has_exec || has_lang
}
@@ -58,6 +68,10 @@ pub fn scan_for_game() -> Vec<GameCandidate> {
let mut candidates = Vec::new();
let mut scan_roots = Vec::new();
if let Ok(cur) = std::env::current_dir() {
scan_roots.push(cur);
}
#[cfg(target_os = "windows")]
{
if let Ok(userprofile) = std::env::var("USERPROFILE") {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"first_launch_done": true,
"language": "tr",
"game_dir": "/home/screamangel/İndirilenler/GOW3 Emu Linux/CUSA01623",
"game_dir": "/home/screamangel/İndirilenler/GOW3 Emu Linux/.CUSA01715",
"target_fps": 60,
"patch_delta_time": true,
"patch_readbacks": true,