Gopher2600/hardware/television/adjustment.go
JetSetIlly 8a8a306670 corrected rewind splicing point
rewind.String() now produces correct summary in all instances

rewind reset on frequency change (in addition to the existing rule about
number of states). timeline no longer reset on this type of rewind
reset.

adjust coordinates function uses the correct zero value for color
clocks. the error could be seen on STEP BACK FRAME when the execution
would stop near clock 0 rathre than clock -68

execution states are recorded and appended to the history every frame
regardless of the snapshot frequency schedule. they continue to be
trimmed in the usual way. on emulation halt meanwhile, the current
coordinates are recorded which is more flexible and allows for video
cycle granularity.
2021-11-18 10:29:33 +00:00

85 lines
2.5 KiB
Go

// This file is part of Gopher2600.
//
// Gopher2600 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Gopher2600 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package television
import (
"github.com/jetsetilly/gopher2600/hardware/television/coords"
"github.com/jetsetilly/gopher2600/hardware/television/specification"
)
// AdjCoords returns a coords.TelevisionCoords with the current coords adjusted
// by the specified amount.
func (tv *Television) AdjCoords(adj Adj, amount int) coords.TelevisionCoords {
coords := tv.GetCoords()
switch adj {
case AdjCPUCycle:
// adjusting by CPU cycle is the same as adjusting by video cycle
// accept to say that a CPU cycle is the equivalent of 3 video cycles
amount *= 3
fallthrough
case AdjClock:
coords.Clock += amount
if coords.Clock >= specification.ClksScanline {
coords.Clock -= specification.ClksScanline
coords.Scanline++
} else if coords.Clock < 0 {
coords.Clock += specification.ClksScanline
coords.Scanline--
}
if coords.Scanline > tv.state.frameInfo.TotalScanlines {
coords.Scanline -= tv.state.frameInfo.TotalScanlines
coords.Frame++
} else if coords.Scanline < 0 {
coords.Scanline += tv.state.frameInfo.TotalScanlines
coords.Frame--
}
case AdjScanline:
coords.Clock = -specification.ClksHBlank
coords.Scanline += amount
if coords.Scanline > tv.state.frameInfo.TotalScanlines {
coords.Scanline -= tv.state.frameInfo.TotalScanlines
coords.Frame++
} else if coords.Scanline < 0 {
coords.Scanline += tv.state.frameInfo.TotalScanlines
coords.Frame--
}
case AdjFrame:
coords.Clock = -specification.ClksHBlank
coords.Scanline = 0
coords.Frame += amount
}
// zero values if frame is less than zero
if coords.Frame < 0 {
coords.Frame = 0
coords.Scanline = 0
coords.Clock = -specification.ClksHBlank
}
return coords
}
// Adj is used to specify adjustment scale for the ReqAdjust() function.
type Adj int
// List of valid Adj values.
const (
AdjFrame Adj = iota
AdjScanline
AdjCPUCycle
AdjClock
)