initial
[supertux.git] / src / leveleditor.c
1
2 /***************************************************************************
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  ***************************************************************************/
10
11 /* leveleditor.c - A built-in level editor for SuperTux
12  by Ricardo Cruz <rick2@aeiou.pt>                      */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <errno.h>
18 #include <unistd.h>
19 #include <SDL.h>
20 #include <SDL_image.h>
21
22 #include "leveleditor.h"
23 #include "gameloop.h"
24 #include "screen.h"
25 #include "defines.h"
26 #include "globals.h"
27 #include "setup.h"
28 #include "menu.h"
29
30 #include "badguy.h"
31
32 char levelname[60];
33 char leveltheme[60];
34 bad_guy_type bad_guys[NUM_BAD_GUYS];
35 SDL_Surface *img_bsod_left[4], *img_laptop_left[3], *img_money_left[2];
36 char song_title[60];
37 char levelfilename[100];
38
39 int time_left;
40 unsigned char* tiles[15];
41 int bkgd_red, bkgd_green, bkgd_blue, level_width;
42
43 SDL_Surface *selection;
44
45 /* definitions to aid development */
46 #define DONE_LEVELEDITOR    1
47 #define DONE_QUIT        2
48 #define DONE_CHANGELEVEL  3
49
50 /* definitions that affect gameplay */
51 #define KEY_CURSOR_SPEED 32
52 #define KEY_CURSOR_FASTSPEED 64
53 #define KEY_LEFT_MARGIN 160
54 #define KEY_RIGHT_MARGIN 480
55
56 #define MOUSE_LEFT_MARGIN 32
57 #define MOUSE_RIGHT_MARGIN 608
58 #define MOUSE_POS_SPEED 32
59
60 /* gameloop funcs declerations */
61
62 void loadlevelgfx(void);
63 void unloadlevelgfx(void);
64 void add_bad_guy(int x, int y, int kind);
65 void loadshared(void);
66 void unloadshared(void);
67 void drawshape(int x, int y, unsigned char c);
68
69 /* own declerations */
70
71 void savelevel();
72 void le_loadlevel(void);
73 void le_change(int x, int y, int sx, unsigned char c);
74 void showhelp();
75
76 /* FIXME: Needs to be implemented. It should ask the user for the level(file)name and then let him create a new level based on this. */
77 void newlevel()
78 {
79
80 }
81
82 /* FIXME: It should let select the user a level, which is in the leveldirectory and then load it. */
83 void selectlevel()
84 {
85
86 }
87
88 int leveleditor()
89 {
90 char str[10];
91
92
93 strcpy(levelfilename,"level1");
94
95 initmenu();
96 menumenu = MENU_LEVELEDITOR;
97 show_menu = YES;
98
99 loadshared();
100 le_loadlevel();
101 loadlevelgfx();
102
103 selection = load_image(DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA);
104
105 int done;
106 done = 0;
107
108 int x, y, i;    /* for cicles */
109 int pos_x, cursor_x, cursor_y, old_cursor_x, fire;
110
111 pos_x = 0;
112 cursor_x = 3*32;
113 old_cursor_x = cursor_x;
114 cursor_y = 2*32;
115 fire = DOWN;
116
117 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
118
119 SDL_Event event;
120 SDLKey key;
121 SDLMod keymod;
122
123 while(1)
124         {
125         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, bkgd_red, bkgd_green, bkgd_blue));
126
127         keymod = SDL_GetModState();
128
129         while(SDL_PollEvent(&event))
130                 {
131                 // testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events
132                 switch(event.type)
133                         {
134                         case SDL_KEYDOWN:       // key pressed
135                                 key = event.key.keysym.sym;
136                                 if(show_menu)
137                                 {
138                                 menu_event(key);
139                                 break;
140                                 }
141                                 switch(key)
142                                         {
143                                         case SDLK_LEFT:
144                                                 if(fire == DOWN)
145                                                         cursor_x -= KEY_CURSOR_SPEED;
146                                                 else
147                                                         cursor_x -= KEY_CURSOR_FASTSPEED;
148
149                                                 if(cursor_x < 0)
150                                                         cursor_x = 0;
151                                                 break;
152                                         case SDLK_RIGHT:
153                                                 if(fire == DOWN)
154                                                         cursor_x += KEY_CURSOR_SPEED;
155                                                 else
156                                                         cursor_x += KEY_CURSOR_FASTSPEED;
157
158                                                 if(cursor_x > (level_width*32) - 1)
159                                                         cursor_x = (level_width*32) - 1;
160                                                 break;
161                                         case SDLK_UP:
162                                                 if(fire == DOWN)
163                                                         cursor_y -= KEY_CURSOR_SPEED;
164                                                 else
165                                                         cursor_y -= KEY_CURSOR_FASTSPEED;
166
167                                                 if(cursor_y < 0)
168                                                         cursor_y = 0;
169                                                 break;
170                                         case SDLK_DOWN:
171                                                 if(fire == DOWN)
172                                                         cursor_y += KEY_CURSOR_SPEED;
173                                                 else
174                                                         cursor_y += KEY_CURSOR_FASTSPEED;
175
176                                                 if(cursor_y > 480-32)
177                                                         cursor_y = 480-32;
178                                                 break;
179                                         case SDLK_LCTRL:
180                                                 fire = UP;
181                                                 break;
182                                         case SDLK_F1:
183                                                 showhelp();
184                                                 break;
185                                         case SDLK_HOME:
186                                                 cursor_x = 0;
187                                                 break;
188                                         case SDLK_END:
189                                                 cursor_x = (level_width * 32) - 32;
190                                                 break;
191                                         case SDLK_PERIOD:
192                                                 le_change(cursor_x, cursor_y, 0, '.');
193                                                 break;
194                                         case SDLK_a:
195                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
196                                                         le_change(cursor_x, cursor_y, 0, 'A');
197                                                 else
198                                                         le_change(cursor_x, cursor_y, 0, 'a');
199                                                 break;
200                                         case SDLK_b:
201                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
202                                                         le_change(cursor_x, cursor_y, 0, 'B');
203                                                 break;
204                                         case SDLK_c:
205                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
206                                                         le_change(cursor_x, cursor_y, 0, 'C');
207                                                 else
208                                                         le_change(cursor_x, cursor_y, 0, 'c');
209                                                 break;
210                                         case SDLK_d:
211                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
212                                                         le_change(cursor_x, cursor_y, 0, 'D');
213                                                 else
214                                                         le_change(cursor_x, cursor_y, 0, 'd');
215                                                 break;
216                                         case SDLK_e:
217                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
218                                                         le_change(cursor_x, cursor_y, 0, 'E');
219                                                 else
220                                                         le_change(cursor_x, cursor_y, 0, 'e');
221                                                 break;
222                                         case SDLK_f:
223                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
224                                                         le_change(cursor_x, cursor_y, 0, 'F');
225                                                 else
226                                                         le_change(cursor_x, cursor_y, 0, 'f');
227                                                 break;
228                                         case SDLK_g:
229                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
230                                                         le_change(cursor_x, cursor_y, 0, 'G');
231                                                 else
232                                                         le_change(cursor_x, cursor_y, 0, 'g');
233                                                 break;
234                                         case SDLK_h:
235                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
236                                                         le_change(cursor_x, cursor_y, 0, 'H');
237                                                 else
238                                                         le_change(cursor_x, cursor_y, 0, 'h');
239                                                 break;
240                                         case SDLK_i:
241                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
242                                                         le_change(cursor_x, cursor_y, 0, 'I');
243                                                 else
244                                                         le_change(cursor_x, cursor_y, 0, 'i');
245                                                 break;
246                                         case SDLK_j:
247                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
248                                                         le_change(cursor_x, cursor_y, 0, 'J');
249                                                 else
250                                                         le_change(cursor_x, cursor_y, 0, 'j');
251                                                 break;
252                                         case SDLK_x:
253                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
254                                                         le_change(cursor_x, cursor_y, 0, 'X');
255                                                 else
256                                                         le_change(cursor_x, cursor_y, 0, 'x');
257                                                 break;
258                                         case SDLK_y:
259                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
260                                                         le_change(cursor_x, cursor_y, 0, 'Y');
261                                                 else
262                                                         le_change(cursor_x, cursor_y, 0, 'y');
263                                                 break;
264                                         case SDLK_LEFTBRACKET:
265                                                 le_change(cursor_x, cursor_y, 0, '[');
266                                                 break;
267                                         case SDLK_RIGHTBRACKET:
268                                                 le_change(cursor_x, cursor_y, 0, ']');
269                                                 break;
270                                         case SDLK_HASH:
271                                         case SDLK_3:
272                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
273                                                         le_change(cursor_x, cursor_y, 0, '#');
274                                                 break;
275                                         case SDLK_DOLLAR:
276                                         case SDLK_4:
277                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
278                                                         le_change(cursor_x, cursor_y, 0, '$');
279                                                 break;
280                                         case SDLK_BACKSLASH:
281                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
282                                                         le_change(cursor_x, cursor_y, 0, '|');
283                                                 else
284                                                         le_change(cursor_x, cursor_y, 0, '\\');
285                                                 break;
286                                         case SDLK_CARET:
287                                                 le_change(cursor_x, cursor_y, 0, '^');
288                                                 break;
289                                         case SDLK_AMPERSAND:
290                                         case SDLK_6:
291                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
292                                                         le_change(cursor_x, cursor_y, 0, '&');
293                                                 break;
294                                         case SDLK_EQUALS:
295                                         case SDLK_0:
296                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
297                                                         le_change(cursor_x, cursor_y, 0, '=');
298                                                 else            /* let's add a bad guy */
299                                                         le_change(cursor_x, cursor_y, 0, '0');
300
301                                                         for(i = 0; i < NUM_BAD_GUYS; ++i)
302                                                                 if (bad_guys[i].alive == NO)
303                                                                         {
304                                                                         bad_guys[i].alive = YES;
305                                                                         bad_guys[i].kind = BAD_BSOD;
306                                                                         bad_guys[i].x = (((int)cursor_x/32)*32);
307                                                                         bad_guys[i].y = (((int)cursor_y/32)*32);
308                                                                         i = NUM_BAD_GUYS;
309                                                                         }
310                                                 break;
311                                         case SDLK_1:
312                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
313                                                         le_change(cursor_x, cursor_y, 0, '!');
314                                                 else            /* let's add a bad guy */
315                                                         le_change(cursor_x, cursor_y, 0, '1');
316
317                                                         for(i = 0; i < NUM_BAD_GUYS; ++i)
318                                                                 if (bad_guys[i].alive == NO)
319                                                                         {
320                                                                         bad_guys[i].alive = YES;
321                                                                         bad_guys[i].kind = BAD_LAPTOP;
322                                                                         bad_guys[i].x = (((int)cursor_x/32)*32);
323                                                                         bad_guys[i].y = (((int)cursor_y/32)*32);
324                                                                         i = NUM_BAD_GUYS;
325                                                                         }
326                                                 break;
327                                         case SDLK_2:
328                                                 le_change(cursor_x, cursor_y, 0, '2');
329
330                                                 for(i = 0; i < NUM_BAD_GUYS; ++i)
331                                                         if (bad_guys[i].alive == NO)
332                                                                 {
333                                                                 bad_guys[i].alive = YES;
334                                                                 bad_guys[i].kind = BAD_MONEY;
335                                                                 bad_guys[i].x = (((int)cursor_x/32)*32);
336                                                                 bad_guys[i].y = (((int)cursor_y/32)*32);
337                                                                 i = NUM_BAD_GUYS;
338                                                                 }
339                                                 break;
340                                         case SDLK_PLUS:
341                                                 if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
342                                                         le_change(cursor_x, cursor_y, 0, '*');
343                                                 break;
344                                         default:
345                                                 break;
346                                         }
347                                 break;
348                         case SDL_KEYUP: // key released
349                                 switch(event.key.keysym.sym)
350                                         {
351                                         case SDLK_LCTRL:
352                                                 fire = DOWN;
353                                                 break;
354                                         case SDLK_ESCAPE:
355                                                 if(!show_menu)
356                                                 show_menu = YES;
357                                                 else
358                                                 show_menu = NO;
359                                                 break;
360                                         default:
361                                                 break;
362                                         }
363                                 break;
364                         case SDL_MOUSEBUTTONDOWN:
365                                 if(event.button.button == SDL_BUTTON_LEFT)
366                                         {
367                                         x = event.motion.x;
368                                         y = event.motion.y;
369
370                                         cursor_x = ((int)(pos_x + x) / 32) * 32;
371                                         cursor_y = ((int) y / 32) * 32;
372                                         }
373                                 break;
374                         case SDL_MOUSEMOTION:
375                                         x = event.motion.x;
376                                         y = event.motion.y;
377
378                                         cursor_x = ((int)(pos_x + x) / 32) * 32;
379                                         cursor_y = ((int) y / 32) * 32;
380                                         break;
381                         case SDL_QUIT:  // window closed
382                                 done = DONE_QUIT;
383                                 break;
384                         default:
385                                 break;
386                         }
387                 }
388
389         /* mouse movements */
390         x = event.motion.x;
391         if(x < MOUSE_LEFT_MARGIN)
392                 pos_x -= MOUSE_POS_SPEED;
393         else if(x > MOUSE_RIGHT_MARGIN)
394                 pos_x += MOUSE_POS_SPEED;
395
396  if(old_cursor_x != cursor_x)
397                 {
398                 if(cursor_x < pos_x + KEY_LEFT_MARGIN)
399                         pos_x = cursor_x - KEY_LEFT_MARGIN;
400
401                 if(cursor_x > pos_x + KEY_RIGHT_MARGIN)
402                         pos_x = cursor_x - KEY_RIGHT_MARGIN;
403                 }
404
405         if(pos_x < 0)
406                 pos_x = 0;
407         if(pos_x > (level_width * 32) - 640)
408                 pos_x = (level_width * 32) - 640;
409
410         old_cursor_x = cursor_x;
411
412         for (y = 0; y < 15; ++y)
413                 for (x = 0; x < 21; ++x)
414                         drawshape(x * 32, y * 32, tiles[y][x + (pos_x / 32)]);
415
416         /* Draw the Bad guys: */
417         for (i = 0; i < NUM_BAD_GUYS; ++i)
418                 {
419 /* printf("\nbad_guys[%i].alive = %i", i, bad_guys[i].alive); */
420                 if(bad_guys[i].alive == NO)
421                         continue;
422 /* to support frames: img_bsod_left[(frame / 5) % 4] */
423                 if(bad_guys[i].kind == BAD_BSOD)
424                         drawimage(img_bsod_left[0], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
425                 else if(bad_guys[i].kind == BAD_LAPTOP)
426                         drawimage(img_laptop_left[0], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
427                 else if (bad_guys[i].kind == BAD_MONEY)
428                         drawimage(img_money_left[0], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
429                 }
430
431                 
432         drawimage(selection, ((int)(cursor_x - pos_x)/32)*32, cursor_y, NO_UPDATE);
433
434         sprintf(str, "%d", time_left);
435         drawtext("TIME", 324, 0, letters_blue, NO_UPDATE);
436         drawtext(str, 404, 0, letters_gold, NO_UPDATE);
437         
438         sprintf(str, "%s", levelname);
439         drawtext("NAME", 0, 0, letters_blue, NO_UPDATE);
440         drawtext(str, 80, 0, letters_gold, NO_UPDATE);
441
442         drawtext("F1 for Help", 10, 430, letters_blue, NO_UPDATE);
443
444         if(show_menu)
445         {
446         done = drawmenu();
447         if(done)
448         return 0;
449         }
450         if(done == DONE_QUIT)
451         return 1;
452         
453         SDL_Delay(50);
454         SDL_Flip(screen);
455         }
456
457 unloadlevelgfx();
458 unloadshared();
459
460 SDL_FreeSurface(selection);
461
462 /*if(done == DONE_SAVE)*/       /* let's save the changes       */
463 /*      savelevel();*/
464 /*
465 if(done == DONE_CHANGELEVEL)             change level 
466         return leveleditor(level);
467 */
468 return done;
469 }
470
471 void le_change(int x, int y, int sx, unsigned char c)
472 {
473 int xx, yy;
474
475 yy = (y / 32);
476 xx = ((x + sx) / 32);
477
478 /* if there is a bad guy over there, remove it */
479 int i;
480 for(i = 0; i < NUM_BAD_GUYS; ++i)
481         if (bad_guys[i].alive)
482                 if(xx == bad_guys[i].x/32 && yy == bad_guys[i].y/32)
483                         bad_guys[i].alive = NO;
484
485
486 if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
487         tiles[yy][xx] = c;
488 }
489
490 /* Save data for this level: */
491 void savelevel(void)
492 {
493 FILE * fi;
494 char * filename;
495
496 char str[80];
497
498 /* Save data file: */
499
500 filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
501 sprintf(filename, "%s/levels/%s.dat", DATA_PREFIX, levelfilename);
502 fi = fopen(filename, "w");
503 if (fi == NULL)
504         {
505         perror(filename);
506         st_shutdown();
507         free(filename);
508         exit(-1);
509         }
510 free(filename);
511
512
513 /* sptrinf("# Level created by SuperTux built-in editor", fi); */
514
515 fputs(levelname, fi);
516 fputs("\n", fi);
517 fputs(leveltheme, fi);
518 fputs("\n", fi);
519 sprintf(str, "%d\n", time_left);        /* time */
520 fputs(str, fi);
521 fputs(song_title, fi);  /* song filename */
522 sprintf(str, "%d\n", bkgd_red); /* red background color */
523 fputs(str, fi);
524 sprintf(str, "%d\n", bkgd_green);       /* green background color */
525 fputs(str, fi);
526 sprintf(str, "%d\n", bkgd_blue);        /* blue background color */
527 fputs(str, fi);
528 sprintf(str, "%d\n", level_width);      /* level width */
529 fputs(str, fi);
530
531 int y;
532 for(y = 0; y < 15; ++y)
533         {
534         fputs(tiles[y], fi);
535         fputs("\n", fi);
536         }
537
538 fclose(fi);
539
540 drawcenteredtext("SAVED!", 240, letters_gold, NO_UPDATE);
541 SDL_Flip(screen);
542 SDL_Delay(1000);
543 }
544
545
546 /* I had to copy loadlevel, because loadlevel changes the tiles.
547  For intance, badguys are removed from the tiles and we have to
548  keep them there.                                             */
549
550 /* Load data for this level: */
551
552 void le_loadlevel(void)
553 {
554 FILE * fi;
555 char * filename;
556
557 char str[80];
558 char* line = malloc(sizeof(char)*10);/*[LEVEL_WIDTH + 5];*/
559
560 /* Load data file: */
561
562 filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
563 sprintf(filename, "%s/levels/%s.dat", DATA_PREFIX, levelfilename);
564 fi = fopen(filename, "r");
565 if (fi == NULL)
566         {
567         perror(filename);
568         st_shutdown();
569         free(filename);
570         exit(-1);
571         }
572 free(filename);
573
574 /* (Level title) */
575 fgets(str, 20, fi);
576 strcpy(levelname, str);
577 levelname[strlen(levelname)-1] = '\0';
578
579 /* (Level theme) */
580 fgets(str, 20, fi);
581 strcpy(leveltheme, str);
582 leveltheme[strlen(leveltheme)-1] = '\0';
583
584 fgets(line, 10, fi);
585 time_left = atoi(line);
586 fgets(str, 60, fi);
587 song_title[0]='\0';
588 strcpy(song_title,str);
589 fgets(line, 10, fi);
590 bkgd_red = atoi(line);
591 fgets(line, 10, fi);
592 bkgd_green= atoi(line);
593 fgets(line, 10, fi);
594 bkgd_blue = atoi(line);
595 fgets(line, 10, fi);
596 level_width = atoi(line);
597
598 free(line);
599 line = malloc(level_width*sizeof(char)+5);
600
601 int x, y;
602 for (y = 0; y < 15; ++y)
603         {
604         fgets(line, level_width + 5, fi);
605         line[strlen(line) - 1] = '\0';
606         free(tiles[y]);
607         tiles[y] = malloc((strlen(line)+5)*sizeof(char));
608         strcpy(tiles[y], line);
609         }
610
611 fclose(fi);
612
613 /* Activate bad guys: */
614
615 /* as oposed to the gameloop.c func, this one doesn't remove
616 the badguys from tiles                                    */
617
618 for (y = 0; y < 15; ++y)
619         for (x = 0; x < level_width; ++x)
620                 if (tiles[y][x] >= '0' && tiles[y][x] <= '9')
621                         add_bad_guy(x * 32, y * 32, tiles[y][x] - '0');
622
623
624 /* Set defaults: */
625
626 if(time_left == 0)
627         time_left = 255;
628
629
630 /* Level Intro: */
631
632 clearscreen(0, 0, 0);
633
634 sprintf(str, "Editing Level %s", levelfilename);
635 drawcenteredtext(str, 200, letters_red, NO_UPDATE);
636
637 sprintf(str, "%s", levelname);
638 drawcenteredtext(str, 224, letters_gold, NO_UPDATE);
639
640 SDL_Flip(screen);
641
642 SDL_Delay(1000);
643 }
644
645 void showhelp()
646 {
647 drawcenteredtext("- Help -", 30, letters_red, NO_UPDATE);
648 drawtext("Keys:", 80, 60, letters_gold, NO_UPDATE);
649
650 char *text[] = {
651         "X/x - Brick0",
652         "Y/y - Brick1",
653         "A/B/! - Box full",
654         "a - Box empty",
655         "C-F - Cloud0",
656         "c-f - Cloud1",
657         "G-J - Bkgd0",
658         "g-j - Bkgd1",
659         "# - Solid0",
660         "[ - Solid1",
661         "= - Solid2",
662         "] - Solid3",
663         "$ - Distro",
664         "^ - Waves",
665         "* - Poletop",
666         "| - Pole",
667         "\\ - Flag",
668         "& - Water",
669         "0-2 - BadGuys",
670         "./Del - Remove tile",
671         "Esc - Menu"};
672
673 int i;
674 for(i = 0; i < sizeof(text)/sizeof(char *); i++)
675         drawtext(text[i], 40, 90+(i*16), letters_blue, NO_UPDATE);
676
677 SDL_Flip(screen);
678
679 int done;
680 done = 0;
681 SDL_Event event;
682
683 while(done == 0)
684         while(SDL_PollEvent(&event))
685                 switch(event.type)
686                         {
687                         case SDL_KEYDOWN:               // key pressed
688                                 done = 1;
689                                 break;
690                         default:
691                                 break;
692                         }
693 }