network_gui.c
changeset 2888 79da960a5372
parent 2887 810e555d5249
child 2889 461c25e6cc1b
equal deleted inserted replaced
2887:810e555d5249 2888:79da960a5372
    26 #define BGC 5
    26 #define BGC 5
    27 #define BTC 15
    27 #define BTC 15
    28 #define MAX_QUERYSTR_LEN 64
    28 #define MAX_QUERYSTR_LEN 64
    29 
    29 
    30 typedef struct network_d {
    30 typedef struct network_d {
    31 	byte company;
    31 	byte company;            // select company in network lobby
    32 	byte field;
    32 	byte field;              // select text-field in start-server and game-listing
    33 	NetworkGameList *server;
    33 	NetworkGameList *server; // selected server in lobby and game-listing
    34 	FiosItem *map;
    34 	FiosItem *map;           // selected map in start-server
    35 } network_d;
    35 } network_d;
    36 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
    36 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
    37 
    37 
    38 typedef struct network_q_d {
    38 typedef struct network_ql_d {
    39 	network_d n;
    39 	network_d n;                 // see above; general stuff
    40 	querystr_d q;
    40 	querystr_d q;                // text-input in start-server and game-listing
    41 } network_q_d;
    41 	NetworkGameList **sort_list; // list of games (sorted)
    42 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_q_d));
    42 	list_d l;                    // accompanying list-administration
       
    43 } network_ql_d;
       
    44 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_ql_d));
       
    45 
       
    46 typedef struct NetworkGameSorting {
       
    47 	bool order;    // Ascending / Descending
       
    48 	byte criteria; // Sorted by name/clients/connectivity
       
    49 } NetworkGameSorting;
       
    50 
       
    51 /* Global to remember sorting after window has been closed */
       
    52 static NetworkGameSorting _ng_sorting;
    43 
    53 
    44 static char _edit_str_buf[MAX_QUERYSTR_LEN*2];
    54 static char _edit_str_buf[MAX_QUERYSTR_LEN*2];
    45 static void ShowNetworkStartServerWindow(void);
    55 static void ShowNetworkStartServerWindow(void);
    46 static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
    56 static void ShowNetworkLobbyWindow(NetworkGameList *ngl);
    47 
    57 
    90 void UpdateNetworkGameWindow(bool unselect)
   100 void UpdateNetworkGameWindow(bool unselect)
    91 {
   101 {
    92 	Window* w = FindWindowById(WC_NETWORK_WINDOW, 0);
   102 	Window* w = FindWindowById(WC_NETWORK_WINDOW, 0);
    93 
   103 
    94 	if (w != NULL) {
   104 	if (w != NULL) {
    95 		if (unselect) WP(w, network_q_d).n.server = NULL;
   105 		if (unselect) WP(w, network_ql_d).n.server = NULL;
    96 		SendWindowMessage(WC_NETWORK_WINDOW, 0, true, 0, 0);
   106 		SendWindowMessage(WC_NETWORK_WINDOW, 0, true, 0, 0);
    97 	}
   107 	}
    98 }
   108 }
    99 
   109 
   100 /* uses network_q_d (network_d and querystr_d) WP macro */
   110 static bool _internal_sort_order; // Used for Qsort order-flipping
       
   111 typedef int CDECL NGameNameSortFunction(const void*, const void*);
       
   112 
       
   113 /** Qsort function to sort by name. */
       
   114 static int CDECL NGameNameSorter(const void *a, const void *b)
       
   115 {
       
   116 	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
       
   117 	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
       
   118 	int r = stricmp(cmp1->info.server_name, cmp2->info.server_name);
       
   119 
       
   120 	return (_internal_sort_order & 1) ? -r : r;
       
   121 }
       
   122 
       
   123 /** Qsort function to sort by the amount of clients online on a
       
   124  * server. If the two servers have the same amount, the one with the
       
   125  * higher maximum is preferred. */
       
   126 static int CDECL NGameClientSorter(const void *a, const void *b)
       
   127 {
       
   128 	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
       
   129 	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
       
   130 	/* Reverse as per default we are interested in most-clients first */
       
   131 	int r = cmp2->info.clients_on - cmp1->info.clients_on;
       
   132 
       
   133 	if (r == 0) r = cmp1->info.clients_max - cmp2->info.clients_max;
       
   134 
       
   135 	return (_internal_sort_order & 1) ? -r : r;
       
   136 }
       
   137 
       
   138 /** Qsort function to sort by joinability. If both servers are the
       
   139  * same, prefer the non-passworded server first. */
       
   140 static int CDECL NGameAllowedSorter(const void *a, const void *b)
       
   141 {
       
   142 	const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
       
   143 	const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
       
   144 	/* Reverse default as we are interested in compatible clients first */
       
   145 	int r = cmp2->info.compatible - cmp1->info.compatible;
       
   146 
       
   147 	if (r == 0) r = cmp1->info.use_password - cmp2->info.use_password;
       
   148 
       
   149 	return (_internal_sort_order & 1) ? -r : r;
       
   150 }
       
   151 
       
   152 static NGameNameSortFunction* const _ngame_sorter[] = {
       
   153 	&NGameNameSorter,
       
   154 	&NGameClientSorter,
       
   155 	&NGameAllowedSorter
       
   156 };
       
   157 
       
   158 /** (Re)build the network game list as its amount has changed because
       
   159  * an item has been added or deleted for example
       
   160  * @param ngl list_d struct that contains all necessary information for sorting */
       
   161 static void BuildNetworkGameList(network_ql_d *nqld)
       
   162 {
       
   163 	NetworkGameList *ngl_temp;
       
   164 	uint n = 0;
       
   165 
       
   166 	if (!(nqld->l.flags & VL_REBUILD)) return;
       
   167 
       
   168 	/* Count the number of games in the list */
       
   169 	for (ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) n++;
       
   170 	if (n == 0) return;
       
   171 
       
   172 	/* Create temporary array of games to use for listing */
       
   173 	free(nqld->sort_list);
       
   174 	nqld->sort_list = malloc(n * sizeof(nqld->sort_list[0]));
       
   175 	if (nqld->sort_list == NULL) error("Could not allocate memory for the network-game-sorting-list");
       
   176 	nqld->l.list_length = n;
       
   177 
       
   178 	for (n = 0, ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) {
       
   179 		nqld->sort_list[n++] = ngl_temp;
       
   180 	}
       
   181 
       
   182 	/* Force resort */
       
   183 	nqld->l.flags &= ~VL_REBUILD;
       
   184 	nqld->l.flags |= VL_RESORT;
       
   185 }
       
   186 
       
   187 static void SortNetworkGameList(network_ql_d *nqld)
       
   188 {
       
   189 	NetworkGameList *item;
       
   190 	uint i;
       
   191 
       
   192 	if (!(nqld->l.flags & VL_RESORT)) return;
       
   193 
       
   194 	_internal_sort_order = nqld->l.flags & VL_DESC;
       
   195 	qsort(nqld->sort_list, nqld->l.list_length, sizeof(nqld->sort_list[0]), _ngame_sorter[nqld->l.sort_type]);
       
   196 
       
   197 	/* After sorting ngl->sort_list contains the sorted items. Put these back
       
   198 	 * into the original list. Basically nothing has changed, we are only
       
   199 	 * shuffling the ->next pointers */
       
   200 	_network_game_list = nqld->sort_list[0];
       
   201 	for (item = _network_game_list, i = 1; i != nqld->l.list_length; i++) {
       
   202 		item->next = nqld->sort_list[i];
       
   203 		item = item->next;
       
   204 	}
       
   205 	item->next = NULL;
       
   206 
       
   207 	nqld->l.flags &= ~VL_RESORT;
       
   208 }
       
   209 
       
   210 /* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
   101 static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
   211 static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
   102 {
   212 {
   103 	network_d *nd = &WP(w, network_q_d).n;
   213 	network_d *nd = &WP(w, network_ql_d).n;
       
   214 	list_d *ld = &WP(w, network_ql_d).l;
   104 
   215 
   105 	switch (e->event) {
   216 	switch (e->event) {
   106 	case WE_CREATE: /* focus input box */
   217 	case WE_CREATE: /* Focus input box */
   107 		nd->field = 3;
   218 		nd->field = 3;
   108 		nd->server = NULL;
   219 		nd->server = NULL;
       
   220 
       
   221 		WP(w, network_ql_d).sort_list = NULL;
       
   222 		ld->flags = VL_REBUILD | (_ng_sorting.order << (VL_DESC - 1));
       
   223 		ld->sort_type = _ng_sorting.criteria;
   109 		break;
   224 		break;
   110 
   225 
   111 	case WE_PAINT: {
   226 	case WE_PAINT: {
   112 		const NetworkGameList *sel = nd->server;
   227 		const NetworkGameList *sel = nd->server;
       
   228 		const char *arrow = (ld->flags & VL_DESC) ? DOWNARROW : UPARROW;
       
   229 
       
   230 		if (ld->flags & VL_REBUILD) {
       
   231 			BuildNetworkGameList(&WP(w, network_ql_d));
       
   232 			SetVScrollCount(w, ld->list_length);
       
   233 		}
       
   234 		if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
   113 
   235 
   114 		w->disabled_state = 0;
   236 		w->disabled_state = 0;
   115 
   237 
   116 		if (sel == NULL) {
   238 		if (sel == NULL) {
   117 			SETBIT(w->disabled_state, 16); SETBIT(w->disabled_state, 17);
   239 			SETBIT(w->disabled_state, 16); SETBIT(w->disabled_state, 17);
   126 
   248 
   127 		SetDParam(0, 0x00);
   249 		SetDParam(0, 0x00);
   128 		SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
   250 		SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
   129 		DrawWindowWidgets(w);
   251 		DrawWindowWidgets(w);
   130 
   252 
   131 		DrawEditBox(w, &WP(w, network_q_d).q, 3);
   253 		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
   132 
   254 
   133 		DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
   255 		DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
   134 		DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
   256 		DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
       
   257 
       
   258 		/* Sort based on widgets: name, clients, compatibility */
       
   259 		switch (ld->sort_type) {
       
   260 			case 6 - 6: DoDrawString(arrow, w->widget[6].right - 10, 42, 0x10); break;
       
   261 			case 7 - 6: DoDrawString(arrow, w->widget[7].right - 10, 42, 0x10); break;
       
   262 			case 8 - 6: DoDrawString(arrow, w->widget[8].right - 10, 42, 0x10); break;
       
   263 		}
   135 
   264 
   136 		{ // draw list of games
   265 		{ // draw list of games
   137 			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
   266 			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
   138 			int32 n = 0;
   267 			int32 n = 0;
   139 			int32 pos = w->vscroll.pos;
   268 			int32 pos = w->vscroll.pos;
   256 		case 0: case 14: /* Close 'X' | Cancel button */
   385 		case 0: case 14: /* Close 'X' | Cancel button */
   257 			DeleteWindowById(WC_NETWORK_WINDOW, 0);
   386 			DeleteWindowById(WC_NETWORK_WINDOW, 0);
   258 			break;
   387 			break;
   259 		case 4: case 5:
   388 		case 4: case 5:
   260 			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
   389 			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
       
   390 			break;
       
   391 		case 6: /* Sort by name */
       
   392 		case 7: /* Sort by connected clients */
       
   393 		case 8: /* Connectivity (green dot) */
       
   394 			if (ld->sort_type == e->click.widget - 6) ld->flags ^= VL_DESC;
       
   395 			ld->flags |= VL_RESORT;
       
   396 			ld->sort_type = e->click.widget - 6;
       
   397 
       
   398 			_ng_sorting.order = !!(ld->flags & VL_DESC);
       
   399 			_ng_sorting.criteria = ld->sort_type;
       
   400 			SetWindowDirty(w);
   261 			break;
   401 			break;
   262 		case 9: { /* Matrix to show networkgames */
   402 		case 9: { /* Matrix to show networkgames */
   263 			NetworkGameList *cur_item;
   403 			NetworkGameList *cur_item;
   264 			uint32 id_v = (e->click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
   404 			uint32 id_v = (e->click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
   265 
   405 
   296 				_network_last_port = nd->server->port;
   436 				_network_last_port = nd->server->port;
   297 				ShowNetworkLobbyWindow(nd->server);
   437 				ShowNetworkLobbyWindow(nd->server);
   298 			}
   438 			}
   299 			break;
   439 			break;
   300 		case 17: // Refresh
   440 		case 17: // Refresh
   301 			if (nd->server != NULL) {
   441 			if (nd->server != NULL)
   302 				NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
   442 				NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
   303 			}
       
   304 			break;
   443 			break;
   305 
   444 
   306 	}	break;
   445 	}	break;
   307 
   446 
   308 	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   447 	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   314 
   453 
   315 		SetWindowDirty(w);
   454 		SetWindowDirty(w);
   316 		break;
   455 		break;
   317 
   456 
   318 	case WE_MOUSELOOP:
   457 	case WE_MOUSELOOP:
   319 		if (nd->field == 3) HandleEditBox(w, &WP(w, network_q_d).q, 3);
   458 		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
   320 		break;
   459 		break;
   321 
   460 
   322 	case WE_MESSAGE: {
   461 	case WE_MESSAGE:
   323 		const NetworkGameList *nglist;
   462 		ld->flags |= VL_REBUILD;
   324 		w->vscroll.count = 0;
       
   325 		/* Game-count has changed, update scroll-count, scrollbar, and resort */
       
   326 		for (nglist = _network_game_list; nglist != NULL; nglist = nglist->next) w->vscroll.count++;
       
   327 		if (w->vscroll.count >= w->vscroll.cap && w->vscroll.pos > w->vscroll.count - w->vscroll.cap) w->vscroll.pos--;
       
   328 
       
   329 		SetWindowDirty(w);
   463 		SetWindowDirty(w);
   330 	}	break;
   464 		break;
   331 
   465 
   332 	case WE_KEYPRESS:
   466 	case WE_KEYPRESS:
   333 		if (nd->field != 3) {
   467 		if (nd->field != 3) {
   334 			if (nd->server != NULL) {
   468 			if (nd->server != NULL) {
   335 				if (e->keypress.keycode == WKC_DELETE) { /* Press 'delete' to remove servers */
   469 				if (e->keypress.keycode == WKC_DELETE) { /* Press 'delete' to remove servers */
   339 				}
   473 				}
   340 			}
   474 			}
   341 			break;
   475 			break;
   342 		}
   476 		}
   343 
   477 
   344 		if (HandleEditBoxKey(w, &WP(w, network_q_d).q, 3, e) == 1) break; // enter pressed
   478 		if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
   345 
   479 
   346 		// The name is only allowed when it starts with a letter!
   480 		// The name is only allowed when it starts with a letter!
   347 		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
   481 		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
   348 			ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
   482 			ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
   349 		} else {
   483 		} else {
   353 		break;
   487 		break;
   354 
   488 
   355 	case WE_ON_EDIT_TEXT:
   489 	case WE_ON_EDIT_TEXT:
   356 		NetworkAddServer(e->edittext.str);
   490 		NetworkAddServer(e->edittext.str);
   357 		NetworkRebuildHostList();
   491 		NetworkRebuildHostList();
       
   492 		break;
       
   493 
       
   494 	case WE_DESTROY: /* Nicely clean up the sort-list */
       
   495 		free(WP(w, network_ql_d).sort_list);
   358 		break;
   496 		break;
   359 	}
   497 	}
   360 }
   498 }
   361 
   499 
   362 static const Widget _network_game_window_widgets[] = {
   500 static const Widget _network_game_window_widgets[] = {
   418 		}
   556 		}
   419 	}
   557 	}
   420 
   558 
   421 	w = AllocateWindowDesc(&_network_game_window_desc);
   559 	w = AllocateWindowDesc(&_network_game_window_desc);
   422 	if (w != NULL) {
   560 	if (w != NULL) {
   423 		querystr = &WP(w, network_q_d).q;
   561 		querystr = &WP(w, network_ql_d).q;
   424 		ttd_strlcpy(_edit_str_buf, _network_player_name, MAX_QUERYSTR_LEN);
   562 		ttd_strlcpy(_edit_str_buf, _network_player_name, MAX_QUERYSTR_LEN);
   425 		w->vscroll.cap = 12;
   563 		w->vscroll.cap = 12;
   426 
   564 
   427 		querystr->text.caret = true;
   565 		querystr->text.caret = true;
   428 		querystr->text.maxlength = MAX_QUERYSTR_LEN - 1;
   566 		querystr->text.maxlength = MAX_QUERYSTR_LEN - 1;
   437 enum {
   575 enum {
   438 	NSSWND_START = 64,
   576 	NSSWND_START = 64,
   439 	NSSWND_ROWSIZE = 12
   577 	NSSWND_ROWSIZE = 12
   440 };
   578 };
   441 
   579 
   442 /* uses network_q_d (network_d and querystr_d) WP macro */
   580 /* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
   443 static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
   581 static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
   444 {
   582 {
   445 	network_d *nd = &WP(w, network_q_d).n;
   583 	network_d *nd = &WP(w, network_ql_d).n;
   446 
   584 
   447 	switch (e->event) {
   585 	switch (e->event) {
   448 	case WE_CREATE: /* focus input box */
   586 	case WE_CREATE: /* focus input box */
   449 		nd->field = 3;
   587 		nd->field = 3;
   450 		_network_game_info.use_password = (_network_server_password[0] != '\0');
   588 		_network_game_info.use_password = (_network_server_password[0] != '\0');
   460 		SetDParam(13, _players_dropdown[_network_game_info.spectators_max]);
   598 		SetDParam(13, _players_dropdown[_network_game_info.spectators_max]);
   461 		SetDParam(15, _language_dropdown[_network_game_info.server_lang]);
   599 		SetDParam(15, _language_dropdown[_network_game_info.server_lang]);
   462 		DrawWindowWidgets(w);
   600 		DrawWindowWidgets(w);
   463 
   601 
   464 		GfxFillRect(11, 63, 258, 215, 0xD7);
   602 		GfxFillRect(11, 63, 258, 215, 0xD7);
   465 		DrawEditBox(w, &WP(w, network_q_d).q, 3);
   603 		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
   466 
   604 
   467 		DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
   605 		DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
   468 
   606 
   469 		DrawString(10, 43, STR_NETWORK_SELECT_MAP, 2);
   607 		DrawString(10, 43, STR_NETWORK_SELECT_MAP, 2);
   470 
   608 
   567 
   705 
   568 		SetWindowDirty(w);
   706 		SetWindowDirty(w);
   569 		break;
   707 		break;
   570 
   708 
   571 	case WE_MOUSELOOP:
   709 	case WE_MOUSELOOP:
   572 		if (nd->field == 3) HandleEditBox(w, &WP(w, network_q_d).q, 3);
   710 		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
   573 		break;
   711 		break;
   574 
   712 
   575 	case WE_KEYPRESS:
   713 	case WE_KEYPRESS:
   576 		if (nd->field == 3) {
   714 		if (nd->field == 3) {
   577 			if (HandleEditBoxKey(w, &WP(w, network_q_d).q, 3, e) == 1) break; // enter pressed
   715 			if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
   578 
   716 
   579 			ttd_strlcpy(_network_server_name, WP(w, network_q_d).q.text.buf, sizeof(_network_server_name));
   717 			ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name));
   580 			UpdateTextBufferSize(&WP(w, network_q_d).q.text);
   718 			UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
   581 		}
   719 		}
   582 		break;
   720 		break;
   583 
   721 
   584 	case WE_ON_EDIT_TEXT: {
   722 	case WE_ON_EDIT_TEXT: {
   585 		ttd_strlcpy(_network_server_password, e->edittext.str, lengthof(_network_server_password));
   723 		ttd_strlcpy(_network_server_password, e->edittext.str, lengthof(_network_server_password));
   636 	_saveload_mode = SLD_NEW_GAME;
   774 	_saveload_mode = SLD_NEW_GAME;
   637 	BuildFileList();
   775 	BuildFileList();
   638 	w->vscroll.cap = 9;
   776 	w->vscroll.cap = 9;
   639 	w->vscroll.count = _fios_num+1;
   777 	w->vscroll.count = _fios_num+1;
   640 
   778 
   641 	WP(w, network_q_d).q.text.caret = true;
   779 	WP(w, network_ql_d).q.text.caret = true;
   642 	WP(w, network_q_d).q.text.maxlength = MAX_QUERYSTR_LEN - 1;
   780 	WP(w, network_ql_d).q.text.maxlength = MAX_QUERYSTR_LEN - 1;
   643 	WP(w, network_q_d).q.text.maxwidth = 160;
   781 	WP(w, network_ql_d).q.text.maxwidth = 160;
   644 	WP(w, network_q_d).q.text.buf = _edit_str_buf;
   782 	WP(w, network_ql_d).q.text.buf = _edit_str_buf;
   645 	UpdateTextBufferSize(&WP(w, network_q_d).q.text);
   783 	UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
   646 }
   784 }
   647 
   785 
   648 static byte NetworkLobbyFindCompanyIndex(byte pos)
   786 static byte NetworkLobbyFindCompanyIndex(byte pos)
   649 {
   787 {
   650 	byte i;
   788 	byte i;
   837 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
   975 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
   838 	_network_lobby_window_widgets,
   976 	_network_lobby_window_widgets,
   839 	NetworkLobbyWindowWndProc,
   977 	NetworkLobbyWindowWndProc,
   840 };
   978 };
   841 
   979 
   842 
   980 /* Show the networklobbywindow with the selected server
       
   981  * @param ngl Selected game pointer which is passed to the new window */
   843 static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
   982 static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
   844 {
   983 {
   845 	Window *w;
   984 	Window *w;
   846 	DeleteWindowById(WC_NETWORK_WINDOW, 0);
   985 	DeleteWindowById(WC_NETWORK_WINDOW, 0);
   847 
   986 
   848 	NetworkQueryServer(_network_last_host, _network_last_port, false);
   987 	NetworkQueryServer(_network_last_host, _network_last_port, false);
   849 
   988 
   850 	w = AllocateWindowDesc(&_network_lobby_window_desc);
   989 	w = AllocateWindowDesc(&_network_lobby_window_desc);
   851 	if (w != NULL) {
   990 	if (w != NULL) {
   852 		WP(w, network_q_d).n.server = ngl;
   991 		WP(w, network_ql_d).n.server = ngl;
   853 		strcpy(_edit_str_buf, "");
   992 		strcpy(_edit_str_buf, "");
   854 		w->vscroll.cap = 10;
   993 		w->vscroll.cap = 10;
   855 	}
   994 	}
   856 }
   995 }
   857 
   996