mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2026-10-25 00:02:16 +00:00
Add Game Boy presets for Chase and Paku Paku, update hello.sgb paths, and improve palette handling
This commit is contained in:
1 parent
3c73a8ab20
commit
23cf476d31
16 files changed
+2140
-20
No files matched your search
+1430
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef __BCD_H_INCLUDE
|
||||
#define __BCD_H_INCLUDE
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/** @file bcd.h
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
#ifndef _CGB_H
|
||||
#define _CGB_H
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/** Macro to create a CGB palette color entry out of 5-bit color components.
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#ifndef __DRAWING_H
|
||||
#define __DRAWING_H
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/** Size of the screen in pixels */
|
||||
@@ -56,7 +56,7 @@
|
||||
#define SIGNED 1
|
||||
#define UNSIGNED 0
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
|
||||
/** Print the string 'str' with no interpretation
|
||||
@see gotogxy()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#ifndef __EMU_DEBUG_INCLUDE
|
||||
#define __EMU_DEBUG_INCLUDE
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
|
||||
/** Macro to display a message in the emulator debug message window
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef __GBDECOMPRESS_H_INCLUDE
|
||||
#define __GBDECOMPRESS_H_INCLUDE
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/** gb-decompress data from sour into dest
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
#define _ISR_H_INCLUDE_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
|
||||
// #define VECTOR_VBL 0x40 // you can not define raw vector for VBlank interrupt
|
||||
#define VECTOR_STAT 0x48 /**< Address for the STAT interrupt vector */
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
#define _METASPRITES_H_INCLUDE
|
||||
|
||||
#include <gb/hardware.h>
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/** Metasprite sub-item structure
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#ifndef _SGB_H
|
||||
#define _SGB_H
|
||||
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define SGB_PAL_01 0x00U /**< SGB Command: Set SGB Palettes 0 & 1 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
.include "gingerbread.sgb"
|
||||
.include "gb/gingerbread.sgb"
|
||||
|
||||
; Set the size of the ROM file here. 0 means 32 kB, 1 means 64 kB, 2 means 128 kB and so on.
|
||||
ROM_SIZE = 1
|
||||
|
||||
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Paku Paku for Game Boy — port of presets/pacman/pakupaku.c
|
||||
*
|
||||
* One-lane chase inspired by crisp-game-lib "PAKU PAKU":
|
||||
* A / Start = reverse Left / Right = face that way
|
||||
* Collect dots; power pellet makes the ghost edible.
|
||||
* Movement/AI match the Pac-Man hardware port; graphics from pacman.5e/5f
|
||||
* (regenerate with: python3 scripts/gen_gb_pakupaku_gfx.py).
|
||||
*/
|
||||
|
||||
//#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"
|
||||
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t word;
|
||||
typedef int8_t sbyte;
|
||||
|
||||
#define FIELD_MAX 152 /* arcade 208 scaled to GB width */
|
||||
#define PLAYER_SPD 2
|
||||
#define NUM_DOTS 18
|
||||
#define HIT_DIST 12
|
||||
|
||||
#define ROW_ABOVE 8
|
||||
#define DOT_TILE_Y 9
|
||||
#define ROW_BELOW 10
|
||||
#define CORRIDOR_Y 68
|
||||
|
||||
/* BG tiles from pacman.5e (after font 0..34) */
|
||||
#define BKG_BASE 40
|
||||
#define T_WALL_ABOVE (BKG_BASE + 0)
|
||||
#define T_WALL_BELOW (BKG_BASE + 1)
|
||||
#define T_DOT (BKG_BASE + 2)
|
||||
#define T_POWER (BKG_BASE + 3)
|
||||
|
||||
/*
|
||||
* Arcade pacman.5f sprites → GB 16×16 (two 8×16 OAM each).
|
||||
* Each frame is 4 tiles at SPR_BASE: L-top, L-bot, R-top, R-bot.
|
||||
* Regenerate: python3 scripts/gen_gb_pakupaku_gfx.py
|
||||
*/
|
||||
#define SPR_BASE 48
|
||||
#define SPR_FRAME(i) ((byte)(SPR_BASE + (i) * 4))
|
||||
#define SP_OPEN SPR_FRAME(0)
|
||||
#define SP_MID SPR_FRAME(1)
|
||||
#define SP_CLOSED SPR_FRAME(2)
|
||||
#define SP_DEATH0 SPR_FRAME(3) /* 11 frames: 3..13 */
|
||||
#define SP_DEATH_N 11
|
||||
#define SP_GHOST0 SPR_FRAME(14)
|
||||
#define SP_GHOST1 SPR_FRAME(15)
|
||||
#define SP_SCARED0 SPR_FRAME(16)
|
||||
#define SP_SCARED1 SPR_FRAME(17)
|
||||
#define SP_EYES SPR_FRAME(18)
|
||||
#define SPR_TILE_COUNT 76
|
||||
|
||||
typedef struct {
|
||||
byte tx;
|
||||
byte active;
|
||||
byte is_power;
|
||||
} Dot;
|
||||
|
||||
word rnd = 0xCACE;
|
||||
word score;
|
||||
byte multiplier;
|
||||
byte player_x;
|
||||
sbyte player_vx;
|
||||
byte enemy_x;
|
||||
sbyte enemy_eye_vx;
|
||||
word power_ticks;
|
||||
word anim_ticks;
|
||||
byte btn_prev;
|
||||
byte game_over;
|
||||
byte waka;
|
||||
Dot dots[NUM_DOTS];
|
||||
|
||||
byte joy_left, joy_right, joy_fire, joy_start;
|
||||
byte sfx_timer;
|
||||
byte sfx_kind; /* 0=off 1/2=waka 3=eat 4=death 6=power */
|
||||
byte death_phase;
|
||||
|
||||
const uint8_t font_1bpp[] = {
|
||||
/* 0 space */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* 1 '0' */ 0x3C,0x66,0x6E,0x76,0x66,0x66,0x3C,0x00,
|
||||
/* 2 '1' */ 0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00,
|
||||
/* 3 '2' */ 0x3C,0x66,0x06,0x0C,0x18,0x30,0x7E,0x00,
|
||||
/* 4 '3' */ 0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00,
|
||||
/* 5 '4' */ 0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x0C,0x00,
|
||||
/* 6 '5' */ 0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00,
|
||||
/* 7 '6' */ 0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00,
|
||||
/* 8 '7' */ 0x7E,0x06,0x0C,0x18,0x30,0x30,0x30,0x00,
|
||||
/* 9 '8' */ 0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00,
|
||||
/*10 '9' */ 0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00,
|
||||
/*11 'A' */ 0x3C,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,
|
||||
/*12 'C' */ 0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x00,
|
||||
/*13 'E' */ 0x7E,0x60,0x60,0x7C,0x60,0x60,0x7E,0x00,
|
||||
/*14 'F' */ 0x7E,0x60,0x60,0x7C,0x60,0x60,0x60,0x00,
|
||||
/*15 'G' */ 0x3C,0x66,0x60,0x6E,0x66,0x66,0x3C,0x00,
|
||||
/*16 'H' */ 0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,
|
||||
/*17 'I' */ 0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,
|
||||
/*18 'K' */ 0x66,0x6C,0x78,0x70,0x78,0x6C,0x66,0x00,
|
||||
/*19 'L' */ 0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,
|
||||
/*20 'M' */ 0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x00,
|
||||
/*21 'N' */ 0x66,0x76,0x7E,0x7E,0x6E,0x66,0x66,0x00,
|
||||
/*22 'O' */ 0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,
|
||||
/*23 'P' */ 0x7C,0x66,0x66,0x7C,0x60,0x60,0x60,0x00,
|
||||
/*24 'R' */ 0x7C,0x66,0x66,0x7C,0x6C,0x66,0x66,0x00,
|
||||
/*25 'S' */ 0x3C,0x66,0x60,0x3C,0x06,0x66,0x3C,0x00,
|
||||
/*26 'T' */ 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,
|
||||
/*27 'U' */ 0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,
|
||||
/*28 'V' */ 0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,
|
||||
/*29 'W' */ 0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00,
|
||||
/*30 'X' */ 0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,
|
||||
/*31 'D' */ 0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00,
|
||||
/*32 '-' */ 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
|
||||
/*33 '!' */ 0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x00,
|
||||
/*34 '/' */ 0x06,0x06,0x0C,0x18,0x30,0x60,0x60,0x00,
|
||||
};
|
||||
|
||||
const uint8_t bkg_tiles[] = {
|
||||
/*{w:8,h:8,bpp:1,count:4,brev:1,np:2,pofs:1,sl:2}*/
|
||||
0xff,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0xff,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x3c,0x00,0x7e,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x7e,0x00,0x3c,0x00,
|
||||
};
|
||||
|
||||
const uint8_t sprite_tiles[] = {
|
||||
/*{w:8,h:8,bpp:1,count:76,brev:1,np:2,pofs:1,sl:2}*/
|
||||
0x00,0x00,0x07,0x07,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x7e,0x7e,0x7c,0x7c,0x78,0x78,
|
||||
0x7c,0x7c,0x7e,0x7e,0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xc0,0xc0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x07,0x07,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x7f,0x7f,0x7f,0x7f,0x78,0x78,
|
||||
0x7f,0x7f,0x7f,0x7f,0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xf0,0xf0,0xf8,0xf8,0xf8,0xf8,0xe0,0xe0,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xe0,0xe0,0xf8,0xf8,0xf8,0xf8,0xf0,0xf0,0xc0,0xc0,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x07,0x07,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
|
||||
0x7f,0x7f,0x7f,0x7f,0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x07,0x07,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xf0,0xf0,0xf8,0xf8,0xf8,0xf8,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
|
||||
0xfc,0xfc,0xfc,0xfc,0xf8,0xf8,0xf8,0xf8,0xf0,0xf0,0xc0,0xc0,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x70,0x70,0x78,0x78,0x7c,0x7c,0x7e,0x7e,
|
||||
0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x1c,0x1c,0x3c,0x3c,0x7c,0x7c,0xfc,0xfc,
|
||||
0xf8,0xf8,0xf8,0xf8,0xf0,0xf0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0xf0,0xf0,0xf8,0xf8,0xfe,0xfe,
|
||||
0x7f,0x7f,0x7f,0x7f,0x3f,0x3f,0x0e,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x1e,0x1e,0x3e,0x3e,0xfe,0xfe,
|
||||
0xfc,0xfc,0xfc,0xfc,0xf8,0xf8,0xe0,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0xfc,0xfc,
|
||||
0xff,0xff,0x7f,0x7f,0x3f,0x3f,0x0e,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x0e,0x7e,0x7e,
|
||||
0xfe,0xfe,0xfc,0xfc,0xf8,0xf8,0xe0,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,
|
||||
0xff,0xff,0xff,0xff,0x7f,0x7f,0x1e,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x1e,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x0f,0x0f,0xff,0xff,0xff,0xff,0x7f,0x7f,0x1e,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xe0,0xe0,0xfe,0xfe,0xfe,0xfe,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x03,0x03,0x0f,0x0f,0x7f,0x7f,0xff,0xff,0x7e,0x7e,0x1c,0x1c,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x80,0x80,0xe0,0xe0,0xfc,0xfc,0xfe,0xfe,0xfc,0xfc,0x70,0x70,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x01,0x01,0x03,0x03,0x0f,0x0f,0x1f,0x1f,0x7f,0x7f,0x7e,0x7e,0x3c,0x3c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x80,0x80,0xe0,0xe0,0xf0,0xf0,0xfc,0xfc,0xfc,0xfc,0x78,0x78,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x01,0x01,0x03,0x03,0x07,0x07,0x07,0x07,0x0f,0x0f,0x1f,0x1f,0x0e,0x0e,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x80,0x80,0xc0,0xc0,0xc0,0xc0,0xe0,0xe0,0xf0,0xf0,0xe0,0xe0,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x01,0x01,0x01,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x07,0x07,0x02,0x02,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0x80,0x80,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x12,0x12,
|
||||
0x08,0x08,0x00,0x00,0x30,0x30,0x00,0x00,0x08,0x08,0x10,0x10,0x02,0x02,0x04,0x04,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80,0x80,
|
||||
0x10,0x10,0x20,0x20,0x00,0x00,0x18,0x18,0x00,0x00,0x20,0x20,0x90,0x90,0x40,0x40,
|
||||
0x00,0x00,0x03,0x03,0x0f,0x0f,0x1f,0x1f,0x3f,0x39,0x3f,0x30,0x3c,0x33,0x7c,0x73,
|
||||
0x7f,0x79,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x6e,0x6e,0x46,0x46,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xf0,0xf0,0xf8,0xf8,0xfc,0xe4,0xfc,0xc0,0xf0,0xcc,0xf2,0xce,
|
||||
0xfe,0xe6,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0x76,0x76,0x62,0x62,0x00,0x00,
|
||||
0x00,0x00,0x03,0x03,0x0f,0x0f,0x1f,0x1f,0x3f,0x39,0x3f,0x30,0x3c,0x33,0x7c,0x73,
|
||||
0x7f,0x79,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7b,0x7b,0x31,0x31,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xf0,0xf0,0xf8,0xf8,0xfc,0xe4,0xfc,0xc0,0xf0,0xcc,0xf2,0xce,
|
||||
0xfe,0xe6,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xde,0xde,0x8c,0x8c,0x00,0x00,
|
||||
0x00,0x00,0x03,0x03,0x0f,0x0f,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x3f,0x39,0x7f,0x79,
|
||||
0x7f,0x7f,0x7f,0x7f,0x7f,0x66,0x7f,0x59,0x7f,0x7f,0x6e,0x6e,0x46,0x46,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xf0,0xf0,0xf8,0xf8,0xfc,0xfc,0xfc,0xfc,0xfc,0x9c,0xfe,0x9e,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfe,0x66,0xfe,0x9a,0xfe,0xfe,0x76,0x76,0x62,0x62,0x00,0x00,
|
||||
0x00,0x00,0x03,0x03,0x0f,0x0f,0x1f,0x1f,0x3f,0x3f,0x3f,0x3f,0x3f,0x39,0x7f,0x79,
|
||||
0x7f,0x7f,0x7f,0x7f,0x7f,0x66,0x7f,0x59,0x7f,0x7f,0x7b,0x7b,0x31,0x31,0x00,0x00,
|
||||
0x00,0x00,0xc0,0xc0,0xf0,0xf0,0xf8,0xf8,0xfc,0xfc,0xfc,0xfc,0xfc,0x9c,0xfe,0x9e,
|
||||
0xfe,0xfe,0xfe,0xfe,0xfe,0x66,0xfe,0x9a,0xfe,0xfe,0xde,0xde,0x8c,0x8c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0f,0x00,0x0c,0x00,0x0c,0x00,
|
||||
0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x3c,0x00,0x30,0x00,0x30,0x00,
|
||||
0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
byte rand8(void) {
|
||||
rnd = rnd * 17 + 53;
|
||||
return (byte)(rnd >> 8);
|
||||
}
|
||||
|
||||
byte abs_diff(byte a, byte b) {
|
||||
return (a > b) ? (byte)(a - b) : (byte)(b - a);
|
||||
}
|
||||
|
||||
byte glyph(char c) {
|
||||
if (c == ' ') return 0;
|
||||
if (c >= '0' && c <= '9') return (byte)(1 + (c - '0'));
|
||||
switch (c) {
|
||||
case 'A': return 11; case 'C': return 12; case 'E': return 13;
|
||||
case 'F': return 14; case 'G': return 15; case 'H': return 16;
|
||||
case 'I': return 17; case 'K': return 18; case 'L': return 19;
|
||||
case 'M': return 20; case 'N': return 21; case 'O': return 22;
|
||||
case 'P': return 23; case 'R': return 24; case 'S': return 25;
|
||||
case 'T': return 26; case 'U': return 27; case 'V': return 28;
|
||||
case 'W': return 29; case 'X': return 30; case 'D': return 31;
|
||||
case '-': return 32; case '!': return 33; case '/': return 34;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void put_str(byte x, byte y, const char* s) {
|
||||
while (*s) set_bkg_tile_xy(x++, y, glyph(*s++));
|
||||
}
|
||||
|
||||
void put_digit(byte x, byte y, byte d) {
|
||||
set_bkg_tile_xy(x, y, (byte)(1 + (d % 10)));
|
||||
}
|
||||
|
||||
void clrscr(void) {
|
||||
byte x, y;
|
||||
for (y = 0; y < 32; y++)
|
||||
for (x = 0; x < 32; x++)
|
||||
set_bkg_tile_xy(x, y, 0);
|
||||
}
|
||||
|
||||
void hide_all_sprites(void) {
|
||||
byte i;
|
||||
for (i = 0; i < 40; i++) move_sprite(i, 0, 0);
|
||||
}
|
||||
|
||||
void read_controls(void) {
|
||||
byte j = joypad();
|
||||
joy_left = (j & J_LEFT) != 0;
|
||||
joy_right = (j & J_RIGHT) != 0;
|
||||
joy_fire = (j & J_A) != 0;
|
||||
joy_start = (j & J_START) != 0;
|
||||
}
|
||||
|
||||
void psg_init(void) {
|
||||
NR52_REG = 0x80;
|
||||
NR50_REG = 0x77;
|
||||
NR51_REG = 0xFF;
|
||||
NR10_REG = 0x00;
|
||||
}
|
||||
|
||||
void sfx_off(void) {
|
||||
sfx_timer = 0;
|
||||
sfx_kind = 0;
|
||||
NR12_REG = 0x00;
|
||||
NR14_REG = 0x80;
|
||||
NR22_REG = 0x00;
|
||||
NR24_REG = 0x80;
|
||||
}
|
||||
|
||||
void beep(word per, byte vol, byte len) {
|
||||
/* ch1 one-shot */
|
||||
NR10_REG = 0x00;
|
||||
NR11_REG = 0x80;
|
||||
NR12_REG = (byte)((vol << 4) | 0x01);
|
||||
NR13_REG = (byte)(per & 0xff);
|
||||
NR14_REG = (byte)(0x80 | ((per >> 8) & 0x07));
|
||||
sfx_timer = len;
|
||||
}
|
||||
|
||||
void play_sfx(byte id) {
|
||||
sfx_kind = id;
|
||||
if (id == 4) death_phase = 0;
|
||||
switch (id) {
|
||||
case 1: beep(0x6C0, 10, 3); break; /* waka hi */
|
||||
case 2: beep(0x650, 9, 3); break; /* waka lo */
|
||||
case 3: beep(0x700, 12, 12); break; /* eat ghost */
|
||||
case 4: beep(0x480, 12, 40); break; /* death */
|
||||
case 6: beep(0x720, 11, 8); break; /* power */
|
||||
default: sfx_off(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void tick_sfx(void) {
|
||||
if (!sfx_timer) return;
|
||||
--sfx_timer;
|
||||
if (!sfx_timer && sfx_kind == 4) {
|
||||
death_phase++;
|
||||
if (death_phase < 4) {
|
||||
beep((word)(0x480 - death_phase * 0x40), 10, 10);
|
||||
sfx_kind = 4;
|
||||
} else {
|
||||
death_phase = 0;
|
||||
sfx_kind = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wait_vblank(void) {
|
||||
wait_vbl_done();
|
||||
tick_sfx();
|
||||
}
|
||||
|
||||
void wait_frames(byte n) {
|
||||
while (n--) wait_vblank();
|
||||
}
|
||||
|
||||
void wait_for_button(void) {
|
||||
read_controls();
|
||||
while (!joy_fire && !joy_start) { wait_vblank(); read_controls(); }
|
||||
while (joy_fire || joy_start) { wait_vblank(); read_controls(); }
|
||||
}
|
||||
|
||||
void draw_hud(void) {
|
||||
put_str(0, 0, "PAKU PAKU");
|
||||
put_str(0, 1, "SCORE");
|
||||
put_digit(6, 1, (byte)((score / 1000) % 10));
|
||||
put_digit(7, 1, (byte)((score / 100) % 10));
|
||||
put_digit(8, 1, (byte)((score / 10) % 10));
|
||||
put_digit(9, 1, (byte)(score % 10));
|
||||
put_str(12, 1, "X");
|
||||
put_digit(13, 1, multiplier > 9 ? 9 : multiplier);
|
||||
put_str(0, 17, "A=TURN");
|
||||
}
|
||||
|
||||
void draw_corridor(void) {
|
||||
byte x;
|
||||
for (x = 0; x < 20; x++) {
|
||||
set_bkg_tile_xy(x, ROW_ABOVE, T_WALL_ABOVE);
|
||||
set_bkg_tile_xy(x, DOT_TILE_Y, 0);
|
||||
set_bkg_tile_xy(x, ROW_BELOW, T_WALL_BELOW);
|
||||
}
|
||||
}
|
||||
|
||||
void add_dots(void) {
|
||||
byte i, pi;
|
||||
pi = (player_x > 80) ? (byte)(1 + (rand8() % 7)) : (byte)(10 + (rand8() % 7));
|
||||
for (i = 0; i < NUM_DOTS; i++) {
|
||||
dots[i].tx = (byte)(i + 1);
|
||||
dots[i].active = 1;
|
||||
dots[i].is_power = (i == pi);
|
||||
}
|
||||
if (multiplier < 99) multiplier++;
|
||||
}
|
||||
|
||||
void draw_dots(void) {
|
||||
byte i;
|
||||
for (i = 0; i < NUM_DOTS; i++) {
|
||||
if (!dots[i].active) {
|
||||
set_bkg_tile_xy(dots[i].tx, DOT_TILE_Y, 0);
|
||||
continue;
|
||||
}
|
||||
if (dots[i].is_power) {
|
||||
if ((anim_ticks >> 3) & 1)
|
||||
set_bkg_tile_xy(dots[i].tx, DOT_TILE_Y, T_POWER);
|
||||
else
|
||||
set_bkg_tile_xy(dots[i].tx, DOT_TILE_Y, 0);
|
||||
} else {
|
||||
set_bkg_tile_xy(dots[i].tx, DOT_TILE_Y, T_DOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void collect_dots(void) {
|
||||
byte i, ptx;
|
||||
ptx = (byte)((player_x + 8) >> 3);
|
||||
if (ptx < 1) ptx = 1;
|
||||
if (ptx > NUM_DOTS) ptx = NUM_DOTS;
|
||||
for (i = 0; i < NUM_DOTS; i++) {
|
||||
if (!dots[i].active) continue;
|
||||
if (dots[i].tx != ptx) continue;
|
||||
dots[i].active = 0;
|
||||
set_bkg_tile_xy(dots[i].tx, DOT_TILE_Y, 0);
|
||||
if (dots[i].is_power) {
|
||||
play_sfx(6);
|
||||
if (!enemy_eye_vx) power_ticks = 200;
|
||||
} else {
|
||||
waka ^= 1;
|
||||
play_sfx(waka ? 1 : 2);
|
||||
}
|
||||
score += multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
byte dots_left(void) {
|
||||
byte i, n = 0;
|
||||
for (i = 0; i < NUM_DOTS; i++)
|
||||
if (dots[i].active) n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
byte pac_frame(void) {
|
||||
byte ai = (byte)(anim_ticks & 3);
|
||||
if (ai == 0) return SP_OPEN;
|
||||
if (ai == 1) return SP_MID;
|
||||
if (ai == 2) return SP_CLOSED;
|
||||
return SP_MID;
|
||||
}
|
||||
|
||||
void put_actor16(byte i0, byte frame, byte flip, byte prop, byte x, byte y) {
|
||||
/* Two 8×16 sprites = one 16×16 arcade sprite; swap halves when flipped. */
|
||||
byte i1 = (byte)(i0 + 1);
|
||||
byte p = prop;
|
||||
byte oam0, oam1;
|
||||
if (flip) p |= S_FLIPX;
|
||||
set_sprite_tile(i0, frame);
|
||||
set_sprite_tile(i1, (byte)(frame + 2));
|
||||
set_sprite_prop(i0, p);
|
||||
set_sprite_prop(i1, p);
|
||||
if (flip) {
|
||||
oam0 = (byte)(x + 16);
|
||||
oam1 = (byte)(x + 8);
|
||||
} else {
|
||||
oam0 = (byte)(x + 8);
|
||||
oam1 = (byte)(x + 16);
|
||||
}
|
||||
/* Hide if past the right edge (OAM X wraps). */
|
||||
if (x > 152) {
|
||||
move_sprite(i0, 0, 0);
|
||||
move_sprite(i1, 0, 0);
|
||||
return;
|
||||
}
|
||||
move_sprite(i0, oam0, (byte)(y + 16));
|
||||
move_sprite(i1, oam1, (byte)(y + 16));
|
||||
}
|
||||
|
||||
void draw_actors(void) {
|
||||
byte ghost, gprop, pflip, gflip;
|
||||
sbyte evx;
|
||||
|
||||
pflip = (player_vx < 0) ? 1 : 0;
|
||||
put_actor16(0, pac_frame(), pflip, 0, player_x, CORRIDOR_Y);
|
||||
|
||||
if (enemy_eye_vx) {
|
||||
ghost = SP_EYES;
|
||||
gflip = (enemy_eye_vx < 0) ? 1 : 0;
|
||||
gprop = 0;
|
||||
} else if (power_ticks) {
|
||||
ghost = ((anim_ticks >> 1) & 1) ? SP_SCARED1 : SP_SCARED0;
|
||||
gflip = 0;
|
||||
gprop = 0;
|
||||
/* blink near end of power */
|
||||
if (power_ticks < 60 && (anim_ticks & 0x08)) {
|
||||
move_sprite(2, 0, 0);
|
||||
move_sprite(3, 0, 0);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ghost = ((anim_ticks >> 1) & 1) ? SP_GHOST1 : SP_GHOST0;
|
||||
evx = (player_x > enemy_x) ? 1 : -1;
|
||||
gflip = (evx < 0) ? 1 : 0;
|
||||
gprop = 0;
|
||||
}
|
||||
put_actor16(2, ghost, gflip, gprop, enemy_x, CORRIDOR_Y);
|
||||
}
|
||||
|
||||
void title_screen(void) {
|
||||
byte x;
|
||||
clrscr();
|
||||
hide_all_sprites();
|
||||
move_bkg(0, 0);
|
||||
/* corridor stripe behind the demo sprites */
|
||||
for (x = 0; x < 20; x++) {
|
||||
set_bkg_tile_xy(x, 6, T_WALL_ABOVE);
|
||||
set_bkg_tile_xy(x, 7, 0);
|
||||
set_bkg_tile_xy(x, 8, T_WALL_BELOW);
|
||||
}
|
||||
put_str(5, 2, "PAKU PAKU");
|
||||
put_actor16(0, SP_OPEN, 0, 0, 52, 48);
|
||||
put_actor16(2, SP_GHOST0, 0, 0, 92, 48);
|
||||
put_str(4, 11, "A TO TURN");
|
||||
put_str(2, 13, "EAT DOTS EAT GHOST");
|
||||
put_str(4, 16, "PRESS START");
|
||||
wait_for_button();
|
||||
sfx_off();
|
||||
}
|
||||
|
||||
void show_game_over(void) {
|
||||
byte frame_i, t, frame;
|
||||
hide_all_sprites();
|
||||
put_actor16(0, SP_OPEN, 0, 0, player_x, CORRIDOR_Y);
|
||||
play_sfx(4);
|
||||
/* Arcade: 11 frames × 8 vblanks */
|
||||
for (frame_i = 0; frame_i < SP_DEATH_N; frame_i++) {
|
||||
frame = (byte)(SP_DEATH0 + (byte)(frame_i * 4));
|
||||
for (t = 0; t < 8; t++) {
|
||||
put_actor16(0, frame, 0, 0, player_x, CORRIDOR_Y);
|
||||
wait_vblank();
|
||||
read_controls();
|
||||
if (joy_fire || joy_start) goto death_done;
|
||||
}
|
||||
}
|
||||
death_done:
|
||||
hide_all_sprites();
|
||||
put_str(5, 7, "GAME OVER");
|
||||
put_str(4, 10, "PRESS START");
|
||||
wait_for_button();
|
||||
sfx_off();
|
||||
}
|
||||
|
||||
void reset_round(void) {
|
||||
player_x = 48;
|
||||
player_vx = 1;
|
||||
enemy_x = 128;
|
||||
enemy_eye_vx = 0;
|
||||
power_ticks = 0;
|
||||
anim_ticks = 0;
|
||||
btn_prev = 1;
|
||||
game_over = 0;
|
||||
waka = 0;
|
||||
sfx_off();
|
||||
draw_corridor();
|
||||
add_dots();
|
||||
}
|
||||
|
||||
void game_loop(void) {
|
||||
byte btn;
|
||||
sbyte evx;
|
||||
byte espd;
|
||||
|
||||
clrscr();
|
||||
hide_all_sprites();
|
||||
move_bkg(0, 0);
|
||||
draw_corridor();
|
||||
draw_hud();
|
||||
reset_round();
|
||||
|
||||
while (!game_over) {
|
||||
wait_vblank();
|
||||
anim_ticks++;
|
||||
read_controls();
|
||||
|
||||
btn = (joy_fire || joy_start) ? 1 : 0;
|
||||
if (btn && !btn_prev) player_vx = (sbyte)-player_vx;
|
||||
btn_prev = btn;
|
||||
if (joy_left) player_vx = -1;
|
||||
if (joy_right) player_vx = 1;
|
||||
|
||||
/* Same wrap as pacman pakupaku.c */
|
||||
player_x = (byte)(player_x + player_vx * PLAYER_SPD);
|
||||
if (player_x < 4) player_x = FIELD_MAX;
|
||||
else if (player_x > FIELD_MAX) player_x = 4;
|
||||
|
||||
collect_dots();
|
||||
if (!dots_left()) add_dots();
|
||||
|
||||
/* Ghost AI — identical rules to presets/pacman/pakupaku.c */
|
||||
if (enemy_eye_vx) {
|
||||
evx = enemy_eye_vx;
|
||||
espd = 3;
|
||||
} else if (power_ticks) {
|
||||
evx = (player_x > enemy_x) ? (sbyte)-1 : 1;
|
||||
espd = 1;
|
||||
} else {
|
||||
evx = (player_x > enemy_x) ? 1 : -1;
|
||||
espd = 2;
|
||||
}
|
||||
if (evx > 0) {
|
||||
if (enemy_x < FIELD_MAX - 2) enemy_x = (byte)(enemy_x + espd);
|
||||
else if (enemy_eye_vx) enemy_eye_vx = 0;
|
||||
} else {
|
||||
if (enemy_x > 6) enemy_x = (byte)(enemy_x - espd);
|
||||
else if (enemy_eye_vx) enemy_eye_vx = 0;
|
||||
}
|
||||
|
||||
if (!enemy_eye_vx && abs_diff(player_x, enemy_x) < HIT_DIST) {
|
||||
if (power_ticks) {
|
||||
play_sfx(3);
|
||||
score += (word)(10 * (multiplier ? multiplier : 1));
|
||||
enemy_eye_vx = (player_x > 80) ? (sbyte)-1 : 1;
|
||||
power_ticks = 0;
|
||||
if (multiplier < 99) multiplier++;
|
||||
} else {
|
||||
game_over = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (power_ticks) power_ticks--;
|
||||
|
||||
draw_dots();
|
||||
draw_hud();
|
||||
draw_actors();
|
||||
}
|
||||
}
|
||||
|
||||
void setup_graphics(void) {
|
||||
DISPLAY_OFF;
|
||||
set_bkg_1bpp_data(0, 35, font_1bpp);
|
||||
set_bkg_data(BKG_BASE, 4, bkg_tiles);
|
||||
set_sprite_data(SPR_BASE, SPR_TILE_COUNT, sprite_tiles);
|
||||
SPRITES_8x16;
|
||||
BGP_REG = 0xE4;
|
||||
OBP0_REG = 0xE4;
|
||||
OBP1_REG = 0xE4;
|
||||
psg_init();
|
||||
HIDE_WIN;
|
||||
SHOW_BKG;
|
||||
SHOW_SPRITES;
|
||||
DISPLAY_ON;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
setup_graphics();
|
||||
score = 0;
|
||||
multiplier = 0;
|
||||
while (1) {
|
||||
title_screen();
|
||||
score = 0;
|
||||
multiplier = 0;
|
||||
game_loop();
|
||||
show_game_over();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Shared Game Boy DMG (olive LCD) palette.
|
||||
*
|
||||
* Shade 0 = lightest (LCD pixel off / "white"), shade 3 = darkest (pixel on).
|
||||
* Values are packed for Canvas ImageData as Uint32 little-endian RGBA (= 0xAABBGGRR).
|
||||
*/
|
||||
|
||||
export function rgbToPixel(r: number, g: number, b: number): number {
|
||||
return 0xFF000000 | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);
|
||||
}
|
||||
|
||||
/** Four DMG shades, lightest → darkest (matches BGP/OBP shade indices). */
|
||||
export const DMG_PALETTE: number[] = [
|
||||
rgbToPixel(0xd0, 0xd8, 0x84), // Lightest (warm mint)
|
||||
rgbToPixel(0x87, 0xa8, 0x4c), // Light mid
|
||||
rgbToPixel(0x52, 0x6b, 0x34), // Dark mid
|
||||
rgbToPixel(0x2d, 0x31, 0x22), // Darkest (deep olive)
|
||||
];
|
||||
|
||||
/** RGB888 triples matching DMG_PALETTE (for boytacean remap / tooling). */
|
||||
export const DMG_PALETTE_RGB: [number, number, number][] = [
|
||||
[0xd0, 0xd8, 0x84],
|
||||
[0x87, 0xa8, 0x4c],
|
||||
[0x52, 0x6b, 0x34],
|
||||
[0x2d, 0x31, 0x22],
|
||||
];
|
||||
|
||||
/** Asset-editor / PREDEF_PALETTES entries (RGB without alpha; callers OR 0xff000000). */
|
||||
export const DMG_PALETTE_RGB24: number[] = [
|
||||
0xd0d884,
|
||||
0x87a84c,
|
||||
0x526b34,
|
||||
0x2d3122,
|
||||
];
|
||||
|
||||
/** Map a greyscale / near-grey RGB888 pixel to a DMG shade (0=light … 3=dark). */
|
||||
export function dmgShadeFromRgb(r: number, g: number, b: number): number {
|
||||
var y = (r + g + b) / 3;
|
||||
if (y >= 192) return 0;
|
||||
if (y >= 128) return 1;
|
||||
if (y >= 64) return 2;
|
||||
return 3;
|
||||
}
|
||||
+10
-2
@@ -14,7 +14,7 @@ export interface EditorContext {
|
||||
}
|
||||
|
||||
export type SelectablePalette = {
|
||||
node: PixNode
|
||||
node: PixNode | null
|
||||
name: string
|
||||
palette: Uint32Array
|
||||
}
|
||||
@@ -224,7 +224,11 @@ export function validateAssetData(datastr: string, fmt): string | null {
|
||||
maxOffset = Math.max(maxOffset, offset);
|
||||
}
|
||||
}
|
||||
var required = maxOffset + (nplanes > 1 ? (nplanes - 1) * pofs : 0) + 1 + skip;
|
||||
// Planar formats (e.g. NES pofs>=wpimg) store extra planes past each image block.
|
||||
// Interleaved formats (GB/SMS pofs < wpimg) already include plane bytes in maxOffset.
|
||||
var planeExtent = (nplanes > 1) ? (nplanes - 1) * pofs : 0;
|
||||
if (planeExtent < wpimg) planeExtent = 0;
|
||||
var required = maxOffset + planeExtent + 1 + skip;
|
||||
|
||||
if (words.length != required) {
|
||||
return `Expected ${required} value(s), found ${words.length}`;
|
||||
@@ -341,6 +345,10 @@ export function convertPaletteFormat(palbytes: UintArray, palfmt: PixelEditorPal
|
||||
|
||||
// TODO: illegal colors?
|
||||
const PREDEF_PALETTES = {
|
||||
// LCD polarity: index 0 = lightest (pixel off), 3 = darkest (pixel on)
|
||||
'gb': [
|
||||
0xd0d884, 0x87a84c, 0x526b34, 0x2d3122,
|
||||
],
|
||||
'nes': [
|
||||
0x525252, 0xB40000, 0xA00000, 0xB1003D, 0x740069, 0x00005B, 0x00005F, 0x001840, 0x002F10, 0x084A08, 0x006700, 0x124200, 0x6D2800, 0x000000, 0x000000, 0x000000,
|
||||
0xC4D5E7, 0xFF4000, 0xDC0E22, 0xFF476B, 0xD7009F, 0x680AD7, 0x0019BC, 0x0054B1, 0x006A5B, 0x008C03, 0x00AB00, 0x2C8800, 0xA47200, 0x000000, 0x000000, 0x000000,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import { newDiv, ProjectView } from "./baseviews";
|
||||
import { platform_id, current_project, projectWindows } from "../ui";
|
||||
import { DMG_PALETTE } from "../../common/gbpalette";
|
||||
import { FileData } from "../../common/workertypes";
|
||||
import { hex, safeident, rgb2bgr } from "../../common/util";
|
||||
import * as pixed from "../pixeleditor";
|
||||
@@ -80,6 +81,18 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
|
||||
node = node.right;
|
||||
}
|
||||
});
|
||||
// Game Boy: default to LCD green scale (0=light … 3=dark) when no project palette
|
||||
if (result.length == 0 && platform_id && platform_id.startsWith('gb')) {
|
||||
if (matchlen == 4) {
|
||||
result.push({ node: null, name: "DMG Green", palette: new Uint32Array(DMG_PALETTE) });
|
||||
} else if (matchlen == 2) {
|
||||
result.push({
|
||||
node: null,
|
||||
name: "DMG Green",
|
||||
palette: new Uint32Array([DMG_PALETTE[0], DMG_PALETTE[3]]),
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+1
-8
@@ -2,16 +2,9 @@
|
||||
import { SM83, SM83State } from "../common/cpu/SM83";
|
||||
import { BasicScanlineMachine, Bus } from "../common/devices";
|
||||
import { newAddressDecoder, padBytes, Keys, makeKeycodeMap, newKeyboardHandler, EmuHalt } from "../common/emu";
|
||||
import { DMG_PALETTE } from "../common/gbpalette";
|
||||
import { hex } from "../common/util";
|
||||
|
||||
// Game Boy DMG palette: 4 shades of green (darkest to lightest)
|
||||
const DMG_PALETTE: number[] = [
|
||||
0xFFd0d884, // Lightest (Warm Mint)
|
||||
0xFF87a84c, // Light Mid
|
||||
0xFF526b34, // Dark Mid
|
||||
0xFF2d3122, // Darkest (Deep Olive)
|
||||
];
|
||||
|
||||
// Convert GBC 15-bit RGB (xBBBBBGGGGGRRRRR) to 32-bit ARGB
|
||||
function cgbColorToARGB(lo: number, hi: number): number {
|
||||
var r5 = lo & 0x1F;
|
||||
|
||||
@@ -7,6 +7,8 @@ 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: 'chase.c', name: "Shiru's Chase Game" },
|
||||
{ id: 'pakupaku.c', name: 'Paku Paku' },
|
||||
{ id: 'hello.sgb', name: 'Hello World (ASM)' },
|
||||
{ id: 'main.wiz', name: 'Snake Game (Wiz)' },
|
||||
];
|
||||
|
||||
Reference in new issue
Block a user