LilyPad 0.9.9, more or less

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@472 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
mattmenke 2009-02-11 09:24:56 +00:00
parent 343afaffdf
commit 3476172c49
40 changed files with 8944 additions and 0 deletions

1714
plugins/LilyPad/Config.cpp Normal file

File diff suppressed because it is too large Load Diff

68
plugins/LilyPad/Config.h Normal file
View File

@ -0,0 +1,68 @@
#ifndef CONFIG_H
#define CONFIG_H
typedef BOOL (CALLBACK *_RegisterRawInputDevices)(PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize);
typedef UINT (CALLBACK *_GetRawInputDeviceInfo)(HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize);
typedef UINT (CALLBACK *_GetRawInputData)(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader);
typedef UINT (CALLBACK *_GetRawInputDeviceList)(PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT puiNumDevices, UINT cbSize);
extern _RegisterRawInputDevices pRegisterRawInputDevices;
extern _GetRawInputDeviceInfo pGetRawInputDeviceInfo;
extern _GetRawInputData pGetRawInputData;
extern _GetRawInputDeviceList pGetRawInputDeviceList;
#include "global.h"
#include "InputManager.h"
struct GeneralConfig {
public:
u8 disablePad[2];
u8 mouseUnfocus;
u8 disableScreenSaver;
u8 closeHacks;
u8 axisButtons;
DeviceAPI keyboardApi;
DeviceAPI mouseApi;
struct {
u8 directInput;
u8 xInput;
} gameApis;
u8 debug;
u8 background;
u8 multipleBinding;
u8 forceHide;
u8 GH2;
// Derived value, calculated by GetInput().
u8 ignoreKeys;
u8 GSThreadUpdates;
u8 escapeFullscreenHack;
u8 guitar[2];
u8 AutoAnalog[2];
wchar_t lastSaveConfigPath[MAX_PATH+1];
wchar_t lastSaveConfigFileName[MAX_PATH+1];
};
extern GeneralConfig config;
void UnloadConfigs();
/*
inline int GetNeededInput(HWND hWnd, int configMode) {
return GetInput(hWnd, flags, configMode);
}*/
void AddIgnore(LPARAM k);
int LoadSettings(int force = 0, wchar_t *file = 0);
void CALLBACK PADconfigure();
// Refreshes the set of enabled devices.
void RefreshEnabledDevices(int updateDeviceList = 0);
#endif

View File

@ -0,0 +1,25 @@
#include "global.h"
#include "DeviceEnumerator.h"
#include "InputManager.h"
#include "WindowsMessaging.h"
#include "DirectInput.h"
#include "KeyboardHook.h"
#include "RawInput.h"
#include "XInput.h"
void EnumDevices() {
// Needed for enumeration of some device types.
dm->ReleaseInput();
InputDeviceManager *oldDm = dm;
dm = new InputDeviceManager();
EnumHookDevices();
EnumWindowsMessagingDevices();
EnumRawInputDevices();
EnumXInputDevices();
EnumDirectInputDevices();
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
delete oldDm;
}

View File

@ -0,0 +1,13 @@
// Shouldn't really be here, but not sure where else to put it.
struct InitInfo {
// 1 when binding key to ignore.
int bindingIgnore;
HWND hWndTop;
HWND hWnd;
// For config screen, need to eat button's message handling.
HWND hWndButton;
};
void EnumDevices();

View File

@ -0,0 +1,127 @@
#include "Global.h"
#include "InputManager.h"
#include "DeviceEnumerator.h"
#include "resource.h"
#include "KeyboardQueue.h"
#include <math.h>
Device *dev;
INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam) {
int i;
HWND hWndList = GetDlgItem(hWnd, IDC_LIST);
static int fullRefresh;
if (dev) {
switch (msg) {
case WM_INITDIALOG:
{
fullRefresh = 1;
SetWindowText(hWnd, dev->displayName);
LVCOLUMNW c;
c.mask = LVCF_TEXT | LVCF_WIDTH;
c.cx = 151;
c.pszText = L"Control";
ListView_InsertColumn(hWndList, 0, &c);
c.cx = 90;
c.pszText = L"Value";
ListView_InsertColumn(hWndList, 1, &c);
ListView_DeleteAllItems(hWndList);
LVITEM item;
item.mask = LVIF_TEXT;
item.iSubItem = 0;
for (i=0; i<dev->numVirtualControls; i++) {
item.pszText = dev->GetVirtualControlName(dev->virtualControls+i);
item.iItem = i;
ListView_InsertItem(hWndList, &item);
}
SetTimer(hWnd, 1, 200, 0);
}
//break;
case WM_TIMER:
{
InitInfo info = {0, hWnd, hWnd, hWndList};
dm->Update(&info);
LVITEMW item;
item.mask = LVIF_TEXT;
item.iSubItem = 1;
//ShowWindow(hWndList, 0);
//LockWindowUpdate(hWndList);
if (!dev->active) {
item.pszText = L"?";
for (i=0; i<dev->numVirtualControls; i++) {
item.iItem = i;
ListView_SetItem(hWndList, &item);
}
fullRefresh = 1;
}
else {
for (i=0; i<dev->numVirtualControls; i++) {
if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) {
VirtualControl *c = dev->virtualControls + i;
wchar_t temp[50];
int val = dev->virtualControlState[i];
if (c->uid & (UID_POV)) {
wsprintfW(temp, L"%i", val);
}
else {
wchar_t *sign = L"";
if (val < 0) {
sign = L"-";
val = -val;
}
if ((c->uid& UID_AXIS) && val) {
val = val;
}
val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN);
wsprintfW(temp, L"%s%i.%03i", sign, val/1000, val%1000);
}
item.pszText = temp;
item.iItem = i;
ListView_SetItem(hWndList, &item);
}
}
dm->PostRead();
fullRefresh = 0;
}
//LockWindowUpdate(0);
//ShowWindow(hWndList, 1);
//UpdateWindow(hWnd);
}
break;
case WM_NOTIFY:
if (1) {
PSHNOTIFY* n = (PSHNOTIFY*) lParam;
if (n->hdr.idFrom != IDC_LIST || n->hdr.code != LVN_KEYDOWN) break;
NMLVKEYDOWN *key = (NMLVKEYDOWN *) n;
if (key->wVKey != VK_ESCAPE) break;
}
else {
case WM_ACTIVATE:
if (wParam != WA_INACTIVE) break;
}
case WM_CLOSE:
KillTimer(hWnd, 1);
dm->ReleaseInput();
// Prevents reaching this branch again.
dev = 0;
EndDialog(hWnd, 1);
break;
default:
break;
}
}
return 0;
}
void Diagnose(int id, HWND hWnd) {
// init = 0;
dev = dm->devices[id];
for (int i=0; i<dm->numDevices; i++) {
if (i != id) dm->DisableDevice(i);
// Shouldn't be needed.
else dm->EnableDevice(i);
}
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog);
ClearKeyQueue();
}

View File

@ -0,0 +1,6 @@
#ifndef DIAGNOSTICS_H
#define DIAGNOSTICS_H
void Diagnose(int id, HWND hWnd);
#endif

View File

@ -0,0 +1,443 @@
#include "global.h"
#include "VKey.h"
#include "DirectInput.h"
#include <dinput.h>
#include "InputManager.h"
#include "DeviceEnumerator.h"
inline static u16 flipShort(u16 s) {
return (s>>8) | (s<<8);
}
inline static u32 flipLong(u32 l) {
return (((u32)flipShort((u16)l))<<16) | flipShort((u16)(l>>16));
}
static void GUIDtoString(wchar_t *data, const GUID *pg) {
wsprintfW(data, L"%08X-%04X-%04X-%04X-%04X%08X",
pg->Data1, (u32)pg->Data2, (u32)pg->Data3,
flipShort(((u16*)pg->Data4)[0]),
flipShort(((u16*)pg->Data4)[1]),
flipLong(((u32*)pg->Data4)[1]));
}
static int StringToGUID(GUID *pg, wchar_t *dataw) {
char data[100];
if (wcslen(dataw) > 50) return 0;
int w = 0;
while (dataw[w]) {
data[w] = (char) dataw[w];
w++;
}
data[w] = 0;
u32 temp[5];
sscanf(data, "%08X-%04X-%04X-%04X-%04X%08X",
&pg->Data1, temp, temp+1,
temp+2, temp+3, temp+4);
pg->Data2 = (u16) temp[0];
pg->Data3 = (u16) temp[1];
((u16*)pg->Data4)[0] = flipShort((u16)temp[2]);
((u16*)pg->Data4)[1] = flipShort((u16)temp[3]);
((u32*)pg->Data4)[1] = flipLong(temp[4]);
return 1;
}
struct DI8Effect {
IDirectInputEffect *die;
int scale;
};
BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef);
class DirectInputDevice : public Device {
public:
DI8Effect *diEffects;
IDirectInputDevice8 *did;
DirectInputDevice(DeviceType type, IDirectInputDevice8* did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID) : Device(DI, type, displayName, instanceID, productID) {
int i;
diEffects = 0;
this->did = did;
did->EnumEffects(EnumEffectsCallback, this, DIEFT_ALL);
did->EnumObjects(EnumDeviceObjectsCallback, this, DIDFT_ALL);
DIOBJECTDATAFORMAT *formats = (DIOBJECTDATAFORMAT*)malloc(sizeof(DIOBJECTDATAFORMAT) * numPhysicalControls);
for (i=0; i<numPhysicalControls; i++) {
formats[i].pguid = 0;
formats[i].dwType = physicalControls[i].type | DIDFT_MAKEINSTANCE(physicalControls[i].id);
formats[i].dwOfs = 4*i;
formats[i].dwFlags = 0;
}
DIDATAFORMAT format;
format.dwSize = sizeof(format);
format.dwDataSize = 4 * numPhysicalControls;
format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
format.dwFlags = 0;
format.dwNumObjs = numPhysicalControls;
format.rgodf = formats;
int res = did->SetDataFormat(&format);
for (i=0; i<numPhysicalControls; i++) {
if (physicalControls[i].type == ABSAXIS) {
DIPROPRANGE prop;
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
prop.diph.dwSize = sizeof(DIPROPRANGE);
prop.diph.dwObj = formats[i].dwType;
prop.diph.dwHow = DIPH_BYID;
prop.lMin = -FULLY_DOWN;
prop.lMax = FULLY_DOWN;
did->SetProperty(DIPROP_RANGE, &prop.diph);
// May do something like this again, if there's any need.
/*
if (FAILED(DI->did->SetProperty(DIPROP_RANGE, &prop.diph))) {
if (FAILED(DI->did->GetProperty(DIPROP_RANGE, &prop.diph))) {
// ????
DI->objects[i].min = prop.lMin;
DI->objects[i].max = prop.lMax;
continue;
}
}
DI->objects[i].min = prop.lMin;
DI->objects[i].max = prop.lMax;
//*/
}
}
free(formats);
}
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {
unsigned int index = binding - pads[0].ffBindings;
if (index >= (unsigned int)pads[0].numFFBindings) {
index = pads[0].numFFBindings + (binding - pads[1].ffBindings);
}
IDirectInputEffect *die = diEffects[index].die;
if (die) {
DIEFFECT dieffect;
memset(&dieffect, 0, sizeof(dieffect));
union {
DIPERIODIC periodic;
DIRAMPFORCE ramp;
DICONSTANTFORCE constant;
};
//cf.lMagnitude = 0;
//memset(&dieffect, 0, sizeof(dieffect));
dieffect.dwSize = sizeof(dieffect);
//dieffect.lpEnvelope = 0;
dieffect.dwStartDelay = 0;
dieffect.lpvTypeSpecificParams = &periodic;
int magnitude = abs((int)((force*10000*(__int64)diEffects[index].scale)/BASE_SENSITIVITY/255));
if (magnitude > 10000) magnitude = 10000;
int type = ffEffectTypes[binding->effectIndex].type;
if (type == EFFECT_CONSTANT) {
dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
constant.lMagnitude = magnitude;
}
else if (type == EFFECT_PERIODIC) {
dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC);
periodic.dwMagnitude = 0;
periodic.lOffset = magnitude;
periodic.dwPhase = 0;
periodic.dwPeriod = 2000000;
}
else if (type == EFFECT_RAMP) {
dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
ramp.lEnd = ramp.lStart = magnitude;
}
dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS;
dieffect.dwDuration = 2000000;
die->SetParameters(&dieffect, DIEP_TYPESPECIFICPARAMS | DIEP_START);
}
}
int Activate(void *d) {
int i, j;
if (active) Deactivate();
InitInfo *info = (InitInfo*)d;
// Note: Have to use hWndTop to properly hide cursor for mouse device.
if (type == OTHER) {
did->SetCooperativeLevel(info->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE);
}
else if (type == KEYBOARD) {
did->SetCooperativeLevel(info->hWndTop, DISCL_FOREGROUND);
}
else {
did->SetCooperativeLevel(info->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
}
if (did->Acquire() != DI_OK) {
return 0;
}
AllocState();
diEffects = (DI8Effect*) calloc(pads[0].numFFBindings + pads[1].numFFBindings, sizeof(DI8Effect));
for (i=0; i<pads[0].numFFBindings + pads[1].numFFBindings; i++) {
ForceFeedbackBinding *b = 0;
if (i >= pads[0].numFFBindings) {
b = &pads[1].ffBindings[i-pads[0].numFFBindings];
}
else
b = &pads[0].ffBindings[i];
ForceFeedbackEffectType *eff = ffEffectTypes + b->effectIndex;
GUID guid;
if (!StringToGUID(&guid, eff->effectID)) continue;
DIEFFECT dieffect;
memset(&dieffect, 0, sizeof(dieffect));
dieffect.dwSize = sizeof(dieffect);
dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS;
dieffect.dwDuration = 2000000;
dieffect.dwGain = 10000;
dieffect.dwTriggerButton = DIEB_NOTRIGGER;
union {
DIPERIODIC pediodic;
DIRAMPFORCE ramp;
DICONSTANTFORCE constant;
} stuff = {0,0,0,0};
if (eff->type == EFFECT_CONSTANT) {
dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
}
else if (eff->type == EFFECT_PERIODIC) {
dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC);
}
else if (eff->type == EFFECT_RAMP) {
dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
}
dieffect.lpvTypeSpecificParams = &stuff;
int maxForce = 0;
int numAxes = 0;
int *axes = (int*) malloc(sizeof(int) * 3 * numFFAxes);
DWORD *axisIDs = (DWORD*)(axes + numFFAxes);
LONG *dirList = (LONG*)(axisIDs + numFFAxes);
dieffect.rgdwAxes = axisIDs;
dieffect.rglDirection = dirList;
for (j=0; j<numFFAxes; j++) {
if (b->axes[j].force) {
int force = abs(b->axes[j].force);
if (force > maxForce) {
maxForce = force;
}
axes[numAxes] = j;
axisIDs[numAxes] = ffAxes[j].id;
dirList[numAxes] = b->axes[j].force;
numAxes++;
}
}
if (!numAxes) {
free(axes);
continue;
}
dieffect.cAxes = numAxes;
diEffects[i].scale = maxForce;
if (!SUCCEEDED(did->CreateEffect(guid, &dieffect, &diEffects[i].die, 0))) {
diEffects[i].die = 0;
diEffects[i].scale = 0;
}
free(axes);
axes = 0;
}
active = 1;
return 1;
}
int Update() {
if (!active) return 0;
if (numPhysicalControls) {
HRESULT res = did->Poll();
// ??
if ((res != DI_OK && res != DI_NOEFFECT) ||
DI_OK != did->GetDeviceState(4*numPhysicalControls, physicalControlState)) {
Deactivate();
return 0;
}
for (int i=0; i<numPhysicalControls; i++) {
if (physicalControls[i].type & RELAXIS) {
physicalControlState[i] *= (FULLY_DOWN/3);
}
else if (physicalControls[i].type & BUTTON) {
physicalControlState[i] = (physicalControlState[i]&0x80) * FULLY_DOWN / 128;
}
}
}
return 1;
}
void Deactivate() {
FreeState();
if (diEffects) {
for (int i=0; i<pads[0].numFFBindings + pads[1].numFFBindings; i++) {
if (diEffects[i].die) {
diEffects[i].die->Stop();
diEffects[i].die->Release();
diEffects[i].die = 0;
}
}
free(diEffects);
diEffects = 0;
}
if (active) {
did->Unacquire();
active = 0;
}
}
~DirectInputDevice() {
did->Release();
}
};
BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef) {
DirectInputDevice * did = (DirectInputDevice*) pvRef;
EffectType type;
int diType = DIEFT_GETTYPE(pdei->dwEffType);
if (diType == DIEFT_CONSTANTFORCE) {
type = EFFECT_CONSTANT;
}
else if (diType == DIEFT_RAMPFORCE) {
type = EFFECT_RAMP;
}
else if (diType == DIEFT_PERIODIC) {
type = EFFECT_PERIODIC;
}
else {
return DIENUM_CONTINUE;
}
wchar_t guidString[50];
GUIDtoString(guidString, &pdei->guid);
did->AddFFEffectType(pdei->tszName, guidString, type);
return DIENUM_CONTINUE;
}
BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) {
DirectInputDevice * did = (DirectInputDevice*) pvRef;
if (lpddoi->dwType & DIDFT_FFACTUATOR) {
did->AddFFAxis(lpddoi->tszName, lpddoi->dwType);
/*
void * t = realloc(DI->actuators, sizeof(DIActuator) * (DI->numActuators+1));
if (t) {
DI->actuators = (DIActuator*) t;
int i = DI->numActuators;
while (i > 0 && (lpddoi->dwType & 0xFFFF00) < (DI->actuators[i-1].id & 0xFFFF00)) {
DI->actuators[i] = DI->actuators[i-1];
i--;
}
DI->actuators[i].maxForce = lpddoi->dwFFMaxForce;
DI->actuators[i].id = lpddoi->dwType;
DI->numActuators++;
}
//*/
}
ControlType type;
if (lpddoi->dwType & DIDFT_POV)
type = POV;
else if (lpddoi->dwType & DIDFT_ABSAXIS)
type = ABSAXIS;
else if (lpddoi->dwType & DIDFT_RELAXIS)
type = RELAXIS;
else if (lpddoi->dwType & DIDFT_PSHBUTTON)
type = PSHBTN;
else if (lpddoi->dwType & DIDFT_TGLBUTTON)
type = TGLBTN;
else
return DIENUM_CONTINUE;
// If too many objects, ignore extra buttons.
if ((did->numPhysicalControls > 255 && DIDFT_GETINSTANCE(lpddoi->dwType) > 255) && (type & (DIDFT_PSHBUTTON | DIDFT_TGLBUTTON))) {
int i;
for (i = did->numPhysicalControls-1; i>did->numPhysicalControls-4; i--) {
if (!lpddoi->tszName[0]) break;
const wchar_t *s1 = lpddoi->tszName;
const wchar_t *s2 = did->physicalControls[i].name;
while (*s1 && *s1 == *s2) {
s1++;
s2++;
}
// If perfect match with one of last 4 names, break.
if (!*s1 && !*s2) break;
while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9')) s1--;
int check = 0;
while (*s1 >= '0' && *s1 <= '9') {
check = check*10 + *s1 - '0';
s1++;
}
while (*s2 >= '0' && *s2 <= '9') {
s2++;
}
// If perfect match other than final number > 30, then break.
// takes care of "button xx" case without causing issues with F keys.
if (!*s1 && !*s2 && check > 30) break;
}
if (i != did->numPhysicalControls-4) {
return DIENUM_CONTINUE;
}
}
int vkey = 0;
if (lpddoi->tszName[0] && did->type == KEYBOARD) {
for (u32 i = 0; i<256; i++) {
wchar_t *t = GetVKStringW((u8)i);
if (!wcsicmp(lpddoi->tszName, t)) {
vkey = i;
break;
}
}
}
did->AddPhysicalControl(type, DIDFT_GETINSTANCE(lpddoi->dwType), vkey, lpddoi->tszName);
return DIENUM_CONTINUE;
}
struct CreationInfo {
LPDIRECTINPUT8 lpDI8;
int count;
};
BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) {
CreationInfo *ci = (CreationInfo*) pvRef;
int *count = (int*) pvRef;
const wchar_t *name;
wchar_t temp[40];
if (lpddi->tszInstanceName[0]) {
name = lpddi->tszInstanceName;
}
else if (lpddi->tszProductName[0]) {
name = lpddi->tszProductName;
}
else {
wsprintfW (temp, L"Device %i", ci->count);
name = temp;
}
ci->count++;
wchar_t *fullName = (wchar_t *) malloc((wcslen(name) + 4) * sizeof(wchar_t));
wsprintf(fullName, L"DX %s", name);
wchar_t instanceID[100];
wchar_t productID[100];
GUIDtoString(instanceID, &lpddi->guidInstance);
GUIDtoString(productID, &lpddi->guidProduct);
DeviceType type = OTHER;
if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD) {
type = KEYBOARD;
}
else if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE) {
type = MOUSE;
}
IDirectInputDevice8 *did;
if (DI_OK == ci->lpDI8->CreateDevice(lpddi->guidInstance, &did, 0)) {
dm->AddDevice(new DirectInputDevice(type, did, fullName, instanceID, productID));
}
free(fullName);
return DIENUM_CONTINUE;
}
void EnumDirectInputDevices() {
CreationInfo ci = {0,0};
if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void**) &ci.lpDI8, 0))) return;
ci.lpDI8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &ci, DIEDFL_ATTACHEDONLY);
ci.lpDI8->Release();
}

