git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

commit d0522b369d92ee1178ab2cd32312697089323af5
parent 0fa82be14d6e9bb7c02211dba42e9134cfca3fa7
Author: toxa <untoxa@mail.ru>
Date:   Fri, 16 Oct 2020 18:34:13 +0300

SGB multiple joypad support; functions work fine with regular devices too; see multiplayer.c example

Diffstat:
Mgbdk-lib/examples/gb/Makefile10+++++++++-
Mgbdk-lib/examples/gb/comm.c1-
Agbdk-lib/examples/gb/multiplayer.c43+++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/include/gb/gb.h48++++++++++++++++++++++++++++++++++++++++++++----
Mgbdk-lib/libc/gb/Makefile2+-
Agbdk-lib/libc/gb/pad_ex.c84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 181 insertions(+), 7 deletions(-)

diff --git a/gbdk-lib/examples/gb/Makefile b/gbdk-lib/examples/gb/Makefile @@ -16,7 +16,8 @@ BINS = galaxy.gb \ farptr.gb \ bcd.gb \ wobble.gb \ - crash.gb + crash.gb \ + multiplayer.gb # sound.gb: Cant do bitfields OTHER = sound.gb \ @@ -103,3 +104,9 @@ ram_fn.o: ram_fn.c ram_fn.gb: ram_fn.o $(CC) -Wl-g_inc_ram=0xD000 -Wl-g_inc_hiram=0xFFA0 -o $@ ram_fn.o + +############################################################ +# SGB multiplayer example + +multiplayer.gb: multiplayer.o + $(CC) -Wm-ys -o $@ $< + diff --git a/gbdk-lib/examples/gb/comm.c b/gbdk-lib/examples/gb/comm.c @@ -77,7 +77,6 @@ void main(void) printf("#%d\n", _io_status); break; } -// putchar(_io_in); *s = _io_in; if(*s == 0) break; s++; diff --git a/gbdk-lib/examples/gb/multiplayer.c b/gbdk-lib/examples/gb/multiplayer.c @@ -0,0 +1,42 @@ +#include <gb/gb.h> +#include <gb/sgb.h> + +UINT8 sprite_data[] = { + 0x3C,0x3C,0x42,0x7E,0x99,0xFF,0xA9,0xFF,0x89,0xFF,0x89,0xFF,0x42,0x7E,0x3C,0x3C, + 0x3C,0x3C,0x42,0x7E,0xB9,0xFF,0x89,0xFF,0x91,0xFF,0xB9,0xFF,0x42,0x7E,0x3C,0x3C, + 0x3C,0x3C,0x42,0x7E,0x99,0xFF,0x89,0xFF,0x99,0xFF,0x89,0xFF,0x5A,0x7E,0x3C,0x3C, + 0x3C,0x3C,0x42,0x7E,0xA9,0xFF,0xA9,0xFF,0xB9,0xFF,0x89,0xFF,0x42,0x7E,0x3C,0x3C +}; + +joypads_t joypads; + +void main(void) { + BGP_REG = OBP0_REG = OBP1_REG = 0xE4; + set_sprite_data(0, 4, sprite_data); + for (UINT8 i = 0; i < 4; i++) { + set_sprite_tile(i, i); + move_sprite(i, (i << 3) + 64, 64); + } + SHOW_SPRITES; + + // init joypads + joypad_init(4, &joypads); + + while(1) { + // poll joypads + joypad_ex(&joypads); + // iterate joypads, move sprites + for (UINT8 i = 0; i < joypads.npads; i++) { + UINT8 joy = joypads.joypads[i]; + if (joy & J_LEFT) scroll_sprite(i, -1, 0); + if (joy & J_RIGHT) scroll_sprite(i, 1, 0); + if (joy & J_UP) scroll_sprite(i, 0, -1); + if (joy & J_DOWN) scroll_sprite(i, 0, 1); + } + // start on joypad 1 resets position + if (joypads.joy0 & J_START) { + for (UINT8 i = 0; i < 4; i++) move_sprite(i, (i << 3) + 64, 64); + } + wait_vbl_done(); + } +} + diff --git a/gbdk-lib/include/gb/gb.h b/gbdk-lib/include/gb/gb.h @@ -318,6 +318,36 @@ UINT8 waitpad(UINT8 mask) NONBANKED __preserves_regs(b, c); */ void waitpadup(void) NONBANKED __preserves_regs(a, b, c, d, e, h, l); +/** Multiplayer joypad structure + must be initialized with joypad_init() first + then it may be used to poll all avaliable joypads with joypad_ex() +*/ + +typedef struct { + UINT8 npads; + union { + struct { + UINT8 joy0, joy1, joy2, joy3; + }; + UINT8 joypads[4]; + }; +} joypads_t; + +/** Initializes joypads_t structure for polling multiple joypads + @param npads number of joypads requested (1, 2 or 4) + @param joypads pointer to joypads_t structure to be initialized + Returns number of joypads avaliable +*/ + +UINT8 joypad_init(UINT8 npads, joypads_t * joypads); + +/** Polls all avaliable joypads + @param joypads pointer to joypads_t structure to be filled with joypad statuses, + must be previously initialized with joypad_init() +*/ + +void joypad_ex(joypads_t * joypads); + /* ************************************************************ */ /** Enables unmasked interrupts @@ -608,10 +638,11 @@ void get_sprite_data(UINT8 first_tile, UINT8 nb_tiles, unsigned char *data) NONBANKED __preserves_regs(b, c); -/** Sets sprite n to display tile number t, from the sprite tile data. - If the GB is in 8x16 sprite mode then it will display the next - tile, t+1, below the first tile. - @param nb Sprite number, range 0 - 39 +/** Sprite attribute structure + x x-coord of the sprite on screen + y y-coord of the sprite on screen + tile sprite tile number + prop sprite properties */ typedef struct OAM_item_t { @@ -620,8 +651,17 @@ typedef struct OAM_item_t { UINT8 prop; } OAM_item_t; +/** Shadow OAM array in WRAM, that is DMA-transferred into the real OAM each VBlank +*/ + extern volatile struct OAM_item_t shadow_OAM[]; +/** Sets sprite n to display tile number t, from the sprite tile data. + If the GB is in 8x16 sprite mode then it will display the next + tile, t+1, below the first tile. + @param nb Sprite number, range 0 - 39 +*/ + inline void set_sprite_tile(UINT8 nb, UINT8 tile) { shadow_OAM[nb].tile=tile; } diff --git a/gbdk-lib/libc/gb/Makefile b/gbdk-lib/libc/gb/Makefile @@ -5,7 +5,7 @@ TOPDIR = ../.. THIS = gb PORT = gbz80 -CSRC = digits.c gprint.c gprintf.c gprintln.c gprintn.c +CSRC = digits.c gprint.c gprintf.c gprintln.c gprintn.c pad_ex.c ASSRC = cgb.s cpy_data.s drawing.s f_ibm_sh.s \ f_italic.s f_min.s f_spect.s get_bk_t.s get_data.s \ diff --git a/gbdk-lib/libc/gb/pad_ex.c b/gbdk-lib/libc/gb/pad_ex.c @@ -0,0 +1,84 @@ +#include <gb/gb.h> +#include <gb/sgb.h> + +UINT8 joypad_init(UINT8 npads, joypads_t * joypads) { + UINT8 np = npads; + if ((np > 1) && (sgb_check())) { + switch (np) { + case 2: + sgb_transfer("\x89\x01"); + break; + case 4: + sgb_transfer("\x89\x03"); + break; + default: + np = 1; + break; + } + } else np = 1; + return joypads->npads = np; +} + +void joypad_ex(joypads_t * joypads) __naked { + joypads; + __asm + lda hl, 2(sp) + ld a, (hl+) + ld e, a + ld d, (hl) + + ld a, (de) + inc de + or a + jr z, 2$ + + dec a + and #3 + inc a +2$: + push bc + ld b, a +1$: + ld a, #0x30 + ldh (#_P1_REG), a + ldh a, (#_P1_REG) + and #0x0f + sub #0x0f + cpl + inc a ; A contains joypad number + + and #3 ; buffer overrun protection + + add e ; HL = DE + A + ld l, a + adc d + sub l + ld h, a + + ld a, #0x20 + ldh (#_P1_REG), a + ldh a, (#_P1_REG) + ldh a, (#_P1_REG) + and #0x0f + ld c, a + ld a, #0x10 + ldh (#_P1_REG), a + ldh a, (#_P1_REG) + ldh a, (#_P1_REG) + ldh a, (#_P1_REG) + ldh a, (#_P1_REG) + ldh a, (#_P1_REG) + ldh a, (#_P1_REG) + and #0x0f + swap a + or c + cpl + ld (hl), a + + dec b + jr nz, 1$ + pop bc + + ret + __endasm; +}

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.