Jump to content
  • Advertisement
Sign in to follow this  

Best Method of gathering input with SDL

This topic is 4523 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement
"Best" is very subjective. Best for what? The answer would be probably be different if you're writing a typing tutor game vs. a two player fighting game.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I would do (from my input class):

// for mouse:
m_MouseX = m_Event.motion.x; (int)
m_MouseY = m_Event.motion.y; (int)
// for keys:
m_pKeysHeld = SDL_GetKeyState(NULL); (unsigned char)(Uint8)


But, event.key.keysym.sym == better for one-time keys, like what SiCrane said.

C++

Share this post


Link to post
Share on other sites
The main question for me was whether to provide a single point of access to SDL's input data (via a singleton style input class), or whether to copy the SDL data and pass it as a parameter. I went for the first way a while ago, but will soon be switching to the second so I can properly do instant replay, rewind, etc.

The other issue (and probably the one the OP is interested in) is whether to check each and every SDL event as it's received (as the AP does for mouse), or just to poll the global SDL state once every frame (as the AP does for keys).

I found that using the global state functions was fine for most game input, but if you need to be certain of the order the events happened (eg if you're passing it to an event based GUI, or maybe checking for a sequence of inputs to make a combo-move) then check each event.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Well... Here's how I do it:

#ifndef CAPP_EVENT_H_
#define CAPP_EVENT_H_

#pragma once

#include <SDL/SDL.h>

#include "CApp_Engine.h"

enum {
UP = SDLK_UP,
DOWN = SDLK_DOWN,
LEFT = SDLK_LEFT,
RIGHT = SDLK_RIGHT,

F1 = SDLK_F1,
F2 = SDLK_F2,
F3 = SDLK_F3,
F4 = SDLK_F4,

ENTER = SDLK_RETURN,
ESCAPE = SDLK_ESCAPE,
SPACE = SDLK_SPACE,
PAUSE = SDLK_p,

KP_UP = SDLK_KP8,
KP_DOWN = SDLK_KP5 | SDLK_KP2,
KP_LEFT = SDLK_KP4,
KP_RIGHT = SDLK_KP6,

MOUSE_LEFT = SDL_BUTTON_LEFT,
MOUSE_RIGHT = SDL_BUTTON_RIGHT,
MOUSE_MIDDLE = SDL_BUTTON_MIDDLE
};

namespace CApp {
class Event {
public:
Event(Engine *pEngine);
~Event();

SDL_Event GetEvent();
int Update();

Uint8 GetKey(int Key);
void SetKey(int Key, bool Active);

int GetMouseX() { return m_Event.motion.x; }
int GetMouseY() { return m_Event.motion.y; }

bool MouseButton(int Button);
bool ClickedIn(SDL_Rect Where, int Button = MOUSE_LEFT);

void SetEngine(Engine *pEngine);

bool HandleMessages();

private:
SDL_Event m_Event;

Uint8 *m_pKeys;

Engine *m_pEngine;
};
};

#endif
//.cpp


//---


//.cpp
#include <SDL/SDL.h>

#include "CApp_Event.h"

namespace CApp {
Event::Event(CApp::Engine *pEngine): m_pEngine(pEngine) {

}

Event::~Event() {

}

bool Event::HandleMessages() {
switch (m_Event.type) {
case SDL_QUIT: {
return false;
} break;

case SDL_VIDEORESIZE: {
m_pEngine->SetWidthHeightBpp(m_Event.resize.w, m_Event.resize.h);

m_pEngine->ReCreateWindow();
} break;
}

if (GetKey(ESCAPE))
return false;

if (GetKey(F1)) {
m_pEngine->ToggleFullScreen(!m_pEngine->IsFullScreen());

SetKey(F1, false);
}

return true;
}

int Event::Update() {
m_pKeys = SDL_GetKeyState(NULL);

return (SDL_PollEvent(&m_Event));
}

SDL_Event Event::GetEvent() {
return (m_Event);
}

Uint8 Event::GetKey(int Key) {
return (m_pKeys[Key]);
}

void Event::SetKey(int Key, bool Active) {
m_pKeys[Key] = ((Active == true) ? 1:0);
}

bool Event::MouseButton(int Button) {
if (m_Event.button.button == Button)
return true;

return false;
}

bool Event::ClickedIn(SDL_Rect Where, int Button) {
int x = this->GetMouseX();
int y = this->GetMouseY();

if (x >= Where.x && x <= Where.x + Where.w && y >= Where.y && y <= Where.y + Where.h) {
if (this->MouseButton(Button))
return true;
}

return false;
}

void Event::SetEngine(Engine *pEngine) {
m_pEngine = pEngine;
}
};



C++

Share this post


Link to post
Share on other sites
I use a system (my code) that would accodomate for what SiCrane has mentioned which is basically a system that has a callback styled reporting (for something like a typing tutor), so on a key/mouse event, you can have access to the event, so you know the time of press, the key, and anything else associated. Then, the input system also has a real time polling style, to which you can get the the state of any key/button as well as anything else, such as mouse position, etc... at any time.

To add upon that, there are built in timers that you can use so you can limit your input rate, which baiscally goes into 'event repeat rates'. So if you want to only allow a key to be pressable once every X ms, you can first check to see if that timer has any time in it, and if it does, then your event code won't execute. If it doesn't have any time in it, then your code executes, after which it sets the delay time.

Finally, you can manually set/release keys/mousebuttons/mouse position with easy to use functions. That way, you can allow something to only happens 'once per release', so no matter how long they hold down a key or button, that code will only be executed once until the user lets go. In the code to set the mouse position, there is also a system to filter out the generated mouse movements generated by SDL_warpmouse, that way you can continously set the mouse position to the center of the screen in a FPS and you won't get the choppiness associated when you do not do what I've done.

Anyways, lot's of stuff to it, it's rather simple, so if you're interested in the code, I'll put that up here, I made a post a while back on it, but it's been much improved since, much improved [wink]

Share this post


Link to post
Share on other sites
It's continously under improvements, it doesn't have cool featues like AP's 'ClickedIn'...yet [wink] I just recently added in the delay features of input to allow repeat rates, to which today I will be adding in a better system to allow for unlimited 'delay' to check against, so you can have a seperate delay for each key if you wanted to. After that it's just adding anything that I see is missing, which I didn't really see much until I saw AP's code, so good work AP(C++)!

Anyways here's the most recent code, I've just added in the delay map system, and I think I got all the bugs out:

Input.h

#pragma once

#include <sdl.h>
#include <string>
#include <vector>
#include <map>

class cInput
{
protected:
// This structure is a representation of a key event, it is protected so
// only this class and derivations can use it
struct tKey
{
// The SDLK_key
SDLKey key;

// Modifiders for the key such as alt, ctrl, and shift
SDLMod mod;

// SDL_KEYUP or SDL_KEYDOWN
Uint8 type;

// The time of press or release
Uint32 time;

// The name of the key
std::string name;

// Modifier key states to check against
bool NumLockDown;
bool CapsDown;
// Controls
bool ControlDown;
bool LeftControlDown;
bool RightControlDown;
// Shifts
bool ShiftDown;
bool LeftShiftDown;
bool RightShiftDown;
// Alts
bool AltDown;
bool LeftAltDown;
bool RightAltDown;

// Default empty constructor
~tKey();

// Constructor that takes an event and extracts the data from it
tKey( const SDL_Event &Event );
};

// This structure is a representation of a mouse event, it is protected so
// only this class and derivations can use it
struct tMouse
{
// The type of event
Uint8 type;

// The state of the action
Uint8 state;

// X and Y coordinates on the screen
Uint16 x;
Uint16 y;

// Specific for SDL_MouseMotion, relative movement values
Sint16 xrel;
Sint16 yrel;

// The time of the event
Uint32 time;

// Specific for SDL_MouseButton, the button that was clicked/released
Uint8 button;

// Default empty constructor
~tMouse();

// Constructor that takes an event and extracts the data from it
tMouse( const SDL_Event &Event );
};

// Vector that serves as the keyboard input buffer for SDL
std::vector<tKey> inputKeyBuffer;

// Vector that serves as the mouse input buffer for SDL
std::vector<tMouse> inputMouseBuffer;

// Stores all of the keys and if they are down or up
std::vector<bool> keyStates;

// Stores the current X coordinate for the mouse
Uint32 mouseX;

// Stores the current Y coordinate for the mouse
Uint32 mouseY;

// Stores all of the keys and if they are down or up
std::vector<bool> buttonStates;

// Current delay for keys
int curKeyDelay;

// Current delay for mouse buttons
int curButtonDelay;

// Current general delay map
std::map<std::string, int> curDelay;

// Current general delay
std::map<std::string, bool> noDelayVar;

// Can a key be pressed again (curDelay == 0)
//bool canPressKeyVar;

// Can a mouse button be pressed again (curDelay == 0)
//bool canPressMouseVar;

public:
// Called on a key press event.
virtual int OnKeyDown( const tKey& Key );

// Called on a key release event.
virtual int OnKeyUp( const tKey& Key );

// Called on a mouse motion event.
virtual int OnMouseMove( const tMouse& Mouse );

// Called on a mouse button press.
virtual int OnMouseButtonDown( const tMouse& Mouse );

// Called on a mouse button release.
virtual int OnMouseButtonUp( const tMouse& Mouse );

// Called on a mouse wheel up event
virtual int OnMouseWheelUp( const tMouse& Mouse );

// Called on a mouse wheel down event
virtual int OnMouseWheelDown( const tMouse& Mouse );

// Virtual default deconstructor
virtual ~cInput();

public:
// Default constructor
cInput();

// Returns true if the key is pressed and false if the key is released
bool IsKeyDown( int Key );

// Sets a key to being released manually
void SetKeyUp( int Key );

// Sets a key to being pressed manually
void SetKeyDown( int Key );

// Get the X coordinate of the mouse
Uint32 GetMouseX();

// Get the Y coordinate of the mouse
Uint32 GetMouseY();

// Set the X coordinate of the mouse
void SetMouseX( Uint32 X );

// Set the Y coordinate of the mouse
void SetMouseY( Uint32 Y );

// Set the X and Y coordinate of the mouse
void SetMouseXY( Uint32 X, Uint32 Y );

// Check to see if the specified mouse button is down
bool IsButtonDown( int Button );

// Sets a button to being released manually
void SetButtonUp( int Button );

// Sets a button to being pressed manually
void SetButtonDown( int Button );

// Input event polling function that takes in events and sees if they need to be processed
bool Poll( const SDL_Event &Event );

// Updates the input system
void Update();

// Set the general delay
void SetDelay(std::string name, unsigned int delay);

// No general delay
bool NoDelay(std::string name);
};




Input.cpp

#include "Input.h"

// Default empty constructor
cInput::tMouse::~tMouse()
{
}

// Constructor that takes an event and extracts the data from it
cInput::tMouse::tMouse( const SDL_Event &Event )
{
// Get the time of the press which is time of construction
time = SDL_GetTicks();

// Assign the type
type = Event.type;

if( type == SDL_MOUSEMOTION )
{
// Save the state
state = Event.motion.state;

// X & Y coordinates of the event
x = Event.motion.x;
y = Event.motion.y;

// Assign the relative movements
xrel = Event.motion.xrel;
yrel = Event.motion.yrel;

// Not used in this event
button = 0;
}
else if( type == SDL_MOUSEBUTTONDOWN || type == SDL_MOUSEBUTTONUP )
{
// Save the state
state = Event.button.state;

// X & Y coordinates of the event
x = Event.button.x;
y = Event.button.y;

// Save the button used
button = Event.button.button;

// Not used in this event
xrel = 0;
yrel = 0;
}
else
{
abort();
}
}

// Default empty constructor
cInput::tKey::~tKey()
{
}

// Constructor that takes an event and extracts the data from it
cInput::tKey::tKey( const SDL_Event &Event )
{
// Get the time of the press which is time of construction
time = SDL_GetTicks();

// Get they data of the event
key = Event.key.keysym.sym;
mod = Event.key.keysym.mod;
type = Event.type;

// Convert the SDLK_key to a string representation
name = SDL_GetKeyName( key );

// Go though and set all of the modifer settings
NumLockDown = mod & KMOD_NUM;
CapsDown = mod & KMOD_CAPS;
LeftControlDown = mod & KMOD_LCTRL;
RightControlDown = mod & KMOD_RCTRL;
LeftShiftDown = mod & KMOD_LSHIFT;
RightShiftDown = mod & KMOD_RSHIFT;
LeftAltDown = mod & KMOD_LALT;
RightAltDown = mod & KMOD_RALT;

// These modifiers are for if you want to see if either is pressed and not one specifically
ControlDown = LeftControlDown | RightControlDown;
ShiftDown = LeftShiftDown | RightShiftDown;
AltDown = LeftAltDown | RightAltDown;
}

cInput::cInput()
{
// Allocate enough memory for a maximum of 64 input events at a time
inputKeyBuffer.reserve(64);

// Allocate enough memory for a maximum of 512 input events at a time
inputMouseBuffer.reserve(512);

// Max number of keys to store states for
keyStates.resize(512);

// Max number of mouse buttons
buttonStates.resize(6);

// Current delay for key presses
//curKeyDelay = 0;

// Current delay for mouse button presses
//curButtonDelay = 0;

// Can a key be pressed
//canPressKeyVar = true;

// Can a key be pressed
//canPressMouseVar = true;
}

// Returns true if the key is pressed and false if the key is released
bool cInput::IsKeyDown( int Key)
{
// Return the result
return keyStates.at( Key );
}

// Sets a key to being released manually
void cInput::SetKeyUp( int Key )
{
// Set the specified key to being released
keyStates.at( Key ) = false;
}

// Sets a key to being pressed manually
void cInput::SetKeyDown( int Key )
{
// Set the specified key to being pressed
keyStates.at( Key ) = true;
}

// Input event polling function that takes in events and sees if they need to be processed
bool cInput::Poll( const SDL_Event &Event )
{
// If it is a key press/release event
if( Event.type == SDL_KEYDOWN || Event.type == SDL_KEYUP )
{
// Save the event to the buffer for processing
inputKeyBuffer.push_back( tKey(Event) );
}
else if( Event.type == SDL_MOUSEMOTION || Event.type == SDL_MOUSEBUTTONDOWN || Event.type == SDL_MOUSEBUTTONUP )
{
// Save the event to the buffer for processing
inputMouseBuffer.push_back( tMouse(Event) );
}
else
return false;

// The event was handeled
return true;
}

// Returns the current X coordinate of the mouse
Uint32 cInput::GetMouseX()
{
return mouseX;
}

// Returns the current Y coordinate of the mouse
Uint32 cInput::GetMouseY()
{
return mouseY;
}

void cInput::SetMouseY( Uint32 Y )
{
// Temporary event variable
SDL_Event msg;

// We want to preserve the events
std::vector<SDL_Event> eventList;

// Save all pending events before we mess with the event queue
while( SDL_PollEvent( &msg ) )
{
// Save it
eventList.push_back( msg );
}

// Warp the mouse
SDL_WarpMouse( mouseX, Y );

// Pump all events
SDL_PumpEvents();

// Eat away the mouse motions
while( SDL_PollEvent( &msg ) )
{
// If it's not a mouse motion, we want it!
if( msg.type != SDL_MOUSEMOTION )
{
// Save it
eventList.push_back( msg );
}
}

// Now go back and restore the event queue
for( size_t x = 0; x < eventList.size(); x++ )
{
SDL_PushEvent( &eventList.at(x) );
}

// Set the current Y position
mouseY = Y;
}

void cInput::SetMouseX( Uint32 X )
{
// Temporary event variable
SDL_Event msg;

// We want to preserve the events
std::vector<SDL_Event> eventList;

// Save all pending events before we mess with the event queue
while( SDL_PollEvent( &msg ) )
{
// Save it
eventList.push_back( msg );
}

// Warp the mouse
SDL_WarpMouse( X, mouseY );

// Pump all events
SDL_PumpEvents();

// Eat away the mouse motions
while( SDL_PollEvent( &msg ) )
{
// If it's not a mouse motion, we want it!
if( msg.type != SDL_MOUSEMOTION )
{
// Save it
eventList.push_back( msg );
}
}

// Now go back and restore the event queue
for( size_t x = 0; x < eventList.size(); x++ )
{
SDL_PushEvent( &eventList.at(x) );
}

// Set the current X position
mouseX = X;
}

void cInput::SetMouseXY( Uint32 X, Uint32 Y )
{
// Temporary event variable
SDL_Event msg;

// We want to preserve the events
std::vector<SDL_Event> eventList;

// Save all pending events before we mess with the event queue
while( SDL_PollEvent( &msg ) )
{
// Save it
eventList.push_back( msg );
}

// Warp the mouse
SDL_WarpMouse( X, Y );

// Pump all events
SDL_PumpEvents();

// Eat away the mouse motions
while( SDL_PollEvent( &msg ) )
{
// If it's not a mouse motion, we want it!
if( msg.type != SDL_MOUSEMOTION )
{
// Save it
eventList.push_back( msg );
}
}

// Now go back and restore the event queue
for( size_t x = 0; x < eventList.size(); x++ )
{
SDL_PushEvent( &eventList.at(x) );
}

// Set the new mouse positions
mouseX = X;
mouseY = Y;
}

// Checks to see if the button is pressed
bool cInput::IsButtonDown( int Button )
{
// Return the result
return buttonStates.at( Button );
}

// Sets a button to being released manually
void cInput::SetButtonUp( int Button )
{
buttonStates.at( Button ) = false;
}

// Sets a button to being pressed manually
void cInput::SetButtonDown( int Button )
{
buttonStates.at( Button ) = true;
}

// Updates the input system
void cInput::Update()
{
static int lastTicks = SDL_GetTicks();
std::map<std::string, int>::iterator itr_2 = curDelay.begin();
while(itr_2 != curDelay.end())
{
itr_2->second -= (SDL_GetTicks() - lastTicks);
itr_2++;
}
lastTicks = SDL_GetTicks();

itr_2 = curDelay.begin();
while(itr_2 != curDelay.end())
{
if(itr_2->second <= 0)
{
itr_2->second = 0;
noDelayVar[itr_2->first] = true;
}
else
{
noDelayVar[itr_2->first] = false;
}
itr_2++;
}

// Get the first element in the buffer
std::vector<tKey>::iterator itr = inputKeyBuffer.begin();

// Loop while we have events to process
while( itr != inputKeyBuffer.end() )
{
// If we have a keydown event
if( itr->type == SDL_KEYDOWN )
{
// Set the state to being pressed
keyStates[itr->key] = true;

// Call the key handeler for a key press
if( OnKeyDown( (*itr) ) )
{
// If we get here, the event is removed from the buffer
inputKeyBuffer.erase( itr );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr++;
}
}

// If we have a keyup event
else if( itr->type == SDL_KEYUP )
{
// Set the state to being released
keyStates[itr->key] = false;

// Call the key handeler for a key release
if( OnKeyUp( (*itr) ) )
{
// If we get here, the event is removed from the buffer
inputKeyBuffer.erase( itr );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr++;
}
}
}

// Get the first element in the buffer
std::vector<tMouse>::iterator itr2 = inputMouseBuffer.begin();

// Only update if there are events to be processed
if( inputMouseBuffer.size() > 0 )
{
// Stores the last X and Y position of the mouse according to the events
mouseX = (inputMouseBuffer.end()-1)->x;
mouseY = (inputMouseBuffer.end()-1)->y;
}

// Loop while we have events to process
while( itr2 != inputMouseBuffer.end() )
{
// If we have a mouse motion event
if( itr2->type == SDL_MOUSEMOTION )
{
// Run this event handeler and check the result
if( OnMouseMove( (*itr2) ) )
{
// If we get here, the event is removed from the buffer
inputMouseBuffer.erase( itr2 );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr2++;
}
}

// If we have a mouse button press event
else if( itr2->type == SDL_MOUSEBUTTONDOWN )
{
// Set the current button as being pressed
buttonStates[itr2->button] = true;

// If the event is a wheel up
if( itr2->button == SDL_BUTTON_WHEELUP )
{
// Run this event handeler and check the result
if( OnMouseWheelUp( (*itr2) ) )
{
// If we get here, the event is removed from the buffer
inputMouseBuffer.erase( itr2 );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr2++;
}
}

// If the event is a wheel down
else if( itr2->button == SDL_BUTTON_WHEELDOWN )
{
// Run this event handeler and check the result
if( OnMouseWheelDown( (*itr2) ) )
{
// If we get here, the event is removed from the buffer
inputMouseBuffer.erase( itr2 );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr2++;
}
}

// Otherwise it's a regular button
else
{
// Run this event handeler and check the result
if( OnMouseButtonDown( (*itr2) ) )
{
// If we get here, the event is removed from the buffer
inputMouseBuffer.erase( itr2 );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr2++;
}
}
}

// If we have a mouse button release event,
// the wheel is ignored here to avoid duplicate messages
else if( itr2->type == SDL_MOUSEBUTTONUP )
{
// Set the current button as being released
buttonStates[itr2->button] = false;

// Run this event handeler and check the result
if( OnMouseButtonUp( (*itr2) ) )
{
// If we get here, the event is removed from the buffer
inputMouseBuffer.erase( itr2 );
}
else
{
// Otherwise we leave the event in the buffer and continue on
itr2++;
}
}
}
}

// Set the key delay
void cInput::SetDelay(std::string name, unsigned int delay)
{
curDelay[name] = delay;
if(delay)
noDelayVar[name] = false;
else
noDelayVar[name] = true;
}

// General delay variable
bool cInput::NoDelay(std::string name)
{
if(noDelayVar.find(name) == noDelayVar.end())
return true;
return noDelayVar[name];
}

// Called on a key press event.
int cInput::OnKeyDown( const tKey& Key ) { return true; }

// Called on a key release event.
int cInput::OnKeyUp( const tKey& Key ) { return true; }

// Called on a mouse motion event.
int cInput::OnMouseMove( const tMouse& Mouse ) { return true; }

// Called on a mouse button press.
int cInput::OnMouseButtonDown( const tMouse& Mouse ) { return true; }

// Called on a mouse button release.
int cInput::OnMouseButtonUp( const tMouse& Mouse ) { return true; }

// Called on a mouse wheel up event
int cInput::OnMouseWheelUp( const tMouse& Mouse ) { return true; }

// Called on a mouse wheel down event
int cInput::OnMouseWheelDown( const tMouse& Mouse ) { return true; }

// Virtual default deconstructor
cInput::~cInput() { }




Then for the demo/docs on using the system as is:

Main.cpp

#include <sdl.h>

/*****************************************************************************/
// Include the input system's header file
#include "Input.h"
/*****************************************************************************/

/*****************************************************************************/
// My making our own class derived from the cInput class, we have access to
// the event callbacks, so as soon as an event happens, we can handle it as
// needed. Look up each of the tKey and tMouse structs to see what you can
// have access to. I've listed out the key properties for you and one usage.

class MyInput : public cInput
{
// Called on a key press event.
int OnKeyDown( const tKey& Key )
{
// Properties of alt
if( Key.AltDown ) {}
if( Key.LeftAltDown ) {}
if( Key.RightAltDown ) {}

if( Key.CapsDown ) {}
if( Key.NumLockDown ) {}

// Properties of control
if( Key.ControlDown ) {}
if( Key.LeftControlDown ) {}
if( Key.RightControlDown ) {}

// Properties of shift
if( Key.LeftShiftDown ) {}
if( Key.RightShiftDown ) {}
if( Key.ShiftDown ) {}

// Tick of time
Key.time;

// True means remove the event from the queue because your processed it
return true;
}

// Called on a key release event.
int OnKeyUp( const tKey& Key )
{
// True means remove the event from the queue because your processed it
return true;
}

// Called on a mouse motion event.
int OnMouseMove( const tMouse& Mouse )
{
// True means remove the event from the queue because your processed it
return true;
}

// Called on a mouse button press.
int OnMouseButtonDown( const tMouse& Mouse )
{
// True means remove the event from the queue because your processed it
return true;
}

// Called on a mouse button release.
int OnMouseButtonUp( const tMouse& Mouse )
{
// True means remove the event from the queue because your processed it
return true;
}

// Called on a mouse wheel up event
int OnMouseWheelUp( const tMouse& Mouse )
{
// True means remove the event from the queue because your processed it
return true;
}

// Called on a mouse wheel down event
int OnMouseWheelDown( const tMouse& Mouse )
{
// True means remove the event from the queue because your processed it
return true;
}
};

MyInput Input;

// Everything else is the **same**!
/*****************************************************************************/

#pragma comment (lib, "SDLmain.lib")
#pragma comment (lib, "SDL.lib")

SDL_Surface* Screen = 0;
bool done = false;

int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
Screen = SDL_SetVideoMode(640, 480, 0, SDL_DOUBLEBUF);
while(!done)
{
SDL_Event Event;
while(SDL_PollEvent(&Event))
{
if(Event.type == SDL_QUIT)
done = true;
/*****************************************************************************/
// In the event processing loop, call the 'Poll'
// function with the current event.
Input.Poll(Event);
/*****************************************************************************/
}
/*****************************************************************************/
// After the event loop, call the 'Update' function
// to process all events and prepare the system for usage.
Input.Update();
// Once that is called, now from here on until the end of the frame
// you can use the library.
/*****************************************************************************/


// BASIC USAGE EXAMPLES AND DOCS
/******************************************************************************
// Set's the Y coordinate of the cursor, the X remains the same
Input.SetMouseY(32);

// Set's the X and Y coordinates of the cursor
Input.SetMouseXY(100, 100);

// Set's the X coordinate of the cursor, the Y remains the same
Input.SetMouseX(64);

// Manually (logically) release a mouse button from being pressed
Input.SetButtonUp(SDL_BUTTON_LEFT);

// Manually (logically) release a key from being pressed
Input.SetKeyUp(SDLK_SPACE);

// Manually (logically) set a key to being pressed
Input.SetKeyDown(SDLK_a);

// Manually (logically) set a mouse button to being pressed
Input.SetButtonDown(SDL_BUTTON_RIGHT);

// Set the delay after a key press until the next avaliable press
Input.SetKeyDelay(100);

// Set the delay after a general event until the next event (user based)
Input.SetDelay(250);

// Set the delay after a mouse button press until the next avaliable press
Input.SetButtonDelay(150);

// Returns true of there is no general delay, false otherwise
if( Input.NoDelay() )
{
}

// Returns true of there is no key delay, false otherwise
if( Input.CanPressKey() )
{
}

// Returns true of there is no button delay, false otherwise
if( Input.CanPressButton() )
{
}

// Returns true of a key is pressed, false otherwise
if( Input.IsKeyDown(SDL_ESCAPE) )
{
done = true;
}

// Returns true of a mouse button is pressed, false otherwise
if( Input.IsButtonDown(SDL_BUTTON_RIGHT) )
{
done = true;
}

// Get the mouse X position
int y = Input.GetMouseX();

// Get the mouse Y position
int x = Input.GetMouseY();
*******************************************************************************/


// ADVANCED USAGE EXAMPLES AND DOCS
/******************************************************************************
if( Input.NoDelay("Key Q") && Input.IsKeyDown(SDLK_q) )
{
printf("Q\n");
// 25 ms till the q key can be pressed again, or any
// key that checks against Input.CanPressKey() function
Input.SetDelay("Key Q", 25);
}

if( Input.NoDelay("Mouse Left") && Input.IsButtonDown(SDL_BUTTON_LEFT) )
{
printf("MOUSE BUTTON LEFT\n");
// 250 ms till the button can be pressed again, or any
// button that checks against Input.CanPressButton() function
Input.SetDelay("Mouse Left", 250);
}

if( Input.NoDelay("1") && Input.GetMouseX() <= 10 )
{
printf("MOUSE <= 10\n");

// 100 ms till this even is triggered again, or any
// event that checks against Input.NoDelay() function
Input.SetDelay("1", 100);
}
*******************************************************************************/

}

SDL_Quit();
return 0;
}



So it may seem like a lot, and it is, but all the hard work is done already. You just have to use it as you need it, which is rather simple and easy. To use this in your project, simply add the .cpp file and the .h file and you're all done. You will simply have to add in the revelant code, but you will not have to modify your code to make it compatible with this library.

And as you can see from Main2.cpp, if you don't want to use that callback system or don't need it, you can simply use the base cInput variable and be all done. The way this is designed, you could actually have multiple Input systems if you wanted to, but I have not finished that design yet, but you could give it a try if you watned to. Ideallly, what would happens is that there would be one master class that handled the Poll/Updating, and sends out the results to each additional input class you register with it.

So should be self explanatory, but if you need help with it feel free to ask! [smile]

[Edited by - Drew_Benton on January 2, 2006 11:19:19 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!