diff --git a/Makefiles/Makefile.SDL.Win32.GCC b/Makefiles/Makefile.SDL.Win32.GCC
index 62c9b88..a3725ff 100644
--- a/Makefiles/Makefile.SDL.Win32.GCC
+++ b/Makefiles/Makefile.SDL.Win32.GCC
@@ -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)
diff --git a/Src/BlockFile.cpp b/Src/BlockFile.cpp
index 7b18cf9..24b5c4e 100644
--- a/Src/BlockFile.cpp
+++ b/Src/BlockFile.cpp
@@ -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';
diff --git a/Src/BlockFile.h b/Src/BlockFile.h
index 641b80e..9e1e633 100644
--- a/Src/BlockFile.h
+++ b/Src/BlockFile.h
@@ -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
diff --git a/Src/Config.cpp b/Src/Config.cpp
deleted file mode 100644
index 7937195..0000000
--- a/Src/Config.cpp
+++ /dev/null
@@ -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 .
- **/
-
-/*
- * Config.cpp
- *
- * Program-wide configuration settings.
- */
-
-#include "Config.h"
-
-
-CConfig g_Config;
diff --git a/Src/Config.h b/Src/Config.h
deleted file mode 100644
index 9afdca8..0000000
--- a/Src/Config.h
+++ /dev/null
@@ -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 .
- **/
-
-/*
- * 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
\ No newline at end of file
diff --git a/Src/Debugger/SupermodelDebugger.cpp b/Src/Debugger/SupermodelDebugger.cpp
index 1583f63..d5a9290 100644
--- a/Src/Debugger/SupermodelDebugger.cpp
+++ b/Src/Debugger/SupermodelDebugger.cpp
@@ -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();
diff --git a/Src/Graphics/Legacy3D/Legacy3D.cpp b/Src/Graphics/Legacy3D/Legacy3D.cpp
index 1628e9f..360b181 100644
--- a/Src/Graphics/Legacy3D/Legacy3D.cpp
+++ b/Src/Graphics/Legacy3D/Legacy3D.cpp
@@ -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();
+
// 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(1, std::min(g_Config.maxTexMaps, glMaxTexUnits));
+ int maxTexMaps = std::max(1, std::min(m_config["MaxTexMaps"].ValueAsDefault(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(1, std::min(g_Config.maxTexMapExtent, maxTexSize / 2048));
+ int mapExtent = std::max(1, std::min(m_config["MaxTexMapExtent"].ValueAsDefault(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() ? fragmentShaderMultiSheetSource : fragmentShaderSingleSheetSource); // single texture shader
+ if (OKAY != LoadShaderProgram(&shaderProgram,&vertexShader,&fragmentShader,m_config["VertexShader"].ValueAs(),m_config["FragmentShader"].ValueAs(),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;
diff --git a/Src/Graphics/Legacy3D/Legacy3D.h b/Src/Graphics/Legacy3D/Legacy3D.h
index c7aed61..0e113e1 100644
--- a/Src/Graphics/Legacy3D/Legacy3D.h
+++ b/Src/Graphics/Legacy3D/Legacy3D.h
@@ -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;
diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp
index db27d2d..4ca5129 100644
--- a/Src/Graphics/New3D/New3D.cpp
+++ b/Src/Graphics/New3D/New3D.cpp
@@ -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;
diff --git a/Src/Graphics/New3D/New3D.h b/Src/Graphics/New3D/New3D.h
index 933d30a..50889c2 100644
--- a/Src/Graphics/New3D/New3D.h
+++ b/Src/Graphics/New3D/New3D.h
@@ -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):
diff --git a/Src/Graphics/New3D/R3DScrollFog.cpp b/Src/Graphics/New3D/R3DScrollFog.cpp
index e926bab..9519a13 100644
--- a/Src/Graphics/New3D/R3DScrollFog.cpp
+++ b/Src/Graphics/New3D/R3DScrollFog.cpp
@@ -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");
diff --git a/Src/Graphics/New3D/R3DShader.cpp b/Src/Graphics/New3D/R3DShader.cpp
index 5c2560c..b84d5a8 100644
--- a/Src/Graphics/New3D/R3DShader.cpp
+++ b/Src/Graphics/New3D/R3DShader.cpp
@@ -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");
diff --git a/Src/Graphics/Render2D.cpp b/Src/Graphics/Render2D.cpp
index 2c3b10f..1d66291 100644
--- a/Src/Graphics/Render2D.cpp
+++ b/Src/Graphics/Render2D.cpp
@@ -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
diff --git a/Src/Graphics/Shader.cpp b/Src/Graphics/Shader.cpp
index 45d6722..5880e6e 100644
--- a/Src/Graphics/Shader.cpp
+++ b/Src/Graphics/Shader.cpp
@@ -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;
}
diff --git a/Src/Graphics/Shader.h b/Src/Graphics/Shader.h
index 60a00f2..7b0ece6 100644
--- a/Src/Graphics/Shader.h
+++ b/Src/Graphics/Shader.h
@@ -29,6 +29,7 @@
#define INCLUDED_SHADER_H
#include "Pkgs/glew.h"
+#include
/*
* 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);
/*
diff --git a/Src/Inputs/Input.cpp b/Src/Inputs/Input.cpp
index 954d62e..fcfed33 100644
--- a/Src/Inputs/Input.cpp
+++ b/Src/Inputs/Input.cpp
@@ -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();
+ 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
diff --git a/Src/Inputs/Input.h b/Src/Inputs/Input.h
index 1babc6e..ee0d199 100644
--- a/Src/Inputs/Input.h
+++ b/Src/Inputs/Input.h
@@ -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()
diff --git a/Src/Inputs/InputSystem.cpp b/Src/Inputs/InputSystem.cpp
index 8285266..337d1a2 100644
--- a/Src/Inputs/InputSystem.cpp
+++ b/Src/Inputs/InputSystem.cpp
@@ -48,359 +48,359 @@ unsigned CInputSystem::totalSrcsReleased = 0;
const char *CInputSystem::s_validKeyNames[] =
{
- // General keys
- "BACKSPACE",
- "TAB",
- "CLEAR",
- "RETURN",
- "PAUSE",
- "ESCAPE",
- "SPACE",
- "EXCLAIM",
- "DBLQUOTE",
- "HASH",
- "DOLLAR",
- "AMPERSAND",
- "QUOTE",
- "LEFTPAREN",
- "RIGHTPAREN",
- "ASTERISK",
- "PLUS",
- "COMMA",
- "MINUS",
- "PERIOD",
- "SLASH",
- "0",
- "1",
- "2",
- "3",
- "4",
- "5",
- "6",
- "7",
- "8",
- "9",
- "COLON",
- "SEMICOLON",
- "LESS",
- "EQUALS",
- "GREATER",
- "QUESTION",
- "AT",
- "LEFTBRACKET",
- "BACKSLASH",
- "RIGHTBRACKET",
- "CARET",
- "UNDERSCORE",
- "BACKQUOTE",
- "A",
- "B",
- "C",
- "D",
- "E",
- "F",
- "G",
- "H",
- "I",
- "J",
- "K",
- "L",
- "M",
- "N",
- "O",
- "P",
- "Q",
- "R",
- "S",
- "T",
- "U",
- "V",
- "W",
- "X",
- "Y",
- "Z",
- "DEL",
-
- // Keypad
- "KEYPAD0",
- "KEYPAD1",
- "KEYPAD2",
- "KEYPAD3",
- "KEYPAD4",
- "KEYPAD5",
- "KEYPAD6",
- "KEYPAD7",
- "KEYPAD8",
- "KEYPAD9",
- "KEYPADPERIOD",
- "KEYPADDIVIDE",
- "KEYPADMULTIPLY",
- "KEYPADMINUS",
- "KEYPADPLUS",
- "KEYPADENTER",
- "KEYPADEQUALS",
-
- // Arrows + Home/End Pad
- "UP",
- "DOWN",
- "RIGHT",
- "LEFT",
- "INSERT",
- "HOME",
- "END",
- "PGUP",
- "PGDN",
+ // General keys
+ "BACKSPACE",
+ "TAB",
+ "CLEAR",
+ "RETURN",
+ "PAUSE",
+ "ESCAPE",
+ "SPACE",
+ "EXCLAIM",
+ "DBLQUOTE",
+ "HASH",
+ "DOLLAR",
+ "AMPERSAND",
+ "QUOTE",
+ "LEFTPAREN",
+ "RIGHTPAREN",
+ "ASTERISK",
+ "PLUS",
+ "COMMA",
+ "MINUS",
+ "PERIOD",
+ "SLASH",
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "COLON",
+ "SEMICOLON",
+ "LESS",
+ "EQUALS",
+ "GREATER",
+ "QUESTION",
+ "AT",
+ "LEFTBRACKET",
+ "BACKSLASH",
+ "RIGHTBRACKET",
+ "CARET",
+ "UNDERSCORE",
+ "BACKQUOTE",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "DEL",
+
+ // Keypad
+ "KEYPAD0",
+ "KEYPAD1",
+ "KEYPAD2",
+ "KEYPAD3",
+ "KEYPAD4",
+ "KEYPAD5",
+ "KEYPAD6",
+ "KEYPAD7",
+ "KEYPAD8",
+ "KEYPAD9",
+ "KEYPADPERIOD",
+ "KEYPADDIVIDE",
+ "KEYPADMULTIPLY",
+ "KEYPADMINUS",
+ "KEYPADPLUS",
+ "KEYPADENTER",
+ "KEYPADEQUALS",
+
+ // Arrows + Home/End Pad
+ "UP",
+ "DOWN",
+ "RIGHT",
+ "LEFT",
+ "INSERT",
+ "HOME",
+ "END",
+ "PGUP",
+ "PGDN",
- // Function Key
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
- "F8",
- "F9",
- "F10",
- "F11",
- "F12",
- "F13",
- "F14",
- "F15",
+ // Function Key
+ "F1",
+ "F2",
+ "F3",
+ "F4",
+ "F5",
+ "F6",
+ "F7",
+ "F8",
+ "F9",
+ "F10",
+ "F11",
+ "F12",
+ "F13",
+ "F14",
+ "F15",
- // Modifier Keys
- "NUMLOCK",
- "CAPSLOCK",
- "SCROLLLOCK",
- "SHIFT",
- "RIGHTSHIFT",
- "LEFTSHIFT",
- "CTRL",
- "RIGHTCTRL",
- "LEFTCTRL",
- "ALT",
- "RIGHTALT",
- "LEFTALT",
- "RIGHTMETA",
- "LEFTMETA",
- "RIGHTWINDOWS",
- "LEFTWINDOWS",
- "ALTGR",
- "COMPOSE",
+ // Modifier Keys
+ "NUMLOCK",
+ "CAPSLOCK",
+ "SCROLLLOCK",
+ "SHIFT",
+ "RIGHTSHIFT",
+ "LEFTSHIFT",
+ "CTRL",
+ "RIGHTCTRL",
+ "LEFTCTRL",
+ "ALT",
+ "RIGHTALT",
+ "LEFTALT",
+ "RIGHTMETA",
+ "LEFTMETA",
+ "RIGHTWINDOWS",
+ "LEFTWINDOWS",
+ "ALTGR",
+ "COMPOSE",
- // Other
- "HELP",
- "PRINT",
- "SYSREQ",
- "BREAK",
- "MENU",
- "POWER",
- "EURO",
- "UNDO"
+ // Other
+ "HELP",
+ "PRINT",
+ "SYSREQ",
+ "BREAK",
+ "MENU",
+ "POWER",
+ "EURO",
+ "UNDO"
};
MousePartsStruct CInputSystem::s_mseParts[] =
{
- // X Axis (Axis 1)
- { "XAXIS", MouseXAxis },
- { "XAXIS_INV", MouseXAxisInv },
- { "XAXIS_POS", MouseXAxisPos },
- { "XAXIS_NEG", MouseXAxisNeg },
- { "RIGHT", MouseXAxisPos },
- { "LEFT", MouseXAxisNeg },
- { "AXIS1", MouseXAxis },
- { "AXIS1_INV", MouseXAxisInv },
- { "AXIS1_POS", MouseXAxisPos },
- { "AXIS1_NEG", MouseXAxisNeg },
-
- // Y Axis (Axis 2)
- { "YAXIS", MouseYAxis },
- { "YAXIS_INV", MouseYAxisInv },
- { "YAXIS_POS", MouseYAxisPos },
- { "YAXIS_NEG", MouseYAxisNeg },
- { "DOWN", MouseYAxisPos },
- { "UP", MouseYAxisNeg },
- { "AXIS2", MouseYAxis },
- { "AXIS2_INV", MouseYAxisInv },
- { "AXIS2_POS", MouseYAxisPos },
- { "AXIS2_NEG", MouseYAxisNeg },
+ // X Axis (Axis 1)
+ { "XAXIS", MouseXAxis },
+ { "XAXIS_INV", MouseXAxisInv },
+ { "XAXIS_POS", MouseXAxisPos },
+ { "XAXIS_NEG", MouseXAxisNeg },
+ { "RIGHT", MouseXAxisPos },
+ { "LEFT", MouseXAxisNeg },
+ { "AXIS1", MouseXAxis },
+ { "AXIS1_INV", MouseXAxisInv },
+ { "AXIS1_POS", MouseXAxisPos },
+ { "AXIS1_NEG", MouseXAxisNeg },
+
+ // Y Axis (Axis 2)
+ { "YAXIS", MouseYAxis },
+ { "YAXIS_INV", MouseYAxisInv },
+ { "YAXIS_POS", MouseYAxisPos },
+ { "YAXIS_NEG", MouseYAxisNeg },
+ { "DOWN", MouseYAxisPos },
+ { "UP", MouseYAxisNeg },
+ { "AXIS2", MouseYAxis },
+ { "AXIS2_INV", MouseYAxisInv },
+ { "AXIS2_POS", MouseYAxisPos },
+ { "AXIS2_NEG", MouseYAxisNeg },
- // Z/Wheel Axis (Axis 3)
- { "ZAXIS", MouseZAxis },
- { "ZAXIS_INV", MouseZAxisInv },
- { "ZAXIS_POS", MouseZAxisPos },
- { "ZAXIS_NEG", MouseZAxisNeg },
- { "WHEEL_UP", MouseZAxisPos },
- { "WHEEL_DOWN", MouseZAxisNeg },
- { "AXIS3", MouseZAxis },
- { "AXIS3_INV", MouseZAxisInv },
- { "AXIS3_POS", MouseZAxisPos },
- { "AXIS3_NEG", MouseZAxisNeg },
+ // Z/Wheel Axis (Axis 3)
+ { "ZAXIS", MouseZAxis },
+ { "ZAXIS_INV", MouseZAxisInv },
+ { "ZAXIS_POS", MouseZAxisPos },
+ { "ZAXIS_NEG", MouseZAxisNeg },
+ { "WHEEL_UP", MouseZAxisPos },
+ { "WHEEL_DOWN", MouseZAxisNeg },
+ { "AXIS3", MouseZAxis },
+ { "AXIS3_INV", MouseZAxisInv },
+ { "AXIS3_POS", MouseZAxisPos },
+ { "AXIS3_NEG", MouseZAxisNeg },
- // Left/Middle/Right Buttons (Buttons 1-3)
- { "LEFT_BUTTON", MouseButtonLeft },
- { "BUTTON1", MouseButtonLeft },
- { "MIDDLE_BUTTON", MouseButtonMiddle },
- { "BUTTON2", MouseButtonMiddle },
- { "RIGHT_BUTTON", MouseButtonRight },
- { "BUTTON3", MouseButtonRight },
+ // Left/Middle/Right Buttons (Buttons 1-3)
+ { "LEFT_BUTTON", MouseButtonLeft },
+ { "BUTTON1", MouseButtonLeft },
+ { "MIDDLE_BUTTON", MouseButtonMiddle },
+ { "BUTTON2", MouseButtonMiddle },
+ { "RIGHT_BUTTON", MouseButtonRight },
+ { "BUTTON3", MouseButtonRight },
- // Extra Buttons (Buttons 4 & 5)
- { "BUTTONX1", MouseButtonX1 },
- { "BUTTON4", MouseButtonX1 },
- { "BUTTONX2", MouseButtonX2 },
- { "BUTTON5", MouseButtonX2 },
+ // Extra Buttons (Buttons 4 & 5)
+ { "BUTTONX1", MouseButtonX1 },
+ { "BUTTON4", MouseButtonX1 },
+ { "BUTTONX2", MouseButtonX2 },
+ { "BUTTON5", MouseButtonX2 },
- // List terminator
- { NULL, MouseUnknown }
+ // List terminator
+ { NULL, MouseUnknown }
};
JoyPartsStruct CInputSystem::s_joyParts[] =
{
- // X-Axis (Axis 1)
- { "XAXIS", JoyXAxis },
- { "XAXIS_INV", JoyXAxisInv },
- { "XAXIS_POS", JoyXAxisPos },
- { "XAXIS_NEG", JoyXAxisNeg },
- { "RIGHT", JoyXAxisPos },
- { "LEFT", JoyXAxisNeg },
- { "AXIS1", JoyXAxis },
- { "AXIS1_INV", JoyXAxisInv },
- { "AXIS1_POS", JoyXAxisPos },
- { "AXIS1_NEG", JoyXAxisNeg },
-
- // Y-Axis (Axis 2)
- { "YAXIS", JoyYAxis },
- { "YAXIS_INV", JoyYAxisInv },
- { "YAXIS_POS", JoyYAxisPos },
- { "YAXIS_NEG", JoyYAxisNeg },
- { "DOWN", JoyYAxisPos },
- { "UP", JoyYAxisNeg },
- { "AXIS2", JoyYAxis },
- { "AXIS2_INV", JoyYAxisInv },
- { "AXIS2_POS", JoyYAxisPos },
- { "AXIS2_NEG", JoyYAxisNeg },
-
- // Z-Axis (Axis 3)
- { "ZAXIS", JoyZAxis },
- { "ZAXIS_INV", JoyZAxisInv },
- { "ZAXIS_POS", JoyZAxisPos },
- { "ZAXIS_NEG", JoyZAxisNeg },
- { "AXIS3", JoyZAxis },
- { "AXIS3_INV", JoyZAxisInv },
- { "AXIS3_POS", JoyZAxisPos },
- { "AXIS3_NEG", JoyZAxisNeg },
+ // X-Axis (Axis 1)
+ { "XAXIS", JoyXAxis },
+ { "XAXIS_INV", JoyXAxisInv },
+ { "XAXIS_POS", JoyXAxisPos },
+ { "XAXIS_NEG", JoyXAxisNeg },
+ { "RIGHT", JoyXAxisPos },
+ { "LEFT", JoyXAxisNeg },
+ { "AXIS1", JoyXAxis },
+ { "AXIS1_INV", JoyXAxisInv },
+ { "AXIS1_POS", JoyXAxisPos },
+ { "AXIS1_NEG", JoyXAxisNeg },
+
+ // Y-Axis (Axis 2)
+ { "YAXIS", JoyYAxis },
+ { "YAXIS_INV", JoyYAxisInv },
+ { "YAXIS_POS", JoyYAxisPos },
+ { "YAXIS_NEG", JoyYAxisNeg },
+ { "DOWN", JoyYAxisPos },
+ { "UP", JoyYAxisNeg },
+ { "AXIS2", JoyYAxis },
+ { "AXIS2_INV", JoyYAxisInv },
+ { "AXIS2_POS", JoyYAxisPos },
+ { "AXIS2_NEG", JoyYAxisNeg },
+
+ // Z-Axis (Axis 3)
+ { "ZAXIS", JoyZAxis },
+ { "ZAXIS_INV", JoyZAxisInv },
+ { "ZAXIS_POS", JoyZAxisPos },
+ { "ZAXIS_NEG", JoyZAxisNeg },
+ { "AXIS3", JoyZAxis },
+ { "AXIS3_INV", JoyZAxisInv },
+ { "AXIS3_POS", JoyZAxisPos },
+ { "AXIS3_NEG", JoyZAxisNeg },
- // RX-Axis (Axis 4)
- { "RXAXIS", JoyRXAxis },
- { "RXAXIS_INV", JoyRXAxisInv },
- { "RXAXIS_POS", JoyRXAxisPos },
- { "RXAXIS_NEG", JoyRXAxisNeg },
- { "AXIS4", JoyRXAxis },
- { "AXIS4_INV", JoyRXAxisInv },
- { "AXIS4_POS", JoyRXAxisPos },
- { "AXIS4_NEG", JoyRXAxisNeg },
+ // RX-Axis (Axis 4)
+ { "RXAXIS", JoyRXAxis },
+ { "RXAXIS_INV", JoyRXAxisInv },
+ { "RXAXIS_POS", JoyRXAxisPos },
+ { "RXAXIS_NEG", JoyRXAxisNeg },
+ { "AXIS4", JoyRXAxis },
+ { "AXIS4_INV", JoyRXAxisInv },
+ { "AXIS4_POS", JoyRXAxisPos },
+ { "AXIS4_NEG", JoyRXAxisNeg },
- // RY-Axis (Axis 5)
- { "RYAXIS", JoyRYAxis },
- { "RYAXIS_INV", JoyRYAxisInv },
- { "RYAXIS_POS", JoyRYAxisPos },
- { "RYAXIS_NEG", JoyRYAxisNeg },
- { "AXIS5", JoyRYAxis },
- { "AXIS5_INV", JoyRYAxisInv },
- { "AXIS5_POS", JoyRYAxisPos },
- { "AXIS5_NEG", JoyRYAxisNeg },
-
- // RZ-Axis (Axis 6)
- { "RZAXIS", JoyRZAxis },
- { "RZAXIS_INV", JoyRZAxisInv },
- { "RZAXIS_POS", JoyRZAxisPos },
- { "RZAXIS_NEG", JoyRZAxisNeg },
- { "AXIS6", JoyRZAxis },
- { "AXIS6_INV", JoyRZAxisInv },
- { "AXIS6_POS", JoyRZAxisPos },
- { "AXIS6_NEG", JoyRZAxisNeg },
+ // RY-Axis (Axis 5)
+ { "RYAXIS", JoyRYAxis },
+ { "RYAXIS_INV", JoyRYAxisInv },
+ { "RYAXIS_POS", JoyRYAxisPos },
+ { "RYAXIS_NEG", JoyRYAxisNeg },
+ { "AXIS5", JoyRYAxis },
+ { "AXIS5_INV", JoyRYAxisInv },
+ { "AXIS5_POS", JoyRYAxisPos },
+ { "AXIS5_NEG", JoyRYAxisNeg },
+
+ // RZ-Axis (Axis 6)
+ { "RZAXIS", JoyRZAxis },
+ { "RZAXIS_INV", JoyRZAxisInv },
+ { "RZAXIS_POS", JoyRZAxisPos },
+ { "RZAXIS_NEG", JoyRZAxisNeg },
+ { "AXIS6", JoyRZAxis },
+ { "AXIS6_INV", JoyRZAxisInv },
+ { "AXIS6_POS", JoyRZAxisPos },
+ { "AXIS6_NEG", JoyRZAxisNeg },
- // Slider 1 (Axis 7)
- { "SLIDER1", JoyS1Axis },
- { "SLIDER1_INV", JoyS1AxisInv },
- { "SLIDER1_POS", JoyS1AxisPos },
- { "SLIDER1_NEG", JoyS1AxisNeg },
- { "AXIS7", JoyS1Axis },
- { "AXIS7_INV", JoyS1AxisInv },
- { "AXIS7_POS", JoyS1AxisPos },
- { "AXIS7_NEG", JoyS1AxisNeg },
+ // Slider 1 (Axis 7)
+ { "SLIDER1", JoyS1Axis },
+ { "SLIDER1_INV", JoyS1AxisInv },
+ { "SLIDER1_POS", JoyS1AxisPos },
+ { "SLIDER1_NEG", JoyS1AxisNeg },
+ { "AXIS7", JoyS1Axis },
+ { "AXIS7_INV", JoyS1AxisInv },
+ { "AXIS7_POS", JoyS1AxisPos },
+ { "AXIS7_NEG", JoyS1AxisNeg },
- // Slider 2 (Axis 8)
- { "SLIDER2", JoyS1Axis },
- { "SLIDER2_INV", JoyS1AxisInv },
- { "SLIDER2_POS", JoyS1AxisPos },
- { "SLIDER2_NEG", JoyS1AxisNeg },
- { "AXIS8", JoyS1Axis },
- { "AXIS8_INV", JoyS1AxisInv },
- { "AXIS8_POS", JoyS1AxisPos },
- { "AXIS8_NEG", JoyS1AxisNeg },
+ // Slider 2 (Axis 8)
+ { "SLIDER2", JoyS1Axis },
+ { "SLIDER2_INV", JoyS1AxisInv },
+ { "SLIDER2_POS", JoyS1AxisPos },
+ { "SLIDER2_NEG", JoyS1AxisNeg },
+ { "AXIS8", JoyS1Axis },
+ { "AXIS8_INV", JoyS1AxisInv },
+ { "AXIS8_POS", JoyS1AxisPos },
+ { "AXIS8_NEG", JoyS1AxisNeg },
- // POV Hat 1
- { "POV1_UP", JoyPOV0Up },
- { "POV1_DOWN", JoyPOV0Down },
- { "POV1_LEFT", JoyPOV0Left },
- { "POV1_RIGHT", JoyPOV0Right },
+ // POV Hat 1
+ { "POV1_UP", JoyPOV0Up },
+ { "POV1_DOWN", JoyPOV0Down },
+ { "POV1_LEFT", JoyPOV0Left },
+ { "POV1_RIGHT", JoyPOV0Right },
- // POV Hat 2
- { "POV2_UP", JoyPOV1Up },
- { "POV2_DOWN", JoyPOV1Down },
- { "POV2_LEFT", JoyPOV1Left },
- { "POV2_RIGHT", JoyPOV1Right },
+ // POV Hat 2
+ { "POV2_UP", JoyPOV1Up },
+ { "POV2_DOWN", JoyPOV1Down },
+ { "POV2_LEFT", JoyPOV1Left },
+ { "POV2_RIGHT", JoyPOV1Right },
- // POV Hat 3
- { "POV3_UP", JoyPOV2Up },
- { "POV3_DOWN", JoyPOV2Down },
- { "POV3_LEFT", JoyPOV2Left },
- { "POV3_RIGHT", JoyPOV2Right },
+ // POV Hat 3
+ { "POV3_UP", JoyPOV2Up },
+ { "POV3_DOWN", JoyPOV2Down },
+ { "POV3_LEFT", JoyPOV2Left },
+ { "POV3_RIGHT", JoyPOV2Right },
- // POV Hat 4
- { "POV4_UP", JoyPOV3Up },
- { "POV4_DOWN", JoyPOV3Down },
- { "POV4_LEFT", JoyPOV3Left },
- { "POV4_RIGHT", JoyPOV3Right },
+ // POV Hat 4
+ { "POV4_UP", JoyPOV3Up },
+ { "POV4_DOWN", JoyPOV3Down },
+ { "POV4_LEFT", JoyPOV3Left },
+ { "POV4_RIGHT", JoyPOV3Right },
- // Buttons 1-32
- { "BUTTON1", JoyButton0 },
- { "BUTTON2", JoyButton1 },
- { "BUTTON3", JoyButton2 },
- { "BUTTON4", JoyButton3 },
- { "BUTTON5", JoyButton4 },
- { "BUTTON6", JoyButton5 },
- { "BUTTON7", JoyButton6 },
- { "BUTTON8", JoyButton7 },
- { "BUTTON9", JoyButton8 },
- { "BUTTON10", JoyButton9 },
- { "BUTTON11", JoyButton10 },
- { "BUTTON12", JoyButton11 },
- { "BUTTON13", JoyButton12 },
- { "BUTTON14", JoyButton13 },
- { "BUTTON15", JoyButton14 },
- { "BUTTON16", JoyButton15 },
- { "BUTTON17", JoyButton16 },
- { "BUTTON18", JoyButton17 },
- { "BUTTON19", JoyButton18 },
- { "BUTTON20", JoyButton19 },
- { "BUTTON21", JoyButton20 },
- { "BUTTON22", JoyButton21 },
- { "BUTTON23", JoyButton22 },
- { "BUTTON24", JoyButton23 },
- { "BUTTON25", JoyButton24 },
- { "BUTTON26", JoyButton25 },
- { "BUTTON27", JoyButton26 },
- { "BUTTON28", JoyButton27 },
- { "BUTTON29", JoyButton28 },
- { "BUTTON30", JoyButton29 },
- { "BUTTON31", JoyButton30 },
- { "BUTTON32", JoyButton31 },
+ // Buttons 1-32
+ { "BUTTON1", JoyButton0 },
+ { "BUTTON2", JoyButton1 },
+ { "BUTTON3", JoyButton2 },
+ { "BUTTON4", JoyButton3 },
+ { "BUTTON5", JoyButton4 },
+ { "BUTTON6", JoyButton5 },
+ { "BUTTON7", JoyButton6 },
+ { "BUTTON8", JoyButton7 },
+ { "BUTTON9", JoyButton8 },
+ { "BUTTON10", JoyButton9 },
+ { "BUTTON11", JoyButton10 },
+ { "BUTTON12", JoyButton11 },
+ { "BUTTON13", JoyButton12 },
+ { "BUTTON14", JoyButton13 },
+ { "BUTTON15", JoyButton14 },
+ { "BUTTON16", JoyButton15 },
+ { "BUTTON17", JoyButton16 },
+ { "BUTTON18", JoyButton17 },
+ { "BUTTON19", JoyButton18 },
+ { "BUTTON20", JoyButton19 },
+ { "BUTTON21", JoyButton20 },
+ { "BUTTON22", JoyButton21 },
+ { "BUTTON23", JoyButton22 },
+ { "BUTTON24", JoyButton23 },
+ { "BUTTON25", JoyButton24 },
+ { "BUTTON26", JoyButton25 },
+ { "BUTTON27", JoyButton26 },
+ { "BUTTON28", JoyButton27 },
+ { "BUTTON29", JoyButton28 },
+ { "BUTTON30", JoyButton29 },
+ { "BUTTON31", JoyButton30 },
+ { "BUTTON32", JoyButton31 },
- // List terminator
- { NULL, JoyUnknown }
+ // List terminator
+ { NULL, JoyUnknown }
};
const char *CInputSystem::s_axisIds[] = { "X", "Y", "Z", "RX", "RY", "RZ", "S1", "S2" };
@@ -409,2059 +409,2284 @@ const char *CInputSystem::s_axisNames[] = { "X-Axis", "Y-Axis", "Z-Axis", "RX-Ax
const char *CInputSystem::GetDefaultAxisName(int axisNum)
{
- return (axisNum >= 0 && axisNum < NUM_JOY_AXES ? s_axisNames[axisNum] : "");
+ return (axisNum >= 0 && axisNum < NUM_JOY_AXES ? s_axisNames[axisNum] : "");
}
-CInputSystem::CInputSystem(const char *systemName) :
- m_dispX(0), m_dispY(0), m_dispW(0), m_dispH(0), m_grabMouse(false), name(systemName)
+CInputSystem::CInputSystem(const char *systemName)
+ : m_dispX(0),
+ m_dispY(0),
+ m_dispW(0),
+ m_dispH(0),
+ m_grabMouse(false),
+ name(systemName)
{
- m_emptySource = new CMultiInputSource();
- m_emptySource->Acquire();
+ m_emptySource = new CMultiInputSource();
+ m_emptySource->Acquire();
}
CInputSystem::~CInputSystem()
{
- m_emptySource->Release();
+ m_emptySource->Release();
- ClearSettings();
- ClearSourceCache(true);
+ ClearSettings();
+ ClearSourceCache(true);
#ifdef DEBUG
- if (totalSrcsAcquired != totalSrcsReleased)
- printf("WARNING - number of input source acquisitions (%u) does not equal number of releases (%u)\n", totalSrcsAcquired, totalSrcsReleased);
+ if (totalSrcsAcquired != totalSrcsReleased)
+ printf("WARNING - number of input source acquisitions (%u) does not equal number of releases (%u)\n", totalSrcsAcquired, totalSrcsReleased);
#endif
}
void CInputSystem::CreateSourceCache()
{
- // Create cache for key sources
- m_anyKeySources = new CInputSource*[NUM_VALID_KEYS];
- memset(m_anyKeySources, 0, sizeof(CInputSource*) * NUM_VALID_KEYS);
- if (m_numKbds != ANY_KEYBOARD)
- {
- m_keySources = new CInputSource**[m_numKbds];
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- {
- m_keySources[kbdNum] = new CInputSource*[NUM_VALID_KEYS];
- memset(m_keySources[kbdNum], 0, sizeof(CInputSource*) * NUM_VALID_KEYS);
- }
- }
+ // Create cache for key sources
+ m_anyKeySources = new CInputSource*[NUM_VALID_KEYS];
+ memset(m_anyKeySources, 0, sizeof(CInputSource*) * NUM_VALID_KEYS);
+ if (m_numKbds != ANY_KEYBOARD)
+ {
+ m_keySources = new CInputSource**[m_numKbds];
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ m_keySources[kbdNum] = new CInputSource*[NUM_VALID_KEYS];
+ memset(m_keySources[kbdNum], 0, sizeof(CInputSource*) * NUM_VALID_KEYS);
+ }
+ }
- // Create cache for mouse sources
- m_anyMseSources = new CInputSource*[NUM_MOUSE_PARTS];
- memset(m_anyMseSources, 0, sizeof(CInputSource*) * NUM_MOUSE_PARTS);
- if (m_numMice != ANY_MOUSE)
- {
- m_mseSources = new CInputSource**[m_numMice];
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- {
- m_mseSources[mseNum] = new CInputSource*[NUM_MOUSE_PARTS];
- memset(m_mseSources[mseNum], 0, sizeof(CInputSource*) * NUM_MOUSE_PARTS);
- }
- }
+ // Create cache for mouse sources
+ m_anyMseSources = new CInputSource*[NUM_MOUSE_PARTS];
+ memset(m_anyMseSources, 0, sizeof(CInputSource*) * NUM_MOUSE_PARTS);
+ if (m_numMice != ANY_MOUSE)
+ {
+ m_mseSources = new CInputSource**[m_numMice];
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ m_mseSources[mseNum] = new CInputSource*[NUM_MOUSE_PARTS];
+ memset(m_mseSources[mseNum], 0, sizeof(CInputSource*) * NUM_MOUSE_PARTS);
+ }
+ }
- // Create cache for joystick sources
- m_anyJoySources = new CInputSource*[NUM_JOY_PARTS];
- memset(m_anyJoySources, 0, sizeof(CInputSource*) * NUM_JOY_PARTS);
- if (m_numJoys != ANY_JOYSTICK)
- {
- m_joySources = new CInputSource**[m_numJoys];
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- {
- m_joySources[joyNum] = new CInputSource*[NUM_JOY_PARTS];
- memset(m_joySources[joyNum], 0, sizeof(CInputSource*) * NUM_JOY_PARTS);
- }
- }
-}
+ // Create cache for joystick sources
+ m_anyJoySources = new CInputSource*[NUM_JOY_PARTS];
+ memset(m_anyJoySources, 0, sizeof(CInputSource*) * NUM_JOY_PARTS);
+ if (m_numJoys != ANY_JOYSTICK)
+ {
+ m_joySources = new CInputSource**[m_numJoys];
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ m_joySources[joyNum] = new CInputSource*[NUM_JOY_PARTS];
+ memset(m_joySources[joyNum], 0, sizeof(CInputSource*) * NUM_JOY_PARTS);
+ }
+ }
+}
void CInputSystem::ClearSourceCache(bool deleteCache)
{
- // Clear cache of keyboard sources
- if (m_anyKeySources != NULL)
- {
- for (size_t keyIndex = 0; keyIndex < NUM_VALID_KEYS; keyIndex++)
- ReleaseSource(m_anyKeySources[keyIndex]);
- if (deleteCache)
- {
- delete[] m_anyKeySources;
- m_anyKeySources = NULL;
- }
- if (m_numKbds != ANY_KEYBOARD)
- {
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- {
- for (size_t keyIndex = 0; keyIndex < NUM_VALID_KEYS; keyIndex++)
- ReleaseSource(m_keySources[kbdNum][keyIndex]);
- if (deleteCache)
- delete[] m_keySources[kbdNum];
- }
- if (deleteCache)
- {
- delete[] m_keySources;
- m_keySources = NULL;
- }
- }
- }
+ // Clear cache of keyboard sources
+ if (m_anyKeySources != NULL)
+ {
+ for (size_t keyIndex = 0; keyIndex < NUM_VALID_KEYS; keyIndex++)
+ ReleaseSource(m_anyKeySources[keyIndex]);
+ if (deleteCache)
+ {
+ delete[] m_anyKeySources;
+ m_anyKeySources = NULL;
+ }
+ if (m_numKbds != ANY_KEYBOARD)
+ {
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ for (size_t keyIndex = 0; keyIndex < NUM_VALID_KEYS; keyIndex++)
+ ReleaseSource(m_keySources[kbdNum][keyIndex]);
+ if (deleteCache)
+ delete[] m_keySources[kbdNum];
+ }
+ if (deleteCache)
+ {
+ delete[] m_keySources;
+ m_keySources = NULL;
+ }
+ }
+ }
- // Clear cache of mouse sources
- if (m_anyMseSources != NULL)
- {
- for (int mseIndex = 0; mseIndex < NUM_MOUSE_PARTS; mseIndex++)
- ReleaseSource(m_anyMseSources[mseIndex]);
- if (deleteCache)
- {
- delete[] m_anyMseSources;
- m_anyMseSources = NULL;
- }
- if (m_numMice != ANY_MOUSE)
- {
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- {
- for (int mseIndex = 0; mseIndex < NUM_MOUSE_PARTS; mseIndex++)
- ReleaseSource(m_mseSources[mseNum][mseIndex]);
- if (deleteCache)
- delete[] m_mseSources[mseNum];
- }
- if (deleteCache)
- {
- delete[] m_mseSources;
- m_mseSources = NULL;
- }
- }
- }
+ // Clear cache of mouse sources
+ if (m_anyMseSources != NULL)
+ {
+ for (int mseIndex = 0; mseIndex < NUM_MOUSE_PARTS; mseIndex++)
+ ReleaseSource(m_anyMseSources[mseIndex]);
+ if (deleteCache)
+ {
+ delete[] m_anyMseSources;
+ m_anyMseSources = NULL;
+ }
+ if (m_numMice != ANY_MOUSE)
+ {
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ for (int mseIndex = 0; mseIndex < NUM_MOUSE_PARTS; mseIndex++)
+ ReleaseSource(m_mseSources[mseNum][mseIndex]);
+ if (deleteCache)
+ delete[] m_mseSources[mseNum];
+ }
+ if (deleteCache)
+ {
+ delete[] m_mseSources;
+ m_mseSources = NULL;
+ }
+ }
+ }
- // Clear cache of joystick sources
- if (m_anyJoySources != NULL)
- {
- for (int joyIndex = 0; joyIndex < NUM_JOY_PARTS; joyIndex++)
- ReleaseSource(m_anyJoySources[joyIndex]);
- if (deleteCache)
- {
- delete[] m_anyJoySources;
- m_anyJoySources = NULL;
- }
- if (m_numJoys != ANY_JOYSTICK)
- {
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- {
- for (int joyIndex = 0; joyIndex < NUM_JOY_PARTS; joyIndex++)
- ReleaseSource(m_joySources[joyNum][joyIndex]);
- if (deleteCache)
- delete[] m_joySources[joyNum];
- }
- if (deleteCache)
- {
- delete[] m_joySources;
- m_joySources = NULL;
- }
- }
- }
+ // Clear cache of joystick sources
+ if (m_anyJoySources != NULL)
+ {
+ for (int joyIndex = 0; joyIndex < NUM_JOY_PARTS; joyIndex++)
+ ReleaseSource(m_anyJoySources[joyIndex]);
+ if (deleteCache)
+ {
+ delete[] m_anyJoySources;
+ m_anyJoySources = NULL;
+ }
+ if (m_numJoys != ANY_JOYSTICK)
+ {
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ for (int joyIndex = 0; joyIndex < NUM_JOY_PARTS; joyIndex++)
+ ReleaseSource(m_joySources[joyNum][joyIndex]);
+ if (deleteCache)
+ delete[] m_joySources[joyNum];
+ }
+ if (deleteCache)
+ {
+ delete[] m_joySources;
+ m_joySources = NULL;
+ }
+ }
+ }
}
void CInputSystem::ReleaseSource(CInputSource *&source)
{
- if (source != NULL)
- source->Release();
- source = NULL;
+ if (source != NULL)
+ source->Release();
+ source = NULL;
}
-
+
CInputSource *CInputSystem::GetKeySource(int kbdNum, int keyIndex)
{
- if (kbdNum == ANY_KEYBOARD)
- {
- // Check keyboard source cache first
- if (m_anyKeySources[keyIndex] == NULL)
- {
- if (m_numKbds == ANY_KEYBOARD)
- m_anyKeySources[keyIndex] = CreateKeySource(ANY_KEYBOARD, keyIndex);
- else
- m_anyKeySources[keyIndex] = CreateAnyKeySource(keyIndex);
- m_anyKeySources[keyIndex]->Acquire();
- }
- return m_anyKeySources[keyIndex];
- }
- else if (kbdNum < m_numKbds)
- {
- // Check keyboard source cache first
- if (m_keySources[kbdNum][keyIndex] == NULL)
- {
- m_keySources[kbdNum][keyIndex] = CreateKeySource(kbdNum, keyIndex);
- m_keySources[kbdNum][keyIndex]->Acquire();
- }
- return m_keySources[kbdNum][keyIndex];
- }
- else
- return m_emptySource;
+ if (kbdNum == ANY_KEYBOARD)
+ {
+ // Check keyboard source cache first
+ if (m_anyKeySources[keyIndex] == NULL)
+ {
+ if (m_numKbds == ANY_KEYBOARD)
+ m_anyKeySources[keyIndex] = CreateKeySource(ANY_KEYBOARD, keyIndex);
+ else
+ m_anyKeySources[keyIndex] = CreateAnyKeySource(keyIndex);
+ m_anyKeySources[keyIndex]->Acquire();
+ }
+ return m_anyKeySources[keyIndex];
+ }
+ else if (kbdNum < m_numKbds)
+ {
+ // Check keyboard source cache first
+ if (m_keySources[kbdNum][keyIndex] == NULL)
+ {
+ m_keySources[kbdNum][keyIndex] = CreateKeySource(kbdNum, keyIndex);
+ m_keySources[kbdNum][keyIndex]->Acquire();
+ }
+ return m_keySources[kbdNum][keyIndex];
+ }
+ else
+ return m_emptySource;
}
CInputSource *CInputSystem::GetMouseSource(int mseNum, EMousePart msePart)
{
- int mseIndex = (int)msePart;
- if (mseNum == ANY_MOUSE)
- {
- // Check mouse source cache first
- if (m_anyMseSources[mseIndex] == NULL)
- {
- if (m_numMice == ANY_MOUSE)
- m_anyMseSources[mseIndex] = CreateMouseSource(ANY_MOUSE, msePart);
- else
- m_anyMseSources[mseIndex] = CreateAnyMouseSource(msePart);
- m_anyMseSources[mseIndex]->Acquire();
- }
- return m_anyMseSources[mseIndex];
- }
- else if (mseNum < m_numMice)
- {
- // Check mouse source cache first
- if (m_mseSources[mseNum][mseIndex] == NULL)
- {
- m_mseSources[mseNum][mseIndex] = CreateMouseSource(mseNum, msePart);
- m_mseSources[mseNum][mseIndex]->Acquire();
- }
- return m_mseSources[mseNum][mseIndex];
- }
- else
- return m_emptySource;
+ int mseIndex = (int)msePart;
+ if (mseNum == ANY_MOUSE)
+ {
+ // Check mouse source cache first
+ if (m_anyMseSources[mseIndex] == NULL)
+ {
+ if (m_numMice == ANY_MOUSE)
+ m_anyMseSources[mseIndex] = CreateMouseSource(ANY_MOUSE, msePart);
+ else
+ m_anyMseSources[mseIndex] = CreateAnyMouseSource(msePart);
+ m_anyMseSources[mseIndex]->Acquire();
+ }
+ return m_anyMseSources[mseIndex];
+ }
+ else if (mseNum < m_numMice)
+ {
+ // Check mouse source cache first
+ if (m_mseSources[mseNum][mseIndex] == NULL)
+ {
+ m_mseSources[mseNum][mseIndex] = CreateMouseSource(mseNum, msePart);
+ m_mseSources[mseNum][mseIndex]->Acquire();
+ }
+ return m_mseSources[mseNum][mseIndex];
+ }
+ else
+ return m_emptySource;
}
CInputSource *CInputSystem::GetJoySource(int joyNum, EJoyPart joyPart)
{
- int joyIndex = (int)joyPart;
- if (joyNum == ANY_JOYSTICK)
- {
- // Check joystick source cache first
- if (m_anyJoySources[joyIndex] == NULL)
- {
- if (m_numJoys == ANY_JOYSTICK)
- m_anyJoySources[joyIndex] = CreateJoySource(ANY_JOYSTICK, joyPart);
- else
- m_anyJoySources[joyIndex] = CreateAnyJoySource(joyPart);
- m_anyJoySources[joyIndex]->Acquire();
- }
- return m_anyJoySources[joyIndex];
- }
- else if (joyNum < m_numJoys)
- {
- // Check joystick source cache first
- if (m_joySources[joyNum][joyIndex] == NULL)
- {
- m_joySources[joyNum][joyIndex] = CreateJoySource(joyNum, joyPart);
- m_joySources[joyNum][joyIndex]->Acquire();
- }
- return m_joySources[joyNum][joyIndex];
- }
- else
- return m_emptySource;
+ int joyIndex = (int)joyPart;
+ if (joyNum == ANY_JOYSTICK)
+ {
+ // Check joystick source cache first
+ if (m_anyJoySources[joyIndex] == NULL)
+ {
+ if (m_numJoys == ANY_JOYSTICK)
+ m_anyJoySources[joyIndex] = CreateJoySource(ANY_JOYSTICK, joyPart);
+ else
+ m_anyJoySources[joyIndex] = CreateAnyJoySource(joyPart);
+ m_anyJoySources[joyIndex]->Acquire();
+ }
+ return m_anyJoySources[joyIndex];
+ }
+ else if (joyNum < m_numJoys)
+ {
+ // Check joystick source cache first
+ if (m_joySources[joyNum][joyIndex] == NULL)
+ {
+ m_joySources[joyNum][joyIndex] = CreateJoySource(joyNum, joyPart);
+ m_joySources[joyNum][joyIndex]->Acquire();
+ }
+ return m_joySources[joyNum][joyIndex];
+ }
+ else
+ return m_emptySource;
}
void CInputSystem::CheckAllSources(unsigned readFlags, bool fullAxisOnly, bool &mseCentered, vector &sources, string &mapping, vector &badSources)
{
- // See if should read keyboards
- if (readFlags & READ_KEYBOARD)
- {
- // Check all keyboard sources for inputs, merging devices if required
- if ((readFlags & READ_MERGE_KEYBOARD) || m_numKbds == ANY_KEYBOARD)
- CheckKeySources(ANY_KEYBOARD, fullAxisOnly, sources, mapping, badSources);
- else
- {
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- CheckKeySources(kbdNum, fullAxisOnly, sources, mapping, badSources);
- }
- }
+ // See if should read keyboards
+ if (readFlags & READ_KEYBOARD)
+ {
+ // Check all keyboard sources for inputs, merging devices if required
+ if ((readFlags & READ_MERGE_KEYBOARD) || m_numKbds == ANY_KEYBOARD)
+ CheckKeySources(ANY_KEYBOARD, fullAxisOnly, sources, mapping, badSources);
+ else
+ {
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ CheckKeySources(kbdNum, fullAxisOnly, sources, mapping, badSources);
+ }
+ }
- // See if should read mice
- if (readFlags & READ_MOUSE)
- {
- // For mouse input, wait until mouse is in centre of display before parsing X- and Y-axis movements
- if (!mseCentered)
- mseCentered = ConfigMouseCentered();
-
- // Check all mouse sources for input, merging devices if required
- if ((readFlags & READ_MERGE_MOUSE) || m_numMice == ANY_MOUSE)
- CheckMouseSources(ANY_MOUSE, fullAxisOnly, mseCentered, sources, mapping, badSources);
- else
- {
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- CheckMouseSources(mseNum, fullAxisOnly, mseCentered, sources, mapping, badSources);
- }
- }
-
- // See if should read joysticks
- if (readFlags & READ_JOYSTICK)
- {
- // Check all joystick sources, merging devices if required
- if ((readFlags & READ_MERGE_JOYSTICK) || m_numJoys == ANY_JOYSTICK)
- CheckJoySources(ANY_JOYSTICK, fullAxisOnly, sources, mapping, badSources);
- else
- {
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- CheckJoySources(joyNum, fullAxisOnly, sources, mapping, badSources);
- }
- }
+ // See if should read mice
+ if (readFlags & READ_MOUSE)
+ {
+ // For mouse input, wait until mouse is in centre of display before parsing X- and Y-axis movements
+ if (!mseCentered)
+ mseCentered = ConfigMouseCentered();
+
+ // Check all mouse sources for input, merging devices if required
+ if ((readFlags & READ_MERGE_MOUSE) || m_numMice == ANY_MOUSE)
+ CheckMouseSources(ANY_MOUSE, fullAxisOnly, mseCentered, sources, mapping, badSources);
+ else
+ {
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ CheckMouseSources(mseNum, fullAxisOnly, mseCentered, sources, mapping, badSources);
+ }
+ }
+
+ // See if should read joysticks
+ if (readFlags & READ_JOYSTICK)
+ {
+ // Check all joystick sources, merging devices if required
+ if ((readFlags & READ_MERGE_JOYSTICK) || m_numJoys == ANY_JOYSTICK)
+ CheckJoySources(ANY_JOYSTICK, fullAxisOnly, sources, mapping, badSources);
+ else
+ {
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ CheckJoySources(joyNum, fullAxisOnly, sources, mapping, badSources);
+ }
+ }
}
void CInputSystem::CheckKeySources(int kbdNum, bool fullAxisOnly, vector &sources, string &mapping, vector &badSources)
{
- // Loop through all valid keys
- for (size_t i = 0; i < NUM_VALID_KEYS; i++)
- {
- const char *keyName = s_validKeyNames[i];
- int keyIndex = GetKeyIndex(keyName);
- if (keyIndex < 0)
- continue;
- // Get key source for keyboard number and key and test to see if it is active (but was not previously) and that it is not a "bad" source
- CInputSource *source = GetKeySource(kbdNum, keyIndex);
- if (source != NULL && source->IsActive() && find(sources.begin(), sources.end(), source) == sources.end() &&
- find(badSources.begin(), badSources.end(), source) == badSources.end())
- {
- // Update mapping string and add source to list
- if (sources.size() == 0)
- mapping.assign("KEY");
- else
- mapping.append("+KEY");
- if (kbdNum >= 0)
- mapping.append(IntToString(kbdNum + 1));
- mapping.append("_");
- mapping.append(keyName);
- sources.push_back(source);
- }
- }
+ // Loop through all valid keys
+ for (size_t i = 0; i < NUM_VALID_KEYS; i++)
+ {
+ const char *keyName = s_validKeyNames[i];
+ int keyIndex = GetKeyIndex(keyName);
+ if (keyIndex < 0)
+ continue;
+ // Get key source for keyboard number and key and test to see if it is active (but was not previously) and that it is not a "bad" source
+ CInputSource *source = GetKeySource(kbdNum, keyIndex);
+ if (source != NULL && source->IsActive() && find(sources.begin(), sources.end(), source) == sources.end() &&
+ find(badSources.begin(), badSources.end(), source) == badSources.end())
+ {
+ // Update mapping string and add source to list
+ if (sources.size() == 0)
+ mapping.assign("KEY");
+ else
+ mapping.append("+KEY");
+ if (kbdNum >= 0)
+ mapping.append(IntToString(kbdNum + 1));
+ mapping.append("_");
+ mapping.append(keyName);
+ sources.push_back(source);
+ }
+ }
}
void CInputSystem::CheckMouseSources(int mseNum, bool fullAxisOnly, bool mseCentered, vector &sources, string &mapping, vector &badSources)
{
- // Loop through all mouse parts
- for (int mseIndex = 0; mseIndex < NUM_MOUSE_PARTS; mseIndex++)
- {
- EMousePart msePart = (EMousePart)mseIndex;
- // Get axis details
- int axisNum;
- int axisDir;
- bool isAxis = GetAxisDetails(msePart, axisNum, axisDir);
- bool isXYAxis = isAxis && (axisNum == AXIS_X || axisNum == AXIS_Y);
- // Ignore X- & Y-axes if mouse hasn't been centered yet and filter axes according to fullAxisOnly
- if ((isXYAxis && !mseCentered) || (isAxis && ((IsFullAxis(msePart) && !fullAxisOnly) || (!IsFullAxis(msePart) && fullAxisOnly))))
- continue;
- // Get mouse source for mouse number and part and test to see if it is active (but was not previously) and that it is not a "bad" source
- CInputSource *source = GetMouseSource(mseNum, msePart);
- if (source != NULL && source->IsActive() && find(sources.begin(), sources.end(), source) == sources.end() &&
- find(badSources.begin(), badSources.end(), source) == badSources.end())
- {
- // Otherwise, update mapping string and add source to list
- const char *partName = LookupName(msePart);
- if (sources.size() == 0)
- mapping.assign("MOUSE");
- else
- mapping.append("+MOUSE");
- if (mseNum >= 0)
- mapping.append(IntToString(mseNum + 1));
- mapping.append("_");
- mapping.append(partName);
- sources.push_back(source);
- }
- }
+ // Loop through all mouse parts
+ for (int mseIndex = 0; mseIndex < NUM_MOUSE_PARTS; mseIndex++)
+ {
+ EMousePart msePart = (EMousePart)mseIndex;
+ // Get axis details
+ int axisNum;
+ int axisDir;
+ bool isAxis = GetAxisDetails(msePart, axisNum, axisDir);
+ bool isXYAxis = isAxis && (axisNum == AXIS_X || axisNum == AXIS_Y);
+ // Ignore X- & Y-axes if mouse hasn't been centered yet and filter axes according to fullAxisOnly
+ if ((isXYAxis && !mseCentered) || (isAxis && ((IsFullAxis(msePart) && !fullAxisOnly) || (!IsFullAxis(msePart) && fullAxisOnly))))
+ continue;
+ // Get mouse source for mouse number and part and test to see if it is active (but was not previously) and that it is not a "bad" source
+ CInputSource *source = GetMouseSource(mseNum, msePart);
+ if (source != NULL && source->IsActive() && find(sources.begin(), sources.end(), source) == sources.end() &&
+ find(badSources.begin(), badSources.end(), source) == badSources.end())
+ {
+ // Otherwise, update mapping string and add source to list
+ const char *partName = LookupName(msePart);
+ if (sources.size() == 0)
+ mapping.assign("MOUSE");
+ else
+ mapping.append("+MOUSE");
+ if (mseNum >= 0)
+ mapping.append(IntToString(mseNum + 1));
+ mapping.append("_");
+ mapping.append(partName);
+ sources.push_back(source);
+ }
+ }
}
void CInputSystem::CheckJoySources(int joyNum, bool fullAxisOnly, vector &sources, string &mapping, vector &badSources)
{
- // Loop through all joystick parts
- for (int joyIndex = 0; joyIndex < NUM_JOY_PARTS; joyIndex++)
- {
- EJoyPart joyPart = (EJoyPart)joyIndex;
- // Filter axes according to fullAxisOnly
- if (IsAxis(joyPart) && ((IsFullAxis(joyPart) && !fullAxisOnly) || (!IsFullAxis(joyPart) && fullAxisOnly)))
- continue;
- // Get joystick source for joystick number and part and test to see if it is active (but was not previously) and that it is not a "bad" source
- CInputSource *source = GetJoySource(joyNum, joyPart);
- if (source != NULL && source->IsActive() && find(sources.begin(), sources.end(), source) == sources.end() &&
- find(badSources.begin(), badSources.end(), source) == badSources.end())
- {
- // Otherwise, update mapping string and add source to list
- const char *partName = LookupName(joyPart);
- if (sources.size() == 0)
- mapping.assign("JOY");
- else
- mapping.append("+JOY");
- if (joyNum >= 0)
- mapping.append(IntToString(joyNum + 1));
- mapping.append("_");
- mapping.append(partName);
- sources.push_back(source);
- }
- }
+ // Loop through all joystick parts
+ for (int joyIndex = 0; joyIndex < NUM_JOY_PARTS; joyIndex++)
+ {
+ EJoyPart joyPart = (EJoyPart)joyIndex;
+ // Filter axes according to fullAxisOnly
+ if (IsAxis(joyPart) && ((IsFullAxis(joyPart) && !fullAxisOnly) || (!IsFullAxis(joyPart) && fullAxisOnly)))
+ continue;
+ // Get joystick source for joystick number and part and test to see if it is active (but was not previously) and that it is not a "bad" source
+ CInputSource *source = GetJoySource(joyNum, joyPart);
+ if (source != NULL && source->IsActive() && find(sources.begin(), sources.end(), source) == sources.end() &&
+ find(badSources.begin(), badSources.end(), source) == badSources.end())
+ {
+ // Otherwise, update mapping string and add source to list
+ const char *partName = LookupName(joyPart);
+ if (sources.size() == 0)
+ mapping.assign("JOY");
+ else
+ mapping.append("+JOY");
+ if (joyNum >= 0)
+ mapping.append(IntToString(joyNum + 1));
+ mapping.append("_");
+ mapping.append(partName);
+ sources.push_back(source);
+ }
+ }
}
bool CInputSystem::ParseInt(string str, int &num)
{
- stringstream ss(str);
- return !(ss >> num).fail();
+ stringstream ss(str);
+ return !(ss >> num).fail();
}
string CInputSystem::IntToString(int num)
{
- stringstream ss;
- ss << num;
- return ss.str();
+ stringstream ss;
+ ss << num;
+ return ss.str();
}
bool CInputSystem::EqualsIgnoreCase(string str1, const char *str2)
{
- for (string::const_iterator ci = str1.begin(); ci < str1.end(); ci++)
- {
- if (*str2 == '\0' || tolower(*ci) != tolower(*str2))
- return false;
- str2++;
- }
- return *str2 == '\0';
+ for (string::const_iterator ci = str1.begin(); ci < str1.end(); ci++)
+ {
+ if (*str2 == '\0' || tolower(*ci) != tolower(*str2))
+ return false;
+ str2++;
+ }
+ return *str2 == '\0';
}
bool CInputSystem::StartsWithIgnoreCase(string str1, const char *str2)
{
- for (string::const_iterator ci = str1.begin(); ci < str1.end(); ci++)
- {
- if (*str2 == '\0')
- return true;
- if (tolower(*ci) != tolower(*str2))
- return false;
- str2++;
- }
- return *str2 == '\0';
+ for (string::const_iterator ci = str1.begin(); ci < str1.end(); ci++)
+ {
+ if (*str2 == '\0')
+ return true;
+ if (tolower(*ci) != tolower(*str2))
+ return false;
+ str2++;
+ }
+ return *str2 == '\0';
}
bool CInputSystem::IsValidKeyName(string str)
{
- for (size_t i = 0; i < NUM_VALID_KEYS; i++)
- {
- if (EqualsIgnoreCase(str, s_validKeyNames[i]))
- return true;
- }
- return false;
+ for (size_t i = 0; i < NUM_VALID_KEYS; i++)
+ {
+ if (EqualsIgnoreCase(str, s_validKeyNames[i]))
+ return true;
+ }
+ return false;
}
EMousePart CInputSystem::LookupMousePart(string str)
{
- for (int i = 0; s_mseParts[i].id != NULL; i++)
- {
- if (EqualsIgnoreCase(str, s_mseParts[i].id))
- return s_mseParts[i].msePart;
- }
- return MouseUnknown;
+ for (int i = 0; s_mseParts[i].id != NULL; i++)
+ {
+ if (EqualsIgnoreCase(str, s_mseParts[i].id))
+ return s_mseParts[i].msePart;
+ }
+ return MouseUnknown;
}
const char *CInputSystem::LookupName(EMousePart msePart)
{
- for (int i = 0; s_mseParts[i].id != NULL; i++)
- {
- if (msePart == s_mseParts[i].msePart)
- return s_mseParts[i].id;
- }
- return NULL;
+ for (int i = 0; s_mseParts[i].id != NULL; i++)
+ {
+ if (msePart == s_mseParts[i].msePart)
+ return s_mseParts[i].id;
+ }
+ return NULL;
}
EJoyPart CInputSystem::LookupJoyPart(string str)
{
- for (int i = 0; s_joyParts[i].id != NULL; i++)
- {
- if (EqualsIgnoreCase(str, s_joyParts[i].id))
- return s_joyParts[i].joyPart;
- }
- return JoyUnknown;
+ for (int i = 0; s_joyParts[i].id != NULL; i++)
+ {
+ if (EqualsIgnoreCase(str, s_joyParts[i].id))
+ return s_joyParts[i].joyPart;
+ }
+ return JoyUnknown;
}
const char *CInputSystem::LookupName(EJoyPart joyPart)
{
- for (int i = 0; s_joyParts[i].id != NULL; i++)
- {
- if (joyPart == s_joyParts[i].joyPart)
- return s_joyParts[i].id;
- }
- return NULL;
+ for (int i = 0; s_joyParts[i].id != NULL; i++)
+ {
+ if (joyPart == s_joyParts[i].joyPart)
+ return s_joyParts[i].id;
+ }
+ return NULL;
}
size_t CInputSystem::ParseDevMapping(string str, const char *devType, int &devNum)
{
- if (!StartsWithIgnoreCase(str, devType))
- return -1;
- size_t size = str.size();
- size_t devLen = strlen(devType);
+ if (!StartsWithIgnoreCase(str, devType))
+ return -1;
+ size_t size = str.size();
+ size_t devLen = strlen(devType);
- // Parse optional device number
- devNum = -1;
- size_t i = devLen;
- while (i < size && isdigit(str[i]))
- i++;
- if (i > devLen && i < size)
- {
- if (!ParseInt(str.substr(devLen, i), devNum))
- return -1;
- devNum--;
- }
+ // Parse optional device number
+ devNum = -1;
+ size_t i = devLen;
+ while (i < size && isdigit(str[i]))
+ i++;
+ if (i > devLen && i < size)
+ {
+ if (!ParseInt(str.substr(devLen, i), devNum))
+ return -1;
+ devNum--;
+ }
- // Check hyphen preceeds device part
- if (i < size - 1 && str[i] == '_')
- return i + 1;
- else
- return -1;
+ // Check hyphen preceeds device part
+ if (i < size - 1 && str[i] == '_')
+ return i + 1;
+ else
+ return -1;
}
CInputSource* CInputSystem::ParseMultiSource(string str, bool fullAxisOnly, bool isOr)
{
- // Check for empty or NONE mapping
- size_t size = str.size();
- if (size == 0 || EqualsIgnoreCase(str, "NONE"))
- return NULL;
+ // Check for empty or NONE mapping
+ size_t size = str.size();
+ if (size == 0 || EqualsIgnoreCase(str, "NONE"))
+ return NULL;
- CInputSource *source = NULL;
- bool isMulti = false;
- vector sources;
+ CInputSource *source = NULL;
+ bool isMulti = false;
+ vector sources;
- size_t start = 0;
- size_t end;
- do
- {
- // Remove leading whitespace/quotes and see if have any plusses/commas in mapping (to specify and/or multiple assignments)
- while ((isspace(str[start]) || str[start] == '"') && start < size - 1)
- start++;
- char delim = (isOr ? ',' : '+');
- end = str.find(delim, start);
- if (end == string::npos)
- end = size;
+ size_t start = 0;
+ size_t end;
+ do
+ {
+ // Remove leading whitespace/quotes and see if have any plusses/commas in mapping (to specify and/or multiple assignments)
+ while ((isspace(str[start]) || str[start] == '"') && start < size - 1)
+ start++;
+ char delim = (isOr ? ',' : '+');
+ end = str.find(delim, start);
+ if (end == string::npos)
+ end = size;
- // Remove tailing whitespace/quotes
- size_t subEnd = end;
- while (subEnd > 0 && (isspace(str[subEnd - 1]) || str[start] == '"'))
- subEnd--;
- string subStr = str.substr(start, subEnd - start);
- start = end + 1;
+ // Remove tailing whitespace/quotes
+ size_t subEnd = end;
+ while (subEnd > 0 && (isspace(str[subEnd - 1]) || str[start] == '"'))
+ subEnd--;
+ string subStr = str.substr(start, subEnd - start);
+ start = end + 1;
- // Parse the multi/single source in substring
- CInputSource *parsed;
- if (isOr)
- parsed = ParseMultiSource(subStr, fullAxisOnly, false);
- else
- parsed = ParseSingleSource(subStr);
+ // Parse the multi/single source in substring
+ CInputSource *parsed;
+ if (isOr)
+ parsed = ParseMultiSource(subStr, fullAxisOnly, false);
+ else
+ parsed = ParseSingleSource(subStr);
- // Check the result is valid
- if ((parsed != NULL) && (parsed->type != SourceInvalid) &&
- ((parsed->type == SourceEmpty) || (parsed->type == SourceFullAxis && fullAxisOnly) || (parsed->type != SourceFullAxis && !fullAxisOnly)))
- {
- // Keep track of all sources parsed
- if (isMulti)
- sources.push_back(parsed);
- else if (source != NULL)
- {
- sources.push_back(source);
- sources.push_back(parsed);
- isMulti = true;
- }
- else
- source = parsed;
- }
- }
- while (start < size);
+ // Check the result is valid
+ if ((parsed != NULL) && (parsed->type != SourceInvalid) &&
+ ((parsed->type == SourceEmpty) || (parsed->type == SourceFullAxis && fullAxisOnly) || (parsed->type != SourceFullAxis && !fullAxisOnly)))
+ {
+ // Keep track of all sources parsed
+ if (isMulti)
+ sources.push_back(parsed);
+ else if (source != NULL)
+ {
+ sources.push_back(source);
+ sources.push_back(parsed);
+ isMulti = true;
+ }
+ else
+ source = parsed;
+ }
+ }
+ while (start < size);
- // If only parsed a single source, return that, otherwise return a CMultiInputSource combining all the sources
- return (isMulti ? new CMultiInputSource(isOr, sources) : source);
+ // If only parsed a single source, return that, otherwise return a CMultiInputSource combining all the sources
+ return (isMulti ? new CMultiInputSource(isOr, sources) : source);
}
CInputSource *CInputSystem::ParseSingleSource(string str)
{
- // First, check for ! at beginning of string, which means input source must not be activated
- if (str[0] == '!')
- {
- // If found, skip any whitespace after that and get remaining string and parse it again
- size_t i = 1;
- while (i < str.size() && str[i] == ' ')
- i++;
- str.erase(0, i);
+ // First, check for ! at beginning of string, which means input source must not be activated
+ if (str[0] == '!')
+ {
+ // If found, skip any whitespace after that and get remaining string and parse it again
+ size_t i = 1;
+ while (i < str.size() && str[i] == ' ')
+ i++;
+ str.erase(0, i);
- CInputSource *source = ParseSingleSource(str);
- if (source != NULL && source != m_emptySource)
- return new CNegInputSource(source);
- else
- return source;
- }
+ CInputSource *source = ParseSingleSource(str);
+ if (source != NULL && source != m_emptySource)
+ return new CNegInputSource(source);
+ else
+ return source;
+ }
- // Try parsing a key mapping
- int kbdNum;
- int keyNameIndex = ParseDevMapping(str, "KEY", kbdNum);
- if (keyNameIndex >= 0)
- {
- string keyName = str.substr(keyNameIndex);
- if (IsValidKeyName(keyName))
- {
- // Lookup key index and map to key source
- int keyIndex = GetKeyIndex(keyName.c_str());
- if (keyIndex >= 0)
- return GetKeySource(kbdNum, keyIndex);
- else if (EqualsIgnoreCase(keyName, "SHIFT") || EqualsIgnoreCase(keyName, "CTRL") || EqualsIgnoreCase(keyName, "ALT"))
- {
- // Handle special cases if not handled by subclass: SHIFT, CTRL and ALT
- string leftName = "LEFT" + keyName;
- string rightName = "RIGHT" + keyName;
- int leftIndex = GetKeyIndex(leftName.c_str());
- int rightIndex = GetKeyIndex(rightName.c_str());
- vector sources;
- if (leftIndex >= 0)
- {
- CInputSource *leftSource = GetKeySource(kbdNum, leftIndex);
- if (leftSource != NULL)
- sources.push_back(leftSource);
- }
- if (rightIndex >= 0)
- {
- CInputSource *rightSource = GetKeySource(kbdNum, rightIndex);
- if (rightSource != NULL)
- sources.push_back(rightSource);
- }
- if (sources.size() > 0)
- return new CMultiInputSource(true, sources);
- }
- return m_emptySource;
- }
- }
-
- // Try parsing a mouse mapping
- int mseNum;
- int msePartIndex = ParseDevMapping(str, "MOUSE", mseNum);
- if (msePartIndex >= 0)
- {
- // Lookup mouse part and map to mouse source
- EMousePart msePart = LookupMousePart(str.substr(msePartIndex));
- if (msePart != MouseUnknown)
- return GetMouseSource(mseNum, msePart);
- }
+ // Try parsing a key mapping
+ int kbdNum;
+ int keyNameIndex = ParseDevMapping(str, "KEY", kbdNum);
+ if (keyNameIndex >= 0)
+ {
+ string keyName = str.substr(keyNameIndex);
+ if (IsValidKeyName(keyName))
+ {
+ // Lookup key index and map to key source
+ int keyIndex = GetKeyIndex(keyName.c_str());
+ if (keyIndex >= 0)
+ return GetKeySource(kbdNum, keyIndex);
+ else if (EqualsIgnoreCase(keyName, "SHIFT") || EqualsIgnoreCase(keyName, "CTRL") || EqualsIgnoreCase(keyName, "ALT"))
+ {
+ // Handle special cases if not handled by subclass: SHIFT, CTRL and ALT
+ string leftName = "LEFT" + keyName;
+ string rightName = "RIGHT" + keyName;
+ int leftIndex = GetKeyIndex(leftName.c_str());
+ int rightIndex = GetKeyIndex(rightName.c_str());
+ vector sources;
+ if (leftIndex >= 0)
+ {
+ CInputSource *leftSource = GetKeySource(kbdNum, leftIndex);
+ if (leftSource != NULL)
+ sources.push_back(leftSource);
+ }
+ if (rightIndex >= 0)
+ {
+ CInputSource *rightSource = GetKeySource(kbdNum, rightIndex);
+ if (rightSource != NULL)
+ sources.push_back(rightSource);
+ }
+ if (sources.size() > 0)
+ return new CMultiInputSource(true, sources);
+ }
+ return m_emptySource;
+ }
+ }
+
+ // Try parsing a mouse mapping
+ int mseNum;
+ int msePartIndex = ParseDevMapping(str, "MOUSE", mseNum);
+ if (msePartIndex >= 0)
+ {
+ // Lookup mouse part and map to mouse source
+ EMousePart msePart = LookupMousePart(str.substr(msePartIndex));
+ if (msePart != MouseUnknown)
+ return GetMouseSource(mseNum, msePart);
+ }
- // Try parsing a joystick mapping
- int joyNum;
- int joyPartIndex = ParseDevMapping(str, "JOY", joyNum);
- if (joyPartIndex >= 0)
- {
- // Lookup joystick part and map to joystick source
- EJoyPart joyPart = LookupJoyPart(str.substr(joyPartIndex));
- if (joyPart != JoyUnknown)
- return GetJoySource(joyNum, joyPart);
- }
+ // Try parsing a joystick mapping
+ int joyNum;
+ int joyPartIndex = ParseDevMapping(str, "JOY", joyNum);
+ if (joyPartIndex >= 0)
+ {
+ // Lookup joystick part and map to joystick source
+ EJoyPart joyPart = LookupJoyPart(str.substr(joyPartIndex));
+ if (joyPart != JoyUnknown)
+ return GetJoySource(joyNum, joyPart);
+ }
- // As last option, assume mapping is just a key name and try creating keyboard source from it (to retain compatibility with previous
- // versions of Supermodel)
- if (IsValidKeyName(str))
- {
- // Lookup key index and map to key source
- int keyIndex = GetKeyIndex(str.c_str());
- if (keyIndex >= 0)
- return GetKeySource(ANY_KEYBOARD, keyIndex);
- else
- return m_emptySource;
- }
+ // As last option, assume mapping is just a key name and try creating keyboard source from it (to retain compatibility with previous
+ // versions of Supermodel)
+ if (IsValidKeyName(str))
+ {
+ // Lookup key index and map to key source
+ int keyIndex = GetKeyIndex(str.c_str());
+ if (keyIndex >= 0)
+ return GetKeySource(ANY_KEYBOARD, keyIndex);
+ else
+ return m_emptySource;
+ }
- // If got here, it was not possible to parse mapping string so return NULL
- return NULL;
+ // If got here, it was not possible to parse mapping string so return NULL
+ return NULL;
}
void CInputSystem::PrintKeySettings(int kbdNum, KeySettings *settings)
{
- printf(" Sensitivity = %u %%\n", settings->sensitivity);
- printf(" Decay Speed = %u %%\n", settings->decaySpeed);
+ printf(" Sensitivity = %u %%\n", settings->sensitivity);
+ printf(" Decay Speed = %u %%\n", settings->decaySpeed);
+}
+
+KeySettings *CInputSystem::LoadKeySettings(const Util::Config::Node &config, int kbdNum)
+{
+ // Get common key settings and create new key settings based on that
+ KeySettings *common = (kbdNum != ANY_KEYBOARD ? GetKeySettings(ANY_KEYBOARD, true) : &m_defKeySettings);
+ KeySettings *settings = new KeySettings(*common);
+ settings->kbdNum = kbdNum;
+
+ // Read settings from ini file
+ string baseKey("InputKey");
+ if (kbdNum != ANY_KEYBOARD)
+ baseKey.append(IntToString(kbdNum + 1));
+ bool read = false;
+ auto *node = config.TryGet(baseKey + "Sensitivity");
+ if (node)
+ {
+ settings->sensitivity = node->ValueAs();
+ read |= true;
+ }
+ node = config.TryGet(baseKey + "DecaySpeed");
+ if (node)
+ {
+ settings->decaySpeed = node->ValueAs();
+ read |= true;
+ }
+ if (read)
+ return settings;
+ delete settings;
+ return NULL;
+}
+
+void CInputSystem::StoreKeySettings(Util::Config::Node *config, KeySettings *settings)
+{
+ // Get common key settings
+ KeySettings *common = (settings->kbdNum != ANY_KEYBOARD ? GetKeySettings(ANY_KEYBOARD, true) : &m_defKeySettings);
+
+ // Write to ini file any settings that are different to common settings
+ string baseKey("InputKey");
+ if (settings->kbdNum != ANY_KEYBOARD)
+ baseKey.append(IntToString(settings->kbdNum + 1));
+ if (settings->sensitivity != common->sensitivity)
+ config->Set(baseKey + "Sensitivity", settings->sensitivity);
+ if (settings->decaySpeed != common->decaySpeed)
+ config->Set(baseKey + "DecaySpeed", settings->decaySpeed);
}
KeySettings *CInputSystem::ReadKeySettings(CINIFile *ini, const char *section, int kbdNum)
{
- // Get common key settings and create new key settings based on that
- KeySettings *common = (kbdNum != ANY_KEYBOARD ? GetKeySettings(ANY_KEYBOARD, true) : &m_defKeySettings);
- KeySettings *settings = new KeySettings(*common);
- settings->kbdNum = kbdNum;
+ // Get common key settings and create new key settings based on that
+ KeySettings *common = (kbdNum != ANY_KEYBOARD ? GetKeySettings(ANY_KEYBOARD, true) : &m_defKeySettings);
+ KeySettings *settings = new KeySettings(*common);
+ settings->kbdNum = kbdNum;
- // Read settings from ini file
- string baseKey("InputKey");
- if (kbdNum != ANY_KEYBOARD)
- baseKey.append(IntToString(kbdNum + 1));
- bool read = false;
- read |= ini->Get(section, baseKey + "Sensitivity", settings->sensitivity) == OKAY;
- read |= ini->Get(section, baseKey + "DecaySpeed", settings->decaySpeed) == OKAY;
- if (read)
- return settings;
- delete settings;
- return NULL;
+ // Read settings from ini file
+ string baseKey("InputKey");
+ if (kbdNum != ANY_KEYBOARD)
+ baseKey.append(IntToString(kbdNum + 1));
+ bool read = false;
+ read |= ini->Get(section, baseKey + "Sensitivity", settings->sensitivity) == OKAY;
+ read |= ini->Get(section, baseKey + "DecaySpeed", settings->decaySpeed) == OKAY;
+ if (read)
+ return settings;
+ delete settings;
+ return NULL;
}
void CInputSystem::WriteKeySettings(CINIFile *ini, const char *section, KeySettings *settings)
{
- // Get common key settings
- KeySettings *common = (settings->kbdNum != ANY_KEYBOARD ? GetKeySettings(ANY_KEYBOARD, true) : &m_defKeySettings);
+ // Get common key settings
+ KeySettings *common = (settings->kbdNum != ANY_KEYBOARD ? GetKeySettings(ANY_KEYBOARD, true) : &m_defKeySettings);
- // Write to ini file any settings that are different to common settings
- string baseKey("InputKey");
- if (settings->kbdNum != ANY_KEYBOARD)
- baseKey.append(IntToString(settings->kbdNum + 1));
- if (settings->sensitivity != common->sensitivity) ini->Set(section, baseKey + "Sensitivity", settings->sensitivity);
- if (settings->decaySpeed != common->decaySpeed) ini->Set(section, baseKey + "DecaySpeed", settings->decaySpeed);
+ // Write to ini file any settings that are different to common settings
+ string baseKey("InputKey");
+ if (settings->kbdNum != ANY_KEYBOARD)
+ baseKey.append(IntToString(settings->kbdNum + 1));
+ if (settings->sensitivity != common->sensitivity) ini->Set(section, baseKey + "Sensitivity", settings->sensitivity);
+ if (settings->decaySpeed != common->decaySpeed) ini->Set(section, baseKey + "DecaySpeed", settings->decaySpeed);
}
void CInputSystem::PrintMouseSettings(int mseNum, MouseSettings *settings)
{
- for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
- printf(" %-7s Dead Zone = %u %%\n", s_axisNames[axisNum], settings->deadZones[axisNum]);
+ for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
+ printf(" %-7s Dead Zone = %u %%\n", s_axisNames[axisNum], settings->deadZones[axisNum]);
+}
+
+MouseSettings *CInputSystem::LoadMouseSettings(const Util::Config::Node &config, int mseNum)
+{
+ // Get common mouse settings and create new mouse settings based on that
+ MouseSettings *common = (mseNum != ANY_MOUSE ? GetMouseSettings(ANY_MOUSE, true) : &m_defMseSettings);
+ MouseSettings *settings = new MouseSettings(*common);
+ settings->mseNum = mseNum;
+
+ // Read settings from ini file
+ string baseKey("InputMouse");
+ if (mseNum != ANY_MOUSE)
+ baseKey.append(IntToString(mseNum + 1));
+ bool read = false;
+ for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
+ {
+ auto *node = config.TryGet(baseKey + s_axisIds[axisNum] + "DeadZone");
+ if (node)
+ {
+ settings->deadZones[axisNum] = node->ValueAs();
+ read |= true;
+ }
+
+ }
+ if (read)
+ return settings;
+ delete settings;
+ return NULL;
+}
+
+void CInputSystem::StoreMouseSettings(Util::Config::Node *config, MouseSettings *settings)
+{
+ // Get common mouse settings
+ MouseSettings *common = (settings->mseNum != ANY_MOUSE ? GetMouseSettings(ANY_MOUSE, true) : &m_defMseSettings);
+
+ // Write to ini file any settings that are different to common/default settings
+ string baseKey("InputMouse");
+ if (settings->mseNum != ANY_MOUSE)
+ baseKey.append(IntToString(settings->mseNum + 1));
+ for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
+ {
+ if (settings->deadZones[axisNum] != common->deadZones[axisNum])
+ config->Set(baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]);
+ }
}
MouseSettings *CInputSystem::ReadMouseSettings(CINIFile *ini, const char *section, int mseNum)
{
- // Get common mouse settings and create new mouse settings based on that
- MouseSettings *common = (mseNum != ANY_MOUSE ? GetMouseSettings(ANY_MOUSE, true) : &m_defMseSettings);
- MouseSettings *settings = new MouseSettings(*common);
- settings->mseNum = mseNum;
+ // Get common mouse settings and create new mouse settings based on that
+ MouseSettings *common = (mseNum != ANY_MOUSE ? GetMouseSettings(ANY_MOUSE, true) : &m_defMseSettings);
+ MouseSettings *settings = new MouseSettings(*common);
+ settings->mseNum = mseNum;
- // Read settings from ini file
- string baseKey("InputMouse");
- if (mseNum != ANY_MOUSE)
- baseKey.append(IntToString(mseNum + 1));
- bool read = false;
- for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
- read |= ini->Get(section, baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]) == OKAY;
- if (read)
- return settings;
- delete settings;
- return NULL;
+ // Read settings from ini file
+ string baseKey("InputMouse");
+ if (mseNum != ANY_MOUSE)
+ baseKey.append(IntToString(mseNum + 1));
+ bool read = false;
+ for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
+ read |= ini->Get(section, baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]) == OKAY;
+ if (read)
+ return settings;
+ delete settings;
+ return NULL;
}
void CInputSystem::WriteMouseSettings(CINIFile *ini, const char *section, MouseSettings *settings)
{
- // Get common mouse settings
- MouseSettings *common = (settings->mseNum != ANY_MOUSE ? GetMouseSettings(ANY_MOUSE, true) : &m_defMseSettings);
-
- // Write to ini file any settings that are different to common/default settings
- string baseKey("InputMouse");
- if (settings->mseNum != ANY_MOUSE)
- baseKey.append(IntToString(settings->mseNum + 1));
- for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
- {
- if (settings->deadZones[axisNum] != common->deadZones[axisNum])
- ini->Set(section, baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]);
- }
+ // Get common mouse settings
+ MouseSettings *common = (settings->mseNum != ANY_MOUSE ? GetMouseSettings(ANY_MOUSE, true) : &m_defMseSettings);
+
+ // Write to ini file any settings that are different to common/default settings
+ string baseKey("InputMouse");
+ if (settings->mseNum != ANY_MOUSE)
+ baseKey.append(IntToString(settings->mseNum + 1));
+ for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
+ {
+ if (settings->deadZones[axisNum] != common->deadZones[axisNum])
+ ini->Set(section, baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]);
+ }
}
void CInputSystem::PrintJoySettings(int joyNum, JoySettings *settings)
{
- const JoyDetails *joyDetails = (joyNum != ANY_JOYSTICK ? GetJoyDetails(joyNum) : NULL);
- for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
- {
- if (joyDetails && !joyDetails->hasAxis[axisNum])
- continue;
- const char *axisName = s_axisNames[axisNum];
- printf(" %-7s Min Value = %d\n", axisName, settings->axisMinVals[axisNum]);
- printf(" %-7s Center/Off Value = %d\n", axisName, settings->axisOffVals[axisNum]);
- printf(" %-7s Max Value = %d\n", axisName, settings->axisMaxVals[axisNum]);
- printf(" %-7s Dead Zone = %u %%\n", axisName, settings->deadZones[axisNum]);
- printf(" %-7s Saturation = %u %%\n", axisName, settings->saturations[axisNum]);
- }
+ const JoyDetails *joyDetails = (joyNum != ANY_JOYSTICK ? GetJoyDetails(joyNum) : NULL);
+ for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
+ {
+ if (joyDetails && !joyDetails->hasAxis[axisNum])
+ continue;
+ const char *axisName = s_axisNames[axisNum];
+ printf(" %-7s Min Value = %d\n", axisName, settings->axisMinVals[axisNum]);
+ printf(" %-7s Center/Off Value = %d\n", axisName, settings->axisOffVals[axisNum]);
+ printf(" %-7s Max Value = %d\n", axisName, settings->axisMaxVals[axisNum]);
+ printf(" %-7s Dead Zone = %u %%\n", axisName, settings->deadZones[axisNum]);
+ printf(" %-7s Saturation = %u %%\n", axisName, settings->saturations[axisNum]);
+ }
+}
+
+JoySettings *CInputSystem::LoadJoySettings(const Util::Config::Node &config, int joyNum)
+{
+ // Get common/default joystick settings and create new joystick settings based on that
+ JoySettings *common = (joyNum != ANY_JOYSTICK ? GetJoySettings(ANY_JOYSTICK, true) : &m_defJoySettings);
+ JoySettings *settings = new JoySettings(*common);
+ settings->joyNum = joyNum;
+
+ // Read settings from ini file
+ string baseKey("InputJoy");
+ if (joyNum != ANY_JOYSTICK)
+ baseKey.append(IntToString(joyNum + 1));
+ bool read = false;
+ for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
+ {
+ const char *axisId = s_axisIds[axisNum];
+ auto *node = config.TryGet(baseKey + axisId + "MinVal");
+ if (node)
+ {
+ settings->axisMinVals[axisNum] = node->ValueAs();
+ read |= true;
+ }
+ node = config.TryGet(baseKey + axisId + "OffVal");
+ if (node)
+ {
+ settings->axisOffVals[axisNum] = node->ValueAs();
+ read |= true;
+ }
+ node = config.TryGet(baseKey + axisId + "MaxVal");
+ if (node)
+ {
+ settings->axisMaxVals[axisNum] = node->ValueAs();
+ read |= true;
+ }
+ node = config.TryGet(baseKey + axisId + "DeadZone");
+ if (node)
+ {
+ settings->deadZones[axisNum] = node->ValueAs();
+ read |= true;
+ }
+ node = config.TryGet(baseKey + axisId + "Saturation");
+ if (node)
+ {
+ settings->saturations[axisNum] = node->ValueAs();
+ read |= true;
+ }
+ }
+ if (read)
+ return settings;
+ delete settings;
+ return NULL;
+}
+
+void CInputSystem::StoreJoySettings(Util::Config::Node *config, JoySettings *settings)
+{
+ // Get common/default joystick settings
+ JoySettings *common = (settings->joyNum != ANY_JOYSTICK ? GetJoySettings(ANY_JOYSTICK, true) : &m_defJoySettings);
+
+ // Write to ini file any settings that are different to common/default settings
+ string baseKey("InputJoy");
+ if (settings->joyNum != ANY_JOYSTICK)
+ baseKey.append(IntToString(settings->joyNum + 1));
+ for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
+ {
+ const char *axisId = s_axisIds[axisNum];
+ if (settings->axisMinVals[axisNum] != common->axisMinVals[axisNum])
+ config->Set(baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]);
+ if (settings->axisOffVals[axisNum] != common->axisOffVals[axisNum])
+ config->Set(baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]);
+ if (settings->axisMaxVals[axisNum] != common->axisMaxVals[axisNum])
+ config->Set(baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]);
+ if (settings->deadZones[axisNum] != common->deadZones[axisNum])
+ config->Set(baseKey + axisId + "DeadZone", settings->deadZones[axisNum]);
+ if (settings->saturations[axisNum] != common->saturations[axisNum])
+ config->Set(baseKey + axisId + "Saturation", settings->saturations[axisNum]);
+ }
}
JoySettings *CInputSystem::ReadJoySettings(CINIFile *ini, const char *section, int joyNum)
{
- // Get common/default joystick settings and create new joystick settings based on that
- JoySettings *common = (joyNum != ANY_JOYSTICK ? GetJoySettings(ANY_JOYSTICK, true) : &m_defJoySettings);
- JoySettings *settings = new JoySettings(*common);
- settings->joyNum = joyNum;
+ // Get common/default joystick settings and create new joystick settings based on that
+ JoySettings *common = (joyNum != ANY_JOYSTICK ? GetJoySettings(ANY_JOYSTICK, true) : &m_defJoySettings);
+ JoySettings *settings = new JoySettings(*common);
+ settings->joyNum = joyNum;
- // Read settings from ini file
- string baseKey("InputJoy");
- if (joyNum != ANY_JOYSTICK)
- baseKey.append(IntToString(joyNum + 1));
- bool read = false;
- for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
- {
- const char *axisId = s_axisIds[axisNum];
- read |= ini->Get(section, baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]) == OKAY;
- read |= ini->Get(section, baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]) == OKAY;
- read |= ini->Get(section, baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]) == OKAY;
- read |= ini->Get(section, baseKey + axisId + "DeadZone", settings->deadZones[axisNum]) == OKAY;
- read |= ini->Get(section, baseKey + axisId + "Saturation", settings->saturations[axisNum]) == OKAY;
- }
- if (read)
- return settings;
- delete settings;
- return NULL;
+ // Read settings from ini file
+ string baseKey("InputJoy");
+ if (joyNum != ANY_JOYSTICK)
+ baseKey.append(IntToString(joyNum + 1));
+ bool read = false;
+ for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
+ {
+ const char *axisId = s_axisIds[axisNum];
+ read |= ini->Get(section, baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]) == OKAY;
+ read |= ini->Get(section, baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]) == OKAY;
+ read |= ini->Get(section, baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]) == OKAY;
+ read |= ini->Get(section, baseKey + axisId + "DeadZone", settings->deadZones[axisNum]) == OKAY;
+ read |= ini->Get(section, baseKey + axisId + "Saturation", settings->saturations[axisNum]) == OKAY;
+ }
+ if (read)
+ return settings;
+ delete settings;
+ return NULL;
}
void CInputSystem::WriteJoySettings(CINIFile *ini, const char *section, JoySettings *settings)
{
- // Get common/default joystick settings
- JoySettings *common = (settings->joyNum != ANY_JOYSTICK ? GetJoySettings(ANY_JOYSTICK, true) : &m_defJoySettings);
+ // Get common/default joystick settings
+ JoySettings *common = (settings->joyNum != ANY_JOYSTICK ? GetJoySettings(ANY_JOYSTICK, true) : &m_defJoySettings);
- // Write to ini file any settings that are different to common/default settings
- string baseKey("InputJoy");
- if (settings->joyNum != ANY_JOYSTICK)
- baseKey.append(IntToString(settings->joyNum + 1));
- for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
- {
- const char *axisId = s_axisIds[axisNum];
- if (settings->axisMinVals[axisNum] != common->axisMinVals[axisNum])
- ini->Set(section, baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]);
- if (settings->axisOffVals[axisNum] != common->axisOffVals[axisNum])
- ini->Set(section, baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]);
- if (settings->axisMaxVals[axisNum] != common->axisMaxVals[axisNum])
- ini->Set(section, baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]);
- if (settings->deadZones[axisNum] != common->deadZones[axisNum])
- ini->Set(section, baseKey + axisId + "DeadZone", settings->deadZones[axisNum]);
- if (settings->saturations[axisNum] != common->saturations[axisNum])
- ini->Set(section, baseKey + axisId + "Saturation", settings->saturations[axisNum]);
- }
+ // Write to ini file any settings that are different to common/default settings
+ string baseKey("InputJoy");
+ if (settings->joyNum != ANY_JOYSTICK)
+ baseKey.append(IntToString(settings->joyNum + 1));
+ for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
+ {
+ const char *axisId = s_axisIds[axisNum];
+ if (settings->axisMinVals[axisNum] != common->axisMinVals[axisNum])
+ ini->Set(section, baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]);
+ if (settings->axisOffVals[axisNum] != common->axisOffVals[axisNum])
+ ini->Set(section, baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]);
+ if (settings->axisMaxVals[axisNum] != common->axisMaxVals[axisNum])
+ ini->Set(section, baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]);
+ if (settings->deadZones[axisNum] != common->deadZones[axisNum])
+ ini->Set(section, baseKey + axisId + "DeadZone", settings->deadZones[axisNum]);
+ if (settings->saturations[axisNum] != common->saturations[axisNum])
+ ini->Set(section, baseKey + axisId + "Saturation", settings->saturations[axisNum]);
+ }
}
KeySettings *CInputSystem::GetKeySettings(int kbdNum, bool useDefault)
{
- KeySettings *common = NULL;
- for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
- {
- if ((*it)->kbdNum == kbdNum)
- return *it;
- else if ((*it)->kbdNum == ANY_KEYBOARD)
- common = *it;
- }
- if (!useDefault)
- return NULL;
- return (common != NULL ? common : &m_defKeySettings);
+ KeySettings *common = NULL;
+ for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
+ {
+ if ((*it)->kbdNum == kbdNum)
+ return *it;
+ else if ((*it)->kbdNum == ANY_KEYBOARD)
+ common = *it;
+ }
+ if (!useDefault)
+ return NULL;
+ return (common != NULL ? common : &m_defKeySettings);
}
MouseSettings *CInputSystem::GetMouseSettings(int mseNum, bool useDefault)
{
- MouseSettings *common = NULL;
- for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
- {
- if ((*it)->mseNum == mseNum)
- return *it;
- else if ((*it)->mseNum == ANY_MOUSE)
- common = *it;
- }
- if (!useDefault)
- return NULL;
- return (common != NULL ? common : &m_defMseSettings);
+ MouseSettings *common = NULL;
+ for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
+ {
+ if ((*it)->mseNum == mseNum)
+ return *it;
+ else if ((*it)->mseNum == ANY_MOUSE)
+ common = *it;
+ }
+ if (!useDefault)
+ return NULL;
+ return (common != NULL ? common : &m_defMseSettings);
}
JoySettings *CInputSystem::GetJoySettings(int joyNum, bool useDefault)
{
- JoySettings *common = NULL;
- for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
- {
- if ((*it)->joyNum == joyNum)
- return *it;
- else if ((*it)->joyNum == ANY_JOYSTICK)
- common = *it;
- }
- if (!useDefault)
- return NULL;
- return (common != NULL ? common : &m_defJoySettings);
+ JoySettings *common = NULL;
+ for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
+ {
+ if ((*it)->joyNum == joyNum)
+ return *it;
+ else if ((*it)->joyNum == ANY_JOYSTICK)
+ common = *it;
+ }
+ if (!useDefault)
+ return NULL;
+ return (common != NULL ? common : &m_defJoySettings);
}
bool CInputSystem::IsAxis(EMousePart msePart)
{
- return msePart >= MouseXAxis && msePart <= MouseZAxisNeg;
+ return msePart >= MouseXAxis && msePart <= MouseZAxisNeg;
}
bool CInputSystem::IsFullAxis(EMousePart msePart)
{
- return IsAxis(msePart) && (((msePart - MouseXAxis) % 4) == AXIS_FULL || ((msePart - MouseXAxis) % 4) == AXIS_INVERTED);
+ return IsAxis(msePart) && (((msePart - MouseXAxis) % 4) == AXIS_FULL || ((msePart - MouseXAxis) % 4) == AXIS_INVERTED);
}
bool CInputSystem::GetAxisDetails(EMousePart msePart, int &axisNum, int &axisDir)
{
- if (!IsAxis(msePart))
- return false;
- axisNum = (msePart - MouseXAxis) / 4;
- axisDir = (msePart - MouseXAxis) % 4;
- return true;
+ if (!IsAxis(msePart))
+ return false;
+ axisNum = (msePart - MouseXAxis) / 4;
+ axisDir = (msePart - MouseXAxis) % 4;
+ return true;
}
bool CInputSystem::IsButton(EMousePart msePart)
{
- return msePart >= MouseButtonLeft && msePart <= MouseButtonX2;
+ return msePart >= MouseButtonLeft && msePart <= MouseButtonX2;
}
int CInputSystem::GetButtonNumber(EMousePart msePart)
{
- if (!IsButton(msePart))
- return -1;
- return msePart - MouseButtonLeft;
+ if (!IsButton(msePart))
+ return -1;
+ return msePart - MouseButtonLeft;
}
EMousePart CInputSystem::GetMouseAxis(int axisNum, int axisDir)
{
- if (axisNum > 0 || axisNum >= NUM_MOUSE_AXES || axisDir < 0 || axisDir > 3)
- return MouseUnknown;
- return (EMousePart)(MouseXAxis + 4 * axisNum + axisDir);
+ if (axisNum > 0 || axisNum >= NUM_MOUSE_AXES || axisDir < 0 || axisDir > 3)
+ return MouseUnknown;
+ return (EMousePart)(MouseXAxis + 4 * axisNum + axisDir);
}
EMousePart CInputSystem::GetMouseButton(int butNum)
{
- if (butNum < 0 || butNum >= NUM_MOUSE_BUTTONS)
- return MouseUnknown;
- return (EMousePart)(MouseButtonLeft + butNum);
+ if (butNum < 0 || butNum >= NUM_MOUSE_BUTTONS)
+ return MouseUnknown;
+ return (EMousePart)(MouseButtonLeft + butNum);
}
bool CInputSystem::IsAxis(EJoyPart joyPart)
{
- return joyPart >= JoyXAxis && joyPart <= JoyS2AxisNeg;
+ return joyPart >= JoyXAxis && joyPart <= JoyS2AxisNeg;
}
bool CInputSystem::IsFullAxis(EJoyPart joyPart)
{
- return IsAxis(joyPart) && (((joyPart - JoyXAxis) % 4) == AXIS_FULL || ((joyPart - JoyXAxis) % 4) == AXIS_INVERTED);
+ return IsAxis(joyPart) && (((joyPart - JoyXAxis) % 4) == AXIS_FULL || ((joyPart - JoyXAxis) % 4) == AXIS_INVERTED);
}
bool CInputSystem::IsSliderAxis(EJoyPart joyPart)
{
- return joyPart >= JoyS1Axis && joyPart <= JoyS2AxisNeg;
+ return joyPart >= JoyS1Axis && joyPart <= JoyS2AxisNeg;
}
bool CInputSystem::GetAxisDetails(EJoyPart joyPart, int &axisNum, int &axisDir)
{
- if (!IsAxis(joyPart))
- return false;
- axisNum = (joyPart - JoyXAxis) / 4;
- axisDir = (joyPart - JoyXAxis) % 4;
- return true;
+ if (!IsAxis(joyPart))
+ return false;
+ axisNum = (joyPart - JoyXAxis) / 4;
+ axisDir = (joyPart - JoyXAxis) % 4;
+ return true;
}
bool CInputSystem::IsPOV(EJoyPart joyPart)
{
- return joyPart >= JoyPOV0Up && joyPart <= JoyPOV3Right;
+ return joyPart >= JoyPOV0Up && joyPart <= JoyPOV3Right;
}
bool CInputSystem::GetPOVDetails(EJoyPart joyPart, int &povNum, int &povDir)
{
- if (!IsPOV(joyPart))
- return false;
- povNum = (joyPart - JoyPOV0Up) / 4;
- povDir = (joyPart - JoyPOV0Up) % 4;
- return true;
+ if (!IsPOV(joyPart))
+ return false;
+ povNum = (joyPart - JoyPOV0Up) / 4;
+ povDir = (joyPart - JoyPOV0Up) % 4;
+ return true;
}
bool CInputSystem::IsButton(EJoyPart joyPart)
{
- return joyPart >= JoyButton0 && joyPart <= JoyButton31;
+ return joyPart >= JoyButton0 && joyPart <= JoyButton31;
}
int CInputSystem::GetButtonNumber(EJoyPart joyPart)
{
- if (!IsButton(joyPart))
- return -1;
- return joyPart - JoyButton0;
+ if (!IsButton(joyPart))
+ return -1;
+ return joyPart - JoyButton0;
}
EJoyPart CInputSystem::GetJoyAxis(int axisNum, int axisDir)
{
- if (axisNum < 0 || axisNum >= NUM_JOY_AXES || axisDir < 0 || axisDir > 3)
- return JoyUnknown;
- return (EJoyPart)(JoyXAxis + 4 * axisNum + axisDir);
+ if (axisNum < 0 || axisNum >= NUM_JOY_AXES || axisDir < 0 || axisDir > 3)
+ return JoyUnknown;
+ return (EJoyPart)(JoyXAxis + 4 * axisNum + axisDir);
}
EJoyPart CInputSystem::GetJoyPOV(int povNum, int povDir)
{
- if (povNum < 0 || povNum >= NUM_JOY_POVS)
- return JoyUnknown;
- return (EJoyPart)(JoyPOV0Up + 4 * povNum + povDir);
+ if (povNum < 0 || povNum >= NUM_JOY_POVS)
+ return JoyUnknown;
+ return (EJoyPart)(JoyPOV0Up + 4 * povNum + povDir);
}
EJoyPart CInputSystem::GetJoyButton(int butNum)
{
- if (butNum < 0 || butNum >= NUM_JOY_BUTTONS)
- return JoyUnknown;
- return (EJoyPart)(JoyButton0 + butNum);
+ if (butNum < 0 || butNum >= NUM_JOY_BUTTONS)
+ return JoyUnknown;
+ return (EJoyPart)(JoyButton0 + butNum);
}
bool CInputSystem::ConfigMouseCentered()
{
- // Get mouse X & Y
- int mx = GetMouseAxisValue(ANY_MOUSE, AXIS_X);
- int my = GetMouseAxisValue(ANY_MOUSE, AXIS_Y);
-
- // See if mouse in center of display
- unsigned lx = m_dispX + m_dispW / 4;
- unsigned ly = m_dispY + m_dispH / 4;
- return mx >= (int)lx && mx <= (int)(lx + m_dispW / 2) && my >= (int)ly && my <= (int)(ly + m_dispH / 2);
-}
+ // Get mouse X & Y
+ int mx = GetMouseAxisValue(ANY_MOUSE, AXIS_X);
+ int my = GetMouseAxisValue(ANY_MOUSE, AXIS_Y);
+
+ // See if mouse in center of display
+ unsigned lx = m_dispX + m_dispW / 4;
+ unsigned ly = m_dispY + m_dispH / 4;
+ return mx >= (int)lx && mx <= (int)(lx + m_dispW / 2) && my >= (int)ly && my <= (int)(ly + m_dispH / 2);
+}
CInputSource *CInputSystem::CreateAnyKeySource(int keyIndex)
{
- // Default ANY_KEYBOARD source is to use CMultiInputSource to combine all individual sources
- vector keySrcs;
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- {
- CInputSource *keySrc = CreateKeySource(kbdNum, keyIndex);
- if (keySrc != NULL)
- keySrcs.push_back(keySrc);
- }
- return new CMultiInputSource(true, keySrcs);
+ // Default ANY_KEYBOARD source is to use CMultiInputSource to combine all individual sources
+ vector keySrcs;
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ CInputSource *keySrc = CreateKeySource(kbdNum, keyIndex);
+ if (keySrc != NULL)
+ keySrcs.push_back(keySrc);
+ }
+ return new CMultiInputSource(true, keySrcs);
}
CInputSource *CInputSystem::CreateAnyMouseSource(EMousePart msePart)
{
- // Default ANY_MOUSE source is to use CMultiInputSource to combine all individual sources
- vector mseSrcs;
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- {
- CInputSource *mseSrc = CreateMouseSource(mseNum, msePart);
- if (mseSrc != NULL)
- mseSrcs.push_back(mseSrc);
- }
- return new CMultiInputSource(true, mseSrcs);
+ // Default ANY_MOUSE source is to use CMultiInputSource to combine all individual sources
+ vector mseSrcs;
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ CInputSource *mseSrc = CreateMouseSource(mseNum, msePart);
+ if (mseSrc != NULL)
+ mseSrcs.push_back(mseSrc);
+ }
+ return new CMultiInputSource(true, mseSrcs);
}
CInputSource *CInputSystem::CreateAnyJoySource(EJoyPart joyPart)
{
- // Default ANY_JOYSTICK source is to use CMultiInputSource to combine all individual sources
- vector joySrcs;
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- {
- CInputSource *joySrc = CreateJoySource(joyNum, joyPart);
- if (joySrc != NULL)
- joySrcs.push_back(joySrc);
- }
- return new CMultiInputSource(true, joySrcs);
+ // Default ANY_JOYSTICK source is to use CMultiInputSource to combine all individual sources
+ vector joySrcs;
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ CInputSource *joySrc = CreateJoySource(joyNum, joyPart);
+ if (joySrc != NULL)
+ joySrcs.push_back(joySrc);
+ }
+ return new CMultiInputSource(true, joySrcs);
}
CInputSource *CInputSystem::CreateKeySource(int kbdNum, int keyIndex)
{
- // Get key settings
- KeySettings *settings = GetKeySettings(kbdNum, true);
+ // Get key settings
+ KeySettings *settings = GetKeySettings(kbdNum, true);
- // Create source for given key index
- return new CKeyInputSource(this, kbdNum, keyIndex, settings->sensitivity, settings->decaySpeed);
+ // Create source for given key index
+ return new CKeyInputSource(this, kbdNum, keyIndex, settings->sensitivity, settings->decaySpeed);
}
CInputSource *CInputSystem::CreateMouseSource(int mseNum, EMousePart msePart)
{
- // Get mouse settings
- MouseSettings *settings = GetMouseSettings(mseNum, true);
+ // Get mouse settings
+ MouseSettings *settings = GetMouseSettings(mseNum, true);
- // Create source according to given mouse part
- int axisNum;
- int axisDir;
- if (GetAxisDetails(msePart, axisNum, axisDir))
- {
- // Part is mouse axis so create axis source with appropriate deadzone setting
- return new CMseAxisInputSource(this, mseNum, axisNum, axisDir, settings->deadZones[axisNum]);
- }
- else if (IsButton(msePart))
- {
- // Part is mouse button so map it to button number
- int butNum = GetButtonNumber(msePart);
- if (butNum < 0)
- return NULL; // Buttons out of range are invalid
- return new CMseButInputSource(this, mseNum, butNum);
- }
+ // Create source according to given mouse part
+ int axisNum;
+ int axisDir;
+ if (GetAxisDetails(msePart, axisNum, axisDir))
+ {
+ // Part is mouse axis so create axis source with appropriate deadzone setting
+ return new CMseAxisInputSource(this, mseNum, axisNum, axisDir, settings->deadZones[axisNum]);
+ }
+ else if (IsButton(msePart))
+ {
+ // Part is mouse button so map it to button number
+ int butNum = GetButtonNumber(msePart);
+ if (butNum < 0)
+ return NULL; // Buttons out of range are invalid
+ return new CMseButInputSource(this, mseNum, butNum);
+ }
- // If got here, then mouse part is invalid
- return NULL;
+ // If got here, then mouse part is invalid
+ return NULL;
}
CInputSource *CInputSystem::CreateJoySource(int joyNum, EJoyPart joyPart)
{
- // Get joystick details and settings
- const JoyDetails *joyDetails = GetJoyDetails(joyNum);
- JoySettings *settings = GetJoySettings(joyNum, true);
-
- // Create source according to given joystick part
- int axisNum;
- int axisDir;
- int povNum;
- int povDir;
- if (GetAxisDetails(joyPart, axisNum, axisDir))
- {
- // Part is joystick axis, so see whether joystick actually has this axis
- if (!joyDetails->hasAxis[axisNum])
- return m_emptySource; // If joystick doesn't have axis, then return empty source rather than NULL as not really an error
- // Otherwise, create axis source with appropriate axis range, deadzone and saturation settings
- return new CJoyAxisInputSource(this, joyNum, axisNum, axisDir,
- settings->axisMinVals[axisNum], settings->axisOffVals[axisNum], settings->axisMaxVals[axisNum],
- settings->deadZones[axisNum], settings->saturations[axisNum]);
- }
- else if (GetPOVDetails(joyPart, povNum, povDir))
- {
- // Part is joystick POV hat controller so see whether joystick has this POV
- if (povNum >= joyDetails->numPOVs)
- return m_emptySource; // If joystick doesn't have POV, then return empty source rather than NULL as not really an error
- return new CJoyPOVInputSource(this, joyNum, povNum, povDir);
- }
- else if (IsButton(joyPart))
- {
- // Part is joystick button so map it to a button number
- int butNum = GetButtonNumber(joyPart);
- if (butNum < 0 || butNum >= NUM_JOY_BUTTONS)
- return NULL; // Buttons out of range are invalid
- if (butNum >= joyDetails->numButtons)
- return m_emptySource; // If joystick doesn't have button, then return empty source rather than NULL as not really an error
- return new CJoyButInputSource(this, joyNum, butNum);
- }
-
- // If got here, then joystick part is invalid
- return NULL;
+ // Get joystick details and settings
+ const JoyDetails *joyDetails = GetJoyDetails(joyNum);
+ JoySettings *settings = GetJoySettings(joyNum, true);
+
+ // Create source according to given joystick part
+ int axisNum;
+ int axisDir;
+ int povNum;
+ int povDir;
+ if (GetAxisDetails(joyPart, axisNum, axisDir))
+ {
+ // Part is joystick axis, so see whether joystick actually has this axis
+ if (!joyDetails->hasAxis[axisNum])
+ return m_emptySource; // If joystick doesn't have axis, then return empty source rather than NULL as not really an error
+ // Otherwise, create axis source with appropriate axis range, deadzone and saturation settings
+ return new CJoyAxisInputSource(this, joyNum, axisNum, axisDir,
+ settings->axisMinVals[axisNum], settings->axisOffVals[axisNum], settings->axisMaxVals[axisNum],
+ settings->deadZones[axisNum], settings->saturations[axisNum]);
+ }
+ else if (GetPOVDetails(joyPart, povNum, povDir))
+ {
+ // Part is joystick POV hat controller so see whether joystick has this POV
+ if (povNum >= joyDetails->numPOVs)
+ return m_emptySource; // If joystick doesn't have POV, then return empty source rather than NULL as not really an error
+ return new CJoyPOVInputSource(this, joyNum, povNum, povDir);
+ }
+ else if (IsButton(joyPart))
+ {
+ // Part is joystick button so map it to a button number
+ int butNum = GetButtonNumber(joyPart);
+ if (butNum < 0 || butNum >= NUM_JOY_BUTTONS)
+ return NULL; // Buttons out of range are invalid
+ if (butNum >= joyDetails->numButtons)
+ return m_emptySource; // If joystick doesn't have button, then return empty source rather than NULL as not really an error
+ return new CJoyButInputSource(this, joyNum, butNum);
+ }
+
+ // If got here, then joystick part is invalid
+ return NULL;
}
bool CInputSystem::Initialize()
{
- // Initialize subclass
- if (!InitializeSystem())
- return false;
+ // Initialize subclass
+ if (!InitializeSystem())
+ return false;
- // Get number of keyboard, mice and joysticks (they are stored here as need to access the values in the destructor)
- m_numKbds = GetNumKeyboards();
- m_numMice = GetNumMice();
- m_numJoys = GetNumJoysticks();
+ // Get number of keyboard, mice and joysticks (they are stored here as need to access the values in the destructor)
+ m_numKbds = GetNumKeyboards();
+ m_numMice = GetNumMice();
+ m_numJoys = GetNumJoysticks();
- // Create cache to hold input sources
- CreateSourceCache();
+ // Create cache to hold input sources
+ CreateSourceCache();
- GrabMouse();
- return true;
+ GrabMouse();
+ return true;
}
void CInputSystem::SetDisplayGeom(unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH)
{
- // Remember display geometry
- m_dispX = dispX;
- m_dispY = dispY;
- m_dispW = dispW;
- m_dispH = dispH;
+ // Remember display geometry
+ m_dispX = dispX;
+ m_dispY = dispY;
+ m_dispW = dispW;
+ m_dispH = dispH;
}
CInputSource* CInputSystem::ParseSource(const char *mapping, bool fullAxisOnly)
{
- return ParseMultiSource(mapping, fullAxisOnly, true);
+ return ParseMultiSource(mapping, fullAxisOnly, true);
}
void CInputSystem::ClearSettings()
{
- // Delete all key settings
- for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
- delete *it;
- m_keySettings.clear();
+ // Delete all key settings
+ for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
+ delete *it;
+ m_keySettings.clear();
- // Delete all mouse settings
- for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
- delete *it;
- m_mseSettings.clear();
+ // Delete all mouse settings
+ for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
+ delete *it;
+ m_mseSettings.clear();
- // Delete all joystick settings
- for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
- delete *it;
- m_joySettings.clear();
+ // Delete all joystick settings
+ for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
+ delete *it;
+ m_joySettings.clear();
}
void CInputSystem::PrintSettings()
{
- puts("Input System Settings");
- puts("---------------------");
- puts("");
+ puts("Input System Settings");
+ puts("---------------------");
+ puts("");
- printf("Input System: %s\n", name);
+ printf("Input System: %s\n", name);
- puts("");
+ puts("");
- PrintDevices();
+ PrintDevices();
- puts("");
+ puts("");
- // Print all key settings for attached keyboards
- KeySettings *keySettings;
- if (m_numKbds == ANY_KEYBOARD)
- {
- puts("Common Keyboard Settings:");
- keySettings = GetKeySettings(ANY_KEYBOARD, true);
- PrintKeySettings(ANY_KEYBOARD, keySettings);
- }
- else
- {
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- {
- printf("Keyboard %d Settings:\n", kbdNum + 1);
- keySettings = GetKeySettings(kbdNum, true);
- PrintKeySettings(kbdNum, keySettings);
- }
- }
+ // Print all key settings for attached keyboards
+ KeySettings *keySettings;
+ if (m_numKbds == ANY_KEYBOARD)
+ {
+ puts("Common Keyboard Settings:");
+ keySettings = GetKeySettings(ANY_KEYBOARD, true);
+ PrintKeySettings(ANY_KEYBOARD, keySettings);
+ }
+ else
+ {
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ printf("Keyboard %d Settings:\n", kbdNum + 1);
+ keySettings = GetKeySettings(kbdNum, true);
+ PrintKeySettings(kbdNum, keySettings);
+ }
+ }
- // Print all mouse settings for attached mice
- MouseSettings *mseSettings;
- if (m_numMice == ANY_MOUSE)
- {
- puts("Common Mouse Settings:");
- mseSettings = GetMouseSettings(ANY_MOUSE, true);
- PrintMouseSettings(ANY_MOUSE, mseSettings);
- }
- else
- {
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- {
- printf("Mouse %d Settings:\n", mseNum + 1);
- mseSettings = GetMouseSettings(mseNum, true);
- PrintMouseSettings(mseNum, mseSettings);
- }
- }
+ // Print all mouse settings for attached mice
+ MouseSettings *mseSettings;
+ if (m_numMice == ANY_MOUSE)
+ {
+ puts("Common Mouse Settings:");
+ mseSettings = GetMouseSettings(ANY_MOUSE, true);
+ PrintMouseSettings(ANY_MOUSE, mseSettings);
+ }
+ else
+ {
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ printf("Mouse %d Settings:\n", mseNum + 1);
+ mseSettings = GetMouseSettings(mseNum, true);
+ PrintMouseSettings(mseNum, mseSettings);
+ }
+ }
- // Print all joystick settings for attached joysticks
- JoySettings *joySettings;
- if (m_numJoys == ANY_JOYSTICK)
- {
- puts("Common Joystick Settings:");
- joySettings = GetJoySettings(ANY_JOYSTICK, true);
- PrintJoySettings(ANY_JOYSTICK, joySettings);
- }
- else
- {
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- {
- printf("Joystick %d Settings:\n", joyNum + 1);
- joySettings = GetJoySettings(joyNum, true);
- PrintJoySettings(joyNum, joySettings);
- }
- }
+ // Print all joystick settings for attached joysticks
+ JoySettings *joySettings;
+ if (m_numJoys == ANY_JOYSTICK)
+ {
+ puts("Common Joystick Settings:");
+ joySettings = GetJoySettings(ANY_JOYSTICK, true);
+ PrintJoySettings(ANY_JOYSTICK, joySettings);
+ }
+ else
+ {
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ printf("Joystick %d Settings:\n", joyNum + 1);
+ joySettings = GetJoySettings(joyNum, true);
+ PrintJoySettings(joyNum, joySettings);
+ }
+ }
- puts("");
+ puts("");
+}
+
+void CInputSystem::LoadFromConfig(const Util::Config::Node &config)
+{
+ ClearSettings();
+ ClearSourceCache();
+
+ // Read all key settings for attached keyboards
+ KeySettings *keySettings = LoadKeySettings(config, ANY_KEYBOARD);
+ if (keySettings != NULL)
+ m_keySettings.push_back(keySettings);
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ keySettings = LoadKeySettings(config, kbdNum);
+ if (keySettings != NULL)
+ m_keySettings.push_back(keySettings);
+ }
+
+ // Read all mouse settings for attached mice
+ MouseSettings *mseSettings = LoadMouseSettings(config, ANY_MOUSE);
+ if (mseSettings != NULL)
+ m_mseSettings.push_back(mseSettings);
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ mseSettings = LoadMouseSettings(config, mseNum);
+ if (mseSettings != NULL)
+ m_mseSettings.push_back(mseSettings);
+ }
+
+ // Read all joystick settings for attached joysticks
+ JoySettings *joySettings = LoadJoySettings(config, ANY_JOYSTICK);
+ if (joySettings != NULL)
+ m_joySettings.push_back(joySettings);
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ joySettings = LoadJoySettings(config, joyNum);
+ if (joySettings != NULL)
+ m_joySettings.push_back(joySettings);
+ }
+}
+
+void CInputSystem::StoreToConfig(Util::Config::Node *config)
+{
+ // Write all key settings
+ for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
+ StoreKeySettings(config, *it);
+
+ // Write all mouse settings
+ for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
+ StoreMouseSettings(config, *it);
+
+ // Write all joystick settings
+ for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
+ StoreJoySettings(config, *it);
}
void CInputSystem::ReadFromINIFile(CINIFile *ini, const char *section)
{
- ClearSettings();
- ClearSourceCache();
+ ClearSettings();
+ ClearSourceCache();
- // Read all key settings for attached keyboards
- KeySettings *keySettings = ReadKeySettings(ini, section, ANY_KEYBOARD);
- if (keySettings != NULL)
- m_keySettings.push_back(keySettings);
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- {
- keySettings = ReadKeySettings(ini, section, kbdNum);
- if (keySettings != NULL)
- m_keySettings.push_back(keySettings);
- }
+ // Read all key settings for attached keyboards
+ KeySettings *keySettings = ReadKeySettings(ini, section, ANY_KEYBOARD);
+ if (keySettings != NULL)
+ m_keySettings.push_back(keySettings);
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ keySettings = ReadKeySettings(ini, section, kbdNum);
+ if (keySettings != NULL)
+ m_keySettings.push_back(keySettings);
+ }
- // Read all mouse settings for attached mice
- MouseSettings *mseSettings = ReadMouseSettings(ini, section, ANY_MOUSE);
- if (mseSettings != NULL)
- m_mseSettings.push_back(mseSettings);
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- {
- mseSettings = ReadMouseSettings(ini, section, mseNum);
- if (mseSettings != NULL)
- m_mseSettings.push_back(mseSettings);
- }
+ // Read all mouse settings for attached mice
+ MouseSettings *mseSettings = ReadMouseSettings(ini, section, ANY_MOUSE);
+ if (mseSettings != NULL)
+ m_mseSettings.push_back(mseSettings);
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ mseSettings = ReadMouseSettings(ini, section, mseNum);
+ if (mseSettings != NULL)
+ m_mseSettings.push_back(mseSettings);
+ }
- // Read all joystick settings for attached joysticks
- JoySettings *joySettings = ReadJoySettings(ini, section, ANY_JOYSTICK);
- if (joySettings != NULL)
- m_joySettings.push_back(joySettings);
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- {
- joySettings = ReadJoySettings(ini, section, joyNum);
- if (joySettings != NULL)
- m_joySettings.push_back(joySettings);
- }
+ // Read all joystick settings for attached joysticks
+ JoySettings *joySettings = ReadJoySettings(ini, section, ANY_JOYSTICK);
+ if (joySettings != NULL)
+ m_joySettings.push_back(joySettings);
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ joySettings = ReadJoySettings(ini, section, joyNum);
+ if (joySettings != NULL)
+ m_joySettings.push_back(joySettings);
+ }
}
void CInputSystem::WriteToINIFile(CINIFile *ini, const char *section)
{
- // Write all key settings
- for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
- WriteKeySettings(ini, section, *it);
+ // Write all key settings
+ for (vector::iterator it = m_keySettings.begin(); it != m_keySettings.end(); it++)
+ WriteKeySettings(ini, section, *it);
- // Write all mouse settings
- for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
- WriteMouseSettings(ini, section, *it);
+ // Write all mouse settings
+ for (vector::iterator it = m_mseSettings.begin(); it != m_mseSettings.end(); it++)
+ WriteMouseSettings(ini, section, *it);
- // Write all joystick settings
- for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
- WriteJoySettings(ini, section, *it);
+ // Write all joystick settings
+ for (vector::iterator it = m_joySettings.begin(); it != m_joySettings.end(); it++)
+ WriteJoySettings(ini, section, *it);
}
bool CInputSystem::ReadMapping(char *buffer, unsigned bufSize, bool fullAxisOnly, unsigned readFlags, const char *escapeMapping)
{
- // Map given escape mapping to an input source
- bool cancelled = false;
- CInputSource *escape = ParseSource(escapeMapping);
- if (escape)
- escape->Acquire();
-
- string badMapping;
- string mapping;
- vector badSources;
- vector sources;
- bool mseCentered = false;
-
- // See which sources activated to begin with and from here on ignore these (this stops badly calibrated axes that are constantly "active"
- // from preventing the user from exiting read loop)
- if (!Poll())
- goto Cancelled;
+ // Map given escape mapping to an input source
+ bool cancelled = false;
+ CInputSource *escape = ParseSource(escapeMapping);
+ if (escape)
+ escape->Acquire();
+
+ string badMapping;
+ string mapping;
+ vector badSources;
+ vector sources;
+ bool mseCentered = false;
+
+ // See which sources activated to begin with and from here on ignore these (this stops badly calibrated axes that are constantly "active"
+ // from preventing the user from exiting read loop)
+ if (!Poll())
+ goto Cancelled;
- CheckAllSources(readFlags, fullAxisOnly, mseCentered, badSources, badMapping, sources);
+ CheckAllSources(readFlags, fullAxisOnly, mseCentered, badSources, badMapping, sources);
- // Loop until have received meaningful inputs
- for (;;)
- {
- // Poll inputs
- if (!Poll())
- goto Cancelled;
+ // Loop until have received meaningful inputs
+ for (;;)
+ {
+ // Poll inputs
+ if (!Poll())
+ goto Cancelled;
- // Check if escape source was triggered
- if (escape && escape->IsActive())
- {
- // If so, wait until source no longer active and then exit
- while (escape->IsActive())
- {
- if (!Poll())
- goto Cancelled;
- CThread::Sleep(1000/60);
- }
- goto Cancelled;
- }
+ // Check if escape source was triggered
+ if (escape && escape->IsActive())
+ {
+ // If so, wait until source no longer active and then exit
+ while (escape->IsActive())
+ {
+ if (!Poll())
+ goto Cancelled;
+ CThread::Sleep(1000/60);
+ }
+ goto Cancelled;
+ }
- // Check all active sources
- CheckAllSources(readFlags, fullAxisOnly, mseCentered, sources, mapping, badSources);
+ // Check all active sources
+ CheckAllSources(readFlags, fullAxisOnly, mseCentered, sources, mapping, badSources);
- // When some inputs have been activated, keep looping until they have all been released again.
- if (sources.size() > 0)
- {
- // Check each source is no longer active
- bool active = false;
- for (vector::iterator it = sources.begin(); it != sources.end(); it++)
- {
- if ((*it)->IsActive())
- {
- active = true;
- break;
- }
- }
- if (!active)
- {
- // If so, get combined type of sources and if is valid then return
- ESourceType type = CMultiInputSource::GetCombinedType(sources);
- if ((type != SourceInvalid) && ((type == SourceFullAxis && fullAxisOnly) || (type != SourceFullAxis && !fullAxisOnly)))
- break;
+ // When some inputs have been activated, keep looping until they have all been released again.
+ if (sources.size() > 0)
+ {
+ // Check each source is no longer active
+ bool active = false;
+ for (vector::iterator it = sources.begin(); it != sources.end(); it++)
+ {
+ if ((*it)->IsActive())
+ {
+ active = true;
+ break;
+ }
+ }
+ if (!active)
+ {
+ // If so, get combined type of sources and if is valid then return
+ ESourceType type = CMultiInputSource::GetCombinedType(sources);
+ if ((type != SourceInvalid) && ((type == SourceFullAxis && fullAxisOnly) || (type != SourceFullAxis && !fullAxisOnly)))
+ break;
- mapping.clear();
- sources.clear();
- mseCentered = false;
- }
- }
+ mapping.clear();
+ sources.clear();
+ mseCentered = false;
+ }
+ }
- // Don't poll continuously
- CThread::Sleep(1000/60);
- }
+ // Don't poll continuously
+ CThread::Sleep(1000/60);
+ }
- // Copy mapping to buffer and return
- strncpy(buffer, mapping.c_str(), bufSize - 1);
- buffer[bufSize - 1] = '\0';
- goto Finish;
+ // Copy mapping to buffer and return
+ strncpy(buffer, mapping.c_str(), bufSize - 1);
+ buffer[bufSize - 1] = '\0';
+ goto Finish;
Cancelled:
- cancelled = true;
+ cancelled = true;
Finish:
- if (escape)
- escape->Release();
- return !cancelled;
+ if (escape)
+ escape->Release();
+ return !cancelled;
}
void CInputSystem::GrabMouse()
{
- m_grabMouse = true;
+ m_grabMouse = true;
}
void CInputSystem::UngrabMouse()
{
- m_grabMouse = false;
+ m_grabMouse = false;
- // Make sure mouse is visible
- SetMouseVisibility(true);
+ // Make sure mouse is visible
+ SetMouseVisibility(true);
}
bool CInputSystem::SendForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd)
{
- const JoyDetails *joyDetails = GetJoyDetails(joyNum);
- if (!joyDetails->hasFFeedback || !joyDetails->axisHasFF[axisNum])
- return false;
- return ProcessForceFeedbackCmd(joyNum, axisNum, ffCmd);
+ const JoyDetails *joyDetails = GetJoyDetails(joyNum);
+ if (!joyDetails->hasFFeedback || !joyDetails->axisHasFF[axisNum])
+ return false;
+ return ProcessForceFeedbackCmd(joyNum, axisNum, ffCmd);
}
bool CInputSystem::DetectJoystickAxis(unsigned joyNum, unsigned &axisNum, const char *escapeMapping, const char *confirmMapping)
{
- const JoyDetails *joyDetails = GetJoyDetails(joyNum);
- if (joyDetails == NULL)
- {
- puts("No such joystick!");
- return false;
- }
+ const JoyDetails *joyDetails = GetJoyDetails(joyNum);
+ if (joyDetails == NULL)
+ {
+ puts("No such joystick!");
+ return false;
+ }
- // Map given escape & confirm mappings to input sources
- bool cancelled = false;
- CInputSource *escape = ParseSource(escapeMapping);
- CInputSource *confirm = ParseSource(confirmMapping);
- CInputSource *output = ParseSource("KEY_SHIFT");
- if (escape)
- escape->Acquire();
- if (confirm)
- confirm->Acquire();
- if (output)
- output->Acquire();
+ // Map given escape & confirm mappings to input sources
+ bool cancelled = false;
+ CInputSource *escape = ParseSource(escapeMapping);
+ CInputSource *confirm = ParseSource(confirmMapping);
+ CInputSource *output = ParseSource("KEY_SHIFT");
+ if (escape)
+ escape->Acquire();
+ if (confirm)
+ confirm->Acquire();
+ if (output)
+ output->Acquire();
- printf("Move axis around and then press Return (or press Esc to cancel): ");
- fflush(stdout); // required on terminals that use buffering
+ printf("Move axis around and then press Return (or press Esc to cancel): ");
+ fflush(stdout); // required on terminals that use buffering
- unsigned maxRange;
- //unsigned maxAxisNum;
+ unsigned maxRange;
+ //unsigned maxAxisNum;
- bool firstOut = true;
- int minVals[NUM_JOY_AXES];
- int maxVals[NUM_JOY_AXES];
- for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
- {
- if (!joyDetails->hasAxis[loopAxisNum])
- continue;
- int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
- minVals[loopAxisNum] = joyVal;
- maxVals[loopAxisNum] = joyVal;
- }
- for (;;)
- {
- if (!Poll())
- goto Cancelled;
-
- // Check if escape source was triggered
- if (escape && escape->IsActive())
- {
- // If so, wait until source no longer active and then exit
- while (escape->IsActive())
- {
- if (!Poll())
- goto Cancelled;
- CThread::Sleep(1000/60);
- }
- goto Cancelled;
- }
+ bool firstOut = true;
+ int minVals[NUM_JOY_AXES];
+ int maxVals[NUM_JOY_AXES];
+ for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
+ {
+ if (!joyDetails->hasAxis[loopAxisNum])
+ continue;
+ int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
+ minVals[loopAxisNum] = joyVal;
+ maxVals[loopAxisNum] = joyVal;
+ }
+ for (;;)
+ {
+ if (!Poll())
+ goto Cancelled;
+
+ // Check if escape source was triggered
+ if (escape && escape->IsActive())
+ {
+ // If so, wait until source no longer active and then exit
+ while (escape->IsActive())
+ {
+ if (!Poll())
+ goto Cancelled;
+ CThread::Sleep(1000/60);
+ }
+ goto Cancelled;
+ }
- // Check if confirm source was triggered
- if (confirm && confirm->IsActive())
- {
- // If so, wait until source no longer active and then exit
- while (confirm->IsActive())
- {
- if (!Poll())
- goto Cancelled;
- CThread::Sleep(1000/60);
- }
- break;
- }
+ // Check if confirm source was triggered
+ if (confirm && confirm->IsActive())
+ {
+ // If so, wait until source no longer active and then exit
+ while (confirm->IsActive())
+ {
+ if (!Poll())
+ goto Cancelled;
+ CThread::Sleep(1000/60);
+ }
+ break;
+ }
- for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
- {
- if (!joyDetails->hasAxis[loopAxisNum])
- continue;
- int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
- minVals[loopAxisNum] = min(joyVal, minVals[loopAxisNum]);
- maxVals[loopAxisNum] = max(joyVal, maxVals[loopAxisNum]);
- }
+ for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
+ {
+ if (!joyDetails->hasAxis[loopAxisNum])
+ continue;
+ int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
+ minVals[loopAxisNum] = min(joyVal, minVals[loopAxisNum]);
+ maxVals[loopAxisNum] = max(joyVal, maxVals[loopAxisNum]);
+ }
- // Check if output source is triggered, and if so output value for debugging
- if (output && output->IsActive())
- {
- if (firstOut)
- puts("");
- printf(" [");
- for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
- {
- int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
- if (loopAxisNum > 0)
- printf(", ");
- printf("%s: %d", s_axisIds[loopAxisNum], joyVal);
- }
- puts("]");
- firstOut = false;
- }
+ // Check if output source is triggered, and if so output value for debugging
+ if (output && output->IsActive())
+ {
+ if (firstOut)
+ puts("");
+ printf(" [");
+ for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
+ {
+ int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
+ if (loopAxisNum > 0)
+ printf(", ");
+ printf("%s: %d", s_axisIds[loopAxisNum], joyVal);
+ }
+ puts("]");
+ firstOut = false;
+ }
- // Don't poll continuously
- CThread::Sleep(1000/60);
- }
+ // Don't poll continuously
+ CThread::Sleep(1000/60);
+ }
- maxRange = 0;
- //maxAxisNum = 0;
- for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
- {
- if (!joyDetails->hasAxis[loopAxisNum])
- continue;
- unsigned range = maxVals[loopAxisNum] - minVals[loopAxisNum];
- if (range > maxRange)
- {
- maxRange = range;
- axisNum = loopAxisNum;
- }
- }
+ maxRange = 0;
+ //maxAxisNum = 0;
+ for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
+ {
+ if (!joyDetails->hasAxis[loopAxisNum])
+ continue;
+ unsigned range = maxVals[loopAxisNum] - minVals[loopAxisNum];
+ if (range > maxRange)
+ {
+ maxRange = range;
+ axisNum = loopAxisNum;
+ }
+ }
- if (maxRange > 3000)
- printf("Detected %s\n", joyDetails->axisName[axisNum]);
- else
- {
- cancelled = true;
- puts("Not Detected");
- }
- goto Finish;
-
+ if (maxRange > 3000)
+ printf("Detected %s\n", joyDetails->axisName[axisNum]);
+ else
+ {
+ cancelled = true;
+ puts("Not Detected");
+ }
+ goto Finish;
+
Cancelled:
- puts("[Cancelled]");
- cancelled = true;
+ puts("[Cancelled]");
+ cancelled = true;
Finish:
- if (escape)
- escape->Release();
- if (confirm)
- confirm->Release();
- if (output)
- output->Release();
- return !cancelled;
+ if (escape)
+ escape->Release();
+ if (confirm)
+ confirm->Release();
+ if (output)
+ output->Release();
+ return !cancelled;
}
bool CInputSystem::CalibrateJoystickAxis(unsigned joyNum, unsigned axisNum, const char *escapeMapping, const char *confirmMapping)
{
- const JoyDetails *joyDetails = GetJoyDetails(joyNum);
- if (joyDetails == NULL || axisNum >= NUM_JOY_AXES || !joyDetails->hasAxis[axisNum])
- {
- puts("No such axis or joystick!");
- return false;
- }
+ const JoyDetails *joyDetails = GetJoyDetails(joyNum);
+ if (joyDetails == NULL || axisNum >= NUM_JOY_AXES || !joyDetails->hasAxis[axisNum])
+ {
+ puts("No such axis or joystick!");
+ return false;
+ }
- // Map given escape mapping to input source
- bool cancelled = false;
- CInputSource *escape = ParseSource(escapeMapping);
- CInputSource *output = ParseSource("KEY_SHIFT");
- if (escape)
- escape->Acquire();
- if (output)
- output->Acquire();
+ // Map given escape mapping to input source
+ bool cancelled = false;
+ CInputSource *escape = ParseSource(escapeMapping);
+ CInputSource *output = ParseSource("KEY_SHIFT");
+ if (escape)
+ escape->Acquire();
+ if (output)
+ output->Acquire();
Repeat:
- printf("Calibrating %s of joystick '%s'.\n\n", joyDetails->axisName[axisNum], joyDetails->name);
-
- unsigned totalRange;
- unsigned posDeadZone;
- unsigned negDeadZone;
- unsigned deadZone;
-
- int posVal = 0;
- int negVal = 0;
- int offVal = 0;
- unsigned posRange = 0;
- unsigned negRange = 0;
- unsigned posOffRange = 0;
- unsigned negOffRange = 0;
- char mapping[50];
- for (unsigned step = 0; step < 3; step++)
- {
- switch (step)
- {
- case 0:
- puts("Step 1:");
- puts(" Move axis now to its furthest positive/'on' position and hold, ie:");
- if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Z || axisNum == AXIS_RZ)
- puts(" - for a horizontal joystick axis, push it all the way to the right.");
- if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
- puts(" - for a vertical joystick axis, push it all the way downwards.");
- if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
- puts(" - for a joystick slider, push it all the way to its extreme.");
- puts(" - for a steering wheel, turn it all the way to the right.");
- puts(" - for a pedal, press it all the way to the floor.");
- break;
- case 1:
- puts("Step 2:");
- puts(" Move axis the other way to its furthest negative position and hold, ie:");
- if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Z || axisNum == AXIS_RZ)
- puts(" - for a horizontal joystick axis, push it all the way to the left.");
- if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
- puts(" - for a vertical joystick axis, push it all the way updwards.");
- if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
- puts(" - for a joystick slider, return it to its off position.");
- puts(" - for a steering wheel, turn it all the way to the left.");
- puts(" - for a pedal, let go of the pedal completely. If there is another pedal");
- puts(" that shares the same axis then press that one all the way to the floor.");
- break;
- case 2:
- puts("Step 3:");
- puts(" Return axis to its central/'off' position and hold, ie:");
- if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
- puts(" - for a joystick axis, let it return to the middle.");
- else if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
- puts(" - for a joystick slider, keep it at its off position.");
- puts(" - for a steering weel, turn it back to the center.");
- puts(" - for a pedal, let go of pedal completely. Likewise for any other pedal");
- puts(" that shares the same axis.");
- break;
- }
- printf("\nPress Return when done (or press Esc to cancel): ");
- fflush(stdout); // required on terminals that use buffering
+ printf("Calibrating %s of joystick '%s'.\n\n", joyDetails->axisName[axisNum], joyDetails->name);
+
+ unsigned totalRange;
+ unsigned posDeadZone;
+ unsigned negDeadZone;
+ unsigned deadZone;
+
+ int posVal = 0;
+ int negVal = 0;
+ int offVal = 0;
+ unsigned posRange = 0;
+ unsigned negRange = 0;
+ unsigned posOffRange = 0;
+ unsigned negOffRange = 0;
+ char mapping[50];
+ for (unsigned step = 0; step < 3; step++)
+ {
+ switch (step)
+ {
+ case 0:
+ puts("Step 1:");
+ puts(" Move axis now to its furthest positive/'on' position and hold, ie:");
+ if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Z || axisNum == AXIS_RZ)
+ puts(" - for a horizontal joystick axis, push it all the way to the right.");
+ if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
+ puts(" - for a vertical joystick axis, push it all the way downwards.");
+ if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
+ puts(" - for a joystick slider, push it all the way to its extreme.");
+ puts(" - for a steering wheel, turn it all the way to the right.");
+ puts(" - for a pedal, press it all the way to the floor.");
+ break;
+ case 1:
+ puts("Step 2:");
+ puts(" Move axis the other way to its furthest negative position and hold, ie:");
+ if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Z || axisNum == AXIS_RZ)
+ puts(" - for a horizontal joystick axis, push it all the way to the left.");
+ if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
+ puts(" - for a vertical joystick axis, push it all the way updwards.");
+ if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
+ puts(" - for a joystick slider, return it to its off position.");
+ puts(" - for a steering wheel, turn it all the way to the left.");
+ puts(" - for a pedal, let go of the pedal completely. If there is another pedal");
+ puts(" that shares the same axis then press that one all the way to the floor.");
+ break;
+ case 2:
+ puts("Step 3:");
+ puts(" Return axis to its central/'off' position and hold, ie:");
+ if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
+ puts(" - for a joystick axis, let it return to the middle.");
+ else if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
+ puts(" - for a joystick slider, keep it at its off position.");
+ puts(" - for a steering weel, turn it back to the center.");
+ puts(" - for a pedal, let go of pedal completely. Likewise for any other pedal");
+ puts(" that shares the same axis.");
+ break;
+ }
+ printf("\nPress Return when done (or press Esc to cancel): ");
+ fflush(stdout); // required on terminals that use buffering
- // Loop until user confirms or aborts
- for (;;)
- {
- if (!ReadMapping(mapping, 50, false, READ_KEYBOARD|READ_MERGE, escapeMapping))
- goto Cancelled;
- if (stricmp(mapping, confirmMapping) == 0)
- break;
- }
+ // Loop until user confirms or aborts
+ for (;;)
+ {
+ if (!ReadMapping(mapping, 50, false, READ_KEYBOARD|READ_MERGE, escapeMapping))
+ goto Cancelled;
+ if (stricmp(mapping, confirmMapping) == 0)
+ break;
+ }
- printf("Calibrating... ");
- fflush(stdout); // required on terminals that use buffering
+ printf("Calibrating... ");
+ fflush(stdout); // required on terminals that use buffering
- // Loop until at least three seconds have elapsed or user aborts
- int joyVal = GetJoyAxisValue(joyNum, axisNum);
- int minVal = joyVal;
- int maxVal = joyVal;
- bool firstOut = true;
- for (unsigned frames = 0; frames < 3 * 60; frames++)
- {
- if (!Poll())
- goto Cancelled;
+ // Loop until at least three seconds have elapsed or user aborts
+ int joyVal = GetJoyAxisValue(joyNum, axisNum);
+ int minVal = joyVal;
+ int maxVal = joyVal;
+ bool firstOut = true;
+ for (unsigned frames = 0; frames < 3 * 60; frames++)
+ {
+ if (!Poll())
+ goto Cancelled;
- // Check if escape source was triggered
- if (escape && escape->IsActive())
- {
- // If so, wait until source no longer active and then exit
- while (escape->IsActive())
- {
- if (!Poll())
- goto Cancelled;
- CThread::Sleep(1000/60);
- }
- goto Cancelled;
- }
+ // Check if escape source was triggered
+ if (escape && escape->IsActive())
+ {
+ // If so, wait until source no longer active and then exit
+ while (escape->IsActive())
+ {
+ if (!Poll())
+ goto Cancelled;
+ CThread::Sleep(1000/60);
+ }
+ goto Cancelled;
+ }
- joyVal = GetJoyAxisValue(joyNum, axisNum);
- minVal = min(minVal, joyVal);
- maxVal = max(maxVal, joyVal);
+ joyVal = GetJoyAxisValue(joyNum, axisNum);
+ minVal = min(minVal, joyVal);
+ maxVal = max(maxVal, joyVal);
- // Check if output source is triggered, and if so output value for debugging
- if (output && output->IsActive())
- {
- if (firstOut)
- puts("");
- printf(" [value: %d, min: %d, %max: %d]\n", joyVal, minVal, maxVal);
- firstOut = false;
- }
+ // Check if output source is triggered, and if so output value for debugging
+ if (output && output->IsActive())
+ {
+ if (firstOut)
+ puts("");
+ printf(" [value: %d, min: %d, %max: %d]\n", joyVal, minVal, maxVal);
+ firstOut = false;
+ }
- // Don't poll continuously
- CThread::Sleep(1000/60);
- }
+ // Don't poll continuously
+ CThread::Sleep(1000/60);
+ }
- printf("Done\n\n");
+ printf("Done\n\n");
- switch (step)
- {
- case 0: posVal = (abs(maxVal) >= abs(minVal) ? maxVal : minVal); break;
- case 1: negVal = (abs(minVal) >= abs(maxVal) ? minVal : maxVal); break;
- case 2:
- if (minVal <= 0 && maxVal >= 0)
- offVal = 0;
- else if (minVal == DEFAULT_JOY_AXISMINVAL)
- offVal = DEFAULT_JOY_AXISMINVAL;
- else if (maxVal == DEFAULT_JOY_AXISMAXVAL)
- offVal = DEFAULT_JOY_AXISMAXVAL;
- else
- offVal = (minVal + maxVal) / 2;
- posRange = abs(posVal - offVal);
- negRange = abs(negVal - offVal);
- posOffRange = (unsigned)(posVal > offVal ? maxVal - offVal : offVal - minVal);
- negOffRange = (unsigned)(posVal > offVal ? offVal - minVal : maxVal - offVal);
- break;
- }
- }
-
- totalRange = posRange + negRange;
- posDeadZone = (unsigned)ceil(100.0 * (double)posOffRange / (double)posRange);
- negDeadZone = (unsigned)ceil(100.0 * (double)negOffRange / (double)negRange);
- deadZone = max(1, max(negDeadZone, posDeadZone));
-
- bool okay;
- if (posVal > negVal)
- okay = negVal <= offVal && offVal <= posVal && totalRange > 3000 && deadZone < 90;
- else
- okay = posVal <= offVal && offVal <= negVal && totalRange > 3000 && deadZone < 90;
- if (okay)
- {
- JoySettings *commonSettings = GetJoySettings(ANY_JOYSTICK, true);
- JoySettings *joySettings = GetJoySettings(joyNum, false);
- if (joySettings == NULL)
- {
- joySettings = new JoySettings(*commonSettings);
- m_joySettings.push_back(joySettings);
- joySettings->joyNum = joyNum;
- }
+ switch (step)
+ {
+ case 0: posVal = (abs(maxVal) >= abs(minVal) ? maxVal : minVal); break;
+ case 1: negVal = (abs(minVal) >= abs(maxVal) ? minVal : maxVal); break;
+ case 2:
+ if (minVal <= 0 && maxVal >= 0)
+ offVal = 0;
+ else if (minVal == DEFAULT_JOY_AXISMINVAL)
+ offVal = DEFAULT_JOY_AXISMINVAL;
+ else if (maxVal == DEFAULT_JOY_AXISMAXVAL)
+ offVal = DEFAULT_JOY_AXISMAXVAL;
+ else
+ offVal = (minVal + maxVal) / 2;
+ posRange = abs(posVal - offVal);
+ negRange = abs(negVal - offVal);
+ posOffRange = (unsigned)(posVal > offVal ? maxVal - offVal : offVal - minVal);
+ negOffRange = (unsigned)(posVal > offVal ? offVal - minVal : maxVal - offVal);
+ break;
+ }
+ }
+
+ totalRange = posRange + negRange;
+ posDeadZone = (unsigned)ceil(100.0 * (double)posOffRange / (double)posRange);
+ negDeadZone = (unsigned)ceil(100.0 * (double)negOffRange / (double)negRange);
+ deadZone = max(1, max(negDeadZone, posDeadZone));
+
+ bool okay;
+ if (posVal > negVal)
+ okay = negVal <= offVal && offVal <= posVal && totalRange > 3000 && deadZone < 90;
+ else
+ okay = posVal <= offVal && offVal <= negVal && totalRange > 3000 && deadZone < 90;
+ if (okay)
+ {
+ JoySettings *commonSettings = GetJoySettings(ANY_JOYSTICK, true);
+ JoySettings *joySettings = GetJoySettings(joyNum, false);
+ if (joySettings == NULL)
+ {
+ joySettings = new JoySettings(*commonSettings);
+ m_joySettings.push_back(joySettings);
+ joySettings->joyNum = joyNum;
+ }
- printf("Calibrated Axis Settings:\n\n");
- printf(" Min Value = %d\n", negVal);
- printf(" Center/Off Value = %d\n", offVal);
- printf(" Max Value = %d\n", posVal);
- printf(" Dead Zone = %u %%\n", deadZone);
- printf("\nAccept these settings: y/n? ");
- fflush(stdout); // required on terminals that use buffering
-
- // Loop until user confirms or declines
- while (ReadMapping(mapping, 50, false, READ_KEYBOARD|READ_MERGE, escapeMapping))
- {
- if (stricmp(mapping, "KEY_N") == 0)
- break;
- else if (stricmp(mapping, "KEY_Y") == 0)
- {
- joySettings->axisMinVals[axisNum] = negVal;
- joySettings->axisMaxVals[axisNum] = posVal;
- joySettings->axisOffVals[axisNum] = offVal;
- joySettings->deadZones[axisNum] = deadZone;
-
- ClearSourceCache();
+ printf("Calibrated Axis Settings:\n\n");
+ printf(" Min Value = %d\n", negVal);
+ printf(" Center/Off Value = %d\n", offVal);
+ printf(" Max Value = %d\n", posVal);
+ printf(" Dead Zone = %u %%\n", deadZone);
+ printf("\nAccept these settings: y/n? ");
+ fflush(stdout); // required on terminals that use buffering
+
+ // Loop until user confirms or declines
+ while (ReadMapping(mapping, 50, false, READ_KEYBOARD|READ_MERGE, escapeMapping))
+ {
+ if (stricmp(mapping, "KEY_N") == 0)
+ break;
+ else if (stricmp(mapping, "KEY_Y") == 0)
+ {
+ joySettings->axisMinVals[axisNum] = negVal;
+ joySettings->axisMaxVals[axisNum] = posVal;
+ joySettings->axisOffVals[axisNum] = offVal;
+ joySettings->deadZones[axisNum] = deadZone;
+
+ ClearSourceCache();
- puts("Accepted");
- goto Finish;
- }
- }
- goto Cancelled;
- }
- else
- {
- puts("There was a problem calibrating the axis. This may be because the steps");
- puts("were not followed correctly or the joystick is sending invalid data.");
- printf("\nTry calibrating again: y/n? ");
- fflush(stdout); // required on terminals that use buffering
-
- // Loop until user confirms or declines
- while (ReadMapping(mapping, 50, false, READ_KEYBOARD|READ_MERGE, escapeMapping))
- {
- if (stricmp(mapping, "KEY_N") == 0)
- break;
- else if (stricmp(mapping, "KEY_Y") == 0)
- {
- puts("[Cancelled]");
- goto Repeat;
- }
- }
- goto Cancelled;
- }
-
+ puts("Accepted");
+ goto Finish;
+ }
+ }
+ goto Cancelled;
+ }
+ else
+ {
+ puts("There was a problem calibrating the axis. This may be because the steps");
+ puts("were not followed correctly or the joystick is sending invalid data.");
+ printf("\nTry calibrating again: y/n? ");
+ fflush(stdout); // required on terminals that use buffering
+
+ // Loop until user confirms or declines
+ while (ReadMapping(mapping, 50, false, READ_KEYBOARD|READ_MERGE, escapeMapping))
+ {
+ if (stricmp(mapping, "KEY_N") == 0)
+ break;
+ else if (stricmp(mapping, "KEY_Y") == 0)
+ {
+ puts("[Cancelled]");
+ goto Repeat;
+ }
+ }
+ goto Cancelled;
+ }
+
Cancelled:
- puts("[Cancelled]");
- cancelled = true;
+ puts("[Cancelled]");
+ cancelled = true;
Finish:
- if (escape)
- escape->Release();
- if (output)
- output->Release();
- return !cancelled;
+ if (escape)
+ escape->Release();
+ if (output)
+ output->Release();
+ return !cancelled;
}
void CInputSystem::PrintDevices()
{
- puts("Keyboards:");
- if (m_numKbds == 0)
- puts(" None");
- else if (m_numKbds == ANY_KEYBOARD)
- puts(" System Keyboard");
- else
- {
- for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
- {
- const KeyDetails *keyDetails = GetKeyDetails(kbdNum);
- printf(" %d: %s\n", kbdNum + 1, keyDetails->name);
- }
- }
+ puts("Keyboards:");
+ if (m_numKbds == 0)
+ puts(" None");
+ else if (m_numKbds == ANY_KEYBOARD)
+ puts(" System Keyboard");
+ else
+ {
+ for (int kbdNum = 0; kbdNum < m_numKbds; kbdNum++)
+ {
+ const KeyDetails *keyDetails = GetKeyDetails(kbdNum);
+ printf(" %d: %s\n", kbdNum + 1, keyDetails->name);
+ }
+ }
- puts("Mice:");
- if (m_numMice == 0)
- puts(" None");
- else if (m_numMice == ANY_MOUSE)
- puts(" System Mouse");
- else
- {
- for (int mseNum = 0; mseNum < m_numMice; mseNum++)
- {
- const MouseDetails *mseDetails = GetMouseDetails(mseNum);
- printf(" %d: %s\n", mseNum + 1, mseDetails->name);
- }
- }
+ puts("Mice:");
+ if (m_numMice == 0)
+ puts(" None");
+ else if (m_numMice == ANY_MOUSE)
+ puts(" System Mouse");
+ else
+ {
+ for (int mseNum = 0; mseNum < m_numMice; mseNum++)
+ {
+ const MouseDetails *mseDetails = GetMouseDetails(mseNum);
+ printf(" %d: %s\n", mseNum + 1, mseDetails->name);
+ }
+ }
- puts("Joysticks:");
- if (m_numJoys == 0)
- puts(" None");
- else if (m_numJoys == ANY_JOYSTICK)
- puts(" System Joystick");
- else
- {
- for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
- {
- const JoyDetails *joyDetails = GetJoyDetails(joyNum);
- if (joyDetails->hasFFeedback)
- printf(" %d: %s [Force Feedback Available]\n", joyNum + 1, joyDetails->name);
- else
- printf(" %d: %s\n", joyNum + 1, joyDetails->name);
- }
- }
+ puts("Joysticks:");
+ if (m_numJoys == 0)
+ puts(" None");
+ else if (m_numJoys == ANY_JOYSTICK)
+ puts(" System Joystick");
+ else
+ {
+ for (int joyNum = 0; joyNum < m_numJoys; joyNum++)
+ {
+ const JoyDetails *joyDetails = GetJoyDetails(joyNum);
+ if (joyDetails->hasFFeedback)
+ printf(" %d: %s [Force Feedback Available]\n", joyNum + 1, joyDetails->name);
+ else
+ printf(" %d: %s\n", joyNum + 1, joyDetails->name);
+ }
+ }
}
/*
* CInputSystem::CKeyInputSource
*/
CInputSystem::CKeyInputSource::CKeyInputSource(CInputSystem *system, int kbdNum, int keyIndex, unsigned sensitivity, unsigned decaySpeed) :
- CInputSource(SourceSwitch), m_system(system), m_kbdNum(kbdNum), m_keyIndex(keyIndex), m_val(0)
+ CInputSource(SourceSwitch), m_system(system), m_kbdNum(kbdNum), m_keyIndex(keyIndex), m_val(0)
{
- // Calculate max value and incr and decr values (sensitivity is given as percentage 1-100, with 100 being most sensitive, and
- // decay speed given as percentage 1-200 of attack speed)
- int s = Clamp((int)sensitivity, 1, 100);
- int d = Clamp((int)decaySpeed, 1, 200);
- m_incr = 100 * s;
- m_decr = d * s;
- m_maxVal = 10000;
+ // Calculate max value and incr and decr values (sensitivity is given as percentage 1-100, with 100 being most sensitive, and
+ // decay speed given as percentage 1-200 of attack speed)
+ int s = Clamp((int)sensitivity, 1, 100);
+ int d = Clamp((int)decaySpeed, 1, 200);
+ m_incr = 100 * s;
+ m_decr = d * s;
+ m_maxVal = 10000;
}
bool CInputSystem::CKeyInputSource::GetValueAsSwitch(bool &val)
{
- if (!m_system->IsKeyPressed(m_kbdNum, m_keyIndex))
- return false;
- val = true;
- return true;
+ if (!m_system->IsKeyPressed(m_kbdNum, m_keyIndex))
+ return false;
+ val = true;
+ return true;
}
bool CInputSystem::CKeyInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
{
- if (m_system->IsKeyPressed(m_kbdNum, m_keyIndex))
- m_val = min(m_maxVal, m_val + m_incr);
- else
- m_val = max(0, m_val - m_decr);
- if (m_val == 0)
- return false;
- val = Scale(m_val, 0, 0, m_maxVal, minVal, offVal, maxVal);
- return true;
+ if (m_system->IsKeyPressed(m_kbdNum, m_keyIndex))
+ m_val = min(m_maxVal, m_val + m_incr);
+ else
+ m_val = max(0, m_val - m_decr);
+ if (m_val == 0)
+ return false;
+ val = Scale(m_val, 0, 0, m_maxVal, minVal, offVal, maxVal);
+ return true;
}
/*
* CInputSystem::CMseAxisInputSource
*/
CInputSystem::CMseAxisInputSource::CMseAxisInputSource(CInputSystem *system, int mseNum, int axisNum, int axisDir, unsigned deadZone) :
- CInputSource(axisDir == AXIS_FULL || axisDir == AXIS_INVERTED ? SourceFullAxis : SourceHalfAxis),
- m_system(system), m_mseNum(mseNum), m_axisNum(axisNum), m_axisDir(axisDir)
+ CInputSource(axisDir == AXIS_FULL || axisDir == AXIS_INVERTED ? SourceFullAxis : SourceHalfAxis),
+ m_system(system), m_mseNum(mseNum), m_axisNum(axisNum), m_axisDir(axisDir)
{
- // If X- or Y-axis then calculate size of dead pixels region in centre of display (deadzone is given as a percentage 0-99)
- if (m_axisNum == AXIS_X || m_axisNum == AXIS_Y)
- {
- double dDeadZone = (double)Clamp((int)deadZone, 0, 99) / 100.0;
- m_deadPixels = (int)(dDeadZone * (double)(m_axisNum == AXIS_X ? m_system->m_dispW : m_system->m_dispH));
- }
- else
- m_deadPixels = Clamp((int)deadZone, 0, 99);
+ // If X- or Y-axis then calculate size of dead pixels region in centre of display (deadzone is given as a percentage 0-99)
+ if (m_axisNum == AXIS_X || m_axisNum == AXIS_Y)
+ {
+ double dDeadZone = (double)Clamp((int)deadZone, 0, 99) / 100.0;
+ m_deadPixels = (int)(dDeadZone * (double)(m_axisNum == AXIS_X ? m_system->m_dispW : m_system->m_dispH));
+ }
+ else
+ m_deadPixels = Clamp((int)deadZone, 0, 99);
}
int CInputSystem::CMseAxisInputSource::ScaleAxisValue(int minVal, int offVal, int maxVal)
{
- int mseVal = m_system->GetMouseAxisValue(m_mseNum, m_axisNum);
- // If X- or Y-axis then convert to value centered around zero (ie relative to centre of display)
- int mseMin, mseMax;
- if (m_axisNum == AXIS_X || m_axisNum == AXIS_Y)
- {
- int dispExtent = (int)(m_axisNum == AXIS_X ? m_system->m_dispW : m_system->m_dispH);
- if (dispExtent == 0)
- return offVal;
- mseMin = -dispExtent / 2;
- mseMax = mseMin + dispExtent - 1;
- mseVal = (m_axisNum == AXIS_X ? mseVal - m_system->m_dispX : mseVal - m_system->m_dispY) - dispExtent / 2;
- }
- else
- {
- // Z-axis (wheel) is always between -100 and 100
- mseMin = -100;
- mseMax = 100;
- }
- // Check value is not zero
- if (mseVal == 0)
- return offVal;
- // Scale values from dead zone to display edge, taking positive or negative values only or using the whole axis range as required
- int dZone = (mseVal > 0 ? m_deadPixels / 2 : m_deadPixels - m_deadPixels / 2);
- if (m_axisDir == AXIS_POS) return Scale(mseVal, dZone, dZone, mseMax, minVal, offVal, maxVal);
- else if (m_axisDir == AXIS_NEG) return Scale(mseVal, -dZone, -dZone, mseMin, minVal, offVal, maxVal);
- else if (m_axisDir == AXIS_FULL)
- {
- // Full axis range
- if (mseVal > 0) return Scale(mseVal, dZone, dZone, mseMax, minVal, offVal, maxVal);
- else return Scale(mseVal, mseMin, -dZone, -dZone, minVal, offVal, maxVal);
- }
- else
- {
- // Full axis range, but inverted
- if (mseVal > 0) return Scale(mseVal, dZone, dZone, mseMax, maxVal, offVal, minVal);
- else return Scale(mseVal, mseMin, -dZone, -dZone, maxVal, offVal, minVal);
- }
+ int mseVal = m_system->GetMouseAxisValue(m_mseNum, m_axisNum);
+ // If X- or Y-axis then convert to value centered around zero (ie relative to centre of display)
+ int mseMin, mseMax;
+ if (m_axisNum == AXIS_X || m_axisNum == AXIS_Y)
+ {
+ int dispExtent = (int)(m_axisNum == AXIS_X ? m_system->m_dispW : m_system->m_dispH);
+ if (dispExtent == 0)
+ return offVal;
+ mseMin = -dispExtent / 2;
+ mseMax = mseMin + dispExtent - 1;
+ mseVal = (m_axisNum == AXIS_X ? mseVal - m_system->m_dispX : mseVal - m_system->m_dispY) - dispExtent / 2;
+ }
+ else
+ {
+ // Z-axis (wheel) is always between -100 and 100
+ mseMin = -100;
+ mseMax = 100;
+ }
+ // Check value is not zero
+ if (mseVal == 0)
+ return offVal;
+ // Scale values from dead zone to display edge, taking positive or negative values only or using the whole axis range as required
+ int dZone = (mseVal > 0 ? m_deadPixels / 2 : m_deadPixels - m_deadPixels / 2);
+ if (m_axisDir == AXIS_POS) return Scale(mseVal, dZone, dZone, mseMax, minVal, offVal, maxVal);
+ else if (m_axisDir == AXIS_NEG) return Scale(mseVal, -dZone, -dZone, mseMin, minVal, offVal, maxVal);
+ else if (m_axisDir == AXIS_FULL)
+ {
+ // Full axis range
+ if (mseVal > 0) return Scale(mseVal, dZone, dZone, mseMax, minVal, offVal, maxVal);
+ else return Scale(mseVal, mseMin, -dZone, -dZone, minVal, offVal, maxVal);
+ }
+ else
+ {
+ // Full axis range, but inverted
+ if (mseVal > 0) return Scale(mseVal, dZone, dZone, mseMax, maxVal, offVal, minVal);
+ else return Scale(mseVal, mseMin, -dZone, -dZone, maxVal, offVal, minVal);
+ }
}
bool CInputSystem::CMseAxisInputSource::GetValueAsSwitch(bool &val)
{
- // For Z-axis (wheel), switch value is handled slightly differently
- if (m_axisNum == AXIS_Z)
- {
- int wheelDir = m_system->GetMouseWheelDir(m_mseNum);
- if (((m_axisDir == AXIS_POS || m_axisDir == AXIS_FULL) && wheelDir <= 0) ||
- ((m_axisDir == AXIS_NEG || m_axisDir == AXIS_INVERTED) && wheelDir >= 0))
- return false;
- }
- else
- {
- if (ScaleAxisValue(0, 0, 3) < 2)
- return false;
- }
- val = true;
- return true;
+ // For Z-axis (wheel), switch value is handled slightly differently
+ if (m_axisNum == AXIS_Z)
+ {
+ int wheelDir = m_system->GetMouseWheelDir(m_mseNum);
+ if (((m_axisDir == AXIS_POS || m_axisDir == AXIS_FULL) && wheelDir <= 0) ||
+ ((m_axisDir == AXIS_NEG || m_axisDir == AXIS_INVERTED) && wheelDir >= 0))
+ return false;
+ }
+ else
+ {
+ if (ScaleAxisValue(0, 0, 3) < 2)
+ return false;
+ }
+ val = true;
+ return true;
}
bool CInputSystem::CMseAxisInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
{
- int axisVal = ScaleAxisValue(minVal, offVal, maxVal);
- if (axisVal == offVal)
- return false;
- val = axisVal;
- return true;
+ int axisVal = ScaleAxisValue(minVal, offVal, maxVal);
+ if (axisVal == offVal)
+ return false;
+ val = axisVal;
+ return true;
}
/*
* CInputSystem::CMseButInputSource
*/
CInputSystem::CMseButInputSource::CMseButInputSource(CInputSystem *system, int mseNum, int butNum) :
- CInputSource(SourceSwitch), m_system(system), m_mseNum(mseNum), m_butNum(butNum)
+ CInputSource(SourceSwitch), m_system(system), m_mseNum(mseNum), m_butNum(butNum)
{
- //
+ //
}
bool CInputSystem::CMseButInputSource::GetValueAsSwitch(bool &val)
{
- if (!m_system->IsMouseButPressed(m_mseNum, m_butNum))
- return false;
- val = true;
- return true;
+ if (!m_system->IsMouseButPressed(m_mseNum, m_butNum))
+ return false;
+ val = true;
+ return true;
}
bool CInputSystem::CMseButInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
{
- if (!m_system->IsMouseButPressed(m_mseNum, m_butNum))
- return false;
- val = maxVal;
- return true;
+ if (!m_system->IsMouseButPressed(m_mseNum, m_butNum))
+ return false;
+ val = maxVal;
+ return true;
}
/*
* CInputSystem::CJoyAxisInputSource
*/
CInputSystem::CJoyAxisInputSource::CJoyAxisInputSource(CInputSystem *system, int joyNum, int axisNum, int axisDir,
- int axisMinVal, int axisOffVal, int axisMaxVal, unsigned deadZone, unsigned saturation) :
- CInputSource(axisDir == AXIS_FULL || axisDir == AXIS_INVERTED ? SourceFullAxis : SourceHalfAxis),
- m_system(system), m_joyNum(joyNum), m_axisNum(axisNum), m_axisDir(axisDir), m_axisMinVal(axisMinVal), m_axisOffVal(axisOffVal), m_axisMaxVal(axisMaxVal)
+ int axisMinVal, int axisOffVal, int axisMaxVal, unsigned deadZone, unsigned saturation) :
+ CInputSource(axisDir == AXIS_FULL || axisDir == AXIS_INVERTED ? SourceFullAxis : SourceHalfAxis),
+ m_system(system), m_joyNum(joyNum), m_axisNum(axisNum), m_axisDir(axisDir), m_axisMinVal(axisMinVal), m_axisOffVal(axisOffVal), m_axisMaxVal(axisMaxVal)
{
- m_axisInverted = m_axisMaxVal < m_axisMinVal;
- // Calculate pos/neg deadzone and saturation points (joystick raw values range from axisMinVal to axisMasVal (centered/off at axisOffVal),
- // deadzone given as percentage 0-99 and saturation given as percentage 1 - 200)
- double dDeadZone = (double)Clamp((int)deadZone, 0, 99) / 100.0;
- double dSaturation = (double)Clamp((int)saturation, (int)deadZone + 1, 200) / 100.0;
- m_posDZone = m_axisOffVal + (int)(dDeadZone * (m_axisMaxVal - m_axisOffVal));
- m_negDZone = m_axisOffVal + (int)(dDeadZone * (m_axisMinVal - m_axisOffVal));
- m_posSat = m_axisOffVal + (int)(dSaturation * (m_axisMaxVal - m_axisOffVal));
- m_negSat = m_axisOffVal + (int)(dSaturation * (m_axisMinVal - m_axisOffVal));
+ m_axisInverted = m_axisMaxVal < m_axisMinVal;
+ // Calculate pos/neg deadzone and saturation points (joystick raw values range from axisMinVal to axisMasVal (centered/off at axisOffVal),
+ // deadzone given as percentage 0-99 and saturation given as percentage 1 - 200)
+ double dDeadZone = (double)Clamp((int)deadZone, 0, 99) / 100.0;
+ double dSaturation = (double)Clamp((int)saturation, (int)deadZone + 1, 200) / 100.0;
+ m_posDZone = m_axisOffVal + (int)(dDeadZone * (m_axisMaxVal - m_axisOffVal));
+ m_negDZone = m_axisOffVal + (int)(dDeadZone * (m_axisMinVal - m_axisOffVal));
+ m_posSat = m_axisOffVal + (int)(dSaturation * (m_axisMaxVal - m_axisOffVal));
+ m_negSat = m_axisOffVal + (int)(dSaturation * (m_axisMinVal - m_axisOffVal));
}
int CInputSystem::CJoyAxisInputSource::ScaleAxisValue(int minVal, int offVal, int maxVal)
{
- // Get raw axis value from input system
- int joyVal = m_system->GetJoyAxisValue(m_joyNum, m_axisNum);
- // Check if value is at axis off value
- if (joyVal == m_axisOffVal)
- return offVal;
- // Scale value between deadzone and saturation points, taking positive or negative values only or using the whole axis range as required
- if (m_axisDir == AXIS_POS) return Scale(joyVal, m_posDZone, m_posDZone, m_posSat, minVal, offVal, maxVal);
- else if (m_axisDir == AXIS_NEG) return Scale(joyVal, m_negDZone, m_negDZone, m_negSat, minVal, offVal, maxVal);
- else if (m_axisDir == AXIS_FULL)
- {
- // Full axis range
- if ((!m_axisInverted && joyVal > m_axisOffVal) || (m_axisInverted && joyVal < m_axisOffVal))
- return Scale(joyVal, m_posDZone, m_posDZone, m_posSat, minVal, offVal, maxVal);
- else
- return Scale(joyVal, m_negSat, m_negDZone, m_negDZone, minVal, offVal, maxVal);
- }
- else
- {
- // Full axis range, but inverted
- if ((!m_axisInverted && joyVal > m_axisOffVal) || (m_axisInverted && joyVal < m_axisOffVal))
- return Scale(joyVal, m_posDZone, m_posDZone, m_posSat, maxVal, offVal, minVal);
- else
- return Scale(joyVal, m_negSat, m_negDZone, m_negDZone, maxVal, offVal, minVal);
- }
+ // Get raw axis value from input system
+ int joyVal = m_system->GetJoyAxisValue(m_joyNum, m_axisNum);
+ // Check if value is at axis off value
+ if (joyVal == m_axisOffVal)
+ return offVal;
+ // Scale value between deadzone and saturation points, taking positive or negative values only or using the whole axis range as required
+ if (m_axisDir == AXIS_POS) return Scale(joyVal, m_posDZone, m_posDZone, m_posSat, minVal, offVal, maxVal);
+ else if (m_axisDir == AXIS_NEG) return Scale(joyVal, m_negDZone, m_negDZone, m_negSat, minVal, offVal, maxVal);
+ else if (m_axisDir == AXIS_FULL)
+ {
+ // Full axis range
+ if ((!m_axisInverted && joyVal > m_axisOffVal) || (m_axisInverted && joyVal < m_axisOffVal))
+ return Scale(joyVal, m_posDZone, m_posDZone, m_posSat, minVal, offVal, maxVal);
+ else
+ return Scale(joyVal, m_negSat, m_negDZone, m_negDZone, minVal, offVal, maxVal);
+ }
+ else
+ {
+ // Full axis range, but inverted
+ if ((!m_axisInverted && joyVal > m_axisOffVal) || (m_axisInverted && joyVal < m_axisOffVal))
+ return Scale(joyVal, m_posDZone, m_posDZone, m_posSat, maxVal, offVal, minVal);
+ else
+ return Scale(joyVal, m_negSat, m_negDZone, m_negDZone, maxVal, offVal, minVal);
+ }
}
bool CInputSystem::CJoyAxisInputSource::GetValueAsSwitch(bool &val)
{
- if (ScaleAxisValue(0, 0, 3) < 2)
- return false;
- val = true;
- return true;
+ if (ScaleAxisValue(0, 0, 3) < 2)
+ return false;
+ val = true;
+ return true;
}
bool CInputSystem::CJoyAxisInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
{
- int axisVal = ScaleAxisValue(minVal, offVal, maxVal);
- if (axisVal == offVal)
- return false;
- val = axisVal;
- return true;
+ int axisVal = ScaleAxisValue(minVal, offVal, maxVal);
+ if (axisVal == offVal)
+ return false;
+ val = axisVal;
+ return true;
}
bool CInputSystem::CJoyAxisInputSource::SendForceFeedbackCmd(ForceFeedbackCmd ffCmd)
{
- return m_system->SendForceFeedbackCmd(m_joyNum, m_axisNum, ffCmd);
+ return m_system->SendForceFeedbackCmd(m_joyNum, m_axisNum, ffCmd);
}
/*
* CInputSystem::CJoyPOVInputSource
*/
CInputSystem::CJoyPOVInputSource::CJoyPOVInputSource(CInputSystem *system, int joyNum, int povNum, int povDir) :
- CInputSource(SourceSwitch), m_system(system), m_joyNum(joyNum), m_povNum(povNum), m_povDir(povDir)
+ CInputSource(SourceSwitch), m_system(system), m_joyNum(joyNum), m_povNum(povNum), m_povDir(povDir)
{
- //
+ //
}
bool CInputSystem::CJoyPOVInputSource::GetValueAsSwitch(bool &val)
{
- if (!m_system->IsJoyPOVInDir(m_joyNum, m_povNum, m_povDir))
- return false;
- val = true;
- return true;
+ if (!m_system->IsJoyPOVInDir(m_joyNum, m_povNum, m_povDir))
+ return false;
+ val = true;
+ return true;
}
bool CInputSystem::CJoyPOVInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
{
- if (!m_system->IsJoyPOVInDir(m_joyNum, m_povNum, m_povDir))
- return false;
- val = maxVal;
- return true;
+ if (!m_system->IsJoyPOVInDir(m_joyNum, m_povNum, m_povDir))
+ return false;
+ val = maxVal;
+ return true;
}
-
+
/*
* CInputSystem::CJoyButInputSource
*/
CInputSystem::CJoyButInputSource::CJoyButInputSource(CInputSystem *system, int joyNum, int butNum) :
- CInputSource(SourceSwitch), m_system(system), m_joyNum(joyNum), m_butNum(butNum)
+ CInputSource(SourceSwitch), m_system(system), m_joyNum(joyNum), m_butNum(butNum)
{
- //
+ //
}
bool CInputSystem::CJoyButInputSource::GetValueAsSwitch(bool &val)
{
- if (!m_system->IsJoyButPressed(m_joyNum, m_butNum))
- return false;
- val = true;
- return true;
+ if (!m_system->IsJoyButPressed(m_joyNum, m_butNum))
+ return false;
+ val = true;
+ return true;
}
bool CInputSystem::CJoyButInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
{
- if (!m_system->IsJoyButPressed(m_joyNum, m_butNum))
- return false;
- val = maxVal;
- return true;
+ if (!m_system->IsJoyButPressed(m_joyNum, m_butNum))
+ return false;
+ val = maxVal;
+ return true;
}
diff --git a/Src/Inputs/InputSystem.h b/Src/Inputs/InputSystem.h
index 9cdb4e8..d4293c9 100644
--- a/Src/Inputs/InputSystem.h
+++ b/Src/Inputs/InputSystem.h
@@ -35,6 +35,7 @@
using namespace std;
#include "MultiInputSource.h"
+#include "Util/NewConfig.h"
class CInput;
class CInputSource;
@@ -104,24 +105,24 @@ class CINIFile;
*/
enum EMousePart
{
- MouseUnknown = -1,
- MouseXAxis = 0,
- MouseXAxisInv,
- MouseXAxisPos,
- MouseXAxisNeg,
- MouseYAxis,
- MouseYAxisInv,
- MouseYAxisPos,
- MouseYAxisNeg,
- MouseZAxis,
- MouseZAxisInv,
- MouseZAxisPos,
- MouseZAxisNeg,
- MouseButtonLeft,
- MouseButtonMiddle,
- MouseButtonRight,
- MouseButtonX1,
- MouseButtonX2,
+ MouseUnknown = -1,
+ MouseXAxis = 0,
+ MouseXAxisInv,
+ MouseXAxisPos,
+ MouseXAxisNeg,
+ MouseYAxis,
+ MouseYAxisInv,
+ MouseYAxisPos,
+ MouseYAxisNeg,
+ MouseZAxis,
+ MouseZAxisInv,
+ MouseZAxisPos,
+ MouseZAxisNeg,
+ MouseButtonLeft,
+ MouseButtonMiddle,
+ MouseButtonRight,
+ MouseButtonX1,
+ MouseButtonX2,
};
/*
@@ -129,99 +130,99 @@ enum EMousePart
*/
enum EJoyPart
{
- JoyUnknown = -1,
- JoyXAxis = 0,
- JoyXAxisInv,
- JoyXAxisPos,
- JoyXAxisNeg,
- JoyYAxis,
- JoyYAxisInv,
- JoyYAxisPos,
- JoyYAxisNeg,
- JoyZAxis,
- JoyZAxisInv,
- JoyZAxisPos,
- JoyZAxisNeg,
- JoyRXAxis,
- JoyRXAxisInv,
- JoyRXAxisPos,
- JoyRXAxisNeg,
- JoyRYAxis,
- JoyRYAxisInv,
- JoyRYAxisPos,
- JoyRYAxisNeg,
- JoyRZAxis,
- JoyRZAxisInv,
- JoyRZAxisPos,
- JoyRZAxisNeg,
- JoyS1Axis,
- JoyS1AxisInv,
- JoyS1AxisPos,
- JoyS1AxisNeg,
- JoyS2Axis,
- JoyS2AxisInv,
- JoyS2AxisPos,
- JoyS2AxisNeg,
- JoyPOV0Up,
- JoyPOV0Down,
- JoyPOV0Left,
- JoyPOV0Right,
- JoyPOV1Up,
- JoyPOV1Down,
- JoyPOV1Left,
- JoyPOV1Right,
- JoyPOV2Up,
- JoyPOV2Down,
- JoyPOV2Left,
- JoyPOV2Right,
- JoyPOV3Up,
- JoyPOV3Down,
- JoyPOV3Left,
- JoyPOV3Right,
- JoyButton0,
- JoyButton1,
- JoyButton2,
- JoyButton3,
- JoyButton4,
- JoyButton5,
- JoyButton6,
- JoyButton7,
- JoyButton8,
- JoyButton9,
- JoyButton10,
- JoyButton11,
- JoyButton12,
- JoyButton13,
- JoyButton14,
- JoyButton15,
- JoyButton16,
- JoyButton17,
- JoyButton18,
- JoyButton19,
- JoyButton20,
- JoyButton21,
- JoyButton22,
- JoyButton23,
- JoyButton24,
- JoyButton25,
- JoyButton26,
- JoyButton27,
- JoyButton28,
- JoyButton29,
- JoyButton30,
- JoyButton31
+ JoyUnknown = -1,
+ JoyXAxis = 0,
+ JoyXAxisInv,
+ JoyXAxisPos,
+ JoyXAxisNeg,
+ JoyYAxis,
+ JoyYAxisInv,
+ JoyYAxisPos,
+ JoyYAxisNeg,
+ JoyZAxis,
+ JoyZAxisInv,
+ JoyZAxisPos,
+ JoyZAxisNeg,
+ JoyRXAxis,
+ JoyRXAxisInv,
+ JoyRXAxisPos,
+ JoyRXAxisNeg,
+ JoyRYAxis,
+ JoyRYAxisInv,
+ JoyRYAxisPos,
+ JoyRYAxisNeg,
+ JoyRZAxis,
+ JoyRZAxisInv,
+ JoyRZAxisPos,
+ JoyRZAxisNeg,
+ JoyS1Axis,
+ JoyS1AxisInv,
+ JoyS1AxisPos,
+ JoyS1AxisNeg,
+ JoyS2Axis,
+ JoyS2AxisInv,
+ JoyS2AxisPos,
+ JoyS2AxisNeg,
+ JoyPOV0Up,
+ JoyPOV0Down,
+ JoyPOV0Left,
+ JoyPOV0Right,
+ JoyPOV1Up,
+ JoyPOV1Down,
+ JoyPOV1Left,
+ JoyPOV1Right,
+ JoyPOV2Up,
+ JoyPOV2Down,
+ JoyPOV2Left,
+ JoyPOV2Right,
+ JoyPOV3Up,
+ JoyPOV3Down,
+ JoyPOV3Left,
+ JoyPOV3Right,
+ JoyButton0,
+ JoyButton1,
+ JoyButton2,
+ JoyButton3,
+ JoyButton4,
+ JoyButton5,
+ JoyButton6,
+ JoyButton7,
+ JoyButton8,
+ JoyButton9,
+ JoyButton10,
+ JoyButton11,
+ JoyButton12,
+ JoyButton13,
+ JoyButton14,
+ JoyButton15,
+ JoyButton16,
+ JoyButton17,
+ JoyButton18,
+ JoyButton19,
+ JoyButton20,
+ JoyButton21,
+ JoyButton22,
+ JoyButton23,
+ JoyButton24,
+ JoyButton25,
+ JoyButton26,
+ JoyButton27,
+ JoyButton28,
+ JoyButton29,
+ JoyButton30,
+ JoyButton31
};
struct MousePartsStruct
{
- const char* id;
- EMousePart msePart;
+ const char* id;
+ EMousePart msePart;
};
struct JoyPartsStruct
{
- const char* id;
- EJoyPart joyPart;
+ const char* id;
+ EJoyPart joyPart;
};
/*
@@ -229,19 +230,19 @@ struct JoyPartsStruct
*/
struct KeySettings
{
- int kbdNum; // Keyboard number (or ANY_KEYBOARD for settings that apply to all keyboards)
- unsigned sensitivity; // Key sensitivity for analog controls as percentage 1-100, where 100 is extremely responsive
+ int kbdNum; // Keyboard number (or ANY_KEYBOARD for settings that apply to all keyboards)
+ unsigned sensitivity; // Key sensitivity for analog controls as percentage 1-100, where 100 is extremely responsive
unsigned decaySpeed; // Decay speed as percentage 1-200 of on speed
-
- /*
- * Creates a KeySettings with default settings
- */
- KeySettings()
- {
- kbdNum = ANY_KEYBOARD;
- sensitivity = DEFAULT_KEY_SENSITIVITY;
- decaySpeed = DEFAULT_KEY_DECAYSPEED;
- }
+
+ /*
+ * Creates a KeySettings with default settings
+ */
+ KeySettings()
+ {
+ kbdNum = ANY_KEYBOARD;
+ sensitivity = DEFAULT_KEY_SENSITIVITY;
+ decaySpeed = DEFAULT_KEY_DECAYSPEED;
+ }
};
/*
@@ -249,19 +250,19 @@ struct KeySettings
*/
struct MouseSettings
{
- int mseNum; // Mouse number (or ANY_MOUSE for settings that apply to all mice)
- unsigned deadZones[NUM_MOUSE_AXES]; // Axis dead zone as a percentage 0-99 of display width (X)/height (Y) or axis range (Z)
+ int mseNum; // Mouse number (or ANY_MOUSE for settings that apply to all mice)
+ unsigned deadZones[NUM_MOUSE_AXES]; // Axis dead zone as a percentage 0-99 of display width (X)/height (Y) or axis range (Z)
- /*
- * Creates a MouseSettings with default settings
- */
- MouseSettings()
- {
- mseNum = ANY_MOUSE;
- deadZones[AXIS_X] = DEFAULT_MSE_DEADZONE;
- deadZones[AXIS_Y] = DEFAULT_MSE_DEADZONE;
- deadZones[AXIS_Z] = 0;
- }
+ /*
+ * Creates a MouseSettings with default settings
+ */
+ MouseSettings()
+ {
+ mseNum = ANY_MOUSE;
+ deadZones[AXIS_X] = DEFAULT_MSE_DEADZONE;
+ deadZones[AXIS_Y] = DEFAULT_MSE_DEADZONE;
+ deadZones[AXIS_Z] = 0;
+ }
};
/*
@@ -269,51 +270,51 @@ struct MouseSettings
*/
struct JoySettings
{
- int joyNum; // Joystick number (or ANY_JOYSTICK for settings that apply to all joysticks)
- int axisMinVals[NUM_JOY_AXES]; // Axis min raw value (default -32768)
- int axisOffVals[NUM_JOY_AXES]; // Axis center/off value (default 0)
- int axisMaxVals[NUM_JOY_AXES]; // Axis max raw value (default 32767)
- unsigned deadZones[NUM_JOY_AXES]; // Axis dead zone as a percentage 0-99 of axis positive/negative ranges
- unsigned saturations[NUM_JOY_AXES]; // Axis saturation as a percentage 1-200 of axis positive/negative ranges
+ int joyNum; // Joystick number (or ANY_JOYSTICK for settings that apply to all joysticks)
+ int axisMinVals[NUM_JOY_AXES]; // Axis min raw value (default -32768)
+ int axisOffVals[NUM_JOY_AXES]; // Axis center/off value (default 0)
+ int axisMaxVals[NUM_JOY_AXES]; // Axis max raw value (default 32767)
+ unsigned deadZones[NUM_JOY_AXES]; // Axis dead zone as a percentage 0-99 of axis positive/negative ranges
+ unsigned saturations[NUM_JOY_AXES]; // Axis saturation as a percentage 1-200 of axis positive/negative ranges
- /*
- * Creates a JoySettings with default settings
- */
- JoySettings()
- {
- joyNum = ANY_JOYSTICK;
- for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
- {
- axisMinVals[axisNum] = DEFAULT_JOY_AXISMINVAL;
- axisOffVals[axisNum] = DEFAULT_JOY_AXISOFFVAL;
- axisMaxVals[axisNum] = DEFAULT_JOY_AXISMAXVAL;
- deadZones[axisNum] = DEFAULT_JOY_DEADZONE;
- saturations[axisNum] = DEFAULT_JOY_SATURATION;
- }
- }
+ /*
+ * Creates a JoySettings with default settings
+ */
+ JoySettings()
+ {
+ joyNum = ANY_JOYSTICK;
+ for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
+ {
+ axisMinVals[axisNum] = DEFAULT_JOY_AXISMINVAL;
+ axisOffVals[axisNum] = DEFAULT_JOY_AXISOFFVAL;
+ axisMaxVals[axisNum] = DEFAULT_JOY_AXISMAXVAL;
+ deadZones[axisNum] = DEFAULT_JOY_DEADZONE;
+ saturations[axisNum] = DEFAULT_JOY_SATURATION;
+ }
+ }
};
struct KeyDetails
{
- char name[MAX_NAME_LENGTH + 1]; // Keyboard name (if available)
+ char name[MAX_NAME_LENGTH + 1]; // Keyboard name (if available)
};
struct MouseDetails
{
- char name[MAX_NAME_LENGTH + 1]; // Mouse name (if available)
- bool isAbsolute; // True if uses absolute positions (ie lightgun)
+ char name[MAX_NAME_LENGTH + 1]; // Mouse name (if available)
+ bool isAbsolute; // True if uses absolute positions (ie lightgun)
};
struct JoyDetails
{
- char name[MAX_NAME_LENGTH + 1]; // Joystick name (if available)
- int numAxes; // Total number of axes on joystick
- int numPOVs; // Total number of POV hat controllers on joystick
- int numButtons; // Total number of buttons on joystick
- bool hasFFeedback; // True if joystick supports force feedback
- bool hasAxis[NUM_JOY_AXES]; // Flags to indicate which axes available on joystick
- char axisName[NUM_JOY_AXES][MAX_NAME_LENGTH + 1]; // Axis names (if available)
- bool axisHasFF[NUM_JOY_AXES]; // Flags to indicate which axes are force feedback enabled
+ char name[MAX_NAME_LENGTH + 1]; // Joystick name (if available)
+ int numAxes; // Total number of axes on joystick
+ int numPOVs; // Total number of POV hat controllers on joystick
+ int numButtons; // Total number of buttons on joystick
+ bool hasFFeedback; // True if joystick supports force feedback
+ bool hasAxis[NUM_JOY_AXES]; // Flags to indicate which axes available on joystick
+ char axisName[NUM_JOY_AXES][MAX_NAME_LENGTH + 1]; // Axis names (if available)
+ bool axisHasFF[NUM_JOY_AXES]; // Flags to indicate which axes are force feedback enabled
};
/*
@@ -321,685 +322,693 @@ struct JoyDetails
* mice and joysticks.
*/
class CInputSystem
-{
+{
private:
- // Array of valid key names
- static const char *s_validKeyNames[];
+ // Array of valid key names
+ static const char *s_validKeyNames[];
- // Lookup table for translating mouse mapping strings to their respective mouse parts
- static MousePartsStruct s_mseParts[];
+ // Lookup table for translating mouse mapping strings to their respective mouse parts
+ static MousePartsStruct s_mseParts[];
- // Lookup table for translating joystick mapping strings to their respective joystick parts
- static JoyPartsStruct s_joyParts[];
+ // Lookup table for translating joystick mapping strings to their respective joystick parts
+ static JoyPartsStruct s_joyParts[];
- // Ids and names of axes
- static const char *s_axisIds[];
- static const char *s_axisNames[];
+ // Ids and names of axes
+ static const char *s_axisIds[];
+ static const char *s_axisNames[];
- // Number of keyboards, mice and joysticks
- int m_numKbds;
- int m_numMice;
- int m_numJoys;
+ // Number of keyboards, mice and joysticks
+ int m_numKbds;
+ int m_numMice;
+ int m_numJoys;
- // Cached input sources
- CInputSource **m_anyKeySources;
- CInputSource **m_anyMseSources;
- CInputSource **m_anyJoySources;
- CInputSource ***m_keySources;
- CInputSource ***m_mseSources;
- CInputSource ***m_joySources;
-
- // Default key, mouse and joystick settings
- KeySettings m_defKeySettings;
- MouseSettings m_defMseSettings;
- JoySettings m_defJoySettings;
+ // Cached input sources
+ CInputSource **m_anyKeySources;
+ CInputSource **m_anyMseSources;
+ CInputSource **m_anyJoySources;
+ CInputSource ***m_keySources;
+ CInputSource ***m_mseSources;
+ CInputSource ***m_joySources;
+
+ // Default key, mouse and joystick settings
+ KeySettings m_defKeySettings;
+ MouseSettings m_defMseSettings;
+ JoySettings m_defJoySettings;
- // Current key, mouse and joystick settings for attached keyboards, mice and joysticks
- vector m_keySettings;
- vector m_mseSettings;
- vector m_joySettings;
+ // Current key, mouse and joystick settings for attached keyboards, mice and joysticks
+ vector m_keySettings;
+ vector m_mseSettings;
+ vector m_joySettings;
- // Empty input source
- CMultiInputSource *m_emptySource;
+ // Empty input source
+ CMultiInputSource *m_emptySource;
- //
- // Helper methods
- //
+ //
+ // Helper methods
+ //
- /*
- * Creates source cache.
- */
- void CreateSourceCache();
+ /*
+ * Creates source cache.
+ */
+ void CreateSourceCache();
- /*
- * Clears cache of all sources and optionally deletes cache itself.
- */
- void ClearSourceCache(bool deleteCache = false);
+ /*
+ * Clears cache of all sources and optionally deletes cache itself.
+ */
+ void ClearSourceCache(bool deleteCache = false);
- /*
- * Releases a source from the cache.
- */
- void ReleaseSource(CInputSource *&source);
-
- /*
- * Returns a key source for the given keyboard number (or all keyboards if ANY_KEYBOARD supplied) and key index.
- * Will check the source cache first and if not found will create the source with CreateAnyKeySource or CreateKeySource.
- */
- CInputSource *GetKeySource(int kbdNum, int keyIndex);
+ /*
+ * Releases a source from the cache.
+ */
+ void ReleaseSource(CInputSource *&source);
+
+ /*
+ * Returns a key source for the given keyboard number (or all keyboards if ANY_KEYBOARD supplied) and key index.
+ * Will check the source cache first and if not found will create the source with CreateAnyKeySource or CreateKeySource.
+ */
+ CInputSource *GetKeySource(int kbdNum, int keyIndex);
- /*
- * Returns a mouse source for the given mouse number (or all mice if ANY_MOUSE supplied) and mouse index.
- * Will check the source cache first and if not found will create the source with CreateAnyMouseSource or CreateMouseSource.
- */
- CInputSource *GetMouseSource(int mseNum, EMousePart msePart);
+ /*
+ * Returns a mouse source for the given mouse number (or all mice if ANY_MOUSE supplied) and mouse index.
+ * Will check the source cache first and if not found will create the source with CreateAnyMouseSource or CreateMouseSource.
+ */
+ CInputSource *GetMouseSource(int mseNum, EMousePart msePart);
- /*
- * Returns a joystick source for the given joystick number (or all joysticks if ANY_JOYSTICK supplied) and joystick index.
- * Will check the source cache first and if not found will create the source with CreateAnyJoySource or CreateJoySource.
- */
- CInputSource *GetJoySource(int joyNum, EJoyPart joyPart);
+ /*
+ * Returns a joystick source for the given joystick number (or all joysticks if ANY_JOYSTICK supplied) and joystick index.
+ * Will check the source cache first and if not found will create the source with CreateAnyJoySource or CreateJoySource.
+ */
+ CInputSource *GetJoySource(int joyNum, EJoyPart joyPart);
- void CheckAllSources(unsigned readFlags, bool fullAxisOnly, bool &mseCentered, vector &sources, string &mapping, vector &badSources);
+ void CheckAllSources(unsigned readFlags, bool fullAxisOnly, bool &mseCentered, vector &sources, string &mapping, vector &badSources);
- /*
- * Finds any currently activated key sources for the given keyboard number (or all keyboards if ANY_KEYBOARD supplied)
- * and adds them to the sources vector, aswell as constructing the corresponding mapping(s) in the given string.
- * If fullAxisOnly is true, then only sources that represent a full axis range (eg MouseXAxis) are considered.
- */
- void CheckKeySources(int kbdNum, bool fullAxisOnly, vector &sources, string &mapping, vector &badSources);
+ /*
+ * Finds any currently activated key sources for the given keyboard number (or all keyboards if ANY_KEYBOARD supplied)
+ * and adds them to the sources vector, aswell as constructing the corresponding mapping(s) in the given string.
+ * If fullAxisOnly is true, then only sources that represent a full axis range (eg MouseXAxis) are considered.
+ */
+ void CheckKeySources(int kbdNum, bool fullAxisOnly, vector &sources, string &mapping, vector &badSources);
- /*
- * Finds any currently activated mouse sources for the given mouse number (or all mice if ANY_MOUSE supplied)
- * and adds them to the sources vector, aswell as constructing the corresponding mapping(s) in the given string.
- * If fullAxisOnly is true, then only sources that represent a full axis range (eg MouseXAxis) are considered.
- */
- void CheckMouseSources(int mseNum, bool fullAxisOnly, bool mseCentered, vector &sources, string &mapping, vector &badSources);
+ /*
+ * Finds any currently activated mouse sources for the given mouse number (or all mice if ANY_MOUSE supplied)
+ * and adds them to the sources vector, aswell as constructing the corresponding mapping(s) in the given string.
+ * If fullAxisOnly is true, then only sources that represent a full axis range (eg MouseXAxis) are considered.
+ */
+ void CheckMouseSources(int mseNum, bool fullAxisOnly, bool mseCentered, vector &sources, string &mapping, vector &badSources);
- /*
- * Finds any currently activated joystick sources for the given joystick number (or all joysticks if ANY_JOYSTICK supplied)
- * and adds them to the sources vector, aswell as constructing the corresponding mapping(s) in the given string.
- * If fullAxisOnly is true, then only sources that represent a full axis range (eg MouseXAxis) are considered.
- */
- void CheckJoySources(int joyNum, bool fullAxisOnly, vector &sources, string &mapping, vector &badSources);
+ /*
+ * Finds any currently activated joystick sources for the given joystick number (or all joysticks if ANY_JOYSTICK supplied)
+ * and adds them to the sources vector, aswell as constructing the corresponding mapping(s) in the given string.
+ * If fullAxisOnly is true, then only sources that represent a full axis range (eg MouseXAxis) are considered.
+ */
+ void CheckJoySources(int joyNum, bool fullAxisOnly, vector &sources, string &mapping, vector &badSources);
- bool ParseInt(string str, int &num);
+ bool ParseInt(string str, int &num);
- string IntToString(int num);
+ string IntToString(int num);
- bool EqualsIgnoreCase(string str1, const char *str2);
+ bool EqualsIgnoreCase(string str1, const char *str2);
- bool StartsWithIgnoreCase(string str1, const char *str2);
+ bool StartsWithIgnoreCase(string str1, const char *str2);
- /*
- * Returns true if the given string represents a valid key name.
- */
- bool IsValidKeyName(string str);
+ /*
+ * Returns true if the given string represents a valid key name.
+ */
+ bool IsValidKeyName(string str);
- /*
- * Returns the EMousePart with the given mapping name or MouseUnknown if not found.
- */
- EMousePart LookupMousePart(string str);
+ /*
+ * Returns the EMousePart with the given mapping name or MouseUnknown if not found.
+ */
+ EMousePart LookupMousePart(string str);
- /*
- * Returns the mapping name for the given EMousePart.
- */
- const char *LookupName(EMousePart msePart);
+ /*
+ * Returns the mapping name for the given EMousePart.
+ */
+ const char *LookupName(EMousePart msePart);
- /*
- * Returns the EJoyPart with the given mapping name or JoyUnknown if not found.
- */
- EJoyPart LookupJoyPart(string str);
+ /*
+ * Returns the EJoyPart with the given mapping name or JoyUnknown if not found.
+ */
+ EJoyPart LookupJoyPart(string str);
- /*
- * Returns the mapping name for the given EJoyPart.
- */
- const char *LookupName(EJoyPart joyPart);
+ /*
+ * Returns the mapping name for the given EJoyPart.
+ */
+ const char *LookupName(EJoyPart joyPart);
- size_t ParseDevMapping(string str, const char *devType, int &devNum);
+ size_t ParseDevMapping(string str, const char *devType, int &devNum);
- /*
- * Parses the given mapping string, possibly representing more than one mapping, and returns an input source for it or NULL if the
- * mapping is invalid.
- * If fullAxisOnly is true, then only mappings that represent a full axis range (eg MouseXAxis) are parsed.
- */
- CInputSource* ParseMultiSource(string str, bool fullAxisOnly, bool isOr);
+ /*
+ * Parses the given mapping string, possibly representing more than one mapping, and returns an input source for it or NULL if the
+ * mapping is invalid.
+ * If fullAxisOnly is true, then only mappings that represent a full axis range (eg MouseXAxis) are parsed.
+ */
+ CInputSource* ParseMultiSource(string str, bool fullAxisOnly, bool isOr);
- /*
- * Parses the given single mapping string and returns an input source for it, or NULL if non exists.
- */
- CInputSource* ParseSingleSource(string str);
+ /*
+ * Parses the given single mapping string and returns an input source for it, or NULL if non exists.
+ */
+ CInputSource* ParseSingleSource(string str);
- /*
- * Prints the given key settings to stdout.
- */
- void PrintKeySettings(int kbdNum, KeySettings *settings);
+ /*
+ * Prints the given key settings to stdout.
+ */
+ void PrintKeySettings(int kbdNum, KeySettings *settings);
- /*
- * Reads key settings from an INI file for the given keyboard number, or common settings if ANY_KEYBOARD specified.
- * Returns NULL if no relevant settings were found in the INI file.
- */
- KeySettings *ReadKeySettings(CINIFile *ini, const char *section, int kbdNum);
+ /*
+ * Reads key settings from an INI file for the given keyboard number, or common settings if ANY_KEYBOARD specified.
+ * Returns NULL if no relevant settings were found in the INI file.
+ */
+ KeySettings *LoadKeySettings(const Util::Config::Node &config, int kbdNum);
+ KeySettings *ReadKeySettings(CINIFile *ini, const char *section, int kbdNum);
- /*
- * Writes the given key settings to an INI file, only writing out settings that are different to their defaults.
- */
- void WriteKeySettings(CINIFile *ini, const char *section, KeySettings *settings);
+ /*
+ * Writes the given key settings to an INI file, only writing out settings that are different to their defaults.
+ */
+ void StoreKeySettings(Util::Config::Node *config, KeySettings *settings);
+ void WriteKeySettings(CINIFile *ini, const char *section, KeySettings *settings);
- /*
- * Prints the given mouse settings to stdout.
- */
- void PrintMouseSettings(int mseNum, MouseSettings *settings);
+ /*
+ * Prints the given mouse settings to stdout.
+ */
+ void PrintMouseSettings(int mseNum, MouseSettings *settings);
- /*
- * Reads mouse settings from an INI file for the given mouse number, or common settings if ANY_MOUSE specified.
- * Returns NULL if no relevant settings were found in the INI file.
- */
- MouseSettings *ReadMouseSettings(CINIFile *ini, const char *section, int mseNum);
+ /*
+ * Loads mouse settings from a config object for the given mouse number, or common settings if ANY_MOUSE specified.
+ * Returns NULL if no relevant settings were found in the config object.
+ */
+ MouseSettings *LoadMouseSettings(const Util::Config::Node &config, int mseNum);
+ MouseSettings *ReadMouseSettings(CINIFile *ini, const char *section, int mseNum);
- /*
- * Writes the given mouse settings to an INI file, only writing out settings that are different to their defaults.
- */
- void WriteMouseSettings(CINIFile *ini, const char *section, MouseSettings *settings);
-
- /*
- * Prints the given joystick settings to stdout.
- */
- void PrintJoySettings(int joyNum, JoySettings *settings);
+ /*
+ * Stores the given mouse settings to a config object, only storing settings that differ from their defaults.
+ */
+ void StoreMouseSettings(Util::Config::Node *config, MouseSettings *settings);
+ void WriteMouseSettings(CINIFile *ini, const char *section, MouseSettings *settings);
+
+ /*
+ * Prints the given joystick settings to stdout.
+ */
+ void PrintJoySettings(int joyNum, JoySettings *settings);
- /*
- * Reads joystick settings from an INI file for the given joystick number, or common settings if ANY_JOYSTICK specified.
- * Returns NULL if no relevant settings were found in the INI file.
- */
- JoySettings *ReadJoySettings(CINIFile *ini, const char *section, int joyNum);
+ /*
+ * Loads joystick settings from a config object for the given joystick number, or common settings if ANY_JOYSTICK specified.
+ * Returns NULL if no relevant settings were found in the config object.
+ */
+ JoySettings *LoadJoySettings(const Util::Config::Node &config, int joyNum);
+ JoySettings *ReadJoySettings(CINIFile *ini, const char *section, int joyNum);
- /*
- * Writes the given joystick settings to an INI file, only writing out settings that are different to their defaults.
- */
- void WriteJoySettings(CINIFile *ini, const char *section, JoySettings *settings);
+ /*
+ * Stores the given joystick settings to a config object, only storing settings that differ from their defaults.
+ */
+ void StoreJoySettings(Util::Config::Node *config, JoySettings *settings);
+ void WriteJoySettings(CINIFile *ini, const char *section, JoySettings *settings);
protected:
- // Current display geometry
- unsigned m_dispX;
- unsigned m_dispY;
- unsigned m_dispW;
- unsigned m_dispH;
+ // Current display geometry
+ unsigned m_dispX;
+ unsigned m_dispY;
+ unsigned m_dispW;
+ unsigned m_dispH;
- // Flag to indicate if system has grabbed mouse
- bool m_grabMouse;
+ // Flag to indicate if system has grabbed mouse
+ bool m_grabMouse;
- /*
- * Constructs an input system with the given name.
- */
- CInputSystem(const char *systemName);
+ /*
+ * Constructs an input system with the given name.
+ */
+ CInputSystem(const char *systemName);
- /*
- * Returns true if the given EMousePart is an axis.
- */
- bool IsAxis(EMousePart msePart);
+ /*
+ * Returns true if the given EMousePart is an axis.
+ */
+ bool IsAxis(EMousePart msePart);
- /*
- * Returns true if the given EMousePart represents a full axis, eg MouseXAxis or MouseXAxisInv.
- */
- bool IsFullAxis(EMousePart msePart);
+ /*
+ * Returns true if the given EMousePart represents a full axis, eg MouseXAxis or MouseXAxisInv.
+ */
+ bool IsFullAxis(EMousePart msePart);
- /*
- * Returns true if the EMousePart represents an axis and sets axisPart and axisDir as follows:
- * axisNum will be the axis number (AXIS_X, AXIS_Y or AXIS_Z)
- * axisDir will be AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS depending on whether the axis has the full range, has
- * the full range but inverted, is negative only, or is positive only.
- */
- bool GetAxisDetails(EMousePart msePart, int &axisNum, int &axisDir);
+ /*
+ * Returns true if the EMousePart represents an axis and sets axisPart and axisDir as follows:
+ * axisNum will be the axis number (AXIS_X, AXIS_Y or AXIS_Z)
+ * axisDir will be AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS depending on whether the axis has the full range, has
+ * the full range but inverted, is negative only, or is positive only.
+ */
+ bool GetAxisDetails(EMousePart msePart, int &axisNum, int &axisDir);
- /*
- * Returns true if the given EMousePart represets a button, eg MouseButtonLeft.
- */
- bool IsButton(EMousePart msePart);
+ /*
+ * Returns true if the given EMousePart represets a button, eg MouseButtonLeft.
+ */
+ bool IsButton(EMousePart msePart);
- /*
- * Returns the button number (indexed from 0) of the given EMousePart if it is a button, or -1 otherwise.
- */
- int GetButtonNumber(EMousePart msePart);
+ /*
+ * Returns the button number (indexed from 0) of the given EMousePart if it is a button, or -1 otherwise.
+ */
+ int GetButtonNumber(EMousePart msePart);
- /*
- * Returns the EMousePart that represents the axis component for the given axis number (AXIS_X, AXIS_Y or AXIS_Z) and direction
- * (AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS), or MouseUnknown otherwise.
- */
- EMousePart GetMouseAxis(int axisNum, int axisDir);
+ /*
+ * Returns the EMousePart that represents the axis component for the given axis number (AXIS_X, AXIS_Y or AXIS_Z) and direction
+ * (AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS), or MouseUnknown otherwise.
+ */
+ EMousePart GetMouseAxis(int axisNum, int axisDir);
- /*
- * Returns the EMousePart that represents the mouse button with the given number (0-4), or MouseUnknown otherwise.
- */
- EMousePart GetMouseButton(int butNum);
+ /*
+ * Returns the EMousePart that represents the mouse button with the given number (0-4), or MouseUnknown otherwise.
+ */
+ EMousePart GetMouseButton(int butNum);
- /*
- * Returns true if the given EJoyPart is an axis.
- */
- bool IsAxis(EJoyPart joyPart);
+ /*
+ * Returns true if the given EJoyPart is an axis.
+ */
+ bool IsAxis(EJoyPart joyPart);
- /*
- * Returns true if the given EJoyPart represents a full axis, eg JoyXAxis.
- */
- bool IsFullAxis(EJoyPart joyPart);
+ /*
+ * Returns true if the given EJoyPart represents a full axis, eg JoyXAxis.
+ */
+ bool IsFullAxis(EJoyPart joyPart);
- /*
- * Returns true if the given EJoyPart represents a slider axis, eg JoyS1Axis.
- */
- bool IsSliderAxis(EJoyPart joyPart);
+ /*
+ * Returns true if the given EJoyPart represents a slider axis, eg JoyS1Axis.
+ */
+ bool IsSliderAxis(EJoyPart joyPart);
- /*
- * Returns true if joystick part represents an axis and sets axisPart and axisDir as follows:
- * axisNum will be the axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ)
- * axisDir is AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS depending on whether the axis has the full range, has
- * the full range but inverted, is negative only, or is positive only.
- */
- bool GetAxisDetails(EJoyPart joyPart, int &axisNum, int &axisDir);
+ /*
+ * Returns true if joystick part represents an axis and sets axisPart and axisDir as follows:
+ * axisNum will be the axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ)
+ * axisDir is AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS depending on whether the axis has the full range, has
+ * the full range but inverted, is negative only, or is positive only.
+ */
+ bool GetAxisDetails(EJoyPart joyPart, int &axisNum, int &axisDir);
- /*
- * Returns true if the given EJoyPart represents a POV hat direction, eg JoyPOV0Left.
- */
- bool IsPOV(EJoyPart joyPart);
+ /*
+ * Returns true if the given EJoyPart represents a POV hat direction, eg JoyPOV0Left.
+ */
+ bool IsPOV(EJoyPart joyPart);
- /*
- * Returns true if the EJoyPart represents a POV hat direction and sets povNum and povDir as follows:
- * povNum will be the POV hat number 0-4,
- * povDir will be POV_UP, POV_DOWN, POV_LEFT or POV_RIGHT.
- */
- bool GetPOVDetails(EJoyPart joyPart, int &povNum, int &povDir);
+ /*
+ * Returns true if the EJoyPart represents a POV hat direction and sets povNum and povDir as follows:
+ * povNum will be the POV hat number 0-4,
+ * povDir will be POV_UP, POV_DOWN, POV_LEFT or POV_RIGHT.
+ */
+ bool GetPOVDetails(EJoyPart joyPart, int &povNum, int &povDir);
- /*
- * Returns true if the given EJoyPart is a button
- */
- bool IsButton(EJoyPart joyPart);
+ /*
+ * Returns true if the given EJoyPart is a button
+ */
+ bool IsButton(EJoyPart joyPart);
- /*
- * Returns the button number (indexed from 0) of the given EJoyPart if it is a button, or -1 otherwise.
- */
- int GetButtonNumber(EJoyPart joyPart);
+ /*
+ * Returns the button number (indexed from 0) of the given EJoyPart if it is a button, or -1 otherwise.
+ */
+ int GetButtonNumber(EJoyPart joyPart);
- /*
- * Returns the EJoyPart that represents the axis component for the given axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ) and
- * direction (AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS), or JoyUnknown otherwise.
- */
- EJoyPart GetJoyAxis(int axisNum, int axisDir);
+ /*
+ * Returns the EJoyPart that represents the axis component for the given axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ) and
+ * direction (AXIS_FULL, AXIS_INVERTED, AXIS_POS or AXIS_POS), or JoyUnknown otherwise.
+ */
+ EJoyPart GetJoyAxis(int axisNum, int axisDir);
- /*
- * Returns the EJoyPart that represents the POV hot direction for the given POV number (0-4) and direction (POV_UP, POV_DOWN,
- * POV_LEFT or POV_RIGHT), JoyUnknown otherwise.
- */
- EJoyPart GetJoyPOV(int povNum, int povDir);
+ /*
+ * Returns the EJoyPart that represents the POV hot direction for the given POV number (0-4) and direction (POV_UP, POV_DOWN,
+ * POV_LEFT or POV_RIGHT), JoyUnknown otherwise.
+ */
+ EJoyPart GetJoyPOV(int povNum, int povDir);
- /*
- * Returns the EJoyPart that represents the joystick button with the given number (0-31), or JoyUnknown otherwise.
- */
- EJoyPart GetJoyButton(int butNum);
+ /*
+ * Returns the EJoyPart that represents the joystick button with the given number (0-31), or JoyUnknown otherwise.
+ */
+ EJoyPart GetJoyButton(int butNum);
- //
- // Abstract methods subclass must implement (ie system-specific code)
- //
+ //
+ // Abstract methods subclass must implement (ie system-specific code)
+ //
- virtual bool InitializeSystem() = 0;
+ virtual bool InitializeSystem() = 0;
- /*
- * Returns the system-specific key index that represents the given key name.
- */
- virtual int GetKeyIndex(const char *keyName) = 0;
+ /*
+ * Returns the system-specific key index that represents the given key name.
+ */
+ virtual int GetKeyIndex(const char *keyName) = 0;
- /*
- * Returns the key name of the given system-specific integer key index.
- */
- virtual const char *GetKeyName(int keyIndex) = 0;
+ /*
+ * Returns the key name of the given system-specific integer key index.
+ */
+ virtual const char *GetKeyName(int keyIndex) = 0;
- /*
- * Returns true if for the given keyboard the key with the system-specific key index is currently pressed.
- */
- virtual bool IsKeyPressed(int kbdNum, int keyIndex) = 0;
+ /*
+ * Returns true if for the given keyboard the key with the system-specific key index is currently pressed.
+ */
+ virtual bool IsKeyPressed(int kbdNum, int keyIndex) = 0;
- /*
- * Returns the current axis value for the given mouse and axis number (AXIS_X, AXIS_Y or AXIS_Z).
- */
- virtual int GetMouseAxisValue(int mseNum, int axisNum) = 0;
+ /*
+ * Returns the current axis value for the given mouse and axis number (AXIS_X, AXIS_Y or AXIS_Z).
+ */
+ virtual int GetMouseAxisValue(int mseNum, int axisNum) = 0;
- /*
- * Returns the current direction (-1, 0 or 1) the Z-axis (wheel) is moving in for the given mouse.
- */
- virtual int GetMouseWheelDir(int mseNum) = 0;
+ /*
+ * Returns the current direction (-1, 0 or 1) the Z-axis (wheel) is moving in for the given mouse.
+ */
+ virtual int GetMouseWheelDir(int mseNum) = 0;
- /*
- * Returns true if for the given mouse the button with the given number is currently pressed.
- */
- virtual bool IsMouseButPressed(int mseNum, int butNum) = 0;
+ /*
+ * Returns true if for the given mouse the button with the given number is currently pressed.
+ */
+ virtual bool IsMouseButPressed(int mseNum, int butNum) = 0;
- /*
- * Returns the current axis value for the given joystick and axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ).
- */
- virtual int GetJoyAxisValue(int joyNum, int axisNum) = 0;
+ /*
+ * Returns the current axis value for the given joystick and axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ).
+ */
+ virtual int GetJoyAxisValue(int joyNum, int axisNum) = 0;
- /*
- * Returns true if for the given joystick the POV-hat controller with the given number is pointing in a particular direction (POV_UP, POV_DOWN,
- * POV_LEFT or POV_RIGHT)
- */
- virtual bool IsJoyPOVInDir(int joyNum, int povNum, int povDir) = 0;
+ /*
+ * Returns true if for the given joystick the POV-hat controller with the given number is pointing in a particular direction (POV_UP, POV_DOWN,
+ * POV_LEFT or POV_RIGHT)
+ */
+ virtual bool IsJoyPOVInDir(int joyNum, int povNum, int povDir) = 0;
- /*
- * Returns true if for the given joystick the button with the given number is currently pressed.
- */
- virtual bool IsJoyButPressed(int joyNum, int butNum) = 0;
+ /*
+ * Returns true if for the given joystick the button with the given number is currently pressed.
+ */
+ virtual bool IsJoyButPressed(int joyNum, int butNum) = 0;
- /*
- * Processes the given force feedback command for the given joystick and axis number.
- */
- virtual bool ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd) = 0;
+ /*
+ * Processes the given force feedback command for the given joystick and axis number.
+ */
+ virtual bool ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd) = 0;
- //
- // Virtual methods subclass can override if required
- //
+ //
+ // Virtual methods subclass can override if required
+ //
- /*
- * Returns true if the mouse is currently centered in the display during configuration.
- */
- virtual bool ConfigMouseCentered();
+ /*
+ * Returns true if the mouse is currently centered in the display during configuration.
+ */
+ virtual bool ConfigMouseCentered();
- /*
- * Creates an input source combining all keyboards for the given key index.
- */
- virtual CInputSource *CreateAnyKeySource(int keyIndex);
+ /*
+ * Creates an input source combining all keyboards for the given key index.
+ */
+ virtual CInputSource *CreateAnyKeySource(int keyIndex);
- /*
- * Creates an input source combining all mice for the given EMousePart.
- */
- virtual CInputSource *CreateAnyMouseSource(EMousePart msePart);
+ /*
+ * Creates an input source combining all mice for the given EMousePart.
+ */
+ virtual CInputSource *CreateAnyMouseSource(EMousePart msePart);
- /*
- * Creates an input source combining all joysticks for the given EJoyPart.
- */
- virtual CInputSource *CreateAnyJoySource(EJoyPart joyPart);
-
- /*
- * Creates an input source for the given keyboard number and key index.
- */
- virtual CInputSource *CreateKeySource(int kbdNum, int keyIndex);
+ /*
+ * Creates an input source combining all joysticks for the given EJoyPart.
+ */
+ virtual CInputSource *CreateAnyJoySource(EJoyPart joyPart);
+
+ /*
+ * Creates an input source for the given keyboard number and key index.
+ */
+ virtual CInputSource *CreateKeySource(int kbdNum, int keyIndex);
- /*
- * Creates an input source for the given mouse number and EMousePart.
- */
- virtual CInputSource *CreateMouseSource(int mseNum, EMousePart msePart);
+ /*
+ * Creates an input source for the given mouse number and EMousePart.
+ */
+ virtual CInputSource *CreateMouseSource(int mseNum, EMousePart msePart);
- /*
- * Creates an input source for the given joystick number and EJoyPart.
- */
- virtual CInputSource *CreateJoySource(int joyNum, EJoyPart joyPart);
+ /*
+ * Creates an input source for the given joystick number and EJoyPart.
+ */
+ virtual CInputSource *CreateJoySource(int joyNum, EJoyPart joyPart);
public:
#ifdef DEBUG
- static unsigned totalSrcsAcquired;
- static unsigned totalSrcsReleased;
+ static unsigned totalSrcsAcquired;
+ static unsigned totalSrcsReleased;
#endif
- static const char *GetDefaultAxisName(int axisNum);
+ static const char *GetDefaultAxisName(int axisNum);
- // Name of this input system
- const char *name;
+ // Name of this input system
+ const char *name;
- virtual ~CInputSystem();
+ virtual ~CInputSystem();
- /*
- * Initializes the input system. Must be called before any other methods are used.
- * Returns false if unable to initialize the system.
- */
- bool Initialize();
+ /*
+ * Initializes the input system. Must be called before any other methods are used.
+ * Returns false if unable to initialize the system.
+ */
+ bool Initialize();
- /*
- * Sets the current display geometry so that mouse movements can be scaled properly.
- */
- void SetDisplayGeom(unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH);
+ /*
+ * Sets the current display geometry so that mouse movements can be scaled properly.
+ */
+ void SetDisplayGeom(unsigned dispX, unsigned dispY, unsigned dispW, unsigned dispH);
- /*
- * Returns the number of attached keyboards (or 0 if the system cannot handle keyboards at all or ANY_KEYBOARD if the system cannot
- * handle multiple keyboards).
- */
- virtual int GetNumKeyboards() = 0;
-
- /*
- * Returns the number of attached mice (or 0 if the system cannot handle mice at all or ANY_MOUSE if the system cannot handle
- * multiple mice).
- */
- virtual int GetNumMice() = 0;
-
- /*
- * Returns number of attached joysticks (or 0 if the system cannot handle joysticks at all or ANY_JOYSTICK if the system cannot
- * handle multiple joysticks).
- */
- virtual int GetNumJoysticks() = 0;
+ /*
+ * Returns the number of attached keyboards (or 0 if the system cannot handle keyboards at all or ANY_KEYBOARD if the system cannot
+ * handle multiple keyboards).
+ */
+ virtual int GetNumKeyboards() = 0;
+
+ /*
+ * Returns the number of attached mice (or 0 if the system cannot handle mice at all or ANY_MOUSE if the system cannot handle
+ * multiple mice).
+ */
+ virtual int GetNumMice() = 0;
+
+ /*
+ * Returns number of attached joysticks (or 0 if the system cannot handle joysticks at all or ANY_JOYSTICK if the system cannot
+ * handle multiple joysticks).
+ */
+ virtual int GetNumJoysticks() = 0;
- /*
- * Returns details about the keyboard with the given number, or NULL if it does not exist.
- */
- virtual const KeyDetails *GetKeyDetails(int kbdNum) = 0;
+ /*
+ * Returns details about the keyboard with the given number, or NULL if it does not exist.
+ */
+ virtual const KeyDetails *GetKeyDetails(int kbdNum) = 0;
- /*
- * Returns details about the mouse with the given number, or NULL if it does not exist.
- */
- virtual const MouseDetails *GetMouseDetails(int mseNum) = 0;
+ /*
+ * Returns details about the mouse with the given number, or NULL if it does not exist.
+ */
+ virtual const MouseDetails *GetMouseDetails(int mseNum) = 0;
- /*
- * Returns details about the joystick with the given number, or NULL if it does not exist.
- */
- virtual const JoyDetails *GetJoyDetails(int joyNum) = 0;
+ /*
+ * Returns details about the joystick with the given number, or NULL if it does not exist.
+ */
+ virtual const JoyDetails *GetJoyDetails(int joyNum) = 0;
- /*
- * Clears all keyboard, mouse and joystick settings.
+ /*
+ * Clears all keyboard, mouse and joystick settings.
*/
- void ClearSettings();
+ void ClearSettings();
- /*
- * Prints current keyboard, mouse and joystick settings to stdout.
- */
- void PrintSettings();
+ /*
+ * Prints current keyboard, mouse and joystick settings to stdout.
+ */
+ void PrintSettings();
- /*
- * Reads all keyboard, mouse and joystick settings (and any additional system-specific additional settings) from the given INI file.
- */
- virtual void ReadFromINIFile(CINIFile *ini, const char *section);
+ /*
+ * Reads all keyboard, mouse and joystick settings (and any additional system-specific additional settings) from the given config object.
+ */
+ virtual void LoadFromConfig(const Util::Config::Node &config);
+ virtual void ReadFromINIFile(CINIFile *ini, const char *section);
- /*
- * Writes all keyboard, mouse and joystick settings (and any additional system-specific settings) to the given INI file.
- */
- virtual void WriteToINIFile(CINIFile *ini, const char *section);
+ /*
+ * Stores all keyboard, mouse and joystick settings (and any additional system-specific settings) to the given config object.
+ */
+ virtual void StoreToConfig(Util::Config::Node *config);
+ virtual void WriteToINIFile(CINIFile *ini, const char *section);
- /*
- * Returns the current key settings for given keyboard number, or common settings if ANY_KEYBOARD specified.
- * If no settings are found and useDefault is false, NULL is returned. If useDefault is true then default settings are returned.
- */
- KeySettings *GetKeySettings(int kbdNum, bool useDefault);
+ /*
+ * Returns the current key settings for given keyboard number, or common settings if ANY_KEYBOARD specified.
+ * If no settings are found and useDefault is false, NULL is returned. If useDefault is true then default settings are returned.
+ */
+ KeySettings *GetKeySettings(int kbdNum, bool useDefault);
- /*
- * Returns the current mouse settings for given mouse number, or common settings if ANY_MOUSE specified.
- * If no settings are found and useDefault is false, NULL is returned. If useDefault is true then default settings are returned.
- */
- MouseSettings *GetMouseSettings(int mseNum, bool useDefault);
+ /*
+ * Returns the current mouse settings for given mouse number, or common settings if ANY_MOUSE specified.
+ * If no settings are found and useDefault is false, NULL is returned. If useDefault is true then default settings are returned.
+ */
+ MouseSettings *GetMouseSettings(int mseNum, bool useDefault);
- /*
- * Returns the current joystick settings for given joystick number, or common settings if ANY_JOYSTICK specified.
- * If no settings are found and useDefault is false, NULL is returned. If useDefault is true then default settings are returned.
- */
- JoySettings *GetJoySettings(int joyNum, bool useDefault);
-
- /*
- * Returns the input source for the given mapping, or NULL if mapping is not valid.
- */
- CInputSource* ParseSource(const char *mapping, bool fullAxisOnly = false);
+ /*
+ * Returns the current joystick settings for given joystick number, or common settings if ANY_JOYSTICK specified.
+ * If no settings are found and useDefault is false, NULL is returned. If useDefault is true then default settings are returned.
+ */
+ JoySettings *GetJoySettings(int joyNum, bool useDefault);
+
+ /*
+ * Returns the input source for the given mapping, or NULL if mapping is not valid.
+ */
+ CInputSource* ParseSource(const char *mapping, bool fullAxisOnly = false);
- /*
- * Waits for any input from the user and once received copies a mapping configuration representing the input (eg KEY_A or JOY1_AXIS_POS)
- * into the given buffer.
- * Returns true if input was successfully received or false if the user activated the given escape mapping or closed the window.
- * readFlags specifies which types of inputs (keyboards, mice, joysticks) are to be read and whether to merge the inputs to a common
- * mapping, eg return MOUSE_XAXIS rather than MOUSE3_XAXIS.
- * If fullAxisOnly is true, then only mappings representing a full axis are returned, eg JOY1_XAXIS is allowed but not JOY1_XAXIS_POS.
- */
- bool ReadMapping(char *buffer, unsigned bufSize, bool fullAxisOnly = false, unsigned readFlags = READ_ALL, const char *escapeMapping = "KEY_ESCAPE");
+ /*
+ * Waits for any input from the user and once received copies a mapping configuration representing the input (eg KEY_A or JOY1_AXIS_POS)
+ * into the given buffer.
+ * Returns true if input was successfully received or false if the user activated the given escape mapping or closed the window.
+ * readFlags specifies which types of inputs (keyboards, mice, joysticks) are to be read and whether to merge the inputs to a common
+ * mapping, eg return MOUSE_XAXIS rather than MOUSE3_XAXIS.
+ * If fullAxisOnly is true, then only mappings representing a full axis are returned, eg JOY1_XAXIS is allowed but not JOY1_XAXIS_POS.
+ */
+ bool ReadMapping(char *buffer, unsigned bufSize, bool fullAxisOnly = false, unsigned readFlags = READ_ALL, const char *escapeMapping = "KEY_ESCAPE");
- /*
- * Updates the current state of the input system (called by CInputs.Poll).
- */
- virtual bool Poll() = 0;
+ /*
+ * Updates the current state of the input system (called by CInputs.Poll).
+ */
+ virtual bool Poll() = 0;
- virtual void GrabMouse();
+ virtual void GrabMouse();
- virtual void UngrabMouse();
+ virtual void UngrabMouse();
- /*
- * Sets the mouse visibility (some systems may choose to ignore this).
- */
- virtual void SetMouseVisibility(bool visible) = 0;
+ /*
+ * Sets the mouse visibility (some systems may choose to ignore this).
+ */
+ virtual void SetMouseVisibility(bool visible) = 0;
- virtual bool SendForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd);
+ virtual bool SendForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd);
- bool DetectJoystickAxis(unsigned joyNum, unsigned &axisNum, const char *escapeMapping = "KEY_ESCAPE", const char *confirmMapping = "KEY_RETURN");
+ bool DetectJoystickAxis(unsigned joyNum, unsigned &axisNum, const char *escapeMapping = "KEY_ESCAPE", const char *confirmMapping = "KEY_RETURN");
- bool CalibrateJoystickAxis(unsigned joyNum, unsigned axisNum, const char *escapeMapping = "KEY_ESCAPE", const char *confirmMapping = "KEY_RETURN");
+ bool CalibrateJoystickAxis(unsigned joyNum, unsigned axisNum, const char *escapeMapping = "KEY_ESCAPE", const char *confirmMapping = "KEY_RETURN");
- void PrintDevices();
+ void PrintDevices();
- //
- // Nested Classes
- //
+ //
+ // Nested Classes
+ //
- /*
- * Input source for a key on a keyboard.
- */
- class CKeyInputSource : public CInputSource
- {
- private:
- CInputSystem *m_system; // Parent input system
- int m_kbdNum; // Keyboard number
- int m_keyIndex; // Key index
- int m_incr; // Key increment for analog values
- int m_decr; // Key decrement for analog values
- int m_val; // Current analog key value
- int m_maxVal; // Maximum analog key value
+ /*
+ * Input source for a key on a keyboard.
+ */
+ class CKeyInputSource : public CInputSource
+ {
+ private:
+ CInputSystem *m_system; // Parent input system
+ int m_kbdNum; // Keyboard number
+ int m_keyIndex; // Key index
+ int m_incr; // Key increment for analog values
+ int m_decr; // Key decrement for analog values
+ int m_val; // Current analog key value
+ int m_maxVal; // Maximum analog key value
- public:
- CKeyInputSource(CInputSystem *system, int kbdNum, int keyIndex, unsigned sensitivity, unsigned decaySpeed);
+ public:
+ CKeyInputSource(CInputSystem *system, int kbdNum, int keyIndex, unsigned sensitivity, unsigned decaySpeed);
- bool GetValueAsSwitch(bool &val);
+ bool GetValueAsSwitch(bool &val);
- bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
- };
+ bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
+ };
- /*
- * Input source for the X- or Y-axis of a mouse.
- */
- class CMseAxisInputSource : public CInputSource
- {
- private:
- CInputSystem *m_system; // Parent input system
- int m_mseNum; // Mouse number
- int m_axisNum; // Axis number (AXIS_X, AXIS_Y or AXIS_Z)
- int m_axisDir; // Axis direction (AXIS_FULL, AXIS_INVERTED, AXIS_POSITIVE or AXIS_NEGATIVE)
- int m_deadPixels; // Size in pixels of dead zone in centre of axis
+ /*
+ * Input source for the X- or Y-axis of a mouse.
+ */
+ class CMseAxisInputSource : public CInputSource
+ {
+ private:
+ CInputSystem *m_system; // Parent input system
+ int m_mseNum; // Mouse number
+ int m_axisNum; // Axis number (AXIS_X, AXIS_Y or AXIS_Z)
+ int m_axisDir; // Axis direction (AXIS_FULL, AXIS_INVERTED, AXIS_POSITIVE or AXIS_NEGATIVE)
+ int m_deadPixels; // Size in pixels of dead zone in centre of axis
- /*
- * Scales the mouse axis value to the given range.
- */
- int ScaleAxisValue(int minVal, int offVal, int maxVal);
+ /*
+ * Scales the mouse axis value to the given range.
+ */
+ int ScaleAxisValue(int minVal, int offVal, int maxVal);
- public:
- CMseAxisInputSource(CInputSystem *system, int mseNum, int axisNum, int axisDir, unsigned deadZone);
+ public:
+ CMseAxisInputSource(CInputSystem *system, int mseNum, int axisNum, int axisDir, unsigned deadZone);
- bool GetValueAsSwitch(bool &val);
+ bool GetValueAsSwitch(bool &val);
- bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
- };
+ bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
+ };
- /*
- * Input source for the button of a mouse.
- */
- class CMseButInputSource : public CInputSource
- {
- private:
- CInputSystem *m_system; // Parent input system
- int m_mseNum; // Mouse number
- int m_butNum; // Button number
+ /*
+ * Input source for the button of a mouse.
+ */
+ class CMseButInputSource : public CInputSource
+ {
+ private:
+ CInputSystem *m_system; // Parent input system
+ int m_mseNum; // Mouse number
+ int m_butNum; // Button number
- public:
- CMseButInputSource(CInputSystem *system, int mseNum, int butNum);
+ public:
+ CMseButInputSource(CInputSystem *system, int mseNum, int butNum);
- bool GetValueAsSwitch(bool &val);
+ bool GetValueAsSwitch(bool &val);
- bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
- };
+ bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
+ };
- /*
- * Input source for the axis of a joystick.
- */
- class CJoyAxisInputSource : public CInputSource
- {
- private:
- CInputSystem *m_system; // Parent input system
- int m_joyNum; // Joystick number
- int m_axisNum; // Axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ)
- int m_axisDir; // Axis direction (AXIS_FULL, AXIS_INVERTED, AXIS_POSITIVE or AXIS_NEGATIVE)
- int m_axisMinVal; // Axis min raw value (default -32768)
- int m_axisOffVal; // Axis center/off raw value (default 0)
- int m_axisMaxVal; // Axis max raw value (default 32767)
- bool m_axisInverted; // True if axis max raw value less than axis min raw value
- int m_posDZone; // Dead zone for positive range (0-99%)
- int m_negDZone; // Dead zone for negative range (0-99%)
- int m_posSat; // Saturation for positive range (1-100%)
- int m_negSat; // Saturation for negative range (1-100%)
+ /*
+ * Input source for the axis of a joystick.
+ */
+ class CJoyAxisInputSource : public CInputSource
+ {
+ private:
+ CInputSystem *m_system; // Parent input system
+ int m_joyNum; // Joystick number
+ int m_axisNum; // Axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ)
+ int m_axisDir; // Axis direction (AXIS_FULL, AXIS_INVERTED, AXIS_POSITIVE or AXIS_NEGATIVE)
+ int m_axisMinVal; // Axis min raw value (default -32768)
+ int m_axisOffVal; // Axis center/off raw value (default 0)
+ int m_axisMaxVal; // Axis max raw value (default 32767)
+ bool m_axisInverted; // True if axis max raw value less than axis min raw value
+ int m_posDZone; // Dead zone for positive range (0-99%)
+ int m_negDZone; // Dead zone for negative range (0-99%)
+ int m_posSat; // Saturation for positive range (1-100%)
+ int m_negSat; // Saturation for negative range (1-100%)
- /*
- * Scales the joystick axis value to the given range.
- */
- int ScaleAxisValue(int minVal, int offVal, int maxVal);
+ /*
+ * Scales the joystick axis value to the given range.
+ */
+ int ScaleAxisValue(int minVal, int offVal, int maxVal);
- public:
- CJoyAxisInputSource(CInputSystem *system, int joyNum, int axisNum, int axisDir, int axisMinVal, int axisOffVal, int axisMaxVal,
- unsigned deadZone, unsigned saturation);
+ public:
+ CJoyAxisInputSource(CInputSystem *system, int joyNum, int axisNum, int axisDir, int axisMinVal, int axisOffVal, int axisMaxVal,
+ unsigned deadZone, unsigned saturation);
- bool GetValueAsSwitch(bool &val);
+ bool GetValueAsSwitch(bool &val);
- bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
+ bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
- bool SendForceFeedbackCmd(ForceFeedbackCmd ffCmd);
- };
+ bool SendForceFeedbackCmd(ForceFeedbackCmd ffCmd);
+ };
- /*
- * Input source for a particular direction of a POV hat controller of a joystick.
- */
- class CJoyPOVInputSource : public CInputSource
- {
- private:
- CInputSystem *m_system; // Parent input system
- int m_joyNum; // Joystick number
- int m_povNum; // POV hat number
- int m_povDir; // POV hat direction (POV_UP, POV_LEFT, POV_RIGHT, POV_DOWN)
+ /*
+ * Input source for a particular direction of a POV hat controller of a joystick.
+ */
+ class CJoyPOVInputSource : public CInputSource
+ {
+ private:
+ CInputSystem *m_system; // Parent input system
+ int m_joyNum; // Joystick number
+ int m_povNum; // POV hat number
+ int m_povDir; // POV hat direction (POV_UP, POV_LEFT, POV_RIGHT, POV_DOWN)
- public:
- CJoyPOVInputSource(CInputSystem *system, int joyNum, int povNum, int povDir);
+ public:
+ CJoyPOVInputSource(CInputSystem *system, int joyNum, int povNum, int povDir);
- bool GetValueAsSwitch(bool &val);
+ bool GetValueAsSwitch(bool &val);
- bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
- };
+ bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
+ };
- /*
- * Input source for the button of a joystick.
- */
- class CJoyButInputSource : public CInputSource
- {
- private:
- CInputSystem *m_system; // Parent input system
- int m_joyNum; // Joystick number
- int m_butNum; // Button number
+ /*
+ * Input source for the button of a joystick.
+ */
+ class CJoyButInputSource : public CInputSource
+ {
+ private:
+ CInputSystem *m_system; // Parent input system
+ int m_joyNum; // Joystick number
+ int m_butNum; // Button number
- public:
- CJoyButInputSource(CInputSystem *system, int joyNum, int butNum);
+ public:
+ CJoyButInputSource(CInputSystem *system, int joyNum, int butNum);
- bool GetValueAsSwitch(bool &val);
+ bool GetValueAsSwitch(bool &val);
- bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
- };
+ bool GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal);
+ };
};
-#endif // INCLUDED_INPUTSYSTEM_H
+#endif // INCLUDED_INPUTSYSTEM_H
diff --git a/Src/Inputs/Inputs.cpp b/Src/Inputs/Inputs.cpp
index da3f1a1..1f57688 100644
--- a/Src/Inputs/Inputs.cpp
+++ b/Src/Inputs/Inputs.cpp
@@ -27,6 +27,7 @@
*/
#include "Supermodel.h"
+#include "Game.h"
#include
#include
@@ -34,240 +35,241 @@
#include
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::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::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::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::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
diff --git a/Src/Inputs/Inputs.h b/Src/Inputs/Inputs.h
index d0d90d4..938ebd3 100644
--- a/Src/Inputs/Inputs.h
+++ b/Src/Inputs/Inputs.h
@@ -29,6 +29,7 @@
#define INCLUDED_INPUTS_H
#include "Types.h"
+#include "Util/NewConfig.h"
#include
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
diff --git a/Src/Model3/DSB.cpp b/Src/Model3/DSB.cpp
index 002b229..322cce1 100644
--- a/Src/Model3/DSB.cpp
+++ b/Src/Model3/DSB.cpp
@@ -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();
+ soundVol = m_config["SoundVolume"].ValueAs();
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())
{
// 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())
{
// 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;
diff --git a/Src/Model3/DSB.h b/Src/Model3/DSB.h
index e8bc711..0addf51 100644
--- a/Src/Model3/DSB.h
+++ b/Src/Model3/DSB.h
@@ -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);
diff --git a/Src/Model3/DriveBoard.cpp b/Src/Model3/DriveBoard.cpp
index d293169..d05bce8 100644
--- a/Src/Model3/DriveBoard.cpp
+++ b/Src/Model3/DriveBoard.cpp
@@ -34,809 +34,822 @@
#include
#include
-#define RAM_SIZE 0x2000 // Z80 RAM
+#define RAM_SIZE 0x2000 // Z80 RAM
bool CDriveBoard::IsAttached(void)
{
- return m_attached && !m_tmpDisabled;
+ return m_attached && !m_tmpDisabled;
}
bool CDriveBoard::IsSimulated(void)
{
- return m_simulated;
+ return m_simulated;
}
void CDriveBoard::GetDIPSwitches(UINT8 &dip1, UINT8 &dip2)
{
- dip1 = m_dip1;
- dip2 = m_dip2;
+ dip1 = m_dip1;
+ dip2 = m_dip2;
}
void CDriveBoard::SetDIPSwitches(UINT8 dip1, UINT8 dip2)
{
- m_dip1 = dip1;
- m_dip2 = dip2;
+ m_dip1 = dip1;
+ m_dip2 = dip2;
}
unsigned CDriveBoard::GetSteeringStrength()
{
- return ((~(m_dip1>>2))&7) + 1;
+ return ((~(m_dip1>>2))&7) + 1;
}
void CDriveBoard::SetSteeringStrength(unsigned steeringStrength)
{
- m_dip1 = (m_dip1&0xE3) | (((~(steeringStrength - 1))&7)<<2);
+ m_dip1 = (m_dip1&0xE3) | (((~(steeringStrength - 1))&7)<<2);
}
void CDriveBoard::Get7SegDisplays(UINT8 &seg1Digit1, UINT8 &seg1Digit2, UINT8 &seg2Digit1, UINT8 &seg2Digit2)
{
- seg1Digit1 = m_seg1Digit1;
- seg1Digit2 = m_seg1Digit2;
- seg2Digit1 = m_seg2Digit1;
- seg2Digit2 = m_seg2Digit2;
+ seg1Digit1 = m_seg1Digit1;
+ seg1Digit2 = m_seg1Digit2;
+ seg2Digit1 = m_seg2Digit1;
+ seg2Digit2 = m_seg2Digit2;
}
CZ80 *CDriveBoard::GetZ80(void)
{
- return &m_z80;
+ return &m_z80;
}
void CDriveBoard::SaveState(CBlockFile *SaveState)
{
- SaveState->NewBlock("DriveBoard", __FILE__);
-
- // Check board is attached and not temporarily disabled
- bool attached = m_attached && !m_tmpDisabled;
- SaveState->Write(&attached, sizeof(attached));
- if (attached)
- {
- // Check if simulated
- SaveState->Write(&m_simulated, sizeof(m_simulated));
- if (m_simulated)
- {
- // TODO - save board simulation state
- }
- else
- {
- // Save DIP switches and digit displays
- SaveState->Write(&m_dip1, sizeof(m_dip1));
- SaveState->Write(&m_dip2, sizeof(m_dip2));
- //SaveState->Write(&m_seg1Digit1, sizeof(m_seg1Digit1)); // No point in saving these
- //SaveState->Write(&m_seg1Digit2, sizeof(m_seg1Digit2));
- //SaveState->Write(&m_seg2Digit1, sizeof(m_seg2Digit1));
- //SaveState->Write(&m_seg2Digit2, sizeof(m_seg2Digit2));
+ SaveState->NewBlock("DriveBoard", __FILE__);
+
+ // Check board is attached and not temporarily disabled
+ bool attached = m_attached && !m_tmpDisabled;
+ SaveState->Write(&attached, sizeof(attached));
+ if (attached)
+ {
+ // Check if simulated
+ SaveState->Write(&m_simulated, sizeof(m_simulated));
+ if (m_simulated)
+ {
+ // TODO - save board simulation state
+ }
+ else
+ {
+ // Save DIP switches and digit displays
+ SaveState->Write(&m_dip1, sizeof(m_dip1));
+ SaveState->Write(&m_dip2, sizeof(m_dip2));
+ //SaveState->Write(&m_seg1Digit1, sizeof(m_seg1Digit1)); // No point in saving these
+ //SaveState->Write(&m_seg1Digit2, sizeof(m_seg1Digit2));
+ //SaveState->Write(&m_seg2Digit1, sizeof(m_seg2Digit1));
+ //SaveState->Write(&m_seg2Digit2, sizeof(m_seg2Digit2));
- // Save RAM state
- SaveState->Write(m_ram, RAM_SIZE);
-
- // Save interrupt and input/output state
- SaveState->Write(&m_initialized, sizeof(m_initialized));
- SaveState->Write(&m_allowInterrupts, sizeof(m_allowInterrupts));
- SaveState->Write(&m_dataSent, sizeof(m_dataSent));
- SaveState->Write(&m_dataReceived, sizeof(m_dataReceived));
- SaveState->Write(&m_adcPortRead, sizeof(m_adcPortRead));
- SaveState->Write(&m_adcPortBit, sizeof(m_adcPortBit));
- SaveState->Write(&m_uncenterVal1, sizeof(m_uncenterVal1));
- SaveState->Write(&m_uncenterVal2, sizeof(m_uncenterVal2));
-
- // Save CPU state
- m_z80.SaveState(SaveState, "DriveBoard Z80");
- }
- }
+ // Save RAM state
+ SaveState->Write(m_ram, RAM_SIZE);
+
+ // Save interrupt and input/output state
+ SaveState->Write(&m_initialized, sizeof(m_initialized));
+ SaveState->Write(&m_allowInterrupts, sizeof(m_allowInterrupts));
+ SaveState->Write(&m_dataSent, sizeof(m_dataSent));
+ SaveState->Write(&m_dataReceived, sizeof(m_dataReceived));
+ SaveState->Write(&m_adcPortRead, sizeof(m_adcPortRead));
+ SaveState->Write(&m_adcPortBit, sizeof(m_adcPortBit));
+ SaveState->Write(&m_uncenterVal1, sizeof(m_uncenterVal1));
+ SaveState->Write(&m_uncenterVal2, sizeof(m_uncenterVal2));
+
+ // Save CPU state
+ m_z80.SaveState(SaveState, "DriveBoard Z80");
+ }
+ }
}
void CDriveBoard::LoadState(CBlockFile *SaveState)
{
- if (SaveState->FindBlock("DriveBoard") != OKAY)
- {
- ErrorLog("Unable to load drive board state. Save state file is corrupt.");
- return;
- }
-
- // Check that board was attached in saved state
- bool wasAttached;
- SaveState->Read(&wasAttached, sizeof(wasAttached));
- if (wasAttached)
- {
- // Check that board configuration exactly matches current configuration
- bool wasSimulated;
- SaveState->Read(&wasSimulated, sizeof(wasSimulated));
- if (wasAttached == m_attached && wasSimulated == m_simulated)
- {
- // Check if board was simulated
- if (wasSimulated)
- {
- // TODO - load board simulation state
- }
- else
- {
- // Load DIP switches and digit displays
- SaveState->Read(&m_dip1, sizeof(m_dip1));
- SaveState->Read(&m_dip2, sizeof(m_dip2));
- //SaveState->Read(&m_seg1Digit1, sizeof(m_seg1Digit1));
- //SaveState->Read(&m_seg1Digit2, sizeof(m_seg1Digit2));
- //SaveState->Read(&m_seg2Digit1, sizeof(m_seg2Digit1));
- //SaveState->Read(&m_seg2Digit2, sizeof(m_seg2Digit2));
+ if (SaveState->FindBlock("DriveBoard") != OKAY)
+ {
+ ErrorLog("Unable to load drive board state. Save state file is corrupt.");
+ return;
+ }
+
+ // Check that board was attached in saved state
+ bool wasAttached;
+ SaveState->Read(&wasAttached, sizeof(wasAttached));
+ if (wasAttached)
+ {
+ // Check that board configuration exactly matches current configuration
+ bool wasSimulated;
+ SaveState->Read(&wasSimulated, sizeof(wasSimulated));
+ if (wasAttached == m_attached && wasSimulated == m_simulated)
+ {
+ // Check if board was simulated
+ if (wasSimulated)
+ {
+ // TODO - load board simulation state
+ }
+ else
+ {
+ // Load DIP switches and digit displays
+ SaveState->Read(&m_dip1, sizeof(m_dip1));
+ SaveState->Read(&m_dip2, sizeof(m_dip2));
+ //SaveState->Read(&m_seg1Digit1, sizeof(m_seg1Digit1));
+ //SaveState->Read(&m_seg1Digit2, sizeof(m_seg1Digit2));
+ //SaveState->Read(&m_seg2Digit1, sizeof(m_seg2Digit1));
+ //SaveState->Read(&m_seg2Digit2, sizeof(m_seg2Digit2));
- // Load RAM state
- SaveState->Read(m_ram, RAM_SIZE);
-
- // Load interrupt and input/output state
- SaveState->Read(&m_initialized, sizeof(m_initialized));
- SaveState->Read(&m_allowInterrupts, sizeof(m_allowInterrupts));
- SaveState->Read(&m_dataSent, sizeof(m_dataSent));
- SaveState->Read(&m_dataReceived, sizeof(m_dataReceived));
- SaveState->Read(&m_adcPortRead, sizeof(m_adcPortRead));
- SaveState->Read(&m_adcPortBit, sizeof(m_adcPortBit));
- SaveState->Read(&m_uncenterVal1, sizeof(m_uncenterVal1));
- SaveState->Read(&m_uncenterVal2, sizeof(m_uncenterVal2));
-
- // Load CPU state
- m_z80.LoadState(SaveState, "DriveBoard Z80");
- }
+ // Load RAM state
+ SaveState->Read(m_ram, RAM_SIZE);
+
+ // Load interrupt and input/output state
+ SaveState->Read(&m_initialized, sizeof(m_initialized));
+ SaveState->Read(&m_allowInterrupts, sizeof(m_allowInterrupts));
+ SaveState->Read(&m_dataSent, sizeof(m_dataSent));
+ SaveState->Read(&m_dataReceived, sizeof(m_dataReceived));
+ SaveState->Read(&m_adcPortRead, sizeof(m_adcPortRead));
+ SaveState->Read(&m_adcPortBit, sizeof(m_adcPortBit));
+ SaveState->Read(&m_uncenterVal1, sizeof(m_uncenterVal1));
+ SaveState->Read(&m_uncenterVal2, sizeof(m_uncenterVal2));
+
+ // Load CPU state
+ m_z80.LoadState(SaveState, "DriveBoard Z80");
+ }
- // Enable board
- m_tmpDisabled = false;
- }
- else
- {
- // Otherwise, disable board as it can't be used with a mismatching configuratin
- m_tmpDisabled = true;
- }
- }
- else
- // Disable board if it was not attached
- m_tmpDisabled = true;
+ // Enable board
+ m_tmpDisabled = false;
+ }
+ else
+ {
+ // Otherwise, disable board as it can't be used with a mismatching configuratin
+ m_tmpDisabled = true;
+ }
+ }
+ else
+ // Disable board if it was not attached
+ m_tmpDisabled = true;
- if (m_attached)
- {
- if (m_tmpDisabled)
- printf("Disabled drive board due to incompatible save state.\n");
+ if (m_attached)
+ {
+ if (m_tmpDisabled)
+ printf("Disabled drive board due to incompatible save state.\n");
- SendStopAll();
- }
+ SendStopAll();
+ }
}
bool CDriveBoard::Init(const UINT8 *romPtr)
-{
- // Assign ROM (note that the ROM data has not yet been loaded)
- m_rom = romPtr;
+{
+ // Assign ROM (note that the ROM data has not yet been loaded)
+ m_rom = romPtr;
- // Check have a valid ROM
- m_attached = (m_rom != NULL);
- if (!m_attached)
- return OKAY;
+ // Check have a valid ROM
+ m_attached = (m_rom != NULL);
+ if (!m_attached)
+ return OKAY;
- // Allocate memory for RAM
- m_ram = new (std::nothrow) UINT8[RAM_SIZE];
- if (NULL == m_ram)
- {
- float ramSizeMB = (float)RAM_SIZE/(float)0x100000;
- return ErrorLog("Insufficient memoy for drive board (needs %1.1f MB).", ramSizeMB);
- }
- memset(m_ram, 0, RAM_SIZE);
+ // Allocate memory for RAM
+ m_ram = new (std::nothrow) UINT8[RAM_SIZE];
+ if (NULL == m_ram)
+ {
+ float ramSizeMB = (float)RAM_SIZE/(float)0x100000;
+ return ErrorLog("Insufficient memoy for drive board (needs %1.1f MB).", ramSizeMB);
+ }
+ memset(m_ram, 0, RAM_SIZE);
- // Initialize Z80
- m_z80.Init(this, NULL);
+ // Initialize Z80
+ m_z80.Init(this, NULL);
- return OKAY;
+ return OKAY;
}
void CDriveBoard::AttachInputs(CInputs *inputs, unsigned gameInputFlags)
{
- m_inputs = inputs;
- m_inputFlags = gameInputFlags;
+ m_inputs = inputs;
+ m_inputFlags = gameInputFlags;
- DebugLog("DriveBoard attached inputs\n");
+ DebugLog("DriveBoard attached inputs\n");
}
void CDriveBoard::AttachOutputs(COutputs *outputs)
{
- m_outputs = outputs;
+ m_outputs = outputs;
- DebugLog("DriveBoard attached outputs\n");
+ DebugLog("DriveBoard attached outputs\n");
}
void CDriveBoard::Reset(void)
{
- m_tmpDisabled = false;
+ m_tmpDisabled = false;
- m_initialized = false;
- m_allowInterrupts = false;
+ m_initialized = false;
+ m_allowInterrupts = false;
- m_seg1Digit1 = 0xFF;
- m_seg1Digit2 = 0xFF;
- m_seg2Digit1 = 0xFF;
- m_seg2Digit2 = 0xFF;
+ m_seg1Digit1 = 0xFF;
+ m_seg1Digit2 = 0xFF;
+ m_seg2Digit1 = 0xFF;
+ m_seg2Digit2 = 0xFF;
- m_dataSent = 0;
- m_dataReceived = 0;
- m_adcPortRead = 0;
- m_adcPortBit = 0;
- m_port42Out = 0;
- m_port46Out = 0;
- m_prev42Out = 0;
- m_prev46Out = 0;
+ m_dataSent = 0;
+ m_dataReceived = 0;
+ m_adcPortRead = 0;
+ m_adcPortBit = 0;
+ m_port42Out = 0;
+ m_port46Out = 0;
+ m_prev42Out = 0;
+ m_prev46Out = 0;
- m_initState = 0;
- m_boardMode = 0;
- m_readMode = 0;
- m_wheelCenter = 0x80;
- m_uncenterVal1 = 0;
- m_uncenterVal2 = 0;
+ m_initState = 0;
+ m_boardMode = 0;
+ m_readMode = 0;
+ m_wheelCenter = 0x80;
+ m_uncenterVal1 = 0;
+ m_uncenterVal2 = 0;
- m_lastConstForce = 0;
- m_lastSelfCenter = 0;
- m_lastFriction = 0;
- m_lastVibrate = 0;
+ m_lastConstForce = 0;
+ m_lastSelfCenter = 0;
+ m_lastFriction = 0;
+ m_lastVibrate = 0;
- // Configure options (cannot be done in Init() because command line settings weren't yet parsed)
- m_simulated = g_Config.simulateDrvBoard;
- SetSteeringStrength(g_Config.steeringStrength);
+ // Configure options (cannot be done in Init() because command line settings weren't yet parsed)
+ m_simulated = false; //TODO: make this run-time configurable when simulation mode is supported
+ SetSteeringStrength(m_config["SteeringStrength"].ValueAsDefault(5));
- m_z80.Reset(); // always reset to provide a valid Z80 state
-
- if (!g_Config.forceFeedback)
- m_attached = false;
+ m_z80.Reset(); // always reset to provide a valid Z80 state
+
+#ifdef SUPERMODEL_WIN32
+ if (!m_config["ForceFeedback"].ValueAsDefault(false))
+ m_attached = false;
+#else
+ m_attached = false;
+#endif
- // Stop any effects that may still be playing
- if (m_attached)
- SendStopAll();
+ // Stop any effects that may still be playing
+ if (m_attached)
+ SendStopAll();
}
UINT8 CDriveBoard::Read(void)
{
- // TODO - simulate initialization sequence even when emulating to get rid of long pause at boot up (drive board can
- // carry on booting whilst game starts)
- if (m_simulated)
- return SimulateRead();
- else
- return m_dataReceived;
+ // TODO - simulate initialization sequence even when emulating to get rid of long pause at boot up (drive board can
+ // carry on booting whilst game starts)
+ if (m_simulated)
+ return SimulateRead();
+ else
+ return m_dataReceived;
}
void CDriveBoard::Write(UINT8 data)
{
- //if (data >= 0x01 && data <= 0x0F ||
- // data >= 0x20 && data <= 0x2F ||
- // data >= 0x30 && data <= 0x3F ||
- // data >= 0x40 && data <= 0x4F ||
- // data >= 0x70 && data <= 0x7F)
- // printf("DriveBoard.Write(%02X)\n", data);
- if (m_simulated)
- SimulateWrite(data);
- else
- {
- m_dataSent = data;
- if (data == 0xCB)
- m_initialized = false;
- }
+ //if (data >= 0x01 && data <= 0x0F ||
+ // data >= 0x20 && data <= 0x2F ||
+ // data >= 0x30 && data <= 0x3F ||
+ // data >= 0x40 && data <= 0x4F ||
+ // data >= 0x70 && data <= 0x7F)
+ // printf("DriveBoard.Write(%02X)\n", data);
+ if (m_simulated)
+ SimulateWrite(data);
+ else
+ {
+ m_dataSent = data;
+ if (data == 0xCB)
+ m_initialized = false;
+ }
}
UINT8 CDriveBoard::SimulateRead(void)
{
- if (m_initialized)
- {
- switch (m_readMode)
- {
- case 0x0: return m_statusFlags; // Status flags
- case 0x1: return m_dip1; // DIP switch 1 value
- case 0x2: return m_dip2; // DIP switch 2 value
- case 0x3: return m_wheelCenter; // Wheel center
- case 0x4: return 0x80; // Cockpit banking center
- case 0x5: return m_inputs->steering->value; // Wheel position
- case 0x6: return 0x80; // Cockpit banking position
- case 0x7: return m_echoVal; // Init status/echo test
- default: return 0xFF;
- }
- }
- else
- {
- switch (m_initState / 5)
- {
- case 0: return 0xCF; // Initiate start
- case 1: return 0xCE;
- case 2: return 0xCD;
- case 3: return 0xCC; // Centering wheel
- default:
- m_initialized = true;
- return 0x80;
- }
- }
+ if (m_initialized)
+ {
+ switch (m_readMode)
+ {
+ case 0x0: return m_statusFlags; // Status flags
+ case 0x1: return m_dip1; // DIP switch 1 value
+ case 0x2: return m_dip2; // DIP switch 2 value
+ case 0x3: return m_wheelCenter; // Wheel center
+ case 0x4: return 0x80; // Cockpit banking center
+ case 0x5: return m_inputs->steering->value; // Wheel position
+ case 0x6: return 0x80; // Cockpit banking position
+ case 0x7: return m_echoVal; // Init status/echo test
+ default: return 0xFF;
+ }
+ }
+ else
+ {
+ switch (m_initState / 5)
+ {
+ case 0: return 0xCF; // Initiate start
+ case 1: return 0xCE;
+ case 2: return 0xCD;
+ case 3: return 0xCC; // Centering wheel
+ default:
+ m_initialized = true;
+ return 0x80;
+ }
+ }
}
void CDriveBoard::SimulateWrite(UINT8 cmd)
{
- // Following are commands for Scud Race. Daytona 2 has a compatible command set while Sega Rally 2 is completely different
- // TODO - finish for Scud Race and Daytona 2
- // TODO - implement for Sega Rally 2
- UINT8 type = cmd>>4;
- UINT8 val = cmd&0xF;
- switch (type)
- {
- case 0: // 0x00-0F Play sequence
- /* TODO */
- break;
- case 1: // 0x10-1F Set centering strength
- if (val == 0)
- // Disable auto-centering
- // TODO - is 0x10 for disable?
- SendSelfCenter(0);
- else
- // Enable auto-centering (0x1 = weakest, 0xF = strongest)
- SendSelfCenter(val * 0x11);
- break;
- case 2: // 0x20-2F Friction strength
- if (val == 0)
- // Disable friction
- // TODO - is 0x20 for disable?
- SendFriction(0);
- else
- // Enable friction (0x1 = weakest, 0xF = strongest)
- SendFriction(val * 0x11);
- break;
- case 3: // 0x30-3F Uncentering (vibrate)
- if (val == 0)
- // Disable uncentering
- SendVibrate(0);
- else
- // Enable uncentering (0x1 = weakest, 0xF = strongest)
- SendVibrate(val * 0x11);
- break;
- case 4: // 0x40-4F Play power-slide sequence
- /* TODO */
- break;
- case 5: // 0x50-5F Rotate wheel right
- SendConstantForce((val + 1) * 0x5);
- break;
- case 6: // 0x60-6F Rotate wheel left
- SendConstantForce(-(val + 1) * 0x5);
- break;
- case 7: // 0x70-7F Set steering parameters
- /* TODO */
- break;
- case 8: // 0x80-8F Test Mode
- switch (val&0x7)
- {
- case 0: SendStopAll(); break; // 0x80 Stop motor
- case 1: SendConstantForce(20); break; // 0x81 Roll wheel right
- case 2: SendConstantForce(-20); break; // 0x82 Roll wheel left
- case 3: /* Ignore - no clutch */ break; // 0x83 Clutch on
- case 4: /* Ignore - no clutch */ break; // 0x84 Clutch off
- case 5: m_wheelCenter = m_inputs->steering->value; break; // 0x85 Set wheel center position
- case 6: /* Ignore */ break; // 0x86 Set cockpit banking position
- case 7: /* Ignore */ break; // 0x87 Lamp on/off
- }
- case 0x9: // 0x90-9F ??? Don't appear to have any effect with Scud Race ROM
- /* TODO */
- break;
- case 0xA: // 0xA0-AF ??? Don't appear to have any effect with Scud Race ROM
- /* TODO */
- break;
- case 0xB: // 0xB0-BF Invalid command (reserved for use by PPC to send cabinet type 0xB0 or 0xB1 during initialization)
- /* Ignore */
- break;
- case 0xC: // 0xC0-CF Set board mode (0xCB = reset board)
- SendStopAll();
- if (val >= 0xB)
- {
- // Reset board
- m_initialized = false;
- m_initState = 0;
- }
- else
- m_boardMode = val;
- break;
- case 0xD: // 0xD0-DF Set read mode
- m_readMode = val&0x7;
- break;
- case 0xE: // 0xE0-EF Invalid command
- /* Ignore */
- break;
- case 0xF: // 0xF0-FF Echo test
- m_echoVal = val;
- break;
- }
+ // Following are commands for Scud Race. Daytona 2 has a compatible command set while Sega Rally 2 is completely different
+ // TODO - finish for Scud Race and Daytona 2
+ // TODO - implement for Sega Rally 2
+ UINT8 type = cmd>>4;
+ UINT8 val = cmd&0xF;
+ switch (type)
+ {
+ case 0: // 0x00-0F Play sequence
+ /* TODO */
+ break;
+ case 1: // 0x10-1F Set centering strength
+ if (val == 0)
+ // Disable auto-centering
+ // TODO - is 0x10 for disable?
+ SendSelfCenter(0);
+ else
+ // Enable auto-centering (0x1 = weakest, 0xF = strongest)
+ SendSelfCenter(val * 0x11);
+ break;
+ case 2: // 0x20-2F Friction strength
+ if (val == 0)
+ // Disable friction
+ // TODO - is 0x20 for disable?
+ SendFriction(0);
+ else
+ // Enable friction (0x1 = weakest, 0xF = strongest)
+ SendFriction(val * 0x11);
+ break;
+ case 3: // 0x30-3F Uncentering (vibrate)
+ if (val == 0)
+ // Disable uncentering
+ SendVibrate(0);
+ else
+ // Enable uncentering (0x1 = weakest, 0xF = strongest)
+ SendVibrate(val * 0x11);
+ break;
+ case 4: // 0x40-4F Play power-slide sequence
+ /* TODO */
+ break;
+ case 5: // 0x50-5F Rotate wheel right
+ SendConstantForce((val + 1) * 0x5);
+ break;
+ case 6: // 0x60-6F Rotate wheel left
+ SendConstantForce(-(val + 1) * 0x5);
+ break;
+ case 7: // 0x70-7F Set steering parameters
+ /* TODO */
+ break;
+ case 8: // 0x80-8F Test Mode
+ switch (val&0x7)
+ {
+ case 0: SendStopAll(); break; // 0x80 Stop motor
+ case 1: SendConstantForce(20); break; // 0x81 Roll wheel right
+ case 2: SendConstantForce(-20); break; // 0x82 Roll wheel left
+ case 3: /* Ignore - no clutch */ break; // 0x83 Clutch on
+ case 4: /* Ignore - no clutch */ break; // 0x84 Clutch off
+ case 5: m_wheelCenter = m_inputs->steering->value; break; // 0x85 Set wheel center position
+ case 6: /* Ignore */ break; // 0x86 Set cockpit banking position
+ case 7: /* Ignore */ break; // 0x87 Lamp on/off
+ }
+ case 0x9: // 0x90-9F ??? Don't appear to have any effect with Scud Race ROM
+ /* TODO */
+ break;
+ case 0xA: // 0xA0-AF ??? Don't appear to have any effect with Scud Race ROM
+ /* TODO */
+ break;
+ case 0xB: // 0xB0-BF Invalid command (reserved for use by PPC to send cabinet type 0xB0 or 0xB1 during initialization)
+ /* Ignore */
+ break;
+ case 0xC: // 0xC0-CF Set board mode (0xCB = reset board)
+ SendStopAll();
+ if (val >= 0xB)
+ {
+ // Reset board
+ m_initialized = false;
+ m_initState = 0;
+ }
+ else
+ m_boardMode = val;
+ break;
+ case 0xD: // 0xD0-DF Set read mode
+ m_readMode = val&0x7;
+ break;
+ case 0xE: // 0xE0-EF Invalid command
+ /* Ignore */
+ break;
+ case 0xF: // 0xF0-FF Echo test
+ m_echoVal = val;
+ break;
+ }
}
void CDriveBoard::RunFrame(void)
{
- if (m_simulated)
- SimulateFrame();
- else
- EmulateFrame();
+ if (m_simulated)
+ SimulateFrame();
+ else
+ EmulateFrame();
}
void CDriveBoard::SimulateFrame(void)
{
- if (!m_initialized)
- m_initState++;
- // TODO - update m_statusFlags and play preset scripts according to board mode
-}
+ if (!m_initialized)
+ m_initState++;
+ // TODO - update m_statusFlags and play preset scripts according to board mode
+}
void CDriveBoard::EmulateFrame(void)
{
- // Assuming Z80 runs @ 4.0MHz and NMI triggers @ 60.0KHz
- // TODO - find out if Z80 frequency is correct and exact frequency of NMI interrupts (just guesswork at the moment!)
- int cycles = (int)(4.0 * 1000000 / 60);
- int loopCycles = 10000;
- while (cycles > 0)
- {
- if (m_allowInterrupts)
- m_z80.TriggerNMI();
- cycles -= m_z80.Run(std::min(loopCycles, cycles));
- }
+ // Assuming Z80 runs @ 4.0MHz and NMI triggers @ 60.0KHz
+ // TODO - find out if Z80 frequency is correct and exact frequency of NMI interrupts (just guesswork at the moment!)
+ int cycles = (int)(4.0 * 1000000 / 60);
+ int loopCycles = 10000;
+ while (cycles > 0)
+ {
+ if (m_allowInterrupts)
+ m_z80.TriggerNMI();
+ cycles -= m_z80.Run(std::min(loopCycles, cycles));
+ }
}
UINT8 CDriveBoard::Read8(UINT32 addr)
{
- // TODO - shouldn't end of ROM be 0x7FFF not 0x8FFF?
- if (addr < 0x9000) // ROM is 0x0000-0x8FFF
- return m_rom[addr];
- else if (addr >= 0xE000) // RAM is 0xE000-0xFFFF
- return m_ram[(addr-0xE000)&0x1FFF];
- else
- {
- //printf("Unhandled Z80 read of %08X (at PC = %04X)\n", addr, m_z80.GetPC());
- return 0xFF;
- }
+ // TODO - shouldn't end of ROM be 0x7FFF not 0x8FFF?
+ if (addr < 0x9000) // ROM is 0x0000-0x8FFF
+ return m_rom[addr];
+ else if (addr >= 0xE000) // RAM is 0xE000-0xFFFF
+ return m_ram[(addr-0xE000)&0x1FFF];
+ else
+ {
+ //printf("Unhandled Z80 read of %08X (at PC = %04X)\n", addr, m_z80.GetPC());
+ return 0xFF;
+ }
}
void CDriveBoard::Write8(UINT32 addr, UINT8 data)
{
- if (addr >= 0xE000) // RAM is 0xE000-0xFFFF
- m_ram[(addr-0xE000)&0x1FFF] = data;
+ if (addr >= 0xE000) // RAM is 0xE000-0xFFFF
+ m_ram[(addr-0xE000)&0x1FFF] = data;
#ifdef DEBUG
- else
- printf("Unhandled Z80 write to %08X (at PC = %04X)\n", addr, m_z80.GetPC());
+ else
+ printf("Unhandled Z80 write to %08X (at PC = %04X)\n", addr, m_z80.GetPC());
#endif
}
UINT8 CDriveBoard::IORead8(UINT32 portNum)
{
- UINT8 adcVal;
- switch (portNum)
- {
- case 32: // DIP 1 value
- return m_dip1;
- case 33: // DIP 2 value
- return m_dip2;
- case 36: // ADC channel 1 - not connected
- case 37: // ADC channel 2 - steering wheel position (0x00 = full left, 0x80 = center, 0xFF = full right)
- case 38: // ADC channel 3 - cockpit bank position (deluxe cabinets) (0x00 = full left, 0x80 = center, 0xFF = full right)
- case 39: // ADC channel 4 - not connected
- if (portNum == m_adcPortRead && m_adcPortBit-- > 0)
- {
- switch (portNum)
- {
- case 36: // Not connected
- adcVal = 0x00;
- break;
- case 37: // Steering wheel for twin racing cabinets - TODO - check actual range of steering, suspect it is not really 0x00-0xFF
- if (m_initialized)
- adcVal = (UINT8)m_inputs->steering->value;
- else
- adcVal = 0x80; // If not initialized, return 0x80 so that wheel centering test does not fail
- break;
- case 38: // Cockpit bank position for deluxe racing cabinets
- adcVal = 0x80;
- break;
- case 39: // Not connected
- adcVal = 0x00;
- break;
- default:
-#ifdef DEBUG
- printf("Unhandled Z80 input on ADC port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
+ UINT8 adcVal;
+ switch (portNum)
+ {
+ case 32: // DIP 1 value
+ return m_dip1;
+ case 33: // DIP 2 value
+ return m_dip2;
+ case 36: // ADC channel 1 - not connected
+ case 37: // ADC channel 2 - steering wheel position (0x00 = full left, 0x80 = center, 0xFF = full right)
+ case 38: // ADC channel 3 - cockpit bank position (deluxe cabinets) (0x00 = full left, 0x80 = center, 0xFF = full right)
+ case 39: // ADC channel 4 - not connected
+ if (portNum == m_adcPortRead && m_adcPortBit-- > 0)
+ {
+ switch (portNum)
+ {
+ case 36: // Not connected
+ adcVal = 0x00;
+ break;
+ case 37: // Steering wheel for twin racing cabinets - TODO - check actual range of steering, suspect it is not really 0x00-0xFF
+ if (m_initialized)
+ adcVal = (UINT8)m_inputs->steering->value;
+ else
+ adcVal = 0x80; // If not initialized, return 0x80 so that wheel centering test does not fail
+ break;
+ case 38: // Cockpit bank position for deluxe racing cabinets
+ adcVal = 0x80;
+ break;
+ case 39: // Not connected
+ adcVal = 0x00;
+ break;
+ default:
+#ifdef DEBUG
+ printf("Unhandled Z80 input on ADC port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
#endif
- return 0xFF;
- }
- return (adcVal>>m_adcPortBit)&0x01;
- }
- else
- {
+ return 0xFF;
+ }
+ return (adcVal>>m_adcPortBit)&0x01;
+ }
+ else
+ {
#ifdef DEBUG
- printf("Unhandled Z80 input on ADC port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
+ printf("Unhandled Z80 input on ADC port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
#endif
- return 0xFF;
- }
- case 40: // PPC command
- return m_dataSent;
- case 44: // Encoder error reporting (kept at 0x00 for no error)
- // Bit 1 0
- // 0 0 = encoder okay, no error
- // 0 1 = encoder error 1 - overcurrent error
- // 1 0 = encoder error 2 - overheat error
- // 1 1 = encoder error 3 - encoder error, reinitializes board
- return 0x00;
- default:
+ return 0xFF;
+ }
+ case 40: // PPC command
+ return m_dataSent;
+ case 44: // Encoder error reporting (kept at 0x00 for no error)
+ // Bit 1 0
+ // 0 0 = encoder okay, no error
+ // 0 1 = encoder error 1 - overcurrent error
+ // 1 0 = encoder error 2 - overheat error
+ // 1 1 = encoder error 3 - encoder error, reinitializes board
+ return 0x00;
+ default:
#ifdef DEBUG
- printf("Unhandled Z80 input on port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
+ printf("Unhandled Z80 input on port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
#endif
- return 0xFF;
- }
+ return 0xFF;
+ }
}
void CDriveBoard::IOWrite8(UINT32 portNum, UINT8 data)
{
- switch (portNum)
- {
- case 16: // Unsure? - single byte 0x03 sent at initialization, then occasionally writes 0x07 & 0xFA to port
- return;
- case 17: // Interrupt control
- if (data == 0x57)
- m_allowInterrupts = true;
- else if (data == 0x53) // Strictly speaking 0x53 then 0x04
- m_allowInterrupts = false;
- return;
- case 28: // Unsure? - two bytes 0xFF, 0xFF sent at initialization only
- case 29: // Unsure? - two bytes 0x0F, 0x17 sent at initialization only
- case 30: // Unsure? - same as port 28
- case 31: // Unsure? - same as port 31
- return;
- case 32: // Left digit of 7-segment display 1
- m_seg1Digit1 = data;
- return;
- case 33: // Right digit of 7-segment display 1
- m_seg1Digit2 = data;
- return;
- case 34: // Left digit of 7-segment display 2
- m_seg2Digit1 = data;
- return;
- case 35: // Right digit of 7-segment display 2
- m_seg2Digit2 = data;
- return;
- case 36: // ADC channel 1 control
- case 37: // ADC channel 2 control
- case 38: // ADC channel 3 control
- case 39: // ADC channel 4 control
- m_adcPortRead = portNum;
- m_adcPortBit = 8;
- return;
- case 41: // Reply for PPC
- m_dataReceived = data;
- if (data == 0xCC)
- m_initialized = true;
- return;
- case 42: // Encoder motor data
- m_port42Out = data;
- ProcessEncoderCmd();
- return;
- case 45: // Clutch/lamp control (deluxe cabinets)
- return;
- case 46: // Encoder motor control
- m_port46Out = data;
- return;
- case 240: // Unsure? - single byte 0xBB sent at initialization only
- return;
- case 241: // Unsure? - single byte 0x4E sent regularly - some sort of watchdog?
- return;
- default:
+ switch (portNum)
+ {
+ case 16: // Unsure? - single byte 0x03 sent at initialization, then occasionally writes 0x07 & 0xFA to port
+ return;
+ case 17: // Interrupt control
+ if (data == 0x57)
+ m_allowInterrupts = true;
+ else if (data == 0x53) // Strictly speaking 0x53 then 0x04
+ m_allowInterrupts = false;
+ return;
+ case 28: // Unsure? - two bytes 0xFF, 0xFF sent at initialization only
+ case 29: // Unsure? - two bytes 0x0F, 0x17 sent at initialization only
+ case 30: // Unsure? - same as port 28
+ case 31: // Unsure? - same as port 31
+ return;
+ case 32: // Left digit of 7-segment display 1
+ m_seg1Digit1 = data;
+ return;
+ case 33: // Right digit of 7-segment display 1
+ m_seg1Digit2 = data;
+ return;
+ case 34: // Left digit of 7-segment display 2
+ m_seg2Digit1 = data;
+ return;
+ case 35: // Right digit of 7-segment display 2
+ m_seg2Digit2 = data;
+ return;
+ case 36: // ADC channel 1 control
+ case 37: // ADC channel 2 control
+ case 38: // ADC channel 3 control
+ case 39: // ADC channel 4 control
+ m_adcPortRead = portNum;
+ m_adcPortBit = 8;
+ return;
+ case 41: // Reply for PPC
+ m_dataReceived = data;
+ if (data == 0xCC)
+ m_initialized = true;
+ return;
+ case 42: // Encoder motor data
+ m_port42Out = data;
+ ProcessEncoderCmd();
+ return;
+ case 45: // Clutch/lamp control (deluxe cabinets)
+ return;
+ case 46: // Encoder motor control
+ m_port46Out = data;
+ return;
+ case 240: // Unsure? - single byte 0xBB sent at initialization only
+ return;
+ case 241: // Unsure? - single byte 0x4E sent regularly - some sort of watchdog?
+ return;
+ default:
#ifdef DEBUG
- printf("Unhandled Z80 output on port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
+ printf("Unhandled Z80 output on port %u (at PC = %04X)\n", portNum, m_z80.GetPC());
#endif
- return;
- }
+ return;
+ }
}
void CDriveBoard::ProcessEncoderCmd(void)
{
- if (m_prev42Out != m_port42Out || m_prev46Out != m_port46Out)
- {
- //printf("46 [%02X] / 42 [%02X]\n", m_port46Out, m_port42Out);
- switch (m_port46Out)
- {
- case 0xFB:
- // TODO - friction? Sent during power slide. 0xFF = strongest or 0x00?
- //SendFriction(m_port42Out);
- break;
+ if (m_prev42Out != m_port42Out || m_prev46Out != m_port46Out)
+ {
+ //printf("46 [%02X] / 42 [%02X]\n", m_port46Out, m_port42Out);
+ switch (m_port46Out)
+ {
+ case 0xFB:
+ // TODO - friction? Sent during power slide. 0xFF = strongest or 0x00?
+ //SendFriction(m_port42Out);
+ break;
- case 0xFC:
- // Centering / uncentering (vibrate)
- // Bit 2 = on for centering, off for uncentering
- if (m_port42Out&0x04)
- {
- // Centering
- // Bit 7 = on for disable, off for enable
- if (m_port42Out&0x80)
- {
- // Disable centering
- SendSelfCenter(0);
- }
- else
- {
- // Bits 3-6 = centering strength 0x0-0xF. This is scaled to range 0x0F-0xFF
- UINT8 strength = ((m_port42Out&0x78)>>3) * 0x10 + 0xF;
- SendSelfCenter(strength);
- }
- }
- else
- {
- // Uncentering
- // Bits 0-1 = data sequence number 0-3
- UINT8 seqNum = m_port42Out&0x03;
- // Bits 4-7 = data values
- UINT16 data = (m_port42Out&0xF0)>>4;
- switch (seqNum)
- {
- case 0: m_uncenterVal1 = data<<4; break;
- case 1: m_uncenterVal1 |= data; break;
- case 2: m_uncenterVal2 = data<<4; break;
- case 3: m_uncenterVal2 |= data; break;
- }
- if (seqNum == 0 && m_uncenterVal1 == 0)
- {
- // Disable uncentering
- SendVibrate(0);
- }
- else if (seqNum == 3 && m_uncenterVal1 > 0)
- {
- // Uncentering - unsure exactly how values sent map to strength or whether they specify some other attributes of effect
- // For now just attempting to map them to a sensible value in range 0x00-0xFF
- UINT8 strength = ((m_uncenterVal1>>1) - 7) * 0x50 + ((m_uncenterVal2>>1) - 5) * 0x10 + 0xF;
- SendVibrate(strength);
- }
- }
- break;
-
- case 0xFD:
- // TODO - unsure? Sent as velocity changes, similar to self-centering
- break;
-
- case 0xFE:
- // Apply constant force to wheel
- // Value is: 0x80 = stop motor, 0x81-0xC0 = roll wheel left, 0x40-0x7F = roll wheel right, scale to range -0x80-0x7F
- // Note: seems to often output 0x7F or 0x81 for stop motor, so narrowing wheel ranges to 0x40-0x7E and 0x82-0xC0
- if (m_port42Out > 0x81)
- {
- if (m_port42Out <= 0xC0)
- SendConstantForce(2 * (0x81 - m_port42Out));
- else
- SendConstantForce(-0x80);
- }
- else if (m_port42Out < 0x7F)
- {
- if (m_port42Out >= 0x40)
- SendConstantForce(2 * (0x7F - m_port42Out));
- else
- SendConstantForce(0x7F);
- }
- else
- SendConstantForce(0);
- break;
-
- case 0xFF:
- // Stop all effects
- if (m_port42Out == 0)
- SendStopAll();
- break;
+ case 0xFC:
+ // Centering / uncentering (vibrate)
+ // Bit 2 = on for centering, off for uncentering
+ if (m_port42Out&0x04)
+ {
+ // Centering
+ // Bit 7 = on for disable, off for enable
+ if (m_port42Out&0x80)
+ {
+ // Disable centering
+ SendSelfCenter(0);
+ }
+ else
+ {
+ // Bits 3-6 = centering strength 0x0-0xF. This is scaled to range 0x0F-0xFF
+ UINT8 strength = ((m_port42Out&0x78)>>3) * 0x10 + 0xF;
+ SendSelfCenter(strength);
+ }
+ }
+ else
+ {
+ // Uncentering
+ // Bits 0-1 = data sequence number 0-3
+ UINT8 seqNum = m_port42Out&0x03;
+ // Bits 4-7 = data values
+ UINT16 data = (m_port42Out&0xF0)>>4;
+ switch (seqNum)
+ {
+ case 0: m_uncenterVal1 = data<<4; break;
+ case 1: m_uncenterVal1 |= data; break;
+ case 2: m_uncenterVal2 = data<<4; break;
+ case 3: m_uncenterVal2 |= data; break;
+ }
+ if (seqNum == 0 && m_uncenterVal1 == 0)
+ {
+ // Disable uncentering
+ SendVibrate(0);
+ }
+ else if (seqNum == 3 && m_uncenterVal1 > 0)
+ {
+ // Uncentering - unsure exactly how values sent map to strength or whether they specify some other attributes of effect
+ // For now just attempting to map them to a sensible value in range 0x00-0xFF
+ UINT8 strength = ((m_uncenterVal1>>1) - 7) * 0x50 + ((m_uncenterVal2>>1) - 5) * 0x10 + 0xF;
+ SendVibrate(strength);
+ }
+ }
+ break;
+
+ case 0xFD:
+ // TODO - unsure? Sent as velocity changes, similar to self-centering
+ break;
+
+ case 0xFE:
+ // Apply constant force to wheel
+ // Value is: 0x80 = stop motor, 0x81-0xC0 = roll wheel left, 0x40-0x7F = roll wheel right, scale to range -0x80-0x7F
+ // Note: seems to often output 0x7F or 0x81 for stop motor, so narrowing wheel ranges to 0x40-0x7E and 0x82-0xC0
+ if (m_port42Out > 0x81)
+ {
+ if (m_port42Out <= 0xC0)
+ SendConstantForce(2 * (0x81 - m_port42Out));
+ else
+ SendConstantForce(-0x80);
+ }
+ else if (m_port42Out < 0x7F)
+ {
+ if (m_port42Out >= 0x40)
+ SendConstantForce(2 * (0x7F - m_port42Out));
+ else
+ SendConstantForce(0x7F);
+ }
+ else
+ SendConstantForce(0);
+ break;
+
+ case 0xFF:
+ // Stop all effects
+ if (m_port42Out == 0)
+ SendStopAll();
+ break;
- default:
- //printf("Unknown = 46 [%02X] / 42 [%02X]\n", m_port46Out, m_port42Out);
- break;
- }
+ default:
+ //printf("Unknown = 46 [%02X] / 42 [%02X]\n", m_port46Out, m_port42Out);
+ break;
+ }
- m_prev42Out = m_port42Out;
- m_prev46Out = m_port46Out;
- }
+ m_prev42Out = m_port42Out;
+ m_prev46Out = m_port46Out;
+ }
}
void CDriveBoard::SendStopAll(void)
{
- //printf(">> Stop All Effects\n");
+ //printf(">> Stop All Effects\n");
- ForceFeedbackCmd ffCmd;
- ffCmd.id = FFStop;
- m_inputs->steering->SendForceFeedbackCmd(ffCmd);
+ ForceFeedbackCmd ffCmd;
+ ffCmd.id = FFStop;
+ m_inputs->steering->SendForceFeedbackCmd(ffCmd);
- m_lastConstForce = 0;
- m_lastSelfCenter = 0;
- m_lastFriction = 0;
- m_lastVibrate = 0;
+ m_lastConstForce = 0;
+ m_lastSelfCenter = 0;
+ m_lastFriction = 0;
+ m_lastVibrate = 0;
}
void CDriveBoard::SendConstantForce(INT8 val)
{
- if (val == m_lastConstForce)
- return;
- /*
- if (val > 0)
- {
- printf(">> Force Right %02X [%8s", val, "");
- for (unsigned i = 0; i < 8; i++)
- printf(i == 0 || i <= (val + 1) / 16 ? ">" : " ");
- printf("]\n");
- }
- else if (val < 0)
- {
- printf(">> Force Left %02X [", -val);
- for (unsigned i = 0; i < 8; i++)
- printf(i == 7 || i >= (val + 128) / 16 ? "<" : " ");
- printf("%8s]\n", "");
- }
- else
- printf(">> Stop Force [%16s]\n", "");
- */
-
- ForceFeedbackCmd ffCmd;
- ffCmd.id = FFConstantForce;
- ffCmd.force = (float)val / (val >= 0 ? 127.0f : 128.0f);
- m_inputs->steering->SendForceFeedbackCmd(ffCmd);
+ if (val == m_lastConstForce)
+ return;
+ /*
+ if (val > 0)
+ {
+ printf(">> Force Right %02X [%8s", val, "");
+ for (unsigned i = 0; i < 8; i++)
+ printf(i == 0 || i <= (val + 1) / 16 ? ">" : " ");
+ printf("]\n");
+ }
+ else if (val < 0)
+ {
+ printf(">> Force Left %02X [", -val);
+ for (unsigned i = 0; i < 8; i++)
+ printf(i == 7 || i >= (val + 128) / 16 ? "<" : " ");
+ printf("%8s]\n", "");
+ }
+ else
+ printf(">> Stop Force [%16s]\n", "");
+ */
+
+ ForceFeedbackCmd ffCmd;
+ ffCmd.id = FFConstantForce;
+ ffCmd.force = (float)val / (val >= 0 ? 127.0f : 128.0f);
+ m_inputs->steering->SendForceFeedbackCmd(ffCmd);
- m_lastConstForce = val;
+ m_lastConstForce = val;
}
void CDriveBoard::SendSelfCenter(UINT8 val)
{
- if (val == m_lastSelfCenter)
- return;
- /*
- if (val == 0)
- printf(">> Stop Self-Center\n");
- else
- printf(">> Self-Center %02X\n", val);
- */
-
- ForceFeedbackCmd ffCmd;
- ffCmd.id = FFSelfCenter;
- ffCmd.force = (float)val / 255.0f;
- m_inputs->steering->SendForceFeedbackCmd(ffCmd);
+ if (val == m_lastSelfCenter)
+ return;
+ /*
+ if (val == 0)
+ printf(">> Stop Self-Center\n");
+ else
+ printf(">> Self-Center %02X\n", val);
+ */
+
+ ForceFeedbackCmd ffCmd;
+ ffCmd.id = FFSelfCenter;
+ ffCmd.force = (float)val / 255.0f;
+ m_inputs->steering->SendForceFeedbackCmd(ffCmd);
- m_lastSelfCenter = val;
+ m_lastSelfCenter = val;
}
void CDriveBoard::SendFriction(UINT8 val)
{
- if (val == m_lastFriction)
- return;
- /*
- if (val == 0)
- printf(">> Stop Friction\n");
- else
- printf(">> Friction %02X\n", val);
- */
-
- ForceFeedbackCmd ffCmd;
- ffCmd.id = FFFriction;
- ffCmd.force = (float)val / 255.0f;
- m_inputs->steering->SendForceFeedbackCmd(ffCmd);
+ if (val == m_lastFriction)
+ return;
+ /*
+ if (val == 0)
+ printf(">> Stop Friction\n");
+ else
+ printf(">> Friction %02X\n", val);
+ */
+
+ ForceFeedbackCmd ffCmd;
+ ffCmd.id = FFFriction;
+ ffCmd.force = (float)val / 255.0f;
+ m_inputs->steering->SendForceFeedbackCmd(ffCmd);
- m_lastFriction = val;
+ m_lastFriction = val;
}
void CDriveBoard::SendVibrate(UINT8 val)
{
- if (val == m_lastVibrate)
- return;
- /*
- if (val == 0)
- printf(">> Stop Vibrate\n");
- else
- printf(">> Vibrate %02X\n", val);
- */
+ if (val == m_lastVibrate)
+ return;
+ /*
+ if (val == 0)
+ printf(">> Stop Vibrate\n");
+ else
+ printf(">> Vibrate %02X\n", val);
+ */
- ForceFeedbackCmd ffCmd;
- ffCmd.id = FFVibrate;
- ffCmd.force = (float)val / 255.0f;
- m_inputs->steering->SendForceFeedbackCmd(ffCmd);
+ ForceFeedbackCmd ffCmd;
+ ffCmd.id = FFVibrate;
+ ffCmd.force = (float)val / 255.0f;
+ m_inputs->steering->SendForceFeedbackCmd(ffCmd);
- m_lastVibrate = val;
+ m_lastVibrate = val;
}
-CDriveBoard::CDriveBoard() : m_attached(false), m_tmpDisabled(false), m_simulated(false),
- m_rom(NULL), m_ram(NULL), m_inputs(NULL), m_outputs(NULL), m_dip1(0xCF), m_dip2(0xFF)
+CDriveBoard::CDriveBoard(const Util::Config::Node &config)
+ : m_config(config),
+ m_attached(false),
+ m_tmpDisabled(false),
+ m_simulated(false),
+ m_dip1(0xCF),
+ m_dip2(0xFF),
+ m_rom(NULL),
+ m_ram(NULL),
+ m_inputs(NULL),
+ m_outputs(NULL)
{
- DebugLog("Built Drive Board\n");
+ DebugLog("Built Drive Board\n");
}
CDriveBoard::~CDriveBoard(void)
-{
- if (m_ram != NULL)
- {
- delete[] m_ram;
- m_ram = NULL;
- }
- m_rom = NULL;
- m_inputs = NULL;
- m_outputs = NULL;
+{
+ if (m_ram != NULL)
+ {
+ delete[] m_ram;
+ m_ram = NULL;
+ }
+ m_rom = NULL;
+ m_inputs = NULL;
+ m_outputs = NULL;
- DebugLog("Destroyed Drive Board\n");
+ DebugLog("Destroyed Drive Board\n");
}
diff --git a/Src/Model3/DriveBoard.h b/Src/Model3/DriveBoard.h
index 105bc52..385cd6a 100644
--- a/Src/Model3/DriveBoard.h
+++ b/Src/Model3/DriveBoard.h
@@ -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
diff --git a/Src/Model3/IEmulator.h b/Src/Model3/IEmulator.h
index 03f57fe..5f96e50 100644
--- a/Src/Model3/IEmulator.h
+++ b/Src/Model3/IEmulator.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):
diff --git a/Src/Model3/Model3.cpp b/Src/Model3/Model3.cpp
index 1c9369f..c71b379 100644
--- a/Src/Model3/Model3.cpp
+++ b/Src/Model3/Model3.cpp
@@ -202,10 +202,13 @@
#include
#include
#include "Supermodel.h"
+#include "Game.h"
+#include "ROMSet.h"
#include "Util/Format.h"
+#include "Util/ByteSwap.h"
#include
#include
-#include
+#include
/******************************************************************************
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() * 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 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 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()),
+ m_gpuMultiThreaded(config["GPUMultiThreaded"].ValueAs()),
+ 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;
diff --git a/Src/Model3/Model3.h b/Src/Model3/Model3.h
index 6a14391..d309f3e 100644
--- a/Src/Model3/Model3.h
+++ b/Src/Model3/Model3.h
@@ -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;
diff --git a/Src/Model3/Model3GraphicsState.h b/Src/Model3/Model3GraphicsState.h
index 53c290e..2a8b297 100644
--- a/Src/Model3/Model3GraphicsState.h
+++ b/Src/Model3/Model3GraphicsState.h
@@ -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
diff --git a/Src/Model3/Real3D.cpp b/Src/Model3/Real3D.cpp
index f0d809a..132af74 100644
--- a/Src/Model3/Real3D.cpp
+++ b/Src/Model3/Real3D.cpp
@@ -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() ? 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())
{
Render3D = NULL;
memoryPool = NULL;
@@ -1117,6 +1119,7 @@ CReal3D::~CReal3D(void)
printf("unable to dump %s\n", "texram");
Util::WriteSurfaceToBMP("textures.bmp", reinterpret_cast(textureRAM), 2048, 2048, false);
#endif
+Util::WriteSurfaceToBMP("textures.bmp", reinterpret_cast(textureRAM), 2048, 2048, false);
Render3D = NULL;
if (memoryPool != NULL)
diff --git a/Src/Model3/Real3D.h b/Src/Model3/Real3D.h
index e340361..db63267 100644
--- a/Src/Model3/Real3D.h
+++ b/Src/Model3/Real3D.h
@@ -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;
diff --git a/Src/Model3/SoundBoard.cpp b/Src/Model3/SoundBoard.cpp
index 2234865..54b9cbd 100644
--- a/Src/Model3/SoundBoard.cpp
+++ b/Src/Model3/SoundBoard.cpp
@@ -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())
{
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());
#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;
diff --git a/Src/Model3/SoundBoard.h b/Src/Model3/SoundBoard.h
index bebe57b..f840d12 100644
--- a/Src/Model3/SoundBoard.h
+++ b/Src/Model3/SoundBoard.h
@@ -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;
diff --git a/Src/Model3/TileGen.cpp b/Src/Model3/TileGen.cpp
index b50c01a..8203e1d 100644
--- a/Src/Model3/TileGen.cpp
+++ b/Src/Model3/TileGen.cpp
@@ -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())
{
IRQ = NULL;
memoryPool = NULL;
diff --git a/Src/Model3/TileGen.h b/Src/Model3/TileGen.h
index 85e782b..44b9999 100644
--- a/Src/Model3/TileGen.h
+++ b/Src/Model3/TileGen.h
@@ -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
diff --git a/Src/OSD/Audio.h b/Src/OSD/Audio.h
index 5ff0c13..ccfbc57 100755
--- a/Src/OSD/Audio.h
+++ b/Src/OSD/Audio.h
@@ -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()
diff --git a/Src/OSD/Outputs.cpp b/Src/OSD/Outputs.cpp
index 160575e..a0a452b 100755
--- a/Src/OSD/Outputs.cpp
+++ b/Src/OSD/Outputs.cpp
@@ -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;
}
diff --git a/Src/OSD/Outputs.h b/Src/OSD/Outputs.h
index 83117ae..203f23e 100755
--- a/Src/OSD/Outputs.h
+++ b/Src/OSD/Outputs.h
@@ -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 .
- **/
-
-/*
- * 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 .
+ **/
+
+/*
+ * 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
};
diff --git a/Src/OSD/SDL/Audio.cpp b/Src/OSD/SDL/Audio.cpp
index 6924227..8811727 100755
--- a/Src/OSD/SDL/Audio.cpp
+++ b/Src/OSD/SDL/Audio.cpp
@@ -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();
diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp
index 46ea505..2d5c33e 100644
--- a/Src/OSD/SDL/Main.cpp
+++ b/Src/OSD/SDL/Main.cpp
@@ -26,6 +26,14 @@
*
* To Do Before Next Release
* -------------------------
+ * - Thoroughly test config system (do overrides work as expected? XInput
+ * force settings?)
+ * - Make sure fragment and vertex shaders are configurable for 3D (and 2D?)
+ * - Remove all occurrences of "using namespace std" from Nik's code.
+ * - Standardize variable naming (recently introduced vars_like_this should be
+ * converted back to varsLikeThis).
+ * - Update save state file revision (strings > 1024 chars are now supported).
+ * - Fix BlockFile.cpp to use fstream!
* - Check to make sure save states use explicitly-sized types for 32/64-bit
* compatibility (i.e., size_t, int, etc. not allowed).
* - Make sure quitting while paused works.
@@ -57,26 +65,38 @@
#include "Supermodel.h"
#include "Util/Format.h"
+#include "Util/NewConfig.h"
+#include "Util/ConfigBuilders.h"
+#include "GameLoader.h"
#include "SDLInputSystem.h"
#ifdef SUPERMODEL_WIN32
#include "DirectInputSystem.h"
#include "WinOutputs.h"
#endif
+#include
+
// Log file names
#define DEBUG_LOG_FILE "debug.log"
#define ERROR_LOG_FILE "error.log"
+/******************************************************************************
+ Global Run-time Config
+******************************************************************************/
+
+static Util::Config::Node s_runtime_config("Global");
+
+
/******************************************************************************
Display Management
******************************************************************************/
/*
* Position and size of rectangular region within OpenGL display to render to.
- * Unlike the g_Config object, these end up containing the actual resolution
- * (and computed offsets within the viewport) that will be rendered based on
- * what was obtained from SDL.
+ * Unlike the config tree, these end up containing the actual resolution (and
+ * computed offsets within the viewport) that will be rendered based on what
+ * was obtained from SDL.
*/
static unsigned xOffset, yOffset; // offset of renderer output within OpenGL viewport
static unsigned xRes, yRes; // renderer output resolution (can be smaller than GL viewport)
@@ -141,7 +161,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
glEnable(GL_SCISSOR_TEST);
// Scissor box (to clip visible area)
- if (g_Config.wideScreen)
+ if (s_runtime_config["WideScreen"].ValueAsDefault(false))
{
glScissor(0, correction, *totalXResPtr, *totalYResPtr - (correction * 2));
}
@@ -180,7 +200,7 @@ static bool CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned *
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
// Set vsync
- SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (g_Config.vsync ? 1 : 0));
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, s_runtime_config["VSync"].ValueAsDefault(false) ? 1 : 0);
// Set video mode
if (SDL_SetVideoMode(*xResPtr,*yResPtr,0,SDL_OPENGL|(fullScreen?SDL_FULLSCREEN|SDL_HWSURFACE:0)) == NULL)
@@ -461,197 +481,6 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
#endif
-/******************************************************************************
- Configuration
-
- Configuration file management and input settings.
-******************************************************************************/
-
-static const char s_configFilePath[] = { "Config/Supermodel.ini" };
-
-// Create and configure inputs
-static bool ConfigureInputs(CInputs *Inputs, bool configure)
-{
- static const char configFileComment[] = {
- ";\n"
- "; Supermodel Configuration File\n"
- ";\n"
- };
-
- // Open and parse configuration file
- CINIFile INI;
- INI.Open(s_configFilePath); // doesn't matter if it exists or not, will get overwritten
- INI.SetDefaultSectionName("Global");
- INI.Parse();
-
- Inputs->ReadFromINIFile(&INI, "Global");
-
- // If the user wants to configure the inputs, do that now
- if (configure)
- {
- // Open an SDL window
- unsigned xOffset, yOffset, xRes=496, yRes=384;
- if (OKAY != CreateGLScreen("Supermodel - Configuring Inputs...", &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
- return (bool) ErrorLog("Unable to start SDL to configure inputs.\n");
-
- // Configure the inputs
- if (Inputs->ConfigureInputs(NULL, xOffset, yOffset, xRes, yRes))
- {
- // Write input configuration and input system settings to config file
- Inputs->WriteToINIFile(&INI, "Global");
-
- if (OKAY != INI.Write(configFileComment))
- ErrorLog("Unable to save configuration to '%s'.", s_configFilePath);
- else
- printf("Configuration successfully saved to '%s'.\n", s_configFilePath);
- }
- else
- puts("Configuration aborted...");
- puts("");
- }
-
- INI.Close();
- return OKAY;
-}
-
-// Apply configuration settings from configuration file (does NOT read input settings; see ConfigureInputs())
-static void ApplySettings(CINIFile *INI, const char *section)
-{
- unsigned x;
- int y;
- string String;
-
- // Model 3
- INI->Get(section, "MultiThreaded", g_Config.multiThreaded);
- INI->Get(section, "GPUMultiThreaded", g_Config.gpuMultiThreaded);
- if (OKAY == INI->Get(section, "PowerPCFrequency", x))
- g_Config.SetPowerPCFrequency(x);
-
- // 3D renderer
- INI->Get(section, "VertexShader", g_Config.vertexShaderFile);
- INI->Get(section, "FragmentShader", g_Config.fragmentShaderFile);
-
- // SCSP and DSB
- if (OKAY == INI->Get(section, "SoundVolume", x))
- g_Config.SetSoundVolume(x);
- if (OKAY == INI->Get(section, "MusicVolume", x))
- g_Config.SetMusicVolume(x);
- if (OKAY == INI->Get(section, "Balance", y))
- g_Config.SetSCSPBalance(y);
- INI->Get(section, "EmulateSound", g_Config.emulateSound);
- INI->Get(section, "EmulateDSB", g_Config.emulateDSB);
-
- // Drive board
-#ifdef SUPERMODEL_WIN32
- INI->Get(section, "ForceFeedback", g_Config.forceFeedback);
-#endif // SUPERMODEL_WIN32
-
- // OSD
- INI->Get(section, "New3DEngine", g_Config.new3DEngine);
- INI->Get(section, "XResolution", g_Config.xRes);
- INI->Get(section, "YResolution", g_Config.yRes);
- INI->Get(section, "FullScreen", g_Config.fullScreen);
- INI->Get(section, "WideScreen", g_Config.wideScreen);
- INI->Get(section, "MultiTexture", g_Config.multiTexture);
- INI->Get(section, "VSync", g_Config.vsync);
- INI->Get(section, "Throttle", g_Config.throttle);
- INI->Get(section, "ShowFrameRate", g_Config.showFPS);
- INI->Get(section, "Crosshairs", g_Config.crosshairs);
- INI->Get(section, "FlipStereo", g_Config.flipStereo);
-
-#ifdef SUPERMODEL_WIN32
- // DirectInput ForceFeedback
- INI->Get(section, "DirectInputConstForceMax", g_Config.dInputConstForceLeftMax);
- INI->Get(section, "DirectInputConstForceMax", g_Config.dInputConstForceRightMax);
- INI->Get(section, "DirectInputConstForceLeftMax", g_Config.dInputConstForceLeftMax);
- INI->Get(section, "DirectInputConstForceRightMax", g_Config.dInputConstForceRightMax);
- INI->Get(section, "DirectInputSelfCenterMax", g_Config.dInputSelfCenterMax);
- INI->Get(section, "DirectInputFrictionMax", g_Config.dInputFrictionMax);
- INI->Get(section, "DirectInputVibrateMax", g_Config.dInputVibrateMax);
-
- // XInput ForceFeedback
- INI->Get(section, "XInputConstForceThreshold", g_Config.xInputConstForceThreshold);
- INI->Get(section, "XInputConstForceMax", g_Config.xInputConstForceMax);
- INI->Get(section, "XInputVibrateMax", g_Config.xInputVibrateMax);
-#endif // SUPERMODEL_WIN32
-}
-
-// Read settings (from a specific section) from the config file
-static void ReadConfigFile(const char *section)
-{
- CINIFile INI;
-
- INI.Open(s_configFilePath);
- INI.SetDefaultSectionName("Global"); // required to read settings not associated with a specific section
- INI.Parse();
- ApplySettings(&INI, section);
- INI.Close();
-}
-
-// Log the configuration to info log
-static void LogConfig(void)
-{
- InfoLog("Program settings:");
-
- // COSDConfig
- InfoLog("\tNew3DEngine = %d", g_Config.new3DEngine);
- InfoLog("\tXResolution = %d", g_Config.xRes);
- InfoLog("\tYResolution = %d", g_Config.yRes);
- InfoLog("\tFullScreen = %d", g_Config.fullScreen);
- InfoLog("\tWideScreen = %d", g_Config.wideScreen);
- InfoLog("\tVSync = %d", g_Config.vsync);
- InfoLog("\tMultiTexture = %d", g_Config.multiTexture);
- InfoLog("\tThrottle = %d", g_Config.throttle);
- InfoLog("\tShowFrameRate = %d", g_Config.showFPS);
- InfoLog("\tCrosshairs = %d", g_Config.crosshairs);
-#ifdef SUPERMODEL_DEBUGGER
- InfoLog("\tDisableDebugger = %d", g_Config.disableDebugger);
-#endif
- InfoLog("\tInputSystem = %s", g_Config.GetInputSystem());
- InfoLog("\tOutputs = %s", g_Config.GetOutputs());
- InfoLog("\tFlipStereo = %d", g_Config.flipStereo);
-
-#ifdef SUPERMODEL_WIN32
- // DirectInput ForceFeedback
- InfoLog("\tDirectInputConstForceLeftMax = %u", g_Config.dInputConstForceLeftMax);
- InfoLog("\tDirectInputConstForceRightMax = %u", g_Config.dInputConstForceRightMax);
- InfoLog("\tDirectInputSelfCenterMax = %u", g_Config.dInputSelfCenterMax);
- InfoLog("\tDirectInputFrictionMax = %u", g_Config.dInputFrictionMax);
- InfoLog("\tDirectInputVibrateMax = %u", g_Config.dInputVibrateMax);
-
- // XInput ForceFeedback
- InfoLog("\tXInputConstForceThreshold = %u", g_Config.xInputConstForceThreshold);
- InfoLog("\tXInputConstForceMax = %u", g_Config.xInputConstForceMax);
- InfoLog("\tXInputVibrateMax = %u", g_Config.xInputVibrateMax);
-#endif // SUPERMODEL_WIN32
-
- // CModel3Config
- InfoLog("\tMultiThreaded = %d", g_Config.multiThreaded);
- InfoLog("\tGPUMultiThreaded = %d", g_Config.gpuMultiThreaded);
- InfoLog("\tPowerPCFrequency = %d", g_Config.GetPowerPCFrequency());
-
- // CSoundBoardConfig
- InfoLog("\tEmulateSound = %d", g_Config.emulateSound);
- InfoLog("\tBalance = %d", g_Config.GetSCSPBalance());
-
- // CDSBConfig
- InfoLog("\tEmulateDSB = %d", g_Config.emulateDSB);
- InfoLog("\tSoundVolume = %d", g_Config.GetSoundVolume());
- InfoLog("\tMusicVolume = %d", g_Config.GetMusicVolume());
-
- // CDriveBoardConfig
-#ifdef SUPERMODEL_WIN32
- InfoLog("\tForceFeedback = %d", g_Config.forceFeedback);
-#endif
-
- // CLegacy3DConfig
- InfoLog("\tVertexShader = %s", g_Config.vertexShaderFile.c_str());
- InfoLog("\tFragmentShader = %s", g_Config.fragmentShaderFile.c_str());
-
- InfoLog("");
-}
-
-
/******************************************************************************
Save States and NVRAM
@@ -674,24 +503,23 @@ static void SaveState(IEmulator *Model3)
{
CBlockFile SaveState;
- char filePath[24];
- sprintf(filePath, "Saves/%s.st%d", Model3->GetGameInfo()->id, s_saveSlot);
- if (OKAY != SaveState.Create(filePath, "Supermodel Save State", "Supermodel Version " SUPERMODEL_VERSION))
+ std::string file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
+ if (OKAY != SaveState.Create(file_path, "Supermodel Save State", "Supermodel Version " SUPERMODEL_VERSION))
{
- ErrorLog("Unable to save state to '%s'.", filePath);
+ ErrorLog("Unable to save state to '%s'.", file_path.c_str());
return;
}
// Write file format version and ROM set ID to header block
int32_t fileVersion = STATE_FILE_VERSION;
SaveState.Write(&fileVersion, sizeof(fileVersion));
- SaveState.Write(Model3->GetGameInfo()->id, strlen(Model3->GetGameInfo()->id)+1);
+ SaveState.Write(Model3->GetGame().name);
// Save state
Model3->SaveState(&SaveState);
SaveState.Close();
- printf("Saved state to '%s'.\n", filePath);
- DebugLog("Saved state to '%s'.\n", filePath);
+ printf("Saved state to '%s'.\n", file_path.c_str());
+ DebugLog("Saved state to '%s'.\n", file_path.c_str());
}
static void LoadState(IEmulator *Model3)
@@ -699,19 +527,18 @@ static void LoadState(IEmulator *Model3)
CBlockFile SaveState;
// Generate file path
- char filePath[24];
- sprintf(filePath, "Saves/%s.st%d", Model3->GetGameInfo()->id, s_saveSlot);
+ std::string file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
// Open and check to make sure format is correct
- if (OKAY != SaveState.Load(filePath))
+ if (OKAY != SaveState.Load(file_path))
{
- ErrorLog("Unable to load state from '%s'.", filePath);
+ ErrorLog("Unable to load state from '%s'.", file_path.c_str());
return;
}
if (OKAY != SaveState.FindBlock("Supermodel Save State"))
{
- ErrorLog("'%s' does not appear to be a valid save state file.", filePath);
+ ErrorLog("'%s' does not appear to be a valid save state file.", file_path.c_str());
return;
}
@@ -719,38 +546,37 @@ static void LoadState(IEmulator *Model3)
SaveState.Read(&fileVersion, sizeof(fileVersion));
if (fileVersion != STATE_FILE_VERSION)
{
- ErrorLog("'%s' is incompatible with this version of Supermodel.", filePath);
+ ErrorLog("'%s' is incompatible with this version of Supermodel.", file_path.c_str());
return;
}
// Load
Model3->LoadState(&SaveState);
SaveState.Close();
- printf("Loaded state from '%s'.\n", filePath);
- DebugLog("Loaded state from '%s'.\n", filePath);
+ printf("Loaded state from '%s'.\n", file_path.c_str());
+ DebugLog("Loaded state from '%s'.\n", file_path.c_str());
}
static void SaveNVRAM(IEmulator *Model3)
{
CBlockFile NVRAM;
- char filePath[24];
- sprintf(filePath, "NVRAM/%s.nv", Model3->GetGameInfo()->id);
- if (OKAY != NVRAM.Create(filePath, "Supermodel NVRAM State", "Supermodel Version " SUPERMODEL_VERSION))
+ std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
+ if (OKAY != NVRAM.Create(file_path, "Supermodel NVRAM State", "Supermodel Version " SUPERMODEL_VERSION))
{
- ErrorLog("Unable to save NVRAM to '%s'. Make sure directory exists!", filePath);
+ ErrorLog("Unable to save NVRAM to '%s'. Make sure directory exists!", file_path.c_str());
return;
}
// Write file format version and ROM set ID to header block
int32_t fileVersion = NVRAM_FILE_VERSION;
NVRAM.Write(&fileVersion, sizeof(fileVersion));
- NVRAM.Write(Model3->GetGameInfo()->id, strlen(Model3->GetGameInfo()->id)+1);
+ NVRAM.Write(Model3->GetGame().name);
// Save NVRAM
Model3->SaveNVRAM(&NVRAM);
NVRAM.Close();
- DebugLog("Saved NVRAM to '%s'.\n", filePath);
+ DebugLog("Saved NVRAM to '%s'.\n", file_path.c_str());
}
static void LoadNVRAM(IEmulator *Model3)
@@ -758,11 +584,10 @@ static void LoadNVRAM(IEmulator *Model3)
CBlockFile NVRAM;
// Generate file path
- char filePath[24];
- sprintf(filePath, "NVRAM/%s.nv", Model3->GetGameInfo()->id);
+ std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
// Open and check to make sure format is correct
- if (OKAY != NVRAM.Load(filePath))
+ if (OKAY != NVRAM.Load(file_path))
{
//ErrorLog("Unable to restore NVRAM from '%s'.", filePath);
return;
@@ -770,7 +595,7 @@ static void LoadNVRAM(IEmulator *Model3)
if (OKAY != NVRAM.FindBlock("Supermodel NVRAM State"))
{
- ErrorLog("'%s' does not appear to be a valid NVRAM file.", filePath);
+ ErrorLog("'%s' does not appear to be a valid NVRAM file.", file_path.c_str());
return;
}
@@ -778,14 +603,14 @@ static void LoadNVRAM(IEmulator *Model3)
NVRAM.Read(&fileVersion, sizeof(fileVersion));
if (fileVersion != NVRAM_FILE_VERSION)
{
- ErrorLog("'%s' is incompatible with this version of Supermodel.", filePath);
+ ErrorLog("'%s' is incompatible with this version of Supermodel.", file_path.c_str());
return;
}
// Load
Model3->LoadNVRAM(&NVRAM);
NVRAM.Close();
- DebugLog("Loaded NVRAM from '%s'.\n", filePath);
+ DebugLog("Loaded NVRAM from '%s'.\n", file_path.c_str());
}
@@ -896,7 +721,7 @@ void EndFrameVideo()
{
// Show crosshairs for light gun games
if (videoInputs)
- UpdateCrosshairs(videoInputs, g_Config.crosshairs);
+ UpdateCrosshairs(videoInputs, s_runtime_config["Crosshairs"].ValueAs());
// Swap the buffers
SDL_GL_SwapBuffers();
@@ -904,12 +729,12 @@ void EndFrameVideo()
static void SuperSleep(UINT32 time)
{
- UINT32 start = SDL_GetTicks();
- UINT32 tics = start;
+ UINT32 start = SDL_GetTicks();
+ UINT32 tics = start;
- while (start + time > tics) {
- tics = SDL_GetTicks();
- }
+ while (start + time > tics) {
+ tics = SDL_GetTicks();
+ }
}
/******************************************************************************
@@ -917,29 +742,26 @@ static void SuperSleep(UINT32 time)
******************************************************************************/
#ifdef SUPERMODEL_DEBUGGER
-int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs, Debugger::CDebugger *Debugger, CINIFile *CmdLine)
+int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs, Debugger::CDebugger *Debugger)
{
CLogger *oldLogger = 0;
#else
-int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs, CINIFile *CmdLine)
+int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs)
{
#endif // SUPERMODEL_DEBUGGER
unsigned prevFPSTicks;
- unsigned fpsFramesElapsed;
- bool gameHasLightguns = false;
- bool quit = false;
- bool paused = false;
- bool dumpTimings = false;
+ unsigned fpsFramesElapsed;
+ bool gameHasLightguns = false;
+ bool quit = false;
+ bool paused = false;
+ bool dumpTimings = false;
// Initialize and load ROMs
if (OKAY != Model3->Init())
return 1;
- if (OKAY != Model3->LoadROMSet(g_Model3GameList, zipFile))
+ if (Model3->LoadGame(game, *rom_set))
return 1;
-
- // Apply game-specific settings and then, lastly, command line settings
- ReadConfigFile(Model3->GetGameInfo()->id);
- ApplySettings(CmdLine, "Global");
+ *rom_set = ROMSet(); // free up this memory we won't need anymore
// Load NVRAM
LoadNVRAM(Model3);
@@ -947,23 +769,22 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
// Start up SDL and open a GL window
char baseTitleStr[128];
char titleStr[128];
- totalXRes = xRes = g_Config.xRes;
- totalYRes = yRes = g_Config.yRes;
- sprintf(baseTitleStr, "Supermodel - %s", Model3->GetGameInfo()->title);
- if (OKAY != CreateGLScreen(baseTitleStr, &xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, true, g_Config.fullScreen))
+ totalXRes = xRes = s_runtime_config["XResolution"].ValueAs();
+ totalYRes = yRes = s_runtime_config["YResolution"].ValueAs();
+ sprintf(baseTitleStr, "Supermodel - %s", game.title.c_str());
+ if (OKAY != CreateGLScreen(baseTitleStr, &xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, true, s_runtime_config["FullScreen"].ValueAs()))
return 1;
-
- // Info log GL information and user options
+
+ // Info log GL information
PrintGLInfo(false, true, false);
- LogConfig();
// Initialize audio system
if (OKAY != OpenAudio())
return 1;
// Hide mouse if fullscreen, enable crosshairs for gun games
- Inputs->GetInputSystem()->SetMouseVisibility(!g_Config.fullScreen);
- gameHasLightguns = !!(Model3->GetGameInfo()->inputFlags & (GAME_INPUT_GUN1|GAME_INPUT_GUN2));
+ Inputs->GetInputSystem()->SetMouseVisibility(!s_runtime_config["FullScreen"].ValueAs());
+ gameHasLightguns = !!(game.inputs & (GAME_INPUT_GUN1|GAME_INPUT_GUN2));
if (gameHasLightguns)
videoInputs = Inputs;
else
@@ -978,7 +799,7 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
// Initialize the renderers
CRender2D *Render2D = new CRender2D();
- IRender3D *Render3D = g_Config.new3DEngine ? ((IRender3D *) new New3D::CNew3D()) : ((IRender3D *) new Legacy3D::CLegacy3D());
+ IRender3D *Render3D = s_runtime_config["New3DEngine"].ValueAs() ? ((IRender3D *) new New3D::CNew3D()) : ((IRender3D *) new Legacy3D::CLegacy3D(s_runtime_config));
if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
goto QuitError;
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
@@ -1013,7 +834,7 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
#endif
while (!quit)
{
- auto startTime = SDL_GetTicks();
+ auto startTime = SDL_GetTicks();
// Render if paused, otherwise run a frame
if (paused)
@@ -1022,7 +843,7 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
Model3->RunFrame();
// Poll the inputs
- if (!Inputs->Poll(Model3->GetGameInfo(), xOffset, yOffset, xRes, yRes))
+ if (!Inputs->Poll(&game, xOffset, yOffset, xRes, yRes))
quit = true;
#ifdef SUPERMODEL_DEBUGGER
@@ -1104,7 +925,7 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiFullScreen->Pressed())
{
// Toggle emulator fullscreen
- g_Config.fullScreen = !g_Config.fullScreen;
+ s_runtime_config.Get("FullScreen").SetValue(!s_runtime_config["FullScreen"].ValueAs());
// Delete renderers and recreate them afterwards since GL context will most likely be lost when switching from/to fullscreen
delete Render2D;
@@ -1113,21 +934,21 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
Render3D = NULL;
// Resize screen
- totalXRes = xRes = g_Config.xRes;
- totalYRes = yRes = g_Config.yRes;
- if (OKAY != ResizeGLScreen(&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,true,g_Config.fullScreen))
+ totalXRes = xRes = s_runtime_config["XResolution"].ValueAs();
+ totalYRes = yRes = s_runtime_config["YResolution"].ValueAs();
+ if (OKAY != ResizeGLScreen(&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,true,s_runtime_config["FullScreen"].ValueAs()))
goto QuitError;
// Recreate renderers and attach to the emulator
Render2D = new CRender2D();
- Render3D = g_Config.new3DEngine ? ((IRender3D *) new New3D::CNew3D()) : ((IRender3D *) new Legacy3D::CLegacy3D());
+ Render3D = s_runtime_config["New3DEngine"].ValueAs() ? ((IRender3D *) new New3D::CNew3D()) : ((IRender3D *) new Legacy3D::CLegacy3D(s_runtime_config));
if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
goto QuitError;
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
goto QuitError;
Model3->AttachRenderers(Render2D,Render3D);
- Inputs->GetInputSystem()->SetMouseVisibility(!g_Config.fullScreen);
+ Inputs->GetInputSystem()->SetMouseVisibility(!s_runtime_config["FullScreen"].ValueAs());
}
else if (Inputs->uiSaveState->Pressed())
{
@@ -1179,12 +1000,10 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiMusicVolUp->Pressed())
{
// Increase music volume by 10%
- if (Model3->GetGameInfo()->mpegBoard)
+ if (!Model3->GetGame().mpeg_board.empty())
{
- int vol = (int) g_Config.GetMusicVolume() + 10;
- if (vol > 200)
- vol = 200;
- g_Config.SetMusicVolume(vol);
+ int vol = std::min(200, s_runtime_config["MusicVolume"].ValueAs() + 10);
+ s_runtime_config.Get("MusicVolume").SetValue(vol);
printf("Music volume: %d%%", vol);
if (200 == vol)
puts(" (maximum)");
@@ -1197,12 +1016,10 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiMusicVolDown->Pressed())
{
// Decrease music volume by 10%
- if (Model3->GetGameInfo()->mpegBoard)
+ if (!Model3->GetGame().mpeg_board.empty())
{
- int vol = (int) g_Config.GetMusicVolume() - 10;
- if (vol < 0)
- vol = 0;
- g_Config.SetMusicVolume(vol);
+ int vol = std::max(0, s_runtime_config["MusicVolume"].ValueAs() - 10);
+ s_runtime_config.Get("MusicVolume").SetValue(vol);
printf("Music volume: %d%%", vol);
if (0 == vol)
puts(" (muted)");
@@ -1215,10 +1032,8 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiSoundVolUp->Pressed())
{
// Increase sound volume by 10%
- int vol = (int) g_Config.GetSoundVolume() + 10;
- if (vol > 200)
- vol = 200;
- g_Config.SetSoundVolume(vol);
+ int vol = std::min(200, s_runtime_config["SoundVolume"].ValueAs() + 10);
+ s_runtime_config.Get("SoundVolume").SetValue(vol);
printf("Sound volume: %d%%", vol);
if (200 == vol)
puts(" (maximum)");
@@ -1228,10 +1043,8 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiSoundVolDown->Pressed())
{
// Decrease sound volume by 10%
- int vol = (int) g_Config.GetSoundVolume() - 10;
- if (vol < 0)
- vol = 0;
- g_Config.SetSoundVolume(vol);
+ int vol = std::max(0, s_runtime_config["SoundVolume"].ValueAs() - 10);
+ s_runtime_config.Get("SoundVolume").SetValue(vol);
printf("Sound volume: %d%%", vol);
if (0 == vol)
puts(" (muted)");
@@ -1241,7 +1054,7 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiDumpInpState->Pressed())
{
// Dump input states
- Inputs->DumpState(Model3->GetGameInfo());
+ Inputs->DumpState(&game);
}
else if (Inputs->uiDumpTimings->Pressed())
{
@@ -1249,8 +1062,9 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
}
else if (Inputs->uiSelectCrosshairs->Pressed() && gameHasLightguns)
{
- g_Config.crosshairs++;
- switch (g_Config.crosshairs & 3)
+ int crosshairs = (s_runtime_config["Crosshairs"].ValueAs() + 1) & 3;
+ s_runtime_config.Get("Crosshairs").SetValue(crosshairs);
+ switch (crosshairs)
{
case 0: puts("Crosshairs disabled."); break;
case 3: puts("Crosshairs enabled."); break;
@@ -1267,8 +1081,8 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
else if (Inputs->uiToggleFrLimit->Pressed())
{
// Toggle frame limiting
- g_Config.throttle = !g_Config.throttle;
- printf("Frame limiting: %s\n", g_Config.throttle?"On":"Off");
+ s_runtime_config.Get("Throttle").SetValue(!s_runtime_config["Throttle"].ValueAs());
+ printf("Frame limiting: %s\n", s_runtime_config["Throttle"].ValueAs() ? "On" : "Off");
}
#ifdef SUPERMODEL_DEBUGGER
else if (Debugger != NULL && Inputs->uiEnterDebugger->Pressed())
@@ -1283,7 +1097,7 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
// Frame rate and limiting
unsigned currentFPSTicks = SDL_GetTicks();
unsigned currentTicks = currentFPSTicks;
- if (g_Config.showFPS)
+ if (s_runtime_config["ShowFrameRate"].ValueAs())
{
++fpsFramesElapsed;
if((currentFPSTicks-prevFPSTicks) >= 1000) // update FPS every 1 second (each tick is 1 ms)
@@ -1295,11 +1109,11 @@ int Supermodel(const char *zipFile, IEmulator *Model3, CInputs *Inputs, COutputs
}
}
- if (paused || g_Config.throttle)
+ if (paused || s_runtime_config["Throttle"].ValueAs())
{
- UINT32 endTime = SDL_GetTicks();
- UINT32 diff = endTime - startTime;
- UINT32 frameTime = (UINT32)(1000 / 60.f); // 60 fps, we could roll with 57.5? that would be a jerk fest on 60hz screens though
+ UINT32 endTime = SDL_GetTicks();
+ UINT32 diff = endTime - startTime;
+ UINT32 frameTime = (UINT32)(1000 / 60.f); // 60 fps, we could roll with 57.5? that would be a jerk fest on 60hz screens though
if (diff < frameTime) {
SuperSleep(frameTime - diff);
@@ -1346,84 +1160,144 @@ QuitError:
}
-/******************************************************************************
- CROM Disassembler
-******************************************************************************/
-
-// Disassemble instructions from CROM
-static int DisassembleCROM(const char *zipFile, uint32_t addr, unsigned n)
-{
- const struct GameInfo *Game;
- uint8_t *crom;
- struct ROMMap Map[] =
- {
- { "CROM", NULL },
- { "CROMxx", NULL },
- { NULL, NULL }
- };
-
- // Do we have a valid CROM address?
- if (addr < 0xFF800000)
- return ErrorLog("Valid CROM address range is FF800000-FFFFFFFF.");
-
- // Allocate memory and set ROM region
- crom = new(std::nothrow) uint8_t[0x8800000];
- if (NULL == crom)
- return ErrorLog("Insufficient memory to load CROM (need %d MB).", (0x8800000/8));
- Map[0].ptr = crom;
- Map[1].ptr = &crom[0x800000];
-
- // Load ROM set
- Game = LoadROMSetFromZIPFile(Map, g_Model3GameList, zipFile, false);
- if (NULL == Game)
- return ErrorLog("Failed to load ROM set.");
-
- // Mirror CROM if necessary
- if (Game->cromSize < 0x800000) // high part of fixed CROM region contains CROM0
- CopyRegion(crom, 0, 0x800000-0x200000, &crom[0x800000], 0x800000);
-
- // Disassemble!
- addr -= 0xFF800000;
- while ((n > 0) && ((addr+4) <= 0x800000))
- {
- uint32_t op = (crom[addr+0]<<24) | (crom[addr+1]<<16) | (crom[addr+2]<<8) | crom[addr+3];
-
- printf("%08X: ", addr+0xFF800000);
- char mnem[16];
- char oprs[48];
- if (DisassemblePowerPC(op, addr+0xFF800000, mnem, oprs, 1))
- {
- if (mnem[0] != '\0') // invalid form
- printf("%08X %s*\t%s\n", op, mnem, oprs);
- else
- printf("%08X ?\n", op);
- }
- else
- printf("%08X %s\t%s\n", op, mnem, oprs);
-
- addr += 4;
- --n;
- }
-
- delete [] crom;
- return OKAY;
-}
-
-
/******************************************************************************
Entry Point and Command Line Procesing
******************************************************************************/
-// Print Supermodel title and copyright information
+static const char s_configFilePath[] = { "Config/Supermodel.ini" };
+static const char s_gameXMLFilePath[] = { "Config/Games.xml" };
+
+// Create and configure inputs
+static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *config, bool configure)
+{
+ static const char configFileComment[] = {
+ ";\n"
+ "; Supermodel Configuration File\n"
+ ";\n"
+ };
+
+ Inputs->LoadFromConfig(*config);
+
+ // If the user wants to configure the inputs, do that now
+ if (configure)
+ {
+ // Open an SDL window
+ unsigned xOffset, yOffset, xRes=496, yRes=384;
+ if (OKAY != CreateGLScreen("Supermodel - Configuring Inputs...", &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
+ return (bool) ErrorLog("Unable to start SDL to configure inputs.\n");
+
+ // Configure the inputs
+ if (Inputs->ConfigureInputs(NULL, xOffset, yOffset, xRes, yRes))
+ {
+ // Write input configuration and input system settings to config file
+ Inputs->StoreToConfig(config);
+ Util::Config::WriteINIFile(s_configFilePath, *config, configFileComment);
+ }
+ else
+ puts("Configuration aborted...");
+ puts("");
+ }
+
+ return OKAY;
+}
+
+// Print game list
+static void PrintGameList(const std::string &xml_file, const std::map &games)
+{
+ if (games.empty())
+ {
+ puts("No games defined.");
+ return;
+ }
+ printf("Games defined in %s:\n", xml_file.c_str());
+ puts("");
+ puts(" ROM Set Title");
+ puts(" ------- -----");
+ for (auto &v: games)
+ {
+ const Game &game = v.second;
+ printf(" %s", game.name.c_str());
+ for (int i = game.name.length(); i < 9; i++) // pad for alignment (no game ID should be more than 9 letters)
+ printf(" ");
+ printf(" %s\n", game.title.c_str());
+ }
+}
+
+static void LogConfig(const Util::Config::Node &config)
+{
+ InfoLog("Runtime configuration:");
+ for (auto &child: config)
+ {
+ if (child.Empty())
+ InfoLog(" %s=", child.Key().c_str());
+ else
+ InfoLog(" %s=%s", child.Key().c_str(), child.ValueAs().c_str());
+ }
+ InfoLog("");
+}
+
+static Util::Config::Node DefaultConfig()
+{
+ Util::Config::Node config("Global");
+ config.Set("GameXMLFile", s_gameXMLFilePath);
+ // CModel3
+ config.Set("MultiThreaded", true);
+ config.Set("GPUMultiThreaded", true);
+ config.Set("PowerPCFrequency", "50");
+ // CLegacy3D
+ config.Set("MultiTexture", false);
+ config.Set("VertexShader", "");
+ config.Set("FragmentShader", "");
+ // CSoundBoard
+ config.Set("EmulateSound", true);
+ config.Set("Balance", false);
+ // CDSB
+ config.Set("EmulateDSB", true);
+ config.Set("SoundVolume", "100");
+ config.Set("MusicVolume", "100");
+ // CDriveBoard
+#ifdef SUPERMODEL_WIN32
+ config.Set("ForceFeedback", false);
+#endif
+ // Platform-specific/UI
+ config.Set("New3DEngine", false);
+ config.Set("XResolution", "496");
+ config.Set("YResolution", "384");
+ config.Set("FullScreen", false);
+ config.Set("WideScreen", false);
+ config.Set("VSync", true);
+ config.Set("Throttle", true);
+ config.Set("ShowFrameRate", false);
+ config.Set("Crosshairs", int(0));
+ config.Set("FlipStereo", false);
+#ifdef SUPERMODEL_WIN32
+ config.Set("InputSystem", "dinput");
+ // DirectInput ForceFeedback
+ config.Set("DirectInputConstForceLeftMax", "100");
+ config.Set("DirectInputConstForceRightMax", "100");
+ config.Set("DirectInputSelfCenterMax", "100");
+ config.Set("DirectInputFrictionMax", "100");
+ config.Set("DirectInputVibrateMax", "100");
+ // XInput ForceFeedback
+ config.Set("XInputConstForceThreshold", "30");
+ config.Set("XInputConstForceMax", "100");
+ config.Set("XInputVibrateMax", "100");
+#else
+ config.Set("InputSystem", "sdl");
+#endif
+ config.Set("Outputs", "none");
+ return config;
+}
+
static void Title(void)
{
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
puts("Copyright 2011-2016 by Bart Trzynadlowski and Nik Henson\n");
}
-// Print usage information
static void Help(void)
{
+ Util::Config::Node defaultConfig = DefaultConfig();
puts("Usage: Supermodel [options]");
puts("ROM set must be a valid ZIP file containing a single game.");
puts("");
@@ -1432,7 +1306,7 @@ static void Help(void)
puts(" -print-games List supported games and quit");
puts("");
puts("Core Options:");
- printf(" -ppc-frequency= PowerPC frequency in MHz [Default: %d]\n", g_Config.GetPowerPCFrequency());
+ printf(" -ppc-frequency= PowerPC frequency in MHz [Default: %d]\n", defaultConfig["PowerPCFrequency"].ValueAs());
puts(" -no-threads Disable multi-threading entirely");
puts(" -gpu-multi-threaded Run graphics rendering in separate thread [Default]");
puts(" -no-gpu-thread Run graphics rendering in main thread");
@@ -1471,8 +1345,8 @@ static void Help(void)
#endif
puts(" -config-inputs Configure keyboards, mice, and game controllers");
#ifdef SUPERMODEL_WIN32
- printf(" -input-system= Input system [Default: %s]\n", g_Config.GetInputSystem());
- printf(" -outputs= Outputs [Default: %s]\n", g_Config.GetOutputs());
+ printf(" -input-system= Input system [Default: %s]\n", defaultConfig["InputSystem"].ValueAs().c_str());
+ printf(" -outputs= Outputs [Default: %s]\n", defaultConfig["Outputs"].ValueAs().c_str());
#endif
puts(" -print-inputs Prints current input configuration");
puts("");
@@ -1480,27 +1354,167 @@ static void Help(void)
puts("Debug Options:");
puts(" -disable-debugger Completely disable debugger functionality");
puts(" -enter-debugger Enter debugger at start of emulation");
- puts(" -dis=[,n] Disassemble PowerPC code from CROM");
puts("");
#endif // SUPERMODEL_DEBUGGER
}
-// Print game list
-static void PrintGameList(void)
+struct ParsedCommandLine
{
- int i, j;
-
- puts("Supported games:");
- puts("");
- puts(" ROM Set Title");
- puts(" ------- -----");
- for (i = 0; g_Model3GameList[i].title != NULL; i++)
+ Util::Config::Node config = Util::Config::Node("CommandLine");
+ std::vector rom_files;
+ bool show_help = false;
+ bool print_games = false;
+ bool print_gl_info = false;
+ bool config_inputs = false;
+ bool print_inputs = false;
+ bool disable_debugger = false;
+ bool enter_debugger = false;
+#ifdef DEBUG
+ std::string gfx_state;
+#endif
+};
+
+static ParsedCommandLine ParseCommandLine(int argc, char **argv)
+{
+ ParsedCommandLine cmd_line;
+ const std::map valued_options
+ { // -option=value
+ { "-game-xml-file", "GameXMLFile" },
+ { "-ppc-frequency", "PowerPCFrequency" },
+ { "-crosshairs", "Crosshairs" },
+ { "-vert-shader", "VertexShader" },
+ { "-frag-shader", "FragmentShader" },
+ { "-sound-volume", "SoundVolume" },
+ { "-music-volume", "MusicVolume" },
+ { "-balance", "Balance" },
+ { "-input-system", "InputSystem" },
+ { "-outputs", "Outputs" }
+ };
+ const std::map> bool_options
+ { // -option
+ { "-threads", { "MultiThreaded", true } },
+ { "-no-threads", { "MultiThreaded", false } },
+ { "-gpu-multi-threaded", { "GPUMultiThreaded", true } },
+ { "-no-gpu-thread", { "GPUMultiThreaded", false } },
+ { "-window", { "FullScreen", false } },
+ { "-fullscreen", { "FullScreen", true } },
+ { "-no-wide-screen", { "WideScreen", false } },
+ { "-wide-screen", { "WideScreen", true } },
+ { "-no-multi-texture", { "MultiTexture", false } },
+ { "-multi-texture", { "MultiTexture", true } },
+ { "-throttle", { "Throttle", true } },
+ { "-no-throttle", { "Throttle", false } },
+ { "-vsync", { "VSync", true } },
+ { "-no-vsync", { "VSync", false } },
+ { "-show-fps", { "ShowFrameRate", true } },
+ { "-no-fps", { "ShowFrameRate", false } },
+ { "-new3d", { "New3DEngine", true } },
+ { "-legacy3d", { "New3DEngine", false } },
+ { "-no-flip-stereo", { "FlipStereo", false } },
+ { "-flip-stereo", { "FlipStereo", true } },
+ { "-sound", { "EmulateSound", true } },
+ { "-no-sound", { "EmulateSound", false } },
+ { "-dsb", { "EmulateDSB", true } },
+ { "-no-dsb", { "EmulateDSB", false } },
+#ifdef SUPERMODEL_WIN32
+ { "-no-force-feedback", { "ForceFeedback", false } },
+ { "-force-feedback", { "ForceFeedback", true } },
+#endif
+
+ };
+ for (int i = 1; i < argc; i++)
{
- printf(" %s", g_Model3GameList[i].id);
- for (j = strlen(g_Model3GameList[i].id); j < 9; j++) // pad for alignment (no game ID is more than 9 letters)
- printf(" ");
- printf(" %s\n", g_Model3GameList[i].title);
+ std::string arg(argv[i]);
+ if (arg[0] == '-')
+ {
+ // First, check maps
+ size_t idx_equals = arg.find_first_of('=');
+ if (idx_equals != std::string::npos)
+ {
+ std::string option(arg.begin(), arg.begin() + idx_equals);
+ std::string value(arg.begin() + idx_equals + 1, arg.end());
+ if (value.length() == 0)
+ {
+ ErrorLog("Argument to '%s' cannot be blank.", option.c_str());
+ continue;
+ }
+ auto it = valued_options.find(option);
+ if (it != valued_options.end())
+ {
+ const std::string &config_key = it->second;
+ cmd_line.config.Set(config_key, value);
+ continue;
+ }
+ }
+ else
+ {
+ auto it = bool_options.find(arg);
+ if (it != bool_options.end())
+ {
+ const std::string &config_key = it->second.first;
+ bool value = it->second.second;
+ cmd_line.config.Set(config_key, value);
+ continue;
+ }
+ else if (valued_options.find(arg) != valued_options.end())
+ {
+ ErrorLog("'%s' requires an argument.", argv[i]);
+ continue;
+ }
+ }
+ // Fell through -- handle special cases
+ if (arg == "-?" || arg == "-h" || arg == "-help" || arg == "--help")
+ cmd_line.show_help = true;
+ else if (arg == "-print-games")
+ cmd_line.print_games = true;
+ else if (arg == "-res" || arg.find("-res=") == 0)
+ {
+ std::vector parts = Util::Format(arg).Split('=');
+ if (parts.size() != 2)
+ ErrorLog("'-res' requires both a width and height (e.g., '-res=496,384').");
+ else
+ {
+ unsigned x, y;
+ if (2 == sscanf(&argv[i][4],"=%d,%d", &x, &y))
+ {
+ std::string xres = Util::Format() << x;
+ std::string yres = Util::Format() << y;
+ cmd_line.config.Set("XResolution", xres);
+ cmd_line.config.Set("YResolution", yres);
+ }
+ else
+ ErrorLog("'-res' requires both a width and height (e.g., '-res=496,384').");
+ }
+ }
+ else if (arg == "-print-gl-info")
+ cmd_line.print_gl_info = true;
+ else if (arg == "-config-inputs")
+ cmd_line.config_inputs = true;
+ else if (arg == "-print-inputs")
+ cmd_line.print_inputs = true;
+#ifdef SUPERMODEL_DEBUGGER
+ else if (arg == "-disable-debugger")
+ cmd_line.disable_debugger = true;
+ else if (arg == "-enter-debugger")
+ cmd_line.enter_debugger = true;
+#endif
+#ifdef DEBUG
+ else if (arg == "-gfx-state")
+ {
+ std::vector parts = Util::Format(arg).Split('=');
+ if (parts.size() != 2)
+ ErrorLog("'-gfx-state' requires a file name.");
+ else
+ cmd_line.gfx_state = parts[1];
+ }
+#endif
+ else
+ ErrorLog("Ignoring unrecognized option: %s", argv[i]);
+ }
+ else
+ cmd_line.rom_files.emplace_back(arg);
}
+ return cmd_line;
}
/*
@@ -1514,10 +1528,6 @@ int main(int argc, char **argv)
#ifdef SUPERMODEL_DEBUGGER
bool cmdEnterDebugger = false;
#endif // SUPERMODEL_DEBUGGER
- char *inputSystem = NULL; // use default input system
- char *outputs = NULL;
- unsigned num_instructions;
- uint32_t addr;
Title();
if (argc <= 1)
@@ -1530,295 +1540,59 @@ int main(int argc, char **argv)
CFileLogger Logger(DEBUG_LOG_FILE, ERROR_LOG_FILE);
Logger.ClearLogs();
SetLogger(&Logger);
-
- // Log the command line used to start Supermodel
InfoLog("Started as:");
for (int i = 0; i < argc; i++)
- InfoLog("\targv[%d] = %s", i, argv[i]);
+ InfoLog(" argv[%d] = %s", i, argv[i]);
InfoLog("");
- // Read global settings from INI file
- ReadConfigFile("Global");
-
- /*
- * Parse command line.
- *
- * Settings are stored in CmdLine so that they can be applied later, after
- * game-specific settings are read from the configuration file (which
- * requires the ROM set to be identified and therefore is done later).
- *
- * Some commands are processed here directly.
- */
- int fileIdx = 0;
- bool cmdPrintInputs = false;
- bool cmdConfigInputs = false;
- bool cmdDis = false;
- CINIFile CmdLine; // not associated with any files, only holds command line options
- CmdLine.SetDefaultSectionName("Global"); // command line settings are global-level
- for (int i = 1; i < argc; i++)
+ // Load config and parse command line
+ auto cmd_line = ParseCommandLine(argc, argv);
+ if (cmd_line.print_gl_info)
{
- if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-?") || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help"))
- {
- Help();
- return 0;
- }
- else if (!strcmp(argv[i], "-print-games"))
- {
- PrintGameList();
- return 0;
- }
- else if (!strncmp(argv[i], "-ppc-frequency", 14))
- {
- int f;
- int ret = sscanf(&argv[i][14], "=%d", &f);
- if (ret != 1)
- ErrorLog("'-ppc-frequency' requires a frequency.");
- else
- CmdLine.Set("Global", "PowerPCFrequency", f);
- }
- else if (!strcmp(argv[i], "-no-threads"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "MultiThreaded", n);
- }
- else if (!strcmp(argv[i], "-gpu-multi-threaded"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "GPUMultiThreaded", n);
- }
- else if (!strcmp(argv[i], "-no-gpu-thread"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "GPUMultiThreaded", n);
- }
-#ifdef SUPERMODEL_DEBUGGER
- else if (!strcmp(argv[i], "-disable-debugger"))
- g_Config.disableDebugger = true;
- else if (!strcmp(argv[i], "-enter-debugger"))
- cmdEnterDebugger = true;
-#endif // SUPERMODEL_DEBUGGER
- else if (!strncmp(argv[i], "-sound-volume", 13))
- {
- unsigned n;
- int ret = sscanf(&argv[i][13],"=%d", &n);
- if (ret != 1)
- ErrorLog("'-sound-volume' requires a volume setting.");
- else
- CmdLine.Set("Global", "SoundVolume", n);
- }
- else if (!strncmp(argv[i], "-music-volume", 13))
- {
- unsigned n;
- int ret = sscanf(&argv[i][13],"=%d", &n);
- if (ret != 1)
- ErrorLog("'-music-volume' requires a volume setting.");
- else
- CmdLine.Set("Global", "MusicVolume", n);
- }
- else if (!strncmp(argv[i], "-balance", 8))
- {
- unsigned n;
- int ret = sscanf(&argv[i][8], "=%d", &n);
- if (ret != 1)
- ErrorLog("'-balance' requires a front/rear balance setting.");
- else
- CmdLine.Set("Global", "Balance", n);
- }
- else if (!strcmp(argv[i], "-flip-stereo"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "FlipStereo", n);
- }
- else if (!strcmp(argv[i], "-no-sound"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "EmulateSound", n);
- }
- else if (!strcmp(argv[i], "-no-dsb"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "EmulateDSB", n);
- }
-#ifdef SUPERMODEL_WIN32
- else if (!strcmp(argv[i], "-force-feedback"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "ForceFeedback", n);
- }
-#endif
- else if (!strncmp(argv[i], "-res", 4))
- {
- unsigned x, y;
-
- int ret = sscanf(&argv[i][4],"=%d,%d", &x, &y);
- if (ret != 2)
- {
- ret = sscanf(&argv[i][4],"=%dx%d", &x, &y);
- if (ret != 2)
- ErrorLog("'-res' requires both a width and a height.");
- }
- if (ret == 2)
- {
- CmdLine.Set("Global", "XResolution", x);
- CmdLine.Set("Global", "YResolution", y);
- }
- }
- else if (!strcmp(argv[i], "-window"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "FullScreen", n);
- }
- else if (!strcmp(argv[i], "-fullscreen"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "FullScreen", n);
- }
- else if (!strcmp(argv[i], "-wide-screen"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "WideScreen", n);
- }
- else if (!strcmp(argv[i], "-multi-texture"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "MultiTexture", n);
- }
- else if (!strcmp(argv[i], "-no-multi-texture"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "MultiTexture", n);
- }
- else if (!strcmp(argv[i], "-vsync"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "VSync", n);
- }
- else if (!strcmp(argv[i], "-no-vsync"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "VSync", n);
- }
- else if (!strcmp(argv[i], "-no-throttle"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "Throttle", n);
- }
- else if (!strcmp(argv[i], "-show-fps"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "ShowFrameRate", n);
- }
- else if (!strncmp(argv[i], "-crosshairs", 11))
- {
- unsigned x;
- int ret = sscanf(&argv[i][11],"=%d", &x);
- if (ret != 1 || x > 3)
- ErrorLog("'-crosshairs' requires a number 0-3");
- else
- CmdLine.Set("Global", "Crosshairs", x);
- }
- else if (!strcmp(argv[i], "-new3d"))
- {
- unsigned n = 1;
- CmdLine.Set("Global", "New3DEngine", n);
- }
- else if (!strcmp(argv[i], "-legacy3d"))
- {
- unsigned n = 0;
- CmdLine.Set("Global", "New3DEngine", n);
- }
- else if (!strncmp(argv[i], "-vert-shader", 12))
- {
- if (argv[i][12] == '\0')
- ErrorLog("'-vert-shader' requires a file path.");
- else if (argv[i][12] != '=')
- ErrorLog("Ignoring unrecognized option: %s", argv[i]);
- else if (argv[i][13] == '\0')
- ErrorLog("'-vert-shader' requires a file path.");
- else
- CmdLine.Set("Global", "VertexShader", &argv[i][13]);
- }
- else if (!strncmp(argv[i], "-frag-shader", 12))
- {
- if (argv[i][12] == '\0')
- ErrorLog("'-frag-shader' requires a file path.");
- else if (argv[i][12] != '=')
- ErrorLog("Ignoring unrecognized option: %s", argv[i]);
- else if (argv[i][13] == '\0')
- ErrorLog("'-frag-shader' requires a file path.");
- else
- CmdLine.Set("Global", "FragmentShader", &argv[i][13]);
- }
-#ifdef SUPERMODEL_WIN32
- else if (!strncmp(argv[i], "-input-system", 13)) // this setting is not written to the config file!
- {
- if (argv[i][13] == '\0')
- ErrorLog("'-input-system' requires an input system name.");
- else if (argv[i][13] != '=')
- ErrorLog("Ignoring unrecognized option: %s", argv[i]);
- else if (argv[i][14] == '\0')
- ErrorLog("'-input-system' requires an input system name.");
- else
- inputSystem = &argv[i][14];
- }
- else if (!strncmp(argv[i], "-outputs", 8)) // this setting is not written to the config file!
- {
- if (argv[i][8] == '\0')
- ErrorLog("'-outputs' requires an outputs name.");
- else if (argv[i][8] != '=')
- ErrorLog("Ignoring unrecognized option: %s", argv[i]);
- else if (argv[i][9] == '\0')
- ErrorLog("'-outputs' requires an outputs name.");
- else
- outputs = &argv[i][9];
- }
-#endif // SUPERMODEL_WIN32
- else if (!strcmp(argv[i], "-print-inputs"))
- cmdPrintInputs = true;
- else if (!strcmp(argv[i], "-config-inputs"))
- cmdConfigInputs = true;
- else if (!strncmp(argv[i], "-dis", 4))
- {
- int ret = sscanf(&argv[i][4],"=%X,%X", &addr, &num_instructions);
- if (ret == 1)
- {
- num_instructions = 16;
- cmdDis = true;
- }
- else if (ret == 2)
- cmdDis = true;
- else
- ErrorLog("'-dis' requires address and, optionally, number of instructions.");
- }
- else if (!strcmp(argv[i], "-print-gl-info"))
- {
- PrintGLInfo(true, false, false);
- return 0;
- }
-#ifdef DEBUG
- else if (!strncmp(argv[i], "-gfx-state", 10))
- {
- if (argv[i][10] == '\0')
- ErrorLog("'-gfx-state' requires a file path.");
- else if (argv[i][10] != '=')
- ErrorLog("Ignoring unrecognized option: %s", argv[i]);
- else if (argv[i][10] == '\0')
- ErrorLog("'-gfx-state' requires a file path.");
- else
- s_gfxStatePath.assign(&argv[i][11]);
- }
-#endif
- else if (argv[i][0] == '-')
- ErrorLog("Ignoring unrecognized option: %s", argv[i]);
- else
- {
- if (fileIdx) // already specified a file
- ErrorLog("Multiple files specified. Using '%s', ignoring '%s'.", argv[fileIdx], argv[i]);
- else
- fileIdx = i;
- }
+ PrintGLInfo(true, false, false);
+ return 0;
}
-
+#ifdef DEBUG
+ s_gfxStatePath.assign(cmd_line.gfx_state);
+#endif
+ bool print_games = cmd_line.print_games;
+ bool rom_specified = !cmd_line.rom_files.empty();
+ if (!rom_specified && !print_games && !cmd_line.config_inputs)
+ {
+ ErrorLog("No ROM file specified.");
+ return 0;
+ }
+
+ // Load game and resolve run-time config
+ Game game;
+ ROMSet rom_set;
+ Util::Config::Node fileConfig("Global");
+ Util::Config::Node fileConfigWithDefaults("Global");
+ {
+ Util::Config::Node config3("Global");
+ Util::Config::Node config4("Global");
+ Util::Config::FromINIFile(&fileConfig, s_configFilePath);
+ Util::Config::MergeINISections(&fileConfigWithDefaults, DefaultConfig(), fileConfig); // apply .ini file's global section over defaults
+ Util::Config::MergeINISections(&config3, fileConfigWithDefaults, cmd_line.config); // apply command line overrides
+ if (rom_specified || print_games)
+ {
+ std::string xml_file = config3["GameXMLFile"].ValueAs();
+ GameLoader loader(xml_file);
+ if (print_games)
+ {
+ PrintGameList(xml_file, loader.GetGames());
+ return 0;
+ }
+ if (loader.Load(&game, &rom_set, *cmd_line.rom_files.begin()))
+ return 1;
+ Util::Config::MergeINISections(&config4, config3, fileConfig[game.name]); // apply game-specific config
+ }
+ else
+ config4 = config3;
+ Util::Config::MergeINISections(&s_runtime_config, config4, cmd_line.config); // apply command line overrides once more
+ }
+ LogConfig(s_runtime_config);
+
// Initialize SDL (individual subsystems get initialized later)
if (SDL_Init(0) != 0)
{
@@ -1828,9 +1602,9 @@ int main(int argc, char **argv)
// Create Model 3 emulator
#ifdef DEBUG
- IEmulator *Model3 = s_gfxStatePath.empty() ? static_cast(new CModel3()) : static_cast(new CModel3GraphicsState(s_gfxStatePath));
+ IEmulator *Model3 = s_gfxStatePath.empty() ? static_cast(new CModel3(s_runtime_config)) : static_cast(new CModel3GraphicsState(s_gfxStatePath));
#else
- IEmulator *Model3 = new CModel3();
+ IEmulator *Model3 = new CModel3(s_runtime_config);
#endif
// Create input system (default is SDL) and debugger
@@ -1843,20 +1617,22 @@ int main(int argc, char **argv)
#endif // SUPERMODEL_DEBUGGER
// Create input system
- g_Config.SetInputSystem(inputSystem);
- if (stricmp(g_Config.GetInputSystem(), "sdl") == 0)
+ // NOTE: fileConfigWithDefaults is passed so that the global section is used
+ // for input settings with default values populated
+ std::string selectedInputSystem = s_runtime_config["InputSystem"].ValueAs();
+ if (selectedInputSystem == "sdl")
InputSystem = new CSDLInputSystem();
#ifdef SUPERMODEL_WIN32
- else if (stricmp(g_Config.GetInputSystem(), "dinput") == 0)
- InputSystem = new CDirectInputSystem(false, false);
- else if (stricmp(g_Config.GetInputSystem(), "xinput") == 0)
- InputSystem = new CDirectInputSystem(false, true);
- else if (stricmp(g_Config.GetInputSystem(), "rawinput") == 0)
- InputSystem = new CDirectInputSystem(true, false);
+ else if (selectedInputSystem == "dinput")
+ InputSystem = new CDirectInputSystem(fileConfigWithDefaults, false, false);
+ else if (selectedInputSystem == "xinput")
+ InputSystem = new CDirectInputSystem(fileConfigWithDefaults, false, true);
+ else if (selectedInputSystem == "rawinput")
+ InputSystem = new CDirectInputSystem(fileConfigWithDefaults, true, false);
#endif // SUPERMODEL_WIN32
else
{
- ErrorLog("Unknown input system: %s\n", g_Config.GetInputSystem());
+ ErrorLog("Unknown input system: %s\n", selectedInputSystem.c_str());
exitCode = 1;
goto Exit;
}
@@ -1870,30 +1646,38 @@ int main(int argc, char **argv)
goto Exit;
}
- if (ConfigureInputs(Inputs, cmdConfigInputs))
+ // NOTE: fileConfig is passed so that the global section is used for input settings
+ // and because this function may write out a new config file, which must preserve
+ // all sections. We don't want to pollute the output with built-in defaults.
+ if (ConfigureInputs(Inputs, &fileConfig, cmd_line.config_inputs))
{
exitCode = 1;
goto Exit;
}
- if (cmdPrintInputs)
+ if (cmd_line.print_inputs)
{
Inputs->PrintInputs(NULL);
InputSystem->PrintSettings();
}
+
+ if (!rom_specified)
+ goto Exit;
// Create outputs
#ifdef SUPERMODEL_WIN32
- g_Config.SetOutputs(outputs);
- if (stricmp(g_Config.GetOutputs(), "none") == 0)
- Outputs = NULL;
- else if (stricmp(g_Config.GetOutputs(), "win") == 0)
- Outputs = new CWinOutputs();
- else
{
- ErrorLog("Unknown outputs: %s\n", g_Config.GetOutputs());
- exitCode = 1;
- goto Exit;
+ std::string outputs = s_runtime_config["Outputs"].ValueAs();
+ if (outputs == "none")
+ Outputs = NULL;
+ else if (outputs == "win")
+ Outputs = new CWinOutputs();
+ else
+ {
+ ErrorLog("Unknown outputs: %s\n", outputs.c_str());
+ exitCode = 1;
+ goto Exit;
+ }
}
#endif // SUPERMODEL_WIN32
@@ -1905,24 +1689,9 @@ int main(int argc, char **argv)
goto Exit;
}
- // From this point onwards, a ROM set is needed
- if (fileIdx == 0)
- {
- ErrorLog("No ROM set specified.");
- exitCode = 1;
- goto Exit;
- }
-
- if (cmdDis)
- {
- if (OKAY != DisassembleCROM(argv[fileIdx], addr, num_instructions))
- exitCode = 1;
- goto Exit;
- }
-
#ifdef SUPERMODEL_DEBUGGER
// Create Supermodel debugger unless debugging is disabled
- if (!g_Config.disableDebugger)
+ if (!cmd_line.disable_debugger)
{
Debugger = new Debugger::CSupermodelDebugger(dynamic_cast(Model3), Inputs, &Logger);
// If -enter-debugger option was set force debugger to break straightaway
@@ -1930,12 +1699,12 @@ int main(int argc, char **argv)
Debugger->ForceBreak(true);
}
// Fire up Supermodel with debugger
- exitCode = Supermodel(argv[fileIdx], Model3, Inputs, Outputs, Debugger, &CmdLine);
+ exitCode = Supermodel(game, &rom_set, Model3, Inputs, Outputs, Debugger);
if (Debugger != NULL)
delete Debugger;
#else
// Fire up Supermodel
- exitCode = Supermodel(argv[fileIdx], Model3, Inputs, Outputs, &CmdLine);
+ exitCode = Supermodel(game, &rom_set, Model3, Inputs, Outputs);
#endif // SUPERMODEL_DEBUGGER
delete Model3;
diff --git a/Src/OSD/SDL/OSDConfig.h b/Src/OSD/SDL/OSDConfig.h
deleted file mode 100644
index cec2b1b..0000000
--- a/Src/OSD/SDL/OSDConfig.h
+++ /dev/null
@@ -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 .
- **/
-
-/*
- * OSDConfig.h
- *
- * Header file defining the COSDConfig class: OSD configuration settings,
- * inherited by CConfig.
- */
-
-#ifndef INCLUDED_OSDCONFIG_H
-#define INCLUDED_OSDCONFIG_H
-
-
-#include
-#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
diff --git a/Src/OSD/SDL/SDLInputSystem.cpp b/Src/OSD/SDL/SDLInputSystem.cpp
index 02325e1..6d9164d 100644
--- a/Src/OSD/SDL/SDLInputSystem.cpp
+++ b/Src/OSD/SDL/SDLInputSystem.cpp
@@ -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)
{
//
}
diff --git a/Src/OSD/Windows/DirectInputSystem.cpp b/Src/OSD/Windows/DirectInputSystem.cpp
index 352633c..d607103 100644
--- a/Src/OSD/Windows/DirectInputSystem.cpp
+++ b/Src/OSD/Windows/DirectInputSystem.cpp
@@ -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();
+ 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() / 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();
+ 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();
+ 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(lFFMag, -DI_EFFECTS_MAX);
}
else
{
- if (g_Config.dInputConstForceLeftMax == 0)
+ unsigned dInputConstForceLeftMax = m_config["DirectInputConstForceLeftMax"].ValueAs();
+ 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(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();
//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(0, std::min(lFFMag, DI_EFFECTS_MAX));
dic.lNegativeCoefficient = std::max(0, std::min(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();
//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(0, std::min(lFFMag, DI_EFFECTS_MAX));
dic.lNegativeCoefficient = std::max(0, std::min(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();
//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(0, std::min(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;
diff --git a/Src/OSD/Windows/DirectInputSystem.h b/Src/OSD/Windows/DirectInputSystem.h
index 3ebf3a8..2b03976 100644
--- a/Src/OSD/Windows/DirectInputSystem.h
+++ b/Src/OSD/Windows/DirectInputSystem.h
@@ -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();
diff --git a/Src/OSD/Windows/WinOutputs.cpp b/Src/OSD/Windows/WinOutputs.cpp
index 598a8b5..7f48f47 100755
--- a/Src/OSD/Windows/WinOutputs.cpp
+++ b/Src/OSD/Windows/WinOutputs.cpp
@@ -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;
diff --git a/Src/Sound/SCSP.cpp b/Src/Sound/SCSP.cpp
index c6f0ff1..fb5c3d6 100644
--- a/Src/Sound/SCSP.cpp
+++ b/Src/Sound/SCSP.cpp
@@ -57,6 +57,9 @@
#include
#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();
+
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();
+ 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;
diff --git a/Src/Sound/SCSP.h b/Src/Sound/SCSP.h
index 802729a..4ce759a 100644
--- a/Src/Sound/SCSP.h
+++ b/Src/Sound/SCSP.h
@@ -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();
diff --git a/Src/Supermodel.h b/Src/Supermodel.h
index 3249419..ff8ace5 100644
--- a/Src/Supermodel.h
+++ b/Src/Supermodel.h
@@ -97,9 +97,6 @@
// Error logging interface
#include "OSD/Logger.h"
-// OSD configuration
-#include "OSDConfig.h" // located in OSD// 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"
/******************************************************************************