TexturedQuad fixes, Better controller input handling (needs custom mapping)

This commit is contained in:
Phillip Stephens 2022-02-08 11:18:12 -08:00
parent 5add26b42e
commit acd861754c
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
14 changed files with 240 additions and 59 deletions

View File

@ -598,17 +598,23 @@ fn set_fullscreen(v: bool) {
}
fn get_controller_player_index(which: u32) -> i32 {
let has_controller = get_app().sdl_open_controllers.contains_key(&which);
let result = if has_controller {
get_app().sdl_open_controllers.get(&which).unwrap().player_index()
} else {
-1
};
let mut result: i32 = -1;
for (key, value) in &get_app().sdl_open_controllers {
if value.instance_id() == which {
result = value.player_index();
break;
}
}
result as i32
}
fn set_controller_player_index(which: u32, index: i32) {
if get_app().sdl_open_controllers.contains_key(&which) {
get_app().sdl_open_controllers.get(&which).unwrap().set_player_index(index);
for (key, value) in &get_app().sdl_open_controllers {
if value.instance_id() == which {
value.set_player_index(index);
break;
}
}
}

View File

@ -81,10 +81,14 @@ mod ffi {
#[namespace = "aurora::shaders"]
#[derive(Debug, Copy, Clone, Hash)]
pub(crate) enum ZTest {
None,
Never,
Less,
Equal,
LEqual,
Greater,
NEqual,
GEqual,
GEqualZWrite,
Always
}
#[namespace = "aurora::shaders"]
#[derive(Debug, Copy, Clone)]
@ -194,7 +198,8 @@ mod ffi {
fn queue_textured_quad_verts(
filter_type: CameraFilterType,
texture: TextureRef,
z_test: ZTest,
z_comparison: ZTest,
z_test: bool,
color: CColor,
pos: &[CVector3f],
uvs: &[CVector2f],
@ -203,7 +208,8 @@ mod ffi {
fn queue_textured_quad(
filter_type: CameraFilterType,
texture: TextureRef,
z_test: ZTest,
z_comparison: ZTest,
z_test: bool,
color: CColor,
uv_scale: f32,
rect: CRectangle,

View File

@ -28,7 +28,8 @@ pub(crate) struct DrawData {
#[derive(Hash)]
pub(crate) struct PipelineConfig {
filter_type: CameraFilterType,
z_test: ZTest,
z_comparison: ZTest,
z_test: bool,
}
pub(crate) const INITIAL_PIPELINES: &[PipelineCreateCommand] = &[
// PipelineCreateCommand::TexturedQuad(PipelineConfig { z_only: false }),
@ -194,12 +195,17 @@ pub(crate) fn construct_pipeline(
},
depth_stencil: Some(wgpu::DepthStencilState {
format: graphics.depth_format,
depth_write_enabled: config.z_test == ZTest::GEqualZWrite,
depth_compare: match config.z_test {
ZTest::None => wgpu::CompareFunction::Always,
depth_write_enabled: config.z_test,
depth_compare: match config.z_comparison {
ZTest::Never => wgpu::CompareFunction::Never,
ZTest::Less => wgpu::CompareFunction::Less,
ZTest::Equal => wgpu::CompareFunction::Equal,
ZTest::LEqual => wgpu::CompareFunction::LessEqual,
ZTest::GEqual | ZTest::GEqualZWrite => wgpu::CompareFunction::GreaterEqual,
_ => todo!(),
ZTest::Greater => wgpu::CompareFunction::Greater,
ZTest::NEqual => wgpu::CompareFunction::NotEqual,
ZTest::GEqual => wgpu::CompareFunction::GreaterEqual,
ZTest::Always => wgpu::CompareFunction::Always,
_=>todo!(),
},
stencil: Default::default(),
bias: Default::default(),
@ -247,14 +253,15 @@ struct Vert {
pub(crate) fn queue_textured_quad(
filter_type: CameraFilterType,
texture: TextureRef,
z_test: ZTest,
z_comparison: ZTest,
z_test: bool,
color: CColor,
uv_scale: f32,
rect: CRectangle,
z: f32,
) {
let pipeline =
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_test }));
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_comparison, z_test }));
let vert_range = push_verts(&[
Vert { pos: Vec3::new(0.0, 0.0, z), uv: Vec2::new(0.0, 0.0) },
Vert { pos: Vec3::new(0.0, 1.0, z), uv: Vec2::new(0.0, uv_scale) },
@ -278,7 +285,8 @@ pub(crate) fn queue_textured_quad(
pub(crate) fn queue_textured_quad_verts(
filter_type: CameraFilterType,
texture: TextureRef,
z_test: ZTest,
z_comparison: ZTest,
z_test: bool,
color: CColor,
pos: &[CVector3f],
uvs: &[CVector2f],
@ -289,7 +297,7 @@ pub(crate) fn queue_textured_quad_verts(
}
let pipeline =
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_test }));
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_comparison, z_test }));
let vert_range = push_verts(
&pos.iter()
.zip(uvs)

View File

@ -167,7 +167,7 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha
TLockedToken<CTexture> tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), iconRes});
if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) {
m_texQuadFilter.emplace(EFilterType::Add, tex, CTexturedQuadFilter::ZTest::GEqual);
//m_texQuadFilter.emplace(EFilterType::Add, tex, CTexturedQuadFilter::ZTest::GEqual);
}
constexpr std::array<CTexturedQuadFilter::Vert, 4> verts{{
@ -176,7 +176,7 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha
{{2.6f, 0.f, 2.6f}, {1.f, 1.f}},
{{2.6f, 0.f, -2.6f}, {1.f, 0.f}},
}};
m_texQuadFilter->drawVerts(iconColor, verts);
//m_texQuadFilter->drawVerts(iconColor, verts);
}
}

