chiark / gitweb /
Initial checkin. Not there yet.
[xor] / xor.h
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