mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
o controller
- added basic controller support - uses third-party package: - github.com/splace/joysticks
This commit is contained in:
parent
1a59db31d1
commit
6957a52adc
7 changed files with 97 additions and 17 deletions
|
@ -65,7 +65,7 @@ func NewDebugger() (*Debugger, error) {
|
|||
}
|
||||
|
||||
// prepare hardware
|
||||
tv, err := television.NewSDLTV("NTSC", 3.0)
|
||||
tv, err := television.NewSDLTV("NTSC", television.IdealScale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -4,26 +4,41 @@ import "fmt"
|
|||
|
||||
// list of sub-systems used when defining errors
|
||||
const (
|
||||
CategoryDebugger = 0
|
||||
CategoryVCS = 64
|
||||
CategoryCPU = 128
|
||||
CategoryMemory = 192
|
||||
CategoryTIA = 256
|
||||
CategoryRIOT = 320
|
||||
CategoryTV = 384
|
||||
CategoryDebugger = 0
|
||||
CategoryVCS = 64
|
||||
CategoryCPU = 128
|
||||
CategoryMemory = 192
|
||||
CategoryTIA = 256
|
||||
CategoryRIOT = 320
|
||||
CategoryTV = 384
|
||||
CategoryController = 448
|
||||
)
|
||||
|
||||
// list of error numbers
|
||||
const (
|
||||
// Debugger
|
||||
NoSymbolsFile = CategoryDebugger + iota
|
||||
SymbolsFileError
|
||||
|
||||
// VCS
|
||||
|
||||
// CPU
|
||||
UnimplementedInstruction = CategoryCPU + iota
|
||||
NullInstruction
|
||||
|
||||
// Memory
|
||||
UnservicedChipWrite = CategoryMemory + iota
|
||||
UnknownRegisterName
|
||||
UnreadableAddress
|
||||
|
||||
// TIA
|
||||
|
||||
// RIOT
|
||||
|
||||
// TV
|
||||
|
||||
// Controller
|
||||
NoControllersFound = CategoryController + iota
|
||||
)
|
||||
|
||||
var messages = map[int]string{
|
||||
|
@ -47,6 +62,9 @@ var messages = map[int]string{
|
|||
// RIOT
|
||||
|
||||
// TV
|
||||
|
||||
// Controller
|
||||
NoControllersFound: "no controllers found",
|
||||
}
|
||||
|
||||
// Values is the type used to specify arguments for a GopherError
|
||||
|
@ -64,6 +82,9 @@ func (er GopherError) Error() string {
|
|||
|
||||
// Category returns the broad categorisation of a GopherError
|
||||
func (er GopherError) Category() int {
|
||||
if er.Errno >= CategoryController {
|
||||
return CategoryController
|
||||
}
|
||||
if er.Errno >= CategoryTV {
|
||||
return CategoryTV
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ func fps(cartridgeFile string, justTheVCS bool) error {
|
|||
return fmt.Errorf("error creating television for fps profiler")
|
||||
}
|
||||
} else {
|
||||
tv, err = television.NewSDLTV("NTSC", 3.0)
|
||||
tv, err = television.NewSDLTV("NTSC", television.IdealScale)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating television for fps profiler")
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ func run(cartridgeFile string) error {
|
|||
var tv television.Television
|
||||
var err error
|
||||
|
||||
tv, err = television.NewSDLTV("NTSC", 3.0)
|
||||
tv, err = television.NewSDLTV("NTSC", television.IdealScale)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating television for fps profiler")
|
||||
}
|
||||
|
|
52
hardware/controller/controller.go
Normal file
52
hardware/controller/controller.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware/memory"
|
||||
|
||||
"github.com/splace/joysticks"
|
||||
)
|
||||
|
||||
// Stick emulaes the digital VCS joystick
|
||||
type Stick struct {
|
||||
device *joysticks.HID
|
||||
err error
|
||||
}
|
||||
|
||||
// NewStick is the preferred method of initialisation for the Stick type
|
||||
func NewStick(tia *memory.ChipMemory) *Stick {
|
||||
stick := new(Stick)
|
||||
|
||||
// there is a flaw (either in splace/joysticks or somewehere else lower
|
||||
// down in the kernel driver) which means that Connect() will not return
|
||||
// until it recieves some input from the controller. to get around this,
|
||||
// we've put the main body of the NewStick() function in a go routine.
|
||||
go func() {
|
||||
// try connecting to specific controller.
|
||||
// system assigned index: typically increments on each new controller added.
|
||||
stick.device = joysticks.Connect(1)
|
||||
if stick.device == nil {
|
||||
stick.err = errors.GopherError{errors.NoControllersFound, nil}
|
||||
return
|
||||
}
|
||||
|
||||
// get/assign channels for specific events
|
||||
buttonPress := stick.device.OnClose(1)
|
||||
buttonRelease := stick.device.OnOpen(1)
|
||||
|
||||
// start feeding OS events onto the event channels.
|
||||
go stick.device.ParcelOutEvents()
|
||||
|
||||
// handle event channels
|
||||
for {
|
||||
select {
|
||||
case <-buttonPress:
|
||||
tia.ChipWrite("INPT4", 0x00)
|
||||
case <-buttonRelease:
|
||||
tia.ChipWrite("INPT4", 0x80)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return stick
|
||||
}
|
|
@ -145,5 +145,5 @@ func (ms *missileSprite) scheduleReset(hblank *bool) {
|
|||
}
|
||||
|
||||
func (ms *missileSprite) scheduleEnable(value uint8) {
|
||||
ms.futureEnable.schedule(delayEnableSprite, value&0x20 == 0x20)
|
||||
ms.futureEnable.schedule(delayEnableSprite, value&0x02 == 0x02)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package hardware
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/hardware/controller"
|
||||
"gopher2600/hardware/cpu"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/hardware/riot"
|
||||
|
@ -25,6 +26,8 @@ type VCS struct {
|
|||
|
||||
// tv is not part of the VCS but is attached to it
|
||||
TV television.Television
|
||||
|
||||
controller *controller.Stick
|
||||
}
|
||||
|
||||
// New is the preferred method of initialisation for the VCS structure
|
||||
|
@ -54,6 +57,13 @@ func New(tv television.Television) (*VCS, error) {
|
|||
return nil, fmt.Errorf("can't allocate memory for VCS RIOT")
|
||||
}
|
||||
|
||||
// TODO: better contoller support
|
||||
vcs.controller = controller.NewStick(vcs.Mem.TIA)
|
||||
|
||||
// TODO: console switch support
|
||||
// - set colour switch bit
|
||||
vcs.Mem.RIOT.ChipWrite("SWCHB", 0x08)
|
||||
|
||||
return vcs, nil
|
||||
}
|
||||
|
||||
|
@ -115,12 +125,6 @@ func (vcs *VCS) Step(videoCycleCallback func(*cpu.InstructionResult) error) (int
|
|||
videoCycleCallback(r)
|
||||
}
|
||||
|
||||
// TODO: full controller support -- this is emulating the rest state for the
|
||||
// two joystick controllers
|
||||
vcs.Mem.TIA.ChipWrite("INPT4", 0x80)
|
||||
vcs.Mem.TIA.ChipWrite("INPT5", 0x80)
|
||||
vcs.Mem.RIOT.ChipWrite("SWCHA", 0xFF)
|
||||
|
||||
r, err = vcs.MC.ExecuteInstruction(cycleVCS)
|
||||
if err != nil {
|
||||
return cpuCycles, nil, err
|
||||
|
|
|
@ -32,6 +32,9 @@ type SDLTV struct {
|
|||
lastFrameRender time.Time
|
||||
}
|
||||
|
||||
// IdealScale is the suggested scaling for the screen
|
||||
const IdealScale = 2.0
|
||||
|
||||
// NewSDLTV is the preferred method for initalising an SDL TV
|
||||
func NewSDLTV(tvType string, scale float32) (*SDLTV, error) {
|
||||
var err error
|
||||
|
|
Loading…
Add table
Reference in a new issue