Merge remote-tracking branch 'upstream/master'

This commit is contained in:
987123879113 2022-09-18 00:46:49 +09:00
commit 2c8606a38d
300 changed files with 54988 additions and 3376 deletions

View File

@ -63,6 +63,7 @@ allowed_gs_hw_fixes = [
"texturePreloading",
"deinterlace",
"cpuSpriteRenderBW",
"gpuPaletteConversion",
]
gs_hw_fix_ranges = {
"mipmap": (0, 2),
@ -73,6 +74,7 @@ gs_hw_fix_ranges = {
"roundSprite": (0, 2),
"deinterlace": (0, 7),
"cpuSpriteRenderBW": (1, 10),
"gpuPaletteConversion": (0, 2),
}
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack", "MTVUSpeedHack"]
# Patches are allowed to have a 'default' key or a crc-32 key, followed by

View File

@ -10,7 +10,7 @@ fi
export BINARY_NAME=$(basename "$ARGV0")
if [[ ! -e "$PWD/$BINARY_NAME.config" ]]; then
mkdir "$PWD/$BINARY_NAME.config"
fi
fi
export XDG_CONFIG_HOME="$PWD/$BINARY_NAME.config"
mkdir -p "$HOME"/.local/share/icons/hicolor/scalable/apps && cp "$APPDIR"/PCSX2.png "$HOME"/.local/share/icons/hicolor/scalable/apps

3
.gitmodules vendored
View File

@ -21,9 +21,6 @@
path = 3rdparty/rapidyaml/rapidyaml
url = https://github.com/biojppm/rapidyaml.git
branch = master
[submodule "3rdparty/imgui/imgui"]
path = 3rdparty/imgui/imgui
url = https://github.com/ocornut/imgui.git
[submodule "3rdparty/glslang/glslang"]
path = 3rdparty/glslang/glslang
url = https://github.com/KhronosGroup/glslang.git

View File

@ -1,19 +1,21 @@
add_library(imgui
imgui/imconfig.h
imgui/imgui.cpp
imgui/imgui.h
imgui/imgui_demo.cpp
imgui/imgui_draw.cpp
imgui/imgui_internal.h
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/imstb_rectpack.h
imgui/imstb_textedit.h
imgui/imstb_truetype.h
imgui/misc/cpp/imgui_stdlib.cpp
include/imconfig.h
include/imgui.h
include/imgui_internal.h
include/imgui_stdlib.h
include/imstb_textedit.h
src/imgui.cpp
src/imgui_demo.cpp
src/imgui_draw.cpp
src/imgui_tables.cpp
src/imgui_widgets.cpp
src/imstb_rectpack.h
src/imstb_truetype.h
src/imgui_stdlib.cpp
)
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui" "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
# Needed for macOS compile.
set_property(TARGET imgui PROPERTY CXX_STANDARD 17)

@ -1 +0,0 @@
Subproject commit 60bea052a92cbb4a93b221002fdf04f0da3698e1

View File

@ -32,7 +32,7 @@
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;$(ProjectDir)imgui;$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
@ -41,21 +41,21 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="imgui\imconfig.h" />
<ClInclude Include="imgui\imgui.h" />
<ClInclude Include="imgui\imgui_internal.h" />
<ClInclude Include="imgui\imstb_rectpack.h" />
<ClInclude Include="imgui\imstb_textedit.h" />
<ClInclude Include="imgui\imstb_truetype.h" />
<ClInclude Include="imgui\misc\cpp\imgui_stdlib.h" />
<ClInclude Include="include\imconfig.h" />
<ClInclude Include="include\imgui.h" />
<ClInclude Include="include\imgui_internal.h" />
<ClInclude Include="include\imstb_rectpack.h" />
<ClInclude Include="include\imstb_textedit.h" />
<ClInclude Include="include\imstb_truetype.h" />
<ClInclude Include="include\imgui_stdlib.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="imgui\imgui.cpp" />
<ClCompile Include="imgui\imgui_demo.cpp" />
<ClCompile Include="imgui\imgui_draw.cpp" />
<ClCompile Include="imgui\imgui_tables.cpp" />
<ClCompile Include="imgui\imgui_widgets.cpp" />
<ClCompile Include="imgui\misc\cpp\imgui_stdlib.cpp" />
<ClCompile Include="src\imgui.cpp" />
<ClCompile Include="src\imgui_demo.cpp" />
<ClCompile Include="src\imgui_draw.cpp" />
<ClCompile Include="src\imgui_tables.cpp" />
<ClCompile Include="src\imgui_widgets.cpp" />
<ClCompile Include="src\imgui_stdlib.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="imgui\imconfig.h" />
<ClInclude Include="imgui\imgui.h" />
<ClInclude Include="imgui\imgui_internal.h" />
<ClInclude Include="imgui\imstb_rectpack.h" />
<ClInclude Include="imgui\imstb_textedit.h" />
<ClInclude Include="imgui\imstb_truetype.h" />
<ClInclude Include="imgui\misc\cpp\imgui_stdlib.h" />
<ClInclude Include="include\imconfig.h" />
<ClInclude Include="include\imgui.h" />
<ClInclude Include="include\imgui_internal.h" />
<ClInclude Include="include\imstb_rectpack.h" />
<ClInclude Include="include\imstb_textedit.h" />
<ClInclude Include="include\imstb_truetype.h" />
<ClInclude Include="include\imgui_stdlib.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="imgui\imgui.cpp" />
<ClCompile Include="imgui\imgui_demo.cpp" />
<ClCompile Include="imgui\imgui_draw.cpp" />
<ClCompile Include="imgui\imgui_tables.cpp" />
<ClCompile Include="imgui\imgui_widgets.cpp" />
<ClCompile Include="imgui\misc\cpp\imgui_stdlib.cpp" />
<ClCompile Include="src\imgui.cpp" />
<ClCompile Include="src\imgui_demo.cpp" />
<ClCompile Include="src\imgui_draw.cpp" />
<ClCompile Include="src\imgui_tables.cpp" />
<ClCompile Include="src\imgui_widgets.cpp" />
<ClCompile Include="src\imgui_stdlib.cpp" />
</ItemGroup>
</Project>

125
3rdparty/imgui/include/imconfig.h vendored Normal file
View File

@ -0,0 +1,125 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
//-----------------------------------------------------------------------------
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
//---- Define assertion handler. Defaults to calling assert().
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
//---- Disable all of Dear ImGui or don't implement standard windows.
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
//---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
//#define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
//#define IMGUI_USE_STB_SPRINTF
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE
//---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*
#define IM_VEC2_CLASS_EXTRA \
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
}
*/

3047
3rdparty/imgui/include/imgui.h vendored Normal file

File diff suppressed because it is too large Load Diff

2944
3rdparty/imgui/include/imgui_internal.h vendored Normal file

File diff suppressed because it is too large Load Diff

18
3rdparty/imgui/include/imgui_stdlib.h vendored Normal file
View File

@ -0,0 +1,18 @@
// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
// This is also an example of how you may wrap your own similar types.
// Changelog:
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
#pragma once
#include <string>
namespace ImGui
{
// ImGui::InputText() with std::string
// Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
}

1447
3rdparty/imgui/include/imstb_textedit.h vendored Normal file

File diff suppressed because it is too large Load Diff

13277
3rdparty/imgui/src/imgui.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

7940
3rdparty/imgui/src/imgui_demo.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

4162
3rdparty/imgui/src/imgui_draw.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

72
3rdparty/imgui/src/imgui_stdlib.cpp vendored Normal file
View File

@ -0,0 +1,72 @@
// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
// This is also an example of how you may wrap your own similar types.
// Changelog:
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
#include "imgui.h"
#include "imgui_stdlib.h"
struct InputTextCallback_UserData
{
std::string* Str;
ImGuiInputTextCallback ChainCallback;
void* ChainCallbackUserData;
};
static int InputTextCallback(ImGuiInputTextCallbackData* data)
{
InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData;
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
{
// Resize string callback
// If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
std::string* str = user_data->Str;
IM_ASSERT(data->Buf == str->c_str());
str->resize(data->BufTextLen);
data->Buf = (char*)str->c_str();
}
else if (user_data->ChainCallback)
{
// Forward to user callback, if any
data->UserData = user_data->ChainCallbackUserData;
return user_data->ChainCallback(data);
}
return 0;
}
bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
}
bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
}
bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
}

4068
3rdparty/imgui/src/imgui_tables.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

8304
3rdparty/imgui/src/imgui_widgets.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

627
3rdparty/imgui/src/imstb_rectpack.h vendored Normal file
View File

@ -0,0 +1,627 @@
// [DEAR IMGUI]
// This is a slightly modified version of stb_rect_pack.h 1.01.
// Grep for [DEAR IMGUI] to find the changes.
//
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// Before #including,
//
// #define STB_RECT_PACK_IMPLEMENTATION
//
// in the file that you want to have the implementation.
//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
//
// Has only had a few tests run, may have issues.
//
// More docs to come.
//
// No memory allocations; uses qsort() and assert() from stdlib.
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
//
// This library currently uses the Skyline Bottom-Left algorithm.
//
// Please note: better rectangle packers are welcome! Please
// implement them to the same API, but with a different init
// function.
//
// Credits
//
// Library
// Sean Barrett
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
//
// LICENSE
//
// See end of file for license information.
//////////////////////////////////////////////////////////////////////////////
//
// INCLUDE SECTION
//
#ifndef STB_INCLUDE_STB_RECT_PACK_H
#define STB_INCLUDE_STB_RECT_PACK_H
#define STB_RECT_PACK_VERSION 1
#ifdef STBRP_STATIC
#define STBRP_DEF static
#else
#define STBRP_DEF extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
typedef int stbrp_coord;
#define STBRP__MAXVAL 0x7fffffff
// Mostly for internal use, but this is the maximum supported coordinate value.
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
//
// Rectangles which are successfully packed have the 'was_packed' flag
// set to a non-zero value and 'x' and 'y' store the minimum location
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
// if you imagine y increasing downwards). Rectangles which do not fit
// have the 'was_packed' flag set to 0.
//
// You should not try to access the 'rects' array from another thread
// while this function is running, as the function temporarily reorders
// the array while it executes.
//
// To pack into another rectangle, you need to call stbrp_init_target
// again. To continue packing into the same rectangle, you can call
// this function again. Calling this multiple times with multiple rect
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
struct stbrp_rect
{
// reserved for your use:
int id;
// input:
stbrp_coord w, h;
// output:
stbrp_coord x, y;
int was_packed; // non-zero if valid packing
}; // 16 bytes, nominally
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
// Initialize a rectangle packer to:
// pack a rectangle that is 'width' by 'height' in dimensions
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
//
// You must call this function every time you start packing into a new target.
//
// There is no "shutdown" function. The 'nodes' memory must stay valid for
// the following stbrp_pack_rects() call (or calls), but can be freed after
// the call (or calls) finish.
//
// Note: to guarantee best results, either:
// 1. make sure 'num_nodes' >= 'width'
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
//
// If you don't do either of the above things, widths will be quantized to multiples
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
//
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
// may run out of temporary storage and be unable to pack some rectangles.
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
// Optionally call this function after init but before doing any packing to
// change the handling of the out-of-temp-memory scenario, described above.
// If you call init again, this will be reset to the default (false).
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
// Optionally select which packing heuristic the library should use. Different
// heuristics will produce better/worse results for different data sets.
// If you call init again, this will be reset to the default.
enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
STBRP_HEURISTIC_Skyline_BF_sortHeight
};
//////////////////////////////////////////////////////////////////////////////
//
// the details of the following structures don't matter to you, but they must
// be visible so you can handle the memory allocations for them
struct stbrp_node
{
stbrp_coord x,y;
stbrp_node *next;
};
struct stbrp_context
{
int width;
int height;
int align;
int init_mode;
int heuristic;
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
};
#ifdef __cplusplus
}
#endif
#endif
//////////////////////////////////////////////////////////////////////////////
//
// IMPLEMENTATION SECTION
//
#ifdef STB_RECT_PACK_IMPLEMENTATION
#ifndef STBRP_SORT
#include <stdlib.h>
#define STBRP_SORT qsort
#endif
#ifndef STBRP_ASSERT
#include <assert.h>
#define STBRP_ASSERT assert
#endif
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
#endif
enum
{
STBRP__INIT_skyline = 1
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
switch (context->init_mode) {
case STBRP__INIT_skyline:
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
break;
default:
STBRP_ASSERT(0);
}
}
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
if (allow_out_of_mem)
// if it's ok to run out of memory, then don't bother aligning them;
// this gives better packing, but may fail due to OOM (even though
// the rectangles easily fit). @TODO a smarter approach would be to only
// quantize once we've hit OOM, then we could get rid of this parameter.
context->align = 1;
else {
// if it's not ok to run out of memory, then quantize the widths
// so that num_nodes is always enough nodes.
//
// I.e. num_nodes * align >= width
// align >= width / num_nodes
// align = ceil(width/num_nodes)
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
nodes[i].next = NULL;
context->init_mode = STBRP__INIT_skyline;
context->heuristic = STBRP_HEURISTIC_Skyline_default;
context->free_head = &nodes[0];
context->active_head = &context->extra[0];
context->width = width;
context->height = height;
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
context->extra[0].x = 0;
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
context->extra[1].y = (1<<30);
context->extra[1].next = NULL;
}
// find minimum y position if it starts at x1
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
{
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
STBRP__NOTUSED(c);
STBRP_ASSERT(first->x <= x0);
#if 0
// skip in case we're past the node
while (node->next->x <= x0)
++node;
#else
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
#endif
STBRP_ASSERT(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
while (node->x < x1) {
if (node->y > min_y) {
// raise min_y higher.
// we've accounted for all waste up to min_y,
// but we'll now add more waste for everything we've visted
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
// the first time through, visited_width might be reduced
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
} else {
// add waste area
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
waste_area += under_width * (min_y - node->y);
visited_width += under_width;
}
node = node->next;
}
*pwaste = waste_area;
return min_y;
}
typedef struct
{
int x,y;
stbrp_node **prev_link;
} stbrp__findresult;
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
{
int best_waste = (1<<30), best_x, best_y = (1 << 30);
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
// align to multiple of c->align
width = (width + c->align - 1);
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
int y,waste;
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
// bottom left
if (y < best_y) {
best_y = y;
best = prev;
}
} else {
// best-fit
if (y + height <= c->height) {
// can only use it if it first vertically
if (y < best_y || (y == best_y && waste < best_waste)) {
best_y = y;
best_waste = waste;
best = prev;
}
}
}
prev = &node->next;
node = node->next;
}
best_x = (best == NULL) ? 0 : (*best)->x;
// if doing best-fit (BF), we also have to try aligning right edge to each node position
//
// e.g, if fitting
//
// ____________________
// |____________________|
//
// into
//
// | |
// | ____________|
// |____________|
//
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
//
// This makes BF take about 2x the time
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
// find first node that's admissible
while (tail->x < width)
tail = tail->next;
while (tail) {
int xpos = tail->x - width;
int y,waste;
STBRP_ASSERT(xpos >= 0);
// find the left position that matches this
while (node->next->x <= xpos) {
prev = &node->next;
node = node->next;
}
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height <= c->height) {
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
best_y = y;
best_waste = waste;
best = prev;
}
}
}
tail = tail->next;
}
}
fr.prev_link = best;
fr.x = best_x;
fr.y = best_y;
return fr;
}
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
// find best position according to heuristic
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
stbrp_node *node, *cur;
// bail if:
// 1. it failed
// 2. the best node doesn't fit (we don't always check this)
// 3. we're out of memory
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
res.prev_link = NULL;
return res;
}
// on success, create new node
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
// insert the new node into the right starting point, and
// let 'cur' point to the remaining nodes needing to be
// stiched back in
cur = *res.prev_link;
if (cur->x < res.x) {
// preserve the existing one, so start testing with the next one
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
} else {
*res.prev_link = node;
}
// from here, traverse cur and free the nodes, until we get to one
// that shouldn't be freed
while (cur->next && cur->next->x <= res.x + width) {
stbrp_node *next = cur->next;
// move the current node to the free list
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
// stitch the list back in
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
#ifdef _DEBUG
cur = context->active_head;
while (cur->x < context->width) {
STBRP_ASSERT(cur->x < cur->next->x);
cur = cur->next;
}
STBRP_ASSERT(cur->next == NULL);
{
int count=0;
cur = context->active_head;
while (cur) {
cur = cur->next;
++count;
}
cur = context->free_head;
while (cur) {
cur = cur->next;
++count;
}
STBRP_ASSERT(count == context->num_nodes+2);
}
#endif
return res;
}
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->h > q->h)
return -1;
if (p->h < q->h)
return 1;
return (p->w > q->w) ? -1 : (p->w < q->w);
}
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i, all_rects_packed = 1;
// we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i;
}
// sort according to heuristic
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
}
// unsort
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags and all_rects_packed status
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
if (!rects[i].was_packed)
all_rects_packed = 0;
}
// return the all_rects_packed status
return all_rects_packed;
}
#endif
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/

