Merge branch 'master' into TemporaryHackishBranch

# Conflicts:
#	Core/Compatibility.cpp
#	Core/Compatibility.h
This commit is contained in:
LunaMoo committed 2020-01-11 19:45:37 +01:00
commit a0306633fc
33 files changed
+327 -215

No files matched your search

+6 -14
View File
@@ -117,7 +117,6 @@ static void *SearchForFreeMem(size_t size) {
// This is purposely not a full wrapper for virtualalloc/mmap, but it
// provides exactly the primitive operations that PPSSPP needs.
void *AllocateExecutableMemory(size_t size) {
#if defined(_WIN32)
void *ptr = nullptr;
@@ -157,7 +156,7 @@ void *AllocateExecutableMemory(size_t size) {
}
#else
static char *map_hint = 0;
#if defined(_M_X64) && !defined(MAP_32BIT)
#if defined(_M_X64)
// Try to request one that is close to our memory location if we're in high memory.
// We use a dummy global variable to give us a good location to start from.
if (!map_hint) {
@@ -165,9 +164,7 @@ void *AllocateExecutableMemory(size_t size) {
map_hint = (char*)round_page(&hint_location) - 0x20000000; // 0.5gb lower than our approximate location
else
map_hint = (char*)0x20000000; // 0.5GB mark in memory
}
else if ((uintptr_t) map_hint > 0xFFFFFFFFULL)
{
} else if ((uintptr_t) map_hint > 0xFFFFFFFFULL) {
map_hint -= round_page(size); /* round down to the next page if we're in high memory */
}
#endif
@@ -176,13 +173,7 @@ void *AllocateExecutableMemory(size_t size) {
if (PlatformIsWXExclusive())
prot = PROT_READ | PROT_WRITE; // POST_EXEC is added later in this case.
void* ptr = mmap(map_hint, size, prot,
MAP_ANON | MAP_PRIVATE
#if defined(_M_X64) && defined(MAP_32BIT)
| MAP_32BIT
#endif
, -1, 0);
void* ptr = mmap(map_hint, size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
#endif /* defined(_WIN32) */
#if !defined(_WIN32)
@@ -193,10 +184,11 @@ void *AllocateExecutableMemory(size_t size) {
if (ptr == failed_result) {
ptr = nullptr;
ERROR_LOG(MEMMAP, "Failed to allocate executable memory (%d)", (int)size);
ERROR_LOG(MEMMAP, "Failed to allocate executable memory (%d) errno=%d", (int)size, errno);
PanicAlert("Failed to allocate executable memory\n%s", GetLastErrorMsg());
}
#if defined(_M_X64) && !defined(_WIN32) && !defined(MAP_32BIT)
#if defined(_M_X64) && !defined(_WIN32)
else if ((uintptr_t)map_hint <= 0xFFFFFFFF) {
// Round up if we're below 32-bit mark, probably allocating sequentially.
map_hint += round_page(size);
-1
View File
@@ -68,7 +68,6 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
CheckSetting(iniFile, gameID, "DisableAccurateDepth", &flags_.DisableAccurateDepth);
CheckSetting(iniFile, gameID, "MGS2AcidHack", &flags_.MGS2AcidHack);
CheckSetting(iniFile, gameID, "SonicRivalsHack", &flags_.SonicRivalsHack);
CheckSetting(iniFile, gameID, "RenderPassMerge", &flags_.RenderPassMerge);
CheckSetting(iniFile, gameID, "AdhocHackDisableNBSwitch", &flags_.AdhocHackDisableNBSwitch);
CheckSetting(iniFile, gameID, "AdhocHackStopFriendClear", &flags_.AdhocHackStopFriendClear);
CheckSetting(iniFile, gameID, "AdhocHackPhantasyStarOffset", &flags_.AdhocHackPhantasyStarOffset);
-1
View File
@@ -68,7 +68,6 @@ struct CompatFlags {
bool DisableAccurateDepth;
bool MGS2AcidHack;
bool SonicRivalsHack;
bool RenderPassMerge;
bool AdhocHackDisableNBSwitch;
bool AdhocHackStopFriendClear;
bool AdhocHackPhantasyStarOffset;
+4
View File
@@ -870,6 +870,10 @@ static ConfigSetting controlSettings[] = {
ConfigSetting("TouchButtonHideSeconds", &g_Config.iTouchButtonHideSeconds, 20, true, true),
ConfigSetting("AutoCenterTouchAnalog", &g_Config.bAutoCenterTouchAnalog, false, true, true),
// Snap touch control position
ConfigSetting("TouchSnapToGrid", &g_Config.bTouchSnapToGrid, false, true, true),
ConfigSetting("TouchSnapGridSize", &g_Config.iTouchSnapGridSize, 64, true, true),
// -1.0f means uninitialized, set in GamepadEmu::CreatePadLayout().
ConfigSetting("ActionButtonSpacing2", &g_Config.fActionButtonSpacing, 1.0f, true, true),
ConfigSetting("ActionButtonCenterX", "ActionButtonCenterY", "ActionButtonScale", nullptr, &g_Config.touchActionButtonCenter, defaultTouchPosShow, true, true),
+5
View File
@@ -285,6 +285,11 @@ public:
int iTouchButtonStyle;
int iTouchButtonOpacity;
int iTouchButtonHideSeconds;
// Snap touch control position
bool bTouchSnapToGrid;
int iTouchSnapGridSize;
// Floating analog stick (recenters on thumb on press).
bool bAutoCenterTouchAnalog;
+41 -20
View File
@@ -226,7 +226,7 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath
currentDirectory = &(it->second);
}
if ( RealPath(*currentDirectory, inpath, realpath) )
if (RealPath(*currentDirectory, inpath, realpath))
{
std::string prefix = realpath;
size_t prefixPos = realpath.find(':');
@@ -243,7 +243,7 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath
VERBOSE_LOG(FILESYS, "MapFilePath: mapped \"%s\" to prefix: \"%s\", path: \"%s\"", inpath.c_str(), fileSystems[i].prefix.c_str(), outpath.c_str());
return 0;
return error == SCE_KERNEL_ERROR_NOCWD ? error : 0;
}
}
}
@@ -270,8 +270,7 @@ std::string MetaFileSystem::NormalizePrefix(std::string prefix) const {
return prefix;
}
void MetaFileSystem::Mount(std::string prefix, IFileSystem *system)
{
void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) {
std::lock_guard<std::recursive_mutex> guard(lock);
MountPoint x;
x.prefix = prefix;
@@ -279,8 +278,7 @@ void MetaFileSystem::Mount(std::string prefix, IFileSystem *system)
fileSystems.push_back(x);
}
void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system)
{
void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) {
std::lock_guard<std::recursive_mutex> guard(lock);
MountPoint x;
x.prefix = prefix;
@@ -288,12 +286,25 @@ void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system)
fileSystems.erase(std::remove(fileSystems.begin(), fileSystems.end(), x), fileSystems.end());
}
void MetaFileSystem::Remount(IFileSystem *oldSystem, IFileSystem *newSystem) {
for (auto it = fileSystems.begin(); it != fileSystems.end(); ++it) {
if (it->system == oldSystem) {
it->system = newSystem;
void MetaFileSystem::Remount(std::string prefix, IFileSystem *newSystem) {
std::lock_guard<std::recursive_mutex> guard(lock);
IFileSystem *oldSystem = nullptr;
for (auto &it : fileSystems) {
if (it.prefix == prefix) {
oldSystem = it.system;
it.system = newSystem;
}
}
bool delOldSystem = true;
for (auto &it : fileSystems) {
if (it.system == oldSystem) {
delOldSystem = false;
}
}
if (delOldSystem)
delete oldSystem;
}
IFileSystem *MetaFileSystem::GetSystemFromFilename(const std::string &filename) {
@@ -350,7 +361,8 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename)
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(filename, of, &system) == 0)
int error = MapFilePath(filename, of, &system);
if (error == 0)
{
return system->GetFileInfo(of);
}
@@ -366,7 +378,8 @@ bool MetaFileSystem::GetHostPath(const std::string &inpath, std::string &outpath
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(inpath, of, &system) == 0) {
int error = MapFilePath(inpath, of, &system);
if (error == 0) {
return system->GetHostPath(of, outpath);
} else {
return false;
@@ -378,7 +391,8 @@ std::vector<PSPFileInfo> MetaFileSystem::GetDirListing(std::string path)
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(path, of, &system) == 0)
int error = MapFilePath(path, of, &system);
if (error == 0)
{
return system->GetDirListing(of);
}
@@ -406,7 +420,8 @@ int MetaFileSystem::ChDir(const std::string &dir)
std::string of;
MountPoint *mountPoint;
if (MapFilePath(dir, of, &mountPoint) == 0)
int error = MapFilePath(dir, of, &mountPoint);
if (error == 0)
{
currentDir[curThread] = mountPoint->prefix + of;
return 0;
@@ -435,7 +450,8 @@ bool MetaFileSystem::MkDir(const std::string &dirname)
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(dirname, of, &system) == 0)
int error = MapFilePath(dirname, of, &system);
if (error == 0)
{
return system->MkDir(of);
}
@@ -450,7 +466,8 @@ bool MetaFileSystem::RmDir(const std::string &dirname)
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(dirname, of, &system) == 0)
int error = MapFilePath(dirname, of, &system);
if (error == 0)
{
return system->RmDir(of);
}
@@ -467,12 +484,14 @@ int MetaFileSystem::RenameFile(const std::string &from, const std::string &to)
std::string rf;
IFileSystem *osystem;
IFileSystem *rsystem = NULL;
if (MapFilePath(from, of, &osystem) == 0)
int error = MapFilePath(from, of, &osystem);
if (error == 0)
{
// If it's a relative path, it seems to always use from's filesystem.
if (to.find(":/") != to.npos)
{
if (!MapFilePath(to, rf, &rsystem))
error = MapFilePath(to, rf, &rsystem);
if (error < 0)
return -1;
}
else
@@ -497,7 +516,8 @@ bool MetaFileSystem::RemoveFile(const std::string &filename)
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(filename, of, &system) == 0)
int error = MapFilePath(filename, of, &system);
if (error == 0)
{
return system->RemoveFile(of);
}
@@ -604,7 +624,8 @@ u64 MetaFileSystem::FreeSpace(const std::string &path)
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
if (MapFilePath(path, of, &system) == 0)
int error = MapFilePath(path, of, &system);
if (error == 0)
return system->FreeSpace(of);
else
return 0;
+1 -1
View File
@@ -52,7 +52,7 @@ public:
void Mount(std::string prefix, IFileSystem *system);
void Unmount(std::string prefix, IFileSystem *system);
void Remount(IFileSystem *oldSystem, IFileSystem *newSystem);
void Remount(std::string prefix, IFileSystem *newSystem);
IFileSystem *GetSystem(const std::string &prefix);
IFileSystem *GetSystemFromFilename(const std::string &filename);
+9
View File
@@ -16,9 +16,11 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/ChunkFile.h"
#include "Core/CoreTiming.h"
#include "Core/MemMapHelpers.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/HLEHelperThread.h"
#include "Core/HLE/KernelWaitHelpers.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/MIPS/MIPSCodeUtils.h"
@@ -91,6 +93,13 @@ void HLEHelperThread::ChangePriority(u32 prio) {
KernelChangeThreadPriority(id_, prio);
}
void HLEHelperThread::Resume(WaitType waitType, SceUID uid, int result) {
bool res = HLEKernel::ResumeFromWait(id_, waitType, uid, result);
if (!res) {
ERROR_LOG(HLE, "Failed to wake helper thread from wait");
}
}
void HLEHelperThread::Forget() {
id_ = 0;
entry_ = 0;
+6
View File
@@ -19,6 +19,7 @@
#include "Core/HLE/sceKernel.h"
class PointerWrap;
enum WaitType : int;
class HLEHelperThread {
public:
@@ -33,10 +34,15 @@ public:
void Terminate();
bool Stopped();
void ChangePriority(u32 prio);
void Resume(WaitType waitType, SceUID uid, int result);
// For savestates.
void Forget();
u32 Entry() {
return entry_;
}
private:
void AllocEntry(u32 size);
void Create(const char *threadName, u32 prio, int stacksize);
+60 -36
View File
@@ -199,6 +199,7 @@ struct IoAsyncParams {
static IoAsyncParams asyncParams[PSP_COUNT_FDS];
static HLEHelperThread *asyncThreads[PSP_COUNT_FDS]{};
static int asyncDefaultPriority = -1;
class FileNode : public KernelObject {
public:
@@ -294,8 +295,11 @@ public:
u64 __IoCompleteAsyncIO(FileNode *f);
static void IoAsyncCleanupThread(int fd, bool force = false) {
if (asyncThreads[fd] && (asyncThreads[fd]->Stopped() || force)) {
static void IoAsyncCleanupThread(int fd) {
if (asyncThreads[fd]) {
if (!asyncThreads[fd]->Stopped()) {
asyncThreads[fd]->Terminate();
}
delete asyncThreads[fd];
asyncThreads[fd] = nullptr;
}
@@ -437,8 +441,6 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) {
if (f->closePending) {
__IoFreeFd(fd, error);
}
IoAsyncCleanupThread(fd);
}
}
@@ -487,8 +489,6 @@ static void __IoSyncNotify(u64 userdata, int cyclesLate) {
HLEKernel::ResumeFromWait(threadID, WAITTYPE_IO, fd, result);
f->waitingSyncThreads.erase(std::remove(f->waitingSyncThreads.begin(), f->waitingSyncThreads.end(), threadID), f->waitingSyncThreads.end());
IoAsyncCleanupThread(fd);
}
static void __IoAsyncBeginCallback(SceUID threadID, SceUID prevCallbackId) {
@@ -662,7 +662,7 @@ void __IoInit() {
}
void __IoDoState(PointerWrap &p) {
auto s = p.Section("sceIo", 1, 4);
auto s = p.Section("sceIo", 1, 5);
if (!s)
return;
@@ -697,31 +697,36 @@ void __IoDoState(PointerWrap &p) {
}
for (int i = 0; i < PSP_COUNT_FDS; ++i) {
auto clearThread = [&]() {
if (asyncThreads[i])
asyncThreads[i]->Forget();
delete asyncThreads[i];
asyncThreads[i] = nullptr;
};
if (s >= 4) {
p.DoVoid(&asyncParams[i], (int)sizeof(IoAsyncParams));
bool hasThread = asyncThreads[i] != nullptr;
p.Do(hasThread);
if (hasThread) {
if (asyncThreads[i])
asyncThreads[i]->Forget();
delete asyncThreads[i];
asyncThreads[i] = nullptr;
if (p.GetMode() == p.MODE_READ)
clearThread();
p.DoClass(asyncThreads[i]);
} else if (!hasThread) {
if (asyncThreads[i])
asyncThreads[i]->Forget();
delete asyncThreads[i];
asyncThreads[i] = nullptr;
clearThread();
}
} else {
asyncParams[i].op = IoAsyncOp::NONE;
asyncParams[i].priority = -1;
if (asyncThreads[i])
asyncThreads[i]->Forget();
delete asyncThreads[i];
asyncThreads[i] = nullptr;
clearThread();
}
}
if (s >= 5) {
p.Do(asyncDefaultPriority);
} else {
asyncDefaultPriority = -1;
}
}
void __IoShutdown() {
@@ -739,6 +744,7 @@ void __IoShutdown() {
delete asyncThreads[i];
asyncThreads[i] = nullptr;
}
asyncDefaultPriority = -1;
pspFileSystem.Unmount("ms0:", memstickSystem);
pspFileSystem.Unmount("fatms0:", memstickSystem);
@@ -771,10 +777,20 @@ u32 __IoGetFileHandleFromId(u32 id, u32 &outError)
}
static void IoStartAsyncThread(int id, FileNode *f) {
IoAsyncCleanupThread(id, true);
int priority = asyncParams[id].priority == -1 ? KernelCurThreadPriority() : asyncParams[id].priority;
asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200);
asyncThreads[id]->Start(id, 0);
if (asyncThreads[id] && !asyncThreads[id]->Stopped()) {
// Wake the thread up.
if (asyncParams[id].priority == -1 && sceKernelGetCompiledSdkVersion() >= 0x04020000) {
asyncThreads[id]->ChangePriority(KernelCurThreadPriority());
}
asyncThreads[id]->Resume(WAITTYPE_ASYNCIO, id, 0);
} else {
IoAsyncCleanupThread(id);
int priority = asyncParams[id].priority;
if (priority == -1)
priority = KernelCurThreadPriority();
asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200);
asyncThreads[id]->Start(id, 0);
}
f->pendingAsyncResult = true;
}
@@ -1249,17 +1265,14 @@ static u32 sceIoGetDevType(int id) {
static u32 sceIoCancel(int id)
{
ERROR_LOG_REPORT(SCEIO, "UNIMPL sceIoCancel(%d)", id);
u32 error;
FileNode *f = __IoGetFd(id, error);
if (f) {
// TODO: Cancel the async operation if possible?
// It seems like this is unsupported for UMDs and memory sticks, based on tests.
return hleReportError(SCEIO, SCE_KERNEL_ERROR_UNSUP, "unimplemented or unsupported");
} else {
ERROR_LOG(SCEIO, "sceIoCancel: unknown id %d", id);
error = SCE_KERNEL_ERROR_BADF;
return hleLogError(SCEIO, SCE_KERNEL_ERROR_BADF, "invalid fd");
}
return error;
}
static u32 npdrmLseek(FileNode *f, s32 where, FileMove whence)
@@ -1482,7 +1495,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) {
return id;
} else {
DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode);
asyncParams[id].priority = -1;
asyncParams[id].priority = asyncDefaultPriority;
// Timing is not accurate, aiming low for now.
return hleDelayResult(id, "file opened", 100);
}
@@ -1958,11 +1971,16 @@ static u32 sceIoChdir(const char *dirname) {
}
static int sceIoChangeAsyncPriority(int id, int priority) {
// priority = -1 is valid
// priority = -1 is valid,means the current thread'priority
if (priority != -1 && (priority < 0x08 || priority > 0x77)) {
return hleLogError(SCEIO, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "illegal priority %d", priority);
}
if (id == -1) {
asyncDefaultPriority = priority;
return hleLogSuccessI(SCEIO, 0);
}
u32 error;
FileNode *f = __IoGetFd(id, error);
if (!f) {
@@ -1970,6 +1988,9 @@ static int sceIoChangeAsyncPriority(int id, int priority) {
}
if (asyncThreads[id] && !asyncThreads[id]->Stopped()) {
if (priority == -1) {
priority = KernelCurThreadPriority();
}
asyncThreads[id]->ChangePriority(priority);
}
@@ -2041,7 +2062,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode)
auto &params = asyncParams[fd];
params.op = IoAsyncOp::OPEN;
params.priority = -1;
params.priority = asyncDefaultPriority;
params.open.filenameAddr = PARAM(0);
params.open.flags = flags;
params.open.mode = mode;
@@ -2087,7 +2108,6 @@ static u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) {
DEBUG_LOG(SCEIO, "%lli = sceIoGetAsyncStat(%i, %i, %08x)", f->asyncResult, id, poll, address);
Memory::Write_U64((u64) f->asyncResult, address);
f->hasAsyncResult = false;
IoAsyncCleanupThread(id);
if (f->closePending) {
__IoFreeFd(id, error);
@@ -2125,7 +2145,6 @@ static int sceIoWaitAsync(int id, u32 address) {
}
Memory::Write_U64((u64) f->asyncResult, address);
f->hasAsyncResult = false;
IoAsyncCleanupThread(id);
if (f->closePending) {
__IoFreeFd(id, error);
@@ -2159,7 +2178,6 @@ static int sceIoWaitAsyncCB(int id, u32 address) {
} else if (f->hasAsyncResult) {
Memory::Write_U64((u64) f->asyncResult, address);
f->hasAsyncResult = false;
IoAsyncCleanupThread(id);
if (f->closePending) {
__IoFreeFd(id, error);
@@ -2183,7 +2201,6 @@ static u32 sceIoPollAsync(int id, u32 address) {
} else if (f->hasAsyncResult) {
Memory::Write_U64((u64) f->asyncResult, address);
f->hasAsyncResult = false;
IoAsyncCleanupThread(id);
if (f->closePending) {
__IoFreeFd(id, error);
@@ -2531,6 +2548,10 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr,
// TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem.
INFO_LOG(SCEIO, "sceIoIoctl: Sector seek for file %i", id);
// Even if the size is 4, it still actually reads a 16 byte struct, it seems.
//if (GetIOTimingMethod() == IOTIMING_REALISTIC) // Need a check for io timing method?
usec = 15000;// Fantasy Golf Pangya Portable(KS) needs a delay over 15000us.
if (Memory::IsValidAddress(indataPtr) && inlen >= 4) {
struct SeekInfo {
u64 offset;
@@ -2653,6 +2674,8 @@ static int IoAsyncFinish(int id) {
if (f) {
// Reset this so the Io funcs don't reject the request.
f->pendingAsyncResult = false;
// Reset the PC back so we will run again on resume.
currentMIPS->pc = asyncThreads[id]->Entry();
auto &params = asyncParams[id];
@@ -2714,6 +2737,7 @@ static int IoAsyncFinish(int id) {
__IoSchedAsync(f, id, us);
__KernelWaitCurThread(WAITTYPE_ASYNCIO, id, 0, 0, false, "async io");
hleSkipDeadbeef();
params.op = IoAsyncOp::NONE;
return 0;
+1 -1
View File
@@ -80,7 +80,7 @@ struct SceKernelSysClock {
// TODO: Map these to PSP wait types. Most of these are wrong.
// remember to update the waitTypeNames array in sceKernelThread.cpp when changing these
enum WaitType
enum WaitType : int
{
WAITTYPE_NONE = 0,
WAITTYPE_SLEEP = 1,
+5
View File
@@ -1898,6 +1898,11 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init)
return -1;
}
if (!Memory::IsValidAddress(bufferAddr)) {
WARN_LOG(ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i): invalid addresses", mpeg, auAddr, bufferAddr, init);
return -1;
}
DEBUG_LOG(ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i)", mpeg, auAddr, bufferAddr, init);
SceMpegAu atracAu;
+5 -33
View File
@@ -425,7 +425,7 @@ static int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout)
DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): waiting", stat, timeout);
__UmdWaitStat(timeout);
umdWaitingThreads.push_back(__KernelGetCurThread());
__KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited with timer");
__KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, false, "umd stat waited with timer");
return 0;
} else {
hleReSchedule("umd stat checked");
@@ -495,45 +495,17 @@ static u32 sceUmdGetErrorStat()
}
void __UmdReplace(std::string filepath) {
// TODO: This should really go through Loaders, no? What if it's an invalid file?
// Only get system from disc0 seems have been enough.
IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:");
IFileSystem* currentISOBlock = pspFileSystem.GetSystem("umd0:");
if (!currentUMD)
return;
FileLoader *loadedFile = ConstructFileLoader(filepath);
IFileSystem* umd2;
if (!loadedFile->Exists()) {
delete loadedFile;
std::string error = "";
if (!UmdReplace(filepath, error)) {
ERROR_LOG(SCEIO, "UMD Replace failed: %s", error.c_str());
return;
}
UpdateLoadedFile(loadedFile);
if (loadedFile->IsDirectory()) {
umd2 = new VirtualDiscFileSystem(&pspFileSystem, filepath);
} else {
auto bd = constructBlockDevice(loadedFile);
if (!bd)
return;
umd2 = new ISOFileSystem(&pspFileSystem, bd);
pspFileSystem.Remount(currentUMD, umd2);
if (currentUMD != currentISOBlock) {
// We mounted an ISO block system separately.
IFileSystem *iso = new ISOBlockSystem(static_cast<ISOFileSystem *>(umd2));
pspFileSystem.Remount(currentISOBlock, iso);
delete currentISOBlock;
}
}
delete currentUMD;
UMDInserted = false;
CoreTiming::ScheduleEvent(usToCycles(200*1000), umdInsertChangeEvent, 0); // Wait sceUmdCheckMedium call
// TODO Is this always correct if UMD was not activated?
u32 notifyArg = PSP_UMD_PRESENT | PSP_UMD_READABLE | PSP_UMD_CHANGED;
if (driveCBId != -1)
if (driveCBId != 0)
__KernelNotifyCallback(driveCBId, notifyArg);
}
+38
View File
@@ -355,3 +355,41 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
coreState = CORE_ERROR;
return false;
}
bool UmdReplace(std::string filepath, std::string &error) {
IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:");
if (!currentUMD) {
error = "has no disc";
return false;
}
FileLoader *loadedFile = ConstructFileLoader(filepath);
if (!loadedFile->Exists()) {
delete loadedFile;
error = loadedFile->Path() + " doesn't exist";
return false;
}
UpdateLoadedFile(loadedFile);
loadedFile = ResolveFileLoaderTarget(loadedFile);
IdentifiedFileType type = Identify_File(loadedFile);
switch (type) {
case IdentifiedFileType::PSP_ISO:
case IdentifiedFileType::PSP_ISO_NP:
case IdentifiedFileType::PSP_DISC_DIRECTORY:
if (!ReInitMemoryForGameISO(loadedFile)) {
error = "reinit memory failed";
return false;
}
break;
default:
error = "Unsupported file type:" + std::to_string((int)type);
return false;
break;
}
return true;
}
+2
View File
@@ -158,3 +158,5 @@ void RegisterFileLoaderFactory(std::string name, std::unique_ptr<FileLoaderFacto
// Can modify the string filename, as it calls IdentifyFile above.
bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string);
bool UmdReplace(std::string filepath, std::string &error);
+30 -1
View File
@@ -83,7 +83,7 @@ void InitMemoryForGameISO(FileLoader *fileLoader) {
IFileSystem *fileSystem = nullptr;
IFileSystem *blockSystem = nullptr;
bool actualIso = false;
if (fileLoader->IsDirectory()) {
fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path());
blockSystem = fileSystem;
@@ -144,6 +144,35 @@ void InitMemoryForGameISO(FileLoader *fileLoader) {
}
}
bool ReInitMemoryForGameISO(FileLoader *fileLoader) {
if (!fileLoader->Exists()) {
return false;
}
IFileSystem *fileSystem = nullptr;
IFileSystem *blockSystem = nullptr;
if (fileLoader->IsDirectory()) {
fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path());
blockSystem = fileSystem;
} else {
auto bd = constructBlockDevice(fileLoader);
if (!bd)
return false;
ISOFileSystem *iso = new ISOFileSystem(&pspFileSystem, bd);
fileSystem = iso;
blockSystem = new ISOBlockSystem(iso);
}
pspFileSystem.Remount("umd0:", blockSystem);
pspFileSystem.Remount("umd1:", blockSystem);
pspFileSystem.Remount("umd:", blockSystem);
pspFileSystem.Remount("disc0:", fileSystem);
return true;
}
void InitMemoryForGamePBP(FileLoader *fileLoader) {
if (!fileLoader->Exists()) {
return;
+1
View File
@@ -25,5 +25,6 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string);
bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string);
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string);
void InitMemoryForGameISO(FileLoader *fileLoader);
bool ReInitMemoryForGameISO(FileLoader *fileLoader);
void InitMemoryForGamePBP(FileLoader *fileLoader);
void PSPLoaders_Shutdown();
+51 -35
View File
@@ -158,6 +158,38 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for
bool g_DarkStalkerStretch;
void SoftGPU::ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight) {
// TODO: This should probably be converted in a shader instead..
fbTexBuffer_.resize(srcwidth * srcheight);
FormatBuffer displayBuffer;
displayBuffer.data = Memory::GetPointer(displayFramebuf_);
for (int y = 0; y < srcheight; ++y) {
u32 *buf_line = &fbTexBuffer_[y * srcwidth];
const u16 *fb_line = &displayBuffer.as16[y * displayStride_];
switch (displayFormat_) {
case GE_FORMAT_565:
ConvertRGBA565ToRGBA8888(buf_line, fb_line, srcwidth);
break;
case GE_FORMAT_5551:
ConvertRGBA5551ToRGBA8888(buf_line, fb_line, srcwidth);
break;
case GE_FORMAT_4444:
ConvertRGBA4444ToRGBA8888(buf_line, fb_line, srcwidth);
break;
default:
ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_);
}
}
desc.width = srcwidth;
desc.height = srcheight;
desc.initData.push_back((uint8_t *)fbTexBuffer_.data());
}
// Copies RGBA8 data from RAM to the currently bound render target.
void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
if (!draw_)
@@ -191,6 +223,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
Draw::Pipeline *pipeline = texColor;
if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) {
u8 *data = Memory::GetPointer(0x04088000);
bool fillDesc = true;
if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) {
// The perfect one.
desc.format = Draw::DataFormat::A1B5G5R5_UNORM_PACK16;
@@ -198,10 +231,15 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
// RB swapped, compensate with a shader.
desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
pipeline = texColorRBSwizzle;
} else {
ConvertTextureDescFrom16(desc, srcwidth, srcheight);
fillDesc = false;
}
if (fillDesc) {
desc.width = displayStride_ == 0 ? srcwidth : displayStride_;
desc.height = srcheight;
desc.initData.push_back(data);
}
desc.width = displayStride_ == 0 ? srcwidth : displayStride_;
desc.height = srcheight;
desc.initData.push_back(data);
u0 = 64.5f / 512.0f;
u1 = 447.5f / 512.0f;
v1 = 16.0f / 272.0f;
@@ -217,6 +255,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
desc.format = Draw::DataFormat::R8G8B8A8_UNORM;
} else if (displayFormat_ == GE_FORMAT_5551) {
u8 *data = Memory::GetPointer(displayFramebuf_);
bool fillDesc = true;
desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) {
// The perfect one.
@@ -225,40 +264,17 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
// RB swapped, compensate with a shader.
desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
pipeline = texColorRBSwizzle;
} else {
ConvertTextureDescFrom16(desc, srcwidth, srcheight);
fillDesc = false;
}
if (fillDesc) {
desc.width = displayStride_ == 0 ? srcwidth : displayStride_;
desc.height = srcheight;
desc.initData.push_back(data);
}
desc.width = displayStride_ == 0 ? srcwidth : displayStride_;
desc.height = srcheight;
desc.initData.push_back(data);
} else {
// TODO: This should probably be converted in a shader instead..
fbTexBuffer.resize(srcwidth * srcheight);
FormatBuffer displayBuffer;
displayBuffer.data = Memory::GetPointer(displayFramebuf_);
for (int y = 0; y < srcheight; ++y) {
u32 *buf_line = &fbTexBuffer[y * srcwidth];
const u16 *fb_line = &displayBuffer.as16[y * displayStride_];
switch (displayFormat_) {
case GE_FORMAT_565:
ConvertRGBA565ToRGBA8888(buf_line, fb_line, srcwidth);
break;
case GE_FORMAT_5551:
ConvertRGBA5551ToRGBA8888(buf_line, fb_line, srcwidth);
break;
case GE_FORMAT_4444:
ConvertRGBA4444ToRGBA8888(buf_line, fb_line, srcwidth);
break;
default:
ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_);
}
}
desc.width = srcwidth;
desc.height = srcheight;
desc.initData.push_back((uint8_t *)fbTexBuffer.data());
ConvertTextureDescFrom16(desc, srcwidth, srcheight);
u1 = 1.0f;
}
if (!hasImage) {
+2 -1
View File
@@ -101,6 +101,7 @@ public:
protected:
void FastRunLoop(DisplayList &list) override;
void CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight);
void ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight);
private:
bool framebufferDirty_;
@@ -113,7 +114,7 @@ private:
Draw::Texture *fbTex;
Draw::Pipeline *texColor;
Draw::Pipeline *texColorRBSwizzle;
std::vector<u32> fbTexBuffer;
std::vector<u32> fbTexBuffer_;
Draw::SamplerState *samplerNearest = nullptr;
Draw::SamplerState *samplerLinear = nullptr;
+3 -2
View File
@@ -485,8 +485,9 @@ void GPU_Vulkan::InitDeviceObjects() {
hacks |= QUEUE_HACK_MGS2_ACID;
if (PSP_CoreParameter().compat.flags().SonicRivalsHack)
hacks |= QUEUE_HACK_SONIC;
if (PSP_CoreParameter().compat.flags().RenderPassMerge)
hacks |= QUEUE_HACK_RENDERPASS_MERGE;
// Always on.
hacks |= QUEUE_HACK_RENDERPASS_MERGE;
if (hacks) {
rm->GetQueueRunner()->EnableHacks(hacks);
+7 -7
View File
@@ -18,12 +18,12 @@
#include <string>
#include "Qt/QtHost.h"
const char* QtHost::SymbolMapFilename(std::string currentFilename) {
std::string result = currentFilename;
size_t dot = result.rfind('.');
if (dot == result.npos)
return (result + ".map").c_str();
std::string QtHost::SymbolMapFilename(std::string currentFilename) {
size_t dot = currentFilename.rfind('.');
if (dot == std::string::npos)
currentFilename.append(".map");
else
currentFilename.replace(dot, -1, ".map");
result.replace(dot, result.npos, ".map");
return result.c_str();
return currentFilename;
}
+5 -6
View File
@@ -64,13 +64,12 @@ public:
#endif
}
virtual bool AttemptLoadSymbolMap() override {
return false;
// TODO: Make this work with Qt and threaded GL... not sure what's so broken.
// auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart);
// return g_symbolMap->LoadSymbolMap(fn);
auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart);
return g_symbolMap->LoadSymbolMap(fn.c_str());
}
void PrepareShutdown() {
g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart));
auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart);
g_symbolMap->SaveSymbolMap(fn.c_str());
}
void SetWindowTitle(const char *message) override {
std::string title = std::string("PPSSPP ") + PPSSPP_GIT_VERSION;
@@ -91,6 +90,6 @@ public:
}
private:
const char* SymbolMapFilename(std::string currentFilename);
std::string SymbolMapFilename(std::string currentFilename);
MainWindow* mainWindow;
};
+2
View File
@@ -29,6 +29,8 @@ MainWindow::MainWindow(QWidget *parent, bool fullscreen) :
QRect rect = desktop->screenGeometry(screenNum);
move((rect.width()-frameGeometry().width()) / 4, (rect.height()-frameGeometry().height()) / 4);
setWindowIcon(QIcon(qApp->applicationDirPath() + "/assets/icon_regular_72.png"));
SetGameTitle("");
emugl = new MainUI(this);
+3 -1
View File
@@ -910,7 +910,9 @@ int main(int argc, char *argv[]) {
if (!name) {
break;
}
if (g_Config.bAutoAudioDevice || g_Config.sAudioDevice == name) {
// Don't start auto switching for a second, because some devices init on start.
bool doAutoSwitch = g_Config.bAutoAudioDevice && framecount > 60;
if (doAutoSwitch || g_Config.sAudioDevice == name) {
StopSDLAudioDevice();
InitSDLAudioDevice(name ? name : "");
}
+4 -3
View File
@@ -64,11 +64,12 @@ void Discord::Init() {
}
void Discord::Shutdown() {
assert(initialized_);
if (initialized_) {
#ifdef ENABLE_DISCORD
Discord_Shutdown();
Discord_Shutdown();
#endif
initialized_ = false;
initialized_ = false;
}
}
void Discord::Update() {
+15 -3
View File
@@ -243,9 +243,15 @@ bool TouchControlLayoutScreen::touch(const TouchInput &touch) {
// if the leftmost point of the control is ahead of the margin,
// move it. Otherwise, don't.
newX = touch.x;
// Snap to grid
if (g_Config.bTouchSnapToGrid)
newX -= (int)(touch.x - bounds.w) % g_Config.iTouchSnapGridSize;
}
if (touch.y > minTouchY && touch.y < maxTouchY) {
newY = touch.y;
// Snap to grid
if (g_Config.bTouchSnapToGrid)
newY -= (int)(touch.y - bounds.h) % g_Config.iTouchSnapGridSize;
}
pickedControl_->ReplaceLayoutParams(new UI::AnchorLayoutParams(newX, newY, NONE, NONE, true));
} else if (mode == 1) {
@@ -324,11 +330,15 @@ void TouchControlLayoutScreen::CreateViews() {
Choice *reset = new Choice(di->T("Reset"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 84));
Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 10));
Choice *visibility = new Choice(co->T("Visibility"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158));
Choice *visibility = new Choice(co->T("Visibility"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 298));
// controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fButtonScale, 0.80, 2.0, co->T("Button Scaling"), screenManager()))
// ->OnChange.Handle(this, &GameSettingsScreen::OnChangeControlScaling);
mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158 + 64 + 10));
CheckBox *snap = new CheckBox(&g_Config.bTouchSnapToGrid, di->T("Snap"), "", new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 228));
PopupSliderChoice *gridSize = new PopupSliderChoice(&g_Config.iTouchSnapGridSize, 1, 256, di->T("Grid"), screenManager(), "", new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158));
gridSize->SetEnabledPtr(&g_Config.bTouchSnapToGrid);
mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 140 + 158 + 64 + 10));
mode_->AddChoice(di->T("Move"));
mode_->AddChoice(di->T("Resize"));
mode_->SetSelection(0);
@@ -338,6 +348,8 @@ void TouchControlLayoutScreen::CreateViews() {
visibility->OnClick.Handle(this, &TouchControlLayoutScreen::OnVisibility);
root_->Add(mode_);
root_->Add(visibility);
root_->Add(snap);
root_->Add(gridSize);
root_->Add(reset);
root_->Add(back);
@@ -352,7 +364,7 @@ void TouchControlLayoutScreen::CreateViews() {
I18NCategory *ms = GetI18NCategory("MainSettings");
tabHolder->AddTab(ms->T("Controls"), controlsHolder);
//tabHolder->AddTab(ms->T("Controls"), controlsHolder);
if (!g_Config.bShowTouchControls) {
// Shouldn't even be able to get here as the way into this dialog should be closed.
+2 -36
View File
@@ -764,48 +764,14 @@ ULAS42214 = true
ULJS19054 = true
NPJH50184 = true
[RenderPassMerge]
UCJS10114 = true
UCKS45084 = true
# GOW : Ghost of Sparta
UCUS98737 = true
UCAS40323 = true
NPHG00092 = true
NPEG00044 = true
NPEG00045 = true
NPJG00120 = true
NPUG80508 = true
UCJS10114 = true
UCES01401 = true
UCES01473 = true
# GOW : Ghost of Sparta Demo
NPEG90035 = true
NPUG70125 = true
NPJG90095 = true
# GOW : Chains Of Olympus
UCAS40198 = true
UCUS98653 = true
UCES00842 = true
ULJM05438 = true
ULJM05348 = true
UCKS45084 = true
NPUG80325 = true
NPEG00023 = true
NPHG00027 = true
NPHG00028 = true
NPJH50170 = true
UCET00844 = true
# GOW: Chains of Olympus Demo
UCUS98705 = true
UCED00971 = true
UCUS98713 = true
[ForceSoftwareRenderer]
# Darkstalkers
ULES00016 = true
ULUS10005 = true
ULJM05005 = true
[DarkStalkersPresentHack]
# Darkstalkers
ULES00016 = true
ULUS10005 = true
ULJM05005 = true
+1 -1
View File
@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'com.android.tools.build:gradle:3.5.3'
}
}
+9 -5
View File
@@ -495,8 +495,12 @@ void DrawBuffer::DrawTextRect(int font, const char *text, float x, float y, floa
// ROTATE_* doesn't yet work right.
void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color color, int align) {
// rough estimate
if (count_ + strlen(text) * 6 > MAX_VERTS) {
size_t textLen = strlen(text);
if (count_ + textLen * 6 > MAX_VERTS) {
Flush(true);
if (textLen * 6 >= MAX_VERTS) {
textLen = std::min(MAX_VERTS / 6 - 10, (int)textLen);
}
}
const AtlasFont &atlasfont = *atlas->fonts[font];
@@ -508,14 +512,14 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co
}
if (align & ROTATE_90DEG_LEFT) {
x -= atlasfont.ascend*fontscaley;
x -= atlasfont.ascend * fontscaley;
// y += h;
} else {
y += atlasfont.ascend * fontscaley;
}
else
y += atlasfont.ascend*fontscaley;
float sx = x;
UTF8 utf(text);
while (true) {
for (size_t i = 0; i < textLen; i++) {
if (utf.end())
break;
cval = utf.next();
+3 -1
View File
@@ -469,7 +469,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
break;
}
if (profile) {
if (profile && profile->timestampDescriptions.size() + 1 < MAX_TIMESTAMP_QUERIES) {
vkCmdWriteTimestamp(cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, profile->queryPool, (uint32_t)profile->timestampDescriptions.size());
profile->timestampDescriptions.push_back(StepToString(step));
}
@@ -789,11 +789,13 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector<VKRStep *> &steps) {
if (steps[j]->copy.src == fb || steps[j]->copy.dst == fb) {
goto done_fb;
}
touchedFramebuffers.insert(steps[j]->copy.dst);
break;
case VKRStepType::BLIT:
if (steps[j]->blit.src == fb || steps[j]->blit.dst == fb) {
goto done_fb;
}
touchedFramebuffers.insert(steps[j]->blit.dst);
break;
case VKRStepType::READBACK:
// Not sure this has much effect, when executed READBACK is always the last step
+4 -4
View File
@@ -85,6 +85,10 @@ enum class VKRRunType {
SYNC,
};
enum {
MAX_TIMESTAMP_QUERIES = 128,
};
class VulkanRenderManager {
public:
VulkanRenderManager(VulkanContext *vulkan);
@@ -299,10 +303,6 @@ private:
FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES];
enum {
MAX_TIMESTAMP_QUERIES = 256,
};
// Submission time state
int curWidth_ = -1;
int curHeight_ = -1;
+1 -1
Submodule ffmpeg updated: 90701640c7...55147e5f33.