From ff2b6b3fcae05f543b193aee200d128fadbaef67 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 28 Feb 2017 01:47:13 +0100 Subject: [PATCH] Assorted cleanup, UWP memory map fixes. PSPFlower runs in both 32-bit and 64-bit. --- Common/CPUDetect.cpp | 7 ++- Common/FileUtil.cpp | 31 ++++++------ Common/LogManager.cpp | 10 ++-- Common/LogManager.h | 12 +++-- Common/MemArenaWin32.cpp | 8 +++- Common/MemoryUtil.cpp | 10 ++++ Common/stdafx.h | 10 ++-- Core/CwCheat.cpp | 1 - Core/FileSystems/BlockDevices.cpp | 6 +-- Core/FileSystems/VirtualDiscFileSystem.cpp | 8 +++- Core/HLE/__sceAudio.cpp | 2 +- Core/HLE/sceDisplay.cpp | 2 - Core/Loaders.cpp | 6 ++- Core/Loaders.h | 4 +- Core/MIPS/x86/Asm.cpp | 5 +- Core/MIPS/x86/CompVFPU.cpp | 2 +- Core/MIPS/x86/JitSafeMem.cpp | 48 ++++++++++++------- Core/MemMap.cpp | 15 +++++- Core/MemMap.h | 41 +++++++++------- Core/System.cpp | 5 +- UI/CwCheatScreen.cpp | 4 ++ UI/DevScreens.cpp | 6 +++ UI/GameInfoCache.cpp | 3 ++ UWP/CoreUWP/CoreUWP.vcxproj | 12 ++--- UWP/GPU_UWP/GPU_UWP.vcxproj | 12 ++--- UWP/PPSSPP_UWPMain.cpp | 34 +++++++++++-- UWP/StorageFileLoader.cpp | 55 ++++++++++++++++++---- UWP/StorageFileLoader.h | 6 +++ Windows/XinputDevice.cpp | 6 +-- Windows/stdafx.h | 23 +-------- ext/native/ext/vjson/json.cpp | 2 + 31 files changed, 258 insertions(+), 138 deletions(-) diff --git a/Common/CPUDetect.cpp b/Common/CPUDetect.cpp index 42c12a716d..4f4304320b 100644 --- a/Common/CPUDetect.cpp +++ b/Common/CPUDetect.cpp @@ -108,14 +108,13 @@ void CPUInfo::Detect() { #endif num_cores = 1; -#ifdef _WIN32 -#ifdef _M_IX86 +#if PPSSPP_PLATFORM(UWP) + OS64bit = Mode64bit; // TODO: Not always accurate! +#elif defined(_WIN32) && defined(_M_IX86) BOOL f64 = false; IsWow64Process(GetCurrentProcess(), &f64); OS64bit = (f64 == TRUE) ? true : false; #endif -#endif - // Set obvious defaults, for extra safety if (Mode64bit) { bSSE = true; diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index eac8240a93..3aceaa607c 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -123,17 +123,20 @@ bool Exists(const std::string &filename) { StripTailDirSlashes(fn); #if defined(_WIN32) -#if PPSSPP_PLATFORM(UWP) - return false; -#else std::wstring copy = ConvertUTF8ToWString(fn); // Make sure Windows will no longer handle critical errors, which means no annoying "No disk" dialog +#if !PPSSPP_PLATFORM(UWP) int OldMode = SetErrorMode(SEM_FAILCRITICALERRORS); - bool success = GetFileAttributes(copy.c_str()) != INVALID_FILE_ATTRIBUTES; - SetErrorMode(OldMode); - return success; #endif + WIN32_FILE_ATTRIBUTE_DATA data{}; + if (!GetFileAttributesEx(copy.c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { + return false; + } +#if !PPSSPP_PLATFORM(UWP) + SetErrorMode(OldMode); +#endif + return true; #else struct stat64 file_info; return stat64(fn.c_str(), &file_info) == 0; @@ -149,7 +152,7 @@ bool IsDirectory(const std::string &filename) #if defined(_WIN32) std::wstring copy = ConvertUTF8ToWString(fn); WIN32_FILE_ATTRIBUTE_DATA data{}; - if (!GetFileAttributesEx(copy.c_str(), GetFileExInfoStandard, &data)) { + if (!GetFileAttributesEx(copy.c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { WARN_LOG(COMMON, "GetFileAttributes failed on %s: %08x", fn.c_str(), GetLastError()); return false; } @@ -170,28 +173,24 @@ bool IsDirectory(const std::string &filename) // Deletes a given filename, return true on success // Doesn't supports deleting a directory -bool Delete(const std::string &filename) -{ +bool Delete(const std::string &filename) { INFO_LOG(COMMON, "Delete: file %s", filename.c_str()); // Return true because we care about the file no // being there, not the actual delete. - if (!Exists(filename)) - { + if (!Exists(filename)) { WARN_LOG(COMMON, "Delete: %s does not exists", filename.c_str()); return true; } // We can't delete a directory - if (IsDirectory(filename)) - { + if (IsDirectory(filename)) { WARN_LOG(COMMON, "Delete failed: %s is a directory", filename.c_str()); return false; } #ifdef _WIN32 - if (!DeleteFile(ConvertUTF8ToWString(filename).c_str())) - { + if (!DeleteFile(ConvertUTF8ToWString(filename).c_str())) { WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", filename.c_str(), GetLastErrorMsg()); return false; @@ -680,7 +679,7 @@ void openIniFile(const std::string fileName) { std::string iniFile; #if defined(_WIN32) #if PPSSPP_PLATFORM(UWP) - // Not supported + // Do nothing. #else iniFile = fileName; // Can't rely on a .txt file extension to auto-open in the right editor, diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index f237de1ca3..c500bd3e96 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -15,6 +15,8 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "ppsspp_config.h" + #include #include "base/logging.h" @@ -31,9 +33,11 @@ const char *hleCurrentThreadName = nullptr; static const char level_to_char[8] = "-NEWIDV"; -// Unfortunately this is quite slow. +#if PPSSPP_PLATFORM(UWP) && defined(_DEBUG) +#define LOG_MSC_OUTPUTDEBUG true +#else #define LOG_MSC_OUTPUTDEBUG false -// #define LOG_MSC_OUTPUTDEBUG true +#endif void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char* fmt, ...) { if (!g_Config.bEnableLogging) @@ -121,7 +125,7 @@ LogManager::LogManager() { #if !defined(MOBILE_DEVICE) || defined(_DEBUG) AddListener(fileLog_); AddListener(consoleLog_); -#if defined(_MSC_VER) && defined(USING_WIN_UI) +#if defined(_MSC_VER) && (defined(USING_WIN_UI) || PPSSPP_PLATFORM(UWP)) if (IsDebuggerPresent() && debuggerLog_ != NULL && LOG_MSC_OUTPUTDEBUG) AddListener(debuggerLog_); #endif diff --git a/Common/LogManager.h b/Common/LogManager.h index d9d37166f1..9ead61ad17 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -17,6 +17,8 @@ #pragma once +#include "ppsspp_config.h" + #include #include @@ -160,10 +162,13 @@ public: void ChangeFileLog(const char *filename); - void SaveConfig(IniFile::Section *section); - void LoadConfig(IniFile::Section *section, bool debugDefaults); + void SaveConfig(IniFile::Section *section); + void LoadConfig(IniFile::Section *section, bool debugDefaults); private: + LogManager(); + ~LogManager(); + LogChannel log_[LogTypes::NUMBER_OF_LOGS]; FileLogListener *fileLog_; ConsoleListener *consoleLog_; @@ -174,7 +179,4 @@ private: std::mutex listeners_lock_; std::vector listeners_; - - LogManager(); - ~LogManager(); }; diff --git a/Common/MemArenaWin32.cpp b/Common/MemArenaWin32.cpp index 3a22197127..58f70a3528 100644 --- a/Common/MemArenaWin32.cpp +++ b/Common/MemArenaWin32.cpp @@ -29,8 +29,12 @@ size_t MemArena::roundup(size_t x) { } void MemArena::GrabLowMemSpace(size_t size) { +#if !PPSSPP_PLATFORM(UWP) hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL); GetSystemInfo(&sysInfo); +#else + hMemoryMapping = 0; +#endif } void MemArena::ReleaseSpace() { @@ -41,8 +45,8 @@ void MemArena::ReleaseSpace() { void *MemArena::CreateView(s64 offset, size_t size, void *base) { size = roundup(size); #if PPSSPP_PLATFORM(UWP) - // TODO - void *ptr = nullptr; + // Can't map views properly. We just grab some RAM. + void *ptr = VirtualAllocFromApp(NULL, size, MEM_COMMIT, PAGE_READWRITE); #else void *ptr = MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base); #endif diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index 579af8fe7f..d1c41c85cd 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "ppsspp_config.h" + #include "Common.h" #include "MemoryUtil.h" #include "StringUtils.h" @@ -302,11 +303,20 @@ bool ProtectMemoryPages(const void* ptr, size_t size, uint32_t memProtFlags) { // mprotect does not seem to, at least not on Android unless I made a mistake somewhere, so we manually round. #ifdef _WIN32 uint32_t protect = ConvertProtFlagsWin32(memProtFlags); + +#if PPSSPP_PLATFORM(UWP) + DWORD oldValue; + if (!VirtualProtectFromApp((void *)ptr, size, protect, &oldValue)) { + PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); + return false; + } +#else DWORD oldValue; if (!VirtualProtect((void *)ptr, size, protect, &oldValue)) { PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); return false; } +#endif return true; #else uint32_t protect = ConvertProtFlagsUnix(memProtFlags); diff --git a/Common/stdafx.h b/Common/stdafx.h index 463ad8211d..037c0bd0a5 100644 --- a/Common/stdafx.h +++ b/Common/stdafx.h @@ -21,15 +21,17 @@ #ifndef _WIN32_WINNT #if _MSC_VER < 1700 -#define _WIN32_WINNT 0x501 // Compile for XP on Visual Studio 2010 and below +#error You need a newer version of Visual Studio. #else -#define _WIN32_WINNT 0x600 // Compile for Vista on Visual Studio 2012 and above -#endif // #if _MSC_VER < 1700 +#define _WIN32_WINNT 0x600 +#endif #endif // #ifndef _WIN32_WINNT +#undef WINVER +#define WINVER 0x0600 #ifndef _WIN32_IE -#define _WIN32_IE 0x0500 // Default value is 0x0400 +#define _WIN32_IE 0x0600 // Default value is 0x0400 #endif #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index f137b65067..7b17019560 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -155,7 +155,6 @@ void CWCheatEngine::CreateCheatFile() { I18NCategory *err = GetI18NCategory("Error"); host->NotifyUserMessage(err->T("Unable to create cheat file, disk may be full")); } - } } diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 38dbc9dd10..34b5dca5f4 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -36,12 +36,12 @@ BlockDevice *constructBlockDevice(FileLoader *fileLoader) { // Check for CISO if (!fileLoader->Exists()) return nullptr; - char buffer[4]; + char buffer[4]{}; size_t size = fileLoader->ReadAt(0, 1, 4, buffer); fileLoader->Seek(0); - if (!memcmp(buffer, "CISO", 4) && size == 4) + if (size == 4 && !memcmp(buffer, "CISO", 4)) return new CISOFileBlockDevice(fileLoader); - else if (!memcmp(buffer, "\x00PBP", 4) && size == 4) + else if (size == 4 && !memcmp(buffer, "\x00PBP", 4)) return new NPDRMDemoBlockDevice(fileLoader); else return new FileBlockDevice(fileLoader); diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 9992cf7179..5d555e4adc 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -809,11 +809,16 @@ void VirtualDiscFileSystem::HandlerLogger(void *arg, HandlerHandle handle, LogTy } VirtualDiscFileSystem::Handler::Handler(const char *filename, VirtualDiscFileSystem *const sys) { -#if !PPSSPP_PLATFORM(UWP) #ifdef _WIN32 +#if PPSSPP_PLATFORM(UWP) +#define dlopen(name, ignore) (void *)LoadPackagedLibrary(ConvertUTF8ToWString(name).c_str(), 0) +#define dlsym(mod, name) GetProcAddress((HMODULE)mod, name) +#define dlclose(mod) FreeLibrary((HMODULE)mod) +#else #define dlopen(name, ignore) (void *)LoadLibrary(ConvertUTF8ToWString(name).c_str()) #define dlsym(mod, name) GetProcAddress((HMODULE)mod, name) #define dlclose(mod) FreeLibrary((HMODULE)mod) +#endif #endif library = dlopen(filename, RTLD_LOCAL | RTLD_NOW); @@ -842,7 +847,6 @@ VirtualDiscFileSystem::Handler::Handler(const char *filename, VirtualDiscFileSys #undef dlsym #undef dlclose #endif -#endif } VirtualDiscFileSystem::Handler::~Handler() { diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index f0c7051d78..1254fb221e 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -407,7 +407,7 @@ void __AudioUpdate() { // numFrames is number of stereo frames. // This is called from *outside* the emulator thread. int __AudioMix(short *outstereo, int numFrames, int sampleRate) { - return resampler.Mix(outstereo, numFrames, false, sampleRate); + return resampler.Mix(outstereo, numFrames, false, sampleRate); } const AudioDebugStats *__AudioGetDebugStats() { diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 5f06011f0d..290c2f5950 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -291,13 +291,11 @@ void __DisplayDoState(PointerWrap &p) { // Maybe a bit tricky to move at this point, though... gstate_c.DoState(p); -#ifndef _XBOX if (s < 2) { // This shouldn't have been savestated anyway, but it was. // It's unlikely to overlap with the first value in gpuStats. p.ExpectVoid(&gl_extensions.gpuVendor, sizeof(gl_extensions.gpuVendor)); } -#endif if (s < 6) { GPUStatistics_v0 oldStats; p.Do(oldStats); diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index f5e8b3a4ce..4fdebc382b 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -37,7 +37,7 @@ // Gross, gross hack! But necessary for UWP, fitting it in neatly would be a major refactor FileLoader *g_OverriddenLoader; -IdentifiedFileType g_OverriddenFiletype; +IdentifiedFileType g_OverriddenFiletype = FILETYPE_UNKNOWN; void OverrideNextLoader(FileLoader *fileLoader, IdentifiedFileType fileType) { g_OverriddenLoader = fileLoader; @@ -48,7 +48,6 @@ FileLoader *ConstructFileLoader(const std::string &filename) { if (filename.find("http://") == 0 || filename.find("https://") == 0) return new CachingFileLoader(new DiskCachingFileLoader(new RetryingFileLoader(new HTTPFileLoader(filename)))); if (filename == "override://") { - g_OverriddenLoader = nullptr; return g_OverriddenLoader; } return new LocalFileLoader(filename); @@ -56,6 +55,9 @@ FileLoader *ConstructFileLoader(const std::string &filename) { // TODO : improve, look in the file more IdentifiedFileType Identify_File(FileLoader *fileLoader) { + if (g_OverriddenFiletype != FILETYPE_UNKNOWN) + return g_OverriddenFiletype; + if (fileLoader == nullptr) { ERROR_LOG(LOADER, "Invalid fileLoader"); return IdentifiedFileType::ERROR_IDENTIFYING; diff --git a/Core/Loaders.h b/Core/Loaders.h index 7a8f8a759d..d4d3764f72 100644 --- a/Core/Loaders.h +++ b/Core/Loaders.h @@ -18,6 +18,7 @@ #pragma once #include + #include "Common/CommonTypes.h" enum class IdentifiedFileType { @@ -47,7 +48,7 @@ enum class IdentifiedFileType { PSP_SAVEDATA_DIRECTORY, PPSSPP_SAVESTATE, - UNKNOWN + UNKNOWN, }; class FileLoader { @@ -101,6 +102,7 @@ std::string ResolvePBPFile(const std::string &filename); IdentifiedFileType Identify_File(FileLoader *fileLoader); +void RegisterFileLoaderFactory(std::string name, std::function factoryFunc); void OverrideNextLoader(FileLoader *fileLoader, IdentifiedFileType fileType); // Can modify the string filename, as it calls IdentifyFile above. diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp index e0134518b3..abf5ff452a 100644 --- a/Core/MIPS/x86/Asm.cpp +++ b/Core/MIPS/x86/Asm.cpp @@ -170,8 +170,11 @@ void Jit::GenerateFixedCode(JitOptions &jo) { MOV(32, R(EAX), M(&mips_->pc)); dispatcherInEAXNoCheck = GetCodePtr(); -#ifdef _M_IX86 +#ifdef MASKED_PSP_MEMORY AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); +#endif + +#ifdef _M_IX86 _assert_msg_(CPU, Memory::base != 0, "Memory base bogus"); MOV(32, R(EAX), MDisp(EAX, (u32)Memory::base)); #elif _M_X64 diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 50a9a01c2a..8085a0f445 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -314,7 +314,7 @@ void Jit::Comp_SVQ(MIPSOpcode op) GetVectorRegs(vregs, V_Quad, vt); MOV(32, R(EAX), gpr.R(rs)); ADD(32, R(EAX), Imm32(imm)); -#ifdef _M_IX86 +#ifdef MASKED_PSP_MEMORY AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); #endif MOV(32, R(ECX), R(EAX)); diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index 95f74ad358..fb3aeaa5d4 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "ppsspp_config.h" + #if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) #include "Core/Config.h" @@ -84,11 +85,15 @@ bool JitSafeMem::PrepareWrite(OpArg &dest, int size) if (ImmValid()) { MemCheckImm(MEM_WRITE); + u32 addr = (iaddr_ & alignMask_); +#ifdef MASKED_PSP_MEMORY + addr &= Memory::MEMVIEW32_MASK; +#endif -#ifdef _M_IX86 - dest = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK & alignMask_)); +#if PPSSPP_ARCH(32BIT) + dest = M(Memory::base + addr); #else - dest = MDisp(MEMBASEREG, iaddr_ & alignMask_); + dest = MDisp(MEMBASEREG, addr); #endif return true; } @@ -109,11 +114,15 @@ bool JitSafeMem::PrepareRead(OpArg &src, int size) if (ImmValid()) { MemCheckImm(MEM_READ); + u32 addr = (iaddr_ & alignMask_); +#ifdef MASKED_PSP_MEMORY + addr &= Memory::MEMVIEW32_MASK; +#endif -#ifdef _M_IX86 - src = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK & alignMask_)); +#if PPSSPP_ARCH(32BIT) + src = M(Memory::base + addr); #else - src = MDisp(MEMBASEREG, iaddr_ & alignMask_); + src = MDisp(MEMBASEREG, addr); #endif return true; } @@ -130,9 +139,12 @@ OpArg JitSafeMem::NextFastAddress(int suboffset) if (iaddr_ != (u32) -1) { u32 addr = (iaddr_ + suboffset) & alignMask_; +#ifdef MASKED_PSP_MEMORY + addr &= Memory::MEMVIEW32_MASK; +#endif -#ifdef _M_IX86 - return M(Memory::base + (addr & Memory::MEMVIEW32_MASK)); +#if PPSSPP_ARCH(32BIT) + return M(Memory::base + addr); #else return MDisp(MEMBASEREG, addr); #endif @@ -140,7 +152,7 @@ OpArg JitSafeMem::NextFastAddress(int suboffset) _dbg_assert_msg_(JIT, (suboffset & alignMask_) == suboffset, "suboffset must be aligned"); -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) return MDisp(xaddr_, (u32) Memory::base + offset_ + suboffset); #else return MComplex(MEMBASEREG, xaddr_, SCALE_1, offset_ + suboffset); @@ -152,7 +164,7 @@ OpArg JitSafeMem::PrepareMemoryOpArg(MemoryOpType type) // We may not even need to move into EAX as a temporary. bool needTemp = alignMask_ != 0xFFFFFFFF; -#ifdef _M_IX86 +#ifdef MASKED_PSP_MEMORY bool needMask = true; // raddr_ != MIPS_REG_SP; // Commented out this speedhack due to low impact // We always mask on 32 bit in fast memory mode. needTemp = needTemp || (fast_ && needMask); @@ -184,7 +196,7 @@ OpArg JitSafeMem::PrepareMemoryOpArg(MemoryOpType type) } else { -#ifdef _M_IX86 +#ifdef MASKED_PSP_MEMORY if (needMask) { jit_->AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); } @@ -200,7 +212,7 @@ OpArg JitSafeMem::PrepareMemoryOpArg(MemoryOpType type) jit_->SUB(32, R(xaddr_), Imm32(offset_)); } -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) return MDisp(xaddr_, (u32) Memory::base + offset_); #else return MComplex(MEMBASEREG, xaddr_, SCALE_1, offset_); @@ -249,7 +261,7 @@ void JitSafeMem::DoSlowWrite(const void *safeFunc, const OpArg& src, int suboffs jit_->AND(32, R(EAX), Imm32(alignMask_)); } -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) jit_->PUSH(EDX); #endif if (!src.IsSimpleReg(EDX)) { @@ -260,7 +272,7 @@ void JitSafeMem::DoSlowWrite(const void *safeFunc, const OpArg& src, int suboffs } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) jit_->POP(EDX); #endif needsCheck_ = true; @@ -449,7 +461,7 @@ void JitSafeMemFuncs::CreateReadFunc(int bits, const void *fallbackFunc) { CheckDirectEAX(); // Since we were CALLed, we need to align the stack before calling C++. -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) SUB(32, R(ESP), Imm8(16 - 4)); ABI_CallFunctionA(thunks_->ProtectFunction(fallbackFunc, 1), R(EAX)); ADD(32, R(ESP), Imm8(16 - 4)); @@ -463,7 +475,7 @@ void JitSafeMemFuncs::CreateReadFunc(int bits, const void *fallbackFunc) { StartDirectAccess(); -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) MOVZX(32, bits, EAX, MDisp(EAX, (u32)Memory::base)); #else MOVZX(32, bits, EAX, MRegSum(MEMBASEREG, EAX)); @@ -476,7 +488,7 @@ void JitSafeMemFuncs::CreateWriteFunc(int bits, const void *fallbackFunc) { CheckDirectEAX(); // Since we were CALLed, we need to align the stack before calling C++. -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) // 4 for return, 4 for saved reg on stack. SUB(32, R(ESP), Imm8(16 - 4 - 4)); ABI_CallFunctionAA(thunks_->ProtectFunction(fallbackFunc, 2), R(EDX), R(EAX)); @@ -491,7 +503,7 @@ void JitSafeMemFuncs::CreateWriteFunc(int bits, const void *fallbackFunc) { StartDirectAccess(); -#ifdef _M_IX86 +#if PPSSPP_ARCH(32BIT) MOV(bits, MDisp(EAX, (u32)Memory::base), R(EDX)); #else MOV(bits, MRegSum(MEMBASEREG, EAX), R(EDX)); diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 923fcfedc0..c2f3248211 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -152,7 +152,10 @@ static bool Memory_TryBase(u32 flags) { if (view.flags & MV_MIRROR_PREVIOUS) { position = last_position; } -#if PPSSPP_ARCH(64BIT) +#if PPSSPP_PLATFORM(UWP) + // For both 32-bit and 64-bit, we need to use address masking. + *(view.out_ptr) = (u8*)VirtualAllocFromApp(base + (view.virtual_address & MEMVIEW32_MASK), view.size, MEM_COMMIT, PAGE_READWRITE); +#elif PPSSPP_ARCH(64BIT) *view.out_ptr = (u8*)g_arena.CreateView( position, view.size, base + view.virtual_address); if (!*view.out_ptr) { @@ -177,7 +180,7 @@ static bool Memory_TryBase(u32 flags) { } return true; - +#if !PPSSPP_PLATFORM(UWP) bail: // Argh! ERROR! Free what we grabbed so far so we can try again. for (int j = 0; j <= i; j++) { @@ -192,9 +195,16 @@ bail: } } return false; +#endif } bool MemoryMap_Setup(u32 flags) { +#if PPSSPP_PLATFORM(UWP) + // We just grab all 256MB. + // We should be able to avoid COMMIT-ing here, TODO. + base = (u8*)VirtualAllocFromApp(0, 0x10000000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + return true; +#else // Figure out how much memory we need to allocate in total. size_t total_mem = 0; for (int i = 0; i < num_views; i++) { @@ -242,6 +252,7 @@ bool MemoryMap_Setup(u32 flags) { // Should return true... return Memory_TryBase(flags); +#endif } void MemoryMap_Shutdown(u32 flags) { diff --git a/Core/MemMap.h b/Core/MemMap.h index 1e66e51d97..da7a52ea26 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -81,6 +81,12 @@ extern u8 *m_pUncachedRAM; extern u32 g_MemorySize; extern u32 g_PSPModel; +// UWP has such limited memory management that we need to mask +// even in 64-bit mode. +#if PPSSPP_ARCH(32BIT) || PPSSPP_PLATFORM(UWP) +#define MASKED_PSP_MEMORY +#endif + enum { // This may be adjusted by remaster games. @@ -92,7 +98,7 @@ enum SCRATCHPAD_SIZE = 0x00004000, -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY // This wraparound should work for PSP too. MEMVIEW32_MASK = 0x3FFFFFFF, #endif @@ -126,8 +132,7 @@ void Clear(); // False when shutdown has already been called. bool IsActive(); -class MemoryInitedLock -{ +class MemoryInitedLock { public: MemoryInitedLock(); ~MemoryInitedLock(); @@ -156,7 +161,7 @@ u64 Read_U64(const u32 _Address); #endif inline u8* GetPointerUnchecked(const u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return (u8 *)(base + (address & MEMVIEW32_MASK)); #else return (u8 *)(base + address); @@ -174,7 +179,7 @@ void WriteUnchecked_U32(const u32 _Data, const u32 _Address); #else inline u32 ReadUnchecked_U32(const u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return *(u32_le *)(base + (address & MEMVIEW32_MASK)); #else return *(u32_le *)(base + address); @@ -182,7 +187,7 @@ inline u32 ReadUnchecked_U32(const u32 address) { } inline float ReadUnchecked_Float(const u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return *(float *)(base + (address & MEMVIEW32_MASK)); #else return *(float *)(base + address); @@ -190,7 +195,7 @@ inline float ReadUnchecked_Float(const u32 address) { } inline u16 ReadUnchecked_U16(const u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return *(u16_le *)(base + (address & MEMVIEW32_MASK)); #else return *(u16_le *)(base + address); @@ -198,15 +203,15 @@ inline u16 ReadUnchecked_U16(const u32 address) { } inline u8 ReadUnchecked_U8(const u32 address) { -#if PPSSPP_ARCH(32BIT) - return (*(u8 *)(base + (address & MEMVIEW32_MASK))); +#ifdef MASKED_PSP_MEMORY + return (*(u8 *)(base + (address & MEMVIEW32_MASK))); #else return (*(u8 *)(base + address)); #endif } inline void WriteUnchecked_U32(u32 data, u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY *(u32_le *)(base + (address & MEMVIEW32_MASK)) = data; #else *(u32_le *)(base + address) = data; @@ -214,7 +219,7 @@ inline void WriteUnchecked_U32(u32 data, u32 address) { } inline void WriteUnchecked_Float(float data, u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY *(float *)(base + (address & MEMVIEW32_MASK)) = data; #else *(float *)(base + address) = data; @@ -222,7 +227,7 @@ inline void WriteUnchecked_Float(float data, u32 address) { } inline void WriteUnchecked_U16(u16 data, u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY *(u16_le *)(base + (address & MEMVIEW32_MASK)) = data; #else *(u16_le *)(base + address) = data; @@ -230,7 +235,7 @@ inline void WriteUnchecked_U16(u16 data, u32 address) { } inline void WriteUnchecked_U8(u8 data, u32 address) { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY (*(u8 *)(base + (address & MEMVIEW32_MASK))) = data; #else (*(u8 *)(base + address)) = data; @@ -337,7 +342,7 @@ struct PSPPointer inline T &operator*() const { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return *(T *)(Memory::base + (ptr & Memory::MEMVIEW32_MASK)); #else return *(T *)(Memory::base + ptr); @@ -346,7 +351,7 @@ struct PSPPointer inline T &operator[](int i) const { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return *((T *)(Memory::base + (ptr & Memory::MEMVIEW32_MASK)) + i); #else return *((T *)(Memory::base + ptr) + i); @@ -355,7 +360,7 @@ struct PSPPointer inline T *operator->() const { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return (T *)(Memory::base + (ptr & Memory::MEMVIEW32_MASK)); #else return (T *)(Memory::base + ptr); @@ -424,7 +429,7 @@ struct PSPPointer inline operator T*() { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return (T *)(Memory::base + (ptr & Memory::MEMVIEW32_MASK)); #else return (T *)(Memory::base + ptr); @@ -433,7 +438,7 @@ struct PSPPointer inline operator const T*() const { -#if PPSSPP_ARCH(32BIT) +#ifdef MASKED_PSP_MEMORY return (const T *)(Memory::base + (ptr & Memory::MEMVIEW32_MASK)); #else return (const T *)(Memory::base + ptr); diff --git a/Core/System.cpp b/Core/System.cpp index 8211a675ff..878aa20d2c 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -629,14 +629,12 @@ void InitSysDirectories() { // Detect the "My Documents"(XP) or "Documents"(on Vista/7/8) folder. #if PPSSPP_PLATFORM(UWP) - const std::string myDocsPath = ""; // TODO UWP - const HRESULT result = E_FAIL; + // We set g_Config.memStickDirectory outside. #else wchar_t myDocumentsPath[MAX_PATH]; const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath); const std::string myDocsPath = ConvertWStringToUTF8(myDocumentsPath) + "/PPSSPP/"; -#endif const std::string installedFile = path + "installed.txt"; const bool installed = File::Exists(installedFile); @@ -686,6 +684,7 @@ void InitSysDirectories() { // Clean up our mess. if (File::Exists(testFile)) File::Delete(testFile); +#endif // Create the default directories that a real PSP creates. Good for homebrew so they can // expect a standard environment. Skipping THEME though, that's pointless. diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index 41fc61819b..891e64cf78 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -177,7 +177,11 @@ UI::EventReturn CwCheatScreen::OnEditCheatFile(UI::EventParams ¶ms) { MIPSComp::jit->ClearCache(); } TriggerFinish(DR_OK); +#if PPSSPP_PLATFORM(UWP) + LaunchBrowser(activeCheatFile.c_str()); +#else File::openIniFile(activeCheatFile); +#endif return UI::EVENT_DONE; } diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 19d9c98a01..03f0b01391 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -391,6 +391,12 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem("Memory Page Size", StringFromFormat("%d bytes", GetMemoryProtectPageSize()))); deviceSpecs->Add(new InfoItem("RW/RX exclusive: ", PlatformIsWXExclusive() ? "Yes" : "No")); + const char *build = "Release"; +#ifdef _DEBUG + build = "Debug"; +#endif + deviceSpecs->Add(new InfoItem("PPSSPP build: ", build)); + #ifdef __ANDROID__ deviceSpecs->Add(new ItemHeader("Audio Information")); deviceSpecs->Add(new InfoItem("Sample rate", StringFromFormat("%d Hz", System_GetPropertyInt(SYSPROP_AUDIO_SAMPLE_RATE)))); diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 4f079b50b9..bda38d9564 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -531,6 +531,9 @@ handleELF: // Let's assume it's an ISO. // TODO: This will currently read in the whole directory tree. Not really necessary for just a // few files. + FileLoader *fl = info_->GetFileLoader(); + if (!fl) + return; // Happens with UWP currently, TODO... BlockDevice *bd = constructBlockDevice(info_->GetFileLoader()); if (!bd) return; // nothing to do here.. diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index a52732c0d9..d0ada12009 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -122,7 +122,7 @@ true pch.h ../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -137,7 +137,7 @@ true pch.h ../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -152,7 +152,7 @@ true pch.h ../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -167,7 +167,7 @@ true pch.h ../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -182,7 +182,7 @@ true pch.h ../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -197,7 +197,7 @@ true pch.h ../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 28da0faa55..3e9fbd6a1d 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -122,7 +122,7 @@ true pch.h ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -137,7 +137,7 @@ true pch.h ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -152,7 +152,7 @@ true pch.h ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -167,7 +167,7 @@ true pch.h ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -182,7 +182,7 @@ true pch.h ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -197,7 +197,7 @@ true pch.h ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index b8930567cd..79b40f5325 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -15,6 +15,8 @@ #include "file/vfs.h" #include "file/zip_read.h" #include "file/file_util.h" +#include "net/http_client.h" +#include "net/resolve.h" #include "base/display.h" #include "util/text/utf8.h" #include "Common/DirectXHelper.h" @@ -45,6 +47,8 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrRegisterDeviceNotify(this); @@ -80,13 +84,18 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrLocalFolder->Path->Data(); + + g_Config.memStickDirectory = ReplaceAll(ConvertWStringToUTF8(memstickFolderW), "\\", "/"); + if (g_Config.memStickDirectory.back() != '/') + g_Config.memStickDirectory += "/"; + // On Win32 it makes more sense to initialize the system directories here // because the next place it was called was in the EmuThread, and it's too late by then. InitSysDirectories(); // Load config up here, because those changes below would be overwritten // if it's not loaded here first. - g_Config.AddSearchPath(""); g_Config.AddSearchPath(GetSysDirectory(DIRECTORY_SYSTEM)); g_Config.SetDefaultPath(GetSysDirectory(DIRECTORY_SYSTEM)); g_Config.Load(configFilename, controlsConfigFilename); @@ -102,12 +111,16 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrSetAllLogLevels(LogTypes::LDEBUG); + } const char *argv[2] = { "fake", nullptr }; - NativeInit(1, argv, "", "", "", false); + + std::string cacheFolder = ConvertWStringToUTF8(ApplicationData::Current->LocalFolder->Path->Data()); + + NativeInit(1, argv, "", "", cacheFolder.c_str(), false); NativeInitGraphics(ctx_.get()); NativeResized(); @@ -125,6 +138,7 @@ PPSSPP_UWPMain::~PPSSPP_UWPMain() { // Deregister device notification m_deviceResources->RegisterDeviceNotify(nullptr); + net::Shutdown(); } // Updates application state when the window size changes (e.g. device orientation change) @@ -293,6 +307,7 @@ void System_SendMessage(const char *command, const char *parameter) { picker->FileTypeFilter->Append(".cso"); picker->FileTypeFilter->Append(".iso"); picker->FileTypeFilter->Append(".bin"); + picker->SuggestedStartLocation = Pickers::PickerLocationId::DocumentsLibrary; create_task(picker->PickSingleFileAsync()).then([](StorageFile ^file){ g_main->LoadStorageFile(file); @@ -318,7 +333,18 @@ void LaunchBrowser(const char *url) { } void Vibrate(int length_ms) { - // TODO: Use Windows::Phone::Devices::Notification where available +#if _M_ARM + if (length_ms == -1 || length_ms == -3) + length_ms = 50; + else if (length_ms == -2) + length_ms = 25; + else + return; + + auto timeSpan = Windows::Foundation::TimeSpan(); + timeSpan.Duration = length_ms * 10000; + Windows::Phone::Devices::Notification::VibrationDevice::GetDefault()->Vibrate(timeSpan); +#endif } void System_AskForPermission(SystemPermission permission) { diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index f9976562b5..1f51424617 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -8,11 +8,17 @@ using namespace Windows::Storage; using namespace Windows::Storage::Streams; StorageFileLoader::StorageFileLoader(Windows::Storage::StorageFile ^file) { - create_task(file->OpenReadAsync()).then([this](IRandomAccessStreamWithContentType ^stream) { + file_ = file; + auto opentask = create_task(file->OpenReadAsync()); + opentask.then([this](IRandomAccessStreamWithContentType ^stream) { stream_ = stream; active_ = true; thread_ = std::thread([this]() { this->threadfunc(); }); }); + auto attrtask = create_task(file->GetBasicPropertiesAsync()); + attrtask.then([this](Windows::Storage::FileProperties::BasicProperties ^props) { + size_ = props->Size; + }); } StorageFileLoader::~StorageFileLoader() { @@ -54,28 +60,63 @@ bool StorageFileLoader::ExistsFast() { } bool StorageFileLoader::IsDirectory() { - return false; + return (file_->Attributes & Windows::Storage::FileAttributes::Directory) != Windows::Storage::FileAttributes::Normal; } s64 StorageFileLoader::FileSize() { - return 0; + if (size_ == -1) + __debugbreak(); // crude race condition detection + return size_; } -std::string StorageFileLoader::Path() const { return ""; } +std::string StorageFileLoader::Path() const { + return ""; +} -std::string StorageFileLoader::Extension() { return ""; } +std::string StorageFileLoader::Extension() { + return ""; +} +void StorageFileLoader::EnsureOpen() { + while (size_ == -1) + Sleep(100); +} + +// Note that multithreaded use could wreak havoc with this... void StorageFileLoader::Seek(s64 absolutePos) { + EnsureOpen(); seekPos_ = absolutePos; } size_t StorageFileLoader::Read(size_t bytes, size_t count, void *data, Flags flags) { + EnsureOpen(); { std::unique_lock lock(mutex_); operations_.push(Operation{ OpType::READ, seekPos_, (int64_t)(bytes * count) }); cond_.notify_one(); } // OK, now wait for response... + { + std::unique_lock responseLock(mutexResponse_); + condResponse_.wait(responseLock); + Operation resp = responses_.front(); + responses_.pop(); + DataReader ^rd = DataReader::FromBuffer(resp.buffer); + Platform::Array ^bytearray = ref new Platform::Array(resp.buffer->Length); + rd->ReadBytes(bytearray); + memcpy(data, bytearray->Data, bytes * count); + return 0; + } +} + +size_t StorageFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) { + EnsureOpen(); + { + std::unique_lock lock(mutex_); + operations_.push(Operation{ OpType::READ, absolutePos, (int64_t)(bytes * count) }); + cond_.notify_one(); + } + // OK, now wait for response... { std::unique_lock responseLock(mutexResponse_); condResponse_.wait(responseLock); @@ -85,7 +126,3 @@ size_t StorageFileLoader::Read(size_t bytes, size_t count, void *data, Flags fla return 0; } } - -size_t StorageFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) { - return 0; -} diff --git a/UWP/StorageFileLoader.h b/UWP/StorageFileLoader.h index a73a86620f..cda75d2d0a 100644 --- a/UWP/StorageFileLoader.h +++ b/UWP/StorageFileLoader.h @@ -10,6 +10,9 @@ #include "Common/CommonTypes.h" #include "Core/Loaders.h" +// This thing is a terrible abomination that wraps asynchronous file access behind a synchronous interface, +// completely defeating MS' design goals for StorageFile. But hey, you gotta do what you gotta do. + class StorageFileLoader : public FileLoader { public: StorageFileLoader(Windows::Storage::StorageFile ^file); @@ -28,6 +31,7 @@ public: private: void threadfunc(); + void EnsureOpen(); enum class OpType { READ, @@ -41,7 +45,9 @@ private: }; bool active_ = false; + int64_t size_ = -1; std::thread thread_; + Windows::Storage::StorageFile ^file_; Windows::Storage::Streams::IRandomAccessStreamWithContentType ^stream_; std::condition_variable cond_; std::mutex mutex_; diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 327d0c0930..1604022de2 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -138,7 +138,7 @@ inline float LinearMapf(float val, float a0, float a1, float b0, float b1) { } static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, float idz, float st) { - Stick s(x, y, 1.0 / 32767.0f); + Stick s(x, y, 1.0f / 32767.0f); float magnitude = sqrtf(s.x * s.x + s.y * s.y); if (magnitude > dz) { @@ -194,8 +194,8 @@ static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, floa } bool NormalizedDeadzoneDiffers(short x1, short y1, short x2, short y2, const float dz) { - Stick s1(x1, y1, 1.0 / 32767.0f); - Stick s2(x2, y2, 1.0 / 32767.0f); + Stick s1(x1, y1, 1.0f / 32767.0f); + Stick s2(x2, y2, 1.0f / 32767.0f); float magnitude1 = sqrtf(s1.x * s1.x + s1.y * s1.y); float magnitude2 = sqrtf(s2.x * s2.x + s2.y * s2.y); diff --git a/Windows/stdafx.h b/Windows/stdafx.h index 4bae55eb37..8d896ecfb5 100644 --- a/Windows/stdafx.h +++ b/Windows/stdafx.h @@ -19,16 +19,13 @@ #pragma warning(disable:4996) -// #define WIN32_LEAN_AND_MEAN // WinSock2 MUST be included before !!! #include -//#ifdef WINDOWS - #undef _WIN32_WINNT #if _MSC_VER < 1700 -#define _WIN32_WINNT 0x501 // Compile for XP on Visual Studio 2010 and below +#error You need a newer version of Visual Studio #else #define _WIN32_WINNT 0x600 // Compile for Vista on Visual Studio 2012 and above #endif @@ -41,27 +38,17 @@ #undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -//#define UNICODE #if defined _M_IX86 - #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") - -#elif defined _M_IA64 - -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") - #elif defined _M_X64 - #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") - #else - #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - #endif #include "Common/CommonWindows.h" + #include #include #include @@ -76,9 +63,3 @@ #include #include "Common/Log.h" - -//#else - - -//#endif - diff --git a/ext/native/ext/vjson/json.cpp b/ext/native/ext/vjson/json.cpp index 654c37954d..7203cb577b 100644 --- a/ext/native/ext/vjson/json.cpp +++ b/ext/native/ext/vjson/json.cpp @@ -286,6 +286,8 @@ void json_append(json_value *lhs, json_value *rhs) } } +#undef ERROR + #define ERROR(it, desc)\ *error_pos = it;\ *error_desc = (char *)desc;\