mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-07 20:11:46 -04:00
Keyboard mouse binding controls (#682)
* kbm controls * submodule * files.cmake * a * Fixes * include <cstring> in J3DStruct.h --------- Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
@@ -1450,7 +1450,6 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiProcessOverlay.cpp
|
||||
src/dusk/imgui/ImGuiCameraOverlay.cpp
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
src/dusk/imgui/ImGuiDebugPad.cpp
|
||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/imgui/ImGuiMapLoader.cpp
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef J3DSTRUCT_H
|
||||
#define J3DSTRUCT_H
|
||||
|
||||
#include <cstring>
|
||||
#include <gx.h>
|
||||
#include <mtx.h>
|
||||
#include <mtx.h>
|
||||
#include "global.h"
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DLightInfo {
|
||||
bool operator==(J3DLightInfo& other) const;
|
||||
@@ -28,7 +28,7 @@ struct J3DLightInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTextureSRTInfo {
|
||||
// NOTE: Big endian when loaded from file!
|
||||
@@ -79,7 +79,7 @@ enum J3DTexMtxMode {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTexMtxInfo {
|
||||
bool operator==(J3DTexMtxInfo& other) const;
|
||||
@@ -97,7 +97,7 @@ struct J3DTexMtxInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DIndTexMtxInfo {
|
||||
J3DIndTexMtxInfo& operator=(J3DIndTexMtxInfo const&);
|
||||
@@ -107,7 +107,7 @@ struct J3DIndTexMtxInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DFogInfo {
|
||||
bool operator==(J3DFogInfo&) const;
|
||||
@@ -126,7 +126,7 @@ struct J3DFogInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DNBTScaleInfo {
|
||||
bool operator==(const J3DNBTScaleInfo& other) const;
|
||||
@@ -153,7 +153,7 @@ struct J3DIndTexOrderInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevSwapModeInfo {
|
||||
/* 0x0 */ u8 mRasSel;
|
||||
@@ -164,7 +164,7 @@ struct J3DTevSwapModeInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevSwapModeTableInfo {
|
||||
/* 0x0 */ u8 field_0x0;
|
||||
@@ -175,7 +175,7 @@ struct J3DTevSwapModeTableInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevStageInfo {
|
||||
/* 0x0 */ u8 field_0x0;
|
||||
@@ -202,7 +202,7 @@ struct J3DTevStageInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DIndTevStageInfo {
|
||||
/* 0x0 */ u8 mIndStage;
|
||||
@@ -219,7 +219,7 @@ struct J3DIndTevStageInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTexCoordInfo {
|
||||
/* 0x0 */ u8 mTexGenType;
|
||||
@@ -265,7 +265,7 @@ struct J3DBlendInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevOrderInfo {
|
||||
void operator=(const J3DTevOrderInfo& other) {
|
||||
|
||||
@@ -1403,7 +1403,7 @@ void dMenu_Fmap2DBack_c::regionTextureDraw() {
|
||||
if (uVar10 != uVar9) {
|
||||
bool b = 0;
|
||||
f32 v = mTransX + (dVar14 + (mRegionMinMapX[uVar10] + field_0xf0c[uVar10]));
|
||||
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
b = true;
|
||||
|
||||
@@ -385,7 +385,6 @@ namespace dusk {
|
||||
m_menuTools.ShowSaveEditor();
|
||||
m_menuTools.ShowStateShare();
|
||||
}
|
||||
DuskDebugPad(); // temporary, remove later
|
||||
|
||||
// Hide mouse cursor if the F1 menu is not open and the cursor is idle for 3 seconds.
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -73,8 +73,6 @@ bool ImGuiButtonCenter(std::string_view text);
|
||||
float ImGuiScale();
|
||||
} // namespace dusk
|
||||
|
||||
void DuskDebugPad();
|
||||
|
||||
#if defined(_WIN32) || \
|
||||
(defined(__APPLE__) && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_MACCATALYST) || \
|
||||
(defined(__linux__) && !defined(__ANDROID__))
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#include "m_Do/m_Do_controller_pad.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "ImGuiConsole.hpp"
|
||||
|
||||
void DuskDebugPad() {
|
||||
auto& pad = mDoCPd_c::getCpadInfo(PAD_1);
|
||||
auto KeyFlag = [&](ImGuiKey key, u32 padFlag) {
|
||||
if (ImGui::IsKeyDown(key))
|
||||
pad.mButtonFlags |= padFlag;
|
||||
if (ImGui::IsKeyPressed(key))
|
||||
pad.mPressedButtonFlags |= padFlag;
|
||||
|
||||
};
|
||||
|
||||
KeyFlag(ImGuiKey_K, PAD_BUTTON_A);
|
||||
KeyFlag(ImGuiKey_J, PAD_BUTTON_B);
|
||||
KeyFlag(ImGuiKey_L, PAD_BUTTON_X);
|
||||
KeyFlag(ImGuiKey_I, PAD_BUTTON_Y);
|
||||
KeyFlag(ImGuiKey_H, PAD_BUTTON_START);
|
||||
KeyFlag(ImGuiKey_O, PAD_TRIGGER_Z);
|
||||
KeyFlag(ImGuiKey_Keypad8, PAD_BUTTON_UP);
|
||||
KeyFlag(ImGuiKey_Keypad2, PAD_BUTTON_DOWN);
|
||||
KeyFlag(ImGuiKey_Keypad6, PAD_BUTTON_RIGHT);
|
||||
KeyFlag(ImGuiKey_Keypad4, PAD_BUTTON_LEFT);
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey_W)) {
|
||||
pad.mMainStickPosY = 1.0f;
|
||||
pad.mMainStickValue = 1.0f;
|
||||
pad.mMainStickAngle = 0x8000;
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey_S)) {
|
||||
pad.mMainStickPosY = -1.0f;
|
||||
pad.mMainStickValue = 1.0f;
|
||||
pad.mMainStickAngle = 0;
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey_D)) {
|
||||
pad.mMainStickPosX = 1.0f;
|
||||
pad.mMainStickValue = 1.0f;
|
||||
pad.mMainStickAngle = 0x4000;
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey_A)) {
|
||||
pad.mMainStickPosX = -1.0f;
|
||||
pad.mMainStickValue = 1.0f;
|
||||
pad.mMainStickAngle = -0x4000;
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey_Q)) {
|
||||
pad.mTriggerLeft = 1.0;
|
||||
pad.mTrigLockL = 1;
|
||||
pad.mHoldLockL = 1;
|
||||
}
|
||||
if (ImGui::IsKeyDown(ImGuiKey_E)) {
|
||||
pad.mTriggerRight = 1.0;
|
||||
pad.mTrigLockR = 1;
|
||||
pad.mHoldLockR = 1;
|
||||
}
|
||||
}
|
||||
@@ -899,7 +899,7 @@ constexpr auto eventFlagToAreaFlagFormat(uint16_t eventFlag) -> AreaFlagInd {
|
||||
// so we skip 24 bytes for the first byte, 16 for the second, etc
|
||||
// essentially (3 - (x % 4)), reversing the modulus, 0=3, 1=2
|
||||
const auto bitsToSkip = 8 * ((sizeof(u32) - 1) - (relativeByteInd % sizeof(u32)));
|
||||
const int areaFlag = ((eventU32Ind) << areaIndexSize) |
|
||||
const int areaFlag = ((eventU32Ind) << areaIndexSize) |
|
||||
((std::countr_zero(eventFlag) + bitsToSkip) & makeMask(areaIndexSize));
|
||||
|
||||
return AreaFlagInd{byteIndexToAreaFlagType(byteInd), areaFlag};
|
||||
@@ -3520,4 +3520,4 @@ inline std::map<uint8_t, AreaFlagIter> imguiAreaFlagLookup =
|
||||
{ 0x1B, AreaFlagIter{ eventAreaFlagsGrotto, {} } },
|
||||
};
|
||||
|
||||
#endif // !DUSK_IMGUI_EVENTFLAGS_HPP
|
||||
#endif // !DUSK_IMGUI_EVENTFLAGS_HPP
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <SDL3/SDL_gamepad.h>
|
||||
#include <SDL3/SDL_keyboard.h>
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <array>
|
||||
@@ -17,9 +18,17 @@
|
||||
namespace dusk::ui {
|
||||
namespace {
|
||||
|
||||
bool keyboard_active(int port) {
|
||||
u32 count = 0;
|
||||
return PADGetKeyButtonBindings(static_cast<u32>(port), &count) != nullptr;
|
||||
}
|
||||
|
||||
Rml::String current_controller_name(int port) {
|
||||
const char* name = PADGetName(port);
|
||||
return name == nullptr ? "None" : name;
|
||||
if (name != nullptr) {
|
||||
return name;
|
||||
}
|
||||
return keyboard_active(port) ? "Keyboard" : "None";
|
||||
}
|
||||
|
||||
Rml::String controller_index_name(u32 index) {
|
||||
@@ -202,6 +211,74 @@ bool keyboard_escape_pressed() {
|
||||
return keys != nullptr && SDL_SCANCODE_ESCAPE < keyCount && keys[SDL_SCANCODE_ESCAPE];
|
||||
}
|
||||
|
||||
Rml::String keyboard_key_name(s32 scancode) {
|
||||
if (scancode == PAD_KEY_INVALID) {
|
||||
return "Not bound";
|
||||
}
|
||||
switch (scancode) {
|
||||
case PAD_KEY_MOUSE_LEFT:
|
||||
return "Mouse Left";
|
||||
case PAD_KEY_MOUSE_MIDDLE:
|
||||
return "Mouse Middle";
|
||||
case PAD_KEY_MOUSE_RIGHT:
|
||||
return "Mouse Right";
|
||||
case PAD_KEY_MOUSE_X1:
|
||||
return "Mouse X1";
|
||||
case PAD_KEY_MOUSE_X2:
|
||||
return "Mouse X2";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (scancode < 0) {
|
||||
return "Unknown";
|
||||
}
|
||||
const char* name = SDL_GetScancodeName(static_cast<SDL_Scancode>(scancode));
|
||||
if (name == nullptr || name[0] == '\0') {
|
||||
return "Unknown";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
bool keyboard_neutral() {
|
||||
int keyCount = 0;
|
||||
const bool* keys = SDL_GetKeyboardState(&keyCount);
|
||||
if (keys != nullptr) {
|
||||
for (int i = 0; i < keyCount; ++i) {
|
||||
if (keys[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
float x, y;
|
||||
if (SDL_GetMouseState(&x, &y) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 keyboard_key_pressed() {
|
||||
int keyCount = 0;
|
||||
const bool* keys = SDL_GetKeyboardState(&keyCount);
|
||||
if (keys != nullptr) {
|
||||
for (int i = 1; i < keyCount; ++i) {
|
||||
if (i == SDL_SCANCODE_ESCAPE) {
|
||||
continue;
|
||||
}
|
||||
if (keys[i]) {
|
||||
return static_cast<s32>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
float x, y;
|
||||
const auto mouseButtons = SDL_GetMouseState(&x, &y);
|
||||
for (int btn = 1; btn <= 5; ++btn) {
|
||||
if (mouseButtons & (1u << (btn - 1))) {
|
||||
return -(btn + 1); // maps to PAD_KEY_MOUSE_LEFT (-2), etc.
|
||||
}
|
||||
}
|
||||
return PAD_KEY_INVALID;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ControllerConfigWindow::ControllerConfigWindow() {
|
||||
@@ -311,23 +388,38 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
|
||||
|
||||
switch (page) {
|
||||
case Page::Controller: {
|
||||
const u32 controllerCount = PADCount();
|
||||
if (controllerCount == 0) {
|
||||
pane.add_text("No controllers detected");
|
||||
break;
|
||||
}
|
||||
pane.add_button(
|
||||
{
|
||||
.text = "None",
|
||||
.isSelected =
|
||||
[port] { return PADGetIndexForPort(port) < 0 && !keyboard_active(port); },
|
||||
})
|
||||
.on_pressed([this, port] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
cancel_pending_binding();
|
||||
PADClearPort(port);
|
||||
PADSetKeyboardActive(static_cast<u32>(port), FALSE);
|
||||
PADSerializeMappings();
|
||||
});
|
||||
|
||||
pane.add_button({
|
||||
.text = "None",
|
||||
.isSelected = [port] { return PADGetIndexForPort(port) < 0; },
|
||||
.text = "Keyboard",
|
||||
.isSelected = [port] { return keyboard_active(port); },
|
||||
})
|
||||
.on_pressed([this, port] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
cancel_pending_binding();
|
||||
PADClearPort(port);
|
||||
PADSetKeyboardActive(static_cast<u32>(port), TRUE);
|
||||
PADSerializeMappings();
|
||||
});
|
||||
|
||||
const u32 controllerCount = PADCount();
|
||||
if (controllerCount == 0) {
|
||||
pane.add_text("No controllers detected");
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < controllerCount; ++i) {
|
||||
pane.add_button(
|
||||
{
|
||||
@@ -338,6 +430,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
|
||||
.on_pressed([this, port, i] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
cancel_pending_binding();
|
||||
PADSetKeyboardActive(static_cast<u32>(port), FALSE);
|
||||
PADSetPortForIndex(i, port);
|
||||
PADSerializeMappings();
|
||||
});
|
||||
@@ -345,6 +438,54 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
|
||||
break;
|
||||
}
|
||||
case Page::Buttons: {
|
||||
if (keyboard_active(port)) {
|
||||
auto addKeyButton = [&](PADButton button) {
|
||||
pane.add_select_button(
|
||||
{
|
||||
.key = PADGetButtonName(button),
|
||||
.getValue =
|
||||
[this, port, button] {
|
||||
if (mPendingKeyButton == static_cast<int>(button)) {
|
||||
return pending_key_label();
|
||||
}
|
||||
u32 count = 0;
|
||||
PADKeyButtonBinding* bindings =
|
||||
PADGetKeyButtonBindings(static_cast<u32>(port), &count);
|
||||
if (bindings == nullptr) {
|
||||
return Rml::String("Not bound");
|
||||
}
|
||||
for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) {
|
||||
if (bindings[i].padButton == button) {
|
||||
return keyboard_key_name(bindings[i].scancode);
|
||||
}
|
||||
}
|
||||
return Rml::String("Not bound");
|
||||
},
|
||||
})
|
||||
.on_pressed([this, port, button] {
|
||||
cancel_pending_binding();
|
||||
mPendingPort = port;
|
||||
mPendingBindingArmed = false;
|
||||
mPendingKeyButton = static_cast<int>(button);
|
||||
});
|
||||
};
|
||||
|
||||
pane.add_section("Buttons");
|
||||
addKeyButton(PAD_BUTTON_A);
|
||||
addKeyButton(PAD_BUTTON_B);
|
||||
addKeyButton(PAD_BUTTON_X);
|
||||
addKeyButton(PAD_BUTTON_Y);
|
||||
addKeyButton(PAD_BUTTON_START);
|
||||
addKeyButton(PAD_TRIGGER_Z);
|
||||
|
||||
pane.add_section("D-Pad");
|
||||
addKeyButton(PAD_BUTTON_UP);
|
||||
addKeyButton(PAD_BUTTON_DOWN);
|
||||
addKeyButton(PAD_BUTTON_LEFT);
|
||||
addKeyButton(PAD_BUTTON_RIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
u32 buttonCount = 0;
|
||||
PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount);
|
||||
if (mappings == nullptr) {
|
||||
@@ -407,6 +548,79 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
|
||||
break;
|
||||
}
|
||||
case Page::Triggers: {
|
||||
if (keyboard_active(port)) {
|
||||
auto addKeyButton = [&](PADButton button) {
|
||||
pane.add_select_button(
|
||||
{
|
||||
.key = PADGetButtonName(button),
|
||||
.getValue =
|
||||
[this, port, button] {
|
||||
if (mPendingKeyButton == static_cast<int>(button)) {
|
||||
return pending_key_label();
|
||||
}
|
||||
u32 count = 0;
|
||||
PADKeyButtonBinding* bindings =
|
||||
PADGetKeyButtonBindings(static_cast<u32>(port), &count);
|
||||
if (bindings == nullptr) {
|
||||
return Rml::String("Not bound");
|
||||
}
|
||||
for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) {
|
||||
if (bindings[i].padButton == button) {
|
||||
return keyboard_key_name(bindings[i].scancode);
|
||||
}
|
||||
}
|
||||
return Rml::String("Not bound");
|
||||
},
|
||||
})
|
||||
.on_pressed([this, port, button] {
|
||||
cancel_pending_binding();
|
||||
mPendingPort = port;
|
||||
mPendingBindingArmed = false;
|
||||
mPendingKeyButton = static_cast<int>(button);
|
||||
});
|
||||
};
|
||||
|
||||
auto addKeyAxis = [&](PADAxis axis) {
|
||||
pane.add_select_button(
|
||||
{
|
||||
.key = PADGetAxisName(axis),
|
||||
.getValue =
|
||||
[this, port, axis] {
|
||||
if (mPendingKeyAxis == static_cast<int>(axis)) {
|
||||
return pending_key_label();
|
||||
}
|
||||
u32 count = 0;
|
||||
PADKeyAxisBinding* bindings =
|
||||
PADGetKeyAxisBindings(static_cast<u32>(port), &count);
|
||||
if (bindings == nullptr) {
|
||||
return Rml::String("Not bound");
|
||||
}
|
||||
for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) {
|
||||
if (bindings[i].padAxis == axis) {
|
||||
return keyboard_key_name(bindings[i].scancode);
|
||||
}
|
||||
}
|
||||
return Rml::String("Not bound");
|
||||
},
|
||||
})
|
||||
.on_pressed([this, port, axis] {
|
||||
cancel_pending_binding();
|
||||
mPendingPort = port;
|
||||
mPendingBindingArmed = false;
|
||||
mPendingKeyAxis = static_cast<int>(axis);
|
||||
});
|
||||
};
|
||||
|
||||
pane.add_section("Analog");
|
||||
addKeyAxis(PAD_AXIS_TRIGGER_L);
|
||||
addKeyAxis(PAD_AXIS_TRIGGER_R);
|
||||
|
||||
pane.add_section("Digital");
|
||||
addKeyButton(PAD_TRIGGER_L);
|
||||
addKeyButton(PAD_TRIGGER_R);
|
||||
break;
|
||||
}
|
||||
|
||||
u32 axisCount = 0;
|
||||
PADAxisMapping* axes = PADGetAxisMappings(port, &axisCount);
|
||||
u32 buttonCount = 0;
|
||||
@@ -473,6 +687,52 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
|
||||
break;
|
||||
}
|
||||
case Page::Sticks: {
|
||||
if (keyboard_active(port)) {
|
||||
auto addKeyAxis = [&](PADAxis axis) {
|
||||
pane.add_select_button(
|
||||
{
|
||||
.key = PADGetAxisDirectionLabel(axis),
|
||||
.getValue =
|
||||
[this, port, axis] {
|
||||
if (mPendingKeyAxis == static_cast<int>(axis)) {
|
||||
return pending_key_label();
|
||||
}
|
||||
u32 count = 0;
|
||||
PADKeyAxisBinding* bindings =
|
||||
PADGetKeyAxisBindings(static_cast<u32>(port), &count);
|
||||
if (bindings == nullptr) {
|
||||
return Rml::String("Not bound");
|
||||
}
|
||||
for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) {
|
||||
if (bindings[i].padAxis == axis) {
|
||||
return keyboard_key_name(bindings[i].scancode);
|
||||
}
|
||||
}
|
||||
return Rml::String("Not bound");
|
||||
},
|
||||
})
|
||||
.on_pressed([this, port, axis] {
|
||||
cancel_pending_binding();
|
||||
mPendingPort = port;
|
||||
mPendingBindingArmed = false;
|
||||
mPendingKeyAxis = static_cast<int>(axis);
|
||||
});
|
||||
};
|
||||
|
||||
pane.add_section("Control Stick");
|
||||
addKeyAxis(PAD_AXIS_LEFT_Y_POS);
|
||||
addKeyAxis(PAD_AXIS_LEFT_Y_NEG);
|
||||
addKeyAxis(PAD_AXIS_LEFT_X_NEG);
|
||||
addKeyAxis(PAD_AXIS_LEFT_X_POS);
|
||||
|
||||
pane.add_section("C Stick");
|
||||
addKeyAxis(PAD_AXIS_RIGHT_Y_POS);
|
||||
addKeyAxis(PAD_AXIS_RIGHT_Y_NEG);
|
||||
addKeyAxis(PAD_AXIS_RIGHT_X_NEG);
|
||||
addKeyAxis(PAD_AXIS_RIGHT_X_POS);
|
||||
break;
|
||||
}
|
||||
|
||||
u32 axisCount = 0;
|
||||
PADAxisMapping* axes = PADGetAxisMappings(port, &axisCount);
|
||||
if (axes == nullptr) {
|
||||
@@ -549,6 +809,21 @@ void ControllerConfigWindow::poll_pending_binding() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPendingKeyButton >= 0 || mPendingKeyAxis >= 0) {
|
||||
const s32 scancode = keyboard_key_pressed();
|
||||
if (scancode != PAD_KEY_INVALID) {
|
||||
if (mPendingKeyButton >= 0) {
|
||||
PADSetKeyButtonBinding(static_cast<u32>(mPendingPort),
|
||||
{scancode, static_cast<PADButton>(mPendingKeyButton)});
|
||||
} else {
|
||||
PADSetKeyAxisBinding(static_cast<u32>(mPendingPort),
|
||||
{scancode, static_cast<PADAxis>(mPendingKeyAxis), 0});
|
||||
}
|
||||
finish_pending_key_binding();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPendingButtonMapping != nullptr) {
|
||||
const s32 nativeButton = PADGetNativeButtonPressed(mPendingPort);
|
||||
if (nativeButton != -1) {
|
||||
@@ -590,26 +865,40 @@ void ControllerConfigWindow::finish_pending_binding(int completedPort) {
|
||||
}
|
||||
|
||||
void ControllerConfigWindow::unmap_pending_binding() {
|
||||
if (mPendingButtonMapping == nullptr && mPendingAxisMapping == nullptr) {
|
||||
if (mPendingButtonMapping == nullptr && mPendingAxisMapping == nullptr &&
|
||||
mPendingKeyButton < 0 && mPendingKeyAxis < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int completedPort = mPendingPort;
|
||||
if (mPendingButtonMapping != nullptr) {
|
||||
mPendingButtonMapping->nativeButton = PAD_NATIVE_BUTTON_INVALID;
|
||||
}
|
||||
if (mPendingAxisMapping != nullptr) {
|
||||
finish_pending_binding(completedPort);
|
||||
} else if (mPendingAxisMapping != nullptr) {
|
||||
mPendingAxisMapping->nativeAxis = {-1, AXIS_SIGN_POSITIVE};
|
||||
mPendingAxisMapping->nativeButton = -1;
|
||||
finish_pending_binding(completedPort);
|
||||
} else if (mPendingKeyButton >= 0) {
|
||||
PADSetKeyButtonBinding(static_cast<u32>(completedPort),
|
||||
{PAD_KEY_INVALID, static_cast<PADButton>(mPendingKeyButton)});
|
||||
finish_pending_key_binding();
|
||||
} else if (mPendingKeyAxis >= 0) {
|
||||
PADSetKeyAxisBinding(static_cast<u32>(completedPort),
|
||||
{PAD_KEY_INVALID, static_cast<PADAxis>(mPendingKeyAxis), 0});
|
||||
finish_pending_key_binding();
|
||||
}
|
||||
finish_pending_binding(completedPort);
|
||||
}
|
||||
|
||||
bool ControllerConfigWindow::capture_active() const {
|
||||
return mPendingButtonMapping != nullptr || mPendingAxisMapping != nullptr;
|
||||
return mPendingButtonMapping != nullptr || mPendingAxisMapping != nullptr ||
|
||||
mPendingKeyButton >= 0 || mPendingKeyAxis >= 0;
|
||||
}
|
||||
|
||||
bool ControllerConfigWindow::pending_input_neutral() const {
|
||||
if (mPendingKeyButton >= 0 || mPendingKeyAxis >= 0) {
|
||||
return keyboard_neutral();
|
||||
}
|
||||
return input_neutral(mPendingPort);
|
||||
}
|
||||
|
||||
@@ -623,16 +912,30 @@ Rml::String ControllerConfigWindow::pending_axis_label() const {
|
||||
|
||||
void ControllerConfigWindow::cancel_pending_binding() {
|
||||
if (mPendingButtonMapping == nullptr && mPendingAxisMapping == nullptr &&
|
||||
!mSuppressNavigationUntilNeutral)
|
||||
!mSuppressNavigationUntilNeutral && mPendingKeyButton < 0 && mPendingKeyAxis < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mPendingButtonMapping = nullptr;
|
||||
mPendingAxisMapping = nullptr;
|
||||
mPendingKeyButton = -1;
|
||||
mPendingKeyAxis = -1;
|
||||
mPendingPort = -1;
|
||||
mPendingBindingArmed = false;
|
||||
mSuppressNavigationUntilNeutral = false;
|
||||
mSuppressNavigationPort = -1;
|
||||
}
|
||||
|
||||
void ControllerConfigWindow::finish_pending_key_binding() {
|
||||
mPendingKeyButton = -1;
|
||||
mPendingKeyAxis = -1;
|
||||
mPendingPort = -1;
|
||||
mPendingBindingArmed = false;
|
||||
PADSerializeMappings();
|
||||
}
|
||||
|
||||
Rml::String ControllerConfigWindow::pending_key_label() const {
|
||||
return mPendingBindingArmed ? "Press a key or mouse button..." : "Waiting...";
|
||||
}
|
||||
|
||||
} // namespace dusk::ui
|
||||
|
||||
@@ -32,6 +32,8 @@ private:
|
||||
Rml::String pending_button_label() const;
|
||||
Rml::String pending_axis_label() const;
|
||||
void cancel_pending_binding();
|
||||
void finish_pending_key_binding();
|
||||
Rml::String pending_key_label() const;
|
||||
|
||||
Page mPage = Page::Controller;
|
||||
Pane* mRightPane = nullptr;
|
||||
@@ -42,6 +44,8 @@ private:
|
||||
int mSuppressNavigationPort = -1;
|
||||
PADButtonMapping* mPendingButtonMapping = nullptr;
|
||||
PADAxisMapping* mPendingAxisMapping = nullptr;
|
||||
int mPendingKeyButton = -1;
|
||||
int mPendingKeyAxis = -1;
|
||||
};
|
||||
|
||||
} // namespace dusk::ui
|
||||
|
||||
@@ -187,8 +187,9 @@ void Overlay::update() {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool showControllerWarning =
|
||||
PADGetIndexForPort(PAD_CHAN0) < 0 && dynamic_cast<Window*>(top_document()) == nullptr;
|
||||
const bool showControllerWarning = PADGetIndexForPort(PAD_CHAN0) < 0 &&
|
||||
PADGetKeyButtonBindings(PAD_CHAN0, nullptr) == nullptr &&
|
||||
dynamic_cast<Window*>(top_document()) == nullptr;
|
||||
if (showControllerWarning && mControllerWarning == nullptr) {
|
||||
mControllerWarning = create_controller_warning(mDocument);
|
||||
} else if (showControllerWarning && mControllerWarning != nullptr) {
|
||||
|
||||
@@ -280,7 +280,6 @@ void main01(void) {
|
||||
for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) {
|
||||
dusk::frame_interp::begin_sim_tick();
|
||||
mDoCPd_c::read();
|
||||
DuskDebugPad();
|
||||
dusk::gyro::read(pacing.sim_pace);
|
||||
fapGm_Execute();
|
||||
mDoAud_Execute();
|
||||
|
||||
Reference in New Issue
Block a user