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
17extern char *DATADIR;
18#endif
19
20extern const char *p1name;
21extern const char *p2name;
22extern int GAME_ACCEL;
23extern int gameLevel;
24
25char *kYouDidIt = "You Dit It!!!";
26char *kNextLevel = "Next:\t\t";
27char *kLooser = "Looser!!!";
28char *kCurrentLevel = "Level:\t\t";
29char *kContinueLeft = "Continues:\t\t";
30char *kGameOver = "Game Over!!!";
31char *kYouGotToLevel = "You Get To ";
32char *kHitActionToContinue = "Hit Action to continue...";
33char *kHitActionForMenu = "Hit Action for menu...";
34char *kContinue    = "Continue?";
35char *kContinueGame= "Continue Game";
36char *kAbortGame   = "Abort Game";
37char *kOptions     = "Options";
38char *kPlayer      = "Player";
39char *kScore       = "Score:\t";
40char *kPlayerName  = "Player Name:\t";
41char *kPlayer1Name  = "P1 Name:\t";
42char *kPlayer2Name  = "P2 Name:\t";
43
44
45static const char *k01 = " 1 - ";
46static const char *k02 = " 2 - ";
47static const char *k03 = " 3 - ";
48static const char *k04 = " 4 - ";
49static const char *k05 = " 5 - ";
50static const char *k06 = " 6 - ";
51static const char *k07 = " 7 - ";
52static const char *k08 = " 8 - ";
53static const char *k09 = " 9 - ";
54static const char *k10 = "10 - ";
55
56static const char *kMustRestart1 = "Major Video Mode Change...";
57static const char *kMustRestart2 = "This will take effect next time you restart Flobo Puyo.";
58char *kHighScores  = "Hall of Fame";
59
60static char *kMusicVolume = "MusicVolume";
61static char *kAudioVolume = "AudioVolume";
62
63char *kCongratulations = "Congratulations!!!";
64char *kPuyosInvasion   = "You stopped Puyo's invasion.\n"
65                         "Peace on Earth is restored!!";
66
67static char *kAudioFX     = "Audio FX\t";
68static char *kMusic       = "Music\t";
69static char *kFullScreen  = "FullScreen\t";
70static char *kOpenGL      = "Use OpenGL\t";
71static char *kControls    = "Change controls...";
72static char *kGameLevel   = "Choose Game Level";
73static char *kLevelEasy   = "Easy";
74static char *kLevelMedium = "Medium";
75static char *kLevelHard   = "Hard";
76
77static char *kPlayer1Left  = "P2 Left:\t";
78static char *kPlayer1Right = "P2 Right:\t";
79static char *kPlayer1Down  = "P2 Down:\t";
80static char *kPlayer1Clockwise        = "P2 Turn L:\t";
81static char *kPlayer1Counterclockwise = "P2 Turn R:\t";
82
83static char *kPlayer2Left   = "P1 Left:\t";
84static char *kPlayer2Right  = "P1 Right:\t";
85static char *kPlayer2Down   = "P1 Down:\t";
86static char *kPlayer2Clockwise        = "P1 Turn L:\t";
87static char *kPlayer2Counterclockwise = "P1 Turn R:\t";
88
89static char *kRules01 = "Puyos are fancy smiling bubbles...";
90static char *kRules02 = "But they can really be invading sometimes!";
91static char *kRules03 = "Send them away by making groups of 4 or more.";
92static char *kRules04 = "Try to make large groups, or many at the same time";
93static char *kRules05 = "to send more bad ghost Puyos to your opponent.";
94
95static char *kAbout01 = "FloboPuyo is an iOS-software production.\t\t";
96static char *kAbout02 = "Puyo's world Meta God:\t\t";
97static char *kAbout03 = "\t\tFlorent 'flobo' Boudet";
98static char *kAbout04 = "X Men:\t\t";
99static char *kAbout05 = "\t\tJean-Christophe 'jeko' Hoelt";
100static char *kAbout06 = "\t\tGuillaume 'gyom' Borios";
101static char *kAbout07 = "Beta Goddess:\t\t";
102static char *kAbout08 = "\t\tTania";
103
104char *AI_NAMES[] = { "Fanzy", "Garou", "Big Rabbit", "Gizmo",
105  "Satanas", "Doctor X", "Tanya", "Mr Gyom",
106  "The Duke","Jeko","--------" };
107
108
109extern SDL_Surface *display;
110extern IIM_Surface *image, *gameScreen;
111IIM_Surface *menuBGImage = 0;
112PuyoCommander *theCommander;
113
114const int cycle_duration = 20;
115
116extern bool fullscreen;
117extern bool useGL;
118static bool sound = true;
119static bool fx = true;
120
121#define SINGLE_PLAYER_GAME "Single Player Game"
122#define TWO_PLAYERS_GAME "Two Players Game"
123
124MenuItems
125main_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
161MenuItems 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
186MenuItems 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
209MenuItems 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
234MenuItems 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
259MenuItems 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
284MenuItems 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
312MenuItems 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
337MenuItems 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
359MenuItems 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
395MenuItems 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
428MenuItems 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
446MenuItems 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
477MenuItems 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
518Menu *menu_pause = NULL;
519
520MenuItems 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
545PuyoCommander::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  fullscreen = GetBoolPreference(kFullScreen,fs);
551#ifdef HAVE_OPENGL
552  useGL      = GetBoolPreference(kOpenGL,false);
553#endif
554  sound = GetBoolPreference(kMusic,snd);
555  fx = GetBoolPreference(kAudioFX,audio);
556
557  int music_volume = GetIntPreference(kMusicVolume, 100);
558  int audio_volume = GetIntPreference(kAudioVolume, 80);
559
560  initGameControls();
561#ifdef __linux__
562  /* This Hack Allows Hardware Surface on Linux */
563  if (fullscreen)
564    setenv("SDL_VIDEODRIVER","dga",0);
565
566  if (SDL_Init(init_flags) < 0) {
567    setenv("SDL_VIDEODRIVER","x11",1);
568    if (SDL_Init(init_flags) < 0) {
569      fprintf(stderr, "SDL initialisation error:  %s\n", SDL_GetError());
570      exit(1);
571    }
572  }
573  else {
574    if (fullscreen)
575      SDL_WM_GrabInput(SDL_GRAB_ON);
576  }
577#else
578  if ( SDL_Init(init_flags) < 0 ) {
579    fprintf(stderr, "SDL initialisation error:  %s\n", SDL_GetError());
580    exit(1);
581  }
582#endif
583
584  initControllers();
585  initHiScores(AI_NAMES);
586
587#ifdef USE_AUDIO
588  audio_init();
589  audio_music_start(0);
590  if (sound==false) Mix_PauseMusic();
591  audio_set_music_on_off(sound);
592  audio_set_sound_on_off(fx);
593
594  audio_set_volume(audio_volume);
595  audio_music_set_volume(music_volume);
596#endif
597
598  display = SDL_SetVideoMode( 640, 480, 0,  SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF|(fullscreen?SDL_FULLSCREEN:0)|(useGL?SDL_GLSDL:0));
599  if ( display == NULL ) {
600    fprintf(stderr, "SDL_SetVideoMode error: %s\n",
601            SDL_GetError());
602    exit(1);
603  }
604  atexit(SDL_Quit);
605  SDL_ShowCursor(SDL_DISABLE);
606
607  smallFont = SoFont_new();
608  SoFont_load (smallFont, IIM_Load_DisplayFormatAlpha ("font4b.png"));
609  menuFont = SoFont_new();
610  SoFont_load (menuFont, IIM_Load_DisplayFormatAlpha ("font3b.png"));
611  darkFont = SoFont_new();
612  SoFont_load (darkFont, IIM_Load_DisplayFormatAlpha ("fontdark.png"));
613
614  IIM_Surface * menuselector = IIM_Load_DisplayFormatAlpha("menusel.png");
615
616  mainMenu = menu_new(main_menu_load(menuFont),menuselector);
617  gameOver1PMenu = menu_new(gameover_1p_menu_load(menuFont, smallFont),menuselector);
618  gameOver2PMenu = menu_new(gameover_2p_menu_load(menuFont, smallFont),menuselector);
619  nextLevelMenu  = menu_new(nextlevel_1p_menu_load(menuFont, smallFont),menuselector);
620  looserMenu     = menu_new(looser_1p_menu_load(menuFont, smallFont),menuselector);
621  finishedMenu   = menu_new(finished_1p_menu_load(menuFont, smallFont),menuselector);
622  gameOverMenu   = gameOver2PMenu;
623  optionMenu     = menu_new(options_menu_load(menuFont, smallFont),menuselector);
624  controlsMenu   = menu_new(controls_menu_load(menuFont, smallFont),menuselector);
625  rulesMenu      = menu_new(rules_menu_load(menuFont),menuselector);
626  highScoresMenu = menu_new(high_scores_menu_load(menuFont),menuselector);
627  aboutMenu      = menu_new(about_menu_load(menuFont),menuselector);
628  singleGameMenu    = menu_new(single_game_menu_load(menuFont,smallFont),menuselector);
629  twoPlayerGameMenu = menu_new(two_player_game_menu_load(menuFont,smallFont),menuselector);
630  mustRestartMenu   = menu_new(must_restart_menu_load(menuFont),menuselector);
631
632  if (menu_pause == NULL) menu_pause = menu_new(pause_menu_load(menuFont),menuselector);
633
634  menu_set_sounds (optionMenu,     sound_pop, sound_slide);
635  menu_set_sounds (controlsMenu,   sound_pop, sound_slide);
636  menu_set_sounds (mainMenu,       sound_pop, sound_slide);
637  menu_set_sounds (rulesMenu,      sound_pop, sound_slide);
638  menu_set_sounds (highScoresMenu, sound_pop, sound_slide);
639  menu_set_sounds (aboutMenu,      sound_pop, sound_slide);
640  menu_set_sounds (singleGameMenu, sound_pop, sound_slide);
641  menu_set_sounds (twoPlayerGameMenu, sound_pop, sound_slide);
642  menu_set_sounds (menu_pause    , sound_pop, sound_slide);
643  melt = doom_melt_new();
644
645  scrollingText = scrolling_text_new(
646    "Welcome to the wonderful world of FloboPuyo !!!  Enjoy its nice graphics, "
647    "happy music and entertaining gameplay...  "
648    "Will you be able to defeat all of the mighty players ?  "
649    "Will you beat the Puyo Gods ???  Have a try !  "
650    "We wish you good luck.                                                    "
651    "                                Hello from PuyoLand !", smallFont);
652  theCommander = this;
653}
654
655void PuyoCommander::run()
656{
657    Menu   *menu = mainMenu;
658
659    cycle = 0;
660    lastRenderedCycle = 0;
661    maxFrameDrop = 10;
662
663    start_time = SDL_GetTicks ();
664
665    audio_music_start (0);
666
667    /*  PuyoStory *introStory = new PuyoStory(this, 0);
668    introStory->loop();
669    delete introStory; */
670
671    menu_show (menu);
672
673    while (1) {
674        SDL_Event e;
675
676        while (SDL_PollEvent (&e)) {
677            GameControlEvent controlEvent;
678            getControlEvent(e, &controlEvent);
679
680            switch (controlEvent.cursorEvent) {
681                case GameControlEvent::kQuit:
682                    goto mml_fin;
683                    break;
684                case GameControlEvent::kDown:
685                    menu_next_item (menu);
686                    break;
687                case GameControlEvent::kUp:
688                    menu_prev_item (menu);
689                    break;
690                case GameControlEvent::kStart:
691                    menu_validate (menu);
692                    if (menu_active_is (menu, "Quit"))
693                        goto mml_fin;
694                    if (menu_active_is (menu, "Options")) {
695                        menu_hide (menu);
696                        optionMenuLoop(NULL);
697                        menu_show (menu);
698                    }
699                    if (menu_active_is (menu, kHighScores)) {
700                        menu_hide(menu);
701                        updateHighScoresMenu();
702                        backLoop(highScoresMenu);
703                        menu_show(menu);
704                    }
705                    if (menu_active_is (menu, "Rules")) {
706                        menu_hide(menu);
707                        backLoop(rulesMenu);
708                        menu_show(menu);
709                    }
710                    if (menu_active_is (menu, "About FloboPuyo")) {
711                        menu_hide(menu);
712                        backLoop(aboutMenu);
713                        menu_show(menu);
714                    }
715                    if (menu_active_is (menu, SINGLE_PLAYER_GAME)) {
716                        menu_hide (menu);
717                        startSingleGameLoop();
718                        menu_show (menu);
719                    }
720                    if (menu_active_is (menu, TWO_PLAYERS_GAME)) {
721                        menu_hide (menu);
722                        startTwoPlayerGameLoop();
723                        menu_show (menu);
724                        audio_music_start(0);
725                    }
726                    break;
727                case GameControlEvent::kBack:
728                    goto mml_fin;
729                    break;
730                default:
731                    break;
732            }
733        }
734    updateAll(NULL);
735  }
736mml_fin:
737  menu_hide (menu);
738}
739
740void PuyoCommander::updateHighScoresMenu(int newOne)
741{
742  hiscore *scores = getHiScores();
743  char tmp[256];
744#define PAS_DE_COMMENTAIRES(X,kXX) \
745  if (newOne == X)  \
746    sprintf(tmp, "%s\t** %d", scores[X].name, scores[X].score); \
747  else \
748    sprintf(tmp, "%s\t%d", scores[X].name, scores[X].score); \
749  menu_set_value(highScoresMenu,kXX,tmp,0);
750
751  PAS_DE_COMMENTAIRES(0,k01);
752  PAS_DE_COMMENTAIRES(1,k02);
753  PAS_DE_COMMENTAIRES(2,k03);
754  PAS_DE_COMMENTAIRES(3,k04);
755  PAS_DE_COMMENTAIRES(4,k05);
756  PAS_DE_COMMENTAIRES(5,k06);
757  PAS_DE_COMMENTAIRES(6,k07);
758  PAS_DE_COMMENTAIRES(7,k08);
759  PAS_DE_COMMENTAIRES(8,k09);
760  PAS_DE_COMMENTAIRES(9,k10);
761}
762
763bool PuyoCommander::changeControlLoop(int controlIndex, PuyoDrawable *starter)
764{
765  bool keyPressed = false;
766  while (1) {
767    SDL_Event e;
768
769    while (SDL_PollEvent (&e)) {
770      GameControlEvent controlEvent;
771      bool tryOk = tryChangeControl(controlIndex, e, &controlEvent);
772
773      switch (controlEvent.cursorEvent) {
774        case GameControlEvent::kQuit:
775          exit(0);
776          goto mml_fin;
777          break;
778        case GameControlEvent::kBack:
779          goto mml_fin;
780          break;
781        default:
782          break;
783      }
784      if (tryOk) {
785        keyPressed = true;
786        goto mml_fin;
787      }
788    }
789    updateAll(starter);
790  }
791mml_fin:
792  return keyPressed;
793}
794
795void PuyoCommander::controlsMenuLoop(PuyoDrawable *d)
796{
797  char newKeyName[250];
798
799  getKeyName(kPlayer1LeftControl, newKeyName);
800  menu_set_value(controlsMenu, kPlayer1Left, newKeyName,0);
801  getKeyName(kPlayer1RightControl, newKeyName);
802  menu_set_value(controlsMenu, kPlayer1Right, newKeyName,0);
803  getKeyName(kPlayer1DownControl, newKeyName);
804  menu_set_value(controlsMenu, kPlayer1Down, newKeyName,0);
805  getKeyName(kPlayer1ClockwiseControl, newKeyName);
806  menu_set_value(controlsMenu, kPlayer1Clockwise, newKeyName,0);
807  getKeyName(kPlayer1CounterclockwiseControl, newKeyName);
808  menu_set_value(controlsMenu, kPlayer1Counterclockwise, newKeyName,0);
809
810  getKeyName(kPlayer2LeftControl, newKeyName);
811  menu_set_value(controlsMenu, kPlayer2Left, newKeyName,0);
812  getKeyName(kPlayer2RightControl, newKeyName);
813  menu_set_value(controlsMenu, kPlayer2Right, newKeyName,0);
814  getKeyName(kPlayer2DownControl, newKeyName);
815  menu_set_value(controlsMenu, kPlayer2Down, newKeyName,0);
816  getKeyName(kPlayer2ClockwiseControl, newKeyName);
817  menu_set_value(controlsMenu, kPlayer2Clockwise, newKeyName,0);
818  getKeyName(kPlayer2CounterclockwiseControl, newKeyName);
819  menu_set_value(controlsMenu, kPlayer2Counterclockwise, newKeyName,1);
820
821  menu_show(controlsMenu);
822  while (1) {
823    SDL_Event e;
824
825    while (SDL_PollEvent (&e)) {
826      char *chosenControl = NULL;
827      int chosenControlIndex;
828      GameControlEvent controlEvent;
829      getControlEvent(e, &controlEvent);
830
831      switch (controlEvent.cursorEvent) {
832        case GameControlEvent::kQuit:
833          exit(0);
834          goto mml_fin;
835          break;
836        case GameControlEvent::kUp:
837          menu_prev_item (controlsMenu);
838          break;
839        case GameControlEvent::kDown:
840          menu_next_item (controlsMenu);
841          break;
842        case GameControlEvent::kStart:
843          menu_validate (controlsMenu);
844          if (menu_active_is (controlsMenu, "Back"))
845            goto mml_fin;
846
847          if (menu_active_is (controlsMenu, kPlayer1Left)) {
848            chosenControl = kPlayer1Left;
849            chosenControlIndex = kPlayer1LeftControl;
850          }
851          if (menu_active_is (controlsMenu, kPlayer1Right)) {
852            chosenControl = kPlayer1Right;
853            chosenControlIndex = kPlayer1RightControl;
854          }
855          if (menu_active_is (controlsMenu, kPlayer1Down)) {
856            chosenControl = kPlayer1Down;
857            chosenControlIndex = kPlayer1DownControl;
858          }
859          if (menu_active_is (controlsMenu, kPlayer1Clockwise)) {
860            chosenControl = kPlayer1Clockwise;
861            chosenControlIndex = kPlayer1ClockwiseControl;
862          }
863          if (menu_active_is (controlsMenu, kPlayer1Counterclockwise)) {
864            chosenControl = kPlayer1Counterclockwise;
865            chosenControlIndex = kPlayer1CounterclockwiseControl;
866          }
867
868          if (menu_active_is (controlsMenu, kPlayer2Left)) {
869            chosenControl = kPlayer2Left;
870            chosenControlIndex = kPlayer2LeftControl;
871          }
872          if (menu_active_is (controlsMenu, kPlayer2Right)) {
873            chosenControl = kPlayer2Right;
874            chosenControlIndex = kPlayer2RightControl;
875          }
876          if (menu_active_is (controlsMenu, kPlayer2Down)) {
877            chosenControl = kPlayer2Down;
878            chosenControlIndex = kPlayer2DownControl;
879          }
880          if (menu_active_is (controlsMenu, kPlayer2Clockwise)) {
881            chosenControl = kPlayer2Clockwise;
882            chosenControlIndex = kPlayer2ClockwiseControl;
883          }
884          if (menu_active_is (controlsMenu, kPlayer2Counterclockwise)) {
885            chosenControl = kPlayer2Counterclockwise;
886            chosenControlIndex = kPlayer2CounterclockwiseControl;
887          }
888
889          if (chosenControl != NULL) {
890            char prevValue[255];
891            strcpy(prevValue, menu_get_value (controlsMenu, chosenControl));
892            menu_set_value(controlsMenu, chosenControl, "<Choose>");
893            if (changeControlLoop(chosenControlIndex, d)) {
894              getKeyName(chosenControlIndex, newKeyName);
895              menu_set_value(controlsMenu, chosenControl, newKeyName);
896              menu_next_item (controlsMenu);
897            }
898            else {
899              menu_set_value(controlsMenu, chosenControl, prevValue);
900            }
901          }
902          break;
903        case GameControlEvent::kBack:
904          goto mml_fin;
905          break;
906        default:
907          break;
908      }
909    }
910
911    updateAll(d);
912  }
913mml_fin:
914  saveControls();
915  menu_hide (controlsMenu);
916}
917
918void PuyoCommander::optionMenuLoop(PuyoDrawable *d)
919{
920  menu_show(optionMenu);
921  while (1) {
922    SDL_Event e;
923
924    while (SDL_PollEvent (&e)) {
925      GameControlEvent controlEvent;
926      getControlEvent(e, &controlEvent);
927
928      switch (controlEvent.cursorEvent) {
929        case GameControlEvent::kQuit:
930          exit(0);
931          goto mml_fin;
932          break;
933        case GameControlEvent::kUp:
934          menu_prev_item (optionMenu);
935          break;
936        case GameControlEvent::kDown:
937          menu_next_item (optionMenu);
938          break;
939        case GameControlEvent::kStart:
940          menu_validate (optionMenu);
941          if (menu_active_is (optionMenu, "Back"))
942            goto mml_fin;
943          if (menu_active_is (optionMenu, kFullScreen)) {
944            fullscreen  = menu_switch_on_off(optionMenu, kFullScreen);
945            SetBoolPreference(kFullScreen,fullscreen);
946            if (useGL)
947            {
948              menu_hide(optionMenu);
949              backLoop(mustRestartMenu,d);
950              menu_show(optionMenu);
951            }
952            else
953            {
954#ifdef _WIN32
955                menu_hide(optionMenu);
956                backLoop(mustRestartMenu,d);
957                menu_show(optionMenu);
958#else
959                SDL_QuitSubSystem(SDL_INIT_VIDEO);
960                SDL_InitSubSystem(SDL_INIT_VIDEO);
961                display = SDL_SetVideoMode(640, 480, 0,
962                                           SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF
963                                           |(fullscreen?SDL_FULLSCREEN:0)|(useGL?SDL_GLSDL:0));
964#endif
965              /* IIM_ReConvertAll();
966              SoFont_Refresh(menuFont);
967              SoFont_Refresh(smallFont);
968              SoFont_Refresh(darkFont); */
969            }
970          }
971          if (menu_active_is (optionMenu, kOpenGL)) {
972            bool useGL2 = menu_switch_on_off(optionMenu, kOpenGL);
973            SetBoolPreference(kOpenGL,useGL2);
974            menu_hide(optionMenu);
975            backLoop(mustRestartMenu,d);
976            menu_show(optionMenu);
977          }
978          if (menu_active_is (optionMenu, kMusic)) {
979            sound = menu_switch_on_off(optionMenu, kMusic);
980            SetBoolPreference(kMusic,sound);
981            audio_set_music_on_off(sound);
982            if (sound) audio_music_start(0);
983          }
984          if (menu_active_is (optionMenu, kAudioFX)) {
985            fx = menu_switch_on_off(optionMenu, kAudioFX);
986            SetBoolPreference(kAudioFX,fx);
987            audio_set_sound_on_off(fx);
988          }
989          if (menu_active_is (optionMenu, kControls)) {
990            menu_hide (optionMenu);
991            controlsMenuLoop(d);
992            menu_show(optionMenu);
993          }
994          break;
995        case GameControlEvent::kBack:
996          goto mml_fin;
997          break;
998        default:
999          break;
1000      }
1001    }
1002
1003    updateAll(d);
1004  }
1005mml_fin:
1006  menu_hide (optionMenu);
1007}
1008
1009#include "corona32.h"
1010#define CORONA_HEIGHT 120
1011
1012void PuyoCommander::backLoop(Menu *menu, PuyoDrawable *starter)
1013{
1014    Corona32 *corona = NULL;
1015    int      *corona_screen;
1016
1017    if (menu == aboutMenu) {
1018        corona = corona32_new();
1019        corona32_resize(corona, 640, CORONA_HEIGHT);
1020        corona_screen = (int*)calloc(640 * CORONA_HEIGHT + 64, sizeof(int));
1021    }
1022
1023    menu_show(menu);
1024    while (1) {
1025        SDL_Event e;
1026
1027        while (SDL_PollEvent (&e)) {
1028            GameControlEvent controlEvent;
1029            getControlEvent(e, &controlEvent);
1030
1031            switch (controlEvent.cursorEvent) {
1032                case GameControlEvent::kQuit:
1033                    exit(0);
1034                    goto mml_fin;
1035                case GameControlEvent::kStart:
1036                case GameControlEvent::kBack:
1037                    goto mml_fin;
1038                    break;
1039            }
1040        }
1041
1042        if (corona)
1043        {
1044            short frequency[2][512];
1045            for (int i=0; i<512; ++i) { // Generate random sound.
1046                frequency[0][i] = rand();
1047                frequency[1][i] = rand();
1048            }
1049            corona32_update(corona, SDL_GetTicks(), frequency);
1050            corona32_displayRGBA(corona, corona_screen);
1051            SDL_Surface *tmpsurf =
1052              SDL_CreateRGBSurfaceFrom (corona_screen, 640, CORONA_HEIGHT,
1053                                        32, 640*4,
1054                                        0x00ff0000, 0x0000ff00, 0x000000ff,
1055                                        0xff000000);
1056            updateAll(starter, tmpsurf);
1057            SDL_FreeSurface (tmpsurf);
1058        }
1059        else
1060            updateAll(starter);
1061    }
1062mml_fin:
1063    menu_hide (menu);
1064    if (corona)
1065    {
1066        corona32_delete(corona);
1067        free(corona_screen);
1068    }
1069}
1070
1071void PuyoCommander::enterStringLoop(Menu *menu, const char *kItem, char out[256])
1072{
1073  int len = 0;
1074  char prevValue[256];
1075  strcpy(prevValue, menu_get_value (menu, kItem));
1076  out[0] = '_';
1077  out[1] = 0;
1078  menu_set_value(menu, kItem, "_");
1079
1080  while (1)
1081  {
1082    SDL_Event e;
1083
1084    while (SDL_PollEvent (&e)) {
1085      GameControlEvent controlEvent;
1086      getControlEvent(e, &controlEvent);
1087      switch (controlEvent.cursorEvent) {
1088        case GameControlEvent::kQuit:
1089          exit(0);
1090          break;
1091        case GameControlEvent::kStart:
1092          out[len] = 0;
1093          menu_set_value(menu, kItem, out);
1094          menu_validate (menu);
1095          return;
1096        case GameControlEvent::kBack:
1097          strcpy(out, prevValue);
1098          menu_set_value(menu, kItem, prevValue);
1099          return;
1100      }
1101      switch (e.type) {
1102        case SDL_KEYDOWN:
1103          {
1104            char ch = 0;
1105            if ((e.key.keysym.sym >= SDLK_a) && (e.key.keysym.sym <= SDLK_z))
1106              ch = e.key.keysym.sym;
1107
1108            if ((ch >= 'a') && (ch <= 'z')) {
1109              if ((len == 0) || (out[len-1] == ' '))
1110                ch = ch - 'a' + 'A';
1111            }
1112
1113            if (e.key.keysym.sym == SDLK_SPACE)
1114              ch = ' ';
1115
1116            if ((ch!=0) && (len < 10)) {
1117              out[len++] = ch;
1118              out[len]   = '_';
1119              out[len+1] = 0;
1120            }
1121
1122            if ((e.key.keysym.sym == SDLK_BACKSPACE) && (len > 0))
1123            {
1124              out[len] = 0;
1125              out[--len] = '_';
1126            }
1127            menu_set_value(menu, kItem, out, 0);
1128          }
1129          break;
1130      }
1131    }
1132    updateAll(NULL);
1133  }
1134}
1135
1136
1137void PuyoCommander::startTwoPlayerGameLoop()
1138{
1139  char player1Name[256];
1140  char player2Name[256];
1141
1142  GetStrPreference("Player1 Name", player1Name, "Player 1");
1143  GetStrPreference("Player2 Name", player2Name, "Player 2");
1144  menu_set_value(twoPlayerGameMenu, kPlayer1Name, player1Name, 0);
1145  menu_set_value(twoPlayerGameMenu, kPlayer2Name, player2Name, 0);
1146
1147  while (!menu_active_is(twoPlayerGameMenu,kLevelMedium))
1148    menu_next_item(twoPlayerGameMenu);
1149
1150  menu_show(twoPlayerGameMenu);
1151  while (1) {
1152    SDL_Event e;
1153
1154    while (SDL_PollEvent (&e)) {
1155      GameControlEvent controlEvent;
1156        getControlEvent(e, &controlEvent);
1157        switch (controlEvent.cursorEvent) {
1158            case GameControlEvent::kQuit:
1159                exit(0);
1160                break;
1161            case GameControlEvent::kDown:
1162                menu_next_item (twoPlayerGameMenu);
1163                break;
1164            case GameControlEvent::kUp:
1165                menu_prev_item (twoPlayerGameMenu);
1166                break;
1167            case GameControlEvent::kStart:
1168                menu_validate (twoPlayerGameMenu);
1169                if (menu_active_is(twoPlayerGameMenu,kPlayer2Name)) {
1170                  enterStringLoop(twoPlayerGameMenu,kPlayer2Name,player2Name);
1171                  menu_next_item (twoPlayerGameMenu);
1172                }
1173                else if (menu_active_is(twoPlayerGameMenu,kPlayer1Name)) {
1174                  enterStringLoop(twoPlayerGameMenu,kPlayer1Name,player1Name);
1175                  menu_next_item (twoPlayerGameMenu);
1176                }
1177                else
1178                  goto mml_play;
1179                break;
1180            case GameControlEvent::kBack:
1181                menu_hide(twoPlayerGameMenu);
1182                return;
1183                break;
1184        }
1185    }
1186    updateAll(NULL);
1187  }
1188
1189mml_play:
1190  menu_hide (twoPlayerGameMenu);
1191
1192  GAME_ACCEL = 2000;
1193  gameLevel = 1;
1194  if (menu_active_is (twoPlayerGameMenu, kLevelMedium)) {
1195    GAME_ACCEL = 1500;
1196    gameLevel = 2;
1197  }
1198  else if (menu_active_is (twoPlayerGameMenu, kLevelHard)) {
1199    GAME_ACCEL = 1000;
1200    gameLevel = 3;
1201  }
1202
1203  int score1 = 0;
1204  int score2 = 0;
1205  gameOverMenu = gameOver2PMenu;
1206  int currentMusicTheme = 0;
1207  if (menu_active_is(gameOverMenu, "NO"))
1208    menu_next_item(gameOverMenu);
1209  while (menu_active_is(gameOverMenu, "YES")) {
1210    menu_next_item(gameOverMenu);
1211    PuyoStarter myStarter(this,false,0,RANDOM,currentMusicTheme);
1212    audio_music_switch_theme(currentMusicTheme);
1213    p1name = player1Name;
1214    p2name = player2Name;
1215    GAME_ACCEL = 1500;
1216    doom_melt_start(melt, menuBGImage);
1217    myStarter.run(score1, score2, 0, 0, 0);
1218    score1 += myStarter.leftPlayerWin();
1219    score2 += myStarter.rightPlayerWin();
1220    currentMusicTheme = (currentMusicTheme + 1) % NB_MUSIC_THEME;
1221  }
1222
1223  SetStrPreference("Player1 Name", player1Name);
1224  SetStrPreference("Player2 Name", player2Name);
1225  doom_melt_start(melt, gameScreen);
1226}
1227
1228
1229struct SelIA {
1230  IA_Type type;
1231  int level;
1232};
1233
1234void PuyoCommander::startSingleGameLoop()
1235{
1236  char playerName[256];
1237
1238    char * defaultName = getenv("USER");
1239    if (defaultName == NULL)
1240      defaultName = "Player";
1241    if (!(defaultName[0]>=32))
1242      defaultName = "Player";
1243    if ((defaultName[0]>='a') && (defaultName[0]<='z'))
1244      defaultName[0] += 'A' - 'a';
1245
1246  GetStrPreference("Player Name", playerName, defaultName);
1247  menu_set_value(singleGameMenu, kPlayerName, playerName, 0);
1248
1249  while (!menu_active_is(singleGameMenu,kLevelMedium))
1250    menu_next_item(singleGameMenu);
1251
1252  menu_show(singleGameMenu);
1253  while (1) {
1254    SDL_Event e;
1255
1256    while (SDL_PollEvent (&e)) {
1257      GameControlEvent controlEvent;
1258        getControlEvent(e, &controlEvent);
1259        switch (controlEvent.cursorEvent) {
1260            case GameControlEvent::kQuit:
1261                exit(0);
1262                break;
1263            case GameControlEvent::kDown:
1264                menu_next_item (singleGameMenu);
1265                break;
1266            case GameControlEvent::kUp:
1267                menu_prev_item (singleGameMenu);
1268                break;
1269            case GameControlEvent::kStart:
1270                menu_validate (singleGameMenu);
1271                if (menu_active_is(singleGameMenu,kPlayerName))
1272                  enterStringLoop(singleGameMenu,kPlayerName,playerName);
1273                else
1274                  goto mml_play;
1275                break;
1276            case GameControlEvent::kBack:
1277                menu_hide(singleGameMenu);
1278                return;
1279                break;
1280        }
1281    }
1282    updateAll(NULL);
1283  }
1284
1285mml_play:
1286  menu_hide (singleGameMenu);
1287
1288  SelIA ia1[] = { {RANDOM, 350}, {FLOBO, 350}, {FLOBO, 250}, {FLOBO, 180}, {FLOBO,  90}, {JEKO, 350}, {TANIA, 320}, {FLOBO, 62}, {RANDOM,0} };
1289  SelIA ia2[] = { {FLOBO,  190}, {JEKO , 180}, {TANIA, 160}, {FLOBO,  90}, {GYOM , 210}, {TANIA, 90}, {JEKO,   80}, {GYOM,  90}, {RANDOM,0} };
1290  SelIA ia3[] = { {TANIA,  130}, {JEKO , 100}, {GYOM ,  90}, {JEKO,   80}, {TANIA,  60}, {GYOM,  60}, {GYOM,   40}, {GYOM,  30}, {RANDOM,0} };
1291
1292  SelIA *ia = &(ia1[0]);
1293
1294  gameLevel = 1;
1295  GAME_ACCEL = 2000;
1296  if (menu_active_is (singleGameMenu, kLevelMedium)) {
1297    ia = &(ia2[0]);
1298    GAME_ACCEL = 1500;
1299    gameLevel = 2;
1300  }
1301  else if (menu_active_is (singleGameMenu, kLevelHard)) {
1302    ia = &(ia3[0]);
1303    GAME_ACCEL = 1000;
1304    gameLevel = 3;
1305  }
1306
1307  int score1 = 0;
1308  int score2 = 0;
1309  int lives  = 3;
1310  if (menu_active_is(finishedMenu,  "NO"))
1311    menu_next_item(finishedMenu);
1312  if (menu_active_is(looserMenu   ,  "NO"))
1313    menu_next_item(looserMenu);
1314  if (menu_active_is(nextLevelMenu,  "NO"))
1315    menu_next_item(nextLevelMenu);
1316  if (menu_active_is(gameOver2PMenu, "NO"))
1317    menu_next_item(gameOver2PMenu);
1318  gameOverMenu = nextLevelMenu;
1319
1320  int lastPoints = 0;
1321  int currentMusicTheme = 0;
1322
1323  int fini = 0;
1324  while (!fini)
1325  {
1326    PuyoStory myStory(this, score2+1);
1327    myStory.loop();
1328    PuyoStarter myStarter(this, true, ia[score2].level, ia[score2].type, currentMusicTheme);
1329    p1name = playerName;
1330    p2name = AI_NAMES[score2];
1331    doom_melt_start(melt, menuBGImage);
1332    audio_music_switch_theme(currentMusicTheme);
1333    myStarter.run(score1, score2, lives, lastPoints, 0);
1334    lastPoints = myStarter.rightPlayerPoints();
1335    score1 += myStarter.leftPlayerWin();
1336    score2 += myStarter.rightPlayerWin();
1337    if (!myStarter.rightPlayerWin())
1338      lives--;
1339    else {
1340      currentMusicTheme = (currentMusicTheme + 1) % NB_MUSIC_THEME;
1341    }
1342
1343    if (ia[score2].level == 0) {
1344      lastPoints += 100000;
1345      if (menu_active_is (singleGameMenu, kLevelMedium))
1346        lastPoints += 150000;
1347      if (menu_active_is (singleGameMenu, kLevelHard))
1348        lastPoints += 250000;
1349      fini = 1;
1350    }
1351
1352    if (!(menu_active_is(gameOverMenu, "YES") && (lives >= 0)))
1353      fini = 1;
1354
1355    if (fini)
1356    {
1357      audio_music_start(0);
1358      int newOne = setHiScore(lastPoints, p1name);
1359      if (newOne >= 0)
1360      {
1361        updateHighScoresMenu(newOne);
1362        backLoop(highScoresMenu, &myStarter);
1363      }
1364    }
1365  }
1366  SetStrPreference("Player Name", playerName);
1367  doom_melt_start(melt, gameScreen);
1368}
1369
1370void PuyoCommander::updateAll(PuyoDrawable *starter, SDL_Surface *extra_surf)
1371{
1372  Uint32  now = 0;
1373
1374  // mise a jour
1375  menu_update (mainMenu, display);
1376  menu_update (gameOverMenu, display);
1377  menu_update (optionMenu, display);
1378  menu_update (controlsMenu, display);
1379  menu_update (rulesMenu, display);
1380  menu_update (highScoresMenu, display);
1381  menu_update (aboutMenu, display);
1382  menu_update (mustRestartMenu, display);
1383  menu_update (singleGameMenu, display);
1384  menu_update (twoPlayerGameMenu, display);
1385  menu_update (menu_pause,display);
1386  scrolling_text_update(scrollingText, display);
1387  doom_melt_update(melt);
1388
1389  // affichage eventuel (pourrait ne pas avoir lieu de tps en tps si machine
1390  // trop lente)
1391  cycle++;
1392  now = SDL_GetTicks ();
1393
1394  if ((now < (start_time + cycle * cycle_duration)) || (cycle - lastRenderedCycle > maxFrameDrop)) {
1395    lastRenderedCycle = cycle;
1396
1397    if (starter) {
1398      starter->draw();
1399    }
1400    else {
1401      SDL_BlitSurface (menuBGImage->surf, NULL, display, NULL);
1402    }
1403
1404    if (extra_surf)
1405    {
1406        SDL_Rect rect;
1407        rect.x = 0;
1408        rect.y = 480 - extra_surf->h;
1409        rect.w = extra_surf->w;
1410        rect.h = extra_surf->h;
1411        SDL_BlitSurface(extra_surf, NULL, display, &rect);
1412    }
1413
1414    if (!starter)
1415      scrolling_text_draw(scrollingText, display, 460);
1416
1417    menu_draw (mainMenu, display);
1418    menu_draw (gameOverMenu, display);
1419    menu_draw (optionMenu, display);
1420    menu_draw (controlsMenu, display);
1421    menu_draw (rulesMenu, display);
1422    menu_draw (highScoresMenu, display);
1423    menu_draw (aboutMenu, display);
1424    menu_draw (mustRestartMenu, display);
1425    menu_draw (singleGameMenu, display);
1426    menu_draw (twoPlayerGameMenu, display);
1427    menu_draw(menu_pause,display);
1428    doom_melt_display(melt, display);
1429    SDL_Flip (display);
1430  }
1431
1432  // delay si machine trop rapide
1433  now = SDL_GetTicks ();
1434  if (now < (start_time + cycle * cycle_duration))
1435    SDL_Delay ((start_time + cycle * cycle_duration) - now);
1436}
1437
1438
1439