5085
3rdparty/imgui/src/imstb_truetype.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,7 @@ ALCH-00007:
name: "Parfait - Chocolat Second Style [Limited Edition]"
region: "NTSC-J"
ALCH-00008:
name: "Aria - The Natural ~Tooi Yume no Mirage~ [Limited Edition]"
name: "Aria - The Natural - Tooi Yume no Mirage [Limited Edition]"
region: "NTSC-J"
ALCH-00009:
name: "Higurashi no Naku Koro ni Matsuri [First Print Limited Edition]"
@ -571,6 +571,8 @@ SCAJ-20020:
SCAJ-20021:
name: "Metal Slug 3"
region: "NTSC-Unk"
gsHWFixes:
gpuPaletteConversion: 2 # Stops excessive VRAM usage with preloading on.
SCAJ-20022:
name: "Super Robot Wars - Alpha 2nd"
region: "NTSC-Unk"
@ -2610,7 +2612,7 @@ SCES-50000:
textureInsideRT: 1
halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
roundSprite: 1 # Fixes ui and hud alignment.
texturePreloading: 0 # Disabling for major speedup.
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
SCES-50001:
name: "Tekken Tag Tournament"
region: "PAL-M5"
@ -5085,7 +5087,7 @@ SCPN-60160:
region: "NTSC-J"
cdvdOffset: 0x03224603
SCPS-11001:
name: "I.Q. Remix"
name: "I.Q. Remix+ - Intelligent Qube"
region: "NTSC-J"
compat: 5
SCPS-11002:
@ -5147,7 +5149,7 @@ SCPS-11014:
region: "NTSC-J"
compat: 5
SCPS-11015:
name: "Check-i-TV"
name: "Check-i-TV [Kyou kara Check! Pack]"
region: "NTSC-J"
SCPS-11016:
name: "Seigi no Mikata"
@ -5776,7 +5778,7 @@ SCPS-15113:
name: "Minna no Tennis"
region: "NTSC-J"
SCPS-15114:
name: "Soukou Kihei Armodyne"
name: "Kikou Souhei Armodyne"
region: "NTSC-J"
speedHacks:
mvuFlagSpeedHack: 0 # Fixes bad graphics.
@ -8686,7 +8688,7 @@ SLED-50117:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLED-50286:
name: "Red Faction [Demo]"
region: "PAL-E"
@ -9777,23 +9779,23 @@ SLES-50383:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLES-50384:
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "PAL-I"
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLES-50385:
name: "Metal Gear Solid 2 - Sons of Liberty"
region: "PAL-S"
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLES-50386:
name: "Crash Bandicoot - Wrath of Cortex"
name: "Crash Bandicoot - The Wrath of Cortex"
region: "PAL-M6"
compat: 5
gsHWFixes:
@ -9916,7 +9918,7 @@ SLES-50446:
InstantVU1SpeedHack: 0 # Fixes SPS.
MTVUSpeedHack: 0
SLES-50447:
name: "All-Star Baseball 2003"
name: "All-Star Baseball 2003 featuring Derek Jeter"
region: "PAL-E"
SLES-50451:
name: "NHL Hitz 2002"
@ -10066,7 +10068,7 @@ SLES-50540:
name: "Simpsons Road Rage"
region: "PAL-E"
SLES-50541:
name: "Capcom vs. SNK 2 - Mark of the Millennium"
name: "Capcom vs. SNK 2 - Mark of the Millennium 2001"
region: "PAL-E"
SLES-50544:
name: "Jet Ion GP"
@ -12262,7 +12264,7 @@ SLES-51600:
name: "WWE Crush Hour"
region: "PAL-E"
SLES-51602:
name: "All-Stars Baseball 2004"
name: "All-Star Baseball 2004 featuring Derek Jeter"
region: "PAL-E"
SLES-51603:
name: "Seek & Destroy"
@ -12726,7 +12728,7 @@ SLES-51834:
name: "Premier Manager 2003-2004"
region: "PAL-F"
SLES-51838:
name: "Asterix & Obelix XXL"
name: "Astérix & Obélix XXL"
region: "PAL-M5"
SLES-51839:
name: "DragonBall Z - Budokai 2"
@ -12955,6 +12957,7 @@ SLES-51917:
textureInsideRT: 1 # Fixes the shape of shadows.
autoFlush: 1 # Fixes water rendering.
halfPixelOffset: 3 # Fixes bloom misalignment, needs this harsh offset for autoflush.
cpuFramebufferConversion: 1 # Fixes shield rendering.
SLES-51918:
name: "Prince of Persia - The Sands of Time"
region: "PAL-M5"
@ -13167,7 +13170,7 @@ SLES-52011:
region: "PAL-E"
compat: 5
SLES-52015:
name: "Les Chevaliers de Baphomet"
name: "Chevaliers de Baphomet, Les - Le Manuscrit de Voynich"
region: "PAL-F"
SLES-52017:
name: "Lord of the Rings, The - Return of the King"
@ -13206,7 +13209,7 @@ SLES-52028:
name: "Junior Sports Basketball"
region: "PAL-M5"
SLES-52034:
name: "Dr. Seuss' The Cat in the Hat"
name: "Cat in the Hat, The"
region: "PAL-M5"
gsHWFixes:
autoFlush: 1
@ -13242,7 +13245,7 @@ SLES-52045:
region: "PAL-E"
compat: 5
SLES-52046:
name: "007 - Quitte ou Double-Alles oder Nichts"
name: "007 - Everything or Nothing"
region: "PAL-F-G"
compat: 5
SLES-52047:
@ -13338,7 +13341,7 @@ SLES-52117:
name: "Go Go Copter"
region: "PAL-M3"
SLES-52118:
name: "Castlevania - Lament of Innocence"
name: "Castlevania"
region: "PAL-M5"
compat: 5
clampModes:
@ -13813,6 +13816,7 @@ SLES-52372:
cpuSpriteRenderBW: 1 # Fixes textures.
autoFlush: 1 # Fixes the position of the shadow and makes it not blocky.
halfPixelOffset: 1 # Fixes shadows.
gpuPaletteConversion: 0 # Stops potential crashes from too many palette textures.
SLES-52373:
name: "Champions of Norrath"
region: "PAL-E-S"
@ -13963,6 +13967,7 @@ SLES-52447:
cpuSpriteRenderBW: 1 # Fixes textures.
autoFlush: 1 # Fixes the position of the shadow and makes it not blocky.
halfPixelOffset: 1 # Fixes shadows.
gpuPaletteConversion: 0 # Stops potential crashes from too many palette textures.
SLES-52448:
name: "Knights of the Temple"
region: "PAL-M4"
@ -14067,6 +14072,7 @@ SLES-52493:
cpuSpriteRenderBW: 1 # Fixes textures.
autoFlush: 1 # Fixes the position of the shadow and makes it not blocky.
halfPixelOffset: 1 # Fixes shadows.
gpuPaletteConversion: 0 # Stops potential crashes from too many palette textures.
SLES-52495:
name: "Bujingai - Swordmaster"
region: "PAL-M5"
@ -14130,7 +14136,7 @@ SLES-52521:
name: "Adibou & Les Voleurs d'Energie"
region: "PAL-M6"
SLES-52523:
name: "Cocoto - Platform Jumper - Griffin's Story"
name: "Cocoto Platform Jumper"
region: "PAL-M5"
SLES-52525:
name: "Mouse Trophy"
@ -14360,6 +14366,8 @@ SLES-52598:
SLES-52599:
name: "Metal Slug 3"
region: "PAL-M5"
gsHWFixes:
gpuPaletteConversion: 2 # Stops excessive VRAM usage with preloading on.
SLES-52600:
name: "Harry Potter and the Prisoner of Azkaban"
region: "PAL-PL"
@ -14776,8 +14784,8 @@ SLES-52782:
gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures.
SLES-52783:
name: "Call of Duty - Le Jour de Gloire"
region: "PAL-F"
name: "Call of Duty - Finest Hour"
region: "PAL-F-S-I"
gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures.
patches:
@ -15471,7 +15479,7 @@ SLES-53045:
region: "PAL-M5"
compat: 5
SLES-53046:
name: "CT Special Forces - Fire for Effect"
name: "Counter Terrorist Special Forces - Fire for Effect"
region: "PAL-M5"
SLES-53047:
name: "Punisher, The"
@ -15497,7 +15505,7 @@ SLES-53059:
region: "PAL-E"
compat: 5
SLES-53060:
name: "Asterix & Obelix XXL 2 - Mission Las Vegum"
name: "Astérix & Obélix XXL 2 - Mission - Las Vegum"
region: "PAL-M3"
SLES-53061:
name: "Atari Anthology"
@ -17062,7 +17070,7 @@ SLES-53724:
name: "World Series of Poker"
region: "PAL-E"
SLES-53725:
name: "Asterix & Obelix XXL 2"
name: "Astérix & Obélix XXL 2 - Mission - Las Vegum"
region: "PAL-M5"
SLES-53726:
name: "Harry Potter and the Goblet of Fire"
@ -17366,7 +17374,7 @@ SLES-53848:
region: "PAL-M5"
compat: 5
SLES-53849:
name: "Asterix & Obelix XXL2"
name: "Astérix & Obélix XXL 2 - Mission - Las Vegum"
region: "PAL-M4"
SLES-53850:
name: "Teenage Mutant Ninja Turtles 3 - Mutant Nightmare"
@ -17536,10 +17544,10 @@ SLES-53920:
name: "Speed Machines 3"
region: "PAL-E"
SLES-53921:
name: "Sim Chemist"
name: "Chemist Tycoon"
region: "PAL-E"
SLES-53922:
name: "Car Wash Tycoon"
name: "Carwash Tycoon"
region: "PAL-E"
SLES-53923:
name: "London Cab Challenge"
@ -18143,10 +18151,10 @@ SLES-54188:
name: "Nickelodeon Avatar - The Legend of Aang"
region: "PAL-M4"
SLES-54193:
name: "Sudoku, Carol Vonderman's"
name: "Carol Vorderman's Sudoku"
region: "PAL-E"
SLES-54194:
name: "Sudoku, Carol Vonderman's"
name: "Carol Vorderman's Sudoku"
region: "PAL-M5"
SLES-54195:
name: "Turbo Trucks"
@ -21500,7 +21508,7 @@ SLES-82009:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
roundSprite: 2 # Fixes font artifacts.
SLES-82010:
name: "Metal Gear Solid 2, Document of"
@ -21527,10 +21535,10 @@ SLES-82013:
gsHWFixes:
halfPixelOffset: 2 # Fixes blurry characters.
SLES-82018:
name: "Cy Girls [Disc 1]"
name: "Cy Girls [Ice Disc]"
region: "PAL-E-F-S"
SLES-82019:
name: "Cy Girls [Disc 2]"
name: "Cy Girls [Aska Disc]"
region: "PAL-E-F-S"
memcardFilters:
- "SLES-82018"
@ -21769,7 +21777,7 @@ SLKA-15007:
gameFixes:
- OPHFlagHack
SLKA-15008:
name: "Choro Q HG2"
name: "Choro Q HG 2"
region: "NTSC-K"
gsHWFixes:
roundSprite: 2 # Fixes sprite ghosting.
@ -21945,6 +21953,8 @@ SLKA-25048:
SLKA-25049:
name: "Metal Slug 3"
region: "NTSC-K"
gsHWFixes:
gpuPaletteConversion: 2 # Stops excessive VRAM usage with preloading on.
SLKA-25050:
name: "Shin Sangoku Musou 3"
region: "NTSC-K"
@ -22847,7 +22857,7 @@ SLKA-35001:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
roundSprite: 2 # Fixes font artifacts.
SLKA-35003:
name: "Sakura Taisen - Atsuki Chishioni"
@ -22901,6 +22911,9 @@ SLPM-55039:
SLPM-55040:
name: "Soukoku no Kusabi - Hiiro no Kakera 3"
region: "NTSC-J"
SLPM-55041:
name: "Kanokon Esuii"
region: "NTSC-J"
SLPM-55042:
name: "Suika A.S+ Eternal Name - Sweet So Sweet [Best Edition]"
region: "NTSC-J"
@ -23279,6 +23292,9 @@ SLPM-55269:
region: "NTSC-J"
gameFixes:
- SoftwareRendererFMVHack # Vertical and horizontal lines in FMV.
SLPM-55270:
name: "Shinkyoku Soukai Polyphonica - After School"
region: "NTSC-J"
SLPM-55271:
name: "FIFA 10 - World Class Soccer [Ea -SY! 1980]"
region: "NTSC-J"
@ -23306,6 +23322,9 @@ SLPM-55283:
SLPM-55285:
name: "Crimson Empire"
region: "NTSC-J"
SLPM-55288:
name: "Shin Koihime Musou - Otome Ryouran - Sangokushi Engi"
region: "NTSC-J"
SLPM-55292:
name: "Grand Theft Auto - San Andreas [Rockstar Classics]"
region: "NTSC-J"
@ -23346,7 +23365,7 @@ SLPM-60109:
textureInsideRT: 1
halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
roundSprite: 1 # Fixes ui and hud alignment.
texturePreloading: 0 # Disabling for major speedup.
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
SLPM-60123:
name: "Gekikuukan Pro Baseball - The End of the Century 1999 [Trial]"
region: "NTSC-J"
@ -23680,7 +23699,7 @@ SLPM-62034:
name: "Jikkyou Powerful Pro Yakyuu 7 Ketteiban"
region: "NTSC-J"
SLPM-62035:
name: "Got to Do! Hot Spring Table Tennis"
name: "Iku ze! Onsen Takkyuu!!"
region: "NTSC-J"
SLPM-62036:
name: "Chou Kousoku Reversi"
@ -23835,7 +23854,7 @@ SLPM-62103:
name: "EX Okuman Chouja Game - The Money Battle"
region: "NTSC-J"
SLPM-62104:
name: "Choro-Q HG2"
name: "Choro Q HG 2"
region: "NTSC-J"
gsHWFixes:
roundSprite: 2 # Fixes sprite ghosting.
@ -23904,7 +23923,7 @@ SLPM-62128:
name: "Le Mans 24 Hours"
region: "NTSC-J"
SLPM-62129:
name: "Climax Tennis - WTA Tour Edition"
name: "Climax Tennis"
region: "NTSC-J"
SLPM-62130:
name: "Virtua Fighter 4"
@ -23973,7 +23992,7 @@ SLPM-62155:
name: "Baseball 2002, The - Battle Ball Park Sengen"
region: "NTSC-J"
SLPM-62157:
name: "Building Baku"
name: "Buile Baku"
region: "NTSC-J"
SLPM-62158:
name: "Virtua Fighter 4"
@ -24095,7 +24114,7 @@ SLPM-62211:
name: "18 Wheeler - American Pro Trucker"
region: "NTSC-J"
SLPM-62212:
name: "Critical Bullet - Seventh Target"
name: "Critical Bullet - 7th Target"
region: "NTSC-J"
SLPM-62213:
name: "Ultimate Fighting Championship 2 - Tap-Out"
@ -24185,7 +24204,7 @@ SLPM-62241:
mipmap: 1
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
SLPM-62244:
name: "Choro Q - High Grade 3"
name: "Choro Q HG 3"
region: "NTSC-J"
SLPM-62245:
name: "Yuusei kara no Buttai X - Episode II"
@ -24391,7 +24410,7 @@ SLPM-62321:
name: "Robocop"
region: "NTSC-J"
SLPM-62322:
name: "Conveni 3, The"
name: "Conveni 3, The - Ano Machi o Dokusen seyo"
region: "NTSC-J"
SLPM-62323:
name: "AI Shougi 2003"
@ -24477,7 +24496,7 @@ SLPM-62354:
name: "Space Invaders 25th Anniversary"
region: "NTSC-J"
SLPM-62355:
name: "Choro Q - High Grade 2"
name: "Choro Q HG 2"
region: "NTSC-J"
gsHWFixes:
roundSprite: 2 # Fixes sprite ghosting.
@ -25178,7 +25197,7 @@ SLPM-62594:
name: "Hot Gimmick Cosplay Mahjong - Pure"
region: "NTSC-J"
SLPM-62595:
name: "Choro Q - HG 3 [Takara The Best]"
name: "Choro Q HG 3 [Takara The Best]"
region: "NTSC-J"
SLPM-62596:
name: "EX Okuman Chouja Game [Takara The Best]"
@ -25545,7 +25564,7 @@ SLPM-62722:
name: "Jissen Pachi-Slot Hisshouhou! Ore no Sora"
region: "NTSC-J"
SLPM-62724:
name: "Conveti 4, The"
name: "Conveni 4, The - Ano Machi o Dokusen seyo"
region: "NTSC-J"
SLPM-62725:
name: "Mahjong Hoah - Shinken Battle II"
@ -25639,7 +25658,7 @@ SLPM-62760:
region: "NTSC-J"
compat: 5
SLPM-62761:
name: "Choro Q - HG 2 [Atlus Best Collection]"
name: "Choro Q HG 2 [Atlus Best Collection]"
region: "NTSC-J"
gsHWFixes:
roundSprite: 2 # Fixes sprite ghosting.
@ -25679,6 +25698,9 @@ SLPM-62774:
SLPM-62775:
name: "Sega Ages 2500 Vol.32 - Phantasy Star Complete Collection"
region: "NTSC-J"
SLPM-62777:
name: "Harukaze P. S. - Plus Situation"
region: "NTSC-J"
SLPM-62778:
name: "Slotter Up Mania 10 - Pioneer Special 3"
region: "NTSC-J"
@ -26048,7 +26070,7 @@ SLPM-65077:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
memcardFilters:
- "SLPM-65078"
- "SLPM-65077"
@ -26058,7 +26080,7 @@ SLPM-65078:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
memcardFilters:
- "SLPM-65078"
- "SLPM-65077"
@ -26078,7 +26100,7 @@ SLPM-65085:
name: "Alone in the Dark - The New Nightmare"
region: "NTSC-J"
SLPM-65086:
name: "Ayumi Hamasaki Dome Tour 2001 - A Visual Mix [Disc1of2]"
name: "Visual Mix - Ayumi Hamasaki Dome Tour 2001 [Disc1of2]"
region: "NTSC-J"
compat: 5
memcardFilters:
@ -26087,7 +26109,7 @@ SLPM-65086:
- "SLPM-65086"
- "SLPM-65087"
SLPM-65087:
name: "Ayumi Hamasaki Dome Tour 2001 - A Visual Mix [Disc2of2]"
name: "Visual Mix - Ayumi Hamasaki Dome Tour 2001 [Disc2of2]"
region: "NTSC-J"
compat: 5
memcardFilters:
@ -26337,6 +26359,8 @@ SLPM-65183:
SLPM-65184:
name: "Document of Metal Gear Solid 2, The"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes corrupted or missing menu fonts.
SLPM-65185:
name: "Ferrari F355 Challenge"
region: "NTSC-J"
@ -26594,8 +26618,10 @@ SLPM-65245:
roundSprite: 2 # Fixes font artifacts.
mergeSprite: 1 # Fixes flame-like bleeding.
SLPM-65246:
name: "Kaidou Battle"
name: "Kaidou Battle - Nikko, Haruna, Rokko, Hakone"
region: "NTSC-J"
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
SLPM-65247:
name: "Sangokushi Senki 2"
region: "NTSC-J"
@ -26619,7 +26645,7 @@ SLPM-65254:
name: "Galaxy Angel"
region: "NTSC-J"
SLPM-65255:
name: "Chobits"
name: "Chobits - Chii dake no Hito"
region: "NTSC-J"
gsHWFixes:
roundSprite: 2 # Reduces font artifacts.
@ -26765,7 +26791,7 @@ SLPM-65299:
name: "Konohana 3"
region: "NTSC-J"
SLPM-65300:
name: "All-Star Pro Wrestling 3"
name: "All-Star Pro Wrestling III"
region: "NTSC-J"
compat: 5
SLPM-65301:
@ -26872,7 +26898,7 @@ SLPM-65329:
name: "Makai Tensei"
region: "NTSC-J"
SLPM-65330:
name: "Akudaikan 2"
name: "Akudaikan 2 - Mousouden"
region: "NTSC-J"
SLPM-65331:
name: "Rockman X7"
@ -27085,7 +27111,7 @@ SLPM-65404:
name: "Kita He - Diamond Dust"
region: "NTSC-J"
SLPM-65405:
name: "Hyper Dimension Fortress Macross"
name: "Chou Jikuu Yousai Macross"
region: "NTSC-J"
compat: 5
SLPM-65406:
@ -27571,7 +27597,7 @@ SLPM-65553:
name: "Metal Wolf Rev"
region: "NTSC-J"
SLPM-65554:
name: "Croket Ban - King no Kiki wo Sukuu"
name: "Croket! Ban-King no Kiki o Sukue"
region: "NTSC-J"
SLPM-65555:
name: "Dragon Quest V - Bride of the Sky"
@ -27767,7 +27793,7 @@ SLPM-65619:
name: "Tom Clancy's Ghost Recon - Jungle Storm"
region: "NTSC-J"
SLPM-65620:
name: "Akudaikan 2 [Global The Best]"
name: "Akudaikan 2 - Mousouden [Global The Best]"
region: "NTSC-J"
SLPM-65621:
name: "Street Fighter III - 3rd Strike"
@ -29030,10 +29056,10 @@ SLPM-65995:
preloadFrameData: 1 # Fixes bad textures on Jake.
halfPixelOffset: 1 # Fixes double image.
SLPM-65996:
name: "Mars of Destruction [Limited Edition]"
name: "Hametsu no Mars [Limited Edition]"
region: "NTSC-J"
SLPM-65997:
name: "Mars of Destruction"
name: "Hametsu no Mars"
region: "NTSC-J"
SLPM-65998:
name: "Vampire Darkstalkers Collection"
@ -29431,11 +29457,14 @@ SLPM-66108:
- "SLAJ-25053"
- "SLPM-66204"
SLPM-66109:
name: "Code Age Commanders"
name: "Code Age Commanders - Tsugumono Tsugarerumono"
region: "NTSC-J"
SLPM-66110:
name: "Fushigi no Umi no Nadia - Inherit the Blue Water [Limited Edition]"
region: "NTSC-J"
SLPM-66111:
name: "Fushigi no Umi no Nadia - Dennou Battle - Miss Nautilus Contest"
region: "NTSC-J"
SLPM-66112:
name: "Fushigi no Umi no Nadia - Inherit the Blue Water"
region: "NTSC-J"
@ -29864,7 +29893,7 @@ SLPM-66229:
name: "GI Jockey 4"
region: "NTSC-J"
SLPM-66231:
name: "Karutagura - Tamashii no Kunou"
name: "Cartagra - Tamashii no Kunou"
region: "NTSC-J"
SLPM-66232:
name: "Need for Speed - Most Wanted"
@ -29935,7 +29964,7 @@ SLPM-66249:
gsHWFixes:
preloadFrameData: 1 # Fixes layers where characters should be visually behind an object.
SLPM-66250:
name: "Choro Q - HG 4 [Takara Best]"
name: "Choro Q HG 4 [Takara Best]"
region: "NTSC-J"
SLPM-66251:
name: "EX Jinsei Game II [Takara Best]"
@ -29978,10 +30007,10 @@ SLPM-66263:
speedHacks:
mvuFlagSpeedHack: 0 # Fixes bad graphics.
SLPM-66264:
name: "Canvas 2 - Niji-iro no Sketch [Deluxe Pack]"
name: "Canvas 2 - Nijiiro no Sketch [DX Pack]"
region: "NTSC-J"
SLPM-66265:
name: "Canvas 2 - Niji-iro no Sketch"
name: "Canvas 2 - Nijiiro no Sketch"
region: "NTSC-J"
SLPM-66266:
name: "Kurogane no Houkou 2 - Warship Commander [Koei The Best]"
@ -30862,7 +30891,7 @@ SLPM-66503:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLPM-66504:
name: "Onimusha 2 [Mega Hits]"
region: "NTSC-J"
@ -30965,7 +30994,7 @@ SLPM-66535:
name: "Ryu Koku"
region: "NTSC-J"
SLPM-66536:
name: "Aria - The Natural ~Tooi Yume no Mirage~"
name: "Aria - The Natural - Tooi Yume no Mirage"
region: "NTSC-J"
SLPM-66537:
name: "Iris no Atelier - Eternal Mana 2 [Gust Best Price]"
@ -31608,6 +31637,9 @@ SLPM-66708:
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
SLPM-66707:
name: "Yukinko Daisenpuu - Sayuki to Koyuki no Hie Hie Daisoudou"
region: "NTSC-J"
SLPM-66709:
name: "Angel Profile"
region: "NTSC-J"
@ -31921,7 +31953,7 @@ SLPM-66792:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLPM-66794:
name: "Metal Gear Solid 3 - Snake Eater [20th Anniversary Edition]"
region: "NTSC-J"
@ -32455,7 +32487,7 @@ SLPM-66966:
name: "Godfather, The [EA-SY! 1980]"
region: "NTSC-J"
SLPM-66967:
name: "Aria - The Natural ~Tooi Yume no Mirage~ [Alchemist Best Collection]"
name: "Aria - The Natural - Tooi Yume no Mirage [Alchemist Best Collection]"
region: "NTSC-J"
SLPM-66968:
name: "Kamiwaza [Acquire the Best]"
@ -32546,7 +32578,7 @@ SLPM-67002:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
roundSprite: 2 # Fixes font artifacts.
SLPM-67003:
name: "Sakura Taisen - Atsuki Chishioni"
@ -32570,7 +32602,7 @@ SLPM-67008:
name: "Metal Gear Solid 2 - Substance [Konami Dendou Collection]"
region: "NTSC-J"
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
roundSprite: 2 # Fixes font artifacts.
SLPM-67009:
name: "Sakura Taisen V - Saraba Itoshiki Hito Yo"
@ -32659,7 +32691,7 @@ SLPM-67515:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLPM-67518:
name: "Onimusha 2 Samurai's Destiny"
region: "NTSC-K"
@ -33146,7 +33178,7 @@ SLPS-20001:
textureInsideRT: 1
halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
roundSprite: 1 # Fixes ui and hud alignment.
texturePreloading: 0 # Disabling for major speedup.
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
SLPS-20002:
name: "Doukyu Billiards"
region: "NTSC-J"
@ -33542,7 +33574,7 @@ SLPS-20150:
name: "Akira Psycho Ball"
region: "NTSC-J"
SLPS-20158:
name: "Yamasa Digi World 2 LCD Edition - Time Cross Qlogos Trigger Zone"
name: "Yamasa Digi World 2 LCD Edition - Time Cross, Qlogos, Trigger Zone"
region: "NTSC-J"
SLPS-20161:
name: "Saikyou Toudai Shogi Special"
@ -33555,10 +33587,10 @@ SLPS-20163:
name: "Typing Kengo 634"
region: "NTSC-J"
SLPS-20165:
name: "La Pucelle"
name: "La Pucelle - Hikari no Seijo Densetsu [Limited Edition]"
region: "NTSC-J"
SLPS-20167:
name: "La Pucelle"
name: "La Pucelle - Hikari no Seijo Densetsu"
region: "NTSC-J"
SLPS-20168:
name: "NHL 2002"
@ -33650,6 +33682,9 @@ SLPS-20208:
SLPS-20209:
name: "Jissen Pachi-Slot Hisshouhou! Aladdin A [Limited Edition]"
region: "NTSC-J"
SLPS-20211:
name: "Yamasa Digi World 3 - Time Park, King Pulsar, Cyber Dragon"
region: "NTSC-J"
SLPS-20213:
name: "Hissatsu Pachinko Station V4 - Drumtic Mahjong"
region: "NTSC-J"
@ -33693,7 +33728,10 @@ SLPS-20222:
name: "Inaka Kurasi - Nan no Shima no Monogatari"
region: "NTSC-J"
SLPS-20226:
name: "Yamasa Digital Slot World SP DX"
name: "Yamasa Digi World SP DX - Neo Planett XX"
region: "NTSC-J"
SLPS-20227:
name: "Yamasa Digi World SP - Neo Planett XX"
region: "NTSC-J"
SLPS-20230:
name: "Chulip"
@ -33733,10 +33771,10 @@ SLPS-20256:
region: "NTSC-J"
compat: 5
SLPS-20257:
name: "Yamasa Digi World 4DX"
name: "Yamasa Digi World 4 DX - Penguin Paradise, Crazy Shaman R, Zakzak Senryoubako R, Destroyer XX, King Pulsar"
region: "NTSC-J"
SLPS-20258:
name: "Yamasa Digi World 4"
name: "Yamasa Digi World 4 - Penguin Paradise, Crazy Shaman R, Zakzak Senryoubako R, Destroyer XX, King Pulsar"
region: "NTSC-J"
SLPS-20259:
name: "Kotoba no Puzzle - Mojipittan"
@ -33853,6 +33891,9 @@ SLPS-20312:
SLPS-20314:
name: "Gold X"
region: "NTSC-J"
SLPS-20315:
name: "Yamasa Digi World SP - Neo Magic Pulsar XX"
region: "NTSC-J"
SLPS-20316:
name: "Hissatsu Pachinko Station v8"
region: "NTSC-J"
@ -33946,7 +33987,7 @@ SLPS-20354:
name: "Yamasa Digi World 3 [Best of Best]"
region: "NTSC-J"
SLPS-20355:
name: "Yamasa Digi World SP - Neo Magic Pulsar XX [Best of Best]"
name: "Yamasa Digi World SP - Neo Planett XX [Best of Best]"
region: "NTSC-J"
SLPS-20356:
name: "Yamasa Digi World 4 [Best of Best]"
@ -33970,7 +34011,7 @@ SLPS-20366:
name: "CR Kamen Rider Pachi-Slot Expert 5"
region: "NTSC-J"
SLPS-20367:
name: "Curry House Coco Ichibanya"
name: "Curry House CoCo Ichiban'ya - Kyou mo Genki da! Curry ga Umai!!"
region: "NTSC-J"
compat: 5
SLPS-20368:
@ -34062,7 +34103,7 @@ SLPS-20397:
name: "Pachitte Chonmage Tatsujin 7 - CR Pachinko Dokaben"
region: "NTSC-J"
SLPS-20398:
name: "La Pucelle - Hikari no Seijyo Densetsu Nijuu"
name: "La Pucelle - Hikari no Seijo Densetsu - 2-shuume Hajimemashita"
region: "NTSC-J"
SLPS-20399:
name: "Taiko no Tatsujin - Go! Go! Godaime [with Tatacon]"
@ -34473,7 +34514,7 @@ SLPS-25013:
speedHacks:
MTVUSpeedHack: 0 # Prevents broken textures and graphics.
SLPS-25014:
name: "Choro Q - High Grade [Limited Edition]"
name: "Choro Q HG [Jenny Hi-Grade Box]"
region: "NTSC-J"
patches:
6F9C4D7C:
@ -34485,7 +34526,7 @@ SLPS-25014:
// Before removing this patch, check initial loading with unformatted memory card.
patch=1,EE,0017B2A8,word,00000000
SLPS-25015:
name: "Choro Q - High Grade"
name: "Choro Q HG"
region: "NTSC-J"
patches:
6F9C4D7C:
@ -34524,7 +34565,7 @@ SLPS-25025:
gameFixes:
- EETimingHack # Correct graphics after changing scene.
SLPS-25026:
name: "Dead or Alive 2 - Hardcore"
name: "DOA 2 - Hardcore"
region: "NTSC-J"
compat: 5
patches:
@ -35152,6 +35193,8 @@ SLPS-25209:
name: "Metal Slug 3"
region: "NTSC-J"
compat: 5
gsHWFixes:
gpuPaletteConversion: 2 # Stops excessive VRAM usage with preloading on.
SLPS-25212:
name: "Giren no Yabou - Zeon Dokuritsu Sensouden"
region: "NTSC-J"
@ -35182,7 +35225,7 @@ SLPS-25221:
name: "Pia - Welcome to Carrot 3"
region: "NTSC-J"
SLPS-25223:
name: "Canvas"
name: "Canvas - Sepia-iro no Motif"
region: "NTSC-J"
SLPS-25224:
name: "Ai yori Aoshi [Shokai Genteiban]"
@ -35865,10 +35908,10 @@ SLPS-25414:
name: "To Heart 2"
region: "NTSC-J"
SLPS-25415:
name: "Chu-Kana Janshi [Collector's Edition]"
name: "Chuuka na Janshi - Tenhoo Painyan [Collector's Edition]"
region: "NTSC-J"
SLPS-25416:
name: "Chu Kana Janshi Tenho Pai-Nyan"
name: "Chuuka na Janshi - Tenhoo Painyan"
region: "NTSC-J"
SLPS-25417:
name: "Panzer Front Ausf.B [Enterbrain Collection]"
@ -35933,6 +35976,8 @@ SLPS-25427:
SLPS-25428:
name: "Metal Slug 3 [SNK Best Collection]"
region: "NTSC-J"
gsHWFixes:
gpuPaletteConversion: 2 # Stops excessive VRAM usage with preloading on.
SLPS-25429:
name: "King of Fighters 2000, The [SNK Best Collection]"
region: "NTSC-J"
@ -36326,12 +36371,12 @@ SLPS-25549:
name: "Gundam Seed Destiny - Generation of C.E."
region: "NTSC-J"
SLPS-25550:
name: "Cowboy Bebop - Tsuitou no Yakyoku [Limited Edition]"
name: "Cowboy Bebop - Tsuioku no Serenade [Limited Edition]"
region: "NTSC-J"
clampModes:
eeClampMode: 0 # Fixes HUD going black.
SLPS-25551:
name: "Cowboy Bebop - Tsuitou no Yakyoku"
name: "Cowboy Bebop - Tsuioku no Serenade"
region: "NTSC-J"
clampModes:
eeClampMode: 0 # Fixes HUD going black.
@ -36737,7 +36782,7 @@ SLPS-25653:
name: "Cluster Edge [Limited Edition]"
region: "NTSC-J"
SLPS-25654:
name: "Cluster Edge"
name: "Cluster Edge - Kimi o Matsu Mirai e no Akashi"
region: "NTSC-J"
SLPS-25655:
name: "dot hack G.U. Vol.2 - Kimi Omou Koe"
@ -37280,7 +37325,7 @@ SLPS-25808:
name: "Saint Beast - Rasen no Shou"
region: "NTSC-J"
SLPS-25809:
name: "Gintama Gin-San to Issho! Boku no Kabuki Machi Nikki"
name: "Gintama - Gin-san to Issho! Boku no Kabuki-chou Nikki"
region: "NTSC-J"
SLPS-25810:
name: "Dear My Sun"
@ -37616,6 +37661,9 @@ SLPS-25918:
region: "NTSC-J"
gsHWFixes:
roundSprite: 1 # Fixes character sprites.
SLPS-25919:
name: "Sengoku Tenka Touitsu"
region: "NTSC-J"
SLPS-25927:
name: "Tomb Raider - Underworld"
region: "NTSC-J"
@ -37677,6 +37725,9 @@ SLPS-25961:
eeRoundMode: 1 # Fixes camera issue.
gameFixes:
- FpuNegDivHack # Fixes target loss issue.
SLPS-25978:
name: "Shin Master of Monsters Final EX"
region: "NTSC-J"
SLPS-25983:
name: "King of Fighters 2002, The - Unlimited Match"
region: "NTSC-J"
@ -38223,7 +38274,7 @@ SLPS-73405:
halfPixelOffset: 2 # Reduces blurriness.
disablePartialInvalidation: 1 # Fixes ghost rendering.
SLPS-73406:
name: "Dead or Alive 2 - Hardcore [PlayStation 2 The Best]"
name: "DOA 2 - Hardcore [PlayStation 2 The Best]"
region: "NTSC-J"
compat: 5
SLPS-73407:
@ -38347,7 +38398,7 @@ SLUS-20002:
textureInsideRT: 1
halfPixelOffset: 2 # Fixes title screen and some intro post processing alignment.
roundSprite: 1 # Fixes ui and hud alignment.
texturePreloading: 0 # Disabling for major speedup.
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
SLUS-20003:
name: "Portal Runner"
region: "NTSC-U"
@ -38556,7 +38607,7 @@ SLUS-20070:
name: "Q-Ball Billiards Master"
region: "NTSC-U"
SLUS-20071:
name: "Dead or Alive 2"
name: "DOA 2 - Hardcore"
region: "NTSC-U"
compat: 5
patches:
@ -38790,7 +38841,7 @@ SLUS-20144:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLUS-20145:
name: "Ring of Red"
region: "NTSC-U"
@ -40554,6 +40605,8 @@ SLUS-20543:
name: "Document of Metal Gear Solid 2, The"
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack # Fixes corrupted or missing menu fonts.
SLUS-20544:
name: "Malice"
region: "NTSC-U"
@ -40575,7 +40628,7 @@ SLUS-20546:
patch=1,EE,00122780,word,27BDFD00
patch=1,EE,00122AE8,word,27BD0300
SLUS-20547:
name: "Cubix Showdown"
name: "Cubix Robots for Everyone - Showdown"
region: "NTSC-U"
compat: 5
SLUS-20548:
@ -40604,7 +40657,7 @@ SLUS-20554:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
roundSprite: 2 # Fixes font artifacts.
SLUS-20555:
name: "Reel Fishing 3"
@ -41289,7 +41342,7 @@ SLUS-20698:
clampModes:
eeClampMode: 2 # Needed for SPS on some characters.
SLUS-20699:
name: "Cowboy Bebop"
name: "Cowboy Bebop - Tsuioku no Serenade"
region: "NTSC-U"
SLUS-20701:
name: "Scooby-Doo! Mystery Mayhem"
@ -41607,6 +41660,7 @@ SLUS-20763:
textureInsideRT: 1 # Fixes the shape of shadows.
autoFlush: 1 # Fixes water rendering.
halfPixelOffset: 3 # Fixes bloom misalignment, needs this harsh offset for autoflush.
cpuFramebufferConversion: 1 # Fixes shield rendering.
SLUS-20764:
name: "Bombastic"
region: "NTSC-U"
@ -41670,6 +41724,7 @@ SLUS-20776:
cpuSpriteRenderBW: 1 # Fixes textures.
autoFlush: 1 # Fixes the position of the shadow and makes it not blocky.
halfPixelOffset: 1 # Fixes shadows.
gpuPaletteConversion: 0 # Stops potential crashes from too many palette textures.
SLUS-20777:
name: "Obscure"
region: "NTSC-U"
@ -42040,7 +42095,7 @@ SLUS-20865:
- "SLUS-20865"
- "SLUS-20704"
SLUS-20866:
name: "Asterix & Obelix XXL - Kick Buttix"
name: "Asterix & Obelix - Kick Buttix"
region: "NTSC-U"
compat: 5
SLUS-20867:
@ -44434,7 +44489,7 @@ SLUS-21328:
patch=1,EE,0016DDD0,word,4B00A29C
patch=1,EE,0016DDD8,word,4AF103BC
SLUS-21329:
name: "Karaoke Revolution Country - CMT Presents"
name: "CMT Presents - Karaoke Revolution - Country"
region: "NTSC-U"
compat: 3
SLUS-21330:
@ -46008,7 +46063,7 @@ SLUS-21666:
region: "NTSC-U"
compat: 5
SLUS-21668:
name: "George of the Jungle"
name: "George of the Jungle and the Search for the Secret"
region: "NTSC-U"
compat: 5
SLUS-21669:
@ -46391,7 +46446,7 @@ SLUS-21750:
name: "Hannah Montana - Spotlight World Tour"
region: "NTSC-U"
SLUS-21751:
name: "Backyard Football '09"
name: "Backyard Baseball '09"
region: "NTSC-U"
compat: 5
SLUS-21752:
@ -47333,7 +47388,7 @@ SLUS-28043:
name: "Test Drive - Eve of Destruction [Trade Demo]"
region: "NTSC-U"
SLUS-28044:
name: "ChoroQ [Trade Demo]"
name: "Choro Q [Trade Demo]"
region: "NTSC-U"
SLUS-28045:
name: "Shin Megami Tensei - Nocturne [Trade Demo]"
@ -47408,7 +47463,7 @@ SLUS-29003:
gameFixes:
- DMABusyHack # Fixes broken half-bottom artifacts.
gsHWFixes:
texturePreloading: 1 # Fixes micro stuttering.
gpuPaletteConversion: 2 # Fixes micro stuttering.
SLUS-29004:
name: "Unison & Dead or Alive 2 Hardcore [Demo]"
region: "NTSC-U"
@ -47642,6 +47697,7 @@ SLUS-29082:
textureInsideRT: 1 # Fixes the shape of shadows.
autoFlush: 1 # Fixes water rendering.
halfPixelOffset: 3 # Fixes bloom misalignment, needs this harsh offset for autoflush.
cpuFramebufferConversion: 1 # Fixes shield rendering.
SLUS-29083:
name: "Maximo vs. The Army of Zin [Demo]"
region: "NTSC-U"
@ -47714,7 +47770,7 @@ SLUS-29110:
clampModes:
vuClampMode: 3 # Fixes lighting on character models as caves and other locations don't turn mobs into glow-in-the-dark creatures by themselves.
SLUS-29111:
name: "Asterix & Obelix XXL - Kick Buttix [Demo]"
name: "Asterix & Obelix - Kick Buttix [Demo]"
region: "NTSC-U"
SLUS-29113:
name: "Burnout 3 [Demo]"