View File

@ -0,0 +1,3 @@
#include "InputManager.h"
void EnumDirectInputDevices();

122
plugins/LilyPad/Global.h Normal file
View File

@ -0,0 +1,122 @@
#pragma once
#ifndef _DEBUG
#define NO_CRT
#endif
#ifdef NO_CRT
#define _CRT_ALLOCATION_DEFINED
#endif
#define UNICODE
#define PADdefs
//#define SIOdefs
#define WM_XBUTTONDOWN 0x020B
#define WM_XBUTTONUP 0x020C
#define WM_XBUTTONDBLCLK 0x020D
#define XBUTTON1 0x0001
#define XBUTTON2 0x0002
#define WM_MOUSEHWHEEL 0x020E
//#define WIN32_LEAN_AND_MEAN
//#define NOGDI
#define _CRT_SECURE_NO_DEPRECATE
// Actually works with 0x0400, but need this to get raw input structures.
#define WINVER 0x0501
#define _WIN32_WINNT WINVER
#define __MSCW32__
#include <stdio.h>
#include <stdlib.h>
#ifdef NDEBUG
#if (_MSC_VER<1300)
#pragma comment(linker,"/RELEASE")
#pragma comment(linker,"/opt:nowin98")
#endif
#endif
#define DIRECTINPUT_VERSION 0x0800
#include <windows.h>
#include <commctrl.h>
extern HINSTANCE hInst;
#include "resource.h"
#include "PS2Etypes.h"
/*
inline void Log(char *s) {
FILE *out2 = fopen("logs\\padLog.txt", "ab");
if (out2) {
fprintf(out2, "%s\n", s);
fclose(out2);
}
int w = GetCurrentThreadId();
char junk[1000];
sprintf(junk, "logs\\padLog%i.txt", w);
out2 = fopen(junk, "ab");
if (out2) {
fprintf(out2, "%s\n", s);
fclose(out2);
}
}
//*/
#ifdef NO_CRT
inline void * malloc(size_t size) {
return HeapAlloc(GetProcessHeap(), 0, size);
}
inline void * calloc(size_t num, size_t size) {
size *= num;
void *out = malloc(size);
if (out) memset(out, 0, size);
return out;
}
inline void free(__inout_opt void * mem) {
if (mem) HeapFree(GetProcessHeap(), 0, mem);
}
inline void * realloc(void *mem, size_t size) {
if (!mem) {
return malloc(size);
}
if (!size) {
free(mem);
return 0;
}
return HeapReAlloc(GetProcessHeap(), 0, mem, size);
}
inline wchar_t * __cdecl wcsdup(const wchar_t *in) {
size_t size = sizeof(wchar_t) * (1+wcslen(in));
wchar_t *out = (wchar_t*) malloc(size);
if (out)
memcpy(out, in, size);
return out;
}
__forceinline void * __cdecl operator new(size_t lSize) {
return HeapAlloc(GetProcessHeap(), 0, lSize);
}
__forceinline void __cdecl operator delete(void *pBlock) {
HeapFree(GetProcessHeap(), 0, pBlock);
}
#endif
__forceinline int __cdecl wcsicmp(const wchar_t *s1, const wchar_t *s2) {
int res = CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, s1, -1, s2, -1);
if (res) return res-2;
return res;
}

View File

@ -0,0 +1,586 @@
#include "InputManager.h"
#include "Global.h"
#include "KeyboardQueue.h"
#include <math.h>
InputDeviceManager *dm = 0;
InputDeviceManager::InputDeviceManager() {
memset(this, 0, sizeof(*this));
}
void InputDeviceManager::ClearDevices() {
for (int i=0; i<numDevices; i++) {
delete devices[i];
}
free(devices);
devices = 0;
numDevices = 0;
}
InputDeviceManager::~InputDeviceManager() {
ClearDevices();
}
Device::Device(DeviceAPI api, DeviceType d, const wchar_t *displayName, const wchar_t *instanceID, wchar_t *productID) {
memset(pads, 0, sizeof(pads));
this->api = api;
type = d;
this->displayName = wcsdup(displayName);
if (instanceID)
this->instanceID = wcsdup(instanceID);
else
this->instanceID = wcsdup(displayName);
this->productID = 0;
if (productID)
this->productID = wcsdup(productID);
active = 0;
attached = 1;
enabled = 0;
virtualControls = 0;
numVirtualControls = 0;
virtualControlState = 0;
oldVirtualControlState = 0;
physicalControls = 0;
numPhysicalControls = 0;
physicalControlState = 0;
ffEffectTypes = 0;
numFFEffectTypes = 0;
ffAxes = 0;
numFFAxes = 0;
}
void Device::FreeState() {
if (virtualControlState) free(virtualControlState);
virtualControlState = 0;
if (oldVirtualControlState) free(oldVirtualControlState);
oldVirtualControlState = 0;
if (physicalControlState) free(physicalControlState);
physicalControlState = 0;
}
Device::~Device() {
Deactivate();
// Generally called by deactivate, but just in case...
FreeState();
int i;
for (int pad=0; pad<2; pad++) {
free(pads[pad].bindings);
for (i=0; i<pads[pad].numFFBindings; i++) {
free(pads[pad].ffBindings[i].axes);
}
free(pads[pad].ffBindings);
}
free(virtualControls);
for (i=numPhysicalControls-1; i>=0; i--) {
if (physicalControls[i].name) free(physicalControls[i].name);
}
free(physicalControls);
free(displayName);
free(instanceID);
free(productID);
if (ffAxes) {
for (i=0; i<numFFAxes; i++) {
free(ffAxes[i].displayName);
}
free(ffAxes);
}
if (ffEffectTypes) {
for (i=0; i<numFFEffectTypes; i++) {
free(ffEffectTypes[i].displayName);
free(ffEffectTypes[i].effectID);
}
free(ffEffectTypes);
}
}
void Device::AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type) {
ffEffectTypes = (ForceFeedbackEffectType*) realloc(ffEffectTypes, sizeof(ForceFeedbackEffectType) * (numFFEffectTypes+1));
ffEffectTypes[numFFEffectTypes].displayName = wcsdup(displayName);
ffEffectTypes[numFFEffectTypes].effectID = wcsdup(effectID);
ffEffectTypes[numFFEffectTypes].type = type;
numFFEffectTypes++;
}
void Device::AddFFAxis(const wchar_t *displayName, int id) {
ffAxes = (ForceFeedbackAxis*) realloc(ffAxes, sizeof(ForceFeedbackAxis) * (numFFAxes+1));
ffAxes[numFFAxes].id = id;
ffAxes[numFFAxes].displayName = wcsdup(displayName);
numFFAxes++;
for (int pad=0; pad<2; pad++) {
for (int i=0; i<pads[pad].numFFBindings; i++) {
ForceFeedbackBinding *b = pads[pad].ffBindings+i;
b->axes = (AxisEffectInfo*) realloc(b->axes, sizeof(AxisEffectInfo) * (numFFAxes));
memset(b->axes + (numFFAxes-1), 0, sizeof(AxisEffectInfo));
}
}
}
void Device::AllocState() {
FreeState();
virtualControlState = (int*) calloc(numVirtualControls, sizeof(int));
oldVirtualControlState = (int*) calloc(numVirtualControls, sizeof(int));
physicalControlState = (int*) calloc(numPhysicalControls, sizeof(int));
}
void Device::FlipState() {
memcpy(oldVirtualControlState, virtualControlState, sizeof(int)*numVirtualControls);
}
void Device::PostRead() {
FlipState();
}
void Device::CalcVirtualState() {
for (int i=0; i<numPhysicalControls; i++) {
PhysicalControl *c = physicalControls+i;
int index = c->baseVirtualControlIndex;
int val = physicalControlState[i];
if (c->type & BUTTON) {
virtualControlState[index] = val;
if (!(virtualControlState[index]>>15) != !(oldVirtualControlState[index]>>15) && c->vkey) {
// Check for alt-F4 to avoid toggling skip mode incorrectly.
if (c->vkey == VK_F4) {
for (int i=0; i<numPhysicalControls; i++) {
if (virtualControlState[physicalControls[i].baseVirtualControlIndex] &&
(physicalControls[i].vkey == VK_MENU ||
physicalControls[i].vkey == VK_RMENU ||
physicalControls[i].vkey == VK_LMENU)) {
return;
}
}
}
int event = KEYPRESS;
if (!(virtualControlState[index]>>15)) event = KEYRELEASE;
QueueKeyEvent(c->vkey, event);
}
}
else if (c->type & ABSAXIS) {
virtualControlState[index] = val;
// Positive. Overkill.
virtualControlState[index+1] = (val & ~(val>>31));
// Negative
virtualControlState[index+2] = (-val & (val>>31));
}
else if (c->type & RELAXIS) {
int delta = val - oldVirtualControlState[index];
virtualControlState[index] = val;
// Positive
virtualControlState[index+1] = (delta & ~(delta>>31));
// Negative
virtualControlState[index+2] = (-delta & (delta>>31));
}
else if (c->type & POV) {
virtualControlState[index] = val;
int iSouth = 0;
int iEast = 0;
if ((unsigned int)val <= 37000) {
double angle = val * (3.141592653589793/18000.0);
double East = sin(angle);
double South = -cos(angle);
double fabsSouth = fabs(South);
double fabsEast = fabs(East);
// Normalize so greatest direction is 1.
double mul;
if (fabsSouth > fabsEast) {
mul = FULLY_DOWN / fabsSouth;
}
else {
mul = FULLY_DOWN / fabsEast;
}
iEast = (int) floor(East * mul + 0.5);
iSouth = (int) floor(South * mul + 0.5);
}
// N
virtualControlState[index+1] = (-iSouth & (iSouth>>31));
// S
virtualControlState[index+3] = (iSouth & ~(iSouth>>31));
// E
virtualControlState[index+2] = (iEast & ~(iEast>>31));
// W
virtualControlState[index+4] = (-iEast & (iEast>>31));
}
}
}
VirtualControl *Device::GetVirtualControl(unsigned int uid) {
for (int i=0; i<numVirtualControls; i++) {
if (virtualControls[i].uid == uid)
return virtualControls + i;
}
return 0;
}
VirtualControl *Device::AddVirtualControl(unsigned int uid, int physicalControlIndex) {
if (numVirtualControls % 16 == 0) {
virtualControls = (VirtualControl*) realloc(virtualControls, sizeof(VirtualControl)*(numVirtualControls+16));
}
VirtualControl *c = virtualControls + numVirtualControls;
c->uid = uid;
c->physicalControlIndex = physicalControlIndex;
numVirtualControls++;
return c;
}
PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name) {
FreeState();
if (numPhysicalControls % 16 == 0) {
physicalControls = (PhysicalControl*) realloc(physicalControls, sizeof(PhysicalControl)*(numPhysicalControls+16));
}
PhysicalControl *control = physicalControls + numPhysicalControls;
memset(control, 0, sizeof(PhysicalControl));
control->type = type;
control->id = id;
if (name) control->name = wcsdup(name);
control->baseVirtualControlIndex = numVirtualControls;
unsigned int uid = id | (type<<16);
if (type & BUTTON) {
AddVirtualControl(uid, numPhysicalControls);
control->vkey = vkey;
}
else if (type & AXIS) {
AddVirtualControl(uid | UID_AXIS, numPhysicalControls);
AddVirtualControl(uid | UID_AXIS_POS, numPhysicalControls);
AddVirtualControl(uid | UID_AXIS_NEG, numPhysicalControls);
}
else if (type & POV) {
AddVirtualControl(uid | UID_POV, numPhysicalControls);
AddVirtualControl(uid | UID_POV_N, numPhysicalControls);
AddVirtualControl(uid | UID_POV_E, numPhysicalControls);
AddVirtualControl(uid | UID_POV_S, numPhysicalControls);
AddVirtualControl(uid | UID_POV_W, numPhysicalControls);
}
numPhysicalControls++;
return control;
}
void Device::SetEffects(unsigned char pad, unsigned char motor, unsigned char force) {
for (int i=0; i<pads[pad].numFFBindings; i++) {
ForceFeedbackBinding *binding = pads[pad].ffBindings+i;
if (binding->motor == motor) {
SetEffect(binding, force);
}
}
}
wchar_t *GetDefaultControlName(unsigned short id, int type) {
static wchar_t name[20];
if (type & BUTTON) {
wsprintfW(name, L"Button %i", id);
}
else if (type & AXIS) {
wsprintfW(name, L"Axis %i", id);
}
else if (type & POV) {
wsprintfW(name, L"POV %i", id);
}
else return L"Unknown";
return name;
}
wchar_t *Device::GetVirtualControlName(VirtualControl *control) {
static wchar_t temp[100];
wchar_t *baseName = 0;
if (control->physicalControlIndex >= 0) {
baseName = physicalControls[control->physicalControlIndex].name;
if (!baseName) baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]);
}
unsigned int uid = control->uid;
if (!baseName) {
baseName = GetDefaultControlName(uid & 0xFFFF, (uid >> 16)& 0x1F);
}
uid &= 0xFF000000;
int len = (int)wcslen(baseName);
if (len > 99) len = 99;
if (uid && len > 89) len = 89;
memcpy(temp, baseName, len*sizeof(wchar_t));
temp[len] = 0;
if (uid) {
wchar_t *out = temp+len;
if (uid == UID_AXIS_POS) {
wcscpy(out, L" +");
}
else if (uid == UID_AXIS_NEG) {
wcscpy(out, L" -");
}
else if (uid == UID_POV_N) {
wcscpy(out, L" N");
}
else if (uid == UID_POV_E) {
wcscpy(out, L" E");
}
else if (uid == UID_POV_S) {
wcscpy(out, L" S");
}
else if (uid == UID_POV_W) {
wcscpy(out, L" W");
}
}
return temp;
}
wchar_t *Device::GetPhysicalControlName(PhysicalControl *control) {
if (control->name) return control->name;
return GetDefaultControlName(control->id, control->type);
}
/*wchar_t *Device::GetControlNameByIndex(int index) {
static wchar_t name[20];
if (type & BUTTON) {
wsprintfW(name, "Button %i", controls);
}
else if (type & AXIS) {
wsprintfW(name, "Button %i", index);
}
else return L"Unknown";
return name;
}//*/
void InputDeviceManager::AddDevice(Device *d) {
devices = (Device**) realloc(devices, sizeof(Device*) * (numDevices+1));
devices[numDevices++] = d;
}
void InputDeviceManager::Update(void *info) {
for (int i=0; i<numDevices; i++) {
if (devices[i]->enabled) {
if (!devices[i]->active) {
if (!devices[i]->Activate(info) || !devices[i]->Update()) continue;
devices[i]->CalcVirtualState();
devices[i]->PostRead();
}
if (devices[i]->Update())
devices[i]->CalcVirtualState();
}
}
}
void InputDeviceManager::PostRead() {
for (int i=0; i<numDevices; i++) {
if (devices[i]->active)
devices[i]->PostRead();
}
}
Device *InputDeviceManager::GetActiveDevice(void *info, int axisHint, unsigned int *uid, int *index, int *value) {
int i, j;
Update(info);
int bestDiff = FULLY_DOWN/2;
Device *bestDevice = 0;
for (i=0; i<numDevices; i++) {
if (devices[i]->active) {
for (j=0; j<devices[i]->numVirtualControls; j++) {
if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j]) continue;
// Fix for two things:
// Releasing button used to click on bind button, and
// DirectInput not updating control state.
//Note: Handling latter not great for pressure sensitive button handling, but should still work...
// with some effort.
if (!((devices[i]->virtualControls[j].uid >> 16) & (POV|RELAXIS))) {
if (abs(devices[i]->oldVirtualControlState[j]) > abs(devices[i]->virtualControlState[j])) {
devices[i]->oldVirtualControlState[j] = 0;
}
}
int diff = abs(devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]);
if ((devices[i]->virtualControls[j].uid & UID_POV) && diff) {
if (devices[i]->virtualControlState[j] == -1) diff = 0;
else diff = 2*FULLY_DOWN;
}
// Make it require a bit more work to bind relative axes.
else if (((devices[i]->virtualControls[j].uid>>16) & 0xFF) == RELAXIS) {
diff = diff/4+1;
}
if (diff > bestDiff) {
if (axisHint != 2) {
if (devices[i]->virtualControls[j].uid & UID_POV) continue;
if (devices[i]->virtualControls[j].uid & UID_AXIS) {
if (!axisHint || (((devices[i]->virtualControls[j].uid>>16)&0xFF) != ABSAXIS)) continue;
}
}
bestDiff = diff;
*uid = devices[i]->virtualControls[j].uid;
*index = j;
bestDevice = devices[i];
if (value) {
if ((devices[i]->virtualControls[j].uid>>16)& RELAXIS) {
*value = devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j];
}
else {
*value = devices[i]->virtualControlState[j];
}
}
}
}
}
}
// Don't call when binding.
// PostRead();
return bestDevice;
}
void InputDeviceManager::ReleaseInput() {
for (int i=0; i<numDevices; i++) {
if (devices[i]->active) devices[i]->Deactivate();
}
}
void InputDeviceManager::EnableDevices(DeviceType type, DeviceAPI api) {
for (int i=0; i<numDevices; i++) {
if (devices[i]->api == api && devices[i]->type == type) {
EnableDevice(i);
}
}
}
void InputDeviceManager::DisableAllDevices() {
for (int i=0; i<numDevices; i++) {
DisableDevice(i);
}
}
void InputDeviceManager::DisableDevice(int index) {
devices[index]->enabled = 0;
// Should never happen, but just in case...
if (devices[index]->active) devices[index]->Deactivate();
}
ForceFeedbackEffectType *Device::GetForcefeedbackEffect(wchar_t *id) {
for (int i=0; i<numFFEffectTypes; i++) {
if (!wcsicmp(id, ffEffectTypes[i].effectID)) {
return &ffEffectTypes[i];
}
}
return 0;
}
ForceFeedbackAxis *Device::GetForceFeedbackAxis(int id) {
for (int i=0; i<numFFAxes; i++) {
if (ffAxes[i].id == id) return &ffAxes[i];
}
return 0;
}
void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices) {
int *oldMatches = (int*) malloc(sizeof(int) * numOldDevices);
int *matches = (int*) malloc(sizeof(int) * numDevices);
int i, j, pad;
Device *old, *dev;
for (i=0; i<numDevices; i++) {
matches[i] = -1;
}
for (i=0; i<numOldDevices; i++) {
oldMatches[i] = -2;
old = oldDevices[i];
for (pad=0; pad<2; pad++) {
if (old->pads[pad].numBindings + old->pads[pad].numFFBindings) {
// Means that there are bindings.
oldMatches[i] = -1;
}
}
}
// Loops through ids looking for match, from most specific to most general.
for (int id=0; id<3; id++) {
for (i=0; i<numOldDevices; i++) {
if (oldMatches[i] >= 0) continue;
for (j=0; j<numDevices; j++) {
if (matches[j] >= 0) {
continue;
}
wchar_t *id1 = devices[j]->IDs[id];
wchar_t *id2 = oldDevices[i]->IDs[id];
if (!id1 || !id2) {
continue;
}
if (!wcsicmp(devices[j]->instanceID, oldDevices[i]->instanceID)) {
matches[j] = i;
oldMatches[i] = j;
break;
}
}
}
}
for (i=0; i<numOldDevices; i++) {
if (oldMatches[i] == -2) continue;
old = oldDevices[i];
if (oldMatches[i] < 0) {
dev = new Device(old->api, old->type, old->displayName, old->instanceID, old->productID);
dev->attached = 0;
AddDevice(dev);
for (j=0; j<old->numVirtualControls; j++) {
VirtualControl *c = old->virtualControls+j;
dev->AddVirtualControl(c->uid, -1);
}
for (j=0; j<old->numFFEffectTypes; j++) {
ForceFeedbackEffectType * effect = old->ffEffectTypes + j;
dev->AddFFEffectType(effect->displayName, effect->effectID, effect->type);
}
for (j=0; j<old->numFFAxes; j++) {
ForceFeedbackAxis * axis = old->ffAxes + j;
dev->AddFFAxis(axis->displayName, axis->id);
}
// Just steal the old bindings directly when there's no matching device.
// Indices will be the same.
memcpy(dev->pads, old->pads, sizeof(old->pads));
memset(old->pads, 0, sizeof(old->pads));
}
else {
dev = devices[oldMatches[i]];
for (pad=0; pad<2; pad++) {
if (old->pads[pad].numBindings) {
dev->pads[pad].bindings = (Binding*) malloc(old->pads[pad].numBindings * sizeof(Binding));
for (int j=0; j<old->pads[pad].numBindings; j++) {
Binding *bo = old->pads[pad].bindings + j;
Binding *bn = dev->pads[pad].bindings + dev->pads[pad].numBindings;
VirtualControl *cn = dev->GetVirtualControl(old->virtualControls[bo->controlIndex].uid);
if (cn) {
*bn = *bo;
bn->controlIndex = cn - dev->virtualControls;
dev->pads[pad].numBindings++;
}
}
}
if (old->pads[pad].numFFBindings) {
dev->pads[pad].ffBindings = (ForceFeedbackBinding*) malloc(old->pads[pad].numFFBindings * sizeof(ForceFeedbackBinding));
for (int j=0; j<old->pads[pad].numFFBindings; j++) {
ForceFeedbackBinding *bo = old->pads[pad].ffBindings + j;
ForceFeedbackBinding *bn = dev->pads[pad].ffBindings + dev->pads[pad].numFFBindings;
ForceFeedbackEffectType *en = dev->GetForcefeedbackEffect(old->ffEffectTypes[bo->effectIndex].effectID);
if (en) {
*bn = *bo;
bn->effectIndex = en - dev->ffEffectTypes;
bn->axes = (AxisEffectInfo*)calloc(dev->numFFAxes, sizeof(AxisEffectInfo));
for (int k=0; k<old->numFFAxes; k++) {
ForceFeedbackAxis *newAxis = dev->GetForceFeedbackAxis(old->ffAxes[k].id);
if (newAxis) {
bn->axes[newAxis - dev->ffAxes] = bo->axes[k];
}
}
dev->pads[pad].numFFBindings++;
}
}
}
}
}
}
free(oldMatches);
free(matches);
}
void InputDeviceManager::SetEffect(unsigned char pad, unsigned char motor, unsigned char force) {
for (int i=0; i<numDevices; i++) {
Device *dev = devices[i];
if (dev->enabled && dev->numFFEffectTypes) {
dev->SetEffects(pad, motor, force);
}
}
}

