[Tux4kids-commits] r1137 - tuxmath/trunk/src

Bolesław Kulbabiński bolekk-guest at alioth.debian.org
Fri Jul 3 14:32:36 UTC 2009


Author: bolekk-guest
Date: 2009-07-03 14:32:35 +0000 (Fri, 03 Jul 2009)
New Revision: 1137

Modified:
   tuxmath/trunk/src/menu.c
   tuxmath/trunk/src/menu.h
   tuxmath/trunk/src/titlescreen.c
   tuxmath/trunk/src/titlescreen.h
Log:
transferred part of choose_menu_item() functionality into run_menu()

Modified: tuxmath/trunk/src/menu.c
===================================================================
--- tuxmath/trunk/src/menu.c	2009-07-03 00:42:41 UTC (rev 1136)
+++ tuxmath/trunk/src/menu.c	2009-07-03 14:32:35 UTC (rev 1137)
@@ -33,6 +33,8 @@
   N_OF_MENUS
 } MenuType;
 
+enum { NONE, CLICK, PAGEUP, PAGEDOWN, STOP, RESIZED };
+
 MenuNode* menus[N_OF_MENUS];
 
 /* buffer size used when reading attributes or names */
@@ -46,6 +48,8 @@
 MenuNode* load_menu_from_file(FILE* xml_file);
 void free_menu(MenuNode* menu);
 
+int run_menu(MenuNode* menu, bool return_choice);
+void render_menu(MenuNode* menu);
 SDL_Surface** render_buttons(MenuNode* menu, bool selected);
 
 
@@ -60,7 +64,7 @@
   new_node->submenu_size = 0;
   new_node->submenu = NULL;
   new_node->activity = 0;
-  new_node->begin = 0;
+  new_node->first_entry = 0;
 
   return new_node;
 }