View File

@ -21,6 +21,7 @@
03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00001251000000000000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00001151000000000000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000150000000000000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000151000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00005106000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,guide:b2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,
@ -367,6 +368,7 @@
030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
@ -439,6 +441,7 @@
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b0,platform:Windows,
030000006f0e00000901000000000000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows,
03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002306000000000000,PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
@ -463,6 +466,7 @@
03000000666600006706000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000151a00006222000000000000,PS2 Dual Plus Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@ -740,6 +744,7 @@
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,
03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
# Mac OS X
@ -1045,11 +1050,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,
03000000503200000110000011010000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,
05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,
05000000503200000110000044010000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,
05000000503200000110000046010000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,
03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux,
03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,

View File

@ -1,6 +1,6 @@
# Once done, this will define
#
# LIBC_FOUND - system has libc
# LIBC_FOUND - system has libc
# LIBC_LIBRARIES - link these to use libc
if(LIBC_LIBRARIES)
@ -12,7 +12,7 @@ find_library(libm NAMES m)
# OSX doesn't have rt. On Linux timer and aio dependency.
if(APPLE)
find_library(libdl NAMES dl)
set(LIBC_LIBRARIES ${librt} ${libdl} ${libm})
set(LIBC_LIBRARIES ${librt} ${libdl} ${libm})
elseif(Linux)
find_library(libdl NAMES dl)
find_library(librt NAMES rt)
@ -23,7 +23,7 @@ else()
set(LIBC_LIBRARIES ${librt} ${libm})
endif()
# handle the QUIETLY and REQUIRED arguments and set LIBC_FOUND to TRUE if
# handle the QUIETLY and REQUIRED arguments and set LIBC_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libc DEFAULT_MSG LIBC_LIBRARIES)

View File

@ -123,7 +123,7 @@ else()
if(X11_API)
check_lib(X11_XCB X11-xcb X11/Xlib-xcb.h)
check_lib(XCB xcb xcb/xcb.h)
check_lib(XRANDR xrandr)
check_lib(XRANDR Xrandr X11/extensions/Xrandr.h)
endif()
if(Linux)

View File

@ -84,7 +84,7 @@ public:
void Evict(std::size_t count = 1)
{
while (m_items.size() >= count)
while (!m_items.empty() && count > 0)
{
typename MapType::iterator lowest = m_items.end();
for (auto iter = m_items.begin(); iter != m_items.end(); ++iter)
@ -93,6 +93,7 @@ public:
lowest = iter;
}
m_items.erase(lowest);
count--;
}
}
@ -118,7 +119,7 @@ public:
{
// evict if we went over
while (m_items.size() > m_max_capacity)
Evict(m_items.size() - (m_max_capacity - 1));
Evict(m_items.size() - m_max_capacity);
}
private:

View File

@ -67,9 +67,9 @@ void SettingsLoadWrapper::Entry(const char* section, const char* var, bool& valu
value = m_si.GetBoolValue(section, var, defvalue);
}
void SettingsLoadWrapper::Entry(const char* section, const char* var, double& value, const double defvalue /*= 0.0*/)
void SettingsLoadWrapper::Entry(const char* section, const char* var, float& value, const float defvalue /*= 0.0*/)
{
value = m_si.GetDoubleValue(section, var, defvalue);
value = m_si.GetFloatValue(section, var, defvalue);
}
void SettingsLoadWrapper::Entry(const char* section, const char* var, std::string& value, const std::string& default_value /*= std::string()*/)
@ -141,9 +141,9 @@ void SettingsSaveWrapper::Entry(const char* section, const char* var, bool& valu
m_si.SetBoolValue(section, var, value);
}
void SettingsSaveWrapper::Entry(const char* section, const char* var, double& value, const double defvalue /*= 0.0*/)
void SettingsSaveWrapper::Entry(const char* section, const char* var, float& value, const float defvalue /*= 0.0*/)
{
m_si.SetDoubleValue(section, var, value);
m_si.SetFloatValue(section, var, value);
}
void SettingsSaveWrapper::Entry(const char* section, const char* var, std::string& value, const std::string& default_value /*= std::string()*/)

View File

@ -29,7 +29,7 @@ public:
virtual void Entry(const char* section, const char* var, int& value, const int defvalue = 0) = 0;
virtual void Entry(const char* section, const char* var, uint& value, const uint defvalue = 0) = 0;
virtual void Entry(const char* section, const char* var, bool& value, const bool defvalue = false) = 0;
virtual void Entry(const char* section, const char* var, double& value, const double defvalue = 0.0) = 0;
virtual void Entry(const char* section, const char* var, float& value, const float defvalue = 0.0) = 0;
virtual void Entry(const char* section, const char* var, std::string& value, const std::string& default_value = std::string()) = 0;
// This special form of Entry is provided for bitfields, which cannot be passed by reference.
@ -65,7 +65,7 @@ public:
void Entry(const char* section, const char* var, int& value, const int defvalue = 0) override;
void Entry(const char* section, const char* var, uint& value, const uint defvalue = 0) override;
void Entry(const char* section, const char* var, bool& value, const bool defvalue = false) override;
void Entry(const char* section, const char* var, double& value, const double defvalue = 0.0) override;
void Entry(const char* section, const char* var, float& value, const float defvalue = 0.0) override;
void Entry(const char* section, const char* var, std::string& value, const std::string& default_value = std::string()) override;
bool EntryBitBool(const char* section, const char* var, bool value, const bool defvalue = false) override;
@ -86,7 +86,7 @@ public:
void Entry(const char* section, const char* var, int& value, const int defvalue = 0) override;
void Entry(const char* section, const char* var, uint& value, const uint defvalue = 0) override;
void Entry(const char* section, const char* var, bool& value, const bool defvalue = false) override;
void Entry(const char* section, const char* var, double& value, const double defvalue = 0.0) override;
void Entry(const char* section, const char* var, float& value, const float defvalue = 0.0) override;
void Entry(const char* section, const char* var, std::string& value, const std::string& default_value = std::string()) override;
bool EntryBitBool(const char* section, const char* var, bool value, const bool defvalue = false) override;

View File

@ -38,6 +38,18 @@ const char* EnumToString(SSE_RoundMode sse)
}
}
SSE_MXCSR SSE_MXCSR::GetCurrent()
{
SSE_MXCSR ret;
ret.bitmask = _mm_getcsr();
return ret;
}
void SSE_MXCSR::SetCurrent(const SSE_MXCSR& value)
{
_mm_setcsr(value.bitmask);
}
SSE_RoundMode SSE_MXCSR::GetRoundMode() const
{
return (SSE_RoundMode)RoundingControl;

View File

@ -185,6 +185,9 @@ union SSE_MXCSR
FlushToZero : 1;
};
static SSE_MXCSR GetCurrent();
static void SetCurrent(const SSE_MXCSR& value);
SSE_RoundMode GetRoundMode() const;
SSE_MXCSR& SetRoundMode(SSE_RoundMode mode);
SSE_MXCSR& ClearExceptionFlags();

View File

@ -454,7 +454,8 @@ void AutoUpdaterDialog::checkIfUpdateNeeded()
void AutoUpdaterDialog::skipThisUpdateClicked()
{
QtHost::SetBaseStringSettingValue("AutoUpdater", "LastVersion", m_latest_version.toUtf8().constData());
Host::SetBaseStringSettingValue("AutoUpdater", "LastVersion", m_latest_version.toUtf8().constData());
Host::CommitBaseSettingChanges();
done(0);
}

View File

