periperhal event PaddleSet now takes a pair of float32 values

float32 pair defined as ports.EventDataPaddle

added functions to convert the float32 to and from a playback entry.
conversion from the playback entry tolerates a single float32 value
meaning that old recording files will work

rename plugging.PortLeftPlayer and plugging.PortRightPlayer to just
plugging.PortLeft and plugging.PortRight
This commit is contained in:
JetSetIlly 2023-02-26 21:54:35 +00:00
parent adabc65246
commit 11fb367ff5
19 changed files with 198 additions and 161 deletions

View file

@ -424,7 +424,7 @@ func (bot *videoChessBot) moveCursor(moveCol int, moveRow int, shortcut bool) {
}
for i := 0; i < move; i++ {
bot.moveCursorOnceStep(plugging.PortLeftPlayer, direction)
bot.moveCursorOnceStep(plugging.PortLeft, direction)
}
} else {
bot.feedback.Diagnostic <- bots.Diagnostic{
@ -449,21 +449,21 @@ func (bot *videoChessBot) moveCursor(moveCol int, moveRow int, shortcut bool) {
if moveCol > 0 {
for i := 0; i < moveCol; i++ {
bot.moveCursorOnceStep(plugging.PortLeftPlayer, ports.Left)
bot.moveCursorOnceStep(plugging.PortLeft, ports.Left)
}
} else if moveCol < 0 {
for i := 0; i > moveCol; i-- {
bot.moveCursorOnceStep(plugging.PortLeftPlayer, ports.Right)
bot.moveCursorOnceStep(plugging.PortLeft, ports.Right)
}
}
if moveRow > 0 {
for i := 0; i < moveRow; i++ {
bot.moveCursorOnceStep(plugging.PortLeftPlayer, ports.Down)
bot.moveCursorOnceStep(plugging.PortLeft, ports.Down)
}
} else if moveRow < 0 {
for i := 0; i > moveRow; i-- {
bot.moveCursorOnceStep(plugging.PortLeftPlayer, ports.Up)
bot.moveCursorOnceStep(plugging.PortLeft, ports.Up)
}
}
}
@ -484,9 +484,9 @@ func (bot *videoChessBot) moveCursor(moveCol int, moveRow int, shortcut bool) {
waiting := true
for waiting {
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: true})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: true})
bot.waitForFrames(downDuration)
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: false})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: false})
select {
case <-bot.obs.audioFeedback:
waiting = false

View file

@ -193,7 +193,7 @@ func (bot *spaceJockeyBot) movePlayerUpToY(y int) {
return
}
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Up, D: ports.DataStickTrue})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Up, D: ports.DataStickTrue})
for y < py && y < py+playerFuzz && py > playerLimitRect.Min.Y {
select {
case bot.image = <-bot.obs.analysis:
@ -206,11 +206,11 @@ func (bot *spaceJockeyBot) movePlayerUpToY(y int) {
return
}
}
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Up, D: ports.DataStickFalse})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Up, D: ports.DataStickFalse})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: true})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: true})
bot.waitForFrames(1)
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: false})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: false})
}
func (bot *spaceJockeyBot) movePlayerDownToY(y int) {
@ -219,7 +219,7 @@ func (bot *spaceJockeyBot) movePlayerDownToY(y int) {
return
}
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Down, D: ports.DataStickTrue})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Down, D: ports.DataStickTrue})
for y > py && y > py+playerFuzz && py < playerLimitRect.Max.Y {
select {
case bot.image = <-bot.obs.analysis:
@ -232,11 +232,11 @@ func (bot *spaceJockeyBot) movePlayerDownToY(y int) {
return
}
}
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Down, D: ports.DataStickFalse})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Down, D: ports.DataStickFalse})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: true})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: true})
bot.waitForFrames(1)
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: false})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: false})
}
type spaceJockeyBot struct {
@ -307,9 +307,9 @@ func NewSpaceJockey(vcs bots.Input, tv bots.TV, specID string) (bots.Bot, error)
if cmpSubImage(bot.image, startRect, startHash) {
select {
case <-time.After(2 * time.Second):
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: true})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: true})
bot.waitForFrames(10)
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.Fire, D: false})
bot.input.PushEvent(ports.InputEvent{Port: plugging.PortLeft, Ev: ports.Fire, D: false})
bot.feedback.Diagnostic <- bots.Diagnostic{
Group: bot.BotID(),

View file

@ -1623,9 +1623,9 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) error {
var id plugging.PortID
switch strings.ToUpper(player) {
case "LEFT":
id = plugging.PortLeftPlayer
id = plugging.PortLeft
case "RIGHT":
id = plugging.PortRightPlayer
id = plugging.PortRight
}
var err error
@ -1782,10 +1782,10 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) error {
switch port {
case "LEFT":
inp := ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: event, D: value}
inp := ports.InputEvent{Port: plugging.PortLeft, Ev: event, D: value}
_, err = dbg.vcs.Input.HandleInputEvent(inp)
case "RIGHT":
inp := ports.InputEvent{Port: plugging.PortRightPlayer, Ev: event, D: value}
inp := ports.InputEvent{Port: plugging.PortRight, Ev: event, D: value}
_, err = dbg.vcs.Input.HandleInputEvent(inp)
}
@ -1802,18 +1802,18 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) error {
switch port {
case "LEFT":
if strings.ToUpper(key) == "NONE" {
inp := ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.KeypadUp, D: nil}
inp := ports.InputEvent{Port: plugging.PortLeft, Ev: ports.KeypadUp, D: nil}
_, err = dbg.vcs.Input.HandleInputEvent(inp)
} else {
inp := ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.KeypadDown, D: rune(key[0])}
inp := ports.InputEvent{Port: plugging.PortLeft, Ev: ports.KeypadDown, D: rune(key[0])}
_, err = dbg.vcs.Input.HandleInputEvent(inp)
}
case "RIGHT":
if strings.ToUpper(key) == "NONE" {
inp := ports.InputEvent{Port: plugging.PortRightPlayer, Ev: ports.KeypadUp, D: nil}
inp := ports.InputEvent{Port: plugging.PortRight, Ev: ports.KeypadUp, D: nil}
_, err = dbg.vcs.Input.HandleInputEvent(inp)
} else {
inp := ports.InputEvent{Port: plugging.PortLeftPlayer, Ev: ports.KeypadDown, D: rune(key[0])}
inp := ports.InputEvent{Port: plugging.PortLeft, Ev: ports.KeypadDown, D: rune(key[0])}
_, err = dbg.vcs.Input.HandleInputEvent(inp)
}
}

