Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalized multi-instance #13172

Merged
merged 4 commits into from
Jul 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 22 additions & 2 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1290,9 +1296,23 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
jitForcedOff = true;
g_Config.iCpuCore = (int)CPUCore::INTERPRETER;
}

// Automatically silence secondary instances. Could be an option I guess, but meh.
if (PPSSPP_ID > 1) {
g_Config.iGlobalVolume = 0;
}

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;
Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down Expand Up @@ -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" />
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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" />
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/proAdhoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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) {
Expand Down
1 change: 0 additions & 1 deletion Core/HLE/proAdhoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
123 changes: 1 addition & 122 deletions Core/HLE/sceNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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();
hrydgard marked this conversation as resolved.
Show resolved Hide resolved
InitLocalIP();
Expand Down
Loading