OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
main.c File Reference

shmup_1942 — S5: bullets, collision and enemy destruction More...

#include <snes.h>
#include <snes/asset.h>
#include <snes/input.h>

Classes

struct  Entity
struct  GameState
 Centralized game state structure. More...

Macros

#define BULLET_ATTR   0x34 /* tile 128, pal 2, prio 3 (max), no flip */
#define BULLET_CX_OFFSET   8 /* ball centre in the 16×16 bullet canvas */
#define BULLET_CY_OFFSET   8
#define BULLET_HIDE_Y   240
#define BULLET_OAM_BASE   (ENEMY_OAM_BASE + MAX_ENEMIES) /* = 9 */
#define BULLET_PALETTE   2
#define BULLET_SPEED   4
#define BULLET_SPRITE   32 /* full 32×32 OAM slot — visible bullet is centred top */
#define BULLET_TILE   128 /* OBJ tile 128 = VRAM word $6800 */
#define ENEMY_ATTR   0xA2 /* tile 64, pal 1, prio 2, V-flip */
#define ENEMY_HIDE_Y   240
#define ENEMY_HITBOX_END   (32 - ENEMY_HITBOX_INSET)
#define ENEMY_HITBOX_INSET   6
#define ENEMY_OAM_BASE   1
#define ENEMY_PALETTE   1
#define ENEMY_SPAWN_MASK   (ENEMY_SPAWN_PERIOD - 1)
#define ENEMY_SPAWN_PERIOD   32 /* power of 2 → mask, not modulo (cc65816 has no fast %) */
#define ENEMY_SPEED   2
#define ENEMY_SPRITE   32
#define ENEMY_TILE   64 /* OBJ tile 64 = VRAM word $6400 */
#define FIRE_COOLDOWN   8 /* frames between consecutive shots */
#define MAP_HEIGHT_PX   512
#define MAX_BULLETS   8
#define MAX_ENEMIES   8
#define OAM_WRITE(_id, _x, _y, _tile, _attr)
#define PLAYER_ATTR   0x20 /* tile 0, pal 0, prio 2, no flip */
#define PLAYER_MAX_X   216
#define PLAYER_MAX_Y   176
#define PLAYER_MIN_X   8
#define PLAYER_MIN_Y   16
#define PLAYER_SPEED   2

Functions

static void bullet_fire (void)
static void bullet_hide (u8 i)
static void bullets_init (void)
static void bullets_render (void)
static void bullets_update (void)
static void collisions_resolve (void)
 DECLARE_BG_ASSET (scene, BG_16COLORS, SC_32x64)
static void enemies_init (void)
static void enemies_render (void)
static void enemies_update (void)
static void enemy_hide (u8 i)
static void enemy_spawn (void)
int main (void)
static u16 prng_next (void)

Variables

u8 bullet_pal []
u8 bullet_pal_end []
u8 bullet_tiles []
u8 bullet_tiles_end []
u8 enemy_pal []
u8 enemy_pal_end []
u8 enemy_tiles []
u8 enemy_tiles_end []
static GameState game
u8 player_pal []
u8 player_pal_end []
u8 player_tiles []
u8 player_tiles_end []

Detailed Description

shmup_1942 — S5: bullets, collision and enemy destruction

Adds player bullets and bullet↔enemy AABB collision on top of S4. Pressing A fires a bullet upward (with a small cooldown). Bullets travel at 4 px/frame; when a bullet's bounding box overlaps an enemy, both deactivate. The scene composition, scroll direction and enemy spawn logic are unchanged from S4.

SNES Concepts
  • Sprite pools as fixed-size arrays of {x, y, active} slots (player gets OAM slot 0, enemies 1-8, bullets 9-16)
  • Multiple sprite types in the same OAM grid: distinct VRAM regions (player @ $6000, enemy @ $6400, bullet @ $6800 — all word addresses) plus distinct sprite palettes (0/1/2)
  • Axis-aligned bounding-box (AABB) overlap test for 32×32 sprites
  • Input edge detection via padPressed() for one-shot fire
What to Observe
  • Press A to fire a bullet upward from the player's nose
  • Bullets travel at 4 px/frame; they despawn at the top of the screen or on hitting an enemy
  • Enemies hit by a bullet vanish immediately (S5.1 will add explosion animations)
  • The terrain keeps scrolling and the enemy pool keeps spawning
Modules Used
console, dma, background, asset, sprite, input
See also
background.h, asset.h, sprite.h, input.h, dma.h

Macro Definition Documentation

◆ BULLET_ATTR

#define BULLET_ATTR   0x34 /* tile 128, pal 2, prio 3 (max), no flip */

◆ BULLET_CX_OFFSET

#define BULLET_CX_OFFSET   8 /* ball centre in the 16×16 bullet canvas */

◆ BULLET_CY_OFFSET

#define BULLET_CY_OFFSET   8

◆ BULLET_HIDE_Y

#define BULLET_HIDE_Y   240

◆ BULLET_OAM_BASE