@@ -186,61 +190,374 @@
 
 /* Display the menu and run the event loop.
    if return_choice = true then return chosen value instead of
-   running handle_choice() */
+   running handle_choice()
+   this function is just a modification of choose_menu_item() */
 int run_menu(MenuNode* menu, bool return_choice)
 {
-  SDL_Surface **menu_item_unselected = NULL;
-  SDL_Surface **menu_item_selected = NULL;
+  SDL_Surface** menu_item_unselected = NULL;
+  SDL_Surface** menu_item_selected = NULL;
+  //SDL_Surface* title = NULL;
   SDL_Event event;
+
+  SDL_Rect left_arrow_rect, right_arrow_rect, stopRect, tmp_rect;
   int redraw, i;
   int stop = 0;
   int items;
 
-  for(;;) /* one execution for one menu level */
+  int action = NONE;
+
+  Uint32 frame_start = 0;       //For keeping frame rate constant
+  /*Uint32 frame_counter = 0;
+  Uint32 frame_now = 0;
+  int tux_frame = 0;*/
+  int loc = 0;                  //The currently selected menu item
+  int old_loc = 1;
+  int click_flag = 1;
+
+  for(;;) /* one loop body execution for one menu page */
   {
+    DrawTitleScreen();
     /* render buttons for current menu page */
     menu_item_unselected = render_buttons(menu, false);
     menu_item_selected = render_buttons(menu, true);
-    items = min(menu->entries_per_page, menu->submenu_size - menu->begin);
+    items = min(menu->entries_per_screen, menu->submenu_size - menu->first_entry);
 
+    /* Arrow buttons in right lower corner, inset by 20 pixels     */
+    /* with a 10 pixel space between:                              */
+    if (images[IMG_RIGHT])
+    {
+      right_arrow_rect.w = images[IMG_RIGHT]->w;
+      right_arrow_rect.h = images[IMG_RIGHT]->h;
+      right_arrow_rect.x = screen->w - images[IMG_RIGHT]->w - 20;
+      right_arrow_rect.y = screen->h - images[IMG_RIGHT]->h - 20;
+    }
 
-    redraw = 1;  // force a full redraw on first pass
+    if (images[IMG_LEFT])
+    {
+      left_arrow_rect.w = images[IMG_LEFT]->w;
+      left_arrow_rect.h = images[IMG_LEFT]->h;
+      left_arrow_rect.x = right_arrow_rect.x - 10 - images[IMG_LEFT]->w;
+      left_arrow_rect.y = screen->h - images[IMG_LEFT]->h - 20;
+    }
+    /* Red "Stop" circle in upper right corner to go back to main menu: */
+    if (images[IMG_STOP])
+    {
+      stopRect.w = images[IMG_STOP]->w;
+      stopRect.h = images[IMG_STOP]->h;
+      stopRect.x = screen->w - images[IMG_STOP]->w;
+      stopRect.y = 0;
+    }
+
+    old_loc = loc = 0;
+
+
+    for(i = 0; i < menu->submenu_size; i++)
+      SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu->submenu[i]->button_rect);
+    SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+    /* Move mouse to current button: */
+    //cursor.x = menu_button_rect[imod].x + menu_button_rect[imod].w/2;
+    //cursor.y = menu_button_rect[imod].y + menu_button_rect[imod].h/2;
+    SDL_WM_GrabInput(SDL_GRAB_OFF);
+
+
+    /******** Main loop:                                *********/
     while (SDL_PollEvent(&event));  // clear pending events
+    stop = false;
     while (!stop)
     {
+      frame_start = SDL_GetTicks();         /* For keeping frame rate constant.*/
+
+      action = NONE;
       while (SDL_PollEvent(&event))
       {
         switch (event.type)
         {
           case SDL_MOUSEMOTION:
           {
-            for (i = menu->begin; i < menu->begin + items; i++)
+            loc = -1;  // By default, don't be in any entry
+
+            for (i = 0; i < items; i++)
             {
-              if (inRect(menu->submenu[i]->button_rect, event.motion.x, event.motion.y))
+              if (inRect(menu->submenu[menu->first_entry + i]->button_rect, event.motion.x, event.motion.y))
               {
                 // Play sound if loc is being changed:
-                if (Opts_GetGlobalOpt(MENU_SOUND))
+                if (Opts_GetGlobalOpt(MENU_SOUND) && old_loc != i)
+                  playsound(SND_TOCK);
+                loc = i;
+                break;   /* from for loop */
+              }
+            }
+
+            /* "Left" button - make click if button active: */
+            if (inRect(left_arrow_rect, event.motion.x, event.motion.y))
+            {
+              if (menu->first_entry > 0)
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
                 {
                   playsound(SND_TOCK);
+                  click_flag = 0;
                 }
+              }
+              break;  /* from case switch */
+            }
+
+            /* "Right" button - go to next page: */
+            else if (inRect(right_arrow_rect, event.motion.x, event.motion.y ))
+            {
+              if (menu->first_entry + items < menu->submenu_size)
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
+                {
+                  playsound(SND_TOCK);
+                  click_flag = 0;
+                }
+              }
+              break;  /* from case switch */
+            }
+
+            else  // Mouse outside of arrow rects - re-enable click sound:
+            {
+              click_flag = 1;
+              break;  /* from case switch */
+            }
+          }
+
+          case SDL_MOUSEBUTTONDOWN:
+          {
+            loc = -1;  // By default, don't be in any entry
+            for (i = 0; i < items; i++)
+            {
+              if (inRect(menu->submenu[menu->first_entry + i]->button_rect, event.motion.x, event.motion.y))
+              {
+                // Play sound if loc is being changed:
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_POP);
+                loc = i;
+                action = CLICK;
                 break;   /* from for loop */
               }
             }
 
-            break;
+            /* "Left" button */
+            if (inRect(left_arrow_rect, event.motion.x, event.motion.y))
+            {
+              if (menu->first_entry > 0)
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_POP);
+                action = PAGEDOWN;
+              }
+              break;  /* from case switch */
+            }
+
+            /* "Right" button - go to next page: */
+            else if (inRect(right_arrow_rect, event.motion.x, event.motion.y ))
+            {
+              if (menu->first_entry + items < menu->submenu_size)
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
+                  playsound(SND_POP);
+                action = PAGEUP;
+              }
+              break;  /* from case switch */
+            }
+
+          /* "Stop" button - go to main menu: */
+            else if (inRect(stopRect, event.button.x, event.button.y ))
+            {
+              playsound(SND_TOCK);
+              action = STOP;
+              break;
+            }
+          } /* End of case SDL_MOUSEDOWN */
+
+
+          case SDL_KEYDOWN:
+          {
+            /* Proceed according to particular key pressed: */
+            switch (event.key.keysym.sym)
+            {
+              case SDLK_ESCAPE:
+              {
+                action = STOP;
+                break;
+              }
+
+              case SDLK_RETURN:
+              case SDLK_SPACE:
+              case SDLK_KP_ENTER:
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_POP);
+                action = CLICK;
+                break;
+              }
+
+              /* Go to previous page, if present: */
+              case SDLK_LEFT:
+              case SDLK_PAGEUP:
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_TOCK);
+                if (menu->first_entry > 0)
+                  action = PAGEDOWN;
+                break;
+              }
+
+              /* Go to next page, if present: */
+              case SDLK_RIGHT:
+              case SDLK_PAGEDOWN:
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_TOCK);
+                if (menu->first_entry + items < menu->submenu_size)
+                  action = PAGEUP;
+                break;
+              }
+
+              /* Go up one entry, if present: */
+              /*case SDLK_UP:
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_TOCK);
+                if (loc > title_offset)
+                  {loc--;}
+                else if (n_menu_entries <= n_entries_per_screen) {
+                  loc = n_menu_entries-1;  // wrap around if only 1 screen
+                }
+                else if (loc == -1 && loc_screen_start > 0) {
+                  loc = loc_screen_start-1;
+                  loc_screen_start -= n_entries_per_screen;
+                }
+                if (loc != old_loc)
+                  warp_mouse = 1;
+                break;
+              }*/
+
+
+              /* Go down one entry, if present: */
+              /*case SDLK_DOWN:
+              {
+                if (Opts_GetGlobalOpt(MENU_SOUND))
+                  playsound(SND_TOCK);
+                if (loc >= 0 && loc + 1 < n_menu_entries)
+                  {loc++;}
+                else if (n_menu_entries <= n_entries_per_screen)
+                  loc = title_offset;       // wrap around if only 1 screen
+                else if (loc == -1)
+                  loc = loc_screen_start;
+                if (loc != old_loc)
+                  warp_mouse = 1;
+                break;
+              }*/
+
+              /* Change window size (used only to debug) */
+              case SDLK_F5:
+              case SDLK_F6:
+              case SDLK_F7:
+              case SDLK_F8:
+              {
+                /* these keys are available only if in debug mode */
+                DEBUGCODE(debug_titlescreen | debug_menu)
+                {
+                  switch(event.key.keysym.sym)
+                  {
+                    case SDLK_F5:
+                    {
+                      /* decrease screen width */
+                      ChangeWindowSize(win_res_x - 50, win_res_y);
+                      break;
+                    }
+                    case SDLK_F6:
+                    {
+                      /* increase screen width */
+                      ChangeWindowSize(win_res_x + 50, win_res_y);
+                      break;
+                    }
+                    case SDLK_F7:
+                    {
+                      /* decrease screen height */
+                      ChangeWindowSize(win_res_x, win_res_y - 50);
+                      break;
+                    }
+                    case SDLK_F8:
+                    {
+                      /* increase screen height */
+                      ChangeWindowSize(win_res_x, win_res_y + 50);
+                      break;
+                    }
+                    default:
+                      break;
+                  }
+                  render_menu(menu);
+                  action = RESIZED;
+                }
+                break;
+              }
+
+              /* Toggle screen mode: */
+              case SDLK_F10:
+              {
+                SwitchScreenMode();
+                RenderTitleScreen();
+                render_menu(menu);
+                action = RESIZED;
+                break;
+              }
+
+              /* Toggle menu music: */
+              case SDLK_F11:
+              {
+                if (Opts_GetGlobalOpt(MENU_MUSIC))
+                {
+                  audioMusicUnload( );
+                  Opts_SetGlobalOpt(MENU_MUSIC, 0);
+                }
+                else
+                {
+                  Opts_SetGlobalOpt(MENU_MUSIC, 1);
+                  audioMusicLoad("tuxi.ogg", -1);
+                }
+                break;
+              }
+
+              default:
+              {
+                /* Some other key - do nothing. */
+              }
+
+              break;  /* To get out of _outer_ switch/case statement */
+            }  /* End of key switch statement */
+          }  // End of case SDL_KEYDOWN in outer switch statement
+        }  // End event switch statement
+
+        if (old_loc != loc) {
+          if(old_loc >= 0)
+          {
+            tmp_rect = menu->submenu[old_loc + menu->first_entry]->button_rect;
+            SDL_BlitSurface(menu_item_unselected[old_loc], NULL, screen, &tmp_rect);
+            SDL_UpdateRect(screen, tmp_rect.x, tmp_rect.y, tmp_rect.x + tmp_rect.w, tmp_rect.y + tmp_rect.h);
           }
+          if(loc >= 0)
+          {
+            tmp_rect = menu->submenu[loc + menu->first_entry]->button_rect;
+            SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &tmp_rect);
+            SDL_UpdateRect(screen, tmp_rect.x, tmp_rect.y, tmp_rect.x + tmp_rect.w, tmp_rect.y + tmp_rect.h);
+          }
+          old_loc = loc;
         }