View File

@ -31,8 +31,8 @@ void CSimpleShadow::Render(const TLockedToken<CTexture>& tex) {
CGraphics::DisableAllLights();
CGraphics::SetModelMatrix(x0_xf);
if (!m_filter || m_filter->GetTex().GetObj() != tex.GetObj())
m_filter.emplace(EFilterType::InvDstMultiply, tex, CTexturedQuadFilter::ZTest::LEqual);
//if (!m_filter || m_filter->GetTex().GetObj() != tex.GetObj())
//m_filter.emplace(EFilterType::InvDstMultiply, tex, CTexturedQuadFilter::ZTest::LEqual);
float radius = x34_radius * x30_scale;
const std::array<CTexturedQuadFilter::Vert, 4> verts{{
@ -41,7 +41,7 @@ void CSimpleShadow::Render(const TLockedToken<CTexture>& tex) {
{{-radius, 0.f, radius}, {1.f, 0.f}},
{{radius, 0.f, radius}, {1.f, 1.f}},
}};
m_filter->drawVerts(zeus::skWhite, verts);
//m_filter->drawVerts(zeus::skWhite, verts);
}
void CSimpleShadow::Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr) {

View File

@ -182,7 +182,7 @@ CTexturedQuadFilter::CTexturedQuadFilter(const std::shared_ptr<aurora::TextureHa
m_flipRect = true; // TODO?
}
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const std::shared_ptr<aurora::TextureHandle>& tex, ZTest ztest)
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const std::shared_ptr<aurora::TextureHandle>& tex, ERglEnum ztest)
: m_booTex(tex), m_zTest(ztest) {
m_flipRect = true; // TODO?
// tex->setClampMode(boo::TextureClampMode::ClampToEdge);
@ -200,7 +200,7 @@ CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const std::shared_ptr
// } BooTrace);
}
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, TLockedToken<CTexture> tex, ZTest ztest)
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, TLockedToken<CTexture> tex, ERglEnum ztest)
: CTexturedQuadFilter(type, (tex ? tex->GetTexture() : nullptr), ztest) {
m_flipRect = true; // TODO?
m_tex = tex;

View File

@ -17,7 +17,7 @@ enum class EFilterType;
class CTexturedQuadFilter {
public:
enum class ZTest { None, LEqual, GEqual, GEqualZWrite };
enum class ZTest { Never, Less, Equal, LEqual, Greater, NEqual, GEqual, Always };
protected:
struct Uniform {
@ -27,11 +27,11 @@ protected:
};
TLockedToken<CTexture> m_tex;
std::shared_ptr<aurora::TextureHandle> m_booTex;
// boo::ObjToken<boo::IGraphicsBufferD> m_vbo;
// boo::ObjToken<boo::IGraphicsBufferD> m_uniBuf;
// boo::ObjToken<boo::IShaderDataBinding> m_dataBind;
// boo::ObjToken<boo::IGraphicsBufferD> m_vbo;
// boo::ObjToken<boo::IGraphicsBufferD> m_uniBuf;
// boo::ObjToken<boo::IShaderDataBinding> m_dataBind;
Uniform m_uniform;
ZTest m_zTest;
ERglEnum m_zTest;
bool m_flipRect = false;
explicit CTexturedQuadFilter(const std::shared_ptr<aurora::TextureHandle>& tex);
@ -44,8 +44,9 @@ public:
static void Initialize();
static void Shutdown();
static constexpr zeus::CRectangle DefaultRect{0.f, 0.f, 1.f, 1.f};
explicit CTexturedQuadFilter(EFilterType type, TLockedToken<CTexture> tex, ZTest zTest = ZTest::None);
explicit CTexturedQuadFilter(EFilterType type, const std::shared_ptr<aurora::TextureHandle>& tex, ZTest zTest = ZTest::None);
explicit CTexturedQuadFilter(EFilterType type, TLockedToken<CTexture> tex, ERglEnum zTest = ERglEnum::Never);
explicit CTexturedQuadFilter(EFilterType type, const std::shared_ptr<aurora::TextureHandle>& tex,
ERglEnum zTest = ERglEnum::Never);
CTexturedQuadFilter(const CTexturedQuadFilter&) = delete;
CTexturedQuadFilter& operator=(const CTexturedQuadFilter&) = delete;
CTexturedQuadFilter(CTexturedQuadFilter&&) = default;

View File

@ -81,22 +81,23 @@ void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& t
realUseUvs.push_back(v + xd0_uvBias0);
}
bool zTest = xac_drawFlags == EGuiModelDrawFlags::Shadeless || xac_drawFlags == EGuiModelDrawFlags::Opaque;
if (noBlur) {
aurora::shaders::queue_textured_quad_verts(
aurora::shaders::CameraFilterType(filter), tex.GetTexture()->ref, aurora::shaders::ZTest::None, useColor,
aurora::shaders::CameraFilterType(filter), tex.GetTexture()->ref, aurora::shaders::ZTest::LEqual, zTest, useColor,
{xe0_coords.data(), xe0_coords.size()}, {realUseUvs.data(), xe0_coords.size()}, 0);
// quad.drawVerts(useColor, verts);
} else if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumMips() == 1) {
aurora::shaders::queue_textured_quad_verts(
aurora::shaders::CameraFilterType(filter), tex.GetTexture()->ref, aurora::shaders::ZTest::None, useColor,
{xe0_coords.data(), xe0_coords.size()}, {realUseUvs.data(), xe0_coords.size()}, 0);
aurora::shaders::CameraFilterType(filter), tex.GetTexture()->ref, aurora::shaders::ZTest::LEqual, zTest,
useColor, {xe0_coords.data(), xe0_coords.size()}, {realUseUvs.data(), xe0_coords.size()}, 0);
} else {
const float tmp = (1.f - x14c_deResFactor) * alpha;
const float tmp3 = 1.f - tmp * tmp * tmp;
const float mip = tmp3 * static_cast<float>(tex.GetNumMips() - 1);
aurora::shaders::queue_textured_quad_verts(
aurora::shaders::CameraFilterType(filter), tex.GetTexture()->ref, aurora::shaders::ZTest::None, useColor,
{xe0_coords.data(), xe0_coords.size()}, {realUseUvs.data(), xe0_coords.size()}, mip);
aurora::shaders::CameraFilterType(filter), tex.GetTexture()->ref, aurora::shaders::ZTest::LEqual, zTest,
useColor, {xe0_coords.data(), xe0_coords.size()}, {realUseUvs.data(), xe0_coords.size()}, mip);
}
}

