Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 05:59 27 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMBasic: Game controller library

Author Message
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4040
Posted: 12:13pm 20 Nov 2023
Copy link to clipboard 
Print this post

Hi folks,

In answer to a query from Peter.

The latest version of my MMBasic game controller library can be found here:

   https://github.com/thwill1000/mmbasic-sptools/blob/develop-tree-shake/src/splib/ctrl.inc

Note this version is NOT the MAIN git branch but will be within a few weeks.

You can ignore this kruft:
'!if !defined(NO_INCLUDE_GUARDS)
On Error Skip 1 : Dim sys.VERSION = -1
If sys.VERSION = -1 Then Error "'system.inc' not included"
sys.provides("ctrl")
If sys.err$ <> "" Then Error sys.err$
'!endif

Also ignore any lines beginning '! as they are instructions to my preprocessor and are not terribly important.

A controller is described by a single driver/subroutine:
' Opens / Closes / Reads controller depending on value of x%
'
' @param  x%  -1   open/initialise controller
'             -2   close/terminate controller
'             -3   for most controllers the same as -2, I2C/Wii controllers
'                  does nothing, this is used when polling controllers for
'                  existence, see Functionctrl.poll_single%(driver$, mask%)
'             > 0  read controller, on exit will contain bit-pattern for active buttons.
Sub some_controller(x%)


The bit-pattern returned is the same as that the CMM2 uses for its Wii Classic support (without analogue - the library does not currently support analogue inputs):
Const ctrl.R      = &h01
Const ctrl.START  = &h02
Const ctrl.HOME   = &h04
Const ctrl.SELECT = &h08
Const ctrl.L      = &h10
Const ctrl.DOWN   = &h20
Const ctrl.RIGHT  = &h40
Const ctrl.UP     = &h80
Const ctrl.LEFT   = &h100
Const ctrl.ZR     = &h200
Const ctrl.X      = &h400
Const ctrl.A      = &h800
Const ctrl.Y      = &h1000
Const ctrl.B      = &h2000
Const ctrl.ZL     = &h4000


A simple basic usage would be:
Dim driver$ = "nes_a" ' the name of a controller SUB as selected by the
                      ' program/user, perhaps via
                      ' Function ctrl.poll_multiple$(drivers$(), mask%, duration%, key%)
Dim key%
Call driver$, -1
Do
 Call driver$, key%
 If key% Then Print ctrl.bits_to_string$(key%)
Loop
Call driver$, -2


The library contains driver/subroutines for:
' Cursor keys + "SPACE" as Fire A.
Sub keys_cursor(x%)

' Cursor keys + "SPACE" as Fire A, "B" as Fire B, "E" or "Q" as SELECT and "S" as START.
Sub keys_cursor_ext(x%)

' Atari joystick on PicoGAME Port A.
Sub atari_a(x%)

' Atari joystick on PicoGAME Port B.
Sub atari_b(x%)

' SNES gamepad on PicoGAME Port A.
Sub snes_a(x%)

' SNES gamepad on PicoGAME Port B.
Sub snes_b(x%)

' NES gamepad on PicoGAME Port A.
Sub nes_a(x%)

' NES gamepad on PicoGAME Port B.
Sub nes_b(x%)

' Gamepad on the Game*Mite.
Sub ctrl.gamemite(x%)

' Atari joystick port on CMM2 Deluxe G2.
Sub atari_dx(x%)

' NES gamepad attached USING ADAPTER to Atari joystick port on CMM2 Deluxe G2.
Sub nes_dx(x%)

' SNES gamepad attached USING ADAPTER to Atari joystick port on CMM2 Deluxe G2.
Sub snes_dx(x%)

' Wii Nunchuk OR Classic gamepad on I2C1.
Sub wii_any_1(x%)

' Wii Nunchuk OR Classic gamepad on I2C2.
Sub wii_any_2(x%)

' Wii Nunchuk OR Classic gamepad on I2C3.
Sub wii_any_3(x%)

' Wii Classic gamepad on I2C1.
Sub wii_classic_1(x%)

' Wii Classic gamepad on I2C2.
Sub wii_classic_2(x%)

' Wii Classic gamepad on I2C3.
Sub wii_classic_3(x%)

' Wii Nunchuk on I2C1.
Sub wii_nunchuk_1(x%)

' Wii Nunchuk on I2C2.
Sub wii_nunchuk_2(x%)

' Wii Nunchuk on I2C3.
Sub wii_nunchuk_3(x%)


Best wishes,

