CnC_Remastered_Collection

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

MAPEDTM.CPP (66724B)


      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\mapedtm.cpv   2.18   16 Oct 1995 16:52:16   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 : MAPEDTM.CPP                              *
     24  *                                                                         *
     25  *                   Programmer : Bill Randolph                            *
     26  *                                                                         *
     27  *                   Start Date : December 7, 1994                         *
     28  *                                                                         *
     29  *                  Last Update : April 9, 1996 [BRR]                      *
     30  *                                                                         *
     31  *-------------------------------------------------------------------------*
     32  * Functions:                                                              *
     33  *   MapEditClass::Handle_Teams -- main team-dialog-handling function      *
     34  *   MapEditClass::Select_Team -- user selects a team from a list          *
     35  *   MapEditClass::Edit_Team -- user edits a team's options                *
     36  *   MapEditClass::Team_Members -- user picks makeup of a team             *
     37  *   MapEditClass::Build_Mission_list -- fills in mission list box         *
     38  *   MapEditClass::Draw_Member -- Draws a member of the team dialog box.   *
     39  *   MapEditClass::Team_Members -- Team members dialog                     * 
     40  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     41 
     42 #include "function.h"
     43 
     44 #ifdef SCENARIO_EDITOR
     45 
     46 
     47 /***************************************************************************
     48  * MapEditClass::Handle_Teams -- main team-dialog-handling function        *
     49  *                                                                         *
     50  * INPUT:                                                                  *
     51  *      none.                                                              *
     52  *                                                                         *
     53  * OUTPUT:                                                                 *
     54  *      none.                                                              *
     55  *                                                                         *
     56  * WARNINGS:                                                               *
     57  *      none.                                                              *
     58  *                                                                         *
     59  * HISTORY:                                                                *
     60  *   12/08/1994 BR : Created.                                              *
     61  *=========================================================================*/
     62 void MapEditClass::Handle_Teams(char const * caption)
     63 {
     64 	int rc;
     65 
     66 	/*------------------------------------------------------------------------
     67 	Team dialog processing loop:
     68 	- Invoke the team selection dialog. If a team's selected, break
     69 	  & return
     70 	- If user wants to edit the current team, do so
     71 	- If user wants to create new team, new a TeamTypeClass & edit it
     72 	- If user wants to delete team, delete the current team
     73 	- Keep looping until 'OK'
     74 	------------------------------------------------------------------------*/
     75 	for (;;) {
     76 
     77 		/*
     78 		............................. Select team .............................
     79 		*/
     80 		rc = Select_Team(caption);
     81 
     82 		/*
     83 		............................. 'OK'; break .............................
     84 		*/
     85 		if (rc == 0) {
     86 			break;
     87 		} else {
     88 
     89 			/*
     90 			............................... 'Edit' ................................
     91 			*/
     92 			if (rc == 1 && CurTeam) {
     93 				if (Edit_Team()==0) {
     94 					Changed = 1;
     95 				}
     96 			} else {
     97 
     98 				/*
     99 				................................ 'New' ................................
    100 				*/
    101 				if (rc == 2) {
    102 					/*
    103 					........................ Create a new team .........................
    104 					*/
    105 					CurTeam = new TeamTypeClass();
    106 					if (CurTeam) {
    107 						/*
    108 						................... delete it if user cancels ...................
    109 						*/
    110 						if (Edit_Team()==-1) {
    111 							delete CurTeam;
    112 							CurTeam = NULL;
    113 						} else {
    114 							Changed = 1;
    115 						}
    116 					} else {
    117 
    118 						/*
    119 						................. Unable to create; issue warning ..................
    120 						*/
    121 						CCMessageBox().Process("No more teams available.");
    122 						HiddenPage.Clear();
    123 						Flag_To_Redraw(true);
    124 						Render();
    125 					}
    126 				} else {
    127 
    128 					/*
    129 					.............................. 'Delete' ...............................
    130 					*/
    131 					if (rc==3) {
    132 						if (CurTeam) {
    133 							CurTeam->Remove();
    134 							CurTeam = NULL;
    135 						}
    136 					}
    137 				}
    138 			}
    139 		}
    140 	}
    141 }
    142 
    143 
    144 /***************************************************************************
    145  * MapEditClass::Select_Team -- user selects a team from a list            *
    146  *                                                                         *
    147  *    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿           *
    148  *    ³                         Teams                          ³           *
    149  *    ³    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿    ³           *
    150  *    ³    ³ Name     House    Class:Count,Class:Count  ³³    ³           *
    151  *    ³    ³ Name     House    Class:Count,Class:Count  ÃÄ´    ³           *
    152  *    ³    ³ Name     House    Class:Count,Class:Count  ³ ³    ³           *
    153  *    ³    ³ Name     House    Class:Count,Class:Count  ³ ³    ³           *
    154  *    ³    ³                                            ³ ³    ³           *
    155  *    ³    ³                                            ³ ³    ³           *
    156  *    ³    ³                                            ÃÄ´    ³           *
    157  *    ³    ³                                            ³³    ³           *
    158  *    ³    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ    ³           *
    159  *    ³                                                        ³           *
    160  *    ³      [Edit]        [New]        [Delete]      [OK]     ³           *
    161  *    ³                                                        ³           *
    162  *    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ           *
    163  *                                                                         *
    164  * INPUT:                                                                  *
    165  *      none.                                                              *
    166  *                                                                         *
    167  * OUTPUT:                                                                 *
    168  *      0 = OK, 1 = Edit, 2 = New, 3 = Delete                              *
    169  *                                                                         *
    170  * WARNINGS:                                                               *
    171  *      Uses HIDBUFF.                                                      *
    172  *                                                                         *
    173  * HISTORY:                                                                *
    174  *   12/08/1994 BR : Created.                                              *
    175  *=========================================================================*/
    176 int MapEditClass::Select_Team(char const * caption)
    177 {
    178 	/*........................................................................
    179 	Dialog & button dimensions
    180 	........................................................................*/
    181 	enum {
    182 		D_DIALOG_W = 528,											// dialog width
    183 		D_DIALOG_H = 290,											// dialog height
    184 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),				// centered x-coord
    185 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),				// centered y-coord
    186 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),		// coord of x-center
    187 
    188 		D_TXT8_H = 22,												// ht of 8-pt text
    189 		D_MARGIN = 14,												// margin width/height
    190 
    191 		D_LIST_W = 500,
    192 		D_LIST_H = 208,
    193 		D_LIST_X = D_DIALOG_X + D_MARGIN,
    194 		D_LIST_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
    195 
    196 		D_EDIT_W = 90,
    197 		D_EDIT_H = 18,
    198 		D_EDIT_X = D_DIALOG_X + (D_DIALOG_W / 8) - (D_EDIT_W / 2),
    199 		D_EDIT_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_EDIT_H,
    200 
    201 		D_NEW_W = 90,
    202 		D_NEW_H = 18,
    203 		D_NEW_X = D_DIALOG_X + (D_DIALOG_W / 8) * 3 - (D_NEW_W / 2),
    204 		D_NEW_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_NEW_H,
    205 
    206 		D_DELETE_W = 90,
    207 		D_DELETE_H = 18,
    208 		D_DELETE_X = D_DIALOG_X + (D_DIALOG_W / 8) * 5 - (D_DELETE_W / 2),
    209 		D_DELETE_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_DELETE_H,
    210 
    211 		D_OK_W = 90,
    212 		D_OK_H = 18,
    213 		D_OK_X = D_DIALOG_X + (D_DIALOG_W / 8) * 7 - (D_OK_W / 2),
    214 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
    215 
    216 		TEAMTXT_LEN = 43,				// max length of a team entry
    217 	};
    218 
    219 	/*........................................................................
    220 	Button enumerations:
    221 	........................................................................*/
    222 	enum {
    223 		TEAM_LIST=100,
    224 		BUTTON_EDIT,
    225 		BUTTON_NEW,
    226 		BUTTON_DELETE,
    227 		BUTTON_OK,
    228 	};
    229 
    230 	/*........................................................................
    231 	Redraw values: in order from "top" to "bottom" layer of the dialog
    232 	........................................................................*/
    233 	typedef enum {
    234 		REDRAW_NONE = 0,
    235 		REDRAW_BUTTONS,
    236 		REDRAW_BACKGROUND,
    237 		REDRAW_ALL = REDRAW_BACKGROUND
    238 	} RedrawType;
    239 	/*........................................................................
    240 	Dialog variables
    241 	........................................................................*/
    242 	RedrawType display;							// requested redraw level
    243 	bool process;									// loop while true
    244 	char *teamtext[TEAMTYPE_MAX + 1];		// text for defined teams
    245 	KeyNumType input;								// user input
    246 	bool edit_team = false;						// true = user wants to edit
    247 	bool new_team = false;						// true = user wants to new
    248 	bool del_team = false;						// true = user wants to new
    249 	int i;											// loop counters
    250 	int j;
    251 	int def_idx;									// default list index
    252 	static int tabs[] = {120, 180};				// list box tab stops
    253 	char txt[10];
    254 //	int housetxt;
    255 
    256 	/*........................................................................
    257 	Buttons
    258 	........................................................................*/
    259 	GadgetClass *commands = NULL;				// the button list
    260 
    261 	ListClass teamlist (TEAM_LIST,
    262 		D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H,
    263 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    264 		Hires_Retrieve("BTN-UP.SHP"),
    265 		Hires_Retrieve("BTN-DN.SHP"));
    266 
    267 	TextButtonClass editbtn (BUTTON_EDIT, "Edit",
    268 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    269 		D_EDIT_X, D_EDIT_Y, D_EDIT_W, D_EDIT_H);
    270 
    271 	TextButtonClass newbtn (BUTTON_NEW, "New",
    272 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    273 		D_NEW_X, D_NEW_Y, D_NEW_W, D_NEW_H);
    274 
    275 	TextButtonClass deletebtn (BUTTON_DELETE, "Delete",
    276 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    277 		D_DELETE_X, D_DELETE_Y, D_DELETE_W, D_DELETE_H);
    278 
    279 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
    280 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    281 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
    282 
    283 	/*
    284 	------------------------------- Initialize -------------------------------
    285 	*/
    286 	Set_Logic_Page(SeenBuff);
    287 
    288 	/*
    289 	........................... Fill in team names ...........................
    290 	*/
    291 	def_idx = 0;
    292 	for (i = 0; i < TeamTypes.Count(); i++) {
    293 		/*
    294 		................... Generate string for this team .....................
    295 		*/
    296 		//teamtext[i] = (char *)HidPage.Get_Graphic_Buffer()->Get_Buffer() + TEAMTXT_LEN * i;
    297 		teamtext[i] = new char[255];
    298 
    299 		/*
    300 		........................ Fill in name & house .........................
    301 		*/
    302 		strcpy(teamtext[i],TeamTypes.Ptr(i)->IniName);
    303 		strcat(teamtext[i],"\t");
    304 		strcat(teamtext[i], HouseTypeClass::As_Reference(TeamTypes.Ptr(i)->House).Suffix);
    305 		strcat(teamtext[i],"\t");
    306 
    307 		/*
    308 		................ Fill in class & count for all classes ................
    309 		*/
    310 		for (j = 0; j < TeamTypes.Ptr(i)->ClassCount; j++) {
    311 			sprintf (txt,"%s:%d", TeamTypes.Ptr(i)->Class[j]->IniName, TeamTypes.Ptr(i)->DesiredNum[j]);
    312 
    313 			/*..................................................................
    314 			Add entry if there's room; break otherwise
    315 			(+ 3 for the ", " and the NULL; +3 again for the "..." for the next
    316 			entry)
    317 			..................................................................*/
    318 			if (strlen(txt) + strlen(teamtext[i]) + 6 < TEAMTXT_LEN) {
    319 				if (j > 0) {
    320 					strcat(teamtext[i],", ");
    321 				}
    322 				strcat(teamtext[i],txt);
    323 			} else {
    324 				strcat(teamtext[i], "...");
    325 				break;
    326 			}
    327 		}
    328 
    329 		/*
    330 		.................. Set def_idx if this is CurTeam .....................
    331 		*/
    332 		if (TeamTypes.Ptr(i)==CurTeam) {
    333 			def_idx = i;
    334 		}
    335 
    336 		/*
    337 		........................... Add to list box ...........................
    338 		*/
    339 		teamlist.Add_Item(teamtext[i]);
    340 	}
    341 
    342 	/*
    343 	....................... Set CurTeam if it isn't ..........................
    344 	*/
    345 	if (TeamTypes.Count()==0) {
    346 		CurTeam = NULL;
    347 	} else {
    348 		if (!CurTeam) {
    349 			CurTeam = TeamTypes.Ptr(def_idx);
    350 		}
    351 	}
    352 
    353 	/*
    354 	............................ Create the list .............................
    355 	*/
    356 	commands = &teamlist;
    357 	editbtn.Add_Tail(*commands);
    358 	newbtn.Add_Tail(*commands);
    359 	deletebtn.Add_Tail(*commands);
    360 	okbtn.Add_Tail(*commands);
    361 
    362 	/*
    363 	------------------------ Init tab stops for list -------------------------
    364 	*/
    365 	teamlist.Set_Tabs(tabs);
    366 
    367 	/*
    368 	-------------------------- Main Processing Loop --------------------------
    369 	*/
    370 	display = REDRAW_ALL;
    371 	process = true;
    372 	while (process) {
    373 		/*
    374 		** If we have just received input focus again after running in the background then
    375 		** we need to redraw.
    376 		*/
    377 		if (AllSurfaces.SurfacesRestored){
    378 			AllSurfaces.SurfacesRestored=FALSE;
    379 			display=REDRAW_ALL;
    380 		}
    381 
    382 		/*
    383 		........................ Invoke game callback .........................
    384 		*/
    385 		Call_Back();
    386 
    387 		/*
    388 		...................... Refresh display if needed ......................
    389 		*/
    390 		if (display) {
    391 
    392 			/*
    393 			...................... Display the dialog box ......................
    394 			*/
    395 			Hide_Mouse();
    396 			if (display >= REDRAW_BACKGROUND) {
    397 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
    398 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
    399 
    400 				/*
    401 				....................... Draw the captions .......................
    402 				*/
    403 				Fancy_Text_Print(caption, D_DIALOG_CX, D_DIALOG_Y + D_MARGIN,
    404 					CC_GREEN, TBLACK,
    405 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
    406 			}
    407 			/*
    408 			........................ Redraw the buttons ........................
    409 			*/
    410 			if (display >= REDRAW_BUTTONS) {
    411 				commands->Draw_All();
    412 			}
    413 			Show_Mouse();
    414 			display = REDRAW_NONE;
    415 		}
    416 
    417 		/*
    418 		........................... Get user input ............................
    419 		*/
    420 		input = commands->Input();
    421 
    422 		/*
    423 		............................ Process input ............................
    424 		*/
    425 		switch (input) {
    426 			case (TEAM_LIST | KN_BUTTON):
    427 				def_idx = teamlist.Current_Index();
    428 				if (def_idx < TeamTypes.Count())
    429 					CurTeam = TeamTypes.Ptr(def_idx);
    430 				break;
    431 
    432 			case (BUTTON_EDIT | KN_BUTTON):
    433 				if (CurTeam) {		// only allow if there's one selected
    434 					process = false;
    435 					edit_team = true;
    436 				}
    437 				break;
    438 
    439 			case (BUTTON_NEW | KN_BUTTON):
    440 				process = false;
    441 				new_team = true;
    442 				break;
    443 
    444 			case (BUTTON_DELETE | KN_BUTTON):
    445 				process = false;
    446 				del_team = true;
    447 				break;
    448 
    449 			case (KN_RETURN):
    450 			case (BUTTON_OK | KN_BUTTON):
    451 				process = false;
    452 				break;
    453 		}
    454 	}
    455 
    456 	/*
    457 	--------------------------- Redraw the display ---------------------------
    458 	*/
    459 	HiddenPage.Clear();
    460 	Flag_To_Redraw(true);
    461 	Render();
    462 
    463 	for (i = 0; i < TeamTypes.Count(); i++) {
    464 		delete [] teamtext[i];
    465 	}
    466 	if (edit_team) return(1);
    467 	if (new_team) return(2);
    468 	if (del_team) return(3);
    469 	return(0);
    470 }
    471 
    472 
    473 /***************************************************************************
    474  * MapEditClass::Edit_Team -- user edits a team's options                  *
    475  *                                                                         *
    476  *  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿      *
    477  *  ³                         Team Editor                           ³      *
    478  *  ³                                                               ³      *
    479  *  ³            Name ______               [Roundabout]             ³      *
    480  *  ³        Priority ______  [   GDI   ]  [Learning  ]             ³      *
    481  *  ³         Max Num ______  [   NOD   ]  [Suicide   ]             ³      *
    482  *  ³        Init Num ______               [Autocreate]             ³      *
    483  *  ³            Fear ______               [Mercenary ]             ³      *
    484  *  ³                                      [Prebuild  ]             ³      *
    485  *  ³                                      [Reinforce ]             ³      *
    486  *  ³                                                               ³      *
    487  *  ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿             ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿  ³      *
    488  *  ³  ³                   ³^³             ³                   ³^³  ³      *
    489  *  ³  ³                   ÃÄ´  [Add >>]   ³                   ÃÄ´  ³      *
    490  *  ³  ³                   ³ ³  [Insert]   ³                   ³ ³  ³      *
    491  *  ³  ³                   ³ ³  [Delete]   ³                   ³ ³  ³      *
    492  *  ³  ³                   ÃÄ´    ____     ³                   ÃÄ´  ³      *
    493  *  ³  ³                   ³v³             ³                   ³v³  ³      *
    494  *  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ             ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ  ³      *
    495  *  ³                                                               ³      *
    496  *  ³        [Members]          [Cancel]           [OK]             ³      *
    497  *  ³                                                               ³      *
    498  *  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ      *
    499  *                                                                         *
    500  * INPUT:                                                                  *
    501  *      none.                                                              *
    502  *                                                                         *
    503  * OUTPUT:                                                                 *
    504  *      0 = OK, -1 = cancel                                                *
    505  *                                                                         *
    506  * WARNINGS:                                                               *
    507  *      CurTeam must NOT be NULL when this function is called.             *
    508  *      This routine invokes the Members dialog, which uses HIDBUFF.       *
    509  *                                                                         *
    510  * HISTORY:                                                                *
    511  *   12/08/1994 BR : Created.                                              *
    512  *=========================================================================*/
    513 int MapEditClass::Edit_Team(void)
    514 {
    515 	/*........................................................................
    516 	Dialog & button dimensions
    517 	........................................................................*/
    518 	enum {
    519 		D_DIALOG_W = 516,
    520 		D_DIALOG_H = 376,
    521 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
    522 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
    523 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
    524 
    525 		D_TXT8_H = 22,
    526 		D_MARGIN = 14,
    527 
    528 		D_NAME_W = 120,
    529 		D_NAME_H = 18,
    530 		D_NAME_X = D_DIALOG_X + D_MARGIN + 100,
    531 		D_NAME_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H,
    532 
    533 		D_PRIORITY_W = 120,
    534 		D_PRIORITY_H = 18,
    535 		D_PRIORITY_X = D_DIALOG_X + D_MARGIN + 100,
    536 		D_PRIORITY_Y = D_NAME_Y + D_NAME_H,
    537 
    538 		D_MAXNUM_W = 120,
    539 		D_MAXNUM_H = 18,
    540 		D_MAXNUM_X = D_DIALOG_X + D_MARGIN + 100,
    541 		D_MAXNUM_Y = D_PRIORITY_Y + D_PRIORITY_H,
    542 
    543 		D_INITNUM_W = 120,
    544 		D_INITNUM_H = 18,
    545 		D_INITNUM_X = D_DIALOG_X + D_MARGIN + 100,
    546 		D_INITNUM_Y = D_MAXNUM_Y + D_MAXNUM_H,
    547 
    548 		D_FEAR_W = 120,
    549 		D_FEAR_H = 18,
    550 		D_FEAR_X = D_DIALOG_X + D_MARGIN + 100,
    551 		D_FEAR_Y = D_INITNUM_Y + D_INITNUM_H,
    552 
    553 		D_GDI_W = 100,
    554 		D_GDI_H = 18,
    555 		D_GDI_X = D_NAME_X + D_NAME_W + D_MARGIN,
    556 		D_GDI_Y = D_NAME_Y + D_NAME_H + D_NAME_H / 2,
    557 
    558 		D_NOD_W = 100,
    559 		D_NOD_H = 18,
    560 		D_NOD_X = D_NAME_X + D_NAME_W + D_MARGIN,
    561 		D_NOD_Y = D_GDI_Y + D_GDI_H,
    562 
    563 		D_NEU_W = 100,
    564 		D_NEU_H = 18,
    565 		D_NEU_X = D_NAME_X + D_NAME_W + D_MARGIN,
    566 		D_NEU_Y = D_NOD_Y + D_NOD_H,
    567 
    568 		D_MULTI1_W = 50,
    569 		D_MULTI1_H = 18,
    570 		D_MULTI1_X = D_GDI_X,
    571 		D_MULTI1_Y = D_GDI_Y,
    572 
    573 		D_MULTI2_W = 50,
    574 		D_MULTI2_H = 18,
    575 		D_MULTI2_X = D_GDI_X + D_MULTI2_W,
    576 		D_MULTI2_Y = D_GDI_Y,
    577 
    578 		D_MULTI3_W = 50,
    579 		D_MULTI3_H = 18,
    580 		D_MULTI3_X = D_NOD_X,
    581 		D_MULTI3_Y = D_NOD_Y,
    582 
    583 		D_MULTI4_W = 50,
    584 		D_MULTI4_H = 18,
    585 		D_MULTI4_X = D_NOD_X + D_MULTI4_W,
    586 		D_MULTI4_Y = D_NOD_Y,
    587 
    588 		D_ROUNDABOUT_W = 130,
    589 		D_ROUNDABOUT_H = 18,
    590 		D_ROUNDABOUT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_ROUNDABOUT_W,
    591 		D_ROUNDABOUT_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H - 10,
    592 
    593 		D_LEARNING_W = D_ROUNDABOUT_W,
    594 		D_LEARNING_H = 18,
    595 		D_LEARNING_X = D_ROUNDABOUT_X,
    596 		D_LEARNING_Y = D_ROUNDABOUT_Y + D_ROUNDABOUT_H,
    597 
    598 		D_SUICIDE_W = D_ROUNDABOUT_W,
    599 		D_SUICIDE_H = 18,
    600 		D_SUICIDE_X = D_ROUNDABOUT_X,
    601 		D_SUICIDE_Y = D_LEARNING_Y + D_LEARNING_H,
    602 
    603 		D_AUTOCREATE_W = D_ROUNDABOUT_W,
    604 		D_AUTOCREATE_H = 18,
    605 		D_AUTOCREATE_X = D_ROUNDABOUT_X,
    606 		D_AUTOCREATE_Y = D_SUICIDE_Y + D_SUICIDE_H,
    607 
    608 		D_MERCENARY_W = D_ROUNDABOUT_W,
    609 		D_MERCENARY_H = 18,
    610 		D_MERCENARY_X = D_ROUNDABOUT_X,
    611 		D_MERCENARY_Y = D_AUTOCREATE_Y + D_AUTOCREATE_H,
    612 
    613 		D_PREBUILT_W = D_ROUNDABOUT_W,
    614 		D_PREBUILT_H = 18,
    615 		D_PREBUILT_X = D_ROUNDABOUT_X,
    616 		D_PREBUILT_Y = D_MERCENARY_Y + D_MERCENARY_H,
    617 
    618 		D_REINFORCE_W = D_ROUNDABOUT_W,
    619 		D_REINFORCE_H = 18,
    620 		D_REINFORCE_X = D_ROUNDABOUT_X,
    621 		D_REINFORCE_Y = D_PREBUILT_Y + D_PREBUILT_H,
    622 
    623 		D_MISSION1_W = 180,
    624 		D_MISSION1_H = 128,
    625 		D_MISSION1_X = D_DIALOG_X + D_MARGIN,
    626 		D_MISSION1_Y = D_REINFORCE_Y + D_REINFORCE_H + D_MARGIN,
    627 
    628 		D_MISSION2_W = 180,
    629 		D_MISSION2_H = 128,
    630 		D_MISSION2_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_MISSION2_W,
    631 		D_MISSION2_Y = D_MISSION1_Y,
    632 
    633 		D_ADD_W = 100,
    634 		D_ADD_H = 18,
    635 		D_ADD_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN,
    636 		D_ADD_Y = D_MISSION1_Y + D_ADD_H,
    637 
    638 		D_INSERT_W = 100,
    639 		D_INSERT_H = 18,
    640 		D_INSERT_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN,
    641 		D_INSERT_Y = D_ADD_Y + D_ADD_H,
    642 
    643 		D_DEL_W = 100,
    644 		D_DEL_H = 18,
    645 		D_DEL_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN,
    646 		D_DEL_Y = D_INSERT_Y + D_INSERT_H,
    647 
    648 		D_ARG_W = 100,
    649 		D_ARG_H = 18,
    650 		D_ARG_X = D_MISSION1_X + D_MISSION1_W + D_MARGIN,
    651 		D_ARG_Y = D_DEL_Y + D_DEL_H,
    652 
    653 		D_MEMBERS_W = 100,
    654 		D_MEMBERS_H = 18,
    655 		D_MEMBERS_X = D_DIALOG_X + (D_DIALOG_W / 6) - D_MEMBERS_W / 2,
    656 		D_MEMBERS_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_MEMBERS_H,
    657 
    658 		D_CANCEL_W = 100,
    659 		D_CANCEL_H = 18,
    660 		D_CANCEL_X = D_DIALOG_X + (D_DIALOG_W / 6) * 3 - D_CANCEL_W / 2,
    661 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_CANCEL_H,
    662 
    663 		D_OK_W = 100,
    664 		D_OK_H = 18,
    665 		D_OK_X = D_DIALOG_X + (D_DIALOG_W / 6) * 5 - D_OK_W / 2,
    666 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_MARGIN - D_OK_H,
    667 	};
    668 
    669 	/*........................................................................
    670 	Button enumerations:
    671 	........................................................................*/
    672 	enum {
    673 		BUTTON_NAME=100,
    674 		BUTTON_RECRUIT,
    675 		BUTTON_MAXNUM,
    676 		BUTTON_INITNUM,
    677 		BUTTON_FEAR,
    678 		BUTTON_GDI,
    679 		BUTTON_NOD,
    680 		BUTTON_NEU,
    681 		BUTTON_JP,			// placeholder
    682 		BUTTON_MULTI1,
    683 		BUTTON_MULTI2,
    684 		BUTTON_MULTI3,
    685 		BUTTON_MULTI4,
    686 		BUTTON_MULTI5,
    687 		BUTTON_MULTI6,
    688 		BUTTON_ROUNDABOUT,
    689 		BUTTON_LEARNING,
    690 		BUTTON_SUICIDE,
    691 		BUTTON_AUTO,
    692 		BUTTON_MERCENARY,
    693 		BUTTON_PREBUILT,
    694 		BUTTON_REINFORCE,
    695 		BUTTON_MISSION1,
    696 		BUTTON_MISSION2,
    697 		BUTTON_ADD,
    698 		BUTTON_INSERT,
    699 		BUTTON_DEL,
    700 		BUTTON_ARG,
    701 		BUTTON_MEMBERS,
    702 		BUTTON_OK,
    703 		BUTTON_CANCEL,
    704 	};
    705 
    706 	/*........................................................................
    707 	Redraw values: in order from "top" to "bottom" layer of the dialog
    708 	........................................................................*/
    709 	typedef enum {
    710 		REDRAW_NONE = 0,
    711 		REDRAW_BUTTONS,
    712 		REDRAW_BACKGROUND,
    713 		REDRAW_ALL = REDRAW_BACKGROUND
    714 	} RedrawType;
    715 
    716 	/*........................................................................
    717 	Dialog variables:
    718 	........................................................................*/
    719 	RedrawType display;							// requested redraw level
    720 	bool process;									// loop while true
    721 	KeyNumType input;
    722 	bool cancel = false;							// true = user cancels
    723 	char name_buf[12];
    724 	char recr_buf[4];
    725 	char maxnum_buf[4];
    726 	char initnum_buf[4];
    727 	char fear_buf[4];
    728 	HousesType house;
    729 	int roundabout;
    730 	int learning;
    731 	int suicide;
    732 	int autocreate;
    733 	int mercenary;
    734 	int prebuilt;
    735 	int reinforce;
    736 	int missioncount;
    737 	TeamMissionStruct missions[TeamTypeClass::MAX_TEAM_MISSIONS];
    738 	char missionbuf[TeamTypeClass::MAX_TEAM_MISSIONS][20];
    739 	int curmission;					// currently-selected mission index
    740 
    741 	char arg_buf[4] = {0};
    742 	static int tabs[] = {130, 180};		// list box tab stops
    743 	int i,j;
    744 
    745 	/*........................................................................
    746 	Buttons:
    747 	........................................................................*/
    748 	ControlClass *commands;
    749 	EditClass name_edt (BUTTON_NAME,
    750 		name_buf, 8,
    751 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    752 		D_NAME_X, D_NAME_Y, D_NAME_W, D_NAME_H, EditClass::ALPHANUMERIC);
    753 
    754 	EditClass recr_edt (BUTTON_RECRUIT,
    755 		recr_buf, 3,
    756 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    757 		D_PRIORITY_X, D_PRIORITY_Y, D_PRIORITY_W, D_PRIORITY_H, EditClass::NUMERIC);
    758 
    759 	EditClass maxnum_edt (BUTTON_MAXNUM,
    760 		maxnum_buf, 3,
    761 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    762 		D_MAXNUM_X, D_MAXNUM_Y, D_MAXNUM_W, D_MAXNUM_H, EditClass::NUMERIC);
    763 
    764 	EditClass initnum_edt (BUTTON_INITNUM,
    765 		initnum_buf, 3,
    766 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    767 		D_INITNUM_X, D_INITNUM_Y, D_INITNUM_W, D_INITNUM_H, EditClass::NUMERIC);
    768 
    769 	EditClass fear_edt (BUTTON_FEAR,
    770 		fear_buf, 3,
    771 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    772 		D_FEAR_X, D_FEAR_Y, D_FEAR_W, D_FEAR_H, EditClass::NUMERIC);
    773 
    774 	TextButtonClass gdibtn (BUTTON_GDI, "GDI",
    775 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    776 		D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H);
    777 
    778 	TextButtonClass nodbtn (BUTTON_NOD, "NOD",
    779 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    780 		D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H);
    781 
    782 	TextButtonClass neubtn (BUTTON_NEU, "NEUTRAL",
    783 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    784 		D_NEU_X, D_NEU_Y, D_NEU_W, D_NEU_H);
    785 
    786 	TextButtonClass multi1btn (BUTTON_MULTI1, "M1",
    787 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    788 		D_MULTI1_X, D_MULTI1_Y, D_MULTI1_W, D_MULTI1_H);
    789 
    790 	TextButtonClass multi2btn (BUTTON_MULTI2, "M2",
    791 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    792 		D_MULTI2_X, D_MULTI2_Y, D_MULTI2_W, D_MULTI2_H);
    793 
    794 	TextButtonClass multi3btn (BUTTON_MULTI3, "M3",
    795 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    796 		D_MULTI3_X, D_MULTI3_Y, D_MULTI3_W, D_MULTI3_H);
    797 
    798 	TextButtonClass multi4btn (BUTTON_MULTI4, "M4",
    799 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    800 		D_MULTI4_X, D_MULTI4_Y, D_MULTI4_W, D_MULTI4_H);
    801 
    802 	TextButtonClass roundbtn (BUTTON_ROUNDABOUT, "Roundabout",
    803 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    804 		D_ROUNDABOUT_X, D_ROUNDABOUT_Y, D_ROUNDABOUT_W, D_ROUNDABOUT_H);
    805 
    806 	TextButtonClass learnbtn (BUTTON_LEARNING, "Learning",
    807 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    808 		D_LEARNING_X, D_LEARNING_Y, D_LEARNING_W, D_LEARNING_H);
    809 
    810 	TextButtonClass suicidebtn (BUTTON_SUICIDE, "Suicide",
    811 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    812 		D_SUICIDE_X, D_SUICIDE_Y, D_SUICIDE_W, D_SUICIDE_H);
    813 
    814 	TextButtonClass autocreatebtn (BUTTON_AUTO, "Autocreate",
    815 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    816 		D_AUTOCREATE_X, D_AUTOCREATE_Y, D_AUTOCREATE_W, D_AUTOCREATE_H);
    817 
    818 	TextButtonClass mercbtn (BUTTON_MERCENARY, "Mercenary",
    819 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    820 		D_MERCENARY_X, D_MERCENARY_Y, D_MERCENARY_W, D_MERCENARY_H);
    821 
    822 	TextButtonClass prebuiltbtn (BUTTON_PREBUILT, "Prebuild",
    823 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    824 		D_PREBUILT_X, D_PREBUILT_Y, D_PREBUILT_W, D_PREBUILT_H);
    825 
    826 	TextButtonClass reinforcebtn (BUTTON_REINFORCE, "Reinforce",
    827 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    828 		D_REINFORCE_X, D_REINFORCE_Y, D_REINFORCE_W, D_REINFORCE_H);
    829 
    830 	ListClass missionlist1 (BUTTON_MISSION1,
    831 		D_MISSION1_X, D_MISSION1_Y, D_MISSION1_W, D_MISSION1_H,
    832 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    833 		Hires_Retrieve("BTN-UP.SHP"),
    834 		Hires_Retrieve("BTN-DN.SHP"));
    835 
    836 	ListClass missionlist2 (BUTTON_MISSION2,
    837 		D_MISSION2_X, D_MISSION2_Y, D_MISSION2_W, D_MISSION2_H,
    838 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    839 		Hires_Retrieve("BTN-UP.SHP"),
    840 		Hires_Retrieve("BTN-DN.SHP"));
    841 
    842 	TextButtonClass addbtn (BUTTON_ADD, "Add >>",
    843 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    844 		D_ADD_X, D_ADD_Y, D_ADD_W, D_ADD_H);
    845 
    846 	TextButtonClass insertbtn (BUTTON_INSERT, "Insert",
    847 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    848 		D_INSERT_X, D_INSERT_Y, D_INSERT_W, D_INSERT_H);
    849 
    850 	TextButtonClass delbtn (BUTTON_DEL, "Delete",
    851 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    852 		D_DEL_X, D_DEL_Y, D_DEL_W, D_DEL_H);
    853 
    854 	EditClass arg_edt (BUTTON_ARG, arg_buf, 4,
    855 		TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    856 		D_ARG_X, D_ARG_Y, D_ARG_W, D_ARG_H, EditClass::ALPHANUMERIC);
    857 
    858 	TextButtonClass membersbtn (BUTTON_MEMBERS, "Members",
    859 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    860 		D_MEMBERS_X, D_MEMBERS_Y, D_MEMBERS_W, D_MEMBERS_H);
    861 
    862 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
    863 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    864 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
    865 
    866 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
    867 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    868 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
    869 
    870 	/*
    871 	------------------------------- Initialize -------------------------------
    872 	*/
    873 	Set_Logic_Page(SeenBuff);
    874 
    875 	/*
    876 	........................... Copy team's state ............................
    877 	*/
    878 	strcpy(name_buf,CurTeam->IniName);
    879 	sprintf(recr_buf,"%d",CurTeam->RecruitPriority);
    880 	sprintf(maxnum_buf,"%d",CurTeam->MaxAllowed);
    881 	sprintf(initnum_buf,"%d",CurTeam->InitNum);
    882 	sprintf(fear_buf,"%d",CurTeam->Fear);
    883 	roundabout = CurTeam->IsRoundAbout;
    884 	learning = CurTeam->IsLearning;
    885 	suicide = CurTeam->IsSuicide;
    886 	house = CurTeam->House;
    887 	autocreate = CurTeam->IsAutocreate;
    888 	mercenary = CurTeam->IsMercenary;
    889 	prebuilt = CurTeam->IsPrebuilt;
    890 	reinforce = CurTeam->IsReinforcable;
    891 
    892 	/*
    893 	......................... Fill in mission lists ..........................
    894 	*/
    895 	for (i = 0; i < TMISSION_COUNT; i++) {
    896 		missionlist1.Add_Item(TeamTypeClass::Name_From_Mission((TeamMissionType)i));
    897 	}
    898 
    899 	missioncount = CurTeam->MissionCount;
    900 	for (i = 0; i < missioncount; i++) {
    901 		missions[i] = CurTeam->MissionList[i];
    902 	}
    903 	Build_Mission_List(missioncount, missions, missionbuf, &missionlist2);
    904 
    905 	curmission = 0;
    906 	if (missioncount) {
    907 		if (missions[curmission].Mission == TMISSION_MOVE || missions[curmission].Mission == TMISSION_UNLOAD) {
    908 			sprintf(arg_buf,"%c",missions[curmission].Argument + 'A');
    909 		} else {
    910 			sprintf(arg_buf,"%d",missions[curmission].Argument);
    911 		}
    912 	}
    913 	missionlist2.Set_Tabs(tabs);
    914 
    915 	/*
    916 	......................... Init the button states .........................
    917 	*/
    918 	name_edt.Set_Text(name_buf,8);
    919 	recr_edt.Set_Text(recr_buf,3);
    920 	maxnum_edt.Set_Text(maxnum_buf,3);
    921 	initnum_edt.Set_Text(initnum_buf,3);
    922 	fear_edt.Set_Text(fear_buf,3);
    923 	arg_edt.Set_Text(arg_buf,3);
    924 
    925 	if (roundabout) {
    926 		roundbtn.Turn_On();
    927 	}
    928 	if (learning) {
    929 		learnbtn.Turn_On();
    930 	}
    931 	if (suicide) {
    932 		suicidebtn.Turn_On();
    933 	}
    934 	if (autocreate) {
    935 		autocreatebtn.Turn_On();
    936 	}
    937 	if (mercenary) {
    938 		mercbtn.Turn_On();
    939 	}
    940 	if (reinforce) {
    941 		reinforcebtn.Turn_On();
    942 	}
    943 	if (prebuilt) {
    944 		prebuiltbtn.Turn_On();
    945 	}
    946 
    947 	/*
    948 	............................ Create the list .............................
    949 	*/
    950 	commands = &okbtn;
    951 	cancelbtn.Add_Tail(*commands);
    952 	membersbtn.Add_Tail(*commands);
    953 
    954 	name_edt.Add_Tail(*commands);
    955 	recr_edt.Add_Tail(*commands);
    956 	maxnum_edt.Add_Tail(*commands);
    957 	initnum_edt.Add_Tail(*commands);
    958 	fear_edt.Add_Tail(*commands);
    959 
    960 	gdibtn.Add_Tail(*commands);
    961 	nodbtn.Add_Tail(*commands);
    962 	neubtn.Add_Tail(*commands);
    963 
    964 	roundbtn.Add_Tail(*commands);
    965 	learnbtn.Add_Tail(*commands);
    966 	suicidebtn.Add_Tail(*commands);
    967 	autocreatebtn.Add_Tail(*commands);
    968 	mercbtn.Add_Tail(*commands);
    969 	prebuiltbtn.Add_Tail(*commands);
    970 	reinforcebtn.Add_Tail(*commands);
    971 
    972 	missionlist1.Add_Tail(*commands);
    973 	missionlist2.Add_Tail(*commands);
    974 	addbtn.Add_Tail(*commands);
    975 	insertbtn.Add_Tail(*commands);
    976 	delbtn.Add_Tail(*commands);
    977 	arg_edt.Add_Tail(*commands);
    978 
    979 	Set_House_Buttons (house, commands, BUTTON_GDI);
    980 
    981 	/*
    982 	-------------------------- Main Processing Loop --------------------------
    983 	*/
    984 	display = REDRAW_ALL;
    985 	process = true;
    986 	while (process) {
    987 		/*
    988 		** If we have just received input focus again after running in the background then
    989 		** we need to redraw.
    990 		*/
    991 		if (AllSurfaces.SurfacesRestored){
    992 			AllSurfaces.SurfacesRestored=FALSE;
    993 			display=REDRAW_ALL;
    994 		}
    995 
    996 		/*
    997 		........................ Invoke game callback .........................
    998 		*/
    999 		Call_Back();
   1000 
   1001 		/*
   1002 		...................... Refresh display if needed ......................
   1003 		*/
   1004 		if (display) {
   1005 
   1006 			/*
   1007 			...................... Display the dialog box ......................
   1008 			*/
   1009 			Hide_Mouse();
   1010 			if (display >= REDRAW_BACKGROUND) {
   1011 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
   1012 
   1013 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
   1014 				/*
   1015 				....................... Draw the captions .......................
   1016 				*/
   1017 				Fancy_Text_Print("Team Edit", D_DIALOG_CX, D_DIALOG_Y + D_MARGIN,
   1018 					CC_GREEN, TBLACK,
   1019 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1020 
   1021 				Fancy_Text_Print("Name", D_NAME_X - 5, D_NAME_Y,
   1022 					CC_GREEN, TBLACK,
   1023 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1024 
   1025 				Fancy_Text_Print("Priority", D_PRIORITY_X - 5, D_PRIORITY_Y,
   1026 					CC_GREEN, TBLACK,
   1027 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1028 
   1029 				Fancy_Text_Print("Max Num", D_MAXNUM_X - 5, D_MAXNUM_Y,
   1030 					CC_GREEN, TBLACK,
   1031 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1032 
   1033 				Fancy_Text_Print("Init Num", D_INITNUM_X - 5, D_INITNUM_Y,
   1034 					CC_GREEN, TBLACK,
   1035 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1036 
   1037 				Fancy_Text_Print("Fear", D_FEAR_X - 5, D_FEAR_Y,
   1038 					CC_GREEN, TBLACK,
   1039 					TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
   1040 			}
   1041 			/*
   1042 			........................ Redraw the buttons ........................
   1043 			*/
   1044 			if (display >= REDRAW_BUTTONS) {
   1045 				commands->Draw_All();
   1046 			}
   1047 			Show_Mouse();
   1048 			display = REDRAW_NONE;
   1049 		}
   1050 
   1051 		/*
   1052 		........................... Get user input ............................
   1053 		*/
   1054 		input = commands->Input();
   1055 
   1056 		/*
   1057 		............................ Process input ............................
   1058 		*/
   1059 		switch (input) {
   1060 			case (BUTTON_NAME | KN_BUTTON):
   1061 				break;
   1062 
   1063 			case (BUTTON_RECRUIT | KN_BUTTON):
   1064 				break;
   1065 
   1066 			case (BUTTON_MAXNUM | KN_BUTTON):
   1067 				break;
   1068 
   1069 			case (BUTTON_INITNUM | KN_BUTTON):
   1070 				break;
   1071 
   1072 			case (BUTTON_FEAR | KN_BUTTON):
   1073 				break;
   1074 
   1075 			/*..................................................................
   1076 			Toggle RoundAbout
   1077 			..................................................................*/
   1078 			case (BUTTON_ROUNDABOUT | KN_BUTTON):
   1079 				if (roundabout) {
   1080 					roundabout = 0;
   1081 					roundbtn.Turn_Off();
   1082 				} else {
   1083 					roundabout = 1;
   1084 					roundbtn.Turn_On();
   1085 				}
   1086 				break;
   1087 
   1088 			/*..................................................................
   1089 			Toggle Learning
   1090 			..................................................................*/
   1091 			case (BUTTON_LEARNING | KN_BUTTON):
   1092 				if (learning) {
   1093 					learning = 0;
   1094 					learnbtn.Turn_Off();
   1095 				} else {
   1096 					learning = 1;
   1097 					learnbtn.Turn_On();
   1098 				}
   1099 				break;
   1100 
   1101 			/*..................................................................
   1102 			Toggle Suicide
   1103 			..................................................................*/
   1104 			case (BUTTON_SUICIDE | KN_BUTTON):
   1105 				if (suicide) {
   1106 					suicide = 0;
   1107 					suicidebtn.Turn_Off();
   1108 				} else {
   1109 					suicide = 1;
   1110 					suicidebtn.Turn_On();
   1111 				}
   1112 				break;
   1113 
   1114 			/*..................................................................
   1115 			Toggle Spy
   1116 			..................................................................*/
   1117 			case (BUTTON_AUTO | KN_BUTTON):
   1118 				if (autocreate) {
   1119 					autocreate = 0;
   1120 					autocreatebtn.Turn_Off();
   1121 				} else {
   1122 					autocreate = 1;
   1123 					autocreatebtn.Turn_On();
   1124 				}
   1125 				break;
   1126 
   1127 			/*..................................................................
   1128 			Toggle Mercenary
   1129 			..................................................................*/
   1130 			case (BUTTON_MERCENARY | KN_BUTTON):
   1131 				if (mercenary) {
   1132 					mercenary = 0;
   1133 					mercbtn.Turn_Off();
   1134 				} else {
   1135 					mercenary = 1;
   1136 					mercbtn.Turn_On();
   1137 				}
   1138 				break;
   1139 
   1140 			case (BUTTON_PREBUILT | KN_BUTTON):
   1141 				if (prebuilt) {
   1142 					prebuilt = 0;
   1143 					prebuiltbtn.Turn_Off();
   1144 				} else {
   1145 					prebuilt = 1;
   1146 					prebuiltbtn.Turn_On();
   1147 				}
   1148 				break;
   1149 
   1150 			case (BUTTON_REINFORCE | KN_BUTTON):
   1151 				if (reinforce) {
   1152 					reinforce = 0;
   1153 					reinforcebtn.Turn_Off();
   1154 				} else {
   1155 					reinforce = 1;
   1156 					reinforcebtn.Turn_On();
   1157 				}
   1158 				break;
   1159 
   1160 			/*..................................................................
   1161 			Select a Mission on the left-hand mission list
   1162 			..................................................................*/
   1163 			case (BUTTON_MISSION1 | KN_BUTTON):
   1164 				break;
   1165 
   1166 			/*..................................................................
   1167 			Select a Mission on the right-hand mission list; update the Argument
   1168 			field to reflect the current value
   1169 			..................................................................*/
   1170 			case (BUTTON_MISSION2 | KN_BUTTON):
   1171 				if (missionlist2.Count() > 0 &&
   1172 					missionlist2.Current_Index() != curmission) {
   1173 					curmission = missionlist2.Current_Index();
   1174 					if (missions[curmission].Mission==TMISSION_MOVE || missions[curmission].Mission == TMISSION_UNLOAD) {
   1175 						sprintf(arg_buf,"%c",missions[curmission].Argument + 'A');
   1176 					} else {
   1177 						sprintf(arg_buf,"%d",missions[curmission].Argument);
   1178 					}
   1179 					arg_edt.Set_Text(arg_buf,3);
   1180 				}
   1181 				break;
   1182 
   1183 			/*..................................................................
   1184 			Copy mission from left list box to right list box
   1185 			..................................................................*/
   1186 			case (BUTTON_ADD | KN_BUTTON):
   1187 			case (BUTTON_INSERT | KN_BUTTON):
   1188 				if (missioncount < TeamTypeClass::MAX_TEAM_MISSIONS) {
   1189 					/*
   1190 					** Set 'i' to the position we're going to add into; this will
   1191 					** be just AFTER the current item if we're adding, and it will
   1192 					** be the current item if we're inserting.
   1193 					*/
   1194 					if (input == (BUTTON_ADD | KN_BUTTON)) {
   1195 						i = missionlist2.Current_Index() + 1;
   1196 						if (i < 0) {
   1197 							i = 0;
   1198 						}
   1199 						if (i > missioncount) {
   1200 							i = missioncount;
   1201 						}
   1202 					} else {
   1203 						i = missionlist2.Current_Index();
   1204 						if (i < 0) {
   1205 							i = 0;
   1206 						}
   1207 						if (i >= missioncount && missioncount > 0) {
   1208 							i = missioncount - 1;
   1209 						}
   1210 					}
   1211 
   1212 					/*
   1213 					** Move all other missions forward in the array
   1214 					*/
   1215 					for (j = missioncount; j > i; j--) {
   1216 						missions[j] = missions[j - 1];
   1217 					}
   1218 
   1219 					/*
   1220 					** Set the Mission value based on 1st list box's index
   1221 					*/
   1222 					missions[i].Mission = (TeamMissionType)(TMISSION_FIRST + missionlist1.Current_Index());
   1223 
   1224 					/*
   1225 					** Set the missions argument field
   1226 					*/
   1227 					if (missions[i].Mission == TMISSION_MOVE || missions[i].Mission == TMISSION_UNLOAD) {
   1228 						missions[i].Argument = toupper(arg_buf[0]) - 'A';
   1229 					} else {
   1230 						missions[i].Argument = atoi(arg_buf);
   1231 					}
   1232 					missioncount++;
   1233 
   1234 					/*
   1235 					** Rebuild the list box from scratch
   1236 					*/
   1237 					Build_Mission_List(missioncount, missions, missionbuf, &missionlist2);
   1238 
   1239 					/*
   1240 					** Update the list's current item index
   1241 					*/
   1242 					missionlist2.Set_Selected_Index(i);
   1243 				}
   1244 				break;
   1245 
   1246 			/*..................................................................
   1247 			Delete mission from right-hand list box
   1248 			..................................................................*/
   1249 			case (BUTTON_DEL | KN_BUTTON):
   1250 				if (missioncount > 0) {
   1251 					i = missionlist2.Current_Index();
   1252 					if (i < 0 || i >= missioncount) {
   1253 						break;
   1254 					}
   1255 
   1256 					/*
   1257 					** Move all missions back in the array
   1258 					*/
   1259 					for (j = i; j < missioncount - 1; j++) {
   1260 						missions[j] = missions[j + 1];
   1261 					}
   1262 					missioncount--;
   1263 
   1264 					/*
   1265 					** Rebuild the list box from scratch
   1266 					*/
   1267 					Build_Mission_List(missioncount, missions, missionbuf, &missionlist2);
   1268 
   1269 					/*
   1270 					** Update the list's current item index
   1271 					*/
   1272 					if (i >= missioncount) {
   1273 						i--;
   1274 						if (i < 0) {
   1275 							i = 0;
   1276 						}
   1277 						missionlist2.Set_Selected_Index(i);
   1278 					}
   1279 				}
   1280 				break;
   1281 
   1282 			/*..................................................................
   1283 			Set house
   1284 			..................................................................*/
   1285 			case (BUTTON_GDI | KN_BUTTON):
   1286 			case (BUTTON_NOD | KN_BUTTON):
   1287 			case (BUTTON_NEU | KN_BUTTON):
   1288 			case (BUTTON_MULTI1 | KN_BUTTON):
   1289 			case (BUTTON_MULTI2 | KN_BUTTON):
   1290 			case (BUTTON_MULTI3 | KN_BUTTON):
   1291 			case (BUTTON_MULTI4 | KN_BUTTON):
   1292 				house = (HousesType)( (input & (~KN_BUTTON)) - BUTTON_GDI);
   1293 				Set_House_Buttons(house, commands, BUTTON_GDI);
   1294 				break;
   1295 
   1296 			/*..................................................................
   1297 			Invoke the members dialog
   1298 			..................................................................*/
   1299 			case (BUTTON_MEMBERS | KN_BUTTON):
   1300 				/*
   1301 				.................... Take editor focus away .....................
   1302 				*/
   1303 				membersbtn.Turn_Off();
   1304 
   1305 				/*
   1306 				....................... Invoke the dialog .......................
   1307 				*/
   1308 				Team_Members(house);
   1309 
   1310 				/*
   1311 				............................ Redraw .............................
   1312 				*/
   1313 				display = REDRAW_ALL;
   1314 				break;
   1315 
   1316 			/*..................................................................
   1317 			OK: return
   1318 			..................................................................*/
   1319 			case (BUTTON_OK | KN_BUTTON):
   1320 				cancel = false;
   1321 				process = false;
   1322 				break;
   1323 
   1324 			/*..................................................................
   1325 			Cancel: return
   1326 			..................................................................*/
   1327 			case (BUTTON_CANCEL | KN_BUTTON):
   1328 				cancel = true;
   1329 				process = false;
   1330 				break;
   1331 
   1332 			/*..................................................................
   1333 			Pass all other events to the currently-active text editor
   1334 			..................................................................*/
   1335 			default:
   1336 				break;
   1337 		}
   1338 	}
   1339 
   1340 	/*
   1341 	--------------------------- Redraw the display ---------------------------
   1342 	*/
   1343 	HiddenPage.Clear();
   1344 	Flag_To_Redraw(true);
   1345 	Render();
   1346 
   1347 	/*
   1348 	------------------------- If cancel, just return -------------------------
   1349 	*/
   1350 	if (cancel) {
   1351 		return(-1);
   1352 	}
   1353 
   1354 	/*
   1355 	------------------------ Save selections & return ------------------------
   1356 	*/
   1357 	CurTeam->Set_Name(name_buf);
   1358 	CurTeam->RecruitPriority = atoi(recr_buf);
   1359 	CurTeam->MaxAllowed = atoi(maxnum_buf);
   1360 	CurTeam->InitNum = atoi(initnum_buf);
   1361 	CurTeam->IsRoundAbout = roundabout;
   1362 	CurTeam->IsLearning = learning;
   1363 	CurTeam->IsSuicide = suicide;
   1364 	CurTeam->IsAutocreate = autocreate;
   1365 	CurTeam->IsPrebuilt = prebuilt;
   1366 	CurTeam->IsReinforcable = reinforce;
   1367 	CurTeam->IsMercenary = mercenary;
   1368 	CurTeam->House = house;
   1369 	CurTeam->MissionCount = missioncount;
   1370 	for (i = 0 ; i < missioncount; i++) {
   1371 		CurTeam->MissionList[i] = missions[i];
   1372 	}
   1373 
   1374 	return(0);
   1375 }
   1376 
   1377 
   1378 /***************************************************************************
   1379  * MapEditClass::Team_Members -- user picks makeup of a team               *
   1380  *                                                                         *
   1381  * Team members are rendered in a 24 x 24 area; the Window coordinates     *
   1382  * have to be set to this area when the object's 'Display()' routine is    *
   1383  * called. Thus, the dialog's window coords have to be divisible by        *
   1384  * 24. The height of the dialog is computed based on how many objects      *
   1385  * there are in it.                                                        *
   1386  *                                                                         *
   1387  * 10 pixels are left between rows of objects, so the # of that type of    *
   1388  * object can be displayed underneath the object.                          *
   1389  *                                                                         *
   1390  *  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                    *
   1391  *  ³                 Team Members                    ³                    *
   1392  *  ³                                                 ³                    *
   1393  *  ³  ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿  ³                    *
   1394  *  ³  ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³  ³                    *
   1395  *  ³  ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´  ³                    *
   1396  *  ³  ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³  ³                    *
   1397  *  ³  ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´  ³                    *
   1398  *  ³  ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³  ³                    *
   1399  *  ³  ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´  ³                    *
   1400  *  ³  ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³  ³                    *
   1401  *  ³  ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´  ³                    *
   1402  *  ³  ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³  ³                    *
   1403  *  ³  ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´  ³                    *
   1404  *  ³  ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³   ³  ³                    *
   1405  *  ³  ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ  ³                    *
   1406  *  ³               [OK]      [Cancel]                ³                    *
   1407  *  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                    *
   1408  *                                                                         *
   1409  * INPUT:                                                                  *
   1410  *      house      house to display objects for                            *
   1411  *                                                                         *
   1412  * OUTPUT:                                                                 *
   1413  *      0 = OK, -1 = cancel                                                *
   1414  *                                                                         *
   1415  * WARNINGS:                                                               *
   1416  *      CurTeam must NOT be NULL when this function is called.             *
   1417  *      This routine uses HIDBUFF for data storage.                        *
   1418  *                                                                         *
   1419  * HISTORY:                                                                *
   1420  *   12/07/1994 BR : Created.                                              *
   1421  *=========================================================================*/
   1422 #define TEENSY_WEENSY
   1423 /*
   1424 **	Dialog & button dimensions
   1425 */
   1426 enum {
   1427 	D_DIALOG_W = 608,
   1428 	D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
   1429 	D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
   1430 
   1431 	D_TXT6_H = 14,
   1432 	D_MARGIN = 14,
   1433 
   1434 #ifdef TEENSY_WEENSY
   1435 	//D_PICTURE_W = 32,
   1436 	//D_PICTURE_H = 24,
   1437 	D_PICTURE_W = 64,				// 9 pictures / row, 16 pixel margin on each side
   1438 	D_PICTURE_H = 48,
   1439 #else
   1440 	//D_PICTURE_W = 32,
   1441 	//D_PICTURE_H = 30,
   1442 	D_PICTURE_W = 64,
   1443 	D_PICTURE_H = 60,
   1444 #endif
   1445 	D_ROW_H = (D_PICTURE_H + 6),
   1446 
   1447 	D_OK_W = 100,
   1448 	D_OK_H = 18,
   1449 	D_OK_X = D_DIALOG_CX - 10 - D_OK_W,
   1450 	D_OK_Y = 0,
   1451 
   1452 	D_CANCEL_W = 100,
   1453 	D_CANCEL_H = 18,
   1454 	D_CANCEL_X = D_DIALOG_CX + 10,
   1455 	D_CANCEL_Y = 0,
   1456 
   1457 };
   1458 
   1459 /*************************************************************************** 
   1460  * MapEditClass::Team_Members -- Team members dialog                       * 
   1461  *                                                                         * 
   1462  * INPUT:                                                                  * 
   1463  *		house			house to show members for											*
   1464  *                                                                         * 
   1465  * OUTPUT:                                                                 * 
   1466  *		0 = OK, -1 = cancel																	*
   1467  *                                                                         * 
   1468  * WARNINGS:                                                               * 
   1469  *		none.																						*
   1470  *                                                                         * 
   1471  * HISTORY:                                                                * 
   1472  *   04/09/1996 BRR : Created.                                             * 
   1473  *=========================================================================*/
   1474 int MapEditClass::Team_Members(HousesType house)
   1475 {
   1476 	/*
   1477 	**	Button enumerations:
   1478 	*/
   1479 	enum {
   1480 		BUTTON_OK = 100,
   1481 		BUTTON_CANCEL,
   1482 	};
   1483 
   1484 	/*
   1485 	**	Redraw values: in order from "top" to "bottom" layer of the dialog
   1486 	**	(highest enum is the lowest layer). Each section of the map checks
   1487 	**	the requested redraw level to see if it's supposed to draw; if it's
   1488 	**	>= its level, it redraws.
   1489 	*/
   1490 	typedef enum {
   1491 		REDRAW_NONE = 0,
   1492 		REDRAW_BUTTONS,
   1493 		REDRAW_BACKGROUND,
   1494 		REDRAW_ALL = REDRAW_BACKGROUND
   1495 	} RedrawType;
   1496 	RedrawType display;							// requested redraw level
   1497 	bool process;									// loop while true
   1498 
   1499 	/*
   1500 	............................ Dialog variables ............................
   1501 	*/
   1502 	KeyNumType input;								// user input
   1503 	bool cancel = false;							// true = user cancels
   1504 
   1505 	/*
   1506 	......................... Team display variables .........................
   1507 	*/
   1508 	const TechnoTypeClass **teamclass;		// array of team classes
   1509 	int *teamcount;								// array of class counts
   1510 	int numcols;									// # units displayed horizontally
   1511 	int numrows;									// # units displayed vertically
   1512 //	int col;											// horizontal picture index
   1513 //	int row;											// vertical picture index
   1514 //	int x,y;
   1515 
   1516 	/*
   1517 	**	Dialog dimensions.
   1518 	*/
   1519 	int dlg_y;
   1520 	int dlg_h;										// dialog height
   1521 	int dlg_picture_top;							// coord of top of pictures
   1522 	int msg_y;										// y-coord for object names
   1523 
   1524 	/*
   1525 	**	Values for parsing the classes.
   1526 	*/
   1527 	InfantryType i_id;
   1528 	AircraftType a_id;
   1529 	UnitType u_id;
   1530 	int curclass = -1;			// current index into 'teamclass'; can be invalid!
   1531 										// (is based on current mouse position)
   1532 	int numclasses;				// current # classes in the team (limited to <=5)
   1533 	int maxclasses;				// max # classes available
   1534 	int i,j;
   1535 
   1536 	/*
   1537 	**	Values for timing when mouse held down.
   1538 	*/
   1539 	int lheld = 0;
   1540 	int rheld = 0;
   1541 	long tdelay[3] = {5, 20, 0};
   1542 	int tindex = 0;
   1543 	long heldtime;
   1544 
   1545 	/*
   1546 	**	Buttons.
   1547 	*/
   1548 	ControlClass *commands;
   1549 
   1550 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
   1551 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1552 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
   1553 
   1554 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
   1555 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
   1556 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
   1557 
   1558 	/*
   1559 	**	Set up the team data arrays (ObjectTypeClass pointers & count)
   1560 	*/
   1561 	teamclass = (const TechnoTypeClass **)(new TechnoTypeClass *[MAX_TEAM_CLASSES]);
   1562 	teamcount = new int[MAX_TEAM_CLASSES];
   1563 
   1564 	/*
   1565 	**	Fill in the ObjectTypeClass array with all available object type ptrs,
   1566 	**	checking to be sure this house can own the object
   1567 	*/
   1568 	i = 0;
   1569 	for (i_id = INFANTRY_FIRST; i_id < INFANTRY_COUNT; i_id++) {
   1570 		if (Verify_House(house,&InfantryTypeClass::As_Reference(i_id))) {
   1571 			teamclass[i] = &InfantryTypeClass::As_Reference(i_id);
   1572 			i++;
   1573 		}
   1574 	}
   1575 
   1576 	for (a_id = AIRCRAFT_FIRST; a_id < AIRCRAFT_COUNT; a_id++) {
   1577 		if (Verify_House(house,&AircraftTypeClass::As_Reference(a_id))) {
   1578 			teamclass[i] = &AircraftTypeClass::As_Reference(a_id);
   1579 			i++;
   1580 		}
   1581 	}
   1582 
   1583 	for (u_id = UNIT_FIRST; u_id < UNIT_COUNT; u_id++) {
   1584 		if (Verify_House(house,&UnitTypeClass::As_Reference(u_id))) {
   1585 			teamclass[i] = &UnitTypeClass::As_Reference(u_id);
   1586 			i++;
   1587 		}
   1588 	}
   1589 
   1590 	/*
   1591 	**	Save max # classes.
   1592 	*/
   1593 	maxclasses = i;
   1594 
   1595 	/*
   1596 	**	Fill in the 'count' array with data from the current team:
   1597 	**	- For every class in the current team, find that class type in the
   1598 	**	  'teamclass' array & set its count value
   1599 	*/
   1600 	for (j = 0; j < maxclasses; j++) {
   1601 		teamcount[j] = 0;
   1602 	}
   1603 
   1604 	/*
   1605 	**	Loop through all classes in the team.
   1606 	*/
   1607 	for (i = 0; i < CurTeam->ClassCount; i++) {
   1608 
   1609 		/*
   1610 		**	Find this class in our array.
   1611 		*/
   1612 		for (j = 0; j < maxclasses; j++) {
   1613 
   1614 			/*
   1615 			**	Set the count; detect a match between the team's class & the
   1616 			**	'teamclass' array entry by comparing the actual pointers; typeid
   1617 			**	won't work because E1 & E2 are the same type class.
   1618 			*/
   1619 			if (CurTeam->Class[i] == teamclass[j]) {
   1620 				teamcount[j] = CurTeam->DesiredNum[i];
   1621 				break;
   1622 			}
   1623 		}
   1624 	}
   1625 	numclasses = CurTeam->ClassCount;
   1626 
   1627 	/*
   1628 	**	Set up the dialog dimensions based on number of classes we have to draw
   1629 	**
   1630 	**	Compute picture rows & cols.
   1631 	*/
   1632 	numcols = (D_DIALOG_W - 16) / D_PICTURE_W;
   1633 	numrows = (maxclasses + numcols - 1) / numcols;
   1634 
   1635 	//
   1636 	//	Dialog's height = top margin + label + picture rows + 
   1637 	// margin + label + margin + btn
   1638 	//
   1639 	dlg_h = (D_MARGIN + D_TXT6_H + D_MARGIN + (numrows * D_ROW_H) + 
   1640 		D_MARGIN + D_TXT6_H + D_MARGIN + D_OK_H + D_MARGIN);
   1641 	if (dlg_h > 400) {
   1642 		dlg_h = 400;
   1643 	}
   1644 	dlg_y = (400 - dlg_h) / 2;
   1645 	dlg_picture_top = dlg_y + D_MARGIN + D_TXT6_H + D_MARGIN;
   1646 	msg_y = dlg_y + D_MARGIN + D_TXT6_H + D_MARGIN + (numrows * D_ROW_H) + D_MARGIN;
   1647 
   1648 	okbtn.Y = dlg_y + dlg_h - D_MARGIN - D_OK_H;
   1649 	cancelbtn.Y = dlg_y + dlg_h - D_MARGIN - D_CANCEL_H;
   1650 
   1651 	/*
   1652 	**	Draw to SeenBuff.
   1653 	*/
   1654 	Set_Logic_Page(SeenBuff);
   1655 
   1656 	/*
   1657 	**	Make sure 'house' is valid.
   1658 	*/
   1659 	if (house!=HOUSE_GOOD && house!=HOUSE_BAD && house != HOUSE_MULTI1 &&
   1660 		house != HOUSE_MULTI2 && house != HOUSE_MULTI3 && house != HOUSE_MULTI4 ) {
   1661 		if (ScenPlayer == SCEN_PLAYER_MPLAYER) {
   1662 			house = HOUSE_MULTI1;
   1663 		} else {
   1664 			house = HOUSE_GOOD;
   1665 		}
   1666 	}
   1667 
   1668 	/*
   1669 	**	Create the list.
   1670 	*/
   1671 	commands = &okbtn;
   1672 	cancelbtn.Add_Tail(*commands);
   1673 
   1674 	/*
   1675 	**	Main Processing Loop.
   1676 	*/
   1677 	display = REDRAW_ALL;
   1678 	process = true;
   1679 	while (process) {
   1680 
   1681 		/*
   1682 		** If we have just received input focus again after running in the background then
   1683 		** we need to redraw.
   1684 		*/
   1685 		if (AllSurfaces.SurfacesRestored){
   1686 			AllSurfaces.SurfacesRestored=FALSE;
   1687 			display=REDRAW_ALL;
   1688 		}
   1689 
   1690 		/*
   1691 		**	Invoke game callback.
   1692 		*/
   1693 		Call_Back();
   1694 
   1695 		/*
   1696 		**	Refresh display if needed.
   1697 		*/
   1698 		if (display) {
   1699 
   1700 			/*
   1701 			**	Display the dialog box.
   1702 			*/
   1703 			Hide_Mouse();
   1704 			if (display >= REDRAW_BACKGROUND) {
   1705 
   1706 				/*
   1707 				**	Display the constant background of this dialog.
   1708 				*/
   1709 				Dialog_Box(D_DIALOG_X, dlg_y, D_DIALOG_W, dlg_h);
   1710 				Draw_Caption(TXT_NONE, D_DIALOG_X, dlg_y, D_DIALOG_W);
   1711 				Fancy_Text_Print("Team Members", D_DIALOG_CX, dlg_y + D_MARGIN, CC_GREEN, TBLACK,
   1712 					TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
   1713 
   1714 				//
   1715 				//	Draw the objects.
   1716 				//
   1717 				for (i = 0; i < maxclasses; i++) {
   1718 					//
   1719 					//	Display the object along with any count value for it.
   1720 					//
   1721 					Draw_Member(teamclass[i], i, teamcount[i], house, 
   1722 						D_DIALOG_X + 16, dlg_picture_top);
   1723 				}
   1724 
   1725 				if ((unsigned)curclass < maxclasses) {
   1726 					Fancy_Text_Print(teamclass[curclass]->Full_Name(),
   1727 						D_DIALOG_X + D_DIALOG_W / 2, msg_y, CC_TAN, TBLACK,
   1728 						TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
   1729 				}
   1730 			}
   1731 
   1732 			/*
   1733 			**	Redraw the buttons.
   1734 			*/
   1735 			if (display >= REDRAW_BUTTONS) {
   1736 				commands->Draw_All();
   1737 			}
   1738 			Show_Mouse();
   1739 			display = REDRAW_NONE;
   1740 		}
   1741 
   1742 		/*
   1743 		**	Get user input.
   1744 		*/
   1745 		input = commands->Input();
   1746 
   1747 		/*
   1748 		**	Process input.
   1749 		*/
   1750 		switch (input) {
   1751 
   1752 			/*
   1753 			**	Mouse buttons set or clear 'held' values
   1754 			*/
   1755 			case (KN_LMOUSE):
   1756 				if (curclass >= 0 && curclass < maxclasses) {
   1757 					lheld = 1;
   1758 					tindex = 2;
   1759 					heldtime = 0;
   1760 				}
   1761 				break;
   1762 
   1763 			case (KN_RMOUSE):
   1764 				if (curclass >= 0 && curclass < maxclasses) {
   1765 					rheld = 1;
   1766 					tindex = 2;
   1767 					heldtime = 0;
   1768 				}
   1769 				break;
   1770 
   1771 			case ((int)KN_LMOUSE | (int)KN_RLSE_BIT):
   1772 				lheld = 0;
   1773 				break;
   1774 
   1775 			case ((int)KN_RMOUSE | (int)KN_RLSE_BIT):
   1776 				rheld = 0;
   1777 				break;
   1778 
   1779 			/*
   1780 			**	OK: save values & return.
   1781 			*/
   1782 			case (BUTTON_OK | KN_BUTTON):
   1783 				process = false;
   1784 				break;
   1785 
   1786 			/*
   1787 			**	Cancel: abort & return.
   1788 			*/
   1789 			case (BUTTON_CANCEL | KN_BUTTON):
   1790 				cancel = true;
   1791 				process = false;
   1792 				break;
   1793 
   1794 			default:
   1795 				/*
   1796 				**	Compute new 'curclass' based on mouse position.
   1797 				*/
   1798 				i = (Get_Mouse_X() - 16 - D_DIALOG_X) / D_PICTURE_W +
   1799 					((Get_Mouse_Y() - dlg_picture_top) / D_ROW_H) * numcols;
   1800 
   1801 				/*
   1802 				**	If it's changed, update class label.
   1803 				*/
   1804 				if (i != curclass) {
   1805 
   1806 					curclass = i;
   1807 
   1808 					/*
   1809 					**	Clear out the previously printed name of the item.
   1810 					*/
   1811 					Hide_Mouse();
   1812 					LogicPage->Fill_Rect(D_DIALOG_X + 8, msg_y, D_DIALOG_X + D_DIALOG_W - 9, msg_y + D_TXT6_H, BLACK);
   1813 
   1814 					if ((unsigned)curclass < maxclasses) {
   1815 						Fancy_Text_Print(teamclass[curclass]->Full_Name(),
   1816 							D_DIALOG_X + D_DIALOG_W / 2, msg_y,
   1817 							CC_GREEN, TBLACK, 
   1818 							TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
   1819 					}
   1820 
   1821 					/*
   1822 					**	Force buttons to not be held.
   1823 					*/
   1824 					lheld = 0;
   1825 					rheld = 0;
   1826 					Show_Mouse();
   1827 				}
   1828 				break;
   1829 		}
   1830 
   1831 		/*
   1832 		**	Check for a 'held' mouse button; if it's down, and the correct
   1833 		**	amount of time has gone by, increment/decrement the count for the
   1834 		**	current class.
   1835 		*/
   1836 		if (lheld) {
   1837 
   1838 			/*
   1839 			**	The first time in, TickCount - heldtime will be larger than
   1840 			**	tdelay[2], so we increment the count immediately; then, we decrement
   1841 			**	tindex to go to the next time delay, which is longer; then, decr.
   1842 			**	again to go to the 1st time delay which is the shortest.
   1843 			*/
   1844 			if (TickCount.Time() - heldtime > tdelay[tindex]) {
   1845 				heldtime = TickCount.Time();
   1846 				if (tindex) {
   1847 					tindex--;
   1848 				}
   1849 
   1850 				/*
   1851 				**	Detect addition of a new class.
   1852 				*/
   1853 				if (teamcount[curclass]==0) {
   1854 
   1855 					/*
   1856 					**	Don't allow more classes than we can handle.
   1857 					*/
   1858 					if (numclasses == TeamTypeClass::MAX_TEAM_CLASSCOUNT) {
   1859 						continue;
   1860 					}
   1861 					numclasses++;
   1862 				}
   1863 				teamcount[curclass]++;
   1864 
   1865 				/*
   1866 				**	Update number label.
   1867 				*/
   1868 				Draw_Member(teamclass[curclass], curclass, teamcount[curclass], 
   1869 					house, D_DIALOG_X + 16, dlg_picture_top);
   1870 
   1871 			}
   1872 
   1873 		} else {
   1874 
   1875 			if (rheld) {
   1876 
   1877 				/*
   1878 				**	The first time in, TickCount - heldtime will be larger than
   1879 				**	tdelay[2], so we increment the count immediately; then, we decrement
   1880 				**	tindex to go to the next time delay, which is longer; then, decr.
   1881 				**	again to go to the 1st time delay which is the shortest.
   1882 				*/
   1883 				if (TickCount.Time() - heldtime > tdelay[tindex]) {
   1884 					if (tindex) {
   1885 						tindex--;
   1886 					}
   1887 					heldtime = TickCount.Time();
   1888 
   1889 					if (teamcount[curclass] > 0) {
   1890 						teamcount[curclass]--;
   1891 
   1892 						/*
   1893 						**	Detect removal of a class.
   1894 						*/
   1895 						if (teamcount[curclass] == 0) {
   1896 							numclasses--;
   1897 						}
   1898 					}
   1899 
   1900 					/*
   1901 					**	Update number label.
   1902 					*/
   1903 					Draw_Member(teamclass[curclass], curclass, teamcount[curclass], 
   1904 						house, D_DIALOG_X + 16, dlg_picture_top);
   1905 
   1906 				}
   1907 			}
   1908 		}
   1909 	}
   1910 
   1911 	/*
   1912 	**	Copy data into team.
   1913 	*/
   1914 	if (!cancel) {
   1915 		CurTeam->ClassCount = numclasses;
   1916 		i = 0;		// current team class index
   1917 		for (j = 0; j < maxclasses; j++) {
   1918 			if (teamcount[j] > 0) {
   1919 				CurTeam->DesiredNum[i] = teamcount[j];
   1920 				CurTeam->Class[i] = teamclass[j];
   1921 				i++;
   1922 			}
   1923 		}
   1924 	}
   1925 
   1926 	/*
   1927 	**	Redraw the display.
   1928 	*/
   1929 	HiddenPage.Clear();
   1930 	Flag_To_Redraw(true);
   1931 	Render();
   1932 
   1933 	delete [] teamclass;
   1934 	delete [] teamcount;
   1935 
   1936 	if (cancel) return(-1);
   1937 	return(0);
   1938 }
   1939 
   1940 
   1941 /***********************************************************************************************
   1942  * MapEditClass::Draw_Member -- Draws a member of the team dialog box.                         *
   1943  *                                                                                             *
   1944  *    This routine will display the cameo image of the potential team member. In the corner,   *
   1945  *    it will show the current quantity of this member for the current team being edited.      *
   1946  *                                                                                             *
   1947  * INPUT:   ptr   -- Pointer to the member object type.                                        *
   1948  *                                                                                             *
   1949  *          index -- The index into the team dialog box array of selectable objects. This is   *
   1950  *                   used to determine the correct X and Y offsets to draw.                    *
   1951  *                                                                                             *
   1952  *          quant -- The quantity number to display in the corner of the image.                *
   1953  *                                                                                             *
   1954  *          house -- The owner of this object.                                                 *
   1955  *				pic_x, pic_y -- x,y coords of upper-left corner to start drawing at
   1956  *                                                                                             *
   1957  * OUTPUT:  none                                                                               *
   1958  *                                                                                             *
   1959  * WARNINGS:   none                                                                            *
   1960  *                                                                                             *
   1961  * HISTORY:                                                                                    *
   1962  *   07/02/1995 JLB : Created.                                                                 *
   1963  *=============================================================================================*/
   1964 void MapEditClass::Draw_Member(TechnoTypeClass const * ptr, int index, 
   1965 	int quant, HousesType house, int pic_x, int pic_y)
   1966 {
   1967 	int numcols = (D_DIALOG_W - 32) / D_PICTURE_W;
   1968 	int col = index % numcols;
   1969 	int row = index / numcols;
   1970 	int x = pic_x + col * D_PICTURE_W;
   1971 	int y = pic_y + row * D_ROW_H;
   1972 
   1973 	WindowList[WINDOW_EDITOR][WINDOWX] = 0;
   1974 	WindowList[WINDOW_EDITOR][WINDOWY] = 0;
   1975 	WindowList[WINDOW_EDITOR][WINDOWWIDTH] = 640 / 8;
   1976 	WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = 400;
   1977 	Change_Window((int)WINDOW_EDITOR);
   1978 
   1979 	Hide_Mouse();
   1980 	Draw_Box(x, y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_GREEN_DOWN, true);
   1981 
   1982 	ptr->Display(x + D_PICTURE_W / 2, y + D_PICTURE_H / 2, WINDOW_EDITOR, house);
   1983 
   1984 	if (quant > 0) {
   1985 		Fancy_Text_Print("%d", x + 1, y + D_PICTURE_H - 16, 
   1986 			CC_GREEN, TBLACK, 
   1987 			TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_DROPSHADOW, quant);
   1988 	}
   1989 
   1990 	Show_Mouse();
   1991 
   1992 #if 0
   1993 	int numcols = (D_DIALOG_W - 16) / D_PICTURE_W;
   1994 	int col = index % numcols;
   1995 	int row = index / numcols;
   1996 	int dlg_y = 0;
   1997 	int x = D_DIALOG_X + 8 + col * D_PICTURE_W;
   1998 	int y = dlg_y + 8 + 13 + row * D_ROW_H;
   1999 
   2000 	/*
   2001 	**	Change the window to this box.
   2002 	*/
   2003 	WindowList[WINDOW_EDITOR][WINDOWX] = x >> 3;
   2004 	WindowList[WINDOW_EDITOR][WINDOWY] = y;
   2005 	WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W >> 3;
   2006 	WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H;
   2007 	Change_Window((int)WINDOW_EDITOR);
   2008 
   2009 	Hide_Mouse();
   2010 	Draw_Box(x, y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_GREEN_DOWN, true);
   2011 	ptr->Display(WinW<<2, WinH>>1, WINDOW_EDITOR, house);
   2012 	if (quant > 0) {
   2013 		Fancy_Text_Print("%d", x+1, y+D_PICTURE_H-8, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_DROPSHADOW, quant);
   2014 	}
   2015 	Show_Mouse();
   2016 #endif
   2017 }
   2018 
   2019 
   2020 /***************************************************************************
   2021  * MapEditClass::Build_Mission_list -- fills in mission list box           *
   2022  *                                                                         *
   2023  * INPUT:                                                                  *
   2024  *      missioncount      # of missions to add to the list                 *
   2025  *      missions            array of TeamMissionStruct's                   *
   2026  *      missionbuf         character arrays to store strings in            *
   2027  *      list               list box to add strings to                      *
   2028  *                                                                         *
   2029  * OUTPUT:                                                                 *
   2030  *      0 = OK, -1 = cancel                                                *
   2031  *                                                                         *
   2032  * WARNINGS:                                                               *
   2033  *      none.                                                              *
   2034  *                                                                         *
   2035  * HISTORY:                                                                *
   2036  *   12/07/1994 BR : Created.                                              *
   2037  *=========================================================================*/
   2038 void MapEditClass::Build_Mission_List(int missioncount, TeamMissionStruct *missions,
   2039 	char missionbuf[TeamTypeClass::MAX_TEAM_MISSIONS][20], ListClass *list)
   2040 {
   2041 	/*
   2042 	** Start with an empty list
   2043 	*/
   2044 	while (list->Count()) {
   2045 		list->Remove_Item(list->Get_Item(0));
   2046 	}
   2047 
   2048 	for (int i = 0; i < missioncount; i++) {
   2049 		/*
   2050 		** generate the string for a MOVE mission; the argument is the
   2051 		** letter-designation of the cell to move to.
   2052 		*/
   2053 		if (missions[i].Mission == TMISSION_MOVE || missions[i].Mission == TMISSION_UNLOAD) {
   2054 			sprintf(missionbuf[i],"%s\t%c",
   2055 				TeamTypeClass::Name_From_Mission(missions[i].Mission),
   2056 				missions[i].Argument + 'A');
   2057 		} else {
   2058 
   2059 			/*
   2060 			** All other missions take a numeric argument.
   2061 			*/
   2062 			sprintf(missionbuf[i],"%s\t%d",
   2063 				TeamTypeClass::Name_From_Mission(missions[i].Mission),
   2064 				missions[i].Argument);
   2065 		}
   2066 
   2067 		/*
   2068 		** Add the string to the list box
   2069 		*/
   2070 		list->Add_Item(missionbuf[i]);
   2071 	}
   2072 }
   2073 
   2074 #endif