Skip to content

Commit

Permalink
Input updates and misc tweaks
Browse files Browse the repository at this point in the history
* Imagine: Add support for mapping buffer ranges in Gfx::Buffer
* Imagine: Add support for custom BufferDeleter size in Buffer
* Imagine: Add Gfx::FanQuad classes
* Imagine: Simplify setPos() overloads in Gfx::BaseQuad
* Imagine: Don't handle Gas/Break analog triggers on Android if joystick already has L/R triggers
* Imagine: Simplify input sub-type handling by mapping more devices as generic gamepads
* Imagine: Remove unneeded Xbox 360 DPad key code remapping since it causes double events due to the DPad acting as joystick
* EmuFramework: Refactor common code into BaseVControllerButtonGroup
* EmuFramework: Make DPad corner lighting consistent using FanQuad
* EmuFramework: Show a grid when setting snap value to 16 and above
* EmuFramework: Batch quads when rendering button groups
* EmuFramework: Pass index buffers into VController elements
* EmuFramework: Ignore L/R analog triggers in ButtonConfigSetView if L2/R2 are already pushed
* EmuFramework: Remove 8BitDo gamepad mappings and instead rely on the generic gamepad profile
* EmuFramework: Fix iCade mode not saving from previous commit
* EmuFramework: Fix RewindManager::rewindState() array indexing at 0
* NES.emu: Fix crash on loadContent() if FDS failed loading previously
* NES.emu: Add key binding to Eject Disk/Switch Side for FDS content
  • Loading branch information
Robert Broglia committed Nov 25, 2023
1 parent ce75bd1 commit aa98fce
Show file tree
Hide file tree
Showing 35 changed files with 645 additions and 331 deletions.
89 changes: 64 additions & 25 deletions EmuFramework/include/emuframework/VController.hh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <imagine/input/DragTracker.hh>
#include <imagine/gfx/Texture.hh>
#include <imagine/gfx/Quads.hh>
#include <imagine/gfx/FanQuads.hh>
#include <imagine/util/variant.hh>
#include <vector>
#include <span>
Expand Down Expand Up @@ -114,7 +115,7 @@ public:
}

protected:
Gfx::ILitTexQuads spriteQuads;
Gfx::ILitTexFanQuads spriteQuads;
Gfx::TextureSpan tex;
Gfx::Texture mapImg;
WRect padBaseArea, padArea;
Expand Down Expand Up @@ -187,42 +188,67 @@ public:
constexpr VControllerButton(KeyInfo key): key{key} {}
void setPos(WPt pos, WRect viewBounds, _2DOrigin = C2DO);
void setSize(WSize size, WSize extendedSize = {});
void setImage(Gfx::RendererTask &, Gfx::TextureSpan, int aR = 1);
void setImage(Gfx::TextureSpan, int aR = 1);
WRect bounds() const { return bounds_; }
WRect realBounds() const { return extendedBounds_; }
void drawBounds(Gfx::RendererCommands &__restrict__) const;
void drawSprite(Gfx::RendererCommands &__restrict__) const;
std::string name(const EmuApp &) const;
bool overlaps(WPt windowPos) const { return enabled && realBounds().overlaps(windowPos); }
void setAlpha(float alpha);

void updateColor(Gfx::Color c, float alpha)
void setAlpha(float alpha, auto &container)
{
color = c;
setAlpha(alpha);
container.updateSprite(*this);
}

void updateColor(Gfx::Color c, float alpha, auto &container)
{
color = c;
setAlpha(alpha, container);
}

void updateSprite(auto &quads)
{
Gfx::ILitTexQuad({.bounds = bounds_.as<int16_t>(), .color = spriteColor, .textureSpan = texture}).write(quads, spriteIdx);
}

void updateSprite(auto &quads, auto &boundQuads)
{
updateSprite(quads);
float brightness = isHighlighted ? 2.f : 1.f;
Gfx::IColQuad({.bounds = extendedBounds_.as<int16_t>(), .color = Gfx::Color{.5f}.multiplyRGB(brightness)}).write(boundQuads, spriteIdx);
}

protected:
Gfx::ILitTexQuads quad;
Gfx::IQuads boundQuads;
Gfx::TextureSpan texture;
protected:
Gfx::Color spriteColor;
WRect bounds_{};
WRect extendedBounds_{};
int aspectRatio{1};

