More input and rendering implementations

This commit is contained in:
Phillip Stephens 2022-02-13 13:32:52 -08:00
parent 7ee8f6e01d
commit 615204f71f
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
24 changed files with 863 additions and 245 deletions

1
Graphics/Cargo.lock generated
View File

@ -97,6 +97,7 @@ dependencies = [
"android_logger", "android_logger",
"bindgen", "bindgen",
"binrw", "binrw",
"bitflags",
"bytemuck", "bytemuck",
"bytemuck_derive", "bytemuck_derive",
"cgmath", "cgmath",

View File

@ -29,6 +29,7 @@ smallvec = "1.7.0"
scopeguard = "1.1.0" scopeguard = "1.1.0"
twox-hash = "1.6.2" twox-hash = "1.6.2"
winit = "0.26.1" winit = "0.26.1"
bitflags = "1.3.2"
# custom sdl2 # custom sdl2
sdl2 = { git = "https://github.com/encounter/rust-sdl2.git", rev = "f39d7a7549fd59bebb1fb42ec12973200bb3080b", features = ["no-link", "hidapi"] } sdl2 = { git = "https://github.com/encounter/rust-sdl2.git", rev = "f39d7a7549fd59bebb1fb42ec12973200bb3080b", features = ["no-link", "hidapi"] }

View File

@ -4,9 +4,59 @@
#include <cinttypes> #include <cinttypes>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#ifndef ENABLE_BITWISE_ENUM
#define ENABLE_BITWISE_ENUM(type) \
constexpr type operator|(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return type(static_cast<T>(a) | static_cast<T>(b)); \
} \
constexpr type operator&(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return type(static_cast<T>(a) & static_cast<T>(b)); \
} \
constexpr type& operator|=(type& a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
a = type(static_cast<T>(a) | static_cast<T>(b)); \
return a; \
} \
constexpr type& operator&=(type& a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
a = type(static_cast<T>(a) & static_cast<T>(b)); \
return a; \
} \
constexpr type operator~(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return type(~static_cast<T>(key)); \
} \
constexpr bool True(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) != 0; \
} \
constexpr bool False(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) == 0; \
}
#endif
namespace aurora { namespace aurora {
enum class SpecialKey : uint8_t; enum class SpecialKey : uint8_t;
enum class ModifierKey : uint16_t {
None = 0,
LeftShift = 1 << 0,
RightShift = 1 << 1,
LeftControl = 1 << 2,
RightControl = 1 << 3,
LeftAlt = 1 << 3,
RightAlt = 1 << 4,
LeftGui = 1 << 5,
RightGui = 1 << 6,
Num = 1 << 7,
Caps = 1 << 8,
Mode = 1 << 9,
// SDL has a reserved value we don't need
};
ENABLE_BITWISE_ENUM(ModifierKey);
enum class ControllerButton : uint8_t; enum class ControllerButton : uint8_t;
enum class ControllerAxis : uint8_t; enum class ControllerAxis : uint8_t;
@ -30,10 +80,10 @@ struct AppDelegate {
virtual void onAppExiting() noexcept = 0; virtual void onAppExiting() noexcept = 0;
// Input // Input
virtual void onCharKeyDown(uint8_t charCode, bool isRepeat) noexcept = 0; virtual void onCharKeyDown(uint8_t charCode, ModifierKey mods, bool isRepeat) noexcept = 0;
virtual void onCharKeyUp(uint8_t charCode) noexcept = 0; virtual void onCharKeyUp(uint8_t charCode, ModifierKey mods) noexcept = 0;
virtual void onSpecialKeyDown(SpecialKey key, bool isRepeat) noexcept = 0; virtual void onSpecialKeyDown(SpecialKey key, ModifierKey mods, bool isRepeat) noexcept = 0;
virtual void onSpecialKeyUp(SpecialKey key) noexcept = 0; virtual void onSpecialKeyUp(SpecialKey key, ModifierKey mods) noexcept = 0;
// Controller // Controller
virtual void onControllerAdded(uint32_t which) noexcept = 0; virtual void onControllerAdded(uint32_t which) noexcept = 0;
@ -41,27 +91,28 @@ struct AppDelegate {
virtual void onControllerButton(uint32_t which, ControllerButton button, bool pressed) noexcept = 0; virtual void onControllerButton(uint32_t which, ControllerButton button, bool pressed) noexcept = 0;
virtual void onControllerAxis(uint32_t which, ControllerAxis axis, int16_t value) noexcept = 0; virtual void onControllerAxis(uint32_t which, ControllerAxis axis, int16_t value) noexcept = 0;
// virtual void resized([[maybe_unused]] const WindowSize& rect, [[maybe_unused]] bool sync) noexcept {} // 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, // virtual void mouseDown([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button,
// [[maybe_unused]] EModifierKey mods) noexcept {} // [[maybe_unused]] EModifierKey mods) noexcept {}
// virtual void mouseUp([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button, // virtual void mouseUp([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button,
// [[maybe_unused]] EModifierKey mods) noexcept {} // [[maybe_unused]] EModifierKey mods) noexcept {}
// virtual void mouseMove([[maybe_unused]] const SWindowCoord& coord) noexcept {} // virtual void mouseMove([[maybe_unused]] const SWindowCoord& coord) noexcept {}
// virtual void mouseEnter([[maybe_unused]] const SWindowCoord& coord) noexcept {} // virtual void mouseEnter([[maybe_unused]] const SWindowCoord& coord) noexcept {}
// virtual void mouseLeave([[maybe_unused]] const SWindowCoord& coord) noexcept {} // virtual void mouseLeave([[maybe_unused]] const SWindowCoord& coord) noexcept {}
// virtual void scroll([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] const SScrollDelta& scroll) noexcept {} // virtual void scroll([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] const SScrollDelta& scroll)
// // noexcept {}
// virtual void touchDown([[maybe_unused]] const STouchCoord& coord, [[maybe_unused]] uintptr_t tid) noexcept {} //
// virtual void touchUp([[maybe_unused]] const STouchCoord& coord, [[maybe_unused]] uintptr_t tid) noexcept {} // virtual void touchDown([[maybe_unused]] const STouchCoord& coord, [[maybe_unused]] uintptr_t tid) noexcept {}
// virtual void touchMove([[maybe_unused]] const STouchCoord& coord, [[maybe_unused]] uintptr_t tid) noexcept {} // virtual void touchUp([[maybe_unused]] const STouchCoord& coord, [[maybe_unused]] uintptr_t tid) noexcept {}
// // virtual void touchMove([[maybe_unused]] const STouchCoord& coord, [[maybe_unused]] uintptr_t tid) noexcept {}
// virtual void charKeyDown([[maybe_unused]] unsigned long charCode, [[maybe_unused]] EModifierKey mods, //
// [[maybe_unused]] bool isRepeat) noexcept {} // virtual void charKeyDown([[maybe_unused]] unsigned long charCode, [[maybe_unused]] EModifierKey mods,
// virtual void charKeyUp([[maybe_unused]] unsigned long charCode, [[maybe_unused]] EModifierKey mods) noexcept {} // [[maybe_unused]] bool isRepeat) noexcept {}
// virtual void specialKeyDown([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods, // virtual void charKeyUp([[maybe_unused]] unsigned long charCode, [[maybe_unused]] EModifierKey mods) noexcept {}
// [[maybe_unused]] bool isRepeat) noexcept {} // virtual void specialKeyDown([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods,
// virtual void specialKeyUp([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods) noexcept {} // [[maybe_unused]] bool isRepeat) noexcept {}
// virtual void modKeyDown([[maybe_unused]] EModifierKey mod, [[maybe_unused]] bool isRepeat) noexcept {} // virtual void specialKeyUp([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods) noexcept {}
// virtual void modKeyUp([[maybe_unused]] EModifierKey mod) noexcept {} // virtual void modKeyDown([[maybe_unused]] EModifierKey mod, [[maybe_unused]] bool isRepeat) noexcept {}
// virtual void modKeyUp([[maybe_unused]] EModifierKey mod) noexcept {}
}; };
} // namespace aurora } // namespace aurora

View File

@ -10,10 +10,10 @@ void App_onAppWindowResized(AppDelegate& cb, const WindowSize& size) noexcept;
void App_onAppWindowMoved(AppDelegate& cb, int32_t x, int32_t y) noexcept; void App_onAppWindowMoved(AppDelegate& cb, int32_t x, int32_t y) noexcept;
void App_onAppExiting(AppDelegate& cb) noexcept; void App_onAppExiting(AppDelegate& cb) noexcept;
// Input // Input
void App_onCharKeyDown(AppDelegate& cb, uint8_t code, bool isRepeat) noexcept; void App_onCharKeyDown(AppDelegate& cb, uint8_t code, std::uint16_t mods, bool isRepeat) noexcept;
void App_onCharKeyUp(AppDelegate& cb, uint8_t code) noexcept; void App_onCharKeyUp(AppDelegate& cb, uint8_t code, std::uint16_t mods) noexcept;
void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, bool isRepeat) noexcept; void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, std::uint16_t mods, bool isRepeat) noexcept;
void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key) noexcept; void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key, std::uint16_t mods) noexcept;
// Controller // Controller
void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept; void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept;
void App_onControllerRemoved(AppDelegate& cb, uint32_t which) noexcept; void App_onControllerRemoved(AppDelegate& cb, uint32_t which) noexcept;

View File

