1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#ifndef _GAME_H
#define _GAME_H
#ifndef LOCAL
#define LOCAL extern
#else
#define WALK_CYCLE 4
// walk animation frames, private
const uint8_t walk_frames[WALK_CYCLE] = { 0, 1, 0, 2 };
#endif
/**
* Game implementation and helpers.
*/
// map size in tiles
#define MAP_W 32
#define MAP_H 21
// some useful tiles
#define LAST_SOLID_TILE 10
#define BATTERY_TILE 224
#define MAX_LIVES 3
// player + other entities
#define MAX_ENTITIES 11
// MSB in our entity data
#define DIR_FLAG 128
// sprite direction
#define DIR_LEFT 1
#define DIR_RIGHT 0
// how long we wait between animation frames
#define FRAME_WAIT 3
// how long the player is invulnerable after death
// time in frames
#define INVUL_TIME 64
// show some game frames before jumping to the game over
// screen; this helps the player to know what happened
#define GAMEOVER_DELAY 72
// types for our pattern groups
// used by spman
enum pattern_type
{
PAT_PLAYER = 0,
PAT_PLAYER_FLIP,
PAT_ENEMY,
PAT_ENEMY_FLIP,
};
// entity types in the same order
// used in the map (see map_conf.json)
enum entity_type
{
ET_UNUSED = 0,
ET_PLAYER,
ET_ENEMY,
};
// notes:
//
// - x, y are the logic position on the map
// - sp.x, sp.y are the position on screen
struct entity
{
uint8_t type;
uint8_t x;
uint8_t y;
uint8_t dir;
uint8_t pat;
uint8_t flags;
uint8_t delay;
uint8_t frame;
void (*update)();
};
void run_game();
void update_player();
void update_enemy();
void draw_map();
void draw_hud();
void erase_battery(uint8_t x, uint8_t y);
uint8_t is_map_blocked(uint8_t x, uint8_t y);
uint8_t is_map_elevator_up(uint8_t x, uint8_t y);
uint8_t is_map_elevator_down(uint8_t x, uint8_t y);
// our entities; the player is 0
LOCAL struct entity entities[MAX_ENTITIES];
// used to read our control method
LOCAL uint8_t control;
// current map; we don't use ROM because we will modify it
LOCAL const uint8_t *cur_map;
// current map tile map (map data, not entities)
LOCAL uint8_t cur_map_data[MAP_W * MAP_H];
// player lives
LOCAL uint8_t lives;
// invulnerability time after death
LOCAL uint8_t invuln;
// batteries left
LOCAL uint8_t batteries;
// show dome delay once the lives run out
LOCAL uint8_t gameover_delay;
// used by all entities
LOCAL struct sprite_attr sp;
// current entity
LOCAL struct entity *self;
#ifdef LOCAL
#undef LOCAL
#endif
#endif // _GAME_H
|