- Added crosshairs for light gun games and disabled mouse cursor in full screen mode (no way to re-enable it now).

- Fixed Real3D FIFO buffer overflow bug.
- Input system cannot be changed for non-Windows builds (only SDL is available).
- Added Spikeout-specific controls.
This commit is contained in:
Bart Trzynadlowski 2011-08-27 21:37:37 +00:00
parent b19f600fec
commit 8be2966ecb
10 changed files with 158 additions and 33 deletions

View file

@ -1497,7 +1497,7 @@ const struct GameInfo g_Model3GameList[] =
FALSE, // 96 MB of banked CROM (Do not Mirror) FALSE, // 96 MB of banked CROM (Do not Mirror)
0x4000000, // 64 MB of VROM 0x4000000, // 64 MB of VROM
0x1000000, // 16 MB of sample ROMs 0x1000000, // 16 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_FIGHTING, GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_SPIKEOUT,
2, // DSB2 MPEG board 2, // DSB2 MPEG board
{ {
@ -1577,7 +1577,7 @@ const struct GameInfo g_Model3GameList[] =
FALSE, // 96 MB of banked CROM (Do not Mirror) FALSE, // 96 MB of banked CROM (Do not Mirror)
0x4000000, // 64 MB of VROM 0x4000000, // 64 MB of VROM
0x1000000, // 16 MB of sample ROMs 0x1000000, // 16 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_FIGHTING, GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_SPIKEOUT,
2, // DSB2 MPEG board 2, // DSB2 MPEG board
{ {

View file

@ -50,7 +50,8 @@
#define GAME_INPUT_ANALOG_JOYSTICK 0x0400 // game has analog joystick #define GAME_INPUT_ANALOG_JOYSTICK 0x0400 // game has analog joystick
#define GAME_INPUT_TWIN_JOYSTICKS 0x0800 // game has twin joysticks #define GAME_INPUT_TWIN_JOYSTICKS 0x0800 // game has twin joysticks
#define GAME_INPUT_SOCCER 0x1000 // game has soccer controls #define GAME_INPUT_SOCCER 0x1000 // game has soccer controls
#define GAME_INPUT_ALL 0x1FFF #define GAME_INPUT_SPIKEOUT 0x2000 // game has Spikeout buttons
#define GAME_INPUT_ALL 0x3FFF
/****************************************************************************** /******************************************************************************

View file

@ -58,8 +58,9 @@ const char* CInput::GetInputGroup()
case GAME_INPUT_UI: return "User Interface Controls"; case GAME_INPUT_UI: return "User Interface Controls";
case GAME_INPUT_COMMON: return "Common Controls"; case GAME_INPUT_COMMON: return "Common Controls";
case GAME_INPUT_JOYSTICK1: // Fall through to below case GAME_INPUT_JOYSTICK1: // Fall through to below
case GAME_INPUT_JOYSTICK2: return "8-Way Joysticks"; case GAME_INPUT_JOYSTICK2: return "4-Way Joysticks";
case GAME_INPUT_FIGHTING: return "Fighting Game Buttons"; case GAME_INPUT_FIGHTING: return "Fighting Game Buttons";
case GAME_INPUT_SPIKEOUT: return "Spikeout Buttons";
case GAME_INPUT_SOCCER: return "Virtua Striker Buttons"; case GAME_INPUT_SOCCER: return "Virtua Striker Buttons";
case GAME_INPUT_VEHICLE: return "Racing Game Steering Controls"; case GAME_INPUT_VEHICLE: return "Racing Game Steering Controls";
case GAME_INPUT_SHIFT4: return "Racing Game Gear Shift"; case GAME_INPUT_SHIFT4: return "Racing Game Gear Shift";

View file

@ -17,7 +17,7 @@ CInputs::CInputs(CInputSystem *system) : m_system(system)
uiLoadState = AddSwitchInput("UILoadState", "Load State", GAME_INPUT_UI, "KEY_F7"); uiLoadState = AddSwitchInput("UILoadState", "Load State", GAME_INPUT_UI, "KEY_F7");
uiDumpInpState = AddSwitchInput("UIDumpInputState", "Dump Input State", GAME_INPUT_UI, "KEY_F8"); uiDumpInpState = AddSwitchInput("UIDumpInputState", "Dump Input State", GAME_INPUT_UI, "KEY_F8");
uiClearNVRAM = AddSwitchInput("UIClearNVRAM", "Clear NVRAM", GAME_INPUT_UI, "KEY_ALT+KEY_N"); uiClearNVRAM = AddSwitchInput("UIClearNVRAM", "Clear NVRAM", GAME_INPUT_UI, "KEY_ALT+KEY_N");
uiToggleCursor = AddSwitchInput("UIToggleCursor", "Toggle Cursor", GAME_INPUT_UI, "KEY_ALT+KEY_I"); uiSelectCrosshairs = AddSwitchInput("UISelectCrosshairs", "Select Crosshairs", GAME_INPUT_UI, "KEY_ALT+KEY_I");
uiToggleFrLimit = AddSwitchInput("UIToggleFrameLimit", "Toggle Frame Limiting", GAME_INPUT_UI, "KEY_ALT+KEY_T"); uiToggleFrLimit = AddSwitchInput("UIToggleFrameLimit", "Toggle Frame Limiting", GAME_INPUT_UI, "KEY_ALT+KEY_T");
#ifdef SUPERMODEL_DEBUGGER #ifdef SUPERMODEL_DEBUGGER
uiEnterDebugger = AddSwitchInput("UIEnterDebugger", "Enter Debugger", GAME_INPUT_UI, "KEY_ALT+KEY_B"); uiEnterDebugger = AddSwitchInput("UIEnterDebugger", "Enter Debugger", GAME_INPUT_UI, "KEY_ALT+KEY_B");
@ -33,7 +33,7 @@ CInputs::CInputs(CInputSystem *system) : m_system(system)
test[0] = AddSwitchInput("TestA", "Test A", GAME_INPUT_COMMON, "KEY_6"); test[0] = AddSwitchInput("TestA", "Test A", GAME_INPUT_COMMON, "KEY_6");
test[1] = AddSwitchInput("TestB", "Test B", GAME_INPUT_COMMON, "KEY_8"); test[1] = AddSwitchInput("TestB", "Test B", GAME_INPUT_COMMON, "KEY_8");
// 8-Way Joysticks // 4-Way Joysticks
up[0] = AddSwitchInput("JoyUp", "P1 Joystick Up", GAME_INPUT_JOYSTICK1, "KEY_UP,JOY1_UP"); up[0] = AddSwitchInput("JoyUp", "P1 Joystick Up", GAME_INPUT_JOYSTICK1, "KEY_UP,JOY1_UP");
down[0] = AddSwitchInput("JoyDown", "P1 Joystick Down", GAME_INPUT_JOYSTICK1, "KEY_DOWN,JOY1_DOWN"); down[0] = AddSwitchInput("JoyDown", "P1 Joystick Down", GAME_INPUT_JOYSTICK1, "KEY_DOWN,JOY1_DOWN");
left[0] = AddSwitchInput("JoyLeft", "P1 Joystick Left", GAME_INPUT_JOYSTICK1, "KEY_LEFT,JOY1_LEFT"); left[0] = AddSwitchInput("JoyLeft", "P1 Joystick Left", GAME_INPUT_JOYSTICK1, "KEY_LEFT,JOY1_LEFT");
@ -53,6 +53,12 @@ CInputs::CInputs(CInputSystem *system) : m_system(system)
guard[1] = AddSwitchInput("Guard2", "P2 Guard", GAME_INPUT_FIGHTING, "JOY2_BUTTON3"); guard[1] = AddSwitchInput("Guard2", "P2 Guard", GAME_INPUT_FIGHTING, "JOY2_BUTTON3");
escape[1] = AddSwitchInput("Escape2", "P2 Escape", GAME_INPUT_FIGHTING, "JOY2_BUTTON4"); escape[1] = AddSwitchInput("Escape2", "P2 Escape", GAME_INPUT_FIGHTING, "JOY2_BUTTON4");
// Spikeout Buttons
shift = AddSwitchInput("Shift", "Shift", GAME_INPUT_SPIKEOUT, "KEY_A,JOY1_BUTTON1");
beat = AddSwitchInput("Beat", "Beat", GAME_INPUT_SPIKEOUT, "KEY_S,JOY1_BUTTON2");
charge = AddSwitchInput("Charge", "Charge",GAME_INPUT_SPIKEOUT, "KEY_D,JOY1_BUTTON3");
jump = AddSwitchInput("Jump", "Jump", GAME_INPUT_SPIKEOUT, "KEY_F,JOY1_BUTTON4");
// Virtua Striker Buttons // Virtua Striker Buttons
shortPass[0] = AddSwitchInput("ShortPass", "P1 Short Pass", GAME_INPUT_SOCCER, "KEY_A,JOY1_BUTTON1"); shortPass[0] = AddSwitchInput("ShortPass", "P1 Short Pass", GAME_INPUT_SOCCER, "KEY_A,JOY1_BUTTON1");
longPass[0] = AddSwitchInput("LongPass", "P1 Long Pass", GAME_INPUT_SOCCER, "KEY_S,JOY1_BUTTON2"); longPass[0] = AddSwitchInput("LongPass", "P1 Long Pass", GAME_INPUT_SOCCER, "KEY_S,JOY1_BUTTON2");

View file

@ -72,7 +72,7 @@ public:
CSwitchInput *uiLoadState; CSwitchInput *uiLoadState;
CSwitchInput *uiDumpInpState; CSwitchInput *uiDumpInpState;
CSwitchInput *uiClearNVRAM; CSwitchInput *uiClearNVRAM;
CSwitchInput *uiToggleCursor; CSwitchInput *uiSelectCrosshairs;
CSwitchInput *uiToggleFrLimit; CSwitchInput *uiToggleFrLimit;
#ifdef SUPERMODEL_DEBUGGER #ifdef SUPERMODEL_DEBUGGER
CSwitchInput *uiEnterDebugger; CSwitchInput *uiEnterDebugger;
@ -96,6 +96,12 @@ public:
CSwitchInput *guard[2]; CSwitchInput *guard[2];
CSwitchInput *escape[2]; CSwitchInput *escape[2];
// Spikeout controls
CSwitchInput *shift;
CSwitchInput *beat;
CSwitchInput *charge;
CSwitchInput *jump;
// Soccer game controls (players 1 and 2) // Soccer game controls (players 1 and 2)
CSwitchInput *shortPass[2]; CSwitchInput *shortPass[2];
CSwitchInput *longPass[2]; CSwitchInput *longPass[2];
@ -140,7 +146,6 @@ public:
CSwitchInput *twinJoyJump; CSwitchInput *twinJoyJump;
CSwitchInput *twinJoyCrouch; CSwitchInput *twinJoyCrouch;
// Analog joystick // Analog joystick
CAxisInput *analogJoyX; CAxisInput *analogJoyX;
CAxisInput *analogJoyY; CAxisInput *analogJoyY;

View file

@ -677,7 +677,7 @@ static const char *stateName[] =
void CDSB2::WriteMPEGFIFO(UINT8 byte) void CDSB2::WriteMPEGFIFO(UINT8 byte)
{ {
printf("fifo: %x (state %s)\n", byte, stateName[mpegState]); //printf("fifo: %x (state %s)\n", byte, stateName[mpegState]);
switch (mpegState) switch (mpegState)
{ {
case ST_IDLE: case ST_IDLE:
@ -693,7 +693,7 @@ void CDSB2::WriteMPEGFIFO(UINT8 byte)
usingMPEGStart = mpegStart; usingMPEGStart = mpegStart;
usingMPEGEnd = mpegEnd; usingMPEGEnd = mpegEnd;
MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart); MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart);
printf("playing %X\n", mpegStart); //printf("playing %X\n", mpegStart);
mpegState = ST_IDLE; mpegState = ST_IDLE;
playing = 1; playing = 1;
} }
@ -737,13 +737,13 @@ void CDSB2::WriteMPEGFIFO(UINT8 byte)
if (playing) if (playing)
{ {
printf("Setting loop point to %x\n", mpegStart); //printf("Setting loop point to %x\n", mpegStart);
usingLoopStart = mpegStart; usingLoopStart = mpegStart;
usingLoopEnd = mpegEnd-mpegStart; usingLoopEnd = mpegEnd-mpegStart;
MPEG_SetLoop((const char *) &mpegROM[usingLoopStart], usingLoopEnd); MPEG_SetLoop((const char *) &mpegROM[usingLoopStart], usingLoopEnd);
} }
printf("mpegStart=%x\n", mpegStart); //printf("mpegStart=%x\n", mpegStart);
break; break;
case ST_GOT24: case ST_GOT24:
mpegEnd &= 0x00FFFF; mpegEnd &= 0x00FFFF;
@ -758,7 +758,7 @@ void CDSB2::WriteMPEGFIFO(UINT8 byte)
case ST_24_1: case ST_24_1:
mpegEnd &= 0xFFFF00; mpegEnd &= 0xFFFF00;
mpegEnd |= (byte); mpegEnd |= (byte);
printf("mpegEnd=%x\n", mpegEnd); //printf("mpegEnd=%x\n", mpegEnd);
// default to full stereo // default to full stereo
// mixer_set_stereo_volume(0, 255, 255); // mixer_set_stereo_volume(0, 255, 255);
@ -781,7 +781,7 @@ void CDSB2::WriteMPEGFIFO(UINT8 byte)
usingMPEGStart = mpegStart; usingMPEGStart = mpegStart;
usingMPEGEnd = mpegEnd; usingMPEGEnd = mpegEnd;
MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart); MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart);
printf("playing %X (from st_gota4)\n", mpegStart); //printf("playing %X (from st_gota4)\n", mpegStart);
playing = 1; playing = 1;
} }
break; break;
@ -816,14 +816,14 @@ void CDSB2::WriteMPEGFIFO(UINT8 byte)
case ST_GOTB6: // rear left(?) volume case ST_GOTB6: // rear left(?) volume
case ST_GOTB0: // left volume case ST_GOTB0: // left volume
volume[0] = byte; volume[0] = byte;
printf("Set L Volume: %02X\n", byte); //printf("Set L Volume: %02X\n", byte);
mpegState = ST_IDLE; mpegState = ST_IDLE;
break; break;
case ST_GOTA7: // rear right(?) volume case ST_GOTA7: // rear right(?) volume
case ST_GOTA1: // right volume case ST_GOTA1: // right volume
case ST_GOTA0: case ST_GOTA0:
volume[1] = byte; volume[1] = byte;
printf("Set R Volume: %02X\n", byte); //printf("Set R Volume: %02X\n", byte);
mpegState = ST_IDLE; mpegState = ST_IDLE;
break; break;
case ST_GOTB2: case ST_GOTB2:
@ -929,7 +929,7 @@ void CDSB2::Write16(UINT32 addr, UINT16 data)
*(UINT16 *) &ram[addr] = data; *(UINT16 *) &ram[addr] = data;
return; return;
} }
printf("W16: %x @ %x\n", data, addr); //printf("W16: %x @ %x\n", data, addr);
} }
void CDSB2::Write32(UINT32 addr, UINT32 data) void CDSB2::Write32(UINT32 addr, UINT32 data)
@ -941,7 +941,7 @@ void CDSB2::Write32(UINT32 addr, UINT32 data)
*(UINT16 *) &ram[addr+2] = data&0xFFFF; *(UINT16 *) &ram[addr+2] = data&0xFFFF;
return; return;
} }
printf("W32: %x @ %x\n", data, addr); //printf("W32: %x @ %x\n", data, addr);
} }
void CDSB2::SendCommand(UINT8 data) void CDSB2::SendCommand(UINT8 data)
@ -1023,7 +1023,7 @@ void CDSB2::Reset(void)
M68KSetContext(&M68K); M68KSetContext(&M68K);
M68KReset(); M68KReset();
printf("DSB2 PC=%06X\n", M68KGetPC()); //printf("DSB2 PC=%06X\n", M68KGetPC());
M68KGetContext(&M68K); M68KGetContext(&M68K);
DebugLog("DSB2 Reset\n"); DebugLog("DSB2 Reset\n");

View file

@ -247,6 +247,14 @@ UINT8 CModel3::ReadInputs(unsigned reg)
data &= ~(Inputs->punch[0]->value<<0); // P1 Punch data &= ~(Inputs->punch[0]->value<<0); // P1 Punch
} }
if ((Game->inputFlags&GAME_INPUT_SPIKEOUT))
{
data &= ~(Inputs->shift->value<<2); // Shift
data &= ~(Inputs->beat->value<<0); // Beat
data &= ~(Inputs->charge->value<<1); // Charge
data &= ~(Inputs->jump->value<<3); // Jump
}
if ((Game->inputFlags&GAME_INPUT_SOCCER)) if ((Game->inputFlags&GAME_INPUT_SOCCER))
{ {
data &= ~(Inputs->shortPass[0]->value<<2); // P1 Short Pass data &= ~(Inputs->shortPass[0]->value<<2); // P1 Short Pass
@ -2164,7 +2172,7 @@ void CModel3::RunMainBoardFrame(void)
++irqCount; ++irqCount;
if (irqCount > 128) if (irqCount > 128)
{ {
printf("\tMIDI FIFO OVERFLOW! (IRQEn=%02X, IRQPend=%02X)\n", IRQ.ReadIRQEnable()&0x40, IRQ.ReadIRQState()); //printf("\tMIDI FIFO OVERFLOW! (IRQEn=%02X, IRQPend=%02X)\n", IRQ.ReadIRQEnable()&0x40, IRQ.ReadIRQState());
break; break;
} }
} }

View file

@ -132,6 +132,7 @@ void CReal3D::BeginFrame(void)
void CReal3D::EndFrame(void) void CReal3D::EndFrame(void)
{ {
error = false; // clear error (just needs to be done once per frame)
status &= ~2; status &= ~2;
Render3D->EndFrame(); Render3D->EndFrame();
} }
@ -698,9 +699,14 @@ void CReal3D::Flush(void)
void CReal3D::WriteTextureFIFO(UINT32 data) void CReal3D::WriteTextureFIFO(UINT32 data)
{ {
textureFIFO[fifoIdx++] = data;
if (fifoIdx >= (0x100000/4)) if (fifoIdx >= (0x100000/4))
ErrorLog("Real3D texture FIFO maxed out!"); {
if (!error)
ErrorLog("Overflow in Real3D texture FIFO!");
error = true;
}
else
textureFIFO[fifoIdx++] = data;
} }
void CReal3D::WriteTexturePort(unsigned reg, UINT32 data) void CReal3D::WriteTexturePort(unsigned reg, UINT32 data)
@ -797,6 +803,8 @@ void CReal3D::WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits,
void CReal3D::Reset(void) void CReal3D::Reset(void)
{ {
error = false;
commandPortWritten = FALSE; commandPortWritten = FALSE;
fifoIdx = 0; fifoIdx = 0;
@ -885,6 +893,7 @@ CReal3D::CReal3D(void)
textureRAM = NULL; textureRAM = NULL;
textureFIFO = NULL; textureFIFO = NULL;
vrom = NULL; vrom = NULL;
error = false;
fifoIdx = 0; fifoIdx = 0;
vromTextureAddr = 0; vromTextureAddr = 0;
vromTextureHeader = 0; vromTextureHeader = 0;

View file

@ -351,6 +351,9 @@ private:
int step; // hardware stepping (as in GameInfo structure) int step; // hardware stepping (as in GameInfo structure)
UINT32 pciID; // PCI vendor and device ID UINT32 pciID; // PCI vendor and device ID
// Error flag (to limit errors to once per frame)
bool error; // true if an error occurred this frame
// Real3D memory // Real3D memory
UINT8 *memoryPool; // all memory allocated here UINT8 *memoryPool; // all memory allocated here
UINT32 *cullingRAMLo; // 4MB of culling RAM at 8C000000 UINT32 *cullingRAMLo; // 4MB of culling RAM at 8C000000

View file

@ -1,3 +1,12 @@
//TODO before release:
// - Controls for Dirt Devils, and other recent games (is bass working?)
// - Crosshairs
// - Comment source code, clean up
// - BOOL -> bool, TRUE/FALSE -> true/false
// - Add option for building with /MD in MSVC Makefile
// - Remove SUPERMODEL_SOUND
// - EmulateSCSP -> EmulateSound ?
/** /**
** Supermodel ** Supermodel
** A Sega Model 3 Arcade Emulator. ** A Sega Model 3 Arcade Emulator.
@ -571,6 +580,70 @@ static void LoadNVRAM(CModel3 *Model3)
} }
/******************************************************************************
UI Rendering
Currently, only does crosshairs for light gun games.
******************************************************************************/
static void GunToViewCoords(float *x, float *y)
{
*x = (*x-150.0f)/(651.0f-150.0f); // Scale [150,651] -> [0.0,1.0]
*y = (*y-80.0f)/(465.0f-80.0f); // Scale [80,465] -> [0.0,1.0]
}
static void DrawCrosshair(float x, float y, float r, float g, float b)
{
glColor3f(r, g, b);
glVertex2f(x-0.01f, y);
glVertex2f(x-0.002f, y);
glVertex2f(x+0.003f, y);
glVertex2f(x+0.01f, y);
glVertex2f(x, y-0.01f*(float)xRes/(float)yRes);
glVertex2f(x, y-0.003f*(float)xRes/(float)yRes);
glVertex2f(x, y+0.002f*(float)xRes/(float)yRes);
glVertex2f(x, y+0.01f*(float)xRes/(float)yRes);
}
static void UpdateCrosshairs(CInputs *Inputs, unsigned showCrosshairs)
{
float x[2], y[2];
showCrosshairs &= 3;
if (!showCrosshairs)
return;
// Set up the viewport and orthogonal projection
glViewport(xOffset, yOffset, xRes, yRes);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D); // no texture mapping
glDisable(GL_BLEND); // no blending
glDisable(GL_DEPTH_TEST); // no Z-buffering needed
glUseProgram(NULL); // no shaders
// Convert gun coordinates to viewspace coordinates
x[0] = (float) Inputs->gunX[0]->value;
y[0] = (float) Inputs->gunY[0]->value;
x[1] = (float) Inputs->gunX[1]->value;
y[1] = (float) Inputs->gunY[1]->value;
GunToViewCoords(&x[0], &y[0]);
GunToViewCoords(&x[1], &y[1]);
// Draw visible crosshairs
glBegin(GL_LINES);
glLineWidth(1.0f);
if ((showCrosshairs & 2) && !Inputs->trigger[0]->offscreenValue) // Player 1
DrawCrosshair(x[0], y[0], 1.0f, 0.0f, 0.0f);
if ((showCrosshairs & 1) && !Inputs->trigger[1]->offscreenValue) // Player 2
DrawCrosshair(x[1], y[1], 0.0f, 1.0f, 0.0f);
glEnd();
}
/****************************************************************************** /******************************************************************************
Main Program Loop Main Program Loop
******************************************************************************/ ******************************************************************************/
@ -589,7 +662,8 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine)
CRender3D *Render3D = new CRender3D(); CRender3D *Render3D = new CRender3D();
unsigned prevFPSTicks, currentFPSTicks, currentTicks, targetTicks, startTicks; unsigned prevFPSTicks, currentFPSTicks, currentTicks, targetTicks, startTicks;
unsigned fpsFramesElapsed, framesElapsed; unsigned fpsFramesElapsed, framesElapsed;
BOOL showCursor = FALSE; // show cursor in full screen mode? unsigned showCrosshairs = 0; // bit 1: player 1 crosshair, bit 0: player 2
bool gameHasLightguns = false;
BOOL quit = 0; BOOL quit = 0;
BOOL paused = 0; BOOL paused = 0;
@ -621,8 +695,14 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine)
if (OKAY != OpenAudio()) if (OKAY != OpenAudio())
return 1; return 1;
// Hide mouse if fullscreen // Hide mouse if fullscreen, enable crosshairs for gun games
Inputs->GetInputSystem()->SetMouseVisibility(!g_Config.fullScreen); Inputs->GetInputSystem()->SetMouseVisibility(!g_Config.fullScreen);
gameHasLightguns = !!(Model3->GetGameInfo()->inputFlags & (GAME_INPUT_GUN1|GAME_INPUT_GUN2));
if (g_Config.fullScreen)
{
if (gameHasLightguns)
showCrosshairs = 3;
}
// Attach the inputs to the emulator // Attach the inputs to the emulator
Model3->AttachInputs(Inputs); Model3->AttachInputs(Inputs);
@ -660,6 +740,9 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine)
// If not, run one frame // If not, run one frame
Model3->RunFrame(); Model3->RunFrame();
// Show crosshairs for light gun games
UpdateCrosshairs(Inputs, showCrosshairs);
// Swap the buffers // Swap the buffers
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
} }
@ -699,7 +782,7 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine)
Debugger->Reset(); Debugger->Reset();
#endif // SUPERMODEL_DEBUGGER #endif // SUPERMODEL_DEBUGGER
printf("Model 3 reset.\n"); puts("Model 3 reset.");
} }
else if (Inputs->uiPause->Pressed()) else if (Inputs->uiPause->Pressed())
{ {
@ -734,17 +817,23 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine)
// Dump input states // Dump input states
Inputs->DumpState(Model3->GetGameInfo()); Inputs->DumpState(Model3->GetGameInfo());
} }
else if (Inputs->uiToggleCursor->Pressed() && g_Config.fullScreen) else if (Inputs->uiSelectCrosshairs->Pressed() && gameHasLightguns)
{ {
// Toggle cursor in full screen mode // Count downwards to get this sequence: both, player 1, player 2, none
showCursor = !showCursor; showCrosshairs--;
Inputs->GetInputSystem()->SetMouseVisibility(!!showCursor); switch ((showCrosshairs&3))
{
case 0: puts("Crosshairs disabled."); break;
case 3: puts("Crosshairs enabled."); break;
case 2: puts("Showing Player 1 crosshair only."); break;
case 1: puts("Showing Player 2 crosshair only."); break;
}
} }
else if (Inputs->uiClearNVRAM->Pressed()) else if (Inputs->uiClearNVRAM->Pressed())
{ {
// Clear NVRAM // Clear NVRAM
Model3->ClearNVRAM(); Model3->ClearNVRAM();
printf("NVRAM cleared.\n"); puts("NVRAM cleared.");
} }
else if (Inputs->uiToggleFrLimit->Pressed()) else if (Inputs->uiToggleFrLimit->Pressed())
{ {
@ -928,8 +1017,7 @@ static int DisassembleCROM(const char *zipFile, UINT32 addr, unsigned n)
static void Title(void) static void Title(void)
{ {
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version "SUPERMODEL_VERSION")"); puts("Supermodel: A Sega Model 3 Arcade Emulator (Version "SUPERMODEL_VERSION")");
puts("Copyright (C) 2011 by Bart Trzynadlowski"); puts("Copyright (C) 2011 by Bart Trzynadlowski\n");
puts("");
} }
// Print usage information // Print usage information
@ -965,7 +1053,9 @@ static void Help(void)
puts(" -music-volume=<v> Set volume of MPEG music in % [Default: 100]"); puts(" -music-volume=<v> Set volume of MPEG music in % [Default: 100]");
puts(""); puts("");
puts("Input Options:"); puts("Input Options:");
#ifdef SUPERMODEL_WIN32
puts(" -input-system=<s> Set input system [Default: SDL]"); puts(" -input-system=<s> Set input system [Default: SDL]");
#endif
puts(" -print-inputs Prints current input configuration"); puts(" -print-inputs Prints current input configuration");
puts(" -config-inputs Configure inputs for keyboards, mice, and joysticks"); puts(" -config-inputs Configure inputs for keyboards, mice, and joysticks");
puts(""); puts("");
@ -1142,6 +1232,7 @@ int main(int argc, char **argv)
else else
CmdLine.Set("Global", "FragmentShader", &argv[i][13]); CmdLine.Set("Global", "FragmentShader", &argv[i][13]);
} }
#ifdef SUPERMODEL_WIN32
else if (!strncmp(argv[i],"-input-system=", 14)) else if (!strncmp(argv[i],"-input-system=", 14))
{ {
if (argv[i][14] == '\0') if (argv[i][14] == '\0')
@ -1149,6 +1240,7 @@ int main(int argc, char **argv)
else else
CmdLine.Set("Global", "InputSystem", &argv[i][14]); CmdLine.Set("Global", "InputSystem", &argv[i][14]);
} }
#endif
else if (!strcmp(argv[i],"-print-inputs")) else if (!strcmp(argv[i],"-print-inputs"))
cmdPrintInputs = true; cmdPrintInputs = true;
else if (!strcmp(argv[i],"-config-inputs")) else if (!strcmp(argv[i],"-config-inputs"))
@ -1172,7 +1264,7 @@ int main(int argc, char **argv)
return 0; return 0;
} }
else if (argv[i][0] == '-') else if (argv[i][0] == '-')
ErrorLog("Ignoring invalid option: %s.", argv[i]); ErrorLog("Ignoring unrecognized option: %s.", argv[i]);
else else
{ {
if (fileIdx) // already specified a file if (fileIdx) // already specified a file