-      }
 
-      if(redraw)
-      {
-        for(i = 0; i < menu->submenu_size; i++)
-          SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu->submenu[i]->button_rect);
-        SDL_UpdateRect(screen, 0, 0, 0, 0);
-        redraw = 0;
-      }
+        switch(action)
+        {
+          case RESIZED:
+            stop = true;
+            break;
+        }
+
+      }  // End SDL_PollEvent while loop
     }
-    break;
 
     /* free button surfaces */
     for(i = 0; i < items; i++)
@@ -261,7 +578,7 @@
   SDL_Rect curr_rect, tmp_rect;
   SDL_Surface* tmp_surf = NULL;
   int i;
-  int items = min(menu->entries_per_page, menu->submenu_size - menu->begin);
+  int items = min(menu->entries_per_screen, menu->submenu_size - menu->first_entry);
 
   menu_items = (SDL_Surface**) malloc(items * sizeof(SDL_Surface*));
   if(NULL == menu_items)
@@ -272,7 +589,7 @@
 
   for (i = 0; i < items; i++)
   {
-    curr_rect = menu->submenu[menu->begin + i]->button_rect;
+    curr_rect = menu->submenu[menu->first_entry + i]->button_rect;
     menu_items[i] = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
                                           curr_rect.w,
                                           curr_rect.h,
@@ -290,7 +607,7 @@
     SDL_FreeSurface(tmp_surf);
 
     /* text */
-    tmp_surf = BlackOutline(_(menu->submenu[menu->begin + i]->title),
+    tmp_surf = BlackOutline(_(menu->submenu[menu->first_entry + i]->title),
                             DEFAULT_MENU_FONT_SIZE, selected ? &yellow : &white);
     tmp_rect = tmp_surf->clip_rect;
     tmp_rect.x = curr_rect.h * 2;
@@ -299,12 +616,12 @@
     SDL_FreeSurface(tmp_surf);
 
     /* icon */
-    if(menu->submenu[menu->begin + i]->icon)
+    if(menu->submenu[menu->first_entry + i]->icon)
     {
-      tmp_rect = menu->submenu[menu->begin + i]->icon->default_img->clip_rect;
+      tmp_rect = menu->submenu[menu->first_entry + i]->icon->default_img->clip_rect;
       tmp_rect.x = 0;
       tmp_rect.y = 0;
-      SDL_BlitSurface(menu->submenu[menu->begin + i]->icon->default_img, NULL, menu_items[i], &tmp_rect);
+      SDL_BlitSurface(menu->submenu[menu->first_entry + i]->icon->default_img, NULL, menu_items[i], &tmp_rect);
     }
   }
 
@@ -356,7 +673,7 @@
   button_w = max_text_w + 3 * max_text_h;
 
   gap = 0.2;
-  menu->entries_per_page = (int) ( (menu_rect.h - gap * button_h) / (1.0 + gap) );
+  menu->entries_per_screen = (int) ( (menu_rect.h - gap * button_h) / (1.0 + gap) );
 
   for(i = 0; i < menu->submenu_size; i++)
   {
@@ -378,6 +695,8 @@
     }
     else
       DEBUGMSG(debug_menu, "render_menu(): no sprite for item #%d.\n", i);
+
+    render_menu(menu->submenu[i]);
   }
 
 }