@ -5,35 +5,27 @@ void App_onAppLaunched(AppDelegate& cb) noexcept { return cb.onAppLaunched(); }
bool App_onAppIdle(AppDelegate& cb, float dt) noexcept { return cb.onAppIdle(dt); } bool App_onAppIdle(AppDelegate& cb, float dt) noexcept { return cb.onAppIdle(dt); }
void App_onAppDraw(AppDelegate& cb) noexcept { cb.onAppDraw(); } void App_onAppDraw(AppDelegate& cb) noexcept { cb.onAppDraw(); }
void App_onAppPostDraw(AppDelegate& cb) noexcept { cb.onAppPostDraw(); } void App_onAppPostDraw(AppDelegate& cb) noexcept { cb.onAppPostDraw(); }
void App_onAppWindowResized(AppDelegate& cb, const WindowSize& size) noexcept { void App_onAppWindowResized(AppDelegate& cb, const WindowSize& size) noexcept { cb.onAppWindowResized(size); }
cb.onAppWindowResized(size); void App_onAppWindowMoved(AppDelegate& cb, int32_t x, int32_t y) noexcept { cb.onAppWindowMoved(x, y); }
}
void App_onAppWindowMoved(AppDelegate& cb, int32_t x, int32_t y) noexcept {
cb.onAppWindowMoved(x, y);
}
void App_onAppExiting(AppDelegate& cb) noexcept { cb.onAppExiting(); } void App_onAppExiting(AppDelegate& cb) noexcept { cb.onAppExiting(); }
// Input // Input
void App_onCharKeyDown(AppDelegate& cb, uint8_t code, bool isRepeat) noexcept { void App_onCharKeyDown(AppDelegate& cb, uint8_t code, std::uint16_t mods, bool isRepeat) noexcept {
cb.onCharKeyDown(code, isRepeat); cb.onCharKeyDown(code, static_cast<ModifierKey>(mods), isRepeat);
} }
void App_onCharKeyUp(AppDelegate& cb, uint8_t code) noexcept { void App_onCharKeyUp(AppDelegate& cb, uint8_t code, std::uint16_t mods) noexcept {
cb.onCharKeyUp(code); cb.onCharKeyUp(code, static_cast<ModifierKey>(mods));
} }
void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, bool isRepeat) noexcept { void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, std::uint16_t mods, bool isRepeat) noexcept {
cb.onSpecialKeyDown(key, isRepeat); cb.onSpecialKeyDown(key, static_cast<ModifierKey>(mods), isRepeat);
} }
void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key) noexcept { void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key, std::uint16_t mods) noexcept {
cb.onSpecialKeyUp(key); cb.onSpecialKeyUp(key, static_cast<ModifierKey>(mods));
} }
// Controller // Controller
void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept { void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept { cb.onControllerAdded(which); }
cb.onControllerAdded(which); void App_onControllerRemoved(AppDelegate& cb, uint32_t which) noexcept { cb.onControllerRemoved(which); }
}
void App_onControllerRemoved(AppDelegate& cb, uint32_t which) noexcept {
cb.onControllerRemoved(which);
}
void App_onControllerButton(AppDelegate& cb, uint32_t which, ControllerButton button, bool pressed) noexcept { void App_onControllerButton(AppDelegate& cb, uint32_t which, ControllerButton button, bool pressed) noexcept {
cb.onControllerButton(which, button, pressed); cb.onControllerButton(which, button, pressed);
} }

View File

