From af633c794179d29a4bf0c01983c8b08d14553596 Mon Sep 17 00:00:00 2001 From: hondres Date: Fri, 18 Dec 2015 06:12:53 +0100 Subject: Better gamepad support --- platform/windows/SCsub | 1 + platform/windows/detect.py | 4 +- platform/windows/joystick.cpp | 528 ++++++++++++++++++++++++++++++++++++++++ platform/windows/joystick.h | 139 +++++++++++ platform/windows/os_windows.cpp | 268 +------------------- platform/windows/os_windows.h | 41 +--- 6 files changed, 682 insertions(+), 299 deletions(-) create mode 100644 platform/windows/joystick.cpp create mode 100644 platform/windows/joystick.h (limited to 'platform/windows') diff --git a/platform/windows/SCsub b/platform/windows/SCsub index f98c1b01ff..2db3d0f51e 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -9,6 +9,7 @@ common_win=[ "tcp_server_winsock.cpp", "packet_peer_udp_winsock.cpp", "stream_peer_winsock.cpp", + "joystick.cpp", ] restarget="godot_res"+env["OBJSUFFIX"] diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 3193a2acbb..a1366e7630 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -243,7 +243,7 @@ def configure(env): env.Append(CCFLAGS=['/DGLES2_ENABLED']) env.Append(CCFLAGS=['/DGLEW_ENABLED']) - LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI','Shlwapi', 'wsock32', 'shell32','advapi32'] + LIBS=['winmm','opengl32','dsound','kernel32','ole32','oleaut32','user32','gdi32', 'IPHLPAPI','Shlwapi', 'wsock32', 'shell32','advapi32','dinput8','dxguid'] env.Append(LINKFLAGS=[p+env["LIBSUFFIX"] for p in LIBS]) env.Append(LIBPATH=[os.getenv("WindowsSdkDir")+"/Lib"]) @@ -369,7 +369,7 @@ def configure(env): env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows']) env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED']) env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED']) - env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','shlwapi','wsock32','kernel32']) + env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','shlwapi','wsock32','kernel32', 'oleaut32', 'dinput8', 'dxguid']) # if (env["bits"]=="32"): # env.Append(LIBS=['gcc_s']) diff --git a/platform/windows/joystick.cpp b/platform/windows/joystick.cpp new file mode 100644 index 0000000000..32620c7779 --- /dev/null +++ b/platform/windows/joystick.cpp @@ -0,0 +1,528 @@ +/*************************************************************************/ +/* joystick.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +//author: Andreas Haas +#include "joystick.h" +#include +#include +#include + +#ifndef __GNUC__ +#define __builtin_bswap32 _byteswap_ulong +#endif + +DWORD WINAPI _xinput_get_state(DWORD dwUserIndex, XINPUT_STATE* pState) { return ERROR_DEVICE_NOT_CONNECTED; } + +joystick_windows::joystick_windows() { + +} + +joystick_windows::joystick_windows(InputDefault* _input, HWND* hwnd) { + + input = _input; + hWnd = hwnd; + joystick_count = 0; + dinput = NULL; + xinput_dll = NULL; + xinput_get_state = NULL; + + load_xinput(); + + for (int i = 0; i < JOYSTICKS_MAX; i++) + attached_joysticks[i] = false; + + + HRESULT result; + result = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dinput, NULL); + if (FAILED(result)) { + printf("failed init DINPUT: %ld\n", result); + } + probe_joysticks(); +} + +joystick_windows::~joystick_windows() { + + close_joystick(); + dinput->Release(); + unload_xinput(); +} + + +bool joystick_windows::have_device(const GUID &p_guid) { + + for (int i = 0; i < JOYSTICKS_MAX; i++) { + + if (d_joysticks[i].guid == p_guid) { + + d_joysticks[i].confirmed = true; + return true; + } + } + return false; +} + +int joystick_windows::check_free_joy_slot() const { + + for (int i = 0; i < JOYSTICKS_MAX; i++) { + + if (!attached_joysticks[i]) + return i; + } + return -1; +} + + +// adapted from SDL2, works a lot better than the MSDN version +bool joystick_windows::is_xinput_device(const GUID *p_guid) { + + PRAWINPUTDEVICELIST dev_list = NULL; + unsigned int dev_list_count = 0; + + if (GetRawInputDeviceList(NULL, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == -1) { + return false; + } + dev_list = (PRAWINPUTDEVICELIST) malloc(sizeof(RAWINPUTDEVICELIST) * dev_list_count); + if (!dev_list) return false; + + if (GetRawInputDeviceList(dev_list, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == -1) { + free(dev_list); + return false; + } + for (int i = 0; i < dev_list_count; i++) { + + RID_DEVICE_INFO rdi; + char dev_name[128]; + UINT rdiSize = sizeof(rdi); + UINT nameSize = sizeof(dev_name); + + rdi.cbSize = rdiSize; + if ( (dev_list[i].dwType == RIM_TYPEHID) && + (GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1) && + (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == (LONG)p_guid->Data1) && + (GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, &dev_name, &nameSize) != (UINT)-1) && + (strstr(dev_name, "IG_") != NULL)) { + + free(dev_list); + return true; + } + } + free(dev_list); + return false; +} + +bool joystick_windows::setup_dinput_joystick(const DIDEVICEINSTANCE* instance) { + + HRESULT hr; + int num = check_free_joy_slot(); + + if (have_device(instance->guidInstance) || num == -1) + return false; + + d_joysticks[joystick_count] = dinput_gamepad(); + dinput_gamepad* joy = &d_joysticks[num]; + + const DWORD devtype = (instance->dwDevType & 0xFF); + + if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) { + //printf("ignore device %s, type %x\n", instance->tszProductName, devtype); + return false; + } + + hr = dinput->CreateDevice(instance->guidInstance, &joy->di_joy, NULL); + + if (FAILED(hr)) { + + //std::wcout << "failed to create device: " << instance->tszProductName << std::endl; + return false; + } + + const GUID &guid = instance->guidProduct; + char uid[128]; + sprintf(uid, "%08lx%04hx%04hx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + __builtin_bswap32(guid.Data1), guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + + id_to_change = num; + joy->di_joy->SetDataFormat(&c_dfDIJoystick2); + joy->di_joy->SetCooperativeLevel(*hWnd, DISCL_FOREGROUND); + joy->di_joy->EnumObjects(objectsCallback, this, NULL); + joy->joy_axis.sort(); + + joy->guid = instance->guidInstance; + input->joy_connection_changed(num, true, instance->tszProductName, uid); + joy->attached = true; + joy->id = num; + attached_joysticks[num] = true; + joy->confirmed = true; + joystick_count++; + return true; +} + +void joystick_windows::setup_joystick_object(const DIDEVICEOBJECTINSTANCE *ob, int p_joy_id) { + + if (ob->dwType & DIDFT_AXIS) { + + HRESULT res; + DIPROPRANGE prop_range; + DIPROPDWORD dilong; + DWORD ofs; + if (ob->guidType == GUID_XAxis) + ofs = DIJOFS_X; + else if (ob->guidType == GUID_YAxis) + ofs = DIJOFS_Y; + else if (ob->guidType == GUID_ZAxis) + ofs = DIJOFS_Z; + else if (ob->guidType == GUID_RxAxis) + ofs = DIJOFS_RX; + else if (ob->guidType == GUID_RyAxis) + ofs = DIJOFS_RY; + else if (ob->guidType == GUID_RzAxis) + ofs = DIJOFS_RZ; + else if (ob->guidType == GUID_Slider) + ofs = DIJOFS_SLIDER(0); + else + return; + prop_range.diph.dwSize = sizeof(DIPROPRANGE); + prop_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); + prop_range.diph.dwObj = ob->dwType; + prop_range.diph.dwHow = DIPH_BYID; + prop_range.lMin = -MAX_JOY_AXIS; + prop_range.lMax = +MAX_JOY_AXIS; + + dinput_gamepad &joy = d_joysticks[p_joy_id]; + + + res = joy.di_joy->SetProperty(DIPROP_RANGE, &prop_range.diph); + if (FAILED(res)) + return; + + dilong.diph.dwSize = sizeof(dilong); + dilong.diph.dwHeaderSize = sizeof(dilong.diph); + dilong.diph.dwObj = ob->dwType; + dilong.diph.dwHow = DIPH_BYID; + dilong.dwData = 0; + + res = IDirectInputDevice8_SetProperty(joy.di_joy, DIPROP_DEADZONE, &dilong.diph); + if (FAILED(res)) + return; + + joy.joy_axis.push_back(ofs); + } +} + +BOOL CALLBACK joystick_windows::enumCallback(const DIDEVICEINSTANCE* instance, void* pContext) { + + + joystick_windows* self = (joystick_windows*)pContext; + if (self->is_xinput_device(&instance->guidProduct)) {; + return DIENUM_CONTINUE; + } + self->setup_dinput_joystick(instance); + return DIENUM_CONTINUE; +} + +BOOL CALLBACK joystick_windows::objectsCallback(const DIDEVICEOBJECTINSTANCE *instance, void *context) { + + joystick_windows* self = (joystick_windows*)context; + self->setup_joystick_object(instance, self->id_to_change); + + return DIENUM_CONTINUE; +} + +void joystick_windows::close_joystick(int id) { + + if (id == -1) { + + for (int i = 0; i < JOYSTICKS_MAX; i++) { + + close_joystick(i); + } + return; + } + + if (!d_joysticks[id].attached) return; + + d_joysticks[id].di_joy->Unacquire(); + d_joysticks[id].di_joy->Release(); + d_joysticks[id].attached = false; + attached_joysticks[d_joysticks[id].id] = false; + d_joysticks[id].guid.Data1 = d_joysticks[id].guid.Data2 = d_joysticks[id].guid.Data3 = 0; + input->joy_connection_changed(id, false, ""); + joystick_count--; +} + +void joystick_windows::probe_joysticks() { + + DWORD dwResult; + for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { + + ZeroMemory(&x_joysticks[i].state, sizeof(XINPUT_STATE)); + + dwResult = xinput_get_state(i, &x_joysticks[i].state); + if ( dwResult == ERROR_SUCCESS) { + + int id = check_free_joy_slot(); + if (id != -1 && !x_joysticks[i].attached) { + + x_joysticks[i].attached = true; + x_joysticks[i].id = id; + attached_joysticks[id] = true; + input->joy_connection_changed(id, true, "XInput Gamepad","__XINPUT_DEVICE__"); + } + } + else if (x_joysticks[i].attached) { + + x_joysticks[i].attached = false; + attached_joysticks[x_joysticks[i].id] = false; + input->joy_connection_changed(x_joysticks[i].id, false, ""); + } + } + + for (int i = 0; i < joystick_count; i++) { + + d_joysticks[i].confirmed = false; + } + + dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, this, DIEDFL_ATTACHEDONLY); + + for (int i = 0; i < joystick_count; i++) { + + if (!d_joysticks[i].confirmed) { + + close_joystick(i); + } + } +} + +unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { + + HRESULT hr; + + for (int i = 0; i < XUSER_MAX_COUNT; i++) { + + xinput_gamepad &joy = x_joysticks[i]; + if (!joy.attached) { + continue; + } + ZeroMemory(&joy.state, sizeof(XINPUT_STATE)); + + xinput_get_state(i, &joy.state); + if (joy.state.dwPacketNumber != joy.last_packet) { + + int button_mask = XINPUT_GAMEPAD_DPAD_UP; + for (int i = 0; i <= 16; i++) { + + p_last_id = input->joy_button(p_last_id, joy.id, i, joy.state.Gamepad.wButtons & button_mask); + button_mask = button_mask * 2; + } + + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); + joy.last_packet = joy.state.dwPacketNumber; + } + } + + for (int i = 0; i < JOYSTICKS_MAX; i++) { + + dinput_gamepad* joy = &d_joysticks[i]; + + if (!joy->attached) + continue; + + DIJOYSTATE2 js; + hr = joy->di_joy->Poll(); + if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joy->di_joy); + joy->di_joy->Poll(); + } + if (FAILED(hr = d_joysticks[i].di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js))) { + + //printf("failed to read joy #%d\n", i); + continue; + } + + p_last_id = post_hat(p_last_id, i, js.rgdwPOV[0]); + + for (int j = 0; j < 128; j++) { + + if (js.rgbButtons[j] & 0x80) { + + if (!joy->last_buttons[j]) { + + p_last_id = input->joy_button(p_last_id, i, j, true); + joy->last_buttons[j] = true; + } + } + else { + + if (joy->last_buttons[j]) { + + p_last_id = input->joy_button(p_last_id, i, j, false); + joy->last_buttons[j] = false; + } + } + } + + // on mingw, these constants are not constants + int count = 6; + int axes[] = { DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ }; + int values[] = { js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz }; + + for (int j = 0; j < joy->joy_axis.size(); j++) { + + for (int k=0; kjoy_axis[j] == axes[k]) { + p_last_id = input->joy_axis(p_last_id, i, j, axis_correct(values[k])); + break; + }; + }; + }; + } + return p_last_id; +} + +unsigned int joystick_windows::post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad) { + + int dpad_val = 0; + + if (p_dpad == -1) { + dpad_val = InputDefault::HAT_MASK_CENTER; + } + if (p_dpad == 0) { + + dpad_val = InputDefault::HAT_MASK_UP; + + } + else if (p_dpad == 4500) { + + dpad_val = (InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_RIGHT); + + } + else if (p_dpad == 9000) { + + dpad_val = InputDefault::HAT_MASK_RIGHT; + + } + else if (p_dpad == 13500) { + + dpad_val = (InputDefault::HAT_MASK_RIGHT | InputDefault::HAT_MASK_DOWN); + + } + else if (p_dpad == 18000) { + + dpad_val = InputDefault::HAT_MASK_DOWN; + + } + else if (p_dpad == 22500) { + + dpad_val = (InputDefault::HAT_MASK_DOWN | InputDefault::HAT_MASK_LEFT); + + } + else if (p_dpad == 27000) { + + dpad_val = InputDefault::HAT_MASK_LEFT; + + } + else if (p_dpad == 31500) { + + dpad_val = (InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_UP); + } + return input->joy_hat(p_last_id, p_device, dpad_val); +}; + +InputDefault::JoyAxis joystick_windows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { + + InputDefault::JoyAxis jx; + if (Math::abs(p_val) < MIN_JOY_AXIS) { + jx.min = -1; + jx.value = 0.0f; + return jx; + } + if (p_xinput) { + + if (p_trigger) { + jx.min = 0; + jx.value = (float)p_val / MAX_TRIGGER; + return jx; + } + jx.min = -1; + if (p_val < 0) { + jx.value = (float)p_val / MAX_JOY_AXIS; + } + else { + jx.value = (float)p_val / (MAX_JOY_AXIS - 1); + } + if (p_negate) { + jx.value = -jx.value; + } + return jx; + } + jx.min = -1; + jx.value = (float)p_val / MAX_JOY_AXIS; + return jx; +} + +void joystick_windows::load_xinput() { + + xinput_get_state = &_xinput_get_state; + xinput_dll = LoadLibrary( "XInput1_4.dll" ); + if (!xinput_dll) { + xinput_dll = LoadLibrary("XInput1_3.dll"); + if (!xinput_dll) { + xinput_dll = LoadLibrary("XInput9_1_0.dll"); + } + } + + if (!xinput_dll) { + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("Could not find XInput, using DirectInput only"); + } + return; + } + + XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputGetState"); + if (!func) { + unload_xinput(); + return; + } + xinput_get_state = func; + return; +} + +void joystick_windows::unload_xinput() { + + if (xinput_dll) { + + FreeLibrary((HMODULE)xinput_dll); + } +} diff --git a/platform/windows/joystick.h b/platform/windows/joystick.h new file mode 100644 index 0000000000..d0d85cd2c9 --- /dev/null +++ b/platform/windows/joystick.h @@ -0,0 +1,139 @@ +/*************************************************************************/ +/* joystick.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +//author: Andreas Haas +#ifndef JOYSTICK_H +#define JOYSTICK_H + +#include "os_windows.h" +#define DIRECTINPUT_VERSION 0x0800 +#include +#include // on unix the file is called "xinput.h", on windows I'm sure it won't mind + +#ifndef SAFE_RELEASE // when Windows Media Device M? is not present +#define SAFE_RELEASE(x) \ +if(x != NULL) \ +{ \ + x->Release(); \ + x = NULL; \ +} +#endif + + +class joystick_windows +{ +public: + joystick_windows(); + joystick_windows(InputDefault* _input, HWND* hwnd); + ~joystick_windows(); + + void probe_joysticks(); + unsigned int process_joysticks(unsigned int p_last_id); +private: + + enum { + JOYSTICKS_MAX = 16, + JOY_AXIS_COUNT = 6, + MIN_JOY_AXIS = 10, + MAX_JOY_AXIS = 32768, + MAX_JOY_BUTTONS = 128, + KEY_EVENT_BUFFER_SIZE = 512, + MAX_TRIGGER = 255 + }; + + struct dinput_gamepad { + + int id; + bool attached; + bool confirmed; + bool last_buttons[MAX_JOY_BUTTONS]; + DWORD last_pad; + + LPDIRECTINPUTDEVICE8 di_joy; + List joy_axis; + GUID guid; + + dinput_gamepad() { + id = -1; + last_pad = -1; + attached = false; + confirmed = false; + + for (int i = 0; i < MAX_JOY_BUTTONS; i++) + last_buttons[i] = false; + } + }; + + struct xinput_gamepad { + + int id; + bool attached; + DWORD last_packet; + XINPUT_STATE state; + + xinput_gamepad() { + attached = false; + last_packet = 0; + } + }; + + typedef DWORD (WINAPI *XInputGetState_t) (DWORD dwUserIndex, XINPUT_STATE* pState); + + HWND* hWnd; + HANDLE xinput_dll; + LPDIRECTINPUT8 dinput; + InputDefault* input; + + int id_to_change; + int joystick_count; + bool attached_joysticks[JOYSTICKS_MAX]; + dinput_gamepad d_joysticks[JOYSTICKS_MAX]; + xinput_gamepad x_joysticks[XUSER_MAX_COUNT]; + + static BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* p_instance, void* p_context); + static BOOL CALLBACK objectsCallback(const DIDEVICEOBJECTINSTANCE* instance, void* context); + + void setup_joystick_object(const DIDEVICEOBJECTINSTANCE* ob, int p_joy_id); + void close_joystick(int id = -1); + void load_xinput(); + void unload_xinput(); + + int check_free_joy_slot() const; + unsigned int post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad); + + bool have_device(const GUID &p_guid); + bool is_xinput_device(const GUID* p_guid); + bool setup_dinput_joystick(const DIDEVICEINSTANCE* instance); + + InputDefault::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; + XInputGetState_t xinput_get_state; +}; + +#endif + + diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 49ce1d3b9a..1eef643579 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -52,6 +52,7 @@ #include "os/memory_pool_dynamic_prealloc.h" #include "globals.h" #include "io/marshalls.h" +#include "joystick.h" #include "shlobj.h" #include @@ -682,6 +683,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { } break; #endif + case WM_DEVICECHANGE: { + + joystick->probe_joysticks(); + } break; default: { @@ -706,108 +711,6 @@ LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { } - -String OS_Windows::get_joystick_name(int id, JOYCAPS jcaps) -{ - char buffer [256]; - char OEM [256]; - HKEY hKey; - DWORD sz; - int res; - - _snprintf(buffer, sizeof(buffer), "%s\\%s\\%s", - REGSTR_PATH_JOYCONFIG, jcaps.szRegKey, - REGSTR_KEY_JOYCURR ); - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); - if (res != ERROR_SUCCESS) - { - res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey); - if (res != ERROR_SUCCESS) - return ""; - } - - sz = sizeof(OEM); - _snprintf( buffer, sizeof(buffer), "Joystick%d%s", id + 1, REGSTR_VAL_JOYOEMNAME); - res = RegQueryValueEx ( hKey, buffer, 0, 0, (LPBYTE) OEM, &sz); - RegCloseKey ( hKey ); - if (res != ERROR_SUCCESS) - return ""; - - _snprintf( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEM); - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); - if (res != ERROR_SUCCESS) - { - res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey); - if (res != ERROR_SUCCESS) - return ""; - } - - - sz = sizeof(buffer); - res = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buffer, - &sz); - RegCloseKey(hKey); - if (res != ERROR_SUCCESS) - return ""; - - return String(buffer); -} - -void OS_Windows::probe_joysticks() { - - static uint32_t last_attached = 0; - - int device_count = joyGetNumDevs(); - - JOYINFOEX jinfo; - jinfo.dwSize = sizeof(JOYINFOEX); - jinfo.dwFlags = JOY_RETURNALL; - - for (int i=0; i 0) && (joyGetPosEx(JOYSTICKID1 + i, &jinfo) == JOYERR_NOERROR); - - if (joy.attached == (last_attached & (1 << i) != 0)) { - continue; - }; - - // there's been a change since last call - - if (joy.attached) - last_attached = last_attached | (1 << i); - else - last_attached &= ~(1 << i); - - if (joy.attached) { - - joy.last_buttons = jinfo.dwButtons; - - joy.last_axis[0] = jinfo.dwXpos; - joy.last_axis[1] = jinfo.dwYpos; - joy.last_axis[2] = jinfo.dwZpos; - joy.last_axis[3] = jinfo.dwRpos; - joy.last_axis[4] = jinfo.dwUpos; - joy.last_axis[5] = jinfo.dwVpos; - - JOYCAPS jcaps; - MMRESULT res = joyGetDevCaps(JOYSTICKID1 + i, &jcaps, sizeof(jcaps)); - if (res == JOYERR_NOERROR) { - String name = get_joystick_name(JOYSTICKID1 + i, jcaps); - if ( name == "") - joy.name = jcaps.szPname; - else - joy.name = name; - - - }; - }; - - joystick_change_queue.push_back(joy); - }; -}; - void OS_Windows::process_key_events() { for(int i=0;iparse_input_event(ievent); - - } else if (p_dpad == 4500) { - - ievent.joy_button.button_index = JOY_DPAD_UP; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - ievent.joy_button.button_index = JOY_DPAD_RIGHT; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - } else if (p_dpad == 9000) { - - ievent.joy_button.button_index = JOY_DPAD_RIGHT; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - } else if (p_dpad == 13500) { - - ievent.joy_button.button_index = JOY_DPAD_RIGHT; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - ievent.joy_button.button_index = JOY_DPAD_DOWN; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - } else if (p_dpad == 18000) { - - ievent.joy_button.button_index = JOY_DPAD_DOWN; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - } else if (p_dpad == 22500) { - - ievent.joy_button.button_index = JOY_DPAD_DOWN; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - ievent.joy_button.button_index = JOY_DPAD_LEFT; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - } else if (p_dpad == 27000) { - - ievent.joy_button.button_index = JOY_DPAD_LEFT; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - } else if (p_dpad == 31500) { - - ievent.joy_button.button_index = JOY_DPAD_LEFT; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - - ievent.joy_button.button_index = JOY_DPAD_UP; - ievent.ID = ++last_id; - input->parse_input_event(ievent); - }; -}; - -void OS_Windows::process_joysticks() { - - if (!main_loop) { - return; - }; - - InputEvent ievent; - - JOYINFOEX jinfo; - jinfo.dwSize = sizeof(JOYINFOEX); - jinfo.dwFlags = JOY_RETURNALL; - - for (int i=0; iparse_input_event(ievent);\ - }; - - CHECK_AXIS(0, jinfo.dwXpos); - CHECK_AXIS(1, jinfo.dwYpos); - CHECK_AXIS(2, jinfo.dwZpos); - CHECK_AXIS(3, jinfo.dwRpos); - CHECK_AXIS(4, jinfo.dwUpos); - CHECK_AXIS(5, jinfo.dwVpos); - - if (joysticks[i].last_pov != jinfo.dwPOV) { - - if (joysticks[i].last_pov != JOY_POVCENTERED) - _post_dpad(joysticks[i].last_pov, i, false); - - if (jinfo.dwPOV != JOY_POVCENTERED) - _post_dpad(jinfo.dwPOV, i, true); - - joysticks[i].last_pov = jinfo.dwPOV; - }; - - if (joysticks[i].last_buttons == jinfo.dwButtons) { - continue; - }; - - ievent.type = InputEvent::JOYSTICK_BUTTON; - for (int j=0; j<32; j++) { - - if ( (joysticks[i].last_buttons & (1<parse_input_event(ievent); - }; - }; - - joysticks[i].last_buttons = jinfo.dwButtons; - }; -}; - - BOOL CALLBACK OS_Windows::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { OS_Windows *self=(OS_Windows*)OS::get_singleton(); MonitorInfo minfo; @@ -1213,6 +968,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_ visual_server->init(); input = memnew( InputDefault ); + joystick = memnew (joystick_windows(input, &hWnd)); AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); @@ -1231,14 +987,6 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_ spatial_sound_2d_server = memnew( SpatialSound2DServerSW ); spatial_sound_2d_server->init(); - probe_joysticks(); // todo: move this to a thread - while (joystick_change_queue.size() > 0) { - Joystick joy = joystick_change_queue.front()->get(); - joystick_change_queue.pop_front(); - joysticks[joy.id] = joy; - input->joy_connection_changed(joy.id, joy.attached, joy.name); - }; - TRACKMOUSEEVENT tme; tme.cbSize=sizeof(TRACKMOUSEEVENT); tme.dwFlags=TME_LEAVE; @@ -1351,6 +1099,7 @@ void OS_Windows::finalize() { main_loop=NULL; + memdelete(joystick); memdelete(input); visual_server->finish(); @@ -1386,7 +1135,6 @@ void OS_Windows::finalize() { physics_2d_server->finish(); memdelete(physics_2d_server); - joystick_change_queue.clear(); monitor_info.clear(); } @@ -1967,7 +1715,7 @@ void OS_Windows::process_events() { MSG msg; - process_joysticks(); + last_id = joystick->process_joysticks(last_id); while(PeekMessageW(&msg,NULL,0,0,PM_REMOVE)) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 026b50c33d..977e25f2d2 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -60,13 +60,11 @@ /** @author Juan Linietsky */ +class joystick_windows; class OS_Windows : public OS { - enum { - JOYSTICKS_MAX = 8, - JOY_AXIS_COUNT = 6, - MAX_JOY_AXIS = 32768, // I've no idea - KEY_EVENT_BUFFER_SIZE=512 + enum { + KEY_EVENT_BUFFER_SIZE=512 }; FILE *stdo; @@ -106,32 +104,6 @@ class OS_Windows : public OS { HINSTANCE hInstance; // Holds The Instance Of The Application HWND hWnd; - struct Joystick { - - int id; - bool attached; - - DWORD last_axis[JOY_AXIS_COUNT]; - DWORD last_buttons; - DWORD last_pov; - String name; - - Joystick() { - id = -1; - attached = false; - for (int i=0; i joystick_change_queue; - int joystick_count; - Joystick joysticks[JOYSTICKS_MAX]; - Size2 window_rect; VideoMode video_mode; @@ -156,13 +128,12 @@ class OS_Windows : public OS { CursorShape cursor_shape; InputDefault *input; + joystick_windows *joystick; #ifdef RTAUDIO_ENABLED AudioDriverRtAudio driver_rtaudio; #endif - void _post_dpad(DWORD p_dpad, int p_device, bool p_pressed); - void _drag_event(int p_x, int p_y, int idx); void _touch_event(bool p_pressed, int p_x, int p_y, int idx); @@ -186,11 +157,7 @@ protected: virtual void finalize_core(); void process_events(); - - void probe_joysticks(); - void process_joysticks(); void process_key_events(); - String get_joystick_name( int id, JOYCAPS jcaps); struct ProcessInfo { -- cgit v1.2.3 From 87dab29f4b71c47cc13e9974dc9462e6109aef96 Mon Sep 17 00:00:00 2001 From: hondres Date: Fri, 18 Dec 2015 19:15:32 +0100 Subject: Use tabs instead of spaces for new gamepad code --- platform/windows/joystick.cpp | 668 +++++++++++++++++++++--------------------- platform/windows/joystick.h | 162 +++++----- 2 files changed, 415 insertions(+), 415 deletions(-) (limited to 'platform/windows') diff --git a/platform/windows/joystick.cpp b/platform/windows/joystick.cpp index 32620c7779..68364ea8d5 100644 --- a/platform/windows/joystick.cpp +++ b/platform/windows/joystick.cpp @@ -44,354 +44,354 @@ joystick_windows::joystick_windows() { joystick_windows::joystick_windows(InputDefault* _input, HWND* hwnd) { - input = _input; - hWnd = hwnd; - joystick_count = 0; - dinput = NULL; - xinput_dll = NULL; - xinput_get_state = NULL; + input = _input; + hWnd = hwnd; + joystick_count = 0; + dinput = NULL; + xinput_dll = NULL; + xinput_get_state = NULL; - load_xinput(); + load_xinput(); - for (int i = 0; i < JOYSTICKS_MAX; i++) - attached_joysticks[i] = false; + for (int i = 0; i < JOYSTICKS_MAX; i++) + attached_joysticks[i] = false; - HRESULT result; - result = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dinput, NULL); - if (FAILED(result)) { - printf("failed init DINPUT: %ld\n", result); - } - probe_joysticks(); + HRESULT result; + result = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dinput, NULL); + if (FAILED(result)) { + printf("failed init DINPUT: %ld\n", result); + } + probe_joysticks(); } joystick_windows::~joystick_windows() { - close_joystick(); - dinput->Release(); - unload_xinput(); + close_joystick(); + dinput->Release(); + unload_xinput(); } bool joystick_windows::have_device(const GUID &p_guid) { - for (int i = 0; i < JOYSTICKS_MAX; i++) { + for (int i = 0; i < JOYSTICKS_MAX; i++) { - if (d_joysticks[i].guid == p_guid) { + if (d_joysticks[i].guid == p_guid) { - d_joysticks[i].confirmed = true; - return true; - } - } - return false; + d_joysticks[i].confirmed = true; + return true; + } + } + return false; } int joystick_windows::check_free_joy_slot() const { - for (int i = 0; i < JOYSTICKS_MAX; i++) { + for (int i = 0; i < JOYSTICKS_MAX; i++) { - if (!attached_joysticks[i]) - return i; - } - return -1; + if (!attached_joysticks[i]) + return i; + } + return -1; } // adapted from SDL2, works a lot better than the MSDN version bool joystick_windows::is_xinput_device(const GUID *p_guid) { - PRAWINPUTDEVICELIST dev_list = NULL; - unsigned int dev_list_count = 0; - - if (GetRawInputDeviceList(NULL, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == -1) { - return false; - } - dev_list = (PRAWINPUTDEVICELIST) malloc(sizeof(RAWINPUTDEVICELIST) * dev_list_count); - if (!dev_list) return false; - - if (GetRawInputDeviceList(dev_list, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == -1) { - free(dev_list); - return false; - } - for (int i = 0; i < dev_list_count; i++) { - - RID_DEVICE_INFO rdi; - char dev_name[128]; - UINT rdiSize = sizeof(rdi); - UINT nameSize = sizeof(dev_name); - - rdi.cbSize = rdiSize; - if ( (dev_list[i].dwType == RIM_TYPEHID) && - (GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1) && - (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == (LONG)p_guid->Data1) && - (GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, &dev_name, &nameSize) != (UINT)-1) && - (strstr(dev_name, "IG_") != NULL)) { - - free(dev_list); - return true; - } - } - free(dev_list); - return false; + PRAWINPUTDEVICELIST dev_list = NULL; + unsigned int dev_list_count = 0; + + if (GetRawInputDeviceList(NULL, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == -1) { + return false; + } + dev_list = (PRAWINPUTDEVICELIST) malloc(sizeof(RAWINPUTDEVICELIST) * dev_list_count); + if (!dev_list) return false; + + if (GetRawInputDeviceList(dev_list, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == -1) { + free(dev_list); + return false; + } + for (int i = 0; i < dev_list_count; i++) { + + RID_DEVICE_INFO rdi; + char dev_name[128]; + UINT rdiSize = sizeof(rdi); + UINT nameSize = sizeof(dev_name); + + rdi.cbSize = rdiSize; + if ( (dev_list[i].dwType == RIM_TYPEHID) && + (GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1) && + (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == (LONG)p_guid->Data1) && + (GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, &dev_name, &nameSize) != (UINT)-1) && + (strstr(dev_name, "IG_") != NULL)) { + + free(dev_list); + return true; + } + } + free(dev_list); + return false; } bool joystick_windows::setup_dinput_joystick(const DIDEVICEINSTANCE* instance) { - HRESULT hr; - int num = check_free_joy_slot(); + HRESULT hr; + int num = check_free_joy_slot(); - if (have_device(instance->guidInstance) || num == -1) - return false; + if (have_device(instance->guidInstance) || num == -1) + return false; - d_joysticks[joystick_count] = dinput_gamepad(); - dinput_gamepad* joy = &d_joysticks[num]; + d_joysticks[joystick_count] = dinput_gamepad(); + dinput_gamepad* joy = &d_joysticks[num]; - const DWORD devtype = (instance->dwDevType & 0xFF); + const DWORD devtype = (instance->dwDevType & 0xFF); - if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) { - //printf("ignore device %s, type %x\n", instance->tszProductName, devtype); - return false; - } + if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) { + //printf("ignore device %s, type %x\n", instance->tszProductName, devtype); + return false; + } - hr = dinput->CreateDevice(instance->guidInstance, &joy->di_joy, NULL); + hr = dinput->CreateDevice(instance->guidInstance, &joy->di_joy, NULL); - if (FAILED(hr)) { + if (FAILED(hr)) { - //std::wcout << "failed to create device: " << instance->tszProductName << std::endl; - return false; - } + //std::wcout << "failed to create device: " << instance->tszProductName << std::endl; + return false; + } - const GUID &guid = instance->guidProduct; - char uid[128]; - sprintf(uid, "%08lx%04hx%04hx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", - __builtin_bswap32(guid.Data1), guid.Data2, guid.Data3, - guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], - guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + const GUID &guid = instance->guidProduct; + char uid[128]; + sprintf(uid, "%08lx%04hx%04hx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + __builtin_bswap32(guid.Data1), guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); - id_to_change = num; - joy->di_joy->SetDataFormat(&c_dfDIJoystick2); - joy->di_joy->SetCooperativeLevel(*hWnd, DISCL_FOREGROUND); - joy->di_joy->EnumObjects(objectsCallback, this, NULL); - joy->joy_axis.sort(); + id_to_change = num; + joy->di_joy->SetDataFormat(&c_dfDIJoystick2); + joy->di_joy->SetCooperativeLevel(*hWnd, DISCL_FOREGROUND); + joy->di_joy->EnumObjects(objectsCallback, this, NULL); + joy->joy_axis.sort(); - joy->guid = instance->guidInstance; - input->joy_connection_changed(num, true, instance->tszProductName, uid); - joy->attached = true; - joy->id = num; - attached_joysticks[num] = true; - joy->confirmed = true; - joystick_count++; - return true; + joy->guid = instance->guidInstance; + input->joy_connection_changed(num, true, instance->tszProductName, uid); + joy->attached = true; + joy->id = num; + attached_joysticks[num] = true; + joy->confirmed = true; + joystick_count++; + return true; } void joystick_windows::setup_joystick_object(const DIDEVICEOBJECTINSTANCE *ob, int p_joy_id) { - if (ob->dwType & DIDFT_AXIS) { - - HRESULT res; - DIPROPRANGE prop_range; - DIPROPDWORD dilong; - DWORD ofs; - if (ob->guidType == GUID_XAxis) - ofs = DIJOFS_X; - else if (ob->guidType == GUID_YAxis) - ofs = DIJOFS_Y; - else if (ob->guidType == GUID_ZAxis) - ofs = DIJOFS_Z; - else if (ob->guidType == GUID_RxAxis) - ofs = DIJOFS_RX; - else if (ob->guidType == GUID_RyAxis) - ofs = DIJOFS_RY; - else if (ob->guidType == GUID_RzAxis) - ofs = DIJOFS_RZ; - else if (ob->guidType == GUID_Slider) - ofs = DIJOFS_SLIDER(0); - else - return; - prop_range.diph.dwSize = sizeof(DIPROPRANGE); - prop_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); - prop_range.diph.dwObj = ob->dwType; - prop_range.diph.dwHow = DIPH_BYID; - prop_range.lMin = -MAX_JOY_AXIS; - prop_range.lMax = +MAX_JOY_AXIS; - - dinput_gamepad &joy = d_joysticks[p_joy_id]; - - - res = joy.di_joy->SetProperty(DIPROP_RANGE, &prop_range.diph); - if (FAILED(res)) - return; - - dilong.diph.dwSize = sizeof(dilong); - dilong.diph.dwHeaderSize = sizeof(dilong.diph); - dilong.diph.dwObj = ob->dwType; - dilong.diph.dwHow = DIPH_BYID; - dilong.dwData = 0; - - res = IDirectInputDevice8_SetProperty(joy.di_joy, DIPROP_DEADZONE, &dilong.diph); - if (FAILED(res)) - return; - - joy.joy_axis.push_back(ofs); - } + if (ob->dwType & DIDFT_AXIS) { + + HRESULT res; + DIPROPRANGE prop_range; + DIPROPDWORD dilong; + DWORD ofs; + if (ob->guidType == GUID_XAxis) + ofs = DIJOFS_X; + else if (ob->guidType == GUID_YAxis) + ofs = DIJOFS_Y; + else if (ob->guidType == GUID_ZAxis) + ofs = DIJOFS_Z; + else if (ob->guidType == GUID_RxAxis) + ofs = DIJOFS_RX; + else if (ob->guidType == GUID_RyAxis) + ofs = DIJOFS_RY; + else if (ob->guidType == GUID_RzAxis) + ofs = DIJOFS_RZ; + else if (ob->guidType == GUID_Slider) + ofs = DIJOFS_SLIDER(0); + else + return; + prop_range.diph.dwSize = sizeof(DIPROPRANGE); + prop_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); + prop_range.diph.dwObj = ob->dwType; + prop_range.diph.dwHow = DIPH_BYID; + prop_range.lMin = -MAX_JOY_AXIS; + prop_range.lMax = +MAX_JOY_AXIS; + + dinput_gamepad &joy = d_joysticks[p_joy_id]; + + + res = joy.di_joy->SetProperty(DIPROP_RANGE, &prop_range.diph); + if (FAILED(res)) + return; + + dilong.diph.dwSize = sizeof(dilong); + dilong.diph.dwHeaderSize = sizeof(dilong.diph); + dilong.diph.dwObj = ob->dwType; + dilong.diph.dwHow = DIPH_BYID; + dilong.dwData = 0; + + res = IDirectInputDevice8_SetProperty(joy.di_joy, DIPROP_DEADZONE, &dilong.diph); + if (FAILED(res)) + return; + + joy.joy_axis.push_back(ofs); + } } BOOL CALLBACK joystick_windows::enumCallback(const DIDEVICEINSTANCE* instance, void* pContext) { - joystick_windows* self = (joystick_windows*)pContext; - if (self->is_xinput_device(&instance->guidProduct)) {; - return DIENUM_CONTINUE; - } - self->setup_dinput_joystick(instance); - return DIENUM_CONTINUE; + joystick_windows* self = (joystick_windows*)pContext; + if (self->is_xinput_device(&instance->guidProduct)) {; + return DIENUM_CONTINUE; + } + self->setup_dinput_joystick(instance); + return DIENUM_CONTINUE; } BOOL CALLBACK joystick_windows::objectsCallback(const DIDEVICEOBJECTINSTANCE *instance, void *context) { - joystick_windows* self = (joystick_windows*)context; - self->setup_joystick_object(instance, self->id_to_change); + joystick_windows* self = (joystick_windows*)context; + self->setup_joystick_object(instance, self->id_to_change); - return DIENUM_CONTINUE; + return DIENUM_CONTINUE; } void joystick_windows::close_joystick(int id) { - if (id == -1) { + if (id == -1) { - for (int i = 0; i < JOYSTICKS_MAX; i++) { + for (int i = 0; i < JOYSTICKS_MAX; i++) { - close_joystick(i); - } - return; - } + close_joystick(i); + } + return; + } - if (!d_joysticks[id].attached) return; + if (!d_joysticks[id].attached) return; - d_joysticks[id].di_joy->Unacquire(); - d_joysticks[id].di_joy->Release(); - d_joysticks[id].attached = false; - attached_joysticks[d_joysticks[id].id] = false; - d_joysticks[id].guid.Data1 = d_joysticks[id].guid.Data2 = d_joysticks[id].guid.Data3 = 0; - input->joy_connection_changed(id, false, ""); - joystick_count--; + d_joysticks[id].di_joy->Unacquire(); + d_joysticks[id].di_joy->Release(); + d_joysticks[id].attached = false; + attached_joysticks[d_joysticks[id].id] = false; + d_joysticks[id].guid.Data1 = d_joysticks[id].guid.Data2 = d_joysticks[id].guid.Data3 = 0; + input->joy_connection_changed(id, false, ""); + joystick_count--; } void joystick_windows::probe_joysticks() { - DWORD dwResult; - for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { + DWORD dwResult; + for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { - ZeroMemory(&x_joysticks[i].state, sizeof(XINPUT_STATE)); + ZeroMemory(&x_joysticks[i].state, sizeof(XINPUT_STATE)); - dwResult = xinput_get_state(i, &x_joysticks[i].state); - if ( dwResult == ERROR_SUCCESS) { + dwResult = xinput_get_state(i, &x_joysticks[i].state); + if ( dwResult == ERROR_SUCCESS) { - int id = check_free_joy_slot(); - if (id != -1 && !x_joysticks[i].attached) { + int id = check_free_joy_slot(); + if (id != -1 && !x_joysticks[i].attached) { - x_joysticks[i].attached = true; - x_joysticks[i].id = id; - attached_joysticks[id] = true; - input->joy_connection_changed(id, true, "XInput Gamepad","__XINPUT_DEVICE__"); - } - } - else if (x_joysticks[i].attached) { + x_joysticks[i].attached = true; + x_joysticks[i].id = id; + attached_joysticks[id] = true; + input->joy_connection_changed(id, true, "XInput Gamepad","__XINPUT_DEVICE__"); + } + } + else if (x_joysticks[i].attached) { - x_joysticks[i].attached = false; - attached_joysticks[x_joysticks[i].id] = false; - input->joy_connection_changed(x_joysticks[i].id, false, ""); - } - } + x_joysticks[i].attached = false; + attached_joysticks[x_joysticks[i].id] = false; + input->joy_connection_changed(x_joysticks[i].id, false, ""); + } + } - for (int i = 0; i < joystick_count; i++) { + for (int i = 0; i < joystick_count; i++) { - d_joysticks[i].confirmed = false; - } + d_joysticks[i].confirmed = false; + } - dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, this, DIEDFL_ATTACHEDONLY); + dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, this, DIEDFL_ATTACHEDONLY); - for (int i = 0; i < joystick_count; i++) { + for (int i = 0; i < joystick_count; i++) { - if (!d_joysticks[i].confirmed) { + if (!d_joysticks[i].confirmed) { - close_joystick(i); - } - } + close_joystick(i); + } + } } unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { - HRESULT hr; + HRESULT hr; - for (int i = 0; i < XUSER_MAX_COUNT; i++) { + for (int i = 0; i < XUSER_MAX_COUNT; i++) { - xinput_gamepad &joy = x_joysticks[i]; - if (!joy.attached) { - continue; - } - ZeroMemory(&joy.state, sizeof(XINPUT_STATE)); + xinput_gamepad &joy = x_joysticks[i]; + if (!joy.attached) { + continue; + } + ZeroMemory(&joy.state, sizeof(XINPUT_STATE)); - xinput_get_state(i, &joy.state); - if (joy.state.dwPacketNumber != joy.last_packet) { + xinput_get_state(i, &joy.state); + if (joy.state.dwPacketNumber != joy.last_packet) { - int button_mask = XINPUT_GAMEPAD_DPAD_UP; - for (int i = 0; i <= 16; i++) { + int button_mask = XINPUT_GAMEPAD_DPAD_UP; + for (int i = 0; i <= 16; i++) { - p_last_id = input->joy_button(p_last_id, joy.id, i, joy.state.Gamepad.wButtons & button_mask); - button_mask = button_mask * 2; - } + p_last_id = input->joy_button(p_last_id, joy.id, i, joy.state.Gamepad.wButtons & button_mask); + button_mask = button_mask * 2; + } - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); - joy.last_packet = joy.state.dwPacketNumber; - } - } + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); + p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); + joy.last_packet = joy.state.dwPacketNumber; + } + } - for (int i = 0; i < JOYSTICKS_MAX; i++) { + for (int i = 0; i < JOYSTICKS_MAX; i++) { - dinput_gamepad* joy = &d_joysticks[i]; + dinput_gamepad* joy = &d_joysticks[i]; - if (!joy->attached) - continue; + if (!joy->attached) + continue; - DIJOYSTATE2 js; - hr = joy->di_joy->Poll(); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { - IDirectInputDevice8_Acquire(joy->di_joy); - joy->di_joy->Poll(); - } - if (FAILED(hr = d_joysticks[i].di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js))) { + DIJOYSTATE2 js; + hr = joy->di_joy->Poll(); + if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joy->di_joy); + joy->di_joy->Poll(); + } + if (FAILED(hr = d_joysticks[i].di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js))) { - //printf("failed to read joy #%d\n", i); - continue; - } + //printf("failed to read joy #%d\n", i); + continue; + } - p_last_id = post_hat(p_last_id, i, js.rgdwPOV[0]); + p_last_id = post_hat(p_last_id, i, js.rgdwPOV[0]); - for (int j = 0; j < 128; j++) { + for (int j = 0; j < 128; j++) { - if (js.rgbButtons[j] & 0x80) { + if (js.rgbButtons[j] & 0x80) { - if (!joy->last_buttons[j]) { + if (!joy->last_buttons[j]) { - p_last_id = input->joy_button(p_last_id, i, j, true); - joy->last_buttons[j] = true; - } - } - else { + p_last_id = input->joy_button(p_last_id, i, j, true); + joy->last_buttons[j] = true; + } + } + else { - if (joy->last_buttons[j]) { + if (joy->last_buttons[j]) { - p_last_id = input->joy_button(p_last_id, i, j, false); - joy->last_buttons[j] = false; - } - } - } + p_last_id = input->joy_button(p_last_id, i, j, false); + joy->last_buttons[j] = false; + } + } + } // on mingw, these constants are not constants int count = 6; @@ -407,122 +407,122 @@ unsigned int joystick_windows::process_joysticks(unsigned int p_last_id) { }; }; }; - } - return p_last_id; + } + return p_last_id; } unsigned int joystick_windows::post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad) { - int dpad_val = 0; + int dpad_val = 0; - if (p_dpad == -1) { - dpad_val = InputDefault::HAT_MASK_CENTER; - } - if (p_dpad == 0) { + if (p_dpad == -1) { + dpad_val = InputDefault::HAT_MASK_CENTER; + } + if (p_dpad == 0) { - dpad_val = InputDefault::HAT_MASK_UP; + dpad_val = InputDefault::HAT_MASK_UP; - } - else if (p_dpad == 4500) { + } + else if (p_dpad == 4500) { - dpad_val = (InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_RIGHT); + dpad_val = (InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_RIGHT); - } - else if (p_dpad == 9000) { + } + else if (p_dpad == 9000) { - dpad_val = InputDefault::HAT_MASK_RIGHT; + dpad_val = InputDefault::HAT_MASK_RIGHT; - } - else if (p_dpad == 13500) { + } + else if (p_dpad == 13500) { - dpad_val = (InputDefault::HAT_MASK_RIGHT | InputDefault::HAT_MASK_DOWN); + dpad_val = (InputDefault::HAT_MASK_RIGHT | InputDefault::HAT_MASK_DOWN); - } - else if (p_dpad == 18000) { + } + else if (p_dpad == 18000) { - dpad_val = InputDefault::HAT_MASK_DOWN; + dpad_val = InputDefault::HAT_MASK_DOWN; - } - else if (p_dpad == 22500) { + } + else if (p_dpad == 22500) { - dpad_val = (InputDefault::HAT_MASK_DOWN | InputDefault::HAT_MASK_LEFT); + dpad_val = (InputDefault::HAT_MASK_DOWN | InputDefault::HAT_MASK_LEFT); - } - else if (p_dpad == 27000) { + } + else if (p_dpad == 27000) { - dpad_val = InputDefault::HAT_MASK_LEFT; + dpad_val = InputDefault::HAT_MASK_LEFT; - } - else if (p_dpad == 31500) { + } + else if (p_dpad == 31500) { - dpad_val = (InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_UP); - } - return input->joy_hat(p_last_id, p_device, dpad_val); + dpad_val = (InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_UP); + } + return input->joy_hat(p_last_id, p_device, dpad_val); }; InputDefault::JoyAxis joystick_windows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { - InputDefault::JoyAxis jx; - if (Math::abs(p_val) < MIN_JOY_AXIS) { - jx.min = -1; - jx.value = 0.0f; - return jx; - } - if (p_xinput) { - - if (p_trigger) { - jx.min = 0; - jx.value = (float)p_val / MAX_TRIGGER; - return jx; - } - jx.min = -1; - if (p_val < 0) { - jx.value = (float)p_val / MAX_JOY_AXIS; - } - else { - jx.value = (float)p_val / (MAX_JOY_AXIS - 1); - } - if (p_negate) { - jx.value = -jx.value; - } - return jx; - } - jx.min = -1; - jx.value = (float)p_val / MAX_JOY_AXIS; - return jx; + InputDefault::JoyAxis jx; + if (Math::abs(p_val) < MIN_JOY_AXIS) { + jx.min = -1; + jx.value = 0.0f; + return jx; + } + if (p_xinput) { + + if (p_trigger) { + jx.min = 0; + jx.value = (float)p_val / MAX_TRIGGER; + return jx; + } + jx.min = -1; + if (p_val < 0) { + jx.value = (float)p_val / MAX_JOY_AXIS; + } + else { + jx.value = (float)p_val / (MAX_JOY_AXIS - 1); + } + if (p_negate) { + jx.value = -jx.value; + } + return jx; + } + jx.min = -1; + jx.value = (float)p_val / MAX_JOY_AXIS; + return jx; } void joystick_windows::load_xinput() { - xinput_get_state = &_xinput_get_state; - xinput_dll = LoadLibrary( "XInput1_4.dll" ); - if (!xinput_dll) { - xinput_dll = LoadLibrary("XInput1_3.dll"); - if (!xinput_dll) { - xinput_dll = LoadLibrary("XInput9_1_0.dll"); - } - } - - if (!xinput_dll) { - if (OS::get_singleton()->is_stdout_verbose()) { - print_line("Could not find XInput, using DirectInput only"); - } - return; - } - - XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputGetState"); - if (!func) { - unload_xinput(); - return; - } - xinput_get_state = func; - return; + xinput_get_state = &_xinput_get_state; + xinput_dll = LoadLibrary( "XInput1_4.dll" ); + if (!xinput_dll) { + xinput_dll = LoadLibrary("XInput1_3.dll"); + if (!xinput_dll) { + xinput_dll = LoadLibrary("XInput9_1_0.dll"); + } + } + + if (!xinput_dll) { + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("Could not find XInput, using DirectInput only"); + } + return; + } + + XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputGetState"); + if (!func) { + unload_xinput(); + return; + } + xinput_get_state = func; + return; } void joystick_windows::unload_xinput() { - if (xinput_dll) { + if (xinput_dll) { - FreeLibrary((HMODULE)xinput_dll); - } + FreeLibrary((HMODULE)xinput_dll); + } } diff --git a/platform/windows/joystick.h b/platform/windows/joystick.h index d0d85cd2c9..4c706b3766 100644 --- a/platform/windows/joystick.h +++ b/platform/windows/joystick.h @@ -48,90 +48,90 @@ if(x != NULL) \ class joystick_windows { public: - joystick_windows(); - joystick_windows(InputDefault* _input, HWND* hwnd); - ~joystick_windows(); + joystick_windows(); + joystick_windows(InputDefault* _input, HWND* hwnd); + ~joystick_windows(); - void probe_joysticks(); - unsigned int process_joysticks(unsigned int p_last_id); + void probe_joysticks(); + unsigned int process_joysticks(unsigned int p_last_id); private: - enum { - JOYSTICKS_MAX = 16, - JOY_AXIS_COUNT = 6, - MIN_JOY_AXIS = 10, - MAX_JOY_AXIS = 32768, - MAX_JOY_BUTTONS = 128, - KEY_EVENT_BUFFER_SIZE = 512, - MAX_TRIGGER = 255 - }; - - struct dinput_gamepad { - - int id; - bool attached; - bool confirmed; - bool last_buttons[MAX_JOY_BUTTONS]; - DWORD last_pad; - - LPDIRECTINPUTDEVICE8 di_joy; - List joy_axis; - GUID guid; - - dinput_gamepad() { - id = -1; - last_pad = -1; - attached = false; - confirmed = false; - - for (int i = 0; i < MAX_JOY_BUTTONS; i++) - last_buttons[i] = false; - } - }; - - struct xinput_gamepad { - - int id; - bool attached; - DWORD last_packet; - XINPUT_STATE state; - - xinput_gamepad() { - attached = false; - last_packet = 0; - } - }; - - typedef DWORD (WINAPI *XInputGetState_t) (DWORD dwUserIndex, XINPUT_STATE* pState); - - HWND* hWnd; - HANDLE xinput_dll; - LPDIRECTINPUT8 dinput; - InputDefault* input; - - int id_to_change; - int joystick_count; - bool attached_joysticks[JOYSTICKS_MAX]; - dinput_gamepad d_joysticks[JOYSTICKS_MAX]; - xinput_gamepad x_joysticks[XUSER_MAX_COUNT]; - - static BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* p_instance, void* p_context); - static BOOL CALLBACK objectsCallback(const DIDEVICEOBJECTINSTANCE* instance, void* context); - - void setup_joystick_object(const DIDEVICEOBJECTINSTANCE* ob, int p_joy_id); - void close_joystick(int id = -1); - void load_xinput(); - void unload_xinput(); - - int check_free_joy_slot() const; - unsigned int post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad); - - bool have_device(const GUID &p_guid); - bool is_xinput_device(const GUID* p_guid); - bool setup_dinput_joystick(const DIDEVICEINSTANCE* instance); - - InputDefault::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; - XInputGetState_t xinput_get_state; + enum { + JOYSTICKS_MAX = 16, + JOY_AXIS_COUNT = 6, + MIN_JOY_AXIS = 10, + MAX_JOY_AXIS = 32768, + MAX_JOY_BUTTONS = 128, + KEY_EVENT_BUFFER_SIZE = 512, + MAX_TRIGGER = 255 + }; + + struct dinput_gamepad { + + int id; + bool attached; + bool confirmed; + bool last_buttons[MAX_JOY_BUTTONS]; + DWORD last_pad; + + LPDIRECTINPUTDEVICE8 di_joy; + List joy_axis; + GUID guid; + + dinput_gamepad() { + id = -1; + last_pad = -1; + attached = false; + confirmed = false; + + for (int i = 0; i < MAX_JOY_BUTTONS; i++) + last_buttons[i] = false; + } + }; + + struct xinput_gamepad { + + int id; + bool attached; + DWORD last_packet; + XINPUT_STATE state; + + xinput_gamepad() { + attached = false; + last_packet = 0; + } + }; + + typedef DWORD (WINAPI *XInputGetState_t) (DWORD dwUserIndex, XINPUT_STATE* pState); + + HWND* hWnd; + HANDLE xinput_dll; + LPDIRECTINPUT8 dinput; + InputDefault* input; + + int id_to_change; + int joystick_count; + bool attached_joysticks[JOYSTICKS_MAX]; + dinput_gamepad d_joysticks[JOYSTICKS_MAX]; + xinput_gamepad x_joysticks[XUSER_MAX_COUNT]; + + static BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* p_instance, void* p_context); + static BOOL CALLBACK objectsCallback(const DIDEVICEOBJECTINSTANCE* instance, void* context); + + void setup_joystick_object(const DIDEVICEOBJECTINSTANCE* ob, int p_joy_id); + void close_joystick(int id = -1); + void load_xinput(); + void unload_xinput(); + + int check_free_joy_slot() const; + unsigned int post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad); + + bool have_device(const GUID &p_guid); + bool is_xinput_device(const GUID* p_guid); + bool setup_dinput_joystick(const DIDEVICEINSTANCE* instance); + + InputDefault::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; + XInputGetState_t xinput_get_state; }; #endif -- cgit v1.2.3 From bec1e003e794c44a8f9fc060502efdec44241f25 Mon Sep 17 00:00:00 2001 From: Ariel Manzur Date: Sun, 20 Dec 2015 11:50:16 -0300 Subject: this failed on mingw on linux (but not on msvc) with 2 problems: 1) it didn't print the error to the console, only this: build_res_file(["platform/windows/godot_res.windows.tools.32.o"], ["platform/windows/godot_res.rc"]) scons: *** [platform/windows/godot_res.windows.tools.32.o] Error 1 I had to print the actual command and run it on a console to see the error. The builder should be able to print the command it's running and the error, like it does with compiler invocations, etc. 2) The actual error was a syntax error on line 11 of godot_res.rc. I looked up "FILEVERSION" and "PRODUCTVERSION" (here https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058(v=vs.85).aspx), it says they take 4 numbers as parameters, so I added those 0s, but I'm not sure if they're in the right order. @masoudbh3 can you check it out? thanks It builds on msvc just fine with (and without) these changes. --- platform/windows/godot_res.rc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'platform/windows') diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index f77182f909..1a38bb4708 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -7,8 +7,8 @@ GODOT_ICON ICON platform/windows/godot.ico 1 VERSIONINFO -FILEVERSION VERSION_MAJOR,VERSION_MINOR,0 -PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,0 +FILEVERSION VERSION_MAJOR,0,VERSION_MINOR,0 +PRODUCTVERSION VERSION_MAJOR,0,VERSION_MINOR,0 FILEOS 4 FILETYPE 1 BEGIN @@ -30,4 +30,4 @@ BEGIN BEGIN VALUE "Translation", 0x409, 1200 END -END \ No newline at end of file +END -- cgit v1.2.3 From 020700af1d664c7b6e3b8b8d50a23e86286ef3dd Mon Sep 17 00:00:00 2001 From: Ariel Manzur Date: Sun, 20 Dec 2015 13:43:08 -0300 Subject: windows resource version thing --- platform/windows/godot_res.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'platform/windows') diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index 1a38bb4708..5f1e951e0f 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -7,8 +7,8 @@ GODOT_ICON ICON platform/windows/godot.ico 1 VERSIONINFO -FILEVERSION VERSION_MAJOR,0,VERSION_MINOR,0 -PRODUCTVERSION VERSION_MAJOR,0,VERSION_MINOR,0 +FILEVERSION VERSION_MAJOR,VERSION_MINOR,0,0 +PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,0,0 FILEOS 4 FILETYPE 1 BEGIN -- cgit v1.2.3