void updateSprite();
public:
Gfx::Color color{};
KeyInfo key{};
bool enabled = true;
uint8_t spriteIdx{};
bool enabled{true};
bool skipLayout{};
bool isHighlighted{};
};

class VControllerButtonGroup
template<class Group>
class BaseVControllerButtonGroup
{
public:
void drawButtons(Gfx::RendererCommands &__restrict__) const;
void updateSprites();
void updateSprite(VControllerButton &);
void setAlpha(float alpha);
};

class VControllerButtonGroup : public BaseVControllerButtonGroup<VControllerButtonGroup>
{
public:
friend class BaseVControllerButtonGroup<VControllerButtonGroup>;

struct LayoutConfig
{
int8_t rowItems{1};
Expand Down Expand Up @@ -260,12 +286,11 @@ public:
WRect realBounds() const { return bounds() + paddingRect(); }
int rows() const;
std::array<KeyInfo, 2> findButtonIndices(WPt windowPos) const;
void drawButtons(Gfx::RendererCommands &__restrict__) const;
void drawBounds(Gfx::RendererCommands &__restrict__) const;
std::string name(const EmuApp &) const;
void updateMeasurements(const Window &win);
void transposeKeysForPlayer(const EmuApp &, int player);
void setAlpha(float alpha) { for(auto &b : buttons) { b.setAlpha(alpha); } }
void setTask(Gfx::RendererTask &task) { quads.setTask(task); boundQuads.setTask(task); }

static size_t layoutConfigSize()
{
Expand All @@ -285,7 +310,10 @@ public:

std::vector<VControllerButton> buttons;
protected:
Gfx::ILitTexQuads quads;
Gfx::IColQuads boundQuads;
WRect bounds_;
int enabledBtns{};
int btnSize{};
int spacingPixels{};
int16_t btnStagger{};
Expand All @@ -294,9 +322,11 @@ public:
LayoutConfig layout{};
};

class VControllerUIButtonGroup
class VControllerUIButtonGroup : public BaseVControllerButtonGroup<VControllerUIButtonGroup>
{
public:
friend class BaseVControllerButtonGroup<VControllerUIButtonGroup>;

struct LayoutConfig
{
int8_t rowItems{1};
Expand All @@ -320,9 +350,8 @@ public:
auto bounds() const { return bounds_; }
WRect realBounds() const { return bounds(); }
int rows() const;
void drawButtons(Gfx::RendererCommands &__restrict__) const;
std::string name(const EmuApp &) const;
void setAlpha(float alpha) { for(auto &b : buttons) { b.setAlpha(alpha); } }
void setTask(Gfx::RendererTask &task) { quads.setTask(task); }

static size_t layoutConfigSize()
{
Expand All @@ -337,7 +366,9 @@ public:

std::vector<VControllerButton> buttons;
protected:
Gfx::ILitTexQuads quads;
WRect bounds_{};
int enabledBtns{};
int btnSize{};
public:
LayoutConfig layout{};
Expand Down Expand Up @@ -397,12 +428,6 @@ public:
}, *this);
}

void draw(Gfx::RendererCommands &__restrict__ cmds, bool showHidden) const
{
drawBounds(cmds, showHidden);
drawButtons(cmds, showHidden);
}

void place(WRect viewBounds, WRect windowBounds, int layoutIdx)
{
auto &lPos = layoutPos[layoutIdx];
Expand Down Expand Up @@ -507,6 +532,15 @@ public:
return 1;
}, *this);
}

void updateSprite(VControllerButton &b)
{
visit([&](auto &e)
{
if constexpr(requires {e.updateSprite(b);})
e.updateSprite(b);
}, *this);
}
};

