Merge branch 'master' into TemporaryHackishBranch

# Conflicts:
#	Core/Config.cpp
This commit is contained in:
LunaMoo committed 2019-03-25 08:43:34 +01:00
commit 92832759fa
126 files changed
+1318 -566

No files matched your search

+1
View File
@@ -39,6 +39,7 @@ assets/flash0
UWP/icph
UWP/.vs
.vs
.vscode
# For Mac
.DS_Store
+1 -1
View File
@@ -58,7 +58,7 @@ matrix:
env: PPSSPP_BUILD_TYPE=Android
APP_ABI=x86_64
- os: linux
compiler: "clang linux"
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
- os: linux
compiler: "gcc"
+4 -3
View File
@@ -108,7 +108,7 @@ option(USING_EGL "Set to ON if target environment uses EGL" ${USING_EGL})
option(USING_FBDEV "Set to ON if target environment uses fbdev (eg. Pandora)" ${USING_FBDEV})
option(USING_GLES2 "Set to ON if target device uses OpenGL ES 2.0" ${USING_GLES2})
option(USING_X11_VULKAN "Set to OFF if target environment doesn't use X11 for Vulkan" ON)
option(USE_WAYLAND_WSI "Enable or disable Wayland WSI support for Vulkan" ON)
option(USE_WAYLAND_WSI "Enable or disable Wayland WSI support for Vulkan" ${USE_WAYLAND_WSI})
# :: Frontends
option(USING_QT_UI "Set to ON if you wish to use the Qt frontend wrapper" ${USING_QT_UI})
option(MOBILE_DEVICE "Set to ON when targeting a mobile device" ${MOBILE_DEVICE})
@@ -270,8 +270,6 @@ if(NOT MSVC)
add_compile_options(-fno-strict-aliasing)
if(${CMAKE_C_COMPILER_ID} STREQUAL "Intel")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -parallel -fopenmp")
else()
add_compile_options(-ffast-math)
endif()
if(X86 OR X86_64)
@@ -1992,6 +1990,9 @@ if(TargetBin)
add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource} "ios/Launch Screen.storyboard")
else()
add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource})
if(TARGET SDL2::SDL2)
add_custom_command(TARGET ${TargetBin} POST_BUILD COMMAND /bin/bash "${CMAKE_SOURCE_DIR}/SDL/macbundle.sh" "${CMAKE_BINARY_DIR}/PPSSPPSDL.app")
endif()
endif()
elseif(WIN32)
add_executable(${TargetBin} WIN32 ${NativeAppSource})
+4 -4
View File
@@ -76,7 +76,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<MinimalRebuild>false</MinimalRebuild>
@@ -103,7 +103,7 @@
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
@@ -133,7 +133,7 @@
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@@ -166,7 +166,7 @@
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+2 -1
View File
@@ -133,6 +133,7 @@ std::string ResolvePath(const std::string &path) {
int result = getFinalPathNameByHandleW(hFile, buf, BUF_SIZE - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
if (result >= BUF_SIZE || result == 0)
wcscpy_s(buf, BUF_SIZE - 1, input.c_str());
CloseHandle(hFile);
}
} else {
wchar_t *longBuf = new wchar_t[BUF_SIZE];
@@ -829,7 +830,7 @@ const std::string &GetExeDirectory()
uint32_t program_path_size = sizeof(program_path) - 1;
#if defined(__linux__)
if (readlink("/proc/self/exe", program_path, 4095) > 0)
if (readlink("/proc/self/exe", program_path, program_path_size) > 0)
#elif defined(__APPLE__) && !defined(IOS)
if (_NSGetExecutablePath(program_path, &program_path_size) == 0)
#elif defined(KERN_PROC_PATHNAME)
+11 -7
View File
@@ -30,7 +30,7 @@ static bool IsDepthStencilFormat(VkFormat format) {
}
}
bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) {
bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *allocator, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) {
Wipe();
width_ = w;
@@ -75,7 +75,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
bool dedicatedAllocation = false;
vulkan_->GetImageMemoryRequirements(image_, &mem_reqs, &dedicatedAllocation);
if (allocator_ && !dedicatedAllocation) {
if (allocator && !dedicatedAllocation) {
allocator_ = allocator;
offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag());
if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) {
ELOG("Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits);
@@ -231,10 +232,13 @@ void VulkanTexture::Destroy() {
if (image_ != VK_NULL_HANDLE) {
vulkan_->Delete().QueueDeleteImage(image_);
}
if (mem_ != VK_NULL_HANDLE && !allocator_) {
vulkan_->Delete().QueueDeleteDeviceMemory(mem_);
} else if (mem_ != VK_NULL_HANDLE) {
allocator_->Free(mem_, offset_);
mem_ = VK_NULL_HANDLE;
if (mem_ != VK_NULL_HANDLE) {
if (allocator_) {
allocator_->Free(mem_, offset_);
mem_ = VK_NULL_HANDLE;
allocator_ = nullptr;
} else {
vulkan_->Delete().QueueDeleteDeviceMemory(mem_);
}
}
}
+4 -4
View File
@@ -8,8 +8,8 @@ class VulkanDeviceAllocator;
// Not very optimal - if you have many small textures you should use other strategies.
class VulkanTexture {
public:
VulkanTexture(VulkanContext *vulkan, VulkanDeviceAllocator *allocator)
: vulkan_(vulkan), allocator_(allocator) {
VulkanTexture(VulkanContext *vulkan)
: vulkan_(vulkan) {
}
~VulkanTexture() {
Destroy();
@@ -18,7 +18,7 @@ public:
// Fast uploads from buffer. Mipmaps supported.
// Usage must at least include VK_IMAGE_USAGE_TRANSFER_DST_BIT in order to use UploadMip.
// When using UploadMip, initialLayout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
bool CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr);
bool CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *allocator, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr);
void UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength); // rowLength is in pixels
void GenerateMip(VkCommandBuffer cmd, int mip);
void EndCreate(VkCommandBuffer cmd, bool vertexTexture = false);
@@ -55,7 +55,7 @@ private:
int32_t height_ = 0;
int32_t numMips_ = 1;
VkFormat format_ = VK_FORMAT_UNDEFINED;
VulkanDeviceAllocator *allocator_;
VulkanDeviceAllocator *allocator_ = nullptr; // If set, memory is from this allocator.
size_t offset_ = 0;
std::string tag_;
};
+15 -17
View File
@@ -23,9 +23,8 @@
#include "base/timeutil.h"
#include "math/math_util.h"
VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size) : device_(vulkan->GetDevice()), buf_(0), offset_(0), size_(size), writePtr_(nullptr) {
vulkan->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &memoryTypeIndex_);
VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage)
: vulkan_(vulkan), size_(size), usage_(usage) {
bool res = AddBuffer();
assert(res);
}
@@ -36,43 +35,42 @@ VulkanPushBuffer::~VulkanPushBuffer() {
bool VulkanPushBuffer::AddBuffer() {
BufInfo info;
VkDevice device = vulkan_->GetDevice();
VkBufferCreateInfo b{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
b.size = size_;
b.flags = 0;
b.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
b.usage = usage_;
b.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
b.queueFamilyIndexCount = 0;
b.pQueueFamilyIndices = nullptr;
VkResult res = vkCreateBuffer(device_, &b, nullptr, &info.buffer);
VkResult res = vkCreateBuffer(device, &b, nullptr, &info.buffer);
if (VK_SUCCESS != res) {
_assert_msg_(G3D, false, "vkCreateBuffer failed! result=%d", (int)res);
return false;
}
// Make validation happy.
// Get the buffer memory requirements. None of this can be cached!
VkMemoryRequirements reqs;
vkGetBufferMemoryRequirements(device_, info.buffer, &reqs);
// TODO: We really should use memoryTypeIndex here..
vkGetBufferMemoryRequirements(device, info.buffer, &reqs);
// Okay, that's the buffer. Now let's allocate some memory for it.
VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
// TODO: Should check here that memoryTypeIndex_ matches reqs.memoryTypeBits.
alloc.memoryTypeIndex = memoryTypeIndex_;
alloc.allocationSize = reqs.size;
vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &alloc.memoryTypeIndex);
res = vkAllocateMemory(device_, &alloc, nullptr, &info.deviceMemory);
res = vkAllocateMemory(device, &alloc, nullptr, &info.deviceMemory);
if (VK_SUCCESS != res) {
_assert_msg_(G3D, false, "vkAllocateMemory failed! size=%d result=%d", (int)reqs.size, (int)res);
vkDestroyBuffer(device_, info.buffer, nullptr);
vkDestroyBuffer(device, info.buffer, nullptr);
return false;
}
res = vkBindBufferMemory(device_, info.buffer, info.deviceMemory, 0);
res = vkBindBufferMemory(device, info.buffer, info.deviceMemory, 0);
if (VK_SUCCESS != res) {
ELOG("vkBindBufferMemory failed! result=%d", (int)res);
vkFreeMemory(device_, info.deviceMemory, nullptr);
vkDestroyBuffer(device_, info.buffer, nullptr);
vkFreeMemory(device, info.deviceMemory, nullptr);
vkDestroyBuffer(device, info.buffer, nullptr);
return false;
}
@@ -137,7 +135,7 @@ size_t VulkanPushBuffer::GetTotalSize() const {
void VulkanPushBuffer::Map() {
_dbg_assert_(G3D, !writePtr_);
VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
VkResult res = vkMapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
_dbg_assert_(G3D, writePtr_);
assert(VK_SUCCESS == res);
}
@@ -152,7 +150,7 @@ void VulkanPushBuffer::Unmap() {
range.memory = buffers_[buf_].deviceMemory;
vkFlushMappedMemoryRanges(device_, 1, &range);
*/
vkUnmapMemory(device_, buffers_[buf_].deviceMemory);
vkUnmapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory);
writePtr_ = nullptr;
}
+7 -7
View File
@@ -22,7 +22,7 @@ class VulkanPushBuffer {
};
public:
VulkanPushBuffer(VulkanContext *vulkan, size_t size);
VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage);
~VulkanPushBuffer();
void Destroy(VulkanContext *vulkan);
@@ -108,13 +108,13 @@ private:
void NextBuffer(size_t minSize);
void Defragment(VulkanContext *vulkan);
VkDevice device_;
VulkanContext *vulkan_;
std::vector<BufInfo> buffers_;
size_t buf_;
size_t offset_;
size_t size_;
uint32_t memoryTypeIndex_;
uint8_t *writePtr_;
size_t buf_ = 0;
size_t offset_ = 0;
size_t size_ = 0;
uint8_t *writePtr_ = nullptr;
VkBufferUsageFlags usage_;
};
// VulkanDeviceAllocator
+1
View File
@@ -73,6 +73,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix);
CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay);
CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS);
CheckSetting(iniFile, gameID, "JitInvalidationHack", &flags_.JitInvalidationHack);
}
void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) {
+1
View File
@@ -73,6 +73,7 @@ struct CompatFlags {
bool YugiohSaveFix;
bool ForceUMDDelay;
bool ForceMax60FPS;
bool JitInvalidationHack;
};
class IniFile;
+6 -6
View File
@@ -400,7 +400,7 @@ static ConfigSetting generalSettings[] = {
ConfigSetting("SimpleFrameStats", &g_Config.bSimpleFrameStats, false),
ConfigSetting("CheckForNewVersion", &g_Config.bCheckForNewVersion, false),
ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion),
ConfigSetting("ForceLagSync", &g_Config.bForceLagSync, false, true, true),
ConfigSetting("ForceLagSync2", &g_Config.bForceLagSync, false, true, true),
ConfigSetting("DiscordPresence", &g_Config.bDiscordPresence, false, false, false), // Or maybe it makes sense to have it per-game? Race conditions abound...
ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers, true, true),
@@ -437,7 +437,7 @@ static ConfigSetting generalSettings[] = {
ConfigSetting("RemoteDebuggerOnStartup", &g_Config.bRemoteDebuggerOnStartup, false),
#ifdef __ANDROID__
ConfigSetting("ScreenRotation", &g_Config.iScreenRotation, ROTATION_LOCKED_HORIZONTAL),
ConfigSetting("ScreenRotation", &g_Config.iScreenRotation, ROTATION_AUTO_HORIZONTAL),
#endif
ConfigSetting("InternalScreenRotation", &g_Config.iInternalScreenRotation, ROTATION_LOCKED_HORIZONTAL),
@@ -1120,7 +1120,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
}
}
void Config::Save() {
void Config::Save(const char *saveReason) {
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;
@@ -1173,11 +1173,11 @@ void Config::Save() {
LogManager::GetInstance()->SaveConfig(log);
if (!iniFile.Save(iniFilename_.c_str())) {
ERROR_LOG(LOADER, "Error saving config - can't write ini '%s'", iniFilename_.c_str());
ERROR_LOG(LOADER, "Error saving config (%s)- can't write ini '%s'", saveReason, iniFilename_.c_str());
System_SendMessage("toast", "Failed to save settings!\nCheck permissions, or try to restart the device.");
return;
}
INFO_LOG(LOADER, "Config saved: '%s'", iniFilename_.c_str());
INFO_LOG(LOADER, "Config saved (%s): '%s'", saveReason, iniFilename_.c_str());
if (!bGameSpecific) //otherwise we already did this in saveGameConfig()
{
@@ -1364,7 +1364,7 @@ bool Config::hasGameConfig(const std::string &pGameId) {
}
void Config::changeGameSpecific(const std::string &pGameId) {
Save();
Save("changeGameSpecific");
gameId_ = pGameId;
bGameSpecific = !pGameId.empty();
}
+1 -1
View File
@@ -421,7 +421,7 @@ public:
std::string dismissedVersion;
void Load(const char *iniFileName = nullptr, const char *controllerIniFilename = nullptr);
void Save();
void Save(const char *saveReason);
void RestoreDefaults();
//per game config managment, should maybe be in it's own class
+1
View File
@@ -37,6 +37,7 @@ enum {
ROTATION_LOCKED_VERTICAL = 2,
ROTATION_LOCKED_HORIZONTAL180 = 3,
ROTATION_LOCKED_VERTICAL180 = 4,
ROTATION_AUTO_HORIZONTAL = 5,
};
enum BufferFilter {
+4 -4
View File
@@ -73,7 +73,7 @@
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
@@ -95,7 +95,7 @@
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@@ -121,7 +121,7 @@
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -150,7 +150,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
<OmitFramePointers>false</OmitFramePointers>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+37 -10
View File
@@ -237,6 +237,21 @@ static void __CheatStart() {
cheatsEnabled = true;
}
static int GetRefreshMs() {
int refresh = g_Config.iCwCheatRefreshRate;
if (!cheatsEnabled)
refresh = 1000;
// Horrible hack for Tony Hawk - Underground 2. See #3854. Avoids crashing somehow
// but still causes regular JIT invalidations which causes stutters.
if (PSP_CoreParameter().compat.flags().JitInvalidationHack) {
refresh = 2;
}
return refresh;
}
void __CheatInit() {
// Always register the event, want savestates to be compatible whether cheats on or off.
CheatEvent = CoreTiming::RegisterEvent("CheatEvent", &hleCheat);
@@ -245,10 +260,8 @@ void __CheatInit() {
__CheatStart();
}
int refresh = g_Config.iCwCheatRefreshRate;
// Only check once a second for cheats to be enabled.
CoreTiming::ScheduleEvent(msToCycles(cheatsEnabled ? refresh : 1000), CheatEvent, 0);
CoreTiming::ScheduleEvent(msToCycles(GetRefreshMs()), CheatEvent, 0);
}
void __CheatShutdown() {
@@ -264,13 +277,11 @@ void __CheatDoState(PointerWrap &p) {
p.Do(CheatEvent);
CoreTiming::RestoreRegisterEvent(CheatEvent, "CheatEvent", &hleCheat);
int refresh = g_Config.iCwCheatRefreshRate;
if (s < 2) {
// Before this we didn't have a checkpoint, so reset didn't work.
// Let's just force one in.
CoreTiming::RemoveEvent(CheatEvent);
CoreTiming::ScheduleEvent(msToCycles(cheatsEnabled ? refresh : 1000), CheatEvent, 0);
CoreTiming::ScheduleEvent(msToCycles(GetRefreshMs()), CheatEvent, 0);
}
}
@@ -284,14 +295,30 @@ void hleCheat(u64 userdata, int cyclesLate) {
}
}
int refresh = g_Config.iCwCheatRefreshRate;
// Check periodically for cheats.
CoreTiming::ScheduleEvent(msToCycles(GetRefreshMs()), CheatEvent, 0);
// Only check once a second for cheats to be enabled.
CoreTiming::ScheduleEvent(msToCycles(cheatsEnabled ? refresh : 1000), CheatEvent, 0);
if (PSP_CoreParameter().compat.flags().JitInvalidationHack) {
std::string gameTitle = g_paramSFO.GetValueString("DISC_ID");
// Horrible hack for Tony Hawk - Underground 2. See #3854. Avoids crashing somehow
// but still causes regular JIT invalidations which causes stutters.
if (gameTitle == "ULUS10014") {
cheatEngine->InvalidateICache(0x08865600, 72);
cheatEngine->InvalidateICache(0x08865690, 4);
} else if (gameTitle == "ULES00033" || gameTitle == "ULES00034" || gameTitle == "ULES00035") { // euro, also 34 and 35
cheatEngine->InvalidateICache(0x088655D8, 72);
cheatEngine->InvalidateICache(0x08865668, 4);
} else if (gameTitle == "ULUS10138") { // MTX MotoTrax. No hack for ULES00581 known.
cheatEngine->InvalidateICache(0x0886DCC0, 72);
cheatEngine->InvalidateICache(0x0886DC20, 4);
cheatEngine->InvalidateICache(0x0886DD40, 4);
}
}
if (!cheatEngine || !cheatsEnabled)
return;
if (g_Config.bReloadCheats) { //Checks if the "reload cheats" button has been pressed.
cheatEngine->ParseCheats();
g_Config.bReloadCheats = false;
+1 -1
View File
@@ -45,8 +45,8 @@ public:
void Run();
bool HasCheats();
private:
void InvalidateICache(u32 addr, int size);
private:
u32 GetAddress(u32 value);
CheatOperation InterpretNextOp(const CheatCode &cheat, size_t &i);
+1 -1
View File
@@ -146,7 +146,7 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK)
float WRAP_WIDTH = 300.0f;
if (UTF8StringNonASCIICount(text.c_str()) > 3)
WRAP_WIDTH = 372.0f;
float y = 140.0f;
float h, sy ,ey;
int n;
+8 -8
View File
@@ -403,7 +403,7 @@ void PSPSaveDialog::DisplaySaveDataInfo1()
char saveDetail[1024];
char am_pm[] = "AM";
char hour_time[10] ;
char hour_time[32];
int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour;
int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min;
switch (g_Config.iTimeFormat) {
@@ -412,17 +412,17 @@ void PSPSaveDialog::DisplaySaveDataInfo1()
strcpy(am_pm, "PM");
hour -= 12;
}
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm);
break;
case 2:
snprintf(hour_time,10,"%02d:%02d", hour, min);
snprintf(hour_time, sizeof(hour_time), "%02d:%02d", hour, min);
break;
default:
if (hour > 12) {
strcpy(am_pm, "PM");
hour -= 12;
}
snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm);
snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm);
}
snprintf(title, sizeof(title), "%s", param.GetFileInfo(currentSelectedSave).title);
@@ -485,7 +485,7 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) {
char date[256];
char am_pm[] = "AM";
char hour_time[10] ;
char hour_time[32];
int hour = modif_time.tm_hour;
int min = modif_time.tm_min;
switch (g_Config.iTimeFormat) {
@@ -494,17 +494,17 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) {
strcpy(am_pm, "PM");
hour -= 12;
}
snprintf(hour_time, 10, "%02d:%02d %s", hour, min, am_pm);
snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm);
break;
case 2:
snprintf(hour_time, 10, "%02d:%02d", hour, min);
snprintf(hour_time, sizeof(hour_time), "%02d:%02d", hour, min);
break;
default:
if (hour > 12) {
strcpy(am_pm, "PM");
hour -= 12;
}
snprintf(hour_time, 10, "%02d:%02d %s", hour, min, am_pm);
snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm);
}
int day = modif_time.tm_mday;
+11 -6
View File
@@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <cstdio>
#include "ppsspp_config.h"
#include "util/text/utf8.h"
#include "file/file_util.h"
@@ -30,7 +31,10 @@
LocalFileLoader::LocalFileLoader(const std::string &filename)
: filesize_(0), filename_(filename) {
if (filename.empty()) {
ERROR_LOG(FILESYS, "LocalFileLoader can't load empty filenames");
return;
}
#ifndef _WIN32
fd_ = open(filename.c_str(), O_RDONLY | O_CLOEXEC);
@@ -47,7 +51,7 @@ LocalFileLoader::LocalFileLoader(const std::string &filename)
lseek(fd_, 0, SEEK_SET);
#endif
#else // !_WIN32
#else // _WIN32
const DWORD access = GENERIC_READ, share = FILE_SHARE_READ, mode = OPEN_EXISTING, flags = FILE_ATTRIBUTE_NORMAL;
#if PPSSPP_PLATFORM(UWP)
@@ -60,14 +64,15 @@ LocalFileLoader::LocalFileLoader(const std::string &filename)
}
LARGE_INTEGER end_offset;
const LARGE_INTEGER zero = { 0 };
if(SetFilePointerEx(handle_, zero, &end_offset, FILE_END) == 0) {
if (SetFilePointerEx(handle_, zero, &end_offset, FILE_END) == 0) {
// Couldn't seek in the file. Close it and give up? This should never happen.
CloseHandle(handle_);
handle_ = INVALID_HANDLE_VALUE;
return;
}
filesize_ = end_offset.QuadPart;
SetFilePointerEx(handle_, zero, nullptr, FILE_BEGIN);
#endif // !_WIN32
#endif // _WIN32
}
LocalFileLoader::~LocalFileLoader() {
+5 -5
View File
@@ -154,6 +154,10 @@ DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string
hAlloc = _hAlloc;
}
DirectoryFileSystem::~DirectoryFileSystem() {
CloseAll();
}
std::string DirectoryFileHandle::GetLocalPath(std::string& basePath, std::string localpath)
{
if (localpath.empty())
@@ -445,16 +449,12 @@ void DirectoryFileHandle::Close()
void DirectoryFileSystem::CloseAll() {
for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
INFO_LOG(FILESYS, "DirectoryFileSystem::CloseAll(): Force closing %d (%s)", (int)iter->first, iter->second.guestFilename.c_str());
iter->second.hFile.Close();
}
entries.clear();
}
DirectoryFileSystem::~DirectoryFileSystem() {
CloseAll();
}
std::string DirectoryFileSystem::GetLocalPath(std::string localpath) {
if (localpath.empty())
return basePath;
+1 -1
View File
@@ -38,7 +38,7 @@ static int kuKernelGetModel() {
const HLEFunction KUBridge[] =
{
{ 0x4C25EA72, &WrapI_CUU<kuKernelLoadModule>, "kuKernelLoadModule", 'i', "cuu" },
{ 0x4C25EA72, &WrapI_CUU<kuKernelLoadModule>, "kuKernelLoadModule", 'i', "sxx" },
{ 0x24331850, &WrapI_V<kuKernelGetModel>, "kuKernelGetModel", 'i', "" },
};
+1 -2
View File
@@ -1,4 +1,3 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
@@ -509,7 +508,7 @@ static void __CtrlWriteUserLatch(CtrlLatch *userLatch, int bufs) {
userLatch->btnMake &= CTRL_MASK_USER;
userLatch->btnPress &= CTRL_MASK_USER;
if (bufs > 0) {
userLatch->btnRelease |= CTRL_MASK_USER;
userLatch->btnRelease |= ~CTRL_MASK_USER;
}
}
+3 -1
View File
@@ -436,7 +436,9 @@ public:
}
u32 args[2] = { params_.userDataAddr, (u32)handle_ };
// TODO: The return value of this is leaking.
__KernelDirectMipsCall(params_.freeFuncAddr, 0, args, 2, false);
if (handle_) { // Avoid calling free-callback on double-free
__KernelDirectMipsCall(params_.freeFuncAddr, 0, args, 2, false);
}
handle_ = 0;
fonts_.clear();
isfontopen_.clear();
+5 -4
View File
@@ -1934,7 +1934,8 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret
if (module->nm.module_start_func != 0 && module->nm.module_start_func != (u32)-1)
{
entryAddr = module->nm.module_start_func;
attribute = module->nm.module_start_thread_attr;
if (module->nm.module_start_thread_attr != 0)
attribute = module->nm.module_start_thread_attr;
}
else if ((entryAddr == (u32)-1) || entryAddr == module->memoryBlockAddr - 1)
{
@@ -1967,7 +1968,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret
stacksize = module->nm.module_start_thread_stacksize;
}
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attribute, 0);
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attribute, 0, (module->nm.attribute & 0x1000) != 0);
__KernelStartThreadValidate(threadID, argsize, argAddr);
__KernelSetThreadRA(threadID, NID_MODULERETURN);
__KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module");
@@ -2049,7 +2050,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
if (Memory::IsValidAddress(stopFunc))
{
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0);
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0);
__KernelStartThreadValidate(threadID, argSize, argAddr);
__KernelSetThreadRA(threadID, NID_MODULERETURN);
__KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "stopped module");
@@ -2132,7 +2133,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize,
}
if (Memory::IsValidAddress(stopFunc)) {
SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0);
SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0);
__KernelStartThreadValidate(threadID, argSize, argp);
__KernelSetThreadRA(threadID, NID_MODULERETURN);
__KernelWaitCurThread(WAITTYPE_MODULE, moduleID, 1, 0, false, "unloadstopped module");
+5 -3
View File
@@ -1944,7 +1944,7 @@ SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32
return id;
}
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) {
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr, bool allowKernel) {
if (threadName == nullptr)
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "NULL thread name");
@@ -1961,7 +1961,7 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32
if (entry != 0)
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid thread entry %08x", entry);
}
if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0)
if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0 && !allowKernel)
return hleReportWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "illegal thread attributes %08x", attr);
if ((attr & ~PSP_THREAD_ATTR_SUPPORTED) != 0)
@@ -1997,7 +1997,9 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32
}
int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) {
return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr);
Thread *cur = __GetCurrentThread();
bool allowKernel = cur ? (cur->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0 : false;
return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr, allowKernel);
}
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs) {
+1 -1
View File
@@ -31,7 +31,7 @@ class DebugInterface;
int sceKernelChangeThreadPriority(SceUID threadID, int priority);
SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr);
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr);
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr, bool allowKernel);
int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr);
int sceKernelDelayThread(u32 usec);
int sceKernelDelayThreadCB(u32 usec);
+5 -3
View File
@@ -318,12 +318,12 @@ static void AnalyzeMpeg(u8 *buffer, u32 validSize, MpegContext *ctx) {
ctx->audioFrameCount = 0;
ctx->endOfAudioReached = false;
ctx->endOfVideoReached = false;
// Sanity Check ctx->mpegFirstTimestamp
if (ctx->mpegFirstTimestamp != 90000) {
WARN_LOG_REPORT(ME, "Unexpected mpeg first timestamp: %llx / %lld", ctx->mpegFirstTimestamp, ctx->mpegFirstTimestamp);
}
if (ctx->mpegMagic != PSMF_MAGIC || ctx->mpegVersion < 0 ||
(ctx->mpegOffset & 2047) != 0 || ctx->mpegOffset == 0) {
// mpeg header is invalid!
@@ -511,7 +511,7 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr
Memory::Write_U32(ringbufferAddr, mpegHandle + 16);
Memory::Write_U32(ringbuffer->dataUpperBound, mpegHandle + 20);
}
MpegContext *ctx = new MpegContext;
MpegContext *ctx = new MpegContext();
if (mpegMap.find(mpegHandle) != mpegMap.end()) {
WARN_LOG_REPORT(HLE, "Replacing existing mpeg context at %08x", mpegAddr);
// Otherwise, it would leak.
@@ -532,6 +532,8 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr
ctx->ignorePcm = false;
ctx->ignoreAvc = false;
ctx->defaultFrameWidth = frameWidth;
ctx->mpegStreamSize = 0;
ctx->mpegOffset = 0;
for (int i = 0; i < MPEG_DATA_ES_BUFFERS; i++) {
ctx->esBuffers[i] = false;
}
+1 -1
View File
@@ -174,7 +174,7 @@ u32 sceNetAdhocInit() {
// TODO: Should use a separated threads for friendFinder, matchingEvent, and matchingInput and created on AdhocctlInit & AdhocMatchingStart instead of here
#define PSP_THREAD_ATTR_KERNEL 0x00001000 // PSP_THREAD_ATTR_KERNEL is located in sceKernelThread.cpp instead of sceKernelThread.h :(
//threadAdhocID = __KernelCreateThreadInternal("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x30, 4096, PSP_THREAD_ATTR_KERNEL);
threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x10, 0x1000, 0, 0);
threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x10, 0x1000, 0, 0, false);
if (threadAdhocID > 0) {
__KernelStartThread(threadAdhocID, 0, 0);
}
+11 -2
View File
@@ -179,8 +179,17 @@ namespace MIPSComp
return;
}
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?");
load ? gpr.MapDirtyIn(rt, rs, false) : gpr.MapInIn(rt, rs);
// This gets hit in a few games, as a result of never-taken delay slots (some branch types
// conditionally execute the delay slot instructions). Ignore in those cases.
if (!js.inDelaySlot) {
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr);
}
if (load) {
gpr.MapDirtyIn(rt, rs, false);
} else {
gpr.MapInIn(rt, rs);
}
if (!g_Config.bFastMemory && rs != MIPS_REG_SP) {
SetCCAndR0ForSafeAddress(rs, offset, SCRATCHREG2, true);
+11 -6
View File
@@ -2301,10 +2301,16 @@ namespace MIPSComp
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
u8 sregs[4], dregs[4];
// Actually, not sure that this instruction accepts an S prefix. We don't apply it in the
// interpreter. But whatever.
// This is a hack that modifies prefixes. We eat them later, so just overwrite.
// S prefix forces the negate flags.
js.prefixS |= 0x000F0000;
// T prefix forces constants on and regnum to 1.
// That means negate still works, and abs activates a different constant.
js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000;
u8 sregs[4], tregs[4], dregs[4];
GetVectorRegsPrefixS(sregs, sz, _VS);
GetVectorRegsPrefixT(tregs, sz, _VS);
GetVectorRegsPrefixD(dregs, sz, _VD);
MIPSReg tempregs[4];
@@ -2316,10 +2322,9 @@ namespace MIPSComp
}
}
MOVI2F(S0, 1.0f, SCRATCHREG1);
for (int i = 0; i < n; ++i) {
fpr.MapDirtyInV(tempregs[i], sregs[i]);
VSUB(fpr.V(tempregs[i]), S0, fpr.V(sregs[i]));
fpr.MapDirtyInInV(tempregs[i], sregs[i], tregs[i]);
VADD(fpr.V(tempregs[i]), fpr.V(tregs[i]), fpr.V(sregs[i]));
}
for (int i = 0; i < n; ++i) {
+10 -1
View File
@@ -1433,12 +1433,21 @@ void ArmJit::CompNEON_Vocp(MIPSOpcode op) {
DISABLE;
}
// TODO: Handle T prefix. Right now it uses 1.0f always.
// This is a hack that modifies prefixes. We eat them later, so just overwrite.
// S prefix forces the negate flags.
js.prefixS |= 0x000F0000;
// T prefix forces constants on and regnum to 1.
// That means negate still works, and abs activates a different constant.
js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000;
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
MappedRegs regs = NEONMapDirtyIn(op, sz, sz);
MOVI2F_neon(Q0, 1.0f, R0);
VSUB(F_32, regs.vd, Q0, regs.vs);
VADD(F_32, regs.vd, Q0, regs.vs);
NEONApplyPrefixD(regs.vd);
fpr.ReleaseSpillLocksAndDiscardTemps();
+14 -8
View File
@@ -172,7 +172,7 @@ namespace MIPSComp {
return;
}
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?");
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr);
if (load) {
gpr.MapDirtyIn(rt, rs, false);
} else {
@@ -364,13 +364,19 @@ namespace MIPSComp {
addrReg = SCRATCH1;
}
} else {
// This actually gets hit in micro machines! rs = ZR rt = ZR. Probably a bug.
// Leaving this a debug assert for future investigation.
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?");
// This gets hit in a few games, as a result of never-taken delay slots (some branch types
// conditionally execute the delay slot instructions). Ignore in those cases.
if (!js.inDelaySlot) {
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr);
}
// If we already have a targetReg, we optimized an imm, and rs is already mapped.
if (targetReg == INVALID_REG) {
load ? gpr.MapDirtyIn(rt, rs) : gpr.MapInIn(rt, rs);
if (load) {
gpr.MapDirtyIn(rt, rs);
} else {
gpr.MapInIn(rt, rs);
}
targetReg = gpr.R(rt);
}
@@ -413,9 +419,9 @@ namespace MIPSComp {
}
void Arm64Jit::Comp_Cache(MIPSOpcode op) {
// int imm = (s16)(op & 0xFFFF);
// int rs = _RS;
// int addr = R(rs) + imm;
// int imm = (s16)(op & 0xFFFF);
// int rs = _RS;
// int addr = R(rs) + imm;
int func = (op >> 16) & 0x1F;
// It appears that a cache line is 0x40 (64) bytes, loops in games
+11 -5
View File
@@ -1952,10 +1952,16 @@ namespace MIPSComp {
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
u8 sregs[4], dregs[4];
// Actually, not sure that this instruction accepts an S prefix. We don't apply it in the
// interpreter. But whatever.
// This is a hack that modifies prefixes. We eat them later, so just overwrite.
// S prefix forces the negate flags.
js.prefixS |= 0x000F0000;
// T prefix forces constants on and regnum to 1.
// That means negate still works, and abs activates a different constant.
js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000;
u8 sregs[4], tregs[4], dregs[4];
GetVectorRegsPrefixS(sregs, sz, _VS);
GetVectorRegsPrefixT(tregs, sz, _VS);
GetVectorRegsPrefixD(dregs, sz, _VD);
MIPSReg tempregs[4];
@@ -1969,8 +1975,8 @@ namespace MIPSComp {
fp.MOVI2F(S0, 1.0f, SCRATCH1);
for (int i = 0; i < n; ++i) {
fpr.MapDirtyInV(tempregs[i], sregs[i]);
fp.FSUB(fpr.V(tempregs[i]), S0, fpr.V(sregs[i]));
fpr.MapDirtyInInV(tempregs[i], sregs[i], tregs[i]);
fp.FADD(fpr.V(tempregs[i]), fpr.V(tregs[i]), fpr.V(sregs[i]));
}
for (int i = 0; i < n; ++i) {
+23 -9
View File
@@ -1174,9 +1174,14 @@ namespace MIPSComp {
// Many more instructions to interpret.
void IRFrontend::Comp_Vmmul(MIPSOpcode op) {
CONDITIONAL_DISABLE(VFPU_MTX);
if (!js.HasNoPrefix()) {
DISABLE;
}
// Matrix multiply (no prefixes)
// D[0 .. N,0 .. M] = S[0 .. N, 0 .. M] * T[0 .. N,0 .. M]
// Matrix multiply (wierd prefixes)
// D[0 .. N, 0 .. M] = S[0 .. N, 0 .. M]' * T[0 .. N, 0 .. M]
// Note: Behaves as if it's implemented through a series of vdots.
// Important: this is a matrix multiply with a pre-transposed S.
MatrixSize sz = GetMtxSize(op);
int n = GetMatrixSide(sz);
@@ -1229,7 +1234,7 @@ namespace MIPSComp {
// TODO: Skip this and resort to method one and transpose the output?
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
ir.Write(IROp::Vec4Dot, s0 + i, sregs[i], tregs[j * 4]);
ir.Write(IROp::Vec4Dot, s0 + i, sregs[i * 4], tregs[j * 4]);
}
ir.Write(IROp::Vec4Mov, dregs[j * 4], s0);
}
@@ -1840,27 +1845,36 @@ namespace MIPSComp {
DISABLE;
}
// Vector one's complement
// d[N] = 1.0 - s[N]
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
u8 sregs[4], dregs[4];
// Actually, not sure that this instruction accepts an S prefix. We don't apply it in the
// interpreter. But whatever.
// This is a hack that modifies prefixes. We eat them later, so just overwrite.
// S prefix forces the negate flags.
js.prefixS |= 0x000F0000;
// T prefix forces constants on and regnum to 1.
// That means negate still works, and abs activates a different constant.
js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000;
u8 sregs[4], tregs[4], dregs[4];
GetVectorRegsPrefixS(sregs, sz, _VS);
// There's no bits for t, so just reuse s. It'll be constants only.
GetVectorRegsPrefixT(tregs, sz, _VS);
GetVectorRegsPrefixD(dregs, sz, _VD);
u8 tempregs[4];
for (int i = 0; i < n; ++i) {
if (!IsOverlapSafe(dregs[i], n, sregs)) {
tempregs[i] = IRVTEMP_PFX_T + i; // using IRTEMP0 for other things
tempregs[i] = IRVTEMP_0 + i;
} else {
tempregs[i] = dregs[i];
}
}
ir.Write(IROp::SetConstF, IRVTEMP_0, ir.AddConstantFloat(1.0f));
for (int i = 0; i < n; ++i) {
ir.Write(IROp::FSub, tempregs[i], IRVTEMP_0, sregs[i]);
ir.Write(IROp::FAdd, tempregs[i], tregs[i], sregs[i]);
}
for (int i = 0; i < n; ++i) {
if (dregs[i] != tempregs[i]) {
+85 -23
View File
@@ -544,15 +544,24 @@ namespace MIPSInt
void Int_Vocp(MIPSOpcode op)
{
float s[4], d[4];
float s[4], t[4], d[4];
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
ReadVector(s, sz, vs);
for (int i = 0; i < GetNumVectorElements(sz); i++)
{
// Always positive NaN.
d[i] = my_isnan(s[i]) ? fabsf(s[i]) : 1.0f - s[i];
// S prefix forces the negate flags.
u32 sprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_SPREFIX];
ApplyPrefixST(s, sprefix | 0x000F0000, sz);
// T prefix forces constants on and regnum to 1.
// That means negate still works, and abs activates a different constant.
u32 tprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_TPREFIX];
ApplyPrefixST(t, (tprefix & ~0x000000FF) | 0x00000055 | 0x0000F000, sz);
for (int i = 0; i < GetNumVectorElements(sz); i++) {
// Always positive NaN. Note that s is always negated from the registers.
d[i] = my_isnan(s[i]) ? fabsf(s[i]) : t[i] + s[i];
}
ApplyPrefixD(d, sz);
WriteVector(d, sz, vd);
@@ -562,22 +571,32 @@ namespace MIPSInt
void Int_Vsocp(MIPSOpcode op)
{
float s[4], d[4];
float s[4], t[4], d[4];
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
VectorSize outSize = GetDoubleVectorSize(sz);
ReadVector(s, sz, vs);
// S prefix forces negate in even/odd and xxyy swizzle.
// abs works, and applies to final position (not source.)
u32 sprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_SPREFIX];
ApplyPrefixST(s, (sprefix & ~0x000F00FF) | 0x00000050 | 0x00050000, outSize);
// T prefix forces constants on and regnum to 0, 1, 0, 1.
// That means negate still works, and abs activates a different constant.
u32 tprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_TPREFIX];
ApplyPrefixST(t, (tprefix & ~0x000000FF) | 0x00000011 | 0x0000F000, outSize);
int n = GetNumVectorElements(sz);
float x = s[0];
d[0] = nanclamp(1.0f - x, 0.0f, 1.0f);
d[1] = nanclamp(x, 0.0f, 1.0f);
VectorSize outSize = V_Pair;
if (n > 1) {
float y = s[1];
d[2] = nanclamp(1.0f - y, 0.0f, 1.0f);
d[3] = nanclamp(y, 0.0f, 1.0f);
outSize = V_Quad;
}
// Essentially D prefix saturation is forced.
d[0] = nanclamp(t[0] + s[0], 0.0f, 1.0f);
d[1] = nanclamp(t[1] + s[1], 0.0f, 1.0f);
if (outSize == V_Quad) {
d[2] = nanclamp(t[2] + s[2], 0.0f, 1.0f);
d[3] = nanclamp(t[3] + s[3], 0.0f, 1.0f);
}
ApplyPrefixD(d, sz);
WriteVector(d, outSize, vd);
PC += 4;
EatPrefixes();
@@ -1801,11 +1820,33 @@ bad:
void Int_Vlgb(MIPSOpcode op)
{
// S & D valid
Reporting::ReportMessage("vlgb not implemented");
if (!PSP_CoreParameter().headLess) {
_dbg_assert_msg_(CPU,0,"vlgb not implemented");
// Vector log binary (extract exponent)
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
FloatBits d;
FloatBits s;
ReadVector(s.f, sz, vs);
// TODO: Test swizzle, t?
ApplySwizzleS(s.f, sz);
if (sz != V_Single) {
ERROR_LOG_REPORT(CPU, "vlgb not implemented for size %d", GetNumVectorElements(sz));
}
for (int i = 0; i < GetNumVectorElements(sz); ++i) {
int exp = (s.u[i] & 0x7F800000) >> 23;
if (exp == 0xFF) {
d.f[i] = s.f[i];
} else if (exp == 0) {
d.f[i] = -INFINITY;
} else {
d.f[i] = (float)(exp - 127);
}
}
ApplyPrefixD(d.f, sz);
WriteVector(d.f, sz, vd);
PC += 4;
EatPrefixes();
}
@@ -1886,10 +1927,31 @@ bad:
void Int_Vsbz(MIPSOpcode op)
{
Reporting::ReportMessage("vsbz not implemented");
if (!PSP_CoreParameter().headLess) {
_dbg_assert_msg_(CPU,0,"vsbz not implemented");
// Vector scale by zero (set exp to 0 to extract mantissa)
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
FloatBits d;
FloatBits s;
ReadVector(s.f, sz, vs);
// TODO: Test swizzle, t?
ApplySwizzleS(s.f, sz);
if (sz != V_Single) {
ERROR_LOG_REPORT(CPU, "vsbz not implemented for size %d", GetNumVectorElements(sz));
}
for (int i = 0; i < GetNumVectorElements(sz); ++i) {
// NAN and denormals pass through.
if (my_isnan(s.f[i]) || (s.u[i] & 0x7F800000) == 0) {
d.u[i] = s.u[i];
} else {
d.u[i] = (127 << 23) | (s.u[i] & 0x007FFFFF);
}
}
ApplyPrefixD(d.f, sz);
WriteVector(d.f, sz, vd);
PC += 4;
EatPrefixes();
}
+18 -30
View File
@@ -524,8 +524,8 @@ const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . .......
{
INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU),
// TODO: Disasm is wrong.
INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INVALID, INVALID, INVALID, INVALID,
INSTR("vdiv", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
@@ -577,20 +577,18 @@ const MIPSInstruction tableVFPU4Jump[32] = // 110100 xxxxx ..... . ....... . ...
INVALID,
INVALID,
//24 - 110100 11 ........ . ....... . .......
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
};
const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . .......
{
// TODO disasm
INSTR("vrnds", JITFUNC(Comp_Generic), Dis_Vrnds, Int_Vrnds, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vrndi", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vrndf1", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
@@ -599,9 +597,7 @@ const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . .......
INVALID, INVALID, INVALID, INVALID,
//8
INVALID, INVALID, INVALID, INVALID,
// TODO: Flags may not be correct (prefixes, etc.) Is this the correct encoding? Others say 10110.
INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU),
INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
//16
INVALID,
INVALID,
@@ -610,9 +606,8 @@ const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . .......
INVALID,
INVALID,
INVALID,
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
//24
INSTR("vuc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000
INSTR("vc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
@@ -731,23 +726,18 @@ const MIPSInstruction tableVFPUMatrixSet1[16] = // 111100 11100 .xxxx . .......
const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . .......
{
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU),
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vbfy1", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vbfy2", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
//4
INSTR("vocp", JITFUNC(Comp_Vocp), Dis_Vbfy, Int_Vocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // one's complement
INSTR("vsocp", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vfad", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vfad, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
//8
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU),
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU),
INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vsgn", JITFUNC(Comp_Vsgn), Dis_Vbfy, Int_Vsgn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INVALID,
//12
@@ -757,9 +747,7 @@ const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . .......
INVALID,
//16
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vmfvc", JITFUNC(Comp_Vmfvc), Dis_Vmftvc, Int_Vmfvc, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU),
// TODO: Flags may not be correct (prefixes, etc.)
INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmftvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU),
INVALID,
INVALID,
+23 -5
View File
@@ -2026,12 +2026,24 @@ void Jit::Comp_Vocp(MIPSOpcode op) {
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
u8 sregs[4], dregs[4];
// This is a hack that modifies prefixes. We eat them later, so just overwrite.
// S prefix forces the negate flags.
js.prefixS |= 0x000F0000;
// T prefix forces constants on and regnum to 1.
// That means negate still works, and abs activates a different constant.
js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000;
u8 sregs[4], tregs[4], dregs[4];
// Actually uses the T prefixes (despite being VS.)
GetVectorRegsPrefixS(sregs, sz, _VS);
if (js.prefixT != 0x0000F055)
GetVectorRegsPrefixT(tregs, sz, _VS);
GetVectorRegsPrefixD(dregs, sz, _VD);
// Flush SIMD.
fpr.SimpleRegsV(sregs, sz, 0);
if (js.prefixT != 0x0000F055)
fpr.SimpleRegsV(tregs, sz, 0);
fpr.SimpleRegsV(dregs, sz, MAP_NOINIT | MAP_DIRTY);
X64Reg tempxregs[4];
@@ -2048,11 +2060,17 @@ void Jit::Comp_Vocp(MIPSOpcode op) {
}
}
MOV(PTRBITS, R(TEMPREG), ImmPtr(&one));
MOVSS(XMM1, MatR(TEMPREG));
if (js.prefixT == 0x0000F055) {
MOV(PTRBITS, R(TEMPREG), ImmPtr(&one));
MOVSS(XMM1, MatR(TEMPREG));
}
for (int i = 0; i < n; ++i) {
MOVSS(XMM0, R(XMM1));
SUBSS(XMM0, fpr.V(sregs[i]));
if (js.prefixT == 0x0000F055) {
MOVSS(XMM0, R(XMM1));
} else {
MOVSS(XMM0, fpr.V(tregs[i]));
}
ADDSS(XMM0, fpr.V(sregs[i]));
MOVSS(tempxregs[i], R(XMM0));
}
+2 -2
View File
@@ -477,7 +477,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont,
utfWord = utfPrev;
finished = true;
break;
}
}
}
}
++numChars;
@@ -549,7 +549,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont,
}
lineWidth += nextWidth;
u32 cval = utf.next();
u32 cval = utf.end() ? 0 : utf.next();
if (spaceWidth > 0)
{
if (!dryRun)
+2 -1
View File
@@ -1865,7 +1865,8 @@ Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u
}
textureCache_->ForgetLastTexture();
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, depth });
bool z_stencil = reason == TempFBO::STENCIL;
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth });
if (!fbo)
return fbo;
+2
View File
@@ -162,6 +162,8 @@ enum class TempFBO {
BLIT,
// For copies of framebuffers (e.g. shader blending.)
COPY,
// Used to copy stencil data, means we need a stencil backing.
STENCIL,
};
inline Draw::DataFormat GEFormatToThin3D(int geFormat) {
+1 -1
View File
@@ -1344,7 +1344,7 @@ void ConvertStencilFuncState(GenericStencilFuncState &state) {
return;
// The PSP's mask is reversed (bits not to write.)
state.writeMask = (~gstate.pmska) & 0xFF;
state.writeMask = (~gstate.getStencilWriteMask()) & 0xFF;
state.sFail = gstate.getStencilOpSFail();
state.zFail = gstate.getStencilOpZFail();
+3
View File
@@ -324,6 +324,9 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
// Set some options.
spirv_cross::CompilerGLSL::Options options;
options.version = gl_extensions.GLSLVersion();
// macOS OpenGL 4.1 implementation does not support GL_ARB_shading_language_420pack.
// Prevent explicit binding location emission enabled in SPIRV-Cross by default.
options.enable_420pack_extension = gl_extensions.ARB_shading_language_420pack;
glsl.set_common_options(options);
// Compile to GLSL, ready to give to GL driver.
*dest = glsl.compile();
+4 -2
View File
@@ -30,16 +30,18 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo
// Account for the projection viewport adjustment when viewport is too large.
auto reverseViewportX = [](float x) {
float pspViewport = (x - gstate.getViewportXCenter()) * (1.0f / gstate.getViewportXScale());
return (pspViewport - gstate_c.vpXOffset) * gstate_c.vpWidthScale;
return (pspViewport * gstate_c.vpWidthScale) - gstate_c.vpXOffset;
};
auto reverseViewportY = [flipViewport](float y) {
float heightScale = gstate_c.vpHeightScale;
float yOffset = gstate_c.vpYOffset;
if (flipViewport) {
// For D3D11 and GLES non-buffered.
heightScale = -heightScale;
yOffset = -yOffset;
}
float pspViewport = (y - gstate.getViewportYCenter()) * (1.0f / gstate.getViewportYScale());
return (pspViewport - gstate_c.vpYOffset) * heightScale;
return (pspViewport * heightScale) - yOffset;
};
auto reverseViewportZ = [hasNegZ](float z) {
float vpZScale = gstate.getViewportZScale();
+3 -1
View File
@@ -457,7 +457,9 @@ void SoftwareTransform(
// If alpha is not allowed to be separate, it must match for both depth/stencil and color. Vulkan requires this.
bool alphaMatchesColor = gstate.isClearModeColorMask() == gstate.isClearModeAlphaMask();
bool depthMatchesStencil = gstate.isClearModeAlphaMask() == gstate.isClearModeDepthMask();
if (params->allowSeparateAlphaClear || (alphaMatchesColor && depthMatchesStencil)) {
bool matchingComponents = params->allowSeparateAlphaClear || (alphaMatchesColor && depthMatchesStencil);
bool stencilNotMasked = !gstate.isClearModeAlphaMask() || gstate.getStencilWriteMask() == 0x00;
if (matchingComponents && stencilNotMasked) {
result->color = transformed[1].color0_32;
// Need to rescale from a [0, 1] float. This is the final transformed value.
result->depth = ToScaledDepthFromIntegerScale((int)(transformed[1].z * 65535.0f));
+1 -1
View File
@@ -89,7 +89,7 @@ static const u32 textureAlignMask16[16] = {
u32 GetTextureBufw(int level, u32 texaddr, GETextureFormat format) {
// This is a hack to allow for us to draw the huge PPGe texture, which is always in kernel ram.
if (texaddr < PSP_GetKernelMemoryEnd())
if (texaddr >= PSP_GetKernelMemoryBase() && texaddr < PSP_GetKernelMemoryEnd())
return gstate.texbufwidth[level] & 0x1FFF;
u32 bufw = gstate.texbufwidth[level] & textureAlignMask16[format];
+3 -1
View File
@@ -127,7 +127,9 @@ GPU_D3D11::~GPU_D3D11() {
void GPU_D3D11::CheckGPUFeatures() {
u32 features = 0;
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
if (!PSP_CoreParameter().compat.flags().DepthRangeHack) {
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
}
features |= GPU_SUPPORTS_BLEND_MINMAX;
features |= GPU_PREFER_CPU_DOWNLOAD;
+2 -1
View File
@@ -330,7 +330,8 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
// A normal clear will be 2 points, the second point has the color.
// We override this value in the pipeline from software transform for clear rectangles.
dynState_.stencilRef = 0xFF;
keys_.depthStencil.stencilWriteMask = 0xFF;
// But we still apply the stencil write mask.
keys_.depthStencil.stencilWriteMask = (~gstate.getStencilWriteMask()) & 0xFF;
} else {
keys_.depthStencil.stencilTestEnable = false;
dynState_.useStencil = false;
+15 -13
View File
@@ -176,21 +176,23 @@ void GPU_DX9::CheckGPUFeatures() {
features |= GPU_SUPPORTS_ACCURATE_DEPTH;
}
// VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel.
// Also causes problems on old NVIDIA.
switch (vendor) {
case Draw::GPUVendor::VENDOR_INTEL:
break;
case Draw::GPUVendor::VENDOR_NVIDIA:
// Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders.
// No idea if KEPLER is the right cutoff, but let's go with it.
if (NVIDIAGetDeviceGeneration(draw_->GetDeviceCaps().deviceID) >= NV_KEPLER) {
if (!PSP_CoreParameter().compat.flags().DepthRangeHack) {
// VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel.
// Also causes problems on old NVIDIA.
switch (vendor) {
case Draw::GPUVendor::VENDOR_INTEL:
break;
case Draw::GPUVendor::VENDOR_NVIDIA:
// Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders.
// No idea if KEPLER is the right cutoff, but let's go with it.
if (NVIDIAGetDeviceGeneration(draw_->GetDeviceCaps().deviceID) >= NV_KEPLER) {
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
}
break;
default:
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
break;
}
break;
default:
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
break;
}
D3DCAPS9 caps;
+1 -1
View File
@@ -233,7 +233,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
dxstate.stencilTest.enable();
dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE);
dxstate.stencilFunc.set(D3DCMP_ALWAYS, 255, 0xFF);
dxstate.stencilMask.set(0xFF);
dxstate.stencilMask.set((~gstate.getStencilWriteMask()) & 0xFF);
} else {
dxstate.stencilTest.disable();
}
+8 -2
View File
@@ -312,8 +312,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
// TODO: Not sure the right way to do this for projection.
// This path destroys resolution on older PowerVR no matter what I do if projection is needed,
// so we disable it on SGX 540 and lesser, and live with the consequences.
bool badPrecision = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_TERRIBLE) != 0;
if (needShaderTexClamp && !(doTextureProjection && badPrecision)) {
bool terriblePrecision = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_TERRIBLE) != 0;
bool clampDisabled = doTextureProjection && terriblePrecision;
// Also with terrible precision we can't do wrapping without destroying the image. See #9189
if (terriblePrecision && (!id.Bit(FS_BIT_CLAMP_S) || !id.Bit(FS_BIT_CLAMP_T))) {
clampDisabled = true;
}
if (needShaderTexClamp && !clampDisabled) {
// We may be clamping inside a larger surface (tex = 64x64, buffer=480x272).
// We may also be wrapping in such a surface, or either one in a too-small surface.
// Obviously, clamping to a smaller surface won't work. But better to clamp to something.
@@ -356,6 +361,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
} else {
if (doTextureProjection) {
// We don't use textureProj because we need better control and it's probably not much of a savings anyway.
// However it is good for precision on older hardware like PowerVR.
WRITE(p, " vec2 uv = %s.xy/%s.z;\n vec2 uv_round;\n", texcoord, texcoord);
} else {
WRITE(p, " vec2 uv = %s.xy;\n vec2 uv_round;\n", texcoord);
+3 -1
View File
@@ -149,7 +149,9 @@ void GPU_GLES::CheckGPUFeatures() {
features |= GPU_SUPPORTS_16BIT_FORMATS;
if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) {
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
if (!PSP_CoreParameter().compat.flags().DepthRangeHack) {
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
}
}
if (gl_extensions.ARB_blend_func_extended || gl_extensions.EXT_blend_func_extended) {
+1 -1
View File
@@ -828,7 +828,7 @@ std::string ShaderManagerGLES::DebugGetShaderString(std::string id, DebugShaderT
// as sometimes these features might have an effect on the ID bits.
#define CACHE_HEADER_MAGIC 0x83277592
#define CACHE_VERSION 13
#define CACHE_VERSION 14
struct CacheHeader {
uint32_t magic;
uint32_t version;
+1 -1
View File
@@ -277,7 +277,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
framebufferManager_->SetDepthUpdated();
}
renderManager->SetStencilFunc(gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF);
renderManager->SetStencilOp(0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE);
renderManager->SetStencilOp((~gstate.getStencilWriteMask()) & 0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE);
renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS);
} else {
// Depth Test
+1 -1
View File
@@ -168,7 +168,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
Draw::Framebuffer *blitFBO = nullptr;
if (useBlit) {
blitFBO = GetTempFBO(TempFBO::COPY, w, h, Draw::FBO_8888);
blitFBO = GetTempFBO(TempFBO::STENCIL, w, h, Draw::FBO_8888);
draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
} else if (dstBuffer->fbo) {
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE });
+5 -5
View File
@@ -88,7 +88,7 @@
<AdditionalIncludeDirectories>..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
@@ -109,7 +109,7 @@
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@@ -136,7 +136,7 @@
<AdditionalIncludeDirectories>..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@@ -162,7 +162,7 @@
<AdditionalIncludeDirectories>..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@@ -390,4 +390,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+2 -1
View File
@@ -562,7 +562,8 @@ static inline Vec4<int> GetTextureFunctionOutput(const Vec4<int>& prim_color, co
const __m128 b = _mm_mul_ps(p, t);
if (gstate.isColorDoublingEnabled()) {
// We double right here, only for modulate. Other tex funcs do not color double.
out_rgb.ivec = _mm_cvtps_epi32(_mm_mul_ps(b, _mm_set_ps1(2.0f / 255.0f)));
const __m128 doubleColor = _mm_setr_ps(2.0f / 255.0f, 2.0f / 255.0f, 2.0f / 255.0f, 1.0f / 255.0f);
out_rgb.ivec = _mm_cvtps_epi32(_mm_mul_ps(b, doubleColor));
} else {
out_rgb.ivec = _mm_cvtps_epi32(_mm_mul_ps(b, _mm_set_ps1(1.0f / 255.0f)));
}
+9 -7
View File
@@ -129,16 +129,18 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat
VkFormat destFormat = GetClutDestFormat(clutFormat, &componentMapping);
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
VulkanTexture *vktex = new VulkanTexture(vulkan_);
vktex->SetTag("DepalClut");
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
if (!vktex->CreateDirect(cmd, alloc_, texturePixels, 1, 1, destFormat,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, &componentMapping)) {
ERROR_LOG(G3D, "Failed to create texture for CLUT");
return nullptr;
}
VkBuffer pushBuffer;
uint32_t pushOffset = push_->PushAligned(rawClut, 1024, 4, &pushBuffer);
VulkanTexture *vktex = new VulkanTexture(vulkan_, alloc_);
vktex->SetTag("DepalClut");
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
if (!vktex->CreateDirect(cmd, texturePixels, 1, 1, destFormat,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, &componentMapping)) {
Crash();
}
vktex->UploadMip(cmd, 0, texturePixels, 1, pushBuffer, pushOffset, texturePixels);
vktex->EndCreate(cmd);
+7 -5
View File
@@ -148,9 +148,11 @@ void DrawEngineVulkan::InitDeviceObjects() {
// if creating and updating them turns out to be expensive.
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
// We now create descriptor pools on demand, so removed from here.
frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 8 * 1024 * 1024);
frame_[i].pushVertex = new VulkanPushBuffer(vulkan_, 2 * 1024 * 1024);
frame_[i].pushIndex = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024);
// Note that pushUBO is also used for tessellation data (search for SetPushBuffer), and to upload
// the null texture. This should be cleaned up...
frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
frame_[i].pushVertex = new VulkanPushBuffer(vulkan_, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
frame_[i].pushIndex = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
}
VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
@@ -174,7 +176,7 @@ void DrawEngineVulkan::InitDeviceObjects() {
res = vkCreateSampler(device, &samp, nullptr, &nullSampler_);
assert(VK_SUCCESS == res);
vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE);
vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan_);
tessDataTransfer = tessDataTransferVulkan;
@@ -276,7 +278,7 @@ void DrawEngineVulkan::BeginFrame() {
if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) {
vertexCache_->Destroy(vulkan_);
delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame.
vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE);
vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
vai_.Clear();
}
+2 -2
View File
@@ -195,9 +195,9 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor
VkCommandBuffer initCmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
// There's only ever a few of these alive, don't need to stress the allocator with these big ones.
drawPixelsTex_ = new VulkanTexture(vulkan_, nullptr);
drawPixelsTex_ = new VulkanTexture(vulkan_);
drawPixelsTex_->SetTag("DrawPixels");
if (!drawPixelsTex_->CreateDirect(initCmd, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) {
if (!drawPixelsTex_->CreateDirect(initCmd, nullptr, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) {
// out of memory?
delete drawPixelsTex_;
drawPixelsTex_ = nullptr;
+9 -2
View File
@@ -181,13 +181,19 @@ GPU_Vulkan::~GPU_Vulkan() {
void GPU_Vulkan::CheckGPUFeatures() {
uint32_t features = 0;
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
if (!PSP_CoreParameter().compat.flags().DepthRangeHack) {
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
}
switch (vulkan_->GetPhysicalDeviceProperties().properties.vendorID) {
case VULKAN_VENDOR_AMD:
// Accurate depth is required on AMD (due to reverse-Z driver bug) so we ignore the compat flag to disable it on those. See #9545
features |= GPU_SUPPORTS_ACCURATE_DEPTH;
break;
case VULKAN_VENDOR_QUALCOMM:
// Accurate depth is required on Adreno too (seems to also have a reverse-Z driver bug).
features |= GPU_SUPPORTS_ACCURATE_DEPTH;
break;
case VULKAN_VENDOR_ARM:
// Also required on older ARM Mali drivers, like the one on many Galaxy S7.
if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth ||
@@ -457,7 +463,8 @@ void GPU_Vulkan::InitDeviceObjects() {
// Initialize framedata
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
assert(!frameData_[i].push_);
frameData_[i].push_ = new VulkanPushBuffer(vulkan_, 64 * 1024);
VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
frameData_[i].push_ = new VulkanPushBuffer(vulkan_, 64 * 1024, usage);
}
VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
+10 -7
View File
@@ -135,7 +135,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
PROFILE_THIS_SCOPE("pipelinebuild");
bool useBlendConstant = false;
VkPipelineColorBlendAttachmentState blend0 = {};
VkPipelineColorBlendAttachmentState blend0{};
blend0.blendEnable = key.blendEnable;
if (key.blendEnable) {
blend0.colorBlendOp = (VkBlendOp)key.blendOpColor;
@@ -174,7 +174,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
dss.depthWriteEnable = key.depthWriteEnable;
}
VkDynamicState dynamicStates[8];
VkDynamicState dynamicStates[8]{};
int numDyn = 0;
if (key.blendEnable &&
(UsesBlendConstant(key.srcAlpha) || UsesBlendConstant(key.srcColor) || UsesBlendConstant(key.destAlpha) || UsesBlendConstant(key.destColor))) {
@@ -208,16 +208,14 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
ms.pSampleMask = nullptr;
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineShaderStageCreateInfo ss[2];
VkPipelineShaderStageCreateInfo ss[2]{};
ss[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
ss[0].pNext = nullptr;
ss[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
ss[0].pSpecializationInfo = nullptr;
ss[0].module = vs->GetModule();
ss[0].pName = "main";
ss[0].flags = 0;
ss[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
ss[1].pNext = nullptr;
ss[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
ss[1].pSpecializationInfo = nullptr;
ss[1].module = fs->GetModule();
@@ -252,7 +250,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
vertexStride = 36;
}
VkVertexInputBindingDescription ibd;
VkVertexInputBindingDescription ibd{};
ibd.binding = 0;
ibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
ibd.stride = vertexStride;
@@ -297,7 +295,12 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
VkPipeline pipeline;
VkResult result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipe, nullptr, &pipeline);
if (result != VK_SUCCESS) {
_assert_msg_(G3D, false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result));
if (result == VK_INCOMPLETE) {
// Bad return value seen on Adreno in Burnout :( Try to ignore?
// TODO: Log all the information we can here!
} else {
_dbg_assert_msg_(G3D, false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result));
}
ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result));
// Create a placeholder to avoid creating over and over if something is broken.
VulkanPipeline *nullPipeline = new VulkanPipeline();
+1 -1
View File
@@ -361,7 +361,7 @@ VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderM
// instantaneous.
#define CACHE_HEADER_MAGIC 0xff51f420
#define CACHE_VERSION 16
#define CACHE_VERSION 17
struct VulkanCacheHeader {
uint32_t magic;
uint32_t version;
+2 -1
View File
@@ -294,7 +294,8 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
// A normal clear will be 2 points, the second point has the color.
// We override this value in the pipeline from software transform for clear rectangles.
dynState.stencilRef = 0xFF;
dynState.stencilWriteMask = 0xFF;
// But we still apply the stencil write mask.
dynState.stencilWriteMask = (~gstate.getStencilWriteMask()) & 0xFF;
} else {
key.stencilTestEnable = false;
key.stencilCompareOp = VK_COMPARE_OP_ALWAYS;
+4 -4
View File
@@ -351,7 +351,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr
depalShaderCache_->SetPushBuffer(drawEngine_->GetPushBufferForTextureData());
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
VulkanTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
drawEngine_->SetDepalTexture(clutTexture->GetImageView());
drawEngine_->SetDepalTexture(clutTexture ? clutTexture->GetImageView() : VK_NULL_HANDLE);
// Only point filtering enabled.
samplerKey.magFilt = false;
samplerKey.minFilt = false;
@@ -604,7 +604,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
{
delete entry->vkTex;
entry->vkTex = new VulkanTexture(vulkan_, allocator_);
entry->vkTex = new VulkanTexture(vulkan_);
VulkanTexture *image = entry->vkTex;
const VkComponentMapping *mapping;
@@ -630,7 +630,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
snprintf(texName, sizeof(texName), "Texture%08x", entry->addr);
image->SetTag(texName);
bool allocSuccess = image->CreateDirect(cmdInit, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
if (!allocSuccess && !lowMemoryMode_) {
WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode");
lowMemoryMode_ = true;
@@ -649,7 +649,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
scaleFactor = 1;
actualFmt = dstFmt;
allocSuccess = image->CreateDirect(cmdInit, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
}
if (!allocSuccess) {
+4 -1
View File
@@ -119,6 +119,9 @@ void System_SendMessage(const char *command, const char *parameter) {
QCoreApplication::postEvent(emugl, new QEvent((QEvent::Type)browseFileEvent));
} else if (!strcmp(command, "browse_folder")) {
QCoreApplication::postEvent(emugl, new QEvent((QEvent::Type)browseFolderEvent));
} else if (!strcmp(command, "graphics_restart")) {
// Should find a way to properly restart the app.
qApp->exit(0);
}
}
@@ -402,7 +405,7 @@ bool MainUI::event(QEvent *e) {
if (QFile::exists(fileName)) {
QDir newPath;
g_Config.currentDirectory = newPath.filePath(fileName).toStdString();
g_Config.Save();
g_Config.Save("browseFileEvent");
NativeMessageReceived("boot", fileName.toStdString().c_str());
}
+30
View File
@@ -30,6 +30,36 @@ No BIOS file required to play, PPSSPP is an "HLE" emulator. Default settings ba
Also includes a really awful hack for MOHH2 multiplayer(MOHH1 works fine without it;p).
~ LunaMoo
What's new in 1.8.0
-------------------
* Avoid crash when starting PPSSPP due to bad AMD Vulkan drivers (#11802)
* PowerVR Vulkan display corruption fixed (#11744, #11747)
* Naruto Shippuden 3 hang fixed (#11780)
* Fixes to various lighting bugs (#11567, #11574, #11577)
* Fix control issue in Sonic Rivals and Rock Band (#11878, #11798, #11879)
* Significant performance improvement in Earth Defense Force 2 (#11172)
* Fix "real clock sync" setting (helps with latency for music games - #11813)
* More speed in FF4 effects and other generated curves (#11425)
* Support for resizing Vulkan on Linux (#11451)
* Improved support for GLES on Linux/IoT (#11507, #11537, #11541, #11632, #11746, #11806, #11845)
* Percentage based frameskipping (#11523)
* DXT accuracy improved, fixing thick white line in Gran Turismo sky (#11530)
* Fix Motorstorm freeze on non-Windows (#11618)
* Faster block transfer in some games like Digimon Adventures (#11531, #11553, #11776)
* Blending optimizations and improvements (#11543, #11620)
* Improve D3D11 rendering issues (#11584)
* Change default graphics backend to D3D11 or OpenGL (#11621, #11658)
* Remove some outdated settings (#11665, #11666, #11667)
* Fix remote disc streaming with ipv6 (#11689, #11700)
* Vulkan: Workarounds for some driver bugs for 5xx series Qualcomm GPUs (#11691, #11694)
* Fix some Qt port issues with recent performance improvements (#11720, #11807, #11808)
* UWP Xbox One: fix X/Back button confusion (#11740)
* Fix Formula 1 2006 timing issue (#11767)
* Fixes and workarounds for some vertex range culling bugs that broke a few games (#11785, #11859), and disable it on older GPUs (#11712, #11773, #11787)
* Android: Allow putting PSP storage on custom paths like SD cards (#11812)
* Corrected vocp instruction, fixing models in Artdink games (#11822, #11835)
* Bundle SDL in binary for macOS builds (#11831)
* Prevent keeping games open on Windows (#11842)
What's new in 1.7.3/1.7.4/1.7.5
-------------------
+35 -12
View File
@@ -27,10 +27,9 @@ static Display* g_Display = NULL;
#endif
static NativeWindowType g_Window = (NativeWindowType)NULL;
int8_t CheckEGLErrors(const std::string& file, uint16_t line) {
int CheckEGLErrors(const char *file, int line) {
EGLenum error;
std::string errortext;
const char *errortext = "unknown";
error = eglGetError();
switch (error)
{
@@ -50,7 +49,7 @@ int8_t CheckEGLErrors(const std::string& file, uint16_t line) {
case EGL_BAD_NATIVE_WINDOW: errortext = "EGL_BAD_NATIVE_WINDOW"; break;
default: errortext = "unknown"; break;
}
printf( "ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n", file.c_str(), line, errortext.c_str(), error );
printf( "ERROR: EGL Error %s detected in file %s at line %d (0x%X)\n", errortext, file, line, error );
return 1;
}
@@ -108,8 +107,13 @@ EGLConfig EGL_FindConfig(int *contextVersion) {
return val;
};
int colorScore = readConfig(EGL_RED_SIZE) + readConfig(EGL_BLUE_SIZE) + readConfig(EGL_GREEN_SIZE);
int alphaScore = readConfig(EGL_ALPHA_SIZE);
// We don't want HDR modes with more than 8 bits per component.
auto readConfigMax = [&](EGLint attr, EGLint m) -> EGLint {
EGLint val = readConfig(attr);
return val > m ? 1 : val; // why not 0?
};
int colorScore = readConfigMax(EGL_RED_SIZE, 8) + readConfigMax(EGL_BLUE_SIZE, 8) + readConfigMax(EGL_GREEN_SIZE, 8);
int alphaScore = readConfigMax(EGL_ALPHA_SIZE, 8);
int depthScore = readConfig(EGL_DEPTH_SIZE);
int levelScore = readConfig(EGL_LEVEL) == 0 ? 100 : 0;
int samplesScore = readConfig(EGL_SAMPLES) == 0 ? 100 : 0;
@@ -120,6 +124,11 @@ EGLConfig EGL_FindConfig(int *contextVersion) {
EGLint caveat = readConfig(EGL_CONFIG_CAVEAT);
int caveatScore = caveat == EGL_NONE ? 100 : (caveat == EGL_NON_CONFORMANT_CONFIG ? 50 : 0);
#ifndef USING_FBDEV
EGLint surfaceType = readConfig(EGL_SURFACE_TYPE);
int surfaceScore = (surfaceType & EGL_WINDOW_BIT) ? 100 : 0;
#endif
EGLint renderable = readConfig(EGL_RENDERABLE_TYPE);
bool renderableGLES3 = (renderable & EGL_OPENGL_ES3_BIT_KHR) != 0;
bool renderableGLES2 = (renderable & EGL_OPENGL_ES2_BIT) != 0;
@@ -138,11 +147,15 @@ EGLConfig EGL_FindConfig(int *contextVersion) {
int score = 0;
// Here's a good place to play with the weights to pick a better config.
score += (colorScore + alphaScore) * 10;
score += colorScore * 10 + alphaScore * 2;
score += depthScore * 5 + stencilScore;
score += levelScore + samplesScore + sampleBufferScore + transparentScore;
score += caveatScore + renderableScoreGLES + renderableScoreGL;
#ifndef USING_FBDEV
score += surfaceScore;
#endif
if (score > bestScore) {
bestScore = score;
best = config;
@@ -154,11 +167,12 @@ EGLConfig EGL_FindConfig(int *contextVersion) {
return best;
}
int8_t EGL_Init() {
int8_t EGL_Init(SDL_Window *window) {
int contextVersion = 0;
EGLConfig eglConfig = EGL_FindConfig(&contextVersion);
if (!eglConfig) {
EGL_ERROR("Unable to find a usable EGL config.", true);
return 1;
}
EGLint contextAttributes[] = {
@@ -172,22 +186,28 @@ int8_t EGL_Init() {
g_eglContext = eglCreateContext(g_eglDisplay, eglConfig, nullptr, contextAttributes);
if (g_eglContext == EGL_NO_CONTEXT) {
EGL_ERROR("Unable to create GLES context!", true);
return 1;
}
#if !defined(USING_FBDEV) && !defined(__APPLE__)
//Get the SDL window handle
// Get the SDL window handle
SDL_SysWMinfo sysInfo; //Will hold our Window information
SDL_VERSION(&sysInfo.version); //Set SDL version
SDL_GetWindowWMInfo(window, &sysInfo);
g_Window = (NativeWindowType)sysInfo.info.x11.window;
#else
g_Window = (NativeWindowType)NULL;
#endif
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, eglConfig, g_Window, nullptr);
if (g_eglSurface == EGL_NO_SURFACE)
if (g_eglSurface == EGL_NO_SURFACE) {
EGL_ERROR("Unable to create EGL surface!", true);
return 1;
}
if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) != EGL_TRUE)
if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) != EGL_TRUE) {
EGL_ERROR("Unable to make GLES context current.", true);
return 1;
}
return 0;
}
@@ -296,7 +316,10 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std:
SDL_ShowWindow(window);
#ifdef USING_EGL
EGL_Init();
if (EGL_Init(window) != 0) {
printf("EGL_Init() failed\n");
return 1;
}
#endif
#ifndef USING_GLES2
+6 -4
View File
@@ -1,6 +1,5 @@
// SDL/EGL implementation of the framework.
// This is quite messy due to platform-specific implementations and #ifdef's.
// Note: SDL1.2 implementation is deprecated and will soon be replaced by SDL2.0.
// If your platform is not supported, it is suggested to use Qt instead.
#include <unistd.h>
@@ -116,6 +115,9 @@ void System_SendMessage(const char *command, const char *parameter) {
} else if (!strcmp(command, "finish")) {
// Do a clean exit
g_QuitRequested = true;
} else if (!strcmp(command, "graphics_restart")) {
// Not sure how we best do this, but do a clean exit, better than being stuck in a bad state.
g_QuitRequested = true;
}
}
@@ -348,9 +350,9 @@ int main(int argc, char *argv[]) {
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
if (VulkanMayBeAvailable()) {
printf("Vulkan might be available.\n");
printf("DEBUG: Vulkan might be available.\n");
} else {
printf("Vulkan is not available.\n");
printf("DEBUG: Vulkan is not available, not using Vulkan.\n");
}
int set_xres = -1;
@@ -618,7 +620,7 @@ int main(int argc, char *argv[]) {
#if !defined(MOBILE_DEVICE)
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
case SDL_WINDOWEVENT_SIZE_CHANGED: // better than RESIZED, more general
{
Uint32 window_flags = SDL_GetWindowFlags(window);
bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN);
+1 -6
View File
@@ -25,16 +25,11 @@ public:
}
void Resize() override {
/*
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
vulkan_->DestroyObjects();
// TODO: Take from real window dimensions
int width = 1024;
int height = 768;
vulkan_->ReinitSurface(width, height);
vulkan_->ReinitSurface();
vulkan_->InitObjects();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
*/
}
void SwapInterval(int interval) override {
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
PPSSPP="${1}"
PPSSPPSDL="${PPSSPP}/Contents/MacOS/PPSSPPSDL"
if [ ! -f "${PPSSPPSDL}" ]; then
echo "No such file: ${PPSSPPSDL}!"
exit 1
fi
SDL=$(otool -L "${PPSSPPSDL}" | grep -v @executable_path | grep -Eo /.+libSDL.+dylib)
if [ "${SDL}" = "" ]; then
echo "SDL is already bundled/unused."
exit 0
fi
if [ ! -f "${SDL}" ]; then
echo "Cannot locate SDL: ${SDL}!"
exit 1
fi
echo "Installing SDL from ${SDL}..."
SDLNAME=$(basename "${SDL}")
mkdir -p "${PPSSPP}/Contents/Frameworks" || exit 1
cp -r "$SDL" "${PPSSPP}/Contents/Frameworks" || exit 1
install_name_tool -change "${SDL}" "@executable_path/../Frameworks/${SDLNAME}" "${PPSSPPSDL}" || exit 1
+2 -2
View File
@@ -44,7 +44,7 @@ void Combo_keyScreen::CreateViews() {
static const int comboKeyImages[5] = {
I_1, I_2, I_3, I_4, I_5,
};
comboselect = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(10, 10, NONE, NONE));
comboselect->SetSpacing(10);
for (int i = 0; i < 5; i++) {
@@ -169,7 +169,7 @@ void Combo_keyScreen::onFinish(DialogResult result) {
g_Config.iCombokey4 = arrayToInt(array);
break;
}
g_Config.Save();
g_Config.Save("Combo_keyScreen::onFInish");
}
UI::EventReturn Combo_keyScreen::ChoiceEventHandler::onChoiceClick(UI::EventParams &e){
+2 -4
View File
@@ -431,8 +431,8 @@ class JoystickHistoryView : public UI::InertView {
public:
JoystickHistoryView(int xAxis, int xDevice, int xDir, int yAxis, int yDevice, int yDir, UI::LayoutParams *layoutParams = nullptr)
: UI::InertView(layoutParams),
xAxis_(xAxis), xDevice_(xDevice), xDir_(xDir),
yAxis_(yAxis), yDevice_(yDevice), yDir_(yDir),
xAxis_(xAxis), xDir_(xDir),
yAxis_(yAxis), yDir_(yDir),
curX_(0.0f), curY_(0.0f),
maxCount_(500) {}
void Draw(UIContext &dc) override;
@@ -455,10 +455,8 @@ private:
};
int xAxis_;
int xDevice_;
int xDir_;
int yAxis_;
int yDevice_;
int yDir_;
float curX_;
+1 -1
View File
@@ -173,7 +173,7 @@ void DisplayLayoutScreen::resized() {
}
void DisplayLayoutScreen::onFinish(DialogResult reason) {
g_Config.Save();
g_Config.Save("DisplayLayoutScreen::onFinish");
}
UI::EventReturn DisplayLayoutScreen::OnCenter(UI::EventParams &e) {
+2 -19
View File
@@ -381,10 +381,7 @@ static void AfterStateBoot(SaveState::Status status, const std::string &message,
void EmuScreen::sendMessage(const char *message, const char *value) {
// External commands, like from the Windows UI.
if (!strcmp(message, "pause") && screenManager()->topScreen() == this) {
releaseButtons();
screenManager()->push(new GamePauseScreen(gamePath_));
} else if (!strcmp(message, "lost_focus")) {
releaseButtons();
} else if (!strcmp(message, "stop")) {
// We will push MainScreen in update().
PSP_Shutdown();
@@ -420,15 +417,12 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
RecreateViews();
} else if (!strcmp(message, "control mapping") && screenManager()->topScreen() == this) {
UpdateUIState(UISTATE_PAUSEMENU);
releaseButtons();
screenManager()->push(new ControlMappingScreen());
} else if (!strcmp(message, "display layout editor") && screenManager()->topScreen() == this) {
UpdateUIState(UISTATE_PAUSEMENU);
releaseButtons();
screenManager()->push(new DisplayLayoutScreen());
} else if (!strcmp(message, "settings") && screenManager()->topScreen() == this) {
UpdateUIState(UISTATE_PAUSEMENU);
releaseButtons();
screenManager()->push(new GameSettingsScreen(gamePath_));
} else if (!strcmp(message, "gpu dump next frame")) {
if (gpu)
@@ -1023,7 +1017,6 @@ void EmuScreen::CreateViews() {
}
UI::EventReturn EmuScreen::OnDevTools(UI::EventParams &params) {
releaseButtons();
I18NCategory *dev = GetI18NCategory("Developer");
DevMenu *devMenu = new DevMenu(dev);
if (params.v)
@@ -1062,8 +1055,8 @@ void EmuScreen::update() {
return;
}
I18NCategory *err = GetI18NCategory("Error");
std::string errLoadingFile = err->T("Error loading file", "Could not load game");
std::string errLoadingFile = gamePath_ + "\n";
errLoadingFile.append(err->T("Error loading file", "Could not load game"));
errLoadingFile.append(" ");
errLoadingFile.append(err->T(errorMessage_.c_str()));
@@ -1082,7 +1075,6 @@ void EmuScreen::update() {
// This is here to support the iOS on screen back button.
if (pauseTrigger_) {
pauseTrigger_ = false;
releaseButtons();
screenManager()->push(new GamePauseScreen(gamePath_));
}
@@ -1394,15 +1386,6 @@ void EmuScreen::autoLoad() {
}
}
// TODO: Add generic loss-of-focus handling for Screens, use this.
void EmuScreen::releaseButtons() {
TouchInput input;
input.flags = TOUCH_RELEASE_ALL;
input.timestamp = time_now_d();
input.id = 0;
touch(input);
}
void EmuScreen::resized() {
RecreateViews();
}
-2
View File
@@ -66,8 +66,6 @@ private:
void setVKeyAnalogX(int stick, int virtualKeyMin, int virtualKeyMax);
void setVKeyAnalogY(int stick, int virtualKeyMin, int virtualKeyMax);
void releaseButtons();
void autoLoad();
void checkPowerDown();
+7 -17
View File
@@ -88,6 +88,7 @@ bool GameInfo::Delete() {
case IdentifiedFileType::ARCHIVE_RAR:
case IdentifiedFileType::ARCHIVE_ZIP:
case IdentifiedFileType::ARCHIVE_7Z:
case IdentifiedFileType::PPSSPP_GE_DUMP:
{
const std::string &fileToRemove = filePath_;
File::Delete(fileToRemove);
@@ -110,27 +111,11 @@ bool GameInfo::Delete() {
}
}
static int64_t GetDirectoryRecursiveSize(const std::string &path) {
std::vector<FileInfo> fileInfo;
getFilesInDir(path.c_str(), &fileInfo);
int64_t sizeSum = 0;
// Note: getFileInDir does not fill in fileSize properly.
for (size_t i = 0; i < fileInfo.size(); i++) {
FileInfo finfo;
getFileInfo(fileInfo[i].fullName.c_str(), &finfo);
if (!finfo.isDirectory)
sizeSum += finfo.size;
else
sizeSum += GetDirectoryRecursiveSize(finfo.fullName);
}
return sizeSum;
}
u64 GameInfo::GetGameSizeInBytes() {
switch (fileType) {
case IdentifiedFileType::PSP_PBP_DIRECTORY:
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
return GetDirectoryRecursiveSize(ResolvePBPDirectory(filePath_));
return getDirectoryRecursiveSize(ResolvePBPDirectory(filePath_), nullptr, GETFILES_GETHIDDEN);
default:
return GetFileLoader()->FileSize();
@@ -229,6 +214,11 @@ bool GameInfo::LoadFromPath(const std::string &gamePath) {
}
std::shared_ptr<FileLoader> GameInfo::GetFileLoader() {
if (filePath_.empty()) {
// Happens when workqueue tries to figure out priorities in PrioritizedWorkQueue::Pop(),
// because priority() calls GetFileLoader()... gnarly.
return fileLoader;
}
if (!fileLoader) {
fileLoader.reset(ConstructFileLoader(filePath_));
}
+1
View File
@@ -146,6 +146,7 @@ protected:
// Note: this can change while loading, use GetTitle().
std::string title;
// TODO: Get rid of this shared_ptr and managae lifetime better instead.
std::shared_ptr<FileLoader> fileLoader;
std::string filePath_;
+5 -5
View File
@@ -1142,7 +1142,7 @@ void GameSettingsScreen::onFinish(DialogResult result) {
Reporting::Enable(enableReports_, "report.ppsspp.org");
Reporting::UpdateConfig();
g_Config.Save();
g_Config.Save("GameSettingsScreen::onFinish");
if (editThenRestore_) {
g_Config.unloadGameConfig();
}
@@ -1215,7 +1215,7 @@ void GameSettingsScreen::CallbackMemstickFolder(bool yes) {
writeDataToFile(true, pendingMemstickFolder_.c_str(), pendingMemstickFolder_.size(), memstickDirFile.c_str());
// Save so the settings, at least, are transferred.
g_Config.memStickDirectory = pendingMemstickFolder_ + "/";
g_Config.Save();
g_Config.Save("MemstickPathChanged");
screenManager()->RecreateAllViews();
}
}
@@ -1227,7 +1227,7 @@ void GameSettingsScreen::CallbackRenderingBackend(bool yes) {
if (yes) {
// Extra save here to make sure the choice really gets saved even if there are shutdown bugs in
// the GPU backend code.
g_Config.Save();
g_Config.Save("GameSettingsScreen::RenderingBackendYes");
System_SendMessage("graphics_restart", "");
} else {
g_Config.iGPUBackend = (int)GetGPUBackend();
@@ -1240,7 +1240,7 @@ void GameSettingsScreen::CallbackRenderingDevice(bool yes) {
if (yes) {
// Extra save here to make sure the choice really gets saved even if there are shutdown bugs in
// the GPU backend code.
g_Config.Save();
g_Config.Save("GameSettingsScreen::RenderingDeviceYes");
System_SendMessage("graphics_restart", "");
} else {
std::string *deviceNameSetting = GPUDeviceNameSetting();
@@ -1473,7 +1473,7 @@ void DeveloperToolsScreen::CreateViews() {
}
void DeveloperToolsScreen::onFinish(DialogResult result) {
g_Config.Save();
g_Config.Save("DeveloperToolsScreen::onFinish");
}
+17 -12
View File
@@ -114,8 +114,8 @@ static bool IsTempPath(const std::string &str) {
class GameButton : public UI::Clickable {
public:
GameButton(const std::string &gamePath, bool gridStyle, UI::LayoutParams *layoutParams = 0)
: UI::Clickable(layoutParams), gridStyle_(gridStyle), gamePath_(gamePath), holdStart_(0), holdEnabled_(true) {}
GameButton(const std::string &gamePath, bool gridStyle, UI::LayoutParams *layoutParams = 0)
: UI::Clickable(layoutParams), gridStyle_(gridStyle), gamePath_(gamePath) {}
void Draw(UIContext &dc) override;
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override {
@@ -157,8 +157,12 @@ public:
}
} else if (hovering_ && key.deviceId == DEVICE_ID_MOUSE && key.keyCode == NKCODE_EXT_MOUSEBUTTON_2) {
// If it's the right mouse button, and it's not otherwise mapped, show the info also.
if (key.flags & KEY_UP) {
if (key.flags & KEY_DOWN) {
showInfoPressed_ = true;
}
if ((key.flags & KEY_UP) && showInfoPressed_) {
showInfo = true;
showInfoPressed_ = false;
}
}
@@ -206,9 +210,10 @@ private:
std::string gamePath_;
std::string title_;
double holdStart_;
bool holdEnabled_;
bool hovering_;
double holdStart_ = 0.0;
bool holdEnabled_ = true;
bool showInfoPressed_ = false;
bool hovering_ = false;
};
void GameButton::Draw(UIContext &dc) {
@@ -404,7 +409,7 @@ void DirButton::Draw(UIContext &dc) {
if (text == "..") {
image = I_UP_DIRECTORY;
}
float tw, th;
dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text.c_str(), &tw, &th, 0);
@@ -802,10 +807,10 @@ void MainScreen::CreateViews() {
scrollHomebrew->SetTag("MainScreenHomebrew");
GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2,
mm->T("How to get games"), "http://www.ppsspp.org/getgames.html", 0,
mm->T("How to get games"), "https://www.ppsspp.org/getgames.html", 0,
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
GameBrowser *tabHomebrew = new GameBrowser(GetSysDirectory(DIRECTORY_GAME), false, &g_Config.bGridView3,
mm->T("How to get homebrew & demos", "How to get homebrew && demos"), "http://www.ppsspp.org/gethomebrew.html",
mm->T("How to get homebrew & demos", "How to get homebrew && demos"), "https://www.ppsspp.org/gethomebrew.html",
FLAG_HOMEBREWSTOREBUTTON,
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
@@ -904,7 +909,7 @@ void MainScreen::CreateViews() {
TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0))));
ver->SetSmall(true);
ver->SetClip(false);
#if defined(USING_WIN_UI) || defined(USING_QT_UI)
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP)
rightColumnItems->Add(new Choice(mm->T("Load","Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile);
#endif
rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings);
@@ -1203,7 +1208,7 @@ UI::EventReturn MainScreen::OnExit(UI::EventParams &e) {
System_SendMessage("finish", "");
// However, let's make sure the config was saved, since it may not have been.
g_Config.Save();
g_Config.Save("MainScreen::OnExit");
#ifdef __ANDROID__
#ifdef ANDROID_NDK_PROFILER
@@ -1271,7 +1276,7 @@ void UmdReplaceScreen::CreateViews() {
scrollAllGames->SetTag("UmdReplaceAllGames");
GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2,
mm->T("How to get games"), "http://www.ppsspp.org/getgames.html", 0,
mm->T("How to get games"), "https://www.ppsspp.org/getgames.html", 0,
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
scrollAllGames->Add(tabAllGames);
+1 -1
View File
@@ -507,7 +507,7 @@ void LogoScreen::render() {
int ppsspp_org_y = yres / 2 + 130;
dc.DrawText("www.ppsspp.org", bounds.centerX(), ppsspp_org_y, textColor, ALIGN_CENTER);
#if (defined(_WIN32) && !PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(ANDROID)
#if (defined(_WIN32) && !PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX)
// Draw the graphics API, except on UWP where it's always D3D11
std::string apiName = screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME);
dc.DrawText(gr->T(apiName), bounds.centerX(), ppsspp_org_y + 50, textColor, ALIGN_CENTER);
+3 -3
View File
@@ -401,7 +401,7 @@ static void CheckFailedGPUBackends() {
writeStringToFile(true, g_Config.sFailedGPUBackends, cache.c_str());
} else {
// Just save immediately, since we have storage.
g_Config.Save();
g_Config.Save("got storage permission");
}
}
@@ -415,7 +415,7 @@ static void ClearFailedGPUBackends() {
if (System_GetPropertyBool(SYSPROP_SUPPORTS_PERMISSIONS)) {
File::Delete(GetSysDirectory(DIRECTORY_APP_CACHE) + "/FailedGraphicsBackends.txt");
} else {
g_Config.Save();
g_Config.Save("clearFailedGPUBackends");
}
}
@@ -1298,7 +1298,7 @@ void NativeShutdown() {
delete host;
host = nullptr;
#endif
g_Config.Save();
g_Config.Save("NativeShutdown");
// Avoid shutting this down when restarting core.
if (!restarting)
+3 -3
View File
@@ -330,7 +330,7 @@ EventReturn ReportScreen::HandleSubmit(EventParams &e) {
if (Reporting::Enable(enableReporting_, "report.ppsspp.org")) {
Reporting::UpdateConfig();
g_Config.Save();
g_Config.Save("ReportScreen::HandleSubmit");
}
std::string filename = includeScreenshot_ ? screenshotFilename_ : "";
@@ -341,7 +341,7 @@ EventReturn ReportScreen::HandleSubmit(EventParams &e) {
}
EventReturn ReportScreen::HandleBrowser(EventParams &e) {
const std::string url = "http://" + Reporting::ServerHost() + "/";
const std::string url = "https://" + Reporting::ServerHost() + "/";
LaunchBrowser(url.c_str());
return EVENT_DONE;
}
@@ -458,7 +458,7 @@ void ReportFinishScreen::ShowSuggestions() {
}
UI::EventReturn ReportFinishScreen::HandleViewFeedback(UI::EventParams &e) {
const std::string url = "http://" + Reporting::ServerHost() + "/game/" + Reporting::CurrentGameID();
const std::string url = "https://" + Reporting::ServerHost() + "/game/" + Reporting::CurrentGameID();
LaunchBrowser(url.c_str());
return EVENT_DONE;
}
+38 -24
View File
@@ -132,8 +132,9 @@ public:
: UI::LinearLayout(orientation, layoutParams) {
}
void SetCompare(CompareFunc lessFunc, DoneFunc) {
void SetCompare(CompareFunc lessFunc, DoneFunc doneFunc) {
lessFunc_ = lessFunc;
doneFunc_ = doneFunc;
}
void Update() override;
@@ -336,43 +337,56 @@ bool SavedataBrowser::ByFilename(const UI::View *v1, const UI::View *v2) {
return strcmp(b1->GamePath().c_str(), b2->GamePath().c_str()) < 0;
}
static time_t GetTotalSize(const SavedataButton *b) {
auto fileLoader = std::unique_ptr<FileLoader>(ConstructFileLoader(b->GamePath()));
tm datetm;
bool success;
switch (Identify_File(fileLoader.get())) {
case IdentifiedFileType::PSP_PBP_DIRECTORY:
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
return getDirectoryRecursiveSize(ResolvePBPDirectory(b->GamePath()), nullptr, GETFILES_GETHIDDEN);
default:
return fileLoader->FileSize();
}
}
bool SavedataBrowser::BySize(const UI::View *v1, const UI::View *v2) {
const SavedataButton *b1 = static_cast<const SavedataButton *>(v1);
const SavedataButton *b2 = static_cast<const SavedataButton *>(v2);
std::shared_ptr<GameInfo> g1info = g_gameInfoCache->GetInfo(nullptr, b1->GamePath(), GAMEINFO_WANTSIZE);
std::shared_ptr<GameInfo> g2info = g_gameInfoCache->GetInfo(nullptr, b2->GamePath(), GAMEINFO_WANTSIZE);
if (GetTotalSize(b1) > GetTotalSize(b2))
return true;
return strcmp(b1->GamePath().c_str(), b2->GamePath().c_str()) < 0;
}
// They might be zero, but that's fine.
return g1info->gameSize > g2info->gameSize;
static time_t GetDateSeconds(const SavedataButton *b) {
auto fileLoader = std::unique_ptr<FileLoader>(ConstructFileLoader(b->GamePath()));
tm datetm;
bool success;
if (Identify_File(fileLoader.get()) == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) {
success = File::GetModifTime(b->GamePath() + "/PARAM.SFO", datetm);
} else {
success = File::GetModifTime(b->GamePath(), datetm);
}
if (success) {
return mktime(&datetm);
}
return (time_t)0;
}
bool SavedataBrowser::ByDate(const UI::View *v1, const UI::View *v2) {
const SavedataButton *b1 = static_cast<const SavedataButton *>(v1);
const SavedataButton *b2 = static_cast<const SavedataButton *>(v2);
auto getDateSeconds = [&](const SavedataButton *b) {
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(nullptr, b->GamePath(), 0);
tm datetm;
bool success;
if (ginfo && ginfo->fileType == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) {
success = File::GetModifTime(b->GamePath() + "/PARAM.SFO", datetm);
} else {
success = File::GetModifTime(b->GamePath(), datetm);
}
if (success) {
return mktime(&datetm);
}
return (time_t)0;
};
return getDateSeconds(b1) > getDateSeconds(b2);
if (GetDateSeconds(b1) > GetDateSeconds(b2))
return true;
return strcmp(b1->GamePath().c_str(), b2->GamePath().c_str()) < 0;
}
bool SavedataBrowser::SortDone() {
PrioritizedWorkQueue *wq = g_gameInfoCache->WorkQueue();
return wq->Done();
return true;
}
void SavedataBrowser::Refresh() {
+1 -1
View File
@@ -286,7 +286,7 @@ void TouchControlLayoutScreen::resized() {
}
void TouchControlLayoutScreen::onFinish(DialogResult reason) {
g_Config.Save();
g_Config.Save("TouchControlLayoutScreen::onFinish");
}
UI::EventReturn TouchControlLayoutScreen::OnVisibility(UI::EventParams &e) {
+2 -2
View File
@@ -106,14 +106,14 @@ void TouchControlVisibilityScreen::CreateViews() {
}
choice->SetCentered(true);
row->Add(choice);
grid->Add(row);
}
}
void TouchControlVisibilityScreen::onFinish(DialogResult result) {
g_Config.Save();
g_Config.Save("TouchControlVisibilityScreen::onFinish");
}
UI::EventReturn TouchControlVisibilityScreen::OnToggleAll(UI::EventParams &e) {
+404 -15
View File
@@ -31,15 +31,31 @@
[VertexDepthRounding]
# Phantasy Star Portable needs depth rounding to 16-bit precision for text to show up.
# It's enough to do it at the vertex granularity. #3777
# Phantasy Star Portable
ULJM05309 = true
ULUS10410 = true
ULES01218 = true
ULJM08023 = true
ULES01218 = true
# Phantasy Star Portable 2 JP (missing text)
# Phantasy Star Portable 1 Demo
NPUH90023 = true
# Phantasy Star Portable 2
ULES01439 = true
ULUS10529 = true
ULJM05493 = true
NPJH50043 = true
ULJM08030 = true
NPUH90023 = true
ULJM91014 = true
NPJH90002 = true
ULJM05732 = true
NPJH50332 = true
# Phantasy Star Portable 2 JP Demo
ULJM91018 = true
NPJH90062 = true
# Phantasy Star Portable Infinity Demo
NPJH90157 = true # Infinity demo
# Puyo Puyo Fever 2 #3663 (layering)
ULJM05058 = true
# NBA 2K13 #6603 (menu glitches)
@@ -48,6 +64,7 @@ ULJS00551 = true
NPJH50713 = true
ULJS00596 = true
ULES01578 = true
ULUS10598 = true
# Power Stone Collection #6257 (map arrow)
ULES00496 = true
ULUS10171 = true
@@ -70,47 +87,83 @@ ULJS00454 = true
# Heroes Phantasia Limited Edition Disc requires pixel depth rounding.
ULJS00455 = true
# Phantasy Star games flickering
# Phantasy Star Portable 1
# Phantasy Star Portable
ULJM05309 = true
ULUS10410 = true
ULES01218 = true
ULJM08023 = true
ULES01218 = true
# Phantasy Star Portable 2 JP
# Phantasy Star Portable 1 Demo
NPUH90023 = true
# Phantasy Star Portable 2
ULES01439 = true
ULUS10529 = true
ULJM05493 = true
NPJH50043 = true
ULJM08030 = true
# Phantasy Star Portable 1 Demo
NPUH90023 = true
ULJM91014 = true
NPJH90002 = true
ULJM05732 = true
NPJH50332 = true
# Phantasy Star Portable 2 JP Demo
ULJM91018 = true
NPJH90062 = true
# Phantasy Star Portable Infinity Demo
NPJH90157 = true # Infinity demo
[DepthRangeHack]
# Phantasy Star Portable 2 and Infinity both use viewport depth outside [0, 1].
# This gets clamped in our current implementation, but attempts to fix it run into
# Other bugs, so we've restored this hack for now.
# Phantasy Star Portable
ULJM05309 = true
ULUS10410 = true
ULES01218 = true
ULJM08023 = true
ULES01218 = true
# Phantasy Star Portable 1 Demo
NPUH90023 = true
# Phantasy Star Portable 2
ULES01439 = true
ULUS10529 = true
ULJM05493 = true
NPJH50043 = true
ULJM08030 = true
ULES01439 = true
ULUS10529 = true
ULJM91018 = true # Infinity demo disc?
NPJH90157 = true # Infinity demo
NPUH90023 = true
ULJM91014 = true
NPJH90002 = true
ULJM05732 = true
NPJH50332 = true
# Phantasy Star Portable 2 JP Demo
ULJM91018 = true
NPJH90062 = true
# Phantasy Star Portable Infinity Demo
NPJH90157 = true # Infinity demo
[ClearToRAM]
# SOCOM Navy Seals games require this. See issue #8973.
# Navy Seals
UCUS98615 = true
ULES00038 = true
UCKS45021 = true
# Fireteam Bravo 3
UCJS10102 = true
# Navy Seals : Tactical Strike
UCES00855 = true
UCUS98649 = true
NPJG00035 = true
NPJG90068 = true
UCJS10102 = true
# Tactical Strike demo
NPUG70003 = true
# Fireteam Bravo
UCKS45021 = true
UCUS98615 = true
UCES00038 = true
ULES00038 = true
# Fireteam Bravo 2
UCES00543 = true
UCUS98645 = true
# Fireteam Bravo 2 Demo
UCUS98677 = true
UCUS98691 = true
# Fireteam Bravo 3
NPHG00032 = true
UCUS98716 = true
UCES01242 = true
@@ -130,15 +183,25 @@ UCKS45022 = true
ULJS19009 = true
NPJH50141 = true
[DisableReadbacks]
# MotoGP copies the framebuffer to RAM every frame. We have a hack to display it directly,
# which means we don't also need a readback.
ULJS00078 = true
ULUS10153 = true
UCES00373 = true
[DrawSyncEatCycles]
# This replaced Crash Tag Team Racing hack to also fix Gundam games
# It makes sceGeDrawSync eat a lot of cycles which can affect timing in lots of games,
# might be negative for others, but happens to fix games below.
# Crash Tag Team Racing needs it to pass checking memory stick screen.
ULUS10044 = true
ULES00168 = true
ULES00169 = true
ULES00170 = true
ULES00171 = true
ULES00172 = true
ULJM05036 = true
ULUS10044 = true
# Gundam Battle Royale might need it to avoid crashes when certain Ace enemies shows up
ULJS00083 = true
ULKS46104 = true
@@ -153,6 +216,14 @@ ULKS46183 = true
ULJS00260 = true
ULJS19041 = true
NPJH50843 = true
# Helps with Jeanne d'Arc weird 40/40 fps problem #5154
UCAS40129 = true
UCJS10048 = true
UCKS45033 = true
UCJS18014 = true
UCUS98700 = true
NPJG00032 = true
UCJX90019 = true
[FakeMipmapChange]
# This hacks separates each mipmap to independent textures to display wrong-size mipmaps.
@@ -162,3 +233,321 @@ NPJH50843 = true
ULJM05753 = true
NPJH50348 = true
ULJM06009 = true
[RequireBufferedRendering]
# Warn the user that the game will not work and have issue, if buffered rendering is not enabled.
# Midnight Club: LA Remix
ULUS10383 = true
ULES01144 = true
ULJS00180 = true
ULJS00267 = true
ULJM05904 = true
NPJH50440 = true
# Midnight Club 3 : DUB edition
ULUS10021 = true
ULES00108 = true
# GTA : VCS
ULUS10160 = true
ULES00502 = true
ULJM05297 = true
ULJM05395 = true
ULJM05884 = true
NPJH50827 = true
# GTA : LCS
ULUS10041 = true
ULES00151 = true
ULJM05255 = true
ULJM05359 = true
ULJM05885 = true
NPJH50825 = true
# GOW : JP/Korean
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
NPJG90095 = true
NPEG90035 = true
NPUG70125 = 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
# Daxter
UCUS98618 = true
UCES00044 = true
NPUG80329 = true
NPEG00025 = true
# Ys Seven
ULUS10551 = true
ULJM05475 = true
NPEH00065 = true
NPJH50350 = true
ULJM08041 = true
NPEH00065 = true
# The Legend of Heroes: Trails in the Sky
ULUS10540 = true
ULUS10578 = true
ULES01556 = true
ULJM05170 = true
ULJM08033 = true
NPJH50373 = true
# Grand Knights History
ULJS00394 = true
ULJS19068 = true
NPJH50518 = true
# Tactics Ogre
ULUS10565 = true
ULES01500 = true
ULJM05753 = true
NPJH50348 = true
ULJM06009 = true
UCKS45164 = true
# Metal Gear Solid : Peace Walker
ULUS10509 = true
ULES01372 = true
ULJM08038 = true
NPJH50045 = true
ULJM05630 = true
# Star Ocean : Second Evolution
ULUS10375 = true
ULES01187 = true
ULJM05591 = true
ULJM05325 = true
UCAS40203 = true
# Driver 76
ULUS10235 = true
ULES00740 = true
# Chili Con Carnage
ULUS10216 = true
ULES00629 = true
# TODO: There are many more.
[RequireBlockTransfer]
# Warn the user that the game will have issue graphic, if simulate block transfer is not enabled.
# Ys Seven need it to fix minimap. See issues #2928
ULUS10551 = true
ULJM05475 = true
NPEH00065 = true
NPJH50350 = true
ULJM08041 = true
NPEH00065 = true
# The Legend of Heroes: Trails in the Sky need it to fix graphical glitch in menu screen. See issues #8053
ULUS10540 = true
ULUS10578 = true
ULES01556 = true
ULJM05170 = true
ULJM08033 = true
NPJH50373 = true
NPUH10191 = true
NPUH10197 = true
# Grand Knights History need it to fix blackboxes on characters and flickering texture . See issues #2135 , #6099
ULJS00394 = true
ULJS19068 = true
NPJH50518 = true
# TODO: Will add some games in the future
NPJH50686 = true # Digimon Adventures (JP, and English patches...)
ULJS00078 = true # MotoGP
ULUS10153 = true # MotoGP
UCES00373 = true # MotoGP
ULUS10551 = true # Ys Seven
ULJM05475 = true # Ys Seven JP
ULUS10549 = true # Ys Seven
NPEH00065 = true # Ys Seven
NPJH50350 = true # Ys Seven
ULJM08041 = true # Ys Seven
[DisableAccurateDepth]
# Midnight Club: LA Remix
ULUS10383 = true
ULES01144 = true
ULJS00180 = true
ULJS00267 = true
ULJM05904 = true
NPJH50440 = true
# Midnight Club 3 : DUB edition
ULUS10021 = true
ULES00108 = true
# Shadow of Destiny (#9545)
ULUS10459 = true
NPJH50036 = true
# Burnout games have problems with this on Mali, and have no use for it
# Legends
ULES00125 = true
ULUS10025 = true
ULJM05228 = true
NPJH50305 = true
ULJM05049 = true
ULKS46027 = true
ULAS42019 = true
# Dominator
ULUS10236 = true
ULES00750 = true
ULJM05242 = true
ULJM05371 = true
NPJH50304 = true
ULES00703 = true
ULAS42095 = true
[RequireDefaultCPUClock]
# 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
NPJG90095 = true
NPEG90035 = true
NPUG70125 = true
[MGS2AcidHack]
ULES00008 = true
ULES00284 = true
ULJM05047 = true
ULKS46065 = true
ULJM08001 = true
ULJM05001 = true
ULAS42007 = true
ULUS10006 = true
ULUS10077 = true
[SonicRivalsHack]
ULES00622 = true # SR1
ULUS10195 = true # SR1
ULUS10323 = true # SR2
ULES00940 = true # SR2
ULET00958 = true
[BlockTransferAllowCreateFB]
NPJH50686 = true # Digimon Adventures (JP, and English patches...)
ULJS00078 = true # MotoGP
ULUS10153 = true # MotoGP
UCES00373 = true # MotoGP
ULUS10551 = true # Ys Seven
ULJM05475 = true # Ys Seven JP
ULUS10549 = true # Ys Seven
NPEH00065 = true # Ys Seven
NPJH50350 = true # Ys Seven
ULJM08041 = true # Ys Seven
[YugiohSaveFix]
# The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat,
# but the real cause still unknown. #7914
# Yu-Gi-Oh! Duel Monsters GX: Tag Force
ULJM05151 = true
ULES00600 = true
ULUS10136 = true
# Yu-Gi-Oh! Duel Monsters GX: Tag Force 2
ULUS10302 = true
ULJM05260 = true
ULES00925 = true
ULES00926 = true
# Yu-Gi-Oh! Duel Monsters GX: Tag Force 3
ULES01183 = true
ULJM05373 = true
# Yu-Gi-Oh! 5D's Tag Force 4
ULUS10481 = true
ULJM05479 = true
ULES01362 = true
# Yu-Gi-Oh! 5D's Tag Force 5
ULUS10555 = true
ULJM05734 = true
ULES01474 = true
# Yu-Gi-Oh! 5D's Tag Force 6
ULJM05940 = true
NPJH50794 = true
# Yu-Gi-Oh! 5D's Tag Force
ULJM05940 = true
# Yu-Gi-Oh! ARC-V Tag Force Special
NPJH00142 = true
[ForceUMDDelay]
# F1 2006 won't boot at all with our standard unrealistically fast timing.
UCES00238 = true
UCJS10045 = true
# F1 2005, japan only?
UCJS10019 = true
[ForceMax60FPS]
# The GOW games are very heavy and render as fast as they can. They benefit greatly from
# capping the framerate at 60fps.
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
# F1 2006 has extremely long loading times if we don't limit the framerate.
UCES00238 = true
UCJS10045 = true
# F1 2005, japan only?
UCJS10019 = true
+1
View File
@@ -153,3 +153,4 @@ d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,righ
05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,
03000000380700008532000010010000,MadCatz Madcatz Fightpad,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b5,righttrigger:b7,
030000000d0f0000ee00000011010000,HORI CO.,LTD. HORIPAD mini4,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
030000000d0f0000c100000011010000,HORI CO.,LTD. HORIPAD S,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
+16 -11
View File
@@ -21,6 +21,7 @@
#include "Common/CommonWindows.h"
#include "util/text/utf8.h"
#include "ext/xxhash.h"
#include "base/display.h"
#include <CommDlg.h>
#include <tchar.h>
@@ -154,17 +155,21 @@ CtrlDisAsmView::CtrlDisAsmView(HWND _wnd)
wnd=_wnd;
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)this);
SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL);
SetScrollRange(wnd, SB_VERT, -1,1,TRUE);
SetScrollRange(wnd, SB_VERT, -1, 1, TRUE);
charWidth = g_Config.iFontWidth;
rowHeight = g_Config.iFontHeight+2;
const float fontScale = 1.0f / g_dpi_scale_real_y;
charWidth = g_Config.iFontWidth * fontScale;
rowHeight = (g_Config.iFontHeight + 2) * fontScale;
int scaledFontHeight = g_Config.iFontHeight * fontScale;
font = CreateFont(scaledFontHeight, charWidth, 0, 0,
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
L"Lucida Console");
boldfont = CreateFont(scaledFontHeight, charWidth, 0, 0,
FW_DEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
L"Lucida Console");
font = CreateFont(rowHeight-2,charWidth,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,
L"Lucida Console");
boldfont = CreateFont(rowHeight-2,charWidth,0,0,FW_DEMIBOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,
L"Lucida Console");
curAddress=0;
showHex=false;
curAddress = 0;
showHex = false;
hasFocus = false;
dontRedraw = false;
keyTaken = false;
@@ -974,8 +979,8 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
std::string newname;
truncate_cpy(name, g_symbolMap->GetLabelString(funcBegin).c_str());
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), L"New function name", name, newname)) {
g_symbolMap->SetLabelName(newname.c_str(),funcBegin);
u32 funcSize = g_symbolMap->GetFunctionSize(curAddress);
g_symbolMap->SetLabelName(newname.c_str(), funcBegin);
u32 funcSize = g_symbolMap->GetFunctionSize(funcBegin);
MIPSAnalyst::RegisterFunction(funcBegin, funcSize, newname.c_str());
MIPSAnalyst::UpdateHashMap();
MIPSAnalyst::ApplyHashMap();
+18 -16
View File
@@ -4,12 +4,13 @@
#include <math.h>
#include "Core/Config.h"
#include "../resource.h"
#include "../../Core/MemMap.h"
#include "../W32Util/Misc.h"
#include "Windows/resource.h"
#include "Core/MemMap.h"
#include "Windows/W32Util/Misc.h"
#include "Windows/InputBox.h"
#include "../Main.h"
#include "../../Core/Debugger/SymbolMap.h"
#include "Windows/main.h"
#include "Core/Debugger/SymbolMap.h"
#include "base/display.h"
#include "Debugger_Disasm.h"
#include "DebuggerShared.h"
@@ -26,19 +27,20 @@ CtrlMemView::CtrlMemView(HWND _wnd)
SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL);
SetScrollRange(wnd, SB_VERT, -1,1,TRUE);
rowHeight = g_Config.iFontHeight;
charWidth = g_Config.iFontWidth;
offsetPositionY = offsetLine*rowHeight;
const float fontScale = 1.0f / g_dpi_scale_real_y;
rowHeight = g_Config.iFontHeight * fontScale;
charWidth = g_Config.iFontWidth * fontScale;
offsetPositionY = offsetLine * rowHeight;
font =
CreateFont(rowHeight,charWidth,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,L"Lucida Console");
underlineFont =
CreateFont(rowHeight,charWidth,0,0,FW_DONTCARE,FALSE,TRUE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,L"Lucida Console");
curAddress=0;
font = CreateFont(rowHeight, charWidth, 0, 0,
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
L"Lucida Console");
underlineFont = CreateFont(rowHeight, charWidth, 0, 0,
FW_DONTCARE, FALSE, TRUE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
L"Lucida Console");
curAddress = 0;
debugger = 0;
searchQuery = "";
matchAddress = -1;
searching = false;
+34 -51
View File
@@ -3,11 +3,12 @@
#include <math.h>
#include <tchar.h>
#include "base/display.h"
#include "util/text/utf8.h"
#include "../resource.h"
#include "Windows/resource.h"
#include "Core/MemMap.h"
#include "../W32Util/Misc.h"
#include "../InputBox.h"
#include "Windows/W32Util/Misc.h"
#include "Windows/InputBox.h"
#include "CtrlRegisterList.h"
#include "Debugger_MemoryDlg.h"
@@ -16,11 +17,10 @@
#include "Debugger_Disasm.h"
#include "DebuggerShared.h"
#include "../main.h"
#include "Windows/main.h"
static const int numCPUs = 1;
//#include "DbgHelp.h"
extern HMENU g_hPopupMenus;
enum { REGISTER_PC = 32, REGISTER_HI, REGISTER_LO, REGISTERS_END };
@@ -29,23 +29,22 @@ TCHAR CtrlRegisterList::szClassName[] = _T("CtrlRegisterList");
void CtrlRegisterList::init()
{
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.lpszClassName = szClassName;
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = CtrlRegisterList::wndProc;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hIcon = 0;
wc.lpszMenuName = 0;
wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
wc.style = CS_DBLCLKS;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof( CtrlRegisterList * );
wc.hIconSm = 0;
RegisterClassEx(&wc);
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.lpszClassName = szClassName;
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = CtrlRegisterList::wndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = 0;
wc.lpszMenuName = 0;
wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
wc.style = CS_DBLCLKS;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(CtrlRegisterList *);
wc.hIconSm = 0;
RegisterClassEx(&wc);
}
void CtrlRegisterList::deinit()
@@ -53,8 +52,6 @@ void CtrlRegisterList::deinit()
//UnregisterClass(szClassName, hInst)
}
LRESULT CALLBACK CtrlRegisterList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CtrlRegisterList *ccp = CtrlRegisterList::getFrom(hwnd);
@@ -109,44 +106,30 @@ LRESULT CALLBACK CtrlRegisterList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, L
break;
case WM_GETDLGCODE: // want chars so that we can return 0 on key press and supress the beeping sound
return DLGC_WANTARROWS|DLGC_WANTCHARS;
default:
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
default:
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
CtrlRegisterList *CtrlRegisterList::getFrom(HWND hwnd)
{
return (CtrlRegisterList *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
return (CtrlRegisterList *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
CtrlRegisterList::CtrlRegisterList(HWND _wnd)
{
wnd=_wnd;
: wnd(_wnd) {
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)this);
//SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL);
//SetScrollRange(wnd, SB_VERT, -1,1,TRUE);
rowHeight=g_Config.iFontHeight;
font = CreateFont(rowHeight,g_Config.iFontWidth,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH,L"Lucida Console");
selecting=false;
selection=0;
category=0;
showHex=false;
cpu=0;
lastPC = 0;
lastCat0Values = NULL;
changedCat0Regs = NULL;
const float fontScale = 1.0f / g_dpi_scale_real_y;
rowHeight = g_Config.iFontHeight * fontScale;
int charWidth = g_Config.iFontWidth * fontScale;
font = CreateFont(rowHeight, charWidth, 0, 0,
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
L"Lucida Console");
}
CtrlRegisterList::~CtrlRegisterList()
{
DeleteObject(font);
+14 -14
View File
@@ -27,23 +27,23 @@ class CtrlRegisterList
RECT rect;
int rowHeight;
int selection;
int marker;
int category;
int selection = 0;
int marker = 0;
int category = 0;
int oldSelection;
int oldSelection = 0;
bool selectionChanged;
bool selecting;
bool hasFocus;
bool showHex;
DebugInterface *cpu;
bool selectionChanged = false;
bool selecting = false;
bool hasFocus = false;
bool showHex = false;
DebugInterface *cpu = nullptr;
static TCHAR szClassName[];
u32 lastPC;
u32 *lastCat0Values;
bool *changedCat0Regs;
bool ctrlDown;
u32 lastPC = 0;
u32 *lastCat0Values = nullptr;
bool *changedCat0Regs = nullptr;
bool ctrlDown = false;
u32 getSelectedRegValue(char *out, size_t size);
void copyRegisterValue();
@@ -79,4 +79,4 @@ public:
{
return cpu;
}
};
};
+2 -2
View File
@@ -159,7 +159,7 @@ void MainThreadFunc() {
if (performingRestart) {
// Okay, switching graphics didn't work out. Probably a driver bug - fallback to restart.
// This happens on NVIDIA when switching OpenGL -> Vulkan.
g_Config.Save();
g_Config.Save("switch_graphics_failed");
W32Util::ExitAndRestart();
}
@@ -196,7 +196,7 @@ void MainThreadFunc() {
g_Config.iGPUBackend = (int)nextBackend;
// Clear this to ensure we try their selection.
g_Config.sFailedGPUBackends.clear();
g_Config.Save();
g_Config.Save("save_graphics_fallback");
W32Util::ExitAndRestart();
} else {
+2 -2
View File
@@ -145,10 +145,10 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error"));
bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO);
if (yes) {
// Change the config to D3D and restart.
// Change the config to D3D9 and restart.
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;
g_Config.sFailedGPUBackends.clear();
g_Config.Save();
g_Config.Save("save_d3d9_fallback");
W32Util::ExitAndRestart();
}
+2 -2
View File
@@ -255,7 +255,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
const char *defaultError = "Insufficient OpenGL driver support detected!\n\n"
"Your GPU reports that it does not support OpenGL 2.0. Would you like to try using DirectX instead?\n\n"
"DirectX is currently compatible with less games, but on your GPU it may be the only choice.\n\n"
"Visit the forums at http://forums.ppsspp.org for more information.\n\n";
"Visit the forums at https://forums.ppsspp.org for more information.\n\n";
std::wstring versionDetected = ConvertUTF8ToWString(glVersion + "\n\n");
std::wstring error = ConvertUTF8ToWString(err->T("InsufficientOpenGLDriver", defaultError));
@@ -271,7 +271,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
bool d3d9 = IDYES == MessageBox(hWnd_, whichD3D9.c_str(), title.c_str(), MB_YESNO);
g_Config.iGPUBackend = d3d9 ? (int)GPUBackend::DIRECT3D9 : (int)GPUBackend::DIRECT3D11;
g_Config.sFailedGPUBackends.clear();
g_Config.Save();
g_Config.Save("save_d3d11_fallback");
W32Util::ExitAndRestart();
}
+2 -2
View File
@@ -127,9 +127,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
if (g_Vulkan->DeviceExtensions().EXT_debug_utils) {
int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
// We're intentionally skipping VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT and
// VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, just too spammy.
g_Vulkan->InitDebugUtilsCallback(&VulkanDebugUtilsCallback, bits, &g_LogOptions);
} else {
int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
+7 -7
View File
@@ -821,25 +821,25 @@ namespace MainWindow {
case ID_OPTIONS_DIRECT3D9:
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;
g_Config.Save();
g_Config.Save("gpu_choice");
RestartApp();
break;
case ID_OPTIONS_DIRECT3D11:
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;
g_Config.Save();
g_Config.Save("gpu_choice");
RestartApp();
break;
case ID_OPTIONS_OPENGL:
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
g_Config.Save();
g_Config.Save("gpu_choice");
RestartApp();
break;
case ID_OPTIONS_VULKAN:
g_Config.iGPUBackend = (int)GPUBackend::VULKAN;
g_Config.Save();
g_Config.Save("gpu_choice");
RestartApp();
break;
@@ -1051,15 +1051,15 @@ namespace MainWindow {
break;
case ID_HELP_OPENWEBSITE:
ShellExecute(NULL, L"open", L"http://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, L"open", L"https://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);
break;
case ID_HELP_BUYGOLD:
ShellExecute(NULL, L"open", L"http://central.ppsspp.org/buygold", NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, L"open", L"https://central.ppsspp.org/buygold", NULL, NULL, SW_SHOWNORMAL);
break;
case ID_HELP_OPENFORUM:
ShellExecute(NULL, L"open", L"http://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, L"open", L"https://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);
break;
case ID_HELP_GITHUB:
+5 -5
View File
@@ -130,7 +130,7 @@
<ForcedIncludeFiles>stdafx.h;Common/DbgNew.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<Optimization>Disabled</Optimization>
@@ -168,7 +168,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<OmitFramePointers>false</OmitFramePointers>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<Optimization>Disabled</Optimization>
@@ -199,7 +199,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -248,7 +248,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointModel>Precise</FloatingPointModel>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -587,4 +587,4 @@
<UserProperties RESOURCE_FILE="DaSh.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>
+2 -2
View File
@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.ppsspp.ppsspp"
android:installLocation="auto"
android:versionCode="17050000"
android:versionName="1.7.5.0">
android:versionCode="18000000"
android:versionName="1.8.0.0">
<!-- Note that versionCode should be in the format xyzzrrrr. Example: 16030000 -->
<!-- In this same case, versionName should be 1.6.3.0 -->
-5
View File
@@ -882,11 +882,6 @@ void getDesiredBackbufferSize(int &sz_x, int &sz_y) {
sz_x = 0;
sz_y = 0;
}
// Round the size up to the nearest multiple of 4. While this may cause a tiny aspect ratio distortion,
// there's some hope that #11151 is a driver bug that might be worked around this way. If this fixes it,
// it'll be worth trying to round to a multiple of 2 instead.
sz_x = (sz_x + 3) & ~3;
sz_y = (sz_y + 3) & ~3;
}
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_setDisplayParameters(JNIEnv *, jclass, jint xres, jint yres, jint dpi, jfloat refreshRate) {
Loaded 100 of 126 files, more files were not shown because too many files have changed in this diff. Show more