View File

@ -0,0 +1,324 @@
#ifndef INPUT_MANAGER_H
#define INPUT_MANAGER_H
// Both of these are hard coded in a lot of places, so don't modify them.
// Base sensitivity means that a sensitivity of that corresponds to a factor of 1.
// Fully down means that value corresponds to a button being fully down (255).
// a value of 128 or more corresponds to that button being pressed, for binary
// values.
#define BASE_SENSITIVITY (1<<16)
#define FULLY_DOWN (1<<16)
/* Idea is for this file and the associated cpp file to be Windows independent.
* Still more effort than it's worth to port to Linux, however.
*/
// Match DirectInput8 values.
enum ControlType {
NO_CONTROL = 0,
// Axes are ints. Relative axes are for mice, mice wheels, etc,
// and are always reported relative to their last value.
// Absolute axes range from -65536 to 65536 and are absolute positions,
// like for joysticks and pressure sensitive buttons.
RELAXIS = 1,
ABSAXIS = 2,
// Buttons range from 0 to 65536.
PSHBTN = 4,
TGLBTN = 8,
// POV controls are ints, values range from -1 to 36000.
// -1 means not pressed, otherwise it's an angle.
// For easy DirectInput compatibility, anything outside.
// that range is treated as -1 (Though 36000-37000 is treated
// like 0 to 1000, just in case).
POV = 16,
};
// Masks to determine button type. Don't need one for POV.
#define BUTTON 12
#define AXIS 3
struct Binding {
int controlIndex;
int command;
int sensitivity;
unsigned char turbo;
};
#define UID_AXIS (1<<31)
#define UID_POV (1<<30)
#define UID_AXIS_POS (1<<24)
#define UID_AXIS_NEG (2<<24)
#define UID_POV_N (3<<24)
#define UID_POV_E (4<<24)
#define UID_POV_S (5<<24)
#define UID_POV_W (6<<24)
// One of these exists for each bindable object.
// Bindable objects consist of buttons, axis, pov controls,
// and individual axis/pov directions. Not that pov controls
// cannot actually be bound, but when trying to bind as an axis,
// all directions are assigned individually.
struct VirtualControl {
// Unique id for control, given device. Based on source control's id,
// source control type, axis/pov flags if it's a pov/axis (Rather than
// a button or a pov/axis control's individual button), and an index,
// if the control is split.
unsigned int uid;
// virtual key code. 0 if none.
int physicalControlIndex;
};
// Need one for each button, axis, and pov control.
// API-specific code creates the PhysicalControls and
// updates their state, standard function then populates
// the VirtualControls and queues the keyboard messages, if
// needed.
struct PhysicalControl {
// index of the first virtual control corresponding to this.
// Buttons have 1 virtual control, axes 3, and povs 5, all
// in a row.
int baseVirtualControlIndex;
ControlType type;
// id. Must be unique for control type.
// short so can be combined with other values to get
// uid for virtual controls.
unsigned short id;
unsigned short vkey;
wchar_t *name;
};
enum DeviceAPI {
NO_API = 0,
DI = 1,
WM = 2,
RAW = 3,
XINPUT = 4,
// Not currently used.
LLHOOK = 5,
// Not a real API, obviously. Only used with keyboards,
// to ignore individual buttons. Wrapper itself takes care
// of ignoring bound keys. Otherwise, works normally.
IGNORE_KEYBOARD = 6,
};
enum DeviceType {
NO_DEVICE = 0,
KEYBOARD = 1,
MOUSE = 2,
OTHER = 3
};
enum EffectType {
EFFECT_CONSTANT,
EFFECT_PERIODIC,
EFFECT_RAMP
};
// force range sfrom -BASE_SENSITIVITY to BASE_SENSITIVITY.
// Order matches ForceFeedbackAxis order. force of 0 means to
// ignore that axis completely. Force of 1 or -1 means to initialize
// the axis with minimum force (Possibly 0 force), if applicable.
struct AxisEffectInfo {
int force;
};
struct ForceFeedbackBinding {
AxisEffectInfo *axes;
int effectIndex;
unsigned char motor;
};
// Bindings listed by effect, so I don't have to bother with
// indexing effects.
struct ForceFeedbackEffectType {
wchar_t *displayName;
// Because I'm lazy, can only have ASCII characters and no spaces.
wchar_t *effectID;
// constant, ramp, or periodic
EffectType type;
};
struct ForceFeedbackAxis {
wchar_t *displayName;
int id;
};
// Note: Unbound controls don't need to be listed, though they can be.
// Nonexistent controls can be listed as well (Like listing 5 buttons
// even for three button mice, as some APIs make it impossible to figure
// out which buttons you really have).
// Used both for active devices and for sets of settings for devices.
// Way things work:
// LoadSettings() will delete all device info, then load settings to get
// one set of generic devices. Then I enumerate all devices. Then I merge
// them, moving settings from the generic devices to the enumerated ones.
// Can't refresh without loading settings.
struct PadBindings {
Binding *bindings;
int numBindings;
ForceFeedbackBinding *ffBindings;
int numFFBindings;
};
// Mostly self-contained, but bindings are modified by config.cpp, to make
// updating the ListView simpler.
class Device {
public:
DeviceAPI api;
DeviceType type;
char active;
char attached;
// Based on input modes.
char enabled;
union {
// Allows for one loop to compare all 3 in order.
wchar_t *IDs[3];
struct {
// Same as DisplayName, when not given. Absolutely must be unique.
// Used for loading/saving controls. If matches, all other strings
// are ignored, so must be unique.
wchar_t *instanceID;
// Not required. Used when a device's instance id changes, doesn't have to
// be unique. For devices that can only have one instance, not needed.
wchar_t *productID;
wchar_t *displayName;
};
};
PadBindings pads[2];
// Virtual controls. All basically act like pressure sensitivity buttons, with
// values between 0 and 2^16. 2^16 is fully down, 0 is up. Larger values
// are allowed, but *only* for absolute axes (Which don't support the flip checkbox).
// Each control on a device must have a unique id, used for binding.
VirtualControl *virtualControls;
int numVirtualControls;
int *virtualControlState;
int *oldVirtualControlState;
PhysicalControl *physicalControls;
int numPhysicalControls;
int *physicalControlState;
ForceFeedbackEffectType *ffEffectTypes;
int numFFEffectTypes;
ForceFeedbackAxis *ffAxes;
int numFFAxes;
void AddFFAxis(const wchar_t *displayName, int id);
void AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type);
Device(DeviceAPI, DeviceType, const wchar_t *displayName, const wchar_t *instanceID = 0, wchar_t *deviceID = 0);
virtual ~Device();
// Allocates memory for old and new state, sets everything to 0.
// all old states are in one array, buttons, axes, and then POVs.
// start of each section is int aligned. This makes it DirectInput
// compatible.
void AllocState();
// Doesn't actually flip. Copies current state to old state.
void FlipState();
// Frees state variables.
void FreeState();
ForceFeedbackEffectType *GetForcefeedbackEffect(wchar_t *id);
ForceFeedbackAxis *GetForceFeedbackAxis(int id);
VirtualControl *GetVirtualControl(unsigned int uid);
PhysicalControl *AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name = 0);
VirtualControl *AddVirtualControl(unsigned int uid, int physicalControlIndex);
virtual wchar_t *GetVirtualControlName(VirtualControl *c);
virtual wchar_t *GetPhysicalControlName(PhysicalControl *c);
void CalcVirtualState();
// args are OS dependent.
inline virtual int Activate(void *args) {
return 0;
}
inline virtual void Deactivate() {
FreeState();
active = 0;
}
// Default update proc. All that's needed for post-based APIs.
inline virtual int Update() {
return active;
}
// force is from -FULLY_DOWN to FULLY_DOWN.
// Either function can be overridden. Second one by default calls the first
// for every bound effect that's affected.
// Note: Only used externally for binding, so if override the other one, can assume
// all other forces are currently 0.
inline virtual void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {}
inline virtual void SetEffects(unsigned char pad, unsigned char motor, unsigned char force);
// Called after reading. Basically calls FlipState().
// Some device types (Those that don't incrementally update)
// could call FlipState elsewhere, but this makes it simpler to ignore
// while binding.
virtual void PostRead();
};
// Don't need objects for devices with no bound controls.
class InputDeviceManager {
public:
Device **devices;
int numDevices;
void ClearDevices();
// When refreshing devices, back up old devices, then
// populate this with new devices, then call copy bindings.
// All old bindings are copied to matching devices.
// When old devices are missing, I do a slightly more careful search
// using id2s and create new dummy devices if no matches.
void CopyBindings(int numDevices, Device **devices);
InputDeviceManager();
~InputDeviceManager();
void AddDevice(Device *d);
// If axisHint is 1, prefer axes.
Device *GetActiveDevice(void *info, int axisHint, unsigned int *uid, int *index, int *value);
void Update(void *attachInfo);
// Called after reading state, after Update().
void PostRead();
void SetEffect(unsigned char pad, unsigned char motor, unsigned char force);
// Update does this as needed.
// void GetInput(void *v);
void ReleaseInput();
void DisableDevice(int index);
inline void EnableDevice(int i) {
devices[i]->enabled = 1;
}
void EnableDevices(DeviceType type, DeviceAPI api);
void DisableAllDevices();
};
extern InputDeviceManager *dm;
#endif

View File

@ -0,0 +1,114 @@
#include "Global.h"
#include "KeyboardHook.h"
#include "InputManager.h"
#include "WindowsKeyboard.h"
#include "Config.h"
#include "VKey.h"
#include "WndProcEater.h"
#include "DeviceEnumerator.h"
extern HINSTANCE hInst;
LRESULT CALLBACK IgnoreKeyboardHook(int code, WPARAM wParam, LPARAM lParam);
ExtraWndProcResult StartHooksWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
class IgnoreKeyboardHookDevice;
static IgnoreKeyboardHookDevice *ikhd = 0;
class IgnoreKeyboardHookDevice : public WindowsKeyboard {
public:
HHOOK hHook;
// When binding, eat all keys
int binding;
IgnoreKeyboardHookDevice() : WindowsKeyboard(IGNORE_KEYBOARD, L"Ignore Keyboard") {
// Don't want to send keypress/keyrelease messages.
for (int i=0; i<numPhysicalControls; i++) {
physicalControls[i].vkey = 0;
}
hHook = 0;
}
int Update() {
//if (!GetKeyboardState(buttonState)) return 0;
for (int i=0; i<=4; i++) virtualControlState[i] = 0;
// So I'll bind to left/right control/shift instead of generic ones.
virtualControlState[VK_SHIFT] = 0;
virtualControlState[VK_CONTROL] = 0;
virtualControlState[VK_MENU] = 0;
return 1;
}
int Activate(void *d) {
if (ikhd) ikhd->Deactivate();
InitInfo *info = (InitInfo*) d;
binding = info->bindingIgnore;
if (info->hWndButton)
EatWndProc(info->hWndButton, StartHooksWndProc);
else
EatWndProc(info->hWnd, StartHooksWndProc);
InitState();
ikhd = this;
active = 1;
return 1;
}
void Deactivate() {
FreeState();
if (active) {
if (hHook) {
UnhookWindowsHookEx(hHook);
hHook = 0;
}
if (ikhd == this) ikhd = 0;
active = 0;
}
}
};
void EnumHookDevices() {
dm->AddDevice(new IgnoreKeyboardHookDevice());
}
// Makes sure hooks are started in correct thread.
ExtraWndProcResult StartHooksWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (ikhd && !ikhd->hHook && ikhd->active) {
ikhd->hHook = SetWindowsHookEx(WH_KEYBOARD_LL, IgnoreKeyboardHook, hInst, 0);
if (ikhd->hHook == 0) ikhd->Deactivate();
}
return CONTINUE_BLISSFULLY_AND_RELEASE_PROC;
}
LRESULT CALLBACK IgnoreKeyboardHook(int code, WPARAM wParam, LPARAM lParam) {
HHOOK hHook = 0;
if (ikhd) {
hHook = ikhd->hHook;
if (hHook) {
if (code == HC_ACTION) {
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*) lParam;
if (key->vkCode < 256) {
for (int i=0; i<ikhd->pads[0].numBindings; i++) {
if (ikhd->pads[0].bindings[i].controlIndex == key->vkCode) {
return 1;
}
}
if (ikhd->binding){
ikhd->UpdateKey(key->vkCode, 1);
return 1;
}
}
}
else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*) lParam;
if (ikhd->binding && key->vkCode < 256)
ikhd->UpdateKey(key->vkCode, 0);
}
}
return CallNextHookEx(hHook, code, wParam, lParam);
}
}
return CallNextHookEx(hHook, code, wParam, lParam);
}

View File

@ -0,0 +1,7 @@
#ifndef KEYBOARD_HOOK_H
#define KEYBOARD_HOOK_H
void EnumHookDevices();
#endif

View File

@ -0,0 +1,66 @@
// This is undoubtedly completely unnecessary.
#include "KeyboardQueue.h"
static int numQueuedEvents = 0;
static keyEvent queuedEvents[20];
// What MS calls a single process Mutex. Faster, supposedly.
// More importantly, can be abbreviated, amusingly, as cSection.
static CRITICAL_SECTION cSection;
static int csInitialized = 0;
void QueueKeyEvent(int key, int event) {
if (!csInitialized) {
csInitialized = 1;
InitializeCriticalSection(&cSection);
}
EnterCriticalSection(&cSection);
if (numQueuedEvents >= 15) {
// Generally shouldn't happen.
for (int i=0; i<15; i++) {
queuedEvents[i] = queuedEvents[i+5];
}
numQueuedEvents = 15;
}
int index = numQueuedEvents;
// Move escape to top of queue. May do something
// with shift/ctrl/alt and F-keys, later.
if (event == KEYPRESS && key == VK_ESCAPE) {
while (index) {
queuedEvents[index-1] = queuedEvents[index];
index--;
}
}
queuedEvents[index].key = key;
queuedEvents[index].event = event;
numQueuedEvents ++;
LeaveCriticalSection(&cSection);
}
int GetQueuedKeyEvent(keyEvent *event) {
int out = 0;
if (numQueuedEvents) {
EnterCriticalSection(&cSection);
// Shouldn't be 0, but just in case...
if (numQueuedEvents) {
*event = queuedEvents[0];
numQueuedEvents--;
out = 1;
for (int i=0; i<numQueuedEvents; i++) {
queuedEvents[i] = queuedEvents[i+1];
}
}
LeaveCriticalSection(&cSection);
}
return out;
}
void ClearKeyQueue() {
if (numQueuedEvents) {
numQueuedEvents = 0;
}
if (csInitialized) {
DeleteCriticalSection(&cSection);
csInitialized = 0;
}
}

View File

@ -0,0 +1,11 @@
#include "Global.h"
#include "PS2Edefs.h"
// This entire thing isn't really needed,
// but takes little enough effort to be safe...
void QueueKeyEvent(int key, int event);
int GetQueuedKeyEvent(keyEvent *event);
// Cleans up as well as clears queue.
void ClearKeyQueue();

1136
plugins/LilyPad/LilyPad.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
EXPORTS
PS2EgetLibType
PS2EgetLibName
PS2EgetLibVersion2
PSEgetLibType
PSEgetLibName
PSEgetLibVersion
PADreadPort1
PADreadPort2
PADinit
PADshutdown
PADopen
PADclose
PADkeyEvent
PADstartPoll
PADpoll
PADquery
PADconfigure
PADtest
PADabout
PADupdate

