Tidy up Debugger + breakpoints initial work
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include <backend/core/Interpreter.hpp>
|
#include <backend/core/Interpreter.hpp>
|
||||||
#include <backend/core/JIT.hpp>
|
#include <backend/core/JIT.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
struct Core {
|
struct Core {
|
||||||
@@ -26,8 +27,16 @@ struct Core {
|
|||||||
void Run(float volumeL, float volumeR);
|
void Run(float volumeL, float volumeR);
|
||||||
void TogglePause() { pause = !pause; }
|
void TogglePause() { pause = !pause; }
|
||||||
[[nodiscard]] VI &GetVI() const { return cpu->GetMem().mmio.vi; }
|
[[nodiscard]] VI &GetVI() const { return cpu->GetMem().mmio.vi; }
|
||||||
|
inline void ToggleBreakpoint(s64 addr) {
|
||||||
|
if(breakpoints.contains(addr)){
|
||||||
|
breakpoints.erase(addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32 breakpoint = 0;
|
breakpoints.insert(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<s64> breakpoints{};
|
||||||
|
|
||||||
bool pause = true;
|
bool pause = true;
|
||||||
u32 cycles = 0;
|
u32 cycles = 0;
|
||||||
|
|||||||
@@ -67,12 +67,22 @@ Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(const u32 addr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto formatComment = [&](const cs_mips_op &operand) {
|
auto formatComment = [&](const cs_mips_op &operand) -> std::string {
|
||||||
return "";
|
switch (operand.type) {
|
||||||
|
case MIPS_OP_IMM:
|
||||||
|
return std::format("#{:X}", operand.is_unsigned ? operand.uimm : operand.imm);
|
||||||
|
case MIPS_OP_MEM:
|
||||||
|
return std::format("{}(0x{:X})", CapstoneToRegValue(operand.mem.base), operand.mem.disp);
|
||||||
|
case MIPS_OP_REG:
|
||||||
|
return std::format("{}", CapstoneToRegValue(operand.reg));
|
||||||
|
default:
|
||||||
|
return "! Unknown !";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (u8 i = 0; i < details->mips.op_count && i < 3; i++) {
|
for (u8 i = 0; i < details->mips.op_count && i < 3; i++) {
|
||||||
result.ops[i] = formatOperand(details->mips.operands[i]);
|
result.ops[i] = formatOperand(details->mips.operands[i]);
|
||||||
|
result.comment += formatComment(details->mips.operands[i]) + " ";
|
||||||
result.full += result.ops[i].str + "\t";
|
result.full += result.ops[i].str + "\t";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,3 +92,107 @@ Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(const u32 addr
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Disassembler::CapstoneToRegValue(mips_reg reg) const {
|
||||||
|
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||||
|
u64 val = 0;
|
||||||
|
switch(reg) {
|
||||||
|
case MIPS_REG_ZERO: case MIPS_REG_ZERO_64: case MIPS_REG_ZERO_NM:
|
||||||
|
val = 0;
|
||||||
|
break;
|
||||||
|
case MIPS_REG_AT: case MIPS_REG_AT_64: case MIPS_REG_AT_NM:
|
||||||
|
val = regs.Read<u64>(1);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_V0: case MIPS_REG_V0_64:
|
||||||
|
val = regs.Read<u64>(2);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_V1: case MIPS_REG_V1_64:
|
||||||
|
val = regs.Read<u64>(3);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_A0: case MIPS_REG_A0_64:
|
||||||
|
val = regs.Read<u64>(4);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_A1: case MIPS_REG_A1_64:
|
||||||
|
val = regs.Read<u64>(5);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_A2: case MIPS_REG_A2_64:
|
||||||
|
val = regs.Read<u64>(6);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_A3: case MIPS_REG_A3_64:
|
||||||
|
val = regs.Read<u64>(7);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T0: case MIPS_REG_T0_64:
|
||||||
|
val = regs.Read<u64>(8);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T1: case MIPS_REG_T1_64:
|
||||||
|
val = regs.Read<u64>(9);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T2: case MIPS_REG_T2_64:
|
||||||
|
val = regs.Read<u64>(10);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T3: case MIPS_REG_T3_64:
|
||||||
|
val = regs.Read<u64>(11);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T4: case MIPS_REG_T4_64:
|
||||||
|
val = regs.Read<u64>(12);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T5: case MIPS_REG_T5_64:
|
||||||
|
val = regs.Read<u64>(13);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T6: case MIPS_REG_T6_64:
|
||||||
|
val = regs.Read<u64>(14);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T7: case MIPS_REG_T7_64:
|
||||||
|
val = regs.Read<u64>(15);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S0: case MIPS_REG_S0_64:
|
||||||
|
val = regs.Read<u64>(16);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S1: case MIPS_REG_S1_64:
|
||||||
|
val = regs.Read<u64>(17);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S2: case MIPS_REG_S2_64:
|
||||||
|
val = regs.Read<u64>(18);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S3: case MIPS_REG_S3_64:
|
||||||
|
val = regs.Read<u64>(19);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S4: case MIPS_REG_S4_64:
|
||||||
|
val = regs.Read<u64>(20);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S5: case MIPS_REG_S5_64:
|
||||||
|
val = regs.Read<u64>(21);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S6: case MIPS_REG_S6_64:
|
||||||
|
val = regs.Read<u64>(22);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_S7: case MIPS_REG_S7_64:
|
||||||
|
val = regs.Read<u64>(23);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T8: case MIPS_REG_T8_64:
|
||||||
|
val = regs.Read<u64>(24);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_T9: case MIPS_REG_T9_64:
|
||||||
|
val = regs.Read<u64>(25);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_K0: case MIPS_REG_K0_64:
|
||||||
|
val = regs.Read<u64>(26);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_K1: case MIPS_REG_K1_64:
|
||||||
|
val = regs.Read<u64>(27);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_GP: case MIPS_REG_GP_64:
|
||||||
|
val = regs.Read<u64>(28);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_SP: case MIPS_REG_SP_64:
|
||||||
|
val = regs.Read<u64>(29);
|
||||||
|
break;
|
||||||
|
case MIPS_REG_RA: case MIPS_REG_RA_64:
|
||||||
|
val = regs.Read<u64>(31);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "! Unknown !";
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::format("{} (= 0x{:016X})", cs_reg_name(handle, reg), val);
|
||||||
|
}
|
||||||
@@ -25,10 +25,12 @@ struct Disassembler {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] DisassemblyResult Disassemble(const u32 address) const;
|
[[nodiscard]] DisassemblyResult Disassemble(const u32 address) const;
|
||||||
[[nodiscard]] DisassemblyResult DisassembleDetailed(u32 address, u32 instruction) const;
|
[[nodiscard]] DisassemblyResult DisassembleDetailed(u32 address, u32 instruction) const;
|
||||||
[[nodiscard]] DisassemblyResult DisassembleSimple(u32 address, u32 instruction) const;
|
[[nodiscard]] DisassemblyResult DisassembleSimple(u32 address, u32 instruction) const;
|
||||||
private:
|
private:
|
||||||
|
std::string CapstoneToRegValue(mips_reg reg) const;
|
||||||
explicit Disassembler(const bool rsp) : rsp(rsp) {
|
explicit Disassembler(const bool rsp) : rsp(rsp) {
|
||||||
if (cs_open(CS_ARCH_MIPS, static_cast<cs_mode>((rsp ? CS_MODE_32 : CS_MODE_64) | CS_MODE_BIG_ENDIAN), &handle) !=
|
if (cs_open(CS_ARCH_MIPS, static_cast<cs_mode>((rsp ? CS_MODE_32 : CS_MODE_64) | CS_MODE_BIG_ENDIAN), &handle) !=
|
||||||
CS_ERR_OK) {
|
CS_ERR_OK) {
|
||||||
|
|||||||
@@ -2,79 +2,124 @@
|
|||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <execution>
|
#include <execution>
|
||||||
|
|
||||||
|
void BreakpointFunc(s64 addr, s64 startAddr, const Disassembler::DisassemblyResult&) {
|
||||||
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
|
bool isBroken = core.breakpoints.contains(addr + 4);
|
||||||
|
if(ImGui::Checkbox(std::format("##toggleBreakpoint{}", (addr - startAddr) / 4).c_str(), &isBroken)) {
|
||||||
|
core.ToggleBreakpoint(addr + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressFunc(s64, s64, const Disassembler::DisassemblyResult& disasm) {
|
||||||
|
if(disasm.success) {
|
||||||
|
ImGui::TextColored(ImColor(0xffeaefb6), "%s", std::format("{:016X}:", disasm.address).c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TextColored(ImColor(0xffeaefb6), "????????????????");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstructionFunc(s64, s64, const Disassembler::DisassemblyResult& disasm) {
|
||||||
|
if(!disasm.success) {
|
||||||
|
ImGui::TextColored(ImColor(0xffcbf1ae), "Disassembly unsuccessful...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TextColored(ImColor(0xffcbf1ae), "%s", std::format("{} ", disasm.mnemonic).c_str());
|
||||||
|
ImGui::SameLine(0, 0);
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
if(disasm.ops[i].str.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(i >= 2) {
|
||||||
|
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", disasm.ops[i].str.c_str());
|
||||||
|
ImGui::SameLine(0, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string op_str = disasm.ops[i].str;
|
||||||
|
if(!disasm.ops[i+1].str.empty())
|
||||||
|
op_str += ", ";
|
||||||
|
|
||||||
|
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", op_str.c_str());
|
||||||
|
ImGui::SameLine(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommentFunc(s64, s64, const Disassembler::DisassemblyResult& disasm) {
|
||||||
|
if(disasm.success) {
|
||||||
|
ImGui::TextColored(ImColor(0xff71efe5), "%s", std::format("{}", disasm.comment).c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TextColored(ImColor(0xff71efe5), "");
|
||||||
|
}
|
||||||
|
|
||||||
bool Debugger::render() {
|
bool Debugger::render() {
|
||||||
n64::Core& core = n64::Core::GetInstance();
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
if(enabled && ImGui::Begin("Debugger", &enabled)) {
|
|
||||||
static u64 startAddr = 0xFFFF'FFFF'8000'0000;
|
|
||||||
static constexpr int addrStep = 4;
|
|
||||||
static bool followPC = false;
|
|
||||||
ImGui::BeginDisabled(followPC);
|
|
||||||
ImGui::InputScalar("Address", ImGuiDataType_U64, &startAddr, &addrStep, nullptr, "%016lX", ImGuiInputTextFlags_CharsHexadecimal);
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Checkbox("Follow program counter:", &followPC);
|
|
||||||
if(followPC)
|
|
||||||
startAddr = core.cpu->GetRegs().pc - 128; // TODO: arbitrary???
|
|
||||||
|
|
||||||
if(ImGui::BeginTable("Disassembly", 3, ImGuiTableFlags_RowBg)) {
|
if(!enabled)
|
||||||
ImGui::TableSetupColumn("Address");
|
return false;
|
||||||
ImGui::TableSetupColumn("Instruction");
|
|
||||||
ImGui::TableSetupColumn("Comment");
|
|
||||||
ImGui::TableHeadersRow();
|
|
||||||
|
|
||||||
for(u64 addr = startAddr; addr < startAddr + MAX_LINES_OF_DISASM * sizeof(u32); addr += sizeof(u32)) {
|
static s64 startAddr = 0xFFFF'FFFF'8000'0000;
|
||||||
auto disasm = Disassembler::GetInstance().Disassemble(addr);
|
int step = 4, stepFast = 256;
|
||||||
auto isPc = addr == core.cpu->GetRegs().pc;
|
static bool followPC = true;
|
||||||
if(isPc) {
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_TableRowBg, 0x809a9ade);
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, 0x807777bf);
|
|
||||||
}
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
if(disasm.success) {
|
|
||||||
ImGui::TableSetColumnIndex(0);
|
|
||||||
ImGui::TextColored(ImColor(0xffeaefb6), "%s", std::format("{:016X}:", disasm.address).c_str());
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
|
||||||
ImGui::TextColored(ImColor(0xffcbf1ae), "%s", std::format("{} ", disasm.mnemonic).c_str());
|
|
||||||
ImGui::SameLine(0, 0);
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
if(i < 2) {
|
|
||||||
if(!disasm.ops[i].str.empty()) {
|
|
||||||
std::string op_str = disasm.ops[i].str;
|
|
||||||
if(!disasm.ops[i+1].str.empty()) op_str += ", ";
|
|
||||||
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", op_str.c_str());
|
|
||||||
ImGui::SameLine(0, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(!disasm.ops[i].str.empty()) {
|
|
||||||
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", disasm.ops[i].str.c_str());
|
|
||||||
ImGui::SameLine(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::TableSetColumnIndex(2);
|
|
||||||
ImGui::TextColored(ImColor(0xff71efe5), "%s", std::format("{}", disasm.comment).c_str());
|
|
||||||
} else {
|
|
||||||
ImGui::TableSetColumnIndex(0);
|
|
||||||
ImGui::TextColored(ImColor(0xffeaefb6), "????????????????");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
|
||||||
ImGui::TextColored(ImColor(0xffcbf1ae), "Disassembly unsuccessful...");
|
|
||||||
ImGui::TableSetColumnIndex(2);
|
|
||||||
ImGui::TextColored(ImColor(0xff71efe5), "");
|
|
||||||
}
|
|
||||||
if(isPc) {
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ImGui::TableGetHoveredColumn() == 2) {
|
ImGui::Begin("Debugger", &enabled);
|
||||||
// do the thing with the little fucking hover popup that shows the memory view
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::BeginDisabled(followPC);
|
||||||
}
|
ImGui::InputScalar("Address", ImGuiDataType_S64, (void*)&startAddr, (void*)&step, (void*)&stepFast, "%016lX", ImGuiInputTextFlags_CharsHexadecimal);
|
||||||
ImGui::End();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
ImGui::Text("Follow program counter:");
|
||||||
|
ImGui::SameLine(0,0);
|
||||||
|
|
||||||
|
ImGui::Checkbox("##followPC", &followPC);
|
||||||
|
ImGui::SameLine(0,0);
|
||||||
|
|
||||||
|
ImGui::Text("Add a breakpoint");
|
||||||
|
ImGui::SameLine(0,0);
|
||||||
|
|
||||||
|
if(followPC)
|
||||||
|
startAddr = core.cpu->GetRegs().pc - 256; // TODO: arbitrary???
|
||||||
|
|
||||||
|
if(ImGui::Button(core.breakpoints.contains(startAddr) ? "-" : "+")) {
|
||||||
|
core.ToggleBreakpoint(startAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::BeginTable("Disassembly", columns.size(), ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit);
|
||||||
|
for(int i = 0; i < columns.size(); i++)
|
||||||
|
ImGui::TableSetupColumn(columns[i].name);
|
||||||
|
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
|
for(u64 addr = startAddr; addr < startAddr + MAX_LINES_OF_DISASM * sizeof(u32); addr += sizeof(u32)) {
|
||||||
|
auto disasm = Disassembler::GetInstance().Disassemble(addr);
|
||||||
|
auto shouldColorRed = addr == core.cpu->GetRegs().nextPC || core.breakpoints.contains(addr);
|
||||||
|
if(shouldColorRed) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_TableRowBg, 0x809a9ade);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, 0x807777bf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
for(int i = 0; i < columns.size(); i++) {
|
||||||
|
ImGui::TableSetColumnIndex(i);
|
||||||
|
columns[i].func(addr, startAddr, disasm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shouldColorRed) {
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ImGui::TableGetHoveredColumn() == 2) {
|
||||||
|
// TODO: do the thing with the little fucking hover popup that shows the memory view
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <backend/Core.hpp>
|
#include <backend/Core.hpp>
|
||||||
|
|
||||||
|
void BreakpointFunc(s64, s64, const Disassembler::DisassemblyResult&);
|
||||||
|
void AddressFunc(s64, s64, const Disassembler::DisassemblyResult&);
|
||||||
|
void InstructionFunc(s64, s64, const Disassembler::DisassemblyResult&);
|
||||||
|
void CommentFunc(s64, s64, const Disassembler::DisassemblyResult&);
|
||||||
|
|
||||||
class Debugger final {
|
class Debugger final {
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
static constexpr auto MAX_LINES_OF_DISASM = 150;
|
static constexpr auto MAX_LINES_OF_DISASM = 150;
|
||||||
|
|
||||||
|
struct Column {
|
||||||
|
const char* name;
|
||||||
|
void (*func)(s64, s64, const Disassembler::DisassemblyResult&) = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<Column, 4> columns = {
|
||||||
|
Column{"Breakpoint", &BreakpointFunc},
|
||||||
|
Column{"Address", &AddressFunc},
|
||||||
|
Column{"Instruction", &InstructionFunc},
|
||||||
|
Column{"Comment", &CommentFunc},
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
void Open() { enabled = true; }
|
void Open() { enabled = true; }
|
||||||
void Close() { enabled = false; }
|
void Close() { enabled = false; }
|
||||||
|
|||||||
@@ -247,6 +247,9 @@ void KaizenGui::RenderUI() {
|
|||||||
}, this, window.getHandle(), filters, 3, nullptr, false);
|
}, this, window.getHandle(), filters, 3, nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(minimized)
|
||||||
|
return;
|
||||||
|
|
||||||
if(core.romLoaded) {
|
if(core.romLoaded) {
|
||||||
core.parallel.UpdateScreen();
|
core.parallel.UpdateScreen();
|
||||||
return;
|
return;
|
||||||
@@ -271,6 +274,12 @@ void KaizenGui::run() {
|
|||||||
quit = true;
|
quit = true;
|
||||||
emuThread.Stop();
|
emuThread.Stop();
|
||||||
break;
|
break;
|
||||||
|
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||||
|
minimized = true;
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_WINDOW_RESTORED:
|
||||||
|
minimized = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
QueryDevices(e);
|
QueryDevices(e);
|
||||||
HandleInput(e);
|
HandleInput(e);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
double fpsCounter = -1.0;
|
double fpsCounter = -1.0;
|
||||||
bool fastForward = false;
|
bool fastForward = false;
|
||||||
bool unlockFramerate = false;
|
bool unlockFramerate = false;
|
||||||
|
bool minimized = false;
|
||||||
|
|
||||||
SettingsWindow settingsWindow;
|
SettingsWindow settingsWindow;
|
||||||
RenderWidget vulkanWidget;
|
RenderWidget vulkanWidget;
|
||||||
|
|||||||
Reference in New Issue
Block a user