1 #include "selgame.h"
2 
3 #include "all.h"
4 #include "../3rdParty/Storm/Source/storm.h"
5 #include "config.h"
6 #include "DiabloUI/diabloui.h"
7 #include "DiabloUI/text.h"
8 #include "DiabloUI/dialogs.h"
9 #include "DiabloUI/selok.h"
10 #include "DiabloUI/selhero.h"
11 #include "options.h"
12 
13 namespace dvl {
14 
15 char selgame_Label[32];
16 char selgame_Ip[129] = "";
17 char selgame_Password[16] = "";
18 char selgame_Description[256];
19 bool selgame_enteringGame;
20 int selgame_selectedGame;
21 bool selgame_endMenu;
22 int *gdwPlayerId;
23 int nDifficulty;
24 int nTickRate;
25 int heroLevel;
26 
27 static _SNETPROGRAMDATA *m_client_info;
28 extern int provider;
29 
30 #define DESCRIPTION_WIDTH 205
31 
32 namespace {
33 
34 char title[32];
35 
36 std::vector<UiListItem *> vecSelGameDlgItems;
37 std::vector<UiItemBase *> vecSelGameDialog;
38 
39 } // namespace
40 
selgame_FreeVectors()41 void selgame_FreeVectors()
42 {
43 	for (std::size_t i = 0; i < vecSelGameDlgItems.size(); i++) {
44 		UiListItem *pUIItem = vecSelGameDlgItems[i];
45 		delete pUIItem;
46 	}
47 	vecSelGameDlgItems.clear();
48 
49 	for (std::size_t i = 0; i < vecSelGameDialog.size(); i++) {
50 		UiItemBase *pUIItem = vecSelGameDialog[i];
51 		delete pUIItem;
52 	}
53 	vecSelGameDialog.clear();
54 }
55 
selgame_Free()56 void selgame_Free()
57 {
58 	ArtBackground.Unload();
59 
60 	selgame_FreeVectors();
61 }
62 
selgame_GameSelection_Init()63 void selgame_GameSelection_Init()
64 {
65 	selgame_enteringGame = false;
66 	selgame_selectedGame = 0;
67 
68 	if (provider == SELCONN_LOOPBACK) {
69 		selgame_enteringGame = true;
70 		selgame_GameSelection_Select(0);
71 		return;
72 	}
73 
74 	strcpy(selgame_Ip, sgOptions.Network.szPreviousHost);
75 
76 	selgame_FreeVectors();
77 
78 	UiAddBackground(&vecSelGameDialog);
79 	UiAddLogo(&vecSelGameDialog);
80 
81 	SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
82 	vecSelGameDialog.push_back(new UiArtText("Client-Server (TCP)", rect1, UIS_CENTER | UIS_BIG));
83 
84 	SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 211), 205, 192 };
85 	vecSelGameDialog.push_back(new UiArtText("Description:", rect2, UIS_MED));
86 
87 	SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 256), DESCRIPTION_WIDTH, 192 };
88 	vecSelGameDialog.push_back(new UiArtText(selgame_Description, rect3));
89 
90 	SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 300), (Sint16)(UI_OFFSET_Y + 211), 295, 33 };
91 	vecSelGameDialog.push_back(new UiArtText("Select Action", rect4, UIS_CENTER | UIS_BIG));
92 
93 	vecSelGameDlgItems.push_back(new UiListItem("Create Game", 0));
94 	vecSelGameDlgItems.push_back(new UiListItem("Join Game", 1));
95 
96 	vecSelGameDialog.push_back(new UiList(vecSelGameDlgItems, PANEL_LEFT + 305, (UI_OFFSET_Y + 255), 285, 26, UIS_CENTER | UIS_MED | UIS_GOLD));
97 
98 	SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
99 	vecSelGameDialog.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect5, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
100 
101 	SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
102 	vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
103 
104 	UiInitList(vecSelGameDlgItems.size(), selgame_GameSelection_Focus, selgame_GameSelection_Select, selgame_GameSelection_Esc, vecSelGameDialog);
105 }
106 
selgame_GameSelection_Focus(int value)107 void selgame_GameSelection_Focus(int value)
108 {
109 	switch (vecSelGameDlgItems[value]->m_value) {
110 	case 0:
111 		strncpy(selgame_Description, "Create a new game with a difficulty setting of your choice.", sizeof(selgame_Description) - 1);
112 		break;
113 	case 1:
114 		strncpy(selgame_Description, "Enter an IP or a hostname and join a game already in progress at that address.", sizeof(selgame_Description) - 1);
115 		break;
116 	}
117 	WordWrapArtStr(selgame_Description, DESCRIPTION_WIDTH);
118 }
119 
120 /**
121  * @brief Load the current hero level from save file
122  * @param pInfo Hero info
123  * @return always true
124  */
UpdateHeroLevel(_uiheroinfo * pInfo)125 BOOL UpdateHeroLevel(_uiheroinfo *pInfo)
126 {
127 	if (strcasecmp(pInfo->name, gszHero) == 0)
128 		heroLevel = pInfo->level;
129 
130 	return true;
131 }
132 
selgame_GameSelection_Select(int value)133 void selgame_GameSelection_Select(int value)
134 {
135 	selgame_enteringGame = true;
136 	selgame_selectedGame = value;
137 
138 	gfnHeroInfo(UpdateHeroLevel);
139 
140 	selgame_FreeVectors();
141 
142 	UiAddBackground(&vecSelGameDialog);
143 	UiAddLogo(&vecSelGameDialog);
144 
145 	SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
146 	vecSelGameDialog.push_back(new UiArtText(title, rect1, UIS_CENTER | UIS_BIG));
147 
148 	SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 34), (Sint16)(UI_OFFSET_Y + 211), 205, 33 };
149 	vecSelGameDialog.push_back(new UiArtText(selgame_Label, rect2, UIS_CENTER | UIS_BIG));
150 
151 	SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 256), DESCRIPTION_WIDTH, 192 };
152 	vecSelGameDialog.push_back(new UiArtText(selgame_Description, rect3));
153 
154 	switch (value) {
155 	case 0: {
156 		strncpy(title, "Create Game", sizeof(title) - 1);
157 
158 		SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 211), 295, 35 };
159 		vecSelGameDialog.push_back(new UiArtText("Select Difficulty", rect4, UIS_CENTER | UIS_BIG));
160 
161 		vecSelGameDlgItems.push_back(new UiListItem("Normal", DIFF_NORMAL));
162 		vecSelGameDlgItems.push_back(new UiListItem("Nightmare", DIFF_NIGHTMARE));
163 		vecSelGameDlgItems.push_back(new UiListItem("Hell", DIFF_HELL));
164 
165 		vecSelGameDialog.push_back(new UiList(vecSelGameDlgItems, PANEL_LEFT + 300, (UI_OFFSET_Y + 282), 295, 26, UIS_CENTER | UIS_MED | UIS_GOLD));
166 
167 		SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
168 		vecSelGameDialog.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect5, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
169 
170 		SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
171 		vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
172 
173 		UiInitList(vecSelGameDlgItems.size(), selgame_Diff_Focus, selgame_Diff_Select, selgame_Diff_Esc, vecSelGameDialog, true);
174 		break;
175 	}
176 	case 1: {
177 		strncpy(title, "Join TCP Games", sizeof(title) - 1);
178 
179 		SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 305), (Sint16)(UI_OFFSET_Y + 211), 285, 33 };
180 		vecSelGameDialog.push_back(new UiArtText("Enter address", rect4, UIS_CENTER | UIS_BIG));
181 
182 		SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 305), (Sint16)(UI_OFFSET_Y + 314), 285, 33 };
183 		vecSelGameDialog.push_back(new UiEdit(selgame_Ip, 128, rect5, UIS_MED | UIS_GOLD));
184 
185 		SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
186 		vecSelGameDialog.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
187 
188 		SDL_Rect rect7 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
189 		vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect7, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
190 
191 		UiInitList(0, NULL, selgame_Password_Init, selgame_GameSelection_Init, vecSelGameDialog);
192 		break;
193 	}
194 	}
195 }
196 
selgame_GameSelection_Esc()197 void selgame_GameSelection_Esc()
198 {
199 	UiInitList_clear();
200 	selgame_enteringGame = false;
201 	selgame_endMenu = true;
202 }
203 
selgame_Diff_Focus(int value)204 void selgame_Diff_Focus(int value)
205 {
206 	switch (vecSelGameDlgItems[value]->m_value) {
207 	case DIFF_NORMAL:
208 		strncpy(selgame_Label, "Normal", sizeof(selgame_Label) - 1);
209 		strncpy(selgame_Description, "Normal Difficulty\nThis is where a starting character should begin the quest to defeat Diablo.", sizeof(selgame_Description) - 1);
210 		break;
211 	case DIFF_NIGHTMARE:
212 		strncpy(selgame_Label, "Nightmare", sizeof(selgame_Label) - 1);
213 		strncpy(selgame_Description, "Nightmare Difficulty\nThe denizens of the Labyrinth have been bolstered and will prove to be a greater challenge. This is recommended for experienced characters only.", sizeof(selgame_Description) - 1);
214 		break;
215 	case DIFF_HELL:
216 		strncpy(selgame_Label, "Hell", sizeof(selgame_Label) - 1);
217 		strncpy(selgame_Description, "Hell Difficulty\nThe most powerful of the underworld's creatures lurk at the gateway into Hell. Only the most experienced characters should venture in this realm.", sizeof(selgame_Description) - 1);
218 		break;
219 	}
220 	WordWrapArtStr(selgame_Description, DESCRIPTION_WIDTH);
221 }
222 
IsDifficultyAllowed(int value)223 bool IsDifficultyAllowed(int value)
224 {
225 	if (value == 0 || (value == 1 && heroLevel >= 20) || (value == 2 && heroLevel >= 30)) {
226 		return true;
227 	}
228 
229 	selgame_Free();
230 
231 	if (value == 1)
232 		UiSelOkDialog(title, "Your character must reach level 20 before you can enter a multiplayer game of Nightmare difficulty.", false);
233 	if (value == 2)
234 		UiSelOkDialog(title, "Your character must reach level 30 before you can enter a multiplayer game of Hell difficulty.", false);
235 
236 	LoadBackgroundArt("ui_art\\selgame.pcx");
237 
238 	return false;
239 }
240 
selgame_Diff_Select(int value)241 void selgame_Diff_Select(int value)
242 {
243 	if (selhero_isMultiPlayer && !IsDifficultyAllowed(vecSelGameDlgItems[value]->m_value)) {
244 		selgame_GameSelection_Select(0);
245 		return;
246 	}
247 
248 	nDifficulty = value;
249 
250 	if (!selhero_isMultiPlayer) {
251 		// This is part of a dangerous hack to enable difficulty selection in single-player.
252 		// FIXME: Dialogs should not refer to each other's variables.
253 
254 		// We're in the selhero loop instead of the selgame one.
255 		// Free the selgame data and flag the end of the selhero loop.
256 		selhero_endMenu = true;
257 
258 		// We only call FreeVectors because ArtBackground.Unload()
259 		// will be called by selheroFree().
260 		selgame_FreeVectors();
261 
262 		// We must clear the InitList because selhero's loop will perform
263 		// one more iteration after this function exits.
264 		UiInitList_clear();
265 
266 		return;
267 	}
268 
269 	selgame_GameSpeedSelection();
270 }
271 
selgame_Diff_Esc()272 void selgame_Diff_Esc()
273 {
274 	if (!selhero_isMultiPlayer) {
275 		selgame_Free();
276 
277 		selhero_Init();
278 		selhero_List_Init();
279 		return;
280 	}
281 
282 	if (provider == SELCONN_LOOPBACK) {
283 		selgame_GameSelection_Esc();
284 		return;
285 	}
286 
287 	selgame_GameSelection_Init();
288 }
289 
selgame_GameSpeedSelection()290 void selgame_GameSpeedSelection()
291 {
292 	gfnHeroInfo(UpdateHeroLevel);
293 
294 	selgame_FreeVectors();
295 
296 	UiAddBackground(&vecSelGameDialog);
297 	UiAddLogo(&vecSelGameDialog);
298 
299 	SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
300 	vecSelGameDialog.push_back(new UiArtText("Create Game", rect1, UIS_CENTER | UIS_BIG));
301 
302 	SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 34), (Sint16)(UI_OFFSET_Y + 211), 205, 33 };
303 	vecSelGameDialog.push_back(new UiArtText(selgame_Label, rect2, UIS_CENTER | UIS_BIG));
304 
305 	SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 256), DESCRIPTION_WIDTH, 192 };
306 	vecSelGameDialog.push_back(new UiArtText(selgame_Description, rect3));
307 
308 	SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 211), 295, 35 };
309 	vecSelGameDialog.push_back(new UiArtText("Select Game Speed", rect4, UIS_CENTER | UIS_BIG));
310 
311 	vecSelGameDlgItems.push_back(new UiListItem("Normal", 20));
312 	vecSelGameDlgItems.push_back(new UiListItem("Fast", 30));
313 	vecSelGameDlgItems.push_back(new UiListItem("Faster", 40));
314 	vecSelGameDlgItems.push_back(new UiListItem("Fastest", 50));
315 
316 	vecSelGameDialog.push_back(new UiList(vecSelGameDlgItems, PANEL_LEFT + 300, (UI_OFFSET_Y + 279), 295, 26, UIS_CENTER | UIS_MED | UIS_GOLD));
317 
318 	SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
319 	vecSelGameDialog.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect5, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
320 
321 	SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
322 	vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
323 
324 	UiInitList(vecSelGameDlgItems.size(), selgame_Speed_Focus, selgame_Speed_Select, selgame_Speed_Esc, vecSelGameDialog, true);
325 }
326 
selgame_Speed_Focus(int value)327 void selgame_Speed_Focus(int value)
328 {
329 	switch (vecSelGameDlgItems[value]->m_value) {
330 	case 20:
331 		strncpy(selgame_Label, "Normal", sizeof(selgame_Label) - 1);
332 		strncpy(selgame_Description, "Normal Speed\nThis is where a starting character should begin the quest to defeat Diablo.", sizeof(selgame_Description) - 1);
333 		break;
334 	case 30:
335 		strncpy(selgame_Label, "Fast", sizeof(selgame_Label) - 1);
336 		strncpy(selgame_Description, "Fast Speed\nThe denizens of the Labyrinth have been hastened and will prove to be a greater challenge. This is recommended for experienced characters only.", sizeof(selgame_Description) - 1);
337 		break;
338 	case 40:
339 		strncpy(selgame_Label, "Faster", sizeof(selgame_Label) - 1);
340 		strncpy(selgame_Description, "Faster Speed\nMost monsters of the dungeon will seek you out quicker than ever before. Only an experienced champion should try their luck at this speed.", sizeof(selgame_Description) - 1);
341 		break;
342 	case 50:
343 		strncpy(selgame_Label, "Fastest", sizeof(selgame_Label) - 1);
344 		strncpy(selgame_Description, "Fastest Speed\nThe minions of the underworld will rush to attack without hesitation. Only a true speed demon should enter at this pace.", sizeof(selgame_Description) - 1);
345 		break;
346 	}
347 	WordWrapArtStr(selgame_Description, DESCRIPTION_WIDTH);
348 }
349 
selgame_Speed_Esc()350 void selgame_Speed_Esc()
351 {
352 	selgame_GameSelection_Select(0);
353 }
354 
selgame_Speed_Select(int value)355 void selgame_Speed_Select(int value)
356 {
357 	nTickRate = vecSelGameDlgItems[value]->m_value;
358 
359 	if (provider == SELCONN_LOOPBACK) {
360 		selgame_Password_Select(0);
361 		return;
362 	}
363 
364 	selgame_Password_Init(0);
365 }
366 
selgame_Password_Init(int value)367 void selgame_Password_Init(int value)
368 {
369 	memset(&selgame_Password, 0, sizeof(selgame_Password));
370 
371 	selgame_FreeVectors();
372 
373 	UiAddBackground(&vecSelGameDialog);
374 	UiAddLogo(&vecSelGameDialog);
375 
376 	SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
377 	vecSelGameDialog.push_back(new UiArtText("Client-Server (TCP)", rect1, UIS_CENTER | UIS_BIG));
378 
379 	SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 211), 205, 192 };
380 	vecSelGameDialog.push_back(new UiArtText("Description:", rect2, UIS_MED));
381 
382 	SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 256), DESCRIPTION_WIDTH, 192 };
383 	vecSelGameDialog.push_back(new UiArtText(selgame_Description, rect3));
384 
385 	SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 305), (Sint16)(UI_OFFSET_Y + 211), 285, 33 };
386 	vecSelGameDialog.push_back(new UiArtText("Enter Password", rect4, UIS_CENTER | UIS_BIG));
387 
388 	SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 305), (Sint16)(UI_OFFSET_Y + 314), 285, 33 };
389 	vecSelGameDialog.push_back(new UiEdit(selgame_Password, 15, rect5, UIS_MED | UIS_GOLD));
390 
391 	SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
392 	vecSelGameDialog.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
393 
394 	SDL_Rect rect7 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
395 	vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect7, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD));
396 
397 	UiInitList(0, NULL, selgame_Password_Select, selgame_Password_Esc, vecSelGameDialog);
398 }
399 
IsGameCompatible(GameData * data)400 static bool IsGameCompatible(GameData *data)
401 {
402 	if (data->versionMajor == PROJECT_VERSION_MAJOR
403 	    && data->versionMinor == PROJECT_VERSION_MINOR
404 	    && data->versionPatch == PROJECT_VERSION_PATCH
405 	    && data->programid == GAME_ID) {
406 		return IsDifficultyAllowed(data->nDifficulty);
407 	}
408 
409 	selgame_Free();
410 
411 	if (data->programid != GAME_ID) {
412 		UiSelOkDialog(title, "The host is running a different game than you.", false);
413 	} else {
414 		char msg[64];
415 		sprintf(msg, "Your version %s does not match the host %d.%d.%d.", PROJECT_VERSION, PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR, PROJECT_VERSION_PATCH);
416 
417 		UiSelOkDialog(title, msg, false);
418 	}
419 
420 	LoadBackgroundArt("ui_art\\selgame.pcx");
421 
422 	return false;
423 }
424 
selgame_Password_Select(int value)425 void selgame_Password_Select(int value)
426 {
427 	if (selgame_selectedGame) {
428 		strcpy(sgOptions.Network.szPreviousHost, selgame_Ip);
429 		if (SNetJoinGame(selgame_selectedGame, selgame_Ip, selgame_Password, NULL, NULL, gdwPlayerId)) {
430 			if (!IsGameCompatible(m_client_info->initdata)) {
431 				selgame_GameSelection_Select(1);
432 				return;
433 			}
434 
435 			UiInitList_clear();
436 			selgame_endMenu = true;
437 		} else {
438 			selgame_Free();
439 			UiSelOkDialog("Multi Player Game", SDL_GetError(), false);
440 			LoadBackgroundArt("ui_art\\selgame.pcx");
441 			selgame_Password_Init(selgame_selectedGame);
442 		}
443 		return;
444 	}
445 
446 	GameData *data = m_client_info->initdata;
447 	data->nDifficulty = nDifficulty;
448 	data->nTickRate = nTickRate;
449 	data->bRunInTown = sgOptions.Gameplay.bRunInTown;
450 	data->bTheoQuest = sgOptions.Gameplay.bTheoQuest;
451 	data->bCowQuest = sgOptions.Gameplay.bCowQuest;
452 
453 	if (SNetCreateGame(NULL, selgame_Password, NULL, 0, (char *)data, sizeof(GameData), MAX_PLRS, NULL, NULL, gdwPlayerId)) {
454 		UiInitList_clear();
455 		selgame_endMenu = true;
456 	} else {
457 		selgame_Free();
458 		UiSelOkDialog("Multi Player Game", SDL_GetError(), false);
459 		LoadBackgroundArt("ui_art\\selgame.pcx");
460 		selgame_Password_Init(0);
461 	}
462 }
463 
selgame_Password_Esc()464 void selgame_Password_Esc()
465 {
466 	if (selgame_selectedGame == 1)
467 		selgame_GameSelection_Select(1);
468 	else
469 		selgame_GameSpeedSelection();
470 }
471 
UiSelectGame(int a1,_SNETPROGRAMDATA * client_info,_SNETPLAYERDATA * user_info,_SNETUIDATA * ui_info,_SNETVERSIONDATA * file_info,int * playerId)472 int UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info,
473     _SNETVERSIONDATA *file_info, int *playerId)
474 {
475 	gdwPlayerId = playerId;
476 	m_client_info = client_info;
477 	LoadBackgroundArt("ui_art\\selgame.pcx");
478 	selgame_GameSelection_Init();
479 
480 	selgame_endMenu = false;
481 	while (!selgame_endMenu) {
482 		UiClearScreen();
483 		UiPollAndRender();
484 	}
485 	selgame_Free();
486 
487 	return selgame_enteringGame;
488 }
489 } // namespace dvl
490