190 lines
6.0 KiB
C
190 lines
6.0 KiB
C
|
/*-
|
||
|
* Copyright (c) 2002 by Edwin de Jong <mauddib@gmx.net>.
|
||
|
*
|
||
|
* Permission to use, copy, modify, and distribute this software and its
|
||
|
* documentation for any purpose and without fee is hereby granted,
|
||
|
* provided that the above copyright notice appear in all copies and that
|
||
|
* both that copyright notice and this permission notice appear in
|
||
|
* supporting documentation.
|
||
|
*
|
||
|
* This file is provided AS IS with no warranties of any kind. The author
|
||
|
* shall have no liability with respect to the infringement of copyrights,
|
||
|
* trade secrets or any patents by this file or any part thereof. In no
|
||
|
* event will the author be liable for any lost revenue or profits or
|
||
|
* other special, indirect and consequential damages.
|
||
|
*
|
||
|
* Revision History:
|
||
|
* 3-May-2002: Added AI to pacman and ghosts, slowed down ghosts.
|
||
|
* 26-Nov-2001: Random level generator added
|
||
|
* 01-Nov-2000: Allocation checks
|
||
|
* 04-Jun-1997: Compatible with xscreensaver
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#define LEVHEIGHT 32U
|
||
|
#define LEVWIDTH 40U
|
||
|
|
||
|
#define GETNB(n) ((1 << (n)) - 1)
|
||
|
#define TESTNB(v, n) (((1 << (n)) & v) != 0x00)
|
||
|
#define SNB(v, n) ((v) |= (1 << (n)))
|
||
|
#define UNSNB(v, n) ((v) &= ~(1 << (n)))
|
||
|
#define GHOSTS 4U
|
||
|
#define MAXMOUTH 11
|
||
|
#define MAXGPOS 2
|
||
|
#define MINGRIDSIZE 4
|
||
|
#define MINSIZE 3
|
||
|
#define NOWHERE 16383
|
||
|
#define START ((LRAND() & 1) ? 1 : 3)
|
||
|
#define MINDOTPERC 10
|
||
|
|
||
|
#define YELLOW (MI_NPIXELS(mi) / 6)
|
||
|
#define GREEN (23 * MI_NPIXELS(mi) / 64)
|
||
|
#define BLUE (45 * MI_NPIXELS(mi) / 64)
|
||
|
#define WHITE (MI_NPIXELS(mi))
|
||
|
|
||
|
#define LINEWIDTH 4
|
||
|
#define HLINEWIDTH 1
|
||
|
#define JAILHEIGHT 7
|
||
|
#define JAILWIDTH 8
|
||
|
|
||
|
#define GETFACTOR(x, y) ((x) > (y) ? 1 : ((x) < (y) ? -1 : 0))
|
||
|
#define SIGN(x) GETFACTOR((x), 0)
|
||
|
#define TRACEVECS 40
|
||
|
|
||
|
#define DEF_TRACKMOUSE "False"
|
||
|
static Bool trackmouse;
|
||
|
|
||
|
typedef struct { int vx, vy; } tracevec_struct;
|
||
|
|
||
|
typedef enum { inbox = 0, goingout, randdir, chasing, hiding } GhostState;
|
||
|
typedef enum { ps_eating = 0, ps_chasing, ps_hiding, ps_random } PacmanState;
|
||
|
typedef enum { GHOST_DANGER, GHOST_EATEN } GameState;
|
||
|
|
||
|
typedef struct {
|
||
|
unsigned int col, row;
|
||
|
unsigned int lastbox, nextcol, nextrow;
|
||
|
int dead;
|
||
|
int cfactor, rfactor;
|
||
|
int cf, rf;
|
||
|
int oldcf, oldrf;
|
||
|
int timeleft;
|
||
|
GhostState aistate;
|
||
|
/*int color; */
|
||
|
int speed;
|
||
|
XPoint delta;
|
||
|
XPoint err;
|
||
|
} ghoststruct;
|
||
|
|
||
|
typedef struct {
|
||
|
unsigned int col, row;
|
||
|
unsigned int lastbox, nextcol, nextrow;
|
||
|
int mouthstage, mouthdirection;
|
||
|
int cfactor, rfactor;
|
||
|
int cf, rf;
|
||
|
int oldcf, oldrf;
|
||
|
int oldlx, oldly;
|
||
|
int justate;
|
||
|
PacmanState aistate;
|
||
|
tracevec_struct trace[TRACEVECS];
|
||
|
int cur_trace;
|
||
|
int state_change;
|
||
|
int roundscore;
|
||
|
int speed;
|
||
|
int lastturn;
|
||
|
XPoint delta;
|
||
|
XPoint err;
|
||
|
} pacmanstruct;
|
||
|
|
||
|
typedef struct {
|
||
|
unsigned short width, height;
|
||
|
unsigned short nrows, ncols;
|
||
|
short xs, ys, xb, yb;
|
||
|
short incx, incy;
|
||
|
GC stippledGC;
|
||
|
int graphics_format;
|
||
|
pacmanstruct pacman;
|
||
|
ghoststruct *ghosts;
|
||
|
unsigned int nghosts;
|
||
|
Pixmap pacmanPixmap[4][MAXMOUTH];
|
||
|
/* Pixmap ghostPixmap[4][MAXGPOS];*/
|
||
|
Pixmap ghostPixmap;
|
||
|
char level[LEVHEIGHT * LEVWIDTH];
|
||
|
unsigned int wallwidth;
|
||
|
unsigned int dotsleft;
|
||
|
int spritexs, spriteys, spritedx, spritedy;
|
||
|
|
||
|
GameState gamestate;
|
||
|
unsigned int timeleft;
|
||
|
} pacmangamestruct;
|
||
|
|
||
|
#define DIRVECS 4
|
||
|
static const struct { int dx, dy; } dirvecs[DIRVECS] =
|
||
|
{ {-1, 0}, {0, 1}, {1, 0}, {0, -1}};
|
||
|
|
||
|
static pacmangamestruct *pacmangames = (pacmangamestruct *) NULL;
|
||
|
|
||
|
typedef char lev_t[LEVHEIGHT][LEVWIDTH + 1];
|
||
|
|
||
|
/* function type definitions */
|
||
|
|
||
|
/* level generation */
|
||
|
static int creatlevelblock(lev_t *level, const unsigned x,
|
||
|
const unsigned y);
|
||
|
static void setblockto(lev_t *level, const unsigned x, const unsigned y,
|
||
|
const char c);
|
||
|
static int checkset(lev_t *level, const unsigned x, const unsigned y);
|
||
|
static int checksetout(lev_t *level, const unsigned x, const unsigned y);
|
||
|
static int checkunsetdef(lev_t *level, const unsigned x, const unsigned y);
|
||
|
static void clearlevel(lev_t *level);
|
||
|
static void copylevel(char *dest, lev_t *level);
|
||
|
static void createjail(lev_t *level, const unsigned width,
|
||
|
const unsigned height);
|
||
|
static void finishjail(lev_t *level, const unsigned width,
|
||
|
const unsigned height);
|
||
|
static int tryset(lev_t *level, const unsigned xpos, const unsigned ypos,
|
||
|
const char *block);
|
||
|
static int creatlevelblock(lev_t *level, const unsigned x,
|
||
|
const unsigned y);
|
||
|
static void filllevel(lev_t *level);
|
||
|
static void frmtlevel(lev_t *level);
|
||
|
static unsigned countdots(ModeInfo * mi);
|
||
|
static int createnewlevel(ModeInfo * mi);
|
||
|
static int check_pos(pacmangamestruct *pp, int y, int x, int ghostpass);
|
||
|
static int check_dot(pacmangamestruct *pp, unsigned int x, unsigned int y);
|
||
|
|
||
|
/* graphics rendering */
|
||
|
static void drawlevel(ModeInfo * mi);
|
||
|
|
||
|
/* AI */
|
||
|
static int ghost_get_posdirs(pacmangamestruct *pp, int *posdirs,
|
||
|
ghoststruct *g);
|
||
|
static void ghost_random(pacmangamestruct *pp, ghoststruct *g);
|
||
|
static void ghost_chasing(pacmangamestruct *pp, ghoststruct *g);
|
||
|
static void ghost_hiding(pacmangamestruct *pp, ghoststruct *g);
|
||
|
static void ghost_update(pacmangamestruct *pp, ghoststruct *g);
|
||
|
|
||
|
static void pac_dot_vec(pacmangamestruct *pp, pacmanstruct *p,
|
||
|
long *vx, long *vy);
|
||
|
static int pac_ghost_prox_and_vector(pacmangamestruct *pp,
|
||
|
pacmanstruct *p, long *vx, long *vy);
|
||
|
static int pac_get_posdirs(pacmangamestruct *pp, pacmanstruct *p,
|
||
|
int *posdirs);
|
||
|
static void pac_clear_trace(pacmanstruct *p);
|
||
|
static void pac_save_trace(pacmanstruct *p, const int vx, const int vy);
|
||
|
static int pac_check_trace(const pacmanstruct *p, const int vx,
|
||
|
const int vy);
|
||
|
static void pac_eating(pacmangamestruct *pp, pacmanstruct *p);
|
||
|
#if 0
|
||
|
static void pac_chasing(pacmangamestruct *pp, pacmanstruct *p);
|
||
|
#endif
|
||
|
static void pac_random(pacmangamestruct *pp, pacmanstruct *p);
|
||
|
static int pac_get_vector_screen(pacmangamestruct *pp, pacmanstruct *p,
|
||
|
const int x, const int y, int *vx, int *vy);
|
||
|
static int pac_trackmouse(ModeInfo * mi, pacmangamestruct *pp,
|
||
|
pacmanstruct *p);
|
||
|
static void pac_update(ModeInfo * mi, pacmangamestruct *pp,
|
||
|
pacmanstruct *p);
|
||
|
|
||
|
/* generic functions */
|
||
|
static void repopulate(ModeInfo * mi);
|