mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-11 10:31:16 +00:00
More debug features: pause/step/resume (#140)
* More debug features: pause/step/resume
* Fix palette order (I think)
* Revert "Fix palette order (I think)"
This reverts commit a81de08f78.
This commit is contained in:
parent
911330e61c
commit
183efa3d8f
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -2,6 +2,10 @@ name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
name: 'clang-format'
|
||||
|
||||
@ -353,13 +353,13 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
if (!g_debugEnabled) {
|
||||
if (!IsleDebug_Enabled()) {
|
||||
g_isle->SetWindowActive(TRUE);
|
||||
Lego()->Resume();
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
if (!g_debugEnabled) {
|
||||
if (!IsleDebug_Enabled()) {
|
||||
g_isle->SetWindowActive(FALSE);
|
||||
Lego()->Pause();
|
||||
}
|
||||
@ -722,6 +722,10 @@ inline bool IsleApp::Tick()
|
||||
// GLOBAL: ISLE 0x4101bc
|
||||
static MxS32 g_startupDelay = 200;
|
||||
|
||||
if (IsleDebug_Paused() && IsleDebug_StepModeEnabled()) {
|
||||
IsleDebug_SetPaused(false);
|
||||
}
|
||||
|
||||
if (!m_windowActive) {
|
||||
SDL_Delay(1);
|
||||
return true;
|
||||
@ -752,6 +756,11 @@ inline bool IsleApp::Tick()
|
||||
}
|
||||
g_lastFrameTime = currentTime;
|
||||
|
||||
if (IsleDebug_StepModeEnabled()) {
|
||||
IsleDebug_SetPaused(true);
|
||||
IsleDebug_ResetStepMode();
|
||||
}
|
||||
|
||||
if (g_startupDelay == 0) {
|
||||
return true;
|
||||
}
|
||||
@ -845,7 +854,7 @@ MxResult IsleApp::ParseArguments(int argc, char** argv)
|
||||
}
|
||||
#ifdef ISLE_DEBUG
|
||||
else if (strcmp(argv[i], "--debug") == 0) {
|
||||
g_debugEnabled = true;
|
||||
IsleDebug_SetEnabled(true);
|
||||
consumed = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,22 +1,150 @@
|
||||
#include "isledebug.h"
|
||||
|
||||
#include "isleapp.h"
|
||||
#include "lego/sources/roi/legoroi.h"
|
||||
#include "legobuildingmanager.h"
|
||||
#include "legoentity.h"
|
||||
#include "legogamestate.h"
|
||||
#include "legoplantmanager.h"
|
||||
#include "legosoundmanager.h"
|
||||
#include "legovideomanager.h"
|
||||
#include "misc.h"
|
||||
#include "mxticklemanager.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <backends/imgui_impl_sdl3.h>
|
||||
#include <backends/imgui_impl_sdlrenderer3.h>
|
||||
#include <imgui.h>
|
||||
|
||||
bool g_debugEnabled;
|
||||
bool g_debugPaused;
|
||||
SDL_Window* g_debugWindow;
|
||||
SDL_Renderer* g_debugRenderer;
|
||||
#define SCANCODE_KEY_PAUSE SDL_SCANCODE_KP_0
|
||||
#define SCANCODE_KEY_RESUME SDL_SCANCODE_KP_PERIOD
|
||||
|
||||
static bool g_debugEnabled;
|
||||
static bool g_debugPaused;
|
||||
static bool g_debugDoStep;
|
||||
static SDL_Window* g_debugWindow;
|
||||
static SDL_Renderer* g_debugRenderer;
|
||||
|
||||
static SDL_Texture* g_videoPalette;
|
||||
|
||||
class DebugViewer {
|
||||
public:
|
||||
static void InsidePlantManager()
|
||||
{
|
||||
LegoPlantManager* plantManager = Lego()->GetPlantManager();
|
||||
ImGui::Value("#plants", plantManager->GetNumPlants());
|
||||
ImGui::Value("#entries", plantManager->m_numEntries);
|
||||
if (plantManager->m_numEntries) {
|
||||
if (ImGui::BeginTable("Animated Entries", 4, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("ROI Name");
|
||||
ImGui::TableSetupColumn("ROI m_unk0x100");
|
||||
ImGui::TableSetupColumn("Entity Name");
|
||||
ImGui::TableSetupColumn("Time");
|
||||
ImGui::TableHeadersRow();
|
||||
for (MxS8 i = 0; i < plantManager->m_numEntries; i++) {
|
||||
const auto* entry = plantManager->m_entries[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::Text("%s", entry->m_roi->m_name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_roi->m_unk0x100);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", entry->m_roi->m_entity->ClassName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_time);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
static void InsideBuildingManager()
|
||||
{
|
||||
auto buildingManager = Lego()->GetBuildingManager();
|
||||
ImGui::Text("nextVariant: %d", buildingManager->m_nextVariant);
|
||||
ImGui::Text("m_unk0x09: %d", buildingManager->m_unk0x09);
|
||||
ImGui::Text("m_unk0x28: %d", buildingManager->m_unk0x28);
|
||||
ImGui::Text("#Animated Entries", buildingManager->m_numEntries);
|
||||
if (buildingManager->m_numEntries) {
|
||||
if (ImGui::BeginTable("Animated Entries", 6, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("ROI Name");
|
||||
ImGui::TableSetupColumn("ROI m_unk0x100");
|
||||
ImGui::TableSetupColumn("Entity Name");
|
||||
ImGui::TableSetupColumn("Time");
|
||||
ImGui::TableSetupColumn("unk_0x0c");
|
||||
ImGui::TableSetupColumn("Muted");
|
||||
ImGui::TableHeadersRow();
|
||||
for (MxS8 i = 0; i < buildingManager->m_numEntries; i++) {
|
||||
const auto* entry = buildingManager->m_entries[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::Text("%s", entry->m_roi->m_name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_roi->m_unk0x100);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", entry->m_roi->m_entity->ClassName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_time);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_unk0x0c);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_muted);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
static void InsideTickleManager()
|
||||
{
|
||||
auto tickleManager = Lego()->GetTickleManager();
|
||||
ImGui::Value("#clients", static_cast<int>(tickleManager->m_clients.size()));
|
||||
if (ImGui::BeginTable("Clients", 3, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("Client");
|
||||
ImGui::TableSetupColumn("Interval");
|
||||
ImGui::TableSetupColumn("Flags");
|
||||
ImGui::TableHeadersRow();
|
||||
for (const auto* ticleClient : tickleManager->m_clients) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", ticleClient->GetClient()->ClassName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", ticleClient->GetTickleInterval());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("0x%x", ticleClient->GetFlags());
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
static void InsideVideoManager()
|
||||
{
|
||||
auto videoManager = Lego()->GetVideoManager();
|
||||
SDL_UpdateTexture(g_videoPalette, NULL, videoManager->m_paletteEntries, 4 * 16);
|
||||
ImGui::Text("Elapsed: %gs", static_cast<float>(videoManager->GetElapsedSeconds()));
|
||||
ImGui::Text("Render3D: %d", videoManager->GetRender3D());
|
||||
ImGui::Text("unk0xe5: %d", videoManager->m_unk0xe5);
|
||||
ImGui::Text("unk0xe5: %d", videoManager->m_unk0xe6);
|
||||
ImGui::Text("unk0x54c: %f", videoManager->m_unk0x54c);
|
||||
ImGui::Text("unk0x54c: %f", videoManager->m_unk0x550);
|
||||
ImGui::Text("unk0x54c: %d", videoManager->m_unk0x554);
|
||||
ImGui::Text("unk0x70: %u", videoManager->m_unk0x70);
|
||||
ImGui::Text("Dither: %d", videoManager->m_dither);
|
||||
ImGui::Text("BufferCount: %u", videoManager->m_bufferCount);
|
||||
ImGui::Text("Paused: %f", videoManager->m_paused);
|
||||
ImGui::Text("back: %g", videoManager->m_back);
|
||||
ImGui::Text("front: %g", videoManager->m_front);
|
||||
ImGui::Text("cameraWidth: %g", videoManager->m_cameraWidth);
|
||||
ImGui::Text("cameraHeight: %g", videoManager->m_cameraHeight);
|
||||
ImGui::Text("fov: %g", videoManager->m_fov);
|
||||
ImVec2 uv_min = ImVec2(0.0f, 0.0f);
|
||||
ImVec2 uv_max = ImVec2(1.0f, 1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, SDL_max(1.0f, ImGui::GetStyle().ImageBorderSize));
|
||||
ImGui::ImageWithBg(
|
||||
(ImTextureID) (uintptr_t) g_videoPalette,
|
||||
ImVec2(200, 200),
|
||||
uv_min,
|
||||
uv_max,
|
||||
ImVec4(0.0f, 0.0f, 0.0f, 1.0f)
|
||||
);
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
};
|
||||
|
||||
void IsleDebug_Init()
|
||||
{
|
||||
@ -38,11 +166,15 @@ void IsleDebug_Init()
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
if (!ImGui_ImplSDL3_InitForSDLRenderer(g_debugWindow, g_debugRenderer)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ImGui_ImplSDL3_InitForSDLRenderer failed");
|
||||
g_debugEnabled = false;
|
||||
break;
|
||||
}
|
||||
g_videoPalette =
|
||||
SDL_CreateTexture(g_debugRenderer, SDL_PIXELFORMAT_RGBX32, SDL_TEXTUREACCESS_STREAMING, 16, 16);
|
||||
SDL_SetTextureScaleMode(g_videoPalette, SDL_SCALEMODE_PIXELART);
|
||||
if (!ImGui_ImplSDLRenderer3_Init(g_debugRenderer)) {
|
||||
g_debugEnabled = false;
|
||||
break;
|
||||
@ -65,6 +197,24 @@ bool IsleDebug_Event(SDL_Event* event)
|
||||
if (!g_debugEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (event->type == SDL_EVENT_KEY_DOWN) {
|
||||
if (event->key.scancode == SCANCODE_KEY_PAUSE) {
|
||||
if (!g_debugPaused) {
|
||||
IsleDebug_SetPaused(true);
|
||||
}
|
||||
else {
|
||||
g_debugDoStep = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (event->key.scancode == SCANCODE_KEY_RESUME) {
|
||||
g_debugDoStep = false;
|
||||
if (g_debugPaused) {
|
||||
IsleDebug_SetPaused(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (SDL_GetWindowFromEvent(event) != g_debugWindow) {
|
||||
return false;
|
||||
}
|
||||
@ -97,6 +247,7 @@ void IsleDebug_Render()
|
||||
}
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
ImGui::ShowDemoWindow(nullptr);
|
||||
LegoOmni* lego = Lego();
|
||||
if (ImGui::Begin("LEGO")) {
|
||||
if (ImGui::TreeNode("Game State")) {
|
||||
@ -121,24 +272,24 @@ void IsleDebug_Render()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Video Manager")) {
|
||||
LegoVideoManager* videoManager = lego->GetVideoManager();
|
||||
ImGui::Text("Elapsed: %g", static_cast<float>(videoManager->GetElapsedSeconds()));
|
||||
ImGui::Value("Render3D", videoManager->GetRender3D());
|
||||
DebugViewer::InsideVideoManager();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Plant Manager")) {
|
||||
LegoPlantManager* plantManager = lego->GetPlantManager();
|
||||
ImGui::Value("#plants", plantManager->GetNumPlants());
|
||||
DebugViewer::InsidePlantManager();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Building Manager")) {
|
||||
LegoBuildingManager* buildingManager = lego->GetBuildingManager();
|
||||
DebugViewer::InsideBuildingManager();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Tickle Manager")) {
|
||||
DebugViewer::InsideTickleManager();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::ShowDemoWindow(nullptr);
|
||||
|
||||
ImGui::Render();
|
||||
SDL_RenderClear(g_debugRenderer);
|
||||
@ -153,3 +304,52 @@ void IsleDebug_Render()
|
||||
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), g_debugRenderer);
|
||||
SDL_RenderPresent(g_debugRenderer);
|
||||
}
|
||||
|
||||
bool IsleDebug_Enabled()
|
||||
{
|
||||
return g_debugEnabled;
|
||||
}
|
||||
|
||||
void IsleDebug_SetEnabled(bool v)
|
||||
{
|
||||
if (v) {
|
||||
SDL_Log(
|
||||
"Press \"%s\" for pausing/stepping the game",
|
||||
SDL_GetKeyName(SDL_GetKeyFromScancode(SCANCODE_KEY_PAUSE, 0, false))
|
||||
);
|
||||
SDL_Log(
|
||||
"Press \"%s\" for resuming the game",
|
||||
SDL_GetKeyName(SDL_GetKeyFromScancode(SCANCODE_KEY_RESUME, 0, false))
|
||||
);
|
||||
}
|
||||
g_debugEnabled = v;
|
||||
}
|
||||
|
||||
void IsleDebug_SetPaused(bool v)
|
||||
{
|
||||
SDL_assert(g_debugPaused == !v);
|
||||
g_debugPaused = v;
|
||||
if (g_debugPaused) {
|
||||
g_isle->SetWindowActive(false);
|
||||
Lego()->Pause();
|
||||
}
|
||||
else {
|
||||
g_isle->SetWindowActive(true);
|
||||
Lego()->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsleDebug_Paused()
|
||||
{
|
||||
return g_debugPaused;
|
||||
}
|
||||
|
||||
void IsleDebug_ResetStepMode()
|
||||
{
|
||||
g_debugDoStep = false;
|
||||
}
|
||||
|
||||
bool IsleDebug_StepModeEnabled()
|
||||
{
|
||||
return g_debugDoStep;
|
||||
}
|
||||
|
||||
@ -3,29 +3,55 @@
|
||||
|
||||
#if defined(ISLE_DEBUG)
|
||||
|
||||
extern bool g_debugEnabled;
|
||||
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
extern bool IsleDebug_Enabled();
|
||||
|
||||
extern void IsleDebug_SetEnabled(bool);
|
||||
|
||||
extern void IsleDebug_Init();
|
||||
|
||||
extern bool IsleDebug_Event(SDL_Event* event);
|
||||
|
||||
extern void IsleDebug_Render();
|
||||
|
||||
extern void IsleDebug_SetPaused(bool v);
|
||||
|
||||
extern bool IsleDebug_Paused();
|
||||
|
||||
extern bool IsleDebug_StepModeEnabled();
|
||||
|
||||
extern void IsleDebug_ResetStepMode();
|
||||
|
||||
#else
|
||||
|
||||
#define IsleDebug_Enabled() (false)
|
||||
|
||||
#define IsleDebug_SetEnabled(V) \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#define IsleDebug_Init() \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#define IsleDebug_Event(EVENT) false
|
||||
#define IsleDebug_Event(EVENT) (false)
|
||||
|
||||
#define IsleDebug_Render() \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#define g_debugEnabled false
|
||||
#define IsleDebug_SetPaused(X) \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#define IsleDebug_Paused() (false)
|
||||
|
||||
#define IsleDebug_StepModeEnabled() (false)
|
||||
|
||||
#define IsleDebug_ResetStepMode() \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -108,6 +108,8 @@ class LegoBuildingManager : public MxCore {
|
||||
LegoCacheSound* m_sound; // 0x24
|
||||
MxBool m_unk0x28; // 0x28
|
||||
LegoWorld* m_world; // 0x2c
|
||||
|
||||
friend class DebugViewer;
|
||||
};
|
||||
|
||||
#endif // LEGOBUILDINGMANAGER_H
|
||||
|
||||
@ -82,6 +82,8 @@ class LEGO1_EXPORT LegoPlantManager : public MxCore {
|
||||
AnimEntry* m_entries[5]; // 0x10
|
||||
MxS8 m_numEntries; // 0x24
|
||||
LegoWorld* m_world; // 0x28
|
||||
|
||||
friend class DebugViewer;
|
||||
};
|
||||
|
||||
#endif // LEGOPLANTMANAGER_H
|
||||
|
||||
@ -124,6 +124,8 @@ class LegoVideoManager : public MxVideoManager {
|
||||
D3DRMRENDERMODE m_rendermode; // 0x584
|
||||
BOOL m_dither; // 0x588
|
||||
DWORD m_bufferCount; // 0x58c
|
||||
|
||||
friend class DebugViewer;
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1007ab20
|
||||
|
||||
@ -89,6 +89,8 @@ class LegoROI : public ViewROI {
|
||||
BoundingSphere m_sphere; // 0xe8
|
||||
undefined m_unk0x100; // 0x100
|
||||
LegoEntity* m_entity; // 0x104
|
||||
|
||||
friend class DebugViewer;
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100dbea8
|
||||
|
||||
@ -55,6 +55,8 @@ class MxTickleManager : public MxCore {
|
||||
|
||||
private:
|
||||
MxTickleClientPtrList m_clients; // 0x08
|
||||
|
||||
friend class DebugViewer;
|
||||
};
|
||||
|
||||
#define TICKLE_MANAGER_NOT_FOUND 0x80000000
|
||||
|
||||
Loading…
Reference in New Issue
Block a user