mirror of
https://github.com/hedge-dev/UnleashedRecomp
synced 2026-06-09 04:40:26 -04:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c357062de8 | |||
| fc51d0e7ae | |||
| f4406cd8d0 | |||
| 2af11c8d2f | |||
| dd54867e58 | |||
| 4b358d8e43 | |||
| 110f341af6 | |||
| 00e148b182 | |||
| eb3225c2f7 | |||
| 4ab26a1696 | |||
| 72a0a17e3a | |||
| 35b9361a91 | |||
| 7788e36704 | |||
| 023fc0edf7 | |||
| d5ca843716 | |||
| dbdf020218 | |||
| d5e947f520 | |||
| a7e004fb60 | |||
| 892e24f71e | |||
| 72a0507c66 | |||
| 2f68ee5df2 |
@@ -155,6 +155,7 @@ set(SWA_PATCHES_CXX_SOURCES
|
|||||||
"patches/aspect_ratio_patches.cpp"
|
"patches/aspect_ratio_patches.cpp"
|
||||||
"patches/audio_patches.cpp"
|
"patches/audio_patches.cpp"
|
||||||
"patches/camera_patches.cpp"
|
"patches/camera_patches.cpp"
|
||||||
|
"patches/debug_patches.cpp"
|
||||||
"patches/fps_patches.cpp"
|
"patches/fps_patches.cpp"
|
||||||
"patches/inspire_patches.cpp"
|
"patches/inspire_patches.cpp"
|
||||||
"patches/misc_patches.cpp"
|
"patches/misc_patches.cpp"
|
||||||
@@ -165,6 +166,15 @@ set(SWA_PATCHES_CXX_SOURCES
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SWA_UI_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_menu.cpp"
|
||||||
"ui/achievement_overlay.cpp"
|
"ui/achievement_overlay.cpp"
|
||||||
"ui/installer_wizard.cpp"
|
"ui/installer_wizard.cpp"
|
||||||
@@ -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/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_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/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/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_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")
|
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")
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
be<float> W;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "Vector.inl"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Hedgehog::Math
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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/Type/hhSharedString.h"
|
||||||
#include "Hedgehog/Base/hhObject.h"
|
#include "Hedgehog/Base/hhObject.h"
|
||||||
#include "Hedgehog/Database/System/hhDatabaseData.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/Math/Vector.h"
|
||||||
|
#include "Hedgehog/MirageCore/Camera/hhCamera.h"
|
||||||
#include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h"
|
#include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhMaterialData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhMaterialData.h"
|
||||||
#include "Hedgehog/MirageCore/RenderData/hhMeshData.h"
|
#include "Hedgehog/MirageCore/RenderData/hhMeshData.h"
|
||||||
@@ -57,6 +61,7 @@
|
|||||||
#include "SWA/CSD/CsdTexListMirage.h"
|
#include "SWA/CSD/CsdTexListMirage.h"
|
||||||
#include "SWA/CSD/GameObjectCSD.h"
|
#include "SWA/CSD/GameObjectCSD.h"
|
||||||
#include "SWA/Camera/Camera.h"
|
#include "SWA/Camera/Camera.h"
|
||||||
|
#include "SWA/Globals.h"
|
||||||
#include "SWA/HUD/GeneralWindow/GeneralWindow.h"
|
#include "SWA/HUD/GeneralWindow/GeneralWindow.h"
|
||||||
#include "SWA/HUD/Loading/Loading.h"
|
#include "SWA/HUD/Loading/Loading.h"
|
||||||
#include "SWA/HUD/Pause/HudPause.h"
|
#include "SWA/HUD/Pause/HudPause.h"
|
||||||
@@ -73,6 +78,8 @@
|
|||||||
#include "SWA/Inspire/InspireTextureOverlayInfo.h"
|
#include "SWA/Inspire/InspireTextureOverlayInfo.h"
|
||||||
#include "SWA/Movie/MovieDisplayer.h"
|
#include "SWA/Movie/MovieDisplayer.h"
|
||||||
#include "SWA/Movie/MovieManager.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/EvilSonic.h"
|
||||||
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
|
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
|
||||||
#include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h"
|
#include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h"
|
||||||
@@ -98,6 +105,7 @@
|
|||||||
#include "SWA/System/GammaController.h"
|
#include "SWA/System/GammaController.h"
|
||||||
#include "SWA/System/InputState.h"
|
#include "SWA/System/InputState.h"
|
||||||
#include "SWA/System/PadState.h"
|
#include "SWA/System/PadState.h"
|
||||||
|
#include "SWA/System/StageManager.h"
|
||||||
#include "SWA/System/World.h"
|
#include "SWA/System/World.h"
|
||||||
#include "boost/smart_ptr/make_shared_object.h"
|
#include "boost/smart_ptr/make_shared_object.h"
|
||||||
#include "boost/smart_ptr/shared_ptr.h"
|
#include "boost/smart_ptr/shared_ptr.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace SWA
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
xpointer<void> m_pVftable;
|
xpointer<void> m_pVftable;
|
||||||
|
// SWA::CCamera::MyCamera
|
||||||
SWA_INSERT_PADDING(0xC4);
|
SWA_INSERT_PADDING(0xC4);
|
||||||
be<float> m_VertAspectRatio;
|
be<float> m_VertAspectRatio;
|
||||||
SWA_INSERT_PADDING(0x48);
|
SWA_INSERT_PADDING(0x48);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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(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;
|
boost::shared_ptr<Hedgehog::Database::CDatabase> m_spDatabase;
|
||||||
SWA_INSERT_PADDING(0x88);
|
SWA_INSERT_PADDING(0x88);
|
||||||
Hedgehog::Base::CSharedString m_StageName;
|
Hedgehog::Base::CSharedString m_StageName;
|
||||||
|
|||||||
@@ -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
|
class CMember
|
||||||
{
|
{
|
||||||
public:
|
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;
|
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"
|
||||||
|
|||||||
@@ -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 <app.h>
|
||||||
|
#include <api/SWA.h>
|
||||||
#include <gpu/video.h>
|
#include <gpu/video.h>
|
||||||
#include <install/installer.h>
|
#include <install/installer.h>
|
||||||
#include <kernel/function.h>
|
#include <kernel/function.h>
|
||||||
@@ -33,6 +34,8 @@ PPC_FUNC(sub_824EB490)
|
|||||||
App::s_isMissingDLC = !Installer::checkAllDLC(GetGamePath());
|
App::s_isMissingDLC = !Installer::checkAllDLC(GetGamePath());
|
||||||
App::s_language = Config::Language;
|
App::s_language = Config::Language;
|
||||||
|
|
||||||
|
SWA::SGlobals::Init();
|
||||||
|
|
||||||
__imp__sub_824EB490(ctx, base);
|
__imp__sub_824EB490(ctx, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <res/font/im_font_atlas.dds.h>
|
#include <res/font/im_font_atlas.dds.h>
|
||||||
#include <shader/shader_cache.h>
|
#include <shader/shader_cache.h>
|
||||||
#include <SWA.h>
|
#include <SWA.h>
|
||||||
|
#include <ui/reddog/reddog_manager.h>
|
||||||
#include <ui/achievement_menu.h>
|
#include <ui/achievement_menu.h>
|
||||||
#include <ui/achievement_overlay.h>
|
#include <ui/achievement_overlay.h>
|
||||||
#include <ui/button_guide.h>
|
#include <ui/button_guide.h>
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
#include <ui/options_menu.h>
|
#include <ui/options_menu.h>
|
||||||
#include <ui/sdl_listener.h>
|
#include <ui/sdl_listener.h>
|
||||||
#include <ui/game_window.h>
|
#include <ui/game_window.h>
|
||||||
|
#include <ui/imgui_utils.h>
|
||||||
#include <patches/aspect_ratio_patches.h>
|
#include <patches/aspect_ratio_patches.h>
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
#include <xxHashMap.h>
|
#include <xxHashMap.h>
|
||||||
@@ -1192,9 +1194,16 @@ static void CreateImGuiBackend()
|
|||||||
AchievementMenu::Init();
|
AchievementMenu::Init();
|
||||||
AchievementOverlay::Init();
|
AchievementOverlay::Init();
|
||||||
ButtonGuide::Init();
|
ButtonGuide::Init();
|
||||||
|
InstallerWizard::Init();
|
||||||
MessageWindow::Init();
|
MessageWindow::Init();
|
||||||
OptionsMenu::Init();
|
OptionsMenu::Init();
|
||||||
InstallerWizard::Init();
|
|
||||||
|
#if !_DEBUG
|
||||||
|
if (Config::Debug)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Reddog::Manager::Init();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui_ImplSDL2_InitForOther(GameWindow::s_pWindow);
|
ImGui_ImplSDL2_InitForOther(GameWindow::s_pWindow);
|
||||||
|
|
||||||
@@ -1965,28 +1974,8 @@ static double g_applicationValues[PROFILER_VALUE_COUNT];
|
|||||||
static Profiler g_presentProfiler;
|
static Profiler g_presentProfiler;
|
||||||
static Profiler g_renderDirectorProfiler;
|
static Profiler g_renderDirectorProfiler;
|
||||||
|
|
||||||
static bool g_profilerVisible;
|
void Video::DrawCounter()
|
||||||
static bool g_profilerWasToggled;
|
|
||||||
|
|
||||||
static void DrawProfiler()
|
|
||||||
{
|
{
|
||||||
bool toggleProfiler = SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_F1] != 0;
|
|
||||||
|
|
||||||
if (!g_profilerWasToggled && toggleProfiler)
|
|
||||||
g_profilerVisible = !g_profilerVisible;
|
|
||||||
|
|
||||||
g_profilerWasToggled = toggleProfiler;
|
|
||||||
|
|
||||||
if (!g_profilerVisible)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImFont* font = ImFontAtlasSnapshot::GetFont("FOT-SeuratPro-M.otf");
|
|
||||||
float defaultScale = font->Scale;
|
|
||||||
font->Scale = ImGui::GetDefaultFont()->FontSize / font->FontSize;
|
|
||||||
ImGui::PushFont(font);
|
|
||||||
|
|
||||||
if (ImGui::Begin("Profiler", &g_profilerVisible))
|
|
||||||
{
|
|
||||||
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
||||||
|
|
||||||
const double applicationAvg = std::accumulate(g_applicationValues, g_applicationValues + PROFILER_VALUE_COUNT, 0.0) / PROFILER_VALUE_COUNT;
|
const double applicationAvg = std::accumulate(g_applicationValues, g_applicationValues + PROFILER_VALUE_COUNT, 0.0) / PROFILER_VALUE_COUNT;
|
||||||
@@ -2029,18 +2018,33 @@ static void DrawProfiler()
|
|||||||
ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
|
ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
|
|
||||||
ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");
|
auto capabilities = g_device->getCapabilities();
|
||||||
ImGui::Text("Triangle Fan: %s", g_capabilities.triangleFan ? "Supported" : "Unsupported");
|
ImGui::Text("Present Wait: %s", capabilities.presentWait ? "Supported" : "Unsupported");
|
||||||
|
ImGui::Text("Triangle Fan: %s", capabilities.triangleFan ? "Supported" : "Unsupported");
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
|
|
||||||
const char* sdlVideoDriver = SDL_GetCurrentVideoDriver();
|
const char* sdlVideoDriver = SDL_GetCurrentVideoDriver();
|
||||||
if (sdlVideoDriver != nullptr)
|
if (sdlVideoDriver != nullptr)
|
||||||
ImGui::Text("SDL Video Driver: %s", sdlVideoDriver);
|
ImGui::Text("SDL Video Driver: %s", sdlVideoDriver);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
ImGui::PopFont();
|
void Video::DrawFPS(ImFont* font)
|
||||||
font->Scale = defaultScale;
|
{
|
||||||
|
if (!Config::ShowFPS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto drawList = ImGui::GetBackgroundDrawList();
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
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) };
|
||||||
|
|
||||||
|
drawList->AddRectFilled(min, max, IM_COL32(0, 0, 0, 255));
|
||||||
|
drawList->AddText(font, fontSize, textPos, IM_COL32_WHITE, fmt.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawImGui()
|
static void DrawImGui()
|
||||||
@@ -2076,7 +2080,12 @@ static void DrawImGui()
|
|||||||
ButtonGuide::Draw();
|
ButtonGuide::Draw();
|
||||||
Fader::Draw();
|
Fader::Draw();
|
||||||
|
|
||||||
DrawProfiler();
|
#if !_DEBUG
|
||||||
|
if (Config::Debug)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Reddog::Manager::Draw();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
@@ -3395,7 +3404,7 @@ static RenderPipeline* CreateGraphicsPipelineInRenderThread(PipelineState pipeli
|
|||||||
pipeline = CreateGraphicsPipeline(pipelineState);
|
pipeline = CreateGraphicsPipeline(pipelineState);
|
||||||
|
|
||||||
#ifdef ASYNC_PSO_DEBUG
|
#ifdef ASYNC_PSO_DEBUG
|
||||||
bool loading = *reinterpret_cast<bool*>(g_memory.Translate(0x83367A4C));
|
bool loading = *SWA::SGlobals::ms_IsLoading;
|
||||||
|
|
||||||
if (loading)
|
if (loading)
|
||||||
++g_pipelinesCreatedAsynchronously;
|
++g_pipelinesCreatedAsynchronously;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ struct Video
|
|||||||
static void Present();
|
static void Present();
|
||||||
static void StartPipelinePrecompilation();
|
static void StartPipelinePrecompilation();
|
||||||
static void WaitForGPU();
|
static void WaitForGPU();
|
||||||
|
static void DrawCounter();
|
||||||
|
static void DrawFPS(ImFont* font);
|
||||||
static struct GuestSurface* GetBackBuffer();
|
static struct GuestSurface* GetBackBuffer();
|
||||||
static void ComputeViewportDimensions();
|
static void ComputeViewportDimensions();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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_ppcContext->f1.f64 = deltaTime;
|
||||||
g_memory.FindFunction(update)(*g_ppcContext, base);
|
g_memory.FindFunction(update)(*g_ppcContext, base);
|
||||||
|
|
||||||
bool loading = PPC_LOAD_U8(0x83367A4C);
|
if (*SWA::SGlobals::ms_IsLoading)
|
||||||
if (loading)
|
|
||||||
{
|
{
|
||||||
now = std::chrono::steady_clock::now();
|
now = std::chrono::steady_clock::now();
|
||||||
constexpr auto INTERVAL = 1000000000ns / 30;
|
constexpr auto INTERVAL = 1000000000ns / 30;
|
||||||
@@ -104,7 +103,7 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31)
|
|||||||
std::this_thread::sleep_until(next);
|
std::this_thread::sleep_until(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
return loading;
|
return *SWA::SGlobals::ms_IsLoading;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADXM_WaitVsync
|
// ADXM_WaitVsync
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <api/SWA.h>
|
#include <api/SWA.h>
|
||||||
|
#include <ui/reddog/debug_draw.h>
|
||||||
#include <ui/game_window.h>
|
#include <ui/game_window.h>
|
||||||
#include <user/achievement_data.h>
|
#include <user/achievement_data.h>
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
|
|||||||
@@ -159,9 +159,7 @@ PPC_FUNC(sub_824B0930)
|
|||||||
{
|
{
|
||||||
g_achievementMenuIntroTime = 0;
|
g_achievementMenuIntroTime = 0;
|
||||||
|
|
||||||
const auto ms_IsRenderHud = (bool*)g_memory.Translate(0x8328BB26);
|
if (*SWA::SGlobals::ms_IsRenderHud && pHudPause->m_IsShown && pHudPause->m_Transition == SWA::eTransitionType_Undefined)
|
||||||
|
|
||||||
if (*ms_IsRenderHud && pHudPause->m_IsShown && pHudPause->m_Transition == SWA::eTransitionType_Undefined)
|
|
||||||
{
|
{
|
||||||
ButtonGuide::Open(Button(Localise("Achievements_Name"), EButtonIcon::Back, EButtonAlignment::Left, EFontQuality::Low));
|
ButtonGuide::Open(Button(Localise("Achievements_Name"), EButtonIcon::Back, EButtonAlignment::Left, EFontQuality::Low));
|
||||||
g_isClosed = false;
|
g_isClosed = false;
|
||||||
|
|||||||
@@ -1,3 +1,34 @@
|
|||||||
#include "frontend_listener.h"
|
#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
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/memory.h>
|
|
||||||
#include <ui/sdl_listener.h>
|
#include <ui/sdl_listener.h>
|
||||||
#include <ui/options_menu.h>
|
|
||||||
#include <os/logger.h>
|
|
||||||
|
|
||||||
class FrontendListener : public SDLEventListener
|
class FrontendListener : public SDLEventListener
|
||||||
{
|
{
|
||||||
bool m_isF8KeyDown = false;
|
bool m_isF8KeyDown = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void OnSDLEvent(SDL_Event* event) override
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,11 @@
|
|||||||
#pragma comment(lib, "dwmapi.lib")
|
#pragma comment(lib, "dwmapi.lib")
|
||||||
#endif
|
#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.bmp.h>
|
||||||
#include <res/images/game_icon_night.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;
|
GameWindow::s_isFocused = true;
|
||||||
|
|
||||||
if (GameWindow::IsFullscreen())
|
if (GameWindow::IsFullscreen())
|
||||||
SDL_ShowCursor(GameWindow::s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
SDL_ShowCursor(GameWindow::s_isCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||||
|
|
||||||
break;
|
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)
|
if (event->type == SDL_CONTROLLERBUTTONDOWN || event->type == SDL_CONTROLLERBUTTONUP || event->type == SDL_CONTROLLERAXISMOTION)
|
||||||
{
|
{
|
||||||
// Hide mouse cursor when controller input is detected.
|
// 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)
|
else if (event->type == SDL_MOUSEMOTION)
|
||||||
{
|
{
|
||||||
@@ -264,23 +269,23 @@ void GameWindow::Update()
|
|||||||
s_isChangingDisplay = false;
|
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);
|
auto surface = SDL_LoadBMP_RW(rw, 1);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
LOGF_ERROR("Failed to load icon: {}", SDL_GetError());
|
LOGF_ERROR("Failed to create surface: {}", SDL_GetError());
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWindow::SetIcon(void* pIconBmp, size_t iconSize)
|
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_SetWindowIcon(s_pWindow, surface);
|
||||||
SDL_FreeSurface(icon);
|
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()
|
const char* GameWindow::GetTitle()
|
||||||
{
|
{
|
||||||
return Config::Language == ELanguage::Japanese
|
return Config::Language == ELanguage::Japanese
|
||||||
@@ -338,7 +406,7 @@ bool GameWindow::SetFullscreen(bool isEnabled)
|
|||||||
if (isEnabled)
|
if (isEnabled)
|
||||||
{
|
{
|
||||||
SDL_SetWindowFullscreen(s_pWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -352,13 +420,13 @@ bool GameWindow::SetFullscreen(bool isEnabled)
|
|||||||
return isEnabled;
|
return isEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWindow::SetFullscreenCursorVisibility(bool isVisible)
|
void GameWindow::SetCursorVisibility(bool isVisible)
|
||||||
{
|
{
|
||||||
s_isFullscreenCursorVisible = isVisible;
|
s_isCursorVisible = isVisible;
|
||||||
|
|
||||||
if (IsFullscreen())
|
if (IsFullscreen())
|
||||||
{
|
{
|
||||||
SDL_ShowCursor(s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
SDL_ShowCursor(s_isCursorVisible ? SDL_ENABLE : SDL_DISABLE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -422,6 +490,8 @@ void GameWindow::ResetDimensions()
|
|||||||
Config::WindowY = s_y;
|
Config::WindowY = s_y;
|
||||||
Config::WindowWidth = s_width;
|
Config::WindowWidth = s_width;
|
||||||
Config::WindowHeight = s_height;
|
Config::WindowHeight = s_height;
|
||||||
|
|
||||||
|
SetDimensions(s_width, s_height, s_x, s_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GameWindow::GetWindowFlags()
|
uint32_t GameWindow::GetWindowFlags()
|
||||||
|
|||||||
@@ -9,6 +9,16 @@
|
|||||||
#define MIN_WIDTH 640
|
#define MIN_WIDTH 640
|
||||||
#define MIN_HEIGHT 480
|
#define MIN_HEIGHT 480
|
||||||
|
|
||||||
|
enum class ECursorType
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
DebugDefault,
|
||||||
|
DebugHorizontal,
|
||||||
|
DebugVertical,
|
||||||
|
DebugLeftDiagonal,
|
||||||
|
DebugRightDiagonal
|
||||||
|
};
|
||||||
|
|
||||||
class GameWindow
|
class GameWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -22,18 +32,21 @@ public:
|
|||||||
|
|
||||||
static inline bool s_isFocused;
|
static inline bool s_isFocused;
|
||||||
static inline bool s_isIconNight;
|
static inline bool s_isIconNight;
|
||||||
static inline bool s_isFullscreenCursorVisible;
|
static inline bool s_isCursorVisible;
|
||||||
static inline bool s_isChangingDisplay;
|
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(void* pIconBmp, size_t iconSize);
|
||||||
static void SetIcon(bool isNight = false);
|
static void SetIcon(bool isNight = false);
|
||||||
|
static void SetCursor(ECursorType cursorType = ECursorType::Default);
|
||||||
static const char* GetTitle();
|
static const char* GetTitle();
|
||||||
static void SetTitle(const char* title = nullptr);
|
static void SetTitle(const char* title = nullptr);
|
||||||
static void SetTitleBarColour();
|
static void SetTitleBarColour();
|
||||||
static bool IsFullscreen();
|
static bool IsFullscreen();
|
||||||
static bool SetFullscreen(bool isEnabled);
|
static bool SetFullscreen(bool isEnabled);
|
||||||
static void SetFullscreenCursorVisibility(bool isVisible);
|
static void SetCursorVisibility(bool isVisible);
|
||||||
static bool IsMaximised();
|
static bool IsMaximised();
|
||||||
static EWindowState SetMaximised(bool isEnabled);
|
static EWindowState SetMaximised(bool isEnabled);
|
||||||
static SDL_Rect GetDimensions();
|
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);
|
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)
|
inline float CalcWidestTextSize(const ImFont* font, float fontSize, std::span<std::string> strs)
|
||||||
{
|
{
|
||||||
auto result = 0.0f;
|
auto result = 0.0f;
|
||||||
|
|||||||
@@ -1556,7 +1556,7 @@ bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame)
|
|||||||
g_currentPage = g_firstPage;
|
g_currentPage = g_firstPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameWindow::SetFullscreenCursorVisibility(true);
|
GameWindow::SetCursorVisibility(true);
|
||||||
s_isVisible = true;
|
s_isVisible = true;
|
||||||
|
|
||||||
while (s_isVisible)
|
while (s_isVisible)
|
||||||
@@ -1568,7 +1568,7 @@ bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame)
|
|||||||
Video::Present();
|
Video::Present();
|
||||||
}
|
}
|
||||||
|
|
||||||
GameWindow::SetFullscreenCursorVisibility(false);
|
GameWindow::SetCursorVisibility(false);
|
||||||
NFD_Quit();
|
NFD_Quit();
|
||||||
|
|
||||||
InstallerWizard::Shutdown();
|
InstallerWizard::Shutdown();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#include "counter_window.h"
|
||||||
|
#include <gpu/video.h>
|
||||||
|
|
||||||
|
static CounterWindow g_window;
|
||||||
|
|
||||||
|
void CounterWindow::Draw()
|
||||||
|
{
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
Video::DrawCounter();
|
||||||
|
}
|
||||||
|
End();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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, ControlTutorial, true);
|
||||||
CONFIG_DEFINE_LOCALISED("System", bool, AchievementNotifications, true);
|
CONFIG_DEFINE_LOCALISED("System", bool, AchievementNotifications, true);
|
||||||
CONFIG_DEFINE_ENUM_LOCALISED("System", ETimeOfDayTransition, TimeOfDayTransition, ETimeOfDayTransition::Xbox);
|
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, InvertCameraX, false);
|
||||||
CONFIG_DEFINE_LOCALISED("Input", bool, InvertCameraY, 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", ECutsceneAspectRatio, CutsceneAspectRatio, ECutsceneAspectRatio::Original);
|
||||||
CONFIG_DEFINE_ENUM_LOCALISED("Video", EUIScaleMode, UIScaleMode, EUIScaleMode::Edge);
|
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, AllowCancellingUnleash, false);
|
||||||
CONFIG_DEFINE_HIDDEN("Exports", bool, DisableAutoSaveWarning, false);
|
CONFIG_DEFINE_HIDDEN("Exports", bool, DisableAutoSaveWarning, false);
|
||||||
CONFIG_DEFINE_HIDDEN("Exports", bool, DisableDLCIcon, false);
|
CONFIG_DEFINE_HIDDEN("Exports", bool, DisableDLCIcon, false);
|
||||||
|
|||||||
+1
-1
Submodule UnleashedRecompResources updated: 2817764f59...263812fd18
Reference in New Issue
Block a user