Added libusb class + libusb log option
This commit is contained in:
parent
b748c5f61a
commit
006af26a6e
|
@ -65,6 +65,7 @@ file (GLOB CXBXR_HEADER_COMMON
|
|||
"${CXBXR_ROOT_DIR}/src/common/input/layout_xbox_device.h"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/InputDevice.h"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/InputManager.h"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/LibusbDevice.h"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/SdlJoystick.h"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/XInputPad.h"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/RawDevice.h"
|
||||
|
@ -236,6 +237,7 @@ file (GLOB CXBXR_SOURCE_COMMON
|
|||
"${CXBXR_ROOT_DIR}/src/common/input/DInputKeyboardMouse.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/InputDevice.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/InputManager.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/LibusbDevice.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/SdlJoystick.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/XInputPad.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/common/input/RawDevice.cpp"
|
||||
|
|
|
@ -82,6 +82,7 @@ const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = {
|
|||
"XMO ",
|
||||
"RINP ",
|
||||
"JVS ",
|
||||
"LIBUSB ",
|
||||
"KRNL ",
|
||||
"LOG ",
|
||||
"XBOX ",
|
||||
|
|
|
@ -90,6 +90,7 @@ typedef enum class _CXBXR_MODULE: unsigned int {
|
|||
XMO,
|
||||
RINP,
|
||||
JVS,
|
||||
LIBUSB,
|
||||
// kernel
|
||||
KRNL,
|
||||
LOG,
|
||||
|
|
|
@ -77,6 +77,14 @@ std::string GetInputDeviceName(int dev_type)
|
|||
str = "Arcade joystick";
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER):
|
||||
str = "Passthrough steel battalion controller";
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER):
|
||||
str = "Passthrough original xbox gamepad";
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID):
|
||||
str = "None";
|
||||
break;
|
||||
|
|
|
@ -56,6 +56,9 @@ typedef enum class _XBOX_INPUT_DEVICE : int {
|
|||
STEEL_BATTALION_CONTROLLER,
|
||||
ARCADE_STICK,
|
||||
DEVICE_MAX,
|
||||
// Devices with the HW_ prefix (= hardware) indicate a real xbox device. Always add these after DEVICE_MAX
|
||||
HW_STEEL_BATTALION_CONTROLLER,
|
||||
HW_XBOX_CONTROLLER,
|
||||
}
|
||||
XBOX_INPUT_DEVICE;
|
||||
|
||||
|
@ -120,6 +123,8 @@ public:
|
|||
bool GetPort(std::string_view Port) const;
|
||||
// sets the port this device is attached to
|
||||
void SetPort(std::string_view Port, bool Connect);
|
||||
// retuns true if it is a libusb device, false otherwise
|
||||
virtual bool IsLibusb() const { return false; };
|
||||
|
||||
|
||||
protected:
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "XInputPad.h"
|
||||
#include "RawDevice.h"
|
||||
#include "DInputKeyboardMouse.h"
|
||||
#include "LibusbDevice.h"
|
||||
#include "InputManager.h"
|
||||
#include "..\devices\usb\XidGamepad.h"
|
||||
#include "core\kernel\exports\EmuKrnl.h" // For EmuLog
|
||||
|
@ -91,11 +92,12 @@ void InputDeviceManager::Initialize(bool is_gui, HWND hwnd)
|
|||
m_Cv.wait(lck, []() {
|
||||
return (Sdl::InitStatus != Sdl::NOT_INIT) &&
|
||||
(XInput::InitStatus != XInput::NOT_INIT) &&
|
||||
(RawInput::InitStatus != RawInput::NOT_INIT);
|
||||
(RawInput::InitStatus != RawInput::NOT_INIT) &&
|
||||
(Libusb::InitStatus != Libusb::NOT_INIT);
|
||||
});
|
||||
lck.unlock();
|
||||
|
||||
if (Sdl::InitStatus < 0 || XInput::InitStatus < 0 || RawInput::InitStatus < 0) {
|
||||
if (Sdl::InitStatus < 0 || XInput::InitStatus < 0 || RawInput::InitStatus < 0 || Libusb::InitStatus < 0) {
|
||||
CxbxrKrnlAbort("Failed to initialize input subsystem! Consult debug log for more information");
|
||||
}
|
||||
|
||||
|
@ -616,6 +618,7 @@ void InputDeviceManager::RefreshDevices()
|
|||
XInput::PopulateDevices();
|
||||
DInput::PopulateDevices();
|
||||
Sdl::PopulateDevices();
|
||||
Libusb::PopulateDevices();
|
||||
lck.lock();
|
||||
m_Cv.wait(lck, []() {
|
||||
return Sdl::PopulateOK;
|
||||
|
@ -719,7 +722,7 @@ void InputDeviceManager::HotplugHandler(bool is_sdl)
|
|||
std::unique_lock<std::mutex> lck(m_Mtx);
|
||||
|
||||
auto it = std::remove_if(m_Devices.begin(), m_Devices.end(), [](const auto &Device) {
|
||||
if (StrStartsWith(Device->GetAPI(), "XInput")) {
|
||||
if (Device->IsLibusb() || StrStartsWith(Device->GetAPI(), "XInput")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -730,6 +733,9 @@ void InputDeviceManager::HotplugHandler(bool is_sdl)
|
|||
|
||||
lck.unlock();
|
||||
XInput::PopulateDevices();
|
||||
// Unfortunately, as documented in this issue https://github.com/libusb/libusb/issues/86, when this was written libusb did not yet support
|
||||
// device hotplug on Windows, so we add the below call here. This will only work if rawinput detects the libusb device.
|
||||
Libusb::PopulateDevices();
|
||||
}
|
||||
|
||||
for (int port = PORT_1; port <= PORT_4; ++port) {
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
// ******************************************************************
|
||||
// *
|
||||
// * This file is part of the Cxbx project.
|
||||
// *
|
||||
// * Cxbx and Cxbe are free software; you can redistribute them
|
||||
// * and/or modify them under the terms of the GNU General Public
|
||||
// * License as published by the Free Software Foundation; either
|
||||
// * version 2 of the license, or (at your option) any later version.
|
||||
// *
|
||||
// * This program 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 recieved a copy of the GNU General Public License
|
||||
// * along with this program; see the file COPYING.
|
||||
// * If not, write to the Free Software Foundation, Inc.,
|
||||
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
||||
// *
|
||||
// * (c) 2021 ergo720
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#define LOG_PREFIX CXBXR_MODULE::LIBUSB
|
||||
|
||||
#include "LibusbDevice.h"
|
||||
#include "InputManager.h"
|
||||
#include "core\kernel\support\Emu.h"
|
||||
|
||||
// Sanitiy check: ensure out libusb version is high enough for libusb_get_device_descriptor to succeed
|
||||
static_assert(LIBUSB_API_VERSION >= 0x01000102);
|
||||
|
||||
|
||||
namespace Libusb
|
||||
{
|
||||
int InitStatus = NOT_INIT;
|
||||
static libusb_device **List = nullptr;
|
||||
|
||||
// These come from here https://github.com/xboxdrv/xboxdrv/blob/ac6ebb1228962220482ea03743cadbe18754246c/src/xpad_device.cpp#L29
|
||||
static constexpr uint16_t SupportedDevices_VidPid[][2] = { // vid, pid
|
||||
0x0d2f, 0x0002,
|
||||
0x045e, 0x0202,
|
||||
0x045e, 0x0285,
|
||||
0x045e, 0x0287,
|
||||
0x045e, 0x0289,
|
||||
0x046d, 0xca84,
|
||||
0x046d, 0xca88,
|
||||
0x05fd, 0x1007,
|
||||
0x05fd, 0x107a,
|
||||
0x0738, 0x4516,
|
||||
0x0738, 0x4522,
|
||||
0x0738, 0x4526,
|
||||
0x0738, 0x4536,
|
||||
0x0738, 0x4556,
|
||||
0x0c12, 0x8802,
|
||||
0x0c12, 0x8810,
|
||||
0x0c12, 0x9902,
|
||||
0x0e4c, 0x1097,
|
||||
0x0e4c, 0x2390,
|
||||
0x0e6f, 0x0003,
|
||||
0x0e6f, 0x0005,
|
||||
0x0e6f, 0x0006,
|
||||
0x0f30, 0x0202,
|
||||
0x0f30, 0x8888,
|
||||
0x102c, 0xff0c,
|
||||
0x044f, 0x0f07,
|
||||
0x0e8f, 0x3008,
|
||||
};
|
||||
|
||||
static constexpr const char *SupportedDevices_Name[] = {
|
||||
"Andamiro Pump It Up pad",
|
||||
"Microsoft X-Box pad v1 (US)",
|
||||
"Microsoft X-Box pad (Japan)",
|
||||
"Microsoft Xbox Controller S",
|
||||
"Microsoft X-Box pad v2 (US)",
|
||||
"Logitech Xbox Cordless Controller",
|
||||
"Logitech Compact Controller for Xbox",
|
||||
"Mad Catz Controller (unverified)",
|
||||
"InterAct 'PowerPad Pro' X-Box pad (Germany)",
|
||||
"Mad Catz Control Pad",
|
||||
"Mad Catz LumiCON",
|
||||
"Mad Catz Control Pad Pro",
|
||||
"Mad Catz MicroCON",
|
||||
"Mad Catz Lynx Wireless Controller",
|
||||
"Zeroplus Xbox Controller",
|
||||
"Zeroplus Xbox Controller",
|
||||
"HAMA VibraX - *FAULTY HARDWARE*",
|
||||
"Radica Gamester Controller",
|
||||
"Radica Games Jtech Controller",
|
||||
"Logic3 Freebird wireless Controller",
|
||||
"Eclipse wireless Controller",
|
||||
"Edge wireless Controller",
|
||||
"Joytech Advanced Controller",
|
||||
"BigBen XBMiniPad Controller",
|
||||
"Joytech Wireless Advanced Controller",
|
||||
"Thrustmaster, Inc. Controller",
|
||||
"Generic xbox control (dealextreme)",
|
||||
};
|
||||
|
||||
static_assert(ARRAY_SIZE(SupportedDevices_VidPid) == ARRAY_SIZE(SupportedDevices_Name));
|
||||
|
||||
void Init(std::mutex &Mtx)
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(Mtx);
|
||||
|
||||
// We only use a single libusb session per cxbxr process, so we do not need to use a libusb context
|
||||
if (libusb_init(nullptr) != 0) {
|
||||
EmuLog(LOG_LEVEL::ERROR2, "Failed to initialize Libusb!");
|
||||
InitStatus = INIT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
InitStatus = INIT_SUCCESS;
|
||||
}
|
||||
|
||||
void DeInit()
|
||||
{
|
||||
InitStatus = NOT_INIT;
|
||||
libusb_exit(nullptr);
|
||||
}
|
||||
|
||||
void PopulateDevices()
|
||||
{
|
||||
// NOTE: the libusb docs say that the list is always appended with a NULL element at the end
|
||||
ssize_t DevicesConnected = libusb_get_device_list(nullptr, &List) - 1;
|
||||
if (DevicesConnected < 0) {
|
||||
EmuLog(LOG_LEVEL::ERROR2, "Failed to enumerate devices. The error was: %s", libusb_strerror(DevicesConnected));
|
||||
return;
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < DevicesConnected; ++i) {
|
||||
libusb_device *LibusbDev = List[i];
|
||||
libusb_device_descriptor Desc;
|
||||
libusb_get_device_descriptor(LibusbDev, &Desc); // always succeeds when LIBUSB_API_VERSION >= 0x01000102
|
||||
auto Device = std::make_shared<LibusbDevice>(&Desc, LibusbDev);
|
||||
if (Device->IsLibusb()) {
|
||||
g_InputDeviceManager.AddDevice(std::move(Device));
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(List, 1);
|
||||
List = nullptr;
|
||||
}
|
||||
|
||||
void GetDeviceChanges()
|
||||
{
|
||||
g_InputDeviceManager.RemoveDevice([](const auto &Device) {
|
||||
const LibusbDevice *dev = dynamic_cast<const LibusbDevice *>(Device);
|
||||
return dev->IsLibusb();
|
||||
});
|
||||
PopulateDevices();
|
||||
}
|
||||
|
||||
bool LibusbDevice::UpdateInput()
|
||||
{
|
||||
// not sure of this yet
|
||||
return true;
|
||||
}
|
||||
|
||||
LibusbDevice::LibusbDevice(libusb_device_descriptor *Desc, libusb_device *Dev)
|
||||
{
|
||||
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
|
||||
|
||||
// The SBC's VID and PID are taken from https://xboxdevwiki.net/Xbox_Input_Devices#Steel_Battalion_Controller
|
||||
if ((Desc->idVendor == 0x0a7b) && (Desc->idProduct == 0xd000)) {
|
||||
m_Type = XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER;
|
||||
m_Name = "Steel battalion controller";
|
||||
assert(Desc->bcdUSB == 0x110); // must be a usb 1.1 device
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(SupportedDevices_VidPid); ++i) {
|
||||
if ((Desc->idVendor = SupportedDevices_VidPid[i][0]) && (Desc->idProduct == SupportedDevices_VidPid[i][1])) {
|
||||
m_Type = XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER;
|
||||
m_Name = SupportedDevices_Name[i];
|
||||
assert(Desc->bcdUSB == 0x110); // must be a usb 1.1 device
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Type == XBOX_INPUT_DEVICE::DEVICE_INVALID) { return; }
|
||||
|
||||
// Duke, S and SBC have 1 configuration, 1 interface and 2 endpoints (input and output) and use the default alternate setting zero.
|
||||
// The code below assumes that third-party controllers follow suit.
|
||||
if (libusb_open(Dev, &m_hDev) == 0) {
|
||||
libusb_config_descriptor *Desc;
|
||||
if (libusb_get_active_config_descriptor(Dev, &Desc) == 0) {
|
||||
if (Desc->bNumInterfaces == 1) {
|
||||
auto Iface = Desc->interface[0];
|
||||
if (Iface.num_altsetting == 1) {
|
||||
auto Setting = Iface.altsetting[0];
|
||||
if (Setting.bNumEndpoints == 2) {
|
||||
for (uint8_t i = 0; i < 2; ++i) {
|
||||
auto Endpoint = Setting.endpoint[i];
|
||||
if (Endpoint.bmAttributes & LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT) {
|
||||
if (Endpoint.bEndpointAddress & 0x80) {
|
||||
m_EndpointIn = Endpoint.bEndpointAddress;
|
||||
m_IntervalIn = Endpoint.bInterval;
|
||||
}
|
||||
else {
|
||||
m_EndpointOut = Endpoint.bEndpointAddress;
|
||||
m_IntervalOut = Endpoint.bInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
EmuLog(LOG_LEVEL::INFO, "Rejected device because of unexpected number of endpoints, bNumEndpoints: %d", Setting.bNumEndpoints);
|
||||
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
EmuLog(LOG_LEVEL::INFO, "Rejected device because of unexpected number of alternative settings, num_altsetting: %d", Iface.num_altsetting);
|
||||
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
EmuLog(LOG_LEVEL::INFO, "Rejected device because of unexpected number of interfaces, bNumInterfaces: %d", Desc->bNumInterfaces);
|
||||
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
|
||||
}
|
||||
libusb_free_config_descriptor(Desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string LibusbDevice::GetDeviceName() const
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
std::string LibusbDevice::GetAPI() const
|
||||
{
|
||||
return "Libusb";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
// ******************************************************************
|
||||
// *
|
||||
// * This file is part of the Cxbx project.
|
||||
// *
|
||||
// * Cxbx and Cxbe are free software; you can redistribute them
|
||||
// * and/or modify them under the terms of the GNU General Public
|
||||
// * License as published by the Free Software Foundation; either
|
||||
// * version 2 of the license, or (at your option) any later version.
|
||||
// *
|
||||
// * This program 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 recieved a copy of the GNU General Public License
|
||||
// * along with this program; see the file COPYING.
|
||||
// * If not, write to the Free Software Foundation, Inc.,
|
||||
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
||||
// *
|
||||
// * (c) 2021 ergo720
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "InputDevice.h"
|
||||
// Suppress warning in libusb about zero sized array
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
#include "libusb.h"
|
||||
#pragma warning(pop)
|
||||
|
||||
|
||||
namespace Libusb
|
||||
{
|
||||
typedef enum _INIT_STATUS : int
|
||||
{
|
||||
NOT_INIT = -2,
|
||||
INIT_ERROR,
|
||||
INIT_SUCCESS,
|
||||
}
|
||||
INIT_STATUS;
|
||||
|
||||
extern int InitStatus;
|
||||
|
||||
// initialize Libusb
|
||||
void Init(std::mutex &Mtx);
|
||||
// shutdown Libusb
|
||||
void DeInit();
|
||||
// refresh the device list in response to a refresh command from the input GUI
|
||||
void PopulateDevices();
|
||||
// update the device list
|
||||
void GetDeviceChanges();
|
||||
|
||||
class LibusbDevice : public InputDevice
|
||||
{
|
||||
public:
|
||||
bool UpdateInput() override;
|
||||
|
||||
LibusbDevice(libusb_device_descriptor *Desc, libusb_device *Dev);
|
||||
|
||||
std::string GetDeviceName() const override;
|
||||
std::string GetAPI() const override;
|
||||
bool IsLibusb() const override { return m_Type != XBOX_INPUT_DEVICE::DEVICE_INVALID; }
|
||||
|
||||
|
||||
private:
|
||||
XBOX_INPUT_DEVICE m_Type;
|
||||
std::string m_Name;
|
||||
libusb_device_handle *m_hDev;
|
||||
unsigned char m_EndpointIn;
|
||||
unsigned char m_EndpointOut;
|
||||
uint8_t m_IntervalIn;
|
||||
uint8_t m_IntervalOut;
|
||||
};
|
||||
}
|
|
@ -41,6 +41,7 @@
|
|||
#include "SdlJoystick.h"
|
||||
#include "XInputPad.h"
|
||||
#include "DInputKeyboardMouse.h"
|
||||
#include "LibusbDevice.h"
|
||||
#include "InputManager.h"
|
||||
|
||||
// These values are those used by Dolphin!
|
||||
|
@ -156,6 +157,7 @@ namespace Sdl
|
|||
else {
|
||||
XInput::GetDeviceChanges();
|
||||
DInput::GetDeviceChanges();
|
||||
Libusb::GetDeviceChanges();
|
||||
std::string port = std::to_string(*static_cast<int *>(Event.user.data1));
|
||||
int port_num, slot;
|
||||
PortStr2Int(port, &port_num, &slot);
|
||||
|
|
|
@ -84,6 +84,7 @@ static int g_DlgIndexes[] = {
|
|||
IDC_LOG_XMO,
|
||||
IDC_LOG_RINP,
|
||||
IDC_LOG_JVS,
|
||||
IDC_LOG_LIBUSB,
|
||||
// Kernel
|
||||
IDC_LOG_KRNL,
|
||||
IDC_LOG_LOG,
|
||||
|
@ -386,6 +387,7 @@ INT_PTR CALLBACK DlgLogConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM
|
|||
case IDC_LOG_DINP:
|
||||
case IDC_LOG_RINP:
|
||||
case IDC_LOG_XINP:
|
||||
case IDC_LOG_LIBUSB:
|
||||
case IDC_LOG_JVS:
|
||||
case IDC_LOG_SDL:
|
||||
case IDC_LOG_FILE:
|
||||
|
|
|
@ -508,6 +508,7 @@ BEGIN
|
|||
CONTROL "VSHCACHE",IDC_LOG_VSHCACHE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,68,140,53,10
|
||||
CONTROL "RINP",IDC_LOG_RINP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,202,195,32,10
|
||||
CONTROL "JVS",IDC_LOG_JVS,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,38,206,28,10
|
||||
CONTROL "LIBUSB",IDC_LOG_LIBUSB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,80,206,41,10
|
||||
END
|
||||
|
||||
IDD_ABOUT DIALOGEX 0, 0, 310, 177
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
#define IDC_LOG_VSHCACHE 962
|
||||
#define IDC_LOG_RINP 963
|
||||
#define IDC_LOG_JVS 964
|
||||
#define IDC_LOG_LIBUSB 965
|
||||
#define IDC_DEVICE_LIST_TOP_SLOT 995
|
||||
#define IDC_DEVICE_LIST_BOTTOM_SLOT 996
|
||||
#define IDC_DEVICE_TOP_SLOT 997
|
||||
|
|
Loading…
Reference in New Issue