git.y1.nz

gbdk-2020

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

commit 7161638dd214ffebcb69a635d0951e848d3f2bdb
parent 2b9a2f4d71d3b58db848c3b2c8a0180bfbcd4c2f
Author: Toxa <untoxa@mail.ru>
Date:   Thu,  2 Sep 2021 13:16:16 +0300

SMS/GG: fix joypad_init(); cross-platform pong

Diffstat:
Dgbdk-lib/examples/ap/sgb_pong/Makefile17-----------------
Dgbdk-lib/examples/ap/sgb_pong/sgb_pong.c145-------------------------------------------------------------------------------
Agbdk-lib/examples/cross-platform/pong/Makefile77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/cross-platform/pong/Makefile.targets44++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/cross-platform/pong/src/pong.c144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/include/gb/hardware.h3+++
Mgbdk-lib/include/sms/hardware.h4++++
Mgbdk-lib/libc/targets/z80/gg/global.s2++
Mgbdk-lib/libc/targets/z80/pad_ex.s10+++++++++-
Mgbdk-lib/libc/targets/z80/sms/global.s2++
10 files changed, 285 insertions(+), 163 deletions(-)

diff --git a/gbdk-lib/examples/ap/sgb_pong/Makefile b/gbdk-lib/examples/ap/sgb_pong/Makefile @@ -1,17 +0,0 @@ -CC = ../../../bin/lcc -mgbz80:ap -Wl-j -Wm-yS -Wm-ys - -BINS = sgb_pong.pocket - -all: $(BINS) - -compile.bat: Makefile - @echo "REM Automatically generated from Makefile" > compile.bat - @make -sn | sed y/\\//\\\\/ | grep -v make >> compile.bat - -# Compile and link single file in one pass -%.pocket: %.c - $(CC) -o $@ $< - -clean: - rm -f *.o *.lst *.map *.pocket *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm *.noi - diff --git a/gbdk-lib/examples/ap/sgb_pong/sgb_pong.c b/gbdk-lib/examples/ap/sgb_pong/sgb_pong.c @@ -1,144 +0,0 @@ -#include <gb/gb.h> -#include <gb/sgb.h> -#include <gbdk/console.h> - -#include <stdint.h> -#include <stdio.h> - -uint8_t 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 - -}; - -// initializes sprites for pad. every pad uses 3 sprites which id's are aligned by 4 -void init_pad(uint8_t n) { - set_sprite_tile(n << 2, n); - set_sprite_tile((n << 2) + 1, n); - set_sprite_tile((n << 2) + 2, n); -} - -// inline function for moving pads; code of this function will be inlined with the code of main() -inline void draw_pad(uint8_t n, uint8_t x, uint8_t y) { - move_sprite(n << 2, x, y); - move_sprite((n << 2) + 1, x, y + 8); - move_sprite((n << 2) + 2, x, y + 16); -} - -joypads_t joypads; - -// absolute Y coordinates of player 1 & 2 -uint8_t player1, player2; -uint16_t player1_score, player2_score; - -// player constraints -#define YMIN 28 -#define YMAX 100 -#define PLAYER1_X 16 -#define PLAYER2_X (uint8_t)((20 * 8) - 8) - -// coordinates and speeds of ball -uint8_t ballX, ballY; -int8_t spd_ballX, spd_ballY; - -#define INITBALLX 80 + 4 -#define INITBALLY 64 + 8 - -const unsigned char HUD[] = " p1: %d p2: %d"; - -// main funxction -void main(void) { - // init palettes - BGP_REG = OBP0_REG = OBP1_REG = 0xE4; - - // load tile data into VRAM - set_sprite_data(0, 4, sprite_data); - - // init pad sprites - init_pad(0); - init_pad(1); - - // init ball sprite - set_sprite_tile(3, 2); - - // show bkg and sprites - SHOW_BKG; SHOW_SPRITES; - - // init 2 joypads - if (joypad_init(2, &joypads) != 2) { - printf(" This program must\n be executed on\n Super GameBoy"); - return; - } - - // init players - player1 = 64, player2 = 64; - player1_score = player2_score = 0; - - // draw score - printf(HUD, player1_score, player2_score); - - // init ball - ballX = INITBALLX, ballY = INITBALLY; - spd_ballX = 1, spd_ballY = 1; - - while(1) { - // poll joypads - joypad_ex(&joypads); - - // player 1 - if (joypads.joy0 & J_UP) { - player1 -= 2; - if (player1 < YMIN) player1 = YMIN; - } else if (joypads.joy0 & J_DOWN) { - player1 += 2; - if (player1 > YMAX) player1 = YMAX; - } - draw_pad(0, PLAYER1_X, player1); - - // player 2 - if (joypads.joy1 & J_UP) { - player2 -= 2; - if (player2 < YMIN) player2 = YMIN; - } else if (joypads.joy1 & J_DOWN) { - player2 += 2; - if (player2 > YMAX) player2 = YMAX; - } - draw_pad(1, PLAYER2_X, player2); - - // move ball - ballX += spd_ballX, ballY += spd_ballY; - // check bounce from limits - if ((ballY < YMIN) || (ballY > (YMAX + 24))) { - spd_ballY = -spd_ballY; - } - // check bounce from bats - if (ballX < (PLAYER1_X + 8)) { - if ((ballY > player1) && (ballY < (player1 + 24)) && (spd_ballX < 0)) - spd_ballX = -spd_ballX; - } else if (ballX > (PLAYER2_X - 8)) { - if ((ballY > player2) && (ballY < (player2 + 24)) && (spd_ballX > 0)) - spd_ballX = -spd_ballX; - } - // check player1 or 2 wins, update scores, start from center - if (ballX < PLAYER1_X) { - // player2 wins - ballX = INITBALLX, ballY = INITBALLY; - spd_ballX = -spd_ballX; - player2_score++; - gotoxy(0, 0); printf(HUD, player1_score, player2_score); - } else if (ballX > PLAYER2_X) { - // player1 wins - ballX = INITBALLX, ballY = INITBALLY; - spd_ballX = -spd_ballX; - player1_score++; - gotoxy(0, 0); printf(HUD, player1_score, player2_score); - } - // move ball sprite - move_sprite(3, ballX, ballY); - - // wait for VBlank to slow down everything - wait_vbl_done(); - } -} - diff --git a/gbdk-lib/examples/cross-platform/pong/Makefile b/gbdk-lib/examples/cross-platform/pong/Makefile @@ -0,0 +1,77 @@ +# If you move this project you can change the directory +# to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/" +GBDK_HOME = ../../../ +LCC = $(GBDK_HOME)bin/lcc + +# Set platforms to build here, spaced separated. (These are in the separate Makefile.targets) +# They can also be built/cleaned individually: "make gg" and "make gg-clean" +# Possible are: gb gbc pocket sms gg +TARGETS=gb pocket sms gg + +# Configure platform specific LCC flags here: +LCCFLAGS_gb = -Wm-ys -Wl-yt0x1B # Set an MBC for banking (1B-ROM+MBC5+RAM+BATT) +LCCFLAGS_pocket = -Wm-ys -Wl-yt0x1B # Usually the same as required for .gb +LCCFLAGS_gbc = -Wm-ys -Wl-yt0x1B -Wm-yc # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) +LCCFLAGS_sms = +LCCFLAGS_gg = + +LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags + +LCCFLAGS += -Wl-j -Wm-yoA -Wm-ya4 -autobank -Wb-ext=.rel -Wb-v # MBC + Autobanking related flags +# LCCFLAGS += -debug # Uncomment to enable debug output +# LCCFLAGS += -v # Uncomment for lcc verbose output + +# You can set the name of the ROM file here +PROJECTNAME = fonts + +# EXT?=gb # Only sets extension to default (game boy .gb) if not populated +SRCDIR = src +OBJDIR = obj/$(EXT) +RESDIR = res +BINDIR = build/$(EXT) +MKDIRS = $(OBJDIR) $(BINDIR) # See bottom of Makefile for directory auto-creation + +BINS = $(OBJDIR)/$(PROJECTNAME).$(EXT) +CSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.c))) $(foreach dir,$(RESDIR),$(notdir $(wildcard $(dir)/*.c))) +ASMSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.s))) +OBJS = $(CSOURCES:%.c=$(OBJDIR)/%.o) $(ASMSOURCES:%.s=$(OBJDIR)/%.o) + +# Builds all targets sequentially +all: $(TARGETS) + +# Compile .c files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .c files in "res/" to .o object files +$(OBJDIR)/%.o: $(RESDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .s assembly files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.s + $(LCC) $(CFLAGS) -c -o $@ $< + +# If needed, compile .c files i n"src/" to .s assembly files +# (not required if .c is compiled directly to .o) +$(OBJDIR)/%.s: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -S -o $@ $< + +# Link the compiled object files into a .gb ROM file +$(BINS): $(OBJS) + $(LCC) $(LCCFLAGS) $(CFLAGS) -o $(BINDIR)/$(PROJECTNAME).$(EXT) $(OBJS) + +clean: + @echo Cleaning + @for target in $(TARGETS); do \ + $(MAKE) $$target-clean; \ + done + +# Include available build targets +include Makefile.targets + + +# create necessary directories after Makefile is parsed but before build +# info prevents the command from being pasted into the makefile +ifneq ($(strip $(EXT)),) # Only make the directories if EXT has been set by a target +$(info $(shell mkdir -p $(MKDIRS))) +endif diff --git a/gbdk-lib/examples/cross-platform/pong/Makefile.targets b/gbdk-lib/examples/cross-platform/pong/Makefile.targets @@ -0,0 +1,44 @@ + +# Platform specific flags for compiling (only populate if they're both present) +ifneq ($(strip $(PORT)),) +ifneq ($(strip $(PLAT)),) +CFLAGS += -m$(PORT):$(PLAT) -D_PLAT_$(PLAT) +endif +endif + +# Called by the individual targets below to build a ROM +build-target: $(BINS) + +clean-target: + rm -rf $(OBJDIR) + rm -rf $(BINDIR) + +gb-clean: + ${MAKE} clean-target EXT=gb +gb: + ${MAKE} build-target PORT=gbz80 PLAT=gb EXT=gb + + +gbc-clean: + ${MAKE} clean-target EXT=gbc +gbc: + ${MAKE} build-target PORT=gbz80 PLAT=gb EXT=gbc + + +pocket-clean: + ${MAKE} clean-target EXT=pocket +pocket: + ${MAKE} build-target PORT=gbz80 PLAT=ap EXT=pocket + + +sms-clean: + ${MAKE} clean-target EXT=sms +sms: + ${MAKE} build-target PORT=z80 PLAT=sms EXT=sms + + +gg-clean: + ${MAKE} clean-target EXT=gg +gg: + ${MAKE} build-target PORT=z80 PLAT=gg EXT=gg + diff --git a/gbdk-lib/examples/cross-platform/pong/src/pong.c b/gbdk-lib/examples/cross-platform/pong/src/pong.c @@ -0,0 +1,143 @@ +#include <gbdk/platform.h> +#include <gbdk/console.h> + +#include <stdint.h> +#include <stdio.h> + +uint8_t 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 + +}; + +// initializes sprites for pad. every pad uses 3 sprites which id's are aligned by 4 +void init_pad(uint8_t n) { + set_sprite_tile(n << 2, n); + set_sprite_tile((n << 2) + 1, n); + set_sprite_tile((n << 2) + 2, n); +} + +// inline function for moving pads; code of this function will be inlined with the code of main() +inline void draw_pad(uint8_t n, uint8_t x, uint8_t y) { + move_sprite(n << 2, x, y); + move_sprite((n << 2) + 1, x, y + 8); + move_sprite((n << 2) + 2, x, y + 16); +} + +joypads_t joypads; + +// absolute Y coordinates of player 1 & 2 +uint8_t player1, player2; +uint16_t player1_score, player2_score; + +// player constraints +#define YMIN 28 +#define YMAX 100 +#define PLAYER1_X DEVICE_SPRITE_OFFSET_X +#define PLAYER2_X (uint8_t)(DEVICE_SPRITE_OFFSET_X + (DEVICE_SCREEN_WIDTH * 8) - 8) + +// coordinates and speeds of ball +uint8_t ballX, ballY; +int8_t spd_ballX, spd_ballY; + +#define INITBALLX 80 + 4 +#define INITBALLY 64 + 8 + +const unsigned char HUD[] = " p1: %d p2: %d"; + +// main funxction +void main(void) { + // init palettes +// BGP_REG = OBP0_REG = OBP1_REG = 0xE4; + + // load tile data into VRAM + set_sprite_data(0, 4, sprite_data); + + // init pad sprites + init_pad(0); + init_pad(1); + + // init ball sprite + set_sprite_tile(3, 2); + + // show bkg and sprites + SHOW_BKG; SHOW_SPRITES; + + // init 2 joypads + if (joypad_init(2, &joypads) != 2) { + printf("Device must support\nat least two joypads"); + return; + } + + // init players + player1 = 64, player2 = 64; + player1_score = player2_score = 0; + + // draw score + printf(HUD, player1_score, player2_score); + + // init ball + ballX = INITBALLX, ballY = INITBALLY; + spd_ballX = 1, spd_ballY = 1; + + while(1) { + // poll joypads + joypad_ex(&joypads); + + // player 1 + if (joypads.joy0 & J_UP) { + player1 -= 2; + if (player1 < YMIN) player1 = YMIN; + } else if (joypads.joy0 & J_DOWN) { + player1 += 2; + if (player1 > YMAX) player1 = YMAX; + } + draw_pad(0, PLAYER1_X, player1); + + // player 2 + if (joypads.joy1 & J_UP) { + player2 -= 2; + if (player2 < YMIN) player2 = YMIN; + } else if (joypads.joy1 & J_DOWN) { + player2 += 2; + if (player2 > YMAX) player2 = YMAX; + } + draw_pad(1, PLAYER2_X, player2); + + // move ball + ballX += spd_ballX, ballY += spd_ballY; + // check bounce from limits + if ((ballY < YMIN) || (ballY > (YMAX + 24))) { + spd_ballY = -spd_ballY; + } + // check bounce from bats + if (ballX < (PLAYER1_X + 8)) { + if ((ballY > player1) && (ballY < (player1 + 24)) && (spd_ballX < 0)) + spd_ballX = -spd_ballX; + } else if (ballX > (PLAYER2_X - 8)) { + if ((ballY > player2) && (ballY < (player2 + 24)) && (spd_ballX > 0)) + spd_ballX = -spd_ballX; + } + // check player1 or 2 wins, update scores, start from center + if (ballX <= PLAYER1_X) { + // player2 wins + ballX = INITBALLX, ballY = INITBALLY; + spd_ballX = -spd_ballX; + player2_score++; + gotoxy(0, 0); printf(HUD, player1_score, player2_score); + } else if (ballX > PLAYER2_X) { + // player1 wins + ballX = INITBALLX, ballY = INITBALLY; + spd_ballX = -spd_ballX; + player1_score++; + gotoxy(0, 0); printf(HUD, player1_score, player2_score); + } + // move ball sprite + move_sprite(3, ballX, ballY); + + // wait for VBlank to slow down everything + wait_vbl_done(); + } +} + diff --git a/gbdk-lib/include/gb/hardware.h b/gbdk-lib/include/gb/hardware.h @@ -368,5 +368,8 @@ __REG IE_REG; /** Interrupt enable */ #define DEVICE_SCREEN_BUFFER_WIDTH 32 #define DEVICE_SCREEN_BUFFER_HEIGHT 32 #define DEVICE_SCREEN_MAP_ENTRY_SIZE 1 +#define DEVICE_SPRITE_OFFSET_X 8 +#define DEVICE_SPRITE_OFFSET_Y 16 + #endif diff --git a/gbdk-lib/include/sms/hardware.h b/gbdk-lib/include/sms/hardware.h @@ -184,6 +184,8 @@ extern volatile UBYTE VDP_ATTR_SHIFT; #define DEVICE_SCREEN_BUFFER_WIDTH 32 #define DEVICE_SCREEN_BUFFER_HEIGHT 28 #define DEVICE_SCREEN_MAP_ENTRY_SIZE 2 +#define DEVICE_SPRITE_OFFSET_X 0 +#define DEVICE_SPRITE_OFFSET_Y 0 #elif defined(__TARGET_gg) #define DEVICE_SCREEN_X_OFFSET 6 #define DEVICE_SCREEN_Y_OFFSET 3 @@ -192,6 +194,8 @@ extern volatile UBYTE VDP_ATTR_SHIFT; #define DEVICE_SCREEN_BUFFER_WIDTH 32 #define DEVICE_SCREEN_BUFFER_HEIGHT 28 #define DEVICE_SCREEN_MAP_ENTRY_SIZE 2 +#define DEVICE_SPRITE_OFFSET_X 48 +#define DEVICE_SPRITE_OFFSET_Y 24 #else #error Unrecognized port #endif diff --git a/gbdk-lib/libc/targets/z80/gg/global.s b/gbdk-lib/libc/targets/z80/gg/global.s @@ -105,6 +105,8 @@ .R10_INT_OFF = 0xFF .R10_INT_EVERY = 0x00 + .JOYPAD_COUNT = 2 ; let's support 2-joypad mods + .UP = 0b00000001 .DOWN = 0b00000010 .LEFT = 0b00000100 diff --git a/gbdk-lib/libc/targets/z80/pad_ex.s b/gbdk-lib/libc/targets/z80/pad_ex.s @@ -9,7 +9,15 @@ _joypad_init:: ld hl, #2 add hl, sp ld a, (hl) - and #3 + or a + jr nz, 1$ + ld a, #1 + jr 2$ +1$: + cp #(.JOYPAD_COUNT + 1) + jr c, 2$ + ld a, #.JOYPAD_COUNT +2$: inc hl ld e, (hl) inc hl diff --git a/gbdk-lib/libc/targets/z80/sms/global.s b/gbdk-lib/libc/targets/z80/sms/global.s @@ -114,6 +114,8 @@ .SELECT = 0b01000000 ; map to RESET .START = 0b01000000 ; map to RESET + .JOYPAD_COUNT = 2 + .JOY_PORT1 = 0xDC .JOY_P1_UP = 0b00000001

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