video

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2020 License: GPL-3.0, GPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package video implements pixel generation for the emulated TIA. Pixel generation is conceptually divided into six areas, implemented as types. These are:

Playfield
Player 0  and  Player 1
Missile 0  and  Missile 1
Ball

Collectively we can refer to these as the playfield and sprites (even though the VCS sprites are nothing like what we now think of sprites, it is a useful appellation none-the-less).

The video subsystem is ticked along with the TIA every video cycle. The playfield is closely related to the TIA's HSYNC and is not ticked separately. The sprites are ticked depending on the state of the TIA's HBLANK signal; it also depends on whether HMOVE has been recently latched in the TIA and whether the sprite has completed any horizontal movement. For this reason the video sub-system and the sprites are initialised with references to the HBLANK signal and the HMOVE latch.

Reading of TIA memory is divided into six different Update*() functions. The timing of when TIA memory is read and registers updated is important and dividing the update functions in this manner helps. The TIA package handles these timings.

The three sprite categories, player, missile and ball, all have common features but have been implemented to be completely separate from one another. The exception is the enclockifier type used by both missiles and the ball.

All sprites keep track of their own phase clocks and position counters. Delayed side effects only occur when the sprite itself is ticked and so each sprite also has an instance of Ticker from the future package.

A significant difference to the description in Andrew Towers' document, "Atari 2600 TIA Hardware Notes", is how HMOVE counters are handled. In Towers' description of the hardware, the HMOVE latch, the counters and the signal line to the sprite are all intertwined. In the emulation this is almost turned inside out with the sprite maintaining its own counter and ticking (include HMOVE stuffing ticks) only when required.

Somewhere during the cycle the video sub-system will decide on what the pixel output should be (in this context we mean VCS clock-wide pixels). That is, we're deciding what the colour of all TV pixels for the duration of the video cycle should be.

The timing of this decision is critical: it must happen before some register updates but after others. Note that the pixel color decision is distinct from sending the color signal to the TV (which is handled by the TIA) package). Sending of the color signal always happens at the very end of the video cycle.

To effectively make the pixel color decision, the video sub-system at the same time processes the pixel "priority". For convenience, pixel collisions are also set at this time.

Index

Constants

This section is empty.

Variables

View Source
var BallSizes = []string{
	"single size",
	"double size",
	"quad size",
	"double-quad size",
}

BallSizes maps ball size values to descriptions of those sizes

View Source
var MissileCopies = []string{
	"one copy",
	"two copies [close]",
	"two copies [med]",
	"three copies [close]",
	"two copies [wide]",
	"one copy",
	"three copies [med]",
	"one copy",
}

MissileCopies maps missile copies values to descriptions of those values

View Source
var MissileSizes = []string{
	"single width",
	"double width",
	"quadruple width",
	"doub-quad width",
}

MissileSizes maps missile sizes values to descriptions of those values

View Source
var PlayerSizes = []string{
	"one copy",
	"two copies [close]",
	"two copies [med]",
	"three copies [close]",
	"two copies [wide]",
	"double size",
	"three copies [med]",
	"quad size",
}

PlayerSizes maps player size and copies values to descriptions of those values

Functions

This section is empty.

Types

type ScreenRegion

type ScreenRegion int

ScreenRegion notes which part of the screen is currently being drawn

const (
	RegionOffScreen ScreenRegion = iota
	RegionLeft
	RegionRight
)

List of valid ScreenRegions

type Video

type Video struct {

	// playfield
	Playfield *playfield

	// sprite objects
	Player0  *playerSprite
	Player1  *playerSprite
	Missile0 *missileSprite
	Missile1 *missileSprite
	Ball     *ballSprite
	// contains filtered or unexported fields
}

Video contains all the components of the video sub-system of the VCS TIA chip

func NewVideo

func NewVideo(mem bus.ChipBus,
	pclk *phaseclock.PhaseClock, hsync *polycounter.Polycounter,
	tv television.Television, hblank, hmoveLatch *bool) (*Video, error)

NewVideo is the preferred method of initialisation for the Video structure.

The playfield type requires access access to the TIA's phaseclock and polyucounter and is used to decide which part of the playfield is to be drawn.

The sprites meanwhile require access to the television. This is for generating information about the sprites reset position - a debugging only requirement but of minimal performance related consequeunce.

The references to the TIA's HBLANK state and whether HMOVE is latched, are required to tune the delays experienced by the various sprite events (eg. reset position).

func (*Video) Pixel

func (vd *Video) Pixel() (uint8, colors.AltColor)

Pixel returns the color of the pixel at the current clock and also sets the collision registers. It will default to returning the background color if no sprite or playfield pixel is present.

func (*Video) PrepareSpritesForHMOVE

func (vd *Video) PrepareSpritesForHMOVE()

PrepareSpritesForHMOVE should be called whenever HMOVE is triggered

func (*Video) RSYNC

func (vd *Video) RSYNC(adjustment int)

RSYNC adjusts the debugging information of the sprites when an RSYNC is triggered

func (*Video) Tick

func (vd *Video) Tick(visible, hmove bool, hmoveCt uint8)

Tick moves all video elements forward one video cycle. This is the conceptual equivalent of the hardware MOTCK line.

func (*Video) UpdateCTRLPF

func (vd *Video) UpdateCTRLPF()

UpdateCTRLPF should be called whenever any of the individual components of the CTRPF are altered. For example, if Playfield.Reflected is altered, then this function should be called so that the CTRLPF value is set to reflect the alteration.

This is only of use to debuggers. It's never required in normal operation of the emulator.

func (*Video) UpdateColor

func (vd *Video) UpdateColor(data bus.ChipData) bool

UpdateColor checks TIA memory for changes to color registers.

Returns true if memory.ChipData has not been serviced.

func (*Video) UpdateNUSIZ

func (vd *Video) UpdateNUSIZ(num int, fromMissile bool)

UpdateNUSIZ should be called whenever the player/missile size/copies information is altered. This function updates the NUSIZ value to reflect the changes whilst maintaining the other NUSIZ bits.

This is only of use to debuggers. It's never required in normal operation of the emulator.

func (*Video) UpdatePlayfield

func (vd *Video) UpdatePlayfield(tiaDelay future.Scheduler, data bus.ChipData) bool

UpdatePlayfield checks TIA memory for new playfield data. Note that CTRLPF is serviced in UpdateSpriteVariations().

Returns true if ChipData has *not* been serviced.

func (*Video) UpdateSpriteHMOVE

func (vd *Video) UpdateSpriteHMOVE(tiaDelay future.Scheduler, data bus.ChipData) bool

UpdateSpriteHMOVE checks TIA memory for changes in sprite HMOVE settings.

Returns true if ChipData has *not* been serviced.

func (*Video) UpdateSpritePixels

func (vd *Video) UpdateSpritePixels(data bus.ChipData) bool

UpdateSpritePixels checks TIA memory for attribute changes that *must* occur after a call to Pixel().

Returns true if memory.ChipData has not been serviced.

func (*Video) UpdateSpritePositioning

func (vd *Video) UpdateSpritePositioning(data bus.ChipData) bool

UpdateSpritePositioning checks TIA memory for strobing of reset registers.

Returns true if memory.ChipData has not been serviced.

func (*Video) UpdateSpriteVariations

func (vd *Video) UpdateSpriteVariations(data bus.ChipData) bool

UpdateSpriteVariations checks TIA memory for writes to registers that affect how sprite pixels are output. Note that CTRLPF is serviced here rather than in UpdatePlayfield(), because it affects the ball sprite.

Returns true if memory.ChipData has not been serviced.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL