mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +00:00
- Program settings are now managed by the CConfig class.
- Moved Logger.h to OSD/, cleaned up comments. - Command line and config file parsing have been rewritten. - Began replacing C standard library headers with C++ versions (eg. stdio.h -> cstdio). I think I got most of them, but not all.
This commit is contained in:
parent
5e1ea75374
commit
d318efe58c
|
@ -156,7 +156,7 @@ endif
|
||||||
# Objects and Dependencies
|
# Objects and Dependencies
|
||||||
#
|
#
|
||||||
HEADERS = Src/Supermodel.h Src/OSD/SDL/Types.h
|
HEADERS = Src/Supermodel.h Src/OSD/SDL/Types.h
|
||||||
OBJ = $(OBJ_DIR)/PPCDisasm.obj $(OBJ_DIR)/Games.obj $(OBJ_DIR)/INIFile.obj $(OBJ_DIR)/BlockFile.obj $(OBJ_DIR)/93C46.obj \
|
OBJ = $(OBJ_DIR)/PPCDisasm.obj $(OBJ_DIR)/Games.obj $(OBJ_DIR)/Config.obj $(OBJ_DIR)/INIFile.obj $(OBJ_DIR)/BlockFile.obj $(OBJ_DIR)/93C46.obj \
|
||||||
$(OBJ_DIR)/ROMLoad.obj $(OBJ_DIR)/unzip.obj $(OBJ_DIR)/ioapi.obj $(OBJ_DIR)/Error.obj $(OBJ_DIR)/glew.obj $(OBJ_DIR)/Shader.obj \
|
$(OBJ_DIR)/ROMLoad.obj $(OBJ_DIR)/unzip.obj $(OBJ_DIR)/ioapi.obj $(OBJ_DIR)/Error.obj $(OBJ_DIR)/glew.obj $(OBJ_DIR)/Shader.obj \
|
||||||
$(OBJ_DIR)/Real3D.obj $(OBJ_DIR)/Render3D.obj $(OBJ_DIR)/Models.obj $(OBJ_DIR)/Render2D.obj $(OBJ_DIR)/TileGen.obj \
|
$(OBJ_DIR)/Real3D.obj $(OBJ_DIR)/Render3D.obj $(OBJ_DIR)/Models.obj $(OBJ_DIR)/Render2D.obj $(OBJ_DIR)/TileGen.obj \
|
||||||
$(OBJ_DIR)/Model3.obj $(OBJ_DIR)/ppc.obj $(OBJ_DIR)/Main.obj $(OBJ_DIR)/Audio.obj $(OBJ_DIR)/Thread.obj $(OBJ_DIR)/SoundBoard.obj \
|
$(OBJ_DIR)/Model3.obj $(OBJ_DIR)/ppc.obj $(OBJ_DIR)/Main.obj $(OBJ_DIR)/Audio.obj $(OBJ_DIR)/Thread.obj $(OBJ_DIR)/SoundBoard.obj \
|
||||||
|
|
31
Src/Config.cpp
Normal file
31
Src/Config.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
** Supermodel
|
||||||
|
** A Sega Model 3 Arcade Emulator.
|
||||||
|
** Copyright 2011 Bart Trzynadlowski
|
||||||
|
**
|
||||||
|
** This file is part of Supermodel.
|
||||||
|
**
|
||||||
|
** Supermodel is free software: you can redistribute it and/or modify it under
|
||||||
|
** the terms of the GNU General Public License as published by the Free
|
||||||
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
** any later version.
|
||||||
|
**
|
||||||
|
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
** more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License along
|
||||||
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Config.cpp
|
||||||
|
*
|
||||||
|
* Program-wide configuration settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
|
||||||
|
CConfig g_Config;
|
71
Src/Config.h
Normal file
71
Src/Config.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
** Supermodel
|
||||||
|
** A Sega Model 3 Arcade Emulator.
|
||||||
|
** Copyright 2011 Bart Trzynadlowski
|
||||||
|
**
|
||||||
|
** This file is part of Supermodel.
|
||||||
|
**
|
||||||
|
** Supermodel is free software: you can redistribute it and/or modify it under
|
||||||
|
** the terms of the GNU General Public License as published by the Free
|
||||||
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
** any later version.
|
||||||
|
**
|
||||||
|
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
** more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License along
|
||||||
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Config.h
|
||||||
|
*
|
||||||
|
* Header file for program-wide configuration settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_CONFIG_H
|
||||||
|
#define INCLUDED_CONFIG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "Supermodel.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CConfig:
|
||||||
|
*
|
||||||
|
* Class defining all configuration settings. Inherits settings from classes
|
||||||
|
* defined throughout the program.
|
||||||
|
*
|
||||||
|
* Conventions
|
||||||
|
* -----------
|
||||||
|
* - Modules and classes should only use the members of their own configuration
|
||||||
|
* class, so long as this is practical. This is left to programmer
|
||||||
|
* discretion. The intent is that one class, CReal3D for example, should not
|
||||||
|
* need information from another unrelated class, CModel3, unless explicitly
|
||||||
|
* passed to it. On the other hand, the OSD layer may have a legitimate
|
||||||
|
* need to use the renderer's video settings rather than maintaining its own.
|
||||||
|
* - Member variables that have a limited range of allowable values must be
|
||||||
|
* private and accessed through accessor members (SetVar(), GetVar()). The
|
||||||
|
* accessors must ensure that a value outside the allowable range is never
|
||||||
|
* returned and must clamp or reset to a default when an invalid setting
|
||||||
|
* is passed. Warnings may be printed.
|
||||||
|
* - Strings should be copied and retained locally.
|
||||||
|
* - Constructors must be defined and must initialize to the program default.
|
||||||
|
* - User-tunable settings should be stored here, not necessarily every
|
||||||
|
* concievable parameter a class initializer might take.
|
||||||
|
*/
|
||||||
|
class CConfig: public COSDConfig, public CRender3DConfig, public CModel3Config, public CSoundBoardConfig, public CDSBConfig
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_Config:
|
||||||
|
*
|
||||||
|
* Program-wide configuration settings object.
|
||||||
|
*/
|
||||||
|
extern CConfig g_Config;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // INCLUDED_CONFIG_H
|
|
@ -1283,7 +1283,7 @@ void CRender3D::SetStep(int stepID)
|
||||||
DebugLog("Render3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF);
|
DebugLog("Render3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, const char *vsFile, const char *fsFile)
|
BOOL CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes)
|
||||||
{
|
{
|
||||||
// Allocate memory for texture buffer
|
// Allocate memory for texture buffer
|
||||||
textureBuffer = new(std::nothrow) GLfloat[512*512*4];
|
textureBuffer = new(std::nothrow) GLfloat[512*512*4];
|
||||||
|
@ -1331,6 +1331,8 @@ BOOL CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
|
||||||
yOffs = yOffset;
|
yOffs = yOffset;
|
||||||
|
|
||||||
// Load shaders
|
// Load shaders
|
||||||
|
const char *vsFile = g_Config.vertexShaderFile.size() ? g_Config.vertexShaderFile.c_str() : NULL;
|
||||||
|
const char *fsFile = g_Config.fragmentShaderFile.size() ? g_Config.fragmentShaderFile.c_str() : NULL;
|
||||||
if (OKAY != LoadShaderProgram(&shaderProgram,&vertexShader,&fragmentShader,vsFile,fsFile,vertexShaderSource,fragmentShaderSource))
|
if (OKAY != LoadShaderProgram(&shaderProgram,&vertexShader,&fragmentShader,vsFile,fsFile,vertexShaderSource,fragmentShaderSource))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,27 @@ struct ModelCache
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
CRender3D Class Definition
|
CRender3D Classes
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CRender3DConfig:
|
||||||
|
*
|
||||||
|
* Settings used by CRender3D.
|
||||||
|
*/
|
||||||
|
class CRender3DConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
string vertexShaderFile; // path to vertex shader or "" to use internal shader
|
||||||
|
string fragmentShaderFile; // fragment shader
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
CRender3DConfig(void)
|
||||||
|
{
|
||||||
|
// nothing to do, strings will be clear to begin with
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CRender3D:
|
* CRender3D:
|
||||||
*
|
*
|
||||||
|
@ -244,30 +262,27 @@ public:
|
||||||
void SetStep(int stepID);
|
void SetStep(int stepID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init(xOffset, yOffset, xRes, yRes, vsFile, fsFile):
|
* Init(xOffset, yOffset, xRes, yRes):
|
||||||
*
|
*
|
||||||
* One-time initialization of the context. Must be called before any other
|
* One-time initialization of the context. Must be called before any other
|
||||||
* members (meaning it should be called even before being attached to any
|
* members (meaning it should be called even before being attached to any
|
||||||
* other objects that want to use it).
|
* other objects that want to use it).
|
||||||
*
|
*
|
||||||
|
* External shader files are loaded according to configuration settings.
|
||||||
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* xOffset X offset of display surface in pixels (in case resolution
|
* xOffset X offset of display surface in pixels (in case resolution
|
||||||
* is smaller than the true display surface).
|
* is smaller than the true display surface).
|
||||||
* yOffset Y offset.
|
* yOffset Y offset.
|
||||||
* xRes Horizontal resolution of display surface in pixels.
|
* xRes Horizontal resolution of display surface in pixels.
|
||||||
* yRes Vertical resolution.
|
* yRes Vertical resolution.
|
||||||
* vsFile External vertex shader path. If NULL, the internal
|
|
||||||
* shader is used.
|
|
||||||
* fsFile External fragment shader path. If NULL, the internal
|
|
||||||
* shader is used.
|
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* OKAY is successful, otherwise FAILED if a non-recoverable error
|
* OKAY is successful, otherwise FAILED if a non-recoverable error
|
||||||
* occurred. Any allocated memory will not be freed until the
|
* occurred. Any allocated memory will not be freed until the
|
||||||
* destructor is called. Prints own error messages.
|
* destructor is called. Prints own error messages.
|
||||||
*/
|
*/
|
||||||
BOOL Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes,
|
BOOL Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes);
|
||||||
const char *vsFile, const char *fsFile);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CRender3D(void):
|
* CRender3D(void):
|
||||||
|
|
|
@ -26,10 +26,8 @@
|
||||||
*
|
*
|
||||||
* To-Do List
|
* To-Do List
|
||||||
* ----------
|
* ----------
|
||||||
* - Allow default section name to be set at any time. To support this, must
|
* - Add an iterator to retrieve all settings associated with a given section.
|
||||||
* allow for multiple sections with the same name to co-exist. The search
|
* This will allow detection of invalid setting names, if the caller desires.
|
||||||
* procedure must look through all sections rather than stopping at the
|
|
||||||
* first section match. This is easy enough to add.
|
|
||||||
* - Add boolean on/off, true/false keywords.
|
* - Add boolean on/off, true/false keywords.
|
||||||
* - Note that linePtr does not necessarily correspond to actual lines in the
|
* - Note that linePtr does not necessarily correspond to actual lines in the
|
||||||
* file (newlines should be counted by the tokenizer for that).
|
* file (newlines should be counted by the tokenizer for that).
|
||||||
|
|
|
@ -63,7 +63,8 @@ public:
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* OKAY if the setting was found, FAIL otherwise. The type is not
|
* OKAY if the setting was found, FAIL otherwise. The type is not
|
||||||
* checked.
|
* checked. If the setting is not found, the output parameter will not
|
||||||
|
* be modified.
|
||||||
*/
|
*/
|
||||||
BOOL Get(string SectionName, string SettingName, int& value);
|
BOOL Get(string SectionName, string SettingName, int& value);
|
||||||
BOOL Get(string SectionName, string SettingName, unsigned& value);
|
BOOL Get(string SectionName, string SettingName, unsigned& value);
|
||||||
|
|
45
Src/Logger.h
45
Src/Logger.h
|
@ -1,45 +0,0 @@
|
||||||
#ifndef INCLUDED_LOGGER_H
|
|
||||||
#define INCLUDED_LOGGER_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CLogger
|
|
||||||
*
|
|
||||||
* Abstract class that receives log messages from Supermodel.
|
|
||||||
*/
|
|
||||||
class CLogger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void DebugLog(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
DebugLog(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoLog(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
InfoLog(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrorLog(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
ErrorLog(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void DebugLog(const char *fmt, va_list vl) = 0;
|
|
||||||
|
|
||||||
virtual void InfoLog(const char *fmt, va_list vl) = 0;
|
|
||||||
|
|
||||||
virtual void ErrorLog(const char *fmt, va_list vl) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // INCLUDED_LOGGER_H
|
|
|
@ -139,8 +139,14 @@ int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *i
|
||||||
int delta = (inRate<<8)/outRate; // (1/fout)/(1/fin)=fin/fout, 24.8 fixed point
|
int delta = (inRate<<8)/outRate; // (1/fout)/(1/fin)=fin/fout, 24.8 fixed point
|
||||||
int outIdx = 0;
|
int outIdx = 0;
|
||||||
int inIdx = 0;
|
int inIdx = 0;
|
||||||
INT16 leftSample, rightSample;
|
INT32 leftSample, rightSample, leftSoundSample, rightSoundSample;
|
||||||
INT16 v[2];
|
INT32 v[2], musicVol, soundVol;
|
||||||
|
|
||||||
|
// Obtain program volume settings and convert to 24.8 fixed point (0-200 -> 0x00-0x200)
|
||||||
|
musicVol = g_Config.GetMusicVolume();
|
||||||
|
soundVol = g_Config.GetSoundVolume();
|
||||||
|
musicVol = (INT32) ((float) 0x100 * (float) musicVol / 100.0f);
|
||||||
|
soundVol = (INT32) ((float) 0x100 * (float) soundVol / 100.0f);
|
||||||
|
|
||||||
// Scale volume from 0x00-0xFF -> 0x00-0x100 (24.8 fixed point)
|
// Scale volume from 0x00-0xFF -> 0x00-0x100 (24.8 fixed point)
|
||||||
v[0] = (INT16) ((float) 0x100 * (float) volumeL / 255.0f);
|
v[0] = (INT16) ((float) 0x100 * (float) volumeL / 255.0f);
|
||||||
|
@ -153,13 +159,17 @@ int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *i
|
||||||
leftSample = ((int)inL[inIdx]*pFrac+(int)inL[inIdx+1]*nFrac) >> 8; // left channel
|
leftSample = ((int)inL[inIdx]*pFrac+(int)inL[inIdx+1]*nFrac) >> 8; // left channel
|
||||||
rightSample = ((int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac) >> 8; // right channel
|
rightSample = ((int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac) >> 8; // right channel
|
||||||
|
|
||||||
// Apply volume
|
// Apply DSB volume and then overall music volume setting
|
||||||
leftSample = (leftSample*v[0]) >> 8;
|
leftSample = (leftSample*v[0]*musicVol) >> 16; // multiplied by two 24.8 numbers, shift back by 16
|
||||||
rightSample = (rightSample*v[0]) >> 8;
|
rightSample = (rightSample*v[0]*musicVol) >> 16;
|
||||||
|
|
||||||
|
// Apply sound volume setting
|
||||||
|
leftSoundSample = (outL[outIdx]*soundVol) >> 8;
|
||||||
|
rightSoundSample = (outR[outIdx]*soundVol) >> 8;
|
||||||
|
|
||||||
// Mix and output
|
// Mix and output
|
||||||
outL[outIdx] = MixAndClip(outL[outIdx], leftSample);
|
outL[outIdx] = MixAndClip(leftSoundSample, leftSample);
|
||||||
outR[outIdx] = MixAndClip(outR[outIdx], rightSample);
|
outR[outIdx] = MixAndClip(rightSoundSample, rightSample);
|
||||||
outIdx++;
|
outIdx++;
|
||||||
|
|
||||||
// Time step
|
// Time step
|
||||||
|
@ -413,6 +423,15 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
|
||||||
int cycles;
|
int cycles;
|
||||||
UINT8 v;
|
UINT8 v;
|
||||||
|
|
||||||
|
if (!g_Config.emulateDSB)
|
||||||
|
{
|
||||||
|
// DSB code applies SCSP volume, too, so we must still mix
|
||||||
|
memset(mpegL, 0, (32000/60+2)*sizeof(INT16));
|
||||||
|
memset(mpegR, 0, (32000/60+2)*sizeof(INT16));
|
||||||
|
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, 0, 0, 44100/60, 32000/60+2, 44100, 32000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// While FIFO not empty, fire interrupts, run for up to one frame
|
// While FIFO not empty, fire interrupts, run for up to one frame
|
||||||
for (cycles = (4000000/60)/4; (cycles > 0) && (fifoIdxR != fifoIdxW); )
|
for (cycles = (4000000/60)/4; (cycles > 0) && (fifoIdxR != fifoIdxW); )
|
||||||
{
|
{
|
||||||
|
@ -948,6 +967,15 @@ void CDSB2::SendCommand(UINT8 data)
|
||||||
void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
|
void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
|
||||||
{
|
{
|
||||||
#ifdef SUPERMODEL_SOUND
|
#ifdef SUPERMODEL_SOUND
|
||||||
|
if (!g_Config.emulateDSB)
|
||||||
|
{
|
||||||
|
// DSB code applies SCSP volume, too, so we must still mix
|
||||||
|
memset(mpegL, 0, (32000/60+2)*sizeof(INT16));
|
||||||
|
memset(mpegR, 0, (32000/60+2)*sizeof(INT16));
|
||||||
|
retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, volume[0], volume[1], 44100/60, 32000/60+2, 44100, 32000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
M68KSetContext(&M68K);
|
M68KSetContext(&M68K);
|
||||||
//printf("DSB2 run frame PC=%06X\n", M68KGetPC());
|
//printf("DSB2 run frame PC=%06X\n", M68KGetPC());
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,71 @@
|
||||||
#include "CPU/Bus.h"
|
#include "CPU/Bus.h"
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Configuration
|
||||||
|
|
||||||
|
Because DSB code mixes both the sound board SCSP and MPEG audio together, both
|
||||||
|
volume settings are stored here (for now).
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CDSBConfig:
|
||||||
|
*
|
||||||
|
* Settings used by CDSB.
|
||||||
|
*/
|
||||||
|
class CDSBConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool emulateDSB; // DSB emulation (enabled if TRUE)
|
||||||
|
|
||||||
|
// Sound (SCSP) volume (0-200, 100 being full amplitude)
|
||||||
|
inline void SetSoundVolume(unsigned vol)
|
||||||
|
{
|
||||||
|
if (vol > 200)
|
||||||
|
{
|
||||||
|
ErrorLog("Sound volume cannot exceed 200%%; setting to 100%%.\n");
|
||||||
|
vol = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
soundVol = vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned GetSoundVolume(void)
|
||||||
|
{
|
||||||
|
return soundVol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Music (DSB MPEG) volume (0-200)
|
||||||
|
inline void SetMusicVolume(unsigned vol)
|
||||||
|
{
|
||||||
|
if (vol > 200)
|
||||||
|
{
|
||||||
|
ErrorLog("Music volume cannot exceed 200%%; setting to 100%%.\n");
|
||||||
|
vol = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicVol = vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned GetMusicVolume(void)
|
||||||
|
{
|
||||||
|
return musicVol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
CDSBConfig(void)
|
||||||
|
{
|
||||||
|
emulateDSB = true;
|
||||||
|
soundVol = 100;
|
||||||
|
musicVol = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned soundVol;
|
||||||
|
unsigned musicVol;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Resampling
|
Resampling
|
||||||
|
|
||||||
|
|
|
@ -184,9 +184,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -1870,7 +1870,7 @@ void CModel3::ClearNVRAM(void)
|
||||||
void CModel3::RunFrame(void)
|
void CModel3::RunFrame(void)
|
||||||
{
|
{
|
||||||
// See if currently running multi-threaded
|
// See if currently running multi-threaded
|
||||||
if (multiThreaded)
|
if (g_Config.multiThreaded)
|
||||||
{
|
{
|
||||||
// If so, check all threads are up and running
|
// If so, check all threads are up and running
|
||||||
if (!StartThreads())
|
if (!StartThreads())
|
||||||
|
@ -1924,7 +1924,7 @@ void CModel3::RunFrame(void)
|
||||||
|
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in CModel3::RunFrame: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in CModel3::RunFrame: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModel3::StartThreads()
|
bool CModel3::StartThreads()
|
||||||
|
@ -1966,7 +1966,7 @@ bool CModel3::StartThreads()
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Unable to create threads and/or synchronization objects: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Unable to create threads and/or synchronization objects: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
DeleteThreadObjects();
|
DeleteThreadObjects();
|
||||||
multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2066,7 +2066,7 @@ void CModel3::RunSoundBoardThread()
|
||||||
|
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in sound board thread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in sound board thread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
#ifdef SUPERMODEL_DRIVEBOARD
|
||||||
|
@ -2097,14 +2097,14 @@ void CModel3::RunDriveBoardThread()
|
||||||
|
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in drive board thread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in drive board thread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CModel3::RunMainBoardFrame(void)
|
void CModel3::RunMainBoardFrame(void)
|
||||||
{
|
{
|
||||||
// Run the PowerPC for a frame
|
// Run the PowerPC for a frame
|
||||||
ppc_execute(ppcFrequency/60-10000);
|
ppc_execute(g_Config.GetPowerPCFrequency()*1000000/60-10000);
|
||||||
//printf("PC=%08X LR=%08X\n", ppc_get_pc(), ppc_get_lr());
|
//printf("PC=%08X LR=%08X\n", ppc_get_pc(), ppc_get_lr());
|
||||||
|
|
||||||
// VBlank
|
// VBlank
|
||||||
|
@ -2612,16 +2612,10 @@ void CModel3::AttachInputs(CInputs *InputsPtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model 3 initialization. Some initialization is deferred until ROMs are loaded in LoadROMSet()
|
// Model 3 initialization. Some initialization is deferred until ROMs are loaded in LoadROMSet()
|
||||||
BOOL CModel3::Init(unsigned ppcFrequencyParam, BOOL multiThreadedParam)
|
BOOL CModel3::Init(void)
|
||||||
{
|
{
|
||||||
float memSizeMB = (float)MEMORY_POOL_SIZE/(float)0x100000;
|
float memSizeMB = (float)MEMORY_POOL_SIZE/(float)0x100000;
|
||||||
|
|
||||||
// PowerPC frequency
|
|
||||||
ppcFrequency = ppcFrequencyParam;
|
|
||||||
if (ppcFrequency < 1000000)
|
|
||||||
ppcFrequency = 1000000;
|
|
||||||
multiThreaded = !!multiThreadedParam;
|
|
||||||
|
|
||||||
// Allocate all memory for ROMs and PPC RAM
|
// Allocate all memory for ROMs and PPC RAM
|
||||||
memoryPool = new(std::nothrow) UINT8[MEMORY_POOL_SIZE];
|
memoryPool = new(std::nothrow) UINT8[MEMORY_POOL_SIZE];
|
||||||
if (NULL == memoryPool)
|
if (NULL == memoryPool)
|
||||||
|
@ -2689,7 +2683,7 @@ CModel3::CModel3(void)
|
||||||
|
|
||||||
securityPtr = 0;
|
securityPtr = 0;
|
||||||
|
|
||||||
multiThreaded = true;
|
g_Config.multiThreaded = true;
|
||||||
startedThreads = false;
|
startedThreads = false;
|
||||||
sndBrdThread = NULL;
|
sndBrdThread = NULL;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
#ifdef SUPERMODEL_DRIVEBOARD
|
||||||
|
|
|
@ -22,12 +22,48 @@
|
||||||
/*
|
/*
|
||||||
* Model3.h
|
* Model3.h
|
||||||
*
|
*
|
||||||
* Header file defining the CModel3 and CModel3Inputs classes.
|
* Header file defining the CModel3, CModel3Config, and CModel3Inputs classes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INCLUDED_MODEL3_H
|
#ifndef INCLUDED_MODEL3_H
|
||||||
#define INCLUDED_MODEL3_H
|
#define INCLUDED_MODEL3_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CModel3Config:
|
||||||
|
*
|
||||||
|
* Settings used by CModel3.
|
||||||
|
*/
|
||||||
|
class CModel3Config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool multiThreaded; // Multi-threading (enabled if TRUE)
|
||||||
|
|
||||||
|
// PowerPC clock frequency in MHz (minimum: 1 MHz)
|
||||||
|
inline void SetPowerPCFrequency(unsigned f)
|
||||||
|
{
|
||||||
|
if ((f<1) || (f>1000))
|
||||||
|
{
|
||||||
|
ErrorLog("PowerPC frequency must be between 1 and 1000 MHz; setting to 40 MHz.");
|
||||||
|
f = 40;
|
||||||
|
}
|
||||||
|
ppcFrequency = f*1000000;
|
||||||
|
}
|
||||||
|
inline unsigned GetPowerPCFrequency(void)
|
||||||
|
{
|
||||||
|
return ppcFrequency/1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
CModel3Config(void)
|
||||||
|
{
|
||||||
|
multiThreaded = false; // disable by default
|
||||||
|
ppcFrequency = 40*1000000; // 40 MHz
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned ppcFrequency; // in Hz
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CModel3:
|
* CModel3:
|
||||||
*
|
*
|
||||||
|
@ -228,20 +264,16 @@ public:
|
||||||
void AttachInputs(CInputs *InputsPtr);
|
void AttachInputs(CInputs *InputsPtr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init(ppcFrequencyParam, multiThreadedParam):
|
* Init(void):
|
||||||
*
|
*
|
||||||
* One-time initialization of the context. Must be called prior to all
|
* One-time initialization of the context. Must be called prior to all
|
||||||
* other members. Allocates memory and initializes device states.
|
* other members. Allocates memory and initializes device states.
|
||||||
*
|
*
|
||||||
* Parameters:
|
|
||||||
* ppcFrequencyParam PowerPC frequency in Hz. If less than 1 MHz,
|
|
||||||
* will be clamped to 1 MHz.
|
|
||||||
*
|
|
||||||
* Returns:
|
* Returns:
|
||||||
* OKAY is successful, otherwise FAILED if a non-recoverable error
|
* OKAY is successful, otherwise FAILED if a non-recoverable error
|
||||||
* occurred. Prints own error messages.
|
* occurred. Prints own error messages.
|
||||||
*/
|
*/
|
||||||
BOOL Init(unsigned ppcFrequencyParam, BOOL multiThreadedParam);
|
BOOL Init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CModel3(void):
|
* CModel3(void):
|
||||||
|
@ -321,10 +353,8 @@ private:
|
||||||
|
|
||||||
// PowerPC
|
// PowerPC
|
||||||
PPC_FETCH_REGION PPCFetchRegions[3];
|
PPC_FETCH_REGION PPCFetchRegions[3];
|
||||||
unsigned ppcFrequency; // clock frequency (Hz)
|
|
||||||
|
|
||||||
// Multiple threading
|
// Multiple threading
|
||||||
bool multiThreaded; // True if should run CPUs in multiple threads, otherwise everything is run in a single thread
|
|
||||||
bool startedThreads; // True if threads have been created and started
|
bool startedThreads; // True if threads have been created and started
|
||||||
CThread *sndBrdThread; // Sound board thread
|
CThread *sndBrdThread; // Sound board thread
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
#ifdef SUPERMODEL_DRIVEBOARD
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
//#define SUPERMODEL_LOG_AUDIO // define this to log all audio to sound.bin
|
#define SUPERMODEL_LOG_AUDIO // define this to log all audio to sound.bin
|
||||||
#ifdef SUPERMODEL_LOG_AUDIO
|
#ifdef SUPERMODEL_LOG_AUDIO
|
||||||
static FILE *soundFP;
|
static FILE *soundFP;
|
||||||
#endif
|
#endif
|
||||||
|
@ -362,10 +362,17 @@ void CSoundBoard::RunFrame(void)
|
||||||
{
|
{
|
||||||
#ifdef SUPERMODEL_SOUND
|
#ifdef SUPERMODEL_SOUND
|
||||||
// Run sound board first to generate SCSP audio
|
// Run sound board first to generate SCSP audio
|
||||||
M68KSetContext(&M68K);
|
if (g_Config.emulateSCSP)
|
||||||
SCSP_Update();
|
{
|
||||||
M68KGetContext(&M68K);
|
M68KSetContext(&M68K);
|
||||||
//memset(audioL, 0, 44100/60*sizeof(INT16));memset(audioR, 0, 44100/60*sizeof(INT16)); // clear, I want DSB only
|
SCSP_Update();
|
||||||
|
M68KGetContext(&M68K);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(audioL, 0, 44100/60*sizeof(INT16));
|
||||||
|
memset(audioR, 0, 44100/60*sizeof(INT16));
|
||||||
|
}
|
||||||
|
|
||||||
// Run DSB and mix with existing audio
|
// Run DSB and mix with existing audio
|
||||||
if (NULL != DSB)
|
if (NULL != DSB)
|
||||||
|
|
|
@ -32,6 +32,23 @@
|
||||||
#include "CPU/Bus.h"
|
#include "CPU/Bus.h"
|
||||||
#include "Model3/DSB.h"
|
#include "Model3/DSB.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSoundBoardConfig:
|
||||||
|
*
|
||||||
|
* Settings used by CSoundBoard.
|
||||||
|
*/
|
||||||
|
class CSoundBoardConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool emulateSCSP; // SCSP emulation (enabled if TRUE)
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
CSoundBoardConfig(void)
|
||||||
|
{
|
||||||
|
emulateSCSP = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CSoundBoard:
|
* CSoundBoard:
|
||||||
*
|
*
|
||||||
|
|
286
Src/OSD/Logger.h
Normal file
286
Src/OSD/Logger.h
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
/*
|
||||||
|
* Logger.h
|
||||||
|
*
|
||||||
|
* Header file for message logging. The OSD code is expected to set up a
|
||||||
|
* default logger (CFileLogger).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_LOGGER_H
|
||||||
|
#define INCLUDED_LOGGER_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Class Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CLogger
|
||||||
|
*
|
||||||
|
* Abstract class that receives log messages from Supermodel's log functions.
|
||||||
|
* The logger object handles actual output of messages. Use the function-based
|
||||||
|
* message logging interface to generate messages.
|
||||||
|
*/
|
||||||
|
class CLogger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* DebugLog(fmt, ...):
|
||||||
|
* DebugLog(fmt, vl):
|
||||||
|
*
|
||||||
|
* Prints to debug log. If DEBUG is not defined, will end up doing nothing.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* fmt printf()-style format string.
|
||||||
|
* ... Variable number of parameters, corresponding to format
|
||||||
|
* string.
|
||||||
|
* vl Variable arguments already stored in a list.
|
||||||
|
*/
|
||||||
|
void DebugLog(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
DebugLog(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DebugLog(const char *fmt, va_list vl) = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InfoLog(fmt, ...):
|
||||||
|
* InfoLog(fmt, vl):
|
||||||
|
*
|
||||||
|
* Prints to error log but does not output an error to stderr. This is
|
||||||
|
* useful for printing session information to the error log.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* fmt printf()-style format string.
|
||||||
|
* ... Variable number of parameters, corresponding to format
|
||||||
|
* string.
|
||||||
|
* vl Variable arguments already stored in a list.
|
||||||
|
*/
|
||||||
|
void InfoLog(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
InfoLog(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void InfoLog(const char *fmt, va_list vl) = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorLog(fmt, ...):
|
||||||
|
* ErrorLog(fmt, vl):
|
||||||
|
*
|
||||||
|
* Prints to error log and outputs an error message to stderr.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* fmt printf()-style format string.
|
||||||
|
* ... Variable number of parameters, corresponding to format
|
||||||
|
* string.
|
||||||
|
* vl Variable arguments already stored in a list.
|
||||||
|
*/
|
||||||
|
void ErrorLog(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
ErrorLog(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ErrorLog(const char *fmt, va_list vl) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CFileLogger:
|
||||||
|
*
|
||||||
|
* Default logger that logs to debug and error log files. Files are opened and
|
||||||
|
* closed for each message in order to preserve contents in case of program
|
||||||
|
* crash.
|
||||||
|
*/
|
||||||
|
class CFileLogger : public CLogger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void DebugLog(const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
char string[1024];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(m_debugLogFile, "ab");
|
||||||
|
if (NULL != fp)
|
||||||
|
{
|
||||||
|
vsprintf(string, fmt, vl);
|
||||||
|
fprintf(fp, string);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
#endif // DEBUG
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoLog(const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
char string[4096];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
vsprintf(string, fmt, vl);
|
||||||
|
|
||||||
|
fp = fopen(m_errorLogFile, "ab");
|
||||||
|
if (NULL != fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "%s\n", string);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLogger::DebugLog("Info: ");
|
||||||
|
CLogger::DebugLog(string);
|
||||||
|
CLogger::DebugLog("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorLog(const char *fmt, va_list vl)
|
||||||
|
{
|
||||||
|
char string[4096];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
vsprintf(string, fmt, vl);
|
||||||
|
fprintf(stderr, "Error: %s\n", string);
|
||||||
|
|
||||||
|
fp = fopen(m_errorLogFile, "ab");
|
||||||
|
if (NULL != fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "%s\n", string);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLogger::DebugLog("Error: ");
|
||||||
|
CLogger::DebugLog(string);
|
||||||
|
CLogger::DebugLog("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClearLogs():
|
||||||
|
*
|
||||||
|
* Clears all log files.
|
||||||
|
*/
|
||||||
|
void ClearLogs(void)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
ClearLog(m_debugLogFile, "Supermodel v"SUPERMODEL_VERSION" Debug Log");
|
||||||
|
#endif // DEBUG
|
||||||
|
ClearLog(m_errorLogFile, "Supermodel v"SUPERMODEL_VERSION" Error Log");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClearLog(file, title):
|
||||||
|
*
|
||||||
|
* Clears a log file.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* file File name.
|
||||||
|
* title A string that is written to the file after it is cleared.
|
||||||
|
*/
|
||||||
|
void ClearLog(const char *file, const char *title)
|
||||||
|
{
|
||||||
|
FILE *fp = fopen(file, "w");
|
||||||
|
if (NULL != fp)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
fprintf(fp, "%s\n", title);
|
||||||
|
for (i = 0; i < strlen(title); i++)
|
||||||
|
fputc('-', fp);
|
||||||
|
fprintf(fp, "\n\n");
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CFileLogger(debugLogFile, errorLogFile):
|
||||||
|
*
|
||||||
|
* Constructor. Specifies debug and error log files to use.
|
||||||
|
*/
|
||||||
|
CFileLogger(const char *debugLogFile, const char *errorLogFile) :
|
||||||
|
m_debugLogFile(debugLogFile), m_errorLogFile(errorLogFile)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *m_debugLogFile;
|
||||||
|
const char *m_errorLogFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Log Functions
|
||||||
|
|
||||||
|
Message logging interface. All messages are passed by the OSD layer to the
|
||||||
|
currently active logger object.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DebugLog(fmt, ...):
|
||||||
|
*
|
||||||
|
* Prints debugging information. The OSD layer may choose to print this to a
|
||||||
|
* log file, the screen, neither, or both. Newlines and other formatting codes
|
||||||
|
* must be explicitly included.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* fmt A format string (the same as printf()).
|
||||||
|
* ... Variable number of arguments, as required by format string.
|
||||||
|
*/
|
||||||
|
extern void DebugLog(const char *fmt, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorLog(fmt, ...):
|
||||||
|
*
|
||||||
|
* Prints error information. Errors need not require program termination and
|
||||||
|
* may simply be informative warnings to the user. Newlines should not be
|
||||||
|
* included in the format string -- they are automatically added at the end of
|
||||||
|
* a line.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* fmt A format string (the same as printf()).
|
||||||
|
* ... Variable number of arguments, as required by format string.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Must always return FAIL.
|
||||||
|
*/
|
||||||
|
extern BOOL ErrorLog(const char *fmt, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InfoLog(fmt, ...);
|
||||||
|
*
|
||||||
|
* Prints information to the error log file but does not print to stderr. This
|
||||||
|
* is useful for logging non-error information. Newlines are automatically
|
||||||
|
* appended.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* fmt Format string (same as printf()).
|
||||||
|
* ... Variable number of arguments as required by format string.
|
||||||
|
*/
|
||||||
|
extern void InfoLog(const char *fmt, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SetLogger(Logger):
|
||||||
|
*
|
||||||
|
* Sets the logger object to use.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* Logger New logger object. If NULL, log messages will not be output.
|
||||||
|
*/
|
||||||
|
extern void SetLogger(CLogger *Logger);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetLogger(void):
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Current logger object (NULL if none has been set).
|
||||||
|
*/
|
||||||
|
extern CLogger *GetLogger(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // INCLUDED_LOGGER_H
|
|
@ -40,10 +40,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <stdarg.h>
|
#include <cstdarg>
|
||||||
#include "Pkgs/glew.h"
|
#include "Pkgs/glew.h"
|
||||||
#ifdef SUPERMODEL_OSX
|
#ifdef SUPERMODEL_OSX
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
@ -57,15 +57,69 @@
|
||||||
#include "DirectInputSystem.h"
|
#include "DirectInputSystem.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CLogger *GetLogger();
|
|
||||||
void SetLogger(CLogger *logger);
|
/******************************************************************************
|
||||||
|
Error and Debug Logging
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// Log file names
|
||||||
|
#define DEBUG_LOG_FILE "debug.log"
|
||||||
|
#define ERROR_LOG_FILE "error.log"
|
||||||
|
|
||||||
|
// Logger object is used to redirect log messages appropriately
|
||||||
|
static CLogger *s_Logger = NULL;
|
||||||
|
|
||||||
|
CLogger *GetLogger()
|
||||||
|
{
|
||||||
|
return s_Logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLogger(CLogger *Logger)
|
||||||
|
{
|
||||||
|
s_Logger = Logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugLog(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (s_Logger == NULL)
|
||||||
|
return;
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
s_Logger->DebugLog(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfoLog(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (s_Logger == NULL)
|
||||||
|
return;
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
s_Logger->InfoLog(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ErrorLog(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (s_Logger == NULL)
|
||||||
|
return FAIL;
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, fmt);
|
||||||
|
s_Logger->ErrorLog(fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Display Management
|
Display Management
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Position and size of rectangular region within OpenGL display to render to
|
* Position and size of rectangular region within OpenGL display to render to.
|
||||||
|
* Unlike the g_Config object, these end up containing the actual resolution
|
||||||
|
* (and computed offsets within the viewport) that will be rendered based on
|
||||||
|
* what was obtained from SDL.
|
||||||
*/
|
*/
|
||||||
unsigned xOffset, yOffset; // offset of renderer output within OpenGL viewport
|
unsigned xOffset, yOffset; // offset of renderer output within OpenGL viewport
|
||||||
unsigned xRes, yRes; // renderer output resolution (can be smaller than GL viewport)
|
unsigned xRes, yRes; // renderer output resolution (can be smaller than GL viewport)
|
||||||
|
@ -162,8 +216,11 @@ static BOOL CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Configuration
|
Configuration
|
||||||
|
|
||||||
|
Configuration file management and input settings.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#define CONFIG_FILE_PATH "Config/Supermodel.ini"
|
#define CONFIG_FILE_PATH "Config/Supermodel.ini"
|
||||||
|
@ -172,19 +229,12 @@ static BOOL CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned *
|
||||||
";\n"
|
";\n"
|
||||||
|
|
||||||
// Create and configure inputs
|
// Create and configure inputs
|
||||||
static CInputs *CreateInputs(CInputSystem *InputSystem, BOOL configure)
|
static bool ConfigureInputs(CInputs *Inputs, bool configure)
|
||||||
{
|
{
|
||||||
// Create and initialize inputs
|
|
||||||
CInputs* Inputs = new CInputs(InputSystem);
|
|
||||||
if (!Inputs->Initialize())
|
|
||||||
{
|
|
||||||
ErrorLog("Unable to initalize inputs.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open and parse configuration file
|
// Open and parse configuration file
|
||||||
CINIFile INI;
|
CINIFile INI;
|
||||||
INI.Open(CONFIG_FILE_PATH); // doesn't matter if it exists or not, will get overwritten
|
INI.Open(CONFIG_FILE_PATH); // doesn't matter if it exists or not, will get overwritten
|
||||||
|
INI.SetDefaultSectionName("Global");
|
||||||
INI.Parse();
|
INI.Parse();
|
||||||
|
|
||||||
Inputs->ReadFromINIFile(&INI, "Global");
|
Inputs->ReadFromINIFile(&INI, "Global");
|
||||||
|
@ -195,10 +245,7 @@ static CInputs *CreateInputs(CInputSystem *InputSystem, BOOL configure)
|
||||||
// Open an SDL window
|
// Open an SDL window
|
||||||
unsigned xOffset, yOffset, xRes=496, yRes=384;
|
unsigned xOffset, yOffset, xRes=496, yRes=384;
|
||||||
if (OKAY != CreateGLScreen("Supermodel - Configuring Inputs...",&xOffset,&yOffset,&xRes,&yRes,FALSE,FALSE))
|
if (OKAY != CreateGLScreen("Supermodel - Configuring Inputs...",&xOffset,&yOffset,&xRes,&yRes,FALSE,FALSE))
|
||||||
{
|
return (bool) ErrorLog("Unable to start SDL to configure inputs.\n");
|
||||||
ErrorLog("Unable to start SDL to configure inputs.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure the inputs
|
// Configure the inputs
|
||||||
if (Inputs->ConfigureInputs(NULL, xOffset, yOffset, xRes, yRes))
|
if (Inputs->ConfigureInputs(NULL, xOffset, yOffset, xRes, yRes))
|
||||||
|
@ -216,9 +263,82 @@ static CInputs *CreateInputs(CInputSystem *InputSystem, BOOL configure)
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inputs;
|
INI.Close();
|
||||||
|
return OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply configuration settings from configuration file
|
||||||
|
static void ApplySettings(CInputs *Inputs, CINIFile *INI, const char *section)
|
||||||
|
{
|
||||||
|
unsigned x;
|
||||||
|
string String;
|
||||||
|
|
||||||
|
// Model 3
|
||||||
|
if (OKAY == INI->Get(section, "MultiThreaded", x))
|
||||||
|
g_Config.multiThreaded = x ? true : false;
|
||||||
|
if (OKAY == INI->Get(section, "PowerPCFrequency", x))
|
||||||
|
g_Config.SetPowerPCFrequency(x);
|
||||||
|
|
||||||
|
// 3D renderer
|
||||||
|
INI->Get(section, "VertexShader", g_Config.vertexShaderFile);
|
||||||
|
INI->Get(section, "FragmentShader", g_Config.fragmentShaderFile);
|
||||||
|
|
||||||
|
// SCSP and DSB
|
||||||
|
if (OKAY == INI->Get(section, "SoundVolume", x))
|
||||||
|
g_Config.SetSoundVolume(x);
|
||||||
|
if (OKAY == INI->Get(section, "MusicVolume", x))
|
||||||
|
g_Config.SetMusicVolume(x);
|
||||||
|
if (OKAY == INI->Get(section, "EmulateSCSP", x))
|
||||||
|
g_Config.emulateSCSP = x ? true : false;
|
||||||
|
if (OKAY == INI->Get(section, "EmulateDSB", x))
|
||||||
|
g_Config.emulateDSB = x ? true : false;
|
||||||
|
|
||||||
|
// OSD
|
||||||
|
INI->Get(section, "XResolution", g_Config.xRes);
|
||||||
|
INI->Get(section, "YResolution", g_Config.yRes);
|
||||||
|
if (OKAY == INI->Get(section, "FullScreen", x))
|
||||||
|
g_Config.fullScreen = x ? true : false;
|
||||||
|
if (OKAY == INI->Get(section, "Throttle", x))
|
||||||
|
g_Config.throttle = x ? true : false;
|
||||||
|
if (OKAY == INI->Get(section, "ShowFrameRate", x))
|
||||||
|
g_Config.showFPS = x ? true : false;
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
if (Inputs != NULL)
|
||||||
|
Inputs->ReadFromINIFile(INI, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read settings (from a specific section) from the config file
|
||||||
|
static void ReadConfigFile(CInputs *Inputs, const char *section)
|
||||||
|
{
|
||||||
|
CINIFile INI;
|
||||||
|
|
||||||
|
INI.Open(CONFIG_FILE_PATH);
|
||||||
|
INI.SetDefaultSectionName("Global"); // required to read settings not associated with a specific section
|
||||||
|
INI.Parse();
|
||||||
|
ApplySettings(Inputs, &INI, section);
|
||||||
|
INI.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
static void DumpConfig(void)
|
||||||
|
{
|
||||||
|
printf("MultiThreaded = %d\n", g_Config.multiThreaded);
|
||||||
|
printf("PowerPCFrequency = %d\n", g_Config.GetPowerPCFrequency());
|
||||||
|
printf("EmulateSCSP = %d\n", g_Config.emulateSCSP);
|
||||||
|
printf("EmulateDSB = %d\n", g_Config.emulateDSB);
|
||||||
|
printf("VertexShader = %s\n", g_Config.vertexShaderFile.c_str());
|
||||||
|
printf("FragmentShader = %s\n", g_Config.fragmentShaderFile.c_str());
|
||||||
|
printf("XResolution = %d\n", g_Config.xRes);
|
||||||
|
printf("YResolution = %d\n", g_Config.yRes);
|
||||||
|
printf("FullScreen = %d\n", g_Config.fullScreen);
|
||||||
|
printf("Throttle = %d\n", g_Config.throttle);
|
||||||
|
printf("ShowFrameRate = %d\n", g_Config.showFPS);
|
||||||
|
printf("InputSystem = %s\n", g_Config.GetInputSystem());
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Save States and NVRAM
|
Save States and NVRAM
|
||||||
|
|
||||||
|
@ -364,14 +484,11 @@ static void LoadNVRAM(CModel3 *Model3)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
int Supermodel(const char *zipFile, CModel3 *Model3, CInputs *Inputs, Debugger::CDebugger *Debugger, unsigned ppcFrequency, BOOL multiThreaded,
|
int Supermodel(const char *zipFile, CModel3 *Model3, CInputs *Inputs, Debugger::CDebugger *Debugger, CINIFile *CmdLine)
|
||||||
unsigned xResParam, unsigned yResParam, BOOL keepAspectRatio, BOOL fullScreen, BOOL noThrottle, BOOL showFPS,
|
|
||||||
const char *vsFile, const char *fsFile)
|
|
||||||
{
|
{
|
||||||
CLogger *oldLogger;
|
CLogger *oldLogger;
|
||||||
#else
|
#else
|
||||||
int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL multiThreaded, unsigned xResParam, unsigned yResParam,
|
int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine)
|
||||||
BOOL keepAspectRatio, BOOL fullScreen, BOOL noThrottle, BOOL showFPS, const char *vsFile, const char *fsFile)
|
|
||||||
{
|
{
|
||||||
CModel3 *Model3 = new CModel3();
|
CModel3 *Model3 = new CModel3();
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
@ -385,23 +502,30 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
BOOL paused = 0;
|
BOOL paused = 0;
|
||||||
|
|
||||||
// Info log user options
|
// Info log user options
|
||||||
InfoLog("PowerPC frequency: %d Hz", ppcFrequency);
|
InfoLog("PowerPC frequency: %d Hz", g_Config.GetPowerPCFrequency());
|
||||||
InfoLog("Resolution: %dx%d (%s)", xResParam, yResParam, fullScreen?"full screen":"windowed");
|
InfoLog("Resolution requested: %dx%d (%s)", g_Config.xRes, g_Config.yRes, g_Config.fullScreen?"full screen":"windowed");
|
||||||
InfoLog("Frame rate limiting: %s", noThrottle?"Disabled":"Enabled");
|
InfoLog("Frame rate limiting: %s", g_Config.throttle?"Enabled":"Disabled");
|
||||||
|
|
||||||
// Initialize and load ROMs
|
// Initialize and load ROMs
|
||||||
Model3->Init(ppcFrequency, multiThreaded);
|
if (OKAY != Model3->Init())
|
||||||
|
return 1;
|
||||||
if (OKAY != Model3->LoadROMSet(Model3GameList, zipFile))
|
if (OKAY != Model3->LoadROMSet(Model3GameList, zipFile))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
// Apply game-specific settings and then, lastly, command line settings
|
||||||
|
ReadConfigFile(Inputs, Model3->GetGameInfo()->id);
|
||||||
|
//DumpConfig();
|
||||||
|
ApplySettings(Inputs, CmdLine, "Global");
|
||||||
|
//DumpConfig();
|
||||||
|
|
||||||
// Load NVRAM
|
// Load NVRAM
|
||||||
LoadNVRAM(Model3);
|
LoadNVRAM(Model3);
|
||||||
|
|
||||||
// Start up SDL and open a GL window
|
// Start up SDL and open a GL window
|
||||||
xRes = xResParam;
|
xRes = g_Config.xRes;
|
||||||
yRes = yResParam;
|
yRes = g_Config.yRes;
|
||||||
sprintf(titleStr, "Supermodel - %s", Model3->GetGameInfo()->title);
|
sprintf(titleStr, "Supermodel - %s", Model3->GetGameInfo()->title);
|
||||||
if (OKAY != CreateGLScreen(titleStr,&xOffset,&yOffset,&xRes,&yRes,keepAspectRatio,fullScreen))
|
if (OKAY != CreateGLScreen(titleStr,&xOffset,&yOffset,&xRes,&yRes,TRUE,g_Config.fullScreen))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Initialize audio system
|
// Initialize audio system
|
||||||
|
@ -409,7 +533,7 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Hide mouse if fullscreen
|
// Hide mouse if fullscreen
|
||||||
Inputs->GetInputSystem()->SetMouseVisibility(!fullScreen);
|
Inputs->GetInputSystem()->SetMouseVisibility(!g_Config.fullScreen);
|
||||||
|
|
||||||
// Attach the inputs to the emulator
|
// Attach the inputs to the emulator
|
||||||
Model3->AttachInputs(Inputs);
|
Model3->AttachInputs(Inputs);
|
||||||
|
@ -417,7 +541,7 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
// Initialize the renderer
|
// Initialize the renderer
|
||||||
if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes))
|
if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes))
|
||||||
goto QuitError;
|
goto QuitError;
|
||||||
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, vsFile, fsFile))
|
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes))
|
||||||
goto QuitError;
|
goto QuitError;
|
||||||
Model3->AttachRenderers(Render2D,Render3D);
|
Model3->AttachRenderers(Render2D,Render3D);
|
||||||
|
|
||||||
|
@ -521,7 +645,7 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
// Dump input states
|
// Dump input states
|
||||||
Inputs->DumpState(Model3->GetGameInfo());
|
Inputs->DumpState(Model3->GetGameInfo());
|
||||||
}
|
}
|
||||||
else if (Inputs->uiToggleCursor->Pressed() && fullScreen)
|
else if (Inputs->uiToggleCursor->Pressed() && g_Config.fullScreen)
|
||||||
{
|
{
|
||||||
// Toggle cursor in full screen mode
|
// Toggle cursor in full screen mode
|
||||||
showCursor = !showCursor;
|
showCursor = !showCursor;
|
||||||
|
@ -536,8 +660,8 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
else if (Inputs->uiToggleFrLimit->Pressed())
|
else if (Inputs->uiToggleFrLimit->Pressed())
|
||||||
{
|
{
|
||||||
// Toggle frame limiting
|
// Toggle frame limiting
|
||||||
noThrottle = !noThrottle;
|
g_Config.throttle = !g_Config.throttle;
|
||||||
printf("Frame limiting: %s\n", noThrottle?"Off":"On");
|
printf("Frame limiting: %s\n", g_Config.throttle?"On":"Off");
|
||||||
}
|
}
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
else if (Inputs->uiEnterDebugger->Pressed())
|
else if (Inputs->uiEnterDebugger->Pressed())
|
||||||
|
@ -554,7 +678,7 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
currentTicks = currentFPSTicks;
|
currentTicks = currentFPSTicks;
|
||||||
|
|
||||||
// FPS
|
// FPS
|
||||||
if (showFPS)
|
if (g_Config.showFPS)
|
||||||
{
|
{
|
||||||
++fpsFramesElapsed;
|
++fpsFramesElapsed;
|
||||||
if((currentFPSTicks-prevFPSTicks) >= 1000) // update FPS every 1 second (each tick is 1 ms)
|
if((currentFPSTicks-prevFPSTicks) >= 1000) // update FPS every 1 second (each tick is 1 ms)
|
||||||
|
@ -567,7 +691,7 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame limiting/paused
|
// Frame limiting/paused
|
||||||
if (paused || !noThrottle)
|
if (paused || g_Config.throttle)
|
||||||
{
|
{
|
||||||
++framesElapsed;
|
++framesElapsed;
|
||||||
targetTicks = startTicks + (unsigned) ((float)framesElapsed * 1000.0f/60.0f);
|
targetTicks = startTicks + (unsigned) ((float)framesElapsed * 1000.0f/60.0f);
|
||||||
|
@ -643,204 +767,6 @@ QuitError:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Error and Debug Logging
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static CLogger *s_logger = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the current logger.
|
|
||||||
*/
|
|
||||||
CLogger *GetLogger()
|
|
||||||
{
|
|
||||||
return s_logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets the current logger.
|
|
||||||
*/
|
|
||||||
void SetLogger(CLogger *logger)
|
|
||||||
{
|
|
||||||
s_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DebugLog(fmt, ...):
|
|
||||||
*
|
|
||||||
* Logs a debug message with the logger.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* fmt Format string (same as printf()).
|
|
||||||
* ... Variable number of arguments as required by format string.
|
|
||||||
*/
|
|
||||||
void DebugLog(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if (s_logger == NULL)
|
|
||||||
return;
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
s_logger->DebugLog(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InfoLog(fmt, ...);
|
|
||||||
*
|
|
||||||
* Logs an info message with the logger.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* fmt Format string (same as printf()).
|
|
||||||
* ... Variable number of arguments as required by format string.
|
|
||||||
*/
|
|
||||||
void InfoLog(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if (s_logger == NULL)
|
|
||||||
return;
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
s_logger->InfoLog(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ErrorLog(fmt, ...):
|
|
||||||
*
|
|
||||||
* Logs an error message with the logger.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* fmt Format string (same as printf()).
|
|
||||||
* ... Variable number of arguments as required by format string.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* Always returns FAIL.
|
|
||||||
*/
|
|
||||||
BOOL ErrorLog(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if (s_logger == NULL)
|
|
||||||
return FAIL;
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
s_logger->ErrorLog(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEBUG_LOG_FILE "debug.log"
|
|
||||||
#define ERROR_LOG_FILE "error.log"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default logger that logs to debug and error log files.
|
|
||||||
*/
|
|
||||||
class CFileLogger : public CLogger
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const char *m_debugLogFile;
|
|
||||||
const char *m_errorLogFile;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CFileLogger(const char *debugLogFile, const char *errorLogFile) :
|
|
||||||
m_debugLogFile(debugLogFile), m_errorLogFile(errorLogFile)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DebugLog(fmt, ...):
|
|
||||||
*
|
|
||||||
* Prints to debug log. The file is opened and closed each time so that its
|
|
||||||
* contents are preserved even if the program crashes.
|
|
||||||
*/
|
|
||||||
void DebugLog(const char *fmt, va_list vl)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
char string[1024];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
fp = fopen(m_debugLogFile, "ab");
|
|
||||||
if (NULL != fp)
|
|
||||||
{
|
|
||||||
vsprintf(string, fmt, vl);
|
|
||||||
fprintf(fp, string);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
#endif // DEBUG
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InfoLog(fmt, ...);
|
|
||||||
*
|
|
||||||
* Prints information to the error log file but does not print to stderr. This
|
|
||||||
* is useful for logging non-error information.
|
|
||||||
*/
|
|
||||||
void InfoLog(const char *fmt, va_list vl)
|
|
||||||
{
|
|
||||||
char string[4096];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
vsprintf(string, fmt, vl);
|
|
||||||
|
|
||||||
fp = fopen(m_errorLogFile, "ab");
|
|
||||||
if (NULL != fp)
|
|
||||||
{
|
|
||||||
fprintf(fp, "%s\n", string);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLogger::DebugLog("Info: ");
|
|
||||||
CLogger::DebugLog(string);
|
|
||||||
CLogger::DebugLog("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ErrorLog(fmt, ...):
|
|
||||||
*
|
|
||||||
* Prints an error to stderr and the error log file.
|
|
||||||
*/
|
|
||||||
void ErrorLog(const char *fmt, va_list vl)
|
|
||||||
{
|
|
||||||
char string[4096];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
vsprintf(string, fmt, vl);
|
|
||||||
fprintf(stderr, "Error: %s\n", string);
|
|
||||||
|
|
||||||
fp = fopen(m_errorLogFile, "ab");
|
|
||||||
if (NULL != fp)
|
|
||||||
{
|
|
||||||
fprintf(fp, "%s\n", string);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLogger::DebugLog("Error: ");
|
|
||||||
CLogger::DebugLog(string);
|
|
||||||
CLogger::DebugLog("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearLogs()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
ClearLog(DEBUG_LOG_FILE, "Supermodel v"SUPERMODEL_VERSION" Debug Log");
|
|
||||||
#endif // DEBUG
|
|
||||||
ClearLog(ERROR_LOG_FILE, "Supermodel v"SUPERMODEL_VERSION" Error Log");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear log file
|
|
||||||
void ClearLog(const char *file, const char *title)
|
|
||||||
{
|
|
||||||
FILE *fp = fopen(file, "w");
|
|
||||||
if (NULL != fp)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
fprintf(fp, "%s\n", title);
|
|
||||||
for (i = 0; i < strlen(title); i++)
|
|
||||||
fputc('-', fp);
|
|
||||||
fprintf(fp, "\n\n");
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Diagnostic Commands
|
Diagnostic Commands
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -988,10 +914,12 @@ static void Help(void)
|
||||||
puts("");
|
puts("");
|
||||||
puts("General Options:");
|
puts("General Options:");
|
||||||
puts(" -?, -h Print this help text");
|
puts(" -?, -h Print this help text");
|
||||||
puts(" -print-games List supported games");
|
puts(" -print-games List supported games and quit");
|
||||||
puts("");
|
puts("");
|
||||||
puts("Emulation Options:");
|
puts("Emulation Options:");
|
||||||
puts(" -ppc-frequency=<f> Set PowerPC frequency in MHz [Default: 25]");
|
puts(" -ppc-frequency=<f> Set PowerPC frequency in MHz [Default: 40]");
|
||||||
|
puts(" -no-scsp Disable Sega Custom Sound Processor (sound effects)");
|
||||||
|
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
|
||||||
puts(" -multi-threaded Enable multi-threading");
|
puts(" -multi-threaded Enable multi-threading");
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
puts(" -disable-debugger Completely disable debugger functionality");
|
puts(" -disable-debugger Completely disable debugger functionality");
|
||||||
|
@ -1007,6 +935,10 @@ static void Help(void)
|
||||||
puts(" -vert-shader=<file> Load 3D vertex shader from external file");
|
puts(" -vert-shader=<file> Load 3D vertex shader from external file");
|
||||||
puts(" -frag-shader=<file> Load 3D fragment shader from external file");
|
puts(" -frag-shader=<file> Load 3D fragment shader from external file");
|
||||||
#endif
|
#endif
|
||||||
|
puts("");
|
||||||
|
puts("Audio Options:");
|
||||||
|
puts(" -sound-volume=<v> Set volume of sound effects in % [Default: 100]");
|
||||||
|
puts(" -music-volume=<v> Set volume of MPEG music in % [Default: 100]");
|
||||||
puts("");
|
puts("");
|
||||||
puts("Input Options:");
|
puts("Input Options:");
|
||||||
puts(" -input-system=<s> Set input system [Default: SDL]");
|
puts(" -input-system=<s> Set input system [Default: SDL]");
|
||||||
|
@ -1017,7 +949,7 @@ static void Help(void)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
puts(" -dis=<addr>[,n] Disassemble PowerPC code from CROM");
|
puts(" -dis=<addr>[,n] Disassemble PowerPC code from CROM");
|
||||||
#endif
|
#endif
|
||||||
puts(" -print-gl-info Print extensive OpenGL information\n");
|
puts(" -print-gl-info Print extensive OpenGL information and quit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print game list
|
// Print game list
|
||||||
|
@ -1045,13 +977,14 @@ static void PrintGameList(void)
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
CINIFile CmdLine; // not associated with any files, holds command line options
|
||||||
int i, ret;
|
int i, ret;
|
||||||
int cmd=0, fileIdx=0, cmdMultiThreaded=0, cmdFullScreen=0, cmdNoThrottle=0, cmdShowFPS=0, cmdPrintInputs=0, cmdConfigInputs=0, cmdPrintGames=0, cmdDis=0, cmdPrintGLInfo=0;
|
int fileIdx=0;
|
||||||
|
bool cmdPrintInputs=false, cmdConfigInputs=false, cmdDis=false;
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
int cmdDisableDebugger = 0, cmdEnterDebugger=0;
|
int cmdEnterDebugger=false;
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
unsigned n, xRes=496, yRes=384, ppcFrequency=25000000;
|
unsigned n;
|
||||||
char *vsFile = NULL, *fsFile = NULL, *inpSysName = NULL;
|
|
||||||
UINT32 addr;
|
UINT32 addr;
|
||||||
|
|
||||||
Title();
|
Title();
|
||||||
|
@ -1066,7 +999,20 @@ int main(int argc, char **argv)
|
||||||
Logger.ClearLogs();
|
Logger.ClearLogs();
|
||||||
SetLogger(&Logger);
|
SetLogger(&Logger);
|
||||||
|
|
||||||
// Parse command line
|
// Read global settings from INI file
|
||||||
|
ReadConfigFile(NULL, "Global");
|
||||||
|
//DumpConfig();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse command line.
|
||||||
|
*
|
||||||
|
* Settings are stored in CmdLine so that they can be applied later, after
|
||||||
|
* game-specific settings are read from the configuration file (which
|
||||||
|
* requires the ROM set to be identified and therefore is done later).
|
||||||
|
*
|
||||||
|
* Some commands are processed here directly.
|
||||||
|
*/
|
||||||
|
CmdLine.SetDefaultSectionName("Global"); // command line settings are global-level
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"-?"))
|
if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"-?"))
|
||||||
|
@ -1075,7 +1021,10 @@ int main(int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i],"-print-games"))
|
else if (!strcmp(argv[i],"-print-games"))
|
||||||
cmd = cmdPrintGames = 1;
|
{
|
||||||
|
PrintGameList();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (!strncmp(argv[i],"-ppc-frequency",14))
|
else if (!strncmp(argv[i],"-ppc-frequency",14))
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
|
@ -1083,21 +1032,45 @@ int main(int argc, char **argv)
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
ErrorLog("-ppc-frequency requires a frequency.");
|
ErrorLog("-ppc-frequency requires a frequency.");
|
||||||
else
|
else
|
||||||
{
|
CmdLine.Set("Global", "PowerPCFrequency", f);
|
||||||
if ((f<1) || (f>1000)) // limit to 1-1000MHz
|
}
|
||||||
ErrorLog("PowerPC frequency must be between 1 and 1000 MHz. Ignoring.");
|
else if (!strcmp(argv[i],"-multi-threaded"))
|
||||||
else
|
{
|
||||||
ppcFrequency = f*1000000;
|
n = 1;
|
||||||
}
|
CmdLine.Set("Global", "MultiThreaded", n);
|
||||||
}
|
}
|
||||||
else if (!strncmp(argv[i],"-multi-threaded", 16))
|
|
||||||
cmd = cmdMultiThreaded = 1;
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
else if (!strncmp(argv[i],"-disable-debugger",17))
|
else if (!strncmp(argv[i],"-disable-debugger"))
|
||||||
cmd = cmdDisableDebugger = 1;
|
g_Config.disableDebugger = true;
|
||||||
else if (!strncmp(argv[i],"-enter-debugger",15))
|
else if (!strcmp(argv[i],"-enter-debugger"))
|
||||||
cmd = cmdEnterDebugger = 1;
|
cmdEnterDebugger = true;
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
else if (!strncmp(argv[i],"-sound-vol",10))
|
||||||
|
{
|
||||||
|
ret = sscanf(&argv[i][10],"=%d",&n);
|
||||||
|
if (ret != 1)
|
||||||
|
ErrorLog("-sound-vol requires a volume setting.");
|
||||||
|
else
|
||||||
|
CmdLine.Set("Global", "SoundVolume", n);
|
||||||
|
}
|
||||||
|
else if (!strncmp(argv[i],"-music-vol",10))
|
||||||
|
{
|
||||||
|
ret = sscanf(&argv[i][10],"=%d",&n);
|
||||||
|
if (ret != 1)
|
||||||
|
ErrorLog("-music-vol requires a volume setting.");
|
||||||
|
else
|
||||||
|
CmdLine.Set("Global", "MusicVolume", n);
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[i], "-no-scsp"))
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
CmdLine.Set("Global", "EmulateSCSP", n);
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[i], "-no-dsb"))
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
CmdLine.Set("Global", "EmulateDSB", n);
|
||||||
|
}
|
||||||
else if (!strncmp(argv[i],"-res",4))
|
else if (!strncmp(argv[i],"-res",4))
|
||||||
{
|
{
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
|
@ -1107,56 +1080,68 @@ int main(int argc, char **argv)
|
||||||
ErrorLog("-res requires both a width and a height.");
|
ErrorLog("-res requires both a width and a height.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xRes = x;
|
CmdLine.Set("Global", "XResolution", x);
|
||||||
yRes = y;
|
CmdLine.Set("Global", "YResolution", y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i],"-fullscreen"))
|
else if (!strcmp(argv[i],"-fullscreen"))
|
||||||
cmd = cmdFullScreen = 1;
|
{
|
||||||
|
n = 1;
|
||||||
|
CmdLine.Set("Global", "FullScreen", n);
|
||||||
|
}
|
||||||
else if (!strcmp(argv[i],"-no-throttle"))
|
else if (!strcmp(argv[i],"-no-throttle"))
|
||||||
cmd = cmdNoThrottle = 1;
|
{
|
||||||
|
n = 0;
|
||||||
|
CmdLine.Set("Global", "Throttle", n);
|
||||||
|
}
|
||||||
else if (!strcmp(argv[i],"-show-fps"))
|
else if (!strcmp(argv[i],"-show-fps"))
|
||||||
cmd = cmdShowFPS = 1;
|
{
|
||||||
|
n = 1;
|
||||||
|
CmdLine.Set("Global", "ShowFrameRate", n);
|
||||||
|
}
|
||||||
else if (!strncmp(argv[i],"-vert-shader=",13))
|
else if (!strncmp(argv[i],"-vert-shader=",13))
|
||||||
{
|
{
|
||||||
if (argv[i][13] == '\0')
|
if (argv[i][13] == '\0')
|
||||||
ErrorLog("-vert-shader requires a file path.");
|
ErrorLog("-vert-shader requires a file path.");
|
||||||
else
|
else
|
||||||
vsFile = &argv[i][13];
|
CmdLine.Set("Global", "VertexShader", &argv[i][13]);
|
||||||
}
|
}
|
||||||
else if (!strncmp(argv[i],"-frag-shader=",13))
|
else if (!strncmp(argv[i],"-frag-shader=",13))
|
||||||
{
|
{
|
||||||
if (argv[i][13] == '\0')
|
if (argv[i][13] == '\0')
|
||||||
ErrorLog("-frag-shader requires a file path.");
|
ErrorLog("-frag-shader requires a file path.");
|
||||||
else
|
else
|
||||||
fsFile = &argv[i][13];
|
CmdLine.Set("Global", "FragmentShader", &argv[i][13]);
|
||||||
}
|
}
|
||||||
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')
|
||||||
ErrorLog("-input-system requires an input system name.");
|
ErrorLog("-input-system requires an input system name.");
|
||||||
else
|
else
|
||||||
inpSysName = &argv[i][14];
|
CmdLine.Set("Global", "InputSystem", &argv[i][14]);
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i],"-print-inputs"))
|
else if (!strcmp(argv[i],"-print-inputs"))
|
||||||
cmd = cmdPrintInputs = 1;
|
cmdPrintInputs = true;
|
||||||
else if (!strcmp(argv[i],"-config-inputs"))
|
else if (!strcmp(argv[i],"-config-inputs"))
|
||||||
cmd = cmdConfigInputs = 1;
|
cmdConfigInputs = true;
|
||||||
else if (!strncmp(argv[i],"-dis",4))
|
else if (!strncmp(argv[i],"-dis",4))
|
||||||
{
|
{
|
||||||
ret = sscanf(&argv[i][4],"=%X,%X",&addr,&n);
|
ret = sscanf(&argv[i][4],"=%X,%X",&addr,&n);
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
{
|
{
|
||||||
n = 16;
|
n = 16;
|
||||||
cmd = cmdDis = 1;
|
cmdDis = true;
|
||||||
}
|
}
|
||||||
else if (ret == 2)
|
else if (ret == 2)
|
||||||
cmd = cmdDis = 1;
|
cmdDis = true;
|
||||||
else
|
else
|
||||||
ErrorLog("-dis requires address and, optionally, number of instructions.");
|
ErrorLog("-dis requires address and, optionally, number of instructions.");
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i],"-print-gl-info"))
|
else if (!strcmp(argv[i],"-print-gl-info"))
|
||||||
cmd = cmdPrintGLInfo = 1;
|
{
|
||||||
|
PrintGLInfo(FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (argv[i][0] == '-')
|
else if (argv[i][0] == '-')
|
||||||
ErrorLog("Ignoring invalid option: %s.", argv[i]);
|
ErrorLog("Ignoring invalid option: %s.", argv[i]);
|
||||||
else
|
else
|
||||||
|
@ -1175,6 +1160,7 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create input system (default is SDL) and debugger
|
||||||
CInputSystem *InputSystem = NULL;
|
CInputSystem *InputSystem = NULL;
|
||||||
CInputs *Inputs = NULL;
|
CInputs *Inputs = NULL;
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
|
@ -1183,27 +1169,33 @@ int main(int argc, char **argv)
|
||||||
Debugger::CSupermodelDebugger *Debugger = NULL;
|
Debugger::CSupermodelDebugger *Debugger = NULL;
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
|
||||||
// Create input system (default is SDL)
|
if (stricmp(g_Config.GetInputSystem(), "sdl") == 0)
|
||||||
if (inpSysName == NULL || stricmp(inpSysName, "sdl") == 0)
|
|
||||||
InputSystem = new CSDLInputSystem();
|
InputSystem = new CSDLInputSystem();
|
||||||
#ifdef SUPERMODEL_WIN32
|
#ifdef SUPERMODEL_WIN32
|
||||||
else if (stricmp(inpSysName, "dinput") == 0)
|
else if (stricmp(g_Config.GetInputSystem(), "dinput") == 0)
|
||||||
InputSystem = new CDirectInputSystem(false, false, false);
|
InputSystem = new CDirectInputSystem(false, false, false);
|
||||||
else if (stricmp(inpSysName, "xinput") == 0)
|
else if (stricmp(g_Config.GetInputSystem(), "xinput") == 0)
|
||||||
InputSystem = new CDirectInputSystem(false, true, false);
|
InputSystem = new CDirectInputSystem(false, true, false);
|
||||||
else if (stricmp(inpSysName, "rawinput") == 0)
|
else if (stricmp(g_Config.GetInputSystem(), "rawinput") == 0)
|
||||||
InputSystem = new CDirectInputSystem(true, false, false);
|
InputSystem = new CDirectInputSystem(true, false, false);
|
||||||
#endif // SUPERMODEL_WIN32
|
#endif // SUPERMODEL_WIN32
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ErrorLog("Unknown input system: '%s'.\n", inpSysName);
|
ErrorLog("Unknown input system: '%s'.\n", g_Config.GetInputSystem());
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create inputs from input system (configuring them if required)
|
// Create inputs from input system (configuring them if required)
|
||||||
Inputs = CreateInputs(InputSystem, cmdConfigInputs);
|
Inputs = new CInputs(InputSystem);
|
||||||
if (Inputs == NULL)
|
if (!Inputs->Initialize())
|
||||||
|
{
|
||||||
|
ErrorLog("Unable to initalize inputs.\n");
|
||||||
|
exitCode = 1;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigureInputs(Inputs, cmdConfigInputs))
|
||||||
{
|
{
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -1215,22 +1207,7 @@ int main(int argc, char **argv)
|
||||||
InputSystem->PrintSettings();
|
InputSystem->PrintSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process commands that don't require ROM set
|
// From this point onwards, a ROM set is needed
|
||||||
if (cmd)
|
|
||||||
{
|
|
||||||
if (cmdPrintGames)
|
|
||||||
{
|
|
||||||
PrintGameList();
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmdPrintGLInfo)
|
|
||||||
{
|
|
||||||
PrintGLInfo(FALSE);
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileIdx == 0)
|
if (fileIdx == 0)
|
||||||
{
|
{
|
||||||
ErrorLog("No ROM set specified.");
|
ErrorLog("No ROM set specified.");
|
||||||
|
@ -1238,22 +1215,18 @@ int main(int argc, char **argv)
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process commands that require ROMs
|
if (cmdDis)
|
||||||
if (cmd)
|
|
||||||
{
|
{
|
||||||
if (cmdDis)
|
if (OKAY != DisassembleCROM(argv[fileIdx], addr, n))
|
||||||
{
|
exitCode = 1;
|
||||||
if (OKAY != DisassembleCROM(argv[fileIdx], addr, n))
|
goto Exit;
|
||||||
exitCode = 1;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
// Create Model3
|
// Create Model3
|
||||||
Model3 = new CModel3();
|
Model3 = new CModel3();
|
||||||
// Create Supermodel debugger unless debugging is disabled
|
// Create Supermodel debugger unless debugging is disabled
|
||||||
if (!cmdDisableDebugger)
|
if (!g_Config.disableDebugger)
|
||||||
{
|
{
|
||||||
Debugger = new Debugger::CSupermodelDebugger(Model3, Inputs, &Logger);
|
Debugger = new Debugger::CSupermodelDebugger(Model3, Inputs, &Logger);
|
||||||
// If -enter-debugger option was set force debugger to break straightaway
|
// If -enter-debugger option was set force debugger to break straightaway
|
||||||
|
@ -1261,13 +1234,13 @@ int main(int argc, char **argv)
|
||||||
Debugger->ForceBreak(true);
|
Debugger->ForceBreak(true);
|
||||||
}
|
}
|
||||||
// Fire up Supermodel with debugger
|
// Fire up Supermodel with debugger
|
||||||
exitCode = Supermodel(argv[fileIdx],Model3,Inputs,Debugger,ppcFrequency,cmdMultiThreaded,xRes,yRes,TRUE,cmdFullScreen,cmdNoThrottle,cmdShowFPS,vsFile,fsFile);
|
exitCode = Supermodel(argv[fileIdx],Model3,Inputs,Debugger,&CmdLine);
|
||||||
if (Debugger != NULL)
|
if (Debugger != NULL)
|
||||||
delete Debugger;
|
delete Debugger;
|
||||||
delete Model3;
|
delete Model3;
|
||||||
#else
|
#else
|
||||||
// Fire up Supermodel
|
// Fire up Supermodel
|
||||||
exitCode = Supermodel(argv[fileIdx],Inputs,ppcFrequency,cmdMultiThreaded,xRes,yRes,TRUE,cmdFullScreen,cmdNoThrottle,cmdShowFPS,vsFile,fsFile);
|
exitCode = Supermodel(argv[fileIdx],Inputs,&CmdLine);
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
* Fundamental data types. This file is used by both C++ and C modules, so it
|
* Fundamental data types. This file is used by both C++ and C modules, so it
|
||||||
* must NOT include any C++-specific constructs. Some modules may elect to
|
* must NOT include any C++-specific constructs. Some modules may elect to
|
||||||
* include it directly rather than through Supermodel.h.
|
* include it directly rather than through Supermodel.h.
|
||||||
|
*
|
||||||
|
* All ports must define this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INCLUDED_TYPES_H
|
#ifndef INCLUDED_TYPES_H
|
||||||
|
|
|
@ -119,7 +119,7 @@ int g,snd_eof=0;
|
||||||
|
|
||||||
if (header.protection_bit==0) getcrc();
|
if (header.protection_bit==0) getcrc();
|
||||||
|
|
||||||
printf("%d Hz, layer %d\n", t_sampling_frequency[header.ID][header.sampling_frequency], header.layer);
|
//printf("%d Hz, layer %d\n", t_sampling_frequency[header.ID][header.sampling_frequency], header.layer);
|
||||||
|
|
||||||
if (setup_audio(&header)!=0) {
|
if (setup_audio(&header)!=0) {
|
||||||
warn("Cannot set up audio. Exiting\n");
|
warn("Cannot set up audio. Exiting\n");
|
||||||
|
|
|
@ -523,7 +523,7 @@ static int min_cycles = 99999999;
|
||||||
|
|
||||||
if (cnt2-cnt1 < min_cycles) {
|
if (cnt2-cnt1 < min_cycles) {
|
||||||
min_cycles = cnt2-cnt1;
|
min_cycles = cnt2-cnt1;
|
||||||
printf("%d cycles\n", min_cycles);
|
//printf("%d cycles\n", min_cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -546,7 +546,7 @@ static int min_cycles = 99999999;
|
||||||
|
|
||||||
if (cnt2-cnt1 < min_cycles) {
|
if (cnt2-cnt1 < min_cycles) {
|
||||||
min_cycles = cnt2-cnt1;
|
min_cycles = cnt2-cnt1;
|
||||||
printf("%d cycles, sfb %d\n", min_cycles, sfb);
|
//printf("%d cycles, sfb %d\n", min_cycles, sfb);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1503,7 +1503,7 @@ static int min_cycles = 99999999;
|
||||||
|
|
||||||
if (cnt2-cnt1 < min_cycles) {
|
if (cnt2-cnt1 < min_cycles) {
|
||||||
min_cycles = cnt2-cnt1;
|
min_cycles = cnt2-cnt1;
|
||||||
printf("%d, %d cycles, %d\n", cnt3-cnt1, min_cycles, start);
|
//printf("%d, %d cycles, %d\n", cnt3-cnt1, min_cycles, start);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
#ifndef INCLUDED_SUPERMODEL_H
|
#ifndef INCLUDED_SUPERMODEL_H
|
||||||
#define INCLUDED_SUPERMODEL_H
|
#define INCLUDED_SUPERMODEL_H
|
||||||
|
|
||||||
|
// Used throughout Supermodel
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Program-Wide Definitions
|
Program-Wide Definitions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -38,8 +44,11 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
OS-Dependent (OSD) Items
|
OS-Dependent (OSD) Items
|
||||||
|
|
||||||
Everything here must be provided by the OSD layer. Include files should be
|
Everything here must be provided by the OSD layer. The following include files
|
||||||
located in the OSD directories for each port.
|
must be located in the OSD directories for each port:
|
||||||
|
|
||||||
|
Types.h Defines fundamental data types.
|
||||||
|
OSDConfig.h COSDConfig class (OSD-specific configuration settings).
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
// stricmp() is non-standard, apparently...
|
// stricmp() is non-standard, apparently...
|
||||||
|
@ -49,6 +58,7 @@
|
||||||
#define stricmp strcasecmp
|
#define stricmp strcasecmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fundamental Data Types:
|
* Fundamental Data Types:
|
||||||
*
|
*
|
||||||
|
@ -68,58 +78,21 @@
|
||||||
* specific stuff. Some modules may choose to include it directly rather than
|
* specific stuff. Some modules may choose to include it directly rather than
|
||||||
* use Supermodel.h, so it must exist.
|
* use Supermodel.h, so it must exist.
|
||||||
*/
|
*/
|
||||||
#include "Types.h"
|
#include "Types.h" // located in OSD/<port>/ directory
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OSD Header Files
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Error logging interface
|
||||||
|
#include "OSD/Logger.h"
|
||||||
|
|
||||||
|
// OSD configuration
|
||||||
|
#include "OSDConfig.h" // located in OSD/<port>/ directory
|
||||||
|
|
||||||
// OSD Interfaces
|
// OSD Interfaces
|
||||||
#include "Thread.h"
|
#include "OSD/Thread.h"
|
||||||
#include "Audio.h"
|
#include "OSD/Audio.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Error and Debug Logging
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DebugLog(fmt, ...):
|
|
||||||
*
|
|
||||||
* Prints debugging information. The OSD layer may choose to print this to a
|
|
||||||
* log file, the screen, neither, or both. Newlines and other formatting codes
|
|
||||||
* must be explicitly included.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* fmt A format string (the same as printf()).
|
|
||||||
* ... Variable number of arguments, as required by format string.
|
|
||||||
*/
|
|
||||||
extern void DebugLog(const char *fmt, ...);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ErrorLog(fmt, ...):
|
|
||||||
*
|
|
||||||
* Prints error information. Errors need not require program termination and
|
|
||||||
* may simply be informative warnings to the user. Newlines should not be
|
|
||||||
* included in the format string -- they are automatically added at the end of
|
|
||||||
* a line.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* fmt A format string (the same as printf()).
|
|
||||||
* ... Variable number of arguments, as required by format string.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* Must always return FAIL.
|
|
||||||
*/
|
|
||||||
extern BOOL ErrorLog(const char *fmt, ...);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InfoLog(fmt, ...);
|
|
||||||
*
|
|
||||||
* Prints information to the error log file but does not print to stderr. This
|
|
||||||
* is useful for logging non-error information. Newlines are automatically
|
|
||||||
* appended.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* fmt Format string (same as printf()).
|
|
||||||
* ... Variable number of arguments as required by format string.
|
|
||||||
*/
|
|
||||||
extern void InfoLog(const char *fmt, ...);
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -129,9 +102,6 @@ extern void InfoLog(const char *fmt, ...);
|
||||||
here, except for external packages and APIs.
|
here, except for external packages and APIs.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "Games.h"
|
#include "Games.h"
|
||||||
#include "ROMLoad.h"
|
#include "ROMLoad.h"
|
||||||
#include "INIFile.h"
|
#include "INIFile.h"
|
||||||
|
@ -168,6 +138,7 @@ extern void InfoLog(const char *fmt, ...);
|
||||||
#include "Model3/SoundBoard.h"
|
#include "Model3/SoundBoard.h"
|
||||||
#include "Model3/DSB.h"
|
#include "Model3/DSB.h"
|
||||||
#include "Model3/Model3.h"
|
#include "Model3/Model3.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
Loading…
Reference in a new issue