1 /*
2  * Seven Kingdoms: Ancient Adversaries
3  *
4  * Copyright 1997,1998 Enlight Software Ltd.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 // Filename    : OINGMENU.H
22 // Description : in-game menu (async version)
23 
24 #include <OVGA.h>
25 #include <OVGABUF.h>
26 #include <OSYS.h>
27 #include <OIMGRES.h>
28 #include <OMOUSE.h>
29 #include <OMOUSECR.h>
30 #include <KEY.h>
31 #include <OPOWER.h>
32 #include <OBOX.h>
33 #include <OREMOTE.h>
34 #include <OTUTOR.h>
35 #include <ONATIONA.h>
36 #include <OWORLDMT.h>
37 #include <OGAME.h>
38 #include <OOPTMENU.h>
39 #include <OINGMENU.h>
40 #include <OFONT.h>
41 #include <OMUSIC.h>
42 #include "gettext.h"
43 
44 
45 
46 enum { GAME_MENU_WIDTH  = 350,
47        GAME_MENU_HEIGHT = 400  };
48 
49 enum { GAME_MENU_X1 = ZOOM_X1 + ( (ZOOM_X2-ZOOM_X1+1) - GAME_MENU_WIDTH ) / 2,
50        GAME_MENU_Y1 = ZOOM_Y1 + ( (ZOOM_Y2-ZOOM_Y1+1) - GAME_MENU_HEIGHT ) / 2 };
51 
52 enum { GAME_OPTION_WIDTH  = 170,
53        GAME_OPTION_HEIGHT = 34   };
54 
55 enum { GAME_OPTION_X1 = GAME_MENU_X1+90,
56        GAME_OPTION_Y1 = GAME_MENU_Y1+93  };
57 
58 enum { MAP_ID_X1 = GAME_MENU_X1 + 18,
59        MAP_ID_Y1 = GAME_MENU_Y1 + 362,
60        MAP_ID_X2 = GAME_MENU_X1 + 330,
61        MAP_ID_Y2 = GAME_MENU_Y1 + 382 };
62 
63 unsigned InGameMenu::menu_hot_key[GAME_OPTION_COUNT] = {'o','s','l', 0,0,0,0,KEY_ESC };
64 
InGameMenu()65 InGameMenu::InGameMenu()
66 {
67    active_flag = 0;
68 }
69 
70 
enter(char untilExitFlag)71 void InGameMenu::enter(char untilExitFlag)
72 {
73    if( active_flag )
74       return;
75 
76    refresh_flag = 1;
77    active_flag = 1;
78 
79    memset(game_menu_option_flag, 1, sizeof(game_menu_option_flag) );
80 
81    if( !nation_array.player_recno)
82    {
83       // when in observe mode
84       game_menu_option_flag[1] = 0;    // disable save game
85       game_menu_option_flag[4] = 0;    // disable retire
86    }
87 
88    if( remote.is_enable() || remote.is_replay() )
89    {
90       // when in when in multi-player mode,
91       game_menu_option_flag[2] = 0;    // disable load game
92       game_menu_option_flag[3] = 0;    // disable training
93       game_menu_option_flag[4] = 0;    // disable retire
94    }
95 
96    mouse_cursor.set_icon(CURSOR_NORMAL);
97 
98    power.win_opened = 1;
99 
100    if( untilExitFlag )
101    {
102       while( is_active() )
103       {
104          sys.yield();
105          vga.flip();
106          mouse.get_event();
107 
108          // display on front buffer
109          char useBackBuf = vga.use_back_buf;
110          vga.use_front();
111          disp();
112          if(useBackBuf)
113             vga.use_back();
114 
115          sys.blt_virtual_buf();
116          music.yield();
117          detect();
118       }
119    }
120 }
121 
disp(int needRepaint)122 void InGameMenu::disp(int needRepaint)
123 {
124    if( !active_flag )
125       return;
126 
127    // since use back buffer, always refresh
128    if( Vga::use_back_buf || needRepaint )
129       refresh_flag = 1;
130 
131    if( refresh_flag )
132    {
133       int x=GAME_MENU_X1+20, y=GAME_MENU_Y1+17;
134 
135       if( Vga::use_back_buf )
136          image_interface.put_back( GAME_MENU_X1, GAME_MENU_Y1, "GAMEMENU" );
137       else
138          image_interface.put_front( GAME_MENU_X1, GAME_MENU_Y1, "GAMEMENU" );
139 
140 
141       for( int b = 0; b < GAME_OPTION_COUNT; ++b)
142       {
143          if( !game_menu_option_flag[b])
144          {
145             // darked disabled button
146             Vga::active_buf->adjust_brightness(
147                GAME_OPTION_X1, GAME_OPTION_Y1 + b*GAME_OPTION_HEIGHT,
148                GAME_OPTION_X1+GAME_OPTION_WIDTH-1,
149                GAME_OPTION_Y1 + (b+1)*GAME_OPTION_HEIGHT-1, -8);
150          }
151       }
152 
153       String str(_("Map I.D."));
154 
155       str += ": ";
156       str += info.random_seed;
157       font_bible.center_put( MAP_ID_X1, MAP_ID_Y1, MAP_ID_X2, MAP_ID_Y2, str);
158 
159       refresh_flag = 0;
160    }
161 }
162 
163 
detect()164 int InGameMenu::detect()
165 {
166    if( !active_flag )
167       return 0;
168 
169    int i, y=GAME_OPTION_Y1, x2, y2;
170 
171    for( i=1 ; i<=GAME_OPTION_COUNT ; i++, y+=GAME_OPTION_HEIGHT )
172    {
173       x2 = GAME_OPTION_X1+GAME_OPTION_WIDTH-1;
174       y2 = y+GAME_OPTION_HEIGHT-1;
175 
176       if( game_menu_option_flag[i-1] == 1 &&
177          (menu_hot_key[i-1] && mouse.key_code == menu_hot_key[i-1] ||
178          mouse.single_click( GAME_OPTION_X1, y, x2, y2 )) )
179          break;
180 
181       if( i == GAME_OPTION_COUNT &&    // assume last option is 'continue'
182          (mouse.any_click(1) || mouse.key_code==KEY_ESC) )
183          break;
184    }
185 
186    if( i>GAME_OPTION_COUNT )
187       return 0;
188 
189    //------ display the pressed down button -----//
190 
191    vga_front.save_area_common_buf( GAME_OPTION_X1, y, x2, y2 );
192 
193    image_interface.put_front( GAME_OPTION_X1, y, "MENU-DWN" );
194 
195    while( mouse.left_press )  // holding down the button
196    {
197       sys.yield();
198       vga.flip();
199       mouse.get_event();
200    }
201 
202    vga_front.rest_area_common_buf();         // restore the up button
203 
204    //--------- run the option -------//
205 
206    exit(0);
207 
208    switch(i)
209    {
210       case 1:     // options
211          option_menu.enter(!remote.is_enable());
212          break;
213 
214       case 2:     // save game
215          sys.save_game();
216          break;
217 
218       case 3:     // load game
219          sys.load_game();
220          break;
221 
222       case 4:     // training
223          tutor.select_run_tutor(1);
224          break;
225 
226       case 5:     // retire
227          if( nation_array.player_recno )     // only when the player's kingdom still exists
228          {
229             if( box.ask(_("Do you really want to retire?"), _("Yes"), _("No"), 175, 320) )
230             {
231                if( remote.is_enable() )
232                {
233                   // BUGHERE : message will not be sent out
234                   short *shortPtr = (short *)remote.new_send_queue_msg( MSG_PLAYER_QUIT, 2*sizeof(short));
235                   shortPtr[0] = nation_array.player_recno;
236                   shortPtr[1] = 1;     // retire
237                }
238                game.game_end(0, 0, 0, 1);          // 1 - retire
239             }
240          }
241          break;
242 
243       case 6:     // quit to main menu
244       {
245          int boxX1;
246 
247          #ifdef GERMAN
248             boxX1 = 125;
249          #else
250             boxX1 = 115;
251          #endif
252 
253          if( !nation_array.player_recno ||
254              box.ask( _("Do you really want to quit to the Main Menu?"), _("Yes"), _("No"), boxX1, 350 ) )
255          {
256             if( remote.is_enable() && nation_array.player_recno )
257             {
258                // BUGHERE : message will not be sent out
259                short *shortPtr = (short *)remote.new_send_queue_msg( MSG_PLAYER_QUIT, 2*sizeof(short));
260                shortPtr[0] = nation_array.player_recno;
261                shortPtr[1] = 0;     // not retire
262             }
263             sys.signal_exit_flag = 2;
264          }
265          break;
266       }
267 
268       case 7:
269          if( !nation_array.player_recno ||
270              box.ask( _("Do you really want to quit Seven Kingdoms?"), _("Yes"), _("No"), 178, 388 ) )
271          {
272             if( remote.is_enable() && nation_array.player_recno )
273             {
274                // BUGHERE : message will not be sent out
275                short *shortPtr = (short *)remote.new_send_queue_msg( MSG_PLAYER_QUIT, 2*sizeof(short));
276                shortPtr[0] = nation_array.player_recno;
277                shortPtr[1] = 1;     // retire
278             }
279             sys.signal_exit_flag = 1;
280          }
281          break;
282    }
283 
284    return 1;
285 }
286 
287 
exit(int action)288 void InGameMenu::exit(int action)
289 {
290    power.win_opened = 0;
291    active_flag = 0;
292 }
293 
294 
abort()295 void InGameMenu::abort()
296 {
297    power.win_opened = 0;
298    active_flag = 0;
299 }
300