mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2024-05-10 17:25:21 -04:00
setup entries output log message on successful application
clarified some database concepts - updated regression and setup packages accordingly
This commit is contained in:
parent
3aa5885ebe
commit
68cf99620e
|
@ -27,14 +27,9 @@ type SerialisedEntry []string
|
|||
|
||||
// Entry represents the generic entry in the database.
|
||||
type Entry interface {
|
||||
// ID returns the string that is used to identify the entry type in
|
||||
// EntryType returns the string that is used to identify the entry type in
|
||||
// the database
|
||||
ID() string
|
||||
|
||||
// String should return information about the entry in a human readable
|
||||
// format. by contrast, machine readable representation is returned by the
|
||||
// Serialise function
|
||||
String() string
|
||||
EntryType() string
|
||||
|
||||
// return the Entry data as an instance of SerialisedEntry.
|
||||
Serialise() (SerialisedEntry, error)
|
||||
|
|
|
@ -125,7 +125,7 @@ func (db *Session) EndSession(commitChanges bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
s.WriteString(recordHeader(k, v.ID()))
|
||||
s.WriteString(recordHeader(k, v.EntryType()))
|
||||
|
||||
for i := 0; i < len(ser); i++ {
|
||||
s.WriteString(fieldSep)
|
||||
|
|
|
@ -32,7 +32,7 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/setup"
|
||||
)
|
||||
|
||||
const logEntryID = "log"
|
||||
const logEntryType = "log"
|
||||
|
||||
const (
|
||||
logFieldCartName int = iota
|
||||
|
@ -87,20 +87,9 @@ func deserialiseLogEntry(fields database.SerialisedEntry) (database.Entry, error
|
|||
return reg, nil
|
||||
}
|
||||
|
||||
// ID implements the database.Entry interface.
|
||||
func (reg LogRegression) ID() string {
|
||||
return logEntryID
|
||||
}
|
||||
|
||||
// String implements the database.Entry interface.
|
||||
func (reg LogRegression) String() string {
|
||||
s := strings.Builder{}
|
||||
|
||||
s.WriteString(fmt.Sprintf("[%s] %s [%s] frames=%d", reg.ID(), reg.CartLoad.ShortName(), reg.TVtype, reg.NumFrames))
|
||||
if reg.Notes != "" {
|
||||
s.WriteString(fmt.Sprintf(" [%s]", reg.Notes))
|
||||
}
|
||||
return s.String()
|
||||
// EntryType implements the database.Entry interface.
|
||||
func (reg LogRegression) EntryType() string {
|
||||
return logEntryType
|
||||
}
|
||||
|
||||
// Serialise implements the database.Entry interface.
|
||||
|
@ -121,6 +110,17 @@ func (reg LogRegression) CleanUp() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// String implements the regressions.Regressor interface
|
||||
func (reg LogRegression) String() string {
|
||||
s := strings.Builder{}
|
||||
|
||||
s.WriteString(fmt.Sprintf("[%s] %s [%s] frames=%d", reg.EntryType(), reg.CartLoad.ShortName(), reg.TVtype, reg.NumFrames))
|
||||
if reg.Notes != "" {
|
||||
s.WriteString(fmt.Sprintf(" [%s]", reg.Notes))
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// regress implements the regression.Regressor interface.
|
||||
func (reg *LogRegression) regress(newRegression bool, output io.Writer, msg string) (bool, string, error) {
|
||||
// make sure logger is clear
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/recorder"
|
||||
)
|
||||
|
||||
const playbackEntryID = "playback"
|
||||
const playbackEntryType = "playback"
|
||||
|
||||
const (
|
||||
playbackFieldScript int = iota
|
||||
|
@ -68,19 +68,9 @@ func deserialisePlaybackEntry(fields database.SerialisedEntry) (database.Entry,
|
|||
return reg, nil
|
||||
}
|
||||
|
||||
// ID implements the database.Entry interface.
|
||||
func (reg PlaybackRegression) ID() string {
|
||||
return playbackEntryID
|
||||
}
|
||||
|
||||
// String implements the database.Entry interface.
|
||||
func (reg PlaybackRegression) String() string {
|
||||
s := strings.Builder{}
|
||||
s.WriteString(fmt.Sprintf("[%s] %s", reg.ID(), filepath.Base(reg.Script)))
|
||||
if reg.Notes != "" {
|
||||
s.WriteString(fmt.Sprintf(" [%s]", reg.Notes))
|
||||
}
|
||||
return s.String()
|
||||
// EntryType implements the database.Entry interface.
|
||||
func (reg PlaybackRegression) EntryType() string {
|
||||
return playbackEntryType
|
||||
}
|
||||
|
||||
// Serialise implements the database.Entry interface.
|
||||
|
@ -101,6 +91,16 @@ func (reg PlaybackRegression) CleanUp() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// String implements the regression.Regressor interface.
|
||||
func (reg PlaybackRegression) String() string {
|
||||
s := strings.Builder{}
|
||||
s.WriteString(fmt.Sprintf("[%s] %s", reg.EntryType(), filepath.Base(reg.Script)))
|
||||
if reg.Notes != "" {
|
||||
s.WriteString(fmt.Sprintf(" [%s]", reg.Notes))
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// regress implements the regression.Regressor interface.
|
||||
func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg string) (_ bool, _ string, rerr error) {
|
||||
output.Write([]byte(msg))
|
||||
|
|
|
@ -40,6 +40,11 @@ const regressionScripts = "scripts"
|
|||
type Regressor interface {
|
||||
database.Entry
|
||||
|
||||
// String should return information about the entry in a human readable
|
||||
// format. by contrast, machine readable representation is returned by the
|
||||
// Serialise function
|
||||
String() string
|
||||
|
||||
// perform the regression test for the regression type. the newRegression
|
||||
// flag is for convenience really (or "logical binding", as the structured
|
||||
// programmers would have it)
|
||||
|
@ -54,15 +59,15 @@ type Regressor interface {
|
|||
// when starting a database session we need to register what entries we will
|
||||
// find in the database.
|
||||
func initDBSession(db *database.Session) error {
|
||||
if err := db.RegisterEntryType(videoEntryID, deserialiseVideoEntry); err != nil {
|
||||
if err := db.RegisterEntryType(videoEntryType, deserialiseVideoEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.RegisterEntryType(playbackEntryID, deserialisePlaybackEntry); err != nil {
|
||||
if err := db.RegisterEntryType(playbackEntryType, deserialisePlaybackEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.RegisterEntryType(logEntryID, deserialiseLogEntry); err != nil {
|
||||
if err := db.RegisterEntryType(logEntryType, deserialiseLogEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -87,7 +92,11 @@ func RegressList(output io.Writer) error {
|
|||
defer db.EndSession(false)
|
||||
|
||||
return db.ForEach(func(key int, e database.Entry) error {
|
||||
output.Write([]byte(fmt.Sprintf("%03d %s\n", key, e.String())))
|
||||
r, ok := e.(Regressor)
|
||||
if !ok {
|
||||
return fmt.Errorf("regression: list: %s does not implement the Regressor interfrace", e.EntryType())
|
||||
}
|
||||
output.Write([]byte(fmt.Sprintf("%03d %s\n", key, r.String())))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -246,7 +255,7 @@ func RegressCleanup(output io.Writer, confirmation io.Reader) error {
|
|||
// no support required
|
||||
|
||||
default:
|
||||
return fmt.Errorf("not supported (%s)", reg.ID())
|
||||
return fmt.Errorf("not supported (%s)", reg.EntryType())
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/setup"
|
||||
)
|
||||
|
||||
const videoEntryID = "video"
|
||||
const videoEntryType = "video"
|
||||
|
||||
const (
|
||||
videoFieldCartName int = iota
|
||||
|
@ -120,36 +120,9 @@ func deserialiseVideoEntry(fields database.SerialisedEntry) (database.Entry, err
|
|||
return reg, nil
|
||||
}
|
||||
|
||||
// ID implements the database.Entry interface.
|
||||
func (reg VideoRegression) ID() string {
|
||||
return videoEntryID
|
||||
}
|
||||
|
||||
// String implements the database.Entry interface.
|
||||
func (reg VideoRegression) String() string {
|
||||
s := strings.Builder{}
|
||||
|
||||
state := ""
|
||||
switch reg.State {
|
||||
case StateNone:
|
||||
state = ""
|
||||
case StateTV:
|
||||
state = " [TV state]"
|
||||
case StatePorts:
|
||||
state = " [ports state]"
|
||||
case StateTimer:
|
||||
state = " [timer state]"
|
||||
case StateCPU:
|
||||
state = " [cpu state]"
|
||||
default:
|
||||
state = " [with state]"
|
||||
}
|
||||
|
||||
s.WriteString(fmt.Sprintf("[%s] %s [%s] frames=%d%s", reg.ID(), reg.CartLoad.ShortName(), reg.TVtype, reg.NumFrames, state))
|
||||
if reg.Notes != "" {
|
||||
s.WriteString(fmt.Sprintf(" [%s]", reg.Notes))
|
||||
}
|
||||
return s.String()
|
||||
// EntryType implements the database.Entry interface.
|
||||
func (reg VideoRegression) EntryType() string {
|
||||
return videoEntryType
|
||||
}
|
||||
|
||||
// Serialise implements the database.Entry interface.
|
||||
|
@ -177,6 +150,33 @@ func (reg VideoRegression) CleanUp() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// String implements the regression.Regressor interface
|
||||
func (reg VideoRegression) String() string {
|
||||
s := strings.Builder{}
|
||||
|
||||
state := ""
|
||||
switch reg.State {
|
||||
case StateNone:
|
||||
state = ""
|
||||
case StateTV:
|
||||
state = " [TV state]"
|
||||
case StatePorts:
|
||||
state = " [ports state]"
|
||||
case StateTimer:
|
||||
state = " [timer state]"
|
||||
case StateCPU:
|
||||
state = " [cpu state]"
|
||||
default:
|
||||
state = " [with state]"
|
||||
}
|
||||
|
||||
s.WriteString(fmt.Sprintf("[%s] %s [%s] frames=%d%s", reg.EntryType(), reg.CartLoad.ShortName(), reg.TVtype, reg.NumFrames, state))
|
||||
if reg.Notes != "" {
|
||||
s.WriteString(fmt.Sprintf(" [%s]", reg.Notes))
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// regress implements the regression.Regressor interface.
|
||||
func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg string) (_ bool, _ string, rerr error) {
|
||||
output.Write([]byte(msg))
|
||||
|
|
|
@ -25,10 +25,11 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/hardware/riot/ports/plugging"
|
||||
)
|
||||
|
||||
const panelSetupID = "panel"
|
||||
const panelSetupEntryType = "panel"
|
||||
|
||||
const (
|
||||
panelSetupFieldCartHash int = iota
|
||||
panelSetupFieldCartName
|
||||
panelSetupFieldP0
|
||||
panelSetupFieldP1
|
||||
panelSetupFieldCol
|
||||
|
@ -39,6 +40,7 @@ const (
|
|||
// PanelSetup is used to adjust the VCS's front panel.
|
||||
type PanelSetup struct {
|
||||
cartHash string
|
||||
cartName string
|
||||
|
||||
p0 bool
|
||||
p1 bool
|
||||
|
@ -61,6 +63,7 @@ func deserialisePanelSetupEntry(fields database.SerialisedEntry) (database.Entry
|
|||
var err error
|
||||
|
||||
set.cartHash = fields[panelSetupFieldCartHash]
|
||||
set.cartName = fields[panelSetupFieldCartName]
|
||||
|
||||
if set.p0, err = strconv.ParseBool(fields[panelSetupFieldP0]); err != nil {
|
||||
return nil, fmt.Errorf("panel: invalid player 0 setting")
|
||||
|
@ -79,20 +82,16 @@ func deserialisePanelSetupEntry(fields database.SerialisedEntry) (database.Entry
|
|||
return set, nil
|
||||
}
|
||||
|
||||
// ID implements the database.Entry interface.
|
||||
func (set PanelSetup) ID() string {
|
||||
return panelSetupID
|
||||
}
|
||||
|
||||
// String implements the database.Entry interface.
|
||||
func (set PanelSetup) String() string {
|
||||
return fmt.Sprintf("%s, p0=%v, p1=%v, col=%v\n", set.cartHash, set.p0, set.p1, set.col)
|
||||
// EntryType implements the database.Entry interface.
|
||||
func (set PanelSetup) EntryType() string {
|
||||
return panelSetupEntryType
|
||||
}
|
||||
|
||||
// Serialise implements the database.Entry interface.
|
||||
func (set *PanelSetup) Serialise() (database.SerialisedEntry, error) {
|
||||
return database.SerialisedEntry{
|
||||
set.cartHash,
|
||||
set.cartName,
|
||||
strconv.FormatBool(set.p0),
|
||||
strconv.FormatBool(set.p1),
|
||||
strconv.FormatBool(set.col),
|
||||
|
@ -113,42 +112,42 @@ func (set PanelSetup) matchCartHash(hash string) bool {
|
|||
}
|
||||
|
||||
// apply implements setupEntry interface.
|
||||
func (set PanelSetup) apply(vcs *hardware.VCS) error {
|
||||
func (set PanelSetup) apply(vcs *hardware.VCS) (string, error) {
|
||||
if set.p0 {
|
||||
inp := ports.InputEvent{Port: plugging.PortPanel, Ev: ports.PanelSetPlayer0Pro, D: true}
|
||||
if _, err := vcs.Input.HandleInputEvent(inp); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
inp := ports.InputEvent{Port: plugging.PortPanel, Ev: ports.PanelSetPlayer0Pro, D: false}
|
||||
if _, err := vcs.Input.HandleInputEvent(inp); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if set.p1 {
|
||||
inp := ports.InputEvent{Port: plugging.PortPanel, Ev: ports.PanelSetPlayer1Pro, D: true}
|
||||
if _, err := vcs.Input.HandleInputEvent(inp); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
inp := ports.InputEvent{Port: plugging.PortPanel, Ev: ports.PanelSetPlayer1Pro, D: false}
|
||||
if _, err := vcs.Input.HandleInputEvent(inp); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if set.col {
|
||||
inp := ports.InputEvent{Port: plugging.PortPanel, Ev: ports.PanelSetColor, D: true}
|
||||
if _, err := vcs.Input.HandleInputEvent(inp); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
inp := ports.InputEvent{Port: plugging.PortPanel, Ev: ports.PanelSetColor, D: false}
|
||||
if _, err := vcs.Input.HandleInputEvent(inp); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return fmt.Sprintf("panel preset: %s: %s", set.cartName, set.notes), nil
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/patch"
|
||||
)
|
||||
|
||||
const patchID = "patch"
|
||||
const patchEntryType = "patch"
|
||||
|
||||
const (
|
||||
patchFieldCartHash int = iota
|
||||
patchFieldPatchFile
|
||||
patchFieldCartName
|
||||
patchFieldNotes
|
||||
numPatchFields
|
||||
)
|
||||
|
@ -35,9 +35,9 @@ const (
|
|||
// Patch is used to patch cartridge memory after cartridge has been
|
||||
// attached/loaded.
|
||||
type Patch struct {
|
||||
cartHash string
|
||||
patchFile string
|
||||
notes string
|
||||
cartHash string
|
||||
cartName string
|
||||
notes string
|
||||
}
|
||||
|
||||
func deserialisePatchEntry(fields database.SerialisedEntry) (database.Entry, error) {
|
||||
|
@ -52,30 +52,24 @@ func deserialisePatchEntry(fields database.SerialisedEntry) (database.Entry, err
|
|||
}
|
||||
|
||||
set.cartHash = fields[patchFieldCartHash]
|
||||
set.patchFile = fields[patchFieldPatchFile]
|
||||
set.cartName = fields[patchFieldCartName]
|
||||
set.notes = fields[patchFieldNotes]
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// ID implements the database.Entry interface.
|
||||
func (set Patch) ID() string {
|
||||
return patchID
|
||||
}
|
||||
|
||||
// String implements the database.Entry interface.
|
||||
func (set Patch) String() string {
|
||||
return fmt.Sprintf("%s, %s", set.cartHash, set.patchFile)
|
||||
// EntryType implements the database.Entry interface.
|
||||
func (set Patch) EntryType() string {
|
||||
return patchEntryType
|
||||
}
|
||||
|
||||
// Serialise implements the database.Entry interface.
|
||||
func (set *Patch) Serialise() (database.SerialisedEntry, error) {
|
||||
return database.SerialisedEntry{
|
||||
set.cartHash,
|
||||
set.patchFile,
|
||||
set.notes,
|
||||
},
|
||||
nil
|
||||
set.cartHash,
|
||||
set.cartName,
|
||||
set.notes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CleanUp implements the database.Entry interface.
|
||||
|
@ -90,10 +84,10 @@ func (set Patch) matchCartHash(hash string) bool {
|
|||
}
|
||||
|
||||
// apply implements setupEntry interface.
|
||||
func (set Patch) apply(vcs *hardware.VCS) error {
|
||||
_, err := patch.CartridgeMemory(vcs.Mem.Cart, set.patchFile)
|
||||
func (set Patch) apply(vcs *hardware.VCS) (string, error) {
|
||||
_, err := patch.CartridgeMemory(vcs.Mem.Cart, set.cartHash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("patch: %w", err)
|
||||
return "", fmt.Errorf("patch: %w", err)
|
||||
}
|
||||
return nil
|
||||
return fmt.Sprintf("patching cartridge: %s: %s", set.cartName, set.notes), nil
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/cartridgeloader"
|
||||
"github.com/jetsetilly/gopher2600/database"
|
||||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
"github.com/jetsetilly/gopher2600/logger"
|
||||
"github.com/jetsetilly/gopher2600/resources"
|
||||
)
|
||||
|
||||
|
@ -39,23 +40,24 @@ type setupEntry interface {
|
|||
// match the hash stored in the database with the user supplied hash
|
||||
matchCartHash(hash string) bool
|
||||
|
||||
// apply changes indicated in the entry to the VCS
|
||||
apply(vcs *hardware.VCS) error
|
||||
// apply changes indicated in the entry to the VCS. returned string value
|
||||
// will be used for log message
|
||||
apply(vcs *hardware.VCS) (string, error)
|
||||
}
|
||||
|
||||
// when starting a database session we must add the details of the entry types
|
||||
// that will be found in the database.
|
||||
func initDBSession(db *database.Session) error {
|
||||
// add entry types
|
||||
if err := db.RegisterEntryType(panelSetupID, deserialisePanelSetupEntry); err != nil {
|
||||
if err := db.RegisterEntryType(panelSetupEntryType, deserialisePanelSetupEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.RegisterEntryType(patchID, deserialisePatchEntry); err != nil {
|
||||
if err := db.RegisterEntryType(patchEntryType, deserialisePatchEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.RegisterEntryType(televisionID, deserialiseTelevisionEntry); err != nil {
|
||||
if err := db.RegisterEntryType(televisionEntryType, deserialiseTelevisionEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -96,10 +98,11 @@ func AttachCartridge(vcs *hardware.VCS, cartload cartridgeloader.Loader, resetVC
|
|||
}
|
||||
|
||||
if set.matchCartHash(vcs.Mem.Cart.Hash) {
|
||||
err := set.apply(vcs)
|
||||
msg, err := set.apply(vcs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Logf("setup", msg)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -22,12 +22,12 @@ import (
|
|||
"github.com/jetsetilly/gopher2600/hardware"
|
||||
)
|
||||
|
||||
const televisionID = "tv"
|
||||
const televisionEntryType = "tv"
|
||||
|
||||
const (
|
||||
televisionFieldCartHash int = iota
|
||||
televisionFieldCartName
|
||||
televisionFieldSpec
|
||||
televisionFieldNotes
|
||||
numtelevisionFields
|
||||
)
|
||||
|
||||
|
@ -35,8 +35,8 @@ const (
|
|||
// attached/loaded.
|
||||
type television struct {
|
||||
cartHash string
|
||||
cartName string
|
||||
spec string
|
||||
notes string
|
||||
}
|
||||
|
||||
func deserialiseTelevisionEntry(fields database.SerialisedEntry) (database.Entry, error) {
|
||||
|
@ -51,28 +51,23 @@ func deserialiseTelevisionEntry(fields database.SerialisedEntry) (database.Entry
|
|||
}
|
||||
|
||||
set.cartHash = fields[televisionFieldCartHash]
|
||||
set.cartName = fields[televisionFieldCartName]
|
||||
set.spec = fields[televisionFieldSpec]
|
||||
set.notes = fields[televisionFieldNotes]
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// ID implements the database.Entry interface.
|
||||
func (set television) ID() string {
|
||||
return televisionID
|
||||
}
|
||||
|
||||
// String implements the database.Entry interface.
|
||||
func (set television) String() string {
|
||||
return fmt.Sprintf("%s, %s", set.cartHash, set.spec)
|
||||
// EntryType implements the database.Entry interface.
|
||||
func (set television) EntryType() string {
|
||||
return televisionEntryType
|
||||
}
|
||||
|
||||
// Serialise implements the database.Entry interface.
|
||||
func (set *television) Serialise() (database.SerialisedEntry, error) {
|
||||
return database.SerialisedEntry{
|
||||
set.cartHash,
|
||||
set.cartName,
|
||||
set.spec,
|
||||
set.notes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -88,7 +83,7 @@ func (set television) matchCartHash(hash string) bool {
|
|||
}
|
||||
|
||||
// apply implements setupEntry interface.
|
||||
func (set television) apply(vcs *hardware.VCS) error {
|
||||
func (set television) apply(vcs *hardware.VCS) (string, error) {
|
||||
// because the apply function is run after attaching the cartridge to the
|
||||
// VCS, any setup entries will take precedence over any spec in the
|
||||
// cartridge filename.
|
||||
|
@ -97,5 +92,10 @@ func (set television) apply(vcs *hardware.VCS) error {
|
|||
// original spec request is AUTO. In other words, a setup entry will not
|
||||
// take precedence over an explicit startup option.
|
||||
|
||||
return vcs.TV.SetSpecConditional(set.spec)
|
||||
err := vcs.TV.SetSpecConditional(set.spec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("forcing %s mode: %s", set.spec, set.cartName), nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue