Make the instance counter global and initialized at startup.

Turn off config saving for secondary instances.
This commit is contained in:
Henrik Rydgård 2020-07-20 11:38:39 +02:00
parent dadffa3eae
commit fa0b9dc1bc
14 changed files with 227 additions and 130 deletions

View File

@ -1449,6 +1449,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/CwCheat.h
Core/HDRemaster.cpp
Core/HDRemaster.h
Core/Instance.cpp
Core/Instance.h
Core/ThreadEventQueue.h
Core/WebServer.cpp
Core/WebServer.h

View File

@ -42,6 +42,7 @@
#include "Core/ConfigValues.h"
#include "Core/Loaders.h"
#include "Core/HLE/sceUtility.h"
#include "Core/Instance.h"
#include "GPU/Common/FramebufferCommon.h"
// TODO: Find a better place for this.
@ -1107,8 +1108,13 @@ static void IterateSettings(IniFile &iniFile, std::function<void(IniFile::Sectio
}
}
Config::Config() : bGameSpecific(false) { }
Config::~Config() { }
Config::Config() : bGameSpecific(false) {
InitInstanceCounter();
}
Config::~Config() {
ShutdownInstanceCounter();
}
std::map<std::string, std::pair<std::string, int>> GetLangValuesMapping() {
std::map<std::string, std::pair<std::string, int>> langValuesMapping;
@ -1290,9 +1296,18 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
jitForcedOff = true;
g_Config.iCpuCore = (int)CPUCore::INTERPRETER;
}
INFO_LOG(LOADER, "Config loaded: '%s'", iniFilename_.c_str());
}
void Config::Save(const char *saveReason) {
if (!IsFirstInstance()) {
// TODO: Should we allow saving config if started from a different directory?
// How do we tell?
WARN_LOG(LOADER, "Not saving config - secondary instances don't.");
return;
}
if (jitForcedOff) {
// if JIT has been forced off, we don't want to screw up the user's ppsspp.ini
g_Config.iCpuCore = (int)CPUCore::JIT;

View File

@ -388,6 +388,7 @@
<ClCompile Include="HLE\sceUsbCam.cpp" />
<ClCompile Include="HLE\sceUsbMic.cpp" />
<ClCompile Include="HW\Camera.cpp" />
<ClCompile Include="Instance.cpp" />
<ClCompile Include="MemFault.cpp" />
<ClCompile Include="MIPS\IR\IRAsm.cpp" />
<ClCompile Include="MIPS\IR\IRCompALU.cpp" />
@ -918,6 +919,7 @@
<ClInclude Include="HLE\sceUsbCam.h" />
<ClInclude Include="HLE\sceUsbMic.h" />
<ClInclude Include="HW\Camera.h" />
<ClInclude Include="Instance.h" />
<ClInclude Include="MemFault.h" />
<ClInclude Include="MIPS\IR\IRFrontend.h" />
<ClInclude Include="MIPS\IR\IRInst.h" />

View File

@ -746,6 +746,9 @@
<ClCompile Include="MemFault.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="Instance.cpp">
<Filter>Core</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
@ -1385,6 +1388,9 @@
<ClInclude Include="MemFault.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="Instance.h">
<Filter>Core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View File

@ -32,6 +32,7 @@
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/Instance.h"
#include "proAdhoc.h"
#include "i18n/i18n.h"
@ -68,7 +69,6 @@ bool updateChatScreen = false;
int newChat = 0;
bool isLocalServer = false;
uint8_t PPSSPP_ID = 0;
sockaddr localIP; // This might serves the same purpose with existing "localip" above, but since this is copied from my old code so here it is (too lazy to rewrite the code)
int isLocalMAC(const SceNetEtherAddr * addr) {

View File

@ -798,7 +798,6 @@ extern std::map<int, AdhocctlHandler> adhocctlHandlers;
extern uint16_t portOffset;
extern bool isLocalServer;
extern uint8_t PPSSPP_ID;
extern sockaddr localIP;
extern uint32_t fakePoolSize;
extern SceNetAdhocMatchingContext * contexts;

View File

@ -42,6 +42,7 @@
#include "Core/HLE/sceNetAdhoc.h"
#include "Core/HLE/sceNet.h"
#include "Core/Reporting.h"
#include "Core/Instance.h"
static bool netInited;
static bool netInetInited;
@ -56,124 +57,6 @@ static struct SceNetMallocStat netMallocStat;
static std::map<int, ApctlHandler> apctlHandlers;
#ifdef _WIN32
static HANDLE hIDMapFile = NULL;
#elif __linux__ || __APPLE__
static int hIDMapFile = 0;
#endif
static int32_t* pIDBuf = NULL;
#define ID_SHM_NAME "/PPSSPP_ID"
// Get current number of instance of PPSSPP running.
// Must be called only once during init.
static uint8_t getPPSSPPInstanceNumber() {
#ifdef _WIN32
uint32_t BUF_SIZE = 4096;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000;
BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1);
hIDMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
TEXT(ID_SHM_NAME)); // name of mapping object
DWORD lasterr = GetLastError();
if (hIDMapFile == NULL)
{
ERROR_LOG(SCENET, "Could not create %s file mapping object (%d).", ID_SHM_NAME, lasterr);
return 1;
}
pIDBuf = (int32_t*)MapViewOfFile(hIDMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(int32_t)); //BUF_SIZE
if (pIDBuf == NULL)
{
ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError());
//CloseHandle(hIDMapFile);
return 1;
}
(*pIDBuf)++;
int id = *pIDBuf;
UnmapViewOfFile(pIDBuf);
//CloseHandle(hIDMapFile); //Should be called when program exits
//hIDMapFile = NULL;
return id;
#elif __ANDROID__
// TODO : replace shm_open & shm_unlink with ashmem or android-shmem
return 1;
#elif __linux__ || __APPLE__
long BUF_SIZE = 4096;
//caddr_t pIDBuf;
int status;
// Create shared memory object
hIDMapFile = shm_open(ID_SHM_NAME, O_CREAT | O_RDWR, 0);
BUF_SIZE = (BUF_SIZE < sysconf(_SC_PAGE_SIZE)) ? sysconf(_SC_PAGE_SIZE) : BUF_SIZE;
if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size
ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME);
return 1;
}
pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0);
if (pIDBuf == MAP_FAILED) { // Set the size
ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME);
pIDBuf = NULL;
return 1;
}
int id = 1;
if (mlock(pIDBuf, BUF_SIZE) == 0) {
(*pIDBuf)++;
id = *pIDBuf;
munlock(pIDBuf, BUF_SIZE);
}
status = munmap(pIDBuf, BUF_SIZE); // Unmap the page
//status = close(hIDMapFile); // Close file, should be called when program exits?
//status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits
return id;
#else
return 1;
#endif
}
static void PPSSPPIDCleanup() {
#ifdef _WIN32
if (hIDMapFile != NULL) {
CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted.
hIDMapFile = NULL;
}
#elif __ANDROID__
if (hIDMapFile != 0) {
close(hIDMapFile);
// TODO : replace shm_unlink with ashmem or android-shmem
//shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist.
hIDMapFile = 0;
}
#elif __linux__ || __APPLE__
// TODO : This unlink should be called when program exits instead of everytime the game reset.
if (hIDMapFile != 0) {
close(hIDMapFile);
shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist.
hIDMapFile = 0;
}
#endif
}
static int InitLocalIP() {
// find local IP
addrinfo* localAddr;
@ -232,10 +115,6 @@ static void __ResetInitNetLib() {
void __NetInit() {
portOffset = g_Config.iPortOffset;
if (PPSSPP_ID == 0) // For persistent ID/IP, New instances may have a possibility to have the same ID/IP if PPSSPPIDCleanup() being called on every reset
{
PPSSPP_ID = getPPSSPPInstanceNumber(); // This should be called when program started instead of when the game started/reseted
}
net::Init();
InitLocalIP();

151
Core/Instance.cpp Normal file
View File

@ -0,0 +1,151 @@
// Copyright (c) 2020 PPSSPP Project.
// This program 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, version 2.0 or later versions.
// This program 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Instance.h"
#if __linux__ || __APPLE__
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#endif
#include "Common/Log.h"
#if PPSSPP_PLATFORM(WINDOWS)
#include "Common/CommonWindows.h"
#endif
#include <cstdint>
uint8_t PPSSPP_ID = 0;
#if PPSSPP_PLATFORM(WINDOWS)
static HANDLE hIDMapFile = NULL;
#else
static int hIDMapFile = 0;
#endif
static int32_t* pIDBuf = NULL;
#define ID_SHM_NAME "/PPSSPP_ID"
// Get current number of instance of PPSSPP running.
// Must be called only once during init.
void InitInstanceCounter() {
#if PPSSPP_PLATFORM(WINDOWS)
uint32_t BUF_SIZE = 4096;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000;
BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1);
hIDMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
TEXT(ID_SHM_NAME)); // name of mapping object
DWORD lasterr = GetLastError();
if (hIDMapFile == NULL)
{
ERROR_LOG(SCENET, "Could not create %s file mapping object (%d).", ID_SHM_NAME, lasterr);
PPSSPP_ID = 1;
return;
}
pIDBuf = (int32_t*)MapViewOfFile(hIDMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(int32_t)); //BUF_SIZE
if (pIDBuf == NULL) {
ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError());
//CloseHandle(hIDMapFile);
PPSSPP_ID = 1;
return;
}
(*pIDBuf)++;
int id = *pIDBuf;
UnmapViewOfFile(pIDBuf);
//CloseHandle(hIDMapFile); //Should be called when program exits
//hIDMapFile = NULL;
PPSSPP_ID = id;
#elif PPSSPP_PLATFORM(ANDROID)
// TODO : replace shm_open & shm_unlink with ashmem or android-shmem
PPSSPP_ID = 1;
#else
long BUF_SIZE = 4096;
//caddr_t pIDBuf;
int status;
// Create shared memory object
hIDMapFile = shm_open(ID_SHM_NAME, O_CREAT | O_RDWR, 0);
BUF_SIZE = (BUF_SIZE < sysconf(_SC_PAGE_SIZE)) ? sysconf(_SC_PAGE_SIZE) : BUF_SIZE;
if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size
ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME);
return 1;
}
pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0);
if (pIDBuf == MAP_FAILED) { // Set the size
ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME);
pIDBuf = NULL;
return 1;
}
int id = 1;
if (mlock(pIDBuf, BUF_SIZE) == 0) {
(*pIDBuf)++;
id = *pIDBuf;
munlock(pIDBuf, BUF_SIZE);
}
status = munmap(pIDBuf, BUF_SIZE); // Unmap the page
//status = close(hIDMapFile); // Close file, should be called when program exits?
//status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits
return id;
#endif
}
void ShutdownInstanceCounter() {
#if PPSSPP_PLATFORM(WINDOWS)
if (hIDMapFile != NULL) {
CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted.
hIDMapFile = NULL;
}
#elif PPSSPP_PLATFORM(ANDROID)
// Do nothing
#else
// TODO : This unlink should be called when program exits instead of everytime the game reset.
if (hIDMapFile != 0) {
close(hIDMapFile);
shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist.
hIDMapFile = 0;
}
#endif
}

