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    : OGAMSCE2.CPP
22 // Description : select scenario menu
23 
24 
25 #include <OSYS.h>
26 #include <OGAME.h>
27 #include <OMOUSE.h>
28 #include <OMOUSECR.h>
29 #include <OVGABUF.h>
30 #include <OIMGRES.h>
31 #include <OBUTT3D.h>
32 #include <OSLIDCUS.h>
33 #include <OBOX.h>
34 #include <OPOWER.h>
35 #include <OFONT.h>
36 #include <KEY.h>
37 #include <OBLOB.h>
38 #include <OINFO.h>
39 #include <OFILETXT.h>
40 #include <OVQUEUE.h>
41 #include <OGETA.h>
42 #include <PlayerStats.h>
43 #include <OGFILE.h>
44 // ####### begin Gilbert 4/11 #######//
45 #include <OMUSIC.h>
46 // ####### end Gilbert 4/11 #######//
47 #include "gettext.h"
48 
49 // --------- declare static funtion --------//
50 
51 static void disp_scroll_bar_func(SlideVBar *scroll, int);
52 enum CHECKBOX_STATE { UNCHECKED = 0, PART_CHECKED = 1, CHECKED = 2 };
53 static void draw_checkbox(int x, int y, CHECKBOX_STATE checked);
54 
55 enum { TUTOR_MENU_X1 = 0,
56 		 TUTOR_MENU_Y1 = 0,
57 		 TUTOR_MENU_WIDTH = VGA_WIDTH,
58 		 TUTOR_MENU_HEIGHT = VGA_HEIGHT };
59 
60 enum { SCROLL_X1 = 757,
61 		 SCROLL_Y1 = 352,
62 		 SCROLL_X2 = 770,
63 		 SCROLL_Y2 = 492 };
64 
65 enum { BROWSE_X1 = 30,
66 		 BROWSE_Y1 = 336,
67 		 BROWSE_REC_WIDTH  = 725,
68 		 BROWSE_REC_HEIGHT = 44,
69 		 BROWSE_X2 = BROWSE_X1 + BROWSE_REC_WIDTH - 1,
70 		 MAX_BROWSE_DISP_REC = 4 };
71 
72 enum { TEXT_AREA_X1 = 43,
73 		 TEXT_AREA_Y1 = 198,
74 		 TEXT_AREA_X2 = 745,
75 		 TEXT_AREA_Y2 = 302,
76 		 TEXT_AREA_WIDTH = TEXT_AREA_X2 - TEXT_AREA_X1 + 1,
77 		 TEXT_AREA_HEIGHT = TEXT_AREA_Y2 - TEXT_AREA_Y1 + 1,
78 };
79 
80 enum { TEXT_SCROLL_X1 = SCROLL_X1,
81 	    TEXT_SCROLL_Y1 = 202,
82 		 TEXT_SCROLL_X2 = SCROLL_X2,
83 		 TEXT_SCROLL_Y2 = 289,
84 };
85 
86 enum { TEXT_OFFSET_X = 11,
87 		 TEXT_OFFSET_Y = 9 };
88 
89 // ####### begin Gilbert 1/11 #########//
90 enum {
91 		 NAME_FIELD_X1 = 180,
92 		 NAME_FIELD_Y1 = 551,
93 		 NAME_FIELD_X2 = 351,
94 //		 NAME_FIELD_Y2 = 566,
95 };
96 // ####### end Gilbert 1/11 #########//
97 
98 
99 #define TU_USE_BACKUP_SURFACE
100 
101 #define TUOPTION_BROWSE(s)     (1 << (s))
102 #define TUOPTION_ALL_BROWSE    0x0000ffff
103 #define TUOPTION_PAGE          0x00010000
104 #define TUOPTION_TEXT_AREA     0x00020000
105 #define TUOPTION_PIC_AREA      0x00040000
106 #define TUOPTION_SCROLL        0x00080000
107 #define TUOPTION_TEXT_SCROLL   0x00100000
108 #define TUOPTION_TEXT_BUFFER   0x00200000
109 // ##### begin Gilbert 1/11 ########//
110 #define TUOPTION_NAME_FIELD    0x00400000
111 // ##### end Gilbert 1/11 ########//
112 #define TUOPTION_ALL           0xffffffff
113 
114 //---------- Begin of function draw_checkbox ----------//
115 //
116 // Though we check for PlayStatus here, this is a very general
117 // purpose function and can be used anywhere with ints instead.
118 //
draw_checkbox(int x,int y,CHECKBOX_STATE checked)119 void draw_checkbox(int x, int y, CHECKBOX_STATE checked)
120 {
121 	// UNPLAYED  = Empty checkbox
122 	// PLAYED    = Line in checkbox
123 	// COMPLETED = Checked
124 
125 	if (checked == CHECKBOX_STATE::CHECKED) {
126 		image_menu.put_front(x, y, "NMPG-RCH");             // Checked checkbox
127 	}
128 	else                                                    // Unchecked checkbox
129 	{
130 		//
131 		// We need an empty checkbox to start. It stays that way for an
132 		// UNCHECKED box. We'll draw a line inside for PART_CHECKED.
133 		//
134 
135 		//---- draw a pseudo-3D empty checkbox ----//
136 		vga_front.rect(x, y, x + 14, y + 14, 10, V_WHITE); // white background
137 		vga_front.line(x, y, x + 14, y, V_WHITE - 8);      // top
138 		vga_front.line(x, y, x, y + 14, V_WHITE - 8);      // left
139 		x += 1;
140 		y += 1;
141 		vga_front.line(x, y, x + 13, y, V_WHITE - 6);	   // inner shadow top
142 		vga_front.line(x, y, x, y + 13, V_WHITE - 6);	   // inner shadow left
143 		x += 1;
144 		y += 1;
145 		vga_front.rect(x, y, x + 12, y + 12, 1, V_WHITE - 1);  // another inner shadow
146 
147 		if (checked == CHECKBOX_STATE::PART_CHECKED)   // Line in the middle
148 		{
149 			vga_front.line(x + 1, y + 4, x + 11, y + 4, VGA_GRAY + 4);  // Dark gray line
150 			vga_front.line(x + 1, y + 5, x + 11, y + 5, VGA_GRAY + 4);  // Dark gray line
151 			vga_front.line(x + 1, y + 6, x + 11, y + 6, VGA_GRAY + 4);  // Dark gray line
152 			vga_front.line(x + 2, y + 7, x + 12, y + 7, V_WHITE - 8);   // slight shadow bottom-right
153 		}
154 	}
155 }
156 //---------- End of function draw_checkbox ----------//
157 
158 //---------- Begin of function Game::select_scenario ----------//
159 //
160 // Select a scenario.
161 //
162 // <int>    scenCount		   - no. of available scenarios.
163 // <char**> scenFileNameArray - an array of <char*> pointing to the file name of the
164 //										  available scenarios.
165 //
166 // return : <int> >0 - id. of the scenario selected.
167 //                 0 - cancel
168 //
select_scenario(int scenCount,ScenInfo * scenInfoArray)169 int Game::select_scenario(int scenCount, ScenInfo* scenInfoArray)
170 {
171 	char* scenFileName;
172 	char	pictName[20];
173 	char	textName[20];
174 	char* pathName;
175 
176 	if( scenCount==0 )
177 	{
178 		box.msg( _("Scenario files not found.") );
179 		return 0;
180 	}
181 
182 	//-------------------------------------//
183 
184 	// ##### begin Gilbert 4/11 ########//
185 	// stop any music
186 	music.stop();
187 	// ##### end Gilbert 4/11 ########//
188 
189 	int menuX1 = TUTOR_MENU_X1;
190 	int menuY1 = TUTOR_MENU_Y1;
191 
192 	mouse_cursor.set_icon(CURSOR_NORMAL);
193 
194 	power.win_opened = 1;
195 
196 	int minRecno = 1;
197 	int browseRecno = minRecno;
198 
199 	//--------------------------------------//
200 	Button3D scrollUp, scrollDown, startButton, cancelButton;
201 	int retFlag = 0;
202 	int refreshFlag = TUOPTION_ALL;
203 
204 	scrollUp.create(menuX1+SCROLL_X1,menuY1+SCROLL_Y1-17, "SV-UP-U", "SV-UP-D", 1, 0);
205 	scrollDown.create(menuX1+SCROLL_X1,menuY1+SCROLL_Y2+1, "SV-DW-U", "SV-DW-D", 1, 0);
206 	// ###### begin Gilbert 1/11 ########//
207 //	startButton.create(menuX1+170, menuY1+529, "START-U", "START-D",1, 0);
208 //	cancelButton.create(menuX1+465, menuY1+529, "CANCEL-U", "CANCEL-D", 1, 0);
209 	startButton.create(menuX1+373, menuY1+529, "START-U", "START-D",1, 0);
210 	cancelButton.create(menuX1+548, menuY1+529, "CANCEL-U", "CANCEL-D", 1, 0);
211 	// ###### end Gilbert 1/11 ########//
212 
213 	SlideVBar scrollBar;
214 	scrollBar.init_scroll(menuX1+SCROLL_X1, menuY1+SCROLL_Y1, menuX1+SCROLL_X2, menuY1+SCROLL_Y2,
215 		MAX_BROWSE_DISP_REC, disp_scroll_bar_func);
216 	scrollBar.set(minRecno, scenCount, minRecno);
217 
218 	scrollBar.set_view_recno(browseRecno - MAX_BROWSE_DISP_REC/2);
219 	Button3D textScrollUp, textScrollDown;
220 	textScrollUp.create(menuX1+TEXT_SCROLL_X1, menuY1+TEXT_SCROLL_Y1-17,
221 		"SV-UP-U", "SV-UP-D", 1, 0);
222 	textScrollDown.create(menuX1+TEXT_SCROLL_X1,menuY1+TEXT_SCROLL_Y2+1,
223 		"SV-DW-U", "SV-DW-D", 1, 0);
224 	VLenQueue textBuffer;
225 	*(textBuffer.reserve(1)) = '\0';
226 
227 	Font &textFont = font_std;
228 	const int TEXT_LINE_SPACE = 4;
229 	const int ESTIMATED_LINE_IN_TEXT_AREA =
230 		(TEXT_AREA_Y2 - TEXT_AREA_Y1 + 1) / (textFont.font_height + TEXT_LINE_SPACE);
231 
232 	SlideVBar textScrollBar;
233 	textScrollBar.init_scroll(menuX1+TEXT_SCROLL_X1, menuY1+TEXT_SCROLL_Y1,
234 		menuX1+TEXT_SCROLL_X2, menuY1+TEXT_SCROLL_Y2,
235 		ESTIMATED_LINE_IN_TEXT_AREA, disp_scroll_bar_func);
236 
237 	// ###### begin Gilbert 1/11 ########//
238 	GetA playerNameField;
239 	playerNameField.init( menuX1+NAME_FIELD_X1, menuY1+NAME_FIELD_Y1, menuX1+NAME_FIELD_X2,
240 		config.player_name, HUMAN_NAME_LEN, &font_san, 0, 1);
241 	// ###### end Gilbert 1/11 ########//
242 
243 #ifdef TU_USE_BACKUP_SURFACE
244 	// create temporary surface
245 	Blob browseArea[MAX_BROWSE_DISP_REC];
246 	Blob scrollArea;
247 	Blob textArea;
248 	Blob textScrollArea;
249 	// ##### begin Gilbert 1/11 #######//
250 	Blob nameFieldArea;
251 	// ##### end Gilbert 1/11 #######//
252 #endif
253 
254 	while(1)
255 	{
256 		//---------- yield --------//
257 
258 		sys.yield();
259 		vga.flip();
260 
261 		mouse.get_event();
262 
263 		if( sys.signal_exit_flag == 1 )
264 		{
265 			retFlag = 0;
266 			break;
267 		}
268 
269 		// --------- display ----------//
270 
271 		if( refreshFlag )
272 		{
273 #ifndef TU_USE_BACKUP_SURFACE
274 			refreshFlag = TUOPTION_ALL;
275 #endif
276 			scenFileName = scenInfoArray[browseRecno-1].file_name;
277 			misc.change_file_ext( pictName, scenFileName, "SCP" );
278 			misc.change_file_ext( textName, scenFileName, "SCT" );
279 			pathName = DIR_SCENARIO_PATH(scenInfoArray[browseRecno-1].dir_id);
280 			err_when( ! *pathName );
281 			if( refreshFlag & TUOPTION_PAGE )
282 			{
283 				mouse.hide_area(menuX1, menuY1, menuX1+TUTOR_MENU_WIDTH, menuY1+TUTOR_MENU_HEIGHT);
284 
285 				image_interface.put_front( menuX1, menuY1, "SCENARIO" );
286 #ifdef TU_USE_BACKUP_SURFACE
287 				// capture into browseArea, scrollArea, textArea
288 				for( int j = 0; j < MAX_BROWSE_DISP_REC; ++j)
289 				{
290 					browseArea[j].resize(2*sizeof(short) + BROWSE_REC_WIDTH*BROWSE_REC_HEIGHT);
291 					vga_front.read_bitmap(
292 						menuX1+BROWSE_X1, menuY1+BROWSE_Y1 + j*BROWSE_REC_HEIGHT,
293 						menuX1+BROWSE_X2, menuY1+BROWSE_Y1 + j*BROWSE_REC_HEIGHT+BROWSE_REC_HEIGHT-1,
294 						browseArea[j].ptr);
295 				}
296 
297 				scrollArea.resize(2*sizeof(short)+(SCROLL_X2-SCROLL_X1+1)*(SCROLL_Y2-SCROLL_Y1+1));
298 				vga_front.read_bitmap(menuX1+SCROLL_X1,menuY1+SCROLL_Y1,menuX1+SCROLL_X2,menuY1+SCROLL_Y2, scrollArea.ptr);
299 
300 				textArea.resize(2*sizeof(short)+TEXT_AREA_WIDTH*TEXT_AREA_HEIGHT);
301 				vga_front.read_bitmap(menuX1+TEXT_AREA_X1, menuY1+TEXT_AREA_Y1,
302 					menuX1+TEXT_AREA_X2, menuY1+TEXT_AREA_Y2, textArea.ptr);
303 
304 				textScrollArea.resize( 2*sizeof(short)+
305 					(TEXT_SCROLL_X2-TEXT_SCROLL_X1+1)*(TEXT_SCROLL_Y2-TEXT_SCROLL_Y1+1));
306 				vga_front.read_bitmap(menuX1+TEXT_SCROLL_X1, menuY1+TEXT_SCROLL_Y1,
307 					menuX1+TEXT_SCROLL_X2, menuY1+TEXT_SCROLL_Y2, textScrollArea.ptr);
308 
309 				// ###### begin Gilbert 1/11 ########//
310 				nameFieldArea.resize( 2*sizeof(short) +
311 					(playerNameField.x_limit-playerNameField.x+1)*playerNameField.height());
312 				vga_front.read_bitmap(playerNameField.x, playerNameField.y,
313 					playerNameField.x_limit, playerNameField.y+playerNameField.height()-1,
314 					nameFieldArea.ptr);
315 				playerNameField.back_ground_bitmap = nameFieldArea.ptr;
316 				// ###### end Gilbert 1/11 ########//
317 #endif
318 				scrollUp.paint();
319 				scrollDown.paint();
320 				startButton.paint();
321 				cancelButton.paint();
322 
323 				textScrollUp.paint();
324 				textScrollDown.paint();
325 
326 				mouse.show_area();
327 			}
328 
329 			if( refreshFlag & TUOPTION_PIC_AREA )
330 			{
331 				String str;
332 
333 				str = pathName;
334 				str += pictName;
335 
336 				if( browseRecno && misc.is_file_exist(str) )
337 				{
338 					File pictFile;
339 					pictFile.file_open(str);
340 					vga_front.put_large_bitmap(menuX1+21,menuY1+19, &pictFile);
341 					pictFile.file_close();
342 				}
343 				else
344 				{
345 					// draw the background
346 #ifdef TU_USE_BACKUP_SURFACE
347 					// copy from ?
348 #endif
349 				}
350 			}
351 
352 			if( refreshFlag & TUOPTION_TEXT_BUFFER )
353 			{
354 				// load text buffer
355 				String str;
356 
357 				str = pathName;
358 				str += textName;
359 
360 				if( browseRecno && misc.is_file_exist(str) )
361 				{
362 					File textFile;
363 					int dataSize;
364 					textFile.file_open(str);
365 					// ##### patch begin Gilbert 2/2 ####//
366 					dataSize = textFile.file_size();
367 
368 					FileTxt fileTxt( &textFile, dataSize );  // initialize fileTxt with an existing file stream
369 
370 					fileTxt.next_line();		// skip the title lines
371 					fileTxt.next_line();
372 					fileTxt.next_line();
373 					fileTxt.next_line();
374 
375 					textBuffer.clear();
376 					fileTxt.read_paragraph(textBuffer.reserve(dataSize+8), dataSize);
377 					// ##### end begin Gilbert 2/2 ####//
378 
379 			      int dispLines;    // no. of lines can be displayed on the area
380 			      int totalLines;   // total no. of lines of the text
381 
382 					textFont.count_line( menuX1+TEXT_AREA_X1, menuY1+TEXT_AREA_Y1,
383 						menuX1+TEXT_AREA_X2, menuY1+TEXT_AREA_Y2,
384 						_(textBuffer.queue_buf), TEXT_LINE_SPACE, dispLines, totalLines );
385 
386 					// textScrollBar.view_size = dispLines;
387 					textScrollBar.set(1, totalLines ,1);
388 					refreshFlag |= TUOPTION_TEXT_SCROLL;
389 				}
390 			}
391 
392 			if( refreshFlag & TUOPTION_TEXT_AREA )
393 			{
394 #ifdef TU_USE_BACKUP_SURFACE
395 				// copy from back buffer
396 				vga_front.put_bitmap(menuX1+TEXT_AREA_X1, menuY1+TEXT_AREA_Y1,
397 					textArea.ptr);
398 #endif
399 					textFont.put_paragraph(menuX1+TEXT_AREA_X1, menuY1+TEXT_AREA_Y1, menuX1+TEXT_AREA_X2, menuY1+TEXT_AREA_Y2,
400 						_(textBuffer.queue_buf), TEXT_LINE_SPACE, textScrollBar.view_recno );		// 4 - space between lines
401 			}
402 
403 			if( refreshFlag & TUOPTION_TEXT_SCROLL )
404 			{
405 #ifdef TU_USE_BACKUP_SURFACE
406 				vga_front.put_bitmap(menuX1+TEXT_SCROLL_X1, menuY1+TEXT_SCROLL_Y1,
407 					textScrollArea.ptr);
408 #endif
409 				// display scroll bar
410 				textScrollBar.paint();
411 			}
412 
413 			if( refreshFlag & TUOPTION_SCROLL )
414 			{
415 #ifdef TU_USE_BACKUP_SURFACE
416 				// copy from back buffer
417 				vga_front.put_bitmap(menuX1+SCROLL_X1, menuY1+SCROLL_Y1,
418 					scrollArea.ptr);
419 #endif
420 				// display scroll bar
421 				scrollBar.paint();
422 			}
423 
424 			if( refreshFlag & TUOPTION_ALL_BROWSE )
425 			{
426 				int rec, slot;
427 				for( slot = 0; slot < scrollBar.view_size; ++slot)
428 				{
429 					int browseSlotX1 = menuX1+BROWSE_X1;
430 					int browseSlotY1 = menuY1+BROWSE_Y1+slot*BROWSE_REC_HEIGHT;
431 					int browseSlotX2 = menuX1+BROWSE_X2;
432 					int browseSlotY2 = menuY1+BROWSE_Y1+(slot+1)*BROWSE_REC_HEIGHT-1;
433 
434 					rec = scrollBar.view_recno + slot;
435 					if( refreshFlag & TUOPTION_BROWSE(slot) )
436 					{
437 #ifdef TU_USE_BACKUP_SURFACE
438 						vga_front.put_bitmap(browseSlotX1, browseSlotY1,
439 							browseArea[rec%MAX_BROWSE_DISP_REC].ptr);
440 #endif
441 						if( rec >= 1 && rec <= scenCount )
442 						{
443 							int textX = font_bible.put(browseSlotX1+TEXT_OFFSET_X,
444 								browseSlotY1+TEXT_OFFSET_Y, misc.format(rec), 0, browseSlotX2 );
445 
446 							//----- display the scenario name -----//
447 
448 							textX = font_bible.put(textX, browseSlotY1+TEXT_OFFSET_Y,
449 								". ", 0, browseSlotX2 );
450 
451 							textX = font_bible.put(textX, browseSlotY1+TEXT_OFFSET_Y,
452 								_(scenInfoArray[rec-1].scen_name), 0, browseSlotX2 );
453 
454 							//---- display the scenario's play status ----//
455 
456 							draw_checkbox(browseSlotX1 + TEXT_OFFSET_X + 675,
457 										  browseSlotY1 + TEXT_OFFSET_Y + 5,
458 										  static_cast<CHECKBOX_STATE>(scenInfoArray[rec - 1].play_status));
459 
460 							//---- display the scenario difficulty and bonus points ----//
461 
462 							String str(_("Difficulty"));
463 							str += " : ";
464 							str += scenInfoArray[rec-1].goal_difficulty;
465 
466 							font_bible.put(browseSlotX1+TEXT_OFFSET_X+400, browseSlotY1+TEXT_OFFSET_Y,
467 												str, 0, browseSlotX2 );
468 
469 							str  = _("Score Bonus");
470 							str += ": ";
471 							str += scenInfoArray[rec-1].goal_score_bonus;
472 
473 							font_bible.put(browseSlotX1+TEXT_OFFSET_X+530, browseSlotY1+TEXT_OFFSET_Y,
474 												str, 0, browseSlotX2 );
475 
476 							//--------------------------------------//
477 
478 							if( rec == browseRecno )
479 							{
480 								vga_front.adjust_brightness(browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2, -2);
481 
482 								//vga_front.put_bitmap_trans_decompress( menuX1+BROWSE_X1, menuY1+BROWSE_Y1+slot*BROWSE_REC_HEIGHT,
483 								//	image_button.read("LS-DWN"));
484 							}
485 						}
486 					}
487 				}
488 			}
489 
490 			// ###### begin Gilbert 1/11 #######//
491 			if( refreshFlag & TUOPTION_NAME_FIELD )
492 				playerNameField.paint();
493 			// ###### end Gilbert 1/11 #######//
494 
495 			refreshFlag = 0;
496 		}
497 
498 		sys.blt_virtual_buf();
499 
500 		if( scrollBar.detect() == 1)
501 		{
502 			refreshFlag |= TUOPTION_SCROLL | TUOPTION_ALL_BROWSE;
503 		}
504 		else if( scrollUp.detect() )
505 		{
506 			// click on scroll up
507 			int oldValue = scrollBar.view_recno;
508 			if( oldValue != scrollBar.set_view_recno(oldValue-1) )
509 				refreshFlag |= TUOPTION_ALL_BROWSE | TUOPTION_SCROLL;
510 		}
511 		else if( scrollDown.detect() )
512 		{
513 			// click on scroll down
514 			int oldValue = scrollBar.view_recno;
515 			if( oldValue != scrollBar.set_view_recno(oldValue+1) )
516 				refreshFlag |= TUOPTION_ALL_BROWSE | TUOPTION_SCROLL;
517 		}
518 		else if( textScrollBar.detect() == 1 )
519 		{
520 			refreshFlag |= TUOPTION_TEXT_SCROLL | TUOPTION_TEXT_AREA;
521 		}
522 		else if( textScrollUp.detect() )
523 		{
524 			// click on scroll up
525 			int oldValue = textScrollBar.view_recno;
526 			if( oldValue != textScrollBar.set_view_recno(oldValue-1) )
527 				refreshFlag |= TUOPTION_TEXT_SCROLL | TUOPTION_TEXT_AREA;
528 		}
529 		else if( textScrollDown.detect() )
530 		{
531 			// click on scroll down
532 			int oldValue = textScrollBar.view_recno;
533 			if( oldValue != textScrollBar.set_view_recno(oldValue+1) )
534 				refreshFlag |= TUOPTION_TEXT_SCROLL | TUOPTION_TEXT_AREA;
535 		}
536 		else if( mouse.double_click( menuX1+BROWSE_X1, menuY1+BROWSE_Y1,
537 			menuX1+BROWSE_X1+BROWSE_REC_WIDTH-1,
538 			menuY1+BROWSE_Y1+ BROWSE_REC_HEIGHT*MAX_BROWSE_DISP_REC -1) )
539 		{
540 			// double click on game slot
541 			int oldValue = browseRecno;
542 			int newValue = scrollBar.view_recno + (mouse.click_y(0) - BROWSE_Y1 - menuY1) / BROWSE_REC_HEIGHT;
543 			if( newValue <= scenCount && newValue == oldValue )
544 			{
545 				browseRecno = newValue;
546 				retFlag = newValue;
547 				break;
548 			}
549 		}
550 		else if( mouse.single_click( menuX1+BROWSE_X1, menuY1+BROWSE_Y1,
551 			menuX1+BROWSE_X1+BROWSE_REC_WIDTH-1,
552 			menuY1+BROWSE_Y1+ BROWSE_REC_HEIGHT*MAX_BROWSE_DISP_REC -1, 2) )
553 		{
554 			int btn;
555 			if (mouse.left_press) { btn = 0; }
556 			else if (mouse.right_press) { btn = 1; }
557 			// click on game slot
558 			int oldValue = browseRecno;
559 			int newValue = scrollBar.view_recno + (mouse.click_y(btn) - BROWSE_Y1 - menuY1) / BROWSE_REC_HEIGHT;
560 			if( newValue <= scenCount )
561 			{
562 				if( oldValue != newValue )
563 				{
564 					browseRecno = newValue;
565 					refreshFlag |= TUOPTION_BROWSE(newValue-scrollBar.view_recno)
566 						| TUOPTION_TEXT_BUFFER
567 						| TUOPTION_TEXT_AREA | TUOPTION_PIC_AREA;
568 					if( oldValue-scrollBar.view_recno >= 0 && oldValue-scrollBar.view_recno < MAX_BROWSE_DISP_REC)
569 						refreshFlag |= TUOPTION_BROWSE(oldValue-scrollBar.view_recno);
570 				}
571 			}
572 
573 			if (mouse.right_press)
574 			{
575 				int status = scenInfoArray[browseRecno - 1].play_status;
576 				status++;
577 				if(status > nsPlayerStats::PlayStatus::COMPLETED)
578 				{
579 					status = nsPlayerStats::PlayStatus::UNPLAYED;
580 				}
581 				scenInfoArray[browseRecno - 1].play_status = status;
582 				int browseSlotX1 = menuX1 + BROWSE_X1;
583 				int browseSlotY1 = menuY1 + BROWSE_Y1 + (newValue - scrollBar.view_recno) * BROWSE_REC_HEIGHT;
584 				draw_checkbox(browseSlotX1 + TEXT_OFFSET_X + 675,
585 							  browseSlotY1 + TEXT_OFFSET_Y + 5,
586 							  static_cast<CHECKBOX_STATE>(status));
587 
588 				// update PLAYSTAT.DAT
589 				String path;
590 				path += DIR_SCENARIO_PATH(scenInfoArray[browseRecno - 1].dir_id);;
591 				path += scenInfoArray[browseRecno - 1].file_name;
592 				playerStats.set_scenario_play_status(scenInfoArray[browseRecno - 1].file_name, static_cast<nsPlayerStats::PlayStatus>(status));
593 			}
594 		}
595 		// ######## begin Gilbert 1/11 #########//
596 		else if( playerNameField.detect() )
597 		{
598 			// load button
599 			refreshFlag = TUOPTION_NAME_FIELD;
600 		}
601 		// ######## end Gilbert 1/11 #########//
602 		else if( cancelButton.detect(KEY_ESC) || mouse.any_click(RIGHT_BUTTON) > 0)		// also when ESC key is pressed or right button
603 		{
604 			// cancel button or escape key
605 			refreshFlag = TUOPTION_ALL;
606 			retFlag = 0;
607 			break;		// break while(1)
608 		}
609 		else if( startButton.detect() )
610 		{
611 			// load button
612 			refreshFlag = TUOPTION_ALL;
613 			retFlag = browseRecno;
614 			break;
615 		}
616 	}
617 
618 	power.win_opened = 0;
619 
620 	return retFlag;
621 }
622 //------------ End of function Game::select_scenario -----------//
623 
624 
disp_scroll_bar_func(SlideVBar * scroll,int)625 static void disp_scroll_bar_func(SlideVBar *scroll, int)
626 {
627 	short rectTop = scroll->rect_top();
628 	short rectBottom = scroll->rect_bottom();
629 	vga_front.bar( scroll->scrn_x1, rectTop, scroll->scrn_x2, rectBottom, VGA_YELLOW+1);
630 	if( rectBottom - rectTop > 6 )
631 	{
632 		vga_front.d3_panel_up(scroll->scrn_x1, rectTop, scroll->scrn_x2, rectBottom,2,0);
633 	}
634 }
635 
636 
637