Merge pull request #288 from pinumbernumber/master

Add XInput support (and misc fixes)
This commit is contained in:
Hans-Kristian Arntzen 2013-08-26 09:20:49 -07:00
commit f08c8cc5c2
8 changed files with 438 additions and 14 deletions

View File

@ -44,7 +44,8 @@ JOBJ := conf/config_file.o \
compat/compat.o \
file_path.o \
tools/input_common_joyconfig.o \
input/dinput.o
input/dinput.o \
input/winxinput_joypad.o
CC = gcc
CXX = g++
@ -63,6 +64,8 @@ HAVE_THREADS = 1
HAVE_RGUI = 1
DYNAMIC = 1
HAVE_WINXINPUT = 1
ifeq ($(SLIM),)
HAVE_SDL = 1
HAVE_SDL_IMAGE = 1
@ -212,6 +215,11 @@ ifeq ($(HAVE_PYTHON), 1)
OBJ += gfx/py_state/py_state.o
endif
ifeq ($(HAVE_WINXINPUT), 1)
DEFINES += -DHAVE_WINXINPUT
OBJ += input/winxinput_joypad.o
endif
ifeq ($(HAVE_DINPUT), 1)
LIBS += -ldinput8 -ldxguid -lole32
DEFINES += -DHAVE_DINPUT

View File

@ -36,11 +36,12 @@ static const frontend_ctx_driver_t *frontend_ctx_drivers[] = {
#if defined(IOS) || defined(OSX)
&frontend_ctx_apple,
#endif
NULL // zero length array is not valid
};
const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident)
{
for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++)
for (unsigned i = 0; frontend_ctx_drivers[i]; i++)
{
if (strcmp(frontend_ctx_drivers[i]->ident, ident) == 0)
return frontend_ctx_drivers[i];
@ -51,7 +52,7 @@ const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident)
const frontend_ctx_driver_t *frontend_ctx_init_first(void)
{
for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++)
for (unsigned i = 0; frontend_ctx_drivers[i]; i++)
return frontend_ctx_drivers[i];
return NULL;

View File

