fc27aa70 |
1 | /* -*-c-*- |
2 | * |
3 | * $Id: xor.h,v 1.1 2003/12/12 10:55:30 mdw Exp $ |
4 | * |
5 | * Main header for XOR |
6 | * |
7 | * (c) 2003 Straylight/Edgeware |
8 | */ |
9 | |
10 | /*----- Licensing notice --------------------------------------------------* |
11 | * |
12 | * This file is part of XOR. |
13 | * |
14 | * XOR is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation; either version 2 of the License, or |
17 | * (at your option) any later version. |
18 | * |
19 | * XOR is distributed in the hope that it will be useful, |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | * GNU General Public License for more details. |
23 | * |
24 | * You should have received a copy of the GNU General Public License |
25 | * along with XOR; if not, write to the Free Software Foundation, |
26 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
27 | */ |
28 | |
29 | /*----- Revision history --------------------------------------------------* |
30 | * |
31 | * $Log: xor.h,v $ |
32 | * Revision 1.1 2003/12/12 10:55:30 mdw |
33 | * Initial checkin. Not there yet. |
34 | * |
35 | */ |
36 | |
37 | #ifndef XOR_H |
38 | #define XOR_H |
39 | |
40 | #ifdef __cplusplus |
41 | extern "C" { |
42 | #endif |
43 | |
44 | /*----- Header files ------------------------------------------------------*/ |
45 | |
46 | #include "config.h" |
47 | |
48 | #include <ctype.h> |
49 | #include <limits.h> |
50 | #include <stdio.h> |
51 | #include <string.h> |
52 | |
53 | #include <unistd.h> |
54 | |
55 | #include <mLib/alloc.h> |
56 | #include <mLib/darray.h> |
57 | #include <mLib/dstr.h> |
58 | #include <mLib/str.h> |
59 | #include <mLib/sub.h> |
60 | |
61 | /*----- Data structures ---------------------------------------------------*/ |
62 | |
63 | typedef struct level { |
64 | int w, h; /* Width and height, in cells */ |
65 | char *name; /* Level name */ |
66 | unsigned f; /* Various flags */ |
67 | int m, mtot; /* Masks collected, and total */ |
68 | int v, vtot; /* Moves made, and allowed */ |
69 | int *d; /* Level data, row-major order */ |
70 | } level; |
71 | |
72 | #define LF_NWMAP 1u /* North-west map collected */ |
73 | #define LF_NEMAP 2u /* North-east map collected */ |
74 | #define LF_SWMAP 4u /* South-west map collected */ |
75 | #define LF_SEMAP 8u /* South-east map collected */ |
76 | #define LF_DARK 16u /* Someone turned the lights out */ |
77 | |
78 | #define LF_MAP "1234D" /* Map bits to characters */ |
79 | |
80 | /* --- Cells and their meanings --- */ |
81 | |
82 | #define C_PLAYER '$' /* Active player */ |
83 | #define C_SPARE '%' /* Inactive player */ |
84 | #define C_WALL '#' /* Solid wall */ |
85 | #define C_EXIT '*' /* Exit door */ |
86 | #define C_EMPTY ' ' /* Empty space */ |
87 | #define C_MASK '+' /* Mask */ |
88 | #define C_NWMAP '1' /* North-west map segment */ |
89 | #define C_NEMAP '2' /* North-east map segment */ |
90 | #define C_SWMAP '3' /* South-west map segment */ |
91 | #define C_SEMAP '4' /* South-east map segment */ |
92 | #define C_UKMAP 'M' /* Unknown map segment */ |
93 | #define C_DOT '-' /* Dots -- horizontal force-field */ |
94 | #define C_WAVE '|' /* Waves -- vertical force-field */ |
95 | #define C_CHICKEN '<' /* Chicken -- moves left */ |
96 | #define C_FISH 'V' /* Fish -- moves downwards */ |
97 | #define C_HBOMB 'C' /* H-bomb -- moves like chicken */ |
98 | #define C_VBOMB 'U' /* V-bomb -- moves like fish */ |
99 | #define C_DOLLY '@' /* Dolly -- slides about */ |
100 | #define C_SWITCH '~' /* Light-switch mask */ |
101 | #define C_BMUS 'O' /* Teleport pad */ |
102 | |
103 | /* --- Celll flags --- */ |
104 | |
105 | #define CF_CELLMASK 255u /* Mask for cell type */ |
106 | #define CF_INFLIGHT 256u /* Object is currently moving */ |
107 | #define CF_DOLLYUP 0u /* Dolly moving up */ |
108 | #define CF_DOLLYDOWN 512u /* Dolly moving down */ |
109 | #define CF_DOLLYLEFT 1024u /* Dolly moving left */ |
110 | #define CF_DOLLYRIGHT 1536u /* Dolly moving right */ |
111 | #define CF_DOLLYMASK 1536u /* Mask for dolly movement */ |
112 | |
113 | /* --- Macros for accessing the map data --- */ |
114 | |
115 | #define CELLREF(l, x, y) \ |
116 | ((l)->d[(x) + (y) * (l)->w]) |
117 | |
118 | #define CELLOK(l, x, y) \ |
119 | ((x) >= 0 && (x) < (l)->w && (y) >= 0 && (y) < (l)->h) |
120 | |
121 | #define CELLSET(l, x, y, c) \ |
122 | (CELLOK((l), (x), (y)) ? \ |
123 | CELLREF((l), (x), (y)) = (c), (void)0 : \ |
124 | (void)0) |
125 | |
126 | #define CELL(l, x, y) \ |
127 | (CELLOK((l), (x), (y)) ? \ |
128 | CELLREF((l), (x), (y)) : \ |
129 | C_WALL) |
130 | |
131 | #define CELLSETFL(l, x, y, f) \ |
132 | (CELLOK((l), (x), (y)) ? \ |
133 | CELLREF((l), (x), (y)) |= (f), (void)0 : \ |
134 | (void)0) |
135 | |
136 | #define CELLCLRFL(l, x, y, f) \ |
137 | (CELLOK((l), (x), (y)) ? \ |
138 | CELLREF((l), (x), (y)) &= ~(f), (void)0 : \ |
139 | (void)0) |
140 | |
141 | /* --- UI information --- * |
142 | * |
143 | * This is private to the UI layer. |
144 | */ |
145 | |
146 | typedef struct ui_state ui_state; |
147 | |
148 | /* --- Player structure --- */ |
149 | |
150 | typedef struct game_player { |
151 | struct game_player *next, *prev; /* Link in list (forward only) */ |
152 | int x, y; /* Current position */ |
153 | unsigned f; /* Flags */ |
154 | ui_state *u; /* User interface state */ |
155 | } game_player; |
156 | |
157 | #define PF_DEAD 1u /* Player has been killed */ |
158 | |
159 | /* --- Undo structures --- */ |
160 | |
161 | typedef struct undo_action { |
162 | struct undo_action *next; /* Next action in chian */ |
163 | int type; /* What kind of thing happened */ |
164 | union { |
165 | struct { int x, y, c; } c; /* Cell change */ |
166 | game_player *p; /* Player */ |
167 | unsigned f; /* Flags to restore */ |
168 | int n; /* Counter to restore */ |
169 | } u; |
170 | } undo_action; |
171 | |
172 | enum { |
173 | A_CELL, /* Cell changed contents */ |
174 | A_DIE, /* Player died */ |
175 | A_LIVE, /* Player became alive */ |
176 | A_LEVEL, /* Level flags changed */ |
177 | A_MASK, /* Mask count changed */ |
178 | A_MOVE, /* Player moved */ |
179 | A_SWITCH, /* Switch to other player */ |
180 | A_END |
181 | }; |
182 | |
183 | typedef struct undo_move { |
184 | struct undo_move *next; |
185 | undo_action *act; |
186 | } undo_move; |
187 | |
188 | /* --- Game state --- */ |
189 | |
190 | typedef struct game_state { |
191 | struct level *l; /* Level information */ |
192 | game_player *p, *ptail; /* Player list */ |
193 | unsigned f; /* Various flags */ |
194 | undo_move *u, *r, *m; /* Undo, redo and current lists */ |
195 | } game_state; |
196 | |
197 | #define GF_QUIT 1u |
198 | #define GF_WIN 2u |
199 | |
200 | /* --- The cell attributes table --- */ |
201 | |
202 | typedef struct cellinfo { |
203 | int c; /* Cell type */ |
204 | unsigned f; /* Various flags */ |
205 | |
206 | void (*hit)(game_state *, int /*x*/, int /*y*/, int /*hx*/, int /*hy*/); |
207 | /* Object at @(x, y)@ has been struck by another object (e.g., a chicken) |
208 | which is now at @(hx, hy)@. */ |
209 | |
210 | int (*nudge)(game_state *, int /*x*/, int /*y*/, int /*dx*/, int /*dy*/); |
211 | /* Object is being nudged by player in given direction. Answer @0@ if |
212 | nothing happens (and the player cannot enter), @1@ if it's OK and the |
213 | space is vacated, or @-1@ if something strange happened. */ |
214 | |
215 | int (*moveh)(game_state *, int /*x*/, int /*y*/); |
216 | int (*movev)(game_state *, int /*x*/, int /*y*/); |
217 | /* See if object can move on its own horizontally or vertically. Return |
218 | * zero if it won't move, or nonzero otherwise. */ |
219 | } cellinfo; |
220 | |
221 | #define CF_HIDE 1u /* Invisible in the dark */ |
222 | #define CF_MASK 2u /* Must collect these */ |
223 | #define CF_HPASS 4u /* Object is passable horizontally */ |
224 | #define CF_VPASS 8u /* Object is passable vertically */ |
225 | #define CF_PLAYER 16u /* Object is a player */ |
226 | #define CF_MAP 32u /* Object shows up on map */ |
227 | |
228 | /* --- Other structures --- */ |
229 | |
230 | typedef struct point { int x, y; } point; |
231 | |
232 | /*----- Global variables --------------------------------------------------*/ |
233 | |
234 | extern const cellinfo *cellmap[]; |
235 | |
236 | /*----- Cell attributes ---------------------------------------------------*/ |
237 | |
238 | extern void cellinfo_init(void); |
239 | |
240 | /*----- Level management --------------------------------------------------*/ |
241 | |
242 | extern int lev_findnext(const level */*l*/, int /*c*/, |
243 | int */*x*/, int */*y*/); |
244 | extern int lev_findcell(const level */*l*/, int /*c*/, |
245 | int */*x*/, int */*y*/); |
246 | extern level *lev_read(FILE */*fp*/); |
247 | extern void lev_write(const level */*l*/, FILE */*fp*/); |
248 | extern void lev_free(level */*l*/); |
249 | extern level *lev_copy(const level */*l*/); |
250 | |
251 | /*----- User interface ----------------------------------------------------*/ |
252 | |
253 | extern void ui_frame(ui_state */*u*/); |
254 | extern void ui_message(ui_state */*u*/, const char */*p*/); |
255 | extern void ui_explode(ui_state */*u*/, const point */*pt*/, int /*n*/); |
256 | extern void ui_track(ui_state */*u*/, int /*x*/, int /*y*/); |
257 | extern void ui_update(ui_state */*u*/); |
258 | extern void ui_switch(ui_state */*u*/); |
259 | extern void ui_init(void); |
260 | extern void ui_update(ui_state */*u*/); |
261 | extern ui_state *ui_start(level */*l*/, int /*x*/, int /*y*/); |
262 | extern void ui_go(game_state */*g*/, ui_state */*u*/); |
263 | extern void ui_destroy(ui_state */*u*/); |
264 | extern void ui_exit(void); |
265 | |
266 | /*----- Undo management ---------------------------------------------------*/ |
267 | |
268 | extern void undo_init(game_state */*g*/); |
269 | extern void undo_begin(game_state */*g*/); |
270 | extern void undo_cell(game_state */*g*/, int /*x*/, int /*y*/, int /*c*/); |
271 | extern void undo_die(game_state */*g*/, game_player */*p*/); |
272 | extern void undo_pmove(game_state */*g*/); |
273 | extern void undo_levelf(game_state */*g*/); |
274 | extern void undo_mask(game_state */*g*/); |
275 | extern void undo_switch(game_state */*g*/); |
276 | extern void undo_commit(game_state */*g*/); |
277 | extern void undo(game_state */*g*/); |
278 | extern void redo(game_state */*g*/); |
279 | extern void undo_free(game_state */*g*/); |
280 | |
281 | /*----- Game engine -------------------------------------------------------*/ |
282 | |
283 | extern void game_explode(game_state */*g*/, const point */*pt*/, int /*n*/); |
284 | extern void game_die(game_state */*g*/, int /*x*/, int /*y*/); |
285 | extern void game_moveobj(game_state */*g*/, int /*x*/, int /*y*/, |
286 | int /*xx*/, int /*yy*/); |
287 | extern void game_switchto(game_state *g, game_player */*p*/); |
288 | extern int game_switch(game_state */*g*/); |
289 | extern void game_move(game_state */*g*/, int /*dx*/, int /*dy*/); |
290 | extern void game_go(level */*l*/); |
291 | extern void game_quit(game_state */*g*/); |
292 | |
293 | /*----- That's all, folks -------------------------------------------------*/ |
294 | |
295 | #ifdef __cplusplus |
296 | } |
297 | #endif |
298 | |
299 | #endif |