Difference between revisions of "GBDK Joypad Tutorial"

From GbdevWiki
Jump to: navigation, search
m (The joypad() function)
(Oops, move joypad() read inside main loop. Also add wait_vbl_done() instead of using code-blocking delay()s. Fix a tile count bug)
 
(6 intermediate revisions by 3 users not shown)
Line 2: Line 2:
 
This tutorial aims to detail the use of the joypad with GBDK.
 
This tutorial aims to detail the use of the joypad with GBDK.
 
==Tools==
 
==Tools==
You will need GBDK, and any knowledge of C.
+
You will need: [[GBDK]], a text editor, [[Game Boy Tile Designer]], and an emulator ([[BGB]] is recommended for its many debug features), and any level of knowledge of C.
 +
 
 +
Substitute your preferred tools if you want, but this tutorial is assuming you have those listed above.
 +
 
 
==The joypad() function==
 
==The joypad() function==
GBDK's gb.h features a joypad() function that returns the status of the joypad.
+
GBDK's [[gb.h]] features a joypad() function that returns the status of the joypad.
  
 
The joypad() function can return the status of the following inputs:
 
The joypad() function can return the status of the following inputs:
Line 28: Line 31:
 
#include <stdio.h> // include this file for the printf() function
 
#include <stdio.h> // include this file for the printf() function
 
#include <gb/gb.h> // include this file for Game Boy functions
 
#include <gb/gb.h> // include this file for Game Boy functions
 +