@ -68,12 +68,6 @@ static bool dinput_init_context(void)
if (g_ctx)
return true;
if (driver.display_type != RARCH_DISPLAY_WIN32)
{
RARCH_ERR("Cannot open DInput as no Win32 window is present.\n");
return false;
}
CoInitialize(NULL);
// Who said we shouldn't have same call signature in a COM API? <_<
@ -386,6 +380,36 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p)
return DIENUM_CONTINUE;
}
static const char* const XBOX_PAD_NAMES[] =
{
"Controller (Gamepad for Xbox 360)",
"Controller (XBOX 360 For Windows)",
"Controller (Xbox 360 Wireless Receiver for Windows)",
"Controller (Xbox wireless receiver for windows)",
"XBOX 360 For Windows (Controller)",
"Xbox 360 Wireless Receiver",
"Xbox Receiver for Windows (Wireless Controller)",
"Xbox wireless receiver for windows (Controller)",
NULL
};
static bool name_is_360_pad(const char* name)
{
for (unsigned i = 0; ; ++i)
{
const char* t = XBOX_PAD_NAMES[i];
if (t == NULL)
return false;
else if (lstrcmpi(name, t) == 0)
return true;
}
}
// Keep track of which pad indexes are 360 controllers
// not static, will be read in winxinput_joypad.c
// -1 = not xbox pad, otherwise 0..3
int g_xbox_pad_indexes[MAX_PLAYERS];
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
{
(void)p;
@ -399,7 +423,18 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
#else
if (FAILED(IDirectInput8_CreateDevice(g_ctx, &inst->guidInstance, pad, NULL)))
#endif
return DIENUM_CONTINUE;
return DIENUM_CONTINUE;
#ifdef HAVE_WINXINPUT
int last_xbox_pad_index = 0;
if (name_is_360_pad(inst->tszProductName))
{
if (last_xbox_pad_index < 4)
g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index;
++last_xbox_pad_index;
}
#endif
IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2);
IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver.video_window,
@ -417,6 +452,9 @@ static bool dinput_joypad_init(void)
{
if (!dinput_init_context())
return false;
for (unsigned i = 0; i < MAX_PLAYERS; ++i)
g_xbox_pad_indexes[i] = -1;
RARCH_LOG("Enumerating DInput joypads ...\n");
IDirectInput8_EnumDevices(g_ctx, DI8DEVCLASS_GAMECTRL,

View File

@ -41,6 +41,9 @@
static const rarch_joypad_driver_t *joypad_drivers[] = {
#ifndef IS_RETROLAUNCH
#ifdef HAVE_WINXINPUT
&winxinput_joypad,
#endif
#ifdef HAVE_DINPUT
&dinput_joypad,
#endif

View File

@ -93,6 +93,7 @@ const char *input_joypad_name(const rarch_joypad_driver_t *driver, unsigned joyp
extern const rarch_joypad_driver_t dinput_joypad;
extern const rarch_joypad_driver_t linuxraw_joypad;
extern const rarch_joypad_driver_t winxinput_joypad; // Named as such to avoid confusion with xb1/360 port code
extern const rarch_joypad_driver_t sdl_joypad;

351
input/winxinput_joypad.c Normal file
View File

@ -0,0 +1,351 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2013 - pinumbernumber
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
// Support 360 controllers on Windows.
// Said controllers do show under DInput but they have limitations in this mode;
// The triggers are combined rather than seperate and it is not possible to use
// the guide button.
// Some wrappers for other controllers also simulate xinput (as it is easier to implement)
// so this may be useful for those also.
#include "input_common.h"
#include "../general.h"
#include "../boolean.h"
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
// Check the definitions do not already exist.
// Official and mingw xinput headers have different include guards
#if ((!_XINPUT_H_) && (!__WINE_XINPUT_H))
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#define XINPUT_GAMEPAD_START 0x0010
#define XINPUT_GAMEPAD_BACK 0x0020
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#define XINPUT_GAMEPAD_A 0x1000
#define XINPUT_GAMEPAD_B 0x2000
#define XINPUT_GAMEPAD_X 0x4000
#define XINPUT_GAMEPAD_Y 0x8000
typedef struct
{
uint16_t wButtons;
uint8_t bLeftTrigger;
uint8_t bRightTrigger;
int16_t sThumbLX;
int16_t sThumbLY;
int16_t sThumbRX;
int16_t sThumbRY;
} XINPUT_GAMEPAD;
typedef struct
{
uint32_t dwPacketNumber;
XINPUT_GAMEPAD Gamepad;
} XINPUT_STATE;
#endif
// Guide constant is not officially documented
#define XINPUT_GAMEPAD_GUIDE 0x0400
#ifndef ERROR_DEVICE_NOT_CONNECTED
#define ERROR_DEVICE_NOT_CONNECTED 1167
#endif
#ifndef HAVE_DINPUT
#error Cannot compile xinput without dinput.
#endif
// Due to 360 pads showing up under both XI and DI, and since we are going
// to have to pass through unhandled joypad numbers to DI, a slightly ugly
// hack is required here. dinput_joypad_init will fill this.
// For each pad index, the appropriate entry will be set to -1 if it is not
// a 360 pad, or the correct XInput player number (0..3 inclusive) if it is.
extern int g_xbox_pad_indexes[MAX_PLAYERS];
// For xinput1_3.dll
static HINSTANCE g_winxinput_dll;
// Function pointer, to be assigned with GetProcAddress
typedef uint32_t (__stdcall *XInputGetStateEx_t)(uint32_t, XINPUT_STATE*);
static XInputGetStateEx_t g_XInputGetStateEx;
// Guide button may or may not be available
static bool g_winxinput_guide_button_supported;
typedef struct
{
XINPUT_STATE xstate;
bool connected;
} winxinput_joypad_state;
static winxinput_joypad_state g_winxinput_states[4];
static int pad_index_to_xplayer_index(unsigned pad)
{
return g_xbox_pad_indexes[pad];
}
static bool winxinput_joypad_init(void)
{
g_winxinput_dll = NULL;
// Find the correct path to load the DLL from.
// Usually this will be from the system directory,
// but occasionally a user may wish to use a third-party
// wrapper DLL (such as x360ce); support these by checking
// the working directory first.
// No need to check for existance as we will be checking LoadLibrary's
// success anyway.
const char* DLL_NAME = "xinput1_3.dll";
g_winxinput_dll = LoadLibrary(DLL_NAME); // Using dylib_* complicates building joyconfig.
if (!g_winxinput_dll)
{
// Loading from working dir failed, try to load from system.
char dll_path[MAX_PATH];
GetSystemDirectory(dll_path, sizeof(dll_path));
strlcat(dll_path, "\\", 1);
strlcat(dll_path, DLL_NAME, sizeof(DLL_NAME));
g_winxinput_dll = LoadLibrary(dll_path);
if (!g_winxinput_dll)
{
RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n");
return false; // DLL does not exist or is invalid
}
}
// If we get here then an xinput DLL is correctly loaded.
// First try to load ordinal 100 (XInputGetStateEx).
g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (const char*)100);
g_winxinput_guide_button_supported = true;
if (!g_XInputGetStateEx)
{
// no ordinal 100. (old version of x360ce perhaps?) Load the ordinary XInputGetState,
// at the cost of losing guide button support.
g_winxinput_guide_button_supported = false;
g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState");
if (!g_XInputGetStateEx)
{
RARCH_ERR("Failed to init XInput: xinput1_3.dll is invalid or corrupt.\n");
return false; // DLL was loaded but did not contain the correct function.
}
RARCH_WARN("XInput: No guide button support.\n");
}
// zero out the states
for (unsigned i = 0; i < 4; ++i)
memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state));
// Do a dummy poll to check which controllers are connected.
XINPUT_STATE dummy_state;
for (unsigned i = 0; i < 4; ++i)
{
g_winxinput_states[i].connected = !(g_XInputGetStateEx(i, &dummy_state) == ERROR_DEVICE_NOT_CONNECTED);
if (g_winxinput_states[i].connected)
RARCH_LOG("Found XInput controller, player #%u\n", i);
}
if ((!g_winxinput_states[0].connected) &&
(!g_winxinput_states[1].connected) &&
(!g_winxinput_states[2].connected) &&
(!g_winxinput_states[3].connected))
return false;
// We're going to have to be buddies with dinput if we want to be able
// to use XI and non-XI controllers together.
return dinput_joypad.init();
}
static bool winxinput_joypad_query_pad(unsigned pad)
{
int xplayer = pad_index_to_xplayer_index(pad);
if (xplayer > -1)
return g_winxinput_states[0].connected;
else
return dinput_joypad.query_pad(pad);
}
static void winxinput_joypad_destroy(void)
{
for (unsigned i = 0; i < 4; ++i)
memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state));
FreeLibrary(g_winxinput_dll);
g_winxinput_dll = NULL;
g_XInputGetStateEx = NULL;
dinput_joypad.destroy();
}
// Buttons are provided by XInput as bits of a uint16.
// Map from rarch button index (0..10) to a mask to bitwise-& the buttons against.
// dpad is handled seperately.
static const uint16_t button_index_to_bitmap_code[] = {
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
XINPUT_GAMEPAD_GUIDE
};
static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey)
{
if (joykey == NO_BTN)
return false;
int xplayer = pad_index_to_xplayer_index(port_num);
if (xplayer == -1)
return dinput_joypad.button(port_num, joykey);
if (!(g_winxinput_states[xplayer].connected))
return false;
uint16_t btn_word = g_winxinput_states[xplayer].xstate.Gamepad.wButtons;
if (GET_HAT_DIR(joykey))
{
switch (GET_HAT_DIR(joykey))
{
case HAT_UP_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_UP;
case HAT_DOWN_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_DOWN;
case HAT_LEFT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_LEFT;
case HAT_RIGHT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_RIGHT;
}
return false; // hat requested and no hat button down
}
else
{
// non-hat button
unsigned num_buttons = g_winxinput_guide_button_supported ? 11 : 10;
if (joykey < num_buttons)
return btn_word & button_index_to_bitmap_code[joykey];
}
return false;
}
static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis)
{
if (joyaxis == AXIS_NONE)
return 0;
int xplayer = pad_index_to_xplayer_index(port_num);
if (xplayer == -1)
return dinput_joypad.axis(port_num, joyaxis);
if (!(g_winxinput_states[xplayer].connected))
return false;
int16_t val = 0;
int axis = -1;
bool is_neg = false;
bool is_pos = false;
if (AXIS_NEG_GET(joyaxis) <= 3) // triggers (axes 4,5) cannot be negative
{
axis = AXIS_NEG_GET(joyaxis);
is_neg = true;
}
else if (AXIS_POS_GET(joyaxis) <= 5)
{
axis = AXIS_POS_GET(joyaxis);
is_pos = true;
}
XINPUT_GAMEPAD* pad = &(g_winxinput_states[xplayer].xstate.Gamepad);
switch (axis)
{
case 0: val = pad->sThumbLX; break;
case 1: val = pad->sThumbLY; break;
case 2: val = pad->sThumbRX; break;
case 3: val = pad->sThumbRY; break;
case 4: val = pad->bLeftTrigger * 32767 / 255; break; // map 0..255 to 0..32767
case 5: val = pad->bRightTrigger * 32767 / 255; break;
}
if (is_neg && val > 0)
val = 0;
else if (is_pos && val < 0)
val = 0;
// Clamp to avoid overflow error
if (val == -32768)
val = -32767;
return val;
}
static void winxinput_joypad_poll(void)
{
for (unsigned i = 0; i < 4; ++i)
if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED)
g_winxinput_states[i].connected = false;
dinput_joypad.poll();
}
static const char* const XBOX_CONTROLLER_NAMES[4] =
{
"Xbox 360 Controller (Player 1)",
"Xbox 360 Controller (Player 2)",
"Xbox 360 Controller (Player 3)",
"Xbox 360 Controller (Player 4)"
};
const char* winxinput_joypad_name (unsigned pad)
{
int xplayer = pad_index_to_xplayer_index(pad);
if (xplayer < 0)
return dinput_joypad.name(pad);
else
// TODO: Different name if disconnected?
return XBOX_CONTROLLER_NAMES[xplayer];
}
const rarch_joypad_driver_t winxinput_joypad = {
winxinput_joypad_init,
winxinput_joypad_query_pad,
winxinput_joypad_destroy,
winxinput_joypad_button,
winxinput_joypad_axis,
winxinput_joypad_poll,
winxinput_joypad_name,
"winxinput",
};

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2010", "RetroArch-msvc2010.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -88,7 +88,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<CompileAs>CompileAsCpp</CompileAs>
@ -108,7 +108,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<CompileAs>CompileAsCpp</CompileAs>
@ -130,7 +130,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<CompileAs>CompileAsCpp</CompileAs>
@ -154,7 +154,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<CompileAs>CompileAsCpp</CompileAs>
@ -250,6 +250,8 @@
</ClCompile>
<ClCompile Include="..\..\input\dinput.c">
</ClCompile>
<ClCompile Include="..\..\input\winxinput_joypad.c">
</ClCompile>
<ClCompile Include="..\..\input\input_common.c">
</ClCompile>
<ClCompile Include="..\..\message.c">