From 72502ec9a21e6e844511276bde34780ad1ff26e4 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 7 Feb 2022 02:45:56 -0800 Subject: [PATCH] Start implementing input --- Graphics/include/aurora.hpp | 8 ++ Graphics/include/lib.hpp | 5 ++ Graphics/lib.cpp | 14 ++++ Graphics/src/lib.rs | 83 +++++++++++++++++--- Runtime/CMain.cpp | 152 +++++++++++++++++++++++------------- 5 files changed, 196 insertions(+), 66 deletions(-) diff --git a/Graphics/include/aurora.hpp b/Graphics/include/aurora.hpp index ff72d2f94..ebdacf513 100644 --- a/Graphics/include/aurora.hpp +++ b/Graphics/include/aurora.hpp @@ -6,6 +6,8 @@ #include namespace aurora { +enum class SpecialKey : std::uint8_t; + struct WindowSize; struct App; @@ -25,6 +27,12 @@ struct AppDelegate { virtual void onAppWindowMoved(std::int32_t x, std::int32_t y) noexcept = 0; virtual void onAppExiting() noexcept = 0; + // Input + virtual void onCharKeyDown(std::uint8_t charCode, bool is_repeat) noexcept = 0; + virtual void onCharKeyUp(std::uint8_t charCode) noexcept = 0; + virtual void onSpecialKeyDown(const SpecialKey& key, bool is_repeat) noexcept = 0; + virtual void onSpecialKeyUp(const SpecialKey& key) noexcept = 0; + // virtual void resized([[maybe_unused]] const WindowSize& rect, [[maybe_unused]] bool sync) noexcept {} // virtual void mouseDown([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button, // [[maybe_unused]] EModifierKey mods) noexcept {} diff --git a/Graphics/include/lib.hpp b/Graphics/include/lib.hpp index 6063e6756..f6953833f 100644 --- a/Graphics/include/lib.hpp +++ b/Graphics/include/lib.hpp @@ -9,4 +9,9 @@ void App_onAppPostDraw(AppDelegate& cb) noexcept; void App_onAppWindowResized(AppDelegate& cb, const WindowSize& size) noexcept; void App_onAppWindowMoved(AppDelegate& cb, std::int32_t x, std::int32_t y) noexcept; void App_onAppExiting(AppDelegate& cb) noexcept; +// Input +void App_onCharKeyDown(AppDelegate& cb, std::uint8_t code, bool is_repeat) noexcept; +void App_onCharKeyUp(AppDelegate& cb, std::uint8_t code) noexcept; +void App_onSpecialKeyDown(AppDelegate& cb, const SpecialKey& key, bool is_repeat); +void App_onSpecialKeyUp(AppDelegate& cb, const SpecialKey& key); } // namespace aurora diff --git a/Graphics/lib.cpp b/Graphics/lib.cpp index d809fd85a..c052ad913 100644 --- a/Graphics/lib.cpp +++ b/Graphics/lib.cpp @@ -12,4 +12,18 @@ void App_onAppWindowMoved(AppDelegate& cb, std::int32_t x, std::int32_t y) noexc cb.onAppWindowMoved(x, y); } void App_onAppExiting(AppDelegate& cb) noexcept { cb.onAppExiting(); } + +// Input +void App_onCharKeyDown(AppDelegate& cb, std::uint8_t code, bool is_repeat) noexcept { + cb.onCharKeyDown(code, is_repeat); +} +void App_onCharKeyUp(AppDelegate& cb, std::uint8_t code) noexcept { + cb.onCharKeyUp(code); +} +void App_onSpecialKeyDown(AppDelegate& cb, const SpecialKey& key, bool is_repeat) { + cb.onSpecialKeyDown(key, is_repeat); +} +void App_onSpecialKeyUp(AppDelegate& cb, const SpecialKey& key) { + cb.onSpecialKeyUp(key); +} } // namespace aurora diff --git a/Graphics/src/lib.rs b/Graphics/src/lib.rs index 947ffca21..8a816da59 100644 --- a/Graphics/src/lib.rs +++ b/Graphics/src/lib.rs @@ -3,21 +3,22 @@ #![allow(unused_variables)] #![allow(unused_unsafe)] -use std::{num::NonZeroU8, time::Instant}; - use wgpu::Backend; use winit::{ - event::{Event, WindowEvent, KeyboardInput}, + event::{ElementState, Event, KeyboardInput, WindowEvent}, event_loop::ControlFlow, }; +use winit::event::VirtualKeyCode; +use std::{num::NonZeroU8, time::Instant, collections::HashMap}; use crate::{ - gpu::{create_depth_texture, create_render_texture, initialize_gpu, DeviceHolder}, - imgui::{initialize_imgui, ImGuiState}, + ffi::WindowSize, + gpu::{create_depth_texture, create_render_texture, DeviceHolder, initialize_gpu}, + imgui::{ImGuiState, initialize_imgui}, shaders::render_into_pass, - ffi::{WindowSize}, }; +use crate::ffi::SpecialKey; mod gpu; mod imgui; @@ -42,6 +43,11 @@ mod ffi { pub(crate) fn App_onAppWindowResized(cb: Pin<&mut AppDelegate>, size: &WindowSize); pub(crate) fn App_onAppWindowMoved(cb: Pin<&mut AppDelegate>, x: i32, y: i32); pub(crate) fn App_onAppExiting(cb: Pin<&mut AppDelegate>); + // Input + pub(crate) fn App_onCharKeyDown(cb: Pin<&mut AppDelegate>, code: u8, is_repeat: bool); + pub(crate) fn App_onCharKeyUp(cb: Pin<&mut AppDelegate>, code: u8); + pub(crate) fn App_onSpecialKeyDown(cb: Pin<&mut AppDelegate>, key: &SpecialKey, is_repeat: bool); + pub(crate) fn App_onSpecialKeyUp(cb: Pin<&mut AppDelegate>, key: &SpecialKey); } pub struct Window { @@ -148,13 +154,13 @@ fn app_run(mut delegate: cxx::UniquePtr) { let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap(); let gpu = initialize_gpu(&window); let imgui = initialize_imgui(&window, &gpu); + let mut special_keys_pressed : [bool; 27] = [false; 27]; shaders::construct_state(gpu.device.clone(), gpu.queue.clone(), &gpu.config); - let app = App { window: ffi::Window { inner: Box::new(WindowContext { window }) }, gpu, imgui }; + let app = App { window: ffi::Window { inner: Box::new(WindowContext { window }) }, gpu, imgui}; unsafe { APP.replace(app); ffi::App_onAppLaunched(delegate.as_mut().unwrap()); }; - let mut last_frame: Option = None; event_loop.run(move |event, _, control_flow| { // Have the closure take ownership of the resources. @@ -187,19 +193,72 @@ fn app_run(mut delegate: cxx::UniquePtr) { &app.gpu.config, ); unsafe { - let window_size = WindowSize{width: app.gpu.surface_config.width, height: app.gpu.surface_config.height}; + let window_size = WindowSize { width: app.gpu.surface_config.width, height: app.gpu.surface_config.height }; ffi::App_onAppWindowResized(delegate.as_mut().unwrap(), &window_size); } } - Event::WindowEvent { event: WindowEvent::Moved(loc), ..} => { + Event::WindowEvent { event: WindowEvent::Moved(loc), .. } => { unsafe { ffi::App_onAppWindowMoved(delegate.as_mut().unwrap(), loc.x, loc.y); } } - Event::WindowEvent { event: WindowEvent::KeyboardInput { - input: KeyboardInput, .. }, .. } => { + Event::WindowEvent { + event: WindowEvent::KeyboardInput { + input: + KeyboardInput { + scancode, + virtual_keycode: Some(key), + state, + .. + }, + .. + }, + .. + } => { + // TODO: Handle normal keys, this will require a refactor in game runtime code + let special_key = match key { + VirtualKeyCode::F1 => SpecialKey::F1, + VirtualKeyCode::F2 => SpecialKey::F2, + VirtualKeyCode::F3 => SpecialKey::F3, + VirtualKeyCode::F4 => SpecialKey::F4, + VirtualKeyCode::F5 => SpecialKey::F5, + VirtualKeyCode::F6 => SpecialKey::F6, + VirtualKeyCode::F7 => SpecialKey::F7, + VirtualKeyCode::F8 => SpecialKey::F8, + VirtualKeyCode::F9 => SpecialKey::F9, + VirtualKeyCode::F10 => SpecialKey::F10, + VirtualKeyCode::F11 => SpecialKey::F11, + VirtualKeyCode::F12 => SpecialKey::F12, + VirtualKeyCode::Escape => SpecialKey::Esc, + VirtualKeyCode::Return => SpecialKey::Enter, + VirtualKeyCode::Back => SpecialKey::Backspace, + VirtualKeyCode::Insert => SpecialKey::Insert, + VirtualKeyCode::Delete => SpecialKey::Delete, + VirtualKeyCode::Home => SpecialKey::Home, + VirtualKeyCode::PageUp => SpecialKey::PgUp, + VirtualKeyCode::PageDown => SpecialKey::PgDown, + VirtualKeyCode::Left => SpecialKey::Left, + VirtualKeyCode::Right => SpecialKey::Right, + VirtualKeyCode::Up => SpecialKey::Up, + VirtualKeyCode::Down => SpecialKey::Down, + VirtualKeyCode::Tab => SpecialKey::Tab, + _ => SpecialKey::None, + }; + if special_key != SpecialKey::None { + let pressed = state == ElementState::Pressed; + let repeat = special_keys_pressed[key as usize] == pressed; + special_keys_pressed[key as usize] = pressed; + + unsafe { + if pressed { + ffi::App_onSpecialKeyDown(delegate.as_mut().unwrap(), &special_key, repeat); + } else { + ffi::App_onSpecialKeyUp(delegate.as_mut().unwrap(), &special_key); + } + } + } } Event::WindowEvent { .. } => {} Event::DeviceEvent { .. } => {} diff --git a/Runtime/CMain.cpp b/Runtime/CMain.cpp index 4c090dcb9..9b8df99e1 100644 --- a/Runtime/CMain.cpp +++ b/Runtime/CMain.cpp @@ -102,9 +102,7 @@ private: } while (count.QuadPart < end); } #else - void NanoSleep(const duration_t duration) { - std::this_thread::sleep_for(duration); - } + void NanoSleep(const duration_t duration) { std::this_thread::sleep_for(duration); } #endif }; @@ -155,21 +153,21 @@ private: boo::SWindowRect m_lastRect; bool m_rectDirty = false; bool m_windowInvalid = false; -// ImGuiWindowCallback m_imguiCallback; + // ImGuiWindowCallback m_imguiCallback; void resized(const boo::SWindowRect& rect, bool sync) override { m_lastRect = rect; m_rectDirty = true; -// m_imguiCallback.resized(rect, sync); + // m_imguiCallback.resized(rect, sync); } void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override { -// if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { -// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { -// as->mouseDown(coord, button, mods); -// } -// } -// m_imguiCallback.mouseDown(coord, button, mods); + // if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { + // if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + // as->mouseDown(coord, button, mods); + // } + // } + // m_imguiCallback.mouseDown(coord, button, mods); } void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override { @@ -178,38 +176,38 @@ private: as->mouseUp(coord, button, mods); } } -// m_imguiCallback.mouseUp(coord, button, mods); + // m_imguiCallback.mouseUp(coord, button, mods); } void mouseMove(const boo::SWindowCoord& coord) override { -// if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { -// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { -// as->mouseMove(coord); -// } -// } -// m_imguiCallback.mouseMove(coord); + // if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { + // if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + // as->mouseMove(coord); + // } + // } + // m_imguiCallback.mouseMove(coord); } -// void mouseEnter(const boo::SWindowCoord& coord) override { m_imguiCallback.mouseEnter(coord); } + // void mouseEnter(const boo::SWindowCoord& coord) override { m_imguiCallback.mouseEnter(coord); } -// void mouseLeave(const boo::SWindowCoord& coord) override { m_imguiCallback.mouseLeave(coord); } + // void mouseLeave(const boo::SWindowCoord& coord) override { m_imguiCallback.mouseLeave(coord); } void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) override { -// if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { -// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { -// as->scroll(coord, scroll); -// } -// } -// m_imguiCallback.scroll(coord, scroll); + // if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { + // if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + // as->scroll(coord, scroll); + // } + // } + // m_imguiCallback.scroll(coord, scroll); } void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat) override { -// if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { -// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { -// as->charKeyDown(charCode, mods, isRepeat); -// } -// } -// m_imguiCallback.charKeyDown(charCode, mods, isRepeat); + // if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { + // if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + // as->charKeyDown(charCode, mods, isRepeat); + // } + // } + // m_imguiCallback.charKeyDown(charCode, mods, isRepeat); } void charKeyUp(unsigned long charCode, boo::EModifierKey mods) override { @@ -218,32 +216,32 @@ private: as->charKeyUp(charCode, mods); } } -// m_imguiCallback.charKeyUp(charCode, mods); + // m_imguiCallback.charKeyUp(charCode, mods); } void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) override { -// if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { -// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { -// as->specialKeyDown(key, mods, isRepeat); -// } -// } -// if (True(mods & boo::EModifierKey::Alt)) { -// if (key == boo::ESpecialKey::Enter) { -// m_fullscreenToggleRequested = true; -// } else if (key == boo::ESpecialKey::F4) { -// m_windowInvalid = true; -// } -// } -// m_imguiCallback.specialKeyDown(key, mods, isRepeat); + // if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { + // if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + // as->specialKeyDown(key, mods, isRepeat); + // } + // } + // if (True(mods & boo::EModifierKey::Alt)) { + // if (key == boo::ESpecialKey::Enter) { + // m_fullscreenToggleRequested = true; + // } else if (key == boo::ESpecialKey::F4) { + // m_windowInvalid = true; + // } + // } + // m_imguiCallback.specialKeyDown(key, mods, isRepeat); } void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) override { -// if (g_mainMP1) { -// if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { -// as->specialKeyUp(key, mods); -// } -// } -// m_imguiCallback.specialKeyUp(key, mods); + // if (g_mainMP1) { + // if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + // as->specialKeyUp(key, mods); + // } + // } + // m_imguiCallback.specialKeyUp(key, mods); } void destroyed() override { m_windowInvalid = true; } @@ -445,14 +443,60 @@ public: g_mainMP1->Shutdown(); } g_mainMP1.reset(); -// m_renderTex.reset(); -// m_pipelineConv.reset(); + // m_renderTex.reset(); + // m_pipelineConv.reset(); m_cvarManager.serialize(); m_voiceEngine.reset(); m_amuseAllocWrapper.reset(); CDvdFile::Shutdown(); } + void onCharKeyDown(uint8_t code, bool is_repeat) noexcept override { + Log.report(logvisor::Info, FMT_STRING("DEBUG CHAR KEYS: '{}', is_repeat {}"), static_cast(code), is_repeat); + // if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->charKeyDown(code, boo::EModifierKey::None, is_repeat); + } + } + // } + } + + void onCharKeyUp(uint8_t code) noexcept override { + Log.report(logvisor::Info, FMT_STRING("DEBUG CHAR KEYS: '{}'"), static_cast(code)); + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->charKeyUp(code, boo::EModifierKey::None); + } + } + } + + void onSpecialKeyDown(const aurora::SpecialKey& key, bool is_repeat) noexcept override { + Log.report(logvisor::Info, FMT_STRING("DEBUG KEYS: SpecialKey {}, is_repeat {}"), key, is_repeat); + /* TODO: Temporarily convert the aurora enum to boo's until we refactor everything */ + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->specialKeyDown(boo::ESpecialKey(key), boo::EModifierKey::None, is_repeat); + } + } + // if (True(mods & boo::EModifierKey::Alt)) { + // if (key == boo::ESpecialKey::Enter) { + // m_fullscreenToggleRequested = true; + // } else if (key == boo::ESpecialKey::F4) { + // m_windowInvalid = true; + // } + // } + } + + void onSpecialKeyUp(const aurora::SpecialKey& key) noexcept override { + /* TODO: Temporarily convert the aurora enum to boo's until we refactor everything */ + if (g_mainMP1) { + if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { + as->specialKeyUp(boo::ESpecialKey(key), boo::EModifierKey::None); + } + } + } + [[nodiscard]] std::string getGraphicsApi() const { return m_cvarCommons.getGraphicsApi(); } [[nodiscard]] uint32_t getSamples() const { return m_cvarCommons.getSamples(); }