Tom
Edited 2023-11-21 08:50 by thwill
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4040
Posted: 12:20pm 20 Nov 2023
Copy link to clipboard 
Print this post

Question: Why is the driver a SUB when having the bit-pattern returned by a FUNCTION would be more convenient ?

Answer: So that the drivers could be replaced by CSUBs for efficiency, though I've not found any necessity to do so yet.

Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4040
Posted: 02:20pm 04 Dec 2023
Copy link to clipboard 
Print this post

Copied from: https://www.thebackshed.com/forum/ViewTopic.php?TID=16465&P=2#213486

  Mixtel90 said  I'm going to have to be careful here. :)
PicoGAME v4 (there is no v3) has a WII Classic controller and a NES/SNES, but pin 1 of the (only) D connector is Latch2 for a second NES/SNES. It's mapped as a Port A NES socket by defat.

Just a thought about using two NES controllers.
I assumed that simply reading it twice, but with a different latch pin would be fine, but you could read two at once. Merely have two data inputs, one from each controller. Carry out a single read operation but store the data pin into its own variable (read then shift).  You've read two controllers in about the same time as reading one. I've not tried this yet but I can't see any problems.


You're just what is technically known as a "bloody nuisance" ... takes one to know one .

I know you need two data pins, but why two latch pins (they're not chip select) ?

Dim bitsA%, bitsB%, i%
Pulse LATCH, PULSE_DURATION!
For i% = 0 To 7
 If Not Pin(DATA_A) Then bitsA% = bitsA% Or 2^i%
 If Not Pin(DATA_B) Then bitsB% = bitsB% Or 2^i%
 Pulse CLOCK, PULSE_DURATION!
Next


Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6797
Posted: 03:58pm 04 Dec 2023
Copy link to clipboard 
Print this post

You don't need two latch pins if you have two data pins. You always need two of something if you have two controllers though, I think. :)

All that will happen (if there are pullups on the data pins) is that, if there is only one controller connected, the empty one will load &hFF. Pin 1 on the D connector could well be controller 2 Data input. As standard it's connected to GP0 anyway and used for the Atari Up input.

-----------------------

I've now got a WII Classic controller and tested it on a CMM2 so I know it's working. :)
Edited 2023-12-05 02:05 by Mixtel90
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4040
Posted: 04:38pm 05 Dec 2023
Copy link to clipboard 
Print this post

Copied from https://www.thebackshed.com/forum/ViewTopic.php?FID=16&TID=16235&LastEntry=Y#213572#213570

  matherp said  What is the issue with the SNES controller. If I buy this for development use will it not be OK? The contents should just be a 16-bit shift register?


In theory as "old stock" originals those should be fine, depending on their vintage they may contain a chain of two 8-bit shift registers.

Our issue has been with identifying "new stock" clones (ideally with DB9 connectors if that is possible).

  Mixtel90 said  I have a cheap Chinese one here that doesn't appear to be a SNES controller although it looks like one. The buttons are multiplexed and, I suspect, the "black blob" may be a microcontroller and not a shift register. The "proper" ones should be correct.


That's one with a DB9 plug. I don't think (but may be wrong) that the blob is a uC it is a simple oscillator and an 8-bit shift register (but not a 4021 as it requires clocking an 8th time and if you read data after 8 clocks it returns 1's instead of 0's ... or the other way around). The oscillator provides "turbo-fire" on some of the buttons and was a common feature on NES clone controllers.

The other sort of clone has the standard SNES plug and contains an unmarked IC that "we" believe is a 5v micro-controller. I suspect these would behave as an approximation of SNES controllers, but we would need to run them at 5v.

Am I to take it Peter that you are going ahead with firmware support even if "we" don't send you working controllers ... you have too much time on your hands .

I think NES, SNES, Atari Joystick and incidentally Game*Mite might be done like so:

DEVICE GAMEPAD_A OPEN [8|16] latch%, clock%, data% [,pulse!]
DEVICE GAMEPAD_B ...
DEVICE JOYSTICK_A OPEN [HIGH|LOW] up%, down%, left%, right%, fire_a% [,fire_b%] [,start%] [,select%] [,home%]
DEVICE JOYSTICK_B ...


Edit: I suppose you could add fire_x, fire_y and the four bumpers l, r, zl and zr to the JOYSTICK option ... but it would need to be custom hardware and a lot of free GPIO to make use of it.

And the corresponding functions should return the same bit-pattern as DEVICE(WII B).

YMMV.

Best wishes,

Tom
Edited 2023-12-06 02:45 by thwill
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024