mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2026-10-25 00:02:16 +00:00
gb: added more presets
This commit is contained in:
1 parent
85c40450b3
commit
e55445fb7b
12 files changed
+1045
-80
No files matched your search
@@ -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>
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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 ++;
|
||||
|
||||
@@ -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
@@ -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)' },
|
||||
];
|
||||
|
||||
|
||||
Reference in new issue
Block a user