1
0
mirror of synced 2025-02-28 14:40:27 +01:00

Rework settings, add border controls

This commit is contained in:
Bobby Dilley 2025-01-04 22:43:08 +00:00
parent 3ecf3a765f
commit 8ed30d6aec
7 changed files with 231 additions and 144 deletions

View File

@ -1,135 +1,98 @@
# SEGA Lindbergh Emulator Configuration File # SEGA Lindbergh Emulator Configuration File
# By the Lindbergh Development Team 2024-2025 # By the Lindbergh Development Team 2024-2025
# All config options here are commented out by default.
# Uncomment them to enable that configuration override option.
# Set the requested dip switch width here # Set the requested dip switch width here
# Default: 640 WIDTH AUTO
# WIDTH 1360
# Set the requested dip switch height here # Set the requested dip switch height here
# Default: 480 HEIGHT AUTO
# HEIGHT 768
# Set if the emulator should go full screen # Set if the emulator should go full screen
# Default: 0 FULLSCREEN 0
# FULLSCREEN 0
# Sets the Input Mode # Sets the Input Mode
# Mode 0: will use both SDL/X11 and EVDEV inputs (default) # Mode 0: will use both SDL/X11 and EVDEV inputs (default)
# Mode 1: will use SDL/X11 inputs only # Mode 1: will use SDL/X11 inputs only
# Mode 2: will use EVDEV raw inputs only, which should be configured at the bottom of the settings file # Mode 2: will use EVDEV raw inputs only, which should be configured at the bottom of the settings file
# Default: 0 INPUT_MODE 0
# INPUT_MODE 0
# Set to 1 if you want to disable SDL (Fixes SRTV boost bar) # Set to 1 if you want to disable SDL (Fixes SRTV boost bar)
# Default: 0 NO_SDL 0
# NO_SDL 1
# Set the Region ( JP/US/EX ) # Set the Region ( JP/US/EX )
# Default: JP REGION EX
# REGION EX
# Set if you want the game to be Free Play # Set if you want the game to be Free Play
# Default: 0 FREEPLAY 1
# FREEPLAY 1
# Set the different keys used to control the games.
# You can find out the key numbers by running `xev` on linux.
# 28=t, 10=1, 39=s, 14=5, 111=Up, 116=Down, 113=Left, 114=Right, 24=q, 25=w, 26=e, 27=r
# 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
# Set if the emulator should emulate JVS and use the keyboard/mouse for controls. # Set if the emulator should emulate JVS and use the keyboard/mouse for controls.
# If this is set to 0, then the emulator will route the traffic to the serial device # If this is set to 0, then the emulator will route the traffic to the serial device
# defined in JVS_PATH if it has been defined. # defined in JVS_PATH if it has been defined.
# Default: 1 EMULATE_JVS 1
# EMULATE_JVS 0
# Set if the emulator should emulate the rideboard used in the special games here # Set if the emulator should emulate the rideboard used in the special games here
# If this is set to 0, then the emulator will route the traffic to the serial device # If this is set to 0, then the emulator will route the traffic to one of the serial ports
# defined in RIDEBOARD_PATH if it has been defined. EMULATE_RIDEBOARD AUTO
# Default: 0 (unless set by game)
# EMULATE_RIDEBOARD 1
# Set if the emulator should emulate the driveboard used in driving games here # Set if the emulator should emulate the driveboard used in driving games here
# If this is set to 0, then the emulator will route the traffic to the serial device # If this is set to 0, then the emulator will route the traffic to one of the serial ports
# defined in DRIVEBOARD_PATH if it has been defined. EMULATE_DRIVEBOARD AUTO
# Default: 0 (unless set by game)
# EMULATE_DRIVEBOARD 1
# Set if the emulator should emulate the motion board from Outrun 2 SP SDX here # Set if the emulator should emulate the motion board from Outrun 2 SP SDX here
# If this is set to 0, then the emulator will route the traffic to the serial device # If this is set to 0, then the emulator will route the traffic to one of the serial ports
# defined in MOTIONBOARD_PATH if it has been defined. EMULATE_MOTIONBOARD AUTO
# Default: 0 (unless set by game)
# EMULATE_MOTIONBOARD 1
# Define the path to pass the JVS packets to if JVS is not being emulated. # Define the path to pass the JVS packets to if JVS is not being emulated.
# Default: /dev/ttyUSB0 JVS_PATH /dev/ttyUSB0
# JVS_PATH /dev/ttyUSB0
# Define the path to pass the first serial port to if it's not being emulated. # Define the path to pass the first serial port to if it's not being emulated.
# Default: /dev/ttyS0 SERIAL_1_PATH /dev/ttyUSB0
# SERIAL_1_PATH /dev/ttyUSB0
# Define the path to pass the second serial port to if it's not being emulated. # Define the path to pass the second serial port to if it's not being emulated.
# Default: /dev/ttyS1 SERIAL_2_PATH /dev/ttyUSB0
# SERIAL_2_PATH /dev/ttyUSB0
# Define the path to the sram.bin file # Define the path to the sram.bin file
# Default: sram.bin SRAM_PATH sram.bin
# SRAM_PATH sram.bin
# Define the path to the eeprom.bin file # Define the path to the eeprom.bin file
# Default: eeprom.bin EEPROM_PATH eeprom.bin
# EEPROM_PATH eeprom.bin
# Set the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI(AMD-PRO) / 4 = Intel / 5 = Unknown) # Set the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI(AMD-PRO) / 4 = Intel / 5 = Unknown)
# Default: 0 GPU_VENDOR 0
# GPU_VENDOR 0
# Set if you want to see debug messages in the console # Set if you want to see debug messages in the console
# Default: 0 DEBUG_MSGS 0
# DEBUG_MSGS 1
# Set if you'd like to add a border for optical light gun tracking
BORDER_ENABLED 0
# Set the thickness of the white border as a percentage of the width of the screen
WHITE_BORDER_PERCENTAGE 2
# Set the thickness of the black border which sits around the
# white border as a percentage of the width of the screen
BLACK_BORDER_PERCENTAGE 0
# Set to true if you experience flickering in hummer # Set to true if you experience flickering in hummer
# Default: 0 HUMMER_FLICKER_FIX 0
# HUMMER_FLICKER_FIX 1
# Set to keep the aspect ratio (4:3) in games like Sega Race TV and Primeval Hunt # Set to keep the aspect ratio (4:3) in games like Sega Race TV and Primeval Hunt
# Default: 0 KEEP_ASPECT_RATIO 0
# KEEP_ASPECT_RATIO 1
# Set to 0 if you want to disable the Glare effect in OutRun # Set to 0 if you want to disable the Glare effect in OutRun
# Default: 0 OUTRUN_LENS_GLARE_ENABLED 1
# OUTRUN_LENS_GLARE_ENABLED 0
# Set to 1 if you want to limit the FPS in games that are not limited like OutRun2
# Default: 0
# FPS_LIMITER_ENABLED 1
# Set the target FPS (will only work if FPS_LIMITER_ENABLED = 1)
# Default: 60
# FPS_TARGET 60
# Set to 1 to bypass cabinet checks including drive board and tower in Outrun 2 SP SDX # Set to 1 to bypass cabinet checks including drive board and tower in Outrun 2 SP SDX
# Default: 0 SKIP_OUTRUN_CABINET_CHECK 0
# SKIP_OUTRUN_CABINET_CHECK 0
# Set to 1 if you want to limit the FPS in games that are not limited like OutRun2
FPS_LIMITER_ENABLED 0
# Set the target FPS (will only work if FPS_LIMITER_ENABLED = 1)
FPS_TARGET 60
# Set to 1 if you want to render LGJ using the mesa patches instead of nVidia (fixes some glitches) # Set to 1 if you want to render LGJ using the mesa patches instead of nVidia (fixes some glitches)
# Default: 1 LGJ_RENDER_WITH_MESA 1
# LGJ_RENDER_WITH_MESA 1
# Set the Primeval Hunt mode # Set the Primeval Hunt mode
# Mode 0: Leaves everything as default # Mode 0: Leaves everything as default
@ -137,16 +100,30 @@
# Mode 2: Side by Side # Mode 2: Side by Side
# Mode 3: 3ds mode 1 (Touch screen to the right) # Mode 3: 3ds mode 1 (Touch screen to the right)
# Mode 4: 3ds mode 2 (Touch screen to the bottom) # Mode 4: 3ds mode 2 (Touch screen to the bottom)
# Default: 1 PRIMEVAL_HUNT_MODE 1
# PRIMEVAL_HUNT_MODE 1
# Hacky way to make MJ4 work at prohibited times? # Hacky way to make MJ4 work at prohibited times?
# MJ4_ENABLED_ALL_THE_TIME 1 # MJ4_ENABLED_ALL_THE_TIME 1
# Set the colour of the lindbergh to change the Segaboot logo # Set the colour of the lindbergh to change the Segaboot logo
# Possible colours are: YELLOW, RED, BLUE, SILVER, REDEX # Possible colours are: YELLOW, RED, BLUE, SILVER, REDEX
# Default: YELLOW LINDBERGH_COLOUR YELLOW
# LINDBERGH_COLOUR YELLOW
# X11 MODE (Input Mode 1)
# To find the value pairs for these run `xev` on linux
TEST_KEY 28 # t
PLAYER_1_START_KEY 10 # 1
PLAYER_1_SERVICE_KEY 39 # s
PLAYER_1_COIN_KEY 14 # 5
PLAYER_1_UP_KEY 111 # Up
PLAYER_1_DOWN_KEY 116 # Down
PLAYER_1_LEFT_KEY 113 # Left
PLAYER_1_RIGHT_KEY 114 # Right
PLAYER_1_BUTTON_1_KEY 24 # q
PLAYER_1_BUTTON_2_KEY 25 # w
PLAYER_1_BUTTON_3_KEY 26 # e
PLAYER_1_BUTTON_4_KEY 27 # r
# EVDEV MODE (Input Mode 2) # EVDEV MODE (Input Mode 2)
# To find the value pairs for these run ./lindbergh --list-controllers # To find the value pairs for these run ./lindbergh --list-controllers

