8c914f79b9a6b2155f1f9667ae0557bc6c15e901
[xscreensaver] / hacks / pacman.h
1 /*-
2  * Copyright (c) 2002 by Edwin de Jong <mauddib@gmx.net>.
3  *
4  * Permission to use, copy, modify, and distribute this software and its
5  * documentation for any purpose and without fee is hereby granted,
6  * provided that the above copyright notice appear in all copies and that
7  * both that copyright notice and this permission notice appear in
8  * supporting documentation.
9  *
10  * This file is provided AS IS with no warranties of any kind.  The author
11  * shall have no liability with respect to the infringement of copyrights,
12  * trade secrets or any patents by this file or any part thereof.  In no
13  * event will the author be liable for any lost revenue or profits or
14  * other special, indirect and consequential damages.
15  *
16  * Revision History:
17  *  3-May-2002: Added AI to pacman and ghosts, slowed down ghosts.
18  * 26-Nov-2001: Random level generator added
19  * 01-Nov-2000: Allocation checks
20  * 04-Jun-1997: Compatible with xscreensaver
21  *
22  */
23
24 #define LEVHEIGHT       32U
25 #define LEVWIDTH        40U
26
27 #define GETNB(n) ((1 << (n)) - 1)
28 #define TESTNB(v, n) (((1 << (n)) & v) != 0x00)
29 #define SNB(v, n) ((v) |= (1 << (n)))
30 #define UNSNB(v, n) ((v) &= ~(1 << (n)))
31 #define GHOSTS 4U
32 #define MAXMOUTH 11
33 #define MAXGPOS 2
34 #define MINGRIDSIZE 4
35 #define MINSIZE 3
36 #define NOWHERE 16383
37 #define START ((LRAND() & 1) ? 1 : 3)
38 #define MINDOTPERC 10
39
40 #define YELLOW (MI_NPIXELS(mi) / 6)
41 #define GREEN (23 * MI_NPIXELS(mi) / 64)
42 #define BLUE (45 * MI_NPIXELS(mi) / 64)
43 #define WHITE (MI_NPIXELS(mi))
44
45 #define LINEWIDTH       4
46 #define HLINEWIDTH      1
47 #define JAILHEIGHT      7
48 #define JAILWIDTH       8
49
50 #define GETFACTOR(x, y) ((x) > (y) ? 1 : ((x) < (y) ? -1 : 0))
51 #define SIGN(x) GETFACTOR((x), 0)
52 #define TRACEVECS 40
53
54 #define DEF_TRACKMOUSE "False"
55 static Bool trackmouse;
56
57 typedef struct { int vx, vy; } tracevec_struct;
58
59 typedef enum { inbox = 0, goingout, randdir, chasing, hiding } GhostState;
60 typedef enum { ps_eating = 0, ps_chasing, ps_hiding, ps_random } PacmanState;
61 typedef enum { GHOST_DANGER, GHOST_EATEN } GameState;
62
63 typedef struct {
64         unsigned int    col, row;
65         unsigned int    lastbox, nextcol, nextrow;
66         int             dead;
67         int             cfactor, rfactor;
68         int             cf, rf;
69         int             oldcf, oldrf;
70         int             timeleft;
71         GhostState      aistate;
72         /*int         color; */
73         int             speed;
74         XPoint          delta;
75         XPoint          err;
76 } ghoststruct;
77
78 typedef struct {
79         unsigned int    col, row;
80         unsigned int    lastbox, nextcol, nextrow;
81         int             mouthstage, mouthdirection;
82         int             cfactor, rfactor;
83         int             cf, rf;
84         int             oldcf, oldrf;
85         int             oldlx, oldly;
86         int             justate;
87         PacmanState     aistate;
88         tracevec_struct trace[TRACEVECS];
89         int             cur_trace;
90         int             state_change;
91         int             roundscore;
92         int             speed;
93         int             lastturn;
94         XPoint          delta;
95         XPoint          err;
96 } pacmanstruct;
97
98 typedef struct {
99         unsigned short  width, height;
100         unsigned short  nrows, ncols;
101         short           xs, ys, xb, yb;
102         short           incx, incy;
103         GC              stippledGC;
104         int             graphics_format;
105         pacmanstruct    pacman;
106         ghoststruct     *ghosts;
107         unsigned int    nghosts;
108         Pixmap          pacmanPixmap[4][MAXMOUTH];
109 /*      Pixmap          ghostPixmap[4][MAXGPOS];*/
110         Pixmap          ghostPixmap;
111         char            level[LEVHEIGHT * LEVWIDTH];
112         unsigned int    wallwidth;
113         unsigned int    dotsleft;
114         int             spritexs, spriteys, spritedx, spritedy;
115
116         GameState       gamestate;
117         unsigned int    timeleft;
118 } pacmangamestruct;
119
120 #define DIRVECS 4
121 static const struct { int dx, dy; } dirvecs[DIRVECS] =
122         { {-1, 0}, {0, 1}, {1, 0}, {0, -1}};
123
124 static pacmangamestruct *pacmangames = (pacmangamestruct *) NULL;
125
126 typedef char lev_t[LEVHEIGHT][LEVWIDTH + 1];
127
128 /* function type definitions */
129
130         /* level generation */
131 static int      creatlevelblock(lev_t *level, const unsigned x, 
132                                 const unsigned y);
133 static void     setblockto(lev_t *level, const unsigned x, const unsigned y, 
134                                 const char c);
135 static int      checkset(lev_t *level, const unsigned x, const unsigned y);
136 static int      checksetout(lev_t *level, const unsigned x, const unsigned y);
137 static int      checkunsetdef(lev_t *level, const unsigned x, const unsigned y);
138 static void     clearlevel(lev_t *level);
139 static void     copylevel(char *dest, lev_t *level);
140 static void     createjail(lev_t *level, const unsigned width, 
141                                 const unsigned height);
142 static void     finishjail(lev_t *level, const unsigned width, 
143                                 const unsigned height);
144 static int      tryset(lev_t *level, const unsigned xpos, const unsigned ypos, 
145                                 const char *block);
146 static int      creatlevelblock(lev_t *level, const unsigned x, 
147                                 const unsigned y);
148 static void     filllevel(lev_t *level);
149 static void     frmtlevel(lev_t *level);
150 static unsigned countdots(ModeInfo * mi);
151 static int      createnewlevel(ModeInfo * mi);
152 static int      check_pos(pacmangamestruct *pp, int y, int x, int ghostpass);
153 static int      check_dot(pacmangamestruct *pp, unsigned int x, unsigned int y);
154
155         /* graphics rendering */
156 static void     drawlevel(ModeInfo * mi);
157
158         /* AI */
159 static int      ghost_get_posdirs(pacmangamestruct *pp, int *posdirs, 
160                                 ghoststruct *g);
161 static void     ghost_random(pacmangamestruct *pp, ghoststruct *g);
162 static void     ghost_chasing(pacmangamestruct *pp, ghoststruct *g);
163 static void     ghost_hiding(pacmangamestruct *pp, ghoststruct *g);
164 static void     ghost_update(pacmangamestruct *pp, ghoststruct *g);
165
166 static void     pac_dot_vec(pacmangamestruct *pp, pacmanstruct *p, 
167                                 long *vx, long *vy);
168 static int      pac_ghost_prox_and_vector(pacmangamestruct *pp, 
169                                 pacmanstruct *p, int *vx, int *vy);
170 static int      pac_get_posdirs(pacmangamestruct *pp, pacmanstruct *p, 
171                                 int *posdirs);
172 static void     pac_clear_trace(pacmanstruct *p);
173 static void     pac_save_trace(pacmanstruct *p, const int vx, const int vy);
174 static int      pac_check_trace(const pacmanstruct *p, const int vx, 
175                                 const int vy);
176 static void     pac_eating(pacmangamestruct *pp, pacmanstruct *p);
177 #if 0
178 static void     pac_chasing(pacmangamestruct *pp, pacmanstruct *p);
179 #endif
180 static void     pac_random(pacmangamestruct *pp, pacmanstruct *p);
181 static int      pac_get_vector_screen(pacmangamestruct *pp, pacmanstruct *p, 
182                         const int x, const int y, int *vx, int *vy);
183 static int      pac_trackmouse(ModeInfo * mi, pacmangamestruct *pp, 
184                         pacmanstruct *p);
185 static void     pac_update(ModeInfo * mi, pacmangamestruct *pp, 
186                         pacmanstruct *p);
187
188         /* generic functions */
189 static void     repopulate(ModeInfo * mi);