371
plugins/LilyPad/LilyPad.rc Normal file
View File

@ -0,0 +1,371 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <winres.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include <winres.h>\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONFIG DIALOGEX 0, 0, 424, 318
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,183,285,WS_EX_CLIENTEDGE
PUSHBUTTON "Delete Selected",ID_DELETE,7,296,59,15
PUSHBUTTON "Clear All",ID_CLEAR,71,296,56,15
PUSHBUTTON "Ignore Key",ID_IGNORE,132,296,58,15
PUSHBUTTON "Square",ID_SQUARE,196,7,45,15
PUSHBUTTON "Cross",ID_CROSS,196,26,45,15
PUSHBUTTON "Triangle",ID_TRIANGLE,246,7,45,15
PUSHBUTTON "Circle",ID_CIRCLE,246,26,45,15
PUSHBUTTON "Select",ID_SELECT,306,7,45,15
PUSHBUTTON "Start",ID_START,306,26,45,15
PUSHBUTTON "Analog",ID_ANALOG,372,7,45,15
PUSHBUTTON "Mouse",ID_MOUSE,372,26,45,15
PUSHBUTTON "L1",ID_L1,196,52,45,15
PUSHBUTTON "R1",ID_R1,372,52,45,15
PUSHBUTTON "L2",ID_L2,196,73,45,15
PUSHBUTTON "R2",ID_R2,372,73,45,15
PUSHBUTTON "L3",ID_L3,195,93,45,15
PUSHBUTTON "R3",ID_R3,371,93,46,15
GROUPBOX "D-Pad",ID_DPAD,251,44,110,68
PUSHBUTTON "Up",ID_DPAD_UP,275,54,35,15
PUSHBUTTON "Left",ID_DPAD_LEFT,257,73,35,15
PUSHBUTTON "Right",ID_DPAD_RIGHT,297,73,35,15
PUSHBUTTON "Down",ID_DPAD_DOWN,275,92,35,15
PUSHBUTTON "Vert Axis",ID_DPAD_UDAXIS,314,54,40,15
PUSHBUTTON "Horiz Axis",ID_DPAD_LRAXIS,314,92,40,15
PUSHBUTTON "L1/R1 Axis",ID_L1R1,231,117,45,15
PUSHBUTTON "L2/R2 Axis",ID_L2R2,281,117,45,15
PUSHBUTTON "L3/R3 Axis",ID_L3R3,331,117,45,15
GROUPBOX "Left Analog Stick",ID_LSTICK,195,135,108,70
PUSHBUTTON "Up",ID_LSTICK_UP,218,145,35,15
PUSHBUTTON "Left",ID_LSTICK_LEFT,200,164,35,15
PUSHBUTTON "Right",ID_LSTICK_RIGHT,240,164,35,15
PUSHBUTTON "Down",ID_LSTICK_DOWN,218,184,35,15
PUSHBUTTON "Vert Axis",ID_LSTICK_UDAXIS,257,145,40,15
PUSHBUTTON "Horiz Axis",ID_LSTICK_LRAXIS,257,184,40,15
GROUPBOX "Right Analog Stick",ID_RSTICK,309,135,108,70
PUSHBUTTON "Up",ID_RSTICK_UP,332,145,35,15
PUSHBUTTON "Left",ID_RSTICK_LEFT,314,164,35,15
PUSHBUTTON "Right",ID_RSTICK_RIGHT,354,164,35,15
PUSHBUTTON "Down",ID_RSTICK_DOWN,332,184,35,15
PUSHBUTTON "Vert Axis",ID_RSTICK_UDAXIS,371,145,40,15
PUSHBUTTON "Horiz Axis",ID_RSTICK_LRAXIS,371,184,40,15
GROUPBOX "Sensitivity",ID_SENSITIVITY,195,207,222,49
EDITTEXT IDC_AXIS_DEVICE1,201,218,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
EDITTEXT IDC_AXIS1,201,230,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
EDITTEXT IDC_AXIS_CONTROL1,201,242,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
CONTROL "",IDC_SLIDER1,"msctls_trackbar32",WS_TABSTOP,276,217,138,17
CONTROL "Flip",IDC_FLIP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,280,240,27,10
CONTROL "Turbo",IDC_TURBO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,240,34,10
EDITTEXT IDC_AXIS_SENSITIVITY1,375,240,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
GROUPBOX "",ID_FF,195,6,222,250
COMBOBOX IDC_FF_EFFECT,203,20,206,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_FF_AXIS1,"msctls_trackbar32",WS_TABSTOP,199,40,214,17
CONTROL "Axis 1",IDC_FF_AXIS1_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,60,37,10
CONTROL "Flip",IDC_FF_AXIS1_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,60,35,10
EDITTEXT IDC_FF_AXIS1_SCALE,375,60,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS2,"msctls_trackbar32",WS_TABSTOP,199,76,214,17
CONTROL "Axis 2",IDC_FF_AXIS2_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,96,37,10
CONTROL "Flip",IDC_FF_AXIS2_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,96,35,10
EDITTEXT IDC_FF_AXIS2_SCALE,375,96,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS3,"msctls_trackbar32",WS_TABSTOP,199,112,214,17
CONTROL "Axis 3",IDC_FF_AXIS3_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,132,37,10
CONTROL "Flip",IDC_FF_AXIS3_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,132,35,10
EDITTEXT IDC_FF_AXIS3_SCALE,375,132,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS4,"msctls_trackbar32",WS_TABSTOP,199,148,214,17
CONTROL "Axis 4",IDC_FF_AXIS4_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,168,37,10
CONTROL "Flip",IDC_FF_AXIS4_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,168,35,10
EDITTEXT IDC_FF_AXIS4_SCALE,375,168,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS5,"msctls_trackbar32",WS_TABSTOP,199,184,214,17
CONTROL "Axis 5",IDC_FF_AXIS5_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,204,37,10
CONTROL "Flip",IDC_FF_AXIS5_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,204,35,10
EDITTEXT IDC_FF_AXIS5_SCALE,375,204,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS6,"msctls_trackbar32",WS_TABSTOP,199,220,214,17
CONTROL "Axis 6",IDC_FF_AXIS6_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,240,37,10
CONTROL "Flip",IDC_FF_AXIS6_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,96,35,10
EDITTEXT IDC_FF_AXIS6_SCALE,375,240,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
PUSHBUTTON "Test",ID_TEST,196,260,62,15
PUSHBUTTON "Back to Controls",ID_CONTROLS,196,296,62,15
PUSHBUTTON "Lock Input",ID_LOCK,196,260,62,15
PUSHBUTTON "Lock Direction",ID_LOCK_DIRECTION,196,278,62,15
PUSHBUTTON "Lock Buttons",ID_LOCK_BUTTONS,196,296,62,15
GROUPBOX "New Force Feedback Effect",IDC_STATIC,262,260,155,51
COMBOBOX IDC_FORCEFEEDBACK,269,273,142,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Big Motor",ID_BIG_MOTOR,269,291,64,14
PUSHBUTTON "Small Motor",ID_SMALL_MOTOR,347,291,64,14
END
IDD_CONFIG_GUITAR DIALOGEX 0, 0, 424, 318
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,183,285,WS_EX_CLIENTEDGE
PUSHBUTTON "Delete Selected",ID_DELETE,7,296,59,15
PUSHBUTTON "Clear All",ID_CLEAR,71,296,56,15
PUSHBUTTON "Ignore Key",ID_IGNORE,132,296,58,15
PUSHBUTTON "Fret 1",ID_R2,283,7,45,15
PUSHBUTTON "Fret 2",ID_CIRCLE,283,30,45,15
PUSHBUTTON "Fret 3",ID_TRIANGLE,283,53,45,15
PUSHBUTTON "Fret 4",ID_CROSS,283,76,45,15
PUSHBUTTON "Fret 5",ID_SQUARE,283,99,45,15
PUSHBUTTON "Start",ID_START,256,122,45,15
PUSHBUTTON "Select/Tilt",ID_SELECT,307,122,45,15
PUSHBUTTON "Whammy Bar Up",ID_LSTICK_UP,219,146,69,15
PUSHBUTTON "Whammy Bar Axis",ID_LSTICK_UDAXIS,212,165,84,15
PUSHBUTTON "Whammy Bar Down",ID_LSTICK_DOWN,219,184,69,15
PUSHBUTTON "Analog",ID_ANALOG,372,7,45,12,NOT WS_VISIBLE
PUSHBUTTON "Mouse",ID_MOUSE,372,51,45,12,NOT WS_VISIBLE
PUSHBUTTON "L3",ID_L3,203,7,45,15,NOT WS_VISIBLE
PUSHBUTTON "R3",ID_R3,203,23,46,15,NOT WS_VISIBLE
PUSHBUTTON "Strum Bar Up",ID_DPAD_UP,336,146,58,15
PUSHBUTTON "Strum Bar Axis",ID_DPAD_UDAXIS,328,165,74,15
PUSHBUTTON "Strum Bar Down",ID_DPAD_DOWN,336,184,58,15
PUSHBUTTON "Left",ID_DPAD_LEFT,342,28,35,15,NOT WS_VISIBLE
PUSHBUTTON "Right",ID_DPAD_RIGHT,382,28,35,15,NOT WS_VISIBLE
PUSHBUTTON "L1",ID_L1,372,85,45,15,NOT WS_VISIBLE
PUSHBUTTON "R1",ID_R1,372,67,45,15,NOT WS_VISIBLE
PUSHBUTTON "L2",ID_L2,372,103,45,15,NOT WS_VISIBLE
PUSHBUTTON "L1/R1 Axis",ID_L1R1,203,74,45,15,NOT WS_VISIBLE
PUSHBUTTON "L2/R2 Axis",ID_L2R2,203,58,45,15,NOT WS_VISIBLE
PUSHBUTTON "L3/R3 Axis",ID_L3R3,203,42,45,15,NOT WS_VISIBLE
GROUPBOX "Sensitivity",ID_SENSITIVITY,195,207,222,49
EDITTEXT IDC_AXIS_DEVICE1,201,218,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
EDITTEXT IDC_AXIS1,201,230,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
EDITTEXT IDC_AXIS_CONTROL1,201,242,74,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
CONTROL "",IDC_SLIDER1,"msctls_trackbar32",WS_TABSTOP,276,217,138,17
CONTROL "Flip",IDC_FLIP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,280,240,27,10
CONTROL "Turbo",IDC_TURBO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,240,34,10
EDITTEXT IDC_AXIS_SENSITIVITY1,375,240,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
GROUPBOX "",ID_FF,195,6,222,250
COMBOBOX IDC_FF_EFFECT,203,20,206,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_FF_AXIS1,"msctls_trackbar32",WS_TABSTOP,199,40,214,17
CONTROL "Axis 1",IDC_FF_AXIS1_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,60,37,10
CONTROL "Flip",IDC_FF_AXIS1_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,60,35,10
EDITTEXT IDC_FF_AXIS1_SCALE,375,60,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS2,"msctls_trackbar32",WS_TABSTOP,199,76,214,17
CONTROL "Axis 2",IDC_FF_AXIS2_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,96,37,10
CONTROL "Flip",IDC_FF_AXIS2_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,96,35,10
EDITTEXT IDC_FF_AXIS2_SCALE,375,96,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS3,"msctls_trackbar32",WS_TABSTOP,199,112,214,17
CONTROL "Axis 3",IDC_FF_AXIS3_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,132,37,10
CONTROL "Flip",IDC_FF_AXIS3_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,132,35,10
EDITTEXT IDC_FF_AXIS3_SCALE,375,132,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS4,"msctls_trackbar32",WS_TABSTOP,199,148,214,17
CONTROL "Axis 4",IDC_FF_AXIS4_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,168,37,10
CONTROL "Flip",IDC_FF_AXIS4_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,168,35,10
EDITTEXT IDC_FF_AXIS4_SCALE,375,168,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS5,"msctls_trackbar32",WS_TABSTOP,199,184,214,17
CONTROL "Axis 5",IDC_FF_AXIS5_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,204,37,10
CONTROL "Flip",IDC_FF_AXIS5_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,260,204,35,10
EDITTEXT IDC_FF_AXIS5_SCALE,375,204,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
CONTROL "",IDC_FF_AXIS6,"msctls_trackbar32",WS_TABSTOP,199,220,214,17
CONTROL "Axis 6",IDC_FF_AXIS6_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,240,37,10
CONTROL "Flip",IDC_FF_AXIS6_FLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,96,35,10
EDITTEXT IDC_FF_AXIS6_SCALE,375,240,33,12,ES_RIGHT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_RTLREADING
PUSHBUTTON "Test",ID_TEST,196,260,62,15
PUSHBUTTON "Back to Controls",ID_CONTROLS,196,296,62,15
PUSHBUTTON "Lock Input",ID_LOCK,196,260,62,15
PUSHBUTTON "Lock Direction",ID_LOCK_DIRECTION,196,278,62,15
PUSHBUTTON "Lock Buttons",ID_LOCK_BUTTONS,196,296,62,15
GROUPBOX "New Force Feedback Effect",IDC_STATIC,262,260,155,51
COMBOBOX IDC_FORCEFEEDBACK,269,273,142,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Big Motor",ID_BIG_MOTOR,269,291,64,14
PUSHBUTTON "Small Motor",ID_SMALL_MOTOR,347,291,64,14
END
IDD_GENERAL DIALOGEX 0, 0, 424, 318
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "Input APIs",IDC_STATIC,7,6,410,131
GROUPBOX "Keyboard API",IDC_STATIC,16,16,192,61
CONTROL "Windows messaging",IDC_KB_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,23,28,112,10
CONTROL "Raw input (XP and later only)",IDC_KB_RAW,"Button",BS_AUTORADIOBUTTON,23,40,112,10
CONTROL "DirectInput",IDC_KB_DI,"Button",BS_AUTORADIOBUTTON,23,52,112,10
CONTROL "Disable (Intended for use with other pad plugins)",IDC_KB_DISABLE,
"Button",BS_AUTORADIOBUTTON,23,64,175,10
GROUPBOX "Game Device APIs",IDC_STATIC,16,81,191,49
CONTROL "DirectInput",IDC_G_DI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,92,65,10
CONTROL "XInput",IDC_G_XI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,104,39,10
CONTROL "Monitor when in background",IDC_BACKGROUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,116,106,10
GROUPBOX "Mouse API",IDC_STATIC,216,16,192,73
CONTROL "Windows messaging",IDC_M_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,224,27,112,10
CONTROL "Raw input (XP and later only)",IDC_M_RAW,"Button",BS_AUTORADIOBUTTON,224,39,112,10
CONTROL "DirectInput",IDC_M_DI,"Button",BS_AUTORADIOBUTTON,224,51,112,10
CONTROL "Disable",IDC_M_DISABLE,"Button",BS_AUTORADIOBUTTON,224,63,39,10
CONTROL "Start without mouse focus",IDC_MOUSE_UNFOCUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,75,97,10
GROUPBOX "Advanced",IDC_STATIC,216,92,192,38
CONTROL "Allow binding entire axes to single buttons",IDC_AXIS_BUTTONS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,104,177,10
CONTROL "Allow multiple binding",IDC_MULTIPLE_BINDING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,116,83,10
GROUPBOX "Pad Options",IDC_STATIC,7,140,410,67
GROUPBOX "Pad 1",IDC_STATIC,16,150,192,49
CONTROL "Disable pad",IDC_DISABLE_PAD1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,162,53,10
CONTROL "Use analog mode whenever possible",IDC_ANALOG_START1,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,174,132,10
CONTROL "Guitar",IDC_GUITAR1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,186,35,10
GROUPBOX "Pad 2",IDC_STATIC,216,150,192,49
CONTROL "Disable pad",IDC_DISABLE_PAD2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,162,53,10
CONTROL "Use analog mode whenever possible",IDC_ANALOG_START2,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,174,132,10
CONTROL "Guitar",IDC_GUITAR2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,186,35,10
GROUPBOX "Device Diagnostics",IDC_STATIC,7,211,201,99
CONTROL "",IDC_LIST,"SysListView32",LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,15,224,185,61,WS_EX_CLIENTEDGE
PUSHBUTTON "Test Device",ID_TEST,86,289,57,15
PUSHBUTTON "Refresh",ID_REFRESH,152,289,48,15
GROUPBOX "Hacks",IDC_STATIC,216,211,201,73
CONTROL "Send escape on close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,223,113,10
CONTROL "Exit emulator on close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,235,86,10
CONTROL "Hide on fullscreen escape",IDC_ESCAPE_FULLSCREEN_HACK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,247,97,10
CONTROL "Always hide cursor",IDC_FORCE_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,259,71,10
CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,271,80,10
CONTROL "Guitar Hero 2",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,333,223,59,10
CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,333,235,62,10
GROUPBOX "Debugging",IDC_STATIC,216,285,79,25
CONTROL "Enable logging",IDC_DEBUG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,296,63,10
PUSHBUTTON "Save",ID_SAVE,369,295,48,15
PUSHBUTTON "Load",ID_LOAD,313,295,48,15
END
IDD_ABOUT DIALOGEX 0, 0, 100, 66
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About LilyPad"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CTEXT "LilyPad plugin",IDC_STATIC,7,7,86,10
ICON IDI_FROG,IDC_STATIC,39,20,20,20
DEFPUSHBUTTON "OK",IDOK,25,45,50,14
END
IDD_DIAG DIALOGEX 0, 0, 190, 178
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " "
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,176,164,WS_EX_CLIENTEDGE
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 417
TOPMARGIN, 7
BOTTOMMARGIN, 311
END
IDD_CONFIG_GUITAR, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 417
TOPMARGIN, 7
BOTTOMMARGIN, 311
END
IDD_GENERAL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 417
TOPMARGIN, 7
BOTTOMMARGIN, 310
END
IDD_ABOUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 93
TOPMARGIN, 7
BOTTOMMARGIN, 59
END
IDD_DIAG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 183
TOPMARGIN, 7
BOTTOMMARGIN, 171
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_FROG ICON "frog.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LilyPad", "LilyPad_VC2005.vcproj", "{E4081455-398C-4610-A87C-90A8A7D72DC3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|Win32.ActiveCfg = Debug|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|Win32.Build.0 = Debug|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|x64.ActiveCfg = Debug|x64
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|x64.Build.0 = Debug|x64
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|Win32.ActiveCfg = Release|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|Win32.Build.0 = Release|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|x64.ActiveCfg = Release|x64
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,741 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="LilyPad"
ProjectGUID="{E4081455-398C-4610-A87C-90A8A7D72DC3}"
RootNamespace="LilyPad"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/LilyPad.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateManifest="false"
ModuleDefinitionFile=".\LilyPad.def"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/LilyPad.pdb"
ImportLibrary=".\Debug/LilyPad.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="3"
TypeLibraryName=".\Debug/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="2"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\LilyPad.def"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/LilyPad.pdb"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="false"
PrecompiledHeaderFile=".\Release/LilyPad.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ntdll.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateManifest="false"
IgnoreAllDefaultLibraries="true"
ModuleDefinitionFile=".\LilyPad.def"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
LinkTimeCodeGeneration="0"
EntryPointSymbol="MyDllMainCRTStartup"
ImportLibrary=".\Release/LilyPad.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="3"
TypeLibraryName=".\Release/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="2"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="2"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
FloatingPointModel="2"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib dinput8.lib dxguid.lib comctl32.lib"
OutputFile="$(OutDir)\$(ProjectName)64.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\LilyPad.def"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
EntryPointSymbol=""
BaseAddress="0x15000000"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mt.exe -manifest $(IntDir)\LilyPad64.dll.manifest -outputresource:$(OutDir)\$(ProjectName)64.dll"
ExcludedFromBuild="true"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="Config.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="Config.h"
>
</File>
<File
RelativePath=".\Diagnostics.cpp"
>
</File>
<File
RelativePath=".\Diagnostics.h"
>
</File>
<File
RelativePath="LilyPad.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="Global.h"
>
</File>
<File
RelativePath="PS2Edefs.h"
>
</File>
<File
RelativePath="PS2Etypes.h"
>
</File>
<File
RelativePath="resource.h"
>
</File>
<File
RelativePath="VKey.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="VKey.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
<File
RelativePath="frog.ico"
>
</File>
<File
RelativePath="LilyPad.def"
>
</File>
<File
RelativePath="LilyPad.rc"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="InputAPIs"
>
<File
RelativePath=".\DirectInput.cpp"
>
</File>
<File
RelativePath=".\DirectInput.h"
>
</File>
<File
RelativePath=".\KeyboardHook.cpp"
>
</File>
<File
RelativePath=".\KeyboardHook.h"
>
</File>
<File
RelativePath=".\KeyboardQueue.cpp"
>
</File>
<File
RelativePath=".\KeyboardQueue.h"
>
</File>
<File
RelativePath=".\RawInput.cpp"
>
</File>
<File
RelativePath=".\RawInput.h"
>
</File>
<File
RelativePath=".\WindowsKeyboard.cpp"
>
</File>
<File
RelativePath=".\WindowsKeyboard.h"
>
</File>
<File
RelativePath=".\WindowsMessaging.cpp"
>
</File>
<File
RelativePath=".\WindowsMessaging.h"
>
</File>
<File
RelativePath=".\WindowsMouse.cpp"
>
</File>
<File
RelativePath=".\WindowsMouse.h"
>
</File>
<File
RelativePath=".\XInput.cpp"
>
</File>
<File
RelativePath=".\XInput.h"
>
</File>
</Filter>
<Filter
Name="Input"
>
<File
RelativePath=".\DeviceEnumerator.cpp"
>
</File>
<File
RelativePath=".\DeviceEnumerator.h"
>
</File>
<File
RelativePath=".\InputManager.cpp"
>
</File>
<File
RelativePath=".\InputManager.h"
>
</File>
<File
RelativePath=".\WndProcEater.cpp"
>
</File>
<File
RelativePath=".\WndProcEater.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LilyPad", "LilyPad_VC2008.vcproj", "{E4081455-398C-4610-A87C-90A8A7D72DC3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|Win32.ActiveCfg = Debug|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|Win32.Build.0 = Debug|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|x64.ActiveCfg = Debug|x64
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Debug|x64.Build.0 = Debug|x64
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|Win32.ActiveCfg = Release|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|Win32.Build.0 = Release|Win32
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|x64.ActiveCfg = Release|x64
{E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,738 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="LilyPad"
ProjectGUID="{E4081455-398C-4610-A87C-90A8A7D72DC3}"
RootNamespace="LilyPad"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/LilyPad.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateManifest="false"
ModuleDefinitionFile=".\LilyPad.def"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/LilyPad.pdb"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary=".\Debug/LilyPad.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="false"
PrecompiledHeaderFile=".\Release/LilyPad.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ntdll.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateManifest="false"
IgnoreAllDefaultLibraries="true"
ModuleDefinitionFile=".\LilyPad.def"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
EntryPointSymbol="MyDllMainCRTStartup"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary=".\Release/LilyPad.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="3"
TypeLibraryName=".\Debug/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="2"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\LilyPad.def"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/LilyPad.pdb"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="3"
TypeLibraryName=".\Release/LilyPad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="2"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEST_EXPORTS"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="2"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
FloatingPointModel="2"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
DisableSpecificWarnings="4995, 4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib dinput8.lib dxguid.lib comctl32.lib"
OutputFile="$(OutDir)\$(ProjectName)64.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\LilyPad.def"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol=""
BaseAddress="0x15000000"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/LilyPad.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mt.exe -manifest $(IntDir)\LilyPad64.dll.manifest -outputresource:$(OutDir)\$(ProjectName)64.dll"
ExcludedFromBuild="true"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="Config.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="Config.h"
>
</File>
<File
RelativePath=".\Diagnostics.cpp"
>
</File>
<File
RelativePath=".\Diagnostics.h"
>
</File>
<File
RelativePath="LilyPad.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="Global.h"
>
</File>
<File
RelativePath="PS2Edefs.h"
>
</File>
<File
RelativePath="PS2Etypes.h"
>
</File>
<File
RelativePath="resource.h"
>
</File>
<File
RelativePath="VKey.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="VKey.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
<File
RelativePath="frog.ico"
>
</File>
<File
RelativePath="LilyPad.def"
>
</File>
<File
RelativePath="LilyPad.rc"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="InputAPIs"
>
<File
RelativePath=".\DirectInput.cpp"
>
</File>
<File
RelativePath=".\DirectInput.h"
>
</File>
<File
RelativePath=".\KeyboardHook.cpp"
>
</File>
<File
RelativePath=".\KeyboardHook.h"
>
</File>
<File
RelativePath=".\KeyboardQueue.cpp"
>
</File>
<File
RelativePath=".\KeyboardQueue.h"
>
</File>
<File
RelativePath=".\RawInput.cpp"
>
</File>
<File
RelativePath=".\RawInput.h"
>
</File>
<File
RelativePath=".\WindowsKeyboard.cpp"
>
</File>
<File
RelativePath=".\WindowsKeyboard.h"
>
</File>
<File
RelativePath=".\WindowsMessaging.cpp"
>
</File>
<File
RelativePath=".\WindowsMessaging.h"
>
</File>
<File
RelativePath=".\WindowsMouse.cpp"
>
</File>
<File
RelativePath=".\WindowsMouse.h"
>
</File>
<File
RelativePath=".\XInput.cpp"
>
</File>
<File
RelativePath=".\XInput.h"
>
</File>
</Filter>
<Filter
Name="Input"
>
<File
RelativePath=".\DeviceEnumerator.cpp"
>
</File>
<File
RelativePath=".\DeviceEnumerator.h"
>
</File>
<File
RelativePath=".\InputManager.cpp"
>
</File>
<File
RelativePath=".\InputManager.h"
>
</File>
<File
RelativePath=".\WndProcEater.cpp"
>
</File>
<File
RelativePath=".\WndProcEater.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

834
plugins/LilyPad/PS2Edefs.h Normal file
View File

@ -0,0 +1,834 @@
#ifndef __PS2EDEFS_H__
#define __PS2EDEFS_H__
/*
* PS2E Definitions v0.6.2 (beta)
*
* Author: linuzappz@hotmail.com
* shadowpcsx2@yahoo.gr
* florinsasu@hotmail.com
*/
/*
Notes:
* Since this is still beta things may change.
* OSflags:
__LINUX__ (linux OS)
_WIN32 (win32 OS)
* common return values (for ie. GSinit):
0 - success
-1 - error
* reserved keys:
F1 to F10 are reserved for the emulator
* plugins should NOT change the current
working directory.
(on win32, add flag OFN_NOCHANGEDIR for
GetOpenFileName)
*/
#include "PS2Etypes.h"
#ifdef __LINUX__
#define CALLBACK
#else
#include <windows.h>
#endif
/* common defines */
#ifndef C_ASSERT
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#endif
#if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) || \
defined(SPU2defs) || defined(CDVDdefs) || defined(DEV9defs) || \
defined(USBdefs) || defined(FWdefs)
#define COMMONdefs
#endif
// PS2EgetLibType returns (may be OR'd)
#define PS2E_LT_GS 0x01
#define PS2E_LT_PAD 0x02 // -=[ OBSOLETE ]=-
#define PS2E_LT_SPU2 0x04
#define PS2E_LT_CDVD 0x08
#define PS2E_LT_DEV9 0x10
#define PS2E_LT_USB 0x20
#define PS2E_LT_FW 0x40
#define PS2E_LT_SIO 0x80
// PS2EgetLibVersion2 (high 16 bits)
#define PS2E_GS_VERSION 0x0006
#define PS2E_PAD_VERSION 0x0002 // -=[ OBSOLETE ]=-
#define PS2E_SPU2_VERSION 0x0005
#define PS2E_CDVD_VERSION 0x0005
#define PS2E_DEV9_VERSION 0x0003
#define PS2E_USB_VERSION 0x0003
#define PS2E_FW_VERSION 0x0002
#define PS2E_SIO_VERSION 0x0001
#ifdef COMMONdefs
u32 CALLBACK PS2EgetLibType(void);
u32 CALLBACK PS2EgetLibVersion2(u32 type);
char* CALLBACK PS2EgetLibName(void);
#endif
// key values:
/* key values must be OS dependant:
win32: the VK_XXX will be used (WinUser)
linux: the XK_XXX will be used (XFree86)
*/
// event values:
#define KEYPRESS 1
#define KEYRELEASE 2
typedef struct {
u32 key;
u32 event;
} keyEvent;
// for 64bit compilers
typedef char __keyEvent_Size__[(sizeof(keyEvent) == 8)?1:-1];
// plugin types
#define SIO_TYPE_PAD 0x00000001
#define SIO_TYPE_MTAP 0x00000004
#define SIO_TYPE_RM 0x00000040
#define SIO_TYPE_MC 0x00000100
typedef int (CALLBACK * SIOchangeSlotCB)(int slot);
typedef struct {
u8 ctrl:4; // control and mode bits
u8 mode:4; // control and mode bits
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute location on the disc (BCD encoded)
u8 trackS; // current sector location on the disc (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded)
u8 pad; // unused
u8 discM; // current minute offset from first track (BCD encoded)
u8 discS; // current sector offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded)
} cdvdSubQ;
typedef struct { // NOT bcd coded
u32 lsn;
u8 type;
} cdvdTD;
typedef struct {
u8 strack; //number of the first track (usually 1)
u8 etrack; //number of the last track
} cdvdTN;
// CDVDreadTrack mode values:
#define CDVD_MODE_2352 0 // full 2352 bytes
#define CDVD_MODE_2340 1 // skip sync (12) bytes
#define CDVD_MODE_2328 2 // skip sync+head+sub (24) bytes
#define CDVD_MODE_2048 3 // skip sync+head+sub (24) bytes
#define CDVD_MODE_2368 4 // full 2352 bytes + 16 subq
// CDVDgetDiskType returns:
#define CDVD_TYPE_ILLEGAL 0xff // Illegal Disc
#define CDVD_TYPE_DVDV 0xfe // DVD Video
#define CDVD_TYPE_CDDA 0xfd // Audio CD
#define CDVD_TYPE_PS2DVD 0x14 // PS2 DVD
#define CDVD_TYPE_PS2CDDA 0x13 // PS2 CD (with audio)
#define CDVD_TYPE_PS2CD 0x12 // PS2 CD
#define CDVD_TYPE_PSCDDA 0x11 // PS CD (with audio)
#define CDVD_TYPE_PSCD 0x10 // PS CD
#define CDVD_TYPE_UNKNOWN 0x05 // Unknown
#define CDVD_TYPE_DETCTDVDD 0x04 // Detecting Dvd Dual Sided
#define CDVD_TYPE_DETCTDVDS 0x03 // Detecting Dvd Single Sided
#define CDVD_TYPE_DETCTCD 0x02 // Detecting Cd
#define CDVD_TYPE_DETCT 0x01 // Detecting
#define CDVD_TYPE_NODISC 0x00 // No Disc
// CDVDgetTrayStatus returns:
#define CDVD_TRAY_CLOSE 0x00
#define CDVD_TRAY_OPEN 0x01
// cdvdTD.type (track types for cds)
#define CDVD_AUDIO_TRACK 0x01
#define CDVD_MODE1_TRACK 0x41
#define CDVD_MODE2_TRACK 0x61
#define CDVD_AUDIO_MASK 0x00
#define CDVD_DATA_MASK 0x40
// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel)
typedef void (*DEV9callback)(int cycles);
typedef int (*DEV9handler)(void);
typedef void (*USBcallback)(int cycles);
typedef int (*USBhandler)(void);
// freeze modes:
#define FREEZE_LOAD 0
#define FREEZE_SAVE 1
#define FREEZE_SIZE 2
typedef struct {
char name[8];
void *common;
} GSdriverInfo;
#ifdef _WIN32
typedef struct { // unsupported values must be set to zero
HWND hWnd;
HMENU hMenu;
HWND hStatusWnd;
} winInfo;
#endif
/* GS plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef GSdefs
// basic funcs
s32 CALLBACK GSinit();
s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread);
void CALLBACK GSclose();
void CALLBACK GSshutdown();
void CALLBACK GSvsync(int field);
void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr);
void CALLBACK GSgifTransfer2(u32 *pMem, u32 size);
void CALLBACK GSgifTransfer3(u32 *pMem, u32 size);
void CALLBACK GSgetLastTag(u64* ptag); // returns the last tag processed (64 bits)
void CALLBACK GSgifSoftReset(u32 mask);
void CALLBACK GSreadFIFO(u64 *mem);
void CALLBACK GSreadFIFO2(u64 *mem, int qwc);
// extended funcs
// GSkeyEvent gets called when there is a keyEvent from the PAD plugin
void CALLBACK GSkeyEvent(keyEvent *ev);
void CALLBACK GSchangeSaveState(int, const char* filename);
void CALLBACK GSmakeSnapshot(char *path);
void CALLBACK GSmakeSnapshot2(char *pathname, int* snapdone, int savejpg);
void CALLBACK GSirqCallback(void (*callback)());
void CALLBACK GSprintf(int timeout, char *fmt, ...);
void CALLBACK GSsetBaseMem(void*);
void CALLBACK GSsetGameCRC(int crc, int gameoptions);
// controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done
void CALLBACK GSsetFrameSkip(int frameskip);
void CALLBACK GSreset();
void CALLBACK GSwriteCSR(u32 value);
void CALLBACK GSgetDriverInfo(GSdriverInfo *info);
#ifdef _WIN32
s32 CALLBACK GSsetWindowInfo(winInfo *info);
#endif
s32 CALLBACK GSfreeze(int mode, freezeData *data);
void CALLBACK GSconfigure();
void CALLBACK GSabout();
s32 CALLBACK GStest();
#endif
/* PAD plugin API -=[ OBSOLETE ]=- */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef PADdefs
// basic funcs
s32 CALLBACK PADinit(u32 flags);
s32 CALLBACK PADopen(void *pDsp);
void CALLBACK PADclose();
void CALLBACK PADshutdown();
// PADkeyEvent is called every vsync (return NULL if no event)
keyEvent* CALLBACK PADkeyEvent();
u8 CALLBACK PADstartPoll(int pad);
u8 CALLBACK PADpoll(u8 value);
// returns: 1 if supported pad1
// 2 if supported pad2
// 3 if both are supported
u32 CALLBACK PADquery();
// call to give a hint to the PAD plugin to query for the keyboard state. A
// good plugin will query the OS for keyboard state ONLY in this function.
// This function is necessary when multithreading because otherwise
// the PAD plugin can get into deadlocks with the thread that really owns
// the window (and input). Note that PADupdate can be called from a different
// thread than the other functions, so mutex or other multithreading primitives
// have to be added to maintain data integrity.
void CALLBACK PADupdate(int pad);
// extended funcs
void CALLBACK PADgsDriverInfo(GSdriverInfo *info);
void CALLBACK PADconfigure();
void CALLBACK PADabout();
s32 CALLBACK PADtest();
#endif
/* SIO plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef SIOdefs
// basic funcs
s32 CALLBACK SIOinit(u32 port, u32 slot, SIOchangeSlotCB f);
s32 CALLBACK SIOopen(void *pDsp);
void CALLBACK SIOclose();
void CALLBACK SIOshutdown();
u8 CALLBACK SIOstartPoll(u8 value);
u8 CALLBACK SIOpoll(u8 value);
// returns: SIO_TYPE_{PAD,MTAP,RM,MC}
u32 CALLBACK SIOquery();
// extended funcs
void CALLBACK SIOconfigure();
void CALLBACK SIOabout();
s32 CALLBACK SIOtest();
#endif
/* SPU2 plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef SPU2defs
// basic funcs
s32 CALLBACK SPU2init();
s32 CALLBACK SPU2open(void *pDsp);
void CALLBACK SPU2close();
void CALLBACK SPU2shutdown();
void CALLBACK SPU2write(u32 mem, u16 value);
u16 CALLBACK SPU2read(u32 mem);
void CALLBACK SPU2readDMA4Mem(u16 *pMem, int size);
void CALLBACK SPU2writeDMA4Mem(u16 *pMem, int size);
void CALLBACK SPU2interruptDMA4();
void CALLBACK SPU2readDMA7Mem(u16* pMem, int size);
void CALLBACK SPU2writeDMA7Mem(u16 *pMem, int size);
// all addresses passed by dma will be pointers to the array starting at baseaddr
// This function is necessary to successfully save and reload the spu2 state
void CALLBACK SPU2setDMABaseAddr(uptr baseaddr);
void CALLBACK SPU2interruptDMA7();
u32 CALLBACK SPU2ReadMemAddr(int core);
void CALLBACK SPU2WriteMemAddr(int core,u32 value);
void CALLBACK SPU2irqCallback(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
// extended funcs
void CALLBACK SPU2async(u32 cycles);
s32 CALLBACK SPU2freeze(int mode, freezeData *data);
void CALLBACK SPU2configure();
void CALLBACK SPU2about();
s32 CALLBACK SPU2test();
#endif
/* CDVD plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef CDVDdefs
// basic funcs
s32 CALLBACK CDVDinit();
s32 CALLBACK CDVDopen(const char* pTitleFilename);
void CALLBACK CDVDclose();
void CALLBACK CDVDshutdown();
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode);
// return can be NULL (for async modes)
u8* CALLBACK CDVDgetBuffer();
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data)
s32 CALLBACK CDVDgetTN(cdvdTN *Buffer); //disk information
s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type
s32 CALLBACK CDVDgetTOC(void* toc); //gets ps2 style toc from disc
s32 CALLBACK CDVDgetDiskType(); //CDVD_TYPE_xxxx
s32 CALLBACK CDVDgetTrayStatus(); //CDVD_TRAY_xxxx
s32 CALLBACK CDVDctrlTrayOpen(); //open disc tray
s32 CALLBACK CDVDctrlTrayClose(); //close disc tray
// extended funcs
void CALLBACK CDVDconfigure();
void CALLBACK CDVDabout();
s32 CALLBACK CDVDtest();
void CALLBACK CDVDnewDiskCB(void (*callback)());
#endif
/* DEV9 plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef DEV9defs
// basic funcs
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
s32 CALLBACK DEV9init();
s32 CALLBACK DEV9open(void *pDsp);
void CALLBACK DEV9close();
void CALLBACK DEV9shutdown();
u8 CALLBACK DEV9read8(u32 addr);
u16 CALLBACK DEV9read16(u32 addr);
u32 CALLBACK DEV9read32(u32 addr);
void CALLBACK DEV9write8(u32 addr, u8 value);
void CALLBACK DEV9write16(u32 addr, u16 value);
void CALLBACK DEV9write32(u32 addr, u32 value);
void CALLBACK DEV9readDMA8Mem(u32 *pMem, int size);
void CALLBACK DEV9writeDMA8Mem(u32 *pMem, int size);
// cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not
void CALLBACK DEV9irqCallback(DEV9callback callback);
DEV9handler CALLBACK DEV9irqHandler(void);
// extended funcs
s32 CALLBACK DEV9freeze(int mode, freezeData *data);
void CALLBACK DEV9configure();
void CALLBACK DEV9about();
s32 CALLBACK DEV9test();
#endif
/* USB plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef USBdefs
// basic funcs
s32 CALLBACK USBinit();
s32 CALLBACK USBopen(void *pDsp);
void CALLBACK USBclose();
void CALLBACK USBshutdown();
u8 CALLBACK USBread8(u32 addr);
u16 CALLBACK USBread16(u32 addr);
u32 CALLBACK USBread32(u32 addr);
void CALLBACK USBwrite8(u32 addr, u8 value);
void CALLBACK USBwrite16(u32 addr, u16 value);
void CALLBACK USBwrite32(u32 addr, u32 value);
// cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not
void CALLBACK USBirqCallback(USBcallback callback);
USBhandler CALLBACK USBirqHandler(void);
void CALLBACK USBsetRAM(void *mem);
// extended funcs
s32 CALLBACK USBfreeze(int mode, freezeData *data);
void CALLBACK USBconfigure();
void CALLBACK USBabout();
s32 CALLBACK USBtest();
#endif
/* FW plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef FWdefs
// basic funcs
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
s32 CALLBACK FWinit();
s32 CALLBACK FWopen(void *pDsp);
void CALLBACK FWclose();
void CALLBACK FWshutdown();
u32 CALLBACK FWread32(u32 addr);
void CALLBACK FWwrite32(u32 addr, u32 value);
void CALLBACK FWirqCallback(void (*callback)());
// extended funcs
s32 CALLBACK FWfreeze(int mode, freezeData *data);
void CALLBACK FWconfigure();
void CALLBACK FWabout();
s32 CALLBACK FWtest();
#endif
// might be useful for emulators
#ifdef PLUGINtypedefs
typedef u32 (CALLBACK* _PS2EgetLibType)(void);
typedef u32 (CALLBACK* _PS2EgetLibVersion2)(u32 type);
typedef char*(CALLBACK* _PS2EgetLibName)(void);
// GS
// NOTE: GSreadFIFOX/GSwriteCSR functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _GSinit)();
typedef s32 (CALLBACK* _GSopen)(void *pDsp, char *Title, int multithread);
typedef void (CALLBACK* _GSclose)();
typedef void (CALLBACK* _GSshutdown)();
typedef void (CALLBACK* _GSvsync)(int field);
typedef void (CALLBACK* _GSgifTransfer1)(u32 *pMem, u32 addr);
typedef void (CALLBACK* _GSgifTransfer2)(u32 *pMem, u32 size);
typedef void (CALLBACK* _GSgifTransfer3)(u32 *pMem, u32 size);
typedef void (CALLBACK* _GSgetLastTag)(u64* ptag); // returns the last tag processed (64 bits)
typedef void (CALLBACK* _GSgifSoftReset)(u32 mask);
typedef void (CALLBACK* _GSreadFIFO)(u64 *pMem);
typedef void (CALLBACK* _GSreadFIFO2)(u64 *pMem, int qwc);
typedef void (CALLBACK* _GSkeyEvent)(keyEvent* ev);
typedef void (CALLBACK* _GSchangeSaveState)(int, const char* filename);
typedef void (CALLBACK* _GSirqCallback)(void (*callback)());
typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...);
typedef void (CALLBACK* _GSsetBaseMem)(void*);
typedef void (CALLBACK* _GSsetGameCRC)(int, int);
typedef void (CALLBACK* _GSsetFrameSkip)(int frameskip);
typedef void (CALLBACK* _GSreset)();
typedef void (CALLBACK* _GSwriteCSR)(u32 value);
typedef void (CALLBACK* _GSgetDriverInfo)(GSdriverInfo *info);
#ifdef _WIN32
typedef s32 (CALLBACK* _GSsetWindowInfo)(winInfo *info);
#endif
typedef void (CALLBACK* _GSmakeSnapshot)(char *path);
typedef void (CALLBACK* _GSmakeSnapshot2)(char *path, int*, int);
typedef s32 (CALLBACK* _GSfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _GSconfigure)();
typedef s32 (CALLBACK* _GStest)();
typedef void (CALLBACK* _GSabout)();
// PAD
typedef s32 (CALLBACK* _PADinit)(u32 flags);
typedef s32 (CALLBACK* _PADopen)(void *pDsp);
typedef void (CALLBACK* _PADclose)();
typedef void (CALLBACK* _PADshutdown)();
typedef keyEvent* (CALLBACK* _PADkeyEvent)();
typedef u8 (CALLBACK* _PADstartPoll)(int pad);
typedef u8 (CALLBACK* _PADpoll)(u8 value);
typedef u32 (CALLBACK* _PADquery)();
typedef void (CALLBACK* _PADupdate)(int pad);
typedef void (CALLBACK* _PADgsDriverInfo)(GSdriverInfo *info);
typedef void (CALLBACK* _PADconfigure)();
typedef s32 (CALLBACK* _PADtest)();
typedef void (CALLBACK* _PADabout)();
// SIO
typedef s32 (CALLBACK* _SIOinit)(u32 port, u32 slot, SIOchangeSlotCB f);
typedef s32 (CALLBACK* _SIOopen)(void *pDsp);
typedef void (CALLBACK* _SIOclose)();
typedef void (CALLBACK* _SIOshutdown)();
typedef u8 (CALLBACK* _SIOstartPoll)(u8 value);
typedef u8 (CALLBACK* _SIOpoll)(u8 value);
typedef u32 (CALLBACK* _SIOquery)();
typedef void (CALLBACK* _SIOconfigure)();
typedef s32 (CALLBACK* _SIOtest)();
typedef void (CALLBACK* _SIOabout)();
// SPU2
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _SPU2init)();
typedef s32 (CALLBACK* _SPU2open)(void *pDsp);
typedef void (CALLBACK* _SPU2close)();
typedef void (CALLBACK* _SPU2shutdown)();
typedef void (CALLBACK* _SPU2write)(u32 mem, u16 value);
typedef u16 (CALLBACK* _SPU2read)(u32 mem);
typedef void (CALLBACK* _SPU2readDMA4Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2writeDMA4Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2interruptDMA4)();
typedef void (CALLBACK* _SPU2readDMA7Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2writeDMA7Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2setDMABaseAddr)(uptr baseaddr);
typedef void (CALLBACK* _SPU2interruptDMA7)();
typedef void (CALLBACK* _SPU2irqCallback)(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
typedef u32 (CALLBACK* _SPU2ReadMemAddr)(int core);
typedef void (CALLBACK* _SPU2WriteMemAddr)(int core,u32 value);
typedef void (CALLBACK* _SPU2async)(u32 cycles);
typedef s32 (CALLBACK* _SPU2freeze)(int mode, freezeData *data);
typedef void (CALLBACK* _SPU2configure)();
typedef s32 (CALLBACK* _SPU2test)();
typedef void (CALLBACK* _SPU2about)();
// CDVD
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _CDVDinit)();
typedef s32 (CALLBACK* _CDVDopen)(const char* pTitleFilename);
typedef void (CALLBACK* _CDVDclose)();
typedef void (CALLBACK* _CDVDshutdown)();
typedef s32 (CALLBACK* _CDVDreadTrack)(u32 lsn, int mode);
typedef u8* (CALLBACK* _CDVDgetBuffer)();
typedef s32 (CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq);
typedef s32 (CALLBACK* _CDVDgetTN)(cdvdTN *Buffer);
typedef s32 (CALLBACK* _CDVDgetTD)(u8 Track, cdvdTD *Buffer);
typedef s32 (CALLBACK* _CDVDgetTOC)(void* toc);
typedef s32 (CALLBACK* _CDVDgetDiskType)();
typedef s32 (CALLBACK* _CDVDgetTrayStatus)();
typedef s32 (CALLBACK* _CDVDctrlTrayOpen)();
typedef s32 (CALLBACK* _CDVDctrlTrayClose)();
typedef void (CALLBACK* _CDVDconfigure)();
typedef s32 (CALLBACK* _CDVDtest)();
typedef void (CALLBACK* _CDVDabout)();
typedef void (CALLBACK* _CDVDnewDiskCB)(void (*callback)());
// DEV9
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _DEV9init)();
typedef s32 (CALLBACK* _DEV9open)(void *pDsp);
typedef void (CALLBACK* _DEV9close)();
typedef void (CALLBACK* _DEV9shutdown)();
typedef u8 (CALLBACK* _DEV9read8)(u32 mem);
typedef u16 (CALLBACK* _DEV9read16)(u32 mem);
typedef u32 (CALLBACK* _DEV9read32)(u32 mem);
typedef void (CALLBACK* _DEV9write8)(u32 mem, u8 value);
typedef void (CALLBACK* _DEV9write16)(u32 mem, u16 value);
typedef void (CALLBACK* _DEV9write32)(u32 mem, u32 value);
typedef void (CALLBACK* _DEV9readDMA8Mem)(u32 *pMem, int size);
typedef void (CALLBACK* _DEV9writeDMA8Mem)(u32 *pMem, int size);
typedef void (CALLBACK* _DEV9irqCallback)(DEV9callback callback);
typedef DEV9handler (CALLBACK* _DEV9irqHandler)(void);
typedef s32 (CALLBACK* _DEV9freeze)(int mode, freezeData *data);
typedef void (CALLBACK* _DEV9configure)();
typedef s32 (CALLBACK* _DEV9test)();
typedef void (CALLBACK* _DEV9about)();
// USB
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _USBinit)();
typedef s32 (CALLBACK* _USBopen)(void *pDsp);
typedef void (CALLBACK* _USBclose)();
typedef void (CALLBACK* _USBshutdown)();
typedef u8 (CALLBACK* _USBread8)(u32 mem);
typedef u16 (CALLBACK* _USBread16)(u32 mem);
typedef u32 (CALLBACK* _USBread32)(u32 mem);
typedef void (CALLBACK* _USBwrite8)(u32 mem, u8 value);
typedef void (CALLBACK* _USBwrite16)(u32 mem, u16 value);
typedef void (CALLBACK* _USBwrite32)(u32 mem, u32 value);
typedef void (CALLBACK* _USBirqCallback)(USBcallback callback);
typedef USBhandler (CALLBACK* _USBirqHandler)(void);
typedef void (CALLBACK* _USBsetRAM)(void *mem);
typedef s32 (CALLBACK* _USBfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _USBconfigure)();
typedef s32 (CALLBACK* _USBtest)();
typedef void (CALLBACK* _USBabout)();
//FW
typedef s32 (CALLBACK* _FWinit)();
typedef s32 (CALLBACK* _FWopen)(void *pDsp);
typedef void (CALLBACK* _FWclose)();
typedef void (CALLBACK* _FWshutdown)();
typedef u32 (CALLBACK* _FWread32)(u32 mem);
typedef void (CALLBACK* _FWwrite32)(u32 mem, u32 value);
typedef void (CALLBACK* _FWirqCallback)(void (*callback)());
typedef s32 (CALLBACK* _FWfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _FWconfigure)();
typedef s32 (CALLBACK* _FWtest)();
typedef void (CALLBACK* _FWabout)();
#endif
#ifdef PLUGINfuncs
// GS
_GSinit GSinit;
_GSopen GSopen;
_GSclose GSclose;
_GSshutdown GSshutdown;
_GSvsync GSvsync;
_GSgifTransfer1 GSgifTransfer1;
_GSgifTransfer2 GSgifTransfer2;
_GSgifTransfer3 GSgifTransfer3;
_GSgetLastTag GSgetLastTag;
_GSgifSoftReset GSgifSoftReset;
_GSreadFIFO GSreadFIFO;
_GSreadFIFO2 GSreadFIFO2;
_GSkeyEvent GSkeyEvent;
_GSchangeSaveState GSchangeSaveState;
_GSmakeSnapshot GSmakeSnapshot;
_GSmakeSnapshot2 GSmakeSnapshot2;
_GSirqCallback GSirqCallback;
_GSprintf GSprintf;
_GSsetBaseMem GSsetBaseMem;
_GSsetGameCRC GSsetGameCRC;
_GSsetFrameSkip GSsetFrameSkip;
_GSreset GSreset;
_GSwriteCSR GSwriteCSR;
_GSgetDriverInfo GSgetDriverInfo;
#ifdef _WIN32
_GSsetWindowInfo GSsetWindowInfo;
#endif
_GSfreeze GSfreeze;
_GSconfigure GSconfigure;
_GStest GStest;
_GSabout GSabout;
// PAD1
_PADinit PAD1init;
_PADopen PAD1open;
_PADclose PAD1close;
_PADshutdown PAD1shutdown;
_PADkeyEvent PAD1keyEvent;
_PADstartPoll PAD1startPoll;
_PADpoll PAD1poll;
_PADquery PAD1query;
_PADupdate PAD1update;
_PADgsDriverInfo PAD1gsDriverInfo;
_PADconfigure PAD1configure;
_PADtest PAD1test;
_PADabout PAD1about;
// PAD2
_PADinit PAD2init;
_PADopen PAD2open;
_PADclose PAD2close;
_PADshutdown PAD2shutdown;
_PADkeyEvent PAD2keyEvent;
_PADstartPoll PAD2startPoll;
_PADpoll PAD2poll;
_PADquery PAD2query;
_PADupdate PAD2update;
_PADgsDriverInfo PAD2gsDriverInfo;
_PADconfigure PAD2configure;
_PADtest PAD2test;
_PADabout PAD2about;
// SIO[2]
_SIOinit SIOinit[2][9];
_SIOopen SIOopen[2][9];
_SIOclose SIOclose[2][9];
_SIOshutdown SIOshutdown[2][9];
_SIOstartPoll SIOstartPoll[2][9];
_SIOpoll SIOpoll[2][9];
_SIOquery SIOquery[2][9];
_SIOconfigure SIOconfigure[2][9];
_SIOtest SIOtest[2][9];
_SIOabout SIOabout[2][9];
// SPU2
_SPU2init SPU2init;
_SPU2open SPU2open;
_SPU2close SPU2close;
_SPU2shutdown SPU2shutdown;
_SPU2write SPU2write;
_SPU2read SPU2read;
_SPU2readDMA4Mem SPU2readDMA4Mem;
_SPU2writeDMA4Mem SPU2writeDMA4Mem;
_SPU2interruptDMA4 SPU2interruptDMA4;
_SPU2readDMA7Mem SPU2readDMA7Mem;
_SPU2writeDMA7Mem SPU2writeDMA7Mem;
_SPU2setDMABaseAddr SPU2setDMABaseAddr;
_SPU2interruptDMA7 SPU2interruptDMA7;
_SPU2ReadMemAddr SPU2ReadMemAddr;
_SPU2WriteMemAddr SPU2WriteMemAddr;
_SPU2irqCallback SPU2irqCallback;
_SPU2async SPU2async;
_SPU2freeze SPU2freeze;
_SPU2configure SPU2configure;
_SPU2test SPU2test;
_SPU2about SPU2about;
// CDVD
_CDVDinit CDVDinit;
_CDVDopen CDVDopen;
_CDVDclose CDVDclose;
_CDVDshutdown CDVDshutdown;
_CDVDreadTrack CDVDreadTrack;
_CDVDgetBuffer CDVDgetBuffer;
_CDVDreadSubQ CDVDreadSubQ;
_CDVDgetTN CDVDgetTN;
_CDVDgetTD CDVDgetTD;
_CDVDgetTOC CDVDgetTOC;
_CDVDgetDiskType CDVDgetDiskType;
_CDVDgetTrayStatus CDVDgetTrayStatus;
_CDVDctrlTrayOpen CDVDctrlTrayOpen;
_CDVDctrlTrayClose CDVDctrlTrayClose;
_CDVDconfigure CDVDconfigure;
_CDVDtest CDVDtest;
_CDVDabout CDVDabout;
_CDVDnewDiskCB CDVDnewDiskCB;
// DEV9
_DEV9init DEV9init;
_DEV9open DEV9open;
_DEV9close DEV9close;
_DEV9shutdown DEV9shutdown;
_DEV9read8 DEV9read8;
_DEV9read16 DEV9read16;
_DEV9read32 DEV9read32;
_DEV9write8 DEV9write8;
_DEV9write16 DEV9write16;
_DEV9write32 DEV9write32;
_DEV9readDMA8Mem DEV9readDMA8Mem;
_DEV9writeDMA8Mem DEV9writeDMA8Mem;
_DEV9irqCallback DEV9irqCallback;
_DEV9irqHandler DEV9irqHandler;
_DEV9configure DEV9configure;
_DEV9freeze DEV9freeze;
_DEV9test DEV9test;
_DEV9about DEV9about;
// USB
_USBinit USBinit;
_USBopen USBopen;
_USBclose USBclose;
_USBshutdown USBshutdown;
_USBread8 USBread8;
_USBread16 USBread16;
_USBread32 USBread32;
_USBwrite8 USBwrite8;
_USBwrite16 USBwrite16;
_USBwrite32 USBwrite32;
_USBirqCallback USBirqCallback;
_USBirqHandler USBirqHandler;
_USBsetRAM USBsetRAM;
_USBconfigure USBconfigure;
_USBfreeze USBfreeze;
_USBtest USBtest;
_USBabout USBabout;
// FW
_FWinit FWinit;
_FWopen FWopen;
_FWclose FWclose;
_FWshutdown FWshutdown;
_FWread32 FWread32;
_FWwrite32 FWwrite32;
_FWirqCallback FWirqCallback;
_FWconfigure FWconfigure;
_FWfreeze FWfreeze;
_FWtest FWtest;
_FWabout FWabout;
#endif
#endif /* __PS2EDEFS_H__ */

View File

@ -0,0 +1,76 @@
#ifndef __PS2ETYPES_H__
#define __PS2ETYPES_H__
#ifndef ARRAYSIZE
#define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
#endif
#if defined (__linux__) && !defined(__LINUX__) // some distributions are lower case
#define __LINUX__
#endif
// Basic types
#if defined(_MSC_VER)
typedef __int8 s8;
typedef __int16 s16;
typedef __int32 s32;
typedef __int64 s64;
typedef unsigned __int8 u8;
typedef unsigned __int16 u16;
typedef unsigned __int32 u32;
typedef unsigned __int64 u64;
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#else
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
#ifdef __LINUX__
typedef union _LARGE_INTEGER
{
long long QuadPart;
} LARGE_INTEGER;
#endif
#if defined(__MINGW32__)
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#else
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
#endif
#ifndef __forceinline
#define __forceinline inline
#endif
#endif // _MSC_VER
#if defined(__x86_64__)
typedef u64 uptr;
typedef s64 sptr;
#else
typedef u32 uptr;
typedef s32 sptr;
#endif
typedef struct {
int size;
s8 *data;
} freezeData;
/* common defines */
#ifndef C_ASSERT
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#endif
#endif /* __PS2ETYPES_H__ */

View File

@ -0,0 +1,341 @@
#include "global.h"
#include "WindowsMessaging.h"
#include "VKey.h"
#include "DeviceEnumerator.h"
#include "WndProcEater.h"
#include "WindowsKeyboard.h"
#include "WindowsMouse.h"
#include "Config.h"
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
int GetRawKeyboards(HWND hWnd) {
RAWINPUTDEVICE Rid;
Rid.hwndTarget = hWnd;
Rid.dwFlags = 0;
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x06;
return pRegisterRawInputDevices(&Rid, 1, sizeof(Rid));
}
void ReleaseRawKeyboards() {
RAWINPUTDEVICE Rid;
Rid.hwndTarget = 0;
Rid.dwFlags = RIDEV_REMOVE;
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x06;
pRegisterRawInputDevices(&Rid, 1, sizeof(Rid));
}
int GetRawMice(HWND hWnd) {
RAWINPUTDEVICE Rid;
Rid.hwndTarget = hWnd;
Rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE;
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x02;
return pRegisterRawInputDevices(&Rid, 1, sizeof(Rid));
}
void ReleaseRawMice() {
RAWINPUTDEVICE Rid;
Rid.hwndTarget = 0;
Rid.dwFlags = RIDEV_REMOVE;
Rid.usUsagePage = 0x01;
Rid.usUsage = 0x02;
pRegisterRawInputDevices(&Rid, 1, sizeof(Rid));
}
// Count of active raw keyboard devices.
// when it gets to 0, release them all.
static int rawKeyboardActivatedCount = 0;
// Same for mice.
static int rawMouseActivatedCount = 0;
class RawInputKeyboard : public WindowsKeyboard {
public:
HANDLE hDevice;
RawInputKeyboard(HANDLE hDevice, wchar_t *name, wchar_t *instanceID=0) : WindowsKeyboard(RAW, name, instanceID) {
this->hDevice = hDevice;
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
}
active = 1;
if (!rawKeyboardActivatedCount++) {
if (!rawMouseActivatedCount && !EatWndProc(hWnd, RawInputWndProc)) {
Deactivate();
return 0;
}
if (!GetRawKeyboards(hWnd)) {
Deactivate();
return 0;
}
}
InitState();
return 1;
}
void Deactivate() {
FreeState();
if (active) {
active = 0;
rawKeyboardActivatedCount --;
if (!rawKeyboardActivatedCount) {
ReleaseRawKeyboards();
if (!rawMouseActivatedCount)
ReleaseExtraProc(RawInputWndProc);
}
}
}
};
static POINT rawOrigCursorPos;
static POINT rawCenter;
class RawInputMouse : public WindowsMouse {
public:
HANDLE hDevice;
RawInputMouse(HANDLE hDevice, wchar_t *name, wchar_t *instanceID=0, wchar_t *productID=0) : WindowsMouse(RAW, 0, name, instanceID, productID) {
this->hDevice = hDevice;
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
}
active = 1;
// HAve to be careful with order. At worst, one unmatched call to ReleaseRawMice on
// EatWndProc fail. In all other cases, no unmatched initialization/cleanup
// lines.
if (!rawMouseActivatedCount++) {
GetCursorPos(&rawOrigCursorPos);
ShowCursor(0);
if (!rawKeyboardActivatedCount && !EatWndProc(hWnd, RawInputWndProc)) {
Deactivate();
return 0;
}
if (!GetRawMice(hWnd)) {
Deactivate();
return 0;
}
RECT r;
// No need to clip cursor, since I seem to have complete control of buttons.
GetWindowRect(hWnd, &r);
rawCenter.x = (r.left + r.right)/2;
rawCenter.y = (r.top + r.bottom)/2;
SetCursorPos(rawCenter.x, rawCenter.y);
}
AllocState();
return 1;
}
void Deactivate() {
FreeState();
if (active) {
active = 0;
rawMouseActivatedCount --;
if (!rawMouseActivatedCount) {
ShowCursor(1);
ReleaseRawMice();
SetCursorPos(rawOrigCursorPos.x, rawOrigCursorPos.y);
if (!rawKeyboardActivatedCount) {
ReleaseExtraProc(RawInputWndProc);
}
}
}
}
/*
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
// Redundant. Should match the next line.
// Deactivate();
if (wmm) wmm->Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
}
if (GetFocus() != hWnd) return 0;
if (!EatWndProc(hWnd, WindowsMessagingWndProc)) {
Deactivate();
return 0;
}
SetCapture(hWnd);
ShowCursor(0);
GetCursorPos(&origCursorPos);
active = 1;
RECT r;
GetWindowRect(hWnd, &r);
ClipCursor(&r);
center.x = (r.left + r.right)/2;
center.y = (r.top + r.bottom)/2;
SetCursorPos(center.x, center.y);
wmm = this;
AllocState();
return 1;
}
void Deactivate() {
FreeState();
if (active) {
ClipCursor(0);
ReleaseCapture();
ShowCursor(1);
SetCursorPos(origCursorPos.x, origCursorPos.y);
if (!wmk)
ReleaseExtraProc(WindowsMessagingWndProc);
active = 0;
wmm = 0;
}
// hWndDlg = 0;
}//*/
};
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (uMsg == WM_INPUT) {
if (GET_RAWINPUT_CODE_WPARAM (wParam) == RIM_INPUT && pGetRawInputData) {
RAWINPUT in;
unsigned int size = sizeof(RAWINPUT);
if (0 < pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER))) {
for (int i=0; i<dm->numDevices; i++) {
Device *dev = dm->devices[i];
if (dev->api != RAW || !dev->active) continue;
if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD) {
RawInputKeyboard* rik = (RawInputKeyboard*)dev;
if (rik->hDevice != in.header.hDevice) continue;
u32 uMsg = in.data.keyboard.Message;
if (!(in.data.keyboard.VKey>>8))
rik->UpdateKey((u8) in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
}
else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE) {
RawInputMouse* rim = (RawInputMouse*)dev;
if (rim->hDevice != in.header.hDevice) continue;
if (in.data.mouse.usFlags) {
// Never been set for me, and specs on what most of them
// actually mean is sorely lacking. Also, specs erroneously
// indicate MOUSE_MOVE_RELATIVE is a flag, when it's really
// 0...
continue;
}
unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF;
int button = 0;
while (buttons) {
if (buttons & 3) {
// 2 is up, 1 is down. Up takes precedence over down.
rim->UpdateButton(button, !(buttons & 2));
}
button++;
buttons >>= 2;
}
if (in.data.mouse.usButtonFlags & 0x400) {
rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData)/WHEEL_DELTA);
}
if (in.data.mouse.lLastX || in.data.mouse.lLastY) {
rim->UpdateAxis(0, in.data.mouse.lLastX);
rim->UpdateAxis(1, in.data.mouse.lLastY);
SetCursorPos(rawCenter.x, rawCenter.y);
}
}
}
}
}
}
else if (uMsg == WM_ACTIVATE) {
for (int i=0; i<dm->numDevices; i++) {
Device *dev = dm->devices[i];
if (dev->api != RAW || dev->physicalControlState == 0) continue;
memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls);
}
}
return CONTINUE_BLISSFULLY;
}
void EnumRawInputDevices() {
UINT count = 0;
if (pGetRawInputDeviceList && pGetRawInputDeviceList(0, &count, sizeof(RAWINPUTDEVICELIST)) != (UINT)-1) {
wchar_t *instanceID = (wchar_t *) malloc(41000*sizeof(wchar_t));
wchar_t *keyName = instanceID + 11000;
wchar_t *displayName = keyName + 10000;
wchar_t *productID = displayName + 10000;
int keyboardCount = 1;
int mouseCount = 1;
if (count) {
RAWINPUTDEVICELIST *list = (RAWINPUTDEVICELIST*) malloc(sizeof(RAWINPUTDEVICELIST) * count);
if (list && pGetRawInputDeviceList(list, &count, sizeof(RAWINPUTDEVICELIST))) {
for (UINT i=0; i<count; i++) {
UINT nameLen = 10000;
if (pGetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &nameLen) &&
nameLen >= 3) {
wcscpy(productID, instanceID);
wchar_t *temp = 0;
for (int j=0; j<3; j++) {
wchar_t *s = wcschr(productID, '#');
if (!s) break;
*s = '\\';
if (j==2) {
*s = 0;
}
if (j==1) temp = s;
}
wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID+3);
if (temp) *temp = 0;
displayName[0] = 0;
HKEY hKey;
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey)) {
DWORD type;
DWORD len = 10000 * sizeof(wchar_t);
if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE*)displayName, &len) &&
len && type == REG_SZ) {
wchar_t *temp2 = wcsrchr(displayName, ';');
if (!temp2) temp2 = displayName;
else temp2++;
// Could do without this, but more effort than it's worth.
wcscpy(keyName, temp2);
}
RegCloseKey(hKey);
}
if (list[i].dwType == RIM_TYPEKEYBOARD) {
if (!displayName[0]) wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
else wsprintfW(displayName, L"Raw KB: %s", keyName);
dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID));
}
else if (list[i].dwType == RIM_TYPEMOUSE) {
if (!displayName[0]) wsprintfW(displayName, L"Raw Mouse %i", mouseCount++);
else wsprintfW(displayName, L"Raw MS: %s", keyName);
dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID));
}
}
}
free(list);
}
}
free(instanceID);
dm->AddDevice(new RawInputKeyboard(0, L"Simulated Keyboard"));
dm->AddDevice(new RawInputMouse(0, L"Simulated Mouse"));
}
}

