1
0
mirror of synced 2024-11-13 14:30:46 +01:00

add proper keymap support

This commit is contained in:
Caviar-X 2024-02-24 22:03:48 +08:00
parent b34bfd642f
commit f921d658ae
4 changed files with 173 additions and 117 deletions

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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;
}