Merge pull request #2174 from RadWolfie/add-imgui
Add Basic ImGui Support
This commit is contained in:
commit
52c88d7462
|
@ -31,3 +31,7 @@
|
||||||
url = https://github.com/Cyan4973/xxHash.git
|
url = https://github.com/Cyan4973/xxHash.git
|
||||||
branch = release
|
branch = release
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "import/imgui"]
|
||||||
|
path = import/imgui
|
||||||
|
url = https://github.com/ocornut/imgui.git
|
||||||
|
shadow = true
|
||||||
|
|
|
@ -35,8 +35,12 @@ add_custom_target(misc-batch
|
||||||
WORKING_DIRECTORY ${CXBXR_ROOT_DIR}
|
WORKING_DIRECTORY ${CXBXR_ROOT_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Custom CMake projects since some import libraries doesn't have it.
|
||||||
|
|
||||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/libtom")
|
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/libtom")
|
||||||
|
|
||||||
|
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/imgui")
|
||||||
|
|
||||||
# Split the files into group for which project is likely
|
# Split the files into group for which project is likely
|
||||||
# going to be used for both header and source files.
|
# going to be used for both header and source files.
|
||||||
# Then move only specific project files into their
|
# Then move only specific project files into their
|
||||||
|
@ -109,6 +113,11 @@ file (GLOB CXBXR_HEADER_GUIv1
|
||||||
)
|
)
|
||||||
|
|
||||||
# Emulator (module)
|
# Emulator (module)
|
||||||
|
file (GLOB CXBXR_HEADER_EMU_IMPORT
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_dx9.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_opengl3.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_win32.h"
|
||||||
|
)
|
||||||
file (GLOB CXBXR_HEADER_EMU
|
file (GLOB CXBXR_HEADER_EMU
|
||||||
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.h"
|
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.h"
|
||||||
"${CXBXR_ROOT_DIR}/src/common/audio/converter.hpp"
|
"${CXBXR_ROOT_DIR}/src/common/audio/converter.hpp"
|
||||||
|
@ -116,6 +125,11 @@ file (GLOB CXBXR_HEADER_EMU
|
||||||
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen.h"
|
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen.h"
|
||||||
"${CXBXR_ROOT_DIR}/src/common/audio/XADPCM.h"
|
"${CXBXR_ROOT_DIR}/src/common/audio/XADPCM.h"
|
||||||
"${CXBXR_ROOT_DIR}/src/common/xbox/Logging.hpp"
|
"${CXBXR_ROOT_DIR}/src/common/xbox/Logging.hpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/audio.hpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/ui.hpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/settings.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/video.hpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/video/RenderBase.hpp"
|
||||||
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl"
|
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl"
|
||||||
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.h"
|
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.h"
|
||||||
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl"
|
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl"
|
||||||
|
@ -260,6 +274,11 @@ file (GLOB CXBXR_SOURCE_GUIv1
|
||||||
file (GLOB CXBXR_KRNL_CPP
|
file (GLOB CXBXR_KRNL_CPP
|
||||||
"${CXBXR_ROOT_DIR}/src/core/kernel/init/CxbxKrnl.cpp"
|
"${CXBXR_ROOT_DIR}/src/core/kernel/init/CxbxKrnl.cpp"
|
||||||
)
|
)
|
||||||
|
file (GLOB CXBXR_SOURCE_EMU_IMPORT
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_dx9.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_opengl3.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_win32.cpp"
|
||||||
|
)
|
||||||
file (GLOB CXBXR_SOURCE_EMU
|
file (GLOB CXBXR_SOURCE_EMU
|
||||||
"${CXBXR_KRNL_CPP}"
|
"${CXBXR_KRNL_CPP}"
|
||||||
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.cpp"
|
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.cpp"
|
||||||
|
@ -268,6 +287,10 @@ file (GLOB CXBXR_SOURCE_EMU
|
||||||
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_common.cpp"
|
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_common.cpp"
|
||||||
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_wgl.cpp"
|
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_wgl.cpp"
|
||||||
"${CXBXR_ROOT_DIR}/src/common/xbox/Logging.cpp"
|
"${CXBXR_ROOT_DIR}/src/common/xbox/Logging.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/audio.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/ui.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/imgui/video.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/src/core/common/video/RenderBase.cpp"
|
||||||
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp"
|
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp"
|
||||||
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/RenderStates.cpp"
|
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/RenderStates.cpp"
|
||||||
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/TextureStates.cpp"
|
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/TextureStates.cpp"
|
||||||
|
@ -385,7 +408,7 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/cxbxr-emu")
|
||||||
set(cxbxr_INSTALL_files "COPYING" "README.md")
|
set(cxbxr_INSTALL_files "COPYING" "README.md")
|
||||||
|
|
||||||
# Cxbx-Reloaded project with third-party libraries
|
# Cxbx-Reloaded project with third-party libraries
|
||||||
set_target_properties(cxbx cxbxr-ldr cxbxr-emu misc-batch subhook libXbSymbolDatabase libtommath libtomcrypt
|
set_target_properties(cxbx cxbxr-ldr cxbxr-emu misc-batch subhook libXbSymbolDatabase libtommath libtomcrypt imgui
|
||||||
PROPERTIES FOLDER Cxbx-Reloaded
|
PROPERTIES FOLDER Cxbx-Reloaded
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 35b1148efb839381b84de9290d9caf0b66ad7d03
|
|
@ -77,12 +77,20 @@ file (GLOB RESOURCES
|
||||||
"${CXBXR_ROOT_DIR}/src/.editorconfig"
|
"${CXBXR_ROOT_DIR}/src/.editorconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
|
||||||
|
${CXBXR_HEADER_EMU_IMPORT}
|
||||||
|
)
|
||||||
|
|
||||||
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
|
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
|
||||||
${CXBXR_HEADER_GUIv1}
|
${CXBXR_HEADER_GUIv1}
|
||||||
${CXBXR_HEADER_COMMON}
|
${CXBXR_HEADER_COMMON}
|
||||||
${CXBXR_HEADER_EMU}
|
${CXBXR_HEADER_EMU}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
|
||||||
|
${CXBXR_SOURCE_EMU_IMPORT}
|
||||||
|
)
|
||||||
|
|
||||||
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
|
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
|
||||||
${CXBXR_SOURCE_GUIv1}
|
${CXBXR_SOURCE_GUIv1}
|
||||||
${CXBXR_SOURCE_COMMON}
|
${CXBXR_SOURCE_COMMON}
|
||||||
|
@ -94,9 +102,11 @@ source_group(TREE ${CXBXR_ROOT_DIR} FILES ${RESOURCES})
|
||||||
add_executable(cxbx WIN32 ${RESOURCES}
|
add_executable(cxbx WIN32 ${RESOURCES}
|
||||||
${CXBXR_HEADER_GUIv1}
|
${CXBXR_HEADER_GUIv1}
|
||||||
${CXBXR_HEADER_COMMON}
|
${CXBXR_HEADER_COMMON}
|
||||||
|
${CXBXR_HEADER_EMU_IMPORT}
|
||||||
${CXBXR_HEADER_EMU}
|
${CXBXR_HEADER_EMU}
|
||||||
${CXBXR_SOURCE_GUIv1}
|
${CXBXR_SOURCE_GUIv1}
|
||||||
${CXBXR_SOURCE_COMMON}
|
${CXBXR_SOURCE_COMMON}
|
||||||
|
${CXBXR_SOURCE_EMU_IMPORT}
|
||||||
${CXBXR_SOURCE_EMU}
|
${CXBXR_SOURCE_EMU}
|
||||||
${CXBXR_GIT_VERSION_H}
|
${CXBXR_GIT_VERSION_H}
|
||||||
)
|
)
|
||||||
|
@ -181,6 +191,7 @@ target_link_libraries(cxbx
|
||||||
subhook
|
subhook
|
||||||
libtomcrypt
|
libtomcrypt
|
||||||
SDL2
|
SDL2
|
||||||
|
imgui
|
||||||
|
|
||||||
${WINS_LIB}
|
${WINS_LIB}
|
||||||
)
|
)
|
||||||
|
|
|
@ -68,6 +68,10 @@ file (GLOB RESOURCES
|
||||||
"${CXBXR_ROOT_DIR}/README.md"
|
"${CXBXR_ROOT_DIR}/README.md"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
|
||||||
|
${CXBXR_HEADER_EMU_IMPORT}
|
||||||
|
)
|
||||||
|
|
||||||
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
|
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
|
||||||
${CXBXR_HEADER_GUIv1}
|
${CXBXR_HEADER_GUIv1}
|
||||||
${CXBXR_HEADER_COMMON}
|
${CXBXR_HEADER_COMMON}
|
||||||
|
@ -75,7 +79,11 @@ source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
|
||||||
"${CXBXR_ROOT_DIR}/src/emulator/targetver.h"
|
"${CXBXR_ROOT_DIR}/src/emulator/targetver.h"
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
|
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
|
||||||
|
${CXBXR_SOURCE_EMU_IMPORT}
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
|
||||||
${CXBXR_SOURCE_GUIv1}
|
${CXBXR_SOURCE_GUIv1}
|
||||||
${CXBXR_SOURCE_COMMON}
|
${CXBXR_SOURCE_COMMON}
|
||||||
${CXBXR_SOURCE_EMU}
|
${CXBXR_SOURCE_EMU}
|
||||||
|
@ -87,9 +95,11 @@ source_group(TREE ${CXBXR_ROOT_DIR} FILES ${RESOURCES})
|
||||||
|
|
||||||
add_library(cxbxr-emu SHARED ${RESOURCES}
|
add_library(cxbxr-emu SHARED ${RESOURCES}
|
||||||
${CXBXR_HEADER_COMMON}
|
${CXBXR_HEADER_COMMON}
|
||||||
|
${CXBXR_HEADER_EMU_IMPORT}
|
||||||
${CXBXR_HEADER_EMU}
|
${CXBXR_HEADER_EMU}
|
||||||
"${CXBXR_ROOT_DIR}/src/emulator/targetver.h"
|
"${CXBXR_ROOT_DIR}/src/emulator/targetver.h"
|
||||||
${CXBXR_SOURCE_COMMON}
|
${CXBXR_SOURCE_COMMON}
|
||||||
|
${CXBXR_SOURCE_EMU_IMPORT}
|
||||||
${CXBXR_SOURCE_EMU}
|
${CXBXR_SOURCE_EMU}
|
||||||
${CXBXR_GIT_VERSION_H}
|
${CXBXR_GIT_VERSION_H}
|
||||||
"${CXBXR_ROOT_DIR}/src/emulator/cxbxr-emu.cpp"
|
"${CXBXR_ROOT_DIR}/src/emulator/cxbxr-emu.cpp"
|
||||||
|
@ -157,6 +167,7 @@ target_link_libraries(cxbxr-emu
|
||||||
subhook
|
subhook
|
||||||
libtomcrypt
|
libtomcrypt
|
||||||
SDL2
|
SDL2
|
||||||
|
imgui
|
||||||
|
|
||||||
${WINS_LIB}
|
${WINS_LIB}
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
cmake_minimum_required (VERSION 3.8)
|
||||||
|
project(imgui LANGUAGES CXX)
|
||||||
|
# Since imgui doesn't have CMake, we'll make an interface project here.
|
||||||
|
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
add_compile_definitions(
|
||||||
|
_CRT_SECURE_NO_WARNINGS
|
||||||
|
_CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add any defines from imconfig.h file in here without need to edit import file directly.
|
||||||
|
add_compile_definitions(
|
||||||
|
IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
|
||||||
|
IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
file (GLOB HEADERS
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imconfig.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imgui.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imgui_internal.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imstb_rectpack.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imstb_textedit.h"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imstb_truetype.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
file (GLOB SOURCES
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imgui.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imgui_draw.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imgui_tables.cpp"
|
||||||
|
"${CXBXR_ROOT_DIR}/import/imgui/imgui_widgets.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(TREE ${CXBXR_ROOT_DIR}/import/imgui PREFIX header FILES ${HEADERS})
|
||||||
|
|
||||||
|
source_group(TREE ${CXBXR_ROOT_DIR}/import/imgui PREFIX source FILES ${SOURCES})
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME}
|
||||||
|
PUBLIC "${CXBXR_ROOT_DIR}/import/imgui"
|
||||||
|
)
|
|
@ -38,6 +38,7 @@ typedef enum class _IPC_UPDATE_GUI {
|
||||||
, XBOX_LED_COLOUR
|
, XBOX_LED_COLOUR
|
||||||
, LOG_ENABLED
|
, LOG_ENABLED
|
||||||
, KRNL_IS_READY
|
, KRNL_IS_READY
|
||||||
|
, OVERLAY
|
||||||
} IPC_UPDATE_GUI;
|
} IPC_UPDATE_GUI;
|
||||||
|
|
||||||
void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value);
|
void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value);
|
||||||
|
|
|
@ -112,6 +112,12 @@ static struct {
|
||||||
const char* RenderResolution = "RenderResolution";
|
const char* RenderResolution = "RenderResolution";
|
||||||
} sect_video_keys;
|
} sect_video_keys;
|
||||||
|
|
||||||
|
static const char* section_overlay = "overlay";
|
||||||
|
static struct {
|
||||||
|
const char* FPS = "FPS";
|
||||||
|
const char* hle_lle_stats = "HLE/LLE Stats";
|
||||||
|
} sect_overlay_keys;
|
||||||
|
|
||||||
static const char* section_audio = "audio";
|
static const char* section_audio = "audio";
|
||||||
static struct {
|
static struct {
|
||||||
const char* adapter = "adapter";
|
const char* adapter = "adapter";
|
||||||
|
@ -452,7 +458,7 @@ bool Settings::LoadConfig()
|
||||||
|
|
||||||
m_input_general.MoAxisRange = m_si.GetLongValue(section_input_general, sect_input_general.mo_axis_range, MO_AXIS_DEFAULT_RANGE);
|
m_input_general.MoAxisRange = m_si.GetLongValue(section_input_general, sect_input_general.mo_axis_range, MO_AXIS_DEFAULT_RANGE);
|
||||||
m_input_general.MoWheelRange = m_si.GetLongValue(section_input_general, sect_input_general.mo_wheel_range, MO_WHEEL_DEFAULT_RANGE);
|
m_input_general.MoWheelRange = m_si.GetLongValue(section_input_general, sect_input_general.mo_wheel_range, MO_WHEEL_DEFAULT_RANGE);
|
||||||
m_input_general.IgnoreKbMoUnfocus = m_si.GetLongValue(section_input_general, sect_input_general.ignore_kbmo_unfocus, 1);
|
m_input_general.IgnoreKbMoUnfocus = m_si.GetBoolValue(section_input_general, sect_input_general.ignore_kbmo_unfocus, true);
|
||||||
|
|
||||||
// ==== Input General End ==============
|
// ==== Input General End ==============
|
||||||
|
|
||||||
|
@ -523,6 +529,13 @@ bool Settings::LoadConfig()
|
||||||
|
|
||||||
// ==== Input Profile End ======
|
// ==== Input Profile End ======
|
||||||
|
|
||||||
|
// ==== Overlay Begin =========
|
||||||
|
|
||||||
|
m_overlay.fps = m_si.GetBoolValue(section_overlay, sect_overlay_keys.FPS, true);
|
||||||
|
m_overlay.hle_lle_stats = m_si.SetBoolValue(section_overlay, sect_overlay_keys.hle_lle_stats, true);
|
||||||
|
|
||||||
|
// ==== Overlay End ===========
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,6 +601,7 @@ bool Settings::Save(std::string file_path)
|
||||||
m_si.SetBoolValue(section_video, sect_video_keys.FullScreen, m_video.bFullScreen, nullptr, true);
|
m_si.SetBoolValue(section_video, sect_video_keys.FullScreen, m_video.bFullScreen, nullptr, true);
|
||||||
m_si.SetBoolValue(section_video, sect_video_keys.MaintainAspect, m_video.bMaintainAspect, nullptr, true);
|
m_si.SetBoolValue(section_video, sect_video_keys.MaintainAspect, m_video.bMaintainAspect, nullptr, true);
|
||||||
m_si.SetLongValue(section_video, sect_video_keys.RenderResolution, m_video.renderScaleFactor, nullptr, false, true);
|
m_si.SetLongValue(section_video, sect_video_keys.RenderResolution, m_video.renderScaleFactor, nullptr, false, true);
|
||||||
|
|
||||||
// ==== Video End ===========
|
// ==== Video End ===========
|
||||||
|
|
||||||
// ==== Audio Begin =========
|
// ==== Audio Begin =========
|
||||||
|
@ -617,7 +631,7 @@ bool Settings::Save(std::string file_path)
|
||||||
|
|
||||||
m_si.SetLongValue(section_input_general, sect_input_general.mo_axis_range, m_input_general.MoAxisRange, nullptr, false, true);
|
m_si.SetLongValue(section_input_general, sect_input_general.mo_axis_range, m_input_general.MoAxisRange, nullptr, false, true);
|
||||||
m_si.SetLongValue(section_input_general, sect_input_general.mo_wheel_range, m_input_general.MoWheelRange, nullptr, false, true);
|
m_si.SetLongValue(section_input_general, sect_input_general.mo_wheel_range, m_input_general.MoWheelRange, nullptr, false, true);
|
||||||
m_si.SetLongValue(section_input_general, sect_input_general.ignore_kbmo_unfocus, m_input_general.IgnoreKbMoUnfocus, nullptr, false, true);
|
m_si.SetBoolValue(section_input_general, sect_input_general.ignore_kbmo_unfocus, m_input_general.IgnoreKbMoUnfocus, nullptr, true);
|
||||||
|
|
||||||
// ==== Input General End =========
|
// ==== Input General End =========
|
||||||
|
|
||||||
|
@ -700,6 +714,13 @@ bool Settings::Save(std::string file_path)
|
||||||
|
|
||||||
// ==== Input Profile End ======
|
// ==== Input Profile End ======
|
||||||
|
|
||||||
|
// ==== Overlay Begin =======
|
||||||
|
|
||||||
|
m_si.SetBoolValue(section_overlay, sect_overlay_keys.FPS, m_overlay.fps, nullptr, true);
|
||||||
|
m_si.SetBoolValue(section_overlay, sect_overlay_keys.hle_lle_stats, m_overlay.hle_lle_stats, nullptr, true);
|
||||||
|
|
||||||
|
// ==== Overlay End =========
|
||||||
|
|
||||||
// ==== Hack Begin ==========
|
// ==== Hack Begin ==========
|
||||||
|
|
||||||
m_si.SetBoolValue(section_hack, sect_hack_keys.DisablePixelShaders, m_hacks.DisablePixelShaders, nullptr, true);
|
m_si.SetBoolValue(section_hack, sect_hack_keys.DisablePixelShaders, m_hacks.DisablePixelShaders, nullptr, true);
|
||||||
|
@ -737,6 +758,7 @@ void Settings::SyncToEmulator()
|
||||||
|
|
||||||
// register Video settings
|
// register Video settings
|
||||||
g_EmuShared->SetVideoSettings(&m_video);
|
g_EmuShared->SetVideoSettings(&m_video);
|
||||||
|
g_EmuShared->SetOverlaySettings(&m_overlay);
|
||||||
|
|
||||||
// register Audio settings
|
// register Audio settings
|
||||||
g_EmuShared->SetAudioSettings(&m_audio);
|
g_EmuShared->SetAudioSettings(&m_audio);
|
||||||
|
@ -744,7 +766,7 @@ void Settings::SyncToEmulator()
|
||||||
// register Network settings
|
// register Network settings
|
||||||
g_EmuShared->SetNetworkSettings(&m_network);
|
g_EmuShared->SetNetworkSettings(&m_network);
|
||||||
|
|
||||||
// register Input settings
|
// register xbox device input settings
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
g_EmuShared->SetInputDevTypeSettings(&m_input_port[i].Type, i);
|
g_EmuShared->SetInputDevTypeSettings(&m_input_port[i].Type, i);
|
||||||
if (m_input_port[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
if (m_input_port[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
||||||
|
@ -766,9 +788,8 @@ void Settings::SyncToEmulator()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_EmuShared->SetInputMoAxisSettings(m_input_general.MoAxisRange);
|
// register Input general settings
|
||||||
g_EmuShared->SetInputMoWheelSettings(m_input_general.MoWheelRange);
|
g_EmuShared->SetInputGeneralSettings(&m_input_general);
|
||||||
g_EmuShared->SetInputKbMoUnfocusSettings(m_input_general.IgnoreKbMoUnfocus);
|
|
||||||
|
|
||||||
// register Hacks settings
|
// register Hacks settings
|
||||||
g_EmuShared->SetHackSettings(&m_hacks);
|
g_EmuShared->SetHackSettings(&m_hacks);
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include "core/common/imgui/settings.h"
|
||||||
|
|
||||||
extern std::string g_exec_filepath;
|
extern std::string g_exec_filepath;
|
||||||
|
|
||||||
// Individual library version
|
// Individual library version
|
||||||
|
@ -134,12 +136,14 @@ public:
|
||||||
} m_audio;
|
} m_audio;
|
||||||
static_assert(sizeof(s_audio) == 0x4C, assert_check_shared_memory(s_audio));
|
static_assert(sizeof(s_audio) == 0x4C, assert_check_shared_memory(s_audio));
|
||||||
|
|
||||||
|
// Input general settings
|
||||||
struct s_input_general {
|
struct s_input_general {
|
||||||
long MoAxisRange;
|
long MoAxisRange;
|
||||||
long MoWheelRange;
|
long MoWheelRange;
|
||||||
bool IgnoreKbMoUnfocus;
|
bool IgnoreKbMoUnfocus;
|
||||||
};
|
bool Reserved1[3];
|
||||||
s_input_general m_input_general;
|
} m_input_general;
|
||||||
|
static_assert(sizeof(s_input_general) == 0xC, assert_check_shared_memory(s_input_general));
|
||||||
|
|
||||||
struct s_input_port {
|
struct s_input_port {
|
||||||
int Type;
|
int Type;
|
||||||
|
@ -179,6 +183,8 @@ public:
|
||||||
} m_hacks;
|
} m_hacks;
|
||||||
static_assert(sizeof(s_hack) == 0x28, assert_check_shared_memory(s_hack));
|
static_assert(sizeof(s_hack) == 0x28, assert_check_shared_memory(s_hack));
|
||||||
|
|
||||||
|
overlay_settings m_overlay;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RemoveLegacyConfigs(unsigned int CurrentRevision);
|
void RemoveLegacyConfigs(unsigned int CurrentRevision);
|
||||||
std::string m_file_path = "";
|
std::string m_file_path = "";
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "core\kernel\exports\EmuKrnl.h" // For EmuLog
|
#include "core\kernel\exports\EmuKrnl.h" // For EmuLog
|
||||||
#include "EmuShared.h"
|
#include "EmuShared.h"
|
||||||
#include "devices\usb\OHCI.h"
|
#include "devices\usb\OHCI.h"
|
||||||
|
#include "core/common/video/RenderBase.hpp"
|
||||||
|
|
||||||
// hle input specific
|
// hle input specific
|
||||||
#include "core\hle\XAPI\Xapi.h"
|
#include "core\hle\XAPI\Xapi.h"
|
||||||
|
@ -360,8 +361,9 @@ bool InputDeviceManager::UpdateXboxPortInput(int usb_port, void* Buffer, int Dir
|
||||||
xid_type < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX));
|
xid_type < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX));
|
||||||
bool has_changed = false;
|
bool has_changed = false;
|
||||||
|
|
||||||
|
// First check if ImGui is focus, then ignore any input update occur.
|
||||||
// If somebody else is currently holding the lock, we won't wait and instead report no input changes
|
// If somebody else is currently holding the lock, we won't wait and instead report no input changes
|
||||||
if (m_Mtx.try_lock()) {
|
if (static_cast<uint8_t>(!g_renderbase->IsImGuiFocus()) & static_cast<uint8_t>(m_Mtx.try_lock())) {
|
||||||
for (auto &dev_ptr : m_Devices) {
|
for (auto &dev_ptr : m_Devices) {
|
||||||
if (dev_ptr->GetPort(usb_port)) {
|
if (dev_ptr->GetPort(usb_port)) {
|
||||||
switch (xid_type)
|
switch (xid_type)
|
||||||
|
@ -706,16 +708,13 @@ std::shared_ptr<InputDevice> InputDeviceManager::FindDevice(int usb_port, int du
|
||||||
void InputDeviceManager::UpdateOpt(bool is_gui)
|
void InputDeviceManager::UpdateOpt(bool is_gui)
|
||||||
{
|
{
|
||||||
if (!is_gui) {
|
if (!is_gui) {
|
||||||
long axis_range, wheel_range;
|
Settings::s_input_general input_general;
|
||||||
bool ignore_kbmo;
|
g_EmuShared->GetInputGeneralSettings(&input_general);
|
||||||
g_EmuShared->GetInputMoAxisSettings(&axis_range);
|
DInput::mo_axis_range_pos = input_general.MoAxisRange;
|
||||||
g_EmuShared->GetInputMoWheelSettings(&wheel_range);
|
DInput::mo_wheel_range_pos = input_general.MoWheelRange;
|
||||||
g_EmuShared->GetInputKbMoUnfocusSettings(&ignore_kbmo);
|
DInput::mo_axis_range_neg = -(input_general.MoAxisRange);
|
||||||
DInput::mo_axis_range_pos = axis_range;
|
DInput::mo_wheel_range_neg = -(input_general.MoWheelRange);
|
||||||
DInput::mo_wheel_range_pos = wheel_range;
|
DInput::IgnoreKbMoUnfocus = input_general.IgnoreKbMoUnfocus;
|
||||||
DInput::mo_axis_range_neg = -(axis_range);
|
|
||||||
DInput::mo_wheel_range_neg = -(wheel_range);
|
|
||||||
DInput::IgnoreKbMoUnfocus = ignore_kbmo;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DInput::mo_axis_range_pos = g_Settings->m_input_general.MoAxisRange;
|
DInput::mo_axis_range_pos = g_Settings->m_input_general.MoAxisRange;
|
||||||
|
|
|
@ -152,7 +152,6 @@ EmuShared::EmuShared()
|
||||||
m_bEmulating_status = false;
|
m_bEmulating_status = false;
|
||||||
m_bFirstLaunch = false;
|
m_bFirstLaunch = false;
|
||||||
m_bClipCursor = false;
|
m_bClipCursor = false;
|
||||||
m_bIgnoreKbMoUnfocus = true;
|
|
||||||
|
|
||||||
// Reserve space (default to 0)
|
// Reserve space (default to 0)
|
||||||
m_bReserved4 = false;
|
m_bReserved4 = false;
|
||||||
|
@ -162,6 +161,10 @@ EmuShared::EmuShared()
|
||||||
std::memset(m_Reserved99, 0, sizeof(m_Reserved99));
|
std::memset(m_Reserved99, 0, sizeof(m_Reserved99));
|
||||||
std::memset(m_DeviceControlNames, '\0', sizeof(m_DeviceControlNames));
|
std::memset(m_DeviceControlNames, '\0', sizeof(m_DeviceControlNames));
|
||||||
std::memset(m_DeviceName, '\0', sizeof(m_DeviceName));
|
std::memset(m_DeviceName, '\0', sizeof(m_DeviceName));
|
||||||
|
m_imgui_general.ini_size = IMGUI_INI_SIZE_MAX;
|
||||||
|
std::memset(&m_imgui_general.ini_settings, 0, sizeof(m_imgui_general.ini_settings));
|
||||||
|
std::memset(&m_imgui_audio_windows, 0, sizeof(m_imgui_audio_windows));
|
||||||
|
std::memset(&m_imgui_video_windows, 0, sizeof(m_imgui_video_windows));
|
||||||
for (auto& i : m_DeviceType) {
|
for (auto& i : m_DeviceType) {
|
||||||
i = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
|
i = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "Mutex.h"
|
#include "Mutex.h"
|
||||||
#include "common\IPCHybrid.hpp"
|
#include "common\IPCHybrid.hpp"
|
||||||
#include "common\input\Button.h"
|
#include "common\input\Button.h"
|
||||||
|
#include "core/common/imgui/settings.h"
|
||||||
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
|
@ -152,12 +153,8 @@ class EmuShared : public Mutex
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * Input option Accessors
|
// * Input option Accessors
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
void GetInputMoAxisSettings(long *axis) { Lock(); *axis = m_MoAxisRange; Unlock(); }
|
void GetInputGeneralSettings(Settings::s_input_general *input_general) { Lock(); *input_general = m_input_general; Unlock(); }
|
||||||
void SetInputMoAxisSettings(const long axis) { Lock(); m_MoAxisRange = axis; Unlock(); }
|
void SetInputGeneralSettings(const Settings::s_input_general *input_general) { Lock(); m_input_general = *input_general; Unlock(); }
|
||||||
void GetInputMoWheelSettings(long *wheel) { Lock(); *wheel = m_MoWheelRange; Unlock(); }
|
|
||||||
void SetInputMoWheelSettings(const long wheel) { Lock(); m_MoWheelRange = wheel; Unlock(); }
|
|
||||||
void GetInputKbMoUnfocusSettings(bool *flag) { Lock(); *flag = m_bIgnoreKbMoUnfocus; Unlock(); }
|
|
||||||
void SetInputKbMoUnfocusSettings(const bool flag) { Lock(); m_bIgnoreKbMoUnfocus = flag; Unlock(); }
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * LLE Flags Accessors
|
// * LLE Flags Accessors
|
||||||
|
@ -200,7 +197,7 @@ class EmuShared : public Mutex
|
||||||
// * Debugging flag Accessors
|
// * Debugging flag Accessors
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
void GetDebuggingFlag(bool *value) { Lock(); *value = m_bDebugging; Unlock(); }
|
void GetDebuggingFlag(bool *value) { Lock(); *value = m_bDebugging; Unlock(); }
|
||||||
void SetDebuggingFlag(const bool *value) { Lock(); m_bDebugging = *value; Unlock(); }
|
void SetDebuggingFlag(const bool value) { Lock(); m_bDebugging = value; Unlock(); }
|
||||||
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
|
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * Previous Memory Layout value Accessors
|
// * Previous Memory Layout value Accessors
|
||||||
|
@ -250,7 +247,44 @@ class EmuShared : public Mutex
|
||||||
// * ClipCursor flag Accessors
|
// * ClipCursor flag Accessors
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
void GetClipCursorFlag(bool *value) { Lock(); *value = m_bClipCursor; Unlock(); }
|
void GetClipCursorFlag(bool *value) { Lock(); *value = m_bClipCursor; Unlock(); }
|
||||||
void SetClipCursorFlag(const bool *value) { Lock(); m_bClipCursor = *value; Unlock(); }
|
void SetClipCursorFlag(const bool value) { Lock(); m_bClipCursor = value; Unlock(); }
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * ImGui Accessors
|
||||||
|
// ******************************************************************
|
||||||
|
void GetImGuiFocusFlag(bool *value) { Lock(); *value = m_imgui_general.is_focus; Unlock(); }
|
||||||
|
void SetImGuiFocusFlag(const bool value) { Lock(); m_imgui_general.is_focus = value; Unlock(); }
|
||||||
|
|
||||||
|
void GetImGuiIniSettings(char value[IMGUI_INI_SIZE_MAX]) {
|
||||||
|
Lock();
|
||||||
|
if (m_imgui_general.ini_size < IMGUI_INI_SIZE_MAX) {
|
||||||
|
value = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strcpy_s(value, IMGUI_INI_SIZE_MAX, m_imgui_general.ini_settings);
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
void SetImGuiIniSettings(const char value[IMGUI_INI_SIZE_MAX]) {
|
||||||
|
Lock();
|
||||||
|
// Do not save if external size is less than internal limit
|
||||||
|
if (m_imgui_general.ini_size < IMGUI_INI_SIZE_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strcpy_s(m_imgui_general.ini_settings, IMGUI_INI_SIZE_MAX, value);
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetImGuiAudioWindows(imgui_audio_windows *value) { Lock(); *value = m_imgui_audio_windows; Unlock(); }
|
||||||
|
void SetImGuiAudioWindows(const imgui_audio_windows* value) { Lock(); m_imgui_audio_windows = *value; Unlock(); }
|
||||||
|
void GetImGuiVideoWindows(imgui_video_windows*value) { Lock(); *value = m_imgui_video_windows; Unlock(); }
|
||||||
|
void SetImGuiVideoWindows(const imgui_video_windows* value) { Lock(); m_imgui_video_windows = *value; Unlock(); }
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * Overlay Accessors
|
||||||
|
// ******************************************************************
|
||||||
|
void GetOverlaySettings(overlay_settings *value) { Lock(); *value = m_imgui_overlay_settings; Unlock(); }
|
||||||
|
void SetOverlaySettings(const overlay_settings* value) { Lock(); m_imgui_overlay_settings = *value; Unlock(); }
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * Reset specific variables to default for kernel mode.
|
// * Reset specific variables to default for kernel mode.
|
||||||
|
@ -301,15 +335,13 @@ class EmuShared : public Mutex
|
||||||
#endif
|
#endif
|
||||||
bool m_bFirstLaunch;
|
bool m_bFirstLaunch;
|
||||||
bool m_bClipCursor;
|
bool m_bClipCursor;
|
||||||
bool m_bIgnoreKbMoUnfocus;
|
bool m_bReserved3;
|
||||||
bool m_bReserved4;
|
bool m_bReserved4;
|
||||||
unsigned int m_dwKrnlProcID; // Only used for kernel mode level.
|
unsigned int m_dwKrnlProcID; // Only used for kernel mode level.
|
||||||
int m_DeviceType[4];
|
int m_DeviceType[4];
|
||||||
char m_DeviceControlNames[4][HIGHEST_NUM_BUTTONS][HOST_BUTTON_NAME_LENGTH];
|
char m_DeviceControlNames[4][HIGHEST_NUM_BUTTONS][HOST_BUTTON_NAME_LENGTH];
|
||||||
char m_DeviceName[4][50];
|
char m_DeviceName[4][50];
|
||||||
long m_MoAxisRange;
|
int m_Reserved99[28]; // Reserve space
|
||||||
long m_MoWheelRange;
|
|
||||||
int m_Reserved99[26]; // Reserve space
|
|
||||||
|
|
||||||
// Settings class in memory should not be tampered by third-party.
|
// Settings class in memory should not be tampered by third-party.
|
||||||
// Third-party program should only be allow to edit settings.ini file.
|
// Third-party program should only be allow to edit settings.ini file.
|
||||||
|
@ -317,7 +349,12 @@ class EmuShared : public Mutex
|
||||||
Settings::s_video m_video;
|
Settings::s_video m_video;
|
||||||
Settings::s_audio m_audio;
|
Settings::s_audio m_audio;
|
||||||
Settings::s_network m_network;
|
Settings::s_network m_network;
|
||||||
|
Settings::s_input_general m_input_general;
|
||||||
Settings::s_hack m_hacks;
|
Settings::s_hack m_hacks;
|
||||||
|
imgui_general m_imgui_general;
|
||||||
|
overlay_settings m_imgui_overlay_settings;
|
||||||
|
imgui_audio_windows m_imgui_audio_windows;
|
||||||
|
imgui_video_windows m_imgui_video_windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
|
@ -65,6 +65,10 @@ void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value)
|
||||||
cmdParam = ID_GUI_STATUS_KRNL_IS_READY;
|
cmdParam = ID_GUI_STATUS_KRNL_IS_READY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IPC_UPDATE_GUI::OVERLAY:
|
||||||
|
cmdParam = ID_GUI_STATUS_OVERLAY;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cmdParam = 0;
|
cmdParam = 0;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
|
||||||
|
#define LOG_PREFIX CXBXR_MODULE::GUI
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "audio.hpp"
|
||||||
|
|
||||||
|
#include "EmuShared.h"
|
||||||
|
|
||||||
|
bool ImGuiAudio::Initialize()
|
||||||
|
{
|
||||||
|
g_EmuShared->GetImGuiAudioWindows(&m_windows);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiAudio::Shutdown()
|
||||||
|
{
|
||||||
|
g_EmuShared->SetImGuiAudioWindows(&m_windows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiAudio::DrawMenu()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Audio")) {
|
||||||
|
ImGui::MenuItem("Debug General Cache Stats", NULL, &m_windows.cache_stats_general);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiAudio::DrawWidgets(bool is_focus, ImGuiWindowFlags input_handler)
|
||||||
|
{
|
||||||
|
//TODO: In need of make interface class to return generic info in some way.
|
||||||
|
extern void DSound_PrintStats(bool, ImGuiWindowFlags, bool m_show_audio_stats);
|
||||||
|
DSound_PrintStats(is_focus, input_handler, m_windows.cache_stats_general);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
class ImGuiAudio
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImGuiAudio() = default;
|
||||||
|
virtual ~ImGuiAudio() = default;
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
void DrawMenu();
|
||||||
|
void DrawWidgets(bool is_focus, ImGuiWindowFlags input_handler);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
imgui_audio_windows m_windows;
|
||||||
|
};
|
|
@ -0,0 +1,53 @@
|
||||||
|
// ******************************************************************
|
||||||
|
// *
|
||||||
|
// * This file is part of the Cxbx-Reloaded project.
|
||||||
|
// *
|
||||||
|
// * Cxbx and Cxbe are free software; you can redistribute them
|
||||||
|
// * and/or modify them under the terms of the GNU General Public
|
||||||
|
// * License as published by the Free Software Foundation; either
|
||||||
|
// * version 2 of the license, or (at your option) any later version.
|
||||||
|
// *
|
||||||
|
// * This program 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 recieved a copy of the GNU General Public License
|
||||||
|
// * along with this program; see the file COPYING.
|
||||||
|
// * If not, write to the Free Software Foundation, Inc.,
|
||||||
|
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
||||||
|
// *
|
||||||
|
// * (c) 2021 RadWolfie
|
||||||
|
// *
|
||||||
|
// * All rights reserved
|
||||||
|
// *
|
||||||
|
// ******************************************************************
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Intended to store as permanent settings
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool fps;
|
||||||
|
bool hle_lle_stats;
|
||||||
|
} overlay_settings;
|
||||||
|
|
||||||
|
// Intended for EmuShared only below
|
||||||
|
|
||||||
|
const int IMGUI_INI_SIZE_MAX = 1024;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool is_focus;
|
||||||
|
bool Reserved[3];
|
||||||
|
int ini_size; // Cannot be touch anywhere except EmuShared's constructor.
|
||||||
|
char ini_settings[IMGUI_INI_SIZE_MAX];
|
||||||
|
} imgui_general;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool cache_stats_general;
|
||||||
|
bool Reserved[3];
|
||||||
|
} imgui_audio_windows;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool cache_stats_vertex;
|
||||||
|
bool Reserved[3];
|
||||||
|
} imgui_video_windows;
|
|
@ -0,0 +1,160 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
//
|
||||||
|
// Copyright 2010 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
|
||||||
|
#define LOG_PREFIX CXBXR_MODULE::GUI
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "ui.hpp"
|
||||||
|
#include "EmuShared.h"
|
||||||
|
|
||||||
|
#include "core/kernel/init/CxbxKrnl.h"
|
||||||
|
|
||||||
|
bool ImGuiUI::Initialize()
|
||||||
|
{
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
m_imgui_context = ImGui::CreateContext();
|
||||||
|
if (!m_imgui_context) {
|
||||||
|
CxbxKrnlCleanup("Unable to create ImGui context!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
#if 0 // TODO: Currently most voted for memory, so this block of code is disabled. And may will add an option between file vs memory.
|
||||||
|
// May be best ideal to do manual update call than ImGui's internal auto update.
|
||||||
|
g_EmuShared->GetStorageLocation(m_file_path);
|
||||||
|
if (m_file_path[0] == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
strcat_s(m_file_path, "/imgui.ini");
|
||||||
|
io.IniFilename = m_file_path;
|
||||||
|
#else
|
||||||
|
io.IniFilename = nullptr;
|
||||||
|
char temp_ini_settings[IMGUI_INI_SIZE_MAX];
|
||||||
|
g_EmuShared->GetImGuiIniSettings(temp_ini_settings);
|
||||||
|
ImGui::LoadIniSettingsFromMemory(temp_ini_settings, IMGUI_INI_SIZE_MAX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
g_EmuShared->GetImGuiFocusFlag(&m_is_focus);
|
||||||
|
|
||||||
|
g_EmuShared->GetOverlaySettings(&m_settings);
|
||||||
|
g_EmuShared->GetFlagsLLE(&m_lle_flags);
|
||||||
|
m_audio.Initialize();
|
||||||
|
m_video.Initialize();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiUI::Shutdown()
|
||||||
|
{
|
||||||
|
size_t ini_size = IMGUI_INI_SIZE_MAX;
|
||||||
|
const char* temp_ini_settings = ImGui::SaveIniSettingsToMemory(&ini_size);
|
||||||
|
if (ini_size > IMGUI_INI_SIZE_MAX) {
|
||||||
|
CxbxKrnlCleanup("ImGui ini settings is too large: %d > %d (IMGUI_INI_SIZE_MAX)", ini_size, IMGUI_INI_SIZE_MAX);
|
||||||
|
}
|
||||||
|
g_EmuShared->SetImGuiIniSettings(temp_ini_settings);
|
||||||
|
g_EmuShared->SetOverlaySettings(&m_settings);
|
||||||
|
m_audio.Shutdown();
|
||||||
|
m_video.Shutdown();
|
||||||
|
ImGui::DestroyContext(m_imgui_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGuiUI::IsImGuiFocus()
|
||||||
|
{
|
||||||
|
return m_is_focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiUI::ToggleImGui()
|
||||||
|
{
|
||||||
|
m_is_focus = !m_is_focus;
|
||||||
|
g_EmuShared->SetImGuiFocusFlag(m_is_focus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiUI::DrawMenu()
|
||||||
|
{
|
||||||
|
if (!m_is_focus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
|
if (ImGui::BeginMenu("Settings")) {
|
||||||
|
if (ImGui::BeginMenu("Overlay")) {
|
||||||
|
bool bChanged = false;
|
||||||
|
bChanged |= ImGui::MenuItem("Show FPS", NULL, &m_settings.fps);
|
||||||
|
bChanged |= ImGui::MenuItem("Show HLE/LLE Stats", NULL, &m_settings.hle_lle_stats);
|
||||||
|
if (bChanged) {
|
||||||
|
g_EmuShared->SetOverlaySettings(&m_settings);
|
||||||
|
ipc_send_gui_update(IPC_UPDATE_GUI::OVERLAY, 1);
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_video.DrawMenu();
|
||||||
|
m_audio.DrawMenu();
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiUI::DrawWidgets()
|
||||||
|
{
|
||||||
|
if (m_settings.fps || m_settings.hle_lle_stats) {
|
||||||
|
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x - (IMGUI_MIN_DIST_SIDE/* * m_backbuffer_scale*/),
|
||||||
|
IMGUI_MIN_DIST_TOP/* * m_backbuffer_scale*/), ImGuiCond_Always, ImVec2(1.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(200.0f/* * m_backbuffer_scale*/, 0.0f));
|
||||||
|
ImGui::SetNextWindowBgAlpha(0.5f);
|
||||||
|
if (ImGui::Begin("overlay_stats", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoNav |
|
||||||
|
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar |
|
||||||
|
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||||
|
|
||||||
|
if (m_settings.fps) {
|
||||||
|
|
||||||
|
float fps_counter;
|
||||||
|
g_EmuShared->GetCurrentFPS(&fps_counter);
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "FPS: %.2f MS / F : %.2f", fps_counter, (float)(1000.0 / fps_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_settings.hle_lle_stats) {
|
||||||
|
std::string flagString = "LLE-";
|
||||||
|
|
||||||
|
// TODO: Need improvement in upstream for all of bLLE_xxx globals
|
||||||
|
// Set LLE flags string based on selected LLE flags
|
||||||
|
if (m_lle_flags & LLE_APU) {
|
||||||
|
flagString.append("A");
|
||||||
|
}
|
||||||
|
if (m_lle_flags & LLE_GPU) {
|
||||||
|
flagString.append("G");
|
||||||
|
}
|
||||||
|
if (m_lle_flags & LLE_USB) {
|
||||||
|
flagString.append("U");
|
||||||
|
}
|
||||||
|
if (m_lle_flags & LLE_JIT) {
|
||||||
|
flagString.append("J");
|
||||||
|
}
|
||||||
|
if (m_lle_flags == 0) {
|
||||||
|
flagString = "HLE";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align text to the right
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetWindowWidth() - ImGui::CalcTextSize(flagString.c_str()).x
|
||||||
|
- ImGui::GetScrollX() - 2 * ImGui::GetStyle().ItemSpacing.x);
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), flagString.c_str());
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiWindowFlags input_handler = m_is_focus ? ImGuiWindowFlags_None : ImGuiWindowFlags_NoInputs;
|
||||||
|
|
||||||
|
m_video.DrawWidgets(m_is_focus, input_handler);
|
||||||
|
|
||||||
|
m_audio.DrawWidgets(m_is_focus, input_handler);
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
//
|
||||||
|
// Copyright 2010 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
#include "audio.hpp"
|
||||||
|
#include "video.hpp"
|
||||||
|
|
||||||
|
constexpr float IMGUI_MIN_DIST_TOP = 20.0f;
|
||||||
|
constexpr float IMGUI_MIN_DIST_SIDE = 1.0f;
|
||||||
|
|
||||||
|
class ImGuiUI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImGuiUI() = default;
|
||||||
|
virtual ~ImGuiUI() = default;
|
||||||
|
|
||||||
|
void ToggleImGui();
|
||||||
|
bool IsImGuiFocus();
|
||||||
|
|
||||||
|
void DrawMenu();
|
||||||
|
void DrawWidgets();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
template<class C, class T>
|
||||||
|
void Render(C callback, T arg)
|
||||||
|
{
|
||||||
|
// Some games seem to call Swap concurrently, so we need to ensure only one thread
|
||||||
|
// at a time can render ImGui
|
||||||
|
std::unique_lock lock(m_imgui_mutex, std::try_to_lock);
|
||||||
|
if (!lock) return;
|
||||||
|
|
||||||
|
callback(this, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::mutex m_imgui_mutex;
|
||||||
|
ImGuiContext* m_imgui_context;
|
||||||
|
char m_file_path[FILENAME_MAX+1];
|
||||||
|
bool m_is_focus;
|
||||||
|
// Using as their own member than integrate may be helpful to bind different plugin at latter change?
|
||||||
|
ImGuiAudio m_audio;
|
||||||
|
ImGuiVideo m_video;
|
||||||
|
overlay_settings m_settings;
|
||||||
|
unsigned int m_lle_flags;
|
||||||
|
// Make them as settings storage.
|
||||||
|
/*bool m_show_fps;
|
||||||
|
bool m_show_LLE_stats;
|
||||||
|
// Make them as memory storage.
|
||||||
|
bool m_show_vertex_stats;
|
||||||
|
bool m_show_audio_stats;
|
||||||
|
*/
|
||||||
|
};
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
|
||||||
|
#define LOG_PREFIX CXBXR_MODULE::GUI
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "video.hpp"
|
||||||
|
#include "ui.hpp"
|
||||||
|
|
||||||
|
#include "EmuShared.h"
|
||||||
|
|
||||||
|
#include "core/kernel/init/CxbxKrnl.h"
|
||||||
|
#include "core/hle/D3D8/XbVertexBuffer.h"
|
||||||
|
|
||||||
|
bool ImGuiVideo::Initialize()
|
||||||
|
{
|
||||||
|
g_EmuShared->GetImGuiVideoWindows(&m_windows);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiVideo::Shutdown()
|
||||||
|
{
|
||||||
|
g_EmuShared->SetImGuiVideoWindows(&m_windows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiVideo::DrawMenu()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Video")) {
|
||||||
|
ImGui::MenuItem("Debug Vertex Buffer Cache Stats", NULL, &m_windows.cache_stats_vertex);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiVideo::DrawWidgets(bool is_focus, ImGuiWindowFlags input_handler)
|
||||||
|
{
|
||||||
|
// Render vertex buffer cache stats
|
||||||
|
if (m_windows.cache_stats_vertex) {
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(IMGUI_MIN_DIST_SIDE, IMGUI_MIN_DIST_TOP), ImGuiCond_FirstUseEver, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(200, 275), ImGuiCond_FirstUseEver);
|
||||||
|
if (ImGui::Begin("Debugging stats", nullptr, input_handler | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||||
|
if (ImGui::CollapsingHeader("Vertex Buffer Cache", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
|
VertexBufferConverter.DrawCacheStats();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
class ImGuiVideo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImGuiVideo() = default;
|
||||||
|
virtual ~ImGuiVideo() = default;
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
void DrawMenu();
|
||||||
|
void DrawWidgets(bool is_focus, ImGuiWindowFlags input_handler);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
imgui_video_windows m_windows;
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
//
|
||||||
|
// Copyright 2010 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
|
||||||
|
//#define LOG_PREFIX CXBXR_MODULE::GUI
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "RenderBase.hpp"
|
||||||
|
|
||||||
|
//#include "core/kernel/init/CxbxKrnl.h"
|
||||||
|
|
||||||
|
std::unique_ptr<RenderBase> g_renderbase;
|
||||||
|
|
||||||
|
bool RenderBase::Initialize()
|
||||||
|
{
|
||||||
|
if (!ImGuiUI::Initialize()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderBase::Shutdown()
|
||||||
|
{
|
||||||
|
DeviceRelease();
|
||||||
|
m_device_release = std::function<void()>{};
|
||||||
|
WindowRelease();
|
||||||
|
m_window_release = std::function<void()>{};
|
||||||
|
ImGuiUI::Shutdown();
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2021 Cxbx-Reloaded Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
//
|
||||||
|
// Copyright 2010 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the COPYING file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../imgui/ui.hpp"
|
||||||
|
|
||||||
|
class RenderBase : public ImGuiUI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderBase() = default;
|
||||||
|
virtual ~RenderBase() = default;
|
||||||
|
|
||||||
|
virtual bool Initialize();
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
template<class C, class T>
|
||||||
|
void Render(std::function<void(C, T)> callback, T arg)
|
||||||
|
{
|
||||||
|
ImGuiUI::Render(callback, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When video backends has its own class, make DeviceRelease call as virtual requirement for parent class usage.
|
||||||
|
void SetDeviceRelease(const std::function<void()>& func_register) {
|
||||||
|
m_device_release = func_register;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceRelease() {
|
||||||
|
m_device_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWindowRelease(const std::function<void()>& func_register) {
|
||||||
|
m_window_release = func_register;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowRelease() {
|
||||||
|
m_window_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::function<void()> m_device_release;
|
||||||
|
std::function<void()> m_window_release;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::unique_ptr<RenderBase> g_renderbase;
|
|
@ -61,6 +61,11 @@
|
||||||
#include "common/util/strConverter.hpp" // for utf8_to_utf16
|
#include "common/util/strConverter.hpp" // for utf8_to_utf16
|
||||||
#include "VertexShaderSource.h"
|
#include "VertexShaderSource.h"
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <backends/imgui_impl_dx9.h>
|
||||||
|
#include <backends/imgui_impl_win32.h>
|
||||||
|
#include "core/common/video/RenderBase.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
@ -123,8 +128,6 @@ static size_t g_QuadToTriangleHostIndexBuffer_Size = 0; //
|
||||||
static INDEX16 *g_pQuadToTriangleIndexData = nullptr;
|
static INDEX16 *g_pQuadToTriangleIndexData = nullptr;
|
||||||
static size_t g_QuadToTriangleIndexData_Size = 0; // = NrOfQuadIndices
|
static size_t g_QuadToTriangleIndexData_Size = 0; // = NrOfQuadIndices
|
||||||
|
|
||||||
static CxbxVertexBufferConverter VertexBufferConverter = {};
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
xbox::X_D3DSurface Surface;
|
xbox::X_D3DSurface Surface;
|
||||||
RECT SrcRect;
|
RECT SrcRect;
|
||||||
|
@ -181,6 +184,31 @@ float g_Xbox_BackbufferScaleY = 1;
|
||||||
|
|
||||||
static constexpr size_t INDEX_BUFFER_CACHE_SIZE = 10000;
|
static constexpr size_t INDEX_BUFFER_CACHE_SIZE = 10000;
|
||||||
|
|
||||||
|
static void CxbxImGui_RenderD3D9(ImGuiUI* m_imgui, IDirect3DSurface9* renderTarget)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_NewFrame();
|
||||||
|
ImGui_ImplWin32_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
m_imgui->DrawMenu();
|
||||||
|
m_imgui->DrawWidgets();
|
||||||
|
|
||||||
|
ImGui::EndFrame();
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
ImDrawData* drawData = ImGui::GetDrawData();
|
||||||
|
if (drawData->TotalVtxCount > 0) {
|
||||||
|
IDirect3DSurface9* pExistingRenderTarget = nullptr;
|
||||||
|
if (SUCCEEDED(g_pD3DDevice->GetRenderTarget(0, &pExistingRenderTarget))) {
|
||||||
|
g_pD3DDevice->SetRenderTarget(0, renderTarget);
|
||||||
|
ImGui_ImplDX9_RenderDrawData(drawData);
|
||||||
|
g_pD3DDevice->SetRenderTarget(0, pExistingRenderTarget);
|
||||||
|
pExistingRenderTarget->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Unused :
|
/* Unused :
|
||||||
static xbox::dword_xt *g_Xbox_D3DDevice; // TODO: This should be a D3DDevice structure
|
static xbox::dword_xt *g_Xbox_D3DDevice; // TODO: This should be a D3DDevice structure
|
||||||
*/
|
*/
|
||||||
|
@ -633,6 +661,13 @@ void CxbxInitWindow(bool bFullInit)
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFocus(g_hEmuWindow);
|
SetFocus(g_hEmuWindow);
|
||||||
|
g_renderbase = std::unique_ptr<RenderBase>(new RenderBase());
|
||||||
|
g_renderbase->Initialize();
|
||||||
|
|
||||||
|
ImGui_ImplWin32_Init(g_hEmuWindow);
|
||||||
|
g_renderbase->SetWindowRelease([] {
|
||||||
|
ImGui_ImplWin32_Shutdown();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUEM(HWND hWnd)
|
void DrawUEM(HWND hWnd)
|
||||||
|
@ -709,6 +744,27 @@ void CxbxReleaseCursor()
|
||||||
ClipCursor(nullptr);
|
ClipCursor(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CxbxUpdateCursor(bool forceShow = false) {
|
||||||
|
// Getting cursor info is a requirement in order to prevent a bug occur with ShowCursor redundant calls.
|
||||||
|
CURSORINFO cursorInfo;
|
||||||
|
cursorInfo.cbSize = sizeof(cursorInfo);
|
||||||
|
if (!GetCursorInfo(&cursorInfo)) {
|
||||||
|
// If cursor info is not available, then ignore the cursor update.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_renderbase->IsImGuiFocus() || forceShow) {
|
||||||
|
if (cursorInfo.flags == 0) {
|
||||||
|
ShowCursor(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((cursorInfo.flags & CURSOR_SHOWING) != 0) {
|
||||||
|
ShowCursor(FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline DWORD GetXboxCommonResourceType(const xbox::dword_xt XboxResource_Common)
|
inline DWORD GetXboxCommonResourceType(const xbox::dword_xt XboxResource_Common)
|
||||||
{
|
{
|
||||||
DWORD dwCommonType = XboxResource_Common & X_D3DCOMMON_TYPE_MASK;
|
DWORD dwCommonType = XboxResource_Common & X_D3DCOMMON_TYPE_MASK;
|
||||||
|
@ -1804,11 +1860,16 @@ void ToggleFauxFullscreen(HWND hWnd)
|
||||||
g_bIsFauxFullscreen = !g_bIsFauxFullscreen;
|
g_bIsFauxFullscreen = !g_bIsFauxFullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
// rendering window message procedure
|
// rendering window message procedure
|
||||||
static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static bool bAutoPaused = false;
|
static bool bAutoPaused = false;
|
||||||
|
|
||||||
|
const LRESULT imguiResult = ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam);
|
||||||
|
if (imguiResult != 0) return imguiResult;
|
||||||
|
|
||||||
switch(msg)
|
switch(msg)
|
||||||
{
|
{
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
|
@ -1900,10 +1961,8 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
||||||
}
|
}
|
||||||
else if (wParam == VK_F1)
|
else if (wParam == VK_F1)
|
||||||
{
|
{
|
||||||
VertexBufferConverter.PrintStats();
|
g_renderbase->ToggleImGui();
|
||||||
|
CxbxUpdateCursor();
|
||||||
extern void DSound_PrintStats(); //TODO: move into plugin class usage.
|
|
||||||
DSound_PrintStats();
|
|
||||||
}
|
}
|
||||||
else if (wParam == VK_F2)
|
else if (wParam == VK_F2)
|
||||||
{
|
{
|
||||||
|
@ -1912,7 +1971,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
||||||
else if (wParam == VK_F3)
|
else if (wParam == VK_F3)
|
||||||
{
|
{
|
||||||
g_bClipCursor = !g_bClipCursor;
|
g_bClipCursor = !g_bClipCursor;
|
||||||
g_EmuShared->SetClipCursorFlag(&g_bClipCursor);
|
g_EmuShared->SetClipCursorFlag(g_bClipCursor);
|
||||||
|
|
||||||
if (g_bClipCursor) {
|
if (g_bClipCursor) {
|
||||||
CxbxClipCursor(hWnd);
|
CxbxClipCursor(hWnd);
|
||||||
|
@ -2007,7 +2066,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
||||||
DInput::mo_leave_wnd = true;
|
DInput::mo_leave_wnd = true;
|
||||||
g_bIsTrackingMoLeave = false;
|
g_bIsTrackingMoLeave = false;
|
||||||
g_bIsTrackingMoMove = true;
|
g_bIsTrackingMoMove = true;
|
||||||
ShowCursor(TRUE);
|
CxbxUpdateCursor(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2024,7 +2083,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
||||||
tme.dwFlags = TME_LEAVE;
|
tme.dwFlags = TME_LEAVE;
|
||||||
TrackMouseEvent(&tme);
|
TrackMouseEvent(&tme);
|
||||||
g_bIsTrackingMoLeave = true;
|
g_bIsTrackingMoLeave = true;
|
||||||
ShowCursor(FALSE);
|
CxbxUpdateCursor();
|
||||||
|
|
||||||
if (g_bIsTrackingMoMove) {
|
if (g_bIsTrackingMoMove) {
|
||||||
DInput::mo_leave_wnd = false;
|
DInput::mo_leave_wnd = false;
|
||||||
|
@ -2037,7 +2096,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
CxbxReleaseCursor();
|
CxbxReleaseCursor();
|
||||||
DestroyWindow(hWnd);
|
DestroyWindow(hWnd);
|
||||||
CxbxKrnlShutDown();
|
CxbxKrnlShutDown();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
|
@ -2056,7 +2115,6 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
||||||
SetCursor(NULL);
|
SetCursor(NULL);
|
||||||
return S_OK; // = Is not part of D3D8 handling.
|
return S_OK; // = Is not part of D3D8 handling.
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2351,7 +2409,8 @@ static void CreateDefaultD3D9Device
|
||||||
// Final release of IDirect3DDevice9 must be called from the window message thread
|
// Final release of IDirect3DDevice9 must be called from the window message thread
|
||||||
// See https://docs.microsoft.com/en-us/windows/win32/direct3d9/multithreading-issues
|
// See https://docs.microsoft.com/en-us/windows/win32/direct3d9/multithreading-issues
|
||||||
RunOnWndMsgThread([] {
|
RunOnWndMsgThread([] {
|
||||||
g_pD3DDevice->Release();
|
// We only need to call bundled device release once here.
|
||||||
|
g_renderbase->DeviceRelease();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2449,6 +2508,13 @@ static void CreateDefaultD3D9Device
|
||||||
|
|
||||||
// Set up cache
|
// Set up cache
|
||||||
g_VertexShaderSource.ResetD3DDevice(g_pD3DDevice);
|
g_VertexShaderSource.ResetD3DDevice(g_pD3DDevice);
|
||||||
|
|
||||||
|
// Set up ImGui's render backend
|
||||||
|
ImGui_ImplDX9_Init(g_pD3DDevice);
|
||||||
|
g_renderbase->SetDeviceRelease([] {
|
||||||
|
ImGui_ImplDX9_Shutdown();
|
||||||
|
g_pD3DDevice->Release();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5348,6 +5414,10 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(D3DDevice_Swap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render ImGui
|
||||||
|
static std::function<void(ImGuiUI*, IDirect3DSurface*)> internal_render = &CxbxImGui_RenderD3D9;
|
||||||
|
g_renderbase->Render(internal_render, pCurrentHostBackBuffer);
|
||||||
|
|
||||||
pCurrentHostBackBuffer->Release();
|
pCurrentHostBackBuffer->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef WALKINDEXBUFFER_H
|
#ifndef WALKINDEXBUFFER_H
|
||||||
#define WALKINDEXBUFFER_H
|
#define WALKINDEXBUFFER_H
|
||||||
|
|
||||||
#include "core\kernel\support\Emu.h"
|
#include "core/hle/D3D8/XbD3D8Types.h"
|
||||||
|
|
||||||
extern void(*WalkIndexBuffer)
|
extern void(*WalkIndexBuffer)
|
||||||
(
|
(
|
||||||
|
|
|
@ -83,6 +83,8 @@
|
||||||
#define IDirect3DSwapChain IDirect3DSwapChain9
|
#define IDirect3DSwapChain IDirect3DSwapChain9
|
||||||
#define IDirect3DQuery IDirect3DQuery9
|
#define IDirect3DQuery IDirect3DQuery9
|
||||||
|
|
||||||
|
typedef xbox::word_xt INDEX16; // TODO: Move INDEX16 into xbox namespace
|
||||||
|
|
||||||
namespace xbox {
|
namespace xbox {
|
||||||
|
|
||||||
// TODO : Declare these aliasses as Xbox type
|
// TODO : Declare these aliasses as Xbox type
|
||||||
|
|
|
@ -38,12 +38,16 @@
|
||||||
#include "core\hle\D3D8\XbVertexBuffer.h"
|
#include "core\hle\D3D8\XbVertexBuffer.h"
|
||||||
#include "core\hle\D3D8\XbConvert.h"
|
#include "core\hle\D3D8\XbConvert.h"
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#define MAX_STREAM_NOT_USED_TIME (2 * CLOCKS_PER_SEC) // TODO: Trim the not used time
|
#define MAX_STREAM_NOT_USED_TIME (2 * CLOCKS_PER_SEC) // TODO: Trim the not used time
|
||||||
|
|
||||||
|
CxbxVertexBufferConverter VertexBufferConverter = {};
|
||||||
|
|
||||||
// Inline vertex buffer emulation
|
// Inline vertex buffer emulation
|
||||||
xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType = xbox::X_D3DPT_INVALID;
|
xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType = xbox::X_D3DPT_INVALID;
|
||||||
uint32_t g_InlineVertexBuffer_WrittenRegisters = 0; // A bitmask, indicating which registers have been set in g_InlineVertexBuffer_Table
|
uint32_t g_InlineVertexBuffer_WrittenRegisters = 0; // A bitmask, indicating which registers have been set in g_InlineVertexBuffer_Table
|
||||||
|
@ -191,6 +195,7 @@ CxbxPatchedStream& CxbxVertexBufferConverter::GetPatchedStream(uint64_t dataKey,
|
||||||
|
|
||||||
auto it = m_PatchedStreams.find(key);
|
auto it = m_PatchedStreams.find(key);
|
||||||
if (it != m_PatchedStreams.end()) {
|
if (it != m_PatchedStreams.end()) {
|
||||||
|
m_TotalLookupSuccesses++;
|
||||||
m_PatchedStreamUsageList.splice(m_PatchedStreamUsageList.begin(), m_PatchedStreamUsageList, it->second);
|
m_PatchedStreamUsageList.splice(m_PatchedStreamUsageList.begin(), m_PatchedStreamUsageList, it->second);
|
||||||
return *it->second;
|
return *it->second;
|
||||||
}
|
}
|
||||||
|
@ -215,12 +220,18 @@ CxbxPatchedStream& CxbxVertexBufferConverter::GetPatchedStream(uint64_t dataKey,
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CxbxVertexBufferConverter::PrintStats()
|
void CxbxVertexBufferConverter::DrawCacheStats()
|
||||||
{
|
{
|
||||||
printf("Vertex Buffer Cache Status: \n");
|
const ULONG falsePositives = std::exchange(m_TotalLookupSuccesses, 0) - m_TotalCacheHits;
|
||||||
printf("- Cache Size: %d\n", m_PatchedStreams.size());
|
const ULONG totalMisses = m_VertexStreamHashMisses + m_DataNotInCacheMisses;
|
||||||
printf("- Hits: %d\n", m_TotalCacheHits);
|
|
||||||
printf("- Misses: %d\n", m_TotalCacheMisses);
|
ImGui::Text("Cache Size: %u", m_PatchedStreams.size());
|
||||||
|
ImGui::Text("Hits: %u", std::exchange(m_TotalCacheHits, 0));
|
||||||
|
ImGui::Text("Total misses: %u", totalMisses);
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::TextUnformatted("Cache miss details:");
|
||||||
|
ImGui::TextWrapped("Vertex stream hash miss: %u", std::exchange(m_VertexStreamHashMisses, 0));
|
||||||
|
ImGui::TextWrapped("Data not in cache: %u", std::exchange(m_DataNotInCacheMisses, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CxbxVertexBufferConverter::ConvertStream
|
void CxbxVertexBufferConverter::ConvertStream
|
||||||
|
@ -339,7 +350,11 @@ void CxbxVertexBufferConverter::ConvertStream
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_TotalCacheMisses++;
|
// Gather stats
|
||||||
|
if (patchedStream.uiVertexStreamInformationHash != pVertexShaderSteamInfoHash)
|
||||||
|
m_VertexStreamHashMisses++;
|
||||||
|
else
|
||||||
|
m_DataNotInCacheMisses++;
|
||||||
|
|
||||||
// If execution reaches here, the cached vertex buffer was not valid and we must reconvert the data
|
// If execution reaches here, the cached vertex buffer was not valid and we must reconvert the data
|
||||||
// Free the existing buffers
|
// Free the existing buffers
|
||||||
|
|
|
@ -40,7 +40,7 @@ typedef struct _CxbxDrawContext
|
||||||
IN DWORD dwStartVertex; // Only D3DDevice_DrawVertices sets this (potentially higher than default 0)
|
IN DWORD dwStartVertex; // Only D3DDevice_DrawVertices sets this (potentially higher than default 0)
|
||||||
IN PWORD pXboxIndexData; // Set by D3DDevice_DrawIndexedVertices, D3DDevice_DrawIndexedVerticesUP and HLE_draw_inline_elements
|
IN PWORD pXboxIndexData; // Set by D3DDevice_DrawIndexedVertices, D3DDevice_DrawIndexedVerticesUP and HLE_draw_inline_elements
|
||||||
IN DWORD dwBaseVertexIndex; // Set to g_Xbox_BaseVertexIndex in D3DDevice_DrawIndexedVertices
|
IN DWORD dwBaseVertexIndex; // Set to g_Xbox_BaseVertexIndex in D3DDevice_DrawIndexedVertices
|
||||||
IN INDEX16 LowIndex, HighIndex; // Set when pXboxIndexData is set
|
IN INDEX16 LowIndex, HighIndex; // Set when pXboxIndexData is set
|
||||||
IN UINT NumVerticesToUse; // Set by CxbxVertexBufferConverter::Apply
|
IN UINT NumVerticesToUse; // Set by CxbxVertexBufferConverter::Apply
|
||||||
// Data if Draw...UP call
|
// Data if Draw...UP call
|
||||||
IN PVOID pXboxVertexStreamZeroData;
|
IN PVOID pXboxVertexStreamZeroData;
|
||||||
|
@ -78,7 +78,7 @@ class CxbxVertexBufferConverter
|
||||||
public:
|
public:
|
||||||
CxbxVertexBufferConverter() = default;
|
CxbxVertexBufferConverter() = default;
|
||||||
void Apply(CxbxDrawContext *pPatchDesc);
|
void Apply(CxbxDrawContext *pPatchDesc);
|
||||||
void PrintStats();
|
void DrawCacheStats();
|
||||||
private:
|
private:
|
||||||
struct StreamKey
|
struct StreamKey
|
||||||
{
|
{
|
||||||
|
@ -99,7 +99,9 @@ class CxbxVertexBufferConverter
|
||||||
|
|
||||||
// Stack tracking
|
// Stack tracking
|
||||||
ULONG m_TotalCacheHits = 0;
|
ULONG m_TotalCacheHits = 0;
|
||||||
ULONG m_TotalCacheMisses = 0;
|
ULONG m_TotalLookupSuccesses = 0;
|
||||||
|
ULONG m_VertexStreamHashMisses = 0;
|
||||||
|
ULONG m_DataNotInCacheMisses = 0;
|
||||||
|
|
||||||
const UINT m_MaxCacheSize = 10000; // Maximum number of entries in the cache
|
const UINT m_MaxCacheSize = 10000; // Maximum number of entries in the cache
|
||||||
const UINT m_CacheElasticity = 200; // Cache is allowed to grow this much more than maximum before being purged to maximum
|
const UINT m_CacheElasticity = 200; // Cache is allowed to grow this much more than maximum before being purged to maximum
|
||||||
|
@ -114,6 +116,8 @@ class CxbxVertexBufferConverter
|
||||||
void ConvertStream(CxbxDrawContext *pPatchDesc, CxbxVertexDeclaration* pCxbxVertexDeclaration, UINT uiStream);
|
void ConvertStream(CxbxDrawContext *pPatchDesc, CxbxVertexDeclaration* pCxbxVertexDeclaration, UINT uiStream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern CxbxVertexBufferConverter VertexBufferConverter;
|
||||||
|
|
||||||
// Inline vertex buffer emulation
|
// Inline vertex buffer emulation
|
||||||
extern xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType;
|
extern xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
#define LOG_PREFIX CXBXR_MODULE::DSOUND
|
#define LOG_PREFIX CXBXR_MODULE::DSOUND
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "core/common/imgui/ui.hpp"
|
||||||
|
|
||||||
#include <core\kernel\exports\xboxkrnl.h>
|
#include <core\kernel\exports\xboxkrnl.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
#include "DirectSoundGlobal.hpp"
|
#include "DirectSoundGlobal.hpp"
|
||||||
|
@ -51,83 +54,102 @@ DWORD g_dwXbMemAllocated = 0;
|
||||||
DWORD g_dwFree2DBuffers = 0;
|
DWORD g_dwFree2DBuffers = 0;
|
||||||
DWORD g_dwFree3DBuffers = 0;
|
DWORD g_dwFree3DBuffers = 0;
|
||||||
|
|
||||||
void DSound_PrintStats()
|
void DSound_PrintStats(bool is_focus, ImGuiWindowFlags input_handler, bool m_show_audio_stats)
|
||||||
{
|
{
|
||||||
DSoundMutexGuardLock;
|
DSoundMutexGuardLock;
|
||||||
|
|
||||||
std::stringstream ss;
|
if (m_show_audio_stats) {
|
||||||
ss << "Stats:"
|
|
||||||
"\n--DirectSound Cache--";
|
|
||||||
ss << "\n\tTotal DSBuffer cache = " << g_pDSoundBufferCache.size();
|
|
||||||
ss << "\n\tTotal DSStream cache = " << g_pDSoundStreamCache.size();
|
|
||||||
|
|
||||||
// Generate DSBuffer stats
|
ImGui::SetNextWindowPos(ImVec2(IMGUI_MIN_DIST_SIDE, IMGUI_MIN_DIST_TOP), ImGuiCond_FirstUseEver, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(200, 275), ImGuiCond_FirstUseEver);
|
||||||
|
if (ImGui::Begin("Debugging stats", nullptr, input_handler | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||||
|
if (ImGui::CollapsingHeader("Audio Buffers", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
|
|
||||||
DWORD dwStatus;
|
ImGui::Text("DirectSound Cache:");
|
||||||
HRESULT hRet;
|
ImGui::BulletText("Total DSBuffer cache = %u", g_pDSoundBufferCache.size());
|
||||||
unsigned index = 0, isActive = 0;
|
ImGui::BulletText("Total DSStream cache = %u", g_pDSoundStreamCache.size());
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
ss << "\nActive DSBuffer cache:";
|
// Generate DSBuffer stats
|
||||||
|
|
||||||
for (const auto& i : g_pDSoundBufferCache) {
|
DWORD dwStatus;
|
||||||
const auto& buffer = i->emuDSBuffer;
|
HRESULT hRet;
|
||||||
hRet = buffer->EmuDirectSoundBuffer8->GetStatus(&dwStatus);
|
unsigned index = 0, isActive = 0;
|
||||||
if (hRet == DS_OK && (dwStatus & DSBSTATUS_PLAYING) != 0) {
|
|
||||||
isActive++;
|
if (ImGui::CollapsingHeader("Active DSBuffer cache")) {
|
||||||
ss << "\n\tDSBufferCache[" << index << "] = " << reinterpret_cast<void*>(i);
|
|
||||||
ss << "\n\t\tstatus = ";
|
for (const auto& i : g_pDSoundBufferCache) {
|
||||||
if ((dwStatus & DSBSTATUS_LOOPING) != 0) {
|
const auto& buffer = i->emuDSBuffer;
|
||||||
ss << "looping";
|
hRet = buffer->EmuDirectSoundBuffer8->GetStatus(&dwStatus);
|
||||||
}
|
if (hRet == DS_OK && (dwStatus & DSBSTATUS_PLAYING) != 0) {
|
||||||
else {
|
if (isActive) {
|
||||||
ss << "play once";
|
ImGui::Separator();
|
||||||
}
|
}
|
||||||
ss << "\n\t\tX_BufferCacheSize = " << buffer->X_BufferCacheSize;
|
isActive++;
|
||||||
ss << "\n\t\tEmuFlags = " << buffer->EmuFlags;
|
|
||||||
ss << "\n\t\tEmuRegionToggle = " << buffer->EmuBufferToggle;
|
ImGui::BulletText("DSBufferCache[%u] = 0x%p", index, reinterpret_cast<void*>(i));
|
||||||
if (buffer->EmuBufferToggle == xbox::X_DSB_TOGGLE_PLAY) {
|
ImGui::Indent();
|
||||||
ss << "\n\t\t\tEmuRegionPlayStartOffset = " << buffer->EmuRegionPlayStartOffset;
|
ImGui::BulletText("status = %s", ((dwStatus & DSBSTATUS_LOOPING) != 0) ? "looping" : "play once");
|
||||||
ss << "\n\t\t\tEmuRegionPlayLength = " << buffer->EmuRegionPlayLength;
|
|
||||||
}
|
ImGui::BulletText("X_BufferCacheSize = 0x%u", buffer->X_BufferCacheSize);
|
||||||
else if (buffer->EmuBufferToggle == xbox::X_DSB_TOGGLE_LOOP) {
|
ImGui::BulletText("EmuFlags = %X", buffer->EmuFlags);
|
||||||
ss << "\n\t\t\tEmuRegionLoopStartOffset = " << buffer->EmuRegionLoopStartOffset;
|
ImGui::BulletText("EmuRegionToggle = 0x%X", buffer->EmuBufferToggle);
|
||||||
ss << "\n\t\t\tEmuRegionLoopLength = " << buffer->EmuRegionLoopLength;
|
if (buffer->EmuBufferToggle == xbox::X_DSB_TOGGLE_PLAY) {
|
||||||
|
ImGui::Indent();
|
||||||
|
ImGui::BulletText("EmuRegionPlayStartOffset = 0x%X", buffer->EmuRegionPlayStartOffset);
|
||||||
|
ImGui::BulletText("EmuRegionPlayLength = 0x%X", buffer->EmuRegionPlayLength);
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
else if (buffer->EmuBufferToggle == xbox::X_DSB_TOGGLE_LOOP) {
|
||||||
|
ImGui::Indent();
|
||||||
|
ImGui::BulletText("EmuRegionLoopStartOffset = 0x%X", buffer->EmuRegionLoopStartOffset);
|
||||||
|
ImGui::BulletText("EmuRegionLoopLength = 0x%X", buffer->EmuRegionLoopLength);
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isActive == 0) {
|
||||||
|
ImGui::BulletText("(none)");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Total active DSBuffer = %u", isActive);
|
||||||
|
}
|
||||||
|
// Generate DSStream stats
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
isActive = 0;
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Active DSStream cache")) {
|
||||||
|
for (const auto& i : g_pDSoundStreamCache) {
|
||||||
|
hRet = i->EmuDirectSoundBuffer8->GetStatus(&dwStatus);
|
||||||
|
if (hRet == DS_OK && (dwStatus & DSBSTATUS_PLAYING) != 0) {
|
||||||
|
if (isActive) {
|
||||||
|
ImGui::Separator();
|
||||||
|
}
|
||||||
|
isActive++;
|
||||||
|
ImGui::BulletText("DSStreamCache[%u] = 0x%p", index, reinterpret_cast<void*>(i));
|
||||||
|
ImGui::Indent();
|
||||||
|
ImGui::BulletText("Max packets allow = %u", i->X_MaxAttachedPackets);
|
||||||
|
ImGui::BulletText("Total packets = %u", i->Host_BufferPacketArray.size());
|
||||||
|
ImGui::BulletText("is processing = %d", i->Host_isProcessing);
|
||||||
|
ImGui::BulletText("EmuFlags = %X", i->EmuFlags);
|
||||||
|
ImGui::BulletText("Xb_Status = %X", i->Xb_Status);
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isActive == 0) {
|
||||||
|
ImGui::BulletText("(none)");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Total active DSStream = %u", isActive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::End();
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isActive == 0) {
|
|
||||||
ss << "\n\t(none)";
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << "\nTotal active DSBuffer = " << isActive;
|
|
||||||
|
|
||||||
// Generate DSStream stats
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
isActive = 0;
|
|
||||||
|
|
||||||
ss << "\nActive DSStream cache:";
|
|
||||||
for (const auto& i : g_pDSoundStreamCache) {
|
|
||||||
hRet = i->EmuDirectSoundBuffer8->GetStatus(&dwStatus);
|
|
||||||
if (hRet == DS_OK && (dwStatus & DSBSTATUS_PLAYING) != 0) {
|
|
||||||
isActive++;
|
|
||||||
ss << "\n\tDSStreamCache[" << index << "] = " << reinterpret_cast<void*>(i);
|
|
||||||
ss << "\n\t\tMax packets allow = " << i->X_MaxAttachedPackets;
|
|
||||||
ss << "\n\t\tTotal packets = " << i->Host_BufferPacketArray.size();
|
|
||||||
ss << "\n\t\tis processing = " << i->Host_isProcessing;
|
|
||||||
ss << "\n\t\tEmuFlags = " << i->EmuFlags;
|
|
||||||
ss << "\n\t\tXb_Status = " << i->Xb_Status;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isActive == 0) {
|
|
||||||
ss << "\n\t(none)";
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << "\nTotal active DSStream = " << isActive;
|
|
||||||
|
|
||||||
EmuLog(LOG_LEVEL::INFO, ss.str().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,13 +488,17 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
||||||
{
|
{
|
||||||
LOG_FUNC_ONE_ARG(Routine);
|
LOG_FUNC_ONE_ARG(Routine);
|
||||||
|
|
||||||
|
bool is_reboot = false;
|
||||||
|
|
||||||
switch (Routine) {
|
switch (Routine) {
|
||||||
case ReturnFirmwareHalt:
|
case ReturnFirmwareHalt:
|
||||||
CxbxKrnlCleanup("Emulated Xbox is halted");
|
CxbxKrnlCleanup("Emulated Xbox is halted");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ReturnFirmwareReboot:
|
case ReturnFirmwareReboot:
|
||||||
LOG_UNIMPLEMENTED(); // fall through
|
LOG_UNIMPLEMENTED();
|
||||||
|
[[fallthrough]];
|
||||||
|
|
||||||
case ReturnFirmwareQuickReboot:
|
case ReturnFirmwareQuickReboot:
|
||||||
{
|
{
|
||||||
if (xbox::LaunchDataPage == NULL)
|
if (xbox::LaunchDataPage == NULL)
|
||||||
|
@ -585,6 +589,7 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
||||||
g_EmuShared->GetBootFlags(&QuickReboot);
|
g_EmuShared->GetBootFlags(&QuickReboot);
|
||||||
QuickReboot |= BOOT_QUICK_REBOOT;
|
QuickReboot |= BOOT_QUICK_REBOOT;
|
||||||
g_EmuShared->SetBootFlags(&QuickReboot);
|
g_EmuShared->SetBootFlags(&QuickReboot);
|
||||||
|
is_reboot = true;
|
||||||
|
|
||||||
g_VMManager.SavePersistentMemory();
|
g_VMManager.SavePersistentMemory();
|
||||||
|
|
||||||
|
@ -665,7 +670,7 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
||||||
LOG_UNIMPLEMENTED();
|
LOG_UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuShared::Cleanup();
|
CxbxKrnlShutDown(is_reboot);
|
||||||
TerminateProcess(GetCurrentProcess(), EXIT_SUCCESS);
|
TerminateProcess(GetCurrentProcess(), EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "common/ReserveAddressRanges.h"
|
#include "common/ReserveAddressRanges.h"
|
||||||
#include "common/xbox/Types.hpp"
|
#include "common/xbox/Types.hpp"
|
||||||
#include "common/win32/WineEnv.h"
|
#include "common/win32/WineEnv.h"
|
||||||
|
#include "core/common/video/RenderBase.hpp"
|
||||||
|
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
@ -1753,11 +1754,13 @@ void CxbxKrnlResume()
|
||||||
g_bEmuSuspended = false;
|
g_bEmuSuspended = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CxbxKrnlShutDown()
|
void CxbxKrnlShutDown(bool is_reboot)
|
||||||
{
|
{
|
||||||
// Clear all kernel boot flags. These (together with the shared memory) persist until Cxbx-Reloaded is closed otherwise.
|
if (!is_reboot) {
|
||||||
int BootFlags = 0;
|
// Clear all kernel boot flags. These (together with the shared memory) persist until Cxbx-Reloaded is closed otherwise.
|
||||||
g_EmuShared->SetBootFlags(&BootFlags);
|
int BootFlags = 0;
|
||||||
|
g_EmuShared->SetBootFlags(&BootFlags);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: This causes a hang when exiting while NV2A is processing
|
// NOTE: This causes a hang when exiting while NV2A is processing
|
||||||
// This is okay for now: It won't leak memory or resources since TerminateProcess will free everything
|
// This is okay for now: It won't leak memory or resources since TerminateProcess will free everything
|
||||||
|
@ -1769,9 +1772,14 @@ void CxbxKrnlShutDown()
|
||||||
// Shutdown the memory manager
|
// Shutdown the memory manager
|
||||||
g_VMManager.Shutdown();
|
g_VMManager.Shutdown();
|
||||||
|
|
||||||
|
// Shutdown the render manager
|
||||||
|
g_renderbase->Shutdown();
|
||||||
|
g_renderbase.release();
|
||||||
|
g_renderbase = nullptr;
|
||||||
|
|
||||||
CxbxUnlockFilePath();
|
CxbxUnlockFilePath();
|
||||||
|
|
||||||
if (CxbxKrnl_hEmuParent != NULL) {
|
if (CxbxKrnl_hEmuParent != NULL && !is_reboot) {
|
||||||
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_DESTROY, 0);
|
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_DESTROY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ void CxbxKrnlSuspend();
|
||||||
void CxbxKrnlResume();
|
void CxbxKrnlResume();
|
||||||
|
|
||||||
/*! terminate gracefully the emulation */
|
/*! terminate gracefully the emulation */
|
||||||
void CxbxKrnlShutDown();
|
void CxbxKrnlShutDown(bool is_reboot = false);
|
||||||
|
|
||||||
/*! display the fatal error message*/
|
/*! display the fatal error message*/
|
||||||
void CxbxKrnlPrintUEM(ULONG ErrorCode);
|
void CxbxKrnlPrintUEM(ULONG ErrorCode);
|
||||||
|
|
|
@ -87,8 +87,6 @@ typedef struct DUMMY_KERNEL
|
||||||
IMAGE_SECTION_HEADER SectionHeader;
|
IMAGE_SECTION_HEADER SectionHeader;
|
||||||
} *PDUMMY_KERNEL;
|
} *PDUMMY_KERNEL;
|
||||||
|
|
||||||
typedef WORD INDEX16;
|
|
||||||
|
|
||||||
extern bool g_DisablePixelShaders;
|
extern bool g_DisablePixelShaders;
|
||||||
extern bool g_UseAllCores;
|
extern bool g_UseAllCores;
|
||||||
extern bool g_SkipRdtscPatching;
|
extern bool g_SkipRdtscPatching;
|
||||||
|
|
|
@ -705,6 +705,23 @@ void OpenGL_draw_inline_elements(NV2AState *d)
|
||||||
OpenGL_draw_end(d);
|
OpenGL_draw_end(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CxbxImGui_RenderOpenGL(ImGuiUI* m_imgui, std::nullptr_t unused)
|
||||||
|
{
|
||||||
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
ImGui_ImplWin32_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
m_imgui->DrawMenu();
|
||||||
|
m_imgui->DrawWidgets();
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
|
||||||
|
ImDrawData* drawData = ImGui::GetDrawData();
|
||||||
|
if (drawData->TotalVtxCount > 0) {
|
||||||
|
ImGui_ImplOpenGL3_RenderDrawData(drawData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGL_draw_state_update(NV2AState *d)
|
void OpenGL_draw_state_update(NV2AState *d)
|
||||||
{
|
{
|
||||||
PGRAPHState *pg = &d->pgraph;
|
PGRAPHState *pg = &d->pgraph;
|
||||||
|
@ -893,6 +910,10 @@ void OpenGL_draw_state_update(NV2AState *d)
|
||||||
pg->gl_zpass_pixel_count_query_count - 1] = gl_query;
|
pg->gl_zpass_pixel_count_query_count - 1] = gl_query;
|
||||||
glBeginQuery(GL_SAMPLES_PASSED, gl_query);
|
glBeginQuery(GL_SAMPLES_PASSED, gl_query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render ImGui
|
||||||
|
static std::function<void(ImGuiUI*, std::nullptr_t)> internal_render = &CxbxImGui_RenderOpenGL;
|
||||||
|
g_renderbase->Render(internal_render, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL_draw_end(NV2AState *d)
|
void OpenGL_draw_end(NV2AState *d)
|
||||||
|
@ -2989,6 +3010,13 @@ void pgraph_init(NV2AState *d)
|
||||||
|
|
||||||
glextensions_init();
|
glextensions_init();
|
||||||
|
|
||||||
|
// Set up ImGui's render backend
|
||||||
|
//ImGui_ImplSDL2_InitForOpenGL(window, pg->gl_context);
|
||||||
|
ImGui_ImplOpenGL3_Init();
|
||||||
|
g_renderbase->SetDeviceRelease([] {
|
||||||
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
|
});
|
||||||
|
|
||||||
/* DXT textures */
|
/* DXT textures */
|
||||||
assert(glo_check_extension("GL_EXT_texture_compression_s3tc"));
|
assert(glo_check_extension("GL_EXT_texture_compression_s3tc"));
|
||||||
/* Internal RGB565 texture format */
|
/* Internal RGB565 texture format */
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#define LOG_PREFIX CXBXR_MODULE::NV2A
|
#define LOG_PREFIX CXBXR_MODULE::NV2A
|
||||||
|
|
||||||
|
|
||||||
#include <core/kernel/exports/xboxkrnl.h> // For PKINTERRUPT, etc.
|
#include <core/kernel/exports/xboxkrnl.h> // For PKINTERRUPT, etc.
|
||||||
|
|
||||||
#ifdef _MSC_VER // Check if MS Visual C compiler
|
#ifdef _MSC_VER // Check if MS Visual C compiler
|
||||||
|
@ -53,6 +52,9 @@
|
||||||
#include "core\kernel\init\CxbxKrnl.h" // For XBOX_MEMORY_SIZE, DWORD, etc
|
#include "core\kernel\init\CxbxKrnl.h" // For XBOX_MEMORY_SIZE, DWORD, etc
|
||||||
#include "core\kernel\support\Emu.h"
|
#include "core\kernel\support\Emu.h"
|
||||||
#include "core\kernel\exports\EmuKrnl.h"
|
#include "core\kernel\exports\EmuKrnl.h"
|
||||||
|
#include <backends/imgui_impl_win32.h>
|
||||||
|
#include <backends/imgui_impl_opengl3.h>
|
||||||
|
#include "core/common/video/RenderBase.hpp"
|
||||||
#include "core\hle\Intercept.hpp"
|
#include "core\hle\Intercept.hpp"
|
||||||
#include "common/win32/Threads.h"
|
#include "common/win32/Threads.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
@ -1157,6 +1159,9 @@ NV2ADevice::NV2ADevice()
|
||||||
NV2ADevice::~NV2ADevice()
|
NV2ADevice::~NV2ADevice()
|
||||||
{
|
{
|
||||||
Reset(); // TODO : Review this
|
Reset(); // TODO : Review this
|
||||||
|
|
||||||
|
g_renderbase->DeviceRelease();
|
||||||
|
|
||||||
delete m_nv2a_state;
|
delete m_nv2a_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,7 @@ void SyncInputSettings(int port_num, int dev_type, bool is_opt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g_EmuShared->SetInputMoAxisSettings(g_Settings->m_input_general.MoAxisRange);
|
g_EmuShared->SetInputGeneralSettings(&g_Settings->m_input_general);
|
||||||
g_EmuShared->SetInputMoWheelSettings(g_Settings->m_input_general.MoWheelRange);
|
|
||||||
g_EmuShared->SetInputKbMoUnfocusSettings(g_Settings->m_input_general.IgnoreKbMoUnfocus);
|
|
||||||
port_num = PORT_INVALID;
|
port_num = PORT_INVALID;
|
||||||
}
|
}
|
||||||
#if 0 // lle usb
|
#if 0 // lle usb
|
||||||
|
|
|
@ -360,6 +360,8 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
||||||
DrawLedBitmap(hwnd, true);
|
DrawLedBitmap(hwnd, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
{
|
{
|
||||||
switch (HIWORD(wParam)) {
|
switch (HIWORD(wParam)) {
|
||||||
|
@ -387,6 +389,10 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
||||||
g_EmuShared->SetIsReady(true);
|
g_EmuShared->SetIsReady(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ID_GUI_STATUS_OVERLAY:
|
||||||
|
g_EmuShared->GetOverlaySettings(&g_Settings->m_overlay);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2330,7 +2336,7 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttachLocalDebugger = (LocalDebuggerState == debuggerOn);
|
bool AttachLocalDebugger = (LocalDebuggerState == debuggerOn);
|
||||||
g_EmuShared->SetDebuggingFlag(&AttachLocalDebugger);
|
g_EmuShared->SetDebuggingFlag(AttachLocalDebugger);
|
||||||
|
|
||||||
/* Main process to generate emulation command line begin. */
|
/* Main process to generate emulation command line begin. */
|
||||||
// If we are adding more arguments, this is the place to do so.
|
// If we are adding more arguments, this is the place to do so.
|
||||||
|
|
|
@ -196,6 +196,7 @@
|
||||||
#define ID_GUI_STATUS_LOG_ENABLED 1099
|
#define ID_GUI_STATUS_LOG_ENABLED 1099
|
||||||
#define IDC_AC_MUTE_WHEN_UNFOCUS 1100
|
#define IDC_AC_MUTE_WHEN_UNFOCUS 1100
|
||||||
#define IDC_IGNORE_KBMO_UNFOCUS 1101
|
#define IDC_IGNORE_KBMO_UNFOCUS 1101
|
||||||
|
#define ID_GUI_STATUS_OVERLAY 1102
|
||||||
#define IDC_XBOX_PORT_0 1158
|
#define IDC_XBOX_PORT_0 1158
|
||||||
#define IDC_XBOX_PORT_1 1166
|
#define IDC_XBOX_PORT_1 1166
|
||||||
#define IDC_XBOX_PORT_2 1174
|
#define IDC_XBOX_PORT_2 1174
|
||||||
|
|
Loading…
Reference in New Issue