draw*text <- functions can now specify the size of the shadow :)
[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 /*  December 28, 2003 - December 29, 2003 */
12  
13 /* leveleditor.c - A built-in level editor for SuperTux
14  by Ricardo Cruz <rick2@aeiou.pt>                      */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <SDL.h>
22 #include <SDL_image.h>
23
24 #include "leveleditor.h"
25 #include "gameloop.h"
26 #include "screen.h"
27 #include "defines.h"
28 #include "globals.h"
29 #include "setup.h"
30 #include "menu.h"
31
32 #include "badguy.h"
33
34 char levelname[60];
35 char leveltheme[60];
36 bad_guy_type bad_guys[NUM_BAD_GUYS];
37 SDL_Surface *img_bsod_left[4], *img_laptop_left[3], *img_money_left[2];
38 char song_title[60];
39 char levelfilename[100];
40
41 int time_left;
42 unsigned char* tiles[15];
43 int bkgd_red, bkgd_green, bkgd_blue, level_width;
44
45 SDL_Surface *selection;
46
47 /* definitions to aid development */
48 #define DONE_LEVELEDITOR    1
49 #define DONE_QUIT        2
50 #define DONE_CHANGELEVEL  3
51
52 /* definitions that affect gameplay */
53 #define KEY_CURSOR_SPEED 32
54 #define KEY_CURSOR_FASTSPEED 64
55 #define KEY_LEFT_MARGIN 160
56 #define KEY_RIGHT_MARGIN 480
57
58 #define MOUSE_LEFT_MARGIN 32
59 #define MOUSE_RIGHT_MARGIN 608
60 #define MOUSE_POS_SPEED 32
61
62 /* gameloop funcs declerations */
63
64 void loadlevelgfx(void);
65 void unloadlevelgfx(void);
66 void add_bad_guy(int x, int y, int kind);
67 void loadshared(void);
68 void unloadshared(void);
69 void drawshape(int x, int y, unsigned char c);
70
71 /* own declerations */
72
73 void savelevel();
74 void le_loadlevel(void);
75 void le_change(int x, int y, int sx, unsigned char c);
76 void showhelp();
77
78 /* 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. */
79 void newlevel()
80 {
81 }
82
83 /* FIXME: It should let select the user a level, which is in the leveldirectory and then load it. */
84 void selectlevel()
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, 1);
436       drawtext(str, 404, 0, letters_gold, NO_UPDATE, 1);
437
438       sprintf(str, "%s", levelname);
439       drawtext("NAME", 0, 0, letters_blue, NO_UPDATE, 1);
440       drawtext(str, 80, 0, letters_gold, NO_UPDATE, 1);
441
442       drawtext("F1 for Help", 10, 430, letters_blue, NO_UPDATE, 1);
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, 1);
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, 1);
636
637   sprintf(str, "%s", levelname);
638   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
639
640   SDL_Flip(screen);
641
642   SDL_Delay(1000);
643 }
644
645 void showhelp()
646 {
647   drawcenteredtext("- Help -", 30, letters_red, NO_UPDATE, 1);
648   drawtext("Keys:", 80, 60, letters_gold, NO_UPDATE, 1);
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, 1);
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 }