diff --git a/external/shader.frag b/external/shader.frag new file mode 100644 index 00000000..cda4cd96 --- /dev/null +++ b/external/shader.frag @@ -0,0 +1,20 @@ +#version 450 +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 0) uniform sampler2D uImage; + +layout(push_constant) uniform Screen { + vec2 size; + vec2 offset; +} uScreen; + +layout(constant_id = 0) const float Scale = 1.0; + +void main() { + vec2 uv = (vUV - uScreen.offset) / uScreen.size; + if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { + FragColor = vec4(0, 0, 0, 1); + } else { + FragColor = Scale * textureLod(uImage, uv, 0.0); + } +} diff --git a/external/shader.vert b/external/shader.vert new file mode 100644 index 00000000..6c1c88d1 --- /dev/null +++ b/external/shader.vert @@ -0,0 +1,8 @@ +#version 450 +layout(location = 0) in vec2 Position; +layout(location = 0) out highp vec2 vUV; + +void main() { + gl_Position = vec4(Position, 0.0, 1.0); + vUV = 0.5 * Position + 0.5; +} diff --git a/src/core/common.hpp b/src/core/common.hpp index 589e7899..ec982fcb 100644 --- a/src/core/common.hpp +++ b/src/core/common.hpp @@ -24,3 +24,6 @@ using m128 = __m128i; #define KiB * 1024 #define MiB (KiB * 1024) #define GiB (MiB * 1024) + +#define N64_CPU_FREQ 93750000 +#define N64_CYCLES_PER_FRAME (N64_CPU_FREQ / 60) \ No newline at end of file diff --git a/src/core/n64/CMakeLists.txt b/src/core/n64/CMakeLists.txt index ab9d4b24..47a9dc7b 100644 --- a/src/core/n64/CMakeLists.txt +++ b/src/core/n64/CMakeLists.txt @@ -20,12 +20,19 @@ find_package(fmt REQUIRED) add_subdirectory(core) +set(PARALLELRDP_INCLUDES + ../../../external/parallel-rdp-standalone/vulkan + ../../../external/parallel-rdp-standalone/util + ../../../external/parallel-rdp-standalone/parallel-rdp + ../../../external/parallel-rdp-standalone/volk + ../../../external/parallel-rdp-standalone/vulkan-headers) + add_library(n64 Core.hpp Core.cpp memory_regions.hpp ../BaseCore.cpp ../BaseCore.hpp) -target_include_directories(n64 PRIVATE . ..) +target_include_directories(n64 PRIVATE . .. ../../frontend/sdl ${PARALLELRDP_INCLUDES}) target_include_directories(n64 PUBLIC ${mio_SOURCE_DIR}/include ${toml11_SOURCE_DIR}/include) target_link_libraries(n64 PRIVATE mio::mio toml11::toml11 fmt::fmt n64-core) diff --git a/src/core/n64/Core.cpp b/src/core/n64/Core.cpp index f843e155..150dc005 100644 --- a/src/core/n64/Core.cpp +++ b/src/core/n64/Core.cpp @@ -1,9 +1,11 @@ #include #include +#include namespace natsukashii::n64::core { Core::Core(const std::string& rom) { mem.LoadROM(rom); + LoadParallelRDP(mem.GetRDRAM()); } void Core::Run() { diff --git a/src/core/n64/Core.hpp b/src/core/n64/Core.hpp index c15e58ff..bfa9e50b 100644 --- a/src/core/n64/Core.hpp +++ b/src/core/n64/Core.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "n64/core/Cpu.hpp" -#include "n64/core/Mem.hpp" +#include +#include #include namespace natsukashii::n64::core { diff --git a/src/core/n64/core/CMakeLists.txt b/src/core/n64/core/CMakeLists.txt index db57f8bd..322254a3 100644 --- a/src/core/n64/core/CMakeLists.txt +++ b/src/core/n64/core/CMakeLists.txt @@ -7,7 +7,11 @@ add_library(n64-core Cpu.hpp Cpu.cpp Mem.cpp - Mem.hpp RDP.cpp RDP.hpp) + Mem.hpp + RDP.cpp + RDP.hpp + mmio/VI.cpp + mmio/VI.hpp mmio/Interrupt.hpp mmio/MI.cpp mmio/MI.hpp mmio/Interrupt.cpp) -target_include_directories(n64-core PRIVATE . .. ../../) +target_include_directories(n64-core PRIVATE . .. ../../ mmio) target_link_libraries(n64-core PUBLIC n64-cpu) diff --git a/src/core/n64/core/Cpu.cpp b/src/core/n64/core/Cpu.cpp index 5a56991b..44ff5d7a 100644 --- a/src/core/n64/core/Cpu.cpp +++ b/src/core/n64/core/Cpu.cpp @@ -1 +1 @@ -#include "Cpu.hpp" +#include diff --git a/src/core/n64/core/Cpu.hpp b/src/core/n64/core/Cpu.hpp index 2f3a32be..055e6b4b 100644 --- a/src/core/n64/core/Cpu.hpp +++ b/src/core/n64/core/Cpu.hpp @@ -1,5 +1,5 @@ #pragma once -#include "n64/core/cpu/Registers.hpp" +#include namespace natsukashii::n64::core { struct Cpu { diff --git a/src/core/n64/core/Mem.hpp b/src/core/n64/core/Mem.hpp index c499355f..7e4b6c69 100644 --- a/src/core/n64/core/Mem.hpp +++ b/src/core/n64/core/Mem.hpp @@ -8,6 +8,9 @@ struct Mem { ~Mem() = default; Mem(); void LoadROM(const std::string&); + [[nodiscard]] auto GetRDRAM() const -> const u8* { + return rdram.data(); + } private: std::vector cart, rdram, sram; u8 dmem[DMEM_SIZE]{}, imem[IMEM_SIZE]{}, pifRam[PIF_RAM_SIZE]{}; diff --git a/src/core/n64/core/mmio/Interrupt.cpp b/src/core/n64/core/mmio/Interrupt.cpp new file mode 100644 index 00000000..e49c1f27 --- /dev/null +++ b/src/core/n64/core/mmio/Interrupt.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +namespace natsukashii::n64::core { +void InterruptRaise(MI &mi, Registers ®s, InterruptType intr) { + switch(intr) { + case InterruptType::VI: + mi.miIntr.vi = true; + break; + case InterruptType::SI: + mi.miIntr.si = true; + break; + case InterruptType::PI: + mi.miIntr.pi = true; + break; + case InterruptType::AI: + mi.miIntr.ai = true; + break; + case InterruptType::DP: + mi.miIntr.dp = true; + break; + case InterruptType::SP: + mi.miIntr.sp = true; + break; + } + + UpdateInterrupt(mi, regs); +} +void InterruptLower(MI &mi, Registers ®s, InterruptType intr) { + switch(intr) { + case InterruptType::VI: + mi.miIntr.vi = false; + break; + case InterruptType::SI: + mi.miIntr.si = false; + break; + case InterruptType::PI: + mi.miIntr.pi = false; + break; + case InterruptType::AI: + mi.miIntr.ai = false; + break; + case InterruptType::DP: + mi.miIntr.dp = false; + break; + case InterruptType::SP: + mi.miIntr.sp = false; + break; + } + + UpdateInterrupt(mi, regs); +} +void UpdateInterrupt(MI &mi, Registers ®s) { + bool interrupt = mi.miIntr.raw & mi.miIntrMask.raw; + regs.cop0.cause.ip2 = interrupt; +} +} \ No newline at end of file diff --git a/src/core/n64/core/mmio/Interrupt.hpp b/src/core/n64/core/mmio/Interrupt.hpp new file mode 100644 index 00000000..cffdd078 --- /dev/null +++ b/src/core/n64/core/mmio/Interrupt.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +namespace natsukashii::n64::core { + +struct Registers; + +enum class InterruptType : u8 { + VI, SI, PI, AI, DP, SP +}; + +void InterruptRaise(MI &mi, Registers ®s, InterruptType intr); +void InterruptLower(MI &mi, Registers ®s, InterruptType intr); +void UpdateInterrupt(MI &mi, Registers ®s); +} \ No newline at end of file diff --git a/src/core/n64/core/mmio/MI.cpp b/src/core/n64/core/mmio/MI.cpp new file mode 100644 index 00000000..8292636d --- /dev/null +++ b/src/core/n64/core/mmio/MI.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include + +#define MI_VERSION_REG 0x02020102 + +namespace natsukashii::n64::core { +MI::MI() { + miIntrMask.raw = 0; + miIntr.raw = 0; + miMode = 0; +} + +u32 MI::Read(u32 paddr) { + switch(paddr & 0xF) { + case 0x0: return miMode & 0x3FF; + case 0x4: return MI_VERSION_REG; + case 0x8: return miIntr.raw & 0x3F; + case 0xC: return miIntrMask.raw & 0x3F; + default: util::panic("Unhandled MI[%08X] read\n", paddr); + } +} + +void MI::Write(Registers& regs, u32 paddr, u32 val) { + switch(paddr & 0xF) { + case 0x0: + miMode &= 0xFFFFFF80; + miMode |= val & 0x7F; + if (val & (1 << 7)) { + miMode &= ~(1 << 7); + } + + if (val & (1 << 8)) { + miMode |= 1 << 7; + } + + if (val & (1 << 9)) { + miMode &= ~(1 << 8); + } + + if (val & (1 << 10)) { + miMode |= 1 << 8; + } + + if (val & (1 << 11)) { + InterruptLower(*this, regs, InterruptType::DP); + } + + if (val & (1 << 12)) { + miMode &= ~(1 << 9); + } + + if (val & (1 << 13)) { + miMode |= 1 << 9; + } + break; + case 0x4: break; + case 0xC: + for (int bit = 0; bit < 6; bit++) { + int clearbit = bit << 1; + int setbit = (bit << 1) + 1; + + if (val & (1 << clearbit)) { + miIntrMask.raw &= ~(1 << bit); + } + + if (val & (1 << setbit)) { + miIntrMask.raw |= 1 << bit; + } + } + + UpdateInterrupt(*this, regs); + break; + default: + util::panic("Unhandled MI[%08X] write (%08X)\n", val, paddr); + } +} +} \ No newline at end of file diff --git a/src/core/n64/core/mmio/MI.hpp b/src/core/n64/core/mmio/MI.hpp new file mode 100644 index 00000000..39bd332d --- /dev/null +++ b/src/core/n64/core/mmio/MI.hpp @@ -0,0 +1,29 @@ +#pragma once +#include + +namespace natsukashii::n64::core { + +union MIIntr { + struct { + unsigned sp: 1; + unsigned si: 1; + unsigned ai: 1; + unsigned vi: 1; + unsigned pi: 1; + unsigned dp: 1; + unsigned: 26; + }; + u32 raw; +}; + +struct Registers; + +struct MI { + MI(); + u32 Read(u32); + void Write(Registers& regs, u32, u32); + + u32 miMode; + MIIntr miIntr{}, miIntrMask{}; +}; +} \ No newline at end of file diff --git a/src/core/n64/core/mmio/VI.cpp b/src/core/n64/core/mmio/VI.cpp new file mode 100644 index 00000000..2f99a5ae --- /dev/null +++ b/src/core/n64/core/mmio/VI.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +namespace natsukashii::n64::core { +VI::VI () { + status.raw = 0xF; + intr = 256; + origin = 0; + width = 320; + current = 0; + vsync = 0; + hsync = 0; + numHalflines = 262; + numFields = 1; + cyclesPerHalfline = 1000; +} + +u32 VI::Read(u32 paddr) { + switch(paddr) { + case 0x04400000: return status.raw; + case 0x04400004: return origin; + case 0x04400008: return width; + case 0x0440000C: return intr; + case 0x04400010: return current << 1; + case 0x04400014: return burst.raw; + case 0x04400018: return vsync; + case 0x0440001C: return hsync; + case 0x04400020: return hsyncLeap.raw; + case 0x04400024: return hvideo.raw; + case 0x04400028: return vvideo.raw; + case 0x0440002C: return vburst.raw; + case 0x04400030: return xscale.raw; + case 0x04400034: return yscale.raw; + default: + util::panic("Unimplemented VI[%08X] read\n", paddr); + } +} + +void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) { + switch(paddr) { + case 0x04400000: + status.raw = val; + numFields = status.serrate ? 2 : 1; + break; + case 0x04400004: { + u32 masked = val & 0xFFFFFF; + if(origin != masked) { + swaps++; + } + origin = masked; + } break; + case 0x04400008: { + width = val & 0x7FF; + } break; + case 0x0440000C: { + intr = val & 0x3FF; + } break; + case 0x04400010: + InterruptLower(mi, regs, InterruptType::VI); + break; + case 0x04400014: burst.raw = val; break; + case 0x04400018: { + vsync = val & 0x3FF; + numHalflines = vsync >> 1; + cyclesPerHalfline = N64_CYCLES_PER_FRAME / numHalflines; + } break; + case 0x0440001C: { + hsync = val & 0x3FF; + } break; + case 0x04400020: hsyncLeap.raw = val; break; + case 0x04400024: hvideo.raw = val; break; + case 0x04400028: vvideo.raw = val; break; + case 0x0440002C: vburst.raw = val; break; + case 0x04400030: xscale.raw = val; break; + case 0x04400034: yscale.raw = val; break; + default: + util::panic("Unimplemented VI[%08X] write (%08X)\n", paddr, val); + } +} +} \ No newline at end of file diff --git a/src/core/n64/core/mmio/VI.hpp b/src/core/n64/core/mmio/VI.hpp new file mode 100644 index 00000000..fd544668 --- /dev/null +++ b/src/core/n64/core/mmio/VI.hpp @@ -0,0 +1,83 @@ +#pragma once +#include + +namespace natsukashii::n64::core { +union VIBurst { + struct { + unsigned hsyncW:8; + unsigned burstW:8; + unsigned vsyncW:4; + unsigned burstStart:10; + unsigned:2; + }; + u32 raw; +}; + +union VIHsyncLeap { + struct { + unsigned leapB:10; + unsigned:6; + unsigned leapA:10; + unsigned:6; + }; + u32 raw; +} ; + +union VIVideo { + struct { + unsigned end:10; + unsigned:6; + unsigned start:10; + unsigned:6; + }; + u32 raw; +}; + +union VIScale { + struct { + unsigned scale:12; + unsigned:4; + unsigned offset:12; + unsigned:4; + }; + u32 raw; +}; + +enum VIFormat { + blank = 0, + reserved = 1, + f5553 = 2, + f8888 = 3 +}; + +union VIStatus { + struct { + u8 format:2; + unsigned serrate:1; + unsigned:29; + }; + + u32 raw; +}; + +struct MI; +struct Registers; + +struct VI { + VI(); + u32 Read(u32); + void Write(MI&, Registers&, u32, u32); + VIScale xscale{}, yscale{}; + VIVideo hvideo{}, vvideo{}; + VIHsyncLeap hsyncLeap{}; + VIStatus status{}; + VIBurst burst{}, vburst{}; + u32 origin, width, current; + u32 vsync, hsync, intr; + u32 hstart{}, vstart{}; + int swaps{}; + int numHalflines; + int numFields; + int cyclesPerHalfline; +}; +} // natsukashii::n64::core diff --git a/src/core/util.hpp b/src/core/util.hpp index f46a4cc6..a407c8bd 100644 --- a/src/core/util.hpp +++ b/src/core/util.hpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace natsukashii::util { enum MessageType : u8 { @@ -133,4 +134,21 @@ inline size_t NextPow2(size_t num) { num |= num >> 16; return num + 1; } + +inline void ReadFileBinary(const std::string& path, void* buf) { + std::ifstream file("external/vert.spv", std::ios::binary); + file.unsetf(std::ios::skipws); + if(!file.is_open()) { + util::panic("Could not load file!\n"); + } + file.seekg(std::ios::end); + auto size = file.tellg(); + file.seekg(std::ios::beg); + if(buf) + free(buf); + + buf = calloc(size, 1); + file.read((char*)buf, size); + file.close(); +} } diff --git a/src/frontend/sdl/Frontend.cpp b/src/frontend/sdl/Frontend.cpp index f7a305fe..49a18648 100644 --- a/src/frontend/sdl/Frontend.cpp +++ b/src/frontend/sdl/Frontend.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace natsukashii::frontend { using namespace natsukashii; diff --git a/src/frontend/sdl/Frontend.hpp b/src/frontend/sdl/Frontend.hpp index f7bb03d1..844ea6b3 100644 --- a/src/frontend/sdl/Frontend.hpp +++ b/src/frontend/sdl/Frontend.hpp @@ -15,7 +15,6 @@ struct App { App(const std::string&, const std::string&); void Run(); private: - SDL_Window *window = nullptr; SDL_Renderer *renderer = nullptr; u32 id; std::unique_ptr core; diff --git a/src/frontend/sdl/ParallelRDPWrapper.cpp b/src/frontend/sdl/ParallelRDPWrapper.cpp index 783311dd..36532479 100644 --- a/src/frontend/sdl/ParallelRDPWrapper.cpp +++ b/src/frontend/sdl/ParallelRDPWrapper.cpp @@ -6,12 +6,11 @@ #include #include -using namespace Vulkan; using namespace natsukashii; +using namespace natsukashii::n64; +using namespace Vulkan; +using namespace RDP; using std::unique_ptr; -using RDP::CommandProcessor; -using RDP::CommandProcessorFlags; -using RDP::VIRegister; static CommandProcessor* command_processor; static WSI* wsi; @@ -19,7 +18,7 @@ static WSI* wsi; std::vector acquire_semaphore; VkQueue GetGraphicsQueue() { - return wsi->get_context().get_graphics_queue(); + return wsi->get_context().get_queue_info().queues[QUEUE_INDEX_GRAPHICS]; } VkInstance GetVkInstance() { @@ -35,7 +34,7 @@ VkDevice GetVkDevice() { } uint32_t GetVkGraphicsQueueFamily() { - return wsi->get_context().get_graphics_queue_family(); + return wsi->get_context().get_queue_info().family_indices[QUEUE_INDEX_GRAPHICS]; } VkFormat GetVkFormat() { @@ -94,11 +93,11 @@ public: } uint32_t get_surface_width() override { - return N64_SCREEN_X * SCREEN_SCALE; + return 800; } uint32_t get_surface_height() override { - return N64_SCREEN_Y * SCREEN_SCALE; + return 600; } bool alive(Vulkan::WSI &wsi) override { @@ -106,11 +105,14 @@ public: } void poll_input() override { - n64_poll_input(); + SDL_Event e; + while(SDL_PollEvent(&e)) { + + } } void event_frame_tick(double frame, double elapsed) override { - n64_render_screen(); + //n64_render_screen(); } }; @@ -125,22 +127,26 @@ void LoadParallelRDP(const u8* rdram) { util::panic("Failed to initialize WSI!"); } - ResourceLayout vert_layout; - ResourceLayout frag_layout; + ResourceLayout vertLayout; + ResourceLayout fragLayout; - vert_layout.input_mask = 1; - vert_layout.output_mask = 1; + vertLayout.input_mask = 1; + vertLayout.output_mask = 1; - frag_layout.input_mask = 1; - frag_layout.output_mask = 1; - frag_layout.spec_constant_mask = 1; - frag_layout.push_constant_size = 4 * sizeof(float); + fragLayout.input_mask = 1; + fragLayout.output_mask = 1; + fragLayout.spec_constant_mask = 1; + fragLayout.push_constant_size = 4 * sizeof(float); - frag_layout.sets[0].sampled_image_mask = 1; - frag_layout.sets[0].fp_mask = 1; - frag_layout.sets[0].array_size[0] = 1; + fragLayout.sets[0].sampled_image_mask = 1; + fragLayout.sets[0].fp_mask = 1; + fragLayout.sets[0].array_size[0] = 1; - fullscreen_quad_program = wsi->get_device().request_program(fullscreen_quad_vert, sizeof(fullscreen_quad_vert), fullscreen_quad_frag, sizeof(fullscreen_quad_frag), &vert_layout, &frag_layout); + u32* fullscreenQuadVert, *fullscreenQuadFrag; + util::ReadFileBinary("external/vert.spv", fullscreenQuadVert); + util::ReadFileBinary("external/frag.spv", fullscreenQuadFrag); + + fullscreen_quad_program = wsi->get_device().request_program(fullscreenQuadVert, sizeof(fullscreenQuadVert), fullscreenQuadFrag, sizeof(fullscreenQuadFrag), &vertLayout, &fragLayout); auto aligned_rdram = reinterpret_cast(rdram); uintptr_t offset = 0; @@ -162,7 +168,7 @@ void LoadParallelRDP(const u8* rdram) { } } -void draw_fullscreen_textured_quad(Util::IntrusivePtr image, Util::IntrusivePtr cmd) { +void DrawFullscreenTexturedQuad(Util::IntrusivePtr image, Util::IntrusivePtr cmd) { cmd->set_texture(0, 0, image->get_view(), Vulkan::StockSampler::LinearClamp); cmd->set_program(fullscreen_quad_program); cmd->set_quad_state(); @@ -200,11 +206,11 @@ void draw_fullscreen_textured_quad(Util::IntrusivePtr image, Util::Intrus cmd->draw(3, 1); } -void update_screen(Util::IntrusivePtr image) { +void UpdateScreen(Util::IntrusivePtr image) { wsi->begin_frame(); if (!image) { - auto info = Vulkan::ImageCreateInfo::immutable_2d_image(N64_SCREEN_X * SCREEN_SCALE, N64_SCREEN_Y * SCREEN_SCALE, VK_FORMAT_R8G8B8A8_UNORM); + auto info = Vulkan::ImageCreateInfo::immutable_2d_image(800, 600, VK_FORMAT_R8G8B8A8_UNORM); info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.misc = IMAGE_MISC_MUTABLE_SRGB_BIT; @@ -228,32 +234,28 @@ void update_screen(Util::IntrusivePtr image) { Util::IntrusivePtr cmd = wsi->get_device().request_command_buffer(); cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly)); - draw_fullscreen_textured_quad(image, cmd); - ImGui_ImplVulkan_RenderDrawData(imgui_frame(), cmd->get_command_buffer()); + DrawFullscreenTexturedQuad(image, cmd); + //ImGui_ImplVulkan_RenderDrawData(imgui_frame(), cmd->get_command_buffer()); cmd->end_render_pass(); wsi->get_device().submit(cmd); wsi->end_frame(); } -void update_screen_parallel_rdp() { - if (unlikely(!command_processor)) { - logfatal("Update screen without an initialized command processor"); - } - - command_processor->set_vi_register(VIRegister::Control, n64sys.vi.status.raw); - command_processor->set_vi_register(VIRegister::Origin, n64sys.vi.vi_origin); - command_processor->set_vi_register(VIRegister::Width, n64sys.vi.vi_width); - command_processor->set_vi_register(VIRegister::Intr, n64sys.vi.vi_v_intr); - command_processor->set_vi_register(VIRegister::VCurrentLine, n64sys.vi.v_current); - command_processor->set_vi_register(VIRegister::Timing, n64sys.vi.vi_burst.raw); - command_processor->set_vi_register(VIRegister::VSync, n64sys.vi.vsync); - command_processor->set_vi_register(VIRegister::HSync, n64sys.vi.hsync); - command_processor->set_vi_register(VIRegister::Leap, n64sys.vi.leap); - command_processor->set_vi_register(VIRegister::HStart, n64sys.vi.hstart.raw); - command_processor->set_vi_register(VIRegister::VStart, n64sys.vi.vstart.raw); - command_processor->set_vi_register(VIRegister::VBurst, n64sys.vi.vburst); - command_processor->set_vi_register(VIRegister::XScale, n64sys.vi.xscale.raw); - command_processor->set_vi_register(VIRegister::YScale, n64sys.vi.yscale.raw); +void UpdateScreenParallelRdp(const n64::core::VI& vi) { + command_processor->set_vi_register(VIRegister::Control, vi.status.raw); + command_processor->set_vi_register(VIRegister::Origin, vi.origin); + command_processor->set_vi_register(VIRegister::Width, vi.width); + command_processor->set_vi_register(VIRegister::Intr, vi.intr); + command_processor->set_vi_register(VIRegister::VCurrentLine, vi.current); + command_processor->set_vi_register(VIRegister::Timing, vi.burst.raw); + command_processor->set_vi_register(VIRegister::VSync, vi.vsync); + command_processor->set_vi_register(VIRegister::HSync, vi.hsync); + command_processor->set_vi_register(VIRegister::Leap, vi.hsyncLeap.raw); + command_processor->set_vi_register(VIRegister::HStart, vi.hstart); + command_processor->set_vi_register(VIRegister::VStart, vi.vstart); + command_processor->set_vi_register(VIRegister::VBurst, vi.burst.raw); + command_processor->set_vi_register(VIRegister::XScale, vi.xscale.raw); + command_processor->set_vi_register(VIRegister::YScale, vi.yscale.raw); RDP::ScanoutOptions opts; opts.persist_frame_on_invalid_input = true; @@ -265,18 +267,18 @@ void update_screen_parallel_rdp() { opts.downscale_steps = true; opts.crop_overscan_pixels = true; Util::IntrusivePtr image = command_processor->scanout(opts); - update_screen(image); + UpdateScreen(image); command_processor->begin_frame_context(); } -void update_screen_parallel_rdp_no_game() { - update_screen(static_cast>(nullptr)); +void UpdateScreenParallelRdpNoGame() { + UpdateScreen(static_cast>(nullptr)); } -void parallel_rdp_enqueue_command(int command_length, word* buffer) { +void ParallelRdpEnqueueCommand(int command_length, u32* buffer) { command_processor->enqueue_command(command_length, buffer); } -void parallel_rdp_on_full_sync() { +void ParallelRdpOnFullSync() { command_processor->wait_for_timeline(command_processor->signal_timeline()); } \ No newline at end of file diff --git a/src/frontend/sdl/ParallelRDPWrapper.hpp b/src/frontend/sdl/ParallelRDPWrapper.hpp index 056d5781..d6a11322 100644 --- a/src/frontend/sdl/ParallelRDPWrapper.hpp +++ b/src/frontend/sdl/ParallelRDPWrapper.hpp @@ -1,7 +1,10 @@ #pragma once #include #include +#include +#include +static SDL_Window* window; VkQueue GetGraphicsQueue(); VkInstance GetVkInstance(); VkPhysicalDevice GetVkPhysicalDevice(); @@ -10,8 +13,8 @@ uint32_t GetVkGraphicsQueueFamily(); VkFormat GetVkFormat(); VkCommandBuffer GetVkCommandBuffer(); void SubmitRequestedVkCommandBuffer(); -void LoadParallelRdp(); -void UpdateScreenParallelRdp(); +void LoadParallelRDP(const u8* rdram); +void UpdateScreenParallelRdp(natsukashii::n64::core::VI& vi); void ParallelRdpEnqueueCommand(int command_length, u32* buffer); void ParallelRdpOnFullSync(); void UpdateScreenParallelRdpNoGame();