337 lines
9.4 KiB
C++
337 lines
9.4 KiB
C++
#include "StdAfx.h"
|
|
#include "frontends/sdl/imgui/sdlsettings.h"
|
|
#include "frontends/sdl/imgui/settingshelper.h"
|
|
#include "frontends/sdl/sdlframe.h"
|
|
|
|
#include "Interface.h"
|
|
#include "CardManager.h"
|
|
#include "Core.h"
|
|
#include "CPU.h"
|
|
#include "CardManager.h"
|
|
#include "Speaker.h"
|
|
#include "Mockingboard.h"
|
|
#include "Registry.h"
|
|
#include "Memory.h"
|
|
|
|
#include "Debugger/Debug.h"
|
|
#include "Debugger/DebugDefs.h"
|
|
|
|
namespace
|
|
{
|
|
|
|
void HelpMarker(const char* desc)
|
|
{
|
|
ImGui::TextDisabled("(?)");
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
ImGui::BeginTooltip();
|
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
|
ImGui::TextUnformatted(desc);
|
|
ImGui::PopTextWrapPos();
|
|
ImGui::EndTooltip();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
namespace sa2
|
|
{
|
|
|
|
void ImGuiSettings::showSettings()
|
|
{
|
|
if (ImGui::Begin("Settings", &myShowSettings))
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
if (ImGui::BeginTabBar("Settings"))
|
|
{
|
|
if (ImGui::BeginTabItem("General"))
|
|
{
|
|
ImGui::Checkbox("Apple Video windowed", &windowed);
|
|
ImGui::SameLine(); HelpMarker("Show Apple video in a separate window.");
|
|
|
|
ImGui::Checkbox("Memory", &myShowMemory);
|
|
ImGui::SameLine(); HelpMarker("Show Apple memory.");
|
|
|
|
if (ImGui::Checkbox("CPU", &myShowCPU) && myShowCPU)
|
|
{
|
|
DebugBegin();
|
|
}
|
|
ImGui::SameLine(); HelpMarker("Show Apple CPU.");
|
|
|
|
ImGui::Checkbox("Show Demo", &myShowDemo);
|
|
ImGui::SameLine(); HelpMarker("Show Dear ImGui DemoWindow.");
|
|
|
|
ImGui::Text("FPS: %d", int(io.Framerate));
|
|
ImGui::EndTabItem();
|
|
}
|
|
if (ImGui::BeginTabItem("Hardware"))
|
|
{
|
|
if (ImGui::BeginTable("Cards", 2, ImGuiTableFlags_RowBg))
|
|
{
|
|
CardManager & manager = GetCardMgr();
|
|
ImGui::TableSetupColumn("Slot");
|
|
ImGui::TableSetupColumn("Card");
|
|
ImGui::TableHeadersRow();
|
|
|
|
for (size_t slot = 0; slot < 8; ++slot)
|
|
{
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable(std::to_string(slot).c_str());
|
|
ImGui::TableNextColumn();
|
|
const SS_CARDTYPE card = manager.QuerySlot(slot);;
|
|
ImGui::Selectable(getCardName(card).c_str());
|
|
}
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable("AUX");
|
|
ImGui::TableNextColumn();
|
|
const SS_CARDTYPE card = manager.QueryAux();
|
|
ImGui::Selectable(getCardName(card).c_str());
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::BeginTable("Type", 2, ImGuiTableFlags_RowBg))
|
|
{
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable("Apple 2");
|
|
ImGui::TableNextColumn();
|
|
const eApple2Type a2e = GetApple2Type();
|
|
ImGui::Selectable(getApple2Name(a2e).c_str());
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable("CPU");
|
|
ImGui::TableNextColumn();
|
|
const eCpuType cpu = GetMainCpu();
|
|
ImGui::Selectable(getCPUName(cpu).c_str());
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable("Mode");
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable(getModeName(g_nAppMode).c_str());
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
}
|
|
|
|
if (ImGui::BeginTabItem("Audio"))
|
|
{
|
|
const int volumeMax = GetPropertySheet().GetVolumeMax();
|
|
if (ImGui::SliderInt("Speaker volume", &mySpeakerVolume, 0, volumeMax))
|
|
{
|
|
SpkrSetVolume(volumeMax - mySpeakerVolume, volumeMax);
|
|
REGSAVE(TEXT(REGVALUE_SPKR_VOLUME), SpkrGetVolume());
|
|
}
|
|
|
|
if (ImGui::SliderInt("Mockingboard volume", &myMockingboardVolume, 0, volumeMax))
|
|
{
|
|
MB_SetVolume(volumeMax - myMockingboardVolume, volumeMax);
|
|
REGSAVE(TEXT(REGVALUE_MB_VOLUME), MB_GetVolume());
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
}
|
|
|
|
ImGui::EndTabBar();
|
|
}
|
|
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void ImGuiSettings::show(SDLFrame * frame)
|
|
{
|
|
if (myShowSettings)
|
|
{
|
|
showSettings();
|
|
}
|
|
|
|
if (myShowMemory)
|
|
{
|
|
showMemory();
|
|
}
|
|
|
|
if (myShowCPU)
|
|
{
|
|
showCPU(frame);
|
|
}
|
|
|
|
if (myShowDemo)
|
|
{
|
|
ImGui::ShowDemoWindow(&myShowDemo);
|
|
}
|
|
}
|
|
|
|
float ImGuiSettings::drawMenuBar()
|
|
{
|
|
float menuBarHeight;
|
|
|
|
if (ImGui::BeginMainMenuBar())
|
|
{
|
|
menuBarHeight = ImGui::GetWindowHeight();
|
|
if (ImGui::BeginMenu("System"))
|
|
{
|
|
ImGui::MenuItem("Settings", nullptr, &myShowSettings);
|
|
ImGui::MenuItem("Memory", nullptr, &myShowMemory);
|
|
if (ImGui::MenuItem("CPU", nullptr, &myShowCPU) && myShowCPU)
|
|
{
|
|
DebugBegin();
|
|
}
|
|
ImGui::Separator();
|
|
ImGui::MenuItem("Demo", nullptr, &myShowDemo);
|
|
ImGui::EndMenu();
|
|
}
|
|
ImGui::EndMainMenuBar();
|
|
}
|
|
else
|
|
{
|
|
menuBarHeight = 0.0;
|
|
}
|
|
|
|
return menuBarHeight;
|
|
}
|
|
|
|
void ImGuiSettings::showMemory()
|
|
{
|
|
if (ImGui::Begin("Memory Viewer", &myShowMemory))
|
|
{
|
|
if (ImGui::BeginTabBar("Memory"))
|
|
{
|
|
if (ImGui::BeginTabItem("Main"))
|
|
{
|
|
void * mainBase = MemGetMainPtr(0);
|
|
myMainMemoryEditor.DrawContents(mainBase, _6502_MEM_LEN);
|
|
ImGui::EndTabItem();
|
|
}
|
|
if (ImGui::BeginTabItem("AUX"))
|
|
{
|
|
void * auxBase = MemGetAuxPtr(0);
|
|
myMainMemoryEditor.DrawContents(auxBase, _6502_MEM_LEN);
|
|
ImGui::EndTabItem();
|
|
}
|
|
ImGui::EndTabBar();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void ImGuiSettings::showCPU(SDLFrame * frame)
|
|
{
|
|
if (ImGui::Begin("CPU", &myShowCPU))
|
|
{
|
|
ImGui::Checkbox("Auto-sync PC", &mySyncCPU);
|
|
|
|
// complicated if condition to preserve widget order
|
|
const bool recalc = mySyncCPU || (ImGui::SameLine(), ImGui::Button("Sync PC"));
|
|
|
|
if (ImGui::Button("Step"))
|
|
{
|
|
frame->ChangeMode(MODE_STEPPING);
|
|
frame->Execute(myStepCycles);
|
|
}
|
|
ImGui::SameLine();
|
|
ImGui::PushItemWidth(150);
|
|
ImGui::DragInt("cycles", &myStepCycles, 0.2f, 0, 256, "%d");
|
|
ImGui::PopItemWidth();
|
|
|
|
if ((ImGui::SameLine(), ImGui::Button("Run")))
|
|
{
|
|
frame->ChangeMode(MODE_RUNNING);
|
|
}
|
|
if ((ImGui::SameLine(), ImGui::Button("Pause")))
|
|
{
|
|
frame->ChangeMode(MODE_PAUSED);
|
|
}
|
|
ImGui::SameLine(); ImGui::Text("%016llu - %04X", g_nCumulativeCycles, regs.pc);
|
|
|
|
if (ImGui::SliderInt("PC position", &g_nDisasmCurLine, 1, 100) || recalc)
|
|
{
|
|
g_nDisasmCurAddress = regs.pc;
|
|
DisasmCalcTopBotAddress();
|
|
}
|
|
const ImGuiTableFlags flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY;
|
|
if (ImGui::BeginTable("Disassembly", 8, flags))
|
|
{
|
|
// weigths proportional to column width (including header)
|
|
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
|
|
ImGui::TableSetupColumn("Disassembly", 0, 30);
|
|
ImGui::TableSetupColumn("Symbol", 0, 20);
|
|
ImGui::TableSetupColumn("Target", 0, 20);
|
|
ImGui::TableSetupColumn("Offset", 0, 6);
|
|
ImGui::TableSetupColumn("Pointer", 0, 7);
|
|
ImGui::TableSetupColumn("Value", 0, 5);
|
|
ImGui::TableSetupColumn("Immediate", 0, 9);
|
|
ImGui::TableSetupColumn("Branch", 0, 6);
|
|
ImGui::TableHeadersRow();
|
|
|
|
ImGuiListClipper clipper;
|
|
clipper.Begin(1000);
|
|
int row = 0;
|
|
WORD nAddress = g_nDisasmTopAddress;
|
|
while (clipper.Step())
|
|
{
|
|
for (; row < clipper.DisplayStart; ++row)
|
|
{
|
|
int iOpcode, iOpmode, nOpbyte;
|
|
_6502_GetOpmodeOpbyte(nAddress, iOpmode, nOpbyte, nullptr);
|
|
nAddress += nOpbyte;
|
|
}
|
|
IM_ASSERT(row == clipper.DisplayStart && "Clipper position mismatch");
|
|
for (; row < clipper.DisplayEnd; ++row)
|
|
{
|
|
DisasmLine_t line;
|
|
const char* pSymbol = FindSymbolFromAddress(nAddress);
|
|
const int bDisasmFormatFlags = GetDisassemblyLine(nAddress, line);
|
|
|
|
char buffer[CONSOLE_WIDTH];
|
|
FormatDisassemblyLine(line, buffer, sizeof(buffer));
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
if (nAddress == regs.pc)
|
|
{
|
|
const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(0, 0, 1, 1));
|
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Selectable(buffer, false, ImGuiSelectableFlags_SpanAllColumns);
|
|
|
|
ImGui::TableNextColumn();
|
|
if (pSymbol)
|
|
{
|
|
ImGui::TextUnformatted(pSymbol);
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(line.sTarget);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(line.sTargetOffset);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(line.sTargetPointer);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(line.sTargetValue);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(line.sImmediate);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(line.sBranch);
|
|
|
|
nAddress += line.nOpbyte;
|
|
}
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
|
|
}
|