See what's going on with flipcode!




This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Input Library
  Submitted by



This is an input library, it is setup to be api independent, but the implemented class uses DirectInput. The library cannot compile on its own, but you can add it to your applications. The code is totally free, and may have a few errors because I am not perfect. The input library is divided into several parts. The input manager lists all available devices, and provides an interface for retrieving them. Create an instance of DInputManager to make all devices available. Each device has several functions. The raw input data can be retrieved, and the offsets for buttons can be looked up. There are also some shortcut functions like mouse->Get("button 1"). A shortcut binding class is also provided that can connect to specific keys/axes/etc. There are also functions provided to bind to the first changed value, etc. Have fun with the library.
Send me questions, comments, or complaints, I've been bored lately.


Currently browsing [inputlib.zip] (10,264 bytes) - [dinput/dinput.h] - (719 bytes)

#ifndef DIRECTINPUT
#define DIRECTINPUT

#include <dinput.h> #include <vector> #include "input/input.h"

class DInputManager : public gs_InputManager { public: DInputManager(); ~DInputManager(); // retrieves individual devices // such as mouse, keyboard, or joystick int GetTotal(); gs_InputDevice* Get(int x); gs_InputDevice* Get( char* name);

// pointers provide a way to bind to a specific data item // isValid is a way of checking if that pointer is still valid int isValid( gs_InputDevice* ref);

// private to normal, but public to all directinput devices void AddDevice( gs_InputDevice* device);

vector< gs_InputDevice*> Devices; IDirectInput8* DInput8; };



#endif

Currently browsing [inputlib.zip] (10,264 bytes) - [dinput/ddevice.cpp] - (7,696 bytes)

#include "ddevice.h"
#include "input/codes.h"

#include "mmgr.h"