#define BULLET_OAM_BASE   (ENEMY_OAM_BASE + MAX_ENEMIES) /* = 9 */

◆ BULLET_PALETTE

#define BULLET_PALETTE   2

◆ BULLET_SPEED

#define BULLET_SPEED   4

◆ BULLET_SPRITE

#define BULLET_SPRITE   32 /* full 32×32 OAM slot — visible bullet is centred top */

◆ BULLET_TILE

#define BULLET_TILE   128 /* OBJ tile 128 = VRAM word $6800 */

◆ ENEMY_ATTR

#define ENEMY_ATTR   0xA2 /* tile 64, pal 1, prio 2, V-flip */

◆ ENEMY_HIDE_Y

#define ENEMY_HIDE_Y   240

◆ ENEMY_HITBOX_END

#define ENEMY_HITBOX_END   (32 - ENEMY_HITBOX_INSET)

◆ ENEMY_HITBOX_INSET

#define ENEMY_HITBOX_INSET   6

◆ ENEMY_OAM_BASE

#define ENEMY_OAM_BASE   1

◆ ENEMY_PALETTE

#define ENEMY_PALETTE   1

◆ ENEMY_SPAWN_MASK

#define ENEMY_SPAWN_MASK   (ENEMY_SPAWN_PERIOD - 1)

◆ ENEMY_SPAWN_PERIOD

#define ENEMY_SPAWN_PERIOD   32 /* power of 2 → mask, not modulo (cc65816 has no fast %) */

◆ ENEMY_SPEED

#define ENEMY_SPEED   2

◆ ENEMY_SPRITE

#define ENEMY_SPRITE   32

◆ ENEMY_TILE

#define ENEMY_TILE   64 /* OBJ tile 64 = VRAM word $6400 */

◆ FIRE_COOLDOWN

#define FIRE_COOLDOWN   8 /* frames between consecutive shots */

◆ MAP_HEIGHT_PX

#define MAP_HEIGHT_PX   512

◆ MAX_BULLETS

#define MAX_BULLETS   8

◆ MAX_ENEMIES

#define MAX_ENEMIES   8

◆ OAM_WRITE

#define OAM_WRITE ( _id,
_x,
_y,
_tile,
_attr )
Value:
do { \
u16 _o = (u16)(_id) << 2; \
oamMemory[_o + 0] = (u8)(_x); \
oamMemory[_o + 1] = (u8)((_y) - 1); \
oamMemory[_o + 2] = (u8)(_tile); \
oamMemory[_o + 3] = (_attr); \
} while(0)
unsigned short u16
16-bit unsigned integer (0 to 65535)
Definition types.h:53
unsigned char u8
8-bit unsigned integer (0 to 255)
Definition types.h:47
u8 oamMemory[]
Hardware OAM buffer (544 bytes at $7E:0300).

◆ PLAYER_ATTR

#define PLAYER_ATTR   0x20 /* tile 0, pal 0, prio 2, no flip */

◆ PLAYER_MAX_X

#define PLAYER_MAX_X   216

◆ PLAYER_MAX_Y

#define PLAYER_MAX_Y   176

◆ PLAYER_MIN_X

#define PLAYER_MIN_X   8

◆ PLAYER_MIN_Y

#define PLAYER_MIN_Y   16

◆ PLAYER_SPEED

#define PLAYER_SPEED   2

Function Documentation

◆ bullet_fire()

void bullet_fire ( void )
static

◆ bullet_hide()

void bullet_hide ( u8 i)
static

◆ bullets_init()

void bullets_init ( void )
static

◆ bullets_render()

void bullets_render ( void )
static

◆ bullets_update()

void bullets_update ( void )
static

◆ collisions_resolve()

void collisions_resolve ( void )
static

◆ DECLARE_BG_ASSET()

DECLARE_BG_ASSET ( scene ,
BG_16COLORS ,
SC_32x64  )

◆ enemies_init()

void enemies_init ( void )
static

◆ enemies_render()

void enemies_render ( void )
static

◆ enemies_update()

void enemies_update ( void )
static

◆ enemy_hide()

void enemy_hide ( u8 i)
static

◆ enemy_spawn()

void enemy_spawn ( void )
static

◆ main()

int main ( void )

◆ prng_next()

u16 prng_next ( void )
static

Variable Documentation

◆ bullet_pal

u8 bullet_pal[]
extern

◆ bullet_pal_end

u8 bullet_pal_end[]

◆ bullet_tiles

u8 bullet_tiles[]
extern

◆ bullet_tiles_end

u8 bullet_tiles_end[]

◆ enemy_pal

u8 enemy_pal[]
extern

◆ enemy_pal_end

u8 enemy_pal_end[]

◆ enemy_tiles

u8 enemy_tiles[]
extern

◆ enemy_tiles_end

u8 enemy_tiles_end[]

◆ game

GameState game
static

◆ player_pal

u8 player_pal[]
extern

◆ player_pal_end

u8 player_pal_end[]

◆ player_tiles

u8 player_tiles[]
extern

◆ player_tiles_end

u8 player_tiles_end[]