57
src/lindbergh/border.c Normal file
View File

@ -0,0 +1,57 @@
#include <GL/gl.h>
#include "border.h"
void drawBorderWithOffset(int width, int height, float borderPercentage, float offsetPercentage, GLfloat *color)
{
// Border thickness based on the percentage of the width/height
int borderWidth = (int)(width * borderPercentage); // Border width as a percentage of the screen width
int borderHeight = borderWidth;
// Offset based on the percentage of the width/height
int offsetX = (int)(width * offsetPercentage); // Horizontal offset from the screen edge
int offsetY = offsetX;
// Set the clear color based on the color parameter
glClearColor(color[0], color[1], color[2], color[3]);
// Left side (borderWidth wide from top to bottom, starting from the left edge with offset)
glScissor(offsetX, offsetY, borderWidth,
height - 2 * offsetY); // X = offsetX, Y = offsetY, Width = borderWidth, Height = (height - 2 * offsetY)
glClear(GL_COLOR_BUFFER_BIT);
// Right side (borderWidth wide from top to bottom, starting from the right edge with offset)
glScissor(width - borderWidth - offsetX, offsetY, borderWidth,
height -
2 * offsetY); // X = (width - borderWidth - offsetX), Y = offsetY, Width = borderWidth, Height = (height - 2 * offsetY)
glClear(GL_COLOR_BUFFER_BIT);
// Top side (borderHeight wide from left to right, starting from the top edge with offset)
glScissor(offsetX, offsetY, width - 2 * offsetX,
borderHeight); // X = offsetX, Y = offsetY, Width = (width - 2 * offsetX), Height = borderHeight
glClear(GL_COLOR_BUFFER_BIT);
// Bottom side (borderHeight wide from left to right, starting from the bottom edge with offset)
glScissor(offsetX, height - borderHeight - offsetY, width - 2 * offsetX,
borderHeight); // X = offsetX, Y = (height - borderHeight - offsetY), Width = (width - 2 * offsetX), Height = borderHeight
glClear(GL_COLOR_BUFFER_BIT);
}
void drawGameBorder(int width, int height, float whiteBorderPercentage, float blackBorderPercentage)
{
// Store the old clear colour
GLfloat originalClearColour[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, originalClearColour);
GLfloat blackColour[4] = {0.0, 0.0, 0.0, 0.0};
GLfloat whiteColour[4] = {1.0, 1.0, 1.0, 0.0};
glEnable(GL_SCISSOR_TEST);
drawBorderWithOffset(width, height, whiteBorderPercentage, blackBorderPercentage, whiteColour);
drawBorderWithOffset(width, height, blackBorderPercentage, 0, blackColour);
glDisable(GL_SCISSOR_TEST);
glClearColor(originalClearColour[0], originalClearColour[1], originalClearColour[2], originalClearColour[3]);
}