@ -1,15 +1,15 @@
use sdl2::controller::{Axis, Button}; use sdl2::controller::{Axis, Button};
use crate::{ use crate::{
app_run, get_args, get_backend, get_backend_string, get_dxt_compression_supported, App, app_run, get_args, get_backend, get_backend_string,
get_dxt_compression_supported,
get_window_size, get_window_size,
sdl::{ sdl::{
get_controller_name,
get_controller_player_index, get_controller_player_index,
set_controller_player_index,
is_controller_gamecube, is_controller_gamecube,
get_controller_name set_controller_player_index,
}, }, set_fullscreen, set_window_title, WindowContext,
set_fullscreen, set_window_title, App, WindowContext,
}; };
#[cxx::bridge(namespace = "aurora")] #[cxx::bridge(namespace = "aurora")]
@ -29,14 +29,27 @@ pub(crate) mod ffi {
pub(crate) fn App_onAppWindowMoved(cb: Pin<&mut AppDelegate>, x: i32, y: i32); pub(crate) fn App_onAppWindowMoved(cb: Pin<&mut AppDelegate>, x: i32, y: i32);
pub(crate) fn App_onAppExiting(cb: Pin<&mut AppDelegate>); pub(crate) fn App_onAppExiting(cb: Pin<&mut AppDelegate>);
// Input // Input
pub(crate) fn App_onCharKeyDown(cb: Pin<&mut AppDelegate>, code: u8, is_repeat: bool); pub(crate) fn App_onCharKeyDown(cb: Pin<&mut AppDelegate>,
pub(crate) fn App_onCharKeyUp(cb: Pin<&mut AppDelegate>, code: u8); code: u8,
mods: u16,
is_repeat: bool,
);
pub(crate) fn App_onCharKeyUp(
cb: Pin<&mut AppDelegate>,
code: u8,
mods: u16,
);
pub(crate) fn App_onSpecialKeyDown( pub(crate) fn App_onSpecialKeyDown(
cb: Pin<&mut AppDelegate>, cb: Pin<&mut AppDelegate>,
key: SpecialKey, key: SpecialKey,
keymod: u16,
is_repeat: bool, is_repeat: bool,
); );
pub(crate) fn App_onSpecialKeyUp(cb: Pin<&mut AppDelegate>, key: SpecialKey); pub(crate) fn App_onSpecialKeyUp(
cb: Pin<&mut AppDelegate>,
key: SpecialKey,
mods: u16,
);
// Controller // Controller
pub(crate) fn App_onControllerAdded(cb: Pin<&mut AppDelegate>, which: u32); pub(crate) fn App_onControllerAdded(cb: Pin<&mut AppDelegate>, which: u32);
pub(crate) fn App_onControllerRemoved(cb: Pin<&mut AppDelegate>, which: u32); pub(crate) fn App_onControllerRemoved(cb: Pin<&mut AppDelegate>, which: u32);
@ -100,26 +113,70 @@ pub(crate) mod ffi {
F10 = 10, F10 = 10,
F11 = 11, F11 = 11,
F12 = 12, F12 = 12,
Esc = 13, F13 = 13,
Enter = 14, F14 = 14,
Backspace = 15, F15 = 15,
Insert = 16, F16 = 16,
Delete = 17, F17 = 17,
Home = 18, F18 = 18,
End = 19, F19 = 19,
PgUp = 20, F20 = 20,
PgDown = 21, F21 = 21,
Left = 22, F22 = 22,
Right = 23, F23 = 23,
Up = 24, F24 = 24,
Down = 25, Esc = 25,
Tab = 26, Enter = 26,
} Backspace = 27,
Insert = 28,
pub struct KeyboardInput { Delete = 29,
pub scancode: u32, Home = 30,
pub state: ElementState, End = 31,
// pub PgUp = 32,
PgDown = 33,
Left = 34,
Right = 35,
Up = 36,
Down = 37,
Tab = 38,
PrintScreen = 39,
ScrollLock = 40,
Pause = 41,
NumLockClear = 42,
KpDivide = 43,
KpMultiply = 44,
KpMinus = 45,
KpPlus = 46,
KpEnter = 47,
KpNum0 = 48,
KpNum1 = 49,
KpNum2 = 51,
KpNum3 = 52,
KpNum4 = 53,
KpNum5 = 54,
KpNum6 = 55,
KpNum7 = 56,
KpNum8 = 57,
KpNum9 = 58,
KpPercent = 59,
KpPeriod = 60,
KpComma = 61,
KpEquals = 62,
Application = 63,
Power = 64,
Execute = 65,
Help = 66,
Menu = 67,
Select = 68,
Stop = 69,
Again = 70,
Undo = 71,
Cut = 72,
Paste = 73,
Find = 74,
VolumeUp = 75,
VolumeDown = 76,
MAX,
} }
pub enum ControllerButton { pub enum ControllerButton {

View File

@ -2,6 +2,7 @@
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
#![allow(non_upper_case_globals)]
use std::time::Instant; use std::time::Instant;
@ -58,7 +59,6 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>, icon: ffi::Icon) {
let sdl = initialize_sdl(); let sdl = initialize_sdl();
let gpu = initialize_gpu(&window); let gpu = initialize_gpu(&window);
let imgui = initialize_imgui(&window, &gpu); let imgui = initialize_imgui(&window, &gpu);
let mut special_keys_pressed: [bool; 512] = [false; 512];
shaders::construct_state(gpu.device.clone(), gpu.queue.clone(), &gpu.config); shaders::construct_state(gpu.device.clone(), gpu.queue.clone(), &gpu.config);
let app = let app =
App { window: ffi::Window { inner: Box::new(WindowContext { window }) }, gpu, imgui, sdl }; App { window: ffi::Window { inner: Box::new(WindowContext { window }) }, gpu, imgui, sdl };
@ -119,65 +119,6 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>, icon: ffi::Icon) {
Event::WindowEvent { event: WindowEvent::Moved(loc), .. } => unsafe { Event::WindowEvent { event: WindowEvent::Moved(loc), .. } => unsafe {
ffi::App_onAppWindowMoved(delegate.as_mut().unwrap_unchecked(), loc.x, loc.y); ffi::App_onAppWindowMoved(delegate.as_mut().unwrap_unchecked(), loc.x, loc.y);
}, },
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 => ffi::SpecialKey::F1,
VirtualKeyCode::F2 => ffi::SpecialKey::F2,
VirtualKeyCode::F3 => ffi::SpecialKey::F3,
VirtualKeyCode::F4 => ffi::SpecialKey::F4,
VirtualKeyCode::F5 => ffi::SpecialKey::F5,
VirtualKeyCode::F6 => ffi::SpecialKey::F6,
VirtualKeyCode::F7 => ffi::SpecialKey::F7,
VirtualKeyCode::F8 => ffi::SpecialKey::F8,
VirtualKeyCode::F9 => ffi::SpecialKey::F9,
VirtualKeyCode::F10 => ffi::SpecialKey::F10,
VirtualKeyCode::F11 => ffi::SpecialKey::F11,
VirtualKeyCode::F12 => ffi::SpecialKey::F12,
VirtualKeyCode::Escape => ffi::SpecialKey::Esc,
VirtualKeyCode::Return => ffi::SpecialKey::Enter,
VirtualKeyCode::Back => ffi::SpecialKey::Backspace,
VirtualKeyCode::Insert => ffi::SpecialKey::Insert,
VirtualKeyCode::Delete => ffi::SpecialKey::Delete,
VirtualKeyCode::Home => ffi::SpecialKey::Home,
VirtualKeyCode::PageUp => ffi::SpecialKey::PgUp,
VirtualKeyCode::PageDown => ffi::SpecialKey::PgDown,
VirtualKeyCode::Left => ffi::SpecialKey::Left,
VirtualKeyCode::Right => ffi::SpecialKey::Right,
VirtualKeyCode::Up => ffi::SpecialKey::Up,
VirtualKeyCode::Down => ffi::SpecialKey::Down,
VirtualKeyCode::Tab => ffi::SpecialKey::Tab,
_ => ffi::SpecialKey::None,
};
if special_key != ffi::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_unchecked(),
special_key,
repeat,
);
} else {
ffi::App_onSpecialKeyUp(
delegate.as_mut().unwrap_unchecked(),
special_key,
);
}
}
}
}
Event::MainEventsCleared => { Event::MainEventsCleared => {
log::trace!("Requesting redraw"); log::trace!("Requesting redraw");
window_ctx.window.request_redraw(); window_ctx.window.request_redraw();

View File

@ -1,12 +1,13 @@
use std::collections::{BTreeMap, HashMap}; use bitflags::bitflags;
use sdl2::{ use sdl2::{
controller::{Axis, GameController}, controller::{Axis, GameController},
event::Event, event::Event,
GameControllerSubsystem, Sdl, GameControllerSubsystem, Sdl,
}; };
use sdl2::keyboard::{Keycode, Mod};
use crate::{cxxbridge::ffi, get_app}; use crate::{cxxbridge::ffi, get_app};
use crate::ffi::SpecialKey;
pub(crate) struct SdlState { pub(crate) struct SdlState {
context: Sdl, context: Sdl,
@ -21,6 +22,126 @@ pub(crate) fn initialize_sdl() -> SdlState {
let controller_sys = context.game_controller().unwrap(); let controller_sys = context.game_controller().unwrap();
SdlState { context, events, controller_sys, open_controllers: Default::default() } SdlState { context, events, controller_sys, open_controllers: Default::default() }
} }
bitflags! {
pub struct ModifierKey : u16 {
const None = 0;
const LeftShift = 0x0001;
const RightShift = 0x0002;
const LeftControl = 0x0004;
const RightControl = 0x0008;
const LeftAlt = 0x0010;
const RightAlt = 0x0020;
const LeftGui = 0x0040;
const RightGui = 0x0080;
const Num = 0x0100;
const Caps = 0x0200;
const Mode = 0x0400;
// SDL has a reserved value we don't need
}
}
fn translate_modifiers(keymod: Mod) -> ModifierKey {
let mut use_mod: ModifierKey = ModifierKey::None;
if keymod.contains(Mod::LSHIFTMOD) {
use_mod.insert(ModifierKey::LeftShift);
}
if keymod.contains(Mod::RSHIFTMOD) {
use_mod.insert(ModifierKey::RightShift);
}
if keymod.contains(Mod::LCTRLMOD) {
use_mod.insert(ModifierKey::LeftControl);
}
if keymod.contains(Mod::RCTRLMOD) {
use_mod.insert(ModifierKey::RightControl);
}
if keymod.contains(Mod::LALTMOD) {
use_mod.insert(ModifierKey::LeftAlt);
}
if keymod.contains(Mod::RALTMOD) {
use_mod.insert(ModifierKey::RightAlt);
}
if keymod.contains(Mod::LGUIMOD) {
use_mod.insert(ModifierKey::LeftGui);
}
if keymod.contains(Mod::RGUIMOD) {
use_mod.insert(ModifierKey::RightGui);
}
if keymod.contains(Mod::NUMMOD) {
use_mod.insert(ModifierKey::Num);
}
if keymod.contains(Mod::CAPSMOD) {
use_mod.insert(ModifierKey::Caps);
}
if keymod.contains(Mod::MODEMOD) {
use_mod.insert(ModifierKey::Mode);
}
use_mod as ModifierKey
}
fn translate_special_key(keycode: Keycode) -> ffi::SpecialKey {
match keycode {
Keycode::F1 => ffi::SpecialKey::F1,
Keycode::F2 => ffi::SpecialKey::F2,
Keycode::F3 => ffi::SpecialKey::F3,
Keycode::F4 => ffi::SpecialKey::F4,
Keycode::F5 => ffi::SpecialKey::F5,
Keycode::F6 => ffi::SpecialKey::F6,
Keycode::F7 => ffi::SpecialKey::F7,
Keycode::F8 => ffi::SpecialKey::F8,
Keycode::F9 => ffi::SpecialKey::F9,
Keycode::F10 => ffi::SpecialKey::F10,
Keycode::F11 => ffi::SpecialKey::F11,
Keycode::F12 => ffi::SpecialKey::F12,
Keycode::F13 => ffi::SpecialKey::F13,
Keycode::F14 => ffi::SpecialKey::F14,
Keycode::F15 => ffi::SpecialKey::F15,
Keycode::F16 => ffi::SpecialKey::F16,
Keycode::F17 => ffi::SpecialKey::F17,
Keycode::F18 => ffi::SpecialKey::F18,
Keycode::F19 => ffi::SpecialKey::F19,
Keycode::F20 => ffi::SpecialKey::F20,
Keycode::F21 => ffi::SpecialKey::F21,
Keycode::F22 => ffi::SpecialKey::F22,
Keycode::F23 => ffi::SpecialKey::F23,
Keycode::F24 => ffi::SpecialKey::F23,
Keycode::Escape => ffi::SpecialKey::Esc,
Keycode::Return => ffi::SpecialKey::Enter,
Keycode::Backspace => ffi::SpecialKey::Backspace,
Keycode::Insert => ffi::SpecialKey::Insert,
Keycode::Delete => ffi::SpecialKey::Delete,
Keycode::Home => ffi::SpecialKey::Home,
Keycode::End => ffi::SpecialKey::End,
Keycode::PageUp => ffi::SpecialKey::PgUp,
Keycode::PageDown => ffi::SpecialKey::PgDown,
Keycode::Left => ffi::SpecialKey::Left,
Keycode::Right => ffi::SpecialKey::Right,
Keycode::Up => ffi::SpecialKey::Up,
Keycode::Down => ffi::SpecialKey::Down,
Keycode::Tab => ffi::SpecialKey::Tab,
Keycode::PrintScreen => ffi::SpecialKey::PrintScreen,
Keycode::ScrollLock => ffi::SpecialKey::ScrollLock,
Keycode::Pause => ffi::SpecialKey::Pause,
Keycode::NumLockClear => ffi::SpecialKey::NumLockClear,
Keycode::KpDivide => ffi::SpecialKey::KpDivide,
Keycode::KpMultiply => ffi::SpecialKey::KpMultiply,
Keycode::KpMinus => ffi::SpecialKey::KpMinus,
Keycode::KpPlus => ffi::SpecialKey::KpPlus,
Keycode::KpEquals => ffi::SpecialKey::KpEquals,
Keycode::Kp0 => ffi::SpecialKey::KpNum0,
Keycode::Kp1 => ffi::SpecialKey::KpNum1,
Keycode::Kp2 => ffi::SpecialKey::KpNum2,
Keycode::Kp3 => ffi::SpecialKey::KpNum3,
Keycode::Kp4 => ffi::SpecialKey::KpNum4,
Keycode::Kp5 => ffi::SpecialKey::KpNum5,
Keycode::Kp6 => ffi::SpecialKey::KpNum6,
Keycode::Kp7 => ffi::SpecialKey::KpNum7,
Keycode::Kp8 => ffi::SpecialKey::KpNum8,
Keycode::Kp9 => ffi::SpecialKey::KpNum9,
Keycode::KpPeriod => ffi::SpecialKey::KpPeriod,
_ => ffi::SpecialKey::None,
}
}
pub(crate) fn poll_sdl_events( pub(crate) fn poll_sdl_events(
state: &mut SdlState, state: &mut SdlState,
@ -75,6 +196,48 @@ pub(crate) fn poll_sdl_events(
value, value,
); );
}, },
Event::KeyDown { keycode, keymod, repeat, .. } => {
let special_key = translate_special_key(keycode.unwrap());
let use_mod = translate_modifiers(keymod);
if special_key != ffi::SpecialKey::None {
unsafe {
ffi::App_onSpecialKeyDown(delegate.as_mut().unwrap_unchecked(),
special_key,
use_mod.bits,
repeat);
}
} else {
let tmp = keycode.unwrap() as u8;
if tmp >= '\x20' as u8 && tmp <= 'z' as u8 {
unsafe {
ffi::App_onCharKeyDown(delegate.as_mut().unwrap_unchecked(),
tmp,
use_mod.bits,
repeat);
}
}
}
},
Event::KeyUp { keycode, keymod, .. } => {
let special_key = translate_special_key(keycode.unwrap());
let use_mod = translate_modifiers(keymod);
if special_key != ffi::SpecialKey::None {
unsafe {
ffi::App_onSpecialKeyUp(delegate.as_mut().unwrap_unchecked(),
special_key,
use_mod.bits);
}
} else {
let tmp = keycode.unwrap() as u8;
if tmp >= '\x20' as u8 && tmp <= 'z' as u8 {
unsafe {
ffi::App_onCharKeyUp(delegate.as_mut().unwrap_unchecked(),
tmp,
use_mod.bits);
}
}
}
},
// SDL overrides exit signals // SDL overrides exit signals
Event::Quit { .. } => { Event::Quit { .. } => {
return false; return false;
@ -142,7 +305,6 @@ pub(crate) fn is_controller_gamecube(which: u32) -> bool {
.map_or(false, |c| c.name() .map_or(false, |c| c.name()
.to_lowercase() .to_lowercase()
.eq("nintendo gamecube controller")) .eq("nintendo gamecube controller"))
} }
pub(crate) fn get_controller_name(which: u32) -> String { pub(crate) fn get_controller_name(which: u32) -> String {

View File

@ -0,0 +1,319 @@
use std::{collections::HashMap, hash::Hash, ops::Range};
use bytemuck_derive::{Pod, Zeroable};
use wgpu::{include_wgsl, vertex_attr_array};
use crate::{
get_app,
gpu::GraphicsConfig,
shaders::{
bind_pipeline, cxxbridge::ffi, get_combined_matrix, pipeline_ref, push_draw_command,
push_uniform, push_verts, texture::create_sampler, BuiltBuffers, PipelineCreateCommand,
PipelineHolder, PipelineRef, ShaderDrawCommand, STATE,
},
util::{align, Vec2, Vec3},
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, CVector4f},
};
#[derive(Debug, Clone)]
pub(crate) struct DrawData {
pipeline: PipelineRef,
vert_range: Range<u64>,
uniform_range: Range<u64>,
}
#[derive(Hash)]
pub(crate) struct PipelineConfig {
filter_type: ffi::CameraFilterType,
z_comparison: ffi::ZTest,
z_test: bool,
}
pub(crate) const INITIAL_PIPELINES: &[PipelineCreateCommand] = &[
// PipelineCreateCommand::ColoredQuad(PipelineConfig { z_only: false }),
// PipelineCreateCommand::ColoredQuad(PipelineConfig { z_only: true }),
];
pub(crate) struct State {
shader: wgpu::ShaderModule,
uniform_layout: wgpu::BindGroupLayout,
uniform_bind_group: wgpu::BindGroup,
sampler: wgpu::Sampler,
pipeline_layout: wgpu::PipelineLayout,
}
pub(crate) fn construct_state(
device: &wgpu::Device,
_queue: &wgpu::Queue,
buffers: &BuiltBuffers,
graphics_config: &GraphicsConfig,
) -> State {
let shader = device.create_shader_module(&include_wgsl!("shader.wgsl"));
let uniform_alignment = device.limits().min_uniform_buffer_offset_alignment;
let uniform_size = wgpu::BufferSize::new(align(
std::mem::size_of::<Uniform>() as u64,
uniform_alignment as u64,
));
let uniform_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Colored Quad Uniform Bind Group Layout"),
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: true,
min_binding_size: uniform_size,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
],
});
let sampler = create_sampler(device, wgpu::AddressMode::Repeat, None);
let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Colored Quad Uniform Bind Group"),
layout: &uniform_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
buffer: &buffers.uniform_buffer,
offset: 0, // dynamic
size: uniform_size,
}),
},
wgpu::BindGroupEntry { binding: 1, resource: wgpu::BindingResource::Sampler(&sampler) },
],
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Colored Quad Pipeline Layout"),
bind_group_layouts: &[&uniform_layout],
push_constant_ranges: &[],
});
State {
shader,
uniform_layout,
uniform_bind_group,
sampler,
pipeline_layout,
}
}
pub(crate) fn construct_pipeline(
device: &wgpu::Device,
graphics: &GraphicsConfig,
state: &State,
config: &PipelineConfig,
) -> PipelineHolder {
let (blend_component, alpha_write) = match config.filter_type {
ffi::CameraFilterType::Multiply => (
wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::Zero,
dst_factor: wgpu::BlendFactor::Src,
operation: wgpu::BlendOperation::Add,
},
true,
),
ffi::CameraFilterType::Add => (
wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Add,
},
false,
),
ffi::CameraFilterType::Subtract => (
wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Subtract,
},
false,
),
ffi::CameraFilterType::Blend => (
wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
operation: wgpu::BlendOperation::Add,
},
false,
),
ffi::CameraFilterType::InvDstMultiply => (
wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::Zero,
dst_factor: wgpu::BlendFactor::OneMinusSrc,
operation: wgpu::BlendOperation::Add,
},
true,
),
_ => todo!(),
};
PipelineHolder {
pipeline: device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Colored Quad Pipeline"),
layout: Some(&state.pipeline_layout),
vertex: wgpu::VertexState {
module: &state.shader,
entry_point: "vs_main",
buffers: &[wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Vert>() as u64,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &vertex_attr_array![0 => Float32x3],
}],
},
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleStrip,
..Default::default()
},
depth_stencil: Some(wgpu::DepthStencilState {
format: graphics.depth_format,
depth_write_enabled: config.z_test,
depth_compare: match config.z_comparison {
ffi::ZTest::Never => wgpu::CompareFunction::Never,
ffi::ZTest::Less => wgpu::CompareFunction::Less,
ffi::ZTest::Equal => wgpu::CompareFunction::Equal,
ffi::ZTest::LEqual => wgpu::CompareFunction::LessEqual,
ffi::ZTest::Greater => wgpu::CompareFunction::Greater,
ffi::ZTest::NEqual => wgpu::CompareFunction::NotEqual,
ffi::ZTest::GEqual => wgpu::CompareFunction::GreaterEqual,
ffi::ZTest::Always => wgpu::CompareFunction::Always,
_ => todo!(),
},
stencil: Default::default(),
bias: Default::default(),
}),
multisample: wgpu::MultisampleState {
count: graphics.msaa_samples,
..Default::default()
},
fragment: Some(wgpu::FragmentState {
module: &state.shader,
entry_point: "fs_main",
targets: &[wgpu::ColorTargetState {
format: graphics.color_format,
blend: Some(wgpu::BlendState {
color: blend_component,
alpha: blend_component,
}),
write_mask: if alpha_write {
wgpu::ColorWrites::ALL
} else {
wgpu::ColorWrites::COLOR
},
}],
}),
multiview: None,
}),
}
}
#[derive(Pod, Zeroable, Copy, Clone, Default, Debug)]
#[repr(C)]
struct Uniform {
xf: CMatrix4f,
color: CColor,
}
#[derive(Pod, Zeroable, Copy, Clone, Default, Debug)]
#[repr(C)]
struct Vert {
pos: Vec3<f32>,
//norm: Vec3<f32>,
}
pub(crate) fn queue_colored_quad(
filter_type: ffi::CameraFilterType,
z_comparison: ffi::ZTest,
z_test: bool,
color: CColor,
rect: CRectangle,
z: f32,
) {
let pipeline = pipeline_ref(&PipelineCreateCommand::ColoredQuad(PipelineConfig {
filter_type,
z_comparison,
z_test,
}));
let vert_range = push_verts(&[
Vert { pos: Vec3::new(0.0, 0.0, z) },
Vert { pos: Vec3::new(0.0, 1.0, z) },
Vert { pos: Vec3::new(1.0, 0.0, z) },
Vert { pos: Vec3::new(1.0, 1.0, z) },
]);
let uniform_range = push_uniform(&Uniform {
xf: CMatrix4f::new(
CVector4f::new(rect.size.x * 2.0, 0.0, 0.0, 0.0),
CVector4f::new(0.0, rect.size.y * 2.0, 0.0, 0.0),
CVector4f::new(0.0, 0.0, 1.0, 0.0),
CVector4f::new(rect.position.x * 2.0 - 1.0, rect.position.y * 2.0 - 1.0, 0.0, 1.0),
),
color,
});
push_colored_quad(pipeline, vert_range, uniform_range);
}
pub(crate) fn queue_colored_quad_verts(
filter_type: ffi::CameraFilterType,
z_comparison: ffi::ZTest,
z_test: bool,
color: CColor,
pos: &[CVector3f],
) {
if pos.len() != 4 {
panic!("Invalid pos: {}", pos.len());
}
let pipeline = pipeline_ref(&PipelineCreateCommand::ColoredQuad(PipelineConfig {
filter_type,
z_comparison,
z_test,
}));
let vert_range = push_verts(
&pos.iter().map(|pos| Vert { pos: pos.into() })
.collect::<Vec<Vert>>(),
);
let uniform_range = push_uniform(&Uniform { xf: get_combined_matrix(), color});
push_colored_quad(pipeline, vert_range, uniform_range);
}
fn push_colored_quad(
pipeline: PipelineRef,
vert_range: Range<u64>,
uniform_range: Range<u64>,
) {
// TODO defer bind group creation to draw time or another thread?
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
push_draw_command(ShaderDrawCommand::ColoredQuad(DrawData {
pipeline,
vert_range,
uniform_range,
}));
}
pub(crate) fn draw_colored_quad<'a>(
data: &DrawData,
state: &'a State,
pass: &mut wgpu::RenderPass<'a>,
buffers: &'a BuiltBuffers,
) {
if !bind_pipeline(data.pipeline, pass) {
return;
}
// Uniform bind group
pass.set_bind_group(0, &state.uniform_bind_group, &[
data.uniform_range.start as wgpu::DynamicOffset
]);
// Vertex buffer
pass.set_vertex_buffer(0, buffers.vertex_buffer.slice(data.vert_range.clone()));
pass.draw(0..4, 0..1);
}

