Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf8fd8fb6c | ||
|
|
7ae4948793 | ||
|
|
9147960de5 | ||
|
|
3a96e9845b | ||
|
|
3992455718 | ||
|
|
08da3bec2c | ||
|
|
04f61833ea |
No files matched your search
@@ -0,0 +1,97 @@
|
||||
# God of War III PC Launcher — Proje Hafızası ve Mimari Özeti
|
||||
|
||||
> **Versiyon:** v2.1
|
||||
> **Depo:** [github.com/ScreamAngel/gow3_launcher](https://github.com/ScreamAngel/gow3_launcher) (`main` dalı)
|
||||
> **Platform Desteği:** Linux (x86_64, Wayland/Hyprland & X11) ve Windows (x86_64 MSVC)
|
||||
> **Tarih:** 07 Kasım 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Proje Mimarisi ve Çekirdek Dosyalar
|
||||
|
||||
* **Launcher Kaynak Kodu (`launcher/src/`):**
|
||||
* `main.rs`: CLI başlatma argümanları (`--play`, `-p`), pencere ikonu yükleme ve eframe/egui giriş noktası.
|
||||
* `app.rs`: Launcher ana GUI arayüzü, 6 sekme (Oyun, Grafik, Yapılandırma, Kontroller, Modlar, Sistem), shader derleme ekranı ve oyun süreci izleyicisi.
|
||||
* `discord_rpc.rs`: Sıfır ek yükümlü, yerel Discord IPC istemcisi (Linux Unix Domain Socket & Windows Named Pipe), gerçek zamanlı bölüm & boss savaşı dedektörü, çoklu dil desteği (`RpcLanguage`).
|
||||
* `win_input.rs`: Windows düşük seviye fare kancası (`WH_MOUSE_LL`), 1ms `timeBeginPeriod` zamanlayıcı çözünürlüğü ve oyun penceresini öne getirme (`SetForegroundWindow`).
|
||||
* `runner.rs`: Mod bindirme (overlay) yöneticisi, Python/Rust mod montajı, oyun süreci (`gow3-probe`) çalıştırma ve log yönlendirme.
|
||||
* `config.rs`: `launcher_config.json` yönetimi, donanım optimizasyonları ve otomatik sistem dili algılama (`default_language()`).
|
||||
* `i18n.rs`: 4 dilli arayüz yerelleştirmesi (Türkçe, English, Deutsch, Español).
|
||||
* `crash_analyzer.rs`: Oyun çöktüğünde `gow3_log.txt` çıktısını analiz edip kullanıcıya çözüm sunan hata teşhis motoru.
|
||||
* **Dağıtılan İkili Dosyalar (Binaries):**
|
||||
* Linux: `gow3-launcher`
|
||||
* Windows: `gow3-launcher-win.exe`
|
||||
* Alt dizin kopyaları: `gow3-linux/gow3-launcher`, `gow3-linux/gow3-launcher-win.exe`
|
||||
|
||||
---
|
||||
|
||||
## 2. Discord Rich Presence (RPC) Entegrasyonu
|
||||
|
||||
* **Resmi App ID:** `1440140183675867156` (*God of War III: Remastered*)
|
||||
* **Resmi Varlıklar (Assets):**
|
||||
* Kapak İkonu (Large Image): `https://cdn.discordapp.com/app-icons/1440140183675867156/2cbf4c7faf6444d474ff7b32b2025ec2.png`
|
||||
* Rozet İkonu (Small Image): `https://raw.githubusercontent.com/ScreamAngel/gow3_launcher/main/gow3.png`
|
||||
* **İletişim Kanalları:**
|
||||
* **Linux:** `$XDG_RUNTIME_DIR/discord-ipc-0`..`9`, `/tmp/discord-ipc-0`..`9`, Flatpak, Snap ve Vesktop (`vesktop-ipc`).
|
||||
* **Windows:** `\\.\pipe\discord-ipc-0`..`9` (Named Pipes). Olası donmaları engellemek için `PeekNamedPipe` ile asenkron kontrol mekanizması eklendi.
|
||||
* **Gerçek Zamanlı Durum Tespiti:**
|
||||
* `gow3_log.txt` dosyasından gerçek çalışma zamanı WAD yüklemeleri (`WAD_STATS: WAD <NAME>` ve `/WAD/PS4_LE/<NAME>.WAD`) taranır. Statik motor sözlüğü (`LoadWadSizeData`) **yoksayılır**.
|
||||
* `user/savedata/*/CUSA01715/*.sce_sys/param.bin` SFO dosyasından anlık kayıt checkpoint'i ve zorluk derecesi çekilir.
|
||||
* Ters kronolojik (newest-first) algoritma ile oyuncunun bulunduğu son bölge veya boss savaşı anlık belirlenir.
|
||||
* **Otomatik Dil Desteği (tr, en, de, es):**
|
||||
* İşletim sistemi dili (Linux'ta `$LANG`, Windows'ta `GetUserDefaultUILanguage`) veya launcher arayüz dili baz alınarak durum otomatik yerelleştirilir.
|
||||
* **Bölüm & Boss Karşılıkları:**
|
||||
* Poseidon Boss Savaşı: `Olympus Dağı (Poseidon Boss Fight)` / `Mount Olympus (Poseidon Boss Fight)`
|
||||
* Hades Boss Savaşı: `Yeraltı Dünyası (Hades Boss Fight)` / `The Underworld (Hades Boss Fight)`
|
||||
* Helios Boss Savaşı: `Olimpiya Şehri (Helios Boss Fight)` / `City of Olympia (Helios Boss Fight)`
|
||||
* Hermes Kovalamacası: `Olimpiya Şehri (Hermes Kovalamacası)` / `City of Olympia (Hermes Chase)`
|
||||
* Herkül Boss Savaşı: `Olympus Forumu (Hercules Boss Fight)` / `Forum of Olympus (Hercules Boss Fight)`
|
||||
* Kronos Boss Savaşı: `Tartarus Çukuru (Cronos Boss Fight)` / `Pit of Tartarus (Cronos Boss Fight)`
|
||||
* Hephaistos Boss Savaşı: `Demirhane (Hephaestus Boss Fight)` / `The Forge (Hephaestus Boss Fight)`
|
||||
* Skorpius Boss Savaşı: `Olimpos Mağaraları (Skorpius Boss Fight)` / `Caverns of Olympus (Skorpius Boss Fight)`
|
||||
* Zeus Boss Savaşı: `Olympus Tepesi (Zeus Boss Fight)` / `Summit of Olympus (Zeus Boss Fight)`
|
||||
* Mücadeleler: `Olympus Mücadelesi 1-7` / `Challenge of Olympus 1-7`
|
||||
* Savaş Arenası: `Savaş Arenası (Combat Arena)` / `Combat Arena`
|
||||
* Menü: `Ana Menüde` / `In Main Menu`
|
||||
* Shader Derleme: `Shader'lar Derleniyor (%X)` / `Compiling Shaders (X%)`
|
||||
|
||||
---
|
||||
|
||||
## 3. Çözülen Kritik Hatalar ve Teknik Notlar
|
||||
|
||||
1. **Windows Fare Tıklama Algılama Hatası:**
|
||||
* Sorun: Windows'ta sol ve sağ tık çalışmıyordu.
|
||||
* Çözüm: `win_input.rs` içindeki `WH_MOUSE_LL` kancasında PS4 SDL2 girdi haritasının beklediği F13/F14 sanal tarama kodları (`0x64` = Kare/Hafif Vuruş, `0x65` = Üçgen/Ağır Vuruş) düzeltildi.
|
||||
2. **Windows Siyah Ekran / Mod Açılış Hatası:**
|
||||
* Sorun: NTFS junction oluşturma yetki hatası yüzünden Windows'ta oyun siyah ekranda takılıyordu.
|
||||
* Çözüm: `runner.rs` içinde Rust tabanlı doğrudan dosya kopyalama bindirmesi (`out/mod-game-rust-overlay`) uygulandı, yol formatı ve dosya doğrulaması eklendi.
|
||||
3. **Shader Ekranı Küçülme / Kapanma / Arka Plana Düşme:**
|
||||
* Sorun: Shader derleme ekranı açıldığında oyun arka plana düşüyor veya görev çubuğuna küçülüyordu.
|
||||
* Çözüm: Oyun penceresi açıldığında shader ekranı 10 saniye boyunca arka planda tam ekran açık kalır, oyun penceresi öne getirilir (`bring_game_window_to_front`) ve süre bitiminde launcher normal moduna döner (asla küçülmez).
|
||||
4. **Linux Hyprland / Wayland Tam Ekran Hatası:**
|
||||
* Sorun: Windows için eklenen pencere boyutu komutları Linux Wayland'de oyunun kenarlıksız pencere moduna geçmesini bozuyordu.
|
||||
* Çözüm: `Maximized(true)` ve ilgili `ViewportCommand` çağrıları `#[cfg(target_os = "windows")]` ile izole edildi, Linux'ta yerel `hyprctl` ve saf Wayland geometri protokolü korundu.
|
||||
5. **Discord RPC'nin Sadece "Ana Menüde" Kalması:**
|
||||
* Sorun: Motorun statik `LoadWadSizeData: WAD_Shell` satırı yüzünden log döngüsü erken çıkış veriyor ve boss/bölüm adımlarını atlıyordu.
|
||||
* Çözüm: Statik sözlük filtrelendi, gerçek WAD yüklemeleri ters sırada önceliklendirildi.
|
||||
|
||||
---
|
||||
|
||||
## 4. Derleme ve Test Komutları
|
||||
|
||||
* **Birim Testleri (30 Test):**
|
||||
```bash
|
||||
cargo test --manifest-path launcher/Cargo.toml
|
||||
```
|
||||
* **Linux Release Derlemesi:**
|
||||
```bash
|
||||
cargo build --release --manifest-path launcher/Cargo.toml
|
||||
cp -f launcher/target/release/launcher gow3-launcher
|
||||
cp -f launcher/target/release/launcher gow3-linux/gow3-launcher
|
||||
```
|
||||
* **Windows Release Derlemesi (Cross-Compile):**
|
||||
```bash
|
||||
cargo xwin build --release --manifest-path launcher/Cargo.toml --target x86_64-pc-windows-msvc
|
||||
cp -f launcher/target/x86_64-pc-windows-msvc/release/launcher.exe gow3-launcher-win.exe
|
||||
cp -f launcher/target/x86_64-pc-windows-msvc/release/launcher.exe gow3-linux/gow3-launcher-win.exe
|
||||
```
|
||||
@@ -415,3 +415,22 @@ void _ZN5ImGui11ProgressBarEfRK6ImVec2PKc(float fraction, const void* size_arg,
|
||||
(void)overlay;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
|
||||
(void)hinstDLL;
|
||||
(void)lpReserved;
|
||||
if (fdwReason == DLL_PROCESS_ATTACH) {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
__attribute__((constructor))
|
||||
static void gow3_runtime_preinit(void) {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1671,7 +1671,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "launcher"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui_extras",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "launcher"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 89 KiB |
@@ -18,6 +18,7 @@ pub enum ViewMode {
|
||||
#[default]
|
||||
MainMenu,
|
||||
Settings,
|
||||
Trophies,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
@@ -1209,6 +1210,10 @@ pub struct LauncherApp {
|
||||
|
||||
// Discord Rich Presence
|
||||
pub discord_rpc: crate::discord_rpc::DiscordRpc,
|
||||
|
||||
// PS4 Trophy System
|
||||
pub trophy_manager: Arc<std::sync::Mutex<crate::trophy::TrophyManager>>,
|
||||
pub trophy_watcher: Option<crate::trophy::TrophyWatcherService>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -1281,6 +1286,13 @@ impl LauncherApp {
|
||||
let discord_rpc = crate::discord_rpc::DiscordRpc::new(config.discord_rpc_enabled);
|
||||
discord_rpc.set_in_menu(&config.language);
|
||||
|
||||
let trophy_manager = Arc::new(std::sync::Mutex::new(crate::trophy::TrophyManager::new(&base_dir)));
|
||||
let trophy_watcher = Some(crate::trophy::TrophyWatcherService::start(
|
||||
base_dir.clone(),
|
||||
trophy_manager.clone(),
|
||||
config.language.clone(),
|
||||
));
|
||||
|
||||
let mut app = Self {
|
||||
base_dir: base_dir.clone(),
|
||||
config,
|
||||
@@ -1342,6 +1354,8 @@ impl LauncherApp {
|
||||
launcher_version,
|
||||
installed_mods,
|
||||
discord_rpc,
|
||||
trophy_manager,
|
||||
trophy_watcher,
|
||||
};
|
||||
|
||||
crate::log_info!("Launcher UI initialized successfully. Version: {}", app.launcher_version);
|
||||
@@ -1689,9 +1703,9 @@ impl LauncherApp {
|
||||
self.shader_loading = None;
|
||||
let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_secs() as i64).unwrap_or(0);
|
||||
let is_modded = self.installed_mods.iter().any(|m| m.is_enabled);
|
||||
self.discord_rpc.set_in_game(self.base_dir.clone(), now, self.config.target_fps, is_modded);
|
||||
self.discord_rpc.set_in_game(self.base_dir.clone(), now, self.config.target_fps, is_modded, &self.config.language);
|
||||
} else {
|
||||
self.discord_rpc.set_compiling_shaders(Some(0.0));
|
||||
self.discord_rpc.set_compiling_shaders(Some(0.0), &self.config.language);
|
||||
// Pre-warm all shaders to 100% with the full Spartan Rage bar before game window is displayed
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Fullscreen(true));
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -2150,7 +2164,7 @@ impl LauncherApp {
|
||||
);
|
||||
ui.painter().rect_filled(top_vignette, 0.0, egui::Color32::from_rgba_unmultiplied(0, 0, 0, 130));
|
||||
|
||||
let bottom_vignette_height = 145.0;
|
||||
let bottom_vignette_height = 168.0;
|
||||
let bottom_vignette = egui::Rect::from_min_max(
|
||||
egui::pos2(screen_rect.min.x, screen_rect.max.y - bottom_vignette_height),
|
||||
screen_rect.max,
|
||||
@@ -2235,6 +2249,11 @@ impl LauncherApp {
|
||||
self.current_lang = *lang;
|
||||
self.config.language = lang.code().to_string();
|
||||
let _ = self.config.save(&self.base_dir);
|
||||
self.discord_rpc.update_language(lang.code());
|
||||
self.discord_rpc.set_in_menu(lang.code());
|
||||
if let Some(ref watcher) = self.trophy_watcher {
|
||||
watcher.set_language(lang.code().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2463,12 +2482,12 @@ impl LauncherApp {
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Bottom-Left: Console Action Menu Items (Row 1: Latest News, Row 2: Mods, Row 3: Options)
|
||||
// 7. Bottom-Left: Console Action Menu Items (Row 1: Latest News, Row 2: Trophies, Row 3: Mods, Row 4: Options)
|
||||
let bl_x = screen_rect.min.x + 28.0;
|
||||
let bl_y = screen_rect.max.y - 124.0;
|
||||
let bl_y = screen_rect.max.y - 156.0;
|
||||
let bl_rect = egui::Rect::from_min_size(
|
||||
egui::pos2(bl_x, bl_y),
|
||||
egui::vec2(280.0, 114.0),
|
||||
egui::vec2(280.0, 146.0),
|
||||
);
|
||||
ui.scope_builder(egui::UiBuilder::new().max_rect(bl_rect), |ui| {
|
||||
ui.vertical(|ui| {
|
||||
@@ -2487,7 +2506,20 @@ impl LauncherApp {
|
||||
self.show_release_notes_modal = true;
|
||||
}
|
||||
|
||||
// Row 2: 📦 MODLAR / MODS
|
||||
// Row 2: 🏆 KUPALAR / TROPHIES
|
||||
if render_console_action_button(
|
||||
ui,
|
||||
"btn_trophies",
|
||||
"🏆",
|
||||
self.t("menu_trophies"),
|
||||
14.5,
|
||||
false,
|
||||
) {
|
||||
self.view_mode = ViewMode::Trophies;
|
||||
self.view_transition_start = std::time::Instant::now();
|
||||
}
|
||||
|
||||
// Row 3: 📦 MODLAR / MODS
|
||||
if render_console_action_button(
|
||||
ui,
|
||||
"btn_mods",
|
||||
@@ -2501,7 +2533,7 @@ impl LauncherApp {
|
||||
self.view_transition_start = std::time::Instant::now();
|
||||
}
|
||||
|
||||
// Row 3: ⚙️ AYARLAR / OPTIONS
|
||||
// Row 4: ⚙️ AYARLAR / OPTIONS
|
||||
if render_console_action_button(
|
||||
ui,
|
||||
"btn_options",
|
||||
@@ -2774,6 +2806,36 @@ impl LauncherApp {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn render_trophies_screen(&mut self, ui: &mut egui::Ui, _ctx: &egui::Context) {
|
||||
let screen_rect = ui.max_rect();
|
||||
|
||||
// 1. Fullscreen Wallpaper (pic1.png)
|
||||
if let Some(ref bg) = self.bg_texture {
|
||||
let uv = egui::Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0));
|
||||
ui.painter().image(bg.id(), screen_rect, uv, egui::Color32::from_white_alpha(90));
|
||||
}
|
||||
|
||||
// 2. Dark Frosted Backdrop
|
||||
ui.painter().rect_filled(
|
||||
screen_rect,
|
||||
0.0,
|
||||
egui::Color32::from_rgba_unmultiplied(10, 11, 16, 238),
|
||||
);
|
||||
|
||||
let mut back_clicked = false;
|
||||
let lang = self.current_lang.code().to_string();
|
||||
|
||||
ui.add_space(8.0);
|
||||
if let Ok(mut mgr) = self.trophy_manager.lock() {
|
||||
crate::trophy::render_trophy_dashboard(ui, &mut mgr, &lang, &mut back_clicked);
|
||||
}
|
||||
|
||||
if back_clicked {
|
||||
self.view_mode = ViewMode::MainMenu;
|
||||
self.view_transition_start = std::time::Instant::now();
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// SCREEN: SİSTEM ÖZELLİKLERİ (SYSTEM SPECS)
|
||||
// ==========================================
|
||||
@@ -3118,6 +3180,17 @@ impl LauncherApp {
|
||||
);
|
||||
}
|
||||
|
||||
ui.add_space(8.0);
|
||||
// 10. Bonus Play QTE and Enemy Spawning Fix
|
||||
ui.horizontal(|ui| {
|
||||
toggle_switch(ui, &mut self.config.bonus_play_fix);
|
||||
let lbl = self.t("bonus_play_fix_toggle");
|
||||
if ui.add(egui::Label::new(egui::RichText::new(lbl).strong().color(egui::Color32::WHITE).size(14.5)).sense(egui::Sense::click())).clicked() {
|
||||
self.config.bonus_play_fix = !self.config.bonus_play_fix;
|
||||
}
|
||||
});
|
||||
ui.label(egui::RichText::new(self.t("bonus_play_fix_desc")).color(egui::Color32::from_rgb(190, 195, 210)).size(12.5));
|
||||
|
||||
ui.add_space(12.0);
|
||||
ui.separator();
|
||||
ui.horizontal(|ui| {
|
||||
@@ -4442,7 +4515,7 @@ impl eframe::App for LauncherApp {
|
||||
|
||||
let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_secs() as i64).unwrap_or(0);
|
||||
let is_modded = self.installed_mods.iter().any(|m| m.is_enabled);
|
||||
self.discord_rpc.set_in_game(self.base_dir.clone(), now, self.config.target_fps, is_modded);
|
||||
self.discord_rpc.set_in_game(self.base_dir.clone(), now, self.config.target_fps, is_modded, &self.config.language);
|
||||
}
|
||||
|
||||
// Oyun penceresi açıldığında oyun ekranını en öne getir ve launcher'ı Normal seviyeye çek
|
||||
@@ -4530,10 +4603,11 @@ impl eframe::App for LauncherApp {
|
||||
s.spacing.scroll.foreground_color = true;
|
||||
});
|
||||
|
||||
// --- MAIN VIEW ROUTING: CONSOLE MAIN MENU OR SETTINGS SCREEN ---
|
||||
// --- MAIN VIEW ROUTING: CONSOLE MAIN MENU, SETTINGS SCREEN OR TROPHIES ---
|
||||
match self.view_mode {
|
||||
ViewMode::MainMenu => self.render_console_main_menu(ui, &ctx),
|
||||
ViewMode::Settings => self.render_settings_screen(ui, &ctx),
|
||||
ViewMode::Trophies => self.render_trophies_screen(ui, &ctx),
|
||||
}
|
||||
|
||||
// Dim background if any modal dialog is currently active
|
||||
@@ -5461,12 +5535,60 @@ impl eframe::App for LauncherApp {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- PS4 STYLE TROPHY TOAST NOTIFICATION RENDERER ---
|
||||
let toast_to_render = if let Ok(mut mgr) = self.trophy_manager.lock() {
|
||||
mgr.advance_queue(self.current_lang.code());
|
||||
mgr.active_toast.clone()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(ref toast) = toast_to_render {
|
||||
// 1. Standalone in-game overlay viewport (always on top of game screen at top-right)
|
||||
let (pos_x, pos_y) = if let Some(mon) = ctx.input(|i| i.viewport().monitor_size) {
|
||||
(mon.x - 390.0, 24.0)
|
||||
} else {
|
||||
(1920.0 - 390.0, 24.0)
|
||||
};
|
||||
|
||||
ctx.show_viewport_immediate(
|
||||
egui::ViewportId::from_hash_of("gow3_trophy_toast_overlay"),
|
||||
egui::ViewportBuilder::default()
|
||||
.with_title("God of War III Trophy Toast")
|
||||
.with_always_on_top()
|
||||
.with_decorations(false)
|
||||
.with_transparent(true)
|
||||
.with_mouse_passthrough(true)
|
||||
.with_active(false)
|
||||
.with_visible(true)
|
||||
.with_inner_size([380.0, 88.0])
|
||||
.with_position([pos_x, pos_y]),
|
||||
|ctx, _class| {
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame::new().fill(egui::Color32::TRANSPARENT))
|
||||
.show(ctx, |ui| {
|
||||
crate::trophy::render_ps4_toast(ui, toast, self.current_lang.code(), true);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// 2. Also render in the launcher window when the launcher is visible and game is not running
|
||||
if !self.is_game_running {
|
||||
crate::trophy::render_ps4_toast(ui, toast, self.current_lang.code(), false);
|
||||
}
|
||||
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LauncherApp {
|
||||
fn drop(&mut self) {
|
||||
self.discord_rpc.shutdown();
|
||||
if let Some(ref watcher) = self.trophy_watcher {
|
||||
watcher.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -245,6 +245,8 @@ pub struct LauncherConfig {
|
||||
#[serde(default = "default_true")]
|
||||
pub skip_cinematics: bool,
|
||||
#[serde(default = "default_true")]
|
||||
pub bonus_play_fix: bool,
|
||||
#[serde(default = "default_true")]
|
||||
pub use_gamemode: bool,
|
||||
#[serde(default = "default_vram_budget")]
|
||||
pub vram_gc_budget_mb: u64,
|
||||
@@ -307,7 +309,7 @@ fn default_discord_client_id() -> String {
|
||||
}
|
||||
|
||||
fn default_language() -> String {
|
||||
"tr".to_string()
|
||||
crate::discord_rpc::detect_system_language().to_string()
|
||||
}
|
||||
fn default_target_fps() -> u32 {
|
||||
60
|
||||
@@ -332,7 +334,7 @@ fn default_last_commit() -> String {
|
||||
"c5638d9956002b8a9f09a240028f6793ddf7b2f8".to_string()
|
||||
}
|
||||
fn default_launcher_version() -> String {
|
||||
"v2.1".to_string()
|
||||
"v2.2".to_string()
|
||||
}
|
||||
fn default_render_resolution() -> String {
|
||||
"native".to_string()
|
||||
@@ -352,6 +354,7 @@ impl Default for LauncherConfig {
|
||||
launch_while_compiling_shaders: false,
|
||||
show_shader_compile_rage_meter: true,
|
||||
skip_cinematics: true,
|
||||
bonus_play_fix: true,
|
||||
use_gamemode: true,
|
||||
vram_gc_budget_mb: default_vram_budget(),
|
||||
dmem_mb: default_dmem(),
|
||||
@@ -801,11 +804,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_launcher_version_is_v20() {
|
||||
assert_eq!(default_launcher_version(), "v2.1");
|
||||
fn test_launcher_version_is_v22() {
|
||||
assert_eq!(default_launcher_version(), "v2.2");
|
||||
let def = LauncherConfig::default();
|
||||
assert!(def.async_readbacks);
|
||||
assert!(def.patch_readbacks);
|
||||
assert!(def.bonus_play_fix);
|
||||
assert!(def.discord_rpc_enabled);
|
||||
assert_eq!(def.discord_client_id, crate::discord_rpc::DISCORD_GOW3_APP_ID);
|
||||
}
|
||||
|
||||
@@ -150,11 +150,14 @@ pub fn text(lang: Language, key: &str) -> &'static str {
|
||||
(Language::Turkish, "system_specs_title") => "SİSTEM ÖZELLİKLERİ",
|
||||
(Language::Turkish, "play_btn_label") => "OYNA",
|
||||
(Language::Turkish, "menu_play") => "OYNA",
|
||||
(Language::Turkish, "menu_trophies") => "KUPALAR",
|
||||
(Language::Turkish, "menu_latest_news") => "GÜNCELLEME NOTLARI",
|
||||
(Language::Turkish, "menu_options") => "AYARLAR",
|
||||
(Language::Turkish, "menu_back") => "GERİ DÖN",
|
||||
(Language::Turkish, "release_notes_title") => "God of War III Launcher - Sürüm Notları (v2.1)",
|
||||
(Language::Turkish, "release_notes_content") => "🔥 GOD OF WAR III LAUNCHER v2.1 YENİLİKLERİ:\n\n• 🎮 Gelişmiş Discord Rich Presence (Bölüm & Boss Fight Tespiti):\n - Resmi 'God of War III: Remastered' Discord App ID (1440140183675867156) ve yüksek çözünürlüklü kapak görseli entegre edildi.\n - Canlı Bölüm ve Chapter Takibi: 'Olympus Dağı', 'Yeraltı Dünyası', 'Labirent', 'Tartarus', 'Olimpiya Şehri', 'Alev Odası' vb.\n - Boss Karşılaşmaları: 'Olympus Dağı (Poseidon Boss Fight)', 'Yeraltı Dünyası (Hades Boss Fight)', 'Tartarus (Kronos Boss Fight)', 'Forum (Herkül Boss Fight)', 'Olimpos Zirvesi (Zeus Boss Fight)' ve diğerleri anlık olarak Discord profilinizde görünür.\n - Özel Modlar: 'Olimpos Mücadeleleri (Challenge of Olympus)' ve 'Savaş Arenası (Combat Arena)' durumu canlı paylaşılır.\n\n• ⚡ Sıfır Performans Kaybı & Geniş İstemci Desteği:\n - Windows Named Pipes, Linux yerel soketleri, Vesktop, Discord Flatpak ve Snap istemcilerini otomatik algılar.\n\n• 🛠️ Genel İyileştirmeler & Kararlılık Güncellemeleri.",
|
||||
(Language::Turkish, "bonus_play_fix_toggle") => "Bonus Play QTE & Düşman Doğma Düzeltmesi",
|
||||
(Language::Turkish, "bonus_play_fix_desc") => "Tanrısal Eşyalar (Godly Possessions / Hephaistos'un Yüzüğü) aktifken QTE sekanslarının erken tetiklenip düşman dalgalarını (arena kilitlenmelerini) ve tuş göstergelerini engellemesini önler.",
|
||||
(Language::Turkish, "release_notes_title") => "God of War III Launcher - Sürüm Notları (v2.2)",
|
||||
(Language::Turkish, "release_notes_content") => "🔥 GOD OF WAR III LAUNCHER v2.2 YENİLİKLERİ:\n\n• 🏆 Gerçek Zamanlı Kupa (Trophy) ve PS4 Bildirim Sistemi:\n - Resmi 36 kupanın tamamı, yüksek çözünürlüklü ikonları ve Türkçe/İngilizce açıklamalarıyla entegre edildi.\n - PS4 Stili Sağ Üst Bildirim Hapı (Toast Notification): Kupa kazanıldığında sağdan kayarak gelir, 4 saniye ekranda kalır ve kararır.\n - Orijinal PS4 Kupa Kazanma Sesi (Trophy Pop SFX) milisaniyesinde çalar.\n - Sıralı Kuyruk Yönetimi (FIFO): Üst üste binen kupaları sıralı gösterir.\n - Kupa Merkezi (Dashboard): İlerleme çubuğu, %100 Platin Ustalık Mührü, filtreleme, kupa arama ve gizli kupa açma desteği.\n\n• 🗡️ Bonus Play & Tanrısal Eşyalar (Godly Possessions) Düzeltmesi:\n - Hephaistos'un Yüzüğü ve diğer bonus eşyalar aktifken QTE'lerin erken tetiklenip düşman dalgalarını engellemesi ve arena kilitlenmeleri düzeltildi.\n\n• 🎮 Kararlılık ve Performans İyileştirmeleri.",
|
||||
(Language::Turkish, "discord_rpc_toggle") => "Discord Rich Presence (Oynuyor Durumu)",
|
||||
(Language::Turkish, "discord_rpc_desc") => "Discord profilinizde 'God of War III: Remastered', bulunduğunuz bölüm, boss savaşları ve oynama sürenizi canlı gösterir.",
|
||||
(Language::Turkish, "discord_client_id_label") => "Discord Uygulama Kimliği (Client ID):",
|
||||
@@ -416,11 +419,14 @@ pub fn text(lang: Language, key: &str) -> &'static str {
|
||||
(Language::English, "system_specs_title") => "SYSTEM SPECIFICATIONS",
|
||||
(Language::English, "play_btn_label") => "PLAY",
|
||||
(Language::English, "menu_play") => "PLAY",
|
||||
(Language::English, "menu_trophies") => "TROPHIES",
|
||||
(Language::English, "menu_latest_news") => "LATEST NEWS",
|
||||
(Language::English, "menu_options") => "OPTIONS",
|
||||
(Language::English, "menu_back") => "BACK",
|
||||
(Language::English, "release_notes_title") => "God of War III Launcher - Release Notes (v2.1)",
|
||||
(Language::English, "release_notes_content") => "🔥 GOD OF WAR III LAUNCHER v2.1 CHANGELOG:\n\n• 🎮 Advanced Discord Rich Presence (Chapters & Boss Fights):\n - Official 'God of War III: Remastered' Discord App ID (1440140183675867156) and official artwork.\n - Real-time Chapter Tracking: 'Mount Olympus', 'Realm of Hades', 'The Labyrinth', 'Tartarus', 'City of Olympia', etc.\n - Boss Fight Detection: 'Olympus Dağı (Poseidon Boss Fight)', 'Yeraltı Dünyası (Hades Boss Fight)', 'Tartarus (Kronos Boss Fight)', 'Forum (Hercules Boss Fight)', 'Mount Olympus Summit (Zeus Boss Fight)', etc.\n - Special Modes: 'Challenge of Olympus' and 'Combat Arena' detected automatically.\n\n• ⚡ Broad Client Support:\n - Works with native Discord, Vesktop, Flatpak, Snap, and Windows Named Pipes.",
|
||||
(Language::English, "bonus_play_fix_toggle") => "Bonus Play QTE & Enemy Spawning Fix",
|
||||
(Language::English, "bonus_play_fix_desc") => "Prevents Godly Possession bonus items (specifically Hephaestus' Ring) from auto-skipping QTEs prematurely, preventing missing enemy wave spawns and missing QTE prompts.",
|
||||
(Language::English, "release_notes_title") => "God of War III Launcher - Release Notes (v2.2)",
|
||||
(Language::English, "release_notes_content") => "🔥 GOD OF WAR III LAUNCHER v2.2 CHANGELOG:\n\n• 🏆 Real-Time Trophy System & PS4 Notification Integration:\n - All 36 trophies tracked with official badges, unlock conditions, and local persistence (trophies_state.json).\n - PS4-Style Pill Toast Notification in the top-right corner with smooth slide-in, 4s hold, and soft fade-out.\n - Authentic PS4 Trophy Pop SFX played at the millisecond of unlocking.\n - Sequential Notification Queue (FIFO) for multiple unlocks.\n - Full Trophy Showcase & Dashboard: Progress bar, dynamic percentage, 100% Platinum Mastery Badge, search & filter.\n\n• 🗡️ Bonus Play & Godly Possessions Fix:\n - Fixed missing enemies and QTE softlocks when equipping Hephaestus' Ring and bonus items.\n\n• ⚡ Stability & performance enhancements.",
|
||||
(Language::English, "discord_rpc_toggle") => "Discord Rich Presence (Activity Status)",
|
||||
(Language::English, "discord_rpc_desc") => "Displays 'God of War III: Remastered', your active chapter, boss fights, and elapsed play time on Discord.",
|
||||
(Language::English, "discord_client_id_label") => "Discord Application ID (Client ID):",
|
||||
@@ -682,11 +688,14 @@ pub fn text(lang: Language, key: &str) -> &'static str {
|
||||
(Language::German, "system_specs_title") => "SYSTEMSPEZIFIKATIONEN",
|
||||
(Language::German, "play_btn_label") => "SPIELEN",
|
||||
(Language::German, "menu_play") => "SPIELEN",
|
||||
(Language::German, "menu_trophies") => "TROPHÄEN",
|
||||
(Language::German, "menu_latest_news") => "NEUIGKEITEN",
|
||||
(Language::German, "menu_options") => "OPTIONEN",
|
||||
(Language::German, "menu_back") => "ZURÜCK",
|
||||
(Language::German, "release_notes_title") => "God of War III Launcher - Versionshinweise (v2.1)",
|
||||
(Language::German, "release_notes_content") => "🔥 GOD OF WAR III LAUNCHER v2.1 NEUIGKEITEN:\n\n• 🎮 Discord Rich Presence Integration:\n - Zeigt 'Spielt God of War III Remastered' mit Kratos-Cover und Spielzeitzähler in deinem Discord-Profil an.\n - Automatische Statusmeldungen für Hauptmenü, Shader-Kompilierung und Spielverlauf.\n - In den Einstellungen ein-/ausschaltbar mit optionaler benutzerdefinierter Client-ID.\n\n• ⚡ Keine Performance-Einbußen & Nahtlose Verbindung.",
|
||||
(Language::German, "bonus_play_fix_toggle") => "Bonus Play QTE & Gegner-Spawn-Korrektur",
|
||||
(Language::German, "bonus_play_fix_desc") => "Verhindert, dass göttliche Besitztümer (Hephaistos' Ring) QTEs vorzeitig überspringen und dadurch das Erscheinen von Gegnerwellen blockieren.",
|
||||
(Language::German, "release_notes_title") => "God of War III Launcher - Versionshinweise (v2.2)",
|
||||
(Language::German, "release_notes_content") => "🔥 GOD OF WAR III LAUNCHER v2.2 NEUIGKEITEN:\n\n• 🏆 Echzeit-Trophäensystem & PS4-Benachrichtigung:\n - Alle 36 Trophäen mit Originalgrafiken, Benachrichtigungskapsel und PS4-Soundeffekt.\n - Trophäen-Showcase mit Fortschrittsanzeige und 100%-Platin-Abzeichen.\n\n• 🗡️ Bonus-Gegenstände Bugfix (QTE & Gegner-Spawn-Korrektur).",
|
||||
(Language::German, "discord_rpc_toggle") => "Discord Rich Presence (Spielstatus)",
|
||||
(Language::German, "discord_rpc_desc") => "Zeigt 'Spielt God of War III Remastered' und die Spielzeit in deinem Discord-Profil an.",
|
||||
(Language::German, "discord_client_id_label") => "Discord Anwendungs-ID (Client ID):",
|
||||
@@ -946,11 +955,14 @@ pub fn text(lang: Language, key: &str) -> &'static str {
|
||||
(Language::Spanish, "system_specs_title") => "ESPECIFICACIONES DEL SISTEMA",
|
||||
(Language::Spanish, "play_btn_label") => "JUGAR",
|
||||
(Language::Spanish, "menu_play") => "JUGAR",
|
||||
(Language::Spanish, "menu_trophies") => "TROFEOS",
|
||||
(Language::Spanish, "menu_latest_news") => "ÚLTIMAS NOTICIAS",
|
||||
(Language::Spanish, "menu_options") => "OPCIONES",
|
||||
(Language::Spanish, "menu_back") => "VOLVER",
|
||||
(Language::Spanish, "release_notes_title") => "God of War III Launcher - Notas de la Versión (v2.1)",
|
||||
(Language::Spanish, "release_notes_content") => "🔥 NOVEDADES DE GOD OF WAR III LAUNCHER v2.1:\n\n• 🎮 Integración con Discord Rich Presence:\n - Muestra 'Jugando a God of War III Remastered' con arte de Kratos y contador de tiempo en tu perfil de Discord.\n - Estados automáticos: En el Menú Principal, Compilando Shaders y Escalando el Monte Olimpo.\n - Se puede activar/desactivar en Ajustes con soporte para Client ID personalizado.\n\n• ⚡ Cero impacto en el rendimiento y conexión inteligente.",
|
||||
(Language::Spanish, "bonus_play_fix_toggle") => "Corrección de QTE y Enemigos en Bonus Play",
|
||||
(Language::Spanish, "bonus_play_fix_desc") => "Evita que las Posesiones Divinas (Anillo de Hefesto) omitan los QTEs prematuramente y bloqueen la aparición de oleadas de enemigos.",
|
||||
(Language::Spanish, "release_notes_title") => "God of War III Launcher - Notas de la Versión (v2.2)",
|
||||
(Language::Spanish, "release_notes_content") => "🔥 NOVEDADES DE GOD OF WAR III LAUNCHER v2.2:\n\n• 🏆 Sistema de Trofeos en Tiempo Real y Notificaciones PS4:\n - Los 36 trofeos oficiales con insignias en alta resolución y efectos de sonido de PS4.\n - Notificaciones flotantes estilo cápsula PS4 y panel de trofeos con medalla de maestría al 100%.\n\n• 🗡️ Corrección de errores en objetos de Bonus Play (QTE y generación de enemigos).",
|
||||
(Language::Spanish, "discord_rpc_toggle") => "Discord Rich Presence (Estado de Juego)",
|
||||
(Language::Spanish, "discord_rpc_desc") => "Muestra 'Jugando a God of War III Remastered' y el tiempo de juego en tu perfil de Discord.",
|
||||
(Language::Spanish, "discord_client_id_label") => "ID de Aplicación de Discord (Client ID):",
|
||||
|
||||
@@ -12,6 +12,7 @@ mod shader_downloader;
|
||||
pub mod mods_manager;
|
||||
pub mod discord_rpc;
|
||||
pub mod win_input;
|
||||
pub mod trophy;
|
||||
|
||||
use app::LauncherApp;
|
||||
use eframe::egui;
|
||||
@@ -81,6 +82,7 @@ fn main() -> eframe::Result<()> {
|
||||
native_options,
|
||||
Box::new(move |cc| {
|
||||
egui_extras::install_image_loaders(&cc.egui_ctx);
|
||||
cc.egui_ctx.set_embed_viewports(false);
|
||||
|
||||
// Register God of War Font and make it primary for Spartan style with unicode fallback
|
||||
let mut fonts = egui::FontDefinitions::default();
|
||||
|
||||
@@ -1313,6 +1313,11 @@ pub fn launch_gow3(
|
||||
|
||||
patch_list.push("Bug Fix - Startup Black Screen".to_string());
|
||||
patch_list.push("Bug Fix - Intro Crash Fix".to_string());
|
||||
patch_list.push("Bug Fix - Trophy Unlock Fix".to_string());
|
||||
|
||||
if config.bonus_play_fix {
|
||||
patch_list.push("Bug Fix - Bonus Play QTE and Enemy Spawning Fix".to_string());
|
||||
}
|
||||
|
||||
if config.skip_cinematics {
|
||||
patch_list.push("Skip Any Video With X Button".to_string());
|
||||
@@ -1341,15 +1346,25 @@ pub fn launch_gow3(
|
||||
}
|
||||
let patches_str = patch_list.join(";");
|
||||
|
||||
// Prepare active patches directory: copy built-in patch XML + XML patches from enabled mods
|
||||
// Prepare active patches directory: copy custom XML patches (excluding built-in) + XML patches from enabled mods
|
||||
let active_patches_dir = out_dir.join("active_patches");
|
||||
let _ = fs::remove_dir_all(&active_patches_dir);
|
||||
let _ = fs::create_dir_all(&active_patches_dir);
|
||||
|
||||
// Copy built-in XML
|
||||
let builtin_xml = patches_path.join("God_of_War_III_Remastered.xml");
|
||||
if builtin_xml.is_file() {
|
||||
let _ = fs::copy(&builtin_xml, active_patches_dir.join("God_of_War_III_Remastered.xml"));
|
||||
// Copy any custom XML patches from patches_path (excluding built-in God_of_War_III_Remastered.xml)
|
||||
if patches_path.is_dir() {
|
||||
if let Ok(entries) = fs::read_dir(&patches_path) {
|
||||
for entry in entries.flatten() {
|
||||
let p = entry.path();
|
||||
if p.is_file() && p.extension().map_or(false, |ext| ext.eq_ignore_ascii_case("xml")) {
|
||||
if let Some(file_name) = p.file_name() {
|
||||
if !file_name.eq_ignore_ascii_case("God_of_War_III_Remastered.xml") {
|
||||
let _ = fs::copy(&p, active_patches_dir.join(file_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and copy all XML patches from enabled mods
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::process::Command;
|
||||
use crate::config::LauncherConfig;
|
||||
use crate::tuner::apply_settings;
|
||||
|
||||
pub const BUILTIN_VERSION: &str = "v2.1";
|
||||
pub const BUILTIN_VERSION: &str = "v2.2";
|
||||
pub const GITHUB_REPO: &str = "ScreamAngel/gow3_launcher";
|
||||
pub const GITHUB_REPO_URL: &str = "https://github.com/ScreamAngel/gow3_launcher.git";
|
||||
|
||||
|
||||
@@ -110,6 +110,14 @@ mod imp {
|
||||
fn WindowFromPoint(point: POINT) -> HWND;
|
||||
fn GetAncestor(hwnd: HWND, ga_flags: u32) -> HWND;
|
||||
fn AttachThreadInput(id_attach: u32, id_attach_to: u32, f_attach: i32) -> i32;
|
||||
fn PlaySoundA(psz_sound: *const u8, hmod: HINSTANCE, fdw_sound: u32) -> i32;
|
||||
}
|
||||
|
||||
pub fn play_sound_memory(bytes: &[u8]) {
|
||||
unsafe {
|
||||
// SND_ASYNC = 0x0001, SND_NODEFAULT = 0x0002, SND_MEMORY = 0x0004
|
||||
PlaySoundA(bytes.as_ptr(), 0, 0x0001 | 0x0002 | 0x0004);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn is_game_window(hwnd: HWND) -> bool {
|
||||
@@ -339,6 +347,7 @@ mod stub {
|
||||
pub fn find_game_hwnd(_pid: u32) -> Option<isize> {
|
||||
None
|
||||
}
|
||||
pub fn play_sound_memory(_bytes: &[u8]) {}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"launch_while_compiling_shaders": false,
|
||||
"show_shader_compile_rage_meter": false,
|
||||
"skip_cinematics": true,
|
||||
"bonus_play_fix": true,
|
||||
"use_gamemode": true,
|
||||
"vram_gc_budget_mb": 6144,
|
||||
"dmem_mb": 9216,
|
||||
@@ -22,19 +23,16 @@
|
||||
"cpu_threads": 20
|
||||
},
|
||||
"last_git_commit": "0b4abe07acb711848d1b5d72402a9de8c0ad9844",
|
||||
"launcher_version": "v2.1",
|
||||
"discord_rpc_enabled": true,
|
||||
"discord_client_id": "1124351711486689290",
|
||||
"launcher_version": "v2.2",
|
||||
"disabled_mods": [
|
||||
"(OPTIONAL) God Armor",
|
||||
"Blades of Athena Damage Boost",
|
||||
"CJ (Mod by Gamer JP)",
|
||||
"game",
|
||||
"Game",
|
||||
"god armor By Richarito v2",
|
||||
"Golden Blades",
|
||||
"DiamondSword v1.1 Author YT @MustopuhGGI",
|
||||
"Skeleton Kratos Skin"
|
||||
"Skeleton Kratos Skin",
|
||||
"Golden Blades",
|
||||
"CJ (Mod by Gamer JP)"
|
||||
],
|
||||
"render_resolution": "native",
|
||||
"fsr_enabled": false,
|
||||
@@ -49,10 +47,10 @@
|
||||
"deadzone_left": 2,
|
||||
"deadzone_right": 2,
|
||||
"keyboard_bindings": {
|
||||
"triangle": "u",
|
||||
"circle": "j",
|
||||
"cross": "g",
|
||||
"square": "t",
|
||||
"triangle": "mouse2",
|
||||
"circle": "f",
|
||||
"cross": "space",
|
||||
"square": "mouse1",
|
||||
"l1": "q",
|
||||
"r1": "e",
|
||||
"l2": "z",
|
||||
@@ -73,5 +71,7 @@
|
||||
"axis_right_x_plus": "kp6",
|
||||
"axis_right_y_minus": "kp8",
|
||||
"axis_right_y_plus": "kp2"
|
||||
}
|
||||
},
|
||||
"discord_rpc_enabled": true,
|
||||
"discord_client_id": "1440140183675867156"
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
{
|
||||
"disabled": [
|
||||
"(OPTIONAL) God Armor",
|
||||
"Blades of Athena Damage Boost",
|
||||
"CJ (Mod by Gamer JP)",
|
||||
"game",
|
||||
"Game",
|
||||
"god armor By Richarito v2",
|
||||
"Golden Blades",
|
||||
"DiamondSword v1.1 Author YT @MustopuhGGI",
|
||||
"Skeleton Kratos Skin"
|
||||
"Skeleton Kratos Skin",
|
||||
"Golden Blades",
|
||||
"CJ (Mod by Gamer JP)"
|
||||
],
|
||||
"order": []
|
||||
}
|
||||
@@ -31,6 +31,12 @@
|
||||
<Line Type="bytes" Address="0x006de2c7" Value="0f84d600000090"/>
|
||||
</PatchList>
|
||||
</Metadata>
|
||||
<Metadata Title="God of War III Remastered" Name="Bug Fix - Bonus Play QTE and Enemy Spawning Fix" Note="Fixes a critical scripting desynchronization in God of War III Bonus Play when Godly Possessions (specifically Hephaestus' Ring) are active. Prevents auto-QTE from prematurely skipping context-sensitive animation death callbacks, ensuring enemy wave spawns and QTE triggers progress without arena softlocks." Author="gow3-launcher" PatchVer="1.0" AppVer="01.02" AppElf="eboot.bin" isEnabled="true">
|
||||
<PatchList>
|
||||
<Line Type="bytes" Address="0x0041b2a3" Value="7542"/>
|
||||
<Line Type="bytes" Address="0x0041b2e7" Value="b901000000909090"/>
|
||||
</PatchList>
|
||||
</Metadata>
|
||||
<Metadata Title="God of War III Remastered" Name="Resolution Patch - 480p" Note="Decreases game output resolution to 854x480 and increases Video Arena to 2.25 GiB. Requires setting DMEM to 2048 MB or more. Only leave one resolution patch enabled; do not enable it with Bug Fix - Texture Corruption Fix." Author="kvicken + cuesta4" PatchVer="1.1" AppVer="01.02" AppElf="eboot.bin" isEnabled="false">
|
||||
<PatchList>
|
||||
<Line Type="bytes" Address="0x005f0c5b" Value="56030000"/>
|
||||
@@ -201,4 +207,14 @@
|
||||
<Line Type="bytes" Address="0x00566090" Value="c3"/>
|
||||
</PatchList>
|
||||
</Metadata>
|
||||
<Metadata Title="God of War III Remastered" Name="Bug Fix - Trophy Unlock Fix" Note="Disables Bonus Play trophy restriction and bounds checks in eboot.bin, enabling all 35 trophies to unlock seamlessly." Author="gow3-launcher" PatchVer="2.1" AppVer="01.02" AppElf="eboot.bin" isEnabled="true">
|
||||
<PatchList>
|
||||
<Line Type="bytes" Address="0x0041ef88" Value="909090909090"/>
|
||||
<Line Type="bytes" Address="0x0041efce" Value="909090909090"/>
|
||||
<Line Type="bytes" Address="0x0041f709" Value="9090"/>
|
||||
<Line Type="bytes" Address="0x0041f73a" Value="9090"/>
|
||||
<Line Type="bytes" Address="0x004252e9" Value="9090"/>
|
||||
<Line Type="bytes" Address="0x00425330" Value="9090"/>
|
||||
</PatchList>
|
||||
</Metadata>
|
||||
</Patch>
|
||||
@@ -0,0 +1,181 @@
|
||||
{
|
||||
"title_id": "CUSA01715",
|
||||
"last_updated": 1794235113,
|
||||
"trophies": {
|
||||
"0": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"1": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"2": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"3": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"4": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"5": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"6": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"7": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"8": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"9": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"10": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"11": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"12": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"13": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"14": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"15": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"16": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"17": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"18": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"19": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"20": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"21": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"22": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"23": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"24": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"25": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"26": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"27": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"28": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"29": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"30": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"31": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"32": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"33": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
},
|
||||
"34": {
|
||||
"unlocked": false,
|
||||
"unlocked_at": null,
|
||||
"unlocked_at_formatted": null
|
||||
}
|
||||
}
|
||||
}
|
||||