@ -20,8 +20,6 @@ target_sources(pcsx2-qt PRIVATE
DisplayWidget.cpp
DisplayWidget.h
EarlyHardwareCheck.cpp
EmuThread.cpp
EmuThread.h
MainWindow.cpp
MainWindow.h
MainWindow.ui

View File

@ -20,7 +20,6 @@
#include "pcsx2/Frontend/ImGuiManager.h"
#include "DisplayWidget.h"
#include "EmuThread.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,189 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "pcsx2/Host.h"
#include "pcsx2/HostDisplay.h"
#include "pcsx2/Frontend/InputManager.h"
#include <QtCore/QList>
#include <QtCore/QEventLoop>
#include <QtCore/QPair>
#include <QtCore/QString>
#include <QtCore/QSemaphore>
#include <QtCore/QTimer>
#include <QtCore/QThread>
#include <atomic>
#include <memory>
class DisplayWidget;
struct VMBootParameters;
enum class CDVD_SourceType : uint8_t;
class EmuThread : public QThread
{
Q_OBJECT
public:
explicit EmuThread(QThread* ui_thread);
~EmuThread();
static void start();
static void stop();
__fi QEventLoop* getEventLoop() const { return m_event_loop; }
__fi bool isFullscreen() const { return m_is_fullscreen; }
__fi bool isRenderingToMain() const { return m_is_rendering_to_main; }
__fi bool isSurfaceless() const { return m_is_surfaceless; }
__fi bool isRunningFullscreenUI() const { return m_run_fullscreen_ui; }
bool isOnEmuThread() const;
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
HostDisplay* acquireHostDisplay(HostDisplay::RenderAPI api);
void connectDisplaySignals(DisplayWidget* widget);
void releaseHostDisplay();
void updateDisplay();
void startBackgroundControllerPollTimer();
void stopBackgroundControllerPollTimer();
void updatePerformanceMetrics(bool force);
public Q_SLOTS:
bool confirmMessage(const QString& title, const QString& message);
void startFullscreenUI(bool fullscreen);
void stopFullscreenUI();
void startVM(std::shared_ptr<VMBootParameters> boot_params);
void resetVM();
void setVMPaused(bool paused);
void shutdownVM(bool save_state = true);
void loadState(const QString& filename);
void loadStateFromSlot(qint32 slot);
void saveState(const QString& filename);
void saveStateToSlot(qint32 slot);
void toggleFullscreen();
void setFullscreen(bool fullscreen);
void setSurfaceless(bool surfaceless);
void applySettings();
void reloadGameSettings();
void updateEmuFolders();
void toggleSoftwareRendering();
void switchRenderer(GSRendererType renderer);
void changeDisc(CDVD_SourceType source, const QString& path);
void reloadPatches();
void reloadInputSources();
void reloadInputBindings();
void requestDisplaySize(float scale);
void enumerateInputDevices();
void enumerateVibrationMotors();
void runOnCPUThread(const std::function<void()>& func);
void queueSnapshot(quint32 gsdump_frames);
Q_SIGNALS:
bool messageConfirmed(const QString& title, const QString& message);
DisplayWidget* onCreateDisplayRequested(bool fullscreen, bool render_to_main);
DisplayWidget* onUpdateDisplayRequested(bool fullscreen, bool render_to_main, bool surfaceless);
void onResizeDisplayRequested(qint32 width, qint32 height);
void onDestroyDisplayRequested();
/// Called when the VM is starting initialization, but has not been completed yet.
void onVMStarting();
/// Called when the VM is created.
void onVMStarted();
/// Called when the VM is paused.
void onVMPaused();
/// Called when the VM is resumed after being paused.
void onVMResumed();
/// Called when the VM is shut down or destroyed.
void onVMStopped();
/// Provided by the host; called when the running executable changes.
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
void onInputDeviceDisconnected(const QString& identifier);
void onVibrationMotorsEnumerated(const QList<InputBindingKey>& motors);
/// Called when a save state is loading, before the file is processed.
void onSaveStateLoading(const QString& path);
/// Called after a save state is successfully loaded. If the save state was invalid, was_successful will be false.
void onSaveStateLoaded(const QString& path, bool was_successful);
/// Called when a save state is being created/saved. The compression/write to disk is asynchronous, so this callback
/// just signifies that the save has started, not necessarily completed.
void onSaveStateSaved(const QString& path);
protected:
void run();
private:
/// Interval at which the controllers are polled when the system is not active.
static constexpr u32 BACKGROUND_CONTROLLER_POLLING_INTERVAL = 100;
/// Poll at half the vsync rate for FSUI to reduce the chance of getting a press+release in the same frame.
static constexpr u32 FULLSCREEN_UI_CONTROLLER_POLLING_INTERVAL = 8;
void destroyVM();
void executeVM();
void checkForSettingChanges();
bool shouldRenderToMain() const;
void createBackgroundControllerPollTimer();
void destroyBackgroundControllerPollTimer();
void connectSignals();
void loadOurSettings();
void loadOurInitialSettings();
private Q_SLOTS:
void stopInThread();
void doBackgroundControllerPoll();
void onDisplayWindowResized(int width, int height, float scale);
void onApplicationStateChanged(Qt::ApplicationState state);
void redrawDisplayWindow();
private:
QThread* m_ui_thread;
QSemaphore m_started_semaphore;
QEventLoop* m_event_loop = nullptr;
QTimer* m_background_controller_polling_timer = nullptr;
std::atomic_bool m_shutdown_flag{false};
bool m_verbose_status = false;
bool m_run_fullscreen_ui = false;
bool m_is_rendering_to_main = false;
bool m_is_fullscreen = false;
bool m_is_surfaceless = false;
bool m_save_state_on_shutdown = false;
bool m_pause_on_focus_loss = false;
bool m_was_paused_by_focus_loss = false;
float m_last_speed = 0.0f;
float m_last_game_fps = 0.0f;
float m_last_video_fps = 0.0f;
int m_last_internal_width = 0;
int m_last_internal_height = 0;
GSRendererType m_last_renderer = GSRendererType::Null;
};
extern EmuThread* g_emu_thread;

View File

@ -27,6 +27,7 @@
#include <QtWidgets/QApplication>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMenu>
#include <QtWidgets/QScrollBar>
#include "GameListModel.h"
#include "GameListRefreshThread.h"
@ -80,7 +81,10 @@ public:
return false;
if (m_filter_region != GameList::Region::Count && entry->region != m_filter_region)
return false;
if (!m_filter_name.isEmpty() && !QString::fromStdString(entry->title).contains(m_filter_name, Qt::CaseInsensitive))
if (!m_filter_name.isEmpty() &&
!QString::fromStdString(entry->path).contains(m_filter_name, Qt::CaseInsensitive) &&
!QString::fromStdString(entry->serial).contains(m_filter_name, Qt::CaseInsensitive) &&
!QString::fromStdString(entry->title).contains(m_filter_name, Qt::CaseInsensitive))
return false;
}
@ -184,6 +188,7 @@ void GameListWidget::initialize()
m_list_view->setFrameStyle(QFrame::NoFrame);
m_list_view->setSpacing(m_model->getCoverArtSpacing());
m_list_view->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
m_list_view->verticalScrollBar()->setSingleStep(15);
updateListFont();
@ -246,8 +251,10 @@ void GameListWidget::cancelRefresh()
m_refresh_thread->cancel();
m_refresh_thread->wait();
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
pxAssertRel(!m_refresh_thread, "Game list thread should be unreferenced by now");
// Cancelling might not be instant if we're say, scanning a gzip dump. Wait until it's done.
while (m_refresh_thread)
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
}
void GameListWidget::refreshImages()
@ -347,7 +354,8 @@ void GameListWidget::onTableViewHeaderSortIndicatorChanged(int, Qt::SortOrder)
void GameListWidget::listZoom(float delta)
{
const float new_scale = std::clamp(m_model->getCoverScale() + delta, MIN_SCALE, MAX_SCALE);
QtHost::SetBaseFloatSettingValue("UI", "GameListCoverArtScale", new_scale);
Host::SetBaseFloatSettingValue("UI", "GameListCoverArtScale", new_scale);
Host::CommitBaseSettingChanges();
m_model->setCoverScale(new_scale);
m_model->updateCacheSize(width(), height());
updateListFont();
@ -368,7 +376,8 @@ void GameListWidget::gridIntScale(int int_scale)
{
const float new_scale = std::clamp(static_cast<float>(int_scale) / 100.0f, MIN_SCALE, MAX_SCALE);
QtHost::SetBaseFloatSettingValue("UI", "GameListCoverArtScale", new_scale);
Host::SetBaseFloatSettingValue("UI", "GameListCoverArtScale", new_scale);
Host::CommitBaseSettingChanges();
m_model->setCoverScale(new_scale);
m_model->updateCacheSize(width(), height());
updateListFont();
@ -389,7 +398,8 @@ void GameListWidget::showGameList()
return;
}
QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", false);
Host::SetBaseBoolSettingValue("UI", "GameListGridView", false);
Host::CommitBaseSettingChanges();
m_ui.stack->setCurrentIndex(0);
resizeTableViewColumnsToFit();
updateToolbar();
@ -405,7 +415,8 @@ void GameListWidget::showGameGrid()
return;
}
QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", true);
Host::SetBaseBoolSettingValue("UI", "GameListGridView", true);
Host::CommitBaseSettingChanges();
m_ui.stack->setCurrentIndex(1);
updateToolbar();
emit layoutChange();
@ -416,7 +427,8 @@ void GameListWidget::setShowCoverTitles(bool enabled)
if (m_model->getShowCoverTitles() == enabled)
return;
QtHost::SetBaseBoolSettingValue("UI", "GameListShowCoverTitles", enabled);
Host::SetBaseBoolSettingValue("UI", "GameListShowCoverTitles", enabled);
Host::CommitBaseSettingChanges();
m_model->setShowCoverTitles(enabled);
if (isShowingGameGrid())
m_model->refresh();
@ -508,14 +520,16 @@ void GameListWidget::saveTableViewColumnVisibilitySettings()
for (int column = 0; column < GameListModel::Column_Count; column++)
{
const bool visible = !m_table_view->isColumnHidden(column);
QtHost::SetBaseBoolSettingValue("GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), visible);
Host::SetBaseBoolSettingValue("GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), visible);
Host::CommitBaseSettingChanges();
}
}
void GameListWidget::saveTableViewColumnVisibilitySettings(int column)
{
const bool visible = !m_table_view->isColumnHidden(column);
QtHost::SetBaseBoolSettingValue("GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), visible);
Host::SetBaseBoolSettingValue("GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), visible);
Host::CommitBaseSettingChanges();
}
void GameListWidget::loadTableViewColumnSortSettings()
@ -538,11 +552,12 @@ void GameListWidget::saveTableViewColumnSortSettings()
if (sort_column >= 0 && sort_column < GameListModel::Column_Count)
{
QtHost::SetBaseStringSettingValue(
Host::SetBaseStringSettingValue(
"GameListTableView", "SortColumn", GameListModel::getColumnName(static_cast<GameListModel::Column>(sort_column)));
}
QtHost::SetBaseBoolSettingValue("GameListTableView", "SortDescending", sort_descending);
Host::SetBaseBoolSettingValue("GameListTableView", "SortDescending", sort_descending);
Host::CommitBaseSettingChanges();
}
const GameList::Entry* GameListWidget::getSelectedEntry() const

View File

@ -29,8 +29,6 @@
#include "common/FileSystem.h"
#include "common/Path.h"
#include "Frontend/INISettingsInterface.h"
#include "pcsx2/CDVD/CDVDcommon.h"
#include "pcsx2/CDVD/CDVDdiscReader.h"
#include "pcsx2/Frontend/GameList.h"
@ -38,13 +36,13 @@
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/HostDisplay.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/Recording/InputRecording.h"
#include "AboutDialog.h"
#include "AutoUpdaterDialog.h"
#include "DisplayWidget.h"
#include "EmuThread.h"
#include "GameList/GameListRefreshThread.h"
#include "GameList/GameListWidget.h"
#include "MainWindow.h"
@ -240,6 +238,7 @@ void MainWindow::setupAdditionalUi()
}
updateEmulationActions(false, false);
updateDisplayRelatedActions(false, false, false);
}
void MainWindow::connectSignals()
@ -312,23 +311,17 @@ void MainWindow::connectSignals()
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionViewStatusBarVerbose, "UI", "VerboseStatusBar", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableSystemConsole, "Logging", "EnableSystemConsole", false);
connect(m_ui.actionEnableSystemConsole, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
#ifndef PCSX2_DEVBUILD
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableVerboseLogging, "Logging", "EnableVerbose", false);
connect(m_ui.actionEnableVerboseLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
#else
// Dev builds always have verbose logging.
m_ui.actionEnableVerboseLogging->setChecked(true);
m_ui.actionEnableVerboseLogging->setEnabled(false);
#endif
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", true);
connect(m_ui.actionEnableEEConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", true);
connect(m_ui.actionEnableIOPConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableFileLogging, "Logging", "EnableFileLogging", false);
connect(m_ui.actionEnableFileLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableLogTimestamps, "Logging", "EnableTimestamps", true);
connect(m_ui.actionEnableLogTimestamps, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableCDVDVerboseReads, "EmuCore", "CdvdVerboseReads", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionSaveBlockDump, "EmuCore", "CdvdDumpBlocks", false);
connect(m_ui.actionSaveBlockDump, &QAction::toggled, this, &MainWindow::onBlockDumpActionToggled);
@ -340,9 +333,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionInputRecPlay, &QAction::triggered, this, &MainWindow::onInputRecPlayActionTriggered);
connect(m_ui.actionInputRecStop, &QAction::triggered, this, &MainWindow::onInputRecStopActionTriggered);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionInputRecConsoleLogs, "Logging", "EnableInputRecordingLogs", false);
connect(m_ui.actionInputRecConsoleLogs, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionInputRecControllerLogs, "Logging", "EnableControllerLogs", false);
connect(m_ui.actionInputRecControllerLogs, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
// These need to be queued connections to stop crashing due to menus opening/closing and switching focus.
connect(m_game_list_widget, &GameListWidget::refreshProgress, this, &MainWindow::onGameListRefreshProgress);
@ -404,6 +395,37 @@ void MainWindow::recreate()
deleteLater();
}
void MainWindow::recreateSettings()
{
QString current_category;
if (m_settings_dialog)
{
current_category = m_settings_dialog->getCategory();
m_settings_dialog->hide();
m_settings_dialog->deleteLater();
m_settings_dialog = nullptr;
}
doSettings(current_category.toUtf8().constData());
}
void MainWindow::resetSettings(bool ui)
{
Host::RequestResetSettings(false, true, false, false, ui);
if (ui)
{
// UI reset includes theme (and eventually language).
// Just updating the theme here, when there's no change, causes Qt to get very confused..
// So, we'll just tear down everything and recreate. We'll need to do that for language
// resets eventaully anyway.
recreate();
}
// g_main_window here for recreate() case above.
g_main_window->recreateSettings();
}
void MainWindow::updateApplicationTheme()
{
if (!s_unthemed_style_name_set)
@ -737,7 +759,8 @@ void MainWindow::onBlockDumpActionToggled(bool checked)
return;
}
QtHost::SetBaseStringSettingValue("EmuCore", "BlockDumpSaveDirectory", new_dir.toUtf8().constData());
Host::SetBaseStringSettingValue("EmuCore", "BlockDumpSaveDirectory", new_dir.toUtf8().constData());
Host::CommitBaseSettingChanges();
}
void MainWindow::saveStateToConfig()
@ -750,7 +773,10 @@ void MainWindow::saveStateToConfig()
const QByteArray geometry_b64 = geometry.toBase64();
const std::string old_geometry_b64 = Host::GetBaseStringSettingValue("UI", "MainWindowGeometry");
if (old_geometry_b64 != geometry_b64.constData())
QtHost::SetBaseStringSettingValue("UI", "MainWindowGeometry", geometry_b64.constData());
{
Host::SetBaseStringSettingValue("UI", "MainWindowGeometry", geometry_b64.constData());
Host::CommitBaseSettingChanges();
}
}
{
@ -758,7 +784,10 @@ void MainWindow::saveStateToConfig()
const QByteArray state_b64 = state.toBase64();
const std::string old_state_b64 = Host::GetBaseStringSettingValue("UI", "MainWindowState");
if (old_state_b64 != state_b64.constData())
QtHost::SetBaseStringSettingValue("UI", "MainWindowState", state_b64.constData());
{
Host::SetBaseStringSettingValue("UI", "MainWindowState", state_b64.constData());
Host::CommitBaseSettingChanges();
}
}
}
@ -806,7 +835,6 @@ void MainWindow::updateEmulationActions(bool starting, bool running)
m_ui.actionSaveState->setEnabled(running);
m_ui.menuSaveState->setEnabled(running);
m_ui.menuWindowSize->setEnabled(starting_or_running);
m_ui.actionViewGameProperties->setEnabled(running);
@ -820,6 +848,19 @@ void MainWindow::updateEmulationActions(bool starting, bool running)
m_ui.actionRescanAllGames->setDisabled(starting_or_running);
}
void MainWindow::updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen)
{
// rendering to main, or switched to gamelist/grid
m_ui.actionViewSystemDisplay->setEnabled((has_surface && render_to_main) || (!has_surface && g_host_display));
m_ui.menuWindowSize->setEnabled(has_surface && !fullscreen);
m_ui.actionFullscreen->setEnabled(has_surface);
{
QSignalBlocker blocker(m_ui.actionFullscreen);
m_ui.actionFullscreen->setChecked(fullscreen);
}
}
void MainWindow::updateStatusBarWidgetVisibility()
{
auto Update = [this](QWidget* widget, bool visible, int stretch) {
@ -922,11 +963,10 @@ bool MainWindow::isShowingGameList() const
bool MainWindow::isRenderingFullscreen() const
{
HostDisplay* display = Host::GetHostDisplay();
if (!display || !m_display_widget)
if (!g_host_display || !m_display_widget)
return false;
return getDisplayContainer()->isFullScreen() || display->IsFullscreen();
return getDisplayContainer()->isFullScreen() || g_host_display->IsFullscreen();
}
bool MainWindow::isRenderingToMain() const
@ -1309,19 +1349,22 @@ void MainWindow::onSaveStateMenuAboutToShow()
void MainWindow::onViewToolbarActionToggled(bool checked)
{
QtHost::SetBaseBoolSettingValue("UI", "ShowToolbar", checked);
Host::SetBaseBoolSettingValue("UI", "ShowToolbar", checked);
Host::CommitBaseSettingChanges();
m_ui.toolBar->setVisible(checked);
}
void MainWindow::onViewLockToolbarActionToggled(bool checked)
{
QtHost::SetBaseBoolSettingValue("UI", "LockToolbar", checked);
Host::SetBaseBoolSettingValue("UI", "LockToolbar", checked);
Host::CommitBaseSettingChanges();
m_ui.toolBar->setMovable(!checked);
}
void MainWindow::onViewStatusBarActionToggled(bool checked)
{
QtHost::SetBaseBoolSettingValue("UI", "ShowStatusBar", checked);
Host::SetBaseBoolSettingValue("UI", "ShowStatusBar", checked);
Host::CommitBaseSettingChanges();
m_ui.statusBar->setVisible(checked);
}
@ -1389,7 +1432,8 @@ void MainWindow::onAboutActionTriggered()
void MainWindow::onCheckForUpdatesActionTriggered()
{
// Wipe out the last version, that way it displays the update if we've previously skipped it.
QtHost::RemoveBaseSettingValue("AutoUpdater", "LastVersion");
Host::RemoveBaseSettingValue("AutoUpdater", "LastVersion");
Host::CommitBaseSettingChanges();
checkForUpdates(true);
}
@ -1459,11 +1503,6 @@ void MainWindow::updateTheme()
m_game_list_widget->refreshImages();
}
void MainWindow::onLoggingOptionChanged()
{
Host::UpdateLogging(QtHost::InNoGUIMode());
}
void MainWindow::onInputRecNewActionTriggered()
{
const bool wasPaused = s_vm_paused;
@ -1717,12 +1756,11 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
{
DevCon.WriteLn("createDisplay(%u, %u)", static_cast<u32>(fullscreen), static_cast<u32>(render_to_main));
HostDisplay* host_display = Host::GetHostDisplay();
if (!host_display)
if (!g_host_display)
return nullptr;
const std::string fullscreen_mode(Host::GetBaseStringSettingValue("EmuCore/GS", "FullscreenMode", ""));
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty() && host_display->SupportsFullscreen());
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty() && g_host_display->SupportsFullscreen());
createDisplayWidget(fullscreen, render_to_main, is_exclusive_fullscreen);
@ -1739,7 +1777,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
g_emu_thread->connectDisplaySignals(m_display_widget);
if (!host_display->CreateRenderDevice(wi.value(), Host::GetStringSettingValue("EmuCore/GS", "Adapter", ""), EmuConfig.GetEffectiveVsyncMode(),
if (!g_host_display->CreateRenderDevice(wi.value(), Host::GetStringSettingValue("EmuCore/GS", "Adapter", ""), EmuConfig.GetEffectiveVsyncMode(),
Host::GetBoolSettingValue("EmuCore/GS", "ThreadedPresentation", false), Host::GetBoolSettingValue("EmuCore/GS", "UseDebugDevice", false)))
{
QMessageBox::critical(this, tr("Error"), tr("Failed to create host display device context."));
@ -1755,8 +1793,6 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
updateWindowTitle();
updateWindowState();
m_ui.actionViewSystemDisplay->setEnabled(true);
m_ui.actionFullscreen->setEnabled(true);
m_ui.actionStartFullscreenUI->setEnabled(false);
m_ui.actionStartFullscreenUI2->setEnabled(false);
@ -1765,7 +1801,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
m_display_widget->setFocus();
host_display->DoneRenderContextCurrent();
g_host_display->DoneRenderContextCurrent();
return m_display_widget;
}
@ -1774,12 +1810,11 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
DevCon.WriteLn("updateDisplay() fullscreen=%s render_to_main=%s surfaceless=%s",
fullscreen ? "true" : "false", render_to_main ? "true" : "false", surfaceless ? "true" : "false");
HostDisplay* host_display = Host::GetHostDisplay();
QWidget* container = m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget);
const bool is_fullscreen = isRenderingFullscreen();
const bool is_rendering_to_main = isRenderingToMain();
const std::string fullscreen_mode(Host::GetBaseStringSettingValue("EmuCore/GS", "FullscreenMode", ""));
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty() && host_display->SupportsFullscreen());
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty() && g_host_display->SupportsFullscreen());
const bool changing_surfaceless = (!m_display_widget != surfaceless);
if (fullscreen == is_fullscreen && is_rendering_to_main == render_to_main && !changing_surfaceless)
return m_display_widget;
@ -1791,8 +1826,8 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
if (!is_rendering_to_main && !render_to_main && !is_exclusive_fullscreen && has_container == needs_container && !needs_container && !changing_surfaceless)
{
DevCon.WriteLn("Toggling to %s without recreating surface", (fullscreen ? "fullscreen" : "windowed"));
if (host_display->IsFullscreen())
host_display->SetFullscreen(false, 0, 0, 0.0f);
if (g_host_display->IsFullscreen())
g_host_display->SetFullscreen(false, 0, 0, 0.0f);
// since we don't destroy the display widget, we need to save it here
if (!is_fullscreen && !is_rendering_to_main)
@ -1817,7 +1852,7 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
return m_display_widget;
}
host_display->DestroyRenderSurface();
g_host_display->DestroyRenderSurface();
destroyDisplayWidget(surfaceless);
@ -1837,7 +1872,7 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
g_emu_thread->connectDisplaySignals(m_display_widget);
if (!host_display->ChangeRenderWindow(wi.value()))
if (!g_host_display->ChangeRenderWindow(wi.value()))
pxFailRel("Failed to recreate surface on new widget.");
if (is_exclusive_fullscreen)
@ -1851,8 +1886,6 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused);
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
QSignalBlocker blocker(m_ui.actionFullscreen);
m_ui.actionFullscreen->setChecked(fullscreen);
return m_display_widget;
}
@ -1919,6 +1952,8 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main, bool
m_ui.mainContainer->setCurrentIndex(1);
}
updateDisplayRelatedActions(true, render_to_main, fullscreen);
// We need the surface visible.
QGuiApplication::sync();
}
@ -2004,6 +2039,8 @@ void MainWindow::destroyDisplayWidget(bool show_game_list)
m_display_container->deleteLater();
m_display_container = nullptr;
}
updateDisplayRelatedActions(false, false, false);
}
void MainWindow::focusDisplayWidget()
@ -2032,7 +2069,10 @@ void MainWindow::saveDisplayWindowGeometryToConfig()
const QByteArray geometry_b64 = geometry.toBase64();
const std::string old_geometry_b64 = Host::GetBaseStringSettingValue("UI", "DisplayWindowGeometry");
if (old_geometry_b64 != geometry_b64.constData())
QtHost::SetBaseStringSettingValue("UI", "DisplayWindowGeometry", geometry_b64.constData());
{
Host::SetBaseStringSettingValue("UI", "DisplayWindowGeometry", geometry_b64.constData());
Host::CommitBaseSettingChanges();
}
}
void MainWindow::restoreDisplayWindowGeometryFromConfig()
@ -2060,7 +2100,7 @@ void MainWindow::setDisplayFullscreen(const std::string& fullscreen_mode)
float refresh_rate;
if (HostDisplay::ParseFullscreenMode(fullscreen_mode, &width, &height, &refresh_rate))
{
if (Host::GetHostDisplay()->SetFullscreen(true, width, height, refresh_rate))
if (g_host_display->SetFullscreen(true, width, height, refresh_rate))
{
Host::AddOSDMessage("Acquired exclusive fullscreen.", 10.0f);
}

View File

@ -85,6 +85,7 @@ public:
void initialize();
void connectVMThreadSignals(EmuThread* thread);
void startupUpdateCheck();
void resetSettings(bool ui);
/// Locks the VM by pausing it, while a popup dialog is displayed.
VMLock pauseAndLockVM();
@ -148,7 +149,6 @@ private Q_SLOTS:
void onCheckForUpdatesActionTriggered();
void onToolsOpenDataDirectoryTriggered();
void updateTheme();
void onLoggingOptionChanged();
void onScreenshotActionTriggered();
void onSaveGSDumpActionTriggered();
void onBlockDumpActionToggled(bool checked);
@ -167,8 +167,6 @@ private Q_SLOTS:
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
void recreate();
protected:
void showEvent(QShowEvent* event) override;
void closeEvent(QCloseEvent* event) override;
@ -186,11 +184,14 @@ private:
void setupAdditionalUi();
void connectSignals();
void recreate();
void recreateSettings();
void saveStateToConfig();
void restoreStateFromConfig();
void updateEmulationActions(bool starting, bool running);
void updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen);
void updateStatusBarWidgetVisibility();
void updateWindowTitle();
void updateWindowState(bool force_visible = false);

File diff suppressed because it is too large Load Diff

View File

@ -14,30 +14,196 @@
*/
#pragma once
#include <atomic>
#include <memory>
#include <functional>
#include <optional>
#include "pcsx2/Host.h"
#include "pcsx2/HostDisplay.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/VMManager.h"
#include <QtCore/QList>
#include <QtCore/QEventLoop>
#include <QtCore/QMetaType>
#include <QtCore/QPair>
#include <QtCore/QString>
#include <functional>
#include <memory>
#include <optional>
#include <QtCore/QSemaphore>
#include <QtCore/QString>
#include <QtCore/QTimer>
#include <QtCore/QThread>
class SettingsInterface;
class EmuThread;
class DisplayWidget;
struct VMBootParameters;
enum class CDVD_SourceType : uint8_t;
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
Q_DECLARE_METATYPE(std::optional<bool>);
Q_DECLARE_METATYPE(std::function<void()>);
Q_DECLARE_METATYPE(GSRendererType);
Q_DECLARE_METATYPE(InputBindingKey);
Q_DECLARE_METATYPE(CDVD_SourceType);
class EmuThread : public QThread
{
Q_OBJECT
public:
explicit EmuThread(QThread* ui_thread);
~EmuThread();
static void start();
static void stop();
__fi QEventLoop* getEventLoop() const { return m_event_loop; }
__fi bool isFullscreen() const { return m_is_fullscreen; }
__fi bool isRenderingToMain() const { return m_is_rendering_to_main; }
__fi bool isSurfaceless() const { return m_is_surfaceless; }
__fi bool isRunningFullscreenUI() const { return m_run_fullscreen_ui; }
bool isOnEmuThread() const;
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
bool acquireHostDisplay(HostDisplay::RenderAPI api);
void connectDisplaySignals(DisplayWidget* widget);
void releaseHostDisplay();
void updateDisplay();
void startBackgroundControllerPollTimer();
void stopBackgroundControllerPollTimer();
void updatePerformanceMetrics(bool force);
public Q_SLOTS:
bool confirmMessage(const QString& title, const QString& message);
void loadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
void checkForSettingChanges(const Pcsx2Config& old_config);
void startFullscreenUI(bool fullscreen);
void stopFullscreenUI();
void startVM(std::shared_ptr<VMBootParameters> boot_params);
void resetVM();
void setVMPaused(bool paused);
void shutdownVM(bool save_state = true);
void loadState(const QString& filename);
void loadStateFromSlot(qint32 slot);
void saveState(const QString& filename);
void saveStateToSlot(qint32 slot);
void toggleFullscreen();
void setFullscreen(bool fullscreen);
void setSurfaceless(bool surfaceless);
void applySettings();
void reloadGameSettings();
void updateEmuFolders();
void toggleSoftwareRendering();
void switchRenderer(GSRendererType renderer);
void changeDisc(CDVD_SourceType source, const QString& path);
void reloadPatches();
void reloadInputSources();
void reloadInputBindings();
void requestDisplaySize(float scale);
void enumerateInputDevices();
void enumerateVibrationMotors();
void runOnCPUThread(const std::function<void()>& func);
void queueSnapshot(quint32 gsdump_frames);
Q_SIGNALS:
bool messageConfirmed(const QString& title, const QString& message);
DisplayWidget* onCreateDisplayRequested(bool fullscreen, bool render_to_main);
DisplayWidget* onUpdateDisplayRequested(bool fullscreen, bool render_to_main, bool surfaceless);
void onResizeDisplayRequested(qint32 width, qint32 height);
void onDestroyDisplayRequested();
/// Called when the VM is starting initialization, but has not been completed yet.
void onVMStarting();
/// Called when the VM is created.
void onVMStarted();
/// Called when the VM is paused.
void onVMPaused();
/// Called when the VM is resumed after being paused.
void onVMResumed();
/// Called when the VM is shut down or destroyed.
void onVMStopped();
/// Provided by the host; called when the running executable changes.
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
void onInputDeviceDisconnected(const QString& identifier);
void onVibrationMotorsEnumerated(const QList<InputBindingKey>& motors);
/// Called when a save state is loading, before the file is processed.
void onSaveStateLoading(const QString& path);
/// Called after a save state is successfully loaded. If the save state was invalid, was_successful will be false.
void onSaveStateLoaded(const QString& path, bool was_successful);
/// Called when a save state is being created/saved. The compression/write to disk is asynchronous, so this callback
/// just signifies that the save has started, not necessarily completed.
void onSaveStateSaved(const QString& path);
protected:
void run();
private:
/// Interval at which the controllers are polled when the system is not active.
static constexpr u32 BACKGROUND_CONTROLLER_POLLING_INTERVAL = 100;
/// Poll at half the vsync rate for FSUI to reduce the chance of getting a press+release in the same frame.
static constexpr u32 FULLSCREEN_UI_CONTROLLER_POLLING_INTERVAL = 8;
void destroyVM();
void executeVM();
bool shouldRenderToMain() const;
void createBackgroundControllerPollTimer();
void destroyBackgroundControllerPollTimer();
void connectSignals();
private Q_SLOTS:
void stopInThread();
void doBackgroundControllerPoll();
void onDisplayWindowResized(int width, int height, float scale);
void onApplicationStateChanged(Qt::ApplicationState state);
void redrawDisplayWindow();
private:
QThread* m_ui_thread;
QSemaphore m_started_semaphore;
QEventLoop* m_event_loop = nullptr;
QTimer* m_background_controller_polling_timer = nullptr;
std::atomic_bool m_shutdown_flag{false};
bool m_verbose_status = false;
bool m_run_fullscreen_ui = false;
bool m_is_rendering_to_main = false;
bool m_is_fullscreen = false;
bool m_is_surfaceless = false;
bool m_save_state_on_shutdown = false;
bool m_pause_on_focus_loss = false;
bool m_was_paused_by_focus_loss = false;
float m_last_speed = 0.0f;
float m_last_game_fps = 0.0f;
float m_last_video_fps = 0.0f;
int m_last_internal_width = 0;
int m_last_internal_height = 0;
GSRendererType m_last_renderer = GSRendererType::Null;
};
extern EmuThread* g_emu_thread;
namespace QtHost
{
/// Sets batch mode (exit after game shutdown).
@ -46,6 +212,9 @@ namespace QtHost
/// Sets NoGUI mode (implys batch mode, does not display main window, exits on shutdown).
bool InNoGUIMode();
/// Returns true if the calling thread is the UI thread.
bool IsOnUIThread();
/// Executes a function on the UI thread.
void RunOnUIThread(const std::function<void()>& func, bool block = false);
@ -58,17 +227,6 @@ namespace QtHost
/// Returns the base path for resources. This may be : prefixed, if we're using embedded resources.
QString GetResourcesBasePath();
/// Thread-safe settings access.
void SetBaseBoolSettingValue(const char* section, const char* key, bool value);
void SetBaseIntSettingValue(const char* section, const char* key, int value);
void SetBaseFloatSettingValue(const char* section, const char* key, float value);
void SetBaseStringSettingValue(const char* section, const char* key, const char* value);
void SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
bool AddBaseValueToStringList(const char* section, const char* key, const char* value);
bool RemoveBaseValueFromStringList(const char* section, const char* key, const char* value);
void RemoveBaseSettingValue(const char* section, const char* key);
void QueueSettingsSave();
/// VM state, safe to access on UI thread.
bool IsVMValid();
bool IsVMPaused();

View File

@ -35,7 +35,6 @@
#include "pcsx2/Config.h"
#include "pcsx2/HostSettings.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "Settings/SettingsDialog.h"
@ -613,7 +612,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
const bool new_value = Accessor::getBoolValue(widget);
QtHost::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value);
Host::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -653,7 +653,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), option_offset]() {
const int new_value = Accessor::getIntValue(widget);
QtHost::SetBaseIntSettingValue(section.c_str(), key.c_str(), new_value + option_offset);
Host::SetBaseIntSettingValue(section.c_str(), key.c_str(), new_value + option_offset);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -692,7 +693,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
const float new_value = Accessor::getFloatValue(widget);
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -732,7 +734,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), range]() {
const float new_value = (static_cast<float>(Accessor::getIntValue(widget)) / range);
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -773,10 +776,11 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
const QString new_value = Accessor::getStringValue(widget);
if (!new_value.isEmpty())
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData());
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData());
else
QtHost::RemoveBaseSettingValue(section.c_str(), key.c_str());
Host::RemoveBaseSettingValue(section.c_str(), key.c_str());
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -835,7 +839,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), to_string_function]() {
const DataType value = static_cast<DataType>(static_cast<UnderlyingType>(Accessor::getIntValue(widget)));
const char* string_value = to_string_function(value);
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), string_value);
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), string_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -896,7 +901,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), enum_names]() {
const UnderlyingType value = static_cast<UnderlyingType>(Accessor::getIntValue(widget));
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_names[value]);
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_names[value]);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -959,7 +965,8 @@ namespace SettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), enum_values]() {
const int value = Accessor::getIntValue(widget);
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_values[value]);
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_values[value]);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -996,13 +1003,14 @@ namespace SettingWidgetBinder
if (!new_value.empty())
{
std::string relative_path(Path::MakeRelative(new_value, EmuFolders::DataRoot));
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
}
else
{
QtHost::RemoveBaseSettingValue(section.c_str(), key.c_str());
Host::RemoveBaseSettingValue(section.c_str(), key.c_str());
}
Host::CommitBaseSettingChanges();
g_emu_thread->updateEmuFolders();
});

View File

@ -19,7 +19,7 @@
#include <algorithm>
#include "AdvancedSystemSettingsWidget.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"

View File

@ -19,7 +19,7 @@
#include <algorithm>
#include "AudioSettingsWidget.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"

View File

@ -130,7 +130,8 @@ void BIOSSettingsWidget::listRefreshed(const QVector<BIOSInfo>& items)
void BIOSSettingsWidget::listItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous)
{
QtHost::SetBaseStringSettingValue("Filenames", "BIOS", current->text(0).toUtf8().constData());
Host::SetBaseStringSettingValue("Filenames", "BIOS", current->text(0).toUtf8().constData());
Host::CommitBaseSettingChanges();
}
BIOSSettingsWidget::RefreshThread::RefreshThread(BIOSSettingsWidget* parent, const QString& directory)