enum class VControllerVisibility : uint8_t
Expand Down Expand Up @@ -549,6 +583,7 @@ public:
bool pointerInputEvent(const Input::MotionEvent &, WindowRect gameRect);
bool keyInput(const Input::KeyEvent &);
void draw(Gfx::RendererCommands &__restrict__, bool showHidden = false);
void draw(Gfx::RendererCommands &__restrict__, const VControllerElement &elem, bool showHidden = false) const;
bool isInKeyboardMode() const;
void setKeyboardImage(Gfx::TextureSpan img);
void setButtonAlpha(std::optional<uint8_t>);
Expand Down Expand Up @@ -581,7 +616,7 @@ public:
bool updateAutoOnScreenControlVisible();
bool readConfig(EmuApp &, MapIO &, unsigned key, size_t size);
void writeConfig(FileIO &) const;
void configure(Window &, Gfx::Renderer &, const Gfx::GlyphTextureSet &face);
void configure(Window &, Gfx::Renderer &, const Gfx::GlyphTextureSet &face, const Gfx::IndexBuffer<uint8_t> &quadIdxs);
void resetEmulatedDevicePositions();
void resetEmulatedDeviceGroups();
void resetUIPositions();
Expand Down Expand Up @@ -610,6 +645,9 @@ private:
const Window *win{};
const WindowData *winData{};
const Gfx::GlyphTextureSet *facePtr{};
const Gfx::IndexBuffer<uint8_t> *quadIdxsPtr{};
Gfx::IndexBuffer<uint8_t> fanQuadIdxs;
Gfx::TextureBinding gamepadTex, uiTex;
VControllerKeyboard kb;
std::vector<VControllerElement> gpElements{};
std::vector<VControllerElement> uiElements{};
Expand Down Expand Up @@ -646,6 +684,7 @@ private:
int uiButtonPixelSize() const;
void writeDeviceButtonsConfig(FileIO &) const;
void writeUIButtonsConfig(FileIO &) const;
void setIndexArray(Gfx::RendererCommands &__restrict__, const VControllerElement &) const;
};

}
3 changes: 2 additions & 1 deletion EmuFramework/include/emuframework/VideoImageOverlay.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ private:
glm::i16vec2 pos;
glm::vec2 texCoord;
};
using Quads = Gfx::BaseQuads<Vertex>;
using Quad = Gfx::BaseQuad<Vertex>;
using Quads = Gfx::ObjectVertexBuffer<Quad>;

Quads quad;
Gfx::Texture texture;
Expand Down
20 changes: 2 additions & 18 deletions EmuFramework/include/emuframework/keyRemappingUtils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,6 @@ constexpr Input::Key genericGamepadKeycodeToOuya(Input::Key k)
default: return k;
}
}

constexpr Input::Key genericGamepadKeycodeToBitdo(Input::Key k)
{
using namespace Input;
switch(k)
{
case Keycode::GAME_A: return Keycode::GAME_B;
case Keycode::GAME_B: return Keycode::GAME_A;
case Keycode::GAME_X: return Keycode::GAME_Y;
case Keycode::GAME_Y: return Keycode::GAME_X;
default: return k;
}
}
#endif

#if defined(__ANDROID__) && __ARM_ARCH == 7
Expand Down Expand Up @@ -247,7 +234,6 @@ constexpr std::span<const KeyConfigDesc> genericKeyConfigs()
static constexpr auto genericGamepadMap = concatToArrayNow<genericGamepadAppKeyCodeMap, genericGamepadBaseMap>;
static constexpr auto ps3GamepadMap = transformMappedKeys(genericGamepadMap, genericGamepadKeycodeToPS3HID);
static constexpr auto ouyaGamepadMap = transformMappedKeys(genericGamepadMap, genericGamepadKeycodeToOuya);
static constexpr auto eightBitdoGamepadMap = transformMappedKeys(genericGamepadMap, genericGamepadKeycodeToBitdo);
#endif

