#include "game/sprites.h" #include #include SDL_Texture *g_spritesheet = NULL; /* ── Pixel art data ───────────────────────────────── * Each sprite is defined as a 16x16 grid of hex color values. * 0x00000000 = transparent * Colors are RGBA packed as 0xRRGGBBAA */ #define T 0x00000000 /* transparent */ /* Color palette */ #define BLK 0x1a1a2eFF /* black/dark */ #define WHT 0xeeeeeaFF /* white */ #define SKN 0xe8b796FF /* skin tone */ #define SKD 0xc48e6aFF /* skin dark */ #define BLU 0x4a7cbdFF /* blue */ #define BLD 0x365e8fFF /* blue dark */ #define BLL 0x6fa8dcFF /* blue light */ #define RED 0xd94444FF /* red */ #define RDD 0xa83232FF /* red dark */ #define RDL 0xff6666FF /* red light */ #define GRN 0x4caf50FF /* green */ #define GRD 0x388e3cFF /* green dark */ #define YLW 0xffd54fFF /* yellow */ #define YLD 0xd4a017FF /* yellow dark */ #define ORG 0xff9800FF /* orange */ #define ORD 0xcc7a00FF /* orange dark */ #define PRP 0x9c27b0FF /* purple */ #define PRD 0x7b1fa2FF /* purple dark */ #define PRL 0xce93d8FF /* purple light */ #define GRY 0x888888FF /* grey */ #define GYD 0x555555FF /* grey dark */ #define GYL 0xbbbbbbFF /* grey light */ #define BRN 0x8d6e63FF /* brown */ #define BRD 0x5d4037FF /* brown dark */ #define CYN 0x4dd0e1FF /* cyan */ #define CYD 0x00acc1FF /* cyan dark */ /* ── Player sprites ────────────────────────────────── */ /* Player idle frame 1 - heroic adventurer */ static const uint32_t player_idle1[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, SKN, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, SKN, T, BLU, BLU, BLU, BLU, BLU, BLU, T, SKN, T, T, T, T, T, T, T, T, BLD, BLD, BLU, BLU, BLD, BLD, T, T, T, T, T, T, T, T, T, T, BLD, BLD, T, T, BLD, BLD, T, T, T, T, T, T, T, T, T, T, BRN, BRN, T, T, BRN, BRN, T, T, T, T, T, T, T, T, T, T, BRD, BRD, T, T, BRD, BRD, T, T, T, T, T, T, }; /* Player idle frame 2 - slight bob */ static const uint32_t player_idle2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, SKN, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, T, T, BLD, BLD, BLU, BLU, BLD, BLD, T, T, T, T, T, T, T, T, T, T, BLD, BLD, T, T, BLD, BLD, T, T, T, T, T, T, T, T, T, T, BRN, BRN, T, T, BRN, BRN, T, T, T, T, T, T, T, T, T, T, BRD, BRD, T, T, BRD, BRD, T, T, T, T, T, T, }; /* Player run frame 1 */ static const uint32_t player_run1[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, SKN, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, SKN, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, T, SKN, T, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLD, T, T, T, T, T, T, T, T, T, T, T, T, BLD, T, T, T, BLD, T, T, T, T, T, T, T, T, T, T, BRN, BRN, T, T, T, BRN, BRN, T, T, T, T, T, T, T, T, BRD, BRD, T, T, T, T, T, BRD, T, T, T, T, T, }; /* Player run frame 2 */ static const uint32_t player_run2[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, SKN, T, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLD, T, BLU, BLU, T, BLD, T, T, T, T, T, T, T, T, T, T, BLD, T, T, T, BLD, T, T, T, T, T, T, T, T, T, T, T, T, BRN, T, BRN, BRN, T, T, T, T, T, T, T, T, T, T, T, T, BRD, T, BRD, T, T, T, T, T, T, T, T, }; /* Player run frame 3 */ static const uint32_t player_run3[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, SKN, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, SKN, T, BLU, BLU, BLU, BLU, BLU, BLU, T, SKN, T, T, T, T, T, T, T, T, BLD, BLD, BLU, BLU, BLD, BLD, T, T, T, T, T, T, T, T, T, BLD, T, T, T, T, T, T, BLD, T, T, T, T, T, T, T, BRN, BRN, T, T, T, T, T, BRN, BRN, T, T, T, T, T, T, T, T, BRD, T, T, T, T, BRD, BRD, T, T, T, T, T, T, }; /* Player run frame 4 - same as run2 mirrored leg positions */ static const uint32_t player_run4[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, SKN, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, SKN, T, T, T, T, T, T, SKN, T, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLD, T, T, T, T, T, T, T, T, T, T, BLD, T, T, T, T, T, BLD, T, T, T, T, T, T, T, T, BRN, BRN, T, T, T, T, BRN, BRN, T, T, T, T, T, T, T, T, BRD, T, T, T, T, T, T, BRD, T, T, T, T, T, T, }; /* Player jump */ static const uint32_t player_jump[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, SKN, T, SKN, SKN, SKD, SKD, SKN, SKN, T, SKN, T, T, T, T, T, T, SKN, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, SKN, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLD, BLD, T, T, BLD, BLD, T, T, T, T, T, T, T, T, T, BRN, BRN, T, T, T, BRN, BRN, T, T, T, T, T, T, T, T, T, BRD, BRD, T, T, T, T, BRN, BRN, T, T, T, T, T, T, T, T, T, T, T, T, T, T, BRD, BRD, T, T, T, T, T, }; /* Player fall */ static const uint32_t player_fall[16*16] = { T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLU, BLU, T, T, T, T, T, T, T, T, T, BLU, BLL, BLL, BLL, BLL, BLL, BLU, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, T, BLK, SKN, SKN, SKN, SKN, SKN, SKN, BLK, T, T, T, T, T, T, T, T, BLK, SKN, BLK, SKN, SKN, BLK, SKN, BLK, T, T, T, T, T, T, T, T, T, SKN, SKN, SKN, SKD, SKN, SKN, T, T, T, T, T, T, T, T, T, T, SKN, SKN, SKD, SKD, SKN, SKN, T, T, T, T, T, T, T, SKN, SKN, BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, SKN, SKN, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, T, BLD, BLU, BLU, BLU, BLU, BLU, BLU, BLD, T, T, T, T, T, T, T, T, T, BLU, BLU, BLU, BLU, BLU, BLU, T, T, T, T, T, T, T, T, T, T, BLD, BLD, T, T, BLD, BLD, T, T, T, T, T, T, T, T, T, T, BRN, BRN, T, T, T, BRN, T, T, T, T, T, T, T, T, T, BRN, BRD, T, T, T, T, BRN, T, T, T, T, T, T, T, T, T, BRD, T, T, T, T, T, BRD, T, T, T, T, T, T, }; /* ── Grunt enemy sprites ───────────────────────────── */ /* Grunt: Red spiky enemy that patrols back and forth */ static const uint32_t grunt_idle1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RED, T, T, T, T, T, RED, T, T, T, T, T, T, T, T, T, RED, RED, T, T, T, RED, RED, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, WHT, BLK, RED, WHT, BLK, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, BLK, BLK, BLK, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, T, RDD, RDD, T, T, RDD, RDD, T, T, T, T, T, T, T, T, T, T, RDD, RDD, T, T, RDD, RDD, T, T, T, T, T, T, T, T, T, T, BLK, BLK, T, T, BLK, BLK, T, T, T, T, T, T, }; static const uint32_t grunt_idle2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RED, T, T, T, T, T, RED, T, T, T, T, T, T, T, T, T, RED, RED, T, T, T, RED, RED, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, WHT, BLK, RED, WHT, BLK, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, BLK, BLK, BLK, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, T, RDD, RDD, T, T, RDD, RDD, T, T, T, T, T, T, T, T, T, T, RDD, RDD, T, T, RDD, RDD, T, T, T, T, T, T, T, T, T, T, BLK, BLK, T, T, BLK, BLK, T, T, T, T, T, T, }; /* Grunt walk frames (same body, different leg positions) */ static const uint32_t grunt_walk1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RED, T, T, T, T, T, RED, T, T, T, T, T, T, T, T, T, RED, RED, T, T, T, RED, RED, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, WHT, BLK, RED, WHT, BLK, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, BLK, BLK, BLK, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, T, T, RDD, T, T, RDD, T, T, T, T, T, T, T, T, T, T, T, RDD, T, T, T, T, RDD, T, T, T, T, T, T, T, T, T, T, BLK, T, T, T, T, BLK, T, T, T, T, T, T, }; static const uint32_t grunt_walk2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RED, T, T, T, T, T, RED, T, T, T, T, T, T, T, T, T, RED, RED, T, T, T, RED, RED, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, WHT, BLK, RED, WHT, BLK, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, RDD, RED, RED, BLK, BLK, BLK, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RDD, T, T, T, T, T, T, T, T, T, T, T, RDD, T, T, T, T, RDD, T, T, T, T, T, T, T, T, T, T, T, RDD, T, T, RDD, T, T, T, T, T, T, T, T, T, T, T, T, BLK, T, T, BLK, T, T, T, T, T, T, T, }; /* Grunt death frame */ static const uint32_t grunt_death[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, RDD, RED, RED, BLK, BLK, RED, BLK, BLK, RED, RED, RDD, T, T, T, T, T, RDD, RED, RED, RED, RED, BLK, RED, RED, RED, RED, RDD, T, T, T, T, T, T, RDD, RED, RED, RED, RED, RED, RED, RED, RDD, T, T, T, T, T, T, T, T, RDD, RDD, RDD, RDD, RDD, RDD, RDD, T, T, T, T, T, }; /* ── Flyer enemy sprites ───────────────────────────── */ /* Flying enemy: Purple bat-like creature */ static const uint32_t flyer_idle1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, PRP, PRP, PRP, PRP, PRP, T, T, T, T, T, T, T, T, T, T, PRP, PRP, PRP, PRP, PRP, PRP, PRP, T, T, T, T, T, T, T, T, PRP, PRP, YLW, BLK, PRP, YLW, BLK, PRP, PRP, T, T, T, T, T, T, T, PRD, PRP, PRP, PRP, PRP, PRP, PRP, PRP, PRD, T, T, T, T, T, T, T, PRD, PRP, PRP, BLK, BLK, PRP, PRP, PRP, PRD, T, T, T, T, T, T, PRL, PRD, PRP, PRP, PRP, PRP, PRP, PRP, PRP, PRD, PRL, T, T, T, T, PRL, PRL, T, PRD, PRP, PRP, PRP, PRP, PRP, PRD, T, PRL, PRL, T, T, PRL, PRL, T, T, T, PRD, PRP, PRP, PRD, T, T, T, T, PRL, PRL, T, PRL, T, T, T, T, T, PRD, PRD, T, T, T, T, T, T, PRL, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; static const uint32_t flyer_idle2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, PRP, PRP, PRP, PRP, PRP, T, T, T, T, T, T, T, T, T, T, PRP, PRP, PRP, PRP, PRP, PRP, PRP, T, T, T, T, T, T, T, T, PRP, PRP, YLW, BLK, PRP, YLW, BLK, PRP, PRP, T, T, T, T, T, T, T, PRD, PRP, PRP, PRP, PRP, PRP, PRP, PRP, PRD, T, T, T, T, T, T, T, PRD, PRP, PRP, BLK, BLK, PRP, PRP, PRP, PRD, T, T, T, T, T, T, T, PRD, PRP, PRP, PRP, PRP, PRP, PRP, PRP, PRD, T, T, T, T, T, PRL, T, T, PRD, PRP, PRP, PRP, PRP, PRP, PRD, T, T, PRL, T, T, PRL, PRL, PRL, T, T, PRD, PRP, PRP, PRD, T, T, T, PRL, PRL, PRL, T, T, T, PRL, PRL, T, T, PRD, PRD, T, T, T, PRL, PRL, T, T, T, T, T, T, PRL, PRL, T, T, T, T, T, PRL, PRL, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Flyer death */ static const uint32_t flyer_death[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, PRP, PRP, PRP, PRP, PRP, T, T, T, T, T, T, T, T, T, T, PRP, PRP, PRP, PRP, PRP, PRP, PRP, T, T, T, T, T, T, T, T, PRP, PRP, BLK, BLK, PRP, BLK, BLK, PRP, PRP, T, T, T, T, T, T, T, PRD, PRP, PRP, PRP, PRP, PRP, PRP, PRP, PRD, T, T, T, T, T, T, T, PRD, PRP, PRP, PRP, BLK, PRP, PRP, PRP, PRD, T, T, T, T, T, T, T, T, PRD, PRP, PRP, PRP, PRP, PRP, PRD, T, T, T, T, T, T, T, T, PRL, T, PRD, PRP, PRP, PRD, T, PRL, T, T, T, T, T, T, T, PRL, T, T, T, PRD, PRD, T, T, T, PRL, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Projectile sprites ────────────────────────────── */ /* Player bullet frame 1 */ static const uint32_t bullet1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, T, T, CYD, CYN, WHT, WHT, CYN, CYD, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, CYD, CYN, WHT, WHT, CYN, CYD, T, T, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Player bullet frame 2 - glow variation */ static const uint32_t bullet2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, CYD, WHT, WHT, WHT, WHT, WHT, WHT, CYD, T, T, T, T, T, T, T, T, CYD, WHT, WHT, WHT, WHT, WHT, WHT, CYD, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Impact effect frame 1 */ static const uint32_t impact1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, WHT, T, T, T, T, T, T, T, T, T, T, T, T, T, WHT, T, T, T, WHT, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, CYN, WHT, CYN, CYN, T, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, WHT, T, CYN, WHT, WHT, WHT, WHT, WHT, CYN, T, WHT, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, T, CYN, CYN, WHT, CYN, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, WHT, T, T, T, WHT, T, T, T, T, T, T, T, T, T, T, T, T, T, WHT, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Impact effect frame 2 - expanding */ static const uint32_t impact2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, CYN, T, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, WHT, CYN, T, T, T, T, T, T, T, T, T, T, CYN, T, CYN, T, WHT, T, CYN, T, CYN, T, T, T, T, T, T, T, T, CYN, WHT, WHT, WHT, WHT, WHT, CYN, T, T, T, T, T, T, T, T, CYN, T, CYN, T, WHT, T, CYN, T, CYN, T, T, T, T, T, T, T, T, T, T, CYN, WHT, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, T, CYN, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Impact effect frame 3 - fading */ static const uint32_t impact3[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, T, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, T, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYD, T, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, CYD, T, T, T, T, T, T, T, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Enemy bullet */ static const uint32_t enemy_bullet1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORD, YLW, WHT, YLW, ORD, T, T, T, T, T, T, T, T, T, T, T, ORD, YLW, WHT, YLW, ORD, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; static const uint32_t enemy_bullet2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, WHT, YLW, ORG, T, T, T, T, T, T, T, T, T, T, ORD, YLW, WHT, WHT, WHT, YLW, ORD, T, T, T, T, T, T, T, T, T, ORD, YLW, WHT, WHT, WHT, YLW, ORD, T, T, T, T, T, T, T, T, T, T, ORG, YLW, WHT, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Hazard sprites ─────────────────────────────────── */ /* Turret idle - metallic gun turret mounted on wall/floor */ static const uint32_t turret_idle1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, GYD, GRY, GYL, GRY, GRY, GYL, GRY, GRY, GRY, GYD, T, T, T, T, T, GYD, GRY, GRY, GRY, RED, RED, GRY, GRY, GRY, GRY, GRY, GYD, T, T, T, T, GYD, GRY, GRY, GRY, RDD, RDD, GRY, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, GYD, GRY, GYL, GRY, GRY, GYL, GRY, GRY, GRY, GYD, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, T, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GYD, T, T, T, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, T, T, T, T, }; /* Turret fire - barrel flash */ static const uint32_t turret_fire1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORG, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, YLW, ORG, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GRY, GRY, GRY, GRY, WHT, YLW, T, T, T, T, T, GYD, GRY, GYL, GRY, GRY, GYL, GRY, GRY, GRY, WHT, YLW, T, T, T, T, GYD, GRY, GRY, GRY, RED, RED, GRY, GRY, GRY, GRY, YLW, ORG, T, T, T, T, GYD, GRY, GRY, GRY, RDD, RDD, GRY, GRY, GRY, GRY, YLW, ORG, T, T, T, T, T, GYD, GRY, GYL, GRY, GRY, GYL, GRY, GRY, GRY, WHT, YLW, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GRY, GRY, GRY, GRY, WHT, YLW, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, YLW, ORG, T, T, T, T, T, T, T, GYD, GRY, GRY, GYD, T, T, T, ORG, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, T, T, T, T, }; /* Moving platform - metallic platform with glowing edges */ #define PLT 0x3a6ea5FF /* platform blue */ #define PLD 0x2a5080FF /* platform blue dark */ #define PLL 0x5a9ed5FF /* platform blue light */ static const uint32_t platform1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, CYN, PLL, PLL, PLT, PLT, PLT, PLT, PLT, PLT, PLT, PLT, PLT, PLT, PLT, PLT, PLL, PLL, PLT, PLT, PLT, PLD, PLT, PLT, PLD, PLT, PLT, PLD, PLT, PLT, PLD, PLT, PLT, PLT, PLT, PLT, PLT, PLD, PLT, PLT, PLD, PLT, PLT, PLD, PLT, PLT, PLD, PLT, PLT, PLT, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, PLD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Flame vent base - metallic grate on floor */ #define FLB 0x2244aaFF /* flame blue */ #define FLD 0x1a3388FF /* flame blue dark */ #define FLL 0x4488ffFF /* flame blue light */ static const uint32_t flame_vent_idle1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FLB, FLB, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, }; /* Flame vent active - blue flames shooting up from grate */ static const uint32_t flame_vent_active1[16*16] = { T, T, T, T, T, T, FLD, T, T, FLD, T, T, T, T, T, T, T, T, T, T, T, FLD, FLB, FLD, FLD, FLB, FLD, T, T, T, T, T, T, T, T, T, FLD, FLB, FLL, FLB, FLB, FLL, FLB, FLD, T, T, T, T, T, T, T, FLD, FLB, FLL, WHT, FLL, FLL, WHT, FLL, FLB, FLD, T, T, T, T, T, T, FLB, FLL, WHT, WHT, FLL, FLL, WHT, WHT, FLL, FLB, T, T, T, T, T, FLD, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, FLD, T, T, T, T, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, T, T, T, T, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, T, T, T, T, FLD, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, FLD, T, T, T, T, T, FLB, FLL, FLL, WHT, WHT, WHT, WHT, FLL, FLL, FLB, T, T, T, T, T, T, T, FLB, FLL, FLL, FLB, FLB, FLL, FLL, FLB, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, }; /* Flame vent active frame 2 - flame flicker */ static const uint32_t flame_vent_active2[16*16] = { T, T, T, T, T, T, T, FLD, FLD, T, T, T, T, T, T, T, T, T, T, T, T, T, FLD, FLB, FLB, FLD, T, T, T, T, T, T, T, T, T, T, T, FLD, FLB, FLL, FLL, FLB, FLD, T, T, T, T, T, T, T, T, T, FLD, FLB, FLL, WHT, WHT, FLL, FLB, FLD, T, T, T, T, T, T, T, FLD, FLB, FLL, WHT, WHT, WHT, WHT, FLL, FLB, FLD, T, T, T, T, T, T, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, T, T, T, T, T, FLD, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, FLD, T, T, T, T, FLB, FLL, WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLB, T, T, T, T, FLB, FLL, FLL, WHT, WHT, WHT, WHT, WHT, WHT, FLL, FLL, FLB, T, T, T, T, T, FLB, FLL, FLL, WHT, WHT, WHT, WHT, FLL, FLL, FLB, T, T, T, T, T, T, T, FLB, FLB, FLL, FLB, FLB, FLL, FLB, FLB, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GRY, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, GYD, }; /* Force field on - vertical energy barrier */ #define FFB 0x4466ffFF /* force field blue */ #define FFD 0x2244ccFF /* force field dark */ #define FFL 0x88aaFFFF /* force field light */ static const uint32_t force_field_on1[16*16] = { T, T, T, FFD, T, FFD, FFB, FFL, FFL, FFB, FFD, T, FFD, T, T, T, T, T, FFD, FFB, FFD, FFB, FFL, WHT, WHT, FFL, FFB, FFD, FFB, FFD, T, T, T, T, T, FFB, FFB, FFL, WHT, WHT, WHT, WHT, FFL, FFB, FFB, T, T, T, T, T, FFD, FFB, FFL, WHT, WHT, FFL, FFL, WHT, WHT, FFL, FFB, FFD, T, T, T, T, T, FFB, FFL, WHT, FFL, FFB, FFB, FFL, WHT, FFL, FFB, T, T, T, T, T, FFD, FFB, FFB, FFL, FFB, FFD, FFD, FFB, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, FFB, FFD, FFB, FFB, FFD, FFB, FFL, FFB, T, T, T, T, T, FFD, FFB, FFB, FFD, FFB, FFL, FFL, FFB, FFD, FFB, FFB, FFD, T, T, T, T, T, FFB, FFD, FFB, FFL, WHT, WHT, FFL, FFB, FFD, FFB, T, T, T, T, T, FFD, FFB, FFB, FFL, WHT, WHT, WHT, WHT, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, WHT, WHT, FFL, FFL, WHT, WHT, FFL, FFB, T, T, T, T, T, FFD, FFB, FFB, FFL, FFB, FFD, FFD, FFB, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, FFB, FFD, FFB, FFB, FFD, FFB, FFL, FFB, T, T, T, T, T, FFD, FFB, FFD, FFB, FFL, FFL, FFL, FFL, FFB, FFD, FFB, FFD, T, T, T, T, T, FFD, T, FFD, FFB, FFL, FFL, FFB, FFD, T, FFD, T, T, T, T, T, T, T, T, T, FFD, FFD, FFD, FFD, T, T, T, T, T, T, }; /* Force field on frame 2 - shimmer */ static const uint32_t force_field_on2[16*16] = { T, T, T, T, T, FFD, FFB, FFB, FFB, FFB, FFD, T, T, T, T, T, T, T, T, FFD, FFD, FFB, FFL, FFL, FFL, FFL, FFB, FFD, FFD, T, T, T, T, T, FFD, FFB, FFB, FFL, WHT, FFL, FFL, WHT, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, WHT, FFL, FFB, FFB, FFL, WHT, FFL, FFB, T, T, T, T, T, FFD, FFB, FFB, FFL, FFB, FFD, FFD, FFB, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, FFB, FFD, FFB, FFB, FFD, FFB, FFL, FFB, T, T, T, T, T, FFD, FFB, FFB, FFD, FFB, FFL, FFL, FFB, FFD, FFB, FFB, FFD, T, T, T, T, T, FFB, FFD, FFB, FFL, WHT, WHT, FFL, FFB, FFD, FFB, T, T, T, T, T, FFD, FFB, FFB, FFL, WHT, WHT, WHT, WHT, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, WHT, FFL, FFB, FFB, FFL, WHT, FFL, FFB, T, T, T, T, T, FFD, FFB, FFB, FFL, FFB, FFD, FFD, FFB, FFL, FFB, FFB, FFD, T, T, T, T, T, FFB, FFL, FFB, FFD, FFB, FFB, FFD, FFB, FFL, FFB, T, T, T, T, T, FFD, FFB, FFD, FFB, FFL, FFL, FFL, FFL, FFB, FFD, FFB, FFD, T, T, T, T, T, FFD, T, FFD, FFB, FFL, FFL, FFB, FFD, T, FFD, T, T, T, T, T, T, T, T, T, FFD, FFB, FFB, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, }; /* Force field off - just dim posts/emitters */ static const uint32_t force_field_off1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, FFD, FFD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Powerup sprites ────────────────────────────────── */ /* Health powerup — red cross / heart icon */ static const uint32_t powerup_health1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RDL, RDL, T, T, RDL, RDL, T, T, T, T, T, T, T, T, T, RDL, RED, RED, RDL, RDL, RED, RED, RDL, T, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, T, T, RDL, RED, RED, WHT, RED, RED, WHT, RED, RED, RDL, T, T, T, T, T, T, RDL, RED, RED, RED, WHT, WHT, RED, RED, RED, RDL, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RDL, T, T, T, T, T, T, T, T, T, T, T, RDL, RED, RED, RDL, T, T, T, T, T, T, T, T, T, T, T, T, T, RDD, RDD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Health powerup frame 2 — slight glow/pulse */ static const uint32_t powerup_health2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, RDL, RDL, T, T, RDL, RDL, T, T, T, T, T, T, T, T, T, RDL, RED, RED, RDL, RDL, RED, RED, RDL, T, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, RDL, RED, RED, RED, WHT, WHT, WHT, WHT, RED, RED, RED, RDL, T, T, T, T, RDL, RED, RED, WHT, WHT, WHT, WHT, WHT, WHT, RED, RED, RDL, T, T, T, T, RDL, RED, RED, RED, WHT, WHT, WHT, WHT, RED, RED, RED, RDL, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RED, RED, RDL, T, T, T, T, T, T, T, T, T, RDL, RED, RED, RED, RED, RDL, T, T, T, T, T, T, T, T, T, T, T, RDD, RDD, RDD, RDD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Jetpack recharge powerup — orange lightning bolt */ static const uint32_t powerup_jetpack1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ORG, ORG, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, WHT, YLW, ORG, ORG, ORG, ORG, T, T, T, T, T, T, T, T, ORG, YLW, WHT, WHT, YLW, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, ORG, ORG, ORG, YLW, WHT, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, T, ORG, ORG, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Jetpack powerup frame 2 — brighter glow */ static const uint32_t powerup_jetpack2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, YLW, YLW, YLW, T, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, WHT, WHT, YLW, YLW, YLW, YLW, T, T, T, T, T, T, T, T, YLW, WHT, WHT, WHT, WHT, WHT, WHT, YLW, T, T, T, T, T, T, T, T, T, YLW, YLW, YLW, WHT, WHT, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, T, YLW, WHT, YLW, T, T, T, T, T, T, T, T, T, T, T, T, T, YLW, YLW, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Drone powerup — cyan spinning gear/orb */ static const uint32_t powerup_drone1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, WHT, WHT, CYN, CYN, CYD, T, T, T, T, T, T, T, CYD, CYN, CYN, WHT, WHT, WHT, WHT, CYN, CYN, CYD, T, T, T, T, T, T, CYN, CYN, WHT, WHT, CYN, CYN, WHT, WHT, CYN, CYN, T, T, T, T, T, CYD, CYN, WHT, WHT, CYN, CYD, CYD, CYN, WHT, WHT, CYN, CYD, T, T, T, T, CYD, CYN, WHT, WHT, CYN, CYD, CYD, CYN, WHT, WHT, CYN, CYD, T, T, T, T, T, CYN, CYN, WHT, WHT, CYN, CYN, WHT, WHT, CYN, CYN, T, T, T, T, T, T, CYD, CYN, CYN, WHT, WHT, WHT, WHT, CYN, CYN, CYD, T, T, T, T, T, T, T, CYD, CYN, CYN, WHT, WHT, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Drone powerup frame 2 — rotated highlight */ static const uint32_t powerup_drone2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, CYD, CYN, WHT, WHT, CYN, CYN, CYN, CYD, T, T, T, T, T, T, T, CYD, CYN, WHT, WHT, CYN, CYN, CYN, CYN, CYN, CYD, T, T, T, T, T, T, CYN, WHT, WHT, CYN, CYD, CYD, CYN, CYN, CYN, CYN, T, T, T, T, T, CYD, CYN, WHT, CYN, CYD, CYD, CYD, CYD, CYN, WHT, CYN, CYD, T, T, T, T, CYD, CYN, WHT, CYN, CYD, CYD, CYD, CYD, CYN, WHT, CYN, CYD, T, T, T, T, T, CYN, CYN, CYN, CYN, CYD, CYD, CYN, WHT, WHT, CYN, T, T, T, T, T, T, CYD, CYN, CYN, CYN, CYN, CYN, WHT, WHT, CYN, CYD, T, T, T, T, T, T, T, CYD, CYN, CYN, CYN, WHT, WHT, CYN, CYD, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Drone companion sprite ────────────────────────── */ /* Small hovering drone — metallic with cyan thruster */ static const uint32_t drone_frame1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYL, GYL, GYL, GYL, T, T, T, T, T, T, T, T, T, T, T, GYL, GRY, GRY, GRY, GRY, GYL, T, T, T, T, T, T, T, T, T, GYL, GRY, GRY, CYN, CYN, GRY, GRY, GYL, T, T, T, T, T, T, T, T, GYD, GRY, CYN, WHT, WHT, CYN, GRY, GYD, T, T, T, T, T, T, T, T, GYD, GRY, CYN, WHT, WHT, CYN, GRY, GYD, T, T, T, T, T, T, T, T, GYL, GRY, GRY, CYN, CYN, GRY, GRY, GYL, T, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, T, T, T, T, GYD, CYD, CYD, GYD, T, T, T, T, T, T, T, T, T, T, T, T, T, CYN, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Drone frame 2 — thruster flicker */ static const uint32_t drone_frame2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYL, GYL, GYL, GYL, T, T, T, T, T, T, T, T, T, T, T, GYL, GRY, GRY, GRY, GRY, GYL, T, T, T, T, T, T, T, T, T, GYL, GRY, GRY, CYN, CYN, GRY, GRY, GYL, T, T, T, T, T, T, T, T, GYD, GRY, CYN, WHT, WHT, CYN, GRY, GYD, T, T, T, T, T, T, T, T, GYD, GRY, CYN, WHT, WHT, CYN, GRY, GYD, T, T, T, T, T, T, T, T, GYL, GRY, GRY, CYN, CYN, GRY, GRY, GYL, T, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GRY, GRY, GYD, T, T, T, T, T, T, T, T, T, T, T, CYD, CYN, CYN, CYD, T, T, T, T, T, T, T, T, T, T, T, T, CYN, WHT, WHT, CYN, T, T, T, T, T, T, T, T, T, T, T, T, T, CYD, CYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Gun powerup sprite ────────────────────────────── */ /* Gun powerup — metallic gun icon (grey/cyan) */ static const uint32_t powerup_gun1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYD, GYD, GYD, GYD, GYD, GYD, T, T, T, T, T, T, T, GYD, GYD, GRY, GRY, GYL, GYL, GYL, GRY, GRY, GYD, T, T, T, T, T, GYD, GRY, GRY, GYL, WHT, WHT, WHT, GYL, GRY, GRY, GRY, GYD, T, T, T, T, GYD, GRY, GYL, WHT, WHT, WHT, WHT, GYL, GRY, GRY, GRY, GYD, T, T, T, T, T, GYD, GRY, GRY, GYL, GYL, GRY, GRY, GYD, GYD, GYD, T, T, T, T, T, T, T, T, GYD, GRY, GRY, GYD, T, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Gun powerup frame 2 — brighter glow */ static const uint32_t powerup_gun2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYL, GYL, GYL, GYL, GYL, GYL, GYD, T, T, T, T, T, T, GYD, GYD, GYL, WHT, WHT, WHT, WHT, WHT, GYL, GYL, GYD, T, T, T, T, T, GYD, GYL, WHT, WHT, WHT, WHT, WHT, WHT, GYL, GYL, GYL, GYD, T, T, T, T, GYD, GYL, WHT, WHT, WHT, WHT, WHT, WHT, GYL, GYL, GYL, GYD, T, T, T, T, T, GYD, GYL, GYL, WHT, WHT, GYL, GYL, GYD, GYD, GYD, T, T, T, T, T, T, T, T, GYD, GYL, GYL, GYD, T, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Fuel powerup sprite ───────────────────────────── */ /* Fuel canister — orange/amber napalm canister icon */ static const uint32_t powerup_fuel1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYD, GYD, T, T, T, T, T, T, T, T, T, T, T, T, GYD, GYL, GYL, GYL, GYD, T, T, T, T, T, T, T, T, T, T, T, ORD, ORG, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, T, ORD, ORG, YLW, YLW, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, ORD, ORG, YLW, YLW, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, ORD, ORG, ORG, ORG, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, ORD, ORG, YLD, YLD, YLD, ORG, ORD, T, T, T, T, T, T, T, T, T, ORD, ORG, ORG, ORG, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, ORD, ORG, YLW, YLW, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, T, ORD, ORG, ORG, ORG, ORD, T, T, T, T, T, T, T, T, T, T, T, T, ORD, ORD, ORD, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Fuel canister frame 2 — brighter glow */ static const uint32_t powerup_fuel2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, GYL, GYL, GYL, T, T, T, T, T, T, T, T, T, T, T, T, GYL, WHT, WHT, WHT, GYL, T, T, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, T, ORG, YLW, WHT, WHT, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, ORG, YLW, WHT, WHT, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, YLW, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, ORG, YLW, ORG, ORG, ORG, YLW, ORG, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, YLW, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, ORG, YLW, WHT, WHT, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, T, ORG, YLW, YLW, YLW, ORG, T, T, T, T, T, T, T, T, T, T, T, T, ORG, ORG, ORG, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Asteroid sprite ────────────────────────────────── */ /* Asteroid-specific greys — cold, cratered moonrock */ #define AST 0x9a9a9aFF /* asteroid surface mid-grey */ #define ASL 0xc0c0c0FF /* asteroid light (rim highlight) */ #define ASD 0x606060FF /* asteroid dark (crater shadow) */ #define ASK 0x404040FF /* asteroid darkest (deep crater) */ #define ASO 0x787878FF /* asteroid outline */ /* Asteroid frame 1 — jagged cratered boulder, irregular silhouette */ static const uint32_t asteroid1[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ASO, ASO, ASO, T, T, T, T, T, T, T, T, T, T, T, T, ASO, ASL, AST, ASO, ASO, T, T, T, T, T, T, T, T, T, T, ASO, ASL, AST, AST, ASD, AST, ASO, ASO, T, T, T, T, T, T, T, ASO, ASL, AST, AST, ASD, ASK, ASD, AST, AST, ASO, T, T, T, T, T, T, ASO, AST, AST, ASD, ASK, ASD, AST, AST, ASL, AST, ASO, T, T, T, T, ASO, AST, AST, ASD, ASD, AST, AST, AST, ASD, AST, AST, ASO, T, T, T, T, ASO, AST, AST, AST, AST, ASD, ASO, AST, AST, ASD, AST, ASO, T, T, T, T, ASO, AST, ASD, AST, AST, AST, AST, ASD, ASK, ASD, AST, ASO, ASO, T, T, T, T, ASO, AST, AST, ASD, ASK, ASD, AST, ASD, AST, AST, AST, ASO, T, T, T, T, ASO, AST, AST, AST, ASD, AST, AST, AST, AST, ASL, ASO, T, T, T, T, T, T, ASO, AST, AST, AST, ASD, AST, AST, ASO, ASO, T, T, T, T, T, T, T, T, ASO, ASO, AST, AST, ASO, ASO, T, T, T, T, T, T, T, T, T, T, T, ASO, ASO, ASO, ASO, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* Asteroid frame 2 — shifted crater highlights for tumble animation */ static const uint32_t asteroid2[16*16] = { T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, ASO, ASO, ASO, T, T, T, T, T, T, T, T, T, T, T, T, ASO, AST, ASL, ASO, ASO, T, T, T, T, T, T, T, T, T, T, ASO, AST, AST, AST, ASD, ASL, ASO, T, T, T, T, T, T, T, T, ASO, AST, ASD, ASK, ASD, AST, AST, AST, ASO, T, T, T, T, T, T, ASO, AST, AST, AST, ASD, AST, AST, ASD, ASK, ASD, ASO, T, T, T, T, T, ASO, AST, ASL, AST, AST, ASD, AST, AST, ASD, AST, ASO, T, T, T, T, ASO, AST, AST, AST, ASD, AST, ASO, ASD, AST, AST, AST, ASO, T, T, T, T, ASO, AST, AST, ASD, ASK, ASD, AST, AST, AST, AST, ASO, ASO, T, T, T, T, T, ASO, AST, AST, ASD, AST, AST, ASD, ASK, ASD, AST, ASO, T, T, T, T, T, ASO, ASL, AST, AST, AST, ASD, AST, ASD, AST, ASO, T, T, T, T, T, T, T, ASO, AST, AST, ASD, AST, AST, ASO, ASO, T, T, T, T, T, T, T, T, T, ASO, AST, AST, ASO, ASO, T, T, T, T, T, T, T, T, T, T, T, T, ASO, ASO, ASO, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, }; /* ── Spritesheet generation ────────────────────────── */ /* All sprite definitions for the sheet - row, column, pixel data */ typedef struct SpriteDef { int row; int col; const uint32_t *pixels; } SpriteDef; static const SpriteDef s_sprite_defs[] = { /* Row 0: Player */ {0, 0, player_idle1}, {0, 1, player_idle2}, {0, 2, player_run1}, {0, 3, player_run2}, {0, 4, player_run3}, {0, 5, player_run4}, {0, 6, player_jump}, {0, 7, player_fall}, /* Row 1: Grunt */ {1, 0, grunt_idle1}, {1, 1, grunt_idle2}, {1, 2, grunt_walk1}, {1, 3, grunt_walk2}, {1, 4, grunt_walk1}, /* reuse frame */ {1, 5, grunt_walk2}, /* reuse frame */ {1, 6, grunt_death}, /* Row 2: Flyer */ {2, 0, flyer_idle1}, {2, 1, flyer_idle2}, {2, 2, flyer_idle1}, /* reuse for fly anim */ {2, 3, flyer_idle2}, {2, 4, flyer_idle1}, {2, 5, flyer_idle2}, {2, 6, flyer_death}, /* Row 3: Projectiles */ {3, 0, bullet1}, {3, 1, bullet2}, {3, 2, impact1}, {3, 3, impact2}, {3, 4, impact3}, {3, 5, enemy_bullet1}, {3, 6, enemy_bullet2}, /* Row 4: Hazards */ {4, 0, turret_idle1}, {4, 1, turret_fire1}, {4, 2, platform1}, {4, 3, flame_vent_idle1}, {4, 4, flame_vent_active1}, {4, 5, flame_vent_active2}, {4, 6, force_field_on1}, {4, 7, force_field_on2}, /* Row 5: Hazards continued + Powerups */ {5, 0, force_field_off1}, {5, 1, powerup_health1}, {5, 2, powerup_health2}, {5, 3, powerup_jetpack1}, {5, 4, powerup_jetpack2}, {5, 5, powerup_drone1}, {5, 6, powerup_drone2}, /* Row 6: Drone companion + Gun powerup + Asteroid */ {6, 0, drone_frame1}, {6, 1, drone_frame2}, {6, 2, powerup_gun1}, {6, 3, powerup_gun2}, {6, 4, asteroid1}, {6, 5, asteroid2}, {6, 6, powerup_fuel1}, {6, 7, powerup_fuel2}, }; #define SHEET_COLS 8 #define SHEET_ROWS 7 SDL_Texture *sprites_generate(SDL_Renderer *renderer) { int w = SHEET_COLS * SPRITE_CELL; int h = SHEET_ROWS * SPRITE_CELL; SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat( 0, w, h, 32, SDL_PIXELFORMAT_RGBA8888); if (!surface) { fprintf(stderr, "Failed to create sprite surface: %s\n", SDL_GetError()); return NULL; } /* Clear to transparent */ SDL_FillRect(surface, NULL, 0); /* Blit each sprite definition */ int count = sizeof(s_sprite_defs) / sizeof(s_sprite_defs[0]); for (int i = 0; i < count; i++) { const SpriteDef *def = &s_sprite_defs[i]; int ox = def->col * SPRITE_CELL; int oy = def->row * SPRITE_CELL; uint32_t *pixels = (uint32_t *)surface->pixels; int pitch = surface->pitch / 4; /* pitch in uint32_t */ for (int y = 0; y < SPRITE_CELL; y++) { for (int x = 0; x < SPRITE_CELL; x++) { uint32_t rgba = def->pixels[y * SPRITE_CELL + x]; if (rgba == 0) continue; /* transparent */ /* Convert from our RRGGBBAA to surface format */ uint8_t r = (rgba >> 24) & 0xFF; uint8_t g = (rgba >> 16) & 0xFF; uint8_t b = (rgba >> 8) & 0xFF; uint8_t a = (rgba) & 0xFF; pixels[(oy + y) * pitch + (ox + x)] = SDL_MapRGBA(surface->format, r, g, b, a); } } } SDL_Texture *tex = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); if (!tex) { fprintf(stderr, "Failed to create sprite texture: %s\n", SDL_GetError()); return NULL; } SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); g_spritesheet = tex; printf("Generated spritesheet: %dx%d (%d sprites)\n", w, h, count); return tex; } /* ── Animation definitions ─────────────────────────── */ #define FRAME(col, row, dur) \ { .src = {(col)*SPRITE_CELL, (row)*SPRITE_CELL, SPRITE_CELL, SPRITE_CELL}, .duration = (dur) } /* Player */ static AnimFrame s_player_idle_frames[] = { FRAME(0, 0, 0.6f), FRAME(1, 0, 0.6f), }; static AnimFrame s_player_run_frames[] = { FRAME(2, 0, 0.1f), FRAME(3, 0, 0.1f), FRAME(4, 0, 0.1f), FRAME(5, 0, 0.1f), }; static AnimFrame s_player_jump_frames[] = { FRAME(6, 0, 1.0f), }; static AnimFrame s_player_fall_frames[] = { FRAME(7, 0, 1.0f), }; /* Grunt */ static AnimFrame s_grunt_idle_frames[] = { FRAME(0, 1, 0.5f), FRAME(1, 1, 0.5f), }; static AnimFrame s_grunt_walk_frames[] = { FRAME(2, 1, 0.15f), FRAME(3, 1, 0.15f), FRAME(4, 1, 0.15f), FRAME(5, 1, 0.15f), }; static AnimFrame s_grunt_death_frames[] = { FRAME(6, 1, 0.3f), }; /* Flyer */ static AnimFrame s_flyer_idle_frames[] = { FRAME(0, 2, 0.3f), FRAME(1, 2, 0.3f), }; static AnimFrame s_flyer_fly_frames[] = { FRAME(2, 2, 0.12f), FRAME(3, 2, 0.12f), FRAME(4, 2, 0.12f), FRAME(5, 2, 0.12f), }; static AnimFrame s_flyer_death_frames[] = { FRAME(6, 2, 0.3f), }; /* Projectiles */ static AnimFrame s_bullet_frames[] = { FRAME(0, 3, 0.08f), FRAME(1, 3, 0.08f), }; static AnimFrame s_impact_frames[] = { FRAME(2, 3, 0.05f), FRAME(3, 3, 0.05f), FRAME(4, 3, 0.08f), }; static AnimFrame s_enemy_bullet_frames[] = { FRAME(5, 3, 0.1f), FRAME(6, 3, 0.1f), }; /* Hazard animations */ static AnimFrame s_turret_idle_frames[] = { FRAME(0, 4, 1.0f), }; static AnimFrame s_turret_fire_frames[] = { FRAME(1, 4, 0.15f), }; static AnimFrame s_platform_frames[] = { FRAME(2, 4, 1.0f), }; static AnimFrame s_flame_vent_idle_frames[] = { FRAME(3, 4, 1.0f), }; static AnimFrame s_flame_vent_active_frames[] = { FRAME(4, 4, 0.08f), FRAME(5, 4, 0.08f), }; static AnimFrame s_force_field_on_frames[] = { FRAME(6, 4, 0.15f), FRAME(7, 4, 0.15f), }; static AnimFrame s_force_field_off_frames[] = { FRAME(0, 5, 1.0f), }; /* Powerups */ static AnimFrame s_powerup_health_frames[] = { FRAME(1, 5, 0.4f), FRAME(2, 5, 0.4f), }; static AnimFrame s_powerup_jetpack_frames[] = { FRAME(3, 5, 0.3f), FRAME(4, 5, 0.3f), }; static AnimFrame s_powerup_drone_frames[] = { FRAME(5, 5, 0.3f), FRAME(6, 5, 0.3f), }; /* Fuel powerup */ static AnimFrame s_powerup_fuel_frames[] = { FRAME(6, 6, 0.35f), FRAME(7, 6, 0.35f), }; /* Gun powerup */ static AnimFrame s_powerup_gun_frames[] = { FRAME(2, 6, 0.4f), FRAME(3, 6, 0.4f), }; /* Asteroid */ static AnimFrame s_asteroid_frames[] = { FRAME(4, 6, 0.15f), FRAME(5, 6, 0.15f), }; /* Drone companion */ static AnimFrame s_drone_frames[] = { FRAME(0, 6, 0.2f), FRAME(1, 6, 0.2f), }; /* Exported animation definitions */ AnimDef anim_player_idle; AnimDef anim_player_run; AnimDef anim_player_jump; AnimDef anim_player_fall; AnimDef anim_grunt_idle; AnimDef anim_grunt_walk; AnimDef anim_grunt_death; AnimDef anim_flyer_idle; AnimDef anim_flyer_fly; AnimDef anim_flyer_death; AnimDef anim_bullet; AnimDef anim_bullet_impact; AnimDef anim_enemy_bullet; AnimDef anim_turret_idle; AnimDef anim_turret_fire; AnimDef anim_platform; AnimDef anim_flame_vent_idle; AnimDef anim_flame_vent_active; AnimDef anim_force_field_on; AnimDef anim_force_field_off; AnimDef anim_powerup_health; AnimDef anim_powerup_jetpack; AnimDef anim_powerup_fuel; AnimDef anim_powerup_drone; AnimDef anim_powerup_gun; AnimDef anim_asteroid; AnimDef anim_drone; void sprites_init_anims(void) { anim_player_idle = (AnimDef){s_player_idle_frames, 2, true, NULL}; anim_player_run = (AnimDef){s_player_run_frames, 4, true, NULL}; anim_player_jump = (AnimDef){s_player_jump_frames, 1, false, NULL}; anim_player_fall = (AnimDef){s_player_fall_frames, 1, false, NULL}; anim_grunt_idle = (AnimDef){s_grunt_idle_frames, 2, true, NULL}; anim_grunt_walk = (AnimDef){s_grunt_walk_frames, 4, true, NULL}; anim_grunt_death = (AnimDef){s_grunt_death_frames, 1, false, NULL}; anim_flyer_idle = (AnimDef){s_flyer_idle_frames, 2, true, NULL}; anim_flyer_fly = (AnimDef){s_flyer_fly_frames, 4, true, NULL}; anim_flyer_death = (AnimDef){s_flyer_death_frames, 1, false, NULL}; anim_bullet = (AnimDef){s_bullet_frames, 2, true, NULL}; anim_bullet_impact = (AnimDef){s_impact_frames, 3, false, NULL}; anim_enemy_bullet = (AnimDef){s_enemy_bullet_frames, 2, true, NULL}; anim_turret_idle = (AnimDef){s_turret_idle_frames, 1, true, NULL}; anim_turret_fire = (AnimDef){s_turret_fire_frames, 1, false, NULL}; anim_platform = (AnimDef){s_platform_frames, 1, true, NULL}; anim_flame_vent_idle = (AnimDef){s_flame_vent_idle_frames, 1, true, NULL}; anim_flame_vent_active = (AnimDef){s_flame_vent_active_frames, 2, true, NULL}; anim_force_field_on = (AnimDef){s_force_field_on_frames, 2, true, NULL}; anim_force_field_off = (AnimDef){s_force_field_off_frames, 1, true, NULL}; anim_powerup_health = (AnimDef){s_powerup_health_frames, 2, true, NULL}; anim_powerup_jetpack = (AnimDef){s_powerup_jetpack_frames, 2, true, NULL}; anim_powerup_fuel = (AnimDef){s_powerup_fuel_frames, 2, true, NULL}; anim_powerup_drone = (AnimDef){s_powerup_drone_frames, 2, true, NULL}; anim_powerup_gun = (AnimDef){s_powerup_gun_frames, 2, true, NULL}; anim_asteroid = (AnimDef){s_asteroid_frames, 2, true, NULL}; anim_drone = (AnimDef){s_drone_frames, 2, true, NULL}; }