Compiles!

This commit is contained in:
SimoZ64
2025-05-05 22:15:45 +02:00
parent 20e8e720a6
commit b4c5c7a3e4
25 changed files with 598 additions and 422 deletions

View File

@@ -3,6 +3,8 @@
#include <memory> #include <memory>
#include <rdp_device.hpp> #include <rdp_device.hpp>
#include <core/mmio/VI.hpp> #include <core/mmio/VI.hpp>
#include <resources/vert.spv.h>
#include <resources/frag.spv.h>
using namespace Vulkan; using namespace Vulkan;
using namespace RDP; using namespace RDP;
@@ -98,13 +100,11 @@ void ParallelRDP::Init(const std::shared_ptr<InstanceFactory> &factory, const st
fragLayout.sets[0].fp_mask = 1; fragLayout.sets[0].fp_mask = 1;
fragLayout.sets[0].array_size[0] = 1; fragLayout.sets[0].array_size[0] = 1;
auto fullscreenQuadVert = Util::ReadFileBinary("resources/vert.spv"); auto sizeVert = sizeof(vertex_shader);
auto fullscreenQuadFrag = Util::ReadFileBinary("resources/frag.spv"); auto sizeFrag = sizeof(fragment_shader);
auto sizeVert = fullscreenQuadVert.size();
auto sizeFrag = fullscreenQuadFrag.size();
fullscreen_quad_program = wsi->get_device().request_program( fullscreen_quad_program = wsi->get_device().request_program(
reinterpret_cast<u32 *>(fullscreenQuadVert.data()), sizeVert, reinterpret_cast<u32 *>(fullscreenQuadFrag.data()), reinterpret_cast<const u32 *>(vertex_shader), sizeVert, reinterpret_cast<const u32 *>(fragment_shader),
sizeFrag, &vertLayout, &fragLayout); sizeFrag, &vertLayout, &fragLayout);
auto aligned_rdram = reinterpret_cast<uintptr_t>(rdram); auto aligned_rdram = reinterpret_cast<uintptr_t>(rdram);

Binary file not shown.

156
resources/frag.spv.h Normal file
View File

@@ -0,0 +1,156 @@
constexpr unsigned char fragment_shader[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00,
0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x0A, 0x00,
0x47, 0x4C, 0x5F, 0x47, 0x4F, 0x4F, 0x47, 0x4C, 0x45, 0x5F, 0x63, 0x70,
0x70, 0x5F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x5F, 0x6C, 0x69, 0x6E, 0x65,
0x5F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00,
0x04, 0x00, 0x08, 0x00, 0x47, 0x4C, 0x5F, 0x47, 0x4F, 0x4F, 0x47, 0x4C,
0x45, 0x5F, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x5F, 0x64, 0x69,
0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x75, 0x76, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x76, 0x55, 0x56, 0x00,
0x05, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x53, 0x63, 0x72, 0x65,
0x65, 0x6E, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x05, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x75, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6E, 0x00,
0x05, 0x00, 0x05, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x46, 0x72, 0x61, 0x67,
0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x40, 0x00, 0x00, 0x00, 0x53, 0x63, 0x61, 0x6C, 0x65, 0x00, 0x00, 0x00,
0x05, 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x00, 0x75, 0x49, 0x6D, 0x61,
0x67, 0x65, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x44, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x0E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F,
0x2B, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x3C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x07, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F,
0x19, 0x00, 0x09, 0x00, 0x41, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x03, 0x00, 0x42, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00,
0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x19, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0xB8, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x04, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0xF7, 0x00, 0x03, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFA, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0xBA, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
0x24, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00,
0xF5, 0x00, 0x07, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x2D, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x05, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x2C, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x2C, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
0xA8, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x31, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x34, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x35, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
0x35, 0x00, 0x00, 0x00, 0xBA, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x34, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x34, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x38, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x37, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x3D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
0x3A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x3F, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
0x44, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x46, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x58, 0x00, 0x07, 0x00,
0x3B, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x8E, 0x00, 0x05, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x47, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x3D, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
0x3A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x3A, 0x00, 0x00, 0x00,
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
};

Binary file not shown.

91
resources/vert.spv.h Normal file
View File

@@ -0,0 +1,91 @@
constexpr unsigned char vertex_shader[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00,
0x04, 0x00, 0x0A, 0x00, 0x47, 0x4C, 0x5F, 0x47, 0x4F, 0x4F, 0x47, 0x4C,
0x45, 0x5F, 0x63, 0x70, 0x70, 0x5F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x5F,
0x6C, 0x69, 0x6E, 0x65, 0x5F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4C, 0x5F, 0x47,
0x4F, 0x4F, 0x47, 0x4C, 0x45, 0x5F, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64,
0x65, 0x5F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00,
0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74,
0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74,
0x53, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x43,
0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x00,
0x06, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x43, 0x75, 0x6C, 0x6C, 0x44, 0x69, 0x73, 0x74, 0x61,
0x6E, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00,
0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x76, 0x55, 0x56, 0x00,
0x48, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x12, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x06, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x15, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x3F, 0x20, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x00, 0x05, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x10, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x8E, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00,
0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
};

View File

@@ -2,12 +2,13 @@
#include <File.hpp> #include <File.hpp>
#include <GameDB.hpp> #include <GameDB.hpp>
#include <Registers.hpp> #include <Registers.hpp>
#include <algorithm>
#include <backend/MemoryRegions.hpp> #include <backend/MemoryRegions.hpp>
#include <backend/core/MMIO.hpp> #include <backend/core/MMIO.hpp>
#include <common.hpp> #include <common.hpp>
#include <log.hpp> #include <log.hpp>
#include <vector> #include <vector>
#include <algorithm>
#include <ranges>
namespace n64 { namespace n64 {
struct ROMHeader { struct ROMHeader {

View File

@@ -3,6 +3,7 @@ project(kaizen)
if (WIN32) if (WIN32)
add_compile_definitions(NOMINMAX) add_compile_definitions(NOMINMAX)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif () endif ()
if(APPLE) if(APPLE)
@@ -10,9 +11,13 @@ if(APPLE)
enable_language(OBJC) enable_language(OBJC)
endif() endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include_directories( include_directories(
. .
../ ../
../../
../utils ../utils
../backend ../backend
../backend/core ../backend/core
@@ -40,6 +45,7 @@ include_directories(
../../external/capstone/include ../../external/capstone/include
../../external/imgui ../../external/imgui
../../external/imgui/backends ../../external/imgui/backends
../../external/nfd/src/include
../../external/cflags/include ../../external/cflags/include
ImGuiImpl/ ImGuiImpl/
) )
@@ -65,22 +71,27 @@ else()
set(ARM64 FALSE) set(ARM64 FALSE)
endif() endif()
set(SIMD_FLAG NULL)
if(ARM64 AND APPLE) if(ARM64 AND APPLE)
message("Defining USE_NEON...") message("Defining USE_NEON...")
add_compile_definitions(USE_NEON) add_compile_definitions(USE_NEON)
set(HAS_SIMD TRUE) add_compile_definitions(SIMD_SUPPORT)
elseif(NOT ARM64)
if(MSVC)
set(SIMD_FLAG /arch:AVX)
else()
set(SIMD_FLAG -msse4.1)
endif()
check_c_compiler_flag(${SIMD_FLAG} HAS_SIMD)
else()
message("Compiling on an unsupported Arm device! Good Luck!")
endif() endif()
if(NOT ARM64)
check_c_compiler_flag(-msse4.1 HAS_SIMD)
endif ()
if (HAS_SIMD) if (HAS_SIMD)
message("Defining SIMD_SUPPORT...") message("Defining SIMD_SUPPORT...")
add_compile_definitions(SIMD_SUPPORT) add_compile_definitions(SIMD_SUPPORT)
if(NOT ARM64) add_compile_options(${SIMD_FLAG})
add_compile_options(-msse3 -msse4.1)
endif()
endif () endif ()
if (${CMAKE_BUILD_TYPE} MATCHES Debug) if (${CMAKE_BUILD_TYPE} MATCHES Debug)
@@ -97,6 +108,7 @@ add_subdirectory(../../external/unarr unarr)
add_subdirectory(../../external/SDL SDL) add_subdirectory(../../external/SDL SDL)
add_subdirectory(../../external/cflags cflags) add_subdirectory(../../external/cflags cflags)
add_subdirectory(../../external/imgui imgui) add_subdirectory(../../external/imgui imgui)
add_subdirectory(../../external/nfd nfd)
set(CAPSTONE_ARCHITECTURE_DEFAULT OFF) set(CAPSTONE_ARCHITECTURE_DEFAULT OFF)
set(CAPSTONE_MIPS_SUPPORT ON) set(CAPSTONE_MIPS_SUPPORT ON)
set(CAPSTONE_X86_SUPPORT ON) set(CAPSTONE_X86_SUPPORT ON)
@@ -110,8 +122,6 @@ add_executable(kaizen
RenderWidget.hpp RenderWidget.hpp
EmuThread.hpp EmuThread.hpp
EmuThread.cpp EmuThread.cpp
MainWindow.hpp
MainWindow.cpp
SettingsWindow.hpp SettingsWindow.hpp
SettingsWindow.cpp SettingsWindow.cpp
CPUSettings.hpp CPUSettings.hpp
@@ -124,9 +134,8 @@ add_executable(kaizen
Debugger.hpp Debugger.hpp
Debugger.cpp) Debugger.cpp)
target_link_libraries(kaizen PUBLIC imgui SDL3::SDL3 SDL3::SDL3-static cflags::cflags discord-rpc fmt mio nlohmann_json parallel-rdp capstone backend) target_link_libraries(kaizen PUBLIC imgui nfd SDL3::SDL3 SDL3::SDL3-static cflags::cflags discord-rpc fmt mio nlohmann_json parallel-rdp capstone backend)
target_compile_definitions(kaizen PUBLIC SDL_MAIN_HANDLED) target_compile_definitions(kaizen PUBLIC SDL_MAIN_HANDLED)
set_target_properties(kaizen PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)
file(COPY ../../resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/) file(COPY ../../resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/)
file(REMOVE file(REMOVE

View File

@@ -1,7 +1,7 @@
#include <Core.hpp> #include <Core.hpp>
#include <EmuThread.hpp> #include <EmuThread.hpp>
EmuThread::EmuThread(const std::shared_ptr<n64::Core> &core, std::string &fps, RenderWidget &renderWidget, EmuThread::EmuThread(const std::shared_ptr<n64::Core> &core, double &fps, RenderWidget &renderWidget,
SettingsWindow &settings) noexcept : SettingsWindow &settings) noexcept :
renderWidget(renderWidget), core(core), settings(settings), fps(fps) {} renderWidget(renderWidget), core(core), settings(settings), fps(fps) {}
@@ -16,7 +16,7 @@ void EmuThread::start() noexcept {
auto sampledFps = 0; auto sampledFps = 0;
static bool oneSecondPassed = false; static bool oneSecondPassed = false;
fps = fmt::format("{:.2f} FPS", 1000.0 / avgFps); fps = 1000.0 / avgFps;
while (!interruptionRequested) { while (!interruptionRequested) {
const auto startFrameTime = std::chrono::high_resolution_clock::now(); const auto startFrameTime = std::chrono::high_resolution_clock::now();
@@ -44,7 +44,7 @@ void EmuThread::start() noexcept {
lastSample = endFrameTime; lastSample = endFrameTime;
avgFps /= sampledFps; avgFps /= sampledFps;
sampledFps = 0; sampledFps = 0;
fps = fmt::format("{:.2f} FPS", 1000.0 / avgFps); fps = 1000.0 / avgFps;
} }
} }
SetRender(false); SetRender(false);

View File

@@ -12,7 +12,7 @@ class EmuThread final {
RenderWidget &renderWidget; RenderWidget &renderWidget;
public: public:
explicit EmuThread(const std::shared_ptr<n64::Core> &, std::string &, RenderWidget &, SettingsWindow &) noexcept; explicit EmuThread(const std::shared_ptr<n64::Core> &, double &, RenderWidget &, SettingsWindow &) noexcept;
void start() noexcept; void start() noexcept;
void TogglePause() const noexcept; void TogglePause() const noexcept;
@@ -24,6 +24,6 @@ public:
bool interruptionRequested = false, isRunning = false; bool interruptionRequested = false, isRunning = false;
std::shared_ptr<n64::Core> core; std::shared_ptr<n64::Core> core;
SettingsWindow &settings; SettingsWindow &settings;
std::string& fps; double& fps;
std::thread thread; std::thread thread;
}; };

View File

@@ -14,7 +14,7 @@ struct ComboItem {
return ret; return ret;
} }
const std::string& getLabel() { return label; } const std::string& getLabel() const { return label; }
void setLabel(const std::string& text) { label = text; } void setLabel(const std::string& text) { label = text; }
private: private:
bool enabled = true; bool enabled = true;
@@ -24,9 +24,9 @@ private:
struct Combobox { struct Combobox {
Combobox(std::string label, std::vector<ComboItem> items, std::string preview = "", bool enabled = true) : label(label), items(items), preview(preview), enabled(enabled) {} Combobox(std::string label, std::vector<ComboItem> items, std::string preview = "", bool enabled = true) : label(label), items(items), preview(preview), enabled(enabled) {}
void addItem(ComboItem& item) { void addItem(const ComboItem& item) {
if(std::find(items.begin(), items.end(), if(std::find_if(items.begin(), items.end(),
[&item](ComboItem& a) { return a.getLabel() == item.getLabel(); }) != items.end()) [&item](const ComboItem& a) { return a.getLabel() == item.getLabel(); }) != items.end())
return; return;
items.push_back(item); items.push_back(item);

View File

@@ -0,0 +1,74 @@
#pragma once
#include <imgui.h>
#include <string>
#include <ranges>
#include <functional>
namespace gui {
struct MenuItem {
MenuItem(const std::string& label, std::function<void()>&& func = nullptr, bool enabled = true) : label(label), exec(std::move(func)), enabled(enabled) {}
bool render() {
bool ret = false;
ImGui::BeginDisabled(!enabled);
if(ImGui::MenuItem(label.c_str())) {
if(exec)
exec();
ret = true;
}
ImGui::EndDisabled();
return ret;
}
void setEnabled(bool v) { enabled = v; }
private:
bool enabled = true;
std::string label;
std::function<void()> exec;
};
struct Menu {
Menu(const std::string& label, const std::vector<MenuItem>& items = {}, bool enabled = true) : label(label), items(items), enabled(enabled) {}
void addMenuItem(const MenuItem& item) { items.push_back(item); }
bool render() {
bool ret = false;
ImGui::BeginDisabled(!enabled);
if(ImGui::BeginMenu(label.c_str())) {
for(auto& item : items) {
ret |= item.render();
}
ImGui::EndMenu();
}
ImGui::EndDisabled();
return ret;
}
void setEnabled(bool v) { enabled = v; }
private:
std::vector<MenuItem> items{};
std::string label{};
bool enabled = true;
};
template <bool main = false>
struct MenuBar {
MenuBar(bool enabled = true) : enabled(enabled) {}
void addMenu(const Menu& menu) { menus.push_back(menu); }
bool render() {
bool ret = false;
ImGui::BeginDisabled(!enabled);
auto beginMenuBar = main ? &ImGui::BeginMainMenuBar : &ImGui::BeginMenuBar;
auto endMenuBar = main ? &ImGui::EndMainMenuBar : &ImGui::EndMenuBar;
if(beginMenuBar()) {
for(auto& menu : menus) {
ret |= menu.render();
}
endMenuBar();
}
ImGui::EndDisabled();
return ret;
}
void setEnabled(bool v) { enabled = v; }
private:
bool enabled = true;
std::vector<Menu> menus{};
};
}

View File

@@ -0,0 +1,33 @@
#include <imgui.h>
#include <string>
#include <functional>
namespace gui {
struct PopupWindow {
PopupWindow(const std::string& title, std::function<void()>&& func = nullptr, bool opened = true) : title(title), exec(func), opened(opened) {}
void setFunc(std::function<void()>&& func) {
exec = func;
}
bool render() {
ImGui::OpenPopup(title.c_str());
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal(title.c_str(), &opened, ImGuiWindowFlags_AlwaysAutoResize))
{
if(exec)
exec();
ImGui::EndPopup();
return true;
}
return false;
}
private:
std::function<void()> exec;
std::string title;
bool opened = true;
};
}

View File

@@ -5,8 +5,8 @@
namespace gui { namespace gui {
template <typename T> template <typename T>
struct Slider { struct Slider {
Slider(const std::string& label, T min = 0, T max = 0, T default = 0) Slider(const std::string& label, T min = 0, T max = 0, T initial_value = 0)
: val(default), label(label), min(min), max(max) { } : val(initial_value), label(label), min(min), max(max) { }
void setValue(T v) { val = v; } void setValue(T v) { val = v; }
bool render() { bool render() {

View File

@@ -0,0 +1,28 @@
#include <imgui.h>
#include <functional>
namespace gui {
struct StatusBar {
StatusBar(std::function<void()>&& func = nullptr, bool enabled = true) : exec(func), enabled(enabled) {}
bool render() {
float statusWindowHeight = ImGui::GetFrameHeight() * 1.4f;
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImVec2 statusBarSize, statusBarPos;
ImGui::SetNextWindowPos(statusBarPos);
ImGui::SetNextWindowSize(statusBarSize);
ImGui::SetNextWindowViewport(viewport->ID);
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking;
ImGui::Begin("StatusBar", nullptr, windowFlags);
if(exec)
exec();
ImGui::End();
}
private:
std::function<void()> exec = nullptr;
bool enabled = true;
};
}

View File

@@ -2,18 +2,19 @@
#include <imgui.h> #include <imgui.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <functional>
namespace gui { namespace gui {
struct TabItem { struct TabItem {
TabItem(std::string label, void(*func)(TabItem*, void* userData) = nullptr, void* userData = nullptr, bool enabled = true) : exec(func), enabled(enabled), userData(userData) {} TabItem(std::string label, std::function<void()>&& func, bool enabled = true) : exec(std::move(func)), enabled(enabled) {}
bool render() { bool render() {
bool ret = false; bool ret = false;
ImGui::BeginDisabled(!enabled); ImGui::BeginDisabled(!enabled);
if(ImGui::BeginTabItem(label.c_str())) { if(ImGui::BeginTabItem(label.c_str())) {
if(exec) if(exec)
exec(this, userData); exec();
ImGui::EndTabItem(); ImGui::EndTabItem();
ret = true; ret = true;
} }
@@ -23,15 +24,12 @@ struct TabItem {
private: private:
bool enabled = true; bool enabled = true;
std::string label; std::string label;
void(*exec)(TabItem*, void* userData); std::function<void()> exec;
void* userData;
}; };
struct TabBar { struct TabBar {
TabBar(std::string label) : label(label) {} TabBar(std::string label, const std::vector<TabItem>& items = {}) : label(label), tabs(items) {}
void addTab(TabItem tabItem) { void addTab(TabItem tabItem) { tabs.push_back(tabItem); }
tabs.push_back(tabItem);
}
bool render() { bool render() {
bool ret = false; bool ret = false;

View File

@@ -1,125 +1,105 @@
#include <Core.hpp>
#include <KaizenGui.hpp> #include <KaizenGui.hpp>
#include <nfd.hpp>
#include <backend/Core.hpp>
#include <ImGuiImpl/StatusBar.hpp>
namespace fs = std::filesystem; KaizenGui::KaizenGui() noexcept : core(std::make_shared<n64::Core>()), vulkanWidget(core), emuThread(core, fpsCounter, vulkanWidget, settingsWindow) {
emuExitFunc = [&]() {
quit = true;
if (emuThread.isRunning) {
emuThread.requestInterruption();
while (emuThread.isRunning) {}
}
};
KaizenGui::KaizenGui() noexcept : mainWindow(core), emuThread(core, mainWindow.fpsCounter, mainWindow.vulkanWidget, settingsWindow) { menuBar.addMenu({"File",
// debugger = std::make_unique<Debugger>(); {
{"Open", [&]() {
NFD::Guard guard;
NFD::UniquePath path;
nfdfilteritem_t filterItem = {"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"};
ConnectMainWindowSignalsToSlots(); auto result = NFD::OpenDialog(path, &filterItem, 1);
Util::RPC::GetInstance().Update(Util::RPC::Idling); if(result == NFD_CANCEL) return;
if(result == NFD_ERROR)
Util::panic("Error: {}", NFD::GetError());
LoadROM(path.get());
}},
{"Exit", std::move(emuExitFunc)}
}
});
menuBar.addMenu({"Emulation",
{
actionPause,
actionStop,
actionReset,
{"Settings", [&]() {
settingsWindow.render();
}},
}
});
menuBar.addMenu({"Help",
{
{"About", [&]() {
gui::PopupWindow about{"About Kaizen", [&]() {
ImGui::Text("Kaizen is a Nintendo 64 emulator that strives");
ImGui::Text("to offer a friendly user experience and compatibility.");
ImGui::Text("Kaizen is licensed under the BSD 3-clause license.");
ImGui::Text("Nintendo 64 is a registered trademarks of Nintendo Co., Ltd.");
}};
}},
}
});
} }
void KaizenGui::ConnectMainWindowSignalsToSlots() noexcept { void KaizenGui::LoadROM(const std::string &path) noexcept {
connect(settingsWindow.get(), &SettingsWindow::regrabKeyboard, this, [&] { grabKeyboard(); }); actionPause.setEnabled(true);
actionReset.setEnabled(true);
actionStop.setEnabled(true);
emuThread.start();
emuThread.core->LoadROM(path);
const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB;
Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB);
}
connect(settingsWindow.get(), &SettingsWindow::gotClosed, this, void KaizenGui::handleEvents() {
[&] { mainWindow->vulkanWidget->wsiPlatform->EnableEventPolling(); }); SDL_Event e;
while(SDL_PollEvent(&e)) {
connect(settingsWindow.get(), &SettingsWindow::gotOpened, this, switch(e.type) {
[&] { mainWindow->vulkanWidget->wsiPlatform->DisableEventPolling(); }); case SDL_EVENT_QUIT:
emuExitFunc();
connect(mainWindow.get(), &MainWindow::OpenSettings, this, [this] { settingsWindow->show(); }); break;
// connect(mainWindow.get(), &MainWindow::OpenDebugger, this, [this] { debugger->show(); }); }
connect(mainWindow.get(), &MainWindow::OpenROM, this, &KaizenGui::LoadROM); }
connect(mainWindow.get(), &MainWindow::Exit, this, &KaizenGui::Quit);
connect(mainWindow.get(), &MainWindow::Reset, emuThread.get(), &EmuThread::Reset);
connect(mainWindow.get(), &MainWindow::Stop, this, [this] { emuThread->requestInterruption(); });
connect(mainWindow.get(), &MainWindow::Pause, emuThread.get(), &EmuThread::TogglePause);
} }
int KaizenGui::run() { int KaizenGui::run() {
bool inputForEmu = true; while(!quit) {
handleEvents();
if(settingsWindow.render()) { menuBar.render();
inputForEmu = false;
// TODO VULKAN CANVAS
gui::StatusBar statusBar{[&]() {
ImGui::Text("GUI FPS: %.2f, Emulation FPS: %.2f", ImGui::GetIO().Framerate, fpsCounter);
}};
statusBar.render();
} }
mainWindow.render();
return 0; return 0;
} }
void KaizenGui::LoadROM(const QString &path) const noexcept { void KaizenGui::LoadTAS(const std::string &path) const noexcept {
mainWindow->actionPause->setEnabled(true); if (emuThread.core->LoadTAS(fs::path(path))) {
mainWindow->actionReset->setEnabled(true); const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB;
mainWindow->actionStop->setEnabled(true); const auto movieName = fs::path(path).stem().string();
emuThread->start();
emuThread->core->LoadROM(path.toStdString());
const auto gameNameDB = emuThread->core->cpu->GetMem().rom.gameNameDB;
mainWindow->setWindowTitle(emuThread->core->cpu->GetMem().rom.gameNameDB.c_str());
Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB);
}
void KaizenGui::Quit() const noexcept {
if (emuThread) {
emuThread->requestInterruption();
while (emuThread->isRunning) {}
}
QApplication::quit();
}
void KaizenGui::LoadTAS(const QString &path) const noexcept {
if (emuThread->core->LoadTAS(fs::path(path.toStdString()))) {
const auto gameNameDB = emuThread->core->cpu->GetMem().rom.gameNameDB;
const auto movieName = fs::path(path.toStdString()).stem().string();
Util::RPC::GetInstance().Update(Util::RPC::MovieReplay, gameNameDB, movieName); Util::RPC::GetInstance().Update(Util::RPC::MovieReplay, gameNameDB, movieName);
return; return;
} }
Util::panic("Could not load TAS movie {}!", path.toStdString()); Util::panic("Could not load TAS movie {}!", path);
}
void KaizenGui::keyPressEvent(QKeyEvent *e) {
if (settingsWindow->inputSettings->selectedDeviceIsNotKeyboard)
return;
emuThread->core->pause = true;
n64::Mem &mem = emuThread->core->cpu->GetMem();
n64::PIF &pif = mem.mmio.si.pif;
const auto k = static_cast<Qt::Key>(e->key());
for (int i = 0; i < 14; i++) {
if (k == settingsWindow->keyMap[i])
pif.UpdateButton(0, static_cast<n64::Controller::Key>(i), true);
}
if (k == settingsWindow->keyMap[14])
pif.UpdateAxis(0, n64::Controller::Axis::Y, 86);
if (k == settingsWindow->keyMap[15])
pif.UpdateAxis(0, n64::Controller::Axis::Y, -86);
if (k == settingsWindow->keyMap[16])
pif.UpdateAxis(0, n64::Controller::Axis::X, -86);
if (k == settingsWindow->keyMap[17])
pif.UpdateAxis(0, n64::Controller::Axis::X, 86);
emuThread->core->pause = false;
QWidget::keyPressEvent(e);
}
void KaizenGui::keyReleaseEvent(QKeyEvent *e) {
if (settingsWindow->inputSettings->selectedDeviceIsNotKeyboard)
return;
emuThread->core->pause = true;
n64::Mem &mem = emuThread->core->cpu->GetMem();
n64::PIF &pif = mem.mmio.si.pif;
const auto k = static_cast<Qt::Key>(e->key());
for (int i = 0; i < 14; i++) {
if (k == settingsWindow->keyMap[i])
pif.UpdateButton(0, static_cast<n64::Controller::Key>(i), false);
}
if (k == settingsWindow->keyMap[14])
pif.UpdateAxis(0, n64::Controller::Axis::Y, 0);
if (k == settingsWindow->keyMap[15])
pif.UpdateAxis(0, n64::Controller::Axis::Y, 0);
if (k == settingsWindow->keyMap[16])
pif.UpdateAxis(0, n64::Controller::Axis::X, 0);
if (k == settingsWindow->keyMap[17])
pif.UpdateAxis(0, n64::Controller::Axis::X, 0);
emuThread->core->pause = false;
QWidget::keyReleaseEvent(e);
} }

View File

@@ -1,24 +1,28 @@
#pragma once #pragma once
#include <Discord.hpp> #include <RenderWidget.hpp>
#include <Debugger.hpp>
#include <ImGuiImpl/Menu.hpp>
#include <EmuThread.hpp> #include <EmuThread.hpp>
#include <MainWindow.hpp> #include <Discord.hpp>
#include <SettingsWindow.hpp>
#include <log.hpp>
#include <memory>
class KaizenGui { class KaizenGui final {
public: public:
KaizenGui() noexcept; explicit KaizenGui() noexcept;
void LoadTAS(const std::string &path) const noexcept; double fpsCounter;
void LoadROM(const std::string &path) const noexcept; gui::MenuBar<true> menuBar;
int run(); gui::MenuItem actionPause{"Pause"}, actionStop{"Stop"}, actionReset{"Reset"};
private:
void Quit() const noexcept;
void ConnectMainWindowSignalsToSlots() noexcept;
MainWindow mainWindow;
SettingsWindow settingsWindow;
EmuThread emuThread;
// std::unique_ptr<Debugger> debugger;
std::shared_ptr<n64::Core> core; std::shared_ptr<n64::Core> core;
EmuThread emuThread;
SettingsWindow settingsWindow;
RenderWidget vulkanWidget;
int run();
void LoadTAS(const std::string &path) const noexcept;
void LoadROM(const std::string &path) noexcept;
private:
bool quit = false;
void handleEvents();
std::function<void()> emuExitFunc;
bool textPauseToggle = false;
}; };

View File

@@ -1,153 +0,0 @@
#include <MainWindow.hpp>
MainWindow::MainWindow(const std::shared_ptr<n64::Core> &core) noexcept : vulkanWidget(core) {
/* if (objectName().isEmpty())
setObjectName("MainWindow");
resize(800, 646);
actionOpenDebuggerWindow = std::make_unique<QAction>(this);
actionOpenDebuggerWindow->setObjectName("actionOpenDebuggerWindow");
actionAbout = std::make_unique<QAction>(this);
actionAbout->setObjectName("actionAbout");
actionOpen = std::make_unique<QAction>(this);
actionOpen->setObjectName("actionOpen");
actionExit = std::make_unique<QAction>(this);
actionExit->setObjectName("actionExit");
actionPause = std::make_unique<QAction>(this);
actionPause->setObjectName("actionPause");
actionReset = std::make_unique<QAction>(this);
actionReset->setObjectName("actionReset");
actionStop = std::make_unique<QAction>(this);
actionStop->setObjectName("actionStop");
actionSettings = std::make_unique<QAction>(this);
actionSettings->setObjectName("actionSettings");
centralwidget = std::make_unique<QWidget>(this);
centralwidget->setObjectName("centralwidget");
verticalLayout = std::make_unique<QVBoxLayout>();
verticalLayout->setSpacing(0);
verticalLayout->setObjectName("verticalLayout");
verticalLayout->setContentsMargins(0, 0, 0, 0);
verticalLayout->addWidget(vulkanWidget.get());
centralwidget->setLayout(verticalLayout.get());
setCentralWidget(centralwidget.get());
menubar = std::make_unique<QMenuBar>(this);
menubar->setObjectName("menubar");
menubar->setGeometry(QRect(0, 0, 800, 22));
menuFile = std::make_unique<QMenu>(menubar.get());
menuFile->setObjectName("menuFile");
menuEmulation = std::make_unique<QMenu>(menubar.get());
menuEmulation->setObjectName("menuEmulation");
menuTools = std::make_unique<QMenu>(menubar.get());
menuTools->setObjectName("menuTools");
menuAbout = std::make_unique<QMenu>(menubar.get());
menuAbout->setObjectName("menuAbout");
setMenuBar(menubar.get());
statusbar = std::make_unique<QStatusBar>(this);
statusbar->setObjectName("statusbar");
fpsCounter = std::make_unique<QLabel>("Not playing");
statusbar->addPermanentWidget(fpsCounter.get());
setStatusBar(statusbar.get());
menubar->addAction(menuFile->menuAction());
menubar->addAction(menuEmulation->menuAction());
menubar->addAction(menuTools->menuAction());
menubar->addAction(menuAbout->menuAction());
menuFile->addAction(actionOpen.get());
menuFile->addAction(actionExit.get());
menuEmulation->addAction(actionSettings.get());
menuEmulation->addAction(actionPause.get());
menuEmulation->addAction(actionReset.get());
menuEmulation->addAction(actionStop.get());
menuTools->addAction(actionOpenDebuggerWindow.get());
menuAbout->addAction(actionAbout.get());
Retranslate();
QMetaObject::connectSlotsByName(this);
actionPause->setDisabled(true);
actionReset->setDisabled(true);
actionStop->setDisabled(true);
vulkanWidget->hide();
ConnectSignalsToSlots();*/
}
void MainWindow::Retranslate() {
/*setWindowTitle(QCoreApplication::translate("MainWindow", "Kaizen", nullptr));
actionOpenDebuggerWindow->setText(QCoreApplication::translate("MainWindow", "CPU Debugger", nullptr));
actionOpenDebuggerWindow->setStatusTip(QCoreApplication::translate(
"MainWindow", "Open the CPU debugger window which allows you see registers, memory and disassembled code",
nullptr));
actionAbout->setText(QCoreApplication::translate("MainWindow", "About Kaizen", nullptr));
actionAbout->setStatusTip(QCoreApplication::translate("MainWindow", "About this emulator", nullptr));
actionOpen->setText(QCoreApplication::translate("MainWindow", "Open...", nullptr));
actionOpen->setStatusTip(QCoreApplication::translate("MainWindow", "Open a ROM", nullptr));
actionOpen->setShortcut(QCoreApplication::translate("MainWindow", "Ctrl+O", nullptr));
actionExit->setText(QCoreApplication::translate("MainWindow", "Exit", nullptr));
actionExit->setStatusTip(QCoreApplication::translate("MainWindow", "Quit the emulator", nullptr));
actionPause->setText(QCoreApplication::translate("MainWindow", "Pause", nullptr));
actionPause->setStatusTip(QCoreApplication::translate("MainWindow", "Pause the emulation", nullptr));
actionReset->setText(QCoreApplication::translate("MainWindow", "Reset", nullptr));
actionReset->setStatusTip(QCoreApplication::translate("MainWindow", "Reset the emulation", nullptr));
actionStop->setText(QCoreApplication::translate("MainWindow", "Stop", nullptr));
actionStop->setStatusTip(QCoreApplication::translate("MainWindow", "Stop the emulation", nullptr));
actionSettings->setText(QCoreApplication::translate("MainWindow", "Settings", nullptr));
actionSettings->setToolTip(QCoreApplication::translate("MainWindow", "Settings", nullptr));
actionSettings->setStatusTip(QCoreApplication::translate("MainWindow", "Open the settings window", nullptr));
menuFile->setTitle(QCoreApplication::translate("MainWindow", "File", nullptr));
menuEmulation->setTitle(QCoreApplication::translate("MainWindow", "Emulation", nullptr));
menuTools->setTitle(QCoreApplication::translate("MainWindow", "Tools", nullptr));
menuAbout->setTitle(QCoreApplication::translate("MainWindow", "Help", nullptr));
*/
} // retranslateUi
void MainWindow::ConnectSignalsToSlots() noexcept {
/* connect(actionOpen.get(), &QAction::triggered, this, [this]() {
const QString file_name = QFileDialog::getOpenFileName(
this, "Nintendo 64 executable", QString(),
"All supported types (*.zip *.ZIP *.7z *.7Z *.rar *.RAR *.tar *.TAR *.n64 *.N64 *.v64 *.V64 *.z64 *.Z64)");
if (!file_name.isEmpty()) {
emit OpenROM(file_name);
vulkanWidget->show();
}
});
connect(actionExit.get(), &QAction::triggered, this, [this]() { emit Exit(); });
connect(this, &MainWindow::destroyed, this, [this]() { emit Exit(); });
connect(actionReset.get(), &QAction::triggered, this, [this]() { emit Reset(); });
connect(actionStop.get(), &QAction::triggered, this, [this]() {
setWindowTitle("Kaizen");
vulkanWidget->hide();
actionPause->setDisabled(true);
actionReset->setDisabled(true);
actionStop->setDisabled(true);
emit Stop();
});
connect(actionPause.get(), &QAction::triggered, this, [this]() {
textPauseToggle = !textPauseToggle;
actionPause->setText(textPauseToggle ? "Resume" : "Pause");
emit Pause();
});
connect(actionAbout.get(), &QAction::triggered, this, [this]() {
QMessageBox::about(this, tr("About Kaizen"),
tr("Kaizen is a Nintendo 64 emulator that strives to offer a friendly user "
"experience and great compatibility.\n"
"Kaizen is licensed under the BSD 3-clause license.\n"
"Nintendo 64 is a registered trademarks of Nintendo Co., Ltd."));
});
connect(actionSettings.get(), &QAction::triggered, this, [this]() { emit OpenSettings(); });
connect(actionOpenDebuggerWindow.get(), &QAction::triggered, this, [this]() { emit OpenDebugger(); });
*/
}
bool MainWindow::render() {
}

View File

@@ -1,37 +0,0 @@
#pragma once
#include <RenderWidget.hpp>
#include <Debugger.hpp>
class MainWindow final {
public:
explicit MainWindow(const std::shared_ptr<n64::Core> &) noexcept;
std::string fpsCounter;
RenderWidget vulkanWidget;
bool render();
//std::unique_ptr<QAction> actionOpenDebuggerWindow{};
//std::unique_ptr<QAction> actionAbout{};
//std::unique_ptr<QAction> actionOpen{};
//std::unique_ptr<QAction> actionExit{};
//std::unique_ptr<QAction> actionPause{};
//std::unique_ptr<QAction> actionReset{};
//std::unique_ptr<QAction> actionStop{};
//std::unique_ptr<QAction> actionSettings{};
//std::unique_ptr<QWidget> centralwidget{};
//std::unique_ptr<QVBoxLayout> verticalLayout{};
//std::unique_ptr<RenderWidget> vulkanWidget{};
//std::unique_ptr<QMenuBar> menubar{};
//std::unique_ptr<QMenu> menuFile{};
//std::unique_ptr<QMenu> menuEmulation{};
//std::unique_ptr<QMenu> menuTools{};
//std::unique_ptr<QMenu> menuAbout{};
//std::unique_ptr<QStatusBar> statusbar{};
//std::unique_ptr<QLabel> fpsCounter{};
private:
void Retranslate();
void ConnectSignalsToSlots() noexcept;
bool textPauseToggle = false;
};

View File

@@ -9,11 +9,11 @@ RenderWidget::RenderWidget(const std::shared_ptr<n64::Core> &core) {
} }
imGuiVkInstanceFactory = std::make_shared<ImGuiInstanceFactory>(); imGuiVkInstanceFactory = std::make_shared<ImGuiInstanceFactory>();
windowHandle()->setVulkanInstance(&imGuiVkInstanceFactory->handle); //windowHandle()->setVulkanInstance(&imGuiVkInstanceFactory->create_instance());
windowHandle()->create(); //windowHandle()->create();
wsiPlatform = std::make_shared<ImGuiWSIPlatform>(core, windowHandle()); //wsiPlatform = std::make_shared<ImGuiWSIPlatform>(core, windowHandle());
windowInfo = std::make_shared<ImGuiParallelRdpWindowInfo>(windowHandle()); // windowInfo = std::make_shared<ImGuiParallelRdpWindowInfo>(windowHandle());
} }
void ImGuiWSIPlatform::poll_input() { void ImGuiWSIPlatform::poll_input() {

View File

@@ -1,76 +1,76 @@
#include <SettingsWindow.hpp> #include <SettingsWindow.hpp>
#include <fmt/core.h> #include <fmt/core.h>
#include <nfd.hpp>
#include <log.hpp>
#include <JSONUtils.hpp>
std::string savePath; std::string savePath;
SettingsWindow::SettingsWindow() { SettingsWindow::SettingsWindow() : settings{JSONOpenOrCreate("resources/settings.json")} {
settings = JSONOpenOrCreate("resources/settings.json");
savePath = JSONGetField<std::string>(settings, "general", "savePath");
keyMap = inputSettings.GetMappedKeys(); keyMap = inputSettings.GetMappedKeys();
savesFolder.setName(fmt::format(savesFolder.getName(), savePath)); savesFolder.setName(fmt::format("Save path: {}",
JSONGetField<std::string>(settings, "general", "savePath")));
tabs.addTab({"General", [](gui::TabItem* tab, void* userData) { tabs.addTab({"General", [&]() {
SettingsWindow* sW = (SettingsWindow*)userData; if(savesFolder.render()) {
if(sW->savesFolder.render()) { NFD::Guard guard;
// TODO: HANDLE FILE DIALOG savePath = QFileDialog::getExistingDirectory(this, tr("Select directory")).toStdString(); NFD::UniquePath outPath;
sW->savesFolder.setName(fmt::format(sW->savesFolder.getName(), savePath));
JSONSetField(sW->settings, "general", "savePath", savePath); auto result = NFD::PickFolder(outPath);
sW->apply.setEnabled(true); if(result == NFD_CANCEL)
return;
if(result == NFD_ERROR)
Util::panic("Error: {}", NFD::GetError());
savesFolder.setName(fmt::format("Save path: {}", outPath.get()));
JSONSetField(settings, "general", "savePath", outPath.get());
apply.setEnabled(true);
} }
}, this}); }});
tabs.addTab({"CPU", [](gui::TabItem* tab, void* userData) { tabs.addTab({"CPU", [&]() {
SettingsWindow* sW = (SettingsWindow*)userData; if(cpuSettings.render()) {
CPUSettings& cS = sW->cpuSettings; if(cpuSettings.getModified())
gui::PushButton& apply = sW->apply;
if(cS.render()) {
if(cS.getModified())
sW->apply.setEnabled(true);
}
}, this});
tabs.addTab({"Audio", [](gui::TabItem* tab, void* userData) {
SettingsWindow* sW = (SettingsWindow*)userData;
AudioSettings& aS = sW->audioSettings;
gui::PushButton& apply = sW->apply;
if(aS.render()) {
if(aS.getModified())
apply.setEnabled(true); apply.setEnabled(true);
} }
}, this}); }});
tabs.addTab({"Input", [](gui::TabItem* tab, void* userData) { tabs.addTab({"Audio", [&]() {
SettingsWindow* sW = (SettingsWindow*)userData; if(audioSettings.render()) {
sW->inputSettings.render(); if(audioSettings.getModified())
InputSettings& iS = sW->inputSettings;
gui::PushButton& apply = sW->apply;
if(iS.render()) {
if(iS.getModified())
apply.setEnabled(true); apply.setEnabled(true);
} }
}, this}); }});
tabs.addTab({"Input", [&]() {
if(inputSettings.render()) {
if(inputSettings.getModified())
apply.setEnabled(true);
}
}});
apply.setEnabled(false); apply.setEnabled(false);
canvas.setFunc([&]() {
tabs.render();
if(apply.render()) {
auto newMap = inputSettings.GetMappedKeys();
if (keyMap != newMap)
keyMap = newMap;
apply.setEnabled(false);
std::ofstream file("resources/settings.json");
file << settings;
file.close();
}
});
} }
bool SettingsWindow::render() { bool SettingsWindow::render() {
tabs.render(); if(canvas.render())
return true;
if(apply.render()) {
auto newMap = inputSettings.GetMappedKeys();
if (keyMap != newMap)
keyMap = newMap;
apply.setEnabled(false);
std::ofstream file("resources/settings.json");
file << settings;
file.close();
}
return false; return false;
} }

View File

@@ -3,25 +3,17 @@
#include <CPUSettings.hpp> #include <CPUSettings.hpp>
#include <InputSettings.hpp> #include <InputSettings.hpp>
#include <ImGuiImpl/TabBar.hpp> #include <ImGuiImpl/TabBar.hpp>
#include <ImGuiImpl/PopupWindow.hpp>
#include <SDL3/SDL_keycode.h> #include <SDL3/SDL_keycode.h>
#include <memory> #include <memory>
class SettingsWindow final { class SettingsWindow final {
gui::PushButton cancel{"Cancel"}, apply{"Apply", "", false}, savesFolder{"Open", "Save path: {}"}; gui::PushButton cancel{"Cancel"}, apply{"Apply", "", false}, savesFolder{"Open", "Save path: {}"};
gui::PopupWindow canvas{"Settings"};
nlohmann::json settings;
CPUSettings cpuSettings{settings}; CPUSettings cpuSettings{settings};
AudioSettings audioSettings{settings}; AudioSettings audioSettings{settings};
InputSettings inputSettings{settings}; InputSettings inputSettings{settings};
//std::unique_ptr<QPushButton> cancel = std::make_unique<QPushButton>("Cancel");
//std::unique_ptr<QPushButton> apply = std::make_unique<QPushButton>("Apply");
//std::unique_ptr<QFileIconProvider> iconProv = std::make_unique<QFileIconProvider>();
//std::unique_ptr<QPushButton> folderBtn = std::make_unique<QPushButton>(iconProv->icon(QFileIconProvider::Folder), "");
//std::unique_ptr<QLabel> folderLabelPrefix = std::make_unique<QLabel>("Save files' path: ");
//std::unique_ptr<QLabel> folderLabel;
//std::unique_ptr<QHBoxLayout> generalLayout = std::make_unique<QHBoxLayout>();
//std::unique_ptr<QVBoxLayout> generalLayoutV = std::make_unique<QVBoxLayout>();
//std::unique_ptr<QTabWidget> tabs = std::make_unique<QTabWidget>();
//std::unique_ptr<QVBoxLayout> mainLayout = std::make_unique<QVBoxLayout>();
//std::unique_ptr<QHBoxLayout> buttonsLayout = std::make_unique<QHBoxLayout>();
public: public:
bool render(); bool render();
SettingsWindow(); SettingsWindow();
@@ -29,7 +21,5 @@ public:
[[nodiscard]] float getVolumeR() const { return audioSettings.volumeR.getValue() / 100.f; } [[nodiscard]] float getVolumeR() const { return audioSettings.volumeR.getValue() / 100.f; }
std::array<SDL_Keycode, 18> keyMap{}; std::array<SDL_Keycode, 18> keyMap{};
nlohmann::json settings;
gui::TabBar tabs{"SettingsTabs"}; gui::TabBar tabs{"SettingsTabs"};
//std::unique_ptr<QWidget> generalSettings{};
}; };

View File

@@ -3,6 +3,8 @@
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <byteswap.hpp> #include <byteswap.hpp>
#include <algorithm>
#include <vector>
namespace Util { namespace Util {
template <typename T> template <typename T>