Seregon/ShadPKG

A tool for deriving PKG packet encryption keys for ps4 written in c++

C++/47.3 KB/No license
gui/main_gui.cpp
ShadPKG / gui / main_gui.cpp
1// SPDX-FileCopyrightText: Copyright 2025 shadPKG
2// SPDX-License-Identifier: GPL-2.0-or-later
3 
4// ╔═══════════════════════════════════════════════════════════════════════════╗
5// ║ ShadPKG GUI - Main Entry Point ║
6// ║ ║
7// ║ ImGui + GLFW + OpenGL3 Application ║
8// ║ ║
9// ║ Window Layout: ║
10// ║ ┌──────────────┬──────────────────────────────────────────────────────┐ ║
11// ║ │ │ │ ║
12// ║ │ NAV BAR │ MAIN VIEWPORT │ ║
13// ║ │ │ (Dynamic view content) │ ║
14// ║ │ [Extract] │ │ ║
15// ║ │ [Inspect] │ │ ║
16// ║ │ [RIF Tool] ├──────────────────────────────────────────────────────┤ ║
17// ║ │ [Settings] │ CONSOLE LOG │ ║
18// ║ │ │ [INFO] System initialized... │ ║
19// ║ └──────────────┴──────────────────────────────────────────────────────┘ ║
20// ║ ║
21// ╚═══════════════════════════════════════════════════════════════════════════╝
22 
23#include "common/assert.h"
24#include <assert.h>
25#ifndef IM_ASSERT
26#define IM_ASSERT(_EXPR) ASSERT(_EXPR)
27#endif
28#include "imgui.h"
29#include "imgui_impl_glfw.h"
30#include "imgui_impl_opengl3.h"
31 
32#if defined(__APPLE__)
33#include <OpenGL/gl3.h>
34#elif defined(_WIN32)
35#define WIN32_LEAN_AND_MEAN
36#include <GL/gl.h>
37#include <windows.h>
38#else
39#include <GL/gl.h>
40#endif
41#include <GLFW/glfw3.h>
42 
43#include <cstdio>
44#include <cstdlib>
45#include <filesystem>
46#include <string>
47#include <vector>
48 
49// GUI Components
50#include "include/ConsoleLog.h"
51#include "include/GUIContext.h"
52#include "include/GuiLogSink.h"
53#include "include/NavBar.h"
54#include "include/StyleManager.h"
55 
56// Views
57#include "include/views/DecompilerView.h"
58#include "include/views/ExtractorView.h"
59#include "include/views/InspectorView.h"
60#include "include/views/RIFView.h"
61#include "include/views/SettingsView.h"
62#include "include/views/StructEditorView.h"
63 
64// Logging
65#include "common/logging/backend.h"
66#include "common/logging/log.h"
67 
68using namespace ShadPKG::GUI;
69 
70// ╔═══════════════════════════════════════════════════════════════════════════╗
71// ║ Global State ║
72// ╚═══════════════════════════════════════════════════════════════════════════╝
73static GUIContext g_Context;
74static NavBar g_NavBar;
75static ConsoleLog g_ConsoleLog;
76static ExtractorView g_ExtractorView;
77static InspectorView g_InspectorView;
78static RIFView g_RIFView;
79static SettingsView g_SettingsView;
80static DecompilerView g_DecompilerView;
81 
82// Drag & drop file paths pending processing
83static std::vector<std::string> g_DroppedFiles;
84static bool g_HasDroppedFiles = false;
85 
86// ┌─────────────────────────────────────────────────────────────────────────┐
87// │ GLFW Callbacks │
88// └─────────────────────────────────────────────────────────────────────────┘
89static void glfw_error_callback(int error, const char *description) {
90 fprintf(stderr, "GLFW Error %d: %s\n", error, description);
91 GuiLogSink::Instance().Error(std::string("GLFW Error: ") + description);
92}
93 
94static void glfw_drop_callback(GLFWwindow *window, int count,
95 const char **paths) {
96 g_DroppedFiles.clear();
97 for (int i = 0; i < count; ++i) {
98 g_DroppedFiles.push_back(paths[i]);
99 }
100 g_HasDroppedFiles = true;
101}
102 
103// ┌─────────────────────────────────────────────────────────────────────────┐
104// │ Process Dropped Files │
105// └─────────────────────────────────────────────────────────────────────────┘
106static void ProcessDroppedFiles() {
107 if (!g_HasDroppedFiles)
108 return;
109 
110 for (const auto &path : g_DroppedFiles) {
111 // Forward to extractor view
112 g_ExtractorView.OnFileDrop(g_Context, path);
113 }
114 
115 g_DroppedFiles.clear();
116 g_HasDroppedFiles = false;
117}
118 
119// ┌─────────────────────────────────────────────────────────────────────────┐
120// │ Draw Main Application Frame │
121// └─────────────────────────────────────────────────────────────────────────┘
122static void DrawMainFrame() {
123 // Get viewport
124 const ImGuiViewport *viewport = ImGui::GetMainViewport();
125 
126 // Setup window flags for fullscreen window
127 ImGuiWindowFlags windowFlags =
128 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
129 ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
130 ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
131 
132 // Cover entire viewport
133 ImGui::SetNextWindowPos(viewport->WorkPos);
134 ImGui::SetNextWindowSize(viewport->WorkSize);
135 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
136 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
137 ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
138 
139 ImGui::Begin("##MainWindow", nullptr, windowFlags);
140 
141 ImGui::PopStyleVar(3);
142 
143 // ═══════════════════════════════════════════════════════════════════════
144 // Layout: NavBar | ContentArea
145 // ═══════════════════════════════════════════════════════════════════════
146 
147 // Draw NavBar on the left
148 g_NavBar.Draw(g_Context);
149 
150 ImGui::SameLine();
151 
152 // Content area (view + console)
153 ImGui::BeginChild("##content_area", ImVec2(0, 0), false);
154 
155 float contentHeight = ImGui::GetContentRegionAvail().y;
156 float consoleHeight = g_ConsoleLog.IsExpanded() ? 180.0f : 30.0f;
157 if (consoleHeight > contentHeight) {
158 consoleHeight = contentHeight;
159 }
160 if (consoleHeight < 0.0f) {
161 consoleHeight = 0.0f;
162 }
163 float viewHeight = contentHeight - consoleHeight;
164 if (viewHeight < 0.0f) {
165 viewHeight = 0.0f;
166 }
167 
168 if (viewHeight > 1.0f) {
169 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(16, 16));
170 ImGui::BeginChild("##view_area", ImVec2(0, viewHeight), true);
171 
172 switch (g_Context.GetCurrentView()) {
173 case GUIContext::View::Extractor:
174 g_ExtractorView.Draw(g_Context);
175 break;
176 case GUIContext::View::Inspector:
177 g_InspectorView.Draw(g_Context);
178 break;
179 case GUIContext::View::RIF:
180 g_RIFView.Draw(g_Context);
181 break;
182 case GUIContext::View::Settings:
183 g_SettingsView.Draw(g_Context);
184 break;
185 // Static instance moved to file scope or initialized elsewhere if needed
186 // For now, rely on global or member instance (the include must be global)
187 // Actually, g_StructEditorView declaration should be kept here if it's
188 // local static, BUT the type definition from include must be global.
189 static StructEditorView g_StructEditorView;
190 
191 // ...
192 
193 case GUIContext::View::Decompiler:
194 g_DecompilerView.Draw(g_Context);
195 break;
196 case GUIContext::View::StructEditor:
197 g_StructEditorView.Draw(g_Context);
198 break;
199 }
200 
201 ImGui::EndChild();
202 ImGui::PopStyleVar();
203 }
204 
205 // ┌─────────────────────────────────────────────────────────────────────────┐
206 // │ Console Log at bottom of content area │
207 // └─────────────────────────────────────────────────────────────────────────┘
208 if (consoleHeight > 1.0f) {
209 g_ConsoleLog.Draw(consoleHeight - 30.0f);
210 }
211 
212 ImGui::EndChild(); // Close ##content_area
213 
214 ImGui::End(); // MainWindow
215}
216 
217// ╔═══════════════════════════════════════════════════════════════════════════╗
218// ║ Main Entry Point ║
219// ╚═══════════════════════════════════════════════════════════════════════════╝
220int main(int argc, char *argv[]) {
221 // Initialize logging
222 Common::Log::Initialize("shadpkg_gui.log");
223 Common::Log::SetColorConsoleBackendEnabled(true);
224 LOG_INFO(Common, "[GUI] Starting ShadPKG GUI");
225 
226 // Setup GLFW
227 glfwSetErrorCallback(glfw_error_callback);
228 if (!glfwInit()) {
229 LOG_ERROR(Common, "[GUI] Failed to initialize GLFW");
230 return 1;
231 }
232 
233 // GL context hints
234#if defined(__APPLE__)
235 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
236 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
237 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
238 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
239 const char *glslVersion = "#version 150";
240#else
241 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
242 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
243 const char *glslVersion = "#version 130";
244#endif
245 
246 // Create window
247 GLFWwindow *window = glfwCreateWindow(1280, 800, "ShadPKG", nullptr, nullptr);
248 if (window == nullptr) {
249 LOG_ERROR(Common, "[GUI] Failed to create GLFW window");
250 glfwTerminate();
251 return 1;
252 }
253 
254 glfwMakeContextCurrent(window);
255 glfwSwapInterval(1); // Enable vsync
256 
257 // Setup drag & drop
258 glfwSetDropCallback(window, glfw_drop_callback);
259 
260 // Setup ImGui context
261 IMGUI_CHECKVERSION();
262 ImGui::CreateContext();
263 ImGuiIO &io = ImGui::GetIO();
264 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
265 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
266 
267 // Apply custom style
268 SetupImGuiStyle();
269 
270 std::filesystem::path executableDir;
271 if (argv != nullptr && argc > 0 && argv[0] != nullptr) {
272 std::error_code ec;
273 const auto absolutePath = std::filesystem::absolute(argv[0], ec);
274 if (!ec) {
275 executableDir = absolutePath.parent_path();
276 }
277 }
278 
279 LoadFonts(io, executableDir);
280 
281 // Setup Platform/Renderer backends
282 ImGui_ImplGlfw_InitForOpenGL(window, true);
283 ImGui_ImplOpenGL3_Init(glslVersion);
284 
285 // Window background color
286 ImVec4 clearColor = Colors::WindowBg;
287 
288 GuiLogSink::Instance().Info("ShadPKG GUI initialized");
289 
290 // ═══════════════════════════════════════════════════════════════════════
291 // Main Loop
292 // ═══════════════════════════════════════════════════════════════════════
293 while (!glfwWindowShouldClose(window)) {
294 glfwPollEvents();
295 
296 // Process any dropped files
297 ProcessDroppedFiles();
298 
299 // Start ImGui frame
300 ImGui_ImplOpenGL3_NewFrame();
301 ImGui_ImplGlfw_NewFrame();
302 ImGui::NewFrame();
303 
304 // Draw the application
305 DrawMainFrame();
306 
307 // Render
308 ImGui::Render();
309 int displayW, displayH;
310 glfwGetFramebufferSize(window, &displayW, &displayH);
311 glViewport(0, 0, displayW, displayH);
312 glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
313 glClear(GL_COLOR_BUFFER_BIT);
314 ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
315 
316 glfwSwapBuffers(window);
317 }
318 
319 // Cleanup
320 ImGui_ImplOpenGL3_Shutdown();
321 ImGui_ImplGlfw_Shutdown();
322 ImGui::DestroyContext();
323 
324 glfwDestroyWindow(window);
325 glfwTerminate();
326 
327 LOG_INFO(Common, "[GUI] ShadPKG GUI shutdown");
328 Common::Log::Stop();
329 
330 return 0;
331}
332