CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

MAPEDDLG.CPP (129817B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header:   F:\projects\c&c\vcs\code\mapeddlg.cpv   2.18   16 Oct 1995 16:49:00   JOE_BOSTIC  $ */
     17 /***************************************************************************
     18  **   C O N F I D E N T I A L --- W E S T W O O D    S T U D I O S        **
     19  ***************************************************************************
     20  *                                                                         *
     21  *                 Project Name : Command & Conquer                        *
     22  *                                                                         *
     23  *                    File Name : MAPEDDLG.CPP                             *
     24  *                                                                         *
     25  *                   Programmer : Bill Randolph                            *
     26  *                                                                         *
     27  *                   Start Date : November 18, 1994                        *
     28  *                                                                         *
     29  *                  Last Update : December 12, 1994   [BR]                 *
     30  *                                                                         *
     31  *-------------------------------------------------------------------------*
     32  * Map Editor dialogs & main menu options                                  *
     33  *-------------------------------------------------------------------------*
     34  * Functions:                                                              *
     35  *   MapEditClass::New_Scenario -- creates a new scenario                  *
     36  *   MapEditClass::Load_Scenario -- loads a scenario INI file              *
     37  *   MapEditClass::Save_Scenario -- saves current scenario to an INI file  *
     38  *   MapEditClass::Pick_Scenario -- dialog for choosing scenario           *
     39  *   MapEditClass::Size_Map -- lets user set size & location of map        *
     40  *   MapEditClass::Scenario_Dialog -- scenario global parameters dialog    *
     41  *   MapEditClass::Handle_Triggers -- processes the trigger dialogs        *
     42  *   MapEditClass::Select_Trigger -- lets user select a trigger            *
     43  *   MapEditClass::Edit_Trigger -- lets user edit a [new] trigger          *
     44  *   MapEditClass::Import_Triggers -- lets user import triggers            *
     45  *   MapEditClass::Import_Teams -- lets user import teams                  *
     46  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     47 
     48 #include	"function.h"
     49 
     50 #ifdef SCENARIO_EDITOR
     51 
     52 
     53 /***************************************************************************
     54  * MapEditClass::New_Scenario -- creates a new scenario                    *
     55  *                                                                         *
     56  * - Prompts user for scenario data (house, scenario #); sets globals      *
     57  *     PlayerPtr (for house) & Scenario (for scenario #)                   *
     58  *   - Prompts user for map size                                           *
     59  * - Initializes the scenario by calling Clear_Scenario(), which calls     *
     60  *     everybody's Init() routine                                          *
     61  *                                                                         *
     62  * INPUT:                                                                  *
     63  *      none.                                                              *
     64  *                                                                         *
     65  * OUTPUT:                                                                 *
     66  *      0 = new scenario created, -1 = not                                 *
     67  *                                                                         *
     68  * WARNINGS:                                                               *
     69  *      none.                                                              *
     70  *                                                                         *
     71  * HISTORY:                                                                *
     72  *   10/21/1994 BR : Created.                                              *
     73  *=========================================================================*/
     74 int MapEditClass::New_Scenario(void)
     75 {
     76 	int scen_num = Scenario;
     77 	ScenarioPlayerType player = ScenPlayer;
     78 	ScenarioDirType dir = ScenDir;
     79 	ScenarioVarType var = ScenVar;
     80 	int rc;
     81 	HousesType house;
     82 
     83 	/*
     84 	------------------------ Prompt for scenario info ------------------------
     85 	*/
     86 	rc = Pick_Scenario("New Scenario", &scen_num, &player, &dir, &var, 1);
     87 	if (rc != 0) {
     88 		return(-1);
     89 	}
     90 
     91 	/*
     92 	-------------------------- Blow away everything --------------------------
     93 	*/
     94 	Clear_Scenario();
     95 
     96 	/*
     97 	----------------------------- Set parameters -----------------------------
     98 	*/
     99 	Scenario = scen_num;
    100 	ScenPlayer = player;
    101 	ScenDir = dir;
    102 	ScenVar = var;
    103 	Set_Scenario_Name(ScenarioName,scen_num,player,dir,var);
    104 
    105 	/*
    106 	----------------------------- Create houses ------------------------------
    107 	*/
    108 	for (house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
    109 		new HouseClass(house);
    110 	}
    111 
    112 	if (ScenPlayer == SCEN_PLAYER_MPLAYER) {
    113 		PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI1);
    114 		PlayerPtr->IsHuman = true;
    115 		LastHouse = HOUSE_MULTI1;
    116 	} else {
    117 		if (player == SCEN_PLAYER_GDI) {
    118 			PlayerPtr = HouseClass::As_Pointer(HOUSE_GOOD);
    119 			PlayerPtr->IsHuman = true;
    120 			Base.House = HOUSE_BAD;
    121 		} else {
    122 			if (player == SCEN_PLAYER_NOD) {
    123 				PlayerPtr = HouseClass::As_Pointer(HOUSE_BAD);
    124 				PlayerPtr->IsHuman = true;
    125 				Base.House = HOUSE_GOOD;
    126 			} else {
    127 				PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4);
    128 				PlayerPtr->IsHuman = true;
    129 				Base.House = HOUSE_MULTI4;
    130 			}
    131 		}
    132 		LastHouse = HOUSE_GOOD;
    133 	}
    134 
    135 	/*
    136 	-------------------------- Init the entire map ---------------------------
    137 	*/
    138 	Init_Clear();
    139 	Fill_In_Data();
    140 
    141 	/*
    142 	-------------------------- Prompt for map size ---------------------------
    143 	*/
    144 	Size_Map(-1,-1,20,20);
    145 
    146 	/*
    147 	------ Set the Home & Reinforcement Cells to the center of the map -------
    148 	*/
    149 	Waypoint[WAYPT_REINF] = XY_Cell(MapCellX + MapCellWidth / 2, MapCellY + MapCellHeight / 2);
    150 	Waypoint[WAYPT_HOME] = XY_Cell(MapCellX + MapCellWidth / 2, MapCellY + MapCellHeight / 2);
    151 	(*this)[Coord_Cell(TacticalCoord)].IsWaypoint = 1;
    152 	Flag_Cell(Coord_Cell(TacticalCoord));
    153 
    154 	ScenarioInit++;
    155 	Set_Tactical_Position(Cell_Coord(Waypoint[WAYPT_HOME]));
    156 	ScenarioInit--;
    157 
    158 	return(0);
    159 }
    160 
    161 
    162 /***************************************************************************
    163  * MapEditClass::Load_Scenario -- loads a scenario INI file                *
    164  *                                                                         *
    165  * - Prompts user for scenario data (house, scenario #); sets globals      *
    166  *     PlayerPtr (for house) & Scenario (for scenario #)                   *
    167  * - Loads the INI file for that scenario                                  *
    168  *                                                                         *
    169  * INPUT:                                                                  *
    170  *      none.                                                              *
    171  *                                                                         *
    172  * OUTPUT:                                                                 *
    173  *      0.                                                                 *
    174  *                                                                         *
    175  * WARNINGS:                                                               *
    176  *      none.                                                              *
    177  *                                                                         *
    178  * HISTORY:                                                                *
    179  *   10/21/1994 BR : Created.                                              *
    180  *=========================================================================*/
    181 int MapEditClass::Load_Scenario(void)
    182 {
    183 	int scen_num = Scenario;
    184 	ScenarioPlayerType player = ScenPlayer;
    185 	ScenarioDirType dir = ScenDir;
    186 	ScenarioVarType var = ScenVar;
    187 	int rc;
    188 
    189 	/*
    190 	------------------------ Prompt for scenario info ------------------------
    191 	*/
    192 	rc = Pick_Scenario("Load Scenario", &scen_num, &player, &dir, &var, 1);
    193 	if (rc != 0) {
    194 		return(-1);
    195 	}
    196 
    197 	/*
    198 	----------------------------- Set parameters -----------------------------
    199 	*/
    200 	Scenario = scen_num;
    201 	ScenPlayer = player;
    202 	ScenDir = dir;
    203 	ScenVar = var;
    204 	Set_Scenario_Name(ScenarioName,scen_num,player,dir,var);
    205 
    206 	/*------------------------------------------------------------------------
    207 	Read_Scenario_Ini() must be able to set PlayerPtr to the right house:
    208 	- Reading the INI will create the house objects
    209 	- PlayerPtr must be set before any Techno objects are created
    210 	- For GDI or NOD scenarios, PlayerPtr is set by reading the INI;
    211 	  but for multiplayer, it's set via the MPlayerLocalID; so, here we have
    212 	  to set various multiplayer variables to fool the Assign_Houses() routine
    213 	  into working properly.
    214 	------------------------------------------------------------------------*/
    215 	if (ScenPlayer == SCEN_PLAYER_MPLAYER) {
    216 		MPlayerLocalID = Build_MPlayerID(2,HOUSE_GOOD);
    217 		MPlayerCount = 1;
    218 		LastHouse = HOUSE_MULTI1;
    219 	}
    220 	else if (ScenPlayer==SCEN_PLAYER_JP) {
    221 		PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4);
    222 		PlayerPtr->IsHuman = true;
    223 		Base.House = HOUSE_MULTI4;
    224 	}
    225 	else {
    226 		LastHouse = HOUSE_GOOD;
    227 	}
    228 
    229 	/*
    230 	-------------------------- Blow away everything --------------------------
    231 	*/
    232 	Clear_Scenario();
    233 
    234 	/*
    235 	------------------------------ Read the INI ------------------------------
    236 	*/
    237 	if (Read_Scenario_Ini(ScenarioName) == 0) {
    238 		CCMessageBox().Process("Unable to read scenario!");
    239 		HiddenPage.Clear();
    240 		Flag_To_Redraw(true);
    241 		Render();
    242 	} else {
    243 		Fill_In_Data();
    244 		Set_Palette(GamePalette);
    245 	}
    246 
    247 	return(0);
    248 }
    249 
    250 
    251 /***************************************************************************
    252  * MapEditClass::Save_Scenario -- saves current scenario to an INI file    *
    253  *                                                                         *
    254  * - Prompts user for scenario data (house, scenario #); sets globals      *
    255  *     PlayerPtr (for house) & Scenario (for scenario #)                   *
    256  * - Saves the INI file for this scenario                                  *
    257  *                                                                         *
    258  * INPUT:                                                                  *
    259  *      none.                                                              *
    260  *                                                                         *
    261  * OUTPUT:                                                                 *
    262  *      0 = OK, -1 = error/cancel                                          *
    263  *                                                                         *
    264  * WARNINGS:                                                               *
    265  *      none.                                                              *
    266  *                                                                         *
    267  * HISTORY:                                                                *
    268  *   10/21/1994 BR : Created.                                              *
    269  *=========================================================================*/
    270 int MapEditClass::Save_Scenario(void)
    271 {
    272 	int scen_num = Scenario;
    273 	ScenarioPlayerType player = ScenPlayer;
    274 	ScenarioDirType dir = ScenDir;
    275 	ScenarioVarType var = ScenVar;
    276 	int rc;
    277 	FILE *fp;
    278 	char fname[13];
    279 
    280 	/*
    281 	------------------------ Prompt for scenario info ------------------------
    282 	*/
    283 	rc = Pick_Scenario("Save Scenario", &scen_num, &player, &dir, &var, 0);
    284 	if (rc != 0) {
    285 		return(-1);
    286 	}
    287 
    288 	/*
    289 	------------------- Warning if scenario already exists -------------------
    290 	*/
    291 	Set_Scenario_Name(fname, scen_num, player, dir, var);
    292 	fp = fopen(fname,"rb");
    293 	if (fp) {
    294 		fclose(fp);
    295 		rc = CCMessageBox().Process("File exists. Replace?", TXT_YES, TXT_NO);
    296 		HiddenPage.Clear();
    297 		Flag_To_Redraw(true);
    298 		Render();
    299 		if (rc==1)
    300 			return(-1);
    301 	}
    302 
    303 	/*
    304 	----------------------------- Set parameters -----------------------------
    305 	*/
    306 	Scenario = scen_num;
    307 	ScenPlayer = player;
    308 	ScenDir = dir;
    309 	ScenVar = var;
    310 	Set_Scenario_Name(ScenarioName,scen_num,player,dir,var);
    311 
    312 	/*------------------------------------------------------------------------
    313 	Player may have changed from GDI to NOD, so change playerptr accordingly
    314 	------------------------------------------------------------------------*/
    315 	if (ScenPlayer == SCEN_PLAYER_GDI || ScenPlayer==SCEN_PLAYER_NOD) {
    316 		if (ScenPlayer==SCEN_PLAYER_GDI) {
    317 			PlayerPtr = HouseClass::As_Pointer(HOUSE_GOOD);
    318 			PlayerPtr->IsHuman = true;
    319 			Base.House = HOUSE_BAD;
    320 		} else {
    321 			if (ScenPlayer == SCEN_PLAYER_NOD) {
    322 				PlayerPtr = HouseClass::As_Pointer(HOUSE_BAD);
    323 				PlayerPtr->IsHuman = true;
    324 				Base.House = HOUSE_GOOD;
    325 			} else {
    326 				PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4);
    327 				PlayerPtr->IsHuman = true;
    328 				Base.House = HOUSE_MULTI4;
    329 			}
    330 		}
    331 		LastHouse = HOUSE_GOOD;
    332 	}
    333 
    334 	/*
    335 	----------------------------- Write the INI ------------------------------
    336 	*/
    337 	Write_Scenario_Ini(ScenarioName);
    338 
    339 	return(0);
    340 }
    341 
    342 
    343 /***************************************************************************
    344  * MapEditClass::Pick_Scenario -- dialog for choosing scenario             *
    345  *                                                                         *
    346  * Prompts user for:                                                       *
    347  *   - House (GDI, NOD)                                                    *
    348  *   - Scenario #                                                          *
    349  *                                                                         *
    350  *           ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                          *
    351  *           ³            Caption               ³                          *
    352  *           ³                                  ³                          *
    353  *           ³         Scenario ___             ³                          *
    354  *           ³          Version ___             ³                          *
    355  *           ³                                  ³                          *
    356  *           ³         [East]  [West]           ³                          *
    357  *           ³                                  ³                          *
    358  *           ³         [    GDI     ]           ³                          *
    359  *           ³         [    NOD     ]           ³                          *
    360  *           ³         [Multi-Player]           ³                          *
    361  *           ³                                  ³                          *
    362  *           ³         [OK]  [Cancel]           ³                          *
    363  *           ³                                  ³                          *
    364  *           ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                          *
    365  *                                                                         *
    366  * INPUT:                                                                  *
    367  *      caption      string to use as a title                              *
    368  *      scen_nump   output: ptr to scenario #                              *
    369  *      playerp      output: ptr to player type                            *
    370  *      dirp         output: ptr to direction                              *
    371  *      varp         output: ptr to variation                              *
    372  *      multi         1 = allow to change single/multiplayer; 0 = not      *
    373  *                                                                         *
    374  * OUTPUT:                                                                 *
    375  *      0 = OK, -1 = cancel                                                *
    376  *                                                                         *
    377  * WARNINGS:                                                               *
    378  *      none.                                                              *
    379  *                                                                         *
    380  * HISTORY:                                                                *
    381  *   10/21/1994 BR : Created.                                              *
    382  *=========================================================================*/
    383 int MapEditClass::Pick_Scenario(char const * caption, int *scen_nump,
    384 	ScenarioPlayerType *playerp, ScenarioDirType *dirp, ScenarioVarType *varp,
    385 	int multi)
    386 {
    387 	/*........................................................................
    388 	Dialog & button dimensions
    389 	........................................................................*/
    390 	enum {
    391 		D_DIALOG_W = 400,											// dialog width
    392 		D_DIALOG_H = 328,											// dialog height
    393 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),				// centered x-coord
    394 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),				// centered y-coord
    395 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),		// coord of x-center
    396 
    397 		D_TXT8_H = 22,												// ht of 8-pt text
    398 		D_MARGIN = 14,												// margin width/height
    399 
    400 		D_SCEN_W = 90,												// Scenario # width
    401 		D_SCEN_H = 18,												// Scenario # height
    402 		D_SCEN_X = D_DIALOG_CX + 5,							// Scenario # x
    403 		D_SCEN_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN,	// Scenario # y
    404 
    405 		D_VARA_W = 26,												// Version A width
    406 		D_VARA_H = 18,												// Version A height
    407 		D_VARA_X = D_DIALOG_CX - (D_VARA_W * 5) / 2,		// Version A x
    408 		D_VARA_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN,		// Version A y
    409 
    410 		D_VARB_W = 26,												// Version B width
    411 		D_VARB_H = 18,												// Version B height
    412 		D_VARB_X = D_VARA_X + D_VARA_W,						// Version B x
    413 		D_VARB_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN,		// Version B y
    414 
    415 		D_VARC_W = 26,												// Version C width
    416 		D_VARC_H = 18,												// Version C height
    417 		D_VARC_X = D_VARB_X + D_VARB_W,						// Version C x
    418 		D_VARC_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN,		// Version C y
    419 
    420 		D_VARD_W = 26,												// Version D width
    421 		D_VARD_H = 18,												// Version D height
    422 		D_VARD_X = D_VARC_X + D_VARC_W,						// Version D x
    423 		D_VARD_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN,		// Version D y
    424 
    425 		D_VARLOSE_W = 26,											// Version Lose width
    426 		D_VARLOSE_H = 18,											// Version Lose height
    427 		D_VARLOSE_X = D_VARD_X + D_VARD_W,					// Version Lose x
    428 		D_VARLOSE_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN,	// Version Lose y
    429 
    430 		D_EAST_W = 100,												// EAST width
    431 		D_EAST_H = 18,												// EAST height
    432 		D_EAST_X = D_DIALOG_CX - D_EAST_W - 5,				// EAST x
    433 		D_EAST_Y = D_VARLOSE_Y + D_VARLOSE_H + D_MARGIN,// EAST y
    434 
    435 		D_WEST_W = 100,												// WEST width
    436 		D_WEST_H = 18,												// WEST height
    437 		D_WEST_X = D_DIALOG_CX + 5,							// WEST x
    438 		D_WEST_Y = D_VARLOSE_Y + D_VARLOSE_H + D_MARGIN,// EAST y
    439 
    440 		D_GDI_W = 140,												// GDI width
    441 		D_GDI_H = 18,												// GDI height
    442 		D_GDI_X = D_DIALOG_CX - (D_GDI_W / 2),				// GDI x
    443 		D_GDI_Y = D_EAST_Y + D_EAST_H + D_MARGIN,			// GDI y
    444 
    445 		D_NOD_W = 140,												// NOD width
    446 		D_NOD_H = 18,												// NOD height
    447 		D_NOD_X = D_DIALOG_CX - (D_NOD_W / 2),				// NOD x
    448 		D_NOD_Y = D_GDI_Y + D_GDI_H,							// NOD y
    449 
    450 		D_NEU_W = 140,												// Neutral width
    451 		D_NEU_H = 18,												// Neutral height
    452 		D_NEU_X = D_DIALOG_CX - (D_NOD_W / 2),				// Neutral x
    453 		D_NEU_Y = D_NOD_Y + D_NOD_H,							// Neutral y
    454 
    455 		D_MPLAYER_W = 140,											// Multi-Player width
    456 		D_MPLAYER_H = 18,											// Multi-Player height
    457 		D_MPLAYER_X = D_DIALOG_CX - (D_MPLAYER_W / 2),	// Multi-Player x
    458 		D_MPLAYER_Y = D_NEU_Y + D_NEU_H,						// Multi-Player y
    459 
    460 		D_OK_W = 90,												// OK width
    461 		D_OK_H = 18,													// OK height
    462 		D_OK_X = D_DIALOG_CX - D_OK_W - 5,					// OK x
    463 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN,	// OK y
    464 
    465 		D_CANCEL_W = 90,											// Cancel width
    466 		D_CANCEL_H = 18,											// Cancel height
    467 		D_CANCEL_X = D_DIALOG_CX + 5,							// Cancel x
    468 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, // Cancel y
    469 
    470 	};
    471 	/*........................................................................
    472 	Button enumerations
    473 	........................................................................*/
    474 	enum {
    475 		BUTTON_GDI=100,
    476 		BUTTON_NOD,
    477 		BUTTON_NEUTRAL,
    478 		BUTTON_MPLAYER,
    479 		BUTTON_EAST,
    480 		BUTTON_WEST,
    481 		BUTTON_OK,
    482 		BUTTON_CANCEL,
    483 		BUTTON_SCENARIO,
    484 		BUTTON_VAR_A,
    485 		BUTTON_VAR_B,
    486 		BUTTON_VAR_C,
    487 		BUTTON_VAR_D,
    488 		BUTTON_VAR_L,
    489 	};
    490 	/*........................................................................
    491 	Redraw values: in order from "top" to "bottom" layer of the dialog
    492 	........................................................................*/
    493 	typedef enum {
    494 		REDRAW_NONE = 0,
    495 		REDRAW_BUTTONS,
    496 		REDRAW_BACKGROUND,
    497 		REDRAW_ALL = REDRAW_BACKGROUND
    498 	} RedrawType;
    499 	/*........................................................................
    500 	Dialog variables
    501 	........................................................................*/
    502 	RedrawType display;							// requested redraw level
    503 	bool process;									// loop while true
    504 	KeyNumType input;
    505 	bool cancel = false;							// true = user cancels
    506 	/*........................................................................
    507 	Other Variables
    508 	........................................................................*/
    509 	char scen_buf[10]={0};						// buffer for editing scenario #
    510 	/*........................................................................
    511 	Buttons
    512 	........................................................................*/
    513 	ControlClass *commands = NULL;		// the button list
    514 
    515 	EditClass editbtn (BUTTON_SCENARIO,
    516 		scen_buf, 5,
    517 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    518 		D_SCEN_X, D_SCEN_Y, D_SCEN_W, D_SCEN_H, EditClass::NUMERIC);
    519 
    520 	TextButtonClass varabtn (BUTTON_VAR_A, "A",
    521 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    522 		D_VARA_X, D_VARA_Y, D_VARA_W, D_VARA_H);
    523 
    524 	TextButtonClass varbbtn (BUTTON_VAR_B, "B",
    525 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    526 		D_VARB_X, D_VARB_Y, D_VARB_W, D_VARB_H);
    527 
    528 	TextButtonClass varcbtn (BUTTON_VAR_C, "C",
    529 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    530 		D_VARC_X, D_VARC_Y, D_VARC_W, D_VARC_H);
    531 
    532 	TextButtonClass vardbtn (BUTTON_VAR_D, "D",
    533 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    534 		D_VARD_X, D_VARD_Y, D_VARD_W, D_VARD_H);
    535 
    536 	TextButtonClass varlbtn (BUTTON_VAR_L, "L",
    537 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    538 		D_VARLOSE_X, D_VARLOSE_Y, D_VARLOSE_W, D_VARLOSE_H);
    539 
    540 	TextButtonClass gdibtn (BUTTON_GDI, "GDI",
    541 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    542 		D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H);
    543 
    544 	TextButtonClass nodbtn (BUTTON_NOD, "NOD",
    545 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    546 		D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H);
    547 
    548 	TextButtonClass playermbtn (BUTTON_MPLAYER, "Multi Player",
    549 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    550 		D_MPLAYER_X, D_MPLAYER_Y, D_MPLAYER_W, D_MPLAYER_H);
    551 
    552 	TextButtonClass eastbtn (BUTTON_EAST, "East",
    553 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    554 		D_EAST_X, D_EAST_Y, D_EAST_W, D_EAST_H);
    555 
    556 	TextButtonClass westbtn (BUTTON_WEST, "West",
    557 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    558 		D_WEST_X, D_WEST_Y, D_WEST_W, D_WEST_H);
    559 
    560 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
    561 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    562 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
    563 
    564 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
    565 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    566 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
    567 
    568 	/*
    569 	------------------------------- Initialize -------------------------------
    570 	*/
    571 	Set_Logic_Page(SeenBuff);
    572 
    573 	sprintf(scen_buf,"%d",(*scen_nump));		// init edit buffer
    574 	editbtn.Set_Text(scen_buf,5);
    575 
    576 	varabtn.Turn_Off();
    577 	varbbtn.Turn_Off();
    578 	varcbtn.Turn_Off();
    579 	vardbtn.Turn_Off();
    580 	varlbtn.Turn_Off();
    581 	switch (*varp) {
    582 		case SCEN_VAR_A:
    583 			varabtn.Turn_On();
    584 			break;
    585 
    586 		case SCEN_VAR_B:
    587 			varbbtn.Turn_On();
    588 			break;
    589 
    590 		case SCEN_VAR_C:
    591 			varcbtn.Turn_On();
    592 			break;
    593 
    594 		case SCEN_VAR_D:
    595 			vardbtn.Turn_On();
    596 			break;
    597 
    598 		case SCEN_VAR_LOSE:
    599 			varlbtn.Turn_On();
    600 			break;
    601 	}
    602 
    603 	/*
    604 	......................... Create the button list .........................
    605 	*/
    606 	commands = &editbtn;
    607 	varabtn.Add_Tail(*commands);
    608 	varbbtn.Add_Tail(*commands);
    609 	varcbtn.Add_Tail(*commands);
    610 	vardbtn.Add_Tail(*commands);
    611 	varlbtn.Add_Tail(*commands);
    612 	if (multi) {
    613 		gdibtn.Add_Tail(*commands);
    614 		nodbtn.Add_Tail(*commands);
    615 		playermbtn.Add_Tail(*commands);
    616 	} else {
    617 		if ((*playerp) == SCEN_PLAYER_MPLAYER) {
    618 			playermbtn.Add_Tail(*commands);
    619 		} else {
    620 			gdibtn.Add_Tail(*commands);
    621 			nodbtn.Add_Tail(*commands);
    622 		}
    623 	}
    624 	eastbtn.Add_Tail(*commands);
    625 	westbtn.Add_Tail(*commands);
    626 	okbtn.Add_Tail(*commands);
    627 	cancelbtn.Add_Tail(*commands);
    628 	/*
    629 	......................... Init the button states .........................
    630 	*/
    631 	if ((*playerp) == SCEN_PLAYER_GDI) {
    632 		gdibtn.Turn_On();
    633 		nodbtn.Turn_Off();
    634 		playermbtn.Turn_Off();
    635 	} else {
    636 		if ((*playerp) == SCEN_PLAYER_NOD) {
    637 			gdibtn.Turn_Off();
    638 			nodbtn.Turn_On();
    639 			playermbtn.Turn_Off();
    640 		} else {
    641 			gdibtn.Turn_Off();
    642 			nodbtn.Turn_Off();
    643 			playermbtn.Turn_On();
    644 		}
    645 	}
    646 
    647 	if ((*dirp)==SCEN_DIR_EAST) {
    648 		eastbtn.Turn_On();
    649 		westbtn.Turn_Off();
    650 	} else {
    651 		eastbtn.Turn_Off();
    652 		westbtn.Turn_On();
    653 	}
    654 
    655 	/*
    656 	-------------------------- Main Processing Loop --------------------------
    657 	*/
    658 	display = REDRAW_ALL;
    659 	process = true;
    660 	while (process) {
    661 		/*
    662 		** If we have just received input focus again after running in the background then
    663 		** we need to redraw.
    664 		*/
    665 		if (AllSurfaces.SurfacesRestored){
    666 			AllSurfaces.SurfacesRestored=FALSE;
    667 			display=REDRAW_ALL;
    668 		}
    669 
    670 		/*
    671 		........................ Invoke game callback .........................
    672 		*/
    673 		Call_Back();
    674 
    675 		/*
    676 		...................... Refresh display if needed ......................
    677 		*/
    678 		if (display) {
    679 
    680 			/*
    681 			...................... Display the dialog box ......................
    682 			*/
    683 			Hide_Mouse();
    684 			if (display >= REDRAW_BACKGROUND) {
    685 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
    686 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
    687 
    688 				/*
    689 				....................... Draw the captions .......................
    690 				*/
    691 				Fancy_Text_Print(caption, D_DIALOG_CX, D_DIALOG_Y + D_MARGIN,
    692 					CC_GREEN, TBLACK,
    693 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
    694 
    695 				Fancy_Text_Print("Scenario", D_DIALOG_CX - 5,
    696 					D_SCEN_Y, CC_GREEN, TBLACK,
    697 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
    698 			}
    699 
    700 			/*
    701 			........................ Redraw the buttons ........................
    702 			*/
    703 			if (display >= REDRAW_BUTTONS) {
    704 				commands->Draw_All();
    705 			}
    706 			Show_Mouse();
    707 			display = REDRAW_NONE;
    708 		}
    709 
    710 		/*
    711 		........................... Get user input ............................
    712 		*/
    713 		input = commands->Input();
    714 
    715 		/*
    716 		............................ Process input ............................
    717 		*/
    718 		switch (input) {
    719 			case (BUTTON_VAR_A | KN_BUTTON):
    720 				(*varp) = SCEN_VAR_A;
    721 				varabtn.Turn_On();
    722 				varbbtn.Turn_Off();
    723 				varcbtn.Turn_Off();
    724 				vardbtn.Turn_Off();
    725 				varlbtn.Turn_Off();
    726 				break;
    727 
    728 			case (BUTTON_VAR_B | KN_BUTTON):
    729 				(*varp) = SCEN_VAR_B;
    730 				varabtn.Turn_Off();
    731 				varbbtn.Turn_On();
    732 				varcbtn.Turn_Off();
    733 				vardbtn.Turn_Off();
    734 				varlbtn.Turn_Off();
    735 				break;
    736 
    737 			case (BUTTON_VAR_C | KN_BUTTON):
    738 				(*varp) = SCEN_VAR_C;
    739 				varabtn.Turn_Off();
    740 				varbbtn.Turn_Off();
    741 				varcbtn.Turn_On();
    742 				vardbtn.Turn_Off();
    743 				varlbtn.Turn_Off();
    744 				break;
    745 
    746 			case (BUTTON_VAR_D | KN_BUTTON):
    747 				(*varp) = SCEN_VAR_D;
    748 				varabtn.Turn_Off();
    749 				varbbtn.Turn_Off();
    750 				varcbtn.Turn_Off();
    751 				vardbtn.Turn_On();
    752 				varlbtn.Turn_Off();
    753 				break;
    754 
    755 			case (BUTTON_VAR_L | KN_BUTTON):
    756 				(*varp) = SCEN_VAR_LOSE;
    757 				varabtn.Turn_Off();
    758 				varbbtn.Turn_Off();
    759 				varcbtn.Turn_Off();
    760 				vardbtn.Turn_Off();
    761 				varlbtn.Turn_On();
    762 				break;
    763 
    764 			case (BUTTON_EAST | KN_BUTTON):
    765 				(*dirp) = SCEN_DIR_EAST;
    766 				eastbtn.Turn_On();
    767 				westbtn.Turn_Off();
    768 				break;
    769 
    770 			case (BUTTON_WEST | KN_BUTTON):
    771 				(*dirp) = SCEN_DIR_WEST;
    772 				eastbtn.Turn_Off();
    773 				westbtn.Turn_On();
    774 				break;
    775 
    776 			case (BUTTON_GDI | KN_BUTTON):
    777 				(*playerp) = SCEN_PLAYER_GDI;
    778 				gdibtn.Turn_On();
    779 				nodbtn.Turn_Off();
    780 				playermbtn.Turn_Off();
    781 				break;
    782 
    783 			case (BUTTON_NOD | KN_BUTTON):
    784 				(*playerp) = SCEN_PLAYER_NOD;
    785 				gdibtn.Turn_Off();
    786 				nodbtn.Turn_On();
    787 				playermbtn.Turn_Off();
    788 				break;
    789 
    790 			case (BUTTON_MPLAYER | KN_BUTTON):
    791 				(*playerp) = SCEN_PLAYER_MPLAYER;
    792 				gdibtn.Turn_Off();
    793 				nodbtn.Turn_Off();
    794 				playermbtn.Turn_On();
    795 				break;
    796 
    797 			case (KN_RETURN):
    798 			case (BUTTON_OK | KN_BUTTON):
    799 				cancel = false;
    800 				process = false;
    801 				break;
    802 
    803 			case (KN_ESC):
    804 			case (BUTTON_CANCEL | KN_BUTTON):
    805 				cancel = true;
    806 				process = false;
    807 				break;
    808 
    809 			case (BUTTON_SCENARIO | KN_BUTTON):
    810 				break;
    811 
    812 			default:
    813 				break;
    814 		}
    815 	}
    816 
    817 	/*
    818 	--------------------------- Redraw the display ---------------------------
    819 	*/
    820 	HiddenPage.Clear();
    821 	Flag_To_Redraw(true);
    822 	Render();
    823 
    824 	/*
    825 	------------------------- If cancel, just return -------------------------
    826 	*/
    827 	if (cancel)
    828 		return(-1);
    829 
    830 	/*
    831 	------------------------ Save selections & return ------------------------
    832 	*/
    833 	(*scen_nump) = atoi(scen_buf);
    834 
    835 	return(0);
    836 }
    837 
    838 
    839 /***************************************************************************
    840  * MapEditClass::Size_Map -- lets user set size & location of map          *
    841  *                                                                         *
    842  * Lets the user select a side of the map and expand/shrink it to the      *
    843  * desired size, or move the whole map around the available map area.      *
    844  *                                                                         *
    845  * The entire available map area is displayed, but the map is limited such *
    846  * that there's always one blank cell around the map; this lets objects    *
    847  * properly exit the screen, since they have a blank undisplayed cell to   *
    848  * exit onto.                                                              *
    849  *                                                                         *
    850  *   ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿               *
    851  *   ³                                                     ³               *
    852  *   ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿   Clear Terrain            ³               *
    853  *   ³  ³                     ³   Water                    ³               *
    854  *   ³  ³                     ³   Tiberium                 ³               *
    855  *   ³  ³                     ³   Rock/Wall/Road           ³               *
    856  *   ³  ³     (Map Area)      ³   GDI Unit                 ³               *
    857  *   ³  ³                     ³   NOD Unit                 ³               *
    858  *   ³  ³                     ³   Neutral Unit             ³               *
    859  *   ³  ³                     ³   Terrain Object           ³               *
    860  *   ³  ³                     ³   Starting Cell            ³               *
    861  *   ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                            ³               *
    862  *   ³                                                     ³               *
    863  *   ³      X            Y            Width      Height    ³               *
    864  *   ³      ##           ##            ##          ##      ³               *
    865  *   ³                                                     ³               *
    866  *   ³                                                     ³               *
    867  *   ³               [OK]            [Cancel]              ³               *
    868  *   ³                                                     ³               *
    869  *   ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ               *
    870  *                                                                         *
    871  * INPUT:                                                                  *
    872  *      x,y,w,h:      initial size parameters (-1 = center the thing)      *
    873  *                                                                         *
    874  * OUTPUT:                                                                 *
    875  *      0 = OK, -1 = cancel                                                *
    876  *                                                                         *
    877  * WARNINGS:                                                               *
    878  *      none.                                                              *
    879  *                                                                         *
    880  * HISTORY:                                                                *
    881  *   10/21/1994 BR : Created.                                              *
    882  *=========================================================================*/
    883 int MapEditClass::Size_Map(int x, int y, int w, int h)
    884 {
    885 	/*........................................................................
    886 	Dialog & button dimensions
    887 	........................................................................*/
    888 	enum {
    889 		D_DIALOG_W = 480,											// dialog width
    890 		D_DIALOG_H = 280,											// dialog height
    891 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),				// centered x-coord
    892 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),				// centered y-coord
    893 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),		// coord of x-center
    894 
    895 		D_TXT8_H = 22,												// ht of 8-pt text
    896 		D_MARGIN = 14,												// margin width/height
    897 
    898 		D_BORD_X1 = D_DIALOG_X + (D_DIALOG_W / 2 - MAP_CELL_W) / 2,
    899 		D_BORD_Y1 = D_DIALOG_Y + 10,
    900 		D_BORD_X2 = D_BORD_X1 + MAP_CELL_W + 1,
    901 		D_BORD_Y2 = D_BORD_Y1 + MAP_CELL_H + 1,
    902 
    903 		D_OK_W = 90,												// OK width
    904 		D_OK_H = 18,												// OK height
    905 		D_OK_X = D_DIALOG_CX - D_OK_W - 5,					// OK x
    906 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN,	// OK y
    907 
    908 		D_CANCEL_W = 90,											// Cancel width
    909 		D_CANCEL_H = 18,											// Cancel height
    910 		D_CANCEL_X = D_DIALOG_CX + 5,							// Cancel x
    911 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN, // Cancel y
    912 
    913 	};
    914 	/*........................................................................
    915 	Button enumerations:
    916 	........................................................................*/
    917 	enum {
    918 		BUTTON_OK=100,
    919 		BUTTON_CANCEL,
    920 	};
    921 	/*........................................................................
    922 	Redraw values: in order from "top" to "bottom" layer of the dialog
    923 	........................................................................*/
    924 	typedef enum {
    925 		REDRAW_NONE = 0,
    926 		REDRAW_MAP,				// includes map interior & coord values
    927 		REDRAW_BACKGROUND,	// includes box, map bord, key, coord labels, btns
    928 		REDRAW_ALL = REDRAW_BACKGROUND
    929 	} RedrawType;
    930 	/*........................................................................
    931 	Dialog variables:
    932 	........................................................................*/
    933 	bool process;									// Loop while true
    934 	RedrawType display;							// requested redraw level
    935 	bool cancel = false;							// true = user cancels
    936 	KeyNumType input;								// user input
    937 	int grabbed = 0;								// 1=TLeft,2=TRight,3=BRight,4=BLeft
    938 	int map_x1;										// map coords x1, pixel coords
    939 	int map_x2;										// map coords x2, pixel coords
    940 	int map_y1;										// map coords y1, pixel coords
    941 	int map_y2;										// map coords y2, pixel coords
    942 	int delta1, delta2;							// mouse-click proximity
    943 	int mx,my;										// last-saved mouse coords
    944 	char txt[40];
    945 	int txt_x,txt_y;								// for displaying text
    946 	unsigned index;								// for drawing map symbology
    947 	CELL cell;										// for drawing map symbology
    948 	int color;										// for drawing map symbology
    949 	ObjectClass * occupier;						// cell's occupier
    950 	/*........................................................................
    951 	Buttons
    952 	........................................................................*/
    953 	ControlClass *commands = NULL;
    954 
    955 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
    956 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    957 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
    958 
    959 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
    960 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    961 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
    962 
    963 	/*
    964 	------------------------------- Initialize -------------------------------
    965 	*/
    966 	Set_Logic_Page(SeenBuff);
    967 
    968 	/*........................................................................
    969 	Set up the actual map area relative to the map's border coords
    970 	........................................................................*/
    971 	if (x==-1) {
    972 		map_x1 = D_BORD_X1 + (MAP_CELL_W - w) / 2 + 1;
    973 	} else {
    974 		map_x1 = D_BORD_X1 + x + 1;
    975 	}
    976 
    977 	if (y==-1) {
    978 		map_y1 = D_BORD_Y1 + (MAP_CELL_H - h) / 2 + 1;
    979 	} else {
    980 		map_y1 = D_BORD_Y1 + y + 1;
    981 	}
    982 
    983 	map_x2 = map_x1 + w - 1;
    984 	map_y2 = map_y1 + h - 1;
    985 
    986 	/*
    987 	------------------------- Build the button list --------------------------
    988 	*/
    989 	commands = &okbtn;
    990 	cancelbtn.Add_Tail(*commands);
    991 
    992 	/*------------------------------------------------------------------------
    993 	Main processing loop
    994 	------------------------------------------------------------------------*/
    995 	display = REDRAW_ALL;
    996 	process = true;
    997 	while (process) {
    998 
    999 		/*
   1000 		** If we have just received input focus again after running in the background then
   1001 		** we need to redraw.
   1002 		*/
   1003 		if (AllSurfaces.SurfacesRestored){
   1004 			AllSurfaces.SurfacesRestored=FALSE;
   1005 			display=REDRAW_ALL;
   1006 		}
   1007 
   1008 		/*
   1009 		------------------------ Invoke game callback -------------------------
   1010 		*/
   1011 		Call_Back();
   1012 
   1013 		/*
   1014 		---------------------- Refresh display if needed ----------------------
   1015 		*/
   1016 		if (display) {
   1017 			Hide_Mouse();
   1018 			/*------------------------------------------------------------------
   1019 			Redraw the background, map border, key, and coord labels
   1020 			------------------------------------------------------------------*/
   1021 			if (display >= REDRAW_BACKGROUND) {
   1022 				/*
   1023 				.......................... Background ...........................
   1024 				*/
   1025 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   1026 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   1027 
   1028 				/*
   1029 				..................... Draw the map border .......................
   1030 				*/
   1031 				LogicPage->Lock();
   1032 				LogicPage->Draw_Rect(D_BORD_X1, D_BORD_Y1, D_BORD_X2, D_BORD_Y2, CC_GREEN_SHADOW);
   1033 				for (index = D_BORD_X1; index < D_BORD_X2;
   1034 					index += (320/ICON_PIXEL_W)) {
   1035 					LogicPage->Put_Pixel(index, D_BORD_Y1-1, CC_GREEN_SHADOW);
   1036 					LogicPage->Put_Pixel(index, D_BORD_Y2+1, CC_GREEN_SHADOW);
   1037 				}
   1038 				for (index = D_BORD_Y1; index < D_BORD_Y2-8;
   1039 					index += (200/ICON_PIXEL_H)) {
   1040 					LogicPage->Put_Pixel(D_BORD_X1-1, index, CC_GREEN_SHADOW);
   1041 					LogicPage->Put_Pixel(D_BORD_X2+1, index, CC_GREEN_SHADOW);
   1042 				}
   1043 
   1044 				/*...............................................................
   1045 				Draw the map "key"
   1046 				...............................................................*/
   1047 				txt_x = D_DIALOG_CX;
   1048 				txt_y = D_DIALOG_Y + 8;
   1049 				Fancy_Text_Print("Clear Terrain", txt_x, txt_y, LTGREY, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1050 				txt_y += 16;
   1051 				Fancy_Text_Print("Water", txt_x, txt_y, BLUE, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1052 				txt_y += 16;
   1053 				Fancy_Text_Print("Tiberium", txt_x, txt_y, GREY, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1054 				txt_y += 16;
   1055 				Fancy_Text_Print("Rock/Wall/Road", txt_x, txt_y, BROWN, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1056 				txt_y += 16;
   1057 				Fancy_Text_Print("GDI Unit", txt_x, txt_y, YELLOW, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1058 				txt_y += 16;
   1059 				Fancy_Text_Print("Nod Unit", txt_x, txt_y, RED, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1060 				txt_y += 16;
   1061 				Fancy_Text_Print("Neutral Unit", txt_x, txt_y, PURPLE, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1062 				txt_y += 16;
   1063 				Fancy_Text_Print("Terrain Object", txt_x, txt_y, DKGREEN, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1064 				txt_y += 16;
   1065 				Fancy_Text_Print("Starting Cell", txt_x, txt_y, WHITE, TBLACK, TPF_DROPSHADOW | TPF_6POINT);
   1066 				/*
   1067 				.................. Draw the coordinate labels ...................
   1068 				*/
   1069 				txt_x = D_DIALOG_X + D_DIALOG_W / 8;
   1070 				txt_y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 33;
   1071 				Fancy_Text_Print("X", txt_x, txt_y, CC_GREEN, TBLACK,
   1072 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1073 
   1074 				txt_x += (D_DIALOG_W - 20) / 4;
   1075 				Fancy_Text_Print("Y", txt_x, txt_y, CC_GREEN, TBLACK,
   1076 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1077 
   1078 				txt_x += (D_DIALOG_W - 20) / 4;
   1079 				Fancy_Text_Print("Width", txt_x, txt_y, CC_GREEN, TBLACK,
   1080 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1081 
   1082 				txt_x += (D_DIALOG_W - 20) / 4;
   1083 				Fancy_Text_Print("Height", txt_x, txt_y, CC_GREEN, TBLACK,
   1084 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1085 
   1086 				LogicPage->Unlock();
   1087 
   1088 				/*
   1089 				...................... Redraw the buttons .......................
   1090 				*/
   1091 				commands->Flag_List_To_Redraw();
   1092 
   1093 			}
   1094 
   1095 			/*------------------------------------------------------------------
   1096 			Redraw the map symbology & location
   1097 			------------------------------------------------------------------*/
   1098 			if (display >= REDRAW_MAP) {
   1099 
   1100 				LogicPage->Lock();
   1101 
   1102 				/*
   1103 				.................... Erase the map interior .....................
   1104 				*/
   1105 				LogicPage->Fill_Rect(D_BORD_X1 + 1, D_BORD_Y1 + 1, D_BORD_X2 - 1, D_BORD_Y2 - 1, BLACK);
   1106 
   1107 				/*...............................................................
   1108 				Draw Land map symbols (use color according to Ground[] array).
   1109 				...............................................................*/
   1110 				for (cell=0; cell < MAP_CELL_TOTAL; cell++) {
   1111 					occupier = (*this)[cell].Cell_Occupier();
   1112 					if (occupier == NULL) {
   1113 						color = Ground[(*this)[cell].Land_Type()].Color;
   1114 						LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(cell) + 1, D_BORD_Y1 + Cell_Y(cell) + 1, color);
   1115 					}
   1116 				}
   1117 
   1118 				LogicPage->Unlock();
   1119 
   1120 				/*
   1121 				................. Draw the actual map location ..................
   1122 				*/
   1123 				LogicPage->Draw_Rect(map_x1, map_y1, map_x2, map_y2, WHITE);
   1124 				switch (grabbed) {
   1125 					case 1:
   1126 						LogicPage->Draw_Line(map_x1, map_y1, map_x1 + 5, map_y1, BLUE);
   1127 						LogicPage->Draw_Line(map_x1, map_y1, map_x1, map_y1 + 5, BLUE);
   1128 						break;
   1129 
   1130 					case 2:
   1131 						LogicPage->Draw_Line(map_x2, map_y1, map_x2 - 5, map_y1, BLUE);
   1132 						LogicPage->Draw_Line(map_x2, map_y1, map_x2, map_y1 + 5, BLUE);
   1133 						break;
   1134 
   1135 					case 3:
   1136 						LogicPage->Draw_Line(map_x2, map_y2, map_x2 - 5, map_y2, BLUE);
   1137 						LogicPage->Draw_Line(map_x2, map_y2, map_x2, map_y2 - 5, BLUE);
   1138 						break;
   1139 
   1140 					case 4:
   1141 						LogicPage->Draw_Line(map_x1, map_y2, map_x1 + 5, map_y2, BLUE);
   1142 						LogicPage->Draw_Line(map_x1, map_y2, map_x1, map_y2 - 5, BLUE);
   1143 						break;
   1144 
   1145 					case 5:
   1146 						LogicPage->Draw_Rect(map_x1, map_y1, map_x2, map_y2, BLUE);
   1147 						break;
   1148 
   1149 					default:
   1150 						break;
   1151 				}
   1152 
   1153 				/*...............................................................
   1154 				Draw Unit map symbols (Use the radar map color according to
   1155 				that specified in the house type class object.
   1156 				DKGREEN = terrain object
   1157 				...............................................................*/
   1158 				for (cell=0; cell < MAP_CELL_TOTAL; cell++) {
   1159 					occupier = (*this)[cell].Cell_Occupier();
   1160 					if (occupier) {
   1161 						color = DKGREEN;
   1162 						if (occupier && occupier->Owner() != HOUSE_NONE) {
   1163 							color = HouseClass::As_Pointer(occupier->Owner())->Class->Color;
   1164 						}
   1165 						LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(cell) + 1, D_BORD_Y1 + Cell_Y(cell) + 1, color);
   1166 					}
   1167 				}
   1168 
   1169 				/*
   1170 				...................... Draw Home location .......................
   1171 				*/
   1172 				LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(Waypoint[WAYPT_HOME]) + 1, D_BORD_Y1 + Cell_Y(Waypoint[WAYPT_HOME]) + 1, WHITE);
   1173 
   1174 				/*
   1175 				..................... Erase old coordinates .....................
   1176 				*/
   1177 				LogicPage->Fill_Rect( D_DIALOG_X + 7,
   1178 					D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 22,
   1179 					D_DIALOG_X + D_DIALOG_W - 7,
   1180 					D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 22 + 10, BLACK);
   1181 
   1182 				/*
   1183 				..................... Draw the coordinates ......................
   1184 				*/
   1185 				txt_x = D_DIALOG_X + D_DIALOG_W / 8;
   1186 				txt_y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - 10 - 22;
   1187 				sprintf(txt,"%d",map_x1 - D_BORD_X1 - 1);
   1188 				Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK,
   1189 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1190 
   1191 				txt_x += (D_DIALOG_W - 20) / 4;
   1192 				sprintf(txt,"%d",map_y1 - D_BORD_Y1 - 1);
   1193 				Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK,
   1194 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1195 
   1196 				txt_x += (D_DIALOG_W - 20) / 4;
   1197 				sprintf(txt,"%d",map_x2 - map_x1 + 1);
   1198 				Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK,
   1199 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1200 
   1201 				txt_x += (D_DIALOG_W - 20) / 4;
   1202 				sprintf(txt,"%d",map_y2 - map_y1 + 1);
   1203 				Fancy_Text_Print(txt, txt_x, txt_y, CC_GREEN, TBLACK,
   1204 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1205 			}
   1206 
   1207 			Show_Mouse();
   1208 			display = REDRAW_NONE;
   1209 		}
   1210 
   1211 		/*
   1212 		------------------------- Process user input --------------------------
   1213 		*/
   1214 		input = commands->Input();
   1215 		/*.....................................................................
   1216 		Normal button processing: This is done when the mouse button is NOT
   1217 		being held down ('grabbed' is 0).
   1218 		.....................................................................*/
   1219 		if (grabbed == 0) {
   1220 			switch (input) {
   1221 				case (KN_RETURN):
   1222 				case (BUTTON_OK | KN_BUTTON):
   1223 					cancel = false;
   1224 					process = false;
   1225 					break;
   1226 
   1227 				case (KN_ESC):
   1228 				case (BUTTON_CANCEL | KN_BUTTON):
   1229 					cancel = true;
   1230 					process = false;
   1231 					break;
   1232 
   1233 				case KN_LMOUSE:
   1234 					/*
   1235 					....................... Grab top left ........................
   1236 					*/
   1237 					delta1 =  abs(_Kbd->MouseQX - map_x1);
   1238 					delta2 =  abs(_Kbd->MouseQY - map_y1);
   1239 					if (delta1 < 3 && delta2 < 3) {
   1240 						grabbed = 1;
   1241 						mx = _Kbd->MouseQX;
   1242 						my = _Kbd->MouseQY;
   1243 						display = REDRAW_MAP;
   1244 						break;
   1245 					}
   1246 					/*
   1247 					...................... Grab top right ........................
   1248 					*/
   1249 					delta1 =  abs(_Kbd->MouseQX - map_x2);
   1250 					delta2 =  abs(_Kbd->MouseQY - map_y1);
   1251 					if (delta1 < 3 && delta2 < 3) {
   1252 						grabbed = 2;
   1253 						mx = _Kbd->MouseQX;
   1254 						my = _Kbd->MouseQY;
   1255 						display = REDRAW_MAP;
   1256 						break;
   1257 					}
   1258 					/*
   1259 					..................... Grab bottom right ......................
   1260 					*/
   1261 					delta1 =  abs(_Kbd->MouseQX - map_x2);
   1262 					delta2 =  abs(_Kbd->MouseQY - map_y2);
   1263 					if (delta1 < 3 && delta2 < 3) {
   1264 						grabbed = 3;
   1265 						mx = _Kbd->MouseQX;
   1266 						my = _Kbd->MouseQY;
   1267 						display = REDRAW_MAP;
   1268 						break;
   1269 					}
   1270 					/*
   1271 					..................... Grab bottom left .......................
   1272 					*/
   1273 					delta1 =  abs(_Kbd->MouseQX - map_x1);
   1274 					delta2 =  abs(_Kbd->MouseQY - map_y2);
   1275 					if (delta1 < 3 && delta2 < 3) {
   1276 						grabbed = 4;
   1277 						mx = _Kbd->MouseQX;
   1278 						my = _Kbd->MouseQY;
   1279 						display = REDRAW_MAP;
   1280 						break;
   1281 					}
   1282 					/*
   1283 					..................... Grab the whole map .....................
   1284 					*/
   1285 					delta1 = abs(_Kbd->MouseQX - ((map_x1 + map_x2) / 2));
   1286 					delta2 = abs(_Kbd->MouseQY - ((map_y1 + map_y2) / 2));
   1287 					if (delta1 < (map_x2 - map_x1) / 4 &&
   1288 						delta2 < (map_y2 - map_y1) / 4) {
   1289 						grabbed = 5;
   1290 						mx = _Kbd->MouseQX;
   1291 						my = _Kbd->MouseQY;
   1292 						display = REDRAW_MAP;
   1293 					}
   1294 					break;
   1295 
   1296 				default:
   1297 					break;
   1298 			}
   1299 		} else {
   1300 			/*.....................................................................
   1301 			Mouse motion processing: This is done while the left mouse button IS
   1302 			being held down.
   1303 			- First, check for the button release; if detected, un-grab
   1304 			- Then, handle mouse motion. WWLIB doesn't pass through a KN_MOUSE_MOVE
   1305 			  value while the button is being held down, so this case must be
   1306 			  trapped as a default.
   1307 			.....................................................................*/
   1308 			switch (input) {
   1309 				case ((int)KN_LMOUSE | (int)KN_RLSE_BIT):
   1310 					grabbed = 0;
   1311 					display = REDRAW_MAP;
   1312 					break;
   1313 
   1314 				default:
   1315 					delta1 = Get_Mouse_X() - mx;
   1316 					delta2 = Get_Mouse_Y() - my;
   1317 					if (delta1==0 && delta2==0) {
   1318 						break;
   1319 					}
   1320 
   1321 					/*
   1322 					....................... Move top left ........................
   1323 					*/
   1324 					if (grabbed==1) {
   1325 						map_x1 += delta1;
   1326 						if (map_x1 > map_x2 - 2) {
   1327 							map_x1 = map_x2 - 2;
   1328 						} else {
   1329 							if (map_x1 < D_BORD_X1 + 2) {
   1330 								map_x1 = D_BORD_X1 + 2;
   1331 							}
   1332 						}
   1333 
   1334 						map_y1 += delta2;
   1335 						if (map_y1 > map_y2 - 2) {
   1336 							map_y1 = map_y2 - 2;
   1337 						} else {
   1338 							if (map_y1 < D_BORD_Y1 + 2) {
   1339 								map_y1 = D_BORD_Y1 + 2;
   1340 							}
   1341 						}
   1342 						display = REDRAW_MAP;
   1343 						mx = Get_Mouse_X();
   1344 						my = Get_Mouse_Y();
   1345 					}
   1346 
   1347 					/*
   1348 					....................... Move top right .......................
   1349 					*/
   1350 					if (grabbed==2) {
   1351 						map_x2 += delta1;
   1352 						if (map_x2 < map_x1 + 2) {
   1353 							map_x2 = map_x1 + 2;
   1354 						} else {
   1355 							if (map_x2 > D_BORD_X2 - 2) {
   1356 								map_x2 = D_BORD_X2 - 2;
   1357 							}
   1358 						}
   1359 
   1360 						map_y1 += delta2;
   1361 						if (map_y1 > map_y2 - 2) {
   1362 							map_y1 = map_y2 - 2;
   1363 						} else {
   1364 							if (map_y1 < D_BORD_Y1 + 2) {
   1365 								map_y1 = D_BORD_Y1 + 2;
   1366 							}
   1367 						}
   1368 						display = REDRAW_MAP;
   1369 						mx = Get_Mouse_X();
   1370 						my = Get_Mouse_Y();
   1371 					}
   1372 
   1373 					/*
   1374 					..................... Move bottom right ......................
   1375 					*/
   1376 					if (grabbed==3) {
   1377 						map_x2 += delta1;
   1378 						if (map_x2 < map_x1 + 2) {
   1379 							map_x2 = map_x1 + 2;
   1380 						} else {
   1381 							if (map_x2 > D_BORD_X2 - 2) {
   1382 								map_x2 = D_BORD_X2 - 2;
   1383 							}
   1384 						}
   1385 
   1386 						map_y2 += delta2;
   1387 						if (map_y2 < map_y1 + 2) {
   1388 							map_y2 = map_y1 + 2;
   1389 						} else {
   1390 							if (map_y2 > D_BORD_Y2 - 2) {
   1391 								map_y2 = D_BORD_Y2 - 2;
   1392 							}
   1393 						}
   1394 						display = REDRAW_MAP;
   1395 						mx = Get_Mouse_X();
   1396 						my = Get_Mouse_Y();
   1397 					}
   1398 
   1399 					/*
   1400 					...................... Move bottom left ......................
   1401 					*/
   1402 					if (grabbed==4) {
   1403 						map_x1 += delta1;
   1404 						if (map_x1 > map_x2 - 2) {
   1405 							map_x1 = map_x2 - 2;
   1406 						} else {
   1407 							if (map_x1 < D_BORD_X1 + 2) {
   1408 								map_x1 = D_BORD_X1 + 2;
   1409 							}
   1410 						}
   1411 
   1412 						map_y2 += delta2;
   1413 						if (map_y2 < map_y1 + 2) {
   1414 							map_y2 = map_y1 + 2;
   1415 						} else {
   1416 							if (map_y2 > D_BORD_Y2 - 2) {
   1417 								map_y2 = D_BORD_Y2 - 2;
   1418 							}
   1419 						}
   1420 						display = REDRAW_MAP;
   1421 						mx = Get_Mouse_X();
   1422 						my = Get_Mouse_Y();
   1423 					}
   1424 
   1425 					/*
   1426 					....................... Move whole map .......................
   1427 					*/
   1428 					if (grabbed==5) {
   1429 						if (map_x1 + delta1 > D_BORD_X1 + 1 && map_x2 + delta1 < D_BORD_X2 - 1) {
   1430 							map_x1 += delta1;
   1431 							map_x2 += delta1;
   1432 						}
   1433 
   1434 						if (map_y1 + delta2 > D_BORD_Y1 + 1 && map_y2 + delta2 < D_BORD_Y2 - 1) {
   1435 							map_y1 += delta2;
   1436 							map_y2 += delta2;
   1437 						}
   1438 						display = REDRAW_MAP;
   1439 						mx = Get_Mouse_X();
   1440 						my = Get_Mouse_Y();
   1441 					}
   1442 					break;
   1443 			}
   1444 		}
   1445 	}
   1446 
   1447 	/*
   1448 	--------------------------- Redraw the display ---------------------------
   1449 	*/
   1450 	HiddenPage.Clear();
   1451 	Flag_To_Redraw(true);
   1452 	Render();
   1453 
   1454 	/*
   1455 	------------------------- If cancel, just return -------------------------
   1456 	*/
   1457 	if (cancel) {
   1458 		return(-1);
   1459 	}
   1460 
   1461 	/*
   1462 	---------------------------- Save selections -----------------------------
   1463 	*/
   1464 	MapCellX = map_x1 - D_BORD_X1 - 1;
   1465 	MapCellY = map_y1 - D_BORD_Y1 - 1;
   1466 	MapCellWidth = map_x2 - map_x1 + 1;
   1467 	MapCellHeight = map_y2 - map_y1 + 1;
   1468 
   1469 	/*
   1470 	--------------------- Clip Home Cell to new map size ---------------------
   1471 	*/
   1472 	if (Cell_X(Waypoint[WAYPT_HOME]) < MapCellX) {
   1473 		Waypoint[WAYPT_HOME] = XY_Cell(MapCellX, Cell_Y(Waypoint[WAYPT_HOME]));
   1474 	}
   1475 
   1476 	if (Cell_X(Waypoint[WAYPT_HOME]) > MapCellX + MapCellWidth - 1) {
   1477 		Waypoint[WAYPT_HOME] = XY_Cell(MapCellX + MapCellWidth - 1, Cell_Y(Waypoint[WAYPT_HOME]));
   1478 	}
   1479 
   1480 	if (Cell_Y(Waypoint[WAYPT_HOME]) < MapCellY) {
   1481 		Waypoint[WAYPT_HOME] = XY_Cell(Cell_X(Waypoint[WAYPT_HOME]), MapCellY);
   1482 	}
   1483 
   1484 	if (Cell_Y(Waypoint[WAYPT_HOME]) > MapCellY + MapCellHeight - 1) {
   1485 		Waypoint[WAYPT_HOME] = XY_Cell(Cell_X(Waypoint[WAYPT_HOME]), MapCellY + MapCellHeight - 1);
   1486 	}
   1487 
   1488 	return(0);
   1489 }
   1490 
   1491 
   1492 /***************************************************************************
   1493  * MapEditClass::Scenario_Dialog -- scenario global parameters dialog      *
   1494  *                                                                         *
   1495  * Lets the user edit the Theater, starting credits for houses, and the    *
   1496  * Edge for HOUSE_GOOD & HOUSE_BAD.                                        *
   1497  *                                                                         *
   1498  * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ *
   1499  * ³       Theater                                Credits / 1000         ³ *
   1500  * ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                                                  ³ *
   1501  * ³  ³ Temperate     ³                          GDI: _____              ³ *
   1502  * ³  ³ Desert        ³                          NOD: _____              ³ *
   1503  * ³  ³ Jungle        ³                      Neutral: _____              ³ *
   1504  * ³  ³               ³                                                  ³ *
   1505  * ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                                                  ³ *
   1506  * ³   Build Level:___                                                   ³ *
   1507  * ³                                                                     ³ *
   1508  * ³                         Reinforcements                              ³ *
   1509  * ³                                                                     ³ *
   1510  * ³                    GDI                NOD                           ³ *
   1511  * ³                                                                     ³ *
   1512  * ³                                                                   ³ *
   1513  * ³                  <-   ->            <-   ->                         ³ *
   1514  * ³                                                                   ³ *
   1515  * ³                                                                     ³ *
   1516  * ³                                                                     ³ *
   1517  * ³                       [OK]     [Cancel]                             ³ *
   1518  * ³                                                                     ³ *
   1519  * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ *
   1520  *                                                                         *
   1521  * INPUT:                                                                  *
   1522  *      none.                                                              *
   1523  *                                                                         *
   1524  * OUTPUT:                                                                 *
   1525  *      0 = OK, -1 = cancel                                                *
   1526  *                                                                         *
   1527  * WARNINGS:                                                               *
   1528  *      Uses HIDBUFF.                                                      *
   1529  *                                                                         *
   1530  * HISTORY:                                                                *
   1531  *   11/14/1994 BR : Created.                                              *
   1532  *=========================================================================*/
   1533 int MapEditClass::Scenario_Dialog(void)
   1534 {
   1535 	/*........................................................................
   1536 	Dialog & button dimensions
   1537 	........................................................................*/
   1538 	enum {
   1539 		D_DIALOG_W = 544,
   1540 		D_DIALOG_H = 320,
   1541 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
   1542 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
   1543 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
   1544 
   1545 		D_TXT8_H = 22,
   1546 		D_MARGIN = 14,
   1547 
   1548 		D_THEATER_W = 200,
   1549 		D_THEATER_H = 68,
   1550 		D_THEATER_X = D_DIALOG_X + D_MARGIN,
   1551 		D_THEATER_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
   1552 
   1553 		D_LEVEL_W = 80,
   1554 		D_LEVEL_H = 18,
   1555 		D_LEVEL_X = D_THEATER_X + D_THEATER_W - D_LEVEL_W,
   1556 		D_LEVEL_Y = D_THEATER_Y + D_THEATER_H + D_MARGIN,
   1557 
   1558 		D_GDICRED_W = 120,
   1559 		D_GDICRED_H = 18,
   1560 		D_GDICRED_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_GDICRED_W,
   1561 		D_GDICRED_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
   1562 
   1563 		D_NODCRED_W = 120,
   1564 		D_NODCRED_H = 18,
   1565 		D_NODCRED_X = D_GDICRED_X,
   1566 		D_NODCRED_Y = D_GDICRED_Y + D_GDICRED_H,
   1567 
   1568 		D_NEUTCRED_W = 120,
   1569 		D_NEUTCRED_H = 18,
   1570 		D_NEUTCRED_X = D_GDICRED_X,
   1571 		D_NEUTCRED_Y = D_NODCRED_Y + D_NODCRED_H,
   1572 
   1573 		D_GDIN_W = 26,
   1574 		D_GDIN_H = 18,
   1575 		D_GDIN_X = D_DIALOG_CX - 5 - D_GDIN_W * 2,
   1576 		D_GDIN_Y = D_LEVEL_Y + D_LEVEL_H + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H,
   1577 
   1578 		D_GDIS_W = 26,
   1579 		D_GDIS_H = 18,
   1580 		D_GDIS_X = D_GDIN_X,
   1581 		D_GDIS_Y = D_GDIN_Y + D_GDIN_H * 2,
   1582 
   1583 		D_GDIW_W = 26,
   1584 		D_GDIW_H = 18,
   1585 		D_GDIW_X = D_DIALOG_CX - 5 - D_GDIN_W * 3,
   1586 		D_GDIW_Y = D_GDIN_Y + D_GDIN_H,
   1587 
   1588 		D_GDIE_W = 26,
   1589 		D_GDIE_H = 18,
   1590 		D_GDIE_X = D_DIALOG_CX - 5 - D_GDIN_W,
   1591 		D_GDIE_Y = D_GDIN_Y + D_GDIN_H,
   1592 
   1593 		D_NODN_W = 26,
   1594 		D_NODN_H = 18,
   1595 		D_NODN_X = D_DIALOG_CX + 5 + D_NODN_W,
   1596 		D_NODN_Y = D_LEVEL_Y + D_LEVEL_H + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H,
   1597 
   1598 		D_NODS_W = 26,
   1599 		D_NODS_H = 18,
   1600 		D_NODS_X = D_NODN_X,
   1601 		D_NODS_Y = D_NODN_Y + D_NODN_H * 2,
   1602 
   1603 		D_NODW_W = 26,
   1604 		D_NODW_H = 18,
   1605 		D_NODW_X = D_DIALOG_CX + 5,
   1606 		D_NODW_Y = D_NODN_Y + D_NODN_H,
   1607 
   1608 		D_NODE_W = 26,
   1609 		D_NODE_H = 18,
   1610 		D_NODE_X = D_DIALOG_CX + 5 + D_NODN_W * 2,
   1611 		D_NODE_Y = D_NODN_Y + D_NODN_H,
   1612 
   1613 		D_OK_W = 90,
   1614 		D_OK_H = 18,
   1615 		D_OK_X = D_DIALOG_CX - D_OK_W - 5,
   1616 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN,
   1617 
   1618 		D_CANCEL_W = 90,
   1619 		D_CANCEL_H = 18,
   1620 		D_CANCEL_X = D_DIALOG_CX + 5,
   1621 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN,
   1622 	};
   1623 	/*........................................................................
   1624 	Button enumerations:
   1625 	........................................................................*/
   1626 	enum {
   1627 		LIST_THEATER=100,
   1628 		TEDIT_LEVEL,
   1629 		TEDIT_GDICRED,
   1630 		TEDIT_NODCRED,
   1631 		TEDIT_NEUTCRED,
   1632 		BUTTON_GDI_N,
   1633 		BUTTON_GDI_E,
   1634 		BUTTON_GDI_S,
   1635 		BUTTON_GDI_W,
   1636 		BUTTON_NOD_N,
   1637 		BUTTON_NOD_E,
   1638 		BUTTON_NOD_S,
   1639 		BUTTON_NOD_W,
   1640 		BUTTON_OK,
   1641 		BUTTON_CANCEL,
   1642 	};
   1643 	/*........................................................................
   1644 	Redraw values: in order from "top" to "bottom" layer of the dialog
   1645 	........................................................................*/
   1646 	typedef enum {
   1647 		REDRAW_NONE = 0,
   1648 		REDRAW_BUTTONS,		// includes map interior & coord values
   1649 		REDRAW_BACKGROUND,	// includes box, map bord, key, coord labels, btns
   1650 		REDRAW_ALL = REDRAW_BACKGROUND
   1651 	} RedrawType;
   1652 	/*........................................................................
   1653 	Dialog variables:
   1654 	........................................................................*/
   1655 	KeyNumType input;								// input from user
   1656 	bool process;									// loop while true
   1657 	RedrawType display;							// true = re-draw everything
   1658 	bool cancel = false;							// true = user cancels
   1659 	/*
   1660 	.......................... Scenario parameters ...........................
   1661 	*/
   1662 	TheaterType theater;				// DisplayClass::Theater
   1663 	TheaterType orig_theater;		// original theater
   1664 	long gdi_credits;					// HouseClass::As_Pointer(HouseType)->Credits
   1665 	long nod_credits;					// HouseClass::As_Pointer(HouseType)->Credits
   1666 	long neut_credits;				// HouseClass::As_Pointer(HouseType)->Credits
   1667 	SourceType gdi_edge;				// HouseClass::As_Pointer(HouseType)->Edge
   1668 	SourceType nod_edge;				// HouseClass::As_Pointer(HouseType)->Edge
   1669 	char level_buf[10] = {0};
   1670 	char gdicred_buf[10] = {0};
   1671 	char nodcred_buf[10] = {0};
   1672 	char neutcred_buf[10] = {0};
   1673 	/*
   1674 	....................... Theater-changing variables .......................
   1675 	*/
   1676 	unsigned char theater_mask;	// template/terrain mask
   1677 	TerrainClass * terrain;	// cell's terrain pointer
   1678 	CELL i;								// loop counter
   1679 	/*........................................................................
   1680 	Buttons
   1681 	........................................................................*/
   1682 	ControlClass *commands = NULL;				// the button list
   1683 	ListClass theaterbtn (LIST_THEATER,
   1684 		D_THEATER_X, D_THEATER_Y, D_THEATER_W, D_THEATER_H,
   1685 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1686 		Hires_Retrieve("BTN-UP.SHP"),
   1687 		Hires_Retrieve("BTN-DN.SHP"));
   1688 
   1689 	EditClass leveledt (TEDIT_GDICRED, level_buf, 4,
   1690 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1691 		D_LEVEL_X, D_LEVEL_Y, D_LEVEL_W, D_LEVEL_H, EditClass::NUMERIC);
   1692 
   1693 	EditClass gdicred (TEDIT_GDICRED, gdicred_buf, 8,
   1694 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1695 		D_GDICRED_X, D_GDICRED_Y, D_GDICRED_W, D_GDICRED_H, EditClass::NUMERIC);
   1696 
   1697 	EditClass nodcred (TEDIT_NODCRED, nodcred_buf, 8,
   1698 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1699 		D_NODCRED_X, D_NODCRED_Y, D_NODCRED_W, D_NODCRED_H, EditClass::NUMERIC);
   1700 
   1701 	EditClass neutcred (TEDIT_NEUTCRED, neutcred_buf, 8,
   1702 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1703 		D_NEUTCRED_X, D_NEUTCRED_Y, D_NEUTCRED_W, D_NEUTCRED_H, EditClass::NUMERIC);
   1704 
   1705 	TextButtonClass gdinbtn (BUTTON_GDI_N, TXT_UP,
   1706 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1707 		D_GDIN_X, D_GDIN_Y, D_GDIN_W, D_GDIN_H);
   1708 
   1709 	TextButtonClass gdiebtn (BUTTON_GDI_E, TXT_RIGHT,
   1710 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1711 		D_GDIE_X, D_GDIE_Y, D_GDIE_W, D_GDIE_H);
   1712 
   1713 	TextButtonClass gdisbtn (BUTTON_GDI_S, TXT_DOWN,
   1714 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1715 		D_GDIS_X, D_GDIS_Y, D_GDIS_W, D_GDIS_H);
   1716 
   1717 	TextButtonClass gdiwbtn (BUTTON_GDI_W, TXT_LEFT,
   1718 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1719 		D_GDIW_X, D_GDIW_Y, D_GDIW_W, D_GDIW_H);
   1720 
   1721 	TextButtonClass nodnbtn (BUTTON_NOD_N, TXT_UP,
   1722 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1723 		D_NODN_X, D_NODN_Y, D_NODN_W, D_NODN_H);
   1724 
   1725 	TextButtonClass nodebtn (BUTTON_NOD_E, TXT_RIGHT,
   1726 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1727 		D_NODE_X, D_NODE_Y, D_NODE_W, D_NODE_H);
   1728 
   1729 	TextButtonClass nodsbtn (BUTTON_NOD_S, TXT_DOWN,
   1730 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1731 		D_NODS_X, D_NODS_Y, D_NODS_W, D_NODS_H);
   1732 
   1733 	TextButtonClass nodwbtn (BUTTON_NOD_W, TXT_LEFT,
   1734 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1735 		D_NODW_X, D_NODW_Y, D_NODW_W, D_NODW_H);
   1736 
   1737 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
   1738 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1739 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
   1740 
   1741 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
   1742 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1743 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
   1744 
   1745 
   1746 	/*
   1747 	------------------------------- Initialize -------------------------------
   1748 	*/
   1749 	Set_Logic_Page(SeenBuff);
   1750 
   1751 	/*
   1752 	.......................... Fill in theater items .........................
   1753 	*/
   1754 	theaterbtn.Add_Item("Desert");
   1755 	theaterbtn.Add_Item("Jungle");
   1756 	theaterbtn.Add_Item("Temperate");
   1757 	theaterbtn.Add_Item("Winter");
   1758 
   1759 	/*
   1760 	............................ Init parameters .............................
   1761 	*/
   1762 	orig_theater = theater = Theater;
   1763 	if (ScenPlayer != SCEN_PLAYER_MPLAYER) {
   1764 		gdi_credits = HouseClass::As_Pointer(HOUSE_GOOD)->Credits / 1000L;
   1765 		nod_credits = HouseClass::As_Pointer(HOUSE_BAD)->Credits / 1000L;
   1766 		neut_credits = HouseClass::As_Pointer(HOUSE_NEUTRAL)->Credits / 1000L;
   1767 		gdi_edge = HouseClass::As_Pointer(HOUSE_GOOD)->Edge;
   1768 		nod_edge = HouseClass::As_Pointer(HOUSE_BAD)->Edge;
   1769 	} else {
   1770 		gdi_credits = 0;
   1771 		nod_credits = 0;
   1772 		neut_credits = 0;
   1773 		gdi_edge = SOURCE_NONE;
   1774 		nod_edge = SOURCE_NONE;
   1775 	}
   1776 
   1777 	/*
   1778 	............................ Create the list .............................
   1779 	*/
   1780 	commands = &theaterbtn;
   1781 	leveledt.Add_Tail(*commands);
   1782 	gdicred.Add_Tail(*commands);
   1783 	nodcred.Add_Tail(*commands);
   1784 	neutcred.Add_Tail(*commands);
   1785 	gdinbtn.Add_Tail(*commands);
   1786 	gdiebtn.Add_Tail(*commands);
   1787 	gdisbtn.Add_Tail(*commands);
   1788 	gdiwbtn.Add_Tail(*commands);
   1789 	nodnbtn.Add_Tail(*commands);
   1790 	nodebtn.Add_Tail(*commands);
   1791 	nodsbtn.Add_Tail(*commands);
   1792 	nodwbtn.Add_Tail(*commands);
   1793 	okbtn.Add_Tail(*commands);
   1794 	cancelbtn.Add_Tail(*commands);
   1795 
   1796 	/*
   1797 	...................... Init GDI Edge button states .......................
   1798 	*/
   1799 	if (gdi_edge==SOURCE_NORTH) gdinbtn.Turn_On();
   1800 	if (gdi_edge==SOURCE_EAST) gdiebtn.Turn_On();
   1801 	if (gdi_edge==SOURCE_SOUTH) gdisbtn.Turn_On();
   1802 	if (gdi_edge==SOURCE_WEST) gdiwbtn.Turn_On();
   1803 
   1804 	/*
   1805 	...................... Init NOD Edge button states .......................
   1806 	*/
   1807 	if (nod_edge==SOURCE_NORTH) nodnbtn.Turn_On();
   1808 	if (nod_edge==SOURCE_EAST) nodebtn.Turn_On();
   1809 	if (nod_edge==SOURCE_SOUTH) nodsbtn.Turn_On();
   1810 	if (nod_edge==SOURCE_WEST) nodwbtn.Turn_On();
   1811 
   1812 	/*
   1813 	.......................... Init credits buffers ..........................
   1814 	*/
   1815 	sprintf(level_buf,"%ld",BuildLevel);
   1816 	leveledt.Set_Text(level_buf,4);
   1817 
   1818 	sprintf(gdicred_buf,"%ld",gdi_credits);
   1819 	gdicred.Set_Text(gdicred_buf,8);
   1820 
   1821 	sprintf(nodcred_buf,"%ld",nod_credits);
   1822 	nodcred.Set_Text(nodcred_buf,8);
   1823 
   1824 	sprintf(neutcred_buf,"%ld",neut_credits);
   1825 	neutcred.Set_Text(neutcred_buf,8);
   1826 
   1827 	theaterbtn.Set_Selected_Index(orig_theater - THEATER_NONE - 1);
   1828 
   1829 	/*
   1830 	-------------------------- Main Processing Loop --------------------------
   1831 	*/
   1832 	display = REDRAW_ALL;
   1833 	process = true;
   1834 	while (process) {
   1835 
   1836 		/*
   1837 		** If we have just received input focus again after running in the background then
   1838 		** we need to redraw.
   1839 		*/
   1840 		if (AllSurfaces.SurfacesRestored){
   1841 			AllSurfaces.SurfacesRestored=FALSE;
   1842 			display=REDRAW_ALL;
   1843 		}
   1844 
   1845 		/*
   1846 		........................ Invoke game callback .........................
   1847 		*/
   1848 		Call_Back();
   1849 
   1850 		/*
   1851 		...................... Refresh display if needed ......................
   1852 		*/
   1853 		if (display) {
   1854 			Hide_Mouse();
   1855 			if (display >= REDRAW_BACKGROUND) {
   1856 
   1857 				/*
   1858 				..................... Draw the background .......................
   1859 				*/
   1860 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   1861 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   1862 
   1863 				/*
   1864 				....................... Draw the labels .........................
   1865 				*/
   1866 				Fancy_Text_Print("Theater", D_THEATER_X + D_THEATER_W / 2,
   1867 					D_THEATER_Y - D_TXT8_H, CC_GREEN, TBLACK,
   1868 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1869 
   1870 				Fancy_Text_Print("Build Level", D_LEVEL_X, D_LEVEL_Y,
   1871 					CC_GREEN, TBLACK,
   1872 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1873 
   1874 				Fancy_Text_Print("Credits/1000", D_GDICRED_X + D_GDICRED_W / 2,
   1875 					D_GDICRED_Y - D_TXT8_H, CC_GREEN, TBLACK,
   1876 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1877 
   1878 				Fancy_Text_Print ("GDI", D_GDICRED_X - 5, D_GDICRED_Y,
   1879 					CC_GREEN, TBLACK,
   1880 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1881 
   1882 				Fancy_Text_Print ("NOD", D_NODCRED_X - 5, D_NODCRED_Y,
   1883 					CC_GREEN, TBLACK,
   1884 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1885 
   1886 				Fancy_Text_Print ("Neutral", D_NEUTCRED_X - 5, D_NEUTCRED_Y,
   1887 					CC_GREEN, TBLACK,
   1888 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1889 
   1890 				Fancy_Text_Print ("Reinforcements", D_DIALOG_CX,
   1891 					D_LEVEL_Y + D_LEVEL_H + D_MARGIN,
   1892 					CC_GREEN, TBLACK,
   1893 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1894 
   1895 				Fancy_Text_Print ("GDI", D_GDIN_X + D_GDIN_W / 2,
   1896 					D_GDIN_Y - D_TXT8_H,
   1897 					CC_GREEN, TBLACK,
   1898 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1899 
   1900 				Fancy_Text_Print ("NOD", D_NODN_X + D_NODN_W / 2,
   1901 					D_NODN_Y - D_TXT8_H,
   1902 					CC_GREEN, TBLACK,
   1903 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1904 
   1905 			}
   1906 			Show_Mouse();
   1907 			display = REDRAW_NONE;
   1908 		}
   1909 
   1910 		/*
   1911 		........................... Get user input ............................
   1912 		*/
   1913 		input = commands->Input();
   1914 
   1915 		/*
   1916 		............................ Process input ............................
   1917 		*/
   1918 		switch (input) {
   1919 
   1920 			/*..................................................................
   1921 			Credit edit boxes: no need for any action
   1922 			..................................................................*/
   1923 			case (TEDIT_GDICRED | KN_BUTTON):
   1924 				break;
   1925 
   1926 			case (TEDIT_NODCRED | KN_BUTTON):
   1927 				break;
   1928 
   1929 			case (TEDIT_NEUTCRED | KN_BUTTON):
   1930 				break;
   1931 
   1932 			/*..................................................................
   1933 			GDI Edge buttons: turn this one on, others off, save the edge value
   1934 			..................................................................*/
   1935 			case (BUTTON_GDI_N | KN_BUTTON):
   1936 				gdi_edge = SOURCE_NORTH;
   1937 				gdinbtn.Turn_On();
   1938 				gdiebtn.Turn_Off();
   1939 				gdisbtn.Turn_Off();
   1940 				gdiwbtn.Turn_Off();
   1941 				break;
   1942 
   1943 			case (BUTTON_GDI_E | KN_BUTTON):
   1944 				gdi_edge = SOURCE_EAST;
   1945 				gdinbtn.Turn_Off();
   1946 				gdiebtn.Turn_On();
   1947 				gdisbtn.Turn_Off();
   1948 				gdiwbtn.Turn_Off();
   1949 				break;
   1950 
   1951 			case (BUTTON_GDI_S | KN_BUTTON):
   1952 				gdi_edge = SOURCE_SOUTH;
   1953 				gdinbtn.Turn_Off();
   1954 				gdiebtn.Turn_Off();
   1955 				gdisbtn.Turn_On();
   1956 				gdiwbtn.Turn_Off();
   1957 				break;
   1958 
   1959 			case (BUTTON_GDI_W | KN_BUTTON):
   1960 				gdi_edge = SOURCE_WEST;
   1961 				gdinbtn.Turn_Off();
   1962 				gdiebtn.Turn_Off();
   1963 				gdisbtn.Turn_Off();
   1964 				gdiwbtn.Turn_On();
   1965 				break;
   1966 
   1967 			/*..................................................................
   1968 			NOD Edge buttons: turn this one on, others off, save the edge value
   1969 			..................................................................*/
   1970 			case (BUTTON_NOD_N | KN_BUTTON):
   1971 				nod_edge = SOURCE_NORTH;
   1972 				nodnbtn.Turn_On();
   1973 				nodebtn.Turn_Off();
   1974 				nodsbtn.Turn_Off();
   1975 				nodwbtn.Turn_Off();
   1976 				break;
   1977 
   1978 			case (BUTTON_NOD_E | KN_BUTTON):
   1979 				nod_edge = SOURCE_EAST;
   1980 				nodnbtn.Turn_Off();
   1981 				nodebtn.Turn_On();
   1982 				nodsbtn.Turn_Off();
   1983 				nodwbtn.Turn_Off();
   1984 				break;
   1985 
   1986 			case (BUTTON_NOD_S | KN_BUTTON):
   1987 				nod_edge = SOURCE_SOUTH;
   1988 				nodnbtn.Turn_Off();
   1989 				nodebtn.Turn_Off();
   1990 				nodsbtn.Turn_On();
   1991 				nodwbtn.Turn_Off();
   1992 				break;
   1993 
   1994 			case (BUTTON_NOD_W | KN_BUTTON):
   1995 				nod_edge = SOURCE_WEST;
   1996 				nodnbtn.Turn_Off();
   1997 				nodebtn.Turn_Off();
   1998 				nodsbtn.Turn_Off();
   1999 				nodwbtn.Turn_On();
   2000 				break;
   2001 
   2002 			case (KN_RETURN):
   2003 			case (BUTTON_OK | KN_BUTTON):
   2004 				cancel = false;
   2005 				process = false;
   2006 				break;
   2007 
   2008 			case (KN_ESC):
   2009 			case (BUTTON_CANCEL | KN_BUTTON):
   2010 				cancel = true;
   2011 				process = false;
   2012 				break;
   2013 
   2014 			default:
   2015 				break;
   2016 		}
   2017 	}
   2018 
   2019 	/*
   2020 	----------------------------- Redraw the map -----------------------------
   2021 	*/
   2022 	HiddenPage.Clear();
   2023 	Flag_To_Redraw(true);
   2024 	Render();
   2025 
   2026 	/*
   2027 	------------------------- If cancel, just return -------------------------
   2028 	*/
   2029 	if (cancel) {
   2030 		return(-1);
   2031 	}
   2032 
   2033 	/*
   2034 	------------------------ Save selections & return ------------------------
   2035 	*/
   2036 	if (ScenPlayer != SCEN_PLAYER_MPLAYER) {
   2037 		/*
   2038 		.............................. Credits ................................
   2039 		*/
   2040 		gdi_credits = atol(gdicred_buf);
   2041 		nod_credits = atol(nodcred_buf);
   2042 		neut_credits = atol(neutcred_buf);
   2043 		HouseClass::As_Pointer(HOUSE_GOOD)->Credits = gdi_credits * 1000L;
   2044 		HouseClass::As_Pointer(HOUSE_BAD)->Credits = nod_credits * 1000L;
   2045 		HouseClass::As_Pointer(HOUSE_NEUTRAL)->Credits = neut_credits * 1000L;
   2046 		/*
   2047 		............................... Edges .................................
   2048 		*/
   2049 		HouseClass::As_Pointer(HOUSE_GOOD)->Edge = gdi_edge;
   2050 		HouseClass::As_Pointer(HOUSE_BAD)->Edge = nod_edge;
   2051 	}
   2052 
   2053 	/*
   2054 	........................... Sidebar build level ..........................
   2055 	*/
   2056 	BuildLevel = atoi(level_buf);
   2057 
   2058 	/*........................................................................
   2059 	Change the theater:
   2060 	- 1st set the Theater global
   2061 	- scan all cells to check their TType for compatibility with the new
   2062 	  theater; if not compatible, set TType to TEMPLATE_NONE & TIcon to 0
   2063 	- Then, re-initialize the TypeClasses for the new Theater
   2064 	........................................................................*/
   2065 	theater = (TheaterType)(THEATER_NONE + 1 + theaterbtn.Current_Index());
   2066 	if (theater != orig_theater) {
   2067 		/*
   2068 		....................... Loop through all cells ........................
   2069 		*/
   2070 		for (i =0;i<MAP_CELL_TOTAL; i++) {
   2071 			/*..................................................................
   2072 			If this cell has a template icon & that template isn't compatible
   2073 			with this theater, set the icon to NONE
   2074 			..................................................................*/
   2075 			if ((*this)[i].TType != TEMPLATE_NONE) {
   2076 				theater_mask = TemplateTypeClass::As_Reference((*this)[i].TType).Theater;
   2077 				if ( (theater_mask & (1 << theater))==0) {
   2078 					(*this)[i].TType = TEMPLATE_NONE;
   2079 					(*this)[i].TIcon = 0;
   2080 				}
   2081 			}
   2082 			/*..................................................................
   2083 			If this cell has terrain in it, and that terrain isn't compatible
   2084 			with this theater, delete the terrain object.
   2085 			..................................................................*/
   2086 			terrain = (*this)[i].Cell_Terrain();
   2087 			if (terrain) {
   2088 				theater_mask = terrain->Class->Theater;
   2089 				if ( (theater_mask & (1<<theater))==0) {
   2090 					delete terrain;
   2091 				}
   2092 			}
   2093 		}
   2094 
   2095 		/*.....................................................................
   2096 		Re-init the object Type Classes for this theater
   2097 		.....................................................................*/
   2098 		Init_Theater(theater);
   2099 		TerrainTypeClass::Init(theater);
   2100 		TemplateTypeClass::Init(theater);
   2101 		OverlayTypeClass::Init(theater);
   2102 		UnitTypeClass::Init(theater);
   2103 		InfantryTypeClass::Init(theater);
   2104 		BuildingTypeClass::Init(theater);
   2105 		BulletTypeClass::Init(theater);
   2106 		AnimTypeClass::Init(theater);
   2107 		AircraftTypeClass::Init(theater);
   2108 		SmudgeTypeClass::Init(theater);
   2109 	}
   2110 
   2111 	return(0);
   2112 }
   2113 
   2114 
   2115 /***************************************************************************
   2116  * Handle_Triggers -- processes the trigger dialogs                        *
   2117  *                                                                         *
   2118  * INPUT:                                                                  *
   2119  *      none.                                                              *
   2120  *                                                                         *
   2121  * OUTPUT:                                                                 *
   2122  *      none.                                                              *
   2123  *                                                                         *
   2124  * WARNINGS:                                                               *
   2125  *      none.                                                              *
   2126  *                                                                         *
   2127  * HISTORY:                                                                *
   2128  *   11/29/1994 BR : Created.                                              *
   2129  *=========================================================================*/
   2130 void MapEditClass::Handle_Triggers(void)
   2131 {
   2132 	int rc;
   2133 
   2134 	/*------------------------------------------------------------------------
   2135 	Trigger dialog processing loop:
   2136 	- Invoke the trigger selection dialog. If a trigger's selected, break
   2137 	  & return
   2138 	- If user wants to edit the current trigger, do so
   2139 	- If user wants to create new trigger, new a TriggerClass & edit it
   2140 	- If user wants to delete trigger, delete the current trigger
   2141 	- Keep looping until 'OK'
   2142 	------------------------------------------------------------------------*/
   2143 	while (1) {
   2144 		/*
   2145 		........................... Select trigger ............................
   2146 		*/
   2147 		rc = Select_Trigger();
   2148 
   2149 		/*
   2150 		............................. 'OK'; break .............................
   2151 		*/
   2152 		if (rc==0) break;
   2153 
   2154 		/*
   2155 		............................... 'Edit' ................................
   2156 		*/
   2157 		if (rc==1 && CurTrigger) {
   2158 			if (Edit_Trigger()==0) {
   2159 				Changed = 1;
   2160 			}
   2161 		}
   2162 
   2163 		/*
   2164 		................................ 'New' ................................
   2165 		*/
   2166 		if (rc==2) {
   2167 			/*
   2168 			..................... Create a new trigger ......................
   2169 			*/
   2170 			CurTrigger = new TriggerClass();
   2171 			if (CurTrigger) {
   2172 				/*
   2173 				................... delete it if user cancels ...................
   2174 				*/
   2175 				if (Edit_Trigger()==-1) {
   2176 					delete CurTrigger;
   2177 					CurTrigger = NULL;
   2178 				} else {
   2179 					Changed = 1;
   2180 				}
   2181 
   2182 			} else {
   2183 
   2184 				/*
   2185 				................. Unable to create; issue warning ..................
   2186 				*/
   2187 				CCMessageBox().Process("No more triggers available.");
   2188 				HiddenPage.Clear();
   2189 				Flag_To_Redraw(true);
   2190 				Render();
   2191 			}
   2192 		}
   2193 
   2194 		/*
   2195 		.............................. 'Delete' ...............................
   2196 		*/
   2197 		if (rc==3) {
   2198 			if (CurTrigger) {
   2199 				CurTrigger->Remove();
   2200 				CurTrigger = NULL;
   2201 				Changed = 1;
   2202 			}
   2203 		}
   2204 	}
   2205 
   2206 	/*------------------------------------------------------------------------
   2207 	Don't allow trigger placement if the trigger is house-specific; such
   2208 	triggers cannot be "placed".
   2209 	------------------------------------------------------------------------*/
   2210 	if (CurTrigger) {
   2211 		if (!TriggerClass::Event_Need_Object(CurTrigger->Event)) {
   2212 			CurTrigger = NULL;
   2213 		}
   2214 	}
   2215 }
   2216 
   2217 
   2218 /***************************************************************************
   2219  * MapEditClass::Select_Trigger -- lets user select a trigger              *
   2220  *                                                                         *
   2221  * CurTrigger can be NULL when this function is called.                    *
   2222  *                                                                         *
   2223  *    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿           *
   2224  *    ³                       Triggers                         ³           *
   2225  *    ³    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿    ³           *
   2226  *    ³    ³ Name     Event     Action    House   Team  ³³    ³           *
   2227  *    ³    ³ Name     Event     Action    House   Team  ÃÄ´    ³           *
   2228  *    ³    ³ Name     Event     Action    House   Team  ³ ³    ³           *
   2229  *    ³    ³ Name     Event     Action    House   Team  ³ ³    ³           *
   2230  *    ³    ³                                            ³ ³    ³           *
   2231  *    ³    ³                                            ³ ³    ³           *
   2232  *    ³    ³                                            ÃÄ´    ³           *
   2233  *    ³    ³                                            ³³    ³           *
   2234  *    ³    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ    ³           *
   2235  *    ³                                                        ³           *
   2236  *    ³      [Edit]        [New]        [Delete]      [OK]     ³           *
   2237  *    ³                                                        ³           *
   2238  *    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ           *
   2239  *                                                                         *
   2240  * INPUT:                                                                  *
   2241  *      none.                                                              *
   2242  *                                                                         *
   2243  * OUTPUT:                                                                 *
   2244  *      0 = OK, 1 = Edit, 2 = New, 3 = Delete                              *
   2245  *                                                                         *
   2246  * WARNINGS:                                                               *
   2247  *      Uses HIDBUFF.                                                      *
   2248  *                                                                         *
   2249  * HISTORY:                                                                *
   2250  *   11/29/1994 BR : Created.                                              *
   2251  *=========================================================================*/
   2252 int MapEditClass::Select_Trigger(void)
   2253 {
   2254 	/*........................................................................
   2255 	Dialog & button dimensions
   2256 	........................................................................*/
   2257 	enum {
   2258 		D_DIALOG_W = 640,
   2259 		D_DIALOG_H = 290,
   2260 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
   2261 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
   2262 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
   2263 
   2264 		D_TXT8_H = 22,
   2265 		D_MARGIN = 14,
   2266 
   2267 		D_LIST_W = 612,
   2268 		D_LIST_H = 208,
   2269 		D_LIST_X = D_DIALOG_X + D_MARGIN,
   2270 		D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
   2271 
   2272 		D_EDIT_W = 90,
   2273 		D_EDIT_H = 18,
   2274 		D_EDIT_X = D_DIALOG_X + (D_DIALOG_W / 8) - (D_EDIT_W / 2),
   2275 		D_EDIT_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_EDIT_H,
   2276 
   2277 		D_NEW_W = 90,
   2278 		D_NEW_H = 18,
   2279 		D_NEW_X = D_DIALOG_X + (D_DIALOG_W / 8) * 3 - (D_NEW_W / 2),
   2280 		D_NEW_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_NEW_H,
   2281 
   2282 		D_DELETE_W = 90,
   2283 		D_DELETE_H = 18,
   2284 		D_DELETE_X = D_DIALOG_X + (D_DIALOG_W / 8) * 5 - (D_DELETE_W / 2),
   2285 		D_DELETE_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_DELETE_H,
   2286 
   2287 		D_OK_W = 90,
   2288 		D_OK_H = 18,
   2289 		D_OK_X = D_DIALOG_X + (D_DIALOG_W / 8) * 7 - (D_OK_W / 2),
   2290 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
   2291 
   2292 	};
   2293 
   2294 	/*........................................................................
   2295 	Button enumerations:
   2296 	........................................................................*/
   2297 	enum {
   2298 		TRIGGER_LIST=100,
   2299 		BUTTON_EDIT,
   2300 		BUTTON_NEW,
   2301 		BUTTON_DELETE,
   2302 		BUTTON_OK,
   2303 	};
   2304 
   2305 	/*........................................................................
   2306 	Redraw values: in order from "top" to "bottom" layer of the dialog
   2307 	........................................................................*/
   2308 	typedef enum {
   2309 		REDRAW_NONE = 0,
   2310 		REDRAW_BUTTONS,
   2311 		REDRAW_BACKGROUND,
   2312 		REDRAW_ALL = REDRAW_BACKGROUND
   2313 	} RedrawType;
   2314 
   2315 	/*........................................................................
   2316 	Dialog variables:
   2317 	........................................................................*/
   2318 	RedrawType display;							// requested redraw level
   2319 	bool process;									// loop while true
   2320 	char *trigtext[TRIGGER_MAX + 1];			// text for defined triggers
   2321 	KeyNumType input;								// user input
   2322 	bool edit_trig = false;						// true = user wants to edit
   2323 	bool new_trig = false;						// true = user wants to new
   2324 	bool del_trig = false;						// true = user wants to new
   2325 	int i;											// loop counter
   2326 	int def_idx;									// default list index
   2327 	static int tabs[] = {70, 240, 390, 440}; 	// list box tab stops
   2328 
   2329 	/*........................................................................
   2330 	Buttons
   2331 	........................................................................*/
   2332 	ControlClass *commands = NULL;				// the button list
   2333 
   2334 	ListClass triggerlist (TRIGGER_LIST, D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H,
   2335 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2336 		Hires_Retrieve("BTN-UP.SHP"),
   2337 		Hires_Retrieve("BTN-DN.SHP"));
   2338 
   2339 	TextButtonClass editbtn (BUTTON_EDIT, "Edit", TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW,
   2340 		D_EDIT_X, D_EDIT_Y, D_EDIT_W, D_EDIT_H);
   2341 
   2342 	TextButtonClass newbtn (BUTTON_NEW, "New", TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW,
   2343 		D_NEW_X, D_NEW_Y, D_NEW_W, D_NEW_H);
   2344 
   2345 	TextButtonClass deletebtn (BUTTON_DELETE, "Delete", TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW,
   2346 		D_DELETE_X, D_DELETE_Y, D_DELETE_W, D_DELETE_H);
   2347 
   2348 	TextButtonClass okbtn (BUTTON_OK, TXT_OK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW,
   2349 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
   2350 
   2351 	/*
   2352 	------------------------------- Initialize -------------------------------
   2353 	*/
   2354 	Set_Logic_Page(SeenBuff);
   2355 
   2356 	/*
   2357 	......................... Fill in trigger names ..........................
   2358 	*/
   2359 	def_idx = 0;
   2360 	for (i = 0; i < Triggers.Count(); i++) {
   2361 		/*.....................................................................
   2362 		Generate string for this trigger
   2363 		- Name can be up to 4 characters
   2364 		- Event can be up to 15 characters
   2365 		- Action can be up to 15 characters
   2366 		- House is 3 characters
   2367 		- Team name is up to 11 characters
   2368 		.....................................................................*/
   2369 		//trigtext[i] = (char *)HidPage.Get_Graphic_Buffer()->Get_Buffer() + 60 * i;
   2370 		trigtext[i] = new char[255];
   2371 		sprintf(trigtext[i],"%s\t%s\t%s\t",
   2372 			Triggers.Ptr(i)->Get_Name(),
   2373 			TriggerClass::Name_From_Event(Triggers.Ptr(i)->Event),
   2374 			TriggerClass::Name_From_Action(Triggers.Ptr(i)->Action));
   2375 
   2376 		/*
   2377 		......................... Add on the house ID .........................
   2378 		*/
   2379 		if (TriggerClass::Event_Need_House(Triggers.Ptr(i)->Event)) {
   2380 			if (Triggers.Ptr(i)->House != HOUSE_NONE) {
   2381 				strcat(trigtext[i], HouseTypeClass::As_Reference(Triggers.Ptr(i)->House).Suffix);
   2382 			} else {
   2383 				strcat(trigtext[i], "!!!");
   2384 			}
   2385 		} else {
   2386 			strcat(trigtext[i],"   ");
   2387 		}
   2388 
   2389 		/*
   2390 		.......................... Add the team name ..........................
   2391 		*/
   2392 		strcat(trigtext[i],"\t");
   2393 		if (TriggerClass::Action_Need_Team(Triggers.Ptr(i)->Action)) {
   2394 			if (Triggers.Ptr(i)->Team) {
   2395 				strcat(trigtext[i],Triggers.Ptr(i)->Team->IniName);
   2396 			} else {
   2397 				strcat(trigtext[i], "!!!");
   2398 			}
   2399 		}
   2400 
   2401 		/*
   2402 		................. Set def_idx if this is CurTrigger ...................
   2403 		*/
   2404 		if (Triggers.Ptr(i) == CurTrigger) {
   2405 			def_idx = i;
   2406 		}
   2407 	}
   2408 
   2409 	/*
   2410 	.......................... Fill in the list box ..........................
   2411 	*/
   2412 	for (i = 0; i < Triggers.Count(); i++) {
   2413 		triggerlist.Add_Item(trigtext[i]);
   2414 	}
   2415 	triggerlist.Set_Selected_Index(def_idx);
   2416 
   2417 	/*
   2418 	....................... Set CurTrigger if it isn't .......................
   2419 	*/
   2420 	if (Triggers.Count()==0) {
   2421 		CurTrigger = NULL;
   2422 	} else {
   2423 		if (!CurTrigger) {
   2424 			CurTrigger = Triggers.Ptr(def_idx);
   2425 		}
   2426 	}
   2427 
   2428 	/*
   2429 	............................ Create the list .............................
   2430 	*/
   2431 	commands = &triggerlist;
   2432 	editbtn.Add_Tail(*commands);
   2433 	newbtn.Add_Tail(*commands);
   2434 	deletebtn.Add_Tail(*commands);
   2435 	okbtn.Add_Tail(*commands);
   2436 
   2437 	/*
   2438 	------------------------ Init tab stops for list -------------------------
   2439 	*/
   2440 	triggerlist.Set_Tabs(tabs);
   2441 
   2442 	/*
   2443 	-------------------------- Main Processing Loop --------------------------
   2444 	*/
   2445 	display = REDRAW_ALL;
   2446 	process = true;
   2447 	while (process) {
   2448 
   2449 		/*
   2450 		** If we have just received input focus again after running in the background then
   2451 		** we need to redraw.
   2452 		*/
   2453 		if (AllSurfaces.SurfacesRestored){
   2454 			AllSurfaces.SurfacesRestored=FALSE;
   2455 			display=REDRAW_ALL;
   2456 		}
   2457 
   2458 		/*
   2459 		........................ Invoke game callback .........................
   2460 		*/
   2461 		Call_Back();
   2462 
   2463 		/*
   2464 		...................... Refresh display if needed ......................
   2465 		*/
   2466 		if (display) {
   2467 
   2468 			/*
   2469 			...................... Display the dialog box ......................
   2470 			*/
   2471 			Hide_Mouse();
   2472 			if (display >= REDRAW_BACKGROUND) {
   2473 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   2474 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   2475 
   2476 				/*
   2477 				....................... Draw the captions .......................
   2478 				*/
   2479 				Fancy_Text_Print("Triggers", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN, CC_GREEN, TBLACK,
   2480 					TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
   2481 			}
   2482 
   2483 			/*
   2484 			........................ Redraw the buttons ........................
   2485 			*/
   2486 			if (display >= REDRAW_BUTTONS) {
   2487 				commands->Draw_All();
   2488 			}
   2489 			Show_Mouse();
   2490 			display = REDRAW_NONE;
   2491 		}
   2492 
   2493 		/*
   2494 		........................... Get user input ............................
   2495 		*/
   2496 		input = commands->Input();
   2497 
   2498 		/*
   2499 		............................ Process input ............................
   2500 		*/
   2501 		switch (input) {
   2502 			case (TRIGGER_LIST | KN_BUTTON):
   2503 				def_idx = triggerlist.Current_Index();
   2504 				if (def_idx < Triggers.Count()) {
   2505 					CurTrigger = Triggers.Ptr(def_idx);
   2506 				}
   2507 				break;
   2508 
   2509 			case (BUTTON_EDIT | KN_BUTTON):
   2510 				if (CurTrigger) {		// only allow if there's one selected
   2511 					process = false;
   2512 					edit_trig = true;
   2513 				}
   2514 				break;
   2515 
   2516 			case (BUTTON_NEW | KN_BUTTON):
   2517 				process = false;
   2518 				new_trig = true;
   2519 				break;
   2520 
   2521 			case (BUTTON_DELETE | KN_BUTTON):
   2522 				process = false;
   2523 				del_trig = true;
   2524 				break;
   2525 
   2526 			case (KN_RETURN):
   2527 			case (BUTTON_OK | KN_BUTTON):
   2528 				process = false;
   2529 				break;
   2530 		}
   2531 	}
   2532 
   2533 	/*
   2534 	--------------------------- Redraw the display ---------------------------
   2535 	*/
   2536 	HiddenPage.Clear();
   2537 	Flag_To_Redraw(true);
   2538 	Render();
   2539 
   2540 	for (i = 0; i < Triggers.Count(); i++) {
   2541 		delete [] trigtext[i];
   2542 	}
   2543 
   2544 	if (edit_trig) return(1);
   2545 	if (new_trig) return(2);
   2546 	if (del_trig) return(3);
   2547 	return(0);
   2548 }
   2549 
   2550 
   2551 /***************************************************************************
   2552  * MapEditClass::Edit_Trigger -- lets user edit a [new] trigger            *
   2553  *                                                                         *
   2554  * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ *
   2555  * ³                           Trigger Editor                            ³ *
   2556  * ³                                                                     ³ *
   2557  * ³             Events                              Actions             ³ *
   2558  * ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿        ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿  ³ *
   2559  * ³  ³                        ³³        ³                         ³³  ³ *
   2560  * ³  ³                        ÃÄ´        ³                         ÃÄ´  ³ *
   2561  * ³  ³                        ³ ³        ³                         ³ ³  ³ *
   2562  * ³  ³                        ³ ³        ³                         ³ ³  ³ *
   2563  * ³  ³                        ÃÄ´        ³                         ÃÄ´  ³ *
   2564  * ³  ³                        ³³        ³                         ³³  ³ *
   2565  * ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ        ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ  ³ *
   2566  * ³                                                                     ³ *
   2567  * ³           Name: _______                   [  Volatile    ]          ³ *
   2568  * ³                               [GDI]       [  Persistent  ]          ³ *
   2569  * ³ Time / Credits: _______       [NOD]       [SemiPersistent]          ³ *
   2570  * ³                                                                     ³ *
   2571  * ³          [Team] Team_Name                                           ³ *
   2572  * ³                                                                     ³ *
   2573  * ³                         [OK]        [Cancel]                        ³ *
   2574  * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ *
   2575  *                                                                         *
   2576  * INPUT:                                                                  *
   2577  *      none.                                                              *
   2578  *                                                                         *
   2579  * OUTPUT:                                                                 *
   2580  *      0 = OK, -1 = cancel                                                *
   2581  *                                                                         *
   2582  * WARNINGS:                                                               *
   2583  *      CurTrigger must NOT be NULL when this function is called.          *
   2584  *                                                                         *
   2585  * HISTORY:                                                                *
   2586  *   11/29/1994 BR : Created.                                              *
   2587  *=========================================================================*/
   2588 int MapEditClass::Edit_Trigger(void)
   2589 {
   2590 	/*........................................................................
   2591 	Dialog & button dimensions
   2592 	........................................................................*/
   2593 	enum {
   2594 		D_DIALOG_W = 528,
   2595 		D_DIALOG_H = 376,
   2596 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
   2597 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
   2598 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
   2599 
   2600 		D_TXT8_H = 22,
   2601 		D_MARGIN = 14,
   2602 
   2603 		D_EVENT_W = 240,
   2604 		D_EVENT_H = 88,
   2605 		D_EVENT_X = D_DIALOG_X + D_MARGIN,
   2606 		D_EVENT_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H,
   2607 
   2608 		D_ACTION_W = 240,
   2609 		D_ACTION_H = 88,
   2610 		D_ACTION_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_ACTION_W,
   2611 		D_ACTION_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN + D_TXT8_H,
   2612 
   2613 		D_NAME_W = 80,
   2614 		D_NAME_H = 18,
   2615 		D_NAME_X = D_EVENT_X + (D_EVENT_W / 2) - 10,
   2616 		D_NAME_Y = D_EVENT_Y + D_EVENT_H + D_MARGIN,
   2617 
   2618 		D_DATA_W = 80,
   2619 		D_DATA_H = 18,
   2620 		D_DATA_X = D_NAME_X,
   2621 		D_DATA_Y = D_NAME_Y + D_NAME_H + D_MARGIN,
   2622 
   2623 		D_TEAM_W = 80,
   2624 		D_TEAM_H = 18,
   2625 		D_TEAM_X = D_NAME_X - D_TEAM_W - 5,
   2626 		D_TEAM_Y = D_DATA_Y + D_DATA_H + D_MARGIN,
   2627 
   2628 		D_GDI_W = 90,
   2629 		D_GDI_H = 18,
   2630 		D_GDI_X = D_DIALOG_CX - (D_GDI_W / 2),
   2631 		D_GDI_Y = D_NAME_Y,
   2632 
   2633 		D_NOD_W = 90,
   2634 		D_NOD_H = 18,
   2635 		D_NOD_X = D_GDI_X,
   2636 		D_NOD_Y = D_GDI_Y + D_GDI_H,
   2637 
   2638 		D_NEU_W = 90,
   2639 		D_NEU_H = 18,
   2640 		D_NEU_X = D_NOD_X,
   2641 		D_NEU_Y = D_NOD_Y + D_NOD_H,
   2642 
   2643 		D_MULTI1_W = 44,
   2644 		D_MULTI1_H = 18,
   2645 		D_MULTI1_X = D_GDI_X,
   2646 		D_MULTI1_Y = D_GDI_Y,
   2647 
   2648 		D_MULTI2_W = 44,
   2649 		D_MULTI2_H = 18,
   2650 		D_MULTI2_X = D_GDI_X + D_MULTI1_W,
   2651 		D_MULTI2_Y = D_GDI_Y,
   2652 
   2653 		D_MULTI3_W = 44,
   2654 		D_MULTI3_H = 18,
   2655 		D_MULTI3_X = D_NOD_X,
   2656 		D_MULTI3_Y = D_NOD_Y,
   2657 
   2658 		D_MULTI4_W = 44,
   2659 		D_MULTI4_H = 18,
   2660 		D_MULTI4_X = D_NOD_X + D_MULTI1_W,
   2661 		D_MULTI4_Y = D_NOD_Y,
   2662 
   2663 		D_VOLATILE_W = 100,
   2664 		D_VOLATILE_H = 18,
   2665 		D_VOLATILE_X = D_ACTION_X + (D_ACTION_W / 2) - (D_VOLATILE_W / 2) + 10,
   2666 		D_VOLATILE_Y = D_NAME_Y,
   2667 
   2668 		D_PERSIST_W = 100,
   2669 		D_PERSIST_H = 18,
   2670 		D_PERSIST_X = D_ACTION_X + (D_ACTION_W / 2) - (D_PERSIST_W / 2) + 10,
   2671 		D_PERSIST_Y = D_VOLATILE_Y + D_VOLATILE_H,
   2672 
   2673 		D_SEMIPERSIST_W = 100,
   2674 		D_SEMIPERSIST_H = 18,
   2675 		D_SEMIPERSIST_X = D_ACTION_X + (D_ACTION_W / 2) - (D_SEMIPERSIST_W / 2) + 10,
   2676 		D_SEMIPERSIST_Y = D_PERSIST_Y + D_PERSIST_H,
   2677 
   2678 		D_OK_W = 90,
   2679 		D_OK_H = 18,
   2680 		D_OK_X = D_DIALOG_CX - 5 - D_OK_W,
   2681 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
   2682 
   2683 		D_CANCEL_W = 90,
   2684 		D_CANCEL_H = 18,
   2685 		D_CANCEL_X = D_DIALOG_CX + 5,
   2686 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_CANCEL_H,
   2687 
   2688 	};
   2689 
   2690 	/*........................................................................
   2691 	Button enumerations:
   2692 	........................................................................*/
   2693 	enum {
   2694 		EVENT_LIST=100,
   2695 		ACTION_LIST,
   2696 		NAME_EDIT,
   2697 		DATA_EDIT,
   2698 		BUTTON_TEAM,
   2699 		BUTTON_GDI,
   2700 		BUTTON_NOD,
   2701 		BUTTON_NEUTRAL,
   2702 		BUTTON_JP,			// placeholder
   2703 		BUTTON_MULTI1,
   2704 		BUTTON_MULTI2,
   2705 		BUTTON_MULTI3,
   2706 		BUTTON_MULTI4,
   2707 		BUTTON_MULTI5,
   2708 		BUTTON_MULTI6,
   2709 		BUTTON_VOLATILE,
   2710 		BUTTON_PERSIST,
   2711 		BUTTON_SEMIPERSIST,
   2712 		BUTTON_OK,
   2713 		BUTTON_CANCEL,
   2714 	};
   2715 
   2716 	/*........................................................................
   2717 	Redraw values: in order from "top" to "bottom" layer of the dialog
   2718 	........................................................................*/
   2719 	typedef enum {
   2720 		REDRAW_NONE = 0,
   2721 		REDRAW_BUTTONS,
   2722 		REDRAW_BACKGROUND,
   2723 		REDRAW_ALL = REDRAW_BACKGROUND
   2724 	} RedrawType;
   2725 
   2726 	/*........................................................................
   2727 	Dialog variables:
   2728 	........................................................................*/
   2729 	RedrawType display;								// requested redraw level
   2730 	bool process;										// loop while true
   2731 	KeyNumType input;									// user input
   2732 	bool cancel = false;								// true = user cancels
   2733 	int i;												// loop counter
   2734 	EventType event_idx;								// index for event list
   2735 	TriggerClass::ActionType action_idx;		// index for action list
   2736 	char namebuf[5];									// name of this trigger
   2737 	char databuf[10];									// for credit/time-based triggers
   2738 	HousesType house;									// house for this trigger
   2739 	const char *eventnames[EVENT_COUNT + 1];	// names of events
   2740 	const char *actionnames[TriggerClass::ACTION_COUNT + 1];	// names of actions
   2741 	TriggerClass::PersistantType persistant;									// trigger's persistence level
   2742 
   2743 	/*........................................................................
   2744 	These flags enable various controls for each EventType.
   2745 	........................................................................*/
   2746 //	static char data_enabled[EVENT_COUNT] = {0,0,0,0,0,0,0,0,0,1,1,1,1,0,0};
   2747 //	static char house_enabled[EVENT_COUNT] = {1,0,0,0,0,1,1,1,1,1,1,1,1,1,1};
   2748 //	static char team_enabled[TriggerClass::ACTION_COUNT] = {0,0,0,1,1,0,1,0,0,0,0,0,0,0};
   2749 
   2750 	/*........................................................................
   2751 	Buttons
   2752 	........................................................................*/
   2753 	ControlClass *commands = NULL;				// the button list
   2754 
   2755 	ListClass eventlist(EVENT_LIST,
   2756 		D_EVENT_X, D_EVENT_Y, D_EVENT_W, D_EVENT_H,
   2757 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2758 		Hires_Retrieve("BTN-UP.SHP"),
   2759 		Hires_Retrieve("BTN-DN.SHP"));
   2760 
   2761 	ListClass actionlist(ACTION_LIST,
   2762 		D_ACTION_X, D_ACTION_Y, D_ACTION_W, D_ACTION_H,
   2763 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2764 		Hires_Retrieve("BTN-UP.SHP"),
   2765 		Hires_Retrieve("BTN-DN.SHP"));
   2766 
   2767 	EditClass name_edt(NAME_EDIT, namebuf, 5,
   2768 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2769 		D_NAME_X, D_NAME_Y, D_NAME_W, D_NAME_H, EditClass::ALPHANUMERIC);
   2770 
   2771 	EditClass data_edt(DATA_EDIT, databuf, 8,
   2772 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2773 		D_DATA_X, D_DATA_Y, D_DATA_W, D_DATA_H, EditClass::ALPHANUMERIC);
   2774 
   2775 	TextButtonClass teambtn(BUTTON_TEAM, "Team",
   2776 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2777 		D_TEAM_X, D_TEAM_Y, D_TEAM_W, D_TEAM_H);
   2778 
   2779 	TextButtonClass gdibtn(BUTTON_GDI, "GDI",
   2780 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2781 		D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H);
   2782 
   2783 	TextButtonClass nodbtn(BUTTON_NOD, "NOD",
   2784 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2785 		D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H);
   2786 
   2787 	TextButtonClass neutralbtn(BUTTON_NEUTRAL, "Neutral",
   2788 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2789 		D_NEU_X, D_NEU_Y, D_NEU_W, D_NEU_H);
   2790 
   2791 	TextButtonClass multi1btn(BUTTON_MULTI1, "M1",
   2792 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2793 		D_MULTI1_X, D_MULTI1_Y, D_MULTI1_W, D_MULTI1_H);
   2794 
   2795 	TextButtonClass multi2btn(BUTTON_MULTI2, "M2",
   2796 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2797 		D_MULTI2_X, D_MULTI2_Y, D_MULTI2_W, D_MULTI2_H);
   2798 
   2799 	TextButtonClass multi3btn(BUTTON_MULTI3, "M3",
   2800 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2801 		D_MULTI3_X, D_MULTI3_Y, D_MULTI3_W, D_MULTI3_H);
   2802 
   2803 	TextButtonClass multi4btn(BUTTON_MULTI4, "M4",
   2804 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2805 		D_MULTI4_X, D_MULTI4_Y, D_MULTI4_W, D_MULTI4_H);
   2806 
   2807 	TextButtonClass volatilebtn(BUTTON_VOLATILE, "Volatile",
   2808 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2809 		D_VOLATILE_X, D_VOLATILE_Y, D_VOLATILE_W, D_VOLATILE_H);
   2810 
   2811 	TextButtonClass persistbtn(BUTTON_PERSIST, "Persistant",
   2812 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2813 		D_PERSIST_X, D_PERSIST_Y, D_PERSIST_W, D_PERSIST_H);
   2814 
   2815 	TextButtonClass semipersistbtn(BUTTON_SEMIPERSIST, "SemiPersistant",
   2816 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2817 		D_SEMIPERSIST_X, D_SEMIPERSIST_Y, D_SEMIPERSIST_W, D_SEMIPERSIST_H);
   2818 
   2819 	TextButtonClass okbtn(BUTTON_OK, TXT_OK,
   2820 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2821 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
   2822 
   2823 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL,
   2824 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   2825 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
   2826 
   2827 	/*
   2828 	------------------------------- Initialize -------------------------------
   2829 	*/
   2830 	Set_Logic_Page(SeenBuff);
   2831 
   2832 	/*
   2833 	....................... Set default button states ........................
   2834 	*/
   2835 	event_idx = CurTrigger->Event;				// event list
   2836 	if (event_idx == EVENT_NONE) event_idx = EVENT_FIRST;
   2837 
   2838 	action_idx = CurTrigger->Action;			// action list
   2839 	if (action_idx == TriggerClass::ACTION_NONE) action_idx = TriggerClass::ACTION_FIRST;
   2840 
   2841 	strcpy(namebuf,CurTrigger->Get_Name());				// Name
   2842 	name_edt.Set_Text(namebuf,5);
   2843 
   2844 	if (TriggerClass::Event_Need_Data(event_idx)) {
   2845 		sprintf(databuf,"%ld",CurTrigger->Data);	// Credits/Time
   2846 		data_edt.Set_Text(databuf,8);
   2847 	}
   2848 
   2849 	house = CurTrigger->House;						// House
   2850 
   2851 	persistant = CurTrigger->IsPersistant;
   2852 
   2853 	volatilebtn.Turn_Off();
   2854 	persistbtn.Turn_Off();
   2855 	semipersistbtn.Turn_Off();
   2856 	switch (CurTrigger->IsPersistant) {
   2857 		case TriggerClass::VOLATILE:
   2858 			volatilebtn.Turn_On();
   2859 			break;
   2860 
   2861 		case TriggerClass::SEMIPERSISTANT:
   2862 			semipersistbtn.Turn_On();
   2863 			break;
   2864 
   2865 		case TriggerClass::PERSISTANT:
   2866 			persistbtn.Turn_On();
   2867 			break;
   2868 	}
   2869 
   2870 	/*
   2871 	......................... Fill in the list boxes .........................
   2872 	*/
   2873 	for (i = 0; i < EVENT_COUNT; i++) {
   2874 		eventnames[i] = TriggerClass::Name_From_Event( (EventType)i);
   2875 		eventlist.Add_Item(eventnames[i]);
   2876 	}
   2877 	eventlist.Set_Selected_Index(event_idx);
   2878 
   2879 	for (i = 0; i < TriggerClass::ACTION_COUNT; i++) {
   2880 		actionnames[i] = TriggerClass::Name_From_Action( (TriggerClass::ActionType)i);
   2881 		actionlist.Add_Item(actionnames[i]);
   2882 	}
   2883 	actionlist.Set_Selected_Index(action_idx);
   2884 
   2885 	/*
   2886 	-------------------------- Main Processing Loop --------------------------
   2887 	*/
   2888 	display = REDRAW_ALL;
   2889 	process = true;
   2890 	while (process) {
   2891 
   2892 		/*
   2893 		** If we have just received input focus again after running in the background then
   2894 		** we need to redraw.
   2895 		*/
   2896 		if (AllSurfaces.SurfacesRestored){
   2897 			AllSurfaces.SurfacesRestored=FALSE;
   2898 			display=REDRAW_ALL;
   2899 		}
   2900 
   2901 		/*
   2902 		........................ Invoke game callback .........................
   2903 		*/
   2904 		Call_Back();
   2905 
   2906 		/*
   2907 		...................... Refresh display if needed ......................
   2908 		*/
   2909 		if (display) {
   2910 
   2911 			/*
   2912 			...................... Display the dialog box ......................
   2913 			*/
   2914 			Hide_Mouse();
   2915 			if (display >= REDRAW_BACKGROUND) {
   2916 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   2917 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   2918 
   2919 				/*
   2920 				....................... Draw the captions .......................
   2921 				*/
   2922 				Fancy_Text_Print("Trigger Editor", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN,
   2923 					CC_GREEN, TBLACK,
   2924 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2925 
   2926 				Fancy_Text_Print("Events", D_EVENT_X + D_EVENT_W / 2,
   2927 					D_EVENT_Y - D_TXT8_H,
   2928 					CC_GREEN, TBLACK,
   2929 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2930 
   2931 				Fancy_Text_Print("Actions", D_ACTION_X + D_ACTION_W / 2,
   2932 					D_ACTION_Y - D_TXT8_H,
   2933 					CC_GREEN, TBLACK,
   2934 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2935 
   2936 				Fancy_Text_Print("Name", D_NAME_X - 5, D_NAME_Y,
   2937 					CC_GREEN, TBLACK,
   2938 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2939 
   2940 				if ((EventType)event_idx==EVENT_CREDITS) {	// use 'Data' for Credits
   2941 					Fancy_Text_Print("Credits", D_DATA_X - 5, D_DATA_Y,
   2942 						CC_GREEN, TBLACK,
   2943 						TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2944 
   2945 				} else {
   2946 					if ((EventType)event_idx==EVENT_TIME) {	// use 'Data' for Time
   2947 						Fancy_Text_Print("1/10 Min", D_DATA_X - 5, D_DATA_Y,
   2948 							CC_GREEN, TBLACK,
   2949 							TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2950 					}
   2951 				}
   2952 
   2953 				if (TriggerClass::Action_Need_Team(action_idx)) {
   2954 					if (CurTrigger->Team) {
   2955 						Fancy_Text_Print(CurTrigger->Team->IniName,
   2956 							D_TEAM_X + D_TEAM_W + 5, D_TEAM_Y, CC_GREEN, TBLACK,
   2957 							TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2958 					} else {
   2959 						Fancy_Text_Print( "!!!",
   2960 							D_TEAM_X + D_TEAM_W + 5, D_TEAM_Y, CC_GREEN, TBLACK,
   2961 							TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   2962 					}
   2963 				}
   2964 			}
   2965 
   2966 			/*
   2967 			..................... Rebuild the button list ......................
   2968 			*/
   2969 			eventlist.Zap();
   2970 			actionlist.Zap();
   2971 			name_edt.Zap();
   2972 			data_edt.Zap();
   2973 			teambtn.Zap();
   2974 			gdibtn.Zap();
   2975 			nodbtn.Zap();
   2976 			neutralbtn.Zap();
   2977 			volatilebtn.Zap();
   2978 			persistbtn.Zap();
   2979 			semipersistbtn.Zap();
   2980 			okbtn.Zap();
   2981 			cancelbtn.Zap();
   2982 
   2983 			commands = &okbtn;
   2984 			cancelbtn.Add_Tail(*commands);
   2985 			eventlist.Add_Tail(*commands);
   2986 			actionlist.Add_Tail(*commands);
   2987 			name_edt.Add_Tail(*commands);
   2988 			volatilebtn.Add_Tail(*commands);
   2989 			persistbtn.Add_Tail(*commands);
   2990 			semipersistbtn.Add_Tail(*commands);
   2991 			if (TriggerClass::Event_Need_Data(event_idx)) {
   2992 				data_edt.Add_Tail(*commands);
   2993 				sprintf(databuf,"%ld",CurTrigger->Data);
   2994 				data_edt.Set_Text(databuf,8);
   2995 			}
   2996 			if (TriggerClass::Event_Need_House(event_idx)) {
   2997 				gdibtn.Add_Tail(*commands);
   2998 				nodbtn.Add_Tail(*commands);
   2999 				neutralbtn.Add_Tail(*commands);
   3000 				Set_House_Buttons(house, commands, BUTTON_GDI);
   3001 			}
   3002 			if (TriggerClass::Action_Need_Team(action_idx)) teambtn.Add_Tail(*commands);
   3003 
   3004 			/*
   3005 			........................ Redraw the buttons ........................
   3006 			*/
   3007 			if (display >= REDRAW_BUTTONS) {
   3008 				commands->Flag_List_To_Redraw();
   3009 			}
   3010 			Show_Mouse();
   3011 			display = REDRAW_NONE;
   3012 		}
   3013 
   3014 		/*
   3015 		........................... Get user input ............................
   3016 		*/
   3017 		input = commands->Input();
   3018 
   3019 		/*
   3020 		............................ Process input ............................
   3021 		*/
   3022 		switch (input) {
   3023 			case (EVENT_LIST | KN_BUTTON):
   3024 				if (eventlist.Current_Index() != event_idx) {
   3025 					event_idx = EventType(eventlist.Current_Index());
   3026 					databuf[0] = 0;
   3027 					CurTrigger->Data = 0;
   3028 					if (!TriggerClass::Event_Need_House(event_idx)) {
   3029 						CurTrigger->House = HOUSE_NONE;
   3030 					}
   3031 					display = REDRAW_ALL;
   3032 				}
   3033 				break;
   3034 
   3035 			case (ACTION_LIST | KN_BUTTON):
   3036 				if (actionlist.Current_Index() != action_idx) {
   3037 					action_idx = TriggerClass::ActionType(actionlist.Current_Index());
   3038 					display = REDRAW_ALL;
   3039 				}
   3040 				break;
   3041 
   3042 			case (NAME_EDIT | KN_BUTTON):
   3043 				break;
   3044 
   3045 			case (DATA_EDIT | KN_BUTTON):
   3046 				break;
   3047 
   3048 			case (BUTTON_GDI | KN_BUTTON):
   3049 			case (BUTTON_NOD | KN_BUTTON):
   3050 			case (BUTTON_NEUTRAL | KN_BUTTON):
   3051 			case (BUTTON_MULTI1 | KN_BUTTON):
   3052 			case (BUTTON_MULTI2 | KN_BUTTON):
   3053 			case (BUTTON_MULTI3 | KN_BUTTON):
   3054 			case (BUTTON_MULTI4 | KN_BUTTON):
   3055 			case (BUTTON_MULTI5 | KN_BUTTON):
   3056 			case (BUTTON_MULTI6 | KN_BUTTON):
   3057 				house = (HousesType)( (input & (~KN_BUTTON)) - BUTTON_GDI);
   3058 				Set_House_Buttons(house, commands, BUTTON_GDI);
   3059 				break;
   3060 
   3061 			case (BUTTON_TEAM | KN_BUTTON):
   3062 				Handle_Teams("Select a Team");
   3063 				if (CurTeam) {
   3064 					CurTrigger->Team = CurTeam;
   3065 				}
   3066 				HiddenPage.Clear();
   3067 				Flag_To_Redraw(true);
   3068 				Render();
   3069 				display = REDRAW_ALL;
   3070 				break;
   3071 
   3072 			case (BUTTON_VOLATILE | KN_BUTTON):
   3073 				persistant = TriggerClass::VOLATILE;
   3074 				volatilebtn.Turn_On();
   3075 				persistbtn.Turn_Off();
   3076 				semipersistbtn.Turn_Off();
   3077 				break;
   3078 
   3079 			case (BUTTON_PERSIST | KN_BUTTON):
   3080 				persistant = TriggerClass::PERSISTANT;
   3081 				volatilebtn.Turn_Off();
   3082 				persistbtn.Turn_On();
   3083 				semipersistbtn.Turn_Off();
   3084 				break;
   3085 
   3086 			case (BUTTON_SEMIPERSIST | KN_BUTTON):
   3087 				persistant = TriggerClass::SEMIPERSISTANT;
   3088 				volatilebtn.Turn_Off();
   3089 				persistbtn.Turn_Off();
   3090 				semipersistbtn.Turn_On();
   3091 				break;
   3092 
   3093 			case (KN_RETURN):
   3094 			case (BUTTON_OK | KN_BUTTON):
   3095 				process = false;
   3096 				break;
   3097 
   3098 			case (KN_ESC):
   3099 			case (BUTTON_CANCEL | KN_BUTTON):
   3100 				cancel = true;
   3101 				process = false;
   3102 				break;
   3103 
   3104 			default:
   3105 				break;
   3106 		}
   3107 	}
   3108 
   3109 	/*
   3110 	------------------------------ Save values -------------------------------
   3111 	*/
   3112 	if (!cancel) {
   3113 
   3114 		/*
   3115 		.......................... Get list indices ...........................
   3116 		*/
   3117 		event_idx = EventType(eventlist.Current_Index());
   3118 		action_idx = TriggerClass::ActionType(actionlist.Current_Index());
   3119 
   3120 		/*
   3121 		......................... Set Event & Action ..........................
   3122 		*/
   3123 		CurTrigger->Event = EventType(event_idx);
   3124 		CurTrigger->Action = TriggerClass::ActionType(action_idx);
   3125 
   3126 		/*
   3127 		.............................. Set name ...............................
   3128 		*/
   3129 		if (strlen(namebuf)==0) {
   3130 			CurTrigger->Set_Name("____");
   3131 		} else {
   3132 			CurTrigger->Set_Name(namebuf);
   3133 		}
   3134 
   3135 		/*
   3136 		.............................. Set Data ...............................
   3137 		*/
   3138 		if (TriggerClass::Event_Need_Data(event_idx)) {
   3139 			CurTrigger->Data = atol(databuf);
   3140 		}
   3141 
   3142 		/*
   3143 		.............................. Set House ..............................
   3144 		*/
   3145 		if (TriggerClass::Event_Need_House(event_idx)) {
   3146 			CurTrigger->House = house;
   3147 		} else {
   3148 			CurTrigger->House = HOUSE_NONE;
   3149 		}
   3150 
   3151 		/*
   3152 		........................... Set Persistence  ..........................
   3153 		*/
   3154 		CurTrigger->IsPersistant = persistant;
   3155 	}
   3156 
   3157 	/*
   3158 	--------------------------- Redraw the display ---------------------------
   3159 	*/
   3160 	HiddenPage.Clear();
   3161 	Flag_To_Redraw(true);
   3162 	Render();
   3163 
   3164 	if (cancel) {
   3165 		return(-1);
   3166 	} else {
   3167 		return(0);
   3168 	}
   3169 }
   3170 
   3171 
   3172 /***************************************************************************
   3173  * MapEditClass::Import_Triggers -- lets user import triggers              *
   3174  *                                                                         *
   3175  *    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                  *
   3176  *    ³                    Triggers                     ³                  *
   3177  *    ³    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿   ³                  *
   3178  *    ³    ³x Name     Event     Action    House  ³³   ³                  *
   3179  *    ³    ³  Name     Event     Action    House  ÃÄ´   ³                  *
   3180  *    ³    ³x Name     Event     Action    House  ³ ³   ³                  *
   3181  *    ³    ³  Name     Event     Action    House  ³ ³   ³                  *
   3182  *    ³    ³                                      ³ ³   ³                  *
   3183  *    ³    ³                                      ³ ³   ³                  *
   3184  *    ³    ³                                      ÃÄ´   ³                  *
   3185  *    ³    ³                                      ³³   ³                  *
   3186  *    ³    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ   ³                  *
   3187  *    ³                                                 ³                  *
   3188  *    ³                [OK]     [Cancel]                ³                  *
   3189  *    ³                                                 ³                  *
   3190  *    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                  *
   3191  *                                                                         *
   3192  * INPUT:                                                                  *
   3193  *      none.                                                              *
   3194  *                                                                         *
   3195  * OUTPUT:                                                                 *
   3196  *      0 = OK, -1 = user cancelled                                        *
   3197  *                                                                         *
   3198  * WARNINGS:                                                               *
   3199  *      none.                                                              *
   3200  *                                                                         *
   3201  * HISTORY:                                                                *
   3202  *   03/29/1995 BRR : Created.                                             *
   3203  *=========================================================================*/
   3204 int MapEditClass::Import_Triggers(void)
   3205 {
   3206 	/*........................................................................
   3207 	Dialog & button dimensions
   3208 	........................................................................*/
   3209 	enum {
   3210 		D_DIALOG_W = 480,
   3211 		D_DIALOG_H = 290,
   3212 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
   3213 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
   3214 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
   3215 
   3216 		D_TXT8_H = 22,
   3217 		D_MARGIN = 14,
   3218 
   3219 		D_LIST_W = 452,
   3220 		D_LIST_H = 208,
   3221 		D_LIST_X = D_DIALOG_X + D_MARGIN,
   3222 		D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
   3223 
   3224 		D_OK_W = 90,
   3225 		D_OK_H = 18,
   3226 		D_OK_X = D_DIALOG_CX - D_OK_W - 5,
   3227 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
   3228 
   3229 		D_CANCEL_W = 90,
   3230 		D_CANCEL_H = 18,
   3231 		D_CANCEL_X = D_DIALOG_CX + 5,
   3232 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
   3233 
   3234 	};
   3235 	/*........................................................................
   3236 	Button enumerations:
   3237 	........................................................................*/
   3238 	enum {
   3239 		TRIGGER_LIST=100,
   3240 		BUTTON_OK,
   3241 		BUTTON_CANCEL,
   3242 	};
   3243 	/*........................................................................
   3244 	Redraw values: in order from "top" to "bottom" layer of the dialog
   3245 	........................................................................*/
   3246 	typedef enum {
   3247 		REDRAW_NONE = 0,
   3248 		REDRAW_BUTTONS,
   3249 		REDRAW_BACKGROUND,
   3250 		REDRAW_ALL = REDRAW_BACKGROUND
   3251 	} RedrawType;
   3252 	/*........................................................................
   3253 	Dialog variables:
   3254 	........................................................................*/
   3255 	RedrawType display;							// requested redraw level
   3256 	bool process;									// loop while true
   3257 	KeyNumType input;								// user input
   3258 	bool cancel = false;
   3259 	static int tabs[] =
   3260 		{70, 220, 370, 420}; 					// list box tab stops
   3261 	DynamicVectorClass<char *> trignames;	// list of INI trigger names
   3262 	char *inibuf;									// working INI buffer
   3263 	CCFileClass file;								// file for reading the INI file
   3264 	char buf[128];									// for reading an INI entry
   3265 	char *tbuffer;									// Accumulation buffer of trigger IDs.
   3266 	int len;											// Length of data in buffer.
   3267 	TriggerClass *trigger;						// Working trigger pointer.
   3268 	char *item;										// for adding to list box
   3269 	char *eventptr;
   3270 	char *actionptr;
   3271 	char *houseptr;
   3272 	int i;
   3273 	/*........................................................................
   3274 	Buttons
   3275 	........................................................................*/
   3276 	ControlClass *commands = NULL;				// the button list
   3277 
   3278 	CheckListClass triggerlist (TRIGGER_LIST,
   3279 		D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H,
   3280 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   3281 		Hires_Retrieve("BTN-UP.SHP"),
   3282 		Hires_Retrieve("BTN-DN.SHP"));
   3283 
   3284 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
   3285 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   3286 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
   3287 
   3288 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
   3289 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   3290 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
   3291 
   3292 	Set_Logic_Page(SeenBuff);
   3293 
   3294 	/*------------------------------------------------------------------------
   3295 	Read the MASTER.INI file
   3296 	------------------------------------------------------------------------*/
   3297 	/*........................................................................
   3298 	Read the file into the staging buffer
   3299 	........................................................................*/
   3300 	inibuf = new char [30000];
   3301 	memset(inibuf, '\0', 30000);
   3302 	file.Set_Name("MASTER.INI");
   3303 	if (!file.Is_Available()) {
   3304 		file.Close();
   3305 		delete [] inibuf;
   3306 		return(-1);
   3307 	} else {
   3308 		file.Read(inibuf, 30000 - 1);
   3309 	}
   3310 	file.Close();
   3311 
   3312 	/*........................................................................
   3313 	Read all entry names in the Triggers section into a temp buffer
   3314 	........................................................................*/
   3315 	len = strlen(inibuf) + 2;
   3316 	tbuffer = inibuf + len;
   3317 	WWGetPrivateProfileString(TriggerClass::INI_Name(), NULL, NULL, tbuffer,
   3318 		30000 - len, inibuf);
   3319 
   3320 	/*........................................................................
   3321 	For each entry in the INI section:
   3322 	- Get the entry
   3323 	- Generate a string describing the trigger
   3324 	- Add that string to the list box
   3325 	- Add a ptr to the INI entry name to our 'trignames' list
   3326 	........................................................................*/
   3327 	while (*tbuffer != '\0') {
   3328 		WWGetPrivateProfileString(TriggerClass::INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, inibuf);
   3329 		item = new char [60];
   3330 
   3331 		/*
   3332 		** Parse the INI entry
   3333 		*/
   3334 		eventptr = strtok(buf,",");
   3335 		actionptr = strtok(NULL,",");
   3336 		strtok(NULL,",");
   3337 		houseptr = strtok(NULL,",");
   3338 
   3339 		/*
   3340 		** Generate the descriptive string
   3341 		*/
   3342 		sprintf(item, " %s\t%s\t%s\t", tbuffer, eventptr, actionptr);
   3343 
   3344 		/*
   3345 		** Add house name if needed
   3346 		*/
   3347 		if (TriggerClass::Event_Need_House(TriggerClass::Event_From_Name(eventptr))) {
   3348 			HousesType house = HouseTypeClass::From_Name(houseptr);
   3349 			if (house != HOUSE_NONE) {
   3350 				strcat(item, HouseTypeClass::As_Reference(house).Suffix);
   3351 			} else {
   3352 				strcat(item, "!!!");
   3353 			}
   3354 		} else {
   3355 			strcat(item,"   ");
   3356 		}
   3357 
   3358 		/*
   3359 		** Add the item to the list box
   3360 		*/
   3361 		triggerlist.Add_Item(item);
   3362 
   3363 		/*
   3364 		** Add the name to our internal name list
   3365 		*/
   3366 		trignames.Add(tbuffer);
   3367 
   3368 		tbuffer += strlen(tbuffer)+1;
   3369 	}
   3370 
   3371 	/*
   3372 	............................ Create the list .............................
   3373 	*/
   3374 	commands = &triggerlist;
   3375 	okbtn.Add_Tail(*commands);
   3376 	cancelbtn.Add_Tail(*commands);
   3377 
   3378 	/*
   3379 	------------------------ Init tab stops for list -------------------------
   3380 	*/
   3381 	triggerlist.Set_Tabs(tabs);
   3382 
   3383 	/*
   3384 	-------------------------- Main Processing Loop --------------------------
   3385 	*/
   3386 	display = REDRAW_ALL;
   3387 	process = true;
   3388 	while (process) {
   3389 
   3390 		/*
   3391 		** If we have just received input focus again after running in the background then
   3392 		** we need to redraw.
   3393 		*/
   3394 		if (AllSurfaces.SurfacesRestored){
   3395 			AllSurfaces.SurfacesRestored=FALSE;
   3396 			display=REDRAW_ALL;
   3397 		}
   3398 
   3399 		/*
   3400 		........................ Invoke game callback .........................
   3401 		*/
   3402 		Call_Back();
   3403 		/*
   3404 		...................... Refresh display if needed ......................
   3405 		*/
   3406 		if (display) {
   3407 			/*
   3408 			...................... Display the dialog box ......................
   3409 			*/
   3410 			Hide_Mouse();
   3411 			if (display >= REDRAW_BACKGROUND) {
   3412 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   3413 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   3414 				/*
   3415 				....................... Draw the captions .......................
   3416 				*/
   3417 				Fancy_Text_Print("Import Triggers", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN,
   3418 					CC_GREEN, TBLACK,
   3419 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   3420 			}
   3421 			/*
   3422 			........................ Redraw the buttons ........................
   3423 			*/
   3424 			if (display >= REDRAW_BUTTONS)
   3425 				commands->Flag_List_To_Redraw();
   3426 			Show_Mouse();
   3427 			display = REDRAW_NONE;
   3428 		}
   3429 
   3430 		/*
   3431 		........................... Get user input ............................
   3432 		*/
   3433 		input = commands->Input();
   3434 
   3435 		/*
   3436 		............................ Process input ............................
   3437 		*/
   3438 		switch (input) {
   3439 			case (TRIGGER_LIST | KN_BUTTON):
   3440 				break;
   3441 
   3442 			case (KN_RETURN):
   3443 			case (BUTTON_OK | KN_BUTTON):
   3444 				process = false;
   3445 				break;
   3446 
   3447 			case (KN_ESC):
   3448 			case (BUTTON_CANCEL | KN_BUTTON):
   3449 				cancel = true;
   3450 				process = false;
   3451 				break;
   3452 		}
   3453 	}
   3454 
   3455 	/*
   3456 	--------------------------- Redraw the display ---------------------------
   3457 	*/
   3458 	HiddenPage.Clear();
   3459 	Flag_To_Redraw(true);
   3460 	Render();
   3461 
   3462 	/*........................................................................
   3463 	Re-parse the INI section; if any item is checked in the list box, create
   3464 	that trigger for this scenario.
   3465 	........................................................................*/
   3466 	if (!cancel) {
   3467 		tbuffer = inibuf + len;
   3468 		i = 0;
   3469 		while (*tbuffer != '\0') {
   3470 
   3471 			/*
   3472 			** If this item is checked on the list, create a new trigger
   3473 			** and fill it in.
   3474 			*/
   3475 			if (triggerlist.Is_Checked(i)) {
   3476 				WWGetPrivateProfileString(TriggerClass::INI_Name(), tbuffer, NULL,
   3477 					buf, sizeof(buf)-1, inibuf);
   3478 
   3479 				trigger = new TriggerClass();
   3480 				trigger->Fill_In(tbuffer, buf);
   3481 
   3482 				if (trigger->House != HOUSE_NONE)
   3483 					HouseTriggers[trigger->House].Add(trigger);
   3484 			}
   3485 
   3486 			tbuffer += strlen(tbuffer)+1;
   3487 			i++;
   3488 		}
   3489 	}
   3490 
   3491 
   3492 	/*........................................................................
   3493 	Clean up memory
   3494 	........................................................................*/
   3495 	trignames.Clear();
   3496 	while (triggerlist.Count()) {
   3497 		item = (char *)triggerlist.Get_Item(0);
   3498 		triggerlist.Remove_Item(item);
   3499 		delete [] item;
   3500 	}
   3501 	delete [] inibuf;
   3502 
   3503 	if (cancel) {
   3504 		return(-1);
   3505 	} else {
   3506 		return(0);
   3507 	}
   3508 }
   3509 
   3510 
   3511 /***************************************************************************
   3512  * MapEditClass::Import_Teams -- lets the user import teams                *
   3513  *                                                                         *
   3514  *    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿           *
   3515  *    ³                         Teams                          ³           *
   3516  *    ³    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿    ³           *
   3517  *    ³    ³ Name     House    Class:Count,Class:Count  ³³    ³           *
   3518  *    ³    ³ Name     House    Class:Count,Class:Count  ÃÄ´    ³           *
   3519  *    ³    ³ Name     House    Class:Count,Class:Count  ³ ³    ³           *
   3520  *    ³    ³ Name     House    Class:Count,Class:Count  ³ ³    ³           *
   3521  *    ³    ³                                            ³ ³    ³           *
   3522  *    ³    ³                                            ³ ³    ³           *
   3523  *    ³    ³                                            ÃÄ´    ³           *
   3524  *    ³    ³                                            ³³    ³           *
   3525  *    ³    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ    ³           *
   3526  *    ³                                                        ³           *
   3527  *    ³                    [OK]    [Cancel]                    ³           *
   3528  *    ³                                                        ³           *
   3529  *    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ           *
   3530  *                                                                         *
   3531  * INPUT:                                                                  *
   3532  *      none.                                                              *
   3533  *                                                                         *
   3534  * OUTPUT:                                                                 *
   3535  *      0 = OK, -1 = user cancelled                                        *
   3536  *                                                                         *
   3537  * WARNINGS:                                                               *
   3538  *      Uses HIDBUFF.                                                      *
   3539  *                                                                         *
   3540  * HISTORY:                                                                *
   3541  *   12/08/1994 BR : Created.                                              *
   3542  *=========================================================================*/
   3543 int MapEditClass::Import_Teams(void)
   3544 {
   3545 	/*........................................................................
   3546 	Dialog & button dimensions
   3547 	........................................................................*/
   3548 	enum {
   3549 		D_DIALOG_W = 528,
   3550 		D_DIALOG_H = 290,
   3551 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
   3552 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
   3553 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
   3554 
   3555 		D_TXT8_H = 22,
   3556 		D_MARGIN = 14,
   3557 
   3558 		D_LIST_W = 500,
   3559 		D_LIST_H = 208,
   3560 		D_LIST_X = D_DIALOG_X + D_MARGIN,
   3561 		D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
   3562 
   3563 		D_OK_W = 90,
   3564 		D_OK_H = 18,
   3565 		D_OK_X = D_DIALOG_CX - D_OK_W - 5,
   3566 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
   3567 
   3568 		D_CANCEL_W = 90,
   3569 		D_CANCEL_H = 18,
   3570 		D_CANCEL_X = D_DIALOG_CX + 5,
   3571 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
   3572 
   3573 		TEAMTXT_LEN = 43,				// max length of a team entry
   3574 	};
   3575 	/*........................................................................
   3576 	Button enumerations:
   3577 	........................................................................*/
   3578 	enum {
   3579 		TEAM_LIST=100,
   3580 		BUTTON_OK,
   3581 		BUTTON_CANCEL,
   3582 	};
   3583 	/*........................................................................
   3584 	Redraw values: in order from "top" to "bottom" layer of the dialog
   3585 	........................................................................*/
   3586 	typedef enum {
   3587 		REDRAW_NONE = 0,
   3588 		REDRAW_BUTTONS,
   3589 		REDRAW_BACKGROUND,
   3590 		REDRAW_ALL = REDRAW_BACKGROUND
   3591 	} RedrawType;
   3592 	/*........................................................................
   3593 	Dialog variables:
   3594 	........................................................................*/
   3595 	RedrawType display;							// requested redraw level
   3596 	bool process;									// loop while true
   3597 	KeyNumType input;								// user input
   3598 	bool cancel = false;
   3599 	static int tabs[] = {120, 180}; 			// list box tab stops
   3600 	DynamicVectorClass<char *> teamnames;	// list of INI team names
   3601 	char *inibuf;									// working INI buffer
   3602 	CCFileClass file;								// file for reading the INI file
   3603 	char buf[128];									// for reading an INI entry
   3604 	char *tbuffer;									// Accumulation buffer of team IDs.
   3605 	int len;											// Length of data in buffer.
   3606 	TeamTypeClass *team;							// Working team pointer.
   3607 	char *item;										// for adding to list box
   3608 	char *houseptr;
   3609 	char *classptr;
   3610 	int numclasses;
   3611 	int i;
   3612 	/*........................................................................
   3613 	Buttons
   3614 	........................................................................*/
   3615 	ControlClass *commands = NULL;				// the button list
   3616 
   3617 	CheckListClass teamlist (TEAM_LIST,
   3618 		D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H,
   3619 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   3620 		Hires_Retrieve("BTN-UP.SHP"),
   3621 		Hires_Retrieve("BTN-DN.SHP"));
   3622 
   3623 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
   3624 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   3625 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
   3626 
   3627 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
   3628 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   3629 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
   3630 
   3631 	Set_Logic_Page(SeenBuff);
   3632 
   3633 	/*------------------------------------------------------------------------
   3634 	Read the MASTER.INI file
   3635 	------------------------------------------------------------------------*/
   3636 	/*........................................................................
   3637 	Read the file into the staging buffer
   3638 	........................................................................*/
   3639 	inibuf = new char [30000];
   3640 	memset(inibuf, '\0', 30000);
   3641 	file.Set_Name("MASTER.INI");
   3642 	if (!file.Is_Available()) {
   3643 		file.Close();
   3644 		delete [] inibuf;
   3645 		return(-1);
   3646 	} else {
   3647 		file.Read(inibuf, 30000 - 1);
   3648 	}
   3649 
   3650 	file.Close();
   3651 	/*........................................................................
   3652 	Read all entry names in the TeamTypes section into a temp buffer
   3653 	........................................................................*/
   3654 	len = strlen(inibuf) + 2;
   3655 	tbuffer = inibuf + len;
   3656 	WWGetPrivateProfileString(TeamTypeClass::INI_Name(), NULL, NULL, tbuffer,
   3657 		30000 - len, inibuf);
   3658 
   3659 	/*........................................................................
   3660 	For each entry in the INI section:
   3661 	- Get the entry
   3662 	- Generate a string describing the team
   3663 	- Add that string to the list box
   3664 	- Add a ptr to the INI entry name to our 'teamnames' list
   3665 	........................................................................*/
   3666 	while (*tbuffer != '\0') {
   3667 		WWGetPrivateProfileString(TeamTypeClass::INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, inibuf);
   3668 		item = new char [60];
   3669 
   3670 		/*
   3671 		** Parse the INI entry
   3672 		*/
   3673 		houseptr = strtok(buf,",");
   3674 		for (i = 0; i < 9; i++) {
   3675 			strtok(NULL,",");
   3676 		}
   3677 		numclasses = atoi(strtok(NULL,","));
   3678 
   3679 		/*
   3680 		** Generate the descriptive string
   3681 		*/
   3682 		sprintf(item," %s\t",tbuffer);
   3683 		HousesType house = HouseTypeClass::From_Name(houseptr);
   3684 		if (house != HOUSE_NONE) {
   3685 			strcat(item, HouseTypeClass::As_Reference(house).Suffix);
   3686 		} else {
   3687 			strcat(item, "!!!");
   3688 		}
   3689 		strcat(item, "\t");
   3690 
   3691 		classptr = strtok(NULL,",");
   3692 		for (i = 0; i < numclasses; i++) {
   3693 			if (strlen(item) + strlen(classptr) < 60) {
   3694 				strcat(item,classptr);
   3695 				classptr = strtok(NULL,",");
   3696 			} else {
   3697 				break;
   3698 			}
   3699 		}
   3700 
   3701 		/*
   3702 		** Add the item to the list box
   3703 		*/
   3704 		teamlist.Add_Item(item);
   3705 		/*
   3706 		** Add the name to our internal name list
   3707 		*/
   3708 		teamnames.Add(tbuffer);
   3709 
   3710 		tbuffer += strlen(tbuffer)+1;
   3711 	}
   3712 
   3713 	/*
   3714 	............................ Create the list .............................
   3715 	*/
   3716 	commands = &teamlist;
   3717 	okbtn.Add_Tail(*commands);
   3718 	cancelbtn.Add_Tail(*commands);
   3719 
   3720 	/*
   3721 	------------------------ Init tab stops for list -------------------------
   3722 	*/
   3723 	teamlist.Set_Tabs(tabs);
   3724 
   3725 	/*
   3726 	-------------------------- Main Processing Loop --------------------------
   3727 	*/
   3728 	display = REDRAW_ALL;
   3729 	process = true;
   3730 	while (process) {
   3731 
   3732 		/*
   3733 		** If we have just received input focus again after running in the background then
   3734 		** we need to redraw.
   3735 		*/
   3736 		if (AllSurfaces.SurfacesRestored){
   3737 			AllSurfaces.SurfacesRestored=FALSE;
   3738 			display=REDRAW_ALL;
   3739 		}
   3740 
   3741 		/*
   3742 		........................ Invoke game callback .........................
   3743 		*/
   3744 		Call_Back();
   3745 		/*
   3746 		...................... Refresh display if needed ......................
   3747 		*/
   3748 		if (display) {
   3749 			/*
   3750 			...................... Display the dialog box ......................
   3751 			*/
   3752 			Hide_Mouse();
   3753 			if (display >= REDRAW_BACKGROUND) {
   3754 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   3755 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   3756 				/*
   3757 				....................... Draw the captions .......................
   3758 				*/
   3759 				Fancy_Text_Print("Import Teams", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN,
   3760 					CC_GREEN, TBLACK,
   3761 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   3762 			}
   3763 			/*
   3764 			........................ Redraw the buttons ........................
   3765 			*/
   3766 			if (display >= REDRAW_BUTTONS)
   3767 				commands->Flag_List_To_Redraw();
   3768 			Show_Mouse();
   3769 			display = REDRAW_NONE;
   3770 		}
   3771 
   3772 		/*
   3773 		........................... Get user input ............................
   3774 		*/
   3775 		input = commands->Input();
   3776 
   3777 		/*
   3778 		............................ Process input ............................
   3779 		*/
   3780 		switch (input) {
   3781 			case (TEAM_LIST | KN_BUTTON):
   3782 				break;
   3783 
   3784 			case (KN_RETURN):
   3785 			case (BUTTON_OK | KN_BUTTON):
   3786 				process = false;
   3787 				break;
   3788 
   3789 			case (KN_ESC):
   3790 			case (BUTTON_CANCEL | KN_BUTTON):
   3791 				cancel = true;
   3792 				process = false;
   3793 				break;
   3794 		}
   3795 	}
   3796 
   3797 	/*
   3798 	--------------------------- Redraw the display ---------------------------
   3799 	*/
   3800 	HiddenPage.Clear();
   3801 	Flag_To_Redraw(true);
   3802 	Render();
   3803 
   3804 	/*........................................................................
   3805 	Re-parse the INI section; if any item is checked in the list box, create
   3806 	that team for this scenario.
   3807 	........................................................................*/
   3808 	if (!cancel) {
   3809 		tbuffer = inibuf + len;
   3810 		i = 0;
   3811 		while (*tbuffer != '\0') {
   3812 			/*
   3813 			** If this item is checked on the list, create a new team
   3814 			** and fill it in.
   3815 			*/
   3816 			if (teamlist.Is_Checked(i)) {
   3817 				WWGetPrivateProfileString(TeamTypeClass::INI_Name(), tbuffer, NULL,
   3818 					buf, sizeof(buf)-1, inibuf);
   3819 
   3820 				team = new TeamTypeClass();
   3821 				team->Fill_In(tbuffer,buf);
   3822 			}
   3823 
   3824 			tbuffer += strlen(tbuffer)+1;
   3825 			i++;
   3826 		}
   3827 	}
   3828 
   3829 	/*........................................................................
   3830 	Clean up memory
   3831 	........................................................................*/
   3832 	teamnames.Clear();
   3833 	while (teamlist.Count()) {
   3834 		item = (char *)teamlist.Get_Item(0);
   3835 		teamlist.Remove_Item(item);
   3836 		delete [] item;
   3837 	}
   3838 	delete [] inibuf;
   3839 
   3840 	if (cancel) {
   3841 		return(-1);
   3842 	} else {
   3843 		return(0);
   3844 	}
   3845 }
   3846 
   3847 #endif