Skip to content

Commit

Permalink
Logitech GT Force emulation #381
Browse files Browse the repository at this point in the history
  • Loading branch information
Matlo committed May 8, 2016
1 parent f7fe764 commit facfc35
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 0 deletions.
11 changes: 11 additions & 0 deletions config/gimx-config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ const long configFrame::ID_MENUITEMG27PS3 = wxNewId();
const long configFrame::ID_MENUITEMG29PS4 = wxNewId();
const long configFrame::ID_MENUITEMDFPS2 = wxNewId();
const long configFrame::ID_MENUITEMDFPPS2 = wxNewId();
const long configFrame::ID_MENUITEMGTFPS2 = wxNewId();
const long configFrame::ID_MENUITEM8 = wxNewId();
const long configFrame::ID_MENUITEM9 = wxNewId();
const long configFrame::ID_MENUITEM10 = wxNewId();
Expand Down Expand Up @@ -1190,6 +1191,8 @@ configFrame::configFrame(wxString file,wxWindow* parent,wxWindowID id)
MenuType->Append(MenuItemDfPs2);
MenuItemDfpPs2 = new wxMenuItem(MenuType, ID_MENUITEMDFPPS2, _("Driving Force Pro PS2"), wxEmptyString, wxITEM_RADIO);
MenuType->Append(MenuItemDfpPs2);
MenuItemGtfPs2 = new wxMenuItem(MenuType, ID_MENUITEMDFPPS2, _("GT Force PS2"), wxEmptyString, wxITEM_RADIO);
MenuType->Append(MenuItemGtfPs2);
MenuBar1->Append(MenuType, _("Type"));
MenuConfiguration = new wxMenu();
MenuConfiguration1 = new wxMenuItem(MenuConfiguration, ID_MENUITEM8, _("1"), wxEmptyString, wxITEM_RADIO);
Expand Down Expand Up @@ -1305,6 +1308,7 @@ configFrame::configFrame(wxString file,wxWindow* parent,wxWindowID id)
Connect(ID_MENUITEMG29PS4,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuTypeItemSelected);
Connect(ID_MENUITEMDFPS2,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuTypeItemSelected);
Connect(ID_MENUITEMDFPPS2,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuTypeItemSelected);
Connect(ID_MENUITEMGTFPS2,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuTypeItemSelected);
Connect(ID_MENUITEM8,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuItemConfiguration);
Connect(ID_MENUITEM9,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuItemConfiguration);
Connect(ID_MENUITEM10,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&configFrame::OnMenuItemConfiguration);
Expand Down Expand Up @@ -2205,6 +2209,9 @@ void configFrame::LoadControllerType()
case C_TYPE_DFP_PS2:
MenuType->Check(ID_MENUITEMDFPPS2, true);
break;
case C_TYPE_GTF_PS2:
MenuType->Check(ID_MENUITEMGTFPS2, true);
break;
case C_TYPE_NONE:
break;
}
Expand Down Expand Up @@ -4087,6 +4094,10 @@ void configFrame::OnMenuTypeItemSelected(wxCommandEvent& event)
{
newType = C_TYPE_DFP_PS2;
}
else if(MenuItemGtfPs2->IsChecked())
{
newType = C_TYPE_GTF_PS2;
}

Controller* controller = configFile.GetController(currentController);