View File

@ -24,7 +24,7 @@
#include "Settings/ControllerSettingsDialog.h"
#include "Settings/ControllerSettingWidgetBinder.h"
#include "Settings/SettingsDialog.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
@ -197,15 +197,21 @@ void ControllerBindingWidget::onClearBindingsClicked()
if (m_dialog->isEditingGlobalSettings())
{
auto lock = Host::GetSettingsLock();
PAD::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
{
auto lock = Host::GetSettingsLock();
PAD::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
}
Host::CommitBaseSettingChanges();
}
else
{
PAD::ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
m_dialog->getProfileSettingsInterface()->Save();
}
saveAndRefresh();
// force a refresh after clearing
g_emu_thread->applySettings();
onTypeChanged();
}
void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device)
@ -221,29 +227,31 @@ void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device)
bool result;
if (m_dialog->isEditingGlobalSettings())
{
auto lock = Host::GetSettingsLock();
result = PAD::MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
{
auto lock = Host::GetSettingsLock();
result = PAD::MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
}
if (result)
Host::CommitBaseSettingChanges();
}
else
{
result = PAD::MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
m_dialog->getProfileSettingsInterface()->Save();
g_emu_thread->reloadInputBindings();
if (result)
{
m_dialog->getProfileSettingsInterface()->Save();
g_emu_thread->reloadInputBindings();
}
}
// force a refresh after mapping
if (result)
saveAndRefresh();
{
g_emu_thread->applySettings();
onTypeChanged();
}
}
void ControllerBindingWidget::saveAndRefresh()
{
onTypeChanged();
QtHost::QueueSettingsSave();
g_emu_thread->applySettings();
}
//////////////////////////////////////////////////////////////////////////
ControllerMacroWidget::ControllerMacroWidget(ControllerBindingWidget* parent)

View File

@ -58,7 +58,6 @@ private:
void populateControllerTypes();
void updateHeaderToolButtons();
void doDeviceAutomaticBinding(const QString& device);
void saveAndRefresh();
Ui::ControllerBindingWidget m_ui;

View File

@ -29,9 +29,7 @@
#include "pcsx2/HostSettings.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
/// This nastyness is required because input profiles aren't overlaid settings like the rest of them, it's
@ -63,7 +61,8 @@ namespace ControllerSettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
const bool new_value = Accessor::getBoolValue(widget);
QtHost::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value);
Host::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -94,7 +93,8 @@ namespace ControllerSettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
const float new_value = Accessor::getFloatValue(widget);
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -127,7 +127,8 @@ namespace ControllerSettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), range]() {
const float new_value = (static_cast<float>(Accessor::getIntValue(widget)) / range);
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
@ -166,10 +167,11 @@ namespace ControllerSettingWidgetBinder
Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() {
const QString new_value = Accessor::getStringValue(widget);
if (!new_value.isEmpty())
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData());
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData());
else
QtHost::RemoveBaseSettingValue(section.c_str(), key.c_str());
Host::RemoveBaseSettingValue(section.c_str(), key.c_str());
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}

View File

@ -15,7 +15,6 @@
#include "PrecompiledHeader.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "Settings/ControllerSettingsDialog.h"
#include "Settings/ControllerGlobalSettingsWidget.h"
@ -23,7 +22,8 @@
#include "Settings/HotkeySettingsWidget.h"
#include "Settings/Python2BindingWidget.h"
#include "pcsx2/Frontend/INISettingsInterface.h"
#include "pcsx2/Frontend/CommonHost.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/Sio.h"
#include "pcsx2/VMManager.h"
@ -163,8 +163,8 @@ void ControllerSettingsDialog::onLoadProfileClicked()
{
auto lock = Host::GetSettingsLock();
PAD::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false);
QtHost::QueueSettingsSave();
}
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
@ -207,9 +207,9 @@ void ControllerSettingsDialog::onRestoreDefaultsClicked()
// actually restore it
{
auto lock = Host::GetSettingsLock();
PAD::SetDefaultConfig(*Host::Internal::GetBaseSettingsLayer());
QtHost::QueueSettingsSave();
CommonHost::SetDefaultSettings(*Host::Internal::GetBaseSettingsLayer(), false, false, true, true, false);
}
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
@ -295,7 +295,8 @@ void ControllerSettingsDialog::setBoolValue(const char* section, const char* key
}
else
{
QtHost::SetBaseBoolSettingValue(section, key, value);
Host::SetBaseBoolSettingValue(section, key, value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}
@ -310,7 +311,8 @@ void ControllerSettingsDialog::setIntValue(const char* section, const char* key,
}
else
{
QtHost::SetBaseIntSettingValue(section, key, value);
Host::SetBaseIntSettingValue(section, key, value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}
@ -325,7 +327,8 @@ void ControllerSettingsDialog::setStringValue(const char* section, const char* k
}
else
{
QtHost::SetBaseStringSettingValue(section, key, value);
Host::SetBaseStringSettingValue(section, key, value);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}
@ -340,7 +343,8 @@ void ControllerSettingsDialog::clearSettingValue(const char* section, const char
}
else
{
QtHost::RemoveBaseSettingValue(section, key);
Host::RemoveBaseSettingValue(section, key);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}

View File

@ -22,7 +22,7 @@
#include "common/StringUtil.h"
#include "DEV9DnsHostDialog.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"

View File

@ -24,13 +24,13 @@
#include "common/StringUtil.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/INISettingsInterface.h"
#include "DEV9SettingsWidget.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"
#include "Frontend/INISettingsInterface.h"
#include "HddCreateQt.h"

View File

@ -51,6 +51,7 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsDialog* dialog, QWidget
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.noInterlacingPatches, "EmuCore", "EnableNoInterlacingPatches", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.perGameSettings, "EmuCore", "EnablePerGameSettings", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.hostFilesystem, "EmuCore", "HostFs", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.warnAboutUnsafeSettings, "EmuCore", "WarnAboutUnsafeSettings", true);
dialog->registerWidgetHelp(m_ui.normalSpeed, tr("Normal Speed"), "100%",
tr("Sets the target emulation speed. It is not guaranteed that this speed will be reached, "
@ -96,6 +97,9 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsDialog* dialog, QWidget
tr("Sets the maximum number of frames that can be queued up to the GS, before the CPU thread will wait for one of them to complete before continuing. "
"Higher values can assist with smoothing out irregular frame times, but add additional input lag."));
dialog->registerWidgetHelp(m_ui.warnAboutUnsafeSettings, tr("Warn About Unsafe Settings"),
tr("Checked"), tr("Displays warnings when settings are enabled which may break games."));
updateOptimalFramePacing();
}

View File

@ -160,6 +160,13 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="warnAboutUnsafeSettings">
<property name="text">
<string>Warn About Unsafe Settings</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -19,7 +19,7 @@
#include <algorithm>
#include "GameFixSettingsWidget.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"

View File

@ -65,9 +65,10 @@ GameListSettingsWidget::~GameListSettingsWidget() = default;
bool GameListSettingsWidget::addExcludedPath(const std::string& path)
{
if (!QtHost::AddBaseValueToStringList("GameList", "ExcludedPaths", path.c_str()))
if (!Host::AddBaseValueToStringList("GameList", "ExcludedPaths", path.c_str()))
return false;
Host::CommitBaseSettingChanges();
m_ui.excludedPaths->addItem(QString::fromStdString(path));
g_main_window->refreshGameList(false);
return true;
@ -107,14 +108,15 @@ void GameListSettingsWidget::addPathToTable(const std::string& path, bool recurs
const std::string path(item->text().toStdString());
if (state == Qt::Checked)
{
QtHost::RemoveBaseValueFromStringList("GameList", "Paths", path.c_str());
QtHost::AddBaseValueToStringList("GameList", "RecursivePaths", path.c_str());
Host::RemoveBaseValueFromStringList("GameList", "Paths", path.c_str());
Host::AddBaseValueToStringList("GameList", "RecursivePaths", path.c_str());
}
else
{
QtHost::RemoveBaseValueFromStringList("GameList", "RecursivePaths", path.c_str());
QtHost::AddBaseValueToStringList("GameList", "Paths", path.c_str());
Host::RemoveBaseValueFromStringList("GameList", "RecursivePaths", path.c_str());
Host::AddBaseValueToStringList("GameList", "Paths", path.c_str());
}
Host::CommitBaseSettingChanges();
});
}
@ -138,8 +140,9 @@ void GameListSettingsWidget::refreshDirectoryList()
void GameListSettingsWidget::addSearchDirectory(const QString& path, bool recursive)
{
const std::string spath(path.toStdString());
QtHost::RemoveBaseValueFromStringList("GameList", recursive ? "Paths" : "RecursivePaths", spath.c_str());
QtHost::AddBaseValueToStringList("GameList", recursive ? "RecursivePaths" : "Paths", spath.c_str());
Host::RemoveBaseValueFromStringList("GameList", recursive ? "Paths" : "RecursivePaths", spath.c_str());
Host::AddBaseValueToStringList("GameList", recursive ? "RecursivePaths" : "Paths", spath.c_str());
Host::CommitBaseSettingChanges();
refreshDirectoryList();
g_main_window->refreshGameList(false);
}
@ -147,12 +150,13 @@ void GameListSettingsWidget::addSearchDirectory(const QString& path, bool recurs
void GameListSettingsWidget::removeSearchDirectory(const QString& path)
{
const std::string spath(path.toStdString());
if (!QtHost::RemoveBaseValueFromStringList("GameList", "Paths", spath.c_str()) &&
!QtHost::RemoveBaseValueFromStringList("GameList", "RecursivePaths", spath.c_str()))
if (!Host::RemoveBaseValueFromStringList("GameList", "Paths", spath.c_str()) &&
!Host::RemoveBaseValueFromStringList("GameList", "RecursivePaths", spath.c_str()))
{
return;
}
Host::CommitBaseSettingChanges();
refreshDirectoryList();
g_main_window->refreshGameList(false);
}
@ -228,7 +232,9 @@ void GameListSettingsWidget::onRemoveExcludedPathButtonClicked()
if (!item)
return;
QtHost::RemoveBaseValueFromStringList("GameList", "ExcludedPaths", item->text().toUtf8().constData());
if (Host::RemoveBaseValueFromStringList("GameList", "ExcludedPaths", item->text().toUtf8().constData()))
Host::CommitBaseSettingChanges();
delete item;
g_main_window->refreshGameList(false);

View File

@ -15,7 +15,6 @@
#include "PrecompiledHeader.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "Settings/InputBindingDialog.h"
@ -259,9 +258,10 @@ void InputBindingDialog::saveListToSettings()
else
{
if (!m_bindings.empty())
QtHost::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
Host::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
else
QtHost::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
Host::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
Host::CommitBaseSettingChanges();
g_emu_thread->reloadInputBindings();
}
}

View File

@ -28,7 +28,6 @@
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "Settings/ControllerSettingsDialog.h"
@ -236,7 +235,8 @@ void InputBindingWidget::setNewBinding()
}
else
{
QtHost::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), new_binding.c_str());
Host::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), new_binding.c_str());
Host::CommitBaseSettingChanges();
g_emu_thread->reloadInputBindings();
}
}
@ -256,7 +256,8 @@ void InputBindingWidget::clearBinding()
}
else
{
QtHost::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
Host::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
Host::CommitBaseSettingChanges();
g_emu_thread->reloadInputBindings();
}
reloadBinding();
@ -413,7 +414,8 @@ void InputVibrationBindingWidget::setKey(ControllerSettingsDialog* dialog, std::
void InputVibrationBindingWidget::clearBinding()
{
m_binding = {};
QtHost::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
Host::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
Host::CommitBaseSettingChanges();
g_emu_thread->reloadInputBindings();
setText(QString());
}
@ -448,7 +450,8 @@ void InputVibrationBindingWidget::onClicked()
const QString new_value(input_dialog.textValue());
m_binding = new_value.toStdString();
QtHost::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_binding.c_str());
Host::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_binding.c_str());
Host::CommitBaseSettingChanges();
setText(new_value);
}

View File

@ -26,7 +26,7 @@
#include "MemoryCardSettingsWidget.h"
#include "CreateMemoryCardDialog.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"

View File

@ -29,7 +29,7 @@
#include "Settings/ControllerSettingWidgetBinder.h"
#include "Settings/InputBindingWidget.h"
#include "Settings/SettingsDialog.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
@ -766,5 +766,5 @@ void Python2BindingWidget::saveMapping()
}
}
QtHost::QueueSettingsSave();
si->Save();
}

View File

@ -19,11 +19,10 @@
#include "common/Path.h"
#include "common/StringUtil.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/Frontend/INISettingsInterface.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/INISettingsInterface.h"
#include "EmuThread.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
@ -152,9 +151,6 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
connect(m_ui.settingsCategory, &QListWidget::currentRowChanged, this, &SettingsDialog::onCategoryCurrentRowChanged);
connect(m_ui.closeButton, &QPushButton::clicked, this, &SettingsDialog::accept);
connect(m_ui.restoreDefaultsButton, &QPushButton::clicked, this, &SettingsDialog::onRestoreDefaultsClicked);
// TODO: Remove this once they're implemented.
m_ui.restoreDefaultsButton->setVisible(false);
}
SettingsDialog::~SettingsDialog()
@ -170,6 +166,11 @@ void SettingsDialog::closeEvent(QCloseEvent*)
deleteLater();
}
QString SettingsDialog::getCategory() const
{
return m_ui.settingsCategory->item(m_ui.settingsCategory->currentRow())->text();
}
void SettingsDialog::setCategory(const char* category)
{
// the titles in the category list will be translated.
@ -194,14 +195,20 @@ void SettingsDialog::onCategoryCurrentRowChanged(int row)
void SettingsDialog::onRestoreDefaultsClicked()
{
if (QMessageBox::question(this, tr("Confirm Restore Defaults"),
tr("Are you sure you want to restore the default settings? Any preferences will be lost."), QMessageBox::Yes,
QMessageBox::No) != QMessageBox::Yes)
{
return;
}
QMessageBox msgbox(this);
msgbox.setIcon(QMessageBox::Question);
msgbox.setWindowTitle(tr("Confirm Restore Defaults"));
msgbox.setText(tr("Are you sure you want to restore the default settings? Any preferences will be lost."));
// TODO
QCheckBox* ui_cb = new QCheckBox(tr("Reset UI Settings"), &msgbox);
msgbox.setCheckBox(ui_cb);
msgbox.addButton(QMessageBox::Yes);
msgbox.addButton(QMessageBox::No);
msgbox.setDefaultButton(QMessageBox::Yes);
if (msgbox.exec() != QMessageBox::Yes)
return;
g_main_window->resetSettings(ui_cb->isChecked());
}
void SettingsDialog::addWidget(QWidget* widget, QString title, QString icon, QString help_text)
@ -382,7 +389,8 @@ void SettingsDialog::setBoolSettingValue(const char* section, const char* key, s
}
else
{
value.has_value() ? QtHost::SetBaseBoolSettingValue(section, key, value.value()) : QtHost::RemoveBaseSettingValue(section, key);
value.has_value() ? Host::SetBaseBoolSettingValue(section, key, value.value()) : Host::RemoveBaseSettingValue(section, key);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}
@ -397,7 +405,8 @@ void SettingsDialog::setIntSettingValue(const char* section, const char* key, st
}
else
{
value.has_value() ? QtHost::SetBaseIntSettingValue(section, key, value.value()) : QtHost::RemoveBaseSettingValue(section, key);
value.has_value() ? Host::SetBaseIntSettingValue(section, key, value.value()) : Host::RemoveBaseSettingValue(section, key);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}
@ -412,7 +421,8 @@ void SettingsDialog::setFloatSettingValue(const char* section, const char* key,
}
else
{
value.has_value() ? QtHost::SetBaseFloatSettingValue(section, key, value.value()) : QtHost::RemoveBaseSettingValue(section, key);
value.has_value() ? Host::SetBaseFloatSettingValue(section, key, value.value()) : Host::RemoveBaseSettingValue(section, key);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}
@ -427,7 +437,8 @@ void SettingsDialog::setStringSettingValue(const char* section, const char* key,
}
else
{
value.has_value() ? QtHost::SetBaseStringSettingValue(section, key, value.value()) : QtHost::RemoveBaseSettingValue(section, key);
value.has_value() ? Host::SetBaseStringSettingValue(section, key, value.value()) : Host::RemoveBaseSettingValue(section, key);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
}

View File

@ -74,6 +74,7 @@ public:
void registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text);
bool eventFilter(QObject* object, QEvent* event) override;
QString getCategory() const;
void setCategory(const char* category);
// Helper functions for reading effective setting values (from game -> global settings).

View File

@ -20,7 +20,7 @@
#include "pcsx2/HostSettings.h"
#include "EmuThread.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"

View File

@ -176,7 +176,6 @@
<ClCompile Include="PrecompiledHeader.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="EmuThread.cpp" />
<ClCompile Include="QtKeyCodes.cpp" />
<ClCompile Include="QtUtils.cpp" />
</ItemGroup>
@ -214,11 +213,10 @@
<QtMoc Include="Settings\ControllerBindingWidgets.h" />
<QtMoc Include="Settings\ControllerGlobalSettingsWidget.h" />
<ClInclude Include="SettingWidgetBinder.h" />
<ClInclude Include="QtHost.h" />
<QtMoc Include="QtHost.h" />
<ClInclude Include="PrecompiledHeader.h" />
<QtMoc Include="AboutDialog.h" />
<QtMoc Include="AutoUpdaterDialog.h" />
<QtMoc Include="EmuThread.h" />
<QtMoc Include="MainWindow.h" />
<QtMoc Include="DisplayWidget.h" />
</ItemGroup>
@ -259,8 +257,8 @@
<ClCompile Include="$(IntDir)moc_AboutDialog.cpp" />
<ClCompile Include="$(IntDir)moc_AutoUpdaterDialog.cpp" />
<ClCompile Include="$(IntDir)moc_DisplayWidget.cpp" />
<ClCompile Include="$(IntDir)moc_EmuThread.cpp" />
<ClCompile Include="$(IntDir)moc_MainWindow.cpp" />
<ClCompile Include="$(IntDir)moc_QtHost.cpp" />
<ClCompile Include="$(IntDir)Tools\InputRecording\moc_NewInputRecordingDlg.cpp" />
<ClCompile Include="$(IntDir)qrc_resources.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@ -42,9 +42,8 @@
<ClCompile Include="$(IntDir)moc_DisplayWidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="EmuThread.cpp" />
<ClCompile Include="QtUtils.cpp" />
<ClCompile Include="$(IntDir)moc_EmuThread.cpp">
<ClCompile Include="$(IntDir)moc_QtHost.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="QtKeyCodes.cpp" />
@ -255,7 +254,6 @@
<ItemGroup>
<QtMoc Include="MainWindow.h" />
<QtMoc Include="DisplayWidget.h" />
<QtMoc Include="EmuThread.h" />
<QtMoc Include="Settings\BIOSSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>

View File

@ -145,7 +145,7 @@ struct CDVD_API
};
// ----------------------------------------------------------------------------
// Multiple interface system for CDVD.
// Multiple interface system for CDVD.
// ----------------------------------------------------------------------------
extern CDVD_API* CDVD; // currently active CDVD access mode api (either Iso, NoDisc, or Disc)

View File