View File

@ -0,0 +1,5 @@
#include "InputManager.h"
// Can't enumerate raw devices, can only detect them when
// receiving data from them, so just use the list from before.
void EnumRawInputDevices();

224
plugins/LilyPad/VKey.cpp Normal file
View File

@ -0,0 +1,224 @@
//#include "global.h"
#include "VKey.h"
char *GetMouseString(unsigned char button) {
switch(button) {
case 0x01: return "Left button";
case 0x02: return "Right button";
case 0x03: return "Middle button";
case 0x04: return "Button 4";
case 0x05: return "Button 5";
case 0x06: return "X-axis";
case 0x07: return "Y-axis";
case 0x08: return "Wheel";
case 0x09: return "Wheel 2";
default:
break;
}
static char t[8];
sprintf(t, "%i", button);
return t;
}
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC 0
#endif
wchar_t *GetVKStringW(unsigned char vk) {
int flag;
static wchar_t t[20];
/*
for (int i=0x90; i<0xFF; i++) {
int res = MapVirtualKey(i, MAPVK_VK_TO_VSC);
static char t[20] ={0};
static char t2[20] ={0};
if (res && (GetKeyNameText((res<<16) + (0<<24), t, 20) || GetKeyNameText((res<<16) + (0<<24), t2, 20))) {
t[19] = 0;
}
}//*/
//char *s1, *s2;
switch(vk) {
//case 0x01: return L"Left button";
//case 0x02: return L"Right button";
//case 0x03: return "Control-break";
//case 0x04: return L"Middle button";
//case 0x08: return "Backspace";
//case 0x09: return "Tab";
case 0x0C: return L"Clear";
//case 0x0D: return "Enter";
//case 0x10: return "Shift";
//case 0x11: return "Ctrl";
//case 0x12: return "Alt";
case 0x13: return L"Pause";
//case 0x14: return "Caps Lock";
//case 0x1B: return "Esc";
//case 0x20: return "Space";
case 0x21:// return "Page Up";
case 0x22:// return "Page Down";
case 0x23:// return "End";
case 0x24:// return "Home";
case 0x25:// return "Left";
case 0x26:// return "Up";
case 0x27:// return "Right";
case 0x28:// return "Down";
case 0x2D:// return "Insert";
case 0x2E:// return "Delete";
case 0x5B:// return "Left Windows";
case 0x5C:// return "Right Windows";
case 0x5D:// return "Application";
case 0x6F:// return "Num /";
flag = 1<<24;
break;
case 0x29: return L"Select";
case 0x2A: return L"Print";
case 0x2B: return L"Execute";
case 0x2C: return L"Prnt Scrn";
case 0x2F: return L"Help";
/*
case 0x30: return "0";
case 0x31: return "1";
case 0x32: return "2";
case 0x33: return "3";
case 0x34: return "4";
case 0x35: return "5";
case 0x36: return "6";
case 0x37: return "7";
case 0x38: return "8";
case 0x39: return "9";
case 0x41: return "A";
case 0x42: return "B";
case 0x43: return "C";
case 0x44: return "D";
case 0x45: return "E";
case 0x46: return "F";
case 0x47: return "G";
case 0x48: return "H";
case 0x49: return "I";
case 0x4A: return "J";
case 0x4B: return "K";
case 0x4C: return "L";
case 0x4D: return "M";
case 0x4E: return "N";
case 0x4F: return "O";
case 0x50: return "P";
case 0x51: return "Q";
case 0x52: return "R";
case 0x53: return "S";
case 0x54: return "T";
case 0x55: return "U";
case 0x56: return "V";
case 0x57: return "W";
case 0x58: return "X";
case 0x59: return "Y";
case 0x5A: return "Z";
//*/
/*
case 0x60: return "Num 0";
case 0x61: return "Num 1";
case 0x62: return "Num 2";
case 0x63: return "Num 3";
case 0x64: return "Num 4";
case 0x65: return "Num 5";
case 0x66: return "Num 6";
case 0x67: return "Num 7";
case 0x68: return "Num 8";
case 0x69: return "Num 9";
//*/
//case 0x6A: return "Num Mul";
//case 0x6B: return "Num Add";
case 0x6C: return L"|";
//case 0x6D: return "Num Sub";
//case 0x6E: return "Num Del";
/*
case 0x70: return "F1";
case 0x71: return "F2";
case 0x72: return "F3";
case 0x73: return "F4";
case 0x74: return "F5";
case 0x75: return "F6";
case 0x76: return "F7";
case 0x77: return "F8";
case 0x78: return "F9";
case 0x79: return "F10";
case 0x7A: return "F11";
case 0x7B: return "F12";
case 0x7C: return "F13";
case 0x7D: return "F14";
case 0x7E: return "F15";
case 0x7F: return "F16";
case 0x80: return "F17";
case 0x81: return "F18";
case 0x82: return "F19";
case 0x83: return "F20";
case 0x84: return "F21";
case 0x85: return "F22";
case 0x86: return "F23";
case 0x87: return "F24";
//*/
//case VK_EQUALS: return "=";
case 0x90: return L"Num Lock";
//case 0x91: return "Scroll Lock";
/*
case 0xA0:
case 0xA1:
s2 = "Shift";
goto skip;
case 0xA2:
case 0xA3:
s2 = "Ctrl";
goto skip;
case 0xA4:
case 0xA5:
s2 = "Alt";
skip:
s1 = "Left";
if (vk&1) s1 = "Right";
sprintf(t, "%s %s", s1, s2);
return t;
/*/
case 0xA0: return L"Left Shift";
case 0xA1: return L"Right Shift";
case 0xA2: return L"Left Ctrl";
case 0xA3: return L"Right Ctrl";
case 0xA4: return L"Left Alt";
case 0xA5: return L"Right Alt";
//*/
case 0xA6: return L"Back";
case 0xA7: return L"Forward";
case 0xA8: return L"Refresh";
case 0xA9: return L"Stop";
case 0xAA: return L"Search";
case 0xAB: return L"Favorites";
case 0xAC: return L"Browser";
//case 0xBA: return ":";
//case 0xBB: return "=";
//case 0xBC: return ",";
//case 0xBD: return "-";
//case 0xBE: return ".";
//case 0xBF: return "/";
//case 0xC0: return "`";
//case 0xDB: return "[";
//case 0xDC: return "\\";
//case 0xDD: return "]";
//case 0xDE: return "'";
//case 0xE2: return "\\";
case 0xFA: return L"Play";
case 0xFB: return L"Zoom";
default:
flag = 0;
break;
}
int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
if (res && GetKeyNameText((res<<16) | flag, t, 20)) {
// don't trust windows
t[19] = 0;
}
else {
wsprintfW(t, L"Key %i", vk);
}
return t;
}

