InputBag in a working state and getting used.
This commit is contained in:
parent
d9ccbede66
commit
597607366e
7 changed files with 112 additions and 9 deletions
|
@ -1,18 +1,30 @@
|
|||
#include "gamebase.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include "inputbag.hpp"
|
||||
#include "key.hpp"
|
||||
#include <sstream>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <ciso646>
|
||||
#include <cassert>
|
||||
|
||||
namespace cloonel {
|
||||
namespace {
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
bool DoEvents() {
|
||||
bool DoEvents (InputBag& parInput) {
|
||||
SDL_Event eve;
|
||||
while (SDL_PollEvent(&eve)) {
|
||||
switch (eve.type) {
|
||||
case SDL_KEYDOWN:
|
||||
//eve.key.keysym.sym
|
||||
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, true);
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, false);
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
return true;
|
||||
}
|
||||
|
@ -24,6 +36,7 @@ namespace cloonel {
|
|||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
GameBase::GameBase (SDLMain* parSdlMain) :
|
||||
m_input(new InputBag()),
|
||||
m_sdlmain(parSdlMain),
|
||||
m_time0(SDL_GetTicks()),
|
||||
m_wantsToQuit(false)
|
||||
|
@ -49,7 +62,8 @@ namespace cloonel {
|
|||
OnRender();
|
||||
SDL_RenderPresent(ren);
|
||||
|
||||
m_wantsToQuit = DoEvents();
|
||||
m_wantsToQuit = DoEvents(*m_input);
|
||||
m_input->KeyStateUpdateFinished();
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
namespace cloonel {
|
||||
class SDLMain;
|
||||
class Texture;
|
||||
class InputBag;
|
||||
|
||||
class GameBase {
|
||||
public:
|
||||
|
@ -20,12 +21,14 @@ namespace cloonel {
|
|||
virtual void Destroy ( void ) noexcept = 0;
|
||||
|
||||
SDLMain* SDLObject ( void ) { return m_sdlmain; }
|
||||
InputBag* InputBagObject ( void ) { return m_input.get(); }
|
||||
|
||||
private:
|
||||
virtual void OnRender ( void ) = 0;
|
||||
virtual void OnUpdate ( float parDelta ) = 0;
|
||||
virtual bool ShouldQuit ( void ) const;
|
||||
|
||||
const std::unique_ptr<InputBag> m_input;
|
||||
SDLMain* const m_sdlmain;
|
||||
unsigned int m_time0;
|
||||
bool m_wantsToQuit;
|
||||
|
|
|
@ -2,9 +2,19 @@
|
|||
#include "character.hpp"
|
||||
#include "moversine.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include "inputbag.hpp"
|
||||
#include "key.hpp"
|
||||
#include <algorithm>
|
||||
#include <SDL2/SDL_scancode.h>
|
||||
|
||||
namespace cloonel {
|
||||
namespace {
|
||||
enum GameActionType {
|
||||
GameAction_Left,
|
||||
GameAction_Right
|
||||
};
|
||||
} //unnamed namespace
|
||||
|
||||
struct GameplaySceneClassic::LocalData {
|
||||
};
|
||||
|
||||
|
@ -14,6 +24,10 @@ namespace cloonel {
|
|||
GameplayScene(parSdlMain),
|
||||
m_local(new LocalData)
|
||||
{
|
||||
//TODO: replace the hardcoded bindings with something more customizable.
|
||||
InputBag& input = *InputBagObject();
|
||||
input.AddAction(GameAction_Left, Key(InputDevice_Keyboard, SDL_SCANCODE_LEFT), "Move left");
|
||||
input.AddAction(GameAction_Left, Key(InputDevice_Keyboard, SDL_SCANCODE_RIGHT), "Move right");
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
|
|
|
@ -3,12 +3,17 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
struct Action {
|
||||
Key key;
|
||||
const std::string name;
|
||||
InputBag::ActionStateType state;
|
||||
bool newStatePressed;
|
||||
|
||||
bool operator== ( const Key& parKey ) const { return key == parKey; }
|
||||
};
|
||||
|
||||
struct InputBag::LocalData {
|
||||
|
@ -17,6 +22,23 @@ namespace cloonel {
|
|||
};
|
||||
|
||||
namespace {
|
||||
// | rl | pr
|
||||
// -----------------
|
||||
// rel | rel | jpr
|
||||
// prs | jrl | prs
|
||||
// jrl | rel | jpr
|
||||
// jpr | jrl | prs
|
||||
const InputBag::ActionStateType g_stateTruthTable[] = {
|
||||
InputBag::ActionState_Released,
|
||||
InputBag::ActionState_JustReleased,
|
||||
InputBag::ActionState_Released,
|
||||
InputBag::ActionState_JustReleased,
|
||||
InputBag::ActionState_JustPressed,
|
||||
InputBag::ActionState_Pressed,
|
||||
InputBag::ActionState_JustPressed,
|
||||
InputBag::ActionState_Pressed
|
||||
};
|
||||
|
||||
///----------------------------------------------------------------------
|
||||
///When actions vector is reallocated, update pointers in mappings.
|
||||
///----------------------------------------------------------------------
|
||||
|
@ -45,7 +67,7 @@ namespace cloonel {
|
|||
///--------------------------------------------------------------------------
|
||||
void InputBag::AddAction (int parAction, const Key& parKey, std::string&& parName) {
|
||||
Action* const oldBuff = m_localdata->actions.data();
|
||||
m_localdata->actions.push_back(Action({parKey, parName, ActionState_Released}));
|
||||
m_localdata->actions.push_back(Action({parKey, parName, ActionState_Released, false}));
|
||||
Action* const newBuff = m_localdata->actions.data();
|
||||
if (oldBuff != newBuff) {
|
||||
UpdatePointers(oldBuff, newBuff, m_localdata->mappings, 0);
|
||||
|
@ -66,4 +88,37 @@ namespace cloonel {
|
|||
m_localdata->actions.clear();
|
||||
m_localdata->mappings.clear();
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::NotifyKeyAction (InputDeviceType parDev, int parScancode, bool parPressed) {
|
||||
const Key searchKey(parDev, parScancode);
|
||||
auto itFound = std::find(m_localdata->actions.begin(), m_localdata->actions.end(), searchKey);
|
||||
//This method gets called every time a keypress or keyrelease is
|
||||
//produced, but if the key is of any use is decided here. So it possible
|
||||
//that a keystroke is not bound to any action and therefore no
|
||||
//corresponding element is present in the actions list.
|
||||
if (m_localdata->actions.end() != itFound)
|
||||
itFound->newStatePressed = parPressed;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::KeyStateUpdateFinished() noexcept {
|
||||
for (auto& currAction : m_localdata->actions) {
|
||||
const int numericState = static_cast<int>(currAction.state);
|
||||
assert(numericState < 4);
|
||||
const int index = (currAction.newStatePressed ? 4 : 0) + numericState;
|
||||
currAction.state = g_stateTruthTable[index];
|
||||
}
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::ClearState() {
|
||||
for (auto& currAction : m_localdata->actions) {
|
||||
currAction.newStatePressed = false;
|
||||
currAction.state = ActionState_Released;
|
||||
}
|
||||
}
|
||||
} //namespace cloonel
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef idF4E67FC292A5480DA4305B806170F520
|
||||
#define idF4E67FC292A5480DA4305B806170F520
|
||||
|
||||
#include "inputdevicetype.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace cloonel {
|
||||
|
@ -21,6 +22,9 @@ namespace cloonel {
|
|||
void AddAction ( int parAction, const Key& parKey, std::string&& parName );
|
||||
ActionStateType ActionState ( int parAction ) const;
|
||||
void Clear ( void );
|
||||
void NotifyKeyAction ( InputDeviceType parDev, int parScancode, bool parPressed );
|
||||
void KeyStateUpdateFinished ( void ) noexcept;
|
||||
void ClearState ( void );
|
||||
|
||||
private:
|
||||
struct LocalData;
|
||||
|
|
10
src/inputdevicetype.hpp
Normal file
10
src/inputdevicetype.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef idED0C5C9767B64910A2998ACDAE14A509
|
||||
#define idED0C5C9767B64910A2998ACDAE14A509
|
||||
|
||||
namespace cloonel {
|
||||
enum InputDeviceType {
|
||||
InputDevice_Keyboard
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
15
src/key.hpp
15
src/key.hpp
|
@ -1,16 +1,13 @@
|
|||
#ifndef id8F6145D6CFBA40338C5804DEC032CE16
|
||||
#define id8F6145D6CFBA40338C5804DEC032CE16
|
||||
|
||||
#include "inputdevicetype.hpp"
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
struct Key {
|
||||
enum KeyDevice {
|
||||
KeyDevice_Keyboard
|
||||
};
|
||||
|
||||
Key ( void ) = default;
|
||||
Key ( KeyDevice parDev, int parScancode, const char parLabel[4] ) :
|
||||
Key ( InputDeviceType parDev, int parScancode, const char parLabel[4] ) :
|
||||
srcdevice(parDev),
|
||||
scancode(parScancode)
|
||||
{
|
||||
|
@ -19,6 +16,12 @@ namespace cloonel {
|
|||
label[2] = parLabel[2];
|
||||
label[3] = parLabel[3];
|
||||
}
|
||||
Key ( InputDeviceType parDev, int parScancode ) :
|
||||
srcdevice(parDev),
|
||||
scancode(parScancode),
|
||||
label {0, 0, 0, 0}
|
||||
{
|
||||
}
|
||||
~Key ( void ) noexcept = default;
|
||||
|
||||
bool operator== ( const Key& parOther ) const {
|
||||
|
@ -31,7 +34,7 @@ namespace cloonel {
|
|||
return (srcdevice == parOther.srcdevice and scancode < parOther.scancode) or (srcdevice < parOther.srcdevice);
|
||||
}
|
||||
|
||||
KeyDevice srcdevice;
|
||||
InputDeviceType srcdevice;
|
||||
int scancode;
|
||||
char label[4];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue