CnC_Remastered_Collection

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

NETDLG.CPP (337753B)


      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: /CounterStrike/NETDLG.CPP 13    10/13/97 2:20p Steve_t $ */
     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 : NETDLG.CPP                               						  *
     24  *                                                                         						  *
     25  *                   Programmer : Bill Randolph                            						  *
     26  *                                                                         						  *
     27  *                   Start Date : January 23, 1995                         						  *
     28  *                                                                         						  *
     29  *                  Last Update : December 12, 1995 [BRR]                  						  *
     30  *                                                                         						  *
     31  *---------------------------------------------------------------------------------------------*
     32  *                                                                         						  *
     33  * These routines establish & maintain peer-to-peer connections between this system				  *
     34  * and all others in the game.  Each system finds out the IPX address of the others,			  *
     35  * and forms a direct connection (IPXConnectionClass) to that system.  Systems are				  *
     36  * found out via broadcast queries.  Every system broadcasts its queries, and every				  *
     37  * system replies to queries it receives.  At the point when the game owner signals				  *
     38  * 'OK', every system must know about all the other systems in the game.							  *
     39  *                                                                         						  *
     40  * How Bridges are handled:																						  *
     41  * Currently, bridges are handled by specifying the destination IPX address of the				  *
     42  * "server" (game owner's system) on the command-line.  This address is used to					  *
     43  * derive a broadcast address to that destination network, and this system's queries			  *
     44  * are broadcast over its network & the server's network; replies to the queries come			  *
     45  * with each system's IPX address attached, so once we have the address, we can form			  *
     46  * a connection with any system on the bridged net.														  *
     47  *                                                                         						  *
     48  * The flaw in this plan is that we can only cross one bridge.  If there are 3 nets				  *
     49  * bridged (A, B, & C), and the server is on net B, and we're on net A, our broadcasts			  *
     50  * will reach nets A & B, but not C.  The way to circumvent this (if it becomes a problem)	  *
     51  * would be to have the server tell us what other systems are in its game, not each				  *
     52  * individual player's system.  Thus, each system would find out about all the other systems	  *
     53  * by interacting with the game's owner system (this would be more involved than what			  *
     54  * I'm doing here).																									  *
     55  *                                                                         						  *
     56  * Here's a list of all the different packets sent over the Global Channel:						  *
     57  *																															  *
     58  *	NET_QUERY_GAME																										  *
     59  *							(no other data)																			  *
     60  *	NET_ANSWER_GAME																									  *
     61  *							Name:					game owner's name													  *
     62  *							GameInfo:			game's version & open state									  *
     63  *	NET_QUERY_PLAYER																									  *
     64  *							Name:					name of game we want players to respond for				  *
     65  *	NET_ANSWER_PLAYER																									  *
     66  *							Name:					player's name														  *
     67  *							PlayerInfo:			info about player													  *
     68  * NET_CHAT_ANNOUNCE																									  *
     69  *							Chat:					unique id of the local node, so I can tell				  *
     70  *													if this chat announcement is from myself					  *
     71  *	NET_QUERY_JOIN																										  *
     72  *							Name:					name of player wanting to join								  *
     73  *							PlayerInfo:			player's requested house, color, & version range		  *
     74  *	NET_CONFIRM_JOIN																									  *
     75  *							PlayerInfo:			approves player's house & color								  *
     76  *	NET_REJECT_JOIN																									  *
     77  *							Reject.Why:			tells why we got rejected										  *
     78  *	NET_GAME_OPTIONS																									  *
     79  *							ScenarioInfo:		info about scenario												  *
     80  *	NET_SIGN_OFF																										  *
     81  *							Name:					name of player signing off										  *
     82  *	NET_PING																												  *
     83  *							(no other data)																			  *
     84  *	NET_GO																												  *
     85  *							Delay:            value of one-way response time, in frames               *
     86  * 																														  *
     87  *---------------------------------------------------------------------------------------------*
     88  * Functions:                                                              						  *
     89  *   Init_Network -- initializes network stuff                             						  *
     90  *   Shutdown_Network -- shuts down network stuff                          						  *
     91  *   Process_Global_Packet -- responds to remote queries                   						  *
     92  *   Destroy_Connection -- destroys the given connection													  *
     93  *   Remote_Connect -- handles connecting this user to others              						  *
     94  *   Net_Join_Dialog -- lets user join an existing game, or start a new one						  *
     95  *   Request_To_Join -- Sends a JOIN request packet to game owner           	 					  *
     96  *   Unjoin_Game -- Cancels joining a game                                                     *
     97  *   Send_Join_Queries -- sends queries for the Join Dialog												  *
     98  *   Get_Join_Responses -- sends queries for the Join Dialog											  *
     99  *   Net_New_Dialog -- lets user start a new game															  *
    100  *   Get_NewGame_Responses -- processes packets for New Game dialog                            *
    101  *   Compute_Name_CRC -- computes CRC from char string                                         *
    102  *   Net_Reconnect_Dialog -- Draws/updates the network reconnect dialog                        *
    103  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    104 //	Warning - Most disgusting cpp file of all time. ajw
    105 
    106 #include "function.h"
    107 
    108 //PG Stubs
    109 void Destroy_Connection(int, int) {}
    110 bool Process_Global_Packet(GlobalPacketType *, IPXAddressClass *) { return false; }
    111 bool Client_Remote_Connect(void) { return false; }
    112 bool Server_Remote_Connect(void) { return false; }
    113 bool Init_Network(void) { return false; }
    114 bool Remote_Connect(void) { return false; }
    115 
    116 #if (0)		//PG
    117 
    118 
    119 #ifdef WIN32
    120 #ifdef WINSOCK_IPX
    121 #include	"WSProto.h"
    122 #else	//WINSOCK_IPX
    123 #include "tcpip.h"
    124 #endif	//WINSOCK_IPX
    125 #include "ccdde.h"
    126 #else	//WIN32
    127 #include "fakesock.h"
    128 #endif	//WIN32
    129 
    130 #include <time.h>
    131 //#include <dos.h>
    132 
    133 //#include "WolDebug.h"
    134 
    135 #define SHOW_MONO		0
    136 //#define OLDWAY			1
    137 
    138 #ifdef FRENCH
    139 #define TXT_HACKHACK  "Connexion En Cours..."
    140 #endif
    141 #if defined(ENGLISH) || defined(GERMAN)
    142 #define TXT_HACKHACK  Text_String(TXT_CONNECTING)
    143 #endif
    144 
    145 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
    146 bool Is_Mission_126x126 (char *file_name);
    147 bool Is_Mission_Aftermath (char *file_name);
    148 bool Is_Mission_Counterstrike (char *file_name);
    149 bool bSpecialAftermathScenario( const char* szScenarioDescription );
    150 #endif
    151 
    152 #ifdef FIXIT_VERSION_3
    153 bool Force_Scenario_Available( const char* szName );
    154 #endif
    155 #ifdef WOLAPI_INTEGRATION
    156 #include "WolStrng.h"
    157 #include "WolapiOb.h"
    158 extern WolapiObject* pWolapi;
    159 #endif
    160 
    161 #include "COORDA.h"
    162 
    163 //---------------------------------------------------------------------------
    164 //	The possible states of the join-game dialog
    165 //---------------------------------------------------------------------------
    166 typedef enum {
    167 	JOIN_REJECTED = -1,		// we've been rejected
    168 	JOIN_NOTHING,				// we're not trying to join a game
    169 	JOIN_WAIT_CONFIRM,		// we're asking to join, & waiting for confirmation
    170 	JOIN_CONFIRMED,			// we've been confirmed
    171 	JOIN_GAME_START,			// the game we've joined is starting
    172 	JOIN_GAME_START_LOAD,	// the game we've joined is starting; load saved game
    173 } JoinStateType;
    174 
    175 //---------------------------------------------------------------------------
    176 //	The possible return codes from Get_Join_Responses()
    177 //---------------------------------------------------------------------------
    178 typedef enum {
    179 	EV_NONE,							// nothing happened
    180 	EV_STATE_CHANGE,				// Join dialog is in a new state
    181 	EV_NEW_GAME,					// a new game formed, or is now open
    182 	EV_NEW_PLAYER,					// a new player was detected
    183 	EV_PLAYER_SIGNOFF,			// a player has signed off
    184 	EV_GAME_SIGNOFF,				// a gamed owner has signed off
    185 	EV_GAME_OPTIONS,				// a game options packet was received
    186 	EV_MESSAGE,						// a message was received
    187 } JoinEventType;
    188 
    189 
    190 //---------------------------------------------------------------------------
    191 //	The possible reasons we're rejected from joining a game
    192 //---------------------------------------------------------------------------
    193 typedef enum {
    194 	REJECT_DUPLICATE_NAME,		// player's name is a duplicate
    195 	REJECT_GAME_FULL,				// game is full
    196 	REJECT_VERSION_TOO_OLD,		// joiner's version is too old
    197 	REJECT_VERSION_TOO_NEW,		// joiner's version is too new
    198 	REJECT_BY_OWNER,				// game owner clicked "reject"
    199 	REJECT_DISBANDED,				// game was disbanded
    200 	REJECT_MISMATCH,				// "rules.ini" file mismatch.
    201 } RejectType;
    202 
    203 #ifdef ENGLISH
    204 char const *EngMisStr[] = {
    205 	"Coastal Influence (Med)",
    206 	"Middle Mayhem (Sm)",
    207 	"Equal Opportunity (Sm)",
    208 	"Marooned II (Med)",
    209 	"Keep off the Grass (Sm)",
    210 	"Isle of Fury (Lg)",
    211 	"Ivory Wastelands (Sm)",
    212 	"Shallow Grave (Med)",
    213 	"North By Northwest (Lg)",
    214 	"First Come, First Serve (Sm)",
    215 	"Island Hoppers (Sm)",
    216 	"Raraku (Lg)",
    217 	"Central Conflict (Lg)",
    218 	"Combat Alley (Med)",
    219 	"Island Wars (Lg)",
    220 	"Desolation (Lg)",
    221 	"No Escape (Med)",
    222 	"No Man's Land (Med)",
    223 	"Normandy (Med)",
    224 	"Pond Skirmish (Med)",
    225 	"Ridge War (Med)",
    226 	"A Path Beyond (Lg)",
    227 	"Dugout Isle (Med)",
    228 	"Treasure Isle (Med)",
    229 
    230 	"Africa (Lg)",
    231 	"Alaska Anarchy (Lg)",
    232 	"All that Glitters... (Lg)",
    233 	"Apre's Peace (Lg)",
    234 	"Antartica (Lg)",
    235 	"Armourgarden (Lg)",
    236 	"Austraila (Med)",
    237 	"Barrier to Entry (Lg)",
    238 	"Bavarian Blast (Med)",
    239 	"Be Shore (Med)",
    240 	"Bearing Straits (Med)",
    241 	"Blow Holes (Lg)",
    242 	"Bonsai (Sm)",
    243 	"Brother Stalin (Lg)",
    244 	"Bullseye (Lg)",
    245 	"C&C (Med)",
    246 	"Camos Canyon (Med)",
    247 	"Camos Coves (Lg)",
    248 	"Camos Cross (Lg)",
    249 	"Camos Crossing (Sm)",
    250 	"Central Arena (Lg)",
    251 	"Canyon River (Med)",
    252 	"Crossroads (Sm)",
    253 	"Czech Mate (Lg)",
    254 	"Dday (Med)",
    255 	"Disaster Central (Lg)",
    256 	"Docklands (Med)",
    257 	"East Coast (Med)",
    258 	"Eastern Seaboard (Lg)",
    259 	"Finger Lake (Lg)",
    260 	"Fjords (Med)",
    261 	"Floodlands (Lg)",
    262 	"Forest under fire (Lg)",
    263 	"Four Corners (Lg)",
    264 	"Frostbit Fjords (Lg)",
    265 	"Glenboig (Sm)",
    266 	"Hell Frozen Over (Lg)",
    267 	"India (Lg)",
    268 	"Indirect Fire (Lg)",
    269 	"Island Wars II (Lg)",
    270 	"Italy (Lg)",
    271 	"Kabalo (Lg)",
    272 	"King of the Hills (Lg)",
    273 	"Lake Divide (Med)",
    274 	"Lakelands (Lg)",
    275 	"Land Ladder (Lg)",
    276 	"Lotsa Lakes (Lg)",
    277 	"Lunar Battlefield (Lg Special)",
    278 	"Malibu Fields (Med)",
    279 	"Marshland (Med)",
    280 	"MyLai Delta (Med)",
    281 	"Natural Harbor (Med)",
    282 	"No Way Out (Lg)",
    283 	"Normandy Landing (Lg)",
    284 	"Ore Wars (Med)",
    285 	"Oz (Lg)",
    286 	"Pilgrim Fathers II (Lg)",
    287 	"Pip's Ice Tea (Med)",
    288 	"Polar Panic (Lg)",
    289 	"Ponds (Med)",
    290 	"Putney (Lg)",
    291 	"Return to Zion (Lg)",
    292 	"Ring of Land (Lg)",
    293 	"River Basin (Lg)",
    294 	"River Delta (Med)",
    295 	"River Islands (Med)",
    296 	"River Maze (Sm)",
    297 	"Rivers (Sm)",
    298 	"Run the Gauntlet (Med)",
    299 	"Scappa Flow (Lg)",
    300 	"Siberian Slaughter (Lg)",
    301 	"Sleepy Valley (Sm)",
    302 	"Snake River (Lg)",
    303 	"Snow Wars (Lg)",
    304 	"Snowball fight (Lg)",
    305 	"Snowy Island (Lg)",
    306 	"So Near So Far (Sm)",
    307 	"South America (Lg)",
    308 	"Spring Line (Lg)",
    309 	"Star (Lg)",
    310 	"Straighter & Narrower (Sm)",
    311 	"TerrainSpotting (Sm)",
    312 	"The Bay (Lg)",
    313 	"The Garden (Lg)",
    314 	"The Great Lakes (Med)",
    315 	"The Ice Arena (Lg)",
    316 	"The Lake District (Lg)",
    317 	"The Linked lands (Lg)",
    318 	"The Mississippi (Med)",
    319 	"The Sticky Bit (Lg)",
    320 	"The Valley (Med)",
    321 	"The Woods Today (Lg)",
    322 	"Things to Come (Lg)",
    323 	"Tiger Core (Sm)",
    324 	"To the Core (Sm)",
    325 	"Tournament Hills (Lg)",
    326 	"Tropical Storm (Med)",
    327 	"Tundra Trouble (Lg)",
    328 	"Uk (Med)",
    329 	"Undiscovered Country (Sm)",
    330 	"United States (Med)",
    331 	"Volcano (Sm)",
    332 	"Wastelands (Lg)",
    333 	"Water Works (Sm)",
    334 	"World Map (Med)",
    335 	"Zambezi (Lg)",
    336 
    337 	"A Pattern of Islands (Lg 8 players)",
    338 	"Arena Valley Extreme (Mega 8 players)",
    339 	"Around the Rim (Sm 4 players)",
    340 	"Ashes to Ashes (Lg 6 players)",
    341 	"Artic Wasteland (Mega 8 players)",
    342 	"Badajoz (Med 4 players)",
    343 	"Baptism of Fire (Lg 6 players)",
    344 	"Big Fish, Small Pond (Lg 6 players)",
    345 	"Blue Lakes (Lg 8 players)",
    346 	"Booby Traps (Mega 8 players)",
    347 	"Bridgehead (Lg 6 players)",
    348 	"Butterfly Bay (Lg 6 players)",
    349 	"Central Conflict Extreme (Mega 8 players)",
    350 	"Circles of Death (Mega 8 players)",
    351 	"Cold Front (Med 6 players)",
    352 	"Cold Pass (Med 4 players)",
    353 	"Combat Zones (Mega 8 players)",
    354 	"Conflict Cove (Sm 4 players)",
    355 	"Culloden Moor (Med 8 players)",
    356 	"Damnation Alley (Mega 8 players)",
    357 	"Death Valley (Mega 8 players)",
    358 	"Deep Six (Mega 8 players)",
    359 	"Destruction Derby (Mega 8 players)",
    360 	"Diamonds Aren't Forever (Mega 8 players)",
    361 	"Elysium (Sm 4 players)",
    362 	"Equal Shares (Lg 4 players)",
    363 	"Frost Bitten (Mega 8 players)",
    364 	"Frozen Valley (Med 6 players)",
    365 	"Gettysburg (Sm 4 players)",
    366 	"Glacial Valley (Sm 4 players)",
    367 	"Gold Coast (Med 6 players)",
    368 	"Gold Rush (Lg 4 players)",
    369 	"Habitat (Lg 4 players)",
    370 	"Hades Frozen Over (Sm 4 players)",
    371 	"Hamburger Hill (Mega 8 players)",
    372 	"Hastings (Sm 4 players)",
    373 	"Hell's Pass (Med 6 players)",
    374 	"Holy Grounds (Mega 8 players)",
    375 	"Ice Bergs (Med 6 players)",
    376 	"Ice Station (Lg 6 players)",
    377 	"Ice Queen (Lg 4 players)",
    378 	"In the Sun (Med 6 players)",
    379 	"Innocents? (Mega 8 players)",
    380 	"Islands (Med 8 players)",
    381 	"Island Plateau (Lg 4 players)",
    382 	"Island Wars Extreme (Mega 8 players)",
    383 	"Kananga (Med 6 players)",
    384 	"King of the Hills Extreme (Mega 8 players)",
    385 	"Lake Land (Lg 8 players)",
    386 	"Land Locked (Lg 8 players)",
    387 	"Lanes (Med 8 players)",
    388 	"Leipzip (Sm 4 players)",
    389 	"Meander (Lg 8 players)",
    390 	"Mekong (Med 8 players)",
    391 	"Middle Ground (Med 8 players)",
    392 	"Naval Conquests (Mega 8 players)",
    393 	"On your Marks (Med 4 players)",
    394 	"Open Warfare (Mega 8 players)",
    395 	"Ore Gardens (Lg 8 players)",
    396 	"Potholes (Mega 8 players)",
    397 	"Puddles (Med 4 players)",
    398 	"Random Violence (Mega 8 players)",
    399 	"Revenge (Med 8 players)",
    400 	"Rias (Med 8 players)",
    401 	"River Crossing (Sm 4 players)",
    402 	"River Rampage (Mega 8 players)",
    403 	"River Rapids (Lg 6 players)",
    404 	"Rivers Wild (Mega 8 players)",
    405 	"Rorkes Drift (Lg 4 players)",
    406 	"Seaside (Med 4 players)",
    407 	"Shades (Med 8 players)",
    408 	"Smuggler's Cove (Lg 6 players)",
    409 	"Snow Garden (Sm 2 players)",
    410 	"Stalingrad (Sm 4 players)",
    411 	"Sticks & Stones (Med 4 players)",
    412 	"Strathearn Valley (Lg 6 players)",
    413 	"Super Bridgehead (Mega 8 players)",
    414 	"Super Mekong (Mega 8 players)",
    415 	"Super Ore Gardens (Mega 8 players)",
    416 	"Switch (Med 4 players)",
    417 	"The Berg (Mega 8 players)",
    418 	"The Boyne (Med 4 players)",
    419 	"The Bulge (Sm 4 players)",
    420 	"The Cauldron (Lg 6 players)",
    421 	"The Finger (Lg 6 players)",
    422 	"The Hills Have Eyes (Mega 8 players)",
    423 	"The Keyes (Med 6 players)",
    424 	"The Lakes (Med 8 players)",
    425 	"The Neck (Med 6 players)",
    426 	"The Web (Lg 6 players)",
    427 	"To the Core (Lg 4 players)",
    428 	"Trafalgar (Lg 4 players)",
    429 	"Twin Rivers (Sm 4 players)",
    430 	"Umtumbo Gorge (Lg 4 players)",
    431 	"Watch Your Step Extreme (Mega 8 players)",
    432 	"Waterfalls (Lg 8 players)",
    433 	"Waterloo Revisited (Lg 6 players)",
    434 	"Water Werks (Mega 8 players)",
    435 	"Warlord's Lake (Sm 4 players)",
    436 	"Zama (Sm 4 players)",
    437 
    438 	NULL
    439 };
    440 #endif
    441 
    442 #ifdef GERMAN
    443 char const *EngMisStr[] = {
    444 
    445 	"A Path Beyond (Lg)",					"Weg ins Jenseits (Gr)",
    446 	"Central Conflict (Lg)",				"Der zentrale Konflikt (Gr)",
    447 	"Coastal Influence (Med)",				"Sturm an der Kste (Mit)",
    448 	"Combat Alley (Med)",					"Boulevard der Schlachten (Mit)",
    449 	"Desolation (Lg)",						"Verwstung (Gr)",
    450 	"Dugout Isle (Med)",						"Buddelschiff (Mit)",
    451 	"Equal Opportunity (Sm)",				"Gleiche Chancen (Kl)",
    452 	"First Come, First Serve (Sm)",		"Wer zuerst kommt... (Kl)",
    453 	"Island Hoppers (Sm)",					"Inselspringen (Kl)",
    454 	"Island Wars (Lg)",						"Der Krieg der Eilande (Gr)",
    455 	"Isle of Fury (Lg)",						"Insel des Zorns (Gr)",
    456 	"Ivory Wastelands (Sm)",				"Elfenbeinwste (Kl)",
    457 	"Keep off the Grass (Sm)",				"Rasen betreten verboten (Kl)",
    458 	"Marooned II (Med)",						"Gestrandet (Mit)",
    459 	"Middle Mayhem (Sm)",					"Mittelsmann (Kl)",
    460 	"No Escape (Med)",						"Kein Entrinnen (Mit)",
    461 	"No Man's Land (Med)",					"Niemandsland (Mit)",
    462 	"Normandy (Med)",							"Normandie (Mit)",
    463 	"North By Northwest (Lg)",				"Nord auf Nordwest (Gr)",
    464 	"Pond Skirmish (Med)",					"Teichgepl„nkel (Mit)",
    465 	"Raraku (Lg)",								"Raraku (Gr)",
    466 	"Ridge War (Med)",						"Das Tal der Cyborgs (Mit)",
    467 	"Shallow Grave (Med)",					"Ein enges Grab (Mit)",
    468 	"Treasure Isle (Med)",					"Die Schatzinsel (Mit)",
    469 
    470 	"Africa (Lg)",								"Afrika (Gr)",
    471 	"Alaska Anarchy (Lg)",					"Anarchie in Alaska (Gr)",
    472 	"All that Glitters... (Lg)",			"Alles was gl„nzt... (Gr)",
    473 	"Apre's Peace (Lg)",						"Apres Frieden (Gr)",
    474 	"Antartica (Lg)",							"Antarktica (Gr)",
    475 	"Armourgarden (Lg)",						"Garten der Panzer (Gr)",
    476 	"Austraila (Med)",						"Koalaland (Mit)",
    477 	"Barrier to Entry (Lg)",				"Zutritt verboten (Gr)",
    478 	"Bavarian Blast (Med)",					"Bayrische Blasmusik (Mit)",
    479 	"Be Shore (Med)",							"Strandl„ufer (Mit)",
    480 	"Bearing Straits (Med)",				"Die Heringstrasse (Mit)",
    481 	"Blow Holes (Lg)",						"L”cheriger K„se (Gr)",
    482 	"Bonsai (Sm)",								"Bonsai (Kl)",
    483 	"Brother Stalin (Lg)",					"Brderchen Stalin (Gr)",
    484 	"Bullseye (Lg)",							"Bullseye (Gr)",
    485 	"C&C (Med)",								"C&C (Mit)",
    486 	"Camos Canyon (Med)",					"Camos-Canyon (Mit)",
    487 	"Camos Coves (Lg)",						"Camos-Grotte (Gr)",
    488 	"Camos Cross (Lg)",						"Camos-Kreuz (Gr)",
    489 	"Camos Crossing (Sm)",					"Camos-Kreuzweg (Kl)",
    490 	"Central Arena (Lg)",					"Spielplatz des Teufels (Gr)",
    491 	"Canyon River (Med)",					"Canyonfluss (Mit)",
    492 	"Crossroads (Sm)",						"Kreuzung (Kl)",
    493 	"Czech Mate (Lg)",						"Tschechische Er”ffnung (Gr)",
    494 	"Dday (Med)",								"D-Day (Mit)",
    495 	"Disaster Central (Lg)",				"Endstation Schweinebucht (Gr)",
    496 	"Docklands (Med)",						"Docklands (Mit)",
    497 	"East Coast (Med)",						"Ostkste (Mit)",
    498 	"Eastern Seaboard (Lg)",				"Die Passage nach Osten (Gr)",
    499 	"Finger Lake (Lg)",						"Fingersee (Gr)",
    500 	"Fjords (Med)",							"Fjorde (Mit)",
    501 	"Floodlands (Lg)",						"Land unter! (Gr)",
    502 	"Forest under fire (Lg)",		   	"Waldsterben im Feuer (Gr)",
    503 	"Four Corners (Lg)",						"Viereck (Gr)",
    504 	"Frostbit Fjords (Lg)",					"Frostbeulenfjord (Gr)",
    505 	"Glenboig (Sm)",							"Glenboig (Kl)",
    506 	"Hell Frozen Over (Lg)",				"Winter in der H”lle (Gr)",
    507 	"India (Lg)",								"Indien (Gr)",
    508 	"Indirect Fire (Lg)",					"Indirekter Beschuss (Gr)",
    509 	"Island Wars II (Lg)",					"Krieg der Inseln (Gr)",
    510 	"Italy (Lg)",								"Italien (Gr)",
    511 	"Kabalo (Lg)",								"Kabalo (Gr)",
    512 	"King of the Hills (Lg)",				"K”nig des Maulwurfshgels (Gr)",
    513 	"Lake Divide (Med)",						"Wasserscheide (Mit)",
    514 	"Lakelands (Lg)",							"Seenplatte (Gr)",
    515 	"Land Ladder (Lg)",						"Das Leiterspiel (Gr)",
    516 	"Lotsa Lakes (Lg)",						"Mehr Seen (Gr)",
    517 	"Lunar Battlefield (Lg Special)",	"Schlachtfeld Mond (Gr Spezial)",
    518 	"Malibu Fields (Med)",					"Malibu (Mit)",
    519 	"Marshland (Med)",						"Schlammschlacht (Mit)",
    520 	"MyLai Delta (Med)",						"Das Delta von My Lai (Mit)",
    521 	"Natural Harbor (Med)",					"Natrlicher Hafen (Mit)",
    522 	"No Way Out (Lg)",						"Kein Entkommen (Gr)",
    523 	"Normandy Landing (Lg)",				"Landung in der Normandie (Gr)",
    524 	"Ore Wars (Med)",							"Die Erz-Kriege (Mit)",
    525 	"Oz (Lg)",									"Das Land Oz (Gr)",
    526 	"Pilgrim Fathers II (Lg)",				"Die Grnderv„ter (Gr)",
    527 	"Pip's Ice Tea (Med)",					"Pips Eistee (Mit)",
    528 	"Polar Panic (Lg)",						"Panik am Pol (Gr)",
    529 	"Ponds (Med)",								"Tmpelspringer (Mit)",
    530 	"Putney (Lg)",								"Putney (Gr)",
    531 	"Return to Zion (Lg)",					"Rckkehr nach Zion (Gr)",
    532 	"Ring of Land (Lg)",						"Der Landring (Gr)",
    533 	"River Basin (Lg)",						"Flusslauf (Gr)",
    534 	"River Delta (Med)",						"Flussdelta (Mit)",
    535 	"River Islands (Med)",					"Flussinsel (Mit)",
    536 	"River Maze (Sm)",						"Flussgewirr (Kl)",
    537 	"Rivers (Sm)",								"Flsse (Kl)",
    538 	"Run the Gauntlet (Med)",				"Spiessrutenlauf (Mit)",
    539 	"Scappa Flow (Lg)",						"Scapa Flow (Gr)",
    540 	"Siberian Slaughter (Lg)",				"Sibirisches Gemetzel (Gr)",
    541 	"Sleepy Valley (Sm)",					"Tal der Ahnungslosen (Kl)",
    542 	"Snake River (Lg)",						"Am Schlangenfluss (Gr)",
    543 	"Snow Wars (Lg)",							"Krieg der Flocken (Gr)",
    544 	"Snowball fight (Lg)",					"Schneeballschlacht (Gr)",
    545 	"Snowy Island (Lg)",						"Schneeinsel (Gr)",
    546 	"So Near So Far (Sm)",					"So nah und doch so fern (Kl)",
    547 	"South America (Lg)",					"Sdamerika (Gr)",
    548 	"Spring Line (Lg)",						"Frhlingsgefhle (Gr)",
    549 	"Star (Lg)",								"Stern (Gr)",
    550 	"Straighter & Narrower (Sm)",			"Enger & schmaler (Kl)",
    551 	"TerrainSpotting (Sm)",					"TerrainSpotting (Kl)",
    552 	"The Bay (Lg)",							"Die Bucht (Gr)",
    553 	"The Garden (Lg)",						"Der Garten (Gr)",
    554 	"The Great Lakes (Med)",				"Die Grossen Seen (Mit)",
    555 	"The Ice Arena (Lg)",					"Eisarena (Gr)",
    556 	"The Lake District (Lg)",				"Kalte Seenplatte (Gr)",
    557 	"The Linked lands (Lg)",				"Die verbundenen L„nder (Gr)",
    558 	"The Mississippi (Med)",				"Grsse von Tom Sawyer (Mit)",
    559 	"The Sticky Bit (Lg)",					"Der klebrige Teil (Gr)",
    560 	"The Valley (Med)",						"Das Tal (Mit)",
    561 	"The Woods Today (Lg)",					"Waldl„ufer (Gr)",
    562 	"Things to Come (Lg)",					"Was die Zukunft bringt (Gr)",
    563 	"Tiger Core (Sm)",						"Das Herz des Tigers (Kl)",
    564 	"To the Core (Sm)",						"Mitten ins Herz (Kl)",
    565 	"Tournament Hills (Lg)",				"Hgel der Entscheidung (Gr)",
    566 	"Tropical Storm (Med)",					"Tropenstrme (Mit)",
    567 	"Tundra Trouble (Lg)",					"Tauziehen in der Tundra (Gr)",
    568 	"Uk (Med)",									"GB (Mit)",
    569 	"Undiscovered Country (Sm)",			"Unentdecktes Land (Kl)",
    570 	"United States (Med)",					"US (Mit)",
    571 	"Volcano (Sm)",							"Vulkan (Kl)",
    572 	"Wastelands (Lg)",						"Wstenei (Gr)",
    573 	"Water Works (Sm)",						"Wasserwerke (Kl)",
    574 	"World Map (Med)",						"Weltkarte (Kl)",
    575 	"Zambezi (Lg)",							"Sambesi (Gr)",
    576 
    577 //#if 0
    578 	"A Pattern of Islands (Lg 8 players)",  		 "Inselmuster (gross, 8 Spieler)",
    579 	"Arena Valley Extreme (Mega 8 players)",		 "Arenatal (sehr gross, 8 Spieler)",
    580 	"Around the Rim (Sm 4 players)",					 "Um die Kante (klein, 4 Spieler)",
    581 	"Ashes to Ashes (Lg 6 players)",					 "Asche zu Asche (gross, 6 Spieler)",
    582 	"Artic Wasteland (Mega 8 players)",				 "Arktische Wste (sehr gross, 8 Spieler)",
    583 	"Badajoz (Med 4 players)",							 "Badjoz (mittelgross, 4 Spieler)",
    584 	"Baptism of Fire (Lg 6 players)",				 "Feuertaufe (gross, 6 Spieler)",
    585 	"Big Fish, Small Pond (Lg 6 players)",			 "Grosser Fisch im kleinen Teich (gross, 6 Spieler)",
    586 	"Blue Lakes (Lg 8 players)",						 "Die blauen Seen (gross, 8 Spieler)",
    587 	"Booby Traps (Mega 8 players)",					 "Vorsicht, Falle! (sehr gross, 8 Spieler)",
    588 	"Bridgehead (Lg 6 players)",						 "Brckenkopf im Niemandsland (gross, 6 Spieler)",
    589 	"Butterfly Bay (Lg 6 players)",					 "Schmetterlingsbucht (gross, 6 Spieler)",
    590 	"Central Conflict Extreme (Mega 8 players)",  "Zentraler Konflikt fr K”nner (sehr gross, 8 Spieler)",
    591 	"Circles of Death (Mega 8 players)",			 "Todeskreise (sehr gross, 8 Spieler)",
    592 	"Cold Front (Med 6 players)",						 "Kaltfront ( mittelgross, 6 Spieler)",
    593 	"Cold Pass (Med 4 players)",						 "Cooler Pass (mittelgross, 4 Spieler)",
    594 	"Combat Zones (Mega 8 players)",					 "Kampfgebiete (sehr gross, 8 Spieler)",
    595 	"Conflict Cove (Sm 4 players)",					 "H”hlenkonflikt (klein, 4 Spieler)",
    596 	"Culloden Moor (Med 8 players)",					 "Culloden-Moor (mittelgross, 8 Spieler)",
    597 	"Damnation Alley (Mega 8 players)",				 "Strasse der Verdammten (sehr gross, 8 Spieler)",
    598 	"Death Valley (Mega 8 players)",					 "Tal des Todes (sehr gross, 8 Spieler)",
    599 	"Deep Six (Mega 8 players)",						 "Tiefe Sechs (sehr gross, 8 Spieler)",
    600 	"Destruction Derby (Mega 8 players)",			 "Destruction Derby (sehr gross, 8 Spieler)",
    601 	"Diamonds Aren't Forever (Mega 8 players)",	 "Verg„ngliche Diamanten (sehr gross, 8 Spieler)",
    602 	"Elysium (Sm 4 players)",							 "Elysium (klein, 4 Spieler)",
    603 	"Equal Shares (Lg 4 players)",					 "Gleiche Anteile (gross, 4 Spieler)",
    604 	"Frost Bitten (Mega 8 players)",					 "Frostbrand (sehr gross, 8 Spieler)",
    605 	"Frozen Valley (Med 6 players)",					 "Eisiges Tal (mittelgross, 6 Spieler)",
    606 	"Gettysburg (Sm 4 players)",						 "Gettysburg (klein, 4 Spieler)",
    607 	"Glacial Valley (Sm 4 players)",					 "Gletschertal (klein, 4 Spieler)",
    608 	"Gold Coast (Med 6 players)",						 "Goldkste (mittelgross, 6 Spieler)",
    609 	"Gold Rush (Lg 4 players)",						 "Goldrausch (gross, 4 Spieler)",
    610 	"Habitat (Lg 4 players)",							 "Habitat (gross, 4 Spieler)",
    611 	"Hades Frozen Over (Sm 4 players)",				 "Frostschutz fr die H”lle (klein, 4 Spieler)",
    612 	"Hamburger Hill (Mega 8 players)",				 "Hamburger Hill (sehr gross, 8 Spieler)",
    613 	"Hastings (Sm 4 players)",							 "Hastings (klein, 4 Spieler)",
    614 	"Hell's Pass (Med 6 players)",					 "H”llenpass (mittelgross, 6 Spieler)",
    615 	"Holy Grounds (Mega 8 players)",					 "Heiliger Boden (sehr gross, 8 Spieler)",
    616 	"Ice Bergs (Med 6 players)",						 "Eisberge (mittelgross, 6 Spieler)",
    617 	"Ice Station (Lg 6 players)",						 "Eisstation  (gross, 6 Spieler)",
    618 	"Ice Queen (Lg 4 players)",						 "Eisk”nigin (gross, 4 Spieler)",
    619 	"In the Sun (Med 6 players)",						 "Unter der Sonne (mittelgross, 6 Spieler)",
    620 	"Innocents? (Mega 8 players)",					 "Unschuldig? Wer? (sehr gross, 8 Spieler)",
    621 	"Islands (Med 8 players)",							 "Inseln im Nebel (mittelgross, 8 Spieler)",
    622 	"Island Plateau (Lg 4 players)",					 "Inselplateau (gross, 4 Spieler)",
    623 	"Island Wars Extreme (Mega 8 players)",		 "Extremes Inselspringen (sehr gross, 8 Spieler)",
    624 	"Kananga (Med 6 players)",							 "Kananga (mittelgross, 6 Spieler)",
    625 	"King of the Hills Extreme (Mega 8 players)", "K”nig des Maulwurfshgels (sehr gross, 8 Spieler)",
    626 	"Lake Land (Lg 8 players)",						 "Seenland (gross, 8 Spieler)",
    627 	"Land Locked (Lg 8 players)",						 "Das Verschlossene Land (gross, 8 Spieler)",
    628 	"Lanes (Med 8 players)",							 "Gassenjungen (mittelgross, 8 Spieler)",
    629 	"Leipzip (Sm 4 players)",							 "Leipzig (klein, 4 Spieler)",
    630 	"Meander (Lg 8 players)",							 "M„ander (gross, 8 Spieler)",
    631 	"Mekong (Med 8 players)",							 "Mekong (mittelgross, 8 Spieler)",
    632 	"Middle Ground (Med 8 players)",					 "Mittelsmann (mittelgross, 8 Spieler)",
    633 	"Naval Conquests (Mega 8 players)",				 "Kommt zur Marine, haben sie gesagt (sehr gross, 8 Spieler)",
    634 	"On your Marks (Med 4 players)",					 "Auf die Pl„tze (mittelgross, 4 Spieler)",
    635 	"Open Warfare (Mega 8 players)",					 "Offener Schlagabtausch (sehr gross, 8 Spieler)",
    636 	"Ore Gardens (Lg 8 players)",						 "Erzparadies (gross, 8 Spieler)",
    637 	"Potholes (Mega 8 players)",						 "Schlagl”cher (sehr gross, 8 Spieler)",
    638 	"Puddles (Med 4 players)",							 "Pftzen (mittelgross, 4 Spieler)",
    639 	"Random Violence (Mega 8 players)",				 "Unberechenbare Gewalt (sehr gross, 8 Spieler)",
    640 	"Revenge (Med 8 players)",							 "Rache (mittelgross, 8 Spieler)",
    641 	"Rias (Med 8 players)",								 "Kabul (mittelgross, 8 Spieler)",
    642 	"River Crossing (Sm 4 players)",					 "Die Furt (klein, 4 Spieler)",
    643 	"River Rampage (Mega 8 players)",				 "Flussfahrt (sehr gross, 8 Spieler)",
    644 	"River Rapids (Lg 6 players)",					 "Stromschnellen (gross, 6 Spieler)",
    645 	"Rivers Wild (Mega 8 players)",					 "Wildwasser (sehr gross, 8 Spieler)",
    646 	"Rorkes Drift (Lg 4 players)",					 "Rorkes Drift (gross, 4 Spieler)",
    647 	"Seaside (Med 4 players)",							 "Strandleben (mittelgross, 4 Spieler)",
    648 	"Shades (Med 8 players)",							 "Schattenreich (mittelgross, 8 Spieler)",
    649 	"Smuggler's Cove (Lg 6 players)",				 "Schmugglerh”hle (gross, 6 Spieler)",
    650 	"Snow Garden (Sm 2 players)",						 "Schneegest”ber (klein, 2 Spieler)",
    651 	"Stalingrad (Sm 4 players)",						 "Stalingrad (klein, 4 Spieler)",
    652 	"Sticks & Stones (Med 4 players)",				 "Holz und Steine (mittelgross, 4 Spieler)",
    653 	"Strathearn Valley (Lg 6 players)",				 "Das Tal von Strathearn (gross, 6 Spieler)",
    654 	"Super Bridgehead (Mega 8 players)",			 "Super-Brckenkopf (sehr gross, 8 Spieler)",
    655 	"Super Mekong (Mega 8 players)",					 "Super-Mekong (sehr gross, 8 Spieler)",
    656 	"Super Ore Gardens (Mega 8 players)",			 "Super-Erzparadies (sehr gross, 8 Spieler)",
    657 	"Switch (Med 4 players)",							 "Schalter (mittelgross, 4 Spieler)",
    658 	"The Berg (Mega 8 players)",						 "Der Berg (sehr gross, 8 Spieler)",
    659 	"The Boyne (Med 4 players)",						 "Boyne (mittelgross, 4 Spieler)",
    660 	"The Bulge (Sm 4 players)",						 "Die W”lbung (klein, 4 Spieler)",
    661 	"The Cauldron (Lg 6 players)",					 "Der Kessel (gross, 6 Spieler)",
    662 	"The Finger (Lg 6 players)",						 "Der Finger (gross, 6 Spieler)",
    663 	"The Hills Have Eyes (Mega 8 players)",		 "Die Hgel haben Augen (sehr gross, 8 Spieler)",
    664 	"The Keyes (Med 6 players)",						 "Ein Sumpf (mittelgross, 6 Spieler)",
    665 	"The Lakes (Med 8 players)",						 "Die Seen (mittelgross, 8 Spieler)",
    666 	"The Neck (Med 6 players)",						 "Der Hals (mittelgross, 6 Spieler)",
    667 	"The Web (Lg 6 players)",							 "Das Netz (gross, 6 Spieler)",
    668 	"To the Core (Lg 4 players)",						 "Mitten ins Herz (gross, 4 Spieler)",
    669 	"Trafalgar (Lg 4 players)",						 "Trafalgar (gross, 4 Spieler)",
    670 	"Twin Rivers (Sm 4 players)",						 "Zwillingsstr”me (klein, 4 Spieler)",
    671 	"Umtumbo Gorge (Lg 4 players)",					 "Die Umtumbo-Schlucht (gross, 4 Spieler)",
    672 	"Watch Your Step Extreme (Mega 8 players)",	 "Vorsicht, Lebensgefahr (sehr gross, 8 Spieler)",
    673 	"Waterfalls (Lg 8 players)",						 "Wasserfall (gross, 8 Spieler)",
    674 	"Waterloo Revisited (Lg 6 players)",			 "Zu Besuch in Waterloo (gross, 6 Spieler)",
    675 	"Water Werks (Mega 8 players)",					 "Wasserwerk (sehr gross, 8 Spieler)",
    676 	"Warlord's Lake (Sm 4 players)",					 "Der See des Kriegsgottes (klein, 4 Spieler)",
    677 	"Zama (Sm 4 players)",								 "Zama (klein, 4 Spieler)",
    678 //#endif
    679         NULL
    680 };
    681 #endif
    682 #ifdef FRENCH
    683 char const *EngMisStr[] = {
    684 
    685 	"A Path Beyond (Lg)",					"Le Passage (Max)",
    686 	"Central Conflict (Lg)",				"Conflit Central (Max)",
    687 	"Coastal Influence (Med)",				"Le Chant des Canons (Moy)",
    688 	"Combat Alley (Med)",					"Aux Armes! (Moy)",
    689 	"Desolation (Lg)",						"D‚solation (Max)",
    690 	"Dugout Isle (Med)",						"L'Ile Maudite (Moy)",
    691 	"Equal Opportunity (Sm)",				"A Chances Egales (Min)",
    692 	"First Come, First Serve (Sm)",		"La Loi du Plus Fort (Min)",
    693 	"Island Hoppers (Sm)",					"D'une Ile … l'autre (Min)",
    694 	"Island Wars (Lg)",						"Guerres Insulaires (Max)",
    695 	"Isle of Fury (Lg)",						"L'Ile de la Furie(Max)",
    696 	"Ivory Wastelands (Sm)",				"Terres d'Ivoire (Min)",
    697 	"Keep off the Grass (Sm)",				"Hors de mon Chemin (Min)",
    698 	"Marooned II (Med)",						"Isolement II (Moy)",
    699 	"Middle Mayhem (Sm)",					"Chaos Interne (Min)",
    700 	"No Escape (Med)",						"Le PiŠge (Moy)",
    701 	"No Man's Land (Med)",					"No Man's Land (Moy)",
    702 	"Normandy (Med)",							"Normandie (Moy)",
    703 	"North By Northwest (Lg)",				"Nord, Nord-Ouest (Max)",
    704 	"Pond Skirmish (Med)",					"Bain de Sang (Moy)",
    705 	"Raraku (Lg)",								"Raraku (Max)",
    706 	"Ridge War (Med)",						"Guerre au Sommet (Moy)",
    707 	"Shallow Grave (Med)",					"La Saveur de la Mort (Moy)",
    708 	"Treasure Isle (Med)",					"L'Ile au Tr‚sor (Moy)",
    709 
    710 	"Africa (Lg)",								"Afrique (Max)",
    711 	"Alaska Anarchy (Lg)",					"Anarchie en Alaska (Max)",
    712 	"All that Glitters... (Lg)",			"Tout ce qui brille... (Max)",
    713 	"Apre's Peace (Lg)",						"Une Paix Durement N‚goci‚e... (Max)",
    714 	"Antartica (Lg)",							"Antarctique (Max)",
    715 	"Armourgarden (Lg)",						"La Guerre des Blind‚s (Max)",
    716 	"Austraila (Med)",						"Australie (Moy)",
    717 	"Barrier to Entry (Lg)",				"BarriŠre … l'Entr‚e (Max)",
    718 	"Bavarian Blast (Med)",					"Tonnerre Bavarois (Moy)",
    719 	"Be Shore (Med)",							"Plages Menac‚es (Moy)",
    720 	"Bearing Straits (Med)",				"Droit Devant ! (Moy)",
    721 	"Blow Holes (Lg)",						"CratŠres (Max)",
    722 	"Bonsai (Sm)",								"Bonsa‹ (Min)",
    723 	"Brother Stalin (Lg)",					"FrŠre Staline (Max)",
    724 	"Bullseye (Lg)",							"L'oeil du Taureau (Max)",
    725 	"C&C (Med)",								"C&C (Moy)",
    726 	"Camos Canyon (Med)",					"Le Canyon (Moy)",
    727 	"Camos Coves (Lg)",						"Criques (Max)",
    728 	"Camos Cross (Lg)",						"La Croix de Guerre (Max)",
    729 	"Camos Crossing (Sm)",					"La Crois‚e des Chemins (Min)",
    730 	"Central Arena (Lg)",					"L'ArŠne Diabolique (Max)",
    731 	"Canyon River (Med)",					"Au Milieu Coule Une RiviŠre (Moy)",
    732 	"Crossroads (Sm)",						"Carrefours (Min)",
    733 	"Czech Mate (Lg)",						"TchŠque et Mat (Max)",
    734 	"Dday (Med)",								"Le Jour J (Moy)",
    735 	"Disaster Central (Lg)",				"D‚sastre Central (Max)",
    736 	"Docklands (Med)",						"L'Enfer des Docks (Moy)",
    737 	"East Coast (Med)",						"C“te Est (Moy)",
    738 	"Eastern Seaboard (Lg)",				"Rivages de l'Est (Max)",
    739 	"Finger Lake (Lg)",						"Le Lac de tous les Dangers (Max)",
    740 	"Fjords (Med)",							"Fjords (Moy)",
    741 	"Floodlands (Lg)",						"Campagne Lacustre (Max)",
    742 	"Forest under fire (Lg)",				"Forˆt en flammes (Max)",
    743 	"Four Corners (Lg)",						"4 Coins (Max)",
    744 	"Frostbit Fjords (Lg)",					"Fjords Gel‚s (Max)",
    745 	"Glenboig (Sm)",							"Glenboig (Min)",
    746 	"Hell Frozen Over (Lg)",				"Enfer de Glace Max)",
    747 	"India (Lg)",								"Inde (Max)",
    748 	"Indirect Fire (Lg)",					"Attaque Indirecte (Max)",
    749 	"Island Wars II (Lg)",					"Guerres Insulaires II (Max)",
    750 	"Italy (Lg)",								"Italie (Max)",
    751 	"Kabalo (Lg)",								"Kabalo (Max)",
    752 	"King of the Hills (Lg)",				"Le Roi des Montagnes (Max)",
    753 	"Lake Divide (Med)",						"La Guerre du Lac (Moy)",
    754 	"Lakelands (Lg)",							"Terres Submerg‚es (Max)",
    755 	"Land Ladder (Lg)",						"Jusqu'au Sommet (Max)",
    756 	"Lotsa Lakes (Lg)",						"Terres de Lacs (Max)",
    757 	"Lunar Battlefield (Lg Special)",	"Combat Lunaire (Max Sp‚cial)",
    758 	"Malibu Fields (Med)",					"Les Champs de Malibu (Moy)",
    759 	"Marshland (Med)",						"Mar‚cages (Moy)",
    760 	"MyLai Delta (Med)",						"Le Delta Mylai (Moy)",
    761 	"Natural Harbor (Med)",					"Port Naturel (Moy)",
    762 	"No Way Out (Lg)",						"Sans Issue (Max)",
    763 	"Normandy Landing (Lg)",				"Le D‚barquement (Max)",
    764 	"Ore Wars (Med)",							"La Guerre du Minerai (Moy)",
    765 	"Oz (Lg)",									"Oz (Max)",
    766 	"Pilgrim Fathers II (Lg)",				"Les PŠlerins 2 (Max)",
    767 	"Pip's Ice Tea (Med)",					"Les Tranch‚es de Glace (Moy)",
    768 	"Polar Panic (Lg)",						"Panique Polaire (Max)",
    769 	"Ponds (Med)",								"Les Etangs (Moy)",
    770 	"Putney (Lg)",								"La Meilleure D‚fense... (Max)",
    771 	"Return to Zion (Lg)",					"Retour … Sion (Max)",
    772 	"Ring of Land (Lg)",						"Le Cycle Infernal (Max)",
    773 	"River Basin (Lg)",						"Confrontation Navale (Max)",
    774 	"River Delta (Med)",						"Le Delta (Moy)",
    775 	"River Islands (Med)",					"C“tes … Surveiller de PrŠs (Moy)",
    776 	"River Maze (Sm)",						"Labyrinthe Fluvial (Min)",
    777 	"Rivers (Sm)",								"RiviŠres (Min)",
    778 	"Run the Gauntlet (Med)",				"Relevons le D‚fi ! (Moy)",
    779 	"Scappa Flow (Lg)",						"Combats Sanglants (Max)",
    780 	"Siberian Slaughter (Lg)",				"Carnage Sib‚rien (Max)",
    781 	"Sleepy Valley (Sm)",					"La Vall‚e Endormie (Min)",
    782 	"Snake River (Lg)",						"La RiviŠre aux Serpents (Max)",
    783 	"Snow Wars (Lg)",							"Guerres de Neige (Max)",
    784 	"Snowball fight (Lg)",					"Bataille de Boules de Neige (Max)",
    785 	"Snowy Island (Lg)",						"L'Ile sous la Neige (Max)",
    786 	"So Near So Far (Sm)",					"Si Loin, Si Proche (Min)",
    787 	"South America (Lg)",					"Am‚rique du Sud (Max)",
    788 	"Spring Line (Lg)",						"Ligne de Front (Max)",
    789 	"Star (Lg)",								"Etoile (Max)",
    790 	"Straighter & Narrower (Sm)",			"L'Entonnoir (Min)",
    791 	"TerrainSpotting (Sm)",					"TerrainSpotting (Min)",
    792 	"The Bay (Lg)",							"La Baie (Max)",
    793 	"The Garden (Lg)",						"Le Jardin (Max)",
    794 	"The Great Lakes (Med)",				"Les Grands Lacs (Moy)",
    795 	"The Ice Arena (Lg)",					"L'ArŠne de Glace (Max)",
    796 	"The Lake District (Lg)",				"Un Lac Imprenable (Max)",
    797 	"The Linked lands (Lg)",				"Passages … Gu‚ (Max)",
    798 	"The Mississippi (Med)",				"Mississippi (Moy)",
    799 	"The Sticky Bit (Lg)",					"Marasme (Max)",
    800 	"The Valley (Med)",						"La Vall‚e (Moy)",
    801 	"The Woods Today (Lg)",					"Aujoud'hui: la Mort ! (Max)",
    802 	"Things to Come (Lg)",					"D‚nouement Incertain (Max)",
    803 	"Tiger Core (Sm)",						"Le Coeur du Tigre (Min)",
    804 	"To the Core (Sm)",						"Le Coeur du Conflit (Min)",
    805 	"Tournament Hills (Lg)",				"Combat en Altitude (Max)",
    806 	"Tropical Storm (Med)",					"Ouragan Tropical (Moy)",
    807 	"Tundra Trouble (Lg)",					"La Toundra (Max)",
    808 	"Uk (Med)",									"Royaume Uni (Moy)",
    809 	"Undiscovered Country (Sm)",			"Terre Inconnue (Min)",
    810 	"United States (Med)",					"Etats Unis (Moy)",
    811 	"Volcano (Sm)",							"Le Volcan (Min)",
    812 	"Wastelands (Lg)",						"Terres D‚sol‚es (Max)",
    813 	"Water Works (Sm)",						"Jeux d'Eau (Min)",
    814 	"World Map (Med)",						"Carte du Monde (Moy)",
    815 	"Zambezi (Lg)",							"ZambŠze (Max)",
    816 //#if 0
    817 	"A Pattern of Islands (Lg 8 players)",			 "Archipel (Max. 8 joueurs)",
    818 	"Arena Valley Extreme (Mega 8 players)",		 "La Vall‚e de l'arŠne (XL 8 joueurs)",
    819 	"Around the Rim (Sm 4 players)",					 "Autour de la crˆte (Min. 4 joueurs)",
    820 	"Ashes to Ashes (Lg 6 players)",					 "R‚duit en cendres (Max. 6 joueurs)",
    821 	"Artic Wasteland (Mega 8 players)",				 "D‚solation arctique (XL 8 joueurs)",
    822 	"Badajoz (Med 4 players)",							 "Badjoz (Moy. 4 joueurs)",
    823 	"Baptism of Fire (Lg 6 players)",				 "Baptˆme du feu (Max. 6 joueurs)",
    824 	"Big Fish, Small Pond (Lg 6 players)",			 "Gros poisson, Min. Mare (Max. 6 joueurs)",
    825 	"Blue Lakes (Lg 8 players)",						 "Lacs bleus (Max. 8 joueurs)",
    826 	"Booby Traps (Mega 8 players)",					 "PiŠges (XL 8 joueurs)",
    827 	"Bridgehead (Lg 6 players)",						 "Tˆte de pont (Max. 6 joueurs)",
    828 	"Butterfly Bay (Lg 6 players)",					 "La baie du papillon (Max. 6 joueurs)",
    829 	"Central Conflict Extreme (Mega 8 players)",	 "Conflit central extrˆme (XL 8 joueurs)",
    830 	"Circles of Death (Mega 8 players)",			 "Les cercles de la mort (XL 8 joueurs)",
    831 	"Cold Front (Med 6 players)",						 "Front froid ( Moy. 6 joueurs)",
    832 	"Cold Pass (Med 4 players)",						 "La Passe Glac‚e (Moy. 4 joueurs)",
    833 	"Combat Zones (Mega 8 players)",					 "Zones de combat (XL 8 joueurs)",
    834 	"Conflict Cove (Sm 4 players)",					 "La Crique du conflit (Min. 4 joueurs)",
    835 	"Culloden Moor (Med 8 players)",					 "La Lande de Culloden (Moy. 8 joueurs)",
    836 	"Damnation Alley (Mega 8 players)",				 "Le chemin de la damnation (XL 8 joueurs)",
    837 	"Death Valley (Mega 8 players)",					 "La vall‚e de la mort (XL 8 joueurs)",
    838 	"Deep Six (Mega 8 players)",						 "Six de profondeur (XL 8 joueurs)",
    839 	"Destruction Derby (Mega 8 players)",			 "Stock car (XL 8 joueurs)",
    840 	"Diamonds Aren't Forever (Mega 8 players)",	 "Les diamants ne sont pas ‚ternels (XL 8 joueurs)",
    841 	"Elysium (Sm 4 players)",							 "Elys‚e (Min. 4 joueurs)",
    842 	"Equal Shares (Lg 4 players)",					 "Parts ‚gales (Max. 4 joueurs)",
    843 	"Frost Bitten (Mega 8 players)",					 "Engelures (XL 8 joueurs)",
    844 	"Frozen Valley (Med 6 players)",					 "La Vall‚e glac‚e (Moy. 6 joueurs)",
    845 	"Gettysburg (Sm 4 players)",						 "Gettysburg (Min. 4 joueurs)",
    846 	"Glacial Valley (Sm 4 players)",					 "Vall‚e de glace (Min. 4 joueurs)",
    847 	"Gold Coast (Med 6 players)",						 "La c“te dor‚e (Moy. 6 joueurs)",
    848 	"Gold Rush (Lg 4 players)",						 "La ru‚e vers l'or (Max. 4 joueurs)",
    849 	"Habitat (Lg 4 players)",							 "Habitat (Max. 4 joueurs)",
    850 	"Hades Frozen Over (Sm 4 players)",				 "Les enfers glac‚s (Min. 4 joueurs)",
    851 	"Hamburger Hill (Mega 8 players)",				 "Hamburger Hill (XL 8 joueurs)",
    852 	"Hastings (Sm 4 players)",							 "Hastings (Min. 4 joueurs)",
    853 	"Hell's Pass (Med 6 players)",					 "La route de l'enfer (Moy. 6 joueurs)",
    854 	"Holy Grounds (Mega 8 players)",					 "Terres saintes (XL 8 joueurs)",
    855 	"Ice Bergs (Med 6 players)",						 "Icebergs (Moy. 6 joueurs)",
    856 	"Ice Station (Lg 6 players)",						 "Station glac‚e (Max. 6 joueurs)",
    857 	"Ice Queen (Lg 4 players)",						 "Reine des glaces (Max. 4 joueurs)",
    858 	"In the Sun (Med 6 players)",						 "Sous le soleil (Moy. 6 joueurs)",
    859 	"Innocents? (Mega 8 players)",					 "Innocents ? (XL 8 joueurs)",
    860 	"Islands (Med 8 players)",							 "Iles (Moy. 8 joueurs)",
    861 	"Island Plateau (Lg 4 players)",					 "Plateau des Œles (Max. 4 joueurs)",
    862 	"Island Wars Extreme (Mega 8 players)",		 "Guerres insulaires extrˆme (XL 8 joueurs)",
    863 	"Kananga (Med 6 players)",							 "Kananga (Moy. 6 joueurs)",
    864 	"King of the Hills Extreme (Mega 8 players)", "Roi des collines extrˆme (XL 8 joueurs)",
    865 	"Lake Land (Lg 8 players)",						 "Paysage lacustre (Max. 8 joueurs)",
    866 	"Land Locked (Lg 8 players)",						 "Enclave (Max. 8 joueurs)",
    867 	"Lanes (Med 8 players)",							 "Le parcours du combattant (Moy. 8 joueurs)",
    868 	"Leipzip (Sm 4 players)",							 "Leipzig (Min. 4 joueurs)",
    869 	"Meander (Lg 8 players)",							 "M‚andre (Max. 8 joueurs)",
    870 	"Mekong (Med 8 players)",							 "M‚kong (Moy. 8 joueurs)",
    871 	"Middle Ground (Med 8 players)",					 "Plateau m‚dian (Moy. 8 joueurs)",
    872 	"Naval Conquests (Mega 8 players)",				 "Conquˆtes navales (XL 8 joueurs)",
    873 	"On your Marks (Med 4 players)",					 "A vos marques (Moy. 4 joueurs)",
    874 	"Open Warfare (Mega 8 players)",					 "Guerre ouverte (XL 8 joueurs)",
    875 	"Ore Gardens (Lg 8 players)",						 "Jardins de minerai (Max. 8 joueurs)",
    876 	"Potholes (Mega 8 players)",						 "Nids de poules (XL 8 joueurs)",
    877 	"Puddles (Med 4 players)",							 "Flaques (Moy. 4 joueurs)",
    878 	"Random Violence (Mega 8 players)",				 "Violence al‚atoire (XL 8 joueurs)",
    879 	"Revenge (Med 8 players)",							 "Vengeance (Moy. 8 joueurs)",
    880 	"Rias (Med 8 players)",								 "Rias (Moy. 8 joueurs)",
    881 	"River Crossing (Sm 4 players)",					 "Passage … gu‚ (Min. 4 joueurs)",
    882 	"River Rampage (Mega 8 players)",				 "RiviŠre d‚chaŒn‚e (XL 8 joueurs)",
    883 	"River Rapids (Lg 6 players)",					 "Rapides (Max. 6 joueurs)",
    884 	"Rivers Wild (Mega 8 players)",					 "RiviŠres sauvages (XL 8 joueurs)",
    885 	"Rorkes Drift (Lg 4 players)",					 "L'Exode de Rorkes (Max. 4 joueurs)",
    886 	"Seaside (Med 4 players)",							 "C“te (Moy. 4 joueurs)",
    887 	"Shades (Med 8 players)",							 "Ombres (Moy. 8 joueurs)",
    888 	"Smuggler's Cove (Lg 6 players)",				 "La Crique du contrebandier (Max. 6 joueurs)",
    889 	"Snow Garden (Sm 2 players)",						 "Jardin de neige (Min. 2 joueurs)",
    890 	"Stalingrad (Sm 4 players)",						 "Stalingrad (Min. 4 joueurs)",
    891 	"Sticks & Stones (Med 4 players)",				 "Bƒton & Roches (Moy. 4 joueurs)",
    892 	"Strathearn Valley (Lg 6 players)",				 "La Vall‚e de Strathearn (Max. 6 joueurs)",
    893 	"Super Bridgehead (Mega 8 players)",			 "Super tˆte de pont (XL 8 joueurs)",
    894 	"Super Mekong (Mega 8 players)",					 "Super M‚kong (XL 8 joueurs)",
    895 	"Super Ore Gardens (Mega 8 players)",			 "Super jardin de minerai (XL 8 joueurs)",
    896 	"Switch (Med 4 players)",							 "Permutation (Moy. 4 joueurs)",
    897 	"The Berg (Mega 8 players)",						 "Le Berg (XL 8 joueurs)",
    898 	"The Boyne (Med 4 players)",						 "Le Boyne (Moy. 4 joueurs)",
    899 	"The Bulge (Sm 4 players)",						 "Le bombement (Min. 4 joueurs)",
    900 	"The Cauldron (Lg 6 players)",					 "Le chaudron (Max. 6 joueurs)",
    901 	"The Finger (Lg 6 players)",						 "Le doigt (Max. 6 joueurs)",
    902 	"The Hills Have Eyes (Mega 8 players)",		 "Les collines ont des yeux (XL 8 joueurs)",
    903 	"The Keyes (Med 6 players)",						 "Les Keyes (Moy. 6 joueurs)",
    904 	"The Lakes (Med 8 players)",						 "Les lacs (Moy. 8 joueurs)",
    905 	"The Neck (Med 6 players)",						 "Le goulot (Moy. 6 joueurs)",
    906 	"The Web (Lg 6 players)",							 "La toile (Max. 6 joueurs)",
    907 	"To the Core (Lg 4 players)",						 "Jusqu'au cour (Max. 4 joueurs)",
    908 	"Trafalgar (Lg 4 players)",						 "Trafalgar (Max. 4 joueurs)",
    909 	"Twin Rivers (Sm 4 players)",						 "Les deux riviŠres (Min. 4 joueurs)",
    910 	"Umtumbo Gorge (Lg 4 players)",					 "La Gorge de Umtumbo (Max. 4 joueurs)",
    911 	"Watch Your Step Extreme (Mega 8 players)",	 "Pas-…-pas extrˆme (XL 8 joueurs)",
    912 	"Waterfalls (Lg 8 players)",						 "Chutes d'eau (Max. 8 joueurs)",
    913 	"Waterloo Revisited (Lg 6 players)",			 "Waterloo II (Max. 6 joueurs)",
    914 	"Water Werks (Mega 8 players)",					 "Jeux d'eau (XL 8 joueurs)",
    915 	"Warlord's Lake (Sm 4 players)",					 "Le lac du guerrier (Min. 4 joueurs)",
    916 	"Zama (Sm 4 players)",								 "Zama (Min. 4 joueurs)",
    917 //#endif
    918 	NULL
    919 };
    920 #endif
    921 
    922 
    923 /*
    924 ******************************** Prototypes *********************************
    925 */
    926 static int Net_Join_Dialog(void);
    927 static int Request_To_Join (char *playername, int join_index,
    928 	HousesType house, PlayerColorType color);
    929 static void Unjoin_Game(char *namebuf,JoinStateType joinstate,
    930 	ListClass *gamelist, ColorListClass *playerlist, int game_index,
    931 	int goto_lobby, int msg_x, int msg_y, int msg_h, int send_x, int send_y,
    932 	int msg_len);
    933 static void Send_Join_Queries(int curgame, JoinStateType joinstate,
    934 	int gamenow, int playernow, int chatnow, char *myname, int init = 0);
    935 static JoinEventType Get_Join_Responses(JoinStateType *joinstate,
    936 	ListClass *gamelist, ColorListClass *playerlist, int join_index,
    937 	char *my_name, RejectType *why);
    938 static int Net_New_Dialog(void);
    939 static JoinEventType Get_NewGame_Responses(ColorListClass *playerlist,
    940 	int *color_used);
    941 void Start_WWChat(ColorListClass *playerlist);
    942 int Update_WWChat(void);
    943 
    944 
    945 #define PCOLOR_BROWN	PCOLOR_GREY
    946 
    947 
    948 /***********************************************************************************************
    949  * Init_Network -- initializes network stuff                               						  *
    950  *                                                                         						  *
    951  * INPUT:                                                                  						  *
    952  *		none.																												  *
    953  *                                                                         						  *
    954  * OUTPUT:                                                                 						  *
    955  *		true = Initialization OK, false = error																  *
    956  *                                                                         						  *
    957  * WARNINGS:                                                               						  *
    958  *		none.																												  *
    959  *                                                                         						  *
    960  * HISTORY:                                                                						  *
    961  *   02/14/1995 BR : Created.                                              						  *
    962  *=============================================================================================*/
    963 bool Init_Network (void)
    964 {
    965 	NetNumType net;
    966 	NetNodeType node;
    967 #ifdef WINSOCK_IPX
    968 	assert ( PacketTransport != NULL );
    969 #endif	//WINSOCK_IPX
    970 
    971 	//------------------------------------------------------------------------
    972 	//	This call allocates all necessary queue buffers, allocates Real-mode
    973 	//	memory, and commands IPX to start listening on the Global Channel.
    974 	//------------------------------------------------------------------------
    975 	if (!Ipx.Init()) {
    976 		return(false);
    977 	}
    978 
    979 	//------------------------------------------------------------------------
    980 	//	Set up the IPX manager to cross a bridge
    981 	//------------------------------------------------------------------------
    982 	if (Session.Type != GAME_INTERNET) {
    983 		if (Session.IsBridge) {
    984 			Session.BridgeNet.Get_Address(net,node);
    985 			Ipx.Set_Bridge(net);
    986 		}
    987 	}
    988 
    989 	return(true);
    990 
    991 }	/* end of Init_Network */
    992 
    993 
    994 /***********************************************************************************************
    995  * Shutdown_Network -- shuts down network stuff                            						  *
    996  *                                                                         						  *
    997  * INPUT:                                                                  						  *
    998  *		none.																												  *
    999  *                                                                         						  *
   1000  * OUTPUT:                                                                 						  *
   1001  *		none.																												  *
   1002  *                                                                         						  *
   1003  * WARNINGS:                                                               						  *
   1004  *		none.																												  *
   1005  *                                                                         						  *
   1006  * HISTORY:                                                                						  *
   1007  *   02/14/1995 BR : Created.                                              						  *
   1008  *=============================================================================================*/
   1009 void Shutdown_Network (void)
   1010 {
   1011 //
   1012 // Note: The thought behind this section of code was that if the program
   1013 // terminates early, without an EventClass::EXIT event, it still needs to
   1014 // tell the other systems that it's gone, so it would send a SIGN_OFF packet.
   1015 // BUT, this causes a sync bug if the systems are running slow and this system
   1016 // is running ahead of the others; it will send the NET_SIGN_OFF >>before<<
   1017 // the other system execute their EventClass::EXIT event, and the other systems
   1018 // will kill the connection at some random Frame # & turn my stuff over to
   1019 // the computer possibly at different times.
   1020 // BRR, 10/29/96
   1021 //
   1022 #if 0
   1023 	//------------------------------------------------------------------------
   1024 	// If the Players vector contains at least one name, send a sign-off
   1025 	// packet.  If 'Players' is empty, I have no name, so there's no point
   1026 	// in sending a sign-off.
   1027 	//------------------------------------------------------------------------
   1028 	if (Session.Players.Count()) {
   1029 		//.....................................................................
   1030 		// Build a sign-off packet & send it
   1031 		//.....................................................................
   1032 		memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   1033 		Session.GPacket.Command = NET_SIGN_OFF;
   1034 		strcpy (Session.GPacket.Name, Session.Players[0]->Name);
   1035 
   1036 		Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   1037 			0, NULL);
   1038 		Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   1039 			0, NULL);
   1040 
   1041 		if (Session.IsBridge	&& !Winsock.Get_Connected()) {
   1042 			Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType), 0,
   1043 				&Session.BridgeNet);
   1044 			Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType), 0,
   1045 				&Session.BridgeNet);
   1046 		}
   1047 
   1048 		//.....................................................................
   1049 		//	Wait for the packets to finish going out (or the Global Channel
   1050 		// times out)
   1051 		//.....................................................................
   1052 		for (;;) {
   1053 			if (Ipx.Global_Num_Send()==0) {
   1054 				break;
   1055 			}
   1056 			Ipx.Service();
   1057 		}
   1058 	}
   1059 #endif
   1060 
   1061 	//------------------------------------------------------------------------
   1062 	//	If I was in a game, I'm not now, so clear the game name
   1063 	//------------------------------------------------------------------------
   1064 	Session.GameName[0] = 0;
   1065 
   1066 }	/* end of Shutdown_Network */
   1067 
   1068 
   1069 /***********************************************************************************************
   1070  * Process_Global_Packet -- responds to remote queries                     						  *
   1071  *                                                                         						  *
   1072  * The only commands from other systems this routine responds to are NET_QUERY_GAME				  *
   1073  * and NET_QUERY_PLAYER.  The other commands are too context-specific to be able					  *
   1074  * to handle here, such as joining the game or signing off; but this routine handles			  *
   1075  * the majority of the program's needs.																		  *
   1076  *                                                                         						  *
   1077  * INPUT:                                                                  						  *
   1078  *		packet		ptr to packet to process																	  *
   1079  *		address		source address of sender																	  *
   1080  *                                                                         						  *
   1081  * OUTPUT:                                                                 						  *
   1082  *		true = packet was processed, false = wasn't															  *
   1083  *                                                                         						  *
   1084  * WARNINGS:                                                               						  *
   1085  *		Session.GameName must have been filled in before this function can be called.				  *
   1086  *                                                                         						  *
   1087  * HISTORY:                                                                						  *
   1088  *   02/15/1995 BR : Created.                                              						  *
   1089  *=============================================================================================*/
   1090 bool Process_Global_Packet(GlobalPacketType *packet, IPXAddressClass *address)
   1091 {
   1092 	GlobalPacketType mypacket;
   1093 
   1094 	//------------------------------------------------------------------------
   1095 	// If our Players vector is empty, just return.
   1096 	//------------------------------------------------------------------------
   1097 	if (Session.Players.Count()==0) {
   1098 		return (true);
   1099 	}
   1100 
   1101 	//------------------------------------------------------------------------
   1102 	//	Another system asking what game this is
   1103 	//------------------------------------------------------------------------
   1104 	if (packet->Command==NET_QUERY_GAME && Session.NetStealth==0) {
   1105 
   1106 		//.....................................................................
   1107 		//	If the game is closed, let every player respond, and let the sender of
   1108 		//	the query sort it all out.  This way, if the game's host exits the game,
   1109 		//	the game still shows up on other players' dialogs.
   1110 		//	If the game is open, only the game owner may respond.
   1111 		//.....................................................................
   1112 		if (strlen(Session.GameName) > 0 && ((!Session.NetOpen) ||
   1113 			(Session.NetOpen &&
   1114 				!strcmp(Session.Players[0]->Name,Session.GameName)))) {
   1115 
   1116 			memset (&mypacket, 0, sizeof(GlobalPacketType));
   1117 
   1118 			mypacket.Command = NET_ANSWER_GAME;
   1119 			strcpy(mypacket.Name, Session.GameName);
   1120 			mypacket.GameInfo.IsOpen = Session.NetOpen;
   1121 
   1122 			Ipx.Send_Global_Message (&mypacket, sizeof(GlobalPacketType), 1,
   1123 				address);
   1124 		}
   1125 		return(true);
   1126 	}
   1127 
   1128 	//------------------------------------------------------------------------
   1129 	//	Another system asking what player I am
   1130 	//------------------------------------------------------------------------
   1131 	else if (packet->Command==NET_QUERY_PLAYER &&
   1132 		!strcmp (packet->Name, Session.GameName) &&
   1133 			(strlen(Session.GameName) > 0) && Session.NetStealth==0) {
   1134 
   1135 		memset (&mypacket, 0, sizeof(GlobalPacketType));		// changed DRD 9/26
   1136 
   1137 		mypacket.Command = NET_ANSWER_PLAYER;
   1138 		strcpy(mypacket.Name, Session.Players[0]->Name);
   1139 		mypacket.PlayerInfo.House = Session.House;
   1140 		mypacket.PlayerInfo.Color = Session.ColorIdx;
   1141 		mypacket.PlayerInfo.NameCRC = Compute_Name_CRC(Session.GameName);
   1142 
   1143 		Ipx.Send_Global_Message (&mypacket, sizeof(GlobalPacketType), 1, address);
   1144 		return(true);
   1145 	}
   1146 
   1147 	return(false);
   1148 
   1149 }	/* end of Process_Global_Packet */
   1150 
   1151 
   1152 /***********************************************************************************************
   1153  * Destroy_Connection -- destroys the given connection													  *
   1154  *                                                                         						  *
   1155  * Call this routine when a connection goes bad, or another player signs off.						  *
   1156  *                                                                         						  *
   1157  * INPUT:                                                                  						  *
   1158  *		id			connection ID to destroy; this should be the HousesType of the player			  *
   1159  *             on this connection																				  *
   1160  *		error		0 = user signed off; 1 = connection error; otherwise, no error is shown.		  *
   1161  *                                                                         						  *
   1162  * OUTPUT:                                                                 						  *
   1163  *		none.																												  *
   1164  *                                                                         						  *
   1165  * WARNINGS:                                                               						  *
   1166  *		none.																												  *
   1167  *                                                                         						  *
   1168  * HISTORY:                                                                						  *
   1169  *   04/22/1995 BR : Created.                                              						  *
   1170  *=============================================================================================*/
   1171 void Destroy_Connection(int id, int error)
   1172 {
   1173 	int i;
   1174 	HouseClass *housep;
   1175 	char txt[80];
   1176 
   1177 	if (Debug_Print_Events) {
   1178 		printf("Destroying connection for house %d (%s)\n",
   1179 			id,HouseClass::As_Pointer((HousesType)id)->IniName);
   1180 	}
   1181 
   1182 	//------------------------------------------------------------------------
   1183 	//	Do nothing if the house isn't human.
   1184 	//------------------------------------------------------------------------
   1185 	housep = HouseClass::As_Pointer((HousesType)id);
   1186 	if (!housep || !housep->IsHuman)
   1187 		return;
   1188 
   1189 	//------------------------------------------------------------------------
   1190 	//	Create a message to display to the user
   1191 	//------------------------------------------------------------------------
   1192 	txt[0] = '\0';
   1193 	if (error==1) {
   1194 		sprintf(txt,Text_String(TXT_CONNECTION_LOST), housep->IniName);
   1195 	} else if (error==0) {
   1196 		sprintf(txt,Text_String(TXT_LEFT_GAME), housep->IniName);
   1197 	}
   1198 
   1199 	if (strlen(txt)) {
   1200 		Session.Messages.Add_Message (NULL,0, txt, housep->RemapColor, TPF_TEXT, Rule.MessageDelay * TICKS_PER_MINUTE);
   1201 		Map.Flag_To_Redraw(false);
   1202 	}
   1203 
   1204 	//------------------------------------------------------------------------
   1205 	// Remove this player from the Players vector
   1206 	//------------------------------------------------------------------------
   1207 	for (i = 0; i < Session.Players.Count(); i++) {
   1208 		if (!stricmp(Session.Players[i]->Name,housep->IniName)) {
   1209 			delete Session.Players[i];
   1210 			Session.Players.Delete(Session.Players[i]);
   1211 			break;
   1212 		}
   1213 	}
   1214 
   1215 	//------------------------------------------------------------------------
   1216 	//	Delete the IPX connection
   1217 	//------------------------------------------------------------------------
   1218 	Ipx.Delete_Connection(id);
   1219 
   1220 	//------------------------------------------------------------------------
   1221 	//	Turn the player's house over to the computer's AI
   1222 	//------------------------------------------------------------------------
   1223 	housep->IsHuman = false;
   1224 	housep->IQ = Rule.MaxIQ;
   1225 	strcpy (housep->IniName,Text_String(TXT_COMPUTER));
   1226 
   1227 	Session.NumPlayers--;
   1228 
   1229 	//------------------------------------------------------------------------
   1230 	//	If we're the last player left, tell the user.
   1231 	//------------------------------------------------------------------------
   1232 	if (Session.NumPlayers == 1) {
   1233 		sprintf(txt,"%s",Text_String(TXT_JUST_YOU_AND_ME));
   1234 		Session.Messages.Add_Message (NULL, 0, txt, housep->RemapColor,
   1235 			TPF_TEXT, Rule.MessageDelay * TICKS_PER_MINUTE);
   1236 		Map.Flag_To_Redraw(false);
   1237 	}
   1238 
   1239 }	/* end of Destroy_Connection */
   1240 
   1241 
   1242 /***********************************************************************************************
   1243  * Remote_Connect -- handles connecting this user to others                						  *
   1244  *                                                                         						  *
   1245  * INPUT:                                                                  						  *
   1246  *		none.																												  *
   1247  *                                                                         						  *
   1248  * OUTPUT:                                                                 						  *
   1249  *		true = connections established; false = not															  *
   1250  *                                                                         						  *
   1251  * WARNINGS:                                                               						  *
   1252  *		none.																												  *
   1253  *                                                                         						  *
   1254  * HISTORY:                                                                						  *
   1255  *   02/14/1995 BR : Created.                                              						  *
   1256  *=============================================================================================*/
   1257 bool Remote_Connect(void)
   1258 {
   1259 	int rc;
   1260 	int stealth;				// original state of Session.NetStealth flag
   1261 
   1262 	//------------------------------------------------------------------------
   1263 	//	Init network timing parameters; these values should work for both a
   1264 	// "real" network, and a simulated modem network (ie Kali)
   1265 	//------------------------------------------------------------------------
   1266 	Ipx.Set_Timing (	30, 		// retry 2 times per second
   1267 							-1, 		// ignore max retries
   1268 							600);		// give up after 10 seconds
   1269 
   1270 	//------------------------------------------------------------------------
   1271 	//	Save the original value of the NetStealth flag, so we can turn stealth
   1272 	//	off for now (during this portion of the dialogs, we must show ourselves)
   1273 	//------------------------------------------------------------------------
   1274 	stealth = Session.NetStealth;
   1275 	Session.NetStealth = 0;
   1276 
   1277 	//------------------------------------------------------------------------
   1278 	//	Init my game name to 0-length, since I haven't joined any game yet.
   1279 	//------------------------------------------------------------------------
   1280 	Session.GameName[0] = 0;
   1281 
   1282 	//------------------------------------------------------------------------
   1283 	//	The game is now "open" for joining.  Close it as soon as we exit this
   1284 	//	routine.
   1285 	//------------------------------------------------------------------------
   1286 	Session.NetOpen = 1;
   1287 
   1288 	//------------------------------------------------------------------------
   1289 	//	Keep looping until something useful happens.
   1290 	//------------------------------------------------------------------------
   1291 	while (1) {
   1292 		//.....................................................................
   1293 		//	Pop up the network Join/New dialog
   1294 		//.....................................................................
   1295 		rc = Net_Join_Dialog();
   1296 
   1297 		//.....................................................................
   1298 		//	-1 = user selected Cancel
   1299 		//.....................................................................
   1300 		if (rc==-1) {
   1301 			Session.NetStealth = stealth;
   1302 			Session.NetOpen = 0;
   1303 			return(false);
   1304 		}
   1305 
   1306 		//.....................................................................
   1307 		//	0 = user has joined an existing game; save values & return
   1308 		//.....................................................................
   1309 		else if (rc==0) {
   1310 			Session.Write_MultiPlayer_Settings ();
   1311 			Session.NetStealth = stealth;
   1312 			Session.NetOpen = 0;
   1313 
   1314 			return(true);
   1315 		}
   1316 
   1317 		//.....................................................................
   1318 		//	1 = user requests New Network Game
   1319 		//.....................................................................
   1320 		else if (rc==1) {
   1321 			//..................................................................
   1322 			//	Pop up the New Network Game dialog; if user selects OK, return
   1323 			//	'true'; otherwise, return to the Join Dialog.
   1324 			//..................................................................
   1325 			if (Net_New_Dialog()) {
   1326 				Session.Write_MultiPlayer_Settings ();
   1327 				Session.NetStealth = stealth;
   1328 				Session.NetOpen = 0;
   1329 
   1330 				return(true);
   1331 			} else {
   1332 				continue;
   1333 			}
   1334 		}
   1335 	}
   1336 
   1337 }	/* end of Remote_Connect */
   1338 
   1339 
   1340 
   1341 /***********************************************************************************************
   1342  * Net_Join_Dialog -- lets user join an existing game or start a new one                       *
   1343  *                                                                                             *
   1344  * This dialog displays an edit field for the player's name, and a list of all non-stealth-    *
   1345  * mode games.  Clicking once on a game name displays a list of who's in that game.  Clicking  *
   1346  * "New" takes the user to the Net_New dialog, where he waits for other users to join his      *
   1347  * game.  All other input is done through this dialog.                                         *
   1348  *                                                                                             *
   1349  * The dialog has several "states":                                                            *
   1350  *                                                                                             *
   1351  *   1) Initially, it waits for the user to fill in his/her name and then to select Join or    *
   1352  *      New; if New is selected, this dialog is exited.                                        *
   1353  *                                                                                             *
   1354  *   2) If Join is selected, the Join & New buttons are removed, but the Cancel button remains.*
   1355  *      The join request is transmitted to the game's owner, and the message "Waiting for      *
   1356  *      Confirmation" is displayed, until a confirmation or denial is received from the game's *
   1357  *      owner.  The user may click Cancel at this point to cancel the join request.            *
   1358  *      (Once Join is selected, the name editing field is disabled, and becomes a display-only *
   1359  *      field.  If cancel is selected, it reappears as an edit field.) The user can still click*
   1360  *      around & see who's in which games.                                                     *
   1361  *                                                                                             *
   1362  *   3) If the join request is denied, the dialog re-initializes to its pre-join state; the    *
   1363  *      Join & New buttons reappear, & the Name field is available again.                      *
   1364  *                                                                                             *
   1365  *   4) If join confirmation is obtained, the message changes to show all the current game	  *
   1366  *      settings.  The user cannot click around & look at other games any more.					  *
   1367  *                                                                                             *
   1368  * Any game running in Stealth mode won't show up on this dialog.                              *
   1369  *                                                                                             *
   1370  * The 'Players' vector matches one-for-one the contents of the list box.  The local system	  *
   1371  * is always listed first; the IPX Address of the local system will NOT be valid in the		  *
   1372  * Players vector.  The Games & Players vectors should be left filled in even after this		  *
   1373  * routine is exited; their contents are used to form connections to the other players,		  *
   1374  * after the scenario has been loaded.																			  *
   1375  *                                                                                             *
   1376  * The 'Chat' vector contains the address of everyone who sends me a chat announcement.		  *
   1377  * The address field is used to send everyone my outgoing messages.  The LastTime				  *
   1378  * field is used as a timeout; if enough time goes by & we don't hear from this node,			  *
   1379  * we ping him, requesting a CHAT_ANNOUNCE if he's still in chat.  If we don't hear				  *
   1380  * from him after that, we remove him from our list.														  *
   1381  *                                                                                             *
   1382  * INPUT:                                                                                      *
   1383  *      none.                                                                                  *
   1384  *                                                                                             *
   1385  * OUTPUT:                                                                                     *
   1386  *      -1 = cancel, 0 = OK, 1 = New net game requested                                        *
   1387  *                                                                                             *
   1388  * WARNINGS:                                                                                   *
   1389  *      none.                                                                                  *
   1390  *                                                                                             *
   1391  * HISTORY:                                                                                    *
   1392  *   02/14/1995 BR : Created.                                                                  *
   1393  *=============================================================================================*/
   1394 static int Net_Join_Dialog(void)
   1395 {
   1396 	//------------------------------------------------------------------------
   1397 	//	Dialog & button dimensions
   1398 	//------------------------------------------------------------------------
   1399 		int d_dialog_w = 320 *RESFACTOR;											// dialog width
   1400 		int d_dialog_h = 200 *RESFACTOR;											// dialog height
   1401 		int d_dialog_x = ((320*RESFACTOR - d_dialog_w) / 2);				// dialog x-coord
   1402 		int d_dialog_y = ((200*RESFACTOR - d_dialog_h) / 2);				// centered y-coord
   1403 		int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);		// center x-coord
   1404 
   1405 		int d_txt6_h = 6 *RESFACTOR+1;												// ht of 6-pt text
   1406 		int d_margin1 = 17 *RESFACTOR;												// large margin
   1407 		int d_margin2 = 7 *RESFACTOR;												// small margin
   1408 
   1409 		int d_name_w = 70 *RESFACTOR;
   1410 		int d_name_h = 9 *RESFACTOR;
   1411 		int d_name_x = d_dialog_x + (d_dialog_w / 4) - (d_name_w / 2);
   1412 		int d_name_y = d_dialog_y + d_margin2 + d_txt6_h + (2*RESFACTOR);
   1413 
   1414 #ifdef OLDWAY
   1415 		int d_gdi_w = 40 *RESFACTOR;
   1416 		int d_gdi_h = 9 *RESFACTOR;
   1417 		int d_gdi_x = d_dialog_cx - d_gdi_w;
   1418 		int d_gdi_y = d_name_y;
   1419 
   1420 		int d_nod_w = 40 *RESFACTOR;
   1421 		int d_nod_h = 9 *RESFACTOR;
   1422 		int d_nod_x = d_dialog_cx;
   1423 		int d_nod_y = d_name_y;
   1424 #else
   1425 		int d_house_w = 60 *RESFACTOR;
   1426 		int d_house_h = (8 * 5 *RESFACTOR);
   1427 		int d_house_x = d_dialog_cx - (d_house_w / 2);
   1428 		int d_house_y = d_name_y;
   1429 #endif
   1430 
   1431 		int d_color_w = 10 *RESFACTOR;
   1432 		int d_color_h = 9 *RESFACTOR;
   1433 		int d_color_y = d_name_y;
   1434 		int d_color_x = d_dialog_x + ((d_dialog_w / 4) * 3) - (d_color_w * 3);
   1435 
   1436 		int d_gamelist_w = 155 *RESFACTOR;
   1437 		int d_gamelist_h = ((6 * 6) + 3) *RESFACTOR;		// 6 rows high
   1438 		int d_gamelist_x = d_dialog_x + d_margin1 - 2*RESFACTOR;
   1439 		int d_gamelist_y = d_color_y + d_color_h + d_margin2 + 2*RESFACTOR/*KO + d_txt6_h + d_margin2*/;
   1440 
   1441 //BG		int d_playerlist_w = 113 *RESFACTOR;
   1442 	int d_playerlist_w = 118 *RESFACTOR;
   1443 		int d_playerlist_h = ((6 * 6) + 3) *RESFACTOR;		// 6 rows high
   1444 		int d_playerlist_x = d_dialog_x + d_dialog_w - (d_margin1 + d_playerlist_w - 2*RESFACTOR);
   1445 		int d_playerlist_y = d_color_y + d_color_h + d_margin2 + 2*RESFACTOR/*KO + d_txt6_h + d_margin2*/;
   1446 
   1447 		int d_count_w = 25 *RESFACTOR;
   1448 		int d_count_h = d_txt6_h;
   1449 		int d_count_x = d_gamelist_x + (d_gamelist_w / 2);
   1450 		int d_count_y = d_gamelist_y + d_gamelist_h + d_margin2;
   1451 
   1452 		int d_level_w = 25 *RESFACTOR;
   1453 		int d_level_h = d_txt6_h;
   1454 		int d_level_x = d_gamelist_x + (d_gamelist_w / 2);
   1455 		int d_level_y = d_count_y + d_count_h;
   1456 
   1457 		int d_credits_w = 25 *RESFACTOR;
   1458 		int d_credits_h = d_txt6_h;
   1459 		int d_credits_x = d_gamelist_x + (d_gamelist_w / 2);
   1460 		int d_credits_y = d_level_y + d_level_h;
   1461 
   1462 		int d_aiplayers_w = 25 *RESFACTOR;
   1463 		int d_aiplayers_h = d_txt6_h;
   1464 		int d_aiplayers_x = d_gamelist_x + (d_gamelist_w / 2);
   1465 		int d_aiplayers_y = d_credits_y + d_level_h;
   1466 
   1467 		int d_options_w = d_playerlist_w;
   1468 		int d_options_h = ((5 * 6) + 4) *RESFACTOR;
   1469 		int d_options_x = d_playerlist_x;
   1470 		int d_options_y = d_playerlist_y + d_playerlist_h + d_margin2 - (2*RESFACTOR);
   1471 
   1472 		int d_message1_w = d_dialog_w - (d_margin1 * 2) + 4*RESFACTOR;
   1473 		int d_message1_h = (14 * d_txt6_h) +3*RESFACTOR;
   1474 		int d_message1_x = d_dialog_x + (d_dialog_w-d_message1_w)/2;
   1475 		int d_message1_y = d_dialog_y + d_dialog_h - (27*RESFACTOR + d_message1_h);
   1476 
   1477 		int d_message2_w = d_message1_w;
   1478 		int d_message2_h = (8 * d_txt6_h) + 3*RESFACTOR;
   1479 		int d_message2_x = d_message1_x;
   1480 		int d_message2_y = d_dialog_y + d_dialog_h - (27*RESFACTOR + d_message2_h);
   1481 
   1482 #ifdef FRENCH              //VG2
   1483 		int d_join_w = 60 *RESFACTOR;
   1484 #else
   1485 		int d_join_w = 40 *RESFACTOR;
   1486 #endif
   1487 		int d_join_h = 9 *RESFACTOR;
   1488 		int d_join_x = d_dialog_x + (d_dialog_w / 6) - (d_join_w / 2);
   1489 		int d_join_y = d_dialog_y + d_dialog_h - d_join_h - 8*RESFACTOR;
   1490 
   1491 		int d_cancel_w = 50 *RESFACTOR;
   1492 		int d_cancel_h = 9 *RESFACTOR;
   1493 		int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
   1494 		int d_cancel_y = d_join_y;
   1495 
   1496 #ifdef FRENCH
   1497 		int d_new_w = 60 *RESFACTOR;
   1498 #else
   1499 		int d_new_w = 40 *RESFACTOR;
   1500 #endif
   1501 		int d_new_h = 9 *RESFACTOR;
   1502 		int d_new_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_new_w / 2);
   1503 		int d_new_y = d_join_y;
   1504 
   1505 		int d_send_w = d_message1_w;
   1506 		int d_send_h = 9 *RESFACTOR;
   1507 		int d_send_x = d_message1_x;
   1508 		int d_send_y = d_message1_y + d_message1_h;
   1509 
   1510 
   1511 	//------------------------------------------------------------------------
   1512 	//	Button Enumerations
   1513 	//------------------------------------------------------------------------
   1514 	enum {
   1515 		BUTTON_NAME = 100,
   1516 #ifdef OLDWAY
   1517 		BUTTON_GDI,
   1518 		BUTTON_NOD,
   1519 #else
   1520 		BUTTON_HOUSE,
   1521 #endif
   1522 		BUTTON_GAMELIST,
   1523 		BUTTON_PLAYERLIST,
   1524 		BUTTON_JOIN,
   1525 		BUTTON_CANCEL,
   1526 		BUTTON_NEW,
   1527 		BUTTON_COUNT,
   1528 		BUTTON_LEVEL,
   1529 		BUTTON_CREDITS,
   1530 		BUTTON_AI_PLAYERS,
   1531 		BUTTON_OPTIONS,
   1532 	};
   1533 
   1534 	//------------------------------------------------------------------------
   1535 	//	Redraw values: in order from "top" to "bottom" layer of the dialog
   1536 	//------------------------------------------------------------------------
   1537 	typedef enum {
   1538 		REDRAW_NONE = 0,
   1539 		REDRAW_PARMS,
   1540 		REDRAW_MESSAGE,
   1541 		REDRAW_COLORS,
   1542 		REDRAW_BUTTONS,
   1543 		REDRAW_BACKGROUND,
   1544 		REDRAW_ALL = REDRAW_BACKGROUND
   1545 	} RedrawType;
   1546 
   1547 	//------------------------------------------------------------------------
   1548 	//	Dialog variables
   1549 	//------------------------------------------------------------------------
   1550 	RedrawType display = REDRAW_ALL;		// redraw level
   1551 	bool process = true;						// process while true
   1552 	KeyNumType input;
   1553 	int cbox_x[] = {
   1554 							d_color_x,
   1555 							d_color_x + d_color_w,
   1556 							d_color_x + (d_color_w * 2),
   1557 							d_color_x + (d_color_w * 3),
   1558 							d_color_x + (d_color_w * 4),
   1559 							d_color_x + (d_color_w * 5),
   1560 							d_color_x + (d_color_w * 6),
   1561 							d_color_x + (d_color_w * 7),
   1562 							};
   1563 	char housetext[25] = "";				// buffer for house droplist
   1564 	int isdropped = 0;
   1565 
   1566 	JoinStateType joinstate = JOIN_NOTHING;	// current "state" of this dialog
   1567 	char namebuf[MPLAYER_NAME_MAX] = {0};		// buffer for player's name
   1568 	int playertabs[] = {71 *RESFACTOR};				// tabs for player list box
   1569 	int optiontabs[] = {8};					// tabs for player list box
   1570 	int game_index = -1;						// index of currently-selected game
   1571 	int join_index = -1;						// index of game we're joining
   1572 	int rc = 0;									// -1 = user cancelled, 1 = New
   1573 	JoinEventType event;						// event from incoming packet
   1574 	int i;										// loop counter
   1575 	char txt[128];
   1576 	char const *p;
   1577 	int parms_received = 0;					// 1 = game options received
   1578 	int found;
   1579 	NodeNameType *who;						// node to add to Players
   1580 	RejectType why;							// reason for rejection
   1581 	TTimerClass<SystemTimerClass> lastclick_timer;			// time b/w send periods
   1582 	int lastclick_idx = 0;					// index of item last clicked on
   1583 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   1584 	Session.Options.ScenarioDescription[0] = 0;	//Flag that we dont know the scenario name yet
   1585 
   1586 	char * item;
   1587 	unsigned long starttime;
   1588 	int load_game = 0;						// 1 = load saved game
   1589 	int goto_lobby;
   1590 	bool messages_have_focus = true;		// Gadget focus starts on the message system
   1591 
   1592 	//------------------------------------------------------------------------
   1593 	//	Buttons
   1594 	//------------------------------------------------------------------------
   1595 	GadgetClass *commands;										// button list
   1596 
   1597 	EditClass name_edt(BUTTON_NAME, namebuf, MPLAYER_NAME_MAX, TPF_TEXT,
   1598 		d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC);
   1599 
   1600 #ifdef OLDWAY
   1601 	TextButtonClass gdibtn(BUTTON_GDI, TXT_ALLIES, TPF_BUTTON, d_gdi_x, d_gdi_y, d_gdi_w);
   1602 	TextButtonClass nodbtn(BUTTON_NOD, TXT_SOVIET, TPF_BUTTON, d_nod_x, d_nod_y, d_nod_w);
   1603 #else
   1604 	Fancy_Text_Print("", 0, 0, 0, 0, TPF_TEXT);
   1605 	DropListClass housebtn(BUTTON_HOUSE, housetext, sizeof(housetext),
   1606 		TPF_TEXT,
   1607 		d_house_x, d_house_y, d_house_w, d_house_h,
   1608 		MFCD::Retrieve("BTN-UP.SHP"),
   1609 		MFCD::Retrieve("BTN-DN.SHP"));
   1610 #endif
   1611 
   1612 	ListClass gamelist(BUTTON_GAMELIST, d_gamelist_x, d_gamelist_y, d_gamelist_w, d_gamelist_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   1613 	ColorListClass playerlist(BUTTON_PLAYERLIST, d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   1614 	TextButtonClass joinbtn(BUTTON_JOIN, TXT_JOIN, TPF_BUTTON, d_join_x, d_join_y, d_join_w);
   1615 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON, d_cancel_x, d_cancel_y, d_cancel_w);
   1616 	TextButtonClass newbtn(BUTTON_NEW, TXT_NEW, TPF_BUTTON, d_new_x, d_new_y, d_new_w);
   1617 	GaugeClass countgauge(BUTTON_COUNT, d_count_x, d_count_y, d_count_w, d_count_h);
   1618 	GaugeClass levelgauge(BUTTON_LEVEL, d_level_x, d_level_y, d_level_w, d_level_h);
   1619 	GaugeClass creditsgauge(BUTTON_CREDITS, d_credits_x, d_credits_y, d_credits_w, d_credits_h);
   1620 	GaugeClass aiplayersgauge(BUTTON_AI_PLAYERS, d_aiplayers_x, d_aiplayers_y, d_aiplayers_w, d_aiplayers_h);
   1621 	CheckListClass optionlist(BUTTON_OPTIONS, d_options_x, d_options_y, d_options_w, d_options_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   1622 	StaticButtonClass descrip(0, "", TPF_CENTER|TPF_TEXT, d_dialog_x + 16*RESFACTOR, d_name_y, d_dialog_w - 32*RESFACTOR, d_txt6_h+1);
   1623 	StaticButtonClass staticcount(0, "     ", TPF_TEXT, d_count_x + d_count_w + 2*RESFACTOR, d_count_y);
   1624 	StaticButtonClass staticlevel(0, "     ", TPF_TEXT, d_level_x + d_level_w + 2*RESFACTOR, d_level_y);
   1625 	StaticButtonClass staticcredits(0, "          ", TPF_TEXT, d_credits_x + d_credits_w + 2*RESFACTOR, d_credits_y);
   1626 	StaticButtonClass staticaiplayers(0, "     ", TPF_TEXT, d_aiplayers_x + d_aiplayers_w + 2*RESFACTOR, d_aiplayers_y);
   1627 
   1628 	//------------------------------------------------------------------------
   1629 	//	Init the button states
   1630 	//------------------------------------------------------------------------
   1631 	//........................................................................
   1632 	// Name & Color
   1633 	//........................................................................
   1634 	Session.ColorIdx = Session.PrefColor;			// init my preferred color
   1635 	strcpy (namebuf, Session.Handle);				// set my name
   1636 	name_edt.Set_Text(namebuf,MPLAYER_NAME_MAX);
   1637 	if (Session.ColorIdx == PCOLOR_DIALOG_BLUE) {
   1638 		name_edt.Set_Color(&ColorRemaps[PCOLOR_REALLY_BLUE]);
   1639 	} else {
   1640 		name_edt.Set_Color(&ColorRemaps[Session.ColorIdx]);
   1641 	}
   1642 
   1643 	//........................................................................
   1644 	// List boxes
   1645 	//........................................................................
   1646 	playerlist.Set_Tabs(playertabs);
   1647 	playerlist.Set_Selected_Style(ColorListClass::SELECT_NORMAL);
   1648 
   1649 	optionlist.Set_Tabs(optiontabs);
   1650 	optionlist.Set_Read_Only(1);
   1651 
   1652 	optionlist.Add_Item(Text_String(TXT_BASES));
   1653 	optionlist.Add_Item(Text_String(TXT_ORE_SPREADS));
   1654 	optionlist.Add_Item(Text_String(TXT_CRATES));
   1655 	optionlist.Add_Item(Text_String(TXT_CAPTURE_THE_FLAG));
   1656 	optionlist.Add_Item(Text_String(TXT_SHADOW_REGROWS));
   1657 
   1658 	optionlist.Check_Item(0, Rule.IsMPBasesOn);
   1659 	optionlist.Check_Item(1, Rule.IsMPTiberiumGrow);
   1660 	optionlist.Check_Item(2, Rule.IsMPCrates);
   1661 	optionlist.Check_Item(3, Rule.IsMPCaptureTheFlag);
   1662 	optionlist.Check_Item(4, Rule.IsMPShadowGrow);
   1663 
   1664 	//........................................................................
   1665 	// House buttons
   1666 	//........................................................................
   1667 #ifdef OLDWAY
   1668 	if (Session.House==HOUSE_GOOD) {
   1669 		gdibtn.Turn_On();
   1670 	} else {
   1671 		nodbtn.Turn_On();
   1672 	}
   1673 #else
   1674 	for (HousesType house = HOUSE_USSR; house <= HOUSE_FRANCE; house++) {
   1675 //	for (HousesType house = HOUSE_FIRST; house <= HOUSE_TURKEY; house++) {
   1676 		housebtn.Add_Item(Text_String(HouseTypeClass::As_Reference(house).Full_Name()));
   1677 	}
   1678 	housebtn.Set_Selected_Index(Session.House - HOUSE_USSR);
   1679 	housebtn.Set_Read_Only (true);
   1680 #endif
   1681 
   1682 	//........................................................................
   1683 	// Option gauges
   1684 	//........................................................................
   1685 	countgauge.Use_Thumb(0);
   1686 	countgauge.Set_Maximum(SessionClass::CountMax[Session.Options.Bases] - SessionClass::CountMin[Session.Options.Bases]);
   1687 	countgauge.Set_Value(Session.Options.UnitCount - SessionClass::CountMin[Session.Options.Bases]);
   1688 
   1689 	levelgauge.Use_Thumb(0);
   1690 	levelgauge.Set_Maximum(MPLAYER_BUILD_LEVEL_MAX - 1);
   1691 	levelgauge.Set_Value(BuildLevel - 1);
   1692 
   1693 	creditsgauge.Use_Thumb(0);
   1694 	creditsgauge.Set_Maximum(Rule.MPMaxMoney);
   1695 	creditsgauge.Set_Value(Session.Options.Credits);
   1696 
   1697 	aiplayersgauge.Use_Thumb(0);
   1698 	aiplayersgauge.Set_Maximum(Session.Options.AIPlayers);
   1699 	aiplayersgauge.Set_Value(Session.Options.AIPlayers);
   1700 
   1701 	Fancy_Text_Print("", 0, 0, scheme, TBLACK, TPF_TEXT);
   1702 
   1703 	Session.Messages.Init (d_message1_x + 1 *RESFACTOR, d_message1_y + 1 *RESFACTOR, 14,
   1704 		MAX_MESSAGE_LENGTH, d_txt6_h, d_send_x + 1 *RESFACTOR, d_send_y + 1 *RESFACTOR, 1,
   1705 		20, MAX_MESSAGE_LENGTH - 5, d_message2_w);
   1706 	Session.Messages.Add_Edit ((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? PCOLOR_REALLY_BLUE : Session.ColorIdx,
   1707 										TPF_TEXT, NULL, '_', d_message2_w);
   1708 	Session.WWChat = 0;
   1709 
   1710 	lastclick_timer = 0;
   1711 
   1712 	//------------------------------------------------------------------------
   1713 	//	Clear the list of games, players, and the chat list
   1714 	//------------------------------------------------------------------------
   1715 	Clear_Vector(&Session.Games);
   1716 	Clear_Vector(&Session.Players);
   1717 	Clear_Vector(&Session.Chat);
   1718 
   1719 	//------------------------------------------------------------------------
   1720 	// Add myself to the Chat vector
   1721 	//------------------------------------------------------------------------
   1722 	who = new NodeNameType;
   1723 	strcpy(who->Name, namebuf);
   1724 	who->Chat.LastTime = 0;
   1725 	who->Chat.LastChance = 0;
   1726 	who->Chat.Color = Session.GPacket.Chat.Color;
   1727 	Session.Chat.Add (who);
   1728 
   1729 	//------------------------------------------------------------------------
   1730 	// Create the "Lobby" game name on the games list, and create a bogus
   1731 	// node for the gamelist, so Games[i] will always match gamelist[i]
   1732 	//------------------------------------------------------------------------
   1733 	who = new NodeNameType;
   1734 	strcpy(who->Name, "");
   1735 	who->Game.IsOpen = 0;
   1736 	who->Game.LastTime = 0;
   1737 	Session.Games.Add (who);
   1738 	item = new char [MPLAYER_NAME_MAX];
   1739 	strcpy(item, Text_String(TXT_LOBBY));
   1740 	gamelist.Add_Item(item);
   1741 	gamelist.Set_Selected_Index(0);
   1742 	game_index = 0;
   1743 
   1744 	//------------------------------------------------------------------------
   1745 	//	Send game-name query & chat announcement; also, initialize timers.
   1746 	//------------------------------------------------------------------------
   1747 	Send_Join_Queries (game_index, joinstate, 1, 0, 1, namebuf, 1);
   1748 	Load_Title_Page(true);
   1749 	CCPalette.Set();	//GamePalette.Set();
   1750 
   1751 	//------------------------------------------------------------------------
   1752 	//	Init Mono Output
   1753 	//------------------------------------------------------------------------
   1754 	#if(SHOW_MONO)
   1755  	Ipx.Configure_Debug(-1, sizeof (GlobalHeaderType), sizeof(NetCommandType), GlobalPacketNames, 0, 13);
   1756 	Ipx.Mono_Debug_Print(-1,1);
   1757 	#endif
   1758 #ifdef WIN32
   1759 //char *fred;
   1760 #endif
   1761 	//------------------------------------------------------------------------
   1762 	//	Processing loop
   1763 	//------------------------------------------------------------------------
   1764 	while (process) {
   1765 		#if(SHOW_MONO)
   1766 		Ipx.Mono_Debug_Print(-1,0);
   1767 		#endif
   1768 
   1769 		/*
   1770 		** Kludge to make sure we redraw the message input line when it loses focus.
   1771 		** If we dont do this then the cursor doesnt disappear.
   1772 		*/
   1773 		if (messages_have_focus) {
   1774 			if (name_edt.Has_Focus()) {
   1775 				if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE;
   1776 				messages_have_focus = false;
   1777 			}
   1778 		} else {
   1779 			if (!name_edt.Has_Focus()) {
   1780 				messages_have_focus = true;
   1781 			}
   1782 		}
   1783 
   1784 		/*
   1785 		** Collapse the country list if we are going to redraw the game list
   1786 		*/
   1787 		if (gamelist.Is_To_Redraw() && housebtn.IsDropped) {
   1788 			housebtn.Collapse();
   1789 			if (display < REDRAW_BACKGROUND) display = REDRAW_BACKGROUND;
   1790 		}
   1791 
   1792 		#ifdef WIN32
   1793 		/*
   1794 		** If we have just received input focus again after running in the background then
   1795 		** we need to redraw.
   1796 		*/
   1797 		if (AllSurfaces.SurfacesRestored) {
   1798 			AllSurfaces.SurfacesRestored=FALSE;
   1799 			display = REDRAW_ALL;
   1800 		}
   1801 		#endif
   1802 		//.....................................................................
   1803 		//	Refresh display if needed
   1804 		//.....................................................................
   1805 		if (display) {
   1806 			Hide_Mouse();
   1807 
   1808 			//..................................................................
   1809 			//	Redraw backgound & dialog box
   1810 			//..................................................................
   1811 			if (display >= REDRAW_BACKGROUND) {
   1812 				housebtn.Collapse();
   1813 				Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
   1814 
   1815 				//...............................................................
   1816 				//	Dialog & Field labels
   1817 				//...............................................................
   1818 				Fancy_Text_Print(TXT_CHANNEL_GAMES, d_gamelist_x + (d_gamelist_w / 2), d_gamelist_y - d_txt6_h, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   1819 				Fancy_Text_Print(TXT_PLAYERS, d_playerlist_x + (d_playerlist_w / 2), d_playerlist_y - d_txt6_h, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   1820 
   1821 				//...............................................................
   1822 				// For game-browsing, label the name, side, & color buttons:
   1823 				//...............................................................
   1824 				if (joinstate < JOIN_CONFIRMED) {
   1825 					Fancy_Text_Print(TXT_YOUR_NAME, d_name_x + (d_name_w / 2), d_name_y - d_txt6_h, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   1826 
   1827 #ifdef OLDWAY
   1828 					Fancy_Text_Print(TXT_SIDE_COLON,
   1829 						d_gdi_x + d_gdi_w,
   1830 						d_gdi_y - d_txt6_h,
   1831 						scheme, TBLACK,
   1832 						TPF_CENTER | TPF_TEXT);
   1833 #else
   1834 					Fancy_Text_Print(TXT_SIDE_COLON,
   1835 						d_house_x + (d_house_w / 2),
   1836 						d_house_y - d_txt6_h,
   1837 						scheme, TBLACK,
   1838 						TPF_CENTER | TPF_TEXT);
   1839 #endif
   1840 
   1841 					Fancy_Text_Print(TXT_COLOR_COLON,
   1842 						d_dialog_x + ((d_dialog_w / 4) * 3),
   1843 						d_color_y - d_txt6_h,
   1844 						scheme, TBLACK,
   1845 						TPF_CENTER | TPF_TEXT);
   1846 				} else {
   1847 					//...............................................................
   1848 					// If we're joined to a game, just print the player's name & side.
   1849 					//...............................................................
   1850 #ifdef OLDWAY
   1851 					if (Session.House==HOUSE_GOOD) {
   1852 						sprintf(txt,Text_String(TXT_S_PLAYING_S),namebuf, Text_String(TXT_ALLIES));
   1853 					} else {
   1854 						sprintf(txt,Text_String(TXT_S_PLAYING_S),namebuf, Text_String(TXT_SOVIET));
   1855 					}
   1856 #else	//OLDWAY
   1857 					sprintf (txt, Text_String(TXT_S_PLAYING_S), namebuf, Text_String(HouseTypeClass::As_Reference(Session.House).Full_Name()));
   1858 #endif	//OLDWAY
   1859 					Fancy_Text_Print(txt,d_dialog_cx, d_dialog_y + d_margin2 + (1*RESFACTOR),
   1860 						(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[Session.ColorIdx],
   1861 						TBLACK, TPF_CENTER | TPF_TEXT);
   1862 				}
   1863 
   1864 				//...............................................................
   1865 				//	Rebuild the button list
   1866 				//...............................................................
   1867 				cancelbtn.Zap();
   1868 				gamelist.Zap();
   1869 				playerlist.Zap();
   1870 #ifdef OLDWAY
   1871 				gdibtn.Zap();
   1872 				nodbtn.Zap();
   1873 #else
   1874 				housebtn.Zap();
   1875 #endif
   1876 				name_edt.Zap();
   1877 				joinbtn.Zap();
   1878 				newbtn.Zap();
   1879 				countgauge.Zap();
   1880 				levelgauge.Zap();
   1881 				creditsgauge.Zap();
   1882 				aiplayersgauge.Zap();
   1883 				staticcount.Zap();
   1884 				staticlevel.Zap();
   1885 				staticcredits.Zap();
   1886 				staticaiplayers.Zap();
   1887 
   1888 				commands = &cancelbtn;
   1889 				gamelist.Add_Tail(*commands);
   1890 				playerlist.Add_Tail(*commands);
   1891 
   1892 				//...............................................................
   1893 				//	Only add the name edit field, the House, Join & New buttons if
   1894 				//	we're doing nothing, or we've just been rejected.
   1895 				//...............................................................
   1896 				if (joinstate < JOIN_CONFIRMED) {
   1897 #ifdef OLDWAY
   1898 					gdibtn.Add_Tail(*commands);
   1899 					nodbtn.Add_Tail(*commands);
   1900 #else
   1901 					housebtn.Add_Tail(*commands);
   1902 #endif
   1903 					name_edt.Add_Tail(*commands);
   1904 					joinbtn.Add_Tail(*commands);
   1905 					newbtn.Add_Tail(*commands);
   1906 				} else {
   1907 					countgauge.Add_Tail(*commands);
   1908 					levelgauge.Add_Tail(*commands);
   1909 					creditsgauge.Add_Tail(*commands);
   1910 					aiplayersgauge.Add_Tail(*commands);
   1911 					staticcount.Add_Tail(*commands);
   1912 					staticlevel.Add_Tail(*commands);
   1913 					staticcredits.Add_Tail(*commands);
   1914 					staticaiplayers.Add_Tail(*commands);
   1915 					optionlist.Add_Tail(*commands);
   1916 					descrip.Add_Tail(*commands);
   1917 				}
   1918 			}
   1919 
   1920 			//..................................................................
   1921 			//	Redraw buttons
   1922 			//..................................................................
   1923 			if (display >= REDRAW_BUTTONS) {
   1924 				aiplayersgauge.Set_Maximum(Rule.MaxPlayers-Session.Players.Count());
   1925 				if (Session.Options.AIPlayers > Rule.MaxPlayers-Session.Players.Count()) {
   1926 					aiplayersgauge.Set_Value(Rule.MaxPlayers-Session.Players.Count());
   1927 				}
   1928 				commands->Draw_All();
   1929 			}
   1930 
   1931 			//..................................................................
   1932 			//	Draw the color boxes
   1933 			//..................................................................
   1934 			if (display >= REDRAW_COLORS && joinstate < JOIN_CONFIRMED) {
   1935 				for (i = 0; i < MAX_MPLAYER_COLORS; i++) {
   1936 					LogicPage->Fill_Rect (cbox_x[i] + 1, d_color_y + 1,
   1937 						cbox_x[i] + 1 + d_color_w - 2 *RESFACTOR, d_color_y + 1 + d_color_h - 2,
   1938 						ColorRemaps[i].Box);
   1939 //						(i == PCOLOR_DIALOG_BLUE) ? ColorRemaps[PCOLOR_REALLY_BLUE].Box : ColorRemaps[i].Box);
   1940 
   1941 					if (i == Session.ColorIdx) {
   1942 						Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, BOXSTYLE_DOWN, false);
   1943 					} else {
   1944 						Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, BOXSTYLE_RAISED, false);
   1945 					}
   1946 				}
   1947 			}
   1948 
   1949 			//..................................................................
   1950 			// Draw the message system; erase old messages first
   1951 			//..................................................................
   1952 			if (display >= REDRAW_MESSAGE) {
   1953 				if (joinstate==JOIN_CONFIRMED) {
   1954 					Draw_Box(d_message2_x, d_message2_y, d_message2_w, d_message2_h, BOXSTYLE_BOX, true);
   1955 				} else {
   1956 					Draw_Box(d_message1_x, d_message1_y, d_message1_w, d_message1_h, BOXSTYLE_BOX, true);
   1957 				}
   1958 				Draw_Box(d_send_x, d_send_y, d_send_w, d_send_h, BOXSTYLE_BOX, true);
   1959 				Session.Messages.Draw();
   1960 			}
   1961 
   1962 			//..................................................................
   1963 			// Redraw the game options
   1964 			//..................................................................
   1965 			if (display >= REDRAW_PARMS && parms_received && joinstate >= JOIN_CONFIRMED) {
   1966 
   1967 				//...............................................................
   1968 				// Scenario title
   1969 				//...............................................................
   1970 //				LogicPage->Fill_Rect(d_dialog_x + 16 *RESFACTOR, d_name_y, d_dialog_x + d_dialog_w - 16 *RESFACTOR, d_name_y + d_txt6_h, BLACK);
   1971 
   1972 				p = Text_String(TXT_SCENARIO_COLON);
   1973 				if (Session.Options.ScenarioDescription[0]) {
   1974 
   1975 					// EW - Scenario language translation goes here!!!!!!!! VG
   1976 					int ii;
   1977 					for (ii = 0; EngMisStr[ii] != NULL;  ii++) {
   1978 						if (!strcmp(Session.Options.ScenarioDescription, EngMisStr[ii])) {
   1979 							#if defined(GERMAN) || defined(FRENCH)
   1980 								sprintf(txt, "%s %s", p, EngMisStr[ii+1]);
   1981 							#else
   1982 								sprintf(txt, "%s %s", p, Session.Options.ScenarioDescription);
   1983 							#endif
   1984 							break;
   1985 						}
   1986 					}
   1987 					if (EngMisStr[ii] == NULL) {
   1988 						sprintf(txt, "%s %s", p, Session.Options.ScenarioDescription);
   1989 					}
   1990 					descrip.Set_Text(txt);
   1991 
   1992 //					sprintf(txt, "%s %s", p, Session.Options.ScenarioDescription);
   1993 //					descrip.Set_Text(txt);
   1994 //					Fancy_Text_Print("%s %s", d_dialog_cx, d_name_y, scheme, BLACK, TPF_TEXT | TPF_CENTER, p, Session.Options.ScenarioDescription);
   1995 				} else {
   1996 					sprintf(txt, "%s %s", p, Text_String(TXT_NOT_FOUND));
   1997 					descrip.Set_Text(txt);
   1998 //					Fancy_Text_Print("%s %s", d_dialog_cx, d_name_y, &ColorRemaps[PCOLOR_RED], TBLACK, TPF_TEXT | TPF_CENTER, p, Text_String(TXT_NOT_FOUND));
   1999 				}
   2000 				//...............................................................
   2001 				// Unit count, tech level, credits, ai players
   2002 				//...............................................................
   2003 //				LogicPage->Fill_Rect(d_count_x + d_count_w + 2 *RESFACTOR, d_count_y, d_count_x + d_count_w + 35 *RESFACTOR, d_aiplayers_y + d_aiplayers_h+RESFACTOR, BLACK);
   2004 
   2005 				Fancy_Text_Print(TXT_COUNT, d_count_x - 2 *RESFACTOR, d_count_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   2006 
   2007 				sprintf(txt,"%d",Session.Options.UnitCount);
   2008 				staticcount.Set_Text(txt);
   2009 				staticcount.Draw_Me();
   2010 //				Fancy_Text_Print(txt, d_count_x + d_count_w + 2 *RESFACTOR, d_count_y, scheme, BLACK, TPF_TEXT);
   2011 
   2012 				Fancy_Text_Print(TXT_LEVEL, d_level_x - 2 *RESFACTOR, d_level_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   2013 				if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) {
   2014 					sprintf(txt,"%d",BuildLevel);
   2015 				} else {
   2016 					sprintf(txt, "**");
   2017 				}
   2018 				staticlevel.Set_Text(txt);
   2019 				staticlevel.Draw_Me();
   2020 //				Fancy_Text_Print(txt, d_level_x + d_level_w + 2 *RESFACTOR, d_level_y, scheme, BLACK, TPF_TEXT);
   2021 
   2022 				Fancy_Text_Print(TXT_CREDITS_COLON, d_credits_x - 2 *RESFACTOR, d_credits_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   2023 				sprintf(txt,"%d",Session.Options.Credits);
   2024 				staticcredits.Set_Text(txt);
   2025 				staticcredits.Draw_Me();
   2026 //				Fancy_Text_Print(txt, d_credits_x + d_credits_w + 2 *RESFACTOR, d_credits_y, scheme, BLACK, TPF_TEXT);
   2027 
   2028 				Fancy_Text_Print(TXT_AI_PLAYERS_COLON, d_aiplayers_x - 2 * RESFACTOR, d_aiplayers_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   2029 				sprintf(txt,"%d",Session.Options.AIPlayers);
   2030 				staticaiplayers.Set_Text(txt);
   2031 				staticaiplayers.Draw_Me();
   2032 //				Fancy_Text_Print(txt, d_aiplayers_x + d_aiplayers_w + 2 *RESFACTOR, d_aiplayers_y, scheme, BLACK, TPF_TEXT);
   2033 			}
   2034 
   2035 			Show_Mouse();
   2036 			display = REDRAW_NONE;
   2037 		}
   2038 
   2039 		//.....................................................................
   2040 		//	Get user input
   2041 		//.....................................................................
   2042 		input = commands->Input();
   2043 
   2044 		if (input & KN_BUTTON) {
   2045 			housebtn.Collapse();
   2046 			display = REDRAW_BACKGROUND;
   2047 		}
   2048 
   2049 		//.....................................................................
   2050 		//	Process input
   2051 		//.....................................................................
   2052 		switch (input) {
   2053 
   2054 			//..................................................................
   2055 			// Mouse Click:
   2056 			// If we're joined to a game, display an error if the user tries to
   2057 			// modify a read-only control.
   2058 			// If user clicks on a color button:
   2059 			//	- If we've joined a game, don't allow a new color selection
   2060 			//	- otherwise, select that color
   2061 			// - Change the color of the user's name & message field to match
   2062 			//   the newly-selected color.
   2063 			//..................................................................
   2064 			case KN_LMOUSE:
   2065 				if (joinstate > JOIN_NOTHING) {
   2066 					if ( (Get_Mouse_X() >= d_count_x &&
   2067 						Get_Mouse_X() <= d_count_x + d_count_w &&
   2068 						Get_Mouse_Y() >= d_count_y &&
   2069 						Get_Mouse_Y() <= d_aiplayers_y + d_aiplayers_h) ||
   2070 						(Get_Mouse_X() >= d_options_x &&
   2071 						Get_Mouse_X() <= d_options_x + d_options_w &&
   2072 						Get_Mouse_Y() >= d_options_y &&
   2073 						Get_Mouse_Y() <= d_options_y + d_options_h) ) {
   2074 						Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_ONLY_HOST_CAN_MODIFY), PCOLOR_BROWN, TPF_TEXT, 1200);
   2075 						Sound_Effect(VOC_SYS_ERROR);
   2076 						display = REDRAW_MESSAGE;
   2077 					}
   2078 					break;
   2079 				}
   2080 
   2081 				if (Keyboard->MouseQX > cbox_x[0] &&
   2082 					Keyboard->MouseQX < (cbox_x[MAX_MPLAYER_COLORS - 1] + d_color_w) &&
   2083 					Keyboard->MouseQY > d_color_y &&
   2084 					Keyboard->MouseQY < (d_color_y + d_color_h)) {
   2085 						Session.PrefColor = (PlayerColorType)
   2086 							((Keyboard->MouseQX - cbox_x[0]) / d_color_w);
   2087 						Session.ColorIdx = Session.PrefColor;
   2088 
   2089 						if (Session.ColorIdx == PCOLOR_DIALOG_BLUE) {
   2090 							name_edt.Set_Color (&ColorRemaps[PCOLOR_REALLY_BLUE]);
   2091 						} else {
   2092 							name_edt.Set_Color (&ColorRemaps[(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   2093 																		PCOLOR_REALLY_BLUE : Session.ColorIdx]);
   2094 						}
   2095 						name_edt.Flag_To_Redraw();
   2096 
   2097 						Session.Messages.Set_Edit_Color((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   2098 																		PCOLOR_REALLY_BLUE : Session.ColorIdx);
   2099 
   2100 						display = REDRAW_COLORS;
   2101 				}
   2102 				break;
   2103 
   2104 			//..................................................................
   2105 			//	User clicks on the game list:
   2106 			//..................................................................
   2107 			case (BUTTON_GAMELIST | KN_BUTTON):
   2108 				//...............................................................
   2109 				// Handle a double-click
   2110 				//...............................................................
   2111 				if (lastclick_timer < 30 && gamelist.Current_Index() == lastclick_idx) {
   2112 
   2113 					//............................................................
   2114 					// If we're in a game, & the item clicked on is a different
   2115 					// game, un-join the game we're in.
   2116 					//............................................................
   2117 					if ((joinstate==JOIN_CONFIRMED || joinstate==JOIN_WAIT_CONFIRM) &&
   2118 						lastclick_idx != game_index) {
   2119 						if (gamelist.Current_Index() == 0) {
   2120 							goto_lobby = 1;
   2121 						} else {
   2122 							goto_lobby = 0;
   2123 						}
   2124 						Unjoin_Game(namebuf, joinstate, &gamelist, &playerlist,
   2125 							game_index, goto_lobby, d_message1_x, d_message1_y, d_txt6_h,
   2126 							d_send_x, d_send_y, MAX_MESSAGE_LENGTH);
   2127 						joinstate = JOIN_NOTHING;
   2128 						display = REDRAW_ALL;
   2129 
   2130 						//.........................................................
   2131 						// Clear the Player vector & the player list box, since
   2132 						// our game_index has changed.
   2133 						//.........................................................
   2134 						Clear_Listbox (&playerlist);
   2135 						Clear_Vector (&Session.Players);
   2136 						game_index = gamelist.Current_Index();
   2137 					}
   2138 					//............................................................
   2139 					// If we clicked on another game, join that game.
   2140 					//............................................................
   2141 					if (joinstate != JOIN_CONFIRMED &&
   2142 						joinstate != JOIN_WAIT_CONFIRM && lastclick_idx > 0) {
   2143 						gamelist.Set_Selected_Index(lastclick_idx);
   2144 						game_index = lastclick_idx;
   2145 						name_edt.Clear_Focus();
   2146 						name_edt.Flag_To_Redraw();
   2147 						strcpy (Session.Handle,namebuf);
   2148 #ifndef OLDWAY
   2149 						Session.House = (HousesType)(housebtn.Current_Index()+HOUSE_USSR);
   2150 #endif
   2151 						join_index = gamelist.Current_Index();
   2152 						parms_received = 0;
   2153 						if (Request_To_Join (namebuf, join_index, Session.House,
   2154 							Session.ColorIdx)) {
   2155 							joinstate = JOIN_WAIT_CONFIRM;
   2156 						} else {
   2157 							display = REDRAW_ALL;
   2158 						}
   2159 					}
   2160 					//............................................................
   2161 					// Otherwise, we must have joined the lobby
   2162 					//............................................................
   2163 					if (game_index == 0) {
   2164 						Clear_Listbox (&playerlist);
   2165 						Session.Messages.Init (d_message1_x + 1 *RESFACTOR, d_message1_y + 1 *RESFACTOR, 14,
   2166 							MAX_MESSAGE_LENGTH, d_txt6_h, d_send_x + 1 *RESFACTOR, d_send_y + 1 *RESFACTOR, 1,
   2167 							20, MAX_MESSAGE_LENGTH - 5, d_message2_w);
   2168 						Session.Messages.Add_Edit ((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   2169 																				PCOLOR_REALLY_BLUE : Session.ColorIdx,
   2170 														 TPF_TEXT, NULL, '_', d_message2_w);
   2171 						Session.WWChat = 0;
   2172 						display = REDRAW_ALL;
   2173 					}
   2174 				} else {
   2175 				//...............................................................
   2176 				// Handle a single-click
   2177 				//...............................................................
   2178 					//............................................................
   2179 					// If no double-click occurred, set the last-clicked index
   2180 					// & double-click timer.
   2181 					//............................................................
   2182 					lastclick_timer = 0;
   2183 					lastclick_idx = gamelist.Current_Index();
   2184 
   2185 					//............................................................
   2186 					//	If we've joined a game, don't allow the selected item to
   2187 					// change
   2188 					//............................................................
   2189 					if (joinstate==JOIN_CONFIRMED || joinstate==JOIN_WAIT_CONFIRM) {
   2190 						gamelist.Set_Selected_Index(game_index);
   2191 					}
   2192 
   2193 					//............................................................
   2194 					// If we're not in a game, and the user clicks on a different
   2195 					// entry, clear the player list & send a player query;
   2196 					// init the click timer, to detect a double-click of this item.
   2197 					//............................................................
   2198 					else if (gamelist.Current_Index() != game_index) {
   2199 
   2200 						Clear_Listbox (&playerlist);
   2201 						Clear_Vector (&Session.Players);
   2202 						game_index = gamelist.Current_Index();
   2203 						Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   2204 					}
   2205 				}
   2206 				break;
   2207 
   2208 #ifdef OLDWAY
   2209 			//..................................................................
   2210 			//	House Buttons: set the player's desired House
   2211 			//..................................................................
   2212 			case (BUTTON_GDI | KN_BUTTON):
   2213 				Session.House = HOUSE_GOOD;
   2214 				gdibtn.Turn_On();
   2215 				nodbtn.Turn_Off();
   2216 				break;
   2217 
   2218 			case (BUTTON_NOD | KN_BUTTON):
   2219 				Session.House = HOUSE_BAD;
   2220 				gdibtn.Turn_Off();
   2221 				nodbtn.Turn_On();
   2222 				break;
   2223 #else
   2224 #endif
   2225 
   2226 			//..................................................................
   2227 			//	JOIN: send a join request packet & switch to waiting-for-
   2228 			// confirmation mode.
   2229 			//..................................................................
   2230 			case (BUTTON_JOIN | KN_BUTTON):
   2231 				name_edt.Clear_Focus();
   2232 				name_edt.Flag_To_Redraw();
   2233 				strcpy (Session.Handle,namebuf);
   2234 #ifndef OLDWAY
   2235 				Session.House = (HousesType)(housebtn.Current_Index()+HOUSE_USSR);
   2236 #endif
   2237 				join_index = gamelist.Current_Index();
   2238 				parms_received = 0;
   2239 				if (Request_To_Join (namebuf, join_index, Session.House,
   2240 					Session.ColorIdx)) {
   2241 					joinstate = JOIN_WAIT_CONFIRM;
   2242 				} else {
   2243 					display = REDRAW_MESSAGE;
   2244 				}
   2245 				break;
   2246 
   2247 			//..................................................................
   2248 			// ESC / CANCEL: send a SIGN_OFF
   2249 			// - If we're part of a game, stay in this dialog; otherwise, exit
   2250 			//..................................................................
   2251 			case (KN_ESC):
   2252 			case (BUTTON_CANCEL | KN_BUTTON):
   2253 				if (housebtn.IsDropped) {
   2254 					housebtn.Collapse();
   2255 				}
   2256 				//...............................................................
   2257 				//	If we're joined to a game, make extra sure the other players in
   2258 				//	that game know I'm exiting; send my SIGN_OFF as an ack-required
   2259 				//	packet.  Don't send this to myself (index 0).
   2260 				//...............................................................
   2261 				if (joinstate == JOIN_CONFIRMED) {
   2262 					Unjoin_Game(namebuf, joinstate, &gamelist, &playerlist,
   2263 						game_index, 1, d_message1_x, d_message1_y, d_txt6_h, d_send_x,
   2264 						d_send_y, MAX_MESSAGE_LENGTH);
   2265 					joinstate = JOIN_NOTHING;
   2266 					display = REDRAW_ALL;
   2267 				} else {
   2268 				//...............................................................
   2269 				// If I'm not joined to a game, send a SIGN_OFF to all players
   2270 				// in my Chat vector (but not to myself, index 0)
   2271 				//...............................................................
   2272 					memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   2273 					Session.GPacket.Command = NET_SIGN_OFF;
   2274 					strcpy(Session.GPacket.Name,namebuf);
   2275 					for (i = 1; i < Session.Chat.Count(); i++) {
   2276 						Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType), 1, &(Session.Chat[i]->Address));
   2277 						Ipx.Service();
   2278 					}
   2279 
   2280 					//............................................................
   2281 					//	Now broadcast a SIGN_OFF just to be thorough
   2282 					//............................................................
   2283 					Ipx.Send_Global_Message (&Session.GPacket,
   2284 						sizeof (GlobalPacketType), 0, NULL);
   2285 					if (Session.IsBridge) {
   2286 						Ipx.Send_Global_Message (&Session.GPacket,
   2287 							sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   2288 					}
   2289 
   2290 					while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   2291 
   2292 					//............................................................
   2293 					// exit the dialog
   2294 					//............................................................
   2295 					process = false;
   2296 					rc = -1;
   2297 				}
   2298 				break;
   2299 
   2300 			//..................................................................
   2301 			//	NEW: bail out with return code 1
   2302 			//..................................................................
   2303 			case (BUTTON_NEW | KN_BUTTON):
   2304 				//...............................................................
   2305 				//	Force user to enter a name
   2306 				//...............................................................
   2307 				if (strlen(namebuf)==0) {
   2308 					Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_NAME_ERROR), PCOLOR_BROWN, TPF_TEXT, 1200);
   2309 					Sound_Effect(VOC_SYS_ERROR);
   2310 					display = REDRAW_MESSAGE;
   2311 					break;
   2312 				}
   2313 
   2314 				//...............................................................
   2315 				//	Ensure name is unique
   2316 				//...............................................................
   2317 				found = 0;
   2318 				for (i = 1; i < Session.Games.Count(); i++) {
   2319 					if (!stricmp(Session.Games[i]->Name, namebuf)) {
   2320 						found = 1;
   2321 						Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_GAMENAME_MUSTBE_UNIQUE), PCOLOR_BROWN, TPF_TEXT, 1200);
   2322 						Sound_Effect(VOC_SYS_ERROR);
   2323 						display = REDRAW_MESSAGE;
   2324 						break;
   2325 					}
   2326 				}
   2327 
   2328 				if (found) {
   2329 					break;
   2330 				}
   2331 
   2332 				//...............................................................
   2333 				//	Save player & game name
   2334 				//...............................................................
   2335 				strcpy(Session.Handle,namebuf);
   2336 				strcpy(Session.GameName,namebuf);
   2337 #ifndef OLDWAY
   2338 				Session.House = (HousesType)(housebtn.Current_Index()+HOUSE_USSR);
   2339 #endif
   2340 
   2341 				name_edt.Clear_Focus();
   2342 				name_edt.Flag_To_Redraw();
   2343 
   2344 				rc = 1;
   2345 				process = false;
   2346 				break;
   2347 
   2348 			//..................................................................
   2349 			//	Default: manage the inter-player messages
   2350 			//..................................................................
   2351 			default:
   2352 				if (Session.Messages.Manage()) {
   2353 					display = REDRAW_MESSAGE;
   2354 				}
   2355 
   2356 				//...............................................................
   2357 				//	Service keyboard input for any message being edited.
   2358 				//...............................................................
   2359 				i = Session.Messages.Input(input);
   2360 
   2361 				//...............................................................
   2362 				//	If 'Input' returned 1, it means refresh the message display.
   2363 				// (We have to redraw the edit line, to erase the cursor.)
   2364 				//...............................................................
   2365 				if (i==1) {
   2366 					Hide_Mouse();
   2367 					Draw_Box(d_send_x, d_send_y, d_send_w, d_send_h,
   2368 						BOXSTYLE_BOX, true);
   2369 					Session.Messages.Draw();
   2370 					Show_Mouse();
   2371 				} else if (i==2) {
   2372 				//...............................................................
   2373 				//	If 'Input' returned 2, it means redraw the message display.
   2374 				// Rather than setting 'display', which would redraw all msgs,
   2375 				// we only need to erase & redraw the edit box here.
   2376 				//...............................................................
   2377 					Hide_Mouse();
   2378 					Draw_Box(d_send_x, d_send_y, d_send_w, d_send_h,
   2379 						BOXSTYLE_BOX, true);
   2380 					Session.Messages.Draw();
   2381 					Show_Mouse();
   2382 				} else if (i==3 || i==4) {
   2383 				//...............................................................
   2384 				//	If 'Input' returned 3, it means send the current message.
   2385 				//...............................................................
   2386 					memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   2387 					Session.GPacket.Command = NET_MESSAGE;
   2388 					strcpy (Session.GPacket.Name, namebuf);
   2389 					if (i==3) {
   2390 						strcpy (Session.GPacket.Message.Buf,
   2391 							Session.Messages.Get_Edit_Buf());
   2392 					} else {
   2393 						strcpy (Session.GPacket.Message.Buf,
   2394 							Session.Messages.Get_Overflow_Buf());
   2395 						Session.Messages.Clear_Overflow_Buf();
   2396 					}
   2397 					Session.GPacket.Message.Color = Session.ColorIdx;
   2398 					Session.GPacket.Message.NameCRC =
   2399 						Compute_Name_CRC(Session.GameName);
   2400 
   2401 					//............................................................
   2402 					//	If we're joined in a game, send the message to every player
   2403 					// in our player list.  Skip the local system (index 0).
   2404 					//............................................................
   2405 					if (joinstate == JOIN_CONFIRMED) {
   2406 						for (i = 1; i < Session.Players.Count(); i++) {
   2407 							Ipx.Send_Global_Message (&Session.GPacket,
   2408 								sizeof(GlobalPacketType),
   2409 								1, &(Session.Players[i]->Address));
   2410 							Ipx.Service();
   2411 						}
   2412 					} else {
   2413 					//............................................................
   2414 					// Otherwise, send the message to all players in our chat list.
   2415 					//............................................................
   2416 						for (i = 1; i < Session.Chat.Count(); i++) {
   2417 							Ipx.Send_Global_Message (&Session.GPacket,
   2418 								sizeof(GlobalPacketType),
   2419 								1, &(Session.Chat[i]->Address));
   2420 							Ipx.Service();
   2421 						}
   2422 						if (Obfuscate(Session.GPacket.Message.Buf) == 0x72A47EF6) {
   2423 							Session.WWChat = 1;
   2424 							Clear_Listbox (&playerlist);
   2425 							Start_WWChat(&playerlist);
   2426 						}
   2427 					}
   2428 
   2429 					//............................................................
   2430 					//	Add the message to our own list, since we're not in the
   2431 					// player list on this dialog.
   2432 					//............................................................
   2433 					Session.Messages.Add_Message (Session.GPacket.Name,
   2434 															(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   2435 																PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   2436 															Session.GPacket.Message.Buf,
   2437 															(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? PCOLOR_REALLY_BLUE : Session.ColorIdx,
   2438 															TPF_TEXT, -1);
   2439 					Session.Messages.Add_Edit((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? PCOLOR_REALLY_BLUE : Session.ColorIdx,
   2440 														TPF_TEXT, NULL, '_', d_message2_w);
   2441 					display = REDRAW_MESSAGE;
   2442 				}
   2443 
   2444 #ifdef OBSOLETE
   2445 				//
   2446 				// This is for the old drop-down list of houses, not used any more.
   2447 				//
   2448 				if (housebtn.IsDropped) {
   2449 					isdropped = 1;
   2450 				} else if (isdropped) {
   2451 					display = REDRAW_ALL;
   2452 				}
   2453 #endif
   2454 
   2455 				break;
   2456 		}
   2457 
   2458 		//.....................................................................
   2459 		//	Resend our query packets
   2460 		//.....................................................................
   2461 		Send_Join_Queries(game_index, joinstate, 0, 0, 0, namebuf);
   2462 
   2463 		//.....................................................................
   2464 		//	Process incoming packets
   2465 		//.....................................................................
   2466 		event = Get_Join_Responses(&joinstate, &gamelist, &playerlist,
   2467 			join_index, namebuf, &why);
   2468 
   2469 		//.....................................................................
   2470 		//	If we've changed state, redraw everything; if we're starting the game,
   2471 		//	break out of the loop.  If we've just joined, send out a player query
   2472 		//	so I'll get added to the list instantly.
   2473 		//.....................................................................
   2474 		if (event == EV_STATE_CHANGE) {
   2475 			display = REDRAW_ALL;
   2476 
   2477 			if (joinstate==JOIN_GAME_START || joinstate == JOIN_GAME_START_LOAD) {
   2478 				if (joinstate==JOIN_GAME_START_LOAD) {
   2479 					load_game = 1;
   2480 				}
   2481 
   2482 				/*
   2483 				** Special new kludge for counterstrike.
   2484 				**
   2485 				** Find local scenario will fail to match a counterstrike mission
   2486 				** unless the CS CD is in the drive. So....
   2487 				**
   2488 				** If Counterstrike is installed and this is an official map and
   2489 				** the file name matches a counterstrike map then tell the host
   2490 				** that I have the scenario so he can continue while we make
   2491 				** sure the local user has the Counterstrike CD in the drive.
   2492 				**
   2493 				*/
   2494 				//	This is duplicated for Aftermath scenarios. ajw
   2495 
   2496 				bool ready_packet_was_sent = false;
   2497 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   2498 				if (Session.ScenarioIsOfficial &&
   2499 					( (Expansion_CS_Present() && Is_Mission_Counterstrike(Session.ScenarioFileName)) ||
   2500 					  (Expansion_AM_Present() && Is_Mission_Aftermath(Session.ScenarioFileName)) ) ) {
   2501 #else
   2502 				if ( Expansion_CS_Present() && Session.ScenarioIsOfficial ) {
   2503 #endif
   2504 
   2505 					CCFileClass check_file ( Session.ScenarioFileName );
   2506 					if ( !check_file.Is_Available() ) {
   2507 
   2508 						int current_drive = CCFileClass::Get_CD_Drive();
   2509 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   2510 						int index = Get_CD_Index(current_drive, 1*60);
   2511 						bool needcd = false;
   2512 						if (Is_Mission_Counterstrike(Session.ScenarioFileName)) {
   2513 							if (index != 2 && index != 3) {
   2514 								RequiredCD = 2;
   2515 								needcd = true;
   2516 							}
   2517 						}
   2518 						if (Is_Mission_Aftermath(Session.ScenarioFileName)) {
   2519 							if (index != 3) {
   2520 								RequiredCD = 3;
   2521 								needcd = true;
   2522 							}
   2523 						}
   2524 						if (needcd) {
   2525 #else
   2526 						if ( Get_CD_Index(current_drive, 1*60) != 2 ){
   2527 							RequiredCD = 2;
   2528 #endif
   2529 
   2530 							/*
   2531 							** We should have the scenario but the wrong disk is in.
   2532 							** Tell the host that I am ready to go anyway.
   2533 							*/
   2534 							memset ((void*)&(Session.GPacket), 0, sizeof (Session.GPacket));
   2535 							Session.GPacket.Command = NET_READY_TO_GO;
   2536 							Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   2537 								1, &Session.HostAddress);
   2538 							while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0);
   2539 							ready_packet_was_sent = true;
   2540 
   2541 							if (!Force_CD_Available (RequiredCD)){
   2542 								Emergency_Exit(EXIT_FAILURE);
   2543 							}
   2544 
   2545 							/*
   2546 							** Update the internal list of scenarios to include the counterstrike
   2547 							** list.
   2548 							*/
   2549 							Session.Read_Scenario_Descriptions();
   2550 
   2551 						}
   2552 					}
   2553 				}
   2554 
   2555 
   2556 				/*
   2557 				** If the scenario that the host wants to play doesn't exist locally then we
   2558 				**	need to request that it is sent. If we can identify the scenario locally then
   2559 				**	we need to fix up the file name so we load the right one.
   2560 				*/
   2561 				Ipx.Set_Timing (25, (unsigned long) -1, 1000);
   2562 				if (Find_Local_Scenario (Session.Options.ScenarioDescription,
   2563 												Session.ScenarioFileName,
   2564 												Session.ScenarioFileLength,
   2565 												Session.ScenarioDigest,
   2566 					 							Session.ScenarioIsOfficial)) {
   2567 
   2568 					Session.Options.ScenarioIndex = 1;		//We dont care what it
   2569 																		//is as long as it isnt -1
   2570 
   2571 					/*
   2572 					** We have the scenario. Tell the host that I am ready to go.
   2573 					*/
   2574 					if ( !ready_packet_was_sent ){
   2575 						memset ((void*)&(Session.GPacket), 0, sizeof (Session.GPacket));
   2576 						Session.GPacket.Command = NET_READY_TO_GO;
   2577 						Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   2578 							1, &Session.HostAddress);
   2579 
   2580 						while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0);
   2581 					}
   2582 				} else {
   2583 #ifndef FIXIT_VERSION_3			//	Removed restriction on downloading official maps.
   2584 					/*
   2585 					** Oh dear. Thats a scenario I don't have. Request that the host sends the
   2586 					**	scenario to me provided it's not an official scenario.
   2587 					**
   2588 					** If the file is received OK then we will get a true return value and the
   2589 					** actual file name to load will be in Session.ScenarioFileName
   2590 					*/
   2591 					if (Session.ScenarioIsOfficial) {
   2592 						Session.Options.ScenarioIndex = -1;
   2593 					} else {
   2594 #endif
   2595 						Session.Options.ScenarioIndex = 1;		//We dont care what it
   2596 																			//is as long as it isnt -1
   2597 #ifdef FIXIT_VERSION_3
   2598 						if( bSpecialAftermathScenario( Session.Options.ScenarioDescription ) )
   2599 							break;
   2600 #endif
   2601 
   2602 						if (!Get_Scenario_File_From_Host(Session.ScenarioFileName, 1)) {
   2603 							break;
   2604 						} else {
   2605 							/*
   2606 							** Make sure we dont time-out because of the download
   2607 							*/
   2608 						}
   2609 #ifndef FIXIT_VERSION_3
   2610 					}
   2611 #endif
   2612 				}
   2613 
   2614 				Ipx.Set_Timing (30, (unsigned long) -1, 600);
   2615 				strcpy (Scen.ScenarioName, Session.ScenarioFileName);
   2616 				rc = 0;
   2617 				process = false;
   2618 
   2619 			} else if (joinstate==JOIN_CONFIRMED) {
   2620 
   2621 			//..................................................................
   2622 			//	If we're newly-confirmed, add myself to the Players list, and
   2623 			// immediately send out a player query
   2624 			//..................................................................
   2625 				//...............................................................
   2626 				//	Clear the player list, then add myself to the list.
   2627 				//...............................................................
   2628 
   2629 				Clear_Listbox(&playerlist);
   2630 				Clear_Vector (&Session.Players);
   2631 
   2632 				item = new char [MPLAYER_NAME_MAX + 64];
   2633 #ifdef OLDWAY
   2634 				if (Session.House==HOUSE_GOOD) {
   2635 					sprintf(item,"%s\t%s",namebuf, Text_String(TXT_ALLIES));
   2636 				} else {
   2637 					sprintf(item,"%s\t%s",namebuf, Text_String(TXT_SOVIET));
   2638 				}
   2639 #else	//OLDWAY
   2640 				sprintf (item, "%s\t%s", namebuf, Text_String(HouseTypeClass::As_Reference(Session.House).Full_Name()));
   2641 #endif	//OLDWAY
   2642 				playerlist.Add_Item(item,
   2643 					(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[Session.ColorIdx]);
   2644 
   2645 				who = new NodeNameType;
   2646 				strcpy(who->Name, namebuf);
   2647 				who->Player.House = Session.House;
   2648 				who->Player.Color = Session.ColorIdx;
   2649 				Session.Players.Add (who);
   2650 
   2651 
   2652 				Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   2653 
   2654 				//...............................................................
   2655 				// Re-init the message system to its new smaller size
   2656 				//...............................................................
   2657 				Session.Messages.Init (d_message2_x + 1 *RESFACTOR, d_message2_y + 1 *RESFACTOR, 8,
   2658 					MAX_MESSAGE_LENGTH, d_txt6_h, d_send_x + 1 *RESFACTOR, d_send_y + 1 *RESFACTOR, 1,
   2659 					20, MAX_MESSAGE_LENGTH - 5, d_message2_w);
   2660 				Session.Messages.Add_Edit((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   2661 																PCOLOR_REALLY_BLUE : Session.ColorIdx,
   2662 													TPF_TEXT, NULL, '_', d_message2_w);
   2663 			} else if (joinstate==JOIN_REJECTED) {
   2664 			//..................................................................
   2665 			//	If we've been rejected, clear any messages we may have been
   2666 			// typing, add a message stating why we were rejected, and send a
   2667 			// chat announcement.
   2668 			//..................................................................
   2669 				Session.Messages.Init (d_message1_x + 1 *RESFACTOR, d_message1_y + 1 *RESFACTOR, 14,
   2670 					MAX_MESSAGE_LENGTH, d_txt6_h, d_send_x + 1 *RESFACTOR, d_send_y + 1 *RESFACTOR, 1,
   2671 					20, MAX_MESSAGE_LENGTH - 5, d_message2_w);
   2672 				Session.Messages.Add_Edit((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   2673 														PCOLOR_REALLY_BLUE : Session.ColorIdx,
   2674 													TPF_TEXT, NULL, '_', d_message2_w);
   2675 
   2676 				Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_REQUEST_DENIED), PCOLOR_BROWN, TPF_TEXT, 1200);
   2677 				Sound_Effect(VOC_SYS_ERROR);
   2678 
   2679 				item = NULL;
   2680 				if (why==REJECT_DUPLICATE_NAME) {
   2681 					item = (char *)Text_String(TXT_NAME_MUSTBE_UNIQUE);
   2682 				}
   2683 				else if (why==REJECT_GAME_FULL) {
   2684 					item = (char *)Text_String(TXT_GAME_FULL);
   2685 				}
   2686 				else if (why==REJECT_VERSION_TOO_OLD) {
   2687 					item = (char *)Text_String(TXT_YOURGAME_OUTDATED);
   2688 				}
   2689 				else if (why==REJECT_VERSION_TOO_NEW) {
   2690 					item = (char *)Text_String(TXT_DESTGAME_OUTDATED);
   2691 				}
   2692 				else if (why==REJECT_MISMATCH) {
   2693 					item = (char *)Text_String(TXT_MISMATCH);
   2694 				}
   2695 				else if (why==REJECT_DISBANDED) {
   2696 					item = (char *)Text_String(TXT_GAME_CANCELLED);
   2697 				}
   2698 				if (item) {
   2699 					Session.Messages.Add_Message(NULL, 0, item, PCOLOR_BROWN, TPF_TEXT, 1200);
   2700 				}
   2701 
   2702 				Send_Join_Queries (game_index, joinstate, 0, 0, 1, namebuf);
   2703 				display = REDRAW_ALL;
   2704 
   2705 			}
   2706 		} else if (event == EV_GAME_OPTIONS) {
   2707 		//.....................................................................
   2708 		//	If the game options have changed, print them.
   2709 		//.....................................................................
   2710 			countgauge.Set_Maximum(
   2711 				SessionClass::CountMax[Session.Options.Bases] -
   2712 				SessionClass::CountMin[Session.Options.Bases]);
   2713 			countgauge.Set_Value(Session.Options.UnitCount -
   2714 				SessionClass::CountMin[Session.Options.Bases]);
   2715 			levelgauge.Set_Value(BuildLevel - 1);
   2716 			creditsgauge.Set_Value(Session.Options.Credits);
   2717 			if (Session.Options.AIPlayers > Rule.MaxPlayers-Session.Players.Count()) {
   2718 				aiplayersgauge.Set_Value(Rule.MaxPlayers-Session.Players.Count());
   2719 			} else {
   2720 				aiplayersgauge.Set_Value(Session.Options.AIPlayers);
   2721 			}
   2722 			optionlist.Check_Item(0,Session.Options.Bases);
   2723 			optionlist.Check_Item(1,Session.Options.Tiberium);
   2724 			optionlist.Check_Item(2,Session.Options.Goodies);
   2725 			optionlist.Check_Item(3,Special.IsCaptureTheFlag);
   2726 			optionlist.Check_Item(4,Special.IsShadowGrow);
   2727 			optionlist.Flag_To_Redraw();
   2728 
   2729 			Sound_Effect(VOC_OPTIONS_CHANGED);
   2730 
   2731 			parms_received = 1;
   2732 			display = REDRAW_PARMS;
   2733 		} else if (event == EV_MESSAGE) {
   2734 		//.....................................................................
   2735 		//	Draw an incoming message
   2736 		//.....................................................................
   2737 			display = REDRAW_MESSAGE;
   2738 			Sound_Effect(VOC_INCOMING_MESSAGE);
   2739 		} else if (event == EV_NEW_GAME) {
   2740 		//.....................................................................
   2741 		// If a new game has formed, or an existing game has changed state
   2742 		// (from open to closed or closed to open), redraw the message system.
   2743 		//.....................................................................
   2744 			display = REDRAW_MESSAGE;
   2745 		} else if (event == EV_NEW_PLAYER || event == EV_PLAYER_SIGNOFF) {
   2746 			aiplayersgauge.Set_Maximum(Rule.MaxPlayers-Session.Players.Count());
   2747 			if (Session.Options.AIPlayers > Rule.MaxPlayers-Session.Players.Count()) {
   2748 				aiplayersgauge.Set_Value(Rule.MaxPlayers-Session.Players.Count());
   2749 			}
   2750 		} else if (event == EV_GAME_SIGNOFF) {
   2751 
   2752 		//.....................................................................
   2753 		// EV_GAME_SIGNOFF:
   2754 		//	A game before the one I've selected is gone, so we have a new index
   2755 		// now. 'game_index' must be kept set to the currently-selected list
   2756 		// item, so we send out queries for the currently-selected game.  It's
   2757 		// therefore imperative that we detect any changes to the game list.
   2758 		// If we're joined in a game, we must decrement our game_index to keep
   2759 		// it aligned with the game we're joined to.
   2760 		//.....................................................................
   2761 			if (joinstate==JOIN_CONFIRMED) {
   2762 				game_index--;
   2763 				join_index--;
   2764 				gamelist.Set_Selected_Index(join_index);
   2765 			} else {
   2766 				gamelist.Flag_To_Redraw();
   2767 				Clear_Listbox(&playerlist);
   2768 				Clear_Vector (&Session.Players);
   2769 				game_index = gamelist.Current_Index();
   2770 				Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   2771 			}
   2772 		}
   2773 
   2774 		//.....................................................................
   2775 		//	Service the Ipx connections
   2776 		//.....................................................................
   2777 		Ipx.Service();
   2778 
   2779 		if (process) {
   2780 			//.....................................................................
   2781 			//	Clean out the Game List; if an old entry is found:
   2782 			//	- Remove it
   2783 			//	- Clear the player list
   2784 			//	- Send queries for the new selected game, if there is one
   2785 			//.....................................................................
   2786 			for (i = 1; i < Session.Games.Count(); i++) {
   2787 				if (TickCount - Session.Games[i]->Game.LastTime > 400) {
   2788 
   2789 					delete Session.Games[i];
   2790 					Session.Games.Delete(Session.Games[i]);
   2791 
   2792 					item = (char *)(gamelist.Get_Item (i));
   2793 					gamelist.Remove_Item (item);
   2794 					delete [] item;
   2795 
   2796 					gamelist.Flag_To_Redraw();
   2797 
   2798 					if (i <= game_index) {
   2799 						if (joinstate==JOIN_CONFIRMED) {
   2800 							game_index--;
   2801 							join_index--;
   2802 							gamelist.Set_Selected_Index(join_index);
   2803 						} else {
   2804 							gamelist.Flag_To_Redraw();
   2805 							Clear_Listbox(&playerlist);
   2806 							Clear_Vector (&Session.Players);
   2807 							game_index = gamelist.Current_Index();
   2808 							Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   2809 						}
   2810 					}
   2811 				}
   2812 			}
   2813 
   2814 			//.....................................................................
   2815 			// If I've changed my name or color, make sure those changes go into
   2816 			// the Chat vector.
   2817 			//.....................................................................
   2818 			strcpy(Session.Chat[0]->Name, namebuf);
   2819 			Session.Chat[0]->Chat.Color = Session.ColorIdx;
   2820 			if (Session.Chat[0]->Chat.Color == PCOLOR_DIALOG_BLUE) {
   2821 				 Session.Chat[0]->Chat.Color = PCOLOR_REALLY_BLUE;
   2822 			}
   2823 
   2824 			//.....................................................................
   2825 			// Clean out the chat vector.  If we find a node that we haven't heard
   2826 			// from in 6 seconds, delete that node.
   2827 			// If we haven't heard from a node in 5 seconds, send him a request
   2828 			// for a chat announcement; he then has 1 second to reply.
   2829 			//.....................................................................
   2830 			for (i = 1; i < Session.Chat.Count(); i++) {
   2831 				if (TickCount - Session.Chat[i]->Chat.LastTime > 360) {
   2832 					delete Session.Chat[i];
   2833 					Session.Chat.Delete(Session.Chat[i]);
   2834 				} else if (TickCount - Session.Chat[i]->Chat.LastTime > 300 &&
   2835 					Session.Chat[i]->Chat.LastChance == 0) {
   2836 					memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   2837 					Session.GPacket.Name[0] = 0;
   2838 					Session.GPacket.Command = NET_CHAT_REQUEST;
   2839 					Ipx.Send_Global_Message (&Session.GPacket,
   2840 						sizeof(GlobalPacketType), 0, &(Session.Chat[i]->Address));
   2841 					Ipx.Service();
   2842 					Session.Chat[i]->Chat.LastChance = 1;
   2843 				}
   2844 			}
   2845 
   2846 			//.....................................................................
   2847 			// Manage the Lobby list:
   2848 			// If the user has selected the 1st Game ("Lobby"), the names of all
   2849 			// users in the Chat area show up in the Players list box.
   2850 			// Users can be changing their names and their colors at any time, so
   2851 			// we scan the Chat list each time to see if anything's changed; if
   2852 			// so, we redraw the player list.
   2853 			// (If WWChat is on, the Chat list is ignored, and the playerlist
   2854 			// contains custom names.)
   2855 			//.....................................................................
   2856 			if (game_index == 0) {
   2857 				if (!Session.WWChat) {
   2858 					while (Session.Chat.Count() > playerlist.Count()) {
   2859 						item = new char [MPLAYER_NAME_MAX];
   2860 						item[0] = 0;
   2861 						playerlist.Add_Item(item);
   2862 						playerlist.Flag_To_Redraw();
   2863 					}
   2864 					while (playerlist.Count() > Session.Chat.Count()) {
   2865 						item = (char *)playerlist.Get_Item(0);
   2866 						playerlist.Remove_Item(item);
   2867 						delete [] item;
   2868 						playerlist.Flag_To_Redraw();
   2869 					}
   2870 					for (i = 0; i < Session.Chat.Count(); i++) {
   2871 						if (stricmp(Session.Chat[i]->Name,playerlist.Get_Item(i)) ||
   2872 							&ColorRemaps[ (Session.Chat[i]->Chat.Color == PCOLOR_DIALOG_BLUE) ?
   2873 												PCOLOR_REALLY_BLUE : Session.Chat[i]->Chat.Color] !=
   2874 							playerlist.Colors[i]) {
   2875 
   2876 							playerlist.Colors[i] =
   2877 								&ColorRemaps[Session.Chat[i]->Chat.Color];
   2878 							if (playerlist.Colors[i] == &ColorRemaps[PCOLOR_DIALOG_BLUE]) {
   2879 								playerlist.Colors[i] = &ColorRemaps[PCOLOR_REALLY_BLUE];
   2880 							}
   2881 							strcpy((char *)playerlist.Get_Item(i), Session.Chat[i]->Name);
   2882 							playerlist.Flag_To_Redraw();
   2883 						}
   2884 					}
   2885 				} else {
   2886 					if (stricmp(Session.Chat[0]->Name,playerlist.Get_Item(0)) ||
   2887 						&ColorRemaps[Session.Chat[0]->Chat.Color] !=
   2888 							playerlist.Colors[0]) {
   2889 						playerlist.Colors[0] = &ColorRemaps[Session.Chat[0]->Chat.Color];
   2890 						strcpy((char *)playerlist.Get_Item(0), Session.Chat[0]->Name);
   2891 						playerlist.Flag_To_Redraw();
   2892 					}
   2893 					if (Update_WWChat()) {
   2894 						display = REDRAW_MESSAGE;
   2895 					}
   2896 				}
   2897 			}
   2898 
   2899 		}
   2900 		//.....................................................................
   2901 		//	Service the sounds & score; GameActive must be false at this point,
   2902 		//	so Call_Back() doesn't intercept global messages from me!
   2903 		//.....................................................................
   2904 		Call_Back();
   2905 
   2906 	}	// end of while
   2907 
   2908 
   2909 	//------------------------------------------------------------------------
   2910 	//	Establish connections with all other players.
   2911 	//------------------------------------------------------------------------
   2912 	if (rc == 0) {
   2913 		//.....................................................................
   2914 		//	If the other guys are playing a scenario I don't have (sniff), I can't
   2915 		//	play.  Try to bail gracefully.
   2916 		//.....................................................................
   2917 		if (Session.Options.ScenarioIndex==-1) {
   2918 			WWMessageBox().Process (TXT_UNABLE_PLAY_WAAUGH);
   2919 
   2920 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   2921 
   2922 			Session.GPacket.Command = NET_SIGN_OFF;
   2923 			strcpy (Session.GPacket.Name, namebuf);
   2924 
   2925 			//..................................................................
   2926 			// Don't send myself the message.
   2927 			//..................................................................
   2928 			for (i = 1; i < Session.Players.Count(); i++) {
   2929 				Ipx.Send_Global_Message (&Session.GPacket,
   2930 					sizeof(GlobalPacketType), 1,
   2931 					&(Session.Players[i]->Address));
   2932 				Ipx.Service();
   2933 			}
   2934 
   2935 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   2936 				0, NULL);
   2937 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   2938 				0, NULL);
   2939 
   2940 			if (Session.IsBridge) {
   2941 				Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType),
   2942 					0, &Session.BridgeNet);
   2943 				Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType),
   2944 					0, &Session.BridgeNet);
   2945 			}
   2946 
   2947 			while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   2948 
   2949 			rc = -1;
   2950 
   2951 		} else {
   2952 
   2953 		//---------------------------------------------------------------------
   2954 		// Prepare to load the scenario.
   2955 		//---------------------------------------------------------------------
   2956 			//..................................................................
   2957 			//	Set the number of players in this game, and the scenario number.
   2958 			//..................................................................
   2959 			Session.NumPlayers = Session.Players.Count();
   2960 		}
   2961 
   2962 		//.....................................................................
   2963 		//	Wait a while, polling the IPX service routines, to give our ACK
   2964 		//	a chance to get to the other system.  If he doesn't get our ACK,
   2965 		// he'll be waiting the whole time we load MIX files.
   2966 		//.....................................................................
   2967 		i = max(Ipx.Global_Response_Time() * 2, 60);
   2968 		starttime = TickCount;
   2969 		while (TickCount - starttime < (unsigned)i) {
   2970 			Ipx.Service();
   2971 		}
   2972 	}
   2973 
   2974 	//------------------------------------------------------------------------
   2975 	//	Init network timing values, using previous response times as a measure
   2976 	//	of what our retry delta & timeout should be.
   2977 	//------------------------------------------------------------------------
   2978 //	Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1,
   2979 //		Ipx.Global_Response_Time() * 4);
   2980 	Ipx.Set_Timing (Ipx.Global_Response_Time () + 2, (unsigned long) -1, max (120, Ipx.Global_Response_Time () * 8));
   2981 
   2982 
   2983 	//------------------------------------------------------------------------
   2984 	//	Clear all lists, but NOT the Games & Players vectors.
   2985 	//------------------------------------------------------------------------
   2986 	Clear_Listbox(&gamelist);
   2987 	Clear_Listbox(&playerlist);
   2988 
   2989 	//------------------------------------------------------------------------
   2990 	// Remove the chat edit box
   2991 	//------------------------------------------------------------------------
   2992 	Session.Messages.Remove_Edit();
   2993 
   2994 	//------------------------------------------------------------------------
   2995 	//	Restore screen
   2996 	//------------------------------------------------------------------------
   2997 	Hide_Mouse();
   2998 	Load_Title_Page(true);
   2999 	Show_Mouse();
   3000 
   3001 	//------------------------------------------------------------------------
   3002 	// Load a game if the game owner told us to
   3003 	//------------------------------------------------------------------------
   3004 	if (load_game) {
   3005 		if (!Load_Game (-1)) {
   3006 			WWMessageBox().Process (TXT_ERROR_LOADING_GAME);
   3007 			rc = -1;
   3008 		}
   3009 		Frame++;
   3010 	}
   3011 
   3012 	//------------------------------------------------------------------------
   3013 	// Clear the Players & Games vectors if we're not joined to a game.
   3014 	// Clear the Chat vector regardless.
   3015 	//------------------------------------------------------------------------
   3016 	if (rc != 0) {
   3017 		Clear_Vector(&Session.Games);
   3018 		Clear_Vector(&Session.Players);
   3019 	}
   3020 	Clear_Vector(&Session.Chat);
   3021 
   3022 	return(rc);
   3023 
   3024 }	/* end of Net_Join_Dialog */
   3025 
   3026 
   3027 /***************************************************************************
   3028  * Request_To_Join -- Sends a JOIN request packet to game owner            *
   3029  *                                                                         *
   3030  * Regardless of the return code, the Join Dialog will need to be redrawn	*
   3031  * after calling this routine.															*
   3032  *                                                                         *
   3033  * INPUT:                                                                  *
   3034  *		playername		player's name														*
   3035  *		join_index		index of game we're joining									*
   3036  *		house				requested house													*
   3037  *		color				requested color													*
   3038  *                                                                         *
   3039  * OUTPUT:                                                                 *
   3040  *		1 = Packet sent, 0 = wasn't														*
   3041  *                                                                         *
   3042  * WARNINGS:                                                               *
   3043  *		none.																						*
   3044  *                                                                         *
   3045  * HISTORY:                                                                *
   3046  *=========================================================================*/
   3047 static int Request_To_Join (char *playername, int join_index,
   3048 	HousesType house, PlayerColorType color)
   3049 {
   3050 	//------------------------------------------------------------------------
   3051 	//	Validate join_index
   3052 	//------------------------------------------------------------------------
   3053 	if (join_index < 1) {
   3054 		Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_MUST_SELECT_GAME), PCOLOR_BROWN, TPF_TEXT, 1200);
   3055 		Sound_Effect(VOC_SYS_ERROR);
   3056 		return(false);
   3057 	}
   3058 	if ( (Session.Games.Count()<=1) || join_index > Session.Games.Count()) {
   3059 		Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_NOTHING_TO_JOIN), PCOLOR_BROWN, TPF_TEXT, 1200);
   3060 		Sound_Effect(VOC_SYS_ERROR);
   3061 		return(false);
   3062 	}
   3063 
   3064 	//------------------------------------------------------------------------
   3065 	//	Force user to enter a name
   3066 	//------------------------------------------------------------------------
   3067 	if (strlen(playername)==0) {
   3068 		Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_NAME_ERROR), PCOLOR_BROWN, TPF_TEXT, 1200);
   3069 		Sound_Effect(VOC_SYS_ERROR);
   3070 		return(false);
   3071 	}
   3072 
   3073 	//------------------------------------------------------------------------
   3074 	//	The game must be open
   3075 	//------------------------------------------------------------------------
   3076 	if (!Session.Games[join_index]->Game.IsOpen) {
   3077 		Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_GAME_IS_CLOSED), PCOLOR_BROWN, TPF_TEXT, 1200);
   3078 		Sound_Effect(VOC_SYS_ERROR);
   3079 		return (false);
   3080 	}
   3081 
   3082 	//------------------------------------------------------------------------
   3083 	//	Send packet to game's owner
   3084 	//------------------------------------------------------------------------
   3085 	memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3086 
   3087 	Session.GPacket.Command = NET_QUERY_JOIN;
   3088 	strcpy (Session.GPacket.Name, playername);
   3089 	Session.GPacket.PlayerInfo.House = house;
   3090 	Session.GPacket.PlayerInfo.Color = color;
   3091 #ifdef FIXIT_VERSION_3
   3092 	//	Guest sends host his version.
   3093 	//	Added to the transmitted _min_ version number is a bit indicating presence of Aftermath expansion.
   3094 	if( Is_Aftermath_Installed() )
   3095 	{
   3096 //		debugprint( "Guest tells host 'I have Aftermath'\n" );
   3097 		Session.GPacket.PlayerInfo.MinVersion = VerNum.Min_Version() |  0x80000000;
   3098 	}
   3099 	else
   3100 	{
   3101 //		debugprint( "Guest tells host 'I don't have Aftermath'\n" );
   3102 		Session.GPacket.PlayerInfo.MinVersion = VerNum.Min_Version();
   3103 	}
   3104 #else
   3105 	Session.GPacket.PlayerInfo.MinVersion = VerNum.Min_Version();
   3106 #endif
   3107 	Session.GPacket.PlayerInfo.MaxVersion = VerNum.Max_Version();
   3108 	Session.GPacket.PlayerInfo.CheatCheck = RuleINI.Get_Unique_ID();
   3109 
   3110 	Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType), 1,
   3111 		&(Session.Games[join_index]->Address));
   3112 
   3113 	return(true);
   3114 
   3115 }	/* end of Request_To_Join */
   3116 
   3117 
   3118 /***************************************************************************
   3119  * Unjoin_Game -- Cancels joining a game                                   *
   3120  *                                                                         *
   3121  * INPUT:                                                                  *
   3122  *		namebuf			current player name												*
   3123  *		joinstate		current join state												*
   3124  *		gamelist			ListBox of game names											*
   3125  *		playerlist		ListBox of player names											*
   3126  *		game_index		index in 'gamelist' of game we're leaving					*
   3127  *		goto_lobby		true = we're going to the lobby								*
   3128  *		msg_x				message system x-coord											*
   3129  *		msg_y				message system y-coord											*
   3130  *		msg_h				message system char height										*
   3131  *		send_x			message system send x-coord									*
   3132  *		send_y			message system send y-coord									*
   3133  *		msg_len			message system max msg length									*
   3134  *                                                                         *
   3135  * OUTPUT:                                                                 *
   3136  *                                                                         *
   3137  * WARNINGS:                                                               *
   3138  *                                                                         *
   3139  * HISTORY:                                                                *
   3140  *   12/12/1995 BRR : Created.                                             *
   3141  *=========================================================================*/
   3142 static void Unjoin_Game(char *namebuf,JoinStateType joinstate,
   3143 	ListClass *gamelist, ColorListClass *playerlist, int game_index,
   3144 	int goto_lobby, int msg_x, int msg_y, int msg_h, int send_x, int send_y,
   3145 	int msg_len)
   3146 {
   3147 	int i;
   3148 	char *item;
   3149 
   3150 	//------------------------------------------------------------------------
   3151 	// Fill in a SIGN_OFF packet
   3152 	//------------------------------------------------------------------------
   3153 	memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3154 	Session.GPacket.Command = NET_SIGN_OFF;
   3155 	strcpy(Session.GPacket.Name,namebuf);
   3156 
   3157 	//------------------------------------------------------------------------
   3158 	//	If we're joined to a game, make extra sure the other players in
   3159 	//	that game know I'm exiting; send my SIGN_OFF as an ack-required
   3160 	//	packet.  Don't send this to myself (index 0).
   3161 	//------------------------------------------------------------------------
   3162 	for (i = 1; i < Session.Players.Count(); i++) {
   3163 		Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType), 1,
   3164 			&(Session.Players[i]->Address));
   3165 		Ipx.Service();
   3166 	}
   3167 
   3168 	if (joinstate == JOIN_WAIT_CONFIRM || joinstate == JOIN_CONFIRMED) {
   3169 		Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType), 1,
   3170 			&(Session.Games[game_index]->Address));
   3171 	}
   3172 
   3173 	//------------------------------------------------------------------------
   3174 	// Re-init the message system to its new larger size
   3175 	//------------------------------------------------------------------------
   3176 	Session.Messages.Init (msg_x + 1, msg_y + 1, 14,
   3177 		msg_len, msg_h, send_x + 1, send_y + 1, 1,
   3178 		20, msg_len - 5);
   3179 	Session.Messages.Add_Edit((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   3180 											PCOLOR_REALLY_BLUE : Session.ColorIdx,
   3181 											TPF_TEXT, NULL, '_');
   3182 
   3183 	//------------------------------------------------------------------------
   3184 	// Remove myself from the player list, and reset my game name
   3185 	//------------------------------------------------------------------------
   3186 	if (playerlist->Count()) {
   3187 		item = (char *)(playerlist->Get_Item(0));
   3188 		playerlist->Remove_Item(item);
   3189 		delete [] item;
   3190 		playerlist->Flag_To_Redraw();
   3191 	}
   3192 
   3193 	if (Session.Players.Count() > 0) {
   3194 		delete Session.Players[0];
   3195 		Session.Players.Delete(Session.Players[0]);
   3196 	}
   3197 
   3198 	Session.GameName[0] = 0;
   3199 
   3200 	//------------------------------------------------------------------------
   3201 	// Highlight "Lobby" on the Game list, Announce I'm ready to chat
   3202 	//------------------------------------------------------------------------
   3203 	if (goto_lobby) {
   3204 		gamelist->Set_Selected_Index(0);
   3205 		Send_Join_Queries (game_index, joinstate, 0, 0, 1, namebuf);
   3206 	}
   3207 
   3208 }	// end of Unjoin_Game
   3209 
   3210 
   3211 /***********************************************************************************************
   3212  * Send_Join_Queries -- sends queries for the Join Dialog												  *
   3213  *                                                                         						  *
   3214  * This routine [re]sends the queries related to the Join Dialog:										  *
   3215  * - NET_QUERY_GAME																									  *
   3216  * - NET_QUERY_PLAYER for the game currently selected (if there is one)								  *
   3217  *																															  *
   3218  * The queries are "staggered" in time so they aren't all sent at once; otherwise, we'd		  *
   3219  * be inundated with reply packets & we'd miss some (even though the replies will require		  *
   3220  * ACK's).																												  *
   3221  *                                                                         						  *
   3222  * INPUT:                                                                  						  *
   3223  *		curgame		index of currently-selected game; -1 = none											  *
   3224  *		joinstate	our current joinstate																		  *
   3225  *		gamenow		if 1, will immediately send the game query											  *
   3226  *		playernow	if 1, will immediately send the player query for currently-selected game	  *
   3227  *		chatnow		if 1, will immediately send the chat announcement									  *
   3228  *		myname		user's name																						  *
   3229  *		init			initialize the timers																		  *
   3230  *                                                                         						  *
   3231  * OUTPUT:                                                                 						  *
   3232  *		none.																												  *
   3233  *                                                                         						  *
   3234  * WARNINGS:                                                               						  *
   3235  *		none.																												  *
   3236  *                                                                         						  *
   3237  * HISTORY:                                                                						  *
   3238  *   02/14/1995 BR : Created.                                              						  *
   3239  *   04/15/1995 BRR : Created.                                                                 *
   3240  *=============================================================================================*/
   3241 static void Send_Join_Queries(int curgame, JoinStateType joinstate,
   3242 	int gamenow, int playernow, int chatnow, char *myname, int init)
   3243 {
   3244 	//........................................................................
   3245 	// These values control the timeouts for sending various types of packets;
   3246 	// they're designed such that they'll rarely occur simultaneously.
   3247 	//........................................................................
   3248 	enum {
   3249 		GAME_QUERY_TIME = 120,
   3250 		PLAYER_QUERY_TIME = 35,
   3251 		CHAT_ANNOUNCE_TIME = 83,
   3252 	};
   3253 	static CDTimerClass<SystemTimerClass> game_timer;		// time between NET_QUERY_GAME's
   3254 	static CDTimerClass<SystemTimerClass> player_timer;	// time between NET_QUERY_PLAYERS's
   3255 	static CDTimerClass<SystemTimerClass> chat_timer;		// time between NET_CHAT_ANNOUNCE's
   3256 
   3257 
   3258 	//------------------------------------------------------------------------
   3259 	// Initialize timers
   3260 	//------------------------------------------------------------------------
   3261 	if (init) {
   3262 		game_timer = GAME_QUERY_TIME;
   3263 		player_timer = PLAYER_QUERY_TIME;
   3264 		chat_timer = CHAT_ANNOUNCE_TIME;
   3265 	}
   3266 
   3267 	//------------------------------------------------------------------------
   3268 	//	Send the game-name query if the time has expired, or we're told to do
   3269 	//	it right now
   3270 	//------------------------------------------------------------------------
   3271 	if (!game_timer || gamenow) {
   3272 
   3273 		game_timer = GAME_QUERY_TIME;
   3274 
   3275 		memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3276 
   3277 		Session.GPacket.Command = NET_QUERY_GAME;
   3278 
   3279 		Ipx.Send_Global_Message (&Session.GPacket,
   3280 			sizeof(GlobalPacketType), 0, NULL);
   3281 
   3282 		//.....................................................................
   3283 		//	If the user specified a remote server address, broadcast over that
   3284 		//	network, too.
   3285 		//.....................................................................
   3286 		if (Session.IsBridge) {
   3287 			Ipx.Send_Global_Message (&Session.GPacket,
   3288 				sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   3289 		}
   3290 	}
   3291 
   3292 	//------------------------------------------------------------------------
   3293 	//	Send the player query for the game currently clicked on, if the time has
   3294 	//	expired and there is a currently-selected game, or we're told to do it
   3295 	//	right now
   3296 	//------------------------------------------------------------------------
   3297 	if ( ((curgame > 0) && (curgame < Session.Games.Count()) &&
   3298 		!player_timer) || playernow) {
   3299 
   3300 		player_timer = PLAYER_QUERY_TIME;
   3301 
   3302 		memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3303 
   3304 		Session.GPacket.Command = NET_QUERY_PLAYER;
   3305 		strcpy (Session.GPacket.Name, Session.Games[curgame]->Name);
   3306 
   3307 		Ipx.Send_Global_Message (&Session.GPacket,
   3308 			sizeof(GlobalPacketType), 0, NULL);
   3309 
   3310 		//.....................................................................
   3311 		//	If the user specified a remote server address, broadcast over that
   3312 		//	network, too.
   3313 		//.....................................................................
   3314 		if (Session.IsBridge) {
   3315 			Ipx.Send_Global_Message (&Session.GPacket,
   3316 				sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   3317 		}
   3318 	}
   3319 
   3320 	//------------------------------------------------------------------------
   3321 	// Send the chat announcement
   3322 	//------------------------------------------------------------------------
   3323 	if ((!chat_timer && joinstate!=JOIN_CONFIRMED) || chatnow) {
   3324 
   3325 		chat_timer = CHAT_ANNOUNCE_TIME;
   3326 
   3327 		memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3328 
   3329 		Session.GPacket.Command = NET_CHAT_ANNOUNCE;
   3330 		strcpy (Session.GPacket.Name, myname);
   3331 		Session.GPacket.Chat.ID = Session.UniqueID;
   3332 		Session.GPacket.Chat.Color = Session.ColorIdx;
   3333 
   3334 		Ipx.Send_Global_Message (&Session.GPacket,
   3335 			sizeof(GlobalPacketType), 0, NULL);
   3336 
   3337 		if (Session.IsBridge) {
   3338 			Ipx.Send_Global_Message (&Session.GPacket,
   3339 				sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   3340 		}
   3341 	}
   3342 
   3343 }	/* end of Send_Join_Queries */
   3344 
   3345 
   3346 /***********************************************************************************************
   3347  * Get_Join_Responses -- sends queries for the Join Dialog												  *
   3348  *                                                                         						  *
   3349  * This routine polls the Global Channel to see if there are any incoming packets;				  *
   3350  * if so, it processes them.  This routine can change the state of the Join Dialog, or			  *
   3351  * the contents of the list boxes, based on what the packet is.										  *
   3352  *                                                                         						  *
   3353  * The list boxes are passed in as pointers; they can't be made globals, because they			  *
   3354  * can't be constructed, because they require shape pointers to the arrow buttons, and			  *
   3355  * the mix files won't have been initialized when the global variables' constructors are		  *
   3356  * called.																												  *
   3357  *                                                                         						  *
   3358  * This routine sets the globals 																				  *
   3359  *		Session.House					(from NET_CONFIRM_JOIN)													  *
   3360  *		Session.ColorIdx				(from NET_CONFIRM_JOIN)													  *
   3361  *		Session.Options.Bases		(from NET_GAME_OPTIONS)													  *
   3362  *		Session.Options.Tiberium	(from NET_GAME_OPTIONS)													  *
   3363  *		Session.Options.Goodies		(from NET_GAME_OPTIONS)													  *
   3364  *		Session.Options.Ghosts		(from NET_GAME_OPTIONS)													  *
   3365  *		ScenarioIdx				(from NET_GAME_OPTIONS; -1 = scenario not found)						  *
   3366  *                                                                         						  *
   3367  * INPUT:                                                                  						  *
   3368  *		joinstate		current state of Join Dialog															  *
   3369  *		gamelist			list box containing game names														  *
   3370  *		playerlist		list box containing player names for the currently-selected game			  *
   3371  *		join_index		index of the game we've joined or are asking to join							  *
   3372  *		my_name			name of local system																		  *
   3373  *		why				ptr: filled in with reason for rejection from a game							  *
   3374  *                                                                         						  *
   3375  * OUTPUT:                                                                 						  *
   3376  *		Event that occurred																							  *
   3377  *                                                                         						  *
   3378  * WARNINGS:                                                               						  *
   3379  *		none.																												  *
   3380  *                                                                         						  *
   3381  * HISTORY:                                                                						  *
   3382  *   02/14/1995 BR : Created.                                              						  *
   3383  *   04/15/1995 BRR : Created.                                                                 *
   3384  *=============================================================================================*/
   3385 static JoinEventType Get_Join_Responses(JoinStateType *joinstate, ListClass *gamelist,
   3386 	ColorListClass *playerlist, int join_index, char *my_name, RejectType *why)
   3387 {
   3388 	int rc;
   3389 	char * item;						// general-purpose string
   3390 	NodeNameType *who;				// node to add to Games or Players
   3391 	int i;
   3392 	int found;
   3393 	JoinEventType retcode = EV_NONE;
   3394 	char txt[80];
   3395 
   3396 	//------------------------------------------------------------------------
   3397 	//	If there is no incoming packet, just return
   3398 	//------------------------------------------------------------------------
   3399 	rc = Ipx.Get_Global_Message (&Session.GPacket, &Session.GPacketlen,
   3400 		&Session.GAddress, &Session.GProductID);
   3401 	if (!rc || Session.GProductID != IPXGlobalConnClass::COMMAND_AND_CONQUER0)
   3402 		return(EV_NONE);
   3403 
   3404 	//------------------------------------------------------------------------
   3405 	//	If we're joined in a game, handle the packet in a standard way; otherwise,
   3406 	//	don't answer standard queries.
   3407 	//------------------------------------------------------------------------
   3408 	if ( (*joinstate)==JOIN_CONFIRMED &&
   3409 		Process_Global_Packet(&Session.GPacket,&Session.GAddress)!=0) {
   3410 		return(EV_NONE);
   3411 	}
   3412 
   3413 	//------------------------------------------------------------------------
   3414 	//	NET_ANSWER_GAME:  Another system is answering our GAME query, so add that
   3415 	//	system to our list box if it's new.
   3416 	//------------------------------------------------------------------------
   3417 	if (Session.GPacket.Command==NET_ANSWER_GAME) {
   3418 
   3419 		//.....................................................................
   3420 		//	See if this name is unique
   3421 		//.....................................................................
   3422 		retcode = EV_NONE;
   3423 		found = 0;
   3424 		for (i = 1; i < Session.Games.Count(); i++) {
   3425 			if (!strcmp(Session.Games[i]->Name, Session.GPacket.Name)) {
   3426 				found = 1;
   3427 
   3428 				//...............................................................
   3429 				//	If name was found, update the node's time stamp & IsOpen flag.
   3430 				//...............................................................
   3431 				Session.Games[i]->Game.LastTime = TickCount;
   3432 				if (Session.Games[i]->Game.IsOpen != Session.GPacket.GameInfo.IsOpen) {
   3433 					item = (char *)gamelist->Get_Item(i);
   3434 					if (Session.GPacket.GameInfo.IsOpen) {
   3435 						sprintf(item,Text_String(TXT_THATGUYS_GAME),
   3436 							Session.GPacket.Name);
   3437 					}
   3438 					else {
   3439 						sprintf(item,Text_String(TXT_THATGUYS_GAME_BRACKET),
   3440 							Session.GPacket.Name);
   3441 					}
   3442 					Session.Games[i]->Game.IsOpen = Session.GPacket.GameInfo.IsOpen;
   3443 					gamelist->Flag_To_Redraw();
   3444 
   3445 					//............................................................
   3446 					//	If this game has gone from closed to open, copy the
   3447 					// responder's address into our Game slot, since the guy
   3448 					// responding to this must be game owner.
   3449 					//............................................................
   3450 					if (Session.Games[i]->Game.IsOpen) {
   3451 						Session.Games[i]->Address = Session.GAddress;
   3452 					}
   3453 
   3454 					//............................................................
   3455 					// If we're in chat mode, print a message that the state of
   3456 					// this game has changed.
   3457 					//............................................................
   3458 					if (*joinstate < JOIN_CONFIRMED) {
   3459 						if (Session.Games[i]->Game.IsOpen) {
   3460 							sprintf(txt,Text_String(TXT_S_FORMED_NEW_GAME),
   3461 								Session.Games[Session.Games.Count()-1]->Name);
   3462 							Sound_Effect(VOC_GAME_FORMING);
   3463 						}
   3464 						else {
   3465 							sprintf(txt,Text_String(TXT_GAME_NOW_IN_PROGRESS),
   3466 								Session.Games[Session.Games.Count()-1]->Name);
   3467 							Sound_Effect(VOC_GAME_CLOSED);
   3468 						}
   3469 						Session.Messages.Add_Message(NULL, 0, txt, PCOLOR_BROWN, TPF_TEXT, 1200);
   3470 						retcode = EV_NEW_GAME;
   3471 					}
   3472 				}
   3473 				break;
   3474 			}
   3475 		}
   3476 
   3477 		//.....................................................................
   3478 		//	name not found (or addresses are different); add it to 'Games'
   3479 		//.....................................................................
   3480 		if (found==0) {
   3481 
   3482 			//..................................................................
   3483 			//	Create a new node structure, fill it in, add it to 'Games'
   3484 			//..................................................................
   3485 			who = new NodeNameType;
   3486 			strcpy(who->Name, Session.GPacket.Name);
   3487 			who->Address = Session.GAddress;
   3488 			who->Game.IsOpen = Session.GPacket.GameInfo.IsOpen;
   3489 			who->Game.LastTime = TickCount;
   3490 			Session.Games.Add (who);
   3491 
   3492 			//..................................................................
   3493 			//	Create a string for "xxx's Game", leaving room for brackets around
   3494 			//	the string if it's a closed game
   3495 			//..................................................................
   3496 			item = new char [MPLAYER_NAME_MAX + 64];
   3497 			if (Session.GPacket.GameInfo.IsOpen) {
   3498 				sprintf(item,Text_String(TXT_THATGUYS_GAME),Session.GPacket.Name);
   3499 			}
   3500 			else {
   3501 				sprintf(item,Text_String(TXT_THATGUYS_GAME_BRACKET),
   3502 					Session.GPacket.Name);
   3503 			}
   3504 			gamelist->Add_Item(item);
   3505 
   3506 			//..................................................................
   3507 			// If this player's in the Chat vector, remove him from there
   3508 			//..................................................................
   3509 			for (i = 1; i < Session.Chat.Count(); i++) {
   3510 				if (Session.Chat[i]->Address==Session.GAddress) {
   3511 					delete Session.Chat[i];
   3512 					Session.Chat.Delete(Session.Chat[i]);
   3513 					break;
   3514 				}
   3515 			}
   3516 
   3517 			//..................................................................
   3518 			// If this game is open, display a message stating that it's
   3519 			// now available.
   3520 			//..................................................................
   3521 			if (Session.GPacket.GameInfo.IsOpen && (*joinstate) < JOIN_CONFIRMED) {
   3522 				sprintf(txt,Text_String(TXT_S_FORMED_NEW_GAME),
   3523 					Session.GPacket.Name);
   3524 				Session.Messages.Add_Message(NULL, 0, txt, PCOLOR_BROWN, TPF_TEXT, 1200);
   3525 				Sound_Effect(VOC_GAME_FORMING);
   3526 			}
   3527 
   3528 			retcode = EV_NEW_GAME;
   3529 		}
   3530 	}
   3531 
   3532 	//------------------------------------------------------------------------
   3533 	//	NET_ANSWER_PLAYER: Another system is answering our PLAYER query, so add
   3534 	// it to our player list box & the Player Vector if it's new
   3535 	//------------------------------------------------------------------------
   3536 	else if (Session.GPacket.Command==NET_ANSWER_PLAYER) {
   3537 		//.....................................................................
   3538 		//	See if this name is unique
   3539 		//.....................................................................
   3540 		retcode = EV_NONE;
   3541 		found = 0;
   3542 		for (i = 0; i < Session.Players.Count(); i++) {
   3543 
   3544 			//..................................................................
   3545 			//	If the address is already present, re-copy their name, color &
   3546 			//	house into the existing entry, in case they've changed it without
   3547 			//	our knowledge; set the 'found' flag so we won't create a new entry.
   3548 			//..................................................................
   3549 			if (Session.Players[i]->Address==Session.GAddress) {
   3550 				strcpy(Session.Players[i]->Name, Session.GPacket.Name);
   3551 				Session.Players[i]->Player.House = Session.GPacket.PlayerInfo.House;
   3552 				Session.Players[i]->Player.Color = Session.GPacket.PlayerInfo.Color;
   3553 
   3554 				playerlist->Colors[i] =
   3555 					&ColorRemaps[Session.GPacket.PlayerInfo.Color];
   3556 
   3557 				if (playerlist->Colors[i] == &ColorRemaps[PCOLOR_DIALOG_BLUE]) {
   3558 					playerlist->Colors[i] = &ColorRemaps[PCOLOR_REALLY_BLUE];
   3559 				}
   3560 
   3561 				found = 1;
   3562 				break;
   3563 			}
   3564 		}
   3565 
   3566 		//.....................................................................
   3567 		//	Don't add this player if he's not part of the game that's selected.
   3568 		//.....................................................................
   3569 		i = gamelist->Current_Index();
   3570 		if (Session.Games.Count() && Session.GPacket.PlayerInfo.NameCRC !=
   3571 			Compute_Name_CRC(Session.Games[i]->Name)) {
   3572 			found = 1;
   3573 		}
   3574 
   3575 		//.....................................................................
   3576 		//	Don't add this player if it's myself.  (We must check the name
   3577 		// since the address of myself in 'Players' won't be valid.)
   3578 		//.....................................................................
   3579 		if (!strcmp (my_name,Session.GPacket.Name)) {
   3580 			found = 1;
   3581 		}
   3582 
   3583 		//.....................................................................
   3584 		//	name not found, or address didn't match; add to player list box
   3585 		// & Players Vector
   3586 		//.....................................................................
   3587 		if (found==0) {
   3588 			//..................................................................
   3589 			//	Create & add a node to the Vector
   3590 			//..................................................................
   3591 			who = new NodeNameType;
   3592 			strcpy(who->Name, Session.GPacket.Name);
   3593 			who->Address = Session.GAddress;
   3594 			who->Player.House = Session.GPacket.PlayerInfo.House;
   3595 			who->Player.Color = Session.GPacket.PlayerInfo.Color;
   3596 			Session.Players.Add (who);
   3597 
   3598 			//..................................................................
   3599 			//	Create & add a string to the list box
   3600 			//..................................................................
   3601 			item = new char [MPLAYER_NAME_MAX + 64];
   3602 #ifdef OLDWAY
   3603 			if (Session.GPacket.PlayerInfo.House==HOUSE_GOOD) {
   3604 				sprintf(item,"%s\t%s",Session.GPacket.Name, Text_String(TXT_ALLIES));
   3605 			} else {
   3606 				sprintf(item,"%s\t%s",Session.GPacket.Name, Text_String(TXT_SOVIET));
   3607 			}
   3608 #else	//OLDWAY
   3609 			sprintf (item, "%s\t%s", Session.GPacket.Name, Text_String(HouseTypeClass::As_Reference(Session.GPacket.PlayerInfo.House).Full_Name()));
   3610 #endif	//OLDWAY
   3611 			playerlist->Add_Item(item,
   3612 				(who->Player.Color == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[who->Player.Color]);
   3613 
   3614 			//..................................................................
   3615 			// If this player's in the Chat vector, remove him from there
   3616 			//..................................................................
   3617 			for (i = 1; i < Session.Chat.Count(); i++) {
   3618 				if (Session.Chat[i]->Address==Session.GAddress) {
   3619 					delete Session.Chat[i];
   3620 					Session.Chat.Delete(Session.Chat[i]);
   3621 					break;
   3622 				}
   3623 			}
   3624 
   3625 			//..................................................................
   3626 			// If this player has joined our game, play a special sound.
   3627 			//..................................................................
   3628 			if ((*joinstate)>=JOIN_CONFIRMED) {
   3629 				Sound_Effect(VOC_PLAYER_JOINED);
   3630 			}
   3631 
   3632 			retcode = EV_NEW_PLAYER;
   3633 		}
   3634 	}
   3635 
   3636 	//------------------------------------------------------------------------
   3637 	//	NET_CONFIRM_JOIN: The game owner has confirmed our JOIN query; mark us
   3638 	// as being confirmed, and start answering queries from other systems
   3639 	//------------------------------------------------------------------------
   3640 	else if (Session.GPacket.Command==NET_CONFIRM_JOIN) {
   3641 		if ( (*joinstate) != JOIN_CONFIRMED) {
   3642 			strcpy (Session.GameName, Session.GPacket.Name);
   3643 			Session.House = Session.GPacket.PlayerInfo.House;
   3644 			Session.ColorIdx = Session.GPacket.PlayerInfo.Color;
   3645 
   3646 			(*joinstate) = JOIN_CONFIRMED;
   3647 			retcode = EV_STATE_CHANGE;
   3648 		}
   3649 	}
   3650 
   3651 	//------------------------------------------------------------------------
   3652 	//	NET_REJECT_JOIN: The game owner has turned down our JOIN query; restore
   3653 	//	the dialog state to its first pop-up state.
   3654 	//------------------------------------------------------------------------
   3655 	else if (Session.GPacket.Command==NET_REJECT_JOIN) {
   3656 		//.....................................................................
   3657 		// If we're confirmed in a game, broadcast a sign-off to tell all other
   3658 		// systems that I'm no longer a part of any game; this way, I'll be
   3659 		// properly removed from their dialogs.
   3660 		//.....................................................................
   3661 		if ( (*joinstate) == JOIN_CONFIRMED) {
   3662 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3663 			Session.GPacket.Command = NET_SIGN_OFF;
   3664 			strcpy (Session.GPacket.Name,my_name);
   3665 
   3666 			for (i = 1; i < Session.Players.Count(); i++) {
   3667 				Ipx.Send_Global_Message (&Session.GPacket,
   3668 					sizeof(GlobalPacketType), 1,
   3669 					&(Session.Players[i]->Address));
   3670 				Ipx.Service();
   3671 			}
   3672 
   3673 			Ipx.Send_Global_Message (&Session.GPacket,
   3674 				sizeof (GlobalPacketType), 0, NULL);
   3675 			if (Session.IsBridge) {
   3676 				Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType),
   3677 					0, &Session.BridgeNet);
   3678 			}
   3679 
   3680 			while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   3681 
   3682 			Session.GameName[0] = 0;
   3683 
   3684 			//..................................................................
   3685 			// remove myself from the player list
   3686 			//..................................................................
   3687 			item = (char *)(playerlist->Get_Item(0));
   3688 			playerlist->Remove_Item(item);
   3689 			delete [] item;
   3690 			playerlist->Flag_To_Redraw();
   3691 
   3692 			delete Session.Players[0];
   3693 			Session.Players.Delete(Session.Players[0]);
   3694 
   3695 			(*joinstate) = JOIN_REJECTED;
   3696 			(*why) = REJECT_BY_OWNER;
   3697 			retcode = EV_STATE_CHANGE;
   3698 		}
   3699 		//.....................................................................
   3700 		// If we're waiting for confirmation & got rejected, tell the user why
   3701 		//.....................................................................
   3702 		else if ((*joinstate) == JOIN_WAIT_CONFIRM) {
   3703 			(*why) = (RejectType)Session.GPacket.Reject.Why;
   3704 			(*joinstate) = JOIN_REJECTED;
   3705 			retcode = EV_STATE_CHANGE;
   3706 		}
   3707 	}
   3708 
   3709 	//------------------------------------------------------------------------
   3710 	//	NET_GAME_OPTIONS: The game owner has changed the game options & is
   3711 	// sending us the new values.
   3712 	//------------------------------------------------------------------------
   3713 	else if (Session.GPacket.Command==NET_GAME_OPTIONS) {
   3714 		if ( (*joinstate)==JOIN_CONFIRMED || (*joinstate)==JOIN_WAIT_CONFIRM) {
   3715 			Session.Options.Credits = Session.GPacket.ScenarioInfo.Credits;
   3716 			Session.Options.Bases = Session.GPacket.ScenarioInfo.IsBases;
   3717 			Session.Options.Tiberium = Session.GPacket.ScenarioInfo.IsTiberium;
   3718 			Session.Options.Goodies = Session.GPacket.ScenarioInfo.IsGoodies;
   3719 //			Session.Options.Ghosts = Session.GPacket.ScenarioInfo.IsGhosties;
   3720 			Session.Options.AIPlayers = Session.GPacket.ScenarioInfo.AIPlayers;
   3721 			BuildLevel = Session.GPacket.ScenarioInfo.BuildLevel;
   3722 			Session.Options.UnitCount = Session.GPacket.ScenarioInfo.UnitCount;
   3723 			Seed = Session.GPacket.ScenarioInfo.Seed;
   3724 			Special = Session.GPacket.ScenarioInfo.Special;
   3725 			Options.GameSpeed = Session.GPacket.ScenarioInfo.GameSpeed;
   3726 
   3727 #ifdef FIXIT_VERSION_3
   3728 			//	Guest receives game version number from host.
   3729 			//	Added to the transmitted version number is a bit indicating presence of Aftermath expansion.
   3730 			unsigned long lVersion = Session.GPacket.ScenarioInfo.Version & ~0x80000000;	//	Actual version number.
   3731 			Session.CommProtocol = VerNum.Version_Protocol( lVersion );
   3732 			bAftermathMultiplayer = Session.GPacket.ScenarioInfo.Version & 0x80000000;
   3733 //			if( bAftermathMultiplayer )
   3734 //				debugprint( "Guest hears host say 'This is an Aftermath game'\n" );
   3735 //			else
   3736 //				debugprint( "Guest hears host say 'This is NOT an Aftermath game'\n" );
   3737 #else
   3738 			Session.CommProtocol = VerNum.Version_Protocol(Session.GPacket.ScenarioInfo.Version);
   3739 			PlayingAgainstVersion = Session.GPacket.ScenarioInfo.Version;
   3740 #endif
   3741 
   3742 			if (Session.Options.Tiberium) {
   3743 				Special.IsTGrowth = 1;
   3744 				Rule.IsTGrowth = 1;
   3745 				Special.IsTSpread = 1;
   3746 				Rule.IsTSpread = 1;
   3747 			} else {
   3748 				Special.IsTGrowth = 0;
   3749 				Rule.IsTGrowth = 0;
   3750 				Special.IsTSpread = 0;
   3751 				Rule.IsTSpread = 0;
   3752 			}
   3753 
   3754 			/*...............................................................
   3755 			Copy the information about the scenario that the host wants to
   3756 			play so ee can request this scenario from the host if we don't
   3757 			have it locally.
   3758 			...............................................................*/
   3759 			strcpy (Session.Options.ScenarioDescription, Session.GPacket.ScenarioInfo.Scenario);
   3760 			strcpy (Session.ScenarioFileName, Session.GPacket.ScenarioInfo.ShortFileName);
   3761 #ifdef WOLAPI_INTEGRATION
   3762 			strncpy (Session.ScenarioDigest, (char*)Session.GPacket.ScenarioInfo.FileDigest, sizeof (Session.GPacket.ScenarioInfo.FileDigest));
   3763 #else
   3764 			strcpy (Session.ScenarioDigest, (char*)Session.GPacket.ScenarioInfo.FileDigest);
   3765 #endif
   3766 			Session.ScenarioIsOfficial = Session.GPacket.ScenarioInfo.OfficialScenario;
   3767 			Session.ScenarioFileLength = Session.GPacket.ScenarioInfo.FileLength;
   3768 
   3769 			retcode = EV_GAME_OPTIONS;
   3770 		}
   3771 	}
   3772 
   3773 	//------------------------------------------------------------------------
   3774 	//	NET_SIGN_OFF: Another system is signing off: search for that system in
   3775 	//	both the game list & player list, & remove it if found
   3776 	//------------------------------------------------------------------------
   3777 	else if (Session.GPacket.Command==NET_SIGN_OFF) {
   3778 		//.....................................................................
   3779 		//	Remove this name from the list of games
   3780 		//.....................................................................
   3781 		for (i = 1; i < Session.Games.Count(); i++) {
   3782 			if (!strcmp(Session.Games[i]->Name, Session.GPacket.Name) &&
   3783 				Session.Games[i]->Address==Session.GAddress) {
   3784 
   3785 				//...............................................................
   3786 				//	If the system signing off is the currently-selected list
   3787 				//	item, clear the player list since that game is no longer
   3788 				//	forming.
   3789 				//...............................................................
   3790 				if (i==gamelist->Current_Index()) {
   3791 					Clear_Listbox (playerlist);
   3792 					Clear_Vector (&Session.Players);
   3793 				}
   3794 
   3795 				//...............................................................
   3796 				//	If the system signing off was the owner of our game, mark
   3797 				//	ourselves as rejected
   3798 				//...............................................................
   3799 				if ( (*joinstate) > JOIN_NOTHING && i==join_index) {
   3800 					(*joinstate) = JOIN_REJECTED;
   3801 					retcode = EV_STATE_CHANGE;
   3802 					(*why) = REJECT_DISBANDED;
   3803 				}
   3804 
   3805 				//...............................................................
   3806 				//	Set my return code
   3807 				//...............................................................
   3808 				if (retcode == EV_NONE) {
   3809 					if (i <= gamelist->Current_Index()) {
   3810 						retcode = EV_GAME_SIGNOFF;
   3811 					}
   3812 					else {
   3813 						retcode = EV_PLAYER_SIGNOFF;
   3814 					}
   3815 				}
   3816 
   3817 				//...............................................................
   3818 				//	Remove game name from game list
   3819 				//...............................................................
   3820 				delete Session.Games[i];
   3821 				Session.Games.Delete(Session.Games[i]);
   3822 				item = (char *)(gamelist->Get_Item (i));
   3823 				gamelist->Remove_Item (item);
   3824 				delete [] item;
   3825 				gamelist->Flag_To_Redraw();
   3826 
   3827 			}
   3828 		}
   3829 
   3830 		//.....................................................................
   3831 		//	Remove this name from the list of players
   3832 		//.....................................................................
   3833 		for (i = 0; i < Session.Players.Count(); i++) {
   3834 
   3835 			//..................................................................
   3836 			//	Name found; remove it
   3837 			//..................................................................
   3838 			if (Session.Players[i]->Address==Session.GAddress) {
   3839 				item = (char *)(playerlist->Get_Item(i));
   3840 				playerlist->Remove_Item(item);
   3841 				delete [] item;
   3842 
   3843 				delete Session.Players[i];
   3844 				Session.Players.Delete(Session.Players[i]);
   3845 
   3846 				playerlist->Flag_To_Redraw();
   3847 
   3848 				//...............................................................
   3849 				// If this player has left our game, play a special sound.
   3850 				//...............................................................
   3851 				if ((*joinstate)>=JOIN_CONFIRMED) {
   3852 					Sound_Effect(VOC_PLAYER_LEFT);
   3853 				}
   3854 
   3855 				if (retcode == EV_NONE) {
   3856 					retcode = EV_PLAYER_SIGNOFF;
   3857 				}
   3858 			}
   3859 		}
   3860 
   3861 		//.....................................................................
   3862 		//	Remove this name from the chat list
   3863 		//.....................................................................
   3864 		for (i = 1; i < Session.Chat.Count(); i++) {
   3865 
   3866 			//..................................................................
   3867 			//	Name found; remove it
   3868 			//..................................................................
   3869 			if (Session.Chat[i]->Address==Session.GAddress) {
   3870 
   3871 				delete Session.Chat[i];
   3872 				Session.Chat.Delete(Session.Chat[i]);
   3873 
   3874 				if (retcode == EV_NONE) {
   3875 					retcode = EV_PLAYER_SIGNOFF;
   3876 				}
   3877 			}
   3878 		}
   3879 	}
   3880 
   3881 	//------------------------------------------------------------------------
   3882 	//	NET_GO: The game's owner is signalling us to start playing.
   3883 	//------------------------------------------------------------------------
   3884 	else if (Session.GPacket.Command==NET_GO) {
   3885 		if ( (*joinstate)==JOIN_CONFIRMED) {
   3886 			Session.MaxAhead = Session.GPacket.ResponseTime.OneWay;
   3887 			(*joinstate) = JOIN_GAME_START;
   3888 			retcode = EV_STATE_CHANGE;
   3889 			Session.HostAddress = Session.GAddress;
   3890 		}
   3891 	}
   3892 
   3893 	//------------------------------------------------------------------------
   3894 	//	NET_LOADGAME: The game's owner is signalling us to start playing.
   3895 	//------------------------------------------------------------------------
   3896 	else if (Session.GPacket.Command==NET_LOADGAME) {
   3897 		if ( (*joinstate)==JOIN_CONFIRMED) {
   3898 			Session.MaxAhead = Session.GPacket.ResponseTime.OneWay;
   3899 			(*joinstate) = JOIN_GAME_START_LOAD;
   3900 			retcode = EV_STATE_CHANGE;
   3901 		}
   3902 	}
   3903 
   3904 	//------------------------------------------------------------------------
   3905 	// NET_CHAT_ANNOUNCE: Someone is ready to chat; add them to our list, if
   3906 	// they aren't already on it, and it's not myself.
   3907 	//------------------------------------------------------------------------
   3908 	else if (Session.GPacket.Command==NET_CHAT_ANNOUNCE) {
   3909 		found = 0;
   3910 		//.....................................................................
   3911 		// If this packet is from myself, don't add it to the list
   3912 		//.....................................................................
   3913 		if (Session.GPacket.Chat.ID == Session.UniqueID) {
   3914 			found = 1;
   3915 		}
   3916 		//.....................................................................
   3917 		// Otherwise, see if we already have this address stored in our list
   3918 		// If so, update that node's time values & name (in case the user
   3919 		// changed it), and return.
   3920 		//.....................................................................
   3921 		else {
   3922 			for (i = 0; i < Session.Chat.Count(); i++) {
   3923 				if (Session.Chat[i]->Address==Session.GAddress) {
   3924 					strcpy (Session.Chat[i]->Name, Session.GPacket.Name);
   3925 					Session.Chat[i]->Chat.LastTime = TickCount;
   3926 					Session.Chat[i]->Chat.LastChance = 0;
   3927 					Session.Chat[i]->Chat.Color = Session.GPacket.Chat.Color;
   3928 					found = 1;
   3929 					break;
   3930 				}
   3931 			}
   3932 		}
   3933 		//.....................................................................
   3934 		// Add a new node to the list
   3935 		//.....................................................................
   3936 		if (!found) {
   3937 			who = new NodeNameType;
   3938 			strcpy (who->Name, Session.GPacket.Name);
   3939 			who->Address = Session.GAddress;
   3940 			who->Chat.LastTime = TickCount;
   3941 			who->Chat.LastChance = 0;
   3942 			who->Chat.Color = Session.GPacket.Chat.Color;
   3943 			Session.Chat.Add (who);
   3944 		}
   3945 	}
   3946 
   3947 	//------------------------------------------------------------------------
   3948 	// NET_CHAT_REQUEST: Someone is requesting a CHAT_ANNOUNCE from us; send
   3949 	// one to him directly.
   3950 	//------------------------------------------------------------------------
   3951 	else if (Session.GPacket.Command==NET_CHAT_REQUEST) {
   3952 		if ((*joinstate) != JOIN_WAIT_CONFIRM && (*joinstate) != JOIN_CONFIRMED) {
   3953 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   3954 
   3955 			Session.GPacket.Command = NET_CHAT_ANNOUNCE;
   3956 			strcpy(Session.GPacket.Name, my_name);
   3957 			Session.GPacket.Chat.ID = Session.UniqueID;
   3958 			Session.GPacket.Chat.Color = Session.ColorIdx;
   3959 
   3960 			Ipx.Send_Global_Message (&Session.GPacket,
   3961 				sizeof(GlobalPacketType), 1, &Session.GAddress);
   3962 
   3963 			Ipx.Service();
   3964 		}
   3965 	}
   3966 
   3967 	//------------------------------------------------------------------------
   3968 	// NET_MESSAGE: Someone is sending us a message
   3969 	//------------------------------------------------------------------------
   3970 	else if (Session.GPacket.Command==NET_MESSAGE) {
   3971 		//.....................................................................
   3972 		// If we're in a game, the sender must be in our game.
   3973 		//.....................................................................
   3974 		if ( (*joinstate)==JOIN_CONFIRMED) {
   3975 			if (Session.GPacket.Message.NameCRC ==
   3976 				Compute_Name_CRC(Session.GameName)) {
   3977 				Session.Messages.Add_Message (Session.GPacket.Name,
   3978 					(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   3979 															PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   3980 					Session.GPacket.Message.Buf,
   3981 					(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   3982 															PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   3983 					TPF_TEXT, -1);
   3984 			}
   3985 		}
   3986 		//.....................................................................
   3987 		// Otherwise, we're in the chat room; display any old message.
   3988 		//.....................................................................
   3989 		else {
   3990 			Session.Messages.Add_Message (Session.GPacket.Name,
   3991 				Session.GPacket.Message.Color,
   3992 				Session.GPacket.Message.Buf,
   3993 				(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   3994 														PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   3995 				TPF_TEXT, -1);
   3996 		}
   3997 
   3998 		retcode = EV_MESSAGE;
   3999 	}
   4000 
   4001 	//------------------------------------------------------------------------
   4002 	//	NET_PING: Someone is pinging me to get a response time measure (will only
   4003 	//	happen after I've joined a game).  Do nothing; the IPX Manager will handle
   4004 	//	sending an ACK, and updating the response time measurements.
   4005 	//------------------------------------------------------------------------
   4006 	else if (Session.GPacket.Command==NET_PING) {
   4007 		retcode = EV_NONE;
   4008 	}
   4009 
   4010 	//------------------------------------------------------------------------
   4011 	//	Default case: nothing happened.  (This case will be hit every time I
   4012 	//	receive my own NET_QUERY_GAME or NET_QUERY_PLAYER packets.)
   4013 	//------------------------------------------------------------------------
   4014 	else {
   4015 		retcode = EV_NONE;
   4016 	}
   4017 
   4018 	return(retcode);
   4019 
   4020 }	/* end of Get_Join_Responses */
   4021 
   4022 
   4023 /***********************************************************************************************
   4024  * Net_New_Dialog -- lets user start a new game                                                *
   4025  *                                                                                             *
   4026  * This dialog shows a list of who's requesting to join this game, and lets                    *
   4027  * the game initiator selectively approve each user.                                           *
   4028  *                                                                                             *
   4029  * The 'Players' vector matches one-for-one the contents of the list box.  The local system	  *
   4030  * is always listed first; the IPX Address of the local system will NOT be valid in the		  *
   4031  * Players vector.  The Games & Players vectors should be left filled in even after this		  *
   4032  * routine is exited; their contents are used to form connections to the other players,		  *
   4033  * after the scenario has been loaded.																			  *
   4034  *                                                                                             *
   4035  * INPUT:                                                                                      *
   4036  *      none.                                                                                  *
   4037  *                                                                                             *
   4038  * OUTPUT:                                                                                     *
   4039  *      true = success, false = cancel                                                         *
   4040  *                                                                                             *
   4041  * WARNINGS:                                                                                   *
   4042  *      Session.GameName must contain this player's name.                                       *
   4043  *                                                                                             *
   4044  * HISTORY:                                                                                    *
   4045  *   02/14/1995 BR : Created.                                                                  *
   4046  *=============================================================================================*/
   4047 static int Net_New_Dialog(void)
   4048 {
   4049 	return 0;	//PG
   4050 #if (0)
   4051 	typedef enum {
   4052 		NUM_MESSAGES = 10
   4053 	} NumMessagesType;
   4054 
   4055 	//------------------------------------------------------------------------
   4056 	//	Dialog & button dimensions
   4057 	//------------------------------------------------------------------------
   4058 	int d_dialog_w = 320 *RESFACTOR;											// dialog width
   4059 	int d_dialog_h = 200 *RESFACTOR;											// dialog height
   4060 	int d_dialog_x = ((320 *RESFACTOR- d_dialog_w) / 2);				// dialog x-coord
   4061 	int d_dialog_y = ((200 *RESFACTOR- d_dialog_h) / 2);				// centered y-coord
   4062 	int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);		// center x-coord
   4063 
   4064 	int d_txt6_h = 6*RESFACTOR+1;												// ht of 6-pt text
   4065 	int d_margin1 = 5*RESFACTOR;												// margin width/height
   4066 	int d_margin2 = 2*RESFACTOR;												// margin width/height
   4067 
   4068 //BG	int d_playerlist_w = 118*RESFACTOR;
   4069 	int d_playerlist_w = 124*RESFACTOR;
   4070 	int d_playerlist_h = (6 * d_txt6_h) + 3*RESFACTOR;			// 6 rows high
   4071 	int d_playerlist_x = d_dialog_x + d_margin1 + d_margin1 + 5*RESFACTOR;
   4072 	int d_playerlist_y = d_dialog_y + d_margin1 + d_txt6_h + 3*RESFACTOR;
   4073 
   4074 	int d_scenariolist_w = 162*RESFACTOR;
   4075 	int d_scenariolist_h = (6 * d_txt6_h) + 3*RESFACTOR;		// 6 rows high
   4076 	int d_scenariolist_x = d_dialog_x + d_dialog_w - d_margin1 - d_margin1 - d_scenariolist_w - (5*RESFACTOR);
   4077 	int d_scenariolist_y = d_playerlist_y;
   4078 
   4079 	int d_reject_w = 55*RESFACTOR;
   4080 	int d_reject_h = 9*RESFACTOR;
   4081 	int d_reject_x = d_playerlist_x + (d_playerlist_w / 2) - (d_reject_w / 2);
   4082 	int d_reject_y = d_playerlist_y + d_playerlist_h + d_margin2;
   4083 
   4084 	int d_count_w = 25*RESFACTOR;
   4085 	int d_count_h = d_txt6_h;
   4086 	int d_count_x = d_playerlist_x + (d_playerlist_w / 2) + 20*RESFACTOR;		// (fudged)
   4087 	int d_count_y = d_reject_y + d_reject_h /*KO+ d_margin2*/;
   4088 
   4089 	int d_level_w = 25*RESFACTOR;
   4090 	int d_level_h = d_txt6_h;
   4091 	int d_level_x = d_playerlist_x + (d_playerlist_w / 2) + 20*RESFACTOR;		// (fudged)
   4092 	int d_level_y = d_count_y + d_count_h;
   4093 
   4094 	int d_credits_w = 25*RESFACTOR;
   4095 	int d_credits_h = d_txt6_h;
   4096 	int d_credits_x = d_playerlist_x + (d_playerlist_w / 2) + 20*RESFACTOR;	// (fudged)
   4097 	int d_credits_y = d_level_y + d_level_h;
   4098 
   4099 	int d_aiplayers_w = 25*RESFACTOR;
   4100 	int d_aiplayers_h = d_txt6_h;
   4101 	int d_aiplayers_x = d_playerlist_x + (d_playerlist_w / 2) + 20*RESFACTOR;	// (fudged)
   4102 	int d_aiplayers_y = d_credits_y + d_credits_h;
   4103 
   4104 	int d_options_w = 106*RESFACTOR;
   4105 	int d_options_h = ((5 * 6) + 4)*RESFACTOR;
   4106 	int d_options_x = d_scenariolist_x + ((d_scenariolist_w - d_options_w) / 2);
   4107 	int d_options_y = d_scenariolist_y + d_scenariolist_h + d_margin1;
   4108 
   4109 	int d_message_w = d_dialog_w - (d_margin1 * 2) - 20*RESFACTOR;
   4110 	int d_message_h = (NUM_MESSAGES * d_txt6_h) + 3*RESFACTOR;	// 10 rows high
   4111 	int d_message_x = d_dialog_x + d_margin1 + 10*RESFACTOR;
   4112 	int d_message_y = d_dialog_y + d_dialog_h - (27*RESFACTOR + d_message_h);
   4113 //	int d_message_y = d_options_y + d_options_h + d_margin1;
   4114 
   4115 	int d_send_w = d_dialog_w - (d_margin1 * 2) - 20*RESFACTOR;
   4116 	int d_send_h = 9*RESFACTOR;
   4117 	int d_send_x = d_dialog_x + d_margin1 + 10*RESFACTOR;
   4118 	int d_send_y = d_message_y + d_message_h;
   4119 
   4120 	int d_ok_w = 50*RESFACTOR;
   4121 	int d_ok_h = 9*RESFACTOR;
   4122 	int d_ok_x = d_dialog_x + (d_dialog_w / 6) - (d_ok_w / 2);
   4123 	int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin1 - 3*RESFACTOR;
   4124 
   4125 	int d_cancel_w = 50*RESFACTOR;
   4126 	int d_cancel_h = 9*RESFACTOR;
   4127 	int d_cancel_x = d_dialog_cx - (d_cancel_w / 2);
   4128 	int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin1 - 3*RESFACTOR;
   4129 
   4130 	int d_load_w = 50*RESFACTOR;
   4131 	int d_load_h = 9*RESFACTOR;
   4132 	int d_load_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_load_w / 2);
   4133 	int d_load_y = d_dialog_y + d_dialog_h - d_load_h - d_margin1 - 3*RESFACTOR;
   4134 
   4135 	//------------------------------------------------------------------------
   4136 	//	Button Enumerations
   4137 	//------------------------------------------------------------------------
   4138 	enum {
   4139 		BUTTON_PLAYERLIST = 100,
   4140 		BUTTON_SCENARIOLIST,
   4141 		BUTTON_REJECT,
   4142 		BUTTON_COUNT,
   4143 		BUTTON_LEVEL,
   4144 		BUTTON_CREDITS,
   4145 		BUTTON_AIPLAYERS,
   4146 		BUTTON_OPTIONS,
   4147 		BUTTON_OK,
   4148 		BUTTON_LOAD,
   4149 		BUTTON_CANCEL,
   4150 	};
   4151 
   4152 	//------------------------------------------------------------------------
   4153 	//	Redraw values: in order from "top" to "bottom" layer of the dialog
   4154 	//------------------------------------------------------------------------
   4155 	typedef enum {
   4156 		REDRAW_NONE = 0,
   4157 		REDRAW_PARMS,
   4158 		REDRAW_MESSAGE,
   4159 		REDRAW_BUTTONS,
   4160 		REDRAW_BACKGROUND,
   4161 		REDRAW_ALL = REDRAW_BACKGROUND
   4162 	} RedrawType;
   4163 
   4164 	//------------------------------------------------------------------------
   4165 	//	Dialog variables
   4166 	//------------------------------------------------------------------------
   4167 	RedrawType display = REDRAW_ALL;		// redraw level
   4168 	bool process = true;						// process while true
   4169 	KeyNumType input;
   4170 
   4171 	int transmit;								// 1 = re-transmit new game options
   4172 
   4173 	long ok_timer = 0;						// for timing OK button
   4174 	int index;									// index for rejecting a player
   4175 	int rc;
   4176 	int i,j;
   4177 	char *item;
   4178 	int tabs[] = {77*RESFACTOR};			// tabs for player list box
   4179 	int optiontabs[] = {8*RESFACTOR};	// tabs for option list box
   4180 
   4181 	NodeNameType *who;						// node to add to Players
   4182 	long ping_timer = 0;						// for sending Ping packets
   4183 
   4184 	int color_used[MAX_MPLAYER_COLORS];	// 1 = color has been used
   4185 	char txt[80];
   4186 	JoinEventType whahoppa;					// event generated by received packets
   4187 	static int first_time = 1;				// 1 = 1st time this dialog is run
   4188 	CCFileClass loadfile ("SAVEGAME.NET");
   4189 	int load_game = 0;						// 1 = load a saved game
   4190 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   4191 
   4192 	//------------------------------------------------------------------------
   4193 	// Buttons
   4194 	//------------------------------------------------------------------------
   4195 	GadgetClass *commands;					// button list
   4196 
   4197 	ColorListClass playerlist(BUTTON_PLAYERLIST, d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   4198 	ListClass scenariolist(BUTTON_SCENARIOLIST, d_scenariolist_x, d_scenariolist_y, d_scenariolist_w, d_scenariolist_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   4199 	TextButtonClass rejectbtn(BUTTON_REJECT, TXT_REJECT, TPF_BUTTON, d_reject_x, d_reject_y);
   4200 	GaugeClass countgauge(BUTTON_COUNT, d_count_x, d_count_y, d_count_w, d_count_h);
   4201 	GaugeClass levelgauge(BUTTON_LEVEL, d_level_x, d_level_y, d_level_w, d_level_h);
   4202 	GaugeClass creditsgauge(BUTTON_CREDITS, d_credits_x, d_credits_y, d_credits_w, d_credits_h);
   4203 	GaugeClass aiplayersgauge(BUTTON_AIPLAYERS, d_aiplayers_x, d_aiplayers_y, d_aiplayers_w, d_aiplayers_h);
   4204 	CheckListClass optionlist(BUTTON_OPTIONS, d_options_x, d_options_y, d_options_w, d_options_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   4205 	TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_BUTTON, d_ok_x, d_ok_y, 60*RESFACTOR);
   4206 	TextButtonClass loadbtn(BUTTON_LOAD, TXT_LOAD_BUTTON, TPF_BUTTON, d_load_x, d_load_y, 60*RESFACTOR);
   4207 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON, d_cancel_x, d_cancel_y, 60*RESFACTOR);
   4208 
   4209 	StaticButtonClass staticunit(0, "    ", TPF_TEXT, d_count_x + d_count_w + 2*RESFACTOR, d_count_y);
   4210 	StaticButtonClass staticlevel(0, "    ", TPF_TEXT, d_level_x + d_level_w + 2*RESFACTOR, d_level_y);
   4211 	StaticButtonClass staticcredits(0, "         ", TPF_TEXT, d_credits_x + d_credits_w + 2*RESFACTOR, d_credits_y);
   4212 	StaticButtonClass staticaiplayers(0, "   ", TPF_TEXT, d_aiplayers_x + d_aiplayers_w + 2*RESFACTOR, d_aiplayers_y);
   4213 
   4214 	//------------------------------------------------------------------------
   4215 	//	Build the button list
   4216 	//------------------------------------------------------------------------
   4217 	commands = &playerlist;
   4218 	scenariolist.Add_Tail(*commands);
   4219 	rejectbtn.Add_Tail(*commands);
   4220 	staticunit.Add_Tail(*commands);
   4221 	staticlevel.Add_Tail(*commands);
   4222 	staticcredits.Add_Tail(*commands);
   4223 	staticaiplayers.Add_Tail(*commands);
   4224 	countgauge.Add_Tail(*commands);
   4225 	creditsgauge.Add_Tail(*commands);
   4226 	aiplayersgauge.Add_Tail(*commands);
   4227 	levelgauge.Add_Tail(*commands);
   4228 	optionlist.Add_Tail(*commands);
   4229 	okbtn.Add_Tail(*commands);
   4230 	cancelbtn.Add_Tail(*commands);
   4231 	if (loadfile.Is_Available()) {
   4232 #ifdef FIXIT_MULTI_SAVE
   4233 //		loadbtn.Add_Tail(*commands);
   4234 #endif
   4235 	} else {
   4236 		cancelbtn.X = loadbtn.X;
   4237 	}
   4238 	playerlist.Set_Tabs(tabs);
   4239 
   4240 	//------------------------------------------------------------------------
   4241 	//	Init dialog values, only the first time through
   4242 	//------------------------------------------------------------------------
   4243 	Special.IsCaptureTheFlag = Rule.IsMPCaptureTheFlag;
   4244 	if (first_time) {
   4245 		Session.Options.Credits = Rule.MPDefaultMoney;			// init credits & credit buffer
   4246 		Session.Options.Bases = Rule.IsMPBasesOn;					// init scenario parameters
   4247 		Session.Options.Tiberium = Rule.IsMPTiberiumGrow;
   4248 		Session.Options.Goodies = Rule.IsMPCrates;
   4249 		Session.Options.AIPlayers = 0;
   4250 		Session.Options.UnitCount =
   4251 			(SessionClass::CountMax[Session.Options.Bases] +
   4252 			SessionClass::CountMin[Session.Options.Bases]) / 2;
   4253 		first_time = 0;
   4254 	}
   4255 
   4256 	//------------------------------------------------------------------------
   4257 	//	Init button states
   4258 	//------------------------------------------------------------------------
   4259 	optionlist.Set_Tabs(optiontabs);
   4260 	optionlist.Set_Read_Only(0);
   4261 
   4262 	optionlist.Add_Item(Text_String(TXT_BASES));
   4263 	optionlist.Add_Item(Text_String(TXT_ORE_SPREADS));
   4264 	optionlist.Add_Item(Text_String(TXT_CRATES));
   4265 	optionlist.Add_Item(Text_String(TXT_CAPTURE_THE_FLAG));
   4266 	optionlist.Add_Item(Text_String(TXT_SHADOW_REGROWS));
   4267 
   4268 	optionlist.Check_Item(0, Session.Options.Bases);
   4269 	optionlist.Check_Item(1, Session.Options.Tiberium);
   4270 	optionlist.Check_Item(2, Session.Options.Goodies);
   4271 	optionlist.Check_Item(3, Special.IsCaptureTheFlag);
   4272 	optionlist.Check_Item(4, Special.IsShadowGrow);
   4273 
   4274 	countgauge.Set_Maximum(SessionClass::CountMax[Session.Options.Bases] - SessionClass::CountMin[Session.Options.Bases]);
   4275 	countgauge.Set_Value(Session.Options.UnitCount - SessionClass::CountMin[Session.Options.Bases]);
   4276 
   4277 	levelgauge.Set_Maximum(MPLAYER_BUILD_LEVEL_MAX - 1);
   4278 	levelgauge.Set_Value(BuildLevel - 1);
   4279 
   4280 	creditsgauge.Set_Maximum(Rule.MPMaxMoney);
   4281 	creditsgauge.Set_Value(Session.Options.Credits);
   4282 
   4283 	//------------------------------------------------------------------------
   4284 	//	Init other scenario parameters
   4285 	//------------------------------------------------------------------------
   4286 	Special.IsTGrowth = Session.Options.Tiberium;
   4287 	Rule.IsTGrowth = Session.Options.Tiberium;
   4288 	Special.IsTSpread = Session.Options.Tiberium;
   4289 	Rule.IsTSpread = Session.Options.Tiberium;
   4290 	transmit = 0;
   4291 
   4292 	//------------------------------------------------------------------------
   4293 	//	Init scenario description list box
   4294 	//------------------------------------------------------------------------
   4295 	for (i = 0; i < Session.Scenarios.Count(); i++) {
   4296 		for (j = 0; EngMisStr[j] != NULL;  j++) {
   4297 			if (!strcmp(Session.Scenarios[i]->Description(), EngMisStr[j])) {
   4298 #ifdef FIXIT_CSII	//	ajw Added Aftermath installed checks (before, it was assumed).
   4299 				//	Add mission if it's available to us.
   4300 				if( !( ( Is_Mission_Counterstrike((char *)(Session.Scenarios[i]->Get_Filename())) && !Is_Counterstrike_Installed() ) ||
   4301 						( Is_Mission_Aftermath((char *)(Session.Scenarios[i]->Get_Filename())) && !Is_Aftermath_Installed() ) ) )
   4302 #endif
   4303 #if defined(GERMAN) || defined(FRENCH)
   4304 					scenariolist.Add_Item(EngMisStr[j+1]);
   4305 #else
   4306 					scenariolist.Add_Item(EngMisStr[j]);
   4307 #endif
   4308 
   4309 				break;
   4310 			}
   4311 		}
   4312 		if ( EngMisStr[j] == NULL) {
   4313 #ifdef FIXIT_CSII	//	ajw Added Aftermath installed checks (before, it was assumed). Added officialness check.
   4314 			//	Add mission if it's available to us.
   4315 			if( !Session.Scenarios[i]->Get_Official() ||
   4316 				!( ( Is_Mission_Counterstrike((char *)(Session.Scenarios[i]->Get_Filename())) && !Is_Counterstrike_Installed() ) ||
   4317 					( Is_Mission_Aftermath((char *)(Session.Scenarios[i]->Get_Filename())) && !Is_Aftermath_Installed() ) ) )
   4318 #endif
   4319 			{
   4320 				scenariolist.Add_Item(Session.Scenarios[i]->Description());
   4321 			}
   4322 		}
   4323 	}
   4324 
   4325 	Session.Options.ScenarioIndex = 0;	// 1st scenario is selected
   4326 #ifdef FIXIT_VERSION_3
   4327 	bAftermathMultiplayer = Is_Aftermath_Installed();
   4328 //	debugprint( "Host decides that, initially, bAftermathMultiplayer is %i\n", bAftermathMultiplayer );
   4329 #else
   4330 	PlayingAgainstVersion = VerNum.Version_Number();
   4331 #endif
   4332 
   4333 	//------------------------------------------------------------------------
   4334 	//	Init player color-used flags
   4335 	//------------------------------------------------------------------------
   4336 	for (i = 0; i < MAX_MPLAYER_COLORS; i++) {
   4337 		color_used[i] = 0;							// init all colors to available
   4338 	}
   4339 	color_used[Session.ColorIdx] = 1;			// set my color to used
   4340 	playerlist.Set_Selected_Style(ColorListClass::SELECT_BAR, scheme);
   4341 
   4342 	//------------------------------------------------------------------------
   4343 	//	Init random-number generator, & create a seed to be used for all random
   4344 	//	numbers from here on out
   4345 	//------------------------------------------------------------------------
   4346 	srand(time(NULL));
   4347 	Seed = rand();
   4348 
   4349 	//------------------------------------------------------------------------
   4350 	//	Init the message display system
   4351 	//------------------------------------------------------------------------
   4352 	Session.Messages.Init(d_message_x + 1*RESFACTOR, d_message_y + 1*RESFACTOR, NUM_MESSAGES,
   4353 		MAX_MESSAGE_LENGTH, d_txt6_h, d_send_x + 1*RESFACTOR, d_send_y + 1*RESFACTOR, 1,
   4354 		20, MAX_MESSAGE_LENGTH - 5, d_message_w);
   4355 	Session.Messages.Add_Edit((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   4356 												PCOLOR_REALLY_BLUE : Session.ColorIdx,
   4357 										TPF_TEXT, NULL, '_', d_message_w);
   4358 
   4359 	//------------------------------------------------------------------------
   4360 	//	Init the version-clipping system
   4361 	//------------------------------------------------------------------------
   4362 	VerNum.Init_Clipping();
   4363 
   4364 	//------------------------------------------------------------------------
   4365 	//	Clear the list of players
   4366 	//------------------------------------------------------------------------
   4367 	Clear_Vector(&Session.Players);
   4368 
   4369 	//------------------------------------------------------------------------
   4370 	//	Add myself to the list, and to the Players vector.
   4371 	//------------------------------------------------------------------------
   4372 	item = new char [MPLAYER_NAME_MAX + 64];
   4373 #ifdef OLDWAY
   4374 	if (Session.House==HOUSE_GOOD) {
   4375 		sprintf(item,"%s\t%s",Session.Handle, Text_String(TXT_ALLIES));
   4376 	} else {
   4377 		sprintf(item,"%s\t%s",Session.Handle, Text_String(TXT_SOVIET));
   4378 	}
   4379 #else	//OLDWAY
   4380 		sprintf (item, "%s\t%s", Session.Handle, Text_String(HouseTypeClass::As_Reference(Session.House).Full_Name()));
   4381 #endif	//OLDWAY
   4382 	playerlist.Add_Item(item,
   4383 		(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[Session.ColorIdx]);
   4384 
   4385 	who = new NodeNameType;
   4386 	strcpy(who->Name, Session.Handle);
   4387 	who->Player.House = Session.House;
   4388 	who->Player.Color = Session.ColorIdx;
   4389 	Session.Players.Add (who);
   4390 	Load_Title_Page(true);
   4391 	CCPalette.Set();	//GamePalette.Set();
   4392 
   4393 	//
   4394 	// Now init the max range of the AI players slider.
   4395 	//
   4396 	aiplayersgauge.Set_Maximum(Rule.MaxPlayers-Session.Players.Count());
   4397 	aiplayersgauge.Set_Value(Session.Options.AIPlayers);
   4398 
   4399 	//------------------------------------------------------------------------
   4400 	//	Processing loop
   4401 	//------------------------------------------------------------------------
   4402 	while (process) {
   4403 		#if(SHOW_MONO)
   4404 		Ipx.Mono_Debug_Print(-1,0);
   4405 		#endif
   4406 
   4407 		#ifdef WIN32
   4408 		/*
   4409 		** If we have just received input focus again after running in the background then
   4410 		** we need to redraw.
   4411 		*/
   4412 		if (AllSurfaces.SurfacesRestored) {
   4413 			AllSurfaces.SurfacesRestored=FALSE;
   4414 			display = REDRAW_ALL;
   4415 		}
   4416 		#endif
   4417 		//.....................................................................
   4418 		//	Refresh display if needed
   4419 		//.....................................................................
   4420 		if (display) {
   4421 			Hide_Mouse();
   4422 
   4423 			//..................................................................
   4424 			//	Redraw backgound & dialog box
   4425 			//..................................................................
   4426 			if (display >= REDRAW_BACKGROUND) {
   4427 				Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
   4428 
   4429 				//...............................................................
   4430 				//	Dialog & Field labels
   4431 				//...............................................................
   4432 				Fancy_Text_Print(TXT_PLAYERS, d_playerlist_x + (d_playerlist_w / 2), d_playerlist_y - d_txt6_h, scheme, TBLACK, TPF_TEXT | TPF_CENTER);
   4433 				Fancy_Text_Print(TXT_SCENARIOS, d_scenariolist_x + (d_scenariolist_w / 2), d_scenariolist_y - d_txt6_h, scheme, TBLACK, TPF_TEXT | TPF_CENTER);
   4434 				Fancy_Text_Print(TXT_COUNT, d_count_x - 2*RESFACTOR, d_count_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   4435 				Fancy_Text_Print(TXT_LEVEL, d_level_x - 2*RESFACTOR, d_level_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   4436 				Fancy_Text_Print(TXT_CREDITS_COLON, d_credits_x - 2*RESFACTOR, d_credits_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   4437 				Fancy_Text_Print(TXT_AI_PLAYERS_COLON, d_aiplayers_x - 2*RESFACTOR, d_aiplayers_y, scheme, TBLACK, TPF_TEXT | TPF_RIGHT);
   4438 			}
   4439 
   4440 			//..................................................................
   4441 			//	Redraw buttons
   4442 			//..................................................................
   4443 			if (display >= REDRAW_BUTTONS) {
   4444 
   4445 				/*
   4446 				** Zap, Zap, Zap
   4447 				*/
   4448 				playerlist.Zap();
   4449 				scenariolist.Zap();
   4450 				rejectbtn.Zap();
   4451 				staticunit.Zap();
   4452 				staticlevel.Zap();
   4453 				staticcredits.Zap();
   4454 				staticaiplayers.Zap();
   4455 				countgauge.Zap();
   4456 				creditsgauge.Zap();
   4457 				aiplayersgauge.Zap();
   4458 				levelgauge.Zap();
   4459 				optionlist.Zap();
   4460 				okbtn.Zap();
   4461 				cancelbtn.Zap();
   4462 				loadbtn.Zap();
   4463 
   4464 
   4465 				/*
   4466 				** Hack hack, hack
   4467 				*/
   4468 				commands = &playerlist;
   4469 				scenariolist.Add_Tail(*commands);
   4470 				rejectbtn.Add_Tail(*commands);
   4471 				staticunit.Add_Tail(*commands);
   4472 				staticlevel.Add_Tail(*commands);
   4473 				staticcredits.Add_Tail(*commands);
   4474 				staticaiplayers.Add_Tail(*commands);
   4475 				countgauge.Add_Tail(*commands);
   4476 				creditsgauge.Add_Tail(*commands);
   4477 				aiplayersgauge.Add_Tail(*commands);
   4478 				levelgauge.Add_Tail(*commands);
   4479 				optionlist.Add_Tail(*commands);
   4480 				okbtn.Add_Tail(*commands);
   4481 				cancelbtn.Add_Tail(*commands);
   4482 #ifdef FIXIT_VERSION_3
   4483 				if( loadfile.Is_Available() ) {
   4484 #else
   4485 				if (loadfile.Is_Available() && PlayingAgainstVersion > VERSION_RED_ALERT_104 ) {
   4486 #endif
   4487 #ifdef FIXIT_MULTI_SAVE
   4488 					loadbtn.Add_Tail(*commands);
   4489 #endif
   4490 				}
   4491 				commands->Draw_All();
   4492 			}
   4493 
   4494 			//..................................................................
   4495 			//	Draw the messages:
   4496 			//	- Erase an old message first
   4497 			//	- If we're in a game, print the game options (if they've been
   4498 			//	  received)
   4499 			//	- If we've been rejected from a game, print that message
   4500 			//..................................................................
   4501 			if (display >= REDRAW_MESSAGE) {
   4502 				Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, BOXSTYLE_BOX, true);
   4503 				Draw_Box(d_send_x, d_send_y, d_send_w, d_send_h, BOXSTYLE_BOX, true);
   4504 				Session.Messages.Draw();
   4505 			}
   4506 
   4507 			//..................................................................
   4508 			// Update game parameter labels
   4509 			//..................................................................
   4510 			if (display >= REDRAW_PARMS) {
   4511 //				LogicPage->Fill_Rect(d_count_x + d_count_w + 2*RESFACTOR, d_count_y, d_count_x + d_count_w + 35*RESFACTOR, d_aiplayers_y + d_aiplayers_h+RESFACTOR, BLACK);
   4512 
   4513 				sprintf(txt,"%d",Session.Options.UnitCount);
   4514 				staticunit.Set_Text(txt);
   4515 				staticunit.Draw_Me();
   4516 //				Fancy_Text_Print(txt, d_count_x + d_count_w + 2*RESFACTOR, d_count_y, scheme, BLACK, TPF_TEXT);
   4517 
   4518 				if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) {
   4519 					sprintf(txt,"%d",BuildLevel);
   4520 				} else {
   4521 					sprintf(txt, "**");
   4522 				}
   4523 				staticlevel.Set_Text(txt);
   4524 				staticlevel.Draw_Me();
   4525 //				Fancy_Text_Print(txt, d_level_x + d_level_w + 2*RESFACTOR, d_level_y, scheme, BLACK, TPF_TEXT);
   4526 
   4527 				sprintf(txt,"%d",Session.Options.Credits);
   4528 				staticcredits.Set_Text(txt);
   4529 				staticcredits.Draw_Me();
   4530 //				Fancy_Text_Print(txt, d_credits_x + d_credits_w + 2*RESFACTOR, d_credits_y, scheme, BLACK, TPF_TEXT);
   4531 
   4532 				sprintf(txt,"%d",Session.Options.AIPlayers);
   4533 				staticaiplayers.Set_Text(txt);
   4534 				staticaiplayers.Draw_Me();
   4535 //				Fancy_Text_Print(txt, d_aiplayers_x + d_aiplayers_w + 2*RESFACTOR, d_aiplayers_y, scheme, BLACK, TPF_TEXT);
   4536 			}
   4537 
   4538 			Show_Mouse();
   4539 			display = REDRAW_NONE;
   4540 		}
   4541 
   4542 		//.....................................................................
   4543 		//	Get user input
   4544 		//.....................................................................
   4545 		input = commands->Input();
   4546 
   4547 		//.....................................................................
   4548 		//	Process input
   4549 		//.....................................................................
   4550 		switch (input) {
   4551 
   4552 			//..................................................................
   4553 			//	New Scenario selected.
   4554 			//..................................................................
   4555 #ifdef FIXIT_VERSION_3		//	All scenarios now allowable as downloads. ajw
   4556 			case (BUTTON_SCENARIOLIST | KN_BUTTON):
   4557 				if (scenariolist.Current_Index() != Session.Options.ScenarioIndex)
   4558 				{
   4559 					Session.Options.ScenarioIndex = scenariolist.Current_Index();
   4560 					transmit = 1;
   4561 				}
   4562 				break;
   4563 
   4564 #else	//	FIXIT_VERSION_3
   4565 			case (BUTTON_SCENARIOLIST | KN_BUTTON):
   4566 				if (scenariolist.Current_Index() != Session.Options.ScenarioIndex) {
   4567 #ifdef FIXIT_CSII	//	checked - ajw
   4568 					if ((PlayingAgainstVersion != VERSION_RED_ALERT_107 && PlayingAgainstVersion != VERSION_RED_ALERT_108 && PlayingAgainstVersion < VERSION_AFTERMATH_CS) &&
   4569 #else
   4570 					if (PlayingAgainstVersion < VERSION_RED_ALERT_107 &&
   4571 #endif
   4572 								Session.Scenarios[scenariolist.Current_Index()]->Get_Expansion()){
   4573 						scenariolist.Set_Selected_Index (Session.Options.ScenarioIndex);
   4574 						Session.Messages.Add_Message(NULL, 0,
   4575 							(char *)Text_String(TXT_NO_CS_SCENARIOS), PCOLOR_BROWN, TPF_TEXT, 1200);
   4576 						Sound_Effect(VOC_SYS_ERROR);
   4577 						if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE;
   4578 #ifdef FIXIT_CSII	//	checked - ajw
   4579 					}else
   4580 					if (PlayingAgainstVersion < VERSION_AFTERMATH_CS &&
   4581 							Is_Mission_126x126((char *)Session.Scenarios[scenariolist.Current_Index()]->Get_Filename() ) ){
   4582 						scenariolist.Set_Selected_Index (Session.Options.ScenarioIndex);
   4583 						Session.Messages.Add_Message(NULL, 0,
   4584 							(char *)Text_String(TXT_NO_CS_SCENARIOS), PCOLOR_BROWN, TPF_TEXT, 1200);
   4585 						Sound_Effect(VOC_SYS_ERROR);
   4586 						if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE;
   4587 #endif
   4588 					} else {
   4589 						Session.Options.ScenarioIndex = scenariolist.Current_Index();
   4590 						transmit = 1;
   4591 					}
   4592 				}
   4593 				break;
   4594 #endif	//	FIXIT_VERSION_3
   4595 
   4596 			//..................................................................
   4597 			//	Reject the currently-selected player (don't allow rejecting myself,
   4598 			//	who will be the first entry in the list)
   4599 			//..................................................................
   4600 			case (BUTTON_REJECT | KN_BUTTON):
   4601 				index = playerlist.Current_Index();
   4602 
   4603 				if (index == 0) {
   4604 					Session.Messages.Add_Message(NULL, 0,
   4605 						(char *)Text_String(TXT_CANT_REJECT_SELF), PCOLOR_BROWN, TPF_TEXT, 1200);
   4606 					Sound_Effect(VOC_SYS_ERROR);
   4607 					display = REDRAW_MESSAGE;
   4608 					break;
   4609 
   4610 				} else if (index < 0 || index >= playerlist.Count()) {
   4611 					Session.Messages.Add_Message(NULL, 0,
   4612 						(char *)Text_String(TXT_SELECT_PLAYER_REJECT),
   4613 						PCOLOR_BROWN, TPF_TEXT, 1200);
   4614 					Sound_Effect(VOC_SYS_ERROR);
   4615 					display = REDRAW_MESSAGE;
   4616 					break;
   4617 				}
   4618 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   4619 
   4620 				Session.GPacket.Command = NET_REJECT_JOIN;
   4621 
   4622 				Ipx.Send_Global_Message (&Session.GPacket,
   4623 					sizeof (GlobalPacketType), 1,
   4624 					&(Session.Players[index]->Address));
   4625 				break;
   4626 
   4627 			//..................................................................
   4628 			//	User adjusts max # units
   4629 			//..................................................................
   4630 			case (BUTTON_COUNT | KN_BUTTON):
   4631 				Session.Options.UnitCount = countgauge.Get_Value() +
   4632 					SessionClass::CountMin[Session.Options.Bases];
   4633 				transmit = 1;
   4634 				display = REDRAW_PARMS;
   4635 				break;
   4636 
   4637 			//..................................................................
   4638 			//	User adjusts build level
   4639 			//..................................................................
   4640 			case (BUTTON_LEVEL | KN_BUTTON):
   4641 				BuildLevel = levelgauge.Get_Value() + 1;
   4642 				if (BuildLevel > MPLAYER_BUILD_LEVEL_MAX)	// if it's pegged, max it out
   4643 					BuildLevel = MPLAYER_BUILD_LEVEL_MAX;
   4644 				transmit = 1;
   4645 				display = REDRAW_PARMS;
   4646 				break;
   4647 
   4648 			//..................................................................
   4649 			//	User edits the credits value; retransmit new game options
   4650 			// Round the credits to the nearest 500.
   4651 			//..................................................................
   4652 			case (BUTTON_CREDITS | KN_BUTTON):
   4653 				Session.Options.Credits = creditsgauge.Get_Value();
   4654 				Session.Options.Credits =
   4655 					((Session.Options.Credits + 250) / 500) * 500;
   4656 				transmit = 1;
   4657 				display = REDRAW_PARMS;
   4658 				break;
   4659 
   4660 			//..................................................................
   4661 			//	User adjusts # of AI players
   4662 			//..................................................................
   4663 			case (BUTTON_AIPLAYERS | KN_BUTTON):
   4664 				Session.Options.AIPlayers = aiplayersgauge.Get_Value();
   4665 				if (Session.Options.AIPlayers+Session.Players.Count() > Rule.MaxPlayers) {	// if it's pegged, max it out
   4666 					Session.Options.AIPlayers = Rule.MaxPlayers - Session.Players.Count();
   4667 					aiplayersgauge.Set_Value(Session.Options.AIPlayers);
   4668 				}
   4669 				transmit = 1;
   4670 				display = REDRAW_PARMS;
   4671 				break;
   4672 
   4673 			//..................................................................
   4674 			// Toggle-able options:
   4675 			// If 'Bases' gets toggled, we have to change the range of the
   4676 			// UnitCount slider.
   4677 			// Also, if Tiberium gets toggled, we have to set the flags
   4678 			// in SpecialClass.
   4679 			//..................................................................
   4680 			case (BUTTON_OPTIONS | KN_BUTTON):
   4681 				if (Special.IsCaptureTheFlag != optionlist.Is_Checked(3) && !Special.IsCaptureTheFlag) {
   4682 					optionlist.Check_Item(0, true);
   4683 				}
   4684 				if (Session.Options.Bases != (optionlist.Is_Checked(0) ? 1 : 0)) {
   4685 					Session.Options.Bases = (optionlist.Is_Checked(0) ? 1 : 0);
   4686 					if (Session.Options.Bases) {
   4687 						Session.Options.UnitCount = Fixed_To_Cardinal (
   4688 							SessionClass::CountMax[1] -
   4689 							SessionClass::CountMin[1],
   4690 							Cardinal_To_Fixed(
   4691 								SessionClass::CountMax[0]-SessionClass::CountMin[0],
   4692 								Session.Options.UnitCount-SessionClass::CountMin[0])) +
   4693 							SessionClass::CountMin[1];
   4694 					} else {
   4695 						optionlist.Check_Item(3, false);
   4696 						Session.Options.UnitCount = Fixed_To_Cardinal (
   4697 							SessionClass::CountMax[0] -
   4698 							SessionClass::CountMin[0],
   4699 							Cardinal_To_Fixed(
   4700 								SessionClass::CountMax[1]-SessionClass::CountMin[1],
   4701 								Session.Options.UnitCount - SessionClass::CountMin[1])) +
   4702 							SessionClass::CountMin[0];
   4703 					}
   4704 					countgauge.Set_Maximum(
   4705 						SessionClass::CountMax[Session.Options.Bases] -
   4706 						SessionClass::CountMin[Session.Options.Bases]);
   4707 					countgauge.Set_Value(Session.Options.UnitCount -
   4708 						SessionClass::CountMin[Session.Options.Bases]);
   4709 				}
   4710 				Session.Options.Tiberium = optionlist.Is_Checked(1);
   4711 				Special.IsTGrowth = Session.Options.Tiberium;
   4712 				Rule.IsTGrowth = Session.Options.Tiberium;
   4713 				Special.IsTSpread = Session.Options.Tiberium;
   4714 				Rule.IsTSpread = Session.Options.Tiberium;
   4715 
   4716 				Session.Options.Goodies = optionlist.Is_Checked(2);
   4717 				Special.IsCaptureTheFlag = optionlist.Is_Checked(3);
   4718 				Special.IsShadowGrow = optionlist.Is_Checked(4);
   4719 
   4720 				transmit = 1;
   4721 				display = REDRAW_PARMS;
   4722 				break;
   4723 
   4724 			//..................................................................
   4725 			//	OK: exit loop with TRUE status
   4726 			//..................................................................
   4727 			case (BUTTON_LOAD | KN_BUTTON):
   4728 			case (BUTTON_OK | KN_BUTTON):
   4729 				//...............................................................
   4730 				//	If a new player has joined in the last second, don't allow
   4731 				//	an OK; force a wait longer than 1 second (to give all players
   4732 				//	a chance to know about this new guy)
   4733 				//...............................................................
   4734 				i = max(Ipx.Global_Response_Time() * 2, 60);
   4735 				while ((int)TickCount - ok_timer < i) {
   4736 					Ipx.Service();
   4737 				}
   4738 
   4739 				//...............................................................
   4740 				//	If there are at least 2 players, go ahead & play; error otherwise
   4741 				//...............................................................
   4742 				if (Session.Players.Count() > 1 ) {
   4743 //				if (Session.Players.Count() + Session.Options.AIPlayers > 1 ) {
   4744 					rc = TRUE;
   4745 					process = FALSE;
   4746 				} else {
   4747 					Session.Messages.Add_Message(NULL, 0, (char *)Text_String(TXT_ONLY_ONE), PCOLOR_BROWN, TPF_TEXT, 1200);
   4748 					Sound_Effect(VOC_SYS_ERROR);
   4749 					display = REDRAW_MESSAGE;
   4750 				}
   4751 				if (input==(BUTTON_LOAD | KN_BUTTON)) {
   4752 					load_game = 1;
   4753 				} else {
   4754 					load_game = 0;
   4755 				}
   4756 				break;
   4757 
   4758 			//..................................................................
   4759 			//	CANCEL: send a SIGN_OFF, bail out with error code
   4760 			//..................................................................
   4761 			case (KN_ESC):
   4762 			case (BUTTON_CANCEL | KN_BUTTON):
   4763 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   4764 
   4765 				Session.GPacket.Command = NET_SIGN_OFF;
   4766 				strcpy (Session.GPacket.Name, Session.Handle);
   4767 
   4768 				//...............................................................
   4769 				//	Broadcast my sign-off over my network
   4770 				//...............................................................
   4771 				Ipx.Send_Global_Message (&Session.GPacket,
   4772 					sizeof (GlobalPacketType), 0, NULL);
   4773 				Ipx.Send_Global_Message (&Session.GPacket,
   4774 					sizeof (GlobalPacketType), 0, NULL);
   4775 				while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   4776 
   4777 				//...............................................................
   4778 				//	Broadcast my sign-off over a bridged network if there is one
   4779 				//...............................................................
   4780 				if (Session.IsBridge) {
   4781 					Ipx.Send_Global_Message (&Session.GPacket,
   4782 						sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   4783 					Ipx.Send_Global_Message (&Session.GPacket,
   4784 						sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   4785 				}
   4786 				while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   4787 
   4788 				//...............................................................
   4789 				//	And now, just be absolutely sure, send my sign-off to each
   4790 				//	player in my game.  (If there's a bridge between us, the other
   4791 				//	player will have specified my address, so he can cross the
   4792 				//	bridge; but I may not have specified a bridge address, so the
   4793 				//	only way I have of crossing the bridge is to send a packet
   4794 				//	directly to him.)
   4795 				// Don't send this message to myself.
   4796 				//...............................................................
   4797 				for (i = 1; i < Session.Players.Count(); i++) {
   4798 					Ipx.Send_Global_Message (&Session.GPacket,
   4799 						sizeof(GlobalPacketType), 1, &(Session.Players[i]->Address));
   4800 					Ipx.Service();
   4801 				}
   4802 				while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   4803 				Session.GameName[0] = 0;
   4804 				process = false;
   4805 				rc = false;
   4806 				break;
   4807 
   4808 			//..................................................................
   4809 			//	Default: manage the inter-player messages
   4810 			//..................................................................
   4811 			default:
   4812 				if (Session.Messages.Manage()) {
   4813 					display = REDRAW_MESSAGE;
   4814 				}
   4815 
   4816 				//...............................................................
   4817 				//	Re-draw the messages & service keyboard input for any message
   4818 				//	being edited.
   4819 				//...............................................................
   4820 				i = Session.Messages.Input(input);
   4821 
   4822 				//...............................................................
   4823 				//	If 'Input' returned 1, it means refresh the message display.
   4824 				//...............................................................
   4825 				if (i==1) {
   4826 					Hide_Mouse();
   4827 					Draw_Box(d_send_x, d_send_y, d_send_w, d_send_h,
   4828 						BOXSTYLE_BOX, true);	// (erase the cursor)
   4829 					Session.Messages.Draw();
   4830 					Show_Mouse();
   4831 				} else if (i==2) {
   4832 				//...............................................................
   4833 				//	If 'Input' returned 2, it means redraw the message display.
   4834 				//...............................................................
   4835 					Hide_Mouse();
   4836 					Draw_Box(d_send_x, d_send_y, d_send_w, d_send_h,
   4837 						BOXSTYLE_BOX, true);	// (erase the cursor)
   4838 					Session.Messages.Draw();
   4839 					Show_Mouse();
   4840 				} else if (i==3 || i==4) {
   4841 				//...............................................................
   4842 				//	If 'input' returned 3, it means send the current message.
   4843 				//...............................................................
   4844 					memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   4845 					Session.GPacket.Command = NET_MESSAGE;
   4846 					strcpy (Session.GPacket.Name, Session.Handle);
   4847 					if (i==3) {
   4848 						strcpy (Session.GPacket.Message.Buf,
   4849 							Session.Messages.Get_Edit_Buf());
   4850 					} else {
   4851 						strcpy (Session.GPacket.Message.Buf,
   4852 							Session.Messages.Get_Overflow_Buf());
   4853 						Session.Messages.Clear_Overflow_Buf();
   4854 					}
   4855 					Session.GPacket.Message.Color = Session.ColorIdx;
   4856 					Session.GPacket.Message.NameCRC =
   4857 						Compute_Name_CRC(Session.GameName);
   4858 
   4859 					//............................................................
   4860 					//	Send the message to every player in our player list, except
   4861 					// myself.
   4862 					//............................................................
   4863 					for (i = 1; i < Session.Players.Count(); i++) {
   4864 						Ipx.Send_Global_Message (&Session.GPacket,
   4865 							sizeof(GlobalPacketType), 1,
   4866 							&(Session.Players[i]->Address));
   4867 						Ipx.Service();
   4868 					}
   4869 
   4870 					//............................................................
   4871 					//	Add the message to our own list, since we're not in the
   4872 					// player list on this dialog.
   4873 					// If there's no message with this ID already displayed, just
   4874 					// add a new message; if there is one, concatenate it.
   4875 					//............................................................
   4876 					Session.Messages.Add_Message (Session.GPacket.Name,
   4877 						(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   4878 															PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   4879 						Session.GPacket.Message.Buf,
   4880 						(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? PCOLOR_REALLY_BLUE : Session.ColorIdx,
   4881 						TPF_TEXT, -1);
   4882 
   4883 					Session.Messages.Add_Edit((Session.ColorIdx == PCOLOR_DIALOG_BLUE) ?
   4884 															PCOLOR_REALLY_BLUE : Session.ColorIdx,
   4885 													TPF_TEXT, NULL, '_', d_message_w);
   4886 
   4887 					display = REDRAW_MESSAGE;
   4888 				}
   4889 				break;
   4890 		}
   4891 
   4892 		//.....................................................................
   4893 		//	Process incoming packets
   4894 		//.....................................................................
   4895 #ifndef FIXIT_VERSION_3
   4896 		int oldversion = PlayingAgainstVersion;
   4897 #endif
   4898 		whahoppa = Get_NewGame_Responses(&playerlist, color_used);
   4899 		if (whahoppa == EV_NEW_PLAYER) {
   4900 			ok_timer = TickCount;
   4901 			aiplayersgauge.Set_Maximum(Rule.MaxPlayers-Session.Players.Count());
   4902 			Session.Options.AIPlayers = aiplayersgauge.Get_Value();
   4903 			if (Session.Options.AIPlayers+Session.Players.Count() > Rule.MaxPlayers) {	// if it's pegged, max it out
   4904 				Session.Options.AIPlayers = Rule.MaxPlayers - Session.Players.Count();
   4905  				aiplayersgauge.Set_Value(Session.Options.AIPlayers);
   4906  			}
   4907 #ifdef FIXIT_VERSION_3		//	All scenarios now allowable for download, regardless of if CS scen. or 126x126 scen.
   4908 			if (display < REDRAW_PARMS) display = REDRAW_PARMS;
   4909 #else	//	FIXIT_VERSION_3
   4910 				if (oldversion == PlayingAgainstVersion){
   4911 					if (display < REDRAW_PARMS) display = REDRAW_PARMS;
   4912 				}else{
   4913 
   4914 					/*
   4915 					** If a CS scenario was selected and we now have a red alert only player
   4916 					** in the mix then deselect the cs scenario.
   4917 					*/
   4918 	#ifdef FIXIT_CSII	//	checked - ajw
   4919 					if ((PlayingAgainstVersion != VERSION_RED_ALERT_107 && PlayingAgainstVersion != VERSION_RED_ALERT_108 && PlayingAgainstVersion < VERSION_AFTERMATH_CS) &&
   4920 	#else
   4921 					if (PlayingAgainstVersion < VERSION_RED_ALERT_107 &&
   4922 	#endif
   4923 								Session.Scenarios[scenariolist.Current_Index()]->Get_Expansion()){
   4924 						scenariolist.Set_Selected_Index (0);
   4925 						Session.Options.ScenarioIndex = scenariolist.Current_Index();
   4926 					}
   4927 	#ifdef FIXIT_CSII	//	checked - ajw
   4928 					/*
   4929 					** If an AM mega scenario was selected and we now have a non-AM
   4930 					** player in the mix then deselect the mega scenario.
   4931 					*/
   4932 					if (PlayingAgainstVersion < VERSION_AFTERMATH_CS &&
   4933 								Is_Mission_126x126((char *)Session.Scenarios[scenariolist.Current_Index()]->Get_Filename() ) ){
   4934 						scenariolist.Set_Selected_Index (0);
   4935 						Session.Options.ScenarioIndex = scenariolist.Current_Index();
   4936 					}
   4937 	#endif
   4938 					display = REDRAW_BACKGROUND;
   4939 				}
   4940 #endif	//	FIXIT_VERSION_3
   4941 
   4942 			transmit = 1;
   4943 		} else if (whahoppa == EV_MESSAGE) {
   4944 			display = REDRAW_MESSAGE;
   4945 		} else if (whahoppa == EV_PLAYER_SIGNOFF) {
   4946 			aiplayersgauge.Set_Maximum(Rule.MaxPlayers-Session.Players.Count());
   4947 			Session.Options.AIPlayers = aiplayersgauge.Get_Value();
   4948 			if (Session.Options.AIPlayers+Session.Players.Count() > Rule.MaxPlayers) {	// if it's pegged, max it out
   4949 				Session.Options.AIPlayers = Rule.MaxPlayers - Session.Players.Count();
   4950  				aiplayersgauge.Set_Value(Session.Options.AIPlayers);
   4951 				display = REDRAW_PARMS;
   4952  			}
   4953 			transmit = 1;
   4954 		}
   4955 
   4956 		//.....................................................................
   4957 		//	If our Transmit flag is set, we need to send out a game option packet
   4958 		// Don't send it to myself.
   4959 		//.....................................................................
   4960 		if (transmit) {
   4961 			for (i = 1; i < Session.Players.Count(); i++) {
   4962 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   4963 
   4964 				Session.GPacket.Command = NET_GAME_OPTIONS;
   4965 
   4966 				/*
   4967 				** Set up the scenario info so the remote player can match the scenario on his machine
   4968 				** or request a download if it doesnt exist
   4969 				*/
   4970 				strcpy (Session.GPacket.ScenarioInfo.Scenario, Session.Scenarios[Session.Options.ScenarioIndex]->Description());
   4971 				CCFileClass file (Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename());
   4972 				Session.GPacket.ScenarioInfo.FileLength = file.Size();
   4973 #ifdef WOLAPI_INTEGRATION
   4974 				strcpy( Session.GPacket.ScenarioInfo.ShortFileName, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename() );
   4975 #else
   4976 				strncpy (Session.GPacket.ScenarioInfo.ShortFileName, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename(), sizeof(Session.GPacket.ScenarioInfo.ShortFileName));
   4977 #endif
   4978 				strncpy ((char*)Session.GPacket.ScenarioInfo.FileDigest, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Digest(), sizeof (Session.GPacket.ScenarioInfo.FileDigest));
   4979 				Session.GPacket.ScenarioInfo.OfficialScenario = Session.Scenarios[Session.Options.ScenarioIndex]->Get_Official();
   4980 
   4981 				Session.GPacket.ScenarioInfo.Credits = Session.Options.Credits;
   4982 				Session.GPacket.ScenarioInfo.IsBases = Session.Options.Bases;
   4983 				Session.GPacket.ScenarioInfo.IsTiberium = Session.Options.Tiberium;
   4984 				Session.GPacket.ScenarioInfo.IsGoodies = Session.Options.Goodies;
   4985 				Session.GPacket.ScenarioInfo.BuildLevel = BuildLevel;
   4986 				Session.GPacket.ScenarioInfo.UnitCount = Session.Options.UnitCount;
   4987 				Session.GPacket.ScenarioInfo.AIPlayers = Session.Options.AIPlayers;
   4988 				Session.GPacket.ScenarioInfo.Seed = Seed;
   4989 				Session.GPacket.ScenarioInfo.Special = Special;
   4990 				Session.GPacket.ScenarioInfo.GameSpeed = Options.GameSpeed;
   4991 #ifdef FIXIT_VERSION_3
   4992 				Session.GPacket.ScenarioInfo.Version = VerNum.Get_Clipped_Version();
   4993 				//	Host encodes whether or not this is an Aftermath game in the highest bit.
   4994 				if( bAftermathMultiplayer )
   4995 				{
   4996 //					debugprint( "Host tells guests 'This is an Aftermath game'\n" );
   4997 					Session.GPacket.ScenarioInfo.Version = VerNum.Get_Clipped_Version() | 0x80000000;
   4998 				}
   4999 				else
   5000 				{
   5001 //					debugprint( "Host tells guests 'This is NOT an Aftermath game'\n" );
   5002 					Session.GPacket.ScenarioInfo.Version = VerNum.Get_Clipped_Version();
   5003 				}
   5004 #else
   5005 				Session.GPacket.ScenarioInfo.Version = VerNum.Get_Clipped_Version();
   5006 #endif
   5007 
   5008 				Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5009 					1, &(Session.Players[i]->Address) );
   5010 			}
   5011 			Sound_Effect(VOC_OPTIONS_CHANGED);
   5012 			transmit = 0;
   5013 		}
   5014 
   5015 		//.....................................................................
   5016 		//	Ping every player in my game, to force the Global Channel to measure
   5017 		//	the connection response time.  Don't ping myself (index 0).
   5018 		//.....................................................................
   5019 		if (TickCount - ping_timer > 15) {
   5020 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5021 			Session.GPacket.Command = NET_PING;
   5022 			for (i = 1; i < Session.Players.Count(); i++) {
   5023 				Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5024 					1, &(Session.Players[i]->Address) );
   5025 			}
   5026 			ping_timer = TickCount;
   5027 		}
   5028 
   5029 		//.....................................................................
   5030 		//	Service the Ipx connections
   5031 		//.....................................................................
   5032 		Ipx.Service();
   5033 
   5034 		//.....................................................................
   5035 		//	Service the sounds & score; GameActive must be false at this point,
   5036 		//	so Call_Back() doesn't intercept global messages from me!
   5037 		//.....................................................................
   5038 		Call_Back();
   5039 	}
   5040 
   5041 	//------------------------------------------------------------------------
   5042 	//	Prepare to load the scenario
   5043 	//------------------------------------------------------------------------
   5044 	if (rc) {
   5045 		//.....................................................................
   5046 		//	Set the player count & scenario number
   5047 		//.....................................................................
   5048 		Session.NumPlayers = Session.Players.Count();
   5049 
   5050 		Scen.Scenario = Session.Options.ScenarioIndex;
   5051 		strcpy (Scen.ScenarioName, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename());
   5052 
   5053 		//.....................................................................
   5054 		//	Compute frame delay value for packet transmissions:
   5055 		//	- Divide global channel's response time by 8 (2 to convert to 1-way
   5056 		//	  value, 4 more to convert from ticks to frames)
   5057 		//.....................................................................
   5058 		if (Session.CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) {
   5059 			Session.MaxAhead = max( ((((Ipx.Global_Response_Time() / 8) +
   5060 				(Session.FrameSendRate - 1)) / Session.FrameSendRate) *
   5061 				Session.FrameSendRate), (Session.FrameSendRate * 2) );
   5062 		}
   5063 		else {
   5064 			Session.MaxAhead = max( (Ipx.Global_Response_Time() / 8),
   5065 										  NETWORK_MIN_MAX_AHEAD );
   5066 		}
   5067 
   5068 		Ipx.Set_Timing (25, (unsigned long) -1, 1000);
   5069 
   5070 		//.....................................................................
   5071 		//	Send all players the NET_GO packet.  Wait until all ACK's have been
   5072 		//	received.
   5073 		//.....................................................................
   5074 		memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5075 		if (load_game)
   5076 			Session.GPacket.Command = NET_LOADGAME;
   5077 		else
   5078 			Session.GPacket.Command = NET_GO;
   5079 		Session.GPacket.ResponseTime.OneWay = Session.MaxAhead;
   5080 		for (i = 1; i < Session.Players.Count(); i++) {
   5081 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5082 				1, &(Session.Players[i]->Address) );
   5083 		}
   5084 		//.....................................................................
   5085 		//	Wait for all the ACK's to come in.
   5086 		//.....................................................................
   5087 		while (Ipx.Global_Num_Send() > 0) {
   5088 			Ipx.Service();
   5089 		}
   5090 
   5091 		/*
   5092 		** Wait for the go responses from each player in case someone needs the scenario
   5093 		** file to be sent.
   5094 		*/
   5095 		int responses[20];		//In big trub if more than 20 players
   5096 		memset (responses, 0, sizeof (responses));
   5097 		int num_responses = 0;
   5098 		bool send_scenario = false;
   5099 #ifdef WIN32
   5100 		WWDebugString ("RA95 - About to wait for 'GO' response.");
   5101 #endif
   5102 		CDTimerClass<SystemTimerClass> response_timer;		// timeout timer for waiting for responses
   5103 		response_timer = 60*10;		// Wait for 10 seconds. If we dont hear by then assume someone crashed
   5104 
   5105 		do	{
   5106 			Ipx.Service();
   5107 			int retcode = Ipx.Get_Global_Message (&Session.GPacket, &Session.GPacketlen,
   5108 				&Session.GAddress, &Session.GProductID);
   5109 			if (retcode && Session.GProductID == IPXGlobalConnClass::COMMAND_AND_CONQUER0) {
   5110 
   5111 				for ( i=1 ; i<Session.Players.Count() ; i++ ) {
   5112 					if (Session.Players[i]->Address == Session.GAddress) {
   5113 						if (!responses[i]) {
   5114 							if (Session.GPacket.Command == NET_REQ_SCENARIO) {
   5115 								responses[i] = Session.GPacket.Command;
   5116 								send_scenario = true;
   5117 								num_responses++;
   5118 							}
   5119 							if (Session.GPacket.Command == NET_READY_TO_GO) {
   5120 								responses[i] = Session.GPacket.Command;
   5121 								num_responses++;
   5122 							}
   5123 						}
   5124 					}
   5125 				}
   5126 			}
   5127 		} while ( num_responses < Session.Players.Count()-1 && response_timer );
   5128 
   5129 #ifdef FIXIT_VERSION_3
   5130 		if( Session.Scenarios[Session.Options.ScenarioIndex]->Get_Official() )
   5131 		{
   5132 			if( !Force_Scenario_Available( Scen.ScenarioName ) )
   5133 				Emergency_Exit(EXIT_FAILURE);
   5134 		}
   5135 #endif
   5136 
   5137 		/*
   5138 		** If one of the machines requested that the scenario be sent then send it.
   5139 		*/
   5140 		if (send_scenario) {
   5141 			memset (Session.ScenarioRequests, 0, sizeof (Session.ScenarioRequests));
   5142 			Session.RequestCount = 0;
   5143 			for ( i=1 ; i<Session.Players.Count() ; i++ ) {
   5144 				if (responses[i] == NET_REQ_SCENARIO) {
   5145 					Session.ScenarioRequests[Session.RequestCount++] = i;
   5146 				}
   5147 			}
   5148 			Send_Remote_File (Scen.ScenarioName, 1);
   5149 		}
   5150 	}
   5151 
   5152 	//------------------------------------------------------------------------
   5153 	//	Init network timing values, using previous response times as a measure
   5154 	//	of what our retry delta & timeout should be.
   5155 	//------------------------------------------------------------------------
   5156 	//Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1, Ipx.Global_Response_Time() * 4);
   5157 	Ipx.Set_Timing (Ipx.Global_Response_Time () + 2, (unsigned long) -1, max (120, Ipx.Global_Response_Time () * 8));
   5158 
   5159 	//------------------------------------------------------------------------
   5160 	//	Clear all lists, but NOT the Games or Players vectors.
   5161 	//------------------------------------------------------------------------
   5162 	while (scenariolist.Count()) {
   5163 		scenariolist.Remove_Item(scenariolist.Get_Item(0));
   5164 	}
   5165 	Clear_Listbox(&playerlist);
   5166 
   5167 	//------------------------------------------------------------------------
   5168 	// Remove the chat edit box
   5169 	//------------------------------------------------------------------------
   5170 	Session.Messages.Remove_Edit();
   5171 
   5172 	//------------------------------------------------------------------------
   5173 	//	Restore screen
   5174 	//------------------------------------------------------------------------
   5175 	Hide_Mouse();
   5176 	Load_Title_Page(true);
   5177 //#ifdef WIN32
   5178 //	Load_Uncompress(CCFileClass("TITLE.CPS"), SysMemPage, SysMemPage, CCPalette);
   5179 //	SysMemPage.Scale(SeenPage);
   5180 //#else
   5181 //	Load_Uncompress(CCFileClass("TITLE.CPS"), HidPage, HidPage, CCPalette);
   5182 //	HidPage.Blit(SeenPage);
   5183 //#endif	//WIN32
   5184 	Show_Mouse();
   5185 
   5186 	if (load_game) {
   5187 		if (!Load_Game (-1)) {
   5188 			WWMessageBox().Process (TXT_ERROR_LOADING_GAME);
   5189 			rc = false;
   5190 		}
   5191 		Frame++;
   5192 	}
   5193 
   5194 	//------------------------------------------------------------------------
   5195 	// Clear the Players vector if we're not starting a game.
   5196 	//------------------------------------------------------------------------
   5197 	if (!rc) {
   5198 		Clear_Vector(&Session.Players);
   5199 	}
   5200 
   5201 //	while (optionlist.Count()>0) {
   5202 //		item = (char *)optionlist.Get_Item(0);
   5203 //		delete [] item;
   5204 //		optionlist.Remove_Item(item);
   5205 //	}
   5206 
   5207 	return(rc);
   5208 #endif
   5209 }	/* end of Net_New_Dialog */
   5210 
   5211 
   5212 /***************************************************************************
   5213  * Get_NewGame_Responses -- processes packets for New Game dialog          *
   5214  *                                                                         *
   5215  * This routine can modify the contents of the given list box, as well		*
   5216  * as the contents of the Players Vector global.									*
   5217  *                                                                         *
   5218  * INPUT:                                                                  *
   5219  *		playerlist		list of players in this game									*
   5220  *		color_used		array of color-used flags										*
   5221  *                                                                         *
   5222  * OUTPUT:                                                                 *
   5223  *		EV_NONE = nothing happened															*
   5224  *		EV_NEW_PLAYER = a new player has joined; false otherwise					*
   5225  *		EV_PLAYER_SIGNOFF = a player has left											*
   5226  *		EV_MESSAGE = a message was received												*
   5227  *                                                                         *
   5228  * WARNINGS:                                                               *
   5229  *		none.																						*
   5230  *                                                                         *
   5231  * HISTORY:                                                                *
   5232  *   04/18/1995 BRR : Created.                                             *
   5233  *=========================================================================*/
   5234 static JoinEventType Get_NewGame_Responses(ColorListClass *playerlist,
   5235 	int *color_used)
   5236 {
   5237 	int rc;
   5238 	char * item;						// general-purpose string
   5239 	NodeNameType *who;				// node to add to Players Vector
   5240 	int i;
   5241 	int found;
   5242 	JoinEventType retval = EV_NONE;
   5243 	int resend;
   5244 	unsigned long version;			// version # to use
   5245 
   5246 	//------------------------------------------------------------------------
   5247 	//	If there is no incoming packet, just return
   5248 	//------------------------------------------------------------------------
   5249 	rc = Ipx.Get_Global_Message (&Session.GPacket, &Session.GPacketlen,
   5250 		&Session.GAddress, &Session.GProductID);
   5251 	if (!rc || Session.GProductID != IPXGlobalConnClass::COMMAND_AND_CONQUER0) {
   5252 		return(EV_NONE);
   5253 	}
   5254 
   5255 	//------------------------------------------------------------------------
   5256 	//	Try to handle the packet in a standard way
   5257 	//------------------------------------------------------------------------
   5258 	if (Process_Global_Packet(&Session.GPacket,&Session.GAddress) != 0) {
   5259 		return(EV_NONE);
   5260 	} else if (Session.GPacket.Command==NET_QUERY_JOIN) {
   5261 	//------------------------------------------------------------------------
   5262 	//	NET_QUERY_JOIN:
   5263 	//------------------------------------------------------------------------
   5264 		//.....................................................................
   5265 		//	See if this name is unique:
   5266 		//	- If the name matches, but the address is different, reject this player
   5267 		//	- If the name & address match, this packet must be a re-send of a
   5268 		//	  previous request; in this case, do nothing.  The other player must have
   5269 		//	  received my CONFIRM_JOIN packet (since it was sent with an ACK
   5270 		//	  required), so we can ignore this resend.
   5271 		//.....................................................................
   5272 		found = 0;
   5273 		resend = 0;
   5274 		for (i = 1; i < Session.Players.Count(); i++) {
   5275 			if (!strcmp(Session.Players[i]->Name,Session.GPacket.Name)) {
   5276 				if (Session.Players[i]->Address != Session.GAddress) {
   5277 					found = 1;
   5278 				}
   5279 				else {
   5280 					resend = 1;
   5281 				}
   5282 				break;
   5283 			}
   5284 		}
   5285 		//.....................................................................
   5286 		// If his name is the same as mine, treat it like a duplicate name
   5287 		//.....................................................................
   5288 		if (!strcmp (Session.Players[0]->Name, Session.GPacket.Name)) {
   5289 			found = 1;
   5290 		}
   5291 
   5292 		//.....................................................................
   5293 		//	Reject if name is a duplicate
   5294 		//.....................................................................
   5295 		if (found) {
   5296 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5297 			Session.GPacket.Command = NET_REJECT_JOIN;
   5298 			Session.GPacket.Reject.Why = (int)REJECT_DUPLICATE_NAME;
   5299 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5300 				1, &Session.GAddress);
   5301 			return(EV_NONE);
   5302 		}
   5303 
   5304 		//.....................................................................
   5305 		//	Reject if there are too many players
   5306 		//.....................................................................
   5307 		else if ( (Session.Players.Count() >= Session.MaxPlayers) && !resend) {
   5308 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5309 			Session.GPacket.Command = NET_REJECT_JOIN;
   5310 			Session.GPacket.Reject.Why = (int)REJECT_GAME_FULL;
   5311 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5312 				1, &Session.GAddress);
   5313 			return(EV_NONE);
   5314 		}
   5315 
   5316 		/*
   5317 		**	Don't allow joining if the rules.ini file doesn't appear to match.
   5318 		*/
   5319 		else if (Session.GPacket.PlayerInfo.CheatCheck != RuleINI.Get_Unique_ID() && !resend) {
   5320 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5321 			Session.GPacket.Command = NET_REJECT_JOIN;
   5322 			Session.GPacket.Reject.Why = (int)REJECT_MISMATCH;
   5323 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType), 1, &Session.GAddress);
   5324 			return(EV_NONE);
   5325 		}
   5326 
   5327 		//.....................................................................
   5328 		//	If this packet is NOT a resend, accept the player.  Grant him the
   5329 		//	requested color if possible.
   5330 		//.....................................................................
   5331 		else if (!resend) {
   5332 			//..................................................................
   5333 			//	Check the player's version range against our own, to see if
   5334 			// there's an overlap region
   5335 			//..................................................................
   5336 #ifdef FIXIT_VERSION_3
   5337 			//	Added to the transmitted _min_ version number is a bit indicating presence of Aftermath expansion.
   5338 			bool bGuestHasAftermath = Session.GPacket.PlayerInfo.MinVersion & 0x80000000;
   5339 			if( bGuestHasAftermath )
   5340 //				debugprint( "Host hears guest say 'I have Aftermath'\n" );
   5341 				;
   5342 			else
   5343 			{
   5344 //				debugprint( "Host hears guest say 'I don't have Aftermath'\n" );
   5345 				if( bAftermathMultiplayer )
   5346 				{
   5347 //					debugprint( "Host decides this is no longer an Aftermath game!\n" );
   5348 					bAftermathMultiplayer = false;
   5349 				}
   5350 			}
   5351 
   5352 			Session.GPacket.PlayerInfo.MinVersion &= ~0x80000000;		//	Strip special bit.
   5353 #endif
   5354 			version = VerNum.Clip_Version (Session.GPacket.PlayerInfo.MinVersion,
   5355 				Session.GPacket.PlayerInfo.MaxVersion);
   5356 
   5357 #ifndef FIXIT_VERSION_3
   5358 			PlayingAgainstVersion = version;
   5359 #endif
   5360 
   5361 // TCTCTC save off version number
   5362 
   5363 			//..................................................................
   5364 			// Reject player if his version is too old
   5365 			//..................................................................
   5366 			if (version == 0) {
   5367 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5368 				Session.GPacket.Command = NET_REJECT_JOIN;
   5369 				Session.GPacket.Reject.Why = (int)REJECT_VERSION_TOO_OLD;
   5370 				Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5371 					1, &Session.GAddress);
   5372 				return(EV_NONE);
   5373 			}
   5374 
   5375 			//..................................................................
   5376 			// Reject player if his version is too new
   5377 			//..................................................................
   5378 			else if (version == 0xffffffff) {
   5379 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5380 				Session.GPacket.Command = NET_REJECT_JOIN;
   5381 				Session.GPacket.Reject.Why = (int)REJECT_VERSION_TOO_NEW;
   5382 				Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5383 					1, &Session.GAddress);
   5384 				return(EV_NONE);
   5385 			}
   5386 			//..................................................................
   5387 			// If the player is accepted, our mutually-accepted version may be
   5388 			// different; set the CommProtocol accordingly.
   5389 			//..................................................................
   5390 			else {
   5391 				Session.CommProtocol = VerNum.Version_Protocol(version);
   5392 			}
   5393 
   5394 			//..................................................................
   5395 			//	Add node to the Vector list
   5396 			//..................................................................
   5397 			who = new NodeNameType;
   5398 			strcpy(who->Name, Session.GPacket.Name);
   5399 			who->Address = Session.GAddress;
   5400 			who->Player.House = Session.GPacket.PlayerInfo.House;
   5401 			Session.Players.Add (who);
   5402 
   5403 			//..................................................................
   5404 			//	Set player's color; if requested color isn't used, give it to him;
   5405 			//	otherwise, give him the 1st available color.  Mark the color we
   5406 			//	give him as used.
   5407 			//..................................................................
   5408 			if (color_used[Session.GPacket.PlayerInfo.Color] == 0) {
   5409 				who->Player.Color = Session.GPacket.PlayerInfo.Color;
   5410 			}
   5411 			else {
   5412 				for (i = 0; i < MAX_MPLAYER_COLORS; i++) {
   5413 					if (color_used[i]==0) {
   5414 						who->Player.Color = (PlayerColorType)i;
   5415 						break;
   5416 					}
   5417 				}
   5418 			}
   5419 			color_used[who->Player.Color] = 1;
   5420 
   5421 			//..................................................................
   5422 			//	Add player name to the list box
   5423 			//..................................................................
   5424 			item = new char [MPLAYER_NAME_MAX + 64];
   5425 #ifdef OLDWAY
   5426 			if (Session.GPacket.PlayerInfo.House==HOUSE_GOOD) {
   5427 				sprintf(item,"%s\t%s",Session.GPacket.Name, Text_String(TXT_ALLIES));
   5428 			}
   5429 			else {
   5430 				sprintf(item,"%s\t%s",Session.GPacket.Name, Text_String(TXT_SOVIET));
   5431 			}
   5432 #else	//OLDWAY
   5433 			sprintf (item, "%s\t%s", Session.GPacket.Name,
   5434 						Text_String(HouseTypeClass::As_Reference(Session.GPacket.PlayerInfo.House).Full_Name()));
   5435 #endif	//OLDWAY
   5436 			playerlist->Add_Item(item,
   5437 				(who->Player.Color == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[who->Player.Color]);
   5438 
   5439 			//..................................................................
   5440 			//	Send a confirmation packet
   5441 			//..................................................................
   5442 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   5443 
   5444 			Session.GPacket.Command = NET_CONFIRM_JOIN;
   5445 			strcpy(Session.GPacket.Name,Session.Handle);
   5446 			Session.GPacket.PlayerInfo.House = who->Player.House;
   5447 			Session.GPacket.PlayerInfo.Color = who->Player.Color;
   5448 
   5449 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   5450 				1, &Session.GAddress);
   5451 
   5452 			//..................................................................
   5453 			// Play a special sound.
   5454 			//..................................................................
   5455 			Sound_Effect(VOC_PLAYER_JOINED);
   5456 
   5457 			retval = EV_NEW_PLAYER;
   5458 		}
   5459 	}
   5460 
   5461 	//------------------------------------------------------------------------
   5462 	//	NET_SIGN_OFF: Another system is signing off: search for that system in
   5463 	//	the player list, & remove it if found
   5464 	//------------------------------------------------------------------------
   5465 	else if (Session.GPacket.Command==NET_SIGN_OFF) {
   5466 		for (i = 0; i < Session.Players.Count(); i++) {
   5467 
   5468 			//..................................................................
   5469 			//	Name found; remove it
   5470 			//..................................................................
   5471 			if (!strcmp (Session.Players[i]->Name, Session.GPacket.Name) &&
   5472 				Session.Players[i]->Address==Session.GAddress) {
   5473 
   5474 				//...............................................................
   5475 				//	Remove from the list box
   5476 				//...............................................................
   5477 				item = (char *)(playerlist->Get_Item(i));
   5478 				playerlist->Remove_Item(item);
   5479 				playerlist->Flag_To_Redraw();
   5480 				delete [] item;
   5481 
   5482 				//...............................................................
   5483 				//	Mark his color as available
   5484 				//...............................................................
   5485 				color_used[Session.Players[i]->Player.Color] = 0;
   5486 
   5487 				//...............................................................
   5488 				//	Delete from the Vector list
   5489 				//...............................................................
   5490 				delete Session.Players[i];
   5491 				Session.Players.Delete(Session.Players[i]);
   5492 
   5493 				//...............................................................
   5494 				// Play a special sound.
   5495 				//...............................................................
   5496 				Sound_Effect(VOC_PLAYER_LEFT);
   5497 
   5498 				retval = EV_PLAYER_SIGNOFF;
   5499 
   5500 				break;
   5501 			}
   5502 		}
   5503 	}
   5504 
   5505 	//------------------------------------------------------------------------
   5506 	//	NET_MESSAGE: Someone is sending us a message
   5507 	//------------------------------------------------------------------------
   5508 	else if (Session.GPacket.Command==NET_MESSAGE) {
   5509 		Session.Messages.Add_Message (Session.GPacket.Name,
   5510 			(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   5511 													PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   5512 			Session.GPacket.Message.Buf,
   5513 			(Session.GPacket.Message.Color == PCOLOR_DIALOG_BLUE) ?
   5514 													PCOLOR_REALLY_BLUE : Session.GPacket.Message.Color,
   5515 			TPF_TEXT, -1);
   5516 
   5517 		Sound_Effect(VOC_INCOMING_MESSAGE);
   5518 
   5519 		retval = EV_MESSAGE;
   5520 	}
   5521 
   5522 	return(retval);
   5523 
   5524 }	/* end of Get_NewGame_Responses */
   5525 
   5526 
   5527 /***************************************************************************
   5528  * Compute_Name_CRC -- computes CRC from char string                       *
   5529  *                                                                         *
   5530  * INPUT:                                                                  *
   5531  *		name		string to create CRC for												*
   5532  *                                                                         *
   5533  * OUTPUT:                                                                 *
   5534  *		CRC																						*
   5535  *                                                                         *
   5536  * WARNINGS:                                                               *
   5537  *		none.																						*
   5538  *                                                                         *
   5539  * HISTORY:                                                                *
   5540  *   06/29/1995 BRR : Created.                                             *
   5541  *=========================================================================*/
   5542 unsigned long Compute_Name_CRC(char *name)
   5543 {
   5544 	char buf[80];
   5545 	unsigned long crc = 0L;
   5546 	int i;
   5547 
   5548 	strcpy (buf, name);
   5549 	strupr (buf);
   5550 
   5551 	for (i = 0; i < (int)strlen(buf); i++) {
   5552 		Add_CRC (&crc, (unsigned long)buf[i]);
   5553 	}
   5554 
   5555 	return (crc);
   5556 
   5557 }	/* end of Compute_Name_CRC */
   5558 
   5559 
   5560 /***************************************************************************
   5561  * Net_Reconnect_Dialog -- Draws/updates the network reconnect dialog      *
   5562  *                                                                         *
   5563  * INPUT:                                                                  *
   5564  *		reconn			1 = reconnect, 0 = waiting for first-time connection	*
   5565  *		fresh				1 = draw from scratch, 0 = only update time counter	*
   5566  *		oldest_index	IPX connection index of oldest connection 				*
   5567  *							(only used for reconnection)									*
   5568  *		timeval			value to print in the countdown field						*
   5569  *                                                                         *
   5570  * OUTPUT:                                                                 *
   5571  *		none.																						*
   5572  *                                                                         *
   5573  * WARNINGS:                                                               *
   5574  *		none.																						*
   5575  *                                                                         *
   5576  * HISTORY:                                                                *
   5577  *   07/08/1995 BRR : Created.                                             *
   5578  *=========================================================================*/
   5579 void Net_Reconnect_Dialog(int reconn, int fresh, int oldest_index,
   5580 	unsigned long timeval)
   5581 {
   5582 	reconn; fresh; oldest_index; timeval;
   5583 #if (0)//PG
   5584 	static int x,y,w,h;
   5585 	int id;
   5586 	char buf1[40] = {0};
   5587 	char buf2[40] = {0};
   5588 	char const *buf3 = "";
   5589 
   5590 	int d_txt6_h = 6 * RESFACTOR+1;
   5591 	int d_margin = 5 * RESFACTOR;
   5592 
   5593 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   5594 
   5595 #ifdef WIN32
   5596 	/*
   5597 	** If we have just received input focus again after running in the background then
   5598 	** we need to redraw.
   5599 	*/
   5600 	if (AllSurfaces.SurfacesRestored) {
   5601 		AllSurfaces.SurfacesRestored=FALSE;
   5602 		fresh = true;
   5603 	}
   5604 #endif
   5605 
   5606 	//------------------------------------------------------------------------
   5607 	//	Draw the dialog from scratch
   5608 	//------------------------------------------------------------------------
   5609 	if (fresh) {
   5610 		Fancy_Text_Print("", 0, 0, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   5611 
   5612 		switch ( Session.Type) {
   5613 			case GAME_IPX:
   5614 			case GAME_INTERNET:
   5615 			case GAME_MODEM:
   5616 			case GAME_NULL_MODEM:
   5617 
   5618 				if (reconn) {
   5619 					id = Ipx.Connection_ID(oldest_index);
   5620 					sprintf(buf1,Text_String(TXT_RECONNECTING_TO),
   5621 						Ipx.Connection_Name(id));
   5622 				} else {
   5623 					sprintf(buf1,Text_String(TXT_WAITING_FOR_CONNECTIONS));
   5624 				}
   5625 				break;
   5626 
   5627 #if(TEN)
   5628 			case GAME_TEN:
   5629 				if (reconn) {
   5630 					id = Ten->Connection_ID(oldest_index);
   5631 					sprintf(buf1,Text_String(TXT_RECONNECTING_TO),
   5632 						Ten->Connection_Name(id));
   5633 				}
   5634 				else {
   5635 					sprintf(buf1,Text_String(TXT_WAITING_FOR_CONNECTIONS));
   5636 				}
   5637 #endif	// TEN
   5638 
   5639 #if(MPATH)
   5640 			case GAME_MPATH:
   5641 				if (reconn) {
   5642 					id = MPath->Connection_ID(oldest_index);
   5643 					sprintf(buf1,Text_String(TXT_RECONNECTING_TO),
   5644 						MPath->Connection_Name(id));
   5645 				}
   5646 				else {
   5647 					sprintf(buf1,Text_String(TXT_WAITING_FOR_CONNECTIONS));
   5648 				}
   5649 #endif	// MPATH
   5650 		}
   5651 
   5652 		sprintf(buf2,Text_String(TXT_TIME_ALLOWED), timeval + 1);
   5653 		buf3 = Text_String(TXT_PRESS_ESC);
   5654 
   5655 		w = max(String_Pixel_Width(buf1),String_Pixel_Width(buf2));
   5656 
   5657 #ifdef FIXIT_VERSION_3
   5658 		char szNewCancelMessage[ 300 ];
   5659 		sprintf( szNewCancelMessage, "%s%s", buf3, TXT_WOL_CANCELMEANSFORFEIT );
   5660 
   5661 		if( Session.Type == GAME_INTERNET && pWolapi && pWolapi->GameInfoCurrent.bTournament )
   5662 		{
   5663 			w = max(String_Pixel_Width(szNewCancelMessage), w);	// * RESFACTOR;		why was it ever multiplied by this!!!?
   5664 			w += (d_margin * 12);
   5665 		}
   5666 		else
   5667 		{
   5668 			w = max(String_Pixel_Width(buf3), w) * RESFACTOR;
   5669 			w += (d_margin * 5);
   5670 		}
   5671 #else
   5672 		w = max(String_Pixel_Width(buf3), w) * RESFACTOR;
   5673 		w += (d_margin * 5);
   5674 #endif
   5675 
   5676 		h = (d_txt6_h * 3) + (d_margin * 6);
   5677 		x = 160*RESFACTOR - (w / 2);
   5678 		y = 100*RESFACTOR - (h / 2);
   5679 
   5680 		Hide_Mouse();
   5681 		Set_Logic_Page(SeenBuff);
   5682 		Dialog_Box(x, y, w, h);
   5683 
   5684 		Fancy_Text_Print (buf1, 160*RESFACTOR, y + (d_margin * 2), scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   5685 
   5686 		Fancy_Text_Print (buf2, 160*RESFACTOR, y + (d_margin * 2) + d_txt6_h + d_margin, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   5687 
   5688 #ifdef FIXIT_VERSION_3
   5689 		if( Session.Type == GAME_INTERNET && pWolapi && pWolapi->GameInfoCurrent.bTournament )
   5690 			Fancy_Text_Print (szNewCancelMessage, 160*RESFACTOR, y + (d_margin * 2) + (d_txt6_h + d_margin) * 2, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   5691 		else
   5692 			Fancy_Text_Print (buf3, 160*RESFACTOR, y + (d_margin * 2) + (d_txt6_h + d_margin) * 2, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   5693 #else
   5694 		Fancy_Text_Print (buf3, 160*RESFACTOR, y + (d_margin * 2) + (d_txt6_h + d_margin) * 2, scheme, TBLACK, TPF_CENTER | TPF_TEXT);
   5695 #endif
   5696 
   5697 		Show_Mouse();
   5698 	}
   5699 	//------------------------------------------------------------------------
   5700 	//	Just update the timeout value on the dialog
   5701 	//------------------------------------------------------------------------
   5702 	else {
   5703 		Hide_Mouse();
   5704 		Set_Logic_Page(SeenBuff);
   5705 
   5706 		sprintf(buf2,Text_String(TXT_TIME_ALLOWED), timeval + 1);
   5707 
   5708 		int fillx = 160*RESFACTOR - (String_Pixel_Width (buf2) / 2) -6;
   5709 		LogicPage->Fill_Rect (fillx, y + (d_margin * 2) + d_txt6_h + d_margin,
   5710 									fillx + String_Pixel_Width (buf2) + 12,
   5711 									y + (d_margin * 2) + d_txt6_h + d_margin + d_txt6_h +1*RESFACTOR,
   5712 									BLACK);
   5713 
   5714 		Fancy_Text_Print (buf2, 160*RESFACTOR, y + (d_margin * 2) + d_txt6_h + d_margin, scheme, BLACK, TPF_CENTER | TPF_TEXT);
   5715 
   5716 		Show_Mouse();
   5717 	}
   5718 #endif
   5719 }	/* end of Net_Reconnect_Dialog */
   5720 
   5721 #define	MAX_CHAT_NAME		12
   5722 #define	MAX_CHAT_PHRASE	45
   5723 
   5724 struct WWPerson {
   5725 	char Name[MAX_CHAT_NAME];
   5726 	char Phrase[MAX_CHAT_PHRASE];
   5727 	PlayerColorType Color;
   5728 	unsigned long LastTime;
   5729 };
   5730 
   5731 struct WWPerson WWPersons[] = {
   5732 	{ {66,105,108,108,32,82,0,0,0,0,0,0,},
   5733 	  {72,101,121,44,32,105,115,110,39,116,32,116,104,105,115,32,99,111,111,108,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5734 	{ {66,105,108,108,32,82,0,0,0,0,0,0,},
   5735 	  {72,101,121,44,32,119,97,110,116,32,115,111,109,101,32,115,101,97,102,111,111,100,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5736 	{ {66,97,114,114,121,32,71,0,0,0,0,0,},
   5737 	  {71,114,101,97,116,46,32,74,117,115,116,32,103,114,101,97,116,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5738 	{ {66,97,114,114,121,32,71,0,0,0,0,0,},
   5739 	  {87,111,110,100,101,114,102,117,108,46,32,80,101,114,102,101,99,116,44,32,105,110,32,102,97,99,116,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5740 	{ {66,105,108,108,32,80,0,0,0,0,0,0,},
   5741 	  {89,111,117,32,99,97,108,108,32,116,104,105,115,32,65,73,63,32,32,83,104,101,101,115,104,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5742 	{ {66,105,108,108,32,80,0,0,0,0,0,0,},
   5743 	  {66,105,108,108,115,32,114,117,108,101,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5744 	{ {66,114,101,116,116,32,83,0,0,0,0,0,},
   5745 	  {84,97,107,101,32,116,104,105,115,32,111,117,116,44,32,110,111,119,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5746 	{ {66,114,101,116,116,32,83,0,0,0,0,0,},
   5747 	  {87,104,121,32,99,97,110,39,116,32,121,111,117,32,102,105,116,32,97,110,121,32,109,111,114,101,32,108,101,116,116,101,114,115,32,111,110,32,116,104,101,32,108,0,0,},PCOLOR_GREEN,0},
   5748 	{ {66,114,101,116,116,32,83,0,0,0,0,0,},
   5749 	  {69,100,44,32,73,32,119,97,110,116,32,116,111,32,116,97,108,107,32,116,111,32,121,111,117,32,97,98,111,117,116,32,116,104,105,115,46,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5750 	{ {66,114,101,116,116,32,83,0,0,0,0,0,},
   5751 	  {69,100,44,32,99,111,109,101,32,116,111,32,109,121,32,111,102,102,105,99,101,44,32,110,111,119,33,32,32,91,99,114,97,99,107,33,93,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5752 	{ {80,101,110,105,110,97,32,70,0,0,0,0,},
   5753 	  {72,97,115,32,97,110,121,111,110,101,32,115,101,101,110,32,109,121,32,115,116,97,112,108,101,114,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5754 	{ {80,101,110,105,110,97,32,70,0,0,0,0,},
   5755 	  {72,97,115,32,97,110,121,111,110,101,32,115,101,101,110,32,109,121,32,116,104,101,115,97,117,114,117,115,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5756 	{ {80,101,110,105,110,97,32,70,0,0,0,0,},
   5757 	  {72,97,115,32,97,110,121,111,110,101,32,115,101,101,110,32,109,121,32,112,101,110,99,105,108,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5758 	{ {77,105,108,111,32,66,0,0,0,0,0,0,},
   5759 	  {72,101,121,32,83,116,101,118,101,44,32,99,97,110,32,119,101,32,109,101,101,116,32,105,110,32,121,111,117,114,32,111,102,102,105,99,101,63,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5760 	{ {77,105,108,111,32,66,0,0,0,0,0,0,},
   5761 	  {83,116,101,118,101,44,32,105,116,39,108,108,32,111,110,108,121,32,116,97,107,101,32,97,32,109,105,110,117,116,101,46,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5762 	{ {82,111,98,32,83,0,0,0,0,0,0,0,},
   5763 	  {77,105,108,111,44,32,100,105,97,108,32,50,52,57,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5764 	{ {69,108,115,98,101,116,104,32,87,0,0,0,},
   5765 	  {84,104,97,116,39,115,32,39,69,108,115,98,101,116,104,39,44,32,119,105,116,104,32,97,110,32,69,45,76,45,83,46,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5766 	{ {69,108,115,98,101,116,104,32,87,0,0,0,},
   5767 	  {84,104,97,116,39,115,32,39,69,108,115,98,101,116,104,39,44,32,110,111,116,32,39,69,108,115,98,97,114,102,39,46,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5768 	{ {69,108,115,98,101,116,104,32,87,0,0,0,},
   5769 	  {84,104,97,116,39,115,32,39,69,108,115,98,101,116,104,39,44,32,110,111,116,32,39,69,108,102,98,117,116,116,39,46,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5770 	{ {75,97,114,101,110,32,71,0,0,0,0,0,},
   5771 	  {84,104,105,115,32,105,115,32,115,111,111,111,32,119,101,105,114,100,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5772 	{ {75,97,114,101,110,32,71,0,0,0,0,0,},
   5773 	  {68,117,104,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5774 	{ {80,104,105,108,32,71,0,0,0,0,0,0,},
   5775 	  {72,101,121,44,32,105,116,32,119,111,114,107,101,100,32,111,110,32,109,121,32,99,111,109,112,117,116,101,114,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5776 	{ {80,104,105,108,32,71,0,0,0,0,0,0,},
   5777 	  {84,104,105,115,32,116,104,105,110,103,32,105,115,32,99,108,101,97,114,108,121,32,97,32,119,97,115,116,101,32,111,102,32,109,101,109,111,114,121,46,0,0,0,0,0,},PCOLOR_GREEN,0},
   5778 	{ {74,111,101,32,66,0,0,0,0,0,0,0,},
   5779 	  {72,109,109,44,32,73,32,115,101,101,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5780 	{ {74,111,101,32,66,0,0,0,0,0,0,0,},
   5781 	  {65,104,104,44,32,121,101,115,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5782 	{ {77,97,114,105,97,32,68,77,77,76,0,0,},
   5783 	  {78,111,116,32,97,110,111,116,104,101,114,32,105,110,115,116,97,108,108,101,114,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5784 	{ {77,97,114,105,97,32,68,77,77,76,0,0,},
   5785 	  {72,65,32,72,65,32,72,65,32,72,65,32,72,65,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5786 	{ {77,105,107,101,32,76,0,0,0,0,0,0,},
   5787 	  {84,104,105,115,32,105,115,32,114,101,97,108,108,121,32,99,111,111,108,33,32,32,71,111,115,104,32,103,117,121,115,33,32,32,87,111,119,33,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5788 	{ {77,105,107,101,32,76,0,0,0,0,0,0,},
   5789 	  {87,111,119,33,32,32,89,111,117,32,103,117,121,115,32,97,114,101,32,116,104,101,32,103,114,101,97,116,101,115,116,33,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5790 	{ {77,105,107,101,32,71,0,0,0,0,0,0,},
   5791 	  {71,114,97,121,102,105,115,104,32,102,111,114,32,108,117,110,99,104,32,97,103,97,105,110,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5792 	{ {77,105,107,101,32,71,0,0,0,0,0,0,},
   5793 	  {84,104,105,115,32,105,115,32,108,97,109,101,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5794 	{ {71,108,101,110,110,32,83,0,0,0,0,0,},
   5795 	  {84,104,105,115,32,116,104,105,110,103,39,115,32,98,117,103,103,101,100,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5796 	{ {71,108,101,110,110,32,83,0,0,0,0,0,},
   5797 	  {83,104,105,112,32,105,116,33,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5798 	{ {83,116,101,118,101,32,87,0,0,0,0,0,},
   5799 	  {79,75,32,101,118,101,114,121,111,110,101,44,32,111,117,116,32,111,102,32,109,121,32,111,102,102,105,99,101,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5800 	{ {69,100,32,68,0,0,0,0,0,0,0,0,},
   5801 	  {65,32,103,111,111,100,32,99,104,97,116,32,112,114,111,103,114,97,109,32,105,115,32,108,105,107,101,32,97,32,110,105,110,106,97,46,46,46,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5802 	{ {69,100,32,68,0,0,0,0,0,0,0,0,},
   5803 	  {65,32,103,111,111,100,32,110,105,110,106,97,32,105,115,32,108,105,107,101,32,97,32,110,105,110,106,97,46,46,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5804 	{ {69,114,105,107,32,89,0,0,0,0,0,0,},
   5805 	  {73,32,119,101,97,114,32,100,101,115,105,103,110,101,114,32,106,101,97,110,115,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5806 	{ {69,114,105,107,32,89,0,0,0,0,0,0,},
   5807 	  {72,101,121,32,66,105,108,108,44,32,116,104,105,115,32,116,104,105,110,103,32,107,101,101,112,115,32,99,114,97,25,26,24,104,105,110,103,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5808 	{ {74,101,102,102,32,70,0,0,0,0,0,0,},
   5809 	  {84,104,105,115,32,105,115,32,97,98,115,111,108,117,116,101,108,121,32,116,104,101,32,98,101,115,116,32,101,118,101,114,33,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5810 	{ {74,101,102,102,32,70,0,0,0,0,0,0,},
   5811 	  {84,104,105,115,32,105,115,32,97,98,115,111,108,117,116,101,108,121,32,116,104,101,32,119,111,114,115,116,32,101,118,101,114,33,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5812 	{ {82,105,99,107,32,78,0,0,0,0,0,0,},
   5813 	  {83,111,117,110,100,115,32,108,105,107,101,32,97,32,100,114,105,118,101,114,32,112,114,111,98,108,101,109,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5814 	{ {83,99,111,116,116,32,66,0,0,0,0,0,},
   5815 	  {73,32,110,101,101,100,32,116,104,105,115,32,102,111,114,32,76,79,76,50,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5816 	{ {83,116,101,118,101,32,84,0,0,0,0,0,},
   5817 	  {84,104,105,115,32,115,101,101,109,115,32,114,97,116,104,101,114,32,115,105,108,108,121,44,32,97,99,116,117,97,108,108,121,46,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5818 	{ {80,97,117,108,32,77,0,0,0,0,0,0,},
   5819 	  {78,111,32,46,46,46,46,32,32,87,32,65,32,89,33,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5820 	{ {82,105,99,107,32,80,0,0,0,0,0,0,},
   5821 	  {65,72,32,72,65,32,72,65,32,72,65,33,33,32,32,72,65,72,65,33,33,32,32,65,72,72,32,72,65,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5822 	{ {74,111,101,32,75,0,0,0,0,0,0,0,},
   5823 	  {83,116,97,108,105,110,32,107,105,108,108,101,100,32,109,121,32,102,97,116,104,101,114,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5824 	{ {74,111,101,32,75,0,0,0,0,0,0,0,},
   5825 	  {73,32,104,111,112,101,32,121,111,117,39,114,101,32,112,114,111,117,100,32,111,102,32,121,111,117,114,115,101,108,102,44,32,66,105,108,108,46,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5826 	{ {66,105,103,32,87,105,108,108,121,0,0,0,},
   5827 	  {65,110,121,98,111,100,121,32,102,101,114,32,97,32,115,112,105,116,116,105,110,39,32,99,111,110,116,101,115,116,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5828 	{ {69,114,105,99,32,87,0,0,0,0,0,0,},
   5829 	  {75,97,114,97,116,101,32,105,115,32,103,111,111,100,32,98,117,116,32,121,111,117,32,117,115,101,32,105,116,32,102,111,114,32,101,118,105,108,33,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5830 	{ {84,101,100,32,77,0,0,0,0,0,0,0,},
   5831 	  {72,97,46,32,32,70,117,110,110,121,46,32,32,84,104,105,115,32,105,115,32,102,117,110,110,121,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5832 	{ {68,97,109,111,110,32,82,0,0,0,0,0,},
   5833 	  {73,32,98,108,97,109,101,32,116,104,101,32,70,114,101,110,99,104,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5834 	{ {68,119,105,103,104,116,32,79,0,0,0,0,},
   5835 	  {79,104,44,32,109,97,110,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5836 	{ {75,105,97,32,72,0,0,0,0,0,0,0,},
   5837 	  {73,111,110,32,99,97,110,110,111,110,32,114,101,97,100,121,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5838 	{ {75,105,97,32,72,0,0,0,0,0,0,0,},
   5839 	  {83,101,108,101,99,116,32,116,97,114,103,101,116,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5840 	{ {66,114,117,99,101,32,74,0,0,0,0,0,},
   5841 	  {73,32,97,109,32,116,104,101,32,71,101,110,105,101,32,111,102,32,116,104,101,32,108,97,109,112,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5842 	{ {76,97,117,114,97,32,87,0,0,0,0,0,},
   5843 	  {71,111,32,97,119,97,121,44,32,66,105,108,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5844 	{ {68,97,118,105,100,32,68,0,0,0,0,0,},
   5845 	  {72,109,109,109,46,46,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5846 	{ {77,105,107,101,32,76,105,0,0,0,0,0,},
   5847 	  {67,97,108,108,32,109,101,32,78,97,116,101,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5848 	{ {68,101,110,122,105,108,32,76,0,0,0,0,},
   5849 	  {84,104,105,115,32,119,111,117,108,100,32,98,101,32,98,101,116,116,101,114,32,111,110,32,116,104,101,32,77,97,99,46,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5850 	{ {71,114,101,103,32,72,0,0,0,0,0,0,},
   5851 	  {66,117,116,32,100,111,101,115,32,105,116,32,102,105,116,32,105,110,116,111,32,50,32,77,66,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5852 	{ {74,111,110,97,116,104,97,110,32,76,0,0,},
   5853 	  {73,32,116,104,105,110,107,32,73,32,110,101,101,100,32,97,32,104,97,105,114,99,117,116,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5854 	{ {65,100,97,109,32,73,0,0,0,0,0,0,},
   5855 	  {87,104,97,116,101,118,101,114,46,32,32,66,101,101,102,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5856 	{ {75,117,114,116,32,79,0,0,0,0,0,0,},
   5857 	  {70,105,120,32,105,116,32,121,111,117,114,115,101,108,102,46,32,32,73,39,109,32,98,117,115,121,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5858 	{ {74,111,115,101,112,104,32,72,0,0,0,0,},
   5859 	  {60,73,99,121,32,103,108,97,114,101,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5860 	{ {77,97,116,116,32,72,0,0,0,0,0,0,},
   5861 	  {73,39,109,32,110,101,118,101,114,32,103,111,111,100,32,119,105,116,104,32,99,108,101,118,101,114,32,111,110,32,116,104,101,32,115,112,111,116,46,46,46,0,0,0,0,},PCOLOR_GREEN,0},
   5862 	{ {67,104,114,105,115,32,82,0,0,0,0,0,},
   5863 	  {73,32,108,111,118,101,32,109,121,32,106,111,98,46,32,32,89,101,97,104,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5864 	{ {80,97,116,32,67,0,0,0,0,0,0,0,},
   5865 	  {73,39,109,32,97,32,112,114,111,102,101,115,115,105,111,110,97,108,32,121,111,100,101,108,108,101,114,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5866 	{ {73,97,110,32,76,0,0,0,0,0,0,0,},
   5867 	  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5868 	{ {74,97,99,107,32,77,0,0,0,0,0,0,},
   5869 	  {73,32,108,105,118,101,32,97,98,111,117,116,32,97,32,98,108,111,99,107,32,102,114,111,109,32,116,104,101,32,112,114,111,112,111,115,101,100,32,115,105,116,101,46,0,},PCOLOR_GREEN,0},
   5870 	{ {74,101,102,102,32,66,0,0,0,0,0,0,},
   5871 	  {84,104,101,121,32,97,108,108,32,108,111,111,107,32,108,105,107,101,32,97,110,116,115,32,102,114,111,109,32,117,112,32,104,101,114,101,46,0,0,0,0,0,0,0,0,},PCOLOR_GREEN,0},
   5872 };
   5873 
   5874 CDTimerClass<SystemTimerClass> wwperson_timer;
   5875 
   5876 void Start_WWChat(ColorListClass *playerlist)
   5877 {
   5878 	char *item;
   5879 	int i;
   5880 	HousesType house;
   5881 
   5882 	//------------------------------------------------------------------------
   5883 	// Ensure a different sequence each time
   5884 	//------------------------------------------------------------------------
   5885 	Scen.RandomNumber = rand();
   5886 
   5887 	//------------------------------------------------------------------------
   5888 	// Add myself to the player list
   5889 	//------------------------------------------------------------------------
   5890 	item = new char [MPLAYER_NAME_MAX + 64];
   5891 #ifdef OLDWAY
   5892 	if (Session.House==HOUSE_GOOD) {
   5893 		sprintf(item,"%s\t%s",Session.Handle, Text_String(TXT_ALLIES));
   5894 	}
   5895 	else {
   5896 		sprintf(item,"%s\t%s",Session.Handle, Text_String(TXT_SOVIET));
   5897 	}
   5898 #else	//OLDWAY
   5899 	sprintf (item, "%s\t%s", Session.Handle, Text_String(HouseTypeClass::As_Reference(Session.House).Full_Name()));
   5900 #endif	//OLDWAY
   5901 	playerlist->Add_Item(item,
   5902 		(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[Session.ColorIdx]);
   5903 
   5904 	//------------------------------------------------------------------------
   5905 	// Add everyone else to the list
   5906 	//------------------------------------------------------------------------
   5907 	for (i = 0; i < sizeof(WWPersons) / sizeof(struct WWPerson); i++) {
   5908 		//.....................................................................
   5909 		// Add the 1st entry to the list no matter what; for entries after the
   5910 		// 1st, only add the name if it's different from the previous name.
   5911 		//.....................................................................
   5912 		if (i==0 || strcmp(WWPersons[i].Name, WWPersons[i-1].Name)) {
   5913 			WWPersons[i].Color = (PlayerColorType)(Random_Pick(0,(int)(PCOLOR_LAST - 1)));
   5914 			if (Percent_Chance(50)) {
   5915 				house = HOUSE_GREECE;
   5916 			} else {
   5917 				house = HOUSE_USSR;
   5918 			}
   5919 //			house = (HousesType)Random_Pick((int)HOUSE_GOOD,(int)HOUSE_BAD);
   5920 			item = new char [MPLAYER_NAME_MAX + 64];
   5921 			if (house != HOUSE_USSR && house != HOUSE_UKRAINE) {
   5922 				sprintf(item,"%s\t%s", WWPersons[i].Name, Text_String(TXT_ALLIES));
   5923 			} else {
   5924 				sprintf(item,"%s\t%s", WWPersons[i].Name, Text_String(TXT_SOVIET));
   5925 			}
   5926 			playerlist->Add_Item(item,
   5927 				(WWPersons[i].Color == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[WWPersons[i].Color]);
   5928 		}
   5929 		//.....................................................................
   5930 		// If this entry's name is the same as the previous, copy the color
   5931 		// value from the previous entry.
   5932 		//.....................................................................
   5933 		else if (i > 0) {
   5934 			WWPersons[i].Color = WWPersons[i-1].Color;
   5935 		}
   5936 
   5937 	}
   5938 
   5939 	//wwperson_timer = 240;
   5940 	wwperson_timer = Random_Pick(90,360);
   5941 
   5942 }	// end of Start_WWChat
   5943 
   5944 
   5945 int Update_WWChat(void)
   5946 {
   5947 	int i;
   5948 	int j;
   5949 
   5950 	//------------------------------------------------------------------------
   5951 	// Do nothing if it's too soon.
   5952 	//------------------------------------------------------------------------
   5953 	if (wwperson_timer > 0) {
   5954 		return(0);
   5955 	}
   5956 
   5957 	//wwperson_timer = 240;
   5958 	wwperson_timer = Random_Pick(90,360);
   5959 
   5960 	//------------------------------------------------------------------------
   5961 	// Even after the timer's gone off, there's only a 1/8 chance we'll
   5962 	// print a message.
   5963 	//------------------------------------------------------------------------
   5964 	if (Percent_Chance(12)) {
   5965 		return(0);
   5966 	}
   5967 
   5968 	//------------------------------------------------------------------------
   5969 	// Randomly select a message to "send"; ensure we pick a message that
   5970 	// hasn't been recently displayed.
   5971 	//------------------------------------------------------------------------
   5972 	j = sizeof(WWPersons) / sizeof(struct WWPerson);
   5973 	i = Random_Pick (0, j - 1);
   5974 	if ((TickCount - WWPersons[i].LastTime) < 1800 &&
   5975 		WWPersons[i].LastTime != 0) {
   5976 		return(0);
   5977 	}
   5978 
   5979 	Session.Messages.Add_Message (WWPersons[i].Name,
   5980 		0,
   5981 		WWPersons[i].Phrase, WWPersons[i].Color,
   5982 		TPF_TEXT, -1);
   5983 	WWPersons[i].LastTime = TickCount;
   5984 
   5985 	return (1);
   5986 
   5987 }	// end of Update_WWChat
   5988 
   5989 
   5990 #if(0)
   5991 /*****************************************************************************/
   5992 void Start_Logging(void)
   5993 {
   5994 	FILE *fp;
   5995 	static char *ColorNames[6] = {
   5996 		"Yellow",
   5997 		"Red",
   5998 		"BlueGreen",
   5999 		"Orange",
   6000 		"Green",
   6001 		"Blue",
   6002 	};
   6003 	int i;
   6004 	int id;
   6005 	HousesType house;
   6006 	char *housenames[] = {
   6007 		"ALLIES",
   6008 		"SOVIET",
   6009 		"Neutral",
   6010 		"Special",
   6011 		"Multi1",
   6012 		"Multi2",
   6013 		"Multi3",
   6014 		"Multi4",
   6015 		};
   6016 	time_t t;
   6017 
   6018 	fp = fopen("NETPLAY.LOG","at");
   6019 	if (!fp)
   6020 		return;
   6021 
   6022 	/*
   6023 	**	Print game header
   6024 	*/
   6025 	t = time(NULL);
   6026 	fprintf (fp,"==============================================================\n");
   6027 	fprintf (fp,"Date:            %s",ctime(&t));
   6028 	fprintf (fp,"Scenario:        %s\n",
   6029 		Session.Scenarios[Session.Options.ScenarioIndex].Description());
   6030 	fprintf (fp,"Total # players: %d\n",Session.NumPlayers);
   6031 	fprintf (fp,"==============================================================\n");
   6032 
   6033 	/*
   6034 	**	Print connection info
   6035 	*/
   6036 
   6037 	/*
   6038 	**	Print player data
   6039 	*/
   6040 	fprintf(fp,"Local Player:\n");
   6041 	fprintf (fp,"             Name:%s\n", Session.Handle);
   6042 	fprintf (fp,"            Color:%s\n", ColorNames[Session.ColorIdx]);
   6043 	fprintf (fp,"            House:%s\n", housenames[Session.House]);
   6044 	fprintf (fp,"\n");
   6045 
   6046 	for (i = 0; i < Ipx.Num_Connections(); i++) {
   6047 		id = Ipx.Connection_ID(i);
   6048 		house = (HouseClass)id;
   6049 		fprintf(fp,"Connection %d:\n",i);
   6050 		fprintf (fp,"             Name:%s\n", Ipx.Connection_Name(id));
   6051 		fprintf (fp,"            Color:%s\n",
   6052 			ColorNames[HouseClass::As_Pointer(house)->RemapColor);
   6053 		fprintf (fp,"            House:%s\n", housenames[house]);
   6054 		fprintf (fp,"\n");
   6055 	}
   6056 
   6057 	/*
   6058 	**	Print game options
   6059 	*/
   6060 	fprintf(fp,"Game Options:\n");
   6061 	fprintf(fp,"             Bases:%d\n",Session.Options.Bases);
   6062 	fprintf(fp,"           Credits:%d\n",Session.Options.Credits);
   6063 	fprintf(fp,"          Tiberium:%d\n",Session.Options.Tiberium);
   6064 	fprintf(fp,"            Crates:%d\n",Session.Options.Goodies);
   6065 	fprintf(fp,"        AI Players:%d\n",Session.Options.AIPlayers);
   6066 	fprintf(fp,"       Build Level:%d\n",BuildLevel);
   6067 	fprintf(fp,"        Unit Count:%d\n",Session.Options.UnitCount);
   6068 	fprintf(fp,"              Seed:%d\n",Seed);
   6069 	fprintf (fp,"\n");
   6070 
   6071 	fclose(fp);
   6072 
   6073 }	/* end of Start_Logging */
   6074 
   6075 
   6076 void Log_Message(char *msg)
   6077 {
   6078 	FILE *fp;
   6079 
   6080 	fp = fopen("NETPLAY.LOG","at");
   6081 	if (!fp)
   6082 		return;
   6083 
   6084 	fprintf(fp,"%s (Frame:%d)\n",msg,Frame);
   6085 	fclose(fp);
   6086 	flushall();
   6087 
   6088 }	/* end of Log_Message */
   6089 #endif
   6090 
   6091 
   6092 
   6093 
   6094 
   6095 #ifndef WOLAPI_INTEGRATION			//	Rest of file ifdeffed out.
   6096 
   6097 
   6098 
   6099 
   6100 
   6101 extern bool Spawn_WChat(bool can_launch);
   6102 
   6103 /***********************************************************************************************
   6104  * Net_Fake_New_Dialog -- lets user start a new game                                           *
   6105  *                                                                                             *
   6106  * This dialog shows a list of who's requesting to join this game, and lets                    *
   6107  * the game initiator selectively approve each user.                                           *
   6108  *                                                                                             *
   6109  * The 'Players' vector matches one-for-one the contents of the list box.  The local system	  *
   6110  * is always listed first; the IPX Address of the local system will NOT be valid in the		  *
   6111  * Players vector.  The Games & Players vectors should be left filled in even after this		  *
   6112  * routine is exited; their contents are used to form connections to the other players,		  *
   6113  * after the scenario has been loaded.																			  *
   6114  *                                                                                             *
   6115  *    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                                           *
   6116  *    ³              New Network Game              ³                                           *
   6117  *    ³                                            ³                                           *
   6118  *    ³     Players               Scenario         ³                                           *
   6119  *    ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿   ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³                                           *
   6120  *    ³ ³ Boffo       ³.³   ³ Green Acres      ³.³ ³                                           *
   6121  *    ³ ³ Bozo        ÃÄ´   ³ Brown Sewers     ÃÄ´ ³                                           *
   6122  *    ³ ³ Bonzo       ³ ³   ³      ...         ³ ³ ³                                           *
   6123  *    ³ ³             ÃÄ´   ³                  ÃÄ´ ³                                           *
   6124  *    ³ ³             ³.³   ³                  ³.³ ³                                           *
   6125  *    ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ   ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³                                           *
   6126  *    ³     [Reject]             Count:--- ##      ³                                           *
   6127  *    ³                          Level:--- ##      ³                                           *
   6128  *    ³                                            ³                                           *
   6129  *    ³               Credits: _____               ³                                           *
   6130  *    ³       [  Bases   ]   [   Crates   ]        ³                                           *
   6131  *    ³       [ Tiberium ]   [ AI Players ]        ³                                           *
   6132  *    ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿   ³                                           *
   6133  *    ³  ³                                     ³   ³                                           *
   6134  *    ³  ³                                     ³   ³                                           *
   6135  *    ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ   ³                                           *
   6136  *    ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿   ³                                           *
   6137  *    ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ   ³                                           *
   6138  *    ³              [OK]    [Cancel]              ³                                           *
   6139  *    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                                           *
   6140  *                                                                                             *
   6141  * INPUT:                                                                                      *
   6142  *      none.                                                                                  *
   6143  *                                                                                             *
   6144  * OUTPUT:                                                                                     *
   6145  *      true = success, false = cancel                                                         *
   6146  *                                                                                             *
   6147  * WARNINGS:                                                                                   *
   6148  *      Session.GameName must contain this player's name.                                      *
   6149  *                                                                                             *
   6150  * HISTORY:                                                                                    *
   6151  *   02/14/1995 BR : Created.                                                                  *
   6152  *=============================================================================================*/
   6153 static int Net_Fake_New_Dialog(void)
   6154 {
   6155 #ifdef WIN32
   6156 	//------------------------------------------------------------------------
   6157 	//	Dialog & button dimensions
   6158 	//------------------------------------------------------------------------
   6159 	int d_dialog_w = 120 *RESFACTOR;											// dialog width
   6160 	int d_dialog_h = 80 *RESFACTOR;											// dialog height
   6161 	int d_dialog_x = ((320 *RESFACTOR- d_dialog_w) / 2);				// dialog x-coord
   6162 	int d_dialog_y = ((200 *RESFACTOR- d_dialog_h) / 2);				// centered y-coord
   6163 	int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);		// center x-coord
   6164 
   6165 	int d_txt6_h = 6*RESFACTOR+1;												// ht of 6-pt text
   6166 	int d_margin1 = 5*RESFACTOR;												// margin width/height
   6167 	int d_margin2 = 2*RESFACTOR;												// margin width/height
   6168 
   6169 	int d_playerlist_w = 118*RESFACTOR;
   6170 	int d_playerlist_h = ((6 * 6) + 3)*RESFACTOR;			// 6 rows high
   6171 	//int d_playerlist_x = d_dialog_x + d_margin1 + d_margin1;
   6172 	int d_playerlist_x = 500*RESFACTOR;
   6173 	int d_playerlist_y = d_dialog_y + d_margin1 + d_txt6_h;
   6174 
   6175 #if (GERMAN | FRENCH)
   6176 	int d_cancel_w = 50*RESFACTOR;
   6177 #else
   6178 	int d_cancel_w = 40*RESFACTOR;
   6179 #endif
   6180 	int d_cancel_h = 9*RESFACTOR;
   6181 	int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
   6182 	int d_cancel_y = d_dialog_y + d_dialog_h - 20*RESFACTOR;
   6183 
   6184 
   6185 	//------------------------------------------------------------------------
   6186 	//	Button Enumerations
   6187 	//------------------------------------------------------------------------
   6188 	enum {
   6189 		BUTTON_PLAYERLIST = 100,
   6190 		BUTTON_CANCEL,
   6191 	};
   6192 
   6193 	//------------------------------------------------------------------------
   6194 	//	Redraw values: in order from "top" to "bottom" layer of the dialog
   6195 	//------------------------------------------------------------------------
   6196 	typedef enum {
   6197 		REDRAW_NONE = 0,
   6198 		REDRAW_PARMS,
   6199 		REDRAW_MESSAGE,
   6200 		REDRAW_BUTTONS,
   6201 		REDRAW_BACKGROUND,
   6202 		REDRAW_ALL = REDRAW_BACKGROUND
   6203 	} RedrawType;
   6204 
   6205 	//------------------------------------------------------------------------
   6206 	//	Dialog variables
   6207 	//------------------------------------------------------------------------
   6208 	RedrawType display = REDRAW_ALL;		// redraw level
   6209 	bool process = true;						// process while true
   6210 	KeyNumType input;
   6211 
   6212 	int transmit;								// 1 = re-transmit new game options
   6213 
   6214 	long ok_timer = 0;						// for timing OK button
   6215 	int rc;
   6216 	int i;
   6217 	char *item;
   6218 	int tabs[] = {77};						// tabs for player list box
   6219 	int optiontabs[] = {8};					// tabs for option list box
   6220 
   6221 	NodeNameType *who;						// node to add to Players
   6222 	long ping_timer = 0;						// for sending Ping packets
   6223 
   6224 	int color_used[MAX_MPLAYER_COLORS];	// 1 = color has been used
   6225 	JoinEventType whahoppa;					// event generated by received packets
   6226 	CCFileClass loadfile ("SAVEGAME.NET");
   6227 	int load_game = 0;						// 1 = load a saved game
   6228 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   6229 
   6230 	int	width;
   6231 	int	height;
   6232 
   6233 	bool	player_joined = false;
   6234 	CountDownTimerClass join_timer;
   6235 
   6236 	//PG_TO_FIX
   6237 	//Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW);
   6238 	Format_Window_String((char*)TXT_HACKHACK, SeenBuff.Get_Height(), width, height);
   6239 
   6240 	//------------------------------------------------------------------------
   6241 	// Buttons
   6242 	//------------------------------------------------------------------------
   6243 	GadgetClass *commands;					// button list
   6244 
   6245 	ColorListClass playerlist(BUTTON_PLAYERLIST,
   6246 		d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h,
   6247 		TPF_TEXT,
   6248 		MFCD::Retrieve("BTN-UP.SHP"),
   6249 		MFCD::Retrieve("BTN-DN.SHP"));
   6250 
   6251 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
   6252 //#if (GERMAN | FRENCH)
   6253 //		d_cancel_x, d_cancel_y);
   6254 //#else
   6255 		d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
   6256 //#endif
   6257 
   6258 	//------------------------------------------------------------------------
   6259 	//	Build the button list
   6260 	//------------------------------------------------------------------------
   6261 	commands = &playerlist;
   6262 	cancelbtn.Add_Tail(*commands);
   6263 	playerlist.Set_Tabs(tabs);
   6264 
   6265 	//------------------------------------------------------------------------
   6266 	//	Init other scenario parameters
   6267 	//------------------------------------------------------------------------
   6268 	Rule.IsTGrowth = Special.IsTGrowth;
   6269 	Special.IsTSpread = Session.Options.Tiberium;
   6270 	Rule.IsTSpread = Special.IsTSpread;
   6271 	transmit = 0;
   6272 
   6273 	//------------------------------------------------------------------------
   6274 	//	Init player color-used flags
   6275 	//------------------------------------------------------------------------
   6276 	for (i = 0; i < MAX_MPLAYER_COLORS; i++) {
   6277 		color_used[i] = 0;							// init all colors to available
   6278 	}
   6279 	color_used[Session.ColorIdx] = 1;			// set my color to used
   6280 	playerlist.Set_Selected_Style(ColorListClass::SELECT_BAR, scheme);
   6281 
   6282 	//------------------------------------------------------------------------
   6283 	//	Init random-number generator, & create a seed to be used for all random
   6284 	//	numbers from here on out
   6285 	//------------------------------------------------------------------------
   6286 //	randomize();
   6287 	Seed = rand();
   6288 
   6289 	//------------------------------------------------------------------------
   6290 	//	Init the version-clipping system
   6291 	//------------------------------------------------------------------------
   6292 	VerNum.Init_Clipping();
   6293 
   6294 	//------------------------------------------------------------------------
   6295 	//	Clear the list of players
   6296 	//------------------------------------------------------------------------
   6297 	Clear_Vector(&Session.Players);
   6298 	//------------------------------------------------------------------------
   6299 	//	Add myself to the list, and to the Players vector.
   6300 	//------------------------------------------------------------------------
   6301 	item = new char [MPLAYER_NAME_MAX + 64];
   6302 #ifdef OLDWAY
   6303 	if (Session.House==HOUSE_GOOD) {
   6304 		sprintf(item,"%s\t%s",Session.Handle, Text_String(TXT_ALLIES));
   6305 	}
   6306 	else {
   6307 		sprintf(item,"%s\t%s",Session.Handle, Text_String(TXT_SOVIET));
   6308 	}
   6309 #else	//OLDWAY
   6310 	sprintf (item, "%s\t%s", Session.Handle, Text_String(HouseTypeClass::As_Reference(Session.House).Full_Name()));
   6311 #endif	//OLDWAY
   6312 	playerlist.Add_Item(item,
   6313 		(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[Session.ColorIdx]);
   6314 
   6315 
   6316 	/*
   6317 	** Process the message loop until we are in focus.
   6318 	*/
   6319 	CDTimerClass<SystemTimerClass> focus_timer;		// Timer to allow a wait after client joins
   6320 	focus_timer = 5*60;
   6321 
   6322 	WWDebugString ("RA95 - About to enter wait for focus loop.\n");
   6323 	SetForegroundWindow ( MainWindow );
   6324 	ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
   6325 
   6326 	if (!GameInFocus) {
   6327 		do {
   6328 			Keyboard->Check();
   6329 			if (!focus_timer){
   6330 				WWDebugString ("RA95 - Calling SetForgroundWindow.\n");
   6331 				SetForegroundWindow ( MainWindow );
   6332 				WWDebugString ("RA95 - Calling ShowWindow.\n");
   6333 				ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
   6334 				focus_timer = 5*60;
   6335 			}
   6336 		}while (!GameInFocus);
   6337 		AllSurfaces.SurfacesRestored=FALSE;
   6338 	}
   6339 
   6340 	who = new NodeNameType;
   6341 	strcpy(who->Name, Session.Handle);
   6342 	who->Player.House = Session.House;
   6343 	who->Player.Color = Session.ColorIdx;
   6344 	Session.Players.Add (who);
   6345 
   6346 	if (LogicPage != &SeenBuff && LogicPage!= &HidPage) {
   6347 		Set_Logic_Page (SeenBuff);
   6348 	}
   6349 
   6350 	Load_Title_Page(true);
   6351 	CCPalette.Set();	//GamePalette.Set();
   6352 
   6353 	//------------------------------------------------------------------------
   6354 	//	Processing loop
   6355 	//------------------------------------------------------------------------
   6356 	while (process) {
   6357 		#if(SHOW_MONO)
   6358 		Ipx.Mono_Debug_Print(-1,0);
   6359 		#endif
   6360 
   6361 		#ifdef WIN32
   6362 		/*
   6363 		** If we have just received input focus again after running in the background then
   6364 		** we need to redraw.
   6365 		*/
   6366 		if (AllSurfaces.SurfacesRestored) {
   6367 			AllSurfaces.SurfacesRestored=FALSE;
   6368 			display = REDRAW_ALL;
   6369 		}
   6370 		#endif
   6371 		//.....................................................................
   6372 		//	Refresh display if needed
   6373 		//.....................................................................
   6374 		if (display) {
   6375 			Hide_Mouse();
   6376 
   6377 			//..................................................................
   6378 			//	Redraw backgound & dialog box
   6379 			//..................................................................
   6380 			if (display >= REDRAW_BACKGROUND) {
   6381 				Load_Title_Page(true);
   6382 				CCPalette.Set();	//GamePalette.Set();
   6383 				Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
   6384 
   6385 				//...............................................................
   6386 				//	Dialog & Field labels
   6387 				//...............................................................
   6388 				Fancy_Text_Print(TXT_HACKHACK, d_dialog_cx-width/2, d_dialog_y + 25*RESFACTOR, scheme, TBLACK, TPF_TEXT);
   6389 
   6390 			}
   6391 
   6392 			//..................................................................
   6393 			//	Redraw buttons
   6394 			//..................................................................
   6395 			if (display >= REDRAW_BUTTONS) {
   6396 				commands->Draw_All();
   6397 			}
   6398 
   6399 			Show_Mouse();
   6400 			display = REDRAW_NONE;
   6401 		}
   6402 
   6403 		//.....................................................................
   6404 		//	Get user input
   6405 		//.....................................................................
   6406 		input = commands->Input();
   6407 
   6408 		//.....................................................................
   6409 		//	Process input
   6410 		//.....................................................................
   6411 		switch (input) {
   6412 
   6413 			case (KN_ESC):
   6414 			case (BUTTON_CANCEL | KN_BUTTON):
   6415 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   6416 
   6417 				Session.GPacket.Command = NET_SIGN_OFF;
   6418 				strcpy (Session.GPacket.Name, Session.Handle);
   6419 
   6420 				//...............................................................
   6421 				//	Broadcast my sign-off over my network
   6422 				//...............................................................
   6423 				Ipx.Send_Global_Message (&Session.GPacket,
   6424 					sizeof (GlobalPacketType), 0, NULL);
   6425 				Ipx.Send_Global_Message (&Session.GPacket,
   6426 					sizeof (GlobalPacketType), 0, NULL);
   6427 				while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   6428 
   6429 				//...............................................................
   6430 				//	And now, just be absolutely sure, send my sign-off to each
   6431 				//	player in my game.  (If there's a bridge between us, the other
   6432 				//	player will have specified my address, so he can cross the
   6433 				//	bridge; but I may not have specified a bridge address, so the
   6434 				//	only way I have of crossing the bridge is to send a packet
   6435 				//	directly to him.)
   6436 				// Don't send this message to myself.
   6437 				//...............................................................
   6438 				for (i = 1; i < Session.Players.Count(); i++) {
   6439 					Ipx.Send_Global_Message (&Session.GPacket,
   6440 						sizeof(GlobalPacketType), 1, &(Session.Players[i]->Address));
   6441 					Ipx.Service();
   6442 				}
   6443 				while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   6444 				Session.GameName[0] = 0;
   6445 				process = false;
   6446 				rc = false;
   6447 				Send_Data_To_DDE_Server ("Hello", strlen("Hello"), DDEServerClass::DDE_CONNECTION_FAILED);
   6448 				GameStatisticsPacketSent = false;
   6449 				Spawn_WChat(false);
   6450 				break;
   6451 
   6452 			//..................................................................
   6453 			//	Default: manage the inter-player messages
   6454 			//..................................................................
   6455 			default:
   6456 				if (Session.Players.Count() > 1) {
   6457 
   6458 					/*
   6459 					** Wait for several secs after receiving request to join before sending
   6460 					** start game packet
   6461 					*/
   6462 					if (!player_joined) {
   6463 						player_joined = true;
   6464 						join_timer.Set (3*60, true);
   6465 						break;
   6466 					} else {
   6467 						if (join_timer.Time()) break;
   6468 					}
   6469 
   6470 					//...............................................................
   6471 					//	If a new player has joined in the last second, don't allow
   6472 					//	an OK; force a wait longer than 1 second (to give all players
   6473 					//	a chance to know about this new guy)
   6474 					//...............................................................
   6475 					i = MAX((int)Ipx.Global_Response_Time() * 2, 60*2);
   6476 					while ((int)TickCount - ok_timer < i) {
   6477 						Ipx.Service();
   6478 					}
   6479 
   6480 					//...............................................................
   6481 					//	If there are at least 2 players, go ahead & play; error otherwise
   6482 					//...............................................................
   6483 					if (Session.Solo || Session.Players.Count() > 1 || Session.Options.Ghosts) {
   6484 						rc = TRUE;
   6485 						process = FALSE;
   6486 					} else {
   6487 						WWMessageBox().Process (TXT_ONLY_ONE,TXT_OOPS,NULL);
   6488 						display = REDRAW_ALL;
   6489 						Sound_Effect(VOC_SYS_ERROR);
   6490 					}
   6491 					//if (input==(BUTTON_LOAD | KN_BUTTON))
   6492 					//	load_game = 1;
   6493 					break;
   6494 				}
   6495 				break;
   6496 
   6497 		}
   6498 
   6499 		//.....................................................................
   6500 		//	Process incoming packets
   6501 		//.....................................................................
   6502 		whahoppa = Get_NewGame_Responses(&playerlist, color_used);
   6503 		if (whahoppa == EV_NEW_PLAYER) {
   6504 			ok_timer = TickCount;
   6505 			transmit = 1;
   6506 		}
   6507 		else if (whahoppa == EV_MESSAGE) {
   6508 			display = REDRAW_MESSAGE;
   6509 		}
   6510 
   6511 		//.....................................................................
   6512 		//	If our Transmit flag is set, we need to send out a game option packet
   6513 		// Don't send it to myself.
   6514 		//.....................................................................
   6515 		if (transmit) {
   6516 			for (i = 1; i < Session.Players.Count(); i++) {
   6517 				memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   6518 
   6519 				Session.GPacket.Command = NET_GAME_OPTIONS;
   6520 				/*
   6521 				** Set up the scenario info so the remote player can match the scenario on his machine
   6522 				** or request a download if it doesnt exist
   6523 				*/
   6524 				strcpy (Session.GPacket.ScenarioInfo.Scenario, Session.Scenarios[Session.Options.ScenarioIndex]->Description());
   6525 				CCFileClass file (Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename());
   6526 
   6527 				//	ajw - I don't understand why this check is done here and not later.
   6528 				if ( !file.Is_Available() ) {
   6529 
   6530 					/*
   6531 					** Special new kludge for counterstrike.
   6532 					**
   6533 					** The only time the file can be unavailable is if its a counterstrike
   6534 					** mission and the CS CD is not in the drive so
   6535 					** make sure the counterstrike CD is in the drive.
   6536 					**
   6537 					** If Counterstrike is installed and
   6538 					** the file name matches a counterstrike map then force the CD
   6539 					** to be there.
   6540 					**
   6541 					*/
   6542 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   6543 					if ( Expansion_CS_Present() || Expansion_AM_Present() ) {
   6544 						if ( toupper (Session.ScenarioFileName [2]) == 'M' ){
   6545 
   6546 							int current_drive = CCFileClass::Get_CD_Drive();
   6547 							int index = Get_CD_Index(current_drive, 1*60);
   6548 							bool needcd = false;
   6549 							if (Is_Mission_Counterstrike(Session.ScenarioFileName) && index!=2 && index!=3) {
   6550 								needcd = true;
   6551 								RequiredCD = 2;
   6552 							}
   6553 							if (Is_Mission_Aftermath(Session.ScenarioFileName) && index!=3) {
   6554 								needcd = true;
   6555 								RequiredCD = 3;
   6556 							}
   6557 							if (needcd) {
   6558 #else
   6559 					if ( Expansion_CS_Present() ) {
   6560 						if ( toupper (Session.ScenarioFileName [2]) == 'M' ){
   6561 							int scen_num;
   6562 							sscanf ( Session.ScenarioFileName, "SCM%02d", &scen_num );
   6563 
   6564 							int current_drive = CCFileClass::Get_CD_Drive();
   6565 							if ( scen_num>24 && Get_CD_Index(current_drive, 1*60) != 2){
   6566 								RequiredCD = 2;
   6567 #endif
   6568 								if (!Force_CD_Available (RequiredCD)){
   6569 									Emergency_Exit(EXIT_FAILURE);
   6570 								}
   6571 
   6572 								/*
   6573 								** Update the internal list of scenarios to include the counterstrike
   6574 								** list.
   6575 								*/
   6576 								Session.Read_Scenario_Descriptions();
   6577 
   6578 							}
   6579 						}
   6580 					}
   6581 
   6582 					/*
   6583 					** See if that file is available now. Its fatal if it isnt.
   6584 					*/
   6585 					if ( !file.Is_Available() ) {
   6586 
   6587 						WWMessageBox().Process (TXT_UNABLE_PLAY_WAAUGH);
   6588 
   6589 						memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   6590 
   6591 						Session.GPacket.Command = NET_SIGN_OFF;
   6592 						strcpy (Session.GPacket.Name, Session.Handle);
   6593 
   6594 						//..................................................................
   6595 						// Don't send myself the message.
   6596 						//..................................................................
   6597 						for (i = 1; i < Session.Players.Count(); i++) {
   6598 							Ipx.Send_Global_Message (&Session.GPacket,
   6599 								sizeof(GlobalPacketType), 1,
   6600 								&(Session.Players[i]->Address));
   6601 							Ipx.Service();
   6602 						}
   6603 
   6604 						Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   6605 							0, NULL);
   6606 						Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   6607 							0, NULL);
   6608 
   6609 						while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   6610 
   6611 						Clear_Listbox(&playerlist);
   6612 
   6613 						//------------------------------------------------------------------------
   6614 						//	Restore screen
   6615 						//------------------------------------------------------------------------
   6616 						Hide_Mouse();
   6617 						Load_Title_Page(true);
   6618 						Show_Mouse();
   6619 
   6620 						//------------------------------------------------------------------------
   6621 						// Clear the Players vector if we're not starting a game.
   6622 						//------------------------------------------------------------------------
   6623 						Clear_Vector(&Session.Players);
   6624 						return (false);
   6625 					}
   6626 				}
   6627 
   6628 
   6629 				Session.GPacket.ScenarioInfo.FileLength = file.Size();
   6630 #ifdef WOLAPI_INTEGRATION
   6631 				strcpy( Session.GPacket.ScenarioInfo.ShortFileName, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename() );
   6632 #else
   6633 				strncpy (Session.GPacket.ScenarioInfo.ShortFileName, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename(), sizeof(Session.GPacket.ScenarioInfo.ShortFileName));
   6634 #endif
   6635 				strncpy ((char*)Session.GPacket.ScenarioInfo.FileDigest, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Digest(), sizeof (Session.GPacket.ScenarioInfo.FileDigest));
   6636 				Session.GPacket.ScenarioInfo.OfficialScenario = Session.Scenarios[Session.Options.ScenarioIndex]->Get_Official();
   6637 
   6638 				Session.GPacket.ScenarioInfo.Credits = Session.Options.Credits;
   6639 				Session.GPacket.ScenarioInfo.IsBases = Session.Options.Bases;
   6640 				Session.GPacket.ScenarioInfo.IsTiberium = Session.Options.Tiberium;
   6641 				Session.GPacket.ScenarioInfo.IsGoodies = Session.Options.Goodies;
   6642 				//Session.GPacket.ScenarioInfo.IsGhosties = Session.Options.Ghosts;
   6643 				Session.GPacket.ScenarioInfo.BuildLevel = BuildLevel;
   6644 				Session.GPacket.ScenarioInfo.UnitCount = Session.Options.UnitCount;
   6645 				Session.GPacket.ScenarioInfo.AIPlayers = Session.Options.AIPlayers;
   6646 				Session.GPacket.ScenarioInfo.Seed = Seed;
   6647 				Session.GPacket.ScenarioInfo.Special = Special;
   6648 				Session.GPacket.ScenarioInfo.GameSpeed = Options.GameSpeed;
   6649 				Session.GPacket.ScenarioInfo.Version = VerNum.Get_Clipped_Version();
   6650 
   6651 				Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   6652 					1, &(Session.Players[i]->Address) );
   6653 			}
   6654 			Sound_Effect(VOC_OPTIONS_CHANGED);
   6655 			transmit = 0;
   6656 		}
   6657 
   6658 		//.....................................................................
   6659 		//	Ping every player in my game, to force the Global Channel to measure
   6660 		//	the connection response time.  Don't ping myself (index 0).
   6661 		//.....................................................................
   6662 		if (TickCount - ping_timer > 15) {
   6663 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   6664 			Session.GPacket.Command = NET_PING;
   6665 			for (i = 1; i < Session.Players.Count(); i++) {
   6666 				Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   6667 					1, &(Session.Players[i]->Address) );
   6668 			}
   6669 			ping_timer = TickCount;
   6670 		}
   6671 
   6672 		//.....................................................................
   6673 		//	Service the Ipx connections
   6674 		//.....................................................................
   6675 		Ipx.Service();
   6676 
   6677 		//.....................................................................
   6678 		//	Service the sounds & score; GameActive must be false at this point,
   6679 		//	so Call_Back() doesn't intercept global messages from me!
   6680 		//.....................................................................
   6681 		Call_Back();
   6682 	}
   6683 
   6684 	//------------------------------------------------------------------------
   6685 	//	Prepare to load the scenario
   6686 	//------------------------------------------------------------------------
   6687 	if (rc) {
   6688 		//.....................................................................
   6689 		//	Set the player count & scenario number
   6690 		//.....................................................................
   6691 		Session.NumPlayers = Session.Players.Count();
   6692 
   6693 		Scen.Scenario = Session.Options.ScenarioIndex;
   6694 		strcpy (Scen.ScenarioName, Session.Scenarios[Session.Options.ScenarioIndex]->Get_Filename());
   6695 
   6696 		//.....................................................................
   6697 		//	Compute frame delay value for packet transmissions:
   6698 		//	- Divide global channel's response time by 8 (2 to convert to 1-way
   6699 		//	  value, 4 more to convert from ticks to frames)
   6700 		//.....................................................................
   6701 		if (Session.CommProtocol == COMM_PROTOCOL_MULTI_E_COMP) {
   6702 			Session.MaxAhead = MAX( ((((Ipx.Global_Response_Time() / 8) +
   6703 				(Session.FrameSendRate - 1)) / Session.FrameSendRate) *
   6704 				Session.FrameSendRate), (Session.FrameSendRate * 2) );
   6705 		}
   6706 		else {
   6707 			Session.MaxAhead = MAX( ((int)Ipx.Global_Response_Time() / 8),
   6708 										  NETWORK_MIN_MAX_AHEAD );
   6709 		}
   6710 
   6711 		//.....................................................................
   6712 		//	Send all players the NET_GO packet.  Wait until all ACK's have been
   6713 		//	received.
   6714 		//.....................................................................
   6715 		memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   6716 		if (load_game)
   6717 			Session.GPacket.Command = NET_LOADGAME;
   6718 		else
   6719 			Session.GPacket.Command = NET_GO;
   6720 		Session.GPacket.ResponseTime.OneWay = Session.MaxAhead;
   6721 		for (i = 1; i < Session.Players.Count(); i++) {
   6722 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   6723 				1, &(Session.Players[i]->Address) );
   6724 		}
   6725 		//.....................................................................
   6726 		//	Wait for all the ACK's to come in.
   6727 		//.....................................................................
   6728 		while (Ipx.Global_Num_Send() > 0) {
   6729 			Ipx.Service();
   6730 		}
   6731 
   6732 
   6733 		/*
   6734 		** Wait for the go responses from each player in case someone needs the scenario
   6735 		** file to be sent.
   6736 		*/
   6737 		int responses[20];		//In big trub if more than 20 players
   6738 		memset (responses, 0, sizeof (responses));
   6739 		int num_responses = 0;
   6740 		bool send_scenario = false;
   6741 		WWDebugString ("RA95 - About to wait for 'GO' response.\n");
   6742 
   6743 		CDTimerClass<SystemTimerClass> response_timer;		// timeout timer for waiting for responses
   6744 		response_timer = 60*30;		// Wait for 30 seconds. If we dont hear by then assume someone crashed
   6745 
   6746 		do	{
   6747 			Ipx.Service();
   6748 			int retcode = Ipx.Get_Global_Message (&Session.GPacket, &Session.GPacketlen,
   6749 				&Session.GAddress, &Session.GProductID);
   6750 			if (retcode && Session.GProductID == IPXGlobalConnClass::COMMAND_AND_CONQUER0) {
   6751 
   6752 				for ( i=1 ; i<Session.Players.Count() ; i++ ) {
   6753 					if (Session.Players[i]->Address == Session.GAddress) {
   6754 						if (!responses[i]) {
   6755 							if (Session.GPacket.Command == NET_REQ_SCENARIO) {
   6756 								responses[i] = Session.GPacket.Command;
   6757 								send_scenario = true;
   6758 								num_responses++;
   6759 							}
   6760 							if (Session.GPacket.Command == NET_READY_TO_GO) {
   6761 								responses[i] = Session.GPacket.Command;
   6762 								num_responses++;
   6763 							}
   6764 						}
   6765 					}
   6766 				}
   6767 			}
   6768 		} while ( num_responses < Session.Players.Count()-1 && response_timer );
   6769 
   6770 		WWDebugString ("RA95 - Exited response wait loop.\n");
   6771 
   6772 		/*
   6773 		** If one of the machines requested that the scenario be sent then send it.
   6774 		*/
   6775 		if (send_scenario) {
   6776 			memset (Session.ScenarioRequests, 0, sizeof (Session.ScenarioRequests));
   6777 			Session.RequestCount = 0;
   6778 			for ( i=1 ; i<Session.Players.Count() ; i++ ) {
   6779 				if (responses[i] == NET_REQ_SCENARIO) {
   6780 					Session.ScenarioRequests[Session.RequestCount++] = i;
   6781 				}
   6782 			}
   6783 			Send_Remote_File (Scen.ScenarioName, 1);
   6784 		}
   6785 
   6786 	}
   6787 
   6788 	//.....................................................................
   6789 	//	Wait a while, polling the IPX service routines, to give our ACK
   6790 	//	a chance to get to the other system.  If he doesn't get our ACK,
   6791 	// he'll be waiting the whole time we load MIX files.
   6792 	//.....................................................................
   6793 	i = MAX((int)Ipx.Global_Response_Time() * 2, 60*2);
   6794 	int starttime = TickCount;
   6795 	while ((int)TickCount - starttime < i) {
   6796 		Ipx.Service();
   6797 	}
   6798 
   6799 	//------------------------------------------------------------------------
   6800 	//	Init network timing values, using previous response times as a measure
   6801 	//	of what our retry delta & timeout should be.
   6802 	//------------------------------------------------------------------------
   6803 	//Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1,
   6804 	//	Ipx.Global_Response_Time() * 4);
   6805 	Ipx.Set_Timing (Ipx.Global_Response_Time () + 2, (unsigned long) -1, max (120, Ipx.Global_Response_Time () * 8));
   6806 
   6807 	Clear_Listbox(&playerlist);
   6808 
   6809 	//------------------------------------------------------------------------
   6810 	//	Restore screen
   6811 	//------------------------------------------------------------------------
   6812 	Hide_Mouse();
   6813 	Load_Title_Page(true);
   6814 	Show_Mouse();
   6815 
   6816 	if (load_game) {
   6817 		if (!Load_Game (-1)) {
   6818 			WWMessageBox().Process (TXT_ERROR_LOADING_GAME);
   6819 			rc = false;
   6820 		}
   6821 		Frame++;
   6822 	}
   6823 
   6824 	//------------------------------------------------------------------------
   6825 	// Clear the Players vector if we're not starting a game.
   6826 	//------------------------------------------------------------------------
   6827 	if (!rc) {
   6828 		Clear_Vector(&Session.Players);
   6829 	}
   6830 
   6831 //	while (optionlist.Count()>0) {
   6832 //		item = (char *)optionlist.Get_Item(0);
   6833 //		delete [] item;
   6834 //		optionlist.Remove_Item(item);
   6835 //	}
   6836 
   6837 	return(rc);
   6838 
   6839 #else	//WIN32
   6840 
   6841 	return (0);
   6842 
   6843 #endif	//WIN32
   6844 }	/* end of Net_Fake_New_Dialog */
   6845 
   6846 
   6847 
   6848 
   6849 
   6850 
   6851 
   6852 
   6853 
   6854 
   6855 /***********************************************************************************************
   6856  * Net_Join_Dialog -- lets user join an existing game or start a new one                       *
   6857  *                                                                                             *
   6858  * This dialog displays an edit field for the player's name, and a list of all non-stealth-    *
   6859  * mode games.  Clicking once on a game name displays a list of who's in that game.  Clicking  *
   6860  * "New" takes the user to the Net_New dialog, where he waits for other users to join his      *
   6861  * game.  All other input is done through this dialog.                                         *
   6862  *                                                                                             *
   6863  * The dialog has several "states":                                                            *
   6864  *                                                                                             *
   6865  *   1) Initially, it waits for the user to fill in his/her name and then to select Join or    *
   6866  *      New; if New is selected, this dialog is exited.                                        *
   6867  *                                                                                             *
   6868  *   2) If Join is selected, the Join & New buttons are removed, but the Cancel button remains.*
   6869  *      The join request is transmitted to the game's owner, and the message "Waiting for      *
   6870  *      Confirmation" is displayed, until a confirmation or denial is received from the game's *
   6871  *      owner.  The user may click Cancel at this point to cancel the join request.            *
   6872  *      (Once Join is selected, the name editing field is disabled, and becomes a display-only *
   6873  *      field.  If cancel is selected, it reappears as an edit field.) The user can still click*
   6874  *      around & see who's in which games.                                                     *
   6875  *                                                                                             *
   6876  *   3) If the join request is denied, the dialog re-initializes to its pre-join state; the    *
   6877  *      Join & New buttons reappear, & the Name field is available again.                      *
   6878  *                                                                                             *
   6879  *   4) If join confirmation is obtained, the message changes to show all the current game	  *
   6880  *      settings.  The user cannot click around & look at other games any more.					  *
   6881  *                                                                                             *
   6882  * Any game running in Stealth mode won't show up on this dialog.                              *
   6883  *                                                                                             *
   6884  * The 'Players' vector matches one-for-one the contents of the list box.  The local system	  *
   6885  * is always listed first; the IPX Address of the local system will NOT be valid in the		  *
   6886  * Players vector.  The Games & Players vectors should be left filled in even after this		  *
   6887  * routine is exited; their contents are used to form connections to the other players,		  *
   6888  * after the scenario has been loaded.																			  *
   6889  *                                                                                             *
   6890  * The 'Chat' vector contains the address of everyone who sends me a chat announcement.		  *
   6891  * The address field is used to send everyone my outgoing messages.  The LastTime				  *
   6892  * field is used as a timeout; if enough time goes by & we don't hear from this node,			  *
   6893  * we ping him, requesting a CHAT_ANNOUNCE if he's still in chat.  If we don't hear				  *
   6894  * from him after that, we remove him from our list.														  *
   6895  *                                                                                             *
   6896  *    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                                    *
   6897  *    ³                 Network Games                     ³                                    *
   6898  *    ³                                                   ³                                    *
   6899  *    ³              Your Name: ____________              ³                                    *
   6900  *    ³                  House: [GDI] [NOD]               ³                                    *
   6901  *    ³          Desired Color: [ ][ ][ ][ ]              ³                                    *
   6902  *    ³                                                   ³                                    *
   6903  *    ³            Games                 Players          ³                                    *
   6904  *    ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³                                    *
   6905  *    ³ ³(Bill's Game         )³.³ ³ Peter Parker GDI ³.³ ³                                    *
   6906  *    ³ ³ Peter Parker's Game  ÃÄ´ ³ Mary Jane    GDI ÃÄ´ ³                                    *
   6907  *    ³ ³(Magnum PI's Game    )³ ³ ³ JJ Jameson   NOD ³ ³ ³                                    *
   6908  *    ³ ³                      ÃÄ´ ³                  ÃÄ´ ³                                    *
   6909  *    ³ ³                      ³.³ ³                  ³.³ ³                                    *
   6910  *    ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³                                    *
   6911  *    ³           Scenario: Big Long Description          ³                                    *
   6912  *    ³                Starting Credits: xxxx             ³                                    *
   6913  *    ³          Count: ---          Level: ---           ³                                    *
   6914  *    ³          Bases: ON          Crates: ON            ³                                    *
   6915  *    ³       Tiberium: ON      AI Players: ON            ³                                    *
   6916  *    ³                                                   ³                                    *
   6917  *    ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿  ³                                    *
   6918  *    ³  ³                                             ³  ³                                    *
   6919  *    ³  ³                                             ³  ³                                    *
   6920  *    ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ  ³                                    *
   6921  *    ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿  ³                                    *
   6922  *    ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ  ³                                    *
   6923  *    ³            [Join]  [Cancel]    [New]              ³                                    *
   6924  *    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                                    *
   6925  *                                                                                             *
   6926  * INPUT:                                                                                      *
   6927  *      none.                                                                                  *
   6928  *                                                                                             *
   6929  * OUTPUT:                                                                                     *
   6930  *      -1 = cancel, 0 = OK, 1 = New net game requested                                        *
   6931  *                                                                                             *
   6932  * WARNINGS:                                                                                   *
   6933  *      none.                                                                                  *
   6934  *                                                                                             *
   6935  * HISTORY:                                                                                    *
   6936  *   02/14/1995 BR : Created.                                                                  *
   6937  *=============================================================================================*/
   6938 static int Net_Fake_Join_Dialog(void)
   6939 {
   6940 
   6941 #ifdef WIN32
   6942 	//------------------------------------------------------------------------
   6943 	//	Dialog & button dimensions
   6944 	//------------------------------------------------------------------------
   6945 		int d_dialog_w = 120 *RESFACTOR;											// dialog width
   6946 		int d_dialog_h = 80 *RESFACTOR;											// dialog height
   6947 		int d_dialog_x = ((320*RESFACTOR - d_dialog_w) / 2);				// dialog x-coord
   6948 		int d_dialog_y = ((200*RESFACTOR - d_dialog_h) / 2);				// centered y-coord
   6949 		int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);		// center x-coord
   6950 
   6951 		int d_txt6_h = 6 *RESFACTOR+1;												// ht of 6-pt text
   6952 		int d_margin1 = 5 *RESFACTOR;												// large margin
   6953 		int d_margin2 = 7 *RESFACTOR;												// small margin
   6954 
   6955 		int d_gamelist_w = 160 *RESFACTOR;
   6956 		int d_gamelist_h = ((6 * 6) + 3) *RESFACTOR;		// 6 rows high
   6957 //		int d_gamelist_x = d_dialog_x + d_margin1 + d_margin1;
   6958 		int d_gamelist_x = 500*RESFACTOR;	//d_dialog_x + d_margin1 + d_margin1;
   6959 		int d_gamelist_y = 50 + d_margin2 + 2*RESFACTOR/*KO + d_txt6_h + d_margin2*/;
   6960 
   6961 		int d_playerlist_w = 118 *RESFACTOR;
   6962 		int d_playerlist_h = ((6 * 6) + 3) *RESFACTOR;		// 6 rows high
   6963 		//int d_playerlist_x = d_dialog_x + d_dialog_w - d_margin1 - d_margin1 - d_playerlist_w;
   6964 		int d_playerlist_x = 500*RESFACTOR;
   6965 		int d_playerlist_y = 50+ d_margin2 + 2*RESFACTOR/*KO + d_txt6_h + d_margin2*/;
   6966 
   6967 #if (GERMAN | FRENCH)
   6968 	int d_cancel_w = 50*RESFACTOR;
   6969 #else
   6970 	int d_cancel_w = 40*RESFACTOR;
   6971 #endif
   6972 	int d_cancel_h = 9*RESFACTOR;
   6973 	int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
   6974 	int d_cancel_y = d_dialog_y + d_dialog_h - 20*RESFACTOR;
   6975 
   6976 	//------------------------------------------------------------------------
   6977 	//	Button Enumerations
   6978 	//------------------------------------------------------------------------
   6979 	enum {
   6980 		BUTTON_GAMELIST = 100,
   6981 		BUTTON_PLAYERLIST,
   6982 		BUTTON_CANCEL,
   6983 	};
   6984 
   6985 	//------------------------------------------------------------------------
   6986 	//	Redraw values: in order from "top" to "bottom" layer of the dialog
   6987 	//------------------------------------------------------------------------
   6988 	typedef enum {
   6989 		REDRAW_NONE = 0,
   6990 		REDRAW_PARMS,
   6991 		REDRAW_MESSAGE,
   6992 		REDRAW_COLORS,
   6993 		REDRAW_BUTTONS,
   6994 		REDRAW_BACKGROUND,
   6995 		REDRAW_ALL = REDRAW_BACKGROUND
   6996 	} RedrawType;
   6997 
   6998 	//------------------------------------------------------------------------
   6999 	//	Dialog variables
   7000 	//------------------------------------------------------------------------
   7001 	RedrawType display = REDRAW_ALL;		// redraw level
   7002 	bool process = true;						// process while true
   7003 	KeyNumType input;
   7004 	char housetext[25] = "";				// buffer for house droplist
   7005 	int isdropped = 0;
   7006 
   7007 	JoinStateType joinstate = JOIN_NOTHING;	// current "state" of this dialog
   7008 	char namebuf[MPLAYER_NAME_MAX] = {0};		// buffer for player's name
   7009 	int playertabs[] = {77 *RESFACTOR};				// tabs for player list box
   7010 	int optiontabs[] = {8};					// tabs for player list box
   7011 	int game_index = -1;						// index of currently-selected game
   7012 	int join_index = -1;						// index of game we're joining
   7013 	int rc = 0;									// -1 = user cancelled, 1 = New
   7014 	JoinEventType event;						// event from incoming packet
   7015 	int i;										// loop counter
   7016 	int parms_received = 0;					// 1 = game options received
   7017 	NodeNameType *who;						// node to add to Players
   7018 	RejectType why;							// reason for rejection
   7019 	TTimerClass<SystemTimerClass> lastclick_timer;			// time b/w send periods
   7020 	int lastclick_idx = 0;					// index of item last clicked on
   7021 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   7022 	int ready_to_go = 0;
   7023 	Session.Options.ScenarioDescription[0] = 0;	//Flag that we dont know the scenario name yet
   7024 	int	width;
   7025 	int	height;
   7026 
   7027 	//PG_TO_FIX
   7028 	//Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW);
   7029 	Format_Window_String((char*)TXT_HACKHACK, SeenBuff.Get_Height(), width, height);
   7030 	char * item;
   7031 	unsigned long starttime;
   7032 	int load_game = 0;						// 1 = load saved game
   7033 
   7034 	//------------------------------------------------------------------------
   7035 	//	Buttons
   7036 	//------------------------------------------------------------------------
   7037 	GadgetClass *commands;										// button list
   7038 
   7039 
   7040 	ListClass gamelist(BUTTON_GAMELIST, d_gamelist_x, d_gamelist_y, d_gamelist_w, d_gamelist_h,
   7041 		TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   7042 
   7043 	ColorListClass playerlist(BUTTON_PLAYERLIST, d_playerlist_x, d_playerlist_y, d_playerlist_w, d_playerlist_h,
   7044 		TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
   7045 
   7046 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
   7047 //#if (GERMAN | FRENCH)
   7048 //		d_cancel_x, d_cancel_y);
   7049 //#else
   7050 		d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
   7051 //#endif
   7052 
   7053 	//------------------------------------------------------------------------
   7054 	//	Init the button states
   7055 	//------------------------------------------------------------------------
   7056 	//........................................................................
   7057 	// Name & Color
   7058 	//........................................................................
   7059 	Session.ColorIdx = Session.PrefColor;			// init my preferred color
   7060 	strcpy (namebuf, Session.Handle);				// set my name
   7061 
   7062 	//........................................................................
   7063 	// List boxes
   7064 	//........................................................................
   7065 	playerlist.Set_Tabs(playertabs);
   7066 	playerlist.Set_Selected_Style(ColorListClass::SELECT_NORMAL);
   7067 
   7068 	Fancy_Text_Print("", 0, 0, scheme, TBLACK,
   7069 		TPF_CENTER | TPF_TEXT);
   7070 
   7071 	lastclick_timer = 0;
   7072 
   7073 	//------------------------------------------------------------------------
   7074 	//	Clear the list of games, players, and the chat list
   7075 	//------------------------------------------------------------------------
   7076 	Clear_Vector(&Session.Games);
   7077 	Clear_Vector(&Session.Players);
   7078 	Clear_Vector(&Session.Chat);
   7079 
   7080 	//------------------------------------------------------------------------
   7081 	// Add myself to the Chat vector
   7082 	//------------------------------------------------------------------------
   7083 	who = new NodeNameType;
   7084 	strcpy(who->Name, namebuf);
   7085 	who->Chat.LastTime = 0;
   7086 	who->Chat.LastChance = 0;
   7087 	who->Chat.Color = Session.GPacket.Chat.Color;
   7088 	Session.Chat.Add (who);
   7089 
   7090 	//------------------------------------------------------------------------
   7091 	// Create the "Lobby" game name on the games list, and create a bogus
   7092 	// node for the gamelist, so Games[i] will always match gamelist[i]
   7093 	//------------------------------------------------------------------------
   7094 	who = new NodeNameType;
   7095 	strcpy(who->Name, "");
   7096 	who->Game.IsOpen = 0;
   7097 	who->Game.LastTime = 0;
   7098 	Session.Games.Add (who);
   7099 	item = new char [MPLAYER_NAME_MAX];
   7100 	strcpy(item, Text_String(TXT_LOBBY));
   7101 	gamelist.Add_Item(item);
   7102 	gamelist.Set_Selected_Index(0);
   7103 	game_index = 0;
   7104 
   7105 	//------------------------------------------------------------------------
   7106 	//	Send game-name query & chat announcement; also, initialize timers.
   7107 	//------------------------------------------------------------------------
   7108 	Send_Join_Queries (game_index, joinstate, 1, 0, 1, namebuf, 1);
   7109 
   7110 	/*
   7111 	** Process the message loop until we are in focus.
   7112 	*/
   7113 	CDTimerClass<SystemTimerClass> focus_timer;		// Timer to allow a wait after client joins
   7114 	focus_timer = 5*60;
   7115 
   7116 	WWDebugString ("RA95 - About to enter wait for focus loop.\n");
   7117 	SetForegroundWindow ( MainWindow );
   7118 	ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
   7119 
   7120 	if (!GameInFocus) {
   7121 		do {
   7122 			Keyboard->Check();
   7123 			if (!focus_timer){
   7124 				WWDebugString ("RA95 - Calling SetForgroundWindow.\n");
   7125 				SetForegroundWindow ( MainWindow );
   7126 				WWDebugString ("RA95 - Calling ShowWindow.\n");
   7127 				ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
   7128 				focus_timer = 5*60;
   7129 			}
   7130 		}while (!GameInFocus);
   7131 		AllSurfaces.SurfacesRestored=FALSE;
   7132 	}
   7133 
   7134 	if (LogicPage != &SeenBuff && LogicPage!= &HidPage) {
   7135 		Set_Logic_Page (SeenBuff);
   7136 	}
   7137 
   7138 	Load_Title_Page(true);
   7139 	CCPalette.Set();	//GamePalette.Set();
   7140 
   7141 	//------------------------------------------------------------------------
   7142 	//	Processing loop
   7143 	//------------------------------------------------------------------------
   7144 	while (process) {
   7145 
   7146 		#ifdef WIN32
   7147 		/*
   7148 		** If we have just received input focus again after running in the background then
   7149 		** we need to redraw.
   7150 		*/
   7151 		if (AllSurfaces.SurfacesRestored) {
   7152 			AllSurfaces.SurfacesRestored=FALSE;
   7153 			display = REDRAW_ALL;
   7154 		}
   7155 		#endif
   7156 		//.....................................................................
   7157 		//	Refresh display if needed
   7158 		//.....................................................................
   7159 		if (display) {
   7160 			Hide_Mouse();
   7161 
   7162 			//..................................................................
   7163 			//	Redraw backgound & dialog box
   7164 			//..................................................................
   7165 			if (display >= REDRAW_BACKGROUND) {
   7166 				Load_Title_Page(true);
   7167 				CCPalette.Set();	//GamePalette.Set();
   7168 				Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
   7169 
   7170 				//...............................................................
   7171 				//	Dialog & Field labels
   7172 				//...............................................................
   7173 				Fancy_Text_Print(TXT_HACKHACK, d_dialog_cx-width/2, d_dialog_y + 25*RESFACTOR, scheme, TBLACK, TPF_TEXT);
   7174 
   7175 				//...............................................................
   7176 				//	Rebuild the button list
   7177 				//...............................................................
   7178 				cancelbtn.Zap();
   7179 				gamelist.Zap();
   7180 				playerlist.Zap();
   7181 
   7182 				commands = &cancelbtn;
   7183 				gamelist.Add_Tail(*commands);
   7184 				playerlist.Add_Tail(*commands);
   7185 
   7186 			}
   7187 
   7188 			//..................................................................
   7189 			//	Redraw buttons
   7190 			//..................................................................
   7191 			if (display >= REDRAW_BUTTONS) {
   7192 				commands->Draw_All();
   7193 			}
   7194 
   7195 			Show_Mouse();
   7196 			display = REDRAW_NONE;
   7197 		}
   7198 
   7199 		//.....................................................................
   7200 		//	Get user input
   7201 		//.....................................................................
   7202 		input = commands->Input();
   7203 
   7204 		//.....................................................................
   7205 		//	Process input
   7206 		//.....................................................................
   7207 		switch (input) {
   7208 
   7209 			//..................................................................
   7210 			// ESC / CANCEL: send a SIGN_OFF
   7211 			// - If we're part of a game, stay in this dialog; otherwise, exit
   7212 			//..................................................................
   7213 			case (KN_ESC):
   7214 			case (BUTTON_CANCEL | KN_BUTTON):
   7215 				//...............................................................
   7216 				//	If we're joined to a game, make extra sure the other players in
   7217 				//	that game know I'm exiting; send my SIGN_OFF as an ack-required
   7218 				//	packet.  Don't send this to myself (index 0).
   7219 				//...............................................................
   7220 				if (joinstate == JOIN_CONFIRMED) {
   7221 					Unjoin_Game(namebuf, joinstate, &gamelist, &playerlist,
   7222 						game_index, 1, 0, 0, d_txt6_h, 0,
   7223 						0, MAX_MESSAGE_LENGTH);
   7224 					joinstate = JOIN_NOTHING;
   7225 					display = REDRAW_ALL;
   7226 				}
   7227 				//...............................................................
   7228 				// If I'm not joined to a game, send a SIGN_OFF to all players
   7229 				// in my Chat vector (but not to myself, index 0)
   7230 				//...............................................................
   7231 				else {
   7232 					memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   7233 					Session.GPacket.Command = NET_SIGN_OFF;
   7234 					strcpy(Session.GPacket.Name,namebuf);
   7235 					for (i = 1; i < Session.Chat.Count(); i++) {
   7236 						Ipx.Send_Global_Message (&Session.GPacket,
   7237 							sizeof(GlobalPacketType),
   7238 							1, &(Session.Chat[i]->Address));
   7239 						Ipx.Service();
   7240 					}
   7241 
   7242 					//............................................................
   7243 					//	Now broadcast a SIGN_OFF just to be thorough
   7244 					//............................................................
   7245 					Ipx.Send_Global_Message (&Session.GPacket,
   7246 						sizeof (GlobalPacketType), 0, NULL);
   7247 					if (Session.IsBridge) {
   7248 						Ipx.Send_Global_Message (&Session.GPacket,
   7249 							sizeof(GlobalPacketType), 0, &Session.BridgeNet);
   7250 					}
   7251 
   7252 					while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   7253 
   7254 					//............................................................
   7255 					// exit the dialog
   7256 					//............................................................
   7257 					Send_Data_To_DDE_Server ("Hello", strlen("Hello"), DDEServerClass::DDE_CONNECTION_FAILED);
   7258 					GameStatisticsPacketSent = false;
   7259 					Spawn_WChat(false);
   7260 					process = false;
   7261 					rc = -1;
   7262 				}
   7263 				break;
   7264 
   7265 
   7266 			//..................................................................
   7267 			//	JOIN: send a join request packet & switch to waiting-for-
   7268 			// confirmation mode.
   7269 			//..................................................................
   7270 			default:
   7271 				if (joinstate == JOIN_NOTHING && gamelist.Count() >1 ) {
   7272 					gamelist.Set_Selected_Index(1);	//lastclick_idx);
   7273 					game_index = 1;
   7274 					strcpy (Session.Handle,namebuf);
   7275 					//Session.House = (HousesType)housebtn.Current_Index();
   7276 					join_index = gamelist.Current_Index();
   7277 					parms_received = 0;
   7278 					if (Request_To_Join (namebuf, join_index, Session.House,
   7279 						Session.ColorIdx)) {
   7280 						joinstate = JOIN_WAIT_CONFIRM;
   7281 					} else {
   7282 						display = REDRAW_ALL;
   7283 					}
   7284 				}
   7285 				break;
   7286 
   7287 		}
   7288 
   7289 		//.....................................................................
   7290 		//	Resend our query packets
   7291 		//.....................................................................
   7292 		Send_Join_Queries(game_index, joinstate, 0, 0, 0, namebuf);
   7293 
   7294 		//.....................................................................
   7295 		//	Process incoming packets
   7296 		//.....................................................................
   7297 		event = Get_Join_Responses(&joinstate, &gamelist, &playerlist,
   7298 			join_index, namebuf, &why);
   7299 
   7300 		//.....................................................................
   7301 		//	If we've changed state, redraw everything; if we're starting the game,
   7302 		//	break out of the loop.  If we've just joined, send out a player query
   7303 		//	so I'll get added to the list instantly.
   7304 		//.....................................................................
   7305 		if (event == EV_STATE_CHANGE) {
   7306 			display = REDRAW_ALL;
   7307 			if (joinstate==JOIN_GAME_START || joinstate == JOIN_GAME_START_LOAD) {
   7308 				if (joinstate==JOIN_GAME_START_LOAD) load_game = 1;
   7309 
   7310 				bool ready_packet_was_sent = false;
   7311 
   7312 				if (!load_game){
   7313 					/*
   7314 					** Special new kludge for counterstrike.
   7315 					**
   7316 					** Find local scenario will fail to match a counterstrike mission
   7317 					** unless the CS CD is in the drive. So....
   7318 					**
   7319 					** If Counterstrike is installed and this is an official map and
   7320 					** the file name matches a counterstrike map then tell the host
   7321 					** that I have the scenario so he can continue while we make
   7322 					** sure the local user has the Counterstrike CD in the drive.
   7323 					**
   7324 					*/
   7325 					//	This is duplicated for Aftermath scenarios. ajw
   7326 
   7327 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   7328 				if (Session.ScenarioIsOfficial &&
   7329 					( (Expansion_CS_Present() && Is_Mission_Counterstrike(Session.ScenarioFileName)) ||
   7330 					  (Expansion_AM_Present() && Is_Mission_Aftermath(Session.ScenarioFileName)) ) ) {
   7331 #else
   7332 					if ( Expansion_CS_Present() && Session.ScenarioIsOfficial ) {
   7333 #endif
   7334 
   7335 						CCFileClass check_file ( Session.ScenarioFileName );
   7336 						if ( !check_file.Is_Available() ) {
   7337 
   7338 							int current_drive = CCFileClass::Get_CD_Drive();
   7339 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   7340 							int index = Get_CD_Index(current_drive, 1*60);
   7341 							bool needcd = false;
   7342 							if (Is_Mission_Counterstrike(Session.ScenarioFileName)) {
   7343 								if (index != 2 && index != 3) {
   7344 									RequiredCD = 2;
   7345 									needcd = true;
   7346 								}
   7347 							}
   7348 							if (Is_Mission_Aftermath(Session.ScenarioFileName)) {
   7349 								if (index != 3) {
   7350 									RequiredCD = 3;
   7351 									needcd = true;
   7352 								}
   7353 							}
   7354 							if (needcd) {
   7355 #else
   7356 							if ( Get_CD_Index(current_drive, 1*60) != 2 ){
   7357 								RequiredCD = 2;
   7358 #endif
   7359 
   7360 								/*
   7361 								** We should have the scenario but the wrong disk is in.
   7362 								** Tell the host that I am ready to go anyway.
   7363 								*/
   7364 								memset ((void*)&(Session.GPacket), 0, sizeof (Session.GPacket));
   7365 								Session.GPacket.Command = NET_READY_TO_GO;
   7366 								Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   7367 									1, &Session.HostAddress);
   7368 								while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0);
   7369 								ready_packet_was_sent = true;
   7370 
   7371 								if (!Force_CD_Available (RequiredCD)){
   7372 									Emergency_Exit(EXIT_FAILURE);
   7373 								}
   7374 
   7375 								CCFileClass testfile ( Session.ScenarioFileName );
   7376 
   7377 								/*
   7378 								** Update the internal list of scenarios to include the counterstrike
   7379 								** list.
   7380 								*/
   7381 								Session.Read_Scenario_Descriptions();
   7382 
   7383 								/*
   7384 								** See if that scenario is available now. Its pretty fatal if it isnt.
   7385 								*/
   7386 								Session.Options.ScenarioIndex = -1;
   7387 								for (i = 0; i < Session.Scenarios.Count(); i++) {
   7388 									if (!strcmp (Session.Scenarios[i]->Description(), Session.Options.ScenarioDescription) ){
   7389 										Session.Options.ScenarioIndex = i;
   7390 										break;
   7391 									}
   7392 								}
   7393 							}
   7394 						}
   7395 					}
   7396 
   7397 
   7398 					/*
   7399 					** If the scenario that the host wants to play doesnt exist locally then we
   7400 					**	need to request that it is sent. If we can identify the scenario locally then
   7401 					**	we need to fix up the file name so we load the right one.
   7402 					*/
   7403 					if (Find_Local_Scenario (Session.Options.ScenarioDescription,
   7404 													Session.ScenarioFileName,
   7405 													Session.ScenarioFileLength,
   7406 													Session.ScenarioDigest,
   7407 					 								Session.ScenarioIsOfficial)) {
   7408 
   7409 						Session.Options.ScenarioIndex = 1;		//We dont care what it
   7410 																			//is as long as it isnt -1
   7411 
   7412 						/*
   7413 						** We have the scenario. Tell the host that I am ready to go.
   7414 						*/
   7415 						if ( !ready_packet_was_sent ){
   7416 							memset ((void*)&(Session.GPacket), 0, sizeof (Session.GPacket));
   7417 							Session.GPacket.Command = NET_READY_TO_GO;
   7418 							Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   7419 								1, &Session.HostAddress);
   7420 							while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0);
   7421 						}
   7422 					} else {
   7423 #ifndef FIXIT_VERSION_3			//	Removed restriction on downloading official maps.
   7424 						/*
   7425 						** Oh dear. Thats a scenario I dont have. Request that the host sends the
   7426 						**	scenario to me provided its not an official Westwood scenario.
   7427 						**
   7428 						** If the file is received OK then we will get a true return value and the
   7429 						** actual file name to load will be in Session.ScenarioFileName
   7430 						*/
   7431 						if (Session.ScenarioIsOfficial) {
   7432 							Session.Options.ScenarioIndex = -1;
   7433 						} else {
   7434 #endif
   7435 							Session.Options.ScenarioIndex = 1;		//We dont care what it
   7436 																				//is as long as it isnt -1
   7437 #ifdef FIXIT_VERSION_3
   7438 							if( bSpecialAftermathScenario( Session.Options.ScenarioDescription ) )
   7439 								break;
   7440 #endif
   7441 
   7442 							if (!Get_Scenario_File_From_Host(Session.ScenarioFileName, 1)) {
   7443 								break;
   7444 							} else {
   7445 								/*
   7446 								** Make sure we dont time-out because of the download
   7447 								*/
   7448 							}
   7449 #ifndef FIXIT_VERSION_3
   7450 						}
   7451 #endif
   7452 					}
   7453 				}else{
   7454 					/*
   7455 					** Make sure we respond to the host in a load game
   7456 					*/
   7457 					memset ((void*)&(Session.GPacket), 0, sizeof (Session.GPacket));
   7458 					Session.GPacket.Command = NET_READY_TO_GO;
   7459 					Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   7460 						1, &Session.HostAddress);
   7461 					while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0);
   7462 				}
   7463 
   7464 				strcpy (Scen.ScenarioName, Session.ScenarioFileName);
   7465 
   7466 				rc = 0;
   7467 				process = false;
   7468 			}
   7469 
   7470 			//..................................................................
   7471 			//	If we're newly-confirmed, add myself to the Players list, and
   7472 			// immediately send out a player query
   7473 			//..................................................................
   7474 			else if (joinstate==JOIN_CONFIRMED) {
   7475 				//...............................................................
   7476 				//	Clear the player list, then add myself to the list.
   7477 				//...............................................................
   7478 				Clear_Listbox(&playerlist);
   7479 				Clear_Vector (&Session.Players);
   7480 
   7481 				item = new char [MPLAYER_NAME_MAX + 12];
   7482 #ifdef OLDWAY
   7483 				if (Session.House==HOUSE_GOOD) {
   7484 					sprintf(item,"%s\t%s",namebuf, Text_String(TXT_ALLIES));
   7485 				} else {
   7486 					sprintf(item,"%s\t%s",namebuf, Text_String(TXT_SOVIET));
   7487 				}
   7488 #else	//OLDWAY
   7489 				sprintf (item, "%s\t%s", namebuf, Text_String(HouseTypeClass::As_Reference(Session.House).Full_Name()));
   7490 #endif	//OLDWAY
   7491 				playerlist.Add_Item(item,
   7492 					(Session.ColorIdx == PCOLOR_DIALOG_BLUE) ? &ColorRemaps[PCOLOR_REALLY_BLUE] : &ColorRemaps[Session.ColorIdx]);
   7493 
   7494 				who = new NodeNameType;
   7495 				strcpy(who->Name, namebuf);
   7496 				who->Player.House = Session.House;
   7497 				who->Player.Color = Session.ColorIdx;
   7498 				Session.Players.Add (who);
   7499 
   7500 				Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   7501 #if (0)
   7502 				//...............................................................
   7503 				// Re-init the message system to its new smaller size
   7504 				//...............................................................
   7505 				Session.Messages.Init (0,0, 8,
   7506 					MAX_MESSAGE_LENGTH, d_txt6_h, 0, 0, 1,
   7507 					20, MAX_MESSAGE_LENGTH - 5);
   7508 				Session.Messages.Add_Edit(Session.ColorIdx, TPF_TEXT | TPF_BRIGHT_COLOR, NULL, '_');
   7509 #endif	//(0)
   7510 			}
   7511 
   7512 			//..................................................................
   7513 			//	If we've been rejected, clear any messages we may have been
   7514 			// typing, add a message stating why we were rejected, and send a
   7515 			// chat announcement.
   7516 			//..................................................................
   7517 			else if (joinstate==JOIN_REJECTED) {
   7518 				Sound_Effect(VOC_SYS_ERROR);
   7519 				Send_Join_Queries (game_index, joinstate, 0, 0, 1, namebuf);
   7520 
   7521 			}
   7522 		}	// end of state change
   7523 
   7524 		//.....................................................................
   7525 		//	If the game options have changed, print them.
   7526 		//.....................................................................
   7527 		else if (event == EV_GAME_OPTIONS) {
   7528 
   7529 			Sound_Effect(VOC_OPTIONS_CHANGED);
   7530 
   7531 			parms_received = 1;
   7532 			display = REDRAW_PARMS;
   7533 		}
   7534 
   7535 
   7536 		//.....................................................................
   7537 		// EV_GAME_SIGNOFF:
   7538 		//	A game before the one I've selected is gone, so we have a new index
   7539 		// now. 'game_index' must be kept set to the currently-selected list
   7540 		// item, so we send out queries for the currently-selected game.  It's
   7541 		// therefore imperative that we detect any changes to the game list.
   7542 		// If we're joined in a game, we must decrement our game_index to keep
   7543 		// it aligned with the game we're joined to.
   7544 		//.....................................................................
   7545 		else if (event == EV_GAME_SIGNOFF) {
   7546 			if (joinstate==JOIN_CONFIRMED) {
   7547 				game_index--;
   7548 				join_index--;
   7549 				gamelist.Set_Selected_Index(join_index);
   7550 			}
   7551 			else {
   7552 				gamelist.Flag_To_Redraw();
   7553 				Clear_Listbox(&playerlist);
   7554 				Clear_Vector (&Session.Players);
   7555 				game_index = gamelist.Current_Index();
   7556 				Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   7557 			}
   7558 		}
   7559 
   7560 		//.....................................................................
   7561 		//	Service the Ipx connections
   7562 		//.....................................................................
   7563 		Ipx.Service();
   7564 
   7565 		if (process) {
   7566 			//.....................................................................
   7567 			//	Clean out the Game List; if an old entry is found:
   7568 			//	- Remove it
   7569 			//	- Clear the player list
   7570 			//	- Send queries for the new selected game, if there is one
   7571 			//.....................................................................
   7572 			for (i = 1; i < Session.Games.Count(); i++) {
   7573 				if (TickCount - Session.Games[i]->Game.LastTime > 400) {
   7574 
   7575 					delete Session.Games[i];
   7576 					Session.Games.Delete(Session.Games[i]);
   7577 
   7578 					item = (char *)(gamelist.Get_Item (i));
   7579 					gamelist.Remove_Item (item);
   7580 					delete [] item;
   7581 
   7582 					if (i <= game_index) {
   7583 						if (joinstate==JOIN_CONFIRMED) {
   7584 							game_index--;
   7585 							join_index--;
   7586 							gamelist.Set_Selected_Index(join_index);
   7587 						}
   7588 						else {
   7589 							gamelist.Flag_To_Redraw();
   7590 							Clear_Listbox(&playerlist);
   7591 							Clear_Vector (&Session.Players);
   7592 							game_index = gamelist.Current_Index();
   7593 							Send_Join_Queries (game_index, joinstate, 0, 1, 0, namebuf);
   7594 						}
   7595 					}
   7596 				}
   7597 			}
   7598 		}
   7599 
   7600 #if (0)
   7601 		/*
   7602 		** If we were flagged to start the game and we recognise both players then quit the loop
   7603 		*/
   7604 		if (ready_to_go && Session.Players.Count() == 2) {
   7605 			rc = 0;
   7606 			process = false;
   7607 		}
   7608 #endif	//(0)
   7609 
   7610 		//.....................................................................
   7611 		//	Service the sounds & score; GameActive must be false at this point,
   7612 		//	so Call_Back() doesn't intercept global messages from me!
   7613 		//.....................................................................
   7614 		Call_Back();
   7615 
   7616 	}	// end of while
   7617 
   7618 
   7619 	//------------------------------------------------------------------------
   7620 	//	Establish connections with all other players.
   7621 	//------------------------------------------------------------------------
   7622 	if (rc == 0) {
   7623 		//.....................................................................
   7624 		//	If the other guys are playing a scenario I don't have (sniff), I can't
   7625 		//	play.  Try to bail gracefully.
   7626 		//.....................................................................
   7627 		if (Session.Options.ScenarioIndex==-1) {
   7628 			WWMessageBox().Process (TXT_UNABLE_PLAY_WAAUGH);
   7629 
   7630 			memset (&Session.GPacket, 0, sizeof(GlobalPacketType));
   7631 
   7632 			Session.GPacket.Command = NET_SIGN_OFF;
   7633 			strcpy (Session.GPacket.Name, namebuf);
   7634 
   7635 			//..................................................................
   7636 			// Don't send myself the message.
   7637 			//..................................................................
   7638 			for (i = 1; i < Session.Players.Count(); i++) {
   7639 				Ipx.Send_Global_Message (&Session.GPacket,
   7640 					sizeof(GlobalPacketType), 1,
   7641 					&(Session.Players[i]->Address));
   7642 				Ipx.Service();
   7643 			}
   7644 
   7645 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   7646 				0, NULL);
   7647 			Ipx.Send_Global_Message (&Session.GPacket, sizeof (GlobalPacketType),
   7648 				0, NULL);
   7649 
   7650 			if (Session.IsBridge) {
   7651 				Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType),
   7652 					0, &Session.BridgeNet);
   7653 				Ipx.Send_Global_Message (&Session.GPacket, sizeof(GlobalPacketType),
   7654 					0, &Session.BridgeNet);
   7655 			}
   7656 
   7657 			while (Ipx.Global_Num_Send() > 0 && Ipx.Service() != 0) ;
   7658 
   7659 			rc = -1;
   7660 
   7661 		}
   7662 		//---------------------------------------------------------------------
   7663 		// Prepare to load the scenario.
   7664 		//---------------------------------------------------------------------
   7665 		else {
   7666 			//..................................................................
   7667 			//	Set the number of players in this game, and the scenario number.
   7668 			//..................................................................
   7669 			Session.NumPlayers = Session.Players.Count();
   7670 ///*
   7671 //**	Hack to fake a scenario name as if it had been sent over the connection.
   7672 //*/
   7673 //sprintf(Scen.ScenarioName, "SCM%02dEA.INI", Session.Options.ScenarioIndex+1);
   7674 
   7675 //			Scen.Scenario = Session.Options.ScenarioIndex;
   7676 		}
   7677 
   7678 		//.....................................................................
   7679 		//	Wait a while, polling the IPX service routines, to give our ACK
   7680 		//	a chance to get to the other system.  If he doesn't get our ACK,
   7681 		// he'll be waiting the whole time we load MIX files.
   7682 		//.....................................................................
   7683 		i = MAX((int)Ipx.Global_Response_Time() * 2, 60*2);
   7684 		starttime = TickCount;
   7685 		while (TickCount - starttime < (unsigned)i) {
   7686 			Ipx.Service();
   7687 		}
   7688 	}
   7689 
   7690 	//------------------------------------------------------------------------
   7691 	//	Init network timing values, using previous response times as a measure
   7692 	//	of what our retry delta & timeout should be.
   7693 	//------------------------------------------------------------------------
   7694 	//Ipx.Set_Timing (Ipx.Global_Response_Time() + 2, -1,
   7695 	//	Ipx.Global_Response_Time() * 4);
   7696 	Ipx.Set_Timing (Ipx.Global_Response_Time () + 2, (unsigned long) -1, max (120, Ipx.Global_Response_Time () * 8));
   7697 
   7698 	//------------------------------------------------------------------------
   7699 	//	Clear all lists, but NOT the Games & Players vectors.
   7700 	//------------------------------------------------------------------------
   7701 	Clear_Listbox(&gamelist);
   7702 	Clear_Listbox(&playerlist);
   7703 
   7704 	//------------------------------------------------------------------------
   7705 	//	Restore screen
   7706 	//------------------------------------------------------------------------
   7707 	Hide_Mouse();
   7708 	Load_Title_Page(true);
   7709 	Show_Mouse();
   7710 	//------------------------------------------------------------------------
   7711 	// Load a game if the game owner told us to
   7712 	//------------------------------------------------------------------------
   7713 	if (load_game) {
   7714 		if (!Load_Game (-1)) {
   7715 			WWMessageBox().Process (TXT_ERROR_LOADING_GAME);
   7716 			rc = -1;
   7717 		}
   7718 		Frame++;
   7719 	}
   7720 
   7721 	//------------------------------------------------------------------------
   7722 	// Clear the Players & Games vectors if we're not joined to a game.
   7723 	// Clear the Chat vector regardless.
   7724 	//------------------------------------------------------------------------
   7725 	if (rc != 0) {
   7726 		Clear_Vector(&Session.Games);
   7727 		Clear_Vector(&Session.Players);
   7728 	}
   7729 	Clear_Vector(&Session.Chat);
   7730 
   7731 	return(rc);
   7732 
   7733 #else	//WIN32
   7734 
   7735 	return (0);
   7736 
   7737 #endif	//WIN32
   7738 
   7739 }	/* end of Net_Join_Dialog */
   7740 
   7741 
   7742 
   7743 
   7744 
   7745 
   7746 
   7747 
   7748 
   7749 
   7750 bool Server_Remote_Connect(void)
   7751 {
   7752 	int stealth;				// original state of Session.NetStealth flag
   7753 
   7754 	//------------------------------------------------------------------------
   7755 	//	Init network timing parameters; these values should work for both a
   7756 	// "real" network, and a simulated modem network (ie Kali)
   7757 	//------------------------------------------------------------------------
   7758 	Ipx.Set_Timing (	30, 		// retry 2 times per second
   7759 							-1, 		// ignore max retries
   7760 							600);		// give up after 10 seconds
   7761 
   7762 	//------------------------------------------------------------------------
   7763 	//	Save the original value of the NetStealth flag, so we can turn stealth
   7764 	//	off for now (during this portion of the dialogs, we must show ourselves)
   7765 	//------------------------------------------------------------------------
   7766 	stealth = Session.NetStealth;
   7767 	Session.NetStealth = 0;
   7768 
   7769 	//------------------------------------------------------------------------
   7770 	//	The game is now "open" for joining.  Close it as soon as we exit this
   7771 	//	routine.
   7772 	//------------------------------------------------------------------------
   7773 	Session.NetOpen = 1;
   7774 
   7775 	//------------------------------------------------------------------------
   7776 	//	Read in last multiplayer game settings from the .INI file
   7777 	//------------------------------------------------------------------------
   7778 	if (!Net_Fake_New_Dialog()) {
   7779 		Session.Write_MultiPlayer_Settings ();
   7780 		return (false);
   7781 	}
   7782 
   7783 	Session.NetOpen = 0;
   7784 	Session.NetStealth = stealth;
   7785 	Session.Write_MultiPlayer_Settings ();
   7786 	return (true);
   7787 
   7788 }	/* end of Server_Remote_Connect */
   7789 
   7790 
   7791 
   7792 
   7793 
   7794 
   7795 
   7796 bool Client_Remote_Connect(void)
   7797 {
   7798 	int rc;
   7799 	int stealth;				// original state of Session.NetStealth flag
   7800 
   7801 	//------------------------------------------------------------------------
   7802 	//	Init network timing parameters; these values should work for both a
   7803 	// "real" network, and a simulated modem network (ie Kali)
   7804 	//------------------------------------------------------------------------
   7805 	Ipx.Set_Timing (	30, 		// retry 2 times per second
   7806 							-1, 		// ignore max retries
   7807 							600);		// give up after 10 seconds
   7808 
   7809 	//------------------------------------------------------------------------
   7810 	//	Save the original value of the NetStealth flag, so we can turn stealth
   7811 	//	off for now (during this portion of the dialogs, we must show ourselves)
   7812 	//------------------------------------------------------------------------
   7813 	stealth = Session.NetStealth;
   7814 	Session.NetStealth = 0;
   7815 
   7816 	//------------------------------------------------------------------------
   7817 	//	The game is now "open" for joining.  Close it as soon as we exit this
   7818 	//	routine.
   7819 	//------------------------------------------------------------------------
   7820 	Session.NetOpen = 1;
   7821 
   7822 	//------------------------------------------------------------------------
   7823 	//	Read in last multiplayer game settings from the .INI file
   7824 	//------------------------------------------------------------------------
   7825 	rc = Net_Fake_Join_Dialog();
   7826 	Session.Write_MultiPlayer_Settings ();
   7827 
   7828 	Session.NetStealth = stealth;
   7829 	Session.NetOpen = 0;
   7830 
   7831 	if (rc == -1) {
   7832 		return(false);
   7833 	} else {
   7834 		return(true);
   7835 	}
   7836 
   7837 }	/* end of Client_Remote_Connect */
   7838 
   7839 
   7840 
   7841 /*************************** end of netdlg.cpp *****************************/
   7842 
   7843 #endif	//#ifndef WOLAPI_INTEGRATION
   7844 #endif