home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 123 / cdrom123.iso / edu / tux / Tuxtype2-1.5.3-installer.exe / src / titlescreen.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-03-25  |  26.3 KB  |  941 lines

  1. /***************************************************************************
  2.  -  file: titlescreen.c
  3.  -  description: splash, title and menu screen functionality 
  4.                             ------------------
  5.     begin                : Thur May 4 2000
  6.     copyright            : (C) 2000 by Sam Hart
  7.                          : (C) 2003 by Jesse Andrews
  8.     email                : tuxtype-dev@tux4kids.net
  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 "globals.h"
  21. #include "funcs.h"
  22. #include "titlescreen.h"
  23.  
  24. /* --- media for menus --- */
  25. SDL_Surface *reg_text[TITLE_MENU_ITEMS + 1][TITLE_MENU_DEPTH + 1];
  26. SDL_Surface *sel_text[TITLE_MENU_ITEMS + 1][TITLE_MENU_DEPTH + 1];
  27. sprite *reg;
  28. sprite *sel;
  29. sprite *menu_gfx[TITLE_MENU_ITEMS + 1][TITLE_MENU_DEPTH + 1];
  30. int     menu_width[TITLE_MENU_DEPTH + 1];
  31.  
  32. int menu_depth; // how deep we are in the menu
  33.  
  34. /* --- other media --- */
  35. SDL_Surface *title;
  36. sprite *Tux;
  37. Mix_Chunk *snd_move, *snd_select;
  38.  
  39. /* --- locations we need --- */
  40. SDL_Rect text_dst[TITLE_MENU_ITEMS + 1];     // location of text for menu
  41. SDL_Rect menu_gfxdest[TITLE_MENU_ITEMS + 1]; // location of animated icon
  42. SDL_Rect menu_button[TITLE_MENU_ITEMS + 1];  // size of "button"
  43.  
  44. int chooseWordlist( void );
  45.  
  46. void draw_button( int id, sprite *s ) {
  47.     SDL_Rect button;
  48.  
  49.     button.x = menu_button[id].x;
  50.     button.y = menu_button[id].y;
  51.     button.w = s->frame[0]->w;
  52.     button.h = s->frame[0]->h;
  53.     SDL_BlitSurface(s->frame[0], NULL, screen, &button);
  54.     button.w = s->frame[1]->w;
  55.     for (button.x += s->frame[0]->w; button.x < (menu_button[id].x + menu_width[menu_depth]); button.x += s->frame[1]->w) 
  56.         SDL_BlitSurface(s->frame[1], NULL, screen, &button);
  57.     button.w = s->frame[2]->w;
  58.     SDL_BlitSurface(s->frame[2], NULL, screen, &button);
  59. }
  60.  
  61. void TitleScreen_load_menu( void ) {
  62.     unsigned char fn[FNLEN];
  63.     int max, i, j;
  64.  
  65.     SDL_ShowCursor(1);
  66.  
  67.     LOG("loading & parsing menu\n");
  68.     
  69.     for (j = 1; j <= TITLE_MENU_DEPTH; j++) {
  70.         max = 0;
  71.         for (i = 1; i <= TITLE_MENU_ITEMS; i++) {
  72.  
  73.             /* --- create text surfaces --- */
  74.  
  75.             reg_text[i][j] = black_outline( _((unsigned char*)menu_text[i][j]), font, &white);
  76.             sel_text[i][j] = black_outline( _((unsigned char*)menu_text[i][j]), font, &yellow);
  77.  
  78.             if (sel_text[i][j]->w > max)
  79.                 max = sel_text[i][j]->w;
  80.  
  81.             /* --- load animated icon for menu item --- */
  82.  
  83.             sprintf(fn, "menu/%s", menu_icon[i][j]);
  84.             menu_gfx[i][j] = LoadSprite(fn, IMG_ALPHA);
  85.         }
  86.         menu_width[j] = max + 20 + 40;
  87.     }
  88.  
  89.     LOG("done creating graphics, now setting positions\n");
  90.  
  91.     /* --- setup menu item destinations --- */
  92.  
  93.     menu_button[1].x = 240;
  94.     menu_button[1].w = menu_width[1];
  95.     menu_button[1].y = 100;
  96.     menu_button[1].h = sel->frame[1]->h;
  97.  
  98.     menu_gfxdest[1].x = 246;
  99.     menu_gfxdest[1].y = menu_button[1].y + 4;
  100.     menu_gfxdest[1].w = 40;
  101.     menu_gfxdest[1].h = 50;
  102.  
  103.     text_dst[1].y = menu_button[1].y+15;
  104.  
  105.     for (j=2; j<6; j++) {
  106.         /* --- setup vertical location of button text --- */
  107.         text_dst[j].y = text_dst[j-1].y + 60;
  108.  
  109.         /* --- setup location of animated icon --- */
  110.         menu_gfxdest[j].x = menu_gfxdest[j-1].x;
  111.         menu_gfxdest[j].y = menu_gfxdest[j-1].y+60;
  112.         menu_gfxdest[j].w = menu_gfxdest[j-1].w;
  113.         menu_gfxdest[j].h = menu_gfxdest[j-1].h;
  114.  
  115.         /* --- setup location of button bkg --- */
  116.         menu_button[j].x = 240;
  117.         menu_button[j].y = menu_button[j-1].y + 60;
  118.         menu_button[j].w = menu_width[1];
  119.         menu_button[j].h = sel->frame[1]->h;
  120.     }
  121. }
  122.  
  123. void TitleScreen_unload_menu( void ) {
  124.     int i,j;
  125.  
  126.     for (i = 1; i <= TITLE_MENU_ITEMS; i++)
  127.         for (j = 1; j <= TITLE_MENU_DEPTH; j++) {
  128.             SDL_FreeSurface(reg_text[i][j]);
  129.             SDL_FreeSurface(sel_text[i][j]);
  130.             FreeSprite(menu_gfx[i][j]);
  131.     }
  132. }
  133.  
  134. void TitleScreen_load_media( void ) {
  135.  
  136.     /* --- load sounds --- */
  137.  
  138.     snd_move = LoadSound("tock.wav");
  139.     snd_select = LoadSound("pop.wav");
  140.  
  141.     /* --- load graphics --- */
  142.  
  143.     title = LoadImage( "title1.png", IMG_ALPHA );
  144.     bkg = LoadImage( "main_bkg.png", IMG_REGULAR );
  145.  
  146.     sel = LoadSprite("menu/sel", IMG_ALPHA);
  147.     reg = LoadSprite("menu/reg", IMG_ALPHA);
  148.  
  149.     Tux = LoadSprite("tux", IMG_ALPHA);
  150.  
  151.     font = LoadFont( menu_font, menu_font_size );
  152.     TitleScreen_load_menu();
  153. }
  154.  
  155. void TitleScreen_unload_media( void ) {
  156.  
  157.     /* --- unload sounds --- */
  158.  
  159.     Mix_FreeChunk(snd_move);
  160.     Mix_FreeChunk(snd_select);
  161.  
  162.     /* --- unload graphics --- */
  163.  
  164.     SDL_FreeSurface(title);
  165.     SDL_FreeSurface(bkg);
  166.  
  167.     FreeSprite(sel);
  168.     FreeSprite(reg);
  169.  
  170.     FreeSprite(Tux);
  171.  
  172.     TTF_CloseFont(font);
  173.     TitleScreen_unload_menu();
  174. }
  175.  
  176. void NotImplimented(void) {
  177.     SDL_Surface *s1, *s2, *s3, *s4;
  178.     sprite *tux;
  179.     SDL_Rect loc;
  180.     int finished=0,i;
  181.  
  182.         LOG( "NotImplimented() - creating text\n" );
  183.  
  184.     s1 = black_outline( _("Work In Progress!"), font, &white);
  185.     s2 = black_outline( _("This feature is not ready yet"), font, &white);
  186.     s3 = black_outline( _("Discuss the future of TuxTyping at"), font, &white);
  187.  
  188.     /* we always want the URL in english */
  189.     if (!useEnglish) {
  190.         TTF_Font *english_font;
  191.         useEnglish = 1;
  192.         english_font = LoadFont( menu_font, menu_font_size );
  193.         s4 = black_outline( "http://tuxtype.sf.net/forums", english_font, &white);
  194.         TTF_CloseFont(english_font);
  195.         useEnglish = 0;
  196.     } else 
  197.         s4 = black_outline( "http://tuxtype.sf.net/forums", font, &white);
  198.  
  199.         LOG( "NotImplimented() - drawing screen\n" );
  200.  
  201.     SDL_BlitSurface( bkg, NULL, screen, NULL );
  202.     loc.x = 320-(s1->w/2); loc.y = 10;
  203.     SDL_BlitSurface( s1, NULL, screen, &loc);
  204.     loc.x = 320-(s2->w/2); loc.y = 60;
  205.     SDL_BlitSurface( s2, NULL, screen, &loc);
  206.     loc.x = 320-(s3->w/2); loc.y = 400;
  207.     SDL_BlitSurface( s3, NULL, screen, &loc);
  208.     loc.x = 320-(s4->w/2); loc.y = 440;
  209.     SDL_BlitSurface( s4, NULL, screen, &loc);
  210.  
  211.     tux = LoadSprite("tux/tux-egypt", IMG_ALPHA);
  212.  
  213.     loc.x = 320-(tux->frame[0]->w/2);
  214.     loc.y = 200;
  215.     loc.w = tux->frame[0]->w;
  216.     loc.h = tux->frame[0]->h;
  217.     SDL_BlitSurface( tux->frame[tux->cur], NULL, screen, &loc);
  218.  
  219.     SDL_UpdateRect(screen, 0, 0, 0, 0);
  220.  
  221.     i=0;
  222.     while (!finished) {
  223.         while (SDL_PollEvent(&event)) 
  224.             switch (event.type) {
  225.                 case SDL_QUIT:
  226.                     exit(0);
  227.                 case SDL_MOUSEBUTTONDOWN:
  228.                 case SDL_KEYDOWN:
  229.                     finished=1;
  230.             }
  231.         i++;
  232.         if (i%5==0) {
  233.             next_frame(tux);
  234.             SDL_BlitSurface( bkg, &loc, screen, &loc);
  235.             SDL_BlitSurface( tux->frame[tux->cur], NULL, screen, &loc);
  236.             SDL_UpdateRect(screen, loc.x, loc.y, loc.w, loc.h);
  237.         }
  238.  
  239.             
  240.         SDL_Delay(40);
  241.     }
  242.  
  243.     SDL_FreeSurface(s1);
  244.     SDL_FreeSurface(s2);
  245.     SDL_FreeSurface(s3);
  246.     SDL_FreeSurface(s4);
  247.     FreeSprite(tux);
  248. }
  249.  
  250. /****************************************
  251. * TitleScreen: Display the title screen *
  252. *****************************************
  253. * display title screen, get input
  254. */
  255. void TitleScreen( void ) {
  256.  
  257.     SDL_Rect dest;
  258.     SDL_Rect Tuxdest, Titledest, cursor;
  259.  
  260.     Uint32 frame = 0;
  261.     int i, j, tux_frame = 0;
  262.     int done = 0;
  263.     int menu_opt = NONE;
  264.     int sub_menu = NONE;
  265.     int update_locs = 1;
  266.     int redraw = 0;
  267.     int key_menu = 1;
  268.     int old_key_menu = 5;
  269.     Uint32 start = 0;
  270.  
  271.     /*
  272.      * StandbyScreen: Display the Standby screen.... 
  273.      */
  274.  
  275.     start = SDL_GetTicks();
  276.  
  277.     if (show_tux4kids) {
  278.         SDL_Surface *standby;
  279.  
  280.         standby = LoadImage("standby.png", IMG_REGULAR|IMG_NO_THEME);
  281.  
  282.         dest.x = ((screen->w) / 2) - (standby->w) / 2;
  283.         dest.y = ((screen->h) / 2) - (standby->h) / 2;
  284.         dest.w = standby->w;
  285.         dest.h = standby->h;
  286.  
  287.         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
  288.         SDL_BlitSurface(standby, NULL, screen, &dest);
  289.         SDL_UpdateRect(screen, 0, 0, 0, 0);
  290.         SDL_FreeSurface(standby);
  291.     }
  292.  
  293.     TitleScreen_load_media();
  294.     SDL_WM_GrabInput(SDL_GRAB_ON);
  295.  
  296.     /***************************
  297.     * Tux and Title animations *
  298.     ***************************/
  299.  
  300.     LOG( "->Now Animatiting Tux and Title on to the screen\n" );
  301.  
  302.     Tuxdest.x = 0;
  303.     Tuxdest.y = screen->h;
  304.     Tuxdest.w = Tux->frame[0]->w;
  305.     Tuxdest.h = Tux->frame[0]->h;
  306.  
  307.     Titledest.x = screen->w;
  308.     Titledest.y = 10;
  309.     Titledest.w = title->w;
  310.     Titledest.h = title->h;
  311.  
  312.     /* --- wait if the first time in the game --- */
  313.  
  314.     if (show_tux4kids) {
  315.         while (SDL_GetTicks()-start < 2000) 
  316.             SDL_Delay(50);
  317.         show_tux4kids = 0;
  318.     }
  319.  
  320.     SDL_ShowCursor(1);    
  321.     TransWipe(bkg, RANDOM_WIPE, 10, 20);
  322.  
  323.     /* --- Pull tux & logo onscreen --- */
  324.  
  325.     for (i = 0; i < (PRE_ANIM_FRAMES * PRE_FRAME_MULT); i++) {
  326.         start = SDL_GetTicks();
  327.         SDL_BlitSurface(bkg, &Tuxdest, screen, &Tuxdest);
  328.         SDL_BlitSurface(bkg, &Titledest, screen, &Titledest);
  329.  
  330.         Tuxdest.y -= Tux->frame[0]->h / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
  331.         Titledest.x -= (screen->w) / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
  332.  
  333.         SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
  334.         SDL_BlitSurface(title, NULL, screen, &Titledest);
  335.  
  336.         SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
  337.         SDL_UpdateRect(screen, Titledest.x, Titledest.y, Titledest.w+40, Titledest.h);
  338.  
  339.         while ((SDL_GetTicks() - start) < 33) 
  340.             SDL_Delay(2);
  341.     }
  342.  
  343.     SDL_BlitSurface(title, NULL, screen, &Titledest);
  344.  
  345.     LOG( "Tux and Title are in place now\n" );
  346.  
  347.     cursor.x = menu_button[1].x + (menu_button[1].w / 2);
  348.     cursor.y = menu_button[1].y + (3 * menu_button[1].h / 4);
  349.  
  350.     SDL_WarpMouse(cursor.x, cursor.y);
  351.     SDL_WM_GrabInput(SDL_GRAB_OFF);
  352.  
  353.     audioMusicLoad( "tuxi.ogg", -1 );
  354.  
  355.     /****************************
  356.     * Main Loop Starts Here ... *
  357.     ****************************/
  358.  
  359.     menu_depth = 1;
  360.     Tuxdest.y = screen->h - Tux->frame[0]->h;
  361.  
  362.     while (!done) {
  363.  
  364.         start=SDL_GetTicks();
  365.  
  366.         /* ---process input queue --- */
  367.  
  368.         menu_opt = NONE; // clear the option so we don't change twice!
  369.  
  370.         old_key_menu = key_menu;
  371.  
  372.         while (SDL_PollEvent(&event)) {
  373.             switch (event.type) {
  374.                 case SDL_MOUSEMOTION:
  375.                     cursor.x = event.motion.x;
  376.                     cursor.y = event.motion.y;
  377.                     break;
  378.                 
  379.                 case SDL_MOUSEBUTTONDOWN:
  380.                     cursor.x = event.motion.x;
  381.                     cursor.y = event.motion.y;
  382.                     for (j = 1; j <= TITLE_MENU_ITEMS; j++) 
  383.                         if ((cursor.x >= menu_button[j].x && cursor.x <= (menu_button[j].x + menu_button[j].w)) && 
  384.                             (cursor.y >= menu_button[j].y && cursor.y <= (menu_button[j].y + menu_button[j].h))) {
  385.                             menu_opt = menu_item[j][menu_depth];
  386.                             playsound(snd_select);
  387.                             DEBUGCODE {
  388.                                 fprintf(stderr, "->>BUTTON CLICK menu_opt = %d\n", menu_opt);
  389.                                 fprintf(stderr, "->J = %d menu_depth=%d\n", j, menu_depth);
  390.                             }
  391.                         }
  392.                     break;
  393.                 
  394.                 case SDL_QUIT:
  395.                     menu_opt = QUIT_GAME;
  396.                     break;
  397.                 
  398.                 case SDL_KEYDOWN:
  399.                     switch (event.key.keysym.sym) {
  400.                         case SDLK_ESCAPE:
  401.                             playsound(snd_select);
  402.                             if (menu_depth != 1) 
  403.                                 menu_opt = MAIN;
  404.                             else
  405.                                 menu_opt = QUIT_GAME;
  406.                             break;
  407.                         case SDLK_F10:
  408.                             switch_screen_mode();
  409.                             redraw=1;
  410.                             break;
  411.                         case SDLK_F11:
  412.                             SDL_SaveBMP( screen, "screenshot.bmp" );
  413.                             break;
  414.                         case SDLK_F12:
  415.                             /* --- reload translation/graphics/media: for themers/translaters --- */
  416.                             TitleScreen_unload_media();
  417.                             LoadLang();
  418.                             TitleScreen_load_media();
  419.                             redraw = 1;
  420.                             break;
  421.                         case SDLK_UP:
  422.                             playsound(snd_move);
  423.                             key_menu--;
  424.                             if (key_menu < 1)
  425.                                 key_menu = 5;
  426.                             break;
  427.                         case SDLK_DOWN:
  428.                             key_menu++;
  429.                             playsound(snd_move);
  430.                             if (key_menu > 5)
  431.                                 key_menu = 1;
  432.                             break;
  433.                         case SDLK_RETURN:
  434.                             if (key_menu) {
  435.                                 menu_opt = menu_item[key_menu][menu_depth];
  436.                                 playsound(snd_select);
  437.                                 break;
  438.                             }
  439.                         default:
  440.                             break;
  441.                     }
  442.                     break;
  443.             }
  444.         }
  445.  
  446.  
  447.         /* --- warp mouse to follow keyboard input --- */
  448.  
  449.         if (old_key_menu != key_menu) {
  450.             cursor.x = menu_button[key_menu].x + (menu_button[key_menu].w / 2);
  451.             cursor.y = menu_button[key_menu].y + (3 * menu_button[key_menu].h / 4);
  452.             SDL_WarpMouse(cursor.x, cursor.y);
  453.         }
  454.  
  455.         /* --- do menu processing --- */
  456.  
  457.         if (menu_opt == QUIT_GAME)
  458.             done = 1;
  459.  
  460.         if (menu_opt == LASER) {
  461.             menu_depth = LASER_SUBMENU;
  462.             sub_menu = LASER;
  463.             update_locs = 1;
  464.         }
  465.  
  466.         if (menu_opt == CASCADE) {
  467.             menu_depth = CASCADE_SUBMENU;
  468.             sub_menu = CASCADE;
  469.             update_locs = 1;
  470.         }
  471.  
  472.         if (menu_opt == OPTIONS) {
  473.             menu_depth = OPTIONS_SUBMENU;
  474.             sub_menu = OPTIONS;
  475.             update_locs = 1;
  476.         }
  477.  
  478.         if (menu_opt == MAIN) {
  479.             menu_depth = ROOTMENU;
  480.             update_locs = 1;
  481.         }
  482.  
  483.         if (menu_opt == NOT_CODED) {
  484.             NotImplimented();
  485.             redraw=1;
  486.         }
  487.  
  488.         if (menu_opt == PROJECT_INFO) {
  489.             projectInfo();
  490.             redraw=1;
  491.         }
  492.  
  493.         if (menu_opt == LESSONS) {
  494.             TitleScreen_unload_media();
  495.             audioMusicUnload( );
  496.  
  497.                         testLesson();
  498.  
  499.             TitleScreen_load_media();
  500.             redraw = 1;
  501.             audioMusicLoad( "tuxi.ogg", -1 );
  502.         }
  503.  
  504.         if (menu_opt == SET_LANGUAGE) {
  505.             TitleScreen_unload_media();
  506.             chooseTheme();
  507.             LoadLang();
  508.             LoadKeyboard();
  509.             TitleScreen_load_media();
  510.             redraw = 1;
  511.             audioMusicLoad( "tuxi.ogg", -1 );
  512.         }
  513.  
  514.         if (menu_opt == LEVEL1) {
  515.             if (chooseWordlist()) {
  516.                 TitleScreen_unload_media();
  517.                 switch (sub_menu) {
  518.                     case CASCADE: PlayCascade( EASY ); break;
  519.                     case LASER:   laser_game(  EASY ); break;
  520.                 }
  521.                 TitleScreen_load_media();
  522.                 audioMusicLoad( "tuxi.ogg", -1 );
  523.             }
  524.             redraw = 1;
  525.         }
  526.  
  527.         if (menu_opt == LEVEL2) {
  528.             if (chooseWordlist()) {
  529.                 TitleScreen_unload_media();
  530.                 switch (sub_menu) {
  531.                     case CASCADE: PlayCascade( MEDIUM ); break;
  532.                     case LASER:   laser_game(  MEDIUM ); break;
  533.                 }
  534.                 TitleScreen_load_media();
  535.                 audioMusicLoad( "tuxi.ogg", -1 );
  536.             }
  537.             redraw = 1;
  538.         }
  539.  
  540.         if (menu_opt == LEVEL3) {
  541.             if (chooseWordlist()) {
  542.                 TitleScreen_unload_media();
  543.                 switch (sub_menu) {
  544.                     case CASCADE: PlayCascade( HARD ); break;
  545.                     case LASER:   laser_game(  HARD ); break;
  546.                 }
  547.                 TitleScreen_load_media();
  548.                 audioMusicLoad( "tuxi.ogg", -1 );
  549.             }
  550.             redraw = 1;
  551.         }
  552.  
  553.         if (menu_opt == LEVEL4) {
  554.             if (chooseWordlist()) {
  555.                 TitleScreen_unload_media();
  556.                 switch (sub_menu) {
  557.                     case CASCADE: PlayCascade( INSANE ); break;
  558.                     case LASER:   laser_game(  INSANE ); break;
  559.                 }
  560.                 TitleScreen_load_media();
  561.                 audioMusicLoad( "tuxi.ogg", -1 );
  562.             }
  563.             redraw = 1;
  564.         }
  565.  
  566.         if (menu_opt == INSTRUCT) {
  567.             TitleScreen_unload_media();
  568.             switch (sub_menu) {
  569.                 case CASCADE: InstructCascade(); break;
  570.                 case LASER:   InstructLaser();   break;
  571.             }
  572.             TitleScreen_load_media();
  573.                         audioMusicLoad( "tuxi.ogg", -1 );
  574.             redraw=1;
  575.         }
  576.  
  577.         if (menu_opt == FREETYPE)  {
  578.             TitleScreen_unload_media();
  579.             Practice();
  580.             TitleScreen_load_media();
  581.             redraw = 1;
  582.         }
  583.  
  584.         if (redraw) {
  585.             SDL_BlitSurface(bkg, NULL, screen, NULL); 
  586.             SDL_BlitSurface(title, NULL, screen, &Titledest);
  587.             frame = redraw = 0;   // so we redraw tux
  588.             update_locs = 1;      // so we redraw menu
  589.         }
  590.  
  591.         /* --- create new menu screen when needed --- */
  592.  
  593.         if (update_locs) {
  594.             /* --- erase the last menu --- */
  595.             for (i = 1; i <= TITLE_MENU_ITEMS; i++) {
  596.                 text_dst[i].x = 290;
  597.                 text_dst[i].w = reg_text[i][menu_depth]->w;
  598.                 text_dst[i].h = reg_text[i][menu_depth]->h;
  599.                 SDL_BlitSurface(bkg, &menu_button[i], screen, &menu_button[i]);
  600.                 menu_button[i].w = menu_width[menu_depth] + (2*reg->frame[2]->w);
  601.             } 
  602.             update_locs=0;
  603.  
  604.             /* --- draw the full menu --- */
  605.  
  606.             for (j = 1; j <= TITLE_MENU_ITEMS; j++) {
  607.                 draw_button( j, reg );
  608.                 SDL_BlitSurface(reg_text[j][menu_depth], NULL, screen, &text_dst[j]);
  609.                 SDL_BlitSurface(menu_gfx[j][menu_depth]->default_img, NULL, screen, &menu_gfxdest[j]);
  610.             }
  611.         }
  612.  
  613.         /* --- make tux blink --- */
  614.  
  615.         tux_frame = 0;
  616.         switch (frame % TUX6) {
  617.             case 0:    tux_frame = 1; break;
  618.             case TUX1: tux_frame = 2; break;
  619.             case TUX2: tux_frame = 3; break;
  620.             case TUX3: tux_frame = 4; break;            
  621.             case TUX4: tux_frame = 3; break;
  622.             case TUX5: tux_frame = 2; break;
  623.         }
  624.  
  625.         if (tux_frame) {
  626.             SDL_BlitSurface(bkg, &Tuxdest, screen, &Tuxdest);
  627.             SDL_BlitSurface(Tux->frame[tux_frame-1], NULL, screen, &Tuxdest);
  628.         }
  629.         /* --- check if mouse is in a menu option --- */
  630.  
  631.         key_menu = 0;
  632.         for (j = 1; j <= TITLE_MENU_ITEMS; j++) {
  633.             if ((cursor.x >= menu_button[j].x && cursor.x <= (menu_button[j].x + menu_button[j].w)) &&
  634.                 (cursor.y >= menu_button[j].y && cursor.y <= (menu_button[j].y + menu_button[j].h))) {
  635.  
  636.                 key_menu = j; // update menu to point
  637.             }
  638.         }
  639.  
  640.         /* --- return old selection to unselected state --- */
  641.  
  642.         if (old_key_menu && (key_menu != old_key_menu)) {
  643.             SDL_BlitSurface(bkg, &menu_button[old_key_menu], screen, &menu_button[old_key_menu]);
  644.             draw_button( old_key_menu, reg );
  645.             SDL_BlitSurface(reg_text[old_key_menu][menu_depth], NULL, screen, &text_dst[old_key_menu]);
  646.             SDL_BlitSurface(menu_gfx[old_key_menu][menu_depth]->default_img, NULL, screen, &menu_gfxdest[old_key_menu]);
  647.         } 
  648.  
  649.         /* --- draw current selection --- */
  650.         if ((key_menu != 0) && ((old_key_menu != key_menu) || (frame%5 == 0))) {
  651.  
  652.             if (key_menu != old_key_menu) {
  653.                 rewind(menu_gfx[key_menu][menu_depth]);
  654.                 playsound(snd_move);
  655.             }
  656.  
  657.             SDL_BlitSurface(bkg, &menu_button[key_menu], screen, &menu_button[key_menu]);
  658.             draw_button( key_menu, sel );
  659.             SDL_BlitSurface(sel_text[key_menu][menu_depth], NULL, screen, &text_dst[key_menu]);
  660.             SDL_BlitSurface(menu_gfx[key_menu][menu_depth]->frame[menu_gfx[key_menu][menu_depth]->cur], NULL, screen, &menu_gfxdest[key_menu]);
  661.  
  662.             next_frame(menu_gfx[key_menu][menu_depth]);
  663.         }
  664.  
  665.         SDL_UpdateRect(screen, 0, 0, 0, 0); // HACK - don't blit the whole screen!
  666.  
  667.         while ((SDL_GetTicks() - start) < 33)
  668.             SDL_Delay(2);
  669.  
  670.         frame++;
  671.     } 
  672.  
  673.     LOG( "->>Freeing title screen images\n" );
  674.  
  675.     TitleScreen_unload_media();
  676.  
  677.     LOG( "->TitleScreen():END \n" );
  678. }
  679.  
  680. #define MAX_WORD_LISTS 100
  681.  
  682. /* returns 0 if user pressed escape ...
  683.  *         1 if word list was set correctly
  684.  */
  685. int chooseWordlist( void ) {
  686.     SDL_Surface *titles[MAX_WORD_LISTS];
  687.     SDL_Surface *select[MAX_WORD_LISTS];
  688.     SDL_Surface *left, *right;
  689.     SDL_Rect leftRect, rightRect;
  690.     SDL_Rect titleRects[8];
  691.     int stop = 0;
  692.     int loc = 0;
  693.     int old_loc = 1;
  694.     int lists = 1;
  695.     int i;
  696.     unsigned char wordPath[FNLEN];
  697.     unsigned char wordlistFile[MAX_WORD_LISTS][200];
  698.     unsigned char wordlistName[MAX_WORD_LISTS][200];
  699.  
  700.     DIR *wordsDir;
  701.     struct dirent *wordsFile;
  702.     struct stat fileStats;
  703.     FILE *tempFile;
  704.  
  705.     /* find the directory to load wordlists from */
  706.  
  707.     for (i=useEnglish; i<2; i++) {
  708.         fileStats.st_mode = 0; // clear last use!
  709.         sprintf( wordPath, "%s/words", realPath[i] );
  710.         stat( wordPath, &fileStats );
  711.         if ( fileStats.st_mode & S_IFDIR )
  712.             break;
  713.     }
  714.  
  715.     if (i==2) {
  716.         fprintf(stderr, "ERROR: Unable to find wordlist directory\n");
  717.         exit(1);
  718.     }
  719.  
  720.     /* create a list of all the .txt files */
  721.  
  722.     wordsDir = opendir( wordPath );    
  723.  
  724.     do {
  725.         wordsFile = readdir(wordsDir);
  726.         if (!wordsFile)
  727.             break;
  728.  
  729.         /* must have at least .txt at the end */
  730.         if (strlen(wordsFile->d_name) < 5)
  731.             continue;
  732.  
  733.         if (strcmp(&wordsFile->d_name[strlen(wordsFile->d_name)-4],".txt"))
  734.             continue;
  735.  
  736.         sprintf( wordlistFile[lists], "%s/%s", wordPath, wordsFile->d_name );
  737.  
  738.         /* load the name for the wordlist from the file ... (1st line) */
  739.         tempFile = fopen( wordlistFile[lists], "r" );
  740.         if (tempFile==NULL) continue;
  741.         fscanf( tempFile, "%[^\n]\n", wordlistName[lists] );
  742.  
  743.         /* check to see if it has a \r at the end of it (dos format!) */
  744.         if (wordlistName[lists][ strlen(wordlistName[lists])-1 ] == '\r')
  745.             wordlistName[lists][ strlen(wordlistName[lists])-1 ] = '\0';
  746.         lists++;
  747.  
  748.         fclose(tempFile);
  749.         
  750.     } while (1);
  751.  
  752.     closedir( wordsDir );    
  753.  
  754.     /* let the user pick the list */
  755.  
  756.     titles[0] = black_outline( _("Alphabet"), font, &white );
  757.     select[0] = black_outline( _("Alphabet"), font, &yellow);
  758.     for (i = 1; i<lists; i++) {
  759.         titles[i] = black_outline( wordlistName[i], font, &white );
  760.         select[i] = black_outline( wordlistName[i], font, &yellow);
  761.     }
  762.  
  763.     SDL_FreeSurface(bkg);
  764.         bkg = LoadImage("main_bkg.png", IMG_REGULAR);
  765.  
  766.         left = LoadImage("left.png", IMG_ALPHA);       
  767.         leftRect.w = left->w; leftRect.h = left->h;
  768.         leftRect.x = 320 - 80 - (leftRect.w/2); leftRect.y = 430;
  769.  
  770.         right = LoadImage("right.png", IMG_ALPHA);
  771.         rightRect.w = right->w; rightRect.h = right->h;
  772.         rightRect.x = 320 + 80 - (rightRect.w/2); rightRect.y = 430;
  773.  
  774.         /* set initial rect sizes */
  775.         titleRects[0].y = 30;
  776.         titleRects[0].w = titleRects[0].h = titleRects[0].x = 0;
  777.         for (i = 1; i<8; i++) { 
  778.                 titleRects[i].y = titleRects[i-1].y + 50;
  779.                 titleRects[i].w = titleRects[i].h = titleRects[i].x = 0;
  780.         }
  781.  
  782.         while (!stop) {
  783.                 while (SDL_PollEvent(&event))
  784.                         switch (event.type) {
  785.                                 case SDL_QUIT:
  786.                                         exit(0);
  787.                                         break;
  788.                                 case SDL_MOUSEMOTION:
  789.                                         for (i=0; (i<8) && (loc-(loc%8)+i<lists); i++)
  790.                                                 if (inRect( titleRects[i], event.motion.x, event.motion.y )) {
  791.                                                         loc = loc-(loc%8)+i;
  792.                                                         break;
  793.                                                 }
  794.  
  795.                                         break;
  796.                                 case SDL_MOUSEBUTTONDOWN:
  797.                                         if (inRect( leftRect, event.button.x, event.button.y ))
  798.                                                 if (loc-(loc%8)-8 >= 0) {
  799.                                                         loc=loc-(loc%8)-8;
  800.                                                         break;
  801.                                                 }
  802.                                         if (inRect( rightRect, event.button.x, event.button.y ))
  803.                                                 if (loc-(loc%8)+8 < lists) {
  804.                                                         loc=loc-(loc%8)+8;
  805.                                                         break;
  806.                                                 }
  807.                                         for (i=0; (i<8) && (loc-(loc%8)+i<lists); i++)
  808.                                                 if (inRect(titleRects[i], event.button.x, event.button.y)) {
  809.                                                         loc = loc-(loc%8)+i;
  810.                             WORDS_init(); /* clear old selection */
  811.                             if (loc==0)
  812.                                 WORDS_use_alphabet(); 
  813.                             else
  814.                                 WORDS_use( wordlistFile[loc] ); 
  815.                                                         stop = 1;
  816.                                                         break;
  817.                                                 }
  818.                                         break;
  819.                                 case SDL_KEYDOWN:
  820.                                         if (event.key.keysym.sym == SDLK_ESCAPE) { stop = 2; break; }
  821.                                         if (event.key.keysym.sym == SDLK_RETURN) {
  822.                         WORDS_init(); /* clear old selection */
  823.                         if (loc==0)
  824.                             WORDS_use_alphabet(); 
  825.                         else
  826.                             WORDS_use( wordlistFile[loc] ); 
  827.                                                 stop = 1;
  828.                                                 break;
  829.                                         }
  830.  
  831.                                         if ((event.key.keysym.sym == SDLK_LEFT) || (event.key.keysym.sym == SDLK_PAGEUP)) {
  832.                                                 if (loc-(loc%8)-8 >= 0)
  833.                                                         loc=loc-(loc%8)-8;
  834.                                         }
  835.  
  836.                                         if ((event.key.keysym.sym == SDLK_RIGHT) || (event.key.keysym.sym == SDLK_PAGEDOWN)) {
  837.                                                 if (loc-(loc%8)+8 < lists)
  838.                                                         loc=(loc-(loc%8)+8);
  839.                                         }
  840.  
  841.                                         if (event.key.keysym.sym == SDLK_UP) {
  842.                                                 if (loc > 0)
  843.                                                         loc--;
  844.                                         }
  845.  
  846.                                         if (event.key.keysym.sym == SDLK_DOWN) {
  847.                                                 if (loc+1<lists)
  848.                                                         loc++;
  849.                                         }
  850.                         }
  851.  
  852.                 if (old_loc != loc) {
  853.                         int start;
  854.  
  855.                         SDL_BlitSurface( bkg, NULL, screen, NULL );
  856.  
  857.                         start = loc - (loc % 8);
  858.                         for (i = start; i<MIN(start+8,lists); i++) {
  859.                                 titleRects[i%8].x = 320 - (titles[i]->w/2);
  860.                                 if (i == loc)
  861.                                         SDL_BlitSurface(select[loc], NULL, screen, &titleRects[i%8]);
  862.                                 else
  863.                                         SDL_BlitSurface(titles[i], NULL, screen, &titleRects[i%8]);
  864.                         }
  865.  
  866.                         /* --- draw buttons --- */
  867.  
  868.                         if (start>0)
  869.                                 SDL_BlitSurface( left, NULL, screen, &leftRect );
  870.  
  871.                         if (start+8<lists)
  872.                                 SDL_BlitSurface( right, NULL, screen, &rightRect );
  873.  
  874.                         SDL_UpdateRect(screen, 0, 0, 0 ,0);
  875.                 }
  876.                 SDL_Delay(40);
  877.                 old_loc = loc;
  878.         }
  879.  
  880.     /* --- clear graphics before leaving function --- */ 
  881.  
  882.     for (i = 0; i<lists; i++) {
  883.         SDL_FreeSurface(titles[i]);
  884.         SDL_FreeSurface(select[i]);
  885.     }
  886.  
  887.     SDL_FreeSurface(left);
  888.     SDL_FreeSurface(right);
  889.  
  890.         DEBUGCODE { fprintf( stderr, "Leaving chooseWordlist();\n" ); }
  891.  
  892.     if (stop == 2)
  893.         return 0;
  894.  
  895.     return 1;
  896. }
  897. void switch_screen_mode(void)
  898. {
  899.   SDL_Surface *tmp;
  900.   SDL_Rect src, dst;
  901.   int window=0;
  902.   src.x = 0; src.y = 0;
  903.   src.w = RES_X; src.h = RES_Y;
  904.   dst.x = 0; dst.y = 0;
  905.  
  906.   tmp = SDL_CreateRGBSurface(
  907.       SDL_SWSURFACE,
  908.       RES_X,
  909.       RES_Y,
  910.       BPP,
  911. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  912.       0xff000000,
  913.       0x00ff0000,
  914.       0x0000ff00,
  915.       0x000000ff
  916. #else
  917.       0x000000ff,
  918.       0x0000ff00,
  919.       0x00ff0000,
  920.       0xff000000
  921. #endif
  922.       );
  923.   if (screen->flags & SDL_FULLSCREEN)
  924.     window=1;
  925.   SDL_BlitSurface(screen,&src,tmp,&dst);
  926.   SDL_UpdateRect(tmp,0,0,RES_X,RES_Y);
  927.   SDL_FreeSurface(screen);
  928.   screen = NULL;
  929.  
  930.   if ( window ){
  931.     screen = SDL_SetVideoMode(RES_X,RES_Y,BPP, SDL_SWSURFACE|SDL_HWPALETTE);
  932.   } else {
  933.     screen = SDL_SetVideoMode(RES_X,RES_Y,BPP, SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
  934.   }
  935.   SDL_BlitSurface(tmp,&src,screen,&dst);
  936.   SDL_UpdateRect(tmp,0,0,RES_X,RES_Y);
  937.   SDL_FreeSurface(tmp);
  938.  
  939. }
  940.  
  941.