more input implementation

This commit is contained in:
Jack Andersen 2015-08-28 15:30:47 -10:00
parent ce42cdd3be
commit 7223a9dce5
22 changed files with 526 additions and 136 deletions

View File

@ -9,4 +9,5 @@ add_library(DNACommon
TXTR.hpp TXTR.cpp TXTR.hpp TXTR.cpp
ANCS.hpp ANCS.hpp
ANIM.hpp ANIM.cpp ANIM.hpp ANIM.cpp
Tweaks/ITweakPlayer.hpp
Tweaks/ITweakPlayerControl.hpp) Tweaks/ITweakPlayerControl.hpp)

View File

@ -0,0 +1,17 @@
#ifndef __DNACOMMON_ITWEAKPLAYER_HPP__
#define __DNACOMMON_ITWEAKPLAYER_HPP__
#include "../DNACommon.hpp"
namespace Retro
{
struct ITweakPlayer : BigYAML
{
virtual float GetLeftLogicalThreshold() const=0;
virtual float GetRightLogicalThreshold() const=0;
};
}
#endif // __DNACOMMON_ITWEAKPLAYER_HPP__

View File

@ -10,6 +10,7 @@ make_dnalist(liblist
CMDLMaterials CMDLMaterials
MREA MREA
Tweaks/CTweakParticle Tweaks/CTweakParticle
Tweaks/CTweakPlayer
Tweaks/CTweakPlayerControl) Tweaks/CTweakPlayerControl)
add_library(DNAMP1 add_library(DNAMP1
DNAMP1.hpp DNAMP1.cpp DNAMP1.hpp DNAMP1.cpp

View File

@ -0,0 +1,24 @@
#ifndef _DNAMP1_CTWEAKPLAYER_HPP_
#define _DNAMP1_CTWEAKPLAYER_HPP_
#include "../../DNACommon/Tweaks/ITweakPlayer.hpp"
namespace Retro
{
namespace DNAMP1
{
struct CTweakPlayer : ITweakPlayer
{
DECL_YAML
Value<float> m_leftDiv;
Value<float> m_rightDiv;
float GetLeftLogicalThreshold() const {return m_leftDiv;}
float GetRightLogicalThreshold() const {return m_rightDiv;}
CTweakPlayer(Athena::io::IStreamReader& reader) {this->read(reader);}
};
}
}
#endif // _DNAMP1_CTWEAKPLAYER_HPP_

@ -1 +1 @@
Subproject commit 2e3512b80098eb0c3facd4fd3ab6433fe424c4f7 Subproject commit 151b0e63338a8f8645f908e48fb7423795224690

View File

@ -11,7 +11,8 @@ class CIOWin;
enum EArchMsgTarget enum EArchMsgTarget
{ {
TargetIOWinManager = 0 TargetIOWinManager = 0,
TargetGame = 1
}; };
enum EArchMsgType enum EArchMsgType

View File

@ -1,5 +1,6 @@
#include "CIOWinManager.hpp" #include "CIOWinManager.hpp"
#include "CArchitectureMessage.hpp" #include "CArchitectureMessage.hpp"
#include "CIOWin.hpp"
namespace Retro namespace Retro
{ {

View File

@ -13,6 +13,7 @@ extern class CGameState* g_GameState;
extern class CInGameTweakManagerBase* g_TweakManager; extern class CInGameTweakManagerBase* g_TweakManager;
extern class CBooRenderer* g_Renderer; extern class CBooRenderer* g_Renderer;
extern class ITweakPlayer* g_tweakPlayer;
extern class ITweakPlayerControl* g_tweakPlayerControl; extern class ITweakPlayerControl* g_tweakPlayerControl;
} }

View File

@ -1,15 +0,0 @@
#ifndef __RETRO_CDOLPHINCONTROLLER_HPP__
#define __RETRO_CDOLPHINCONTROLLER_HPP__
#include "IController.hpp"
namespace Retro
{
class CDolphinController : public IController
{
};
}
#endif // __RETRO_CDOLPHINCONTROLLER_HPP__

View File

@ -1,8 +1,250 @@
#include <Math.hpp>
#include "CFinalInput.hpp" #include "CFinalInput.hpp"
namespace Retro namespace Retro
{ {
CFinalInput::CFinalInput()
: x0_dt(0.0),
x4_controllerIdx(0),
x8_anaLeftX(0.0),
xc_anaLeftY(0.0),
x10_anaRightX(0.0),
x14_anaRightY(0.0),
x18_anaLeftTrigger(0.0),
x1c_anaRightTrigger(0.0),
x20_enableAnaLeftXP(false),
x20_enableAnaLeftNegXP(false),
x21_enableAnaLeftYP(false),
x21_enableAnaLeftNegYP(false),
x22_enableAnaRightXP(false),
x22_enableAnaRightNegXP(false),
x23_enableAnaRightYP(false),
x23_enableAnaRightNegYP(false),
x24_anaLeftTriggerP(false),
x28_anaRightTriggerP(false),
x2c_b24_A(false),
x2c_b25_B(false),
x2c_b26_X(false),
x2c_b27_Y(false),
x2c_b28_Z(false),
x2c_b29_L(false),
x2c_b30_R(false),
x2c_b31_DPUp(false),
x2d_b24_DPRight(false),
x2d_b25_DPDown(false),
x2d_b26_DPLeft(false),
x2d_b27_Start(false),
x2d_b28_PA(false),
x2d_b29_PB(false),
x2d_b30_PX(false),
x2d_b31_PY(false),
x2e_b24_PZ(false),
x2e_b25_PL(false),
x2e_b26_PR(false),
x2e_b27_PDPUp(false),
x2e_b28_PDPRight(false),
x2e_b29_PDPDown(false),
x2e_b30_PDPLeft(false),
x2e_b31_PStart(false) {}
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(Math::clamp<float>(-1.0, data.m_leftStick[0] / 72.0 / leftDiv, 1.0)),
xc_anaLeftY(Math::clamp<float>(-1.0, data.m_leftStick[1] / 72.0 / leftDiv, 1.0)),
x10_anaRightX(Math::clamp<float>(-1.0, data.m_rightStick[0] / 59.0 / rightDiv, 1.0)),
x14_anaRightY(Math::clamp<float>(-1.0, data.m_rightStick[0] / 59.0 / rightDiv, 1.0)),
x18_anaLeftTrigger(data.m_analogTriggers[0] * 0.0066666668),
x1c_anaRightTrigger(data.m_analogTriggers[1] * 0.0066666668),
x20_enableAnaLeftXP(DLARight() && !prevInput.DLARight()),
x20_enableAnaLeftNegXP(DLALeft() && !prevInput.DLALeft()),
x21_enableAnaLeftYP(DLAUp() && !prevInput.DLAUp()),
x21_enableAnaLeftNegYP(DLADown() && !prevInput.DLADown()),
x22_enableAnaRightXP(DRARight() && !prevInput.DRARight()),
x22_enableAnaRightNegXP(DRALeft() && !prevInput.DRALeft()),
x23_enableAnaRightYP(DRAUp() && !prevInput.DRAUp()),
x23_enableAnaRightNegYP(DRADown() && !prevInput.DRADown()),
x24_anaLeftTriggerP(DLTrigger() && !prevInput.DLTrigger()),
x28_anaRightTriggerP(DRTrigger() && !prevInput.DRTrigger()),
x2c_b24_A(data.m_btns & boo::DOL_A),
x2c_b25_B(data.m_btns & boo::DOL_B),
x2c_b26_X(data.m_btns & boo::DOL_X),
x2c_b27_Y(data.m_btns & boo::DOL_Y),
x2c_b28_Z(data.m_btns & boo::DOL_Z),
x2c_b29_L(data.m_btns & boo::DOL_L),
x2c_b30_R(data.m_btns & boo::DOL_R),
x2c_b31_DPUp(data.m_btns & boo::DOL_UP),
x2d_b24_DPRight(data.m_btns & boo::DOL_RIGHT),
x2d_b25_DPDown(data.m_btns & boo::DOL_DOWN),
x2d_b26_DPLeft(data.m_btns & boo::DOL_LEFT),
x2d_b27_Start(data.m_btns & boo::DOL_START),
x2d_b28_PA(DA() && !prevInput.DA()),
x2d_b29_PB(DB() && !prevInput.DB()),
x2d_b30_PX(DX() && !prevInput.DX()),
x2d_b31_PY(DY() && !prevInput.DY()),
x2e_b24_PZ(DZ() && !prevInput.DZ()),
x2e_b25_PL(DL() && !prevInput.DL()),
x2e_b26_PR(DR() && !prevInput.DR()),
x2e_b27_PDPUp(DDPUp() && !prevInput.DDPUp()),
x2e_b28_PDPRight(DDPRight() && !prevInput.DDPRight()),
x2e_b29_PDPDown(DDPDown() && !prevInput.DDPDown()),
x2e_b30_PDPLeft(DDPLeft() && !prevInput.DDPLeft()),
x2e_b31_PStart(DStart() && !prevInput.DStart()) {}
static float KBToAnaLeftX(const CKeyboardMouseControllerData& data)
{
float retval = 0.0;
if (data.m_charKeys['a'])
retval -= 1.0;
if (data.m_charKeys['d'])
retval += 1.0;
return retval;
}
static float KBToAnaLeftY(const CKeyboardMouseControllerData& data)
{
float retval = 0.0;
if (data.m_charKeys['s'])
retval -= 1.0;
if (data.m_charKeys['w'])
retval += 1.0;
return retval;
}
static float KBToAnaRightX(const CKeyboardMouseControllerData& data)
{
float retval = 0.0;
if (data.m_charKeys['2'])
retval -= 1.0;
if (data.m_charKeys['4'])
retval += 1.0;
return retval;
}
static float KBToAnaRightY(const CKeyboardMouseControllerData& data)
{
float retval = 0.0;
if (data.m_charKeys['3'])
retval -= 1.0;
if (data.m_charKeys['1'])
retval += 1.0;
return retval;
}
CFinalInput::CFinalInput(int cIdx, float dt,
const CKeyboardMouseControllerData& data,
const CFinalInput& prevInput)
: x0_dt(dt),
x4_controllerIdx(cIdx),
x8_anaLeftX(KBToAnaLeftX(data)),
xc_anaLeftY(KBToAnaLeftY(data)),
x10_anaRightX(KBToAnaRightX(data)),
x14_anaRightY(KBToAnaRightY(data)),
x18_anaLeftTrigger(data.m_charKeys['q'] ? 1.0 : 0.0),
x1c_anaRightTrigger(data.m_charKeys['e'] ? 1.0 : 0.0),
x20_enableAnaLeftXP(DLARight() && !prevInput.DLARight()),
x20_enableAnaLeftNegXP(DLALeft() && !prevInput.DLALeft()),
x21_enableAnaLeftYP(DLAUp() && !prevInput.DLAUp()),
x21_enableAnaLeftNegYP(DLADown() && !prevInput.DLADown()),
x22_enableAnaRightXP(DRARight() && !prevInput.DRARight()),
x22_enableAnaRightNegXP(DRALeft() && !prevInput.DRALeft()),
x23_enableAnaRightYP(DRAUp() && !prevInput.DRAUp()),
x23_enableAnaRightNegYP(DRADown() && !prevInput.DRADown()),
x24_anaLeftTriggerP(DLTrigger() && !prevInput.DLTrigger()),
x28_anaRightTriggerP(DRTrigger() && !prevInput.DRTrigger()),
x2c_b24_A(data.m_mouseButtons[boo::IWindowCallback::BUTTON_PRIMARY]),
x2c_b25_B(data.m_charKeys[' ']),
x2c_b26_X(data.m_charKeys['c']),
x2c_b27_Y(data.m_mouseButtons[boo::IWindowCallback::BUTTON_SECONDARY]),
x2c_b28_Z(data.m_charKeys['\t']),
x2c_b29_L(data.m_charKeys['q']),
x2c_b30_R(data.m_charKeys['e']),
x2c_b31_DPUp(data.m_specialKeys[boo::IWindowCallback::KEY_UP]),
x2d_b24_DPRight(data.m_specialKeys[boo::IWindowCallback::KEY_RIGHT]),
x2d_b25_DPDown(data.m_specialKeys[boo::IWindowCallback::KEY_DOWN]),
x2d_b26_DPLeft(data.m_specialKeys[boo::IWindowCallback::KEY_LEFT]),
x2d_b27_Start(data.m_specialKeys[boo::IWindowCallback::KEY_ESC]),
x2d_b28_PA(DA() && !prevInput.DA()),
x2d_b29_PB(DB() && !prevInput.DB()),
x2d_b30_PX(DX() && !prevInput.DX()),
x2d_b31_PY(DY() && !prevInput.DY()),
x2e_b24_PZ(DZ() && !prevInput.DZ()),
x2e_b25_PL(DL() && !prevInput.DL()),
x2e_b26_PR(DR() && !prevInput.DR()),
x2e_b27_PDPUp(DDPUp() && !prevInput.DDPUp()),
x2e_b28_PDPRight(DDPRight() && !prevInput.DDPRight()),
x2e_b29_PDPDown(DDPDown() && !prevInput.DDPDown()),
x2e_b30_PDPLeft(DDPLeft() && !prevInput.DDPLeft()),
x2e_b31_PStart(DStart() && !prevInput.DStart())
{
if (x8_anaLeftX || xc_anaLeftY)
{
float len = sqrtf(x8_anaLeftX * x8_anaLeftX + xc_anaLeftY * xc_anaLeftY);
x8_anaLeftX /= len;
xc_anaLeftY /= len;
}
if (x10_anaRightX || x14_anaRightY)
{
float len = sqrtf(x10_anaRightX * x10_anaRightX + x14_anaRightY * x14_anaRightY);
x10_anaRightX /= len;
x14_anaRightY /= len;
}
}
CFinalInput& CFinalInput::operator|=(const CFinalInput& other)
{
if (fabsf(other.x8_anaLeftX) > fabsf(x8_anaLeftX))
x8_anaLeftX = other.x8_anaLeftX;
if (fabsf(other.xc_anaLeftY) > fabsf(xc_anaLeftY))
xc_anaLeftY = other.xc_anaLeftY;
if (fabsf(other.x10_anaRightX) > fabsf(x10_anaRightX))
x10_anaRightX = other.x10_anaRightX;
if (fabsf(other.x14_anaRightY) > fabsf(x14_anaRightY))
x14_anaRightY = other.x14_anaRightY;
if (fabsf(other.x18_anaLeftTrigger) > fabsf(x18_anaLeftTrigger))
x18_anaLeftTrigger = other.x18_anaLeftTrigger;
if (fabsf(other.x1c_anaRightTrigger) > fabsf(x1c_anaRightTrigger))
x1c_anaRightTrigger = other.x1c_anaRightTrigger;
x20_enableAnaLeftXP |= other.x20_enableAnaLeftXP;
x20_enableAnaLeftNegXP |= other.x20_enableAnaLeftNegXP;
x21_enableAnaLeftYP |= other.x21_enableAnaLeftYP;
x21_enableAnaLeftNegYP |= other.x21_enableAnaLeftNegYP;
x22_enableAnaRightXP |= other.x22_enableAnaRightXP;
x22_enableAnaRightNegXP |= other.x22_enableAnaRightNegXP;
x23_enableAnaRightYP |= other.x23_enableAnaRightYP;
x23_enableAnaRightNegYP |= other.x23_enableAnaRightNegYP;
x24_anaLeftTriggerP |= other.x24_anaLeftTriggerP;
x28_anaRightTriggerP |= other.x28_anaRightTriggerP;
x2c_b24_A |= other.x2c_b24_A;
x2c_b25_B |= other.x2c_b25_B;
x2c_b26_X |= other.x2c_b26_X;
x2c_b27_Y |= other.x2c_b27_Y;
x2c_b28_Z |= other.x2c_b28_Z;
x2c_b29_L |= other.x2c_b29_L;
x2c_b30_R |= other.x2c_b30_R;
x2c_b31_DPUp |= other.x2c_b31_DPUp;
x2d_b24_DPRight |= other.x2d_b24_DPRight;
x2d_b25_DPDown |= other.x2d_b25_DPDown;
x2d_b26_DPLeft |= other.x2d_b26_DPLeft;
x2d_b27_Start |= other.x2d_b27_Start;
x2d_b28_PA |= other.x2d_b28_PA;
x2d_b29_PB |= other.x2d_b29_PB;
x2d_b30_PX |= other.x2d_b30_PX;
x2d_b31_PY |= other.x2d_b31_PY;
x2e_b24_PZ |= other.x2e_b24_PZ;
x2e_b25_PL |= other.x2e_b25_PL;
x2e_b26_PR |= other.x2e_b26_PR;
x2e_b27_PDPUp |= other.x2e_b27_PDPUp;
x2e_b28_PDPRight |= other.x2e_b28_PDPRight;
x2e_b29_PDPDown |= other.x2e_b29_PDPDown;
x2e_b30_PDPLeft |= other.x2e_b30_PDPLeft;
x2e_b31_PStart |= other.x2e_b31_PStart;
return *this;
}
} }

View File

@ -2,6 +2,8 @@
#define __RETRO_CFINALINPUT_HPP__ #define __RETRO_CFINALINPUT_HPP__
#include "../RetroTypes.hpp" #include "../RetroTypes.hpp"
#include "CKeyboardMouseController.hpp"
#include <boo/inputdev/DolphinSmashAdapter.hpp>
namespace Retro namespace Retro
{ {
@ -16,12 +18,23 @@ class CFinalInput
float x14_anaRightY; float x14_anaRightY;
float x18_anaLeftTrigger; float x18_anaLeftTrigger;
float x1c_anaRightTrigger; float x1c_anaRightTrigger;
bool x20_enableAnaLeftXP;
bool x21_enableAnaLeftYP; /* These were originally per-axis bools, requiring two logical tests
bool x22_enableAnaRightXP; * at read-time; now they're logical cardinal-direction states
bool x23_enableAnaRightYP; * (negative values indicated) */
float x24_anaLeftTriggerP; bool x20_enableAnaLeftXP:1;
float x28_anaRightTriggerP; bool x20_enableAnaLeftNegXP:1;
bool x21_enableAnaLeftYP:1;
bool x21_enableAnaLeftNegYP:1;
bool x22_enableAnaRightXP:1;
bool x22_enableAnaRightNegXP:1;
bool x23_enableAnaRightYP:1;
bool x23_enableAnaRightNegYP:1;
/* These were originally redundantly-compared floats;
* now the logical state is stored directly */
bool x24_anaLeftTriggerP:1;
bool x28_anaRightTriggerP:1;
bool x2c_b24_A:1; bool x2c_b24_A:1;
bool x2c_b25_B:1; bool x2c_b25_B:1;
@ -50,6 +63,16 @@ class CFinalInput
bool x2e_b31_PStart:1; bool x2e_b31_PStart:1;
public: public:
CFinalInput();
CFinalInput(int cIdx, float dt,
const boo::DolphinControllerState& data,
const CFinalInput& prevInput,
float leftDiv, float rightDiv);
CFinalInput(int cIdx, float dt,
const CKeyboardMouseControllerData& data,
const CFinalInput& prevInput);
CFinalInput& operator|=(const CFinalInput& other);
bool PStart() const {return x2e_b31_PStart;} bool PStart() const {return x2e_b31_PStart;}
bool PR() const {return x2e_b26_PR;} bool PR() const {return x2e_b26_PR;}
bool PL() const {return x2e_b25_PL;} bool PL() const {return x2e_b25_PL;}
@ -62,16 +85,16 @@ public:
bool PDPLeft() const {return x2e_b30_PDPLeft;} bool PDPLeft() const {return x2e_b30_PDPLeft;}
bool PDPDown() const {return x2e_b29_PDPDown;} bool PDPDown() const {return x2e_b29_PDPDown;}
bool PDPUp() const {return x2e_b27_PDPUp;} bool PDPUp() const {return x2e_b27_PDPUp;}
bool PRTrigger() const {return x28_anaRightTriggerP > 0.050000001;} bool PRTrigger() const {return x28_anaRightTriggerP;}
bool PLTrigger() const {return x24_anaLeftTriggerP > 0.050000001;} bool PLTrigger() const {return x24_anaLeftTriggerP;}
bool PRARight() const {return x22_enableAnaRightXP && x10_anaRightX > 0.69999999;} bool PRARight() const {return x22_enableAnaRightXP;}
bool PRALeft() const {return x22_enableAnaRightXP && x10_anaRightX < -0.69999999;} bool PRALeft() const {return x22_enableAnaRightNegXP;}
bool PRADown() const {return x23_enableAnaRightYP && x14_anaRightY < -0.69999999;} bool PRADown() const {return x23_enableAnaRightNegYP;}
bool PRAUp() const {return x23_enableAnaRightYP && x14_anaRightY > 0.69999999;} bool PRAUp() const {return x23_enableAnaRightYP;}
bool PLARight() const {return x20_enableAnaLeftXP && x8_anaLeftX > 0.69999999;} bool PLARight() const {return x20_enableAnaLeftXP;}
bool PLALeft() const {return x20_enableAnaLeftXP && x8_anaLeftX < -0.69999999;} bool PLALeft() const {return x20_enableAnaLeftNegXP;}
bool PLADown() const {return x21_enableAnaLeftYP && xc_anaLeftY < -0.69999999;} bool PLADown() const {return x21_enableAnaLeftNegYP;}
bool PLAUp() const {return x21_enableAnaLeftYP && xc_anaLeftY > 0.69999999;} bool PLAUp() const {return x21_enableAnaLeftYP;}
bool DStart() const {return x2d_b27_Start;} bool DStart() const {return x2d_b27_Start;}
bool DR() const {return x2c_b30_R;} bool DR() const {return x2c_b30_R;}
bool DL() const {return x2c_b29_L;} bool DL() const {return x2c_b29_L;}

View File

@ -1,8 +1,38 @@
#include "CInputGenerator.hpp" #include "CInputGenerator.hpp"
#include "../CArchitectureMessage.hpp"
#include "../CArchitectureQueue.hpp"
namespace Retro namespace Retro
{ {
void CInputGenerator::Update(float dt, CArchitectureQueue& queue)
{
/* Keyboard/Mouse first */
CFinalInput kbInput = m_windowCb.getFinalInput(0, dt);
bool kbUsed = false;
/* Dolphin controllers next */
for (int i=0 ; i<4 ; ++i)
{
bool connected;
EStatusChange change = m_dolphinCb.getStatusChange(i, connected);
if (change)
queue.Push(std::move(MakeMsg::CreateControllerStatus(TargetGame, i, connected)));
if (connected)
{
CFinalInput input = m_dolphinCb.getFinalInput(i, dt, m_leftDiv, m_rightDiv);
if (i == 0) /* Merge KB input with first controller */
{
input |= kbInput;
kbUsed = true;
}
queue.Push(std::move(MakeMsg::CreateUserInput(TargetGame, input)));
}
}
/* Send straight keyboard input if no first controller present */
if (!kbUsed)
queue.Push(std::move(MakeMsg::CreateUserInput(TargetGame, kbInput)));
}
} }

View File

@ -1,114 +1,181 @@
#ifndef __RETRO_CINPUTGENERATOR_HPP__ #ifndef __RETRO_CINPUTGENERATOR_HPP__
#define __RETRO_CINPUTGENERATOR_HPP__ #define __RETRO_CINPUTGENERATOR_HPP__
#include <atomic>
#include <boo/boo.hpp> #include <boo/boo.hpp>
#include "CFinalInput.hpp"
#include "CKeyboardMouseController.hpp"
namespace Retro namespace Retro
{ {
class CArchitectureQueue;
class CInputGenerator : public boo::DeviceFinder
class CInputGenerator
{ {
enum EStatusChange
{
StatusNoChange = 0,
StatusConnected = 1,
StatusDisconnected = 2
};
/* When the sticks are used as logical (digital) input,
* these thresholds determine the vector magnitude indicating
* the logical state */
float m_leftDiv;
float m_rightDiv;
public:
CInputGenerator(float leftDiv, float rightDiv)
: boo::DeviceFinder({typeid(boo::DolphinSmashAdapter)}),
m_leftDiv(leftDiv),
m_rightDiv(rightDiv) {}
/* Keyboard and mouse events are delivered on the main game
* thread as part of the app's main event loop. The OS is responsible
* for buffering events in its own way, then boo flushes the buffer
* at the start of each frame, invoking these methods. No atomic locking
* is necessary, only absolute state tracking. */
struct WindowCallback : boo::IWindowCallback struct WindowCallback : boo::IWindowCallback
{ {
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) CKeyboardMouseControllerData m_data;
void mouseDown(const SWindowCoord&, EMouseButton button, EModifierKey)
{ {
fprintf(stderr, "Mouse Down %d (%f,%f)\n", button, coord.norm[0], coord.norm[1]); m_data.m_mouseButtons[button] = true;
} }
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) void mouseUp(const SWindowCoord&, EMouseButton button, EModifierKey)
{ {
fprintf(stderr, "Mouse Up %d (%f,%f)\n", button, coord.norm[0], coord.norm[1]); m_data.m_mouseButtons[button] = false;
} }
void mouseMove(const SWindowCoord& coord) void mouseMove(const SWindowCoord& coord)
{ {
//fprintf(stderr, "Mouse Move (%f,%f)\n", coord.norm[0], coord.norm[1]); m_data.m_mouseCoord = coord;
} }
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll) void scroll(const SWindowCoord&, const SScrollDelta& scroll)
{ {
fprintf(stderr, "Mouse Scroll (%f,%f) (%f,%f)\n", coord.norm[0], coord.norm[1], scroll.delta[0], scroll.delta[1]); m_data.m_accumScroll += scroll;
} }
void touchDown(const STouchCoord& coord, uintptr_t tid) void charKeyDown(unsigned long charCode, EModifierKey, bool)
{ {
//fprintf(stderr, "Touch Down %16lX (%f,%f)\n", tid, coord.coord[0], coord.coord[1]); charCode = tolower(charCode);
} if (charCode > 255)
void touchUp(const STouchCoord& coord, uintptr_t tid) return;
{ m_data.m_charKeys[charCode] = true;
//fprintf(stderr, "Touch Up %16lX (%f,%f)\n", tid, coord.coord[0], coord.coord[1]);
}
void touchMove(const STouchCoord& coord, uintptr_t tid)
{
//fprintf(stderr, "Touch Move %16lX (%f,%f)\n", tid, coord.coord[0], coord.coord[1]);
}
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat)
{
} }
void charKeyUp(unsigned long charCode, EModifierKey mods) void charKeyUp(unsigned long charCode, EModifierKey mods)
{ {
charCode = tolower(charCode);
if (charCode > 255)
return;
m_data.m_charKeys[charCode] = false;
} }
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat) void specialKeyDown(ESpecialKey key, EModifierKey, bool)
{ {
m_data.m_specialKeys[key] = true;
} }
void specialKeyUp(ESpecialKey key, EModifierKey mods) void specialKeyUp(ESpecialKey key, EModifierKey)
{ {
m_data.m_specialKeys[key] = false;
} }
void modKeyDown(EModifierKey mod, bool isRepeat) void modKeyDown(EModifierKey mod, bool)
{ {
m_data.m_modMask = EModifierKey(m_data.m_modMask | mod);
} }
void modKeyUp(EModifierKey mod) void modKeyUp(EModifierKey mod)
{ {
m_data.m_modMask = EModifierKey(m_data.m_modMask & ~mod);
} }
void reset()
{
m_data.m_accumScroll.zeroOut();
}
CFinalInput m_lastUpdate;
const CFinalInput& getFinalInput(unsigned idx, float dt)
{
m_lastUpdate = CFinalInput(idx, dt, m_data, m_lastUpdate);
return m_lastUpdate;
}
} m_windowCb; } m_windowCb;
/* Input via the smash adapter is received asynchronously on a USB
* report thread. This class atomically exchanges that data to the
* game thread as needed */
struct DolphinSmashAdapterCallback : boo::IDolphinSmashAdapterCallback struct DolphinSmashAdapterCallback : boo::IDolphinSmashAdapterCallback
{ {
std::atomic<EStatusChange> m_statusChanges[4];
bool m_connected[4] = {};
boo::DolphinControllerState m_states[4];
std::mutex m_stateLock;
void controllerConnected(unsigned idx, boo::EDolphinControllerType) void controllerConnected(unsigned idx, boo::EDolphinControllerType)
{ {
printf("CONTROLLER %u CONNECTED\n", idx); /* Controller thread */
m_statusChanges[idx].store(StatusConnected);
} }
void controllerDisconnected(unsigned idx, boo::EDolphinControllerType) void controllerDisconnected(unsigned idx, boo::EDolphinControllerType)
{ {
printf("CONTROLLER %u DISCONNECTED\n", idx); /* Controller thread */
std::unique_lock<std::mutex> lk(m_stateLock);
m_statusChanges[idx].store(StatusDisconnected);
m_states[idx].reset();
} }
void controllerUpdate(unsigned idx, boo::EDolphinControllerType, void controllerUpdate(unsigned idx, boo::EDolphinControllerType,
const boo::DolphinControllerState& state) const boo::DolphinControllerState& state)
{ {
printf("CONTROLLER %u UPDATE %d %d\n", idx, state.m_leftStick[0], state.m_leftStick[1]); /* Controller thread */
std::unique_lock<std::mutex> lk(m_stateLock);
m_states[idx] = state;
} }
};
class ApplicationDeviceFinder : public boo::DeviceFinder CFinalInput m_lastUpdates[4];
const CFinalInput& getFinalInput(unsigned idx, float dt,
float leftDiv, float rightDiv)
{
/* Game thread */
std::unique_lock<std::mutex> lk(m_stateLock);
boo::DolphinControllerState state = m_states[idx];
lk.unlock();
state.clamp(); /* PADClamp equivalent */
m_lastUpdates[idx] = CFinalInput(idx, dt, state, m_lastUpdates[idx], leftDiv, rightDiv);
return m_lastUpdates[idx];
}
EStatusChange getStatusChange(unsigned idx, bool& connected)
{
/* Game thread */
EStatusChange ch = m_statusChanges[idx].exchange(StatusNoChange);
if (ch == StatusConnected)
m_connected[idx] = true;
else if (ch == StatusDisconnected)
m_connected[idx] = false;
connected = m_connected[idx];
return ch;
}
} m_dolphinCb;
/* Device connection/disconnection events are handled on a separate thread
* using the relevant OS API. This thread blocks in a loop until an event is
* received. Device pointers should only be manipulated by this thread using
* the deviceConnected() and deviceDisconnected() callbacks. */
std::unique_ptr<boo::DolphinSmashAdapter> smashAdapter = NULL;
void deviceConnected(boo::DeviceToken& tok)
{ {
std::unique_ptr<boo::DolphinSmashAdapter> smashAdapter = NULL; /* Device listener thread */
DolphinSmashAdapterCallback m_cb; if (!smashAdapter)
public:
ApplicationDeviceFinder()
: boo::DeviceFinder({typeid(boo::DolphinSmashAdapter)})
{}
void deviceConnected(boo::DeviceToken& tok)
{ {
if (!smashAdapter) smashAdapter.reset(dynamic_cast<boo::DolphinSmashAdapter*>(tok.openAndGetDevice()));
{ smashAdapter->setCallback(&m_dolphinCb);
smashAdapter.reset(dynamic_cast<boo::DolphinSmashAdapter*>(tok.openAndGetDevice()));
smashAdapter->setCallback(&m_cb);
smashAdapter->startRumble(0);
}
} }
void deviceDisconnected(boo::DeviceToken&, boo::DeviceBase* device) }
{ void deviceDisconnected(boo::DeviceToken&, boo::DeviceBase* device)
if (smashAdapter.get() == device) {
smashAdapter.reset(nullptr); if (smashAdapter.get() == device)
} smashAdapter.reset(nullptr);
}; }
/* This is where the game thread enters */
void Update(float dt, CArchitectureQueue& queue);
}; };

View File

@ -1,15 +0,0 @@
#ifndef __RETRO_CKEYBOARDCONTROLLER_HPP__
#define __RETRO_CKEYBOARDCONTROLLER_HPP__
#include "IController.hpp"
namespace Retro
{
class CKeyboardController : public IController
{
};
}
#endif // __RETRO_CKEYBOARDCONTROLLER_HPP__

View File

@ -0,0 +1,21 @@
#ifndef __RETRO_CKEYBOARDMOUSECONTROLLER_HPP__
#define __RETRO_CKEYBOARDMOUSECONTROLLER_HPP__
#include <boo/boo.hpp>
namespace Retro
{
struct CKeyboardMouseControllerData
{
bool m_charKeys[256] = {};
bool m_specialKeys[26] = {};
bool m_mouseButtons[6] = {};
boo::IWindowCallback::EModifierKey m_modMask = boo::IWindowCallback::MKEY_NONE;
boo::IWindowCallback::SWindowCoord m_mouseCoord;
boo::IWindowCallback::SScrollDelta m_accumScroll;
};
}
#endif // __RETRO_CKEYBOARDMOUSECONTROLLER_HPP__

View File

@ -1,8 +1,6 @@
add_library(RuntimeCommonInput add_library(RuntimeCommonInput
IController.hpp IController.hpp
CDolphinController.hpp CKeyboardMouseController.hpp
CKeyboardController.hpp
CMouseController.hpp
ControlMapper.hpp ControlMapper.cpp ControlMapper.hpp ControlMapper.cpp
CInputGenerator.hpp CInputGenerator.cpp CInputGenerator.hpp CInputGenerator.cpp
CFinalInput.hpp CFinalInput.cpp) CFinalInput.hpp CFinalInput.cpp)

View File

@ -1,15 +0,0 @@
#ifndef __RETRO_CMOUSECONTROLLER_HPP__
#define __RETRO_CMOUSECONTROLLER_HPP__
#include "IController.hpp"
namespace Retro
{
class CMouseController : public IController
{
};
}
#endif // __RETRO_CMOUSECONTROLLER_HPP__

View File

@ -1,25 +1,22 @@
#ifndef __RETRO_ICONTROLLER_HPP__ #ifndef __RETRO_ICONTROLLER_HPP__
#define __RETRO_ICONTROLLER_HPP__ #define __RETRO_ICONTROLLER_HPP__
#include "../RetroTypes.hpp"
namespace Retro namespace Retro
{ {
class IController class IController
{ {
public: public:
class CControllerAxis enum EMotorState
{ {
MotorStop = 0,
MotorRumble = 1,
MotorStopHard = 2
}; };
class CControllerButton virtual void Poll()=0;
{ virtual void SetMotorState(EMotorState state)=0;
};
class IControllerGamepadData
{
};
void Poll();
u32 GetDeviceCount();
}; };
} }

View File

@ -11,6 +11,7 @@ add_executable(mp1
main.cpp) main.cpp)
target_link_libraries(mp1 target_link_libraries(mp1
RuntimeCommonCharacter RuntimeCommonCharacter
RuntimeCommonInput
RuntimeCommon RuntimeCommon
DNAMP1 DNAMP1
DNACommon DNACommon

View File

@ -3,10 +3,12 @@
#include "CResFactory.hpp" #include "CResFactory.hpp"
#include "CResLoader.hpp" #include "CResLoader.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp" #include "DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp"
namespace Retro namespace Retro
{ {
ITweakPlayer* g_tweakPlayer = nullptr;
ITweakPlayerControl* g_tweakPlayerControl = nullptr; ITweakPlayerControl* g_tweakPlayerControl = nullptr;
namespace MP1 namespace MP1
@ -28,6 +30,10 @@ void CTweaks::RegisterTweaks()
CResLoader& loader = factory.GetLoader(); CResLoader& loader = factory.GetLoader();
std::unique_ptr<CInputStream> strm; std::unique_ptr<CInputStream> strm;
strm.reset(loader.LoadNewResourceSync(IDFromFactory(factory, "Player"), nullptr));
TOneStatic<DNAMP1::CTweakPlayer> player(*strm);
g_tweakPlayer = player.GetAllocSpace();
strm.reset(loader.LoadNewResourceSync(IDFromFactory(factory, "PlayerControls"), nullptr)); strm.reset(loader.LoadNewResourceSync(IDFromFactory(factory, "PlayerControls"), nullptr));
TOneStatic<DNAMP1::CTweakPlayerControl> playerControl(*strm); TOneStatic<DNAMP1::CTweakPlayerControl> playerControl(*strm);
g_tweakPlayerControl = playerControl.GetAllocSpace(); g_tweakPlayerControl = playerControl.GetAllocSpace();

View File

@ -24,6 +24,8 @@
#include "CArchitectureQueue.hpp" #include "CArchitectureQueue.hpp"
#include "CMain.hpp" #include "CMain.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp"
namespace Retro namespace Retro
{ {
CMemoryCardSys* g_MemoryCardSys = nullptr; CMemoryCardSys* g_MemoryCardSys = nullptr;
@ -98,7 +100,9 @@ class CGameArchitectureSupport
CAudioStateWin m_audioStateWin; CAudioStateWin m_audioStateWin;
public: public:
CGameArchitectureSupport() CGameArchitectureSupport()
: m_audioSys(0,0,0,0,0) : m_audioSys(0,0,0,0,0),
m_inputGenerator(g_tweakPlayer->GetLeftLogicalThreshold(),
g_tweakPlayer->GetRightLogicalThreshold())
{ {
} }
bool Update() bool Update()

2
libBoo

@ -1 +1 @@
Subproject commit 12e5948d3178df7f689d9676e103760dbb89d07d Subproject commit f9c4ed076157c78fd131f83c5d0f3bc4c95ae13a