View File

@ -76,7 +76,8 @@ void CSplashScreen::Draw() {
aurora::shaders::queue_textured_quad(
aurora::shaders::CameraFilterType::Blend,
m_texture->GetTexture()->ref,
aurora::shaders::ZTest::None,
aurora::shaders::ZTest::Always,
false,
color,
1.f,
rect,

View File

@ -6,8 +6,8 @@ namespace metaforce {
CFinalInput::CFinalInput() = default;
//CFinalInput::CFinalInput(int cIdx, float dt, const boo::DolphinControllerState& data, const CFinalInput& prevInput,
// float leftDiv, float rightDiv)
// CFinalInput::CFinalInput(int cIdx, float dt, const boo::DolphinControllerState& data, const CFinalInput& prevInput,
// float leftDiv, float rightDiv)
//: x0_dt(dt)
//, x4_controllerIdx(cIdx)
//, x8_anaLeftX(zeus::clamp(-1.0f, data.m_leftStick[0] / 72.0f / leftDiv, 1.0f))
@ -75,9 +75,9 @@ CFinalInput::CFinalInput(int cIdx, float dt, const SAuroraControllerState& data,
, x2c_b25_B(data.m_btns[size_t(aurora::ControllerButton::B)])
, x2c_b26_X(data.m_btns[size_t(aurora::ControllerButton::X)])
, x2c_b27_Y(data.m_btns[size_t(aurora::ControllerButton::Y)])
, x2c_b28_Z(data.m_btns[size_t(aurora::ControllerButton::RightShoulder)])
, x2c_b29_L(data.m_axes[size_t(aurora::ControllerAxis::TriggerLeft)] > 29490)
, x2c_b30_R(data.m_axes[size_t(aurora::ControllerAxis::TriggerRight)] > 29490)
, x2c_b28_Z(data.m_btns[size_t(aurora::ControllerButton::Back)])
, x2c_b29_L(data.m_btns[size_t(aurora::ControllerButton::LeftShoulder)])
, x2c_b30_R(data.m_btns[size_t(aurora::ControllerButton::RightShoulder)])
, x2c_b31_DPUp(data.m_btns[size_t(aurora::ControllerButton::DPadUp)])
, x2d_b24_DPRight(data.m_btns[size_t(aurora::ControllerButton::DPadRight)])
, x2d_b25_DPDown(data.m_btns[size_t(aurora::ControllerButton::DPadDown)])
@ -94,7 +94,21 @@ CFinalInput::CFinalInput(int cIdx, float dt, const SAuroraControllerState& data,
, x2e_b28_PDPRight(DDPRight() && !prevInput.DDPRight())
, x2e_b29_PDPDown(DDPDown() && !prevInput.DDPDown())
, x2e_b30_PDPLeft(DDPLeft() && !prevInput.DDPLeft())
, x2e_b31_PStart(DStart() && !prevInput.DStart()) {}
, x2e_b31_PStart(DStart() && !prevInput.DStart()) {
if (x2c_b29_L) {
x18_anaLeftTrigger = 150.f * 0.007f;
}
if (x2c_b30_R) {
x1c_anaRightTrigger = 150.f * 0.007f;
}
if (x18_anaLeftTrigger > (150.f * 0.007f) && !x2c_b29_L) {
x2c_b29_L = true;
}
if (x1c_anaRightTrigger > (150.f * 0.007f) && !x2c_b30_R) {
x2c_b30_R = true;
}
}
CFinalInput::CFinalInput(int cIdx, float dt, const CKeyboardMouseControllerData& data, const CFinalInput& prevInput)
: x0_dt(dt)
@ -207,4 +221,110 @@ CFinalInput CFinalInput::ScaleAnalogueSticks(float leftDiv, float rightDiv) cons
ret.m_rightMul = 1.f / rightDiv;
return ret;
}
/* The following code is derived from pad.c in libogc
*
* Copyright (C) 2004 - 2009
* Michael Wiedenbauer (shagkur)
* Dave Murphy (WinterMute)
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*/
constexpr std::array<int16_t, 8> pad_clampregion{
30, 180, 15, 72, 40, 15, 59, 31,
};
static void pad_clampstick(int16_t& px, int16_t& py, int16_t max, int16_t xy, int16_t min) {
int x = px;
int y = py;
int signX;
if (x > 0) {
signX = 1;
} else {
signX = -1;
x = -x;
}
int signY;
if (y > 0) {
signY = 1;
} else {
signY = -1;
y = -y;
}
if (x <= min) {
x = 0;
} else {
x -= min;
}
if (y <= min) {
y = 0;
} else {
y -= min;
}
if (x == 0 && y == 0) {
px = py = 0;
return;
}
if (xy * y <= xy * x) {
const int d = xy * x + (max - xy) * y;
if (xy * max < d) {
x = int16_t(xy * max * x / d);
y = int16_t(xy * max * y / d);
}
} else {
const int d = xy * y + (max - xy) * x;
if (xy * max < d) {
x = int16_t(xy * max * x / d);
y = int16_t(xy * max * y / d);
}
}
px = int16_t(signX * x);
py = int16_t(signY * y);
}
static void pad_clamptrigger(int16_t& trigger) {
const int16_t min = pad_clampregion[0];
const int16_t max = pad_clampregion[1];
if (trigger <= min) {
trigger = 0;
} else {
if (max < trigger) {
trigger = max;
}
trigger -= min;
}
}
void SAuroraControllerState::clamp() {
pad_clampstick(m_axes[size_t(aurora::ControllerAxis::LeftX)], m_axes[size_t(aurora::ControllerAxis::LeftY)],
pad_clampregion[3], pad_clampregion[4], pad_clampregion[2]);
pad_clampstick(m_axes[size_t(aurora::ControllerAxis::RightX)], m_axes[size_t(aurora::ControllerAxis::RightY)],
pad_clampregion[6], pad_clampregion[7], pad_clampregion[5]);
pad_clamptrigger(m_axes[size_t(aurora::ControllerAxis::TriggerLeft)]);
pad_clamptrigger(m_axes[size_t(aurora::ControllerAxis::TriggerRight)]);
}
} // namespace metaforce

View File

@ -14,6 +14,7 @@ namespace metaforce {
struct SAuroraControllerState {
std::array<int16_t, size_t(aurora::ControllerAxis::MAX)> m_axes{};
std::bitset<size_t(aurora::ControllerButton::MAX)> m_btns{};
void clamp();
};
struct CFinalInput {

View File

@ -2,7 +2,7 @@
#include "Runtime/CArchitectureMessage.hpp"
#include "Runtime/CArchitectureQueue.hpp"
#include "imgui/magic_enum.hpp"
namespace metaforce {
void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
@ -14,7 +14,7 @@ void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
const CFinalInput& kbInput = getFinalInput(0, dt);
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, kbInput));
/* Dolphin controllers next */
/* Dolphin controllers next */
// for (int i = 0; i < 4; ++i) {
// bool connected;
// EStatusChange change = m_dolphinCb.getStatusChange(i, connected);
@ -38,4 +38,40 @@ void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
// }
}
void CInputGenerator::controllerAxis(uint32_t which, aurora::ControllerAxis axis, int16_t value) noexcept {
s32 idx = aurora::get_controller_player_index(which);
if (idx < 0) {
return;
}
switch (axis) {
case aurora::ControllerAxis::LeftY:
case aurora::ControllerAxis::RightY:
/* Value is inverted compared to what we expect on the Y axis */
value = -value;
[[fallthrough]];
case aurora::ControllerAxis::LeftX:
case aurora::ControllerAxis::RightX:
value /= 256;
if (value < -127)
value = -127;
else if (value > 127)
value = 127;
break;
case aurora::ControllerAxis::TriggerLeft:
case aurora::ControllerAxis::TriggerRight:
printf("Axis before clamp %i", value);
value /= 128;
if (value < 0)
value = 0;
printf(" after clamp %i\n", value);
break;
default:
break;
}
m_state[idx].m_axes[size_t(axis)] = value;
}
} // namespace metaforce

View File

@ -25,13 +25,13 @@ class CInputGenerator /*: public boo::DeviceFinder*/ {
float m_leftDiv;
float m_rightDiv;
CKeyboardMouseControllerData m_data;
SAuroraControllerState m_state;
SAuroraControllerState m_state[4];
CFinalInput m_lastUpdate;
const CFinalInput& getFinalInput(unsigned idx, float dt) {
auto input = CFinalInput(idx, dt, m_data, m_lastUpdate);
// Merge controller input with kb/m input
input |= CFinalInput(idx, dt, m_state, m_lastUpdate, m_leftDiv, m_rightDiv);
input |= CFinalInput(idx, dt, m_state[idx], m_lastUpdate, m_leftDiv, m_rightDiv);
m_lastUpdate = input;
return m_lastUpdate;
}
@ -50,13 +50,13 @@ public:
// }
void controllerButton(uint32_t idx, aurora::ControllerButton button, bool pressed) noexcept {
// TODO check idx
m_state.m_btns.set(size_t(button), pressed);
}
void controllerAxis(uint32_t idx, aurora::ControllerAxis axis, int16_t value) noexcept {
// TODO check idx
m_state.m_axes[size_t(axis)] = value;
s32 player = aurora::get_controller_player_index(idx);
if (player < 0) {
return;
}
m_state[player].m_btns.set(size_t(button), pressed);
}
void controllerAxis(uint32_t idx, aurora::ControllerAxis axis, int16_t value) noexcept;
/* Keyboard and mouse events are delivered on the main game
* thread as part of the app's main event loop. The OS is responsible

View File

@ -2048,7 +2048,8 @@ void CFrontEndUI::Draw() {
aurora::shaders::queue_textured_quad(
aurora::shaders::CameraFilterType::Add,
x38_pressStart->GetTexture()->ref,
aurora::shaders::ZTest::None,
aurora::shaders::ZTest::Always,
false,
color,
1.f,
rect,