#if defined(__ANDROID__) && __ARM_ARCH == 7
Expand Down Expand Up @@ -275,17 +261,15 @@ constexpr std::span<const KeyConfigDesc> genericKeyConfigs()
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::GENERIC_GAMEPAD, "Generic Gamepad", genericGamepadMap},
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::PS3_CONTROLLER, "PS3 Controller", ps3GamepadMap},
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::OUYA_CONTROLLER, "OUYA Controller", ouyaGamepadMap},
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::_8BITDO_SF30_PRO, "8Bitdo SF30 Pro", eightBitdoGamepadMap},
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::_8BITDO_SN30_PRO_PLUS, "8BitDo SN30 Pro+", eightBitdoGamepadMap},
#endif
#if defined(__ANDROID__) && __ARM_ARCH == 7
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::XPERIA_PLAY, "Xperia Play", xperiaPlayGamepadMap},
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::XPERIA_PLAY, "Xperia Play", xperiaPlayGamepadMap},
#endif
#ifdef CONFIG_MACHINE_PANDORA
KeyConfigDesc{Map::SYSTEM, DeviceSubtype::PANDORA_HANDHELD, "Pandora Keys", pandoraKeysMap},
#endif
#ifdef CONFIG_INPUT_APPLE_GAME_CONTROLLER
KeyConfigDesc{Map::APPLE_GAME_CONTROLLER,"Default", appleGamepadMap},
KeyConfigDesc{Map::APPLE_GAME_CONTROLLER, "Default", appleGamepadMap},
#endif
#ifdef CONFIG_INPUT_BLUETOOTH
KeyConfigDesc{Map::WIIMOTE, "Default", wiimoteMap},
Expand Down
2 changes: 1 addition & 1 deletion EmuFramework/src/EmuApp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ void EmuApp::mainInitCommon(IG::ApplicationInitParams initParams, IG::Applicatio
win.setAcceptDnd(true);
renderer.setWindowValidOrientations(win, menuOrientation());
inputManager.updateInputDevices(ctx);
vController.configure(win, renderer, viewManager.defaultFace);
vController.configure(win, renderer, viewManager.defaultFace, viewManager.quadIndices);
if(EmuSystem::inputHasKeyboard)
{
vController.setKeyboardImage(asset(AssetID::keyboardOverlay));
Expand Down
8 changes: 5 additions & 3 deletions EmuFramework/src/RewindManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,20 @@ bool RewindManager::reset()

void RewindManager::saveState(EmuApp &app)
{
assert(maxStates);
assumeExpr(maxStates);
assumeExpr(stateIdx < maxStates);
//log.debug("saving rewind state index:{}", stateIdx);
auto &entry = stateEntries[stateIdx];
stateIdx = stateIdx + 1 == maxStates ? 0 : stateIdx + 1;
entry.size = app.writeState({entry.data, stateSize}, {.uncompressed = true});
stateIdx = (stateIdx + 1) % maxStates;
}

void RewindManager::rewindState(EmuApp &app)
{
if(!maxStates)
return;
auto prevIdx = (stateIdx - 1) % maxStates;
assumeExpr(stateIdx < maxStates);
auto prevIdx = stateIdx ? stateIdx - 1 : maxStates - 1;
auto &entry = stateEntries[prevIdx];
if(!entry.size)
return;
Expand Down
15 changes: 12 additions & 3 deletions EmuFramework/src/gui/ButtonConfigView.cc
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void ButtonConfigSetView::initPointerUI()
void ButtonConfigSetView::place()
{
text.compile(renderer(), {.alignment = Gfx::TextAlignment::center});
using Quad = decltype(quads)::Quad;
using Quad = decltype(quads)::Type;
auto map = quads.map();
Quad{{.bounds = viewRect().as<int16_t>()}}.write(map, 0);
if(pointerUIIsInit())
Expand Down Expand Up @@ -278,15 +278,24 @@ bool ButtonConfigSetView::inputEvent(const Input::Event &e)
}
return true;
}
if(contains(pushedKeys, keyEv.mapKey()))
{
return true;
}
if((contains(pushedKeys, Input::Keycode::GAME_L2) || contains(pushedKeys, Input::Keycode::GAME_R2)) &&
(keyEv.mapKey() == Input::Keycode::JS_LTRIGGER_AXIS || keyEv.mapKey() == Input::Keycode::JS_RTRIGGER_AXIS))
{
log.info("ignoring trigger axis to avoid duplicate events since L2/R2 keys are pushed");
return true;
}
pushedKeys.tryPushBack(keyEv.mapKey());
return true;
}
else if(keyEv.released())
{
if(pushedKeys.size())
finalize();
}
return false;
return true;
}
}, e);
}
Expand Down
1 change: 1 addition & 0 deletions EmuFramework/src/gui/InputManagerView.cc
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ void InputManagerDeviceView::onShow()
void InputManagerDeviceView::confirmICadeMode()
{
devConf.setICadeMode(iCadeMode.flipBoolValue(*this));
devConf.save(inputManager);
onShow();
app().defaultVController().setPhysicalControlsPresent(appContext().keyInputIsPresent());
}
Expand Down

0 comments on commit aa98fce

Please sign in to comment.