gb: added more presets

This commit is contained in:
Steven Hugg committed 2026-09-11 11:57:12 +02:00
1 parent 85c40450b3
commit e55445fb7b
12 files changed
+1045 -80

No files matched your search

+1 -1
View File
@@ -67,7 +67,7 @@
#ifndef _METASPRITES_H_INCLUDE
#define _METASPRITES_H_INCLUDE
#include <gb/hardware.h>
//#include <gb/hardware.h>
#include "types.h"
#include <stdint.h>
+136
View File
@@ -0,0 +1,136 @@
/*
* gbtext.h - 8x8 text font + helpers for Game Boy presets.
*
* Glyphs are the NES "chr_generic" font (ASCII tiles 0x20-0x7a).
* That font stores two bitplanes: plane 0 is a drop shadow and
* plane 1 is the glyph. Game Boy 2bpp tiles use the same
* color-index layout (index = plane0 | plane1<<1), so the bytes
* are copied verbatim, just interleaved per scanline.
*
* Tile indices equal ASCII codes, so a C string can be written
* straight to the tile map with put_str().
*/
#ifndef GBTEXT_H
#define GBTEXT_H
#include <stdint.h>
#include <string.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#define FONT_TILE_BASE 0x20U
#define FONT_NUM_TILES 91U
const uint8_t font_tiles[FONT_NUM_TILES*16] = {
/*;;{w:8,h:8,bpp:1,count:91,brev:1,np:2,pofs:1,sl:2};;*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3c,0x38,0x3c,0x38,0x3c,0x30,0x38,0x30,0x38,0x30,0x38,0x00,0x38,0x30,0x38,0x00,
0x3c,0x28,0x3c,0x28,0x3c,0x28,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x28,0x7e,0x7c,0x7e,0x28,0x7e,0x7c,0x7e,0x28,0x3c,0x00,0x00,0x00,
0x0c,0x08,0x3f,0x3e,0x3f,0x28,0x3e,0x3c,0x3e,0x14,0x7e,0x7c,0x7e,0x10,0x18,0x00,
0x00,0x00,0x76,0x64,0x7e,0x48,0x7c,0x10,0x3e,0x24,0x7e,0x4c,0x6e,0x00,0x00,0x00,
0x00,0x00,0x38,0x30,0x7c,0x48,0x7c,0x30,0x7e,0x5c,0x7e,0x48,0x7e,0x34,0x3e,0x00,
0x30,0x20,0x30,0x20,0x70,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0e,0x0c,0x1e,0x18,0x3c,0x30,0x38,0x30,0x38,0x30,0x3c,0x18,0x1e,0x0c,0x0e,0x00,
0x70,0x60,0x78,0x30,0x3c,0x18,0x1c,0x18,0x1c,0x18,0x3c,0x30,0x78,0x60,0x70,0x00,
0x00,0x00,0x00,0x00,0x3e,0x3c,0x3e,0x18,0x3e,0x3c,0x3e,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x10,0x18,0x10,0x7e,0x7c,0x7e,0x10,0x18,0x10,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x30,0x38,0x30,0x78,0x60,0x70,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x3c,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x30,0x38,0x30,0x38,0x00,
0x06,0x04,0x0e,0x0c,0x0e,0x08,0x1c,0x18,0x1c,0x10,0x38,0x30,0x38,0x20,0x30,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x1c,0x18,0x3c,0x38,0x3c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x0c,0x3e,0x38,0x7c,0x60,0x7e,0x6c,0x7e,0x7c,0x7e,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x0c,0x3e,0x38,0x3e,0x0c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x7c,0x7e,0x0c,0x0e,0x0c,0x0e,0x0c,0x0e,0x00,
0x7e,0x7c,0x7e,0x6c,0x7e,0x60,0x7c,0x78,0x7e,0x0c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x60,0x7c,0x78,0x7e,0x6c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x7e,0x7c,0x7e,0x6c,0x7e,0x6c,0x7e,0x0c,0x0e,0x0c,0x0e,0x0c,0x0e,0x0c,0x0e,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x6c,0x7e,0x38,0x7e,0x6c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x6c,0x7e,0x3c,0x3e,0x0c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x00,0x00,0x38,0x30,0x38,0x30,0x38,0x00,0x38,0x30,0x38,0x30,0x38,0x00,0x00,0x00,
0x00,0x00,0x38,0x30,0x38,0x30,0x38,0x00,0x38,0x30,0x38,0x30,0x78,0x60,0x70,0x00,
0x0e,0x0c,0x1e,0x18,0x3c,0x30,0x78,0x60,0x78,0x30,0x3c,0x18,0x1e,0x0c,0x0e,0x00,
0x00,0x00,0x00,0x00,0x3e,0x3c,0x3e,0x00,0x3e,0x3c,0x3e,0x00,0x00,0x00,0x00,0x00,
0x70,0x60,0x78,0x30,0x3c,0x18,0x1e,0x0c,0x1e,0x18,0x3c,0x30,0x78,0x60,0x70,0x00,
0x3c,0x38,0x7e,0x6c,0x7e,0x0c,0x1e,0x18,0x3c,0x30,0x38,0x00,0x38,0x30,0x38,0x00,
0x3c,0x38,0x7e,0x44,0x7e,0x5c,0x7e,0x54,0x7e,0x5c,0x7e,0x40,0x7e,0x3c,0x3e,0x00,
0x3e,0x3c,0x7f,0x66,0x77,0x66,0x7f,0x7e,0x7f,0x66,0x77,0x66,0x77,0x66,0x77,0x00,
0x7e,0x7c,0x7f,0x66,0x77,0x66,0x7f,0x7c,0x7f,0x66,0x77,0x66,0x7f,0x7c,0x7e,0x00,
0x3e,0x3c,0x7f,0x66,0x77,0x60,0x70,0x60,0x70,0x60,0x77,0x66,0x7f,0x3c,0x3e,0x00,
0x7c,0x78,0x7e,0x6c,0x7f,0x66,0x77,0x66,0x77,0x66,0x7f,0x6c,0x7e,0x78,0x7c,0x00,
0x7f,0x7e,0x7f,0x60,0x70,0x60,0x7f,0x7e,0x7f,0x60,0x70,0x60,0x7f,0x7e,0x7f,0x00,
0x7f,0x7e,0x7f,0x60,0x70,0x60,0x7c,0x78,0x7c,0x60,0x70,0x60,0x70,0x60,0x70,0x00,
0x3e,0x3c,0x7f,0x66,0x77,0x60,0x7f,0x6e,0x7f,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x00,
0x77,0x66,0x77,0x66,0x77,0x66,0x7f,0x7e,0x7f,0x66,0x77,0x66,0x77,0x66,0x77,0x00,
0x7f,0x7e,0x7f,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x7f,0x7e,0x7f,0x00,
0x07,0x06,0x07,0x06,0x07,0x06,0x07,0x06,0x77,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x00,
0x77,0x66,0x7f,0x6c,0x7e,0x78,0x7c,0x70,0x7c,0x78,0x7e,0x6c,0x7f,0x66,0x77,0x00,
0x70,0x60,0x70,0x60,0x70,0x60,0x70,0x60,0x70,0x60,0x70,0x60,0x7f,0x7e,0x7f,0x00,
0xfe,0xec,0xff,0xfe,0xff,0xd6,0xff,0xd6,0xff,0xc6,0xe7,0xc6,0xe7,0xc6,0xe7,0x00,
0x77,0x66,0x7f,0x76,0x7f,0x7e,0x7f,0x7e,0x7f,0x6e,0x7f,0x66,0x77,0x66,0x77,0x00,
0x3e,0x3c,0x7f,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x00,
0x7e,0x7c,0x7f,0x66,0x77,0x66,0x7f,0x7c,0x7e,0x60,0x70,0x60,0x70,0x60,0x70,0x00,
0x3e,0x3c,0x7f,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x7f,0x6c,0x7f,0x3e,0x3f,0x00,
0x7e,0x7c,0x7f,0x66,0x77,0x66,0x7f,0x7c,0x7e,0x78,0x7e,0x6c,0x7f,0x66,0x77,0x00,
0x3e,0x3c,0x7f,0x66,0x77,0x60,0x7e,0x3c,0x3f,0x06,0x77,0x66,0x7f,0x3c,0x3e,0x00,
0x7f,0x7e,0x7f,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x00,
0x77,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x00,
0x77,0x66,0x77,0x66,0x77,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x3c,0x3e,0x18,0x1c,0x00,
0xe7,0xc6,0xe7,0xc6,0xff,0xd6,0xff,0xd6,0xff,0xd6,0xff,0xfe,0xff,0x6c,0x7e,0x00,
0x77,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x18,0x3e,0x3c,0x7f,0x66,0x77,0x66,0x77,0x00,
0x77,0x66,0x77,0x66,0x77,0x66,0x7f,0x3c,0x3e,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x00,
0x7f,0x7e,0x7f,0x06,0x0f,0x0c,0x1e,0x18,0x3c,0x30,0x78,0x60,0x7f,0x7e,0x7f,0x00,
0x1f,0x1e,0x1f,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1f,0x1e,0x1f,0x00,
0x30,0x20,0x38,0x30,0x38,0x10,0x1c,0x18,0x1c,0x08,0x0e,0x0c,0x0e,0x04,0x06,0x00,
0xf8,0xf0,0xf8,0x30,0x38,0x30,0x38,0x30,0x38,0x30,0x38,0x30,0xf8,0xf0,0xf8,0x00,
0x18,0x10,0x3c,0x38,0x7e,0x6c,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7e,0x7f,0x00,
0x30,0x20,0x30,0x20,0x38,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x38,0x3e,0x0c,0x3e,0x3c,0x7e,0x4c,0x7e,0x34,0x3e,0x00,
0x70,0x60,0x70,0x60,0x7c,0x78,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x78,0x7c,0x00,
0x00,0x00,0x00,0x00,0x3c,0x38,0x7e,0x6c,0x7e,0x60,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x0e,0x0c,0x0e,0x0c,0x3e,0x3c,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x3c,0x3e,0x00,
0x00,0x00,0x00,0x00,0x3c,0x38,0x7e,0x64,0x7e,0x7c,0x7e,0x60,0x7e,0x3c,0x3e,0x00,
0x00,0x00,0x3c,0x38,0x7e,0x6c,0x7e,0x60,0x7c,0x78,0x7c,0x60,0x70,0x60,0x70,0x00,
0x00,0x00,0x00,0x00,0x3e,0x3c,0x7e,0x6c,0x7e,0x3c,0x3e,0x0c,0x7e,0x78,0x7c,0x00,
0x70,0x60,0x70,0x60,0x7c,0x78,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x00,
0x00,0x00,0x1c,0x18,0x1c,0x00,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x00,
0x00,0x00,0x0e,0x0c,0x0e,0x00,0x0e,0x0c,0x0e,0x0c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x70,0x60,0x70,0x60,0x7e,0x6c,0x7e,0x78,0x7c,0x70,0x7c,0x78,0x7e,0x6c,0x7e,0x00,
0x3c,0x38,0x3c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x18,0x1c,0x00,
0x00,0x00,0x00,0x00,0x7e,0x6c,0x7f,0x7e,0x7f,0x56,0x7f,0x66,0x77,0x66,0x77,0x00,
0x00,0x00,0x00,0x00,0x7c,0x78,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x00,
0x00,0x00,0x00,0x00,0x3c,0x38,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x38,0x3c,0x00,
0x00,0x00,0x00,0x00,0x7c,0x78,0x7e,0x6c,0x7e,0x78,0x7c,0x60,0x70,0x60,0x70,0x00,
0x00,0x00,0x00,0x00,0x3e,0x3c,0x7e,0x6c,0x7e,0x3c,0x3e,0x0c,0x0e,0x0c,0x0e,0x00,
0x00,0x00,0x00,0x00,0x7c,0x78,0x7e,0x6c,0x7e,0x60,0x70,0x60,0x70,0x60,0x70,0x00,
0x00,0x00,0x00,0x00,0x3e,0x3c,0x7e,0x60,0x7c,0x38,0x3e,0x0c,0x7e,0x78,0x7c,0x00,
0x00,0x00,0x1c,0x18,0x3e,0x3c,0x3e,0x18,0x1c,0x18,0x1c,0x18,0x1e,0x0c,0x0e,0x00,
0x00,0x00,0x00,0x00,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x34,0x3e,0x00,
0x00,0x00,0x00,0x00,0x7e,0x6c,0x7e,0x6c,0x7e,0x6c,0x7e,0x3c,0x3e,0x18,0x1c,0x00,
0x00,0x00,0x00,0x00,0xe7,0xc6,0xe7,0xc6,0xff,0xd6,0xff,0x7c,0x7e,0x6c,0x7e,0x00,
0x00,0x00,0x00,0x00,0x7e,0x6c,0x7e,0x38,0x3c,0x10,0x3c,0x38,0x7e,0x6c,0x7e,0x00,
0x00,0x00,0x00,0x00,0x7e,0x6c,0x7e,0x6c,0x7e,0x3c,0x3e,0x18,0x7c,0x70,0x78,0x00,
0x00,0x00,0x00,0x00,0x7e,0x7c,0x7e,0x18,0x3c,0x30,0x78,0x60,0x7e,0x7c,0x7e,0x00,
/*;;*/
};
/* load the font into BG tile data (call with the LCD off) */
static void font_init(void) {
set_bkg_data(FONT_TILE_BASE, FONT_NUM_TILES, font_tiles);
}
/* write a string to the tile map; tile index == ASCII code */
static void put_str(uint8_t x, uint8_t y, const char* s) {
set_bkg_tiles(x, y, strlen(s), 1, (uint8_t*)s);
}
/* write a single character to the tile map */
static void put_char(uint8_t x, uint8_t y, char c) {
set_bkg_tiles(x, y, 1, 1, (uint8_t*)&c);
}
#endif
+28 -63
View File
@@ -1,78 +1,43 @@
/*
Hello world for Game Boy.
Set the BG palette, write a message to the tile map,
then turn on the LCD.
Ported from presets/nes/hello.c, using GBDK (gb/gb.h).
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdint.h>
#include <string.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#include "gbtext.h"
#define NUM_TILES 46
// main function, run after console reset
void main(void) {
static const uint8_t font[NUM_TILES*16] = {
/*;;{w:8,h:8,bpp:1,count:46,brev:1,np:2,pofs:1,sl:2};;*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x81,0x81,0x42,0x42,0x24,0x24,0x18,0x18,0x18,0x18,0x24,0x24,0x42,0x42,0x81,0x81
,0x00,0x00,0x24,0x24,0x00,0x00,0x00,0x00,0x24,0x24,0x18,0x18,0x00,0x00,0x00,0x00
,0x00,0x00,0x24,0x24,0x00,0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x00,0x00,0x00,0x00
,0x00,0x00,0x36,0x36,0x49,0x49,0x41,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00
,0x00,0x00,0x00,0x00,0x08,0x08,0x04,0x04,0x7E,0x7E,0x04,0x04,0x08,0x08,0x00,0x00
,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x20,0x7E,0x7E,0x20,0x20,0x10,0x10,0x00,0x00
,0x00,0x00,0x10,0x10,0x38,0x38,0x54,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00
,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x54,0x54,0x38,0x38,0x10,0x10,0x00,0x00
,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x7C,0x7C,0x10,0x10,0x10,0x10,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x06,0x06,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x1E,0x1E,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x02,0x02,0x0C,0x0C,0x02,0x02,0x02,0x02,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x12,0x12,0x12,0x12,0x1E,0x1E,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00
,0x00,0x00,0x1E,0x1E,0x10,0x10,0x1E,0x1E,0x02,0x02,0x02,0x02,0x1E,0x1E,0x00,0x00
,0x00,0x00,0x0C,0x0C,0x10,0x10,0x1C,0x1C,0x12,0x12,0x12,0x12,0x0C,0x0C,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x04,0x04,0x0E,0x0E,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x22,0x22,0x1C,0x1C,0x22,0x22,0x22,0x22,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x1E,0x1E,0x12,0x12,0x1E,0x1E,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00
,0x00,0x00,0x18,0x18,0x24,0x24,0x3C,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x38,0x38,0x24,0x24,0x38,0x38,0x24,0x24,0x24,0x24,0x38,0x38,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x38,0x38,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x38,0x38,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x20,0x20,0x38,0x38,0x20,0x20,0x20,0x20,0x3C,0x3C,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x20,0x20,0x38,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00
,0x00,0x00,0x18,0x18,0x20,0x20,0x2C,0x2C,0x24,0x24,0x24,0x24,0x18,0x18,0x00,0x00
,0x00,0x00,0x24,0x24,0x24,0x24,0x3C,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x38,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x38,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x38,0x38,0x00,0x00
,0x00,0x00,0x24,0x24,0x28,0x28,0x30,0x30,0x28,0x28,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x38,0x00,0x00
,0x00,0x00,0x22,0x22,0x36,0x36,0x2A,0x2A,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00
,0x00,0x00,0x24,0x24,0x34,0x34,0x2C,0x2C,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x18,0x18,0x00,0x00
,0x00,0x00,0x38,0x38,0x24,0x24,0x38,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00
,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x24,0x24,0x24,0x2C,0x2C,0x1C,0x1C,0x02,0x02
,0x00,0x00,0x38,0x38,0x24,0x24,0x38,0x38,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x20,0x20,0x18,0x18,0x04,0x04,0x04,0x04,0x38,0x38,0x00,0x00
,0x00,0x00,0x3E,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00
,0x00,0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x18,0x18,0x00,0x00
,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00
,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x2A,0x2A,0x14,0x14,0x00,0x00
,0x00,0x00,0x22,0x22,0x14,0x14,0x08,0x08,0x08,0x08,0x14,0x14,0x22,0x22,0x00,0x00
,0x00,0x00,0x22,0x22,0x14,0x14,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x3C,0x3C,0x00,0x00
/*;;*/
};
void main(void)
{
// GB can only write VRAM while the LCD is off
DISPLAY_OFF;
memcpy(_VRAM8000, font, sizeof(font)); // copy tile data
memcpy(_SCRN0, font, 32*32); // copy garbage data to screen
BGP_REG = 0xe4; // palette
LCDC_REG = LCDCF_ON|LCDCF_BG8000|LCDCF_BG9800|LCDCF_BGON|LCDCF_OBJ16|LCDCF_OBJON|LCDCF_WIN9C00|LCDCF_WINOFF;
// background palette: color 0 = white, 1 = light, 2 = dark, 3 = black
BGP_REG = 0xE4;
OBP0_REG = OBP1_REG = 0xE4;
// copy the 8x8 font into BG tile data
font_init();
// write text to the tile map (tile index == ASCII code)
put_str(2, 2, "HELLO, WORLD!");
// enable the background layer, then the LCD
SHOW_BKG;
DISPLAY_ON;
// Loop forever
while(1) {
// Game main loop processing goes here
// Done processing, yield CPU and wait for start of next frame
// infinite loop
while (1) {
wait_vbl_done();
}
}
+86
View File
@@ -0,0 +1,86 @@
/*
Metasprites combine several hardware sprites to make a larger
sprite. Our demo uses 4 hardware sprites in a 2x2 pattern,
forming 16x16 pixel sprites.
Ported from presets/nes/metasprites.c, using GBDK (gb/metasprites.h).
The Game Boy OAM holds 40 sprites, so 10 actors of 4 sprites each
fit on screen (the NES fits 16).
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdint.h>
#include <stdlib.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#include "gb/metasprites.h"
#include "gbtext.h"
///// METASPRITES
// a 2x2 metasprite made from four font tiles
#define TILE 0x21
const metasprite_t metasprite[] = {
METASPR_ITEM(0, 0, TILE+0, 0),
METASPR_ITEM(0, 8, TILE+1, 0),
METASPR_ITEM(8, 0, TILE+2, 0),
METASPR_ITEM(8, 8, TILE+3, 0),
METASPR_TERM
};
// number of actors (4 h/w sprites each; 10 * 4 = 40 sprites)
#define NUM_ACTORS 10
// actor x/y positions
uint8_t actor_x[NUM_ACTORS];
uint8_t actor_y[NUM_ACTORS];
// actor x/y deltas per frame (signed)
int8_t actor_dx[NUM_ACTORS];
int8_t actor_dy[NUM_ACTORS];
// setup LCD and tile data
void setup_graphics(void) {
DISPLAY_OFF;
BGP_REG = OBP0_REG = OBP1_REG = 0xE4;
LCDC_REG |= LCDCF_BG8000;
font_init();
SHOW_BKG;
SHOW_SPRITES;
DISPLAY_ON;
}
// main program
void main(void) {
uint8_t i; // actor index
// initialize PPU
setup_graphics();
// initialize actors with random values
for (i=0; i<NUM_ACTORS; i++) {
actor_x[i] = rand();
actor_y[i] = rand();
actor_dx[i] = (rand() & 7) - 3;
actor_dy[i] = (rand() & 7) - 3;
}
// loop forever
while (1) {
uint8_t base = 0; // first free sprite ID
// draw and move all actors
for (i=0; i<NUM_ACTORS; i++) {
base += move_metasprite(metasprite, FONT_TILE_BASE, base,
actor_x[i], actor_y[i]);
actor_x[i] += actor_dx[i];
actor_y[i] += actor_dy[i];
}
// hide rest of sprites
hide_sprites_range(base, 40);
// wait for next frame
wait_vbl_done();
}
}
+174
View File
@@ -0,0 +1,174 @@
/*
* A simple music player for Game Boy.
*
* Port of presets/nes/music.c, which drives two pulse channels and a
* triangle (bass) channel from a compact note stream. The Game Boy has
* two pulse channels and a wave channel, so the triangle maps to the
* wave channel and the same score plays on two pulses + wave.
*
* Score format (identical to the NES version):
* byte < 0x80 a note number (index into the period tables below)
* byte >= 0x80 end of chord; low 6 bits = duration in frames
* 0xff end of score
*
* Notes < BASS_NOTE go to the wave channel, the rest to the pulses,
* exactly like the NES player routes low notes to the triangle.
*
* "The Easy Winners" by Scott Joplin.
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdint.h>
#include <string.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#include "gbtext.h"
typedef uint8_t byte;
typedef uint16_t word;
#define BASS_NOTE 36
/* Note indices match the NES score: MIDI note = index + 20.
* Pulse periods are 11-bit: f = 131072 / (2048 - X). Indices below 16
* are under the pulse channel's range and clamp to X = 0. */
const word note_table_pulse[64] = {
0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
0x02c,0x09d,0x107,0x16b,0x1c9,0x223,0x277,0x2c7,
0x312,0x358,0x39b,0x3da,0x416,0x44e,0x483,0x4b5,
0x4e5,0x511,0x53b,0x563,0x589,0x5ac,0x5ce,0x5ed,
0x60b,0x627,0x642,0x65b,0x672,0x689,0x69e,0x6b2,
0x6c4,0x6d6,0x6e7,0x6f7,0x706,0x714,0x721,0x72d,
0x739,0x744,0x74f,0x759,0x762,0x76b,0x773,0x77b,
};
/* Wave-channel periods: f = 65536 / (2048 - X). The wave channel goes
* an octave lower than the pulses, so it covers the low bass notes. */
const word note_table_wave[64] = {
0x000,0x000,0x000,0x000,0x02c,0x09d,0x107,0x16b,
0x1c9,0x223,0x277,0x2c7,0x312,0x358,0x39b,0x3da,
0x416,0x44e,0x483,0x4b5,0x4e5,0x511,0x53b,0x563,
0x589,0x5ac,0x5ce,0x5ed,0x60b,0x627,0x642,0x65b,
0x672,0x689,0x69e,0x6b2,0x6c4,0x6d6,0x6e7,0x6f7,
0x706,0x714,0x721,0x72d,0x739,0x744,0x74f,0x759,
0x762,0x76b,0x773,0x77b,0x783,0x78a,0x790,0x797,
0x79d,0x7a2,0x7a7,0x7ac,0x7b1,0x7b6,0x7ba,0x7be,
};
/* 32-sample triangle waveform, two 4-bit samples per byte. */
const uint8_t wave_pattern[16] = {
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
};
byte cur_duration = 0;
byte chs = 0; /* channels assigned for the current chord */
const byte* music_ptr = 0;
extern const byte music1[]; /* score -- see end of file */
byte next_music_byte(void) {
return *music_ptr++;
}
void psg_init(void) {
byte i;
NR52_REG = 0x80; /* sound on */
NR51_REG = 0xFF; /* all channels to both outputs */
NR50_REG = 0x77; /* master volume */
NR10_REG = 0x00; /* pulse 1 sweep off */
/* load wave RAM with the wave DAC off */
NR30_REG = 0x00;
for (i = 0; i < 16; i++) _AUD3WAVERAM[i] = wave_pattern[i];
NR32_REG = 0x20; /* wave output level 100% */
}
void gb_pulse_note(byte ch, word period, byte vol) {
byte lo = (byte)(period & 0xff);
byte hi = (byte)((period >> 8) & 0x07);
byte env = (byte)((vol << 4) | 0x02); /* decay envelope from vol */
if (ch == 0) {
NR11_REG = 0x80; /* 50% duty */
NR12_REG = env;
NR13_REG = lo;
NR14_REG = (byte)(0x80 | hi); /* trigger */
} else {
NR21_REG = 0x80;
NR22_REG = env;
NR23_REG = lo;
NR24_REG = (byte)(0x80 | hi); /* trigger */
}
}
void gb_wave_note(word period) {
NR30_REG = 0x80; /* wave DAC on */
NR31_REG = 0x00; /* length (unused) */
NR32_REG = 0x20; /* 100% volume */
NR33_REG = (byte)(period & 0xff);
NR34_REG = (byte)(0x80 | ((period >> 8) & 0x07)); /* trigger */
}
void play_music(void) {
if (music_ptr) {
/* run out the duration timer, fetching notes as needed */
while (cur_duration == 0) {
byte note = next_music_byte();
if ((note & 0x80) == 0) {
/* pulses play higher notes, wave handles the low bass */
if (note >= BASS_NOTE || (chs & 4)) {
word period = note_table_pulse[note & 63];
/* use whichever pulse generator is free */
if (!(chs & 1)) {
gb_pulse_note(0, period, 15);
chs |= 1;
} else if (!(chs & 2)) {
gb_pulse_note(1, period, 15);
chs |= 2;
}
} else {
gb_wave_note(note_table_wave[note & 63]);
chs |= 4;
}
} else {
/* end of chord: set duration and free every channel */
if (note == 0xff) music_ptr = 0;
cur_duration = note & 63;
chs = 0;
}
}
cur_duration--;
}
}
void start_music(const byte* music) {
music_ptr = music;
cur_duration = 0;
chs = 0;
}
void main(void) {
/* title screen (LCD off while writing tiles and the tile map) */
DISPLAY_OFF;
BGP_REG = 0xE4;
OBP0_REG = OBP1_REG = 0xE4;
font_init();
put_str(1, 7, "THE EASY WINNERS");
put_str(4, 9, "SCOTT JOPLIN");
SHOW_BKG;
DISPLAY_ON;
psg_init();
music_ptr = 0;
while (1) {
if (!music_ptr) start_music(music1);
wait_vbl_done();
play_music();
}
}
const byte music1[] = {
0x2a,0x1e,0x95,0x33,0x27,0x9f,0x31,0x25,0x8a,0x2f,0x23,0x8b,0x2e,0x22,0x89,0x2c,0x20,0x8b,0x2a,0x1e,0x95,0x28,0x1c,0x8a,0x27,0x1b,0x95,0x25,0x19,0x8b,0x23,0x17,0x89,0x22,0x12,0x8b,0x23,0x8a,0x25,0x8b,0x27,0x89,0x28,0x1e,0x8c,0x2a,0x1c,0x89,0x2c,0x1b,0x8c,0x2e,0x19,0x89,0x2f,0x17,0x95,0x27,0x23,0x1e,0x95,0x12,0x95,0x23,0x1e,0x27,0x95,0x2f,0x33,0x17,0x95,0x2f,0x33,0x27,0x94,0x12,0x95,0x33,0x36,0x23,0x95,0x38,0x32,0x17,0x8b,0x33,0x36,0x89,0x1e,0x27,0x23,0x8b,0x38,0x32,0x8a,0x33,0x36,0x12,0x8b,0x32,0x38,0x89,0x36,0x33,0x27,0x95,0x3d,0x37,0x10,0x8b,0x3b,0x38,0x8a,0x20,0x23,0x28,0x8b,0x37,0x3d,0x89,0x38,0x3b,0x10,0x8b,0x37,0x3d,0x8a,0x3b,0x38,0x28,0x8b,0x36,0x33,0x8a,0x17,0x95,0x2a,0x1e,0x23,0x8b,0x2c,0x89,0x2e,0x12,0x8b,0x2f,0x8a,0x31,0x27,0x23,0x8b,0x32,0x89,0x2f,0x33,0x17,0x95,0x33,0x2f,0x1e,0x95,0x12,0x94,0x36,0x33,0x1e,0x95,0x32,0x38,0x17,0x8b,0x36,0x33,0x89,0x23,0x1e,0x27,0x8b,0x38,0x32,0x8a,0x33,0x36,0x18,0x8b,0x33,0x36,0x8a,0x33,0x36,0x2a,0x95,0x36,0x19,0x8b,0x31,0x2e,0x89,0x25,0x22,0x2a,0x8b,0x36,0x8a,0x2f,0x35,0x19,0x8b,0x36,0x89,0x38,0x2f,0x29,0x95,0x2e,0x36,0x1e,0x95,0x1c,0x28,0x95,0x27,0x1b,0x8b,0x2a,0x8a,0x2e,0x25,0x19,0x8b,0x34,0x89,0x33,0x2f,0x23,0x95,0x33,0x2f,0x1e,0x95,0x12,0x94,0x33,0x36,0x23,0x95,0x32,0x38,0x17,0x8b,0x33,0x36,0x8a,0x23,0x27,0x1e,0x8b,0x38,0x32,0x89,0x36,0x33,0x12,0x8b,0x32,0x38,0x8a,0x33,0x36,0x1e,0x94,0x37,0x3d,0x10,0x8b,0x3b,0x38,0x8a,0x23,0x28,0x20,0x8b,0x3d,0x37,0x89,0x3b,0x38,0x1c,0x8b,0x38,0x3b,0x8a,0x3a,0x3d,0x38,0x8b,0x3f,0x37,0x3a,0x89,0x27,0x1b,0x8b,0x33,0x8a,0x37,0x22,0x16,0x8b,0x3a,0x8a,0x3f,0x0f,0x1b,0x95,0x3a,0x8b,0x3b,0x8a,0x3d,0x37,0x1c,0x8b,0x3b,0x38,0x89,0x23,0x28,0x20,0x8b,0x3d,0x37,0x8a,0x38,0x3b,0x10,0x8b,0x3d,0x37,0x89,0x38,0x3b,0x20,0x8b,0x36,0x33,0x8a,0x17,0x23,0x8b,0x38,0x34,0x8a,0x33,0x36,0x1e,0x8b,0x31,0x34,0x8a,0x2f,0x33,0x17,0x8b,0x36,0x33,0x8a,0x23,0x27,0x1e,0x8b,0x33,0x36,0x8a,0x36,0x30,0x12,0x8a,0x34,0x31,0x8a,0x1e,0x28,0x22,0x8b,0x30,0x36,0x89,0x34,0x31,0x12,0x8b,0x2e,0x28,0x33,0x8a,0x31,0x28,0x2e,0x95,0x27,0x2f,0x1e,0x95,0x12,0x95,0x14,0x94,0x16,0x95,0x2f,0x33,0x17,0x95,0x2f,0x33,0x27,0x94,0x12,0x95,0x36,0x33,0x23,0x95,0x32,0x38,0x17,0x8a,0x33,0x36,0x8a,0x23,0x27,0x1e,0x8b,0x32,0x38,0x8a,0x33,0x36,0x12,0x8b,0x38,0x32,0x8a,0x36,0x33,0x27,0x95,0x3d,0x37,0x10,0x8a,0x3b,0x38,0x8a,0x23,0x28,0x20,0x8b,0x37,0x3d,0x89,0x3b,0x38,0x10,0x8b,0x37,0x3d,0x8a,0x38,0x3b,0x23,0x8b,0x36,0x33,0x8a,0x17,0x95,0x2a,0x1e,0x23,0x8b,0x2c,0x8a,0x2e,0x12,0x8b,0x2f,0x89,0x31,0x23,0x1e,0x8b,0x32,0x8a,0x33,0x2f,0x17,0x95,0x2f,0x33,0x1e,0x94,0x12,0x95,0x36,0x33,0x27,0x95,0x38,0x32,0x17,0x8a,0x36,0x33,0x8a,0x23,0x1e,0x27,0x8b,0x38,0x32,0x89,0x33,0x36,0x18,0x8c,0x36,0x33,0x89,0x33,0x36,0x21,0x95,0x36,0x19,0x8b,0x2e,0x31,0x8a,0x25,0x2a,0x22,0x8b,0x36,0x89,0x35,0x2f,0x19,0x8b,0x36,0x8a,0x2f,0x38,0x25,0x94,0x36,0x2e,0x2a,0x95,0x1c,0x28,0x95,0x27,0x1b,0x8c,0x2a,0x89,0x2e,0x25,0x19,0x8b,0x34,0x8a,0x33,0x2f,0x23,0x95,0x2f,0x33,0x1e,0x94,0x12,0x95,0x33,0x36,0x23,0x95,0x32,0x38,0x17,0x8a,0x33,0x36,0x8a,0x23,0x1e,0x27,0x8b,0x32,0x38,0x89,0x36,0x33,0x12,0x8c,0x32,0x38,0x89,0x33,0x36,0x1e,0x95,0x37,0x3d,0x10,0x8b,0x3b,0x38,0x8a,0x23,0x20,0x28,0x8a,0x3d,0x37,0x8a,0x38,0x3b,0x1c,0x8b,0x3b,0x38,0x8a,0x3d,0x38,0x3a,0x8b,0x3a,0x3f,0x37,0x89,0x27,0x1b,0x8b,0x33,0x8a,0x37,0x22,0x16,0x8b,0x3a,0x8a,0x3f,0x0f,0x1b,0x95,0x3a,0x8b,0x3b,0x8a,0x3d,0x37,0x1c,0x8b,0x3b,0x38,0x8a,0x20,0x28,0x23,0x8b,0x3d,0x37,0x89,0x38,0x3b,0x10,0x8b,0x3d,0x37,0x8a,0x38,0x3b,0x20,0x8b,0x33,0x36,0x89,0x17,0x23,0x8b,0x38,0x34,0x8a,0x36,0x33,0x23,0x8b,0x34,0x31,0x89,0x2f,0x33,0x17,0x8c,0x36,0x33,0x89,0x1e,0x27,0x23,0x8c,0x33,0x36,0x89,0x36,0x30,0x12,0x8b,0x34,0x31,0x8a,0x1e,0x28,0x22,0x8a,0x30,0x36,0x8a,0x34,0x31,0x1e,0x8b,0x28,0x2e,0x33,0x89,0x28,0x31,0x2e,0x95,0x27,0x2f,0x17,0x95,0x12,0x1e,0x95,0x3b,0x36,0x33,0x96,0x2a,0x8b,0x2b,0x8a,0x2c,0x1e,0x12,0x8b,0x2d,0x89,0x2e,0x28,0x1e,0x8b,0x2e,0x31,0x8a,0x16,0x22,0x8b,0x36,0x89,0x34,0x1e,0x22,0x8b,0x31,0x8a,0x2c,0x25,0x19,0x8b,0x2d,0x89,0x2e,0x28,0x25,0x8b,0x33,0x2e,0x8a,0x25,0x19,0x8c,0x31,0x89,0x2c,0x1a,0x26,0x8b,0x2e,0x8a,0x2f,0x1b,0x27,0x8b,0x2a,0x89,0x2c,0x23,0x1e,0x8b,0x2e,0x8a,0x2f,0x12,0x1e,0x8b,0x30,0x89,0x31,0x27,0x23,0x8b,0x32,0x8a,0x33,0x17,0x23,0x8b,0x32,0x8a,0x33,0x1e,0x23,0x8b,0x38,0x33,0x8a,0x1e,0x12,0x8b,0x36,0x8a,0x31,0x1e,0x23,0x8b,0x33,0x89,0x34,0x25,0x19,0x8b,0x3d,0x89,0x1e,0x28,0x22,0x8b,0x33,0x89,0x34,0x12,0x1e,0x8b,0x3d,0x8a,0x1e,0x22,0x28,0x8a,0x33,0x8a,0x34,0x19,0x25,0x8b,0x3d,0x89,0x28,0x1e,0x22,0x8b,0x3b,0x89,0x3a,0x1e,0x12,0x8b,0x38,0x8a,0x36,0x22,0x16,0x8b,0x34,0x8a,0x33,0x23,0x17,0x8b,0x3b,0x8a,0x1e,0x23,0x27,0x8a,0x32,0x8a,0x33,0x12,0x1e,0x8b,0x3b,0x89,0x27,0x23,0x1e,0x8b,0x32,0x89,0x33,0x23,0x17,0x8b,0x3b,0x89,0x1e,0x23,0x27,0x8b,0x38,0x8a,0x36,0x12,0x1e,0x8b,0x33,0x89,0x31,0x1e,0x27,0x8b,0x2f,0x8a,0x2e,0x20,0x14,0x8b,0x2f,0x8a,0x30,0x2a,0x24,0x8b,0x30,0x38,0x8a,0x24,0x18,0x8b,0x36,0x89,0x33,0x24,0x20,0x8b,0x30,0x8a,0x2e,0x27,0x1b,0x8b,0x2f,0x89,0x30,0x24,0x2a,0x8b,0x30,0x38,0x8a,0x20,0x14,0x8b,0x33,0x36,0x8a,0x38,0x30,0x24,0x8b,0x33,0x36,0x89Line truncated
};
+58
View File
@@ -0,0 +1,58 @@
/*
Scrolling demo for Game Boy.
The background tile map is 32x32 tiles (256x256 pixels) and
wraps around, so the scroll registers can move anywhere in it.
We put text at the top, middle and bottom rows and scroll the
view up and down through the whole map.
Ported from presets/nes/scroll.c, using GBDK (gb/gb.h).
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdint.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#include "gbtext.h"
// scroll the window up and down until the end
void scroll_demo(void) {
int y = 0; // y scroll position
int dy = 1; // y scroll direction
// infinite loop
while (1) {
// wait for next frame
wait_vbl_done();
// update y variable
y += dy;
// change direction when hitting either edge of scroll area
if (y >= 255) dy = -1;
if (y == 0) dy = 1;
// set the Y scroll register
SCY_REG = y;
}
}
// main function, run after console reset
void main(void) {
DISPLAY_OFF;
// background palette: color 0 = white, 1 = light, 2 = dark, 3 = black
BGP_REG = 0xE4;
font_init();
// write text to the tile map
put_str(2, 0, "Tile map row 0");
put_str(2, 15, "Tile map row 15");
put_str(2, 29, "Tile map row 29");
// enable rendering
SHOW_BKG;
DISPLAY_ON;
// scroll the view back and forth
scroll_demo();
}
+357
View File
@@ -0,0 +1,357 @@
/*
Siege for Game Boy — port of presets/nes/siegegame.c.
A character-based surround-the-opponent game. Two players (one
human, one AI) leave trails that box each other in; the first
one to hit a wall, a trail, or the other player loses the round.
Porting notes:
- The NES version reads the nametable back from the PPU to
detect collisions and steer the AI (see getchar()). On the
Game Boy VRAM can only be accessed during VBlank, so we keep
a shadow copy of the playfield in RAM instead.
- Text uses the gbtext.h font (tile index == ASCII code), so
strings can be written straight to the tile map.
- The NES draws player tails as colored tiles; here we use two
custom dither tiles (light for player 1, dark for player 2)
appended after the font tiles.
- Flashing colliding players reuses the NES trick of XORing the
head tile index with 0x80: tiles 0x80 and up are blank, so
the head alternates between visible and hidden.
- Playfield is cropped to 20x17 tiles to fit the GB screen.
Controls: D-pad moves player 1, Start starts the game.
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#include "gbtext.h"
typedef uint8_t byte;
typedef uint16_t word;
// screen is 20x18 tiles; leave the bottom row blank
#define COLS 20
#define ROWS 17
////////// GAME DATA
typedef struct {
byte x;
byte y;
byte dir;
word score;
char head_attr;
char tail_attr;
int collided:1;
int human:1;
} Player;
Player players[2];
byte attract;
byte gameover;
byte frames_per_move;
// shadow copy of the tile map, for collision checks and AI
// (GB VRAM can only be read during VBlank, so mirror in RAM)
byte playfield[COLS*ROWS];
#define START_SPEED 12
#define MAX_SPEED 5
#define MAX_SCORE 7
// two custom tail tiles appended after the font tiles
// (the NES version uses two colored tiles for the tails)
#define TAIL_TILE_P1 (FONT_TILE_BASE + FONT_NUM_TILES) // 0x7b
#define TAIL_TILE_P2 (FONT_TILE_BASE + FONT_NUM_TILES + 1) // 0x7c
// three custom tiles for the border
#define BORDER_LR (FONT_TILE_BASE + FONT_NUM_TILES + 2) // 0x7d
#define BORDER_UD (FONT_TILE_BASE + FONT_NUM_TILES + 3) // 0x7e
#define BORDER_CORNER (FONT_TILE_BASE + FONT_NUM_TILES + 4) // 0x7f
// blank tile used to clear tiles 0x80-0xff (see init)
const uint8_t zero_tile[16] = {0};
// tail tiles: dark checkerboard (player 1), light (player 2)
const uint8_t tail_tiles[5*16] = {
/*;;{w:8,h:8,bpp:1,count:5,brev:1,np:2,pofs:1,sl:2};;*/
0x55,0x55,0xAA,0xAA, 0x55,0x55,0xAA,0xAA,
0x55,0x55,0xAA,0xAA, 0x55,0x55,0xAA,0xAA,
0x55,0x00,0xAA,0x00, 0x55,0x00,0xAA,0x00,
0x55,0x00,0xAA,0x00, 0x55,0x00,0xAA,0x00,
0x00,0x00,0x00,0xFF, 0x55,0x00,0xAA,0x00,
0x55,0x00,0xAA,0x00, 0x00,0xFF,0x00,0x00,
0x14,0x42,0x28,0x42, 0x14,0x42,0x28,0x42,
0x14,0x42,0x28,0x42, 0x14,0x42,0x28,0x42,
0x00,0xFF,0x2A,0x81, 0x54,0x81,0x2A,0x81,
0x54,0x81,0x2A,0x81, 0x54,0x81,0x00,0xFF,
/*;;*/
};
////////// TEXT ROUTINES
// read a playfield character: from the shadow buffer,
// no VBlank tricks needed (unlike the NES nametable read)
byte getchar(byte x, byte y) {
return playfield[y*COLS+x];
}
void cputcxy(byte x, byte y, char ch) {
put_char(x, y, ch);
// keep shadow buffer in sync with the screen
playfield[y*COLS+x] = ch;
}
void cputsxy(byte x, byte y, const char* str) {
byte i;
for (i=0; str[i]; i++)
cputcxy(x+i, y, str[i]);
}
void clrscr() {
byte x, y;
memset(playfield, 0, sizeof(playfield));
// fill the visible tile map with spaces
for (y=0; y<ROWS; y++)
for (x=0; x<COLS; x++)
put_char(x, y, ' ');
}
///////////
const char BOX_CHARS[8] = {
BORDER_CORNER,
BORDER_CORNER,
BORDER_CORNER,
BORDER_CORNER,
BORDER_LR,
BORDER_LR,
BORDER_UD,
BORDER_UD,
};
void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
byte x1 = x;
cputcxy(x, y, chars[2]);
cputcxy(x2, y, chars[3]);
cputcxy(x, y2, chars[0]);
cputcxy(x2, y2, chars[1]);
while (++x < x2) {
cputcxy(x, y, chars[5]);
cputcxy(x, y2, chars[4]);
}
while (++y < y2) {
cputcxy(x1, y, chars[6]);
cputcxy(x2, y, chars[7]);
}
}
void draw_playfield() {
draw_box(1,2,COLS-2,ROWS-1,BOX_CHARS);
if (attract) {
cputsxy(4,ROWS-1,"PRESS START");
} else {
cputsxy(1,1,"P1:");
cputcxy(4,1,players[0].score+'0');
cputsxy(13,1,"P2:");
cputcxy(16,1,players[1].score+'0');
}
}
typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t;
const char DIR_X[4] = { 1, 0, -1, 0 };
const char DIR_Y[4] = { 0, 1, 0, -1 };
void init_game() {
memset(players, 0, sizeof(players));
players[0].head_attr = '1';
players[1].head_attr = '2';
players[0].tail_attr = TAIL_TILE_P1;
players[1].tail_attr = TAIL_TILE_P2;
frames_per_move = START_SPEED;
}
void reset_players() {
players[0].x = players[0].y = 5;
players[0].dir = D_RIGHT;
players[1].x = COLS-6;
players[1].y = ROWS-6;
players[1].dir = D_LEFT;
players[0].collided = players[1].collided = 0;
}
void draw_player(Player* p) {
cputcxy(p->x, p->y, p->head_attr);
}
void move_player(Player* p) {
cputcxy(p->x, p->y, p->tail_attr);
p->x += DIR_X[p->dir];
p->y += DIR_Y[p->dir];
if (getchar(p->x, p->y) != 0)
p->collided = 1;
draw_player(p);
}
void human_control(Player* p) {
byte dir = 0xff;
byte joy = joypad();
// start game if attract mode
if (attract && (joy & J_START))
gameover = 1;
// do not allow movement unless human player
if (!p->human) return;
if (joy & J_LEFT) dir = D_LEFT;
if (joy & J_RIGHT) dir = D_RIGHT;
if (joy & J_UP) dir = D_UP;
if (joy & J_DOWN) dir = D_DOWN;
// don't let the player reverse
if (dir < 0x80 && dir != (p->dir ^ 2)) {
p->dir = dir;
}
}
byte ai_try_dir(Player* p, dir_t dir, byte shift) {
byte x,y;
dir &= 3;
x = p->x + (DIR_X[dir] << shift);
y = p->y + (DIR_Y[dir] << shift);
if (x < COLS && y < ROWS && getchar(x, y) == 0) {
p->dir = dir;
return 1;
} else {
return 0;
}
}
void ai_control(Player* p) {
dir_t dir;
if (p->human) return;
dir = p->dir;
if (!ai_try_dir(p, dir, 0)) {
ai_try_dir(p, dir+1, 0);
ai_try_dir(p, dir-1, 0);
} else {
ai_try_dir(p, dir-1, 0) && ai_try_dir(p, dir-1, 1+(rand() & 3));
ai_try_dir(p, dir+1, 0) && ai_try_dir(p, dir+1, 1+(rand() & 3));
ai_try_dir(p, dir, rand() & 3);
}
}
void flash_colliders() {
byte i;
// flash players that collided by toggling the head tile
// between the glyph and the blank tile 0x80 up
for (i=0; i<56; i++) {
wait_vbl_done(); // head draws happen right after VBlank
if (players[0].collided) players[0].head_attr ^= 0x80;
if (players[1].collided) players[1].head_attr ^= 0x80;
draw_player(&players[0]);
draw_player(&players[1]);
wait_vbl_done(); // two frames per flash, like the NES version
}
// even number of flashes leaves head_attr restored
}
void make_move() {
byte i;
for (i=0; i<frames_per_move; i++) {
human_control(&players[0]);
wait_vbl_done(); // pace one move every frames_per_move frames
}
ai_control(&players[0]);
ai_control(&players[1]);
// if players collide, 2nd player gets the point
// (draws happen right after the last VBlank above)
move_player(&players[1]);
move_player(&players[0]);
}
void declare_winner(byte winner) {
byte i;
clrscr();
// draw nested boxes closing in on the center
for (i=0; i<ROWS/2-3; i++) {
draw_box(i,i,COLS-1-i,ROWS-1-i,BOX_CHARS);
wait_vbl_done();
}
cputsxy(6,10,"WINNER:");
cputsxy(6,13,"PLAYER ");
cputcxy(6+7, 13, '1'+winner);
// ~1.25 seconds (NES delay() counts frames)
for (i=0; i<75; i++) wait_vbl_done();
gameover = 1;
}
void play_round() {
display_off();
clrscr();
draw_playfield();
reset_players();
DISPLAY_ON;
while (1) {
make_move();
if (gameover) return; // attract mode -> start
if (players[0].collided || players[1].collided) break;
}
flash_colliders();
// add scores to players that didn't collide
if (players[0].collided) players[1].score++;
if (players[1].collided) players[0].score++;
// increase speed
if (frames_per_move > MAX_SPEED) frames_per_move--;
// game over?
if (players[0].score != players[1].score) {
if (players[0].score >= MAX_SCORE)
declare_winner(0);
else if (players[1].score >= MAX_SCORE)
declare_winner(1);
}
}
void play_game() {
gameover = 0;
init_game();
if (!attract)
players[0].human = 1;
while (!gameover) {
play_round();
}
}
void main() {
byte i, x, y;
DISPLAY_OFF;
// unsigned tile indexing so ASCII codes work; must be set before
// set_bkg_data(), which uses it to pick the VRAM tile base
LCDC_REG |= LCDCF_BG8000;
// load font (tiles 0x20-0x7a, tile index == ASCII) + tail tiles
font_init();
set_bkg_data(TAIL_TILE_P1, sizeof(tail_tiles)/16, tail_tiles);
// clear tiles 0x80-0xff so head_attr^0x80 flashing shows blank
for (i=0x80; i!=0; i++)
set_bkg_data(i, 1, zero_tile);
// 4-shade palette
BGP_REG = 0xE4;
// fill the tile map with spaces
for (y=0; y<ROWS; y++)
for (x=0; x<COLS; x++)
put_char(x, y, ' ');
SHOW_BKG;
DISPLAY_ON;
while (1) {
attract = 1;
play_game();
attract = 0;
play_game();
}
}
+75
View File
@@ -0,0 +1,75 @@
/*
Sprite demo for Game Boy.
Animate all 40 hardware sprites (the Game Boy OAM holds 40,
where the NES has 64).
Ported from presets/nes/sprites.c, using GBDK (gb/gb.h).
The font tiles loaded for the background live at 0x8000, which
is the same tile data the objects use, so we can point the
sprites at them too.
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdint.h>
#include <stdlib.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#include "gbtext.h"
// number of actors
#define NUM_ACTORS 40 // 40 sprites (Game Boy maximum)
// actor x/y positions
uint8_t actor_x[NUM_ACTORS]; // horizontal coordinates
uint8_t actor_y[NUM_ACTORS]; // vertical coordinates
// actor x/y deltas per frame (signed)
int8_t actor_dx[NUM_ACTORS]; // horizontal velocity
int8_t actor_dy[NUM_ACTORS]; // vertical velocity
// setup LCD and tile data
void setup_graphics(void) {
DISPLAY_OFF;
// 4-shade palettes (index 0 is transparent for objects)
BGP_REG = OBP0_REG = OBP1_REG = 0xE4;
// use 0x8000 for BG tile data so background and objects
// share the same font tiles
LCDC_REG |= LCDCF_BG8000;
// load the font tiles at 0x8000 (shared by BG and objects)
font_init();
SHOW_BKG;
SHOW_SPRITES;
DISPLAY_ON;
}
// main program
void main(void) {
uint8_t i; // actor index
// initialize actors with random values
for (i=0; i<NUM_ACTORS; i++) {
actor_x[i] = rand();
actor_y[i] = rand();
actor_dx[i] = (rand() & 7) - 3;
actor_dy[i] = (rand() & 7) - 3;
}
setup_graphics();
// loop forever
while (1) {
// draw and move all actors
for (i=0; i<NUM_ACTORS; i++) {
set_sprite_tile(i, FONT_TILE_BASE + i);
move_sprite(i, actor_x[i], actor_y[i]);
actor_x[i] += actor_dx[i];
actor_y[i] += actor_dy[i];
}
// wait for next frame
wait_vbl_done();
}
}
+22 -4
View File
@@ -1,4 +1,20 @@
/*
Drawing primitives demo for Game Boy.
Uses the GBDK pixel plotting library (gb/drawing.h) to draw
characters, circles, boxes, and lines in the various draw
modes (SOLID, XOR) and foreground/background colors.
No font data is included in this file. The characters drawn by
gprintf()/gotogxy() use the 256-character IBM fixed-width font
(font_ibm_fixed) compiled into the GBDK drawing library, which
is linked in automatically via gb.lib.
The last section scrolls the whole screen by replotting every
pixel one row up at a time. This is slow, since each call to
plot_point() reads and writes a byte of pixel memory.
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
@@ -9,18 +25,19 @@
#include "gb/gb.h"
#include "gb/drawing.h"
// draw a starburst of lines radiating from (x,y)
void linetest(uint8_t x, uint8_t y, uint8_t w) {
color(DKGREY,WHITE,SOLID);
for (int i = -w; i <= w; i++) line(x,y,x+i,y-w);
for (int i = -w; i <= w; i++) line(x,y,x+w,y+i);
for (int i = -w; i <= w; i++) line(x,y,x+i,y+w);
for (int i = -w; i <= w; i++) line(x,y,x-w,y+i);
for (int i = -w; i <= w; i++) line(x,y,x-w,y+i);
}
void main(void)
{
uint8_t a,b,c,d,e;
c=0;
uint8_t a,b,c,d,e; // loop counters and color indices
c=0; // character code to draw, starting at 0
/* Draw many characters on the screen with different fg and bg colours */
for (a=0; a<=15; a++) {
for (b=0; b<=15; b++) {
@@ -32,7 +49,7 @@ void main(void)
}
color(d,e,SOLID);
gprintf("%c",c++);
}
}
}
/* Draw two circles, a line, and two boxes in different drawing modes */
@@ -47,6 +64,7 @@ void main(void)
box(0,130,40,143,M_NOFILL);
box(50,130,90,143,M_FILL);
// draw lines fanning out from a point
linetest(130, 100, 20);
/* Scroll the screen using the hardest method imaginable :) */
+21 -8
View File
@@ -1,4 +1,12 @@
/*
Physics demo for Game Boy.
A single sprite with velocity and friction, using fixed-point
coordinates: positions are 16-bit values where the lower 4 bits
are the sub-pixel fraction, dropped with >> 4 when the sprite
is moved. Arrow keys apply thrust; holding A gives a jump burst.
*/
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
@@ -12,6 +20,7 @@
// Postion values are calculated as 16 bit numbers and their
// lower 4 bits are dropped when applying them to the sprite
// 4 frames of a ball sprite (8x8, 1bpp)
UINT8 sprite_data[] = {
/*;;{w:8,h:8,bpp:1,count:4,brev:1,np:2,pofs:1,sl:2};;*/
0x3C,0x3C,0x42,0x7E,0x99,0xFF,0xA9,0xFF,0x89,0xFF,0x89,0xFF,0x42,0x7E,0x3C,0x3C,
@@ -23,12 +32,12 @@ UINT8 sprite_data[] = {
joypads_t joypads;
// sprite coords
UINT16 PosX, PosY;
INT16 SpdX, SpdY;
UINT8 Jump;
// fixed-point sprite coords (fraction in lower 4 bits)
UINT16 PosX, PosY; // position
INT16 SpdX, SpdY; // velocity
UINT8 Jump; // frames of jump thrust remaining
// main funxction
// main function
void main(void) {
// init palettes
BGP_REG = OBP0_REG = OBP1_REG = 0xE4;
@@ -45,14 +54,16 @@ void main(void) {
// init 2 joypads
joypad_init(1, &joypads);
// start at screen center with zero velocity
PosX = PosY = 64 << 4;
Jump = SpdX = SpdY = 0;
// loop forever
while(1) {
// poll joypads
joypad_ex(&joypads);
// game object
// game object: arrow keys apply thrust, clamped to a max speed
if (joypads.joy0 & J_UP) {
SpdY -= 2;
if (SpdY < -64) SpdY = -64;
@@ -67,24 +78,26 @@ void main(void) {
SpdX += 2;
if (SpdX > 64) SpdX = 64;
}
// A button triggers a 3-frame jump (only when grounded)
if ((joypads.joy0 & J_A) && (!Jump)) {
Jump = 3;
}
// jump
// jump: apply upward impulse while Jump counts down
if (Jump) {
SpdY -= 8;
if (SpdY < -32) SpdY = -32;
Jump--;
}
// apply velocity to position
PosX += SpdX, PosY += SpdY;
// Translate to pixels and move sprite
// Downshift by 4 bits to use the whole number values
move_sprite(0, PosX >> 4, PosY >> 4);
// decelerate
// friction: velocities decay toward zero each frame
if (SpdY >= 0) {
if (SpdY) SpdY--;
} else SpdY ++;
+78
View File
@@ -0,0 +1,78 @@
//#link "gb/sfr.sgb"
//#link "gb/crt0.sgb"
//#resource "gb/global.sgb"
#include <stdint.h>
#include <string.h>
#include "gb/types.h"
#include "gb/hardware.h"
#include "gb/gb.h"
#define NUM_TILES 46
static const uint8_t font[NUM_TILES*16] = {
/*;;{w:8,h:8,bpp:1,count:46,brev:1,np:2,pofs:1,sl:2};;*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x81,0x81,0x42,0x42,0x24,0x24,0x18,0x18,0x18,0x18,0x24,0x24,0x42,0x42,0x81,0x81
,0x00,0x00,0x24,0x24,0x00,0x00,0x00,0x00,0x24,0x24,0x18,0x18,0x00,0x00,0x00,0x00
,0x00,0x00,0x24,0x24,0x00,0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x00,0x00,0x00,0x00
,0x00,0x00,0x36,0x36,0x49,0x49,0x41,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00
,0x00,0x00,0x00,0x00,0x08,0x08,0x04,0x04,0x7E,0x7E,0x04,0x04,0x08,0x08,0x00,0x00
,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x20,0x7E,0x7E,0x20,0x20,0x10,0x10,0x00,0x00
,0x00,0x00,0x10,0x10,0x38,0x38,0x54,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00
,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x54,0x54,0x38,0x38,0x10,0x10,0x00,0x00
,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x7C,0x7C,0x10,0x10,0x10,0x10,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x06,0x06,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x1E,0x1E,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x02,0x02,0x0C,0x0C,0x02,0x02,0x02,0x02,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x12,0x12,0x12,0x12,0x1E,0x1E,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00
,0x00,0x00,0x1E,0x1E,0x10,0x10,0x1E,0x1E,0x02,0x02,0x02,0x02,0x1E,0x1E,0x00,0x00
,0x00,0x00,0x0C,0x0C,0x10,0x10,0x1C,0x1C,0x12,0x12,0x12,0x12,0x0C,0x0C,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x04,0x04,0x0E,0x0E,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x22,0x22,0x1C,0x1C,0x22,0x22,0x22,0x22,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x1E,0x1E,0x12,0x12,0x1E,0x1E,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00
,0x00,0x00,0x18,0x18,0x24,0x24,0x3C,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x38,0x38,0x24,0x24,0x38,0x38,0x24,0x24,0x24,0x24,0x38,0x38,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x1C,0x00,0x00
,0x00,0x00,0x38,0x38,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x38,0x38,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x20,0x20,0x38,0x38,0x20,0x20,0x20,0x20,0x3C,0x3C,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x20,0x20,0x38,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00
,0x00,0x00,0x18,0x18,0x20,0x20,0x2C,0x2C,0x24,0x24,0x24,0x24,0x18,0x18,0x00,0x00
,0x00,0x00,0x24,0x24,0x24,0x24,0x3C,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x38,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x38,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x38,0x38,0x00,0x00
,0x00,0x00,0x24,0x24,0x28,0x28,0x30,0x30,0x28,0x28,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x38,0x00,0x00
,0x00,0x00,0x22,0x22,0x36,0x36,0x2A,0x2A,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00
,0x00,0x00,0x24,0x24,0x34,0x34,0x2C,0x2C,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x18,0x18,0x00,0x00
,0x00,0x00,0x38,0x38,0x24,0x24,0x38,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00
,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x24,0x24,0x24,0x2C,0x2C,0x1C,0x1C,0x02,0x02
,0x00,0x00,0x38,0x38,0x24,0x24,0x38,0x38,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00
,0x00,0x00,0x1C,0x1C,0x20,0x20,0x18,0x18,0x04,0x04,0x04,0x04,0x38,0x38,0x00,0x00
,0x00,0x00,0x3E,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00
,0x00,0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x18,0x18,0x00,0x00
,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00
,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x2A,0x2A,0x14,0x14,0x00,0x00
,0x00,0x00,0x22,0x22,0x14,0x14,0x08,0x08,0x08,0x08,0x14,0x14,0x22,0x22,0x00,0x00
,0x00,0x00,0x22,0x22,0x14,0x14,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00
,0x00,0x00,0x3C,0x3C,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x3C,0x3C,0x00,0x00
/*;;*/
};
void main(void)
{
DISPLAY_OFF;
memcpy(_VRAM8000, font, sizeof(font)); // copy tile data
memcpy(_SCRN0, font, 32*32); // copy garbage data to screen
BGP_REG = 0xe4; // palette
LCDC_REG = LCDCF_ON|LCDCF_BG8000|LCDCF_BG9800|LCDCF_BGON|LCDCF_OBJ16|LCDCF_OBJON|LCDCF_WIN9C00|LCDCF_WINOFF;
DISPLAY_ON;
// Loop forever
while(1) {
// Game main loop processing goes here
// Done processing, yield CPU and wait for start of next frame
wait_vbl_done();
}
}
+9 -4
View File
@@ -4,12 +4,17 @@ import { PLATFORMS } from "../common/emu";
import { disassembleSM83 } from "../common/cpu/disasmSM83";
const GB_PRESETS: Preset[] = [
{ id: 'hello.c', name: 'Hello World (C)' },
{ id: 'testdrawing.c', name: 'Drawing Routines (C)' },
{ id: 'testphys.c', name: 'Sprite Test (C)' },
{ id: 'hello.c', name: 'Hello World', category: 'C' },
{ id: 'testdrawing.c', name: 'Drawing Routines' },
{ id: 'testphys.c', name: 'Joypad Sprite' },
{ id: 'sprites.c', name: 'Multiple Sprites' },
{ id: 'metasprites.c', name: 'Metasprites' },
{ id: 'scroll.c', name: 'Scrolling' },
{ id: 'music.c', name: 'Music Player' },
{ id: 'siegegame.c', name: 'Siege Game' },
{ id: 'chase.c', name: "Shiru's Chase Game" },
{ id: 'pakupaku.c', name: 'Paku Paku' },
{ id: 'hello.sgb', name: 'Hello World (ASM)' },
{ id: 'hello.sgb', name: 'Hello World (ASM)', category: 'assembler' },
{ id: 'main.wiz', name: 'Snake Game (Wiz)' },
];