31
Core/Instance.h Normal file
View File

@ -0,0 +1,31 @@
// Copyright (c) 2020 PPSSPP Project.
// This program 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, version 2.0 or later versions.
// This program 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "ppsspp_config.h"
#include <cstdint>
extern uint8_t PPSSPP_ID;
void InitInstanceCounter();
void ShutdownInstanceCounter();
inline bool IsFirstInstance() {
return PPSSPP_ID == 1;
}

View File

@ -432,6 +432,7 @@
<ClInclude Include="..\..\Core\FileSystems\VirtualDiscFileSystem.h" />
<ClInclude Include="..\..\Core\Font\PGF.h" />
<ClInclude Include="..\..\Core\HDRemaster.h" />
<ClInclude Include="..\..\Core\Instance.h" />
<ClInclude Include="..\..\Core\HLE\FunctionWrappers.h" />
<ClInclude Include="..\..\Core\HLE\HLE.h" />
<ClInclude Include="..\..\Core\HLE\HLEHelperThread.h" />
@ -648,6 +649,7 @@
<ClCompile Include="..\..\Core\FileSystems\VirtualDiscFileSystem.cpp" />
<ClCompile Include="..\..\Core\Font\PGF.cpp" />
<ClCompile Include="..\..\Core\HDRemaster.cpp" />
<ClCompile Include="..\..\Core\Instance.cpp" />
<ClCompile Include="..\..\Core\HLE\HLE.cpp" />
<ClCompile Include="..\..\Core\HLE\HLEHelperThread.cpp" />
<ClCompile Include="..\..\Core\HLE\HLETables.cpp" />

