add proper keymap support
This commit is contained in:
parent
b34bfd642f
commit
f921d658ae
@ -67,3 +67,18 @@ FREEPLAY 1
|
||||
|
||||
# Set if you want to see degug messages in the console
|
||||
DEBUG_MSGS 0
|
||||
|
||||
# Keymap settings
|
||||
# Configure the keymap using `xev`
|
||||
TEST_KEY 28
|
||||
PLAYER_1_START_KEY 10
|
||||
PLAYER_1_SERVICE_KEY 39
|
||||
PLAYER_1_COIN_KEY 14
|
||||
PLAYER_1_UP_KEY 111
|
||||
PLAYER_1_DOWN_KEY 116
|
||||
PLAYER_1_LEFT_KEY 113
|
||||
PLAYER_1_RIGHT_KEY 114
|
||||
PLAYER_1_BUTTON_1_KEY 24
|
||||
PLAYER_1_BUTTON_2_KEY 25
|
||||
PLAYER_1_BUTTON_3_KEY 26
|
||||
PLAYER_1_BUTTON_4_KEY 27
|
@ -397,6 +397,42 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
|
||||
else if (strcmp(command, "DEBUG_MSGS") == 0)
|
||||
config->showDebugMessages = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"TEST_KEY") == 0)
|
||||
config->keymap.test = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
//TODO: add config when supporting player2
|
||||
else if (strcmp(command,"PLAYER_1_START_KEY") == 0)
|
||||
config->keymap.player1.start = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_SERVICE_KEY") == 0)
|
||||
config->keymap.player1.service = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_COIN_KEY") == 0)
|
||||
config->keymap.player1.coin = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_UP_KEY") == 0)
|
||||
config->keymap.player1.up = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_DOWN_KEY") == 0)
|
||||
config->keymap.player1.down = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_LEFT_KEY") == 0)
|
||||
config->keymap.player1.left = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_RIGHT_KEY") == 0)
|
||||
config->keymap.player1.right = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_BUTTON_1_KEY") == 0)
|
||||
config->keymap.player1.button1 = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_BUTTON_2_KEY") == 0)
|
||||
config->keymap.player1.button2 = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_BUTTON_3_KEY") == 0)
|
||||
config->keymap.player1.button3 = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command,"PLAYER_1_BUTTON_4_KEY") == 0)
|
||||
config->keymap.player1.button4 = atoi(getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else
|
||||
printf("Error: Unknown settings command %s\n", command);
|
||||
}
|
||||
@ -404,6 +440,36 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
|
||||
return 0;
|
||||
}
|
||||
|
||||
KeyMapping getDefualtKeymap()
|
||||
{
|
||||
KeyMapping a;
|
||||
a.test = 28;
|
||||
a.player1.start = 10;
|
||||
a.player1.service = 39;
|
||||
a.player1.coin = 14;
|
||||
a.player1.up = 111;
|
||||
a.player1.down = 116;
|
||||
a.player1.left = 113;
|
||||
a.player1.right = 114;
|
||||
a.player1.button1 = 24;
|
||||
a.player1.button2 = 25;
|
||||
a.player1.button3 = 26;
|
||||
a.player1.button4 = 27;
|
||||
//TODO: Add keys when supporting player2
|
||||
a.player2.start = -1;
|
||||
a.player2.service = -1;
|
||||
a.player2.coin = -1;
|
||||
a.player2.up = -1;
|
||||
a.player2.down = -1;
|
||||
a.player2.left = -1;
|
||||
a.player2.right = -1;
|
||||
a.player2.button1 = -1;
|
||||
a.player2.button2 = -1;
|
||||
a.player2.button3 = -1;
|
||||
a.player2.button4 = -1;
|
||||
return a;
|
||||
}
|
||||
|
||||
int initConfig()
|
||||
{
|
||||
config.emulateRideboard = 0;
|
||||
@ -427,6 +493,7 @@ int initConfig()
|
||||
config.gameID = "XXXX";
|
||||
config.gameDVP = "DVP-XXXX";
|
||||
config.gameType = SHOOTING;
|
||||
config.keymap = getDefualtKeymap();
|
||||
if (detectGame(config.crc32) != 0)
|
||||
{
|
||||
printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32, config.crc32);
|
||||
|
@ -83,6 +83,30 @@ typedef enum
|
||||
FIGHTING
|
||||
} GameType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int service;
|
||||
unsigned int start;
|
||||
unsigned int coin;
|
||||
unsigned int up;
|
||||
unsigned int down;
|
||||
unsigned int left;
|
||||
unsigned int right;
|
||||
unsigned int button1;
|
||||
unsigned int button2;
|
||||
unsigned int button3;
|
||||
unsigned int button4;
|
||||
} PlayerKeyMapping;
|
||||
|
||||
// All keycode can be found using `xev` binary's debug output
|
||||
// NOTE: Maybe using tagged union for driving and shooting games
|
||||
typedef struct
|
||||
{
|
||||
unsigned int test;
|
||||
PlayerKeyMapping player1;
|
||||
PlayerKeyMapping player2;
|
||||
} KeyMapping;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int emulateRideboard;
|
||||
@ -100,6 +124,7 @@ typedef struct
|
||||
Colour lindberghColour;
|
||||
GameStatus gameStatus;
|
||||
GameType gameType;
|
||||
KeyMapping keymap;
|
||||
uint32_t crc32;
|
||||
GameRegion region;
|
||||
int freeplay;
|
||||
@ -109,6 +134,7 @@ typedef struct
|
||||
char* gameDVP;
|
||||
} EmulatorConfig;
|
||||
|
||||
KeyMapping getDefualtKeymap();
|
||||
int initConfig();
|
||||
EmulatorConfig *getConfig();
|
||||
char *getGameName();
|
||||
|
@ -28,161 +28,109 @@ int initInput()
|
||||
*/
|
||||
int XNextEventDriving(Display *display, XEvent *event_return, int returnValue)
|
||||
{
|
||||
switch (event_return->type)
|
||||
KeyMapping keymap = getConfig()->keymap;
|
||||
if (event_return->type == KeyPress || event_return->type == KeyRelease)
|
||||
{
|
||||
|
||||
case KeyRelease:
|
||||
case KeyPress:
|
||||
{
|
||||
switch (event_return->xkey.keycode)
|
||||
{
|
||||
case 28:
|
||||
if (event_return->xkey.keycode == keymap.test)
|
||||
setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress);
|
||||
break;
|
||||
case 39:
|
||||
else if (event_return->xkey.keycode == keymap.player1.service)
|
||||
setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress);
|
||||
break;
|
||||
case 14:
|
||||
else if (event_return->xkey.keycode == keymap.player1.coin)
|
||||
incrementCoin(PLAYER_1, event_return->type == KeyPress);
|
||||
break;
|
||||
case 15:
|
||||
else if (event_return->xkey.keycode == keymap.player2.coin)
|
||||
incrementCoin(PLAYER_2, event_return->type == KeyPress);
|
||||
break;
|
||||
case 111: // Up
|
||||
setAnalogue(ANALOGUE_2, event_return->type == KeyPress ? pow(2, 10) - 1 : 0);
|
||||
break;
|
||||
case 116: // Down
|
||||
setAnalogue(ANALOGUE_3, event_return->type == KeyPress ? pow(2, 10) - 1 : 0);
|
||||
break;
|
||||
case 113: // Left
|
||||
setAnalogue(ANALOGUE_1, event_return->type == KeyPress ? pow(2, 10) * 0.2 : pow(2, 10) * 0.5);
|
||||
break;
|
||||
case 114: // Right
|
||||
setAnalogue(ANALOGUE_1, event_return->type == KeyPress ? pow(2, 10) * 0.8 : pow(2, 10) * 0.5);
|
||||
break;
|
||||
case 10:
|
||||
else if (event_return->xkey.keycode == keymap.player1.up)
|
||||
setAnalogue(ANALOGUE_2,
|
||||
event_return->type == KeyPress ? pow(2, 10) - 1 : 0);
|
||||
else if (event_return->xkey.keycode == keymap.player1.down)
|
||||
setAnalogue(ANALOGUE_3,
|
||||
event_return->type == KeyPress ? pow(2, 10) - 1 : 0);
|
||||
else if (event_return->xkey.keycode == keymap.player1.left)
|
||||
setAnalogue(ANALOGUE_1, event_return->type == KeyPress
|
||||
? pow(2, 10) * 0.2
|
||||
: pow(2, 10) * 0.5);
|
||||
else if (event_return->xkey.keycode == keymap.player1.right)
|
||||
setAnalogue(ANALOGUE_1, event_return->type == KeyPress
|
||||
? pow(2, 10) * 0.8
|
||||
: pow(2, 10) * 0.5);
|
||||
else if (event_return->xkey.keycode == keymap.player1.start)
|
||||
setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress);
|
||||
break;
|
||||
case 24:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button1)
|
||||
setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress);
|
||||
break;
|
||||
case 25:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button2)
|
||||
setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress);
|
||||
break;
|
||||
case 26:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button3)
|
||||
setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress);
|
||||
break;
|
||||
case 27:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button4)
|
||||
setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress);
|
||||
break;
|
||||
case 29:
|
||||
else if (event_return->xkey.keycode == keymap.player1.up)
|
||||
setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress);
|
||||
break;
|
||||
case 30:
|
||||
else if (event_return->xkey.keycode == keymap.player1.down)
|
||||
setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress);
|
||||
break;
|
||||
case 31:
|
||||
else if (event_return->xkey.keycode == keymap.player1.left)
|
||||
setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress);
|
||||
break;
|
||||
case 32:
|
||||
else if (event_return->xkey.keycode == keymap.player1.right)
|
||||
setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Button mapping used for shooting games
|
||||
*/
|
||||
int XNextEventShooting(Display *display, XEvent *event_return, int returnValue)
|
||||
int XNextEventShooting(Display *display, XEvent *event_return, int returnValue)
|
||||
{
|
||||
switch (event_return->type)
|
||||
KeyMapping keymap = getConfig()->keymap;
|
||||
if (event_return->type == KeyPress || event_return->type == KeyRelease)
|
||||
{
|
||||
|
||||
case KeyRelease:
|
||||
case KeyPress:
|
||||
{
|
||||
switch (event_return->xkey.keycode)
|
||||
{
|
||||
case 28:
|
||||
if (event_return->xkey.keycode == keymap.test)
|
||||
setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress);
|
||||
break;
|
||||
case 39:
|
||||
else if (event_return->xkey.keycode == keymap.player1.service)
|
||||
setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress);
|
||||
break;
|
||||
case 14:
|
||||
else if (event_return->xkey.keycode == keymap.player1.coin)
|
||||
incrementCoin(PLAYER_1, event_return->type == KeyPress);
|
||||
break;
|
||||
case 15:
|
||||
else if (event_return->xkey.keycode == keymap.player2.coin)
|
||||
incrementCoin(PLAYER_2, event_return->type == KeyPress);
|
||||
break;
|
||||
case 111:
|
||||
setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress);
|
||||
break;
|
||||
case 116:
|
||||
setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress);
|
||||
break;
|
||||
case 113:
|
||||
setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress);
|
||||
break;
|
||||
case 114:
|
||||
setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress);
|
||||
break;
|
||||
case 10:
|
||||
else if (event_return->xkey.keycode == keymap.player1.start)
|
||||
setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress);
|
||||
break;
|
||||
case 24:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button1)
|
||||
setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress);
|
||||
break;
|
||||
case 25:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button2)
|
||||
setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress);
|
||||
break;
|
||||
case 26:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button3)
|
||||
setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress);
|
||||
break;
|
||||
case 27:
|
||||
else if (event_return->xkey.keycode == keymap.player1.button4)
|
||||
setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
else if (event_return->xkey.keycode == keymap.player1.up)
|
||||
setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress);
|
||||
else if (event_return->xkey.keycode == keymap.player1.down)
|
||||
setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress);
|
||||
else if (event_return->xkey.keycode == keymap.player1.left)
|
||||
setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress);
|
||||
else if (event_return->xkey.keycode == keymap.player1.right)
|
||||
setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress);
|
||||
}
|
||||
else if (event_return->type == MotionNotify)
|
||||
{
|
||||
setAnalogue(ANALOGUE_1, ((double)event_return->xmotion.x / (double)getConfig()->width) * pow(2, 10));
|
||||
setAnalogue(ANALOGUE_2, ((double)event_return->xmotion.y / (double)getConfig()->height) * pow(2, 10));
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
setAnalogue(ANALOGUE_1,
|
||||
((double)event_return->xmotion.x / (double)getConfig()->width) *
|
||||
pow(2, 10));
|
||||
setAnalogue(ANALOGUE_2, ((double)event_return->xmotion.y /
|
||||
(double)getConfig()->height) *
|
||||
pow(2, 10));
|
||||
}
|
||||
else if (event_return->type == ButtonPress || event_return->type == ButtonRelease)
|
||||
{
|
||||
switch (event_return->xbutton.button)
|
||||
{
|
||||
case 1: // Trigger
|
||||
// Trigger
|
||||
if (event_return->xbutton.button == 1)
|
||||
setSwitch(PLAYER_1, BUTTON_1, event_return->type == ButtonPress);
|
||||
break;
|
||||
case 3: // Reload
|
||||
// Reload
|
||||
else if (event_return->xbutton.button == 3)
|
||||
setSwitch(PLAYER_1, BUTTON_2, event_return->type == ButtonPress);
|
||||
break;
|
||||
case 9: // Gun Button
|
||||
// Gun button
|
||||
else if (event_return->xbutton.button == 2)
|
||||
setSwitch(PLAYER_1, BUTTON_3, event_return->type == ButtonPress);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user