View File

@ -0,0 +1,24 @@
struct Uniform {
xf: mat4x4<f32>;
color: vec4<f32>;
};
@group(0) @binding(0)
var<uniform> ubuf: Uniform;
struct VertexOutput {
@builtin(position) pos: vec4<f32>;
//@builtin(normal) norm: vec4<f32>;
};
@stage(vertex)
fn vs_main(@location(0) in_pos: vec3<f32>) -> VertexOutput {//, @location(1) in_norm: vec3<f32>) -> VertexOutput {
var out: VertexOutput;
out.pos = ubuf.xf * vec4<f32>(in_pos, 1.0);
//out.norm = in_norm;
return out;
}
@stage(fragment)
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return ubuf.color;
}

View File

@ -10,6 +10,7 @@ use crate::shaders::{
write_texture, write_texture,
}, },
textured_quad::{queue_textured_quad, queue_textured_quad_verts}, textured_quad::{queue_textured_quad, queue_textured_quad_verts},
colored_quad::{queue_colored_quad, queue_colored_quad_verts},
update_fog_state, update_model_view, update_projection, update_fog_state, update_model_view, update_projection,
}; };
@ -190,6 +191,21 @@ pub(crate) mod ffi {
rect: CRectangle, rect: CRectangle,
z: f32, z: f32,
); );
fn queue_colored_quad_verts(
filter_type: CameraFilterType,
z_comparison: ZTest,
z_test: bool,
color: CColor,
pos: &[CVector3f],
);
fn queue_colored_quad(
filter_type: CameraFilterType,
z_comparison: ZTest,
z_test: bool,
color: CColor,
rect: CRectangle,
z: f32,
);
fn queue_movie_player( fn queue_movie_player(
tex_y: TextureRef, tex_y: TextureRef,
tex_u: TextureRef, tex_u: TextureRef,

View File

@ -25,6 +25,7 @@ mod model;
mod movie_player; mod movie_player;
mod texture; mod texture;
mod textured_quad; mod textured_quad;
mod colored_quad;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
enum ColoredStripMode { enum ColoredStripMode {
@ -33,6 +34,7 @@ enum ColoredStripMode {
FullAdditive, FullAdditive,
Subtractive, Subtractive,
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct ColoredStripVert { struct ColoredStripVert {
position: CVector3f, position: CVector3f,
@ -46,6 +48,7 @@ enum Command {
SetScissor(u32, u32, u32, u32), SetScissor(u32, u32, u32, u32),
Draw(ShaderDrawCommand), Draw(ShaderDrawCommand),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum ShaderDrawCommand { enum ShaderDrawCommand {
Aabb(aabb::DrawData), Aabb(aabb::DrawData),
@ -53,21 +56,17 @@ enum ShaderDrawCommand {
amount: f32, amount: f32,
clear_depth: bool, clear_depth: bool,
}, },
ColoredQuadFilter { ColoredQuad(colored_quad::DrawData),
filter_type: ffi::CameraFilterType,
color: CColor,
rect: CRectangle,
},
ColoredStripFilter { ColoredStripFilter {
mode: ColoredStripMode, mode: ColoredStripMode,
verts: Vec<ColoredStripVert>, verts: Vec<ColoredStripVert>,
color: CColor, color: CColor,
}, },
Decal {/* TODO */}, Decal { /* TODO */ },
ElementGen {/* TODO */}, ElementGen { /* TODO */ },
EnergyBar {/* TODO */}, EnergyBar { /* TODO */ },
EnvFx {/* TODO */}, EnvFx { /* TODO */ },
FluidPlane {/* TODO */}, FluidPlane { /* TODO */ },
FogVolumeFilter { FogVolumeFilter {
two_way: bool, two_way: bool,
color: CColor, color: CColor,
@ -76,8 +75,8 @@ enum ShaderDrawCommand {
pass: u8, pass: u8,
verts: Vec<CVector3f>, verts: Vec<CVector3f>,
}, },
LineRenderer {/* TODO */}, LineRenderer { /* TODO */ },
MapSurface {/* TODO */}, MapSurface { /* TODO */ },
Model { Model {
pipeline_id: u32, pipeline_id: u32,
material_id: u32, material_id: u32,
@ -88,13 +87,13 @@ enum ShaderDrawCommand {
model_flags: u32, model_flags: u32,
}, },
MoviePlayer(movie_player::DrawData), MoviePlayer(movie_player::DrawData),
NES {/* TODO */}, NES { /* TODO */ },
ParticleSwoosh {/* TODO */}, ParticleSwoosh { /* TODO */ },
PhazonSuitFilter {/* TODO */}, PhazonSuitFilter { /* TODO */ },
RadarPaint {/* TODO */}, RadarPaint { /* TODO */ },
RandomStaticFilter {/* TODO */}, RandomStaticFilter { /* TODO */ },
ScanLinesFilter {/* TODO */}, ScanLinesFilter { /* TODO */ },
TextSupport {/* TODO */}, TextSupport { /* TODO */ },
TexturedQuad(textured_quad::DrawData), TexturedQuad(textured_quad::DrawData),
ThermalCold, ThermalCold,
ThermalHot, ThermalHot,
@ -123,9 +122,11 @@ struct RenderState {
render_textures: HashMap<u32, RenderTexture>, render_textures: HashMap<u32, RenderTexture>,
// Shader states // Shader states
aabb: aabb::State, aabb: aabb::State,
colored_quad: colored_quad::State,
textured_quad: textured_quad::State, textured_quad: textured_quad::State,
movie_player: movie_player::State, movie_player: movie_player::State,
} }
pub(crate) fn construct_state( pub(crate) fn construct_state(
device: Arc<wgpu::Device>, device: Arc<wgpu::Device>,
queue: Arc<wgpu::Queue>, queue: Arc<wgpu::Queue>,
@ -147,6 +148,7 @@ pub(crate) fn construct_state(
}), }),
}; };
let aabb = aabb::construct_state(&device, &queue, &buffers, graphics_config); let aabb = aabb::construct_state(&device, &queue, &buffers, graphics_config);
let colored_quad = colored_quad::construct_state(&device, &queue, &buffers, graphics_config);
let textured_quad = textured_quad::construct_state(&device, &queue, &buffers, graphics_config); let textured_quad = textured_quad::construct_state(&device, &queue, &buffers, graphics_config);
let movie_player = movie_player::construct_state(&device, &queue, &buffers, graphics_config); let movie_player = movie_player::construct_state(&device, &queue, &buffers, graphics_config);
let mut state = RenderState { let mut state = RenderState {
@ -162,6 +164,7 @@ pub(crate) fn construct_state(
textures: Default::default(), textures: Default::default(),
render_textures: Default::default(), render_textures: Default::default(),
aabb, aabb,
colored_quad,
textured_quad, textured_quad,
movie_player, movie_player,
}; };
@ -268,18 +271,22 @@ struct PipelineRef {
pub(crate) enum PipelineCreateCommand { pub(crate) enum PipelineCreateCommand {
Aabb(aabb::PipelineConfig), Aabb(aabb::PipelineConfig),
ColoredQuad(colored_quad::PipelineConfig),
TexturedQuad(textured_quad::PipelineConfig), TexturedQuad(textured_quad::PipelineConfig),
MoviePlayer(movie_player::PipelineConfig), MoviePlayer(movie_player::PipelineConfig),
} }
#[inline(always)] #[inline(always)]
fn hash_with_seed<T: Hash>(value: &T, seed: u64) -> u64 { fn hash_with_seed<T: Hash>(value: &T, seed: u64) -> u64 {
let mut state = Xxh3Hash64::with_seed(seed); let mut state = Xxh3Hash64::with_seed(seed);
value.hash(&mut state); value.hash(&mut state);
state.finish() state.finish()
} }
fn construct_pipeline(state: &mut RenderState, cmd: &PipelineCreateCommand) -> u64 { fn construct_pipeline(state: &mut RenderState, cmd: &PipelineCreateCommand) -> u64 {
let id = match cmd { let id = match cmd {
PipelineCreateCommand::Aabb(ref config) => hash_with_seed(config, 0xAABB), PipelineCreateCommand::Aabb(ref config) => hash_with_seed(config, 0xAABB),
PipelineCreateCommand::ColoredQuad(ref config) => hash_with_seed(config, 0xC013B),
PipelineCreateCommand::TexturedQuad(ref config) => hash_with_seed(config, 0xEEAD), PipelineCreateCommand::TexturedQuad(ref config) => hash_with_seed(config, 0xEEAD),
PipelineCreateCommand::MoviePlayer(ref config) => hash_with_seed(config, 0xFAAE), PipelineCreateCommand::MoviePlayer(ref config) => hash_with_seed(config, 0xFAAE),
}; };
@ -291,6 +298,12 @@ fn construct_pipeline(state: &mut RenderState, cmd: &PipelineCreateCommand) -> u
&state.aabb, &state.aabb,
config, config,
), ),
PipelineCreateCommand::ColoredQuad(ref config) => colored_quad::construct_pipeline(
state.device.as_ref(),
&state.graphics_config,
&state.colored_quad,
config,
),
PipelineCreateCommand::TexturedQuad(ref config) => textured_quad::construct_pipeline( PipelineCreateCommand::TexturedQuad(ref config) => textured_quad::construct_pipeline(
state.device.as_ref(), state.device.as_ref(),
&state.graphics_config, &state.graphics_config,
@ -356,6 +369,9 @@ pub(crate) fn render_into_pass(pass: &mut wgpu::RenderPass) {
ShaderDrawCommand::Aabb(data) => { ShaderDrawCommand::Aabb(data) => {
aabb::draw_aabb(data, &state.aabb, pass, &state.buffers); aabb::draw_aabb(data, &state.aabb, pass, &state.buffers);
} }
ShaderDrawCommand::ColoredQuad(data) => {
colored_quad::draw_colored_quad(data, &state.colored_quad, pass, &state.buffers);
}
ShaderDrawCommand::TexturedQuad(data) => { ShaderDrawCommand::TexturedQuad(data) => {
textured_quad::draw_textured_quad( textured_quad::draw_textured_quad(
data, data,
@ -385,22 +401,29 @@ fn update_model_view(mv: CMatrix4f, mv_inv: CMatrix4f) {
global_buffers.global_current.mv_inv = mv_inv; global_buffers.global_current.mv_inv = mv_inv;
global_buffers.global_dirty = true; global_buffers.global_dirty = true;
} }
fn update_projection(proj: CMatrix4f) { fn update_projection(proj: CMatrix4f) {
let global_buffers = unsafe { &mut GLOBAL_BUFFERS }; let global_buffers = unsafe { &mut GLOBAL_BUFFERS };
global_buffers.global_current.proj = proj; global_buffers.global_current.proj = proj;
global_buffers.global_dirty = true; global_buffers.global_dirty = true;
} }
fn update_fog_state(state: ffi::FogState) { fn update_fog_state(state: ffi::FogState) {
let global_buffers = unsafe { &mut GLOBAL_BUFFERS }; let global_buffers = unsafe { &mut GLOBAL_BUFFERS };
global_buffers.global_current.fog = state; global_buffers.global_current.fog = state;
global_buffers.global_dirty = true; global_buffers.global_dirty = true;
} }
fn get_projection_matrix() -> CMatrix4f {
let global_buffers = unsafe { &GLOBAL_BUFFERS };
global_buffers.global_current.proj
}
fn get_combined_matrix() -> CMatrix4f { fn get_combined_matrix() -> CMatrix4f {
let global_buffers = unsafe { &GLOBAL_BUFFERS }; let global_buffers = unsafe { &GLOBAL_BUFFERS };
CMatrix4f::from( CMatrix4f::from(
cgmath::Matrix4::from(global_buffers.global_current.mv) cgmath::Matrix4::from(global_buffers.global_current.proj)
* cgmath::Matrix4::from(global_buffers.global_current.proj), * cgmath::Matrix4::from(global_buffers.global_current.mv),
) )
} }
@ -417,10 +440,12 @@ fn push_draw_command(cmd: ShaderDrawCommand) {
let state = unsafe { STATE.as_mut().unwrap_unchecked() }; let state = unsafe { STATE.as_mut().unwrap_unchecked() };
state.commands.push_back(Command::Draw(cmd)); state.commands.push_back(Command::Draw(cmd));
} }
fn set_viewport(rect: CRectangle, znear: f32, zfar: f32) { fn set_viewport(rect: CRectangle, znear: f32, zfar: f32) {
let state = unsafe { STATE.as_mut().unwrap_unchecked() }; let state = unsafe { STATE.as_mut().unwrap_unchecked() };
state.commands.push_back(Command::SetViewport(rect, znear, zfar)); state.commands.push_back(Command::SetViewport(rect, znear, zfar));
} }
fn set_scissor(x: u32, y: u32, w: u32, h: u32) { fn set_scissor(x: u32, y: u32, w: u32, h: u32) {
let state = unsafe { STATE.as_mut().unwrap_unchecked() }; let state = unsafe { STATE.as_mut().unwrap_unchecked() };
state.commands.push_back(Command::SetScissor(x, y, w, h)); state.commands.push_back(Command::SetScissor(x, y, w, h));
@ -429,6 +454,7 @@ fn set_scissor(x: u32, y: u32, w: u32, h: u32) {
fn resolve_color(rect: ffi::ClipRect, bind: u32, clear_depth: bool) { fn resolve_color(rect: ffi::ClipRect, bind: u32, clear_depth: bool) {
// TODO // TODO
} }
fn resolve_depth(rect: ffi::ClipRect, bind: u32) { fn resolve_depth(rect: ffi::ClipRect, bind: u32) {
// TODO // TODO
} }

View File

@ -3,7 +3,6 @@
#include <numeric> #include <numeric>
#include <iostream> #include <iostream>
#include "boo/boo.hpp"
#include "logvisor/logvisor.hpp" #include "logvisor/logvisor.hpp"
#include "ImGuiEngine.hpp" #include "ImGuiEngine.hpp"
@ -144,7 +143,7 @@ static std::string CPUFeatureString(const zeus::CPUInfo& cpuInf) {
#endif #endif
return features; return features;
} }
#if 0
struct WindowCallback : boo::IWindowCallback { struct WindowCallback : boo::IWindowCallback {
friend struct Application; friend struct Application;
@ -246,28 +245,27 @@ private:
void destroyed() override { m_windowInvalid = true; } void destroyed() override { m_windowInvalid = true; }
}; };
#endif
struct Application : aurora::AppDelegate { struct Application : aurora::AppDelegate {
private: private:
WindowCallback m_windowCallback;
hecl::Runtime::FileStoreManager& m_fileMgr; hecl::Runtime::FileStoreManager& m_fileMgr;
hecl::CVarManager& m_cvarManager; hecl::CVarManager& m_cvarManager;
hecl::CVarCommons& m_cvarCommons; hecl::CVarCommons& m_cvarCommons;
ImGuiConsole m_imGuiConsole; ImGuiConsole m_imGuiConsole;
std::string m_errorString; std::string m_errorString;
// boo::ObjToken<boo::ITextureR> m_renderTex;
std::string m_deferredProject; std::string m_deferredProject;
bool m_projectInitialized = false; bool m_projectInitialized = false;
// std::unique_ptr<hecl::Database::Project> m_proj;
std::optional<amuse::BooBackendVoiceAllocator> m_amuseAllocWrapper; std::optional<amuse::BooBackendVoiceAllocator> m_amuseAllocWrapper;
std::unique_ptr<boo::IAudioVoiceEngine> m_voiceEngine; std::unique_ptr<boo::IAudioVoiceEngine> m_voiceEngine;
// std::unique_ptr<hecl::PipelineConverterBase> m_pipelineConv;
Limiter m_limiter{}; Limiter m_limiter{};
bool m_noShaderWarmup = false; bool m_noShaderWarmup = false;
bool m_firstFrame = true; bool m_firstFrame = true;
bool m_fullscreenToggleRequested = false;
bool m_quitRequested = false;
using delta_clock = std::chrono::high_resolution_clock; using delta_clock = std::chrono::high_resolution_clock;
std::chrono::time_point<delta_clock> m_prevFrameTime; std::chrono::time_point<delta_clock> m_prevFrameTime;
@ -361,9 +359,9 @@ public:
OPTICK_FRAME("MainThread"); OPTICK_FRAME("MainThread");
// Check if fullscreen has been toggled, if so set the fullscreen cvar accordingly // Check if fullscreen has been toggled, if so set the fullscreen cvar accordingly
if (m_windowCallback.m_fullscreenToggleRequested) { if (m_fullscreenToggleRequested) {
m_cvarCommons.m_fullscreen->fromBoolean(!m_cvarCommons.getFullscreen()); m_cvarCommons.m_fullscreen->fromBoolean(!m_cvarCommons.getFullscreen());
m_windowCallback.m_fullscreenToggleRequested = false; m_fullscreenToggleRequested = false;
} }
// Check if the user has modified the fullscreen CVar, if so set fullscreen state accordingly // Check if the user has modified the fullscreen CVar, if so set fullscreen state accordingly
@ -397,6 +395,14 @@ public:
m_imGuiConsole.ShowAboutWindow(false, m_errorString); m_imGuiConsole.ShowAboutWindow(false, m_errorString);
} }
if (m_quitRequested) {
if (g_mainMP1) {
g_mainMP1->Quit();
} else {
return false;
}
}
return true; return true;
} }
@ -469,48 +475,48 @@ public:
CDvdFile::Shutdown(); CDvdFile::Shutdown();
} }
void onCharKeyDown(uint8_t code, bool isRepeat) noexcept override { void onCharKeyDown(uint8_t code, aurora::ModifierKey mods, bool isRepeat) noexcept override {
Log.report(logvisor::Info, FMT_STRING("DEBUG CHAR KEYS: '{}', isRepeat {}"), static_cast<char>(code), isRepeat); Log.report(logvisor::Info, FMT_STRING("DEBUG CHAR KEYS: '{}', isRepeat {}"), static_cast<char>(code), isRepeat);
// if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { // if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) {
if (g_mainMP1) { if (g_mainMP1) {
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
as->charKeyDown(code, boo::EModifierKey::None, isRepeat); as->charKeyDown(code, mods, isRepeat);
} }
} }
// } // }
} }
void onCharKeyUp(uint8_t code) noexcept override { void onCharKeyUp(uint8_t code, aurora::ModifierKey mods) noexcept override {
Log.report(logvisor::Info, FMT_STRING("DEBUG CHAR KEYS: '{}'"), static_cast<char>(code)); Log.report(logvisor::Info, FMT_STRING("DEBUG CHAR KEYS: '{}'"), static_cast<char>(code));
if (g_mainMP1) { if (g_mainMP1) {
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
as->charKeyUp(code, boo::EModifierKey::None); as->charKeyUp(code, mods);
} }
} }
} }
void onSpecialKeyDown(aurora::SpecialKey key, bool isRepeat) noexcept override { void onSpecialKeyDown(aurora::SpecialKey key, aurora::ModifierKey mods, bool isRepeat) noexcept override {
Log.report(logvisor::Info, FMT_STRING("DEBUG KEYS: SpecialKey {}, isRepeat {}"), key, isRepeat); Log.report(logvisor::Info, FMT_STRING("DEBUG KEYS: SpecialKey {}, isRepeat {}"), key, isRepeat);
/* TODO: Temporarily convert the aurora enum to boo's until we refactor everything */ /* TODO: Temporarily convert the aurora enum to boo's until we refactor everything */
if (g_mainMP1) { if (g_mainMP1) {
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
as->specialKeyDown(boo::ESpecialKey(key), boo::EModifierKey::None, isRepeat); as->specialKeyDown(key, mods, isRepeat);
}
}
if (True(mods & (aurora::ModifierKey::LeftAlt | aurora::ModifierKey::RightAlt))) {
if (key == aurora::SpecialKey::Enter) {
m_fullscreenToggleRequested = true;
} else if (key == aurora::SpecialKey::F4) {
m_quitRequested = true;
} }
} }
// 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(aurora::SpecialKey key) noexcept override { void onSpecialKeyUp(aurora::SpecialKey key, aurora::ModifierKey mods) noexcept override {
/* TODO: Temporarily convert the aurora enum to boo's until we refactor everything */ /* TODO: Temporarily convert the aurora enum to boo's until we refactor everything */
if (g_mainMP1) { if (g_mainMP1) {
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
as->specialKeyUp(boo::ESpecialKey(key), boo::EModifierKey::None); as->specialKeyUp(key, mods);
} }
} }
} }

View File

@ -1,4 +1,9 @@
#include "Runtime/GuiSys/CGuiPane.hpp" #include "Runtime/GuiSys/CGuiPane.hpp"
#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
#include <aurora_shaders.h>
namespace metaforce { namespace metaforce {
@ -7,32 +12,45 @@ CGuiPane::CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, con
CGuiPane::InitializeBuffers(); CGuiPane::InitializeBuffers();
} }
void CGuiPane::Draw(const CGuiWidgetDrawParms& parms) {
CGraphics::SetModelMatrix(x34_worldXF * zeus::CTransform::Translate(xc8_scaleCenter));
if (GetIsVisible()) {
auto col = xa8_color2;
col.a() = parms.x0_alphaMod * xa8_color2.a();
aurora::shaders::queue_colored_quad_verts(aurora::shaders::CameraFilterType::Blend, aurora::shaders::ZTest::Always,
false, col, {xc0_verts.data(), xc0_verts.size()});
}
CGuiWidget::Draw(parms);
}
void CGuiPane::ScaleDimensions(const zeus::CVector3f& scale) { void CGuiPane::ScaleDimensions(const zeus::CVector3f& scale) {
InitializeBuffers(); InitializeBuffers();
for (auto& vert : xc0_verts) {
for (TexShaderVert& v : xc0_verts) { vert -= xc8_scaleCenter;
v.m_pos -= xc8_scaleCenter; vert *= scale;
v.m_pos *= scale; vert += xc8_scaleCenter;
v.m_pos += xc8_scaleCenter;
} }
} }
void CGuiPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) { void CGuiPane::SetDimensions(const zeus::CVector2f& dim, bool initBuffers) {
xb8_dim = dim; xb8_dim = dim;
if (initVBO) if (initBuffers)
InitializeBuffers(); InitializeBuffers();
} }
zeus::CVector2f CGuiPane::GetDimensions() const { return xb8_dim; } zeus::CVector2f CGuiPane::GetDimensions() const { return xb8_dim; }
void CGuiPane::InitializeBuffers() { void CGuiPane::InitializeBuffers() {
if (xc0_verts.size() < 4) #if 0
xc0_verts.resize(4); if (xc0_verts == nullptr) {
xc0_verts = new float[3 * 4];
}
#endif
xc0_verts[0].assign(-xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f);
xc0_verts[1].assign(-xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f);
xc0_verts[2].assign(xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f);
xc0_verts[3].assign(xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f);
xc0_verts[0].m_pos.assign(-xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f);
xc0_verts[1].m_pos.assign(-xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f);
xc0_verts[2].m_pos.assign(xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f);
xc0_verts[3].m_pos.assign(xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f);
} }
void CGuiPane::WriteData(COutputStream& out, bool flag) const {} void CGuiPane::WriteData(COutputStream& out, bool flag) const {}

View File

@ -14,13 +14,8 @@ class CGuiPane : public CGuiWidget {
protected: protected:
zeus::CVector2f xb8_dim; zeus::CVector2f xb8_dim;
struct TexShaderVert {
zeus::CVector3f m_pos;
zeus::CVector2f m_uv;
};
/* Originally a vert-buffer pointer for GX */ /* Originally a vert-buffer pointer for GX */
std::vector<TexShaderVert> xc0_verts; std::array<zeus::CVector3f, 4> xc0_verts;
// u32 x104_ = 4; /* vert count */
zeus::CVector3f xc8_scaleCenter; zeus::CVector3f xc8_scaleCenter;
@ -28,6 +23,7 @@ public:
CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, const zeus::CVector3f& scaleCenter); CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, const zeus::CVector3f& scaleCenter);
FourCC GetWidgetTypeID() const override { return FOURCC('PANE'); } FourCC GetWidgetTypeID() const override { return FOURCC('PANE'); }
void Draw(const CGuiWidgetDrawParms& parms) override;
virtual void ScaleDimensions(const zeus::CVector3f& scale); virtual void ScaleDimensions(const zeus::CVector3f& scale);
virtual void SetDimensions(const zeus::CVector2f& dim, bool initVBO); virtual void SetDimensions(const zeus::CVector2f& dim, bool initVBO);
virtual zeus::CVector2f GetDimensions() const; virtual zeus::CVector2f GetDimensions() const;

View File

@ -17,13 +17,13 @@ constexpr std::array<zeus::CVector3f, 4> NormalPoints{{
{1.f, 0.f, 0.f}, {1.f, 0.f, 0.f},
{0.f, 0.f, 0.f}, {0.f, 0.f, 0.f},
}}; }};
bool testProjectedLine(const zeus::CVector2f& a, const zeus::CVector2f& b, const zeus::CVector2f& point) { bool testProjectedLine(const zeus::CVector2f& a, const zeus::CVector2f& b, const zeus::CVector2f& point) {
const zeus::CVector2f normal = (b - a).perpendicularVector().normalized(); const zeus::CVector2f normal = (b - a).perpendicularVector().normalized();
return point.dot(normal) >= a.dot(normal); return point.dot(normal) >= a.dot(normal);
} }
} // Anonymous namespace } // Anonymous namespace
bool CGuiTextPane::sDrawPaneRects = true;
CGuiTextPane::CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim, CGuiTextPane::CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim,
const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props, const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props,
const zeus::CColor& fontCol, const zeus::CColor& outlineCol, s32 extentX, s32 extentY) const zeus::CColor& fontCol, const zeus::CColor& outlineCol, s32 extentX, s32 extentY)
@ -46,6 +46,10 @@ void CGuiTextPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) {
void CGuiTextPane::ScaleDimensions(const zeus::CVector3f& scale) {} void CGuiTextPane::ScaleDimensions(const zeus::CVector3f& scale) {}
void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) { void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
if (sDrawPaneRects) {
CGuiPane::Draw({0.2f * parms.x0_alphaMod, parms.x4_cameraOffset});
}
if (!GetIsVisible()) { if (!GetIsVisible()) {
return; return;
} }
@ -53,19 +57,19 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
zeus::CVector2f dims = GetDimensions(); zeus::CVector2f dims = GetDimensions();
if (xd4_textSupport.x34_extentX) { if (xd4_textSupport.x34_extentX != 0) {
dims.x() /= float(xd4_textSupport.x34_extentX); dims.x() /= float(xd4_textSupport.x34_extentX);
} else { } else {
dims.x() = 0.f; dims.x() = 0.f;
} }
if (xd4_textSupport.x38_extentY) { if (xd4_textSupport.x38_extentY != 0) {
dims.y() /= float(xd4_textSupport.x38_extentY); dims.y() /= float(xd4_textSupport.x38_extentY);
} else { } else {
dims.y() = 0.f; dims.y() = 0.f;
} }
const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front() + xc8_scaleCenter) *
zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); zeus::CTransform::Scale(dims.x(), 1.f, dims.y());
CGraphics::SetModelMatrix(x34_worldXF * local); CGraphics::SetModelMatrix(x34_worldXF * local);
@ -98,7 +102,7 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear); ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
xd4_textSupport.Render(); xd4_textSupport.Render();
xd4_textSupport.SetGeometryColor(geomCol * zeus::CColor(geomCol.a, geomCol.a, geomCol.a, 1.f)); xd4_textSupport.SetGeometryColor(geomCol * zeus::CColor(geomCol.a(), geomCol.a(), geomCol.a(), 1.f));
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One,
ERglBlendFactor::One, ERglLogicOp::Clear); ERglBlendFactor::One, ERglLogicOp::Clear);
xd4_textSupport.Render(); xd4_textSupport.Render();
@ -111,7 +115,7 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
bool CGuiTextPane::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const { bool CGuiTextPane::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const {
const zeus::CVector2f dims = GetDimensions(); const zeus::CVector2f dims = GetDimensions();
const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front() + xc8_scaleCenter) *
zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); zeus::CTransform::Scale(dims.x(), 1.f, dims.y());
const zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f(); const zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f();

