Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
I'm trying to make a simple pong game that you can play multiplayer via Super Gameboy kinda like Bomberman GB did. I found the function that checks if your playing on a super gameboy or regular gameboy, but now I just need to figure out the second controllers inputs. Is there any information on that out there?
Offline
Check out the SGB Multiplayer Commands here. You can use BGB to test if you send the packets right. You might want to check out higan to see if you can get two-controller support that way.
cYa,
Tauwasser
Last edited by Tauwasser (2014-10-22 07:08:04)
Offline
Ok I found this within that thing you linked, but I dont really know how to use this. Do you understand it? Can you give me an example of it being used?
SGB Command 11h - MLT_REQ
Used to request multiplayer mode (ie. input from more than one joypad).
Because this function provides feedback from the SGB/SNES to the gameboy program, it is also used to detect SGB hardware.
Byte Content
0 Command*8+Length (fixed length=1)
1 Multiplayer Control (0-3) (Bit0=Enable, Bit1=Two/Four Players)
0 = One player
1 = Two players
3 = Four players
2-F Not used (zero)
In one player mode, the second joypad (if any) is used for the SGB system program. In two player mode, both joypads are used for the game. Because SNES have only two joypad sockets, four player mode requires an external "Multiplayer 5" adapter.
Reading Multiple Controllers (Joypads)
When having enabled multiple controllers by MLT_REQ, data for each joypad can be read out through JOYPAD register (FF00) as follows: First set P14 and P15 both HIGH (deselect both Buttons and Cursor keys), you can now read the lower 4bits of FF00 which indicate the joypad ID for the following joypad input:
0Fh Joypad 1
0Eh Joypad 2
0Dh Joypad 3
0Ch Joypad 4
Next, set P14 and P15 low (one after each other) to select Buttons and Cursor lines, and read-out joypad state as normally. When completed, set P14 and P15 back HIGH, this automatically increments the joypad number (or restarts counting once reached the lastmost joypad). Repeat the procedure until you have read-out states for all two (or four) joypads.
Also I found this in hardware.h, which im 99% sure has to do with this, but I dont know how to use it.
#define P1_REG (*(__REG)0xFF00) /* Joystick: 1.1.P15.P14.P13.P12.P11.P10 */
Last edited by Crona (2014-10-22 10:20:08)
Offline
Did you look at the SGB Command Packet Transfers part?
Below is example code from a game:
;; Point hl to SGB command ;; don't interrupt this sequence, ;; e.g. by reading keypad ld a, [hl] ;; length field in packet header @send_sgb: and a, $07 ret z ld b, a @for_length: push bc xor a, a ld [$FF00 + $00], a ld a, $30 ld [$FF00 + $00], a ld b, $10 ;; 0x10 bytes per packet @outer: ld e, $08 ;; 0x08 bits per byte ldi a, [hl] ld d, a @inner: bit 0, d ;; set P14 or P15 according to current data bit to send ld a, $10 jr nz, @5C38 ld a, $20 @5C38: ld [$FF00 + $00], a ld a, $30 ld [$FF00 + $00], a rr d dec e jr nz, @inner dec b jr nz, @outer ld a, $20 ld [$FF00 + $00], a ld a, $30 ld [$FF00 + $00], a call delay_loop pop bc dec b jr nz, @for_length ret @delay_loop: ld de, $1B58 @loop: nop nop nop dec de ld a, d or a, e jr nz, @loop ret
The initial MLT_REQ check would then look like this:
@check_sgb ld hl, @MLT_REQ_ON call @send_sgb call @delay_loop ld a, [$FF00 + $00] ;; read joypad ID and a, $03 cp a, $03 jr nz, @is_sgb ;; should not be joypad 1 ;; simulate reading joypad state ;; to get SGB to apply MLT_REQ ld a, $20 ;; P14 low ld [$FF00 + $00], a ld a, [$FF00 + $00] ld a, [$FF00 + $00] call @delay_loop call @delay_loop ld a, $30 ;; P14, P15 low ld [$FF00 + $00], a call @delay_loop call @delay_loop ld a, $10 ;; P15 low ld [$FF00 + $00], a ld a, [$FF00 + $00] ld a, [$FF00 + $00] ld a, [$FF00 + $00] ld a, [$FF00 + $00] ld a, [$FF00 + $00] ld a, [$FF00 + $00] call @delay_loop call @delay_loop ld a, $30 ;; P14, P15 low ld [$FF00 + $00], a ld a, [$FF00 + $00] ld a, [$FF00 + $00] ld a, [$FF00 + $00] call @delay_loop call @delay_loop ld a, [$FF00 + $00] ;; read joypad ID and a, $03 cp a, $03 jr nz, @is_sgb ;; should not be 1 call @send_mlt_req_off and a, a ret @is_sgb: call @send_mlt_req_off scf ret @send_mlt_req_off: ld hl, @MLT_REQ_OFF call @send_sgb jp @delay_loop @MLT_REQ_OFF: db $89, $00, $00, $00, $00, $00, $00, $00 db $00, $00, $00, $00, $00, $00, $00, $00 @MLT_REQ_ON: db $89, $01, $00, $00, $00, $00, $00, $00 db $00, $00, $00, $00, $00, $00, $00, $00
And that would be my short analysis of SGB transfers. I guess you'll have to check out if that works for you or not. I'm pretty sure the bulk of the code here is just to make sure the SGB actually updated the controller requests. So if you read all ones after selecting the controller twice, that's bad.
cYa,
Tauwasser
Offline
Yes!, Found this post, and whilst I don't fully understand all the ASM involved I'm going to try to! I think there's a way to make it less ASM involved perhaps with GBDK as you're essentially timing writes to a memory address (0xFF00) with pulses of data every 15us , which last for 5 us.
Sooo If you were to create a delay_loop function or two in ASM (one for 15us and another for 5 us) orr possibly just the 5us one and run it 3 times even.
Then Push the correct value of one of the following values into the address, e.g.:
RESET = Binary 00000000 or Decimal 0;
Bit 0 = Binary 00010000 or Decimal 16
Bit 1 = Binary 00100000 or Decimal 32
HIGH = Binary 00110000 or Decimal 48
http://bgb.bircd.org/pandocs.htm#joypadinput (scroll down to the transferring bits section below it also)
Offline