elf = $(name).elf
bin = $(name).gba
-data = data/color.raw data/color.pal data/height.raw data/menuscr.555 \
- data/spr_game.raw data/spr_game.pal data/spr_logo.raw data/spr_logo.pal
+data = data/color.raw data/color.pal data/color.gpal data/height.raw \
+ data/spr_game.raw data/spr_game.pal data/spr_logo.raw data/spr_logo.pal \
+ data/menuscr.raw data/menuscr.pal data/menuscr.gpal \
+ data/spr_menu.raw data/spr_menu.pal
libs = libs/maxmod/libmm.a
%.pal: %.png tools/pngdump/pngdump
tools/pngdump/pngdump -o $@ -c $<
+%.gpal: %.png tools/pngdump/pngdump
+ tools/pngdump/pngdump -o $@ -c -g $<
+
%.555: %.png tools/pngdump/pngdump
tools/pngdump/pngdump -o $@ -555 $<
/* main game data */
extern unsigned char color_pixels[];
extern unsigned char color_cmap[];
+extern unsigned char color_gba_cmap[];
extern unsigned char height_pixels[];
extern unsigned char spr_game_pixels[];
/* menu screen assets */
extern unsigned char menuscr_pixels[];
+extern unsigned char menuscr_cmap[];
+extern unsigned char menuscr_gba_cmap[];
+extern unsigned char spr_menu_pixels[];
+extern unsigned char spr_menu_cmap[];
/* logo splash assets */
extern unsigned char spr_logo_pixels[];
.globl color_pixels
.globl color_cmap
+ .globl color_gba_cmap
.globl height_pixels
.globl spr_game_pixels
.globl spr_game_cmap
.globl menuscr_pixels
+ .globl menuscr_cmap
+ .globl menuscr_gba_cmap
+ .globl spr_menu_pixels
+ .globl spr_menu_cmap
.globl spr_logo_pixels
.globl spr_logo_cmap
.align 1
color_pixels:
.incbin "data/color.raw"
+
.align 1
color_cmap:
.incbin "data/color.pal"
+
+ .align 1
+color_gba_cmap:
+ .incbin "data/color.gpal"
+
.align 1
height_pixels:
.incbin "data/height.raw"
.align 1
spr_game_pixels:
.incbin "data/spr_game.raw"
+
.align 1
spr_game_cmap:
.incbin "data/spr_game.pal"
.align 1
menuscr_pixels:
- .incbin "data/menuscr.555"
+ .incbin "data/menuscr.raw"
+
+ .align 1
+menuscr_cmap:
+ .incbin "data/menuscr.pal"
+
+ .align 1
+menuscr_gba_cmap:
+ .incbin "data/menuscr.gpal"
+
+ .align 1
+spr_menu_pixels:
+ .incbin "data/spr_menu.raw"
+
+ .align 1
+spr_menu_cmap:
+ .incbin "data/spr_menu.pal"
.align 1
spr_logo_pixels:
.incbin "data/spr_logo.raw"
+
.align 1
spr_logo_cmap:
.incbin "data/spr_logo.pal"
int change_screen(struct screen *scr);
struct screen *find_screen(const char *name);
+int gba_colors;
+
#ifndef BUILD_GBA
int32_t view_dtheta, view_dphi, view_zoom;
#endif
#include "input.h"
#include "gba.h"
#include "sprite.h"
+#include "timer.h"
#include "debug.h"
#include "voxscape.h"
#include "data.h"
#define NEAR 2
#define FAR 85
+#define P_RATE 500
+#define E_RATE 500
+
static int gamescr_start(void);
static void gamescr_stop(void);
static void gamescr_frame(void);
struct vox_object vobj;
short hp;
short anm;
- int last_fire;
+ int last_shot;
};
#define ENEMY_VALID(e) ((e)->anm != 0)
static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
static int32_t pos[2], angle, horizon = 80;
+static unsigned long last_shot;
#define COLOR_HORIZON 192
#define COLOR_ZENITH 255
#define MAX_ENEMIES (255 - CMAP_SPAWN0)
struct enemy enemies[MAX_ENEMIES];
-int num_enemies, total_enemies;
+int num_kills, total_enemies;
static int energy;
#define MAX_ENERGY 5
return &gamescr;
}
+static void setup_palette(void)
+{
+ int i;
+ unsigned char *cmap = gba_colors ? color_gba_cmap : color_cmap;
+
+ emuprint("setting up %s palette", gba_colors ? "GBA" : "NDS/Emu");
+
+ for(i=0; i<256; i++) {
+ int r = cmap[i * 3];
+ int g = cmap[i * 3 + 1];
+ int b = cmap[i * 3 + 2];
+ gba_bgpal[i] = RGB555(r, g, b);
+ }
+}
+
static int gamescr_start(void)
{
int i, j, sidx;
vblperf_setcolor(0);
pos[0] = pos[1] = VOX_SZ << 15;
+ angle = 0x8000;
+ last_shot = timer_msec > P_RATE ? timer_msec - P_RATE : 0;
vox_init(VOX_SZ, VOX_SZ, height_pixels, color_pixels);
vox_proj(FOV, NEAR, FAR);
vox_view(pos[0], pos[1], -40, angle);
/* setup color image palette */
- for(i=0; i<256; i++) {
- int r = color_cmap[i * 3];
- int g = color_cmap[i * 3 + 1];
- int b = color_cmap[i * 3 + 2];
- gba_bgpal[i] = (((uint16_t)b << 7) & 0x7c00) | (((uint16_t)g << 2) & 0x3e0) | (((uint16_t)r >> 3) & 0x1f);
- }
+ setup_palette();
spr_setup(16, 16, spr_game_pixels, spr_game_cmap);
wait_vblank();
spr_oam(oam, sidx++, SPRID_UISLASH, 216, 144, SPR_VRECT | SPR_256COL);
dynspr_base = sidx;
- num_enemies = total_enemies = 0;
+ num_kills = total_enemies = 0;
energy = 5;
memset(enemies, 0, sizeof enemies);
enemy->vobj.px = -1;
enemy->anm = 0xff;
enemy->hp = 2;
- enemy->last_fire = 0;
+ enemy->last_shot = timer_msec > E_RATE ? timer_msec - E_RATE : 0;
if(++total_enemies >= MAX_ENEMIES) {
goto endspawn;
}
pos[0] += fwd[0];
pos[1] += fwd[1];
}
- if(keystate & BN_B) {
- for(i=0; i<num_enemies; i++) {
+ if((keystate & BN_B) && (timer_msec - last_shot >= P_RATE)) {
+ emuprint("pew");
+ last_shot = timer_msec;
+ for(i=0; i<total_enemies; i++) {
if(enemies[i].hp && enemies[i].vobj.px >= 0) {
int dx = enemies[i].vobj.px - 120;
int dy = enemies[i].vobj.py - 80;
if(abs(dx) < 10 && abs(dy) < 10) {
- emuprint("pow");
enemies[i].hp--;
break;
}
snum = 0;
/* turrets number */
- spr_oam(oam, dynspr_base + snum++, numspr[num_enemies][0], 200, 144, SPR_VRECT | SPR_256COL);
- spr_oam(oam, dynspr_base + snum++, numspr[num_enemies][1], 208, 144, SPR_VRECT | SPR_256COL);
+ spr_oam(oam, dynspr_base + snum++, numspr[num_kills][0], 200, 144, SPR_VRECT | SPR_256COL);
+ spr_oam(oam, dynspr_base + snum++, numspr[num_kills][1], 208, 144, SPR_VRECT | SPR_256COL);
spr_oam(oam, dynspr_base + snum++, numspr[total_enemies][0], 224, 144, SPR_VRECT | SPR_256COL);
spr_oam(oam, dynspr_base + snum++, numspr[total_enemies][1], 232, 144, SPR_VRECT | SPR_256COL);
/* energy bar */
panic(get_pc(), "failed to initialize screens");
}
- if(change_screen(find_screen("logo")) == -1) {
+ if(change_screen(find_screen("game")) == -1) {
panic(get_pc(), "failed to find starting screen");
}
#include "util.h"
#include "dma.h"
#include "input.h"
+#include "sprite.h"
#include "debug.h"
+enum {
+ MENU_START,
+ MENU_CTRL,
+ MENU_COLORS,
+ MENU_SCORE,
+
+ NUM_MENU_ITEMS
+};
+
static int menuscr_start(void);
static void menuscr_stop(void);
static void menuscr_frame(void);
menuscr_vblank
};
+static int num_vbl;
+static int cur_x, cur_y;
+static int sel;
+static int running;
+
+static const short pos[][2] = {{76, 88}, {87, 108}, {29, 128}, {75, 148}};
+#define CUR_XOFFS 16
+
struct screen *init_menu_screen(void)
{
return &menuscr;
}
+static void setup_palette(void)
+{
+ int i;
+ unsigned char *cmap = gba_colors ? menuscr_gba_cmap : menuscr_cmap;
+
+ for(i=0; i<256; i++) {
+ int r = cmap[i * 3];
+ int g = cmap[i * 3 + 1];
+ int b = cmap[i * 3 + 2];
+ gba_bgpal[i] = RGB555(r, g, b);
+ }
+}
+
static int menuscr_start(void)
{
- gba_setmode(3, DISPCNT_BG2);
- dma_copy16(3, gba_vram_lfb0, menuscr_pixels, 240 * 160, 0);
+ gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ);
+ dma_copy16(3, gba_vram_lfb0, menuscr_pixels, 240 * 160 / 2, 0);
+
+ setup_palette();
+
+ spr_setup(16, 4, spr_menu_pixels, spr_menu_cmap);
+
+ wait_vblank();
+ spr_clear();
+
+ cur_x = pos[0][0] - CUR_XOFFS;
+ cur_y = pos[0][1];
+
+ running = 1;
return 0;
}
static void menuscr_stop(void)
{
+ running = 0;
+ wait_vblank();
+ spr_clear();
}
static void menuscr_frame(void)
{
update_keyb();
- if(KEYPRESS(BN_START)) {
+ if(KEYPRESS(BN_START) || (sel == 0 && KEYPRESS(BN_A))) {
change_screen(find_screen("game"));
return;
}
+
+ if(KEYPRESS(BN_DOWN) && sel <= NUM_MENU_ITEMS) {
+ cur_x = pos[++sel][0] - CUR_XOFFS;
+ cur_y = pos[sel][1];
+ }
+ if(KEYPRESS(BN_UP) && sel > 0) {
+ cur_x = pos[--sel][0] - CUR_XOFFS;
+ cur_y = pos[sel][1];
+ }
+ if((KEYPRESS(BN_LEFT) || KEYPRESS(BN_RIGHT)) && sel == MENU_COLORS) {
+ gba_colors ^= 1;
+ setup_palette();
+ }
+
+ wait_vblank();
}
+static const int curspr[] = {
+ SPRID(0, 0), SPRID(32, 0), SPRID(64, 0), SPRID(96, 0),
+ SPRID(0, 16), SPRID(32, 16), SPRID(64, 16), SPRID(96, 16)
+};
+
+#define MENU_COLOR_FBPTR (void*)(VRAM_LFB_FB0_ADDR + 117 * 240)
+
static void menuscr_vblank(void)
{
+ int anm, frm;
+ unsigned int flags = SPR_SZ32 | SPR_HRECT | SPR_256COL;
+ void *src;
+
+ if(!running) return;
+
+ anm = (num_vbl++ >> 3) & 0xf;
+ frm = anm & 7;
+
+ if(anm >= 8) flags |= SPR_VFLIP;
+
+ spr_oam(0, 0, curspr[frm], cur_x - 16, cur_y - 8, flags);
+
+ src = menuscr_pixels + (gba_colors ? 160 : 117) * 240;
+ dma_copy32(3, MENU_COLOR_FBPTR, src, 16 * 240 / 4, 0);
}
#include "gba.h"
#define RGB555(r, g, b) \
- (((r) >> 3) | (((g) << 2) & 0x3e0) | (((b) << 7) & 0x7c00))
+ ((((uint16_t)(r) >> 3) & 0x1f) | \
+ (((uint16_t)(g) << 2) & 0x3e0) | \
+ (((uint16_t)(b) << 7) & 0x7c00))
#ifdef BUILD_GBA