View File

@ -9,6 +9,7 @@
namespace metaforce { namespace metaforce {
class CGuiTextPane : public CGuiPane { class CGuiTextPane : public CGuiPane {
static bool sDrawPaneRects;
CGuiTextSupport xd4_textSupport; CGuiTextSupport xd4_textSupport;
public: public:

View File

@ -1,6 +1,10 @@
#include "Runtime/Graphics/CGraphics.hpp"
#include "Runtime/GuiSys/CGuiWidget.hpp" #include "Runtime/GuiSys/CGuiWidget.hpp"
#include "Runtime/GuiSys/CGuiFrame.hpp" #include "Runtime/GuiSys/CGuiFrame.hpp"
#include <aurora.h>
#include <aurora_shaders.h>
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
namespace metaforce { namespace metaforce {
@ -111,7 +115,7 @@ void CGuiWidget::Update(float dt) {
sib->Update(dt); sib->Update(dt);
} }
void CGuiWidget::Draw(const CGuiWidgetDrawParms&) {} void CGuiWidget::Draw(const CGuiWidgetDrawParms& parms) {}
void CGuiWidget::ProcessUserInput(const CFinalInput& input) {} void CGuiWidget::ProcessUserInput(const CFinalInput& input) {}
void CGuiWidget::Touch() {} void CGuiWidget::Touch() {}

View File

@ -128,10 +128,10 @@ CFinalInput::CFinalInput(int cIdx, float dt, const CKeyboardMouseControllerData&
, x23_enableAnaRightNegYP(DRADown() && !prevInput.DRADown()) , x23_enableAnaRightNegYP(DRADown() && !prevInput.DRADown())
, x24_anaLeftTriggerP(DLTrigger() && !prevInput.DLTrigger()) , x24_anaLeftTriggerP(DLTrigger() && !prevInput.DLTrigger())
, x28_anaRightTriggerP(DRTrigger() && !prevInput.DRTrigger()) , x28_anaRightTriggerP(DRTrigger() && !prevInput.DRTrigger())
, x2c_b31_DPUp(data.m_specialKeys[size_t(boo::ESpecialKey::Up)]) , x2c_b31_DPUp(data.m_specialKeys[size_t(aurora::SpecialKey::Up)])
, x2d_b24_DPRight(data.m_specialKeys[size_t(boo::ESpecialKey::Right)]) , x2d_b24_DPRight(data.m_specialKeys[size_t(aurora::SpecialKey::Right)])
, x2d_b25_DPDown(data.m_specialKeys[size_t(boo::ESpecialKey::Down)]) , x2d_b25_DPDown(data.m_specialKeys[size_t(aurora::SpecialKey::Down)])
, x2d_b26_DPLeft(data.m_specialKeys[size_t(boo::ESpecialKey::Left)]) , x2d_b26_DPLeft(data.m_specialKeys[size_t(aurora::SpecialKey::Left)])
, x2d_b28_PA(DA() && !prevInput.DA()) , x2d_b28_PA(DA() && !prevInput.DA())
, x2d_b29_PB(DB() && !prevInput.DB()) , x2d_b29_PB(DB() && !prevInput.DB())
, x2d_b30_PX(DX() && !prevInput.DX()) , x2d_b30_PX(DX() && !prevInput.DX())

View File

@ -67,22 +67,22 @@ public:
void mouseMove(const boo::SWindowCoord& coord) { m_data.m_mouseCoord = coord; } void mouseMove(const boo::SWindowCoord& coord) { m_data.m_mouseCoord = coord; }
void scroll(const boo::SWindowCoord&, const boo::SScrollDelta& scroll) { m_data.m_accumScroll += scroll; } void scroll(const boo::SWindowCoord&, const boo::SScrollDelta& scroll) { m_data.m_accumScroll += scroll; }
void charKeyDown(unsigned long charCode, boo::EModifierKey, bool) { void charKeyDown(uint8_t charCode, aurora::ModifierKey, bool) {
charCode = tolower(charCode); charCode = tolower(charCode);
if (charCode > 255) if (charCode > 255)
return; return;
m_data.m_charKeys[charCode] = true; m_data.m_charKeys[charCode] = true;
} }
void charKeyUp(unsigned long charCode, boo::EModifierKey mods) { void charKeyUp(uint8_t charCode, aurora::ModifierKey mods) {
charCode = tolower(charCode); charCode = tolower(charCode);
if (charCode > 255) if (charCode > 255)
return; return;
m_data.m_charKeys[charCode] = false; m_data.m_charKeys[charCode] = false;
} }
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey, bool) { m_data.m_specialKeys[size_t(key)] = true; } void specialKeyDown(aurora::SpecialKey key, aurora::ModifierKey, bool) { m_data.m_specialKeys[size_t(key)] = true; }
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey) { m_data.m_specialKeys[size_t(key)] = false; } void specialKeyUp(aurora::SpecialKey key, aurora::ModifierKey) { m_data.m_specialKeys[size_t(key)] = false; }
void modKeyDown(boo::EModifierKey mod, bool) { m_data.m_modMask = m_data.m_modMask | mod; } void modKeyDown(aurora::ModifierKey mod, bool) { m_data.m_modMask = m_data.m_modMask | mod; }
void modKeyUp(boo::EModifierKey mod) { m_data.m_modMask = m_data.m_modMask & ~mod; } void modKeyUp(aurora::ModifierKey mod) { m_data.m_modMask = m_data.m_modMask & ~mod; }
void reset() { m_data.m_accumScroll.zeroOut(); } void reset() { m_data.m_accumScroll.zeroOut(); }

View File

@ -2,14 +2,15 @@
#include <array> #include <array>
#include <boo/IWindow.hpp> #include <boo/IWindow.hpp>
#include "aurora.h"
namespace metaforce { namespace metaforce {
struct CKeyboardMouseControllerData { struct CKeyboardMouseControllerData {
std::array<bool, 256> m_charKeys{}; std::array<bool, 256> m_charKeys{};
std::array<bool, static_cast<size_t>(boo::ESpecialKey::MAX)> m_specialKeys{}; std::array<bool, static_cast<size_t>(aurora::SpecialKey::MAX)> m_specialKeys{};
std::array<bool, 6> m_mouseButtons{}; std::array<bool, 6> m_mouseButtons{};
boo::EModifierKey m_modMask = boo::EModifierKey::None; aurora::ModifierKey m_modMask = aurora::ModifierKey::None;
boo::SWindowCoord m_mouseCoord; boo::SWindowCoord m_mouseCoord;
boo::SScrollDelta m_accumScroll; boo::SScrollDelta m_accumScroll;
}; };

View File

@ -2045,16 +2045,8 @@ void CFrontEndUI::Draw() {
x38_pressStart->GetHeight() / 480.f * vPad); x38_pressStart->GetHeight() / 480.f * vPad);
zeus::CColor color = zeus::skWhite; zeus::CColor color = zeus::skWhite;
color.a() = x64_pressStartAlpha; color.a() = x64_pressStartAlpha;
aurora::shaders::queue_textured_quad( aurora::shaders::queue_textured_quad(aurora::shaders::CameraFilterType::Add, x38_pressStart->GetTexture()->ref,
aurora::shaders::CameraFilterType::Add, aurora::shaders::ZTest::Always, false, color, 1.f, rect, 0.f);
x38_pressStart->GetTexture()->ref,
aurora::shaders::ZTest::Always,
false,
color,
1.f,
rect,
0.f
);
} }
if (xc0_attractCount > 0) { if (xc0_attractCount > 0) {
@ -2065,7 +2057,9 @@ void CFrontEndUI::Draw() {
/* To black */ /* To black */
zeus::CColor color = zeus::skBlack; zeus::CColor color = zeus::skBlack;
color.a() = 1.f - x58_fadeBlackTimer; color.a() = 1.f - x58_fadeBlackTimer;
m_fadeToBlack.draw(color); zeus::CRectangle rect(0, 0, 1, 1);
aurora::shaders::queue_colored_quad(aurora::shaders::CameraFilterType::Blend, aurora::shaders::ZTest::Always,
false, color, rect, 0.f);
} }
} }
@ -2075,12 +2069,16 @@ void CFrontEndUI::Draw() {
/* To black */ /* To black */
zeus::CColor color = zeus::skBlack; zeus::CColor color = zeus::skBlack;
color.a() = zeus::clamp(0.f, 1.f - x58_fadeBlackTimer, 1.f); color.a() = zeus::clamp(0.f, 1.f - x58_fadeBlackTimer, 1.f);
m_fadeToBlack.draw(color); zeus::CRectangle rect(0, 0, 1, 1);
aurora::shaders::queue_colored_quad(aurora::shaders::CameraFilterType::Blend, aurora::shaders::ZTest::Always,
false, color, rect, 0.f);
} else if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) { } else if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) {
/* From black with 30-sec skip to title */ /* From black with 30-sec skip to title */
zeus::CColor color = zeus::skBlack; zeus::CColor color = zeus::skBlack;
color.a() = 1.f - zeus::clamp(0.f, 30.f - x58_fadeBlackTimer, 1.f); color.a() = 1.f - zeus::clamp(0.f, 30.f - x58_fadeBlackTimer, 1.f);
m_fadeToBlack.draw(color); zeus::CRectangle rect(0, 0, 1, 1);
aurora::shaders::queue_colored_quad(aurora::shaders::CameraFilterType::Blend, aurora::shaders::ZTest::Always,
false, color, rect, 0.f);
} }
} }

