diff --git a/Makefiles/Makefile.OSX b/Makefiles/Makefile.OSX
index bb07732..1d23d1c 100644
--- a/Makefiles/Makefile.OSX
+++ b/Makefiles/Makefile.OSX
@@ -72,6 +72,9 @@ PLATFORM_LDFLAGS = $(SDL_LIBS) -lz -lm -lstdc++ -F/Library/Frameworks/
###############################################################################
# Core Makefile
###############################################################################
+
+PLATFORM_SRC_FILES = \
+ Src/OSD/OSX/FileSystemPath.cpp
include Makefiles/Rules.inc
diff --git a/Makefiles/Makefile.UNIX b/Makefiles/Makefile.UNIX
index d499234..1e48361 100644
--- a/Makefiles/Makefile.UNIX
+++ b/Makefiles/Makefile.UNIX
@@ -69,6 +69,9 @@ PLATFORM_LDFLAGS = $(SDL2_LIBS) -lGL -lGLU -lz -lm -lstdc++ -lpthread -lSDL2_net
###############################################################################
# Core Makefile
###############################################################################
+
+PLATFORM_SRC_FILES = \
+ Src/OSD/Unix/FileSystemPath.cpp
include Makefiles/Rules.inc
diff --git a/Makefiles/Makefile.Win32 b/Makefiles/Makefile.Win32
index 3e86534..0d984dc 100644
--- a/Makefiles/Makefile.Win32
+++ b/Makefiles/Makefile.Win32
@@ -103,6 +103,7 @@ PLATFORM_LDFLAGS = -static -L$(sort $(PLATFORM_LIB_DIR)) $(SDL2_LIBS) $(PLATFORM
PLATFORM_SRC_FILES = \
Src/OSD/Windows/DirectInputSystem.cpp \
+ Src/OSD/Windows/FileSystemPath.cpp \
Src/OSD/Windows/WinOutputs.cpp
.PHONY: clean
diff --git a/Src/OSD/FileSystemPath.h b/Src/OSD/FileSystemPath.h
new file mode 100644
index 0000000..3c04b62
--- /dev/null
+++ b/Src/OSD/FileSystemPath.h
@@ -0,0 +1,41 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2003-2022 The Supermodel Team
+ **
+ ** 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 .
+ **/
+
+/*
+ * FileSystemPaths.h
+ *
+ * Header file for OS-dependent Supermodel files locations.
+ */
+
+#ifndef INCLUDED_FILESYSTEMPATH_H
+#define INCLUDED_FILESYSTEMPATH_H
+
+#include
+
+namespace FileSystemPath
+{
+ enum PathType { Analysis, Config, Log, NVRAM, Saves, Screenshots }; // Filesystem path types
+ bool PathExists(std::string fileSystemPath); // Checks if a directory exists (returns true if exists, false if it doesn't)
+ std::string GetPath(PathType pathType); // Generates a path to be used by Supermodel files
+}
+
+
+#endif // INCLUDED_FILESYSTEMPATH_H
diff --git a/Src/OSD/OSX/FileSystemPath.cpp b/Src/OSD/OSX/FileSystemPath.cpp
new file mode 100644
index 0000000..9536d27
--- /dev/null
+++ b/Src/OSD/OSX/FileSystemPath.cpp
@@ -0,0 +1,46 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2003-2022 The Supermodel Team
+ **
+ ** 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 .
+ **/
+
+#include "FileSystemPath.h"
+#include
+
+namespace FileSystemPath
+{
+ // Generates a path to be used by Supermodel files
+ std::string GetPath(PathType pathType)
+ {
+ switch (pathType)
+ {
+ case Analysis:
+ return "Analysis/";
+ case Config:
+ return "Config/";
+ case Log:
+ return "";
+ case NVRAM:
+ return "NVRAM/";
+ case Saves:
+ return "Saves/";
+ case Screenshots:
+ return "";
+ }
+ }
+}
diff --git a/Src/OSD/SDL/Audio.cpp b/Src/OSD/SDL/Audio.cpp
index dc626d3..ca132f2 100755
--- a/Src/OSD/SDL/Audio.cpp
+++ b/Src/OSD/SDL/Audio.cpp
@@ -142,30 +142,6 @@ void SetAudioType(Game::AudioTypes type)
AudioType = type;
}
-static INT16 AddAndClampINT16(INT32 x, INT32 y)
-{
- INT32 sum = x + y;
- if (sum > INT16_MAX) {
- sum = INT16_MAX;
- }
- if (sum < INT16_MIN) {
- sum = INT16_MIN;
- }
- return (INT16)sum;
-}
-
-static INT16 MixINT16(INT32 x, INT32 y)
-{
- INT32 sum = (x + y)>>1;
- if (sum > INT16_MAX) {
- sum = INT16_MAX;
- }
- if (sum < INT16_MIN) {
- sum = INT16_MIN;
- }
- return (INT16)sum;
-}
-
static INT16 MixINT16(float x, float y)
{
INT32 sum = (INT32)((x + y)*0.5f); //!! dither
@@ -185,7 +161,7 @@ static float MixFloat(float x, float y)
static INT16 ClampINT16(float x)
{
- INT32 xi = (INT32)x;
+ INT32 xi = (INT32)x; //!! dither
if (xi > INT16_MAX) {
xi = INT16_MAX;
}
diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp
index e0267e9..5562543 100644
--- a/Src/OSD/SDL/Main.cpp
+++ b/Src/OSD/SDL/Main.cpp
@@ -66,6 +66,7 @@
#include "Util/Format.h"
#include "Util/NewConfig.h"
#include "Util/ConfigBuilders.h"
+#include "OSD/FileSystemPath.h"
#include "GameLoader.h"
#include "SDLInputSystem.h"
#include "SDLIncludes.h"
@@ -470,15 +471,24 @@ static void SaveFrameBuffer(const std::string& file)
void Screenshot()
{
// Make a screenshot
- char file[128];
- std::string info = "Screenshot created: ";
time_t now = std::time(nullptr);
tm* ltm = std::localtime(&now);
+ std::string file = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Screenshots)
+ << "Screenshot_"
+ << std::setfill('0') << std::setw(4) << (1900 + ltm->tm_year)
+ << '-'
+ << std::setw(2) << (1 + ltm->tm_mon)
+ << '-'
+ << std::setw(2) << ltm->tm_mday
+ << "_("
+ << std::setw(2) << ltm->tm_hour
+ << '-'
+ << std::setw(2) << ltm->tm_min
+ << '-'
+ << std::setw(2) << ltm->tm_sec
+ << ").bmp";
- sprintf(file, "Screenshot %.4d-%.2d-%.2d (%.2d-%.2d-%.2d).bmp", 1900 + ltm->tm_year, 1 + ltm->tm_mon, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
-
- info += file;
- puts(info.c_str());
+ std::cout << "Screenshot created: " << file << std::endl;
SaveFrameBuffer(file);
}
@@ -549,7 +559,7 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
if ((unknownPolyBits[idx] & mask))
{
Emu->RenderFrame();
- std::string file = Util::Format() << "Analysis/" << GetFileBaseName(s_gfxStatePath) << "." << "poly" << "." << idx << "_" << Util::Hex(mask) << ".bmp";
+ std::string file = Util::Format() << s_analysisPath << GetFileBaseName(s_gfxStatePath) << "." << "poly" << "." << idx << "_" << Util::Hex(mask) << ".bmp";
SaveFrameBuffer(file);
}
}
@@ -565,7 +575,7 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
if ((unknownCullingNodeBits[idx] & mask))
{
Emu->RenderFrame();
- std::string file = Util::Format() << "Analysis/" << GetFileBaseName(s_gfxStatePath) << "." << "culling" << "." << idx << "_" << Util::Hex(mask) << ".bmp";
+ std::string file = Util::Format() << s_analysisPath << GetFileBaseName(s_gfxStatePath) << "." << "culling" << "." << idx << "_" << Util::Hex(mask) << ".bmp";
SaveFrameBuffer(file);
}
}
@@ -574,7 +584,7 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
glReadBuffer(readBuffer);
// Generate the HTML GUI
- std::string file = Util::Format() << "Analysis/_" << GetFileBaseName(s_gfxStatePath) << ".html";
+ std::string file = Util::Format() << s_analysisPath << "_" << GetFileBaseName(s_gfxStatePath) << ".html";
std::ofstream fs(file);
if (!fs.good())
ErrorLog("Unable to open '%s' for writing.", file.c_str());
@@ -615,7 +625,7 @@ static void SaveState(IEmulator *Model3)
{
CBlockFile SaveState;
- std::string file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
+ std::string file_path = Util::Format() << FileSystemPath::GetPath(FileSystemPath::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'.", file_path.c_str());
@@ -640,7 +650,7 @@ static void LoadState(IEmulator *Model3, std::string file_path = std::string())
// Generate file path
if (file_path.empty())
- file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
+ file_path = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Saves) << Model3->GetGame().name << ".st" << s_saveSlot;
// Open and check to make sure format is correct
if (OKAY != SaveState.Load(file_path))
@@ -674,7 +684,7 @@ static void SaveNVRAM(IEmulator *Model3)
{
CBlockFile NVRAM;
- std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
+ std::string file_path = Util::Format() << FileSystemPath::GetPath(FileSystemPath::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!", file_path.c_str());
@@ -697,7 +707,7 @@ static void LoadNVRAM(IEmulator *Model3)
CBlockFile NVRAM;
// Generate file path
- std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
+ std::string file_path = Util::Format() << FileSystemPath::GetPath(FileSystemPath::NVRAM) << Model3->GetGame().name << ".nv";
// Open and check to make sure format is correct
if (OKAY != NVRAM.Load(file_path))
@@ -1448,8 +1458,10 @@ QuitError:
Entry Point and Command Line Procesing
******************************************************************************/
-static const char s_configFilePath[] = { "Config/Supermodel.ini" };
-static const char s_gameXMLFilePath[] = { "Config/Games.xml" };
+static const std::string s_analysisPath = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Analysis);
+static const std::string s_configFilePath = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Config) << "Supermodel.ini";
+static const std::string s_gameXMLFilePath = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Config) << "Games.xml";
+static const std::string s_logFilePath = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Log) << "Supermodel.log";
// Create and configure inputs
static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *fileConfig, Util::Config::Node *runtimeConfig, const Game &game, bool configure)
@@ -1640,8 +1652,8 @@ static void Help(void)
puts("General Options:");
puts(" -?, -h, -help, --help Print this help text");
puts(" -print-games List supported games and quit");
- printf(" -game-xml-file= ROM set definition file [Default: %s]\n", s_gameXMLFilePath);
- puts(" -log-output= Log output destination(s) [Default: Supermodel.log]");
+ printf(" -game-xml-file= ROM set definition file [Default: %s]\n", s_gameXMLFilePath.c_str());
+ printf(" -log-output= Log output destination(s) [Default: %s]\n", s_logFilePath.c_str());
puts(" -log-level= Logging threshold [Default: info]");
puts("");
puts("Core Options:");
@@ -1737,7 +1749,7 @@ struct ParsedCommandLine
{
// Logging is special: it is only parsed from the command line and
// therefore, defaults are needed early
- config.Set("LogOutput", "Supermodel.log");
+ config.Set("LogOutput", s_logFilePath.c_str());
config.Set("LogLevel", "info");
}
};
diff --git a/Src/OSD/Unix/FileSystemPath.cpp b/Src/OSD/Unix/FileSystemPath.cpp
new file mode 100644
index 0000000..4ab5916
--- /dev/null
+++ b/Src/OSD/Unix/FileSystemPath.cpp
@@ -0,0 +1,162 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2003-2022 The Supermodel Team
+ **
+ ** 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 .
+ **/
+
+#include "FileSystemPath.h"
+#include "Util/Format.h"
+#include
+#include
+#include
+#include
+#include
+
+namespace FileSystemPath
+{
+ // Checks if a directory exists (returns true if exists, false if it doesn't)
+ bool PathExists(std::string fileSystemPath)
+ {
+ bool pathExists = false;
+ struct stat pathInfo;
+
+ if (stat(fileSystemPath.c_str(), &pathInfo) == 0 && S_ISDIR(pathInfo.st_mode))
+ {
+ pathExists = true;
+ }
+
+ return pathExists;
+
+ }
+
+ // Generates a path to be used by Supermodel files
+ std::string GetPath(PathType pathType)
+ {
+ std::string finalPath = "";
+ std::string homePath = "";
+ std::string strPathType = "";
+ struct passwd* pwd = getpwuid(getuid());
+
+ // Resolve pathType to string for later use
+ switch (pathType)
+ {
+ case Analysis:
+ strPathType = "Analysis";
+ break;
+ case Config:
+ strPathType = "Config";
+ break;
+ case Log:
+ strPathType = "Log";
+ break;
+ case NVRAM:
+ strPathType = "NVRAM";
+ break;
+ case Saves:
+ strPathType = "Saves";
+ break;
+ case Screenshots:
+ strPathType = "Screenshots";
+ break;
+ }
+
+ // Get user's HOME directory
+ if (pwd)
+ {
+ homePath = pwd->pw_dir;
+ }
+ else
+ {
+ homePath = getenv("HOME");
+ }
+
+ // If Config path exists in current directory or the user doesn't have a HOME directory use current directory
+ if (FileSystemPath::PathExists("Config") || homePath.empty())
+ {
+ // Use current directory
+ if (pathType == Screenshots || pathType == Log)
+ {
+ finalPath = "";
+ }
+ else
+ {
+ // If directory doesn't exist, create it
+ if (!FileSystemPath::PathExists(strPathType))
+ {
+ mkdir(strPathType.c_str(), 0775);
+ }
+ finalPath = strPathType;
+ }
+ }
+ // Check if $HOME/.supermodel exists
+ else if (FileSystemPath::PathExists(Util::Format() << homePath << "/.supermodel"))
+ {
+ // Use $HOME/.supermodel
+ finalPath = Util::Format() << homePath << "/.supermodel/" << strPathType;
+ // If directory doesn't exist, create it
+ if (!FileSystemPath::PathExists(finalPath))
+ {
+ mkdir(finalPath.c_str(), 0775);
+ }
+ }
+ // On Linux one may want to follow the XDG base directory specs (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
+ else
+ {
+ // Use $HOME/.config/supermodel or $HOME/.local/share/supermodel depending on the file type
+ if (pathType == Config)
+ {
+ finalPath = Util::Format() << homePath << "/.config/supermodel";
+ // If directory doesn't exist, create it
+ if (!FileSystemPath::PathExists(finalPath))
+ {
+ mkdir(finalPath.c_str(), 0775);
+ }
+ // If directory doesn't exist, create it
+ finalPath = Util::Format() << homePath << "/.config/supermodel/Config";
+ if (!FileSystemPath::PathExists(finalPath))
+ {
+ mkdir(finalPath.c_str(), 0775);
+ }
+ }
+ else
+ {
+ finalPath = Util::Format() << homePath << "/.local/share/supermodel";
+ // If directory doesn't exist, create it
+ if (!FileSystemPath::PathExists(finalPath))
+ {
+ mkdir(finalPath.c_str(), 0775);
+ }
+ // If directory doesn't exist, create it
+ finalPath = Util::Format() << homePath << "/.local/share/supermodel/" << strPathType;
+ if (!FileSystemPath::PathExists(finalPath))
+ {
+ mkdir(finalPath.c_str(), 0775);
+ }
+ }
+
+ }
+
+ if (finalPath != "")
+ {
+ finalPath = Util::Format() << finalPath << "/";
+ }
+
+ return finalPath;
+
+ }
+}
diff --git a/Src/OSD/Windows/FileSystemPath.cpp b/Src/OSD/Windows/FileSystemPath.cpp
new file mode 100644
index 0000000..9536d27
--- /dev/null
+++ b/Src/OSD/Windows/FileSystemPath.cpp
@@ -0,0 +1,46 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2003-2022 The Supermodel Team
+ **
+ ** 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 .
+ **/
+
+#include "FileSystemPath.h"
+#include
+
+namespace FileSystemPath
+{
+ // Generates a path to be used by Supermodel files
+ std::string GetPath(PathType pathType)
+ {
+ switch (pathType)
+ {
+ case Analysis:
+ return "Analysis/";
+ case Config:
+ return "Config/";
+ case Log:
+ return "";
+ case NVRAM:
+ return "NVRAM/";
+ case Saves:
+ return "Saves/";
+ case Screenshots:
+ return "";
+ }
+ }
+}
diff --git a/Src/Sound/MPEG/MpegAudio.cpp b/Src/Sound/MPEG/MpegAudio.cpp
index 2a49eaa..45e8c68 100644
--- a/Src/Sound/MPEG/MpegAudio.cpp
+++ b/Src/Sound/MPEG/MpegAudio.cpp
@@ -132,5 +132,3 @@ void MpegDec::DecodeAudio(int16_t* left, int16_t* right, int numStereoSamples)
}
}
-
-
diff --git a/Src/Sound/SCSP.cpp b/Src/Sound/SCSP.cpp
index f150277..249fd8c 100644
--- a/Src/Sound/SCSP.cpp
+++ b/Src/Sound/SCSP.cpp
@@ -85,6 +85,7 @@ bool legacySound; // For LegacySound (SCSP DSP) config option.
#define MAX_SCSP 2
+//#define CORRECT_FOR_18BIT_DAC
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
static double SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
@@ -228,11 +229,11 @@ static int TimCnt[3];
int ARTABLE[64],DRTABLE[64];
//Envelope times in ms
-double ARTimes[64]={100000/*infinity*/,100000/*infinity*/,8100.0,6900.0,6000.0,4800.0,4000.0,3400.0,3000.0,2400.0,2000.0,1700.0,1500.0,
+static const double ARTimes[64] = {100000/*infinity*/,100000/*infinity*/,8100.0,6900.0,6000.0,4800.0,4000.0,3400.0,3000.0,2400.0,2000.0,1700.0,1500.0,
1200.0,1000.0,860.0,760.0,600.0,500.0,430.0,380.0,300.0,250.0,220.0,190.0,150.0,130.0,110.0,95.0,
76.0,63.0,55.0,47.0,38.0,31.0,27.0,24.0,19.0,15.0,13.0,12.0,9.4,7.9,6.8,6.0,4.7,3.8,3.4,3.0,2.4,
2.0,1.8,1.6,1.3,1.1,0.93,0.85,0.65,0.53,0.44,0.40,0.35,0.0,0.0};
-double DRTimes[64]={100000/*infinity*/,100000/*infinity*/,118200.0,101300.0,88600.0,70900.0,59100.0,50700.0,44300.0,35500.0,29600.0,25300.0,22200.0,17700.0,
+static const double DRTimes[64] = {100000/*infinity*/,100000/*infinity*/,118200.0,101300.0,88600.0,70900.0,59100.0,50700.0,44300.0,35500.0,29600.0,25300.0,22200.0,17700.0,
14800.0,12700.0,11100.0,8900.0,7400.0,6300.0,5500.0,4400.0,3700.0,3200.0,2800.0,2200.0,1800.0,1600.0,1400.0,1100.0,
920.0,790.0,690.0,550.0,460.0,390.0,340.0,270.0,230.0,200.0,170.0,140.0,110.0,98.0,85.0,68.0,57.0,49.0,43.0,34.0,
28.0,25.0,22.0,18.0,14.0,12.0,11.0,8.5,7.1,6.1,5.4,4.3,3.6,3.1};
@@ -719,10 +720,10 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
else
SDL=0.0;
- if(iSDL==0x6)
- int a=1;
- if(iTL==0x3a)
- int a=1;
+ //if(iSDL==0x6)
+ // int a=1;
+ //if(iTL==0x3a)
+ // int a=1;
LPANTABLE[i]=FIX((4.0*LPAN*TL*SDL));
RPANTABLE[i]=FIX((4.0*RPAN*TL*SDL));
@@ -1373,24 +1374,22 @@ signed int inline SCSP_UpdateSlot(_SLOT *slot)
//if (SSCTL(slot) == 0) {
if (PCM8B(slot)) //8 bit signed
{
- signed char *p1 = (signed char *) &(slot->base[addr1 ^ 1]);
- signed char *p2 = (signed char *) &(slot->base[addr2 ^ 1]);
+ signed char p1 = *(signed char *) &(slot->base[addr1 ^ 1]);
+ signed char p2 = *(signed char *) &(slot->base[addr2 ^ 1]);
int s;
signed int fpart = slot->cur_addr&((1 << SHIFT) - 1);
//sample=(p[0])<<8;
- s = (int)(p1[0] << 8)*((1 << SHIFT) - fpart) + (int)(p2[0] << 8)*fpart;
+ s = (int)(p1 << 8)*((1 << SHIFT) - fpart) + (int)(p2 << 8)*fpart;
sample = (s >> SHIFT);
}
else //16 bit signed (endianness?)
{
- signed short *p1 = (signed short *) &(slot->base[addr1]);
- signed short *p2 = (signed short *) &(slot->base[addr2]);
+ signed short p1 = *(signed short *) &(slot->base[addr1]);
+ signed short p2 = *(signed short *) &(slot->base[addr2]);
int s;
signed int fpart = slot->cur_addr&((1 << SHIFT) - 1);
//sample=(p[0]);
- s = (int)(p1[0])*((1 << (SHIFT)) - fpart) + (int)(p2[0])*fpart;
-
-
+ s = (int)(p1)*((1 << (SHIFT)) - fpart) + (int)(p2)*fpart;
sample = (s >> (SHIFT));
//sample=((p[0]>>8)&0xFF)|(p[0]<<8);
@@ -1498,6 +1497,11 @@ signed int inline SCSP_UpdateSlot(_SLOT *slot)
UINT16 Enc = ((TL(slot)) << 0x0) | (0x7 << 0xd);
*RBUFDST = (sample * LPANTABLE[Enc]) >> (SHIFT + 1);
}
+ else
+ {
+ UINT16 Enc = (0 << 0x0) | (0x7 << 0xd);
+ *RBUFDST = (sample * LPANTABLE[Enc]) >> (SHIFT + 1);
+ }
}
@@ -1667,14 +1671,23 @@ void SCSP_DoMasterSamples(int nsamples)
{
smpfl = ICLIP18(smpfl);
smpfr = ICLIP18(smpfr);
+
+#ifdef CORRECT_FOR_18BIT_DAC
+ *buffl++ = (float)smpfl * 0.25f;
+ *buffr++ = (float)smpfr * 0.25f;
+#else
+ *buffl++ = (float)smpfl;
+ *buffr++ = (float)smpfr;
+#endif
}
else
{
smpfl = ICLIP16(smpfl >> 2);
smpfr = ICLIP16(smpfr >> 2);
+
+ *buffl++ = (float)smpfl;
+ *buffr++ = (float)smpfr;
}
- *buffl++ = (float)smpfl;
- *buffr++ = (float)smpfr;
if (HasSlaveSCSP)
{
@@ -1682,15 +1695,29 @@ void SCSP_DoMasterSamples(int nsamples)
{
smprl = ICLIP18(smprl);
smprr = ICLIP18(smprr);
+
+#ifdef CORRECT_FOR_18BIT_DAC
+ *bufrl++ = (float)smprl * 0.25f;
+ *bufrr++ = (float)smprr * 0.25f;
+#else
+ *bufrl++ = (float)smprl;
+ *bufrr++ = (float)smprr;
+#endif
}
else
{
- smprl = ICLIP16(smprl >> 2);
+ smprl = ICLIP16(smprl >> 2);
smprr = ICLIP16(smprr >> 2);
+
+ *bufrl++ = (float)smprl;
+ *bufrr++ = (float)smprr;
}
}
- *bufrl++ = (float)smprl;
- *bufrr++ = (float)smprr;
+ else
+ {
+ *bufrl++ = (float)smprl;
+ *bufrr++ = (float)smprr;
+ }
SCSP_TimersAddTicks(1);
CheckPendingIRQ();
diff --git a/Src/Sound/SCSPDSP.cpp b/Src/Sound/SCSPDSP.cpp
index 2c8277c..e0c51bb 100644
--- a/Src/Sound/SCSPDSP.cpp
+++ b/Src/Sound/SCSPDSP.cpp
@@ -150,13 +150,10 @@ unsigned char UnpackFunc[]={0x8B,0xD8,0x8B,0xC8,0x81,0xE3,0x00,0x80,0x00,0x00,0x
static UINT16 PACK(INT32 val)
{
- UINT32 temp;
- int sign, exponent, k;
-
- sign = (val >> 23) & 0x1;
- temp = (val ^ (val << 1)) & 0xFFFFFF;
- exponent = 0;
- for (k = 0; k < 12; k++)
+ int sign = (val >> 23) & 0x1;
+ UINT32 temp = (val ^ (val << 1)) & 0xFFFFFF;
+ int exponent = 0;
+ for (int k = 0; k < 12; k++)
{
if (temp & 0x800000)
break;
@@ -177,13 +174,10 @@ static UINT16 PACK(INT32 val)
static INT32 UNPACK(UINT16 val)
{
- int sign, exponent, mantissa;
- INT32 uval;
-
- sign = (val >> 15) & 0x1;
- exponent = (val >> 11) & 0xF;
- mantissa = val & 0x7FF;
- uval = mantissa << 11;
+ int sign = (val >> 15) & 0x1;
+ int exponent = (val >> 11) & 0xF;
+ int mantissa = val & 0x7FF;
+ INT32 uval = mantissa << 11;
if (exponent > 11)
{
exponent = 11;
@@ -417,7 +411,7 @@ void SCSPDSP_Step(_SCSPDSP *DSP)
//ADDR+=DSP->RBP<<13;
//MEMVAL=DSP->SCSPRAM[ADDR>>1];
ADDR += DSP->RBP << 12;
- if (ADDR > 0x7ffff) ADDR = 0;
+ if (ADDR > 0x7ffff) ADDR = 0; //!! MAME has ADDR <<= 1 in here, but this seems to be wrong?
if (MRD && (step & 1)) //memory only allowed on odd? DoA inserts NOPs on even
{
if (NOFL)
diff --git a/Src/Sound/SCSPLFO.cpp b/Src/Sound/SCSPLFO.cpp
index ec484b4..c0d06cf 100644
--- a/Src/Sound/SCSPLFO.cpp
+++ b/Src/Sound/SCSPLFO.cpp
@@ -49,10 +49,13 @@ struct _LFO
static int PLFO_TRI[256], PLFO_SQR[256], PLFO_SAW[256], PLFO_NOI[256];
static int ALFO_TRI[256], ALFO_SQR[256], ALFO_SAW[256], ALFO_NOI[256];
-static float LFOFreq[32] = { 0.17f, 0.19f, 0.23f, 0.27f, 0.34f, 0.39f, 0.45f, 0.55f, 0.68f, 0.78f, 0.92f, 1.10f, 1.39f, 1.60f, 1.87f, 2.27f,
- 2.87f, 3.31f, 3.92f, 4.79f, 6.15f, 7.18f, 8.60f, 10.8f, 14.4f, 17.2f, 21.5f, 28.7f, 43.1f, 57.4f, 86.1f, 172.3f };
-static float ASCALE[8] = { 0.0f, 0.4f, 0.8f, 1.5f, 3.0f, 6.0f, 12.0f, 24.0f };
-static float PSCALE[8] = { 0.0f, 7.0f, 13.5f, 27.0f, 55.0f, 112.0f, 230.0f, 494.0f };
+static const float LFOFreq[32] =
+{
+ 0.17f,0.19f,0.23f,0.27f,0.34f,0.39f,0.45f,0.55f,0.68f,0.78f,0.92f,1.10f,1.39f,1.60f,1.87f,2.27f,
+ 2.87f,3.31f,3.92f,4.79f,6.15f,7.18f,8.60f,10.8f,14.4f,17.2f,21.5f,28.7f,43.1f,57.4f,86.1f,172.3f
+};
+static const float ASCALE[8] = {0.0f,0.4f,0.8f,1.5f,3.0f,6.0f,12.0f,24.0f};
+static const float PSCALE[8] = {0.0f,7.0f,13.5f,27.0f,55.0f,112.0f,230.0f,494.0f};
static int PSCALES[8][256];
static int ASCALES[8][256];
@@ -141,9 +144,9 @@ signed int inline ALFO_Step(struct _LFO *LFO)
{
int p;
LFO->phase += LFO->phase_step;
-#if LFO_SHIFT!=8
+#if LFO_SHIFT!=8
LFO->phase &= (1 << (LFO_SHIFT + 8)) - 1;
-#endif
+#endif
p = LFO->table[LFO->phase >> LFO_SHIFT];
p = LFO->scale[p];
return p << (SHIFT - LFO_SHIFT);
@@ -151,7 +154,7 @@ signed int inline ALFO_Step(struct _LFO *LFO)
void LFO_ComputeStep(struct _LFO *LFO, UINT32 LFOF, UINT32 LFOWS, UINT32 LFOS, int ALFO)
{
- float step = (float)LFOFreq[LFOF] * 256.0f / (float)44100.0f;
+ float step = (float)LFOFreq[LFOF] * 256.0f / 44100.0f;
LFO->phase_step = (unsigned int)((float)(1 << LFO_SHIFT)*step);
if (ALFO)
{
@@ -175,4 +178,4 @@ void LFO_ComputeStep(struct _LFO *LFO, UINT32 LFOF, UINT32 LFOWS, UINT32 LFOS, i
}
LFO->scale = PSCALES[LFOS];
}
-}
\ No newline at end of file
+}
diff --git a/VS2008/Supermodel.vcxproj b/VS2008/Supermodel.vcxproj
index e23a43d..068dd15 100644
--- a/VS2008/Supermodel.vcxproj
+++ b/VS2008/Supermodel.vcxproj
@@ -351,6 +351,7 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+
diff --git a/VS2008/Supermodel.vcxproj.filters b/VS2008/Supermodel.vcxproj.filters
index 496677b..e040fae 100644
--- a/VS2008/Supermodel.vcxproj.filters
+++ b/VS2008/Supermodel.vcxproj.filters
@@ -257,6 +257,9 @@
Source Files\OSD\Windows
+
+ Source Files\OSD\Windows
+
Source Files\Pkgs