4
plugins/LilyPad/VKey.h Normal file
View File

@ -0,0 +1,4 @@
#include "global.h"
char *GetMouseString(unsigned char button);
wchar_t *GetVKStringW(unsigned char vk);

View File

@ -0,0 +1,38 @@
#include "global.h"
#include "VKey.h"
#include "WindowsKeyboard.h"
#include "KeyboardQueue.h"
WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) :
Device(api, KEYBOARD, displayName, instanceID, deviceID) {
for (int i=0; i<256; i++) {
AddPhysicalControl(PSHBTN, i, i);
}
}
wchar_t *WindowsKeyboard::GetPhysicalControlName(PhysicalControl *control) {
int id = control->id;
if (control->type == PSHBTN && id >= 0 && id < 256) {
wchar_t *w = GetVKStringW(id);
if (w) return w;
}
return Device::GetPhysicalControlName(control);
}
void WindowsKeyboard::UpdateKey(int vkey, int state) {
if (vkey > 4 && vkey < 256) {
physicalControlState[vkey] = (state << 16);
}
}
void WindowsKeyboard::InitState() {
AllocState();
for (int vkey=5; vkey<256; vkey++) {
int value = (unsigned short)(((short)GetAsyncKeyState(vkey))>>15);
value += value&1;
if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT) {
value = 0;
}
physicalControlState[vkey] = value;
}
}