View File

@ -224,17 +224,17 @@ CGameArchitectureSupport::~CGameArchitectureSupport() {
CStreamAudioManager::Shutdown(); CStreamAudioManager::Shutdown();
} }
void CGameArchitectureSupport::charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat) { void CGameArchitectureSupport::charKeyDown(uint8_t charCode, aurora::ModifierKey mods, bool isRepeat) {
x30_inputGenerator.charKeyDown(charCode, mods, isRepeat); x30_inputGenerator.charKeyDown(charCode, mods, isRepeat);
// m_parent.m_console->handleCharCode(charCode, mods, isRepeat); // m_parent.m_console->handleCharCode(charCode, mods, isRepeat);
} }
void CGameArchitectureSupport::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) { void CGameArchitectureSupport::specialKeyDown(aurora::SpecialKey key, aurora::ModifierKey mods, bool isRepeat) {
x30_inputGenerator.specialKeyDown(key, mods, isRepeat); x30_inputGenerator.specialKeyDown(key, mods, isRepeat);
// m_parent.m_console->handleSpecialKeyDown(key, mods, isRepeat); // m_parent.m_console->handleSpecialKeyDown(key, mods, isRepeat);
} }
void CGameArchitectureSupport::specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) { void CGameArchitectureSupport::specialKeyUp(aurora::SpecialKey key, aurora::ModifierKey mods) {
x30_inputGenerator.specialKeyUp(key, mods); x30_inputGenerator.specialKeyUp(key, mods);
// m_parent.m_console->handleSpecialKeyUp(key, mods); // m_parent.m_console->handleSpecialKeyUp(key, mods);
} }