6
src/lindbergh/border.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef BORDER_H
#define BORDER_H
void drawGameBorder(int width, int height, float whiteBorderPercentage, float blackBorderPercentage);
#endif // BORDER_H

View File

@ -367,6 +367,8 @@ static int detectGame(uint32_t elf_crc)
config.gameNativeResolutions = ""; config.gameNativeResolutions = "";
config.gameType = SHOOTING; config.gameType = SHOOTING;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1360;
config.height = 768;
return 0; return 0;
} }
break; break;
@ -381,6 +383,8 @@ static int detectGame(uint32_t elf_crc)
config.gameNativeResolutions = ""; config.gameNativeResolutions = "";
config.gameType = SHOOTING; config.gameType = SHOOTING;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1024;
config.height = 768;
return 0; return 0;
} }
break; break;
@ -843,6 +847,8 @@ static int detectGame(uint32_t elf_crc)
config.gameNativeResolutions = ""; config.gameNativeResolutions = "";
config.gameType = SHOOTING; config.gameType = SHOOTING;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1360;
config.height = 768;
return 0; return 0;
} }
break; break;
@ -939,6 +945,24 @@ const char *getGpuTypeString(GpuType gpuType)
return GpuTypeStrings[gpuType]; return GpuTypeStrings[gpuType];
} }
void toLowerCase(char *str) {
while (*str) { // Iterate through the string until the null terminator
*str = tolower((unsigned char)*str); // Convert each character to lowercase
str++; // Move to the next character
}
}
int getNextIntOrAuto(char *saveptr, int defaultValue) {
char nextToken[256];
strcpy(nextToken, getNextToken(NULL, " ", &saveptr));
toLowerCase(nextToken);
if(strcmp(nextToken, "auto") == 0)
return defaultValue;
return atoi(nextToken);
}
int readConfig(FILE *configFile, EmulatorConfig *config) int readConfig(FILE *configFile, EmulatorConfig *config)
{ {
char buffer[MAX_LINE_LENGTH]; char buffer[MAX_LINE_LENGTH];
@ -953,11 +977,15 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
char *command = getNextToken(buffer, " ", &saveptr); char *command = getNextToken(buffer, " ", &saveptr);
if (strcmp(command, "WIDTH") == 0) if (strcmp(command, "WIDTH") == 0) {
config->width = atoi(getNextToken(NULL, " ", &saveptr)); int defaultValue = config->width;
config->width = getNextIntOrAuto(saveptr, defaultValue);
}
else if (strcmp(command, "HEIGHT") == 0) else if (strcmp(command, "HEIGHT") == 0) {
config->height = atoi(getNextToken(NULL, " ", &saveptr)); int defaultValue = config->height;
config->height = getNextIntOrAuto(saveptr, defaultValue);
}
else if (strcmp(command, "EEPROM_PATH") == 0) else if (strcmp(command, "EEPROM_PATH") == 0)
strcpy(config->eepromPath, getNextToken(NULL, " ", &saveptr)); strcpy(config->eepromPath, getNextToken(NULL, " ", &saveptr));
@ -965,14 +993,20 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
else if (strcmp(command, "SRAM_PATH") == 0) else if (strcmp(command, "SRAM_PATH") == 0)
strcpy(config->sramPath, getNextToken(NULL, " ", &saveptr)); strcpy(config->sramPath, getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "EMULATE_RIDEBOARD") == 0) else if (strcmp(command, "EMULATE_RIDEBOARD") == 0) {
config->emulateRideboard = atoi(getNextToken(NULL, " ", &saveptr)); int defaultValue = config->emulateRideboard;
config->emulateRideboard = getNextIntOrAuto(saveptr, defaultValue);
}
else if (strcmp(command, "EMULATE_DRIVEBOARD") == 0) else if (strcmp(command, "EMULATE_DRIVEBOARD") == 0) {
config->emulateDriveboard = atoi(getNextToken(NULL, " ", &saveptr)); int defaultValue = config->emulateDriveboard;
config->emulateDriveboard = getNextIntOrAuto(saveptr, defaultValue);
}
else if (strcmp(command, "EMULATE_MOTIONBOARD") == 0) else if (strcmp(command, "EMULATE_MOTIONBOARD") == 0) {
config->emulateMotionboard = atoi(getNextToken(NULL, " ", &saveptr)); int defaultValue = config->emulateMotionboard;
config->emulateMotionboard = getNextIntOrAuto(saveptr, defaultValue);
}
else if (strcmp(command, "FULLSCREEN") == 0) else if (strcmp(command, "FULLSCREEN") == 0)
config->fullscreen = atoi(getNextToken(NULL, " ", &saveptr)); config->fullscreen = atoi(getNextToken(NULL, " ", &saveptr));
@ -1254,6 +1288,15 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
else if (strcmp(command, "SKIP_OUTRUN_CABINET_CHECK") == 0) else if (strcmp(command, "SKIP_OUTRUN_CABINET_CHECK") == 0)
config->skipOutrunCabinetCheck = atoi(getNextToken(NULL, " ", &saveptr)); config->skipOutrunCabinetCheck = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "BORDER_ENABLED") == 0)
config->borderEnabled = atoi(getNextToken(NULL, " ", &saveptr));
else if (strcmp(command, "WHITE_BORDER_PERCENTAGE") == 0)
config->whiteBorderPercentage = (float) atoi(getNextToken(NULL, " ", &saveptr)) / 100.0;
else if (strcmp(command, "BLACK_BORDER_PERCENTAGE") == 0)
config->blackBorderPercentage = (float) atoi(getNextToken(NULL, " ", &saveptr)) / 100.0;
else if (strcmp(command, "INPUT_MODE") == 0) else if (strcmp(command, "INPUT_MODE") == 0)
config->inputMode = atoi(getNextToken(NULL, " ", &saveptr)); config->inputMode = atoi(getNextToken(NULL, " ", &saveptr));
@ -1313,7 +1356,7 @@ int initConfig()
strcpy(config.serial2Path, "/dev/ttyS1"); strcpy(config.serial2Path, "/dev/ttyS1");
config.width = 640; config.width = 640;
config.height = 480; config.height = 480;
config.region = 0; config.region = EX;
config.freeplay = -1; config.freeplay = -1;
config.showDebugMessages = 0; config.showDebugMessages = 0;
config.hummerFlickerFix = 0; config.hummerFlickerFix = 0;
@ -1340,6 +1383,9 @@ int initConfig()
memset(&config.arcadeInputs.analogue_deadzone_end, 0, sizeof(config.arcadeInputs.analogue_deadzone_end)); memset(&config.arcadeInputs.analogue_deadzone_end, 0, sizeof(config.arcadeInputs.analogue_deadzone_end));
config.crc32 = elf_crc; config.crc32 = elf_crc;
config.skipOutrunCabinetCheck = 0; config.skipOutrunCabinetCheck = 0;
config.borderEnabled = 0;
config.whiteBorderPercentage = 0.02;
config.blackBorderPercentage = 0.0;
if (detectGame(config.crc32) != 0) if (detectGame(config.crc32) != 0)
{ {
log_warn("Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: " log_warn("Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: "

View File

@ -103,9 +103,9 @@ typedef enum
typedef enum typedef enum
{ {
JP, JP = 0,
US, US = 1,
EX EX = 2
} GameRegion; } GameRegion;
typedef enum typedef enum
@ -261,6 +261,9 @@ typedef struct
ArcadeInputs arcadeInputs; ArcadeInputs arcadeInputs;
int inputMode; // 0 = both, 1 = SDL/X11 only, 2 = EVDEV only int inputMode; // 0 = both, 1 = SDL/X11 only, 2 = EVDEV only
int skipOutrunCabinetCheck; int skipOutrunCabinetCheck;
float whiteBorderPercentage;
float blackBorderPercentage;
int borderEnabled;
} EmulatorConfig; } EmulatorConfig;
KeyMapping getDefaultKeymap(); KeyMapping getDefaultKeymap();

View File

@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#include "fps_limiter.h" #include "fps_limiter.h"
#include "sdlcalls.h" #include "sdlcalls.h"
#include "border.h"
extern SDL_Window *SDLwindow; extern SDL_Window *SDLwindow;
extern char SDLgameTitle[]; extern char SDLgameTitle[];
@ -88,14 +89,19 @@ void FGAPIENTRY glutMainLoopEvent(void)
void FGAPIENTRY glutSwapBuffers(void) void FGAPIENTRY glutSwapBuffers(void)
{ {
if (getConfig()->noSDL) EmulatorConfig *config = getConfig();
if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
if (config->noSDL)
{ {
void FGAPIENTRY (*_glutSwapBuffers)(void) = dlsym(RTLD_NEXT, "glutSwapBuffers"); void FGAPIENTRY (*_glutSwapBuffers)(void) = dlsym(RTLD_NEXT, "glutSwapBuffers");
_glutSwapBuffers(); _glutSwapBuffers();
return; return;
} }
int gId = getConfig()->crc32; int gId = config->crc32;
if (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA || gId == OUTRUN_2_SP_SDX_REVA_TEST || gId == OUTRUN_2_SP_SDX_REVA_TEST2 || if (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA || gId == OUTRUN_2_SP_SDX_REVA_TEST || gId == OUTRUN_2_SP_SDX_REVA_TEST2 ||
gId == OUTRUN_2_SP_SDX_TEST) gId == OUTRUN_2_SP_SDX_TEST)
{ {
@ -104,7 +110,7 @@ void FGAPIENTRY glutSwapBuffers(void)
SDL_GL_SwapWindow(SDLwindow); SDL_GL_SwapWindow(SDLwindow);
if (getConfig()->fpsLimiter) if (config->fpsLimiter)
{ {
fpsLimit.frameStart = Clock_now(); fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit); FpsLimiter(&fpsLimit);
@ -290,8 +296,7 @@ void FGAPIENTRY glutKeyboardFunc(void (*callback)(unsigned char, int, int))
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutKeyboardFunc)(void (*callback)(unsigned char, int, int)) = void FGAPIENTRY (*_glutKeyboardFunc)(void (*callback)(unsigned char, int, int)) = dlsym(RTLD_NEXT, "glutKeyboardFunc");
dlsym(RTLD_NEXT, "glutKeyboardFunc");
_glutKeyboardFunc(callback); _glutKeyboardFunc(callback);
return; return;
} }
@ -302,8 +307,7 @@ void FGAPIENTRY glutKeyboardUpFunc(void (*callback)(unsigned char, int, int))
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutKeyboardUpFunc)(void (*callback)(unsigned char, int, int)) = void FGAPIENTRY (*_glutKeyboardUpFunc)(void (*callback)(unsigned char, int, int)) = dlsym(RTLD_NEXT, "glutKeyboardUpFunc");
dlsym(RTLD_NEXT, "glutKeyboardUpFunc");
_glutKeyboardUpFunc(callback); _glutKeyboardUpFunc(callback);
return; return;
} }
@ -358,8 +362,7 @@ void FGAPIENTRY glutPassiveMotionFunc(void (*callback)(int, int))
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutPassiveMotionFunc)(void (*callback)(int, int)) = void FGAPIENTRY (*_glutPassiveMotionFunc)(void (*callback)(int, int)) = dlsym(RTLD_NEXT, "glutPassiveMotionFunc");
dlsym(RTLD_NEXT, "glutPassiveMotionFunc");
_glutPassiveMotionFunc(callback); _glutPassiveMotionFunc(callback);
return; return;
} }
@ -414,8 +417,7 @@ void FGAPIENTRY glutSolidSphere(double radius, GLint slices, GLint stacks)
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutSolidSphere)(double radius, GLint slices, GLint stacks) = void FGAPIENTRY (*_glutSolidSphere)(double radius, GLint slices, GLint stacks) = dlsym(RTLD_NEXT, "glutSolidSphere");
dlsym(RTLD_NEXT, "glutSolidSphere");
_glutSolidSphere(radius, slices, stacks); _glutSolidSphere(radius, slices, stacks);
return; return;
} }
@ -426,8 +428,7 @@ void FGAPIENTRY glutWireSphere(double radius, GLint slices, GLint stacks)
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutWireSphere)(double radius, GLint slices, GLint stacks) = void FGAPIENTRY (*_glutWireSphere)(double radius, GLint slices, GLint stacks) = dlsym(RTLD_NEXT, "glutWireSphere");
dlsym(RTLD_NEXT, "glutWireSphere");
_glutWireSphere(radius, slices, stacks); _glutWireSphere(radius, slices, stacks);
return; return;
} }
@ -438,8 +439,7 @@ void FGAPIENTRY glutWireCone(double base, double height, GLint slices, GLint sta
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutWireCone)(double base, double height, GLint slices, GLint stacks) = void FGAPIENTRY (*_glutWireCone)(double base, double height, GLint slices, GLint stacks) = dlsym(RTLD_NEXT, "glutWireCone");
dlsym(RTLD_NEXT, "glutWireCone");
_glutWireCone(base, height, slices, stacks); _glutWireCone(base, height, slices, stacks);
return; return;
} }
@ -450,8 +450,7 @@ void FGAPIENTRY glutSolidCone(double base, double height, GLint slices, GLint st
{ {
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutSolidCone)(double base, double height, GLint slices, GLint stacks) = void FGAPIENTRY (*_glutSolidCone)(double base, double height, GLint slices, GLint stacks) = dlsym(RTLD_NEXT, "glutSolidCone");
dlsym(RTLD_NEXT, "glutSolidCone");
_glutSolidCone(base, height, slices, stacks); _glutSolidCone(base, height, slices, stacks);
return; return;
} }

