示例#1
0
文件: game.c 项目: sergot/asteroids
void update_game(game *g) {
    if(g->status == Quit) {
        del_game(g);
    } else {
        if(first_a == NULL)
            g->status = Win;
        else {
            update_shoots();
            update_asteroids();
            update_collisions(g);

            update_ship(g, first_a);
        }
    }
}
示例#2
0
文件: ogfilea.cpp 项目: mecirt/7k2
//-------- Begin of function GameFileArray::menu --------//
//
// <int> actionMode = -2 - save screen to back buffer
//                    -1 - restore screen to back buffer
//                    1 - save game
//                    2 - load game
//                    3 - load game from main menu
//
// <int *> recno    = if overwritting save game or load game acion 
//                    is succcessful, return the recno of GameFile
//
// return : <int> 1 - game loaded/saved
//                0 - user cancel loading/saving 
//               -1 - loading/saving error
//
int GameFileArray::menu(int actionMode, int *recno)
{
	enum { PAGE_WIDTH = 800, PAGE_HEIGHT = 600 };

	int bx = (VGA_WIDTH - PAGE_WIDTH) / 2;
	int by = (VGA_HEIGHT - PAGE_HEIGHT) / 2;

	if( actionMode == -2 || actionMode == -1)
	{
		// copy or restore screen to back buffer
		int scrnX1, scrnY1, scrnX2, scrnY2;
		scrnX1 = bx;
		scrnY1 = by;
		scrnX2 = scrnX1 + PAGE_WIDTH - 1;
		scrnY2 = scrnY1 + PAGE_HEIGHT - 1;

		return 1;
	}

	action_mode = actionMode;
	pre_game = 0;
	if( actionMode == 3 )		// actionMode = 3 means load game from main menu, so action_mode is still two
	{
		action_mode = 2;
		pre_game = 1;
	}

	if( action_mode==2 && size()==0 )
	{
		box.msg( text_game_menu.str_none_save_game() ); // "You haven't saved any games yet." );
		return 0;
	}

	// load race icon
	char deinitGameSet=0;
	char deinitUnitRes=0;
	char deinitRaceRes=0;
	char deinitMonsterRes=0;

	if( !game_set.set_opened_flag )
	{
		game_set.open_set(1);
		deinitGameSet = 1;
	}
	if( !unit_res.init_flag )
	{
		unit_res.init();
		deinitUnitRes = 1;
	}
	if( !race_res.init_flag )
	{
		race_res.init();
		deinitRaceRes = 1;
	}

	if( !monster_res.init_flag )
	{
		monster_res.init();
		// ##### begin Gilbert 30/10 ######//
		// deinitRaceRes = 1;
		deinitMonsterRes = 1;
		// ##### end Gilbert 30/10 ######//
	}

	//-------------------------------------//

	mouse_cursor.set_icon(CURSOR_NORMAL);
	mouse_cursor.set_frame(0);

	power.win_opened = 1;

	int minRecno = 1;

	//------ set current record no. -------//

	// ####### begin Gilbert 3/5 ########//
	int i;
	if( size() == 0 )
	{
		browse_recno = 0;
	}
	else
	{
		browse_recno = 1;
		for( i=1 ; i<=size() ; i++ )
		{
			if( strcasecmp(last_file_name, game_file_array[i]->file_name)==0 )
			{
				browse_recno = i;
				break;
			}
		}
	}
	// ####### end Gilbert 3/5 ########//

	//---------------------------------//

	browse_top_recno = minRecno;
	// in save game mode, browse_recno = 0 means selecting empty slot
	// in load game mode, browse_recno = 0 means nonthing is selected
	// browse_top_recno = browse_recno ? browse_recno : minRecno;

	// -------- generate palette ------//

	short colorRemapTable[0x100];
	{
		String str(DIR_IMAGE);
		if( pre_game )
			str += "CHOOSE.COL";
		else
			str += "CHOOSE2.COL";

		File palFile;
		palFile.file_open(str);
		ColorTable colorTable;

		BYTE palBuf[0x100][3];
		palFile.file_seek(8);     				// bypass the header info
		palFile.file_read(palBuf, sizeof(palBuf));
		palFile.file_close();

		// ------- palette description -------------//

		PalDesc palBufDesc( palBuf, 3, 0x100, 8 );

		//-------- create color remap table ---------//

		colorTable.generate_table_fast( 0, palBufDesc, ColorTable::bright_func );
		memcpy( colorRemapTable, colorTable.get_table(0), sizeof(colorRemapTable) );
	}

	int retFlag = 0;

#define SLOT_Y_SPACING 80
#define SLOT_X1(n) (bx + 119)
#define SLOT_Y1(n) (by + SLOT_Y_SPACING * (n) + 110)
#define SLOT_X2(n) (bx + 119 + SLOT_WIDTH - 1)
#define SLOT_Y2(n) (by + SLOT_Y_SPACING * (n) + 110 + SLOT_HEIGHT - 1)

	char *arrowBitmap = image_button.read("TRI-R");
	int pageUpX1 = bx + (LSCROLL_X2 + LSCROLL_X1 - ((Bitmap *)arrowBitmap)->get_width()) / 2;
	int pageUpY1 = by + (LSCROLL_Y2 + LSCROLL_Y1 - ((Bitmap *)arrowBitmap)->get_height()) / 2;
	int pageUpX2 = pageUpX1 + ((Bitmap *)arrowBitmap)->get_width() - 1;
	int pageUpY2 = pageUpY1 + ((Bitmap *)arrowBitmap)->get_height() - 1;
	int pageDownX1 = bx + (RSCROLL_X2 + RSCROLL_X1 - ((Bitmap *)arrowBitmap)->get_width()) / 2;
	int pageDownY1 = by + (RSCROLL_Y2 + RSCROLL_Y1 - ((Bitmap *)arrowBitmap)->get_height()) / 2;
	int pageDownX2 = pageDownX1 + ((Bitmap *)arrowBitmap)->get_width() - 1;
	int pageDownY2 = pageDownY1 + ((Bitmap *)arrowBitmap)->get_height() - 1;

	int pageNoX1 = bx + 556;
	int pageNoY1 = by + 87;
	int pageNoX2 = bx + 675;
	int pageNoY2 = by + 107;

	// ------- define save buffer area ----------//

	Blob2DW browseArea[MAX_BROWSE_DISP_REC];		// save bitmap of save game slot areas
	Blob2DW pageUpArea, pageDownArea;
	Blob2DW pageNoArea;

	// ------- define button object ----------//

	Button startButton, cancelButton, delButton;
	Button saveNewButton;

	if( !pre_game )
	{
		startButton.create_text( bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2, 
			action_mode == 1 ? text_game_menu.str_save() : text_game_menu.str_load() );
		if( action_mode == 1 )
			saveNewButton.create_text( bx+BUTTON3_X1, by+BUTTON3_Y1, bx+BUTTON3_X2, by+BUTTON3_Y2, 
				text_game_menu.str_save_new() );
		delButton.create_text( bx+BUTTON7_X1, by+BUTTON7_Y1, bx+BUTTON7_X2, by+BUTTON7_Y2, text_game_menu.str_delete_save() );
		cancelButton.create_text( bx+BUTTON4_X1, by+BUTTON4_Y1, bx+BUTTON4_X2, by+BUTTON4_Y2, text_game_menu.str_cancel() );
	}

//	int i;
	int page, maxPage;
	maxPage = (size()-minRecno+1 + MAX_BROWSE_DISP_REC-1) / MAX_BROWSE_DISP_REC;	// divide but round up
	page = (browse_recno - minRecno) / MAX_BROWSE_DISP_REC;

	while(1)
	{
		//---------- yield --------//

		sys.yield();

		mouse.get_event();

		// --------- display ----------//

				// ------- display image --------//

				File imageFile;
				String str(DIR_IMAGE);
				if( pre_game )
				{
					str += "CHOOSE.ICN";
					imageFile.file_open(str);
					vga.active_buf->put_large_bitmap(bx, by, &imageFile, colorRemapTable);
				}
				else
				{
					str += "CHOOSE2.ICN";
					imageFile.file_open(str);
					vga.active_buf->put_large_bitmap_trans(bx, by, &imageFile, colorRemapTable);
				}

				// ------- display title -------//

				if( action_mode == 1 )
					font_bold_black.center_put( bx+SCROLL_SHEET_X1, by+SCROLL_SHEET_Y1, 
						bx+SCROLL_SHEET_X2, SLOT_Y1(0), text_game_menu.str_save_game() ); // "Save Game" );
				else if( action_mode == 2 )
					font_bold_black.center_put( bx+SCROLL_SHEET_X1, by+SCROLL_SHEET_Y1, 
						bx+SCROLL_SHEET_X2, SLOT_Y1(0), text_game_menu.str_load_game() ); // "Load Game" );

				// display save, save new/ load, delete cancel button

				if( pre_game )
				{
					if( action_mode == 1 )
					{
						font_thin_black.center_put( bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2, text_game_menu.str_save() ); // "Save" );
						font_thin_black.center_put( bx+BUTTON3_X1, by+BUTTON3_Y1, bx+BUTTON3_X2, by+BUTTON3_Y2, text_game_menu.str_save_new() ); // "Save New" );
					}
					else if( action_mode == 2 )
					{
						font_thin_black.center_put( bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2, text_game_menu.str_load() ); // "Load" );
					}
					font_thin_black.center_put( bx+BUTTON4_X1, by+BUTTON4_Y1, bx+BUTTON4_X2, by+BUTTON4_Y2, text_game_menu.str_cancel() ); // "Cancel" );
					font_thin_black.center_put( bx+BUTTON7_X1, by+BUTTON7_Y1, bx+BUTTON7_X2, by+BUTTON7_Y2, text_game_menu.str_delete_save() ); // "Delete" );
				}
				else
				{
					startButton.paint();
					if( action_mode == 1 )
						saveNewButton.paint();
					cancelButton.paint();
					delButton.paint();
				}

				// capture area

				for( i = 0; i < MAX_BROWSE_DISP_REC; ++i )
				{
					browseArea[i].clear();
					browseArea[i].resize(SLOT_X1(i), SLOT_Y1(i), SLOT_WIDTH, SLOT_HEIGHT );
					vga.active_buf->read_bitmapW( SLOT_X1(i), SLOT_Y1(i), SLOT_X2(i), SLOT_Y2(i), browseArea[i].bitmap_ptr() );
				}

				// capture page up area
				pageUpArea.clear();
				pageUpArea.resize( pageUpX1, pageUpY1, ((Bitmap *)arrowBitmap)->get_width(), ((Bitmap *)arrowBitmap)->get_height() );
				vga.active_buf->read_bitmapW( pageUpX1, pageUpY1, pageUpX2, pageUpY2, pageUpArea.bitmap_ptr() );
				pageDownArea.clear();
				pageDownArea.resize( pageDownX1, pageDownY1, ((Bitmap *)arrowBitmap)->get_width(), ((Bitmap *)arrowBitmap)->get_height() );
				vga.active_buf->read_bitmapW( pageDownX1, pageDownY1, pageDownX2, pageDownY2, pageDownArea.bitmap_ptr() );

				// capture page no area
				pageNoArea.clear();
				pageNoArea.resize( pageNoX1, pageNoY1, pageNoX2-pageNoX1+1, pageNoY2-pageNoY1+1 );
				vga.active_buf->read_bitmapW( pageNoX1, pageNoY1, pageNoX2, pageNoY2, pageNoArea.bitmap_ptr() );

			for( i = 0; i < MAX_BROWSE_DISP_REC; ++i )
			{
					int browseSlotX1 = SLOT_X1(i);
					int browseSlotY1 = SLOT_Y1(i);
					int browseSlotX2 = SLOT_X2(i);
					int browseSlotY2 = SLOT_Y2(i);

					// draw save bitmap area
					vga_buffer.put_bitmapW( browseSlotX1, browseSlotY1, browseArea[i].bitmap_ptr() );

					// draw slot content
					int rec = page * MAX_BROWSE_DISP_REC + i + minRecno;
					if( rec == 0 )
					{
						font_bold_black.center_put( browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2, text_game_menu.str_empty_game_slot() ); // "Empty Game Slot" );
					}
					else if( rec >= 1 && rec <= size() )
					{
						// remain game_file_array[rec]->disp_info() for file find
						operator[](rec)->disp_info( browseSlotX1, browseSlotY1 );		
					}

					// draw selected frame

					if( rec == browse_recno )
					{
						// draw black frame
						vga_buffer.rect( browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2, 2, V_BLACK );
					}
			}

//				String str;
//				str = "page ";
//				str += page+1;
//				str += "/";
//				str += maxPage;
				vga.active_buf->put_bitmapW( pageNoX1, pageNoY1, pageNoArea.bitmap_ptr() );		
				font_snds.center_put( pageNoX1, pageNoY1, pageNoX2, pageNoY2, text_game_menu.str_page_str(page+1, maxPage) );

				if( page > 0 )
					vga.active_buf->put_bitmap(pageUpX1, pageUpY1, arrowBitmap, 0, 2, true);
				else
					vga.active_buf->put_bitmapW( pageUpX1, pageUpY1, pageUpArea.bitmap_ptr() );

				if( page < maxPage-1 )
					vga.active_buf->put_bitmap(pageDownX1, pageDownY1, arrowBitmap, 0, 2);
				else
					vga.active_buf->put_bitmapW( pageDownX1, pageDownY1, pageDownArea.bitmap_ptr() );

		// ------ detect slots -------//

		int breakWhileFlag = 0;

		for( i = 0; i < MAX_BROWSE_DISP_REC; ++i )
		{
			int rec = page * MAX_BROWSE_DISP_REC + i + minRecno;
			int browseSlotX1 = SLOT_X1(i);
			int browseSlotY1 = SLOT_Y1(i);
			int browseSlotX2 = SLOT_X2(i);
			int browseSlotY2 = SLOT_Y2(i);

			if( rec < minRecno || rec > size() )
				continue;

			if( mouse.double_click(browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2) )
			{
				// double click on game slot
				if( browse_recno == rec )
				{
					browse_recno = rec;
					if( recno )
						*recno = browse_recno;
					breakWhileFlag = 1;	// signal to break while(1) loop
					retFlag = process_action(0);

//					if( retFlag < 0 )
//						box.msg("Error");
					break;		// BUGHERE : how to break while loop
				}
			}
			else if( mouse.single_click(browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2) )
			{
				// click on game slot
				if( browse_recno != rec )
				{
					// refresh old slot
					int oldSlot = browse_recno - page * MAX_BROWSE_DISP_REC - minRecno;

					// refresh new slot
					browse_recno = rec;
					break;
				}
			}
		}

		// ------- detect scroll button -------//

		if( page > 0 && mouse.any_click( bx+LSCROLL_X1, by+LSCROLL_Y1, bx+LSCROLL_X2, by+LSCROLL_Y2 ) )
		{
			page--;
		}

		if( page < maxPage-1 && mouse.any_click( bx+RSCROLL_X1, by+RSCROLL_Y1, bx+RSCROLL_X2, by+RSCROLL_Y2 ) )
		{
			page++;
		}

		// -------- detect button at bottom -------//

		if( (pre_game ? mouse.single_click( bx+BUTTON4_X1, by+BUTTON4_Y1, bx+BUTTON4_X2, by+BUTTON4_Y2) : cancelButton.detect())
			|| mouse.key_code == KEY_ESC || mouse.any_click(RIGHT_BUTTON) > 0)		// also when ESC key is pressed or right button
		{
			// cancel button or escape key
			retFlag = 0;
			breakWhileFlag = 1;
			break;		// break while(1)
		}
		else if( (action_mode == 1 || (action_mode == 2 && browse_recno))
			&& (pre_game ? mouse.single_click(bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2) : startButton.detect()) )
		{
			// save / load button
			if( recno )
				*recno = browse_recno;
			retFlag = process_action(0);
			if( retFlag != 0 )
			{
//				if( retFlag < 0 )
//					box.msg("Error");
				breakWhileFlag = 1;
				break;
			}
		}
		else if( action_mode == 1
			&& (pre_game ? mouse.single_click( bx+BUTTON3_X1, by+BUTTON3_Y1, bx+BUTTON3_X2, by+BUTTON3_Y2) : saveNewButton.detect()) )
		{
			// save new button
			retFlag = process_action(1);
			if( retFlag != 0 )
			{
//				if( retFlag < 0 )
//					box.msg("Error");
				breakWhileFlag = 1;
				break;
			}
		}
		else if( browse_recno 
			&& (pre_game ? mouse.single_click( bx+BUTTON7_X1, by+BUTTON7_Y1, bx+BUTTON7_X2, by+BUTTON7_Y2) : delButton.detect()) )
		{
			// delete save game button
			if( browse_recno != 0 )			// cannot del save game slot
			{
				del_game();
				if( browse_recno > size() )
				{
					browse_recno = size();
				}
//				if( browse_top_recno > size()-MAX_BROWSE_DISP_REC+1)
//					browse_top_recno = size()-MAX_BROWSE_DISP_REC+1;
//				if( browse_top_recno < minRecno )
//					browse_top_recno = minRecno;
				// scrollBar.set_view_recno(browse_top_recno);

				// recalculate page
				maxPage = (size()-minRecno+1 + MAX_BROWSE_DISP_REC-1) / MAX_BROWSE_DISP_REC;	// divide but round up
				if( page >= maxPage )
				{
					page = maxPage - 1;
					if( page < 0 )
						page = 0;
				}

				if( action_mode == 2 && size()==0 )
				{
					box.msg( text_game_menu.str_none_save_game()); // "You haven't saved any games yet." );
					return 0;
				}
			}
			else
			{
				box.msg( text_game_menu.str_cannot_delete_slot()); // "Cannot delete this slot");
			}
		}
                vga.flip();

		if( breakWhileFlag )
			break;
	}

	power.win_opened = 0;
	if( retFlag <= 0 )
	{
		// if load game is successful, no need to deinit resource
		if( deinitGameSet )
			game_set.close_set();
		if( deinitUnitRes )
			unit_res.deinit();
		if( deinitRaceRes )
			race_res.deinit();
		if( deinitMonsterRes )
			monster_res.deinit();
	}

	mouse.reset_click();
	return retFlag;

#undef SLOT_X1
#undef SLOT_Y1
#undef SLOT_X2
#undef SLOT_y2
}
示例#3
0
文件: OGFILEA.cpp 项目: Cap-Man/7kaa
//-------- Begin of function GameFileArray::menu --------//
//
// <int> actionMode = -2 - save screen to back buffer
//                    -1 - restore screen to back buffer
//                    1 - save game
//                    2 - load game
//
// <int *> recno    = if overwritting save game or load game acion 
//                    is succcessful, return the recno of GameFile
//
// return : <int> 1 - game loaded/saved
//                0 - user cancel loading/saving 
//               -1 - loading/saving error
//
int GameFileArray::menu(int actionMode, int *recno)
{
	if( actionMode == -2 || actionMode == -1)
	{
		// copy or restore screen to back buffer
		int scrnX1, scrnY1, scrnX2, scrnY2;
		if( game.game_mode==GAME_PREGAME )	  // called from the main menu, not in the game
		{
			scrnX1 = FILE_MAIN_MENU_X1;
			scrnY1 = FILE_MAIN_MENU_Y1;
		}
		else
		{
			scrnX1 = FILE_IN_GAME_MENU_X1;
			scrnY1 = FILE_IN_GAME_MENU_Y1;
		}
		scrnX2 = scrnX1 + FILE_MENU_WIDTH-1;
		scrnY2 = scrnY1 + FILE_MENU_HEIGHT-1;

		mouse.hide_area( scrnX1, scrnY1, scrnX2, scrnY2);

		if( actionMode == -2 )
			// save to back buffer
			IMGcopy(vga_back.buf_ptr(), vga_back.buf_pitch(),
				vga_front.buf_ptr(), vga_front.buf_pitch(),
				scrnX1, scrnY1, scrnX2, scrnY2);
		else
			// restore from back buffer
			IMGcopy(vga_front.buf_ptr(), vga_front.buf_pitch(),
				vga_back.buf_ptr(), vga_back.buf_pitch(),
				scrnX1, scrnY1, scrnX2, scrnY2);

		mouse.show_area();

		return 1;
	}

	// #### begin Gilbert 25/9 ########//
	//#ifdef DEMO          // No game saving in demo version
	//	box.msg( "Sorry, you cannot load/save game in the demo version." );
	//	return -1;
	//#endif
	// #### end Gilbert 25/9 ########//

	action_mode = actionMode;

	if( action_mode==2 && size()==0 )
	{
		box.msg( _("You haven't saved any games yet.") );
		return 0;
	}

	// load race icon
	char deinitGameSet=0;
	char deinitUnitRes=0;
	char deinitRaceRes=0;

	if( !game_set.set_opened_flag )
	{
		game_set.open_set(1);
		deinitGameSet = 1;
	}
	if( !unit_res.init_flag )
	{
		unit_res.init();
		deinitUnitRes = 1;
	}
	if( !race_res.init_flag )
	{
		race_res.init();
		deinitRaceRes = 1;
	}

	//-------------------------------------//

	if( game.game_mode==GAME_PREGAME )	  // called from the main menu, not in the game
	{
		menu_x1 = FILE_MAIN_MENU_X1;
		menu_y1 = FILE_MAIN_MENU_Y1;
	}
	else
	{
		menu_x1 = FILE_IN_GAME_MENU_X1;
		menu_y1 = FILE_IN_GAME_MENU_Y1;
	}

	int x=menu_x1, y=menu_y1+17;

	// vga_back.adjust_brightness( x, y, x+menu_x1-1, y+menu_y1-1, -6 );
	vga_util.blt_buf( x, y, x+menu_x1-1, y+menu_y1-1, 0 );

	mouse_cursor.set_icon(CURSOR_NORMAL);

	power.win_opened = 1;

	int minRecno = action_mode == 1 ? 0 : 1;

	//------ set current record no. -------//

	for( int i=1 ; i<=size() ; i++ )
	{
		if( strcmp(last_file_name, game_file_array[i]->file_name)==0 )
		{
			browse_recno = i;
			break;
		}
	}

	//---------------------------------//

	browse_top_recno = minRecno;
	// in save game mode, browse_recno = 0 means selecting empty slot
	// in load game mode, browse_recno = 0 means nonthing is selected
	// browse_top_recno = browse_recno ? browse_recno : minRecno;

	//--------------------------------------//
	Button3D scrollUp, scrollDown, saveButton, saveNewButton, delButton, cancelButton;
	int retFlag = 0;
	int refreshFlag = LSOPTION_ALL;
	//int scrollButtonY1 = menu_y1+SCROLL_Y1, scrollButtonY2 = menu_y1+SCROLL_Y2;
	//int dragingScrollBar = 0;
	//int dragScrollYDiff;	// when draging begins, mouse.cur_y - scrollButtonY1

	SlideVBar scrollBar;
	scrollBar.init_scroll(menu_x1+SCROLL_X1, menu_y1+SCROLL_Y1, menu_x1+SCROLL_X2, menu_y1+SCROLL_Y2,
		MAX_BROWSE_DISP_REC, disp_scroll_bar_func);
	scrollBar.set(minRecno, size(), browse_top_recno);

	// try to centre the selected record on the browser
	//browse_top_recno = browse_recno - MAX_BROWSE_DISP_REC /2;
	//if( browse_top_recno > size()-MAX_BROWSE_DISP_REC+1)
	//	browse_top_recno = size()-MAX_BROWSE_DISP_REC+1;
	//if( browse_top_recno < minRecno )
	//	browse_top_recno = minRecno;
	browse_top_recno = scrollBar.set_view_recno(browse_recno - MAX_BROWSE_DISP_REC /2);

	Blob browseArea[MAX_BROWSE_DISP_REC];
	Blob scrollArea;

	while(1)
	{
		//---------- yield --------//

		sys.yield();

		mouse.get_event();

		// When called ingame sys.signal_exit_flag is set to 2 by Sys::load_game
		if( sys.signal_exit_flag == 1 )
		{
			retFlag = 0;
			break;
		}

		// --------- display ----------//

		if( refreshFlag )
		{
			if( refreshFlag & LSOPTION_PAGE )
			{
				mouse.hide_area(menu_x1, menu_y1, menu_x1+FILE_MENU_WIDTH, menu_y1+FILE_MENU_HEIGHT);

				image_interface.put_front( menu_x1, menu_y1, actionMode==1 ? (char*)"SAVEGAME" : (char*)"LOADGAME" );

				scrollUp.paint(menu_x1+SCROLL_X1+1,menu_y1+SCROLL_Y1-17, "SV-UP-U", "SV-UP-D");
				scrollDown.paint(menu_x1+SCROLL_X1+1,menu_y1+SCROLL_Y2+1, "SV-DW-U", "SV-DW-D");
				if( action_mode == 1)
				{
					saveButton.paint(menu_x1+34, menu_y1+354, "SAVE", "CANCEL1D");
					saveNewButton.paint(menu_x1+147, menu_y1+354, "SAVE-NEW", "CANCEL1D");
					delButton.paint(menu_x1+260, menu_y1+354, "DELETE", "CANCEL1D");
				}
				else if( action_mode == 2)
				{
					saveButton.paint(menu_x1+34, menu_y1+354, "LOAD", "CANCEL1D");
				}
				cancelButton.paint(menu_x1+473, menu_y1+354, "CANCEL1", "CANCEL1D");

				// capture browseArea, scrollArea
				for( int j = 0; j < MAX_BROWSE_DISP_REC; ++j)
				{
					browseArea[j].resize(2*sizeof(short)+BROWSE_REC_WIDTH*BROWSE_REC_HEIGHT);
					vga_front.read_bitmap( 
						menu_x1+BROWSE_X1, menu_y1+BROWSE_Y1+j*BROWSE_REC_HEIGHT,
						menu_x1+BROWSE_X2, menu_y1+BROWSE_Y1+j*BROWSE_REC_HEIGHT+BROWSE_REC_HEIGHT-1,
						browseArea[j].ptr);
				}

				scrollArea.resize(2*sizeof(short)+SCROLL_WIDTH*SCROLL_HEIGHT);
				vga_front.read_bitmap( menu_x1+SCROLL_X1, menu_y1+SCROLL_Y1, 
					menu_x1+SCROLL_X2, menu_y1+SCROLL_Y2, scrollArea.ptr);

				mouse.show_area();
			}

			if( scrollBar.max_recno != size() )
			{
				scrollBar.set_max_recno(size());
				if( scrollBar.view_recno > scrollBar.max_view_recno() )
				{
					scrollBar.view_recno = scrollBar.max_view_recno();
				}
				refreshFlag |= LSOPTION_SCROLL;
			}

			if( refreshFlag & LSOPTION_SCROLL )
			{
				vga_front.put_bitmap( menu_x1+SCROLL_X1, menu_y1+SCROLL_Y1,
					scrollArea.ptr);
				scrollBar.paint();
			}

			if( refreshFlag & LSOPTION_ALL_SLOTS )
			{
				for(int slot = 0; slot < MAX_BROWSE_DISP_REC; ++slot)
				{
					int rec = slot + scrollBar.view_recno;
					if( refreshFlag & LSOPTION_SLOT(slot) )
					{
						int browseSlotX1 = menu_x1+BROWSE_X1;
						int browseSlotY1 = menu_y1+BROWSE_Y1+slot*BROWSE_REC_HEIGHT;
						int browseSlotX2 = menu_x1+BROWSE_X2;
						int browseSlotY2 = menu_y1+BROWSE_Y1+(slot+1)*BROWSE_REC_HEIGHT-1;

						mouse.hide_area(browseSlotX1, browseSlotY1,
							browseSlotX2, browseSlotY2);
						vga_front.put_bitmap( browseSlotX1, browseSlotY1,
							browseArea[rec%MAX_BROWSE_DISP_REC].ptr);

						if( rec == 0 )
						{
							err_when( action_mode!=1 );
							font_bible.center_put( browseSlotX1, browseSlotY1,
								browseSlotX2, browseSlotY2, _("Empty Game Slot") );
						}
						else if( rec <= size() )
						{
							game_file_array[rec]->disp_info(browseSlotX1, browseSlotY1);
						}
						if( rec == browse_recno )
						{
							vga_front.adjust_brightness( browseSlotX1, browseSlotY1,
								browseSlotX2, browseSlotY2, -2);
							vga_front.put_bitmap_trans_decompress(browseSlotX1, browseSlotY1,
								image_button.read("LS-DWN"));
						}
						mouse.show_area();
					}
				}
				// disp_browse();
			}

			refreshFlag = 0;
		}

		sys.blt_virtual_buf();

		if( scrollBar.detect() == 1 )
		{
			browse_top_recno = scrollBar.view_recno;
			refreshFlag |= LSOPTION_SCROLL | LSOPTION_ALL_SLOTS;
		}
		else if( scrollUp.detect() )
		{
			// click on scroll up
			int oldValue = scrollBar.view_recno;
			if( oldValue != scrollBar.set_view_recno(oldValue-1) )
				refreshFlag |= LSOPTION_SCROLL | LSOPTION_ALL_SLOTS;
			browse_top_recno = scrollBar.view_recno;
		}
		else if( scrollDown.detect() )
		{
			// click on scroll down
			// click on scroll up
			int oldValue = scrollBar.view_recno;
			if( oldValue != scrollBar.set_view_recno(oldValue+1) )
				refreshFlag |= LSOPTION_SCROLL | LSOPTION_ALL_SLOTS;
			browse_top_recno = scrollBar.view_recno;
		}
		else if( mouse.double_click( menu_x1+BROWSE_X1, menu_y1+BROWSE_Y1, 
			menu_x1+BROWSE_X1+BROWSE_REC_WIDTH-1, 
			menu_y1+BROWSE_Y1+ BROWSE_REC_HEIGHT*MAX_BROWSE_DISP_REC -1) )
		{
			// double click on game slot
			int oldValue = browse_recno;
			int newValue = scrollBar.view_recno + (mouse.click_y(0) - BROWSE_Y1 - menu_y1) / BROWSE_REC_HEIGHT;
			if( newValue <= size())
			{
				// ######## begin Gilbert 31/10 ########//
				if( newValue == oldValue )
				{
					browse_recno = newValue;
					refreshFlag |= LSOPTION_SLOT(newValue-scrollBar.view_recno);
					if( oldValue-scrollBar.view_recno >= 0 && oldValue-scrollBar.view_recno < MAX_BROWSE_DISP_REC )
						refreshFlag |= LSOPTION_SLOT(oldValue-scrollBar.view_recno);
					if( recno )
						*recno = browse_recno;
					retFlag = process_action(0);
//					if( retFlag < 0 )
//						box.msg("Error");
					break;
				}
				// ######## end Gilbert 31/10 ########//
			}
		}
		else if( mouse.single_click( menu_x1+BROWSE_X1, menu_y1+BROWSE_Y1, 
			menu_x1+BROWSE_X1+BROWSE_REC_WIDTH-1, 
			menu_y1+BROWSE_Y1+ BROWSE_REC_HEIGHT*MAX_BROWSE_DISP_REC -1) )
		{
			// click on game slot
			int oldValue = browse_recno;
			int newValue = scrollBar.view_recno + (mouse.click_y(0) - BROWSE_Y1 - menu_y1) / BROWSE_REC_HEIGHT;
			if( newValue <= size())
			{
				// ##### begin Gilbert 31/10 #######//
				//if( oldValue == browse_recno )
				//{
				//	browse_recno = newValue;
				//	refreshFlag |= LSOPTION_SLOT(oldValue-scrollBar.view_recno)
				//		| LSOPTION_SLOT(newValue-scrollBar.view_recno);
				//}
				if( newValue != oldValue )
				{
					browse_recno = newValue;
					refreshFlag |= LSOPTION_SLOT(newValue-scrollBar.view_recno);
					if( oldValue-scrollBar.view_recno >= 0 && oldValue-scrollBar.view_recno < MAX_BROWSE_DISP_REC )
						refreshFlag |= LSOPTION_SLOT(oldValue-scrollBar.view_recno);
				}
				// ##### end Gilbert 31/10 #######//
			}
		}
		else if( cancelButton.detect(KEY_ESC) || mouse.any_click(RIGHT_BUTTON) > 0)		// also when ESC key is pressed or right button
		{
			// cancel button or escape key
			refreshFlag = LSOPTION_ALL;
			retFlag = 0;
			break;		// break while(1)
		}
		else if( (action_mode == 1 || (action_mode == 2 && browse_recno))
			&& saveButton.detect() )
		{
			// save / load button
			refreshFlag = LSOPTION_ALL;
			if( recno )
				*recno = browse_recno;
			retFlag = process_action(0);
			// ##### begin Gilbert 15/10 #####//
			if( retFlag != 0 )
			{
//				if( retFlag < 0 )
//					box.msg("Error");
				break;
			}
			// ##### end Gilbert 15/10 #####//
		}
		else if( action_mode == 1 && saveNewButton.detect() )
		{
			// save new button
			refreshFlag = LSOPTION_ALL;
			retFlag = process_action(1);
//			if( retFlag < 0 )
//				box.msg("Error");
			break;
		}
		else if( action_mode == 1 && browse_recno && delButton.detect() )
		{
			// delete save game button
			if( browse_recno != 0 )			// cannot del save game slot
			{
				del_game();
				if( browse_recno > size() )
				{
					browse_recno = size();
				}
				if( browse_top_recno > size()-MAX_BROWSE_DISP_REC+1)
					browse_top_recno = size()-MAX_BROWSE_DISP_REC+1;
				if( browse_top_recno < minRecno )
					browse_top_recno = minRecno;
				scrollBar.set_view_recno(browse_top_recno);
				refreshFlag |= LSOPTION_ALL_SLOTS | LSOPTION_SCROLL;
			}
			else
			{
				box.msg(_("Cannot delete this slot"));
			}
			refreshFlag = LSOPTION_ALL;
		}
	}

	power.win_opened = 0;
	if( retFlag <= 0 )
	{
		// if load game is successful, no need to deinit resource
		if( deinitGameSet )
			game_set.close_set();
		if( deinitUnitRes )
			unit_res.deinit();
		if( deinitRaceRes )
			race_res.deinit();
	}

	mouse.reset_click();
	return retFlag;
}