Merge branch 'master' into TemporaryHackishBranch

# Conflicts:
#	.gitignore
#	CMakeLists.txt
#	Core/HLE/sceNet.cpp
#	UI/GameSettingsScreen.cpp
#	UI/MainScreen.cpp
#	UI/MiscScreens.cpp
#	UI/ui_atlas.cpp
#	UI/ui_atlas.h
#	Windows/resource.h
#	android/.gitignore
#	android/assets/ui_atlas.zim
#	assets/ui_atlas.zim
#	assets/ui_atlas_lowmem.zim
#	atlasscript_lowmem.txt
#	ext/native/tools/atlastool/atlastool.vcxproj
#	ext/native/tools/tools.sln
#	ext/native/ui/ui_context.cpp
#	gradle/wrapper/gradle-wrapper.properties

also fix atlas generation.
This commit is contained in:
LunaMoo committed 2020-04-05 19:34:24 +02:00
commit 6e202e5bdd
336 files changed
+6667 -75332

No files matched your search

+2 -4
View File
@@ -28,8 +28,6 @@ Windows/ARM64
Windows/ipch
Windows/bin-release
Windows/win-version.h
ui_atlas.zim.png
ui_atlas_high.zim.png
android/assets
ext/_Output
android/lint.xml
@@ -87,10 +85,10 @@ __testfinish.txt
__testfailure.bmp
GameLogNotes.txt
screenshots
android/ui_atlas_luna.zim
android/assets/lang
android/assets/flash0
ppge_atlas.zim.png
ui_atlas_luna.zim.png
ppge_atlas_luna.zim.png
local.properties
r.sh
+3
View File
@@ -28,3 +28,6 @@
[submodule "ext/rapidjson"]
path = ext/rapidjson
url = https://github.com/Tencent/rapidjson.git
[submodule "ext/native/tools/prebuilt"]
path = ext/native/tools/prebuilt
url = https://github.com/hrydgard/ppsspp-freetype.git
+2 -2
View File
@@ -86,11 +86,11 @@ matrix:
env: PPSSPP_BUILD_TYPE=Linux
LIBRETRO=TRUE
- os: osx
osx_image: xcode8.3
osx_image: xcode9
compiler: "clang"
env: PPSSPP_BUILD_TYPE=macOS
- os: osx
osx_image: xcode8.3
osx_image: xcode9
compiler: "clang"
env: PPSSPP_BUILD_TYPE=iOS
- os: windows
+24 -20
View File
@@ -166,6 +166,10 @@ endif()
include_directories(ext/native)
# Work around for some misfeature of the current glslang build system
include_directories(ext/glslang)
if(NOT OPENGL_LIBRARIES AND USING_GLES2)
set(OPENGL_LIBRARIES GLESv2 EGL)
endif()
@@ -268,6 +272,7 @@ if(NOT MSVC)
# Disable some warnings
add_definitions(-Wno-multichar)
add_definitions(-Wno-deprecated-register)
add_definitions(-Wno-tautological-pointer-compare)
# Don't compile with strict aliasing, we're not 100% aliasing-safe
add_compile_options(-fno-strict-aliasing)
@@ -485,12 +490,6 @@ add_library(gason STATIC
ext/native/ext/gason/gason.h
)
add_library(rg_etc1 STATIC
ext/native/ext/rg_etc1/rg_etc1.cpp
ext/native/ext/rg_etc1/rg_etc1.h
)
include_directories(ext/native/ext/rg_etc1)
if(USE_FFMPEG)
if(NOT FFMPEG_DIR)
if(NOT USE_SYSTEM_FFMPEG)
@@ -661,13 +660,16 @@ else()
set(LIBZIP_LIBRARY libzip)
endif()
# FindPNG does a few things we don't want. So do it ourselves. Fixed to libpng17
find_path(PNG_PNG_INCLUDE_DIR NAMES "libpng17/png.h")
find_library(PNG_LIBRARY NAMES png17 libpng17)
find_package(PackageHandleStandardArgs)
find_package_handle_standard_args(PNG REQUIRED_VARS PNG_LIBRARY PNG_PNG_INCLUDE_DIR)
# Arm platforms require at least libpng17.
if(ANDROID OR ARMV7 OR ARM64 OR ARM OR IOS)
set(PNG_REQUIRED_VERSION 1.7)
else()
set(PNG_REQUIRED_VERSION 1.6)
endif()
find_package(PNG ${PNG_REQUIRED_VERSION})
if(PNG_FOUND)
include_directories(${PNG_PNG_INCLUDE_DIR})
include_directories(${PNG_INCLUDE_DIRS})
else()
if(ARM)
set(PNG_ARM_INCLUDES
@@ -701,8 +703,8 @@ else()
ext/native/ext/libpng17/pngwutil.c
${PNG_ARM_INCLUDES}
)
set(PNG_LIBRARY png17)
include_directories(ext/native/ext)
set(PNG_LIBRARIES png17)
include_directories(ext/native/ext/libpng17)
endif()
set(nativeExtra)
@@ -844,6 +846,7 @@ list(APPEND NativeAppSource
UI/DiscordIntegration.cpp
UI/NativeApp.cpp
UI/BackgroundAudio.cpp
UI/ChatScreen.cpp
UI/DevScreens.cpp
UI/DisplayLayoutEditor.cpp
UI/DisplayLayoutScreen.cpp
@@ -869,7 +872,6 @@ list(APPEND NativeAppSource
UI/CwCheatScreen.cpp
UI/InstallZipScreen.cpp
UI/ProfilerDraw.cpp
UI/ui_atlas.cpp
UI/TextureUtil.cpp
UI/ComboKeyMappingScreen.cpp
)
@@ -1042,6 +1044,8 @@ add_library(native STATIC
ext/native/thread/threadutil.h
ext/native/thread/threadpool.cpp
ext/native/thread/threadpool.h
ext/native/ui/root.cpp
ext/native/ui/root.h
ext/native/ui/screen.cpp
ext/native/ui/screen.h
ext/native/ui/ui.cpp
@@ -1082,7 +1086,7 @@ if(ANDROID)
set(ATOMIC_LIB atomic)
endif()
target_link_libraries(native ${LIBZIP_LIBRARY} ${PNG_LIBRARY} ${ZLIB_LIBRARY} rg_etc1 gason udis86 ${RT_LIB} ${nativeExtraLibs} ${ATOMIC_LIB})
target_link_libraries(native ${LIBZIP_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARY} gason udis86 ${RT_LIB} ${nativeExtraLibs} ${ATOMIC_LIB})
if(TARGET Ext::GLEW)
target_link_libraries(native Ext::GLEW)
endif()
@@ -1760,8 +1764,6 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/Util/BlockAllocator.h
Core/Util/PPGeDraw.cpp
Core/Util/PPGeDraw.h
Core/Util/ppge_atlas.cpp
Core/Util/ppge_atlas.h
${CORE_NEON}
${GPU_SOURCES}
ext/disarm.cpp
@@ -1805,7 +1807,7 @@ if(FFmpeg_FOUND)
endif()
# Discord integration
if(USE_DISCORD AND NOT IOS)
if(USE_DISCORD AND NOT IOS AND NOT LIBRETRO)
add_definitions(-DUSE_DISCORD=1)
target_link_libraries(${CoreLibName} discord-rpc)
endif()
@@ -1933,6 +1935,7 @@ endif()
set(NativeAssets
android/assets/ui_atlas_luna.zim
android/assets/ui_atlas_luna.meta
assets/lang
assets/shaders
assets/scalers
@@ -1941,7 +1944,8 @@ set(NativeAssets
assets/compat.ini
assets/gamecontrollerdb.txt
assets/langregion.ini
assets/ppge_atlas.zim
assets/ppge_atlas_luna.zim
assets/ppge_atlas_luna.meta
assets/rargray.png
assets/unknown.png
assets/zip.png
+13
View File
@@ -117,6 +117,19 @@ void PointerWrap::Do(std::wstring &x) {
(*ptr) += stringLen;
}
void PointerWrap::Do(std::u16string &x) {
int stringLen = sizeof(char16_t) * ((int)x.length() + 1);
Do(stringLen);
switch (mode) {
case MODE_READ: x = (char16_t*)*ptr; break;
case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break;
case MODE_MEASURE: break;
case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (char16_t*)*ptr, "Savestate verification failure: (at %p).\n", x.c_str()); break;
}
(*ptr) += stringLen;
}
struct standard_tm {
int tm_sec;
int tm_min;
+2 -1
View File
@@ -459,7 +459,8 @@ public:
// Store strings.
void Do(std::string &x);
void Do(std::wstring &x);
void Do(std::wstring &x); // DEPRECATED, do not save wstrings
void Do(std::u16string &x);
void Do(tm &t);
+8 -8
View File
@@ -137,7 +137,7 @@
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>stdafx.h;Common/DbgNew.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@@ -164,7 +164,7 @@
<ForcedIncludeFiles>stdafx.h;Common/DbgNew.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<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>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
@@ -192,7 +192,7 @@
<ForcedIncludeFiles>stdafx.h;Common/DbgNew.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
@@ -220,7 +220,7 @@
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
@@ -253,7 +253,7 @@
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
@@ -283,7 +283,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
@@ -318,7 +318,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
@@ -353,7 +353,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;..</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;../ext/snappy;../ext/glslang;..</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
+1
View File
@@ -74,6 +74,7 @@
<ClInclude Include="Hashmaps.h" />
<ClInclude Include="Vulkan\VulkanDebug.h" />
<ClInclude Include="BitScan.h" />
<ClInclude Include="MakeUnique.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
+1 -5
View File
@@ -64,11 +64,7 @@ ConsoleListener::ConsoleListener() : bHidden(true)
logPending = new char[LOG_PENDING_MAX];
}
++refCount;
#elif defined(ANDROID)
bUseColor = false;
#elif defined(IOS)
bUseColor = false;
#elif PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(SWITCH)
#elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(SWITCH)
bUseColor = false;
#elif defined(_MSC_VER)
bUseColor = false;
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2014 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "ppsspp_config.h"
#if PPSSPP_PLATFORM(SWITCH)
#include <switch.h>
#include "Common/Log.h"
#include "Common/GL/GLInterface/EGLSwitch.h"
EGLDisplay cInterfaceEGLSwitch::OpenDisplay() {
return eglGetDisplay(EGL_DEFAULT_DISPLAY);
}
EGLNativeWindowType cInterfaceEGLSwitch::InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) {
return nwindowGetDefault();
}
void cInterfaceEGLSwitch::ShutdownPlatform() {
}
#endif
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2014 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include "Common/GL/GLInterface/EGL.h"
class cInterfaceEGLSwitch : public cInterfaceEGL {
public:
cInterfaceEGLSwitch() {}
protected:
EGLDisplay OpenDisplay() override;
EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) override;
void ShutdownPlatform() override;
void OverrideBackbufferDimensions(int internalWidth, int internalHeight) override {
internalWidth_ = internalWidth;
internalHeight_ = internalHeight;
}
private:
int internalWidth_ = 0;
int internalHeight_ = 0;
};
+5
View File
@@ -2,10 +2,13 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "ppsspp_config.h"
#include "Common/GL/GLInterfaceBase.h"
#ifdef __ANDROID__
#include "Common/GL/GLInterface/EGLAndroid.h"
#elif PPSSPP_PLATFORM(SWITCH)
#include "Common/GL/GLInterface/EGLSwitch.h"
#elif defined(__APPLE__)
#include "Common/GL/GLInterface/AGL.h"
#elif defined(_WIN32)
@@ -23,6 +26,8 @@
cInterfaceBase* HostGL_CreateGLInterface(){
#ifdef __ANDROID__
return new cInterfaceEGLAndroid;
#elif if PPSSPP_PLATFORM(SWITCH)
return new cInterfaceEGLSwitch;
#elif defined(__APPLE__)
return new cInterfaceAGL;
#elif defined(_WIN32)
+5
View File
@@ -343,6 +343,7 @@ void UpdateNativeMenuKeys() {
KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ESCAPE),
KeyDef(DEVICE_ID_ANY, NKCODE_BACK),
KeyDef(DEVICE_ID_ANY, NKCODE_BUTTON_B),
KeyDef(DEVICE_ID_MOUSE, NKCODE_EXT_MOUSEBUTTON_4),
};
for (size_t i = 0; i < ARRAY_SIZE(hardcodedCancelKeys); i++) {
@@ -696,12 +697,16 @@ const KeyMap_IntStrPair psp_button_names[] = {
{VIRTKEY_AXIS_RIGHT_Y_MIN, "RightAn.Down"},
{VIRTKEY_AXIS_RIGHT_X_MIN, "RightAn.Left"},
{VIRTKEY_AXIS_RIGHT_X_MAX, "RightAn.Right"},
{VIRTKEY_OPENCHAT, "OpenChat" },
{VIRTKEY_AXIS_SWAP, "AxisSwap"},
{VIRTKEY_DEVMENU, "DevMenu"},
{VIRTKEY_TEXTURE_DUMP, "Texture Dumping"},
{VIRTKEY_TEXTURE_REPLACE, "Texture Replacement"},
{VIRTKEY_SCREENSHOT, "Screenshot"},
{VIRTKEY_MUTE_TOGGLE, "Mute toggle"},
{VIRTKEY_ANALOG_ROTATE_CW, "Rotate Analog (CW)"},
{VIRTKEY_ANALOG_ROTATE_CCW, "Rotate Analog (CCW)"},
{CTRL_HOME, "Home"},
{CTRL_HOLD, "Hold"},
+4
View File
@@ -57,6 +57,10 @@ enum {
VIRTKEY_TEXTURE_DUMP = 0x40000019,
VIRTKEY_TEXTURE_REPLACE = 0x4000001A,
VIRTKEY_SCREENSHOT = 0x4000001B,
VIRTKEY_MUTE_TOGGLE = 0x4000001C,
VIRTKEY_OPENCHAT = 0x4000001D,
VIRTKEY_ANALOG_ROTATE_CW = 0x4000001E,
VIRTKEY_ANALOG_ROTATE_CCW = 0x4000001F,
VIRTKEY_LAST,
VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST
};
+2 -2
View File
@@ -122,7 +122,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char *
#if MAX_LOGLEVEL >= DEBUG_LEVEL
#define _dbg_assert_(_t_, _a_) \
if (!(_a_)) {\
ERROR_LOG(_t_, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \
ERROR_LOG(_t_, #_a_ "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \
__LINE__, __FILE__); \
if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \
}
@@ -184,4 +184,4 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char *
Crash(); \
}
#endif // __ANDROID__
#endif // __ANDROID__
+6 -6
View File
@@ -50,7 +50,7 @@ static SYSTEM_INFO sys_info;
#endif
#define MEM_PAGE_MASK ((MEM_PAGE_SIZE)-1)
#define round_page(x) ((((uintptr_t)(x)) + MEM_PAGE_MASK) & ~(MEM_PAGE_MASK))
#define ppsspp_round_page(x) ((((uintptr_t)(x)) + MEM_PAGE_MASK) & ~(MEM_PAGE_MASK))
#ifdef _WIN32
// Win32 flags are odd...
@@ -127,7 +127,7 @@ void *AllocateExecutableMemory(size_t size) {
GetSystemInfo(&sys_info);
#if defined(_M_X64)
if ((uintptr_t)&hint_location > 0xFFFFFFFFULL) {
size_t aligned_size = round_page(size);
size_t aligned_size = ppsspp_round_page(size);
#if 1 // Turn off to hunt for RIP bugs on x86-64.
ptr = SearchForFreeMem(aligned_size);
if (!ptr) {
@@ -161,11 +161,11 @@ void *AllocateExecutableMemory(size_t size) {
// We use a dummy global variable to give us a good location to start from.
if (!map_hint) {
if ((uintptr_t) &hint_location > 0xFFFFFFFFULL)
map_hint = (char*)round_page(&hint_location) - 0x20000000; // 0.5gb lower than our approximate location
map_hint = (char*)ppsspp_round_page(&hint_location) - 0x20000000; // 0.5gb lower than our approximate location
else
map_hint = (char*)0x20000000; // 0.5GB mark in memory
} else if ((uintptr_t) map_hint > 0xFFFFFFFFULL) {
map_hint -= round_page(size); /* round down to the next page if we're in high memory */
map_hint -= ppsspp_round_page(size); /* round down to the next page if we're in high memory */
}
#endif
@@ -191,7 +191,7 @@ void *AllocateExecutableMemory(size_t size) {
#if defined(_M_X64) && !defined(_WIN32)
else if ((uintptr_t)map_hint <= 0xFFFFFFFF) {
// Round up if we're below 32-bit mark, probably allocating sequentially.
map_hint += round_page(size);
map_hint += ppsspp_round_page(size);
// If we moved ahead too far, skip backwards and recalculate.
// When we free, we keep moving forward and eventually move too far.
@@ -204,7 +204,7 @@ void *AllocateExecutableMemory(size_t size) {
}
void *AllocateMemoryPages(size_t size, uint32_t memProtFlags) {
size = round_page(size);
size = ppsspp_round_page(size);
#ifdef _WIN32
if (sys_info.dwPageSize == 0)
GetSystemInfo(&sys_info);
+17 -12
View File
@@ -285,6 +285,14 @@ void VulkanContext::EndFrame() {
}
}
void VulkanContext::UpdateInflightFrames(int n) {
assert(n >= 1 && n <= MAX_INFLIGHT_FRAMES);
inflightFrames_ = n;
if (curFrame_ >= inflightFrames_) {
curFrame_ = 0;
}
}
void VulkanContext::WaitUntilQueueIdle() {
// Should almost never be used
vkQueueWaitIdle(gfx_queue_);
@@ -949,20 +957,17 @@ bool VulkanContext::InitSwapchain() {
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
}
for (size_t i = 0; i < presentModeCount; i++) {
if (swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
// Default to the first present mode from the list.
bool match = false;
match = match || ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_FIFO_RELAXED) && presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_FIFO) && presentModes[i] == VK_PRESENT_MODE_FIFO_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_IMMEDIATE) && presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR);
// Default to the first present mode from the list.
if (match || swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
swapchainPresentMode = presentModes[i];
}
if ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if ((flags_ & VULKAN_FLAG_PRESENT_FIFO_RELAXED) && presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
break;
}
if ((flags_ & VULKAN_FLAG_PRESENT_IMMEDIATE) && presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
if (match) {
break;
}
}
+10 -3
View File
@@ -13,6 +13,7 @@ enum {
VULKAN_FLAG_PRESENT_MAILBOX = 2,
VULKAN_FLAG_PRESENT_IMMEDIATE = 4,
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
VULKAN_FLAG_PRESENT_FIFO = 16,
};
enum {
@@ -136,6 +137,7 @@ public:
VkDevice GetDevice() const { return device_; }
VkInstance GetInstance() const { return instance_; }
uint32_t GetFlags() const { return flags_; }
void UpdateFlags(uint32_t flags) { flags_ = flags; }
VulkanDeleteList &Delete() { return globalDeleteList_; }
@@ -174,10 +176,13 @@ public:
VkResult InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata);
void DestroyDebugMsgCallback();
VkPhysicalDevice GetPhysicalDevice(int n = 0) const {
VkPhysicalDevice GetPhysicalDevice(int n) const {
return physical_devices_[n];
}
int GetCurrentPhysicalDevice() const {
VkPhysicalDevice GetCurrentPhysicalDevice() const {
return physical_devices_[physical_device_];
}
int GetCurrentPhysicalDeviceIndex() const {
return physical_device_;
}
int GetNumPhysicalDevices() const {
@@ -200,7 +205,7 @@ public:
const PhysicalDeviceProps &GetPhysicalDeviceProperties(int i = -1) const {
if (i < 0)
i = GetCurrentPhysicalDevice();
i = GetCurrentPhysicalDeviceIndex();
return physicalDeviceProperties_[i];
}
@@ -249,6 +254,8 @@ public:
int GetInflightFrames() const {
return inflightFrames_;
}
// Don't call while a frame is in progress.
void UpdateInflightFrames(int n);
int GetCurFrame() const {
return curFrame_;
+1
View File
@@ -236,6 +236,7 @@ bool g_vulkanMayBeAvailable = false;
static const char *device_name_blacklist[] = {
"NVIDIA:SHIELD Tablet K1",
"SDL:Horizon",
};
static const char *so_names[] = {
+38 -4
View File
@@ -441,6 +441,7 @@ static ConfigSetting generalSettings[] = {
ConfigSetting("AutoLoadSaveState", &g_Config.iAutoLoadSaveState, 0, true, true),
ReportedConfigSetting("EnableCheats", &g_Config.bEnableCheats, true, true, true),
ConfigSetting("CwCheatRefreshRate", &g_Config.iCwCheatRefreshRate, 77, true, true),
ConfigSetting("CwCheatScrollPosition", &g_Config.fCwCheatScrollPosition, 0.0f, true, true),
ConfigSetting("ScreenshotsAsPNG", &g_Config.bScreenshotsAsPNG, false, true, true),
ConfigSetting("ScreenshotsAtRenderRes", &g_Config.bScreenshotsAtRenderRes, false, true, true),
@@ -454,6 +455,9 @@ static ConfigSetting generalSettings[] = {
ConfigSetting("EnableStateUndo", &g_Config.bEnableStateUndo, false/*&DefaultEnableStateUndo*/, true, true),
ConfigSetting("RewindFlipFrequency", &g_Config.iRewindFlipFrequency, 0, true, true),
ConfigSetting("ShowRegionOnGameIcon", &g_Config.bShowRegionOnGameIcon, false, true, true),
ConfigSetting("ShowIDOnGameIcon", &g_Config.bShowIDOnGameIcon, false, true, true),
ConfigSetting("GameGridScale", &g_Config.fGameGridScale, 1.0, true, true),
ConfigSetting("GridView1", &g_Config.bGridView1, true),
ConfigSetting("GridView2", &g_Config.bGridView2, true),
ConfigSetting("GridView3", &g_Config.bGridView3, false),
@@ -786,6 +790,9 @@ static ConfigSetting graphicsSettings[] = {
ConfigSetting("GfxDebugSplitSubmit", &g_Config.bGfxDebugSplitSubmit, false, false, false),
ConfigSetting("LogFrameDrops", &g_Config.bLogFrameDrops, false, true, false),
ConfigSetting("InflightFrames", &g_Config.iInflightFrames, 3, true, false),
ConfigSetting("RenderDuplicateFrames", &g_Config.bRenderDuplicateFrames, false, true, true),
ConfigSetting(false),
};
@@ -840,6 +847,12 @@ static ConfigSetting controlSettings[] = {
ConfigSetting("ComboKey3Mapping", &g_Config.iCombokey3, 0, true, true),
ConfigSetting("ComboKey4Mapping", &g_Config.iCombokey4, 0, true, true),
ConfigSetting("ComboKey0Toggle", &g_Config.bComboToggle0, false, true, true),
ConfigSetting("ComboKey1Toggle", &g_Config.bComboToggle1, false, true, true),
ConfigSetting("ComboKey2Toggle", &g_Config.bComboToggle2, false, true, true),
ConfigSetting("ComboKey3Toggle", &g_Config.bComboToggle3, false, true, true),
ConfigSetting("ComboKey4Toggle", &g_Config.bComboToggle4, false, true, true),
#if defined(_WIN32)
// A win32 user seeing touch controls is likely using PPSSPP on a tablet. There it makes
// sense to default this to on.
@@ -861,6 +874,7 @@ static ConfigSetting controlSettings[] = {
ConfigSetting("TiltSensitivityX", &g_Config.iTiltSensitivityX, 100, true, true),
ConfigSetting("TiltSensitivityY", &g_Config.iTiltSensitivityY, 100, true, true),
ConfigSetting("DeadzoneRadius", &g_Config.fDeadzoneRadius, 0.2f, true, true),
ConfigSetting("TiltDeadzoneSkip", &g_Config.fTiltDeadzoneSkip, 0.0f, true, true),
ConfigSetting("TiltInputType", &g_Config.iTiltInputType, 0, true, true),
#endif
@@ -870,6 +884,7 @@ static ConfigSetting controlSettings[] = {
ConfigSetting("TouchButtonOpacity", &g_Config.iTouchButtonOpacity, 65, true, true),
ConfigSetting("TouchButtonHideSeconds", &g_Config.iTouchButtonHideSeconds, 20, true, true),
ConfigSetting("AutoCenterTouchAnalog", &g_Config.bAutoCenterTouchAnalog, false, true, true),
ConfigSetting("AnalogAutoRotSpeed", &g_Config.fAnalogAutoRotSpeed, 15.0f, true, true),
// Snap touch control position
ConfigSetting("TouchSnapToGrid", &g_Config.bTouchSnapToGrid, false, true, true),
@@ -898,6 +913,8 @@ static ConfigSetting controlSettings[] = {
ConfigSetting("Speed1KeyX", "Speed1KeyY", "Speed1KeyScale", "ShowSpeed1Key", &g_Config.touchSpeed1Key, defaultTouchPosHide, true, true),
ConfigSetting("Speed2KeyX", "Speed2KeyY", "Speed2KeyScale", "ShowSpeed2Key", &g_Config.touchSpeed2Key, defaultTouchPosHide, true, true),
ConfigSetting("RapidFireKeyX", "RapidFireKeyY", "RapidFireKeyScale", "ShowRapidFireKey", &g_Config.touchRapidFireKey, defaultTouchPosHide, true, true),
ConfigSetting("AnalogRotationCWKeyX", "AnalogRotationKeyCWY", "AnalogRotationKeyCWScale", "ShowAnalogRotationCWKey", &g_Config.touchAnalogRotationCWKey, defaultTouchPosHide, true, true),
ConfigSetting("AnalogRotationCCWKeyX", "AnalogRotationKeyCCWY", "AnalogRotationKeyCCWScale", "ShowAnalogRotationCCWKey", &g_Config.touchAnalogRotationCCWKey, defaultTouchPosHide, true, true),
#ifdef _WIN32
ConfigSetting("DInputAnalogDeadzone", &g_Config.fDInputAnalogDeadzone, 0.1f, true, true),
@@ -927,7 +944,15 @@ static ConfigSetting controlSettings[] = {
static ConfigSetting networkSettings[] = {
ConfigSetting("EnableWlan", &g_Config.bEnableWlan, false, true, true),
ConfigSetting("EnableAdhocServer", &g_Config.bEnableAdhocServer, false, true, true),
ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, true, true),
ConfigSetting("ChatButtonPosition",&g_Config.iChatButtonPosition,BOTTOM_LEFT,true,true),
ConfigSetting("ChatScreenPosition",&g_Config.iChatScreenPosition,BOTTOM_LEFT,true,true),
ConfigSetting("EnableQuickChat", &g_Config.bEnableQuickChat, true, true, true),
ConfigSetting("QuickChat1", &g_Config.sQuickChat0, "Quick Chat 1", true, true),
ConfigSetting("QuickChat2", &g_Config.sQuickChat1, "Quick Chat 2", true, true),
ConfigSetting("QuickChat3", &g_Config.sQuickChat2, "Quick Chat 3", true, true),
ConfigSetting("QuickChat4", &g_Config.sQuickChat3, "Quick Chat 4", true, true),
ConfigSetting("QuickChat5", &g_Config.sQuickChat4, "Quick Chat 5", true, true),
ConfigSetting(false),
};
@@ -968,7 +993,7 @@ static ConfigSetting systemParamSettings[] = {
ReportedConfigSetting("ButtonPreference", &g_Config.iButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS, true, true),
ConfigSetting("LockParentalLevel", &g_Config.iLockParentalLevel, 0, true, true),
ConfigSetting("WlanAdhocChannel", &g_Config.iWlanAdhocChannel, PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC, true, true),
#if defined(USING_WIN_UI)
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
ConfigSetting("BypassOSKWithKeyboard", &g_Config.bBypassOSKWithKeyboard, false, true, true),
ConfigSetting("DisableWinMenu", &g_Config.bDisableWinMenu, false, true, true),
ConfigSetting("DisableWinBorders", &g_Config.bDisableWinBorders, false, true, true),
@@ -1116,6 +1141,12 @@ std::map<std::string, std::pair<std::string, int>> GetLangValuesMapping() {
return langValuesMapping;
}
void Config::Reload() {
reload_ = true;
Load();
reload_ = false;
}
void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
const bool useIniFilename = iniFileName != nullptr && strlen(iniFileName) > 0;
iniFilename_ = FindConfigFile(useIniFilename ? iniFileName : "ppsspp.ini");
@@ -1492,7 +1523,8 @@ bool Config::hasGameConfig(const std::string &pGameId) {
}
void Config::changeGameSpecific(const std::string &pGameId, const std::string &title) {
Save("changeGameSpecific");
if (!reload_)
Save("changeGameSpecific");
gameId_ = pGameId;
gameIdTitle_ = title;
bGameSpecific = !pGameId.empty();
@@ -1571,7 +1603,7 @@ bool Config::loadGameConfig(const std::string &pGameId, const std::string &title
}
void Config::unloadGameConfig() {
if (bGameSpecific){
if (bGameSpecific) {
changeGameSpecific();
IniFile iniFile;
@@ -1624,6 +1656,8 @@ void Config::ResetControlLayout() {
reset(g_Config.touchSpeed1Key);
reset(g_Config.touchSpeed2Key);
reset(g_Config.touchRapidFireKey);
reset(g_Config.touchAnalogRotationCWKey);
reset(g_Config.touchAnalogRotationCCWKey);
}
void Config::GetReportingInfo(UrlEncoder &data) {
+42 -1
View File
@@ -28,6 +28,17 @@
extern const char *PPSSPP_GIT_VERSION;
const int MAX_CONFIG_VOLUME = 8;
enum ChatPositions {
BOTTOM_LEFT = 0,
BOTTOM_CENTER = 1,
BOTOM_RIGHT = 2,
TOP_LEFT = 3,
TOP_CENTER = 4,
TOP_RIGHT = 5,
CENTER_LEFT = 6,
CENTER_RIGHT = 7,
};
namespace http {
class Download;
class Downloader;
@@ -196,6 +207,7 @@ public:
bool bEnableCheats;
bool bReloadCheats;
int iCwCheatRefreshRate;
float fCwCheatScrollPosition;
int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive
bool bBlockTransferGPU;
bool bDisableSlowFramebufEffects;
@@ -205,6 +217,8 @@ public:
std::string sPostShaderName; // Off for off.
bool bGfxDebugOutput;
bool bGfxDebugSplitSubmit;
int iInflightFrames;
bool bRenderDuplicateFrames;
// Sound
bool bEnableSound;
@@ -219,6 +233,9 @@ public:
// UI
bool bShowDebuggerOnLoad;
int iShowFPSCounter;
bool bShowRegionOnGameIcon;
bool bShowIDOnGameIcon;
float fGameGridScale;
// TODO: Maybe move to a separate theme system.
uint32_t uItemStyleFg;
@@ -268,6 +285,8 @@ public:
int iTiltSensitivityY;
//the deadzone radius of the tilt
float fDeadzoneRadius;
// deadzone skip
float fTiltDeadzoneSkip;
//type of tilt input currently selected: Defined in TiltEventProcessor.h
//0 - no tilt, 1 - analog stick, 2 - D-Pad, 3 - Action Buttons (Tri, Cross, Square, Circle)
int iTiltInputType;
@@ -286,6 +305,8 @@ public:
int iTouchButtonStyle;
int iTouchButtonOpacity;
int iTouchButtonHideSeconds;
// Auto rotation speed
float fAnalogAutoRotSpeed;
// Snap touch control position
bool bTouchSnapToGrid;
@@ -319,6 +340,8 @@ public:
ConfigTouchPos touchSpeed1Key;
ConfigTouchPos touchSpeed2Key;
ConfigTouchPos touchRapidFireKey;
ConfigTouchPos touchAnalogRotationCWKey;
ConfigTouchPos touchAnalogRotationCCWKey;
// Controls Visibility
bool bShowTouchControls;
@@ -335,6 +358,12 @@ public:
int iCombokey3;
int iCombokey4;
bool bComboToggle0;
bool bComboToggle1;
bool bComboToggle2;
bool bComboToggle3;
bool bComboToggle4;
// Ignored on iOS and other platforms that lack pause.
bool bShowTouchPause;
@@ -388,10 +417,20 @@ public:
bool bEnableAdhocServer;
int iWlanAdhocChannel;
bool bWlanPowerSave;
bool bEnableNetworkChat;
//for chat position , moveable buttons is better than this
int iChatButtonPosition;
int iChatScreenPosition;
bool bEnableQuickChat;
std::string sQuickChat0;
std::string sQuickChat1;
std::string sQuickChat2;
std::string sQuickChat3;
std::string sQuickChat4;
int iPSPModel;
int iFirmwareVersion;
// TODO: Make this work with your platform, too!
bool bBypassOSKWithKeyboard;
#if defined(USING_WIN_UI)
bool bDisableWinMenu;
@@ -438,6 +477,7 @@ public:
void Load(const char *iniFileName = nullptr, const char *controllerIniFilename = nullptr);
void Save(const char *saveReason);
void Reload();
void RestoreDefaults();
//per game config managment, should maybe be in it's own class
@@ -476,6 +516,7 @@ protected:
void LoadStandardControllerIni();
private:
bool reload_ = false;
std::string gameId_;
std::string gameIdTitle_;
std::string iniFilename_;
+8 -11
View File
@@ -71,7 +71,6 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Windows\fix_2017.props" />
</ImportGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -134,7 +133,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../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>Precise</FloatingPointModel>
@@ -156,7 +155,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../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>Precise</FloatingPointModel>
@@ -179,7 +178,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
@@ -202,7 +201,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
@@ -229,7 +228,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
@@ -260,7 +259,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
@@ -290,7 +289,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
@@ -320,7 +319,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
@@ -834,7 +833,6 @@
<ClCompile Include="Util\DisArm64.cpp" />
<ClCompile Include="Util\GameManager.cpp" />
<ClCompile Include="Util\PPGeDraw.cpp" />
<ClCompile Include="Util\ppge_atlas.cpp" />
<ClCompile Include="..\ext\xxhash.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IntrinsicFunctions>
@@ -1166,7 +1164,6 @@
<ClInclude Include="Util\DisArm64.h" />
<ClInclude Include="Util\GameManager.h" />
<ClInclude Include="Util\PPGeDraw.h" />
<ClInclude Include="Util\ppge_atlas.h" />
<ClInclude Include="..\ext\xxhash.h" />
<ClInclude Include="WaveFile.h" />
<ClInclude Include="WebServer.h" />
-6
View File
@@ -336,9 +336,6 @@
<ClCompile Include="Util\PPGeDraw.cpp">
<Filter>Util</Filter>
</ClCompile>
<ClCompile Include="Util\ppge_atlas.cpp">
<Filter>Util</Filter>
</ClCompile>
<ClCompile Include="HLE\sceFont.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
@@ -1000,9 +997,6 @@
<ClInclude Include="Util\PPGeDraw.h">
<Filter>Util</Filter>
</ClInclude>
<ClInclude Include="Util\ppge_atlas.h">
<Filter>Util</Filter>
</ClInclude>
<ClInclude Include="HLE\sceFont.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
@@ -17,7 +17,7 @@
#include <algorithm>
#ifndef USING_QT_UI
#include <libpng17/png.h>
#include <png.h>
#include <zlib.h>
#endif
#include "data/base64.h"
+5
View File
@@ -144,8 +144,13 @@ void PSPDialog::DoState(PointerWrap &p)
p.Do(isFading);
p.Do(fadeIn);
p.Do(fadeValue);
// I don't think we should save these two... Let's just ignore them for now for compat.
int okButtonImg = 0;
p.Do(okButtonImg);
int cancelButtonImg = 0;
p.Do(cancelButtonImg);
p.Do(okButtonFlag);
p.Do(cancelButtonFlag);
+4 -2
View File
@@ -17,6 +17,8 @@
#pragma once
#include "gfx/texture_atlas.h"
#include "Common/Common.h"
#include "Common/CommonTypes.h"
#include "Common/Swap.h"
@@ -112,8 +114,8 @@ protected:
bool fadeIn;
u32 fadeValue;
int okButtonImg;
int cancelButtonImg;
ImageID okButtonImg;
ImageID cancelButtonImg;
int okButtonFlag;
int cancelButtonFlag;
};
+1 -1
View File
@@ -211,7 +211,7 @@ void PSPGamedataInstallDialog::WriteSfoFile() {
size_t sfoSize;
sfoFile.WriteSFO(&sfoData,&sfoSize);
u32 handle = pspFileSystem.OpenFile(sfopath, (FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE | FILEACCESS_TRUNCATE));
int handle = pspFileSystem.OpenFile(sfopath, (FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE | FILEACCESS_TRUNCATE));
if (handle >= 0) {
pspFileSystem.WriteFile(handle, sfoData, sfoSize);
pspFileSystem.CloseFile(handle);
+2 -2
View File
@@ -62,7 +62,7 @@ private:
u64 allReadSize; // use this to calculate progress value.
int progressValue;
u32 currentInputFile;
int currentInputFile;
u32 currentInputBytesLeft;
u32 currentOutputFile;
int currentOutputFile;
};
+9 -10
View File
@@ -45,7 +45,7 @@ int PSPMsgDialog::Init(unsigned int paramAddr) {
// Ignore if already running
if (GetStatus() != SCE_UTILITY_STATUS_NONE) {
ERROR_LOG_REPORT(SCEUTILITY, "sceUtilityMsgDialogInitStart: invalid status");
return 0;
return SCE_ERROR_UTILITY_INVALID_STATUS;
}
messageDialogAddr = paramAddr;
@@ -148,10 +148,9 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK)
WRAP_WIDTH = 372.0f;
float y = 140.0f;
float h, sy ,ey;
int n;
PPGeMeasureText(0, &h, &n, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
float h2 = h * n / 2.0f;
float h, sy, ey;
PPGeMeasureText(nullptr, &h, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
float h2 = h / 2.0f;
ey = y + h2 + 20.0f;
if (hasYesNo)
@@ -172,7 +171,7 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK)
yesColor = 0xFFFFFFFF;
noColor = 0xFFFFFFFF;
}
PPGeMeasureText(&w, &h, 0, choiceText, FONT_SCALE);
PPGeMeasureText(&w, &h, choiceText, FONT_SCALE);
w = 15.0f;
h = 8.0f;
float y2 = y + h2 + 8.0f;
@@ -225,14 +224,14 @@ int PSPMsgDialog::Update(int animSpeed) {
UpdateButtons();
UpdateFade(animSpeed);
okButtonImg = I_CIRCLE;
cancelButtonImg = I_CROSS;
okButtonImg = ImageID("I_CIRCLE");
cancelButtonImg = ImageID("I_CROSS");
okButtonFlag = CTRL_CIRCLE;
cancelButtonFlag = CTRL_CROSS;
if (messageDialog.common.buttonSwap == 1)
{
okButtonImg = I_CROSS;
cancelButtonImg = I_CIRCLE;
okButtonImg = ImageID("I_CROSS");
cancelButtonImg = ImageID("I_CIRCLE");
okButtonFlag = CTRL_CROSS;
cancelButtonFlag = CTRL_CIRCLE;
}
+25 -15
View File
@@ -28,9 +28,14 @@
#define NETCONF_CONNECT_APNET 0
#define NETCONF_STATUS_APNET 1
#define NETCONF_CONNECT_ADHOC 2
#define NETCONF_CONNECT_APNET_LAST 3
#define NETCONF_CREATE_ADHOC 4
#define NETCONF_JOIN_ADHOC 5
// Needs testing.
const static int NET_INIT_DELAY_US = 300000;
const static int NET_SHUTDOWN_DELAY_US = 26000;
PSPNetconfDialog::PSPNetconfDialog() {
}
@@ -39,7 +44,7 @@ PSPNetconfDialog::~PSPNetconfDialog() {
int PSPNetconfDialog::Init(u32 paramAddr) {
// Already running
if (status != SCE_UTILITY_STATUS_NONE && status != SCE_UTILITY_STATUS_SHUTDOWN)
if (status != SCE_UTILITY_STATUS_NONE)
return SCE_ERROR_UTILITY_INVALID_STATUS;
int size = Memory::Read_U32(paramAddr);
@@ -47,7 +52,7 @@ int PSPNetconfDialog::Init(u32 paramAddr) {
// Only copy the right size to support different request format
Memory::Memcpy(&request, paramAddr, size);
status = SCE_UTILITY_STATUS_INITIALIZE;
ChangeStatusInit(NET_INIT_DELAY_US);
// Eat any keys pressed before the dialog inited.
UpdateButtons();
@@ -67,16 +72,18 @@ void PSPNetconfDialog::DrawBanner() {
}
int PSPNetconfDialog::Update(int animSpeed) {
if (GetStatus() != SCE_UTILITY_STATUS_RUNNING) {
return SCE_ERROR_UTILITY_INVALID_STATUS;
}
UpdateButtons();
auto di = GetI18NCategory("Dialog");
auto err = GetI18NCategory("Error");
const float WRAP_WIDTH = 254.0f;
const int confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? I_CROSS : I_CIRCLE;
const ImageID confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? ImageID("I_CROSS") : ImageID("I_CIRCLE");
const int confirmBtn = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? CTRL_CROSS : CTRL_CIRCLE;
if (status == SCE_UTILITY_STATUS_INITIALIZE) {
status = SCE_UTILITY_STATUS_RUNNING;
} else if (status == SCE_UTILITY_STATUS_RUNNING && (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET)) {
if (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET || request.netAction == NETCONF_CONNECT_APNET_LAST) {
UpdateFade(animSpeed);
StartDraw();
DrawBanner();
@@ -87,26 +94,24 @@ int PSPNetconfDialog::Update(int animSpeed) {
if (IsButtonPressed(confirmBtn)) {
StartFade(false);
status = SCE_UTILITY_STATUS_FINISHED;
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
// TODO: When the dialog is aborted, does it really set the result to this?
// It seems to make Phantasy Star Portable 2 happy, so it should be okay for now.
request.common.result = SCE_UTILITY_DIALOG_RESULT_ABORT;
}
} else if (status == SCE_UTILITY_STATUS_RUNNING && (request.netAction == NETCONF_CONNECT_ADHOC || request.netAction == NETCONF_CREATE_ADHOC || request.netAction == NETCONF_JOIN_ADHOC)) {
if (request.NetconfData != NULL) {
EndDraw();
} else if (request.netAction == NETCONF_CONNECT_ADHOC || request.netAction == NETCONF_CREATE_ADHOC || request.netAction == NETCONF_JOIN_ADHOC) {
if (request.NetconfData.IsValid()) {
Shutdown(true);
if (sceNetAdhocctlCreate(request.NetconfData->groupName) == 0) {
status = SCE_UTILITY_STATUS_FINISHED;
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
return 0;
}
return -1;
}
} else if (status == SCE_UTILITY_STATUS_FINISHED) {
status = SCE_UTILITY_STATUS_SHUTDOWN;
}
EndDraw();
return 0;
}
@@ -114,7 +119,12 @@ int PSPNetconfDialog::Shutdown(bool force) {
if (status != SCE_UTILITY_STATUS_FINISHED && !force)
return SCE_ERROR_UTILITY_INVALID_STATUS;
return PSPDialog::Shutdown(force);
PSPDialog::Shutdown(force);
if (!force) {
ChangeStatusShutdown(NET_SHUTDOWN_DELAY_US);
}
return 0;
}
void PSPNetconfDialog::DoState(PointerWrap &p) {
+5
View File
@@ -44,6 +44,11 @@ public:
virtual int Shutdown(bool force = false) override;
virtual void DoState(PointerWrap &p) override;
protected:
bool UseAutoStatus() override {
return false;
}
private:
void DrawBanner();
SceUtilityNetconfParam request;
+118 -84
View File
@@ -15,9 +15,11 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include "base/NativeApp.h"
#include "i18n/i18n.h"
#include "math/math_util.h"
#include <algorithm>
#include "util/text/utf8.h"
#include "Core/Dialog/PSPOskDialog.h"
#include "Core/Util/PPGeDraw.h"
@@ -29,10 +31,6 @@
#include "Common/ChunkFile.h"
#include "GPU/GPUState.h"
#if defined(USING_WIN_UI)
#include "base/NativeApp.h"
#endif
#ifndef _WIN32
#include <ctype.h>
#include <math.h>
@@ -73,73 +71,73 @@ const int kor_lconsCom[] = {18,0,2,21,3,4,26,3,5,0,7,8,15,7,9,16,7,10,18,7,11,24
// Korean (Hangul) last consonant Separation key
const int kor_lconsSpr[] = {2,1,9,4,4,12,5,4,18,8,8,0,9,8,6,10,8,7,11,8,9,12,8,16,13,8,17,14,8,18,17,17,9};
static const wchar_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
static const char16_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
{
{
// Latin Lowercase
{L"1234567890-+"},
{L"qwertyuiop[]"},
{L"asdfghjkl;@~"},
{L"zxcvbnm,./?\\"},
{u"1234567890-+"},
{u"qwertyuiop[]"},
{u"asdfghjkl;@~"},
{u"zxcvbnm,./?\\"},
},
{
// Latin Uppercase
{L"!@#$%^&*()_+"},
{L"QWERTYUIOP{}"},
{L"ASDFGHJKL:\"`"},
{L"ZXCVBNM<>/?|"},
{u"!@#$%^&*()_+"},
{u"QWERTYUIOP{}"},
{u"ASDFGHJKL:\"`"},
{u"ZXCVBNM<>/?|"},
},
{
// Hiragana
{L"あかさたなはまやらわぁゃっ"},
{L"いきしちにひみ り ぃ  "},
{L"うくすつぬふむゆるをぅゅ゛"},
{L"えけせてねへめ れ ぇ ゜"},
{L"おこそとのほもよろんぉょー"},
{u"あかさたなはまやらわぁゃっ"},
{u"いきしちにひみ り ぃ  "},
{u"うくすつぬふむゆるをぅゅ゛"},
{u"えけせてねへめ れ ぇ ゜"},
{u"おこそとのほもよろんぉょー"},
},
{
// Katakana
{L"アカサタナハマヤラワァャッ"},
{L"イキシチニヒミ リ ィ  "},
{L"ウクスツヌフムユルヲゥュ゛"},
{L"エケセテネヘメ レ ェ ゜"},
{L"オコソトノホモヨロンォョー"},
{u"アカサタナハマヤラワァャッ"},
{u"イキシチニヒミ リ ィ  "},
{u"ウクスツヌフムユルヲゥュ゛"},
{u"エケセテネヘメ レ ェ ゜"},
{u"オコソトノホモヨロンォョー"},
},
{
// Korean(Hangul)
{L"1234567890-+"},
{L"ㅃㅉㄸㄲㅆ!@#$%^&"},
{L"ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ[]"},
{L"ㅁㄴㅇㄹㅎㅗㅓㅏㅣ;@~"},
{L"ㅋㅌㅊㅍㅠㅜㅡ<>/?|"},
{u"1234567890-+"},
{u"ㅃㅉㄸㄲㅆ!@#$%^&"},
{u"ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ[]"},
{u"ㅁㄴㅇㄹㅎㅗㅓㅏㅣ;@~"},
{u"ㅋㅌㅊㅍㅠㅜㅡ<>/?|"},
},
{
// Russian Lowercase
{L"1234567890-+"},
{L"йцукенгшщзхъ"},
{L"фывапролджэё"},
{L"ячсмитьбю/?|"},
{u"1234567890-+"},
{u"йцукенгшщзхъ"},
{u"фывапролджэё"},
{u"ячсмитьбю/?|"},
},
{
// Russian Uppercase
{L"!@#$%^&*()_+"},
{L"ЙЦУКЕНГШЩЗХЪ"},
{L"ФЫВАПРОЛДЖЭЁ"},
{L"ЯЧСМИТЬБЮ/?|"},
{u"!@#$%^&*()_+"},
{u"ЙЦУКЕНГШЩЗХЪ"},
{u"ФЫВАПРОЛДЖЭЁ"},
{u"ЯЧСМИТЬБЮ/?|"},
},
{
// Latin Full-width Lowercase
{ L"1234567890-+" },
{ L"qwertyuiop[]" },
{ L"asdfghjkl;@~" },
{ L"zxcvbnm,./?¥¥" },
{ u"1234567890-+" },
{ u"qwertyuiop[]" },
{ u"asdfghjkl;@~" },
{ u"zxcvbnm,./?¥¥" },
},
{
// Latin Full-width Uppercase
{ L"!@#$%^&*()_+" },
{ L"QWERTYUIOP{}" },
{ L"ASDFGHJKL:¥”‘" },
{ L"ZXCVBNM<>/?|" },
{ u"!@#$%^&*()_+" },
{ u"QWERTYUIOP{}" },
{ u"ASDFGHJKL:¥”‘" },
{ u"ZXCVBNM<>/?|" },
},
};
@@ -169,7 +167,7 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_
{
if (!em_address.IsValid())
{
_string = "";
_string.clear();
return;
}
@@ -196,17 +194,17 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_
_string = stringBuffer;
}
void GetWideStringFromPSPPointer(std::wstring& _string, const PSPPointer<u16_le>& em_address)
void GetWideStringFromPSPPointer(std::u16string& _string, const PSPPointer<u16_le>& em_address)
{
if (!em_address.IsValid())
{
_string = L"";
_string.clear();
return;
}
const size_t maxLength = 2047;
wchar_t stringBuffer[maxLength + 1];
wchar_t *string = stringBuffer;
char16_t stringBuffer[maxLength + 1];
char16_t *string = stringBuffer;
u16_le *input = &em_address[0];
int c;
@@ -216,7 +214,7 @@ void GetWideStringFromPSPPointer(std::wstring& _string, const PSPPointer<u16_le>
_string = stringBuffer;
}
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input)
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const char16_t *input)
{
char stringBuffer[2048];
char *string = stringBuffer;
@@ -317,7 +315,7 @@ int PSPOskDialog::Init(u32 oskPtr) {
i_level = 0;
inputChars = L"";
inputChars.clear();
if (oskParams->fields[0].intext.IsValid()) {
auto src = oskParams->fields[0].intext;
@@ -331,13 +329,16 @@ int PSPOskDialog::Init(u32 oskPtr) {
// Eat any keys pressed before the dialog inited.
UpdateButtons();
std::lock_guard<std::mutex> guard(nativeMutex_);
nativeStatus_ = PSPOskNativeStatus::IDLE;
StartFade(true);
return 0;
}
std::wstring PSPOskDialog::CombinationKorean(bool isInput)
std::u16string PSPOskDialog::CombinationKorean(bool isInput)
{
std::wstring string;
std::u16string string;
isCombinated = true;
@@ -577,9 +578,9 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
return string;
}
std::wstring PSPOskDialog::CombinationString(bool isInput)
std::u16string PSPOskDialog::CombinationString(bool isInput)
{
std::wstring string;
std::u16string string;
isCombinated = false;
@@ -658,7 +659,7 @@ std::wstring PSPOskDialog::CombinationString(bool isInput)
string += inputChars[i];
}
if (string.size() <= FieldMaxLength())
if (string.size() < FieldMaxLength())
{
string += oskKeys[currentKeyboard][selectedRow][selectedCol];
}
@@ -751,7 +752,7 @@ void PSPOskDialog::RenderKeyboard()
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
int selectedCol = selectedChar % numKeyCols[currentKeyboard];
wchar_t temp[2];
char16_t temp[2];
temp[1] = '\0';
std::string buffer;
@@ -768,7 +769,7 @@ void PSPOskDialog::RenderKeyboard()
PPGeDrawText(oskDesc.c_str(), title , 20, PPGE_ALIGN_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF));
std::wstring result;
std::u16string result;
result = CombinationString(false);
@@ -836,7 +837,6 @@ void PSPOskDialog::RenderKeyboard()
}
}
#if defined(USING_WIN_UI)
// TODO: Why does this have a 2 button press lag/delay when
// re-opening the dialog box? I don't get it.
int PSPOskDialog::NativeKeyboard() {
@@ -844,23 +844,52 @@ int PSPOskDialog::NativeKeyboard() {
return SCE_ERROR_UTILITY_INVALID_STATUS;
}
std::wstring titleText;
GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc);
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
bool beginInputBox = false;
if (nativeStatus_ == PSPOskNativeStatus::IDLE) {
std::lock_guard<std::mutex> guard(nativeMutex_);
if (nativeStatus_ == PSPOskNativeStatus::IDLE) {
nativeStatus_ = PSPOskNativeStatus::WAITING;
beginInputBox = true;
}
}
std::wstring defaultText;
GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext);
if (beginInputBox) {
std::u16string titleText;
GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc);
if (defaultText.empty())
defaultText.assign(L"VALUE");
std::u16string defaultText;
GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext);
if (defaultText.empty())
defaultText.assign(u"VALUE");
// There's already ConvertUCS2ToUTF8 in this file. Should we use that instead of the global ones?
System_InputBoxGetString(::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), [&](bool result, const std::string &value) {
std::lock_guard<std::mutex> guard(nativeMutex_);
if (nativeStatus_ != PSPOskNativeStatus::WAITING) {
return;
}
nativeValue_ = value;
nativeStatus_ = result ? PSPOskNativeStatus::SUCCESS : PSPOskNativeStatus::FAILURE;
});
} else if (nativeStatus_ == PSPOskNativeStatus::SUCCESS) {
inputChars = ConvertUTF8ToUCS2(nativeValue_);
nativeValue_.clear();
if (System_InputBoxGetWString(titleText.c_str(), defaultText, inputChars)) {
u32 maxLength = FieldMaxLength();
if (inputChars.length() > maxLength) {
ERROR_LOG(SCEUTILITY, "NativeKeyboard: input text too long(%d characters/glyphs max), truncating to game-requested length.", maxLength);
inputChars.erase(maxLength, std::string::npos);
}
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
nativeStatus_ = PSPOskNativeStatus::DONE;
} else if (nativeStatus_ == PSPOskNativeStatus::FAILURE) {
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
nativeStatus_ = PSPOskNativeStatus::DONE;
}
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
#endif
u16_le *outText = oskParams->fields[0].outtext;
@@ -870,7 +899,7 @@ int PSPOskDialog::NativeKeyboard() {
// Only write the bytes of the output and the null terminator, don't write the rest.
for (size_t i = 0; i < end; ++i) {
u16 value = 0;
if (i < FieldMaxLength())
if (i < FieldMaxLength() && i < inputChars.size())
value = inputChars[i];
outText[i] = value;
}
@@ -880,7 +909,6 @@ int PSPOskDialog::NativeKeyboard() {
return 0;
}
#endif
int PSPOskDialog::Update(int animSpeed) {
if (GetStatus() != SCE_UTILITY_STATUS_RUNNING) {
@@ -902,12 +930,10 @@ int PSPOskDialog::Update(int animSpeed) {
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
int selectedExtra = selectedChar % numKeyCols[currentKeyboard];
// TODO: Add your platforms here when you have a NativeKeyboard func.
#if defined(USING_WIN_UI)
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
// Windows: Fall back to the OSK/continue normally if we're in fullscreen.
// The dialog box doesn't work right if in fullscreen.
if(g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen)
if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen)
return NativeKeyboard();
#endif
@@ -919,15 +945,15 @@ int PSPOskDialog::Update(int animSpeed) {
auto di = GetI18NCategory("Dialog");
PPGeDrawImage(I_SQUARE, 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Space"), 390, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
if (g_Config.iButtonPreference != PSP_SYSTEMPARAM_BUTTON_CIRCLE) {
PPGeDrawImage(I_CROSS, 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(I_CIRCLE, 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CIRCLE"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
} else {
PPGeDrawImage(I_CIRCLE, 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(I_CROSS, 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CIRCLE"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
}
PPGeDrawText(di->T("Select"), 75, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
@@ -1055,9 +1081,9 @@ int PSPOskDialog::Update(int animSpeed) {
} else if (IsButtonPressed(CTRL_SQUARE) && inputChars.size() < FieldMaxLength()) {
// Use a regular space if the current keyboard isn't Japanese nor full-width English
if (currentKeyboardLanguage != OSK_LANGUAGE_JAPANESE && currentKeyboardLanguage != OSK_LANGUAGE_ENGLISH_FW)
inputChars += L" ";
inputChars += u" ";
else
inputChars += L" ";
inputChars += u" ";
}
EndDraw();
@@ -1070,7 +1096,7 @@ int PSPOskDialog::Update(int animSpeed) {
for (size_t i = 0; i < end; ++i)
{
u16 value = 0;
if (i < inputChars.size())
if (i < FieldMaxLength() && i < inputChars.size())
value = inputChars[i];
outText[i] = value;
}
@@ -1089,6 +1115,7 @@ int PSPOskDialog::Shutdown(bool force)
if (!force) {
ChangeStatusShutdown(OSK_SHUTDOWN_DELAY_US);
}
nativeStatus_ = PSPOskNativeStatus::IDLE;
return 0;
}
@@ -1097,7 +1124,7 @@ void PSPOskDialog::DoState(PointerWrap &p)
{
PSPDialog::DoState(p);
auto s = p.Section("PSPOskDialog", 1);
auto s = p.Section("PSPOskDialog", 1, 2);
if (!s)
return;
@@ -1106,7 +1133,14 @@ void PSPOskDialog::DoState(PointerWrap &p)
p.Do(oskIntext);
p.Do(oskOuttext);
p.Do(selectedChar);
p.Do(inputChars);
if (s >= 2) {
p.Do(inputChars);
} else {
// Discard the wstring.
std::wstring wstr;
p.Do(wstr);
}
// Don't need to save state native status or value.
}
pspUtilityDialogCommon *PSPOskDialog::GetCommonParam()
+17 -6
View File
@@ -17,6 +17,7 @@
#pragma once
#include <mutex>
#include <string>
#include "Core/Dialog/PSPDialog.h"
@@ -202,6 +203,14 @@ static const std::string OskKeyboardNames[] =
"English Full-width",
};
enum class PSPOskNativeStatus {
IDLE,
DONE,
WAITING,
SUCCESS,
FAILURE,
};
class PSPOskDialog: public PSPDialog {
public:
PSPOskDialog();
@@ -220,14 +229,12 @@ protected:
private:
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le>& em_address);
void ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input);
void ConvertUCS2ToUTF8(std::string& _string, const char16_t *input);
void RenderKeyboard();
#if defined(USING_WIN_UI)
int NativeKeyboard();
#endif
std::wstring CombinationString(bool isInput); // for Japanese, Korean
std::wstring CombinationKorean(bool isInput); // for Korea
std::u16string CombinationString(bool isInput); // for Japanese, Korean
std::u16string CombinationKorean(bool isInput); // for Korea
void RemoveKorean(); // for Korean character removal
u32 FieldMaxLength();
@@ -239,11 +246,15 @@ private:
std::string oskOuttext;
int selectedChar;
std::wstring inputChars;
std::u16string inputChars;
OskKeyboardDisplay currentKeyboard;
OskKeyboardLanguage currentKeyboardLanguage;
bool isCombinated;
std::mutex nativeMutex_;
PSPOskNativeStatus nativeStatus_ = PSPOskNativeStatus::IDLE;
std::string nativeValue_;
int i_level; // for Korean Keyboard support
int i_value[3]; // for Korean Keyboard support
};
+7 -8
View File
@@ -534,9 +534,8 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo)
{
const float WRAP_WIDTH = 254.0f;
float y = 136.0f, h;
int n;
PPGeMeasureText(0, &h, &n, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
float h2 = h * (float)n / 2.0f;
PPGeMeasureText(nullptr, &h, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
float h2 = h / 2.0f;
if (hasYesNo)
{
auto di = GetI18NCategory("Dialog");
@@ -555,7 +554,7 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo)
yesColor = 0xFFFFFFFF;
noColor = 0xFFFFFFFF;
}
PPGeMeasureText(&w, &h, 0, choiceText, FONT_SCALE);
PPGeMeasureText(&w, &h, choiceText, FONT_SCALE);
w = w / 2.0f + 5.5f;
h /= 2.0f;
float y2 = y + h2 + 4.0f;
@@ -610,13 +609,13 @@ int PSPSaveDialog::Update(int animSpeed)
UpdateButtons();
UpdateFade(animSpeed);
okButtonImg = I_CIRCLE;
cancelButtonImg = I_CROSS;
okButtonImg = ImageID("I_CIRCLE");
cancelButtonImg = ImageID("I_CROSS");
okButtonFlag = CTRL_CIRCLE;
cancelButtonFlag = CTRL_CROSS;
if (param.GetPspParam()->common.buttonSwap == 1) {
okButtonImg = I_CROSS;
cancelButtonImg = I_CIRCLE;
okButtonImg = ImageID("I_CROSS");
cancelButtonImg = ImageID("I_CIRCLE");
okButtonFlag = CTRL_CROSS;
cancelButtonFlag = CTRL_CIRCLE;
}
+2 -2
View File
@@ -61,7 +61,7 @@ namespace
bool ReadPSPFile(std::string filename, u8 **data, s64 dataSize, s64 *readSize)
{
u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ);
int handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ);
if (handle < 0)
return false;
@@ -81,7 +81,7 @@ namespace
bool WritePSPFile(std::string filename, u8 *data, SceSize dataSize)
{
u32 handle = pspFileSystem.OpenFile(filename, (FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE | FILEACCESS_TRUNCATE));
int handle = pspFileSystem.OpenFile(filename, (FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE | FILEACCESS_TRUNCATE));
if (handle < 0)
return false;
@@ -21,6 +21,7 @@
#include <mutex>
#include <cstring>
#include "ppsspp_config.h"
#include "file/file_util.h"
#include "file/free.h"
#include "util/text/utf8.h"
@@ -29,6 +30,11 @@
#include "Core/FileLoaders/DiskCachingFileLoader.h"
#include "Core/System.h"
#if PPSSPP_PLATFORM(SWITCH)
// Far from optimal, but I guess it works...
#define fseeko fseek
#endif
static const char *CACHEFILE_MAGIC = "ppssppDC";
static const s64 SAFETY_FREE_DISK_SPACE = 768 * 1024 * 1024; // 768 MB
// Aim to allow this many files cached at once.
+6 -1
View File
@@ -117,7 +117,12 @@ std::string LocalFileLoader::Path() const {
}
size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) {
#if PPSSPP_PLATFORM(ANDROID)
#if PPSSPP_PLATFORM(SWITCH)
// Toolchain has no fancy IO API. We must lock.
std::lock_guard<std::mutex> guard(readLock_);
lseek(fd_, absolutePos, SEEK_SET);
return read(fd_, data, bytes * count) / bytes;
#elif PPSSPP_PLATFORM(ANDROID)
// pread64 doesn't appear to actually be 64-bit safe, though such ISOs are uncommon. See #10862.
if (absolutePos <= 0x7FFFFFFF) {
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64
+1 -1
View File
@@ -78,7 +78,7 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, F
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
readSize += bytesFromCache;
if (bytesFromCache == 0) {
// We can't read any more.
// We can't read any more.
break;
}
}
+2 -1
View File
@@ -197,7 +197,8 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader)
u64 lastIndexPos = index[indexSize - 1] & 0x7FFFFFFF;
u64 expectedFileSize = lastIndexPos << indexShift;
if (expectedFileSize > fileSize) {
ERROR_LOG(LOADER, "Expected CSO to at least be %lld bytes, but file is %lld bytes", expectedFileSize, fileSize);
ERROR_LOG(LOADER, "Expected CSO to at least be %lld bytes, but file is %lld bytes. File: '%s'",
expectedFileSize, fileSize, fileLoader->Path().c_str());
NotifyReadError();
}
}
+11 -2
View File
@@ -442,7 +442,8 @@ void DirectoryFileHandle::Close()
if (SetEndOfFile(hFile) == 0) {
ERROR_LOG_REPORT(FILESYS, "Failed to truncate file.");
}
#else
#elif !PPSSPP_PLATFORM(SWITCH)
// Note: it's not great that Switch cannot truncate appropriately...
if (ftruncate(hFile, (off_t)needsTrunc_) != 0) {
ERROR_LOG_REPORT(FILESYS, "Failed to truncate file.");
}
@@ -794,10 +795,17 @@ static std::string SimulateVFATBug(std::string filename) {
// These are the characters allowed in DOS filenames.
static const char *FAT_UPPER_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&'(){}-_`~";
static const char *FAT_LOWER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&'(){}-_`~";
static const char *LOWER_CHARS = "abcdefghijklmnopqrstuvwxyz";
// To avoid logging/comparing, skip all this if it has no lowercase chars to begin with.
size_t lowerchar = filename.find_first_of(LOWER_CHARS);
if (lowerchar == filename.npos) {
return filename;
}
bool apply_hack = false;
size_t dot_pos = filename.find('.');
if (dot_pos == filename.npos) {
if (dot_pos == filename.npos && filename.length() <= 8) {
size_t badchar = filename.find_first_not_of(FAT_LOWER_CHARS);
if (badchar == filename.npos) {
// It's all lowercase. Convert to upper.
@@ -824,6 +832,7 @@ static std::string SimulateVFATBug(std::string filename) {
}
if (apply_hack) {
VERBOSE_LOG(FILESYS, "Applying VFAT hack to filename: %s", filename.c_str());
// In this situation, NT would write UPPERCASE, and just set a flag to say "actually lowercase".
// That VFAT flag isn't read by the PSP firmware, so let's pretend to "not read it."
std::transform(filename.begin(), filename.end(), filename.begin(), toupper);
+190 -7
View File
@@ -59,6 +59,8 @@ enum
HLE_AFTER_DEBUG_BREAK = 0x20,
// Don't fill temp regs with 0xDEADBEEF.
HLE_AFTER_SKIP_DEADBEEF = 0x40,
// Execute pending mips calls.
HLE_AFTER_QUEUED_CALLS = 0x80,
};
static std::vector<HLEModule> moduleDB;
@@ -68,6 +70,33 @@ static const char *hleAfterSyscallReschedReason;
static const HLEFunction *latestSyscall = nullptr;
static int idleOp;
struct HLEMipsCallInfo {
u32 func;
PSPAction *action;
std::vector<u32> args;
};
struct HLEMipsCallStack {
u32_le nextOff;
union {
struct {
u32_le func;
u32_le actionIndex;
u32_le argc;
};
struct {
u32_le ra;
u32_le v0;
u32_le v1;
};
};
};
// No need to save state, always flushed at a syscall end.
static std::vector<HLEMipsCallInfo> enqueuedMipsCalls;
// Does need to be saved, referenced by the stack and owned.
static std::vector<PSPAction *> mipsCallActions;
void hleDelayResultFinish(u64 userdata, int cycleslate)
{
u32 error;
@@ -86,16 +115,14 @@ void hleDelayResultFinish(u64 userdata, int cycleslate)
WARN_LOG(HLE, "Someone else woke up HLE-blocked thread?");
}
void HLEInit()
{
void HLEInit() {
RegisterAllModules();
delayedResultEvent = CoreTiming::RegisterEvent("HLEDelayedResult", hleDelayResultFinish);
idleOp = GetSyscallOp("FakeSysCalls", NID_IDLE);
}
void HLEDoState(PointerWrap &p)
{
auto s = p.Section("HLE", 1);
void HLEDoState(PointerWrap &p) {
auto s = p.Section("HLE", 1, 2);
if (!s)
return;
@@ -103,13 +130,35 @@ void HLEDoState(PointerWrap &p)
latestSyscall = nullptr;
p.Do(delayedResultEvent);
CoreTiming::RestoreRegisterEvent(delayedResultEvent, "HLEDelayedResult", hleDelayResultFinish);
if (s >= 2) {
int actions = (int)mipsCallActions.size();
p.Do(actions);
if (actions != (int)mipsCallActions.size()) {
mipsCallActions.resize(actions);
}
for (auto &action : mipsCallActions) {
int actionTypeID = action != nullptr ? action->actionTypeID : -1;
p.Do(actionTypeID);
if (actionTypeID != -1) {
if (p.mode == p.MODE_READ)
action = __KernelCreateAction(actionTypeID);
action->DoState(p);
}
}
}
}
void HLEShutdown()
{
void HLEShutdown() {
hleAfterSyscall = HLE_AFTER_NOTHING;
latestSyscall = nullptr;
moduleDB.clear();
enqueuedMipsCalls.clear();
for (auto p : mipsCallActions) {
delete p;
}
mipsCallActions.clear();
}
void RegisterModule(const char *name, int numFunctions, const HLEFunction *funcTable)
@@ -354,6 +403,137 @@ bool hleIsKernelMode() {
return latestSyscall && (latestSyscall->flags & HLE_KERNEL_SYSCALL) != 0;
}
void hleEnqueueCall(u32 func, int argc, const u32 *argv, PSPAction *afterAction) {
std::vector<u32> args;
args.resize(argc);
memcpy(args.data(), argv, argc * sizeof(u32));
enqueuedMipsCalls.push_back({ func, afterAction, args });
hleAfterSyscall |= HLE_AFTER_QUEUED_CALLS;
}
void hleFlushCalls() {
u32 &sp = currentMIPS->r[MIPS_REG_SP];
PSPPointer<HLEMipsCallStack> stackData;
VERBOSE_LOG(HLE, "Flushing %d HLE mips calls from %s, sp=%08x", (int)enqueuedMipsCalls.size(), latestSyscall ? latestSyscall->name : "?", sp);
// First, we'll add a marker for the final return.
sp -= sizeof(HLEMipsCallStack);
stackData.ptr = sp;
stackData->nextOff = 0xFFFFFFFF;
stackData->ra = currentMIPS->pc;
stackData->v0 = currentMIPS->r[MIPS_REG_V0];
stackData->v1 = currentMIPS->r[MIPS_REG_V1];
// Now we'll set up the first in the chain.
currentMIPS->pc = enqueuedMipsCalls[0].func;
currentMIPS->r[MIPS_REG_RA] = HLEMipsCallReturnAddress();
for (int i = 0; i < (int)enqueuedMipsCalls[0].args.size(); i++) {
currentMIPS->r[MIPS_REG_A0 + i] = enqueuedMipsCalls[0].args[i];
}
// For stack info, process the first enqueued call last, so we run it first.
// We don't actually need to store 0's args, but keep it consistent.
for (int i = (int)enqueuedMipsCalls.size() - 1; i >= 0; --i) {
auto &info = enqueuedMipsCalls[i];
u32 stackRequired = (int)info.args.size() * sizeof(u32) + sizeof(HLEMipsCallStack);
u32 stackAligned = (stackRequired + 0xF) & ~0xF;
sp -= stackAligned;
stackData.ptr = sp;
stackData->nextOff = stackAligned;
stackData->func = info.func;
if (info.action) {
stackData->actionIndex = (int)mipsCallActions.size();
mipsCallActions.push_back(info.action);
} else {
stackData->actionIndex = 0xFFFFFFFF;
}
stackData->argc = (int)info.args.size();
for (int j = 0; j < (int)info.args.size(); ++j) {
Memory::Write_U32(info.args[j], sp + sizeof(HLEMipsCallStack) + j * sizeof(u32));
}
}
enqueuedMipsCalls.clear();
DEBUG_LOG(HLE, "Executing HLE mips call at %08x, sp=%08x", currentMIPS->pc, sp);
}
void HLEReturnFromMipsCall() {
u32 &sp = currentMIPS->r[MIPS_REG_SP];
PSPPointer<HLEMipsCallStack> stackData;
// At this point, we may have another mips call to run, or be at the end...
stackData.ptr = sp;
if ((stackData->nextOff & 0x0000000F) != 0 || !Memory::IsValidAddress(sp + stackData->nextOff)) {
ERROR_LOG(HLE, "Corrupt stack on HLE mips call return: %08x", stackData->nextOff);
Core_UpdateState(CORE_ERROR);
return;
}
if (stackData->actionIndex != 0xFFFFFFFF && stackData->actionIndex < (u32)mipsCallActions.size()) {
PSPAction *&action = mipsCallActions[stackData->actionIndex];
VERBOSE_LOG(HLE, "Executing action for HLE mips call at %08x, sp=%08x", stackData->func, sp);
// Search for the saved v0/v1 values, to preserve the PSPAction API...
PSPPointer<HLEMipsCallStack> finalMarker = stackData;
while ((finalMarker->nextOff & 0x0000000F) == 0 && Memory::IsValidAddress(finalMarker.ptr + finalMarker->nextOff)) {
finalMarker.ptr += finalMarker->nextOff;
}
if (finalMarker->nextOff != 0xFFFFFFFF) {
ERROR_LOG(HLE, "Corrupt stack on HLE mips call return action: %08x", finalMarker->nextOff);
Core_UpdateState(CORE_ERROR);
return;
}
MipsCall mc;
mc.savedV0 = finalMarker->v0;
mc.savedV1 = finalMarker->v1;
action->run(mc);
finalMarker->v0 = mc.savedV0;
finalMarker->v1 = mc.savedV1;
delete action;
action = nullptr;
// Note: the action could actually enqueue more, adding another layer on stack after this.
}
sp += stackData->nextOff;
stackData.ptr = sp;
if (stackData->nextOff == 0xFFFFFFFF) {
// We're done. Grab the HLE result's v0/v1 and return from the syscall.
currentMIPS->pc = stackData->ra;
currentMIPS->r[MIPS_REG_V0] = stackData->v0;
currentMIPS->r[MIPS_REG_V1] = stackData->v1;
sp += sizeof(HLEMipsCallStack);
bool canClear = true;
for (auto p : mipsCallActions) {
canClear = canClear && p == nullptr;
}
if (canClear) {
mipsCallActions.clear();
}
VERBOSE_LOG(HLE, "Finished HLE mips calls, v0=%08x, sp=%08x", currentMIPS->r[MIPS_REG_V0], sp);
return;
}
// Alright, we have another to call.
hleSkipDeadbeef();
currentMIPS->pc = stackData->func;
currentMIPS->r[MIPS_REG_RA] = HLEMipsCallReturnAddress();
for (int i = 0; i < (int)stackData->argc; i++) {
currentMIPS->r[MIPS_REG_A0 + i] = Memory::Read_U32(sp + sizeof(HLEMipsCallStack) + i * sizeof(u32));
}
DEBUG_LOG(HLE, "Executing next HLE mips call at %08x, sp=%08x", currentMIPS->pc, sp);
}
const static u32 deadbeefRegs[12] = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF};
inline static void SetDeadbeefRegs()
{
@@ -375,6 +555,8 @@ inline void hleFinishSyscall(const HLEFunction &info)
if ((hleAfterSyscall & HLE_AFTER_SKIP_DEADBEEF) == 0)
SetDeadbeefRegs();
if ((hleAfterSyscall & HLE_AFTER_QUEUED_CALLS) != 0)
hleFlushCalls();
if ((hleAfterSyscall & HLE_AFTER_CURRENT_CALLBACKS) != 0 && (hleAfterSyscall & HLE_AFTER_RESCHED_CALLBACKS) == 0)
__KernelForceCallbacks();
@@ -661,6 +843,7 @@ void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res,
const char *funcName = "?";
u32 funcFlags = 0;
if (latestSyscall) {
_dbg_assert_(HLE, latestSyscall->argmask != nullptr);
hleFormatLogArgs(formatted_args, sizeof(formatted_args), latestSyscall->argmask);
// This acts as an override (for error returns which are usually hex.)
+5
View File
@@ -24,6 +24,7 @@
#include "Core/MIPS/MIPS.h"
class PointerWrap;
class PSPAction;
typedef void (* HLEFunc)();
enum {
@@ -116,6 +117,8 @@ void hleSkipDeadbeef();
void hleSetSteppingTime(double t);
// Check if the current syscall context is kernel.
bool hleIsKernelMode();
// Enqueue a MIPS function to be called after this HLE call finishes.
void hleEnqueueCall(u32 func, int argc, const u32 *argv, PSPAction *afterAction = nullptr);
// Delays the result for usec microseconds, allowing other threads to run during this time.
u32 hleDelayResult(u32 result, const char *reason, int usec);
@@ -144,6 +147,8 @@ void CallSyscall(MIPSOpcode op);
void WriteFuncStub(u32 stubAddr, u32 symAddr);
void WriteFuncMissingStub(u32 stubAddr, u32 nid);
void HLEReturnFromMipsCall();
const HLEFunction *GetSyscallFuncPointer(MIPSOpcode op);
// For jit, takes arg: const HLEFunction *
void *GetQuickSyscallFunc(MIPSOpcode op);
+8 -7
View File
@@ -89,13 +89,14 @@
//sound
//zlibdec
const HLEFunction FakeSysCalls[] = {
{NID_THREADRETURN, __KernelReturnFromThread, "__KernelReturnFromThread"},
{NID_CALLBACKRETURN, __KernelReturnFromMipsCall, "__KernelReturnFromMipsCall"},
{NID_INTERRUPTRETURN, __KernelReturnFromInterrupt, "__KernelReturnFromInterrupt"},
{NID_EXTENDRETURN, __KernelReturnFromExtendStack, "__KernelReturnFromExtendStack"},
{NID_MODULERETURN, __KernelReturnFromModuleFunc, "__KernelReturnFromModuleFunc"},
{NID_IDLE, __KernelIdle, "_sceKernelIdle"},
{NID_GPUREPLAY, __KernelGPUReplay, "__KernelGPUReplay"},
{NID_THREADRETURN, __KernelReturnFromThread, "__KernelReturnFromThread", 'x', ""},
{NID_CALLBACKRETURN, __KernelReturnFromMipsCall, "__KernelReturnFromMipsCall", 'x', ""},
{NID_INTERRUPTRETURN, __KernelReturnFromInterrupt, "__KernelReturnFromInterrupt", 'x', ""},
{NID_EXTENDRETURN, __KernelReturnFromExtendStack, "__KernelReturnFromExtendStack", 'x', ""},
{NID_MODULERETURN, __KernelReturnFromModuleFunc, "__KernelReturnFromModuleFunc", 'x', ""},
{NID_IDLE, __KernelIdle, "_sceKernelIdle", 'x', ""},
{NID_GPUREPLAY, __KernelGPUReplay, "__KernelGPUReplay", 'x', ""},
{NID_HLECALLRETURN, HLEReturnFromMipsCall, "HLEReturnFromMipsCall", 'x', ""},
};
const HLEFunction UtilsForUser[] =
+1
View File
@@ -22,6 +22,7 @@
#define NID_INTERRUPTRETURN 0xbadd00d5
#define NID_EXTENDRETURN 0xbad0b0c9
#define NID_MODULERETURN 0xbad0d318
#define NID_HLECALLRETURN 0xbad0259b
#define NID_IDLE 0x1d7e1d7e
#define NID_GPUREPLAY 0x9e45bd95
+2 -2
View File
@@ -21,7 +21,7 @@
class KernelThreadDebugInterface : public MIPSDebugInterface {
public:
KernelThreadDebugInterface(MIPSState *c, ThreadContext &t) : MIPSDebugInterface(c), ctx(t) {
KernelThreadDebugInterface(MIPSState *c, PSPThreadContext &t) : MIPSDebugInterface(c), ctx(t) {
}
unsigned int getPC() override { return ctx.pc; }
@@ -86,5 +86,5 @@ public:
}
protected:
ThreadContext &ctx;
PSPThreadContext &ctx;
};
+72 -15
View File
@@ -63,6 +63,13 @@ std::recursive_mutex peerlock;
SceNetAdhocPdpStat * pdp[255];
SceNetAdhocPtpStat * ptp[255];
uint32_t localip;
std::vector<std::string> chatLog;
std::string name = "";
std::string incoming = "";
std::string message = "";
bool chatScreenVisible = false;
bool updateChatScreen = false;
int newChat = 0;
int isLocalMAC(const SceNetEtherAddr * addr) {
SceNetEtherAddr saddr;
@@ -1011,6 +1018,45 @@ void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node) {
free(node);
}
void sendChat(std::string chatString) {
SceNetAdhocctlChatPacketC2S chat;
auto n = GetI18NCategory("Networking");
chat.base.opcode = OPCODE_CHAT;
//TODO check network inited, check send success or not, chatlog.pushback error on failed send, pushback error on not connected
if (friendFinderRunning)
{
// Send Chat to Server
if (!chatString.empty()) {
//maximum char allowed is 64 character for compability with original server (pro.coldbird.net)
message = chatString.substr(0, 60); // 64 return chat variable corrupted is it out of memory?
strcpy(chat.message, message.c_str());
//Send Chat Messages
int chatResult = send(metasocket, (const char *)&chat, sizeof(chat), 0);
NOTICE_LOG(SCENET, "Send Chat %s to Adhoc Server", chat.message);
name = g_Config.sNickName.c_str();
chatLog.push_back(name.substr(0, 8) + ": " + chat.message);
if (chatScreenVisible) {
updateChatScreen = true;
}
}
}
else {
chatLog.push_back(n->T("You're in Offline Mode, go to lobby or online hall"));
if (chatScreenVisible) {
updateChatScreen = true;
}
}
}
std::vector<std::string> getChatLog() {
// this log used by chat screen
if (chatLog.size() > 50) {
//erase the first 40 element limit the chatlog size
chatLog.erase(chatLog.begin(), chatLog.begin() + 40);
}
return chatLog;
}
int friendFinder(){
// Receive Buffer
int rxpos = 0;
@@ -1054,13 +1100,6 @@ int friendFinder(){
}*/
}
// Send Chat Messages
//while(popFromOutbox(chat.message))
//{
// // Send Chat to Server
// sceNetInetSend(metasocket, (const char *)&chat, sizeof(chat), 0);
//}
// Wait for Incoming Data
int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos, 0);
@@ -1110,14 +1149,23 @@ int friendFinder(){
if (rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) {
// Cast Packet
SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx;
// Fix for Idiots that try to troll the "ME" Nametag
if (strcasecmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME");
// Add Incoming Chat to HUD
//printf("Receive chat message %s", packet->base.message);
DEBUG_LOG(SCENET, "Received chat message %s", packet->base.message);
NOTICE_LOG(SCENET, "Received chat message %s", packet->base.message);
incoming = "";
name = (char *)packet->name.data;
incoming.append(name.substr(0, 8));
incoming.append(": ");
incoming.append((char *)packet->base.message);
chatLog.push_back(incoming);
//im new to pointer btw :( doesn't know its safe or not this should update the chat screen when data coming
if (chatScreenVisible) {
updateChatScreen = true;
}
else {
if (newChat < 50) {
newChat += 1;
}
}
// Move RX Buffer
memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C));
@@ -1139,7 +1187,16 @@ int friendFinder(){
// Add User
addFriend(packet);
incoming = "";
incoming.append((char *)packet->name.data);
incoming.append(" Joined ");
//do we need ip?
//joined.append((char *)packet->ip);
chatLog.push_back(incoming);
//im new to pointer btw :( doesn't know its safe or not this should update the chat screen when data coming
if (chatScreenVisible) {
updateChatScreen = true;
}
// Update HUD User Count
#ifdef LOCALHOST_AS_PEER
setUserCount(getActivePeerCount());
+12 -2
View File
@@ -764,10 +764,10 @@ typedef struct {
#pragma pack(pop)
#endif
class AfterMatchingMipsCall : public Action {
class AfterMatchingMipsCall : public PSPAction {
public:
AfterMatchingMipsCall() {}
static Action *Create() { return new AfterMatchingMipsCall(); }
static PSPAction *Create() { return new AfterMatchingMipsCall(); }
void DoState(PointerWrap &p) override {
auto s = p.Section("AfterMatchingMipsCall", 1, 2);
if (!s)
@@ -851,6 +851,16 @@ SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * contex
*/
void addFriend(SceNetAdhocctlConnectPacketS2C * packet);
/**
* Send chat or get that
* @param std::string ChatString
*/
void sendChat(std::string chatString);
std::vector<std::string> getChatLog();
extern bool chatScreenVisible;
extern bool updateChatScreen;
extern int newChat;
/*
* Find a Peer/Friend by MAC address
*/
+2 -2
View File
@@ -28,9 +28,9 @@
#include "Core/Reporting.h"
typedef PSPPointer<char> PSPCharPointer;
typedef PSPPointer<u16> PSPWCharPointer;
typedef PSPPointer<char16_t> PSPWCharPointer;
typedef PSPPointer<const char> PSPConstCharPointer;
typedef PSPPointer<const u16> PSPConstWCharPointer;
typedef PSPPointer<const char16_t> PSPConstWCharPointer;
static u16 errorUTF8;
static u16 errorUTF16;
+35 -12
View File
@@ -49,6 +49,7 @@
#include "Core/HLE/sceKernel.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/Util/PPGeDraw.h"
#include "GPU/GPU.h"
#include "GPU/GPUState.h"
@@ -549,6 +550,9 @@ static int CalculateFrameSkip() {
static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
PROFILE_THIS_SCOPE("timing");
FPSLimit fpsLimiter = PSP_CoreParameter().fpsLimit;
int fpsLimit = 60;
if (fpsLimiter != FPSLimit::NORMAL)
fpsLimit = fpsLimiter == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
throttle = FrameTimingThrottled();
skipFrame = false;
@@ -556,7 +560,16 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
// we have nothing to do here.
bool doFrameSkip = g_Config.iFrameSkip != 0;
if (!throttle && g_Config.bFrameSkipUnthrottle) {
bool unthrottleNeedsSkip = g_Config.bFrameSkipUnthrottle;
if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) {
// Vulkan doesn't support the interval setting, so we force frameskip.
unthrottleNeedsSkip = true;
// If it's not a clean multiple of 60, we may need frameskip to achieve it.
if (fpsLimit == 0 || (fpsLimit >= 0 && fpsLimit != 15 && fpsLimit != 30 && fpsLimit != 60)) {
doFrameSkip = true;
}
}
if (!throttle && unthrottleNeedsSkip) {
doFrameSkip = true;
skipFrame = true;
if (numSkippedFrames >= 7) {
@@ -571,10 +584,8 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
time_update();
float scaledTimestep = timestep;
if (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) {
scaledTimestep *= 60.0f / g_Config.iFpsLimit1;
} else if (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) {
scaledTimestep *= 60.0f / g_Config.iFpsLimit2;
if (fpsLimit > 0 && fpsLimit != 60) {
scaledTimestep *= 60.0f / fpsLimit;
}
if (lastFrameTime == 0.0 || wasPaused) {
@@ -594,13 +605,16 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
// Auto-frameskip automatically if speed limit is set differently than the default.
bool useAutoFrameskip = g_Config.bAutoFrameSkip && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
bool forceFrameskip = (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 60) || (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 60);
bool forceFrameskip = fpsLimit > 60 && unthrottleNeedsSkip;
int frameSkipNum = CalculateFrameSkip();
if (g_Config.bAutoFrameSkip || forceFrameskip) {
// autoframeskip
// Argh, we are falling behind! Let's skip a frame and see if we catch up.
if (curFrameTime > nextFrameTime && doFrameSkip) {
skipFrame = true;
if (forceFrameskip) {
throttle = false;
}
}
} else if (frameSkipNum >= 1) {
// fixed frameskip
@@ -740,9 +754,17 @@ void __DisplayFlip(int cyclesLate) {
// Also let's always flip for animated shaders.
const ShaderInfo *shaderInfo = g_Config.sPostShaderName == "Off" ? nullptr : GetPostShaderInfo(g_Config.sPostShaderName);
bool postEffectRequiresFlip = false;
if (shaderInfo && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE)
postEffectRequiresFlip = shaderInfo->requires60fps;
// postEffectRequiresFlip is not compatible with frameskip unthrottling, see #12325.
if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && !(g_Config.bFrameSkipUnthrottle && !FrameTimingThrottled())) {
if (shaderInfo) {
postEffectRequiresFlip = (shaderInfo->requires60fps || g_Config.bRenderDuplicateFrames);
} else {
postEffectRequiresFlip = g_Config.bRenderDuplicateFrames;
}
}
const bool fbDirty = gpu->FramebufferDirty();
if (fbDirty || noRecentFlip || postEffectRequiresFlip) {
int frameSleepPos = frameTimeHistoryPos;
CalculateFPS();
@@ -768,7 +790,7 @@ void __DisplayFlip(int cyclesLate) {
// Check first though, might've just quit / been paused.
if (coreState == CORE_RUNNING) {
coreState = CORE_NEXTFRAME;
gpu->CopyDisplayToOutput();
gpu->CopyDisplayToOutput(fbReallyDirty);
if (fbReallyDirty) {
actualFlips++;
}
@@ -819,6 +841,7 @@ void __DisplayFlip(int cyclesLate) {
void hleAfterFlip(u64 userdata, int cyclesLate) {
gpu->BeginFrame(); // doesn't really matter if begin or end of frame.
PPGeNotifyFrame();
// This seems like as good a time as any to check if the config changed.
if (lagSyncScheduled != g_Config.bForceLagSync) {
@@ -929,6 +952,8 @@ void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelFormat, int sync)
if (sync == PSP_DISPLAY_SETBUF_IMMEDIATE) {
// Write immediately to the current framebuffer parameters.
framebuf = fbstate;
// Also update latchedFramebuf for any sceDisplayGetFramebuf() after this.
latchedFramebuf = fbstate;
gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.stride, framebuf.fmt);
// IMMEDIATE means that the buffer is fine. We can just flip immediately.
// Doing it in non-buffered though creates problems (black screen) on occasion though
@@ -1033,9 +1058,7 @@ bool __DisplayGetFramebuf(PSPPointer<u8> *topaddr, u32 *linesize, u32 *pixelForm
}
static u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelFormatPtr, int latchedMode) {
// NOTE: This is wrong and partially reverts #8753. Presumably there's something else involved here as well.
// See #8816. Could also be a firmware version difference, there are a few of those...
const FrameBufferState &fbState = (latchedMode == PSP_DISPLAY_SETBUF_NEXTFRAME && framebufIsLatched) ? latchedFramebuf : framebuf;
const FrameBufferState &fbState = latchedMode == PSP_DISPLAY_SETBUF_NEXTFRAME ? latchedFramebuf : framebuf;
if (Memory::IsValidAddress(topaddrPtr))
Memory::Write_U32(fbState.topaddr, topaddrPtr);
+246 -38
View File
@@ -35,9 +35,15 @@ enum {
FONT_IS_OPEN = 1,
};
// For the save states.
static bool useAllocCallbacks = true;
// Actions
static int actionPostAllocCallback;
static int actionPostOpenCallback;
static int actionPostOpenAllocCallback;
static int actionPostCharInfoAllocCallback;
static int actionPostCharInfoFreeCallback;
// Monster Hunter sequence:
// 36:46:998 c:\dev\ppsspp\core\hle\scefont.cpp:469 E[HLE]: sceFontNewLib 89ad4a0, 9fff5cc
@@ -82,30 +88,31 @@ struct FontRegistryEntry {
const char *fontName;
int expireDate;
int shadow_option;
u32 fontFileSize;
bool ignoreIfMissing;
};
static const FontRegistryEntry fontRegistry[] = {
// This was added for Chinese translations and is not normally loaded on a PSP.
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_CHINESE, 0, 1, "zh_gb.pgf", "FTT-NewRodin Pro DB", 0, 0, true },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0 },
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0},
{0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0},
{0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0},
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_CHINESE, 0, 1, "zh_gb.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700, true },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0, 69108 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0, 65124 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72948 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0, 67700},
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72828 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0, 68220 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0, 77032 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0, 71144 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0, 41000 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0, 40164 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0, 42692 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0, 41488 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0, 43136 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0, 41772 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0, 45184 },
{ 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0, 43044 },
{ 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0, 394192 },
};
static const float pointDPI = 72.f;
@@ -204,6 +211,7 @@ public:
PGF *GetPGF() { return &pgf_; }
const PGF *GetPGF() const { return &pgf_; }
u32 getSize() const { return dataSize_; }
bool IsValid() const { return valid_; }
void DoState(PointerWrap &p) {
@@ -228,6 +236,7 @@ private:
style_.fontV = (float)pgf_.header.vSize / 64.0f;
style_.fontHRes = (float)pgf_.header.hResolution / 64.0f;
style_.fontVRes = (float)pgf_.header.vResolution / 64.0f;
this->dataSize_ = (u32)dataSize;
}
void Init(const u8 *data, size_t dataSize, const FontRegistryEntry &entry) {
@@ -247,11 +256,13 @@ private:
strncpy(style_.fontFileName, entry.fileName, sizeof(style_.fontFileName));
style_.fontAttributes = entry.extraAttributes;
style_.fontExpire = entry.expireDate;
this->dataSize_ = entry.fontFileSize;
}
PGF pgf_;
PGFFontStyle style_;
bool valid_;
u32 dataSize_;
DISALLOW_COPY_AND_ASSIGN(Font);
};
@@ -338,10 +349,10 @@ private:
DISALLOW_COPY_AND_ASSIGN(LoadedFont);
};
class PostAllocCallback : public Action {
class PostAllocCallback : public PSPAction {
public:
PostAllocCallback() {}
static Action *Create() { return new PostAllocCallback(); }
static PSPAction *Create() { return new PostAllocCallback(); }
void DoState(PointerWrap &p) override {
auto s = p.Section("PostAllocCallback", 1, 2);
if (!s)
@@ -360,10 +371,10 @@ private:
u32 errorCodePtr_;
};
class PostOpenCallback : public Action {
class PostOpenCallback : public PSPAction {
public:
PostOpenCallback() {}
static Action *Create() { return new PostOpenCallback(); }
static PSPAction *Create() { return new PostOpenCallback(); }
void DoState(PointerWrap &p) override {
auto s = p.Section("PostOpenCallback", 1);
if (!s)
@@ -378,6 +389,69 @@ private:
u32 fontLibID_;
};
class PostOpenAllocCallback : public PSPAction {
public:
PostOpenAllocCallback() {}
static PSPAction *Create() { return new PostOpenAllocCallback(); }
void DoState(PointerWrap &p) override {
auto s = p.Section("PostOpenAllocCallback", 1);
if (!s)
return;
p.Do(fontLibID_);
p.Do(fontHandle_);
p.Do(fontIndex_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
void SetFont(u32 handle, int index) { fontHandle_ = handle; fontIndex_ = index; }
private:
u32 fontLibID_;
u32 fontHandle_;
int fontIndex_;
};
class PostCharInfoAllocCallback : public PSPAction {
public:
PostCharInfoAllocCallback() {}
static PSPAction *Create() { return new PostCharInfoAllocCallback(); }
void DoState(PointerWrap &p) override {
auto s = p.Section("PostCharInfoAllocCallback", 1);
if (!s)
return;
p.Do(fontLibID_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
private:
u32 fontLibID_;
};
class PostCharInfoFreeCallback : public PSPAction {
public:
PostCharInfoFreeCallback() {}
static PSPAction *Create() { return new PostCharInfoFreeCallback(); }
void DoState(PointerWrap &p) override {
auto s = p.Section("PostCharInfoFreeCallback", 1);
if (!s)
return;
p.Do(fontLibID_);
p.Do(charInfo_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
void SetCharInfo(PSPPointer<PGFCharInfo> charInfo) { charInfo_ = charInfo; }
private:
u32 fontLibID_;
PSPPointer<PGFCharInfo> charInfo_;
};
struct NativeFontLib {
FontNewLibParams params;
// TODO
@@ -406,7 +480,7 @@ public:
// For save states only.
}
FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f), altCharCode_(0x5F) {
FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f), altCharCode_(0x5F), charInfoBitmapAddress_(0) {
nfl_ = 0;
Memory::ReadStruct(paramPtr, &params_);
if (params_.numFonts > 9) {
@@ -418,8 +492,8 @@ public:
PostAllocCallback *action = (PostAllocCallback *) __KernelCreateAction(actionPostAllocCallback);
action->SetFontLib(GetListID(), errorCodePtr);
u32 args[2] = { params_.userDataAddr, allocSize };
__KernelDirectMipsCall(params_.allocFuncAddr, action, args, 2, true);
u32 args[2] = { userDataAddr(), allocSize };
hleEnqueueCall(allocFuncAddr(), 2, args, action);
}
u32 GetListID() {
@@ -429,25 +503,29 @@ public:
void Done() {
for (size_t i = 0; i < fonts_.size(); i++) {
if (isfontopen_[i] == FONT_IS_OPEN) {
fontMap[fonts_[i]]->Close();
CloseFont(fontMap[fonts_[i]]);
delete fontMap[fonts_[i]];
fontMap.erase(fonts_[i]);
}
}
u32 args[2] = { params_.userDataAddr, (u32)handle_ };
u32 args[2] = { userDataAddr(), (u32)handle_ };
// TODO: The return value of this is leaking.
if (handle_) { // Avoid calling free-callback on double-free
__KernelDirectMipsCall(params_.freeFuncAddr, 0, args, 2, false);
if (coreState != CORE_POWERDOWN) {
hleEnqueueCall(freeFuncAddr(), 2, args);
}
}
handle_ = 0;
fonts_.clear();
isfontopen_.clear();
openAllocatedAddresses_.clear();
}
void AllocDone(u32 allocatedAddr) {
handle_ = allocatedAddr;
fonts_.resize(params_.numFonts);
isfontopen_.resize(params_.numFonts);
openAllocatedAddresses_.resize(params_.numFonts);
for (size_t i = 0; i < fonts_.size(); i++) {
u32 addr = allocatedAddr + 0x4C + (u32)i * 0x4C;
isfontopen_[i] = 0;
@@ -471,6 +549,9 @@ public:
u32 handle() const { return handle_; }
int numFonts() const { return params_.numFonts; }
u32_le userDataAddr() const{ return params_.userDataAddr; }
u32_le allocFuncAddr() const { return params_.allocFuncAddr; }
u32_le freeFuncAddr() const { return params_.freeFuncAddr; }
void SetResolution(float hres, float vres) {
fontHRes_ = hres;
@@ -524,6 +605,24 @@ public:
delete prevFont->second;
}
fontMap[loadedFont->Handle()] = loadedFont;
if (!useAllocCallbacks)
return loadedFont;
u32 allocSize = 12;
if (mode == FONT_OPEN_INTERNAL_STINGY) {
allocSize = 0x239B4;
} else if (mode == FONT_OPEN_INTERNAL_FULL) {
allocSize += loadedFont->GetFont()->getSize();
}
PostOpenAllocCallback *action = (PostOpenAllocCallback *)__KernelCreateAction(actionPostOpenAllocCallback);
action->SetFontLib(GetListID());
action->SetFont(loadedFont->Handle(), freeFontIndex);
u32 args[2] = { userDataAddr(), allocSize };
hleEnqueueCall(allocFuncAddr(), 2, args, action);
return loadedFont;
}
@@ -531,14 +630,28 @@ public:
for (size_t i = 0; i < fonts_.size(); i++) {
if (fonts_[i] == font->Handle()) {
isfontopen_[i] = 0;
if (openAllocatedAddresses_[i] != 0 && coreState != CORE_POWERDOWN) {
u32 args[2] = { userDataAddr(), openAllocatedAddresses_[i] };
hleEnqueueCall(freeFuncAddr(), 2, args);
openAllocatedAddresses_[i] = 0;
}
break;
}
}
flushFont();
font->Close();
}
void flushFont() {
if (charInfoBitmapAddress_ != 0 && coreState != CORE_POWERDOWN) {
u32 args[2] = { userDataAddr(), charInfoBitmapAddress_ };
hleEnqueueCall(freeFuncAddr(), 2, args);
charInfoBitmapAddress_ = 0;
}
}
void DoState(PointerWrap &p) {
auto s = p.Section("FontLib", 1, 2);
auto s = p.Section("FontLib", 1, 3);
if (!s)
return;
@@ -555,6 +668,14 @@ public:
} else {
nfl_ = 0;
}
if (s >= 3) {
p.Do(openAllocatedAddresses_);
p.Do(charInfoBitmapAddress_);
} else {
openAllocatedAddresses_.resize(params_.numFonts);
charInfoBitmapAddress_ = 0;
}
}
void SetFileFontHandle(u32 handle) {
@@ -563,6 +684,20 @@ public:
u32 GetAltCharCode() const { return altCharCode_; }
u32 GetOpenAllocatedAddress(int index) const {
if(index < numFonts())
return openAllocatedAddresses_[index];
return 0;
}
void SetOpenAllocatedAddress(int index, u32 addr) {
if (index < numFonts())
openAllocatedAddresses_[index] = addr;
}
u32 GetCharInfoBitmapAddress() const { return charInfoBitmapAddress_; }
void SetCharInfoBitmapAddress(u32 addr) { charInfoBitmapAddress_ = addr; }
private:
std::vector<u32> fonts_;
std::vector<u32> isfontopen_;
@@ -573,6 +708,8 @@ private:
int fileFontHandle_;
int handle_;
int altCharCode_;
std::vector<u32> openAllocatedAddresses_;
u32 charInfoBitmapAddress_;
PSPPointer<NativeFontLib> nfl_;
DISALLOW_COPY_AND_ASSIGN(FontLib);
@@ -590,6 +727,7 @@ void PostAllocCallback::run(MipsCall &call) {
FontLib *fontLib = fontLibList[fontLibID_];
fontLib->AllocDone(v0);
fontLibMap[fontLib->handle()] = fontLibID_;
// This is the same as v0 above.
call.setReturnValue(fontLib->handle());
}
INFO_LOG(SCEFONT, "Leaving PostAllocCallback::run");
@@ -601,6 +739,34 @@ void PostOpenCallback::run(MipsCall &call) {
fontLib->SetFileFontHandle(v0);
}
void PostOpenAllocCallback::run(MipsCall &call) {
FontLib *fontLib = fontLibList[fontLibID_];
u32 v0 = currentMIPS->r[MIPS_REG_V0];
fontLib->SetOpenAllocatedAddress(fontIndex_, v0);
}
void PostCharInfoAllocCallback::run(MipsCall &call) {
FontLib *fontLib = fontLibList[fontLibID_];
u32 v0 = currentMIPS->r[MIPS_REG_V0];
if (v0 == 0) {
call.setReturnValue(ERROR_FONT_OUT_OF_MEMORY); // From JPCSP, if alloc size is 0, still this error value?
} else {
fontLib->SetCharInfoBitmapAddress(v0);
}
}
void PostCharInfoFreeCallback::run(MipsCall &call) {
FontLib *fontLib = fontLibList[fontLibID_];
fontLib->SetCharInfoBitmapAddress(0);
u32 allocSize = charInfo_->bitmapWidth * charInfo_->bitmapHeight;
PostCharInfoAllocCallback *action = (PostCharInfoAllocCallback *)__KernelCreateAction(actionPostCharInfoAllocCallback);
action->SetFontLib(fontLibID_);
u32 args[2] = { fontLib->userDataAddr(), allocSize };
hleEnqueueCall(fontLib->allocFuncAddr(), 2, args, action);
}
inline bool LoadedFont::GetCharInfo(int charCode, PGFCharInfo *charInfo, int glyphType) const {
auto fontLib = GetFontLib();
int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode();
@@ -709,8 +875,12 @@ int GetInternalFontIndex(Font *font) {
}
void __FontInit() {
useAllocCallbacks = true;
actionPostAllocCallback = __KernelRegisterActionType(PostAllocCallback::Create);
actionPostOpenCallback = __KernelRegisterActionType(PostOpenCallback::Create);
actionPostOpenAllocCallback = __KernelRegisterActionType(PostOpenAllocCallback::Create);
actionPostCharInfoAllocCallback = __KernelRegisterActionType(PostCharInfoAllocCallback::Create);
actionPostCharInfoFreeCallback = __KernelRegisterActionType(PostCharInfoFreeCallback::Create);
}
void __FontShutdown() {
@@ -733,7 +903,7 @@ void __FontShutdown() {
}
void __FontDoState(PointerWrap &p) {
auto s = p.Section("sceFont", 1);
auto s = p.Section("sceFont", 1, 2);
if (!s)
return;
@@ -747,6 +917,16 @@ void __FontDoState(PointerWrap &p) {
__KernelRestoreActionType(actionPostAllocCallback, PostAllocCallback::Create);
p.Do(actionPostOpenCallback);
__KernelRestoreActionType(actionPostOpenCallback, PostOpenCallback::Create);
if (s >= 2) {
p.Do(actionPostOpenAllocCallback);
__KernelRestoreActionType(actionPostOpenAllocCallback, PostOpenAllocCallback::Create);
p.Do(actionPostCharInfoAllocCallback);
__KernelRestoreActionType(actionPostCharInfoAllocCallback, PostCharInfoAllocCallback::Create);
p.Do(actionPostCharInfoFreeCallback);
__KernelRestoreActionType(actionPostCharInfoFreeCallback, PostCharInfoFreeCallback::Create);
} else {
useAllocCallbacks = false;
}
}
static u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) {
@@ -912,14 +1092,13 @@ static u32 sceFontOpenUserFile(u32 libHandle, const char *fileName, u32 mode, u3
static int sceFontClose(u32 fontHandle) {
LoadedFont *font = GetLoadedFont(fontHandle, false);
if (font)
{
if (font) {
DEBUG_LOG(SCEFONT, "sceFontClose(%x)", fontHandle);
FontLib *fontLib = font->GetFontLib();
if (fontLib)
if (fontLib) {
fontLib->CloseFont(font);
}
else
}
} else
ERROR_LOG(SCEFONT, "sceFontClose(%x) - font not open?", fontHandle);
return 0;
}
@@ -1100,6 +1279,27 @@ static int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) {
auto charInfo = PSPPointer<PGFCharInfo>::Create(charInfoPtr);
font->GetCharInfo(charCode, charInfo);
if (!useAllocCallbacks)
return 0;
u32 allocSize = charInfo->bitmapWidth * charInfo->bitmapHeight;
if (charInfo->sfp26AdvanceH != 0 || charInfo->sfp26AdvanceV != 0) {
if (font->GetFontLib()->GetCharInfoBitmapAddress() != 0) {
PostCharInfoFreeCallback *action = (PostCharInfoFreeCallback *)__KernelCreateAction(actionPostCharInfoFreeCallback);
action->SetFontLib(font->GetFontLib()->GetListID());
action->SetCharInfo(charInfo);
u32 args[2] = { font->GetFontLib()->userDataAddr(), font->GetFontLib()->GetCharInfoBitmapAddress() };
hleEnqueueCall(font->GetFontLib()->freeFuncAddr(), 2, args, action);
} else {
PostCharInfoAllocCallback *action = (PostCharInfoAllocCallback *)__KernelCreateAction(actionPostCharInfoAllocCallback);
action->SetFontLib(font->GetFontLib()->GetListID());
u32 args[2] = { font->GetFontLib()->userDataAddr(), allocSize };
hleEnqueueCall(font->GetFontLib()->allocFuncAddr(), 2, args, action);
}
}
return 0;
}
@@ -1215,7 +1415,15 @@ static int sceFontSetAltCharacterCode(u32 fontLibHandle, u32 charCode) {
static int sceFontFlush(u32 fontHandle) {
INFO_LOG(SCEFONT, "sceFontFlush(%i)", fontHandle);
// Probably don't need to do anything here.
LoadedFont *font = GetLoadedFont(fontHandle, true);
if (!font) {
ERROR_LOG_REPORT(SCEFONT, "sceFontFlush(%08x): bad font", fontHandle);
return ERROR_FONT_INVALID_PARAMETER;
}
font->GetFontLib()->flushFont();
return 0;
}
+3 -2
View File
@@ -930,7 +930,7 @@ static u32 sceIoGetstat(const char *filename, u32 addr) {
}
static u32 sceIoChstat(const char *filename, u32 iostatptr, u32 changebits) {
ERROR_LOG(SCEIO, "UNIMPL sceIoChstat(%s, %08x, %08x)", filename, iostatptr, changebits);
ERROR_LOG_REPORT(SCEIO, "UNIMPL sceIoChstat(%s, %08x, %08x)", filename, iostatptr, changebits);
if (changebits & SCE_CST_MODE)
ERROR_LOG(SCEIO, "sceIoChstat: change mode requested");
if (changebits & SCE_CST_ATTR)
@@ -2731,7 +2731,8 @@ static int IoAsyncFinish(int id) {
break;
default:
ERROR_LOG_REPORT(SCEIO, "Unknown async op %d", params.op);
ERROR_LOG_REPORT(SCEIO, "Unknown async op %d", (int)params.op);
us = 0;
break;
}
+16 -22
View File
@@ -37,16 +37,14 @@ struct NativeAlarm
u32_le commonPtr;
};
struct Alarm : public KernelObject
{
struct PSPAlarm : public KernelObject {
const char *GetName() override {return "[Alarm]";}
const char *GetTypeName() override {return "Alarm";}
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_ALMID; }
static int GetStaticIDType() { return SCE_KERNEL_TMID_Alarm; }
int GetIDType() const override { return SCE_KERNEL_TMID_Alarm; }
void DoState(PointerWrap &p) override
{
void DoState(PointerWrap &p) override {
auto s = p.Section("Alarm", 1);
if (!s)
return;
@@ -57,7 +55,7 @@ struct Alarm : public KernelObject
NativeAlarm alm;
};
void __KernelScheduleAlarm(Alarm *alarm, u64 micro);
void __KernelScheduleAlarm(PSPAlarm *alarm, u64 micro);
class AlarmIntrHandler : public IntrHandler
{
@@ -69,7 +67,7 @@ public:
u32 error;
int alarmID = triggeredAlarm.front();
Alarm *alarm = kernelObjects.Get<Alarm>(alarmID, error);
PSPAlarm *alarm = kernelObjects.Get<PSPAlarm>(alarmID, error);
if (error)
{
WARN_LOG(SCEKERNEL, "Ignoring deleted alarm %08x", alarmID);
@@ -95,7 +93,7 @@ public:
{
DEBUG_LOG(SCEKERNEL, "Rescheduling alarm %08x for +%dms", alarmID, result);
u32 error;
Alarm *alarm = kernelObjects.Get<Alarm>(alarmID, error);
PSPAlarm *alarm = kernelObjects.Get<PSPAlarm>(alarmID, error);
__KernelScheduleAlarm(alarm, result);
}
else
@@ -106,21 +104,19 @@ public:
DEBUG_LOG(SCEKERNEL, "Finished alarm %08x", alarmID);
// Delete the alarm if it's not rescheduled.
kernelObjects.Destroy<Alarm>(alarmID);
kernelObjects.Destroy<PSPAlarm>(alarmID);
}
}
};
static int alarmTimer = -1;
static void __KernelTriggerAlarm(u64 userdata, int cyclesLate)
{
static void __KernelTriggerAlarm(u64 userdata, int cyclesLate) {
int uid = (int) userdata;
u32 error;
Alarm *alarm = kernelObjects.Get<Alarm>(uid, error);
if (alarm)
{
PSPAlarm *alarm = kernelObjects.Get<PSPAlarm>(uid, error);
if (alarm) {
triggeredAlarm.push_back(uid);
__TriggerInterrupt(PSP_INTR_IMMEDIATE, PSP_SYSTIMER0_INTR);
}
@@ -144,14 +140,12 @@ void __KernelAlarmDoState(PointerWrap &p)
CoreTiming::RestoreRegisterEvent(alarmTimer, "Alarm", __KernelTriggerAlarm);
}
KernelObject *__KernelAlarmObject()
{
KernelObject *__KernelAlarmObject() {
// Default object to load from state.
return new Alarm;
return new PSPAlarm;
}
void __KernelScheduleAlarm(Alarm *alarm, u64 micro)
{
void __KernelScheduleAlarm(PSPAlarm *alarm, u64 micro) {
alarm->alm.schedule = CoreTiming::GetGlobalTimeUs() + micro;
CoreTiming::ScheduleEvent(usToCycles(micro), alarmTimer, alarm->GetUID());
}
@@ -161,7 +155,7 @@ static SceUID __KernelSetAlarm(u64 micro, u32 handlerPtr, u32 commonPtr)
if (!Memory::IsValidAddress(handlerPtr))
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
Alarm *alarm = new Alarm;
PSPAlarm *alarm = new PSPAlarm();
SceUID uid = kernelObjects.Create(alarm);
alarm->alm.size = NATIVEALARM_SIZE;
@@ -197,13 +191,13 @@ int sceKernelCancelAlarm(SceUID uid)
CoreTiming::UnscheduleEvent(alarmTimer, uid);
return kernelObjects.Destroy<Alarm>(uid);
return kernelObjects.Destroy<PSPAlarm>(uid);
}
int sceKernelReferAlarmStatus(SceUID uid, u32 infoPtr)
{
u32 error;
Alarm *alarm = kernelObjects.Get<Alarm>(uid, error);
PSPAlarm *alarm = kernelObjects.Get<PSPAlarm>(uid, error);
if (!alarm)
{
ERROR_LOG(SCEKERNEL, "sceKernelReferAlarmStatus(%08x, %08x): invalid alarm", uid, infoPtr);
@@ -228,4 +222,4 @@ int sceKernelReferAlarmStatus(SceUID uid, u32 infoPtr)
Memory::Write_U32(alarm->alm.commonPtr, infoPtr + 16);
return 0;
}
}
+3 -5
View File
@@ -48,15 +48,13 @@ static const u32 PSP_NUMBER_SUBINTERRUPTS = 32;
// INTERRUPT MANAGEMENT
//////////////////////////////////////////////////////////////////////////
class InterruptState
{
class InterruptState {
public:
void save();
void restore();
void clear();
void DoState(PointerWrap &p)
{
void DoState(PointerWrap &p) {
auto s = p.Section("InterruptState", 1);
if (!s)
return;
@@ -64,7 +62,7 @@ public:
p.Do(savedCpu);
}
ThreadContext savedCpu;
PSPThreadContext savedCpu;
};
// STATE
+2 -9
View File
@@ -213,10 +213,6 @@ struct SceKernelVplHeader {
do {
auto b = prev->next;
if (b->sizeInBlocks > allocBlocks) {
if (nextFreeBlock_ == b) {
nextFreeBlock_ = prev;
}
prev = b;
b = SplitBlock(b, allocBlocks);
}
@@ -289,16 +285,13 @@ struct SceKernelVplHeader {
void UnlinkFreeBlock(PSPPointer<SceKernelVplBlock> b, PSPPointer<SceKernelVplBlock> prev) {
allocatedInBlocks_ += b->sizeInBlocks;
prev->next = b->next;
if (nextFreeBlock_ == b) {
nextFreeBlock_ = prev;
}
nextFreeBlock_ = prev;
b->next = SentinelPtr();
}
PSPPointer<SceKernelVplBlock> SplitBlock(PSPPointer<SceKernelVplBlock> b, u32 allocBlocks) {
u32 prev = b->next.ptr;
u32 prev = b.ptr;
b->sizeInBlocks -= allocBlocks;
b->next = b + b->sizeInBlocks;
b += b->sizeInBlocks;
b->sizeInBlocks = allocBlocks;
+57 -60
View File
@@ -155,8 +155,8 @@ void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting);
void ExportFuncSymbol(const FuncSymbolExport &func);
void UnexportFuncSymbol(const FuncSymbolExport &func);
class Module;
static bool KernelImportModuleFuncs(Module *module, u32 *firstImportStubAddr, bool reimporting = false);
class PSPModule;
static bool KernelImportModuleFuncs(PSPModule *module, u32 *firstImportStubAddr, bool reimporting = false);
struct NativeModule {
u32_le next;
@@ -228,10 +228,10 @@ enum NativeModuleStatus {
MODULE_STATUS_UNLOADING = 8,
};
class Module : public KernelObject {
class PSPModule : public KernelObject {
public:
Module() : textStart(0), textEnd(0), libstub(0), libstubend(0), memoryBlockAddr(0), isFake(false) {}
~Module() {
PSPModule() : textStart(0), textEnd(0), libstub(0), libstubend(0), memoryBlockAddr(0), isFake(false) {}
~PSPModule() {
if (memoryBlockAddr) {
// If it's either below user memory, or using a high kernel bit, it's in kernel.
if (memoryBlockAddr < PSP_GetUserMemoryBase() || memoryBlockAddr > PSP_GetUserMemoryEnd()) {
@@ -421,10 +421,10 @@ public:
KernelObject *__KernelModuleObject()
{
return new Module;
return new PSPModule;
}
class AfterModuleEntryCall : public Action {
class AfterModuleEntryCall : public PSPAction {
public:
AfterModuleEntryCall() {}
SceUID moduleID_;
@@ -438,7 +438,7 @@ public:
p.Do(moduleID_);
p.Do(retValAddr);
}
static Action *Create() {
static PSPAction *Create() {
return new AfterModuleEntryCall;
}
};
@@ -507,7 +507,7 @@ void __KernelModuleDoState(PointerWrap &p)
u32 error;
// We process these late, since they depend on loadedModules for interlinking.
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (module && module->libstub != 0) {
if (!KernelImportModuleFuncs(module, nullptr, true)) {
ERROR_LOG(LOADER, "Something went wrong loading imports on load state");
@@ -655,7 +655,7 @@ void ImportVarSymbol(const VarSymbolImport &var) {
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(var.moduleName)) {
continue;
}
@@ -676,7 +676,7 @@ void ImportVarSymbol(const VarSymbolImport &var) {
void ExportVarSymbol(const VarSymbolExport &var) {
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(var.moduleName)) {
continue;
}
@@ -694,7 +694,7 @@ void ExportVarSymbol(const VarSymbolExport &var) {
void UnexportVarSymbol(const VarSymbolExport &var) {
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(var.moduleName)) {
continue;
}
@@ -724,7 +724,7 @@ void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting) {
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(func.moduleName)) {
continue;
}
@@ -765,7 +765,7 @@ void ExportFuncSymbol(const FuncSymbolExport &func) {
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(func.moduleName)) {
continue;
}
@@ -790,7 +790,7 @@ void UnexportFuncSymbol(const FuncSymbolExport &func) {
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(func.moduleName)) {
continue;
}
@@ -806,7 +806,7 @@ void UnexportFuncSymbol(const FuncSymbolExport &func) {
}
}
void Module::Cleanup() {
void PSPModule::Cleanup() {
MIPSAnalyst::ForgetFunctions(textStart, textEnd);
loadedModules.erase(GetUID());
@@ -909,7 +909,7 @@ static bool IsHLEVersionedModule(const char *name) {
return false;
}
static bool KernelImportModuleFuncs(Module *module, u32 *firstImportStubAddr, bool reimporting) {
static bool KernelImportModuleFuncs(PSPModule *module, u32 *firstImportStubAddr, bool reimporting) {
struct PspLibStubEntry {
u32_le name;
u16_le version;
@@ -1090,8 +1090,8 @@ static int gzipDecompress(u8 *OutBuffer, int OutBufferLength, u8 *InBuffer) {
return stream.total_out;
}
static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, u32 &error) {
Module *module = new Module;
static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, u32 &error) {
PSPModule *module = new PSPModule();
kernelObjects.Create(module);
loadedModules.insert(module->GetUID());
memset(&module->nm, 0, sizeof(module->nm));
@@ -1133,7 +1133,7 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
if (size > elfSize) {
*error_string = StringFromFormat("ELF/PRX truncated: %d > %d", (int)size, (int)elfSize);
module->Cleanup();
kernelObjects.Destroy<Module>(module->GetUID());
kernelObjects.Destroy<PSPModule>(module->GetUID());
return nullptr;
}
const auto maxElfSize = std::max(head->elf_size, head->psp_size);
@@ -1166,7 +1166,7 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
if (addr == (u32)-1) {
error = SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED;
module->Cleanup();
kernelObjects.Destroy<Module>(module->GetUID());
kernelObjects.Destroy<PSPModule>(module->GetUID());
} else {
error = 0;
module->memoryBlockAddr = addr;
@@ -1207,7 +1207,7 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
if (newptr)
delete [] newptr;
module->Cleanup();
kernelObjects.Destroy<Module>(module->GetUID());
kernelObjects.Destroy<PSPModule>(module->GetUID());
error = SCE_KERNEL_ERROR_UNSUPPORTED_PRX_TYPE;
return nullptr;
}
@@ -1221,7 +1221,7 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
if (newptr)
delete [] newptr;
module->Cleanup();
kernelObjects.Destroy<Module>(module->GetUID());
kernelObjects.Destroy<PSPModule>(module->GetUID());
error = result;
return nullptr;
}
@@ -1536,8 +1536,8 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd
return module;
}
static Module *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOption *options, std::string *error_string) {
Module *module = 0;
static PSPModule *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOption *options, std::string *error_string) {
PSPModule *module = nullptr;
// Check for PBP
if (memcmp(fileptr, "\0PBP", 4) == 0) {
// PBP!
@@ -1583,8 +1583,7 @@ static Module *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOptio
return module;
}
static void __KernelStartModule(Module *m, int args, const char *argp, SceKernelSMOption *options)
{
static void __KernelStartModule(PSPModule *m, int args, const char *argp, SceKernelSMOption *options) {
m->nm.status = MODULE_STATUS_STARTED;
if (m->nm.module_start_func != 0 && m->nm.module_start_func != (u32)-1)
{
@@ -1599,16 +1598,12 @@ static void __KernelStartModule(Module *m, int args, const char *argp, SceKernel
}
u32 __KernelGetModuleGP(SceUID uid)
{
u32 __KernelGetModuleGP(SceUID uid) {
u32 error;
Module *module = kernelObjects.Get<Module>(uid, error);
if (module)
{
PSPModule *module = kernelObjects.Get<PSPModule>(uid, error);
if (module) {
return module->nm.gp_value;
}
else
{
} else {
return 0;
}
}
@@ -1619,7 +1614,7 @@ void __KernelLoadReset() {
u32 error;
while (!loadedModules.empty()) {
SceUID moduleID = *loadedModules.begin();
Module *module = kernelObjects.Get<Module>(moduleID, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleID, error);
if (module) {
module->Cleanup();
} else {
@@ -1635,8 +1630,6 @@ void __KernelLoadReset() {
HLEShutdown();
Replacement_Init();
HLEInit();
assert(gpu);
gpu->Reinitialize();
}
__KernelModuleInit();
@@ -1688,12 +1681,12 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
pspFileSystem.ReadFile(handle, temp, (size_t)info.size);
PSP_SetLoading("Loading modules...");
Module *module = __KernelLoadModule(temp, (size_t)info.size, 0, error_string);
PSPModule *module = __KernelLoadModule(temp, (size_t)info.size, 0, error_string);
if (!module || module->isFake) {
if (module) {
module->Cleanup();
kernelObjects.Destroy<Module>(module->GetUID());
kernelObjects.Destroy<PSPModule>(module->GetUID());
}
ERROR_LOG(LOADER, "Failed to load module %s", filename);
*error_string = "Failed to load executable: " + *error_string;
@@ -1772,7 +1765,7 @@ bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_str
Memory::WriteUnchecked_U32(runDumpCode[i], mipsr4k.pc + (int)i * sizeof(u32_le));
}
Module *module = new Module;
PSPModule *module = new PSPModule();
kernelObjects.Create(module);
loadedModules.insert(module->GetUID());
memset(&module->nm, 0, sizeof(module->nm));
@@ -1836,6 +1829,9 @@ int sceKernelLoadExec(const char *filename, u32 paramPtr)
Core_UpdateState(CORE_ERROR);
return -1;
}
if (gpu) {
gpu->Reinitialize();
}
return 0;
}
@@ -1846,7 +1842,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
for (size_t i = 0; i < ARRAY_SIZE(lieAboutSuccessModules); i++) {
if (!strcmp(name, lieAboutSuccessModules[i])) {
Module *module = new Module;
PSPModule *module = new PSPModule();
kernelObjects.Create(module);
loadedModules.insert(module->GetUID());
memset(&module->nm, 0, sizeof(module->nm));
@@ -1897,7 +1893,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
WARN_LOG_REPORT(LOADER, "sceKernelLoadModule: unsupported options size=%08x, flags=%08x, pos=%d, access=%d, data=%d, text=%d", lmoption->size, lmoption->flags, lmoption->position, lmoption->access, lmoption->mpiddata, lmoption->mpidtext);
}
Module *module = 0;
PSPModule *module = nullptr;
u8 *temp = new u8[(int)size];
u32 handle = pspFileSystem.OpenFile(name, FILEACCESS_READ);
pspFileSystem.ReadFile(handle, temp, (size_t)size);
@@ -1920,6 +1916,9 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
NOTICE_LOG_REPORT(LOADER, "Module %s is blacklisted or undecryptable - we try __KernelLoadExec", name);
// Name might get deleted.
const std::string safeName = name;
if (gpu) {
gpu->Reinitialize();
}
return __KernelLoadExec(safeName.c_str(), 0, &error_string);
} else {
hleLogError(LOADER, error, "failed to load");
@@ -1957,7 +1956,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret
Memory::ReadStruct(optionAddr, &smoption);
}
u32 error;
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module) {
INFO_LOG(SCEMODULE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x,%08x): error %08x", moduleId, argsize, argAddr, returnValueAddr, optionAddr, error);
RETURN(error);
@@ -2056,7 +2055,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
// TODO: In a lot of cases (even for errors), this should resched. Needs testing.
u32 error;
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module)
{
ERROR_LOG(SCEMODULE, "sceKernelStopModule(%08x, %08x, %08x, %08x, %08x): invalid module id", moduleId, argSize, argAddr, returnValueAddr, optionAddr);
@@ -2129,12 +2128,12 @@ static u32 sceKernelUnloadModule(u32 moduleId)
{
INFO_LOG(SCEMODULE,"sceKernelUnloadModule(%i)", moduleId);
u32 error;
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module)
return hleDelayResult(error, "module unloaded", 150);
module->Cleanup();
kernelObjects.Destroy<Module>(moduleId);
kernelObjects.Destroy<PSPModule>(moduleId);
return hleDelayResult(moduleId, "module unloaded", 500);
}
@@ -2151,7 +2150,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize,
// TODO: In a lot of cases (even for errors), this should resched. Needs testing.
u32 error;
Module *module = kernelObjects.Get<Module>(moduleID, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleID, error);
if (!module) {
if (WithStatus)
ERROR_LOG(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): invalid module id", exitCode, argSize, argp, statusAddr, optionAddr);
@@ -2200,7 +2199,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize,
INFO_LOG(SCEMODULE, "sceKernelSelfStopUnloadModule(%08x, %08x, %08x): no stop func", exitCode, argSize, argp);
sceKernelExitDeleteThread(exitCode);
module->Cleanup();
kernelObjects.Destroy<Module>(moduleID);
kernelObjects.Destroy<PSPModule>(moduleID);
} else {
if (WithStatus)
ERROR_LOG_REPORT(SCEMODULE, "sceKernelStopUnloadSelfModuleWithStatus(%08x, %08x, %08x, %08x, %08x): bad stop func address", exitCode, argSize, argp, statusAddr, optionAddr);
@@ -2208,7 +2207,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize,
ERROR_LOG_REPORT(SCEMODULE, "sceKernelSelfStopUnloadModule(%08x, %08x, %08x): bad stop func address", exitCode, argSize, argp);
sceKernelExitDeleteThread(exitCode);
module->Cleanup();
kernelObjects.Destroy<Module>(moduleID);
kernelObjects.Destroy<PSPModule>(moduleID);
}
} else {
if (WithStatus)
@@ -2244,7 +2243,7 @@ void __KernelReturnFromModuleFunc()
sceKernelDeleteThread(leftThreadID);
u32 error;
Module *module = kernelObjects.Get<Module>(leftModuleID, error);
PSPModule *module = kernelObjects.Get<PSPModule>(leftModuleID, error);
if (!module) {
ERROR_LOG_REPORT(SCEMODULE, "Returned from deleted module start/stop func");
return;
@@ -2274,7 +2273,7 @@ void __KernelReturnFromModuleFunc()
if (module->nm.status == MODULE_STATUS_UNLOADING) {
// TODO: Delete the waiting thread?
module->Cleanup();
kernelObjects.Destroy<Module>(leftModuleID);
kernelObjects.Destroy<PSPModule>(leftModuleID);
}
}
@@ -2284,11 +2283,9 @@ struct GetModuleIdByAddressArg
SceUID result;
};
static bool __GetModuleIdByAddressIterator(Module *module, GetModuleIdByAddressArg *state)
{
static bool __GetModuleIdByAddressIterator(PSPModule *module, GetModuleIdByAddressArg *state) {
const u32 start = module->memoryBlockAddr, size = module->memoryBlockSize;
if (start != 0 && start <= state->addr && start + size > state->addr)
{
if (start != 0 && start <= state->addr && start + size > state->addr) {
state->result = module->GetUID();
return false;
}
@@ -2347,7 +2344,7 @@ static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr)
size_t size = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END);
std::string error_string;
pspFileSystem.SeekFile(handle, pos, FILEMOVE_BEGIN);
Module *module = 0;
PSPModule *module = nullptr;
u8 *temp = new u8[size - pos];
pspFileSystem.ReadFile(handle, temp, size - pos);
u32 magic;
@@ -2405,7 +2402,7 @@ static SceUID sceKernelLoadModuleBufferUsbWlan(u32 size, u32 bufPtr, u32 flags,
WARN_LOG_REPORT(LOADER, "sceKernelLoadModuleBufferUsbWlan: unsupported options size=%08x, flags=%08x, pos=%d, access=%d, data=%d, text=%d", lmoption->size, lmoption->flags, lmoption->position, lmoption->access, lmoption->mpiddata, lmoption->mpidtext);
}
std::string error_string;
Module *module = 0;
PSPModule *module = nullptr;
u32 magic;
u32 error;
module = __KernelLoadELFFromPtr(Memory::GetPointer(bufPtr), size, 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, error);
@@ -2447,7 +2444,7 @@ static u32 sceKernelQueryModuleInfo(u32 uid, u32 infoAddr)
{
INFO_LOG(SCEMODULE, "sceKernelQueryModuleInfo(%i, %08x)", uid, infoAddr);
u32 error;
Module *module = kernelObjects.Get<Module>(uid, error);
PSPModule *module = kernelObjects.Get<PSPModule>(uid, error);
if (!module)
return error;
if (!Memory::IsValidAddress(infoAddr)) {
@@ -2488,7 +2485,7 @@ static u32 sceKernelGetModuleIdList(u32 resultBuffer, u32 resultBufferSize, u32
u32 error;
for (SceUID moduleId : loadedModules) {
Module *module = kernelObjects.Get<Module>(moduleId, error);
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module->isFake) {
if (resultBufferOffset < resultBufferSize) {
Memory::Write_U32(module->GetUID(), resultBuffer + resultBufferOffset);
+26 -35
View File
@@ -62,7 +62,7 @@ struct NativeMutex
s32_le numWaitThreads;
};
struct Mutex : public KernelObject
struct PSPMutex : public KernelObject
{
const char *GetName() override { return nm.name; }
const char *GetTypeName() override { return "Mutex"; }
@@ -189,7 +189,7 @@ void __KernelMutexDoState(PointerWrap &p)
KernelObject *__KernelMutexObject()
{
return new Mutex;
return new PSPMutex;
}
KernelObject *__KernelLwMutexObject()
@@ -202,8 +202,7 @@ void __KernelMutexShutdown()
mutexHeldLocks.clear();
}
static void __KernelMutexAcquireLock(Mutex *mutex, int count, SceUID thread)
{
static void __KernelMutexAcquireLock(PSPMutex *mutex, int count, SceUID thread) {
#if defined(_DEBUG)
auto locked = mutexHeldLocks.equal_range(thread);
for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter)
@@ -216,13 +215,11 @@ static void __KernelMutexAcquireLock(Mutex *mutex, int count, SceUID thread)
mutex->nm.lockThread = thread;
}
static void __KernelMutexAcquireLock(Mutex *mutex, int count)
{
static void __KernelMutexAcquireLock(PSPMutex *mutex, int count) {
__KernelMutexAcquireLock(mutex, count, __KernelGetCurThread());
}
static void __KernelMutexEraseLock(Mutex *mutex)
{
static void __KernelMutexEraseLock(PSPMutex *mutex) {
if (mutex->nm.lockThread != -1)
{
SceUID id = mutex->GetUID();
@@ -259,8 +256,7 @@ static std::vector<SceUID>::iterator __KernelMutexFindPriority(std::vector<SceUI
return best;
}
static bool __KernelUnlockMutexForThread(Mutex *mutex, SceUID threadID, u32 &error, int result)
{
static bool __KernelUnlockMutexForThread(PSPMutex *mutex, SceUID threadID, u32 &error, int result) {
if (!HLEKernel::VerifyWait(threadID, WAITTYPE_MUTEX, mutex->GetUID()))
return false;
@@ -283,8 +279,7 @@ static bool __KernelUnlockMutexForThread(Mutex *mutex, SceUID threadID, u32 &err
return true;
}
static bool __KernelUnlockMutexForThreadCheck(Mutex *mutex, SceUID threadID, u32 &error, int result, bool &wokeThreads)
{
static bool __KernelUnlockMutexForThreadCheck(PSPMutex *mutex, SceUID threadID, u32 &error, int result, bool &wokeThreads) {
if (mutex->nm.lockThread == -1 && __KernelUnlockMutexForThread(mutex, threadID, error, 0))
return true;
return false;
@@ -292,7 +287,7 @@ static bool __KernelUnlockMutexForThreadCheck(Mutex *mutex, SceUID threadID, u32
void __KernelMutexBeginCallback(SceUID threadID, SceUID prevCallbackId)
{
auto result = HLEKernel::WaitBeginCallback<Mutex, WAITTYPE_MUTEX, SceUID>(threadID, prevCallbackId, mutexWaitTimer);
auto result = HLEKernel::WaitBeginCallback<PSPMutex, WAITTYPE_MUTEX, SceUID>(threadID, prevCallbackId, mutexWaitTimer);
if (result == HLEKernel::WAIT_CB_SUCCESS)
DEBUG_LOG(SCEKERNEL, "sceKernelLockMutexCB: Suspending lock wait for callback");
else
@@ -301,7 +296,7 @@ void __KernelMutexBeginCallback(SceUID threadID, SceUID prevCallbackId)
void __KernelMutexEndCallback(SceUID threadID, SceUID prevCallbackId)
{
auto result = HLEKernel::WaitEndCallback<Mutex, WAITTYPE_MUTEX, SceUID>(threadID, prevCallbackId, mutexWaitTimer, __KernelUnlockMutexForThreadCheck);
auto result = HLEKernel::WaitEndCallback<PSPMutex, WAITTYPE_MUTEX, SceUID>(threadID, prevCallbackId, mutexWaitTimer, __KernelUnlockMutexForThreadCheck);
if (result == HLEKernel::WAIT_CB_RESUMED_WAIT)
DEBUG_LOG(SCEKERNEL, "sceKernelLockMutexCB: Resuming lock wait for callback");
}
@@ -324,7 +319,7 @@ int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optio
if ((attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && initialCount > 1)
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
Mutex *mutex = new Mutex();
PSPMutex *mutex = new PSPMutex();
SceUID id = kernelObjects.Create(mutex);
mutex->nm.size = sizeof(mutex->nm);
@@ -357,7 +352,7 @@ int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optio
int sceKernelDeleteMutex(SceUID id)
{
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
if (mutex)
{
DEBUG_LOG(SCEKERNEL, "sceKernelDeleteMutex(%i)", id);
@@ -373,7 +368,7 @@ int sceKernelDeleteMutex(SceUID id)
if (wokeThreads)
hleReSchedule("mutex deleted");
return kernelObjects.Destroy<Mutex>(id);
return kernelObjects.Destroy<PSPMutex>(id);
}
else
{
@@ -382,8 +377,7 @@ int sceKernelDeleteMutex(SceUID id)
}
}
static bool __KernelLockMutexCheck(Mutex *mutex, int count, u32 &error)
{
static bool __KernelLockMutexCheck(PSPMutex *mutex, int count, u32 &error) {
if (error)
return false;
@@ -411,8 +405,7 @@ static bool __KernelLockMutexCheck(Mutex *mutex, int count, u32 &error)
return false;
}
static bool __KernelLockMutex(Mutex *mutex, int count, u32 &error)
{
static bool __KernelLockMutex(PSPMutex *mutex, int count, u32 &error) {
if (!__KernelLockMutexCheck(mutex, count, error))
return false;
@@ -433,8 +426,7 @@ static bool __KernelLockMutex(Mutex *mutex, int count, u32 &error)
return false;
}
static bool __KernelUnlockMutex(Mutex *mutex, u32 &error)
{
static bool __KernelUnlockMutex(PSPMutex *mutex, u32 &error) {
__KernelMutexEraseLock(mutex);
bool wokeThreads = false;
@@ -459,7 +451,7 @@ static bool __KernelUnlockMutex(Mutex *mutex, u32 &error)
void __KernelMutexTimeout(u64 userdata, int cyclesLate)
{
SceUID threadID = (SceUID)userdata;
HLEKernel::WaitExecTimeout<Mutex, WAITTYPE_MUTEX>(threadID);
HLEKernel::WaitExecTimeout<PSPMutex, WAITTYPE_MUTEX>(threadID);
}
void __KernelMutexThreadEnd(SceUID threadID)
@@ -470,7 +462,7 @@ void __KernelMutexThreadEnd(SceUID threadID)
SceUID waitingMutexID = __KernelGetWaitID(threadID, WAITTYPE_MUTEX, error);
if (waitingMutexID)
{
Mutex *mutex = kernelObjects.Get<Mutex>(waitingMutexID, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(waitingMutexID, error);
if (mutex)
HLEKernel::RemoveWaitingThread(mutex->waitingThreads, threadID);
}
@@ -481,7 +473,7 @@ void __KernelMutexThreadEnd(SceUID threadID)
{
// Need to increment early so erase() doesn't invalidate.
SceUID mutexID = (*iter++).second;
Mutex *mutex = kernelObjects.Get<Mutex>(mutexID, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(mutexID, error);
if (mutex)
{
@@ -491,8 +483,7 @@ void __KernelMutexThreadEnd(SceUID threadID)
}
}
static void __KernelWaitMutex(Mutex *mutex, u32 timeoutPtr)
{
static void __KernelWaitMutex(PSPMutex *mutex, u32 timeoutPtr) {
if (timeoutPtr == 0 || mutexWaitTimer == -1)
return;
@@ -511,7 +502,7 @@ static void __KernelWaitMutex(Mutex *mutex, u32 timeoutPtr)
int sceKernelCancelMutex(SceUID uid, int count, u32 numWaitThreadsPtr)
{
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(uid, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(uid, error);
if (mutex)
{
bool lockable = count <= 0 || __KernelLockMutexCheck(mutex, count, error);
@@ -566,7 +557,7 @@ int sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr)
{
DEBUG_LOG(SCEKERNEL, "sceKernelLockMutex(%i, %i, %08x)", id, count, timeoutPtr);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
if (__KernelLockMutex(mutex, count, error))
return 0;
@@ -591,7 +582,7 @@ int sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr)
{
DEBUG_LOG(SCEKERNEL, "sceKernelLockMutexCB(%i, %i, %08x)", id, count, timeoutPtr);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
if (!__KernelLockMutexCheck(mutex, count, error))
{
@@ -630,7 +621,7 @@ int sceKernelTryLockMutex(SceUID id, int count)
{
DEBUG_LOG(SCEKERNEL, "sceKernelTryLockMutex(%i, %i)", id, count);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
if (__KernelLockMutex(mutex, count, error))
return 0;
@@ -645,7 +636,7 @@ int sceKernelUnlockMutex(SceUID id, int count)
{
DEBUG_LOG(SCEKERNEL, "sceKernelUnlockMutex(%i, %i)", id, count);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
PSPMutex *mutex = kernelObjects.Get<PSPMutex>(id, error);
if (error)
return error;
@@ -672,7 +663,7 @@ int sceKernelUnlockMutex(SceUID id, int count)
int sceKernelReferMutexStatus(SceUID id, u32 infoAddr)
{
u32 error;
Mutex *m = kernelObjects.Get<Mutex>(id, error);
PSPMutex *m = kernelObjects.Get<PSPMutex>(id, error);
if (!m)
{
ERROR_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%i, %08x): invalid mutex id", id, infoAddr);
@@ -1136,4 +1127,4 @@ int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr)
ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatus(%08x, %08x)", error, workareaPtr, infoPtr);
return error;
}
}
}
+17 -21
View File
@@ -53,8 +53,7 @@ struct NativeSemaphore
};
struct Semaphore : public KernelObject
{
struct PSPSemaphore : public KernelObject {
const char *GetName() override { return ns.name; }
const char *GetTypeName() override { return "Semaphore"; }
@@ -103,12 +102,11 @@ void __KernelSemaDoState(PointerWrap &p)
KernelObject *__KernelSemaphoreObject()
{
return new Semaphore;
return new PSPSemaphore;
}
// Returns whether the thread should be removed.
static bool __KernelUnlockSemaForThread(Semaphore *s, SceUID threadID, u32 &error, int result, bool &wokeThreads)
{
static bool __KernelUnlockSemaForThread(PSPSemaphore *s, SceUID threadID, u32 &error, int result, bool &wokeThreads) {
if (!HLEKernel::VerifyWait(threadID, WAITTYPE_SEMA, s->GetUID()))
return true;
@@ -139,7 +137,7 @@ static bool __KernelUnlockSemaForThread(Semaphore *s, SceUID threadID, u32 &erro
void __KernelSemaBeginCallback(SceUID threadID, SceUID prevCallbackId)
{
auto result = HLEKernel::WaitBeginCallback<Semaphore, WAITTYPE_SEMA, SceUID>(threadID, prevCallbackId, semaWaitTimer);
auto result = HLEKernel::WaitBeginCallback<PSPSemaphore, WAITTYPE_SEMA, SceUID>(threadID, prevCallbackId, semaWaitTimer);
if (result == HLEKernel::WAIT_CB_SUCCESS)
DEBUG_LOG(SCEKERNEL, "sceKernelWaitSemaCB: Suspending sema wait for callback");
else
@@ -148,15 +146,14 @@ void __KernelSemaBeginCallback(SceUID threadID, SceUID prevCallbackId)
void __KernelSemaEndCallback(SceUID threadID, SceUID prevCallbackId)
{
auto result = HLEKernel::WaitEndCallback<Semaphore, WAITTYPE_SEMA, SceUID>(threadID, prevCallbackId, semaWaitTimer, __KernelUnlockSemaForThread);
auto result = HLEKernel::WaitEndCallback<PSPSemaphore, WAITTYPE_SEMA, SceUID>(threadID, prevCallbackId, semaWaitTimer, __KernelUnlockSemaForThread);
if (result == HLEKernel::WAIT_CB_RESUMED_WAIT)
DEBUG_LOG(SCEKERNEL, "sceKernelWaitSemaCB: Resuming sema wait for callback");
}
// Resume all waiting threads (for delete / cancel.)
// Returns true if it woke any threads.
static bool __KernelClearSemaThreads(Semaphore *s, int reason)
{
static bool __KernelClearSemaThreads(PSPSemaphore *s, int reason) {
u32 error;
bool wokeThreads = false;
std::vector<SceUID>::iterator iter, end;
@@ -170,7 +167,7 @@ static bool __KernelClearSemaThreads(Semaphore *s, int reason)
int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
if (newCount > s->ns.maxCount)
@@ -215,7 +212,7 @@ int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32
return SCE_KERNEL_ERROR_ILLEGAL_ATTR;
}
Semaphore *s = new Semaphore;
PSPSemaphore *s = new PSPSemaphore();
SceUID id = kernelObjects.Create(s);
s->ns.size = sizeof(NativeSemaphore);
@@ -244,7 +241,7 @@ int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32
int sceKernelDeleteSema(SceUID id)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
DEBUG_LOG(SCEKERNEL, "sceKernelDeleteSema(%i)", id);
@@ -253,7 +250,7 @@ int sceKernelDeleteSema(SceUID id)
if (wokeThreads)
hleReSchedule("semaphore deleted");
return kernelObjects.Destroy<Semaphore>(id);
return kernelObjects.Destroy<PSPSemaphore>(id);
}
else
{
@@ -265,7 +262,7 @@ int sceKernelDeleteSema(SceUID id)
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferSemaStatus(%i, %08x)", id, infoPtr);
@@ -290,7 +287,7 @@ int sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
int sceKernelSignalSema(SceUID id, int signal)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
if (s->ns.currentCount + signal - (int) s->waitingThreads.size() > s->ns.maxCount)
@@ -336,10 +333,10 @@ void __KernelSemaTimeout(u64 userdata, int cycleslate)
u32 error;
SceUID uid = __KernelGetWaitID(threadID, WAITTYPE_SEMA, error);
HLEKernel::WaitExecTimeout<Semaphore, WAITTYPE_SEMA>(threadID);
HLEKernel::WaitExecTimeout<PSPSemaphore, WAITTYPE_SEMA>(threadID);
// If in FIFO mode, that may have cleared another thread to wake up.
Semaphore *s = kernelObjects.Get<Semaphore>(uid, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(uid, error);
if (s && (s->ns.attr & PSP_SEMA_ATTR_PRIORITY) == PSP_SEMA_ATTR_FIFO) {
bool wokeThreads;
std::vector<SceUID>::iterator iter = s->waitingThreads.begin();
@@ -351,8 +348,7 @@ void __KernelSemaTimeout(u64 userdata, int cycleslate)
}
}
static void __KernelSetSemaTimeout(Semaphore *s, u32 timeoutPtr)
{
static void __KernelSetSemaTimeout(PSPSemaphore *s, u32 timeoutPtr) {
if (timeoutPtr == 0 || semaWaitTimer == -1)
return;
@@ -378,7 +374,7 @@ static int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, bool pro
hleEatCycles(500);
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
if (wantedCount > s->ns.maxCount)
@@ -438,7 +434,7 @@ int sceKernelPollSema(SceUID id, int wantedCount)
}
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
if (s->ns.currentCount >= wantedCount && s->waitingThreads.size() == 0)
File diff suppressed because it is too large. Load diff
+16 -16
View File
@@ -26,7 +26,7 @@
// There's a good description of the thread scheduling rules in:
// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/ThreadManForUser.java
class Thread;
class PSPThread;
class DebugInterface;
int sceKernelChangeThreadPriority(SceUID threadID, int priority);
@@ -119,8 +119,7 @@ typedef void (* WaitEndCallbackFunc)(SceUID threadID, SceUID prevCallbackId);
void __KernelRegisterWaitTypeFuncs(WaitType type, WaitBeginCallbackFunc beginFunc, WaitEndCallbackFunc endFunc);
struct ThreadContext
{
struct PSPThreadContext {
void reset();
// r must be followed by f.
@@ -168,8 +167,8 @@ u32 __KernelGetCurThreadStackStart();
const char *__KernelGetThreadName(SceUID threadID);
bool KernelIsThreadDormant(SceUID threadID);
void __KernelSaveContext(ThreadContext *ctx, bool vfpuEnabled);
void __KernelLoadContext(ThreadContext *ctx, bool vfpuEnabled);
void __KernelSaveContext(PSPThreadContext *ctx, bool vfpuEnabled);
void __KernelLoadContext(PSPThreadContext *ctx, bool vfpuEnabled);
u32 __KernelResumeThreadFromWait(SceUID threadID, u32 retval); // can return an error value
u32 __KernelResumeThreadFromWait(SceUID threadID, u64 retval);
@@ -205,7 +204,8 @@ void __KernelReturnFromExtendStack();
void __KernelIdle();
u32 __KernelMipsCallReturnAddress();
u32 HLEMipsCallReturnAddress();
u32 __KernelCallbackReturnAddress();
u32 __KernelInterruptReturnAddress(); // TODO: remove
SceUID sceKernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg);
@@ -216,10 +216,10 @@ int sceKernelGetCallbackCount(SceUID cbId);
void sceKernelCheckCallback();
int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr);
class Action;
class PSPAction;
// Not an official Callback object, just calls a mips function on the current thread.
void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter);
void __KernelDirectMipsCall(u32 entryPoint, PSPAction *afterAction, u32 args[], int numargs, bool reschedAfter);
void __KernelReturnFromMipsCall(); // Called as HLE function
bool __KernelInCallback();
@@ -228,8 +228,8 @@ bool __KernelInCallback();
bool __KernelCheckCallbacks();
bool __KernelForceCallbacks();
bool __KernelCurHasReadyCallbacks();
void __KernelSwitchContext(Thread *target, const char *reason);
bool __KernelExecutePendingMipsCalls(Thread *currentThread, bool reschedAfter);
void __KernelSwitchContext(PSPThread *target, const char *reason);
bool __KernelExecutePendingMipsCalls(PSPThread *currentThread, bool reschedAfter);
void __KernelNotifyCallback(SceUID cbId, int notifyArg);
// Switch to an idle / non-user thread, if not already on one.
@@ -243,8 +243,8 @@ u32 __KernelSetThreadRA(SceUID threadID, u32 nid);
// A call into game code. These can be pending on a thread.
// Similar to Callback-s (NOT CallbackInfos) in JPCSP.
typedef Action *(*ActionCreator)();
Action *__KernelCreateAction(int actionType);
typedef PSPAction *(*ActionCreator)();
PSPAction *__KernelCreateAction(int actionType);
int __KernelRegisterActionType(ActionCreator creator);
void __KernelRestoreActionType(int actionType, ActionCreator creator);
@@ -258,7 +258,7 @@ struct MipsCall {
u32 cbId;
u32 args[6];
int numArgs;
Action *doAfter;
PSPAction *doAfter;
u32 savedPc;
u32 savedV0;
u32 savedV1;
@@ -279,10 +279,10 @@ struct MipsCall {
}
};
class Action
class PSPAction
{
public:
virtual ~Action() {}
virtual ~PSPAction() {}
virtual void run(MipsCall &call) = 0;
virtual void DoState(PointerWrap &p) = 0;
int actionTypeID;
@@ -300,7 +300,7 @@ enum ThreadStatus
THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
};
void __KernelChangeThreadState(Thread *thread, ThreadStatus newStatus);
void __KernelChangeThreadState(PSPThread *thread, ThreadStatus newStatus);
typedef void (*ThreadCallback)(SceUID threadID);
void __KernelListenThreadEnd(ThreadCallback callback);
+11 -3
View File
@@ -355,11 +355,11 @@ static void AnalyzeMpeg(u8 *buffer, u32 validSize, MpegContext *ctx) {
INFO_LOG(ME, "First timestamp: %lld, Last timestamp: %lld", ctx->mpegFirstTimestamp, ctx->mpegLastTimestamp);
}
class PostPutAction : public Action {
class PostPutAction : public PSPAction {
public:
PostPutAction() {}
void setRingAddr(u32 ringAddr) { ringAddr_ = ringAddr; }
static Action *Create() { return new PostPutAction; }
static PSPAction *Create() { return new PostPutAction; }
void DoState(PointerWrap &p) override {
auto s = p.Section("PostPutAction", 1);
if (!s)
@@ -1524,7 +1524,7 @@ static u32 sceMpegRingbufferPut(u32 ringbufferAddr, int numPackets, int availabl
int writeOffset = ringbuffer->packetsWritePos % (s32)ringbuffer->packets;
u32 packetsThisRound = std::min(numPackets, (s32)ringbuffer->packets - writeOffset);
u32 args[3] = {(u32)ringbuffer->data + (u32)writeOffset * 2048, packetsThisRound, (u32)ringbuffer->callback_args};
__KernelDirectMipsCall(ringbuffer->callback_addr, action, args, 3, false);
hleEnqueueCall(ringbuffer->callback_addr, 3, args, action);
} else {
ERROR_LOG_REPORT(ME, "sceMpegRingbufferPut: callback_addr zero");
}
@@ -1939,6 +1939,14 @@ static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth
DEBUG_LOG(ME, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x)", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr);
if (frameWidth == 0) {
if (!ctx->defaultFrameWidth) {
frameWidth = ctx->avc.avcDetailFrameWidth;
} else {
frameWidth = ctx->defaultFrameWidth;
}
}
int x = Memory::Read_U32(rangeAddr);
int y = Memory::Read_U32(rangeAddr + 4);
int width = Memory::Read_U32(rangeAddr + 8);
+79 -17
View File
@@ -28,6 +28,7 @@
#include "Common/ChunkFile.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/MIPS/MIPS.h"
#include "Core/Config.h"
#include "Core/MemMapHelpers.h"
@@ -47,6 +48,9 @@ static bool netInetInited;
static bool netApctlInited;
u32 netDropRate = 0;
u32 netDropDuration = 0;
u32 netPoolAddr = 0;
u32 netThread1Addr = 0;
u32 netThread2Addr = 0;
static struct SceNetMallocStat netMallocStat;
@@ -239,14 +243,13 @@ static void __UpdateApctlHandlers(int oldState, int newState, int flag, int erro
for(std::map<int, ApctlHandler>::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) {
args[4] = it->second.argument;
__KernelDirectMipsCall(it->second.entryPoint, NULL, args, 5, true);
hleEnqueueCall(it->second.entryPoint, 5, args);
}
}
// This feels like a dubious proposition, mostly...
void __NetDoState(PointerWrap &p) {
auto s = p.Section("sceNet", 1, 2);
auto s = p.Section("sceNet", 1, 3);
if (!s)
return;
@@ -262,6 +265,28 @@ void __NetDoState(PointerWrap &p) {
p.Do(netDropRate);
p.Do(netDropDuration);
}
if (s < 3) {
netPoolAddr = 0;
netThread1Addr = 0;
netThread2Addr = 0;
} else {
p.Do(netPoolAddr);
p.Do(netThread1Addr);
p.Do(netThread2Addr);
}
}
static inline u32 AllocUser(u32 size, bool fromTop, const char *name) {
u32 addr = userMemory.Alloc(size, fromTop, name);
if (addr == -1)
return 0;
return addr;
}
static inline void FreeUser(u32 &addr) {
if (addr != 0)
userMemory.Free(addr);
addr = 0;
}
static u32 sceNetTerm() {
@@ -271,37 +296,76 @@ static u32 sceNetTerm() {
WARN_LOG(SCENET, "sceNetTerm()");
netInited = false;
FreeUser(netPoolAddr);
FreeUser(netThread1Addr);
FreeUser(netThread2Addr);
return 0;
}
// TODO: should that struct actually be initialized here?
static u32 sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) {
// May need to Terminate old one first since the game (ie. GTA:VCS) might not called sceNetTerm before the next sceNetInit and behave strangely
if (netInited)
static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) {
// TODO: The correct behavior is actually to allocate more and leak the other threads/pool.
// But we reset here for historic reasons (GTA:VCS potentially triggers this.)
if (netInited)
sceNetTerm();
if (poolSize == 0) {
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid pool size");
} else if (calloutPri < 0x08 || calloutPri > 0x77) {
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "invalid callout thread priority");
} else if (netinitPri < 0x08 || netinitPri > 0x77) {
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "invalid init thread priority");
}
// TODO: Should also start the threads, probably? For now, let's just allocate.
// TODO: Respect the stack size if firmware set to 1.50?
u32 stackSize = 4096;
netThread1Addr = AllocUser(stackSize, true, "netstack1");
if (netThread1Addr == 0) {
return hleLogError(SCENET, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate thread");
}
netThread2Addr = AllocUser(stackSize, true, "netstack2");
if (netThread2Addr == 0) {
FreeUser(netThread1Addr);
return hleLogError(SCENET, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate thread");
}
netPoolAddr = AllocUser(poolSize, false, "netpool");
if (netPoolAddr == 0) {
FreeUser(netThread1Addr);
FreeUser(netThread2Addr);
return hleLogError(SCENET, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate pool");
}
WARN_LOG(SCENET, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, currentMIPS->pc);
netInited = true;
netMallocStat.maximum = poolSize;
netMallocStat.free = poolSize;
netMallocStat.pool = 0;
return 0;
return hleLogSuccessI(SCENET, 0);
}
static u32 sceWlanGetEtherAddr(u32 addrAddr) {
if (!Memory::IsValidRange(addrAddr, 6)) {
// More correctly, it should crash.
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "illegal address");
}
u8 *addr = Memory::GetPointer(addrAddr);
// Read MAC Address from config
uint8_t mac[6] = {0};
if (PPSSPP_ID > 1) {
memset(&mac, PPSSPP_ID, sizeof(mac));
} else if (!ParseMacAddress(g_Config.sMACAddress.c_str(), mac)) {
} else if (!ParseMacAddress(g_Config.sMACAddress.c_str(), addr)) {
ERROR_LOG(SCENET, "Error parsing mac address %s", g_Config.sMACAddress.c_str());
Memory::Memset(addrAddr, 0, 6);
} else {
CBreakPoints::ExecMemCheck(addrAddr, true, 6, currentMIPS->pc);
}
DEBUG_LOG(SCENET, "sceWlanGetEtherAddr(%08x)", addrAddr);
for (int i = 0; i < 6; i++)
Memory::Write_U8(mac[i], addrAddr + i);
return 0;
return hleLogSuccessI(SCENET, hleDelayResult(0, "get ether mac", 200));
}
static u32 sceNetGetLocalEtherAddr(u32 addrAddr) {
@@ -309,13 +373,11 @@ static u32 sceNetGetLocalEtherAddr(u32 addrAddr) {
}
static u32 sceWlanDevIsPowerOn() {
DEBUG_LOG(SCENET, "UNTESTED sceWlanDevIsPowerOn()");
return g_Config.bEnableWlan ? 1 : 0;
return hleLogSuccessVerboseI(SCENET, g_Config.bEnableWlan ? 1 : 0);
}
static u32 sceWlanGetSwitchState() {
VERBOSE_LOG(SCENET, "sceWlanGetSwitchState()");
return g_Config.bEnableWlan ? 1 : 0;
return hleLogSuccessVerboseI(SCENET, g_Config.bEnableWlan ? 1 : 0);
}
// Probably a void function, but often returns a useful value.
@@ -638,7 +700,7 @@ static int sceNetSetDropRate(u32 dropRate, u32 dropDuration)
}
const HLEFunction sceNet[] = {
{0X39AF39A6, &WrapU_UUUUU<sceNetInit>, "sceNetInit", 'x', "xxxxx"},
{0X39AF39A6, &WrapI_UUUUU<sceNetInit>, "sceNetInit", 'i', "xxxxx"},
{0X281928A9, &WrapU_V<sceNetTerm>, "sceNetTerm", 'x', "" },
{0X89360950, &WrapI_UU<sceNetEtherNtostr>, "sceNetEtherNtostr", 'i', "xx" },
{0XD27961C9, &WrapI_UU<sceNetEtherStrton>, "sceNetEtherStrton", 'i', "xx" },
+8 -10
View File
@@ -160,8 +160,6 @@ void __NetAdhocInit() {
}
u32 sceNetAdhocInit() {
// Library uninitialized
INFO_LOG(SCENET, "sceNetAdhocInit() at %08x", currentMIPS->pc);
if (!netAdhocInited) {
// Clear Translator Memory
memset(&pdp, 0, sizeof(pdp));
@@ -173,17 +171,17 @@ u32 sceNetAdhocInit() {
// Create fake PSP Thread for callback
// 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, false);
// TODO: This should probably be a user thread, but maybe from sceNetAdhocctlInit?
threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x10, 0x1000, PSP_THREAD_ATTR_KERNEL, 0, true);
if (threadAdhocID > 0) {
__KernelStartThread(threadAdhocID, 0, 0);
}
// Return Success
return 0;
return hleLogSuccessInfoI(SCENET, 0, "at %08x", currentMIPS->pc);
}
// Already initialized
return ERROR_NET_ADHOC_ALREADY_INITIALIZED;
return hleLogWarning(SCENET, ERROR_NET_ADHOC_ALREADY_INITIALIZED, "already initialized");
}
static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) {
@@ -1424,7 +1422,6 @@ int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type,
}
int sceNetAdhocTerm() {
INFO_LOG(SCENET, "sceNetAdhocTerm()");
// WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup all the sockets right?
if (netAdhocctlInited) sceNetAdhocctlTerm();
@@ -1453,10 +1450,11 @@ int sceNetAdhocTerm() {
// if (_manage_modules != 0) sceUtilityUnloadModule(PSP_MODULE_NET_INET);
// Library shutdown
netAdhocInited = false;
return 0;
return hleLogSuccessInfoI(SCENET, 0);
} else {
// Seems to return this when called a second time after being terminated without another initialisation
return SCE_KERNEL_ERROR_LWMUTEX_NOT_FOUND;
// TODO: Reportedly returns SCE_KERNEL_ERROR_LWMUTEX_NOT_FOUND in some cases?
// Only seen returning 0 in tests.
return hleLogWarning(SCENET, 0, "already uninitialized");
}
}
+3 -3
View File
@@ -234,10 +234,10 @@ public:
bool HasReachedEnd() {
// The pts are ignored - the end is when we're out of data.
return mediaengine->IsVideoEnd() && mediaengine->IsNoAudioData();
return mediaengine->IsVideoEnd() && (mediaengine->IsNoAudioData() || !mediaengine->IsActuallyPlayingAudio());
}
u32 filehandle;
int filehandle;
u32 fileoffset;
int readSize;
int streamSize;
@@ -1617,7 +1617,7 @@ static int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr)
bool doVideoStep = true;
if (psmfplayer->playMode == PSMF_PLAYER_MODE_PAUSE) {
doVideoStep = false;
} else if (!psmfplayer->mediaengine->IsNoAudioData()) {
} else if (!psmfplayer->mediaengine->IsNoAudioData() && psmfplayer->mediaengine->IsActuallyPlayingAudio()) {
s64 deltapts = psmfplayer->mediaengine->getVideoTimeStamp() - psmfplayer->mediaengine->getAudioTimeStamp();
// Don't skip the very first frame, sometimes audio starts with an early timestamp.
if (deltapts > 0 && psmfplayer->mediaengine->getVideoTimeStamp() > 0) {
+11 -4
View File
@@ -37,6 +37,13 @@
#include "Core/HLE/sceKernel.h"
#include "Core/HLE/sceRtc.h"
#ifdef HAVE_LIBNX
// I guess that works...
#define setenv(x, y, z) (void*)0
#define tzset() (void*)0
#define unsetenv(x) (void*)0
#endif // HAVE_LIBNX
// This is a base time that everything is relative to.
// This way, time doesn't move strangely with savestates, turbo speed, etc.
static PSPTimeval rtcBaseTime;
@@ -494,7 +501,7 @@ static int sceRtcConvertLocalTimeToUTC(u32 tickLocalPtr,u32 tickUTCPtr)
long timezone_val;
_get_timezone(&timezone_val);
srcTick -= -timezone_val * 1000000ULL;
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux)
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux) && !defined(HAVE_LIBNX)
time_t timezone = 0;
tm *time = localtime(&timezone);
srcTick -= time->tm_gmtoff*1000000ULL;
@@ -519,7 +526,7 @@ static int sceRtcConvertUtcToLocalTime(u32 tickUTCPtr,u32 tickLocalPtr)
long timezone_val;
_get_timezone(&timezone_val);
srcTick += -timezone_val * 1000000ULL;
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux)
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux) && !defined(HAVE_LIBNX)
time_t timezone = 0;
tm *time = localtime(&timezone);
srcTick += time->tm_gmtoff*1000000ULL;
@@ -1054,7 +1061,7 @@ static int sceRtcFormatRFC2822LocalTime(u32 outPtr, u32 srcTickPtr)
long timezone_val;
_get_timezone(&timezone_val);
tz_seconds = -timezone_val;
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux)
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux) && !defined(HAVE_LIBNX)
time_t timezone = 0;
tm *time = localtime(&timezone);
tz_seconds = time->tm_gmtoff;
@@ -1091,7 +1098,7 @@ static int sceRtcFormatRFC3339LocalTime(u32 outPtr, u32 srcTickPtr)
long timezone_val;
_get_timezone(&timezone_val);
tz_seconds = -timezone_val;
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux)
#elif !defined(_AIX) && !defined(__sgi) && !defined(__hpux) && !defined(HAVE_LIBNX)
time_t timezone = 0;
tm *time = localtime(&timezone);
tz_seconds = time->tm_gmtoff;
+1 -1
View File
@@ -269,7 +269,7 @@ static u32 sceSasGetEndFlag(u32 core) {
endFlag |= (1 << i);
}
DEBUG_LOG(SCESAS, "%08x=sceSasGetEndFlag(%08x)", endFlag, core);
VERBOSE_LOG(SCESAS, "%08x=sceSasGetEndFlag(%08x)", endFlag, core);
return endFlag;
}
+37 -34
View File
@@ -470,55 +470,46 @@ static int sceUtilityOskGetStatus()
}
static int sceUtilityNetconfInitStart(u32 paramsAddr)
{
static int sceUtilityNetconfInitStart(u32 paramsAddr) {
if (currentDialogActive && currentDialogType != UTILITY_DIALOG_NET) {
WARN_LOG(SCEUTILITY, "sceUtilityNetconfInitStart(%08x): wrong dialog type", paramsAddr);
return SCE_ERROR_UTILITY_WRONG_TYPE;
return hleLogWarning(SCEUTILITY, SCE_ERROR_UTILITY_WRONG_TYPE, "wrong dialog type");
}
oldStatus = 100;
currentDialogType = UTILITY_DIALOG_NET;
currentDialogActive = true;
int ret = netDialog.Init(paramsAddr);
INFO_LOG(SCEUTILITY, "%08x=sceUtilityNetconfInitStart(%08x)", ret, paramsAddr);
return ret;
currentDialogActive = true;
return hleLogSuccessInfoI(SCEUTILITY, netDialog.Init(paramsAddr));
}
static int sceUtilityNetconfShutdownStart()
{
static int sceUtilityNetconfShutdownStart() {
if (currentDialogType != UTILITY_DIALOG_NET) {
WARN_LOG(SCEUTILITY, "sceUtilityNetconfShutdownStart(): wrong dialog type");
return SCE_ERROR_UTILITY_WRONG_TYPE;
return hleLogWarning(SCEUTILITY, SCE_ERROR_UTILITY_WRONG_TYPE, "wrong dialog type");
}
currentDialogActive = false;
int ret = netDialog.Shutdown();
DEBUG_LOG(SCEUTILITY, "%08x=sceUtilityNetconfShutdownStart()",ret);
return ret;
return hleLogSuccessI(SCEUTILITY, netDialog.Shutdown());
}
static int sceUtilityNetconfUpdate(int animSpeed)
{
int ret = netDialog.Update(animSpeed);
ERROR_LOG(SCEUTILITY, "UNIMPL %08x=sceUtilityNetconfUpdate(%i)", ret, animSpeed);
return ret;
}
static int sceUtilityNetconfGetStatus()
{
// Spam in Danball Senki BOOST
static int sceUtilityNetconfUpdate(int animSpeed) {
if (currentDialogType != UTILITY_DIALOG_NET) {
DEBUG_LOG(SCEUTILITY, "sceUtilityNetconfGetStatus(): wrong dialog type");
return SCE_ERROR_UTILITY_WRONG_TYPE;
return hleLogWarning(SCEUTILITY, SCE_ERROR_UTILITY_WRONG_TYPE, "wrong dialog type");
}
return hleLogSuccessI(SCEUTILITY, netDialog.Update(animSpeed));
}
static int sceUtilityNetconfGetStatus() {
if (currentDialogType != UTILITY_DIALOG_NET) {
// Spam in Danball Senki BOOST.
return hleLogDebug(SCEUTILITY, SCE_ERROR_UTILITY_WRONG_TYPE, "wrong dialog type");
}
int status = netDialog.GetStatus();
if (oldStatus != status) {
oldStatus = status;
DEBUG_LOG(SCEUTILITY, "%08x=sceUtilityNetconfGetStatus()", status);
return hleLogSuccessI(SCEUTILITY, status);
}
return status;
return hleLogSuccessVerboseI(SCEUTILITY, status);
}
static int sceUtilityCheckNetParam(int id)
@@ -769,6 +760,18 @@ static u32 sceUtilityUnloadNetModule(u32 module)
return 0;
}
static int sceUtilityNpSigninInitStart(u32 paramsPtr) {
return hleLogError(SCEUTILITY, 0, "not implemented");
}
static int sceUtilityNpSigninUpdate(int animSpeed) {
return hleLogError(SCEUTILITY, 0, "not implemented");
}
static int sceUtilityNpSigninGetStatus() {
return hleLogError(SCEUTILITY, 0, "not implemented");
}
static void sceUtilityInstallInitStart(u32 unknown)
{
WARN_LOG_REPORT(SCEUTILITY, "UNIMPL sceUtilityInstallInitStart()");
@@ -934,7 +937,7 @@ const HLEFunction sceUtility[] =
{0X0251B134, &WrapI_U<sceUtilityScreenshotInitStart>, "sceUtilityScreenshotInitStart", 'i', "x" },
{0XF9E0008C, &WrapI_V<sceUtilityScreenshotShutdownStart>, "sceUtilityScreenshotShutdownStart", 'i', "" },
{0XAB083EA9, &WrapI_U<sceUtilityScreenshotUpdate>, "sceUtilityScreenshotUpdate", 'i', "x" },
{0XAB083EA9, &WrapI_U<sceUtilityScreenshotUpdate>, "sceUtilityScreenshotUpdate", 'i', "i" },
{0XD81957B7, &WrapI_V<sceUtilityScreenshotGetStatus>, "sceUtilityScreenshotGetStatus", 'i', "" },
{0X86A03A27, &WrapI_U<sceUtilityScreenshotContStart>, "sceUtilityScreenshotContStart", 'i', "x" },
@@ -947,10 +950,10 @@ const HLEFunction sceUtility[] =
{0XB57E95D9, &WrapI_V<sceUtilityGamedataInstallGetStatus>, "sceUtilityGamedataInstallGetStatus", 'i', "" },
{0X180F7B62, &WrapI_V<sceUtilityGamedataInstallAbort>, "sceUtilityGamedataInstallAbort", 'i', "" },
{0X16D02AF0, nullptr, "sceUtilityNpSigninInitStart", '?', "" },
{0XE19C97D6, nullptr, "sceUtilityNpSigninShutdownStart", '?', "" },
{0XF3FBC572, nullptr, "sceUtilityNpSigninUpdate", '?', "" },
{0X86ABDB1B, nullptr, "sceUtilityNpSigninGetStatus", '?', "" },
{0X16D02AF0, &WrapI_U<sceUtilityNpSigninInitStart>, "sceUtilityNpSigninInitStart", 'i', "x" },
{0XE19C97D6, nullptr, "sceUtilityNpSigninShutdownStart", 'i', "" },
{0XF3FBC572, &WrapI_I<sceUtilityNpSigninUpdate>, "sceUtilityNpSigninUpdate", 'i', "i" },
{0X86ABDB1B, &WrapI_V<sceUtilityNpSigninGetStatus>, "sceUtilityNpSigninGetStatus", 'i', "" },
{0X1281DA8E, &WrapV_U<sceUtilityInstallInitStart>, "sceUtilityInstallInitStart", 'v', "x" },
{0X5EF1C24A, nullptr, "sceUtilityInstallShutdownStart", '?', "" },
+10 -9
View File
@@ -231,10 +231,10 @@ void *v4l_loop(void *data) {
if (ioctl(v4l_fd, VIDIOC_DQBUF, &buf) == -1) {
ERROR_LOG(HLE, "VIDIOC_DQBUF; errno=%d(%s)", errno, strerror(errno));
switch (errno) {
case EAGAIN:
continue;
default:
return NULL;
case EAGAIN:
continue;
default:
return nullptr;
}
}
@@ -265,9 +265,10 @@ void *v4l_loop(void *data) {
buf.memory = V4L2_MEMORY_MMAP;
if (ioctl(v4l_fd, VIDIOC_QBUF, &buf) == -1) {
ERROR_LOG(HLE, "VIDIOC_QBUF");
return NULL;
return nullptr;
}
}
return nullptr;
}
int __v4l_startCapture(int ideal_width, int ideal_height) {
@@ -338,10 +339,10 @@ int __v4l_startCapture(int ideal_width, int ideal_height) {
frmsize.index++;
if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
INFO_LOG(HLE, "V4L2: frame size supported: %dx%d", frmsize.discrete.width, frmsize.discrete.height);
if (frmsize.discrete.width >= ideal_width && frmsize.discrete.height >= ideal_height
&& fmt.fmt.pix.width == 0 && fmt.fmt.pix.height == 0
|| frmsize.discrete.width >= ideal_width && frmsize.discrete.height >= ideal_height
&& frmsize.discrete.width < fmt.fmt.pix.width && frmsize.discrete.height < fmt.fmt.pix.height) {
bool matchesIdeal = frmsize.discrete.width >= ideal_width && frmsize.discrete.height >= ideal_height;
bool zeroPix = fmt.fmt.pix.width == 0 && fmt.fmt.pix.height == 0;
bool pixLarger = frmsize.discrete.width < fmt.fmt.pix.width && frmsize.discrete.height < fmt.fmt.pix.height;
if (matchesIdeal && (zeroPix || pixLarger)) {
fmt.fmt.pix.width = frmsize.discrete.width;
fmt.fmt.pix.height = frmsize.discrete.height;
}
+4
View File
@@ -992,6 +992,10 @@ bool MediaEngine::IsNoAudioData() {
return !m_demux->hasNextAudioFrame(NULL, NULL, NULL, NULL);
}
bool MediaEngine::IsActuallyPlayingAudio() {
return getAudioTimeStamp() >= 0;
}
s64 MediaEngine::getVideoTimeStamp() {
return m_videopts;
}
+1
View File
@@ -89,6 +89,7 @@ public:
bool IsVideoEnd() { return m_isVideoEnd; }
bool IsNoAudioData();
bool IsActuallyPlayingAudio();
int VideoWidth() { return m_desWidth; }
int VideoHeight() { return m_desHeight; }
+7 -3
View File
@@ -1022,6 +1022,8 @@ skip:
bool ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols) {
std::lock_guard<std::recursive_mutex> guard(functions_lock);
FunctionsVector new_functions;
AnalyzedFunction currentFunction = {startAddr};
u32 furthestBranch = 0;
@@ -1142,7 +1144,7 @@ skip:
}
}
functions.push_back(currentFunction);
new_functions.push_back(currentFunction);
furthestBranch = 0;
addr += 4;
@@ -1157,10 +1159,10 @@ skip:
if (addr <= endAddr) {
currentFunction.end = addr + 4;
functions.push_back(currentFunction);
new_functions.push_back(currentFunction);
}
for (auto iter = functions.begin(); iter != functions.end(); iter++) {
for (auto iter = new_functions.begin(); iter != new_functions.end(); iter++) {
iter->size = iter->end - iter->start + 4;
if (insertSymbols && !iter->foundInSymbolMap) {
char temp[256];
@@ -1168,6 +1170,8 @@ skip:
}
}
// Concatenate the new functions to the end of the old ones.
functions.insert(functions.end(), new_functions.begin(), new_functions.end());
return insertSymbols;
}
+1 -1
View File
@@ -249,7 +249,7 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
}
bool hasEncrypted = false;
u32 fd;
int fd;
if ((fd = pspFileSystem.OpenFile(bootpath, FILEACCESS_READ)) >= 0)
{
u8 head[4];
+1 -1
View File
@@ -21,7 +21,7 @@
#ifdef USING_QT_UI
#include <QtGui/QImage>
#else
#include <libpng17/png.h>
#include <png.h>
#include "ext/jpge/jpge.h"
#endif
+7 -1
View File
@@ -220,6 +220,12 @@ void CPU_Init() {
// ERROR_LOG(LOADER, "PBP directory resolution failed.");
InitMemoryForGamePBP(loadedFile);
break;
case IdentifiedFileType::PSP_ELF:
if (Memory::g_PSPModel != PSP_MODEL_FAT) {
INFO_LOG(LOADER, "ELF, using full PSP-2000 memory access");
Memory::g_MemorySize = Memory::RAM_DOUBLE_SIZE;
}
break;
default:
break;
}
@@ -609,7 +615,7 @@ void InitSysDirectories() {
INFO_LOG(COMMON, "Memstick directory not present, creating at '%s'", g_Config.memStickDirectory.c_str());
}
const std::string testFile = g_Config.memStickDirectory + "/_writable_test.$$$";
const std::string testFile = g_Config.memStickDirectory + "_writable_test.$$$";
// If any directory is read-only, fall back to the Documents directory.
// We're screwed anyway if we can't write to Documents, or can't detect it.
+1 -1
View File
@@ -18,7 +18,7 @@
#ifdef USING_QT_UI
#include <QtGui/QImage>
#else
#include <libpng17/png.h>
#include <png.h>
#endif
#include <algorithm>
+1 -1
View File
@@ -55,7 +55,7 @@ std::string GameManager::GetTempFilename() const {
GetTempFileName(tempPath, L"PSP", 1, buffer);
return ConvertWStringToUTF8(buffer);
#else
return g_Config.memStickDirectory + "/ppsspp.dl";
return g_Config.memStickDirectory + "ppsspp.dl";
#endif
}
+324 -75
View File
@@ -18,6 +18,9 @@
#include <algorithm>
#include "base/stringutil.h"
#include "file/vfs.h"
#include "gfx/texture_atlas.h"
#include "gfx_es2/draw_text.h"
#include "image/zim_load.h"
#include "image/png_load.h"
#include "util/text/utf8.h"
@@ -36,6 +39,8 @@
#include "Core/MemMapHelpers.h"
#include "Core/System.h"
Atlas g_ppge_atlas;
static u32 atlasPtr;
static int atlasWidth;
static int atlasHeight;
@@ -99,6 +104,38 @@ static AtlasCharLine char_one_line;
static AtlasLineArray char_lines;
static AtlasTextMetrics char_lines_metrics;
static bool textDrawerInited = false;
static TextDrawer *textDrawer = nullptr;
struct PPGeTextDrawerCacheKey {
bool operator < (const PPGeTextDrawerCacheKey &other) const {
if (align != other.align)
return align < other.align;
if (wrapWidth != other.wrapWidth)
return wrapWidth < other.wrapWidth;
return text < other.text;
}
std::string text;
int align;
float wrapWidth;
};
struct PPGeTextDrawerImage {
TextStringEntry entry;
u32 ptr;
};
std::map<PPGeTextDrawerCacheKey, PPGeTextDrawerImage> textDrawerImages;
// Overwrite the current text lines buffer so it can be drawn later.
void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale,
int WrapType = PPGE_LINE_NONE, int wrapWidth = 0);
// These functions must be called between PPGeBegin and PPGeEnd.
// Draw currently buffered text using the state from PPGeGetTextBoundingBox() call.
// Clears the buffer and state when done.
void PPGeDrawCurrentText(u32 color = 0xFFFFFFFF);
void PPGeSetTexture(u32 dataAddr, int width, int height);
//only 0xFFFFFF of data is used
static void WriteCmd(u8 cmd, u32 data) {
Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr);
@@ -125,18 +162,18 @@ static void BeginVertexData() {
vertexStart = dataWritePtr;
}
static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color = 0xFFFFFFFF) {
static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color = 0xFFFFFFFF, float off = -0.5f) {
if (g_RemasterMode) {
PPGeRemasterVertex vtx;
vtx.x = x - 0.5f; vtx.y = y - 0.5f; vtx.z = 0;
vtx.u = u * tw - 0.5f; vtx.v = v * th - 0.5f;
vtx.x = x + off; vtx.y = y + off; vtx.z = 0;
vtx.u = u * tw + off; vtx.v = v * th + off;
vtx.color = color;
Memory::WriteStruct(dataWritePtr, &vtx);
dataWritePtr += sizeof(vtx);
} else {
PPGeVertex vtx;
vtx.x = x - 0.5f; vtx.y = y - 0.5f; vtx.z = 0;
vtx.u = u * tw - 0.5f; vtx.v = v * th - 0.5f;
vtx.x = x + off; vtx.y = y + off; vtx.z = 0;
vtx.u = u * tw + off; vtx.v = v * th + off;
vtx.color = color;
Memory::WriteStruct(dataWritePtr, &vtx);
dataWritePtr += sizeof(vtx);
@@ -171,23 +208,30 @@ void __PPGeSetupListArgs()
}
}
void __PPGeInit()
{
void __PPGeInit() {
// PPGe isn't really important for headless, and LoadZIM takes a long time.
if (PSP_CoreParameter().gpuCore == GPUCORE_NULL || host->ShouldSkipUI()) {
// Let's just not bother.
dlPtr = 0;
NOTICE_LOG(SCEGE, "Not initializing PPGe - GPU is NullGpu");
return;
}
u8 *imageData[12];
int width[12];
int height[12];
int flags;
if (!LoadZIM("ppge_atlas.zim", width, height, &flags, imageData)) {
bool skipZIM = PSP_CoreParameter().gpuCore == GPUCORE_NULL || host->ShouldSkipUI();
u8 *imageData[12]{};
int width[12]{};
int height[12]{};
int flags = 0;
bool loadedZIM = !skipZIM && LoadZIM("ppge_atlas.zim", width, height, &flags, imageData);
if (!skipZIM && !loadedZIM) {
PanicAlert("Failed to load ppge_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
ERROR_LOG(SCEGE, "PPGe init failed - no atlas texture. PPGe stuff will not be drawn.");
return;
}
if (loadedZIM) {
size_t atlas_data_size;
uint8_t *atlas_data;
if (!g_ppge_atlas.IsMetadataLoaded()) {
atlas_data = VFSReadFile("ppge_atlas.meta", &atlas_data_size);
if (atlas_data)
g_ppge_atlas.Load(atlas_data, atlas_data_size);
delete[] atlas_data;
}
}
u32 atlasSize = height[0] * width[0] / 2; // it's a 4-bit paletted texture in ram
@@ -196,7 +240,7 @@ void __PPGeInit()
dlPtr = __PPGeDoAlloc(dlSize, false, "PPGe Display List");
dataPtr = __PPGeDoAlloc(dataSize, false, "PPGe Vertex Data");
__PPGeSetupListArgs();
atlasPtr = __PPGeDoAlloc(atlasSize, false, "PPGe Atlas Texture");
atlasPtr = atlasSize == 0 ? 0 : __PPGeDoAlloc(atlasSize, false, "PPGe Atlas Texture");
palette = __PPGeDoAlloc(paletteSize, false, "PPGe Texture Palette");
// Generate 16-greyscale palette. All PPGe graphics are greyscale so we can use a tiny paletted texture.
@@ -206,7 +250,7 @@ void __PPGeInit()
}
const u32_le *imagePtr = (u32_le *)imageData[0];
u8 *ramPtr = (u8 *)Memory::GetPointer(atlasPtr);
u8 *ramPtr = atlasPtr == 0 ? nullptr : (u8 *)Memory::GetPointer(atlasPtr);
// Palettize to 4-bit, the easy way.
for (int i = 0; i < width[0] * height[0] / 2; i++) {
@@ -221,13 +265,18 @@ void __PPGeInit()
free(imageData[0]);
// We can't create it here, because Android needs it on the right thread.
textDrawerInited = false;
textDrawer = nullptr;
textDrawerImages.clear();
DEBUG_LOG(SCEGE, "PPGe drawing library initialized. DL: %08x Data: %08x Atlas: %08x (%i) Args: %08x",
dlPtr, dataPtr, atlasPtr, atlasSize, listArgs.ptr);
}
void __PPGeDoState(PointerWrap &p)
{
auto s = p.Section("PPGeDraw", 1, 2);
auto s = p.Section("PPGeDraw", 1, 3);
if (!s)
return;
@@ -245,6 +294,30 @@ void __PPGeDoState(PointerWrap &p)
p.Do(listArgs);
}
if (s >= 3) {
uint32_t sz = (uint32_t)textDrawerImages.size();
p.Do(sz);
switch (p.mode) {
case PointerWrap::MODE_READ:
textDrawerImages.clear();
for (uint32_t i = 0; i < sz; ++i) {
// We only care about the pointers, so we can free them. We'll decimate right away.
PPGeTextDrawerCacheKey key{ StringFromFormat("__savestate__%d", i), -1, -1 };
textDrawerImages[key] = PPGeTextDrawerImage{};
p.Do(textDrawerImages[key].ptr);
}
break;
default:
for (const auto &im : textDrawerImages) {
p.Do(im.second.ptr);
}
break;
}
} else {
textDrawerImages.clear();
}
p.Do(dlPtr);
p.Do(dlWritePtr);
p.Do(dlSize);
@@ -280,6 +353,9 @@ void __PPGeShutdown()
dlPtr = 0;
savedContextPtr = 0;
listArgs = 0;
delete textDrawer;
textDrawer = nullptr;
}
void PPGeBegin()
@@ -614,31 +690,63 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont,
return metrics;
}
void PPGeMeasureText(float *w, float *h, int *n,
const char *text, float scale, int WrapType, int wrapWidth)
{
const AtlasFont &atlasfont = *ppge_atlas.fonts[0];
static bool HasTextDrawer() {
// We create this on first use so it's on the correct thread.
if (textDrawerInited) {
return textDrawer != nullptr;
}
// TODO: Should we pass a draw_?
textDrawer = TextDrawer::Create(nullptr);
if (textDrawer) {
textDrawer->SetFontScale(1.0f, 1.0f);
textDrawer->SetForcedDPIScale(1.0f);
textDrawer->SetFont(g_Config.sFont.c_str(), 18, 0);
}
textDrawerInited = true;
return textDrawer != nullptr;
}
void PPGeMeasureText(float *w, float *h, const char *text, float scale, int WrapType, int wrapWidth) {
if (HasTextDrawer()) {
float mw, mh;
textDrawer->SetFontScale(scale, scale);
int dtalign = (WrapType & PPGE_LINE_WRAP_WORD) ? FLAG_WRAP_TEXT : 0;
if (WrapType & PPGE_LINE_USE_ELLIPSIS)
dtalign |= FLAG_ELLIPSIZE_TEXT;
Bounds b(0, 0, wrapWidth <= 0 ? 480.0f : wrapWidth, 272.0f);
textDrawer->MeasureStringRect(text, strlen(text), b, &mw, &mh, dtalign);
if (w)
*w = mw;
if (h)
*h = mh;
return;
}
if (!g_ppge_atlas.IsMetadataLoaded() || g_ppge_atlas.num_fonts < 1) {
if (w)
*w = 0;
if (h)
*h = 0;
return;
}
const AtlasFont &atlasfont = g_ppge_atlas.fonts[0];
AtlasTextMetrics metrics = BreakLines(text, atlasfont, 0, 0, 0, scale, scale, WrapType, wrapWidth, true);
if (w) *w = metrics.maxWidth;
if (h) *h = metrics.lineHeight;
if (n) *n = metrics.numLines;
if (h) *h = metrics.lineHeight * metrics.numLines;
}
void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale, int WrapType, int wrapWidth)
{
const AtlasFont &atlasfont = *ppge_atlas.fonts[0];
const AtlasFont &atlasfont = g_ppge_atlas.fonts[0];
if (!g_ppge_atlas.IsMetadataLoaded() || g_ppge_atlas.num_fonts < 1) {
return;
}
char_lines_metrics = BreakLines(text, atlasfont, x, y, align, scale, lineHeightScale, WrapType, wrapWidth, false);
}
void PPGeMeasureCurrentText(float *x, float *y, float *w, float *h, int *n)
{
if (x) *x = char_lines_metrics.x;
if (y) *y = char_lines_metrics.y;
if (w) *w = char_lines_metrics.maxWidth;
if (h) *h = char_lines_metrics.lineHeight;
if (n) *n = char_lines_metrics.numLines;
}
static void PPGeResetCurrentText() {
char_one_line.clear();
char_lines.clear();
@@ -672,8 +780,110 @@ void PPGeDrawCurrentText(u32 color)
PPGeResetCurrentText();
}
void PPGeDrawText(const char *text, float x, float y, int align, float scale, u32 color)
{
// Return a value such that (1 << value) >= x
int GetPow2(int x) {
#ifdef __GNUC__
int ret = 31 - __builtin_clz(x | 1);
if ((1 << ret) < x)
#else
int ret = 0;
while ((1 << ret) < x)
#endif
ret++;
return ret;
}
static PPGeTextDrawerImage PPGeGetTextImage(const char *text, int align, float scale, float maxWidth, bool wrap) {
int tdalign = (align & PPGE_ALIGN_HCENTER) ? ALIGN_HCENTER : 0;
tdalign |= FLAG_ELLIPSIZE_TEXT;
if (wrap) {
tdalign |= FLAG_WRAP_TEXT;
}
PPGeTextDrawerCacheKey key{ text, tdalign, maxWidth / scale };
PPGeTextDrawerImage im;
auto cacheItem = textDrawerImages.find(key);
if (cacheItem != textDrawerImages.end()) {
im = cacheItem->second;
cacheItem->second.entry.lastUsedFrame = gpuStats.numFlips;
} else {
std::vector<uint8_t> bitmapData;
textDrawer->SetFontScale(scale, scale);
Bounds b(0, 0, maxWidth, 272.0f);
std::string cleaned = ReplaceAll(text, "\r", "");
textDrawer->DrawStringBitmapRect(bitmapData, im.entry, Draw::DataFormat::R8_UNORM, cleaned.c_str(), b, tdalign);
int bufwBytes = ((im.entry.bmWidth + 31) / 32) * 16;
u32 sz = bufwBytes * (im.entry.bmHeight + 1);
u32 origSz = sz;
im.ptr = __PPGeDoAlloc(sz, true, "PPGeText");
if (bitmapData.size() & 1)
bitmapData.resize(bitmapData.size() + 1);
if (im.ptr) {
int wBytes = (im.entry.bmWidth + 1) / 2;
u8 *ramPtr = (u8 *)Memory::GetPointer(im.ptr);
for (int y = 0; y < im.entry.bmHeight; ++y) {
for (int x = 0; x < wBytes; ++x) {
uint8_t c1 = bitmapData[y * im.entry.bmWidth + x * 2];
uint8_t c2 = bitmapData[y * im.entry.bmWidth + x * 2 + 1];
// Convert this to 4-bit palette values.
ramPtr[y * bufwBytes + x] = (c2 & 0xF0) | (c1 >> 4);
}
if (bufwBytes != wBytes) {
memset(ramPtr + y * bufwBytes + wBytes, 0, bufwBytes - wBytes);
}
}
memset(ramPtr + im.entry.bmHeight * bufwBytes, 0, bufwBytes + sz - origSz);
}
im.entry.lastUsedFrame = gpuStats.numFlips;
textDrawerImages[key] = im;
}
return im;
}
static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, int align, float scale, u32 color) {
int bufw = ((im.entry.bmWidth + 31) / 32) * 32;
int wp2 = GetPow2(im.entry.bmWidth);
int hp2 = GetPow2(im.entry.bmHeight);
WriteCmd(GE_CMD_TEXADDR0, im.ptr & 0xFFFFF0);
WriteCmd(GE_CMD_TEXBUFWIDTH0, bufw | ((im.ptr & 0xFF000000) >> 8));
WriteCmd(GE_CMD_TEXSIZE0, wp2 | (hp2 << 8));
WriteCmd(GE_CMD_TEXFLUSH, 0);
float w = im.entry.width * scale;
float h = im.entry.height * scale;
if (align & PPGE_ALIGN_HCENTER)
x -= w / 2.0f;
else if (align & PPGE_ALIGN_RIGHT)
x -= w;
if (align & PPGE_ALIGN_VCENTER)
y -= h / 2.0f;
else if (align & PPGE_ALIGN_BOTTOM)
y -= h;
BeginVertexData();
float u1 = (float)im.entry.width / (1 << wp2);
float v1 = (float)im.entry.height / (1 << hp2);
Vertex(x, y, 0, 0, 1 << wp2, 1 << hp2, color, 0.0f);
Vertex(x + w, y + h, u1, v1, 1 << wp2, 1 << hp2, color, 0.0f);
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
PPGeSetDefaultTexture();
}
void PPGeDrawText(const char *text, float x, float y, int align, float scale, u32 color) {
if (HasTextDrawer()) {
PPGeTextDrawerImage im = PPGeGetTextImage(text, align, scale, 480.0f - x, false);
PPGeDrawTextImage(im, x, y, align, scale, color);
return;
}
PPGePrepareText(text, x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS);
PPGeDrawCurrentText(color);
}
@@ -707,10 +917,40 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl
s = StripTrailingWhite(s);
}
PPGePrepareText(s.c_str(), x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
int zoom = (PSP_CoreParameter().pixelHeight + 479) / 480;
float maxScaleDown = zoom == 1 ? 1.3f : 2.0f;
if (HasTextDrawer()) {
float actualWidth, actualHeight;
Bounds b(0, 0, wrapWidth <= 0 ? 480.0f - x : wrapWidth, wrapHeight);
int tdalign = (align & PPGE_ALIGN_HCENTER) ? ALIGN_HCENTER : 0;
textDrawer->SetFontScale(scale, scale);
textDrawer->MeasureStringRect(s.c_str(), s.size(), b, &actualWidth, &actualHeight, tdalign | FLAG_WRAP_TEXT);
if (wrapHeight != 0.0f && actualHeight > wrapHeight) {
// Cheap way to get the line height.
float oneLine, twoLines;
textDrawer->MeasureString("|", 1, &actualWidth, &oneLine);
textDrawer->MeasureStringRect("|\n|", 3, Bounds(0, 0, 480, 272), &actualWidth, &twoLines);
float lineHeight = twoLines - oneLine;
if (actualHeight > wrapHeight * maxScaleDown) {
float maxLines = floor(wrapHeight * maxScaleDown / lineHeight);
actualHeight = (maxLines + 1) * lineHeight;
// Add an ellipsis if it's just too long to be readable.
// On a PSP, it does this without scaling it down.
s = StripTrailingWhite(CropLinesToCount(s, (int)maxLines)) + "\n...";
}
scale *= wrapHeight / actualHeight;
}
PPGeTextDrawerImage im = PPGeGetTextImage(s.c_str(), align, scale, wrapWidth <= 0 ? 480.0f - x : wrapWidth, true);
PPGeDrawTextImage(im, x, y, align, scale, color);
return;
}
PPGePrepareText(s.c_str(), x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
float actualHeight = char_lines_metrics.lineHeight * char_lines_metrics.numLines;
if (wrapHeight != 0.0f && actualHeight > wrapHeight) {
if (actualHeight > wrapHeight * maxScaleDown) {
@@ -731,15 +971,16 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl
}
// Draws a "4-patch" for button-like things that can be resized
void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color)
{
void PPGeDraw4Patch(ImageID atlasImage, float x, float y, float w, float h, u32 color) {
if (!dlPtr)
return;
const AtlasImage &img = ppge_images[atlasImage];
float borderx = img.w / 20;
float bordery = img.h / 20;
float u1 = img.u1, uhalf = (img.u1 + img.u2) / 2, u2 = img.u2;
float v1 = img.v1, vhalf = (img.v1 + img.v2) / 2, v2 = img.v2;
const AtlasImage *img = g_ppge_atlas.getImage(atlasImage);
if (!img)
return;
float borderx = img->w / 20;
float bordery = img->h / 20;
float u1 = img->u1, uhalf = (img->u1 + img->u2) / 2, u2 = img->u2;
float v1 = img->v1, vhalf = (img->v1 + img->v2) / 2, v2 = img->v2;
float xmid1 = x + borderx;
float xmid2 = x + w - borderx;
float ymid1 = y + bordery;
@@ -771,8 +1012,7 @@ void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 colo
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}
void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color)
{
void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color) {
if (!dlPtr)
return;
@@ -787,29 +1027,35 @@ void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color)
}
// Just blits an image to the screen, multiplied with the color.
void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color)
void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color)
{
if (!dlPtr)
return;
const AtlasImage &img = ppge_atlas.images[atlasImage];
float w = img.w;
float h = img.h;
const AtlasImage *img = g_ppge_atlas.getImage(atlasImage);
if (!img) {
return;
}
float w = img->w;
float h = img->h;
BeginVertexData();
Vertex(x, y, img.u1, img.v1, atlasWidth, atlasHeight, color);
Vertex(x + w, y + h, img.u2, img.v2, atlasWidth, atlasHeight, color);
Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color);
Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color);
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}
void PPGeDrawImage(int atlasImage, float x, float y, float w, float h, int align, u32 color)
void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int align, u32 color)
{
if (!dlPtr)
return;
const AtlasImage &img = ppge_atlas.images[atlasImage];
const AtlasImage *img = g_ppge_atlas.getImage(atlasImage);
if (!img) {
return;
}
BeginVertexData();
Vertex(x, y, img.u1, img.v1, atlasWidth, atlasHeight, color);
Vertex(x + w, y + h, img.u2, img.v2, atlasWidth, atlasHeight, color);
Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color);
Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color);
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}
@@ -823,20 +1069,6 @@ void PPGeDrawImage(float x, float y, float w, float h, float u1, float v1, float
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}
// Return a value such that (1 << value) >= x
int GetPow2(int x)
{
#ifdef __GNUC__
int ret = 31 - __builtin_clz(x|1);
if ((1 << ret) < x)
#else
int ret = 0;
while ((1 << ret) < x)
#endif
ret++;
return ret;
}
void PPGeSetDefaultTexture()
{
WriteCmd(GE_CMD_TEXTUREMAPENABLE, 1);
@@ -990,3 +1222,20 @@ void PPGeImage::SetTexture() {
}
}
void PPGeNotifyFrame() {
if (textDrawer) {
textDrawer->OncePerFrame();
}
// Do this always, in case the platform has no TextDrawer but save state did.
for (auto it = textDrawerImages.begin(); it != textDrawerImages.end(); ) {
if (it->second.entry.lastUsedFrame - gpuStats.numFlips >= 97) {
kernelMemory.Free(it->second.ptr);
it = textDrawerImages.erase(it);
} else {
++it;
}
}
PPGeImage::Decimate();
}
+11 -30
View File
@@ -19,7 +19,9 @@
#include <vector>
#include <string>
#include "ppge_atlas.h"
#include "gfx/texture_atlas.h"
#include "Common/CommonTypes.h"
class PointerWrap;
@@ -43,10 +45,6 @@ void __PPGeShutdown();
void PPGeBegin();
void PPGeEnd();
// If you want to draw using this texture but not go through the PSP GE emulation,
// jsut call this. Will bind the texture to unit 0.
void PPGeBindTexture();
enum {
PPGE_ALIGN_LEFT = 0,
PPGE_ALIGN_RIGHT = 16,
@@ -63,11 +61,6 @@ enum {
PPGE_ALIGN_BOTTOMRIGHT = PPGE_ALIGN_BOTTOM | PPGE_ALIGN_RIGHT,
};
enum {
PPGE_ESCAPE_NONE,
PPGE_ESCAPE_BACKSLASHED,
};
enum {
PPGE_LINE_NONE = 0,
PPGE_LINE_USE_ELLIPSIS = 1, // use ellipses in too long words
@@ -76,21 +69,7 @@ enum {
};
// Get the metrics of the bounding box of the text without changing the buffer or state.
void PPGeMeasureText(float *w, float *h, int *n,
const char *text, float scale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0);
// Overwrite the current text lines buffer so it can be drawn later.
void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale,
int WrapType = PPGE_LINE_NONE, int wrapWidth = 0);
// Get the metrics of the bounding box of the currently stated text.
void PPGeMeasureCurrentText(float *x, float *y, float *w, float *h, int *n);
// These functions must be called between PPGeBegin and PPGeEnd.
// Draw currently buffered text using the state from PPGeGetTextBoundingBox() call.
// Clears the buffer and state when done.
void PPGeDrawCurrentText(u32 color = 0xFFFFFFFF);
void PPGeMeasureText(float *w, float *h, const char *text, float scale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0);
// Draws some text using the one font we have.
// Clears the text buffer when done.
@@ -98,13 +77,15 @@ void PPGeDrawText(const char *text, float x, float y, int align, float scale = 1
void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF);
// Draws a "4-patch" for button-like things that can be resized.
void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF);
void PPGeDraw4Patch(ImageID atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF);
// Just blits an image to the screen, multiplied with the color.
void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF);
void PPGeDrawImage(int atlasImage, float x, float y, float w, float h, int align, u32 color = 0xFFFFFFFF);
void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF);
void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int align, u32 color = 0xFFFFFFFF);
void PPGeDrawImage(float x, float y, float w, float h, float u1, float v1, float u2, float v2, int tw, int th, u32 color);
void PPGeNotifyFrame();
class PPGeImage {
public:
PPGeImage(const std::string &pspFilename);
@@ -130,8 +111,9 @@ public:
return height_;
}
private:
static void Decimate();
private:
static std::vector<PPGeImage *> loadedTextures_;
std::string filename_;
@@ -150,6 +132,5 @@ private:
void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color);
void PPGeSetDefaultTexture();
void PPGeSetTexture(u32 dataAddr, int width, int height);
void PPGeDisableTexture();
File diff suppressed because it is too large. Load diff
-18
View File
@@ -1,18 +0,0 @@
// Header generated by atlastool from ppge_atlasscript.txt (hrydgard@gmail.com)
#pragma once
#include "gfx/texture_atlas.h"
// FONTS_ppge
#define UBUNTU24 0
// IMAGES_ppge
#define I_CROSS 0
#define I_CIRCLE 1
#define I_SQUARE 2
#define I_TRIANGLE 3
extern const Atlas ppge_atlas;
extern const AtlasImage ppge_images[4];
+18
View File
@@ -37,6 +37,8 @@ DrawEngineCommon::DrawEngineCommon() : decoderMap_(16) {
decJitCache_ = new VertexDecoderJitCache();
transformed = (TransformedVertex *)AllocateMemoryPages(TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
transformedExpanded = (TransformedVertex *)AllocateMemoryPages(3 * TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
useHWTransform_ = g_Config.bHardwareTransform;
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
}
DrawEngineCommon::~DrawEngineCommon() {
@@ -171,6 +173,9 @@ void DrawEngineCommon::Resized() {
});
decoderMap_.Clear();
ClearTrackedVertexArrays();
useHWTransform_ = g_Config.bHardwareTransform;
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
}
u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize) {
@@ -737,6 +742,19 @@ void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim,
}
}
bool DrawEngineCommon::CanUseHardwareTransform(int prim) {
if (!useHWTransform_)
return false;
return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
}
bool DrawEngineCommon::CanUseHardwareTessellation(GEPatchPrimType prim) {
if (useHWTessellation_) {
return CanUseHardwareTransform(PatchPrimToPrim(prim));
}
return false;
}
void TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) {
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
+7
View File
@@ -86,6 +86,9 @@ public:
void SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope);
void ClearSplineBezierWeights();
bool CanUseHardwareTransform(int prim);
bool CanUseHardwareTessellation(GEPatchPrimType prim);
std::vector<std::string> DebugGetVertexLoaderIDs();
std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType);
@@ -101,6 +104,7 @@ public:
VertexDecoder *GetVertexDecoder(u32 vtype);
protected:
virtual bool UpdateUseHWTessellation(bool enabled) { return enabled; }
virtual void ClearTrackedVertexArrays() {}
int ComputeNumVertsToDecode() const;
@@ -128,6 +132,9 @@ protected:
return 1;
}
bool useHWTransform_ = false;
bool useHWTessellation_ = false;
// Vertex collector buffers
u8 *decoded = nullptr;
u16 *decIndex = nullptr;
+14 -6
View File
@@ -236,6 +236,10 @@ void FramebufferManagerCommon::EstimateDrawingSize(u32 fb_address, GEBufferForma
drawing_width = scissor_width;
drawing_height = std::max(drawing_height, scissor_height);
}
if (scissor_width == 481 && region_width == 480 && scissor_height == 273 && region_height == 272) {
drawing_width = 480;
drawing_height = 272;
}
} else {
// If viewport wasn't valid, let's just take the greatest anything regardless of stride.
drawing_width = std::min(std::max(region_width, scissor_width), fb_stride);
@@ -848,7 +852,7 @@ void FramebufferManagerCommon::SetViewport2D(int x, int y, int w, int h) {
draw_->SetViewports(1, &vp);
}
void FramebufferManagerCommon::CopyDisplayToOutput() {
void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
DownloadFramebufferOnSwitch(currentRenderVfb_);
shaderManager_->DirtyLastShader();
@@ -871,12 +875,16 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
CardboardSettings cardboardSettings;
GetCardboardSettings(&cardboardSettings);
VirtualFramebuffer *vfb = GetVFBAt(displayFramebufPtr_);
// If it's not really dirty, we're probably frameskipping. Use the last working one.
u32 fbaddr = reallyDirty ? displayFramebufPtr_ : prevDisplayFramebufPtr_;
prevDisplayFramebufPtr_ = fbaddr;
VirtualFramebuffer *vfb = GetVFBAt(fbaddr);
if (!vfb) {
// Let's search for a framebuf within this range. Note that we also look for
// "framebuffers" sitting in RAM (created from block transfer or similar) so we only take off the kernel
// and uncached bits of the address when comparing.
const u32 addr = displayFramebufPtr_ & 0x3FFFFFFF;
const u32 addr = fbaddr & 0x3FFFFFFF;
for (size_t i = 0; i < vfbs_.size(); ++i) {
VirtualFramebuffer *v = vfbs_[i];
const u32 v_addr = v->fb_address & 0x3FFFFFFF;
@@ -914,7 +922,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
}
if (!vfb) {
if (Memory::IsValidAddress(displayFramebufPtr_)) {
if (Memory::IsValidAddress(fbaddr)) {
// The game is displaying something directly from RAM. In GTA, it's decoded video.
if (!vfb) {
shaderManager_->DirtyLastShader();
@@ -925,12 +933,12 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
// Just a pointer to plain memory to draw. We should create a framebuffer, then draw to it.
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
DrawFramebufferToOutput(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true);
DrawFramebufferToOutput(Memory::GetPointer(fbaddr), displayFormat_, displayStride_, true);
gstate_c.Dirty(DIRTY_BLEND_STATE);
return;
}
} else {
DEBUG_LOG(FRAMEBUF, "Found no FBO to display! displayFBPtr = %08x", displayFramebufPtr_);
DEBUG_LOG(FRAMEBUF, "Found no FBO to display! displayFBPtr = %08x", fbaddr);
// No framebuffer to display! Clear to black.
if (useBufferedRendering_) {
shaderManager_->DirtyLastShader();
+6 -1
View File
@@ -228,7 +228,7 @@ public:
void RebindFramebuffer();
std::vector<FramebufferInfo> GetFramebufferList();
void CopyDisplayToOutput();
void CopyDisplayToOutput(bool reallyDirty);
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset, u32 skipDrawReason);
void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt);
@@ -264,6 +264,10 @@ public:
return displayFramebuf_ ? displayFormat_ : GE_FORMAT_INVALID;
}
bool UseBufferedRendering() {
return useBufferedRendering_;
}
bool MayIntersectFramebuffer(u32 start) {
// Clear the cache/kernel bits.
start = start & 0x3FFFFFFF;
@@ -383,6 +387,7 @@ protected:
u32 displayFramebufPtr_ = 0;
u32 displayStride_ = 0;
GEBufferFormat displayFormat_;
u32 prevDisplayFramebufPtr_ = 0;
VirtualFramebuffer *displayFramebuf_ = nullptr;
VirtualFramebuffer *prevDisplayFramebuf_ = nullptr;
-6
View File
@@ -34,12 +34,6 @@
#include "GPU/Common/GPUStateUtils.h"
bool CanUseHardwareTransform(int prim) {
if (!g_Config.bHardwareTransform)
return false;
return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
}
bool IsStencilTestOutputDisabled() {
// The mask applies on all stencil ops.
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF) {
-1
View File
@@ -51,7 +51,6 @@ StencilValueType ReplaceAlphaWithStencilType();
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend);
ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bufferFormat);
bool CanUseHardwareTransform(int prim);
LogicOpReplaceType ReplaceLogicOpType();
+2 -2
View File
@@ -60,7 +60,7 @@ std::string VertexShaderDesc(const VShaderID &id) {
return desc.str();
}
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform) {
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool useHWTessellation) {
bool isModeThrough = (vertType & GE_VTYPE_THROUGH) != 0;
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool doTextureTransform = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX;
@@ -131,7 +131,7 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform)
id.SetBit(VS_BIT_NORM_REVERSE, gstate.areNormalsReversed());
id.SetBit(VS_BIT_HAS_TEXCOORD, hasTexcoord);
if (g_Config.bHardwareTessellation) {
if (useHWTessellation) {
id.SetBit(VS_BIT_BEZIER, doBezier);
id.SetBit(VS_BIT_SPLINE, doSpline);
if (doBezier || doSpline) {
+1 -1
View File
@@ -223,7 +223,7 @@ class Bugs;
}
void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform);
void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform, bool useHWTessellation);
// Generates a compact string that describes the shader. Useful in a list to get an overview
// of the current flora of shaders.
std::string VertexShaderDesc(const VShaderID &id);
+3 -5
View File
@@ -11,8 +11,6 @@
#include "GPU/Common/FramebufferCommon.h"
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/Math3D.h"
#include "Core/Reporting.h"
#include "Core/Config.h"
using namespace Lin;
@@ -91,7 +89,7 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo
maxValues[3] = NAN;
}
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport) {
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport, bool useBufferedRendering) {
if (dirtyUniforms & DIRTY_TEXENV) {
Uint8x3ToFloat4(ub->texEnvColor, gstate.texenvcolor);
}
@@ -149,7 +147,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
ConvertProjMatrixToVulkan(flippedMatrix);
}
if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && g_display_rotation != DisplayRotation::ROTATE_0) {
if (!useBufferedRendering && g_display_rotation != DisplayRotation::ROTATE_0) {
flippedMatrix = flippedMatrix * g_display_rot_matrix;
}
CopyMatrix4x4(ub->proj, flippedMatrix.getReadPtr());
@@ -162,7 +160,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
} else {
proj_through.setOrthoVulkan(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
}
if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && g_display_rotation != DisplayRotation::ROTATE_0) {
if (!useBufferedRendering && g_display_rotation != DisplayRotation::ROTATE_0) {
proj_through = proj_through * g_display_rot_matrix;
}
// proj_through.translateAndScale(Vec3(0, 0, 0), Vec3(1.0f / debugscale, 1.0f / debugscale, 0));
+1 -1
View File
@@ -186,7 +186,7 @@ R"( float4x3 u_bone[8];
void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bool hasNegZ);
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport);
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport, bool useBufferedRendering);
void LightUpdateUniforms(UB_VS_Lights *ub, uint64_t dirtyUniforms);
void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms);
+1 -1
View File
@@ -517,7 +517,7 @@ void SoftwareTransform(
numTrans = 0;
drawIndexed = false;
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
bool useBufferedRendering = fbman->UseBufferedRendering();
bool flippedY = g_Config.iGPUBackend == (int)GPUBackend::OPENGL && !useBufferedRendering;
-7
View File
@@ -28,13 +28,6 @@
#include "GPU/ge_constants.h"
#include "GPU/GPUState.h" // only needed for UVScale stuff
bool CanUseHardwareTessellation(GEPatchPrimType prim) {
if (g_Config.bHardwareTessellation && !g_Config.bSoftwareRendering) {
return CanUseHardwareTransform(PatchPrimToPrim(prim));
}
return false;
}
class SimpleBufferManager {
private:
u8 *buf_;
-2
View File
@@ -207,8 +207,6 @@ void SoftwareTessellation(OutputBuffers &output, const Surface &surface, u32 ori
} // namespace Spline
bool CanUseHardwareTessellation(GEPatchPrimType prim);
// Define function object for TemplateParameterDispatcher
#define TEMPLATE_PARAMETER_DISPATCHER_FUNCTION(NAME, FUNCNAME, FUNCTYPE) \
struct NAME { \
+5 -6
View File
@@ -795,7 +795,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi
}
} else {
// Apply to buffered mode only.
if (!(g_Config.iRenderingMode == FB_BUFFERED_MODE))
if (!framebufferManager_->UseBufferedRendering())
return false;
const bool clutFormat =
@@ -875,8 +875,7 @@ void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram
_dbg_assert_msg_(G3D, framebuffer != nullptr, "Framebuffer must not be null.");
framebuffer->usageFlags |= FB_USAGE_TEXTURE;
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (useBufferedRendering) {
if (framebufferManager_->UseBufferedRendering()) {
const u64 cachekey = entry->CacheKey();
const auto &fbInfo = fbTexInfo_[cachekey];
@@ -918,7 +917,7 @@ void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram
}
bool TextureCacheCommon::SetOffsetTexture(u32 offset) {
if (g_Config.iRenderingMode != FB_BUFFERED_MODE) {
if (!framebufferManager_->UseBufferedRendering()) {
return false;
}
u32 texaddr = gstate.getTextureAddress(0);
@@ -1307,7 +1306,7 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
memcpy(out + outPitch * y, texptr + bufw * sizeof(u16) * y, w * sizeof(u16));
}
}
} else if (h >= 8 && !expandTo32bit) {
} else if (h >= 8 && bufw <= w && !expandTo32bit) {
// Note: this is always safe since h must be a power of 2, so a multiple of 8.
UnswizzleFromMem((u32 *)out, outPitch, texptr, bufw, h, 2);
if (reverseColors) {
@@ -1346,7 +1345,7 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
memcpy(out + outPitch * y, texptr + bufw * sizeof(u32) * y, w * sizeof(u32));
}
}
} else if (h >= 8) {
} else if (h >= 8 && bufw <= w) {
UnswizzleFromMem((u32 *)out, outPitch, texptr, bufw, h, 4);
if (reverseColors) {
ReverseColors(out, out, format, h * outPitch / 4, useBGRA);
+1 -1
View File
@@ -93,7 +93,7 @@ u32 GetTextureBufw(int level, u32 texaddr, GETextureFormat format) {
return gstate.texbufwidth[level] & 0x1FFF;
u32 bufw = gstate.texbufwidth[level] & textureAlignMask16[format];
if (bufw == 0) {
if (bufw == 0 && format <= GE_TFMT_DXT5) {
// If it's less than 16 bytes, use 16 bytes.
bufw = (8 * 16) / textureBitsPerPixel[format];
}
+4 -4
View File
@@ -514,11 +514,11 @@ rotateVBO:
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform, useHWTessellation_);
ID3D11InputLayout *inputLayout = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType());
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
shaderManager_->UpdateUniforms();
shaderManager_->UpdateUniforms(framebufferManager_->UseBufferedRendering());
shaderManager_->BindUniforms();
context_->IASetInputLayout(inputLayout);
@@ -598,10 +598,10 @@ rotateVBO:
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false);
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false, false);
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
shaderManager_->UpdateUniforms();
shaderManager_->UpdateUniforms(framebufferManager_->UseBufferedRendering());
shaderManager_->BindUniforms();
// We really do need a vertex layout for each vertex shader (or at least check its ID bits for what inputs it uses)!
+3 -5
View File
@@ -73,7 +73,6 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
lastVsync_ = g_Config.bVSync ? 1 : 0;
stockD3D11.Create(device_);
@@ -212,8 +211,7 @@ void GPU_D3D11::DeviceRestore() {
}
void GPU_D3D11::InitClear() {
bool useNonBufferedRendering = g_Config.iRenderingMode == FB_NON_BUFFERED_MODE;
if (useNonBufferedRendering) {
if (!framebufferManager_->UseBufferedRendering()) {
// device_->Clear(0, NULL, D3DCLEAR_STENCIL | D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.f, 0);
}
}
@@ -263,13 +261,13 @@ void GPU_D3D11::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat f
framebufferManagerD3D11_->SetDisplayFramebuffer(framebuf, stride, format);
}
void GPU_D3D11::CopyDisplayToOutput() {
void GPU_D3D11::CopyDisplayToOutput(bool reallyDirty) {
float blendColor[4]{};
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], blendColor, 0xFFFFFFFF);
drawEngine_.Flush();
framebufferManagerD3D11_->CopyDisplayToOutput();
framebufferManagerD3D11_->CopyDisplayToOutput(reallyDirty);
framebufferManagerD3D11_->EndFrame();
// shaderManager_->EndFrame();
+1 -3
View File
@@ -71,7 +71,7 @@ private:
void InitClear() override;
void BeginFrame() override;
void CopyDisplayToOutput() override;
void CopyDisplayToOutput(bool reallyDirty) override;
ID3D11Device *device_;
ID3D11DeviceContext *context_;
@@ -81,6 +81,4 @@ private:
DepalShaderCacheD3D11 *depalShaderCache_;
DrawEngineD3D11 drawEngine_;
ShaderManagerD3D11 *shaderManagerD3D11_;
int lastVsync_;
};
+4 -4
View File
@@ -149,12 +149,12 @@ void ShaderManagerD3D11::DirtyLastShader() {
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE);
}
uint64_t ShaderManagerD3D11::UpdateUniforms() {
uint64_t ShaderManagerD3D11::UpdateUniforms(bool useBufferedRendering) {
uint64_t dirty = gstate_c.GetDirtyUniforms();
if (dirty != 0) {
D3D11_MAPPED_SUBRESOURCE map;
if (dirty & DIRTY_BASE_UNIFORMS) {
BaseUpdateUniforms(&ub_base, dirty, true);
BaseUpdateUniforms(&ub_base, dirty, true, useBufferedRendering);
context_->Map(push_base, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, &ub_base, sizeof(ub_base));
context_->Unmap(push_base, 0);
@@ -183,13 +183,13 @@ void ShaderManagerD3D11::BindUniforms() {
context_->PSSetConstantBuffers(0, 1, ps_cbs);
}
void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform) {
void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation) {
VShaderID VSID;
FShaderID FSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation);
} else {
VSID = lastVSID_;
}
+2 -2
View File
@@ -84,7 +84,7 @@ public:
ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel);
~ShaderManagerD3D11();
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform);
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation);
void ClearShaders();
void DirtyLastShader() override;
@@ -94,7 +94,7 @@ public:
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
uint64_t UpdateUniforms();
uint64_t UpdateUniforms(bool useBufferedRendering);
void BindUniforms();
// TODO: Avoid copying these buffers if same as last draw, can still point to it assuming we're still in the same pushbuffer.
+1 -1
View File
@@ -139,7 +139,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
return;
}
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();
// Blend
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects);
Loaded 100 of 336 files, more files were not shown because too many files have changed in this diff. Show more