@ -332,11 +332,11 @@ bool GzippedFileReader::OkIndex()
// No valid index file. Generate an index
Console.Warning("This may take a while (but only once). Scanning compressed file to generate a quick access index...");
const s64 prevoffset = FileSystem::FTell64(m_src);
Access* index;
FILE* infile = FileSystem::OpenCFile(m_filename.c_str(), "rb");
int len = build_index(infile, GZFILE_SPAN_DEFAULT, &index);
int len = build_index(m_src, GZFILE_SPAN_DEFAULT, &index);
printf("\n"); // build_index prints progress without \n's
fclose(infile);
FileSystem::FSeek64(m_src, prevoffset, SEEK_SET);
if (len >= 0)
{

View File

@ -212,7 +212,7 @@ bool IOCtlSrc::ReadDVDInfo()
// least 18 bytes of the layer descriptor or else the ioctl will fail. The
// media specific information seems to be empty, so there's no point reading
// any more than that.
// UPDATE 15 Jan 2021
// Okay so some drives seem to have descriptors BIGGER than 22 bytes!
// This causes the read to fail with INVALID_PARAMETER.

View File

@ -1156,29 +1156,32 @@ endif()
if(PCSX2_CORE)
list(APPEND pcsx2FrontendSources
Frontend/CommonHost.cpp
Frontend/CommonHotkeys.cpp
Frontend/FullscreenUI.cpp
Frontend/GameList.cpp
Frontend/HostSettings.cpp
Frontend/ImGuiFullscreen.cpp
Frontend/INISettingsInterface.cpp
Frontend/InputManager.cpp
Frontend/InputSource.cpp
Frontend/LayeredSettingsInterface.cpp
Frontend/LogSink.cpp
GSDumpReplayer.cpp
HostSettings.cpp
INISettingsInterface.cpp
VMManager.cpp
)
list(APPEND pcsx2FrontendHeaders
Frontend/CommonHost.h
Frontend/FullscreenUI.h
Frontend/GameList.h
Frontend/ImGuiFullscreen.h
Frontend/INISettingsInterface.h
Frontend/InputManager.h
Frontend/InputSource.h
Frontend/LayeredSettingsInterface.h
Frontend/LogSink.h
GSDumpReplayer.h
HostSettings.h
INISettingsInterface.h
VMManager.h)
endif()
@ -1500,7 +1503,6 @@ set(pcsx2WindowsSources
CDVD/Windows/IOCtlSrc.cpp
windows/FlatFileReaderWindows.cpp
windows/Optimus.cpp
windows/VCprojects/IopSif.cpp
windows/WinConsolePipe.cpp
windows/WinKeyCodes.cpp
windows/WinPowerProfile.cpp

View File

@ -341,7 +341,7 @@ void CACHE()
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
// CACHE_LOG("cpuRegs.GPR.r[_Rs_].UL[0] = %x, IMM = %x RT = %x", cpuRegs.GPR.r[_Rs_].UL[0], _Imm_, _Rt_);
switch (_Rt_)
switch (_Rt_)
{
case 0x1a: //DHIN (Data Cache Hit Invalidate)
doCacheHitOp(addr, "DHIN", [](CacheLine line)

View File

@ -212,6 +212,7 @@ ImplementEnumOperators(SpeedhackId);
//------------ DEFAULT sseMXCSR VALUES ---------------
#define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
#define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop"
#define SYSTEM_sseMXCSR 0x1f80
// --------------------------------------------------------------------------------------
// TraceFiltersEE
@ -427,6 +428,9 @@ struct Pcsx2Config
static const char* GetRendererName(GSRendererType type);
static constexpr float DEFAULT_FRAME_RATE_NTSC = 59.94f;
static constexpr float DEFAULT_FRAME_RATE_PAL = 50.00f;
union
{
u64 bitset;
@ -503,24 +507,24 @@ struct Pcsx2Config
VsyncMode VsyncEnable{VsyncMode::Off};
double LimitScalar{1.0};
double FramerateNTSC{59.94};
double FrameratePAL{50.00};
float LimitScalar{1.0f};
float FramerateNTSC{DEFAULT_FRAME_RATE_NTSC};
float FrameratePAL{DEFAULT_FRAME_RATE_PAL};
AspectRatioType AspectRatio{AspectRatioType::RAuto4_3_3_2};
FMVAspectRatioSwitchType FMVAspectRatioSwitch{FMVAspectRatioSwitchType::Off};
GSInterlaceMode InterlaceMode{GSInterlaceMode::Automatic};
double Zoom{100.0};
double StretchY{100.0};
float Zoom{100.0f};
float StretchY{100.0f};
#ifndef PCSX2_CORE
double OffsetX{0.0};
double OffsetY{0.0};
float OffsetX{0.0f};
float OffsetY{0.0f};
#else
int Crop[4]{};
#endif
double OsdScale{100.0};
float OsdScale{100.0};
GSRendererType Renderer{GSRendererType::Auto};
uint UpscaleMultiplier{1};
@ -623,14 +627,14 @@ struct Pcsx2Config
s32 SpeakerConfiguration{0};
s32 DplDecodingLevel{0};
double VolumeAdjustC{ 0.0f };
double VolumeAdjustFL{ 0.0f };
double VolumeAdjustFR{ 0.0f };
double VolumeAdjustBL{ 0.0f };
double VolumeAdjustBR{ 0.0f };
double VolumeAdjustSL{ 0.0f };
double VolumeAdjustSR{ 0.0f };
double VolumeAdjustLFE{ 0.0f };
float VolumeAdjustC{ 0.0f };
float VolumeAdjustFL{ 0.0f };
float VolumeAdjustFR{ 0.0f };
float VolumeAdjustBL{ 0.0f };
float VolumeAdjustBR{ 0.0f };
float VolumeAdjustSL{ 0.0f };
float VolumeAdjustSR{ 0.0f };
float VolumeAdjustLFE{ 0.0f };
std::string OutputModule;
@ -891,9 +895,9 @@ struct Pcsx2Config
// ------------------------------------------------------------------------
struct FramerateOptions
{
double NominalScalar{1.0};
double TurboScalar{2.0};
double SlomoScalar{0.5};
float NominalScalar{1.0f};
float TurboScalar{2.0f};
float SlomoScalar{0.5f};
void LoadSave(SettingsWrapper& wrap);
void SanityCheck();
@ -967,7 +971,9 @@ struct Pcsx2Config
MultitapPort1_Enabled : 1,
ConsoleToStdio : 1,
HostFs : 1;
HostFs : 1,
WarnAboutUnsafeSettings : 1;
// uses automatic ntfs compression when creating new memory cards (Win32 only)
#ifdef _WIN32
@ -1049,10 +1055,9 @@ namespace EmuFolders
extern std::string InputProfiles;
// Assumes that AppRoot and DataRoot have been initialized.
void SetDefaults();
bool EnsureFoldersExist();
void SetDefaults(SettingsInterface& si);
void LoadConfig(SettingsInterface& si);
void Save(SettingsInterface& si);
bool EnsureFoldersExist();
} // namespace EmuFolders
/////////////////////////////////////////////////////////////////////////////////////////

View File

@ -353,7 +353,7 @@ double GetVerticalFrequency()
static double AdjustToHostRefreshRate(double vertical_frequency, double frame_limit)
{
if (!EmuConfig.GS.SyncToHostRefreshRate || EmuConfig.GS.LimitScalar != 1.0)
if (!EmuConfig.GS.SyncToHostRefreshRate || EmuConfig.GS.LimitScalar != 1.0f)
{
SPU2SetDeviceSampleRateMultiplier(1.0);
s_use_vsync_for_timing = false;
@ -361,7 +361,7 @@ static double AdjustToHostRefreshRate(double vertical_frequency, double frame_li
}
float host_refresh_rate;
if (!Host::GetHostDisplay()->GetHostRefreshRate(&host_refresh_rate))
if (!g_host_display->GetHostRefreshRate(&host_refresh_rate))
{
Console.Warning("Cannot sync to host refresh since the query failed.");
SPU2SetDeviceSampleRateMultiplier(1.0);
@ -390,7 +390,7 @@ u32 UpdateVSyncRate()
// The PS2's vsync timer is an *independent* crystal that is fixed to either 59.94 (NTSC)
// or 50.0 (PAL) Hz. It has *nothing* to do with real TV timings or the real vsync of
// the GS's output circuit. It is the same regardless if the GS is outputting interlace
// or progressive scan content.
// or progressive scan content.
const double vertical_frequency = GetVerticalFrequency();
@ -413,7 +413,7 @@ u32 UpdateVSyncRate()
break;
case GS_VideoMode::PAL:
case GS_VideoMode::DVD_PAL:
custom = (EmuConfig.GS.FrameratePAL != 50.0);
custom = (EmuConfig.GS.FrameratePAL != Pcsx2Config::GSOptions::DEFAULT_FRAME_RATE_PAL);
if (gsIsInterlaced)
total_scanlines = SCANLINES_TOTAL_PAL_I;
else
@ -421,7 +421,7 @@ u32 UpdateVSyncRate()
break;
case GS_VideoMode::NTSC:
case GS_VideoMode::DVD_NTSC:
custom = (EmuConfig.GS.FramerateNTSC != 59.94);
custom = (EmuConfig.GS.FramerateNTSC != Pcsx2Config::GSOptions::DEFAULT_FRAME_RATE_NTSC);
if (gsIsInterlaced)
total_scanlines = SCANLINES_TOTAL_NTSC_I;
else
@ -457,7 +457,7 @@ u32 UpdateVSyncRate()
if (video_mode_initialized)
Console.WriteLn(Color_Green, "(UpdateVSyncRate) Mode Changed to %s.", ReportVideoMode());
if (custom && video_mode_initialized)
Console.Indent().WriteLn(Color_StrongGreen, "... with user configured refresh rate: %.02f Hz", vertical_frequency);
@ -543,7 +543,7 @@ static __fi void DoFMVSwitch()
RendererSwitched = false;
}
// Convenience function to update UI thread and set patches.
// Convenience function to update UI thread and set patches.
static __fi void frameLimitUpdateCore()
{
DoFMVSwitch();
@ -564,7 +564,7 @@ static __fi void frameLimitUpdateCore()
static __fi void frameLimit()
{
// Framelimiter off in settings? Framelimiter go brrr.
if (EmuConfig.GS.LimitScalar == 0.0 || s_use_vsync_for_timing)
if (EmuConfig.GS.LimitScalar == 0.0f || s_use_vsync_for_timing)
{
frameLimitUpdateCore();
return;
@ -585,15 +585,15 @@ static __fi void frameLimit()
// Conversion of delta from CPU ticks (microseconds) to milliseconds
s32 msec = (int) ((sDeltaTime * -1000) / (s64) GetTickFrequency());
// If any integer value of milliseconds exists, sleep it off.
// Prior comments suggested that 1-2 ms sleeps were inaccurate on some OSes;
// further testing suggests instead that this was utter bullshit.
// further testing suggests instead that this was utter bullshit.
if (msec > 1)
{
Threading::Sleep(msec - 1);
}
// Conversion to milliseconds loses some precision; after sleeping off whole milliseconds,
// spin the thread without sleeping until we finally reach our expected end time.
while (GetCPUTicks() < uExpectedEnd)
@ -628,7 +628,7 @@ static __fi void VSyncStart(u32 sCycle)
hwIntcIrq(INTC_VBLANK_S);
psxVBlankStart();
if (gates) rcntStartGate(true, sCycle); // Counters Start Gate code
// INTC - VB Blank Start Hack --
@ -746,7 +746,7 @@ __fi void rcntUpdate_vSync()
if (vsyncCounter.Mode == MODE_VSYNC)
{
VSyncEnd(vsyncCounter.sCycle);
vsyncCounter.sCycle += vSyncInfo.Blank;
vsyncCounter.CycleT = vSyncInfo.Render;
vsyncCounter.Mode = MODE_VRENDER;
@ -962,7 +962,7 @@ static __fi void rcntEndGate(bool isVblank , u32 sCycle)
// calls to rcntUpdate).
counters[i].mode.IsCounting = 1;
counters[i].sCycleT = cpuRegs.cycle;
EECNT_LOG("EE Counter[%d] %s EndGate Type0, count = %x", i,
isVblank ? "vblank" : "hblank", counters[i].count );
break;
@ -1131,7 +1131,7 @@ __fi u16 rcntRead32( u32 mem )
case(RCNT3_MODE): return (u16)counters[3].modeval;
case(RCNT3_TARGET): return (u16)counters[3].target;
}
return psHu16(mem);
}

View File

@ -257,7 +257,7 @@ EXTERN int ThreadRun;
#define SMAP_R_RXFIFO_FRAME_CNT (SMAP_REGBASE + 0xf3C)
#define SMAP_R_RXFIFO_FRAME_DEC (SMAP_REGBASE + 0xf40)
#define SMAP_R_RXFIFO_DATA (SMAP_REGBASE + 0x1100)
#define SMAP_R_FIFO_ADDR (SMAP_REGBASE + 0x1200)
#define SMAP_FIFO_CMD_READ (1<<1)
#define SMAP_FIFO_DATA_SWAP (1<<0)

View File

@ -66,7 +66,7 @@ namespace PacketReader::ARP
, senderProtocolAddress{std::make_unique<u8[]>(original.protocolAddressLength)}
, targetHardwareAddress{std::make_unique<u8[]>(original.hardwareAddressLength)}
, targetProtocolAddress{std::make_unique<u8[]>(original.protocolAddressLength)}
{
{
memcpy(senderHardwareAddress.get(), original.senderHardwareAddress.get(), hardwareAddressLength);
memcpy(senderProtocolAddress.get(), original.senderProtocolAddress.get(), protocolAddressLength);
memcpy(targetHardwareAddress.get(), original.targetHardwareAddress.get(), hardwareAddressLength);

View File

@ -19,7 +19,7 @@ namespace PacketReader::IP
{
struct IP_Address
{
union
union
{
u8 bytes[4];
u32 integer;

View File

@ -82,7 +82,7 @@ namespace PacketReader::IP
* Not Defined (xxx000)
* 6 = Internetwork Control Class 6
* 7 = Network Control Class 7
*
*
* Lower 3 Bits
* In TOS, defined as follows
* bit 0: Reliability

View File

@ -75,7 +75,7 @@ using namespace std::chrono_literals;
FreeBSD
Raw sockets restricted
No unprivilaged ICMP sockets
Timeouts reported as a normal packet??
Timeouts reported as a normal packet??
Ping cli
Present for all platforms, but command args differ

View File

@ -371,15 +371,15 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter,
* but it doesn't tell you whether it's a bridge or an LBFO team or something more exotic.
* The way to distinguish exactly which flavor of ms_implat you have is to look at which LWF driver is bound to the *virtual miniport* above the IM driver.
* This is two steps then.
*
*
* 1. Given a physical NIC, you first want to determine which virtual NIC is layered over it.
* 2. Given a virtual NIC, you want to determine whether ms_bridge is bound to it.
*
*
* To get the first part, look through the interface stack table (GetIfStackTable). Search the stack table for any entry where the lower is the IfIndex of the physical NIC.
* For any such entry (there will probably be a few), check if that entry's upper IfIndex is the IfIndex for a virtual miniport with component ID "COMPOSITEBUS\MS_IMPLAT_MP".
* If you find such a thing, that means the physical NIC is a member of a bridge/LBFO/something-else-fancy.
* If you don't find it, then you know the NIC isn't part of the bridge that comes with Windows 8 / Windows 10.
*
*
* To get the second part, just use the same INetCfg code above on the *virtual* NIC's component. If the ms_bridge component is bound to the virtual NIC,
* then that virtual NIC is doing bridging. Otherwise, it's doing something else (like LBFO).
*/

View File

@ -194,8 +194,8 @@ void tx_process()
if (dev9.txfifo_rd_ptr==16384)
dev9.txfifo_rd_ptr=0;
}
if (dev9.txfifo_rd_ptr&(~16383))
{
@ -612,7 +612,7 @@ void smap_write16(u32 addr, u16 value)
value = (value >> 8) | (value << 8);
dev9Ru16(addr) = value;
/*
switch (addr & 0x7)
switch (addr & 0x7)
{
case 0: // ctrl_stat
DevCon.WriteLn("DEV9: TX_CTRL_STAT[%d]: write %x", (addr - SMAP_BD_TX_BASE) / 8, value);
@ -642,7 +642,7 @@ void smap_write16(u32 addr, u16 value)
value = (value >> 8) | (value << 8);
dev9Ru16(addr) = value;
/*
switch (addr & 0x7)
switch (addr & 0x7)
{
case 0: // ctrl_stat
DevCon.WriteLn("DEV9: RX_CTRL_STAT[%d]: write %x", rx_index, value);
@ -772,7 +772,7 @@ void smap_write16(u32 addr, u16 value)
emu_printf("SMAP: SMAP_R_EMAC3_TxMODE0_H 16bit write %x\n", value);
dev9Ru16(addr) = value;
return;
case SMAP_R_EMAC3_TxMODE1_H:
emu_printf("SMAP: SMAP_R_EMAC3_TxMODE1_H 16bit write %x\n", value);
dev9Ru16(addr) = value;

View File

@ -49,7 +49,7 @@ enum {
THS_WAIT_SUSPEND = 0x0C,
THS_DORMANT = 0x10,
};
enum {
WAIT_NONE = 0,
WAIT_WAKEUP_REQ = 1,

View File

@ -91,7 +91,7 @@ public:
{
return SysTraceLog::IsActive() && EmuConfig.Trace.EE.m_EnableAll;
}
std::string GetCategory() const override { return "EE"; }
};
@ -266,7 +266,7 @@ struct SysTraceLogPack
SysTraceLog_EE_Disasm COP1;
SysTraceLog_EE_Disasm COP2;
SysTraceLog_EE_Disasm Cache;
SysTraceLog_EE_Registers KnownHw;
SysTraceLog_EE_Registers UnknownHw;
SysTraceLog_EE_Registers DMAhw;
@ -281,7 +281,7 @@ struct SysTraceLogPack
EE_PACK();
} EE;
struct IOP_PACK
{
SysTraceLog_IOP Bios;

View File

@ -221,11 +221,11 @@ void DisassemblyManager::analyze(u32 address, u32 size = 1024)
std::vector<BranchLine> DisassemblyManager::getBranchLines(u32 start, u32 size)
{
std::vector<BranchLine> result;
auto it = findDisassemblyEntry(entries,start,false);
if (it != entries.end())
{
do
do
{
it->second->getBranchLines(start,size,result);
it++;
@ -258,7 +258,7 @@ void DisassemblyManager::getLine(u32 address, bool insertSymbols, DisassemblyLin
DisassemblyEntry* entry = it->second;
if (entry->disassemble(address,dest,insertSymbols))
return;
if (address % 4)
dest.totalSize = ((address+3) & ~3)-address;
else
@ -277,7 +277,7 @@ u32 DisassemblyManager::getStartAddress(u32 address)
if (it == entries.end())
return address;
}
DisassemblyEntry* entry = it->second;
int line = entry->getLineNum(address,true);
return entry->getLineAddress(line);
@ -288,7 +288,7 @@ u32 DisassemblyManager::getNthPreviousAddress(u32 address, int n)
while (cpu->isValidAddress(address))
{
auto it = findDisassemblyEntry(entries,address,false);
while (it != entries.end())
{
DisassemblyEntry* entry = it->second;
@ -302,10 +302,10 @@ u32 DisassemblyManager::getNthPreviousAddress(u32 address, int n)
n -= oldLineNum+1;
it = findDisassemblyEntry(entries,address,false);
}
analyze(address-127,128);
}
return address-n*4;
}
@ -314,7 +314,7 @@ u32 DisassemblyManager::getNthNextAddress(u32 address, int n)
while (cpu->isValidAddress(address))
{
auto it = findDisassemblyEntry(entries,address,false);
while (it != entries.end())
{
DisassemblyEntry* entry = it->second;
@ -532,7 +532,7 @@ void DisassemblyFunction::load()
break;
}
}
u32 funcPos = address;
u32 funcEnd = address+size;
@ -563,7 +563,7 @@ void DisassemblyFunction::load()
DisassemblyComment* comment = new DisassemblyComment(cpu,funcPos,nextPos-funcPos,".align","4");
entries[funcPos] = comment;
lineAddresses.push_back(funcPos);
funcPos = nextPos;
opcodeSequenceStart = funcPos;
continue;
@ -572,14 +572,14 @@ void DisassemblyFunction::load()
MIPSAnalyst::MipsOpcodeInfo opInfo = MIPSAnalyst::GetOpcodeInfo(cpu,funcPos);
u32 opAddress = funcPos;
funcPos += 4;
// skip branches and their delay slots
if (opInfo.isBranch)
{
if (funcPos < funcEnd) funcPos += 4; // only include delay slots within the function bounds
continue;
}
// lui
if (MIPS_GET_OP(opInfo.encodedOpcode) == 0x0F && funcPos < funcEnd && funcPos != nextData)
{
@ -692,7 +692,7 @@ void DisassemblyFunction::clear()
bool DisassemblyOpcode::disassemble(u32 address, DisassemblyLineInfo& dest, bool insertSymbols)
{
char opcode[64],arguments[256];
std::string dis = cpu->disasm(address,insertSymbols);
parseDisasm(cpu->GetSymbolMap(),dis.c_str(),opcode,arguments,insertSymbols);
dest.type = DISTYPE_OPCODE;
@ -770,7 +770,7 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool
{
case MACRO_LI:
dest.name = name;
addressSymbol = cpu->GetSymbolMap().GetLabelString(immediate);
if (!addressSymbol.empty() && insertSymbols)
{
@ -780,7 +780,7 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool
}
dest.params = buffer;
dest.info.hasRelevantAddress = true;
dest.info.releventAddress = immediate;
break;
@ -883,7 +883,7 @@ void DisassemblyData::createLines()
u32 pos = address;
u32 end = address+size;
u32 maxChars = DisassemblyManager::getMaxParamChars();
std::string currentLine;
u32 currentLineStart = pos;
@ -904,7 +904,7 @@ void DisassemblyData::createLines()
DataEntry entry = {currentLine,pos-1-currentLineStart,lineCount++};
lines[currentLineStart] = entry;
lineAddresses.push_back(currentLineStart);
currentLine = "";
currentLineStart = pos-1;
inString = false;
@ -925,11 +925,11 @@ void DisassemblyData::createLines()
{
if (inString)
currentLine += "\"";
DataEntry entry = {currentLine,pos-1-currentLineStart,lineCount++};
lines[currentLineStart] = entry;
lineAddresses.push_back(currentLineStart);
currentLine = "";
currentLineStart = pos-1;
inString = false;

View File

@ -305,7 +305,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
while (true)
{
if (opcodeStack.empty())
{
{
sprintf(expressionError,"Closing parenthesis without opening one");
return false;
}
@ -319,7 +319,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
while (true)
{
if (opcodeStack.empty())
{
{
sprintf(expressionError,"Closing bracket without opening one");
return false;
}

View File

@ -57,19 +57,19 @@ namespace MIPSAnalyst
{
u32 op = r5900Debug.read32(addr);
const R5900::OPCODE& opcode = R5900::GetInstruction(op);
int branchType = (opcode.flags & BRANCHTYPE_MASK);
if ((opcode.flags & IS_BRANCH) && (branchType == BRANCHTYPE_BRANCH || branchType == BRANCHTYPE_BC1))
return addr + 4 + ((signed short)(op&0xFFFF)<<2);
else
return INVALIDTARGET;
}
u32 GetBranchTargetNoRA(u32 addr)
{
u32 op = r5900Debug.read32(addr);
const R5900::OPCODE& opcode = R5900::GetInstruction(op);
int branchType = (opcode.flags & BRANCHTYPE_MASK);
if ((opcode.flags & IS_BRANCH) && (branchType == BRANCHTYPE_BRANCH || branchType == BRANCHTYPE_BC1))
{
@ -86,7 +86,7 @@ namespace MIPSAnalyst
{
u32 op = r5900Debug.read32(addr);
const R5900::OPCODE& opcode = R5900::GetInstruction(op);
if ((opcode.flags & IS_BRANCH) && (opcode.flags & BRANCHTYPE_MASK) == BRANCHTYPE_BRANCH)
{
bool sure = false;
@ -290,7 +290,7 @@ namespace MIPSAnalyst
}
}
}
if (end) {
// most functions are aligned to 8 or 16 bytes
// add the padding to this one
@ -353,7 +353,7 @@ namespace MIPSAnalyst
case BRANCHTYPE_BRANCH:
info.isConditional = true;
info.branchTarget = info.opcodeAddress + 4 + ((s16)(op&0xFFFF)<<2);
rs = info.cpu->getRegister(0,MIPS_GET_RS(op))._u64[0];
rt = info.cpu->getRegister(0,MIPS_GET_RT(op))._u64[0];
switch (opcode.flags & CONDTYPE_MASK)
@ -381,7 +381,7 @@ namespace MIPSAnalyst
info.conditionMet = (((s64)rs) >= 0);
break;
}
break;
case BRANCHTYPE_REGISTER:
info.isConditional = false;
@ -430,7 +430,7 @@ namespace MIPSAnalyst
info.lrType = LOADSTORE_LEFT;
else if (opcode.flags & IS_RIGHT)
info.lrType = LOADSTORE_RIGHT;
u32 rs = info.cpu->getRegister(0, (int)MIPS_GET_RS(op));
s16 imm16 = op & 0xFFFF;
info.dataAddress = rs + imm16;
@ -457,7 +457,7 @@ namespace MIPSAnalyst
info.dataSize = 16;
break;
}
info.hasRelevantAddress = true;
info.releventAddress = info.dataAddress;
}

View File

@ -49,7 +49,7 @@ namespace MIPSAnalyst
DebugInterface* cpu;
u32 opcodeAddress;
u32 encodedOpcode;
// shared between branches and conditional moves
bool isConditional;
bool conditionMet;
@ -72,6 +72,6 @@ namespace MIPSAnalyst
bool hasRelevantAddress;
u32 releventAddress;
} MipsOpcodeInfo;
MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address);
};

View File

@ -27,7 +27,7 @@ public:
{
//
}
static void queueError(ErrorType type, const wchar_t* text, ...)
{
//
@ -177,7 +177,7 @@ void SplitLine(const char* Line, char* Name, char* Arguments)
*Name++ = *Line++;
}
*Name = 0;
while (*Line == ' ' || *Line == '\t') Line++;
while (*Line != 0)
@ -587,7 +587,7 @@ bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, const char*
while (*Line == ' ' || *Line == '\t') Line++;
if (*Line != 0) return false; // there's something else, bad
// opcode is ok - now set all flags
Opcode = SourceOpcode;
immediate.value = immediate.originalValue;
@ -601,13 +601,13 @@ void CMipsInstruction::setOmittedRegisters()
// copy over omitted registers
if (Opcode.flags & MO_RSD)
registers.grd = registers.grs;
if (Opcode.flags & MO_RST)
registers.grt = registers.grs;
if (Opcode.flags & MO_RDT)
registers.grt = registers.grd;
if (Opcode.flags & MO_FRSD)
registers.frd = registers.frs;
}
@ -641,7 +641,7 @@ bool CMipsInstruction::Validate()
if (immediateType != MIPS_NOIMMEDIATE)
{
immediate.originalValue = immediate.value;
if (Opcode.flags & MO_IMMALIGNED) // immediate must be aligned
{
if (immediate.value % 4)
@ -657,7 +657,7 @@ bool CMipsInstruction::Validate()
} else if (Opcode.flags & MO_IPCR) // relative 16 bit value
{
int num = (immediate.value-RamPos-4);
if (num > 0x20000 || num < (-0x20000))
{
Logger::queueError(Logger::Error,L"Branch target %08X out of range",immediate.value);
@ -665,7 +665,7 @@ bool CMipsInstruction::Validate()
}
immediate.value = num >> 2;
}
int immediateBits = getImmediateBits(immediateType);
unsigned int mask = (0xFFFFFFFF << (32-immediateBits)) >> (32-immediateBits);
int digits = (immediateBits+3) / 4;
@ -678,7 +678,7 @@ bool CMipsInstruction::Validate()
immediate.value &= mask;
}
return true;
}
@ -689,11 +689,11 @@ void CMipsInstruction::encodeNormal()
if (registers.grs.num != -1) encoding |= MIPS_RS(registers.grs.num); // source reg
if (registers.grt.num != -1) encoding |= MIPS_RT(registers.grt.num); // target reg
if (registers.grd.num != -1) encoding |= MIPS_RD(registers.grd.num); // dest reg
if (registers.frt.num != -1) encoding |= MIPS_FT(registers.frt.num); // float target reg
if (registers.frs.num != -1) encoding |= MIPS_FS(registers.frs.num); // float source reg
if (registers.frd.num != -1) encoding |= MIPS_FD(registers.frd.num); // float dest reg
if (registers.ps2vrt.num != -1) encoding |= (registers.ps2vrt.num << 16); // ps2 vector target reg
if (registers.ps2vrs.num != -1) encoding |= (registers.ps2vrs.num << 21); // ps2 vector source reg
if (registers.ps2vrd.num != -1) encoding |= (registers.ps2vrd.num << 6); // ps2 vector dest reg

View File

@ -133,7 +133,7 @@ bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask)
return true;
}
if (dataAddress != INVALID_ADDRESS) {
if (info != NULL) {
info->type = ST_DATA;

View File

@ -120,7 +120,7 @@ __fi tDMA_TAG* SPRdmaGetAddr(u32 addr, bool write)
DevCon.Warning("MTVU: SPR Accessing VU1 Memory");
vu1Thread.WaitVU();
}
//Access for VU Memory
if((addr >= 0x1100c000) && (addr < 0x11010000))
@ -134,7 +134,7 @@ __fi tDMA_TAG* SPRdmaGetAddr(u32 addr, bool write)
//DevCon.Warning("VU0 Mem %x", addr);
return (tDMA_TAG*)(VU0.Mem + (addr & 0xff0));
}
//Possibly not needed but the manual doesn't say SPR cannot access it.
if((addr >= 0x11000000) && (addr < 0x11004000))
{
@ -147,8 +147,8 @@ __fi tDMA_TAG* SPRdmaGetAddr(u32 addr, bool write)
//DevCon.Warning("VU1 Micro %x", addr);
return (tDMA_TAG*)(VU1.Micro + (addr & 0x3ff0));
}
// Unreachable
return NULL;
}
@ -255,7 +255,7 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
cpuClearInt( 11 );
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
}
cpuClearInt( channel );
QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
}
@ -307,7 +307,7 @@ __fi u32 dmacRead32( u32 mem )
// Set OPH and APATH from counter, cycling paths and alternating OPH
return gifRegs.stat._u32 & ~(7 << 9) | (counter & 1 ? counter << 9 : 0);
}
return psHu32(mem);
}

View File

@ -41,7 +41,7 @@ Advanced users may wish to use a different folder for their BIOS, you can do so
![PCSX2_First_Time_Configuration_bios.png](PCSX2_First_Time_Configuration_bios.png)
## Post-Setup Configuration
A large number of games work out-of-the-box on default PCSX2 settings. However, a subset of games require special settings to run, and some games require special settings to be upscaled. This guide will briefly cover some frequent problems and configuration settings to address them.
A large number of games work out-of-the-box on default PCSX2 settings. However, a subset of games require special settings to run, and some games require special settings to be upscaled. This guide will briefly cover some frequent problems and configuration settings to address them.
### Multi-Threaded VU1 (MTVU)
The MTVU option is a unique case of a recommended setting that is **not** enabled by default. MTVU boosts performance for PCs with at least 3 cores with almost no consequences for the overwhelming majority of games. However, a small number of high profile games are incompabible with MTVU and will break if it is enabled. For these reasons, we do not enable it by default, **but strongly recommend you do so yourself**. If your game fails to boot, crashes, stalls, or has other problems with it enabled, disable it and try again.
@ -50,7 +50,7 @@ The MTVU option is a unique case of a recommended setting that is **not** enable
Looking for information specific to a single game? Head to the [PCSX2 Wiki](https://wiki.pcsx2.net/Main_Page) and search for your game using the search bar in the top right. Known issues and solutions should be towards the bottom of a game's wiki page.
### General solutions
Want some general ideas to try that are not specific to a game? Here are some more commonly known issues and solutions to try.
Want some general ideas to try that are not specific to a game? Here are some more commonly known issues and solutions to try.
*Note: For some of these issues, multiple solutions are given one after the other. Before moving from one solution to the next, **undo the previous solution**. Stacking multiple fixes on top of each other is usually unnecessary and likely to introduce new issues.*
#### Grid-like pattern on screen
@ -74,7 +74,7 @@ Sometimes a game uses blending for lighting effects and needs more accuracy for
Increment Blending Accuracy until the problem goes away. Note, higher Blending Accuracy substantially increases performance requirements.
#### Flickering or improperly shaped shadows
This can either be a GS or VU problem so solutions will vary wildly by game.
This can either be a GS or VU problem so solutions will vary wildly by game.
##### GS
Navigate to the GSdx Advanced Settings and Hacks:

View File

@ -5,7 +5,7 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2019 PCSX2 Dev Team
*
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.

View File

@ -25,7 +25,7 @@ There are a number of ways to help the project, whether it be bug reporting, gam
* Want to improve the PCSX2 wiki? [Here is how to contribute](https://wiki.pcsx2.net/Help!_How_to_contribute_guide)
### Question 4: Is PCSX2 ready to run out-of-the-box?
No, first, you must dump your PlayStation 2 console's BIOS using the BIOS dumper. The BIOS dumper is [available on the PCSX2 website](https://pcsx2.net/download/releases/tools.html).
No, first, you must dump your PlayStation 2 console's BIOS using the BIOS dumper. The BIOS dumper is [available on the PCSX2 website](https://pcsx2.net/download/releases/tools.html).
After dumping your PlayStation 2 console's BIOS and copying it to your computer, launch PCSX2, step through the first time setup wizard, and then you may begin playing.
@ -44,7 +44,7 @@ After dumping your PlayStation 2 console's BIOS and copying it to your computer,
*Note: Recommended Single Thread Performance is based on moderately complex games. Games that pushed the PS2 hardware to its limits will struggle on CPUs at this level. Some release titles and 2D games which underutilized the PS2 hardware may run on CPUs rated as low as 1200. A quick reference for CPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:CPU_intensive_games), [Forum](https://forums.pcsx2.net/Thread-LIST-The-Most-CPU-Intensive-Games) and CPU **light** games: [Forum](https://forums.pcsx2.net/Thread-LIST-Games-that-don-t-need-a-strong-CPU-to-emulate)*
#### Recommended
#### Recommended
| Operating System | CPU | GPU | RAM |
| --- | --- | --- | --- |
@ -66,7 +66,7 @@ The CPU load as reported in software such as Windows' Task Manager is usually a
No. PCSX2 does not use or require SLI or Crossfire.
### Question 9: How do I check if a game is playable?
The PCSX2 website has a [compatibility list](https://pcsx2.net/compat/) with every game that has been tested.
The PCSX2 website has a [compatibility list](https://pcsx2.net/compat/) with every game that has been tested.
### Question 10: Do PS1 (PSX) games work on PCSX2?
@ -74,12 +74,12 @@ The PCSX2 website has a [compatibility list](https://pcsx2.net/compat/) with eve
No, they will not work without issues. Please use a proper PS1 emulator, such as Duckstation or Mednafen.
#### If you are a tinkerer and like to break things:
PS1 games may work on PCSX2, but compatibility is very limited. Specific settings are often required to get a game to boot, and there are other universal problems including missing/pitch-shifted audio and severe FMV corruption. A [forum thread for PS1 compatibility](https://forums.pcsx2.net/Thread-PSX-Mode-Unofficial-Compatibility-List) is tracking some fixes and compatibility reports.
PS1 games may work on PCSX2, but compatibility is very limited. Specific settings are often required to get a game to boot, and there are other universal problems including missing/pitch-shifted audio and severe FMV corruption. A [forum thread for PS1 compatibility](https://forums.pcsx2.net/Thread-PSX-Mode-Unofficial-Compatibility-List) is tracking some fixes and compatibility reports.
*While we encourage discussion about PS1 games and improving compatibility, bug reports are NOT being accepted for PS1 games. Any reports for PS1 games will be closed immediately as invalid.*
### Question 11: Why does my game not work like it did in an earlier PCSX2 version?
Any change to the emulator may fix one game, but cause problems for another. If the issue is severe and not fixable with different settings, you can always revert back to the last known PCSX2 version to work, and report the build number that broke the game. [Development builds](https://pcsx2.net/download/development.html) are very helpful for finding the exact change that caused a regression.
Any change to the emulator may fix one game, but cause problems for another. If the issue is severe and not fixable with different settings, you can always revert back to the last known PCSX2 version to work, and report the build number that broke the game. [Development builds](https://pcsx2.net/download/development.html) are very helpful for finding the exact change that caused a regression.
### Question 12: Why is PCSX2 slow?
The PlayStation 2 is a complex console, and this substantially raises the PC requirements to emulate it at full speed accurately. [This forum thread](https://forums.pcsx2.net/Thread-Why-is-PCSX2-slow) helps explain some of the technical reasons behind it, and our current guidelines for PC requirements are listed above.
@ -142,12 +142,12 @@ Some settings are greyed out. These are advanced counters that should only be mo
### Question 22: What is the normal speed for a PlayStation 2 game?
* NTSC games will play at 59.94 FPS
* PAL games will play at 50 FPS
* Keep in mind that there is a difference between the internal framerate (iFPS) and what PCSX2 shows as virtual framerate (vFPS).
* Keep in mind that there is a difference between the internal framerate (iFPS) and what PCSX2 shows as virtual framerate (vFPS).
These framerates are what the PlayStation 2 console would push to a real TV through its video cable. A game itself, typically, internally generates only half of those frames, and repeats frames to fill the gaps. This is why a "full speed" game may not "feel like 60 FPS". The console's "speed" (meaning AI, sound, physics, *everything*) is tied to the playback framerate, which is what PCSX2 reports as its "FPS".
These framerates are what the PlayStation 2 console would push to a real TV through its video cable. A game itself, typically, internally generates only half of those frames, and repeats frames to fill the gaps. This is why a "full speed" game may not "feel like 60 FPS". The console's "speed" (meaning AI, sound, physics, *everything*) is tied to the playback framerate, which is what PCSX2 reports as its "FPS".
### Question 23: What are Gamefixes?
Gamefixes are specialized fixes built into PCSX2 for specific games. Gamefixes mostly fix core emulation problems that would crash or soft lock a game, rather than graphical or performance issues. By default, the "System > Automatic Gamefixes" option is enabled, meaning any games that need gamefixes will have them automatically applied, regardless of what gamefix settings you have enabled.
Gamefixes are specialized fixes built into PCSX2 for specific games. Gamefixes mostly fix core emulation problems that would crash or soft lock a game, rather than graphical or performance issues. By default, the "System > Automatic Gamefixes" option is enabled, meaning any games that need gamefixes will have them automatically applied, regardless of what gamefix settings you have enabled.
Most games will not need gamefixes, however if your game is having issues, you can try manually enabling them in Emulation Settings.
@ -161,7 +161,7 @@ As the name says, speedhacks are hacks to make things faster. They will speed up
*Bug reports of issues caused by speedhacks will NOT be accepted, and will be immediately closed as invalid.*
### Question 25: What are all these EE/IOP and VU options?
The PS2 EE, IOP and VU processors are substantially different from a PC CPU and require different rounding and clamping modes to do math accurately. Most games work fine on the default options, but some games might need a different setting. You can check the [PCSX2 Wiki](https://wiki.pcsx2.net/Category:Games) to see if your game needs an alternate setting, or check the [PCSX2 Forums](https://forums.pcsx2.net/) to see if anyone else has posted about it there.
The PS2 EE, IOP and VU processors are substantially different from a PC CPU and require different rounding and clamping modes to do math accurately. Most games work fine on the default options, but some games might need a different setting. You can check the [PCSX2 Wiki](https://wiki.pcsx2.net/Category:Games) to see if your game needs an alternate setting, or check the [PCSX2 Forums](https://forums.pcsx2.net/) to see if anyone else has posted about it there.
### Question 26: What are PCSX2 plugins?
Older versions of PCSX2 used a plugin framework for various sections of the emulator. A plugin is a small, incomplete piece of software that, when plugged in to another piece of software, provides some sort of additional function. PCSX2 used to use plugins for:
@ -184,7 +184,7 @@ For Linux users, PCSX2 will automatically detect and bind controls to any recogn
---
## Useful Links
### BIOS Dumping Guides
### BIOS Dumping Guides
* [pgert's guide to BIOS and memory card tools](https://forums.pcsx2.net/Thread-An-orientation-through-some-of-the-PCSX2-BIOS-memcard-tools-Windows?pid=183709#pid183709)
* [One of the original BIOS dumping guides, originally from ngemu](https://forums.pcsx2.net/Thread-Guide-to-Dumping-Your-PS2-Bios-over-LAN)

View File

@ -150,7 +150,7 @@ std::pair<u32,u32> ElfObject::getTextRange()
if (start <= header.e_entry && (start+size) > header.e_entry)
return std::make_pair(start,size);
}
return std::make_pair(0,0);
}

View File

@ -0,0 +1,312 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/CrashHandler.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/Threading.h"
#include "Frontend/CommonHost.h"
#include "Frontend/FullscreenUI.h"
#include "Frontend/GameList.h"
#include "Frontend/LayeredSettingsInterface.h"
#include "Frontend/InputManager.h"
#include "Frontend/LogSink.h"
#include "GS.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#include "Host.h"
#include "HostSettings.h"
#include "IconsFontAwesome5.h"
#include "MemoryCardFile.h"
#include "PAD/Host/PAD.h"
#include "PerformanceMetrics.h"
#include "Sio.h"
#include "VMManager.h"
#ifdef _WIN32
#include "common/RedtapeWindows.h"
#include <KnownFolders.h>
#include <ShlObj.h>
#endif
static constexpr u32 SETTINGS_VERSION = 1;
namespace CommonHost
{
static void SetAppRoot();
static void SetResourcesDirectory();
static bool ShouldUsePortableMode();
static void SetDataDirectory();
static void SetCommonDefaultSettings(SettingsInterface& si);
} // namespace CommonHost
bool CommonHost::InitializeCriticalFolders()
{
SetAppRoot();
SetResourcesDirectory();
SetDataDirectory();
// logging of directories in case something goes wrong super early
Console.WriteLn("AppRoot Directory: %s", EmuFolders::AppRoot.c_str());
Console.WriteLn("DataRoot Directory: %s", EmuFolders::DataRoot.c_str());
Console.WriteLn("Resources Directory: %s", EmuFolders::Resources.c_str());
// allow SetDataDirectory() to change settings directory (if we want to split config later on)
if (EmuFolders::Settings.empty())
EmuFolders::Settings = Path::Combine(EmuFolders::DataRoot, "inis");
// Write crash dumps to the data directory, since that'll be accessible for certain.
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
// the resources directory should exist, bail out if not
if (!FileSystem::DirectoryExists(EmuFolders::Resources.c_str()))
{
Console.Error("Resources directory is missing.");
return false;
}
return true;
}
void CommonHost::SetAppRoot()
{
std::string program_path(FileSystem::GetProgramPath());
Console.WriteLn("Program Path: %s", program_path.c_str());
EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path));
}
void CommonHost::SetResourcesDirectory()
{
#ifndef __APPLE__
// On Windows/Linux, these are in the binary directory.
EmuFolders::Resources = Path::Combine(EmuFolders::AppRoot, "resources");
#else
// On macOS, this is in the bundle resources directory.
EmuFolders::Resources = Path::Canonicalize(Path::Combine(EmuFolders::AppRoot, "../Resources"));
#endif
}
bool CommonHost::ShouldUsePortableMode()
{
// Check whether portable.ini exists in the program directory.
return FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "portable.ini").c_str());
}
void CommonHost::SetDataDirectory()
{
if (ShouldUsePortableMode())
{
EmuFolders::DataRoot = EmuFolders::AppRoot;
return;
}
#if defined(_WIN32)
// On Windows, use My Documents\PCSX2 to match old installs.
PWSTR documents_directory;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory)))
{
if (std::wcslen(documents_directory) > 0)
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "PCSX2");
CoTaskMemFree(documents_directory);
}
#elif defined(__linux__)
// Use $XDG_CONFIG_HOME/PCSX2 if it exists.
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
{
EmuFolders::DataRoot = Path::Combine(xdg_config_home, "PCSX2");
}
else
{
// Use ~/PCSX2 for non-XDG, and ~/.config/PCSX2 for XDG.
// Maybe we should drop the former when Qt goes live.
const char* home_dir = getenv("HOME");
if (home_dir)
{
#ifndef XDG_STD
EmuFolders::DataRoot = Path::Combine(home_dir, "PCSX2");
#else
// ~/.config should exist, but just in case it doesn't and this is a fresh profile..
const std::string config_dir(Path::Combine(home_dir, ".config"));
if (!FileSystem::DirectoryExists(config_dir.c_str()))
FileSystem::CreateDirectoryPath(config_dir.c_str(), false);
EmuFolders::DataRoot = Path::Combine(config_dir, "PCSX2");
#endif
}
}
#elif defined(__APPLE__)
static constexpr char MAC_DATA_DIR[] = "Library/Application Support/PCSX2";
const char* home_dir = getenv("HOME");
if (home_dir)
EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR);
#endif
// make sure it exists
if (!EmuFolders::DataRoot.empty() && !FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str()))
{
// we're in trouble if we fail to create this directory... but try to hobble on with portable
if (!FileSystem::CreateDirectoryPath(EmuFolders::DataRoot.c_str(), false))
EmuFolders::DataRoot.clear();
}
// couldn't determine the data directory? fallback to portable.
if (EmuFolders::DataRoot.empty())
EmuFolders::DataRoot = EmuFolders::AppRoot;
}
bool CommonHost::CheckSettingsVersion()
{
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
uint settings_version;
return (bsi->GetUIntValue("UI", "SettingsVersion", &settings_version) && settings_version == SETTINGS_VERSION);
}
void CommonHost::LoadStartupSettings()
{
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
EmuFolders::LoadConfig(*bsi);
EmuFolders::EnsureFoldersExist();
UpdateLogging(*bsi);
}
void CommonHost::SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui)
{
if (si.GetUIntValue("UI", "SettingsVersion", 0u) != SETTINGS_VERSION)
si.SetUIntValue("UI", "SettingsVersion", SETTINGS_VERSION);
if (folders)
EmuFolders::SetDefaults(si);
if (core)
{
VMManager::SetDefaultSettings(si);
SetCommonDefaultSettings(si);
}
if (controllers)
PAD::SetDefaultControllerConfig(si);
if (hotkeys)
PAD::SetDefaultHotkeyConfig(si);
if (ui)
Host::SetDefaultUISettings(si);
}
void CommonHost::SetCommonDefaultSettings(SettingsInterface& si)
{
SetDefaultLoggingSettings(si);
}
void CommonHost::CPUThreadInitialize()
{
Threading::SetNameOfCurrentThread("CPU Thread");
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
// neither of these should ever fail.
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
pxFailRel("Failed to allocate memory map");
// We want settings loaded so we choose the correct renderer for big picture mode.
// This also sorts out input sources.
VMManager::LoadSettings();
}
void CommonHost::CPUThreadShutdown()
{
InputManager::CloseSources();
VMManager::WaitForSaveStateFlush();
VMManager::Internal::ReleaseMemory();
VMManager::Internal::ReleaseGlobals();
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
}
void CommonHost::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
{
SettingsInterface* binding_si = Host::GetSettingsInterfaceForBindings();
InputManager::ReloadSources(si, lock);
InputManager::ReloadBindings(si, *binding_si);
UpdateLogging(si);
}
void CommonHost::CheckForSettingsChanges(const Pcsx2Config& old_config)
{
// Nothing yet.
}
void CommonHost::OnVMStarting()
{
CommonHost::Internal::ResetVMHotkeyState();
}
void CommonHost::OnVMStarted()
{
FullscreenUI::OnVMStarted();
}
void CommonHost::OnVMDestroyed()
{
FullscreenUI::OnVMDestroyed();
}
void CommonHost::OnVMPaused()
{
InputManager::PauseVibration();
FullscreenUI::OnVMPaused();
}
void CommonHost::OnVMResumed()
{
FullscreenUI::OnVMResumed();
}
void CommonHost::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name, u32 game_crc)
{
if (FullscreenUI::IsInitialized())
{
GetMTGS().RunOnGSThread([disc_path, game_serial, game_name, game_crc]() {
FullscreenUI::OnRunningGameChanged(std::move(disc_path), std::move(game_serial), std::move(game_name), game_crc);
});
}
}
void CommonHost::CPUThreadVSync()
{
InputManager::PollSources();
}
bool Host::GetSerialAndCRCForFilename(const char* filename, std::string* serial, u32* crc)
{
{
auto lock = GameList::GetLock();
if (const GameList::Entry* entry = GameList::GetEntryForPath(filename); entry)
{
*serial = entry->serial;
*crc = entry->crc;
return true;
}
}
// Just scan it.. hopefully it'll come back okay.
GameList::Entry temp_entry;
if (GameList::PopulateEntryFromPath(filename, &temp_entry))
{
*serial = std::move(temp_entry.serial);
*crc = temp_entry.crc;
return true;
}
return false;
}

View File

@ -0,0 +1,84 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Defs.h"
#include <string>
#include <mutex>
#include "Config.h"
class SettingsInterface;
namespace Host
{
/// Sets host-specific default settings.
void SetDefaultUISettings(SettingsInterface& si);
} // namespace Host
namespace CommonHost
{
/// Initializes critical folders (AppRoot, DataRoot, Settings). Call once on startup.
bool InitializeCriticalFolders();
/// Checks settings version. Call once on startup. If it returns false, you should prompt the user to reset.
bool CheckSettingsVersion();
/// Loads early settings. Call once on startup.
void LoadStartupSettings();
/// Sets default settings for the specified categories.
void SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui);
/// Initializes common host state, called on the CPU thread.
void CPUThreadInitialize();
/// Cleans up common host state, called on the CPU thread.
void CPUThreadShutdown();
/// Loads common host settings (including input bindings).
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
/// Called after settings are updated.
void CheckForSettingsChanges(const Pcsx2Config& old_config);
/// Called when the VM is starting initialization, but has not been completed yet.
void OnVMStarting();
/// Called when the VM is created.
void OnVMStarted();
/// Called when the VM is shut down or destroyed.
void OnVMDestroyed();
/// Called when the VM is paused.
void OnVMPaused();
/// Called when the VM is resumed after being paused.
void OnVMResumed();
/// Called when the running executable changes.
void OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name, u32 game_crc);
/// Provided by the host; called once per frame at guest vsync.
void CPUThreadVSync();
namespace Internal
{
/// Resets any state for hotkey-related VMs, called on VM startup.
void ResetVMHotkeyState();
} // namespace Internal
} // namespace CommonHost

View File

@ -0,0 +1,240 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "Frontend/CommonHost.h"
#include "Frontend/FullscreenUI.h"
#include "Frontend/InputManager.h"
#include "GS.h"
#include "Host.h"
#include "IconsFontAwesome5.h"
#include "Recording/InputRecordingControls.h"
#include "VMManager.h"
static s32 s_current_save_slot = 1;
static std::optional<LimiterModeType> s_limiter_mode_prior_to_hold_interaction;
void CommonHost::Internal::ResetVMHotkeyState()
{
s_current_save_slot = 1;
s_limiter_mode_prior_to_hold_interaction.reset();
}
static void HotkeyAdjustTargetSpeed(double delta)
{
EmuConfig.Framerate.NominalScalar = EmuConfig.GS.LimitScalar + delta;
VMManager::SetLimiterMode(LimiterModeType::Nominal);
gsUpdateFrequency(EmuConfig);
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
Host::AddIconOSDMessage("SpeedChanged", ICON_FA_CLOCK,
fmt::format("Target speed set to {:.0f}%.", std::round(EmuConfig.Framerate.NominalScalar * 100.0)), 5.0f);
}
static constexpr s32 CYCLE_SAVE_STATE_SLOTS = 10;
static void HotkeyCycleSaveSlot(s32 delta)
{
// 1..10
s_current_save_slot = ((s_current_save_slot - 1) + delta);
if (s_current_save_slot < 0)
s_current_save_slot = CYCLE_SAVE_STATE_SLOTS;
else
s_current_save_slot = (s_current_save_slot % CYCLE_SAVE_STATE_SLOTS) + 1;
const u32 crc = VMManager::GetGameCRC();
const std::string serial(VMManager::GetGameSerial());
const std::string filename(VMManager::GetSaveStateFileName(serial.c_str(), crc, s_current_save_slot));
FILESYSTEM_STAT_DATA sd;
if (!filename.empty() && FileSystem::StatFile(filename.c_str(), &sd))
{
char date_buf[128] = {};
#ifdef _WIN32
ctime_s(date_buf, std::size(date_buf), &sd.ModificationTime);
#else
ctime_r(&sd.ModificationTime, date_buf);
#endif
// remove terminating \n
size_t len = std::strlen(date_buf);
if (len > 0 && date_buf[len - 1] == '\n')
date_buf[len - 1] = 0;
Host::AddIconOSDMessage(
"CycleSaveSlot", ICON_FA_SEARCH, fmt::format("Save slot {} selected (last save: {}).", s_current_save_slot, date_buf), 5.0f);
}
else
{
Host::AddIconOSDMessage(
"CycleSaveSlot", ICON_FA_SEARCH, fmt::format("Save slot {} selected (no save yet).", s_current_save_slot), 5.0f);
}
}
static void HotkeyLoadStateSlot(s32 slot)
{
const u32 crc = VMManager::GetGameCRC();
if (crc == 0)
{
Host::AddIconOSDMessage(
"LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE, "Cannot load state from a slot without a game running.", 10.0f);
return;
}
const std::string serial(VMManager::GetGameSerial());
if (!VMManager::HasSaveStateInSlot(serial.c_str(), crc, slot))
{
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE, fmt::format("No save state found in slot {}.", slot));
return;
}
VMManager::LoadStateFromSlot(slot);
}
static void HotkeySaveStateSlot(s32 slot)
{
if (VMManager::GetGameCRC() == 0)
{
Host::AddIconOSDMessage(
"SaveStateToSlot", ICON_FA_EXCLAMATION_TRIANGLE, "Cannot save state to a slot without a game running.", 10.0f);
return;
}
VMManager::SaveStateToSlot(slot);
}
BEGIN_HOTKEY_LIST(g_common_hotkeys)
DEFINE_HOTKEY("OpenPauseMenu", "System", "Open Pause Menu", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
FullscreenUI::OpenPauseMenu();
})
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
VMManager::SetPaused(VMManager::GetState() != VMState::Paused);
})
DEFINE_HOTKEY("ToggleFullscreen", "System", "Toggle Fullscreen", [](s32 pressed) {
if (!pressed)
Host::SetFullscreen(!Host::IsFullscreen());
})
DEFINE_HOTKEY("ToggleFrameLimit", "System", "Toggle Frame Limit", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
{
VMManager::SetLimiterMode(
(EmuConfig.LimiterMode != LimiterModeType::Unlimited) ? LimiterModeType::Unlimited : LimiterModeType::Nominal);
}
})
DEFINE_HOTKEY("ToggleTurbo", "System", "Toggle Turbo", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
{
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Turbo) ? LimiterModeType::Turbo : LimiterModeType::Nominal);
}
})
DEFINE_HOTKEY("ToggleSlowMotion", "System", "Toggle Slow Motion", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
{
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Slomo) ? LimiterModeType::Slomo : LimiterModeType::Nominal);
}
})
DEFINE_HOTKEY("HoldTurbo", "System", "Turbo (Hold)", [](s32 pressed) {
if (!VMManager::HasValidVM())
return;
if (pressed > 0 && !s_limiter_mode_prior_to_hold_interaction.has_value())
{
s_limiter_mode_prior_to_hold_interaction = VMManager::GetLimiterMode();
VMManager::SetLimiterMode((s_limiter_mode_prior_to_hold_interaction.value() != LimiterModeType::Turbo) ? LimiterModeType::Turbo :
LimiterModeType::Nominal);
}
else if (pressed >= 0 && s_limiter_mode_prior_to_hold_interaction.has_value())
{
VMManager::SetLimiterMode(s_limiter_mode_prior_to_hold_interaction.value());
s_limiter_mode_prior_to_hold_interaction.reset();
}
})
DEFINE_HOTKEY("IncreaseSpeed", "System", "Increase Target Speed", [](s32 pressed) {
if (!pressed)
HotkeyAdjustTargetSpeed(0.1);
})
DEFINE_HOTKEY("DecreaseSpeed", "System", "Decrease Target Speed", [](s32 pressed) {
if (!pressed)
HotkeyAdjustTargetSpeed(-0.1);
})
DEFINE_HOTKEY("FrameAdvance", "System", "Frame Advance", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
VMManager::FrameAdvance(1);
})
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
Host::RequestVMShutdown(true, true, EmuConfig.SaveStateOnShutdown);
})
DEFINE_HOTKEY("ResetVM", "System", "Reset Virtual Machine", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
VMManager::Reset();
})
DEFINE_HOTKEY("InputRecToggleMode", "System", "Toggle Input Recording Mode", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
g_InputRecordingControls.RecordModeToggle();
})
DEFINE_HOTKEY("PreviousSaveStateSlot", "Save States", "Select Previous Save Slot", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
HotkeyCycleSaveSlot(-1);
})
DEFINE_HOTKEY("NextSaveStateSlot", "Save States", "Select Next Save Slot", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
HotkeyCycleSaveSlot(1);
})
DEFINE_HOTKEY("SaveStateToSlot", "Save States", "Save State To Selected Slot", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
VMManager::SaveStateToSlot(s_current_save_slot);
})
DEFINE_HOTKEY("LoadStateFromSlot", "Save States", "Load State From Selected Slot", [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
HotkeyLoadStateSlot(s_current_save_slot);
})
#define DEFINE_HOTKEY_SAVESTATE_X(slotnum) \
DEFINE_HOTKEY("SaveStateToSlot" #slotnum, "Save States", "Save State To Slot " #slotnum, [](s32 pressed) { \
if (!pressed) \
HotkeySaveStateSlot(slotnum); \
})
#define DEFINE_HOTKEY_LOADSTATE_X(slotnum) \
DEFINE_HOTKEY("LoadStateFromSlot" #slotnum, "Save States", "Load State From Slot " #slotnum, [](s32 pressed) { \
if (!pressed) \
HotkeyLoadStateSlot(slotnum); \
})
DEFINE_HOTKEY_SAVESTATE_X(1)
DEFINE_HOTKEY_LOADSTATE_X(1)
DEFINE_HOTKEY_SAVESTATE_X(2)
DEFINE_HOTKEY_LOADSTATE_X(2)
DEFINE_HOTKEY_SAVESTATE_X(3)
DEFINE_HOTKEY_LOADSTATE_X(3)
DEFINE_HOTKEY_SAVESTATE_X(4)
DEFINE_HOTKEY_LOADSTATE_X(4)
DEFINE_HOTKEY_SAVESTATE_X(5)
DEFINE_HOTKEY_LOADSTATE_X(5)
DEFINE_HOTKEY_SAVESTATE_X(6)
DEFINE_HOTKEY_LOADSTATE_X(6)
DEFINE_HOTKEY_SAVESTATE_X(7)
DEFINE_HOTKEY_LOADSTATE_X(7)
DEFINE_HOTKEY_SAVESTATE_X(8)
DEFINE_HOTKEY_LOADSTATE_X(8)
DEFINE_HOTKEY_SAVESTATE_X(9)
DEFINE_HOTKEY_LOADSTATE_X(9)
DEFINE_HOTKEY_SAVESTATE_X(10)
DEFINE_HOTKEY_LOADSTATE_X(10)
#undef DEFINE_HOTKEY_SAVESTATE_X
#undef DEFINE_HOTKEY_LOADSTATE_X
END_HOTKEY_LIST()

View File

@ -677,6 +677,13 @@ bool D3D11HostDisplay::BeginPresent(bool frame_skip)
return false;
}
// When using vsync, the time here seems to include the time for the buffer to become available.
// This blows our our GPU usage number considerably, so read the timestamp before the final blit
// in this configuration. It does reduce accuracy a little, but better than seeing 100% all of
// the time, when it's more like a couple of percent.
if (m_vsync_mode != VsyncMode::Off && m_gpu_timing_enabled)
PopTimestampQuery();
static constexpr std::array<float, 4> clear_color = {};
m_context->ClearRenderTargetView(m_swap_chain_rtv.get(), clear_color.data());
m_context->OMSetRenderTargets(1, m_swap_chain_rtv.addressof(), nullptr);
@ -693,14 +700,15 @@ void D3D11HostDisplay::EndPresent()
ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
if (m_gpu_timing_enabled)
// See note in BeginPresent() for why it's conditional on vsync-off.
const bool vsync_on = m_vsync_mode != VsyncMode::Off;
if (!vsync_on && m_gpu_timing_enabled)
PopTimestampQuery();
const UINT vsync_rate = static_cast<UINT>(m_vsync_mode != VsyncMode::Off);
if (vsync_rate == 0 && m_using_allow_tearing)
if (!vsync_on && m_using_allow_tearing)
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
else
m_swap_chain->Present(vsync_rate, 0);
m_swap_chain->Present(static_cast<UINT>(vsync_on), 0);
if (m_gpu_timing_enabled)
KickTimestampQuery();
@ -772,8 +780,7 @@ void D3D11HostDisplay::PopTimestampQuery()
}
}
// delay ending the current query until we've read back some
if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1))
if (m_timestamp_query_started)
{
m_context->End(m_timestamp_queries[m_write_timestamp_query][2].get());
m_context->End(m_timestamp_queries[m_write_timestamp_query][0].get());
@ -785,7 +792,7 @@ void D3D11HostDisplay::PopTimestampQuery()
void D3D11HostDisplay::KickTimestampQuery()
{
if (m_timestamp_query_started || !m_timestamp_queries[0][0])
if (m_timestamp_query_started || !m_timestamp_queries[0][0] || m_waiting_timestamp_queries == NUM_TIMESTAMP_QUERIES)
return;
m_context->Begin(m_timestamp_queries[m_write_timestamp_query][0].get());

View File

@ -75,7 +75,7 @@ public:
protected:
static constexpr u32 DISPLAY_CONSTANT_BUFFER_SIZE = 16;
static constexpr u8 NUM_TIMESTAMP_QUERIES = 3;
static constexpr u8 NUM_TIMESTAMP_QUERIES = 5;
static AdapterAndModeList GetAdapterAndModeList(IDXGIFactory* dxgi_factory);

View File

@ -20,7 +20,6 @@
#include "Frontend/FullscreenUI.h"
#include "Frontend/ImGuiManager.h"
#include "Frontend/ImGuiFullscreen.h"
#include "Frontend/INISettingsInterface.h"
#include "Frontend/InputManager.h"
#include "Frontend/GameList.h"
#include "IconsFontAwesome5.h"
@ -40,6 +39,7 @@
#include "Host.h"
#include "HostDisplay.h"
#include "HostSettings.h"
#include "INISettingsInterface.h"
#include "MemoryCardFile.h"
#include "PAD/Host/PAD.h"
#include "ps2/BiosTools.h"
@ -119,7 +119,9 @@ using ImGuiFullscreen::MenuImageButton;
using ImGuiFullscreen::NavButton;
using ImGuiFullscreen::NavTitle;
using ImGuiFullscreen::OpenChoiceDialog;
using ImGuiFullscreen::OpenConfirmMessageDialog;
using ImGuiFullscreen::OpenFileSelector;
using ImGuiFullscreen::OpenInfoMessageDialog;
using ImGuiFullscreen::OpenInputStringDialog;
using ImGuiFullscreen::PopPrimaryColor;
using ImGuiFullscreen::PushPrimaryColor;
@ -279,6 +281,7 @@ namespace FullscreenUI
static void DoLoadInputProfile();
static void DoSaveInputProfile();
static void DoSaveInputProfile(const std::string& name);
static void DoResetSettings();
static bool DrawToggleSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section, const char* key,
bool default_value, bool enabled = true, bool allow_tristate = true, float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT,
@ -462,7 +465,7 @@ void FullscreenUI::UpdateForcedVsync(bool should_force)
const VsyncMode mode = EmuConfig.GetEffectiveVsyncMode();
// toss it through regardless of the mode, because options can change it
Host::GetHostDisplay()->SetVSync((should_force && mode == VsyncMode::Off) ? VsyncMode::On : mode);
g_host_display->SetVSync((should_force && mode == VsyncMode::Off) ? VsyncMode::On : mode);
}
void FullscreenUI::OnVMStarted()
@ -852,7 +855,7 @@ void FullscreenUI::DoChangeDiscFromFile()
auto callback = [](const std::string& path) {
if (!path.empty())
{
if (!GameList::IsScannableFilename(path))
if (!VMManager::IsDiscFileName(path))
{
ShowToast({}, fmt::format("{} is not a valid disc image.", FileSystem::GetDisplayNameFromPath(path)));
}
@ -1704,8 +1707,7 @@ void FullscreenUI::SwitchToGameSettings(const GameList::Entry* entry)
void FullscreenUI::PopulateGraphicsAdapterList()
{
HostDisplay* display = Host::GetHostDisplay();
HostDisplay::AdapterAndModeList ml(display->GetAdapterAndModeList());
HostDisplay::AdapterAndModeList ml(g_host_display->GetAdapterAndModeList());
s_graphics_adapter_list_cache = std::move(ml.adapter_names);
s_fullscreen_mode_list_cache = std::move(ml.fullscreen_modes);
s_fullscreen_mode_list_cache.insert(s_fullscreen_mode_list_cache.begin(), "Borderless Fullscreen");
@ -2022,6 +2024,13 @@ void FullscreenUI::DrawInterfaceSettingsPage()
DrawToggleSetting(bsi, ICON_FA_PLAY " Show Status Indicators",
"Shows indicators when fast forwarding, pausing, and other abnormal states are active.", "EmuCore/GS", "OsdShowIndicators", true);
MenuHeading("Operations");
if (MenuButton(ICON_FA_FOLDER_MINUS " Reset Settings", "Resets configuration to defaults (excluding controller settings).",
!IsEditingGameSettings(bsi)))
{
DoResetSettings();
}
EndMenuButtons();
}
@ -2247,6 +2256,8 @@ void FullscreenUI::DrawEmulationSettingsPage()
"EmuCore", "EnablePerGameSettings", true);
DrawToggleSetting(bsi, "Enable Host Filesystem", "Enables access to files from the host: namespace in the virtual machine.", "EmuCore",
"HostFs", false);
DrawToggleSetting(bsi, "Warn About Unsafe Settings", "Displays warnings when settings are enabled which may break games.", "EmuCore",
"WarnAboutUnsafeSettings", true);
EndMenuButtons();
}
@ -2321,7 +2332,7 @@ void FullscreenUI::DrawSystemSettingsPage()
static constexpr const char* ee_cycle_rate_settings[] = {
"50% Speed", "60% Speed", "75% Speed", "100% Speed (Default)", "130% Speed", "180% Speed", "300% Speed"};
static constexpr const char* ee_cycle_skip_settings[] = {
"Normal (Default)", "Mild Underclock", "Moderate Overclock", "Maximum Overclock"};
"Normal (Default)", "Mild Underclock", "Moderate Underclock", "Maximum Underclock"};
static constexpr const char* ee_rounding_mode_settings[] = {"Nearest", "Negative", "Positive", "Chop/Zero (Default)"};
static constexpr const char* affinity_control_settings[] = {
"Disabled", "EE > VU > GS", "EE > GS > VU", "VU > EE > GS", "VU > GS > EE", "GS > EE > VU", "GS > VU > EE"};
@ -2918,7 +2929,8 @@ void FullscreenUI::ResetControllerSettings()
{
SettingsInterface* dsi = GetEditingSettingsInterface();
PAD::SetDefaultConfig(*dsi);
PAD::SetDefaultControllerConfig(*dsi);
PAD::SetDefaultHotkeyConfig(*dsi);
ShowToast(std::string(), "Controller settings reset to default.");
}
@ -3005,6 +3017,18 @@ void FullscreenUI::DoSaveInputProfile()
});
}
void FullscreenUI::DoResetSettings()
{
OpenConfirmMessageDialog(ICON_FA_FOLDER_MINUS " Reset Settings",
"Are you sure you want to restore the default settings? Any preferences will be lost.", [](bool result) {
if (result)
{
Host::RunOnCPUThread([]() { Host::RequestResetSettings(false, true, false, false, false); });
ShowToast(std::string(), "Settings reset to defaults.");
}
});
}
void FullscreenUI::DrawControllerSettingsPage()
{
BeginMenuButtons();
@ -3577,7 +3601,7 @@ bool FullscreenUI::InitializeSaveStateListEntry(
std::vector<u32> screenshot_pixels;
if (SaveState_ReadScreenshot(li->path, &screenshot_width, &screenshot_height, &screenshot_pixels))
{
li->preview_texture = Host::GetHostDisplay()->CreateTexture(
li->preview_texture = g_host_display->CreateTexture(
screenshot_width, screenshot_height, screenshot_pixels.data(), sizeof(u32) * screenshot_width, false);
if (!li->preview_texture)
Console.Error("Failed to upload save state image to GPU");
@ -4176,98 +4200,6 @@ void FullscreenUI::DrawAboutWindow()
ImGui::PopFont();
}
bool FullscreenUI::DrawErrorWindow(const char* message)
{
bool is_open = true;
ImGuiFullscreen::BeginLayout();
ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f));
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup("ReportError");
ImGui::PushFont(g_large_font);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f));
if (ImGui::BeginPopupModal("ReportError", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
{
ImGui::SetCursorPos(LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING));
ImGui::TextWrapped("%s", message);
ImGui::GetCurrentWindow()->DC.CursorPos.y += LayoutScale(5.0f);
BeginMenuButtons();
if (ActiveButton(ICON_FA_WINDOW_CLOSE " Close", false))
{
ImGui::CloseCurrentPopup();
is_open = false;
}
EndMenuButtons();
ImGui::EndPopup();
}
ImGui::PopStyleVar(2);
ImGui::PopFont();
ImGuiFullscreen::EndLayout();
return !is_open;
}
bool FullscreenUI::DrawConfirmWindow(const char* message, bool* result)
{
bool is_open = true;
ImGuiFullscreen::BeginLayout();
ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f));
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup("ConfirmMessage");
ImGui::PushFont(g_large_font);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f));
if (ImGui::BeginPopupModal("ConfirmMessage", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
{
ImGui::SetCursorPos(LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING));
ImGui::TextWrapped("%s", message);
ImGui::GetCurrentWindow()->DC.CursorPos.y += LayoutScale(5.0f);
BeginMenuButtons();
bool done = false;
if (ActiveButton(ICON_FA_CHECK " Yes", false))
{
*result = true;
done = true;
}
if (ActiveButton(ICON_FA_TIMES " No", false))
{
*result = false;
done = true;
}
if (done)
{
ImGui::CloseCurrentPopup();
is_open = false;
}
EndMenuButtons();
ImGui::EndPopup();
}
ImGui::PopStyleVar(2);
ImGui::PopFont();
ImGuiFullscreen::EndLayout();
return !is_open;
}
FullscreenUI::ProgressCallback::ProgressCallback(std::string name)
: BaseProgressCallback()
, m_name(std::move(name))

View File

@ -36,10 +36,6 @@ namespace FullscreenUI
void Shutdown();
void Render();
// Returns true if the message has been dismissed.
bool DrawErrorWindow(const char* message);
bool DrawConfirmWindow(const char* message, bool* result);
class ProgressCallback final : public BaseProgressCallback
{
public:

View File

@ -36,7 +36,7 @@
#include "Elfheader.h"
#include "VMManager.h"
#include "Frontend/INISettingsInterface.h"
#include "pcsx2/INISettingsInterface.h"
enum : u32
{
@ -48,6 +48,8 @@ namespace GameList
{
using CacheMap = std::unordered_map<std::string, GameList::Entry>;
static bool IsScannableFilename(const std::string_view& path);
static Entry* GetMutableEntryForPath(const char* path);
static bool GetElfListEntry(const std::string& path, GameList::Entry* entry);
@ -122,15 +124,7 @@ const char* GameList::EntryCompatibilityRatingToString(CompatibilityRating ratin
bool GameList::IsScannableFilename(const std::string_view& path)
{
static const char* extensions[] = {".iso", ".mdf", ".nrg", ".bin", ".img", ".gz", ".cso", ".chd", ".elf", ".irx", ".py2"};
for (const char* test_extension : extensions)
{
if (StringUtil::EndsWithNoCase(path, test_extension))
return true;
}
return false;
return VMManager::IsDiscFileName(path) || VMManager::IsElfFileName(path);
}
void GameList::FillBootParametersForEntry(VMBootParameters* params, const Entry* entry)
@ -204,7 +198,7 @@ bool GameList::GetElfListEntry(const std::string& path, GameList::Entry* entry)
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
entry->path = path;
entry->serial.clear();
entry->title = Path::StripExtension(display_name);
entry->title = Path::GetFileTitle(display_name);
entry->region = Region::Other;
entry->total_size = static_cast<u64>(file_size);
entry->type = EntryType::ELF;

View File

@ -101,8 +101,6 @@ namespace GameList
const char* RegionToString(Region region);
const char* EntryCompatibilityRatingToString(CompatibilityRating rating);
bool IsScannableFilename(const std::string_view& path);
/// Fills in boot parameters (iso or elf) based on the game list entry.
void FillBootParametersForEntry(VMBootParameters* params, const Entry* entry);

View File

@ -15,6 +15,9 @@
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/CrashHandler.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "Frontend/LayeredSettingsInterface.h"
#include "GS.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
@ -121,18 +124,24 @@ void Host::SetBaseStringListSettingValue(const char* section, const char* key, c
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringList(section, key, values);
}
void Host::DeleteBaseSettingValue(const char* section, const char* key)
bool Host::AddBaseValueToStringList(const char* section, const char* key, const char* value)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->AddToStringList(section, key, value);
}
bool Host::RemoveBaseValueFromStringList(const char* section, const char* key, const char* value)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->RemoveFromStringList(section, key, value);
}
void Host::RemoveBaseSettingValue(const char* section, const char* key)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->DeleteValue(section, key);
}
void Host::CommitBaseSettingChanges()
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->Save();
}
std::string Host::GetStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
{
std::unique_lock lock(s_settings_mutex);
@ -221,8 +230,7 @@ void Host::Internal::UpdateEmuFolders()
if (VMManager::HasValidVM())
{
if (EmuFolders::Cheats != old_cheats_directory ||
EmuFolders::CheatsWS != old_cheats_ws_directory ||
if (EmuFolders::Cheats != old_cheats_directory || EmuFolders::CheatsWS != old_cheats_ws_directory ||
EmuFolders::CheatsNI != old_cheats_ni_directory)
{
VMManager::ReloadPatches(true, true);

View File

@ -31,13 +31,17 @@
#include "fmt/core.h"
#include "HostDisplay.h"
#include "imgui_internal.h"
#include "misc/cpp/imgui_stdlib.h"
#include "imgui_stdlib.h"
#include <array>
#include <cmath>
#include <deque>
#include <mutex>
#include <variant>
namespace ImGuiFullscreen
{
using MessageDialogCallbackVariant = std::variant<InfoMessageDialogCallback, ConfirmMessageDialogCallback>;
static std::optional<Common::RGBA8Image> LoadTextureImage(const char* path);
static std::shared_ptr<HostDisplayTexture> UploadTexture(const char* path, const Common::RGBA8Image& image);
static void TextureLoaderThread();
@ -45,6 +49,7 @@ namespace ImGuiFullscreen
static void DrawFileSelector();
static void DrawChoiceDialog();
static void DrawInputDialog();
static void DrawMessageDialog();
static void DrawBackgroundProgressDialogs(ImVec2& position, float spacing);
static void DrawNotifications(ImVec2& position, float spacing);
static void DrawToast();
@ -110,6 +115,12 @@ namespace ImGuiFullscreen
static std::string s_input_dialog_ok_text;
static InputStringDialogCallback s_input_dialog_callback;
static bool s_message_dialog_open = false;
static std::string s_message_dialog_title;
static std::string s_message_dialog_message;
static std::array<std::string, 3> s_message_dialog_buttons;
static MessageDialogCallbackVariant s_message_dialog_callback;
struct FileSelectorItem
{
FileSelectorItem() = default;
@ -215,6 +226,7 @@ void ImGuiFullscreen::Shutdown()
s_notifications.clear();
s_background_progress_dialogs.clear();
CloseInputDialog();
CloseMessageDialog();
s_choice_dialog_open = false;
s_choice_dialog_checkable = false;
s_choice_dialog_title = {};
@ -266,7 +278,7 @@ std::optional<Common::RGBA8Image> ImGuiFullscreen::LoadTextureImage(const char*
std::shared_ptr<HostDisplayTexture> ImGuiFullscreen::UploadTexture(const char* path, const Common::RGBA8Image& image)
{
std::unique_ptr<HostDisplayTexture> texture =
Host::GetHostDisplay()->CreateTexture(image.GetWidth(), image.GetHeight(), image.GetPixels(), image.GetByteStride());
g_host_display->CreateTexture(image.GetWidth(), image.GetHeight(), image.GetPixels(), image.GetByteStride());
if (!texture)
{
Console.Error("failed to create %ux%u texture for resource", image.GetWidth(), image.GetHeight());
@ -459,6 +471,7 @@ void ImGuiFullscreen::EndLayout()
DrawFileSelector();
DrawChoiceDialog();
DrawInputDialog();
DrawMessageDialog();
const float notification_margin = LayoutScale(10.0f);
const float spacing = LayoutScale(10.0f);
@ -1839,9 +1852,13 @@ void ImGuiFullscreen::DrawInputDialog()
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup(s_input_dialog_title.c_str());
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(20.0f, 20.0f));
ImGui::PushFont(g_large_font);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING));
ImGui::PushStyleColor(ImGuiCol_Text, UIPrimaryTextColor);
ImGui::PushStyleColor(ImGuiCol_TitleBg, UIPrimaryDarkColor);
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIPrimaryColor);
ImGui::PushStyleColor(ImGuiCol_PopupBg, UIBackgroundColor);
bool is_open = true;
if (ImGui::BeginPopupModal(s_input_dialog_title.c_str(), &is_open,
@ -1884,8 +1901,9 @@ void ImGuiFullscreen::DrawInputDialog()
if (!is_open)
CloseInputDialog();
ImGui::PopFont();
ImGui::PopStyleColor(4);
ImGui::PopStyleVar(2);
ImGui::PopFont();
}
void ImGuiFullscreen::CloseInputDialog()
@ -1902,6 +1920,125 @@ void ImGuiFullscreen::CloseInputDialog()
s_input_dialog_callback = {};
}
bool ImGuiFullscreen::IsMessageBoxDialogOpen()
{
return s_message_dialog_open;
}
void ImGuiFullscreen::OpenConfirmMessageDialog(
std::string title, std::string message, ConfirmMessageDialogCallback callback, std::string yes_button_text, std::string no_button_text)
{
CloseMessageDialog();
s_message_dialog_open = true;
s_message_dialog_title = std::move(title);
s_message_dialog_message = std::move(message);
s_message_dialog_callback = std::move(callback);
s_message_dialog_buttons[0] = std::move(yes_button_text);
s_message_dialog_buttons[1] = std::move(no_button_text);
}
void ImGuiFullscreen::OpenInfoMessageDialog(
std::string title, std::string message, InfoMessageDialogCallback callback, std::string button_text)
{
CloseMessageDialog();
s_message_dialog_open = true;
s_message_dialog_title = std::move(title);
s_message_dialog_message = std::move(message);
s_message_dialog_callback = std::move(callback);
s_message_dialog_buttons[0] = std::move(button_text);
}
void ImGuiFullscreen::OpenMessageDialog(std::string title, std::string message, MessageDialogCallback callback,
std::string first_button_text, std::string second_button_text, std::string third_button_text)
{
CloseMessageDialog();
s_message_dialog_open = true;
s_message_dialog_title = std::move(title);
s_message_dialog_message = std::move(message);
s_message_dialog_callback = std::move(callback);
s_message_dialog_buttons[0] = std::move(first_button_text);
s_message_dialog_buttons[1] = std::move(second_button_text);
s_message_dialog_buttons[2] = std::move(third_button_text);
}
void ImGuiFullscreen::CloseMessageDialog()
{
if (!s_message_dialog_open)
return;
s_message_dialog_open = false;
s_message_dialog_title = {};
s_message_dialog_message = {};
s_message_dialog_buttons = {};
s_message_dialog_callback = {};
}
void ImGuiFullscreen::DrawMessageDialog()
{
if (!s_message_dialog_open)
return;
const char* win_id = s_message_dialog_title.empty() ? "##messagedialog" : s_message_dialog_title.c_str();
ImGui::SetNextWindowSize(LayoutScale(700.0f, 0.0f));
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup(win_id);
ImGui::PushFont(g_large_font);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(20.0f, 20.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING));
ImGui::PushStyleColor(ImGuiCol_Text, UIPrimaryTextColor);
ImGui::PushStyleColor(ImGuiCol_TitleBg, UIPrimaryDarkColor);
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIPrimaryColor);
ImGui::PushStyleColor(ImGuiCol_PopupBg, UIBackgroundColor);
bool is_open = true;
const u32 flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
(s_message_dialog_title.empty() ? ImGuiWindowFlags_NoTitleBar : 0);
std::optional<s32> result;
if (ImGui::BeginPopupModal(win_id, &is_open, flags))
{
BeginMenuButtons();
ImGui::TextWrapped("%s", s_message_dialog_message.c_str());
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(10.0f));
for (s32 button_index = 0; button_index < static_cast<s32>(s_message_dialog_buttons.size()); button_index++)
{
if (!s_message_dialog_buttons[button_index].empty() && ActiveButton(s_message_dialog_buttons[button_index].c_str(), false))
{
result = button_index;
ImGui::CloseCurrentPopup();
}
}
EndMenuButtons();
ImGui::EndPopup();
}
ImGui::PopStyleColor(4);
ImGui::PopStyleVar(3);
ImGui::PopFont();
if (!is_open || result.has_value())
{
// have to move out in case they open another dialog in the callback
auto cb = (std::move(s_message_dialog_callback));
CloseMessageDialog();
if (std::holds_alternative<InfoMessageDialogCallback>(cb))
std::get<InfoMessageDialogCallback>(cb)();
else if (std::holds_alternative<ConfirmMessageDialogCallback>(cb))
std::get<ConfirmMessageDialogCallback>(cb)(result.value_or(1) == 0);
}
}
static float s_notification_vertical_position = 0.3f;
static float s_notification_vertical_direction = -1.0f;

Some files were not shown because too many files have changed in this diff Show More