1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/* Glotski Header */
/* Defines datatypes and low-level (#define) functions */
#define GLOTNAME "Glotski"
#define GLOTVER "0.2"
#ifndef LEVELPATH
#define LEVELPATH "/usr/share/games/glotski/"
#endif
enum _glottype;
typedef enum _glottype glottype;
enum _dirtype;
typedef enum _dirtype dirtype;
enum _glottype {IMMOBILE = 0, HORIZONTAL, VERTICAL, BIMOBILE};
enum _dirtype {LEFT = 0, UP, RIGHT, DOWN}; /* Harkens back to GFP */
#define X 0
#define Y 1
#define SPLIT 2
struct _pair;
typedef struct _pair pair;
struct _glot;
typedef struct _glot glot;
struct _goal;
typedef struct _goal goal;
struct _setuplist;
typedef struct _setuplist setuplist;
struct _movelist;
typedef struct _movelist movelist;
struct _level;
typedef struct _level level;
struct _pair { /* A pair of void pointers as one object */
void *a;
void *b;
};
struct _glot { /* A moving block, aka a glot */
glottype type; /* The type of glot */
level *parent; /* The level that the glot belongs to */
unsigned int red, green, blue; /* The glot's color */
int loc[2]; /* Location - offset of mask. Can be negative. */
int size[2]; /* Bounding box of piece */
char *field; /* Mask of piece's shape */
int id; /* The designation in the parsed file */
void *element; /* The graphical element representing the glot */
};
struct _goal { /* A doubly-linked list of goals */
glot **field; /* Pointers to necessary glots (or NULL for unnecessary) */
int size[2]; /* Redundant, kinda, but necessary for LOOKUP macro */
goal *prev; /* Previous goal satisfied */
goal *next; /* Next goal to be satisfied */
};
struct _setuplist { /* A singly-linked list of glots */
glot *this; /* The current glot */
setuplist *next; /* The glot after that */
};
struct _movelist { /* A doubly-linked list of moves */
glot *myglot; /* The piece being moved */
int startloc[2]; /* The location the piece began with */
int endloc[2]; /* The new location of the piece */
int goalsat; /* Did it satisfy a goal? */
movelist *prev; /* The previous move made (null if the first move) */
movelist *next; /* The next move made (null if the last move */
};
struct _level { /* A series of glots with a goal, aka a level*/
glot **field; /* Pointers to glots when full, null when empty */
int size[2]; /* Size of board, X and Y */
double usize[2]; /* Unit size for drawing, X and Y (start as 32) */
double scale[2]; /* Scale, X and Y (start as 1) (for bevel sizes) */
double zoom[2]; /* Zoom, X and Y (start as 1) (for resizing win)*/
double gzoom[2]; /* Goal window zoom, X and Y (start as 0.5) */
setuplist *setup; /* List of glots - the board setup */
goal *mygoal; /* Trying to bring level to this glot state */
int state; /* What goal has currently been achieved */
int numgoals; /* Total number of goals */
int *equiv; /* For the eq routines */
int nextid; /* The next identifier to be assigned: starts at 0 */
/* Also functions as number of glots on level */
int uniteid; /* The next union identifier to be assigned: starts at 1 */
movelist *move; /* The current move being made */
int nummoves; /* The number of moves made */
int step; /* The minimum number of moves needed to win */
int won; /* Beat level */
void *lelement; /* The graphical element representing the level */
void *gelement; /* The graphical element representing the goal */
void *telement; /* The UI element representing the goal toggle */
void *selement; /* The UI element representing the status */
int showgoal; /* Show the goal element? (Default: True) */
};
/* mod 2 finds axis */
/* if dirtype >= SPLIT or dirtype & SPLIT then negative, else positive */
/* if (axis + 1) & jifftype then piece can move in that direction */
#define AXIS(a) ((a) & 1) /* 0 if X axis, 1 if Y axis */
#define SIGN(a) ((a) & SPLIT) /* true if positive direction */
#define COMPAT(piece, dir) ((AXIS(dir)+1) & (piece->type)) /* true if piece can
go that dir */
#define LOOKUP(w, x, y) ((w)->field[(x) + (y)*(w)->size[X]])
#define XDIR(newx, prevx) (((newx) < (prevx)) ? LEFT : RIGHT)
#define YDIR(newy, prevy) (((newy) < (prevy)) ? UP : DOWN)
/* From glotski.c */
level *makelevel(int xsize, int ysize);
glot *makeglot(level *mylevel, int xloc, int yloc);
goal *makegoal(level *mylevel);
movelist *makemove(level *mylevel);
void deleteglot(glot *myglot);
void deletegoal(goal *mygoal);
void popgoal(goal **mygoal);
void deletelevel(level *mylevel);
void deletemove(movelist *mymove);
void popmove(movelist **mymove);
int goalequiv(level *mylevel);
int glotplace(glot *myglot, int xloc, int yloc, int perform);
int glotmove(glot *moving, dirtype dir, int perform);
void undo(level *mylevel);
void redo(level *mylevel);
/* From equiv.c */
void eq_init(level *mylevel);
int eq_equiv(int *eq, int node1, int node2);
int eq_unite(int *eq, int *id, int parent, int node);
/* From parse.c */
level *loadlev(char *levname, int usepath);
/* From canvas.c */
void moveelement(glot *myglot, int xloc, int yloc);
void redrawgoal(level *mylevel);
void updatestatus(level *mylevel);
|