o television

- commentary and documentation
    - added DebugColorSignal type

o tia/video
    - changes due to addition of DebugColorSignal
This commit is contained in:
steve 2019-12-11 09:58:56 +00:00
parent 1a5a1fbff8
commit d764ece740
7 changed files with 52 additions and 31 deletions

View file

@ -187,7 +187,7 @@ func (tia *TIA) Step(serviceMemory bool) (bool, error) {
// resolve video pixels. note that we always send the debug color
// regardless of hblank
pixelColor, debugColor := tia.Video.Pixel()
tia.sig.AltPixel = television.ColorSignal(debugColor)
tia.sig.AltPixel = debugColor
if tia.hblank {
// if hblank is on then we don't sent the resolved color but the video
// black signal instead

View file

@ -112,7 +112,7 @@ func (vd *Video) PrepareSpritesForHMOVE() {
// 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 (vd *Video) Pixel() (uint8, uint8) {
func (vd *Video) Pixel() (uint8, television.DebugColorSignal) {
bgc := vd.Playfield.backgroundColor
pfu, pfc := vd.Playfield.pixel()
p0u, p0c := vd.Player0.pixel()
@ -211,7 +211,8 @@ func (vd *Video) Pixel() (uint8, uint8) {
// priorties
priority := vd.Playfield.priority || (vd.Playfield.scoremode && vd.Playfield.region == regionLeft)
var col, dcol uint8
var col uint8
var dcol television.DebugColorSignal
if priority {
if pfu { // priority 1

View file

@ -78,10 +78,15 @@ var colorsAltRaw = []uint32{
0x333333, 0x84c8fc, 0x9246c0, 0x901c00, 0xe8e84a, 0xd5824a, 0x328432,
}
// as used in Stella, the colors above are used as below. note that using a
// alt pixel ColorSignal not in the following list may result in a panic
// DebugColorSignal is used by the debugging feature of the television (if
// available). Each signal sent to the televsoin should specify a
// DebugColorSignal, indicating from which video element the pixel was
// generated.
type DebugColorSignal uint16
// List of valid DebugColorSignals
const (
AltColBackground = iota
AltColBackground DebugColorSignal = iota
AltColBall
AltColPlayfield
AltColPlayer0
@ -120,11 +125,7 @@ func getColor(spec *Specification, sig ColorSignal) (byte, byte, byte) {
}
// getColor translates a color signal to the individual color components
func getAltColor(sig ColorSignal) (byte, byte, byte) {
if sig == VideoBlack {
return videoBlack[red], videoBlack[green], videoBlack[blue]
}
func getAltColor(sig DebugColorSignal) (byte, byte, byte) {
if int(sig) >= len(colorsAlt) {
panic("alt color signal too big")
}

23
television/doc.go Normal file
View file

@ -0,0 +1,23 @@
// Package television implements the output device of the emulated VCS. The
// television interface is used wherever a television needs to be connected.
// The NewTelevision() function creates a new instance of a reference
// implementation of the Television interface. In truth, it is probably the
// only implementation required but the option is there for alternatives.
//
// It is common for instances of television to be embedded in other type
// structure, thereby extending the "features" of the television and allowing
// the extended type to be used wherever the Television interface is required.
// The digest package is a good example of this idea.
//
// It is important to note that the reference television implementation does
// not render pixels or mix sound itself. Instead, the television interface
// exposes two functions, AddPixelRenderer() and AddAudioMixer(). These can be
// used to add as many renderers and mixers as required.
//
// The main means of communication is the Signal() function. This function
// accepts an instance of SignalAttributes which gives details of how the
// television should be behaving. The SignalAttributes type is meant to emulate
// the electrical signal between the VCS and the television but some
// concessions have been made for easement. The HSyncSimple in particular is a
// large piece of fudge but a necessary one.
package television

View file

@ -38,26 +38,17 @@ type Television interface {
End() error
}
// PixelRenderer implementations displays, or otherwise works with, visal
// information from a television
// PixelRenderer implementations displays, or otherwise works with, visual
// information from a television. For example digest.Video.
//
// examples of renderers that display visual information:
// * SDLPlay
// * ImageTV
//
// examples of renderers that do not display visual information but only work
// with it:
// * DigestTV
//
// PixelRenderer implementations find it convenient to maintain a reference to
// PixelRenderer implementations often find it convenient to maintain a reference to
// the parent Television implementation and maybe even embed the Television
// interface. ie.
//
// type ExampleTV struct {
// type ExampleTV struct {
// television.Television
//
// ...
// }
// }
type PixelRenderer interface {
// Resize is called when the television implementation detects that extra
// scanlines are required in the display.
@ -111,7 +102,9 @@ type PixelRenderer interface {
EndRendering() error
}
// AudioMixer implementations work with sound; most probably playing it.
// AudioMixer implementations work with sound; most probably playing it. An
// example of an AudioMixer that does not play sound but otherwise works with
// it is the digest.Audio type.
type AudioMixer interface {
SetAudio(audioData uint8) error
FlushAudio() error
@ -134,7 +127,7 @@ type SignalAttributes struct {
// AltPixel allows the emulator to set an alternative color for each pixel
// - used to signal the debug color in addition to the regular color
// - arguable that this be sent as some sort of meta-signal
AltPixel ColorSignal
AltPixel DebugColorSignal
// the HSyncSimple attribute is not part of the real TV spec. The signal
// for a real flyback is the HSync signal (held for 8 color clocks).
@ -162,7 +155,7 @@ type SignalAttributes struct {
// with the GetState() function
type StateReq int
// list of valid state requests
// List of valid state requests
const (
ReqFramenum StateReq = iota
ReqScanline

View file

@ -52,13 +52,16 @@ type Specification struct {
AspectBias float32
}
// From the Stella Programmer's Guide:
//
// "Each scan lines starts with 68 clock counts of horizontal blank (not seen on
// the TV screen) followed by 160 clock counts to fully scan one line of TV
// picture. When the electron beam reaches the end of a scan line, it returns
// to the left side of the screen, waits for the 68 horizontal blank clock
// counts, and proceeds to draw the next line below."
//
// Horizontal clock counts are the same for both TV specificationst
// Horizontal clock counts are the same for both TV specifications. Vertical
// information should be accessed via SpecNTSC or SpecPAL.
const (
HorizClksHBlank = 68
HorizClksVisible = 160

View file

@ -69,8 +69,8 @@ type television struct {
// before we accept the frame characteristics
const stabilityThreshold = 5
// NewTelevision creates a new instance of StellaTelevision for a
// minimalist implementation of a televsion for the VCS emulation
// NewTelevision creates a new instance of the television type, satisfying the
// Television interface.
func NewTelevision(tvType string) (Television, error) {
tv := &television{}