mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-12-20 20:19:35 -06:00
Compare commits
21 Commits
v1.0.0-bet
...
debug-menu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c357062de8 | ||
|
|
fc51d0e7ae | ||
|
|
f4406cd8d0 | ||
|
|
2af11c8d2f | ||
|
|
dd54867e58 | ||
|
|
4b358d8e43 | ||
|
|
110f341af6 | ||
|
|
00e148b182 | ||
|
|
eb3225c2f7 | ||
|
|
4ab26a1696 | ||
|
|
72a0a17e3a | ||
|
|
35b9361a91 | ||
|
|
7788e36704 | ||
|
|
023fc0edf7 | ||
|
|
d5ca843716 | ||
|
|
dbdf020218 | ||
|
|
d5e947f520 | ||
|
|
a7e004fb60 | ||
|
|
892e24f71e | ||
|
|
72a0507c66 | ||
|
|
2f68ee5df2 |
@@ -154,7 +154,8 @@ set(SWA_PATCHES_CXX_SOURCES
|
||||
"patches/ui/frontend_listener.cpp"
|
||||
"patches/aspect_ratio_patches.cpp"
|
||||
"patches/audio_patches.cpp"
|
||||
"patches/camera_patches.cpp"
|
||||
"patches/camera_patches.cpp"
|
||||
"patches/debug_patches.cpp"
|
||||
"patches/fps_patches.cpp"
|
||||
"patches/inspire_patches.cpp"
|
||||
"patches/misc_patches.cpp"
|
||||
@@ -165,6 +166,15 @@ set(SWA_PATCHES_CXX_SOURCES
|
||||
)
|
||||
|
||||
set(SWA_UI_CXX_SOURCES
|
||||
"ui/reddog/windows/counter_window.cpp"
|
||||
"ui/reddog/windows/exports_window.cpp"
|
||||
"ui/reddog/windows/view_window.cpp"
|
||||
"ui/reddog/windows/welcome_window.cpp"
|
||||
"ui/reddog/windows/window_list.cpp"
|
||||
"ui/reddog/reddog_controls.cpp"
|
||||
"ui/reddog/reddog_manager.cpp"
|
||||
"ui/reddog/reddog_window.cpp"
|
||||
"ui/reddog/debug_draw.cpp"
|
||||
"ui/achievement_menu.cpp"
|
||||
"ui/achievement_overlay.cpp"
|
||||
"ui/installer_wizard.cpp"
|
||||
@@ -196,22 +206,22 @@ set(SWA_INSTALL_CXX_SOURCES
|
||||
set(SWA_USER_CXX_SOURCES
|
||||
"user/achievement_data.cpp"
|
||||
"user/config.cpp"
|
||||
)
|
||||
|
||||
set(SWA_MOD_CXX_SOURCES
|
||||
"mod/mod_loader.cpp"
|
||||
)
|
||||
|
||||
set(SWA_MOD_CXX_SOURCES
|
||||
"mod/mod_loader.cpp"
|
||||
)
|
||||
|
||||
set(SWA_THIRDPARTY_SOURCES
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/backends/imgui_impl_sdl2.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/imgui.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/imgui.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_demo.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_draw.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_tables.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_widgets.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot/implot.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot/implot_demo.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot/implot_items.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot/implot.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot/implot_demo.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot/implot_items.cpp"
|
||||
"${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack/lzxd.c"
|
||||
"${SWA_THIRDPARTY_ROOT}/tiny-AES-c/aes.c"
|
||||
"${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source/smolv.cpp"
|
||||
@@ -220,7 +230,7 @@ set(SWA_THIRDPARTY_SOURCES
|
||||
set(SWA_THIRDPARTY_INCLUDES
|
||||
"${SWA_THIRDPARTY_ROOT}/concurrentqueue"
|
||||
"${SWA_THIRDPARTY_ROOT}/ddspp"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui"
|
||||
"${SWA_THIRDPARTY_ROOT}/imgui"
|
||||
"${SWA_THIRDPARTY_ROOT}/implot"
|
||||
"${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack"
|
||||
"${SWA_THIRDPARTY_ROOT}/magic_enum/include"
|
||||
@@ -247,7 +257,7 @@ set(SWA_CXX_SOURCES
|
||||
"exports.cpp"
|
||||
"main.cpp"
|
||||
"misc_impl.cpp"
|
||||
"stdafx.cpp"
|
||||
"stdafx.cpp"
|
||||
"version.cpp"
|
||||
|
||||
${SWA_KERNEL_CXX_SOURCES}
|
||||
@@ -260,7 +270,7 @@ set(SWA_CXX_SOURCES
|
||||
${SWA_PATCHES_CXX_SOURCES}
|
||||
${SWA_UI_CXX_SOURCES}
|
||||
${SWA_INSTALL_CXX_SOURCES}
|
||||
${SWA_USER_CXX_SOURCES}
|
||||
${SWA_USER_CXX_SOURCES}
|
||||
${SWA_MOD_CXX_SOURCES}
|
||||
${SWA_THIRDPARTY_SOURCES}
|
||||
)
|
||||
@@ -274,7 +284,7 @@ else()
|
||||
add_executable(UnleashedRecomp ${SWA_CXX_SOURCES})
|
||||
endif()
|
||||
|
||||
set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME})
|
||||
set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME})
|
||||
|
||||
if (SWA_FLATPAK)
|
||||
target_compile_definitions(UnleashedRecomp PRIVATE "GAME_INSTALL_DIRECTORY=\"/var/data\"")
|
||||
@@ -380,8 +390,8 @@ function(compile_pixel_shader FILE_PATH)
|
||||
endfunction()
|
||||
|
||||
compile_vertex_shader(copy_vs)
|
||||
compile_pixel_shader(csd_filter_ps)
|
||||
compile_vertex_shader(csd_no_tex_vs)
|
||||
compile_pixel_shader(csd_filter_ps)
|
||||
compile_vertex_shader(csd_no_tex_vs)
|
||||
compile_vertex_shader(csd_vs)
|
||||
compile_pixel_shader(enhanced_motion_blur_ps)
|
||||
compile_pixel_shader(gaussian_blur_3x3)
|
||||
@@ -425,21 +435,21 @@ generate_aggregate_header(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/api"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/api/SWA.h"
|
||||
)
|
||||
|
||||
# Only show build type if not Release.
|
||||
set(IS_BUILD_TYPE_IN_VER_STRING 0)
|
||||
if (NOT ${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||
set(IS_BUILD_TYPE_IN_VER_STRING 1)
|
||||
endif()
|
||||
|
||||
include("version.cmake")
|
||||
GenerateVersionSources(
|
||||
OUTPUT_DIR "${PROJECT_SOURCE_DIR}"
|
||||
VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt"
|
||||
H_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.h.template"
|
||||
CXX_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.cpp.template"
|
||||
BUILD_TYPE ${CMAKE_BUILD_TYPE}
|
||||
IS_BUILD_TYPE_IN_VER_STRING ${IS_BUILD_TYPE_IN_VER_STRING}
|
||||
|
||||
# Only show build type if not Release.
|
||||
set(IS_BUILD_TYPE_IN_VER_STRING 0)
|
||||
if (NOT ${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||
set(IS_BUILD_TYPE_IN_VER_STRING 1)
|
||||
endif()
|
||||
|
||||
include("version.cmake")
|
||||
GenerateVersionSources(
|
||||
OUTPUT_DIR "${PROJECT_SOURCE_DIR}"
|
||||
VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt"
|
||||
H_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.h.template"
|
||||
CXX_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.cpp.template"
|
||||
BUILD_TYPE ${CMAKE_BUILD_TYPE}
|
||||
IS_BUILD_TYPE_IN_VER_STRING ${IS_BUILD_TYPE_IN_VER_STRING}
|
||||
IS_GIT_REPO 1
|
||||
)
|
||||
|
||||
@@ -456,6 +466,24 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/co
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_NAME "g_select_fade" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_NAME "g_select_fill" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_close_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_close_1.dds" ARRAY_NAME "g_button_close_1")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_close_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_close_2.dds" ARRAY_NAME "g_button_close_2")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_minimum_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_minimum_1.dds" ARRAY_NAME "g_button_minimum_1")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_minimum_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_minimum_2.dds" ARRAY_NAME "g_button_minimum_2")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_pin_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_pin_1.dds" ARRAY_NAME "g_button_pin_1")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_pin_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_pin_2.dds" ARRAY_NAME "g_button_pin_2")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/checkbox_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/checkbox_1.dds" ARRAY_NAME "g_checkbox_1")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/checkbox_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/checkbox_2.dds" ARRAY_NAME "g_checkbox_2")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/common_button_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/common_button_1.dds" ARRAY_NAME "g_common_button_1")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/common_button_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/common_button_2.dds" ARRAY_NAME "g_common_button_2")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/common_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/common_icon.dds" ARRAY_NAME "g_common_icon")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/debug_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/debug_icon.dds" ARRAY_NAME "g_debug_icon")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor.bmp" ARRAY_NAME "g_mouse_cursor")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_h.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_h.bmp" ARRAY_NAME "g_mouse_cursor_h")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_slant_l.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_slant_l.bmp" ARRAY_NAME "g_mouse_cursor_slant_l")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_slant_r.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_slant_r.bmp" ARRAY_NAME "g_mouse_cursor_slant_r")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_v.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_v.bmp" ARRAY_NAME "g_mouse_cursor_v")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/title_bar.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/title_bar.dds" ARRAY_NAME "g_title_bar")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_002.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_002.dds" ARRAY_NAME "g_install_002" COMPRESSION_TYPE "zstd")
|
||||
|
||||
19
UnleashedRecomp/api/Hedgehog/Math/Aabb.h
Normal file
19
UnleashedRecomp/api/Hedgehog/Math/Aabb.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace Hedgehog::Math
|
||||
{
|
||||
class CAabb // Eigen::AlignedBox3f
|
||||
{
|
||||
public:
|
||||
Hedgehog::Math::CVector min;
|
||||
Hedgehog::Math::CVector max;
|
||||
|
||||
CVector Center() const;
|
||||
};
|
||||
|
||||
SWA_ASSERT_SIZEOF(CAabb, 0x18);
|
||||
}
|
||||
|
||||
#include "Aabb.inl"
|
||||
12
UnleashedRecomp/api/Hedgehog/Math/Aabb.inl
Normal file
12
UnleashedRecomp/api/Hedgehog/Math/Aabb.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Hedgehog::Math
|
||||
{
|
||||
inline CVector Hedgehog::Math::CAabb::Center() const
|
||||
{
|
||||
// return (min + max) / 2;
|
||||
Hedgehog::Math::CVector result;
|
||||
result.X = (max.X + min.X) * 0.5f;
|
||||
result.Y = (max.Y + min.Y) * 0.5f;
|
||||
result.Z = 0.5f * (max.Z + min.Z);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
21
UnleashedRecomp/api/Hedgehog/Math/Matrix.h
Normal file
21
UnleashedRecomp/api/Hedgehog/Math/Matrix.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace Hedgehog::Math
|
||||
{
|
||||
class CMatrix
|
||||
{
|
||||
public:
|
||||
be<float> data[16]; // Eigen::Affine3f
|
||||
};
|
||||
|
||||
class CMatrix44
|
||||
{
|
||||
public:
|
||||
be<float> data[16]; // Eigen::Matrix4f
|
||||
};
|
||||
|
||||
SWA_ASSERT_SIZEOF(CMatrix, 0x40);
|
||||
SWA_ASSERT_SIZEOF(CMatrix44, 0x40);
|
||||
}
|
||||
17
UnleashedRecomp/api/Hedgehog/Math/Quaternion.h
Normal file
17
UnleashedRecomp/api/Hedgehog/Math/Quaternion.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace Hedgehog::Math
|
||||
{
|
||||
class CQuaternion //Eigen::Quaternionf;
|
||||
{
|
||||
public:
|
||||
be<float> X;
|
||||
be<float> Y;
|
||||
be<float> Z;
|
||||
be<float> W;
|
||||
};
|
||||
|
||||
SWA_ASSERT_SIZEOF(CQuaternion, 0x10);
|
||||
}
|
||||
@@ -28,3 +28,5 @@ namespace Hedgehog::Math
|
||||
be<float> W;
|
||||
};
|
||||
}
|
||||
|
||||
#include "Vector.inl"
|
||||
|
||||
4
UnleashedRecomp/api/Hedgehog/Math/Vector.inl
Normal file
4
UnleashedRecomp/api/Hedgehog/Math/Vector.inl
Normal file
@@ -0,0 +1,4 @@
|
||||
namespace Hedgehog::Math
|
||||
{
|
||||
|
||||
}
|
||||
18
UnleashedRecomp/api/Hedgehog/MirageCore/Camera/hhCamera.h
Normal file
18
UnleashedRecomp/api/Hedgehog/MirageCore/Camera/hhCamera.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace Hedgehog::Mirage
|
||||
{
|
||||
class CCamera : Base::CObject
|
||||
{
|
||||
public:
|
||||
Math::CMatrix m_View;
|
||||
Math::CMatrix44 m_Projection;
|
||||
Math::CVector m_Position;
|
||||
Math::CVector m_Direction;
|
||||
be<float> m_AspectRatio;
|
||||
be<float> m_Near;
|
||||
be<float> m_Far;
|
||||
};
|
||||
}
|
||||
@@ -27,7 +27,11 @@
|
||||
#include "Hedgehog/Base/Type/hhSharedString.h"
|
||||
#include "Hedgehog/Base/hhObject.h"
|
||||
#include "Hedgehog/Database/System/hhDatabaseData.h"
|
||||
#include "Hedgehog/Math/Aabb.h"
|
||||
#include "Hedgehog/Math/Matrix.h"
|
||||
#include "Hedgehog/Math/Quaternion.h"
|
||||
#include "Hedgehog/Math/Vector.h"
|
||||
#include "Hedgehog/MirageCore/Camera/hhCamera.h"
|
||||
#include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h"
|
||||
#include "Hedgehog/MirageCore/RenderData/hhMaterialData.h"
|
||||
#include "Hedgehog/MirageCore/RenderData/hhMeshData.h"
|
||||
@@ -57,6 +61,7 @@
|
||||
#include "SWA/CSD/CsdTexListMirage.h"
|
||||
#include "SWA/CSD/GameObjectCSD.h"
|
||||
#include "SWA/Camera/Camera.h"
|
||||
#include "SWA/Globals.h"
|
||||
#include "SWA/HUD/GeneralWindow/GeneralWindow.h"
|
||||
#include "SWA/HUD/Loading/Loading.h"
|
||||
#include "SWA/HUD/Pause/HudPause.h"
|
||||
@@ -73,6 +78,8 @@
|
||||
#include "SWA/Inspire/InspireTextureOverlayInfo.h"
|
||||
#include "SWA/Movie/MovieDisplayer.h"
|
||||
#include "SWA/Movie/MovieManager.h"
|
||||
#include "SWA/Path/PathController.h"
|
||||
#include "SWA/Path/Animation/PathAnimation.h"
|
||||
#include "SWA/Player/Character/EvilSonic/EvilSonic.h"
|
||||
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
|
||||
#include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h"
|
||||
@@ -98,6 +105,7 @@
|
||||
#include "SWA/System/GammaController.h"
|
||||
#include "SWA/System/InputState.h"
|
||||
#include "SWA/System/PadState.h"
|
||||
#include "SWA/System/StageManager.h"
|
||||
#include "SWA/System/World.h"
|
||||
#include "boost/smart_ptr/make_shared_object.h"
|
||||
#include "boost/smart_ptr/shared_ptr.h"
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace SWA
|
||||
{
|
||||
public:
|
||||
xpointer<void> m_pVftable;
|
||||
SWA_INSERT_PADDING(0xC4);
|
||||
// SWA::CCamera::MyCamera
|
||||
SWA_INSERT_PADDING(0xC4);
|
||||
be<float> m_VertAspectRatio;
|
||||
SWA_INSERT_PADDING(0x48);
|
||||
be<float> m_HorzAspectRatio;
|
||||
|
||||
69
UnleashedRecomp/api/SWA/Globals.h
Normal file
69
UnleashedRecomp/api/SWA/Globals.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace SWA
|
||||
{
|
||||
struct SGlobals
|
||||
{
|
||||
// ms_DrawLightFieldSamplingPoint: サンプリング点をデバッグ表示
|
||||
static inline bool* ms_DrawLightFieldSamplingPoint;
|
||||
|
||||
// ms_IgnoreLightFieldData: データを無視する
|
||||
static inline bool* ms_IgnoreLightFieldData;
|
||||
|
||||
// IsCollisionRender
|
||||
static inline bool* ms_IsCollisionRender;
|
||||
|
||||
// N/A
|
||||
static inline bool* ms_IsLoading;
|
||||
|
||||
// IsObjectCollisionRender
|
||||
static inline bool* ms_IsObjectCollisionRender;
|
||||
|
||||
// ms_IsRenderDebugDraw: デバッグ描画
|
||||
static inline bool* ms_IsRenderDebugDraw;
|
||||
|
||||
// ms_IsRenderDebugDrawText: デバッグ文字描画
|
||||
static inline bool* ms_IsRenderDebugDrawText;
|
||||
|
||||
// ms_IsRenderDebugPositionDraw: デバッグ位置描画
|
||||
static inline bool* ms_IsRenderDebugPositionDraw;
|
||||
|
||||
// ms_IsRenderGameMainHud: ゲームメインHUD 描画
|
||||
static inline bool* ms_IsRenderGameMainHud;
|
||||
|
||||
// ms_IsRenderHud: 全 HUD 描画
|
||||
static inline bool* ms_IsRenderHud;
|
||||
|
||||
// ms_IsRenderHudPause: ポーズメニュー 描画
|
||||
static inline bool* ms_IsRenderHudPause;
|
||||
|
||||
// IsTriggerRender
|
||||
static inline bool* ms_IsTriggerRender;
|
||||
|
||||
// ms_LightFieldDebug: 値をデバッグ表示
|
||||
static inline bool* ms_LightFieldDebug;
|
||||
|
||||
// VisualizeLoadedLevel: ミップレベルを視覚化 赤=0, 緑=1, 青=2, 黄=未ロード
|
||||
static inline bool* ms_VisualizeLoadedLevel;
|
||||
|
||||
static void Init()
|
||||
{
|
||||
ms_DrawLightFieldSamplingPoint = (bool*)MmGetHostAddress(0x83367BCE);
|
||||
ms_IgnoreLightFieldData = (bool*)MmGetHostAddress(0x83367BCF);
|
||||
ms_IsCollisionRender = (bool*)MmGetHostAddress(0x833678A6);
|
||||
ms_IsLoading = (bool*)MmGetHostAddress(0x83367A4C);
|
||||
ms_IsObjectCollisionRender = (bool*)MmGetHostAddress(0x83367905);
|
||||
ms_IsRenderDebugDraw = (bool*)MmGetHostAddress(0x8328BB23);
|
||||
ms_IsRenderDebugDrawText = (bool*)MmGetHostAddress(0x8328BB25);
|
||||
ms_IsRenderDebugPositionDraw = (bool*)MmGetHostAddress(0x8328BB24);
|
||||
ms_IsRenderGameMainHud = (bool*)MmGetHostAddress(0x8328BB27);
|
||||
ms_IsRenderHud = (bool*)MmGetHostAddress(0x8328BB26);
|
||||
ms_IsRenderHudPause = (bool*)MmGetHostAddress(0x8328BB28);
|
||||
ms_IsTriggerRender = (bool*)MmGetHostAddress(0x83367904);
|
||||
ms_LightFieldDebug = (bool*)MmGetHostAddress(0x83367BCD);
|
||||
ms_VisualizeLoadedLevel = (bool*)MmGetHostAddress(0x833678C1);
|
||||
}
|
||||
};
|
||||
}
|
||||
22
UnleashedRecomp/api/SWA/Path/Animation/PathAnimation.h
Normal file
22
UnleashedRecomp/api/SWA/Path/Animation/PathAnimation.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace SWA::PathAnimation
|
||||
{
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
xpointer<void> m_pVftable;
|
||||
SWA_INSERT_PADDING(0x18);
|
||||
};
|
||||
|
||||
|
||||
class Controller
|
||||
{
|
||||
public:
|
||||
xpointer<void> m_pVftable;
|
||||
SWA_INSERT_PADDING(0x1C);
|
||||
be<float> m_DistanceAlongPath;
|
||||
};
|
||||
SWA_ASSERT_OFFSETOF(Controller, m_DistanceAlongPath, 0x20);
|
||||
}
|
||||
13
UnleashedRecomp/api/SWA/Path/PathController.h
Normal file
13
UnleashedRecomp/api/SWA/Path/PathController.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "Animation/PathAnimation.h"
|
||||
|
||||
namespace SWA
|
||||
{
|
||||
class CPathController
|
||||
{
|
||||
public:
|
||||
be<uint32_t> m_Field000;
|
||||
be<uint32_t> m_Field004;
|
||||
boost::shared_ptr<PathAnimation::Controller> m_spPathAnimationController;
|
||||
};
|
||||
}
|
||||
@@ -29,7 +29,8 @@ namespace SWA
|
||||
SWA_INSERT_PADDING(0x10);
|
||||
};
|
||||
|
||||
SWA_INSERT_PADDING(0x1C);
|
||||
SWA_INSERT_PADDING(0x10);
|
||||
hh::map<Hedgehog::Base::CSharedString, boost::shared_ptr<SWA::CWorld>> m_Worlds;
|
||||
boost::shared_ptr<Hedgehog::Database::CDatabase> m_spDatabase;
|
||||
SWA_INSERT_PADDING(0x88);
|
||||
Hedgehog::Base::CSharedString m_StageName;
|
||||
|
||||
30
UnleashedRecomp/api/SWA/System/StageManager.h
Normal file
30
UnleashedRecomp/api/SWA/System/StageManager.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "SWA.inl"
|
||||
#include "Hedgehog/Base/Thread/hhSynchronizedObject.h"
|
||||
#include "Hedgehog/Universe/Engine/hhMessageActor.h"
|
||||
#include "SWA/System/GameObject.h"
|
||||
|
||||
|
||||
namespace SWA
|
||||
{
|
||||
class CStageManager //: public SWA::CGameObject, public Hedgehog::Base::CSynchronizedObject
|
||||
{
|
||||
public:
|
||||
SWA_INSERT_PADDING(0xC4);
|
||||
boost::shared_ptr<SWA::CPathController> m_spStageGuidePathController; //xpointer<SWA::CPathController> m_pStageGuidePathController;
|
||||
SWA_INSERT_PADDING(0x4);
|
||||
Hedgehog::Math::CVector m_PlayerPosition;
|
||||
be<float> m_Field0DC; // Sonic's air distance from path??
|
||||
SWA_INSERT_PADDING(0x3C);
|
||||
be<float> m_StageGuidePathRatio; // Not updated in retail
|
||||
be<float> m_StageGuidePathLength;
|
||||
SWA_INSERT_PADDING(0x9C);
|
||||
};
|
||||
|
||||
SWA_ASSERT_OFFSETOF(CStageManager, m_spStageGuidePathController, 0xC4);
|
||||
SWA_ASSERT_OFFSETOF(CStageManager, m_PlayerPosition, 0xD0);
|
||||
SWA_ASSERT_OFFSETOF(CStageManager, m_StageGuidePathRatio, 0x11C);
|
||||
SWA_ASSERT_OFFSETOF(CStageManager, m_StageGuidePathLength, 0x120);
|
||||
SWA_ASSERT_SIZEOF(CStageManager, 0x1C0);
|
||||
}
|
||||
@@ -12,9 +12,21 @@ namespace SWA
|
||||
class CMember
|
||||
{
|
||||
public:
|
||||
SWA_INSERT_PADDING(0x80);
|
||||
//boost::shared_ptr<Hedgehog::Mirage::CRenderScene> m_spRenderScene;
|
||||
//Hedgehog::Base::CSharedString m_Name;
|
||||
SWA_INSERT_PADDING(0xC);
|
||||
boost::shared_ptr<CCamera> m_spCamera;
|
||||
boost::shared_ptr<CCamera> m_spOverrideCamera;
|
||||
SWA_INSERT_PADDING(0x64);
|
||||
};
|
||||
|
||||
xpointer<CMember> m_pMember;
|
||||
|
||||
boost::shared_ptr<CCamera> GetCamera() const;
|
||||
};
|
||||
|
||||
//SWA_ASSERT_OFFSETOF(CWorld::CMember, m_spCamera, 0xC);
|
||||
//SWA_ASSERT_SIZEOF(CWorld::CMember, 0x80);
|
||||
}
|
||||
|
||||
#include "World.inl"
|
||||
|
||||
7
UnleashedRecomp/api/SWA/System/World.inl
Normal file
7
UnleashedRecomp/api/SWA/System/World.inl
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace SWA
|
||||
{
|
||||
inline boost::shared_ptr<CCamera> CWorld::GetCamera() const
|
||||
{
|
||||
return m_pMember->m_spOverrideCamera ? m_pMember->m_spOverrideCamera : m_pMember->m_spCamera;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <app.h>
|
||||
#include <api/SWA.h>
|
||||
#include <gpu/video.h>
|
||||
#include <install/installer.h>
|
||||
#include <kernel/function.h>
|
||||
@@ -33,6 +34,8 @@ PPC_FUNC(sub_824EB490)
|
||||
App::s_isMissingDLC = !Installer::checkAllDLC(GetGamePath());
|
||||
App::s_language = Config::Language;
|
||||
|
||||
SWA::SGlobals::Init();
|
||||
|
||||
__imp__sub_824EB490(ctx, base);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <res/font/im_font_atlas.dds.h>
|
||||
#include <shader/shader_cache.h>
|
||||
#include <SWA.h>
|
||||
#include <ui/reddog/reddog_manager.h>
|
||||
#include <ui/achievement_menu.h>
|
||||
#include <ui/achievement_overlay.h>
|
||||
#include <ui/button_guide.h>
|
||||
@@ -26,6 +27,7 @@
|
||||
#include <ui/options_menu.h>
|
||||
#include <ui/sdl_listener.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <ui/imgui_utils.h>
|
||||
#include <patches/aspect_ratio_patches.h>
|
||||
#include <user/config.h>
|
||||
#include <xxHashMap.h>
|
||||
@@ -1192,9 +1194,16 @@ static void CreateImGuiBackend()
|
||||
AchievementMenu::Init();
|
||||
AchievementOverlay::Init();
|
||||
ButtonGuide::Init();
|
||||
InstallerWizard::Init();
|
||||
MessageWindow::Init();
|
||||
OptionsMenu::Init();
|
||||
InstallerWizard::Init();
|
||||
|
||||
#if !_DEBUG
|
||||
if (Config::Debug)
|
||||
#endif
|
||||
{
|
||||
Reddog::Manager::Init();
|
||||
}
|
||||
|
||||
ImGui_ImplSDL2_InitForOther(GameWindow::s_pWindow);
|
||||
|
||||
@@ -1965,82 +1974,77 @@ static double g_applicationValues[PROFILER_VALUE_COUNT];
|
||||
static Profiler g_presentProfiler;
|
||||
static Profiler g_renderDirectorProfiler;
|
||||
|
||||
static bool g_profilerVisible;
|
||||
static bool g_profilerWasToggled;
|
||||
|
||||
static void DrawProfiler()
|
||||
void Video::DrawCounter()
|
||||
{
|
||||
bool toggleProfiler = SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_F1] != 0;
|
||||
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
||||
|
||||
if (!g_profilerWasToggled && toggleProfiler)
|
||||
g_profilerVisible = !g_profilerVisible;
|
||||
const double applicationAvg = std::accumulate(g_applicationValues, g_applicationValues + PROFILER_VALUE_COUNT, 0.0) / PROFILER_VALUE_COUNT;
|
||||
double presentAvg = g_presentProfiler.UpdateAndReturnAverage();
|
||||
double renderDirectorAvg = g_renderDirectorProfiler.UpdateAndReturnAverage();
|
||||
|
||||
g_profilerWasToggled = toggleProfiler;
|
||||
if (ImPlot::BeginPlot("Frame Time"))
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_Y1, 0.0, 20.0);
|
||||
ImPlot::SetupAxis(ImAxis_Y1, "ms", ImPlotAxisFlags_None);
|
||||
ImPlot::PlotLine<double>("Application", g_applicationValues, PROFILER_VALUE_COUNT, 1.0, 0.0, ImPlotLineFlags_None, g_profilerValueIndex);
|
||||
ImPlot::PlotLine<double>("Present", g_presentProfiler.values, PROFILER_VALUE_COUNT, 1.0, 0.0, ImPlotLineFlags_None, g_profilerValueIndex);
|
||||
ImPlot::PlotLine<double>("Render Director", g_renderDirectorProfiler.values, PROFILER_VALUE_COUNT, 1.0, 0.0, ImPlotLineFlags_None, g_profilerValueIndex);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
|
||||
if (!g_profilerVisible)
|
||||
g_profilerValueIndex = (g_profilerValueIndex + 1) % PROFILER_VALUE_COUNT;
|
||||
|
||||
ImGui::Text("Current Application: %g ms (%g FPS)", App::s_deltaTime * 1000.0, 1.0 / App::s_deltaTime);
|
||||
ImGui::Text("Current Present: %g ms (%g FPS)", g_presentProfiler.value.load(), 1000.0 / g_presentProfiler.value.load());
|
||||
ImGui::Text("Current Render Director: %g ms (%g FPS)", g_renderDirectorProfiler.value.load(), 1000.0 / g_renderDirectorProfiler.value.load());
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Text("Average Application: %g ms (%g FPS)", applicationAvg, 1000.0 / applicationAvg);
|
||||
ImGui::Text("Average Present: %g ms (%g FPS)", presentAvg, 1000.0 / presentAvg);
|
||||
ImGui::Text("Average Render Director: %g ms (%g FPS)", renderDirectorAvg, 1000.0 / renderDirectorAvg);
|
||||
ImGui::NewLine();
|
||||
|
||||
O1HeapDiagnostics diagnostics, physicalDiagnostics;
|
||||
{
|
||||
std::lock_guard lock(g_userHeap.mutex);
|
||||
diagnostics = o1heapGetDiagnostics(g_userHeap.heap);
|
||||
}
|
||||
{
|
||||
std::lock_guard lock(g_userHeap.physicalMutex);
|
||||
physicalDiagnostics = o1heapGetDiagnostics(g_userHeap.physicalHeap);
|
||||
}
|
||||
|
||||
ImGui::Text("Heap Allocated: %d MB", int32_t(diagnostics.allocated / (1024 * 1024)));
|
||||
ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
|
||||
ImGui::NewLine();
|
||||
|
||||
auto capabilities = g_device->getCapabilities();
|
||||
ImGui::Text("Present Wait: %s", capabilities.presentWait ? "Supported" : "Unsupported");
|
||||
ImGui::Text("Triangle Fan: %s", capabilities.triangleFan ? "Supported" : "Unsupported");
|
||||
ImGui::NewLine();
|
||||
|
||||
const char* sdlVideoDriver = SDL_GetCurrentVideoDriver();
|
||||
if (sdlVideoDriver != nullptr)
|
||||
ImGui::Text("SDL Video Driver: %s", sdlVideoDriver);
|
||||
}
|
||||
|
||||
void Video::DrawFPS(ImFont* font)
|
||||
{
|
||||
if (!Config::ShowFPS)
|
||||
return;
|
||||
|
||||
ImFont* font = ImFontAtlasSnapshot::GetFont("FOT-SeuratPro-M.otf");
|
||||
float defaultScale = font->Scale;
|
||||
font->Scale = ImGui::GetDefaultFont()->FontSize / font->FontSize;
|
||||
ImGui::PushFont(font);
|
||||
auto drawList = ImGui::GetBackgroundDrawList();
|
||||
|
||||
if (ImGui::Begin("Profiler", &g_profilerVisible))
|
||||
{
|
||||
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
||||
auto fmt = fmt::format("FPS: {:.2f}", 1000.0 / g_presentProfiler.value.load());
|
||||
auto fontSize = Scale(12.0f);
|
||||
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, fmt.c_str());
|
||||
|
||||
const double applicationAvg = std::accumulate(g_applicationValues, g_applicationValues + PROFILER_VALUE_COUNT, 0.0) / PROFILER_VALUE_COUNT;
|
||||
double presentAvg = g_presentProfiler.UpdateAndReturnAverage();
|
||||
double renderDirectorAvg = g_renderDirectorProfiler.UpdateAndReturnAverage();
|
||||
ImVec2 min = { Scale(40), Scale(30) };
|
||||
ImVec2 max = { min.x + std::max(Scale(75), textSize.x + Scale(10)), min.y + Scale(15) };
|
||||
ImVec2 textPos = { min.x + Scale(2), CENTRE_TEXT_VERT(min, max, textSize) - Scale(0.5f) };
|
||||
|
||||
if (ImPlot::BeginPlot("Frame Time"))
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_Y1, 0.0, 20.0);
|
||||
ImPlot::SetupAxis(ImAxis_Y1, "ms", ImPlotAxisFlags_None);
|
||||
ImPlot::PlotLine<double>("Application", g_applicationValues, PROFILER_VALUE_COUNT, 1.0, 0.0, ImPlotLineFlags_None, g_profilerValueIndex);
|
||||
ImPlot::PlotLine<double>("Present", g_presentProfiler.values, PROFILER_VALUE_COUNT, 1.0, 0.0, ImPlotLineFlags_None, g_profilerValueIndex);
|
||||
ImPlot::PlotLine<double>("Render Director", g_renderDirectorProfiler.values, PROFILER_VALUE_COUNT, 1.0, 0.0, ImPlotLineFlags_None, g_profilerValueIndex);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
|
||||
g_profilerValueIndex = (g_profilerValueIndex + 1) % PROFILER_VALUE_COUNT;
|
||||
|
||||
ImGui::Text("Current Application: %g ms (%g FPS)", App::s_deltaTime * 1000.0, 1.0 / App::s_deltaTime);
|
||||
ImGui::Text("Current Present: %g ms (%g FPS)", g_presentProfiler.value.load(), 1000.0 / g_presentProfiler.value.load());
|
||||
ImGui::Text("Current Render Director: %g ms (%g FPS)", g_renderDirectorProfiler.value.load(), 1000.0 / g_renderDirectorProfiler.value.load());
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Text("Average Application: %g ms (%g FPS)", applicationAvg, 1000.0 / applicationAvg);
|
||||
ImGui::Text("Average Present: %g ms (%g FPS)", presentAvg, 1000.0 / presentAvg);
|
||||
ImGui::Text("Average Render Director: %g ms (%g FPS)", renderDirectorAvg, 1000.0 / renderDirectorAvg);
|
||||
ImGui::NewLine();
|
||||
|
||||
O1HeapDiagnostics diagnostics, physicalDiagnostics;
|
||||
{
|
||||
std::lock_guard lock(g_userHeap.mutex);
|
||||
diagnostics = o1heapGetDiagnostics(g_userHeap.heap);
|
||||
}
|
||||
{
|
||||
std::lock_guard lock(g_userHeap.physicalMutex);
|
||||
physicalDiagnostics = o1heapGetDiagnostics(g_userHeap.physicalHeap);
|
||||
}
|
||||
|
||||
ImGui::Text("Heap Allocated: %d MB", int32_t(diagnostics.allocated / (1024 * 1024)));
|
||||
ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");
|
||||
ImGui::Text("Triangle Fan: %s", g_capabilities.triangleFan ? "Supported" : "Unsupported");
|
||||
ImGui::NewLine();
|
||||
|
||||
const char* sdlVideoDriver = SDL_GetCurrentVideoDriver();
|
||||
if (sdlVideoDriver != nullptr)
|
||||
ImGui::Text("SDL Video Driver: %s", sdlVideoDriver);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
ImGui::PopFont();
|
||||
font->Scale = defaultScale;
|
||||
drawList->AddRectFilled(min, max, IM_COL32(0, 0, 0, 255));
|
||||
drawList->AddText(font, fontSize, textPos, IM_COL32_WHITE, fmt.c_str());
|
||||
}
|
||||
|
||||
static void DrawImGui()
|
||||
@@ -2076,7 +2080,12 @@ static void DrawImGui()
|
||||
ButtonGuide::Draw();
|
||||
Fader::Draw();
|
||||
|
||||
DrawProfiler();
|
||||
#if !_DEBUG
|
||||
if (Config::Debug)
|
||||
#endif
|
||||
{
|
||||
Reddog::Manager::Draw();
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
@@ -3395,7 +3404,7 @@ static RenderPipeline* CreateGraphicsPipelineInRenderThread(PipelineState pipeli
|
||||
pipeline = CreateGraphicsPipeline(pipelineState);
|
||||
|
||||
#ifdef ASYNC_PSO_DEBUG
|
||||
bool loading = *reinterpret_cast<bool*>(g_memory.Translate(0x83367A4C));
|
||||
bool loading = *SWA::SGlobals::ms_IsLoading;
|
||||
|
||||
if (loading)
|
||||
++g_pipelinesCreatedAsynchronously;
|
||||
|
||||
@@ -23,6 +23,8 @@ struct Video
|
||||
static void Present();
|
||||
static void StartPipelinePrecompilation();
|
||||
static void WaitForGPU();
|
||||
static void DrawCounter();
|
||||
static void DrawFPS(ImFont* font);
|
||||
static struct GuestSurface* GetBackBuffer();
|
||||
static void ComputeViewportDimensions();
|
||||
};
|
||||
|
||||
97
UnleashedRecomp/patches/debug_patches.cpp
Normal file
97
UnleashedRecomp/patches/debug_patches.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <api/SWA.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <user/config.h>
|
||||
#include <ui/reddog/debug_draw.h>
|
||||
#include <ui/imgui_utils.h>
|
||||
#include <patches/aspect_ratio_patches.h>
|
||||
|
||||
|
||||
// boost::~::SWA::CDebugDraw::CMember::SDrawLine
|
||||
PPC_FUNC_IMPL(__imp__sub_822C9398);
|
||||
PPC_FUNC(sub_822C9398)
|
||||
{
|
||||
auto a2 = (Hedgehog::Math::CVector*)g_memory.Translate(ctx.r4.u32);
|
||||
auto a3 = (Hedgehog::Math::CVector*)g_memory.Translate(ctx.r5.u32);
|
||||
auto a4 = (be<unsigned int>*)g_memory.Translate(ctx.r6.u32);
|
||||
|
||||
Reddog::Vector3 start(a2->X, a2->Y, a2->Z);
|
||||
Reddog::Vector3 end(a3->X, a3->Y, a3->Z);
|
||||
|
||||
const Reddog::SDrawLine line{
|
||||
start, end, a4->value
|
||||
};
|
||||
|
||||
Reddog::DebugDraw::DrawLine(line);
|
||||
|
||||
__imp__sub_822C9398(ctx, base);
|
||||
}
|
||||
|
||||
|
||||
// SWA::CStageManager::UpdateParallel
|
||||
//PPC_FUNC_IMPL(__imp__sub_82521C68);
|
||||
//PPC_FUNC(sub_82521C68)
|
||||
//{
|
||||
// __imp__sub_82521C68(ctx, base);
|
||||
//}
|
||||
|
||||
|
||||
// SWA::CStageManager::UpdateSerial
|
||||
PPC_FUNC_IMPL(__imp__sub_82522040);
|
||||
PPC_FUNC(sub_82522040)
|
||||
{
|
||||
auto a1 = static_cast<SWA::CStageManager*>(g_memory.Translate(ctx.r3.u32));
|
||||
|
||||
__imp__sub_82522040(ctx, base);
|
||||
|
||||
// Draw player position
|
||||
if (Reddog::DebugDraw::GetIsDrawPosition())
|
||||
{
|
||||
// TODO (RadiantDerg): Reimplement SWA::CStageManager ability to draw progress ratio
|
||||
// NOTE: Currently does not work, is the API mapping horribly misaligned/misunderstood?
|
||||
if (a1->m_spStageGuidePathController)
|
||||
{
|
||||
if (a1->m_spStageGuidePathController->m_spPathAnimationController)
|
||||
{
|
||||
auto PAC = a1->m_spStageGuidePathController->m_spPathAnimationController;
|
||||
//Reddog::DebugDraw::DrawTextLog(fmt::format("m_DistanceAlongPath = {:.2f}", PAC->m_DistanceAlongPath.get()).c_str());
|
||||
}
|
||||
|
||||
// Ratio
|
||||
if (a1->m_StageGuidePathLength.get() > 0.0f)
|
||||
{
|
||||
//float distance = 0; // GetDistanceAlongPath(a1->m_StageGuidePathController)
|
||||
//a1->m_StageGuidePathRatio = distance / a1->m_StageGuidePathLength;
|
||||
|
||||
const Reddog::SDrawText ratioText{
|
||||
{Scale(g_aspectRatioOffsetX + 720), Scale(g_aspectRatioOffsetY + 36)},
|
||||
fmt::format("{:.1f}m [{:.1f}/100.0]", a1->m_StageGuidePathLength.get(), a1->m_StageGuidePathRatio.get()),
|
||||
0,
|
||||
3.25f,
|
||||
0xFFFFFFFF,
|
||||
Reddog::eDrawTextFlags_NoShadow
|
||||
};
|
||||
|
||||
Reddog::DebugDraw::DrawText2D(ratioText);
|
||||
}
|
||||
}
|
||||
|
||||
// Position
|
||||
const Reddog::SDrawText positionText{
|
||||
{Scale(g_aspectRatioOffsetX + 750), Scale(g_aspectRatioOffsetY + 120)},
|
||||
fmt::format("( {:.2f}, {:.2f}, {:.2f} )", a1->m_PlayerPosition.X.get(), a1->m_PlayerPosition.Y.get(), a1->m_PlayerPosition.Z.get()),
|
||||
0,
|
||||
2.0f,
|
||||
0xFFFFFFFF,
|
||||
Reddog::eDrawTextFlags_NoShadow
|
||||
};
|
||||
|
||||
Reddog::DebugDraw::DrawText2D(positionText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// GetIsDebugRenderForGameObject()
|
||||
//PPC_FUNC(sub_82512BF8)
|
||||
//{
|
||||
// ctx.r3.u8 = 1; // Always return true
|
||||
//}
|
||||
@@ -94,8 +94,7 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31)
|
||||
g_ppcContext->f1.f64 = deltaTime;
|
||||
g_memory.FindFunction(update)(*g_ppcContext, base);
|
||||
|
||||
bool loading = PPC_LOAD_U8(0x83367A4C);
|
||||
if (loading)
|
||||
if (*SWA::SGlobals::ms_IsLoading)
|
||||
{
|
||||
now = std::chrono::steady_clock::now();
|
||||
constexpr auto INTERVAL = 1000000000ns / 30;
|
||||
@@ -104,7 +103,7 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31)
|
||||
std::this_thread::sleep_until(next);
|
||||
}
|
||||
|
||||
return loading;
|
||||
return *SWA::SGlobals::ms_IsLoading;
|
||||
}
|
||||
|
||||
// ADXM_WaitVsync
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <api/SWA.h>
|
||||
#include <ui/reddog/debug_draw.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <user/achievement_data.h>
|
||||
#include <user/config.h>
|
||||
|
||||
@@ -159,9 +159,7 @@ PPC_FUNC(sub_824B0930)
|
||||
{
|
||||
g_achievementMenuIntroTime = 0;
|
||||
|
||||
const auto ms_IsRenderHud = (bool*)g_memory.Translate(0x8328BB26);
|
||||
|
||||
if (*ms_IsRenderHud && pHudPause->m_IsShown && pHudPause->m_Transition == SWA::eTransitionType_Undefined)
|
||||
if (*SWA::SGlobals::ms_IsRenderHud && pHudPause->m_IsShown && pHudPause->m_Transition == SWA::eTransitionType_Undefined)
|
||||
{
|
||||
ButtonGuide::Open(Button(Localise("Achievements_Name"), EButtonIcon::Back, EButtonAlignment::Left, EFontQuality::Low));
|
||||
g_isClosed = false;
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
#include "frontend_listener.h"
|
||||
#include <api/SWA.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <os/logger.h>
|
||||
#include <ui/options_menu.h>
|
||||
|
||||
FrontendListener m_frontendListener;
|
||||
FrontendListener g_frontendListener;
|
||||
|
||||
void FrontendListener::OnSDLEvent(SDL_Event* event)
|
||||
{
|
||||
if (OptionsMenu::s_isVisible)
|
||||
return;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
if (event->key.keysym.sym != SDLK_F8 || m_isF8KeyDown)
|
||||
break;
|
||||
|
||||
*SWA::SGlobals::ms_IsRenderHud = !*SWA::SGlobals::ms_IsRenderHud;
|
||||
|
||||
LOGFN("HUD {}", *SWA::SGlobals::ms_IsRenderHud ? "ON" : "OFF");
|
||||
|
||||
m_isF8KeyDown = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYUP:
|
||||
m_isF8KeyDown = event->key.keysym.sym != SDLK_F8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/memory.h>
|
||||
#include <ui/sdl_listener.h>
|
||||
#include <ui/options_menu.h>
|
||||
#include <os/logger.h>
|
||||
|
||||
class FrontendListener : public SDLEventListener
|
||||
{
|
||||
bool m_isF8KeyDown = false;
|
||||
|
||||
public:
|
||||
void OnSDLEvent(SDL_Event* event) override
|
||||
{
|
||||
if (OptionsMenu::s_isVisible)
|
||||
return;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
if (event->key.keysym.sym != SDLK_F8 || m_isF8KeyDown)
|
||||
break;
|
||||
|
||||
// アプリケーション設定 / 開発用 / デバッグ / HUD / 全 HUD 描画
|
||||
const auto ms_IsRenderHud = (bool*)g_memory.Translate(0x8328BB26);
|
||||
|
||||
*ms_IsRenderHud = !*ms_IsRenderHud;
|
||||
|
||||
LOGFN("HUD {}", *ms_IsRenderHud ? "ON" : "OFF");
|
||||
|
||||
m_isF8KeyDown = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYUP:
|
||||
m_isF8KeyDown = event->key.keysym.sym != SDLK_F8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void OnSDLEvent(SDL_Event* event) override;
|
||||
};
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
#pragma comment(lib, "dwmapi.lib")
|
||||
#endif
|
||||
|
||||
#include <res/images/reddog/mouse_cursor.bmp.h>
|
||||
#include <res/images/reddog/mouse_cursor_h.bmp.h>
|
||||
#include <res/images/reddog/mouse_cursor_slant_l.bmp.h>
|
||||
#include <res/images/reddog/mouse_cursor_slant_r.bmp.h>
|
||||
#include <res/images/reddog/mouse_cursor_v.bmp.h>
|
||||
#include <res/images/game_icon.bmp.h>
|
||||
#include <res/images/game_icon_night.bmp.h>
|
||||
|
||||
@@ -105,7 +110,7 @@ int Window_OnSDLEvent(void*, SDL_Event* event)
|
||||
GameWindow::s_isFocused = true;
|
||||
|
||||
if (GameWindow::IsFullscreen())
|
||||
SDL_ShowCursor(GameWindow::s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
SDL_ShowCursor(GameWindow::s_isCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -146,7 +151,7 @@ int Window_OnSDLEvent(void*, SDL_Event* event)
|
||||
if (event->type == SDL_CONTROLLERBUTTONDOWN || event->type == SDL_CONTROLLERBUTTONUP || event->type == SDL_CONTROLLERAXISMOTION)
|
||||
{
|
||||
// Hide mouse cursor when controller input is detected.
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_ShowCursor(GameWindow::s_isCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
else if (event->type == SDL_MOUSEMOTION)
|
||||
{
|
||||
@@ -264,23 +269,23 @@ void GameWindow::Update()
|
||||
s_isChangingDisplay = false;
|
||||
}
|
||||
|
||||
SDL_Surface* GameWindow::GetIconSurface(void* pIconBmp, size_t iconSize)
|
||||
SDL_Surface* GameWindow::CreateSurface(void* pBitmapData, size_t bitmapSize)
|
||||
{
|
||||
auto rw = SDL_RWFromMem(pIconBmp, iconSize);
|
||||
auto rw = SDL_RWFromMem(pBitmapData, bitmapSize);
|
||||
auto surface = SDL_LoadBMP_RW(rw, 1);
|
||||
|
||||
if (!surface)
|
||||
LOGF_ERROR("Failed to load icon: {}", SDL_GetError());
|
||||
LOGF_ERROR("Failed to create surface: {}", SDL_GetError());
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
void GameWindow::SetIcon(void* pIconBmp, size_t iconSize)
|
||||
{
|
||||
if (auto icon = GetIconSurface(pIconBmp, iconSize))
|
||||
if (auto surface = CreateSurface(pIconBmp, iconSize))
|
||||
{
|
||||
SDL_SetWindowIcon(s_pWindow, icon);
|
||||
SDL_FreeSurface(icon);
|
||||
SDL_SetWindowIcon(s_pWindow, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,6 +301,69 @@ void GameWindow::SetIcon(bool isNight)
|
||||
}
|
||||
}
|
||||
|
||||
void GameWindow::SetCursor(ECursorType cursorType)
|
||||
{
|
||||
if (s_currentCursor == cursorType)
|
||||
return;
|
||||
|
||||
s_currentCursor = cursorType;
|
||||
|
||||
uint8_t* pBitmapData;
|
||||
size_t bitmapSize;
|
||||
int x, y;
|
||||
|
||||
switch (cursorType)
|
||||
{
|
||||
case ECursorType::DebugDefault:
|
||||
pBitmapData = g_mouse_cursor;
|
||||
bitmapSize = sizeof(g_mouse_cursor);
|
||||
x = 0;
|
||||
y = 0;
|
||||
break;
|
||||
|
||||
case ECursorType::DebugHorizontal:
|
||||
pBitmapData = g_mouse_cursor_h;
|
||||
bitmapSize = sizeof(g_mouse_cursor_h);
|
||||
x = 15;
|
||||
y = 15;
|
||||
break;
|
||||
|
||||
case ECursorType::DebugVertical:
|
||||
pBitmapData = g_mouse_cursor_v;
|
||||
bitmapSize = sizeof(g_mouse_cursor_v);
|
||||
x = 15;
|
||||
y = 15;
|
||||
break;
|
||||
|
||||
case ECursorType::DebugLeftDiagonal:
|
||||
pBitmapData = g_mouse_cursor_slant_l;
|
||||
bitmapSize = sizeof(g_mouse_cursor_slant_l);
|
||||
x = 16;
|
||||
y = 15;
|
||||
break;
|
||||
|
||||
case ECursorType::DebugRightDiagonal:
|
||||
pBitmapData = g_mouse_cursor_slant_r;
|
||||
bitmapSize = sizeof(g_mouse_cursor_slant_r);
|
||||
x = 16;
|
||||
y = 15;
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_SetCursor(SDL_GetDefaultCursor());
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto surface = CreateSurface(pBitmapData, bitmapSize))
|
||||
{
|
||||
if (auto cursor = SDL_CreateColorCursor(surface, x, y))
|
||||
{
|
||||
SDL_SetCursor(cursor);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* GameWindow::GetTitle()
|
||||
{
|
||||
return Config::Language == ELanguage::Japanese
|
||||
@@ -338,7 +406,7 @@ bool GameWindow::SetFullscreen(bool isEnabled)
|
||||
if (isEnabled)
|
||||
{
|
||||
SDL_SetWindowFullscreen(s_pWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
SDL_ShowCursor(s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
SDL_ShowCursor(s_isCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -352,13 +420,13 @@ bool GameWindow::SetFullscreen(bool isEnabled)
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
void GameWindow::SetFullscreenCursorVisibility(bool isVisible)
|
||||
void GameWindow::SetCursorVisibility(bool isVisible)
|
||||
{
|
||||
s_isFullscreenCursorVisible = isVisible;
|
||||
s_isCursorVisible = isVisible;
|
||||
|
||||
if (IsFullscreen())
|
||||
{
|
||||
SDL_ShowCursor(s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
SDL_ShowCursor(s_isCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -422,6 +490,8 @@ void GameWindow::ResetDimensions()
|
||||
Config::WindowY = s_y;
|
||||
Config::WindowWidth = s_width;
|
||||
Config::WindowHeight = s_height;
|
||||
|
||||
SetDimensions(s_width, s_height, s_x, s_y);
|
||||
}
|
||||
|
||||
uint32_t GameWindow::GetWindowFlags()
|
||||
|
||||
@@ -9,6 +9,16 @@
|
||||
#define MIN_WIDTH 640
|
||||
#define MIN_HEIGHT 480
|
||||
|
||||
enum class ECursorType
|
||||
{
|
||||
Default,
|
||||
DebugDefault,
|
||||
DebugHorizontal,
|
||||
DebugVertical,
|
||||
DebugLeftDiagonal,
|
||||
DebugRightDiagonal
|
||||
};
|
||||
|
||||
class GameWindow
|
||||
{
|
||||
public:
|
||||
@@ -22,18 +32,21 @@ public:
|
||||
|
||||
static inline bool s_isFocused;
|
||||
static inline bool s_isIconNight;
|
||||
static inline bool s_isFullscreenCursorVisible;
|
||||
static inline bool s_isCursorVisible;
|
||||
static inline bool s_isChangingDisplay;
|
||||
|
||||
static SDL_Surface* GetIconSurface(void* pIconBmp, size_t iconSize);
|
||||
static inline ECursorType s_currentCursor;
|
||||
|
||||
static SDL_Surface* CreateSurface(void* pBitmapData, size_t bitmapSize);
|
||||
static void SetIcon(void* pIconBmp, size_t iconSize);
|
||||
static void SetIcon(bool isNight = false);
|
||||
static void SetCursor(ECursorType cursorType = ECursorType::Default);
|
||||
static const char* GetTitle();
|
||||
static void SetTitle(const char* title = nullptr);
|
||||
static void SetTitleBarColour();
|
||||
static bool IsFullscreen();
|
||||
static bool SetFullscreen(bool isEnabled);
|
||||
static void SetFullscreenCursorVisibility(bool isVisible);
|
||||
static void SetCursorVisibility(bool isVisible);
|
||||
static bool IsMaximised();
|
||||
static EWindowState SetMaximised(bool isEnabled);
|
||||
static SDL_Rect GetDimensions();
|
||||
|
||||
@@ -219,6 +219,17 @@ inline void DrawTextWithShadow(const ImFont* font, float fontSize, const ImVec2&
|
||||
drawList->AddText(font, fontSize, pos, colour, text, nullptr);
|
||||
}
|
||||
|
||||
inline void DrawTextWithShadow(ImDrawList* drawList, const ImFont* font, float fontSize, const ImVec2& pos, ImU32 colour, const char* text, float offset = 2.0f, float radius = 1.0f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255))
|
||||
{
|
||||
offset = Scale(offset);
|
||||
|
||||
SetOutline(radius);
|
||||
drawList->AddText(font, fontSize, { pos.x + offset, pos.y + offset }, shadowColour, text);
|
||||
ResetOutline();
|
||||
|
||||
drawList->AddText(font, fontSize, pos, colour, text, nullptr);
|
||||
}
|
||||
|
||||
inline float CalcWidestTextSize(const ImFont* font, float fontSize, std::span<std::string> strs)
|
||||
{
|
||||
auto result = 0.0f;
|
||||
|
||||
@@ -1556,7 +1556,7 @@ bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame)
|
||||
g_currentPage = g_firstPage;
|
||||
}
|
||||
|
||||
GameWindow::SetFullscreenCursorVisibility(true);
|
||||
GameWindow::SetCursorVisibility(true);
|
||||
s_isVisible = true;
|
||||
|
||||
while (s_isVisible)
|
||||
@@ -1568,7 +1568,7 @@ bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame)
|
||||
Video::Present();
|
||||
}
|
||||
|
||||
GameWindow::SetFullscreenCursorVisibility(false);
|
||||
GameWindow::SetCursorVisibility(false);
|
||||
NFD_Quit();
|
||||
|
||||
InstallerWizard::Shutdown();
|
||||
|
||||
236
UnleashedRecomp/ui/reddog/debug_draw.cpp
Normal file
236
UnleashedRecomp/ui/reddog/debug_draw.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
#include <api/SWA.h>
|
||||
#include <ui/reddog/debug_draw.h>
|
||||
#include "ui/imgui_utils.h"
|
||||
|
||||
|
||||
namespace Reddog
|
||||
{
|
||||
bool operator<= (const ImVec2& a, const ImVec2& b) { return a.x <= b.x && a.y <= b.y; }
|
||||
bool operator>= (const ImVec2& a, const ImVec2& b) { return a.x >= b.x && a.y >= b.y; }
|
||||
Hedgehog::Math::CVector4 operator /= (const Hedgehog::Math::CVector4& vec4, float divisor)
|
||||
{
|
||||
auto result = vec4;
|
||||
|
||||
if (result.X.value != 0.0f)
|
||||
result.X.value /= divisor;
|
||||
if (result.Y.value != 0.0f)
|
||||
result.Y.value /= divisor;
|
||||
if (result.Z.value != 0.0f)
|
||||
result.Z.value /= divisor;
|
||||
if (result.W.value != 0.0f)
|
||||
result.W.value /= divisor;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ImVec2 GetNDCCoordinate(const Vector3& in_rPosition)
|
||||
{
|
||||
auto& res = ImGui::GetIO().DisplaySize;
|
||||
|
||||
//const auto camera = SWA::CGameDocument::GetInstance()->GetWorld()->GetCamera();
|
||||
//Hedgehog::Math::CVector4 ndc = camera->m_MyCamera.m_View * Hedgehog::Math::CVector4(in_rVec.x, in_rVec.y, in_rVec.z, 1.0f);
|
||||
//ndc = camera->m_MyCamera.m_Projection * ndc;
|
||||
|
||||
//if (ndc.W > 0.0f) // Check if given position is in front of the camera
|
||||
//{
|
||||
// // normalize
|
||||
// if (ndc.W != 0.0f)
|
||||
// ndc /= ndc.W;
|
||||
|
||||
// const ImVec2 screen_pos = {
|
||||
// res.x / 2 * (1 - -ndc.X), // x
|
||||
// res.y / 2 * (1 - ndc.Y) // y
|
||||
// };
|
||||
|
||||
// return screen_pos; // Return screen coordinates
|
||||
//}
|
||||
|
||||
return { -1, -1 }; // Return invalid
|
||||
}
|
||||
|
||||
|
||||
void Exec_DrawLines(ImDrawList* drawList, ImVec2 canvasSize, float delta)
|
||||
{
|
||||
if (DebugDraw::ms_LineList.empty())
|
||||
return;
|
||||
|
||||
for (auto line : DebugDraw::ms_LineList)
|
||||
{
|
||||
const auto start = GetNDCCoordinate(line.Start);
|
||||
const auto end = GetNDCCoordinate(line.End);
|
||||
|
||||
// Prevent wrap around
|
||||
if (start >= ImVec2(0, 0) && end >= ImVec2(0, 0)
|
||||
&& start <= canvasSize && end <= canvasSize)
|
||||
{
|
||||
drawList->AddLine(start, end, line.Colour, 2.5f);
|
||||
}
|
||||
}
|
||||
|
||||
DebugDraw::ms_LineList.clear();
|
||||
}
|
||||
|
||||
|
||||
void Exec_DrawScreenText(ImDrawList* drawList, ImVec2 canvasSize, float delta, ImFont* font)
|
||||
{
|
||||
if (DebugDraw::ms_FreeTextList.empty())
|
||||
return;
|
||||
|
||||
auto fontSize = Scale(12.0f);
|
||||
|
||||
for (auto freeText = DebugDraw::ms_FreeTextList.begin(); freeText != DebugDraw::ms_FreeTextList.end();)
|
||||
{
|
||||
// Draw as overlay
|
||||
if ((freeText->Flags & eDrawTextFlags_Overlay) == eDrawTextFlags_Overlay)
|
||||
drawList = ImGui::GetForegroundDrawList();
|
||||
else
|
||||
drawList = ImGui::GetBackgroundDrawList();
|
||||
|
||||
// Draw only on valid screen coordinates
|
||||
if (freeText->Position >= ImVec2(0, 0) && freeText->Position <= canvasSize)
|
||||
{
|
||||
if ((freeText->Flags & eDrawTextFlags_NoShadow) == eDrawTextFlags_NoShadow)
|
||||
drawList->AddText(font, fontSize * freeText->Scale, freeText->Position, freeText->Colour, freeText->Text.c_str());
|
||||
else
|
||||
DrawTextWithShadow(drawList, font, fontSize * freeText->Scale, freeText->Position, freeText->Colour, freeText->Text.c_str(), 1.0f, 1.0f, IM_COL32(0, 0, 0, 128));
|
||||
}
|
||||
|
||||
// Decrement timer
|
||||
freeText->Time -= delta;
|
||||
|
||||
// Remove if expired
|
||||
if (freeText->Time < 0.0f)
|
||||
freeText = DebugDraw::ms_FreeTextList.erase(freeText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Exec_DrawLogText(ImDrawList* drawList, ImVec2 canvasSize, float delta, ImFont* font)
|
||||
{
|
||||
if (DebugDraw::ms_LogTextList.empty())
|
||||
return;
|
||||
|
||||
constexpr ImGuiWindowFlags flags { 0
|
||||
| ImGuiWindowFlags_NoTitleBar
|
||||
| ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_NoMove
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_AlwaysAutoResize
|
||||
};
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
|
||||
ImGui::Begin("Status", nullptr, flags);
|
||||
ImGui::PushFont(font);
|
||||
ImGui::SetWindowFontScale(Scale(0.4f));
|
||||
|
||||
for (auto logText = DebugDraw::ms_LogTextList.begin(); logText != DebugDraw::ms_LogTextList.end();)
|
||||
{
|
||||
bool useColor = logText->Colour != (ImU32)-1;
|
||||
|
||||
if (useColor)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, logText->Colour);
|
||||
|
||||
ImGui::TextUnformatted(logText->Text.c_str());
|
||||
|
||||
if (useColor)
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
// Decrement timer
|
||||
logText->Time -= delta;
|
||||
|
||||
// Remove if expired
|
||||
if (logText->Time < 0.0f)
|
||||
logText = DebugDraw::ms_LogTextList.erase(logText);
|
||||
|
||||
if (logText != DebugDraw::ms_LogTextList.end())
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos({ canvasSize.x - Scale(2) - ImGui::GetWindowSize().x, Scale(2) });
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopFont();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
void DebugDraw::DrawLine(const SDrawLine& in_rLine)
|
||||
{
|
||||
if (Config::Debug && !ms_IsRendering && GetIsDrawDebug())
|
||||
ms_LineList.push_back(in_rLine);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawText2D(const SDrawText& in_rText)
|
||||
{
|
||||
if (Config::Debug && !ms_IsRendering && GetIsDrawText())
|
||||
ms_FreeTextList.push_back(in_rText);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawText2D(const SDrawText& in_rText, const Vector3& in_rPosition)
|
||||
{
|
||||
if (Config::Debug && !ms_IsRendering && GetIsDrawText())
|
||||
{
|
||||
auto txt = in_rText;
|
||||
txt.Position = GetNDCCoordinate(in_rPosition);
|
||||
ms_FreeTextList.push_back(txt);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDraw::DrawTextLog(const SDrawText& in_rText)
|
||||
{
|
||||
if (Config::Debug && !ms_IsRendering && GetIsDrawText())
|
||||
ms_LogTextList.push_back(in_rText);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawTextLog(const char* in_Text, float in_Time, ImU32 in_Colour, ImU16 in_Priority)
|
||||
{
|
||||
if (Config::Debug && !ms_IsRendering && GetIsDrawText())
|
||||
ms_LogTextList.push_back({ ImVec2(0,0), in_Text, in_Time, 0, in_Colour, eDrawTextFlags_None, in_Priority});
|
||||
}
|
||||
|
||||
void DebugDraw::Render(ImFont* font)
|
||||
{
|
||||
auto& io = ImGui::GetIO();
|
||||
auto& res = io.DisplaySize;
|
||||
float deltaTime = io.DeltaTime;
|
||||
auto drawList = ImGui::GetBackgroundDrawList();
|
||||
|
||||
/*DrawText2D({ ImVec2(Scale(50), Scale(300)), "TEST1 NO SHADOW", 0, 2, 0xFF37C800, eDrawTextFlags_NoShadow });
|
||||
DrawText2D({ ImVec2(Scale(50), Scale(325)), "TEST2 OVERLAY", 0, 2, 0xFF37C800, eDrawTextFlags_Overlay });
|
||||
DrawText2D({ ImVec2(Scale(50), Scale(350)), "TEST3 SCALE", 0, 5, 0xFF37C800 });
|
||||
|
||||
DrawTextLog("TEST1 NORMAL");
|
||||
DrawTextLog("TEST2 COLORED", 0, 0xFF37C800);*/
|
||||
|
||||
auto stats = fmt::format("== Stats ==\nLines: {}\nTexts: {}\nLogs: {}", ms_LineList.size(), ms_FreeTextList.size(), ms_LogTextList.size());
|
||||
SDrawText text = { ImVec2(Scale(40), Scale(75)), stats, 0, 0.75f };
|
||||
DrawText2D(text);
|
||||
|
||||
ms_IsRendering = true;
|
||||
|
||||
Exec_DrawLines(drawList, res, deltaTime);
|
||||
Exec_DrawScreenText(nullptr, res, deltaTime, font);
|
||||
Exec_DrawLogText(drawList, res, deltaTime, font);
|
||||
|
||||
ms_IsRendering = false;
|
||||
}
|
||||
|
||||
bool DebugDraw::GetIsDrawDebug()
|
||||
{
|
||||
return *SWA::SGlobals::ms_IsRenderDebugDraw;
|
||||
}
|
||||
|
||||
bool DebugDraw::GetIsDrawText()
|
||||
{
|
||||
return *SWA::SGlobals::ms_IsRenderDebugDrawText;
|
||||
}
|
||||
|
||||
bool DebugDraw::GetIsDrawPosition()
|
||||
{
|
||||
return *SWA::SGlobals::ms_IsRenderDebugPositionDraw;
|
||||
}
|
||||
}
|
||||
66
UnleashedRecomp/ui/reddog/debug_draw.h
Normal file
66
UnleashedRecomp/ui/reddog/debug_draw.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace Reddog
|
||||
{
|
||||
struct Vector3
|
||||
{
|
||||
float x, y, z;
|
||||
constexpr Vector3() : x(0.0f), y(0.0f), z(0.0f) {}
|
||||
constexpr Vector3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
|
||||
};
|
||||
|
||||
enum SDrawTextFlags : uint8_t
|
||||
{
|
||||
eDrawTextFlags_None = 0,
|
||||
eDrawTextFlags_Overlay = 1 << 0,
|
||||
eDrawTextFlags_NoShadow = 1 << 1,
|
||||
};
|
||||
|
||||
struct SDrawLine
|
||||
{
|
||||
Vector3 Start { 0,0,0 };
|
||||
Vector3 End { 0,0,0 };
|
||||
ImU32 Colour { IM_COL32(255, 255, 255, 255) };
|
||||
float Size { 2 };
|
||||
};
|
||||
|
||||
struct SDrawText
|
||||
{
|
||||
ImVec2 Position { 0,0 };
|
||||
std::string Text;
|
||||
float Time { 0 };
|
||||
float Scale { 1 };
|
||||
ImU32 Colour { IM_COL32(255, 255, 255, 255) };
|
||||
SDrawTextFlags Flags { eDrawTextFlags_None };
|
||||
ImU16 Priority { 0 };
|
||||
};
|
||||
|
||||
|
||||
ImVec2 GetNDCCoordinate(const Vector3& in_rPosition);
|
||||
|
||||
|
||||
class DebugDraw
|
||||
{
|
||||
public:
|
||||
static inline bool ms_IsRendering = false;
|
||||
|
||||
static inline std::vector<SDrawLine> ms_LineList = {};
|
||||
static inline std::vector<SDrawText> ms_FreeTextList = {};
|
||||
static inline std::vector<SDrawText> ms_LogTextList = {};
|
||||
|
||||
static void DrawLine(const SDrawLine& in_rLine);
|
||||
|
||||
static void DrawText2D(const SDrawText& in_rText);
|
||||
static void DrawText2D(const SDrawText& in_rText, const Vector3& in_rPosition);
|
||||
|
||||
static void DrawTextLog(const SDrawText& in_rText);
|
||||
static void DrawTextLog(const char* in_Text, float in_Time = 0, ImU32 in_Colour = IM_COL32(255, 255, 255, 255), ImU16 in_Priority = 0);
|
||||
|
||||
static void Render(ImFont* font);
|
||||
|
||||
static bool GetIsDrawDebug();
|
||||
static bool GetIsDrawText();
|
||||
static bool GetIsDrawPosition();
|
||||
};
|
||||
}
|
||||
189
UnleashedRecomp/ui/reddog/reddog_controls.cpp
Normal file
189
UnleashedRecomp/ui/reddog/reddog_controls.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
#include "reddog_controls.h"
|
||||
#include <gpu/video.h>
|
||||
#include <ui/imgui_utils.h>
|
||||
|
||||
#include <res/images/reddog/checkbox_1.dds.h>
|
||||
#include <res/images/reddog/checkbox_2.dds.h>
|
||||
#include <res/images/reddog/common_button_1.dds.h>
|
||||
#include <res/images/reddog/common_button_2.dds.h>
|
||||
|
||||
constexpr float BUTTON_SIZE = 32.0f;
|
||||
constexpr float CHECKBOX_SIZE = 16.0f;
|
||||
|
||||
static std::unique_ptr<GuestTexture> g_upCheckbox1;
|
||||
static std::unique_ptr<GuestTexture> g_upCheckbox2;
|
||||
static std::unique_ptr<GuestTexture> g_upCommonButton1;
|
||||
static std::unique_ptr<GuestTexture> g_upCommonButton2;
|
||||
|
||||
void Reddog::InitControlsResources()
|
||||
{
|
||||
g_upCheckbox1 = LoadTexture(g_checkbox_1, sizeof(g_checkbox_1));
|
||||
g_upCheckbox2 = LoadTexture(g_checkbox_2, sizeof(g_checkbox_2));
|
||||
g_upCommonButton1 = LoadTexture(g_common_button_1, sizeof(g_common_button_1));
|
||||
g_upCommonButton2 = LoadTexture(g_common_button_2, sizeof(g_common_button_2));
|
||||
}
|
||||
|
||||
bool Reddog::Button(const char* label)
|
||||
{
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
auto& ctx = *GImGui;
|
||||
auto& style = ctx.Style;
|
||||
auto id = window->GetID(label);
|
||||
auto pos = window->DC.CursorPos;
|
||||
|
||||
ImVec2 labelSize = { 0, 0 };
|
||||
|
||||
if (label && label[0] != '\0')
|
||||
labelSize = ImGui::CalcTextSize(label, nullptr, true);
|
||||
|
||||
ImVec2 size = { BUTTON_SIZE / 2 + labelSize.x, BUTTON_SIZE / 2 };
|
||||
ImRect rect(pos, { pos.x + size.x, pos.y + size.y });
|
||||
ImRect paddedRect({ rect.Min.x, rect.Min.y - 1 }, { rect.Max.x, rect.Max.y + 1 });
|
||||
|
||||
ImGui::ItemSize(paddedRect, style.FramePadding.y);
|
||||
|
||||
if (!ImGui::ItemAdd(rect, id))
|
||||
return false;
|
||||
|
||||
bool isHovered, isHeld;
|
||||
bool isPressed = ImGui::ButtonBehavior(rect, id, &isHovered, &isHeld);
|
||||
|
||||
auto texture = isHeld && isHovered
|
||||
? g_upCommonButton2.get()
|
||||
: g_upCommonButton1.get();
|
||||
|
||||
constexpr float uvSize = 6.0f / 2.0f;
|
||||
auto tl = PIXELS_TO_UV_COORDS(32, 32, 0, 0, 8, 8);
|
||||
auto tc = PIXELS_TO_UV_COORDS(32, 32, 8, 0, 16, 8);
|
||||
auto tr = PIXELS_TO_UV_COORDS(32, 32, 24, 0, 8, 8);
|
||||
auto cl = PIXELS_TO_UV_COORDS(32, 32, 0, 8, 8, 16);
|
||||
auto cc = PIXELS_TO_UV_COORDS(32, 32, 8, 8, 16, 16);
|
||||
auto cr = PIXELS_TO_UV_COORDS(32, 32, 24, 8, 8, 16);
|
||||
auto bl = PIXELS_TO_UV_COORDS(32, 32, 0, 24, 8, 8);
|
||||
auto bc = PIXELS_TO_UV_COORDS(32, 32, 8, 24, 16, 8);
|
||||
auto br = PIXELS_TO_UV_COORDS(32, 32, 24, 24, 8, 8);
|
||||
|
||||
window->DrawList->AddImage(texture, rect.Min, { rect.Min.x + uvSize, rect.Min.y + uvSize }, GET_UV_COORDS(tl));
|
||||
window->DrawList->AddImage(texture, { rect.Min.x + uvSize, rect.Min.y }, { rect.Max.x - uvSize, rect.Min.y + uvSize }, GET_UV_COORDS(tc));
|
||||
window->DrawList->AddImage(texture, { rect.Max.x - uvSize, rect.Min.y }, { rect.Max.x, rect.Min.y + uvSize }, GET_UV_COORDS(tr));
|
||||
window->DrawList->AddImage(texture, { rect.Min.x, rect.Min.y + uvSize }, { rect.Min.x + uvSize, rect.Max.y - uvSize }, GET_UV_COORDS(cl));
|
||||
window->DrawList->AddImage(texture, { rect.Min.x + uvSize, rect.Min.y + uvSize }, { rect.Max.x - uvSize, rect.Max.y - uvSize }, GET_UV_COORDS(cc));
|
||||
window->DrawList->AddImage(texture, { rect.Max.x - uvSize, rect.Min.y + uvSize }, { rect.Max.x, rect.Max.y - uvSize }, GET_UV_COORDS(cr));
|
||||
window->DrawList->AddImage(texture, { rect.Min.x, rect.Max.y - uvSize }, { rect.Min.x + uvSize, rect.Max.y }, GET_UV_COORDS(bl));
|
||||
window->DrawList->AddImage(texture, { rect.Min.x + uvSize, rect.Max.y - uvSize }, { rect.Max.x - uvSize, rect.Max.y }, GET_UV_COORDS(bc));
|
||||
window->DrawList->AddImage(texture, { rect.Max.x - uvSize, rect.Max.y - uvSize }, rect.Max, GET_UV_COORDS(br));
|
||||
|
||||
float textOffset = isHeld && isPressed ? 1.0f : 0.0f;
|
||||
|
||||
if (label && label[0] != '\0')
|
||||
ImGui::RenderText({ textOffset + rect.Min.x + (size.x - labelSize.x) * 0.5f, textOffset + rect.Min.y + (size.y - labelSize.y) * 0.5f }, label);
|
||||
|
||||
return isPressed;
|
||||
}
|
||||
|
||||
bool Reddog::Checkbox(const char* label, bool* v)
|
||||
{
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
auto& ctx = *GImGui;
|
||||
auto& style = ctx.Style;
|
||||
auto id = window->GetID(label);
|
||||
auto labelSize = ImGui::CalcTextSize(label, nullptr, true);
|
||||
auto pos = window->DC.CursorPos;
|
||||
|
||||
ImVec2 size = { CHECKBOX_SIZE, CHECKBOX_SIZE };
|
||||
ImRect testRect(pos, { pos.x + size.x, pos.y + size.y });
|
||||
ImRect totalRect(pos, { pos.x + size.x + (labelSize.x > 0.0f ? style.ItemInnerSpacing.x + labelSize.x : 0.0f), pos.y + size.y });
|
||||
|
||||
ImGui::ItemSize(totalRect, style.FramePadding.y);
|
||||
|
||||
if (!ImGui::ItemAdd(totalRect, id))
|
||||
return false;
|
||||
|
||||
bool isHovered, isHeld;
|
||||
bool isPressed = ImGui::ButtonBehavior(testRect, id, &isHovered, &isHeld);
|
||||
|
||||
if (isPressed)
|
||||
{
|
||||
*v = !*v;
|
||||
ImGui::MarkItemEdited(id);
|
||||
}
|
||||
|
||||
auto texture = *v
|
||||
? g_upCheckbox2.get()
|
||||
: g_upCheckbox1.get();
|
||||
|
||||
window->DrawList->AddImage(texture, testRect.Min, testRect.Max);
|
||||
|
||||
if (labelSize.x > 0.0f)
|
||||
ImGui::RenderText({ testRect.Max.x + style.ItemInnerSpacing.x, testRect.Min.y + style.FramePadding.y }, label);
|
||||
|
||||
return isPressed;
|
||||
}
|
||||
|
||||
bool Reddog::ExplicitButton(const char* label, EButtonTextAlignment textAlignment, const ImVec2& size, float fontScale)
|
||||
{
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
auto font = ImGui::GetFont();
|
||||
font->Scale = fontScale;
|
||||
|
||||
ImGui::PushFont(font);
|
||||
|
||||
ImVec2 textSize = ImGui::CalcTextSize(label);
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
ImVec2 buttonMax = { pos.x + size.x, pos.y + size.y };
|
||||
|
||||
ImGui::InvisibleButton(label, size);
|
||||
|
||||
bool isHovered = ImGui::IsItemHovered();
|
||||
bool isActive = ImGui::IsItemActive();
|
||||
|
||||
ImVec4 colBg = isHovered ? ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered) : ImGui::GetStyleColorVec4(ImGuiCol_Button);
|
||||
ImVec4 colBorder = ImGui::GetStyleColorVec4(ImGuiCol_Border);
|
||||
ImVec4 colText = ImGui::GetStyleColorVec4(ImGuiCol_Text);
|
||||
|
||||
window->DrawList->AddRectFilled(pos, buttonMax, ImGui::ColorConvertFloat4ToU32(colBg));
|
||||
window->DrawList->AddRect(pos, buttonMax, ImGui::ColorConvertFloat4ToU32(colBorder));
|
||||
|
||||
auto colTextU32 = ImGui::ColorConvertFloat4ToU32(colText);
|
||||
auto framePadding = ImGui::GetStyle().FramePadding;
|
||||
auto marginX = 8.0f;
|
||||
auto textY = (pos.y + (size.y - textSize.y) * 0.5f) - 1.0f;
|
||||
|
||||
switch (textAlignment)
|
||||
{
|
||||
case EButtonTextAlignment::Left:
|
||||
window->DrawList->AddText({ pos.x + framePadding.x + marginX, textY }, colTextU32, label);
|
||||
break;
|
||||
|
||||
case EButtonTextAlignment::Centre:
|
||||
window->DrawList->AddText({ pos.x + (size.x - textSize.x) * 0.5f, textY }, colTextU32, label);
|
||||
break;
|
||||
|
||||
case EButtonTextAlignment::Right:
|
||||
window->DrawList->AddText({ size.x - framePadding.x - textSize.x - marginX, textY }, colTextU32, label);
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::PopFont();
|
||||
|
||||
return isActive;
|
||||
}
|
||||
|
||||
void Reddog::Separator(float upperPadding, float lowerPadding)
|
||||
{
|
||||
ImGui::Dummy(ImVec2(0.0f, upperPadding));
|
||||
ImGui::Separator();
|
||||
ImGui::Dummy(ImVec2(0.0f, lowerPadding));
|
||||
}
|
||||
17
UnleashedRecomp/ui/reddog/reddog_controls.h
Normal file
17
UnleashedRecomp/ui/reddog/reddog_controls.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace Reddog
|
||||
{
|
||||
enum class EButtonTextAlignment
|
||||
{
|
||||
Left,
|
||||
Centre,
|
||||
Right
|
||||
};
|
||||
|
||||
void InitControlsResources();
|
||||
bool Button(const char* label);
|
||||
bool Checkbox(const char* label, bool* v);
|
||||
bool ExplicitButton(const char* label, EButtonTextAlignment textAlignment = EButtonTextAlignment::Centre, const ImVec2& size = { 0, 0 }, float fontScale = 1);
|
||||
void Separator(float upperPadding = 0, float lowerPadding = 0);
|
||||
}
|
||||
154
UnleashedRecomp/ui/reddog/reddog_manager.cpp
Normal file
154
UnleashedRecomp/ui/reddog/reddog_manager.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "reddog_manager.h"
|
||||
#include <gpu/imgui/imgui_snapshot.h>
|
||||
#include <gpu/video.h>
|
||||
#include <ui/reddog/windows/window_list.h>
|
||||
#include <ui/reddog/reddog_controls.h>
|
||||
#include <ui/reddog/debug_draw.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <ui/imgui_utils.h>
|
||||
|
||||
#include <res/images/reddog/debug_icon.dds.h>
|
||||
|
||||
static std::unique_ptr<GuestTexture> g_upDebugIcon;
|
||||
|
||||
static ImVec2 g_debugIconPosOrig;
|
||||
static ImVec2 g_debugIconPos = { 0, 0 };
|
||||
|
||||
static bool g_isDebugIconClicked = false;
|
||||
static bool g_isDraggingDebugIcon = false;
|
||||
static bool g_isReddogToggled = false;
|
||||
static bool g_isWindowListVisible = false;
|
||||
|
||||
void Reddog::Manager::Init()
|
||||
{
|
||||
s_font = ImFontAtlasSnapshot::GetFont("micross.ttf");
|
||||
g_upDebugIcon = LoadTexture(g_debug_icon, sizeof(g_debug_icon));
|
||||
|
||||
Reddog::InitControlsResources();
|
||||
Reddog::InitWindowResources();
|
||||
}
|
||||
|
||||
void Reddog::Manager::Draw()
|
||||
{
|
||||
bool isReddogToggled = SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_F1] != 0;
|
||||
|
||||
if (!g_isReddogToggled && isReddogToggled)
|
||||
{
|
||||
s_isVisible = !s_isVisible;
|
||||
|
||||
if (!s_isVisible)
|
||||
{
|
||||
g_debugIconPos = { 0, 0 };
|
||||
GameWindow::SetCursor(ECursorType::Default);
|
||||
GameWindow::SetCursorVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
g_isReddogToggled = isReddogToggled;
|
||||
|
||||
Video::DrawFPS(s_font);
|
||||
|
||||
// Render our Debug Draw
|
||||
DebugDraw::Render(s_font);
|
||||
|
||||
if (!s_isVisible)
|
||||
return;
|
||||
|
||||
if (GameWindow::s_currentCursor == ECursorType::Default)
|
||||
{
|
||||
GameWindow::SetCursor(ECursorType::DebugDefault);
|
||||
GameWindow::SetCursorVisibility(true);
|
||||
}
|
||||
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
auto& res = ImGui::GetIO().DisplaySize;
|
||||
|
||||
auto debugIconSize = Scale(32);
|
||||
ImVec2 debugIconMin = g_debugIconPos;
|
||||
ImVec2 debugIconMax = { g_debugIconPos.x + debugIconSize, g_debugIconPos.y + debugIconSize };
|
||||
|
||||
drawList->AddImage(g_upDebugIcon.get(), debugIconMin, debugIconMax);
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(debugIconMin, debugIconMax, false) && ImGui::IsMouseClicked(0))
|
||||
{
|
||||
g_debugIconPosOrig = g_debugIconPos;
|
||||
g_isDraggingDebugIcon = true;
|
||||
}
|
||||
|
||||
g_isDebugIconClicked = false;
|
||||
|
||||
if (g_isDraggingDebugIcon && ImGui::IsMouseDown(0))
|
||||
{
|
||||
auto& delta = ImGui::GetIO().MouseDelta;
|
||||
g_debugIconPos.x += delta.x;
|
||||
g_debugIconPos.y += delta.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_isDraggingDebugIcon &&
|
||||
g_debugIconPos.x == g_debugIconPosOrig.x &&
|
||||
g_debugIconPos.y == g_debugIconPosOrig.y)
|
||||
{
|
||||
g_isDebugIconClicked = true;
|
||||
g_isWindowListVisible = !g_isWindowListVisible;
|
||||
}
|
||||
|
||||
g_isDraggingDebugIcon = false;
|
||||
}
|
||||
|
||||
if (auto pWindowList = GetWindow<WindowList>(WINDOW_LIST_NAME))
|
||||
{
|
||||
if (!g_isDebugIconClicked && !pWindowList->IsFocused)
|
||||
pWindowList->IsVisible = g_isWindowListVisible = false;
|
||||
|
||||
pWindowList->IsVisible = g_isWindowListVisible;
|
||||
|
||||
if (pWindowList->ImWindow)
|
||||
{
|
||||
if (debugIconMin.x > res.x / 2)
|
||||
{
|
||||
pWindowList->ImWindow->Pos.x = debugIconMax.x - pWindowList->ImWindow->Size.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWindowList->ImWindow->Pos.x = debugIconMin.x;
|
||||
}
|
||||
|
||||
if (debugIconMin.y > res.y / 2)
|
||||
{
|
||||
pWindowList->ImWindow->Pos.y = debugIconMin.y - pWindowList->ImWindow->Size.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWindowList->ImWindow->Pos.y = debugIconMin.y + debugIconSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& pWindow : Reddog::GetWindows())
|
||||
{
|
||||
auto pTrueWindow = (Reddog::Window*)pWindow;
|
||||
|
||||
if (!pTrueWindow->IsVisible)
|
||||
continue;
|
||||
|
||||
pWindow->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
Reddog::Window* Reddog::Manager::GetWindow(const char* pName)
|
||||
{
|
||||
for (auto pWindow : Reddog::GetWindows())
|
||||
{
|
||||
if (strcmp(pWindow->GetName(), pName) == 0)
|
||||
return (Reddog::Window*)pWindow;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Reddog::Manager::GetWindow(const char* pName)
|
||||
{
|
||||
return (T*)Reddog::Manager::GetWindow(pName);
|
||||
}
|
||||
22
UnleashedRecomp/ui/reddog/reddog_manager.h
Normal file
22
UnleashedRecomp/ui/reddog/reddog_manager.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <ui/reddog/reddog_window.h>
|
||||
|
||||
namespace Reddog
|
||||
{
|
||||
class Manager
|
||||
{
|
||||
public:
|
||||
static inline bool s_isVisible = false;
|
||||
|
||||
static inline ImFont* s_font{ nullptr };
|
||||
|
||||
static void Init();
|
||||
static void Draw();
|
||||
|
||||
static Window* GetWindow(const char* pName);
|
||||
|
||||
template<typename T>
|
||||
static T* GetWindow(const char* pName);
|
||||
};
|
||||
}
|
||||
428
UnleashedRecomp/ui/reddog/reddog_window.cpp
Normal file
428
UnleashedRecomp/ui/reddog/reddog_window.cpp
Normal file
@@ -0,0 +1,428 @@
|
||||
#include "reddog_window.h"
|
||||
#include <gpu/video.h>
|
||||
#include <ui/reddog/reddog_manager.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <ui/imgui_utils.h>
|
||||
|
||||
#include <res/images/reddog/button_close_1.dds.h>
|
||||
#include <res/images/reddog/button_close_2.dds.h>
|
||||
#include <res/images/reddog/button_minimum_1.dds.h>
|
||||
#include <res/images/reddog/button_minimum_2.dds.h>
|
||||
#include <res/images/reddog/button_pin_1.dds.h>
|
||||
#include <res/images/reddog/button_pin_2.dds.h>
|
||||
#include <res/images/reddog/common_icon.dds.h>
|
||||
#include <res/images/reddog/title_bar.dds.h>
|
||||
|
||||
constexpr float MIN_WINDOW_SIZE = 21.0f;
|
||||
|
||||
static std::unique_ptr<GuestTexture> g_upButtonClose1;
|
||||
static std::unique_ptr<GuestTexture> g_upButtonClose2;
|
||||
static std::unique_ptr<GuestTexture> g_upButtonMinimum1;
|
||||
static std::unique_ptr<GuestTexture> g_upButtonMinimum2;
|
||||
static std::unique_ptr<GuestTexture> g_upButtonPin1;
|
||||
static std::unique_ptr<GuestTexture> g_upButtonPin2;
|
||||
static std::unique_ptr<GuestTexture> g_upCommonIcon;
|
||||
static std::unique_ptr<GuestTexture> g_upTitleBar;
|
||||
static std::unique_ptr<GuestTexture> g_upWindowFrame;
|
||||
|
||||
float g_defaultFontScale;
|
||||
ImGuiStyle g_defaultStyle;
|
||||
|
||||
static std::vector<Reddog::IWindow*>& Reddog::GetWindows()
|
||||
{
|
||||
static std::vector<Reddog::IWindow*> g_windows;
|
||||
return g_windows;
|
||||
}
|
||||
|
||||
void Reddog::InitWindowResources()
|
||||
{
|
||||
g_defaultFontScale = Reddog::Manager::s_font->Scale;
|
||||
|
||||
auto& style = ImGui::GetStyle();
|
||||
g_defaultStyle = style;
|
||||
|
||||
g_upButtonClose1 = LoadTexture(g_button_close_1, sizeof(g_button_close_1));
|
||||
g_upButtonClose2 = LoadTexture(g_button_close_2, sizeof(g_button_close_2));
|
||||
g_upButtonMinimum1 = LoadTexture(g_button_minimum_1, sizeof(g_button_minimum_1));
|
||||
g_upButtonMinimum2 = LoadTexture(g_button_minimum_2, sizeof(g_button_minimum_2));
|
||||
g_upButtonPin1 = LoadTexture(g_button_pin_1, sizeof(g_button_pin_1));
|
||||
g_upButtonPin2 = LoadTexture(g_button_pin_2, sizeof(g_button_pin_2));
|
||||
g_upCommonIcon = LoadTexture(g_common_icon, sizeof(g_common_icon));
|
||||
g_upTitleBar = LoadTexture(g_title_bar, sizeof(g_title_bar));
|
||||
}
|
||||
|
||||
void Reddog::Window::BeginStyle()
|
||||
{
|
||||
Reddog::Manager::s_font->Scale = ImGui::GetDefaultFont()->FontSize / Reddog::Manager::s_font->FontSize;
|
||||
|
||||
ImGui::PushFont(Reddog::Manager::s_font);
|
||||
|
||||
UpdateStyle();
|
||||
}
|
||||
|
||||
void Reddog::Window::UpdateStyle()
|
||||
{
|
||||
auto& style = ImGui::GetStyle();
|
||||
|
||||
style.WindowMinSize = { 0, MIN_WINDOW_SIZE };
|
||||
|
||||
auto colBg = IsFocused
|
||||
? ImGui::ColorConvertU32ToFloat4(ActiveColour)
|
||||
: ImGui::ColorConvertU32ToFloat4(InactiveColour);
|
||||
|
||||
auto colBlack = ImVec4(0, 0, 0, 1);
|
||||
auto colTrans = ImVec4(0, 0, 0, 0);
|
||||
auto colWhite = ImVec4(1, 1, 1, 1);
|
||||
|
||||
style.Colors[ImGuiCol_Border] = colTrans;
|
||||
style.Colors[ImGuiCol_Button] = colTrans;
|
||||
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.67f, 0.67f, 0.67f, 1);
|
||||
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.675f, 0.675f, 0.675f, 1);
|
||||
style.Colors[ImGuiCol_CheckMark] = colBlack;
|
||||
style.Colors[ImGuiCol_ChildBg] = colBg;
|
||||
style.Colors[ImGuiCol_FrameBg] = colBg;
|
||||
style.Colors[ImGuiCol_PopupBg] = colBg;
|
||||
style.Colors[ImGuiCol_ResizeGrip] = colTrans;
|
||||
style.Colors[ImGuiCol_ResizeGripActive] = colTrans;
|
||||
style.Colors[ImGuiCol_ResizeGripHovered] = colTrans;
|
||||
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.6f, 0.6f, 0.6f, 1);
|
||||
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(1, 0.6f, 0, 1);
|
||||
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(1, 0.6f, 0, 1);
|
||||
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(1, 0.6f, 0, 1);
|
||||
style.Colors[ImGuiCol_SeparatorActive] = colTrans;
|
||||
style.Colors[ImGuiCol_SeparatorHovered] = colTrans;
|
||||
style.Colors[ImGuiCol_SliderGrab] = colWhite;
|
||||
style.Colors[ImGuiCol_Tab] = ImVec4(0.467f, 0.467f, 0.467f, 1);
|
||||
style.Colors[ImGuiCol_TabActive] = ImVec4(0.6f, 0.6f, 0.6f, 1);
|
||||
style.Colors[ImGuiCol_TabHovered] = ImVec4(0.667f, 0.667f, 0.667f, 1);
|
||||
style.Colors[ImGuiCol_Text] = colBlack;
|
||||
style.Colors[ImGuiCol_WindowBg] = colBg;
|
||||
}
|
||||
|
||||
void Reddog::Window::EndStyle()
|
||||
{
|
||||
ImGui::PopFont();
|
||||
|
||||
Reddog::Manager::s_font->Scale = g_defaultFontScale;
|
||||
|
||||
ImGui::GetStyle() = g_defaultStyle;
|
||||
}
|
||||
|
||||
void Reddog::Window::CreateWindowGrips()
|
||||
{
|
||||
if (!ImWindow || !IsFocused)
|
||||
return;
|
||||
|
||||
auto& io = ImGui::GetIO();
|
||||
|
||||
auto windowPos = ImWindow->Pos;
|
||||
auto windowSize = ImWindow->Size;
|
||||
|
||||
constexpr float resizeMargin = 5.0f;
|
||||
|
||||
ImRect grips[6] =
|
||||
{
|
||||
// Corners
|
||||
ImRect(windowPos.x, windowPos.y + windowSize.y - resizeMargin, windowPos.x + resizeMargin, windowPos.y + windowSize.y), // Bottom left
|
||||
ImRect(windowPos.x + windowSize.x - resizeMargin, windowPos.y + windowSize.y - resizeMargin, windowPos.x + windowSize.x, windowPos.y + windowSize.y), // Bottom right
|
||||
|
||||
// Edges
|
||||
ImRect(windowPos.x + resizeMargin, windowPos.y, windowPos.x + windowSize.x - resizeMargin, windowPos.y + resizeMargin), // Top
|
||||
ImRect(windowPos.x + resizeMargin, windowPos.y + windowSize.y - resizeMargin, windowPos.x + windowSize.x - resizeMargin, windowPos.y + windowSize.y), // Bottom
|
||||
ImRect(windowPos.x, windowPos.y + resizeMargin, windowPos.x + resizeMargin, windowPos.y + windowSize.y - resizeMargin), // Left
|
||||
ImRect(windowPos.x + windowSize.x - resizeMargin, windowPos.y + resizeMargin, windowPos.x + windowSize.x, windowPos.y + windowSize.y - resizeMargin) // Right
|
||||
};
|
||||
|
||||
auto hoveredGrip = -1;
|
||||
|
||||
for (int i = 0; i < IM_ARRAYSIZE(grips); i++)
|
||||
{
|
||||
auto& grip = grips[i];
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(grip.Min, grip.Max))
|
||||
hoveredGrip = i;
|
||||
}
|
||||
|
||||
if (hoveredGrip < 0)
|
||||
{
|
||||
GameWindow::SetCursor(ECursorType::DebugDefault);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hoveredGrip == 0)
|
||||
{
|
||||
GameWindow::SetCursor(ECursorType::DebugRightDiagonal);
|
||||
}
|
||||
else if (hoveredGrip == 1)
|
||||
{
|
||||
GameWindow::SetCursor(ECursorType::DebugLeftDiagonal);
|
||||
}
|
||||
else if (hoveredGrip == 2 || hoveredGrip == 3)
|
||||
{
|
||||
GameWindow::SetCursor(ECursorType::DebugVertical);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameWindow::SetCursor(ECursorType::DebugHorizontal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reddog::Window::DrawFrame()
|
||||
{
|
||||
if (!ImWindow)
|
||||
return;
|
||||
|
||||
if ((Flags & eWindowFlags_NoResize) == 0)
|
||||
CreateWindowGrips();
|
||||
|
||||
UpdateStyle();
|
||||
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
auto windowPos = ImWindow->Pos;
|
||||
auto windowSize = ImWindow->Size;
|
||||
auto isFocused = ImGui::IsWindowFocused();
|
||||
auto hasTitleBar = (Flags & eWindowFlags_NoTitleBar) == 0;
|
||||
|
||||
float titleBarHeight = hasTitleBar ? 20.0f : 0.0f;
|
||||
|
||||
ImVec2 windowMin = { windowPos.x, windowPos.y + titleBarHeight };
|
||||
ImVec2 windowMax = { windowPos.x + windowSize.x, windowPos.y + windowSize.y };
|
||||
|
||||
drawList->AddRectFilled(windowMin, windowMax, isFocused ? ActiveColour : InactiveColour);
|
||||
drawList->AddLine(windowMin, { windowMax.x, windowMin.y }, IM_COL32(170, 170, 170, 255)); // Outer top line.
|
||||
drawList->AddLine({ windowMin.x + 1, windowMin.y + 1 }, { windowMin.x + 1, windowMax.y }, IM_COL32(153, 153, 153, 255)); // Outer left line.
|
||||
drawList->AddLine({ windowMin.x, windowMax.y - 2 }, { windowMax.x, windowMax.y - 2 }, IM_COL32(51, 51, 51, 255)); // Outer bottom line.
|
||||
drawList->AddLine({ windowMax.x - 2, windowMin.y + 1 }, { windowMax.x - 2, windowMax.y }, IM_COL32(85, 85, 85, 255)); // Outer right line.
|
||||
drawList->AddLine({ windowMin.x + 2, windowMin.y + 1 }, { windowMax.x - 2, windowMin.y + 1 }, IM_COL32(51, 51, 51, 255)); // Inner top line.
|
||||
drawList->AddLine({ windowMin.x + 2, windowMin.y + 2 }, { windowMin.x + 2, windowMax.y - 2 }, IM_COL32(85, 85, 85, 255)); // Inner left line.
|
||||
drawList->AddLine({ windowMin.x + 3, windowMax.y - 3 }, { windowMax.x - 2, windowMax.y - 3 }, IM_COL32(170, 170, 170, 255)); // Inner bottom line.
|
||||
drawList->AddLine({ windowMax.x - 3, windowMin.y + 2 }, { windowMax.x - 3, windowMax.y - 3 }, IM_COL32(153, 153, 153, 255)); // Inner right line.
|
||||
|
||||
// Close window if unfocused whilst unpinned (yes it works like this in SU preview).
|
||||
if (!IsPinned && !isFocused && m_pIsVisible)
|
||||
*m_pIsVisible = !*m_pIsVisible;
|
||||
|
||||
if (hasTitleBar)
|
||||
{
|
||||
auto height = titleBarHeight;
|
||||
auto left = PIXELS_TO_UV_COORDS(32, 32, 0, 0, 3, 32);
|
||||
auto centre = PIXELS_TO_UV_COORDS(32, 32, 3, 0, 26, 32);
|
||||
auto right = PIXELS_TO_UV_COORDS(32, 32, 29, 0, 3, 32);
|
||||
|
||||
auto colTitleBar = isFocused
|
||||
? IM_COL32(220, 220, 247, 255)
|
||||
: IM_COL32(176, 176, 176, 255);
|
||||
|
||||
drawList->AddImage(g_upTitleBar.get(), { windowPos.x, windowPos.y }, { windowPos.x + 3, windowPos.y + height }, GET_UV_COORDS(left), colTitleBar);
|
||||
drawList->AddImage(g_upTitleBar.get(), { windowPos.x + 3, windowPos.y }, { windowPos.x + windowSize.x - 3, windowPos.y + height }, GET_UV_COORDS(centre), colTitleBar);
|
||||
drawList->AddImage(g_upTitleBar.get(), { windowPos.x + windowSize.x - 3, windowPos.y }, { windowPos.x + windowSize.x, windowPos.y + height }, GET_UV_COORDS(right), colTitleBar);
|
||||
|
||||
auto cmnSize = 16.0f;
|
||||
|
||||
ImVec2 cmnIconMin = { windowPos.x + 9, windowPos.y + 2 };
|
||||
ImVec2 cmnIconMax = { cmnIconMin.x + cmnSize, cmnIconMin.y + cmnSize };
|
||||
|
||||
drawList->AddImage(g_upCommonIcon.get(), cmnIconMin, cmnIconMax, { 0, 0 }, { 1, 1 }, IM_COL32_WHITE);
|
||||
|
||||
auto colTitleText = isFocused
|
||||
? IM_COL32_WHITE
|
||||
: IM_COL32(190, 190, 190, 255);
|
||||
|
||||
drawList->AddText({ cmnIconMax.x + 5, windowPos.y + 4 }, colTitleText, Name);
|
||||
|
||||
float controlsWidth = 0;
|
||||
float controlsMargin = 4;
|
||||
|
||||
ImVec2 closeButtonMin = { windowPos.x + windowSize.x - cmnSize - controlsMargin, windowPos.y + 3 };
|
||||
ImVec2 closeButtonMax = { closeButtonMin.x + cmnSize, closeButtonMin.y + cmnSize };
|
||||
|
||||
if (IsCloseVisible)
|
||||
{
|
||||
controlsWidth += closeButtonMax.x - closeButtonMin.x + controlsMargin;
|
||||
|
||||
ImGui::SetCursorScreenPos(closeButtonMin);
|
||||
ImGui::InvisibleButton("##CloseButton", { cmnSize, cmnSize });
|
||||
bool isCloseButtonActive = ImGui::IsItemActive();
|
||||
|
||||
if (isCloseButtonActive)
|
||||
{
|
||||
drawList->AddImage(g_upButtonClose2.get(), closeButtonMin, closeButtonMax);
|
||||
m_isCloseButtonPressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawList->AddImage(g_upButtonClose1.get(), closeButtonMin, closeButtonMax);
|
||||
|
||||
if (m_isCloseButtonPressed && m_pIsVisible)
|
||||
{
|
||||
*m_pIsVisible = !*m_pIsVisible;
|
||||
m_isCloseButtonPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 minimumButtonMin = { windowPos.x + windowSize.x - cmnSize - controlsWidth - controlsMargin, windowPos.y + 3 };
|
||||
ImVec2 minimumButtonMax = { minimumButtonMin.x + cmnSize, minimumButtonMin.y + cmnSize };
|
||||
|
||||
if (IsMinimumVisible)
|
||||
{
|
||||
controlsWidth += minimumButtonMax.x - minimumButtonMin.x + controlsMargin;
|
||||
|
||||
ImGui::SetCursorScreenPos(minimumButtonMin);
|
||||
ImGui::InvisibleButton("##MinimumButton", { cmnSize, cmnSize });
|
||||
bool isMinimumButtonActive = ImGui::IsItemActive();
|
||||
|
||||
if (isMinimumButtonActive)
|
||||
{
|
||||
drawList->AddImage(g_upButtonMinimum2.get(), minimumButtonMin, minimumButtonMax);
|
||||
m_isMinimumButtonPressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawList->AddImage(g_upButtonMinimum1.get(), minimumButtonMin, minimumButtonMax);
|
||||
|
||||
if (m_isMinimumButtonPressed)
|
||||
{
|
||||
SetMinimum(!IsMinimum);
|
||||
m_isMinimumButtonPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 pinButtonMin = { windowPos.x + windowSize.x - cmnSize - controlsWidth - controlsMargin, windowPos.y + 3 };
|
||||
ImVec2 pinButtonMax = { pinButtonMin.x + cmnSize, pinButtonMin.y + cmnSize };
|
||||
|
||||
if (IsPinVisible)
|
||||
{
|
||||
controlsWidth += pinButtonMax.x - pinButtonMin.x + controlsMargin;
|
||||
|
||||
ImGui::SetCursorScreenPos(pinButtonMin);
|
||||
ImGui::InvisibleButton("##PinButton", { cmnSize, cmnSize });
|
||||
bool isPinButtonActive = ImGui::IsItemActive();
|
||||
|
||||
if (isPinButtonActive)
|
||||
{
|
||||
drawList->AddImage(g_upButtonPin2.get(), pinButtonMin, pinButtonMax);
|
||||
m_isPinButtonPressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawList->AddImage(g_upButtonPin1.get(), pinButtonMin, pinButtonMax);
|
||||
|
||||
if (m_isPinButtonPressed)
|
||||
{
|
||||
IsPinned = !IsPinned;
|
||||
m_isPinButtonPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 titleBarMin = { windowPos.x, windowPos.y };
|
||||
ImVec2 titleBarMax = { windowPos.x + windowSize.x - controlsWidth, windowPos.y + titleBarHeight };
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(titleBarMin, titleBarMax, false))
|
||||
{
|
||||
if (IsMinimumVisible && ImGui::IsMouseDoubleClicked(0))
|
||||
SetMinimum(!IsMinimum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reddog::Window::SetMinimum(bool isMinimum)
|
||||
{
|
||||
IsMinimum = isMinimum;
|
||||
|
||||
if (!ImWindow)
|
||||
return;
|
||||
|
||||
auto windowSize = ImWindow->Size;
|
||||
|
||||
if (IsMinimum)
|
||||
{
|
||||
m_preMinimumWindowSize = windowSize;
|
||||
ImGui::SetWindowSize(ImWindow, { windowSize.x, MIN_WINDOW_SIZE });
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::SetWindowSize(ImWindow, { windowSize.x, m_preMinimumWindowSize.y });
|
||||
}
|
||||
}
|
||||
|
||||
void Reddog::Window::SetVisible(bool isVisible)
|
||||
{
|
||||
IsVisible = m_isSetVisible = isVisible;
|
||||
}
|
||||
|
||||
bool Reddog::Window::Begin(bool* pIsVisible)
|
||||
{
|
||||
if (pIsVisible)
|
||||
{
|
||||
m_pIsVisible = pIsVisible;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pIsVisible = &IsVisible;
|
||||
}
|
||||
|
||||
BeginStyle();
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints({ m_minWidth, m_minHeight }, { m_maxWidth, m_maxHeight });
|
||||
|
||||
auto flags = REDDOG_IMGUI_FLAGS;
|
||||
|
||||
if ((Flags & eWindowFlags_NoResize) != 0)
|
||||
flags |= ImGuiWindowFlags_NoResize;
|
||||
|
||||
if (m_preBegin)
|
||||
m_preBegin();
|
||||
|
||||
bool result = ImGui::Begin(Name, m_pIsVisible, flags);
|
||||
|
||||
if (m_postBegin)
|
||||
m_postBegin();
|
||||
|
||||
if (result && *m_pIsVisible)
|
||||
{
|
||||
ImWindow = ImGui::GetCurrentWindow();
|
||||
IsFocused = ImGui::IsWindowFocused();
|
||||
|
||||
if ((Flags & eWindowFlags_Centre) != 0 && !m_isSetCentre)
|
||||
{
|
||||
auto viewport = ImGui::GetMainViewport();
|
||||
auto windowPos = ImGui::GetWindowPos();
|
||||
auto pos = ImVec2((viewport->Size.x / 2) - (ImWindow->Size.x / 2), (viewport->Size.y / 2) - (ImWindow->Size.y / 2));
|
||||
|
||||
ImGui::SetWindowPos(pos);
|
||||
}
|
||||
|
||||
// Keep centring window until it has been moved.
|
||||
if (ImGui::IsMouseDragging(0) && ImGui::IsWindowHovered())
|
||||
m_isSetCentre = true;
|
||||
|
||||
if (m_isSetVisible)
|
||||
{
|
||||
ImGui::SetWindowFocus();
|
||||
m_isSetVisible = false;
|
||||
}
|
||||
|
||||
DrawFrame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Reddog::Window::End()
|
||||
{
|
||||
if (m_preEnd)
|
||||
m_preEnd();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (m_postEnd)
|
||||
m_postEnd();
|
||||
|
||||
EndStyle();
|
||||
}
|
||||
99
UnleashedRecomp/ui/reddog/reddog_window.h
Normal file
99
UnleashedRecomp/ui/reddog/reddog_window.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#define REDDOG_IMGUI_FLAGS ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBackground
|
||||
|
||||
namespace Reddog
|
||||
{
|
||||
enum EWindowFlags : uint32_t
|
||||
{
|
||||
eWindowFlags_None = 0,
|
||||
eWindowFlags_NoTitleBar = 1 << 0,
|
||||
eWindowFlags_NoResize = 1 << 1,
|
||||
eWindowFlags_NoListEntry = 1 << 2,
|
||||
eWindowFlags_Centre = 1 << 3
|
||||
};
|
||||
|
||||
class IWindow
|
||||
{
|
||||
public:
|
||||
virtual ~IWindow() = default;
|
||||
virtual const char* GetName() = 0;
|
||||
virtual void Draw() = 0;
|
||||
};
|
||||
|
||||
extern std::vector<IWindow*>& GetWindows();
|
||||
|
||||
class Window : public IWindow
|
||||
{
|
||||
private:
|
||||
bool* m_pIsVisible{ nullptr };
|
||||
|
||||
bool m_isSetCentre{};
|
||||
bool m_isSetVisible{};
|
||||
|
||||
bool m_isCloseButtonPressed{};
|
||||
bool m_isMinimumButtonPressed{};
|
||||
bool m_isPinButtonPressed{};
|
||||
|
||||
ImVec2 m_preMinimumWindowSize{};
|
||||
|
||||
void BeginStyle();
|
||||
void UpdateStyle();
|
||||
void EndStyle();
|
||||
void CreateWindowGrips();
|
||||
void DrawFrame();
|
||||
|
||||
protected:
|
||||
float m_minWidth{ 175.0f };
|
||||
float m_minHeight{};
|
||||
float m_maxWidth{ FLT_MAX };
|
||||
float m_maxHeight{ FLT_MAX };
|
||||
|
||||
std::function<void()> m_preBegin{ nullptr };
|
||||
std::function<void()> m_postBegin{ nullptr };
|
||||
std::function<void()> m_preEnd{ nullptr };
|
||||
std::function<void()> m_postEnd{ nullptr };
|
||||
|
||||
public:
|
||||
const char* Name{ "(null)" };
|
||||
EWindowFlags Flags{ eWindowFlags_None };
|
||||
bool IsFocused{ true };
|
||||
bool IsCloseVisible{ true };
|
||||
bool IsMinimumVisible{ true };
|
||||
bool IsPinVisible{ true };
|
||||
bool IsMinimum{};
|
||||
bool IsPinned{ true };
|
||||
bool IsVisible{};
|
||||
ImGuiWindow* ImWindow{ nullptr };
|
||||
ImU32 ActiveColour{ IM_COL32(227, 227, 255, 255) };
|
||||
ImU32 InactiveColour{ IM_COL32(182, 182, 182, 255) };
|
||||
|
||||
Window()
|
||||
{
|
||||
GetWindows().push_back(this);
|
||||
}
|
||||
|
||||
Window(const char* pName, EWindowFlags flags = eWindowFlags_None) : Name(pName), Flags(flags)
|
||||
{
|
||||
GetWindows().push_back(this);
|
||||
}
|
||||
|
||||
const char* GetName() override
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
void Draw() override
|
||||
{
|
||||
Begin();
|
||||
End();
|
||||
}
|
||||
|
||||
void SetMinimum(bool isMinimum);
|
||||
void SetVisible(bool isVisible = true);
|
||||
bool Begin(bool* pIsVisible = nullptr);
|
||||
void End();
|
||||
};
|
||||
|
||||
void InitWindowResources();
|
||||
}
|
||||
13
UnleashedRecomp/ui/reddog/windows/counter_window.cpp
Normal file
13
UnleashedRecomp/ui/reddog/windows/counter_window.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "counter_window.h"
|
||||
#include <gpu/video.h>
|
||||
|
||||
static CounterWindow g_window;
|
||||
|
||||
void CounterWindow::Draw()
|
||||
{
|
||||
if (Begin())
|
||||
{
|
||||
Video::DrawCounter();
|
||||
}
|
||||
End();
|
||||
}
|
||||
17
UnleashedRecomp/ui/reddog/windows/counter_window.h
Normal file
17
UnleashedRecomp/ui/reddog/windows/counter_window.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <ui/reddog/reddog_window.h>
|
||||
|
||||
class CounterWindow : public Reddog::Window
|
||||
{
|
||||
public:
|
||||
CounterWindow() : Window()
|
||||
{
|
||||
Name = "Counter";
|
||||
|
||||
m_minWidth = 215;
|
||||
m_minHeight = 328;
|
||||
}
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
21
UnleashedRecomp/ui/reddog/windows/exports_window.cpp
Normal file
21
UnleashedRecomp/ui/reddog/windows/exports_window.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "exports_window.h"
|
||||
#include <ui/reddog/reddog_controls.h>
|
||||
#include <user/config.h>
|
||||
|
||||
static ExportsWindow g_window;
|
||||
|
||||
void ExportsWindow::Draw()
|
||||
{
|
||||
if (Begin())
|
||||
{
|
||||
ImGui::TextColored({ 1, 0, 0, 1 }, "For testing purposes only, use Hedge Mod Manager to toggle these.");
|
||||
Reddog::Checkbox("Allow Cancelling Unleash", &Config::AllowCancellingUnleash.Value);
|
||||
Reddog::Checkbox("Disable Auto Save Warning", &Config::DisableAutoSaveWarning.Value);
|
||||
Reddog::Checkbox("Disable DLC Icon", &Config::DisableDLCIcon.Value);
|
||||
Reddog::Checkbox("Fix Unleash Out of Control Drain", &Config::FixUnleashOutOfControlDrain.Value);
|
||||
Reddog::Checkbox("Homing Attack on Boost", &Config::HomingAttackOnBoost.Value);
|
||||
Reddog::Checkbox("Save Score at Checkpoints", &Config::SaveScoreAtCheckpoints.Value);
|
||||
Reddog::Checkbox("Skip Intro Logos", &Config::SkipIntroLogos.Value);
|
||||
}
|
||||
End();
|
||||
}
|
||||
15
UnleashedRecomp/ui/reddog/windows/exports_window.h
Normal file
15
UnleashedRecomp/ui/reddog/windows/exports_window.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <ui/reddog/reddog_window.h>
|
||||
|
||||
class ExportsWindow : public Reddog::Window
|
||||
{
|
||||
public:
|
||||
ExportsWindow() : Window()
|
||||
{
|
||||
Name = "Exports";
|
||||
Flags = Reddog::eWindowFlags_NoResize;
|
||||
}
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
62
UnleashedRecomp/ui/reddog/windows/view_window.cpp
Normal file
62
UnleashedRecomp/ui/reddog/windows/view_window.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "view_window.h"
|
||||
#include <api/SWA.h>
|
||||
#include <gpu/video.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <ui/reddog/debug_draw.h>
|
||||
#include <ui/reddog/reddog_controls.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <user/config.h>
|
||||
|
||||
static ViewWindow g_window;
|
||||
|
||||
void ViewWindow::Draw()
|
||||
{
|
||||
if (Begin())
|
||||
{
|
||||
Reddog::Checkbox("Render FPS", &Config::ShowFPS.Value);
|
||||
|
||||
Reddog::Separator();
|
||||
|
||||
Reddog::Checkbox("Render HUD (F8)", SWA::SGlobals::ms_IsRenderHud);
|
||||
Reddog::Checkbox("Render Main Game HUD", SWA::SGlobals::ms_IsRenderGameMainHud);
|
||||
Reddog::Checkbox("Render Pause HUD", SWA::SGlobals::ms_IsRenderHudPause);
|
||||
|
||||
Reddog::Separator();
|
||||
|
||||
Reddog::Checkbox("Render Debug Draw", SWA::SGlobals::ms_IsRenderDebugDraw);
|
||||
Reddog::Checkbox("Render Debug Draw Text", SWA::SGlobals::ms_IsRenderDebugDrawText);
|
||||
Reddog::Checkbox("Render Debug Position Draw", SWA::SGlobals::ms_IsRenderDebugPositionDraw);
|
||||
|
||||
Reddog::Separator();
|
||||
|
||||
Reddog::Checkbox("Draw Light Field Sampling Point", SWA::SGlobals::ms_DrawLightFieldSamplingPoint);
|
||||
Reddog::Checkbox("Ignore Light Field Data", SWA::SGlobals::ms_IgnoreLightFieldData);
|
||||
Reddog::Checkbox("Light Field Debug", SWA::SGlobals::ms_LightFieldDebug);
|
||||
|
||||
Reddog::Separator();
|
||||
|
||||
Reddog::Checkbox("Visualize Loaded GI Mip Level", SWA::SGlobals::ms_VisualizeLoadedLevel);
|
||||
|
||||
Reddog::Separator();
|
||||
|
||||
Reddog::Checkbox("Render Event Collision", SWA::SGlobals::ms_IsTriggerRender);
|
||||
Reddog::Checkbox("Render Object Collision", SWA::SGlobals::ms_IsObjectCollisionRender);
|
||||
Reddog::Checkbox("Render Stage Collision", SWA::SGlobals::ms_IsCollisionRender);
|
||||
ImGui::TextColored({ 1, 0, 0, 1 }, "* Requires stage restart.");
|
||||
|
||||
Reddog::Separator();
|
||||
|
||||
if (Reddog::Button("Reset Window Dimensions (F2)"))
|
||||
{
|
||||
Config::Fullscreen = GameWindow::SetFullscreen(false);
|
||||
GameWindow::ResetDimensions();
|
||||
}
|
||||
|
||||
if (Reddog::Button("Recentre Window (F3)"))
|
||||
{
|
||||
if (!GameWindow::IsFullscreen())
|
||||
GameWindow::SetDimensions(GameWindow::s_width, GameWindow::s_height);
|
||||
}
|
||||
}
|
||||
End();
|
||||
}
|
||||
15
UnleashedRecomp/ui/reddog/windows/view_window.h
Normal file
15
UnleashedRecomp/ui/reddog/windows/view_window.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <ui/reddog/reddog_window.h>
|
||||
|
||||
class ViewWindow : public Reddog::Window
|
||||
{
|
||||
public:
|
||||
ViewWindow() : Window()
|
||||
{
|
||||
Name = "View";
|
||||
Flags = Reddog::eWindowFlags_NoResize;
|
||||
}
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
13
UnleashedRecomp/ui/reddog/windows/welcome_window.cpp
Normal file
13
UnleashedRecomp/ui/reddog/windows/welcome_window.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "welcome_window.h"
|
||||
|
||||
static WelcomeWindow g_window;
|
||||
|
||||
void WelcomeWindow::Draw()
|
||||
{
|
||||
if (Begin())
|
||||
{
|
||||
ImGui::TextColored({ 1, 0, 0, 1 }, "!!! ATTENTION !!!");
|
||||
ImGui::Text("For development use only.\nAny changes made here may cause unexpected behaviour.\nUse at your own risk!");
|
||||
}
|
||||
End();
|
||||
}
|
||||
20
UnleashedRecomp/ui/reddog/windows/welcome_window.h
Normal file
20
UnleashedRecomp/ui/reddog/windows/welcome_window.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <ui/game_window.h>
|
||||
#include <ui/reddog/reddog_window.h>
|
||||
|
||||
class WelcomeWindow : public Reddog::Window
|
||||
{
|
||||
public:
|
||||
WelcomeWindow() : Window()
|
||||
{
|
||||
Name = "Welcome";
|
||||
Flags = (Reddog::EWindowFlags)(Reddog::eWindowFlags_NoResize | Reddog::eWindowFlags_NoListEntry | Reddog::eWindowFlags_Centre);
|
||||
IsMinimumVisible = false;
|
||||
IsPinVisible = false;
|
||||
IsPinned = false;
|
||||
IsVisible = true;
|
||||
}
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
22
UnleashedRecomp/ui/reddog/windows/window_list.cpp
Normal file
22
UnleashedRecomp/ui/reddog/windows/window_list.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "window_list.h"
|
||||
#include <ui/reddog/reddog_controls.h>
|
||||
|
||||
static WindowList g_window;
|
||||
|
||||
void WindowList::Draw()
|
||||
{
|
||||
if (Begin())
|
||||
{
|
||||
for (auto& pWindow : Reddog::GetWindows())
|
||||
{
|
||||
auto pTrueWindow = (Reddog::Window*)pWindow;
|
||||
|
||||
if ((pTrueWindow->Flags & Reddog::eWindowFlags_NoListEntry) != 0)
|
||||
continue;
|
||||
|
||||
if (Reddog::ExplicitButton(pTrueWindow->Name, Reddog::EButtonTextAlignment::Left, { 190, 32 }, 1.1f))
|
||||
pTrueWindow->SetVisible();
|
||||
}
|
||||
}
|
||||
End();
|
||||
}
|
||||
20
UnleashedRecomp/ui/reddog/windows/window_list.h
Normal file
20
UnleashedRecomp/ui/reddog/windows/window_list.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <ui/reddog/reddog_window.h>
|
||||
|
||||
#define WINDOW_LIST_NAME "##WindowList"
|
||||
|
||||
class WindowList : public Reddog::Window
|
||||
{
|
||||
public:
|
||||
WindowList() : Window()
|
||||
{
|
||||
Name = WINDOW_LIST_NAME;
|
||||
Flags = (Reddog::EWindowFlags)(Reddog::eWindowFlags_NoTitleBar | Reddog::eWindowFlags_NoResize | Reddog::eWindowFlags_NoListEntry);
|
||||
ActiveColour = InactiveColour = IM_COL32_WHITE;
|
||||
|
||||
m_minWidth = m_minHeight = 0;
|
||||
}
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
@@ -608,6 +608,7 @@ public:
|
||||
CONFIG_DEFINE_LOCALISED("System", bool, ControlTutorial, true);
|
||||
CONFIG_DEFINE_LOCALISED("System", bool, AchievementNotifications, true);
|
||||
CONFIG_DEFINE_ENUM_LOCALISED("System", ETimeOfDayTransition, TimeOfDayTransition, ETimeOfDayTransition::Xbox);
|
||||
CONFIG_DEFINE_HIDDEN("System", bool, Debug, false);
|
||||
|
||||
CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraX, false);
|
||||
CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraY, false);
|
||||
@@ -676,6 +677,8 @@ public:
|
||||
CONFIG_DEFINE_ENUM_LOCALISED("Video", ECutsceneAspectRatio, CutsceneAspectRatio, ECutsceneAspectRatio::Original);
|
||||
CONFIG_DEFINE_ENUM_LOCALISED("Video", EUIScaleMode, UIScaleMode, EUIScaleMode::Edge);
|
||||
|
||||
CONFIG_DEFINE_HIDDEN("Debug", bool, ShowFPS, false);
|
||||
|
||||
CONFIG_DEFINE_HIDDEN("Exports", bool, AllowCancellingUnleash, false);
|
||||
CONFIG_DEFINE_HIDDEN("Exports", bool, DisableAutoSaveWarning, false);
|
||||
CONFIG_DEFINE_HIDDEN("Exports", bool, DisableDLCIcon, false);
|
||||
|
||||
Submodule UnleashedRecompResources updated: 2817764f59...263812fd18
Reference in New Issue
Block a user