Expand Down
2 changes: 2 additions & 0 deletions config/gimx-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ class configFrame: public wxFrame
static const long ID_MENUITEMG29PS4;
static const long ID_MENUITEMDFPS2;
static const long ID_MENUITEMDFPPS2;
static const long ID_MENUITEMGTFPS2;
static const long ID_MENUITEM8;
static const long ID_MENUITEM9;
static const long ID_MENUITEM10;
Expand Down Expand Up @@ -349,6 +350,7 @@ class configFrame: public wxFrame
wxMenuItem* MenuItemG29Ps4;
wxMenuItem* MenuItemDfPs2;
wxMenuItem* MenuItemDfpPs2;
wxMenuItem* MenuItemGtfPs2;
wxStaticText* IntensityButtonId;
wxGrid* GridMouseOption;
wxTextCtrl* MouseOptionsBuffer;
Expand Down
5 changes: 5 additions & 0 deletions config/wxsmith/configframe.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,11 @@
<handler function="OnMenuTypeItemSelected" entry="EVT_MENU" />
<radio>1</radio>
</object>
<object class="wxMenuItem" name="ID_MENUITEMGTFPS2" variable="MenuItemGtfPs2" member="yes">
<label>GT Force PS2</label>
<handler function="OnMenuTypeItemSelected" entry="EVT_MENU" />
<radio>1</radio>
</object>
</object>
<object class="wxMenu" variable="MenuConfiguration" member="yes">
<label>Profile</label>
Expand Down
1 change: 1 addition & 0 deletions shared/controller/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef enum
C_TYPE_G29_PS4,
C_TYPE_DF_PS2,
C_TYPE_DFP_PS2,
C_TYPE_GTF_PS2,
// <- add new types here
C_TYPE_NONE,
C_TYPE_MAX = C_TYPE_NONE,
Expand Down
38 changes: 38 additions & 0 deletions shared/controller/include/gtf_ps2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright (c) 2016 Mathieu Laurendeau <[email protected]>
License: GPLv3
*/

#ifndef GTF_PS2_H_
#define GTF_PS2_H_

#include <defs.h>
#include <stdint.h>

typedef enum
{
gtfPs2a_wheel = rel_axis_lstick_x,
gtfPs2a_triangle = abs_axis_7,
gtfPs2a_circle = abs_axis_8,
gtfPs2a_cross = abs_axis_9,
gtfPs2a_square = abs_axis_10,
gtfPs2a_l1 = abs_axis_11,
gtfPs2a_r1 = abs_axis_12,
gtfPs2a_gasPedal = abs_axis_17,
gtfPs2a_brakePedal = abs_axis_18,
} e_gtfPs2_axis_index;

/*
*
*/
typedef struct GIMX_PACKED
{
uint16_t buttonsAndWheel; // 10 LSB = wheel, 6 MSB = buttons
uint8_t : 8;
uint8_t pedals; // combined pedals
uint8_t gasPedal;
uint8_t brakePedal;
uint8_t : 8;
} s_report_gtfPs2;

#endif /* GTF_PS2_H_ */
2 changes: 2 additions & 0 deletions shared/controller/include/report.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <g29_ps4.h>
#include <df_ps2.h>
#include <dfp_ps2.h>
#include <gtf_ps2.h>

#define MAX_REPORTS 2

Expand All @@ -35,6 +36,7 @@ typedef union
s_report_g29Ps4 g29Ps4;
s_report_dfPs2 dfPs2;
s_report_dfpPs2 dfpPs2;
s_report_gtfPs2 gtfPs2;
} s_report;

typedef struct GIMX_PACKED
Expand Down
117 changes: 117 additions & 0 deletions shared/controller/src/gtf_ps2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
Copyright (c) 2016 Mathieu Laurendeau <[email protected]>
License: GPLv3
*/

#include <gtf_ps2.h>
#include <report.h>
#include <controller2.h>
#include <string.h>

#define GTF_SQUARE_MASK 0x0800
#define GTF_CROSS_MASK 0x0400
#define GTF_TRIANGLE_MASK 0x2000
#define GTF_CIRCLE_MASK 0x1000
#define GTF_R1_MASK 0x4000
#define GTF_L1_MASK 0x8000


static s_axis axes[AXIS_MAX] =
{
[gtfPs2a_wheel] = { .name = "wheel", .max_unsigned_value = MAX_AXIS_VALUE_10BITS },

[gtfPs2a_gasPedal] = { .name = "gas", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_brakePedal] = { .name = "brake", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_triangle] = { .name = "triangle", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_circle] = { .name = "circle", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_cross] = { .name = "cross", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_square] = { .name = "square", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_l1] = { .name = "l1", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },
[gtfPs2a_r1] = { .name = "r1", .max_unsigned_value = MAX_AXIS_VALUE_8BITS },

};