View File

@ -80,6 +80,7 @@
<ClCompile Include="..\..\Core\CoreTiming.cpp" />
<ClCompile Include="..\..\Core\CwCheat.cpp" />
<ClCompile Include="..\..\Core\HDRemaster.cpp" />
<ClCompile Include="..\..\Core\Instance.cpp" />
<ClCompile Include="..\..\Core\Host.cpp" />
<ClCompile Include="..\..\Core\Loaders.cpp" />
<ClCompile Include="..\..\Core\MemFault.cpp" />
@ -718,6 +719,7 @@
<ClInclude Include="..\..\Core\CoreTiming.h" />
<ClInclude Include="..\..\Core\CwCheat.h" />
<ClInclude Include="..\..\Core\HDRemaster.h" />
<ClInclude Include="..\..\Core\Instance.h" />
<ClInclude Include="..\..\Core\Host.h" />
<ClInclude Include="..\..\Core\Loaders.h" />
<ClInclude Include="..\..\Core\MemFault.h" />

View File

@ -46,6 +46,8 @@
#include "Core/CoreParameter.h"
#include "Core/System.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/Instance.h"
#include "Windows/EmuThread.h"
#include "Windows/WindowsAudio.h"
#include "Windows/WindowsHost.h"
@ -101,8 +103,9 @@ WindowsHost::WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindo
void WindowsHost::SetConsolePosition() {
HWND console = GetConsoleWindow();
if (console != NULL && g_Config.iConsoleWindowX != -1 && g_Config.iConsoleWindowY != -1)
if (console != NULL && g_Config.iConsoleWindowX != -1 && g_Config.iConsoleWindowY != -1) {
SetWindowPos(console, NULL, g_Config.iConsoleWindowX, g_Config.iConsoleWindowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
}
void WindowsHost::UpdateConsolePosition() {
@ -167,6 +170,9 @@ void WindowsHost::SetWindowTitle(const char *message) {
#ifdef _DEBUG
winTitle.append(L" (debug)");
#endif
if (PPSSPP_ID >= 1) {
winTitle.append(ConvertUTF8ToWString(StringFromFormat(" (instance: %d)", (int)PPSSPP_ID)));
}
MainWindow::SetWindowTitle(winTitle.c_str());
PostMessage(mainWindow_, MainWindow::WM_USER_WINDOW_TITLE_CHANGED, 0, 0);
@ -280,7 +286,7 @@ static std::string SymbolMapFilename(const char *currentFilename, const char* ex
return result + ".ppsspp-symbols" + ext;
} else {
size_t dot = result.rfind('.');
const size_t dot = result.rfind('.');
if (dot == result.npos)
return result + ext;
@ -360,8 +366,8 @@ bool WindowsHost::CreateDesktopShortcut(std::string argumentPath, std::string ga
// Sanitize the game title for banned characters.
const char bannedChars[] = "<>:\"/\\|?*";
for (size_t i = 0; i < gameTitle.size(); i++) {
for (size_t c = 0; c < strlen(bannedChars); c++) {
if (gameTitle[i] == bannedChars[c]) {
for (char c : bannedChars) {
if (gameTitle[i] == c) {
gameTitle[i] = '_';
break;
}

View File

@ -291,6 +291,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Core/CoreTiming.cpp \
$(SRC)/Core/CwCheat.cpp \
$(SRC)/Core/HDRemaster.cpp \
$(SRC)/Core/Instance.cpp \
$(SRC)/Core/Host.cpp \
$(SRC)/Core/Loaders.cpp \
$(SRC)/Core/PSPLoaders.cpp \

View File

@ -342,6 +342,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \
$(COREDIR)/CoreTiming.cpp \
$(COREDIR)/CwCheat.cpp \
$(COREDIR)/HDRemaster.cpp \
$(COREDIR)/Instance.cpp \
$(COREDIR)/Debugger/Breakpoints.cpp \
$(COREDIR)/Debugger/SymbolMap.cpp \
$(COREDIR)/Dialog/PSPDialog.cpp \