View File

@ -0,0 +1,13 @@
#include "Global.h"
#include "InputManager.h"
// Shared functionality for WM and RAW keyboards.
class WindowsKeyboard : public Device {
public:
WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID=0, wchar_t *deviceID=0);
wchar_t *GetPhysicalControlName(PhysicalControl *control);
void UpdateKey(int vkey, int state);
// Calls AllocState() and initializes to current keyboard state using
// GetAsyncKeyState().
void InitState();
};

View File

@ -0,0 +1,191 @@
#include "global.h"
#include "WindowsMessaging.h"
#include "VKey.h"
#include "DeviceEnumerator.h"
#include "WndProcEater.h"
#include "WindowsKeyboard.h"
#include "WindowsMouse.h"
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
class WindowsMessagingKeyboard;
class WindowsMessagingMouse;
static WindowsMessagingKeyboard *wmk = 0;
static WindowsMessagingMouse *wmm = 0;
class WindowsMessagingKeyboard : public WindowsKeyboard {
public:
WindowsMessagingKeyboard() : WindowsKeyboard(WM, L"WM Keyboard") {
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
// Redundant. Should match the next line.
// Deactivate();
if (wmk) wmk->Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
// hWndDlg = info->hWnd;
}
if (!wmm && !EatWndProc(hWnd, WindowsMessagingWndProc)) {
Deactivate();
return 0;
}
wmk = this;
InitState();
active = 1;
return 1;
}
void Deactivate() {
FreeState();
if (active) {
if (!wmm)
ReleaseExtraProc(WindowsMessagingWndProc);
active = 0;
wmk = 0;
}
// hWndDlg = 0;
}
void CheckKey(int vkey) {
UpdateKey(vkey, 1&(((unsigned short)GetAsyncKeyState(vkey))>>15));
}
};
class WindowsMessagingMouse : public WindowsMouse {
public:
WindowsMessagingMouse() : WindowsMouse(WM, 1, L"WM Mouse") {
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
// Redundant. Should match the next line.
// Deactivate();
if (wmm) wmm->Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
}
if (!wmk && !EatWndProc(hWnd, WindowsMessagingWndProc)) {
Deactivate();
return 0;
}
SetCapture(hWnd);
ShowCursor(0);
GetCursorPos(&origCursorPos);
active = 1;
RECT r;
GetWindowRect(hWnd, &r);
ClipCursor(&r);
center.x = (r.left + r.right)/2;
center.y = (r.top + r.bottom)/2;
SetCursorPos(center.x, center.y);
wmm = this;
AllocState();
return 1;
}
void Deactivate() {
FreeState();
if (active) {
ClipCursor(0);
ReleaseCapture();
ShowCursor(1);
SetCursorPos(origCursorPos.x, origCursorPos.y);
if (!wmk)
ReleaseExtraProc(WindowsMessagingWndProc);
active = 0;
wmm = 0;
}
}
};
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (wmk) {
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) {
if (wParam == VK_SHIFT) {
wmk->CheckKey(VK_RSHIFT);
wmk->CheckKey(VK_LSHIFT);
}
else if (wParam == VK_CONTROL) {
wmk->CheckKey(VK_RCONTROL);
wmk->CheckKey(VK_LCONTROL);
}
else if (wParam == VK_MENU) {
wmk->CheckKey(VK_RMENU);
wmk->CheckKey(VK_LMENU);
}
else
wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
return NO_WND_PROC;
}
// Needed to prevent default handling of keys in some situations.
else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) {
return NO_WND_PROC;
}
else if (uMsg == WM_ACTIVATE) {
memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls);
}
}
if (wmm) {
if (uMsg == WM_MOUSEMOVE) {
POINT p;
GetCursorPos(&p);
// Need check to prevent cursor movement cascade.
if (p.x != wmm->center.x || p.y != wmm->center.y) {
wmm->UpdateAxis(0, p.x - wmm->center.x);
wmm->UpdateAxis(1, p.y - wmm->center.y);
SetCursorPos(wmm->center.x, wmm->center.y);
}
return NO_WND_PROC;
}
else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) {
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) {
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) {
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) {
wmm->UpdateButton(3+((wParam>>16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEWHEEL) {
wmm->UpdateAxis(2, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEHWHEEL) {
wmm->UpdateAxis(3, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
/*
else if (uMsg == WM_KILLFOCUS) {
wmm->Deactivate();
}//*/
}
return CONTINUE_BLISSFULLY;
}
void EnumWindowsMessagingDevices() {
dm->AddDevice(new WindowsMessagingKeyboard());
dm->AddDevice(new WindowsMessagingMouse());
}

View File

@ -0,0 +1,3 @@
#include "InputManager.h"
void EnumWindowsMessagingDevices();

View File

@ -0,0 +1,44 @@
#include "global.h"
#include "VKey.h"
#include "WindowsMouse.h"
WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) :
Device(api, MOUSE, displayName, instanceID, deviceID) {
int i;
for (i=0; i<5; i++) {
AddPhysicalControl(PSHBTN, i, i);
}
for (i=0; i<3+hWheel; i++) {
AddPhysicalControl(RELAXIS, i+5, i+5);
}
}
wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control) {
wchar_t *names[9] = {
L"L Button",
L"R Button",
L"M Button",
L"Mouse 4",
L"Mouse 5",
L"X Axis",
L"Y Axis",
L"Y Wheel",
L"X Wheel"
};
if (control->id < 9) return names[control->id];
return Device::GetPhysicalControlName(control);
}
void WindowsMouse::UpdateButton(unsigned int button, int state) {
if (button > 4) return;
physicalControlState[button] = (state << 16);
}
void WindowsMouse::UpdateAxis(unsigned int axis, int delta) {
if (axis > 3) return;
// 1 mouse pixel = 1/8th way down.
physicalControlState[5+axis] += (delta<<(16 - 3*(axis < 2)));
}

View File

@ -0,0 +1,19 @@
#include "Global.h"
#include "InputManager.h"
// Shared functionality for WM and RAW keyboards.
class WindowsMouse : public Device {
public:
POINT origCursorPos;
POINT center;
// hWheel variable lets me display no horizontal wheel for raw input, just to make it clear
// that it's not supported.
WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID=0, wchar_t *deviceID=0);
wchar_t *GetPhysicalControlName(PhysicalControl *control);
// State is 0 for up, 1 for down.
void UpdateButton(unsigned int button, int state);
// 0/1 are x/y. 2 is vert wheel, 3 is horiz wheel.
// Delta is in my micro units. change of (1<<16) is 1 full unit, with
// the default sensitivity.
void UpdateAxis(unsigned int axis, int delta);
};

View File

@ -0,0 +1,71 @@
#include "WndProcEater.h"
static HWND hWndEaten = 0;
static WNDPROC eatenWndProc = 0;
static ExtraWndProc* extraProcs = 0;
static int numExtraProcs = 0;
void ReleaseExtraProc(ExtraWndProc proc) {
for (int i=0; i<numExtraProcs; i++) {
if (extraProcs[i] == proc) {
extraProcs[i] = extraProcs[--numExtraProcs];
break;
}
}
if (!numExtraProcs && eatenWndProc) {
free(extraProcs);
extraProcs = 0;
if (hWndEaten && IsWindow(hWndEaten)) {
SetWindowLongPtr(hWndEaten, GWLP_WNDPROC, (LONG_PTR)eatenWndProc);
}
hWndEaten = 0;
eatenWndProc = 0;
}
}
void ReleaseEatenProc() {
while (numExtraProcs) ReleaseExtraProc(extraProcs[0]);
}
LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
ExtraWndProcResult res = CONTINUE_BLISSFULLY;
LRESULT out = 0;
// Here because want it for binding, even when no keyboard mode is selected.
if (uMsg == WM_GETDLGCODE) {
return DLGC_WANTALLKEYS | CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
}
for (int i=0; i<numExtraProcs; i++) {
ExtraWndProcResult res2 = extraProcs[i](hWnd, uMsg, wParam, lParam, &out);
if (res2 != res) {
if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC) {
ReleaseExtraProc(extraProcs[i]);
i--;
}
else if (res2 > res) res = res2;
}
}
if (res != NO_WND_PROC) {
if (out == WM_DESTROY) {
ReleaseEatenProc();
}
if (res == CONTINUE_BLISSFULLY)
out = CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
else if (res == USE_DEFAULT_WND_PROC)
out = DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return out;
}
int EatWndProc(HWND hWnd, ExtraWndProc proc) {
if (hWnd != hWndEaten) {
ReleaseEatenProc();
eatenWndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)OverrideWndProc);
// ???
if (!eatenWndProc) return 0;
hWndEaten = hWnd;
}
extraProcs = (ExtraWndProc*) realloc(extraProcs, sizeof(ExtraWndProc)*(numExtraProcs+1));
extraProcs[numExtraProcs++] = proc;
return 1;
}