DInputDevice::DInputDevice(IDirectInputDevice8* device, DInputManager* manager) { Listener = 0; Data = 0; ValueData = 0; StateData = 0;

Device = device; Manager = manager;

// record device name DIDEVICEINSTANCE dinstance; dinstance.dwSize = sizeof(dinstance); Device->GetDeviceInfo( &dinstance);

Type = strlwr(dinstance.tszInstanceName);

// record number of values and states DIDEVCAPS caps; caps.dwSize = sizeof(DIDEVCAPS); Device->GetCapabilities(&caps);

Axes = caps.dwAxes; POVs = caps.dwPOVs; Values = Axes + POVs; States= caps.dwButtons; // set up the cooperative level Device->SetCooperativeLevel(GetActiveWindow(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND | DISCL_NOWINKEY);

// now enumerate all the device pieces and set the // data mode SetFormat(); // set up the return data structure ReturnData.Set( this, ValueData, Values, StateData, States);

// get first set of values SetShortCuts(); Update(); }

DInputDevice::~DInputDevice() { if (Device) Device->Release(); if (Data) delete [] Data; }

gs_InputData& DInputDevice::GetInput() { return ReturnData; }

void DInputDevice::Update() { // this updates the input // get data in a buffered format, then send to all the // classes that want buffered data, and update the state memory int error = Device->Poll();

if (error == DIERR_NOTACQUIRED) { Device->Acquire(); error = Device->Poll(); if (error == DIERR_NOTACQUIRED) return; }

// get current data Device->GetDeviceState(DataSize, Data);

// if any objects want to recieve events, get buffered data if (Listener) { DIDEVICEOBJECTDATA data[BUFFERSIZE]; unsigned long l = BUFFERSIZE; Device->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), data, &l, 0);

// REMEMBER TO CHECK if error == buffer input lost // iterate through all the data in the list for (int x = 0; x < l; x++) { InputState tosend; tosend.Parent = this; tosend.Time = data[x].dwTimeStamp;

// data[x].dwOfs if (data[x].dwOfs < Values*4) tosend.Index = data[x].dwOfs / 4; else tosend.Index = data[x].dwOfs - (3*Values); tosend.Data = (int)data[x].dwData; // actual value // then send it to all that have requested it Listener->Message(&tosend); } } }

void DInputDevice::SetAxisMode( AxisStates state ) { int error;

Device->Unacquire(); // set up the buffer size DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE;

if (state == AxisRelative) dipdw.dwData = DIPROPAXISMODE_REL; else dipdw.dwData = DIPROPAXISMODE_ABS;

error = Device->SetProperty(DIPROP_AXISMODE , &dipdw.diph); }

void DInputDevice::SetFormat() { int offset, x; offset = 0; DIDATAFORMAT format; format.dwSize = sizeof(format); format.dwObjSize = sizeof( DIOBJECTDATAFORMAT );

if ( Type.find( "mouse") != -1) format.dwFlags = DIDF_RELAXIS; else format.dwFlags = DIDF_ABSAXIS;

DIOBJECTDATAFORMAT* array = new DIOBJECTDATAFORMAT[Values+States];

DIOBJECTDATAFORMAT toadd; toadd.pguid = 0; // wildcard toadd.dwFlags = 0; // ignore aspect for (x = 0; x < Axes; x++) { toadd.dwOfs = offset; // byte offset toadd.dwType = DIDFT_AXIS | DIDFT_ANYINSTANCE; // any axis offset+=4; array[x] = toadd; }

for (x = 0; x < POVs; x++) { toadd.dwOfs = offset; // byte offset toadd.dwType = DIDFT_POV | DIDFT_ANYINSTANCE; // any pov switch offset+=4; array[x+Axes] = toadd; }

for (x = 0; x < States; x++) { toadd.dwOfs = offset; // byte offset toadd.dwType = DIDFT_BUTTON | DIDFT_ANYINSTANCE; // any button offset+=1; array[x+Axes+POVs] = toadd; }

DataSize = offset + (4-(offset%4));

format.dwDataSize = DataSize; // Size of a data packet returned by the device, in bytes. This value must be a multiple of 4 and must exceed the largest offset value for an object's data within the data packet. format.dwNumObjs = Values + States; // Number of objects in the rgodf array. format.rgodf = array; // Address to an array // special keyboard only format, used for proper indexing if (Type.find("keyboard") != -1) { format = c_dfDIKeyboard; DataSize = 256; States = 256; }



int error = Device->SetDataFormat( &format);

delete [] array;

// now set up the data arrays for getting input Data = new char[DataSize]; memset(Data,0, DataSize); ValueData = (int*)&Data[0]; StateData = (unsigned char*)&Data[Values*4];

}

void DInputDevice::SetShortCuts() { if (GetType().find("mouse") != -1) { MOUSEX = 0; MOUSEY = 1;

if (Axes > 2) MOUSEZ = 2; else MOUSEZ = -1; MOUSEBUTTON0 = Values + 0; MOUSEBUTTON1 = Values + 1; if (States > 2) MOUSEBUTTON2 = Values + 2; else MOUSEBUTTON2 = -1; } if (GetType().find("joystick") != -1) { JOYSTICKX = 0; JOYSTICKY = 1;

if (Axes > 2) JOYSTICKZ = 2; else JOYSTICKZ = -1; JOYSTICKBUTTON0 = Values + 0; JOYSTICKBUTTON1 = Values + 1; if (States > 2) JOYSTICKBUTTON2 = Values + 2; else JOYSTICKBUTTON2 = -1;

if (States > 3) JOYSTICKBUTTON3 = Values + 3; else JOYSTICKBUTTON3 = -1;

}

}

BOOL CALLBACK DIEnumDeviceObjectsCallback( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { DInputDevice* d = (DInputDevice*)pvRef;

if (d->CheckName( (char*)lpddoi->tszName ) != 0) return DIENUM_STOP;

return DIENUM_CONTINUE; }

int DInputDevice::CheckName( char* name) { if (CheckMode == 1) { if (toCheck.find( strlwr(name) ) != -1) { Found = Enumerated; return 1; } } else { if (Enumerated == Found) { toCheck = name; return 1; } }

Enumerated++; return 0; }

int DInputDevice::GetIndex( string name ) { Enumerated = 0; Found = -1; toCheck = name.c_str(); // force to copy string, otherwise uses pointer to same resource and tries to delete memory across dll CheckMode = 1; // this is probably slow, but it works // enumerate all the objects // check readable name // if readable name == name // then return index // if none work, return -1 Device->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS); Device->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_POV); Device->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_BUTTON);

return Found; }

string DInputDevice::GetName( int index) { toCheck = ""; CheckMode = 2; Enumerated = 0; Found = index; return toCheck; }

int DInputDevice::AddNotify( gs_InputListener* b) { // if there are no listeners, the input buffer // is not needed, if there are, make sure there is a buffer SetInputBuffer(BUFFERSIZE);

Listener = b; return 1; }

int DInputDevice::RemoveNotify( gs_InputListener* b) { Listener = 0;

// if there are no listeners, the input buffer // is not needed SetInputBuffer(0);

return 1; }

void DInputDevice::SetInputBuffer(int size) { Device->Unacquire(); // set up the buffer size DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = BUFFERSIZE; // buffer size int error = Device->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph); }

Currently browsing [inputlib.zip] (10,264 bytes) - [dinput/ddevice.h] - (1,762 bytes)

#ifndef DINPUTDEVICEINC
#define DINPUTDEVICEINC

#include <string> #include "dinput.h"

// data usually is reported // axes, slider, povs, buttons #define BUFFERSIZE 40

class DInputDevice : public gs_InputDevice { public: DInputDevice(IDirectInputDevice8* device, DInputManager* manager); ~DInputDevice();

string GetType() { return Type; }

// this returns input but does not update // the pointer it returns should be valid throughout // the life of the device gs_InputData& GetInput(); void Update(); // this updates the input void SetAxisMode( AxisStates state ); int GetIndex( string name ); string GetName( int index);

int GetTotalAxes() { return Axes; } int GetTotalButtons() { return States; } int GetTotalPOVs() { return POVs; }

void Set(int index, int pos) { }// REMEMBER UNIMPLEMENTED void SetInputBuffer(int size); int AddNotify( gs_InputListener* b); int RemoveNotify( gs_InputListener* b);

// private to all but file scope (enumeration function needs) void AddItem(LPCDIDEVICEOBJECTINSTANCE obj); // adds device axes, keys, etc int CheckName( char* name );

private: gs_InputListener* Listener;

void SetFormat(); void SetShortCuts(); // this sets up the programmer shortcuts (ie MOUSEX, MOUSEY, etc) gs_InputData ReturnData; string Type; IDirectInputDevice8* Device; DInputManager* Manager;

char* Data; int* ValueData; unsigned char* StateData; int DataSize; int Values; // any ranges (axes, povs, sliders) int States; // off/on devices(keyboard keys, mouse buttons) int Axes; int POVs;

// temporary variable that need to be global to the object string toCheck; int Found; int Enumerated; int CheckMode; };

#endif

Currently browsing [inputlib.zip] (10,264 bytes) - [dinput/dinput.cpp] - (1,955 bytes)

#include <string>
using namespace std;

#include "dinput.h" #include "core.h" #include "ddevice.h"

#include "mmgr.h"

#define SafeRelease(r) if(r) { r->Release(); }

// enumeration function BOOL CALLBACK DIEnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { DInputManager* d = (DInputManager*)pvRef; IDirectInputDevice8* device;

d->DInput8->CreateDevice(lpddi->guidInstance, &device, 0); if (device) d->AddDevice( new DInputDevice( device, d));

return DIENUM_CONTINUE; // or DIENUM_STOP }

DInputManager::DInputManager() {

// initialize direct input // and enumerate all devices int error = DirectInput8Create( GethInstance(), // HINSTANCE DIRECTINPUT_VERSION, // Verstion IID_IDirectInput8A, // ANSI version ( replace a with w for unicode) (void**)&DInput8, 0); // COM Agregation if (!DInput8) return;

DInput8->EnumDevices(0, // all device types DIEnumCallback,// which callback this, // optional value to pass to callback DIEDFL_ATTACHEDONLY); // why would I want to enumerate unattached devices? }

DInputManager::~DInputManager() { SafeRelease(DInput8);

for (int x = 0; x < Devices.size(); x++) delete Devices[x];

}

// retrieves individual devices // such as mouse, keyboard, or joystick int DInputManager::GetTotal() { return Devices.size(); }

gs_InputDevice* DInputManager::Get(int x) { return Devices[x]; }

gs_InputDevice* DInputManager::Get( char* name) { for (int x = 0; x < Devices.size(); x++) { if (Devices[x]->GetType().find(name) != -1) return Devices[x]; } return 0; }

// pointers provide a way to bind to a specific data item // isValid is a way of checking if that pointer is still valid int DInputManager::isValid( gs_InputDevice* ref) { // REMEMBER TO FILL return 1; }

void DInputManager::AddDevice( gs_InputDevice* device) { Devices.push_back(device); }

Currently browsing [inputlib.zip] (10,264 bytes) - [binding.cpp] - (2,002 bytes)

#include "binding.h"

class EventListener : public gs_InputListener { public: EventListener( gs_InputManager *manager, gs_Binding* parent, int checkflags) { Device = 0; Manager = manager; Parent = parent; CheckFlags = checkflags; }

EventListener( gs_InputDevice *device, gs_Binding* parent, int checkflags) { Device = device; Manager = 0; Parent = parent; CheckFlags = checkflags; }

int Message( gs_InputState* s) { // check if this is the type of input wanted int InputType = 0;

if (s->Index < s->Parent->GetTotalAxes()) InputType = AXISONLY; else if (s->Index < s->Parent->GetTotalPOVs()) InputType = POVONLY; else if (s->Index < s->Parent->GetTotalButtons()) InputType = BUTTONONLY;

if (CheckFlags == InputType) { Parent->Connect(&s->Parent->GetInput(), s->Index);

// clean up if (Manager) { // added notify to multiple devices for(int x = 0; x < Manager->GetTotal(); x++) Manager->Get(x)->RemoveNotify(this); } else // just clean up single device Device->RemoveNotify(this);

delete this; // I know this is not right, but it is the best solution I could think of to get rid of object after connection return 1; } return 1; }

gs_InputDevice *Device; gs_InputManager *Manager; gs_Binding* Parent; int CheckFlags; };

int gs_Binding::ConnectFirst(gs_InputManager* manager, int flags) { Disconnect();

EventListener* e = new EventListener( manager, this, flags);

for( int x = 0; x < manager->GetTotal(); x++) manager->Get(x)->AddNotify(e); return 1; }

int gs_Binding::ConnectFirst(gs_InputDevice* device, int flags) { Disconnect(); device->AddNotify( new EventListener( device, this, flags));

return 1; }

void gs_Binding::Connect( gs_InputData* source, int index) { Source = source; Index = index; }

int gs_Binding::Get() { if (!Source) return 0; return Source->Get(Index); }

Currently browsing [inputlib.zip] (10,264 bytes) - [input.cpp] - (966 bytes)

#include "input.h"

// initialize the extern variables int MOUSEX; int MOUSEY; int MOUSEZ; // scroll wheel int MOUSEBUTTON0;// left int MOUSEBUTTON1;// right int MOUSEBUTTON2;// middle mouse button int JOYSTICKX; int JOYSTICKY; int JOYSTICKZ;

int JOYSTICKBUTTON0; int JOYSTICKBUTTON1; int JOYSTICKBUTTON2; int JOYSTICKBUTTON3;

void gs_InputManager::Run() { for( int x = 0; x < GetTotal(); x++) { Get(x)->Update(); } }



/// INPUT DEVICE ///////////////////////////////////// ////////////////////////////////////////////////////// gs_Binding gs_InputDevice::GetBinding( int index) { return gs_Binding( &GetInput(), index); }

// more friendly versions gs_Binding gs_InputDevice::GetBinding( string name) { return gs_Binding( &GetInput(), GetIndex(name) ); }

int gs_InputDevice::Get( int index) { return GetInput().Get(index); }

int gs_InputDevice::Get( string name) { return Get( GetIndex(name)); }

Currently browsing [inputlib.zip] (10,264 bytes) - [binding.h] - (1,161 bytes)

#ifndef BINDINGINC
#define BINDINGINC

class gs_Binding; #include "input.h"

#define AXISONLY 1 #define BUTTONONLY 2 #define KEYONLY BUTTONONLY #define POVONLY 3

// this class provides a way of connecting device input // to an application class gs_Binding { public: gs_Binding() { Disconnect(); } gs_Binding( gs_Binding* other) { Connect(other->Source, other->Index); } gs_Binding( gs_InputData* source, int index) { Connect(source,index);} ~gs_Binding() { } // connects to the first key that recieves input // flags allow for selective connecting // both return immediately (before actually connected) because they wait for the user to send an event int ConnectFirst(gs_InputManager* manager, int flags); int ConnectFirst(gs_InputDevice* device, int flags);

// for checking if it is connecte int isConnected() { return ((Source != 0) && (Index != -1)); }

// void Disconnect() { Source = 0; Index = -1; }

// bind this to a specific input void Connect( gs_InputData* source, int index); // for retrieving the value int Get();

private: gs_InputData* Source; int Index; };

#endif

Currently browsing [inputlib.zip] (10,264 bytes) - [codes.h] - (5,694 bytes)

/////////////////////////////////////////////////////
//
//	device value mapping shortcuts
//	these provide easy and device independant names
//	for a programmer to refer to
//	they should be treated like defines
//	but in actuallity they are ints
//	so that the input device handler can set them
//
/////////////////////////////////////////////////////
#ifndef INPUTCODESINC
#define INPUTCODESINC



extern int MOUSEX; extern int MOUSEY; extern int MOUSEZ; // scroll wheel extern int MOUSEBUTTON0;// left extern int MOUSEBUTTON1;// right extern int MOUSEBUTTON2;// middle mouse button extern int JOYSTICKX; extern int JOYSTICKY; extern int JOYSTICKZ;

extern int JOYSTICKBUTTON0; extern int JOYSTICKBUTTON1; extern int JOYSTICKBUTTON2; extern int JOYSTICKBUTTON3;

///////////////////////////////////////// // // keyboard scan codes // ///////////////////////////////////////// #define KEY_ESC 0x01 #define KEY_1 0x02 #define KEY_2 0x03 #define KEY_3 0x04 #define KEY_4 0x05 #define KEY_5 0x06 #define KEY_6 0x07 #define KEY_7 0x08 #define KEY_8 0x09 #define KEY_9 0x0A #define KEY_0 0x0B #define KEY_MINUS 0x0C /* - on main keyboard */ #define KEY_EQUALS 0x0D #define KEY_BACKSPACE 0x0E /* backspace */ #define KEY_TAB 0x0F #define KEY_Q 0x10 #define KEY_W 0x11 #define KEY_E 0x12 #define KEY_R 0x13 #define KEY_T 0x14 #define KEY_Y 0x15 #define KEY_U 0x16 #define KEY_I 0x17 #define KEY_O 0x18 #define KEY_P 0x19 #define KEY_LBRACKET 0x1A #define KEY_RBRACKET 0x1B #define KEY_ENTER 0x1C /* Enter on main keyboard */ #define KEY_LCTRL 0x1D #define KEY_A 0x1E #define KEY_S 0x1F #define KEY_D 0x20 #define KEY_F 0x21 #define KEY_G 0x22 #define KEY_H 0x23 #define KEY_J 0x24 #define KEY_K 0x25 #define KEY_L 0x26 #define KEY_SEMICOLON 0x27 #define KEY_APOSTROPHE 0x28 #define KEY_TILDE 0x29 /* accent grave */ #define KEY_LSHIFT 0x2A #define KEY_BACKSLASH 0x2B #define KEY_Z 0x2C #define KEY_X 0x2D #define KEY_C 0x2E #define KEY_V 0x2F #define KEY_B 0x30 #define KEY_N 0x31 #define KEY_M 0x32 #define KEY_COMMA 0x33 #define KEY_PERIOD 0x34 /* . on main keyboard */ #define KEY_SLASH 0x35 /* / on main keyboard */ #define KEY_RSHIFT 0x36 #define KEY_NUMPADASTERISK 0x37 /* * on numeric keypad */ #define KEY_LALT 0x38 /* left Alt */ #define KEY_SPACE 0x39 #define KEY_CAPS 0x3A #define KEY_F1 0x3B #define KEY_F2 0x3C #define KEY_F3 0x3D #define KEY_F4 0x3E #define KEY_F5 0x3F #define KEY_F6 0x40 #define KEY_F7 0x41 #define KEY_F8 0x42 #define KEY_F9 0x43 #define KEY_F10 0x44 #define KEY_NUMLOCK 0x45 #define KEY_SCROLL 0x46 /* Scroll Lock */ #define KEY_NUMPAD7 0x47 #define KEY_NUMPAD8 0x48 #define KEY_NUMPAD9 0x49 #define KEY_NUMPADMINUS 0x4A /* - on numeric keypad */ #define KEY_NUMPAD4 0x4B #define KEY_NUMPAD5 0x4C #define KEY_NUMPAD6 0x4D #define KEY_NUMPADPLUS 0x4E /* + on numeric keypad */ #define KEY_NUMPAD1 0x4F #define KEY_NUMPAD2 0x50 #define KEY_NUMPAD3 0x51 #define KEY_NUMPAD0 0x52 #define KEY_NUMPADPERIOD 0x53 /* . on numeric keypad */ #define KEY_F11 0x57 #define KEY_F12 0x58 #define KEY_F13 0x64 /* (NEC PC98) */ #define KEY_F14 0x65 /* (NEC PC98) */ #define KEY_F15 0x66 /* (NEC PC98) */ #define KEY_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */ #define KEY_COLON 0x92 /* (NEC PC98) */ #define KEY_UNDERLINE 0x93 /* (NEC PC98) */ #define KEY_NUMPADENTER 0x9C /* Enter on numeric keypad */ #define KEY_RCTRL 0x9D #define KEY_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */ #define KEY_NUMPADSLASH 0xB5 /* / on numeric keypad */ #define KEY_RALT 0xB8 /* right Alt */ #define KEY_HOME 0xC7 /* Home on arrow keypad */ #define KEY_UP 0xC8 /* UpArrow on arrow keypad */ #define KEY_PGUP 0xC9 /* PgUp on arrow keypad */ #define KEY_LEFT 0xCB /* LeftArrow on arrow keypad */ #define KEY_RIGHT 0xCD /* RightArrow on arrow keypad */ #define KEY_END 0xCF /* End on arrow keypad */ #define KEY_DOWN 0xD0 /* DownArrow on arrow keypad */ #define KEY_PGDN 0xD1 /* PgDn on arrow keypad */ #define KEY_INS 0xD2 /* Insert on arrow keypad */ #define KEY_DEL 0xD3 /* Delete on arrow keypad */ #define KEY_LWIN 0xDB /* Left Windows key */ #define KEY_RWIN 0xDC /* Right Windows key */ #define KEY_APPS 0xDD /* AppMenu key */



#endif

Currently browsing [inputlib.zip] (10,264 bytes) - [input.h] - (4,288 bytes)

#ifndef INPUTINC
#define INPUTINC

#include <list> #include <string>

#include "behavior.h"

enum InputTypes { AxisInput, ButtonInput }; enum AxisStates { AxisRelative, AxisAbsolute };

class gs_InputDevice; class gs_InputData;

struct InputState { gs_InputDevice* Parent; unsigned int Time; // time in milliseconds int Index; // which value (x,y or z axis, a,b,or c key) int Data; // actual value }; typedef InputState gs_InputState;

// this listens for any input events // message is passed as an inputstate struct class gs_InputListener { public: // see more notes under gs_InputDevice::AddNotify(..) virtual int Message(gs_InputState* input) { return 0; } };

class gs_InputManager : public gs_Behavior { public: // retrieves individual devices // such as mouse, keyboard, or joystick virtual int GetTotal() { return 0; } virtual gs_InputDevice* Get(int x) { return 0; } virtual gs_InputDevice* Get( char* name) { return 0; }

// pointers provide a way to bind to a specific data item // isValid is a way of checking if that pointer is still valid virtual int isValid( gs_InputDevice* ref) { return 1; }

// polls and updates all the input devices void Run(); };

//////////////////////////////////////////////// #include "binding.h"

class gs_InputDevice { public: virtual ~gs_InputDevice() { };

// this returns input but does not update // the pointer it returns should be valid throughout // the life of the device virtual gs_InputData& GetInput() = 0; virtual void Update() { }; // this updates the input virtual void Set(int index, int pos) { } // gets the index for a common device part // ex. a, x axis, joystick button 1 // flags are defined in binding.h virtual int GetIndex( string name ) { return 0; } virtual string GetName( int index) { return ""; }

// returns a binding that can retrieve data // type = value or state gs_Binding GetBinding( int index );

// more friendly version gs_Binding GetBinding( string name); int Get( int index); int Get( string name);

//////////////////////// virtual int GetTotalAxes() { return 0;} virtual int GetTotalButtons() { return 0; } int GetTotalKeys() { return GetTotalButtons(); } virtual int GetTotalPOVs() { return 0; }

virtual void SetInputBuffer(int size) { } virtual int AddNotify( gs_InputListener* b) { return 0; } virtual int RemoveNotify( gs_InputListener* b) { return 0; } // this calls a method with parameters // total events // pointer to event list // the overhead is acceptable because a function would need // to be called to store the input anyhow virtual void SetAxisMode( AxisStates state ) { } virtual string GetType() { return "unknown";} // get device type (ie mouse, keyboard, joystick, ff joystick) };

class gs_InputData { public: // this needs to be set at the beginning of the lifetime of // this object // it is not a constructor because then it would be more // difficult to include as a non-pointer member void Set( gs_InputDevice *parent, int *v, int tv, unsigned char* s, int ts) { Parent = parent; ValueData = v; TotalValues = tv; StateData = s; TotalStates = ts; } // different types of data // axes, pov switch // button states // value is a variable of any amount that indicates // a device position (slider, axis, etc) // macros can be used to offer lexical names for values // ex. KEY_A = scancode of a = index for getvalue on keyboard inline const int GetValue( int index) { return ValueData[index]; }

// state is any on/off switch (keyboard, buttons, etc) inline const unsigned char GetState( int index) { return StateData[index]; }

inline const int Get( int index) { // REMEMBER DO BOUNDS CHECKING if (index < TotalValues) return ValueData[index]; else return StateData[index-TotalValues]; }

inline int GetTotalValues() { return TotalValues; } inline int GetTotalStates() { return TotalStates; } inline int GetTotal() { return TotalValues + TotalStates; }

inline gs_InputDevice* GetParent(); private: gs_InputDevice *Parent; int *ValueData; unsigned char *StateData;

int TotalValues; int TotalStates; };

#endif

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.