Modified: tuxmath/trunk/src/menu.h
===================================================================
--- tuxmath/trunk/src/menu.h	2009-07-03 00:42:41 UTC (rev 1136)
+++ tuxmath/trunk/src/menu.h	2009-07-03 14:32:35 UTC (rev 1137)
@@ -72,8 +72,8 @@
 
   /* these fields are used only if submenu_size > 0 */
   bool display_title;
-  int entries_per_page;
-  int begin;
+  int entries_per_screen;
+  int first_entry;
 };
 
 typedef struct mNode MenuNode;

Modified: tuxmath/trunk/src/titlescreen.c
===================================================================
--- tuxmath/trunk/src/titlescreen.c	2009-07-03 00:42:41 UTC (rev 1136)
+++ tuxmath/trunk/src/titlescreen.c	2009-07-03 14:32:35 UTC (rev 1137)
@@ -41,6 +41,7 @@
 #include "highscore.h"
 #include "convert_utf.h" // for wide char to UTF-8 conversion
 #include "SDL_extras.h"
+#include "menu.h"
 
 /* --- Data Structure for Dirty Blitting --- */
 SDL_Rect srcupdate[MAX_UPDATES];
@@ -392,6 +393,14 @@
   DEBUGMSG(debug_titlescreen, "leaving TitleScreen()\n");
 }
 
+void DrawTitleScreen(void)
+{
+  SDL_BlitSurface(current_bkg(), NULL, screen, &bkg_rect);
+  SDL_BlitSurface(Tux->frame[0], NULL, screen, &tux_rect);
+  SDL_BlitSurface(title, NULL, screen, &title_rect);
+  SDL_UpdateRect(screen, 0, 0, 0, 0);
+}
+
 /* Render and position all titlescreen items to match current
    screen size. Rendering is done only if needed.
    This function must be called after every resolution change

Modified: tuxmath/trunk/src/titlescreen.h
===================================================================
--- tuxmath/trunk/src/titlescreen.h	2009-07-03 00:42:41 UTC (rev 1136)
+++ tuxmath/trunk/src/titlescreen.h	2009-07-03 14:32:35 UTC (rev 1137)
@@ -125,6 +125,7 @@
 /*In titlescreen.c */
 void TitleScreen(void);
 int RenderTitleScreen(void);
+void DrawTitleScreen(void);
 int ChooseMission(void);  //FIXME really should be in fileops.c
 int choose_menu_item(const char **menu_text, 
                      sprite **menu_sprites, 




More information about the Tux4kids-commits mailing list