View File

@ -0,0 +1,18 @@
#include "Global.h"
/* Need this to let window be subclassed multiple times but still clean up nicely.
*/
enum ExtraWndProcResult {
CONTINUE_BLISSFULLY,
// Calls ReleaseExtraProc without messing up order.
CONTINUE_BLISSFULLY_AND_RELEASE_PROC,
USE_DEFAULT_WND_PROC,
NO_WND_PROC
};
typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *out);
int EatWndProc(HWND hWnd, ExtraWndProc proc);
void ReleaseExtraProc(ExtraWndProc proc);
void ReleaseEatenProc();

214
plugins/LilyPad/XInput.cpp Normal file
View File

@ -0,0 +1,214 @@
#include "global.h"
#include "VKey.h"
#include "DirectInput.h"
#include <xinput.h>
#include "InputManager.h"
#include "DeviceEnumerator.h"
// This way, I don't require that XInput junk be installed.
typedef void (CALLBACK *_XInputEnable)(BOOL enable);
typedef DWORD (CALLBACK *_XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState);
typedef DWORD (CALLBACK *_XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration);
_XInputEnable pXInputEnable = 0;
_XInputGetState pXInputGetState = 0;
_XInputSetState pXInputSetState = 0;
static int xInputActiveCount = 0;
// Completely unncessary, really.
__forceinline int ShortToAxis(int v) {
// If positive and at least 1 << 14, increment.
v += (!((v>>15)&1)) & ((v>>14)&1);
// Not just double.
return v << 1;
}
class XInputDevice : public Device {
// Cached last vibration values by pad and motor.
// Need this, as only one value is changed at a time.
int ps2Vibration[2][2];
// Minor optimization - cache last set vibration values
// When there's no change, no need to do anything.
XINPUT_VIBRATION xInputVibration;
public:
int index;
XInputDevice(int index, wchar_t *displayName) : Device(XINPUT, OTHER, displayName) {
memset(ps2Vibration, 0, sizeof(ps2Vibration));
memset(&xInputVibration, 0, sizeof(xInputVibration));
this->index = index;
int i;
for (i=0; i<16; i++) {
// The i > 9 accounts for the 2 bit skip in button flags.
AddPhysicalControl(PSHBTN, i + 2*(i > 9), 0);
}
for (; i<20; i++) {
// The i > 9 accounts for the 2 bit skip in button flags.
AddPhysicalControl(ABSAXIS, i + 2*(i > 9), 0);
}
AddFFAxis(L"Slow Motor", 0);
AddFFAxis(L"Fast Motor", 1);
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
}
wchar_t *GetPhysicalControlName(PhysicalControl *c) {
const static wchar_t *names[] = {
L"D-pad Up",
L"D-pad Down",
L"D-pad Left",
L"D-pad Right",
L"Start",
L"Back",
L"Left Thumb",
L"Right Thumb",
L"Left Shoulder",
L"Right Shoulder",
L"A",
L"B",
L"X",
L"Y",
L"Left Trigger",
L"Right Trigger",
L"Left Thumb X",
L"Left Thumb Y",
L"Right Thumb X",
L"Right Thumb Y",
};
unsigned int i = (unsigned int) (c - physicalControls);
if (i < 20) {
return (wchar_t*)names[i];
}
return Device::GetPhysicalControlName(c);
}
int Activate(void *d) {
if (active) Deactivate();
if (!xInputActiveCount) {
pXInputEnable(1);
}
xInputActiveCount++;
active = 1;
AllocState();
return 1;
}
int Update() {
if (!active) return 0;
XINPUT_STATE state;
// memset(&state, 0, sizeof(state));
if (ERROR_SUCCESS != pXInputGetState(index, &state)) {
Deactivate();
return 0;
}
int buttons = state.Gamepad.wButtons;
for (int i=0; i<14; i++) {
physicalControlState[i] = ((buttons >> physicalControls[i].id)&1)<<16;
}
physicalControlState[14] = (((int)state.Gamepad.bLeftTrigger) + (state.Gamepad.bLeftTrigger>>7)) << 8;
physicalControlState[15] = (((int)state.Gamepad.bRightTrigger) + (state.Gamepad.bRightTrigger>>7)) << 8;
/*
state.Gamepad.sThumbLX = 0x8000;
state.Gamepad.sThumbLY = 0x7FFF;
state.Gamepad.sThumbRX = 0x3FFF;
state.Gamepad.sThumbRY = 0;
/*/
physicalControlState[16] = ShortToAxis(state.Gamepad.sThumbLX);
physicalControlState[17] = ShortToAxis(state.Gamepad.sThumbLY);
physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbRX);
physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRY);
return 1;
}
void SetEffects(unsigned char pad, unsigned char motor, unsigned char force) {
ps2Vibration[pad][motor] = force;
int newVibration[2] = {0,0};
for (int p=0; p<2; p++) {
for (int i=0; i<pads[p].numFFBindings; i++) {
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
newVibration[0] += (int)((pads[p].ffBindings[i].axes[0].force * (__int64)ps2Vibration[p][pads[p].ffBindings[i].motor]) / 255);
newVibration[1] += (int)((pads[p].ffBindings[i].axes[1].force * (__int64)ps2Vibration[p][pads[p].ffBindings[i].motor]) / 255);
}
}
newVibration[0] = abs(newVibration[0]);
if (newVibration[0] > 65535) {
newVibration[0] = 65535;
}
newVibration[1] = abs(newVibration[1]);
if (newVibration[1] > 65535) {
newVibration[1] = 65535;
}
if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed) {
XINPUT_VIBRATION newv = {newVibration[0], newVibration[1]};
if (ERROR_SUCCESS == pXInputSetState(index, &newv)) {
xInputVibration = newv;
}
}
}
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {
PadBindings p[2];
p[0] = pads[0];
p[1] = pads[1];
pads[0].ffBindings = binding;
pads[0].numFFBindings = 1;
pads[1].numFFBindings = 0;
SetEffects(0, binding->motor, 255);
pads[0] = p[0];
pads[1] = p[1];
}
void Deactivate() {
if (xInputVibration.wLeftMotorSpeed || xInputVibration.wRightMotorSpeed) {
memset(&xInputVibration, 0, sizeof(xInputVibration));
pXInputSetState(index, &xInputVibration);
}
memset(ps2Vibration, 0, sizeof(ps2Vibration));
FreeState();
if (active) {
if (!--xInputActiveCount) {
pXInputEnable(0);
}
active = 0;
}
}
~XInputDevice() {
}
};
void EnumXInputDevices() {
int i;
wchar_t temp[30];
if (!pXInputSetState) {
// Also used as flag to indicute XInput not installed, so
// don't repeatedly try to load it.
if (pXInputEnable) return;
HMODULE hMod = 0;
for (i=3; i>= 0; i--) {
wsprintfW(temp, L"xinput1_%i.dll", i);
if (hMod = LoadLibraryW(temp)) break;
}
if (hMod) {
if ((pXInputEnable = (_XInputEnable) GetProcAddress(hMod, "XInputEnable")) &&
(pXInputGetState = (_XInputGetState) GetProcAddress(hMod, "XInputGetState"))) {
pXInputSetState = (_XInputSetState) GetProcAddress(hMod, "XInputSetState");
}
}
if (!pXInputSetState) {
pXInputEnable = (_XInputEnable)-1;
return;
}
}
pXInputEnable(1);
for (i=0; i<4; i++) {
XINPUT_STATE state;
if (ERROR_SUCCESS == pXInputGetState(i, &state)) {
wsprintfW(temp, L"XInput Pad %i", i);
dm->AddDevice(new XInputDevice(i, temp));
}
}
pXInputEnable(0);
}

3
plugins/LilyPad/XInput.h Normal file
View File

@ -0,0 +1,3 @@
#include "InputManager.h"
void EnumXInputDevices();

BIN
plugins/LilyPad/frog.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

158
plugins/LilyPad/resource.h Normal file
View File

@ -0,0 +1,158 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by LilyPad.rc
//
#define IDD_GENERAL 102
#define IDD_ABOUT 103
#define IDI_FROG 104
#define IDD_CONFIG 105
#define IDD_CONFIG_GUITAR 106
#define IDD_PROPPAGE_LARGE 107
#define IDC_CURSOR1 107
#define IDC_ESCAPE_FULLSCREEN_HACK 107
#define IDD_DIAG 109
#define IDC_CLOSE_HACK1 1099
#define IDC_KB_DISABLE 1100
#define IDC_KB_DI 1101
#define IDC_KB_WM 1102
#define IDC_KB_RAW 1103
#define IDC_DISABLE_PAD1 1104
#define IDC_DISABLE_PAD2 1105
#define IDC_M_DISABLE 1106
#define IDC_M_DI 1107
#define IDC_M_WM 1108
#define IDC_M_RAW 1109
#define IDC_G_XI 1110
#define IDC_G_DI 1111
#define IDC_CLOSE_HACK2 1112
#define IDC_CLOSE_HACK3 1113
#define IDC_DEBUG_FILE 1114
#define IDC_GUITAR1 1115
#define IDC_GUITAR2 1116
#define IDC_ANALOG_START1 1117
#define IDC_ANALOG_START2 1118
#define IDC_DISABLE_SCREENSAVER 1119
#define IDC_MOUSE_UNFOCUS 1120
#define IDC_MOUSE_UNFOCUS2 1121
#define IDC_AXIS_BUTTONS 1121
#define IDC_BACKGROUND 1122
#define IDC_MULTIPLE_BINDING 1123
#define IDC_DISABLE_SCREENSAVER2 1124
#define IDC_FORCE_HIDE 1124
#define IDC_FORCE_HIDE2 1125
#define IDC_GH2_HACK 1125
#define IDC_FORCEFEEDBACK_HACK1 1126
#define IDC_DISABLE_SCREENSAVER4 1127
#define IDC_FORCEFEEDBACK_HACK2 1127
#define IDC_GS_THREAD_INPUT 1128
#define IDC_SLIDER1 0x1000
#define IDC_FLIP1 0x1001
#define IDC_AXIS1 0x1002
#define IDC_AXIS_CONTROL1 0x1003
#define IDC_AXIS_SENSITIVITY1 0x1004
#define IDC_TURBO 0x1005
#define IDC_AXIS_DEVICE1 0x1006
#define ID_SENSITIVITY 0x1007
#define ID_DPAD 0x1008
#define ID_LSTICK 0x1009
#define ID_RSTICK 0x100A
#define ID_GUITAR_HERO 0x10FB
#define ID_LOCK_BUTTONS 0x10FC
#define ID_LOCK 0x10FD
#define ID_LOCK_DIRECTION 0x10FE
#define ID_MOUSE 0x10FF
#define ID_SELECT 0x1100
#define ID_L3 0x1101
#define ID_R3 0x1102
#define ID_START 0x1103
#define ID_DPAD_UP 0x1104
#define ID_DPAD_RIGHT 0x1105
#define ID_DPAD_DOWN 0x1106
#define ID_DPAD_LEFT 0x1107
#define ID_L2 0x1108
#define ID_R2 0x1109
#define ID_L1 0x110A
#define ID_R1 0x110B
#define ID_TRIANGLE 0x110C
#define ID_CIRCLE 0x110D
#define ID_CROSS 0x110E
#define ID_SQUARE 0x110F
#define ID_LSTICK_UP 0x1110
#define ID_LSTICK_RIGHT 0x1111
#define ID_LSTICK_DOWN 0x1112
#define ID_LSTICK_LEFT 0x1113
#define ID_RSTICK_UP 0x1114
#define ID_RSTICK_RIGHT 0x1115
#define ID_RSTICK_DOWN 0x1116
#define ID_RSTICK_LEFT 0x1117
#define ID_ANALOG 0x1118
#define ID_DPAD_LRAXIS 0x1120
#define ID_DPAD_UDAXIS 0x1121
#define ID_LSTICK_LRAXIS 0x1122
#define ID_LSTICK_UDAXIS 0x1123
#define ID_RSTICK_LRAXIS 0x1124
#define ID_RSTICK_UDAXIS 0x1125
#define ID_L1R1 0x1126
#define ID_L2R2 0x1127
#define ID_L3R3 0x1128
#define ID_DELETE 0x11FF
#define ID_DEBUG 0x1200
#define ID_IGNORE 0x1201
#define ID_CLEAR 0x1202
#define ID_REFRESH 0x1202
#define ID_SAVE 0x1204
#define ID_LOAD 0x1205
#define IDC_LIST 0x1207
#define IDC_FORCEFEEDBACK 0x1208
#define IDC_FORCEFEEDBACK_FUNCTION 0x1209
#define ID_BIG_MOTOR 0x120A
#define ID_SMALL_MOTOR 0x120B
#define ID_TEST 0x1300
#define ID_CONTROLS 0x1301
#define IDC_FF_DEVICE 0x1302
#define IDC_FF_MOTOR 0x1303
#define ID_FF 0x1304
#define IDC_FF_EFFECT 0x1305
#define IDC_FF_AXIS1_ENABLED 0x1310
#define IDC_FF_AXIS1 0x1311
#define IDC_FF_AXIS1_FLIP 0x1312
#define IDC_FF_AXIS1_SCALE 0x1313
#define IDC_FF_AXIS2_ENABLED 0x1320
#define IDC_FF_AXIS2 0x1321
#define IDC_FF_AXIS2_FLIP 0x1322
#define IDC_FF_AXIS2_SCALE 0x1323
#define IDC_FF_AXIS3_ENABLED 0x1330
#define IDC_FF_AXIS3 0x1331
#define IDC_FF_AXIS3_FLIP 0x1332
#define IDC_FF_AXIS3_SCALE 0x1333
#define IDC_FF_AXIS4_ENABLED 0x1340
#define IDC_FF_AXIS4 0x1341
#define IDC_FF_AXIS4_FLIP 0x1342
#define IDC_FF_AXIS4_SCALE 0x1343
#define IDC_FF_AXIS5_ENABLED 0x1350
#define IDC_FF_AXIS5 0x1351
#define IDC_FF_AXIS5_FLIP 0x1352
#define IDC_FF_AXIS5_SCALE 0x1353
#define IDC_FF_AXIS6_ENABLED 0x1360
#define IDC_FF_AXIS6 0x1361
#define IDC_FF_AXIS6_FLIP 0x1362
#define IDC_FF_AXIS6_SCALE 0x1363
#define IDC_FF_AXIS7_ENABLED 0x1370
#define IDC_FF_AXIS7 0x1371
#define IDC_FF_AXIS7_FLIP 0x1372
#define IDC_FF_AXIS7_SCALE 0x1373
#define IDC_FF_AXIS8_ENABLED 0x1380
#define IDC_FF_AXIS8 0x1381
#define IDC_FF_AXIS8_FLIP 0x1382
#define IDC_FF_AXIS8_SCALE 0x1383
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 112
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1127
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif