From db455ba5c1c5a47a9f0a7de46680377f13f663e5 Mon Sep 17 00:00:00 2001 From: toxieainc Date: Tue, 8 Nov 2022 08:11:14 +0100 Subject: [PATCH 1/7] add undefd codepath for correct use of the 18bit DAC path (which seems to be triggered for all games) the volume correction to bring the data back into a valid range is not really needed in practice though, only Daytona2 seems to need it, and also only extremely rarely, so lets just live with a tiny bit of clamping for that game then while add it, make some formatting similar to MAME, and add one comment regarding a most likely wrong recent MAME change --- Src/OSD/SDL/Audio.cpp | 26 +-------------- Src/Sound/MPEG/MpegAudio.cpp | 2 -- Src/Sound/SCSP.cpp | 65 +++++++++++++++++++++++++----------- Src/Sound/SCSPDSP.cpp | 24 +++++-------- Src/Sound/SCSPLFO.cpp | 19 ++++++----- 5 files changed, 67 insertions(+), 69 deletions(-) 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/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 +} From df7787f0401cf6b0d12b636caccaf8f4d72c9337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Casas=20Sch=C3=B6ssow?= Date: Mon, 14 Nov 2022 20:06:09 +0100 Subject: [PATCH 2/7] Keep Supermodel files (config, nvram, saves, etc.) in a predictable path when running on Linux --- Makefiles/Makefile.UNIX | 3 + Makefiles/Makefile.Win32 | 1 + Src/OSD/FileSystemPath.h | 40 ++++++++++ Src/OSD/SDL/Main.cpp | 29 ++++--- Src/OSD/Unix/FileSystemPath.cpp | 122 +++++++++++++++++++++++++++++ Src/OSD/Windows/FileSystemPath.cpp | 37 +++++++++ 6 files changed, 219 insertions(+), 13 deletions(-) create mode 100644 Src/OSD/FileSystemPath.h create mode 100644 Src/OSD/Unix/FileSystemPath.cpp create mode 100644 Src/OSD/Windows/FileSystemPath.cpp 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..b23a92f --- /dev/null +++ b/Src/OSD/FileSystemPath.h @@ -0,0 +1,40 @@ +/** + ** 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 +{ + bool PathExists(std::string fileSystemPath); // Checks if a directory exists (returns true if exists, false if it doesn't) + std::string GetPath(std::string pathType); // Generates a path to be used by Supermodel files +} + + +#endif // INCLUDED_FILESYSTEMPATH_H diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index e0267e9..19fa4f4 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" @@ -475,7 +476,7 @@ void Screenshot() time_t now = std::time(nullptr); tm* ltm = std::localtime(&now); - 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); + sprintf(file, "%sScreenshot %.4d-%.2d-%.2d (%.2d-%.2d-%.2d).bmp", FileSystemPath::GetPath("Screenshots").c_str(), 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()); @@ -549,7 +550,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 +566,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 +575,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 +616,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("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 +641,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("Saves") << Model3->GetGame().name << ".st" << s_saveSlot; // Open and check to make sure format is correct if (OKAY != SaveState.Load(file_path)) @@ -674,7 +675,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("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 +698,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("NVRAM") << Model3->GetGame().name << ".nv"; // Open and check to make sure format is correct if (OKAY != NVRAM.Load(file_path)) @@ -1448,8 +1449,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("Analysis"); +static const std::string s_configFilePath = Util::Format() << FileSystemPath::GetPath("Config") << "Supermodel.ini"; +static const std::string s_gameXMLFilePath = Util::Format() << FileSystemPath::GetPath("Config") << "Games.xml"; +static const std::string s_logFilePath = Util::Format() << FileSystemPath::GetPath("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 +1643,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 +1740,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..b7a8e8c --- /dev/null +++ b/Src/OSD/Unix/FileSystemPath.cpp @@ -0,0 +1,122 @@ +/** + ** 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(std::string pathType) + { + std::string finalPath = ""; + std::string homePath = ""; + struct passwd* pwd = getpwuid(getuid()); + + // 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(pathType)) mkdir(pathType.c_str(), 0775); + finalPath = pathType; + } + + } + // Check if $HOME/.supermodel exists + else if (FileSystemPath::PathExists(Util::Format() << homePath << "/.supermodel")) + { + // Use $HOME/.supermodel + finalPath = Util::Format() << homePath << "/.supermodel/" << pathType; + // 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/" << pathType; + 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..66f9126 --- /dev/null +++ b/Src/OSD/Windows/FileSystemPath.cpp @@ -0,0 +1,37 @@ +/** + ** 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(std::string pathType) + { + if (pathType == "Config") return "Config/"; + if (pathType == "Screenshots") return ""; + if (pathType == "Saves") return "Saves/"; + if (pathType == "NVRAM") return "NVRAM/"; + if (pathType == "Log") return ""; + if (pathType == "Analysis") return "Analysis/"; + } +} From d11efb85535ef3244b7d4fde8d0fe49af25c4210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Casas=20Sch=C3=B6ssow?= Date: Tue, 15 Nov 2022 17:40:01 +0100 Subject: [PATCH 3/7] Changed pathType from string var to enum --- Src/OSD/FileSystemPath.h | 3 ++- Src/OSD/SDL/Main.cpp | 18 +++++++------- Src/OSD/Unix/FileSystemPath.cpp | 38 ++++++++++++++++++++++++------ Src/OSD/Windows/FileSystemPath.cpp | 23 ++++++++++++------ 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/Src/OSD/FileSystemPath.h b/Src/OSD/FileSystemPath.h index b23a92f..b192f2b 100644 --- a/Src/OSD/FileSystemPath.h +++ b/Src/OSD/FileSystemPath.h @@ -32,8 +32,9 @@ namespace FileSystemPath { + enum fsPathType { 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(std::string pathType); // Generates a path to be used by Supermodel files + std::string GetPath(fsPathType pathType); // Generates a path to be used by Supermodel files } diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index 19fa4f4..c98d5d9 100644 --- a/Src/OSD/SDL/Main.cpp +++ b/Src/OSD/SDL/Main.cpp @@ -476,7 +476,7 @@ void Screenshot() time_t now = std::time(nullptr); tm* ltm = std::localtime(&now); - sprintf(file, "%sScreenshot %.4d-%.2d-%.2d (%.2d-%.2d-%.2d).bmp", FileSystemPath::GetPath("Screenshots").c_str(), 1900 + ltm->tm_year, 1 + ltm->tm_mon, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec); + sprintf(file, "%sScreenshot %.4d-%.2d-%.2d (%.2d-%.2d-%.2d).bmp", FileSystemPath::GetPath(FileSystemPath::Screenshots).c_str(), 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()); @@ -616,7 +616,7 @@ static void SaveState(IEmulator *Model3) { CBlockFile SaveState; - std::string file_path = Util::Format() << FileSystemPath::GetPath("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()); @@ -641,7 +641,7 @@ static void LoadState(IEmulator *Model3, std::string file_path = std::string()) // Generate file path if (file_path.empty()) - file_path = Util::Format() << FileSystemPath::GetPath("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)) @@ -675,7 +675,7 @@ static void SaveNVRAM(IEmulator *Model3) { CBlockFile NVRAM; - std::string file_path = Util::Format() << FileSystemPath::GetPath("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()); @@ -698,7 +698,7 @@ static void LoadNVRAM(IEmulator *Model3) CBlockFile NVRAM; // Generate file path - std::string file_path = Util::Format() << FileSystemPath::GetPath("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)) @@ -1449,10 +1449,10 @@ QuitError: Entry Point and Command Line Procesing ******************************************************************************/ -static const std::string s_analysisPath = Util::Format() << FileSystemPath::GetPath("Analysis"); -static const std::string s_configFilePath = Util::Format() << FileSystemPath::GetPath("Config") << "Supermodel.ini"; -static const std::string s_gameXMLFilePath = Util::Format() << FileSystemPath::GetPath("Config") << "Games.xml"; -static const std::string s_logFilePath = Util::Format() << FileSystemPath::GetPath("Log") << "Supermodel.log"; +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) diff --git a/Src/OSD/Unix/FileSystemPath.cpp b/Src/OSD/Unix/FileSystemPath.cpp index b7a8e8c..ce899fe 100644 --- a/Src/OSD/Unix/FileSystemPath.cpp +++ b/Src/OSD/Unix/FileSystemPath.cpp @@ -45,12 +45,36 @@ namespace FileSystemPath } // Generates a path to be used by Supermodel files - std::string GetPath(std::string pathType) + std::string GetPath(fsPathType 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) { @@ -65,15 +89,15 @@ namespace FileSystemPath if (FileSystemPath::PathExists("Config") || homePath.empty()) { // Use current directory - if (pathType == "Screenshots" || pathType == "Log") + if (pathType == Screenshots || pathType == Log) { finalPath = ""; } else { // If directory doesn't exist, create it - if (!FileSystemPath::PathExists(pathType)) mkdir(pathType.c_str(), 0775); - finalPath = pathType; + if (!FileSystemPath::PathExists(strPathType)) mkdir(strPathType.c_str(), 0775); + finalPath = strPathType; } } @@ -81,7 +105,7 @@ namespace FileSystemPath else if (FileSystemPath::PathExists(Util::Format() << homePath << "/.supermodel")) { // Use $HOME/.supermodel - finalPath = Util::Format() << homePath << "/.supermodel/" << pathType; + finalPath = Util::Format() << homePath << "/.supermodel/" << strPathType; // If directory doesn't exist, create it if (!FileSystemPath::PathExists(finalPath)) { @@ -92,7 +116,7 @@ namespace FileSystemPath else { // Use $HOME/.config/supermodel or $HOME/.local/share/supermodel depending on the file type - if (pathType == "Config") + if (pathType == Config) { finalPath = Util::Format() << homePath << "/.config/supermodel"; // If directory doesn't exist, create it @@ -108,7 +132,7 @@ namespace FileSystemPath // 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/" << pathType; + finalPath = Util::Format() << homePath << "/.local/share/supermodel/" << strPathType; if (!FileSystemPath::PathExists(finalPath)) mkdir(finalPath.c_str(), 0775); } diff --git a/Src/OSD/Windows/FileSystemPath.cpp b/Src/OSD/Windows/FileSystemPath.cpp index 66f9126..4390730 100644 --- a/Src/OSD/Windows/FileSystemPath.cpp +++ b/Src/OSD/Windows/FileSystemPath.cpp @@ -25,13 +25,22 @@ namespace FileSystemPath { // Generates a path to be used by Supermodel files - std::string GetPath(std::string pathType) + std::string GetPath(fsPathType pathType) { - if (pathType == "Config") return "Config/"; - if (pathType == "Screenshots") return ""; - if (pathType == "Saves") return "Saves/"; - if (pathType == "NVRAM") return "NVRAM/"; - if (pathType == "Log") return ""; - if (pathType == "Analysis") return "Analysis/"; + switch (pathType) + { + case Analysis: + return "Analysis/"; + case Config: + return "Config/"; + case Log: + return ""; + case NVRAM: + return "NVRAM/"; + case Saves: + return "Saves/"; + case Screenshots: + return ""; + } } } From 317f8bacde218f529f3107643af5cb3986ba4729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Casas=20Sch=C3=B6ssow?= Date: Mon, 21 Nov 2022 22:27:15 +0100 Subject: [PATCH 4/7] First review code changes (identation and cosmetic changes) --- Src/OSD/FileSystemPath.h | 4 +- Src/OSD/Unix/FileSystemPath.cpp | 88 ++++++++++++++++++------------ Src/OSD/Windows/FileSystemPath.cpp | 26 ++++----- 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/Src/OSD/FileSystemPath.h b/Src/OSD/FileSystemPath.h index b192f2b..3c04b62 100644 --- a/Src/OSD/FileSystemPath.h +++ b/Src/OSD/FileSystemPath.h @@ -32,9 +32,9 @@ namespace FileSystemPath { - enum fsPathType { Analysis, Config, Log, NVRAM, Saves, Screenshots }; // Filesystem path types + 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(fsPathType pathType); // Generates a path to be used by Supermodel files + std::string GetPath(PathType pathType); // Generates a path to be used by Supermodel files } diff --git a/Src/OSD/Unix/FileSystemPath.cpp b/Src/OSD/Unix/FileSystemPath.cpp index ce899fe..4ab5916 100644 --- a/Src/OSD/Unix/FileSystemPath.cpp +++ b/Src/OSD/Unix/FileSystemPath.cpp @@ -45,45 +45,45 @@ namespace FileSystemPath } // Generates a path to be used by Supermodel files - std::string GetPath(fsPathType pathType) + std::string GetPath(PathType pathType) { std::string finalPath = ""; std::string homePath = ""; std::string strPathType = ""; - struct passwd* pwd = getpwuid(getuid()); + 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; + 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 (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()) @@ -96,10 +96,12 @@ namespace FileSystemPath else { // If directory doesn't exist, create it - if (!FileSystemPath::PathExists(strPathType)) mkdir(strPathType.c_str(), 0775); + if (!FileSystemPath::PathExists(strPathType)) + { + mkdir(strPathType.c_str(), 0775); + } finalPath = strPathType; } - } // Check if $HOME/.supermodel exists else if (FileSystemPath::PathExists(Util::Format() << homePath << "/.supermodel")) @@ -120,25 +122,39 @@ namespace FileSystemPath { finalPath = Util::Format() << homePath << "/.config/supermodel"; // If directory doesn't exist, create it - if (!FileSystemPath::PathExists(finalPath)) mkdir(finalPath.c_str(), 0775); + 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); - + 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 (!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 (!FileSystemPath::PathExists(finalPath)) + { + mkdir(finalPath.c_str(), 0775); + } } } - if (finalPath != "") finalPath = Util::Format() << finalPath << "/"; + if (finalPath != "") + { + finalPath = Util::Format() << finalPath << "/"; + } return finalPath; diff --git a/Src/OSD/Windows/FileSystemPath.cpp b/Src/OSD/Windows/FileSystemPath.cpp index 4390730..9536d27 100644 --- a/Src/OSD/Windows/FileSystemPath.cpp +++ b/Src/OSD/Windows/FileSystemPath.cpp @@ -25,22 +25,22 @@ namespace FileSystemPath { // Generates a path to be used by Supermodel files - std::string GetPath(fsPathType pathType) + 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 ""; + case Analysis: + return "Analysis/"; + case Config: + return "Config/"; + case Log: + return ""; + case NVRAM: + return "NVRAM/"; + case Saves: + return "Saves/"; + case Screenshots: + return ""; } } } From 07429b9187e69332b2b277483aa4baa517b8aae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Casas=20Sch=C3=B6ssow?= Date: Sun, 4 Dec 2022 19:42:19 +0100 Subject: [PATCH 5/7] Switched to Util::Format() to generate screenshot filename --- Src/OSD/SDL/Main.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index c98d5d9..5562543 100644 --- a/Src/OSD/SDL/Main.cpp +++ b/Src/OSD/SDL/Main.cpp @@ -471,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, "%sScreenshot %.4d-%.2d-%.2d (%.2d-%.2d-%.2d).bmp", FileSystemPath::GetPath(FileSystemPath::Screenshots).c_str(), 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); } From d83e4754fecd4f5ad4b4f997d6cdf5dd2ba10490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Casas=20Sch=C3=B6ssow?= Date: Tue, 6 Dec 2022 13:25:20 +0100 Subject: [PATCH 6/7] Fixed build on macOS --- Makefiles/Makefile.OSX | 3 +++ Src/OSD/OSX/FileSystemPath.cpp | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 Src/OSD/OSX/FileSystemPath.cpp 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/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 ""; + } + } +} From 50d947deeec0545c23f5c3be6ada99baddbe0aad Mon Sep 17 00:00:00 2001 From: gm-matthew <108370479+gm-matthew@users.noreply.github.com> Date: Wed, 14 Dec 2022 00:39:13 +0000 Subject: [PATCH 7/7] Add FileSystemPath.cpp to Visual Studio project --- VS2008/Supermodel.vcxproj | 1 + VS2008/Supermodel.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) 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