1 /***************************************************************************
2 menu.c - description
3 -------------------
4 begin : Sat Jan 15 2000
5 copyright : (C) 2000 by Perdig
6 email : perdig@linuxbr.com.br
7
8 $Id: menu.c,v 1.23 2001/01/11 15:28:03 perdig Exp $
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20 #include "config.h"
21 #include "menu.h"
22 #include "graphics.h"
23 #include "effects.h"
24 #include "game.h"
25 #include "level.h"
26 #include "score.h"
27 #include "dirent.h"
28 #ifdef USE_SOUND
29 #include "sound.h"
30 #endif
31 #include "limits.h"
32 #include <stdio.h>
33 #include <string.h>
34
35 #define MENU_WINDOW_WIDTH (480 + 128)
36 #define MENU_WINDOW_HEIGHT (480)
37
38 //#include "images/logo.xpm"
39 //#include "images/logocar.xpm"
40 //
41 /* Menu screen geometry
42 * <---------- 614 --------->
43 * |-------------------------| /\
44 * ||-----| |------| | ||
45 * || | | | | ||
46 * ||menu | | | | ||
47 * ||-----| | help | |
48 * | | | | 482
49 * | |------| |
50 * | | ||
51 * | | ||
52 * | | ||
53 * | | ||
54 * | | ||
55 * | | \/
56 * ---------------------------
57 * menu_window -> x = 10
58 * y = 10
59 * w = max textwidth + 32 + 8 + 2
60 * h = (textheight+pad)*len + 8
61 *
62 * menu_text -> x = 10 + 4 + 32 + 2
63 * y = 10 + 4
64 * w = max textwidth
65 * h = max textheight
66 *
67 * help_window -> x = 614 - w - 10
68 * y = 10
69 * w = max textwidth + 8
70 * h = max textheight + 8
71 *
72 * help_text -> x = 614 - w - 10 + 4
73 * y = 10 + 4
74 * w = textwidth
75 * h = textheight
76 *
77 * cursor -> x = 10
78 * y = 10 + (textheight+pad)*(pos+0.5) - CAROFF
79 * w = 32
80 * h = 32
81 *
82 * Splash Screen geometry
83 *
84 * <---------- 614 --------->
85 * |-------------------------| /\
86 * ||------------| |-------|| ||
87 * || info win | | || ||
88 * ||------------| | level || ||
89 * | | ||
90 * | | desc || 482
91 * | | ||
92 * ||----------| | || ||
93 * || help win | | || ||
94 * ||----------| |-------|| ||
95 * | | ||
96 * ||---- progress bar ---|| ||
97 * | | \/
98 * ---------------------------
99 *
100 * progress bar: x = 10
101 * y = 482 - 10 - h
102 * h = 32
103 * w = 614 - 10 - 10
104 *
105 * level desc: x = 614 - w - 10
106 * y = 10
107 * w = textwidth + 8
108 * h = textheight + 8
109 *
110 * level desc text: x = 614 - w - 10 + 4
111 * y = 10 + 4
112 * w = textwidth
113 * h = textheight
114 *
115 * info win: x = 10
116 * y = 10
117 * w = textwidth + 8
118 * h = textheight + 8
119 *
120 * info win text: x = 10 + 4
121 * y = 10 + 4
122 * w = textwidth
123 * h = textheight
124 *
125 * help win: x = 10
126 * y = level desc y + level desc h - h
127 * w = textwidth + 8
128 * h = textheight + 8
129 *
130 * help win text: x = help win x + 4
131 * y = help win y + 4
132 * w = textwidth
133 * h = textheight
134 */
135
136 #define splText(TEXT) do { \
137 draw_window(40, 179, 365, 12 + text_height(FONT_BIG) + 12); \
138 text(dbuffer(), 52, 191, TEXT, get_color(COLOR_TEXT), FONT_BIG); } while (0)
139
140 #define splText2(TEXT) do { \
141 draw_window(95, 25 + 144 + 5 + 30, 430, 100); \
142 text(dbuffer(), 102, 239, TEXT, get_color(COLOR_TEXT), FONT_BIG); } while (0)
143
144 Pixmap logo;
145 Pixmap logocar[2];
146 Pixmap logocar_mask[2];
147 GC bufGC;
148 GC dbufGC;
149
150 // Score struct
151 extern scoreStruct score;
152
153 // Splash struct
154 struct splash_struct spl;
155
156 // Help and Info text
157 static char info[512];
158
159 static char game_help[] = "*Game control*\nArrow keys: Move the car around\nSpace bar: Use smoke\nEscape: Quit level";
160
161 static char menu_help[] = "*Menu control*\n\nArrow keys\n Move the cursor around\nEnter key\n Select an option\nESC key\n Return to previous screen\n";
162
163 // Size of sprite
164 extern int SPRITE_SIZE;
165 extern int TILE_WIDTH;
166 extern int TILE_HEIGHT;
167
168 // Blend cache
169 blend_cache_t blend_cache;
170
chooseLevel()171 char *chooseLevel() {
172 struct dirent **dirlist = NULL;
173 char **options = NULL;
174 char **info = NULL;
175 int levNum;
176 int n = 0, m = 0;
177
178 // Search the dir
179 n = scandir("./maps", &dirlist, 0, alphasort);
180 if (n <= 0) {
181 hdbg("Can't find the maps directory");
182 return NULL;
183 }
184 // Create the string list
185 // Allocate memory
186 options = (char **)calloc(n, sizeof(char *));
187 while (n--) {
188 if (*dirlist[n]->d_name != '.' && strcmp(dirlist[n]->d_name, "CVS") != 0) {
189 options[m] = dirlist[n]->d_name;
190 m++;
191 }
192 }
193
194 // Create the info list
195 info = (char **)calloc(m, sizeof(char *));
196 for (n = 0; n < m; n++) {
197 info[n] = levelDescription(options[n]);
198 }
199
200 levNum = create_menu(options, info, m);
201
202 for (n = 0; n < m; n++) {
203 free(info[n]);
204 }
205
206 if (levNum == 255)
207 return NULL;
208 else
209 return options[levNum];
210 }
211
chooseMap(int num)212 int chooseMap(int num) {
213 char **maps;
214 int a, len, cmd;
215 maps = (char **)calloc(num, sizeof(char *));
216 if (num < 10)
217 len = 1;
218 else if (num < 100)
219 len = 2;
220 else
221 len = 3;
222 for (a = 0; a < num; a++) {
223 maps[a] = (char *)malloc(sizeof(char) * len);
224 sprintf(maps[a], "%d", a+1);
225 }
226 cmd = create_menu(maps, NULL, num);
227 if (cmd == 255)
228 return -1;
229 else
230 return cmd;
231 }
232
endScreen(levelStruct * level,int oldscore,int mode)233 void endScreen(levelStruct *level, int oldscore, int mode) {
234 char msg[512];
235 int pos = -1;
236 char *name;
237 int x = (WINDOW_WIDTH - 134)/2 - 175;
238 int y = (WINDOW_HEIGHT - 2)/2 - 65;
239 XImage *clean_window;
240
241 // Victory message
242 if (mode == VICTORY) {
243 sprintf(msg, "Congratulations!\nYou won the %s!\n"
244 "Regular score: %9d\n"
245 "Winning bonus: %9d\n"
246 "Total: %9d",
247 level->name, oldscore, score.value-oldscore, score.value);
248 }
249
250 // Game over message
251 if (mode == GAME_OVER) {
252 sprintf(msg, "That's too bad! You lost!\n"
253 "Better luck next time!\n"
254 "Regular score: %9d\n"
255 "Winning bonus: %9d\n"
256 "Total: %9d",
257 oldscore, score.value-oldscore, score.value);
258 }
259
260 clean_window = get_image(dbuffer(), x, y, 350, 130);
261
262 // Draw window
263 draw_window( x, y, 350, 130);
264 // Draw text
265 text(dbuffer(), x+12, y+12, msg, get_color(COLOR_TEXT), FONT_FIXED);
266 graphics_sync();
267 wait_key();
268
269
270
271 // Now checks for the hiscore!
272 if (level->map && newRecord(level, &score)) {
273 ldbg("You got a new record!");
274 sound_select (16);
275 sound_volume (64);
276 sound_start ();
277 // Clean up
278 i_blit(clean_window, dbuffer(), x, y, 350, 130);
279 name = getName();
280 if (name != NULL && *name != 0)
281 pos = addRecord(level, &score, name);
282 }
283
284 // Puts the window backs to its original size
285 if (WINDOW_WIDTH != MENU_WINDOW_WIDTH || WINDOW_HEIGHT != MENU_WINDOW_HEIGHT) {
286 resize_window(MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT);
287 }
288
289 ldbg("Position: %d", pos);
290 displayHiscores(pos, level, false);
291 return;
292 }
293
getName()294 char *getName() {
295 int cmd = -1;
296 char temp[3];
297 char msg[256];
298 char *name = (char *)malloc(256 * sizeof(char));
299 int x = (WINDOW_WIDTH-134)/2 - 175;
300 int y = (WINDOW_HEIGHT-2)/2 - 65;
301 KeySym key;
302 XImage *window_img;
303 // If we don't do that, the window will get darker with
304 // every keystroke!
305 draw_window(x, y, 350, 130);
306 window_img = get_image(dbuffer(), x, y, 350, 130);
307 // Now window_img has a XImage of the window we want! How beautiful is that?
308 strcpy(name, "");
309 while (cmd < 0) {
310 strcpy(msg, "Congratulations!\nYou made into the hiscores!\nPlease enter your name:");
311 // Draw window
312 i_blit(window_img, dbuffer(), x, y, 350, 130);
313 text(dbuffer(), x+12, y+12, msg, get_color(COLOR_TEXT), FONT_FIXED);
314 text(dbuffer(), x+12, y+22+3*text_height(FONT_FIXED), name, get_color("#BB0000"), FONT_FIXED);
315 graphics_sync();
316 /* Get the player name */
317 key = wait_char(temp);
318 if (key == XK_Return)
319 break;
320 if (key == XK_Escape)
321 return NULL;
322 if (key == XK_Delete || key == XK_BackSpace) {
323 if (strlen(name) >= 1)
324 name[ strlen(name)-1 ] = 0;
325 continue;
326 }
327 if (temp)
328 strcat(name, temp);
329 }
330 return name;
331 }
332
initIntro()333 void initIntro() {
334 //cleanScr();
335 text(dbuffer(), MENU_WINDOW_WIDTH/2-50, MENU_WINDOW_HEIGHT/2, "Hold on...",
336 get_color(COLOR_WHITE), FONT_BIG);
337 graphics_sync();
338 load_pixmap(&logocar[0], &logocar_mask[0], "images/logocar.xpm",
339 NULL, NULL);
340 graphics_sync();
341 load_pixmap(&logocar[1], &logocar_mask[1], "images/logocar2.xpm",
342 NULL, NULL);
343 graphics_sync();
344 load_pixmap(&logo, 0, "images/xrally.xpm", NULL, NULL );
345 graphics_sync();
346 strcpy(info, "");
347 }
348
introAnim()349 void introAnim() {
350 s_blit(logo, dbuffer(), 0, 0, 614, 484);
351 wait_time(1000000); /* wait a few seconds so we can see the intro screen */
352 }
353
showLogo()354 void showLogo() {
355 //m_blit(logo, 0, dbuffer(), dbufGC, 604, 144, 5, 5);
356 //m_blit(logo, 0, dbuffer(), dbufGC, 614, 484, 0, 0);
357 blit(logo, dbuffer(), 0, 0, 614, 484);
358 }
359
360 #define CH (text_height(FONT_MEDIUM))
361 #define PADDING 4
362 #define CAROFF 18
draw_cursor(int pos)363 void draw_cursor(int pos) {
364 m_blit(logocar[0], logocar_mask[0], dbuffer(), 10 + 4 + 232*(pos/20), 14 + (CH+PADDING)*(2*(pos%20)+1)/2 - CAROFF, 32, 32);
365 }
366
cleanScr()367 void cleanScr() {
368 rect(dbuffer(), 0, 0, MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT, get_color(COLOR_BACK), 1);
369 }
370
get_user_option()371 int get_user_option() {
372 int cmd = -1;
373 char **options;
374 char **help_msg;
375 options = (char **)calloc(3, sizeof(char *));
376 options[0] = (char *)malloc(16 * sizeof(char));
377 options[1] = (char *)malloc(16 * sizeof(char));
378 options[2] = (char *)malloc(16 * sizeof(char));
379 help_msg = (char **)calloc(3, sizeof(char *));
380 help_msg[0] = menu_help;
381 help_msg[1] = menu_help;
382 help_msg[2] = menu_help;
383 strcpy(options[0], "New Game");
384 strcpy(options[1], "View Hiscores");
385 strcpy(options[2], "Exit");
386 cmd = create_menu(options, help_msg, 3);
387 if (cmd == 255)
388 return 2;
389 else
390 return cmd;
391 }
392
create_menu(char ** options,char ** info,int len)393 int create_menu(char **options, char **info, int len) {
394 int cmd = -1;
395 int currentOption = 0;
396 int cnt;
397 XColor color;
398 Pixmap menu_pixmap;
399 Pixmap help_pixmap;
400 XImage *help_image = NULL;
401 XImage *old_menu_image = NULL;
402 XImage *old_help_image = NULL;
403 int menu_x, menu_y, menu_w, menu_h;
404 int help_x, help_y, help_w, help_h, tmp_w, tmp_h;
405
406 /* Geometry */
407 // menu
408 menu_x = 10;
409 menu_y = 10;
410 menu_w = 0;
411 menu_h = 0;
412 for (cnt = 0; cnt < len; cnt++) {
413 text_rectangle(options[cnt], FONT_MEDIUM, &tmp_w, &tmp_h);
414 if (tmp_w > menu_w)
415 menu_w = tmp_w;
416 if (tmp_h > menu_h)
417 menu_h = tmp_h;
418 }
419 menu_w+=42 + (len/20)*(menu_w+PADDING);
420 menu_h = (menu_h+PADDING)*(len>20?20:len) + 8;
421 // help
422 help_w = 0;
423 help_h = 0;
424 for (cnt = 0; cnt < len; cnt++) {
425 if (info)
426 text_rectangle(info[cnt], FONT_MEDIUM, &tmp_w, &tmp_h);
427 else
428 tmp_w = tmp_h = 0;
429 if (tmp_w > help_w)
430 help_w = tmp_w;
431 if (tmp_h > help_h)
432 help_h = tmp_h;
433 }
434 help_w+=8;
435 help_h+=8;
436 help_x = MENU_WINDOW_WIDTH - help_w - 10;
437 help_y = 10;
438
439 color.red = color.blue = color.green = 0;
440 /* Creates the menu pixmap */
441 menu_pixmap = create_pixmap(menu_w, menu_h);
442 /* Background -> shaded image */
443 i_blit( blend_image(logo, menu_x, menu_y, menu_w, menu_h, &blend_cache),
444 menu_pixmap, 0, 0, menu_w, menu_h);
445 /* Text -> options list */
446 for (cnt = 0; cnt < len; cnt++) {
447 text(menu_pixmap, 32 + 4 + 2, 4 + (text_height(FONT_MEDIUM)+PADDING)*cnt, options[cnt], get_color(COLOR_TEXT), FONT_MEDIUM);
448 }
449 /* Creates the help pixmap */
450 help_pixmap = create_pixmap(help_w, help_h);
451 /* Background -> shaded image */
452 help_image = blend_image(logo, help_x , help_y, help_w, help_h, &blend_cache);
453 i_blit( help_image, help_pixmap, 0, 0, help_w, help_h);
454 /* Text -> infoText */
455 if (info)
456 text(help_pixmap, 4, 4, info[currentOption], get_color(COLOR_TEXT), FONT_MEDIUM);
457
458 old_menu_image = get_image(logo, menu_x, menu_y, menu_w, menu_h);
459 old_help_image = get_image(logo, help_x , help_y, help_w, help_h);
460
461 s_blit(menu_pixmap, dbuffer(), menu_x, menu_y, menu_w, menu_h);
462 s_blit(help_pixmap, dbuffer(), help_x, help_y, help_w, help_h);
463 // Main loop
464 while (cmd < 0) {
465 cleanScr();
466 showLogo();
467 i_blit( help_image, help_pixmap, 0, 0, help_w, help_h);
468 if (info)
469 text(help_pixmap, 4, 4, info[currentOption], get_color(COLOR_TEXT), FONT_MEDIUM);
470 blit(menu_pixmap, dbuffer(), menu_x, menu_y, menu_w, menu_h);
471 blit(help_pixmap, dbuffer(), help_x, help_y, help_w, help_h);
472 draw_cursor(currentOption);
473 //optionList(menu_pixmap, options, len);
474 graphics_sync();
475 if (!userOption(¤tOption)) {
476 cmd = currentOption;
477 }
478 currentOption = (currentOption < 0) ? 0 : currentOption;
479 currentOption = (currentOption > (len-1)) ? (len-1) : currentOption;
480 }
481 ldbg("Cmd: %d", cmd);
482 usi_blit(old_menu_image, dbuffer(), menu_x, menu_y, menu_w, menu_h);
483 usi_blit(old_help_image, dbuffer(), help_x, help_y, help_w, help_h);
484 return cmd;
485 }
486
displayHiscores(int mark,levelStruct * level,bool loadAgain)487 void displayHiscores(int mark, levelStruct *level, bool loadAgain) {
488 char *levelFile = NULL;
489 char **lines;
490 int num, a;
491 int cmd = -1;
492 int limit = 10;
493 char pos[9] = "";
494 int offset = 0;
495 struct splash_struct splScr;
496 XImage *blend_hiscores;
497 XImage *old_blend_hiscores;
498 if (loadAgain) {
499 levelFile = chooseLevel();
500 if (levelFile == NULL)
501 return;
502 sprintf(splScr.txt, "Loading hiscores for %s", levelFile);
503 splScr.n = 9;
504 splScr.mode = 2;
505 splash(splScr, levelFile);
506 if (!levelFile)
507 return;
508 if (!quickLoadLevel(level, levelFile)) {
509 hdbg("Can't load level!");
510 return;
511 }
512 }
513 lines = listRecords(level);
514 if (!lines) {
515 ldbg("No record with that name!");
516 num = 0;
517 } else {
518 num = (int)*lines[0];
519 }
520 if (num == 0) {
521 ldbg("No record with that name!");
522 }
523 lines++;
524 limit = (num < 10) ? num : 10;
525 blend_hiscores = blend_image(logo, 5 - 3, 179 - 3, 600,
526 (limit != 0 ? limit * 30 : 30), &blend_cache);
527 old_blend_hiscores = get_image(logo, 5 - 3, 179 - 3, 600,
528 (limit != 0 ? limit * 30 : 30));
529 cleanScr();
530 showLogo();
531 graphics_sync();
532 si_blit(blend_hiscores, dbuffer(), 5 - 3, 179 - 3, 600, (limit != 0 ? limit * 30 : 30));
533 while (cmd < 0) {
534 cleanScr();
535 showLogo();
536 i_blit(blend_hiscores, dbuffer(), 5 - 3, 179 - 3, 600, (limit != 0 ? limit * 30 : 30));
537 for (a = 0; a < limit; a++) {
538 sprintf(pos, "%2d-", a+offset+1);
539 if ((a+offset) != mark) {
540 text(dbuffer(), 57, 179+30*(a%10), lines[a+offset], get_color(COLOR_TEXT), FONT_MEDIUM);
541 text(dbuffer(), 5, 179+30*(a%10), pos, get_color(COLOR_TEXT), FONT_MEDIUM);
542 }
543 else {
544 text(dbuffer(), 57, 179+30*(a%10), lines[a+offset], get_color("#BB0000"), FONT_MEDIUM);
545 text(dbuffer(), 5, 179+30*(a%10), pos, get_color("#BB0000"), FONT_MEDIUM);
546 }
547 }
548 if (num == 0) {
549 text(dbuffer(), 5, 179, "This level doesn't have any Hiscore", get_color(COLOR_TEXT), FONT_MEDIUM);
550 }
551
552 graphics_sync();
553 if (!userOption(&offset)) {
554 usi_blit(old_blend_hiscores, dbuffer(), 5 - 3, 179 - 3, 600, (limit != 0 ? limit * 30 : 30));
555 return;
556 }
557 offset = (offset > (num-10)) ? num - 10 : offset;
558 offset = (offset < 0) ? 0 : offset;
559 }
560 usi_blit(old_blend_hiscores, dbuffer(), 5 - 3, 179 - 3, 600, (limit != 0 ? limit * 30 : 30));
561 return;
562 }
563
userOption(int * cmd)564 bool userOption(int *cmd) {
565 KeySym key;
566 int a;
567 a = *cmd;
568 while (a == *cmd) {
569 key = wait_key();
570 switch(key) {
571 case(XK_KP_8):
572 case(XK_Up):
573 case(XK_KP_Up):
574 *cmd-=1;
575 return true;
576 break;
577 case(XK_KP_4):
578 case(XK_Left):
579 case(XK_KP_Left):
580 *cmd-=10;
581 return true;
582 break;
583 case(XK_KP_2):
584 case(XK_Down):
585 case(XK_KP_Down):
586 *cmd+=1;
587 return true;
588 break;
589 case(XK_KP_6):
590 case(XK_Right):
591 case(XK_KP_Right):
592 *cmd+=10;
593 return true;
594 break;
595 case(XK_KP_Enter):
596 case(XK_Return):
597 return false;
598 break;
599 case(XK_Escape):
600 case 'Q':
601 case 'q':
602 *cmd=255;
603 return false;
604 default:
605 break;
606 }
607 }
608
609 return true;
610 }
611
splash(struct splash_struct spl_arg,char * filename)612 void splash(struct splash_struct spl_arg, char *filename) {
613 strncpy(spl.txt, spl_arg.txt, 256);
614 spl.info = levelDescription(filename);
615 spl.n = spl_arg.n;
616 spl.mode = spl_arg.mode;
617 spl.cur = 0;
618 update_splash();
619 }
620
update_splash_hiscore()621 void update_splash_hiscore() {
622 splText2(spl.txt);
623 rect(dbuffer(), 3, 387, 608, 36, get_color("#AA6800"), 1);
624 rect(dbuffer(), 5, 389, (572*spl.cur)/spl.n, 32, get_color("#86A886"), 1);
625 m_blit(logocar[0], logocar_mask[0], dbuffer(), 5 + (572*spl.cur)/spl.n, 389, 32, 32);
626 }
627
update_splash()628 void update_splash() {
629 XImage *blend_info;
630 XImage *blend_help;
631 XImage *blend_desc;
632 int info_x, info_y, info_w, info_h;
633 int help_x, help_y, help_w, help_h;
634 int desc_x, desc_y, desc_w, desc_h;
635 cleanScr();
636 showLogo();
637 if (spl.mode == 2) {
638 update_splash_hiscore();
639 } else {
640 // Info window
641 info_x = 10;
642 text_rectangle(spl.txt, FONT_BIG, &info_w, &info_h);
643 info_w+=8;
644 info_h+=8;
645 info_y = 10;
646 // Desc window
647 desc_y = 10;
648 text_rectangle(spl.info, FONT_MEDIUM, &desc_w, &desc_h);
649 desc_w+=8;
650 desc_h+=8;
651 desc_x = 614 - desc_w - 10;
652 // Help window
653 help_x = 10;
654 text_rectangle(game_help, FONT_MEDIUM, &help_w, &help_h);
655 help_w+=8;
656 help_h+=8;
657 help_y = desc_y + desc_h - help_h;
658 // Get windows
659 blend_info = blend_image(logo, info_x, info_y, info_w, info_h, &blend_cache);
660 blend_help = blend_image(logo, help_x, help_y, help_w, help_h, &blend_cache);
661 blend_desc = blend_image(logo, desc_x, desc_y, desc_w, desc_h, &blend_cache);
662 // Draw windows
663 i_blit(blend_info, dbuffer(), info_x, info_y, info_w, info_h);
664 i_blit(blend_help, dbuffer(), help_x, help_y, help_w, help_h);
665 i_blit(blend_desc, dbuffer(), desc_x, desc_y, desc_w, desc_h);
666 // Draw texts
667 text(dbuffer(), info_x + 4, info_y + 4, spl.txt, get_color(COLOR_TEXT), FONT_BIG);
668 text(dbuffer(), help_x + 4, help_y + 4, game_help, get_color(COLOR_TEXT), FONT_MEDIUM);
669 text(dbuffer(), desc_x + 4, desc_y + 4, spl.info, get_color(COLOR_TEXT), FONT_MEDIUM);
670 // Lower sound
671 #ifdef USE_SOUND
672 sound_changevol (-4);
673 #endif
674 // Draw progress bar
675 rect(dbuffer(), 10, 482 - 10 - 32, 614 - 10 - 10, 32, get_color("#AA6800"), 1);
676 rect(dbuffer(), 10, 482 - 10 - 32, ((614 - 10 - 10)*spl.cur)/spl.n, 32, get_color(COLOR_GREEN), 1);
677 m_blit(logocar[0], logocar_mask[0], dbuffer(), 10 + ((614-10-10)*spl.cur)/spl.n, 482-10-32, 32, 32);
678 }
679 graphics_sync();
680 spl.cur++;
681 if (spl.cur > spl.n)
682 spl.cur = spl.n;
683 }
684
levelDescription(char * level)685 char *levelDescription(char *level) {
686 char *desc;
687 char livStr[16] = "";
688 char bonStr[64] = "";
689 levelStruct lev;
690 desc = (char *)malloc(512 * sizeof(char));
691 quickLoadLevel(&lev, level);
692 if (lev.lives < 0) {
693 sprintf(livStr, "No Lives!");
694 }
695 else if (lev.lives == 1) {
696 sprintf(livStr, "1 live");
697 }
698 else {
699 sprintf(livStr, "%d lives", lev.lives);
700 }
701
702 if (lev.livesbonus < 0 && lev.lives >= 0) {
703 sprintf(bonStr, "%d pts / lives\nbeyond %d at\nend of level", -lev.livesbonus, lev.lives);
704 }
705 else if (lev.livesbonus >= 0) {
706 sprintf(bonStr, "%d pts / live at\nend of level", lev.livesbonus);
707 }
708
709 sprintf(desc, "**%s**\n\nTileset: %s\n%d map%c\n%s\n%d pts / extra live\n%s\n\n*First map:*\nPlayer speed: %d\nEnemy speed: %d\n", lev.name, lev.tileset, lev.number, (lev.number>1)?'s':' ', livStr, lev.extra, bonStr, lev.map[0].carVel, lev.map[0].aiVel);
710
711 return desc;
712 }
713