View File

@ -157,13 +157,13 @@ public:
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) { void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) {
x30_inputGenerator.scroll(coord, scroll); x30_inputGenerator.scroll(coord, scroll);
} }
void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat); void charKeyDown(uint8_t charCode, aurora::ModifierKey mods, bool isRepeat);
void charKeyUp(unsigned long charCode, boo::EModifierKey mods) { x30_inputGenerator.charKeyUp(charCode, mods); } void charKeyUp(uint8_t charCode, aurora::ModifierKey mods) { x30_inputGenerator.charKeyUp(charCode, mods); }
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat); void specialKeyDown(aurora::SpecialKey key, aurora::ModifierKey mods, bool isRepeat);
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods); void specialKeyUp(aurora::SpecialKey key, aurora::ModifierKey mods);
void modKeyDown(boo::EModifierKey mod, bool isRepeat) { x30_inputGenerator.modKeyDown(mod, isRepeat); } void modKeyDown(aurora::ModifierKey mod, bool isRepeat) { x30_inputGenerator.modKeyDown(mod, isRepeat); }
void modKeyUp(boo::EModifierKey mod) { x30_inputGenerator.modKeyUp(mod); } void modKeyUp(aurora::ModifierKey mod) { x30_inputGenerator.modKeyUp(mod); }
void PreloadAudio(); void PreloadAudio();
bool LoadAudio(); bool LoadAudio();