1 /*-
2 # X-BASED DINOSAUR CUBE
3 #
4 # DinoU.c
5 #
6 ###
7 #
8 # Copyright (c) 1995 - 99 David Albert Bagley, bagleyd@tux.org
9 #
10 # All Rights Reserved
11 #
12 # Permission to use, copy, modify, and distribute this software and
13 # its documentation for any purpose and without fee is hereby granted,
14 # provided that the above copyright notice appear in all copies and
15 # that both that copyright notice and this permission notice appear in
16 # supporting documentation, and that the name of the author not be
17 # used in advertising or publicity pertaining to distribution of the
18 # software without specific, written prior permission.
19 #
20 # This program is distributed in the hope that it will be "playable",
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 #
24 */
25
26 /* Undo algorithm */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <X11/IntrinsicP.h>
31 #include <X11/Intrinsic.h>
32 #include <X11/StringDefs.h>
33 #include <X11/CoreP.h>
34 #include "DinoP.h"
35 #include "Dino2dP.h"
36 #include "Dino3dP.h"
37
38 typedef struct _MoveRecord {
39 #if 0
40 int face, position, direction, style, control;
41 #endif
42 unsigned long int packed; /* This makes assumptions on the data. */
43 } MoveRecord;
44
45 typedef struct _MoveStack {
46 MoveRecord move;
47 struct _MoveStack *previous, *next;
48 } MoveStack;
49
50 static MoveStack *currMove, *lastMove, *firstMove;
51 static int count;
52 static DinoCornerLoc startLoc[MAXFACES][MAXORIENT];
53
54 static void InitStack(void);
55 static void PushStack(MoveRecord move);
56 static void PopStack(MoveRecord * move);
57 static int EmptyStack(void);
58 static void FlushStack(void);
59
60 static void
InitStack(void)61 InitStack(void)
62 {
63 if (!(lastMove = (MoveStack *) malloc(sizeof (MoveStack))))
64 XtError("Not enough memory, exiting.");
65 if (!(firstMove = (MoveStack *) malloc(sizeof (MoveStack))))
66 XtError("Not enough memory, exiting.");
67 firstMove->previous = lastMove->next = NULL;
68 firstMove->next = lastMove;
69 lastMove->previous = firstMove;
70 count = 0;
71 }
72
73 static void
PushStack(MoveRecord move)74 PushStack(MoveRecord move)
75 {
76 if (!(currMove = (MoveStack *) malloc(sizeof (MoveStack))))
77 XtError("Not enough memory, exiting.");
78 lastMove->previous->next = currMove;
79 currMove->previous = lastMove->previous;
80 currMove->next = lastMove;
81 lastMove->previous = currMove;
82 currMove->move = move;
83 count++;
84 }
85
86 static void
PopStack(MoveRecord * move)87 PopStack(MoveRecord * move)
88 {
89 *move = lastMove->previous->move;
90 currMove = lastMove->previous;
91 lastMove->previous->previous->next = lastMove;
92 lastMove->previous = lastMove->previous->previous;
93 (void) free((void *) currMove);
94 count--;
95 }
96
97 static int
EmptyStack(void)98 EmptyStack(void)
99 {
100 return (lastMove->previous == firstMove);
101 }
102
103 static void
FlushStack(void)104 FlushStack(void)
105 {
106 while (lastMove->previous != firstMove) {
107 currMove = lastMove->previous;
108 lastMove->previous->previous->next = lastMove;
109 lastMove->previous = lastMove->previous->previous;
110 (void) free((void *) currMove);
111 }
112 count = 0;
113 }
114
115 /**********************************/
116
117 void
InitMoves(void)118 InitMoves(void)
119 {
120 InitStack();
121 }
122
123 static void
WriteMove(MoveRecord * move,int face,int position,int direction,int style,int control)124 WriteMove(MoveRecord * move, int face, int position, int direction, int style, int control)
125 {
126 #if 0
127 move->face = face;
128 moves->position = position;
129 move->direction = direction;
130 move->style = style;
131 move->control = control;
132 #endif
133 move->packed = ((control & 0xF) << 16) + ((style & 0xF) << 12) +
134 ((direction & 0xF) << 8) + ((position & 0xF) << 4) + (face & 0xF);
135 }
136
137 static void
ReadMove(int * face,int * position,int * direction,int * style,int * control,MoveRecord move)138 ReadMove(int *face, int *position, int *direction, int *style, int *control, MoveRecord move)
139 {
140 #if 0
141 *face = move.face;
142 *position = move.position;
143 *direction = move.direction;
144 *style = move.style;
145 *control = move.control;
146 #endif
147 *face = (int) (move.packed & 0xF);
148 *position = (int) ((move.packed >> 4) & 0xF);
149 *direction = (int) ((move.packed >> 8) & 0xF);
150 *style = (int) ((move.packed >> 12) & 0xF);
151 *control = (int) ((move.packed >> 16) & 0xF);
152 }
153
154 void
PutMove(int face,int position,int direction,int style,int control)155 PutMove(int face, int position, int direction, int style, int control)
156 {
157 MoveRecord move;
158
159 WriteMove(&move, face, position, direction, style, control);
160 PushStack(move);
161 }
162
163 void
GetMove(int * face,int * position,int * direction,int * style,int * control)164 GetMove(int *face, int *position, int *direction, int *style, int *control)
165 {
166 MoveRecord move;
167
168 PopStack(&move);
169 ReadMove(face, position, direction, style, control, move);
170 }
171
172 int
MadeMoves(void)173 MadeMoves(void)
174 {
175 return !EmptyStack();
176 }
177
178 void
FlushMoves(DinoWidget w)179 FlushMoves(DinoWidget w)
180 {
181 int face, position;
182
183 FlushStack();
184 for (face = 0; face < MAXFACES; face++)
185 for (position = 0; position < MAXORIENT; position++) {
186 startLoc[face][position].face = w->dino.cubeLoc[face][position].face;
187 startLoc[face][position].rotation =
188 w->dino.cubeLoc[face][position].rotation;
189 }
190 }
191
192 int
NumMoves(void)193 NumMoves(void)
194 {
195 return count;
196 }
197
198 void
ScanMoves(FILE * fp,DinoWidget w,int moves)199 ScanMoves(FILE * fp, DinoWidget w, int moves)
200 {
201 int face, position, direction, style, control, k;
202 char c;
203
204 for (k = 0; k < moves; k++) {
205 while ((c = getc(fp)) != EOF && c != SYMBOL);
206 (void) fscanf(fp, "%d %d %d %d %d", &face, &position, &direction,
207 &style, &control);
208 MoveDino(w, face, position, direction, style, control);
209 }
210 }
211
212 void
PrintMoves(FILE * fp)213 PrintMoves(FILE * fp)
214 {
215 int face, position, direction, style, control, counter = 0;
216
217 currMove = firstMove->next;
218 (void) fprintf(fp, "moves\tface\tpos\tdir\tstyle\tcon\n");
219 while (currMove != lastMove) {
220 ReadMove(&face, &position, &direction, &style, &control, currMove->move);
221 (void) fprintf(fp, "%d%c\t%d\t%d\t%d\t%d\t%d\n",
222 ++counter, SYMBOL, face, position, direction, style, control);
223 currMove = currMove->next;
224 }
225 }
226
227 void
ScanStartPosition(FILE * fp,DinoWidget w)228 ScanStartPosition(FILE * fp, DinoWidget w)
229 {
230 int face, position, num;
231 char c;
232
233 while ((c = getc(fp)) != EOF && c != SYMBOL);
234 for (face = 0; face < MAXFACES; face++)
235 for (position = 0; position < MAXORIENT; position++) {
236 (void) fscanf(fp, "%d ", &num);
237 startLoc[face][position].face = num;
238 if (w->dino.orient) {
239 (void) fscanf(fp, "%d ", &num);
240 startLoc[face][position].rotation = num;
241 }
242 }
243 }
244
245 void
PrintStartPosition(FILE * fp,DinoWidget w)246 PrintStartPosition(FILE * fp, DinoWidget w)
247 {
248 int face, position;
249
250 (void) fprintf(fp, "\nstartingPosition%c\n", SYMBOL);
251 for (face = 0; face < MAXFACES; face++) {
252 for (position = 0; position < MAXORIENT; position++) {
253 (void) fprintf(fp, "%d ", startLoc[face][position].face);
254 if (w->dino.orient)
255 (void) fprintf(fp, "%d ", startLoc[face][position].rotation);
256 }
257 (void) fprintf(fp, "\n");
258 }
259 }
260
261 void
SetStartPosition(DinoWidget w)262 SetStartPosition(DinoWidget w)
263 {
264 int face, position;
265
266 for (face = 0; face < MAXFACES; face++)
267 for (position = 0; position < MAXORIENT; position++) {
268 w->dino.cubeLoc[face][position].face = startLoc[face][position].face;
269 if (w->dino.orient)
270 w->dino.cubeLoc[face][position].rotation =
271 startLoc[face][position].rotation;
272 }
273 DrawAllPolyhedrons(w);
274 }
275