• Main Page
  • Classes
  • Files
  • File List
  • File Members

code/source/tcyc_menu.cpp

Go to the documentation of this file.
00001 /*
00002  * TetriCycle
00003  * Copyright (C) 2009, 2010 Cale Scholl
00004  *
00005  * This file is part of TetriCycle.
00006  *
00007  * TetriCycle is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU Lesser General Public License as published
00009  * by the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * TetriCycle is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with TetriCycle.  If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 /** @file tcyc_menu.cpp
00022  * @author Cale Scholl / calvinss4
00023  */
00024 
00025 #include "tcyc_menu.h"
00026 
00027 #include <unistd.h>        // for usleep
00028 #include <gcmodplay.h>     // for MODPlay
00029 #include "Player.h"        // for Player
00030 #include "Options.h"       // for Options
00031 #include "PowerupUtils.h"  // for PowerupUtils
00032 #include "libwiigui/gui.h" // for GuiSound
00033 #include "menu.h"          // for ResumeGui
00034 #include "main.h"          // for TCYC_SetUp2D, TCYC_DrawText, TetriCycle_main
00035 #include "tcyc_input.h"    // for PausePressedAnyPlayer
00036 
00037 extern GuiImageData *pointer[MAX_PLAYERS]; ///< pointing icon, represented by a hand
00038 extern GuiImage *bgImg;       ///< the background image
00039 extern GuiSound *bgMusic;     ///< the background music
00040 extern GuiWindow *mainWindow; ///< the main window
00041 
00042 extern Player *g_players;  ///< the player instances
00043 extern MODPlay g_modPlay;  ///< used for playing the game music
00044 extern bool g_isEditMode;  ///< true when editing the playfield
00045 extern bool g_isClassicMode; ///< classic mode
00046 extern int g_tcycMenu;     ///< the current menu state
00047 extern Options *g_options; ///< the global options
00048 
00049 GuiTrigger *trigA;
00050 GuiTrigger *trigHome;
00051 
00052 GuiSound *btnSoundOver;
00053 GuiSound *g_heartbeatSound;
00054 GuiSound *g_tetrisCheerSound;
00055 
00056 GuiImageData *btnOutline;
00057 GuiImageData *btnOutlineOver;
00058 GuiImageData *btnLargeOutline;
00059 GuiImageData *btnLargeOutlineOver;
00060 GuiImageData *btnData40x40Square;
00061 GuiImageData *btnData40x40SquareOver;
00062 GuiImageData *btnData80x40;
00063 GuiImageData *btnData80x40Over;
00064 GuiImageData *btnDataMinus;
00065 GuiImageData *btnDataMinusOver;
00066 GuiImageData *btnDataPlus;
00067 GuiImageData *btnDataPlusOver;
00068 GuiImageData *tetrisLove;
00069 GuiImageData *grabber[MAX_PLAYERS];
00070 GuiImageData *debug_grabber1;
00071 GuiImageData *debug_grabber2;
00072 GuiImageData *debug_grabber3;
00073 GuiImageData *debug_grabber4;
00074 static GuiImageData *logoImgData;
00075 static GuiImageData *upArrowImgData;
00076 static GuiImageData *upArrowOverImgData;
00077 static GuiImageData *downArrowImgData;
00078 static GuiImageData *downArrowOverImgData;
00079 
00080 // function prototypes
00081 static void TCYC_MenuStartup();
00082 static void TCYC_MenuLoadResources();
00083 static int TCYC_MenuMainScreen();
00084 static int TCYC_MenuGame();
00085 static void TCYC_MenuPlayerProfilesPopup();
00086 static void TCYC_MenuMpOptionsPopup(bool isGlobalOptions = true);
00087 static void TCYC_MenuPowerupsPopup(GuiWindow *parentWindow, 
00088                                    vector<bool> &isPowerupEnabled,
00089                                    PowerupId powerupStartQueue[MAX_ACQUIRED_POWERUPS]);
00090 
00091 static void _DoEasterEgg();
00092 
00093 /// Pause the game.
00094 void TCYC_MenuPause(const char *pauseTxt, GXColor *txtColor)
00095 {
00096   g_options->isPaused = true;
00097   MODPlay_Pause(&g_modPlay, 1); // pause music
00098 
00099   GuiText txt(pauseTxt, 38, txtColor ? *txtColor : (GXColor){255, 255, 255, 255});
00100   txt.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
00101   txt.SetPosition(0, 0);
00102 
00103   GuiWindow pauseWindow(screenwidth, screenheight);
00104   if (pauseTxt)
00105     pauseWindow.Append(&txt);
00106 
00107   // Quit Button
00108   GuiButton quitBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00109   GuiText quitBtnTxt("Quit", 28, (GXColor){0, 0, 0, 255});
00110   GuiImage quitBtnImg(btnOutline);
00111   GuiImage quitBtnImgOver(btnOutlineOver);
00112 
00113   quitBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
00114   quitBtn.SetPosition(-50 - btnOutline->GetWidth(), -50);
00115   quitBtn.SetLabel(&quitBtnTxt);
00116   quitBtn.SetImage(&quitBtnImg);
00117   quitBtn.SetImageOver(&quitBtnImgOver);
00118   quitBtn.SetSoundOver(btnSoundOver);
00119   quitBtn.SetTrigger(trigA);
00120   quitBtn.SetEffectGrow();
00121   pauseWindow.Append(&quitBtn);
00122 
00123   // Restart Button
00124   GuiButton restartBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00125   GuiText restartBtnTxt("Restart", 28, (GXColor){0, 0, 0, 255});
00126   GuiImage restartBtnImg(btnOutline);
00127   GuiImage restartBtnImgOver(btnOutlineOver);
00128 
00129   restartBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
00130   restartBtn.SetPosition(-50, -50);
00131   restartBtn.SetLabel(&restartBtnTxt);
00132   restartBtn.SetImage(&restartBtnImg);
00133   restartBtn.SetImageOver(&restartBtnImgOver);
00134   restartBtn.SetSoundOver(btnSoundOver);
00135   restartBtn.SetTrigger(trigA);
00136   restartBtn.SetEffectGrow();
00137   pauseWindow.Append(&restartBtn);
00138 
00139   // We can only pause from within the game, so the gui is already halted.
00140   mainWindow->Append(&pauseWindow);
00141 
00142   TCYC_SetUp2D();
00143 
00144   while (g_options->isPaused)
00145   {
00146     UpdatePads();
00147     TCYC_DrawText();
00148     mainWindow->Draw();
00149 
00150     for (int i = g_options->players - 1; i >= 0; --i) // so that player 1's cursor appears on top!
00151     {
00152       if (userInput[i].wpad->ir.valid)
00153       {
00154         Menu_DrawImg(userInput[i].wpad->ir.x - 48, userInput[i].wpad->ir.y - 48,
00155                      96, 96, pointer[i]->GetImage(), userInput[i].wpad->ir.angle, 
00156                      1, 1, 255);
00157       }
00158 
00159       DoRumble(i);
00160       mainWindow->Update(&userInput[i]);
00161     }
00162 
00163     Menu_Render();
00164 
00165     if (PausePressedAnyPlayer())
00166     {
00167       g_options->isPaused = false;
00168       MODPlay_Pause(&g_modPlay, 0); // unpause music
00169     }
00170     else if (quitBtn.GetState() == STATE_CLICKED)
00171     {
00172       g_options->isPaused = false;
00173       g_tcycMenu = TCYC_MENU_MAIN;
00174     }
00175     else if (restartBtn.GetState() == STATE_CLICKED)
00176     {
00177       g_options->isPaused = false;
00178       g_tcycMenu = TCYC_MENU_GAME;
00179     }
00180   }
00181 
00182   // Scan pads again or else pressing A will cause the piece to drop.
00183   UpdatePads();
00184 
00185   mainWindow->Remove(&pauseWindow);
00186 }
00187 
00188 /// Displays an error message and exits the program.
00189 /**
00190  * Example:
00191   @code
00192   if (g_totalPowerups > MAX_POWERUPS)
00193   {
00194     char errorBuf[60] = "In defines_Powerup.h you must set MAX_POWERUPS to ";
00195     sprintf(errorBuf + 50, "%d.", g_totalPowerups);
00196     TCYC_MenuError(errorBuf);
00197   }
00198   @endcode
00199  */
00200 void TCYC_MenuError(const char *errorTxt)
00201 {
00202   WindowPrompt("ERROR", errorTxt, "exit");
00203   exit(1);
00204 }
00205 
00206 /// Load all the menu resources.
00207 void TCYC_MenuLoadResources()
00208 {
00209   trigA    = new GuiTrigger();
00210   trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
00211   trigHome = new GuiTrigger();
00212   trigHome->SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0);
00213 
00214   btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM);
00215   g_heartbeatSound = new GuiSound(heartbeat_pcm, heartbeat_pcm_size, SOUND_PCM);
00216   g_tetrisCheerSound = new GuiSound(tetris_cheer_pcm, tetris_cheer_pcm_size, SOUND_PCM);
00217   
00218   btnOutline             = new GuiImageData(button_png);
00219   btnOutlineOver         = new GuiImageData(button_over_png);
00220   btnLargeOutline        = new GuiImageData(button_large_png);
00221   btnLargeOutlineOver    = new GuiImageData(button_large_over_png);
00222   btnData40x40Square     = new GuiImageData(keyboard_key_png);
00223   btnData40x40SquareOver = new GuiImageData(keyboard_key_over_png);
00224   btnData80x40           = new GuiImageData(keyboard_mediumkey_png);
00225   btnData80x40Over       = new GuiImageData(keyboard_mediumkey_over_png);
00226   btnDataMinus           = new GuiImageData(scrollbar_arrowdown_png);
00227   btnDataMinusOver       = new GuiImageData(scrollbar_arrowdown_over_png);
00228   btnDataPlus            = new GuiImageData(scrollbar_arrowup_png);
00229   btnDataPlusOver        = new GuiImageData(scrollbar_arrowup_over_png);
00230   tetrisLove             = new GuiImageData(tetris_love_png);
00231   grabber[0]             = new GuiImageData(player1_grab_png);
00232   grabber[1]             = new GuiImageData(player2_grab_png);
00233   grabber[2]             = new GuiImageData(player3_grab_png);
00234   grabber[3]             = new GuiImageData(player4_grab_png);
00235   debug_grabber1         = new GuiImageData(player1_grab_png);
00236   debug_grabber2         = new GuiImageData(player2_grab_png);
00237   debug_grabber3         = new GuiImageData(player3_grab_png);
00238   debug_grabber4         = new GuiImageData(player4_grab_png);
00239   logoImgData            = new GuiImageData(logo_alien_png);
00240   upArrowImgData         = new GuiImageData(up_arrow_png);
00241   upArrowOverImgData     = new GuiImageData(up_arrow_over_png);
00242   downArrowImgData       = new GuiImageData(down_arrow_png);
00243   downArrowOverImgData   = new GuiImageData(down_arrow_over_png);
00244 
00245   // Init the main screen background image and music.
00246   bgImg   = new GuiImage(tetrisLove);
00247   bgMusic = new GuiSound(tetricycle_by_dj_dimz_ogg, tetricycle_by_dj_dimz_ogg_size, SOUND_OGG);
00248   bgMusic->SetVolume(50);
00249   bgMusic->SetLoop(true);
00250 }
00251 
00252 /// Displays the startup screen.
00253 void TCYC_MenuStartup()
00254 { 
00255   GuiText titleTxt("TetriCycle 1.2 by calvinss4", 30, (GXColor){255, 255, 255, 255});
00256   titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00257   titleTxt.SetPosition(0, 50);
00258 
00259   GuiText wwwTxt("www.wiibrew.org/wiki/TetriCycle", 28, (GXColor){255, 255, 255, 255});
00260   wwwTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00261   wwwTxt.SetPosition(0, 90);
00262 
00263   GuiText sourceTxt1("This game is open source. See:", 28, (GXColor){255, 255, 255, 255});
00264   sourceTxt1.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00265   sourceTxt1.SetPosition(0, 140);
00266 
00267   GuiText sourceTxt2("code.google.com/p/tetricycle", 28, (GXColor){255, 255, 255, 255});
00268   sourceTxt2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00269   sourceTxt2.SetPosition(0, 175);
00270 
00271   GuiText emailTxt1("Bugs, questions or comments:", 28, (GXColor){255, 255, 255, 255});
00272   emailTxt1.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00273   emailTxt1.SetPosition(0, 225);
00274 
00275   GuiText emailTxt2("code.google.com/p/tetricycle/issues", 28, (GXColor){255, 255, 255, 255});
00276   emailTxt2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00277   emailTxt2.SetPosition(0, 260);
00278 
00279   GuiText scamTxt("If you paid for this you were scammed!", 26, (GXColor){255, 255, 255, 255});
00280   scamTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00281   scamTxt.SetPosition(0, 310);
00282 
00283   GuiText initTxt("PRESS ANY BUTTON", 30, (GXColor){255, 255, 255, 255});
00284   initTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00285   initTxt.SetPosition(0, 360);
00286 
00287   GuiWindow w(screenwidth, screenheight);
00288   w.Append(&titleTxt);
00289   w.Append(&wwwTxt);
00290   w.Append(&sourceTxt1);
00291   w.Append(&sourceTxt2);
00292   w.Append(&emailTxt1);
00293   w.Append(&emailTxt2);
00294   w.Append(&scamTxt);
00295   w.Append(&initTxt);
00296   
00297   HaltGui();
00298   mainWindow->Append(&w);
00299   ResumeGui();
00300 
00301   // Load resources while the startup screen is displaying.
00302   TCYC_MenuLoadResources();
00303 
00304   bool loop = true;
00305   while (loop)
00306   {
00307     for (int i = 0; i < MAX_PLAYERS; ++i)
00308     {
00309       if (WPAD_ButtonsDown(i))
00310       {
00311         loop = false;
00312         break;
00313       }
00314     }
00315   }
00316 
00317   HaltGui();
00318   mainWindow->Remove(&w);
00319 }
00320 
00321 /// The game state loop.
00322 void TCYC_MenuLoop()
00323 {
00324   // Display the startup screen.
00325   TCYC_MenuStartup();
00326 
00327   g_tcycMenu = TCYC_MENU_MAIN;
00328 
00329   while (g_tcycMenu != TCYC_MENU_EXIT)
00330   {
00331     switch (g_tcycMenu)
00332     {
00333       case TCYC_MENU_MAIN:
00334         g_tcycMenu = TCYC_MenuMainScreen(); // halts the gui before exiting
00335         break;
00336       case TCYC_MENU_GAME:
00337         g_tcycMenu = TCYC_MenuGame();
00338         break;
00339       default: // unrecognized menu
00340         g_tcycMenu = TCYC_MENU_EXIT;
00341         break;
00342     }
00343   }
00344 }
00345 
00346 /// Displays the main menu screen.
00347 int TCYC_MenuMainScreen()
00348 {
00349   static const int RIGHT_OFFSET = 0;
00350   static const int LEFT_OFFSET = 32;
00351   static const int TOP_OFFSET = 155;
00352   static const int BOTTOM_OFFSET = -50;
00353 
00354   ResetVideo_Menu();
00355   if (!g_isEditMode)
00356     bgMusic->Play();
00357   g_isEditMode = false;
00358   g_isClassicMode = false;
00359 
00360   // logo
00361   GuiImage logoImg(logoImgData);
00362   logoImg.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00363   logoImg.SetPosition(0, 40);
00364 
00365   //--- Classic Mode ---
00366   GuiText classicTxt("Classical:", 24, (GXColor){255, 255, 255, 255});
00367   classicTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00368   classicTxt.SetPosition(LEFT_OFFSET, TOP_OFFSET);
00369 
00370   // 1P button
00371   GuiButton classicp1Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00372   GuiText classicp1BtnTxt("1P", 22, (GXColor){0, 0, 0, 255});
00373   GuiImage classicp1BtnImg(btnData40x40Square);
00374   GuiImage classicp1BtnImgOver(btnData40x40SquareOver);
00375 
00376   classicp1Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00377   classicp1Btn.SetPosition(LEFT_OFFSET, TOP_OFFSET + 30);
00378   classicp1Btn.SetLabel(&classicp1BtnTxt);
00379   classicp1Btn.SetImage(&classicp1BtnImg);
00380   classicp1Btn.SetImageOver(&classicp1BtnImgOver);
00381   classicp1Btn.SetSoundOver(btnSoundOver);
00382   classicp1Btn.SetTrigger(trigA);
00383   classicp1Btn.SetEffectGrow();
00384 
00385   // 2P button
00386   GuiButton classicp2Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00387   GuiText classicp2BtnTxt("2P", 22, (GXColor){0, 0, 0, 255});
00388   GuiImage classicp2BtnImg(btnData40x40Square);
00389   GuiImage classicp2BtnImgOver(btnData40x40SquareOver);
00390 
00391   classicp2Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00392   classicp2Btn.SetPosition(LEFT_OFFSET + btnData40x40Square->GetWidth(), TOP_OFFSET + 30);
00393   classicp2Btn.SetLabel(&classicp2BtnTxt);
00394   classicp2Btn.SetImage(&classicp2BtnImg);
00395   classicp2Btn.SetImageOver(&classicp2BtnImgOver);
00396   classicp2Btn.SetSoundOver(btnSoundOver);
00397   classicp2Btn.SetTrigger(trigA);
00398   classicp2Btn.SetEffectGrow();
00399 
00400   // 3P button
00401   GuiButton classicp3Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00402   GuiText classicp3BtnTxt("3P", 22, (GXColor){0, 0, 0, 255});
00403   GuiImage classicp3BtnImg(btnData40x40Square);
00404   GuiImage classicp3BtnImgOver(btnData40x40SquareOver);
00405 
00406   classicp3Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00407   classicp3Btn.SetPosition(LEFT_OFFSET + 2 * btnData40x40Square->GetWidth(), TOP_OFFSET + 30);
00408   classicp3Btn.SetLabel(&classicp3BtnTxt);
00409   classicp3Btn.SetImage(&classicp3BtnImg);
00410   classicp3Btn.SetImageOver(&classicp3BtnImgOver);
00411   classicp3Btn.SetSoundOver(btnSoundOver);
00412   classicp3Btn.SetTrigger(trigA);
00413   classicp3Btn.SetEffectGrow();
00414 
00415   // 4P button
00416   GuiButton classicp4Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00417   GuiText classicp4BtnTxt("4P", 22, (GXColor){0, 0, 0, 255});
00418   GuiImage classicp4BtnImg(btnData40x40Square);
00419   GuiImage classicp4BtnImgOver(btnData40x40SquareOver);
00420 
00421   classicp4Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00422   classicp4Btn.SetPosition(LEFT_OFFSET + 3 * btnData40x40Square->GetWidth(), TOP_OFFSET + 30);
00423   classicp4Btn.SetLabel(&classicp4BtnTxt);
00424   classicp4Btn.SetImage(&classicp4BtnImg);
00425   classicp4Btn.SetImageOver(&classicp4BtnImgOver);
00426   classicp4Btn.SetSoundOver(btnSoundOver);
00427   classicp4Btn.SetTrigger(trigA);
00428   classicp4Btn.SetEffectGrow();
00429 
00430   static const int PLAYER_DY = 60;
00431 
00432   //--- Cylindrical Mode ---
00433   GuiText cylindricalTxt("Cylindrical:", 24, (GXColor){255, 255, 255, 255});
00434   cylindricalTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00435   cylindricalTxt.SetPosition(LEFT_OFFSET, TOP_OFFSET + (PLAYER_DY + btnData40x40Square->GetHeight()) * 1);
00436 
00437   // 1P button
00438   GuiButton p1Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00439   GuiText p1BtnTxt("1P", 22, (GXColor){0, 0, 0, 255});
00440   GuiImage p1BtnImg(btnData40x40Square);
00441   GuiImage p1BtnImgOver(btnData40x40SquareOver);
00442 
00443   p1Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00444   p1Btn.SetPosition(LEFT_OFFSET, TOP_OFFSET + 30 + (PLAYER_DY + btnData40x40Square->GetHeight()) * 1);
00445   p1Btn.SetLabel(&p1BtnTxt);
00446   p1Btn.SetImage(&p1BtnImg);
00447   p1Btn.SetImageOver(&p1BtnImgOver);
00448   p1Btn.SetSoundOver(btnSoundOver);
00449   p1Btn.SetTrigger(trigA);
00450   p1Btn.SetEffectGrow();
00451 
00452   // 2P button
00453   GuiButton p2Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00454   GuiText p2BtnTxt("2P", 22, (GXColor){0, 0, 0, 255});
00455   GuiImage p2BtnImg(btnData40x40Square);
00456   GuiImage p2BtnImgOver(btnData40x40SquareOver);
00457 
00458   p2Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00459   p2Btn.SetPosition(LEFT_OFFSET + btnData40x40Square->GetWidth(), TOP_OFFSET + 30 + (PLAYER_DY + btnData40x40Square->GetHeight()) * 1);
00460   p2Btn.SetLabel(&p2BtnTxt);
00461   p2Btn.SetImage(&p2BtnImg);
00462   p2Btn.SetImageOver(&p2BtnImgOver);
00463   p2Btn.SetSoundOver(btnSoundOver);
00464   p2Btn.SetTrigger(trigA);
00465   p2Btn.SetEffectGrow();
00466 
00467   // 3P button
00468   GuiButton p3Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00469   GuiText p3BtnTxt("3P", 22, (GXColor){0, 0, 0, 255});
00470   GuiImage p3BtnImg(btnData40x40Square);
00471   GuiImage p3BtnImgOver(btnData40x40SquareOver);
00472 
00473   p3Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00474   p3Btn.SetPosition(LEFT_OFFSET + 2 * btnData40x40Square->GetWidth(), TOP_OFFSET + 30 + (PLAYER_DY + btnData40x40Square->GetHeight()) * 1);
00475   p3Btn.SetLabel(&p3BtnTxt);
00476   p3Btn.SetImage(&p3BtnImg);
00477   p3Btn.SetImageOver(&p3BtnImgOver);
00478   p3Btn.SetSoundOver(btnSoundOver);
00479   p3Btn.SetTrigger(trigA);
00480   p3Btn.SetEffectGrow();
00481 
00482   // 4P button
00483   GuiButton p4Btn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00484   GuiText p4BtnTxt("4P", 22, (GXColor){0, 0, 0, 255});
00485   GuiImage p4BtnImg(btnData40x40Square);
00486   GuiImage p4BtnImgOver(btnData40x40SquareOver);
00487 
00488   p4Btn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00489   p4Btn.SetPosition(LEFT_OFFSET + 3 * btnData40x40Square->GetWidth(), TOP_OFFSET + 30 + (PLAYER_DY + btnData40x40Square->GetHeight()) * 1);
00490   p4Btn.SetLabel(&p4BtnTxt);
00491   p4Btn.SetImage(&p4BtnImg);
00492   p4Btn.SetImageOver(&p4BtnImgOver);
00493   p4Btn.SetSoundOver(btnSoundOver);
00494   p4Btn.SetTrigger(trigA);
00495   p4Btn.SetEffectGrow();
00496 
00497   // player profiles button
00498   GuiButton profileBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00499   GuiText profileBtnTxt("Player Profiles", 22, (GXColor){0, 0, 0, 255});
00500   GuiImage profileBtnImg(btnOutline);
00501   GuiImage profileBtnImgOver(btnOutlineOver);
00502 
00503   profileBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
00504   profileBtn.SetPosition(RIGHT_OFFSET, TOP_OFFSET);
00505   profileBtn.SetLabel(&profileBtnTxt);
00506   profileBtn.SetImage(&profileBtnImg);
00507   profileBtn.SetImageOver(&profileBtnImgOver);
00508   profileBtn.SetSoundOver(btnSoundOver);
00509   profileBtn.SetTrigger(trigA);
00510   profileBtn.SetEffectGrow();
00511 
00512   // multiplayer options button
00513   GuiButton mpOptionsBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00514   GuiText mpOptionsBtnTxt("MP Options", 22, (GXColor){0, 0, 0, 255});
00515   GuiImage mpOptionsBtnImg(btnOutline);
00516   GuiImage mpOptionsBtnImgOver(btnOutlineOver);
00517 
00518   mpOptionsBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
00519   mpOptionsBtn.SetPosition(RIGHT_OFFSET, TOP_OFFSET + btnOutline->GetHeight() * 1);
00520   mpOptionsBtn.SetLabel(&mpOptionsBtnTxt);
00521   mpOptionsBtn.SetImage(&mpOptionsBtnImg);
00522   mpOptionsBtn.SetImageOver(&mpOptionsBtnImgOver);
00523   mpOptionsBtn.SetSoundOver(btnSoundOver);
00524   mpOptionsBtn.SetTrigger(trigA);
00525   mpOptionsBtn.SetEffectGrow();
00526 
00527   // handicap options button
00528   GuiButton mpHandicapsBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00529   GuiText mpHandicapsBtnTxt("MP Handicaps", 22, (GXColor){0, 0, 0, 255});
00530   GuiImage mpHandicapsBtnImg(btnOutline);
00531   GuiImage mpHandicapsBtnImgOver(btnOutlineOver);
00532 
00533   mpHandicapsBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
00534   mpHandicapsBtn.SetPosition(RIGHT_OFFSET, TOP_OFFSET + btnOutline->GetHeight() * 2);
00535   mpHandicapsBtn.SetLabel(&mpHandicapsBtnTxt);
00536   mpHandicapsBtn.SetImage(&mpHandicapsBtnImg);
00537   mpHandicapsBtn.SetImageOver(&mpHandicapsBtnImgOver);
00538   mpHandicapsBtn.SetSoundOver(btnSoundOver);
00539   mpHandicapsBtn.SetTrigger(trigA);
00540   mpHandicapsBtn.SetEffectGrow();
00541 
00542   // return to loader button
00543   GuiButton returnBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00544   GuiText returnBtnTxt("Return to loader", 20, (GXColor){0, 0, 0, 255});
00545   GuiImage returnBtnImg(btnOutline);
00546   GuiImage returnBtnImgOver(btnOutlineOver);
00547 
00548   returnBtn.SetAlignment(ALIGN_CENTRE/*ALIGN_RIGHT*/, ALIGN_BOTTOM);
00549   returnBtn.SetPosition(0/*RIGHT_OFFSET - btnOutline->GetWidth()*/, BOTTOM_OFFSET);
00550   returnBtn.SetLabel(&returnBtnTxt);
00551   returnBtn.SetImage(&returnBtnImg);
00552   returnBtn.SetImageOver(&returnBtnImgOver);
00553   returnBtn.SetSoundOver(btnSoundOver);
00554   returnBtn.SetTrigger(trigA);
00555   returnBtn.SetTrigger(trigHome);
00556   returnBtn.SetEffectGrow();
00557 
00558   // exit to wii menu button
00559   GuiButton exitBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
00560   GuiText exitBtnTxt("Exit to Wii menu", 20, (GXColor){0, 0, 0, 255});
00561   GuiImage exitBtnImg(btnOutline);
00562   GuiImage exitBtnImgOver(btnOutlineOver);
00563 
00564   exitBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
00565   exitBtn.SetPosition(RIGHT_OFFSET, BOTTOM_OFFSET);
00566   exitBtn.SetLabel(&exitBtnTxt);
00567   exitBtn.SetImage(&exitBtnImg);
00568   exitBtn.SetImageOver(&exitBtnImgOver);
00569   exitBtn.SetSoundOver(btnSoundOver);
00570   exitBtn.SetTrigger(trigA);
00571   exitBtn.SetTrigger(trigHome);
00572   exitBtn.SetEffectGrow();
00573 
00574   // easter egg button
00575   GuiButton heartBtn(150, 150);
00576   heartBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
00577   heartBtn.SetPosition(0, 25);
00578   heartBtn.SetSoundOver(btnSoundOver);
00579   heartBtn.SetTrigger(trigA);
00580 
00581   static const int PLAYER_BOTTOM_OFFSET = -5;
00582 
00583   //--- Adjust Playfield ---
00584   GuiText playfieldTxt("Edit Playfield:", 24, (GXColor){255, 255, 255, 255});
00585   playfieldTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
00586   playfieldTxt.SetPosition(LEFT_OFFSET, BOTTOM_OFFSET + PLAYER_BOTTOM_OFFSET - btnData40x40Square->GetHeight() - 8);
00587 
00588   GuiButton edit1PBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00589   GuiText edit1PBtnTxt("1P", 22, (GXColor){0, 0, 0, 255});
00590   GuiImage edit1PBtnImg(btnData40x40Square);
00591   GuiImage edit1PBtnImgOver(btnData40x40SquareOver);
00592 
00593   edit1PBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
00594   edit1PBtn.SetPosition(LEFT_OFFSET, BOTTOM_OFFSET + PLAYER_BOTTOM_OFFSET);
00595   edit1PBtn.SetLabel(&edit1PBtnTxt);
00596   edit1PBtn.SetImage(&edit1PBtnImg);
00597   edit1PBtn.SetImageOver(&edit1PBtnImgOver);
00598   edit1PBtn.SetSoundOver(btnSoundOver);
00599   edit1PBtn.SetTrigger(trigA);
00600   edit1PBtn.SetEffectGrow();
00601 
00602   GuiButton edit2PBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00603   GuiText edit2PBtnTxt("2P", 22, (GXColor){0, 0, 0, 255});
00604   GuiImage edit2PBtnImg(btnData40x40Square);
00605   GuiImage edit2PBtnImgOver(btnData40x40SquareOver);
00606 
00607   edit2PBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
00608   edit2PBtn.SetPosition(LEFT_OFFSET + btnData40x40Square->GetWidth(), BOTTOM_OFFSET + PLAYER_BOTTOM_OFFSET);
00609   edit2PBtn.SetLabel(&edit2PBtnTxt);
00610   edit2PBtn.SetImage(&edit2PBtnImg);
00611   edit2PBtn.SetImageOver(&edit2PBtnImgOver);
00612   edit2PBtn.SetSoundOver(btnSoundOver);
00613   edit2PBtn.SetTrigger(trigA);
00614   edit2PBtn.SetEffectGrow();
00615 
00616   GuiButton edit3PBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00617   GuiText edit3PBtnTxt("3P", 22, (GXColor){0, 0, 0, 255});
00618   GuiImage edit3PBtnImg(btnData40x40Square);
00619   GuiImage edit3PBtnImgOver(btnData40x40SquareOver);
00620 
00621   edit3PBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
00622   edit3PBtn.SetPosition(LEFT_OFFSET + 2 * btnData40x40Square->GetWidth(), BOTTOM_OFFSET + PLAYER_BOTTOM_OFFSET);
00623   edit3PBtn.SetLabel(&edit3PBtnTxt);
00624   edit3PBtn.SetImage(&edit3PBtnImg);
00625   edit3PBtn.SetImageOver(&edit3PBtnImgOver);
00626   edit3PBtn.SetSoundOver(btnSoundOver);
00627   edit3PBtn.SetTrigger(trigA);
00628   edit3PBtn.SetEffectGrow();
00629 
00630   GuiButton edit4PBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00631   GuiText edit4PBtnTxt("4P", 22, (GXColor){0, 0, 0, 255});
00632   GuiImage edit4PBtnImg(btnData40x40Square);
00633   GuiImage edit4PBtnImgOver(btnData40x40SquareOver);
00634 
00635   edit4PBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
00636   edit4PBtn.SetPosition(LEFT_OFFSET + 3 * btnData40x40Square->GetWidth(), BOTTOM_OFFSET + PLAYER_BOTTOM_OFFSET);
00637   edit4PBtn.SetLabel(&edit4PBtnTxt);
00638   edit4PBtn.SetImage(&edit4PBtnImg);
00639   edit4PBtn.SetImageOver(&edit4PBtnImgOver);
00640   edit4PBtn.SetSoundOver(btnSoundOver);
00641   edit4PBtn.SetTrigger(trigA);
00642   edit4PBtn.SetEffectGrow();
00643 
00644   //--- Populate the window ---
00645   GuiWindow w(screenwidth, screenheight);
00646   w.Append(bgImg);
00647   w.Append(&logoImg);
00648   w.Append(&classicTxt);
00649   w.Append(&classicp1Btn);
00650   w.Append(&classicp2Btn);
00651   w.Append(&classicp3Btn);
00652   w.Append(&classicp4Btn);
00653   w.Append(&cylindricalTxt);
00654   w.Append(&p1Btn);
00655   w.Append(&p2Btn);
00656   w.Append(&p3Btn);
00657   w.Append(&p4Btn);
00658   w.Append(&playfieldTxt);
00659   w.Append(&edit1PBtn);
00660   w.Append(&edit2PBtn);
00661   w.Append(&edit3PBtn);
00662   w.Append(&edit4PBtn);
00663   w.Append(&profileBtn);
00664   w.Append(&mpOptionsBtn);
00665   w.Append(&mpHandicapsBtn);
00666   w.Append(&returnBtn);
00667   w.Append(&exitBtn);
00668   w.Append(&heartBtn);
00669   //w.Append(&networkBtn);
00670 
00671   HaltGui();
00672   mainWindow->Append(&w);
00673   ResumeGui();
00674 
00675   int menu = TCYC_MENU_NONE;
00676 
00677   while (menu == TCYC_MENU_NONE)
00678   {
00679     usleep(THREAD_SLEEP);
00680     if (p1Btn.GetState() == STATE_CLICKED)
00681     {
00682       g_options->players = 1;
00683       menu = TCYC_MENU_GAME;
00684     }
00685     else if (p2Btn.GetState() == STATE_CLICKED)
00686     {
00687       g_options->players = 2;
00688       menu = TCYC_MENU_GAME;
00689     }
00690     else if (p3Btn.GetState() == STATE_CLICKED)
00691     {
00692       g_options->players = 3;
00693       menu = TCYC_MENU_GAME;
00694     }
00695     else if (p4Btn.GetState() == STATE_CLICKED)
00696     {
00697       g_options->players = 4;
00698       menu = TCYC_MENU_GAME;
00699     }
00700     else if (profileBtn.GetState() == STATE_CLICKED)
00701     {
00702       profileBtn.ResetState();
00703       TCYC_MenuPlayerProfilesPopup();
00704     }
00705     else if (mpOptionsBtn.GetState() == STATE_CLICKED)
00706     {
00707       mpOptionsBtn.ResetState();
00708       TCYC_MenuMpOptionsPopup();
00709     }
00710     else if (mpHandicapsBtn.GetState() == STATE_CLICKED)
00711     {
00712       mpHandicapsBtn.ResetState();
00713       TCYC_MenuMpOptionsPopup(false/*isGlobalOptions*/);
00714     }
00715     else if (returnBtn.GetState() == STATE_CLICKED)
00716     {
00717       exit(0);
00718     }
00719     else if (exitBtn.GetState() == STATE_CLICKED)
00720     {
00721       SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
00722     }
00723     else if (heartBtn.GetState() == STATE_CLICKED)
00724     {
00725       heartBtn.ResetState();
00726       _DoEasterEgg();
00727     }
00728     else if (edit1PBtn.GetState() == STATE_CLICKED)
00729     {
00730       g_options->players = 1;
00731       menu = TCYC_MENU_GAME;
00732       g_isEditMode = true;
00733     }
00734     else if (edit2PBtn.GetState() == STATE_CLICKED)
00735     {
00736       g_options->players = 2;
00737       menu = TCYC_MENU_GAME;
00738       g_isEditMode = true;
00739     }
00740     else if (edit3PBtn.GetState() == STATE_CLICKED)
00741     {
00742       g_options->players = 3;
00743       menu = TCYC_MENU_GAME;
00744       g_isEditMode = true;
00745     }
00746     else if (edit4PBtn.GetState() == STATE_CLICKED)
00747     {
00748       g_options->players = 4;
00749       menu = TCYC_MENU_GAME;
00750       g_isEditMode = true;
00751     }
00752           else if (classicp1Btn.GetState() == STATE_CLICKED)
00753     {
00754       g_options->players = 1;
00755       menu = TCYC_MENU_GAME;
00756             g_isClassicMode = true;
00757     }
00758     else if (classicp2Btn.GetState() == STATE_CLICKED)
00759     {
00760       g_options->players = 2;
00761       menu = TCYC_MENU_GAME;
00762             g_isClassicMode = true;
00763     }
00764     else if (classicp3Btn.GetState() == STATE_CLICKED)
00765     {
00766       g_options->players = 3;
00767       menu = TCYC_MENU_GAME;
00768             g_isClassicMode = true;
00769     }
00770     else if (classicp4Btn.GetState() == STATE_CLICKED)
00771     {
00772       g_options->players = 4;
00773       menu = TCYC_MENU_GAME;
00774             g_isClassicMode = true;
00775     }
00776   }
00777 
00778   if (!g_isEditMode)
00779     bgMusic->Stop();
00780 
00781   HaltGui();
00782   mainWindow->Remove(&w);
00783   return menu;
00784 }
00785 
00786 /// Runs the game loop.
00787 int TCYC_MenuGame()
00788 {
00789   // Doing this in a loop allows us to reset the game.
00790   while (g_tcycMenu == TCYC_MENU_GAME)
00791   {
00792     if (g_isEditMode)
00793       TCYC_EditPlayfield();
00794     else
00795       TCYC_Game();
00796   }
00797 
00798   return TCYC_MENU_MAIN;
00799 }
00800 
00801 /// Launches the player profiles popup.
00802 void TCYC_MenuPlayerProfilesPopup()
00803 {
00804   static const char *rotateStr[] = {"normal", "reverse", "piece"};
00805   static const char *guideStr[]  = {"off", "shadow", "line"};
00806   static const int PADDING_TOP = 12;
00807   GXColor helpTxtColor = (GXColor){0, 170, 0, 255};
00808   GXColor blackColor = (GXColor){0, 0, 0, 255};
00809 
00810   int player = 0;
00811   char playerBuf[7+1+1] = "PLAYER "; // values: 1-MAX_PLAYERS + "PLAYER "
00812   sprintf(playerBuf + 7, "%d", player + 1);
00813 
00814   u8 rotation[MAX_PLAYERS];
00815   u8 guide[MAX_PLAYERS];
00816   bool isShakeEnabled[MAX_PLAYERS];
00817   bool isPreviewEnabled[MAX_PLAYERS];
00818 
00819   for (int i = 0; i < MAX_PLAYERS; ++i)
00820   {
00821     rotation[i]         = g_players[i].rotation;
00822     guide[i]            = g_players[i].guide;
00823     isShakeEnabled[i]   = g_players[i].isShakeEnabled;
00824     isPreviewEnabled[i] = g_players[i].isPreviewEnabled;
00825   }
00826 
00827   // popup window
00828   GuiWindow promptWindow(screenwidth - 100, screenheight - 100);
00829   promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
00830   promptWindow.SetPosition(0, 0);
00831 
00832   // background image
00833   GuiImage profilesBgImg(screenwidth - 100, screenheight - 100, (GXColor){170, 170, 170, 255});
00834 
00835   // title text
00836   GuiText titleTxt("Player Profiles", 30, blackColor);
00837   titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00838   titleTxt.SetPosition(0, 15);
00839 
00840   // PLAYER LEFT ARROW BUTTON
00841   GuiButton playerLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00842   GuiText playerLeftArrowBtnTxt("<", 22, blackColor);
00843   GuiText playerLeftArrowBtnTxtOver("<", 22, helpTxtColor);
00844   GuiImage playerLeftArrowBtnImg(btnData40x40Square);
00845   GuiImage playerLeftArrowBtnImgOver(btnData40x40SquareOver);
00846 
00847   playerLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00848   playerLeftArrowBtn.SetPosition(-80, 60);
00849   playerLeftArrowBtn.SetLabel(&playerLeftArrowBtnTxt);
00850   playerLeftArrowBtn.SetLabelOver(&playerLeftArrowBtnTxtOver);
00851   playerLeftArrowBtn.SetImage(&playerLeftArrowBtnImg);
00852   playerLeftArrowBtn.SetImageOver(&playerLeftArrowBtnImgOver);
00853   playerLeftArrowBtn.SetSoundOver(btnSoundOver);
00854   playerLeftArrowBtn.SetTrigger(trigA);
00855   playerLeftArrowBtn.SetEffectGrow();
00856 
00857   // PLAYER RIGHT ARROW BUTTON
00858   GuiButton playerRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00859   GuiText playerRightArrowBtnTxt(">", 22, blackColor);
00860   GuiText playerRightArrowBtnTxtOver(">", 22, helpTxtColor);
00861   GuiImage playerRightArrowBtnImg(btnData40x40Square);
00862   GuiImage playerRightArrowBtnImgOver(btnData40x40SquareOver);
00863 
00864   playerRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00865   playerRightArrowBtn.SetPosition(80, 60);
00866   playerRightArrowBtn.SetLabel(&playerRightArrowBtnTxt);
00867   playerRightArrowBtn.SetLabelOver(&playerRightArrowBtnTxtOver);
00868   playerRightArrowBtn.SetImage(&playerRightArrowBtnImg);
00869   playerRightArrowBtn.SetImageOver(&playerRightArrowBtnImgOver);
00870   playerRightArrowBtn.SetSoundOver(btnSoundOver);
00871   playerRightArrowBtn.SetTrigger(trigA);
00872   playerRightArrowBtn.SetEffectGrow();
00873 
00874   // PLAYER TEXT
00875   GuiText playerTxt(playerBuf, 22, blackColor);
00876   playerTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00877   playerTxt.SetPosition(0, 60 + PADDING_TOP);
00878 
00879   // ROTATION TEXT BUTTON
00880   GuiButton rotationTxtBtn((9 + 1) * 11, 22);
00881   GuiText rotationTxtBtnTxt("rotation:", 22, blackColor);
00882   GuiText rotationTxtBtnTxtOver("rotation:", 22, helpTxtColor);
00883 
00884   rotationTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00885   rotationTxtBtn.SetPosition(20, 60 + PADDING_TOP + 1 * 40);
00886   rotationTxtBtn.SetLabel(&rotationTxtBtnTxt);
00887   rotationTxtBtn.SetLabelOver(&rotationTxtBtnTxtOver);
00888   rotationTxtBtn.SetSoundOver(btnSoundOver);
00889   rotationTxtBtn.SetTrigger(trigA);
00890 
00891   // ROTATION LEFT ARROW BUTTON
00892   GuiButton rotationLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00893   GuiText rotationLeftArrowBtnTxt("<", 22, blackColor);
00894   GuiText rotationLeftArrowBtnTxtOver("<", 22, helpTxtColor);
00895   GuiImage rotationLeftArrowBtnImg(btnData40x40Square);
00896   GuiImage rotationLeftArrowBtnImgOver(btnData40x40SquareOver);
00897 
00898   rotationLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00899   rotationLeftArrowBtn.SetPosition(-80, 60 + 1 * 40);
00900   rotationLeftArrowBtn.SetLabel(&rotationLeftArrowBtnTxt);
00901   rotationLeftArrowBtn.SetLabelOver(&rotationLeftArrowBtnTxtOver);
00902   rotationLeftArrowBtn.SetImage(&rotationLeftArrowBtnImg);
00903   rotationLeftArrowBtn.SetImageOver(&rotationLeftArrowBtnImgOver);
00904   rotationLeftArrowBtn.SetSoundOver(btnSoundOver);
00905   rotationLeftArrowBtn.SetTrigger(trigA);
00906   rotationLeftArrowBtn.SetEffectGrow();
00907 
00908   // ROTATION RIGHT ARROW BUTTON
00909   GuiButton rotationRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00910   GuiText rotationRightArrowBtnTxt(">", 22, blackColor);
00911   GuiText rotationRightArrowBtnTxtOver(">", 22, helpTxtColor);
00912   GuiImage rotationRightArrowBtnImg(btnData40x40Square);
00913   GuiImage rotationRightArrowBtnImgOver(btnData40x40SquareOver);
00914 
00915   rotationRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00916   rotationRightArrowBtn.SetPosition(80, 60 + 1 * 40);
00917   rotationRightArrowBtn.SetLabel(&rotationRightArrowBtnTxt);
00918   rotationRightArrowBtn.SetLabelOver(&rotationRightArrowBtnTxtOver);
00919   rotationRightArrowBtn.SetImage(&rotationRightArrowBtnImg);
00920   rotationRightArrowBtn.SetImageOver(&rotationRightArrowBtnImgOver);
00921   rotationRightArrowBtn.SetSoundOver(btnSoundOver);
00922   rotationRightArrowBtn.SetTrigger(trigA);
00923   rotationRightArrowBtn.SetEffectGrow();
00924 
00925   // ROTATION TEXT
00926   GuiText rotationTxt(rotateStr[rotation[player]], 22, blackColor);
00927   rotationTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00928   rotationTxt.SetPosition(0, 60 + PADDING_TOP + 1 * 40);
00929 
00930   //---
00931   // SHADOW TEXT BUTTON
00932   GuiButton shadowTxtBtn((6 + 1) * 11, 22);
00933   GuiText shadowTxtBtnTxt("guide:", 22, blackColor);
00934   GuiText shadowTxtBtnTxtOver("guide:", 22, helpTxtColor);
00935 
00936   shadowTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00937   shadowTxtBtn.SetPosition(20, 60 + PADDING_TOP + 2 * 40);
00938   shadowTxtBtn.SetLabel(&shadowTxtBtnTxt);
00939   shadowTxtBtn.SetLabelOver(&shadowTxtBtnTxtOver);
00940   shadowTxtBtn.SetSoundOver(btnSoundOver);
00941   shadowTxtBtn.SetTrigger(trigA);
00942 
00943   // SHADOW LEFT ARROW BUTTON
00944   GuiButton shadowLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00945   GuiText shadowLeftArrowBtnTxt("<", 22, blackColor);
00946   GuiText shadowLeftArrowBtnTxtOver("<", 22, helpTxtColor);
00947   GuiImage shadowLeftArrowBtnImg(btnData40x40Square);
00948   GuiImage shadowLeftArrowBtnImgOver(btnData40x40SquareOver);
00949 
00950   shadowLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00951   shadowLeftArrowBtn.SetPosition(-80, 60 + 2 * 40);
00952   shadowLeftArrowBtn.SetLabel(&shadowLeftArrowBtnTxt);
00953   shadowLeftArrowBtn.SetLabelOver(&shadowLeftArrowBtnTxtOver);
00954   shadowLeftArrowBtn.SetImage(&shadowLeftArrowBtnImg);
00955   shadowLeftArrowBtn.SetImageOver(&shadowLeftArrowBtnImgOver);
00956   shadowLeftArrowBtn.SetSoundOver(btnSoundOver);
00957   shadowLeftArrowBtn.SetTrigger(trigA);
00958   shadowLeftArrowBtn.SetEffectGrow();
00959 
00960   // SHADOW RIGHT ARROW BUTTON
00961   GuiButton shadowRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00962   GuiText shadowRightArrowBtnTxt(">", 22, blackColor);
00963   GuiText shadowRightArrowBtnTxtOver(">", 22, helpTxtColor);
00964   GuiImage shadowRightArrowBtnImg(btnData40x40Square);
00965   GuiImage shadowRightArrowBtnImgOver(btnData40x40SquareOver);
00966 
00967   shadowRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00968   shadowRightArrowBtn.SetPosition(80, 60 + 2 * 40);
00969   shadowRightArrowBtn.SetLabel(&shadowRightArrowBtnTxt);
00970   shadowRightArrowBtn.SetLabelOver(&shadowRightArrowBtnTxtOver);
00971   shadowRightArrowBtn.SetImage(&shadowRightArrowBtnImg);
00972   shadowRightArrowBtn.SetImageOver(&shadowRightArrowBtnImgOver);
00973   shadowRightArrowBtn.SetSoundOver(btnSoundOver);
00974   shadowRightArrowBtn.SetTrigger(trigA);
00975   shadowRightArrowBtn.SetEffectGrow();
00976 
00977   // SHADOW TEXT
00978   GuiText shadowTxt(guideStr[guide[player]], 22, blackColor);
00979   shadowTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
00980   shadowTxt.SetPosition(0, 60 + PADDING_TOP + 2 * 40);
00981 
00982   //---
00983   // PREVIEW TEXT BUTTON
00984   GuiButton previewTxtBtn((9 + 1) * 11, 22);
00985   GuiText previewTxtBtnTxt("preview:", 22, blackColor);
00986   GuiText previewTxtBtnTxtOver("preview:", 22, helpTxtColor);
00987 
00988   previewTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00989   previewTxtBtn.SetPosition(20, 60 + PADDING_TOP + 3 * 40);
00990   previewTxtBtn.SetLabel(&previewTxtBtnTxt);
00991   previewTxtBtn.SetLabelOver(&previewTxtBtnTxtOver);
00992   previewTxtBtn.SetSoundOver(btnSoundOver);
00993   previewTxtBtn.SetTrigger(trigA);
00994 
00995   // PREVIEW LEFT ARROW BUTTON
00996   GuiButton previewLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00997   GuiText previewLeftArrowBtnTxt("<", 22, blackColor);
00998   GuiText previewLeftArrowBtnTxtOver("<", 22, helpTxtColor);
00999   GuiImage previewLeftArrowBtnImg(btnData40x40Square);
01000   GuiImage previewLeftArrowBtnImgOver(btnData40x40SquareOver);
01001 
01002   previewLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01003   previewLeftArrowBtn.SetPosition(-80, 60 + 3 * 40);
01004   previewLeftArrowBtn.SetLabel(&previewLeftArrowBtnTxt);
01005   previewLeftArrowBtn.SetLabelOver(&previewLeftArrowBtnTxtOver);
01006   previewLeftArrowBtn.SetImage(&previewLeftArrowBtnImg);
01007   previewLeftArrowBtn.SetImageOver(&previewLeftArrowBtnImgOver);
01008   previewLeftArrowBtn.SetSoundOver(btnSoundOver);
01009   previewLeftArrowBtn.SetTrigger(trigA);
01010   previewLeftArrowBtn.SetEffectGrow();
01011 
01012   // PREVIEW RIGHT ARROW BUTTON
01013   GuiButton previewRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01014   GuiText previewRightArrowBtnTxt(">", 22, blackColor);
01015   GuiText previewRightArrowBtnTxtOver(">", 22, helpTxtColor);
01016   GuiImage previewRightArrowBtnImg(btnData40x40Square);
01017   GuiImage previewRightArrowBtnImgOver(btnData40x40SquareOver);
01018 
01019   previewRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01020   previewRightArrowBtn.SetPosition(80, 60 + 3 * 40);
01021   previewRightArrowBtn.SetLabel(&previewRightArrowBtnTxt);
01022   previewRightArrowBtn.SetLabelOver(&previewRightArrowBtnTxtOver);
01023   previewRightArrowBtn.SetImage(&previewRightArrowBtnImg);
01024   previewRightArrowBtn.SetImageOver(&previewRightArrowBtnImgOver);
01025   previewRightArrowBtn.SetSoundOver(btnSoundOver);
01026   previewRightArrowBtn.SetTrigger(trigA);
01027   previewRightArrowBtn.SetEffectGrow();
01028 
01029   // PREVIEW TEXT
01030   GuiText previewTxt(isPreviewEnabled[player] ? "on" : "off", 22, blackColor);
01031   previewTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01032   previewTxt.SetPosition(0, 60 + PADDING_TOP + 3 * 40);
01033 
01034   //---
01035   // SHAKE TEXT BUTTON
01036   GuiButton shakeTxtBtn((7 + 1) * 11, 22);
01037   GuiText shakeTxtBtnTxt("shake:", 22, blackColor);
01038   GuiText shakeTxtBtnTxtOver("shake:", 22, helpTxtColor);
01039 
01040   shakeTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01041   shakeTxtBtn.SetPosition(20, 60 + PADDING_TOP + 4 * 40);
01042   shakeTxtBtn.SetLabel(&shakeTxtBtnTxt);
01043   shakeTxtBtn.SetLabelOver(&shakeTxtBtnTxtOver);
01044   shakeTxtBtn.SetSoundOver(btnSoundOver);
01045   shakeTxtBtn.SetTrigger(trigA);
01046 
01047   // SHAKE LEFT ARROW BUTTON
01048   GuiButton shakeLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01049   GuiText shakeLeftArrowBtnTxt("<", 22, blackColor);
01050   GuiText shakeLeftArrowBtnTxtOver("<", 22, helpTxtColor);
01051   GuiImage shakeLeftArrowBtnImg(btnData40x40Square);
01052   GuiImage shakeLeftArrowBtnImgOver(btnData40x40SquareOver);
01053 
01054   shakeLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01055   shakeLeftArrowBtn.SetPosition(-80, 60 + 4 * 40);
01056   shakeLeftArrowBtn.SetLabel(&shakeLeftArrowBtnTxt);
01057   shakeLeftArrowBtn.SetLabelOver(&shakeLeftArrowBtnTxtOver);
01058   shakeLeftArrowBtn.SetImage(&shakeLeftArrowBtnImg);
01059   shakeLeftArrowBtn.SetImageOver(&shakeLeftArrowBtnImgOver);
01060   shakeLeftArrowBtn.SetSoundOver(btnSoundOver);
01061   shakeLeftArrowBtn.SetTrigger(trigA);
01062   shakeLeftArrowBtn.SetEffectGrow();
01063 
01064   // SHAKE RIGHT ARROW BUTTON
01065   GuiButton shakeRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01066   GuiText shakeRightArrowBtnTxt(">", 22, blackColor);
01067   GuiText shakeRightArrowBtnTxtOver(">", 22, helpTxtColor);
01068   GuiImage shakeRightArrowBtnImg(btnData40x40Square);
01069   GuiImage shakeRightArrowBtnImgOver(btnData40x40SquareOver);
01070 
01071   shakeRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01072   shakeRightArrowBtn.SetPosition(80, 60 + 4 * 40);
01073   shakeRightArrowBtn.SetLabel(&shakeRightArrowBtnTxt);
01074   shakeRightArrowBtn.SetLabelOver(&shakeRightArrowBtnTxtOver);
01075   shakeRightArrowBtn.SetImage(&shakeRightArrowBtnImg);
01076   shakeRightArrowBtn.SetImageOver(&shakeRightArrowBtnImgOver);
01077   shakeRightArrowBtn.SetSoundOver(btnSoundOver);
01078   shakeRightArrowBtn.SetTrigger(trigA);
01079   shakeRightArrowBtn.SetEffectGrow();
01080 
01081   // SHAKE TEXT
01082   GuiText shakeTxt(isShakeEnabled[player] ? "on" : "off", 22, blackColor);
01083   shakeTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01084   shakeTxt.SetPosition(0, 60 + PADDING_TOP + 4 * 40);
01085 
01086   //---
01087   // CONFIRM BUTTON
01088   GuiButton confirmBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01089   GuiText confirmBtnTxt("OK", 22, (GXColor){0, 0, 255, 255});
01090   GuiImage confirmBtnImg(btnData40x40Square);
01091   GuiImage confirmBtnImgOver(btnData40x40SquareOver);
01092 
01093   confirmBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
01094   confirmBtn.SetPosition(-10, -10);
01095   confirmBtn.SetLabel(&confirmBtnTxt);
01096   confirmBtn.SetImage(&confirmBtnImg);
01097   confirmBtn.SetImageOver(&confirmBtnImgOver);
01098   confirmBtn.SetSoundOver(btnSoundOver);
01099   confirmBtn.SetTrigger(trigA);
01100   confirmBtn.SetEffectGrow();
01101 
01102   // CANCEL BUTTON
01103   GuiButton cancelBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01104   GuiText cancelBtnTxt("X", 22, (GXColor){255, 0, 0, 255});
01105   GuiImage cancelBtnImg(btnData40x40Square);
01106   GuiImage cancelBtnImgOver(btnData40x40SquareOver);
01107 
01108   cancelBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01109   cancelBtn.SetPosition(-10, 10);
01110   cancelBtn.SetLabel(&cancelBtnTxt);
01111   cancelBtn.SetImage(&cancelBtnImg);
01112   cancelBtn.SetImageOver(&cancelBtnImgOver);
01113   cancelBtn.SetSoundOver(btnSoundOver);
01114   cancelBtn.SetTrigger(trigA);
01115   cancelBtn.SetEffectGrow();
01116 
01117   // HELP BUTTON
01118   GuiButton helpBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01119   GuiText helpBtnTxt("?", 22, helpTxtColor);
01120   GuiImage helpBtnImg(btnData40x40Square);
01121   GuiImage helpBtnImgOver(btnData40x40SquareOver);
01122 
01123   helpBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
01124   helpBtn.SetPosition(10, -10);
01125   helpBtn.SetLabel(&helpBtnTxt);
01126   helpBtn.SetImage(&helpBtnImg);
01127   helpBtn.SetImageOver(&helpBtnImgOver);
01128   helpBtn.SetSoundOver(btnSoundOver);
01129   helpBtn.SetTrigger(trigA);
01130   helpBtn.SetEffectGrow();
01131 
01132   // Populate the window.
01133   promptWindow.Append(&profilesBgImg);
01134   promptWindow.Append(&titleTxt);
01135   promptWindow.Append(&playerLeftArrowBtn);
01136   promptWindow.Append(&playerRightArrowBtn);
01137   promptWindow.Append(&playerTxt);
01138 
01139   promptWindow.Append(&rotationTxtBtn);
01140   promptWindow.Append(&rotationLeftArrowBtn);
01141   promptWindow.Append(&rotationRightArrowBtn);
01142   promptWindow.Append(&rotationTxt);
01143 
01144   promptWindow.Append(&shakeTxtBtn);
01145   promptWindow.Append(&shakeLeftArrowBtn);
01146   promptWindow.Append(&shakeRightArrowBtn);
01147   promptWindow.Append(&shakeTxt);
01148 
01149   promptWindow.Append(&shadowTxtBtn);
01150   promptWindow.Append(&shadowLeftArrowBtn);
01151   promptWindow.Append(&shadowRightArrowBtn);
01152   promptWindow.Append(&shadowTxt);
01153 
01154   promptWindow.Append(&previewTxtBtn);
01155   promptWindow.Append(&previewLeftArrowBtn);
01156   promptWindow.Append(&previewRightArrowBtn);
01157   promptWindow.Append(&previewTxt);
01158 
01159   promptWindow.Append(&confirmBtn);
01160   promptWindow.Append(&cancelBtn);
01161   promptWindow.Append(&helpBtn);
01162 
01163   promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
01164   HaltGui();
01165   // This sets the state for all child elements, including child windows; 
01166   // that is why we disable the state first, then add the child window.
01167   mainWindow->SetState(STATE_DISABLED);
01168   mainWindow->Append(&promptWindow);
01169   mainWindow->ChangeFocus(&promptWindow);
01170   ResumeGui();
01171 
01172   while (true)
01173   {
01174     usleep(THREAD_SLEEP);
01175 
01176     if (confirmBtn.GetState() == STATE_CLICKED)
01177     {
01178       for (int i = 0; i < MAX_PLAYERS; ++i)
01179       {
01180         g_players[i].rotation         = rotation[i];
01181         g_players[i].guide            = guide[i];
01182         g_players[i].isShakeEnabled   = isShakeEnabled[i];
01183         g_players[i].isPreviewEnabled = isPreviewEnabled[i];
01184       }
01185 
01186       break;
01187     }
01188     else if (cancelBtn.GetState() == STATE_CLICKED)
01189     {
01190       break;
01191     }
01192     else if (helpBtn.GetState() == STATE_CLICKED)
01193     {
01194       helpBtn.ResetState();
01195 
01196       WindowPrompt(
01197         "HINT",
01198         "The option menu labels are clickable. Click on them for more information!",
01199         "OK",
01200         NULL,
01201         &promptWindow);
01202     }
01203     // player buttons
01204     else if (playerLeftArrowBtn.GetState() == STATE_CLICKED)
01205     {
01206       HaltGui();
01207       playerLeftArrowBtn.SetState(STATE_SELECTED);
01208       player--;
01209       if (player < 0)
01210         player = MAX_PLAYERS - 1;
01211 
01212       sprintf(playerBuf + 7, "%d", player + 1);
01213       playerTxt.SetText(playerBuf);
01214       rotationTxt.SetText(rotateStr[rotation[player]]);
01215       shadowTxt.SetText(guideStr[guide[player]]);
01216       shakeTxt.SetText(isShakeEnabled[player] ? "on" : "off");
01217       previewTxt.SetText(isPreviewEnabled[player] ? "on" : "off");
01218       ResumeGui();
01219     }
01220     else if (playerRightArrowBtn.GetState() == STATE_CLICKED)
01221     {
01222       HaltGui();
01223       playerRightArrowBtn.SetState(STATE_SELECTED);
01224       player++;
01225       if (player >= MAX_PLAYERS)
01226         player = 0;
01227 
01228       sprintf(playerBuf + 7, "%d", player + 1);
01229       playerTxt.SetText(playerBuf);
01230       rotationTxt.SetText(rotateStr[rotation[player]]);
01231       shadowTxt.SetText(guideStr[guide[player]]);
01232       shakeTxt.SetText(isShakeEnabled[player] ? "on" : "off");
01233       previewTxt.SetText(isPreviewEnabled[player] ? "on" : "off");
01234       ResumeGui();
01235     }
01236     // rotation
01237     else if (rotationTxtBtn.GetState() == STATE_CLICKED)
01238     {
01239       rotationTxtBtn.ResetState();
01240 
01241       WindowPrompt(
01242         "ROTATION",
01243         "The direction in which the tetris cylinder rotates. "
01244         "Set it to 'reverse' to reverse the direction. "
01245         "Set it to 'piece' to instead move the piece.",
01246         "OK",
01247         NULL,
01248         &promptWindow);
01249     }
01250     else if (rotationLeftArrowBtn.GetState() == STATE_CLICKED 
01251              || rotationRightArrowBtn.GetState() == STATE_CLICKED)
01252     {
01253       HaltGui();
01254       int rot = rotation[player];
01255       if (rotationLeftArrowBtn.GetState() == STATE_CLICKED)
01256         --rot;
01257       else
01258         ++rot;
01259 
01260       if (rot == ROTATE_SIZE)
01261         rot = 0;
01262       else if (rot < 0)
01263         rot = ROTATE_SIZE - 1;
01264 
01265       rotation[player] = rot;
01266       rotationTxt.SetText(rotateStr[rotation[player]]);
01267       rotationLeftArrowBtn.ResetState();
01268       rotationRightArrowBtn.ResetState();
01269       ResumeGui();
01270     }
01271     // shake
01272     else if (shakeTxtBtn.GetState() == STATE_CLICKED)
01273     {
01274       shakeTxtBtn.ResetState();
01275 
01276       WindowPrompt(
01277         "SHAKE",
01278         "Allows tetris pieces to be dropped by performing a vertical shake "
01279         "motion with the wiimote.",
01280         "OK",
01281         NULL,
01282         &promptWindow);
01283     }
01284     else if (shakeLeftArrowBtn.GetState() == STATE_CLICKED 
01285              || shakeRightArrowBtn.GetState() == STATE_CLICKED)
01286     {
01287       HaltGui();
01288       shakeLeftArrowBtn.ResetState();
01289       shakeRightArrowBtn.ResetState();
01290       isShakeEnabled[player] = !isShakeEnabled[player];
01291       shakeTxt.SetText(isShakeEnabled[player] ? "on" : "off");
01292       ResumeGui();
01293     }
01294     // shadow
01295     else if (shadowTxtBtn.GetState() == STATE_CLICKED)
01296     {
01297       shadowTxtBtn.ResetState();
01298 
01299       WindowPrompt(
01300         "GUIDE",
01301         "The guide mode. 'Shadow' mode shows where the current piece will drop. "
01302         "'Line' mode shows a guide line.",
01303         "OK",
01304         NULL,
01305         &promptWindow);
01306     }
01307     else if (shadowLeftArrowBtn.GetState() == STATE_CLICKED 
01308              || shadowRightArrowBtn.GetState() == STATE_CLICKED)
01309     {
01310       HaltGui();
01311       int gd = guide[player];
01312       if (shadowLeftArrowBtn.GetState() == STATE_CLICKED)
01313         --gd;
01314       else
01315         ++gd;
01316 
01317       if (gd == GUIDE_SIZE)
01318         gd = 0;
01319       else if (gd < 0)
01320         gd = GUIDE_SIZE - 1;
01321       
01322       guide[player] = gd;
01323       shadowTxt.SetText(guideStr[guide[player]]);
01324       shadowLeftArrowBtn.ResetState();
01325       shadowRightArrowBtn.ResetState();
01326       ResumeGui();
01327     }
01328     // preview
01329     else if (previewTxtBtn.GetState() == STATE_CLICKED)
01330     {
01331       previewTxtBtn.ResetState();
01332 
01333       WindowPrompt(
01334         "PREVIEW",
01335         "Shows the next piece.",
01336         "OK",
01337         NULL,
01338         &promptWindow);
01339     }
01340     else if (previewLeftArrowBtn.GetState() == STATE_CLICKED 
01341              || previewRightArrowBtn.GetState() == STATE_CLICKED)
01342     {
01343       HaltGui();
01344       previewLeftArrowBtn.ResetState();
01345       previewRightArrowBtn.ResetState();
01346       isPreviewEnabled[player] = !isPreviewEnabled[player];
01347       previewTxt.SetText(isPreviewEnabled[player] ? "on" : "off");
01348       ResumeGui();
01349     }
01350   }
01351 
01352   promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
01353   while(promptWindow.GetEffect() > 0) usleep(THREAD_SLEEP);
01354   HaltGui();
01355   mainWindow->Remove(&promptWindow);
01356   mainWindow->SetState(STATE_DEFAULT);
01357   ResumeGui();
01358 }
01359 
01360 /// Launches the powerups popup.
01361 void TCYC_MenuPowerupsPopup(GuiWindow *parentWindow, 
01362                             vector<bool> &isPowerupEnabled,
01363                             PowerupId powerupStartQueue[MAX_ACQUIRED_POWERUPS])
01364 {
01365   GXColor helpTxtColor = (GXColor){0, 170, 0, 255};
01366   GXColor blackColor = (GXColor){0, 0, 0, 255};
01367 
01368   vector<bool> tmpIsPowerupEnabled(isPowerupEnabled);
01369 
01370   PowerupId tmpPowerupStartQueue[MAX_ACQUIRED_POWERUPS];
01371   memcpy(tmpPowerupStartQueue, powerupStartQueue, sizeof(tmpPowerupStartQueue));
01372 
01373   // popup window
01374   GuiWindow window(screenwidth - 100, screenheight - 100);
01375   window.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
01376   window.SetPosition(0, 0);
01377   window.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
01378 
01379   // background image
01380   GuiImage bgImg(screenwidth - 100, screenheight - 100, (GXColor){150, 150, 150, 255});
01381 
01382   // title text
01383   GuiText titleTxt("Powerups", 30, blackColor);
01384   titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01385   titleTxt.SetPosition(0, 15);
01386 
01387   // CONFIRM BUTTON
01388   GuiButton confirmBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01389   GuiText confirmBtnTxt("OK", 22, (GXColor){0, 0, 255, 255});
01390   GuiImage confirmBtnImg(btnData40x40Square);
01391   GuiImage confirmBtnImgOver(btnData40x40SquareOver);
01392 
01393   confirmBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
01394   confirmBtn.SetPosition(-10, -10);
01395   confirmBtn.SetLabel(&confirmBtnTxt);
01396   confirmBtn.SetImage(&confirmBtnImg);
01397   confirmBtn.SetImageOver(&confirmBtnImgOver);
01398   confirmBtn.SetSoundOver(btnSoundOver);
01399   confirmBtn.SetTrigger(trigA);
01400   confirmBtn.SetEffectGrow();
01401 
01402   // CANCEL BUTTON
01403   GuiButton cancelBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01404   GuiText cancelBtnTxt("X", 22, (GXColor){255, 0, 0, 255});
01405   GuiImage cancelBtnImg(btnData40x40Square);
01406   GuiImage cancelBtnImgOver(btnData40x40SquareOver);
01407 
01408   cancelBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01409   cancelBtn.SetPosition(-10, 10);
01410   cancelBtn.SetLabel(&cancelBtnTxt);
01411   cancelBtn.SetImage(&cancelBtnImg);
01412   cancelBtn.SetImageOver(&cancelBtnImgOver);
01413   cancelBtn.SetSoundOver(btnSoundOver);
01414   cancelBtn.SetTrigger(trigA);
01415   cancelBtn.SetEffectGrow();
01416 
01417   // HELP BUTTON
01418   GuiButton helpBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01419   GuiText helpBtnTxt("?", 22, helpTxtColor);
01420   GuiImage helpBtnImg(btnData40x40Square);
01421   GuiImage helpBtnImgOver(btnData40x40SquareOver);
01422 
01423   helpBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
01424   helpBtn.SetPosition(10, -10);
01425   helpBtn.SetLabel(&helpBtnTxt);
01426   helpBtn.SetImage(&helpBtnImg);
01427   helpBtn.SetImageOver(&helpBtnImgOver);
01428   helpBtn.SetSoundOver(btnSoundOver);
01429   helpBtn.SetTrigger(trigA);
01430   helpBtn.SetEffectGrow();
01431 
01432   // ALL ON BUTTON
01433   GuiButton allOnBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01434   GuiText allOnTxt("on", 22, blackColor);
01435   GuiImage allOnImg(btnData40x40Square);
01436   GuiImage allOnImgOver(btnData40x40SquareOver);
01437 
01438   allOnBtn.SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
01439   allOnBtn.SetPosition(-btnData40x40Square->GetWidth() / 2, -10);
01440   allOnBtn.SetLabel(&allOnTxt);
01441   allOnBtn.SetImage(&allOnImg);
01442   allOnBtn.SetImageOver(&allOnImgOver);
01443   allOnBtn.SetSoundOver(btnSoundOver);
01444   allOnBtn.SetTrigger(trigA);
01445   allOnBtn.SetEffectGrow();
01446 
01447   // ALL OFF BUTTON
01448   GuiButton allOffBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01449   GuiText allOffTxt("off", 22, blackColor);
01450   GuiImage allOffImg(btnData40x40Square);
01451   GuiImage allOffImgOver(btnData40x40SquareOver);
01452 
01453   allOffBtn.SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
01454   allOffBtn.SetPosition(btnData40x40Square->GetWidth() / 2, -10);
01455   allOffBtn.SetLabel(&allOffTxt);
01456   allOffBtn.SetImage(&allOffImg);
01457   allOffBtn.SetImageOver(&allOffImgOver);
01458   allOffBtn.SetSoundOver(btnSoundOver);
01459   allOffBtn.SetTrigger(trigA);
01460   allOffBtn.SetEffectGrow();
01461 
01462   // SCROLL UP BUTTON
01463   GuiButton scrollUpBtn(upArrowImgData->GetWidth(), upArrowImgData->GetHeight());
01464   GuiImage scrollUpImg(upArrowImgData);
01465   GuiImage scrollUpImgOver(upArrowOverImgData);
01466 
01467   scrollUpBtn.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
01468   scrollUpBtn.SetPosition(-10, -upArrowImgData->GetHeight() / 2 - 10);
01469   scrollUpBtn.SetImage(&scrollUpImg);
01470   scrollUpBtn.SetImageOver(&scrollUpImgOver);
01471   scrollUpBtn.SetSoundOver(btnSoundOver);
01472   scrollUpBtn.SetTrigger(trigA);
01473   scrollUpBtn.SetEffectGrow();
01474 
01475   // SCROLL DOWN BUTTON
01476   GuiButton scrollDownBtn(downArrowImgData->GetWidth(), downArrowImgData->GetHeight());
01477   GuiImage scrollDownImg(downArrowImgData);
01478   GuiImage scrollDownImgOver(downArrowOverImgData);
01479 
01480   scrollDownBtn.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
01481   scrollDownBtn.SetPosition(-10, downArrowImgData->GetHeight() / 2 + 10);
01482   scrollDownBtn.SetImage(&scrollDownImg);
01483   scrollDownBtn.SetImageOver(&scrollDownImgOver);
01484   scrollDownBtn.SetSoundOver(btnSoundOver);
01485   scrollDownBtn.SetTrigger(trigA);
01486   scrollDownBtn.SetEffectGrow();
01487 
01488   // add buttons to window
01489   window.Append(&bgImg);
01490   window.Append(&titleTxt);
01491   window.Append(&confirmBtn);
01492   window.Append(&cancelBtn);
01493   window.Append(&helpBtn);
01494   window.Append(&allOnBtn);
01495   window.Append(&allOffBtn);
01496   window.Append(&scrollUpBtn);
01497   window.Append(&scrollDownBtn);
01498 
01499   // POWERUP BUTTONS
01500   int top = 60;
01501 
01502   vector<GuiButton> powerupIconBtns(g_totalPowerups);
01503   vector<GuiImage> powerupIconImgs(g_totalPowerups);
01504 
01505   vector<GuiButton> powerupOnBtns(g_totalPowerups);
01506   vector<GuiText> powerupOnTxts(g_totalPowerups);
01507   vector<GuiImage> powerupOnImgs(g_totalPowerups);
01508   vector<GuiImage> powerupOnImgsOver(g_totalPowerups);
01509 
01510   vector<GuiButton> powerupHelpBtns(g_totalPowerups);
01511   vector<GuiText> powerupHelpTxts(g_totalPowerups);
01512   vector<GuiImage> powerupHelpImgs(g_totalPowerups);
01513   vector<GuiImage> powerupHelpImgsOver(g_totalPowerups);
01514 
01515   for (int i = 0; i < g_totalPowerups; ++i)
01516   {
01517     // powerup icon buttons
01518     powerupIconImgs[i].SetImage(PowerupUtils::GetImageData((PowerupId)i));
01519     powerupIconImgs[i].SetDisplaySize(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01520 
01521     powerupIconBtns[i].SetSize(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01522     powerupIconBtns[i].SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01523     powerupIconBtns[i].SetPosition(20, top + i * btnData40x40Square->GetHeight());
01524     powerupIconBtns[i].SetImage(&powerupIconImgs[i]);
01525     powerupIconBtns[i].SetSoundOver(btnSoundOver);
01526     powerupIconBtns[i].SetTrigger(trigA);
01527     powerupIconBtns[i].SetEffectGrow();
01528 
01529     // powerup on/off buttons
01530     powerupOnTxts[i].SetText(tmpIsPowerupEnabled[i] ? "on" : "off");
01531     powerupOnTxts[i].SetFontSize(22);
01532     powerupOnTxts[i].SetColor(blackColor);
01533     powerupOnImgs[i].SetImage(btnData40x40Square);
01534     powerupOnImgsOver[i].SetImage(btnData40x40SquareOver);
01535 
01536     powerupOnBtns[i].SetSize(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01537     powerupOnBtns[i].SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01538     powerupOnBtns[i].SetPosition(20 + btnData40x40Square->GetWidth(), top + i * btnData40x40Square->GetHeight());
01539     powerupOnBtns[i].SetLabel(&powerupOnTxts[i]);
01540     powerupOnBtns[i].SetImage(&powerupOnImgs[i]);
01541     powerupOnBtns[i].SetImageOver(&powerupOnImgsOver[i]);
01542     powerupOnBtns[i].SetSoundOver(btnSoundOver);
01543     powerupOnBtns[i].SetTrigger(trigA);
01544     powerupOnBtns[i].SetEffectGrow();
01545 
01546     // powerup help buttons
01547     powerupHelpTxts[i].SetText("?");
01548     powerupHelpTxts[i].SetFontSize(22);
01549     powerupHelpTxts[i].SetColor(helpTxtColor);
01550     powerupHelpImgs[i].SetImage(btnData40x40Square);
01551     powerupHelpImgsOver[i].SetImage(btnData40x40SquareOver);
01552 
01553     powerupHelpBtns[i].SetSize(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01554     powerupHelpBtns[i].SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01555     powerupHelpBtns[i].SetPosition(20 + 2 * btnData40x40Square->GetWidth(), top + i * btnData40x40Square->GetHeight());
01556     powerupHelpBtns[i].SetLabel(&powerupHelpTxts[i]);
01557     powerupHelpBtns[i].SetImage(&powerupHelpImgs[i]);
01558     powerupHelpBtns[i].SetImageOver(&powerupHelpImgsOver[i]);
01559     powerupHelpBtns[i].SetSoundOver(btnSoundOver);
01560     powerupHelpBtns[i].SetTrigger(trigA);
01561     powerupHelpBtns[i].SetEffectGrow();
01562 
01563     int state = STATE_DEFAULT;
01564     bool visible = true;
01565     int ypos = top + i * btnData40x40Square->GetHeight();
01566 
01567     // only show 6 powerups at a time
01568     if (ypos < 60 || ypos > 60 + 5 * 40)
01569     {
01570       state = STATE_DISABLED;
01571       visible = false;
01572     }
01573 
01574     powerupIconBtns[i].SetState(state);
01575     powerupIconBtns[i].SetVisible(visible);
01576     powerupOnBtns[i].SetState(state);
01577     powerupOnBtns[i].SetVisible(visible);
01578     powerupHelpBtns[i].SetState(state);
01579     powerupHelpBtns[i].SetVisible(visible);
01580 
01581     window.Append(&powerupIconBtns[i]);
01582     window.Append(&powerupOnBtns[i]);
01583     window.Append(&powerupHelpBtns[i]);
01584   }
01585 
01586   // POWERUP QUEUE BUTTONS
01587   GuiButton powerupQueueBtns[MAX_ACQUIRED_POWERUPS];
01588   GuiImage powerupQueueImgs[MAX_ACQUIRED_POWERUPS];
01589 
01590   int y = 0;
01591   for (int i = 0; i < MAX_ACQUIRED_POWERUPS; ++i, y += POWERUP_WIDTH)
01592   {
01593     powerupQueueImgs[i].SetImage(tmpPowerupStartQueue[i] == POWERUP_ID_NONE ? 
01594       btnData40x40Square : PowerupUtils::GetImageData(tmpPowerupStartQueue[i]));
01595     powerupQueueImgs[i].SetDisplaySize(POWERUP_WIDTH, POWERUP_WIDTH);
01596 
01597     powerupQueueBtns[i].SetSize(POWERUP_WIDTH, POWERUP_WIDTH);
01598     powerupQueueBtns[i].SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01599     powerupQueueBtns[i].SetPosition(-60, 60 + y);
01600     powerupQueueBtns[i].SetImage(powerupQueueImgs + i);
01601     powerupQueueBtns[i].SetSoundOver(btnSoundOver);
01602     powerupQueueBtns[i].SetTrigger(trigA);
01603     powerupQueueBtns[i].SetEffectGrow();
01604 
01605     window.Append(powerupQueueBtns + i);
01606   }
01607 
01608   HaltGui();
01609   // This sets the state for all child elements, including child windows; 
01610   // that is why we disable the state first, then add the child window.
01611   parentWindow->DisableChildren();
01612   parentWindow->Append(&window);
01613   ResumeGui();
01614 
01615   while (true)
01616   {
01617     usleep(THREAD_SLEEP);
01618 
01619     if (confirmBtn.GetState() == STATE_CLICKED)
01620     {
01621       isPowerupEnabled = tmpIsPowerupEnabled;
01622       memcpy(powerupStartQueue, tmpPowerupStartQueue, sizeof(tmpPowerupStartQueue));
01623       break;
01624     }
01625     else if (cancelBtn.GetState() == STATE_CLICKED)
01626     {
01627       break;
01628     }
01629     else if (helpBtn.GetState() == STATE_CLICKED)
01630     {
01631       helpBtn.ResetState();
01632 
01633       WindowPrompt(
01634         "HINT",
01635         "Click powerup icon to add it to initial powerup queue. Click "
01636         "icon in queue to remove it. Powerups only appear in "
01637         "game if turned on.",
01638         "OK",
01639         NULL,
01640         &window);
01641     }
01642     else if (allOnBtn.GetState() == STATE_CLICKED
01643              || allOffBtn.GetState() == STATE_CLICKED)
01644     {
01645       bool enabled = (allOnBtn.GetState() == STATE_CLICKED);
01646       allOnBtn.ResetState();
01647       allOffBtn.ResetState();
01648       for (int i = 0; i < g_totalPowerups; ++i)
01649       {
01650         tmpIsPowerupEnabled[i] = enabled;
01651         powerupOnTxts[i].SetText(enabled ? "on" : "off");
01652       }
01653     }
01654     else if (scrollUpBtn.GetState() == STATE_CLICKED
01655              || scrollDownBtn.GetState() == STATE_CLICKED)
01656     {
01657       bool scrollUp = (scrollUpBtn.GetState() == STATE_CLICKED);
01658       scrollUpBtn.ResetState();
01659       scrollDownBtn.ResetState();
01660       if (scrollUp)
01661       {
01662         top += 2 * 40; // scroll 2 powerups at a time
01663         if (top > 60)
01664           top = 60;
01665       }
01666       else
01667       {
01668         top -= 2 * 40; // scroll 2 powerups at a time
01669         int min = 60 - (g_totalPowerups - 2) * 40;
01670         if (top < min)
01671           top = min; // always show at least 2 powerups
01672       }
01673       for (int i = 0; i < g_totalPowerups; ++i)
01674       {
01675         int ypos = top + i * btnData40x40Square->GetHeight();
01676         powerupIconBtns[i].SetPosition(20, ypos);
01677         powerupOnBtns[i].SetPosition(20 + btnData40x40Square->GetWidth(), ypos);
01678         powerupHelpBtns[i].SetPosition(20 + 2 * btnData40x40Square->GetWidth(), ypos);
01679 
01680         int state = STATE_DEFAULT;
01681         bool visible = true;
01682 
01683         // only show 6 powerups at a time
01684         if (ypos < 60 || ypos > 60 + 5 * 40)
01685         {
01686           state = STATE_DISABLED;
01687           visible = false;
01688         }
01689 
01690         powerupIconBtns[i].SetState(state);
01691         powerupIconBtns[i].SetVisible(visible);
01692         powerupOnBtns[i].SetState(state);
01693         powerupOnBtns[i].SetVisible(visible);
01694         powerupHelpBtns[i].SetState(state);
01695         powerupHelpBtns[i].SetVisible(visible);
01696       }
01697     }
01698 
01699     for (int i = 0; i < g_totalPowerups; ++i)
01700     {
01701       if (powerupIconBtns[i].GetState() == STATE_CLICKED)
01702       {
01703         powerupIconBtns[i].ResetState();
01704         // Add powerup to queue.
01705         for (int j = 0; j < MAX_ACQUIRED_POWERUPS; ++j)
01706         {
01707           if (tmpPowerupStartQueue[j] == POWERUP_ID_NONE)
01708           {
01709             PowerupUtils::GetSound((PowerupId)i)->Play();
01710             tmpPowerupStartQueue[j] = (PowerupId)i;
01711             powerupQueueImgs[j].SetImage(PowerupUtils::GetImageData((PowerupId)i));
01712             break;
01713           }
01714         }
01715         break;
01716       }
01717       else if (powerupOnBtns[i].GetState() == STATE_CLICKED)
01718       {
01719         powerupOnBtns[i].ResetState();
01720         tmpIsPowerupEnabled[i] = !tmpIsPowerupEnabled[i];
01721         powerupOnTxts[i].SetText(tmpIsPowerupEnabled[i] ? "on" : "off");
01722         break;
01723       }
01724       else if (powerupHelpBtns[i].GetState() == STATE_CLICKED)
01725       {
01726         powerupHelpBtns[i].ResetState();
01727         std::string *helpText = PowerupUtils::GetHelpText((PowerupId)i);
01728         WindowPrompt(
01729           helpText[0].c_str(), // title
01730           helpText[1].c_str(), // message
01731           "OK",
01732           NULL,
01733           &window);
01734         break;
01735       }
01736     }
01737 
01738     for (int i = 0; i < MAX_ACQUIRED_POWERUPS; ++i)
01739     {
01740       if (powerupQueueBtns[i].GetState() == STATE_CLICKED)
01741       {
01742         powerupQueueBtns[i].ResetState();
01743         // Remove powerup from queue.
01744         PowerupUtils::GetInvalidTargetSound()->Play();
01745         tmpPowerupStartQueue[i] = POWERUP_ID_NONE;
01746         powerupQueueImgs[i].SetImage(btnData40x40Square);
01747         break;
01748       }
01749     }
01750   }
01751 
01752   window.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
01753   while (window.GetEffect() > 0) usleep(THREAD_SLEEP);
01754   HaltGui();
01755   parentWindow->Remove(&window);
01756   parentWindow->SetState(STATE_DEFAULT);
01757   ResumeGui();
01758 }
01759 
01760 /// Launches the multiplayer options popup.
01761 void TCYC_MenuMpOptionsPopup(bool isGlobalOptions)
01762 {
01763   static const int PADDING_TOP = 8;
01764   GXColor helpTxtColor = (GXColor){0, 170, 0, 255};
01765   GXColor blackColor = (GXColor){0, 0, 0, 255};
01766 
01767   int player = 0;
01768   char playerBuf[7+1+1] = "PLAYER "; // values: 1-MAX_PLAYERS + "PLAYER "
01769   sprintf(playerBuf + 7, "%d", player + 1);
01770 
01771   bool isHandicapEnabled[MAX_PLAYERS];
01772   Profile profiles[MAX_PLAYERS];
01773 
01774   if (isGlobalOptions)
01775   {
01776     // Store the global options at index 0.
01777     isHandicapEnabled[player] = true; // Global options are always enabled.
01778     profiles[player] = g_options->profile;
01779   }
01780   else
01781   {
01782     // Initialize the handicap options.
01783     for (int i = 0; i < MAX_PLAYERS; ++i)
01784     {
01785       isHandicapEnabled[i] = g_players[i].isHandicapEnabled;
01786       profiles[i] = g_players[i].profile;
01787     }
01788   }
01789 
01790   char maxLinesBuf[3+1]; // values: 0-995
01791   sprintf(maxLinesBuf, "%d", profiles[player].maxLines);
01792   char defMaxLinesBuf[3+1];
01793   sprintf(defMaxLinesBuf, "%d", DEFAULT_MAX_PLAYLINES);
01794 
01795   char attackRateBuf[2+1]; // values: 0-99
01796   sprintf(attackRateBuf, "%d", profiles[player].attackRate);
01797   char defAttackRateBuf[2+1];
01798   sprintf(defAttackRateBuf, "%d", DEFAULT_ATTACK_RATE);
01799 
01800   char powerupRateBuf[2+1]; // values: 0-99
01801   sprintf(powerupRateBuf, "%d", profiles[player].powerupRate);
01802   char defPowerupRateBuf[2+1];
01803   sprintf(defPowerupRateBuf, "%d", DEFAULT_POWERUP_RATE);
01804 
01805   // popup window
01806   GuiWindow promptWindow(screenwidth - 100, screenheight - 100);
01807   promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
01808   promptWindow.SetPosition(0, 0);
01809 
01810   // background image
01811   GuiImage mpOptBgImg(screenwidth - 100, screenheight - 100, (GXColor){170, 170, 170, 255});
01812 
01813   // title text
01814   GuiText titleTxt(isGlobalOptions ? "Multiplayer Options" : "Handicap Options", 30, blackColor);
01815   titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01816   titleTxt.SetPosition(0, 15);
01817 
01818   // PLAYER LEFT ARROW BUTTON
01819   GuiButton playerLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01820   GuiText playerLeftArrowBtnTxt("<", 22, blackColor);
01821   GuiText playerLeftArrowBtnTxtOver("<", 22, helpTxtColor);
01822   GuiImage playerLeftArrowBtnImg(btnData40x40Square);
01823   GuiImage playerLeftArrowBtnImgOver(btnData40x40SquareOver);
01824 
01825   playerLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01826   playerLeftArrowBtn.SetPosition(-80, 60);
01827   playerLeftArrowBtn.SetLabel(&playerLeftArrowBtnTxt);
01828   playerLeftArrowBtn.SetLabelOver(&playerLeftArrowBtnTxtOver);
01829   playerLeftArrowBtn.SetImage(&playerLeftArrowBtnImg);
01830   playerLeftArrowBtn.SetImageOver(&playerLeftArrowBtnImgOver);
01831   playerLeftArrowBtn.SetSoundOver(btnSoundOver);
01832   playerLeftArrowBtn.SetTrigger(trigA);
01833   playerLeftArrowBtn.SetEffectGrow();
01834 
01835   // PLAYER RIGHT ARROW BUTTON
01836   GuiButton playerRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01837   GuiText playerRightArrowBtnTxt(">", 22, blackColor);
01838   GuiText playerRightArrowBtnTxtOver(">", 22, helpTxtColor);
01839   GuiImage playerRightArrowBtnImg(btnData40x40Square);
01840   GuiImage playerRightArrowBtnImgOver(btnData40x40SquareOver);
01841 
01842   playerRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01843   playerRightArrowBtn.SetPosition(80, 60);
01844   playerRightArrowBtn.SetLabel(&playerRightArrowBtnTxt);
01845   playerRightArrowBtn.SetLabelOver(&playerRightArrowBtnTxtOver);
01846   playerRightArrowBtn.SetImage(&playerRightArrowBtnImg);
01847   playerRightArrowBtn.SetImageOver(&playerRightArrowBtnImgOver);
01848   playerRightArrowBtn.SetSoundOver(btnSoundOver);
01849   playerRightArrowBtn.SetTrigger(trigA);
01850   playerRightArrowBtn.SetEffectGrow();
01851 
01852   // PLAYER TEXT
01853   GuiText playerTxt(playerBuf, 22, blackColor);
01854   playerTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01855   playerTxt.SetPosition(0, 60 + PADDING_TOP);
01856 
01857   // HANDICAP LEFT ARROW BUTTON
01858   GuiButton handicapLeftArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01859   GuiText handicapLeftArrowBtnTxt("<", 22, blackColor);
01860   GuiText handicapLeftArrowBtnTxtOver("<", 22, helpTxtColor);
01861   GuiImage handicapLeftArrowBtnImg(btnData40x40Square);
01862   GuiImage handicapLeftArrowBtnImgOver(btnData40x40SquareOver);
01863 
01864   handicapLeftArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01865   handicapLeftArrowBtn.SetPosition(-80, 60 + btnData40x40Square->GetHeight());
01866   handicapLeftArrowBtn.SetLabel(&handicapLeftArrowBtnTxt);
01867   handicapLeftArrowBtn.SetLabelOver(&handicapLeftArrowBtnTxtOver);
01868   handicapLeftArrowBtn.SetImage(&handicapLeftArrowBtnImg);
01869   handicapLeftArrowBtn.SetImageOver(&handicapLeftArrowBtnImgOver);
01870   handicapLeftArrowBtn.SetSoundOver(btnSoundOver);
01871   handicapLeftArrowBtn.SetTrigger(trigA);
01872   handicapLeftArrowBtn.SetEffectGrow();
01873 
01874   // HANDICAP RIGHT ARROW BUTTON
01875   GuiButton handicapRightArrowBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01876   GuiText handicapRightArrowBtnTxt(">", 22, blackColor);
01877   GuiText handicapRightArrowBtnTxtOver(">", 22, helpTxtColor);
01878   GuiImage handicapRightArrowBtnImg(btnData40x40Square);
01879   GuiImage handicapRightArrowBtnImgOver(btnData40x40SquareOver);
01880 
01881   handicapRightArrowBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01882   handicapRightArrowBtn.SetPosition(80, 60 + btnData40x40Square->GetHeight());
01883   handicapRightArrowBtn.SetLabel(&handicapRightArrowBtnTxt);
01884   handicapRightArrowBtn.SetLabelOver(&handicapRightArrowBtnTxtOver);
01885   handicapRightArrowBtn.SetImage(&handicapRightArrowBtnImg);
01886   handicapRightArrowBtn.SetImageOver(&handicapRightArrowBtnImgOver);
01887   handicapRightArrowBtn.SetSoundOver(btnSoundOver);
01888   handicapRightArrowBtn.SetTrigger(trigA);
01889   handicapRightArrowBtn.SetEffectGrow();
01890 
01891   // HANDICAP TEXT
01892   GuiText handicapTxt(isHandicapEnabled[player] ? "enabled" : "disabled", 22, blackColor);
01893   handicapTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01894   handicapTxt.SetPosition(0, 60 + PADDING_TOP + btnData40x40Square->GetHeight());
01895 
01896   // MAX LINES TEXT BUTTON
01897   GuiButton linesTxtBtn((10 + 1) * 11, 22);
01898   GuiText linesTxtBtnTxt("max lines:", 22, blackColor);
01899   GuiText linesTxtBtnTxtOver("max lines:", 22, helpTxtColor);
01900 
01901   linesTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01902   linesTxtBtn.SetPosition(10, 60 + PADDING_TOP + 2 * btnData40x40Square->GetHeight());
01903   linesTxtBtn.SetLabel(&linesTxtBtnTxt);
01904   linesTxtBtn.SetLabelOver(&linesTxtBtnTxtOver);
01905   linesTxtBtn.SetSoundOver(btnSoundOver);
01906   linesTxtBtn.SetTrigger(trigA);
01907 
01908   // MAX LINES TEXT
01909   GuiText linesTxt(isHandicapEnabled[player] ? (profiles[player].maxLines ? maxLinesBuf : "off") : "disabled", 22, blackColor);
01910   linesTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01911   linesTxt.SetPosition(-20, 60 + PADDING_TOP + 2 * btnData40x40Square->GetHeight());
01912 
01913   // MAX LINES DEFAULT BUTTON
01914   GuiButton linesDefaultBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01915   GuiText linesDefaultBtnTxt(defMaxLinesBuf, 22, blackColor);
01916   GuiText linesDefaultBtnTxtOver(defMaxLinesBuf, 22, helpTxtColor);
01917   GuiImage linesDefaultBtnImg(btnData40x40Square);
01918   GuiImage linesDefaultBtnImgOver(btnData40x40SquareOver);
01919 
01920   linesDefaultBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01921   linesDefaultBtn.SetPosition(-10 - 2 * btnData40x40Square->GetWidth(), 60 + 2 * btnData40x40Square->GetHeight());
01922   linesDefaultBtn.SetLabel(&linesDefaultBtnTxt);
01923   linesDefaultBtn.SetLabelOver(&linesDefaultBtnTxtOver);
01924   linesDefaultBtn.SetImage(&linesDefaultBtnImg);
01925   linesDefaultBtn.SetImageOver(&linesDefaultBtnImgOver);
01926   linesDefaultBtn.SetSoundOver(btnSoundOver);
01927   linesDefaultBtn.SetTrigger(trigA);
01928   linesDefaultBtn.SetEffectGrow();
01929 
01930   // MAX LINES MINUS BUTTON
01931   GuiButton linesMinusBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01932   GuiText linesMinusBtnTxt("-", 22, blackColor);
01933   GuiText linesMinusBtnTxtOver("-", 22, helpTxtColor);
01934   GuiImage linesMinusBtnImg(btnData40x40Square);
01935   GuiImage linesMinusBtnImgOver(btnData40x40SquareOver);
01936 
01937   linesMinusBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01938   linesMinusBtn.SetPosition(-10 - btnData40x40Square->GetWidth(), 60 + 2 * btnData40x40Square->GetHeight());
01939   linesMinusBtn.SetLabel(&linesMinusBtnTxt);
01940   linesMinusBtn.SetLabelOver(&linesMinusBtnTxtOver);
01941   linesMinusBtn.SetImage(&linesMinusBtnImg);
01942   linesMinusBtn.SetImageOver(&linesMinusBtnImgOver);
01943   linesMinusBtn.SetSoundOver(btnSoundOver);
01944   linesMinusBtn.SetTrigger(trigA);
01945   linesMinusBtn.SetEffectGrow();
01946 
01947   // MAX LINES PLUS BUTTON
01948   GuiButton linesPlusBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01949   GuiText linesPlusBtnTxt("+", 22, blackColor);
01950   GuiText linesPlusBtnTxtOver("+", 22, helpTxtColor);
01951   GuiImage linesPlusBtnImg(btnData40x40Square);
01952   GuiImage linesPlusBtnImgOver(btnData40x40SquareOver);
01953 
01954   linesPlusBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01955   linesPlusBtn.SetPosition(-10, 60 + 2 * btnData40x40Square->GetHeight());
01956   linesPlusBtn.SetLabel(&linesPlusBtnTxt);
01957   linesPlusBtn.SetLabelOver(&linesPlusBtnTxtOver);
01958   linesPlusBtn.SetImage(&linesPlusBtnImg);
01959   linesPlusBtn.SetImageOver(&linesPlusBtnImgOver);
01960   linesPlusBtn.SetSoundOver(btnSoundOver);
01961   linesPlusBtn.SetTrigger(trigA);
01962   linesPlusBtn.SetEffectGrow();
01963 
01964   // ATTACK RATE TEXT BUTTON
01965   GuiButton attackTxtBtn((12 + 1) * 11, 22);
01966   GuiText attackTxtBtnTxt("attack rate:", 22, blackColor);
01967   GuiText attackTxtBtnTxtOver("attack rate:", 22, helpTxtColor);
01968 
01969   attackTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01970   attackTxtBtn.SetPosition(10, 60 + PADDING_TOP + 3 * btnData40x40Square->GetHeight());
01971   attackTxtBtn.SetLabel(&attackTxtBtnTxt);
01972   attackTxtBtn.SetLabelOver(&attackTxtBtnTxtOver);
01973   attackTxtBtn.SetSoundOver(btnSoundOver);
01974   attackTxtBtn.SetTrigger(trigA);
01975 
01976   // ATTACK RATE TEXT
01977   GuiText attackTxt(isHandicapEnabled[player] ? (profiles[player].attackRate ? attackRateBuf : "off") : "disabled", 22, blackColor);
01978   attackTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
01979   attackTxt.SetPosition(-20, 60 + PADDING_TOP + 3 * btnData40x40Square->GetHeight());
01980 
01981   // ATTACK RATE DEFAULT BUTTON
01982   GuiButton attackDefaultBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
01983   GuiText attackDefaultBtnTxt(defAttackRateBuf, 22, blackColor);
01984   GuiText attackDefaultBtnTxtOver(defAttackRateBuf, 22, helpTxtColor);
01985   GuiImage attackDefaultBtnImg(btnData40x40Square);
01986   GuiImage attackDefaultBtnImgOver(btnData40x40SquareOver);
01987 
01988   attackDefaultBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
01989   attackDefaultBtn.SetPosition(-10 - 2 * btnData40x40Square->GetWidth(), 60 + 3 * btnData40x40Square->GetHeight());
01990   attackDefaultBtn.SetLabel(&attackDefaultBtnTxt);
01991   attackDefaultBtn.SetLabelOver(&attackDefaultBtnTxtOver);
01992   attackDefaultBtn.SetImage(&attackDefaultBtnImg);
01993   attackDefaultBtn.SetImageOver(&attackDefaultBtnImgOver);
01994   attackDefaultBtn.SetSoundOver(btnSoundOver);
01995   attackDefaultBtn.SetTrigger(trigA);
01996   attackDefaultBtn.SetEffectGrow();
01997 
01998   // ATTACK RATE MINUS BUTTON
01999   GuiButton attackMinusBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02000   GuiText attackMinusBtnTxt("-", 22, blackColor);
02001   GuiText attackMinusBtnTxtOver("-", 22, helpTxtColor);
02002   GuiImage attackMinusBtnImg(btnData40x40Square);
02003   GuiImage attackMinusBtnImgOver(btnData40x40SquareOver);
02004 
02005   attackMinusBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
02006   attackMinusBtn.SetPosition(-10 - btnData40x40Square->GetWidth(), 60 + 3 * btnData40x40Square->GetHeight());
02007   attackMinusBtn.SetLabel(&attackMinusBtnTxt);
02008   attackMinusBtn.SetLabelOver(&attackMinusBtnTxtOver);
02009   attackMinusBtn.SetImage(&attackMinusBtnImg);
02010   attackMinusBtn.SetImageOver(&attackMinusBtnImgOver);
02011   attackMinusBtn.SetSoundOver(btnSoundOver);
02012   attackMinusBtn.SetTrigger(trigA);
02013   attackMinusBtn.SetEffectGrow();
02014 
02015   // ATTACK RATE PLUS BUTTON
02016   GuiButton attackPlusBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02017   GuiText attackPlusBtnTxt("+", 22, blackColor);
02018   GuiText attackPlusBtnTxtOver("+", 22, helpTxtColor);
02019   GuiImage attackPlusBtnImg(btnData40x40Square);
02020   GuiImage attackPlusBtnImgOver(btnData40x40SquareOver);
02021 
02022   attackPlusBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
02023   attackPlusBtn.SetPosition(-10, 60 + 3 * btnData40x40Square->GetHeight());
02024   attackPlusBtn.SetLabel(&attackPlusBtnTxt);
02025   attackPlusBtn.SetLabelOver(&attackPlusBtnTxtOver);
02026   attackPlusBtn.SetImage(&attackPlusBtnImg);
02027   attackPlusBtn.SetImageOver(&attackPlusBtnImgOver);
02028   attackPlusBtn.SetSoundOver(btnSoundOver);
02029   attackPlusBtn.SetTrigger(trigA);
02030   attackPlusBtn.SetEffectGrow();
02031 
02032   //---
02033   // POWERUP RATE TEXT BUTTON
02034   GuiButton powerupRateTxtBtn((14 + 1) * 11, 22);
02035   GuiText powerupRateTxtBtnTxt("powerup rate:", 22, blackColor);
02036   GuiText powerupRateTxtBtnTxtOver("powerup rate:", 22, helpTxtColor);
02037 
02038   powerupRateTxtBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
02039   powerupRateTxtBtn.SetPosition(10, 60 + PADDING_TOP + 4 * 40);
02040   powerupRateTxtBtn.SetLabel(&powerupRateTxtBtnTxt);
02041   powerupRateTxtBtn.SetLabelOver(&powerupRateTxtBtnTxtOver);
02042   powerupRateTxtBtn.SetSoundOver(btnSoundOver);
02043   powerupRateTxtBtn.SetTrigger(trigA);
02044 
02045   // POWERUP RATE TEXT
02046   GuiText powerupRateTxt(isHandicapEnabled[player] ? (profiles[player].powerupRate ? powerupRateBuf : "off") : "disabled", 22, blackColor);
02047   powerupRateTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
02048   powerupRateTxt.SetPosition(-20, 60 + PADDING_TOP + 4 * 40);
02049 
02050   // POWERUP RATE DEFAULT BUTTON
02051   GuiButton powerupRateDefaultBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02052   GuiText powerupRateDefaultBtnTxt(defPowerupRateBuf, 22, blackColor);
02053   GuiText powerupRateDefaultBtnTxtOver(defPowerupRateBuf, 22, helpTxtColor);
02054   GuiImage powerupRateDefaultBtnImg(btnData40x40Square);
02055   GuiImage powerupRateDefaultBtnImgOver(btnData40x40SquareOver);
02056 
02057   powerupRateDefaultBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
02058   powerupRateDefaultBtn.SetPosition(-10 - 2 * btnData40x40Square->GetWidth(), 60 + 4 * 40);
02059   powerupRateDefaultBtn.SetLabel(&powerupRateDefaultBtnTxt);
02060   powerupRateDefaultBtn.SetLabelOver(&powerupRateDefaultBtnTxtOver);
02061   powerupRateDefaultBtn.SetImage(&powerupRateDefaultBtnImg);
02062   powerupRateDefaultBtn.SetImageOver(&powerupRateDefaultBtnImgOver);
02063   powerupRateDefaultBtn.SetSoundOver(btnSoundOver);
02064   powerupRateDefaultBtn.SetTrigger(trigA);
02065   powerupRateDefaultBtn.SetEffectGrow();
02066 
02067   // POWERUP RATE MINUS BUTTON
02068   GuiButton powerupRateMinusBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02069   GuiText powerupRateMinusBtnTxt("-", 22, blackColor);
02070   GuiText powerupRateMinusBtnTxtOver("-", 22, helpTxtColor);
02071   GuiImage powerupRateMinusBtnImg(btnData40x40Square);
02072   GuiImage powerupRateMinusBtnImgOver(btnData40x40SquareOver);
02073 
02074   powerupRateMinusBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
02075   powerupRateMinusBtn.SetPosition(-10 - btnData40x40Square->GetWidth(), 60 + 4 * 40);
02076   powerupRateMinusBtn.SetLabel(&powerupRateMinusBtnTxt);
02077   powerupRateMinusBtn.SetLabelOver(&powerupRateMinusBtnTxtOver);
02078   powerupRateMinusBtn.SetImage(&powerupRateMinusBtnImg);
02079   powerupRateMinusBtn.SetImageOver(&powerupRateMinusBtnImgOver);
02080   powerupRateMinusBtn.SetSoundOver(btnSoundOver);
02081   powerupRateMinusBtn.SetTrigger(trigA);
02082   powerupRateMinusBtn.SetEffectGrow();
02083 
02084   // POWERUP RATE PLUS BUTTON
02085   GuiButton powerupRatePlusBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02086   GuiText powerupRatePlusBtnTxt("+", 22, blackColor);
02087   GuiText powerupRatePlusBtnTxtOver("+", 22, helpTxtColor);
02088   GuiImage powerupRatePlusBtnImg(btnData40x40Square);
02089   GuiImage powerupRatePlusBtnImgOver(btnData40x40SquareOver);
02090 
02091   powerupRatePlusBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
02092   powerupRatePlusBtn.SetPosition(-10, 60 + 4 * 40);
02093   powerupRatePlusBtn.SetLabel(&powerupRatePlusBtnTxt);
02094   powerupRatePlusBtn.SetLabelOver(&powerupRatePlusBtnTxtOver);
02095   powerupRatePlusBtn.SetImage(&powerupRatePlusBtnImg);
02096   powerupRatePlusBtn.SetImageOver(&powerupRatePlusBtnImgOver);
02097   powerupRatePlusBtn.SetSoundOver(btnSoundOver);
02098   powerupRatePlusBtn.SetTrigger(trigA);
02099   powerupRatePlusBtn.SetEffectGrow();
02100 
02101   // CONFIRM BUTTON
02102   GuiButton confirmBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02103   GuiText confirmBtnTxt("OK", 22, (GXColor){0, 0, 255, 255});
02104   GuiImage confirmBtnImg(btnData40x40Square);
02105   GuiImage confirmBtnImgOver(btnData40x40SquareOver);
02106 
02107   confirmBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
02108   confirmBtn.SetPosition(-10, -10);
02109   confirmBtn.SetLabel(&confirmBtnTxt);
02110   confirmBtn.SetImage(&confirmBtnImg);
02111   confirmBtn.SetImageOver(&confirmBtnImgOver);
02112   confirmBtn.SetSoundOver(btnSoundOver);
02113   confirmBtn.SetTrigger(trigA);
02114   confirmBtn.SetEffectGrow();
02115 
02116   // CANCEL BUTTON
02117   GuiButton cancelBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02118   GuiText cancelBtnTxt("X", 22, (GXColor){255, 0, 0, 255});
02119   GuiImage cancelBtnImg(btnData40x40Square);
02120   GuiImage cancelBtnImgOver(btnData40x40SquareOver);
02121 
02122   cancelBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
02123   cancelBtn.SetPosition(-10, 10);
02124   cancelBtn.SetLabel(&cancelBtnTxt);
02125   cancelBtn.SetImage(&cancelBtnImg);
02126   cancelBtn.SetImageOver(&cancelBtnImgOver);
02127   cancelBtn.SetSoundOver(btnSoundOver);
02128   cancelBtn.SetTrigger(trigA);
02129   cancelBtn.SetEffectGrow();
02130 
02131   // HELP BUTTON
02132   GuiButton helpBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
02133   GuiText helpBtnTxt("?", 22, helpTxtColor);
02134   GuiImage helpBtnImg(btnData40x40Square);
02135   GuiImage helpBtnImgOver(btnData40x40SquareOver);
02136 
02137   helpBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
02138   helpBtn.SetPosition(10, -10);
02139   helpBtn.SetLabel(&helpBtnTxt);
02140   helpBtn.SetImage(&helpBtnImg);
02141   helpBtn.SetImageOver(&helpBtnImgOver);
02142   helpBtn.SetSoundOver(btnSoundOver);
02143   helpBtn.SetTrigger(trigA);
02144   helpBtn.SetEffectGrow();
02145 
02146   // POWERUP BUTTON
02147   GuiButton powerupBtn(btnOutline->GetWidth(), btnOutline->GetHeight());
02148   GuiText powerupTxt("Powerups", 22, (GXColor){0, 0, 0, 255});
02149   GuiImage powerupImg(btnOutline);
02150   GuiImage powerupImgOver(btnOutlineOver);
02151 
02152   powerupBtn.SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
02153   powerupBtn.SetPosition(0, -10);
02154   powerupBtn.SetLabel(&powerupTxt);
02155   powerupBtn.SetImage(&powerupImg);
02156   powerupBtn.SetImageOver(&powerupImgOver);
02157   powerupBtn.SetSoundOver(btnSoundOver);
02158   powerupBtn.SetTrigger(trigA);
02159   powerupBtn.SetEffectGrow();
02160   powerupBtn.SetState(!isHandicapEnabled[player] ? STATE_DISABLED : STATE_DEFAULT);
02161   //powerupBtn.SetVisible(isHandicapEnabled[player]);
02162 
02163   promptWindow.Append(&mpOptBgImg);
02164   promptWindow.Append(&titleTxt);
02165   if (!isGlobalOptions)
02166   {
02167     // handicap options
02168     promptWindow.Append(&playerLeftArrowBtn);
02169     promptWindow.Append(&playerRightArrowBtn);
02170     promptWindow.Append(&playerTxt);
02171     promptWindow.Append(&handicapLeftArrowBtn);
02172     promptWindow.Append(&handicapRightArrowBtn);
02173     promptWindow.Append(&handicapTxt);
02174   }
02175   promptWindow.Append(&linesTxtBtn);
02176   promptWindow.Append(&linesTxt);
02177   promptWindow.Append(&linesDefaultBtn);
02178   promptWindow.Append(&linesMinusBtn);
02179   promptWindow.Append(&linesPlusBtn);
02180   promptWindow.Append(&attackTxtBtn);
02181   promptWindow.Append(&attackTxt);
02182   promptWindow.Append(&attackDefaultBtn);
02183   promptWindow.Append(&attackMinusBtn);
02184   promptWindow.Append(&attackPlusBtn);
02185   promptWindow.Append(&powerupRateTxtBtn);
02186   promptWindow.Append(&powerupRateTxt);
02187   promptWindow.Append(&powerupRateDefaultBtn);
02188   promptWindow.Append(&powerupRateMinusBtn);
02189   promptWindow.Append(&powerupRatePlusBtn);
02190   promptWindow.Append(&confirmBtn);
02191   promptWindow.Append(&cancelBtn);
02192   promptWindow.Append(&helpBtn);
02193   promptWindow.Append(&powerupBtn);
02194 
02195   promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
02196   HaltGui();
02197   // This sets the state for all child elements, including child windows; 
02198   // that is why we disable the state first, then add the child window.
02199   mainWindow->SetState(STATE_DISABLED);
02200   mainWindow->Append(&promptWindow);
02201   mainWindow->ChangeFocus(&promptWindow);
02202   ResumeGui();
02203 
02204   while (true)
02205   {
02206     usleep(THREAD_SLEEP);
02207 
02208     if (confirmBtn.GetState() == STATE_CLICKED)
02209     {
02210       if (isGlobalOptions)
02211       {
02212         g_options->profile = profiles[player];
02213         g_options->powerupsSize = 0;
02214         for (int j = 0; j < g_totalPowerups; ++j)
02215         {
02216           if (profiles[player].isPowerupEnabled[j])
02217             g_options->powerups[g_options->powerupsSize++] = (PowerupId)j;
02218         }
02219       }
02220       else // handicap options
02221       {
02222         for (int i = 0; i < MAX_PLAYERS; ++i)
02223         {
02224           g_players[i].isHandicapEnabled = isHandicapEnabled[i];
02225           g_players[i].profile = profiles[i];
02226           g_players[i].powerupsSize = 0;
02227           for (int j = 0; j < g_totalPowerups; ++j)
02228           {
02229             if (profiles[i].isPowerupEnabled[j])
02230               g_players[i].powerups[g_players[i].powerupsSize++] = (PowerupId)j;
02231           }
02232         }
02233       }
02234 
02235       break;
02236     }
02237     else if (cancelBtn.GetState() == STATE_CLICKED)
02238     {
02239       break;
02240     }
02241     else if (helpBtn.GetState() == STATE_CLICKED)
02242     {
02243       helpBtn.ResetState();
02244 
02245       WindowPrompt(
02246         "HINT",
02247         isGlobalOptions ? 
02248           "The option menu labels are clickable. Click on them for more information!" 
02249           : "Handicap options override multiplayer options!",
02250         "OK",
02251         NULL,
02252         &promptWindow);
02253     }
02254     // player buttons
02255     else if (playerLeftArrowBtn.GetState() == STATE_CLICKED
02256              || playerRightArrowBtn.GetState() == STATE_CLICKED)
02257     {
02258       HaltGui();
02259 
02260       if (playerLeftArrowBtn.GetState() == STATE_CLICKED)
02261       {
02262         playerLeftArrowBtn.SetState(STATE_SELECTED);
02263         player--;
02264         if (player < 0)
02265           player = MAX_PLAYERS - 1;
02266       }
02267       else if (playerRightArrowBtn.GetState() == STATE_CLICKED)
02268       {
02269         playerRightArrowBtn.SetState(STATE_SELECTED);
02270         player++;
02271         if (player >= MAX_PLAYERS)
02272           player = 0;
02273       }
02274 
02275       sprintf(playerBuf + 7, "%d", player + 1);
02276       playerTxt.SetText(playerBuf);
02277       handicapTxt.SetText(isHandicapEnabled[player] ? "enabled" : "disabled");
02278 
02279       sprintf(maxLinesBuf, "%d", profiles[player].maxLines);
02280       if (isHandicapEnabled[player])
02281         linesTxt.SetText(profiles[player].maxLines ? maxLinesBuf : "off");
02282       else
02283         linesTxt.SetText("disabled");
02284 
02285       sprintf(attackRateBuf, "%d", profiles[player].attackRate);
02286       if (isHandicapEnabled[player])
02287         attackTxt.SetText(profiles[player].attackRate ? attackRateBuf : "off");
02288       else
02289         attackTxt.SetText("disabled");
02290 
02291       sprintf(powerupRateBuf, "%d", profiles[player].powerupRate);
02292       if (isHandicapEnabled[player])
02293         powerupRateTxt.SetText(profiles[player].powerupRate ? powerupRateBuf : "off");
02294       else
02295         powerupRateTxt.SetText("disabled");
02296 
02297       //powerupBtn.SetVisible(isHandicapEnabled[player]);
02298       powerupBtn.SetState(!isHandicapEnabled[player] ? STATE_DISABLED : STATE_DEFAULT);
02299 
02300       ResumeGui();
02301     }
02302     // handicap buttons
02303     else if (handicapLeftArrowBtn.GetState() == STATE_CLICKED
02304              || handicapRightArrowBtn.GetState() == STATE_CLICKED)
02305     {
02306       HaltGui();
02307 
02308       if (handicapLeftArrowBtn.GetState() == STATE_CLICKED)
02309         handicapLeftArrowBtn.SetState(STATE_SELECTED);
02310       else if (handicapRightArrowBtn.GetState() == STATE_CLICKED)
02311         handicapRightArrowBtn.SetState(STATE_SELECTED);
02312 
02313       isHandicapEnabled[player] = !isHandicapEnabled[player];
02314       handicapTxt.SetText(isHandicapEnabled[player] ? "enabled" : "disabled");
02315 
02316       sprintf(maxLinesBuf, "%d", profiles[player].maxLines);
02317       if (isHandicapEnabled[player])
02318         linesTxt.SetText(profiles[player].maxLines ? maxLinesBuf : "off");
02319       else
02320         linesTxt.SetText("disabled");
02321 
02322       sprintf(attackRateBuf, "%d", profiles[player].attackRate);
02323       if (isHandicapEnabled[player])
02324         attackTxt.SetText(profiles[player].attackRate ? attackRateBuf : "off");
02325       else
02326         attackTxt.SetText("disabled");
02327 
02328       sprintf(powerupRateBuf, "%d", profiles[player].powerupRate);
02329       if (isHandicapEnabled[player])
02330         powerupRateTxt.SetText(profiles[player].powerupRate ? powerupRateBuf : "off");
02331       else
02332         powerupRateTxt.SetText("disabled");
02333 
02334       //powerupBtn.SetVisible(isHandicapEnabled[player]);
02335       powerupBtn.SetState(!isHandicapEnabled[player] ? STATE_DISABLED : STATE_DEFAULT);
02336 
02337       ResumeGui();
02338     }
02339     // max lines
02340     else if (linesTxtBtn.GetState() == STATE_CLICKED)
02341     {
02342       linesTxtBtn.ResetState();
02343 
02344       WindowPrompt(
02345         "MAX LINES",
02346         "You win the game after clearing this many lines.",
02347         "OK",
02348         NULL,
02349         &promptWindow);
02350     }
02351     // attack rate
02352     else if (attackTxtBtn.GetState() == STATE_CLICKED)
02353     {
02354       attackTxtBtn.ResetState();
02355 
02356       WindowPrompt(
02357         "ATTACK RATE",
02358         "You attack all your opponents every time you score this many points. "
02359         "This raises the speed of the falling block by one level.",
02360         "OK",
02361         NULL,
02362         &promptWindow);
02363     }
02364     // powerup rate
02365     else if (powerupRateTxtBtn.GetState() == STATE_CLICKED)
02366     {
02367       powerupRateTxtBtn.ResetState();
02368 
02369       WindowPrompt(
02370         "POWERUP RATE",
02371         "Every 'x' pieces will be a powerup piece. "
02372         "Clear a powerup piece to earn that powerup.",
02373         "OK",
02374         NULL,
02375         &promptWindow);
02376     }
02377 
02378     if (!isHandicapEnabled[player])
02379       continue;
02380 
02381     // max lines
02382     if (linesDefaultBtn.GetState() == STATE_CLICKED)
02383     {
02384       HaltGui();
02385       linesDefaultBtn.SetState(STATE_SELECTED);
02386       profiles[player].maxLines = DEFAULT_MAX_PLAYLINES;
02387       sprintf(maxLinesBuf, "%d", profiles[player].maxLines);
02388       linesTxt.SetText(maxLinesBuf);
02389       ResumeGui();
02390     }
02391     else if (linesMinusBtn.GetState() == STATE_CLICKED)
02392     {
02393       HaltGui();
02394       linesMinusBtn.SetState(STATE_SELECTED);
02395 
02396       if (profiles[player].maxLines <= 5)
02397         profiles[player].maxLines = 0;
02398       else
02399         profiles[player].maxLines -= 5;
02400 
02401       if (profiles[player].maxLines <= 0)
02402       {
02403         profiles[player].maxLines = 0;
02404         linesTxt.SetText("off");
02405       }
02406       else
02407       {
02408         sprintf(maxLinesBuf, "%d", profiles[player].maxLines);
02409         linesTxt.SetText(maxLinesBuf);
02410       }
02411       ResumeGui();
02412     }
02413     else if (linesPlusBtn.GetState() == STATE_CLICKED)
02414     {
02415       HaltGui();
02416       linesPlusBtn.SetState(STATE_SELECTED);
02417       profiles[player].maxLines += 5;
02418       if (profiles[player].maxLines >= 1000)
02419         profiles[player].maxLines = 995;
02420 
02421       sprintf(maxLinesBuf, "%d", profiles[player].maxLines);
02422       linesTxt.SetText(maxLinesBuf);
02423       ResumeGui();
02424     }
02425     // attack rate
02426     else if (attackDefaultBtn.GetState() == STATE_CLICKED)
02427     {
02428       HaltGui();
02429       attackDefaultBtn.SetState(STATE_SELECTED);
02430       profiles[player].attackRate = DEFAULT_ATTACK_RATE;
02431       sprintf(attackRateBuf, "%d", profiles[player].attackRate);
02432       attackTxt.SetText(attackRateBuf);
02433       ResumeGui();
02434     }
02435     else if (attackMinusBtn.GetState() == STATE_CLICKED)
02436     {
02437       HaltGui();
02438       attackMinusBtn.SetState(STATE_SELECTED);
02439 
02440       if (profiles[player].attackRate > 0)
02441         profiles[player].attackRate--;
02442 
02443       if (profiles[player].attackRate <= 0)
02444       {
02445         profiles[player].attackRate = 0;
02446         attackTxt.SetText("off");
02447       }
02448       else
02449       {
02450         sprintf(attackRateBuf, "%d", profiles[player].attackRate);
02451         attackTxt.SetText(attackRateBuf);
02452       }
02453       ResumeGui();
02454     }
02455     else if (attackPlusBtn.GetState() == STATE_CLICKED)
02456     {
02457       HaltGui();
02458       attackPlusBtn.SetState(STATE_SELECTED);
02459       profiles[player].attackRate++;
02460       if (profiles[player].attackRate >= 100)
02461         profiles[player].attackRate = 99;
02462 
02463       sprintf(attackRateBuf, "%d", profiles[player].attackRate);
02464       attackTxt.SetText(attackRateBuf);
02465       ResumeGui();
02466     }
02467     // powerup rate
02468     else if (powerupRateDefaultBtn.GetState() == STATE_CLICKED)
02469     {
02470       HaltGui();
02471       powerupRateDefaultBtn.SetState(STATE_SELECTED);
02472       profiles[player].powerupRate = DEFAULT_POWERUP_RATE;
02473       sprintf(powerupRateBuf, "%d", profiles[player].powerupRate);
02474       powerupRateTxt.SetText(powerupRateBuf);
02475       ResumeGui();
02476     }
02477     else if (powerupRateMinusBtn.GetState() == STATE_CLICKED)
02478     {
02479       HaltGui();
02480       powerupRateMinusBtn.SetState(STATE_SELECTED);
02481 
02482       if (profiles[player].powerupRate > 0)
02483         profiles[player].powerupRate--;
02484 
02485       if (profiles[player].powerupRate <= 0)
02486       {
02487         profiles[player].powerupRate = 0;
02488         powerupRateTxt.SetText("off");
02489       }
02490       else
02491       {
02492         sprintf(powerupRateBuf, "%d", profiles[player].powerupRate);
02493         powerupRateTxt.SetText(powerupRateBuf);
02494       }
02495       ResumeGui();
02496     }
02497     else if (powerupRatePlusBtn.GetState() == STATE_CLICKED)
02498     {
02499       HaltGui();
02500       powerupRatePlusBtn.SetState(STATE_SELECTED);
02501       profiles[player].powerupRate++;
02502       if (profiles[player].powerupRate >= 100)
02503         profiles[player].powerupRate = 99;
02504 
02505       sprintf(powerupRateBuf, "%d", profiles[player].powerupRate);
02506       powerupRateTxt.SetText(powerupRateBuf);
02507       ResumeGui();
02508     }
02509     // powerups
02510     else if (powerupBtn.GetState() == STATE_CLICKED)
02511     {
02512       powerupBtn.ResetState();
02513       TCYC_MenuPowerupsPopup(&promptWindow, 
02514                              profiles[player].isPowerupEnabled, 
02515                              profiles[player].powerupStartQueue);
02516     }
02517 
02518     HaltGui();
02519     // max lines
02520     if (linesDefaultBtn.GetState() == STATE_SELECTED
02521         || linesDefaultBtn.GetState() == STATE_CLICKED
02522         || linesMinusBtn.GetState() == STATE_SELECTED 
02523         || linesMinusBtn.GetState() == STATE_CLICKED
02524         || linesPlusBtn.GetState() == STATE_SELECTED
02525         || linesPlusBtn.GetState() == STATE_CLICKED)
02526     {
02527       linesTxt.SetColor(helpTxtColor);
02528     }
02529     else
02530     {
02531       linesTxt.SetColor(blackColor);
02532     }
02533     // attack rate
02534     if (attackDefaultBtn.GetState() == STATE_SELECTED
02535         || attackDefaultBtn.GetState() == STATE_CLICKED
02536         || attackMinusBtn.GetState() == STATE_SELECTED 
02537         || attackMinusBtn.GetState() == STATE_CLICKED
02538         || attackPlusBtn.GetState() == STATE_SELECTED
02539         || attackPlusBtn.GetState() == STATE_CLICKED)
02540     {
02541       attackTxt.SetColor(helpTxtColor);
02542     }
02543     else
02544     {
02545       attackTxt.SetColor(blackColor);
02546     }
02547     // powerup rate
02548     if (powerupRateDefaultBtn.GetState() == STATE_SELECTED
02549         || powerupRateDefaultBtn.GetState() == STATE_CLICKED
02550         || powerupRateMinusBtn.GetState() == STATE_SELECTED 
02551         || powerupRateMinusBtn.GetState() == STATE_CLICKED
02552         || powerupRatePlusBtn.GetState() == STATE_SELECTED
02553         || powerupRatePlusBtn.GetState() == STATE_CLICKED)
02554     {
02555       powerupRateTxt.SetColor(helpTxtColor);
02556     }
02557     else
02558     {
02559       powerupRateTxt.SetColor(blackColor);
02560     }
02561     ResumeGui();
02562   }
02563 
02564   promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
02565   while (promptWindow.GetEffect() > 0) usleep(THREAD_SLEEP);
02566   HaltGui();
02567   mainWindow->Remove(&promptWindow);
02568   mainWindow->SetState(STATE_DEFAULT);
02569   ResumeGui();
02570 }
02571 
02572 void _DoEasterEgg()
02573 {
02574   GuiWindow heart(screenwidth, screenheight);
02575   GuiImageData tetrisHeartPink(tetris_heart_pink_png);
02576   GuiImage heartBg(&tetrisHeartPink);
02577 
02578   GuiText thanks("Thank you fans!", 24, (GXColor){0, 0, 0, 255});
02579   thanks.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
02580   thanks.SetPosition(-20, -55);
02581 
02582   GuiText sig("-Cale", 24, (GXColor){0, 0, 0, 255});
02583   sig.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
02584   sig.SetPosition(-20, -25);
02585 
02586   heart.Append(&heartBg);
02587   heart.Append(&thanks);
02588   heart.Append(&sig);
02589 
02590   HaltGui();
02591   mainWindow->DisableChildren();
02592   mainWindow->Append(&heart);
02593   mainWindow->ChangeFocus(&heart);
02594   ResumeGui();
02595 
02596   bgMusic->SetVolume(20);
02597 
02598   bool loop = true;
02599   while (loop)
02600   {
02601     if (!g_heartbeatSound->IsPlaying())
02602       g_heartbeatSound->Play();
02603 
02604     for (int i = 0; i < MAX_PLAYERS; ++i)
02605     {
02606       if (WPAD_ButtonsDown(i))
02607       {
02608         loop = false;
02609         break;
02610       }
02611     }
02612   }
02613 
02614   g_heartbeatSound->Stop();
02615   bgMusic->SetVolume(50);
02616 
02617   HaltGui();
02618   mainWindow->Remove(&heart);
02619   mainWindow->SetState(STATE_DEFAULT);
02620   ResumeGui();
02621 }

Generated on Wed Oct 20 2010 17:06:58 for TetriCycle by  doxygen 1.7.1