mirror of https://github.com/AxioDL/metaforce.git
More input and rendering implementations
This commit is contained in:
parent
7ee8f6e01d
commit
615204f71f
|
@ -97,6 +97,7 @@ dependencies = [
|
|||
"android_logger",
|
||||
"bindgen",
|
||||
"binrw",
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
"bytemuck_derive",
|
||||
"cgmath",
|
||||
|
|
|
@ -29,6 +29,7 @@ smallvec = "1.7.0"
|
|||
scopeguard = "1.1.0"
|
||||
twox-hash = "1.6.2"
|
||||
winit = "0.26.1"
|
||||
bitflags = "1.3.2"
|
||||
# custom sdl2
|
||||
sdl2 = { git = "https://github.com/encounter/rust-sdl2.git", rev = "f39d7a7549fd59bebb1fb42ec12973200bb3080b", features = ["no-link", "hidapi"] }
|
||||
|
||||
|
|
|
@ -4,9 +4,59 @@
|
|||
#include <cinttypes>
|
||||
#include <type_traits>
|
||||
#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 {
|
||||
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 ControllerAxis : uint8_t;
|
||||
|
||||
|
@ -30,10 +80,10 @@ struct AppDelegate {
|
|||
virtual void onAppExiting() noexcept = 0;
|
||||
|
||||
// Input
|
||||
virtual void onCharKeyDown(uint8_t charCode, bool isRepeat) noexcept = 0;
|
||||
virtual void onCharKeyUp(uint8_t charCode) noexcept = 0;
|
||||
virtual void onSpecialKeyDown(SpecialKey key, bool isRepeat) noexcept = 0;
|
||||
virtual void onSpecialKeyUp(SpecialKey key) noexcept = 0;
|
||||
virtual void onCharKeyDown(uint8_t charCode, ModifierKey mods, bool isRepeat) noexcept = 0;
|
||||
virtual void onCharKeyUp(uint8_t charCode, ModifierKey mods) noexcept = 0;
|
||||
virtual void onSpecialKeyDown(SpecialKey key, ModifierKey mods, bool isRepeat) noexcept = 0;
|
||||
virtual void onSpecialKeyUp(SpecialKey key, ModifierKey mods) noexcept = 0;
|
||||
|
||||
// Controller
|
||||
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 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 mouseDown([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button,
|
||||
// [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void mouseUp([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button,
|
||||
// [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void mouseMove([[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 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 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 charKeyUp([[maybe_unused]] unsigned long charCode, [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void specialKeyDown([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods,
|
||||
// [[maybe_unused]] bool isRepeat) noexcept {}
|
||||
// virtual void specialKeyUp([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void modKeyDown([[maybe_unused]] EModifierKey mod, [[maybe_unused]] bool isRepeat) noexcept {}
|
||||
// virtual void modKeyUp([[maybe_unused]] EModifierKey mod) 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,
|
||||
// [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void mouseUp([[maybe_unused]] const SWindowCoord& coord, [[maybe_unused]] EMouseButton button,
|
||||
// [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void mouseMove([[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 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 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 charKeyUp([[maybe_unused]] unsigned long charCode, [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void specialKeyDown([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods,
|
||||
// [[maybe_unused]] bool isRepeat) noexcept {}
|
||||
// virtual void specialKeyUp([[maybe_unused]] ESpecialKey key, [[maybe_unused]] EModifierKey mods) noexcept {}
|
||||
// virtual void modKeyDown([[maybe_unused]] EModifierKey mod, [[maybe_unused]] bool isRepeat) noexcept {}
|
||||
// virtual void modKeyUp([[maybe_unused]] EModifierKey mod) noexcept {}
|
||||
};
|
||||
} // namespace aurora
|
||||
|
|
|
@ -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_onAppExiting(AppDelegate& cb) noexcept;
|
||||
// Input
|
||||
void App_onCharKeyDown(AppDelegate& cb, uint8_t code, bool isRepeat) noexcept;
|
||||
void App_onCharKeyUp(AppDelegate& cb, uint8_t code) noexcept;
|
||||
void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, bool isRepeat) noexcept;
|
||||
void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key) noexcept;
|
||||
void App_onCharKeyDown(AppDelegate& cb, uint8_t code, std::uint16_t mods, bool isRepeat) noexcept;
|
||||
void App_onCharKeyUp(AppDelegate& cb, uint8_t code, std::uint16_t mods) noexcept;
|
||||
void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, std::uint16_t mods, bool isRepeat) noexcept;
|
||||
void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key, std::uint16_t mods) noexcept;
|
||||
// Controller
|
||||
void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept;
|
||||
void App_onControllerRemoved(AppDelegate& cb, uint32_t which) noexcept;
|
||||
|
|
|
@ -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); }
|
||||
void App_onAppDraw(AppDelegate& cb) noexcept { cb.onAppDraw(); }
|
||||
void App_onAppPostDraw(AppDelegate& cb) noexcept { cb.onAppPostDraw(); }
|
||||
void App_onAppWindowResized(AppDelegate& cb, const WindowSize& size) noexcept {
|
||||
cb.onAppWindowResized(size);
|
||||
}
|
||||
void App_onAppWindowMoved(AppDelegate& cb, int32_t x, int32_t y) noexcept {
|
||||
cb.onAppWindowMoved(x, y);
|
||||
}
|
||||
void App_onAppWindowResized(AppDelegate& cb, const WindowSize& size) noexcept { cb.onAppWindowResized(size); }
|
||||
void App_onAppWindowMoved(AppDelegate& cb, int32_t x, int32_t y) noexcept { cb.onAppWindowMoved(x, y); }
|
||||
void App_onAppExiting(AppDelegate& cb) noexcept { cb.onAppExiting(); }
|
||||
|
||||
// Input
|
||||
void App_onCharKeyDown(AppDelegate& cb, uint8_t code, bool isRepeat) noexcept {
|
||||
cb.onCharKeyDown(code, isRepeat);
|
||||
void App_onCharKeyDown(AppDelegate& cb, uint8_t code, std::uint16_t mods, bool isRepeat) noexcept {
|
||||
cb.onCharKeyDown(code, static_cast<ModifierKey>(mods), isRepeat);
|
||||
}
|
||||
void App_onCharKeyUp(AppDelegate& cb, uint8_t code) noexcept {
|
||||
cb.onCharKeyUp(code);
|
||||
void App_onCharKeyUp(AppDelegate& cb, uint8_t code, std::uint16_t mods) noexcept {
|
||||
cb.onCharKeyUp(code, static_cast<ModifierKey>(mods));
|
||||
}
|
||||
void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, bool isRepeat) noexcept {
|
||||
cb.onSpecialKeyDown(key, isRepeat);
|
||||
void App_onSpecialKeyDown(AppDelegate& cb, SpecialKey key, std::uint16_t mods, bool isRepeat) noexcept {
|
||||
cb.onSpecialKeyDown(key, static_cast<ModifierKey>(mods), isRepeat);
|
||||
}
|
||||
void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key) noexcept {
|
||||
cb.onSpecialKeyUp(key);
|
||||
void App_onSpecialKeyUp(AppDelegate& cb, SpecialKey key, std::uint16_t mods) noexcept {
|
||||
cb.onSpecialKeyUp(key, static_cast<ModifierKey>(mods));
|
||||
}
|
||||
|
||||
// Controller
|
||||
void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept {
|
||||
cb.onControllerAdded(which);
|
||||
}
|
||||
void App_onControllerRemoved(AppDelegate& cb, uint32_t which) noexcept {
|
||||
cb.onControllerRemoved(which);
|
||||
}
|
||||
void App_onControllerAdded(AppDelegate& cb, uint32_t which) noexcept { cb.onControllerAdded(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 {
|
||||
cb.onControllerButton(which, button, pressed);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use sdl2::controller::{Axis, Button};
|
||||
|
||||
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,
|
||||
sdl::{
|
||||
get_controller_name,
|
||||
get_controller_player_index,
|
||||
set_controller_player_index,
|
||||
is_controller_gamecube,
|
||||
get_controller_name
|
||||
},
|
||||
set_fullscreen, set_window_title, App, WindowContext,
|
||||
set_controller_player_index,
|
||||
}, set_fullscreen, set_window_title, WindowContext,
|
||||
};
|
||||
|
||||
#[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_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_onCharKeyDown(cb: Pin<&mut AppDelegate>,
|
||||
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(
|
||||
cb: Pin<&mut AppDelegate>,
|
||||
key: SpecialKey,
|
||||
keymod: u16,
|
||||
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
|
||||
pub(crate) fn App_onControllerAdded(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,
|
||||
F11 = 11,
|
||||
F12 = 12,
|
||||
Esc = 13,
|
||||
Enter = 14,
|
||||
Backspace = 15,
|
||||
Insert = 16,
|
||||
Delete = 17,
|
||||
Home = 18,
|
||||
End = 19,
|
||||
PgUp = 20,
|
||||
PgDown = 21,
|
||||
Left = 22,
|
||||
Right = 23,
|
||||
Up = 24,
|
||||
Down = 25,
|
||||
Tab = 26,
|
||||
}
|
||||
|
||||
pub struct KeyboardInput {
|
||||
pub scancode: u32,
|
||||
pub state: ElementState,
|
||||
// pub
|
||||
F13 = 13,
|
||||
F14 = 14,
|
||||
F15 = 15,
|
||||
F16 = 16,
|
||||
F17 = 17,
|
||||
F18 = 18,
|
||||
F19 = 19,
|
||||
F20 = 20,
|
||||
F21 = 21,
|
||||
F22 = 22,
|
||||
F23 = 23,
|
||||
F24 = 24,
|
||||
Esc = 25,
|
||||
Enter = 26,
|
||||
Backspace = 27,
|
||||
Insert = 28,
|
||||
Delete = 29,
|
||||
Home = 30,
|
||||
End = 31,
|
||||
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 {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#![allow(unused_imports)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unused_unsafe)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
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 gpu = initialize_gpu(&window);
|
||||
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);
|
||||
let app =
|
||||
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 {
|
||||
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 => {
|
||||
log::trace!("Requesting redraw");
|
||||
window_ctx.window.request_redraw();
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use sdl2::{
|
||||
controller::{Axis, GameController},
|
||||
event::Event,
|
||||
GameControllerSubsystem, Sdl,
|
||||
};
|
||||
use sdl2::keyboard::{Keycode, Mod};
|
||||
|
||||
use crate::{cxxbridge::ffi, get_app};
|
||||
use crate::ffi::SpecialKey;
|
||||
|
||||
pub(crate) struct SdlState {
|
||||
context: Sdl,
|
||||
|
@ -21,6 +22,126 @@ pub(crate) fn initialize_sdl() -> SdlState {
|
|||
let controller_sys = context.game_controller().unwrap();
|
||||
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(
|
||||
state: &mut SdlState,
|
||||
|
@ -75,6 +196,48 @@ pub(crate) fn poll_sdl_events(
|
|||
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
|
||||
Event::Quit { .. } => {
|
||||
return false;
|
||||
|
@ -142,7 +305,6 @@ pub(crate) fn is_controller_gamecube(which: u32) -> bool {
|
|||
.map_or(false, |c| c.name()
|
||||
.to_lowercase()
|
||||
.eq("nintendo gamecube controller"))
|
||||
|
||||
}
|
||||
|
||||
pub(crate) fn get_controller_name(which: u32) -> String {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -10,6 +10,7 @@ use crate::shaders::{
|
|||
write_texture,
|
||||
},
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -190,6 +191,21 @@ pub(crate) mod ffi {
|
|||
rect: CRectangle,
|
||||
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(
|
||||
tex_y: TextureRef,
|
||||
tex_u: TextureRef,
|
||||
|
|
|
@ -25,6 +25,7 @@ mod model;
|
|||
mod movie_player;
|
||||
mod texture;
|
||||
mod textured_quad;
|
||||
mod colored_quad;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum ColoredStripMode {
|
||||
|
@ -33,6 +34,7 @@ enum ColoredStripMode {
|
|||
FullAdditive,
|
||||
Subtractive,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct ColoredStripVert {
|
||||
position: CVector3f,
|
||||
|
@ -46,6 +48,7 @@ enum Command {
|
|||
SetScissor(u32, u32, u32, u32),
|
||||
Draw(ShaderDrawCommand),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ShaderDrawCommand {
|
||||
Aabb(aabb::DrawData),
|
||||
|
@ -53,21 +56,17 @@ enum ShaderDrawCommand {
|
|||
amount: f32,
|
||||
clear_depth: bool,
|
||||
},
|
||||
ColoredQuadFilter {
|
||||
filter_type: ffi::CameraFilterType,
|
||||
color: CColor,
|
||||
rect: CRectangle,
|
||||
},
|
||||
ColoredQuad(colored_quad::DrawData),
|
||||
ColoredStripFilter {
|
||||
mode: ColoredStripMode,
|
||||
verts: Vec<ColoredStripVert>,
|
||||
color: CColor,
|
||||
},
|
||||
Decal {/* TODO */},
|
||||
ElementGen {/* TODO */},
|
||||
EnergyBar {/* TODO */},
|
||||
EnvFx {/* TODO */},
|
||||
FluidPlane {/* TODO */},
|
||||
Decal { /* TODO */ },
|
||||
ElementGen { /* TODO */ },
|
||||
EnergyBar { /* TODO */ },
|
||||
EnvFx { /* TODO */ },
|
||||
FluidPlane { /* TODO */ },
|
||||
FogVolumeFilter {
|
||||
two_way: bool,
|
||||
color: CColor,
|
||||
|
@ -76,8 +75,8 @@ enum ShaderDrawCommand {
|
|||
pass: u8,
|
||||
verts: Vec<CVector3f>,
|
||||
},
|
||||
LineRenderer {/* TODO */},
|
||||
MapSurface {/* TODO */},
|
||||
LineRenderer { /* TODO */ },
|
||||
MapSurface { /* TODO */ },
|
||||
Model {
|
||||
pipeline_id: u32,
|
||||
material_id: u32,
|
||||
|
@ -88,13 +87,13 @@ enum ShaderDrawCommand {
|
|||
model_flags: u32,
|
||||
},
|
||||
MoviePlayer(movie_player::DrawData),
|
||||
NES {/* TODO */},
|
||||
ParticleSwoosh {/* TODO */},
|
||||
PhazonSuitFilter {/* TODO */},
|
||||
RadarPaint {/* TODO */},
|
||||
RandomStaticFilter {/* TODO */},
|
||||
ScanLinesFilter {/* TODO */},
|
||||
TextSupport {/* TODO */},
|
||||
NES { /* TODO */ },
|
||||
ParticleSwoosh { /* TODO */ },
|
||||
PhazonSuitFilter { /* TODO */ },
|
||||
RadarPaint { /* TODO */ },
|
||||
RandomStaticFilter { /* TODO */ },
|
||||
ScanLinesFilter { /* TODO */ },
|
||||
TextSupport { /* TODO */ },
|
||||
TexturedQuad(textured_quad::DrawData),
|
||||
ThermalCold,
|
||||
ThermalHot,
|
||||
|
@ -123,9 +122,11 @@ struct RenderState {
|
|||
render_textures: HashMap<u32, RenderTexture>,
|
||||
// Shader states
|
||||
aabb: aabb::State,
|
||||
colored_quad: colored_quad::State,
|
||||
textured_quad: textured_quad::State,
|
||||
movie_player: movie_player::State,
|
||||
}
|
||||
|
||||
pub(crate) fn construct_state(
|
||||
device: Arc<wgpu::Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
|
@ -147,6 +148,7 @@ pub(crate) fn construct_state(
|
|||
}),
|
||||
};
|
||||
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 movie_player = movie_player::construct_state(&device, &queue, &buffers, graphics_config);
|
||||
let mut state = RenderState {
|
||||
|
@ -162,6 +164,7 @@ pub(crate) fn construct_state(
|
|||
textures: Default::default(),
|
||||
render_textures: Default::default(),
|
||||
aabb,
|
||||
colored_quad,
|
||||
textured_quad,
|
||||
movie_player,
|
||||
};
|
||||
|
@ -268,18 +271,22 @@ struct PipelineRef {
|
|||
|
||||
pub(crate) enum PipelineCreateCommand {
|
||||
Aabb(aabb::PipelineConfig),
|
||||
ColoredQuad(colored_quad::PipelineConfig),
|
||||
TexturedQuad(textured_quad::PipelineConfig),
|
||||
MoviePlayer(movie_player::PipelineConfig),
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn hash_with_seed<T: Hash>(value: &T, seed: u64) -> u64 {
|
||||
let mut state = Xxh3Hash64::with_seed(seed);
|
||||
value.hash(&mut state);
|
||||
state.finish()
|
||||
}
|
||||
|
||||
fn construct_pipeline(state: &mut RenderState, cmd: &PipelineCreateCommand) -> u64 {
|
||||
let id = match cmd {
|
||||
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::MoviePlayer(ref config) => hash_with_seed(config, 0xFAAE),
|
||||
};
|
||||
|
@ -291,6 +298,12 @@ fn construct_pipeline(state: &mut RenderState, cmd: &PipelineCreateCommand) -> u
|
|||
&state.aabb,
|
||||
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(
|
||||
state.device.as_ref(),
|
||||
&state.graphics_config,
|
||||
|
@ -356,6 +369,9 @@ pub(crate) fn render_into_pass(pass: &mut wgpu::RenderPass) {
|
|||
ShaderDrawCommand::Aabb(data) => {
|
||||
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) => {
|
||||
textured_quad::draw_textured_quad(
|
||||
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_dirty = true;
|
||||
}
|
||||
|
||||
fn update_projection(proj: CMatrix4f) {
|
||||
let global_buffers = unsafe { &mut GLOBAL_BUFFERS };
|
||||
global_buffers.global_current.proj = proj;
|
||||
global_buffers.global_dirty = true;
|
||||
}
|
||||
|
||||
fn update_fog_state(state: ffi::FogState) {
|
||||
let global_buffers = unsafe { &mut GLOBAL_BUFFERS };
|
||||
global_buffers.global_current.fog = state;
|
||||
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 {
|
||||
let global_buffers = unsafe { &GLOBAL_BUFFERS };
|
||||
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() };
|
||||
state.commands.push_back(Command::Draw(cmd));
|
||||
}
|
||||
|
||||
fn set_viewport(rect: CRectangle, znear: f32, zfar: f32) {
|
||||
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||
state.commands.push_back(Command::SetViewport(rect, znear, zfar));
|
||||
}
|
||||
|
||||
fn set_scissor(x: u32, y: u32, w: u32, h: u32) {
|
||||
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||
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) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
fn resolve_depth(rect: ffi::ClipRect, bind: u32) {
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <numeric>
|
||||
#include <iostream>
|
||||
|
||||
#include "boo/boo.hpp"
|
||||
#include "logvisor/logvisor.hpp"
|
||||
|
||||
#include "ImGuiEngine.hpp"
|
||||
|
@ -144,7 +143,7 @@ static std::string CPUFeatureString(const zeus::CPUInfo& cpuInf) {
|
|||
#endif
|
||||
return features;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct WindowCallback : boo::IWindowCallback {
|
||||
friend struct Application;
|
||||
|
||||
|
@ -246,28 +245,27 @@ private:
|
|||
|
||||
void destroyed() override { m_windowInvalid = true; }
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Application : aurora::AppDelegate {
|
||||
private:
|
||||
WindowCallback m_windowCallback;
|
||||
hecl::Runtime::FileStoreManager& m_fileMgr;
|
||||
hecl::CVarManager& m_cvarManager;
|
||||
hecl::CVarCommons& m_cvarCommons;
|
||||
ImGuiConsole m_imGuiConsole;
|
||||
std::string m_errorString;
|
||||
|
||||
// boo::ObjToken<boo::ITextureR> m_renderTex;
|
||||
std::string m_deferredProject;
|
||||
bool m_projectInitialized = false;
|
||||
// std::unique_ptr<hecl::Database::Project> m_proj;
|
||||
std::optional<amuse::BooBackendVoiceAllocator> m_amuseAllocWrapper;
|
||||
std::unique_ptr<boo::IAudioVoiceEngine> m_voiceEngine;
|
||||
// std::unique_ptr<hecl::PipelineConverterBase> m_pipelineConv;
|
||||
|
||||
Limiter m_limiter{};
|
||||
bool m_noShaderWarmup = false;
|
||||
|
||||
bool m_firstFrame = true;
|
||||
bool m_fullscreenToggleRequested = false;
|
||||
bool m_quitRequested = false;
|
||||
using delta_clock = std::chrono::high_resolution_clock;
|
||||
std::chrono::time_point<delta_clock> m_prevFrameTime;
|
||||
|
||||
|
@ -361,9 +359,9 @@ public:
|
|||
OPTICK_FRAME("MainThread");
|
||||
|
||||
// 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_windowCallback.m_fullscreenToggleRequested = false;
|
||||
m_fullscreenToggleRequested = false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
if (m_quitRequested) {
|
||||
if (g_mainMP1) {
|
||||
g_mainMP1->Quit();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -469,48 +475,48 @@ public:
|
|||
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);
|
||||
// if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) {
|
||||
if (g_mainMP1) {
|
||||
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));
|
||||
if (g_mainMP1) {
|
||||
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);
|
||||
/* 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, 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 */
|
||||
if (g_mainMP1) {
|
||||
if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) {
|
||||
as->specialKeyUp(boo::ESpecialKey(key), boo::EModifierKey::None);
|
||||
as->specialKeyUp(key, mods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#include "Runtime/GuiSys/CGuiPane.hpp"
|
||||
#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp"
|
||||
|
||||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
|
||||
#include <aurora_shaders.h>
|
||||
|
||||
namespace metaforce {
|
||||
|
||||
|
@ -7,32 +12,45 @@ CGuiPane::CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, con
|
|||
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) {
|
||||
InitializeBuffers();
|
||||
|
||||
for (TexShaderVert& v : xc0_verts) {
|
||||
v.m_pos -= xc8_scaleCenter;
|
||||
v.m_pos *= scale;
|
||||
v.m_pos += xc8_scaleCenter;
|
||||
for (auto& vert : xc0_verts) {
|
||||
vert -= xc8_scaleCenter;
|
||||
vert *= scale;
|
||||
vert += xc8_scaleCenter;
|
||||
}
|
||||
}
|
||||
|
||||
void CGuiPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) {
|
||||
void CGuiPane::SetDimensions(const zeus::CVector2f& dim, bool initBuffers) {
|
||||
xb8_dim = dim;
|
||||
if (initVBO)
|
||||
if (initBuffers)
|
||||
InitializeBuffers();
|
||||
}
|
||||
|
||||
zeus::CVector2f CGuiPane::GetDimensions() const { return xb8_dim; }
|
||||
|
||||
void CGuiPane::InitializeBuffers() {
|
||||
if (xc0_verts.size() < 4)
|
||||
xc0_verts.resize(4);
|
||||
#if 0
|
||||
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 {}
|
||||
|
|
|
@ -14,13 +14,8 @@ class CGuiPane : public CGuiWidget {
|
|||
protected:
|
||||
zeus::CVector2f xb8_dim;
|
||||
|
||||
struct TexShaderVert {
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CVector2f m_uv;
|
||||
};
|
||||
/* Originally a vert-buffer pointer for GX */
|
||||
std::vector<TexShaderVert> xc0_verts;
|
||||
// u32 x104_ = 4; /* vert count */
|
||||
std::array<zeus::CVector3f, 4> xc0_verts;
|
||||
|
||||
zeus::CVector3f xc8_scaleCenter;
|
||||
|
||||
|
@ -28,6 +23,7 @@ public:
|
|||
CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, const zeus::CVector3f& scaleCenter);
|
||||
FourCC GetWidgetTypeID() const override { return FOURCC('PANE'); }
|
||||
|
||||
void Draw(const CGuiWidgetDrawParms& parms) override;
|
||||
virtual void ScaleDimensions(const zeus::CVector3f& scale);
|
||||
virtual void SetDimensions(const zeus::CVector2f& dim, bool initVBO);
|
||||
virtual zeus::CVector2f GetDimensions() const;
|
||||
|
|
|
@ -17,13 +17,13 @@ constexpr std::array<zeus::CVector3f, 4> NormalPoints{{
|
|||
{1.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) {
|
||||
const zeus::CVector2f normal = (b - a).perpendicularVector().normalized();
|
||||
return point.dot(normal) >= a.dot(normal);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
bool CGuiTextPane::sDrawPaneRects = true;
|
||||
CGuiTextPane::CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim,
|
||||
const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props,
|
||||
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::Draw(const CGuiWidgetDrawParms& parms) {
|
||||
if (sDrawPaneRects) {
|
||||
CGuiPane::Draw({0.2f * parms.x0_alphaMod, parms.x4_cameraOffset});
|
||||
}
|
||||
|
||||
if (!GetIsVisible()) {
|
||||
return;
|
||||
}
|
||||
|
@ -53,19 +57,19 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
|
|||
|
||||
zeus::CVector2f dims = GetDimensions();
|
||||
|
||||
if (xd4_textSupport.x34_extentX) {
|
||||
if (xd4_textSupport.x34_extentX != 0) {
|
||||
dims.x() /= float(xd4_textSupport.x34_extentX);
|
||||
} else {
|
||||
dims.x() = 0.f;
|
||||
}
|
||||
|
||||
if (xd4_textSupport.x38_extentY) {
|
||||
if (xd4_textSupport.x38_extentY != 0) {
|
||||
dims.y() /= float(xd4_textSupport.x38_extentY);
|
||||
} else {
|
||||
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());
|
||||
CGraphics::SetModelMatrix(x34_worldXF * local);
|
||||
|
||||
|
@ -98,7 +102,7 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
|
|||
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
|
||||
ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
|
||||
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,
|
||||
ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||
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 {
|
||||
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());
|
||||
const zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f();
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
namespace metaforce {
|
||||
|
||||
class CGuiTextPane : public CGuiPane {
|
||||
static bool sDrawPaneRects;
|
||||
CGuiTextSupport xd4_textSupport;
|
||||
|
||||
public:
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
#include "Runtime/GuiSys/CGuiWidget.hpp"
|
||||
#include "Runtime/GuiSys/CGuiFrame.hpp"
|
||||
|
||||
#include <aurora.h>
|
||||
#include <aurora_shaders.h>
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace metaforce {
|
||||
|
@ -111,7 +115,7 @@ void CGuiWidget::Update(float dt) {
|
|||
sib->Update(dt);
|
||||
}
|
||||
|
||||
void CGuiWidget::Draw(const CGuiWidgetDrawParms&) {}
|
||||
void CGuiWidget::Draw(const CGuiWidgetDrawParms& parms) {}
|
||||
void CGuiWidget::ProcessUserInput(const CFinalInput& input) {}
|
||||
void CGuiWidget::Touch() {}
|
||||
|
||||
|
|
|
@ -128,10 +128,10 @@ CFinalInput::CFinalInput(int cIdx, float dt, const CKeyboardMouseControllerData&
|
|||
, x23_enableAnaRightNegYP(DRADown() && !prevInput.DRADown())
|
||||
, x24_anaLeftTriggerP(DLTrigger() && !prevInput.DLTrigger())
|
||||
, x28_anaRightTriggerP(DRTrigger() && !prevInput.DRTrigger())
|
||||
, x2c_b31_DPUp(data.m_specialKeys[size_t(boo::ESpecialKey::Up)])
|
||||
, x2d_b24_DPRight(data.m_specialKeys[size_t(boo::ESpecialKey::Right)])
|
||||
, x2d_b25_DPDown(data.m_specialKeys[size_t(boo::ESpecialKey::Down)])
|
||||
, x2d_b26_DPLeft(data.m_specialKeys[size_t(boo::ESpecialKey::Left)])
|
||||
, x2c_b31_DPUp(data.m_specialKeys[size_t(aurora::SpecialKey::Up)])
|
||||
, x2d_b24_DPRight(data.m_specialKeys[size_t(aurora::SpecialKey::Right)])
|
||||
, x2d_b25_DPDown(data.m_specialKeys[size_t(aurora::SpecialKey::Down)])
|
||||
, x2d_b26_DPLeft(data.m_specialKeys[size_t(aurora::SpecialKey::Left)])
|
||||
, x2d_b28_PA(DA() && !prevInput.DA())
|
||||
, x2d_b29_PB(DB() && !prevInput.DB())
|
||||
, x2d_b30_PX(DX() && !prevInput.DX())
|
||||
|
|
|
@ -67,22 +67,22 @@ public:
|
|||
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 charKeyDown(unsigned long charCode, boo::EModifierKey, bool) {
|
||||
void charKeyDown(uint8_t charCode, aurora::ModifierKey, bool) {
|
||||
charCode = tolower(charCode);
|
||||
if (charCode > 255)
|
||||
return;
|
||||
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);
|
||||
if (charCode > 255)
|
||||
return;
|
||||
m_data.m_charKeys[charCode] = false;
|
||||
}
|
||||
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey, 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 modKeyDown(boo::EModifierKey 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 specialKeyDown(aurora::SpecialKey key, aurora::ModifierKey, bool) { m_data.m_specialKeys[size_t(key)] = true; }
|
||||
void specialKeyUp(aurora::SpecialKey key, aurora::ModifierKey) { m_data.m_specialKeys[size_t(key)] = false; }
|
||||
void modKeyDown(aurora::ModifierKey mod, bool) { 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(); }
|
||||
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
#include <array>
|
||||
#include <boo/IWindow.hpp>
|
||||
#include "aurora.h"
|
||||
|
||||
namespace metaforce {
|
||||
|
||||
struct CKeyboardMouseControllerData {
|
||||
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{};
|
||||
boo::EModifierKey m_modMask = boo::EModifierKey::None;
|
||||
aurora::ModifierKey m_modMask = aurora::ModifierKey::None;
|
||||
boo::SWindowCoord m_mouseCoord;
|
||||
boo::SScrollDelta m_accumScroll;
|
||||
};
|
||||
|
|
|
@ -2045,16 +2045,8 @@ void CFrontEndUI::Draw() {
|
|||
x38_pressStart->GetHeight() / 480.f * vPad);
|
||||
zeus::CColor color = zeus::skWhite;
|
||||
color.a() = x64_pressStartAlpha;
|
||||
aurora::shaders::queue_textured_quad(
|
||||
aurora::shaders::CameraFilterType::Add,
|
||||
x38_pressStart->GetTexture()->ref,
|
||||
aurora::shaders::ZTest::Always,
|
||||
false,
|
||||
color,
|
||||
1.f,
|
||||
rect,
|
||||
0.f
|
||||
);
|
||||
aurora::shaders::queue_textured_quad(aurora::shaders::CameraFilterType::Add, x38_pressStart->GetTexture()->ref,
|
||||
aurora::shaders::ZTest::Always, false, color, 1.f, rect, 0.f);
|
||||
}
|
||||
|
||||
if (xc0_attractCount > 0) {
|
||||
|
@ -2065,7 +2057,9 @@ void CFrontEndUI::Draw() {
|
|||
/* To black */
|
||||
zeus::CColor color = zeus::skBlack;
|
||||
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 */
|
||||
zeus::CColor color = zeus::skBlack;
|
||||
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) {
|
||||
/* From black with 30-sec skip to title */
|
||||
zeus::CColor color = zeus::skBlack;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,17 +224,17 @@ CGameArchitectureSupport::~CGameArchitectureSupport() {
|
|||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
// m_parent.m_console->handleSpecialKeyUp(key, mods);
|
||||
}
|
||||
|
|
|
@ -157,13 +157,13 @@ public:
|
|||
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) {
|
||||
x30_inputGenerator.scroll(coord, scroll);
|
||||
}
|
||||
void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat);
|
||||
void charKeyUp(unsigned long charCode, boo::EModifierKey mods) { x30_inputGenerator.charKeyUp(charCode, mods); }
|
||||
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat);
|
||||
void charKeyDown(uint8_t charCode, aurora::ModifierKey mods, bool isRepeat);
|
||||
void charKeyUp(uint8_t charCode, aurora::ModifierKey mods) { x30_inputGenerator.charKeyUp(charCode, mods); }
|
||||
void specialKeyDown(aurora::SpecialKey key, aurora::ModifierKey mods, bool isRepeat);
|
||||
|
||||
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods);
|
||||
void modKeyDown(boo::EModifierKey mod, bool isRepeat) { x30_inputGenerator.modKeyDown(mod, isRepeat); }
|
||||
void modKeyUp(boo::EModifierKey mod) { x30_inputGenerator.modKeyUp(mod); }
|
||||
void specialKeyUp(aurora::SpecialKey key, aurora::ModifierKey mods);
|
||||
void modKeyDown(aurora::ModifierKey mod, bool isRepeat) { x30_inputGenerator.modKeyDown(mod, isRepeat); }
|
||||
void modKeyUp(aurora::ModifierKey mod) { x30_inputGenerator.modKeyUp(mod); }
|
||||
|
||||
void PreloadAudio();
|
||||
bool LoadAudio();
|
||||
|
|
Loading…
Reference in New Issue