View File

@ -24,6 +24,7 @@
#include "sdlcalls.h" #include "sdlcalls.h"
#include "patch.h" #include "patch.h"
#include "config.h" #include "config.h"
#include "border.h"
bool sdlGame = false; bool sdlGame = false;
extern SDL_Window *SDLwindow; extern SDL_Window *SDLwindow;
@ -35,6 +36,11 @@ extern Window win;
void glXToSDLSwapBuffers(Display *dpy, GLXDrawable drawable) void glXToSDLSwapBuffers(Display *dpy, GLXDrawable drawable)
{ {
pollEvents(); pollEvents();
EmulatorConfig *config = getConfig();
if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
SDL_GL_SwapWindow(SDLwindow); SDL_GL_SwapWindow(SDLwindow);
if (getConfig()->fpsLimiter) if (getConfig()->fpsLimiter)
{ {
@ -65,8 +71,8 @@ XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
return _glXChooseVisual(dpy, screen, attribList); return _glXChooseVisual(dpy, screen, attribList);
} }
void GLAPIENTRY openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, void GLAPIENTRY openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message,
const GLchar *message, const void *userParam) const void *userParam)
{ {
if (id == 1099) if (id == 1099)
return; return;
@ -89,9 +95,14 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
{ {
void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable) = dlsym(RTLD_NEXT, "glXSwapBuffers"); void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable) = dlsym(RTLD_NEXT, "glXSwapBuffers");
int gId = getConfig()->crc32; EmulatorConfig *config = getConfig();
if (getConfig()->noSDL && (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA ||
gId == OUTRUN_2_SP_SDX_REVA_TEST || gId == OUTRUN_2_SP_SDX_REVA_TEST2 || gId == OUTRUN_2_SP_SDX_TEST)) if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
int gId = config->crc32;
if (getConfig()->noSDL && (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA || gId == OUTRUN_2_SP_SDX_REVA_TEST ||
gId == OUTRUN_2_SP_SDX_REVA_TEST2 || gId == OUTRUN_2_SP_SDX_TEST))
{ {
XEvent event; XEvent event;
while (XPending(dpy)) while (XPending(dpy))
@ -100,7 +111,7 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
} }
} }
_glXSwapBuffers(dpy, drawable); _glXSwapBuffers(dpy, drawable);
if (getConfig()->fpsLimiter) if (config->fpsLimiter)
{ {
fpsLimit.frameStart = Clock_now(); fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit); FpsLimiter(&fpsLimit);
@ -139,8 +150,7 @@ GLXContext glXGetCurrentContext()
GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list) GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
{ {
GLXPbuffer (*_glXCreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attrib_list) = GLXPbuffer (*_glXCreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attrib_list) = dlsym(RTLD_NEXT, "glXCreatePbuffer");
dlsym(RTLD_NEXT, "glXCreatePbuffer");
if (sdlGame) if (sdlGame)
return 0; return 0;
return _glXCreatePbuffer(dpy, config, attrib_list); return _glXCreatePbuffer(dpy, config, attrib_list);
@ -164,8 +174,7 @@ void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
{ {
XVisualInfo *(*_glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config) = XVisualInfo *(*_glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config) = dlsym(RTLD_NEXT, "glXGetVisualFromFBConfig");
dlsym(RTLD_NEXT, "glXGetVisualFromFBConfig");
if (sdlGame) if (sdlGame)
return 0; return 0;
return _glXGetVisualFromFBConfig(dpy, config); return _glXGetVisualFromFBConfig(dpy, config);
@ -203,9 +212,9 @@ GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attrib_list,
if (__NV_PRIME_RENDER_OFFLOAD == NULL) if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " "; __NV_PRIME_RENDER_OFFLOAD = " ";
if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) && if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) &&
((gId == THE_HOUSE_OF_THE_DEAD_4_REVA) || (gId == THE_HOUSE_OF_THE_DEAD_4_REVB) || ((gId == THE_HOUSE_OF_THE_DEAD_4_REVA) || (gId == THE_HOUSE_OF_THE_DEAD_4_REVB) || (gId == THE_HOUSE_OF_THE_DEAD_4_REVC) ||
(gId == THE_HOUSE_OF_THE_DEAD_4_REVC) || (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) || (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) || (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) || (gId == THE_HOUSE_OF_THE_DEAD_EX) ||
(gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) || (gId == THE_HOUSE_OF_THE_DEAD_EX) || (gId == TOO_SPICY))) (gId == TOO_SPICY)))
{ {
for (int i = 0; attrib_list[i] != None; i += 2) for (int i = 0; attrib_list[i] != None; i += 2)
{ {
@ -222,8 +231,8 @@ GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attrib_list,
GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct) GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
{ {
GLXContext (*_glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, GLXContext (*_glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct) =
Bool direct) = dlsym(RTLD_NEXT, "glXCreateNewContext"); dlsym(RTLD_NEXT, "glXCreateNewContext");
GLXContext ctx = _glXCreateNewContext(dpy, config, render_type, share_list, direct); GLXContext ctx = _glXCreateNewContext(dpy, config, render_type, share_list, direct);
@ -237,20 +246,12 @@ GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int render_type
return ctx; return ctx;
} }
GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
int *attrib_list)
{ {
if (sdlGame) if (sdlGame)
return 0; return 0;
int pbufferAttribs[] = {GLX_PBUFFER_WIDTH, int pbufferAttribs[] = {
width, GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height, GLX_PRESERVED_CONTENTS, true, GLX_LARGEST_PBUFFER, true, None};
GLX_PBUFFER_HEIGHT,
height,
GLX_PRESERVED_CONTENTS,
true,
GLX_LARGEST_PBUFFER,
true,
None};
return glXCreatePbuffer(dpy, config, pbufferAttribs); return glXCreatePbuffer(dpy, config, pbufferAttribs);
} }
@ -274,8 +275,7 @@ GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_lis
__NV_PRIME_RENDER_OFFLOAD = " "; __NV_PRIME_RENDER_OFFLOAD = " ";
if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) && if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) &&
((gId == INITIALD_4_REVA) || (gId == INITIALD_4_REVB) || (gId == INITIALD_4_REVC) || (gId == INITIALD_4_REVD) || ((gId == INITIALD_4_REVA) || (gId == INITIALD_4_REVB) || (gId == INITIALD_4_REVC) || (gId == INITIALD_4_REVD) ||
(gId == INITIALD_4_REVG) || (gId == INITIALD_4_EXP_REVB) || (gId == INITIALD_4_EXP_REVC) || (gId == INITIALD_4_REVG) || (gId == INITIALD_4_EXP_REVB) || (gId == INITIALD_4_EXP_REVC) || gId == INITIALD_4_EXP_REVD))
gId == INITIALD_4_EXP_REVD))
{ {
for (int i = 0; attrib_list[i] != None; i += 2) for (int i = 0; attrib_list[i] != None; i += 2)
{ {
@ -296,8 +296,7 @@ int glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute
return glXGetFBConfigAttrib(dpy, config, attribute, value); return glXGetFBConfigAttrib(dpy, config, attribute, value);
} }
GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
Bool direct)
{ {
if (sdlGame) if (sdlGame)
return 0; return 0;