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",
|
"android_logger",
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"binrw",
|
"binrw",
|
||||||
|
"bitflags",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"bytemuck_derive",
|
"bytemuck_derive",
|
||||||
"cgmath",
|
"cgmath",
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
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,
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue