summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/recorder/wormlet.c499
-rw-r--r--uisimulator/win32/Makefile6
-rw-r--r--uisimulator/x11/Makefile6
3 files changed, 239 insertions, 272 deletions
diff --git a/apps/recorder/wormlet.c b/apps/recorder/wormlet.c
index ab8ef0aa91..d7ac2aa6df 100644
--- a/apps/recorder/wormlet.c
+++ b/apps/recorder/wormlet.c
@@ -25,48 +25,48 @@
25#include "kernel.h" 25#include "kernel.h"
26#include "menu.h" 26#include "menu.h"
27 27
28#define MAX_WORM_LENGTH 500 // size of the ring of the worm 28#define MAX_WORM_LENGTH 500 /* size of the ring of the worm */
29#define INITIAL_WORM_LENGTH 10 // when the game starts 29#define INITIAL_WORM_LENGTH 10 /* when the game starts */
30#define WORM_PER_FOOD 7 // num of pixel the worm grows by eating a food 30#define WORM_PER_FOOD 7 /* num of pixel the worm grows per eaten food */
31 31
32// The worm is stored in a ring of xy coordinates 32/* The worm is stored in a ring of xy coordinates */
33short wormx[MAX_WORM_LENGTH]; 33static short wormx[MAX_WORM_LENGTH];
34short wormy[MAX_WORM_LENGTH]; 34static short wormy[MAX_WORM_LENGTH];
35 35
36int head; // index of the head within the buffer 36static int head; /* index of the head within the buffer */
37short headx; 37static short headx;
38short heady; 38static short heady;
39 39
40int tail; // index of the tail within the buffer 40static int tail; /* index of the tail within the buffer */
41int growing; // number of cyles the worm still keeps growing 41static int growing; /* number of cyles the worm still keeps growing */
42 42
43 43
44#define MAX_FOOD 5 // maximal number of food items 44#define MAX_FOOD 5 /* maximal number of food items */
45#define FOOD_SIZE 3 // the width and height of a food 45#define FOOD_SIZE 3 /* the width and height of a food */
46short foodx[MAX_FOOD]; 46static short foodx[MAX_FOOD];
47short foody[MAX_FOOD]; 47static short foody[MAX_FOOD];
48 48
49#define MAX_ARGH 100 // maximal number of argh items 49#define MAX_ARGH 100 /* maximal number of argh items */
50#define ARGH_SIZE 4 // the width and height of a argh 50#define ARGH_SIZE 4 /* the width and height of a argh */
51#define ARGHS_PER_FOOD 2 // number of arghs produced each time a food was eaten 51#define ARGHS_PER_FOOD 2 /* number of arghs produced per eaten food */
52short arghx[MAX_ARGH]; 52static short arghx[MAX_ARGH];
53short arghy[MAX_ARGH]; 53static short arghy[MAX_ARGH];
54int arghCount; 54static int arghCount;
55 55
56// direction vector in which the worm moves 56/* direction vector in which the worm moves */
57short dirx; // only values -1 0 1 allowed 57static short dirx; /* only values -1 0 1 allowed */
58short diry; // only values -1 0 1 allowed 58static short diry; /* only values -1 0 1 allowed */
59 59
60int speed = 10; 60static int speed = 10;
61 61
62// return values of checkCollision 62/* return values of checkCollision */
63#define COLLISION_NONE 0 63#define COLLISION_NONE 0
64#define COLLISION_WORM 1 64#define COLLISION_WORM 1
65#define COLLISION_FOOD 2 65#define COLLISION_FOOD 2
66#define COLLISION_ARGH 3 66#define COLLISION_ARGH 3
67#define COLLISION_FIELD 4 67#define COLLISION_FIELD 4
68 68
69// size of the field the worm lives in 69/* size of the field the worm lives in */
70#define FIELD_RECT_X 1 70#define FIELD_RECT_X 1
71#define FIELD_RECT_Y 1 71#define FIELD_RECT_Y 1
72#define FIELD_RECT_WIDTH LCD_HEIGHT - 2 72#define FIELD_RECT_WIDTH LCD_HEIGHT - 2
@@ -76,12 +76,11 @@ int speed = 10;
76 * Returns the current length of the worm. 76 * Returns the current length of the worm.
77 * @return int a positive value 77 * @return int a positive value
78 */ 78 */
79int getWormLength(void) { 79static int getWormLength(void) {
80 // initial simple calculation will be overwritten 80 /* initial simple calculation will be overwritten if wrong. */
81 // if wrong.
82 int retVal = head - tail; 81 int retVal = head - tail;
83 82
84 // if the worm 'crosses' the boundaries of the ringbuffer 83 /* if the worm 'crosses' the boundaries of the ringbuffer */
85 if (retVal < 0) { 84 if (retVal < 0) {
86 retVal = head + MAX_WORM_LENGTH - tail; 85 retVal = head + MAX_WORM_LENGTH - tail;
87 } 86 }
@@ -98,7 +97,7 @@ int getWormLength(void) {
98 * @return Returns true if the coordinate hits the food specified by 97 * @return Returns true if the coordinate hits the food specified by
99 * foodIndex. 98 * foodIndex.
100 */ 99 */
101bool specificFoodCollision(int foodIndex, int x, int y) { 100static bool specificFoodCollision(int foodIndex, int x, int y) {
102 bool retVal = false; 101 bool retVal = false;
103 if (x >= foodx[foodIndex] && 102 if (x >= foodx[foodIndex] &&
104 x < foodx[foodIndex] + FOOD_SIZE && 103 x < foodx[foodIndex] + FOOD_SIZE &&
@@ -116,15 +115,13 @@ bool specificFoodCollision(int foodIndex, int x, int y) {
116 * -1 is returned. 115 * -1 is returned.
117 * @return int -1 <= value < MAX_FOOD 116 * @return int -1 <= value < MAX_FOOD
118 */ 117 */
119int foodCollision(int x, int y) { 118static int foodCollision(int x, int y) {
120 int i = 0; 119 int i = 0;
121 int retVal = -1; 120 int retVal = -1;
122 bool collisionDetected = false; 121 for (i = 0; i < MAX_FOOD; i++) {
123 for (i = 0; i < MAX_FOOD && !collisionDetected; i++) {
124 if (specificFoodCollision(i, x, y)) { 122 if (specificFoodCollision(i, x, y)) {
125
126 collisionDetected = true;
127 retVal = i; 123 retVal = i;
124 break;
128 } 125 }
129 } 126 }
130 return retVal; 127 return retVal;
@@ -139,16 +136,17 @@ int foodCollision(int x, int y) {
139 * @return Returns true if the coordinate hits the argh specified by 136 * @return Returns true if the coordinate hits the argh specified by
140 * arghIndex. 137 * arghIndex.
141 */ 138 */
142bool specificArghCollision(int arghIndex, int x, int y) { 139static bool specificArghCollision(int arghIndex, int x, int y) {
143 bool retVal = false;
144 if (x >= arghx[arghIndex] &&
145 x < arghx[arghIndex] + ARGH_SIZE &&
146 y >= arghy[arghIndex] &&
147 y < arghy[arghIndex] + ARGH_SIZE) {
148 140
149 retVal = true; 141 if ( x >= arghx[arghIndex] &&
142 y >= arghy[arghIndex] &&
143 x < arghx[arghIndex] + ARGH_SIZE &&
144 y < arghy[arghIndex] + ARGH_SIZE )
145 {
146 return true;
150 } 147 }
151 return retVal; 148
149 return false;
152} 150}
153 151
154/** 152/**
@@ -159,17 +157,15 @@ bool specificArghCollision(int arghIndex, int x, int y) {
159 * @param int y The y coordinate. 157 * @param int y The y coordinate.
160 * @return int -1 <= value < arghCount <= MAX_ARGH 158 * @return int -1 <= value < arghCount <= MAX_ARGH
161 */ 159 */
162int arghCollision(int x, int y) { 160static int arghCollision(int x, int y) {
163 int i = 0; 161 int i = 0;
164 int retVal = -1; 162 int retVal = -1;
165 bool collisionDetected = false;
166 163
167 // search for the argh that has the specified coords 164 /* search for the argh that has the specified coords */
168 for (i = 0; i < arghCount && !collisionDetected; i++) { 165 for (i = 0; i < arghCount; i++) {
169 if (specificArghCollision(i, x, y)) { 166 if (specificArghCollision(i, x, y)) {
170
171 collisionDetected = true;
172 retVal = i; 167 retVal = i;
168 break;
173 } 169 }
174 } 170 }
175 return retVal; 171 return retVal;
@@ -181,23 +177,25 @@ int arghCollision(int x, int y) {
181 * 0 <= foodIndex <= MAX_FOOD 177 * 0 <= foodIndex <= MAX_FOOD
182 * @return Returns true if the worm collides with the specified food. 178 * @return Returns true if the worm collides with the specified food.
183 */ 179 */
184bool wormFoodCollision(int foodIndex) { 180static bool wormFoodCollision(int foodIndex)
181{
185 bool retVal = false; 182 bool retVal = false;
186 183
187 // buffer wormLength because getWormLength is expensive 184 /* buffer wormLength because getWormLength is expensive */
188 int wormLength = getWormLength(); 185 int wormLength = getWormLength();
189 int i; 186 int i;
190 187
191 // although all the worm gets iterated i is NOT the index 188 /* although all the worm gets iterated i is NOT
192 // of the worm arrays 189 the index of the worm arrays */
193 for (i = 0; i < wormLength && !retVal; i++) { 190 for (i = 0; i < wormLength; i++) {
194 191
195 // convert i to the true worm indices 192 /* convert i to the true worm indices */
196 int wormIndex = (tail + i) % MAX_WORM_LENGTH; 193 int wormIndex = (tail + i) % MAX_WORM_LENGTH;
197 194 if (specificFoodCollision(foodIndex,
198 // The check 195 wormx[wormIndex],
199 if (specificFoodCollision(foodIndex, wormx[wormIndex], wormy[wormIndex])) { 196 wormy[wormIndex])) {
200 retVal = true; 197 retVal = true;
198 break;
201 } 199 }
202 } 200 }
203 201
@@ -206,27 +204,29 @@ bool wormFoodCollision(int foodIndex) {
206 204
207/** 205/**
208 * Checks wether the worm collides with the argh at the specfied argh-arrays. 206 * Checks wether the worm collides with the argh at the specfied argh-arrays.
209 * @param int arghIndex The index of the argh in the arrays. Ensure the value is 207 * @param int arghIndex The index of the argh in the arrays.
210 * 0 <= arghIndex < arghCount <= MAX_ARGH 208 * Ensure the value is 0 <= arghIndex < arghCount <= MAX_ARGH
211 * @return Returns true if the worm collides with the specified argh. 209 * @return Returns true if the worm collides with the specified argh.
212 */ 210 */
213bool wormArghCollision(int arghIndex) { 211static bool wormArghCollision(int arghIndex)
212{
214 bool retVal = false; 213 bool retVal = false;
215 214
216 // buffer wormLength because getWormLength is expensive 215 /* buffer wormLength because getWormLength is expensive */
217 int wormLength = getWormLength(); 216 int wormLength = getWormLength();
218 int i; 217 int i;
219 218
220 // although all the worm gets iterated i is NOT the index 219 /* although all the worm gets iterated i is NOT
221 // of the worm arrays 220 the index of the worm arrays */
222 for (i = 0; i < wormLength && !retVal; i++) { 221 for (i = 0; i < wormLength; i++) {
223 222
224 // convert i to the true worm indices 223 /* convert i to the true worm indices */
225 int wormIndex = (tail + i) % MAX_WORM_LENGTH; 224 int wormIndex = (tail + i) % MAX_WORM_LENGTH;
226 225 if (specificArghCollision(arghIndex,
227 // The check 226 wormx[wormIndex],
228 if (specificArghCollision(arghIndex, wormx[wormIndex], wormy[wormIndex])) { 227 wormy[wormIndex])) {
229 retVal = true; 228 retVal = true;
229 break;
230 } 230 }
231 } 231 }
232 232
@@ -239,37 +239,38 @@ bool wormArghCollision(int arghIndex) {
239 * @param int index 239 * @param int index
240 * Ensure that 0 <= index < MAX_FOOD. 240 * Ensure that 0 <= index < MAX_FOOD.
241 */ 241 */
242void makeFood(int index) { 242static void makeFood(int index) {
243 243
244 int x = 0; 244 int x = 0;
245 int y = 0; 245 int y = 0;
246 bool collisionDetected = false; 246 bool collisionDetected = false;
247 247
248 do { 248 do {
249 // make coordinates for a new food so that 249 /* make coordinates for a new food so that
250 // the entire food lies within the FIELD 250 the entire food lies within the FIELD */
251 x = rand() % (FIELD_RECT_WIDTH - FOOD_SIZE); 251 x = rand() % (FIELD_RECT_WIDTH - FOOD_SIZE);
252 y = rand() % (FIELD_RECT_HEIGHT - FOOD_SIZE); 252 y = rand() % (FIELD_RECT_HEIGHT - FOOD_SIZE);
253 253
254 // Ensure that the new food doesn't collide with any 254 /* Ensure that the new food doesn't collide with any
255 // existing foods or arghs. 255 existing foods or arghs.
256 // If one or more corners of the new food hit any existing 256 If one or more corners of the new food hit any existing
257 // argh or food a collision is detected. 257 argh or food a collision is detected.
258 */
258 collisionDetected = 259 collisionDetected =
259 foodCollision(x , y ) >= 0 || 260 foodCollision(x, y ) >= 0 ||
260 foodCollision(x + FOOD_SIZE - 1, y ) >= 0 || 261 foodCollision(x, y + FOOD_SIZE - 1) >= 0 ||
261 foodCollision(x , y + FOOD_SIZE - 1) >= 0 || 262 foodCollision(x + FOOD_SIZE - 1, y ) >= 0 ||
262 foodCollision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0 || 263 foodCollision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0 ||
263 arghCollision(x , y ) >= 0 || 264 arghCollision(x, y ) >= 0 ||
264 arghCollision(x + FOOD_SIZE - 1, y ) >= 0 || 265 arghCollision(x, y + FOOD_SIZE - 1) >= 0 ||
265 arghCollision(x , y + FOOD_SIZE - 1) >= 0 || 266 arghCollision(x + FOOD_SIZE - 1, y ) >= 0 ||
266 arghCollision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0; 267 arghCollision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0;
267 268
268 // use coordinates for further testing 269 /* use coordinates for further testing */
269 foodx[index] = x; 270 foodx[index] = x;
270 foody[index] = y; 271 foody[index] = y;
271 272
272 // now test wether we accidently hit the worm with food ;) 273 /* now test wether we accidently hit the worm with food ;) */
273 collisionDetected |= wormFoodCollision(index); 274 collisionDetected |= wormFoodCollision(index);
274 } 275 }
275 while (collisionDetected); 276 while (collisionDetected);
@@ -281,11 +282,12 @@ void makeFood(int index) {
281 * the coordinates of the desired food can be found. Ensure 282 * the coordinates of the desired food can be found. Ensure
282 * that the value is 0 <= index <= MAX_FOOD. 283 * that the value is 0 <= index <= MAX_FOOD.
283 */ 284 */
284void clearFood(int index) { 285static void clearFood(int index)
285 // remove the old food from the screen 286{
286 lcd_clearrect (foodx[index] + FIELD_RECT_X, 287 /* remove the old food from the screen */
287 foody[index] + FIELD_RECT_Y, 288 lcd_clearrect(foodx[index] + FIELD_RECT_X,
288 FOOD_SIZE, FOOD_SIZE); 289 foody[index] + FIELD_RECT_Y,
290 FOOD_SIZE, FOOD_SIZE);
289} 291}
290 292
291/** 293/**
@@ -294,14 +296,15 @@ void clearFood(int index) {
294 * the coordinates of the desired food can be found. Ensure 296 * the coordinates of the desired food can be found. Ensure
295 * that the value is 0 <= index <= MAX_FOOD. 297 * that the value is 0 <= index <= MAX_FOOD.
296 */ 298 */
297void drawFood(int index) { 299static void drawFood(int index)
298 // draw the food object 300{
299 lcd_fillrect (foodx[index] + FIELD_RECT_X, 301 /* draw the food object */
300 foody[index] + FIELD_RECT_Y, 302 lcd_fillrect(foodx[index] + FIELD_RECT_X,
301 FOOD_SIZE, FOOD_SIZE); 303 foody[index] + FIELD_RECT_Y,
304 FOOD_SIZE, FOOD_SIZE);
302 lcd_clearrect(foodx[index] + FIELD_RECT_X + 1, 305 lcd_clearrect(foodx[index] + FIELD_RECT_X + 1,
303 foody[index] + FIELD_RECT_Y + 1, 306 foody[index] + FIELD_RECT_Y + 1,
304 FOOD_SIZE - 2, FOOD_SIZE - 2); 307 FOOD_SIZE - 2, FOOD_SIZE - 2);
305} 308}
306 309
307/** 310/**
@@ -310,35 +313,37 @@ void drawFood(int index) {
310 * @param int index 313 * @param int index
311 * Ensure that 0 <= index < arghCount < MAX_ARGH. 314 * Ensure that 0 <= index < arghCount < MAX_ARGH.
312 */ 315 */
313void makeArgh(int index) { 316static void makeArgh(int index)
317{
314 int x; 318 int x;
315 int y; 319 int y;
316 bool collisionDetected = false; 320 bool collisionDetected = false;
317 321
318 do { 322 do {
319 // make coordinates for a new argh so that 323 /* make coordinates for a new argh so that
320 // the entire food lies within the FIELD 324 the entire food lies within the FIELD */
321 x = rand() % (FIELD_RECT_WIDTH - ARGH_SIZE); 325 x = rand() % (FIELD_RECT_WIDTH - ARGH_SIZE);
322 y = rand() % (FIELD_RECT_HEIGHT - ARGH_SIZE); 326 y = rand() % (FIELD_RECT_HEIGHT - ARGH_SIZE);
323 // Ensure that the new argh doesn't intersect with any 327 /* Ensure that the new argh doesn't intersect with any
324 // existing foods or arghs. 328 existing foods or arghs.
325 // If one or more corners of the new argh hit any existing 329 If one or more corners of the new argh hit any existing
326 // argh or food an intersection is detected. 330 argh or food an intersection is detected.
331 */
327 collisionDetected = 332 collisionDetected =
328 foodCollision(x , y ) >= 0 || 333 foodCollision(x, y ) >= 0 ||
329 foodCollision(x + ARGH_SIZE - 1, y ) >= 0 || 334 foodCollision(x, y + ARGH_SIZE - 1) >= 0 ||
330 foodCollision(x , y + ARGH_SIZE - 1) >= 0 || 335 foodCollision(x + ARGH_SIZE - 1, y ) >= 0 ||
331 foodCollision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0 || 336 foodCollision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0 ||
332 arghCollision(x , y ) >= 0 || 337 arghCollision(x, y ) >= 0 ||
333 arghCollision(x + ARGH_SIZE - 1, y ) >= 0 || 338 arghCollision(x, y + ARGH_SIZE - 1) >= 0 ||
334 arghCollision(x , y + ARGH_SIZE - 1) >= 0 || 339 arghCollision(x + ARGH_SIZE - 1, y ) >= 0 ||
335 arghCollision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0; 340 arghCollision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0;
336 341
337 // use the candidate coordinates to make a real argh 342 /* use the candidate coordinates to make a real argh */
338 arghx[index] = x; 343 arghx[index] = x;
339 arghy[index] = y; 344 arghy[index] = y;
340 345
341 // now test wether we accidently hit the worm with argh ;) 346 /* now test wether we accidently hit the worm with argh ;) */
342 collisionDetected |= wormArghCollision(index); 347 collisionDetected |= wormArghCollision(index);
343 } 348 }
344 while (collisionDetected); 349 while (collisionDetected);
@@ -350,42 +355,42 @@ void makeArgh(int index) {
350 * the coordinates of the desired argh can be found. Ensure 355 * the coordinates of the desired argh can be found. Ensure
351 * that the value is 0 <= index < arghCount <= MAX_ARGH. 356 * that the value is 0 <= index < arghCount <= MAX_ARGH.
352 */ 357 */
353void drawArgh(int index) { 358static void drawArgh(int index)
354 // draw the new argh 359{
355 lcd_fillrect (arghx[index] + FIELD_RECT_X, 360 /* draw the new argh */
356 arghy[index] + FIELD_RECT_Y, 361 lcd_fillrect(arghx[index] + FIELD_RECT_X,
357 ARGH_SIZE, ARGH_SIZE); 362 arghy[index] + FIELD_RECT_Y,
363 ARGH_SIZE, ARGH_SIZE);
358} 364}
359 365
360/** 366/**
361 * Initializes the worm-, food- and argh-arrays, draws a frame, 367 * Initializes the worm-, food- and argh-arrays, draws a frame,
362 * makes some food and argh and display all that stuff. 368 * makes some food and argh and display all that stuff.
363 */ 369 */
364void initWormlet(void) { 370static void initWormlet(void)
371{
372 int i;
365 373
366 // Needed when the game is restarted using BUTTON_ON 374 /* Initialize all the worm coordinates to 0,0. */
367 lcd_clear_display(); 375 memset(wormx,0,sizeof wormx);
376 memset(wormy,0,sizeof wormy);
368 377
369 // Initialize all the worm coordinates to 0,0. 378 /* Needed when the game is restarted using BUTTON_ON */
370 int i; 379 lcd_clear_display();
371 for (i = 0; i < MAX_WORM_LENGTH; i++){
372 wormx[i] = 0;
373 wormy[i] = 0;
374 }
375 380
376 // initialize the worm size 381 /* initialize the worm size */
377 head = INITIAL_WORM_LENGTH; 382 head = INITIAL_WORM_LENGTH;
378 tail = 0; 383 tail = 0;
379 384
380 // initialize the worm start point 385 /* initialize the worm start point */
381 headx = 0; 386 headx = 0;
382 heady = 0; 387 heady = 0;
383 388
384 // set the initial direction the worm creeps to 389 /* set the initial direction the worm creeps to */
385 dirx = 1; 390 dirx = 1;
386 diry = 0; 391 diry = 0;
387 392
388 // make and display some food and argh 393 /* make and display some food and argh */
389 arghCount = MAX_FOOD; 394 arghCount = MAX_FOOD;
390 for (i = 0; i < MAX_FOOD; i++) { 395 for (i = 0; i < MAX_FOOD; i++) {
391 makeFood(i); 396 makeFood(i);
@@ -394,63 +399,56 @@ void initWormlet(void) {
394 drawArgh(i); 399 drawArgh(i);
395 } 400 }
396 401
397 // draw the game field 402 /* draw the game field */
398 lcd_invertrect (0 , 0 , FIELD_RECT_WIDTH + 2, FIELD_RECT_HEIGHT + 2); 403 lcd_invertrect(0, 0, FIELD_RECT_WIDTH + 2, FIELD_RECT_HEIGHT + 2);
399 lcd_invertrect(0 + 1, 0 + 1, FIELD_RECT_WIDTH , FIELD_RECT_HEIGHT); 404 lcd_invertrect(1, 1, FIELD_RECT_WIDTH, FIELD_RECT_HEIGHT);
400 405
401 // make everything visible 406 /* make everything visible */
402 lcd_update(); 407 lcd_update();
403} 408}
404 409
405/** 410/**
406 * Move the worm one step further. 411 * Move the worm one step further.
407 * The direction in which the worm moves is taken 412 * The direction in which the worm moves is taken from dirx and diry. If the
408 * from dirx and diry. If the 413 * worm crosses the boundaries of the field the worm is wrapped (it enters
409 * worm crosses the boundaries of the field the 414 * the field from the opposite side). moveWorm decreases growing if > 0.
410 * worm is wrapped (it enters the field from the
411 * opposite side). moveWorm decreases growing if > 0.
412 */ 415 */
413void moveWorm(void) { 416static void moveWorm(void)
414 // find the next array index for the head 417{
418 /* find the next array index for the head */
415 head++; 419 head++;
416 if (head >= MAX_WORM_LENGTH){ 420 if (head >= MAX_WORM_LENGTH)
417 head = 0; 421 head = 0;
418 }
419 422
420 // find the next array index for the tail 423 /* find the next array index for the tail */
421 tail++; 424 tail++;
422 if (tail >= MAX_WORM_LENGTH){ 425 if (tail >= MAX_WORM_LENGTH)
423 tail = 0; 426 tail = 0;
424 }
425 427
426 // determine the new head position 428 /* determine the new head position */
427 headx += dirx; 429 headx += dirx;
428 heady += diry; 430 heady += diry;
429 431
430 // Wrap the new head position if necessary 432 /* Wrap the new head position if necessary */
431 if (headx >= FIELD_RECT_WIDTH) { 433 if (headx >= FIELD_RECT_WIDTH)
432 headx = 0; 434 headx = 0;
433 } 435 else
434 436 if (headx < 0)
435 if (headx < 0){ 437 headx = FIELD_RECT_WIDTH - 1;
436 headx = FIELD_RECT_WIDTH - 1;
437 }
438 438
439 if (heady >= FIELD_RECT_HEIGHT) { 439 if (heady >= FIELD_RECT_HEIGHT)
440 heady = 0; 440 heady = 0;
441 } 441 else
442 442 if (heady < 0)
443 if (heady < 0) { 443 heady = FIELD_RECT_HEIGHT - 1;
444 heady = FIELD_RECT_HEIGHT - 1;
445 }
446 444
447 // store the new head position in the 445 /* store the new head position in the worm arrays */
448 // worm arrays
449 wormx[head] = headx; 446 wormx[head] = headx;
450 wormy[head] = heady; 447 wormy[head] = heady;
451 448
452 // update the worms grow state 449 /* update the worms grow state */
453 if (growing > 0) growing --; 450 if (growing > 0)
451 growing--;
454} 452}
455 453
456/** 454/**
@@ -458,11 +456,12 @@ void moveWorm(void) {
458 * the display buffer. lcd_update() is NOT called thus 456 * the display buffer. lcd_update() is NOT called thus
459 * the caller has to take care that the buffer is displayed. 457 * the caller has to take care that the buffer is displayed.
460 */ 458 */
461void drawWorm(void) { 459static void drawWorm(void)
462 // draw the new head 460{
461 /* draw the new head */
463 lcd_drawpixel( wormx[head] + FIELD_RECT_X, wormy[head] + FIELD_RECT_Y); 462 lcd_drawpixel( wormx[head] + FIELD_RECT_X, wormy[head] + FIELD_RECT_Y);
464 463
465 // clear the space behind the worm 464 /* clear the space behind the worm */
466 lcd_clearpixel(wormx[tail] + FIELD_RECT_X, wormy[tail] + FIELD_RECT_Y); 465 lcd_clearpixel(wormx[tail] + FIELD_RECT_X, wormy[tail] + FIELD_RECT_Y);
467} 466}
468 467
@@ -473,25 +472,22 @@ void drawWorm(void) {
473 * @return int The index of the worm arrays that contain x, y. 472 * @return int The index of the worm arrays that contain x, y.
474 * Returns -1 if the coordinates are not part of the worm. 473 * Returns -1 if the coordinates are not part of the worm.
475 */ 474 */
476int wormCollision(int x, int y) { 475static int wormCollision(int x, int y)
476{
477 int retVal = -1; 477 int retVal = -1;
478 478
479 // getWormLength is expensive -> buffer the value 479 /* getWormLength is expensive -> buffer the value */
480 int wormLength = getWormLength(); 480 int wormLength = getWormLength();
481 int i; 481 int i;
482 482
483 // test each entry that is part of the worm 483 /* test each entry that is part of the worm */
484 for (i = 0; i < wormLength && retVal == -1; i++) { 484 for (i = 0; i < wormLength && retVal == -1; i++) {
485 485
486 // The iteration iterates the length of the worm. 486 /* The iteration iterates the length of the worm.
487 // Here's the conversion to the true indices within 487 Here's the conversion to the true indices within the worm arrays. */
488 // the worm arrays.
489 int trueIndex = (tail + i) % MAX_WORM_LENGTH; 488 int trueIndex = (tail + i) % MAX_WORM_LENGTH;
490 489 if (wormx[trueIndex] == x && wormy[trueIndex] == y)
491 // The check
492 if (wormx[trueIndex] == x && wormy[trueIndex] == y) {
493 retVal = trueIndex; 490 retVal = trueIndex;
494 }
495 } 491 }
496 return retVal; 492 return retVal;
497} 493}
@@ -501,13 +497,14 @@ int wormCollision(int x, int y) {
501 * crossed the field boundaries. 497 * crossed the field boundaries.
502 * @return bool true if the worm just has wrapped. 498 * @return bool true if the worm just has wrapped.
503 */ 499 */
504bool fieldCollision(void) { 500static bool fieldCollision(void)
501{
505 bool retVal = false; 502 bool retVal = false;
506 if ((headx == FIELD_RECT_WIDTH - 1 && dirx == -1) || 503 if ((headx == FIELD_RECT_WIDTH - 1 && dirx == -1) ||
507 (headx == 0 && dirx == 1) ||
508 (heady == FIELD_RECT_HEIGHT - 1 && diry == -1) || 504 (heady == FIELD_RECT_HEIGHT - 1 && diry == -1) ||
509 (heady == 0 && diry == 1)) { 505 (headx == 0 && dirx == 1) ||
510 506 (heady == 0 && diry == 1))
507 {
511 retVal = true; 508 retVal = true;
512 } 509 }
513 return retVal; 510 return retVal;
@@ -516,78 +513,46 @@ bool fieldCollision(void) {
516/** 513/**
517 * Checks and returns wether the head of the worm 514 * Checks and returns wether the head of the worm
518 * is colliding with something currently. 515 * is colliding with something currently.
519 * @return int One of the values 516 * @return int One of the values:
520 * <ul> 517 * COLLISION_NONE
521 * <li>COLLISION_NONE 518 * COLLISION_WORM
522 * <li>COLLISION_WORM 519 * COLLISION_FOOD
523 * <li>COLLISION_FOOD 520 * COLLISION_ARGH
524 * <li>COLLISION_ARGH 521 * COLLISION_FIELD
525 * <li>COLLISION_FIELD
526 * </ul>
527 */ 522 */
528int checkCollision(void) { 523static int checkCollision(void)
524{
529 int retVal = COLLISION_NONE; 525 int retVal = COLLISION_NONE;
530 526
531 if (wormCollision(headx, heady) >= 0) { 527 if (wormCollision(headx, heady) >= 0)
532 retVal = COLLISION_WORM; 528 retVal = COLLISION_WORM;
533 }
534 529
535 if (foodCollision(headx, heady) >= 0) { 530 if (foodCollision(headx, heady) >= 0)
536 retVal = COLLISION_FOOD; 531 retVal = COLLISION_FOOD;
537 }
538 532
539 if (arghCollision(headx, heady) >= 0) { 533 if (arghCollision(headx, heady))
540 retVal = COLLISION_ARGH; 534 retVal = COLLISION_ARGH;
541 }
542 535
543 if (fieldCollision()) { 536 if (fieldCollision())
544 retVal = COLLISION_FIELD; 537 retVal = COLLISION_FIELD;
545 }
546 538
547 return retVal; 539 return retVal;
548} 540}
549 541
550/*
551void debugOutput(void) {
552 char buf[40];
553
554 // head
555 snprintf(buf, sizeof(buf), "h:%d(%d;%d) ", head, wormx[head], wormy[head]);
556 lcd_putsxy(FIELD_RECT_WIDTH + 3, 0, buf, 0);
557
558 // tail
559 snprintf(buf, sizeof(buf), "t:%d(%d;%d) ", tail, wormx[tail], wormy[tail]);
560 lcd_putsxy(FIELD_RECT_WIDTH + 3, 8, buf, 0);
561
562 // speed
563 snprintf(buf, sizeof(buf), "div:%d ", speed);
564 lcd_putsxy(FIELD_RECT_WIDTH + 3, 16, buf, 0);
565
566 // collision
567 switch (checkCollision()) {
568 case COLLISION_NONE: snprintf(buf, sizeof(buf), "free "); break;
569 case COLLISION_WORM: snprintf(buf, sizeof(buf), "worm "); break;
570 case COLLISION_FOOD: snprintf(buf, sizeof(buf), "food "); break;
571 case COLLISION_ARGH: snprintf(buf, sizeof(buf), "argh "); break;
572 case COLLISION_FIELD: snprintf(buf, sizeof(buf), "field "); break;
573 }
574 lcd_putsxy(FIELD_RECT_WIDTH + 3, 24, buf, 0);
575}
576*/
577
578/** 542/**
579 * Prints out the score board with all the status information 543 * Prints out the score board with all the status information
580 * about the game. 544 * about the game.
581 */ 545 */
582void scoreBoard(void) { 546static void scoreBoard(void)
547{
583 char buf[15]; 548 char buf[15];
584 char buf2[15]; 549 char buf2[15];
585 550
586 // Title 551 /* Title */
587 snprintf(buf, sizeof (buf), "Wormlet"); 552 snprintf(buf, sizeof (buf), "Wormlet");
588 lcd_putsxy(FIELD_RECT_WIDTH + 3, 0, buf, 0); 553 lcd_putsxy(FIELD_RECT_WIDTH + 3, 0, buf, 0);
589 554
590 // length 555 /* length */
591 snprintf(buf, sizeof (buf), "length:"); 556 snprintf(buf, sizeof (buf), "length:");
592 lcd_putsxy(FIELD_RECT_WIDTH + 3, 12, buf, 0); 557 lcd_putsxy(FIELD_RECT_WIDTH + 3, 12, buf, 0);
593 snprintf(buf, sizeof (buf), "%d ", getWormLength() - growing); 558 snprintf(buf, sizeof (buf), "%d ", getWormLength() - growing);
@@ -596,12 +561,10 @@ void scoreBoard(void) {
596 switch (checkCollision()) { 561 switch (checkCollision()) {
597 case COLLISION_NONE: 562 case COLLISION_NONE:
598 snprintf(buf, sizeof(buf), "I'm hungry! "); 563 snprintf(buf, sizeof(buf), "I'm hungry! ");
599 if (growing > 0) { 564 if (growing > 0)
600 snprintf(buf2, sizeof(buf2), "growing"); 565 snprintf(buf2, sizeof(buf2), "growing");
601 } 566 else
602 else {
603 snprintf(buf2, sizeof(buf2), " "); 567 snprintf(buf2, sizeof(buf2), " ");
604 }
605 break; 568 break;
606 569
607 case COLLISION_WORM: 570 case COLLISION_WORM:
@@ -634,7 +597,8 @@ void scoreBoard(void) {
634 * @return bool Returns true if the worm is dead. Returns 597 * @return bool Returns true if the worm is dead. Returns
635 * false if the worm is healthy, up and creeping. 598 * false if the worm is healthy, up and creeping.
636 */ 599 */
637bool processCollisions(void) { 600static bool processCollisions(void)
601{
638 bool wormDead = false; 602 bool wormDead = false;
639 int index = -1; 603 int index = -1;
640 604
@@ -642,44 +606,39 @@ bool processCollisions(void) {
642 606
643 if (!wormDead) { 607 if (!wormDead) {
644 608
645 // check if food was eaten 609 /* check if food was eaten */
646 index = foodCollision(headx, heady); 610 index = foodCollision(headx, heady);
647 if (index != -1){ 611 if (index != -1){
612 int i;
613
648 clearFood(index); 614 clearFood(index);
649 makeFood(index); 615 makeFood(index);
650 drawFood(index); 616 drawFood(index);
651 617
652 int i = 0;
653
654 for (i = 0; i < ARGHS_PER_FOOD; i++) { 618 for (i = 0; i < ARGHS_PER_FOOD; i++) {
655 arghCount++; 619 arghCount++;
656 if (arghCount > MAX_ARGH) { 620 if (arghCount > MAX_ARGH)
657 arghCount = MAX_ARGH; 621 arghCount = MAX_ARGH;
658 }
659 makeArgh(arghCount - 1); 622 makeArgh(arghCount - 1);
660 drawArgh(arghCount - 1); 623 drawArgh(arghCount - 1);
661 } 624 }
662 625
663 tail -= WORM_PER_FOOD; 626 tail -= WORM_PER_FOOD;
664 growing += WORM_PER_FOOD; 627 growing += WORM_PER_FOOD;
665 if (tail < 0) { 628 if (tail < 0)
666 tail += MAX_WORM_LENGTH; 629 tail += MAX_WORM_LENGTH;
667 }
668 630
669 drawWorm(); 631 drawWorm();
670 } 632 }
671 633
672 // check if argh was eaten 634 /* check if argh was eaten */
673 else { 635 else {
674 index = arghCollision(headx, heady); 636 index = arghCollision(headx, heady);
675 if (index != -1) { 637 if (index != -1)
676 wormDead = true; 638 wormDead = true;
677 } 639 else
678 else { 640 if (wormCollision(headx, heady) != -1)
679 if (wormCollision(headx, heady) != -1) {
680 wormDead = true; 641 wormDead = true;
681 }
682 }
683 } 642 }
684 } 643 }
685 return wormDead; 644 return wormDead;
@@ -691,14 +650,15 @@ bool processCollisions(void) {
691 * with a dead worm. Returns false if the user 650 * with a dead worm. Returns false if the user
692 * aborted the game manually. 651 * aborted the game manually.
693 */ 652 */
694bool run(void) { 653static bool run(void)
654{
695 int button = 0; 655 int button = 0;
696 int wormDead = false; 656 int wormDead = false;
697 657
698 // initialize the board and so on 658 /* initialize the board and so on */
699 initWormlet(); 659 initWormlet();
700 660
701 // change the direction of the worm 661 /* change the direction of the worm */
702 while (button != BUTTON_OFF && ! wormDead) 662 while (button != BUTTON_OFF && ! wormDead)
703 { 663 {
704 switch (button) { 664 switch (button) {
@@ -732,7 +692,6 @@ bool run(void) {
732 } 692 }
733 693
734 moveWorm(); 694 moveWorm();
735// debugOutput();
736 wormDead = processCollisions(); 695 wormDead = processCollisions();
737 drawWorm(); 696 drawWorm();
738 scoreBoard(); 697 scoreBoard();
@@ -751,25 +710,25 @@ Menu wormlet(void)
751 int button; 710 int button;
752 do { 711 do {
753 712
754 // button state will be overridden if 713 /* button state will be overridden if
755 // the game quits with the death of the worm. 714 the game quits with the death of the worm.
756 // Initializing button to BUTTON_OFF ensures 715 Initializing button to BUTTON_OFF ensures
757 // that the user can hit BUTTON_OFF during the 716 that the user can hit BUTTON_OFF during the
758 // game to return to the menu. 717 game to return to the menu.
718 */
759 button = BUTTON_OFF; 719 button = BUTTON_OFF;
760 720
761 // start the game 721 /* start the game */
762 wormDead = run(); 722 wormDead = run();
763 723
764 // if worm isn't dead the game was quit 724 /* if worm isn't dead the game was quit
765 // via BUTTON_OFF -> no need to wait for 725 via BUTTON_OFF -> no need to wait for buttons. */
766 // buttons.
767 if (wormDead) { 726 if (wormDead) {
768 do { 727 do {
769 button = button_get(true); 728 button = button_get(true);
770 } 729 }
771 // BUTTON_ON -> start new game 730 /* BUTTON_ON -> start new game */
772 // BUTTON_OFF -> back to game menu 731 /* BUTTON_OFF -> back to game menu */
773 while (button != BUTTON_OFF && button != BUTTON_ON); 732 while (button != BUTTON_OFF && button != BUTTON_ON);
774 } 733 }
775 } 734 }
diff --git a/uisimulator/win32/Makefile b/uisimulator/win32/Makefile
index 21bd09ea90..7282afdc24 100644
--- a/uisimulator/win32/Makefile
+++ b/uisimulator/win32/Makefile
@@ -68,7 +68,8 @@ APPS = main.c tree.c menu.c credits.c main_menu.c\
68MENUS = games_menu.c screensavers_menu.c settings_menu.c sound_menu.c 68MENUS = games_menu.c screensavers_menu.c settings_menu.c sound_menu.c
69 69
70ifeq ($(DISPLAY),-DHAVE_LCD_BITMAP) 70ifeq ($(DISPLAY),-DHAVE_LCD_BITMAP)
71 APPS += tetris.c sokoban.c blank.c bounce.c boxes.c icons.c bmp.c widgets.c 71 APPS += tetris.c sokoban.c blank.c bounce.c boxes.c icons.c bmp.c \
72 widgets.c wormlet.c
72endif 73endif
73 74
74SRCS = button.c dir-win32.c lcd-win32.c panic-win32.c thread-win32.c \ 75SRCS = button.c dir-win32.c lcd-win32.c panic-win32.c thread-win32.c \
@@ -122,6 +123,9 @@ $(OBJDIR)/widgets.o: $(RECDIR)/widgets.c
122$(OBJDIR)/tetris.o: $(RECDIR)/tetris.c 123$(OBJDIR)/tetris.o: $(RECDIR)/tetris.c
123 $(CC) $(APPCFLAGS) -c $< -o $@ 124 $(CC) $(APPCFLAGS) -c $< -o $@
124 125
126$(OBJDIR)/wormlet.o: $(RECDIR)/wormlet.c
127 $(CC) $(APPCFLAGS) -c $< -o $@
128
125$(OBJDIR)/sokoban.o: $(RECDIR)/sokoban.c 129$(OBJDIR)/sokoban.o: $(RECDIR)/sokoban.c
126 $(CC) $(APPCFLAGS) -c $< -o $@ 130 $(CC) $(APPCFLAGS) -c $< -o $@
127 131
diff --git a/uisimulator/x11/Makefile b/uisimulator/x11/Makefile
index c381b915b2..7a61c50ed3 100644
--- a/uisimulator/x11/Makefile
+++ b/uisimulator/x11/Makefile
@@ -89,7 +89,8 @@ APPS = main.c tree.c menu.c credits.c main_menu.c\
89MENUS = games_menu.c screensavers_menu.c settings_menu.c sound_menu.c 89MENUS = games_menu.c screensavers_menu.c settings_menu.c sound_menu.c
90 90
91ifeq ($(DISPLAY),-DHAVE_LCD_BITMAP) 91ifeq ($(DISPLAY),-DHAVE_LCD_BITMAP)
92 APPS += tetris.c sokoban.c blank.c bounce.c boxes.c icons.c bmp.c widgets.c 92 APPS += tetris.c sokoban.c blank.c bounce.c boxes.c icons.c bmp.c \
93 widgets.c wormlet.c
93endif 94endif
94 95
95SRCS = screenhack.c uibasic.c resources.c visual.c lcd-x11.c stubs.c \ 96SRCS = screenhack.c uibasic.c resources.c visual.c lcd-x11.c stubs.c \
@@ -184,6 +185,9 @@ $(OBJDIR)/widgets.o: $(RECDIR)/widgets.c
184$(OBJDIR)/tetris.o: $(RECDIR)/tetris.c 185$(OBJDIR)/tetris.o: $(RECDIR)/tetris.c
185 $(CC) $(APPCFLAGS) -c $< -o $@ 186 $(CC) $(APPCFLAGS) -c $< -o $@
186 187
188$(OBJDIR)/wormlet.o: $(RECDIR)/wormlet.c
189 $(CC) $(APPCFLAGS) -c $< -o $@
190
187$(OBJDIR)/sokoban.o: $(RECDIR)/sokoban.c 191$(OBJDIR)/sokoban.o: $(RECDIR)/sokoban.c
188 $(CC) $(APPCFLAGS) -c $< -o $@ 192 $(CC) $(APPCFLAGS) -c $< -o $@
189 193