1 #include <stdlib.h>
2 #include <math.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include "glSDL.h"
6 #include "PuyoCommander.h"
7 #include "PuyoStarter.h"
8 #include "PuyoVersion.h"
9 #include "PuyoStory.h"
10 #include "preferences.h"
11 #include "InputManager.h"
12 #include "HiScores.h"
13 #include "PuyoDoomMelt.h"
14 #include "IosImgProcess.h"
15 
16 #ifndef DATADIR
17 extern char *DATADIR;
18 #endif
19 
20 extern const char *p1name;
21 extern const char *p2name;
22 extern int GAME_ACCEL;
23 extern int gameLevel;
24 
25 char *kYouDidIt = "You Dit It!!!";
26 char *kNextLevel = "Next:\t\t";
27 char *kLooser = "Looser!!!";
28 char *kCurrentLevel = "Level:\t\t";
29 char *kContinueLeft = "Continues:\t\t";
30 char *kGameOver = "Game Over!!!";
31 char *kYouGotToLevel = "You Get To ";
32 char *kHitActionToContinue = "Hit Action to continue...";
33 char *kHitActionForMenu = "Hit Action for menu...";
34 char *kContinue    = "Continue?";
35 char *kContinueGame= "Continue Game";
36 char *kAbortGame   = "Abort Game";
37 char *kOptions     = "Options";
38 char *kPlayer      = "Player";
39 char *kScore       = "Score:\t";
40 char *kPlayerName  = "Player Name:\t";
41 char *kPlayer1Name  = "P1 Name:\t";
42 char *kPlayer2Name  = "P2 Name:\t";
43 
44 
45 static const char *k01 = " 1 - ";
46 static const char *k02 = " 2 - ";
47 static const char *k03 = " 3 - ";
48 static const char *k04 = " 4 - ";
49 static const char *k05 = " 5 - ";
50 static const char *k06 = " 6 - ";
51 static const char *k07 = " 7 - ";
52 static const char *k08 = " 8 - ";
53 static const char *k09 = " 9 - ";
54 static const char *k10 = "10 - ";
55 
56 static const char *kMustRestart1 = "Major Video Mode Change...";
57 static const char *kMustRestart2 = "This will take effect next time you restart Flobo Puyo.";
58 char *kHighScores  = "Hall of Fame";
59 
60 static char *kMusicVolume = "MusicVolume";
61 static char *kAudioVolume = "AudioVolume";
62 
63 char *kCongratulations = "Congratulations!!!";
64 char *kPuyosInvasion   = "                        You stopped Puyo's invasion.\n"
65                          "                         Peace on Earth is restored!!";
66 
67 static char *kAudioFX     = "Audio FX\t";
68 static char *kMusic       = "Music\t";
69 static char *kFullScreen  = "FullScreen\t";
70 static char *kOpenGL      = "Use OpenGL\t";
71 static char *kControls    = "Change controls...";
72 static char *kGameLevel   = "Choose Game Level";
73 static char *kLevelEasy   = "Easy";
74 static char *kLevelMedium = "Medium";
75 static char *kLevelHard   = "Hard";
76 
77 static char *kPlayer1Left  = "P2 Left:\t";
78 static char *kPlayer1Right = "P2 Right:\t";
79 static char *kPlayer1Down  = "P2 Down:\t";
80 static char *kPlayer1Clockwise        = "P2 Turn L:\t";
81 static char *kPlayer1Counterclockwise = "P2 Turn R:\t";
82 
83 static char *kPlayer2Left   = "P1 Left:\t";
84 static char *kPlayer2Right  = "P1 Right:\t";
85 static char *kPlayer2Down   = "P1 Down:\t";
86 static char *kPlayer2Clockwise        = "P1 Turn L:\t";
87 static char *kPlayer2Counterclockwise = "P1 Turn R:\t";
88 
89 static char *kRules01 = "Puyos are fancy smiling bubbles...";
90 static char *kRules02 = "But they can really be invading sometimes!";
91 static char *kRules03 = "Send them away by making groups of 4 or more.";
92 static char *kRules04 = "Try to make large groups, or many at the same time";
93 static char *kRules05 = "to send more bad ghost Puyos to your opponent.";
94 
95 static char *kAbout01 = "FloboPuyo is an iOS-software production.\t\t";
96 static char *kAbout02 = "Puyo's world Meta God:\t\t";
97 static char *kAbout03 = "\t\tFlorent 'flobo' Boudet";
98 static char *kAbout04 = "X Men:\t\t";
99 static char *kAbout05 = "\t\tJean-Christophe 'jeko' Hoelt";
100 static char *kAbout06 = "\t\tGuillaume 'gyom' Borios";
101 static char *kAbout07 = "Beta Goddess:\t\t";
102 static char *kAbout08 = "\t\tTania";
103 
104 char *AI_NAMES[] = { "Fanzy", "Garou", "Big Rabbit", "Gizmo",
105   "Satanas", "Doctor X", "Tanya", "Mr Gyom",
106   "The Duke","Jeko","--------" };
107 
108 
109 extern SDL_Surface *display;
110 extern IIM_Surface *image, *gameScreen;
111 IIM_Surface *menuBGImage = 0;
112 PuyoCommander *theCommander;
113 
114 const int cycle_duration = 20;
115 
116 extern bool fullscreen;
117 extern bool useGL;
118 static bool sound = true;
119 static bool fx = true;
120 
121 #define SINGLE_PLAYER_GAME "Single Player Game"
122 #define TWO_PLAYERS_GAME "Two Players Game"
123 
124 MenuItems
main_menu_load(SoFont * font)125 main_menu_load (SoFont * font)
126 {
127   static MenuItemsTab main_menu = {
128     MENUITEM_BLANKLINE,
129     MENUITEM_BLANKLINE,
130     MENUITEM (SINGLE_PLAYER_GAME),
131     MENUITEM (TWO_PLAYERS_GAME),
132     MENUITEM_BLANKLINE,
133     MENUITEM ("Options"),
134     MENUITEM_BLANKLINE,
135     MENUITEM (kHighScores),
136     MENUITEM_BLANKLINE,
137     MENUITEM ("Rules"),
138     MENUITEM ("About FloboPuyo"),
139     MENUITEM_BLANKLINE,
140     MENUITEM ("Quit"),
141     MENUITEM_END
142   };
143   static int loaded = 0;
144 
145   if (!loaded) {
146     menu_items_set_font_for (main_menu, SINGLE_PLAYER_GAME, font);
147     menu_items_set_font_for (main_menu, TWO_PLAYERS_GAME, font);
148     menu_items_set_font_for (main_menu, kHighScores, font);
149     menu_items_set_font_for (main_menu, "Options", font);
150     menu_items_set_font_for (main_menu, "Rules", font);
151     menu_items_set_font_for (main_menu, "About FloboPuyo", font);
152     menu_items_set_font_for (main_menu, "Quit", font);
153     loaded = 1;
154     menuBGImage = IIM_Load_DisplayFormat("MenuBackground.jpg");
155   }
156 
157   return main_menu;
158 }
159 
160 
two_player_game_menu_load(SoFont * font,SoFont * small_font)161 MenuItems two_player_game_menu_load (SoFont *font, SoFont *small_font)
162 {
163   static MenuItemsTab go_menu =
164   {
165     MENUITEM(kPlayer1Name),
166     MENUITEM(kPlayer2Name),
167     MENUITEM_BLANKLINE,
168     MENUITEM_BLANKLINE,
169     MENUITEM_BLANKLINE,
170     MENUITEM_INACTIVE(kGameLevel),
171     MENUITEM_BLANKLINE,
172     MENUITEM(kLevelEasy),
173     MENUITEM(kLevelMedium),
174     MENUITEM(kLevelHard),
175     MENUITEM_END
176   };
177   menu_items_set_font_for(go_menu, kGameLevel,   font);
178   menu_items_set_font_for(go_menu, kLevelEasy,   font);
179   menu_items_set_font_for(go_menu, kLevelMedium, font);
180   menu_items_set_font_for(go_menu, kLevelHard,   font);
181   menu_items_set_font_for(go_menu, kPlayer1Name, font);
182   menu_items_set_font_for(go_menu, kPlayer2Name, font);
183   return go_menu;
184 }
185 
single_game_menu_load(SoFont * font,SoFont * small_font)186 MenuItems single_game_menu_load (SoFont *font, SoFont *small_font)
187 {
188   static MenuItemsTab go_menu =
189   {
190     MENUITEM(kPlayerName),
191     MENUITEM_BLANKLINE,
192     MENUITEM_BLANKLINE,
193     MENUITEM_BLANKLINE,
194     MENUITEM_INACTIVE(kGameLevel),
195     MENUITEM_BLANKLINE,
196     MENUITEM(kLevelEasy),
197     MENUITEM(kLevelMedium),
198     MENUITEM(kLevelHard),
199     MENUITEM_END
200   };
201   menu_items_set_font_for(go_menu, kGameLevel,   font);
202   menu_items_set_font_for(go_menu, kLevelEasy,   font);
203   menu_items_set_font_for(go_menu, kLevelMedium, font);
204   menu_items_set_font_for(go_menu, kLevelHard,   font);
205   menu_items_set_font_for(go_menu, kPlayerName,  font);
206   return go_menu;
207 }
208 
gameover_2p_menu_load(SoFont * font,SoFont * small_font)209 MenuItems gameover_2p_menu_load (SoFont *font, SoFont *small_font)
210 {
211   static MenuItemsTab go_menu = {
212     MENUITEM_BLANKLINE,
213     MENUITEM_BLANKLINE,
214     MENUITEM_BLANKLINE,
215     MENUITEM_BLANKLINE,
216     MENUITEM_BLANKLINE,
217     MENUITEM_INACTIVE(kPlayer),
218     MENUITEM_BLANKLINE,
219     MENUITEM_BLANKLINE,
220     MENUITEM_INACTIVE(kScore),
221     MENUITEM_BLANKLINE,
222     MENUITEM_BLANKLINE,
223     MENUITEM_INACTIVE(kContinue),
224     MENUITEM("YES"),
225     MENUITEM("NO"),
226     MENUITEM_END
227   };
228   menu_items_set_font_for(go_menu, kPlayer,    font);
229   menu_items_set_font_for(go_menu, kScore,     font);
230   menu_items_set_font_for(go_menu, kContinue,  font);
231   return go_menu;
232 }
233 
finished_1p_menu_load(SoFont * font,SoFont * small_font)234 MenuItems finished_1p_menu_load (SoFont *font, SoFont *small_font)
235 {
236   static MenuItemsTab go_menu = {
237     MENUITEM_BLANKLINE,
238     MENUITEM_BLANKLINE,
239     MENUITEM_BLANKLINE,
240     MENUITEM_BLANKLINE,
241     MENUITEM_BLANKLINE,
242     MENUITEM_INACTIVE(kCongratulations),
243     MENUITEM_BLANKLINE,
244     MENUITEM_BLANKLINE,
245     MENUITEM_INACTIVE(kPuyosInvasion),
246     MENUITEM_BLANKLINE,
247     MENUITEM_BLANKLINE,
248     MENUITEM_INACTIVE(kHitActionForMenu),
249     MENUITEM("YES"),
250     MENUITEM("NO"),
251     MENUITEM_END
252   };
253   menu_items_set_font_for(go_menu, kCongratulations,  font);
254   menu_items_set_font_for(go_menu, kPuyosInvasion, font);
255   menu_items_set_font_for(go_menu, kHitActionForMenu, small_font);
256   return go_menu;
257 }
258 
nextlevel_1p_menu_load(SoFont * font,SoFont * small_font)259 MenuItems nextlevel_1p_menu_load (SoFont *font, SoFont *small_font)
260 {
261   static MenuItemsTab go_menu = {
262     MENUITEM_BLANKLINE,
263     MENUITEM_BLANKLINE,
264     MENUITEM_BLANKLINE,
265     MENUITEM_BLANKLINE,
266     MENUITEM_BLANKLINE,
267     MENUITEM_INACTIVE(kYouDidIt),
268     MENUITEM_BLANKLINE,
269     MENUITEM_BLANKLINE,
270     MENUITEM_INACTIVE(kNextLevel),
271     MENUITEM_BLANKLINE,
272     MENUITEM_BLANKLINE,
273     MENUITEM_INACTIVE(kHitActionToContinue),
274     MENUITEM("YES"),
275     MENUITEM("NO"),
276     MENUITEM_END
277   };
278   menu_items_set_font_for(go_menu, kYouDidIt,  font);
279   menu_items_set_font_for(go_menu, kNextLevel, font);
280   menu_items_set_font_for(go_menu, kHitActionToContinue, small_font);
281   return go_menu;
282 }
283 
looser_1p_menu_load(SoFont * font,SoFont * small_font)284 MenuItems looser_1p_menu_load (SoFont *font, SoFont *small_font)
285 {
286   static MenuItemsTab go_menu = {
287     MENUITEM_BLANKLINE,
288     MENUITEM_BLANKLINE,
289     MENUITEM_BLANKLINE,
290     MENUITEM_BLANKLINE,
291     MENUITEM_BLANKLINE,
292     MENUITEM_INACTIVE(kLooser),
293     MENUITEM_BLANKLINE,
294     MENUITEM_BLANKLINE,
295     MENUITEM_INACTIVE(kCurrentLevel),
296     MENUITEM_BLANKLINE,
297     MENUITEM_INACTIVE(kContinueLeft),
298     MENUITEM_BLANKLINE,
299     MENUITEM_BLANKLINE,
300     MENUITEM_INACTIVE(kHitActionToContinue),
301     MENUITEM("YES"),
302     MENUITEM("NO"),
303     MENUITEM_END
304   };
305   menu_items_set_font_for(go_menu, kLooser,  font);
306   menu_items_set_font_for(go_menu, kCurrentLevel, font);
307   menu_items_set_font_for(go_menu, kContinueLeft, font);
308   menu_items_set_font_for(go_menu, kHitActionToContinue, small_font);
309   return go_menu;
310 }
311 
gameover_1p_menu_load(SoFont * font,SoFont * small_font)312 MenuItems gameover_1p_menu_load (SoFont *font, SoFont *small_font)
313 {
314   static MenuItemsTab go_menu = {
315     MENUITEM_BLANKLINE,
316     MENUITEM_BLANKLINE,
317     MENUITEM_BLANKLINE,
318     MENUITEM_BLANKLINE,
319     MENUITEM_BLANKLINE,
320     MENUITEM_INACTIVE(kGameOver),
321     MENUITEM_BLANKLINE,
322     MENUITEM_BLANKLINE,
323     MENUITEM_INACTIVE(kYouGotToLevel),
324     MENUITEM_BLANKLINE,
325     MENUITEM_BLANKLINE,
326     MENUITEM_INACTIVE(kHitActionForMenu),
327     MENUITEM("YES"),
328     MENUITEM("NO"),
329     MENUITEM_END
330   };
331   menu_items_set_font_for(go_menu, kGameOver,    font);
332   menu_items_set_font_for(go_menu, kYouGotToLevel, font);
333   menu_items_set_font_for(go_menu, kHitActionForMenu,  small_font);
334   return go_menu;
335 }
336 
rules_menu_load(SoFont * font)337 MenuItems rules_menu_load (SoFont *font) {
338   static MenuItemsTab option_menu = {
339     MENUITEM_INACTIVE(kRules01),
340     MENUITEM_INACTIVE(kRules02),
341     MENUITEM_BLANKLINE,
342     MENUITEM_INACTIVE(kRules03),
343     MENUITEM_BLANKLINE,
344     MENUITEM_INACTIVE(kRules04),
345     MENUITEM_INACTIVE(kRules05),
346     MENUITEM_BLANKLINE,
347     MENUITEM("Back"),
348     MENUITEM_END
349   };
350   menu_items_set_font_for(option_menu, kRules01, font);
351   menu_items_set_font_for(option_menu, kRules02, font);
352   menu_items_set_font_for(option_menu, kRules03, font);
353   menu_items_set_font_for(option_menu, kRules04, font);
354   menu_items_set_font_for(option_menu, kRules05, font);
355 
356   return option_menu;
357 }
358 
high_scores_menu_load(SoFont * font)359 MenuItems high_scores_menu_load (SoFont *font)
360 {
361   static MenuItemsTab option_menu =
362   {
363     MENUITEM_INACTIVE(kHighScores),
364     MENUITEM_BLANKLINE,
365     MENUITEM_BLANKLINE,
366     MENUITEM_BLANKLINE,
367     MENUITEM_INACTIVE(k01),
368     MENUITEM_INACTIVE(k02),
369     MENUITEM_INACTIVE(k03),
370     MENUITEM_INACTIVE(k04),
371     MENUITEM_INACTIVE(k05),
372     MENUITEM_INACTIVE(k06),
373     MENUITEM_INACTIVE(k07),
374     MENUITEM_INACTIVE(k08),
375     MENUITEM_INACTIVE(k09),
376     MENUITEM_INACTIVE(k10),
377     MENUITEM("Back"),
378     MENUITEM_END
379   };
380   menu_items_set_font_for(option_menu, kHighScores, font);
381   menu_items_set_font_for(option_menu, k01, font);
382   menu_items_set_font_for(option_menu, k02, font);
383   menu_items_set_font_for(option_menu, k03, font);
384   menu_items_set_font_for(option_menu, k04, font);
385   menu_items_set_font_for(option_menu, k05, font);
386   menu_items_set_font_for(option_menu, k06, font);
387   menu_items_set_font_for(option_menu, k07, font);
388   menu_items_set_font_for(option_menu, k08, font);
389   menu_items_set_font_for(option_menu, k09, font);
390   menu_items_set_font_for(option_menu, k10, font);
391 
392   return option_menu;
393 }
394 
about_menu_load(SoFont * font)395 MenuItems about_menu_load (SoFont *font)
396 {
397   static MenuItemsTab option_menu = {
398     MENUITEM_INACTIVE(kAbout01),
399     MENUITEM_BLANKLINE,
400     MENUITEM_INACTIVE(kVersion),
401     MENUITEM_BLANKLINE,
402     MENUITEM_INACTIVE(kAbout02),
403     MENUITEM_INACTIVE(kAbout03),
404     MENUITEM_BLANKLINE,
405     MENUITEM_INACTIVE(kAbout04),
406     MENUITEM_INACTIVE(kAbout05),
407     MENUITEM_INACTIVE(kAbout06),
408     MENUITEM_BLANKLINE,
409     MENUITEM_INACTIVE(kAbout07),
410     MENUITEM_INACTIVE(kAbout08),
411     MENUITEM_BLANKLINE,
412     MENUITEM("Back"),
413     MENUITEM_END
414   };
415   menu_items_set_font_for(option_menu, kAbout01, font);
416   menu_items_set_font_for(option_menu, kVersion, font);
417   menu_items_set_font_for(option_menu, kAbout02, font);
418   menu_items_set_font_for(option_menu, kAbout03, font);
419   menu_items_set_font_for(option_menu, kAbout04, font);
420   menu_items_set_font_for(option_menu, kAbout05, font);
421   menu_items_set_font_for(option_menu, kAbout06, font);
422   menu_items_set_font_for(option_menu, kAbout07, font);
423   menu_items_set_font_for(option_menu, kAbout08, font);
424 
425   return option_menu;
426 }
427 
must_restart_menu_load(SoFont * font)428 MenuItems must_restart_menu_load (SoFont *font)
429 {
430   static MenuItemsTab option_menu = {
431     MENUITEM_BLANKLINE,
432     MENUITEM_BLANKLINE,
433     MENUITEM_INACTIVE(kMustRestart1),
434     MENUITEM_BLANKLINE,
435     MENUITEM_BLANKLINE,
436     MENUITEM_INACTIVE(kMustRestart2),
437     MENUITEM_BLANKLINE,
438     MENUITEM("Back"),
439     MENUITEM_END
440   };
441   menu_items_set_font_for(option_menu, kMustRestart1, font);
442   menu_items_set_font_for(option_menu, kMustRestart2, font);
443   return option_menu;
444 }
445 
options_menu_load(SoFont * font,SoFont * small_font)446 MenuItems options_menu_load (SoFont *font, SoFont *small_font)
447 {
448   static MenuItemsTab option_menu = {
449     MENUITEM(kFullScreen),
450 #ifdef HAVE_OPENGL
451     MENUITEM(kOpenGL),
452 #endif
453     MENUITEM_BLANKLINE,
454     MENUITEM(kMusic),
455     MENUITEM(kAudioFX),
456     MENUITEM_BLANKLINE,
457     MENUITEM(kControls),
458     MENUITEM_BLANKLINE,
459     MENUITEM("Back"),
460     MENUITEM_END
461   };
462   menu_items_set_font_for(option_menu,  kMusic, font);
463   menu_items_set_font_for(option_menu,  kAudioFX, font);
464   menu_items_set_font_for(option_menu,  kControls, font);
465   menu_items_set_font_for(option_menu,  "Back", font);
466   menu_items_set_font_for(option_menu,  kFullScreen, font);
467   menu_items_set_value_for(option_menu, kFullScreen, fullscreen?"ON":"OFF");
468 #ifdef HAVE_OPENGL
469   menu_items_set_font_for(option_menu,  kOpenGL, font);
470   menu_items_set_value_for(option_menu, kOpenGL, useGL?"ON":"OFF");
471 #endif
472   menu_items_set_value_for(option_menu, kMusic,      sound?"ON":"OFF");
473   menu_items_set_value_for(option_menu, kAudioFX,    fx?"ON":"OFF");
474   return option_menu;
475 }
476 
controls_menu_load(SoFont * font,SoFont * small_font)477 MenuItems controls_menu_load (SoFont *font, SoFont *small_font)
478 {
479   static MenuItemsTab controls_menu = {
480     //MENUITEM("Player 1 Joystick"),
481     //MENUITEM("Player 2 Joystick"),
482     MENUITEM_BLANKLINE,
483     MENUITEM(kPlayer2Left),
484     MENUITEM(kPlayer2Right),
485     MENUITEM(kPlayer2Down),
486     MENUITEM(kPlayer2Clockwise),
487     MENUITEM(kPlayer2Counterclockwise),
488     MENUITEM_BLANKLINE,
489     MENUITEM(kPlayer1Left),
490     MENUITEM(kPlayer1Right),
491     MENUITEM(kPlayer1Down),
492     MENUITEM(kPlayer1Clockwise),
493     MENUITEM(kPlayer1Counterclockwise),
494     MENUITEM_BLANKLINE,
495     MENUITEM("Back"),
496     MENUITEM_END
497   };
498   //menu_items_set_font_for(controls_menu,  "Player 1 Joystick", font);
499 
500   menu_items_set_font_for(controls_menu,  kPlayer1Left, font);
501   menu_items_set_font_for(controls_menu,  kPlayer1Right, font);
502   menu_items_set_font_for(controls_menu,  kPlayer1Down, font);
503   menu_items_set_font_for(controls_menu,  kPlayer1Clockwise, font);
504   menu_items_set_font_for(controls_menu,  kPlayer1Counterclockwise, font);
505 
506   menu_items_set_font_for(controls_menu,  kPlayer2Left, font);
507   menu_items_set_font_for(controls_menu,  kPlayer2Right, font);
508   menu_items_set_font_for(controls_menu,  kPlayer2Down, font);
509   menu_items_set_font_for(controls_menu,  kPlayer2Clockwise, font);
510   menu_items_set_font_for(controls_menu,  kPlayer2Counterclockwise, font);
511 
512   menu_items_set_font_for(controls_menu,  "Back", font);
513  //menu_items_set_value_for(controls_menu, "Player 1 Joystick", SDL_JoystickName(0));
514   //menu_items_set_value_for(controls_menu, kPlayer1Left, "s");
515   return controls_menu;
516 }
517 
518 Menu *menu_pause = NULL;
519 
pause_menu_load(SoFont * font)520 MenuItems pause_menu_load (SoFont * font)
521 {
522   static MenuItemsTab main_menu = {
523     MENUITEM_BLANKLINE,
524     MENUITEM_BLANKLINE,
525     MENUITEM (kContinueGame),
526     MENUITEM_BLANKLINE,
527     MENUITEM (kOptions),
528     MENUITEM_BLANKLINE,
529     MENUITEM_BLANKLINE,
530     MENUITEM (kAbortGame),
531     MENUITEM_END
532   };
533   static int loaded = 0;
534 
535   if (!loaded) {
536     menu_items_set_font_for (main_menu, kContinueGame, font);
537     menu_items_set_font_for (main_menu, kOptions, font);
538     menu_items_set_font_for (main_menu, kAbortGame, font);
539     loaded = 1;
540   }
541 
542   return main_menu;
543 }
544 
PuyoCommander(bool fs,bool snd,bool audio)545 PuyoCommander::PuyoCommander(bool fs, bool snd, bool audio)
546 {
547   int init_flags = SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK;
548 
549   SDL_Delay(500);
550   corona = NULL;
551   fullscreen = GetBoolPreference(kFullScreen,fs);
552 #ifdef HAVE_OPENGL
553   useGL      = GetBoolPreference(kOpenGL,false);
554 #endif
555   sound = GetBoolPreference(kMusic,snd);
556   fx = GetBoolPreference(kAudioFX,audio);
557 
558   int music_volume = GetIntPreference(kMusicVolume, 100);
559   int audio_volume = GetIntPreference(kAudioVolume, 80);
560 
561   initGameControls();
562 #ifdef USE_DGA
563   /* This Hack Allows Hardware Surface on Linux */
564   if (fullscreen)
565     setenv("SDL_VIDEODRIVER","dga",0);
566 
567   if (SDL_Init(init_flags) < 0) {
568     setenv("SDL_VIDEODRIVER","x11",1);
569     if (SDL_Init(init_flags) < 0) {
570       fprintf(stderr, "SDL initialisation error:  %s\n", SDL_GetError());
571       exit(1);
572     }
573   }
574   else {
575     if (fullscreen)
576       SDL_WM_GrabInput(SDL_GRAB_ON);
577   }
578 #else
579 #ifdef WIN32
580   _putenv("SDL_VIDEODRIVER=windib");
581 #endif
582   if ( SDL_Init(init_flags) < 0 ) {
583     fprintf(stderr, "SDL initialisation error:  %s\n", SDL_GetError());
584     exit(1);
585   }
586 #endif
587 
588   initControllers();
589   initHiScores(AI_NAMES);
590 
591 #ifdef USE_AUDIO
592   audio_init();
593   audio_music_start(0);
594   if (sound==false) Mix_PauseMusic();
595   audio_set_music_on_off(sound);
596   audio_set_sound_on_off(fx);
597 
598   audio_set_volume(audio_volume);
599   audio_music_set_volume(music_volume);
600 #endif
601 
602   display = SDL_SetVideoMode( 640, 480, 0,  SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF|(fullscreen?SDL_FULLSCREEN:0)|(useGL?SDL_GLSDL:0));
603   if ( display == NULL ) {
604     fprintf(stderr, "SDL_SetVideoMode error: %s\n",
605             SDL_GetError());
606     exit(1);
607   }
608   atexit(SDL_Quit);
609   SDL_ShowCursor(SDL_DISABLE);
610 
611   smallFont = SoFont_new();
612   SoFont_load (smallFont, IIM_Load_DisplayFormatAlpha ("font4b.png"));
613   menuFont = SoFont_new();
614   SoFont_load (menuFont, IIM_Load_DisplayFormatAlpha ("font3b.png"));
615   darkFont = SoFont_new();
616   SoFont_load (darkFont, IIM_Load_DisplayFormatAlpha ("fontdark.png"));
617 
618   IIM_Surface * menuselector = IIM_Load_DisplayFormatAlpha("menusel.png");
619 
620   mainMenu = menu_new(main_menu_load(menuFont),menuselector);
621   gameOver1PMenu = menu_new(gameover_1p_menu_load(menuFont, smallFont),menuselector);
622   gameOver2PMenu = menu_new(gameover_2p_menu_load(menuFont, smallFont),menuselector);
623   nextLevelMenu  = menu_new(nextlevel_1p_menu_load(menuFont, smallFont),menuselector);
624   looserMenu     = menu_new(looser_1p_menu_load(menuFont, smallFont),menuselector);
625   finishedMenu   = menu_new(finished_1p_menu_load(menuFont, smallFont),menuselector);
626   gameOverMenu   = gameOver2PMenu;
627   optionMenu     = menu_new(options_menu_load(menuFont, smallFont),menuselector);
628   controlsMenu   = menu_new(controls_menu_load(menuFont, smallFont),menuselector);
629   rulesMenu      = menu_new(rules_menu_load(menuFont),menuselector);
630   highScoresMenu = menu_new(high_scores_menu_load(menuFont),menuselector);
631   aboutMenu      = menu_new(about_menu_load(menuFont),menuselector);
632   singleGameMenu    = menu_new(single_game_menu_load(menuFont,smallFont),menuselector);
633   twoPlayerGameMenu = menu_new(two_player_game_menu_load(menuFont,smallFont),menuselector);
634   mustRestartMenu   = menu_new(must_restart_menu_load(menuFont),menuselector);
635 
636   if (menu_pause == NULL) menu_pause = menu_new(pause_menu_load(menuFont),menuselector);
637 
638   menu_set_sounds (optionMenu,     sound_pop, sound_slide);
639   menu_set_sounds (controlsMenu,   sound_pop, sound_slide);
640   menu_set_sounds (mainMenu,       sound_pop, sound_slide);
641   menu_set_sounds (rulesMenu,      sound_pop, sound_slide);
642   menu_set_sounds (highScoresMenu, sound_pop, sound_slide);
643   menu_set_sounds (aboutMenu,      sound_pop, sound_slide);
644   menu_set_sounds (singleGameMenu, sound_pop, sound_slide);
645   menu_set_sounds (twoPlayerGameMenu, sound_pop, sound_slide);
646   menu_set_sounds (menu_pause    , sound_pop, sound_slide);
647   melt = doom_melt_new();
648 
649   scrollingText = scrolling_text_new(
650     "Welcome to the wonderful world of FloboPuyo !!!  Enjoy its nice graphics, "
651     "happy music and entertaining gameplay...  "
652     "Will you be able to defeat all of the mighty players ?  "
653     "Will you beat the Puyo Gods ???  Have a try !  "
654     "We wish you good luck.                                                    "
655     "                                Hello from PuyoLand !", smallFont);
656   theCommander = this;
657 }
658 
run()659 void PuyoCommander::run()
660 {
661     Menu   *menu = mainMenu;
662 
663     cycle = 0;
664     lastRenderedCycle = 0;
665     maxFrameDrop = 10;
666 
667     start_time = SDL_GetTicks ();
668 
669     audio_music_start (0);
670 
671     /*  PuyoStory *introStory = new PuyoStory(this, 0);
672     introStory->loop();
673     delete introStory; */
674 
675     menu_show (menu);
676 
677     while (1) {
678         SDL_Event e;
679 
680         while (SDL_PollEvent (&e)) {
681             GameControlEvent controlEvent;
682             getControlEvent(e, &controlEvent);
683 
684             switch (controlEvent.cursorEvent) {
685                 case GameControlEvent::kQuit:
686                     goto mml_fin;
687                     break;
688                 case GameControlEvent::kDown:
689                     menu_next_item (menu);
690                     break;
691                 case GameControlEvent::kUp:
692                     menu_prev_item (menu);
693                     break;
694                 case GameControlEvent::kStart:
695                     menu_validate (menu);
696                     if (menu_active_is (menu, "Quit"))
697                         goto mml_fin;
698                     if (menu_active_is (menu, "Options")) {
699                         menu_hide (menu);
700                         optionMenuLoop(NULL);
701                         menu_show (menu);
702                     }
703                     if (menu_active_is (menu, kHighScores)) {
704                         menu_hide(menu);
705                         updateHighScoresMenu();
706                         backLoop(highScoresMenu);
707                         menu_show(menu);
708                     }
709                     if (menu_active_is (menu, "Rules")) {
710                         menu_hide(menu);
711                         backLoop(rulesMenu);
712                         menu_show(menu);
713                     }
714                     if (menu_active_is (menu, "About FloboPuyo")) {
715                         menu_hide(menu);
716                         backLoop(aboutMenu);
717                         menu_show(menu);
718                     }
719                     if (menu_active_is (menu, SINGLE_PLAYER_GAME)) {
720                         menu_hide (menu);
721                         startSingleGameLoop();
722                         menu_show (menu);
723                     }
724                     if (menu_active_is (menu, TWO_PLAYERS_GAME)) {
725                         menu_hide (menu);
726                         startTwoPlayerGameLoop();
727                         menu_show (menu);
728                         audio_music_start(0);
729                     }
730                     break;
731                 case GameControlEvent::kBack:
732                     goto mml_fin;
733                     break;
734                 default:
735                     break;
736             }
737         }
738     updateAll(NULL);
739   }
740 mml_fin:
741   menu_hide (menu);
742 }
743 
updateHighScoresMenu(int newOne)744 void PuyoCommander::updateHighScoresMenu(int newOne)
745 {
746   hiscore *scores = getHiScores();
747   char tmp[256];
748 #define PAS_DE_COMMENTAIRES(X,kXX) \
749   if (newOne == X)  \
750     sprintf(tmp, "%s\t** %d", scores[X].name, scores[X].score); \
751   else \
752     sprintf(tmp, "%s\t%d", scores[X].name, scores[X].score); \
753   menu_set_value(highScoresMenu,kXX,tmp,0);
754 
755   PAS_DE_COMMENTAIRES(0,k01);
756   PAS_DE_COMMENTAIRES(1,k02);
757   PAS_DE_COMMENTAIRES(2,k03);
758   PAS_DE_COMMENTAIRES(3,k04);
759   PAS_DE_COMMENTAIRES(4,k05);
760   PAS_DE_COMMENTAIRES(5,k06);
761   PAS_DE_COMMENTAIRES(6,k07);
762   PAS_DE_COMMENTAIRES(7,k08);
763   PAS_DE_COMMENTAIRES(8,k09);
764   PAS_DE_COMMENTAIRES(9,k10);
765 }
766 
changeControlLoop(int controlIndex,PuyoDrawable * starter)767 bool PuyoCommander::changeControlLoop(int controlIndex, PuyoDrawable *starter)
768 {
769   bool keyPressed = false;
770   while (1) {
771     SDL_Event e;
772 
773     while (SDL_PollEvent (&e)) {
774       GameControlEvent controlEvent;
775       bool tryOk = tryChangeControl(controlIndex, e, &controlEvent);
776 
777       switch (controlEvent.cursorEvent) {
778         case GameControlEvent::kQuit:
779           exit(0);
780           goto mml_fin;
781           break;
782         case GameControlEvent::kBack:
783           goto mml_fin;
784           break;
785         default:
786           break;
787       }
788       if (tryOk) {
789         keyPressed = true;
790         goto mml_fin;
791       }
792     }
793     updateAll(starter);
794   }
795 mml_fin:
796   return keyPressed;
797 }
798 
controlsMenuLoop(PuyoDrawable * d)799 void PuyoCommander::controlsMenuLoop(PuyoDrawable *d)
800 {
801   char newKeyName[250];
802 
803   getKeyName(kPlayer1LeftControl, newKeyName);
804   menu_set_value(controlsMenu, kPlayer1Left, newKeyName,0);
805   getKeyName(kPlayer1RightControl, newKeyName);
806   menu_set_value(controlsMenu, kPlayer1Right, newKeyName,0);
807   getKeyName(kPlayer1DownControl, newKeyName);
808   menu_set_value(controlsMenu, kPlayer1Down, newKeyName,0);
809   getKeyName(kPlayer1ClockwiseControl, newKeyName);
810   menu_set_value(controlsMenu, kPlayer1Clockwise, newKeyName,0);
811   getKeyName(kPlayer1CounterclockwiseControl, newKeyName);
812   menu_set_value(controlsMenu, kPlayer1Counterclockwise, newKeyName,0);
813 
814   getKeyName(kPlayer2LeftControl, newKeyName);
815   menu_set_value(controlsMenu, kPlayer2Left, newKeyName,0);
816   getKeyName(kPlayer2RightControl, newKeyName);
817   menu_set_value(controlsMenu, kPlayer2Right, newKeyName,0);
818   getKeyName(kPlayer2DownControl, newKeyName);
819   menu_set_value(controlsMenu, kPlayer2Down, newKeyName,0);
820   getKeyName(kPlayer2ClockwiseControl, newKeyName);
821   menu_set_value(controlsMenu, kPlayer2Clockwise, newKeyName,0);
822   getKeyName(kPlayer2CounterclockwiseControl, newKeyName);
823   menu_set_value(controlsMenu, kPlayer2Counterclockwise, newKeyName,1);
824 
825   menu_show(controlsMenu);
826   while (1) {
827     SDL_Event e;
828 
829     while (SDL_PollEvent (&e)) {
830       char *chosenControl = NULL;
831       int chosenControlIndex;
832       GameControlEvent controlEvent;
833       getControlEvent(e, &controlEvent);
834 
835       switch (controlEvent.cursorEvent) {
836         case GameControlEvent::kQuit:
837           exit(0);
838           goto mml_fin;
839           break;
840         case GameControlEvent::kUp:
841           menu_prev_item (controlsMenu);
842           break;
843         case GameControlEvent::kDown:
844           menu_next_item (controlsMenu);
845           break;
846         case GameControlEvent::kStart:
847           menu_validate (controlsMenu);
848           if (menu_active_is (controlsMenu, "Back"))
849             goto mml_fin;
850 
851           if (menu_active_is (controlsMenu, kPlayer1Left)) {
852             chosenControl = kPlayer1Left;
853             chosenControlIndex = kPlayer1LeftControl;
854           }
855           if (menu_active_is (controlsMenu, kPlayer1Right)) {
856             chosenControl = kPlayer1Right;
857             chosenControlIndex = kPlayer1RightControl;
858           }
859           if (menu_active_is (controlsMenu, kPlayer1Down)) {
860             chosenControl = kPlayer1Down;
861             chosenControlIndex = kPlayer1DownControl;
862           }
863           if (menu_active_is (controlsMenu, kPlayer1Clockwise)) {
864             chosenControl = kPlayer1Clockwise;
865             chosenControlIndex = kPlayer1ClockwiseControl;
866           }
867           if (menu_active_is (controlsMenu, kPlayer1Counterclockwise)) {
868             chosenControl = kPlayer1Counterclockwise;
869             chosenControlIndex = kPlayer1CounterclockwiseControl;
870           }
871 
872           if (menu_active_is (controlsMenu, kPlayer2Left)) {
873             chosenControl = kPlayer2Left;
874             chosenControlIndex = kPlayer2LeftControl;
875           }
876           if (menu_active_is (controlsMenu, kPlayer2Right)) {
877             chosenControl = kPlayer2Right;
878             chosenControlIndex = kPlayer2RightControl;
879           }
880           if (menu_active_is (controlsMenu, kPlayer2Down)) {
881             chosenControl = kPlayer2Down;
882             chosenControlIndex = kPlayer2DownControl;
883           }
884           if (menu_active_is (controlsMenu, kPlayer2Clockwise)) {
885             chosenControl = kPlayer2Clockwise;
886             chosenControlIndex = kPlayer2ClockwiseControl;
887           }
888           if (menu_active_is (controlsMenu, kPlayer2Counterclockwise)) {
889             chosenControl = kPlayer2Counterclockwise;
890             chosenControlIndex = kPlayer2CounterclockwiseControl;
891           }
892 
893           if (chosenControl != NULL) {
894             char prevValue[255];
895             strcpy(prevValue, menu_get_value (controlsMenu, chosenControl));
896             menu_set_value(controlsMenu, chosenControl, "<Choose>");
897             if (changeControlLoop(chosenControlIndex, d)) {
898               getKeyName(chosenControlIndex, newKeyName);
899               menu_set_value(controlsMenu, chosenControl, newKeyName);
900               menu_next_item (controlsMenu);
901             }
902             else {
903               menu_set_value(controlsMenu, chosenControl, prevValue);
904             }
905           }
906           break;
907         case GameControlEvent::kBack:
908           goto mml_fin;
909           break;
910         default:
911           break;
912       }
913     }
914 
915     updateAll(d);
916   }
917 mml_fin:
918   saveControls();
919   menu_hide (controlsMenu);
920 }
921 
optionMenuLoop(PuyoDrawable * d)922 void PuyoCommander::optionMenuLoop(PuyoDrawable *d)
923 {
924   menu_show(optionMenu);
925   while (1) {
926     SDL_Event e;
927 
928     while (SDL_PollEvent (&e)) {
929       GameControlEvent controlEvent;
930       getControlEvent(e, &controlEvent);
931 
932       switch (controlEvent.cursorEvent) {
933         case GameControlEvent::kQuit:
934           exit(0);
935           goto mml_fin;
936           break;
937         case GameControlEvent::kUp:
938           menu_prev_item (optionMenu);
939           break;
940         case GameControlEvent::kDown:
941           menu_next_item (optionMenu);
942           break;
943         case GameControlEvent::kStart:
944           menu_validate (optionMenu);
945           if (menu_active_is (optionMenu, "Back"))
946             goto mml_fin;
947           if (menu_active_is (optionMenu, kFullScreen)) {
948             fullscreen  = menu_switch_on_off(optionMenu, kFullScreen);
949             SetBoolPreference(kFullScreen,fullscreen);
950             if (useGL)
951             {
952               menu_hide(optionMenu);
953               backLoop(mustRestartMenu,d);
954               menu_show(optionMenu);
955             }
956             else
957             {
958 #ifdef _WIN32
959                 menu_hide(optionMenu);
960                 backLoop(mustRestartMenu,d);
961                 menu_show(optionMenu);
962 #else
963                 SDL_QuitSubSystem(SDL_INIT_VIDEO);
964                 SDL_InitSubSystem(SDL_INIT_VIDEO);
965                 display = SDL_SetVideoMode(640, 480, 0,
966                                            SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF
967                                            |(fullscreen?SDL_FULLSCREEN:0)|(useGL?SDL_GLSDL:0));
968 #endif
969               /* IIM_ReConvertAll();
970               SoFont_Refresh(menuFont);
971               SoFont_Refresh(smallFont);
972               SoFont_Refresh(darkFont); */
973             }
974           }
975           if (menu_active_is (optionMenu, kOpenGL)) {
976             bool useGL2 = menu_switch_on_off(optionMenu, kOpenGL);
977             SetBoolPreference(kOpenGL,useGL2);
978             menu_hide(optionMenu);
979             backLoop(mustRestartMenu,d);
980             menu_show(optionMenu);
981           }
982           if (menu_active_is (optionMenu, kMusic)) {
983             sound = menu_switch_on_off(optionMenu, kMusic);
984             SetBoolPreference(kMusic,sound);
985             audio_set_music_on_off(sound);
986             if (sound) audio_music_start(0);
987           }
988           if (menu_active_is (optionMenu, kAudioFX)) {
989             fx = menu_switch_on_off(optionMenu, kAudioFX);
990             SetBoolPreference(kAudioFX,fx);
991             audio_set_sound_on_off(fx);
992           }
993           if (menu_active_is (optionMenu, kControls)) {
994             menu_hide (optionMenu);
995             controlsMenuLoop(d);
996             menu_show(optionMenu);
997           }
998           break;
999         case GameControlEvent::kBack:
1000           goto mml_fin;
1001           break;
1002         default:
1003           break;
1004       }
1005     }
1006 
1007     updateAll(d);
1008   }
1009 mml_fin:
1010   menu_hide (optionMenu);
1011 }
1012 
backLoop(Menu * menu,PuyoDrawable * starter)1013 void PuyoCommander::backLoop(Menu *menu, PuyoDrawable *starter)
1014 {
1015 
1016     if (menu == aboutMenu) {
1017         corona = corona32_new();
1018         corona32_resize(corona, 640, CORONA_HEIGHT);
1019         corona_screen = (int*)calloc(640 * CORONA_HEIGHT + 64, sizeof(int));
1020     }
1021 
1022     menu_show(menu);
1023     while (1) {
1024         SDL_Event e;
1025 
1026         while (SDL_PollEvent (&e)) {
1027             GameControlEvent controlEvent;
1028             getControlEvent(e, &controlEvent);
1029 
1030             switch (controlEvent.cursorEvent) {
1031                 case GameControlEvent::kQuit:
1032                     exit(0);
1033                     goto mml_fin;
1034                 case GameControlEvent::kStart:
1035                 case GameControlEvent::kBack:
1036                     goto mml_fin;
1037                     break;
1038             }
1039         }
1040         updateAll(starter);
1041     }
1042 mml_fin:
1043     menu_hide (menu);
1044     if (corona)
1045     {
1046         corona32_delete(corona);
1047         free(corona_screen);
1048         corona = NULL;
1049     }
1050 }
1051 
enterStringLoop(Menu * menu,const char * kItem,char out[256])1052 void PuyoCommander::enterStringLoop(Menu *menu, const char *kItem, char out[256])
1053 {
1054   int len = 0;
1055   char prevValue[256];
1056   strcpy(prevValue, menu_get_value (menu, kItem));
1057   out[0] = '_';
1058   out[1] = 0;
1059   menu_set_value(menu, kItem, "_");
1060 
1061   while (1)
1062   {
1063     SDL_Event e;
1064 
1065     while (SDL_PollEvent (&e)) {
1066       GameControlEvent controlEvent;
1067       getControlEvent(e, &controlEvent);
1068       switch (controlEvent.cursorEvent) {
1069         case GameControlEvent::kQuit:
1070           exit(0);
1071           break;
1072         case GameControlEvent::kStart:
1073           out[len] = 0;
1074           menu_set_value(menu, kItem, out);
1075           menu_validate (menu);
1076           return;
1077         case GameControlEvent::kBack:
1078           strcpy(out, prevValue);
1079           menu_set_value(menu, kItem, prevValue);
1080           return;
1081       }
1082       switch (e.type) {
1083         case SDL_KEYDOWN:
1084           {
1085             char ch = 0;
1086             if ((e.key.keysym.sym >= SDLK_a) && (e.key.keysym.sym <= SDLK_z))
1087               ch = e.key.keysym.sym;
1088 
1089             if ((ch >= 'a') && (ch <= 'z')) {
1090               if ((len == 0) || (out[len-1] == ' '))
1091                 ch = ch - 'a' + 'A';
1092             }
1093 
1094             if (e.key.keysym.sym == SDLK_SPACE)
1095               ch = ' ';
1096 
1097             if ((ch!=0) && (len < 10)) {
1098               out[len++] = ch;
1099               out[len]   = '_';
1100               out[len+1] = 0;
1101             }
1102 
1103             if ((e.key.keysym.sym == SDLK_BACKSPACE) && (len > 0))
1104             {
1105               out[len] = 0;
1106               out[--len] = '_';
1107             }
1108             menu_set_value(menu, kItem, out, 0);
1109           }
1110           break;
1111       }
1112     }
1113     updateAll(NULL);
1114   }
1115 }
1116 
1117 
startTwoPlayerGameLoop()1118 void PuyoCommander::startTwoPlayerGameLoop()
1119 {
1120   char player1Name[256];
1121   char player2Name[256];
1122 
1123   GetStrPreference("Player1 Name", player1Name, "Player 1");
1124   GetStrPreference("Player2 Name", player2Name, "Player 2");
1125   menu_set_value(twoPlayerGameMenu, kPlayer1Name, player1Name, 0);
1126   menu_set_value(twoPlayerGameMenu, kPlayer2Name, player2Name, 0);
1127 
1128   while (!menu_active_is(twoPlayerGameMenu,kLevelMedium))
1129     menu_next_item(twoPlayerGameMenu);
1130 
1131   menu_show(twoPlayerGameMenu);
1132   while (1) {
1133     SDL_Event e;
1134 
1135     while (SDL_PollEvent (&e)) {
1136       GameControlEvent controlEvent;
1137         getControlEvent(e, &controlEvent);
1138         switch (controlEvent.cursorEvent) {
1139             case GameControlEvent::kQuit:
1140                 exit(0);
1141                 break;
1142             case GameControlEvent::kDown:
1143                 menu_next_item (twoPlayerGameMenu);
1144                 break;
1145             case GameControlEvent::kUp:
1146                 menu_prev_item (twoPlayerGameMenu);
1147                 break;
1148             case GameControlEvent::kStart:
1149                 menu_validate (twoPlayerGameMenu);
1150                 if (menu_active_is(twoPlayerGameMenu,kPlayer2Name)) {
1151                   enterStringLoop(twoPlayerGameMenu,kPlayer2Name,player2Name);
1152                   menu_next_item (twoPlayerGameMenu);
1153                 }
1154                 else if (menu_active_is(twoPlayerGameMenu,kPlayer1Name)) {
1155                   enterStringLoop(twoPlayerGameMenu,kPlayer1Name,player1Name);
1156                   menu_next_item (twoPlayerGameMenu);
1157                 }
1158                 else
1159                   goto mml_play;
1160                 break;
1161             case GameControlEvent::kBack:
1162                 menu_hide(twoPlayerGameMenu);
1163                 return;
1164                 break;
1165         }
1166     }
1167     updateAll(NULL);
1168   }
1169 
1170 mml_play:
1171   menu_hide (twoPlayerGameMenu);
1172 
1173   GAME_ACCEL = 2000;
1174   gameLevel = 1;
1175   if (menu_active_is (twoPlayerGameMenu, kLevelMedium)) {
1176     GAME_ACCEL = 1500;
1177     gameLevel = 2;
1178   }
1179   else if (menu_active_is (twoPlayerGameMenu, kLevelHard)) {
1180     GAME_ACCEL = 1000;
1181     gameLevel = 3;
1182   }
1183 
1184   int score1 = 0;
1185   int score2 = 0;
1186   gameOverMenu = gameOver2PMenu;
1187   int currentMusicTheme = 0;
1188   if (menu_active_is(gameOverMenu, "NO"))
1189     menu_next_item(gameOverMenu);
1190   while (menu_active_is(gameOverMenu, "YES")) {
1191     menu_next_item(gameOverMenu);
1192     PuyoStarter myStarter(this,false,0,RANDOM,currentMusicTheme);
1193     audio_music_switch_theme(currentMusicTheme);
1194     p1name = player1Name;
1195     p2name = player2Name;
1196     GAME_ACCEL = 1500;
1197     doom_melt_start(melt, menuBGImage);
1198     myStarter.run(score1, score2, 0, 0, 0);
1199     score1 += myStarter.leftPlayerWin();
1200     score2 += myStarter.rightPlayerWin();
1201     currentMusicTheme = (currentMusicTheme + 1) % NB_MUSIC_THEME;
1202   }
1203 
1204   SetStrPreference("Player1 Name", player1Name);
1205   SetStrPreference("Player2 Name", player2Name);
1206   doom_melt_start(melt, gameScreen);
1207 }
1208 
1209 
1210 struct SelIA {
1211   IA_Type type;
1212   int level;
1213 };
1214 
startSingleGameLoop()1215 void PuyoCommander::startSingleGameLoop()
1216 {
1217   char playerName[256];
1218 
1219     char * defaultName = getenv("USER");
1220     if (defaultName == NULL)
1221       defaultName = "Player";
1222     if (!(defaultName[0]>=32))
1223       defaultName = "Player";
1224     if ((defaultName[0]>='a') && (defaultName[0]<='z'))
1225       defaultName[0] += 'A' - 'a';
1226 
1227   GetStrPreference("Player Name", playerName, defaultName);
1228   menu_set_value(singleGameMenu, kPlayerName, playerName, 0);
1229 
1230   while (!menu_active_is(singleGameMenu,kLevelMedium))
1231     menu_next_item(singleGameMenu);
1232 
1233   menu_show(singleGameMenu);
1234   while (1) {
1235     SDL_Event e;
1236 
1237     while (SDL_PollEvent (&e)) {
1238       GameControlEvent controlEvent;
1239         getControlEvent(e, &controlEvent);
1240         switch (controlEvent.cursorEvent) {
1241             case GameControlEvent::kQuit:
1242                 exit(0);
1243                 break;
1244             case GameControlEvent::kDown:
1245                 menu_next_item (singleGameMenu);
1246                 break;
1247             case GameControlEvent::kUp:
1248                 menu_prev_item (singleGameMenu);
1249                 break;
1250             case GameControlEvent::kStart:
1251                 menu_validate (singleGameMenu);
1252                 if (menu_active_is(singleGameMenu,kPlayerName))
1253                   enterStringLoop(singleGameMenu,kPlayerName,playerName);
1254                 else
1255                   goto mml_play;
1256                 break;
1257             case GameControlEvent::kBack:
1258                 menu_hide(singleGameMenu);
1259                 return;
1260                 break;
1261         }
1262     }
1263     updateAll(NULL);
1264   }
1265 
1266 mml_play:
1267   menu_hide (singleGameMenu);
1268 
1269   SelIA ia1[] = { {RANDOM, 350}, {FLOBO, 350}, {FLOBO, 250}, {FLOBO, 180}, {FLOBO,  90}, {JEKO, 350}, {TANIA, 320}, {FLOBO, 62}, {RANDOM,0} };
1270   SelIA ia2[] = { {FLOBO,  190}, {JEKO , 180}, {TANIA, 160}, {FLOBO,  90}, {GYOM , 210}, {TANIA, 90}, {JEKO,   80}, {GYOM,  90}, {RANDOM,0} };
1271   SelIA ia3[] = { {TANIA,  130}, {JEKO , 100}, {GYOM ,  90}, {JEKO,   80}, {TANIA,  60}, {GYOM,  60}, {GYOM,   40}, {GYOM,  30}, {RANDOM,0} };
1272 
1273   SelIA *ia = &(ia1[0]);
1274 
1275   gameLevel = 1;
1276   GAME_ACCEL = 2000;
1277   if (menu_active_is (singleGameMenu, kLevelMedium)) {
1278     ia = &(ia2[0]);
1279     GAME_ACCEL = 1500;
1280     gameLevel = 2;
1281   }
1282   else if (menu_active_is (singleGameMenu, kLevelHard)) {
1283     ia = &(ia3[0]);
1284     GAME_ACCEL = 1000;
1285     gameLevel = 3;
1286   }
1287 
1288   int score1 = 0;
1289   int score2 = 0;
1290   int lives  = 3;
1291   if (menu_active_is(finishedMenu,  "NO"))
1292     menu_next_item(finishedMenu);
1293   if (menu_active_is(looserMenu   ,  "NO"))
1294     menu_next_item(looserMenu);
1295   if (menu_active_is(nextLevelMenu,  "NO"))
1296     menu_next_item(nextLevelMenu);
1297   if (menu_active_is(gameOver2PMenu, "NO"))
1298     menu_next_item(gameOver2PMenu);
1299   gameOverMenu = nextLevelMenu;
1300 
1301   int lastPoints = 0;
1302   int currentMusicTheme = 0;
1303 
1304   int fini = 0;
1305   while (!fini)
1306   {
1307     PuyoStory myStory(this, score2+1);
1308     myStory.loop();
1309     PuyoStarter myStarter(this, true, ia[score2].level, ia[score2].type, currentMusicTheme);
1310     p1name = playerName;
1311     p2name = AI_NAMES[score2];
1312     doom_melt_start(melt, menuBGImage);
1313     audio_music_switch_theme(currentMusicTheme);
1314     myStarter.run(score1, score2, lives, lastPoints, 0);
1315     lastPoints = myStarter.rightPlayerPoints();
1316     score1 += myStarter.leftPlayerWin();
1317     score2 += myStarter.rightPlayerWin();
1318     if (!myStarter.rightPlayerWin())
1319       lives--;
1320     else {
1321       currentMusicTheme = (currentMusicTheme + 1) % NB_MUSIC_THEME;
1322     }
1323 
1324     if (ia[score2].level == 0) {
1325       lastPoints += 100000;
1326       if (menu_active_is (singleGameMenu, kLevelMedium))
1327         lastPoints += 150000;
1328       if (menu_active_is (singleGameMenu, kLevelHard))
1329         lastPoints += 250000;
1330       fini = 1;
1331     }
1332 
1333     if (!(menu_active_is(gameOverMenu, "YES") && (lives >= 0)))
1334       fini = 1;
1335 
1336     if (fini)
1337     {
1338       audio_music_start(0);
1339       int newOne = setHiScore(lastPoints, p1name);
1340       if (newOne >= 0)
1341       {
1342         updateHighScoresMenu(newOne);
1343         backLoop(highScoresMenu, &myStarter);
1344       }
1345     }
1346   }
1347   SetStrPreference("Player Name", playerName);
1348   doom_melt_start(melt, gameScreen);
1349 }
1350 
1351 #define TIME_TOLERANCE 4
1352 
updateAll(PuyoDrawable * starter,SDL_Surface * extra_surf)1353 void PuyoCommander::updateAll(PuyoDrawable *starter, SDL_Surface *extra_surf)
1354 {
1355   Uint32  now = 0;
1356 
1357   // mise a jour
1358   menu_update (mainMenu, display);
1359 
1360   menu_update(gameOver2PMenu, display);
1361   menu_update(gameOver1PMenu, display);
1362   menu_update(nextLevelMenu, display);
1363   menu_update(finishedMenu, display);
1364   menu_update(looserMenu, display);
1365 
1366   menu_update (optionMenu, display);
1367   menu_update (controlsMenu, display);
1368   menu_update (rulesMenu, display);
1369   menu_update (highScoresMenu, display);
1370   menu_update (aboutMenu, display);
1371   menu_update (mustRestartMenu, display);
1372   menu_update (singleGameMenu, display);
1373   menu_update (twoPlayerGameMenu, display);
1374   menu_update (menu_pause,display);
1375   scrolling_text_update(scrollingText, display);
1376   doom_melt_update(melt);
1377 
1378   // affichage eventuel (pourrait ne pas avoir lieu de tps en tps si machine
1379   // trop lente)
1380   cycle++;
1381   now = SDL_GetTicks ();
1382 
1383   if ((now < (start_time + (cycle + TIME_TOLERANCE) * cycle_duration))
1384                   || (cycle - lastRenderedCycle > maxFrameDrop))
1385   {
1386     lastRenderedCycle = cycle;
1387 
1388     if (starter) {
1389       starter->draw();
1390     }
1391     else {
1392       SDL_BlitSurface (menuBGImage->surf, NULL, display, NULL);
1393     }
1394 
1395     if (corona)
1396     {
1397         short frequency[2][512];
1398         for (int i=0; i<512; ++i) { // Generate random sound.
1399             frequency[0][i] = rand();
1400             frequency[1][i] = rand();
1401         }
1402         corona32_update(corona, SDL_GetTicks(), frequency);
1403         corona32_displayRGBA(corona, corona_screen);
1404         SDL_Surface *tmpsurf =
1405             SDL_CreateRGBSurfaceFrom (corona_screen, 640, CORONA_HEIGHT,
1406                                       32, 640*4,
1407                                       0x00ff0000, 0x0000ff00, 0x000000ff,
1408                                       0xff000000);
1409         SDL_Rect rect;
1410         rect.x = 0;
1411         rect.y = 480 - tmpsurf->h;
1412         rect.w = tmpsurf->w;
1413         rect.h = tmpsurf->h;
1414         SDL_BlitSurface(tmpsurf, NULL, display, &rect);
1415         SDL_FreeSurface (tmpsurf);
1416     }
1417     if (extra_surf)
1418     {
1419         SDL_Rect rect;
1420         rect.x = 0;
1421         rect.y = 480 - extra_surf->h;
1422         rect.w = extra_surf->w;
1423         rect.h = extra_surf->h;
1424         SDL_BlitSurface(extra_surf, NULL, display, &rect);
1425     }
1426 
1427     if (!starter)
1428       scrolling_text_draw(scrollingText, display, 460);
1429 
1430     menu_draw (mainMenu, display);
1431     menu_draw(gameOver2PMenu, display);
1432     menu_draw(gameOver1PMenu, display);
1433     menu_draw(nextLevelMenu, display);
1434     menu_draw(finishedMenu, display);
1435     menu_draw(looserMenu, display);
1436     menu_draw (optionMenu, display);
1437     menu_draw (controlsMenu, display);
1438     menu_draw (rulesMenu, display);
1439     menu_draw (highScoresMenu, display);
1440     menu_draw (aboutMenu, display);
1441     menu_draw (mustRestartMenu, display);
1442     menu_draw (singleGameMenu, display);
1443     menu_draw (twoPlayerGameMenu, display);
1444     menu_draw(menu_pause,display);
1445     doom_melt_display(melt, display);
1446     SDL_Flip (display);
1447   }
1448 
1449   // delay si machine trop rapide
1450   now = SDL_GetTicks ();
1451   if (now < (start_time + cycle * cycle_duration)) {
1452     int ttw = ((start_time + cycle * cycle_duration) - now);
1453     ttw /= 2;
1454     SDL_Delay (ttw);
1455   }
1456 }
1457 
1458 
1459