f26a200b2f3fb65247c5fc5465d50163358d918f
[rocksndiamonds.git] / src / screens.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  ©1995 Artsoft Development                               *
5 *        Holger Schemel                                    *
6 *        33659 Bielefeld-Senne                             *
7 *        Telefon: (0521) 493245                            *
8 *        eMail: aeglos@valinor.owl.de                      *
9 *               aeglos@uni-paderborn.de                    *
10 *               q99492@pbhrzx.uni-paderborn.de             *
11 *----------------------------------------------------------*
12 *  screens.c                                               *
13 ***********************************************************/
14
15 #include "screens.h"
16 #include "events.h"
17 #include "sound.h"
18 #include "game.h"
19 #include "tools.h"
20 #include "editor.h"
21 #include "misc.h"
22 #include "files.h"
23 #include "buttons.h"
24
25 void DrawMainMenu()
26 {
27   int i;
28
29   FadeSounds();
30   GetPlayerConfig();
31   LoadLevel(level_nr);
32
33   ClearWindow();
34   DrawText(SX+16, SY+8,  "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW);
35   DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel",
36            FS_SMALL,FC_RED);
37   DrawText(SX+32, SY+64, "Name:",FS_BIG,FC_GREEN);
38   DrawText(SX+192,SY+64, player.alias_name,FS_BIG,FC_RED);
39   DrawText(SX+32, SY+96, "Level:",FS_BIG,FC_GREEN);
40   DrawText(SX+352,SY+96, int2str(level_nr,3),FS_BIG,
41            (level_nr<leveldir[leveldir_nr].num_ready ? FC_RED : FC_YELLOW));
42   DrawText(SX+32, SY+128,"Hall Of Fame",FS_BIG,FC_GREEN);
43   DrawText(SX+32, SY+160,"Level Creator",FS_BIG,FC_GREEN);
44   DrawText(SY+32, SY+192,"Info Screen",FS_BIG,FC_GREEN);
45   DrawText(SX+32, SY+224,"Start Game",FS_BIG,FC_GREEN);
46   DrawText(SX+32, SY+256,"Setup",FS_BIG,FC_GREEN);
47   DrawText(SX+32, SY+288,"Quit",FS_BIG,FC_GREEN);
48
49   DrawMicroLevel(MICROLEV_XPOS,MICROLEV_YPOS);
50
51   for(i=2;i<10;i++)
52     DrawGraphic(0,i,GFX_KUGEL_BLAU);
53   DrawGraphic(10,3,GFX_KUGEL_BLAU);
54   DrawGraphic(14,3,GFX_KUGEL_BLAU);
55
56   DrawText(SX+54+16,SY+326,"A Game by Artsoft Development",FS_SMALL,FC_BLUE);
57   DrawText(SX+40+16,SY+344,"Graphics: Deluxe Paint IV Amiga",
58            FS_SMALL,FC_BLUE);
59   DrawText(SX+60+16,SY+362,"Sounds: AudioMaster IV Amiga",
60            FS_SMALL,FC_BLUE);
61
62   FadeToFront();
63   InitAnimation();
64   HandleMainMenu(0,0,0,0,MB_MENU_MARK);
65
66   TapeStop();
67   if (TAPE_IS_EMPTY(tape))
68     LoadLevelTape(level_nr);
69   DrawCompleteVideoDisplay();
70
71   OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
72
73   XAutoRepeatOn(display);
74 }
75
76 void HandleMainMenu(int mx, int my, int dx, int dy, int button)
77 {
78   static int choice = 3;
79   static int redraw = TRUE;
80   int x = (mx+32-SX)/32, y = (my+32-SY)/32;
81
82   if (redraw)
83   {
84     DrawGraphic(0,choice-1,GFX_KUGEL_ROT);
85     redraw = FALSE;
86   }
87
88   if (dx || dy)
89   {
90     if (dx && choice==4)
91     {
92       x = (dx<0 ? 11 : 15);
93       y = 4;
94     }
95     else if (dy)
96     {
97       x = 1;
98       y = choice+dy;
99     }
100     else
101       x = y = 0;
102
103     if (y<3)
104       y = 3;
105     else if (y>10)
106       y = 10;
107   }
108
109   if (!mx && !my && !dx && !dy)
110   {
111     x = 1;
112     y = choice;
113   }
114
115   if (y==4 && ((x==11 && level_nr>0) ||
116                (x==15 && level_nr<LEVELDIR_SIZE(leveldir[leveldir_nr]))) &&
117       button)
118   {
119     static long level_delay = 0;
120     int step = (button==1 ? 1 : button==2 ? 5 : 10);
121     int new_level_nr, old_level_nr = level_nr;
122
123     new_level_nr = level_nr + (x==11 ? -step : +step);
124     if (new_level_nr<0)
125       new_level_nr = 0;
126     if (new_level_nr>LEVELDIR_SIZE(leveldir[leveldir_nr])-1)
127       new_level_nr = LEVELDIR_SIZE(leveldir[leveldir_nr])-1;
128
129     if (old_level_nr==new_level_nr || !DelayReached(&level_delay,20))
130       goto out;
131
132     level_nr = new_level_nr;
133
134     if (level_nr>player.handicap && level_nr<leveldir[leveldir_nr].num_ready)
135     {
136       if (x==11 || leveldir[leveldir_nr].num_free==0)
137         level_nr = player.handicap;
138       else
139         level_nr = leveldir[leveldir_nr].num_ready;
140     }
141
142     DrawTextExt(drawto,gc,SX+352,SY+96, int2str(level_nr,3),FS_BIG,
143                 (level_nr<leveldir[leveldir_nr].num_ready ?FC_RED :FC_YELLOW));
144     DrawTextExt(window,gc,SX+352,SY+96, int2str(level_nr,3),FS_BIG,
145                 (level_nr<leveldir[leveldir_nr].num_ready ?FC_RED :FC_YELLOW));
146
147     LoadLevel(level_nr);
148     DrawMicroLevel(MICROLEV_XPOS,MICROLEV_YPOS);
149
150     TapeErase();
151     LoadLevelTape(level_nr);
152     DrawCompleteVideoDisplay();
153   }
154   else if (x==1 && y>=3 && y<=10)
155   {
156     if (button)
157     {
158       if (y!=choice)
159       {
160         DrawGraphic(0,y-1,GFX_KUGEL_ROT);
161         DrawGraphic(0,choice-1,GFX_KUGEL_BLAU);
162       }
163       choice = y;
164     }
165     else
166     {
167       if (y==3)
168       {
169         game_status = TYPENAME;
170         HandleTypeName(strlen(player.alias_name),0);
171       }
172       else if (y==4)
173       {
174         if (num_leveldirs)
175         {
176           game_status = CHOOSELEVEL;
177           DrawChooseLevel();
178           redraw = TRUE;
179         }
180       }
181       else if (y==5)
182       {
183         game_status = HALLOFFAME;
184         DrawHallOfFame(-1);
185         redraw = TRUE;
186       }
187       else if (y==6)
188       {
189         game_status = LEVELED;
190         DrawLevelEd();
191         redraw = TRUE;
192       }
193       else if (y==7)
194       {
195         game_status = HELPSCREEN;
196         DrawHelpScreen();
197         redraw = TRUE;
198       }
199       else if (y==8)
200       {
201         if (autorecord_on && !tape.playing)
202           TapeInitRecording();
203
204         game_status = PLAYING;
205         InitGame();
206         redraw = TRUE;
207       }
208       else if (y==9)
209       {
210         game_status = SETUP;
211         DrawSetupScreen();
212         redraw = TRUE;
213       }
214       else if (y==10)
215       {
216         if (AreYouSure("Do you really want to quit ?",AYS_ASK|AYS_STAY_CLOSED))
217           game_status = EXITGAME;
218       }
219     }
220   }
221   BackToFront();
222
223   out:
224
225   if (game_status==MAINMENU)
226     DoAnimation();
227 }
228
229 #define MAX_HELPSCREEN_ELS      10
230 #define HA_NEXT                 -999
231 #define HA_END                  -1000
232
233 static long helpscreen_state;
234 static int helpscreen_step[MAX_HELPSCREEN_ELS];
235 static int helpscreen_frame[MAX_HELPSCREEN_ELS];
236 static int helpscreen_delay[MAX_HELPSCREEN_ELS];
237 static int helpscreen_action[] =
238 {
239   GFX_SPIELFIGUR,1,100,                                         HA_NEXT,
240   GFX_ERDREICH,1,100,                                           HA_NEXT,
241   GFX_LEERRAUM,1,100,                                           HA_NEXT,
242   GFX_MORAST_LEER,1,100,                                        HA_NEXT,
243   GFX_BETON,1,100,                                              HA_NEXT,
244   GFX_MAUERWERK,1,100,                                          HA_NEXT,
245   GFX_MAUER_R1,3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,
246   GFX_MAUER_L1,3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,      HA_NEXT,
247   GFX_UNSICHTBAR,1,100,                                         HA_NEXT,
248   GFX_FELSBODEN,1,100,                                          HA_NEXT,
249   GFX_CHAR_A,30,3, GFX_CHAR_AUSRUF,32,3,                        HA_NEXT,
250   GFX_EDELSTEIN,2,5,                                            HA_NEXT,
251   GFX_DIAMANT,2,5,                                              HA_NEXT,
252   GFX_EDELSTEIN2,2,5,                                           HA_NEXT,
253   GFX_EDELSTEIN3,2,5,                                           HA_NEXT,
254   GFX_FELSBROCKEN,4,5,                                          HA_NEXT,
255   GFX_BOMBE,1,50, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10,         HA_NEXT,
256   GFX_KOKOSNUSS,1,50, GFX_CRACKINGNUT,3,1, GFX_EDELSTEIN,1,10,  HA_NEXT,
257   GFX_ERZ_EDEL,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN,1,10,     HA_NEXT,
258   GFX_ERZ_DIAM,1,50, GFX_EXPLOSION,8,1, GFX_DIAMANT,1,10,       HA_NEXT,
259   GFX_ERZ_EDEL2,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN2,1,10,   HA_NEXT,
260   GFX_ERZ_EDEL3,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN3,1,10,   HA_NEXT,
261   GFX_GEBLUBBER,4,4,                                            HA_NEXT,
262   GFX_SCHLUESSEL1,4,33,                                         HA_NEXT,
263   GFX_PFORTE1,4,33,                                             HA_NEXT,
264   GFX_PFORTE1X,4,33,                                            HA_NEXT,
265   GFX_DYNAMIT_AUS,1,100,                                        HA_NEXT,
266   GFX_DYNAMIT,7,6, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10,        HA_NEXT,
267   GFX_DYNABOMB,1,33, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10,      HA_NEXT,
268   GFX_DYNABOMB_NR,1,100,                                        HA_NEXT,
269   GFX_DYNABOMB_SZ,1,100,                                        HA_NEXT,
270   GFX_FLIEGER+4,1,3, GFX_FLIEGER+0,1,3, GFX_FLIEGER+4,1,3,
271   GFX_FLIEGER+5,1,3, GFX_FLIEGER+1,1,3, GFX_FLIEGER+5,1,3,
272   GFX_FLIEGER+6,1,3, GFX_FLIEGER+2,1,3, GFX_FLIEGER+6,1,3,
273   GFX_FLIEGER+7,1,3, GFX_FLIEGER+3,1,3, GFX_FLIEGER+7,1,3,      HA_NEXT,
274   GFX_KAEFER+4,1,1, GFX_KAEFER+0,1,1, GFX_KAEFER+4,1,1,
275   GFX_KAEFER+5,1,1, GFX_KAEFER+1,1,1, GFX_KAEFER+5,1,1,
276   GFX_KAEFER+6,1,1, GFX_KAEFER+2,1,1, GFX_KAEFER+6,1,1,
277   GFX_KAEFER+7,1,1, GFX_KAEFER+3,1,1, GFX_KAEFER+7,1,1,         HA_NEXT,
278   GFX_PACMAN+0,1,3, GFX_PACMAN+4,1,2, GFX_PACMAN+0,1,3,
279   GFX_PACMAN+1,1,3, GFX_PACMAN+5,1,2, GFX_PACMAN+1,1,3,
280   GFX_PACMAN+2,1,3, GFX_PACMAN+6,1,2, GFX_PACMAN+2,1,3,
281   GFX_PACMAN+3,1,3, GFX_PACMAN+7,1,2, GFX_PACMAN+3,1,3,         HA_NEXT,
282   GFX_MAMPFER+0,4,0, GFX_MAMPFER+3,1,0, GFX_MAMPFER+2,1,0,
283   GFX_MAMPFER+1,1,0,                                            HA_NEXT,
284   GFX_MAMPFER2+0,4,0, GFX_MAMPFER2+3,1,0, GFX_MAMPFER2+2,1,0,
285   GFX_MAMPFER2+1,1,0,                                           HA_NEXT,
286   GFX_ZOMBIE+0,4,0, GFX_ZOMBIE+3,1,0, GFX_ZOMBIE+2,1,0,
287   GFX_ZOMBIE+1,1,0,                                             HA_NEXT,
288   GFX_ABLENK,4,1,                                               HA_NEXT,
289   GFX_BIRNE_AUS,1,33, GFX_BIRNE_EIN,1,33,                       HA_NEXT,
290   GFX_ZEIT_VOLL,1,33, GFX_ZEIT_LEER,1,33,                       HA_NEXT,
291   GFX_TROPFEN,1,33, GFX_AMOEBING,4,1, GFX_AMOEBE_LEBT,1,10,     HA_NEXT,
292   GFX_AMOEBE_TOT+2,2,50, GFX_AMOEBE_TOT,2,50,                   HA_NEXT,
293   GFX_AMOEBE_LEBT,4,40,                                         HA_NEXT,
294   GFX_AMOEBE_LEBT,1,10, GFX_AMOEBING,4,2,                       HA_NEXT,
295   GFX_AMOEBE_LEBT,1,33, GFX_AMOEBE_TOT,1,33, GFX_EXPLOSION,8,1,
296   GFX_DIAMANT,1,10,                                             HA_NEXT,
297   GFX_LIFE,1,100,                                               HA_NEXT,
298   GFX_LIFE_ASYNC,1,100,                                         HA_NEXT,
299   GFX_SIEB_LEER,4,2,                                            HA_NEXT,
300   GFX_SIEB2_LEER,4,2,                                           HA_NEXT,
301   GFX_AUSGANG_ZU,1,100, GFX_AUSGANG_ACT,4,2,
302   GFX_AUSGANG_AUF+0,4,1, GFX_AUSGANG_AUF+3,1,1,
303   GFX_AUSGANG_AUF+2,1,1, GFX_AUSGANG_AUF+1,1,1,                 HA_NEXT,
304   GFX_AUSGANG_AUF+0,4,1, GFX_AUSGANG_AUF+3,1,1,
305   GFX_AUSGANG_AUF+2,1,1, GFX_AUSGANG_AUF+1,1,1,                 HA_NEXT,
306   HA_END
307 };
308 static char *helpscreen_eltext[][2] =
309 {
310   "THE HERO:",                          "(Is _this_ guy good old Rockford?)",
311   "Normal sand:",                       "You can dig through it",
312   "Empty field:",                       "You can walk through it",
313   "Quicksand: You cannot pass it,",     "but rocks can fall though it",
314   "Massive Wall:",                      "Nothing can go through it",
315   "Normal Wall: You can't go through",  "it, but you can bomb it away",
316   "Growing Wall: Grows to the left or", "right if there is an empty field",
317   "Invisible Wall: Behaves like normal","wall, but is invisible",
318   "Old Wall: Like normal wall, but",    "some things can fall down from it",
319   "Letter Wall: Looks like a letter,",  "behaves like a normal wall",
320   "Emerald: You must collect enough of","them to finish a level",
321   "Diamond: Counts as 3 emeralds, but", "can be destroyed by rocks",
322   "Diamond (BD style): Counts like one","emerald and behaves a bit different",
323   "Red emerald: Seems to behave like",  "the BD style diamond",
324   "Rock: Smashes several things;",      "Can be moved by the player",
325   "Bomb: You can move it, but be",      "careful when dropping it",
326   "Nut: Throw a rock on it to open it;","Each nut contains an emerald",
327   "Wall with an emerald inside:",       "Bomb the wall away to get it",
328   "Wall with a diamond inside:",        "Bomb the wall away to get it",
329   "Wall with BD style diamond inside:", "Bomb the wall away to get it",
330   "Wall with red emerald inside:",      "Bomb the wall away to get it",
331   "Acid: Things that fall in are gone", "forever (including our hero)",
332   "Key: Opens the door that has the",   "same color (red/yellow/green/blue)",
333   "Door: Can be opened by the key",     "with the same color",
334   "Door: You have to find out the",     "right color of the key for it",
335   "Dynamite: Collect it and use it to", "destroy walls or kill enemies",
336   "Dynamite: This one explodes after",  "a few seconds",
337   "Dyna Bomb: Explodes in 4 directions","with variable explosion size",
338   "Dyna Bomb: Increases the number of", "dyna bombs available at a time",
339   "Dyna Bomb: Increases the size of",   "explosion of dyna bombs",
340   "Spaceship: Moves at the left side",  "of walls; don't touch it!",
341   "Bug: Moves at the right side of",    "walls; don't touch it!",
342   "Pacman: Eats the amoeba and you,",   "if you're not careful",
343   "Cruncher: Eats diamonds and you,",   "if you're not careful",
344   "Cruncher (BD style):",               "Eats almost everything",
345   "Robot: Tries to kill the player",    "",
346   "Magic Wheel: Touch it to get rid of","the robots for some seconds",
347   "Light Bulb: It seems to have no",    "special function, but looks nice",
348   "Extra Time Orb: Adds some seconds",  "to the time available for the level",
349   "Amoeba Drop: Grows to an amoeba on", "the ground - don't touch it",
350   "Dead Amoeba: Does not grow, but",    "can still kill bugs and spaceships",
351   "Normal Amoeba: Grows through empty", "fields, sand and quicksand",
352   "Dropping Amoeba: This one makes",    "drops that grow to a new amoeba",
353   "Living Amoeba (BD style): Contains", "other element, when surrounded",
354   "Game Of Life: Behaves like the well","known 'Game Of Life' (2333 style)",
355   "Biomaze: A bit like the 'Game Of",   "Life', but builds crazy mazes",
356   "Magic Wall: Changes rocks, emeralds","and diamonds when they pass it",
357   "Magic Wall (BD style):",             "Changes rocks and BD style diamonds",
358   "Exit door: Opens if you have enough","emeralds to finish the level",
359   "Open exit door: Enter here to leave","the level and exit the actual game",
360 };
361 static int num_helpscreen_els = sizeof(helpscreen_eltext)/(2*sizeof(char *));
362
363 static char *helpscreen_music[][3] =
364 {
365   "Alchemy",                    "Ian Boddy",            "Drive",
366   "The Chase",                  "Propaganda",           "A Secret Wish",
367   "Network 23",                 "Tangerine Dream",      "Exit",
368   "Czardasz",                   "Robert Pieculewicz",   "Czardasz",
369   "21st Century Common Man",    "Tangerine Dream",      "Tyger",
370   "Voyager",                    "The Alan Parsons Project","Pyramid",
371   "Twilight Painter",           "Tangerine Dream",      "Heartbreakers"
372 };
373 static int helpscreen_musicpos;
374
375 void DrawHelpScreenElAction(int start)
376 {
377   int i = 0, j = 0;
378   int frame, delay, graphic;
379   int xstart = SX+16, ystart = SY+64+2*32, ystep = TILEY+4;
380
381   while(helpscreen_action[j] != HA_END)
382   {
383     if (i>=start+MAX_HELPSCREEN_ELS || i>=num_helpscreen_els)
384       break;
385     else if (i<start || helpscreen_delay[i-start])
386     {
387       if (i>=start && helpscreen_delay[i-start])
388         helpscreen_delay[i-start]--;
389
390       while(helpscreen_action[j] != HA_NEXT)
391         j++;
392       j++;
393       i++;
394       continue;
395     }
396
397     j += 3*helpscreen_step[i-start];
398     graphic = helpscreen_action[j++];
399
400     if (helpscreen_frame[i-start])
401     {
402       frame = helpscreen_action[j++] - helpscreen_frame[i-start];
403       helpscreen_frame[i-start]--;
404     }
405     else
406     {
407       frame = 0;
408       helpscreen_frame[i-start] = helpscreen_action[j++]-1;
409     }
410
411     delay = helpscreen_action[j++];
412     helpscreen_delay[i-start] = delay;
413
414     if (helpscreen_action[j] == HA_NEXT)
415     {
416       if (!helpscreen_frame[i-start])
417         helpscreen_step[i-start] = 0;
418     }
419     else
420     {
421       if (!helpscreen_frame[i-start])
422         helpscreen_step[i-start]++;
423       while(helpscreen_action[j] != HA_NEXT)
424         j++;
425     }
426     j++;
427
428     DrawGraphicExtHiRes(drawto,gc,xstart,ystart+(i-start)*ystep,
429                         graphic+frame);
430     i++;
431   }
432
433   redraw_tiles += 28;
434   for(i=2;i<16;i++)
435     redraw[0][i] = redraw[1][i] = TRUE;
436   redraw_mask |= REDRAW_TILES;
437 }
438
439 void DrawHelpScreenElText(int start)
440 {
441   int i;
442   int xstart = SX+56, ystart = SY+65+2*32, ystep = TILEY+4;
443   char text[FULL_SXSIZE/FONT2_XSIZE+10];
444
445   ClearWindow();
446   DrawText(SX+16, SY+8,  "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW);
447   DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel",
448            FS_SMALL,FC_RED);
449
450   sprintf(text,"The game elements:");
451   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+100,
452            text,FS_SMALL,FC_GREEN);
453
454   for(i=start;i<start+MAX_HELPSCREEN_ELS && i<num_helpscreen_els;i++)
455   {
456     DrawText(xstart,ystart+(i-start)*ystep+(*helpscreen_eltext[i][1] ? 0 : 8),
457              helpscreen_eltext[i][0],FS_SMALL,FC_YELLOW);
458     DrawText(xstart,ystart+(i-start)*ystep+16,
459              helpscreen_eltext[i][1],FS_SMALL,FC_YELLOW);
460   }
461
462   sprintf(text,"Press any key or button for next page");
463   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+SYSIZE-20,
464            text,FS_SMALL,FC_BLUE);
465 }
466
467 void DrawHelpScreenMusicText(int num)
468 {
469   int ystart = 150, ystep = 30;
470   char text[FULL_SXSIZE/FONT2_XSIZE+10];
471
472   FadeSounds();
473   ClearWindow();
474   DrawText(SX+16, SY+8,  "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW);
475   DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel",
476            FS_SMALL,FC_RED);
477
478   sprintf(text,"The game background music loops:");
479   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+100,
480            text,FS_SMALL,FC_GREEN);
481
482   sprintf(text,"Excerpt from");
483   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+0*ystep,
484            text,FS_SMALL,FC_YELLOW);
485   sprintf(text,"%c%s%c",'\"',helpscreen_music[num][0],'\"');
486   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+1*ystep,
487            text,FS_SMALL,FC_RED);
488   sprintf(text,"by");
489   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+2*ystep,
490            text,FS_SMALL,FC_YELLOW);
491   sprintf(text,"%s",helpscreen_music[num][1]);
492   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+3*ystep,
493            text,FS_SMALL,FC_RED);
494   sprintf(text,"from the album");
495   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+4*ystep,
496            text,FS_SMALL,FC_YELLOW);
497   sprintf(text,"%c%s%c",'\"',helpscreen_music[num][2],'\"');
498   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+5*ystep,
499            text,FS_SMALL,FC_RED);
500
501   sprintf(text,"Press any key or button for next page");
502   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+SYSIZE-20,
503            text,FS_SMALL,FC_BLUE);
504
505   PlaySoundLoop(background_loop[num]);
506 }
507
508 void DrawHelpScreenCreditsText()
509 {
510   int ystart = 150, ystep = 30;
511   char text[FULL_SXSIZE/FONT2_XSIZE+10];
512
513   FadeSounds();
514   ClearWindow();
515   DrawText(SX+16, SY+8,  "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW);
516   DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel",
517            FS_SMALL,FC_RED);
518
519   sprintf(text,"Program information:");
520   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+100,
521            text,FS_SMALL,FC_GREEN);
522
523   sprintf(text,"This game is Freeware!");
524   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+0*ystep,
525            text,FS_SMALL,FC_YELLOW);
526   sprintf(text,"If you like it, send e-mail to:");
527   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+1*ystep,
528            text,FS_SMALL,FC_YELLOW);
529   sprintf(text,"aeglos@valinor.owl.de");
530   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+2*ystep,
531            text,FS_SMALL,FC_RED);
532   sprintf(text,"or SnailMail to:");
533   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+3*ystep,
534            text,FS_SMALL,FC_YELLOW);
535   sprintf(text,"Holger Schemel");
536   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+4*ystep,
537            text,FS_SMALL,FC_RED);
538   sprintf(text,"Sennehof 28");
539   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+4*ystep+20,
540            text,FS_SMALL,FC_RED);
541   sprintf(text,"33659 Bielefeld");
542   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+4*ystep+40,
543            text,FS_SMALL,FC_RED);
544   sprintf(text,"Germany");
545   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+4*ystep+60,
546            text,FS_SMALL,FC_RED);
547
548   sprintf(text,"If you have created new levels,");
549   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+7*ystep,
550            text,FS_SMALL,FC_YELLOW);
551   sprintf(text,"send them to me to include them!");
552   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+8*ystep,
553            text,FS_SMALL,FC_YELLOW);
554   sprintf(text,":-)");
555   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+9*ystep,
556            text,FS_SMALL,FC_YELLOW);
557
558   sprintf(text,"Press any key or button for main menu");
559   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+SYSIZE-20,
560            text,FS_SMALL,FC_BLUE);
561 }
562
563 void DrawHelpScreen()
564 {
565   int i;
566
567   CloseDoor(DOOR_CLOSE_2);
568
569   for(i=0;i<MAX_HELPSCREEN_ELS;i++)
570     helpscreen_step[i] = helpscreen_frame[i] = helpscreen_delay[i] = 0;
571   helpscreen_musicpos = 0;
572   helpscreen_state = 0;
573   DrawHelpScreenElText(0);
574   DrawHelpScreenElAction(0);
575
576   FadeToFront();
577   InitAnimation();
578   PlaySoundLoop(SND_RHYTHMLOOP);
579 }
580
581 void HandleHelpScreen(int button)
582 {
583   static long hs_delay = 0;
584   int num_helpscreen_els_pages =
585     (num_helpscreen_els + MAX_HELPSCREEN_ELS-1) / MAX_HELPSCREEN_ELS;
586   int button_released = !button;
587   int i;
588
589   if (button_released)
590   {
591     if (helpscreen_state<num_helpscreen_els_pages-1)
592     {
593       for(i=0;i<MAX_HELPSCREEN_ELS;i++)
594         helpscreen_step[i] = helpscreen_frame[i] = helpscreen_delay[i] = 0;
595       helpscreen_state++;
596       DrawHelpScreenElText(helpscreen_state*MAX_HELPSCREEN_ELS);
597       DrawHelpScreenElAction(helpscreen_state*MAX_HELPSCREEN_ELS);
598     }
599     else if (helpscreen_state<num_helpscreen_els_pages+num_bg_loops-1)
600     {
601       helpscreen_state++;
602       DrawHelpScreenMusicText(helpscreen_state-num_helpscreen_els_pages);
603     }
604     else if (helpscreen_state==num_helpscreen_els_pages+num_bg_loops-1)
605     {
606       helpscreen_state++;
607       DrawHelpScreenCreditsText();
608     }
609     else
610     {
611       FadeSounds();
612       DrawMainMenu();
613       game_status = MAINMENU;
614     }
615   }
616   else
617   {
618     if (DelayReached(&hs_delay,3))
619     {
620       if (helpscreen_state<num_helpscreen_els_pages)
621         DrawHelpScreenElAction(helpscreen_state*MAX_HELPSCREEN_ELS);
622     }
623     DoAnimation();
624   }
625
626   BackToFront();
627 }
628
629 void CheckCheat()
630 {
631   int old_handicap = player.handicap;
632
633   if (!strcmp(player.alias_name,"Artsoft"))
634     player.handicap = MAX(0,leveldir[leveldir_nr].num_ready-1);
635
636   if (player.handicap != old_handicap)
637   {
638     SavePlayerInfo(PLAYER_LEVEL);
639     level_nr = player.handicap;
640   }
641 }
642
643 void HandleTypeName(int newxpos, KeySym key)
644 {
645   static int xpos = 0, ypos = 2;
646   unsigned char ascii;
647
648   if (newxpos)
649   {
650     xpos = newxpos;
651     DrawText(SX+6*32,SY+ypos*32,player.alias_name,FS_BIG,FC_YELLOW);
652     DrawGraphic(xpos+6,ypos,GFX_KUGEL_ROT);
653     return;
654   }
655
656   if ((key>=XK_A && key<=XK_Z) || (key>=XK_a && key<=XK_z && 
657       xpos<MAX_NAMELEN-1))
658   {
659     if (key>=XK_A && key<=XK_Z)
660       ascii = 'A'+(char)(key-XK_A);
661     if (key>=XK_a && key<=XK_z)
662       ascii = 'a'+(char)(key-XK_a);
663     player.alias_name[xpos] = ascii;
664     player.alias_name[xpos+1] = 0;
665     xpos++;
666     DrawTextExt(drawto,gc,SX+6*32,SY+ypos*32,
667                 player.alias_name,FS_BIG,FC_YELLOW);
668     DrawTextExt(window,gc,SX+6*32,SY+ypos*32,
669                 player.alias_name,FS_BIG,FC_YELLOW);
670     DrawGraphic(xpos+6,ypos,GFX_KUGEL_ROT);
671   }
672   else if (key==XK_Delete && xpos>0)
673   {
674     player.alias_name[xpos] = 0;
675     xpos--;
676     DrawGraphic(xpos+6,ypos,GFX_KUGEL_ROT);
677     DrawGraphic(xpos+7,ypos,GFX_LEERRAUM);
678   }
679   else if (key==XK_Return && xpos>0)
680   {
681     DrawText(SX+6*32,SY+ypos*32,player.alias_name,FS_BIG,FC_RED);
682     DrawGraphic(xpos+6,ypos,GFX_LEERRAUM);
683     SavePlayerInfo(PLAYER_SETUP);
684     CheckCheat();
685
686     game_status = MAINMENU;
687     DrawMainMenu();
688   }
689   BackToFront();
690 }
691
692 void DrawChooseLevel()
693 {
694   int i;
695
696   CloseDoor(DOOR_CLOSE_2);
697
698   ClearWindow();
699   DrawText(SX,SY,"Level Directories",FS_BIG,FC_GREEN);
700   for(i=0;i<num_leveldirs;i++)
701   {
702     DrawText(SX+32,SY+(i+2)*32,leveldir[i].name,FS_BIG,FC_YELLOW);
703     DrawGraphic(0,i+2,GFX_KUGEL_BLAU);
704   }
705
706   FadeToFront();
707   InitAnimation();
708   HandleChooseLevel(0,0,0,0,MB_MENU_MARK);
709 }
710
711 void HandleChooseLevel(int mx, int my, int dx, int dy, int button)
712 {
713   static int choice = 3;
714   static int redraw = TRUE;
715   int x = (mx+32-SX)/32, y = (my+32-SY)/32;
716
717   if (redraw)
718   {
719     DrawGraphic(0,choice-1,GFX_KUGEL_ROT);
720     redraw = FALSE;
721   }
722
723   if (dx || dy)
724   {
725     if (dy)
726     {
727       x = 1;
728       y = choice+dy;
729     }
730     else
731       x = y = 0;
732
733     if (y<3)
734       y = 3;
735     else if (y>num_leveldirs+2)
736       y = num_leveldirs+2;
737   }
738
739   if (!mx && !my && !dx && !dy)
740   {
741     x = 1;
742     y = choice;
743   }
744
745   if (x==1 && y>=3 && y<=num_leveldirs+2)
746   {
747     if (button)
748     {
749       if (y!=choice)
750       {
751         DrawGraphic(0,y-1,GFX_KUGEL_ROT);
752         DrawGraphic(0,choice-1,GFX_KUGEL_BLAU);
753       }
754       choice = y;
755     }
756     else
757     {
758       player.leveldir_nr = leveldir_nr = y-3;
759       LoadPlayerInfo(PLAYER_LEVEL);
760       SavePlayerInfo(PLAYER_SETUP);
761       CheckCheat();
762
763       game_status = MAINMENU;
764       DrawMainMenu();
765       redraw = TRUE;
766     }
767   }
768   BackToFront();
769
770   if (game_status==CHOOSELEVEL)
771     DoAnimation();
772 }
773
774 void DrawHallOfFame(int pos)
775 {
776   int y;
777   char txt[40];
778
779   CloseDoor(DOOR_CLOSE_2);
780
781   if (pos<0) 
782     LoadScore(level_nr);
783   ClearWindow();
784   DrawText(SX+64,SY+10,"Hall Of Fame",FS_BIG,FC_YELLOW);
785   sprintf(txt,"HighScores of Level %d",level_nr);
786   DrawText(SX+256-strlen(txt)*7,SY+48,txt,FS_SMALL,FC_RED);
787   for(y=0;y<MAX_SCORE_ENTRIES;y++)
788   {
789     DrawText(SX,SY+64+y*32,".................",FS_BIG,
790              (y==pos ? FC_RED : FC_GREEN));
791     DrawText(SX,SY+64+y*32,highscore[y].Name,FS_BIG,
792              (y==pos ? FC_RED : FC_GREEN));
793     DrawText(SX+12*32,SY+64+y*32,
794              int2str(highscore[y].Score,5),FS_BIG,
795              (y==pos ? FC_RED : FC_GREEN));
796   }
797
798   FadeToFront();
799   InitAnimation();
800   PlaySound(SND_HALLOFFAME);
801 }
802
803 void HandleHallOfFame(int button)
804 {
805   int button_released = !button;
806
807   if (button_released)
808   {
809     FadeSound(SND_HALLOFFAME);
810     game_status = MAINMENU;
811     DrawMainMenu();
812     BackToFront();
813   }
814   else
815     DoAnimation();
816 }
817
818 void DrawSetupScreen()
819 {
820   int i;
821
822   CloseDoor(DOOR_CLOSE_2);
823
824   ClearWindow();
825   DrawText(SX+16, SY+16,  "SETUP",FS_BIG,FC_YELLOW);
826   DrawText(SX+32, SY+2*32,"Sound:",FS_BIG,FC_GREEN);
827   DrawText(SX+32, SY+3*32,"Sound loops:",FS_BIG,FC_GREEN);
828   DrawText(SX+32, SY+4*32,"Game music:",FS_BIG,FC_GREEN);
829   DrawText(SX+32, SY+5*32,"Toons:",FS_BIG,FC_GREEN);
830   DrawText(SX+32, SY+6*32,"Buffered gfx:",FS_BIG,FC_GREEN);
831   DrawText(SX+32, SY+7*32,"Fading:",FS_BIG,FC_GREEN);
832   DrawText(SX+32, SY+8*32,"Quick Doors:",FS_BIG,FC_GREEN);
833   DrawText(SX+32, SY+9*32,"Auto-Record:",FS_BIG,FC_GREEN);
834   DrawText(SX+32, SY+10*32,"Joystick:",FS_BIG,FC_GREEN);
835   DrawText(SX+32, SY+11*32,"Cal. Joystick",FS_BIG,FC_GREEN);
836
837   DrawText(SX+32, SY+13*32,"Exit",FS_BIG,FC_GREEN);
838   DrawText(SX+32, SY+14*32,"Save and exit",FS_BIG,FC_GREEN);
839
840   if (SETUP_SOUND_ON(player.setup))
841     DrawText(SX+14*32, SY+2*32,"on",FS_BIG,FC_YELLOW);
842   else
843     DrawText(SX+14*32, SY+2*32,"off",FS_BIG,FC_BLUE);
844
845   if (SETUP_SOUND_LOOPS_ON(player.setup))
846     DrawText(SX+14*32, SY+3*32,"on",FS_BIG,FC_YELLOW);
847   else
848     DrawText(SX+14*32, SY+3*32,"off",FS_BIG,FC_BLUE);
849
850   if (SETUP_SOUND_MUSIC_ON(player.setup))
851     DrawText(SX+14*32, SY+4*32,"on",FS_BIG,FC_YELLOW);
852   else
853     DrawText(SX+14*32, SY+4*32,"off",FS_BIG,FC_BLUE);
854
855   if (SETUP_TOONS_ON(player.setup))
856     DrawText(SX+14*32, SY+5*32,"on",FS_BIG,FC_YELLOW);
857   else
858     DrawText(SX+14*32, SY+5*32,"off",FS_BIG,FC_BLUE);
859
860   if (!SETUP_DIRECT_DRAW_ON(player.setup))
861     DrawText(SX+14*32, SY+6*32,"on",FS_BIG,FC_YELLOW);
862   else
863     DrawText(SX+14*32, SY+6*32,"off",FS_BIG,FC_BLUE);
864
865   if (SETUP_FADING_ON(player.setup))
866     DrawText(SX+14*32, SY+7*32,"on",FS_BIG,FC_YELLOW);
867   else
868     DrawText(SX+14*32, SY+7*32,"off",FS_BIG,FC_BLUE);
869
870   if (SETUP_QUICK_DOORS_ON(player.setup))
871     DrawText(SX+14*32, SY+8*32,"on",FS_BIG,FC_YELLOW);
872   else
873     DrawText(SX+14*32, SY+8*32,"off",FS_BIG,FC_BLUE);
874
875   if (SETUP_RECORD_EACH_GAME_ON(player.setup))
876     DrawText(SX+14*32, SY+9*32,"on",FS_BIG,FC_YELLOW);
877   else
878     DrawText(SX+14*32, SY+9*32,"off",FS_BIG,FC_BLUE);
879
880   if (SETUP_2ND_JOYSTICK_ON(player.setup))
881     DrawText(SX+14*32, SY+10*32,"2nd",FS_BIG,FC_YELLOW);
882   else
883     DrawText(SX+14*32, SY+10*32,"1st",FS_BIG,FC_YELLOW);
884
885   for(i=2;i<15;i++)
886     if (i!=12)
887       DrawGraphic(0,i,GFX_KUGEL_BLAU);
888
889   FadeToFront();
890   InitAnimation();
891   HandleSetupScreen(0,0,0,0,MB_MENU_MARK);
892 }
893
894 void HandleSetupScreen(int mx, int my, int dx, int dy, int button)
895 {
896   static int choice = 3;
897   static int redraw = TRUE;
898   int x = (mx+32-SX)/32, y = (my+32-SY)/32;
899
900   if (redraw)
901   {
902     DrawGraphic(0,choice-1,GFX_KUGEL_ROT);
903     redraw = FALSE;
904   }
905
906   if (dx || dy)
907   {
908     if (dy)
909     {
910       x = 1;
911       y = choice+dy;
912     }
913     else
914       x = y = 0;
915
916     if (y==13)
917       y = (dy>0 ? 14 : 12);
918
919     if (y<3)
920       y = 3;
921     else if (y>15)
922       y = 15;
923   }
924
925   if (!mx && !my && !dx && !dy)
926   {
927     x = 1;
928     y = choice;
929   }
930
931   if (x==1 && y>=3 && y<=15 && y!=13)
932   {
933     if (button)
934     {
935       if (y!=choice)
936       {
937         DrawGraphic(0,y-1,GFX_KUGEL_ROT);
938         DrawGraphic(0,choice-1,GFX_KUGEL_BLAU);
939       }
940       choice = y;
941     }
942     else
943     {
944       int yy = y-1;
945
946       if (y==3 && sound_status==SOUND_AVAILABLE)
947       {
948         if (SETUP_SOUND_ON(player.setup))
949           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
950         else
951           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
952         player.setup ^= SETUP_SOUND;
953       }
954       else if (y==4 && sound_loops_allowed)
955       {
956         if (SETUP_SOUND_LOOPS_ON(player.setup))
957           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
958         else
959           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
960         player.setup ^= SETUP_SOUND_LOOPS;
961       }
962       else if (y==5 && sound_loops_allowed)
963       {
964         if (SETUP_SOUND_MUSIC_ON(player.setup))
965           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
966         else
967           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
968         player.setup ^= SETUP_SOUND_MUSIC;
969       }
970       else if (y==6)
971       {
972         if (SETUP_TOONS_ON(player.setup))
973           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
974         else
975           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
976         player.setup ^= SETUP_TOONS;
977       }
978       else if (y==7)
979       {
980         if (!SETUP_DIRECT_DRAW_ON(player.setup))
981           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
982         else
983           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
984         player.setup ^= SETUP_DIRECT_DRAW;
985       }
986       else if (y==8)
987       {
988         if (SETUP_FADING_ON(player.setup))
989           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
990         else
991           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
992         player.setup ^= SETUP_FADING;
993       }
994       else if (y==9)
995       {
996         if (SETUP_QUICK_DOORS_ON(player.setup))
997           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
998         else
999           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
1000         player.setup ^= SETUP_QUICK_DOORS;
1001       }
1002       else if (y==10)
1003       {
1004         if (SETUP_RECORD_EACH_GAME_ON(player.setup))
1005           DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
1006         else
1007           DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
1008         player.setup ^= SETUP_RECORD_EACH_GAME;
1009       }
1010       else if (y==11)
1011       {
1012         if (SETUP_2ND_JOYSTICK_ON(player.setup))
1013           DrawText(SX+14*32, SY+yy*32,"1st",FS_BIG,FC_YELLOW);
1014         else
1015           DrawText(SX+14*32, SY+yy*32,"2nd",FS_BIG,FC_YELLOW);
1016         player.setup ^= SETUP_2ND_JOYSTICK;
1017       }
1018       else if (y==12)
1019       {
1020         CalibrateJoystick();
1021         redraw = TRUE;
1022       }
1023       else if (y==14 || y==15)
1024       {
1025         if (y==15)
1026         {
1027           SavePlayerInfo(PLAYER_SETUP);
1028           SaveJoystickData();
1029         }
1030
1031         game_status = MAINMENU;
1032         DrawMainMenu();
1033         redraw = TRUE;
1034       }
1035     }
1036   }
1037   BackToFront();
1038
1039   if (game_status==SETUP)
1040     DoAnimation();
1041 }
1042
1043 void CalibrateJoystick()
1044 {
1045 #ifdef __FreeBSD__
1046   struct joystick joy_ctrl;
1047 #else
1048   struct joystick_control
1049   {
1050     int buttons;
1051     int x;
1052     int y;
1053   } joy_ctrl;
1054 #endif
1055
1056   int new_joystick_xleft, new_joystick_xright, new_joystick_xmiddle;
1057   int new_joystick_yupper, new_joystick_ylower, new_joystick_ymiddle;
1058
1059   if (joystick_status==JOYSTICK_OFF)
1060     goto error_out;
1061
1062   ClearWindow();
1063   DrawText(SX+16, SY+7*32, "MOVE JOYSTICK TO",FS_BIG,FC_YELLOW);
1064   DrawText(SX+16, SY+8*32, " THE UPPER LEFT ",FS_BIG,FC_YELLOW);
1065   DrawText(SX+16, SY+9*32, "AND PRESS BUTTON",FS_BIG,FC_YELLOW);
1066   BackToFront();
1067
1068 #ifdef __FreeBSD__
1069   joy_ctrl.b1 = joy_ctrl.b2 = 0;
1070 #else
1071   joy_ctrl.buttons = 0;
1072 #endif
1073   while(Joystick() & JOY_BUTTON);
1074 #ifdef __FreeBSD__
1075   while(!(joy_ctrl.b1||joy_ctrl.b2))
1076 #else
1077   while(!joy_ctrl.buttons)
1078 #endif
1079   {
1080     if (read(joystick_device, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
1081     {
1082       joystick_status=JOYSTICK_OFF;
1083       goto error_out;
1084     }
1085     Delay(10000);
1086   }
1087
1088   new_joystick_xleft = joy_ctrl.x;
1089   new_joystick_yupper = joy_ctrl.y;
1090
1091   ClearWindow();
1092   DrawText(SX+16, SY+7*32, "MOVE JOYSTICK TO",FS_BIG,FC_YELLOW);
1093   DrawText(SX+32, SY+8*32, "THE LOWER RIGHT",FS_BIG,FC_YELLOW);
1094   DrawText(SX+16, SY+9*32, "AND PRESS BUTTON",FS_BIG,FC_YELLOW);
1095   BackToFront();
1096
1097 #ifdef __FreeBSD__
1098   joy_ctrl.b1 = joy_ctrl.b2 = 0;
1099 #else
1100   joy_ctrl.buttons = 0;
1101 #endif
1102   while(Joystick() & JOY_BUTTON);
1103 #ifdef __FreeBSD__
1104   while(!(joy_ctrl.b1||joy_ctrl.b2))
1105 #else
1106   while(!joy_ctrl.buttons)
1107 #endif
1108   {
1109     if (read(joystick_device, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
1110     {
1111       joystick_status=JOYSTICK_OFF;
1112       goto error_out;
1113     }
1114     Delay(10000);
1115   }
1116
1117   new_joystick_xright = joy_ctrl.x;
1118   new_joystick_ylower = joy_ctrl.y;
1119
1120   ClearWindow();
1121   DrawText(SX+32, SY+16+7*32, "CENTER JOYSTICK",FS_BIG,FC_YELLOW);
1122   DrawText(SX+16, SY+16+8*32, "AND PRESS BUTTON",FS_BIG,FC_YELLOW);
1123   BackToFront();
1124
1125 #ifdef __FreeBSD__
1126   joy_ctrl.b1 = joy_ctrl.b2 = 0;
1127 #else
1128   joy_ctrl.buttons = 0;
1129 #endif
1130   while(Joystick() & JOY_BUTTON);
1131 #ifdef __FreeBSD__
1132   while(!(joy_ctrl.b1||joy_ctrl.b2))
1133 #else
1134   while(!joy_ctrl.buttons)
1135 #endif
1136   {
1137     if (read(joystick_device, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
1138     {
1139       joystick_status=JOYSTICK_OFF;
1140       goto error_out;
1141     }
1142     Delay(10000);
1143   }
1144
1145   new_joystick_xmiddle = joy_ctrl.x;
1146   new_joystick_ymiddle = joy_ctrl.y;
1147
1148   joystick[joystick_nr].xleft = new_joystick_xleft;
1149   joystick[joystick_nr].yupper = new_joystick_yupper;
1150   joystick[joystick_nr].xright = new_joystick_xright;
1151   joystick[joystick_nr].ylower = new_joystick_ylower;
1152   joystick[joystick_nr].xmiddle = new_joystick_xmiddle;
1153   joystick[joystick_nr].ymiddle = new_joystick_ymiddle;
1154
1155   CheckJoystickData();
1156
1157   DrawSetupScreen();
1158   while(Joystick() & JOY_BUTTON);
1159   return;
1160
1161   error_out:
1162
1163   ClearWindow();
1164   DrawText(SX+16, SY+16, "NO JOYSTICK",FS_BIG,FC_YELLOW);
1165   DrawText(SX+16, SY+48, " AVAILABLE ",FS_BIG,FC_YELLOW);
1166   Delay(3000000);
1167   DrawSetupScreen();
1168 }
1169
1170 void HandleVideoButtons(int mx, int my, int button)
1171 {
1172   if (game_status!=MAINMENU && game_status!=PLAYING)
1173     return;
1174
1175   switch(CheckVideoButtons(mx,my,button))
1176   {
1177     case BUTTON_VIDEO_EJECT:
1178       TapeStop();
1179       if (!TAPE_IS_EMPTY(tape))
1180         SaveLevelTape(tape.level_nr);
1181       else
1182         AreYouSure("Tape is empty !",AYS_CONFIRM);
1183       DrawCompleteVideoDisplay();
1184       break;
1185     case BUTTON_VIDEO_STOP:
1186       TapeStop();
1187       break;
1188     case BUTTON_VIDEO_PAUSE:
1189       TapeTogglePause();
1190       break;
1191     case BUTTON_VIDEO_REC:
1192       if (tape.pausing)
1193         TapeTogglePause();
1194       else if (game_status==MAINMENU)
1195         TapeInitRecording();
1196       break;
1197     case BUTTON_VIDEO_PLAY:
1198       if (tape.pausing)
1199         TapeTogglePause();
1200       else if (game_status==MAINMENU)
1201         TapeInitPlaying();
1202       break;
1203     default:
1204       break;
1205   }
1206 }
1207
1208 void HandleSoundButtons(int mx, int my, int button)
1209 {
1210   if (game_status!=PLAYING)
1211     return;
1212
1213   switch(CheckSoundButtons(mx,my,button))
1214   {
1215     case BUTTON_SOUND_MUSIC:
1216       if (sound_music_on)
1217       { 
1218         sound_music_on = FALSE;
1219         player.setup &= ~SETUP_SOUND_MUSIC;
1220         FadeSound(background_loop[level_nr % num_bg_loops]);
1221         DrawSoundDisplay(BUTTON_SOUND_MUSIC_OFF);
1222       }
1223       else if (sound_loops_allowed)
1224       { 
1225         sound_music_on = TRUE;
1226         player.setup |= SETUP_SOUND_MUSIC;
1227         PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
1228         DrawSoundDisplay(BUTTON_SOUND_MUSIC_ON);
1229       }
1230       else
1231         DrawSoundDisplay(BUTTON_SOUND_MUSIC_OFF);
1232       break;
1233     case BUTTON_SOUND_LOOPS:
1234       if (sound_loops_on)
1235       { 
1236         sound_loops_on = FALSE;
1237         player.setup &= ~SETUP_SOUND_LOOPS;
1238         DrawSoundDisplay(BUTTON_SOUND_LOOPS_OFF);
1239       }
1240       else if (sound_loops_allowed)
1241       { 
1242         sound_loops_on = TRUE;
1243         player.setup |= SETUP_SOUND_LOOPS;
1244         DrawSoundDisplay(BUTTON_SOUND_LOOPS_ON);
1245       }
1246       else
1247         DrawSoundDisplay(BUTTON_SOUND_LOOPS_OFF);
1248       break;
1249     case BUTTON_SOUND_SOUND:
1250       if (sound_on)
1251       { 
1252         sound_on = FALSE;
1253         player.setup &= ~SETUP_SOUND;
1254         DrawSoundDisplay(BUTTON_SOUND_SOUND_OFF);
1255       }
1256       else if (sound_status==SOUND_AVAILABLE)
1257       { 
1258         sound_on = TRUE;
1259         player.setup |= SETUP_SOUND;
1260         DrawSoundDisplay(BUTTON_SOUND_SOUND_ON);
1261       }
1262       else
1263         DrawSoundDisplay(BUTTON_SOUND_SOUND_OFF);
1264       break;
1265     default:
1266       break;
1267   }
1268 }
1269
1270 void HandleGameButtons(int mx, int my, int button)
1271 {
1272   if (game_status!=PLAYING)
1273     return;
1274
1275   switch(CheckGameButtons(mx,my,button))
1276   {
1277     case BUTTON_GAME_STOP:
1278       if (AreYouSure("Do you really want to quit the game ?",
1279                       AYS_ASK | AYS_STAY_CLOSED))
1280       { 
1281         game_status = MAINMENU;
1282         DrawMainMenu();
1283       }
1284       else
1285         OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1286       break;
1287     case BUTTON_GAME_PAUSE:
1288       if (tape.pausing)
1289       {
1290         tape.pausing = FALSE;
1291         DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
1292       }
1293       else
1294       {
1295         tape.pausing = TRUE;
1296         DrawVideoDisplay(VIDEO_STATE_PAUSE_ON,0);
1297       }
1298       break;
1299     case BUTTON_GAME_PLAY:
1300       if (tape.pausing)
1301       {
1302         tape.pausing = FALSE;
1303         DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
1304       }
1305       break;
1306     default:
1307       break;
1308   }
1309 }