pound-emu_pound/core/main.cpp
Ronald Caesar ba45834583
feat!: rewrote program in a data oriented style.
This is because the source code is objected oriented which is not cpu cache
friendly, making the program slower than it has to be. Yuzu's entire
codebase is written in a objected oriented way and I wonder how much faster
it could if they had use DoD principles from the very beginning.

That's why I want to instill DoD fundamentals early on so this won't be a
problem going forward.

Signed-off-by: Ronald Caesar <github43132@proton.me>
2025-08-02 04:05:05 -04:00

128 lines
4.4 KiB
C++

// Copyright 2025 Pound Emulator Project. All rights reserved.
#include <chrono>
#include <memory>
#include <thread>
#include "ARM/cpu.h"
#include "Base/Config.h"
#include "Base/Logging/Backend.h"
#include "JIT/jit.h"
#include "gui/gui.h"
#include "memory/arena.h"
#include <SDL3/SDL_opengl.h>
#include "gui/color.h"
#include "gui/panels.h"
#include "imgui_impl_opengl3.h"
#include "imgui_impl_sdl3.h"
int main()
{
// This is meant to replace malloc() and its related functions.
// TODO(GloriousTaco:memory): Implement std::allocator for this custom allocator which allows it to manage the memory of C++ standard types like std::vector.
memory::arena_t arena = memory::arena_init(1024);
Base::Log::Initialize();
Base::Log::Start();
const auto& config_dir = Base::FS::GetUserPath(Base::FS::PathType::BinaryDir);
Config::Load(config_dir / "config.toml");
// Create GUI manager
gui::window_t window = {.data = nullptr, .gl_context = nullptr};
(void)gui::window_init(&window, "Pound Emulator", Config::windowWidth(), Config::windowHeight());
if (bool return_code = gui::init_imgui(&window); false == return_code)
{
LOG_ERROR(Render, "Failed to initialize GUI");
return EXIT_FAILURE;
}
const size_t panels_capacity = 2;
const char* panel_names[panels_capacity] = {PANEL_NAME_CPU, PANEL_NAME_PERFORMANCE};
bool panels_visibility[panels_capacity] = {false};
bool imgui_demo_visible = false;
gui::gui_t gui = {
.window = window,
.custom_panels = panel_names,
.custom_panels_visibility = panels_visibility,
.custom_panels_capacity = panels_capacity,
};
gui::panel::performance_panel_t performance_panel = {};
gui::panel::performance_data_t performance_data = {.frame_count = 1};
std::chrono::steady_clock::time_point performance_panel_last_render = std::chrono::steady_clock::now();
// Main loop
bool is_running = true;
bool show_cpu_result_popup = false;
while (true == is_running)
{
SDL_Event event;
while (::SDL_PollEvent(&event))
{
(void)::ImGui_ImplSDL3_ProcessEvent(&event);
if (event.type == SDL_EVENT_QUIT)
{
is_running = false;
}
}
::ImGui_ImplOpenGL3_NewFrame();
::ImGui_ImplSDL3_NewFrame();
::ImGui::NewFrame();
if (int8_t return_code = gui::render_memu_bar(gui.custom_panels, gui.custom_panels_capacity,
gui.custom_panels_visibility, &imgui_demo_visible);
WINDOW_SHOULD_CLOSE == return_code)
{
is_running = false;
}
for (size_t i = 0; i < panels_capacity; ++i)
{
if (false == gui.custom_panels_visibility[i])
{
continue;
}
if (0 == ::strcmp(gui.custom_panels[i], PANEL_NAME_PERFORMANCE))
{
int8_t return_code = gui::panel::render_performance_panel(&performance_panel, &performance_data,
&performance_panel_last_render);
if (ERROR_PANEL_IS_CLOSED == return_code)
{
gui.custom_panels_visibility[i] = false;
}
}
if (0 == ::strcmp(gui.custom_panels[i], PANEL_NAME_CPU))
{
int8_t return_code = gui::panel::render_cpu_panel(&show_cpu_result_popup);
if (ERROR_PANEL_IS_CLOSED == return_code)
{
gui.custom_panels_visibility[i] = false;
}
}
}
// End Frame.
ImGui::Render();
const ImGuiIO& io = ImGui::GetIO();
::glViewport(0, 0, static_cast<GLint>(io.DisplaySize.x), static_cast<GLint>(io.DisplaySize.y));
::glClearColor(0.08f, 0.08f, 0.10f, 1.0f);
::glClear(GL_COLOR_BUFFER_BIT);
::ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
if (bool sdl_ret_code = ::SDL_GL_SwapWindow(gui.window.data); false == sdl_ret_code)
{
LOG_ERROR(Render, "Failed to update window with OpenGL rendering: {}", SDL_GetError());
is_running = false;
}
// Small delay to prevent excessive CPU usage
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
gui::destroy();
}