static s_axis_name_dir axis_name_dirs[] =
{
{.name = "wheel", {.axis = gtfPs2a_wheel, .props = AXIS_PROP_CENTERED}},

{.name = "gas", {.axis = gtfPs2a_gasPedal, .props = AXIS_PROP_POSITIVE}},
{.name = "brake", {.axis = gtfPs2a_brakePedal, .props = AXIS_PROP_POSITIVE}},

{.name = "r1", {.axis = gtfPs2a_r1, .props = AXIS_PROP_TOGGLE}},
{.name = "l1", {.axis = gtfPs2a_l1, .props = AXIS_PROP_TOGGLE}},
{.name = "circle", {.axis = gtfPs2a_circle, .props = AXIS_PROP_TOGGLE}},
{.name = "square", {.axis = gtfPs2a_square, .props = AXIS_PROP_TOGGLE}},
{.name = "cross", {.axis = gtfPs2a_cross, .props = AXIS_PROP_TOGGLE}},
{.name = "triangle", {.axis = gtfPs2a_triangle, .props = AXIS_PROP_TOGGLE}},
};

static s_report_gtfPs2 default_report =
{
.buttonsAndWheel = CENTER_AXIS_VALUE_10BITS,
.pedals = CENTER_AXIS_VALUE_8BITS,
.gasPedal = MAX_AXIS_VALUE_8BITS,
.brakePedal = MAX_AXIS_VALUE_8BITS,
};

static void init_report(s_report * report)
{
memcpy(report, &default_report, sizeof(default_report));
}

static unsigned int build_report(int axis[AXIS_MAX], s_report_packet report[MAX_REPORTS])
{
unsigned int index = 0;
report[index].length = sizeof(s_report_gtfPs2);
s_report_gtfPs2* gtfPs2 = &report[index].value.gtfPs2;

gtfPs2->buttonsAndWheel = clamp(0, axis[gtfPs2a_wheel] + CENTER_AXIS_VALUE_10BITS, MAX_AXIS_VALUE_10BITS);
gtfPs2->gasPedal = clamp(0, MAX_AXIS_VALUE_8BITS - axis[gtfPs2a_gasPedal], MAX_AXIS_VALUE_8BITS);
gtfPs2->brakePedal = clamp(0, MAX_AXIS_VALUE_8BITS - axis[gtfPs2a_brakePedal], MAX_AXIS_VALUE_8BITS);

gtfPs2->pedals = clamp(0, (axis[gtfPs2a_gasPedal] - axis[gtfPs2a_brakePedal]) / 2 + CENTER_AXIS_VALUE_8BITS, MAX_AXIS_VALUE_8BITS);

if (axis[gtfPs2a_square])
{
gtfPs2->buttonsAndWheel |= GTF_SQUARE_MASK;
}
if (axis[gtfPs2a_cross])
{
gtfPs2->buttonsAndWheel |= GTF_CROSS_MASK;
}
if (axis[gtfPs2a_triangle])
{
gtfPs2->buttonsAndWheel |= GTF_TRIANGLE_MASK;
}
if (axis[gtfPs2a_circle])
{
gtfPs2->buttonsAndWheel |= GTF_CIRCLE_MASK;
}
if (axis[gtfPs2a_r1])
{
gtfPs2->buttonsAndWheel |= GTF_R1_MASK;
}
if (axis[gtfPs2a_l1])
{
gtfPs2->buttonsAndWheel |= GTF_L1_MASK;
}

return index;
}

static s_controller controller =
{
.name = "GTF PS2",
.refresh_period = { .min_value = 10000, .default_value = 10000 },
.axes = axes,
.axis_name_dirs = { .nb = sizeof(axis_name_dirs)/sizeof(*axis_name_dirs), .values = axis_name_dirs },
.fp_build_report = build_report,
.fp_init_report = init_report,
};

void gtfPs2_init(void) __attribute__((constructor (101)));
void gtfPs2_init(void)
{
controller_register(C_TYPE_GTF_PS2, &controller);
}

0 comments on commit facfc35

Please sign in to comment.