#include <stdint.h> // Include this file to use std types such as uint8_t
  
 
void main(void){
 
void main(void){
Line 116: Line 120:
 
<pre>
 
<pre>
 
#include <gb/gb.h> // include this file for Game Boy functions
 
#include <gb/gb.h> // include this file for Game Boy functions
 +
#include <stdint.h> // Include this file to use std types such as uint8_t
  
 
//Created with GBTD, exported to .c with options from: 0, to: 0, label: smile
 
//Created with GBTD, exported to .c with options from: 0, to: 0, label: smile
unsigned char smile[] =
+
const unsigned char smile[] =
 
{
 
{
 
   0x3C,0x3C,0x42,0x42,0x81,0x81,0xA5,0xA5,
 
   0x3C,0x3C,0x42,0x42,0x81,0x81,0xA5,0xA5,
Line 126: Line 131:
 
void main(){
 
void main(){
 
 
int x = 55; // Our beginning x coord
+
uint8_t joydata;
int y = 75; // Our beginning y coord
+
uint8_t x = 55; // Our beginning x coord
 +
uint8_t y = 75; // Our beginning y coord
 
 
 
SPRITES_8x8;
 
SPRITES_8x8;
set_sprite_data(0, 0, smile);
+
 
 +
set_sprite_data(0, 1, smile);
 
set_sprite_tile(0, 0);
 
set_sprite_tile(0, 0);
 
move_sprite(0, x, y); // Move sprite to our predefined x and y coords
 
move_sprite(0, x, y); // Move sprite to our predefined x and y coords
Line 137: Line 144:
  
 
while(1){
 
while(1){
if(joypad()==J_RIGHT) // If RIGHT is pressed
+
joydata = joypad(); // Read once per frame and cache the result
 +
 
 +
if (joydata & J_RIGHT) // If RIGHT is pressed
 
{
 
{
 
x++;
 
x++;
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
delay(10);
 
 
}
 
}
 
 
if(joypad()==J_LEFT)  // If LEFT is pressed
+
if (joydata & J_LEFT)  // If LEFT is pressed
 
{
 
{
 
x--;
 
x--;
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
delay(10);
 
 
}
 
}
 
 
if(joypad()==J_UP)  // If UP is pressed
+
if (joydata & J_UP)  // If UP is pressed
 
{  
 
{  
 
y--;
 
y--;
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
delay(10);
 
 
}
 
}
 
 
if(joypad()==J_DOWN)  // If DOWN is pressed
+
if (joydata & J_DOWN)  // If DOWN is pressed
 
{  
 
{  
 
y++;
 
y++;
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
 
move_sprite(0,x,y); // move sprite 0 to x and y coords
delay(10);
 
 
}
 
}
 +
 +
wait_vbl_done(); // Idle until next frame
 
}
 
}
 +
}
 
</pre>
 
</pre>
 +
 +
==Exercises==
 +
 +
* Try changing the sprite when you press a key or switch directions.
 +
* Use J_START or J_SELECT to "pause" or open a menu.
 +
* Detect three buttons being pressed at once.[http://gbdev.gg8.se/forums/viewtopic.php?id=344]

Latest revision as of 01:06, 24 June 2021

Introduction

This tutorial aims to detail the use of the joypad with GBDK.

Tools

You will need: GBDK, a text editor, Game Boy Tile Designer, and an emulator (BGB is recommended for its many debug features), and any level of knowledge of C.

Substitute your preferred tools if you want, but this tutorial is assuming you have those listed above.

The joypad() function

GBDK's gb.h features a joypad() function that returns the status of the joypad.

The joypad() function can return the status of the following inputs:

J_START
J_SELECT
J_B
J_A
J_DOWN
J_UP
J_LEFT
J_RIGHT

Program 1: Return joypad() status

Program1.gif

Lets write a simple program to return the status of joypad() when a button is pressed:

#include <stdio.h> // include this file for the printf() function
#include <gb/gb.h> // include this file for Game Boy functions
#include <stdint.h> // Include this file to use std types such as uint8_t

void main(void){
	
	while(1) {

	switch(joypad()) {
		
		case J_RIGHT : // If joypad() is equal to RIGHT
			printf("Right!\n");
			delay(100);
			break;
		case J_LEFT : // If joypad() is equal to LEFT
                        printf("Left!\n");
                        delay(100);
			break;
		case J_UP : // If joypad() is equal to UP
			printf("Up!\n");
			delay(100);
			break;
		case J_DOWN : // If joypad() is equal to DOWN
			printf("Down!\n");
			delay(100);
			break;
		case J_START : // If joypad() is equal to START
			printf("Start!\n");
			delay(100);
			break;
		case J_SELECT : // If joypad() is equal to SELECT
			printf("Select!\n");
			delay(100);
			break;
		case J_A : // If joypad() is equal to A
			printf("A!\n");
			delay(100);
			break;
		case J_B : // If joypad() is equal to B
			printf("B!\n");
			delay(100);
			break;			
		default :
			break;
			}
		}
	}

Program 2: Using waitpad() and waitpadup()

Program2.gif

There are also two more joypad functions that you can utilize:

waitpad()  // This function waits for a button to be pressed.
waitpadup() // This function waits for all buttons to be released.

Lets use both the waitpad() function and the waitpadup() function in a simple program:

#include <stdio.h> // include this file for the printf() function
#include <gb/gb.h> // include this file for Game Boy functions

void main(void){
	
	while(1) {

	printf("Please press A\n");
	waitpad(J_A); // waitpad() is waiting for the A button to be pressed.
	printf("You pressed A! Cool!\n\n");
	
	printf("Hold down the LEFT button\n");
	waitpad(J_LEFT); // waitpad() is waiting for the LEFT button to be pressed.
	printf("You're holding down LEFT!\n");
	waitpadup(); // waitpadup() is waiting for all buttons to be depressed but you have to hold down LEFT to get here so it is
                    // waiting on LEFT to be depressed.
	printf("You've released LEFT\n\n\n");
	
		}
	}

Program 3: Moving a sprite on the display

Program3.gif

Now lets use the joypad() function to move a sprite on the screen. If you are inexperienced with GBDK sprites, you will need to view the GBDK Sprite Tutorial.

#include <gb/gb.h> // include this file for Game Boy functions
#include <stdint.h> // Include this file to use std types such as uint8_t

//Created with GBTD, exported to .c with options from: 0, to: 0, label: smile
const unsigned char smile[] =
{
  0x3C,0x3C,0x42,0x42,0x81,0x81,0xA5,0xA5,
  0x81,0x81,0x81,0xA5,0x42,0x5A,0x3C,0x3C
};

void main(){
	
	uint8_t joydata;
	uint8_t x = 55; // Our beginning x coord
	uint8_t y = 75; // Our beginning y coord
	
	SPRITES_8x8;

	set_sprite_data(0, 1, smile);
	set_sprite_tile(0, 0);
	move_sprite(0, x, y); // Move sprite to our predefined x and y coords

	SHOW_SPRITES;

	while(1){
		joydata = joypad(); // Read once per frame and cache the result

		if (joydata & J_RIGHT) // If RIGHT is pressed
		{
			x++;
			move_sprite(0,x,y); // move sprite 0 to x and y coords
		}
		
		if (joydata & J_LEFT)  // If LEFT is pressed
		{
			x--;
			move_sprite(0,x,y); // move sprite 0 to x and y coords
		}
		
		if (joydata & J_UP)  // If UP is pressed
		{ 
			y--;
			move_sprite(0,x,y); // move sprite 0 to x and y coords
		}
		
		if (joydata & J_DOWN)  // If DOWN is pressed
		{ 
			y++;
			move_sprite(0,x,y); // move sprite 0 to x and y coords
		}
	
		wait_vbl_done(); // Idle until next frame
	}
}

Exercises

  • Try changing the sprite when you press a key or switch directions.
  • Use J_START or J_SELECT to "pause" or open a menu.
  • Detect three buttons being pressed at once.[1]