mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
o debugger
- DISPLAY command only opens the display if it is called without additional arguments. - for example, calling "DISPLAY DEBUGCOLORS" does not cause the display to appear.
This commit is contained in:
parent
8ebc46cc6f
commit
00873d6308
10 changed files with 87 additions and 19 deletions
|
@ -761,13 +761,15 @@ func (dbg *Debugger) parseCommand(userInput string) (bool, error) {
|
|||
case KeywordDisplay:
|
||||
var err error
|
||||
|
||||
visibility := true
|
||||
action, present := tokens.Get()
|
||||
if present {
|
||||
action = strings.ToUpper(action)
|
||||
switch action {
|
||||
case "OFF":
|
||||
visibility = false
|
||||
err = dbg.vcs.TV.SetFeature(television.ReqSetVisibility, false)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
case "DEBUG":
|
||||
err = dbg.vcs.TV.SetFeature(television.ReqToggleDebug)
|
||||
if err != nil {
|
||||
|
@ -796,11 +798,11 @@ func (dbg *Debugger) parseCommand(userInput string) (bool, error) {
|
|||
default:
|
||||
return false, fmt.Errorf("unknown display action (%s)", action)
|
||||
}
|
||||
}
|
||||
|
||||
err = dbg.vcs.TV.SetFeature(television.ReqSetVisibility, visibility)
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else {
|
||||
err = dbg.vcs.TV.SetFeature(television.ReqSetVisibility, true)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
case KeywordMouse:
|
||||
|
|
|
@ -73,6 +73,11 @@ func (hm *hmove) isset() bool {
|
|||
return hm.latch
|
||||
}
|
||||
|
||||
// isjustset checks to see if the horiztonal movement sequence has just started
|
||||
func (hm *hmove) isjustset() bool {
|
||||
return hm.count == 15 && hm.phase == hm.colorClock.Phase
|
||||
}
|
||||
|
||||
// tick returns the current hmove ripple counter and whether a tick has occurred
|
||||
func (hm *hmove) tick() (int, bool) {
|
||||
// if we've reached a count of -1 then no tick will ever occur
|
||||
|
|
|
@ -27,7 +27,7 @@ func newRsync(colorClock *polycounter.Polycounter) *rsync {
|
|||
|
||||
// MachineInfoTerse returns the RSYNC information in verbose format
|
||||
func (rs rsync) MachineInfoTerse() string {
|
||||
if rs.isActive() {
|
||||
if rs.isactive() {
|
||||
return fmt.Sprintf("RS=%d", rs.remainingCycles)
|
||||
}
|
||||
return "RS=-"
|
||||
|
@ -35,7 +35,7 @@ func (rs rsync) MachineInfoTerse() string {
|
|||
|
||||
// MachineInfo returns the RSYNC information in verbose format
|
||||
func (rs rsync) MachineInfo() string {
|
||||
if rs.isActive() {
|
||||
if rs.isactive() {
|
||||
return fmt.Sprintf("rsync: reset in %d cycle(s)", rs.remainingCycles)
|
||||
}
|
||||
return "rsync: not set"
|
||||
|
@ -46,7 +46,7 @@ func (rs rsync) String() string {
|
|||
return rs.MachineInfo()
|
||||
}
|
||||
|
||||
func (rs rsync) isActive() bool {
|
||||
func (rs rsync) isactive() bool {
|
||||
return rs.remainingCycles > -1
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,10 @@ func (rs *rsync) set() {
|
|||
rs.colorClock.ResetPhase()
|
||||
}
|
||||
|
||||
func (rs *rsync) isjustset() bool {
|
||||
return rs.remainingCycles == 5
|
||||
}
|
||||
|
||||
func (rs *rsync) tick() bool {
|
||||
if rs.remainingCycles == -1 {
|
||||
return false
|
||||
|
|
|
@ -182,6 +182,15 @@ func (tia *TIA) StepVideoCycle() bool {
|
|||
tia.motionClock = false
|
||||
}
|
||||
|
||||
// send metasignal information before we perform any state ticking
|
||||
err := tia.tv.MetaSignal(television.MetaSignalAttributes{
|
||||
Hmove: tia.Hmove.isjustset(),
|
||||
Rsync: tia.rsync.isjustset(),
|
||||
Wsync: tia.wsync})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// set up new scanline if colorClock has ticked its way to the reset point or if
|
||||
// an rsync has matured (see rsync.go commentary)
|
||||
if tia.rsync.tick() {
|
||||
|
@ -224,7 +233,7 @@ func (tia *TIA) StepVideoCycle() bool {
|
|||
}
|
||||
|
||||
// at the end of the video cycle we want to finally signal the televison
|
||||
err := tia.tv.Signal(television.SignalAttributes{
|
||||
err = tia.tv.Signal(television.SignalAttributes{
|
||||
VSync: tia.vsync,
|
||||
VBlank: tia.vblank,
|
||||
FrontPorch: frontPorch,
|
||||
|
|
|
@ -130,6 +130,7 @@ func (vd *Video) ResolveHorizMovement(count int) {
|
|||
// present. it also sets the collision registers
|
||||
// - it need not be called therefore during VBLANK or HBLANK
|
||||
func (vd *Video) Pixel(debugColors bool) uint8 {
|
||||
bgc := vd.Playfield.backgroundColor
|
||||
pfu, pfc := vd.Playfield.pixel()
|
||||
blu, blc := vd.Ball.pixel()
|
||||
p0u, p0c := vd.Player0.pixel()
|
||||
|
@ -138,9 +139,15 @@ func (vd *Video) Pixel(debugColors bool) uint8 {
|
|||
m1u, m1c := vd.Missile1.pixel()
|
||||
|
||||
// override program colors with debug colors
|
||||
// -- same/similar colors to those used in the Stella emulator
|
||||
if debugColors {
|
||||
bgc = 0x00 // black (stella uses a light grey)
|
||||
blc = 0xb4 // cyan
|
||||
pfc = 0x62 // purple
|
||||
p0c = 0x32 // red
|
||||
p1c = 0x15 // gold
|
||||
p1c = 0x12 // gold
|
||||
m0c = 0xf2 // orange
|
||||
m1c = 0xd2 // green
|
||||
}
|
||||
|
||||
// collisions
|
||||
|
@ -266,7 +273,7 @@ func (vd *Video) Pixel(debugColors bool) uint8 {
|
|||
}
|
||||
|
||||
// priority 4
|
||||
return vd.Playfield.backgroundColor
|
||||
return bgc
|
||||
}
|
||||
|
||||
func createTriggerList(playerSize uint8) []int {
|
||||
|
|
|
@ -253,6 +253,11 @@ func (tv *HeadlessTV) Signal(sig SignalAttributes) error {
|
|||
return tv.HookSetPixel(x, y, red, green, blue, sig.VBlank)
|
||||
}
|
||||
|
||||
// MetaSignal recieves (and processes) additional emulator information from the emulator
|
||||
func (tv *HeadlessTV) MetaSignal(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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package sdltv
|
||||
|
||||
// callback is used to wrap functions supplied to RequestCallbackRegistration()
|
||||
// callback is used to wrap functions supplied to RequestCallback()
|
||||
|
||||
type callback struct {
|
||||
channel chan func()
|
||||
|
|
|
@ -24,8 +24,8 @@ type screen struct {
|
|||
lastX int32
|
||||
lastY int32
|
||||
|
||||
// pixels arrays are of maximum screen size - actual smalled screens are
|
||||
// masked appropriately
|
||||
// pixels arrays are of maximum screen size - actual smaller play screens
|
||||
// are masked appropriately
|
||||
pixels []byte
|
||||
pixelsFade []byte
|
||||
|
||||
|
@ -54,6 +54,9 @@ type screen struct {
|
|||
|
||||
// stabiliser to make sure image remains solid
|
||||
stb *screenStabiliser
|
||||
|
||||
// overlay for screen showing metasignal information
|
||||
metasignals *metasignalOverlay
|
||||
}
|
||||
|
||||
func newScreen(tv *SDLTV) (*screen, error) {
|
||||
|
@ -112,6 +115,12 @@ func newScreen(tv *SDLTV) (*screen, error) {
|
|||
// new stabiliser
|
||||
scr.stb = newScreenStabiliser(scr)
|
||||
|
||||
// new overlay
|
||||
scr.metasignals, err = newMetasignalOverlay(scr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return scr, nil
|
||||
}
|
||||
|
||||
|
@ -204,6 +213,12 @@ func (scr *screen) setPixel(x, y int32, red, green, blue byte, vblank bool) erro
|
|||
func (scr *screen) update(paused bool) error {
|
||||
var err error
|
||||
|
||||
// update additional overlays
|
||||
err = scr.metasignals.update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// clear image from rendered. using a non-video-black color if screen is
|
||||
// unmasked
|
||||
if scr.unmasked {
|
||||
|
@ -242,6 +257,14 @@ func (scr *screen) update(paused bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// show debugging overlay
|
||||
if scr.unmasked {
|
||||
err = scr.renderer.Copy(scr.metasignals.texture, scr.srcRect, scr.destRect)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// add cursor if tv is paused
|
||||
// - drawing last so that cursor isn't masked
|
||||
if paused {
|
||||
|
@ -291,7 +314,7 @@ func (scr *screen) update(paused bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (scr *screen) swapPixels() {
|
||||
func (scr *screen) clearPixels() {
|
||||
// swap which pixel buffer we're using in time for next round of pixel
|
||||
// plotting
|
||||
swp := scr.pixels
|
||||
|
@ -302,4 +325,7 @@ func (scr *screen) swapPixels() {
|
|||
for i := 0; i < len(scr.pixels); i++ {
|
||||
scr.pixels[i] = 0
|
||||
}
|
||||
|
||||
// clear pixels in additional overlays
|
||||
scr.metasignals.clearPixels()
|
||||
}
|
||||
|
|
|
@ -77,9 +77,9 @@ func NewSDLTV(tvType string, scale float32) (*SDLTV, error) {
|
|||
}
|
||||
|
||||
// register headlesstv callbacks
|
||||
// leave SignalNewScanline() hook at its default
|
||||
// --leave SignalNewScanline() hook at its default
|
||||
tv.HookNewFrame = func() error {
|
||||
defer tv.scr.swapPixels()
|
||||
defer tv.scr.clearPixels()
|
||||
err := tv.scr.stb.checkStableFrame()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -49,6 +49,15 @@ type SignalAttributes struct {
|
|||
Pixel ColorSignal
|
||||
}
|
||||
|
||||
// MetaSignalAttributes represents any additional emulator data sent to the
|
||||
// "television" (in inverted commas). not all television implementations need
|
||||
// to do anything useful with this information.
|
||||
type MetaSignalAttributes struct {
|
||||
Hmove bool
|
||||
Rsync bool
|
||||
Wsync bool
|
||||
}
|
||||
|
||||
// Television defines the operations that can be performed on the television
|
||||
type Television interface {
|
||||
MachineInfoTerse() string
|
||||
|
@ -56,6 +65,7 @@ type Television interface {
|
|||
|
||||
Reset() error
|
||||
Signal(SignalAttributes) error
|
||||
MetaSignal(MetaSignalAttributes) error
|
||||
|
||||
GetState(StateReq) (interface{}, error)
|
||||
GetMetaState(MetaStateReq) (string, error)
|
||||
|
|
Loading…
Add table
Reference in a new issue