English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Blitz Basic (https://eab.abime.net/forumdisplay.php?f=126)
-   -   4 controller support on blitz (https://eab.abime.net/showthread.php?t=87968)

Shatterhand 19 July 2017 14:32

4 controller support on blitz
 
I remember some Blitz games do actually support 4 controllers ( Skidmarks comes to mind now, I think those Tennis Champ games were also coded in Blitz)

Yet on its manual all joystick functions only mention port 0 or 1, and trying to access any other "port" will give me an error.

Is there any way to do it ?

Also, does the CD32 supports this somehow ? I dunno if the CD32 has a serial port.

demolition 19 July 2017 14:38

The Amiga only has two joystick ports. 4-player games use a parallel port adapter to interface to the two extra controllers, so you have to access the parallel port. I think Blitz should have methods to do this? If you can read the parallel port pins directly, I think it should be fairly simple to read the extra joysticks.

Here's the pinout:
http://www.tmeeco.eu/9X4EVER/GOODIES...iga4Player.htm

The CD32 can also be used with a 4-player adapter if you connect an SX-1, SX-32 or other expansion which provides a parallel port.

Shatterhand 19 July 2017 14:47

Yeah, I know its a parallel port cable (not Serial like I said in the OP, urgh)..... just thought there was an easy way to do it.

Blitz manual talks about the CIA chip and which register is responsible for the parallel port, but I have no idea of how to read that.

I don't think many people with CD32s have a SX-1 or SX-32, right?

demolition 19 July 2017 14:53

Quote:

Originally Posted by Shatterhand (Post 1172375)
I don't think many people with CD32s have a SX-1 or SX-32, right?

No, these kind of expansions were expensive so not particularly common. It basically turns the CD32 into an A1200 with a CD-drive but it is much cheaper to just add a CD-drive to a regular A1200. Then you also get a keyboard.

Daedalus 19 July 2017 15:50

Reading the parallel port is pretty simple really, from memory it's just a matter of setting the pins high and then reading them back to read the port status. I used this method to read them in my ControllerTest program, which was written in Blitz. I can dig out the code for you if you'd like? I'm pretty sure (I hope) that I put the routine in a little function that you can easily use without worrying about how it works...

Actually, I have a vague memory of an add-in library for Blitz also offering 4-player joystick support, but it wasn't one of the standard libraries. I'll see if I can find that too...

Shatterhand 19 July 2017 15:52

Quote:

Originally Posted by Daedalus (Post 1172386)
Reading the parallel port is pretty simple really, from memory it's just a matter of setting the pins high and then reading them back to read the port status. I used this method to read them in my ControllerTest program, which was written in Blitz. I can dig out the code for you if you'd like? I'm pretty sure (I hope) that I put the routine in a little function that you can easily use without worrying about how it works...

Yeah, I would be *really* thankful :) Any help is appreciated

Daedalus 19 July 2017 15:56

No problem, I'll stick it here tonight, time permitting...

idrougge 19 July 2017 18:52

Use the RI Zonejoy library. It should already be in your deflibs.
Quote:

Function: JHoriz
---------------------------------------------------------------------------
Modes : Amiga/Blitz
Syntax : jh.b=JHoriz(joy#)

This command is used to test the horizontal direction of the selected
joystick. It returns:

0: No horizontal direction
-1: Joystick left
1: Joystick right

Function: JVert
---------------------------------------------------------------------------
Modes : Amiga/Blitz
Syntax : jv.b=JVert(joy#)

This command is used to test the vertical direction of the selected
joystick. It returns:

0: No vertical direction
-1: Joystick up
1: Joystick down

Function: JFire
------------------------------------------------------------------------
Modes : Amiga/Blitz
Syntax : jf.b=JFire(joy#)

This command tests the fire button status of the joystick joy#, where
joy# is between 1 and 4. You should note that, as with all the joystick
commmands, joy#=1 refers to the Amiga's joystick port, joy#=2 refers to
the mouse port, and joy#=3 or joy#=4 refer to the four player adapter
ports.

This command returns 0 for fire button not pressed or -1 for pressed

Function: AllFire
------------------------------------------------------------------------
Modes : Amiga/Blitz
Syntax : af.b=AllFire [(bit_pattern)]

This command is used to test the fire button status of all four
joysticks. It returns a byte with the first four bits giving the
joystick status, false=fire button not pressed, true=fire button pressed.
The following bits belong to joysticks:

bit 0: joystick 1 (joystick port)
bit 1: joystick 2 (mouse port)
bit 2: joystick 3 (four player adaptor)
bit 3: joystick 4 (four player adaptor)

The optional bit pattern can be used to restrict the testing of the fire
buttons. If a bit in the pattern is clear (false) then the joystick it
belongs to will not have its fire button tested,

e.g. AllFire (%0011) will test joysticks 1 and 2 and return the
result. It will return false for joysticks 3 and 4.

Statement/Function: JAdaptorStatus
------------------------------------------------------------------------
Modes : Amiga/Blitz
Syntax : JAdaptorStatus On/Off
oldstatus=JAdaptorStatus(On/Off)

This command toggles the reading of the four player adaptor for the
following commands:

AllFire
Jvert
JHoriz
JFire

When the status is off, these commands will return 0 when you attempt to
read from joysticks 3 and 4. When on the testing will be performed
normally. Default status for the adaptor is on.

Daedalus 19 July 2017 19:52

Here you go - this will give you two routines that will give you direction and button information for any port. Ports 0 and 1 are the standard Amiga ports, and 2 and 3 are on the parallel port adaptor. You could also use the existing Blitz commands and just use these for ports 2 and 3 if you liked.

The joydir{port.b} function returns a byte representing the direction of the selected stick, with the lowest 4 bits representing the 4 directions. Note that it will allow opposite directions to be read (e.g. left and right), even though with most controllers that's mechanically impossible. Bit 0 is up, bit 1 is down, bit 2 is left and bit 3 is right, and the bit is set when the controller is pushed that direction. For example:

Code:

joybyte.b = joydir{i}
If joybyte & %0100
  NPrint "Left!"
End If

The joybuttons{port.b} function returns a word where the lowest 3 bits represent the buttons - bit 0 is fire (left mouse button), bit 1 is 2nd fire (right mouse button) and bit 2 is 3rd fire (middle mouse button). It also includes support for 2 buttons on the Player 3 stick, but not Player 4 (don't think anything ever used this anyway - most 4-player adaptors don't support more than one button). Note that it's active low, so if the bit is set, the button *isn't* pressed. For example:

Code:

btns.w = joybuttons{1}
If btns & %00000010
  NPrint "Fire 2 pressed on port 1"
End If

Finally, before actually reading the parallel port, you need to set all pins to high so they can be read. This only needs to be done once:

Code:

Poke.b $BFD200,Peek.b($BFD200) | %00000111 ; Handshake lines to output
Poke.b $BFD000,Peek.b($BFD000) | %00000111 ; Handshake lines high

Poke.b $BFD200,Peek.b($BFD200) & %11111000 ; Handshake lines back to input

Poke.b $BFE301,%11111111 ; Output mode
Poke.b $BFE101,%11111111 ; All pins high


So the full code can look like this:

Code:

; Initialisation
Poke.b $BFD200,Peek.b($BFD200) | %00000111 ; Handshake lines to output
Poke.b $BFD000,Peek.b($BFD000) | %00000111 ; Handshake lines high

Poke.b $BFD200,Peek.b($BFD200) & %11111000 ; Handshake lines back to input

Poke.b $BFE301,%11111111 ; Output mode
Poke.b $BFE101,%11111111 ; All pins high


Function.b joydir{port.b}
result.b=0

If port<2
  If port=1
    bytes.w=Peek.w($DFF00C) ; JOY1DAT
  Else
    bytes.w=Peek.w($DFF00A) ; JOY0DAT
  End If

  bit9.w=bytes&%0000001000000000
  bit8.w=bytes&%0000000100000000
  bit1.w=bytes&%0000000000000010
  bit0.w=bytes&%0000000000000001

  result = result | (((bit9 LSR 1) EOR bit8) LSR 8) ; Up
  result = result | (bit1 LSL 2)                    ; Right
  result = result | (bit1 EOR (bit0 LSL 1))        ; Down
  result = result | (bit9 LSR 7)                    ; Left

Else ; Parallel port adaptor
  byte.b = NOT Peek.b($BFE101)
  If port=2
    result=byte & %00001111
  Else
    result=(byte & %11110000) LSR 4
  End If
End If

Function Return result
End Function


Function.b joybuttons{port.b}
result.w=0

If port<2
  buttonbyte.b=Peek.b($BFE001) ; CIA for button 1
  If port=1
    result=(buttonbyte & %0000000010000000) LSR 7
  Else
    result=(buttonbyte & %0000000001000000) LSR 6
  End If

  bytes.w=(Peek.w($DFF016) LSR (9+(port*4))) ; Potgo for buttons 2 & 3
  result=result | (bytes & %0000000000000010)
  bytes.w=(Peek.w($DFF016) LSR (6+(port*4)))
  result=result | (bytes & %0000000000000100)
Else ; Parallel port adaptor

  buttonbyte=Peek.b($BFD000)
  If port=3
    result=(buttonbyte & %00000001)
    result=result | %00000010 ; No second fire button on port 3 (Yet... Wired to Ack)
  Else
    result=(buttonbyte & %00000100) LSR 2
    result=result | (buttonbyte & %00000010)
  End If
  result=result | % 11111100
End If
Function Return result
End Function

Looking at it now, there's probably scope for optimisation - I mostly wrote it as a literal translation from the description in the Hardware Reference Manual - but it works fine.

Daedalus 19 July 2017 19:53

Quote:

Originally Posted by idrougge (Post 1172463)
Use the RI Zonejoy library. It should already be in your deflibs.

Ah yes, knew I saw it somewhere...

Shatterhand 20 July 2017 03:49

Hey, thank you guys. This will be very helpful!


All times are GMT +2. The time now is 21:34.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.08139 seconds with 11 queries