mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-21 21:35:38 +00:00
Massive internal change: removed CConfig object and replaced it with a hierarchical config object system (Util::Config::Node). Games are now defined in an XML file. Hopefully I didn't break too many things :/
This commit is contained in:
parent
26a4417a5f
commit
f34e25dfc7
|
@ -38,7 +38,7 @@ BITS = 64
|
|||
#
|
||||
# Include console-based debugger in emulator ('yes' or 'no')
|
||||
#
|
||||
ENABLE_DEBUGGER = no
|
||||
ENABLE_DEBUGGER = yes
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
@ -58,7 +58,7 @@ BOOST_INCLUDEPATH = /mingw64/boost_1_55_0
|
|||
ifeq ($(strip $(BITS)),64)
|
||||
SDL_LIBPATH = /mingw64/lib64
|
||||
#SDL_INCLUDEPATH = /mingw64/x86_64-w64-mingw32/include/SDL
|
||||
SDL_INCLUDEPATH = /mingw64/SDL-1.2.15/include
|
||||
SDL_INCLUDEPATH = c:\tdm-gcc-64\include\SDL
|
||||
else
|
||||
SDL_LIBPATH = /mingw/lib
|
||||
SDL_INCLUDEPATH = /mingw/include/SDL
|
||||
|
@ -100,7 +100,7 @@ LD = g++
|
|||
COMPILER_FLAGS = -I$(SDL_INCLUDEPATH) -ISrc/ -ISrc/OSD/ -ISrc/OSD/SDL/ -ISrc/OSD/Windows/ -c -Wall -DSUPERMODEL_WIN32 -DGLEW_STATIC -O3
|
||||
CFLAGS = $(COMPILER_FLAGS)
|
||||
CPPFLAGS = $(COMPILER_FLAGS) -I$(BOOST_INCLUDEPATH) -std=c++11
|
||||
LFLAGS = -o $(OUTFILE) $(OBJ) -L$(SDL_LIBPATH) -lmingw32 -lSDLmain -lSDL -lopengl32 -lglu32 -ldinput8 -ldxguid -lole32 -loleaut32 -lwbemuuid -lz -s #-l:$(WINSDK_LIBPATH)/WbemUuid.lib -s
|
||||
LFLAGS = -o $(OUTFILE) $(OBJ) -L$(SDL_LIBPATH) -lmingw32 -lSDLmain -lSDL -lopengl32 -lglu32 -ldinput8 -ldxguid -lole32 -loleaut32 -lwbemuuid -lz -s # -l:$(WINSDK_LIBPATH)/WbemUuid.lib -s
|
||||
|
||||
#
|
||||
# Build options...
|
||||
|
@ -119,11 +119,11 @@ endif
|
|||
#
|
||||
# Objects and Dependencies
|
||||
#
|
||||
OBJ = $(OBJ_DIR)/Format.o $(OBJ_DIR)/NewConfig.o \
|
||||
$(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/Config.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
||||
OBJ = $(OBJ_DIR)/PPCDisasm.o $(OBJ_DIR)/Games.o $(OBJ_DIR)/INIFile.o $(OBJ_DIR)/BlockFile.o $(OBJ_DIR)/93C46.o \
|
||||
$(OBJ_DIR)/ROMLoad.o $(OBJ_DIR)/unzip.o $(OBJ_DIR)/ioapi.o $(OBJ_DIR)/Error.o $(OBJ_DIR)/glew.o $(OBJ_DIR)/Shader.o \
|
||||
$(OBJ_DIR)/Real3D.o $(OBJ_DIR)/Legacy3D.o $(OBJ_DIR)/Models.o $(OBJ_DIR)/TextureRefs.o \
|
||||
$(OBJ_DIR)/New3D.o $(OBJ_DIR)/Mat4.o $(OBJ_DIR)/Model.o $(OBJ_DIR)/PolyHeader.o $(OBJ_DIR)/Texture.o $(OBJ_DIR)/TextureSheet.o $(OBJ_DIR)/VBO.o $(OBJ_DIR)/Vec.o $(OBJ_DIR)/R3DShader.o $(OBJ_DIR)/R3DFloat.o \
|
||||
$(OBJ_DIR)/R3DScrollFog.o \
|
||||
$(OBJ_DIR)/Render2D.o $(OBJ_DIR)/TileGen.o \
|
||||
$(OBJ_DIR)/Model3.o $(OBJ_DIR)/ppc.o $(OBJ_DIR)/Main.o $(OBJ_DIR)/Audio.o $(OBJ_DIR)/Thread.o $(OBJ_DIR)/SoundBoard.o \
|
||||
$(OBJ_DIR)/SCSP.o $(OBJ_DIR)/SCSPDSP.o $(OBJ_DIR)/68K.o $(OBJ_DIR)/m68kcpu.o $(OBJ_DIR)/m68kopnz.o $(OBJ_DIR)/m68kopdm.o \
|
||||
|
@ -137,7 +137,8 @@ OBJ = $(OBJ_DIR)/Format.o $(OBJ_DIR)/NewConfig.o \
|
|||
$(OBJ_DIR)/amp_util.o \
|
||||
$(OBJ_DIR)/Crypto.o \
|
||||
$(OBJ_DIR)/Logger.o \
|
||||
$(OBJ_DIR)/tinyxml2.o
|
||||
$(OBJ_DIR)/tinyxml2.o \
|
||||
$(OBJ_DIR)/ByteSwap.o $(OBJ_DIR)/Format.o $(OBJ_DIR)/NewConfig.o $(OBJ_DIR)/ConfigBuilders.o $(OBJ_DIR)/GameLoader.o
|
||||
|
||||
|
||||
# If built-in debugger enabled, include all debugging classes
|
||||
|
@ -159,9 +160,9 @@ ppcd: $(BIN_DIR) $(OBJ_DIR)
|
|||
$(CXX) Src/CPU/PowerPC/PPCDisasm.cpp $(CPPFLAGS) -DSTANDALONE -o $(OBJ_DIR)/ppcd.o
|
||||
$(LD) -o $(BIN_DIR)/ppcd.exe -mconsole $(OBJ_DIR)/ppcd.o
|
||||
|
||||
tests: $(BIN_DIR) $(OBJ_DIR) $(OBJ) Src/Util/Test_Config.cpp Src/Pkgs/tinyxml2.cpp
|
||||
tests: $(BIN_DIR) $(OBJ_DIR) $(OBJ_DIR)/NewConfig.o $(OBJ_DIR)/ConfigBuilders.o Src/Util/Test_Config.cpp Src/Pkgs/tinyxml2.cpp
|
||||
$(CXX) Src/Util/Test_Config.cpp $(CPPFLAGS) -o $(OBJ_DIR)/Test_Config.o
|
||||
$(LD) -o $(BIN_DIR)/test_config.exe -mconsole $(OBJ_DIR)/Test_Config.o $(OBJ_DIR)/Format.o $(OBJ_DIR)/NewConfig.o $(OBJ_DIR)/Logger.o $(OBJ_DIR)/tinyxml2.o
|
||||
$(LD) -o $(BIN_DIR)/test_config.exe -mconsole $(OBJ_DIR)/Test_Config.o $(OBJ_DIR)/Format.o $(OBJ_DIR)/NewConfig.o $(OBJ_DIR)/ConfigBuilders.o $(OBJ_DIR)/Logger.o $(OBJ_DIR)/tinyxml2.o
|
||||
|
||||
$(BIN_DIR):
|
||||
mkdir $(BIN_DIR)
|
||||
|
|
|
@ -35,17 +35,28 @@
|
|||
Output Functions
|
||||
******************************************************************************/
|
||||
|
||||
void CBlockFile::ReadString(char *str, unsigned strLen, unsigned maxLen)
|
||||
void CBlockFile::ReadString(std::string *str, uint32_t length)
|
||||
{
|
||||
if (NULL == fp)
|
||||
return;
|
||||
if (strLen>maxLen)
|
||||
strLen = maxLen;
|
||||
fread(str, sizeof(char), strLen, fp);
|
||||
str[strLen] = '\0';
|
||||
str->clear();
|
||||
//TODO: use fstream to get rid of this ugly hack
|
||||
bool keep_loading = true;
|
||||
for (size_t i = 0; i < length; i++)
|
||||
{
|
||||
char c;
|
||||
fread(&c, sizeof(char), 1, fp);
|
||||
if (keep_loading)
|
||||
{
|
||||
if (!c)
|
||||
keep_loading = false;
|
||||
else
|
||||
*str += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CBlockFile::ReadBytes(void *data, unsigned numBytes)
|
||||
unsigned CBlockFile::ReadBytes(void *data, uint32_t numBytes)
|
||||
{
|
||||
if (NULL == fp)
|
||||
return 0;
|
||||
|
@ -90,7 +101,7 @@ void CBlockFile::WriteDWord(uint32_t data)
|
|||
UpdateBlockSize();
|
||||
}
|
||||
|
||||
void CBlockFile::WriteBytes(const void *data, unsigned numBytes)
|
||||
void CBlockFile::WriteBytes(const void *data, uint32_t numBytes)
|
||||
{
|
||||
if (NULL == fp)
|
||||
return;
|
||||
|
@ -98,24 +109,11 @@ void CBlockFile::WriteBytes(const void *data, unsigned numBytes)
|
|||
UpdateBlockSize();
|
||||
}
|
||||
|
||||
void CBlockFile::WriteBlockHeader(const char *name, const char *comment)
|
||||
void CBlockFile::WriteBlockHeader(const std::string &name, const std::string &comment)
|
||||
{
|
||||
unsigned nameLen, commentLen;
|
||||
const char nullComment[1] = {'\0'};
|
||||
|
||||
if (NULL == fp)
|
||||
return;
|
||||
|
||||
if (comment == NULL)
|
||||
comment = nullComment;
|
||||
|
||||
nameLen = strlen(name);
|
||||
commentLen = strlen(comment);
|
||||
if (nameLen > 1024)
|
||||
nameLen = 1024;
|
||||
if (commentLen > 1024)
|
||||
commentLen = 1024;
|
||||
|
||||
|
||||
// Record current block starting position
|
||||
blockStartPos = ftell(fp);
|
||||
|
||||
|
@ -123,12 +121,10 @@ void CBlockFile::WriteBlockHeader(const char *name, const char *comment)
|
|||
WriteDWord(0); // will be automatically updated as we write the file
|
||||
|
||||
// Write name and comment lengths
|
||||
WriteDWord(nameLen+1);
|
||||
WriteDWord(commentLen+1);
|
||||
WriteBytes(name, nameLen);
|
||||
WriteByte(0);
|
||||
WriteBytes(comment, commentLen);
|
||||
WriteByte(0);
|
||||
WriteDWord(name.size() + 1);
|
||||
WriteDWord(comment.size() + 1);
|
||||
Write(name);
|
||||
Write(comment);
|
||||
|
||||
// Record the start of the current data section
|
||||
dataStartPos = ftell(fp);
|
||||
|
@ -151,66 +147,74 @@ void CBlockFile::WriteBlockHeader(const char *name, const char *comment)
|
|||
data ... Raw data (blockLength - total header size).
|
||||
******************************************************************************/
|
||||
|
||||
unsigned CBlockFile::Read(void *data, unsigned numBytes)
|
||||
unsigned CBlockFile::Read(void *data, uint32_t numBytes)
|
||||
{
|
||||
if (mode == 'r')
|
||||
return ReadBytes(data, numBytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CBlockFile::Write(const void *data, unsigned numBytes)
|
||||
void CBlockFile::Write(const void *data, uint32_t numBytes)
|
||||
{
|
||||
if (mode == 'w')
|
||||
WriteBytes(data, numBytes);
|
||||
}
|
||||
|
||||
void CBlockFile::NewBlock(const char *name, const char *comment)
|
||||
void CBlockFile::Write(const std::string &str)
|
||||
{
|
||||
if (mode == 'w')
|
||||
WriteBytes(str.c_str(), str.length() + 1);
|
||||
}
|
||||
|
||||
void CBlockFile::NewBlock(const std::string &name, const std::string &comment)
|
||||
{
|
||||
if (mode == 'w')
|
||||
WriteBlockHeader(name, comment);
|
||||
}
|
||||
|
||||
bool CBlockFile::FindBlock(const char *name)
|
||||
bool CBlockFile::FindBlock(const std::string &name)
|
||||
{
|
||||
long int curPos = 0;
|
||||
unsigned blockLen, nameLen, commentLen;
|
||||
|
||||
if (mode != 'r')
|
||||
return FAIL;
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
long int curPos = 0;
|
||||
while (curPos < fileSize)
|
||||
{
|
||||
blockStartPos = curPos;
|
||||
|
||||
// Read header
|
||||
curPos += ReadDWord(&blockLen);
|
||||
curPos += ReadDWord(&nameLen);
|
||||
curPos += ReadDWord(&commentLen);
|
||||
ReadString(strBuf,nameLen,1025);
|
||||
uint32_t block_length;
|
||||
uint32_t name_length;
|
||||
uint32_t comment_length;
|
||||
curPos += ReadDWord(&block_length);
|
||||
curPos += ReadDWord(&name_length);
|
||||
curPos += ReadDWord(&comment_length);
|
||||
std::string block_name;
|
||||
ReadString(&block_name, name_length);
|
||||
|
||||
// Is this the block we want?
|
||||
if (!strcmp(strBuf,name))
|
||||
if (block_name == name)
|
||||
{
|
||||
fseek(fp, blockStartPos+12+nameLen+commentLen, SEEK_SET); // move to beginning of data
|
||||
fseek(fp, blockStartPos + 12 + name_length + comment_length, SEEK_SET); // move to beginning of data
|
||||
dataStartPos = ftell(fp);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
// Move to next block
|
||||
fseek(fp, blockStartPos+blockLen, SEEK_SET);
|
||||
curPos = blockStartPos+blockLen;
|
||||
if (blockLen == 0) // this would never advance
|
||||
fseek(fp, blockStartPos + block_length, SEEK_SET);
|
||||
curPos = blockStartPos + block_length;
|
||||
if (block_length == 0) // this would never advance
|
||||
break;
|
||||
}
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
bool CBlockFile::Create(const char *file, const char *headerName, const char *comment)
|
||||
bool CBlockFile::Create(const std::string &file, const std::string &headerName, const std::string &comment)
|
||||
{
|
||||
fp = fopen(file, "wb");
|
||||
fp = fopen(file.c_str(), "wb");
|
||||
if (NULL == fp)
|
||||
return FAIL;
|
||||
mode = 'w';
|
||||
|
@ -218,9 +222,9 @@ bool CBlockFile::Create(const char *file, const char *headerName, const char *co
|
|||
return OKAY;
|
||||
}
|
||||
|
||||
bool CBlockFile::Load(const char *file)
|
||||
bool CBlockFile::Load(const std::string &file)
|
||||
{
|
||||
fp = fopen(file, "rb");
|
||||
fp = fopen(file.c_str(), "rb");
|
||||
if (NULL == fp)
|
||||
return FAIL;
|
||||
mode = 'r';
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
* Number of bytes read. If not the same as numBytes, an error
|
||||
* occurred.
|
||||
*/
|
||||
unsigned Read(void *data, unsigned numBytes);
|
||||
unsigned Read(void *data, uint32_t numBytes);
|
||||
|
||||
/*
|
||||
* FindBlock(name):
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
* Returns:
|
||||
* OKAY if found, FAIL if unable to locate.
|
||||
*/
|
||||
bool FindBlock(const char *name);
|
||||
bool FindBlock(const std::string &name);
|
||||
|
||||
/*
|
||||
* Write(data, numBytes):
|
||||
|
@ -83,7 +83,18 @@ public:
|
|||
* data Data to write.
|
||||
* numBytes Number of bytes to write.
|
||||
*/
|
||||
void Write(const void *data, unsigned numBytes);
|
||||
void Write(const void *data, uint32_t numBytes);
|
||||
|
||||
/*
|
||||
* Write(str):
|
||||
*
|
||||
* Outputs string (including null terminator) at the current file pointer
|
||||
* position. Updates the block header appropriately.
|
||||
*
|
||||
* Parameters:
|
||||
* str String to write.
|
||||
*/
|
||||
void Write(const std::string &str);
|
||||
|
||||
/*
|
||||
* NewBlock(name, comment):
|
||||
|
@ -95,7 +106,7 @@ public:
|
|||
* name Block name. Must be unique and not NULL.
|
||||
* comment Comment string to embed in the block header.
|
||||
*/
|
||||
void NewBlock(const char *title, const char *comment);
|
||||
void NewBlock(const std::string &title, const std::string &comment);
|
||||
|
||||
/*
|
||||
* Create(file, headerName, comment):
|
||||
|
@ -113,7 +124,7 @@ public:
|
|||
* Returns:
|
||||
* OKAY if successfully opened, otherwise FAIL.
|
||||
*/
|
||||
bool Create(const char *file, const char *headerName, const char *comment);
|
||||
bool Create(const std::string &file, const std::string &headerName, const std::string &comment);
|
||||
|
||||
/*
|
||||
* Load(file):
|
||||
|
@ -129,7 +140,7 @@ public:
|
|||
* subsequent operations will be silently ignored (reads will return
|
||||
* 0's). Write commands will be ignored.
|
||||
*/
|
||||
bool Load(const char *file);
|
||||
bool Load(const std::string &file);
|
||||
|
||||
/*
|
||||
* Close(void):
|
||||
|
@ -149,17 +160,16 @@ public:
|
|||
|
||||
private:
|
||||
// Helper functions
|
||||
void ReadString(char *str, unsigned strLen, unsigned maxLen);
|
||||
unsigned ReadBytes(void *data, unsigned numBytes);
|
||||
void ReadString(std::string *str, uint32_t length);
|
||||
unsigned ReadBytes(void *data, uint32_t numBytes);
|
||||
unsigned ReadDWord(uint32_t *data);
|
||||
void UpdateBlockSize(void);
|
||||
void WriteByte(uint8_t data);
|
||||
void WriteDWord(uint32_t data);
|
||||
void WriteBytes(const void *data, unsigned numBytes);
|
||||
void WriteBlockHeader(const char *name, const char *comment);
|
||||
void WriteBytes(const void *data, uint32_t numBytes);
|
||||
void WriteBlockHeader(const std::string &name, const std::string &comment);
|
||||
|
||||
// File state data
|
||||
char strBuf[1026]; // buffers up to a 1024-character string, its terminator, and an extra terminator (just in case)
|
||||
FILE *fp;
|
||||
int mode; // 'r' for read, 'w' for write
|
||||
long int fileSize; // size of file in bytes
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** 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
71
Src/Config.h
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** 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 Legacy3D::CLegacy3DConfig, public CModel3Config, public CSoundBoardConfig, public CDSBConfig, public CDriveBoardConfig
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
* g_Config:
|
||||
*
|
||||
* Program-wide configuration settings object.
|
||||
*/
|
||||
extern CConfig g_Config;
|
||||
|
||||
|
||||
#endif // INCLUDED_CONFIG_H
|
|
@ -514,7 +514,7 @@ namespace Debugger
|
|||
}
|
||||
else if (CheckToken(token, "caip", "configallinputs")) // configallinputs
|
||||
{
|
||||
m_inputs->ConfigureInputs(m_model3->GetGameInfo());
|
||||
m_inputs->ConfigureInputs(&m_model3->GetGame());
|
||||
return false;
|
||||
}
|
||||
//
|
||||
|
@ -544,7 +544,7 @@ namespace Debugger
|
|||
|
||||
bool CSupermodelDebugger::InputIsValid(::CInput *input)
|
||||
{
|
||||
return input->IsUIInput() || (input->gameFlags & m_model3->GetGameInfo()->inputFlags);
|
||||
return input->IsUIInput() || (input->gameFlags & m_model3->GetGame().inputs);
|
||||
}
|
||||
|
||||
void CSupermodelDebugger::ListInputs()
|
||||
|
@ -599,14 +599,14 @@ namespace Debugger
|
|||
CConsoleDebugger::Attached();
|
||||
|
||||
char fileName[25];
|
||||
sprintf(fileName, "Debug/%s.ds", m_model3->GetGameInfo()->id);
|
||||
sprintf(fileName, "Debug/%s.ds", m_model3->GetGame().name.c_str());
|
||||
LoadState(fileName);
|
||||
}
|
||||
|
||||
void CSupermodelDebugger::Detaching()
|
||||
{
|
||||
char fileName[25];
|
||||
sprintf(fileName, "Debug/%s.ds", m_model3->GetGameInfo()->id);
|
||||
sprintf(fileName, "Debug/%s.ds", m_model3->GetGame().name.c_str());
|
||||
SaveState(fileName);
|
||||
|
||||
CConsoleDebugger::Detaching();
|
||||
|
|
|
@ -799,7 +799,7 @@ void CLegacy3D::DescendNodePtr(UINT32 nodeAddr)
|
|||
}
|
||||
|
||||
// Draws viewports of the given priority
|
||||
void CLegacy3D::RenderViewport(UINT32 addr, int pri)
|
||||
void CLegacy3D::RenderViewport(UINT32 addr, int pri, bool wideScreen)
|
||||
{
|
||||
static const GLfloat color[8][3] = {
|
||||
{ 0.0, 0.0, 0.0 }, // off
|
||||
|
@ -823,7 +823,7 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
|
|||
if (nextAddr == 0) // memory probably hasn't been set up yet, abort
|
||||
return;
|
||||
if (nextAddr != 0x01000000)
|
||||
RenderViewport(nextAddr, pri);
|
||||
RenderViewport(nextAddr, pri, wideScreen);
|
||||
|
||||
// Skip disabled viewports
|
||||
//if ((vpnode[0] & 0x20) != 0)
|
||||
|
@ -849,7 +849,7 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
|
|||
// Set up viewport and projection (TO-DO: near and far clipping)
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
if (g_Config.wideScreen && (vpX==0) && (vpWidth>=495) && (vpY==0) && (vpHeight >= 383)) // only expand viewports that occupy whole screen
|
||||
if (wideScreen && (vpX==0) && (vpWidth>=495) && (vpY==0) && (vpHeight >= 383)) // only expand viewports that occupy whole screen
|
||||
{
|
||||
// Wide screen hack only modifies X axis and not the Y FOV
|
||||
viewportX = 0;
|
||||
|
@ -958,6 +958,8 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
|
|||
|
||||
void CLegacy3D::RenderFrame(void)
|
||||
{
|
||||
bool wideScreen = m_config["WideScreen"].ValueAs<bool>();
|
||||
|
||||
// Begin frame
|
||||
ClearErrors(); // must be cleared each frame
|
||||
|
||||
|
@ -1009,7 +1011,7 @@ void CLegacy3D::RenderFrame(void)
|
|||
//ClearModelCache(&PolyCache);
|
||||
ClearDisplayList(&PolyCache);
|
||||
ClearDisplayList(&VROMCache);
|
||||
RenderViewport(0x800000,pri);
|
||||
RenderViewport(0x800000,pri,wideScreen);
|
||||
DrawDisplayList(&VROMCache, POLY_STATE_NORMAL);
|
||||
DrawDisplayList(&PolyCache, POLY_STATE_NORMAL);
|
||||
DrawDisplayList(&VROMCache, POLY_STATE_ALPHA);
|
||||
|
@ -1058,9 +1060,9 @@ void CLegacy3D::AttachMemory(const UINT32 *cullingRAMLoPtr, const UINT32 *cullin
|
|||
DebugLog("Legacy3D attached Real3D memory regions\n");
|
||||
}
|
||||
|
||||
void CLegacy3D::SetStep(int stepID)
|
||||
void CLegacy3D::SetStepping(int stepping)
|
||||
{
|
||||
step = stepID;
|
||||
step = stepping;
|
||||
|
||||
if ((step!=0x10) && (step!=0x15) && (step!=0x20) && (step!=0x21))
|
||||
{
|
||||
|
@ -1124,12 +1126,12 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
|
|||
// Get upper limit for number of texture maps to use from max number of texture units supported by video card
|
||||
GLint glMaxTexUnits;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &glMaxTexUnits);
|
||||
int maxTexMaps = std::max<int>(1, std::min<int>(g_Config.maxTexMaps, glMaxTexUnits));
|
||||
int maxTexMaps = std::max<int>(1, std::min<int>(m_config["MaxTexMaps"].ValueAsDefault<int>(9), glMaxTexUnits));
|
||||
|
||||
// Get upper limit for extent of texture maps to use from max texture size supported by video card
|
||||
GLint maxTexSize;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
|
||||
int mapExtent = std::max<int>(1, std::min<unsigned>(g_Config.maxTexMapExtent, maxTexSize / 2048));
|
||||
int mapExtent = std::max<int>(1, std::min<unsigned>(m_config["MaxTexMapExtent"].ValueAsDefault<int>(4), maxTexSize / 2048));
|
||||
int mapSize = 2048 * mapExtent;
|
||||
while (mapExtent > 1)
|
||||
{
|
||||
|
@ -1147,10 +1149,8 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
|
|||
}
|
||||
|
||||
// Load shaders, using multi-sheet shader if requested.
|
||||
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;
|
||||
const char *fragmentShaderSource = (g_Config.multiTexture ? fragmentShaderMultiSheetSource : fragmentShaderSingleSheetSource); // single texture shader
|
||||
if (OKAY != LoadShaderProgram(&shaderProgram,&vertexShader,&fragmentShader,vsFile,fsFile,vertexShaderSource,fragmentShaderSource))
|
||||
const char *fragmentShaderSource = (m_config["MultiTexture"].ValueAs<bool>() ? fragmentShaderMultiSheetSource : fragmentShaderSingleSheetSource); // single texture shader
|
||||
if (OKAY != LoadShaderProgram(&shaderProgram,&vertexShader,&fragmentShader,m_config["VertexShader"].ValueAs<std::string>(),m_config["FragmentShader"].ValueAs<std::string>(),vertexShaderSource,fragmentShaderSource))
|
||||
return FAIL;
|
||||
|
||||
// Try locating default "textureMap" uniform in shader program
|
||||
|
@ -1291,7 +1291,8 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
|
|||
return OKAY;
|
||||
}
|
||||
|
||||
CLegacy3D::CLegacy3D(void)
|
||||
CLegacy3D::CLegacy3D(const Util::Config::Node &config)
|
||||
: m_config(config)
|
||||
{
|
||||
cullingRAMLo = NULL;
|
||||
cullingRAMHi = NULL;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "Graphics/IRender3D.h"
|
||||
#include "Pkgs/glew.h"
|
||||
#include "Util/NewConfig.h"
|
||||
|
||||
namespace Legacy3D {
|
||||
|
||||
|
@ -223,30 +224,6 @@ struct TexSheet
|
|||
CLegacy3D Classes
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* CLegacy3DConfig:
|
||||
*
|
||||
* Settings used by CLegacy3D.
|
||||
*/
|
||||
class CLegacy3DConfig
|
||||
{
|
||||
public:
|
||||
string vertexShaderFile; // path to vertex shader or "" to use internal shader
|
||||
string fragmentShaderFile; // fragment shader
|
||||
unsigned maxTexMaps; // maximum number of texture maps to use (1-9)
|
||||
unsigned maxTexMapExtent; // maximum extent of texture maps (where num of tex sheets per map = extent ^ 2)
|
||||
bool multiTexture; // if enabled and no external fragment shader, select internal shader w/ multiple texture sheet support
|
||||
|
||||
// Defaults
|
||||
CLegacy3DConfig(void)
|
||||
{
|
||||
// strings will be clear to begin with
|
||||
maxTexMaps = 9;
|
||||
maxTexMapExtent = 4;
|
||||
multiTexture = false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* CLegacy3D:
|
||||
*
|
||||
|
@ -314,17 +291,17 @@ public:
|
|||
const UINT32 *vromPtr, const UINT16 *textureRAMPtr);
|
||||
|
||||
/*
|
||||
* SetStep(stepID):
|
||||
* SetStepping(stepping):
|
||||
*
|
||||
* Sets the Model 3 hardware stepping, which also determines the Real3D
|
||||
* functionality. The default is Step 1.0. This should be called prior to
|
||||
* any other emulation functions and after Init().
|
||||
*
|
||||
* Parameters:
|
||||
* stepID 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0,
|
||||
* or 0x21 for Step 2.1. Anything else defaults to 1.0.
|
||||
* stepping 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0, or
|
||||
* 0x21 for Step 2.1. Anything else defaults to 1.0.
|
||||
*/
|
||||
void SetStep(int stepID);
|
||||
void SetStepping(int stepping);
|
||||
|
||||
/*
|
||||
* Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes):
|
||||
|
@ -355,16 +332,19 @@ public:
|
|||
* CLegacy3D(void):
|
||||
* ~CLegacy3D(void):
|
||||
*
|
||||
* Parameters:
|
||||
* config Configuration object.
|
||||
*
|
||||
* Constructor and destructor.
|
||||
*/
|
||||
CLegacy3D(void);
|
||||
CLegacy3D(const Util::Config::Node &config);
|
||||
~CLegacy3D(void);
|
||||
|
||||
private:
|
||||
/*
|
||||
* Private Members
|
||||
*/
|
||||
|
||||
|
||||
// Real3D address translation
|
||||
const UINT32 *TranslateCullingAddress(UINT32 addr);
|
||||
const UINT32 *TranslateModelAddress(UINT32 addr);
|
||||
|
@ -397,7 +377,7 @@ private:
|
|||
void DescendCullingNode(UINT32 addr);
|
||||
void DescendPointerList(UINT32 addr);
|
||||
void DescendNodePtr(UINT32 nodeAddr);
|
||||
void RenderViewport(UINT32 addr, int pri);
|
||||
void RenderViewport(UINT32 addr, int pri, bool wideScreen);
|
||||
|
||||
// In-frame error reporting
|
||||
bool ErrorLocalVertexOverflow(void);
|
||||
|
@ -407,6 +387,8 @@ private:
|
|||
/*
|
||||
* Data
|
||||
*/
|
||||
|
||||
const Util::Config::Node &m_config;
|
||||
|
||||
// Stepping
|
||||
int step;
|
||||
|
|
|
@ -35,9 +35,9 @@ void CNew3D::AttachMemory(const UINT32 *cullingRAMLoPtr, const UINT32 *cullingRA
|
|||
m_textureRAM = textureRAMPtr;
|
||||
}
|
||||
|
||||
void CNew3D::SetStep(int stepID)
|
||||
void CNew3D::SetStepping(int stepping)
|
||||
{
|
||||
m_step = stepID;
|
||||
m_step = stepping;
|
||||
|
||||
if ((m_step != 0x10) && (m_step != 0x15) && (m_step != 0x20) && (m_step != 0x21)) {
|
||||
m_step = 0x10;
|
||||
|
|
|
@ -104,17 +104,17 @@ public:
|
|||
const UINT32 *vromPtr, const UINT16 *textureRAMPtr);
|
||||
|
||||
/*
|
||||
* SetStep(stepID):
|
||||
* SetStepping(stepping):
|
||||
*
|
||||
* Sets the Model 3 hardware stepping, which also determines the Real3D
|
||||
* functionality. The default is Step 1.0. This should be called prior to
|
||||
* any other emulation functions and after Init().
|
||||
*
|
||||
* Parameters:
|
||||
* stepID 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0,
|
||||
* or 0x21 for Step 2.1. Anything else defaults to 1.0.
|
||||
* stepping 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0, or
|
||||
* 0x21 for Step 2.1. Anything else defaults to 1.0.
|
||||
*/
|
||||
void SetStep(int stepID);
|
||||
void SetStepping(int stepping);
|
||||
|
||||
/*
|
||||
* Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes):
|
||||
|
|
|
@ -80,7 +80,7 @@ void R3DScrollFog::DrawScrollFog(float r, float g, float b, float a)
|
|||
|
||||
void R3DScrollFog::AllocResources()
|
||||
{
|
||||
bool success = LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, nullptr, nullptr, vertexShaderFog, fragmentShaderFog);
|
||||
bool success = LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, std::string(), std::string(), vertexShaderFog, fragmentShaderFog);
|
||||
|
||||
m_locMVP = glGetUniformLocation(m_shaderProgram, "mvp");
|
||||
m_locFogColour = glGetUniformLocation(m_shaderProgram, "fogColour");
|
||||
|
|
|
@ -195,7 +195,7 @@ bool R3DShader::LoadShader(const char* vertexShader, const char* fragmentShader)
|
|||
fShader = fragmentShaderBasic;
|
||||
}
|
||||
|
||||
success = LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, nullptr, nullptr, vShader, fShader);
|
||||
success = LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, std::string(), std::string(), vShader, fShader);
|
||||
|
||||
m_locTexture1 = glGetUniformLocation(m_shaderProgram, "tex1");
|
||||
m_locTexture2 = glGetUniformLocation(m_shaderProgram, "tex2");
|
||||
|
|
|
@ -638,7 +638,7 @@ void CRender2D::AttachVRAM(const uint8_t *vramPtr)
|
|||
bool CRender2D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes)
|
||||
{
|
||||
// Load shaders
|
||||
if (OKAY != LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, 0, 0, s_vertexShaderSource, s_fragmentShaderSource))
|
||||
if (OKAY != LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, std::string(), std::string(), s_vertexShaderSource, s_fragmentShaderSource))
|
||||
return FAIL;
|
||||
|
||||
// Get locations of the uniforms
|
||||
|
|
|
@ -82,7 +82,7 @@ static char *LoadShaderSource(const char *file)
|
|||
return buf;
|
||||
}
|
||||
|
||||
bool LoadShaderProgram(GLuint *shaderProgramPtr, GLuint *vertexShaderPtr, GLuint *fragmentShaderPtr, const char *vsFile, const char *fsFile, const char *vsString, const char *fsString)
|
||||
bool LoadShaderProgram(GLuint *shaderProgramPtr, GLuint *vertexShaderPtr, GLuint *fragmentShaderPtr, std::string vsFile, std::string fsFile, const char *vsString, const char *fsString)
|
||||
{
|
||||
char infoLog[2048];
|
||||
const char *vsSource, *fsSource; // source code
|
||||
|
@ -91,12 +91,12 @@ bool LoadShaderProgram(GLuint *shaderProgramPtr, GLuint *vertexShaderPtr, GLuint
|
|||
bool ret = OKAY;
|
||||
|
||||
// Load shaders from files if specified
|
||||
if (vsFile != NULL)
|
||||
vsSource = LoadShaderSource(vsFile);
|
||||
if (!vsFile.empty())
|
||||
vsSource = LoadShaderSource(vsFile.c_str());
|
||||
else
|
||||
vsSource = vsString;
|
||||
if (fsFile != NULL)
|
||||
fsSource = LoadShaderSource(fsFile);
|
||||
if (!fsFile.empty())
|
||||
fsSource = LoadShaderSource(fsFile.c_str());
|
||||
else
|
||||
fsSource = fsString;
|
||||
if (vsSource == NULL || fsSource == NULL)
|
||||
|
@ -161,9 +161,9 @@ bool LoadShaderProgram(GLuint *shaderProgramPtr, GLuint *vertexShaderPtr, GLuint
|
|||
|
||||
// Clean up and quit
|
||||
Quit:
|
||||
if ((vsSource != NULL) && (vsFile != NULL)) // loaded from file, must delete
|
||||
if ((vsSource != NULL) && !vsFile.empty()) // loaded from file, must delete
|
||||
delete [] vsSource;
|
||||
if ((fsSource != NULL) && (fsFile != NULL)) // ""
|
||||
if ((fsSource != NULL) && !fsFile.empty()) // ""
|
||||
delete [] fsSource;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define INCLUDED_SHADER_H
|
||||
|
||||
#include "Pkgs/glew.h"
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
* LoadShaderProgram(shaderProgramPtr, vertexShaderPtr, fragmentShaderPtr,
|
||||
|
@ -52,8 +53,8 @@
|
|||
* OKAY is successfully loaded, otherwise FAIL. Prints own error messages.
|
||||
*/
|
||||
extern bool LoadShaderProgram(GLuint *shaderProgramPtr, GLuint *vertexShaderPtr,
|
||||
GLuint *fragmentShaderPtr, const char *vsFile,
|
||||
const char *fsFile, const char *vsString,
|
||||
GLuint *fragmentShaderPtr, std::string vsFile,
|
||||
std::string fsFile, const char *vsString,
|
||||
const char *fsString);
|
||||
|
||||
/*
|
||||
|
|
|
@ -83,29 +83,29 @@ const char* CInput::GetInputGroup()
|
|||
{
|
||||
switch (gameFlags)
|
||||
{
|
||||
case GAME_INPUT_UI: return "User Interface Controls";
|
||||
case GAME_INPUT_COMMON: return "Common Controls";
|
||||
case GAME_INPUT_JOYSTICK1: // Fall through to below
|
||||
case GAME_INPUT_JOYSTICK2: return "4-Way Joysticks";
|
||||
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_VEHICLE: return "Racing Game Steering Controls";
|
||||
case GAME_INPUT_SHIFT4: return "Racing Game Gear 4-Way Shift";
|
||||
case GAME_INPUT_SHIFTUPDOWN: return "Racing Game Gear Up/Down Shift";
|
||||
case GAME_INPUT_VR4: return "Racing Game 4 VR View Buttons";
|
||||
case GAME_INPUT_VIEWCHANGE: return "Racing Game View Change";
|
||||
case GAME_INPUT_HANDBRAKE: return "Racing Game Handbrake";
|
||||
case GAME_INPUT_HARLEY: return "Harley Davidson Controls";
|
||||
case GAME_INPUT_TWIN_JOYSTICKS: return "Virtual On Controls";
|
||||
case GAME_INPUT_ANALOG_JOYSTICK: return "Analog Joystick";
|
||||
case GAME_INPUT_GUN1: // Fall through to below
|
||||
case GAME_INPUT_GUN2: return "Light Guns";
|
||||
case GAME_INPUT_ANALOG_GUN1: // Fall through to below
|
||||
case GAME_INPUT_ANALOG_GUN2: return "Analog Guns";
|
||||
case GAME_INPUT_SKI: return "Ski Controls";
|
||||
case GAME_INPUT_MAGTRUCK: return "Magical Truck Controls";
|
||||
case GAME_INPUT_FISHING: return "Fishing Controls";
|
||||
case Game::INPUT_UI: return "User Interface Controls";
|
||||
case Game::INPUT_COMMON: return "Common Controls";
|
||||
case Game::INPUT_JOYSTICK1: // Fall through to below
|
||||
case Game::INPUT_JOYSTICK2: return "4-Way Joysticks";
|
||||
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_VEHICLE: return "Racing Game Steering Controls";
|
||||
case Game::INPUT_SHIFT4: return "Racing Game Gear 4-Way Shift";
|
||||
case Game::INPUT_SHIFTUPDOWN: return "Racing Game Gear Up/Down Shift";
|
||||
case Game::INPUT_VR4: return "Racing Game 4 VR View Buttons";
|
||||
case Game::INPUT_VIEWCHANGE: return "Racing Game View Change";
|
||||
case Game::INPUT_HANDBRAKE: return "Racing Game Handbrake";
|
||||
case Game::INPUT_HARLEY: return "Harley Davidson Controls";
|
||||
case Game::INPUT_TWIN_JOYSTICKS: return "Virtual On Controls";
|
||||
case Game::INPUT_ANALOG_JOYSTICK: return "Analog Joystick";
|
||||
case Game::INPUT_GUN1: // Fall through to below
|
||||
case Game::INPUT_GUN2: return "Light Guns";
|
||||
case Game::INPUT_ANALOG_GUN1: // Fall through to below
|
||||
case Game::INPUT_ANALOG_GUN2: return "Analog Guns";
|
||||
case Game::INPUT_SKI: return "Ski Controls";
|
||||
case Game::INPUT_MAGTRUCK: return "Magical Truck Controls";
|
||||
case Game::INPUT_FISHING: return "Fishing Controls";
|
||||
default: return "Misc";
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +147,38 @@ void CInput::ResetToDefaultMapping()
|
|||
SetMapping(m_defaultMapping);
|
||||
}
|
||||
|
||||
void CInput::LoadFromConfig(const Util::Config::Node &config)
|
||||
{
|
||||
// See if input is configurable
|
||||
if (IsConfigurable())
|
||||
{
|
||||
// If so, check INI file for mapping string
|
||||
string key("Input");
|
||||
key.append(id);
|
||||
string mapping;
|
||||
auto *node = config.TryGet(key);
|
||||
if (node)
|
||||
{
|
||||
// If found, then set mapping string
|
||||
mapping = node->ValueAs<std::string>();
|
||||
SetMapping(mapping.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If input has not been configured, then force recreation of source anyway since input system settings may have changed
|
||||
CreateSource();
|
||||
}
|
||||
|
||||
void CInput::StoreToConfig(Util::Config::Node *config)
|
||||
{
|
||||
if (!IsConfigurable())
|
||||
return;
|
||||
string key("Input");
|
||||
key.append(id);
|
||||
config->Set(key, m_mapping);
|
||||
}
|
||||
|
||||
void CInput::ReadFromINIFile(CINIFile *ini, const char *section)
|
||||
{
|
||||
// See if input is configurable
|
||||
|
|
|
@ -23,21 +23,20 @@
|
|||
* Input.h
|
||||
*
|
||||
* Header file for base input class, CInput, defining an input source. Also
|
||||
* defines GAME_INPUT_UI.
|
||||
* defines Game::INPUT_UI.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_INPUT_H
|
||||
#define INCLUDED_INPUT_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "Game.h"
|
||||
#include "Util/NewConfig.h"
|
||||
|
||||
class CInputSource;
|
||||
class CInputSystem;
|
||||
class CINIFile;
|
||||
|
||||
// Special game input flag for UI controls
|
||||
#define GAME_INPUT_UI 0
|
||||
|
||||
// Flags for inputs
|
||||
#define INPUT_FLAGS_SWITCH 0x0001
|
||||
#define INPUT_FLAGS_ANALOG 0x0002
|
||||
|
@ -152,13 +151,15 @@ public:
|
|||
void ResetToDefaultMapping();
|
||||
|
||||
/*
|
||||
* Reads the input's mapping(s) from the given INI file, as well as any other settings.
|
||||
* Loads the input's mapping(s) from the given config object, as well as any other settings.
|
||||
*/
|
||||
virtual void LoadFromConfig(const Util::Config::Node &config);
|
||||
virtual void ReadFromINIFile(CINIFile *ini, const char *section);
|
||||
|
||||
/*
|
||||
* Writes the current input mapping(s) to the given INI file, as well as any other settings.
|
||||
* Stores the current input mapping(s) to the given config object, as well as any other settings.
|
||||
*/
|
||||
virtual void StoreToConfig(Util::Config::Node *config);
|
||||
virtual void WriteToINIFile(CINIFile *ini, const char *section);
|
||||
|
||||
void InputSystemChanged();
|
||||
|
@ -207,13 +208,13 @@ public:
|
|||
|
||||
inline bool CInput::IsUIInput()
|
||||
{
|
||||
return gameFlags == GAME_INPUT_UI;
|
||||
return gameFlags == Game::INPUT_UI;
|
||||
}
|
||||
|
||||
inline bool CInput::IsConfigurable()
|
||||
{
|
||||
// All inputs except UI and virtual ones can be configured by the user
|
||||
return (gameFlags != GAME_INPUT_UI) && !(flags & INPUT_FLAGS_VIRTUAL);
|
||||
return (gameFlags != Game::INPUT_UI) && !(flags & INPUT_FLAGS_VIRTUAL);
|
||||
}
|
||||
|
||||
inline bool CInput::IsVirtual()
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "Supermodel.h"
|
||||
#include "Game.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <vector>
|
||||
|
@ -34,240 +35,241 @@
|
|||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
CInputs::CInputs(CInputSystem *system) : m_system(system)
|
||||
CInputs::CInputs(CInputSystem *system)
|
||||
: m_system(system)
|
||||
{
|
||||
// UI controls are hard coded here, everything else is initialized to NONE so that it can be loaded from
|
||||
// the config file.
|
||||
|
||||
// UI Controls
|
||||
uiExit = AddSwitchInput("UIExit", "Exit UI", GAME_INPUT_UI, "KEY_ESCAPE");
|
||||
uiReset = AddSwitchInput("UIReset", "Reset", GAME_INPUT_UI, "KEY_ALT+KEY_R");
|
||||
uiPause = AddSwitchInput("UIPause", "Pause", GAME_INPUT_UI, "KEY_ALT+KEY_P");
|
||||
uiFullScreen = AddSwitchInput("UIFullScreen", "Toggle Fullscreen", GAME_INPUT_UI, "KEY_ALT+KEY_RETURN");
|
||||
uiSaveState = AddSwitchInput("UISaveState", "Save State", GAME_INPUT_UI, "KEY_F5");
|
||||
uiChangeSlot = AddSwitchInput("UIChangeSlot", "Change Save Slot", GAME_INPUT_UI, "KEY_F6");
|
||||
uiLoadState = AddSwitchInput("UILoadState", "Load State", GAME_INPUT_UI, "KEY_F7");
|
||||
uiMusicVolUp = AddSwitchInput("UIMusicVolUp", "Increase Music Volume", GAME_INPUT_UI, "KEY_F10");
|
||||
uiMusicVolDown = AddSwitchInput("UIMusicVolDown", "Decrease Music Volume", GAME_INPUT_UI, "KEY_F9");
|
||||
uiSoundVolUp = AddSwitchInput("UISoundVolUp", "Increase Sound Volume", GAME_INPUT_UI, "KEY_F12");
|
||||
uiSoundVolDown = AddSwitchInput("UISoundVolDown", "Decrease Sound Volume", GAME_INPUT_UI, "KEY_F11");
|
||||
uiClearNVRAM = AddSwitchInput("UIClearNVRAM", "Clear NVRAM", GAME_INPUT_UI, "KEY_ALT+KEY_N");
|
||||
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");
|
||||
uiDumpInpState = AddSwitchInput("UIDumpInputState", "Dump Input State", GAME_INPUT_UI, "KEY_ALT+KEY_U");
|
||||
uiDumpTimings = AddSwitchInput("UIDumpTimings", "Dump Frame Timings", GAME_INPUT_UI, "KEY_ALT+KEY_O");
|
||||
uiExit = AddSwitchInput("UIExit", "Exit UI", Game::INPUT_UI, "KEY_ESCAPE");
|
||||
uiReset = AddSwitchInput("UIReset", "Reset", Game::INPUT_UI, "KEY_ALT+KEY_R");
|
||||
uiPause = AddSwitchInput("UIPause", "Pause", Game::INPUT_UI, "KEY_ALT+KEY_P");
|
||||
uiFullScreen = AddSwitchInput("UIFullScreen", "Toggle Fullscreen", Game::INPUT_UI, "KEY_ALT+KEY_RETURN");
|
||||
uiSaveState = AddSwitchInput("UISaveState", "Save State", Game::INPUT_UI, "KEY_F5");
|
||||
uiChangeSlot = AddSwitchInput("UIChangeSlot", "Change Save Slot", Game::INPUT_UI, "KEY_F6");
|
||||
uiLoadState = AddSwitchInput("UILoadState", "Load State", Game::INPUT_UI, "KEY_F7");
|
||||
uiMusicVolUp = AddSwitchInput("UIMusicVolUp", "Increase Music Volume", Game::INPUT_UI, "KEY_F10");
|
||||
uiMusicVolDown = AddSwitchInput("UIMusicVolDown", "Decrease Music Volume", Game::INPUT_UI, "KEY_F9");
|
||||
uiSoundVolUp = AddSwitchInput("UISoundVolUp", "Increase Sound Volume", Game::INPUT_UI, "KEY_F12");
|
||||
uiSoundVolDown = AddSwitchInput("UISoundVolDown", "Decrease Sound Volume", Game::INPUT_UI, "KEY_F11");
|
||||
uiClearNVRAM = AddSwitchInput("UIClearNVRAM", "Clear NVRAM", Game::INPUT_UI, "KEY_ALT+KEY_N");
|
||||
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");
|
||||
uiDumpInpState = AddSwitchInput("UIDumpInputState", "Dump Input State", Game::INPUT_UI, "KEY_ALT+KEY_U");
|
||||
uiDumpTimings = AddSwitchInput("UIDumpTimings", "Dump Frame Timings", Game::INPUT_UI, "KEY_ALT+KEY_O");
|
||||
#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");
|
||||
#endif
|
||||
|
||||
// Common Controls
|
||||
start[0] = AddSwitchInput("Start1", "P1 Start", GAME_INPUT_COMMON, "NONE");
|
||||
start[1] = AddSwitchInput("Start2", "P2 Start", GAME_INPUT_COMMON, "NONE");
|
||||
coin[0] = AddSwitchInput("Coin1", "P1 Coin", GAME_INPUT_COMMON, "NONE");
|
||||
coin[1] = AddSwitchInput("Coin2", "P2 Coin", GAME_INPUT_COMMON, "NONE");
|
||||
service[0] = AddSwitchInput("ServiceA", "Service A", GAME_INPUT_COMMON, "NONE");
|
||||
service[1] = AddSwitchInput("ServiceB", "Service B", GAME_INPUT_COMMON, "NONE");
|
||||
test[0] = AddSwitchInput("TestA", "Test A", GAME_INPUT_COMMON, "NONE");
|
||||
test[1] = AddSwitchInput("TestB", "Test B", GAME_INPUT_COMMON, "NONE");
|
||||
start[0] = AddSwitchInput("Start1", "P1 Start", Game::INPUT_COMMON, "NONE");
|
||||
start[1] = AddSwitchInput("Start2", "P2 Start", Game::INPUT_COMMON, "NONE");
|
||||
coin[0] = AddSwitchInput("Coin1", "P1 Coin", Game::INPUT_COMMON, "NONE");
|
||||
coin[1] = AddSwitchInput("Coin2", "P2 Coin", Game::INPUT_COMMON, "NONE");
|
||||
service[0] = AddSwitchInput("ServiceA", "Service A", Game::INPUT_COMMON, "NONE");
|
||||
service[1] = AddSwitchInput("ServiceB", "Service B", Game::INPUT_COMMON, "NONE");
|
||||
test[0] = AddSwitchInput("TestA", "Test A", Game::INPUT_COMMON, "NONE");
|
||||
test[1] = AddSwitchInput("TestB", "Test B", Game::INPUT_COMMON, "NONE");
|
||||
|
||||
// 4-Way Joysticks
|
||||
up[0] = AddSwitchInput("JoyUp", "P1 Joystick Up", GAME_INPUT_JOYSTICK1, "NONE");
|
||||
down[0] = AddSwitchInput("JoyDown", "P1 Joystick Down", GAME_INPUT_JOYSTICK1, "NONE");
|
||||
left[0] = AddSwitchInput("JoyLeft", "P1 Joystick Left", GAME_INPUT_JOYSTICK1, "NONE");
|
||||
right[0] = AddSwitchInput("JoyRight", "P1 Joystick Right", GAME_INPUT_JOYSTICK1, "NONE");
|
||||
up[1] = AddSwitchInput("JoyUp2", "P2 Joystick Up", GAME_INPUT_JOYSTICK2, "NONE");
|
||||
down[1] = AddSwitchInput("JoyDown2", "P2 Joystick Down", GAME_INPUT_JOYSTICK2, "NONE");
|
||||
left[1] = AddSwitchInput("JoyLeft2", "P2 Joystick Left", GAME_INPUT_JOYSTICK2, "NONE");
|
||||
right[1] = AddSwitchInput("JoyRight2", "P2 Joystick Right", GAME_INPUT_JOYSTICK2, "NONE");
|
||||
up[0] = AddSwitchInput("JoyUp", "P1 Joystick Up", Game::INPUT_JOYSTICK1, "NONE");
|
||||
down[0] = AddSwitchInput("JoyDown", "P1 Joystick Down", Game::INPUT_JOYSTICK1, "NONE");
|
||||
left[0] = AddSwitchInput("JoyLeft", "P1 Joystick Left", Game::INPUT_JOYSTICK1, "NONE");
|
||||
right[0] = AddSwitchInput("JoyRight", "P1 Joystick Right", Game::INPUT_JOYSTICK1, "NONE");
|
||||
up[1] = AddSwitchInput("JoyUp2", "P2 Joystick Up", Game::INPUT_JOYSTICK2, "NONE");
|
||||
down[1] = AddSwitchInput("JoyDown2", "P2 Joystick Down", Game::INPUT_JOYSTICK2, "NONE");
|
||||
left[1] = AddSwitchInput("JoyLeft2", "P2 Joystick Left", Game::INPUT_JOYSTICK2, "NONE");
|
||||
right[1] = AddSwitchInput("JoyRight2", "P2 Joystick Right", Game::INPUT_JOYSTICK2, "NONE");
|
||||
|
||||
// Fighting Game Buttons
|
||||
punch[0] = AddSwitchInput("Punch", "P1 Punch", GAME_INPUT_FIGHTING, "NONE");
|
||||
kick[0] = AddSwitchInput("Kick", "P1 Kick", GAME_INPUT_FIGHTING, "NONE");
|
||||
guard[0] = AddSwitchInput("Guard", "P1 Guard", GAME_INPUT_FIGHTING, "NONE");
|
||||
escape[0] = AddSwitchInput("Escape", "P1 Escape", GAME_INPUT_FIGHTING, "NONE");
|
||||
punch[1] = AddSwitchInput("Punch2", "P2 Punch", GAME_INPUT_FIGHTING, "NONE");
|
||||
kick[1] = AddSwitchInput("Kick2", "P2 Kick", GAME_INPUT_FIGHTING, "NONE");
|
||||
guard[1] = AddSwitchInput("Guard2", "P2 Guard", GAME_INPUT_FIGHTING, "NONE");
|
||||
escape[1] = AddSwitchInput("Escape2", "P2 Escape", GAME_INPUT_FIGHTING, "NONE");
|
||||
punch[0] = AddSwitchInput("Punch", "P1 Punch", Game::INPUT_FIGHTING, "NONE");
|
||||
kick[0] = AddSwitchInput("Kick", "P1 Kick", Game::INPUT_FIGHTING, "NONE");
|
||||
guard[0] = AddSwitchInput("Guard", "P1 Guard", Game::INPUT_FIGHTING, "NONE");
|
||||
escape[0] = AddSwitchInput("Escape", "P1 Escape", Game::INPUT_FIGHTING, "NONE");
|
||||
punch[1] = AddSwitchInput("Punch2", "P2 Punch", Game::INPUT_FIGHTING, "NONE");
|
||||
kick[1] = AddSwitchInput("Kick2", "P2 Kick", Game::INPUT_FIGHTING, "NONE");
|
||||
guard[1] = AddSwitchInput("Guard2", "P2 Guard", Game::INPUT_FIGHTING, "NONE");
|
||||
escape[1] = AddSwitchInput("Escape2", "P2 Escape", Game::INPUT_FIGHTING, "NONE");
|
||||
|
||||
// Spikeout Buttons
|
||||
shift = AddSwitchInput("Shift", "Shift", GAME_INPUT_SPIKEOUT, "NONE");
|
||||
beat = AddSwitchInput("Beat", "Beat", GAME_INPUT_SPIKEOUT, "NONE");
|
||||
charge = AddSwitchInput("Charge", "Charge",GAME_INPUT_SPIKEOUT, "NONE");
|
||||
jump = AddSwitchInput("Jump", "Jump", GAME_INPUT_SPIKEOUT, "NONE");
|
||||
shift = AddSwitchInput("Shift", "Shift", Game::INPUT_SPIKEOUT, "NONE");
|
||||
beat = AddSwitchInput("Beat", "Beat", Game::INPUT_SPIKEOUT, "NONE");
|
||||
charge = AddSwitchInput("Charge", "Charge",Game::INPUT_SPIKEOUT, "NONE");
|
||||
jump = AddSwitchInput("Jump", "Jump", Game::INPUT_SPIKEOUT, "NONE");
|
||||
|
||||
// Virtua Striker Buttons
|
||||
shortPass[0] = AddSwitchInput("ShortPass", "P1 Short Pass", GAME_INPUT_SOCCER, "NONE");
|
||||
longPass[0] = AddSwitchInput("LongPass", "P1 Long Pass", GAME_INPUT_SOCCER, "NONE");
|
||||
shoot[0] = AddSwitchInput("Shoot", "P1 Shoot", GAME_INPUT_SOCCER, "NONE");
|
||||
shortPass[1] = AddSwitchInput("ShortPass2", "P2 Short Pass", GAME_INPUT_SOCCER, "NONE");
|
||||
longPass[1] = AddSwitchInput("LongPass2", "P2 Long Pass", GAME_INPUT_SOCCER, "NONE");
|
||||
shoot[1] = AddSwitchInput("Shoot2", "P2 Shoot", GAME_INPUT_SOCCER, "NONE");
|
||||
shortPass[0] = AddSwitchInput("ShortPass", "P1 Short Pass", Game::INPUT_SOCCER, "NONE");
|
||||
longPass[0] = AddSwitchInput("LongPass", "P1 Long Pass", Game::INPUT_SOCCER, "NONE");
|
||||
shoot[0] = AddSwitchInput("Shoot", "P1 Shoot", Game::INPUT_SOCCER, "NONE");
|
||||
shortPass[1] = AddSwitchInput("ShortPass2", "P2 Short Pass", Game::INPUT_SOCCER, "NONE");
|
||||
longPass[1] = AddSwitchInput("LongPass2", "P2 Long Pass", Game::INPUT_SOCCER, "NONE");
|
||||
shoot[1] = AddSwitchInput("Shoot2", "P2 Shoot", Game::INPUT_SOCCER, "NONE");
|
||||
|
||||
// Racing Game Steering Controls
|
||||
CAnalogInput *steeringLeft = AddAnalogInput("SteeringLeft", "Steer Left", GAME_INPUT_VEHICLE, "NONE");
|
||||
CAnalogInput *steeringRight = AddAnalogInput("SteeringRight", "Steer Right", GAME_INPUT_VEHICLE, "NONE");
|
||||
CAnalogInput *steeringLeft = AddAnalogInput("SteeringLeft", "Steer Left", Game::INPUT_VEHICLE, "NONE");
|
||||
CAnalogInput *steeringRight = AddAnalogInput("SteeringRight", "Steer Right", Game::INPUT_VEHICLE, "NONE");
|
||||
|
||||
steering = AddAxisInput ("Steering", "Full Steering", GAME_INPUT_VEHICLE, "NONE", steeringLeft, steeringRight);
|
||||
accelerator = AddAnalogInput("Accelerator", "Accelerator Pedal", GAME_INPUT_VEHICLE, "NONE");
|
||||
brake = AddAnalogInput("Brake", "Brake Pedal/Front Brake", GAME_INPUT_VEHICLE, "NONE");
|
||||
gearShiftUp = AddSwitchInput("GearShiftUp", "Shift Up", GAME_INPUT_VEHICLE, "NONE");
|
||||
gearShiftDown = AddSwitchInput("GearShiftDown", "Shift Down", GAME_INPUT_VEHICLE, "NONE");
|
||||
steering = AddAxisInput ("Steering", "Full Steering", Game::INPUT_VEHICLE, "NONE", steeringLeft, steeringRight);
|
||||
accelerator = AddAnalogInput("Accelerator", "Accelerator Pedal", Game::INPUT_VEHICLE, "NONE");
|
||||
brake = AddAnalogInput("Brake", "Brake Pedal/Front Brake", Game::INPUT_VEHICLE, "NONE");
|
||||
gearShiftUp = AddSwitchInput("GearShiftUp", "Shift Up", Game::INPUT_VEHICLE, "NONE");
|
||||
gearShiftDown = AddSwitchInput("GearShiftDown", "Shift Down", Game::INPUT_VEHICLE, "NONE");
|
||||
|
||||
// Racing Game Gear Shift
|
||||
CSwitchInput *shift1 = AddSwitchInput("GearShift1", "Shift 1", GAME_INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift2 = AddSwitchInput("GearShift2", "Shift 2", GAME_INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift3 = AddSwitchInput("GearShift3", "Shift 3", GAME_INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift4 = AddSwitchInput("GearShift4", "Shift 4", GAME_INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shiftN = AddSwitchInput("GearShiftN", "Shift Neutral", GAME_INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift1 = AddSwitchInput("GearShift1", "Shift 1", Game::INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift2 = AddSwitchInput("GearShift2", "Shift 2", Game::INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift3 = AddSwitchInput("GearShift3", "Shift 3", Game::INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shift4 = AddSwitchInput("GearShift4", "Shift 4", Game::INPUT_SHIFT4, "NONE");
|
||||
CSwitchInput *shiftN = AddSwitchInput("GearShiftN", "Shift Neutral", Game::INPUT_SHIFT4, "NONE");
|
||||
|
||||
gearShift4 = AddGearShift4Input("GearShift", "Gear Shift", GAME_INPUT_SHIFT4, shift1, shift2, shift3, shift4, shiftN, gearShiftUp, gearShiftDown);
|
||||
gearShift4 = AddGearShift4Input("GearShift", "Gear Shift", Game::INPUT_SHIFT4, shift1, shift2, shift3, shift4, shiftN, gearShiftUp, gearShiftDown);
|
||||
|
||||
// Racing Game 4 VR View Buttons
|
||||
vr[0] = AddSwitchInput("VR1", "VR1", GAME_INPUT_VR4, "NONE");
|
||||
vr[1] = AddSwitchInput("VR2", "VR2", GAME_INPUT_VR4, "NONE");
|
||||
vr[2] = AddSwitchInput("VR3", "VR3", GAME_INPUT_VR4, "NONE");
|
||||
vr[3] = AddSwitchInput("VR4", "VR4", GAME_INPUT_VR4, "NONE");
|
||||
vr[0] = AddSwitchInput("VR1", "VR1", Game::INPUT_VR4, "NONE");
|
||||
vr[1] = AddSwitchInput("VR2", "VR2", Game::INPUT_VR4, "NONE");
|
||||
vr[2] = AddSwitchInput("VR3", "VR3", Game::INPUT_VR4, "NONE");
|
||||
vr[3] = AddSwitchInput("VR4", "VR4", Game::INPUT_VR4, "NONE");
|
||||
|
||||
// Racing Game Single View Change Button
|
||||
viewChange = AddSwitchInput("ViewChange", "View Change", GAME_INPUT_VIEWCHANGE, "NONE");
|
||||
viewChange = AddSwitchInput("ViewChange", "View Change", Game::INPUT_VIEWCHANGE, "NONE");
|
||||
|
||||
// Racing Game Handbrake
|
||||
handBrake = AddSwitchInput("HandBrake", "Hand Brake", GAME_INPUT_HANDBRAKE, "NONE");
|
||||
handBrake = AddSwitchInput("HandBrake", "Hand Brake", Game::INPUT_HANDBRAKE, "NONE");
|
||||
|
||||
// Harley Davidson Controls
|
||||
rearBrake = AddAnalogInput("RearBrake", "Rear Brake", GAME_INPUT_HARLEY, "NONE");
|
||||
musicSelect = AddSwitchInput("MusicSelect", "Music Selection", GAME_INPUT_HARLEY, "NONE");
|
||||
rearBrake = AddAnalogInput("RearBrake", "Rear Brake", Game::INPUT_HARLEY, "NONE");
|
||||
musicSelect = AddSwitchInput("MusicSelect", "Music Selection", Game::INPUT_HARLEY, "NONE");
|
||||
|
||||
// Virtual On Controls
|
||||
twinJoyTurnLeft = AddSwitchInput("TwinJoyTurnLeft", "Macro Turn Left", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurnRight = AddSwitchInput("TwinJoyTurnRight", "Macro Turn Right", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyForward = AddSwitchInput("TwinJoyForward", "Macro Forward", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyReverse = AddSwitchInput("TwinJoyReverse", "Macro Reverse", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyStrafeLeft = AddSwitchInput("TwinJoyStrafeLeft", "Macro Strafe Left", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyStrafeRight = AddSwitchInput("TwinJoyStrafeRight", "Macro Strafe Right", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyJump = AddSwitchInput("TwinJoyJump", "Macro Jump", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyCrouch = AddSwitchInput("TwinJoyCrouch", "Macro Crouch", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyLeft1 = AddSwitchInput("TwinJoyLeft1", "Left Joystick Left", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyLeft2 = AddSwitchInput("TwinJoyLeft2", "Right Joystick Left", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyRight1 = AddSwitchInput("TwinJoyRight1", "Left Joystick Right", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyRight2 = AddSwitchInput("TwinJoyRight2", "Right Joystick Right", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyUp1 = AddSwitchInput("TwinJoyUp1", "Left Joystick Up", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyUp2 = AddSwitchInput("TwinJoyUp2", "Right Joystick Up", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyDown1 = AddSwitchInput("TwinJoyDown1", "Left Joystick Down", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyDown2 = AddSwitchInput("TwinJoyDown2", "Right Joystick Down", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyShot1 = AddSwitchInput("TwinJoyShot1", "Left Shot Trigger", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyShot2 = AddSwitchInput("TwinJoyShot2", "Right Shot Trigger", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurbo1 = AddSwitchInput("TwinJoyTurbo1", "Left Turbo", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurbo2 = AddSwitchInput("TwinJoyTurbo2", "Right Turbo", GAME_INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurnLeft = AddSwitchInput("TwinJoyTurnLeft", "Macro Turn Left", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurnRight = AddSwitchInput("TwinJoyTurnRight", "Macro Turn Right", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyForward = AddSwitchInput("TwinJoyForward", "Macro Forward", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyReverse = AddSwitchInput("TwinJoyReverse", "Macro Reverse", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyStrafeLeft = AddSwitchInput("TwinJoyStrafeLeft", "Macro Strafe Left", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyStrafeRight = AddSwitchInput("TwinJoyStrafeRight", "Macro Strafe Right", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyJump = AddSwitchInput("TwinJoyJump", "Macro Jump", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyCrouch = AddSwitchInput("TwinJoyCrouch", "Macro Crouch", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyLeft1 = AddSwitchInput("TwinJoyLeft1", "Left Joystick Left", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyLeft2 = AddSwitchInput("TwinJoyLeft2", "Right Joystick Left", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyRight1 = AddSwitchInput("TwinJoyRight1", "Left Joystick Right", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyRight2 = AddSwitchInput("TwinJoyRight2", "Right Joystick Right", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyUp1 = AddSwitchInput("TwinJoyUp1", "Left Joystick Up", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyUp2 = AddSwitchInput("TwinJoyUp2", "Right Joystick Up", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyDown1 = AddSwitchInput("TwinJoyDown1", "Left Joystick Down", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyDown2 = AddSwitchInput("TwinJoyDown2", "Right Joystick Down", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyShot1 = AddSwitchInput("TwinJoyShot1", "Left Shot Trigger", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyShot2 = AddSwitchInput("TwinJoyShot2", "Right Shot Trigger", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurbo1 = AddSwitchInput("TwinJoyTurbo1", "Left Turbo", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
twinJoyTurbo2 = AddSwitchInput("TwinJoyTurbo2", "Right Turbo", Game::INPUT_TWIN_JOYSTICKS, "NONE");
|
||||
|
||||
// Analog Joystick
|
||||
CAnalogInput *analogJoyLeft = AddAnalogInput("AnalogJoyLeft", "Analog Left", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyRight = AddAnalogInput("AnalogJoyRight", "Analog Right", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyUp = AddAnalogInput("AnalogJoyUp", "Analog Up", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyDown = AddAnalogInput("AnalogJoyDown", "Analog Down", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyLeft = AddAnalogInput("AnalogJoyLeft", "Analog Left", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyRight = AddAnalogInput("AnalogJoyRight", "Analog Right", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyUp = AddAnalogInput("AnalogJoyUp", "Analog Up", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
CAnalogInput *analogJoyDown = AddAnalogInput("AnalogJoyDown", "Analog Down", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
|
||||
analogJoyX = AddAxisInput ("AnalogJoyX", "Analog X-Axis", GAME_INPUT_ANALOG_JOYSTICK, "NONE", analogJoyLeft, analogJoyRight);
|
||||
analogJoyY = AddAxisInput ("AnalogJoyY", "Analog Y-Axis", GAME_INPUT_ANALOG_JOYSTICK, "NONE", analogJoyUp, analogJoyDown);
|
||||
analogJoyTrigger1 = AddSwitchInput("AnalogJoyTrigger", "Trigger Button 1", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyTrigger2 = AddSwitchInput("AnalogJoyTrigger2", "Trigger Button 2", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyEvent1 = AddSwitchInput("AnalogJoyEvent", "Event Button 1", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyEvent2 = AddSwitchInput("AnalogJoyEvent2", "Event Button 2", GAME_INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyX = AddAxisInput ("AnalogJoyX", "Analog X-Axis", Game::INPUT_ANALOG_JOYSTICK, "NONE", analogJoyLeft, analogJoyRight);
|
||||
analogJoyY = AddAxisInput ("AnalogJoyY", "Analog Y-Axis", Game::INPUT_ANALOG_JOYSTICK, "NONE", analogJoyUp, analogJoyDown);
|
||||
analogJoyTrigger1 = AddSwitchInput("AnalogJoyTrigger", "Trigger Button 1", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyTrigger2 = AddSwitchInput("AnalogJoyTrigger2", "Trigger Button 2", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyEvent1 = AddSwitchInput("AnalogJoyEvent", "Event Button 1", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
analogJoyEvent2 = AddSwitchInput("AnalogJoyEvent2", "Event Button 2", Game::INPUT_ANALOG_JOYSTICK, "NONE");
|
||||
|
||||
// Light guns
|
||||
CAnalogInput *gun1Left = AddAnalogInput("GunLeft", "P1 Gun Left", GAME_INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Right = AddAnalogInput("GunRight", "P1 Gun Right", GAME_INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Up = AddAnalogInput("GunUp", "P1 Gun Up", GAME_INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Down = AddAnalogInput("GunDown", "P1 Gun Down", GAME_INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Left = AddAnalogInput("GunLeft", "P1 Gun Left", Game::INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Right = AddAnalogInput("GunRight", "P1 Gun Right", Game::INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Up = AddAnalogInput("GunUp", "P1 Gun Up", Game::INPUT_GUN1, "NONE");
|
||||
CAnalogInput *gun1Down = AddAnalogInput("GunDown", "P1 Gun Down", Game::INPUT_GUN1, "NONE");
|
||||
|
||||
gunX[0] = AddAxisInput("GunX", "P1 Gun X-Axis", GAME_INPUT_GUN1, "NONE", gun1Left, gun1Right, 150, 400, 651); // normalize to [150,651]
|
||||
gunY[0] = AddAxisInput("GunY", "P1 Gun Y-Axis", GAME_INPUT_GUN1, "NONE", gun1Up, gun1Down, 80, 272, 465); // normalize to [80,465]
|
||||
gunX[0] = AddAxisInput("GunX", "P1 Gun X-Axis", Game::INPUT_GUN1, "NONE", gun1Left, gun1Right, 150, 400, 651); // normalize to [150,651]
|
||||
gunY[0] = AddAxisInput("GunY", "P1 Gun Y-Axis", Game::INPUT_GUN1, "NONE", gun1Up, gun1Down, 80, 272, 465); // normalize to [80,465]
|
||||
|
||||
CSwitchInput *gun1Trigger = AddSwitchInput("Trigger", "P1 Trigger", GAME_INPUT_GUN1, "NONE");
|
||||
CSwitchInput *gun1Offscreen = AddSwitchInput("Offscreen", "P1 Point Off-screen", GAME_INPUT_GUN1, "NONE");
|
||||
CSwitchInput *gun1Trigger = AddSwitchInput("Trigger", "P1 Trigger", Game::INPUT_GUN1, "NONE");
|
||||
CSwitchInput *gun1Offscreen = AddSwitchInput("Offscreen", "P1 Point Off-screen", Game::INPUT_GUN1, "NONE");
|
||||
|
||||
trigger[0] = AddTriggerInput("AutoTrigger", "P1 Auto Trigger", GAME_INPUT_GUN1, gun1Trigger, gun1Offscreen);
|
||||
trigger[0] = AddTriggerInput("AutoTrigger", "P1 Auto Trigger", Game::INPUT_GUN1, gun1Trigger, gun1Offscreen);
|
||||
|
||||
CAnalogInput *gun2Left = AddAnalogInput("GunLeft2", "P2 Gun Left", GAME_INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Right = AddAnalogInput("GunRight2", "P2 Gun Right", GAME_INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Up = AddAnalogInput("GunUp2", "P2 Gun Up", GAME_INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Down = AddAnalogInput("GunDown2", "P2 Gun Down", GAME_INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Left = AddAnalogInput("GunLeft2", "P2 Gun Left", Game::INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Right = AddAnalogInput("GunRight2", "P2 Gun Right", Game::INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Up = AddAnalogInput("GunUp2", "P2 Gun Up", Game::INPUT_GUN2, "NONE");
|
||||
CAnalogInput *gun2Down = AddAnalogInput("GunDown2", "P2 Gun Down", Game::INPUT_GUN2, "NONE");
|
||||
|
||||
gunX[1] = AddAxisInput("GunX2", "P2 Gun X-Axis", GAME_INPUT_GUN2, "NONE", gun2Left, gun2Right, 150, 400, 651); // normalize to [150,651]
|
||||
gunY[1] = AddAxisInput("GunY2", "P2 Gun Y-Axis", GAME_INPUT_GUN2, "NONE", gun2Up, gun2Down, 80, 272, 465); // normalize to [80,465]
|
||||
gunX[1] = AddAxisInput("GunX2", "P2 Gun X-Axis", Game::INPUT_GUN2, "NONE", gun2Left, gun2Right, 150, 400, 651); // normalize to [150,651]
|
||||
gunY[1] = AddAxisInput("GunY2", "P2 Gun Y-Axis", Game::INPUT_GUN2, "NONE", gun2Up, gun2Down, 80, 272, 465); // normalize to [80,465]
|
||||
|
||||
CSwitchInput *gun2Trigger = AddSwitchInput("Trigger2", "P2 Trigger", GAME_INPUT_GUN2, "NONE");
|
||||
CSwitchInput *gun2Offscreen = AddSwitchInput("Offscreen2", "P2 Point Off-screen", GAME_INPUT_GUN2, "NONE");
|
||||
CSwitchInput *gun2Trigger = AddSwitchInput("Trigger2", "P2 Trigger", Game::INPUT_GUN2, "NONE");
|
||||
CSwitchInput *gun2Offscreen = AddSwitchInput("Offscreen2", "P2 Point Off-screen", Game::INPUT_GUN2, "NONE");
|
||||
|
||||
trigger[1] = AddTriggerInput("AutoTrigger2", "P2 Auto Trigger", GAME_INPUT_GUN2, gun2Trigger, gun2Offscreen);
|
||||
trigger[1] = AddTriggerInput("AutoTrigger2", "P2 Auto Trigger", Game::INPUT_GUN2, gun2Trigger, gun2Offscreen);
|
||||
|
||||
// Analog guns
|
||||
CAnalogInput *analogGun1Left = AddAnalogInput("AnalogGunLeft", "P1 Analog Gun Left", GAME_INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Right = AddAnalogInput("AnalogGunRight", "P1 Analog Gun Right", GAME_INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Up = AddAnalogInput("AnalogGunUp", "P1 Analog Gun Up", GAME_INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Down = AddAnalogInput("AnalogGunDown", "P1 Analog Gun Down", GAME_INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Left = AddAnalogInput("AnalogGunLeft", "P1 Analog Gun Left", Game::INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Right = AddAnalogInput("AnalogGunRight", "P1 Analog Gun Right", Game::INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Up = AddAnalogInput("AnalogGunUp", "P1 Analog Gun Up", Game::INPUT_ANALOG_GUN1, "NONE");
|
||||
CAnalogInput *analogGun1Down = AddAnalogInput("AnalogGunDown", "P1 Analog Gun Down", Game::INPUT_ANALOG_GUN1, "NONE");
|
||||
|
||||
analogGunX[0] = AddAxisInput("AnalogGunX", "P1 Analog Gun X-Axis", GAME_INPUT_ANALOG_GUN1, "NONE", analogGun1Left, analogGun1Right, 0, 0x80, 0xFF);
|
||||
analogGunY[0] = AddAxisInput("AnalogGunY", "P1 Analog Gun Y-Axis", GAME_INPUT_ANALOG_GUN1, "NONE", analogGun1Up, analogGun1Down, 0xFF, 0x80, 0);
|
||||
analogGunX[0] = AddAxisInput("AnalogGunX", "P1 Analog Gun X-Axis", Game::INPUT_ANALOG_GUN1, "NONE", analogGun1Left, analogGun1Right, 0, 0x80, 0xFF);
|
||||
analogGunY[0] = AddAxisInput("AnalogGunY", "P1 Analog Gun Y-Axis", Game::INPUT_ANALOG_GUN1, "NONE", analogGun1Up, analogGun1Down, 0xFF, 0x80, 0);
|
||||
|
||||
analogTriggerLeft[0] = AddSwitchInput("AnalogTriggerLeft", "P1 Analog Gun Left Trigger", GAME_INPUT_ANALOG_GUN1, "NONE");
|
||||
analogTriggerRight[0] = AddSwitchInput("AnalogTriggerRight", "P1 Analog Gun Right Trigger", GAME_INPUT_ANALOG_GUN1, "NONE");
|
||||
analogTriggerLeft[0] = AddSwitchInput("AnalogTriggerLeft", "P1 Analog Gun Left Trigger", Game::INPUT_ANALOG_GUN1, "NONE");
|
||||
analogTriggerRight[0] = AddSwitchInput("AnalogTriggerRight", "P1 Analog Gun Right Trigger", Game::INPUT_ANALOG_GUN1, "NONE");
|
||||
|
||||
CAnalogInput *analogGun2Left = AddAnalogInput("AnalogGunLeft2", "P2 Analog Gun Left", GAME_INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Right = AddAnalogInput("AnalogGunRight2", "P2 Analog Gun Right", GAME_INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Up = AddAnalogInput("AnalogGunUp2", "P2 Analog Gun Up", GAME_INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Down = AddAnalogInput("AnalogGunDown2", "P2 Analog Gun Down", GAME_INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Left = AddAnalogInput("AnalogGunLeft2", "P2 Analog Gun Left", Game::INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Right = AddAnalogInput("AnalogGunRight2", "P2 Analog Gun Right", Game::INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Up = AddAnalogInput("AnalogGunUp2", "P2 Analog Gun Up", Game::INPUT_ANALOG_GUN2, "NONE");
|
||||
CAnalogInput *analogGun2Down = AddAnalogInput("AnalogGunDown2", "P2 Analog Gun Down", Game::INPUT_ANALOG_GUN2, "NONE");
|
||||
|
||||
analogGunX[1] = AddAxisInput("AnalogGunX2", "P2 Analog Gun X-Axis", GAME_INPUT_ANALOG_GUN2, "NONE", analogGun2Left, analogGun2Right, 0, 0x80, 0xFF);
|
||||
analogGunY[1] = AddAxisInput("AnalogGunY2", "P2 Analog Gun Y-Axis", GAME_INPUT_ANALOG_GUN2, "NONE", analogGun2Up, analogGun2Down, 0xFF, 0x80, 0);
|
||||
analogGunX[1] = AddAxisInput("AnalogGunX2", "P2 Analog Gun X-Axis", Game::INPUT_ANALOG_GUN2, "NONE", analogGun2Left, analogGun2Right, 0, 0x80, 0xFF);
|
||||
analogGunY[1] = AddAxisInput("AnalogGunY2", "P2 Analog Gun Y-Axis", Game::INPUT_ANALOG_GUN2, "NONE", analogGun2Up, analogGun2Down, 0xFF, 0x80, 0);
|
||||
|
||||
analogTriggerLeft[1] = AddSwitchInput("AnalogTriggerLeft2", "P2 Analog Gun Left Trigger", GAME_INPUT_ANALOG_GUN2, "NONE");
|
||||
analogTriggerRight[1] = AddSwitchInput("AnalogTriggerRight2", "P2 Analog Gun Right Trigger", GAME_INPUT_ANALOG_GUN2, "NONE");
|
||||
analogTriggerLeft[1] = AddSwitchInput("AnalogTriggerLeft2", "P2 Analog Gun Left Trigger", Game::INPUT_ANALOG_GUN2, "NONE");
|
||||
analogTriggerRight[1] = AddSwitchInput("AnalogTriggerRight2", "P2 Analog Gun Right Trigger", Game::INPUT_ANALOG_GUN2, "NONE");
|
||||
|
||||
// Ski controls
|
||||
CAnalogInput *skiLeft = AddAnalogInput("SkiLeft", "Ski Champ Left", GAME_INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiRight = AddAnalogInput("SkiRight", "Ski Champ Right", GAME_INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiUp = AddAnalogInput("SkiUp", "Ski Champ Up", GAME_INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiDown = AddAnalogInput("SkiDown", "Ski Champ Down", GAME_INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiLeft = AddAnalogInput("SkiLeft", "Ski Champ Left", Game::INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiRight = AddAnalogInput("SkiRight", "Ski Champ Right", Game::INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiUp = AddAnalogInput("SkiUp", "Ski Champ Up", Game::INPUT_SKI, "NONE");
|
||||
CAnalogInput *skiDown = AddAnalogInput("SkiDown", "Ski Champ Down", Game::INPUT_SKI, "NONE");
|
||||
|
||||
skiX = AddAxisInput ("SkiX", "Ski Champ X-Axis", GAME_INPUT_SKI, "NONE", skiLeft, skiRight, 0xFF, 0x80, 0);
|
||||
skiY = AddAxisInput ("SkiY", "Ski Champ Y-Axis", GAME_INPUT_SKI, "NONE", skiUp, skiDown);
|
||||
skiPollLeft = AddSwitchInput("SkiPollLeft", "Ski Champ Poll Left", GAME_INPUT_SKI, "NONE");
|
||||
skiPollRight = AddSwitchInput("SkiPollRight", "Ski Champ Poll Right", GAME_INPUT_SKI, "NONE");
|
||||
skiSelect1 = AddSwitchInput("SkiSelect1", "Ski Champ Select 1", GAME_INPUT_SKI, "NONE");
|
||||
skiSelect2 = AddSwitchInput("SkiSelect2", "Ski Champ Select 2", GAME_INPUT_SKI, "NONE");
|
||||
skiSelect3 = AddSwitchInput("SkiSelect3", "Ski Champ Select 3", GAME_INPUT_SKI, "NONE");
|
||||
skiX = AddAxisInput ("SkiX", "Ski Champ X-Axis", Game::INPUT_SKI, "NONE", skiLeft, skiRight, 0xFF, 0x80, 0);
|
||||
skiY = AddAxisInput ("SkiY", "Ski Champ Y-Axis", Game::INPUT_SKI, "NONE", skiUp, skiDown);
|
||||
skiPollLeft = AddSwitchInput("SkiPollLeft", "Ski Champ Poll Left", Game::INPUT_SKI, "NONE");
|
||||
skiPollRight = AddSwitchInput("SkiPollRight", "Ski Champ Poll Right", Game::INPUT_SKI, "NONE");
|
||||
skiSelect1 = AddSwitchInput("SkiSelect1", "Ski Champ Select 1", Game::INPUT_SKI, "NONE");
|
||||
skiSelect2 = AddSwitchInput("SkiSelect2", "Ski Champ Select 2", Game::INPUT_SKI, "NONE");
|
||||
skiSelect3 = AddSwitchInput("SkiSelect3", "Ski Champ Select 3", Game::INPUT_SKI, "NONE");
|
||||
|
||||
// Magical truck controls
|
||||
CAnalogInput *magicalLeverUp1 = AddAnalogInput("MagicalLeverUp1", "P1 Magical Lever Up", GAME_INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverDown1 = AddAnalogInput("MagicalLeverDown1", "P1 Magical Lever Down", GAME_INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverUp2 = AddAnalogInput("MagicalLeverUp2", "P2 Magical Lever Up", GAME_INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverDown2 = AddAnalogInput("MagicalLeverDown2", "P2 Magical Lever Down", GAME_INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverUp1 = AddAnalogInput("MagicalLeverUp1", "P1 Magical Lever Up", Game::INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverDown1 = AddAnalogInput("MagicalLeverDown1", "P1 Magical Lever Down", Game::INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverUp2 = AddAnalogInput("MagicalLeverUp2", "P2 Magical Lever Up", Game::INPUT_MAGTRUCK, "NONE");
|
||||
CAnalogInput *magicalLeverDown2 = AddAnalogInput("MagicalLeverDown2", "P2 Magical Lever Down", Game::INPUT_MAGTRUCK, "NONE");
|
||||
|
||||
magicalLever1 = AddAxisInput( "MagicalLever1", "P1 Magical Lever", GAME_INPUT_MAGTRUCK, "NONE", magicalLeverUp1, magicalLeverDown1, 0xFF, 0x80, 0);
|
||||
magicalLever2 = AddAxisInput( "MagicalLever2", "P2 Magical Lever", GAME_INPUT_MAGTRUCK, "NONE", magicalLeverUp2, magicalLeverDown2, 0xFF, 0x80, 0);
|
||||
magicalPedal1 = AddSwitchInput( "MagicalPedal1", "P1 Magical Pedal", GAME_INPUT_MAGTRUCK, "NONE");
|
||||
magicalPedal2 = AddSwitchInput( "MagicalPedal2", "P2 Magical Pedal", GAME_INPUT_MAGTRUCK, "NONE");
|
||||
magicalLever1 = AddAxisInput( "MagicalLever1", "P1 Magical Lever", Game::INPUT_MAGTRUCK, "NONE", magicalLeverUp1, magicalLeverDown1, 0xFF, 0x80, 0);
|
||||
magicalLever2 = AddAxisInput( "MagicalLever2", "P2 Magical Lever", Game::INPUT_MAGTRUCK, "NONE", magicalLeverUp2, magicalLeverDown2, 0xFF, 0x80, 0);
|
||||
magicalPedal1 = AddSwitchInput( "MagicalPedal1", "P1 Magical Pedal", Game::INPUT_MAGTRUCK, "NONE");
|
||||
magicalPedal2 = AddSwitchInput( "MagicalPedal2", "P2 Magical Pedal", Game::INPUT_MAGTRUCK, "NONE");
|
||||
|
||||
// Sega Bass Fishing controls
|
||||
CAnalogInput *fishingRodLeft = AddAnalogInput("FishingRodLeft", "Rod Left", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodRight = AddAnalogInput("FishingRodRight", "Rod Right", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodUp = AddAnalogInput("FishingRodUp", "Rod Up", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodDown = AddAnalogInput("FishingRodDown", "Rod Down", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingReelFaster = AddAnalogInput("FishingReelFaster", "Reel Faster", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingReelSlower = AddAnalogInput("FishingReelSlower", "Reel Slower", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickLeft = AddAnalogInput("FishingStickLeft", "Stick Left", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickRight = AddAnalogInput("FishingStickRight", "Stick Right", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickUp = AddAnalogInput("FishingStickUp", "Stick Up", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickDown = AddAnalogInput("FishingStickDown", "Stick Down", GAME_INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodLeft = AddAnalogInput("FishingRodLeft", "Rod Left", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodRight = AddAnalogInput("FishingRodRight", "Rod Right", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodUp = AddAnalogInput("FishingRodUp", "Rod Up", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingRodDown = AddAnalogInput("FishingRodDown", "Rod Down", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingReelFaster = AddAnalogInput("FishingReelFaster", "Reel Faster", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingReelSlower = AddAnalogInput("FishingReelSlower", "Reel Slower", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickLeft = AddAnalogInput("FishingStickLeft", "Stick Left", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickRight = AddAnalogInput("FishingStickRight", "Stick Right", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickUp = AddAnalogInput("FishingStickUp", "Stick Up", Game::INPUT_FISHING, "NONE");
|
||||
CAnalogInput *fishingStickDown = AddAnalogInput("FishingStickDown", "Stick Down", Game::INPUT_FISHING, "NONE");
|
||||
|
||||
fishingRodX = AddAxisInput( "FishingRodX", "Rod X-Axis", GAME_INPUT_FISHING, "NONE", fishingRodLeft, fishingRodRight, 0, 0x80, 0xFF);
|
||||
fishingRodY = AddAxisInput( "FishingRodY", "Rod Y-Axis", GAME_INPUT_FISHING, "NONE", fishingRodUp, fishingRodDown, 0xFF, 0x80, 0);
|
||||
fishingReel = AddAxisInput( "FishingReel", "Reel Speed", GAME_INPUT_FISHING, "NONE", fishingReelSlower, fishingReelFaster, 0, 0x80, 0xFF);
|
||||
fishingStickX = AddAxisInput( "FishingStickX", "Stick X-Axis", GAME_INPUT_FISHING, "NONE", fishingStickLeft, fishingStickRight, 0, 0x80, 0xFF);
|
||||
fishingStickY = AddAxisInput( "FishingStickY", "Stick Y-Axis", GAME_INPUT_FISHING, "NONE", fishingStickUp, fishingStickDown, 0xFF, 0x80, 0);
|
||||
fishingCast = AddSwitchInput( "FishingCast", "Cast", GAME_INPUT_FISHING, "NONE");
|
||||
fishingSelect = AddSwitchInput( "FishingSelect", "Select", GAME_INPUT_FISHING, "NONE");
|
||||
fishingRodX = AddAxisInput( "FishingRodX", "Rod X-Axis", Game::INPUT_FISHING, "NONE", fishingRodLeft, fishingRodRight, 0, 0x80, 0xFF);
|
||||
fishingRodY = AddAxisInput( "FishingRodY", "Rod Y-Axis", Game::INPUT_FISHING, "NONE", fishingRodUp, fishingRodDown, 0xFF, 0x80, 0);
|
||||
fishingReel = AddAxisInput( "FishingReel", "Reel Speed", Game::INPUT_FISHING, "NONE", fishingReelSlower, fishingReelFaster, 0, 0x80, 0xFF);
|
||||
fishingStickX = AddAxisInput( "FishingStickX", "Stick X-Axis", Game::INPUT_FISHING, "NONE", fishingStickLeft, fishingStickRight, 0, 0x80, 0xFF);
|
||||
fishingStickY = AddAxisInput( "FishingStickY", "Stick Y-Axis", Game::INPUT_FISHING, "NONE", fishingStickUp, fishingStickDown, 0xFF, 0x80, 0);
|
||||
fishingCast = AddSwitchInput( "FishingCast", "Cast", Game::INPUT_FISHING, "NONE");
|
||||
fishingSelect = AddSwitchInput( "FishingSelect", "Select", Game::INPUT_FISHING, "NONE");
|
||||
}
|
||||
|
||||
CInputs::~CInputs()
|
||||
|
@ -399,9 +401,26 @@ bool CInputs::Initialize()
|
|||
// Initialize all the inputs
|
||||
for (vector<CInput*>::iterator it = m_inputs.begin(); it != m_inputs.end(); it++)
|
||||
(*it)->Initialize(m_system);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInputs::LoadFromConfig(const Util::Config::Node &config)
|
||||
{
|
||||
m_system->LoadFromConfig(config);
|
||||
|
||||
for (vector<CInput*>::iterator it = m_inputs.begin(); it != m_inputs.end(); it++)
|
||||
(*it)->LoadFromConfig(config);
|
||||
}
|
||||
|
||||
void CInputs::StoreToConfig(Util::Config::Node *config)
|
||||
{
|
||||
m_system->StoreToConfig(config);
|
||||
|
||||
for (vector<CInput*>::iterator it = m_inputs.begin(); it != m_inputs.end(); it++)
|
||||
(*it)->StoreToConfig(config);
|
||||
}
|
||||
|
||||
void CInputs::ReadFromINIFile(CINIFile *ini, const char *section)
|
||||
{
|
||||
m_system->ReadFromINIFile(ini, section);
|
||||
|
@ -418,21 +437,21 @@ void CInputs::WriteToINIFile(CINIFile *ini, const char *section)
|
|||
(*it)->WriteToINIFile(ini, section);
|
||||
}
|
||||
|
||||
bool CInputs::ConfigureInputs(const GameInfo *game)
|
||||
bool CInputs::ConfigureInputs(const Game *game)
|
||||
{
|
||||
m_system->UngrabMouse();
|
||||
|
||||
// Print header and help message
|
||||
int gameFlags;
|
||||
if (game != NULL)
|
||||
uint32_t gameFlags;
|
||||
if (game)
|
||||
{
|
||||
PrintHeader("Configure Inputs for %s", game->title);
|
||||
gameFlags = game->inputFlags;
|
||||
PrintHeader("Configure Inputs for %s", game->title.c_str());
|
||||
gameFlags = game->inputs;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintHeader("Configure Inputs");
|
||||
gameFlags = GAME_INPUT_ALL;
|
||||
gameFlags = Game::INPUT_ALL;
|
||||
}
|
||||
PrintConfigureInputsHelp();
|
||||
|
||||
|
@ -599,7 +618,7 @@ Finish:
|
|||
return !cancelled;
|
||||
}
|
||||
|
||||
bool CInputs::ConfigureInputs(const GameInfo *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH)
|
||||
bool CInputs::ConfigureInputs(const Game *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH)
|
||||
{
|
||||
// Let the input system know the display geometry
|
||||
m_system->SetDisplayGeom(dispX, dispY, dispW, dispH);
|
||||
|
@ -697,19 +716,19 @@ void CInputs::CalibrateJoystick(int joyNum)
|
|||
}
|
||||
}
|
||||
|
||||
void CInputs::PrintInputs(const GameInfo *game)
|
||||
void CInputs::PrintInputs(const Game *game)
|
||||
{
|
||||
// Print header
|
||||
int gameFlags;
|
||||
if (game != NULL)
|
||||
{
|
||||
PrintHeader("Input Assignments for %s", game->title);
|
||||
gameFlags = game->inputFlags;
|
||||
PrintHeader("Input Assignments for %s", game->title.c_str());
|
||||
gameFlags = game->inputs;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintHeader("Input Assignments");
|
||||
gameFlags = GAME_INPUT_ALL;
|
||||
gameFlags = Game::INPUT_ALL;
|
||||
}
|
||||
|
||||
const char *groupLabel = NULL;
|
||||
|
@ -731,7 +750,7 @@ void CInputs::PrintInputs(const GameInfo *game)
|
|||
puts("");
|
||||
}
|
||||
|
||||
bool CInputs::Poll(const GameInfo *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH)
|
||||
bool CInputs::Poll(const Game *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH)
|
||||
{
|
||||
// Update the input system with the current display geometry
|
||||
m_system->SetDisplayGeom(dispX, dispY, dispW, dispH);
|
||||
|
@ -741,7 +760,7 @@ bool CInputs::Poll(const GameInfo *game, unsigned dispX, unsigned dispY, unsigne
|
|||
return false;
|
||||
|
||||
// Poll all UI inputs and all the inputs used by the current game, or all inputs if game is NULL
|
||||
int gameFlags = (game != NULL ? game->inputFlags : GAME_INPUT_ALL);
|
||||
uint32_t gameFlags = game ? game->inputs : Game::INPUT_ALL;
|
||||
for (vector<CInput*>::iterator it = m_inputs.begin(); it != m_inputs.end(); it++)
|
||||
{
|
||||
if ((*it)->IsUIInput() || ((*it)->gameFlags & gameFlags))
|
||||
|
@ -750,19 +769,19 @@ bool CInputs::Poll(const GameInfo *game, unsigned dispX, unsigned dispY, unsigne
|
|||
return true;
|
||||
}
|
||||
|
||||
void CInputs::DumpState(const GameInfo *game)
|
||||
void CInputs::DumpState(const Game *game)
|
||||
{
|
||||
// Print header
|
||||
int gameFlags;
|
||||
if (game != NULL)
|
||||
{
|
||||
PrintHeader("Input States for %s", game->title);
|
||||
gameFlags = game->inputFlags;
|
||||
PrintHeader("Input States for %s", game->title.c_str());
|
||||
gameFlags = game->inputs;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintHeader("Input States");
|
||||
gameFlags = GAME_INPUT_ALL;
|
||||
gameFlags = Game::INPUT_ALL;
|
||||
}
|
||||
|
||||
// Loop through the inputs used by the current game, or all inputs if game is NULL, and dump their values to stdout
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define INCLUDED_INPUTS_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "Util/NewConfig.h"
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
@ -41,7 +42,7 @@ class CSwitchInput;
|
|||
class CGearShift4Input;
|
||||
class CTriggerInput;
|
||||
class CINIFile;
|
||||
struct GameInfo;
|
||||
struct Game;
|
||||
|
||||
/*
|
||||
* Represents the collection of Model3 inputs.
|
||||
|
@ -266,27 +267,29 @@ public:
|
|||
bool Initialize();
|
||||
|
||||
/*
|
||||
* Reads the input mapping assignments from the given INI file.
|
||||
* Loads the input mapping assignments from the given config object.
|
||||
*/
|
||||
void LoadFromConfig(const Util::Config::Node &config);
|
||||
void ReadFromINIFile(CINIFile *ini, const char *section);
|
||||
|
||||
/*
|
||||
* Writes the current input mapping assignments to the given INI file.
|
||||
* Stores the current input mapping assignments to the given config object.
|
||||
*/
|
||||
void StoreToConfig(Util::Config::Node *config);
|
||||
void WriteToINIFile(CINIFile *ini, const char *section);
|
||||
|
||||
/*
|
||||
* Configures the current input mapping assignments for the given game, or all inputs if game is NULL, by asking the user for input.
|
||||
* Returns true if the inputs were configured okay or false if the user exited without requesting to save changes.
|
||||
*/
|
||||
bool ConfigureInputs(const GameInfo *game);
|
||||
bool ConfigureInputs(const Game *game);
|
||||
|
||||
/*
|
||||
* Configures the current input mapping assignments for the given game, or all inputs if game is NULL, by asking the user for input.
|
||||
* Takes display geometry if this has not been set previously by a call to Poll().
|
||||
* Returns true if the inputs were configured okay or false if the user exited without requesting to save changes.
|
||||
*/
|
||||
bool ConfigureInputs(const GameInfo *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH);
|
||||
bool ConfigureInputs(const Game *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH);
|
||||
|
||||
void CalibrateJoysticks();
|
||||
|
||||
|
@ -295,18 +298,18 @@ public:
|
|||
/*
|
||||
* Prints to stdout the current input mapping assignments for the given game, or all inputs if game is NULL.
|
||||
*/
|
||||
void PrintInputs(const GameInfo *game);
|
||||
void PrintInputs(const Game *game);
|
||||
|
||||
/*
|
||||
* Polls (updates) the inputs for the given game, or all inputs if game is NULL, updating their values from their respective input sources.
|
||||
* First the input system is polled (CInputSystem.Poll()) and then each input is polled (CInput.Poll()).
|
||||
*/
|
||||
bool Poll(const GameInfo *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH);
|
||||
bool Poll(const Game *game, unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH);
|
||||
|
||||
/*
|
||||
* Prints the current values of the inputs for the given game, or all inputs if game is NULL, to stdout for debugging purposes.
|
||||
*/
|
||||
void DumpState(const GameInfo *game);
|
||||
void DumpState(const Game *game);
|
||||
};
|
||||
|
||||
#endif // INCLUDED_INPUTS_H
|
||||
|
|
|
@ -144,8 +144,8 @@ int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *i
|
|||
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 = m_config["MusicVolume"].ValueAs<int>();
|
||||
soundVol = m_config["SoundVolume"].ValueAs<int>();
|
||||
musicVol = (INT32) ((float) 0x100 * (float) musicVol / 100.0f);
|
||||
soundVol = (INT32) ((float) 0x100 * (float) soundVol / 100.0f);
|
||||
|
||||
|
@ -426,7 +426,7 @@ void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
|
|||
int cycles;
|
||||
UINT8 v;
|
||||
|
||||
if (!g_Config.emulateDSB)
|
||||
if (!m_config["EmulateDSB"].ValueAs<bool>())
|
||||
{
|
||||
// DSB code applies SCSP volume, too, so we must still mix
|
||||
memset(mpegL, 0, (32000/60+2)*sizeof(INT16));
|
||||
|
@ -603,7 +603,9 @@ CZ80 *CDSB1::GetZ80(void)
|
|||
return &Z80;
|
||||
}
|
||||
|
||||
CDSB1::CDSB1(void)
|
||||
CDSB1::CDSB1(const Util::Config::Node &config)
|
||||
: m_config(config),
|
||||
Resampler(config)
|
||||
{
|
||||
progROM = NULL;
|
||||
mpegROM = NULL;
|
||||
|
@ -981,7 +983,7 @@ void CDSB2::SendCommand(UINT8 data)
|
|||
|
||||
void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
|
||||
{
|
||||
if (!g_Config.emulateDSB)
|
||||
if (!m_config["EmulateDSB"].ValueAs<bool>())
|
||||
{
|
||||
// DSB code applies SCSP volume, too, so we must still mix
|
||||
memset(mpegL, 0, (32000/60+2)*sizeof(INT16));
|
||||
|
@ -1184,7 +1186,9 @@ M68KCtx *CDSB2::GetM68K(void)
|
|||
return &M68K;
|
||||
}
|
||||
|
||||
CDSB2::CDSB2(void)
|
||||
CDSB2::CDSB2(const Util::Config::Node &config)
|
||||
: m_config(config),
|
||||
Resampler(config)
|
||||
{
|
||||
progROM = NULL;
|
||||
mpegROM = NULL;
|
||||
|
|
|
@ -33,83 +33,7 @@
|
|||
|
||||
#include "Types.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(int vol)
|
||||
{
|
||||
if (vol > 200)
|
||||
{
|
||||
ErrorLog("Sound volume cannot exceed 200%%; setting to 100%%.\n");
|
||||
vol = 100;
|
||||
}
|
||||
|
||||
if (vol < 0)
|
||||
{
|
||||
ErrorLog("Sound volume cannot be negative; setting to 0%%.\n");
|
||||
vol = 0;
|
||||
}
|
||||
|
||||
soundVol = (unsigned) vol;
|
||||
}
|
||||
|
||||
inline unsigned GetSoundVolume(void)
|
||||
{
|
||||
return soundVol;
|
||||
}
|
||||
|
||||
// Music (DSB MPEG) volume (0-200)
|
||||
inline void SetMusicVolume(int vol)
|
||||
{
|
||||
if (vol > 200)
|
||||
{
|
||||
ErrorLog("Music volume cannot exceed 200%%; setting to 100%%.\n");
|
||||
vol = 100;
|
||||
}
|
||||
|
||||
if (vol < 0)
|
||||
{
|
||||
ErrorLog("Music volume cannot be negative; setting to 0%%.\n");
|
||||
vol = 0;
|
||||
}
|
||||
|
||||
musicVol = (unsigned) vol;
|
||||
}
|
||||
|
||||
inline unsigned GetMusicVolume(void)
|
||||
{
|
||||
return musicVol;
|
||||
}
|
||||
|
||||
// Defaults
|
||||
CDSBConfig(void)
|
||||
{
|
||||
emulateDSB = true;
|
||||
soundVol = 100;
|
||||
musicVol = 100;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned soundVol;
|
||||
unsigned musicVol;
|
||||
};
|
||||
#include "Util/NewConfig.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -142,7 +66,12 @@ class CDSBResampler
|
|||
public:
|
||||
int UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *inR, UINT8 volumeL, UINT8 volumeR, int sizeOut, int sizeIn, int outRate, int inRate);
|
||||
void Reset(void);
|
||||
CDSBResampler(const Util::Config::Node &config)
|
||||
: m_config(config)
|
||||
{
|
||||
}
|
||||
private:
|
||||
const Util::Config::Node &m_config;
|
||||
int nFrac;
|
||||
int pFrac;
|
||||
};
|
||||
|
@ -261,10 +190,12 @@ public:
|
|||
CZ80 *GetZ80(void);
|
||||
|
||||
// Constructor and destructor
|
||||
CDSB1(void);
|
||||
CDSB1(const Util::Config::Node &config);
|
||||
~CDSB1(void);
|
||||
|
||||
private:
|
||||
const Util::Config::Node &m_config;
|
||||
|
||||
// Resampler
|
||||
CDSBResampler Resampler;
|
||||
int retainedSamples; // how many MPEG samples carried over from previous frame
|
||||
|
@ -336,10 +267,12 @@ public:
|
|||
M68KCtx *GetM68K(void);
|
||||
|
||||
// Constructor and destructor
|
||||
CDSB2(void);
|
||||
CDSB2(const Util::Config::Node &config);
|
||||
~CDSB2(void);
|
||||
|
||||
private:
|
||||
const Util::Config::Node &m_config;
|
||||
|
||||
// Private helper functions
|
||||
void WriteMPEGFIFO(UINT8 byte);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,26 +28,7 @@
|
|||
#ifndef INCLUDED_DRIVEBOARD_H
|
||||
#define INCLUDED_DRIVEBOARD_H
|
||||
|
||||
/*
|
||||
* CDriveBoardConfig:
|
||||
*
|
||||
* Settings used by CDriveBoard.
|
||||
*/
|
||||
class CDriveBoardConfig
|
||||
{
|
||||
public:
|
||||
bool forceFeedback; // Enable drive board emulation/simulation (read only during Reset(), cannot be changed in-game)
|
||||
bool simulateDrvBoard; // Simulate drive board rather than emulating it
|
||||
unsigned steeringStrength; // Setting for steering strength on DIP switches of drive board
|
||||
|
||||
// Defaults
|
||||
CDriveBoardConfig(void)
|
||||
{
|
||||
forceFeedback = false;
|
||||
simulateDrvBoard = false;
|
||||
steeringStrength = 5;
|
||||
}
|
||||
};
|
||||
#include "Util/NewConfig.h"
|
||||
|
||||
/*
|
||||
* CDriveBoard
|
||||
|
@ -55,287 +36,292 @@ public:
|
|||
class CDriveBoard : public IBus
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* IsAttached(void):
|
||||
*
|
||||
* Returns:
|
||||
* True if the drive board is "attached" and should be emulated,
|
||||
* otherwise false.
|
||||
*/
|
||||
bool IsAttached(void);
|
||||
/*
|
||||
* IsAttached(void):
|
||||
*
|
||||
* Returns:
|
||||
* True if the drive board is "attached" and should be emulated,
|
||||
* otherwise false.
|
||||
*/
|
||||
bool IsAttached(void);
|
||||
|
||||
/*
|
||||
* IsSimulated(void):
|
||||
*
|
||||
* Returns:
|
||||
* True if the drive board is being simulated rather than actually
|
||||
* emulated, otherwise false.
|
||||
*/
|
||||
bool IsSimulated(void);
|
||||
/*
|
||||
* IsSimulated(void):
|
||||
*
|
||||
* Returns:
|
||||
* True if the drive board is being simulated rather than actually
|
||||
* emulated, otherwise false.
|
||||
*/
|
||||
bool IsSimulated(void);
|
||||
|
||||
/*
|
||||
* GetDIPSwitches(dip1, dip2):
|
||||
*
|
||||
* Reads the two sets of DIP switches on the drive board.
|
||||
*
|
||||
* Parameters:
|
||||
* dip1 Reference of variable to store DIP switch 1 to.
|
||||
* dip2 DIP switch 2.
|
||||
*/
|
||||
void GetDIPSwitches(UINT8 &dip1, UINT8 &dip2);
|
||||
/*
|
||||
* GetDIPSwitches(dip1, dip2):
|
||||
*
|
||||
* Reads the two sets of DIP switches on the drive board.
|
||||
*
|
||||
* Parameters:
|
||||
* dip1 Reference of variable to store DIP switch 1 to.
|
||||
* dip2 DIP switch 2.
|
||||
*/
|
||||
void GetDIPSwitches(UINT8 &dip1, UINT8 &dip2);
|
||||
|
||||
/*
|
||||
* SetDIPSwitches(dip1, dip2):
|
||||
*
|
||||
* Sets the DIP switches.
|
||||
*
|
||||
* Parameters:
|
||||
* dip1 DIP switch 1 value.
|
||||
* dip2 DIP switch 2 value.
|
||||
*/
|
||||
void SetDIPSwitches(UINT8 dip1, UINT8 dip2);
|
||||
/*
|
||||
* SetDIPSwitches(dip1, dip2):
|
||||
*
|
||||
* Sets the DIP switches.
|
||||
*
|
||||
* Parameters:
|
||||
* dip1 DIP switch 1 value.
|
||||
* dip2 DIP switch 2 value.
|
||||
*/
|
||||
void SetDIPSwitches(UINT8 dip1, UINT8 dip2);
|
||||
|
||||
/*
|
||||
* GetSteeringStrength(void):
|
||||
*
|
||||
* Returns:
|
||||
* Strength of the steering based on drive board DIP switches (1-8).
|
||||
*/
|
||||
unsigned GetSteeringStrength(void);
|
||||
/*
|
||||
* GetSteeringStrength(void):
|
||||
*
|
||||
* Returns:
|
||||
* Strength of the steering based on drive board DIP switches (1-8).
|
||||
*/
|
||||
unsigned GetSteeringStrength(void);
|
||||
|
||||
/*
|
||||
* SetSteeringStrength(steeringStrength):
|
||||
*
|
||||
* Sets the steering strength (modifies the DIP switch setting).
|
||||
*
|
||||
* Parameters:
|
||||
* steeringStrength A value ranging from 1 to 8.
|
||||
*/
|
||||
void SetSteeringStrength(unsigned steeringStrength);
|
||||
/*
|
||||
* SetSteeringStrength(steeringStrength):
|
||||
*
|
||||
* Sets the steering strength (modifies the DIP switch setting).
|
||||
*
|
||||
* Parameters:
|
||||
* steeringStrength A value ranging from 1 to 8.
|
||||
*/
|
||||
void SetSteeringStrength(unsigned steeringStrength);
|
||||
|
||||
/*
|
||||
* Get7SegDisplays(seg1Digit1, seg1Digit2, seg2Digit1, seg2Digit2):
|
||||
*
|
||||
* Reads the 7-segment displays.
|
||||
*
|
||||
* Parameters:
|
||||
* seg1Digit1 Reference of variable to store digit 1 of the first 7-
|
||||
* segment display to.
|
||||
* seg1Digit2 First display, second digit.
|
||||
* seg2Digit1 Second display, first digit.
|
||||
* seg2Digit2 Second display, second digit.
|
||||
*/
|
||||
void Get7SegDisplays(UINT8 &seg1Digit, UINT8 &seg1Digit2, UINT8 &seg2Digit1, UINT8 &seg2Digit2);
|
||||
/*
|
||||
* Get7SegDisplays(seg1Digit1, seg1Digit2, seg2Digit1, seg2Digit2):
|
||||
*
|
||||
* Reads the 7-segment displays.
|
||||
*
|
||||
* Parameters:
|
||||
* seg1Digit1 Reference of variable to store digit 1 of the first 7-
|
||||
* segment display to.
|
||||
* seg1Digit2 First display, second digit.
|
||||
* seg2Digit1 Second display, first digit.
|
||||
* seg2Digit2 Second display, second digit.
|
||||
*/
|
||||
void Get7SegDisplays(UINT8 &seg1Digit, UINT8 &seg1Digit2, UINT8 &seg2Digit1, UINT8 &seg2Digit2);
|
||||
|
||||
/*
|
||||
* GetZ80(void):
|
||||
*
|
||||
* Returns:
|
||||
* The Z80 object.
|
||||
*/
|
||||
CZ80 *GetZ80(void);
|
||||
/*
|
||||
* GetZ80(void):
|
||||
*
|
||||
* Returns:
|
||||
* The Z80 object.
|
||||
*/
|
||||
CZ80 *GetZ80(void);
|
||||
|
||||
/*
|
||||
* SaveState(SaveState):
|
||||
*
|
||||
* Saves the drive board state.
|
||||
*
|
||||
* Parameters:
|
||||
* SaveState Block file to save state information to.
|
||||
*/
|
||||
void SaveState(CBlockFile *SaveState);
|
||||
/*
|
||||
* SaveState(SaveState):
|
||||
*
|
||||
* Saves the drive board state.
|
||||
*
|
||||
* Parameters:
|
||||
* SaveState Block file to save state information to.
|
||||
*/
|
||||
void SaveState(CBlockFile *SaveState);
|
||||
|
||||
/*
|
||||
* LoadState(SaveState):
|
||||
*
|
||||
* Restores the drive board state.
|
||||
*
|
||||
* Parameters:
|
||||
* SaveState Block file to load save state information from.
|
||||
*/
|
||||
void LoadState(CBlockFile *SaveState);
|
||||
/*
|
||||
* LoadState(SaveState):
|
||||
*
|
||||
* Restores the drive board state.
|
||||
*
|
||||
* Parameters:
|
||||
* SaveState Block file to load save state information from.
|
||||
*/
|
||||
void LoadState(CBlockFile *SaveState);
|
||||
|
||||
/*
|
||||
* Init(romPtr):
|
||||
*
|
||||
* Initializes (and "attaches") the drive board. This should be called
|
||||
* before other members.
|
||||
*
|
||||
* Parameters:
|
||||
* romPtr Pointer to the drive board ROM (Z80 program). If this
|
||||
* is NULL, then the drive board will not be emulated.
|
||||
*
|
||||
* Returns:
|
||||
* FAIL if the drive board could not be initialized (prints own error
|
||||
* message), otherwise OKAY. If the drive board is not attached
|
||||
* because no ROM was passed to it, no error is generated and the
|
||||
* drive board is silently disabled (detached).
|
||||
*/
|
||||
bool Init(const UINT8 *romPtr);
|
||||
/*
|
||||
* Init(romPtr):
|
||||
*
|
||||
* Initializes (and "attaches") the drive board. This should be called
|
||||
* before other members.
|
||||
*
|
||||
* Parameters:
|
||||
* romPtr Pointer to the drive board ROM (Z80 program). If this
|
||||
* is NULL, then the drive board will not be emulated.
|
||||
*
|
||||
* Returns:
|
||||
* FAIL if the drive board could not be initialized (prints own error
|
||||
* message), otherwise OKAY. If the drive board is not attached
|
||||
* because no ROM was passed to it, no error is generated and the
|
||||
* drive board is silently disabled (detached).
|
||||
*/
|
||||
bool Init(const UINT8 *romPtr);
|
||||
|
||||
/*
|
||||
* AttachInputs(InputsPtr, gameInputFlags):
|
||||
*
|
||||
* Attaches inputs to the drive board (for access to the steering wheel
|
||||
* position).
|
||||
*
|
||||
* Parameters:
|
||||
* inputs Pointer to the input object.
|
||||
* gameInputFlags The current game's input flags.
|
||||
*/
|
||||
void AttachInputs(CInputs *inputs, unsigned gameInputFlags);
|
||||
/*
|
||||
* AttachInputs(InputsPtr, gameInputFlags):
|
||||
*
|
||||
* Attaches inputs to the drive board (for access to the steering wheel
|
||||
* position).
|
||||
*
|
||||
* Parameters:
|
||||
* inputs Pointer to the input object.
|
||||
* gameInputFlags The current game's input flags.
|
||||
*/
|
||||
void AttachInputs(CInputs *inputs, unsigned gameInputFlags);
|
||||
|
||||
void AttachOutputs(COutputs *outputs);
|
||||
void AttachOutputs(COutputs *outputs);
|
||||
|
||||
/*
|
||||
* Reset(void):
|
||||
*
|
||||
* Resets the drive board.
|
||||
*/
|
||||
void Reset(void);
|
||||
/*
|
||||
* Reset(void):
|
||||
*
|
||||
* Resets the drive board.
|
||||
*/
|
||||
void Reset(void);
|
||||
|
||||
/*
|
||||
* Read():
|
||||
*
|
||||
* Reads data from the drive board.
|
||||
*
|
||||
* Returns:
|
||||
* Data read.
|
||||
*/
|
||||
UINT8 Read(void);
|
||||
/*
|
||||
* Read():
|
||||
*
|
||||
* Reads data from the drive board.
|
||||
*
|
||||
* Returns:
|
||||
* Data read.
|
||||
*/
|
||||
UINT8 Read(void);
|
||||
|
||||
/*
|
||||
* Write(data):
|
||||
*
|
||||
* Writes data to the drive board.
|
||||
*
|
||||
* Parameters:
|
||||
* data Data to send.
|
||||
*/
|
||||
void Write(UINT8 data);
|
||||
/*
|
||||
* Write(data):
|
||||
*
|
||||
* Writes data to the drive board.
|
||||
*
|
||||
* Parameters:
|
||||
* data Data to send.
|
||||
*/
|
||||
void Write(UINT8 data);
|
||||
|
||||
/*
|
||||
* RunFrame(void):
|
||||
*
|
||||
* Emulates a single frame's worth of time on the drive board.
|
||||
*/
|
||||
void RunFrame(void);
|
||||
/*
|
||||
* RunFrame(void):
|
||||
*
|
||||
* Emulates a single frame's worth of time on the drive board.
|
||||
*/
|
||||
void RunFrame(void);
|
||||
|
||||
/*
|
||||
* CDriveBoard():
|
||||
* ~CDriveBoard():
|
||||
*
|
||||
* Constructor and destructor. Memory is freed by destructor.
|
||||
*/
|
||||
CDriveBoard();
|
||||
~CDriveBoard(void);
|
||||
/*
|
||||
* CDriveBoard(config):
|
||||
* ~CDriveBoard():
|
||||
*
|
||||
* Constructor and destructor. Memory is freed by destructor.
|
||||
*
|
||||
* Paramters:
|
||||
* config Run-time configuration. The reference should be held because
|
||||
* this changes at run-time.
|
||||
*/
|
||||
CDriveBoard(const Util::Config::Node &config);
|
||||
~CDriveBoard(void);
|
||||
|
||||
/*
|
||||
* Read8(addr):
|
||||
* IORead8(portNum):
|
||||
*
|
||||
* Methods for reading from Z80's memory and IO space. Required by CBus.
|
||||
*
|
||||
* Parameters:
|
||||
* addr Address in memory (0-0xFFFF).
|
||||
* portNum Port address (0-255).
|
||||
*
|
||||
* Returns:
|
||||
* A byte of data from the address or port.
|
||||
*/
|
||||
UINT8 Read8(UINT32 addr);
|
||||
UINT8 IORead8(UINT32 portNum);
|
||||
|
||||
/*
|
||||
* Write8(addr, data):
|
||||
* IORead8(portNum, data):
|
||||
*
|
||||
* Methods for writing to Z80's memory and IO space. Required by CBus.
|
||||
*
|
||||
* Parameters:
|
||||
* addr Address in memory (0-0xFFFF).
|
||||
* portNum Port address (0-255).
|
||||
* data Byte to write.
|
||||
*/
|
||||
void Write8(UINT32 addr, UINT8 data);
|
||||
void IOWrite8(UINT32 portNum, UINT8 data);
|
||||
|
||||
/*
|
||||
* Read8(addr):
|
||||
* IORead8(portNum):
|
||||
*
|
||||
* Methods for reading from Z80's memory and IO space. Required by CBus.
|
||||
*
|
||||
* Parameters:
|
||||
* addr Address in memory (0-0xFFFF).
|
||||
* portNum Port address (0-255).
|
||||
*
|
||||
* Returns:
|
||||
* A byte of data from the address or port.
|
||||
*/
|
||||
UINT8 Read8(UINT32 addr);
|
||||
UINT8 IORead8(UINT32 portNum);
|
||||
|
||||
/*
|
||||
* Write8(addr, data):
|
||||
* IORead8(portNum, data):
|
||||
*
|
||||
* Methods for writing to Z80's memory and IO space. Required by CBus.
|
||||
*
|
||||
* Parameters:
|
||||
* addr Address in memory (0-0xFFFF).
|
||||
* portNum Port address (0-255).
|
||||
* data Byte to write.
|
||||
*/
|
||||
void Write8(UINT32 addr, UINT8 data);
|
||||
void IOWrite8(UINT32 portNum, UINT8 data);
|
||||
|
||||
private:
|
||||
bool m_attached; // True if drive board is attached
|
||||
bool m_tmpDisabled; // True if temporarily disabled by loading an incompatible save state
|
||||
bool m_simulated; // True if drive board should be simulated rather than emulated
|
||||
const Util::Config::Node &m_config;
|
||||
bool m_attached; // True if drive board is attached
|
||||
bool m_tmpDisabled; // True if temporarily disabled by loading an incompatible save state
|
||||
bool m_simulated; // True if drive board should be simulated rather than emulated
|
||||
|
||||
UINT8 m_dip1; // Value of DIP switch 1
|
||||
UINT8 m_dip2; // Value of DIP switch 2
|
||||
UINT8 m_dip1; // Value of DIP switch 1
|
||||
UINT8 m_dip2; // Value of DIP switch 2
|
||||
|
||||
const UINT8* m_rom; // 32k ROM
|
||||
UINT8* m_ram; // 8k RAM
|
||||
const UINT8* m_rom; // 32k ROM
|
||||
UINT8* m_ram; // 8k RAM
|
||||
|
||||
CZ80 m_z80; // Z80 CPU @ 4MHz
|
||||
CZ80 m_z80; // Z80 CPU @ 4MHz
|
||||
|
||||
CInputs *m_inputs;
|
||||
unsigned m_inputFlags;
|
||||
CInputs *m_inputs;
|
||||
unsigned m_inputFlags;
|
||||
|
||||
COutputs *m_outputs;
|
||||
|
||||
// Emulation state
|
||||
bool m_initialized; // True if drive board has finished initialization
|
||||
bool m_allowInterrupts; // True if drive board has enabled NMI interrupts
|
||||
COutputs *m_outputs;
|
||||
|
||||
// Emulation state
|
||||
bool m_initialized; // True if drive board has finished initialization
|
||||
bool m_allowInterrupts; // True if drive board has enabled NMI interrupts
|
||||
|
||||
UINT8 m_seg1Digit1; // Current value of left digit on 7-segment display 1
|
||||
UINT8 m_seg1Digit2; // Current value of right digit on 7-segment display 1
|
||||
UINT8 m_seg2Digit1; // Current value of left digit on 7-segment display 2
|
||||
UINT8 m_seg2Digit2; // Current value of right digit on 7-segment display 2
|
||||
UINT8 m_seg1Digit1; // Current value of left digit on 7-segment display 1
|
||||
UINT8 m_seg1Digit2; // Current value of right digit on 7-segment display 1
|
||||
UINT8 m_seg2Digit1; // Current value of left digit on 7-segment display 2
|
||||
UINT8 m_seg2Digit2; // Current value of right digit on 7-segment display 2
|
||||
|
||||
UINT8 m_dataSent; // Last command sent by main board
|
||||
UINT8 m_dataReceived; // Data to send back to main board
|
||||
UINT8 m_dataSent; // Last command sent by main board
|
||||
UINT8 m_dataReceived; // Data to send back to main board
|
||||
|
||||
UINT16 m_adcPortRead; // ADC port currently reading from
|
||||
UINT8 m_adcPortBit; // Bit number currently reading on ADC port
|
||||
UINT16 m_adcPortRead; // ADC port currently reading from
|
||||
UINT8 m_adcPortBit; // Bit number currently reading on ADC port
|
||||
|
||||
UINT8 m_port42Out; // Last value sent to Z80 I/O port 42 (encoder motor data)
|
||||
UINT8 m_port46Out; // Last value sent to Z80 I/O port 46 (encoder motor control)
|
||||
UINT8 m_port42Out; // Last value sent to Z80 I/O port 42 (encoder motor data)
|
||||
UINT8 m_port46Out; // Last value sent to Z80 I/O port 46 (encoder motor control)
|
||||
|
||||
UINT8 m_prev42Out; // Previous value sent to Z80 I/O port 42
|
||||
UINT8 m_prev46Out; // Previous value sent to Z80 I/O port 46
|
||||
UINT8 m_prev42Out; // Previous value sent to Z80 I/O port 42
|
||||
UINT8 m_prev46Out; // Previous value sent to Z80 I/O port 46
|
||||
|
||||
UINT8 m_uncenterVal1; // First part of pending uncenter command
|
||||
UINT8 m_uncenterVal2; // Second part of pending uncenter command
|
||||
UINT8 m_uncenterVal1; // First part of pending uncenter command
|
||||
UINT8 m_uncenterVal2; // Second part of pending uncenter command
|
||||
|
||||
// Simulation state
|
||||
UINT8 m_initState;
|
||||
UINT8 m_statusFlags;
|
||||
UINT8 m_boardMode;
|
||||
UINT8 m_readMode;
|
||||
UINT8 m_wheelCenter;
|
||||
UINT8 m_cockpitCenter;
|
||||
UINT8 m_echoVal;
|
||||
// Simulation state
|
||||
UINT8 m_initState;
|
||||
UINT8 m_statusFlags;
|
||||
UINT8 m_boardMode;
|
||||
UINT8 m_readMode;
|
||||
UINT8 m_wheelCenter;
|
||||
UINT8 m_cockpitCenter;
|
||||
UINT8 m_echoVal;
|
||||
|
||||
// Feedback state
|
||||
INT8 m_lastConstForce; // Last constant force command sent
|
||||
UINT8 m_lastSelfCenter; // Last self center command sent
|
||||
UINT8 m_lastFriction; // Last friction command sent
|
||||
UINT8 m_lastVibrate; // Last vibrate command sent
|
||||
// Feedback state
|
||||
INT8 m_lastConstForce; // Last constant force command sent
|
||||
UINT8 m_lastSelfCenter; // Last self center command sent
|
||||
UINT8 m_lastFriction; // Last friction command sent
|
||||
UINT8 m_lastVibrate; // Last vibrate command sent
|
||||
|
||||
UINT8 SimulateRead(void);
|
||||
UINT8 SimulateRead(void);
|
||||
|
||||
void SimulateWrite(UINT8 data);
|
||||
void SimulateWrite(UINT8 data);
|
||||
|
||||
void SimulateFrame(void);
|
||||
void SimulateFrame(void);
|
||||
|
||||
void EmulateFrame(void);
|
||||
void EmulateFrame(void);
|
||||
|
||||
void ProcessEncoderCmd(void);
|
||||
void ProcessEncoderCmd(void);
|
||||
|
||||
void SendStopAll(void);
|
||||
void SendStopAll(void);
|
||||
|
||||
void SendConstantForce(INT8 val);
|
||||
void SendConstantForce(INT8 val);
|
||||
|
||||
void SendSelfCenter(UINT8 val);
|
||||
void SendSelfCenter(UINT8 val);
|
||||
|
||||
void SendFriction(UINT8 val);
|
||||
void SendFriction(UINT8 val);
|
||||
|
||||
void SendVibrate(UINT8 val);
|
||||
void SendVibrate(UINT8 val);
|
||||
};
|
||||
|
||||
#endif // INCLUDED_DRIVEBOARD_H
|
||||
#endif // INCLUDED_DRIVEBOARD_H
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#define INCLUDED_IEMULATOR_H
|
||||
|
||||
class CBlockFile;
|
||||
struct GameInfo;
|
||||
struct Game;
|
||||
struct ROMSet;
|
||||
class CRender2D;
|
||||
class IRender3D;
|
||||
class CInputs;
|
||||
|
@ -116,31 +117,30 @@ public:
|
|||
* Resets the system. Does not modify non-volatile memory.
|
||||
*/
|
||||
virtual void Reset(void) = 0;
|
||||
|
||||
|
||||
/*
|
||||
* GetGameInfo(void):
|
||||
* GetGame(void):
|
||||
*
|
||||
* Returns:
|
||||
* A pointer to the presently loaded game's information structure (or
|
||||
* NULL if no ROM set has yet been loaded).
|
||||
* A reference to the presently loaded game's information structure (which
|
||||
* will be blank if no game has yet been loaded).
|
||||
*/
|
||||
virtual const struct GameInfo * GetGameInfo(void) = 0;
|
||||
|
||||
virtual const Game &GetGame(void) const = 0;
|
||||
|
||||
/*
|
||||
* LoadROMSet(GameList, zipFile):
|
||||
* LoadGame(game, rom_set):
|
||||
*
|
||||
* Loads a complete ROM set from the specified ZIP archive.
|
||||
* Loads a game, copying in the provided ROMs and setting the hardware
|
||||
* stepping.
|
||||
*
|
||||
* NOTE: Command line settings will not have been applied here yet.
|
||||
*
|
||||
* Parameters:
|
||||
* GameList List of all supported games and their ROMs.
|
||||
* zipFile ZIP file to load from.
|
||||
* Parameters:
|
||||
* game Game information.
|
||||
* rom_set ROMs.
|
||||
*
|
||||
* Returns:
|
||||
* OKAY if successful, FAIL otherwise. Prints errors.
|
||||
*/
|
||||
virtual bool LoadROMSet(const struct GameInfo *GameList, const char *zipFile) = 0;
|
||||
virtual bool LoadGame(const Game &game, const ROMSet &rom_set) = 0;
|
||||
|
||||
/*
|
||||
* AttachRenderers(Render2DPtr, Render3DPtr):
|
||||
|
|
|
@ -202,10 +202,13 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "Supermodel.h"
|
||||
#include "Game.h"
|
||||
#include "ROMSet.h"
|
||||
#include "Util/Format.h"
|
||||
#include "Util/ByteSwap.h"
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
/******************************************************************************
|
||||
Model 3 Inputs
|
||||
|
@ -244,7 +247,7 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data = (data&0xDF)|(EEPROM.Read()<<5); // bank 1 contains EEPROM data bit
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SKI))
|
||||
if ((m_game.inputs & Game::INPUT_SKI))
|
||||
{
|
||||
if ((inputBank&1) == 0)
|
||||
{
|
||||
|
@ -261,12 +264,12 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
|
||||
data = 0xFF;
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SKI))
|
||||
if ((m_game.inputs & Game::INPUT_SKI))
|
||||
{
|
||||
data &= ~(Inputs->skiPollRight->value<<0);
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_JOYSTICK1))
|
||||
if ((m_game.inputs & Game::INPUT_JOYSTICK1))
|
||||
{
|
||||
data &= ~(Inputs->up[0]->value<<5); // P1 Up
|
||||
data &= ~(Inputs->down[0]->value<<4); // P1 Down
|
||||
|
@ -274,7 +277,7 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->right[0]->value<<6); // P1 Right
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_FIGHTING))
|
||||
if ((m_game.inputs & Game::INPUT_FIGHTING))
|
||||
{
|
||||
data &= ~(Inputs->escape[0]->value<<3); // P1 Escape
|
||||
data &= ~(Inputs->guard[0]->value<<2); // P1 Guard
|
||||
|
@ -282,7 +285,7 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->punch[0]->value<<0); // P1 Punch
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SPIKEOUT))
|
||||
if ((m_game.inputs & Game::INPUT_SPIKEOUT))
|
||||
{
|
||||
data &= ~(Inputs->shift->value<<2); // Shift
|
||||
data &= ~(Inputs->beat->value<<0); // Beat
|
||||
|
@ -290,14 +293,14 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->jump->value<<3); // Jump
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SOCCER))
|
||||
if ((m_game.inputs & Game::INPUT_SOCCER))
|
||||
{
|
||||
data &= ~(Inputs->shortPass[0]->value<<2); // P1 Short Pass
|
||||
data &= ~(Inputs->longPass[0]->value<<0); // P1 Long Pass
|
||||
data &= ~(Inputs->shoot[0]->value<<1); // P1 Shoot
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_VR4))
|
||||
if ((m_game.inputs & Game::INPUT_VR4))
|
||||
{
|
||||
data &= ~(Inputs->vr[0]->value<<0); // VR1 Red
|
||||
data &= ~(Inputs->vr[1]->value<<1); // VR2 Blue
|
||||
|
@ -305,16 +308,16 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->vr[3]->value<<3); // VR4 Green
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_VIEWCHANGE))
|
||||
if ((m_game.inputs & Game::INPUT_VIEWCHANGE))
|
||||
{
|
||||
// Harley is wired slightly differently
|
||||
if ((Game->inputFlags&GAME_INPUT_HARLEY))
|
||||
if ((m_game.inputs & Game::INPUT_HARLEY))
|
||||
data &= ~(Inputs->viewChange->value<<1); // View change
|
||||
else
|
||||
data &= ~(Inputs->viewChange->value<<0); // View change
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SHIFT4))
|
||||
if ((m_game.inputs & Game::INPUT_SHIFT4))
|
||||
{
|
||||
if (Inputs->gearShift4->value == 2) // Shift 2
|
||||
data &= ~0x60;
|
||||
|
@ -326,10 +329,10 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~0x10;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SHIFTUPDOWN))
|
||||
if ((m_game.inputs & Game::INPUT_SHIFTUPDOWN))
|
||||
{
|
||||
// Harley is wired slightly differently
|
||||
if ((Game->inputFlags&GAME_INPUT_HARLEY))
|
||||
if ((m_game.inputs & Game::INPUT_HARLEY))
|
||||
{
|
||||
if (Inputs->gearShiftUp->value) // Shift up
|
||||
data &= ~0x60;
|
||||
|
@ -345,16 +348,16 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
}
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_HANDBRAKE))
|
||||
if ((m_game.inputs & Game::INPUT_HANDBRAKE))
|
||||
data &= ~(Inputs->handBrake->value<<1); // Hand brake
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_HARLEY))
|
||||
if ((m_game.inputs & Game::INPUT_HARLEY))
|
||||
data &= ~(Inputs->musicSelect->value<<0); // Music select
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_GUN1))
|
||||
if ((m_game.inputs & Game::INPUT_GUN1))
|
||||
data &= ~(Inputs->trigger[0]->value<<0); // P1 Trigger
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_ANALOG_JOYSTICK))
|
||||
if ((m_game.inputs & Game::INPUT_ANALOG_JOYSTICK))
|
||||
{
|
||||
data &= ~(Inputs->analogJoyTrigger1->value<<5); // Trigger 1
|
||||
data &= ~(Inputs->analogJoyTrigger2->value<<4); // Trigger 2
|
||||
|
@ -362,7 +365,7 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->analogJoyEvent2->value<<1); // Event Button 2
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_TWIN_JOYSTICKS)) // First twin joystick
|
||||
if ((m_game.inputs & Game::INPUT_TWIN_JOYSTICKS)) // First twin joystick
|
||||
{
|
||||
/*
|
||||
* Process left joystick inputs first
|
||||
|
@ -418,16 +421,16 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~0x40;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_ANALOG_GUN1))
|
||||
if ((m_game.inputs & Game::INPUT_ANALOG_GUN1))
|
||||
{
|
||||
data &= ~(Inputs->analogTriggerLeft[0]->value<<0);
|
||||
data &= ~(Inputs->analogTriggerRight[0]->value<<1);
|
||||
}
|
||||
|
||||
if ((Game->inputFlags & GAME_INPUT_MAGTRUCK))
|
||||
if ((m_game.inputs & Game::INPUT_MAGTRUCK))
|
||||
data &= ~(Inputs->magicalPedal1->value << 0);
|
||||
|
||||
if ((Game->inputFlags & GAME_INPUT_FISHING))
|
||||
if ((m_game.inputs & Game::INPUT_FISHING))
|
||||
{
|
||||
data &= ~(Inputs->fishingCast->value << 0);
|
||||
data &= ~(Inputs->fishingSelect->value << 1);
|
||||
|
@ -441,7 +444,7 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
if (DriveBoard.IsAttached())
|
||||
data = DriveBoard.Read();
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_JOYSTICK2))
|
||||
if ((m_game.inputs & Game::INPUT_JOYSTICK2))
|
||||
{
|
||||
data &= ~(Inputs->up[1]->value<<5); // P2 Up
|
||||
data &= ~(Inputs->down[1]->value<<4); // P2 Down
|
||||
|
@ -449,7 +452,7 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->right[1]->value<<6); // P2 Right
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_FIGHTING))
|
||||
if ((m_game.inputs & Game::INPUT_FIGHTING))
|
||||
{
|
||||
data &= ~(Inputs->escape[1]->value<<3); // P2 Escape
|
||||
data &= ~(Inputs->guard[1]->value<<2); // P2 Guard
|
||||
|
@ -457,14 +460,14 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~(Inputs->punch[1]->value<<0); // P2 Punch
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SOCCER))
|
||||
if ((m_game.inputs & Game::INPUT_SOCCER))
|
||||
{
|
||||
data &= ~(Inputs->shortPass[1]->value<<2); // P2 Short Pass
|
||||
data &= ~(Inputs->longPass[1]->value<<0); // P2 Long Pass
|
||||
data &= ~(Inputs->shoot[1]->value<<1); // P2 Shoot
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_TWIN_JOYSTICKS)) // Second twin joystick (see register 0x08 for comments)
|
||||
if ((m_game.inputs & Game::INPUT_TWIN_JOYSTICKS)) // Second twin joystick (see register 0x08 for comments)
|
||||
{
|
||||
|
||||
data &= ~(Inputs->twinJoyShot2->value<<0);
|
||||
|
@ -494,16 +497,16 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
data &= ~0x80;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_GUN2))
|
||||
if ((m_game.inputs & Game::INPUT_GUN2))
|
||||
data &= ~(Inputs->trigger[1]->value<<0); // P2 Trigger
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_ANALOG_GUN2))
|
||||
if ((m_game.inputs & Game::INPUT_ANALOG_GUN2))
|
||||
{
|
||||
data &= ~(Inputs->analogTriggerLeft[1]->value<<0);
|
||||
data &= ~(Inputs->analogTriggerRight[1]->value<<1);
|
||||
}
|
||||
|
||||
if ((Game->inputFlags & GAME_INPUT_MAGTRUCK))
|
||||
if ((m_game.inputs & Game::INPUT_MAGTRUCK))
|
||||
data &= ~(Inputs->magicalPedal2->value << 0);
|
||||
|
||||
return data;
|
||||
|
@ -521,22 +524,22 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
|
||||
// Load ADC channels with input data
|
||||
memset(adc, 0, sizeof(adc));
|
||||
if ((Game->inputFlags&GAME_INPUT_VEHICLE))
|
||||
if ((m_game.inputs & Game::INPUT_VEHICLE))
|
||||
{
|
||||
adc[0] = (UINT8)Inputs->steering->value;
|
||||
adc[1] = (UINT8)Inputs->accelerator->value;
|
||||
adc[2] = (UINT8)Inputs->brake->value;
|
||||
if ((Game->inputFlags&GAME_INPUT_HARLEY))
|
||||
if ((m_game.inputs & Game::INPUT_HARLEY))
|
||||
adc[3] = (UINT8)Inputs->rearBrake->value;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_ANALOG_JOYSTICK))
|
||||
if ((m_game.inputs & Game::INPUT_ANALOG_JOYSTICK))
|
||||
{
|
||||
adc[0] = (UINT8)Inputs->analogJoyY->value;
|
||||
adc[1] = (UINT8)Inputs->analogJoyX->value;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_ANALOG_GUN1)||(Game->inputFlags&GAME_INPUT_ANALOG_GUN2))
|
||||
if ((m_game.inputs & Game::INPUT_ANALOG_GUN1)||(m_game.inputs & Game::INPUT_ANALOG_GUN2))
|
||||
{
|
||||
adc[0] = (UINT8)Inputs->analogGunX[0]->value;
|
||||
adc[2] = (UINT8)Inputs->analogGunY[0]->value;
|
||||
|
@ -544,19 +547,19 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
|||
adc[3] = (UINT8)Inputs->analogGunY[1]->value;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags&GAME_INPUT_SKI))
|
||||
if ((m_game.inputs & Game::INPUT_SKI))
|
||||
{
|
||||
adc[0] = (UINT8)Inputs->skiY->value;
|
||||
adc[1] = (UINT8)Inputs->skiX->value;
|
||||
}
|
||||
|
||||
if ((Game->inputFlags & GAME_INPUT_MAGTRUCK))
|
||||
if ((m_game.inputs & Game::INPUT_MAGTRUCK))
|
||||
{
|
||||
adc[0] = uint8_t(Inputs->magicalLever1->value);
|
||||
adc[1] = uint8_t(Inputs->magicalLever2->value);
|
||||
}
|
||||
|
||||
if ((Game->inputFlags & GAME_INPUT_FISHING))
|
||||
if ((m_game.inputs & Game::INPUT_FISHING))
|
||||
{
|
||||
adc[0] = uint8_t(Inputs->fishingRodY->value);
|
||||
adc[1] = uint8_t(Inputs->fishingRodX->value);
|
||||
|
@ -615,7 +618,7 @@ void CModel3::WriteInputs(unsigned reg, UINT8 data)
|
|||
case 0x87: // Read light gun register
|
||||
serialFIFO1 = 0; // clear serial FIFO 1
|
||||
serialFIFO2 = 0;
|
||||
if ((Game->inputFlags&GAME_INPUT_GUN1||Game->inputFlags&GAME_INPUT_GUN2))
|
||||
if ((m_game.inputs & Game::INPUT_GUN1||m_game.inputs & Game::INPUT_GUN2))
|
||||
{
|
||||
switch (gunReg)
|
||||
{
|
||||
|
@ -940,7 +943,7 @@ UINT8 CModel3::Read8(UINT32 addr)
|
|||
|
||||
// 53C810 SCSI
|
||||
case 0xC0: // only on Step 1.0
|
||||
if (Game->step != 0x10)
|
||||
if (m_game.stepping != "1.0")
|
||||
break;
|
||||
case 0xF9:
|
||||
case 0xC1:
|
||||
|
@ -1174,7 +1177,7 @@ UINT32 CModel3::Read32(UINT32 addr)
|
|||
|
||||
// 53C810 SCSI
|
||||
case 0xC0: // only on Step 1.0
|
||||
if (Game->step != 0x10) // check for Step 1.0
|
||||
if (m_game.stepping != "1.0") // check for Step 1.0
|
||||
break;
|
||||
case 0xF9:
|
||||
case 0xC1:
|
||||
|
@ -1291,7 +1294,7 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
|
|||
|
||||
// 53C810 SCSI
|
||||
case 0xC0: // only on Step 1.0
|
||||
if (Game->step != 0x10)
|
||||
if (m_game.stepping != "1.0")
|
||||
goto Unknown8;
|
||||
case 0xF9:
|
||||
case 0xC1:
|
||||
|
@ -1553,7 +1556,7 @@ void CModel3::Write32(UINT32 addr, UINT32 data)
|
|||
|
||||
// 53C810 SCSI
|
||||
case 0xC0: // step 1.0 only
|
||||
if (Game->step != 0x10)
|
||||
if (m_game.stepping != "1.0")
|
||||
goto Unknown32;
|
||||
case 0xF9:
|
||||
case 0xC1:
|
||||
|
@ -1687,20 +1690,20 @@ void CModel3::RunFrame(void)
|
|||
UINT32 start = CThread::GetTicks();
|
||||
|
||||
// See if currently running multi-threaded
|
||||
if (g_Config.multiThreaded)
|
||||
if (m_multiThreaded)
|
||||
{
|
||||
// If so, check all threads are up and running
|
||||
if (!StartThreads())
|
||||
goto ThreadError;
|
||||
|
||||
// Wake threads for PPC main board (if multi-threading GPU), sound board (if sync'd) and drive board (if attached) so they can process a frame
|
||||
if ((g_Config.gpuMultiThreaded && !ppcBrdThreadSync->Post()) ||
|
||||
(syncSndBrdThread && !sndBrdThreadSync->Post()) ||
|
||||
(DriveBoard.IsAttached() && !drvBrdThreadSync->Post()))
|
||||
if ((m_gpuMultiThreaded && !ppcBrdThreadSync->Post()) ||
|
||||
(syncSndBrdThread && !sndBrdThreadSync->Post()) ||
|
||||
(DriveBoard.IsAttached() && !drvBrdThreadSync->Post()))
|
||||
goto ThreadError;
|
||||
|
||||
// If not multi-threading GPU, then run PPC main board for a frame and sync GPUs now in this thread
|
||||
if (!g_Config.gpuMultiThreaded)
|
||||
if (!m_gpuMultiThreaded)
|
||||
{
|
||||
RunMainBoardFrame();
|
||||
SyncGPUs();
|
||||
|
@ -1714,9 +1717,9 @@ void CModel3::RunFrame(void)
|
|||
goto ThreadError;
|
||||
|
||||
// Wait for PPC main board, sound board and drive board threads to finish their work (if they are running and haven't finished already)
|
||||
while ((g_Config.gpuMultiThreaded && !ppcBrdThreadDone) ||
|
||||
(syncSndBrdThread && !sndBrdThreadDone) ||
|
||||
(DriveBoard.IsAttached() && !drvBrdThreadDone))
|
||||
while ((m_gpuMultiThreaded && !ppcBrdThreadDone) ||
|
||||
(syncSndBrdThread && !sndBrdThreadDone) ||
|
||||
(DriveBoard.IsAttached() && !drvBrdThreadDone))
|
||||
{
|
||||
if (!notifySync->Wait(notifyLock))
|
||||
goto ThreadError;
|
||||
|
@ -1730,7 +1733,7 @@ void CModel3::RunFrame(void)
|
|||
goto ThreadError;
|
||||
|
||||
// If multi-threading GPU, then sync GPUs last while PPC main board thread is waiting
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
SyncGPUs();
|
||||
}
|
||||
else
|
||||
|
@ -1750,7 +1753,7 @@ void CModel3::RunFrame(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in CModel3::RunFrame: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
}
|
||||
|
||||
void CModel3::RunMainBoardFrame(void)
|
||||
|
@ -1758,7 +1761,7 @@ void CModel3::RunMainBoardFrame(void)
|
|||
UINT32 start = CThread::GetTicks();
|
||||
|
||||
// Compute display and VBlank timings
|
||||
unsigned ppcCycles = g_Config.GetPowerPCFrequency() * 1000000;
|
||||
unsigned ppcCycles = m_config["PowerPCFrequency"].ValueAs<unsigned>() * 1000000;
|
||||
unsigned frameCycles = ppcCycles / 60;
|
||||
unsigned vblCycles = (unsigned)((float) frameCycles * 2.5f/100.0f); // 2.5% vblank (ridiculously short and wrong but bigger values cause flicker in Daytona)
|
||||
unsigned dispCycles = frameCycles - vblCycles;
|
||||
|
@ -1774,15 +1777,15 @@ void CModel3::RunMainBoardFrame(void)
|
|||
// The values below were arrived at by trial and error and clearly more investigation is required. If it turns out that the status bit is
|
||||
// connected to the end of VBlank then the code below should be removed and the timing handled via GPU.VBlankEnd() instead.
|
||||
unsigned statusCycles;
|
||||
if (Game->step >= 0x20)
|
||||
if (m_game.stepping == "2.0" || m_game.stepping == "2.1")
|
||||
{
|
||||
// For some reason, Fighting Vipers 2 and Daytona USA 2 require completely different timing to the rest of the step 2.x games
|
||||
if (!strcmp(Game->id, "daytona2") || (Game->step == 0x20 && !strcmp(Game->id, "fvipers2")))
|
||||
if (m_game.name == "daytona2" || (m_game.stepping == "2.0" && m_game.name == "fvipers2"))
|
||||
statusCycles = (unsigned)((float)frameCycles * 24.0f/100.0f);
|
||||
else
|
||||
statusCycles = (unsigned)((float)frameCycles * 9.12f/100.0f);
|
||||
}
|
||||
else if (Game->step == 0x15)
|
||||
else if (m_game.stepping == "1.5")
|
||||
statusCycles = (unsigned)((float)frameCycles * 5.5f/100.0f);
|
||||
else
|
||||
statusCycles = (unsigned)((float)frameCycles * 48.0f/100.0f);
|
||||
|
@ -1905,7 +1908,7 @@ bool CModel3::StartThreads(void)
|
|||
return true;
|
||||
|
||||
// Create synchronization objects
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
ppcBrdThreadSync = CThread::CreateSemaphore(0);
|
||||
if (ppcBrdThreadSync == NULL)
|
||||
|
@ -1938,7 +1941,7 @@ bool CModel3::StartThreads(void)
|
|||
stopThreads = false;
|
||||
|
||||
// Create PPC main board thread, if multi-threading GPU
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
ppcBrdThread = CThread::CreateThread(StartMainBoardThread, this);
|
||||
if (ppcBrdThread == NULL)
|
||||
|
@ -1971,7 +1974,7 @@ bool CModel3::StartThreads(void)
|
|||
ThreadError:
|
||||
ErrorLog("Unable to create threads and/or synchronization objects: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
DeleteThreadObjects();
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1999,7 +2002,7 @@ bool CModel3::PauseThreads(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in CModel3::PauseThreads: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2022,7 +2025,7 @@ bool CModel3::ResumeThreads(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in CModel3::ResumeThreads: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2086,7 +2089,7 @@ bool CModel3::StopThreads(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in CModel3::StopThreads: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2244,7 +2247,7 @@ int CModel3::RunMainBoardThread(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in RunMainBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2289,7 +2292,7 @@ bool CModel3::WakeSoundBoardThread(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in WakeSoundBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2373,7 +2376,7 @@ int CModel3::RunSoundBoardThread(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in RunSoundBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2429,7 +2432,7 @@ int CModel3::RunSoundBoardThreadSyncd(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in RunSoundBoardThreadSyncd: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2485,7 +2488,7 @@ int CModel3::RunDriveBoardThread(void)
|
|||
|
||||
ThreadError:
|
||||
ErrorLog("Threading error in RunDriveBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||
g_Config.multiThreaded = false;
|
||||
m_multiThreaded = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2546,13 +2549,13 @@ void CModel3::Reset(void)
|
|||
******************************************************************************/
|
||||
|
||||
// Apply patches to games
|
||||
void CModel3::Patch(void)
|
||||
static void Patch(uint8_t *crom, const Game &game)
|
||||
{
|
||||
if (!strcmp(Game->id, "scudp"))
|
||||
if (game.name == "scudp")
|
||||
{
|
||||
// Base offset of program in CROM: 0x710000
|
||||
}
|
||||
else if (!strcmp(Game->id, "lemans24"))
|
||||
else if (game.name == "lemans24")
|
||||
{
|
||||
// Base offset of program in CROM: 6473C0
|
||||
*(UINT32 *) &crom[0x6D8C4C] = 0x00000002; // comm. mode: 00=master, 01=slave, 02=satellite
|
||||
|
@ -2561,18 +2564,18 @@ void CModel3::Patch(void)
|
|||
*(UINT32 *) &crom[0x73EDD0] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x73EDC4] = 0x60000000;
|
||||
}
|
||||
else if (!strcmp(Game->id, "lostwsga"))
|
||||
else if (game.name == "lostwsga")
|
||||
{
|
||||
*(UINT32 *) &crom[0x7374f4] = 0x38840004; // an actual bug in the game code
|
||||
}
|
||||
else if (!strcmp(Game->id, "vs215") || !strcmp(Game->id, "vs215o") || !strcmp(Game->id, "vs29815"))
|
||||
else if (game.name == "vs215" || game.name == "vs215o" || game.name == "vs29815")
|
||||
{
|
||||
// VS215 is a modification of VS2 that runs on Step 1.5 hardware. I
|
||||
// suspect the code here is trying to detect the system type but am too
|
||||
// lazy to figure it out right now.
|
||||
*(UINT32 *) &crom[0x7001A8] = 0x48000000+(0xFFF01630-0xFFF001A8); // force a jump to FFF01630
|
||||
}
|
||||
else if (!strcmp(Game->id, "vs298"))
|
||||
else if (game.name == "vs298")
|
||||
{
|
||||
// Base offset of program in CROM: 600000
|
||||
// Inexplicably, at PC=AFC1C, a call is made to FC78, which is right in the middle of some
|
||||
|
@ -2581,36 +2584,36 @@ void CModel3::Patch(void)
|
|||
// Or, 300138 needs to be written with a non-zero value, it is loaded from EEPROM but is 0.
|
||||
*(UINT32 *) &crom[0x6AFC1C] = 0x60000000;
|
||||
}
|
||||
else if (!strcmp(Game->id, "srally2"))
|
||||
else if (game.name == "srally2")
|
||||
{
|
||||
*(UINT32 *) &crom[0x7C0C4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x7C0C8] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x7C0CC] = 0x60000000;
|
||||
}
|
||||
else if (!strcmp(Game->id, "harley"))
|
||||
else if (game.name == "harley")
|
||||
{
|
||||
*(UINT32 *) &crom[0x50E8D4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50E8F4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50FB84] = 0x60000000;
|
||||
}
|
||||
else if (!strcmp(Game->id, "harleyb"))
|
||||
else if (game.name == "harleyb")
|
||||
{
|
||||
*(UINT32 *) &crom[0x50ECB4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50ECD4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50FF64] = 0x60000000;
|
||||
}
|
||||
else if (!strcmp(Game->id, "swtrilgy"))
|
||||
else if (game.name == "swtrilgy")
|
||||
{
|
||||
*(UINT32 *) &crom[0xF0E48] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x043DC] = 0x48000090; // related to joystick feedback
|
||||
*(UINT32 *) &crom[0x029A0] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x02A0C] = 0x60000000;
|
||||
}
|
||||
else if (!strcmp(Game->id, "swtrilgya"))
|
||||
else if (game.name == "swtrilgya")
|
||||
{
|
||||
*(UINT32 *) &crom[0xF6DD0] = 0x60000000; // from MAME
|
||||
}
|
||||
else if (!strcmp(Game->id, "eca") || !strcmp(Game->id, "ecax"))
|
||||
else if (game.name == "eca" || game.name == "ecax")
|
||||
{
|
||||
*(UINT32 *) &crom[0x535580] = 0x60000000;
|
||||
//*(UINT32 *) &crom[0x5023B4] = 0x60000000;
|
||||
|
@ -2660,89 +2663,98 @@ static void Reverse32(uint8_t *buf, size_t size)
|
|||
// 64-bit magic number used to detect loading of optional ROMs
|
||||
#define MAGIC_NUMBER 0x4C444D5245505553ULL
|
||||
|
||||
const struct GameInfo * CModel3::GetGameInfo(void)
|
||||
const Game &CModel3::GetGame() const
|
||||
{
|
||||
return Game;
|
||||
return m_game;
|
||||
}
|
||||
|
||||
// Stepping-dependent parameters (MPC10x type, etc.) are initialized here
|
||||
bool CModel3::LoadROMSet(const struct GameInfo *GameList, const char *zipFile)
|
||||
bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
|
||||
{
|
||||
struct ROMMap Map[] =
|
||||
m_game = Game();
|
||||
|
||||
/*
|
||||
* Copy in ROM data with mirroring as necessary for the following cases:
|
||||
*
|
||||
* - VROM: 64MB. If <= 32MB, mirror to high 32MB.
|
||||
* - Banked CROM: 128MB. If <= 64MB, mirror to high 64MB.
|
||||
* - Fixed CROM: 8MB. If < 8MB, loaded only in high part of space and low
|
||||
* part is a mirror of (banked) CROM0.
|
||||
* - Sample ROM: 16MB. If <= 8MB, mirror to high 8MB.
|
||||
*
|
||||
* ROMs are released after being loaded.
|
||||
*/
|
||||
if (rom_set.get_rom("vrom").size <= 32*0x100000)
|
||||
{
|
||||
{ "CROM", crom },
|
||||
{ "CROMxx", &crom[0x800000] },
|
||||
{ "VROM", vrom },
|
||||
{ "SndProg", soundROM },
|
||||
{ "Samples", sampleROM },
|
||||
{ "DSBProg", dsbROM },
|
||||
{ "DSBMPEG", mpegROM },
|
||||
{ "DriveBd", driveROM },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
PPC_CONFIG PPCConfig;
|
||||
|
||||
// Magic numbers to detect if optional ROMs are loaded
|
||||
*(UINT64 *) driveROM = MAGIC_NUMBER;
|
||||
|
||||
// Load game
|
||||
Game = LoadROMSetFromZIPFile(Map, GameList, zipFile, true);
|
||||
if (NULL == Game)
|
||||
return ErrorLog("Failed to load ROM set.");
|
||||
|
||||
// Perform mirroring as necessary
|
||||
if (Game->vromSize < 0x4000000) // VROM is actually 64 MB
|
||||
CopyRegion(vrom, Game->vromSize, 0x4000000, vrom, Game->vromSize);
|
||||
if (Game->cromSize < 0x800000) // low part of fixed CROM region contains CROM0
|
||||
CopyRegion(crom, 0, 0x800000-Game->cromSize, &crom[0x800000], 0x800000);
|
||||
if (Game->mirrorLow64MB) // for games w/ 64 MB or less banked CROM, mirror to upper 128 MB
|
||||
CopyRegion(&crom[0x800000], 0x4000000, 0x8000000, &crom[0x800000], 0x4000000);
|
||||
if (Game->sampleSize < 0x1000000) // if less than 16 MB of sample ROMs, mirror
|
||||
CopyRegion(sampleROM, 0x800000, 0x1000000, sampleROM, 0x800000);
|
||||
|
||||
// Byte reverse the PowerPC ROMs (convert to little endian words)
|
||||
Reverse32(crom, 0x800000+0x8000000);
|
||||
|
||||
// Byte swap sound board 68K ROMs (convert to little endian words)
|
||||
Reverse16(soundROM, 0x80000);
|
||||
Reverse16(sampleROM, 0x1000000);
|
||||
|
||||
// Initialize CPU and configure hardware (CPU speed is set in Init())
|
||||
if (Game->step >= 0x20) // Step 2.0+
|
||||
{
|
||||
PPCConfig.pvr = PPC_MODEL_603R; // 166 MHz
|
||||
PPCConfig.bus_frequency = BUS_FREQUENCY_66MHZ;
|
||||
PPCConfig.bus_frequency_multiplier = 0x25; // 2.5X multiplier
|
||||
PCIBridge.SetModel(0x106); // MPC106
|
||||
}
|
||||
else if (Game->step == 0x15) // Step 1.5
|
||||
{
|
||||
PPCConfig.pvr = PPC_MODEL_603E; // 100 MHz
|
||||
PPCConfig.bus_frequency = BUS_FREQUENCY_66MHZ;
|
||||
PPCConfig.bus_frequency_multiplier = 0x15; // 1.5X multiplier
|
||||
if (!strcmp(Game->id, "scudp1")) // some Step 1.x games use MPC106
|
||||
PCIBridge.SetModel(0x106);
|
||||
else
|
||||
PCIBridge.SetModel(0x105); // MPC105
|
||||
}
|
||||
else if (Game->step == 0x10) // Step 1.0
|
||||
{
|
||||
PPCConfig.pvr = PPC_MODEL_603R; // 66 MHz
|
||||
PPCConfig.bus_frequency = BUS_FREQUENCY_66MHZ;
|
||||
PPCConfig.bus_frequency_multiplier = 0x10; // 1X multiplier
|
||||
if (!strcmp(Game->id, "bass") || !strcmp(Game->id, "getbass")) // some Step 1.x games use MPC106
|
||||
PCIBridge.SetModel(0x106);
|
||||
else
|
||||
PCIBridge.SetModel(0x105); // MPC105
|
||||
rom_set.get_rom("vrom").CopyTo(&vrom[0], 32*100000);
|
||||
rom_set.get_rom("vrom").CopyTo(&vrom[32*0x100000], 32*0x100000);
|
||||
}
|
||||
else
|
||||
return ErrorLog("Game uses an unrecognized stepping (%d.%d), cannot configure Model 3.", (Game->step>>4)&0xF, Game->step&0xF);
|
||||
rom_set.get_rom("vrom").CopyTo(vrom, 64*0x100000);
|
||||
if (rom_set.get_rom("banked_crom").size <= 64*0x100000)
|
||||
{
|
||||
rom_set.get_rom("banked_crom").CopyTo(&crom[8*0x100000 + 0], 64*0x100000);
|
||||
rom_set.get_rom("banked_crom").CopyTo(&crom[8*0x100000 + 64*0x100000], 64*0x100000);
|
||||
}
|
||||
else
|
||||
rom_set.get_rom("banked_crom").CopyTo(&crom[8*0x100000 + 0], 128*0x100000);
|
||||
size_t crom_size = rom_set.get_rom("crom").size;
|
||||
rom_set.get_rom("crom").CopyTo(&crom[8*0x100000 - crom_size], crom_size);
|
||||
if (crom_size < 8*0x100000)
|
||||
rom_set.get_rom("banked_crom").CopyTo(&crom[0], 8*0x100000 - crom_size);
|
||||
if (rom_set.get_rom("sound_samples").size <= 8*0x100000)
|
||||
{
|
||||
rom_set.get_rom("sound_samples").CopyTo(&sampleROM[0], 8*0x100000);
|
||||
rom_set.get_rom("sound_samples").CopyTo(&sampleROM[8*0x100000], 8*0x100000);
|
||||
}
|
||||
else
|
||||
rom_set.get_rom("sound_samples").CopyTo(sampleROM, 16*0x100000);
|
||||
rom_set.get_rom("sound_program").CopyTo(soundROM, 512*1024);
|
||||
rom_set.get_rom("mpeg_program").CopyTo(dsbROM, 128*1024);
|
||||
rom_set.get_rom("mpeg_music").CopyTo(mpegROM, 16*0x100000);
|
||||
rom_set.get_rom("driveboard_program").CopyTo(driveROM, 64*1024);
|
||||
|
||||
// Convert PowerPC and 68K ROMs to little endian words
|
||||
Util::FlipEndian32(crom, 8*0x100000 + 128*0x100000);
|
||||
Util::FlipEndian16(soundROM, 512*1024);
|
||||
Util::FlipEndian16(sampleROM, 16*0x100000);
|
||||
|
||||
GPU.SetStep(Game->step);
|
||||
|
||||
ppc_init(&PPCConfig);
|
||||
// Initialize CPU
|
||||
PPC_CONFIG ppc_config;
|
||||
if (game.stepping == "2.0" || game.stepping == "2.1")
|
||||
{
|
||||
ppc_config.pvr = PPC_MODEL_603R; // 166 MHz
|
||||
ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ;
|
||||
ppc_config.bus_frequency_multiplier = 0x25; // 2.5X multiplier
|
||||
PCIBridge.SetModel(0x106); // MPC106
|
||||
}
|
||||
else if (game.stepping == "1.5")
|
||||
{
|
||||
ppc_config.pvr = PPC_MODEL_603E; // 100 MHz
|
||||
ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ;
|
||||
ppc_config.bus_frequency_multiplier = 0x15; // 1.5X multiplier
|
||||
if (game.name == "scudp1")
|
||||
PCIBridge.SetModel(0x106); // some Step 1.x games use MPC106
|
||||
else
|
||||
PCIBridge.SetModel(0x105); // MPC105
|
||||
}
|
||||
else if (game.stepping == "1.0")
|
||||
{
|
||||
ppc_config.pvr = PPC_MODEL_603R; // 66 MHz
|
||||
ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ;
|
||||
ppc_config.bus_frequency_multiplier = 0x10; // 1X multiplier
|
||||
if (game.name == "bass" || game.name == "getbass")
|
||||
PCIBridge.SetModel(0x106); // some Step 1.x games use MPC106
|
||||
else
|
||||
PCIBridge.SetModel(0x105); // MPC105
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorLog("Cannot configure Model 3 because game uses unrecognized stepping (%s).", game.stepping.c_str());
|
||||
return FAIL;
|
||||
}
|
||||
ppc_init(&ppc_config);
|
||||
ppc_attach_bus(this);
|
||||
|
||||
PPCFetchRegions[0].start = 0;
|
||||
PPCFetchRegions[0].end = 0x007FFFFF;
|
||||
PPCFetchRegions[0].ptr = (UINT32 *) ram;
|
||||
|
@ -2752,67 +2764,71 @@ bool CModel3::LoadROMSet(const struct GameInfo *GameList, const char *zipFile)
|
|||
PPCFetchRegions[2].start = 0;
|
||||
PPCFetchRegions[2].end = 0;
|
||||
PPCFetchRegions[2].ptr = NULL;
|
||||
|
||||
ppc_set_fetch(PPCFetchRegions);
|
||||
|
||||
// DSB board (if present)
|
||||
if (Game->mpegBoard == 1) // Z80 board, do not byte swap program ROM
|
||||
// Initialize Real3D
|
||||
int stepping = ((game.stepping[0] - '0') << 4) | (game.stepping[2] - '0');
|
||||
GPU.SetStepping(stepping);
|
||||
|
||||
// MPEG board (if present)
|
||||
if (rom_set.get_rom("mpeg_program").size)
|
||||
{
|
||||
DSB = new(std::nothrow) CDSB1();
|
||||
if (NULL == DSB)
|
||||
return ErrorLog("Insufficient memory for Digital Sound Board object.");
|
||||
if (OKAY != DSB->Init(dsbROM,mpegROM))
|
||||
return FAIL;
|
||||
}
|
||||
else if (Game->mpegBoard == 2) // 68K board
|
||||
{
|
||||
Reverse16(dsbROM, 0x20000); // byte swap program ROM
|
||||
DSB = new(std::nothrow) CDSB2();
|
||||
if (NULL == DSB)
|
||||
return ErrorLog("Insufficient memory for Digital Sound Board object.");
|
||||
if (OKAY != DSB->Init(dsbROM,mpegROM))
|
||||
if (game.mpeg_board == "DSB1")
|
||||
{
|
||||
DSB = new(std::nothrow) CDSB1(m_config);
|
||||
if (NULL == DSB)
|
||||
return ErrorLog("Insufficient memory for Digital Sound Board object.");
|
||||
}
|
||||
else if (game.mpeg_board == "DSB2")
|
||||
{
|
||||
Util::FlipEndian16(dsbROM, 128*1024); // 68K program needs to be byte swapped
|
||||
DSB = new(std::nothrow) CDSB2(m_config);
|
||||
if (NULL == DSB)
|
||||
return ErrorLog("Insufficient memory for Digital Sound Board object.");
|
||||
}
|
||||
else if (game.mpeg_board.empty())
|
||||
ErrorLog("No MPEG board type defined in game XML for MPEG ROMs.");
|
||||
else
|
||||
ErrorLog("Unknown MPEG board type '%s'. Only 'DSB1' and 'DSB2' are supported.", game.mpeg_board.c_str());
|
||||
if (DSB && OKAY != DSB->Init(dsbROM, mpegROM))
|
||||
return FAIL;
|
||||
}
|
||||
SoundBoard.AttachDSB(DSB);
|
||||
|
||||
// Drive board (if present)
|
||||
if (Game->driveBoard)
|
||||
if (rom_set.get_rom("driveboard_program").size)
|
||||
{
|
||||
// Was the optional drive board ROM loaded?
|
||||
if (MAGIC_NUMBER != *(UINT64 *) driveROM) // magic number overwritten by ROM
|
||||
{
|
||||
if (DriveBoard.Init(driveROM))
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
DriveBoard.Init(NULL);
|
||||
if (DriveBoard.Init(driveROM))
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
DriveBoard.Init(NULL); // disable
|
||||
DriveBoard.Init(NULL);
|
||||
|
||||
// Security board encryption device
|
||||
m_cryptoDevice.Init(Game->encryptionKey, std::bind(&CModel3::ReadSecurityRAM, this, std::placeholders::_1));
|
||||
m_cryptoDevice.Init(game.encryption_key, std::bind(&CModel3::ReadSecurityRAM, this, std::placeholders::_1));
|
||||
|
||||
// Apply ROM patches
|
||||
Patch();
|
||||
//TODO: place these in XML
|
||||
Patch(crom, game);
|
||||
|
||||
// Print game information
|
||||
std::set<std::string> extraHw;
|
||||
if (Game->mpegBoard)
|
||||
extraHw.insert(Util::Format() << "Digital Sound Board (Type " << Game->mpegBoard << ")");
|
||||
if (Game->driveBoard)
|
||||
extraHw.insert("Drive Board");
|
||||
if (Game->encryptionKey)
|
||||
extraHw.insert("Security Board");
|
||||
printf(" Title: %s\n", Game->title);
|
||||
printf(" ROM Set: %s\n", Game->id);
|
||||
printf(" Developer: %s\n", Game->mfgName);
|
||||
printf(" Year: %d\n", Game->year);
|
||||
printf(" Step: %d.%d\n", (Game->step>>4)&0xF, Game->step&0xF);
|
||||
if (!extraHw.empty())
|
||||
printf(" Extra Hardware: %s\n", Util::Format(", ").Join(extraHw).str().c_str());
|
||||
printf("\n");
|
||||
std::set<std::string> extra_hw;
|
||||
if (DSB)
|
||||
extra_hw.insert(Util::Format() << "Digital Sound Board (Type " << game.mpeg_board << ")");
|
||||
if (rom_set.get_rom("driveboard_program").size)
|
||||
extra_hw.insert("Drive Board");
|
||||
if (game.encryption_key)
|
||||
extra_hw.insert("Security Board");
|
||||
std::cout << " Title: " << game.title << std::endl;
|
||||
std::cout << " ROM Set: " << game.name << std::endl;
|
||||
std::cout << " Developer: " << game.manufacturer << std::endl;
|
||||
std::cout << " Year: " << game.year << std::endl;
|
||||
std::cout << " Stepping: " << game.stepping << std::endl;
|
||||
if (!extra_hw.empty())
|
||||
std::cout << " Extra Hardware: " << Util::Format(", ").Join(extra_hw) << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
m_game = game;
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
@ -2827,7 +2843,7 @@ void CModel3::AttachInputs(CInputs *InputsPtr)
|
|||
Inputs = InputsPtr;
|
||||
|
||||
if (DriveBoard.IsAttached())
|
||||
DriveBoard.AttachInputs(Inputs, Game->inputFlags);
|
||||
DriveBoard.AttachInputs(Inputs, m_game.inputs);
|
||||
|
||||
DebugLog("Model 3 attached inputs\n");
|
||||
}
|
||||
|
@ -2835,7 +2851,7 @@ void CModel3::AttachInputs(CInputs *InputsPtr)
|
|||
void CModel3::AttachOutputs(COutputs *OutputsPtr)
|
||||
{
|
||||
Outputs = OutputsPtr;
|
||||
Outputs->SetGame(Game);
|
||||
Outputs->SetGame(m_game);
|
||||
Outputs->Attached();
|
||||
|
||||
if (DriveBoard.IsAttached())
|
||||
|
@ -2853,6 +2869,7 @@ bool CModel3::Init(void)
|
|||
memoryPool = new(std::nothrow) UINT8[MEMORY_POOL_SIZE];
|
||||
if (NULL == memoryPool)
|
||||
return ErrorLog("Insufficient memory for Model 3 object (needs %1.1f MB).", memSizeMB);
|
||||
memset(memoryPool, 0, MEMORY_POOL_SIZE);
|
||||
|
||||
// Set up pointers
|
||||
ram = &memoryPool[OFFSET_RAM];
|
||||
|
@ -2901,13 +2918,19 @@ CDriveBoard *CModel3::GetDriveBoard(void)
|
|||
return &DriveBoard;
|
||||
}
|
||||
|
||||
CModel3::CModel3(void)
|
||||
CModel3::CModel3(const Util::Config::Node &config)
|
||||
: m_config(config),
|
||||
m_multiThreaded(config["MultiThreaded"].ValueAs<bool>()),
|
||||
m_gpuMultiThreaded(config["GPUMultiThreaded"].ValueAs<bool>()),
|
||||
TileGen(config),
|
||||
GPU(config),
|
||||
SoundBoard(config),
|
||||
DriveBoard(config)
|
||||
{
|
||||
// Initialize pointers so dtor can know whether to free them
|
||||
memoryPool = NULL;
|
||||
|
||||
// Various uninitialized pointers
|
||||
Game = NULL;
|
||||
Inputs = NULL;
|
||||
Outputs = NULL;
|
||||
ram = NULL;
|
||||
|
@ -2995,7 +3018,6 @@ CModel3::~CModel3(void)
|
|||
DSB = NULL;
|
||||
}
|
||||
|
||||
Game = NULL;
|
||||
Inputs = NULL;
|
||||
Outputs = NULL;
|
||||
ram = NULL;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "Model3/IEmulator.h"
|
||||
#include "Model3/Crypto.h"
|
||||
#include "Util/NewConfig.h"
|
||||
|
||||
/*
|
||||
* FrameTimings
|
||||
|
@ -47,44 +48,6 @@ struct FrameTimings
|
|||
UINT32 frameTicks;
|
||||
};
|
||||
|
||||
/*
|
||||
* CModel3Config:
|
||||
*
|
||||
* Settings used by CModel3.
|
||||
*/
|
||||
class CModel3Config
|
||||
{
|
||||
public:
|
||||
bool multiThreaded; // Multi-threaded (enabled if true)
|
||||
bool gpuMultiThreaded; // Multi-threaded rendering (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 50 MHz.");
|
||||
f = 50;
|
||||
}
|
||||
ppcFrequency = f*1000000;
|
||||
}
|
||||
inline unsigned GetPowerPCFrequency(void)
|
||||
{
|
||||
return ppcFrequency/1000000;
|
||||
}
|
||||
|
||||
// Defaults
|
||||
CModel3Config(void)
|
||||
{
|
||||
multiThreaded = true; // enable by default
|
||||
gpuMultiThreaded = true; // enable by default
|
||||
ppcFrequency = 50*1000000; // 50 MHz
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned ppcFrequency; // in Hz
|
||||
};
|
||||
|
||||
/*
|
||||
* CModel3:
|
||||
*
|
||||
|
@ -110,7 +73,7 @@ public:
|
|||
void RunFrame(void);
|
||||
void RenderFrame(void);
|
||||
void Reset(void);
|
||||
const struct GameInfo * GetGameInfo(void);
|
||||
const Game &GetGame(void) const;
|
||||
void AttachRenderers(CRender2D *Render2DPtr, IRender3D *Render3DPtr);
|
||||
void AttachInputs(CInputs *InputsPtr);
|
||||
void AttachOutputs(COutputs *OutputsPtr);
|
||||
|
@ -131,20 +94,19 @@ public:
|
|||
void Write64(UINT32 addr, UINT64 data);
|
||||
|
||||
/*
|
||||
* LoadROMSet(GameList, zipFile):
|
||||
* LoadGame(game, rom_set):
|
||||
*
|
||||
* Loads a complete ROM set from the specified ZIP archive.
|
||||
*
|
||||
* NOTE: Command line settings will not have been applied here yet.
|
||||
* Loads a game, copying in the provided ROMs and setting the hardware
|
||||
* stepping.
|
||||
*
|
||||
* Parameters:
|
||||
* GameList List of all supported games and their ROMs.
|
||||
* zipFile ZIP file to load from.
|
||||
* game Game information.
|
||||
* rom_set ROMs.
|
||||
*
|
||||
* Returns:
|
||||
* OKAY if successful, FAIL otherwise. Prints errors.
|
||||
*/
|
||||
bool LoadROMSet(const struct GameInfo *GameList, const char *zipFile);
|
||||
bool LoadGame(const Game &game, const ROMSet &rom_set);
|
||||
|
||||
/*
|
||||
* GetSoundBoard(void):
|
||||
|
@ -181,15 +143,19 @@ public:
|
|||
FrameTimings GetTimings(void);
|
||||
|
||||
/*
|
||||
* CModel3(void):
|
||||
* CModel3(config):
|
||||
* ~CModel3(void):
|
||||
*
|
||||
* Constructor and destructor for Model 3 class. Constructor performs a
|
||||
* bare-bones initialization of object; does not perform any memory
|
||||
* allocation or any actions that can fail. The destructor will deallocate
|
||||
* memory and free resources used by the object (and its child objects).
|
||||
*
|
||||
* Paramters:
|
||||
* config Run-time configuration. The reference should be held because
|
||||
* this changes at run-time.
|
||||
*/
|
||||
CModel3(void);
|
||||
CModel3(const Util::Config::Node &config);
|
||||
~CModel3(void);
|
||||
|
||||
/*
|
||||
|
@ -206,7 +172,6 @@ private:
|
|||
void SetCROMBank(unsigned idx);
|
||||
UINT8 ReadSystemRegister(unsigned reg);
|
||||
void WriteSystemRegister(unsigned reg, UINT8 data);
|
||||
void Patch(void);
|
||||
|
||||
void RunMainBoardFrame(void); // Runs PPC main board for a frame
|
||||
void SyncGPUs(void); // Sync's up GPUs in preparation for rendering - must be called when PPC is not running
|
||||
|
@ -230,8 +195,13 @@ private:
|
|||
int RunSoundBoardThreadSyncd(void); // Runs sound board thread (sync'd in step with render thread)
|
||||
int RunDriveBoardThread(void); // Runs drive board thread (sync'd in step with render thread)
|
||||
|
||||
// Runtime configuration
|
||||
const Util::Config::Node &m_config;
|
||||
bool m_multiThreaded;
|
||||
bool m_gpuMultiThreaded;
|
||||
|
||||
// Game and hardware information
|
||||
const struct GameInfo *Game;
|
||||
Game m_game;
|
||||
|
||||
// Game inputs and outputs
|
||||
CInputs *Inputs;
|
||||
|
|
|
@ -90,11 +90,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
const struct GameInfo * GetGameInfo(void)
|
||||
const Game &GetGame(void)
|
||||
{
|
||||
return m_game;
|
||||
}
|
||||
|
||||
bool LoadGame(const Game &game)
|
||||
{
|
||||
//TODO: write me
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
//TODO: replicate this logic in LoadGame()
|
||||
bool LoadROMSet(const struct GameInfo *gameList, const char *zipFile)
|
||||
{
|
||||
// Load ROM
|
||||
|
|
|
@ -111,7 +111,7 @@ void CReal3D::LoadState(CBlockFile *SaveState)
|
|||
SaveState->Read(memoryPool, MEM_POOL_SIZE_RW);
|
||||
|
||||
// If multi-threaded, update read-only snapshots too
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
UpdateSnapshots(true);
|
||||
Render3D->UploadTextures(0, 0, 0, 2048, 2048);
|
||||
SaveState->Read(&fifoIdx, sizeof(fifoIdx));
|
||||
|
@ -159,7 +159,7 @@ uint32_t CReal3D::SyncSnapshots(void)
|
|||
commandPortWrittenRO = commandPortWritten;
|
||||
commandPortWritten = false;
|
||||
|
||||
if (!g_Config.gpuMultiThreaded)
|
||||
if (!m_gpuMultiThreaded)
|
||||
return 0;
|
||||
|
||||
// Update read-only queue
|
||||
|
@ -230,7 +230,7 @@ uint32_t CReal3D::UpdateSnapshots(bool copyWhole)
|
|||
void CReal3D::BeginFrame(void)
|
||||
{
|
||||
// If multi-threaded, perform now any queued texture uploads to renderer before rendering begins
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
for (const auto &it : queuedUploadTexturesRO) {
|
||||
Render3D->UploadTextures(it.level, it.x, it.y, it.width, it.height);
|
||||
|
@ -632,7 +632,7 @@ void CReal3D::StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigne
|
|||
{
|
||||
for (uint32_t xx = 0; xx < 8; xx++)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(textureRAMDirty, destOffset * 2);
|
||||
textureRAM[destOffset++] = texData[decode[(yy*8+xx)^1]];
|
||||
}
|
||||
|
@ -668,11 +668,11 @@ void CReal3D::StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigne
|
|||
{
|
||||
uint8_t byte1 = texData[decode[(yy^1)*8+((xx+0)^1)]/2]>>8;
|
||||
uint8_t byte2 = texData[decode[(yy^1)*8+((xx+1)^1)]/2]&0xFF;
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(textureRAMDirty, destOffset * 2);
|
||||
StoreTexelByte(&textureRAM[destOffset], byteSelect, byte1);
|
||||
++destOffset;
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(textureRAMDirty, destOffset * 2);
|
||||
StoreTexelByte(&textureRAM[destOffset], byteSelect, byte2);
|
||||
++destOffset;
|
||||
|
@ -686,7 +686,7 @@ void CReal3D::StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigne
|
|||
|
||||
// Signal to renderer that textures have changed
|
||||
// TO-DO: mipmaps? What if a game writes non-mipmap textures to mipmap area?
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
// If multi-threaded, then queue calls to UploadTextures for render thread to perform at beginning of next frame
|
||||
QueuedUploadTextures upl;
|
||||
|
@ -866,21 +866,21 @@ void CReal3D::WriteTexturePort(unsigned reg, uint32_t data)
|
|||
|
||||
void CReal3D::WriteLowCullingRAM(uint32_t addr, uint32_t data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(cullingRAMLoDirty, addr);
|
||||
cullingRAMLo[addr/4] = data;
|
||||
}
|
||||
|
||||
void CReal3D::WriteHighCullingRAM(uint32_t addr, uint32_t data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(cullingRAMHiDirty, addr);
|
||||
cullingRAMHi[addr/4] = data;
|
||||
}
|
||||
|
||||
void CReal3D::WritePolygonRAM(uint32_t addr, uint32_t data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(polyRAMDirty, addr);
|
||||
polyRAM[addr/4] = data;
|
||||
}
|
||||
|
@ -958,7 +958,7 @@ void CReal3D::Reset(void)
|
|||
dmaStatus = 0;
|
||||
dmaUnknownReg = 0;
|
||||
|
||||
unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
unsigned memSize = (m_gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
memset(memoryPool, 0, memSize);
|
||||
memset(m_vromTextureFIFO, 0, sizeof(m_vromTextureFIFO));
|
||||
|
||||
|
@ -974,20 +974,20 @@ void CReal3D::AttachRenderer(IRender3D *Render3DPtr)
|
|||
{
|
||||
Render3D = Render3DPtr;
|
||||
|
||||
// If multi-threaded, attach read-only snapshots to renderer instead of real ones
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
// If mult-threaded, attach read-only snapshots to renderer instead of real ones
|
||||
if (m_gpuMultiThreaded)
|
||||
Render3D->AttachMemory(cullingRAMLoRO, cullingRAMHiRO, polyRAMRO, vrom, textureRAMRO);
|
||||
else
|
||||
Render3D->AttachMemory(cullingRAMLo, cullingRAMHi, polyRAM, vrom, textureRAM);
|
||||
|
||||
Render3D->SetStep(step);
|
||||
Render3D->SetStepping(step);
|
||||
|
||||
DebugLog("Real3D attached a Render3D object\n");
|
||||
}
|
||||
|
||||
void CReal3D::SetStep(int stepID)
|
||||
void CReal3D::SetStepping(int stepping)
|
||||
{
|
||||
step = stepID;
|
||||
step = stepping;
|
||||
if ((step!=0x10) && (step!=0x15) && (step!=0x20) && (step!=0x21))
|
||||
{
|
||||
DebugLog("Real3D: Unrecognized stepping: %d.%d\n", (step>>4)&0xF, step&0xF);
|
||||
|
@ -1002,14 +1002,14 @@ void CReal3D::SetStep(int stepID)
|
|||
|
||||
// Pass to renderer
|
||||
if (Render3D != NULL)
|
||||
Render3D->SetStep(step);
|
||||
Render3D->SetStepping(step);
|
||||
|
||||
DebugLog("Real3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF);
|
||||
}
|
||||
|
||||
bool CReal3D::Init(const uint8_t *vromPtr, IBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit)
|
||||
{
|
||||
uint32_t memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
uint32_t memSize = (m_config["GPUMultiThreaded"].ValueAs<bool>() ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
float memSizeMB = (float)memSize/(float)0x100000;
|
||||
|
||||
// IRQ and bus objects
|
||||
|
@ -1030,7 +1030,7 @@ bool CReal3D::Init(const uint8_t *vromPtr, IBus *BusObjectPtr, CIRQ *IRQObjectPt
|
|||
textureFIFO = (uint32_t *) &memoryPool[OFFSET_TEXFIFO];
|
||||
|
||||
// If multi-threaded, set up pointers for read-only snapshots and dirty page arrays too
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
cullingRAMLoRO = (uint32_t *) &memoryPool[OFFSET_8C_RO];
|
||||
cullingRAMHiRO = (uint32_t *) &memoryPool[OFFSET_8E_RO];
|
||||
|
@ -1049,7 +1049,9 @@ bool CReal3D::Init(const uint8_t *vromPtr, IBus *BusObjectPtr, CIRQ *IRQObjectPt
|
|||
return OKAY;
|
||||
}
|
||||
|
||||
CReal3D::CReal3D(void)
|
||||
CReal3D::CReal3D(const Util::Config::Node &config)
|
||||
: m_config(config),
|
||||
m_gpuMultiThreaded(config["GPUMultiThreaded"].ValueAs<bool>())
|
||||
{
|
||||
Render3D = NULL;
|
||||
memoryPool = NULL;
|
||||
|
@ -1117,6 +1119,7 @@ CReal3D::~CReal3D(void)
|
|||
printf("unable to dump %s\n", "texram");
|
||||
Util::WriteSurfaceToBMP<Util::A1RGB5>("textures.bmp", reinterpret_cast<uint8_t *>(textureRAM), 2048, 2048, false);
|
||||
#endif
|
||||
Util::WriteSurfaceToBMP<Util::A1RGB5>("textures.bmp", reinterpret_cast<uint8_t *>(textureRAM), 2048, 2048, false);
|
||||
|
||||
Render3D = NULL;
|
||||
if (memoryPool != NULL)
|
||||
|
|
|
@ -334,17 +334,17 @@ public:
|
|||
void AttachRenderer(IRender3D *Render3DPtr);
|
||||
|
||||
/*
|
||||
* SetStep(stepID):
|
||||
* SetStepping(stepping):
|
||||
*
|
||||
* Sets the Model 3 hardware stepping, which also determines the Real3D
|
||||
* functionality. The default is Step 1.0. This should be called prior to
|
||||
* any other emulation functions and after Init().
|
||||
*
|
||||
* Parameters:
|
||||
* stepID 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0,
|
||||
* or 0x21 for Step 2.1. Anything else defaults to 1.0.
|
||||
* stepping 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0, or
|
||||
* 0x21 for Step 2.1. Anything else defaults to 1.0.
|
||||
*/
|
||||
void SetStep(int stepID);
|
||||
void SetStepping(int stepping);
|
||||
|
||||
/*
|
||||
* Init(vromPtr, BusObjectPtr, IRQObjectPtr, dmaIRQBit):
|
||||
|
@ -370,12 +370,16 @@ public:
|
|||
bool Init(const uint8_t *vromPtr, IBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit);
|
||||
|
||||
/*
|
||||
* CReal3D(void):
|
||||
* CReal3D(config):
|
||||
* ~CReal3D(void):
|
||||
*
|
||||
* Constructor and destructor.
|
||||
*
|
||||
* Paramters:
|
||||
* config Run-time configuration. The reference should be held because
|
||||
* this changes at run-time.
|
||||
*/
|
||||
CReal3D(void);
|
||||
CReal3D(const Util::Config::Node &config);
|
||||
~CReal3D(void);
|
||||
|
||||
private:
|
||||
|
@ -389,6 +393,10 @@ private:
|
|||
uint32_t UpdateSnapshots(bool copyWhole);
|
||||
uint32_t UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty);
|
||||
|
||||
// Config
|
||||
const Util::Config::Node &m_config;
|
||||
const bool m_gpuMultiThreaded;
|
||||
|
||||
// Renderer attached to the Real3D
|
||||
IRender3D *Render3D;
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ void CSoundBoard::WriteMIDIPort(UINT8 data)
|
|||
bool CSoundBoard::RunFrame(void)
|
||||
{
|
||||
// Run sound board first to generate SCSP audio
|
||||
if (g_Config.emulateSound)
|
||||
if (m_config["EmulateSound"].ValueAs<bool>())
|
||||
{
|
||||
M68KSetContext(&M68K);
|
||||
SCSP_Update();
|
||||
|
@ -355,7 +355,7 @@ bool CSoundBoard::RunFrame(void)
|
|||
DSB->RunFrame(audioL, audioR);
|
||||
|
||||
// Output the audio buffers
|
||||
bool bufferFull = OutputAudio(44100/60, audioL, audioR);
|
||||
bool bufferFull = OutputAudio(44100/60, audioL, audioR, m_config["FlipStereo"].ValueAs<bool>());
|
||||
|
||||
#ifdef SUPERMODEL_LOG_AUDIO
|
||||
// Output to binary file
|
||||
|
@ -478,7 +478,7 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
|||
// Initialize SCSPs
|
||||
SCSP_SetBuffers(audioL, audioR, 44100/60);
|
||||
SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback);
|
||||
if (OKAY != SCSP_Init(2))
|
||||
if (OKAY != SCSP_Init(m_config, 2))
|
||||
return FAIL;
|
||||
SCSP_SetRAM(0, ram1);
|
||||
SCSP_SetRAM(1, ram2);
|
||||
|
@ -503,7 +503,8 @@ CDSB *CSoundBoard::GetDSB(void)
|
|||
return DSB;
|
||||
}
|
||||
|
||||
CSoundBoard::CSoundBoard(void)
|
||||
CSoundBoard::CSoundBoard(const Util::Config::Node &config)
|
||||
: m_config(config)
|
||||
{
|
||||
DSB = NULL;
|
||||
memoryPool = NULL;
|
||||
|
|
|
@ -33,50 +33,6 @@
|
|||
#include "Model3/DSB.h"
|
||||
#include "OSD/Thread.h"
|
||||
|
||||
/*
|
||||
* CSoundBoardConfig:
|
||||
*
|
||||
* Settings used by CSoundBoard.
|
||||
*/
|
||||
class CSoundBoardConfig
|
||||
{
|
||||
public:
|
||||
bool emulateSound; // sound board emulation (enabled if true)
|
||||
|
||||
// Master/slave SCSP relative balance (-100-100, with 100 meaning master volume doubled, slave silenced)
|
||||
inline void SetSCSPBalance(int bal)
|
||||
{
|
||||
if (bal > 100)
|
||||
{
|
||||
ErrorLog("Front/rear balance cannot exceed 100%%; setting to 100%%.\n");
|
||||
bal = 100;
|
||||
}
|
||||
|
||||
if (bal < -100)
|
||||
{
|
||||
ErrorLog("Front/rear balance cannot be less than -100%%; setting to -100%%.\n");
|
||||
bal = -100;
|
||||
}
|
||||
|
||||
scspBalance = bal;
|
||||
}
|
||||
|
||||
inline int GetSCSPBalance(void)
|
||||
{
|
||||
return scspBalance;
|
||||
}
|
||||
|
||||
// Defaults
|
||||
CSoundBoardConfig(void)
|
||||
{
|
||||
emulateSound = true;
|
||||
scspBalance = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int scspBalance;
|
||||
};
|
||||
|
||||
/*
|
||||
* CSoundBoard:
|
||||
*
|
||||
|
@ -211,18 +167,25 @@ public:
|
|||
bool Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr);
|
||||
|
||||
/*
|
||||
* CSoundBoard(void):
|
||||
* CSoundBoard(config):
|
||||
* ~CSoundBoard(void):
|
||||
*
|
||||
* Constructor and destructor.
|
||||
*
|
||||
* Paramters:
|
||||
* config Run-time configuration. The reference should be held because
|
||||
* this changes at run-time.
|
||||
*/
|
||||
CSoundBoard(void);
|
||||
CSoundBoard(const Util::Config::Node &config);
|
||||
~CSoundBoard(void);
|
||||
|
||||
private:
|
||||
// Private helper functions
|
||||
void UpdateROMBanks(void);
|
||||
|
||||
// Config
|
||||
const Util::Config::Node &m_config;
|
||||
|
||||
// Digital Sound Board
|
||||
CDSB *DSB;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ void CTileGen::LoadState(CBlockFile *SaveState)
|
|||
RecomputePalettes();
|
||||
|
||||
// If multi-threaded, update read-only snapshots too
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
UpdateSnapshots(true);
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ void CTileGen::EndVBlank(void)
|
|||
void CTileGen::RecomputePalettes(void)
|
||||
{
|
||||
// Writing the colors forces palettes to be computed
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
for (unsigned colorAddr = 0; colorAddr < 32768*4; colorAddr += 4 )
|
||||
{
|
||||
|
@ -169,7 +169,7 @@ UINT32 CTileGen::SyncSnapshots(void)
|
|||
recomputePalettes = false;
|
||||
}
|
||||
|
||||
if (!g_Config.gpuMultiThreaded)
|
||||
if (!m_gpuMultiThreaded)
|
||||
return 0;
|
||||
|
||||
// Update read-only snapshots
|
||||
|
@ -274,7 +274,7 @@ UINT32 CTileGen::ReadRAM32(unsigned addr)
|
|||
|
||||
void CTileGen::WriteRAM32(unsigned addr, UINT32 data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
MARK_DIRTY(vramDirty, addr);
|
||||
*(UINT32 *) &vram[addr] = data;
|
||||
|
||||
|
@ -285,7 +285,7 @@ void CTileGen::WriteRAM32(unsigned addr, UINT32 data)
|
|||
unsigned color = addr/4; // color index
|
||||
|
||||
// Same address in both palettes must be marked dirty
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
MARK_DIRTY(palDirty[0], addr);
|
||||
MARK_DIRTY(palDirty[1], addr);
|
||||
|
@ -333,7 +333,7 @@ void CTileGen::InitPalette(void)
|
|||
for (int i = 0; i < 0x20000/4; i++)
|
||||
{
|
||||
WritePalette(i, *(UINT32 *) &vram[0x100000 + i*4]);
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
palRO[0][i] = pal[0][i];
|
||||
palRO[1][i] = pal[1][i];
|
||||
|
@ -444,7 +444,7 @@ void CTileGen::WriteRegister(unsigned reg, UINT32 data)
|
|||
|
||||
void CTileGen::Reset(void)
|
||||
{
|
||||
unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
unsigned memSize = (m_gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
memset(memoryPool, 0, memSize);
|
||||
memset(regs, 0, sizeof(regs));
|
||||
memset(regsRO, 0, sizeof(regsRO));
|
||||
|
@ -465,7 +465,7 @@ void CTileGen::AttachRenderer(CRender2D *Render2DPtr)
|
|||
Render2D = Render2DPtr;
|
||||
|
||||
// If multi-threaded, attach read-only snapshots to renderer instead of real ones
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
Render2D->AttachVRAM(vramRO);
|
||||
Render2D->AttachPalette((const UINT32 **)palRO);
|
||||
|
@ -484,7 +484,7 @@ void CTileGen::AttachRenderer(CRender2D *Render2DPtr)
|
|||
|
||||
bool CTileGen::Init(CIRQ *IRQObjectPtr)
|
||||
{
|
||||
unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
unsigned memSize = (m_gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
float memSizeMB = (float)memSize/(float)0x100000;
|
||||
|
||||
// Allocate all memory for all TileGen RAM regions
|
||||
|
@ -498,7 +498,7 @@ bool CTileGen::Init(CIRQ *IRQObjectPtr)
|
|||
pal[1] = (UINT32 *) &memoryPool[OFFSET_PAL_B];
|
||||
|
||||
// If multi-threaded, set up pointers for read-only snapshots and dirty page arrays too
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
if (m_gpuMultiThreaded)
|
||||
{
|
||||
vramRO = (UINT8 *) &memoryPool[OFFSET_VRAM_RO];
|
||||
palRO[0] = (UINT32 *) &memoryPool[OFFSET_PAL_RO_A];
|
||||
|
@ -515,7 +515,9 @@ bool CTileGen::Init(CIRQ *IRQObjectPtr)
|
|||
return OKAY;
|
||||
}
|
||||
|
||||
CTileGen::CTileGen(void)
|
||||
CTileGen::CTileGen(const Util::Config::Node &config)
|
||||
: m_config(config),
|
||||
m_gpuMultiThreaded(config["GPUMultiThreaded"].ValueAs<bool>())
|
||||
{
|
||||
IRQ = NULL;
|
||||
memoryPool = NULL;
|
||||
|
|
|
@ -238,12 +238,16 @@ public:
|
|||
bool Init(CIRQ *IRQObjectPtr);
|
||||
|
||||
/*
|
||||
* CTileGen(void):
|
||||
* CTileGen(config):
|
||||
* ~CTileGen(void):
|
||||
*
|
||||
* Constructor and destructor.
|
||||
*
|
||||
* Paramters:
|
||||
* config Run-time configuration. The reference should be held because
|
||||
* this changes at run-time.
|
||||
*/
|
||||
CTileGen(void);
|
||||
CTileGen(const Util::Config::Node &config);
|
||||
~CTileGen(void);
|
||||
|
||||
private:
|
||||
|
@ -253,7 +257,10 @@ private:
|
|||
void WritePalette(unsigned color, UINT32 data);
|
||||
UINT32 UpdateSnapshots(bool copyWhole);
|
||||
UINT32 UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned size, UINT8 *dirty);
|
||||
|
||||
|
||||
const Util::Config::Node &m_config;
|
||||
const bool m_gpuMultiThreaded;
|
||||
|
||||
CIRQ *IRQ; // IRQ controller the tile generator is attached to
|
||||
CRender2D *Render2D; // 2D renderer the tile generator is attached to
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ extern bool OpenAudio();
|
|||
*
|
||||
* Sends a chunk of two-channel audio with the given number of samples to the audio system.
|
||||
*/
|
||||
extern bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer);
|
||||
extern bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, bool flipStereo);
|
||||
|
||||
/*
|
||||
* CloseAudio()
|
||||
|
|
|
@ -67,12 +67,12 @@ COutputs::~COutputs()
|
|||
//
|
||||
}
|
||||
|
||||
const GameInfo *COutputs::GetGame() const
|
||||
const Game &COutputs::GetGame() const
|
||||
{
|
||||
return m_game;
|
||||
}
|
||||
|
||||
void COutputs::SetGame(const GameInfo *game)
|
||||
void COutputs::SetGame(const Game &game)
|
||||
{
|
||||
m_game = game;
|
||||
}
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** 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/>.
|
||||
**/
|
||||
|
||||
/*
|
||||
* Outputs.h
|
||||
*
|
||||
* Base class for outputs.
|
||||
*/
|
||||
|
||||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** 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/>.
|
||||
**/
|
||||
|
||||
/*
|
||||
* Outputs.h
|
||||
*
|
||||
* Base class for outputs.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_OUTPUTS_H
|
||||
#define INCLUDED_OUTPUTS_H
|
||||
|
||||
/*
|
||||
* EOutputs enumeration of all available outputs.
|
||||
* Currently just contains the outputs for the driving games - more will need to be added for the other games.
|
||||
*/
|
||||
enum EOutputs
|
||||
{
|
||||
OutputUnknown = -1,
|
||||
OutputPause = 0,
|
||||
OutputLampStart,
|
||||
OutputLampView1,
|
||||
OutputLampView2,
|
||||
OutputLampView3,
|
||||
OutputLampView4,
|
||||
OutputLampLeader,
|
||||
OutputRawDrive,
|
||||
OutputRawLamps
|
||||
};
|
||||
|
||||
#define NUM_OUTPUTS 9
|
||||
|
||||
struct GameInfo;
|
||||
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
/*
|
||||
* EOutputs enumeration of all available outputs.
|
||||
* Currently just contains the outputs for the driving games - more will need to be added for the other games.
|
||||
*/
|
||||
enum EOutputs
|
||||
{
|
||||
OutputUnknown = -1,
|
||||
OutputPause = 0,
|
||||
OutputLampStart,
|
||||
OutputLampView1,
|
||||
OutputLampView2,
|
||||
OutputLampView3,
|
||||
OutputLampView4,
|
||||
OutputLampLeader,
|
||||
OutputRawDrive,
|
||||
OutputRawLamps
|
||||
};
|
||||
|
||||
#define NUM_OUTPUTS 9
|
||||
|
||||
class COutputs
|
||||
{
|
||||
public:
|
||||
|
@ -95,14 +95,14 @@ public:
|
|||
*
|
||||
* Returns the currently running game.
|
||||
*/
|
||||
const GameInfo *GetGame() const;
|
||||
const Game &GetGame() const;
|
||||
|
||||
/*
|
||||
* SetGame(game):
|
||||
*
|
||||
* Sets the currently running game.
|
||||
*/
|
||||
void SetGame(const GameInfo *game);
|
||||
void SetGame(const Game &game);
|
||||
|
||||
/*
|
||||
* GetValue(output):
|
||||
|
@ -137,7 +137,7 @@ protected:
|
|||
private:
|
||||
static const char* s_outputNames[]; // Static array of output names
|
||||
|
||||
const GameInfo *m_game; // Currently running game
|
||||
Game m_game; // Currently running game
|
||||
bool m_first[NUM_OUTPUTS]; // For each output, true if an initial value has been set
|
||||
UINT8 m_values[NUM_OUTPUTS]; // Current value of each output
|
||||
};
|
||||
|
|
|
@ -190,7 +190,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
|||
callback(callbackData);
|
||||
}
|
||||
|
||||
static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, void *dest)
|
||||
static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, void *dest, bool flipStereo)
|
||||
{
|
||||
INT16 *p = (INT16*)dest;
|
||||
|
||||
|
@ -198,7 +198,7 @@ static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuff
|
|||
for (unsigned i = 0; i < numSamples; i++)
|
||||
*p++ = leftBuffer[i] + rightBuffer[i]; // TODO: these should probably be clipped!
|
||||
#else
|
||||
if (g_Config.flipStereo) // swap left and right channels
|
||||
if (flipStereo) // swap left and right channels
|
||||
{
|
||||
for (unsigned i = 0; i < numSamples; i++)
|
||||
{
|
||||
|
@ -280,7 +280,7 @@ bool OpenAudio()
|
|||
return OKAY;
|
||||
}
|
||||
|
||||
bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer)
|
||||
bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, bool flipStereo)
|
||||
{
|
||||
//printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||
// numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
||||
|
@ -295,7 +295,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer)
|
|||
|
||||
// Mix together left and right channels into single chunk of data
|
||||
INT16 mixBuffer[NUM_CHANNELS * SAMPLES_PER_FRAME];
|
||||
MixChannels(numSamples, leftBuffer, rightBuffer, mixBuffer);
|
||||
MixChannels(numSamples, leftBuffer, rightBuffer, mixBuffer, flipStereo);
|
||||
|
||||
// Lock SDL audio callback so that it doesn't interfere with following code
|
||||
SDL_LockAudio();
|
||||
|
|
1163
Src/OSD/SDL/Main.cpp
1163
Src/OSD/SDL/Main.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,174 +0,0 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011-2016 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** 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/>.
|
||||
**/
|
||||
|
||||
/*
|
||||
* OSDConfig.h
|
||||
*
|
||||
* Header file defining the COSDConfig class: OSD configuration settings,
|
||||
* inherited by CConfig.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_OSDCONFIG_H
|
||||
#define INCLUDED_OSDCONFIG_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include "Supermodel.h"
|
||||
using namespace std;
|
||||
|
||||
|
||||
/*
|
||||
* COSDConfig:
|
||||
*
|
||||
* Settings used by COSDConfig.
|
||||
*/
|
||||
class COSDConfig
|
||||
{
|
||||
public:
|
||||
bool new3DEngine; // New 3D engine
|
||||
unsigned xRes, yRes; // X and Y resolution, in pixels
|
||||
bool fullScreen; // Full screen mode (if true)
|
||||
bool wideScreen; // Wide screen hack
|
||||
bool vsync; // Enable v-sync
|
||||
bool throttle; // 60 Hz frame limiting
|
||||
bool showFPS; // Show frame rate
|
||||
unsigned crosshairs; // For game guns: 0 = no crosshairs, 1 = player 1 only, 2 = player 2 only, 3 = both players
|
||||
bool flipStereo; // Flip stereo channels
|
||||
|
||||
#ifdef SUPERMODEL_DEBUGGER
|
||||
bool disableDebugger; // disables the debugger (not stored in the config. file)
|
||||
#endif
|
||||
|
||||
#ifdef SUPERMODEL_WIN32
|
||||
unsigned dInputConstForceLeftMax;
|
||||
unsigned dInputConstForceRightMax;
|
||||
unsigned dInputSelfCenterMax;
|
||||
unsigned dInputFrictionMax;
|
||||
unsigned dInputVibrateMax;
|
||||
unsigned xInputConstForceThreshold;
|
||||
unsigned xInputConstForceMax;
|
||||
unsigned xInputVibrateMax;
|
||||
#endif
|
||||
|
||||
// Input system
|
||||
inline void SetInputSystem(const char *inpSysName)
|
||||
{
|
||||
if (inpSysName == NULL)
|
||||
{
|
||||
#ifdef SUPERMODEL_WIN32 // default is DirectInput on Windows
|
||||
inputSystem = "dinput";
|
||||
#else // everyone else uses SDL
|
||||
inputSystem = "sdl";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (stricmp(inpSysName,"sdl")
|
||||
#ifdef SUPERMODEL_WIN32
|
||||
&& stricmp(inpSysName,"dinput") && stricmp(inpSysName,"xinput") && stricmp(inpSysName,"rawinput")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef SUPERMODEL_WIN32
|
||||
ErrorLog("Unknown input system '%s', defaulting to DirectInput.", inpSysName);
|
||||
inputSystem = "dinput";
|
||||
#else
|
||||
ErrorLog("Unknown input system '%s', defaulting to SDL.", inpSysName);
|
||||
inputSystem = "sdl";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
inputSystem = inpSysName;
|
||||
}
|
||||
|
||||
inline const char *GetInputSystem(void)
|
||||
{
|
||||
return inputSystem.c_str();
|
||||
}
|
||||
|
||||
// Outputs
|
||||
inline void SetOutputs(const char *outputsName)
|
||||
{
|
||||
if (outputsName == NULL)
|
||||
{
|
||||
outputs = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
if (stricmp(outputsName, "none")
|
||||
#ifdef SUPERMODEL_WIN32
|
||||
&& stricmp(outputsName, "win")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ErrorLog("Unknown outputs '%s', defaulting to None.", outputsName);
|
||||
outputs = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
outputs = outputsName;
|
||||
}
|
||||
|
||||
inline const char *GetOutputs(void)
|
||||
{
|
||||
return outputs.c_str();
|
||||
}
|
||||
|
||||
// Defaults
|
||||
COSDConfig(void)
|
||||
{
|
||||
new3DEngine = false;
|
||||
xRes = 496;
|
||||
yRes = 384;
|
||||
fullScreen = false;
|
||||
wideScreen = false;
|
||||
vsync = true;
|
||||
throttle = true;
|
||||
showFPS = false;
|
||||
crosshairs = 0;
|
||||
flipStereo = false;
|
||||
#ifdef SUPERMODEL_DEBUGGER
|
||||
disableDebugger = false;
|
||||
#endif
|
||||
#ifdef SUPERMODEL_WIN32
|
||||
inputSystem = "dinput";
|
||||
dInputConstForceLeftMax = 100;
|
||||
dInputConstForceRightMax = 100;
|
||||
dInputSelfCenterMax = 100;
|
||||
dInputFrictionMax = 100;
|
||||
dInputVibrateMax = 100;
|
||||
xInputConstForceThreshold = 30;
|
||||
xInputConstForceMax = 100;
|
||||
xInputVibrateMax = 100;
|
||||
#else
|
||||
inputSystem = "sdl";
|
||||
#endif
|
||||
outputs = "none";
|
||||
}
|
||||
|
||||
private:
|
||||
string inputSystem;
|
||||
string outputs;
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDED_OSDCONFIG_H
|
|
@ -182,7 +182,13 @@ SDLKeyMapStruct CSDLInputSystem::s_keyMap[] =
|
|||
{ "UNDO", SDLK_UNDO }
|
||||
};
|
||||
|
||||
CSDLInputSystem::CSDLInputSystem() : CInputSystem("SDL"), m_keyState(NULL), m_mouseX(0), m_mouseY(0), m_mouseZ(0), m_mouseButtons(0)
|
||||
CSDLInputSystem::CSDLInputSystem()
|
||||
: CInputSystem("SDL"),
|
||||
m_keyState(NULL),
|
||||
m_mouseX(0),
|
||||
m_mouseY(0),
|
||||
m_mouseZ(0),
|
||||
m_mouseButtons(0)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
|
@ -428,8 +428,9 @@ const char *CDirectInputSystem::ConstructName(bool useRawInput, bool useXInput)
|
|||
return (useXInput ? "Xinput" : "DirectInput");
|
||||
}
|
||||
|
||||
CDirectInputSystem::CDirectInputSystem(bool useRawInput, bool useXInput) :
|
||||
CDirectInputSystem::CDirectInputSystem(const Util::Config::Node &config, bool useRawInput, bool useXInput) :
|
||||
CInputSystem(ConstructName(useRawInput, useXInput)),
|
||||
m_config(config),
|
||||
m_useRawInput(useRawInput), m_useXInput(useXInput), m_enableFFeedback(true),
|
||||
m_initializedCOM(false), m_activated(false), m_hwnd(NULL), m_screenW(0), m_screenH(0),
|
||||
m_getRIDevListPtr(NULL), m_getRIDevInfoPtr(NULL), m_regRIDevsPtr(NULL), m_getRIDataPtr(NULL),
|
||||
|
@ -1791,13 +1792,15 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
break;
|
||||
|
||||
case FFConstantForce:
|
||||
{
|
||||
// Check if constant force effect is disabled
|
||||
if (g_Config.xInputConstForceMax == 0)
|
||||
unsigned xInputConstForceMax = m_config["XInputConstForceMax"].ValueAs<unsigned>();
|
||||
if (xInputConstForceMax == 0)
|
||||
return false;
|
||||
// Constant force effect is mapped to either left or right vibration motor depending on its direction
|
||||
negForce = ffCmd.force < 0.0f;
|
||||
absForce = (negForce ? -ffCmd.force : ffCmd.force);
|
||||
threshold = (float)g_Config.xInputConstForceThreshold / 100.0f;
|
||||
threshold = (float)m_config["XInputConstForceThreshold"].ValueAs<unsigned>() / 100.0f;
|
||||
// Check if constant force effect is being stopped or is below threshold
|
||||
if (absForce == 0.0f || absForce < threshold)
|
||||
{
|
||||
|
@ -1808,25 +1811,27 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
else if (negForce)
|
||||
{
|
||||
// If force is negative (to left), set left motor vibrating
|
||||
pInfo->xiConstForceLeft = (WORD)(absForce * (float)(g_Config.xInputConstForceMax * XI_VIBRATE_SCALE));
|
||||
pInfo->xiConstForceLeft = (WORD)(absForce * (float)(xInputConstForceMax * XI_VIBRATE_SCALE));
|
||||
pInfo->xiConstForceRight = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If force positive (to right), set right motor vibrating
|
||||
pInfo->xiConstForceLeft = 0;
|
||||
pInfo->xiConstForceRight = (WORD)(absForce * (float)(g_Config.xInputConstForceMax * XI_VIBRATE_SCALE));
|
||||
pInfo->xiConstForceRight = (WORD)(absForce * (float)(xInputConstForceMax * XI_VIBRATE_SCALE));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case FFSelfCenter:
|
||||
case FFFriction:
|
||||
// Self center and friction effects are not mapped
|
||||
return false;
|
||||
|
||||
case FFVibrate:
|
||||
// Check if vibration effect is disabled
|
||||
if (g_Config.xInputVibrateMax == 0)
|
||||
{
|
||||
// Check if vibration effect is disabled
|
||||
unsigned xInputVibrateMax = m_config["XInputVibrateMax"].ValueAs<unsigned>();
|
||||
if (xInputVibrateMax == 0)
|
||||
return false;
|
||||
// Check if vibration effect is being stopped
|
||||
if (ffCmd.force == 0.0f)
|
||||
|
@ -1837,10 +1842,10 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
else
|
||||
{
|
||||
// Otherwise, set both motors vibrating
|
||||
pInfo->xiVibrateBoth = (WORD)(ffCmd.force * (float)(g_Config.xInputVibrateMax * XI_VIBRATE_SCALE));
|
||||
pInfo->xiVibrateBoth = (WORD)(ffCmd.force * (float)(xInputVibrateMax * XI_VIBRATE_SCALE));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
// Unknown feedback command
|
||||
return false;
|
||||
|
@ -1893,16 +1898,18 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
//printf("FFConstantForce %0.2f\n", 100.0f * ffCmd.force);
|
||||
if (ffCmd.force >= 0.0f)
|
||||
{
|
||||
if (g_Config.dInputConstForceRightMax == 0)
|
||||
unsigned dInputConstForceRightMax = m_config["DirectInputConstForceRightMax"].ValueAs<unsigned>();
|
||||
if (dInputConstForceRightMax == 0)
|
||||
return false;
|
||||
lFFMag = (LONG)(-ffCmd.force * (float)(g_Config.dInputConstForceRightMax * DI_EFFECTS_SCALE)); // Invert sign for DirectInput effect
|
||||
lFFMag = (LONG)(-ffCmd.force * (float)(dInputConstForceRightMax * DI_EFFECTS_SCALE)); // Invert sign for DirectInput effect
|
||||
dicf.lMagnitude = std::max<LONG>(lFFMag, -DI_EFFECTS_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_Config.dInputConstForceLeftMax == 0)
|
||||
unsigned dInputConstForceLeftMax = m_config["DirectInputConstForceLeftMax"].ValueAs<unsigned>();
|
||||
if (dInputConstForceLeftMax == 0)
|
||||
return false;
|
||||
lFFMag = (LONG)(-ffCmd.force * (float)(g_Config.dInputConstForceLeftMax * DI_EFFECTS_SCALE)); // Invert sign for DirectInput effect
|
||||
lFFMag = (LONG)(-ffCmd.force * (float)(dInputConstForceLeftMax * DI_EFFECTS_SCALE)); // Invert sign for DirectInput effect
|
||||
dicf.lMagnitude = std::min<LONG>(lFFMag, DI_EFFECTS_MAX);
|
||||
}
|
||||
|
||||
|
@ -1911,10 +1918,12 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
break;
|
||||
|
||||
case FFSelfCenter:
|
||||
{
|
||||
unsigned dInputSelfCenterMax = m_config["DirectInputSelfCenterMax"].ValueAs<unsigned>();
|
||||
//printf("FFSelfCenter %0.2f\n", 100.0f * ffCmd.force);
|
||||
if (g_Config.dInputSelfCenterMax == 0)
|
||||
if (dInputSelfCenterMax == 0)
|
||||
return false;
|
||||
lFFMag = (LONG)(ffCmd.force * (float)(g_Config.dInputSelfCenterMax * DI_EFFECTS_SCALE));
|
||||
lFFMag = (LONG)(ffCmd.force * (float)(dInputSelfCenterMax * DI_EFFECTS_SCALE));
|
||||
dic.lOffset = 0;
|
||||
dic.lPositiveCoefficient = std::max<LONG>(0, std::min<LONG>(lFFMag, DI_EFFECTS_MAX));
|
||||
dic.lNegativeCoefficient = std::max<LONG>(0, std::min<LONG>(lFFMag, DI_EFFECTS_MAX));
|
||||
|
@ -1925,12 +1934,14 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
eff.cbTypeSpecificParams = sizeof(DICONDITION);
|
||||
eff.lpvTypeSpecificParams = &dic;
|
||||
break;
|
||||
|
||||
}
|
||||
case FFFriction:
|
||||
{
|
||||
unsigned dInputFrictionMax = m_config["DirectInputFrictionMax"].ValueAs<unsigned>();
|
||||
//printf("FFFriction %0.2f\n", 100.0f * ffCmd.force);
|
||||
if (g_Config.dInputFrictionMax == 0)
|
||||
if (dInputFrictionMax == 0)
|
||||
return false;
|
||||
lFFMag = (LONG)(ffCmd.force * (float)(g_Config.dInputFrictionMax * DI_EFFECTS_SCALE));
|
||||
lFFMag = (LONG)(ffCmd.force * (float)(dInputFrictionMax * DI_EFFECTS_SCALE));
|
||||
dic.lOffset = 0;
|
||||
dic.lPositiveCoefficient = std::max<LONG>(0, std::min<LONG>(lFFMag, DI_EFFECTS_MAX));
|
||||
dic.lNegativeCoefficient = std::max<LONG>(0, std::min<LONG>(lFFMag, DI_EFFECTS_MAX));
|
||||
|
@ -1941,12 +1952,14 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
eff.cbTypeSpecificParams = sizeof(DICONDITION);
|
||||
eff.lpvTypeSpecificParams = &dic;
|
||||
break;
|
||||
|
||||
}
|
||||
case FFVibrate:
|
||||
{
|
||||
unsigned dInputVibrateMax = m_config["DirectInputVibrateMax"].ValueAs<unsigned>();
|
||||
//printf("FFVibrate %0.2f\n", 100.0f * ffCmd.force);
|
||||
if (g_Config.dInputVibrateMax == 0)
|
||||
if (dInputVibrateMax == 0)
|
||||
return false;
|
||||
dFFMag = (DWORD)(ffCmd.force * (float)(g_Config.dInputVibrateMax * DI_EFFECTS_SCALE));
|
||||
dFFMag = (DWORD)(ffCmd.force * (float)(dInputVibrateMax * DI_EFFECTS_SCALE));
|
||||
dip.dwMagnitude = std::max<DWORD>(0, std::min<DWORD>(dFFMag, DI_EFFECTS_MAX));
|
||||
dip.lOffset = 0;
|
||||
dip.dwPhase = 0;
|
||||
|
@ -1955,7 +1968,7 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
|
|||
eff.cbTypeSpecificParams = sizeof(DIPERIODIC);
|
||||
eff.lpvTypeSpecificParams = &dip;
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
// Unknown feedback command
|
||||
return false;
|
||||
|
|
|
@ -108,6 +108,8 @@ typedef /*WINUSERAPI*/ DWORD (WINAPI *XInputSetStatePtr)(IN DWORD dwUserIndex, I
|
|||
class CDirectInputSystem : public CInputSystem
|
||||
{
|
||||
private:
|
||||
const Util::Config::Node &m_config;
|
||||
|
||||
// Lookup table to map key names to DirectInput keycodes and Virtual keycodes
|
||||
static DIKeyMapStruct s_keyMap[];
|
||||
|
||||
|
@ -232,7 +234,7 @@ public:
|
|||
* to the same shared axis and so cannot be distinguished when pressed together.
|
||||
* If enableFFeedback is true then force feedback is enabled (for those joysticks which are force feedback capable).
|
||||
*/
|
||||
CDirectInputSystem(bool useRawInput, bool useXInput);
|
||||
CDirectInputSystem(const Util::Config::Node &config, bool useRawInput, bool useXInput);
|
||||
|
||||
~CDirectInputSystem();
|
||||
|
||||
|
|
|
@ -221,23 +221,19 @@ LRESULT CWinOutputs::UnregisterClient(HWND hwnd, LPARAM id)
|
|||
LRESULT CWinOutputs::SendIdString(HWND hwnd, LPARAM id)
|
||||
{
|
||||
// Id 0 is the name of the game
|
||||
const char *name;
|
||||
std::string name;
|
||||
if (id == 0)
|
||||
name = GetGame()->id;
|
||||
name = GetGame().name;
|
||||
else
|
||||
name = MapIdToName(id);
|
||||
name = MapIdToName(id) ? MapIdToName(id) : "";
|
||||
|
||||
// NULL name is an empty string
|
||||
if (name == NULL)
|
||||
name = "";
|
||||
|
||||
// Allocate memory for message
|
||||
int dataLen = sizeof(CopyDataIdString) + strlen(name);
|
||||
int dataLen = sizeof(CopyDataIdString) + name.length();
|
||||
CopyDataIdString *data = (CopyDataIdString*)new(nothrow) UINT8[dataLen];
|
||||
if (!data)
|
||||
return 1;
|
||||
data->id = id;
|
||||
strcpy(data->string, name);
|
||||
strcpy(data->string, name.c_str());
|
||||
|
||||
// Reply by using SendMessage with WM_COPYDATA
|
||||
COPYDATASTRUCT copyData;
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
#include <cmath>
|
||||
#include "Sound/SCSPDSP.h"
|
||||
|
||||
static const Util::Config::Node *s_config = 0;
|
||||
static bool s_multiThreaded = false;
|
||||
|
||||
//#define NEWSCSP
|
||||
//#define RB_VOLUME
|
||||
|
||||
|
@ -552,8 +555,11 @@ void SCSP_StopSlot(_SLOT *slot,int keyoff)
|
|||
|
||||
#define log2(n) (log((float) n)/log((float) 2))
|
||||
|
||||
bool SCSP_Init(int n)
|
||||
bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||
{
|
||||
s_config = &config;
|
||||
s_multiThreaded = config["MultiThreaded"].ValueAs<bool>();
|
||||
|
||||
if(n==2)
|
||||
{
|
||||
SCSP=SCSPs+1;
|
||||
|
@ -928,7 +934,7 @@ void SCSP_UpdateRegR(int reg)
|
|||
/*
|
||||
* MIDI FIFO critical section!
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
v|=MidiStack[MidiR];
|
||||
|
@ -943,7 +949,7 @@ void SCSP_UpdateRegR(int reg)
|
|||
MidiInFill--;
|
||||
SCSP->data[0x5/2]=v;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
}
|
||||
break;
|
||||
|
@ -1770,7 +1776,12 @@ void SCSP_DoMasterSamples(int nsamples)
|
|||
* When one SCSP is fully attenuated, the other's samples will be multiplied
|
||||
* by 2.
|
||||
*/
|
||||
float balance = (float) g_Config.GetSCSPBalance() / 100.0f;
|
||||
float balance = (float) s_config->Get("Balance").ValueAs<float>();
|
||||
if (balance < -100.0f)
|
||||
balance = -100.0f;
|
||||
else if (balance > 100.0f)
|
||||
balance = 100.0f;
|
||||
balance /= 100.0f;
|
||||
float masterBalance = 1.0f+balance;
|
||||
float slaveBalance = 1.0f-balance;
|
||||
|
||||
|
@ -1935,7 +1946,7 @@ void SCSP_MidiIn(BYTE val)
|
|||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
//DebugLog("Midi Buffer push %02X",val);
|
||||
|
@ -1945,7 +1956,7 @@ void SCSP_MidiIn(BYTE val)
|
|||
//Int68kCB(IrqMidi);
|
||||
// SCSP.data[0x20/2]|=0x8;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
}
|
||||
|
||||
|
@ -1954,7 +1965,7 @@ void SCSP_MidiOutW(BYTE val)
|
|||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
//printf("68K: MIDI out\n");
|
||||
|
@ -1963,7 +1974,7 @@ void SCSP_MidiOutW(BYTE val)
|
|||
MidiOutW&=7;
|
||||
++MidiOutFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
}
|
||||
|
||||
|
@ -1978,7 +1989,7 @@ unsigned char SCSP_MidiOutR()
|
|||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
val=MidiStack[MidiOutR++];
|
||||
|
@ -1986,7 +1997,7 @@ unsigned char SCSP_MidiOutR()
|
|||
MidiOutR&=7;
|
||||
--MidiOutFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
|
||||
return val;
|
||||
|
@ -1999,12 +2010,12 @@ unsigned char SCSP_MidiOutFill()
|
|||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
v = MidiOutFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
|
||||
return v;
|
||||
|
@ -2017,12 +2028,12 @@ unsigned char SCSP_MidiInFill()
|
|||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
v = MidiInFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
if (s_multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
|
||||
return v;
|
||||
|
|
|
@ -58,7 +58,7 @@ UINT8 SCSP_MidiOutR();
|
|||
* Returns:
|
||||
* FAIL if an error occured (prints own error messages), OKAY otherwise.
|
||||
*/
|
||||
bool SCSP_Init(int n);
|
||||
bool SCSP_Init(const Util::Config::Node &config, int n);
|
||||
|
||||
void SCSP_SetRAM(int n,UINT8 *r);
|
||||
void SCSP_RTECheck();
|
||||
|
|
|
@ -97,9 +97,6 @@
|
|||
// Error logging interface
|
||||
#include "OSD/Logger.h"
|
||||
|
||||
// OSD configuration
|
||||
#include "OSDConfig.h" // located in OSD/<port>/ directory
|
||||
|
||||
// OSD Interfaces
|
||||
#include "OSD/Thread.h"
|
||||
#include "OSD/Audio.h"
|
||||
|
@ -154,7 +151,6 @@
|
|||
#include "Model3/DSB.h"
|
||||
#include "Model3/DriveBoard.h"
|
||||
#include "Model3/Model3.h"
|
||||
#include "Config.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
|
Loading…
Reference in a new issue