mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
makefile vet target removed and put 'go vet' into lint target. awk filter for unkeyed struct errors removed
850 lines
25 KiB
Go
850 lines
25 KiB
Go
// This file is part of Gopher2600.
|
|
//
|
|
// Gopher2600 is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Gopher2600 is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package sdlimgui
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/inkyblackness/imgui-go/v4"
|
|
"github.com/jetsetilly/gopher2600/debugger/govern"
|
|
"github.com/jetsetilly/gopher2600/gui/fonts"
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/plusrom"
|
|
"github.com/jetsetilly/gopher2600/logger"
|
|
"github.com/jetsetilly/gopher2600/prefs"
|
|
)
|
|
|
|
const winPrefsID = "Preferences"
|
|
|
|
type winPrefs struct {
|
|
playmodeWin
|
|
debuggerWin
|
|
|
|
img *SdlImgui
|
|
}
|
|
|
|
func newWinPrefs(img *SdlImgui) (window, error) {
|
|
win := &winPrefs{
|
|
img: img,
|
|
}
|
|
|
|
return win, nil
|
|
}
|
|
|
|
func (win *winPrefs) init() {
|
|
}
|
|
|
|
func (win *winPrefs) id() string {
|
|
return winPrefsID
|
|
}
|
|
func (win *winPrefs) playmodeDraw() bool {
|
|
if !win.playmodeOpen {
|
|
return false
|
|
}
|
|
|
|
imgui.SetNextWindowPosV(imgui.Vec2{X: 100, Y: 40}, imgui.ConditionFirstUseEver, imgui.Vec2{X: 0, Y: 0})
|
|
if imgui.BeginV(win.playmodeID(win.id()), &win.playmodeOpen, imgui.WindowFlagsAlwaysAutoResize) {
|
|
win.draw()
|
|
}
|
|
|
|
win.playmodeWin.playmodeGeom.update()
|
|
imgui.End()
|
|
|
|
return true
|
|
}
|
|
|
|
func (win *winPrefs) debuggerDraw() bool {
|
|
if !win.debuggerOpen {
|
|
return false
|
|
}
|
|
|
|
imgui.SetNextWindowPosV(imgui.Vec2{X: 29, Y: 61}, imgui.ConditionFirstUseEver, imgui.Vec2{X: 0, Y: 0})
|
|
|
|
if imgui.BeginV(win.debuggerID(win.id()), &win.debuggerOpen, imgui.WindowFlagsAlwaysAutoResize) {
|
|
win.draw()
|
|
}
|
|
|
|
win.debuggerWin.debuggerGeom.update()
|
|
imgui.End()
|
|
|
|
return true
|
|
}
|
|
|
|
func (win *winPrefs) draw() {
|
|
var setDef func()
|
|
var setDefLabel = ""
|
|
|
|
// tab-bar to switch between different "areas" of the TIA
|
|
imgui.BeginTabBar("")
|
|
if imgui.BeginTabItem("VCS") {
|
|
win.drawVCS()
|
|
imgui.EndTabItem()
|
|
}
|
|
|
|
if imgui.BeginTabItem("Television") {
|
|
win.drawTelevision()
|
|
imgui.EndTabItem()
|
|
setDef = func() {
|
|
win.img.dbg.VCS().Env.Prefs.TV.SetDefaults()
|
|
win.img.displayPrefs.Colour.SetDefaults()
|
|
}
|
|
setDefLabel = "Television"
|
|
}
|
|
|
|
if win.img.rnd.supportsCRT() {
|
|
if imgui.BeginTabItem("CRT") {
|
|
win.drawCRT()
|
|
imgui.EndTabItem()
|
|
setDef = win.img.displayPrefs.CRT.SetDefaults
|
|
setDefLabel = "CRT"
|
|
}
|
|
}
|
|
|
|
if imgui.BeginTabItem("Playmode") {
|
|
win.drawPlaymodeTab()
|
|
imgui.EndTabItem()
|
|
}
|
|
|
|
if win.img.mode.Load().(govern.Mode) == govern.ModeDebugger {
|
|
if imgui.BeginTabItem("Debugger") {
|
|
win.drawDebuggerTab()
|
|
imgui.EndTabItem()
|
|
}
|
|
}
|
|
|
|
if imgui.BeginTabItem("Rewind") {
|
|
win.drawRewindTab()
|
|
imgui.EndTabItem()
|
|
setDef = win.img.dbg.Rewind.Prefs.SetDefaults
|
|
setDefLabel = "Rewind"
|
|
}
|
|
|
|
if imgui.BeginTabItem("ARM") {
|
|
win.drawARMTab()
|
|
imgui.EndTabItem()
|
|
setDef = win.img.dbg.VCS().Env.Prefs.ARM.SetDefaults
|
|
setDefLabel = "ARM"
|
|
}
|
|
|
|
if imgui.BeginTabItem("PlusROM") {
|
|
win.drawPlusROMTab()
|
|
imgui.EndTabItem()
|
|
}
|
|
|
|
if imgui.BeginTabItem("UI") {
|
|
win.drawUITab()
|
|
imgui.EndTabItem()
|
|
}
|
|
|
|
imgui.EndTabBar()
|
|
|
|
imguiSeparator()
|
|
win.drawDiskButtons()
|
|
|
|
// draw "Set Defaults" button
|
|
if setDef != nil {
|
|
imgui.SameLine()
|
|
if imgui.Button(fmt.Sprintf("Set %s Defaults", setDefLabel)) {
|
|
// some preferences are sensitive to the goroutine SetDefaults() is
|
|
// called within
|
|
win.img.dbg.PushFunction(setDef)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (win *winPrefs) drawGlSwapInterval() {
|
|
var glSwapInterval string
|
|
|
|
const (
|
|
descImmediate = "Immediate updates"
|
|
descWithVerticalRetrace = "Sync with vertical retrace"
|
|
descAdaptive = "Adaptive VSYNC"
|
|
descTicker = "Ticker"
|
|
)
|
|
|
|
switch win.img.prefs.glSwapInterval.Get().(int) {
|
|
default:
|
|
glSwapInterval = descImmediate
|
|
case 1:
|
|
glSwapInterval = descWithVerticalRetrace
|
|
case -1:
|
|
glSwapInterval = descAdaptive
|
|
case 2:
|
|
glSwapInterval = descTicker
|
|
}
|
|
|
|
if imgui.BeginCombo("Swap Interval", glSwapInterval) {
|
|
if imgui.Selectable(descImmediate) {
|
|
win.img.prefs.glSwapInterval.Set(syncImmediateUpdate)
|
|
}
|
|
if imgui.Selectable(descWithVerticalRetrace) {
|
|
win.img.prefs.glSwapInterval.Set(syncWithVerticalRetrace)
|
|
}
|
|
if imgui.Selectable(descAdaptive) {
|
|
win.img.prefs.glSwapInterval.Set(syncAdaptive)
|
|
}
|
|
if imgui.Selectable(descTicker) {
|
|
win.img.prefs.glSwapInterval.Set(syncTicker)
|
|
}
|
|
imgui.EndCombo()
|
|
}
|
|
}
|
|
|
|
func (win *winPrefs) drawPlaymodeTab() {
|
|
imgui.Spacing()
|
|
|
|
activePause := win.img.prefs.activePause.Get().(bool)
|
|
if imgui.Checkbox("'Active' Pause Screen", &activePause) {
|
|
win.img.prefs.activePause.Set(activePause)
|
|
}
|
|
win.img.imguiTooltipSimple(`An 'active' pause screen is one that tries to present
|
|
a television image that is sympathetic to the display kernel
|
|
of the ROM.`)
|
|
|
|
imgui.Spacing()
|
|
if imgui.CollapsingHeader("Notification Overlay") {
|
|
controllerNotifications := win.img.prefs.controllerNotifcations.Get().(bool)
|
|
if imgui.Checkbox("Controller Changes", &controllerNotifications) {
|
|
win.img.prefs.controllerNotifcations.Set(controllerNotifications)
|
|
}
|
|
|
|
plusromNotifications := win.img.prefs.plusromNotifications.Get().(bool)
|
|
if imgui.Checkbox("PlusROM Network Activity", &plusromNotifications) {
|
|
win.img.prefs.plusromNotifications.Set(plusromNotifications)
|
|
}
|
|
|
|
superchargerNotifications := win.img.prefs.superchargerNotifications.Get().(bool)
|
|
if imgui.Checkbox("Supercharger Tape Motion", &superchargerNotifications) {
|
|
win.img.prefs.superchargerNotifications.Set(superchargerNotifications)
|
|
}
|
|
|
|
audioMuteNotification := win.img.prefs.audioMuteNotification.Get().(bool)
|
|
if imgui.Checkbox("Audio Mute Indicator", &audioMuteNotification) {
|
|
win.img.prefs.audioMuteNotification.Set(audioMuteNotification)
|
|
}
|
|
|
|
visibility := float32(win.img.prefs.notificationVisibility.Get().(float64)) * 100
|
|
if imgui.SliderFloatV("Visibility", &visibility, 0.0, 100.0, "%.0f%%", imgui.SliderFlagsNone) {
|
|
win.img.prefs.notificationVisibility.Set(visibility / 100)
|
|
}
|
|
|
|
memoryUsageInOverlay := win.img.prefs.memoryUsageInOverlay.Get().(bool)
|
|
if imgui.Checkbox("Memory Usage in FPS Overlay", &memoryUsageInOverlay) {
|
|
win.img.prefs.memoryUsageInOverlay.Set(memoryUsageInOverlay)
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
if imgui.CollapsingHeader("OpenGL Settings") {
|
|
imgui.Spacing()
|
|
win.drawGlSwapInterval()
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
if imgui.CollapsingHeader("Frame Queue") {
|
|
imgui.Spacing()
|
|
|
|
// the values we show in the preferences window are the current values
|
|
// as known by the screen type. we do no show the values in the
|
|
// underlying preference type directly
|
|
win.img.screen.crit.section.Lock()
|
|
fpsCapped := win.img.screen.crit.fpsCapped
|
|
frameQueueAuto := win.img.screen.crit.frameQueueAuto
|
|
frameQueueLen := int32(win.img.screen.crit.frameQueueLen)
|
|
win.img.screen.crit.section.Unlock()
|
|
|
|
if !fpsCapped {
|
|
imgui.PushItemFlag(imgui.ItemFlagsDisabled, true)
|
|
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, disabledAlpha)
|
|
defer imgui.PopItemFlag()
|
|
defer imgui.PopStyleVar()
|
|
}
|
|
|
|
if imgui.Checkbox("Automatic Frame Queue Length", &frameQueueAuto) {
|
|
win.img.prefs.frameQueueLenAuto.Set(frameQueueAuto)
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
if frameQueueAuto {
|
|
imgui.PushItemFlag(imgui.ItemFlagsDisabled, true)
|
|
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, disabledAlpha)
|
|
defer imgui.PopItemFlag()
|
|
defer imgui.PopStyleVar()
|
|
}
|
|
|
|
if imgui.SliderInt("Frame Queue Length", &frameQueueLen, 1, maxFrameQueue) {
|
|
win.img.prefs.frameQueueLen.Set(frameQueueLen)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (win *winPrefs) drawDebuggerTab() {
|
|
imgui.Spacing()
|
|
|
|
audioMute := win.img.prefs.audioMuteDebugger.Get().(bool)
|
|
if imgui.Checkbox("Audio Muted (in debugger)", &audioMute) {
|
|
win.img.prefs.audioMuteDebugger.Set(audioMute)
|
|
}
|
|
|
|
termOnError := win.img.prefs.terminalOnError.Get().(bool)
|
|
if imgui.Checkbox("Open Terminal on Error", &termOnError) {
|
|
err := win.img.prefs.terminalOnError.Set(termOnError)
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not set preference value: %v", err)
|
|
}
|
|
}
|
|
|
|
showTooltips := win.img.prefs.showTooltips.Get().(bool)
|
|
if imgui.Checkbox("Show Tooltips", &showTooltips) {
|
|
win.img.prefs.showTooltips.Set(showTooltips)
|
|
}
|
|
|
|
showTimelineThumbnail := win.img.prefs.showTimelineThumbnail.Get().(bool)
|
|
if imgui.Checkbox("Show Thumbnail in Timeline", &showTimelineThumbnail) {
|
|
win.img.prefs.showTimelineThumbnail.Set(showTimelineThumbnail)
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
if imgui.CollapsingHeader("6507 Disassembly") {
|
|
imgui.Spacing()
|
|
usefxxmirror := win.img.dbg.Disasm.Prefs.FxxxMirror.Get().(bool)
|
|
if imgui.Checkbox("Use Fxxx Mirror", &usefxxmirror) {
|
|
win.img.dbg.Disasm.Prefs.FxxxMirror.Set(usefxxmirror)
|
|
}
|
|
|
|
usesymbols := win.img.dbg.Disasm.Prefs.Symbols.Get().(bool)
|
|
if imgui.Checkbox("Use Symbols", &usesymbols) {
|
|
win.img.dbg.Disasm.Prefs.Symbols.Set(usesymbols)
|
|
|
|
// if disassembly has address labels then turning symbols off may alter
|
|
// the vertical scrolling of the disassembly window.
|
|
//
|
|
// set focusOnAddr to true to force preference change to take effect
|
|
win.img.wm.debuggerWindows[winDisasmID].(*winDisasm).focusOnAddr = true
|
|
}
|
|
|
|
colorDisasm := win.img.prefs.colorDisasm.Get().(bool)
|
|
if imgui.Checkbox("Listing in Colour", &colorDisasm) {
|
|
win.img.prefs.colorDisasm.Set(colorDisasm)
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
if imgui.CollapsingHeader("OpenGL Settings") {
|
|
imgui.Spacing()
|
|
win.drawGlSwapInterval()
|
|
}
|
|
}
|
|
|
|
func (win *winPrefs) drawRewindTab() {
|
|
imgui.Spacing()
|
|
|
|
rewindMaxEntries := int32(win.img.dbg.Rewind.Prefs.MaxEntries.Get().(int))
|
|
if imgui.SliderIntV("Max Entries##maxentries", &rewindMaxEntries, 10, 500, fmt.Sprintf("%d", rewindMaxEntries), imgui.SliderFlagsNone) {
|
|
win.img.dbg.PushFunction(func() {
|
|
win.img.dbg.Rewind.Prefs.MaxEntries.Set(rewindMaxEntries)
|
|
})
|
|
}
|
|
|
|
imgui.Spacing()
|
|
imguiIndentText("Changing these values will cause the")
|
|
imguiIndentText("existing rewind history to be lost.")
|
|
|
|
imgui.Spacing()
|
|
imgui.Spacing()
|
|
|
|
rewindFreq := int32(win.img.dbg.Rewind.Prefs.Freq.Get().(int))
|
|
if imgui.SliderIntV("Frequency##freq", &rewindFreq, 1, 5, fmt.Sprintf("%d", rewindFreq), imgui.SliderFlagsNone) {
|
|
win.img.dbg.PushFunction(func() {
|
|
win.img.dbg.Rewind.Prefs.Freq.Set(rewindFreq)
|
|
})
|
|
}
|
|
|
|
imgui.Spacing()
|
|
imguiIndentText("Higher rewind frequencies may cause the")
|
|
imguiIndentText("rewind controls to feel sluggish.")
|
|
}
|
|
|
|
func (win *winPrefs) drawVCS() {
|
|
imgui.Spacing()
|
|
|
|
if imgui.CollapsingHeaderV("Randomisation", imgui.TreeNodeFlagsDefaultOpen) {
|
|
randState := win.img.dbg.VCS().Env.Prefs.RandomState.Get().(bool)
|
|
if imgui.Checkbox("Random State (on startup)", &randState) {
|
|
win.img.dbg.VCS().Env.Prefs.RandomState.Set(randState)
|
|
}
|
|
|
|
randPins := win.img.dbg.VCS().Env.Prefs.RandomPins.Get().(bool)
|
|
if imgui.Checkbox("Random Pins", &randPins) {
|
|
win.img.dbg.VCS().Env.Prefs.RandomPins.Set(randPins)
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
if imgui.CollapsingHeaderV("Audio", imgui.TreeNodeFlagsNone) {
|
|
// enable options
|
|
imgui.AlignTextToFramePadding()
|
|
imgui.Text("Muted")
|
|
imgui.SameLineV(0, 15)
|
|
|
|
audioEnabledPlaymode := win.img.prefs.audioMutePlaymode.Get().(bool)
|
|
if imgui.Checkbox("Playmode", &audioEnabledPlaymode) {
|
|
win.img.prefs.audioMutePlaymode.Set(audioEnabledPlaymode)
|
|
}
|
|
|
|
imgui.SameLineV(0, 15)
|
|
audioEnabledDebugger := win.img.prefs.audioMuteDebugger.Get().(bool)
|
|
if imgui.Checkbox("Debugger", &audioEnabledDebugger) {
|
|
win.img.prefs.audioMuteDebugger.Set(audioEnabledDebugger)
|
|
}
|
|
|
|
// stereo options
|
|
stereo := win.img.audio.Prefs.Stereo.Get().(bool)
|
|
if imgui.Checkbox("Stereo Sound", &stereo) {
|
|
win.img.audio.Prefs.Stereo.Set(stereo)
|
|
}
|
|
|
|
if !stereo {
|
|
imgui.PushItemFlag(imgui.ItemFlagsDisabled, true)
|
|
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, disabledAlpha)
|
|
}
|
|
|
|
imgui.SameLineV(0, 15)
|
|
discrete := win.img.audio.Prefs.Discrete.Get().(bool)
|
|
if imgui.Checkbox("Discrete Channels", &discrete) {
|
|
win.img.audio.Prefs.Discrete.Set(discrete)
|
|
}
|
|
|
|
if discrete {
|
|
imgui.PushItemFlag(imgui.ItemFlagsDisabled, true)
|
|
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, disabledAlpha)
|
|
}
|
|
|
|
// seperation values assume that there are three levels of effect
|
|
// support by sdlaudio
|
|
separation := int32(win.img.audio.Prefs.Separation.Get().(int))
|
|
seperationLabel := ""
|
|
switch separation {
|
|
case 1:
|
|
seperationLabel = "Narrow"
|
|
case 2:
|
|
seperationLabel = "Wide"
|
|
case 3:
|
|
seperationLabel = "Very Wide"
|
|
}
|
|
if imgui.SliderIntV("Separation", &separation, 1, 3, seperationLabel, 1.0) {
|
|
win.img.audio.Prefs.Separation.Set(separation)
|
|
}
|
|
|
|
if discrete {
|
|
imgui.PopStyleVar()
|
|
imgui.PopItemFlag()
|
|
}
|
|
|
|
if !stereo {
|
|
imgui.PopStyleVar()
|
|
imgui.PopItemFlag()
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
if imgui.CollapsingHeaderV("TIA Revision", imgui.TreeNodeFlagsNone) {
|
|
win.drawTIARev()
|
|
}
|
|
|
|
imgui.Spacing()
|
|
if imgui.CollapsingHeader("AtariVox") {
|
|
imgui.Spacing()
|
|
imgui.Text("AtariVox output is currently only available")
|
|
imgui.Text("via the Festival voice synthsizer. The path")
|
|
imgui.Text("to the binary is specified below:")
|
|
|
|
imgui.Spacing()
|
|
binary := win.img.dbg.VCS().Env.Prefs.AtariVox.FestivalBinary.Get().(string)
|
|
if imgui.InputTextV("##festivalbinary", &binary, imgui.InputTextFlagsEnterReturnsTrue, nil) {
|
|
win.img.dbg.VCS().Env.Prefs.AtariVox.FestivalBinary.Set(binary)
|
|
win.img.dbg.PushFunction(win.img.dbg.VCS().RIOT.Ports.RestartPeripherals)
|
|
}
|
|
|
|
imgui.Spacing()
|
|
enabled := win.img.dbg.VCS().Env.Prefs.AtariVox.FestivalEnabled.Get().(bool)
|
|
if imgui.Checkbox("Enable Festival Output", &enabled) {
|
|
win.img.dbg.VCS().Env.Prefs.AtariVox.FestivalEnabled.Set(enabled)
|
|
win.img.dbg.PushFunction(win.img.dbg.VCS().RIOT.Ports.RestartPeripherals)
|
|
}
|
|
|
|
var warning bool
|
|
|
|
switch win.img.mode.Load().(govern.Mode) {
|
|
case govern.ModePlay:
|
|
warning = win.img.prefs.audioMutePlaymode.Get().(bool)
|
|
case govern.ModeDebugger:
|
|
warning = win.img.prefs.audioMuteDebugger.Get().(bool)
|
|
}
|
|
|
|
if warning && enabled {
|
|
imgui.SameLine()
|
|
imgui.PushStyleColor(imgui.StyleColorText, win.img.cols.Warning)
|
|
imgui.AlignTextToFramePadding()
|
|
imgui.Text(fmt.Sprintf(" %c", fonts.Warning))
|
|
imgui.PopStyleColor()
|
|
win.img.imguiTooltipSimple(`Emulation audio is currently muted. There will
|
|
be no AtariVox output even though the engine is
|
|
currently enabled.`)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (win *winPrefs) drawARMTab() {
|
|
imgui.Spacing()
|
|
|
|
if win.img.cache.VCS.Mem.Cart.GetCoProcBus() == nil {
|
|
imgui.Text("Current ROM does not have an ARM coprocessor")
|
|
imguiSeparator()
|
|
}
|
|
|
|
immediate := win.img.dbg.VCS().Env.Prefs.ARM.Immediate.Get().(bool)
|
|
if imgui.Checkbox("Immediate ARM Execution", &immediate) {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.Immediate.Set(immediate)
|
|
}
|
|
win.img.imguiTooltipSimple("ARM program consumes no 6507 time (like Stella)\nIf this option is set the other ARM settings are irrelevant")
|
|
|
|
if immediate {
|
|
imgui.PushItemFlag(imgui.ItemFlagsDisabled, true)
|
|
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, disabledAlpha)
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
var mamState string
|
|
switch win.img.dbg.VCS().Env.Prefs.ARM.MAM.Get().(int) {
|
|
case -1:
|
|
mamState = "Driver"
|
|
case 0:
|
|
mamState = "Disabled"
|
|
case 1:
|
|
mamState = "Partial"
|
|
case 2:
|
|
mamState = "Full"
|
|
}
|
|
imgui.PushItemWidth(imguiGetFrameDim("Disabled").X + imgui.FrameHeight())
|
|
if imgui.BeginComboV("Default MAM State##mam", mamState, imgui.ComboFlagsNone) {
|
|
if imgui.Selectable("Driver") {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.MAM.Set(-1)
|
|
}
|
|
if imgui.Selectable("Disabled") {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.MAM.Set(0)
|
|
}
|
|
if imgui.Selectable("Partial") {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.MAM.Set(1)
|
|
}
|
|
if imgui.Selectable("Full") {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.MAM.Set(2)
|
|
}
|
|
imgui.EndCombo()
|
|
}
|
|
imgui.PopItemWidth()
|
|
win.img.imguiTooltipSimple(`The MAM state at the start of the Thumb program.
|
|
|
|
For most purposes, this should be set to 'Driver'. This means that the emulated driver
|
|
for the cartridge mapper decides what the value should be.
|
|
|
|
If the 'Default MAM State' value is not set to 'Driver' then the Thumb program will be
|
|
prevented from changing the MAM state.
|
|
|
|
The MAM should almost never be disabled completely.`)
|
|
|
|
imgui.Spacing()
|
|
imgui.Separator()
|
|
imgui.Spacing()
|
|
|
|
clk := float32(win.img.dbg.VCS().Env.Prefs.ARM.Clock.Get().(float64))
|
|
if imgui.SliderFloatV("Clock Speed", &clk, 50, 300, "%.0f Mhz", imgui.SliderFlagsNone) {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.Clock.Set(float64(clk))
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
reg := float32(win.img.dbg.VCS().Env.Prefs.ARM.CycleRegulator.Get().(float64))
|
|
if imgui.SliderFloatV("Cycle Regulator", ®, 0.5, 2.0, "%.02f", imgui.SliderFlagsNone) {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.CycleRegulator.Set(float64(reg))
|
|
}
|
|
imguiTooltipSimple(`The cycle regulator is a way of adjusting the amount of
|
|
time each instruction in the ARM program takes`, true)
|
|
|
|
if immediate {
|
|
imgui.PopStyleVar()
|
|
imgui.PopItemFlag()
|
|
}
|
|
|
|
imgui.Spacing()
|
|
imgui.Separator()
|
|
imgui.Spacing()
|
|
|
|
abortOnMemoryFault := win.img.dbg.VCS().Env.Prefs.ARM.AbortOnMemoryFault.Get().(bool)
|
|
if imgui.Checkbox("Abort on Memory Fault", &abortOnMemoryFault) {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.AbortOnMemoryFault.Set(abortOnMemoryFault)
|
|
}
|
|
win.img.imguiTooltipSimple(`Abort execution on a memory fault. For example when accessing
|
|
a memory address that does not exist.
|
|
|
|
Note that the program will always abort if the access is a PC fetch, even if this option is not set.
|
|
|
|
Illegal accesses will be logged even if program does not abort.`)
|
|
|
|
misalignedAccessIsFault := win.img.dbg.VCS().Env.Prefs.ARM.MisalignedAccessIsFault.Get().(bool)
|
|
if imgui.Checkbox("Treat Misaligned Accesses as Memory Faults", &misalignedAccessIsFault) {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.MisalignedAccessIsFault.Set(misalignedAccessIsFault)
|
|
}
|
|
|
|
undefinedSymbolWarning := win.img.dbg.VCS().Env.Prefs.ARM.UndefinedSymbolWarning.Get().(bool)
|
|
if imgui.Checkbox("Undefined Symbols Warning", &undefinedSymbolWarning) {
|
|
win.img.dbg.VCS().Env.Prefs.ARM.UndefinedSymbolWarning.Set(undefinedSymbolWarning)
|
|
}
|
|
imguiTooltipSimple(`It is possible to compile an ELF binary with undefined symbols.
|
|
This option presents causes a warning to appear when such a binary is loaded`, true)
|
|
}
|
|
|
|
func (win *winPrefs) drawPlusROMTab() {
|
|
imgui.Spacing()
|
|
|
|
if _, ok := win.img.cache.VCS.Mem.Cart.GetContainer().(*plusrom.PlusROM); !ok {
|
|
imgui.Text("Current ROM is not a PlusROM")
|
|
imguiSeparator()
|
|
}
|
|
|
|
drawPlusROMNick(win.img)
|
|
}
|
|
|
|
func (win *winPrefs) drawUITab() {
|
|
imgui.Spacing()
|
|
|
|
if imgui.CollapsingHeaderV("Font Sizing and Spacing", imgui.TreeNodeFlagsDefaultOpen) {
|
|
imgui.Spacing()
|
|
|
|
var resetFonts bool
|
|
|
|
const (
|
|
minFontSize = 8
|
|
maxFontSize = 30
|
|
)
|
|
|
|
// flags to be used in float slider
|
|
sliderFlags := imgui.SliderFlagsAlwaysClamp | imgui.SliderFlagsNoInput
|
|
|
|
// gui font
|
|
guiSize := int32(win.img.prefs.guiFontSize.Get().(int))
|
|
if imgui.SliderIntV("##guiFontSizeSlider", &guiSize, minFontSize, maxFontSize, "%dpt", sliderFlags) {
|
|
win.img.prefs.guiFontSize.Set(guiSize)
|
|
}
|
|
if imgui.IsItemDeactivatedAfterEdit() {
|
|
resetFonts = true
|
|
}
|
|
imgui.SameLineV(0, 5)
|
|
|
|
guiSizeS := fmt.Sprintf("%d", guiSize)
|
|
if imguiDecimalInput("GUI Font Size##guiFontSize", 3, &guiSizeS) {
|
|
if sz, err := strconv.ParseInt(guiSizeS, 10, 32); err == nil {
|
|
if sz >= minFontSize && sz <= maxFontSize {
|
|
win.img.prefs.guiFontSize.Set(sz)
|
|
resetFonts = true
|
|
}
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
// terminal font
|
|
terminalSize := int32(win.img.prefs.terminalFontSize.Get().(int))
|
|
if imgui.SliderIntV("##terminalFontSizeSlider", &terminalSize, minFontSize, maxFontSize, "%dpt", sliderFlags) {
|
|
win.img.prefs.terminalFontSize.Set(terminalSize)
|
|
}
|
|
if imgui.IsItemDeactivatedAfterEdit() {
|
|
resetFonts = true
|
|
}
|
|
imgui.SameLineV(0, 5)
|
|
|
|
terminalSizeS := fmt.Sprintf("%d", terminalSize)
|
|
if imguiDecimalInput("Terminal Font Size##terminalFontSize", 3, &terminalSizeS) {
|
|
if sz, err := strconv.ParseInt(terminalSizeS, 10, 32); err == nil {
|
|
if sz >= minFontSize && sz <= maxFontSize {
|
|
win.img.prefs.terminalFontSize.Set(sz)
|
|
resetFonts = true
|
|
}
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
// code font
|
|
codeSize := int32(win.img.prefs.codeFontSize.Get().(int))
|
|
if imgui.SliderIntV("##codeFontSizeSlider", &codeSize, minFontSize, maxFontSize, "%dpt", sliderFlags) {
|
|
win.img.prefs.codeFontSize.Set(codeSize)
|
|
}
|
|
if imgui.IsItemDeactivatedAfterEdit() {
|
|
resetFonts = true
|
|
}
|
|
imgui.SameLineV(0, 5)
|
|
|
|
codeSizeS := fmt.Sprintf("%d", codeSize)
|
|
if imguiDecimalInput("Code Font Size##codeFontSize", 3, &codeSizeS) {
|
|
if sz, err := strconv.ParseInt(codeSizeS, 10, 32); err == nil {
|
|
if sz >= minFontSize && sz <= maxFontSize {
|
|
win.img.prefs.codeFontSize.Set(sz)
|
|
resetFonts = true
|
|
}
|
|
}
|
|
}
|
|
|
|
imgui.Spacing()
|
|
|
|
// code line spacing
|
|
lineSpacing := int32(win.img.prefs.codeFontLineSpacing.Get().(int))
|
|
if imgui.SliderInt("Line spacing in ARM Code window", &lineSpacing, 0, 5) {
|
|
win.img.prefs.codeFontLineSpacing.Set(lineSpacing)
|
|
}
|
|
|
|
// reset fonts if prefs have changed
|
|
if resetFonts {
|
|
win.img.resetFonts = resetFontFrames
|
|
}
|
|
}
|
|
}
|
|
|
|
func (win *winPrefs) drawDiskButtons() {
|
|
if imgui.Button("Save All") {
|
|
err := win.img.prefs.save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (imgui debugger) preferences: %v", err)
|
|
}
|
|
err = win.img.displayPrefs.CRT.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (display/crt) preferences: %v", err)
|
|
}
|
|
err = win.img.displayPrefs.Colour.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (display/colour) preferences: %v", err)
|
|
}
|
|
err = win.img.audio.Prefs.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (sdlaudio) preferences: %v", err)
|
|
}
|
|
win.img.dbg.PushFunction(func() {
|
|
err = win.img.dbg.VCS().Env.Prefs.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (vcs) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.TV.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (tv) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.ARM.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (arm) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.AtariVox.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (atarivox) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.PlusROM.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (plusrom) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.Revision.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (tia revisions) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.Rewind.Prefs.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (rewind) preferences: %v", err)
|
|
}
|
|
if win.img.mode.Load().(govern.Mode) == govern.ModeDebugger {
|
|
err = win.img.dbg.Disasm.Prefs.Save()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not save (disasm) preferences: %v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
imgui.SameLine()
|
|
if imgui.Button("Restore All") {
|
|
err := win.img.prefs.load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (imgui debugger) preferences: %v", err)
|
|
}
|
|
err = win.img.displayPrefs.CRT.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (display/crt) preferences: %v", err)
|
|
}
|
|
err = win.img.displayPrefs.Colour.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (display/colour) preferences: %v", err)
|
|
}
|
|
err = win.img.audio.Prefs.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (sdlaudio) preferences: %v", err)
|
|
}
|
|
win.img.dbg.PushFunction(func() {
|
|
err = win.img.dbg.VCS().Env.Prefs.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (vcs) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.TV.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (tv) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.ARM.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (arm) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.AtariVox.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (atarivox) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.PlusROM.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (plusrom) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.VCS().Env.Prefs.Revision.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (tia revisions) preferences: %v", err)
|
|
}
|
|
err = win.img.dbg.Rewind.Prefs.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (rewind) preferences: %v", err)
|
|
}
|
|
if win.img.mode.Load().(govern.Mode) == govern.ModeDebugger {
|
|
err = win.img.dbg.Disasm.Prefs.Load()
|
|
if err != nil {
|
|
logger.Logf(logger.Allow, "sdlimgui", "could not restore (disasm) preferences: %v", err)
|
|
}
|
|
}
|
|
})
|
|
|
|
win.img.resetFonts = resetFontFrames
|
|
}
|
|
}
|
|
|
|
func prefsCheckbox(p *prefs.Bool, id string) {
|
|
v := p.Get().(bool)
|
|
if imgui.Checkbox(id, &v) {
|
|
p.Set(v)
|
|
}
|
|
}
|