Initial checkin. Not there yet.
[xor] / xor.h
CommitLineData
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
63typedef 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
146typedef struct ui_state ui_state;
147
148/* --- Player structure --- */
149
150typedef 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
161typedef 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
172enum {
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
183typedef struct undo_move {
184 struct undo_move *next;
185 undo_action *act;
186} undo_move;
187
188/* --- Game state --- */
189
190typedef 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
202typedef 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
230typedef struct point { int x, y; } point;
231
232/*----- Global variables --------------------------------------------------*/
233
234extern const cellinfo *cellmap[];
235
236/*----- Cell attributes ---------------------------------------------------*/
237
238extern void cellinfo_init(void);
239
240/*----- Level management --------------------------------------------------*/
241
242extern int lev_findnext(const level */*l*/, int /*c*/,
243 int */*x*/, int */*y*/);
244extern int lev_findcell(const level */*l*/, int /*c*/,
245 int */*x*/, int */*y*/);
246extern level *lev_read(FILE */*fp*/);
247extern void lev_write(const level */*l*/, FILE */*fp*/);
248extern void lev_free(level */*l*/);
249extern level *lev_copy(const level */*l*/);
250
251/*----- User interface ----------------------------------------------------*/
252
253extern void ui_frame(ui_state */*u*/);
254extern void ui_message(ui_state */*u*/, const char */*p*/);
255extern void ui_explode(ui_state */*u*/, const point */*pt*/, int /*n*/);
256extern void ui_track(ui_state */*u*/, int /*x*/, int /*y*/);
257extern void ui_update(ui_state */*u*/);
258extern void ui_switch(ui_state */*u*/);
259extern void ui_init(void);
260extern void ui_update(ui_state */*u*/);
261extern ui_state *ui_start(level */*l*/, int /*x*/, int /*y*/);
262extern void ui_go(game_state */*g*/, ui_state */*u*/);
263extern void ui_destroy(ui_state */*u*/);
264extern void ui_exit(void);
265
266/*----- Undo management ---------------------------------------------------*/
267
268extern void undo_init(game_state */*g*/);
269extern void undo_begin(game_state */*g*/);
270extern void undo_cell(game_state */*g*/, int /*x*/, int /*y*/, int /*c*/);
271extern void undo_die(game_state */*g*/, game_player */*p*/);
272extern void undo_pmove(game_state */*g*/);
273extern void undo_levelf(game_state */*g*/);
274extern void undo_mask(game_state */*g*/);
275extern void undo_switch(game_state */*g*/);
276extern void undo_commit(game_state */*g*/);
277extern void undo(game_state */*g*/);
278extern void redo(game_state */*g*/);
279extern void undo_free(game_state */*g*/);
280
281/*----- Game engine -------------------------------------------------------*/
282
283extern void game_explode(game_state */*g*/, const point */*pt*/, int /*n*/);
284extern void game_die(game_state */*g*/, int /*x*/, int /*y*/);
285extern void game_moveobj(game_state */*g*/, int /*x*/, int /*y*/,
286 int /*xx*/, int /*yy*/);
287extern void game_switchto(game_state *g, game_player */*p*/);
288extern int game_switch(game_state */*g*/);
289extern void game_move(game_state */*g*/, int /*dx*/, int /*dy*/);
290extern void game_go(level */*l*/);
291extern void game_quit(game_state */*g*/);
292
293/*----- That's all, folks -------------------------------------------------*/
294
295#ifdef __cplusplus
296 }
297#endif
298
299#endif