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.