yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
controller.cc
Go to the documentation of this file.
1#include "controller.h"
2
4
5#include <string>
6
7#include "absl/status/status.h"
14#include "app/emu/emulator.h"
16#include "app/platform/timing.h"
17#include "imgui/imgui.h"
18
19namespace yaze {
20
21absl::Status Controller::OnEntry(std::string filename) {
22 // Create window backend using factory (auto-selects SDL2 or SDL3)
25
27 config.title = "Yet Another Zelda3 Editor";
28 config.resizable = true;
29 config.high_dpi = false; // Disabled to match legacy behavior (SDL_WINDOW_RESIZABLE only)
30
31 RETURN_IF_ERROR(window_backend_->Initialize(config));
32
33 // Create renderer via factory (auto-selects SDL2 or SDL3)
35 if (!window_backend_->InitializeRenderer(renderer_.get())) {
36 return absl::InternalError("Failed to initialize renderer");
37 }
38
39 // Initialize ImGui via backend (handles SDL2/SDL3 automatically)
40 RETURN_IF_ERROR(window_backend_->InitializeImGui(renderer_.get()));
41
42 // Initialize the graphics Arena with the renderer
44
45 // Set up audio for emulator (using backend's audio resources)
46 auto audio_buffer = window_backend_->GetAudioBuffer();
47 if (audio_buffer) {
48 editor_manager_.emulator().set_audio_buffer(audio_buffer.get());
49 }
50 editor_manager_.emulator().set_audio_device_id(window_backend_->GetAudioDevice());
51
52 // Initialize editor manager with renderer
53 editor_manager_.Initialize(renderer_.get(), filename);
54
55 active_ = true;
56 return absl::OkStatus();
57}
58
59void Controller::SetStartupEditor(const std::string& editor_name,
60 const std::string& panels) {
61 // Process command-line flags for editor and panels
62 // Example: --editor=Dungeon --open_panels="dungeon.room_list,Room 0"
63 if (!editor_name.empty()) {
65 }
66}
67
69 if (!window_backend_) return;
70
72 while (window_backend_->PollEvent(event)) {
73 switch (event.type) {
76 active_ = false;
77 break;
78 default:
79 // Other events are handled by ImGui via ProcessNativeEvent
80 // which is called inside PollEvent
81 break;
82 }
83
84 // Forward native SDL events to emulator input for event-based paths
85 if (event.has_native_event) {
86 editor_manager_.emulator().input_manager().ProcessEvent(
87 static_cast<void*>(&event.native_event));
88 }
89 }
90}
91
92absl::Status Controller::OnLoad() {
93 if (!window_backend_) {
94 return absl::InternalError("Window backend not initialized");
95 }
96
97 if (editor_manager_.quit() || !window_backend_->IsActive()) {
98 active_ = false;
99 return absl::OkStatus();
100 }
101
102#if TARGET_OS_IPHONE != 1
103 // Start new ImGui frame via backend (handles SDL2/SDL3 automatically)
104 window_backend_->NewImGuiFrame();
105 ImGui::NewFrame();
106
107 const ImGuiViewport* viewport = ImGui::GetMainViewport();
108
109 // Calculate layout offsets for sidebars and status bar
110 const float left_offset = editor_manager_.GetLeftLayoutOffset();
111 const float right_offset = editor_manager_.GetRightLayoutOffset();
112 const float bottom_offset = editor_manager_.GetBottomLayoutOffset();
113
114 // Adjust dockspace position and size for sidebars and status bar
115 ImVec2 dockspace_pos = viewport->WorkPos;
116 ImVec2 dockspace_size = viewport->WorkSize;
117
118 dockspace_pos.x += left_offset;
119 dockspace_size.x -= (left_offset + right_offset);
120 dockspace_size.y -= bottom_offset; // Reserve space for status bar at bottom
121
122 ImGui::SetNextWindowPos(dockspace_pos);
123 ImGui::SetNextWindowSize(dockspace_size);
124 ImGui::SetNextWindowViewport(viewport->ID);
125
126 // Check if menu bar should be visible (WASM can hide it for clean UI)
127 bool show_menu_bar = true;
130 }
131
132 ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking;
133 if (show_menu_bar) {
134 window_flags |= ImGuiWindowFlags_MenuBar;
135 }
136 window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
137 ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
138 window_flags |=
139 ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus |
140 ImGuiWindowFlags_NoBackground;
141
142 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
143 ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
144 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
145 ImGui::Begin("DockSpaceWindow", nullptr, window_flags);
146 ImGui::PopStyleVar(3);
147
148 // Create DockSpace with adjusted size
149 ImGuiID dockspace_id = ImGui::GetID("MainDockSpace");
151 dockspace_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode);
152
153 if (show_menu_bar) {
154 editor_manager_.DrawMenuBar(); // Draw the fixed menu bar at the top
155 }
156
158 ImGui::End();
159
160 // Draw menu bar restore button when menu is hidden (WASM)
161 if (!show_menu_bar && editor_manager_.ui_coordinator()) {
163 }
164#endif
166 absl::Status update_status = editor_manager_.Update();
168 RETURN_IF_ERROR(update_status);
169 return absl::OkStatus();
170}
171
173 if (!window_backend_ || !renderer_) return;
174
175 // Process pending texture commands (max 8 per frame for consistent performance)
177
178 renderer_->Clear();
179
180 // Render ImGui draw data and handle viewports via backend
181 window_backend_->RenderImGui(renderer_.get());
182
183 renderer_->Present();
184
185 // Get delta time AFTER render for accurate measurement
186 float delta_time = TimingManager::Get().Update();
187
188 // Gentle frame rate cap to prevent excessive CPU usage
189 // Only delay if we're rendering faster than 144 FPS (< 7ms per frame)
190 if (delta_time < 0.007f) {
191 SDL_Delay(1); // Tiny delay to yield CPU without affecting ImGui timing
192 }
193}
194
196 if (renderer_) {
197 renderer_->Shutdown();
198 }
199 if (window_backend_) {
200 window_backend_->Shutdown();
201 }
202}
203
204absl::Status Controller::LoadRomForTesting(const std::string& rom_path) {
205 // Use EditorManager's OpenRomOrProject which handles the full initialization:
206 // 1. Load ROM file into session
207 // 2. ConfigureEditorDependencies()
208 // 3. LoadAssets() - initializes all editors and loads graphics
209 // 4. Updates UI state (hides welcome screen, etc.)
210 return editor_manager_.OpenRomOrProject(rom_path);
211}
212
213} // namespace yaze
editor::EditorManager editor_manager_
Definition controller.h:71
absl::Status LoadRomForTesting(const std::string &rom_path)
absl::Status OnEntry(std::string filename="")
Definition controller.cc:21
void SetStartupEditor(const std::string &editor_name, const std::string &cards)
Definition controller.cc:59
std::unique_ptr< platform::IWindowBackend > window_backend_
Definition controller.h:70
absl::Status OnLoad()
Definition controller.cc:92
void DoRender() const
std::unique_ptr< gfx::IRenderer > renderer_
Definition controller.h:72
static TimingManager & Get()
Definition timing.h:20
float Update()
Update the timing manager (call once per frame)
Definition timing.h:29
void DrawMenuBar()
Draw the main menu bar.
UICoordinator * ui_coordinator()
void Initialize(gfx::IRenderer *renderer, const std::string &filename="")
void OpenEditorAndPanelsFromFlags(const std::string &editor_name, const std::string &panels_str)
absl::Status Update()
Main update loop for the editor application.
auto emulator() -> emu::Emulator &
absl::Status OpenRomOrProject(const std::string &filename)
void Initialize(IRenderer *renderer)
Definition arena.cc:15
void ProcessTextureQueue(IRenderer *renderer)
Definition arena.cc:110
static Arena & Get()
Definition arena.cc:19
static std::unique_ptr< IRenderer > Create(RendererBackendType type=RendererBackendType::kDefault)
Create a renderer instance with the specified backend type.
static void BeginEnhancedDockSpace(ImGuiID dockspace_id, const ImVec2 &size=ImVec2(0, 0), ImGuiDockNodeFlags flags=0)
static WidgetIdRegistry & Instance()
static WindowBackendType GetDefaultType()
Get the default backend type for this build.
static std::unique_ptr< IWindowBackend > Create(WindowBackendType type)
Create a window backend of the specified type.
SDL2/SDL3 compatibility layer.
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
Window configuration parameters.
Definition iwindow.h:24
Platform-agnostic window event data.
Definition iwindow.h:63
WindowEventType type
Definition iwindow.h:64