Diffstat (limited to 'noncore/games/sfcave-sdl/menu.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/games/sfcave-sdl/menu.cpp | 337 |
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 | |||
11 | MenuOption :: MenuOption( QString text, int id ) | ||
12 | { | ||
13 | menuText = text; | ||
14 | menuId = id; | ||
15 | nextMenu = 0; | ||
16 | highlighted = false; | ||
17 | } | ||
18 | |||
19 | MenuOption :: ~MenuOption() | ||
20 | { | ||
21 | } | ||
22 | |||
23 | |||
24 | int 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 | |||
40 | void MenuOption :: setNextMenu( Menu *item, bool down ) | ||
41 | { | ||
42 | nextMenu = item; | ||
43 | downMenuTree = down; | ||
44 | } | ||
45 | |||
46 | |||
47 | |||
48 | //----------------- Menu Class ------------- | ||
49 | |||
50 | SDL_Surface * Menu :: sfcaveTextImage; | ||
51 | Menu *Menu :: mainMenu; | ||
52 | Menu *Menu :: currentMenu; | ||
53 | |||
54 | // This is the Master Menu constructor | ||
55 | Menu :: 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 | ||
151 | Menu :: Menu( Menu *p ) | ||
152 | { | ||
153 | parentMenu = p; | ||
154 | //listItems.setAutoDelete( TRUE ); | ||
155 | currentMenuOption = 0; | ||
156 | } | ||
157 | |||
158 | Menu :: ~Menu() | ||
159 | { | ||
160 | if ( this == mainMenu ) | ||
161 | { | ||
162 | SDL_FreeSurface( sfcaveTextImage ); | ||
163 | delete stars; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | void 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 | |||
213 | int 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 | |||
316 | MenuOption *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 | |||
325 | void Menu :: resetToTopMenu() | ||
326 | { | ||
327 | currentMenu = mainMenu; | ||
328 | initCurrentMenu(); | ||
329 | } | ||
330 | |||
331 | void 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 | } | ||