diff --git a/FUTURE b/FUTURE index 11663cb6..0a732e38 100644 --- a/FUTURE +++ b/FUTURE @@ -36,8 +36,6 @@ o display of colors in the terminal (check for 256 color terminal) sdl screen ---------- -o faded copy of metasignal overlay for incomplete frames (when halted) - o info under mouse. floating tooltip diff --git a/debugger/commands.go b/debugger/commands.go index 5a823b05..221fa85c 100644 --- a/debugger/commands.go +++ b/debugger/commands.go @@ -1023,7 +1023,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) return doNothing, err } case "METASIGNALS": - err = dbg.gui.SetFeature(gui.ReqToggleShowMetaPixels) + err = dbg.gui.SetFeature(gui.ReqToggleShowMetaVideo) if err != nil { return doNothing, err } diff --git a/debugger/debugger.go b/debugger/debugger.go index 9f061811..03a83f52 100644 --- a/debugger/debugger.go +++ b/debugger/debugger.go @@ -4,7 +4,6 @@ import ( "fmt" "gopher2600/debugger/commandline" "gopher2600/debugger/console" - "gopher2600/debugger/metavideo" "gopher2600/debugger/script" "gopher2600/disassembly" "gopher2600/errors" @@ -50,9 +49,9 @@ type Debugger struct { // metavideo is additional information about the emulation state (ie. // if a sprite was reset or if WSYNC is active, etc.) // - // videomon.Check() is called every video cycle to inform the gui of + // metavideo.Check() is called every video cycle to inform the gui of // the metainformation of the last television signal - videomon *metavideo.Monitor + metavideo *metavideoMonitor // halt conditions breakpoints *breakpoints @@ -169,8 +168,8 @@ func NewDebugger(tvType string) (*Debugger, error) { // set up debugging interface to memory dbg.dbgmem = &memoryDebug{mem: dbg.vcs.Mem, symtable: &dbg.disasm.Symtable} - // set up metapixel monitor - dbg.videomon = &metavideo.Monitor{Mem: dbg.vcs.Mem, MC: dbg.vcs.CPU, Rend: dbg.vcs.TV} + // set up metavideo monitor + dbg.metavideo = &metavideoMonitor{Mem: dbg.vcs.Mem, MC: dbg.vcs.CPU, Renderer: dbg.gui} // set up breakpoints/traps dbg.breakpoints = newBreakpoints(dbg) @@ -298,7 +297,7 @@ func (dbg *Debugger) videoCycle(result *result.Instruction) error { dbg.trapMessages = dbg.traps.check(dbg.trapMessages) dbg.watchMessages = dbg.watches.check(dbg.watchMessages) - return dbg.videomon.Check() + return dbg.metavideo.Check() } // inputLoop has two modes, defined by the videoCycle argument. when diff --git a/debugger/events.go b/debugger/events.go index 2c317261..876ab753 100644 --- a/debugger/events.go +++ b/debugger/events.go @@ -32,7 +32,7 @@ func (dbg *Debugger) guiEventHandler(event gui.Event) error { err = dbg.gui.SetFeature(gui.ReqToggleAltColors) case "2": // toggle metasignals overlay - err = dbg.gui.SetFeature(gui.ReqToggleShowMetaPixels) + err = dbg.gui.SetFeature(gui.ReqToggleShowMetaVideo) case "=": fallthrough // equal sign is the same as plus, for convenience diff --git a/debugger/metavideo.go b/debugger/metavideo.go new file mode 100644 index 00000000..6849de6b --- /dev/null +++ b/debugger/metavideo.go @@ -0,0 +1,76 @@ +package debugger + +import ( + "gopher2600/gui/metavideo" + "gopher2600/hardware/cpu" + "gopher2600/hardware/memory" +) + +// metavideoMonitor watches for writes to specific video related memory locations. when +// these locations are written to, a MetaSignal is sent to the Renderer +// implementation. +type metavideoMonitor struct { + Mem *memory.VCSMemory + MC *cpu.CPU + Renderer metavideo.Renderer + + // the emulation doesn't access memory every video cycle. we do check if it + // every cycle however, so we need a way of filtering out false-positives + // indicators that a memory address has been triggered. + lastAddress uint16 +} + +// Check should be called every video cycle to record the current state of the +// emulation/system +func (mv *metavideoMonitor) Check() error { + var err error + var sig metavideo.MetaSignalAttributes + + // special handling of WSYNC signal - we want every pixel to be coloured + // while the RdyFlag is false, not just when WSYNC is first triggered. + if !mv.MC.RdyFlg { + sig = metavideo.MetaSignalAttributes{Label: "WSYNC", Red: 0, Green: 0, Blue: 255} + err = mv.Renderer.MetaSignal(sig) + if err != nil { + return err + } + return nil + } + + if mv.Mem.LastAccessWrite && mv.Mem.LastAccessAddress != mv.lastAddress { + sendSignal := true + + switch mv.Mem.LastAccessAddress { + case 0x03: // RSYNC + sig = metavideo.MetaSignalAttributes{Label: "RSYNC", Red: 255, Green: 0, Blue: 0} + case 0x2a: // HMOVE + sig = metavideo.MetaSignalAttributes{Label: "HMOVE", Red: 0, Green: 255, Blue: 0} + case 0x10: + sig = metavideo.MetaSignalAttributes{Label: "RESP0", Red: 0, Green: 255, Blue: 255} + case 0x11: + sig = metavideo.MetaSignalAttributes{Label: "RESP1", Red: 0, Green: 255, Blue: 255} + case 0x12: + sig = metavideo.MetaSignalAttributes{Label: "RESM0", Red: 0, Green: 255, Blue: 255} + case 0x13: + sig = metavideo.MetaSignalAttributes{Label: "RESM1", Red: 0, Green: 255, Blue: 255} + case 0x14: + sig = metavideo.MetaSignalAttributes{Label: "RESBL", Red: 0, Green: 255, Blue: 255} + case 0x2b: + sig = metavideo.MetaSignalAttributes{Label: "HMCLR", Red: 255, Green: 0, Blue: 255} + default: + sendSignal = false + } + + if sendSignal { + err = mv.Renderer.MetaSignal(sig) + if err != nil { + return err + } + } + + // note address + mv.lastAddress = mv.Mem.LastAccessAddress + } + + return nil +} diff --git a/debugger/metavideo/metavideo.go b/debugger/metavideo/metavideo.go deleted file mode 100644 index 8b075581..00000000 --- a/debugger/metavideo/metavideo.go +++ /dev/null @@ -1,91 +0,0 @@ -package metavideo - -import ( - "gopher2600/hardware/cpu" - "gopher2600/hardware/memory" -) - -// MetaSignalAttributes contains information about the last television signal. it is up to -// the Renderer to match this up with the last television signal -type MetaSignalAttributes struct { - Label string - - // Renderer implementations are free to use the color information - // as they wish (adding alpha information seems a probable scenario). - Red, Green, Blue byte -} - -// Renderer implementations will add signal information to a presentation layer -// somehow. -type Renderer interface { - MetaSignal(MetaSignalAttributes) error -} - -// Monitor watches for writes to specific video related memory locations. when -// these locations are written to, a MetaSignal is sent to the Renderer -// implementation. -type Monitor struct { - Mem *memory.VCSMemory - MC *cpu.CPU - Rend Renderer - - // the emulation doesn't access memory every video cycle. we do check if it - // every cycle however, so we need a way of filtering out false-positives - // indicators that a memory address has been triggered. - lastAddress uint16 -} - -// Check should be called every video cycle to record the current state of the -// emulation/system -func (mon *Monitor) Check() error { - var err error - var sig MetaSignalAttributes - - // special handling of WSYNC signal - we want every pixel to be coloured - // while the RdyFlag is false, not just when WSYNC is first triggered. - if !mon.MC.RdyFlg { - sig = MetaSignalAttributes{Label: "WSYNC", Red: 0, Green: 0, Blue: 255} - err = mon.Rend.MetaSignal(sig) - if err != nil { - return err - } - return nil - } - - if mon.Mem.LastAccessWrite && mon.Mem.LastAccessAddress != mon.lastAddress { - sendSignal := true - - switch mon.Mem.LastAccessAddress { - case 0x03: // RSYNC - sig = MetaSignalAttributes{Label: "RSYNC", Red: 255, Green: 0, Blue: 0} - case 0x2a: // HMOVE - sig = MetaSignalAttributes{Label: "HMOVE", Red: 0, Green: 255, Blue: 0} - case 0x10: - sig = MetaSignalAttributes{Label: "RESP0", Red: 0, Green: 255, Blue: 255} - case 0x11: - sig = MetaSignalAttributes{Label: "RESP1", Red: 0, Green: 255, Blue: 255} - case 0x12: - sig = MetaSignalAttributes{Label: "RESM0", Red: 0, Green: 255, Blue: 255} - case 0x13: - sig = MetaSignalAttributes{Label: "RESM1", Red: 0, Green: 255, Blue: 255} - case 0x14: - sig = MetaSignalAttributes{Label: "RESBL", Red: 0, Green: 255, Blue: 255} - case 0x2b: - sig = MetaSignalAttributes{Label: "HMCLR", Red: 255, Green: 0, Blue: 255} - default: - sendSignal = false - } - - if sendSignal { - err = mon.Rend.MetaSignal(sig) - if err != nil { - return err - } - } - - // note address - mon.lastAddress = mon.Mem.LastAccessAddress - } - - return nil -} diff --git a/gui/gui.go b/gui/gui.go index 78b0af00..3e45a3cc 100644 --- a/gui/gui.go +++ b/gui/gui.go @@ -1,32 +1,36 @@ package gui -import "gopher2600/television" +import ( + "gopher2600/gui/metavideo" + "gopher2600/television" +) // FeatureReq is used to request the setting of a gui attribute -// eg. toggling the metapixel layer +// eg. toggling the metavideo layer type FeatureReq int // list of valid feature requests const ( - ReqSetVisibility FeatureReq = iota // bool, optional bool (update on show) - ReqSetVisibilityStable // none - ReqSetAllowDebugging // bool - ReqSetPause // bool - ReqSetMasking // bool - ReqToggleMasking // none - ReqSetAltColors // bool - ReqToggleAltColors // none - ReqSetShowMetaPixels // bool - ReqToggleShowMetaPixels // none - ReqSetScale // float - ReqIncScale // none - ReqDecScale // none + ReqSetVisibility FeatureReq = iota // bool, optional bool (update on show) + ReqSetVisibilityStable // none + ReqSetAllowDebugging // bool + ReqSetPause // bool + ReqSetMasking // bool + ReqToggleMasking // none + ReqSetAltColors // bool + ReqToggleAltColors // none + ReqSetShowMetaVideo // bool + ReqToggleShowMetaVideo // none + ReqSetScale // float + ReqIncScale // none + ReqDecScale // none ) // GUI defines the operations that can be performed on GUIs type GUI interface { television.Television television.Renderer + metavideo.Renderer // returns true if GUI is currently visible. false if not IsVisible() bool diff --git a/gui/metavideo/metavideo.go b/gui/metavideo/metavideo.go new file mode 100644 index 00000000..b959fd5c --- /dev/null +++ b/gui/metavideo/metavideo.go @@ -0,0 +1,17 @@ +package metavideo + +// Renderer implementations will add signal information to a presentation layer +// somehow. +type Renderer interface { + MetaSignal(MetaSignalAttributes) error +} + +// MetaSignalAttributes contains information about the last television signal. it is up to +// the Renderer to match this up with the last television signal +type MetaSignalAttributes struct { + Label string + + // Renderer implementations are free to use the color information + // as they wish (adding alpha information seems a probable scenario). + Red, Green, Blue byte +} diff --git a/gui/sdl/metavideo.go b/gui/sdl/metavideo.go index 337dc1e1..2235260d 100644 --- a/gui/sdl/metavideo.go +++ b/gui/sdl/metavideo.go @@ -1,7 +1,7 @@ package sdl import ( - "gopher2600/debugger/metavideo" + "gopher2600/gui/metavideo" "github.com/veandco/go-sdl2/sdl" ) @@ -9,66 +9,102 @@ import ( type metaVideoOverlay struct { scr *screen - pixels []byte - texture *sdl.Texture + texture *sdl.Texture + textureFade *sdl.Texture + + pixels []byte + pixelsFade []byte labels [][]string } func newMetaVideoOverlay(scr *screen) (*metaVideoOverlay, error) { - mpx := new(metaVideoOverlay) - mpx.scr = scr + mv := new(metaVideoOverlay) + mv.scr = scr // our acutal screen data - mpx.pixels = make([]byte, mpx.scr.maxWidth*mpx.scr.maxHeight*scrDepth) + mv.pixels = make([]byte, mv.scr.maxWidth*mv.scr.maxHeight*scrDepth) + mv.pixelsFade = make([]byte, mv.scr.maxWidth*mv.scr.maxHeight*scrDepth) // labels - mpx.labels = make([][]string, mpx.scr.maxHeight) - for i := 0; i < len(mpx.labels); i++ { - mpx.labels[i] = make([]string, mpx.scr.maxWidth) + mv.labels = make([][]string, mv.scr.maxHeight) + for i := 0; i < len(mv.labels); i++ { + mv.labels[i] = make([]string, mv.scr.maxWidth) } var err error - mpx.texture, err = scr.renderer.CreateTexture(uint32(sdl.PIXELFORMAT_ABGR8888), int(sdl.TEXTUREACCESS_STREAMING), int32(mpx.scr.maxWidth), int32(mpx.scr.maxHeight)) + mv.texture, err = scr.renderer.CreateTexture(uint32(sdl.PIXELFORMAT_ABGR8888), int(sdl.TEXTUREACCESS_STREAMING), int32(mv.scr.maxWidth), int32(mv.scr.maxHeight)) if err != nil { return nil, err } - mpx.texture.SetAlphaMod(100) - mpx.texture.SetBlendMode(sdl.BlendMode(sdl.BLENDMODE_BLEND)) + mv.texture.SetBlendMode(sdl.BlendMode(sdl.BLENDMODE_BLEND)) + mv.texture.SetAlphaMod(100) - return mpx, nil + mv.textureFade, err = scr.renderer.CreateTexture(uint32(sdl.PIXELFORMAT_ABGR8888), int(sdl.TEXTUREACCESS_STREAMING), int32(mv.scr.maxWidth), int32(mv.scr.maxHeight)) + if err != nil { + return nil, err + } + mv.textureFade.SetBlendMode(sdl.BlendMode(sdl.BLENDMODE_BLEND)) + mv.textureFade.SetAlphaMod(50) + + return mv, nil } -func (mpx *metaVideoOverlay) setPixel(sig metavideo.MetaSignalAttributes) error { - i := (mpx.scr.lastY*mpx.scr.maxWidth + mpx.scr.lastX) * scrDepth +func (mv *metaVideoOverlay) setPixel(sig metavideo.MetaSignalAttributes) error { + i := (mv.scr.lastY*mv.scr.maxWidth + mv.scr.lastX) * scrDepth - if i >= int32(len(mpx.pixels)) { + if i >= int32(len(mv.pixels)) { return nil } - mpx.pixels[i] = sig.Red - mpx.pixels[i+1] = sig.Green - mpx.pixels[i+2] = sig.Blue - mpx.pixels[i+3] = 255 + mv.pixels[i] = sig.Red + mv.pixels[i+1] = sig.Green + mv.pixels[i+2] = sig.Blue + mv.pixels[i+3] = 255 // silently allow empty labels - mpx.labels[mpx.scr.lastY][mpx.scr.lastX] = sig.Label + mv.labels[mv.scr.lastY][mv.scr.lastX] = sig.Label return nil } -func (mpx *metaVideoOverlay) clearPixels() { - for i := 0; i < len(mpx.pixels); i++ { - mpx.pixels[i] = 0 +func (mv *metaVideoOverlay) newFrame() { + // swap pixel array with pixelsFade array + // -- see comment in sdl.screen.newFrame() function for why we do this + swp := mv.pixels + mv.pixels = mv.pixelsFade + mv.pixelsFade = swp + + // clear regular pixels + for i := 0; i < len(mv.pixels); i++ { + mv.pixels[i] = 0 } } -func (mpx *metaVideoOverlay) update() error { - err := mpx.texture.Update(nil, mpx.pixels, int(mpx.scr.maxWidth*scrDepth)) +func (mv *metaVideoOverlay) update(paused bool) error { + if paused { + err := mv.textureFade.Update(nil, mv.pixelsFade, int(mv.scr.maxWidth*scrDepth)) + if err != nil { + return err + } + + err = mv.scr.renderer.Copy(mv.textureFade, mv.scr.srcRect, mv.scr.destRect) + if err != nil { + return err + } + } + + err := mv.texture.Update(nil, mv.pixels, int(mv.scr.maxWidth*scrDepth)) if err != nil { return err } + + err = mv.scr.renderer.Copy(mv.texture, mv.scr.srcRect, mv.scr.destRect) + if err != nil { + return err + } + return nil } @@ -79,10 +115,5 @@ func (gtv *GUI) MetaSignal(sig metavideo.MetaSignalAttributes) error { return nil } - err := gtv.Television.MetaSignal(sig) - if err != nil { - return err - } - - return gtv.scr.metaPixels.setPixel(sig) + return gtv.scr.metaVideo.setPixel(sig) } diff --git a/gui/sdl/requests.go b/gui/sdl/requests.go index a86534d0..5ed74dad 100644 --- a/gui/sdl/requests.go +++ b/gui/sdl/requests.go @@ -51,12 +51,12 @@ func (gtv *GUI) SetFeature(request gui.FeatureReq, args ...interface{}) error { gtv.scr.useAltPixels = !gtv.scr.useAltPixels gtv.update() - case gui.ReqSetShowMetaPixels: - gtv.scr.showMetaPixels = args[0].(bool) + case gui.ReqSetShowMetaVideo: + gtv.scr.showMetaVideo = args[0].(bool) gtv.update() - case gui.ReqToggleShowMetaPixels: - gtv.scr.showMetaPixels = !gtv.scr.showMetaPixels + case gui.ReqToggleShowMetaVideo: + gtv.scr.showMetaVideo = !gtv.scr.showMetaVideo gtv.update() case gui.ReqSetScale: diff --git a/gui/sdl/screen.go b/gui/sdl/screen.go index 60210bc2..79dfcf8c 100644 --- a/gui/sdl/screen.go +++ b/gui/sdl/screen.go @@ -3,6 +3,7 @@ package sdl import ( "gopher2600/errors" "gopher2600/performance/limiter" + "gopher2600/television" "github.com/veandco/go-sdl2/sdl" ) @@ -12,7 +13,8 @@ import ( const scrDepth int32 = 4 type screen struct { - gtv *GUI + gtv *GUI + spec *television.Specification // regulates how often the screen is updated fpsLimiter *limiter.FpsLimiter @@ -74,9 +76,9 @@ type screen struct { // overlay for screen showing metasignal information // -- always allocated but only used when tv.allowDebugging and - // showMetaPixels are true - metaPixels *metaVideoOverlay - showMetaPixels bool + // showMetaVideo are true + metaVideo *metaVideoOverlay + showMetaVideo bool } func newScreen(gtv *GUI) (*screen, error) { @@ -107,7 +109,7 @@ func newScreen(gtv *GUI) (*screen, error) { scr.stb = newScreenStabiliser(scr) // new overlay - scr.metaPixels, err = newMetaVideoOverlay(scr) + scr.metaVideo, err = newMetaVideoOverlay(scr) if err != nil { return nil, err } @@ -118,14 +120,14 @@ func newScreen(gtv *GUI) (*screen, error) { func (scr *screen) changeTVSpec() error { var err error - spec := scr.gtv.GetSpec() + scr.spec = scr.gtv.GetSpec() - scr.maxWidth = int32(spec.ClocksPerScanline) - scr.maxHeight = int32(spec.ScanlinesTotal) + scr.maxWidth = int32(scr.spec.ClocksPerScanline) + scr.maxHeight = int32(scr.spec.ScanlinesTotal) scr.maxMask = &sdl.Rect{X: 0, Y: 0, W: scr.maxWidth, H: scr.maxHeight} - scr.playWidth = int32(spec.ClocksPerVisible) - scr.setPlayArea(int32(spec.ScanlinesPerVisible), int32(spec.ScanlinesPerVBlank+spec.ScanlinesPerVSync)) + scr.playWidth = int32(scr.spec.ClocksPerVisible) + scr.setPlayArea(int32(scr.spec.ScanlinesPerVisible), int32(scr.spec.ScanlinesPerVBlank+scr.spec.ScanlinesPerVSync)) // pixelWidth is the number of tv pixels per color clock. we don't need to // worry about this again once we've created the window and set the scaling @@ -158,7 +160,7 @@ func (scr *screen) changeTVSpec() error { scr.altPixelsFade = make([]byte, scr.maxWidth*scr.maxHeight*scrDepth) // frame limiter - scr.fpsLimiter, err = limiter.NewFPSLimiter(int(spec.FramesPerSecond)) + scr.fpsLimiter, err = limiter.NewFPSLimiter(int(scr.spec.FramesPerSecond)) if err != nil { return errors.NewFormattedError(errors.SDL, err) } @@ -170,7 +172,7 @@ func (scr *screen) changeTVSpec() error { func (scr *screen) setPlayArea(scanlines int32, top int32) error { scr.playHeight = scanlines scr.playDstMask = &sdl.Rect{X: 0, Y: 0, W: scr.playWidth, H: scr.playHeight} - scr.playSrcMask = &sdl.Rect{X: int32(scr.gtv.GetSpec().ClocksPerHblank), Y: top, W: scr.playWidth, H: scr.playHeight} + scr.playSrcMask = &sdl.Rect{X: int32(scr.spec.ClocksPerHblank), Y: top, W: scr.playWidth, H: scr.playHeight} return scr.setMasking(scr.unmasked) } @@ -317,18 +319,12 @@ func (scr *screen) update(paused bool) error { if scr.unmasked { scr.renderer.SetDrawColor(100, 100, 100, 20) scr.renderer.SetDrawBlendMode(sdl.BlendMode(sdl.BLENDMODE_BLEND)) - spec := scr.gtv.GetSpec() - scr.renderer.FillRect(&sdl.Rect{X: 0, Y: 0, W: int32(spec.ClocksPerHblank), H: int32(spec.ScanlinesTotal)}) + scr.renderer.FillRect(&sdl.Rect{X: 0, Y: 0, W: int32(scr.spec.ClocksPerHblank), H: int32(scr.spec.ScanlinesTotal)}) } // show metasignal overlay - if scr.gtv.allowDebugging && scr.showMetaPixels { - err = scr.metaPixels.update() - if err != nil { - return err - } - - err = scr.renderer.Copy(scr.metaPixels.texture, scr.srcRect, scr.destRect) + if scr.gtv.allowDebugging && scr.showMetaVideo { + err = scr.metaVideo.update(paused) if err != nil { return err } @@ -343,7 +339,7 @@ func (scr *screen) update(paused bool) error { // cursor is one step ahead of pixel -- move to new scanline if // necessary - if x >= scr.gtv.GetSpec().ClocksPerScanline+scr.gtv.GetSpec().ClocksPerHblank { + if x >= scr.spec.ClocksPerScanline+scr.spec.ClocksPerHblank { x = 0 y++ } @@ -383,29 +379,28 @@ func (scr *screen) update(paused bool) error { return nil } -func (scr *screen) clearPixels(fade bool) { +func (scr *screen) newFrame() { if scr.gtv.allowDebugging { - // clear pixels in additional overlays - scr.metaPixels.clearPixels() + // swap pixel array with pixelsFade array + // -- note that we don't do this with the texture instead because + // updating the the extra texture if we don't need to (faded pixels + // only show when the emulation is paused) is expensive + swp := scr.pixels + scr.pixels = scr.pixelsFade + scr.pixelsFade = swp - if fade { - // "fade" alternative pixels and clear - swp := scr.altPixels - scr.altPixels = scr.altPixelsFade - scr.altPixelsFade = swp - for i := 0; i < len(scr.altPixels); i++ { - scr.altPixels[i] = 0 - } + // clear pixels in metavideo overlay + scr.metaVideo.newFrame() - // "fade" regular pixels - swp = scr.pixels - scr.pixels = scr.pixelsFade - scr.pixelsFade = swp - } else { - // clear "faded" pixels - for i := 0; i < len(scr.pixelsFade); i++ { - scr.pixelsFade[i] = 0 - } + // swap pixel array with pixelsFade array + // -- see comment above + swp = scr.altPixels + scr.altPixels = scr.altPixelsFade + scr.altPixelsFade = swp + + // clear altpixels + for i := 0; i < len(scr.altPixels); i++ { + scr.altPixels[i] = 0 } } diff --git a/gui/sdl/sdl.go b/gui/sdl/sdl.go index 6d2c9ec6..dc963cb8 100644 --- a/gui/sdl/sdl.go +++ b/gui/sdl/sdl.go @@ -90,7 +90,6 @@ func NewGUI(tvType string, scale float32, tv television.Television) (gui.GUI, er // update the gui so that it reflects changes to buffered data in the tv struct func (gtv *GUI) update() error { - // abbrogate most of the updating to the screen instance err := gtv.scr.update(gtv.paused) if err != nil { return err @@ -113,12 +112,19 @@ func (gtv *GUI) ChangeTVSpec() error { // NewFrame implements television.Renderer interface func (gtv *GUI) NewFrame(frameNum int) error { - defer gtv.scr.clearPixels(true) err := gtv.scr.stb.stabiliseFrame() if err != nil { return err } - return gtv.update() + + err = gtv.update() + if err != nil { + return err + } + + gtv.scr.newFrame() + + return nil } // NewScanline implements television.Renderer interface @@ -145,7 +151,7 @@ func (gtv *GUI) Reset() error { if err != nil { return err } - gtv.scr.clearPixels(false) + gtv.scr.newFrame() gtv.scr.lastX = 0 gtv.scr.lastY = 0 return nil diff --git a/television/stella.go b/television/stella.go index f2d305da..5bcbb86a 100644 --- a/television/stella.go +++ b/television/stella.go @@ -2,7 +2,6 @@ package television import ( "fmt" - "gopher2600/debugger/metavideo" "gopher2600/errors" "strings" ) @@ -291,11 +290,6 @@ func (btv *BasicTelevision) Signal(sig SignalAttributes) error { return nil } -// MetaSignal recieves (and processes) additional emulator information from the emulator -func (btv *BasicTelevision) MetaSignal(metavideo.MetaSignalAttributes) error { - return nil -} - // GetState returns the TVState object for the named state. television // implementations in other packages will difficulty extending this function // because TVStateReq does not expose its members. (although it may need to if diff --git a/television/television.go b/television/television.go index 13752e95..d65240a7 100644 --- a/television/television.go +++ b/television/television.go @@ -1,7 +1,5 @@ package television -import "gopher2600/debugger/metavideo" - // StateReq is used to identify which television attribute is being asked // with the GetState() function type StateReq int @@ -56,7 +54,6 @@ type Television interface { Reset() error Signal(SignalAttributes) error - MetaSignal(metavideo.MetaSignalAttributes) error GetState(StateReq) (int, error) GetSpec() *Specification