summaryrefslogtreecommitdiff
path: root/noncore/games/sfcave-sdl/menu.cpp
Unidiff
Diffstat (limited to 'noncore/games/sfcave-sdl/menu.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/sfcave-sdl/menu.cpp337
1 files changed, 337 insertions, 0 deletions
diff --git a/noncore/games/sfcave-sdl/menu.cpp b/noncore/games/sfcave-sdl/menu.cpp
new file mode 100644
index 0000000..0a7366f
--- a/dev/null
+++ b/noncore/games/sfcave-sdl/menu.cpp
@@ -0,0 +1,337 @@
1#include <SDL_image.h>
2#include "SDL_rotozoom.h"
3
4#include "constants.h"
5#include "sfcave.h"
6#include "game.h"
7#include "menu.h"
8#include "font.h"
9#include "starfield.h"
10
11MenuOption :: MenuOption( QString text, int id )
12{
13 menuText = text;
14 menuId = id;
15 nextMenu = 0;
16 highlighted = false;
17}
18
19MenuOption :: ~MenuOption()
20{
21}
22
23
24int MenuOption :: draw( SDL_Surface *screen, int y )
25{
26 if ( highlighted )
27 {
28 int x = (240 - FontHandler::TextWidth( FONT_MENU_HIGHLIGHTED, (const char *)menuText.c_str() ))/2;
29 FontHandler::draw( screen, FONT_MENU_HIGHLIGHTED, (const char *)menuText.c_str(), x, y );
30 return FontHandler::FontHeight( FONT_MENU_HIGHLIGHTED );
31 }
32 else
33 {
34 int x = (240 - FontHandler::TextWidth( FONT_MENU_UNHIGHLIGHTED, (const char *)menuText.c_str() ))/2;
35 FontHandler::draw( screen, FONT_MENU_UNHIGHLIGHTED, (const char *)menuText.c_str(), x, y );
36 return FontHandler::FontHeight( FONT_MENU_UNHIGHLIGHTED );
37 }
38}
39
40void MenuOption :: setNextMenu( Menu *item, bool down )
41{
42 nextMenu = item;
43 downMenuTree = down;
44}
45
46
47
48//----------------- Menu Class -------------
49
50SDL_Surface * Menu :: sfcaveTextImage;
51Menu *Menu :: mainMenu;
52Menu *Menu :: currentMenu;
53
54// This is the Master Menu constructor
55Menu :: Menu( SFCave *p )
56{
57 parent = p;
58 parentMenu = 0;
59 statusText = "";
60
61 //listItems.setAutoDelete( TRUE );
62
63 SDL_Surface *tmp = IMG_Load( IMAGES_PATH "sfcave_text.bmp" );
64 sfcaveTextImage = SDL_CreateRGBSurface(SDL_SWSURFACE, tmp->w, tmp->h, 32,
65 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000);
66 SDL_BlitSurface(tmp, NULL, sfcaveTextImage, NULL);
67 SDL_FreeSurface(tmp);
68
69 // Create menu structure
70 // Top level menu has 5 items - Start Game, Replays, Options, Help, and Quit
71 // Replays, Option menu items hav submenus
72 MenuOption *replayMenu = 0;
73 MenuOption *optionsMenu = 0;
74 MenuOption *item = 0;
75 addMenuOption( "Start Game", MENU_STARTGAME );
76 replayMenu = addMenuOption( "Replays", MENU_REPLAYS );
77 optionsMenu = addMenuOption( "Options", MENU_OPTIONS );
78 addMenuOption( "Help", MENU_HELP );
79 addMenuOption( "Quit", MENU_QUIT );
80
81 // Now deal with the Replays Menu
82 Menu *replay = new Menu( this );
83 replay->addMenuOption( "Play Replay", MENU_PLAY_REPLAY );
84 replay->addMenuOption( "Load Replay", MENU_LOAD_REPLAY );
85 replay->addMenuOption( "Save Replay", MENU_SAVE_REPLAY );
86 item = replay->addMenuOption( "Back", MENU_BACK );
87 item->setNextMenu( this, false );
88 replayMenu->setNextMenu( replay );
89
90 // Now deal with the Options MenucurrentMenu->currentMenuOption->setHighlighted( false );
91 listItems.front()->highlight( true );
92
93 Menu *options = new Menu( this );
94 MenuOption *typeMenu = 0;
95 MenuOption *difficultyMenu = 0;
96 MenuOption *soundsMenu = 0;
97 typeMenu = options->addMenuOption( "Game Type", MENU_GAME_TYPE );
98 difficultyMenu = options->addMenuOption( "Difficulty", MENU_DIFFICULTY );
99 soundsMenu = options->addMenuOption( "Sound", MENU_SOUNDS );
100 options->addMenuOption( "Clear Scores", MENU_CLEAR_SCORES );
101 item = options->addMenuOption( "Back", MENU_BACK );
102 item->setNextMenu( this, false );
103 optionsMenu->setNextMenu( options );
104
105 // Game Type menu
106 Menu *gameType = new Menu( options );
107 item = gameType->addMenuOption( "SFCave", MENU_GAME_SFCAVE );
108 item->setNextMenu( options );
109 item = gameType->addMenuOption( "Gates", MENU_GAME_GATES );
110 item->setNextMenu( options );
111 item = gameType->addMenuOption( "Fly", MENU_GAME_FLY );
112 item->setNextMenu( options );
113 item = gameType->addMenuOption( "Back", MENU_BACK );
114 item->setNextMenu( options );
115 typeMenu->setNextMenu( gameType );
116
117 // Game Difficulty menu
118 Menu *gameDifficulty = new Menu( options );
119 item = gameDifficulty->addMenuOption( "Easy", MENU_DIFFICULTY_EASY );
120 item->setNextMenu( options, false );
121 item = gameDifficulty->addMenuOption( "Normal", MENU_DIFFICULTY_NORMAL );
122 item->setNextMenu( options, false );
123 item = gameDifficulty->addMenuOption( "Hard", MENU_DIFFICULTY_HARD );
124 item->setNextMenu( options, false );
125 item = gameDifficulty->addMenuOption( "Back", MENU_BACK );
126 item->setNextMenu( options, false );
127 difficultyMenu->setNextMenu( gameDifficulty );
128
129 // Sounds Menu
130 Menu *sounds = new Menu( options );
131 sounds->addMenuOption( "Sound On", MENU_SOUND_ON );
132 sounds->addMenuOption( "Sound Off", MENU_SOUND_OFF );
133 sounds->addMenuOption( "Music On", MENU_MUSIC_ON );
134 sounds->addMenuOption( "Music Off", MENU_MUSIC_OFF );
135 item = sounds->addMenuOption( "Back", MENU_BACK );
136 item->setNextMenu( options, false );
137 soundsMenu->setNextMenu( sounds );
138
139 // Set static variables for menu selection up
140 mainMenu = this;
141 currentMenuOption = 0;
142
143 resetToTopMenu();
144
145 angle = 0;
146
147 stars = new StarField;
148}
149
150// This is a private constructor used for creating sub menus - only called by the Master Menu
151Menu :: Menu( Menu *p )
152{
153 parentMenu = p;
154 //listItems.setAutoDelete( TRUE );
155 currentMenuOption = 0;
156}
157
158Menu :: ~Menu()
159{
160 if ( this == mainMenu )
161 {
162 SDL_FreeSurface( sfcaveTextImage );
163 delete stars;
164 }
165}
166
167void Menu :: draw( SDL_Surface *screen )
168{
169 // draw stafield
170 stars->draw( screen );
171 stars->move( );
172
173 // Draw the spinning SFCave logo
174 SDL_Surface *rotozoom_pic;
175 SDL_Rect dest;
176
177 angle += 2;
178 if ( angle > 359 )
179 angle = 0;
180 if ((rotozoom_pic=rotozoomSurface (sfcaveTextImage, angle*1, 1, SMOOTHING_ON))!=NULL)
181 {
182 dest.x = (screen->w - rotozoom_pic->w)/2;
183 dest.y = 10;
184 dest.w = rotozoom_pic->w;
185 dest.h = rotozoom_pic->h;
186 SDL_BlitSurface( rotozoom_pic, NULL, screen, &dest );
187 SDL_FreeSurface(rotozoom_pic);
188 }
189
190 // Draw what game is selected
191 char text[100];
192 sprintf( text, "Current Game: %s", (const char *)parent->getCurrentGame()->getGameName().c_str() );
193 //Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)text ))/2, 120, (const char *)text );
194 FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)text, (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)text ))/2, 120 );
195 sprintf( text, "Difficulty: %s", (const char *)parent->getCurrentGame()->getGameDifficultyText().c_str() );
196 //Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)text ))/2, 120 + Menu::scoreFont.FontHeight()+2, (const char *)text );
197 FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)text, (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)text ))/2, 120 + FontHandler::FontHeight( FONT_WHITE_TEXT ) );
198
199 if ( statusText != "" )
200 FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)statusText.c_str(), (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)statusText.c_str() ))/2, 120 + (2*FontHandler::FontHeight( FONT_WHITE_TEXT ))+6 );
201 // Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)statusText ))/2, 120 + (Menu::scoreFont.FontHeight()*2)+6, (const char *)statusText );
202
203
204 // Loop round each menu option and draw it
205 int y = 155;
206 list<MenuOption *>::iterator it;
207 for ( it = currentMenu->listItems.begin(); it != currentMenu->listItems.end() ; ++it )
208 {
209 y += (*it)->draw( screen, y ) + 2;
210 }
211}
212
213int Menu :: handleKeys( SDL_KeyboardEvent &key )
214{
215 if ( key.type != SDL_KEYDOWN )
216 return -1;
217
218 statusText = "";
219 switch( key.keysym.sym )
220 {
221 case SDLK_DOWN:
222 {
223 // Move to next menu item
224 currentMenu->currentMenuOption->highlight( false );
225
226 list<MenuOption *>::iterator it;
227 for ( it = currentMenu->listItems.begin(); it != currentMenu->listItems.end() ; ++it )
228 {
229 if ( (*it) == currentMenu->currentMenuOption )
230 {
231 it++;
232 break;
233 }
234 }
235
236 if ( it == currentMenu->listItems.end() )
237 it = currentMenu->listItems.begin();
238
239 currentMenu->currentMenuOption = *it;
240 currentMenu->currentMenuOption->highlight( true );
241
242 break;
243 }
244 case SDLK_UP:
245 {
246 // Move to previous menu item
247 currentMenu->currentMenuOption->highlight( false );
248 list<MenuOption *>::iterator it;
249 bool reachedBeginning = false;
250 for ( it = (currentMenu->listItems).end()--; ; --it )
251 {
252 if ( (*it) == currentMenu->currentMenuOption )
253 {
254
255 if ( it == currentMenu->listItems.begin( ) )
256 {
257 reachedBeginning = true;
258 break;
259 }
260 else
261 it--;
262 break;
263 }
264
265 }
266
267 if ( reachedBeginning )
268 currentMenu->currentMenuOption = currentMenu->listItems.back();
269 else
270 currentMenu->currentMenuOption = *it;
271
272 currentMenu->currentMenuOption->highlight( true );
273
274 break;
275 }
276 case SDLK_LEFT:
277 if ( currentMenu->parentMenu != 0 )
278 {
279 currentMenu = currentMenu->parentMenu;
280 printf( "HERE\n" );
281
282 return -1;
283 }
284 break;
285
286 case SDLK_RETURN:
287 case SDLK_SPACE:
288 {
289 // select menu item
290 int id = currentMenu->currentMenuOption->getMenuId();
291 // // if the current item has a child menu then move to that menu
292 Menu *next = currentMenu->currentMenuOption->getNextMenu();
293 if ( next != 0 )
294 {
295 bool down = currentMenu->currentMenuOption->isDownMenuTree();
296 currentMenu = next;
297 if ( down )
298 initCurrentMenu();
299 // return -1;
300 }
301 // else
302 {
303 return id;
304 }
305
306 break;
307 }
308
309 default:
310 break;
311 }
312
313 return -1;
314}
315
316MenuOption *Menu :: addMenuOption( QString text, int id )
317{
318 MenuOption *item = new MenuOption( text, id );
319
320 listItems.push_back( item );
321
322 return item;
323}
324
325void Menu :: resetToTopMenu()
326{
327 currentMenu = mainMenu;
328 initCurrentMenu();
329}
330
331void Menu :: initCurrentMenu()
332{
333 if ( currentMenu->currentMenuOption != 0 )
334 currentMenu->currentMenuOption->highlight( false );
335 currentMenu->currentMenuOption = currentMenu->listItems.front();
336 currentMenu->currentMenuOption->highlight( true );
337}