mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2024-05-20 05:40:49 -04:00
removed emulation package. moved types to debugger/govern package
the emulation package has been unecessary since the amalgamation of the debugger and play modes. in order to allow switching between the two modes it was necessary to remove the playmode package and to move all playmode loops and other considerations into the debugger package. as a result the abstraction offered by the emulation package is uncessary
This commit is contained in:
parent
faddd7dfb9
commit
28ffedbf11
|
@ -24,7 +24,7 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/instance"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
|
@ -207,14 +207,14 @@ func (cmp *Comparison) CreateFromLoader(cartload cartridgeloader.Loader) error {
|
|||
return
|
||||
}
|
||||
|
||||
err = cmp.VCS.Run(func() (emulation.State, error) {
|
||||
err = cmp.VCS.Run(func() (govern.State, error) {
|
||||
select {
|
||||
case <-cmp.emulationQuit:
|
||||
return emulation.Ending, nil
|
||||
return govern.Ending, nil
|
||||
default:
|
||||
}
|
||||
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
if err != nil {
|
||||
cmp.driver.quit <- err
|
||||
|
|
|
@ -27,12 +27,12 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/coprocessor/developer"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger/dbgmem"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/script"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
|
||||
"github.com/jetsetilly/gopher2600/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/disassembly/symbols"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/hardware/cpu/registers"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/plusrom"
|
||||
|
@ -266,7 +266,7 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) error {
|
|||
coords = dbg.vcs.TV.AdjCoords(adj, adjAmount)
|
||||
}
|
||||
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(func() error {
|
||||
// update catchupQuantum before starting rewind process
|
||||
dbg.catchupQuantum = dbg.stepQuantum
|
||||
|
@ -380,13 +380,13 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) error {
|
|||
dbg.runUntilHalt = false
|
||||
|
||||
if arg == "LAST" {
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(dbg.Rewind.GotoLast)
|
||||
} else if arg == "SUMMARY" {
|
||||
dbg.printLine(terminal.StyleInstrument, dbg.Rewind.String())
|
||||
} else {
|
||||
frame, _ := strconv.Atoi(arg)
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(func() error {
|
||||
err := dbg.Rewind.GotoFrame(frame)
|
||||
if err != nil {
|
||||
|
@ -411,7 +411,7 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) error {
|
|||
}
|
||||
}
|
||||
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(func() error {
|
||||
err := dbg.Rewind.GotoCoords(coords)
|
||||
if err != nil {
|
||||
|
|
|
@ -30,11 +30,11 @@ import (
|
|||
coprocDisasm "github.com/jetsetilly/gopher2600/coprocessor/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger/dbgmem"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/script"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
|
||||
"github.com/jetsetilly/gopher2600/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/cpu/execution"
|
||||
|
@ -290,7 +290,7 @@ type Debugger struct {
|
|||
// CreateUserInterface is used to initialise the user interface used by the
|
||||
// emulation. It returns an instance of both the GUI and Terminal interfaces
|
||||
// in the repsective packages.
|
||||
type CreateUserInterface func(emulation.Emulation) (gui.GUI, terminal.Terminal, error)
|
||||
type CreateUserInterface func(*Debugger) (gui.GUI, terminal.Terminal, error)
|
||||
|
||||
// NewDebugger creates and initialises everything required for a new debugging
|
||||
// session.
|
||||
|
@ -312,8 +312,8 @@ func NewDebugger(opts CommandLineOptions, create CreateUserInterface) (*Debugger
|
|||
// emulator is starting in the "none" mode (the advangatge of this is that
|
||||
// we get to set the underlying type of the atomic.Value early before
|
||||
// anyone has a change to call State() or Mode() from another thread)
|
||||
dbg.state.Store(emulation.EmulatorStart)
|
||||
dbg.mode.Store(emulation.ModeNone)
|
||||
dbg.state.Store(govern.EmulatorStart)
|
||||
dbg.mode.Store(govern.ModeNone)
|
||||
|
||||
var err error
|
||||
|
||||
|
@ -449,17 +449,17 @@ func NewDebugger(opts CommandLineOptions, create CreateUserInterface) (*Debugger
|
|||
}
|
||||
|
||||
// VCS implements the emulation.Emulation interface.
|
||||
func (dbg *Debugger) VCS() emulation.VCS {
|
||||
func (dbg *Debugger) VCS() *hardware.VCS {
|
||||
return dbg.vcs
|
||||
}
|
||||
|
||||
// TV implements the emulation.Emulation interface.
|
||||
func (dbg *Debugger) TV() emulation.TV {
|
||||
func (dbg *Debugger) TV() *television.Television {
|
||||
return dbg.vcs.TV
|
||||
}
|
||||
|
||||
// Debugger implements the emulation.Emulation interface.
|
||||
func (dbg *Debugger) Debugger() emulation.Debugger {
|
||||
func (dbg *Debugger) Debugger() *Debugger {
|
||||
return dbg
|
||||
}
|
||||
|
||||
|
@ -469,13 +469,13 @@ func (dbg *Debugger) UserInput() chan userinput.Event {
|
|||
}
|
||||
|
||||
// State implements the emulation.Emulation interface.
|
||||
func (dbg *Debugger) State() emulation.State {
|
||||
return dbg.state.Load().(emulation.State)
|
||||
func (dbg *Debugger) State() govern.State {
|
||||
return dbg.state.Load().(govern.State)
|
||||
}
|
||||
|
||||
// Mode implements the emulation.Emulation interface.
|
||||
func (dbg *Debugger) Mode() emulation.Mode {
|
||||
return dbg.mode.Load().(emulation.Mode)
|
||||
func (dbg *Debugger) Mode() govern.Mode {
|
||||
return dbg.mode.Load().(govern.Mode)
|
||||
}
|
||||
|
||||
// set the emulation state
|
||||
|
@ -484,7 +484,7 @@ func (dbg *Debugger) Mode() emulation.Mode {
|
|||
// debugger.SetFeature(ReqSetPause) even from within the debugger package
|
||||
// (SetFeature() puts the request on the RawEvent Queue meaning it will be
|
||||
// inserted in the input loop correctly)
|
||||
func (dbg *Debugger) setState(state emulation.State) {
|
||||
func (dbg *Debugger) setState(state govern.State) {
|
||||
dbg.setStateQuiet(state, false)
|
||||
}
|
||||
|
||||
|
@ -493,8 +493,8 @@ func (dbg *Debugger) setState(state emulation.State) {
|
|||
//
|
||||
// * see setState() comment, although debugger.SetFeature(ReqSetPause) will
|
||||
// always be "noisy"
|
||||
func (dbg *Debugger) setStateQuiet(state emulation.State, quiet bool) {
|
||||
if state == emulation.Rewinding {
|
||||
func (dbg *Debugger) setStateQuiet(state govern.State, quiet bool) {
|
||||
if state == govern.Rewinding {
|
||||
dbg.vcs.Mem.Cart.BreakpointsDisable(true)
|
||||
dbg.endPlayback()
|
||||
dbg.endRecording()
|
||||
|
@ -533,15 +533,15 @@ func (dbg *Debugger) setStateQuiet(state emulation.State, quiet bool) {
|
|||
prevState := dbg.State()
|
||||
dbg.state.Store(state)
|
||||
|
||||
if !quiet && dbg.Mode() == emulation.ModePlay {
|
||||
if !quiet && dbg.Mode() == govern.ModePlay {
|
||||
switch state {
|
||||
case emulation.Initialising:
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventInitialising)
|
||||
case emulation.Paused:
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventPause)
|
||||
case emulation.Running:
|
||||
if prevState > emulation.Initialising {
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventRun)
|
||||
case govern.Initialising:
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventInitialising)
|
||||
case govern.Paused:
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventPause)
|
||||
case govern.Running:
|
||||
if prevState > govern.Initialising {
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventRun)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -552,7 +552,7 @@ func (dbg *Debugger) setStateQuiet(state emulation.State, quiet bool) {
|
|||
// * consider using debugger.SetFeature(ReqSetMode) even from within the
|
||||
// debugger package (SetFeature() puts the request on the RawEvent Queue
|
||||
// meaning it will be inserted in the input loop correctly)
|
||||
func (dbg *Debugger) setMode(mode emulation.Mode) error {
|
||||
func (dbg *Debugger) setMode(mode govern.Mode) error {
|
||||
if dbg.Mode() == mode {
|
||||
return nil
|
||||
}
|
||||
|
@ -566,8 +566,8 @@ func (dbg *Debugger) setMode(mode emulation.Mode) error {
|
|||
// however, because the user has asked to switch to playmode we should
|
||||
// cause the debugger mode to run until the halting condition is matched
|
||||
// (which we know will occur in the almost immediate future)
|
||||
if mode == emulation.ModePlay && !dbg.halting.allowPlaymode() {
|
||||
if dbg.Mode() == emulation.ModeDebugger {
|
||||
if mode == govern.ModePlay && !dbg.halting.allowPlaymode() {
|
||||
if dbg.Mode() == govern.ModeDebugger {
|
||||
dbg.runUntilHalt = true
|
||||
dbg.continueEmulation = true
|
||||
}
|
||||
|
@ -601,26 +601,26 @@ func (dbg *Debugger) setMode(mode emulation.Mode) error {
|
|||
// screen.go)
|
||||
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
dbg.vcs.TV.AddFrameTrigger(dbg.Rewind)
|
||||
dbg.vcs.TV.AddFrameTrigger(dbg.counter)
|
||||
|
||||
// simple detection of whether cartridge is ejected when switching to
|
||||
// playmode. if it is ejected then open ROM selected.
|
||||
if dbg.Mode() == emulation.ModePlay && dbg.vcs.Mem.Cart.IsEjected() {
|
||||
if dbg.Mode() == govern.ModePlay && dbg.vcs.Mem.Cart.IsEjected() {
|
||||
err = dbg.forceROMSelector()
|
||||
if err != nil {
|
||||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
} else {
|
||||
dbg.setState(emulation.Running)
|
||||
dbg.setState(govern.Running)
|
||||
}
|
||||
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
dbg.vcs.TV.AddFrameTrigger(dbg.Rewind)
|
||||
dbg.vcs.TV.AddFrameTrigger(dbg.ref)
|
||||
dbg.vcs.TV.AddFrameTrigger(dbg.counter)
|
||||
dbg.setState(emulation.Paused)
|
||||
dbg.setState(govern.Paused)
|
||||
|
||||
// debugger needs knowledge about previous frames (via the reflector)
|
||||
// if we're moving from playmode. also we want to make sure we end on
|
||||
|
@ -630,7 +630,7 @@ func (dbg *Debugger) setMode(mode emulation.Mode) error {
|
|||
// catchupEndAdj we will always enter the debugger on the last cycle of
|
||||
// an instruction. although correct in terms of coordinates, is
|
||||
// confusing.
|
||||
if prevMode == emulation.ModePlay {
|
||||
if prevMode == govern.ModePlay {
|
||||
dbg.catchupEndAdj = true
|
||||
dbg.RerunLastNFrames(2)
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ func (dbg *Debugger) StartInDebugMode(filename string) error {
|
|||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
|
||||
err = dbg.setMode(emulation.ModeDebugger)
|
||||
err = dbg.setMode(govern.ModeDebugger)
|
||||
if err != nil {
|
||||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
|
@ -808,7 +808,7 @@ func (dbg *Debugger) StartInPlayMode(filename string) error {
|
|||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
|
||||
err = dbg.setMode(emulation.ModePlay)
|
||||
err = dbg.setMode(govern.ModePlay)
|
||||
if err != nil {
|
||||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
|
@ -842,7 +842,7 @@ func (dbg *Debugger) run() error {
|
|||
// inputloop will continue until debugger is to be terminated
|
||||
for dbg.running {
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
err := dbg.playLoop()
|
||||
if err != nil {
|
||||
// if we ever encounter a cartridge ejected error in playmode
|
||||
|
@ -856,14 +856,14 @@ func (dbg *Debugger) run() error {
|
|||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
}
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
switch dbg.State() {
|
||||
case emulation.Running:
|
||||
case govern.Running:
|
||||
dbg.runUntilHalt = true
|
||||
dbg.continueEmulation = true
|
||||
case emulation.Paused:
|
||||
case govern.Paused:
|
||||
dbg.haltImmediately = true
|
||||
case emulation.Rewinding:
|
||||
case govern.Rewinding:
|
||||
default:
|
||||
return curated.Errorf("emulation state not supported on *start* of debugging loop: %s", dbg.State())
|
||||
}
|
||||
|
@ -880,7 +880,7 @@ func (dbg *Debugger) run() error {
|
|||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
dbg.unwindLoopRestart = nil
|
||||
} else if dbg.State() == emulation.Ending {
|
||||
} else if dbg.State() == govern.Ending {
|
||||
dbg.running = false
|
||||
}
|
||||
default:
|
||||
|
@ -948,19 +948,19 @@ func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error)
|
|||
dbg.bots.Quit()
|
||||
|
||||
// attching a cartridge implies the initialise state
|
||||
dbg.setState(emulation.Initialising)
|
||||
dbg.setState(govern.Initialising)
|
||||
|
||||
// set state after initialisation according to the emulation mode
|
||||
defer func() {
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
if dbg.runUntilHalt && e == nil {
|
||||
dbg.setState(emulation.Running)
|
||||
dbg.setState(govern.Running)
|
||||
} else {
|
||||
dbg.setState(emulation.Paused)
|
||||
dbg.setState(govern.Paused)
|
||||
}
|
||||
case emulation.ModePlay:
|
||||
dbg.setState(emulation.Running)
|
||||
case govern.ModePlay:
|
||||
dbg.setState(govern.Running)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -1224,12 +1224,12 @@ func (dbg *Debugger) endComparison() {
|
|||
|
||||
func (dbg *Debugger) hotload() (e error) {
|
||||
// tell GUI that we're in the initialistion phase
|
||||
dbg.setState(emulation.Initialising)
|
||||
dbg.setState(govern.Initialising)
|
||||
defer func() {
|
||||
if dbg.runUntilHalt && e == nil {
|
||||
dbg.setState(emulation.Running)
|
||||
dbg.setState(govern.Running)
|
||||
} else {
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventPause)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventPause)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/prefs"
|
||||
)
|
||||
|
@ -143,7 +142,7 @@ func TestDebugger_withNonExistantInitScript(t *testing.T) {
|
|||
|
||||
var trm *mockTerm
|
||||
|
||||
create := func(e emulation.Emulation) (gui.GUI, terminal.Terminal, error) {
|
||||
create := func(dbg *debugger.Debugger) (gui.GUI, terminal.Terminal, error) {
|
||||
trm = newMockTerm(t)
|
||||
return &mockGUI{}, trm, nil
|
||||
}
|
||||
|
@ -166,7 +165,7 @@ func TestDebugger(t *testing.T) {
|
|||
|
||||
var trm *mockTerm
|
||||
|
||||
create := func(e emulation.Emulation) (gui.GUI, terminal.Terminal, error) {
|
||||
create := func(dbg *debugger.Debugger) (gui.GUI, terminal.Terminal, error) {
|
||||
trm = newMockTerm(t)
|
||||
return &mockGUI{}, trm, nil
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/cpu/instructions"
|
||||
"github.com/jetsetilly/gopher2600/hardware/cpu/registers"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory"
|
||||
|
@ -48,7 +48,7 @@ func (dbg *Debugger) PushDeepPoke(addr uint16, value uint8, newValue uint8, valu
|
|||
}
|
||||
|
||||
dbg.PushRawEventImmediate(func() {
|
||||
dbg.setStateQuiet(emulation.Rewinding, true)
|
||||
dbg.setStateQuiet(govern.Rewinding, true)
|
||||
dbg.unwindLoop(doDeepPoke)
|
||||
})
|
||||
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Package emulation is an abstraction of the various modes Gopher2600 can
|
||||
// operate in, principally play-mode and the debugger.
|
||||
// Package govern defines the types that define the current condition of the
|
||||
// emulation. The three conditions are Mode, State and Event.
|
||||
//
|
||||
// It is useful when linking packages/types that require a *passive* knowledge
|
||||
// of the emulation. For example, a GUI might want to know what the current
|
||||
// state of the emulation is.
|
||||
//
|
||||
// Some package types might still need an active knowledge of the emulation
|
||||
// however. In which case, simply relying on the Emulation interface is
|
||||
// probably not enough.
|
||||
package emulation
|
||||
// Also defined is the method of requesting a state change from the GUI. Most
|
||||
// often state change comes from the emulation but in some intances it is
|
||||
// necessary to instruct the emulation to change mode or state - for example,
|
||||
// from the GUI as a result of the a user request.
|
||||
package govern
|
|
@ -13,54 +13,10 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package emulation
|
||||
package govern
|
||||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/userinput"
|
||||
)
|
||||
|
||||
// TV is a minimal abstraction of the TV hardware. Exists mainly to avoid a
|
||||
// circular import to the hardware package.
|
||||
//
|
||||
// The only likely implementation of this interface is the
|
||||
// television.Television type.
|
||||
type TV interface {
|
||||
}
|
||||
|
||||
// VCS is a minimal abstraction of the VCS hardware. Exists mainly to avoid a
|
||||
// circular import to the hardware package.
|
||||
//
|
||||
// The only likely implementation of this interface is the hardware.VCS type.
|
||||
type VCS interface {
|
||||
}
|
||||
|
||||
// VCS is a minimal abstraction of the Gopher2600 debugger. Exists mainly to
|
||||
// avoid a circular import to the debugger package.
|
||||
//
|
||||
// The only likely implementation of this interface is the debugger.Debugger
|
||||
// type.
|
||||
type Debugger interface {
|
||||
}
|
||||
|
||||
// Emulation defines the public functions required for a GUI implementation
|
||||
// (and possibly other things) to interface with the underlying emulator.
|
||||
type Emulation interface {
|
||||
TV() TV
|
||||
VCS() VCS
|
||||
Debugger() Debugger
|
||||
UserInput() chan userinput.Event
|
||||
|
||||
// Send a request to set an emulation feature
|
||||
SetFeature(request FeatureReq, args ...FeatureReqData) error
|
||||
|
||||
// Immediate request for the state and mode of the emulation
|
||||
State() State
|
||||
Mode() Mode
|
||||
}
|
||||
|
||||
// Mode inidicates the broad features of the emulation. For example, Debugger
|
||||
// indicates that the emulation is capable or is willing to handle debugging
|
||||
// features.
|
||||
// Mode inidicates the broad features of the emulation. Currently defined to be
|
||||
// debugger and play.
|
||||
type Mode int
|
||||
|
||||
func (m Mode) String() string {
|
||||
|
@ -112,9 +68,9 @@ const (
|
|||
Ending
|
||||
)
|
||||
|
||||
// Event describes an event that might occur in the emulation which is outside
|
||||
// of the scope of the VCS. For example, when the emulation is paused an
|
||||
// EventPause can be sent to the GUI (see FeatureReq type in the gui package).
|
||||
// Event is something that happens to change the state of the emulation. For
|
||||
// example, the user presses the pause while playing game. This will cause the
|
||||
// GUI to send an EventPause event to the emulation.
|
||||
type Event int
|
||||
|
||||
// List of defined events.
|
||||
|
@ -130,3 +86,30 @@ const (
|
|||
EventMute
|
||||
EventUnmute
|
||||
)
|
||||
|
||||
// FeatureReq is used to request the setting of an emulation attribute
|
||||
// eg. a pause request from the GUI
|
||||
type FeatureReq string
|
||||
|
||||
// FeatureReqData represents the information associated with a FeatureReq. See
|
||||
// commentary for the defined FeatureReq values for the underlying type.
|
||||
type FeatureReqData interface{}
|
||||
|
||||
// List of valid feature requests. argument must be of the type specified or
|
||||
// else the interface{} type conversion will fail and the application will
|
||||
// probably crash.
|
||||
//
|
||||
// Note that, like the name suggests, these are requests, they may or may not
|
||||
// be satisfied depending on other conditions in the GUI.
|
||||
const (
|
||||
// notify gui of the underlying emulation mode.
|
||||
ReqSetPause FeatureReq = "ReqSetPause" // bool
|
||||
|
||||
// change emulation mode
|
||||
ReqSetMode FeatureReq = "ReqSetMode" // emulation.Mode
|
||||
)
|
||||
|
||||
// Sentinal error returned if emulation does no support requested feature.
|
||||
const (
|
||||
UnsupportedEmulationFeature = "unsupported emulation feature: %v"
|
||||
)
|
|
@ -16,7 +16,7 @@
|
|||
package debugger
|
||||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/coords"
|
||||
)
|
||||
|
||||
|
@ -26,25 +26,25 @@ import (
|
|||
// required for catchupLoop().
|
||||
func (dbg *Debugger) CatchUpLoop(tgt coords.TelevisionCoords) error {
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
fpscap := dbg.vcs.TV.SetFPSCap(false)
|
||||
defer dbg.vcs.TV.SetFPSCap(fpscap)
|
||||
|
||||
dbg.vcs.Run(func() (emulation.State, error) {
|
||||
dbg.vcs.Run(func() (govern.State, error) {
|
||||
dbg.userInputHandler_catchUpLoop()
|
||||
|
||||
coords := dbg.vcs.TV.GetCoords()
|
||||
if coords.Frame >= tgt.Frame {
|
||||
return emulation.Ending, nil
|
||||
return govern.Ending, nil
|
||||
}
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
// turn off TV's fps frame limiter
|
||||
fpsCap := dbg.vcs.TV.SetFPSCap(false)
|
||||
|
||||
// we've already set emulation state to emulation.Rewinding
|
||||
// we've already set emulation state to govern.Rewinding
|
||||
|
||||
dbg.catchupContinue = func() bool {
|
||||
newCoords := dbg.vcs.TV.GetCoords()
|
||||
|
@ -69,7 +69,7 @@ func (dbg *Debugger) CatchUpLoop(tgt coords.TelevisionCoords) error {
|
|||
dbg.vcs.TV.SetFPSCap(fpsCap)
|
||||
dbg.catchupContinue = nil
|
||||
dbg.catchupEnd = nil
|
||||
dbg.setState(emulation.Paused)
|
||||
dbg.setState(govern.Paused)
|
||||
dbg.runUntilHalt = false
|
||||
dbg.continueEmulation = dbg.catchupEndAdj
|
||||
dbg.catchupEndAdj = false
|
||||
|
|
|
@ -19,9 +19,9 @@ import (
|
|||
"io"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/script"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/hardware/cpu"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
)
|
||||
|
@ -35,7 +35,7 @@ import (
|
|||
// function is being called.
|
||||
//
|
||||
// note that the debugger state is not changed by this function. it is up to
|
||||
// the caller of the function to set emulation.State appropriately.
|
||||
// the caller of the function to set govern.State appropriately.
|
||||
func (dbg *Debugger) unwindLoop(onRestart func() error) {
|
||||
dbg.unwindLoopRestart = onRestart
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func (dbg *Debugger) catchupLoop(inputter terminal.Input) error {
|
|||
if !dbg.vcs.CPU.LastResult.Final {
|
||||
// if we're in the rewinding state then a new rewind event has
|
||||
// started and we must return immediately so that it can continue
|
||||
if dbg.State() == emulation.Rewinding {
|
||||
if dbg.State() == govern.Rewinding {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, isVideoStep bool) error
|
|||
var err error
|
||||
|
||||
for dbg.running {
|
||||
if dbg.Mode() != emulation.ModeDebugger {
|
||||
if dbg.Mode() != govern.ModeDebugger {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, isVideoStep bool) error
|
|||
}
|
||||
|
||||
// emulation has been put into a different mode. exit loop immediately
|
||||
if dbg.Mode() != emulation.ModeDebugger {
|
||||
if dbg.Mode() != govern.ModeDebugger {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, isVideoStep bool) error
|
|||
}
|
||||
|
||||
// set pause emulation state
|
||||
dbg.setState(emulation.Paused)
|
||||
dbg.setState(govern.Paused)
|
||||
|
||||
// take note of current machine state if the emulation was in a running
|
||||
// state and is halting just now
|
||||
|
@ -324,7 +324,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, isVideoStep bool) error
|
|||
}
|
||||
|
||||
// emulation has been put into a different mode. exit loop immediately
|
||||
if dbg.Mode() != emulation.ModeDebugger {
|
||||
if dbg.Mode() != govern.ModeDebugger {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -351,10 +351,10 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, isVideoStep bool) error
|
|||
// stepping.
|
||||
if dbg.halting.volatileTraps.isEmpty() {
|
||||
if inputter.IsInteractive() {
|
||||
dbg.setState(emulation.Running)
|
||||
dbg.setState(govern.Running)
|
||||
}
|
||||
} else {
|
||||
dbg.setState(emulation.Stepping)
|
||||
dbg.setState(govern.Stepping)
|
||||
}
|
||||
|
||||
// update comparison point before execution continues
|
||||
|
@ -362,7 +362,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, isVideoStep bool) error
|
|||
dbg.Rewind.SetComparison()
|
||||
}
|
||||
} else if inputter.IsInteractive() {
|
||||
dbg.setState(emulation.Stepping)
|
||||
dbg.setState(govern.Stepping)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ package debugger
|
|||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/userinput"
|
||||
|
@ -65,7 +65,7 @@ func (dbg *Debugger) playLoop() error {
|
|||
dbg.liveBankInfo = dbg.vcs.Mem.Cart.GetBank(dbg.vcs.CPU.PC.Address())
|
||||
|
||||
// run and handle events
|
||||
return dbg.vcs.Run(func() (emulation.State, error) {
|
||||
return dbg.vcs.Run(func() (govern.State, error) {
|
||||
// update counters. because of the way LastResult works we need to make
|
||||
// sure we only use it in the event that the CPU RdyFlag is set
|
||||
//
|
||||
|
@ -93,12 +93,12 @@ func (dbg *Debugger) playLoop() error {
|
|||
if dbg.halting.halt {
|
||||
// set debugging mode. halting messages will be preserved and
|
||||
// shown when entering debugging mode
|
||||
dbg.setMode(emulation.ModeDebugger)
|
||||
return emulation.Ending, nil
|
||||
dbg.setMode(govern.ModeDebugger)
|
||||
return govern.Ending, nil
|
||||
}
|
||||
|
||||
if dbg.Mode() != emulation.ModePlay {
|
||||
return emulation.Ending, nil
|
||||
if dbg.Mode() != govern.ModePlay {
|
||||
return govern.Ending, nil
|
||||
}
|
||||
|
||||
// return without checking interface unless we exceed the
|
||||
|
@ -113,12 +113,12 @@ func (dbg *Debugger) playLoop() error {
|
|||
case <-dbg.eventCheckPulse.C:
|
||||
err := dbg.readEventsHandler()
|
||||
if err != nil {
|
||||
return emulation.Ending, err
|
||||
return govern.Ending, err
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
if dbg.state.Load().(emulation.State) == emulation.Running {
|
||||
if dbg.state.Load().(govern.State) == govern.Running {
|
||||
dbg.Rewind.RecordState()
|
||||
}
|
||||
|
||||
|
|
|
@ -17,50 +17,49 @@ package debugger
|
|||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
)
|
||||
|
||||
func argLen(args []emulation.FeatureReqData, expectedLen int) error {
|
||||
func argLen(args []govern.FeatureReqData, expectedLen int) error {
|
||||
if len(args) != expectedLen {
|
||||
return curated.Errorf("wrong number of arguments (%d instead of %d)", len(args), expectedLen)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReqFeature implements the emulation.Emulation interface.
|
||||
func (dbg *Debugger) SetFeature(request emulation.FeatureReq, args ...emulation.FeatureReqData) error {
|
||||
// ReqFeature implements the govern.Emulation interface.
|
||||
func (dbg *Debugger) SetFeature(request govern.FeatureReq, args ...govern.FeatureReqData) error {
|
||||
var err error
|
||||
|
||||
switch request {
|
||||
case emulation.ReqSetPause:
|
||||
case govern.ReqSetPause:
|
||||
err = argLen(args, 1)
|
||||
if err != nil {
|
||||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
dbg.PushRawEvent(func() {
|
||||
// Pause implements the emulation.Emulation interface.
|
||||
if args[0].(bool) {
|
||||
dbg.setState(emulation.Paused)
|
||||
dbg.setState(govern.Paused)
|
||||
} else {
|
||||
dbg.setState(emulation.Running)
|
||||
dbg.setState(govern.Running)
|
||||
}
|
||||
})
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
err = curated.Errorf("not reacting to %s in debug mode (use terminal input instead)", request)
|
||||
}
|
||||
|
||||
case emulation.ReqSetMode:
|
||||
case govern.ReqSetMode:
|
||||
err = argLen(args, 1)
|
||||
if err != nil {
|
||||
return curated.Errorf("debugger: %v", err)
|
||||
}
|
||||
|
||||
dbg.PushRawEventImmediate(func() {
|
||||
err := dbg.setMode(args[0].(emulation.Mode))
|
||||
err := dbg.setMode(args[0].(govern.Mode))
|
||||
if err != nil {
|
||||
logger.Logf("debugger", err.Error())
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/coords"
|
||||
)
|
||||
|
@ -34,30 +34,30 @@ func (dbg *Debugger) RewindByAmount(amount int) bool {
|
|||
default:
|
||||
panic(fmt.Sprintf("Rewind: unsupported mode (%v)", dbg.Mode()))
|
||||
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
coords := dbg.vcs.TV.GetCoords()
|
||||
tl := dbg.Rewind.GetTimeline()
|
||||
|
||||
if amount < 0 && coords.Frame-1 <= tl.AvailableStart {
|
||||
dbg.setStateQuiet(emulation.Paused, true)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventRewindAtStart)
|
||||
dbg.setStateQuiet(govern.Paused, true)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventRewindAtStart)
|
||||
return false
|
||||
}
|
||||
|
||||
if amount > 0 && coords.Frame+1 >= tl.AvailableEnd {
|
||||
dbg.setStateQuiet(emulation.Paused, true)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventRewindAtEnd)
|
||||
dbg.setStateQuiet(govern.Paused, true)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventRewindAtEnd)
|
||||
return false
|
||||
}
|
||||
|
||||
dbg.setStateQuiet(emulation.Rewinding, true)
|
||||
dbg.setStateQuiet(govern.Rewinding, true)
|
||||
dbg.Rewind.GotoFrame(coords.Frame + amount)
|
||||
dbg.setStateQuiet(emulation.Paused, true)
|
||||
dbg.setStateQuiet(govern.Paused, true)
|
||||
|
||||
if amount < 0 {
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventRewindBack)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventRewindBack)
|
||||
} else {
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, emulation.EventRewindFoward)
|
||||
dbg.gui.SetFeature(gui.ReqEmulationEvent, govern.EventRewindFoward)
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -72,8 +72,8 @@ func (dbg *Debugger) RewindToFrame(fn int, last bool) bool {
|
|||
default:
|
||||
panic(fmt.Sprintf("RewindToFrame: unsupported mode (%v)", dbg.Mode()))
|
||||
|
||||
case emulation.ModeDebugger:
|
||||
if dbg.State() == emulation.Rewinding {
|
||||
case govern.ModeDebugger:
|
||||
if dbg.State() == govern.Rewinding {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -100,9 +100,9 @@ func (dbg *Debugger) RewindToFrame(fn int, last bool) bool {
|
|||
// how we push the doRewind() function depends on what kind of inputloop we
|
||||
// are currently in
|
||||
dbg.PushRawEventImmediate(func() {
|
||||
// set state to emulation.Rewinding as soon as possible (but
|
||||
// set state to govern.Rewinding as soon as possible (but
|
||||
// remembering that we must do it in the debugger goroutine)
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(doRewind)
|
||||
})
|
||||
|
||||
|
@ -118,8 +118,8 @@ func (dbg *Debugger) GotoCoords(coords coords.TelevisionCoords) bool {
|
|||
default:
|
||||
panic(fmt.Sprintf("GotoCoords: unsupported mode (%v)", dbg.Mode()))
|
||||
|
||||
case emulation.ModeDebugger:
|
||||
if dbg.State() == emulation.Rewinding {
|
||||
case govern.ModeDebugger:
|
||||
if dbg.State() == govern.Rewinding {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -139,9 +139,9 @@ func (dbg *Debugger) GotoCoords(coords coords.TelevisionCoords) bool {
|
|||
// how we push the doRewind() function depends on what kind of inputloop we
|
||||
// are currently in
|
||||
dbg.PushRawEventImmediate(func() {
|
||||
// set state to emulation.Rewinding as soon as possible (but
|
||||
// set state to govern.Rewinding as soon as possible (but
|
||||
// remembering that we must do it in the debugger goroutine)
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(doRewind)
|
||||
})
|
||||
|
||||
|
@ -157,8 +157,8 @@ func (dbg *Debugger) RerunLastNFrames(frames int) bool {
|
|||
default:
|
||||
panic(fmt.Sprintf("RerunLastNFrames: unsupported mode (%v)", dbg.Mode()))
|
||||
|
||||
case emulation.ModeDebugger:
|
||||
if dbg.State() == emulation.Rewinding {
|
||||
case govern.ModeDebugger:
|
||||
if dbg.State() == govern.Rewinding {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -194,9 +194,9 @@ func (dbg *Debugger) RerunLastNFrames(frames int) bool {
|
|||
// upate catchupQuantum before starting rewind process
|
||||
dbg.catchupQuantum = QuantumClock
|
||||
|
||||
// set state to emulation.Rewinding as soon as possible (but
|
||||
// set state to govern.Rewinding as soon as possible (but
|
||||
// remembering that we must do it in the debugger goroutine)
|
||||
dbg.setState(emulation.Rewinding)
|
||||
dbg.setState(govern.Rewinding)
|
||||
dbg.unwindLoop(doRewind)
|
||||
})
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ package debugger
|
|||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/userinput"
|
||||
)
|
||||
|
||||
|
@ -45,7 +45,7 @@ func (dbg *Debugger) userInputHandler(ev userinput.Event) error {
|
|||
|
||||
// mode specific special input (not passed to the VCS as controller input)
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
switch ev := ev.(type) {
|
||||
case userinput.EventMouseWheel:
|
||||
amount := int(ev.Delta) + dbg.rewindMouseWheelAccumulation
|
||||
|
@ -73,7 +73,7 @@ func (dbg *Debugger) userInputHandler(ev userinput.Event) error {
|
|||
}
|
||||
} else {
|
||||
dbg.rewindKeyboardAccumulation = 0
|
||||
if dbg.State() != emulation.Running {
|
||||
if dbg.State() != govern.Running {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (dbg *Debugger) userInputHandler(ev userinput.Event) error {
|
|||
}
|
||||
} else {
|
||||
dbg.rewindKeyboardAccumulation = 0
|
||||
if dbg.State() != emulation.Running {
|
||||
if dbg.State() != govern.Running {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -106,18 +106,18 @@ func (dbg *Debugger) userInputHandler(ev userinput.Event) error {
|
|||
if ev.Down {
|
||||
switch ev.Button {
|
||||
case userinput.GamepadButtonBack:
|
||||
if dbg.State() != emulation.Paused {
|
||||
dbg.SetFeature(emulation.ReqSetPause, true)
|
||||
if dbg.State() != govern.Paused {
|
||||
dbg.SetFeature(govern.ReqSetPause, true)
|
||||
} else {
|
||||
dbg.SetFeature(emulation.ReqSetPause, false)
|
||||
dbg.SetFeature(govern.ReqSetPause, false)
|
||||
}
|
||||
return nil
|
||||
case userinput.GamepadButtonGuide:
|
||||
switch dbg.Mode() {
|
||||
case emulation.ModePlay:
|
||||
dbg.SetFeature(emulation.ReqSetMode, emulation.ModeDebugger)
|
||||
case emulation.ModeDebugger:
|
||||
dbg.SetFeature(emulation.ReqSetMode, emulation.ModePlay)
|
||||
case govern.ModePlay:
|
||||
dbg.SetFeature(govern.ReqSetMode, govern.ModeDebugger)
|
||||
case govern.ModeDebugger:
|
||||
dbg.SetFeature(govern.ReqSetMode, govern.ModePlay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ func (dbg *Debugger) userInputHandler(ev userinput.Event) error {
|
|||
// direction). unpause if the emulation is currently paused
|
||||
//
|
||||
// * we're only allowing this for playmode
|
||||
if dbg.Mode() == emulation.ModePlay && dbg.State() == emulation.Paused && handled {
|
||||
dbg.SetFeature(emulation.ReqSetPause, false)
|
||||
if dbg.Mode() == govern.ModePlay && dbg.State() == govern.Paused && handled {
|
||||
dbg.SetFeature(govern.ReqSetPause, false)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
// 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 emulation
|
||||
|
||||
// FeatureReq is used to request the setting of an emulation attribute
|
||||
// eg. a pause request from the GUI
|
||||
type FeatureReq string
|
||||
|
||||
// FeatureReqData represents the information associated with a FeatureReq. See
|
||||
// commentary for the defined FeatureReq values for the underlying type.
|
||||
type FeatureReqData interface{}
|
||||
|
||||
// List of valid feature requests. argument must be of the type specified or
|
||||
// else the interface{} type conversion will fail and the application will
|
||||
// probably crash.
|
||||
//
|
||||
// Note that, like the name suggests, these are requests, they may or may not
|
||||
// be satisfied depending on other conditions in the GUI.
|
||||
const (
|
||||
// notify gui of the underlying emulation mode.
|
||||
ReqSetPause FeatureReq = "ReqSetPause" // bool
|
||||
|
||||
// change emulation mode
|
||||
ReqSetMode FeatureReq = "ReqSetMode" // emulation.Mode
|
||||
)
|
||||
|
||||
// Sentinal error returned if emulation does no support requested feature.
|
||||
const (
|
||||
UnsupportedEmulationFeature = "unsupported emulation feature: %v"
|
||||
)
|
|
@ -27,11 +27,11 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal/colorterm"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal/plainterm"
|
||||
"github.com/jetsetilly/gopher2600/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/gui/sdlimgui"
|
||||
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
|
||||
|
@ -236,10 +236,10 @@ func launch(sync *mainSync) {
|
|||
fallthrough
|
||||
|
||||
case "PLAY":
|
||||
err = emulate(emulation.ModePlay, md, sync)
|
||||
err = emulate(govern.ModePlay, md, sync)
|
||||
|
||||
case "DEBUG":
|
||||
err = emulate(emulation.ModeDebugger, md, sync)
|
||||
err = emulate(govern.ModeDebugger, md, sync)
|
||||
|
||||
case "DISASM":
|
||||
err = disasm(md)
|
||||
|
@ -267,7 +267,7 @@ const defaultInitScript = "debuggerInit"
|
|||
|
||||
// emulate is the main emulation launch function, shared by play and debug
|
||||
// modes. the other modes initialise and run the emulation differently.
|
||||
func emulate(emulationMode emulation.Mode, md *modalflag.Modes, sync *mainSync) error {
|
||||
func emulate(emulationMode govern.Mode, md *modalflag.Modes, sync *mainSync) error {
|
||||
// start new commandline mode. to this we'll add the command line arguments
|
||||
// that are specific to the emulation mode (it's unfortunate that mode is
|
||||
// used to describe two separate concepts but they really have nothing to
|
||||
|
@ -297,7 +297,7 @@ func emulate(emulationMode emulation.Mode, md *modalflag.Modes, sync *mainSync)
|
|||
opts.Profile = md.AddString("profile", "none", "run performance check with profiling: command separated CPU, MEM, TRACE or ALL")
|
||||
|
||||
// playmode specific arguments
|
||||
if emulationMode == emulation.ModePlay {
|
||||
if emulationMode == govern.ModePlay {
|
||||
opts.ComparisonROM = md.AddString("comparisonROM", "", "ROM to run in parallel for comparison")
|
||||
opts.ComparisonPrefs = md.AddString("comparisonPrefs", "", "preferences for comparison emulation")
|
||||
opts.Record = md.AddBool("record", false, "record user input to a file")
|
||||
|
@ -308,7 +308,7 @@ func emulate(emulationMode emulation.Mode, md *modalflag.Modes, sync *mainSync)
|
|||
}
|
||||
|
||||
// debugger specific arguments
|
||||
if emulationMode == emulation.ModeDebugger {
|
||||
if emulationMode == govern.ModeDebugger {
|
||||
opts.InitScript = md.AddString("initscript", defInitScript, "script to run on debugger start")
|
||||
opts.TermType = md.AddString("term", "IMGUI", "terminal type to use in debug mode: IMGUI, COLOR, PLAIN")
|
||||
} else {
|
||||
|
@ -348,7 +348,7 @@ func emulate(emulationMode emulation.Mode, md *modalflag.Modes, sync *mainSync)
|
|||
// prepare new debugger, supplying a debugger.CreateUserInterface function.
|
||||
// this function will be called by NewDebugger() and in turn will send a
|
||||
// GUI create message to the main goroutine
|
||||
dbg, err := debugger.NewDebugger(opts, func(e emulation.Emulation) (gui.GUI, terminal.Terminal, error) {
|
||||
dbg, err := debugger.NewDebugger(opts, func(e *debugger.Debugger) (gui.GUI, terminal.Terminal, error) {
|
||||
var term terminal.Terminal
|
||||
var scr gui.GUI
|
||||
|
||||
|
@ -402,13 +402,13 @@ func emulate(emulationMode emulation.Mode, md *modalflag.Modes, sync *mainSync)
|
|||
// a call to performance.RunProfiler()
|
||||
dbgLaunch := func() error {
|
||||
switch emulationMode {
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
err := dbg.StartInDebugMode(md.GetArg(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
err := dbg.StartInPlayMode(md.GetArg(0))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -435,9 +435,9 @@ func emulate(emulationMode emulation.Mode, md *modalflag.Modes, sync *mainSync)
|
|||
// filename argument for RunProfiler
|
||||
s := ""
|
||||
switch emulationMode {
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
s = "debugger"
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
s = "play"
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ package sdlimgui
|
|||
|
||||
import (
|
||||
"github.com/go-gl/gl/v3.2-core/gl"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/sdlimgui/shaders"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/specification"
|
||||
)
|
||||
|
@ -90,14 +90,14 @@ func (attr *dbgScrHelper) set(img *SdlImgui) {
|
|||
// end of critical section
|
||||
|
||||
// show cursor
|
||||
switch img.emulation.State() {
|
||||
case emulation.Paused:
|
||||
switch img.dbg.State() {
|
||||
case govern.Paused:
|
||||
gl.Uniform1i(attr.showCursor, 1)
|
||||
case emulation.Running:
|
||||
case govern.Running:
|
||||
gl.Uniform1i(attr.showCursor, 0)
|
||||
case emulation.Stepping:
|
||||
case govern.Stepping:
|
||||
gl.Uniform1i(attr.showCursor, 1)
|
||||
case emulation.Rewinding:
|
||||
case govern.Rewinding:
|
||||
gl.Uniform1i(attr.showCursor, 1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
"sync/atomic"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
)
|
||||
|
||||
// LazyDebugger lazily accesses Debugger information.
|
||||
|
@ -31,18 +31,18 @@ type LazyDebugger struct {
|
|||
liveDisasmEntry atomic.Value // disassembly.Entry
|
||||
breakpoints atomic.Value // debugger.BreakpointsQuery
|
||||
hasChanged atomic.Value // bool
|
||||
state atomic.Value // emulation.State
|
||||
state atomic.Value // govern.State
|
||||
|
||||
Quantum debugger.Quantum
|
||||
LiveDisasmEntry disassembly.Entry
|
||||
Breakpoints debugger.BreakpointsQuery
|
||||
HasChanged bool
|
||||
|
||||
// the emulation.State below is taken at the same time as the reset of the
|
||||
// the govern.State below is taken at the same time as the reset of the
|
||||
// lazy values. this value should be used in preference to the live
|
||||
// emulation.State() value (which is safe to obtain outside of the lazy
|
||||
// govern.State() value (which is safe to obtain outside of the lazy
|
||||
// system) when synchronisation is important
|
||||
State emulation.State
|
||||
State govern.State
|
||||
}
|
||||
|
||||
func newLazyDebugger(val *LazyValues) *LazyDebugger {
|
||||
|
@ -78,5 +78,5 @@ func (lz *LazyDebugger) update() {
|
|||
// load current hasChanged value and unlatch (see push() function)
|
||||
lz.HasChanged = lz.hasChanged.Load().(bool)
|
||||
lz.hasChanged.Store(false)
|
||||
lz.State, _ = lz.state.Load().(emulation.State)
|
||||
lz.State, _ = lz.state.Load().(govern.State)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"sync/atomic"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
)
|
||||
|
@ -28,12 +27,9 @@ import (
|
|||
// thread to the emulation. Use these values rather than directly accessing
|
||||
// those exposed by the emulation.
|
||||
type LazyValues struct {
|
||||
emulation emulation.Emulation
|
||||
|
||||
// vcs and dbg are taken from the emulation supplied to SetEmulation()
|
||||
dbg *debugger.Debugger
|
||||
tv *television.Television
|
||||
vcs *hardware.VCS
|
||||
dbg *debugger.Debugger
|
||||
|
||||
// pointers to these instances. non-pointer instances trigger the race
|
||||
// detector for some reason.
|
||||
|
@ -67,16 +63,12 @@ type LazyValues struct {
|
|||
}
|
||||
|
||||
// NewLazyValues is the preferred method of initialisation for the Values type.
|
||||
func NewLazyValues(e emulation.Emulation) *LazyValues {
|
||||
func NewLazyValues(dbg *debugger.Debugger) *LazyValues {
|
||||
val := &LazyValues{}
|
||||
|
||||
val.emulation = e
|
||||
val.tv = e.TV().(*television.Television)
|
||||
val.vcs = e.VCS().(*hardware.VCS)
|
||||
switch dbg := e.Debugger().(type) {
|
||||
case *debugger.Debugger:
|
||||
val.dbg = dbg
|
||||
}
|
||||
val.dbg = dbg
|
||||
val.tv = val.dbg.TV()
|
||||
val.vcs = val.dbg.VCS()
|
||||
|
||||
val.Debugger = newLazyDebugger(val)
|
||||
val.CPU = newLazyCPU(val)
|
||||
|
@ -107,7 +99,7 @@ func NewLazyValues(e emulation.Emulation) *LazyValues {
|
|||
|
||||
// Refresh lazy values.
|
||||
func (val *LazyValues) Refresh() {
|
||||
if val.emulation == nil {
|
||||
if val.dbg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -169,7 +161,7 @@ func (val *LazyValues) Refresh() {
|
|||
|
||||
// FastRefresh lazy values. Updates only the values that are needed in playmode.
|
||||
func (val *LazyValues) FastRefresh() {
|
||||
if val.emulation == nil {
|
||||
if val.dbg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
)
|
||||
|
||||
// manager handles windows and menus in the system.
|
||||
|
@ -209,13 +209,13 @@ func (wm *manager) draw() {
|
|||
}
|
||||
|
||||
switch wm.img.mode {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
// playmode draws the screen and other windows that have been listed
|
||||
// as being safe to draw in playmode
|
||||
for _, w := range wm.playmodeWindows {
|
||||
w.playmodeDraw()
|
||||
}
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
// see commentary for screenPos in windowManager declaration
|
||||
wm.screenPos = imgui.WindowPos()
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"math"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
)
|
||||
|
||||
|
@ -172,7 +172,7 @@ func (wm *manager) drawMenu() {
|
|||
wdth -= rightJustText(wdth, fmt.Sprintf("%.2fHz", wm.img.lz.TV.Hz), true)
|
||||
}
|
||||
|
||||
if wm.img.emulation.State() == emulation.Running {
|
||||
if wm.img.dbg.State() == govern.Running {
|
||||
if wm.img.lz.TV.ReqFPS < 1.0 {
|
||||
wdth -= rightJustText(wdth, "< 1 fps", true)
|
||||
} else if math.IsInf(float64(wm.img.lz.TV.ActualFPS), 0) {
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/prefs"
|
||||
"github.com/jetsetilly/gopher2600/resources"
|
||||
"github.com/jetsetilly/gopher2600/resources/fs"
|
||||
|
@ -77,7 +77,7 @@ func (wm *manager) saveManagerState() (rerr error) {
|
|||
continue
|
||||
}
|
||||
|
||||
s := fmt.Sprintf("%s%s%s%s%v\n", emulation.ModeDebugger.String(), prefs.KeySep, key, prefs.KeySep, win.debuggerIsOpen())
|
||||
s := fmt.Sprintf("%s%s%s%s%v\n", govern.ModeDebugger.String(), prefs.KeySep, key, prefs.KeySep, win.debuggerIsOpen())
|
||||
n, err := fmt.Fprint(f, s)
|
||||
if err != nil {
|
||||
return curated.Errorf("manager state: %v", err)
|
||||
|
@ -94,7 +94,7 @@ func (wm *manager) saveManagerState() (rerr error) {
|
|||
continue
|
||||
}
|
||||
|
||||
s := fmt.Sprintf("%s%s%s%s%v\n", emulation.ModePlay.String(), prefs.KeySep, key, prefs.KeySep, win.playmodeIsOpen())
|
||||
s := fmt.Sprintf("%s%s%s%s%v\n", govern.ModePlay.String(), prefs.KeySep, key, prefs.KeySep, win.playmodeIsOpen())
|
||||
n, err := fmt.Fprint(f, s)
|
||||
if err != nil {
|
||||
return curated.Errorf("manager state: %v", err)
|
||||
|
@ -159,13 +159,13 @@ func (wm *manager) loadManagerState() (rerr error) {
|
|||
k := spt[1]
|
||||
v := spt[2]
|
||||
|
||||
if m == emulation.ModeDebugger.String() {
|
||||
if m == govern.ModeDebugger.String() {
|
||||
if w, ok := wm.debuggerWindows[k]; ok {
|
||||
w.debuggerSetOpen(strings.ToUpper(v) == "TRUE")
|
||||
}
|
||||
}
|
||||
|
||||
if m == emulation.ModePlay.String() {
|
||||
if m == govern.ModePlay.String() {
|
||||
if w, ok := wm.playmodeWindows[k]; ok {
|
||||
w.playmodeSetOpen(strings.ToUpper(v) == "TRUE")
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ func newPlayScr(img *SdlImgui) *playScr {
|
|||
rightAlign: true,
|
||||
},
|
||||
emulationEvent: emulationEventNotification{
|
||||
emulation: img.emulation,
|
||||
emulation: img.dbg,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
"github.com/jetsetilly/gopher2600/hardware/riot/ports/plugging"
|
||||
|
@ -118,9 +119,9 @@ func (pn *peripheralNotification) draw(win *playScr) {
|
|||
// emulationEventNotification is used to draw an indicator on the screen for
|
||||
// events defined in the emulation package.
|
||||
type emulationEventNotification struct {
|
||||
emulation emulation.Emulation
|
||||
emulation *debugger.Debugger
|
||||
open bool
|
||||
currentEvent emulation.Event
|
||||
currentEvent govern.Event
|
||||
frames int
|
||||
|
||||
// audio mute is handled differently to other events. we want the icon for
|
||||
|
@ -130,18 +131,18 @@ type emulationEventNotification struct {
|
|||
mute bool
|
||||
}
|
||||
|
||||
func (ee *emulationEventNotification) set(event emulation.Event) {
|
||||
func (ee *emulationEventNotification) set(event govern.Event) {
|
||||
ee.currentEvent = event
|
||||
ee.open = true
|
||||
ee.frames = notificationDurationEvent
|
||||
switch event {
|
||||
case emulation.EventRun:
|
||||
case govern.EventRun:
|
||||
ee.frames = notificationDurationEventRun
|
||||
case emulation.EventScreenshot:
|
||||
case govern.EventScreenshot:
|
||||
ee.frames = notificationDurationScreenshot
|
||||
case emulation.EventMute:
|
||||
case govern.EventMute:
|
||||
ee.mute = true
|
||||
case emulation.EventUnmute:
|
||||
case govern.EventUnmute:
|
||||
ee.mute = false
|
||||
}
|
||||
}
|
||||
|
@ -155,16 +156,16 @@ func (ee *emulationEventNotification) tick() {
|
|||
|
||||
if ee.frames == 0 {
|
||||
// if emulation is paused then force the current event to EventPause
|
||||
if ee.emulation.State() == emulation.Paused {
|
||||
ee.currentEvent = emulation.EventPause
|
||||
if ee.emulation.State() == govern.Paused {
|
||||
ee.currentEvent = govern.EventPause
|
||||
}
|
||||
|
||||
// special handling of open when current event is EventPause or if mute
|
||||
// is enabled
|
||||
if ee.currentEvent != emulation.EventPause {
|
||||
if ee.currentEvent != govern.EventPause {
|
||||
if ee.mute {
|
||||
ee.open = true
|
||||
ee.currentEvent = emulation.EventMute
|
||||
ee.currentEvent = govern.EventMute
|
||||
} else {
|
||||
ee.open = false
|
||||
}
|
||||
|
@ -196,23 +197,23 @@ func (ee *emulationEventNotification) draw(win *playScr, hosted bool) {
|
|||
}
|
||||
|
||||
switch ee.currentEvent {
|
||||
case emulation.EventInitialising:
|
||||
case govern.EventInitialising:
|
||||
imgui.Text("")
|
||||
case emulation.EventPause:
|
||||
case govern.EventPause:
|
||||
imgui.Text(string(fonts.EmulationPause))
|
||||
case emulation.EventRun:
|
||||
case govern.EventRun:
|
||||
imgui.Text(string(fonts.EmulationRun))
|
||||
case emulation.EventRewindBack:
|
||||
case govern.EventRewindBack:
|
||||
imgui.Text(string(fonts.EmulationRewindBack))
|
||||
case emulation.EventRewindFoward:
|
||||
case govern.EventRewindFoward:
|
||||
imgui.Text(string(fonts.EmulationRewindForward))
|
||||
case emulation.EventRewindAtStart:
|
||||
case govern.EventRewindAtStart:
|
||||
imgui.Text(string(fonts.EmulationRewindAtStart))
|
||||
case emulation.EventRewindAtEnd:
|
||||
case govern.EventRewindAtEnd:
|
||||
imgui.Text(string(fonts.EmulationRewindAtEnd))
|
||||
case emulation.EventScreenshot:
|
||||
case govern.EventScreenshot:
|
||||
imgui.Text(string(fonts.Camera))
|
||||
case emulation.EventMute:
|
||||
case govern.EventMute:
|
||||
if hosted || win.img.prefs.audioMuteNotification.Get().(bool) {
|
||||
imgui.Text(string(fonts.AudioMute))
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ package sdlimgui
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
|
@ -128,7 +128,7 @@ func (pol *polling) wait() sdl.Event {
|
|||
} else {
|
||||
working := pol.awake ||
|
||||
pol.img.lz.Debugger.HasChanged ||
|
||||
pol.img.emulation.State() != emulation.Paused ||
|
||||
pol.img.dbg.State() != govern.Paused ||
|
||||
pol.img.wm.dbgScr.crtPreview
|
||||
|
||||
if working {
|
||||
|
|
|
@ -17,7 +17,7 @@ package sdlimgui
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/prefs"
|
||||
"github.com/jetsetilly/gopher2600/resources"
|
||||
)
|
||||
|
@ -236,11 +236,11 @@ func (p *preferences) loadWindowPreferences() error {
|
|||
var group string
|
||||
|
||||
switch p.img.mode {
|
||||
case emulation.ModeNone:
|
||||
case govern.ModeNone:
|
||||
p.img.plt.window.Hide()
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
group = "sdlimgui.debugger"
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
group = "sdlimgui.playmode"
|
||||
default:
|
||||
panic(fmt.Sprintf("cannot set window mode for unsupported emulation mode (%v)", p.img.mode))
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/bots"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
"github.com/jetsetilly/gopher2600/hardware/riot/ports/plugging"
|
||||
|
@ -54,7 +54,7 @@ func (img *SdlImgui) serviceSetFeature(request featureRequest) {
|
|||
case gui.ReqSetEmulationMode:
|
||||
err = argLen(request.args, 1)
|
||||
if err == nil {
|
||||
img.setEmulationMode(request.args[0].(emulation.Mode))
|
||||
img.setEmulationMode(request.args[0].(govern.Mode))
|
||||
}
|
||||
|
||||
case gui.ReqEnd:
|
||||
|
@ -106,7 +106,7 @@ func (img *SdlImgui) serviceSetFeature(request featureRequest) {
|
|||
if img.isPlaymode() {
|
||||
err = argLen(request.args, 1)
|
||||
if err == nil {
|
||||
img.playScr.emulationEvent.set(request.args[0].(emulation.Event))
|
||||
img.playScr.emulationEvent.set(request.args[0].(govern.Event))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"image/color"
|
||||
"sync"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/signal"
|
||||
|
@ -360,14 +360,14 @@ func (scr *screen) NewFrame(frameInfo television.FrameInfo) error {
|
|||
}
|
||||
|
||||
if scr.crit.monitorSync && scr.crit.monitorSyncInRange {
|
||||
switch scr.img.emulation.State() {
|
||||
case emulation.Rewinding:
|
||||
switch scr.img.dbg.State() {
|
||||
case govern.Rewinding:
|
||||
fallthrough
|
||||
case emulation.Paused:
|
||||
case govern.Paused:
|
||||
scr.crit.renderIdx = scr.crit.plotIdx
|
||||
scr.crit.prevRenderIdx = scr.crit.plotIdx
|
||||
scr.crit.bufferUsed = len(scr.crit.bufferPixels)
|
||||
case emulation.Running:
|
||||
case govern.Running:
|
||||
if scr.crit.bufferUsed > 0 {
|
||||
scr.crit.bufferUsed--
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ func (scr *screen) copyPixelsPlaymode() {
|
|||
// poor results for one frame kernels (depending on the ROM and what is
|
||||
// happening on the screen at the time of the pause ) and will be
|
||||
// sub-optimal for three frame kernels in almost all cases.
|
||||
if scr.img.emulation.State() == emulation.Paused {
|
||||
if scr.img.dbg.State() == govern.Paused {
|
||||
activePause := scr.img.prefs.activePause.Get().(bool)
|
||||
if scr.crit.pauseFrame || !activePause {
|
||||
copy(scr.crit.pixels.Pix, scr.crit.bufferPixels[scr.crit.renderIdx].Pix)
|
||||
|
|
|
@ -21,8 +21,8 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui/crt"
|
||||
"github.com/jetsetilly/gopher2600/gui/sdlaudio"
|
||||
"github.com/jetsetilly/gopher2600/gui/sdlimgui/lazyvalues"
|
||||
|
@ -63,16 +63,13 @@ type SdlImgui struct {
|
|||
// allow sufficient time to close the font size selector combo box
|
||||
resetFonts int
|
||||
|
||||
// parent emulation. should be set via setEmulation() only
|
||||
emulation emulation.Emulation
|
||||
|
||||
// the current mode of the underlying
|
||||
mode emulation.Mode
|
||||
mode govern.Mode
|
||||
|
||||
// taken from the emulation field and assigned in the setEmulation() function
|
||||
dbg *debugger.Debugger
|
||||
tv *television.Television
|
||||
vcs *hardware.VCS
|
||||
dbg *debugger.Debugger
|
||||
userinput chan userinput.Event
|
||||
|
||||
// lazy value system allows safe access to the debugger/emulation from the
|
||||
|
@ -127,21 +124,17 @@ type SdlImgui struct {
|
|||
// NewSdlImgui is the preferred method of initialisation for type SdlImgui
|
||||
//
|
||||
// MUST ONLY be called from the gui thread.
|
||||
func NewSdlImgui(e emulation.Emulation) (*SdlImgui, error) {
|
||||
func NewSdlImgui(dbg *debugger.Debugger) (*SdlImgui, error) {
|
||||
img := &SdlImgui{
|
||||
context: imgui.CreateContext(nil),
|
||||
io: imgui.CurrentIO(),
|
||||
postRenderFunctions: make(chan func(), 100),
|
||||
}
|
||||
|
||||
img.emulation = e
|
||||
img.tv = e.TV().(*television.Television)
|
||||
img.vcs = e.VCS().(*hardware.VCS)
|
||||
switch dbg := e.Debugger().(type) {
|
||||
case *debugger.Debugger:
|
||||
img.dbg = dbg
|
||||
}
|
||||
img.userinput = e.UserInput()
|
||||
img.dbg = dbg
|
||||
img.tv = img.dbg.TV()
|
||||
img.vcs = img.dbg.VCS()
|
||||
img.userinput = img.dbg.UserInput()
|
||||
|
||||
// path to dear imgui ini file
|
||||
iniPath, err := resources.JoinPath(imguiIniFile)
|
||||
|
@ -163,7 +156,7 @@ func NewSdlImgui(e emulation.Emulation) (*SdlImgui, error) {
|
|||
return nil, curated.Errorf("sdlimgui: %v", err)
|
||||
}
|
||||
|
||||
img.lz = lazyvalues.NewLazyValues(img.emulation)
|
||||
img.lz = lazyvalues.NewLazyValues(img.dbg)
|
||||
img.screen = newScreen(img)
|
||||
img.term = newTerm()
|
||||
|
||||
|
@ -298,18 +291,18 @@ func (img *SdlImgui) end() {
|
|||
|
||||
// draw gui. called from service loop.
|
||||
func (img *SdlImgui) draw() {
|
||||
if img.mode == emulation.ModeNone {
|
||||
if img.mode == govern.ModeNone {
|
||||
return
|
||||
}
|
||||
|
||||
if img.emulation.State() == emulation.EmulatorStart {
|
||||
if img.dbg.State() == govern.EmulatorStart {
|
||||
return
|
||||
}
|
||||
|
||||
imgui.PushFont(img.glsl.fonts.defaultFont)
|
||||
defer imgui.PopFont()
|
||||
|
||||
if img.mode == emulation.ModePlay {
|
||||
if img.mode == govern.ModePlay {
|
||||
img.playScr.draw()
|
||||
}
|
||||
|
||||
|
@ -320,14 +313,14 @@ func (img *SdlImgui) draw() {
|
|||
// is the gui in playmode or not. thread safe. called from emulation thread
|
||||
// and gui thread.
|
||||
func (img *SdlImgui) isPlaymode() bool {
|
||||
return img.mode == emulation.ModePlay
|
||||
return img.mode == govern.ModePlay
|
||||
}
|
||||
|
||||
// set emulation and handle the changeover gracefully. this includes the saving
|
||||
// and loading of preference groups.
|
||||
//
|
||||
// should only be called from gui thread.
|
||||
func (img *SdlImgui) setEmulationMode(mode emulation.Mode) error {
|
||||
func (img *SdlImgui) setEmulationMode(mode govern.Mode) error {
|
||||
// release captured mouse before switching emulation modes. if we don't do
|
||||
// this then the capture state will remain if we flip back to the emulation
|
||||
// mode later. at this point the captured mouse can cause confusion
|
||||
|
@ -337,12 +330,12 @@ func (img *SdlImgui) setEmulationMode(mode emulation.Mode) error {
|
|||
img.prefs.loadWindowPreferences()
|
||||
|
||||
switch mode {
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
img.screen.clearTextureRenderers()
|
||||
img.screen.addTextureRenderer(img.wm.dbgScr)
|
||||
img.plt.window.Show()
|
||||
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
img.screen.clearTextureRenderers()
|
||||
img.screen.addTextureRenderer(img.playScr)
|
||||
img.plt.window.Show()
|
||||
|
@ -379,9 +372,9 @@ func (img *SdlImgui) setAudioMute() {
|
|||
if img.isPlaymode() {
|
||||
mute = img.prefs.audioMutePlaymode.Get().(bool)
|
||||
if mute {
|
||||
img.playScr.emulationEvent.set(emulation.EventMute)
|
||||
img.playScr.emulationEvent.set(govern.EventMute)
|
||||
} else {
|
||||
img.playScr.emulationEvent.set(emulation.EventUnmute)
|
||||
img.playScr.emulationEvent.set(govern.EventUnmute)
|
||||
}
|
||||
img.vcs.RIOT.Ports.MutePeripherals(mute)
|
||||
} else {
|
||||
|
|
|
@ -18,7 +18,7 @@ package sdlimgui
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/riot/ports/plugging"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
"github.com/jetsetilly/gopher2600/userinput"
|
||||
|
@ -43,9 +43,9 @@ func (img *SdlImgui) Service() {
|
|||
|
||||
// refresh lazy values
|
||||
switch img.mode {
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
img.lz.Refresh()
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
img.lz.FastRefresh()
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ func (img *SdlImgui) Service() {
|
|||
}
|
||||
img.io.AddMouseWheelDelta(deltaX/4, deltaY/4)
|
||||
|
||||
if img.mode != emulation.ModePlay || !img.wm.playmodeWindows[winSelectROMID].playmodeIsOpen() {
|
||||
if img.mode != govern.ModePlay || !img.wm.playmodeWindows[winSelectROMID].playmodeIsOpen() {
|
||||
select {
|
||||
case img.userinput <- userinput.EventMouseWheel{Delta: deltaY}:
|
||||
default:
|
||||
|
@ -386,9 +386,9 @@ func (img *SdlImgui) serviceKeyboard(ev *sdl.KeyboardEvent) {
|
|||
|
||||
case sdl.SCANCODE_GRAVE:
|
||||
if img.isPlaymode() {
|
||||
img.emulation.SetFeature(emulation.ReqSetMode, emulation.ModeDebugger)
|
||||
img.dbg.SetFeature(govern.ReqSetMode, govern.ModeDebugger)
|
||||
} else {
|
||||
img.emulation.SetFeature(emulation.ReqSetMode, emulation.ModePlay)
|
||||
img.dbg.SetFeature(govern.ReqSetMode, govern.ModePlay)
|
||||
}
|
||||
|
||||
case sdl.SCANCODE_F8:
|
||||
|
@ -413,7 +413,7 @@ func (img *SdlImgui) serviceKeyboard(ev *sdl.KeyboardEvent) {
|
|||
img.glsl.shaders[playscrShaderID].(*playscrShader).scheduleScreenshot(modeSingle)
|
||||
}
|
||||
|
||||
img.playScr.emulationEvent.set(emulation.EventScreenshot)
|
||||
img.playScr.emulationEvent.set(govern.EventScreenshot)
|
||||
|
||||
case sdl.SCANCODE_F14:
|
||||
fallthrough
|
||||
|
@ -425,16 +425,16 @@ func (img *SdlImgui) serviceKeyboard(ev *sdl.KeyboardEvent) {
|
|||
case sdl.SCANCODE_PAUSE:
|
||||
if img.isPlaymode() {
|
||||
var err error
|
||||
if img.emulation.State() == emulation.Paused {
|
||||
err = img.emulation.SetFeature(emulation.ReqSetPause, false)
|
||||
if img.dbg.State() == govern.Paused {
|
||||
err = img.dbg.SetFeature(govern.ReqSetPause, false)
|
||||
} else {
|
||||
err = img.emulation.SetFeature(emulation.ReqSetPause, true)
|
||||
err = img.dbg.SetFeature(govern.ReqSetPause, true)
|
||||
}
|
||||
if err != nil {
|
||||
logger.Logf("sdlimgui", err.Error())
|
||||
}
|
||||
} else {
|
||||
if img.emulation.State() == emulation.Paused {
|
||||
if img.dbg.State() == govern.Paused {
|
||||
img.term.pushCommand("RUN")
|
||||
} else {
|
||||
img.term.pushCommand("HALT")
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/debugger"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
|
@ -120,7 +120,7 @@ func (win *winControl) draw() {
|
|||
|
||||
func (win *winControl) drawRunButton() {
|
||||
runDim := imgui.Vec2{X: imguiRemainingWinWidth(), Y: imgui.FrameHeight()}
|
||||
if win.img.emulation.State() == emulation.Running {
|
||||
if win.img.dbg.State() == govern.Running {
|
||||
if imguiColourButton(win.img.cols.False, fmt.Sprintf("%c Halt", fonts.Halt), runDim) {
|
||||
win.img.term.pushCommand("HALT")
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ func (win *winControl) drawFPS() {
|
|||
}
|
||||
|
||||
imgui.Spacing()
|
||||
if win.img.emulation.State() == emulation.Running {
|
||||
if win.img.dbg.State() == govern.Running {
|
||||
if win.img.lz.TV.ActualFPS <= win.img.lz.TV.ReqFPS*0.95 {
|
||||
imgui.Text("running below requested FPS")
|
||||
} else if win.img.lz.TV.ActualFPS > win.img.lz.TV.ReqFPS*1.05 {
|
||||
|
@ -253,13 +253,13 @@ func (win *winControl) drawMouseCapture() {
|
|||
if win.img.wm.dbgScr.isCaptured {
|
||||
imgui.AlignTextToFramePadding()
|
||||
label := "RMB to release input"
|
||||
if win.img.emulation.State() == emulation.Running {
|
||||
if win.img.dbg.State() == govern.Running {
|
||||
label = "RMB to halt & release input"
|
||||
}
|
||||
imgui.Text(label)
|
||||
} else {
|
||||
label := "Capture input & run"
|
||||
if win.img.emulation.State() == emulation.Running {
|
||||
if win.img.dbg.State() == govern.Running {
|
||||
label = "Capture input & continue"
|
||||
}
|
||||
if imgui.Button(label) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/coprocessor/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm"
|
||||
)
|
||||
|
@ -114,7 +114,7 @@ func (win *winCoProcDisasm) draw() {
|
|||
if imgui.Checkbox("Disassembly Enabled", &isEnabled) {
|
||||
win.img.dbg.PushRawEvent(func() {
|
||||
win.img.dbg.CoProcDisasm.Enable(isEnabled)
|
||||
if win.img.emulation.State() != emulation.Running {
|
||||
if win.img.dbg.State() != govern.Running {
|
||||
// rerun the last two frames in order to gather as much disasm
|
||||
// information as possible.
|
||||
win.img.dbg.RerunLastNFrames(2)
|
||||
|
|
|
@ -21,8 +21,8 @@ import (
|
|||
|
||||
"github.com/go-gl/gl/v3.2-core/gl"
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/vcs"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/coords"
|
||||
|
@ -254,7 +254,7 @@ func (win *winDbgScr) draw() {
|
|||
if imgui.IsWindowFocused() && imageHovered {
|
||||
// mouse click will cause the rewind goto coords to run only when the
|
||||
// emulation is paused
|
||||
if win.img.emulation.State() == emulation.Paused {
|
||||
if win.img.dbg.State() == govern.Paused {
|
||||
if imgui.IsMouseDown(0) {
|
||||
coords := coords.TelevisionCoords{
|
||||
Frame: win.img.lz.TV.Coords.Frame,
|
||||
|
@ -464,7 +464,7 @@ func (win *winDbgScr) drawReflectionTooltip() {
|
|||
imguiSeparator()
|
||||
|
||||
// if mouse is over a pixel from the previous frame then show nothing except a note
|
||||
if win.img.emulation.State() == emulation.Paused {
|
||||
if win.img.dbg.State() == govern.Paused {
|
||||
if win.mouse.scanline > win.img.screen.crit.lastScanline ||
|
||||
(win.mouse.scanline == win.img.screen.crit.lastScanline && win.mouse.clock > win.img.screen.crit.lastClock) {
|
||||
imgui.Text("From previous frame")
|
||||
|
|
|
@ -18,8 +18,8 @@ package sdlimgui
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/disassembly"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
|
||||
|
||||
|
@ -42,7 +42,7 @@ type winDisasm struct {
|
|||
img *SdlImgui
|
||||
|
||||
// more recently seen emulation state
|
||||
lastSeenState emulation.State
|
||||
lastSeenState govern.State
|
||||
lastSeenPC uint16
|
||||
|
||||
// height of options line at bottom of window. valid after first frame
|
||||
|
@ -130,10 +130,10 @@ func (win *winDisasm) draw() {
|
|||
// followCPU is set; or the PC has changed (this is because the state
|
||||
// change might be missed)
|
||||
//
|
||||
// using the lazy emulation.State value rather than the live state - the
|
||||
// using the lazy govern.State value rather than the live state - the
|
||||
// live state can cause synchronisation problems meaning focus is lost
|
||||
if win.followCPU {
|
||||
if (win.img.lz.Debugger.State == emulation.Paused && win.lastSeenState != emulation.Paused) ||
|
||||
if (win.img.lz.Debugger.State == govern.Paused && win.lastSeenState != govern.Paused) ||
|
||||
win.img.lz.CPU.PC.Address() != win.lastSeenPC {
|
||||
|
||||
win.focusOnAddr = true
|
||||
|
|
|
@ -17,7 +17,7 @@ package sdlimgui
|
|||
|
||||
import (
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
)
|
||||
|
||||
|
@ -76,7 +76,7 @@ func (win *winLog) draw() {
|
|||
}
|
||||
|
||||
// very simple conditions to scroll to the bottom
|
||||
if win.scrollToBottom || win.img.emulation.State() == emulation.Running {
|
||||
if win.scrollToBottom || win.img.dbg.State() == govern.Running {
|
||||
win.scrollToBottom = false
|
||||
imgui.SetScrollHereY(0.0)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
)
|
||||
|
@ -106,7 +106,7 @@ func (win *winPrefs) draw() {
|
|||
imgui.EndTabItem()
|
||||
}
|
||||
|
||||
if win.img.mode == emulation.ModeDebugger {
|
||||
if win.img.mode == govern.ModeDebugger {
|
||||
if imgui.BeginTabItem("Debugger") {
|
||||
win.drawDebuggerTab()
|
||||
imgui.EndTabItem()
|
||||
|
@ -418,9 +418,9 @@ func (win *winPrefs) drawVCS() {
|
|||
var warning bool
|
||||
|
||||
switch win.img.mode {
|
||||
case emulation.ModePlay:
|
||||
case govern.ModePlay:
|
||||
warning = win.img.prefs.audioMutePlaymode.Get().(bool)
|
||||
case emulation.ModeDebugger:
|
||||
case govern.ModeDebugger:
|
||||
warning = win.img.prefs.audioMuteDebugger.Get().(bool)
|
||||
}
|
||||
|
||||
|
@ -587,7 +587,7 @@ func (win *winPrefs) drawDiskButtons() {
|
|||
logger.Logf("sdlimgui", "could not save (rewind) preferences: %v", err)
|
||||
}
|
||||
|
||||
if win.img.mode == emulation.ModeDebugger {
|
||||
if win.img.mode == govern.ModeDebugger {
|
||||
err = win.img.dbg.Disasm.Prefs.Save()
|
||||
if err != nil {
|
||||
logger.Logf("sdlimgui", "could not save (disasm) preferences: %v", err)
|
||||
|
@ -636,7 +636,7 @@ func (win *winPrefs) drawDiskButtons() {
|
|||
logger.Logf("sdlimgui", "could not restore (rewind) preferences: %v", err)
|
||||
}
|
||||
|
||||
if win.img.mode == emulation.ModeDebugger {
|
||||
if win.img.mode == govern.ModeDebugger {
|
||||
err = win.img.dbg.Disasm.Prefs.Load()
|
||||
if err != nil {
|
||||
logger.Logf("sdlimgui", "could not restore (disasm) preferences: %v", err)
|
||||
|
|
|
@ -20,8 +20,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
"github.com/jetsetilly/gopher2600/resources/unique"
|
||||
|
@ -175,7 +175,7 @@ func (win *winTerm) debuggerDraw() {
|
|||
// the prompt in the terminal should show the disassembly for the
|
||||
// instruction the PC is *currently* on. in other words, the
|
||||
// disassembly for the inesturction to be executed *next*
|
||||
if win.img.emulation.State() == emulation.Running {
|
||||
if win.img.dbg.State() == govern.Running {
|
||||
res := win.img.lz.Debugger.LiveDisasmEntry
|
||||
imgui.Text(res.String())
|
||||
if !win.img.lz.Debugger.LiveDisasmEntry.Result.Final {
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/gui/fonts"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/coords"
|
||||
"github.com/jetsetilly/gopher2600/tracker"
|
||||
|
@ -265,7 +265,7 @@ func (win *winTracker) draw() {
|
|||
|
||||
imgui.EndTable()
|
||||
|
||||
if win.img.emulation.State() == emulation.Running {
|
||||
if win.img.dbg.State() == govern.Running {
|
||||
imgui.SetScrollHereY(1.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
package gui
|
||||
|
||||
// Stub is a type of convenience that implements the GUI interface.
|
||||
type Stub struct{}
|
||||
|
||||
// SetFeature implements the GUI interface.
|
||||
|
|
|
@ -17,7 +17,7 @@ package hardware
|
|||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
)
|
||||
|
||||
// While the continueCheck() function only runs at the end of a CPU instruction
|
||||
|
@ -32,19 +32,19 @@ import (
|
|||
// if performanceFilter >= hardware.PerfomrmanceBrake {
|
||||
// performanceFilter = 0
|
||||
// if end_condition == true {
|
||||
// return emulation.Ending, nill
|
||||
// return govern.Ending, nill
|
||||
// }
|
||||
// }
|
||||
// return emulation.Running, nill
|
||||
// return govern.Running, nill
|
||||
//
|
||||
const PerformanceBrake = 100
|
||||
|
||||
// Run sets the emulation running as quickly as possible. continuteCheck()
|
||||
// should return false when an external event (eg. a GUI event) indicates that
|
||||
// the emulation should stop.
|
||||
func (vcs *VCS) Run(continueCheck func() (emulation.State, error)) error {
|
||||
func (vcs *VCS) Run(continueCheck func() (govern.State, error)) error {
|
||||
if continueCheck == nil {
|
||||
continueCheck = func() (emulation.State, error) { return emulation.Running, nil }
|
||||
continueCheck = func() (govern.State, error) { return govern.Running, nil }
|
||||
}
|
||||
|
||||
// see the equivalient videoCycle() in the VCS.Step() function for an
|
||||
|
@ -83,16 +83,16 @@ func (vcs *VCS) Run(continueCheck func() (emulation.State, error)) error {
|
|||
|
||||
var err error
|
||||
|
||||
state := emulation.Running
|
||||
state := govern.Running
|
||||
|
||||
for state != emulation.Ending {
|
||||
for state != govern.Ending {
|
||||
switch state {
|
||||
case emulation.Running:
|
||||
case govern.Running:
|
||||
err := vcs.CPU.ExecuteInstruction(videoCycle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case emulation.Paused:
|
||||
case govern.Paused:
|
||||
default:
|
||||
return curated.Errorf("vcs: unsupported emulation state (%d) in Run() function", state)
|
||||
}
|
||||
|
@ -109,16 +109,16 @@ func (vcs *VCS) Run(continueCheck func() (emulation.State, error)) error {
|
|||
// RunForFrameCount sets emulator running for the specified number of frames.
|
||||
// Useful for FPS and regression tests. Not used by the debugger because traps
|
||||
// (and volatile traps) are more flexible.
|
||||
func (vcs *VCS) RunForFrameCount(numFrames int, continueCheck func(frame int) (emulation.State, error)) error {
|
||||
func (vcs *VCS) RunForFrameCount(numFrames int, continueCheck func(frame int) (govern.State, error)) error {
|
||||
if continueCheck == nil {
|
||||
continueCheck = func(frame int) (emulation.State, error) { return emulation.Running, nil }
|
||||
continueCheck = func(frame int) (govern.State, error) { return govern.Running, nil }
|
||||
}
|
||||
|
||||
frameNum := vcs.TV.GetCoords().Frame
|
||||
targetFrame := frameNum + numFrames
|
||||
|
||||
state := emulation.Running
|
||||
for frameNum != targetFrame && state != emulation.Ending {
|
||||
state := govern.Running
|
||||
for frameNum != targetFrame && state != govern.Ending {
|
||||
err := vcs.Step(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/coords"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/signal"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/specification"
|
||||
|
@ -174,7 +174,7 @@ type Television struct {
|
|||
prevSignalFirst int
|
||||
|
||||
// state of emulation
|
||||
emulationState emulation.State
|
||||
emulationState govern.State
|
||||
}
|
||||
|
||||
// NewTelevision creates a new instance of the television type, satisfying the
|
||||
|
@ -535,7 +535,7 @@ func (tv *Television) newScanline() error {
|
|||
|
||||
// check for realtime mixing requirements. if it is required then
|
||||
// immediately push the audio data from the previous frame to the mixer
|
||||
if tv.realtimeMixer != nil && tv.emulationState == emulation.Running && tv.state.frameInfo.Stable {
|
||||
if tv.realtimeMixer != nil && tv.emulationState == govern.Running && tv.state.frameInfo.Stable {
|
||||
if tv.realtimeMixer.MoreAudio() {
|
||||
err := tv.realtimeMixer.SetAudio(tv.prevSignals[:tv.prevSignalLastIdx])
|
||||
if err != nil {
|
||||
|
@ -669,7 +669,7 @@ func (tv *Television) newFrame(fromVsync bool) error {
|
|||
// renderers and audio mixers.
|
||||
func (tv *Television) renderSignals() error {
|
||||
// do not render pixels if emulation is in the rewinding state
|
||||
if tv.emulationState != emulation.Rewinding {
|
||||
if tv.emulationState != govern.Rewinding {
|
||||
for _, r := range tv.renderers {
|
||||
err := r.SetPixels(tv.signals, tv.currentSignalIdx)
|
||||
if err != nil {
|
||||
|
@ -768,23 +768,23 @@ func (tv *Television) SetSpec(spec string) error {
|
|||
|
||||
// SetEmulationState is called by emulation whenever state changes. How we
|
||||
// handle incoming signals depends on the current state.
|
||||
func (tv *Television) SetEmulationState(state emulation.State) error {
|
||||
func (tv *Television) SetEmulationState(state govern.State) error {
|
||||
prev := tv.emulationState
|
||||
tv.emulationState = state
|
||||
|
||||
switch prev {
|
||||
case emulation.Paused:
|
||||
case govern.Paused:
|
||||
// start off the unpaused state by measuring the current framerate.
|
||||
// this "clears" the ticker channel and means the feedback from
|
||||
// GetActualFPS() is less misleading
|
||||
tv.lmtr.measureActual()
|
||||
|
||||
case emulation.Rewinding:
|
||||
case govern.Rewinding:
|
||||
tv.renderSignals()
|
||||
}
|
||||
|
||||
switch state {
|
||||
case emulation.Paused:
|
||||
case govern.Paused:
|
||||
err := tv.renderSignals()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -22,11 +22,10 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
"github.com/jetsetilly/gopher2600/setup"
|
||||
"github.com/jetsetilly/gopher2600/userinput"
|
||||
)
|
||||
|
||||
// sentinal error returned by Run() loop.
|
||||
|
@ -100,7 +99,7 @@ func Check(output io.Writer, profile Profile, cartload cartridgeloader.Loader, s
|
|||
performanceBrake := 0
|
||||
|
||||
// run until specified time elapses
|
||||
err = vcs.Run(func() (emulation.State, error) {
|
||||
err = vcs.Run(func() (govern.State, error) {
|
||||
for {
|
||||
performanceBrake++
|
||||
if performanceBrake >= hardware.PerformanceBrake {
|
||||
|
@ -112,7 +111,7 @@ func Check(output io.Writer, profile Profile, cartload cartridgeloader.Loader, s
|
|||
// period has finished, return false to cause vcs.Run() to
|
||||
// return
|
||||
if v {
|
||||
return emulation.Ending, curated.Errorf(timedOut)
|
||||
return govern.Ending, curated.Errorf(timedOut)
|
||||
}
|
||||
|
||||
// timerChan has returned false which indicates that the
|
||||
|
@ -121,11 +120,11 @@ func Check(output io.Writer, profile Profile, cartload cartridgeloader.Loader, s
|
|||
// frame.
|
||||
startFrame = tv.GetCoords().Frame
|
||||
default:
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
}
|
||||
}
|
||||
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
}
|
||||
})
|
||||
return err
|
||||
|
@ -148,38 +147,3 @@ func Check(output io.Writer, profile Profile, cartload cartridgeloader.Loader, s
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// stubEmulation is handed to the GUI through ReqSetEmulation. Provides the
|
||||
// minimum implementation for the Emulation interface.
|
||||
type stubEmulation struct {
|
||||
vcs emulation.VCS
|
||||
tv emulation.TV
|
||||
}
|
||||
|
||||
func (e *stubEmulation) TV() emulation.TV {
|
||||
return e.tv
|
||||
}
|
||||
|
||||
func (e *stubEmulation) VCS() emulation.VCS {
|
||||
return e.vcs
|
||||
}
|
||||
|
||||
func (e *stubEmulation) Debugger() emulation.Debugger {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *stubEmulation) UserInput() chan userinput.Event {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *stubEmulation) SetFeature(request emulation.FeatureReq, args ...emulation.FeatureReqData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *stubEmulation) State() emulation.State {
|
||||
return emulation.Running
|
||||
}
|
||||
|
||||
func (e *stubEmulation) Mode() emulation.Mode {
|
||||
return emulation.ModePlay
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package reflection
|
|||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
|
@ -30,7 +30,7 @@ import (
|
|||
type Reflector struct {
|
||||
vcs *hardware.VCS
|
||||
renderer Renderer
|
||||
emulationState emulation.State
|
||||
emulationState govern.State
|
||||
|
||||
history []ReflectedVideoStep
|
||||
|
||||
|
@ -57,17 +57,17 @@ func (ref *Reflector) Clear() {
|
|||
|
||||
// SetEmulationState is called by emulation whenever state changes. How we
|
||||
// handle reflections depends on the current state.
|
||||
func (ref *Reflector) SetEmulationState(state emulation.State) {
|
||||
func (ref *Reflector) SetEmulationState(state govern.State) {
|
||||
prev := ref.emulationState
|
||||
ref.emulationState = state
|
||||
|
||||
switch prev {
|
||||
case emulation.Rewinding:
|
||||
case govern.Rewinding:
|
||||
ref.render()
|
||||
}
|
||||
|
||||
switch state {
|
||||
case emulation.Paused:
|
||||
case govern.Paused:
|
||||
err := ref.render()
|
||||
if err != nil {
|
||||
logger.Logf("reflection", "%v", err)
|
||||
|
@ -125,7 +125,7 @@ func (ref *Reflector) Step(bank mapper.BankInfo) error {
|
|||
|
||||
// push history to reflection renderer
|
||||
func (ref *Reflector) render() error {
|
||||
if ref.emulationState != emulation.Rewinding {
|
||||
if ref.emulationState != govern.Rewinding {
|
||||
if ref.renderer != nil {
|
||||
if err := ref.renderer.Reflect(ref.history); err != nil {
|
||||
return curated.Errorf("reflection: %v", err)
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/database"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
|
@ -160,7 +160,7 @@ func (reg *LogRegression) regress(newRegression bool, output io.Writer, msg stri
|
|||
logOutput := &strings.Builder{}
|
||||
|
||||
// run emulation
|
||||
err = vcs.RunForFrameCount(reg.NumFrames, func(frame int) (emulation.State, error) {
|
||||
err = vcs.RunForFrameCount(reg.NumFrames, func(frame int) (govern.State, error) {
|
||||
// display progress meter every 1 second
|
||||
select {
|
||||
case <-tck.C:
|
||||
|
@ -170,7 +170,7 @@ func (reg *LogRegression) regress(newRegression bool, output io.Writer, msg stri
|
|||
|
||||
logger.WriteRecent(logOutput)
|
||||
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -25,8 +25,8 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/database"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/digest"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
|
@ -150,13 +150,13 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
|
|||
tck := time.NewTicker(dur)
|
||||
|
||||
// run emulation
|
||||
err = vcs.Run(func() (emulation.State, error) {
|
||||
err = vcs.Run(func() (govern.State, error) {
|
||||
hasEnded, err := plb.EndFrame()
|
||||
if err != nil {
|
||||
return emulation.Ending, curated.Errorf("playback: %v", err)
|
||||
return govern.Ending, curated.Errorf("playback: %v", err)
|
||||
}
|
||||
if hasEnded {
|
||||
return emulation.Ending, curated.Errorf("playback: ended unexpectedly")
|
||||
return govern.Ending, curated.Errorf("playback: ended unexpectedly")
|
||||
}
|
||||
|
||||
// display progress meter every 1 second
|
||||
|
@ -165,7 +165,7 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
|
|||
output.Write([]byte(fmt.Sprintf("\r%s [%s]", msg, plb)))
|
||||
default:
|
||||
}
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -27,8 +27,8 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/database"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/digest"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
"github.com/jetsetilly/gopher2600/setup"
|
||||
|
@ -232,7 +232,7 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
|
|||
tck := time.NewTicker(dur)
|
||||
|
||||
// run emulation
|
||||
err = vcs.RunForFrameCount(reg.NumFrames, func(frame int) (emulation.State, error) {
|
||||
err = vcs.RunForFrameCount(reg.NumFrames, func(frame int) (govern.State, error) {
|
||||
// display progress meter every 1 second
|
||||
select {
|
||||
case <-tck.C:
|
||||
|
@ -259,7 +259,7 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
|
|||
}
|
||||
}
|
||||
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/cpu"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory"
|
||||
|
@ -32,6 +32,13 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/logger"
|
||||
)
|
||||
|
||||
// Emulation defines as much of the emulation we require access to.
|
||||
type Emulation interface {
|
||||
Mode() govern.Mode
|
||||
State() govern.State
|
||||
VCS() *hardware.VCS
|
||||
}
|
||||
|
||||
// Runner provides the rewind package the opportunity to run the emulation.
|
||||
type Runner interface {
|
||||
// CatchupLoop should loop until the frame/scanline/clock coordinates are
|
||||
|
@ -106,7 +113,7 @@ const overhead = 2
|
|||
|
||||
// Rewind contains a history of machine states for the emulation.
|
||||
type Rewind struct {
|
||||
emulation emulation.Emulation
|
||||
emulation Emulation
|
||||
vcs *hardware.VCS
|
||||
runner Runner
|
||||
|
||||
|
@ -145,10 +152,10 @@ type Rewind struct {
|
|||
}
|
||||
|
||||
// NewRewind is the preferred method of initialisation for the Rewind type.
|
||||
func NewRewind(emulation emulation.Emulation, runner Runner) (*Rewind, error) {
|
||||
func NewRewind(emulation Emulation, runner Runner) (*Rewind, error) {
|
||||
r := &Rewind{
|
||||
emulation: emulation,
|
||||
vcs: emulation.VCS().(*hardware.VCS),
|
||||
vcs: emulation.VCS(),
|
||||
runner: runner,
|
||||
}
|
||||
|
||||
|
@ -443,7 +450,7 @@ type findResults struct {
|
|||
// the one that is requested.
|
||||
func (r *Rewind) findFrameIndex(frame int) findResults {
|
||||
searchFrame := frame - 1
|
||||
if r.emulation.Mode() == emulation.ModeDebugger {
|
||||
if r.emulation.Mode() == govern.ModeDebugger {
|
||||
searchFrame--
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ package rewind
|
|||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/specification"
|
||||
)
|
||||
|
@ -160,7 +160,7 @@ func (r *Rewind) GetTimeline() Timeline {
|
|||
|
||||
func (r *Rewind) addTimelineEntry(frameInfo television.FrameInfo) {
|
||||
// do not alter the timeline information if we're in the rewinding state
|
||||
if r.emulation.State() == emulation.Rewinding {
|
||||
if r.emulation.State() == govern.Rewinding {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
|
||||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/curated"
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/hardware/instance"
|
||||
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
||||
|
@ -193,17 +193,17 @@ func (thmb *Thumbnailer) CreateFromLoader(cartload cartridgeloader.Loader, numFr
|
|||
|
||||
tgtFrame := thmb.vcs.TV.GetCoords().Frame + numFrames
|
||||
|
||||
err = thmb.vcs.Run(func() (emulation.State, error) {
|
||||
err = thmb.vcs.Run(func() (govern.State, error) {
|
||||
select {
|
||||
case <-thmb.emulationQuit:
|
||||
return emulation.Ending, nil
|
||||
return govern.Ending, nil
|
||||
default:
|
||||
}
|
||||
|
||||
if numFrames != UndefinedNumFrames && thmb.vcs.TV.GetCoords().Frame >= tgtFrame {
|
||||
return emulation.Ending, nil
|
||||
return govern.Ending, nil
|
||||
}
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
if err != nil {
|
||||
logger.Logf("thumbnailer", err.Error())
|
||||
|
@ -235,17 +235,17 @@ func (thmb *Thumbnailer) SingleFrameFromRewindState(state *rewind.State) {
|
|||
// run until target frame has been generated
|
||||
tgtFrame := thmb.vcs.TV.GetCoords().Frame + 1
|
||||
|
||||
err := thmb.vcs.Run(func() (emulation.State, error) {
|
||||
err := thmb.vcs.Run(func() (govern.State, error) {
|
||||
select {
|
||||
case <-thmb.emulationQuit:
|
||||
return emulation.Ending, nil
|
||||
return govern.Ending, nil
|
||||
default:
|
||||
}
|
||||
|
||||
if thmb.vcs.TV.GetCoords().Frame >= tgtFrame {
|
||||
return emulation.Ending, nil
|
||||
return govern.Ending, nil
|
||||
}
|
||||
return emulation.Running, nil
|
||||
return govern.Running, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -16,12 +16,18 @@
|
|||
package tracker
|
||||
|
||||
import (
|
||||
"github.com/jetsetilly/gopher2600/emulation"
|
||||
"github.com/jetsetilly/gopher2600/debugger/govern"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television"
|
||||
"github.com/jetsetilly/gopher2600/hardware/television/coords"
|
||||
"github.com/jetsetilly/gopher2600/hardware/tia/audio"
|
||||
)
|
||||
|
||||
// Emulation defines as much of the emulation we require access to.
|
||||
type Emulation interface {
|
||||
State() govern.State
|
||||
TV() *television.Television
|
||||
}
|
||||
|
||||
type Entry struct {
|
||||
Coords coords.TelevisionCoords
|
||||
Channel int
|
||||
|
@ -35,7 +41,7 @@ type Entry struct {
|
|||
// Tracker implements the audio.Tracker interface and keeps a history of the
|
||||
// audio registers over time.
|
||||
type Tracker struct {
|
||||
emulation emulation.Emulation
|
||||
emulation Emulation
|
||||
|
||||
entries []Entry
|
||||
|
||||
|
@ -49,7 +55,7 @@ type Tracker struct {
|
|||
const maxTrackerEntries = 1024
|
||||
|
||||
// NewTracker is the preferred method of initialisation for the Tracker type.
|
||||
func NewTracker(emulation emulation.Emulation) *Tracker {
|
||||
func NewTracker(emulation Emulation) *Tracker {
|
||||
return &Tracker{
|
||||
emulation: emulation,
|
||||
entries: make([]Entry, 0, maxTrackerEntries),
|
||||
|
@ -63,7 +69,7 @@ func (tr *Tracker) Reset() {
|
|||
|
||||
// Tick implements the audio.Tracker interface
|
||||
func (tr *Tracker) Tick(channel int, reg audio.Registers) {
|
||||
if tr.emulation.State() == emulation.Rewinding {
|
||||
if tr.emulation.State() == govern.Rewinding {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -71,7 +77,7 @@ func (tr *Tracker) Tick(channel int, reg audio.Registers) {
|
|||
tr.prevRegister[channel] = reg
|
||||
|
||||
if changed {
|
||||
tv := tr.emulation.TV().(*television.Television)
|
||||
tv := tr.emulation.TV()
|
||||
|
||||
e := Entry{
|
||||
Coords: tv.GetCoords(),
|
||||
|
|
Loading…
Reference in a new issue