Add stuff
This commit is contained in:
parent
1603bfe532
commit
6d7d49496e
@ -8,6 +8,8 @@ int initConfig() {
|
||||
config.emulateRideboard = 0;
|
||||
strcpy(config.eepromPath, "eeprom.bin");
|
||||
strcpy(config.sramPath, "sram.bin");
|
||||
config.width = 1024;
|
||||
config.height = 768;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ typedef struct
|
||||
int emulateRideboard;
|
||||
char eepromPath[MAX_PATH_LENGTH];
|
||||
char sramPath[MAX_PATH_LENGTH];
|
||||
int width;
|
||||
int height;
|
||||
} EmulatorConfig;
|
||||
|
||||
int initConfig();
|
||||
|
@ -1,9 +1,18 @@
|
||||
#include <GL/freeglut.h>
|
||||
#include <dlfcn.h>
|
||||
#include <GL/glx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "jvs.h"
|
||||
#include "securityboard.h"
|
||||
|
||||
int gameModeWidth = -1;
|
||||
int gameModeHeight = -1;
|
||||
|
||||
FGAPI int FGAPIENTRY glutEnterGameMode()
|
||||
{
|
||||
glutCreateWindow("SEGA Lindbergh");
|
||||
glutCreateWindow("SEGA Lindbergh (GLUT)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -12,3 +21,105 @@ FGAPI void FGAPIENTRY glutLeaveGameMode()
|
||||
glutDestroyWindow(glutGetWindow());
|
||||
return;
|
||||
}
|
||||
|
||||
FGAPI void FGAPIENTRY glutSetCursor(int cursor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FGAPI void FGAPIENTRY glutGameModeString(const char *string)
|
||||
{
|
||||
printf("glutGameModeString: %s\n", string);
|
||||
|
||||
char gameModeString[1024];
|
||||
strcpy(gameModeString, string);
|
||||
|
||||
char *widthString = gameModeString;
|
||||
char *heightString = NULL;
|
||||
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
if (gameModeString[i] == 'x')
|
||||
{
|
||||
gameModeString[i] = 0;
|
||||
heightString = &gameModeString[i + 1];
|
||||
}
|
||||
|
||||
if (gameModeString[i] == ':')
|
||||
{
|
||||
gameModeString[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int width = atoi(widthString);
|
||||
int height = atoi(heightString);
|
||||
|
||||
if (getConfig()->width != width || getConfig()->height != height)
|
||||
{
|
||||
printf("Warning: Game is overriding resolution settings to %dX%d\n", width, height);
|
||||
getConfig()->width = width;
|
||||
getConfig()->height = height;
|
||||
}
|
||||
}
|
||||
|
||||
Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int class, Visual *visual, unsigned long valueMask, XSetWindowAttributes *attributes)
|
||||
{
|
||||
|
||||
Window (*_XCreateWindow)(Display * display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int class, Visual *visual, unsigned long valueMask, XSetWindowAttributes *attributes) = dlsym(RTLD_NEXT, "XCreateWindow");
|
||||
|
||||
width = getConfig()->width;
|
||||
height = getConfig()->height;
|
||||
|
||||
// Ensure that the windows will respond with keyboard and mouse events
|
||||
attributes->event_mask = attributes->event_mask | KeyPressMask | KeyReleaseMask | PointerMotionMask;
|
||||
|
||||
Window window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
int XNextEvent(Display *display, XEvent *event_return)
|
||||
{
|
||||
|
||||
int (*_XNextEvent)(Display * display, XEvent * event_return) = dlsym(RTLD_NEXT, "XNextEvent");
|
||||
int returnValue = _XNextEvent(display, event_return);
|
||||
|
||||
switch (event_return->type)
|
||||
{
|
||||
case KeyPress:
|
||||
switch (event_return->xkey.keycode)
|
||||
{
|
||||
case 28:
|
||||
securityBoardSetSwitch(BUTTON_TEST, 1);
|
||||
break;
|
||||
case 39:
|
||||
securityBoardSetSwitch(BUTTON_SERVICE, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KeyRelease:
|
||||
switch (event_return->xkey.keycode)
|
||||
{
|
||||
case 28:
|
||||
securityBoardSetSwitch(BUTTON_TEST, 0);
|
||||
break;
|
||||
case 39:
|
||||
securityBoardSetSwitch(BUTTON_SERVICE, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
int XSetStandardProperties(Display *display, Window window, const char *window_name, const char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints)
|
||||
{
|
||||
int (*_XSetStandardProperties)(Display * display, Window window, const char *window_name, const char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints) = dlsym(RTLD_NEXT, "XSetStandardProperties");
|
||||
return _XSetStandardProperties(display, window, "SEGA Lindbergh (X11)", icon_name, icon_pixmap, argv, argc, hints);
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "hook.h"
|
||||
@ -42,9 +44,11 @@ void __attribute__((constructor)) hook_init()
|
||||
if (initJVS() != 0)
|
||||
exit(1);
|
||||
|
||||
if(initSecurityBoard() != 0)
|
||||
if (initSecurityBoard() != 0)
|
||||
exit(1);
|
||||
|
||||
securityBoardSetDipResolution(getConfig()->width, getConfig()->height);
|
||||
|
||||
printf("Loader init success\n");
|
||||
}
|
||||
|
||||
@ -76,9 +80,27 @@ int open(const char *pathname, int flags)
|
||||
return hooks[SERIAL1];
|
||||
}
|
||||
|
||||
if (strncmp(pathname, "/tmp/", 5) == 0)
|
||||
{
|
||||
mkdir("tmp", 0777);
|
||||
return _open(pathname + 1, flags);
|
||||
}
|
||||
|
||||
return _open(pathname, flags);
|
||||
}
|
||||
|
||||
FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
{
|
||||
FILE *(*_fopen)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen");
|
||||
|
||||
if (strcmp(pathname, "/root/lindbergrc") == 0)
|
||||
{
|
||||
return _fopen("lindbergrc", mode);
|
||||
}
|
||||
|
||||
return _fopen(pathname, mode);
|
||||
}
|
||||
|
||||
int openat(int dirfd, const char *pathname, int flags)
|
||||
{
|
||||
int (*_openat)(int dirfd, const char *pathname, int flags) = dlsym(RTLD_NEXT, "openat");
|
||||
@ -194,6 +216,13 @@ int system(const char *command)
|
||||
|
||||
if (strcmp(command, "lsmod | grep basebd > /dev/null") == 0)
|
||||
return 0;
|
||||
|
||||
if (strcmp(command, "cd /tmp/segaboot > /dev/null") == 0)
|
||||
return system("cd tmp/segaboot > /dev/null");
|
||||
|
||||
if (strcmp(command, "mkdir /tmp/segaboot > /dev/null") == 0)
|
||||
return system("mkdir tmp/segaboot > /dev/null");
|
||||
|
||||
/*
|
||||
if (strcmp(command, "lspci | grep \"Multimedia audio controller: %Creative\" > /dev/null") == 0)
|
||||
return 0;
|
||||
@ -219,49 +248,49 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
{
|
||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
||||
|
||||
if(basePortAddress == 0xFFFF)
|
||||
// The first port called is usually random, but everything after that
|
||||
// is a constant offset, so this is a hack to fix that.
|
||||
// When run as sudo it works fine!?
|
||||
|
||||
if (basePortAddress == 0xFFFF)
|
||||
basePortAddress = port;
|
||||
|
||||
if(port > 0x38)
|
||||
if (port > 0x38)
|
||||
port = port - basePortAddress;
|
||||
|
||||
securityBoardIn(port, (uint32_t *) &(ctx->uc_mcontext.gregs[REG_EAX]));
|
||||
securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX]));
|
||||
|
||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE7:
|
||||
case 0xE7: // OUT IMMIDIATE
|
||||
{
|
||||
// printf("Warning: IO WRITE IMMIDIATE %X\n", code[1]);
|
||||
ctx->uc_mcontext.gregs[REG_EIP] += 2;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE6:
|
||||
case 0xE6: // OUT IMMIDIATE
|
||||
{
|
||||
// printf("Warning: IO WRITE IMMIDIATE %X\n", code[1]);
|
||||
ctx->uc_mcontext.gregs[REG_EIP] += 2;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xEE:
|
||||
case 0xEE: // OUT
|
||||
{
|
||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
||||
uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF;
|
||||
// printf("Warning: IO WRITE Port %X Data %X\n", port, data);
|
||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xEF:
|
||||
case 0xEF: // OUT
|
||||
{
|
||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
||||
// printf("Warning: IO WRITE Port %X\n", port);
|
||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
#include "motionboard.h"
|
||||
|
||||
ssize_t motionboardRead(int fd, void *buf, size_t count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t motionboardWrite(int fd, const void *buf, size_t count) {
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
#include <stdio.h>
|
||||
|
||||
ssize_t motionboardRead(int fd, void *buf, size_t count);
|
||||
ssize_t motionboardWrite(int fd, const void *buf, size_t count);
|
@ -2,17 +2,18 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "securityboard.h"
|
||||
#include "config.h"
|
||||
|
||||
#define SECURITY_BOARD_FRONT_PANEL 0x38
|
||||
#define SECURITY_BOARD_KEYCHIP 0xFF
|
||||
|
||||
#define DIP_SWITCH_ROTATION 2
|
||||
#define DIP_SWITCH_ROTATION 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int serviceSwitch;
|
||||
int testSwitch;
|
||||
int dipSwitch[8];
|
||||
int dipSwitch[8 + 1]; // Start index at 1
|
||||
int led[2];
|
||||
} SecurityBoard;
|
||||
|
||||
@ -21,6 +22,38 @@ SecurityBoard securityBoard = {0};
|
||||
int initSecurityBoard()
|
||||
{
|
||||
securityBoard.dipSwitch[DIP_SWITCH_ROTATION] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setResolutionDips(int dip4, int dip5, int dip6)
|
||||
{
|
||||
securityBoard.dipSwitch[4] = dip4;
|
||||
securityBoard.dipSwitch[5] = dip5;
|
||||
securityBoard.dipSwitch[6] = dip6;
|
||||
}
|
||||
|
||||
int securityBoardSetDipResolution(int width, int height)
|
||||
{
|
||||
if (width == 640 && height == 480)
|
||||
setResolutionDips(0, 0, 0);
|
||||
else if (width == 800 && height == 600)
|
||||
setResolutionDips(0, 0, 1);
|
||||
else if (width == 1024 && height == 768)
|
||||
setResolutionDips(0, 1, 0);
|
||||
else if (width == 1280 && height == 1024)
|
||||
setResolutionDips(0, 1, 1);
|
||||
else if (width == 800 && height == 480)
|
||||
setResolutionDips(1, 0, 0);
|
||||
else if (width == 1024 && height == 600)
|
||||
setResolutionDips(1, 0, 1);
|
||||
else if (width == 1280 && height == 768)
|
||||
setResolutionDips(1, 1, 0);
|
||||
else if (width == 1360 && height == 768)
|
||||
setResolutionDips(1, 1, 1);
|
||||
else
|
||||
printf("Warning: Resolution not compatible, using 640 x 480\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -30,6 +63,17 @@ int securityBoardSetRotation(int rotation)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int securityBoardSetDipSwitch(int switchNumber, int value)
|
||||
{
|
||||
if (switchNumber == 0)
|
||||
{
|
||||
printf("Error: Dip Switch index starts at 1\n");
|
||||
return 1;
|
||||
}
|
||||
securityBoard.dipSwitch[switchNumber] = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int securityBoardSetSwitch(JVSInput switchNumber, int value)
|
||||
{
|
||||
switch (switchNumber)
|
||||
@ -64,21 +108,22 @@ int securityBoardIn(uint16_t port, uint32_t *data)
|
||||
result &= ~0x08;
|
||||
if (securityBoard.testSwitch)
|
||||
result &= ~0x04;
|
||||
if (securityBoard.dipSwitch[7])
|
||||
result &= ~0x800;
|
||||
if (securityBoard.dipSwitch[0])
|
||||
result &= ~0x400;
|
||||
if (securityBoard.dipSwitch[1])
|
||||
result &= ~0x200;
|
||||
if (securityBoard.dipSwitch[2])
|
||||
result &= ~0x100;
|
||||
if (securityBoard.dipSwitch[3])
|
||||
result &= ~0x80;
|
||||
if (securityBoard.dipSwitch[4])
|
||||
result &= ~0x40;
|
||||
if (securityBoard.dipSwitch[5])
|
||||
result &= ~0x20;
|
||||
|
||||
if (securityBoard.dipSwitch[6])
|
||||
result &= ~0x800; // DIP 6
|
||||
if (securityBoard.dipSwitch[5])
|
||||
result &= ~0x400; // DIP 5
|
||||
if (securityBoard.dipSwitch[4])
|
||||
result &= ~0x200; // DIP 4
|
||||
if (securityBoard.dipSwitch[3])
|
||||
result &= ~0x100; // DIP 3
|
||||
if (securityBoard.dipSwitch[2])
|
||||
result &= ~0x80; // DIP 2
|
||||
if (securityBoard.dipSwitch[1])
|
||||
result &= ~0x40; // DIP 1
|
||||
if (securityBoard.dipSwitch[8])
|
||||
result &= ~0x20;
|
||||
if (securityBoard.dipSwitch[7])
|
||||
result &= ~0x10;
|
||||
|
||||
*data = result;
|
||||
|
@ -8,3 +8,4 @@ int securityBoardIn(uint16_t port, uint32_t *data);
|
||||
int securityBoardSetSwitch(JVSInput switchNumber, int value);
|
||||
int securityBoardSetRotation(int rotation);
|
||||
int securityBoardSetDipSwitch(int switchNumber, int value);
|
||||
int securityBoardSetDipResolution(int width, int height);
|
||||
|
Loading…
Reference in New Issue
Block a user