View file

@ -47,7 +47,7 @@ func (pn *peripheralNotification) set(peripheral plugging.PeripheralID) {
switch peripheral {
case plugging.PeriphStick:
pn.icon = fmt.Sprintf("%c", fonts.Stick)
case plugging.PeriphPaddle:
case plugging.PeriphPaddles:
pn.icon = fmt.Sprintf("%c", fonts.Paddle)
case plugging.PeriphKeypad:
pn.icon = fmt.Sprintf("%c", fonts.Keypad)

View file

@ -83,9 +83,9 @@ func (img *SdlImgui) serviceSetFeature(request featureRequest) {
if err == nil {
port := request.args[0].(plugging.PortID)
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
img.playScr.peripheralLeft.set(request.args[1].(plugging.PeripheralID))
case plugging.PortRightPlayer:
case plugging.PortRight:
img.playScr.peripheralRight.set(request.args[1].(plugging.PeripheralID))
}
}

View file

@ -206,7 +206,7 @@ func (img *SdlImgui) Service() {
if button != userinput.GamepadButtonNone {
select {
case img.userinput <- userinput.EventGamepadButton{
ID: plugging.PortLeftPlayer,
ID: plugging.PortLeft,
Button: button,
Down: ev.State == 1,
}:
@ -243,7 +243,7 @@ func (img *SdlImgui) Service() {
if dir != userinput.DPadNone {
select {
case img.userinput <- userinput.EventGamepadDPad{
ID: plugging.PortLeftPlayer,
ID: plugging.PortLeft,
Direction: dir,
}:
default:
@ -256,7 +256,7 @@ func (img *SdlImgui) Service() {
joy := sdl.JoystickFromInstanceID(ev.Which)
select {
case img.userinput <- userinput.EventStelladaptor{
ID: plugging.PortLeftPlayer,
ID: plugging.PortLeft,
Horiz: joy.Axis(0),
Vert: joy.Axis(1),
}:
@ -278,7 +278,7 @@ func (img *SdlImgui) Service() {
case 1:
select {
case img.userinput <- userinput.EventGamepadThumbstick{
ID: plugging.PortLeftPlayer,
ID: plugging.PortLeft,
Thumbstick: userinput.GamepadThumbstickLeft,
Horiz: pad.Axis(0),
Vert: pad.Axis(1),
@ -291,7 +291,7 @@ func (img *SdlImgui) Service() {
case 4:
select {
case img.userinput <- userinput.EventGamepadThumbstick{
ID: plugging.PortLeftPlayer,
ID: plugging.PortLeft,
Thumbstick: userinput.GamepadThumbstickRight,
Horiz: pad.Axis(3),
Vert: pad.Axis(4),
@ -313,7 +313,7 @@ func (img *SdlImgui) Service() {
if trigger != userinput.GamepadTriggerNone {
select {
case img.userinput <- userinput.EventGamepadTrigger{
ID: plugging.PortLeftPlayer,
ID: plugging.PortLeft,
Trigger: trigger,
Amount: ev.Value,
}:

View file

@ -93,7 +93,7 @@ func NewAtariVox(inst *instance.Instance, port plugging.PortID, bus ports.Periph
//
// moreover ROM developers understand that the atarivox is to be plugged
// into the right player port and don't support left player port
if port != plugging.PortRightPlayer {
if port != plugging.PortRight {
return nil
}
@ -216,9 +216,9 @@ func (vox *AtariVox) Update(data chipbus.ChangedRegister) bool {
case cpubus.SWCHA:
// mask and shift SWCHA value to the normlised value
switch vox.port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
vox.swcha = data.Value & 0xf0
case plugging.PortRightPlayer:
case plugging.PortRight:
vox.swcha = (data.Value & 0x0f) << 4
}

View file

@ -73,11 +73,11 @@ func NewGamepad(instance *instance.Instance, port plugging.PortID, bus ports.Per
}
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
pad.buttonInptx = chipbus.INPT4
pad.secondInptx = chipbus.INPT1
pad.insertedInptx = chipbus.INPT0
case plugging.PortRightPlayer:
case plugging.PortRight:
pad.buttonInptx = chipbus.INPT5
pad.secondInptx = chipbus.INPT3
pad.insertedInptx = chipbus.INPT2

View file

@ -47,9 +47,9 @@ func NewKeypad(instance *instance.Instance, port plugging.PortID, bus ports.Peri
}
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
key.column = [3]chipbus.Register{chipbus.INPT0, chipbus.INPT1, chipbus.INPT4}
case plugging.PortRightPlayer:
case plugging.PortRight:
key.column = [3]chipbus.Register{chipbus.INPT2, chipbus.INPT3, chipbus.INPT5}
}
@ -149,9 +149,9 @@ func (key *Keypad) Update(data chipbus.ChangedRegister) bool {
var v uint8
switch key.port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
v = data.Value & 0xf0
case plugging.PortRightPlayer:
case plugging.PortRight:
v = (data.Value & 0x0f) << 4
}

View file

@ -72,10 +72,10 @@ func NewPaddle(instance *instance.Instance, port plugging.PortID, bus ports.Peri
// !!TODO: support for paddle player 3 and paddle player 4
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
pdl.inptx = chipbus.INPT0
pdl.buttonMask = 0x80
case plugging.PortRightPlayer:
case plugging.PortRight:
pdl.inptx = chipbus.INPT1
pdl.buttonMask = 0x40
}
@ -112,7 +112,7 @@ func (pdl *Paddle) PortID() plugging.PortID {
// ID implements the ports.Peripheral interface.
func (pdl *Paddle) ID() plugging.PeripheralID {
return plugging.PeriphPaddle
return plugging.PeriphPaddles
}
// HandleEvent implements the ports.Peripheral interface.
@ -149,14 +149,13 @@ func (pdl *Paddle) HandleEvent(event ports.Event, data ports.EventData) (bool, e
var r float32
switch d := data.(type) {
case float32:
r = d
case ports.EventDataPaddle:
// TODO: support vert paddle
r = d[0]
case ports.EventDataPlayback:
f, err := strconv.ParseFloat(string(d), 32)
if err != nil {
return false, fmt.Errorf("paddle: %v: unexpected event data", event)
}
r = float32(f)
var vals ports.EventDataPaddle
vals.FromString(string(d))
r = vals[0]
default:
return false, fmt.Errorf("paddle: %v: unexpected event data", event)
}

View file

@ -60,9 +60,9 @@ func NewStick(instance *instance.Instance, port plugging.PortID, bus ports.Perip
}
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
stk.buttonInptx = chipbus.INPT4
case plugging.PortRightPlayer:
case plugging.PortRight:
stk.buttonInptx = chipbus.INPT5
}

View file

@ -43,7 +43,7 @@ func Fingerprint(port plugging.PortID, data *[]byte) ports.NewPeripheral {
return controllers.NewStick
}
if port != plugging.PortRightPlayer && port != plugging.PortLeftPlayer {
if port != plugging.PortRight && port != plugging.PortLeft {
panic(fmt.Sprintf("cannot fingerprint for port %v", port))
}
@ -98,7 +98,7 @@ func matchPattern(patterns [][]byte, data []byte) bool {
}
func fingerprintSaveKey(port plugging.PortID, data []byte) bool {
if port != plugging.PortRightPlayer {
if port != plugging.PortRight {
return false
}
@ -134,7 +134,7 @@ func fingerprintSaveKey(port plugging.PortID, data []byte) bool {
}
func fingerprintAtariVox(port plugging.PortID, data []byte) bool {
if port != plugging.PortRightPlayer {
if port != plugging.PortRight {
return false
}
@ -164,7 +164,7 @@ func fingerprintStick(port plugging.PortID, data []byte) bool {
var patterns [][]byte
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
patterns = [][]byte{
{0x24, 0x0c, 0x10}, // bit INPT4; bpl (joystick games only)
{0x24, 0x0c, 0x30}, // bit INPT4; bmi (joystick games only)
@ -209,7 +209,7 @@ func fingerprintStick(port plugging.PortID, data []byte) bool {
{0xa5, 0x3c, 0x29, 0x80, 0xd0}, // lda INPT4|$30; and #$80; bne (joystick games only)
{0xad, 0x0c, 0x00, 0x29, 0x80}, // lda.w INPT4|$30; and #$80 (joystick games only)
}
case plugging.PortRightPlayer:
case plugging.PortRight:
patterns = [][]byte{
{0x24, 0x0d, 0x10}, // bit INPT5; bpl (joystick games only)
{0x24, 0x0d, 0x30}, // bit INPT5; bmi (joystick games only)
@ -247,7 +247,7 @@ func fingerprintKeypad(port plugging.PortID, data []byte) bool {
var patterns [][]byte
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
patterns = [][]byte{
{0x24, 0x38, 0x30}, // bit INPT0|$30; bmi
{0xa5, 0x38, 0x10}, // lda INPT0|$30; bpl
@ -275,7 +275,7 @@ func fingerprintKeypad(port plugging.PortID, data []byte) bool {
return matchPattern(patterns, data)
}
case plugging.PortRightPlayer:
case plugging.PortRight:
patterns = [][]byte{
{0x24, 0x3a, 0x30}, // bit INPT2|$30; bmi
{0xa5, 0x3a, 0x10}, // lda INPT2|$30; bpl
@ -308,7 +308,7 @@ func fingerprintGamepad(port plugging.PortID, data []byte) bool {
var patterns [][]byte
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
patterns = [][]byte{
{0x24, 0x09, 0x10}, // bit INPT1; bpl (Genesis only)
{0x24, 0x09, 0x30}, // bit INPT1; bmi (paddle ROMS too)
@ -330,7 +330,7 @@ func fingerprintGamepad(port plugging.PortID, data []byte) bool {
{0x25, 0x39, 0x30}, // and INPT1|$30; bmi (Genesis only)
{0x25, 0x09, 0x10}, // and INPT1; bpl (Genesis only)
}
case plugging.PortRightPlayer:
case plugging.PortRight:
patterns = [][]byte{
{0x24, 0x0b, 0x10}, // bit INPT3; bpl
{0x24, 0x0b, 0x30}, // bit INPT3; bmi
@ -352,7 +352,7 @@ func fingerprintPaddle(port plugging.PortID, data []byte) bool {
var patterns [][]byte
switch port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
patterns = [][]byte{
//{ 0x24, 0x08, 0x10 }, // bit INPT0; bpl (many joystick games too!)
//{ 0x24, 0x08, 0x30 }, // bit INPT0; bmi (joystick games: Spike's Peak, Sweat, Turbo!)
@ -378,7 +378,7 @@ func fingerprintPaddle(port plugging.PortID, data []byte) bool {
{0xb5, 0x38, 0x49, 0xff, 0x0a}, // lda INPT0|$30,x; eor #$ff; asl (Blackjack)
{0xb1, 0xf2, 0x30, 0x02, 0xe6}, // lda ($f2),y; bmi...; inc (Warplock)
}
case plugging.PortRightPlayer:
case plugging.PortRight:
patterns = [][]byte{
{0x24, 0x0a, 0x10}, // bit INPT2; bpl (no joystick games)
{0x24, 0x0a, 0x30}, // bit INPT2; bmi (no joystick games)

View file

@ -91,7 +91,7 @@ func NewSaveKey(instance *instance.Instance, port plugging.PortID, bus ports.Per
//
// moreover ROM developers understand that the savekey is to be
// plugged into the right player port and don't support left player port
if port != plugging.PortRightPlayer {
if port != plugging.PortRight {
return nil
}
@ -187,9 +187,9 @@ func (sk *SaveKey) Update(data chipbus.ChangedRegister) bool {
case cpubus.SWCHA:
// mask and shift SWCHA value to the normlised value
switch sk.port {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
sk.swcha = data.Value & 0xf0
case plugging.PortRightPlayer:
case plugging.PortRight:
sk.swcha = (data.Value & 0x0f) << 4
}

View file

@ -17,6 +17,9 @@ package ports
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/jetsetilly/gopher2600/hardware/riot/ports/plugging"
"github.com/jetsetilly/gopher2600/hardware/television/coords"
@ -33,11 +36,14 @@ type Event string
const (
NoEvent Event = "NoEvent" // nil
// fire will be interpreted by both stick and paddle depending on which
// controller is attached.
// fire is the standard fire button present on all controller types
Fire Event = "Fire" // bool
// joystick.
// second button is treated as the paired paddle fire button as well as the
// B button on a game pad
SecondFire Event = "SecondFire" // bool
// joystick
Centre Event = "Centre" // nil
Up Event = "Up" // EventDataStick
Down Event = "Down" // EventDataStick
@ -48,17 +54,14 @@ const (
RightUp Event = "RightUp" // EventDataStick
RightDown Event = "RightDown" // EventDataStick
// gamepad second button
SecondFire Event = "SecondFire" // bool
// paddles
PaddleSet Event = "PaddleSet" // EventDataPaddle
// paddles.
PaddleSet Event = "PaddleSet" // float32
// keyboard.
// keyboard
KeypadDown Event = "KeypadDown" // rune
KeypadUp Event = "KeypadUp" // nil
// panel.
// panel
PanelSelect Event = "PanelSelect" // bool
PanelReset Event = "PanelReset" // bool
@ -88,6 +91,34 @@ type EventDataPlayback string
// Event data for stick types.
type EventDataStick string
// Event data for paddle types. first entry is for primary paddle for the part
// (ie. INP0 or INP2) and the second entry is for the secondary paddle (ie.
// INP1 or INP3)
type EventDataPaddle [2]float32
// String implements the string.Stringer interface and is intended to be used
// when writing to a playback file
func (ev EventDataPaddle) String() string {
return fmt.Sprintf("%f;%f", ev[0], ev[1])
}
// FromString is the inverse of the String() function
func (ev *EventDataPaddle) FromString(s string) error {
// splitting up to two strings. if there's only string in the split then
// that's okay and it only means that the EventDataPaddle was written by an
// early version of the emulator
sp := strings.SplitN(s, ";", 2)
for i := range sp {
f, err := strconv.ParseFloat(sp[i], 32)
if err != nil {
return err
}
ev[i] = float32(f)
}
return nil
}
// List of valid values for EventDataStick.
//
// A note on the values. DataStickTrue will set the bits associated with the

View file

@ -19,14 +19,22 @@ package plugging
// can be plugged.
type PortID string
// List of defined PortIDs.
// List of defined PortIDs. These refer to the physical ports at the back of
// the console. In the case of paired paddles, two paddles use a single player
// port so thinking of these ports as left and right "players" might be
// misleading. So long as restrict our thinking to left and right "ports" we're
// okay.
//
// We could potentially extend this to support a future Quadtari implementation.
// Also, "left" and "right" are from the point of view of somebody using the
// console normally (ie. the ports are at the back of the console)
//
// Similarly, in the case of devices like the Quadtari, many players can be
// plugged into a single port
const (
PortUnplugged PortID = "Unplugged"
PortLeftPlayer PortID = "Left"
PortRightPlayer PortID = "Right"
PortPanel PortID = "Panel"
PortUnplugged PortID = "Unplugged"
PortLeft PortID = "Left"
PortRight PortID = "Right"
PortPanel PortID = "Panel"
)
// PeripheralID identifies the class of device a Peripheral implemenation
@ -39,7 +47,7 @@ const (
PeriphPanel PeripheralID = "Panel"
PeriphStick PeripheralID = "Stick"
PeriphGamepad PeripheralID = "Gamepad"
PeriphPaddle PeripheralID = "Paddle"
PeriphPaddles PeripheralID = "Paddles"
PeriphKeypad PeripheralID = "Keypad"
PeriphSavekey PeripheralID = "Savekey"
PeriphAtariVox PeripheralID = "AtariVox"

View file

@ -148,12 +148,12 @@ func (p *Ports) Plug(port plugging.PortID, c NewPeripheral) error {
p.Panel.Unplug()
}
p.Panel = periph
case plugging.PortLeftPlayer:
case plugging.PortLeft:
if p.LeftPlayer != nil {
p.LeftPlayer.Unplug()
}
p.LeftPlayer = periph
case plugging.PortRightPlayer:
case plugging.PortRight:
if p.RightPlayer != nil {
p.RightPlayer.Unplug()
}
@ -343,8 +343,8 @@ func (p *Ports) AttachPlugMonitor(m plugging.PlugMonitor) {
// notify monitor of currently plugged peripherals
if p.monitor != nil {
p.monitor.Plugged(plugging.PortLeftPlayer, p.LeftPlayer.ID())
p.monitor.Plugged(plugging.PortRightPlayer, p.RightPlayer.ID())
p.monitor.Plugged(plugging.PortLeft, p.LeftPlayer.ID())
p.monitor.Plugged(plugging.PortRight, p.RightPlayer.ID())
}
}
@ -353,9 +353,9 @@ func (p *Ports) PeripheralID(id plugging.PortID) plugging.PeripheralID {
switch id {
case plugging.PortPanel:
return p.Panel.ID()
case plugging.PortLeftPlayer:
case plugging.PortLeft:
return p.LeftPlayer.ID()
case plugging.PortRightPlayer:
case plugging.PortRight:
return p.RightPlayer.ID()
}
@ -365,12 +365,12 @@ func (p *Ports) PeripheralID(id plugging.PortID) plugging.PeripheralID {
// WriteSWCHx implements the peripheral.PeripheralBus interface.
func (p *Ports) WriteSWCHx(id plugging.PortID, data uint8) {
switch id {
case plugging.PortLeftPlayer:
case plugging.PortLeft:
data &= 0xf0 // keep only the bits for player 0
data |= p.swcha_mux & 0x0f // combine with the existing player 1 bits
p.swcha_mux = data
p.riot.ChipWrite(chipbus.SWCHA, p.deriveSWCHA())
case plugging.PortRightPlayer:
case plugging.PortRight:
data = (data & 0xf0) >> 4 // move bits into the player 1 nibble
data |= p.swcha_mux & 0xf0 // combine with the existing player 0 bits
p.swcha_mux = data
@ -407,9 +407,9 @@ func (p *Ports) HandleInputEvent(inp InputEvent) (bool, error) {
switch inp.Port {
case plugging.PortPanel:
handled, err = p.Panel.HandleEvent(inp.Ev, inp.D)
case plugging.PortLeftPlayer:
case plugging.PortLeft:
handled, err = p.LeftPlayer.HandleEvent(inp.Ev, inp.D)
case plugging.PortRightPlayer:
case plugging.PortRight:
handled, err = p.RightPlayer.HandleEvent(inp.Ev, inp.D)
}

View file

@ -107,12 +107,12 @@ func NewVCS(tv *television.Television, prefs *preferences.Preferences) (*VCS, er
return nil, err
}
err = vcs.RIOT.Ports.Plug(plugging.PortLeftPlayer, controllers.NewStick)
err = vcs.RIOT.Ports.Plug(plugging.PortLeft, controllers.NewStick)
if err != nil {
return nil, err
}
err = vcs.RIOT.Ports.Plug(plugging.PortRightPlayer, controllers.NewStick)
err = vcs.RIOT.Ports.Plug(plugging.PortRight, controllers.NewStick)
if err != nil {
return nil, err
}
@ -175,11 +175,11 @@ func (vcs *VCS) AttachCartridge(cartload cartridgeloader.Loader, reset bool) err
}
// fingerprint new peripherals. peripherals are not changed if option is not set
err = vcs.FingerprintPeripheral(plugging.PortLeftPlayer, cartload)
err = vcs.FingerprintPeripheral(plugging.PortLeft, cartload)
if err != nil {
return err
}
err = vcs.FingerprintPeripheral(plugging.PortRightPlayer, cartload)
err = vcs.FingerprintPeripheral(plugging.PortRight, cartload)
if err != nil {
return err
}

View file

@ -132,9 +132,9 @@ func NewPlayback(transcript string, checkROM bool) (*Playback, error) {
case -1:
entry.event.Port = plugging.PortUnplugged
case 1:
entry.event.Port = plugging.PortLeftPlayer
entry.event.Port = plugging.PortLeft
case 2:
entry.event.Port = plugging.PortRightPlayer
entry.event.Port = plugging.PortRight
case 3:
entry.event.Port = plugging.PortPanel
default:

View file

@ -54,16 +54,16 @@ func (c *Controllers) handleEvents(id plugging.PortID, ev ports.Event, d ports.E
}
func (c *Controllers) mouseMotion(ev EventMouseMotion) (bool, error) {
return c.handleEvents(plugging.PortLeftPlayer, ports.PaddleSet, ev.X)
return c.handleEvents(plugging.PortLeft, ports.PaddleSet, ports.EventDataPaddle{ev.X})
}
func (c *Controllers) mouseButton(ev EventMouseButton) (bool, error) {
switch ev.Button {
case MouseButtonLeft:
if ev.Down {
return c.handleEvents(plugging.PortLeftPlayer, ports.Fire, true)
return c.handleEvents(plugging.PortLeft, ports.Fire, true)
} else {
return c.handleEvents(plugging.PortLeftPlayer, ports.Fire, false)
return c.handleEvents(plugging.PortLeft, ports.Fire, false)
}
}
@ -102,62 +102,62 @@ func (c *Controllers) differentiateKeyboard(key string, down bool) (bool, error)
switch key {
case "Y":
if c.inputHandler.PeripheralID(plugging.PortRightPlayer) == plugging.PeriphKeypad {
portID = plugging.PortRightPlayer
if c.inputHandler.PeripheralID(plugging.PortRight) == plugging.PeriphKeypad {
portID = plugging.PortRight
ev = keyEv
d = '6'
} else {
portID = plugging.PortRightPlayer
portID = plugging.PortRight
ev = ports.Up
d = stickEvData
}
case "F":
if c.inputHandler.PeripheralID(plugging.PortRightPlayer) == plugging.PeriphKeypad {
portID = plugging.PortRightPlayer
if c.inputHandler.PeripheralID(plugging.PortRight) == plugging.PeriphKeypad {
portID = plugging.PortRight
ev = keyEv
d = '7'
} else {
portID = plugging.PortRightPlayer
portID = plugging.PortRight
ev = ports.Fire
d = fireEvData
}
case "G":
if c.inputHandler.PeripheralID(plugging.PortRightPlayer) == plugging.PeriphKeypad {
portID = plugging.PortRightPlayer
if c.inputHandler.PeripheralID(plugging.PortRight) == plugging.PeriphKeypad {
portID = plugging.PortRight
ev = keyEv
d = '8'
} else {
portID = plugging.PortRightPlayer
portID = plugging.PortRight
ev = ports.Left
d = stickEvData
}
case "H":
if c.inputHandler.PeripheralID(plugging.PortRightPlayer) == plugging.PeriphKeypad {
portID = plugging.PortRightPlayer
if c.inputHandler.PeripheralID(plugging.PortRight) == plugging.PeriphKeypad {
portID = plugging.PortRight
ev = keyEv
d = '9'
} else {
portID = plugging.PortRightPlayer
portID = plugging.PortRight
ev = ports.Down
d = stickEvData
}
case "B":
if c.inputHandler.PeripheralID(plugging.PortRightPlayer) == plugging.PeriphKeypad {
portID = plugging.PortRightPlayer
if c.inputHandler.PeripheralID(plugging.PortRight) == plugging.PeriphKeypad {
portID = plugging.PortRight
ev = keyEv
d = '0'
} else {
portID = plugging.PortLeftPlayer
portID = plugging.PortLeft
ev = ports.SecondFire
d = fireEvData
}
case "6":
if c.inputHandler.PeripheralID(plugging.PortRightPlayer) == plugging.PeriphKeypad {
portID = plugging.PortRightPlayer
if c.inputHandler.PeripheralID(plugging.PortRight) == plugging.PeriphKeypad {
portID = plugging.PortRight
ev = keyEv
d = '6'
} else {
portID = plugging.PortRightPlayer
portID = plugging.PortRight
ev = ports.SecondFire
d = fireEvData
}
@ -191,57 +191,57 @@ func (c *Controllers) keyboard(ev EventKeyboard) (bool, error) {
// joystick (left player)
case "Left":
return c.handleEvents(plugging.PortLeftPlayer, ports.Left, ports.DataStickTrue)
return c.handleEvents(plugging.PortLeft, ports.Left, ports.DataStickTrue)
case "Right":
return c.handleEvents(plugging.PortLeftPlayer, ports.Right, ports.DataStickTrue)
return c.handleEvents(plugging.PortLeft, ports.Right, ports.DataStickTrue)
case "Up":
return c.handleEvents(plugging.PortLeftPlayer, ports.Up, ports.DataStickTrue)
return c.handleEvents(plugging.PortLeft, ports.Up, ports.DataStickTrue)
case "Down":
return c.handleEvents(plugging.PortLeftPlayer, ports.Down, ports.DataStickTrue)
return c.handleEvents(plugging.PortLeft, ports.Down, ports.DataStickTrue)
case "Space":
return c.handleEvents(plugging.PortLeftPlayer, ports.Fire, true)
return c.handleEvents(plugging.PortLeft, ports.Fire, true)
// joystick (right player)
// * keypad and joystick share some keys (see below for other inputs)
case "J":
return c.handleEvents(plugging.PortRightPlayer, ports.Right, ports.DataStickTrue)
return c.handleEvents(plugging.PortRight, ports.Right, ports.DataStickTrue)
// keypad (left player)
case "1", "2", "3":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, rune(ev.Key[0]))
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, rune(ev.Key[0]))
case "Q":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '4')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '4')
case "W":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '5')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '5')
case "E":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '6')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '6')
case "A":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '7')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '7')
case "S":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '8')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '8')
case "D":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '9')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '9')
case "Z":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '*')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '*')
case "X":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '0')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '0')
case "C":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadDown, '#')
return c.handleEvents(plugging.PortLeft, ports.KeypadDown, '#')
// keypad (right player)
// * keypad and joystick share some keys (see below for other inputs)
case "4":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadDown, '1')
return c.handleEvents(plugging.PortRight, ports.KeypadDown, '1')
case "5":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadDown, '2')
return c.handleEvents(plugging.PortRight, ports.KeypadDown, '2')
case "R":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadDown, '4')
return c.handleEvents(plugging.PortRight, ports.KeypadDown, '4')
case "T":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadDown, '5')
return c.handleEvents(plugging.PortRight, ports.KeypadDown, '5')
case "V":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadDown, '*')
return c.handleEvents(plugging.PortRight, ports.KeypadDown, '*')
case "N":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadDown, '#')
return c.handleEvents(plugging.PortRight, ports.KeypadDown, '#')
default:
// keypad (right player) *OR* joystick (right player)
@ -258,29 +258,29 @@ func (c *Controllers) keyboard(ev EventKeyboard) (bool, error) {
// josytick (left player)
case "Left":
return c.handleEvents(plugging.PortLeftPlayer, ports.Left, ports.DataStickFalse)
return c.handleEvents(plugging.PortLeft, ports.Left, ports.DataStickFalse)
case "Right":
return c.handleEvents(plugging.PortLeftPlayer, ports.Right, ports.DataStickFalse)
return c.handleEvents(plugging.PortLeft, ports.Right, ports.DataStickFalse)
case "Up":
return c.handleEvents(plugging.PortLeftPlayer, ports.Up, ports.DataStickFalse)
return c.handleEvents(plugging.PortLeft, ports.Up, ports.DataStickFalse)
case "Down":
return c.handleEvents(plugging.PortLeftPlayer, ports.Down, ports.DataStickFalse)
return c.handleEvents(plugging.PortLeft, ports.Down, ports.DataStickFalse)
case "Space":
return c.handleEvents(plugging.PortLeftPlayer, ports.Fire, false)
return c.handleEvents(plugging.PortLeft, ports.Fire, false)
// joystick (right player)
// * keypad and joystick share some keys (see below for other inputs)
case "J":
return c.handleEvents(plugging.PortRightPlayer, ports.Right, ports.DataStickFalse)
return c.handleEvents(plugging.PortRight, ports.Right, ports.DataStickFalse)
// keyboard (left player)
case "1", "2", "3", "Q", "W", "E", "A", "S", "D", "Z", "X", "C":
return c.handleEvents(plugging.PortLeftPlayer, ports.KeypadUp, nil)
return c.handleEvents(plugging.PortLeft, ports.KeypadUp, nil)
// keyboard (right player)
// * keypad and joystick share some keys (see below for other inputs)
case "4", "5", "R", "T", "V", "N":
return c.handleEvents(plugging.PortRightPlayer, ports.KeypadUp, nil)
return c.handleEvents(plugging.PortRight, ports.KeypadUp, nil)
default:
// keypad (right player) *OR* joystick (right player)
@ -288,8 +288,6 @@ func (c *Controllers) keyboard(ev EventKeyboard) (bool, error) {
return c.differentiateKeyboard(ev.Key, false)
}
}
return false, nil
}
func (c *Controllers) gamepadDPad(ev EventGamepadDPad) (bool, error) {
@ -419,12 +417,11 @@ func (c *Controllers) gamepadTriggers(ev EventGamepadTrigger) (bool, error) {
}
c.triggerPaddle = n
return c.handleEvents(ev.ID, ports.PaddleSet, c.triggerPaddle)
return c.handleEvents(ev.ID, ports.PaddleSet, ports.EventDataPaddle{c.triggerPaddle})
}
func (c *Controllers) stelladaptor(ev EventStelladaptor) (bool, error) {
switch c.inputHandler.PeripheralID(plugging.PortLeftPlayer) {
switch c.inputHandler.PeripheralID(ev.ID) {
case plugging.PeriphStick:
// boundary value is compared again incoming axes values
//
@ -461,9 +458,11 @@ func (c *Controllers) stelladaptor(ev EventStelladaptor) (bool, error) {
return c.handleEvents(ev.ID, ports.Centre, nil)
case plugging.PeriphPaddle:
paddle := float32(int32(ev.Horiz)+32768) / 65535
return c.handleEvents(ev.ID, ports.PaddleSet, paddle)
case plugging.PeriphPaddles:
return c.handleEvents(ev.ID, ports.PaddleSet, ports.EventDataPaddle{
float32(int32(ev.Horiz)+32768) / 65535,
float32(int32(ev.Vert)+32768) / 65535,
})
}
return false, nil