FS2_Open
Open source remastering of the Freespace 2 engine
stand_gui.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #ifndef SCP_UNIX
13 
14 #ifdef _WIN32
15 #include <windows.h>
16 #include <commctrl.h>
17 #endif
18 
19 #include "network/stand_gui.h"
20 #include "freespace2/freespace.h"
22 #include "network/multi.h"
23 #include "network/multimsgs.h"
24 #include "network/multiutil.h"
25 #include "mission/missiongoals.h"
26 #include "cmdline/cmdline.h"
27 #include "network/multi_kick.h"
28 #include "network/multi_pmsg.h"
29 #include "missionui/chatbox.h"
30 #include "network/multi_endgame.h"
32 #include "playerman/player.h"
33 #include "osapi/osregistry.h"
34 #include "io/timer.h"
35 #include "globalincs/version.h"
36 #include "ship/ship.h"
37 #include "cfile/cfile.h"
38 #include "fs2netd/fs2netd_client.h"
39 
40 #include <string>
41 
42 
45 static HWND Standalone_hwnd = NULL;
46 static BOOL Standalone_minimized = FALSE;
47 
48 #define ST_MODE_CREATE 0
49 #define ST_MODE_UPDATE 1
50 #define ST_MODE_REMOVE 2
51 
52 #define MSG_SYSTRAYICON WM_USER+99
53 
54 static void standalone_do_systray(int mode);
55 
56 // system tray menu item identifiers...
57 #define STP_RESET_ALL 1
58 #define STP_SHUTDOWN 2
59 #define STP_SHOW 3
60 #define STP_RESET_FS2NETD 4
61 
62 
63 // -----------------------------------------------------------------------------------------
64 // standalone global defs
65 
66 #define MAX_STANDALONE_PAGES 5
67 
68 #define STD_STATS_UPDATE_TIME 500 // ms between updating player stats on the visible controls
69 #define STD_NG_UPDATE_TIME 100 // ms between updating netgame information are controls
70 
71 // coords for the "shutdown" button (client window coords)
72 static int Std_shutdown_coords[GR_NUM_RESOLUTIONS][2] = {
73  { 130, 450 }, // GR_640
74  { 130, 450 } // GR_640
75 };
76 
77 // you should reference Page_handles and Pages with these defines from now on
78 #define CONNECT_PAGE 0
79 #define MULTIPLAYER_PAGE 1
80 #define PLAYER_INFO_PAGE 2
81 #define GODSTUFF_PAGE 3
82 #define DEBUG_PAGE 4
83 
84 // standalone gui property sheet stuff
85 static HWND Psht;
86 static HWND Page_handles[MAX_STANDALONE_PAGES];
87 static PROPSHEETPAGE Pages[MAX_STANDALONE_PAGES];
88 static PROPSHEETHEADER Sheet;
89 
90 // index into Page_handles[] representing the currently selected page
91 static int Active_standalone_page;
92 
93 // timestamp for updating currently selected player stats on the player info page
95 
96 // timestamp for updating the netgame information are text controls
98 
99 // banned player callsigns
100 #define STANDALONE_MAX_BAN 50
103 
104 char title_str[512];
105 
106 // ----------------------------------------------------------------------------------------
107 // mission validation dialog
108 //
109 
110 static HWND Multi_gen_dialog = NULL; // the dialog itself
111 
112 // dialog proc for this dialog
114 {
115  switch(uMsg){
116  case WM_INITDIALOG:
117  return TRUE;
118 
119  // destory command
120  case WM_DESTROY:
121  Multi_gen_dialog = NULL;
122  break;
123  }
124  return FALSE;
125 }
126 
127 // create the validate dialog
128 void std_create_gen_dialog(char *title)
129 {
130  // if the dialog is already active, do nothing
131  if(Multi_gen_dialog != NULL){
132  return;
133  }
134 
135  // if we are minimized then don't bother
136  if (Standalone_minimized) {
137  return;
138  }
139 
140  // otherwise create the dialog
141  Multi_gen_dialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_GEN), Psht, (DLGPROC)std_gen_dialog_proc);
142  if(Multi_gen_dialog != NULL){
143  SetWindowText(Multi_gen_dialog, title);
144  }
145 }
146 
147 // kill the validate dialog();
149 {
150  // if the dialog is not active, do nothing
151  if(Multi_gen_dialog == NULL){
152  return;
153  }
154 
155  // kill it
156  DestroyWindow(Multi_gen_dialog);
157  Multi_gen_dialog = NULL;
158 }
159 
160 // set the text in the filename of the validate dialog
161 // valid values for field_num == 0 .. 2
162 void std_gen_set_text(char *str, int field_num)
163 {
164  HWND ctrl;
165 
166  // if the dialog is not active
167  if((Multi_gen_dialog == NULL) || (str == NULL) || (field_num < 0) || (field_num > 2)){
168  return;
169  }
170 
171  // otherwise set the text
172  ctrl = GetDlgItem(Multi_gen_dialog, (int)MAKEINTRESOURCE(IDC_FIELD1));
173  switch(field_num){
174  case 0:
175  ctrl = GetDlgItem(Multi_gen_dialog,(int)MAKEINTRESOURCE(IDC_FIELD1));
176  break;
177  case 1:
178  ctrl = GetDlgItem(Multi_gen_dialog,(int)MAKEINTRESOURCE(IDC_FIELD2));
179  break;
180  case 2:
181  ctrl = GetDlgItem(Multi_gen_dialog,(int)MAKEINTRESOURCE(IDC_FIELD3));
182  break;
183  }
184  SetWindowText(ctrl, str);
185 }
186 
187 // is the validate dialog active
189 {
190  return Multi_gen_dialog != NULL;
191 }
192 
193 // ----------------------------------------------------------------------------------------
194 // connection page/tab functions
195 //
196 static HWND Multi_std_name; // standalone name text edit control
197 HWND Multi_std_host_passwd; // host password text control
199 
200 // convert the index of an item in the list box into an index into the net players array
202 
203 // set the text box indicating how many players are connected, returning the determined count
205 {
206  HWND ctrl;
207  char str[40];
208  char val[10];
209  int idx,count;
210 
211  // setup the text string
212  strcpy_s(str,XSTR("# Connections : ",911));
213 
214  // determine how many players are actually connected
215  count = 0;
216  for(idx=0;idx<MAX_PLAYERS;idx++){
217  if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx])){
218  count++;
219  }
220  }
221 
222  // tack on the player count to the end of the string
223  sprintf(val,"%d",count);
224  strcat_s(str,val);
225 
226  // set the text itself
227  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE],(int)MAKEINTRESOURCE(IDC_CON_COUNT));
228  SetWindowText(ctrl,str);
229 
230  // return the num of players found
231  return count;
232 }
233 
234 // set the connect status (connected or not) of the game host
236 {
237  int idx,found;
238  HWND ctrl;
239 
240  // first try and find the host
241  found = 0;
242  for(idx=0;idx<MAX_PLAYERS;idx++){
244  found = 1;
245  break;
246  }
247  }
248 
249  // get the control and set the status
250  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE],(int)MAKEINTRESOURCE(IDC_HOST_IS));
251  if(found){
252  SetWindowText(ctrl, XSTR("Host connected ? Yes",912));
253  } else {
254  SetWindowText(ctrl, XSTR("Host connected ? No",913));
255  }
256 }
257 
258 // add an ip string to the connect page listbox
259 void std_connect_add_ip_string(char *string)
260 {
261  HWND ctrl;
262 
263  // add the item
264  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE], (int)MAKEINTRESOURCE(IDC_CONPING));
265  SendMessage(ctrl, LB_ADDSTRING, (WPARAM)0, (LPARAM)(LPCTSTR)string);
266 }
267 
268 // remove an ip string from the connect page listbox
270 {
271  HWND ctrl;
272  int loc;
273 
274  // get the control handle
275  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE], (int)MAKEINTRESOURCE(IDC_CONPING));
276 
277  // NOTE the use of FINDSTRING and _not_ FINDSTRINGEXACT !!
278  // since we've appended the ping to the end of the string, we can only check the
279  // "prefix" which is the net_players name
280  loc = SendMessage(ctrl, LB_FINDSTRING, (WPARAM)-1, (LPARAM)(LPCTSTR)string);
281 
282  if(loc!=LB_ERR){
283  SendMessage(ctrl, LB_DELETESTRING, (WPARAM)loc, (LPARAM)0);
284  }
285 }
286 
287 // set an ip string on the connect page listbox
288 void std_connect_set_ip_string(char *lookup,char *string)
289 {
290  HWND ctrl;
291  int loc;
292 
293  // get the control handle
294  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE],(int)MAKEINTRESOURCE(IDC_CONPING));
295 
296  // NOTE the use of FINDSTRING and _not_ FINDSTRINGEXACT !!
297  // since we've appended the ping to the end of the string, we can only check the
298  // "prefix" which is the net_players name
299  loc = SendMessage(ctrl,LB_FINDSTRING,(WPARAM)-1,(LPARAM)(LPCTSTR)lookup);
300 
301  if(loc!=LB_ERR){
302  SendMessage(ctrl,LB_DELETESTRING,(WPARAM)loc,(LPARAM)0);
303  SendMessage(ctrl,LB_INSERTSTRING,(WPARAM)loc,(LPARAM)string);
304  }
305 }
306 
308 {
309  int player_num,sel;
310  HWND ctrl;
311 
312  // get the control handle
313  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE],(int)MAKEINTRESOURCE(IDC_CONPING));
314 
315  sel = SendMessage(ctrl,LB_GETCURSEL,(WPARAM)0,(LPARAM)0);
316  // attempt to get the player index
317  if(sel != CB_ERR){
318  player_num = std_connect_lindex_to_npindex(sel);
319 
320  // if we found him, then kick the bastard
321  if(player_num != -1){
322  multi_kick_player(player_num,0);
323  }
324  }
325 }
326 
327 // update the ping for this particular player
329 {
330  char str[40],ping[10],sml_ping[10],lookup[50];
331 
332  // as long as his ping is not -1, do an update
333  if(p->s_info.ping.ping_avg > -1){
334  // get the lookup string
335  psnet_addr_to_string(lookup,&p->p_info.addr);
336 
337  // build the string to replace the ping with
338  strcpy_s(str,lookup);
339  strcat_s(str,", ");
340 
341  // chop it off at pings greater than 1 second
342  if(p->s_info.ping.ping_avg > 1000){
343  strcat_s(str,XSTR("> 1 sec",914));
344  strcpy_s(sml_ping,XSTR("> 1 sec",914));
345  }
346  else {
347  sprintf(ping,"%d",p->s_info.ping.ping_avg);
348  strcat_s(str,ping);
349  strcat_s(str,XSTR(" ms",915));
350  strcpy_s(sml_ping,ping); strcat_s(sml_ping,XSTR(" ms",915));
351  }
352 
353  // set the string
354  std_connect_set_ip_string(lookup,str);
355  }
356 }
357 
358 // clear all the controls for this page
360 {
361  HWND handle;
362 
363  // set various connect counts
366 
367  // reset the list of players and pings
368  handle = GetDlgItem(Page_handles[CONNECT_PAGE],(int)MAKEINTRESOURCE(IDC_CONPING));
369  SendMessage(handle,LB_RESETCONTENT,(WPARAM)0,(LPARAM)0);
370 }
371 
372 // set the game name for the standalone. passing NULL uses the default
374 {
375  char buf[MAX_GAMENAME_LEN+1];
376 
377  // use the default name for now
378  if(name == NULL){
379  // if a permanent name exists, use that instead of the default
380  if(strlen(Multi_options_g.std_pname)){
382  } else {
383  strcpy_s(Netgame.name,XSTR("Standalone Server",916));
384  }
385  } else {
386  strcpy_s(Netgame.name,name);
387 
388  // update fs2netd
389  if (MULTI_IS_TRACKER_GAME) {
391  Sleep(50);
393  }
394  }
395 
396  // update systray icon
397  standalone_do_systray(ST_MODE_UPDATE);
398 
399  // update the text control
400  strcpy_s(buf,Netgame.name);
402  SetWindowText(Multi_std_name,buf);
404 }
405 
406 // the user has changed the text in the server name text box. handle this
408 {
409  char buf[MAX_GAMENAME_LEN+1];
410  int max_len = MAX_GAMENAME_LEN;
411 
413  memset(buf,0,MAX_GAMENAME_LEN+1);
414  memcpy(&buf[0],&max_len,sizeof(int));
415 
416  // get the new text
417  SendMessage(Multi_std_name,EM_GETLINE,(WPARAM)0,(LPARAM)(LPCSTR)buf);
418 
419  // just copy it over for now. we may want to process this more later on
420  strncpy(Netgame.name, buf, sizeof(Netgame.name));
421 
422  // copy it to the permanent name
423  strncpy(Multi_options_g.std_pname, buf, sizeof(Multi_options_g.std_pname));
424 
425  // update systray icon
426  standalone_do_systray(ST_MODE_UPDATE);
427 
428  // update fs2netd with the info
429  if (MULTI_IS_TRACKER_GAME) {
431  Sleep(50);
433  }
434  }
435 }
436 
437 // the user has changed the text in the host password text box
439 {
440  char buf[STD_PASSWD_LEN+1];
441  int max_len = STD_PASSWD_LEN;
442 
443  memset(buf,0,STD_PASSWD_LEN+1);
444  memcpy(&buf[0],&max_len,sizeof(int));
445 
446  // get the new text
447  SendMessage(Multi_std_host_passwd,EM_GETLINE,(WPARAM)0,(LPARAM)(LPCSTR)buf);
448 
449  // just copy it over for now. we may want to process this more later on
450  strncpy(Multi_options_g.std_passwd, buf, sizeof(Multi_options_g.std_passwd));
451 }
452 
453 // convert the index of an item in the list box into an index into the net players array
455 {
456  HWND ctrl;
457  char list_text[40];
458  char addr_text[40];
459  int ret,idx;
460 
461  // get the control handle
462  ctrl = GetDlgItem(Page_handles[CONNECT_PAGE],(int)MAKEINTRESOURCE(IDC_CONPING));
463 
464  // get the string contained at a given index
465  SendMessage(ctrl,LB_GETTEXT,(WPARAM)index,(LPARAM)(LPSTR)list_text);
466 
467  // look through the net players array and compare address strings (yuck)
468  ret = -1;
469  for(idx=0;idx<MAX_PLAYERS;idx++){
470  // only look at connected players
471  if(MULTI_CONNECTED(Net_players[idx])){
472  strcpy_s(addr_text,"");
473  psnet_addr_to_string(addr_text,&Net_players[idx].p_info.addr);
474 
475  // if we found the match
476  if((addr_text[0] != '\0') && (strstr(list_text,addr_text) != NULL)){
477  ret = idx;
478  break;
479  }
480  }
481  }
482 
483  return ret;
484 }
485 
486 // message handler for the connect tab
488 {
489  switch(uMsg){
490  // initialize the dialog
491  case WM_INITDIALOG:
492  // setup the page handle array for this page
493  Page_handles[CONNECT_PAGE] = hwndDlg;
494 
495  // create the standalone name text box and limit its text length
496  Multi_std_name = GetDlgItem(hwndDlg, (int)MAKEINTRESOURCE(IDC_STD_NAME));
497  SendMessage(Multi_std_name, EM_SETLIMITTEXT, (WPARAM)MAX_GAMENAME_LEN, (LPARAM)0);
499 
500  // create the standalone host password input box
501  Multi_std_host_passwd = GetDlgItem(hwndDlg, (int)MAKEINTRESOURCE(IDC_STD_HOST_PASSWD));
502  SendMessage(Multi_std_host_passwd, EM_SETLIMITTEXT, (WPARAM)STD_PASSWD_LEN, (LPARAM)0);
503  memset(Multi_options_g.std_passwd, 0, STD_PASSWD_LEN+1);
504 
505  return 1;
506 
507  // process a command of some kind (usually button presses)
508  case WM_COMMAND:
509  switch(HIWORD(wParam)){
510  // a button press
511  case BN_CLICKED :
512  switch(LOWORD(wParam)){
513  // the reset standalone button
514  case IDC_RESET_MULTI :
515  // multi_standalone_quit_game();
517  break;
518 
519  // kick the currently selected player
520  case IDC_KICK_BUTTON :
522  break;
523 
524  // refresh file list (PXO)
525  case IDC_PXO_REFRESH:
527  // delete mvalid.cfg if it exists
529 
530  // refresh missions
532  }
533  break;
534  }
535  break;
536  // an edit control text has been changed
537  case EN_UPDATE :
538  if((HWND)lParam == Multi_std_name){
539  // update the standalone name field in Netgame.name
541  } else if((HWND)lParam == Multi_std_host_passwd){
542  // update the standalone host passwd
544  }
545  break;
546  }
547  break;
548 
549  // a notification message
550  case WM_NOTIFY :
551  // notification that this is the current selected page. set our own internal data vars
552  if(((LPNMHDR)lParam)->code == PSN_SETACTIVE){
553  Active_standalone_page = CONNECT_PAGE;
554  } else if ( (((LPNMHDR)lParam)->code == PSN_APPLY) || (((LPNMHDR)lParam)->code == PSN_RESET) ) {
555  PostMessage( Psht, WM_DESTROY, 0, 0 );
556  }
557  break;
558 
559  default :
560  return 0;
561  }
562  return 0;
563 }
564 
565 
566 // ----------------------------------------------------------------------------------------
567 // multiplayer page/tab functions
568 //
569 
570 static HWND Framecap_trackbar; // trackbar for capping framerate
571 static HWND Standalone_FPS; // text control for displaying framerate
572 static HWND Standalone_mission_name; // text control for showing the current mission name
573 static HWND Standalone_missiontime; // text control for showing current mission time
574 static HIMAGELIST Goal_bitmaps; // bitmaps array for the goal tree control
575 static HWND Standalone_goals; // goal tree control handle
576 static HTREEITEM Goal_items[3]; // primary, secondary, and bonus goal items
577 static HWND Std_ng_max_players; // max players display text control
578 static HWND Std_ng_max_observers; // max observers display text control
579 static HWND Std_ng_security; // netgame security display text control
580 static HWND Std_ng_respawns; // netgame # respawns display text control
581 
582 #define GOALVIEW_X 5 // goal view control extents
583 #define GOALVIEW_Y 242 //
584 #define GOALVIEW_W 160 //
585 #define GOALVIEW_H 168 //
586 
587 // handle the user sliding the framerate cap scrollbar around
589 
590 // initialize the framerate cap slide control
592 
593 // initialize all the controls for this page
594 void std_multi_init_multi_controls(HWND hwndDlg);
595 
596 // return the handle to the item matching the given parameters
597 HTREEITEM std_multi_get_goal_item(char *goal_string,int type);
598 
599 // set the mission time in seconds
600 void std_multi_set_standalone_missiontime(float mission_time)
601 {
602  char txt[20];
603  char time_txt[30];
604  fix m_time = fl2f(mission_time);
605 
606  // format the time string and set the text
607  game_format_time(m_time,time_txt);
608  sprintf(txt," : %.1f", mission_time);
609  strcat_s(time_txt,txt);
610  SetWindowText(Standalone_missiontime,time_txt);
611 }
612 
613 // set the mission name
615 {
616  // set the text
617  SetWindowText(Standalone_mission_name,mission_name);
618 }
619 
620 // initialize the goal tree for this mission
622 {
623  TV_ITEM new_item;
624  TV_INSERTSTRUCT tree_insert;
625  char goal_name[NAME_LENGTH+1];
626 
627  // clear out the tree control
628  TreeView_DeleteAllItems(Standalone_goals);
629 
630  // add the primary goal tag
631  new_item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
632  new_item.pszText = goal_name;
633  strcpy(new_item.pszText,XSTR("Primary Objectives",917));
634  new_item.iImage = 0;
635  new_item.iSelectedImage = 0;
636  tree_insert.hParent = NULL;
637  tree_insert.hInsertAfter = TVI_FIRST;
638  tree_insert.item = new_item;
639  Goal_items[0] = TreeView_InsertItem(Standalone_goals,&tree_insert);
640 
641  // add the secondary goal tag
642  new_item.pszText = goal_name;
643  strcpy(new_item.pszText,XSTR("Secondary Objectives",918));
644  new_item.iImage = 0;
645  new_item.iSelectedImage = 0;
646  tree_insert.hInsertAfter = TVI_LAST;
647  tree_insert.item = new_item;
648  Goal_items[1] = TreeView_InsertItem(Standalone_goals,&tree_insert);
649 
650  // add the bonus goal tag
651  new_item.pszText = goal_name;
652  strcpy(new_item.pszText,XSTR("Bonus Objectives",919));
653  new_item.iImage = 0;
654  new_item.iSelectedImage = 0;
655  tree_insert.item = new_item;
656  Goal_items[2] = TreeView_InsertItem(Standalone_goals,&tree_insert);
657 }
658 
659 // add all the goals from the current mission to the tree control
661 {
662  TV_ITEM new_item;
663  TV_INSERTSTRUCT tree_insert;
664  int idx,goal_flags,perm_goal_flags;
665  char goal_name[NAME_LENGTH+1];
666 
667  // setup data common for every item
668  new_item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
669  tree_insert.hInsertAfter = TVI_LAST;
670 
671  perm_goal_flags = 0;
672  for(idx=0;idx<Num_goals;idx++){
673  // reset the goal flags
674  goal_flags = 0;
675 
676  switch(Mission_goals[idx].type & GOAL_TYPE_MASK){
677  // primary goal
678  case PRIMARY_GOAL :
679  goal_flags |= (1<<1); // (image index == 1, primary goal)
680  perm_goal_flags |= (1<<1);
681  break;
682 
683  // a secondary goal
684  case SECONDARY_GOAL :
685  goal_flags |= (1<<2); // (image index == 1, secondary goal)
686  perm_goal_flags |= (1<<2);
687  break;
688 
689  // a bonus goal
690  case BONUS_GOAL :
691  goal_flags |= (1<<3); // (image index == 1, bonus goal)
692  perm_goal_flags |= (1<<3);
693  break;
694 
695  default :
696  goal_flags |= (1<<0); // (image index == 3, no goal)
697  break;
698  }
699 
700  // first select whether to insert under primary, secondary, or bonus tree roots
701  tree_insert.hParent = Goal_items[Mission_goals[idx].type & GOAL_TYPE_MASK];
702 
703  // set the goal name
704  new_item.pszText = goal_name;
705  strcpy(new_item.pszText,Mission_goals[idx].name);
706 
707  // set the correct image indices
708  new_item.iImage = (goal_flags & (1<<0)) ? 3 : 0;
709  new_item.iSelectedImage = (goal_flags & (1<<0)) ? 3 : 0;
710 
711  // insert the item
712  tree_insert.item = new_item;
713  TreeView_InsertItem(Standalone_goals,&tree_insert);
714  }
715 
716  // check to see if there are any of the three types of mission goals. If not, then
717  // insert "none"
718  if(!(perm_goal_flags & (1<<1))){
719  // insert the "none" item
720  tree_insert.hParent = Goal_items[0];
721  new_item.pszText = goal_name;
722  strcpy(new_item.pszText,XSTR("none",920));
723  new_item.iImage = 3;
724  new_item.iSelectedImage = 3;
725  tree_insert.item = new_item;
726  TreeView_InsertItem(Standalone_goals,&tree_insert);
727  }
728  if(!(perm_goal_flags & (1<<2))){
729  // insert the "none" item
730  tree_insert.hParent = Goal_items[1];
731  new_item.pszText = goal_name;
732  strcpy(new_item.pszText,XSTR("none",920));
733  new_item.iImage = 3;
734  new_item.iSelectedImage = 3;
735  tree_insert.item = new_item;
736  TreeView_InsertItem(Standalone_goals,&tree_insert);
737  }
738  if(!(perm_goal_flags & (1<<3))){
739  // insert the "none" item
740  tree_insert.hParent = Goal_items[1];
741  new_item.pszText = goal_name;
742  strcpy(new_item.pszText,XSTR("none",920));
743  new_item.iImage = 3;
744  new_item.iSelectedImage = 3;
745  tree_insert.item = new_item;
746  TreeView_InsertItem(Standalone_goals,&tree_insert);
747  }
748 
749  // expand out all the tree roots so all goals are shown
750  for(idx=0;idx<3;idx++){
751  TreeView_Expand(Standalone_goals,Goal_items[idx],TVE_EXPAND);
752  }
753 }
754 
755 // update all the goals in the goal tree based upon the mission status
757 {
758  HTREEITEM update_item;
759  TV_ITEM setting,lookup;
760  int idx,should_update;
761 
762  setting.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
763 
764  // go through all the goals
765  for(idx=0;idx<Num_goals;idx++){
766  // get a handle to the tree item
767  update_item = NULL;
769 
770  // continue if we didn't get a valid item
771  if(update_item == NULL){
772  continue;
773  }
774 
775  // get the tree item itself (as it currently stands)
776  lookup.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
777  lookup.hItem = update_item;
778  if(!TreeView_GetItem(Standalone_goals,&lookup)){
779  continue;
780  }
781 
782  should_update = 0;
783  // determine what image to set for each one (failed, satisfied, incomplete, etc)
784  switch(Mission_goals[idx].satisfied){
785  case GOAL_FAILED :
786  // determine if we should update the item
787  if((lookup.iImage != 4) && (lookup.iSelectedImage != 4)){
788  setting.iImage = 4;
789  setting.iSelectedImage = 4;
790 
791  should_update = 1;
792  }
793  break;
794  case GOAL_COMPLETE :
795  // determine if we should update the item
796  if((lookup.iImage != 2) && (lookup.iSelectedImage != 2)){
797  setting.iImage = 2;
798  setting.iSelectedImage = 2;
799 
800  should_update = 1;
801  }
802  break;
803 
804  case GOAL_INCOMPLETE :
805  // determine if we should update the item
806  if((lookup.iImage != 1) && (lookup.iSelectedImage != 1)){
807  setting.iImage = 1;
808  setting.iSelectedImage = 1;
809 
810  should_update = 1;
811  }
812  break;
813  }
814 
815  // set the actual image
816  if(should_update){
817  setting.hItem = update_item;
818  TreeView_SetItem(Standalone_goals,&setting);
819  }
820  }
821 }
822 
823 // set the framerate text box for this page
825 {
826  char fr[10];
827 
828  // set the window text
829  sprintf(fr,"%.1f",f);
830  SetWindowText(Standalone_FPS,fr);
831 }
832 
833 // clear all the controls for this page
835 {
836  // clear out the mission name text static
837  SetWindowText(Standalone_mission_name,"");
838 
839  // clear out the framerate text box
840  SetWindowText(Standalone_FPS,"");
841 
842  // clear out the misison time text box
843  SetWindowText(Standalone_missiontime,"");
844 
845  // clear out the netgame max players text box
846  SetWindowText(Std_ng_max_players,"");
847 
848  // clear out the netgame max observer text box
849  SetWindowText(Std_ng_max_observers,"");
850 
851  // clear out the netgame security text box
852  SetWindowText(Std_ng_security,"");
853 
854  // clear out the netgame respawns # text box
855  SetWindowText(Std_ng_respawns,"");
856 
857  // clear the goal tree control
859 }
860 
861 // update the netgame information area controls with the current Netgame settings
863 {
864  char buf[40];
865 
866  // update the
867 
868  // update the max players control
869  sprintf(buf,"%d",Netgame.max_players);
870  SetWindowText(Std_ng_max_players,buf);
871 
872  // update the max observers control
874  SetWindowText(Std_ng_max_observers,buf);
875 
876  // update the netgame security control
877  sprintf(buf,"%d",Netgame.security);
878  SetWindowText(Std_ng_security,buf);
879 
880  // update the netgame respawns # control
881  sprintf(buf,"%u",Netgame.respawn);
882  SetWindowText(Std_ng_respawns,buf);
883 }
884 
885 // handle the user sliding the framerate cap scrollbar around
887 {
888  int pos;
889  char pos_text[10];
890 
891  // determine where the slider now is
892  pos = SendMessage(ctrl,TBM_GETPOS,(WPARAM)0,(LPARAM)0);
893 
894  // update the text display
895  sprintf(pos_text,"%d",pos);
896  SetWindowText(GetDlgItem(Page_handles[MULTIPLAYER_PAGE],(int)MAKEINTRESOURCE(IDC_FRAMECAP_STATIC)),pos_text);
897 
898  // set the framecap var
900 }
901 
902 // initialize the framerate cap slide control
904 {
905  WPARAM wp;
906  LPARAM lp;
907 
908  // create the trackbar object
909  Framecap_trackbar = CreateWindowEx(0,TRACKBAR_CLASS,NULL,WS_CHILD | WS_VISIBLE,
910  10,10,300,30,hwndDlg,NULL,GetModuleHandle(NULL),NULL);
911 
912  // set the range of the framerate cap
913  wp = (WPARAM)(BOOL)TRUE;
914  lp = (LPARAM)MAKELONG(1, 100);
915  SendMessage(Framecap_trackbar,TBM_SETRANGE,wp,lp);
916 
917  // set the default framerate cap the be the standalone default
918  wp = (WPARAM)(BOOL)TRUE;
919  lp = (LPARAM)(LONG)30;
920  SendMessage(Framecap_trackbar,TBM_SETPOS,wp,lp);
921 
922  // call this to update the standalone framecap on this first run
923  std_multi_handle_framecap_scroll(Framecap_trackbar);
924 }
925 
926 // initialize all the controls for this page
928 {
929  HBITMAP ref;
930  COLORREF mask;
931 
932  // create the framecap slider
934 
935  // create the framerate display text box
936  Standalone_FPS = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_STANDALONE_FPS));
937 
938  // create the missiontime text box
939  Standalone_missiontime = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_STANDALONE_MTIME));
940 
941  // create the mission name text box
942  Standalone_mission_name = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_MISSION_NAME));
943 
944  // create the netgame max players text box
945  Std_ng_max_players = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_NG_MAXPLAYERS));
946 
947  // create the netgame max observers text box
948  Std_ng_max_observers = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_NG_MAXOBSERVERS));
949 
950  // create the netgame security text box
951  Std_ng_security = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_NG_SECURITY));
952 
953  // create the netgame respawns # text box
954  Std_ng_respawns = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_NG_RESPAWNS));
955 
956  // load the goal tree-view bitmaps
957  Goal_bitmaps = ImageList_Create(16,16,ILC_COLOR4 | ILC_MASK,5,0);
958 
959  mask = 0x00ff00ff;
960  ref = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_GOAL_ORD));
961  ImageList_AddMasked(Goal_bitmaps,ref,mask);
962 
963  ref = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_GOAL_INC));
964  mask = 0x00ffffff;
965  ImageList_AddMasked(Goal_bitmaps,ref,mask);
966 
967  ref = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_GOAL_COMP));
968  mask = 0x00ffffff;
969  ImageList_AddMasked(Goal_bitmaps,ref,mask);
970 
971  ref = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_GOAL_NONE));
972  mask = 0x00ffffff;
973  ImageList_AddMasked(Goal_bitmaps,ref,mask);
974 
975  ref = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_GOAL_FAIL));
976  mask = 0x00ffffff;
977  ImageList_AddMasked(Goal_bitmaps,ref,mask);
978 
979  // create the tree view control and associate its image list
980  Standalone_goals = CreateWindowEx(0, WC_TREEVIEW, XSTR("Tree View",921),
981  WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES,
983  hwndDlg, NULL, GetModuleHandle(NULL), NULL);
984  TreeView_SetImageList(Standalone_goals,Goal_bitmaps,TVSIL_NORMAL);
985 }
986 
987 // return the handle to the item matching the given parameters
988 HTREEITEM std_multi_get_goal_item(char *goal_string,int type)
989 {
990  HTREEITEM ret,moveup;
991  TV_ITEM lookup;
992  int done;
993  char goal_name_text[NAME_LENGTH+1];
994 
995  // look under the correct root item
996  lookup.mask = TVIF_TEXT;
997  lookup.pszText = goal_name_text;
998  lookup.cchTextMax = NAME_LENGTH;
999  strcpy(lookup.pszText,goal_string);
1000 
1001  // search through all the items
1002  done=0;
1003  ret=NULL;
1004  moveup = TreeView_GetChild(Standalone_goals,Goal_items[type]);
1005  while(!done && moveup!=NULL){
1006  lookup.hItem = moveup;
1007  TreeView_GetItem(Standalone_goals,&lookup);
1008  if(strcmp(lookup.pszText,goal_string)==0){
1009  ret = moveup;
1010  done=1;
1011  }
1012  if(!done){
1013  moveup = TreeView_GetNextItem(Standalone_goals,moveup,TVGN_NEXT);
1014  }
1015  }
1016  return ret;
1017 }
1018 
1019 // message handler for the multiplayer tab
1021 {
1022  switch(uMsg){
1023  // initialize the page
1024  case WM_INITDIALOG:
1025  // set the page handle
1026  Page_handles[MULTIPLAYER_PAGE] = hwndDlg;
1027 
1028  // initialize all the controls
1030  return 1;
1031  break;
1032 
1033  // a scroll message from the framerate cap trackbar
1034  case WM_HSCROLL:
1036  return 1;
1037  break;
1038 
1039  // notification that this page has been set as active
1040  case WM_NOTIFY :
1041  // setup our own internal vars
1042  if(((LPNMHDR)lParam)->code == PSN_SETACTIVE){
1043  Active_standalone_page = MULTIPLAYER_PAGE;
1044  } else if ( (((LPNMHDR)lParam)->code == PSN_APPLY) || (((LPNMHDR)lParam)->code == PSN_RESET) ) {
1045  // PostMessage( Psht, WM_DESTROY, 0, 0 );
1047  }
1048  break;
1049 
1050  default :
1051  return 0;
1052  break;
1053  }
1054  return 0;
1055 }
1056 
1057 
1058 // ---------------------------------------------------------------------------------------
1059 // player info page/tab functions
1060 //
1061 
1062 #define MAX_PLAYER_STAT_FIELDS 14 // the # of stats fields for a given set
1063 static HWND Player_name_list; // the listbox control with player callsigns in it
1064 static HWND Player_ship_type; // the current player's ship type
1065 static HWND Player_ping_time; // the current player's ping time
1066 static HWND Player_stats[MAX_PLAYER_STAT_FIELDS]; // text boxes for player alltime statistics info
1067 static HWND Player_mstats[MAX_PLAYER_STAT_FIELDS]; // text boxes for player mission statistics info
1068 
1069 // sprintf and set window text to the passed int
1070 #define STD_ADDSTRING(hwnd,val) { snprintf(txt,sizeof(txt)-1,"%d",(int)val); SetWindowText(hwnd,txt); }
1071 
1072 // intialize all the controls in the player info tab
1074 
1075 // returns true or false depending on whether the passed netplayer is the currently selected guy
1077 
1078 // start displaying info for the passed player on this page
1080 {
1081  char txt[40];
1082  txt[sizeof(txt)-1] = '\0';
1083 
1084  // set his ship type
1085  SetWindowText(Player_ship_type,Ship_info[p->p_info.ship_class].name);
1086 
1087  // display his ping time
1089 
1090  // his alltime stats
1091  scoring_struct *ptr = &p->m_player->stats;
1092  STD_ADDSTRING(Player_stats[0], ptr->score);
1093  STD_ADDSTRING(Player_stats[1], ptr->kill_count);
1094  STD_ADDSTRING(Player_stats[2], ptr->kill_count - ptr->kill_count_ok);
1095  STD_ADDSTRING(Player_stats[3], ptr->assists);
1096  STD_ADDSTRING(Player_stats[4], ptr->p_shots_fired);
1097  STD_ADDSTRING(Player_stats[5], ptr->p_shots_hit);
1098  STD_ADDSTRING(Player_stats[6], ptr->p_bonehead_hits);
1099  STD_ADDSTRING(Player_stats[7],
1100  (ptr->p_shots_fired > 0) ? (int)((float)100.0*((float)ptr->p_shots_hit/(float)ptr->p_shots_fired)) : 0);
1101  STD_ADDSTRING(Player_stats[8],
1102  (ptr->p_shots_fired > 0) ? (int)((float)100.0*((float)ptr->p_bonehead_hits/(float)ptr->p_shots_fired)) : 0);
1103  STD_ADDSTRING(Player_stats[9], ptr->s_shots_fired);
1104  STD_ADDSTRING(Player_stats[10], ptr->s_shots_hit);
1105  STD_ADDSTRING(Player_stats[11], ptr->s_bonehead_hits);
1106  STD_ADDSTRING(Player_stats[12],
1107  (ptr->s_shots_fired > 0) ? (int)((float)100.0*((float)ptr->s_shots_hit/(float)ptr->s_shots_fired)) : 0);
1108  STD_ADDSTRING(Player_stats[13],
1109  (ptr->s_shots_fired > 0) ? (int)((float)100.0*((float)ptr->s_bonehead_hits/(float)ptr->s_shots_fired)) : 0);
1110 
1111  // his stats for the current mission
1112  STD_ADDSTRING(Player_mstats[0], ptr->m_score);
1113  STD_ADDSTRING(Player_mstats[1], ptr->m_kill_count);
1114  STD_ADDSTRING(Player_mstats[2], ptr->m_kill_count - ptr->m_kill_count_ok);
1115  STD_ADDSTRING(Player_mstats[3], ptr->m_assists);
1116  STD_ADDSTRING(Player_mstats[4], ptr->mp_shots_fired);
1117  STD_ADDSTRING(Player_mstats[5], ptr->mp_shots_hit);
1118  STD_ADDSTRING(Player_mstats[6], ptr->mp_bonehead_hits);
1119  STD_ADDSTRING(Player_mstats[7],
1120  (ptr->mp_shots_fired > 0) ? (int)((float)100.0*((float)ptr->mp_shots_hit/(float)ptr->mp_shots_fired)) : 0);
1121  STD_ADDSTRING(Player_mstats[8],
1122  (ptr->mp_shots_fired > 0) ? (int)((float)100.0*((float)ptr->mp_bonehead_hits/(float)ptr->mp_shots_fired)) : 0);
1123  STD_ADDSTRING(Player_mstats[9], ptr->ms_shots_fired);
1124  STD_ADDSTRING(Player_mstats[10], ptr->ms_shots_hit);
1125  STD_ADDSTRING(Player_mstats[11], ptr->ms_bonehead_hits);
1126  STD_ADDSTRING(Player_mstats[12],
1127  (ptr->ms_shots_fired > 0) ? (int)((float)100.0*((float)ptr->ms_shots_hit/(float)ptr->ms_shots_fired)) : 0);
1128  STD_ADDSTRING(Player_mstats[13],
1129  (ptr->ms_shots_fired > 0) ? (int)((float)100.0*((float)ptr->ms_bonehead_hits/(float)ptr->ms_shots_fired)) : 0);
1130 }
1131 
1132 // check to see if this player is the one being displayed, and if so, then update the display info
1133 // return 1 if the player was updated
1135 {
1136  // only update if this is the currently active player
1139  return 1;
1140  }
1141  return 0;
1142 }
1143 
1144 // add a player to the list on the player info page
1146 {
1147  // add the item
1148  SendMessage(Player_name_list,CB_ADDSTRING,(WPARAM)0,(LPARAM)(LPCTSTR)p->m_player->callsign);
1149 
1150  // if this is the first item on the list, then select it and display it
1151  if(SendMessage(Player_name_list,CB_GETCOUNT,(WPARAM)0,(LPARAM)0) == 1){
1152  // select the item
1153  SendMessage(Player_name_list,CB_SETCURSEL,(WPARAM)0,(LPARAM)0);
1154 
1155  // display this players info
1157  }
1158 }
1159 
1160 // remove a player from the list on the player info page
1162 {
1163  int loc;
1164 
1165  // lookup thie player
1166  loc = SendMessage(Player_name_list,CB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)(LPCTSTR)p->m_player->callsign);
1167 
1168  // if we found the entry, then delete it
1169  if(loc!=CB_ERR){
1170  SendMessage(Player_name_list,CB_DELETESTRING,(WPARAM)loc,(LPARAM)0);
1171  }
1172 }
1173 
1174 // update the ping display for this player
1176 {
1177  char sml_ping[30];
1178 
1179  // chop it off at pings greater than 1 second
1180  if(p->s_info.ping.ping_avg > 1000){
1181  strcpy_s(sml_ping,XSTR("> 1 sec",914));
1182  }
1183  // use the ping itself
1184  else {
1185  sprintf(sml_ping,"%d",p->s_info.ping.ping_avg);
1186  strcat_s(sml_ping,XSTR(" ms",915));
1187  }
1188 
1189  SetWindowText(Player_ping_time,sml_ping);
1190 }
1191 
1192 // clear the player info page controls
1194 {
1195  int idx;
1196 
1197  // clear the player selection list
1198  SendMessage(Player_name_list,CB_RESETCONTENT,(WPARAM)0,(LPARAM)0);
1199 
1200  // clear out misc items
1201  SetWindowText(Player_ship_type,"");
1202  SetWindowText(Player_ping_time,"");
1203 
1204  // clear out the player stats
1205  for(idx=0;idx<MAX_PLAYER_STAT_FIELDS;idx++){
1206  SetWindowText(Player_stats[idx],"");
1207  SetWindowText(Player_mstats[idx],"");
1208  }
1209 }
1210 
1211 // intialize all the controls in the player info tab
1213 {
1214  // create the player callsign listbox
1215  Player_name_list = GetDlgItem(Page_handles[PLAYER_INFO_PAGE],(int)MAKEINTRESOURCE(IDC_PLAYER_LIST));
1216 
1217  // create the player ship type text box
1218  Player_ship_type = GetDlgItem(Page_handles[PLAYER_INFO_PAGE],(int)MAKEINTRESOURCE(IDC_PSHIP_TYPE));
1219 
1220  // create the player ping time text box
1221  Player_ping_time = GetDlgItem(Page_handles[PLAYER_INFO_PAGE],(int)MAKEINTRESOURCE(IDC_PING_TIME));
1222 
1223  // initialize the various and sundry statistics text controls (alltime)
1224  Player_stats[0] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_SCORE));
1225  Player_stats[1] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_KILL_COUNT));
1226  Player_stats[2] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_KILL_COUNT_BH));
1227  Player_stats[3] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_ASSISTS));
1228  Player_stats[4] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_PSHOTS));
1229  Player_stats[5] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_PHITS));
1230  Player_stats[6] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_PBHHITS));
1231  Player_stats[7] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_PPCT));
1232  Player_stats[8] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_PBHPCT));
1233  Player_stats[9] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_SSHOTS));
1234  Player_stats[10] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_SECHITS));
1235  Player_stats[11] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_SBHHITS));
1236  Player_stats[12] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_SPCT));
1237  Player_stats[13] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_SBHPCT));
1238 
1239  // initialize the various and sundry statistics text controls (this mission)
1240  Player_mstats[0] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MSCORE));
1241  Player_mstats[1] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MKILL_COUNT));
1242  Player_mstats[2] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MKILL_COUNT_BH));
1243  Player_mstats[3] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MASSISTS));
1244  Player_mstats[4] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MPSHOTS));
1245  Player_mstats[5] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MPHITS));
1246  Player_mstats[6] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MPBHHITS));
1247  Player_mstats[7] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MPPCT));
1248  Player_mstats[8] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MPBHPCT));
1249  Player_mstats[9] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MSSHOTS));
1250  Player_mstats[10] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MSECHITS));
1251  Player_mstats[11] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MSBHHITS));
1252  Player_mstats[12] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MSPCT));
1253  Player_mstats[13] = GetDlgItem(Page_handles[PLAYER_INFO_PAGE], (int)MAKEINTRESOURCE(IDC_MSBHPCT));
1254 }
1255 
1256 // returns true or false depending on whether the passed netplayer is the currently selected guy
1258 {
1259  int sel;
1260  char player[40];
1261 
1262  // get the index of the currently selected item
1263  sel = SendMessage(Player_name_list,CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
1264 
1265  // if we didn't find the item, return a 0 length string
1266  if(sel == LB_ERR){
1267  return 0;
1268  }
1269 
1270  // otherwise, get the callsign of the given player
1271  SendMessage(Player_name_list,CB_GETLBTEXT,(WPARAM)sel,(LPARAM)player);
1272 
1273  // if there is a valid player selected and he's the guy we want
1274  return ((player[0] != '\0') && (strcmp(p->m_player->callsign,player) == 0)) ? 1 : 0;
1275 }
1276 
1277 // message handler for the player info tab
1279 {
1280  int val,player_num;
1281  char callsign[40];
1282 
1283  switch(uMsg){
1284  // initialize the dialog
1285  case WM_INITDIALOG:
1286  // set the page handle
1287  Page_handles[PLAYER_INFO_PAGE] = hwndDlg;
1288 
1289  // intialize all the control
1291  return 1;
1292  break;
1293 
1294  // a command message of some kind
1295  case WM_COMMAND:
1296  switch(HIWORD(wParam)){
1297  // a listbox selection change message
1298  case CBN_SELCHANGE :
1299  // get the newly selected item
1300  val = SendMessage(Player_name_list,CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
1301  if(val!=CB_ERR){
1302  // get the callsign
1303  if(SendMessage(Player_name_list,CB_GETLBTEXT,(WPARAM)val,(LPARAM)callsign) != CB_ERR){
1304  // lookup the player
1305  player_num = multi_find_player_by_callsign(callsign);
1306 
1307  // if we found him then display his info
1308  if(player_num != -1){
1310  }
1311  }
1312  }
1313  break;
1314  }
1315  break;
1316 
1317  // a notification message
1318  case WM_NOTIFY :
1319  // set our page to be the active one
1320  if(((LPNMHDR)lParam)->code == PSN_SETACTIVE){
1321  Active_standalone_page = PLAYER_INFO_PAGE;
1322  } else if ( (((LPNMHDR)lParam)->code == PSN_APPLY) || (((LPNMHDR)lParam)->code == PSN_RESET) ) {
1323  PostMessage( Psht, WM_DESTROY, 0, 0 );
1324  }
1325  break;
1326 
1327  default :
1328  return 0;
1329  break;
1330  }
1331  return 0;
1332 }
1333 
1334 
1335 // ---------------------------------------------------------------------------------------
1336 // player god stuff page/tab functions
1337 //
1338 
1339 #define GODSTUFF_MAX_ITEMS 19 // how many items we can fit on the chatbox at one time
1340 
1341 static HWND God_player_list; // the listbox of player callsigns
1342 static HWND Godstuff_fps; // the framerate text box
1343 static HWND Godstuff_broadcast_text; // the text input box for sending messages to players
1344 static HWND Godstuff_broadcast_button; // the button to send the text messages
1345 static HWND Godstuff_player_messages; // handle to the list box containing player chatter
1346 static HDC Godstuff_player_messages_HDC = 0; // DC handle to the list box containing player chatter
1347 
1348 static int Godstuff_longest_message = 0; // longest width of a string in the godstuff list box
1349 
1350 
1351 // initialize all the controls in the godstuff tab
1352 void std_gs_init_godstuff_controls(HWND hwndDlg);
1353 
1354 // add a player to the listbox on the godstuff page
1356 {
1357  // add the item
1358  SendMessage(God_player_list,CB_ADDSTRING,(WPARAM)0,(LPARAM)(LPCTSTR)p->m_player->callsign);
1359 
1360  // if this is the first item on the list, then select it
1361  if(SendMessage(God_player_list,CB_GETCOUNT,(WPARAM)0,(LPARAM)0) == 1){
1362  // select the item
1363  SendMessage(God_player_list,CB_SETCURSEL,(WPARAM)0,(LPARAM)0);
1364  }
1365 }
1366 
1367 // remove a player from the listbox on the godstuff page
1369 {
1370  int loc;
1371 
1372  // lookup the player
1373  loc = SendMessage(God_player_list,CB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)(LPCTSTR)p->m_player->callsign);
1374 
1375  // if we found him, them delete the item
1376  if(loc!=CB_ERR){
1377  SendMessage(God_player_list,CB_DELETESTRING,(WPARAM)loc,(LPARAM)0);
1378  }
1379 }
1380 
1381 // send a message as if the standalone were a player
1383 {
1384  char txt[256];
1385 
1386  // get the text in the edit control
1387  memset(txt,0,256);
1388  txt[0]=120;
1389  SendMessage(Godstuff_broadcast_text,EM_GETLINE,(WPARAM)0,(LPARAM)&txt[0]);
1390 
1391  // if the string is not zero length
1392  if( txt[0] != '\0' ){
1393  // send a game chat packet
1395 
1396  // add the text to our own control
1398 
1399  // clear the text control
1400  SetWindowText(Godstuff_broadcast_text, "");
1401  }
1402 }
1403 
1404 // set the framerate text box for this page
1406 {
1407  char fr[10];
1408 
1409  // set the window text
1410  sprintf(fr,"%.1f",f);
1411  SetWindowText(Godstuff_fps,fr);
1412 }
1413 
1414 // clear the godstuff page controlsv
1416 {
1417  // clear the framerate area
1418  SetWindowText(Godstuff_fps, "0");
1419 
1420  // clear the text area
1421  SetWindowText(Godstuff_broadcast_text,"");
1422 
1423  // reset the combo box
1424  SendMessage(God_player_list, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
1425 
1426  // clear the player chatter listbox
1427  SendMessage(Godstuff_player_messages, LB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
1428 }
1429 
1430 // initialize all the controls in the godstuff tab
1432 {
1433  // initialize the player listbox control
1434  God_player_list = GetDlgItem(Page_handles[GODSTUFF_PAGE], (int)MAKEINTRESOURCE(IDC_PLAYER_GOD_LIST));
1435 
1436  // initialize the framerate text box
1437  Godstuff_fps = GetDlgItem(Page_handles[GODSTUFF_PAGE], (int)MAKEINTRESOURCE(IDC_GODSTUFF_FPS));
1438 
1439  // initialize the messaging edit control
1440  Godstuff_broadcast_text = GetDlgItem(Page_handles[GODSTUFF_PAGE], (int)MAKEINTRESOURCE(IDC_GODSTUFF_BROADCAST));
1441  SendMessage(Godstuff_broadcast_text, EM_SETLIMITTEXT, (WPARAM)CHATBOX_MAX_LEN, (LPARAM)0);
1442  SendMessage(Godstuff_broadcast_text, EM_FMTLINES, (WPARAM)TRUE, (LPARAM)0);
1443 
1444  // create the player chatter list box
1445  Godstuff_player_messages = GetDlgItem(Page_handles[GODSTUFF_PAGE], (int)MAKEINTRESOURCE(IDC_GOD_CHAT));
1446  // we'll need a DC for player messages as well
1447  if (!Godstuff_player_messages_HDC)
1448  Godstuff_player_messages_HDC = GetDC(Godstuff_player_messages);
1449  // and set/rest the string with tracker too
1450  Godstuff_longest_message = 0;
1451 
1452  // initialize the message broadcast button
1453  Godstuff_broadcast_button = GetDlgItem(Page_handles[GODSTUFF_PAGE], (int)MAKEINTRESOURCE(IDC_GODSTUFF_SENDMESS));
1454  // hide the button -- we can now process return key
1455  ShowWindow(Godstuff_broadcast_button, SW_HIDE);
1456 
1457 }
1458 
1459 // message handler for the godstuff tab
1461 {
1462  switch (uMsg)
1463  {
1464  // initialize the dialog
1465  case WM_INITDIALOG:
1466  {
1467  // setup the page handle
1468  Page_handles[GODSTUFF_PAGE] = hwndDlg;
1469 
1470  // initialize the controls for this page
1472 
1473  return 1;
1474  }
1475  break;
1476 
1477  // destroy the dialog
1478  case WM_DESTROY:
1479  {
1480  if (Godstuff_player_messages_HDC) {
1481  ReleaseDC(Godstuff_player_messages, Godstuff_player_messages_HDC);
1482  }
1483  }
1484  break;
1485 
1486  // a notification message
1487  case WM_NOTIFY:
1488  {
1489  // set this page to be the currently active one
1490  if(((LPNMHDR)lParam)->code == PSN_SETACTIVE){
1491  Active_standalone_page = GODSTUFF_PAGE;
1492  } else if ( (((LPNMHDR)lParam)->code == PSN_APPLY) || (((LPNMHDR)lParam)->code == PSN_RESET) ) {
1493  PostMessage( Psht, WM_DESTROY, 0, 0 );
1494  }
1495  }
1496  break;
1497 
1498 
1499  // a command message of some kind
1500  case WM_COMMAND:
1501  {
1502  switch ( HIWORD(wParam) )
1503  {
1504  // a button click
1505  case BN_CLICKED:
1506  switch ( LOWORD(wParam) )
1507  {
1508  // send the message to the player
1509  case IDC_GODSTUFF_SENDMESS:
1511  break;
1512  }
1513 
1514  break;
1515  }
1516  }
1517  break;
1518 
1519  default:
1520  return 0;
1521  break;
1522  }
1523 
1524  return 0;
1525 }
1526 
1527 
1528 // ---------------------------------------------------------------------------------------
1529 // debug page/tab functions
1530 //
1531 
1532 static HWND Standalone_state_string; // the text control box
1533 static HWND Standalone_multilog_string = NULL;
1534 
1535 // initialize the controls for the debug page
1536 void std_debug_init_debug_controls(HWND hwndDlg);
1537 
1538 // set the text on the standalones state indicator box
1540 {
1541  // set the text
1542  SetWindowText(Standalone_state_string,str);
1543 }
1544 
1545 void std_debug_multilog_add_line(const char *str)
1546 {
1547  SCP_string log_str;
1548 
1549  if ( !str || !strlen(str) ) {
1550  return;
1551  }
1552 
1553  if (Standalone_multilog_string == NULL) {
1554  return;
1555  }
1556 
1557  log_str = str;
1558 
1559  // parse the string, adding each new line to the list
1560  size_t nline = log_str.find('\n');
1561 
1562  while (nline != SCP_string::npos) {
1563  log_str[nline] = '\0';
1564 
1565  SendMessage(Standalone_multilog_string, LB_ADDSTRING, 0, (LPARAM)log_str.c_str());
1566 
1567  // reset our width, using best guess, so that we have a working hscroll
1568  uint h_size = SendMessage(Standalone_multilog_string, LB_GETHORIZONTALEXTENT, 0, 0);
1569 
1570  if ( (h_size / 6) < log_str.size() ) {
1571  SendMessage(Standalone_multilog_string, LB_SETHORIZONTALEXTENT, log_str.size() * 6, 0);
1572  }
1573 
1574  // remove excess lines, if needed
1575  int l_count = SendMessage(Standalone_multilog_string, LB_GETCOUNT, 0, 0);
1576 
1577  if ( (l_count > 0) && (l_count >= 100) ) {
1578  SendMessage(Standalone_multilog_string, LB_DELETESTRING, 0, 0);
1579  }
1580 
1581  // move to next newline, if there is one
1582  log_str.erase(0, nline+1);
1583  nline = log_str.find('\n');
1584 
1585  // skip single newline at end, if it exists
1586  if ( (nline+1) == log_str.size() ) {
1587  break;
1588  }
1589  }
1590 }
1591 
1592 // clear the debug page controls
1594 {
1595  // set the current debug state
1597 }
1598 
1599 // initialize the controls for the debug page
1601 {
1602  // create the state string text box
1603  Standalone_state_string = GetDlgItem(hwndDlg,(int)MAKEINTRESOURCE(IDC_STANDALONE_STATE));
1604 
1605  // standalone state indicator
1606  SetWindowText(Standalone_state_string,"");
1607 
1608  // do the multi-log string too
1609  Standalone_multilog_string = GetDlgItem(hwndDlg, (int)MAKEINTRESOURCE(IDC_MULTILOG));
1610  SendMessage(Standalone_multilog_string, LB_RESETCONTENT, 0, 0);
1611 }
1612 
1613 // message handler for the godstuff tab
1615 {
1616  switch(uMsg){
1617  // initialize the dialog
1618  case WM_INITDIALOG:
1619  // setup the page handle
1620  Page_handles[DEBUG_PAGE] = hwndDlg;
1621 
1622  // intialize the controls for this page
1624  return 1;
1625  break;
1626 
1627  // a notification message
1628  case WM_NOTIFY :
1629  // set the currently active page to this one
1630  if(((LPNMHDR)lParam)->code == PSN_SETACTIVE){
1631  Active_standalone_page = DEBUG_PAGE;
1632  } else if ( (((LPNMHDR)lParam)->code == PSN_APPLY) || (((LPNMHDR)lParam)->code == PSN_RESET) ) {
1633  Standalone_multilog_string = NULL;
1634  PostMessage( Psht, WM_DESTROY, 0, 0 );
1635  }
1636  break;
1637 
1638  default :
1639  return 0;
1640  break;
1641  }
1642  return 0;
1643 }
1644 
1645 
1646 // ---------------------------------------------------------------------------------------
1647 // general functions
1648 //
1649 
1650 // add a player and take care of updating all gui/data details
1652 {
1653  char ip_string[60];
1654 
1655  // get his ip string and add it to the list
1656  psnet_addr_to_string(ip_string,&p->p_info.addr);
1657  std_connect_add_ip_string(ip_string);
1658 
1659  // add to the player info player list box, and update his info
1662 
1663  // add to the god stuff player list box
1665 
1666  // check to see if this guy is the host.
1668 
1669  // set the connection count
1671 }
1672 
1673 // remove a player and take care of updateing all gui/data details
1675 {
1676  int count;
1677  char ip_string[60];
1678 
1679  // determine his ip string and remove it from the list
1680  psnet_addr_to_string(ip_string,&p->p_info.addr);
1681  std_connect_remove_ip_string(ip_string);
1682 
1683  // remove from the player info player list box
1685 
1686  // remove from the godstuff list box
1688 
1689  // update the host connect count
1691 
1692  // update the currently connected players
1694 
1695  if(count == 0){
1696  // multi_standalone_quit_game();
1698  return 1;
1699  }
1700 
1701  return 0;
1702 }
1703 
1704 // set any relevant controls which display the framerate of the standalone
1705 void std_set_standalone_fps(float fps)
1706 {
1707  // set the framerate in the multiplayer dialog
1709 
1710  // set the framerate in the godstuff dialog
1711  std_gs_set_framerate(fps);
1712 }
1713 
1714 // update any relveant controls which display the ping for the given player
1716 {
1717  // update the ping on the connect page
1719 
1720  // update the ping on the player info page
1722 }
1723 
1724 // reset everything in the standalone gui (all the controls)
1726 {
1727  // clear the connect page controls
1729 
1730  // clear the multi page controls
1732 
1733  // clear the player info page controls
1735 
1736  // clear the godstuff page controls
1738 
1739  // clear the debug page controls
1741 
1742  // set all framerate displays to 0
1743  std_set_standalone_fps((float)0);
1744 
1745  // set the mission time
1747 
1748  // reset the stats update timestamp
1750 
1751  // reset the netgame info timestamp
1752  Standalone_ng_stamp = -1;
1753 }
1754 
1755 // do any gui related issues on the standalone (like periodically updating player stats, etc...)
1756 // notify the user that the standalone has failed to login to the tracker on startup
1758 {
1759 }
1760 
1762 {
1763  int idx;
1764 
1765  // check to see if the timestamp for updating player selected stats has popped
1767  // reset the timestamp
1769 
1770  // update any player currently selected
1771  // there's probably a nicer way to do this, but...
1772  for(idx=0;idx<MAX_PLAYERS;idx++){
1773  if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx])){
1775  break;
1776  }
1777  }
1778  }
1779  }
1780 
1781  // check to see if the timestamp for updating the netgame information controls has popped
1783  // reset the timestamp
1785 
1786  // update the controls
1788  }
1789 }
1790 
1791 
1792 
1793 // attempt to log the standalone into the tracker
1795 {
1796 }
1797 
1798 // reset all stand gui timestamps
1800 {
1801  // reset the stats update stamp
1803 
1804  // reset the netgame controls update timestamp
1806 }
1807 
1808 // add a line of text chat to the standalone
1809 void std_add_chat_text(const char *text,int player_index,int add_id)
1810 {
1811  int num_items,ret_val;
1812  char format[512];
1813  SIZE text_size = { 0, 0 };
1814 
1815  // invalid player ?
1816  if (player_index == -1)
1817  return;
1818 
1819  // format the chat text nicely
1820  if (add_id) {
1821  if ( MULTI_STANDALONE(Net_players[player_index]) ) {
1822  sprintf(format, XSTR("<SERVER> %s", 924), text);
1823  } else {
1824  sprintf(format, "%s: %s", Net_players[player_index].m_player->callsign, text);
1825  }
1826  } else {
1827  strcpy_s(format, text);
1828  }
1829 
1830  // this thing isn't all that accurate, it typically produces a longer line, but I don't really care :p
1831  if (Godstuff_player_messages_HDC)
1832  GetTextExtentPoint32(Godstuff_player_messages_HDC, format, strlen(format), &text_size);
1833 
1834  if (Godstuff_longest_message < text_size.cx)
1835  Godstuff_longest_message = (int)text_size.cx;
1836 
1837  SendMessage(Godstuff_player_messages, LB_SETHORIZONTALEXTENT, (WPARAM)Godstuff_longest_message, (LPARAM)0);
1838 
1839  // this thing isn't all that accurate, it typically produces a longer line, but I don't really care :p
1840  if (Godstuff_player_messages_HDC)
1841  GetTextExtentPoint32(Godstuff_player_messages_HDC, format, strlen(format), &text_size);
1842 
1843  if (Godstuff_longest_message < text_size.cx)
1844  Godstuff_longest_message = (int)text_size.cx;
1845 
1846  SendMessage(Godstuff_player_messages, LB_SETHORIZONTALEXTENT, (WPARAM)Godstuff_longest_message, (LPARAM)0);
1847 
1848  // insert the text string into the godstuff chat box and scroll it down to the bottom
1849  SendMessage(Godstuff_player_messages, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)format);
1850 
1851  num_items = SendMessage(Godstuff_player_messages, LB_GETCOUNT, (WPARAM)0, (LPARAM)0);
1852 
1853  if (num_items > 19) {
1854  ret_val = SendMessage(Godstuff_player_messages, LB_SETTOPINDEX, (WPARAM)num_items - GODSTUFF_MAX_ITEMS, (LPARAM)0);
1855  }
1856 }
1857 
1858 // if the standalone is host password protected
1860 {
1861  return (Multi_options_g.std_passwd[0] != '\0') ? 1 : 0;
1862 }
1863 
1864 // change the default property sheet interface into something more useful
1866 {
1867  HWND ok_button = NULL;
1868  HWND cancel_button = NULL;
1869  HWND apply_button = NULL;
1870  HWND help_button = NULL;
1871  char lookup[512];
1872 
1873  // get the buttons on the property sheet itself
1874  HWND child = GetWindow(Psht,GW_CHILD);
1875  while(child != NULL){
1876  // get the text of the window
1877  memset(lookup,0,512);
1878  GetWindowText(child,lookup,511);
1879 
1880  // if its the OK button
1881  if(!stricmp(lookup,XSTR("ok",925))){
1882  ok_button = child;
1883  }
1884 
1885  // if its the cancel button
1886  if(!stricmp(lookup,XSTR("cancel",926))){
1887  cancel_button = child;
1888  }
1889 
1890  // if its the apply button
1891  if(!stricmp(lookup,XSTR("&apply",927))){
1892  apply_button = child;
1893  }
1894 
1895  // if its the help button
1896  if(!stricmp(lookup,XSTR("help",928))){
1897  help_button = child;
1898  }
1899 
1900  child = GetWindow(child,GW_HWNDNEXT);
1901  }
1902 
1903  // kill em all
1904  if(apply_button != NULL){
1905  DestroyWindow(apply_button);
1906  }
1907 
1908  // rename the shutdown button and move it over a bit
1909  if(ok_button != NULL){
1910  // set the text
1911  SetWindowText(ok_button,XSTR("Shutdown",929));
1912 
1913  // move it
1914  SetWindowPos(ok_button,
1915  HWND_TOP,
1916  Std_shutdown_coords[gr_screen.res][0],
1917  Std_shutdown_coords[gr_screen.res][1],
1918  0,0,
1919  SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER
1920  );
1921  }
1922 
1923  // kill em all
1924  if(cancel_button != NULL){
1925  DestroyWindow(cancel_button);
1926  }
1927 
1928  // kill em all
1929  if(help_button != NULL){
1930  DestroyWindow(help_button);
1931  }
1932 
1933  // now we want to mess with the titlebar controls
1934 }
1935 
1936 // if the given callsign is banned from the server
1937 int std_player_is_banned(const char *name)
1938 {
1939  int idx;
1940 
1941  // go through the ban list
1942  for(idx=0;idx<Standalone_ban_count;idx++){
1943  if(!stricmp(name,Standalone_ban_list[idx])){
1944  return 1;
1945  }
1946  }
1947 
1948  // not banned
1949  return 0;
1950 }
1951 
1952 // add a callsign to the ban list
1953 void std_add_ban(const char *name)
1954 {
1955  // if we've reached the max bans
1957  return;
1958  }
1959 
1960  // otherwise add it
1962  strcpy_s(Standalone_ban_list[Standalone_ban_count++],name);
1963 }
1964 
1965 
1966 // -------------------------------------------------------------------------------
1967 // property sheet/page creation and handling
1968 //
1969 
1971 {
1972  PROPSHEETPAGE *p;
1973 
1974  // connect tab
1975  p = &Pages[CONNECT_PAGE];
1976  p->dwSize = sizeof(PROPSHEETPAGE);
1977  p->dwFlags = PSP_DEFAULT;
1978  p->hInstance = GetModuleHandle(NULL);
1979  p->pszTemplate = MAKEINTRESOURCE(IDD_CONNECT);
1980  p->pszIcon = NULL;
1981  p->pfnDlgProc = (DLGPROC)connect_proc;
1982  p->pszTitle = XSTR("Connections",930);
1983  p->lParam = 0;
1984  p->pfnCallback = NULL;
1985 
1986  // multiplayer tab
1987  p = &Pages[MULTIPLAYER_PAGE];
1988  p->dwSize = sizeof(PROPSHEETPAGE);
1989  p->dwFlags = PSP_DEFAULT;
1990  p->hInstance = GetModuleHandle(NULL);
1991  p->pszTemplate = MAKEINTRESOURCE(IDD_MULTI);
1992  p->pszIcon = NULL;
1993  p->pfnDlgProc = (DLGPROC)multi_proc;
1994  p->pszTitle = XSTR("Multi-Player",931);
1995  p->lParam = 0;
1996  p->pfnCallback = NULL;
1997 
1998  // player tab
1999  p = &Pages[PLAYER_INFO_PAGE];
2000  p->dwSize = sizeof(PROPSHEETPAGE);
2001  p->dwFlags = PSP_DEFAULT;
2002  p->hInstance = GetModuleHandle(NULL);
2003  p->pszTemplate = MAKEINTRESOURCE(IDD_PLAYER_DIALOG);
2004  p->pszIcon = NULL;
2005  p->pfnDlgProc = (DLGPROC)player_info_proc;
2006  p->pszTitle = XSTR("Player info",932);
2007  p->lParam = 0;
2008  p->pfnCallback = NULL;
2009 
2010  // godstuff tab
2011  p = &Pages[GODSTUFF_PAGE];
2012  p->dwSize = sizeof(PROPSHEETPAGE);
2013  p->dwFlags = PSP_DEFAULT;
2014  p->hInstance = GetModuleHandle(NULL);
2015  p->pszTemplate = MAKEINTRESOURCE(IDD_GODSTUFF);
2016  p->pszIcon = NULL;
2017  p->pfnDlgProc = (DLGPROC)godstuff_proc;
2018  p->pszTitle = XSTR("God Stuff",933);
2019  p->lParam = 0;
2020  p->pfnCallback = NULL;
2021 
2022  // debug tab
2023  p = &Pages[DEBUG_PAGE];
2024  p->dwSize = sizeof(PROPSHEETPAGE);
2025  p->dwFlags = PSP_DEFAULT;
2026  p->hInstance = GetModuleHandle(NULL);
2027  p->pszTemplate = MAKEINTRESOURCE(IDD_DEBUG_DIALOG);
2028  p->pszIcon = NULL;
2029  p->pfnDlgProc = (DLGPROC)debug_proc;
2030  p->pszTitle = XSTR("Debug",934);
2031  p->lParam = 0;
2032  p->pfnCallback = NULL;
2033 }
2034 
2035 // build a title string
2036 void std_build_title_string(char *str)
2037 {
2038  char temp[256];
2039  char ver_str[15];
2040 
2041  // build the version #
2042  memset(ver_str, 0, sizeof(ver_str));
2043 
2044  if (FS_VERSION_BUILD == 0 && FS_VERSION_REVIS == 0) { //-V547
2045  snprintf(ver_str, sizeof(ver_str)-1, "%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR);
2046  } else if (FS_VERSION_REVIS == 0) {
2047  snprintf(ver_str, sizeof(ver_str)-1, "%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
2048  } else {
2049  snprintf(ver_str, sizeof(ver_str)-1, "%i.%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD, FS_VERSION_REVIS);
2050  }
2051 
2052  // now build the title
2053  memset(temp, 0, 256);
2054 
2055  snprintf(temp, sizeof(temp)-1, "%s %s", XSTR("FreeSpace Standalone", 935), ver_str);
2056 
2057  // output first part
2058  strcpy(str, temp);
2059 }
2060 
2061 // initialize the property sheet itself
2063 {
2064  LONG styles;
2065 
2066  // initialize the property pages
2068 
2069  // create the property sheet
2070  Sheet.dwSize = sizeof(PROPSHEETHEADER);
2071  Sheet.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS | PSH_NOAPPLYNOW;
2072  Sheet.hwndParent = hwndDlg;
2073  Sheet.hInstance = GetModuleHandle(NULL);
2074  Sheet.nPages = MAX_STANDALONE_PAGES;
2075 
2076  // set the title bar appropriately
2077  memset(title_str, 0, 512);
2079  Sheet.pszCaption = title_str;
2080 
2081  Sheet.nStartPage = 0;
2082  Sheet.ppsp = &Pages[0];
2083  Sheet.pfnCallback = NULL;
2084  Psht = (HWND)PropertySheet(&Sheet);
2085 
2086  // set the window style to include a minimize button
2087  styles = GetWindowLong(Psht, GWL_STYLE );
2088  if ( styles != 0 ) {
2089  SetWindowLong(Psht, GWL_STYLE, styles | WS_MINIMIZEBOX);
2090  }
2091 
2092  styles = GetWindowLong(Psht, GWL_EXSTYLE );
2093  if ( styles != 0 ) {
2094  SetWindowLong( Psht, GWL_EXSTYLE, (styles & ~WS_EX_CONTEXTHELP) );
2095  }
2096 
2098 
2099  // change the default property sheet interface into something more useful
2100  std_mutate_sheet();
2101 
2102  // return a handle to this property sheet
2103  return Psht;
2104 }
2105 
2106 static HMENU std_create_systray_menu()
2107 {
2108  char tstr[64];
2109  memset(tstr, 0, sizeof(tstr));
2110 
2111  HMENU stdPopup = CreatePopupMenu();
2112 
2113  // Type of connection:
2114  snprintf(tstr, sizeof(tstr)-1, "Connection Type: %s", MULTI_IS_TRACKER_GAME ? "FS2NetD" : "Local/IP");
2115  AppendMenu(stdPopup, MF_STRING | MF_GRAYED, 0, tstr);
2116 
2117  // Status of FS2NetD connection:
2118  if (MULTI_IS_TRACKER_GAME) {
2119  snprintf(tstr, sizeof(tstr)-1, "FS2NetD Status: %s", fs2netd_is_online() ? "Online" : "Offline");
2120  AppendMenu(stdPopup, MF_STRING | MF_GRAYED, 0, tstr);
2121  }
2122 
2123  // ----------------------------------------------
2124  AppendMenu(stdPopup, MF_SEPARATOR, 0, NULL);
2125 
2126  // Game name:
2127  snprintf(tstr, sizeof(tstr)-1, "Name: %s", Netgame.name);
2128  AppendMenu(stdPopup, MF_STRING | MF_GRAYED, 0, tstr);
2129 
2130  // Mission name:
2131  snprintf(tstr, sizeof(tstr)-1, "Mission: %s", strlen(Netgame.mission_name) ? Netgame.mission_name : "<none>");
2132  AppendMenu(stdPopup, MF_STRING | MF_GRAYED, 0, tstr);
2133 
2134  // Number of players:
2135  snprintf(tstr, sizeof(tstr)-1, "Num Players: %d", multi_num_players());
2136  AppendMenu(stdPopup, MF_STRING | MF_GRAYED, 0, tstr);
2137 
2138  // ----------------------------------------------
2139  AppendMenu(stdPopup, MF_SEPARATOR, 0, NULL);
2140 
2141  // Reset All (main window command):
2142  AppendMenu(stdPopup, MF_STRING, STP_RESET_ALL, "Reset All");
2143 
2144  // Reset FS2NetD (not a main window command, yet):
2145  if (MULTI_IS_TRACKER_GAME) {
2146  AppendMenu(stdPopup, MF_STRING, STP_RESET_FS2NETD, "Reset FS2NetD");
2147  }
2148 
2149  // Shutdown server (main window command):
2150  AppendMenu(stdPopup, MF_STRING, STP_SHUTDOWN, "Shutdown");
2151 
2152  // ----------------------------------------------
2153  AppendMenu(stdPopup, MF_SEPARATOR, 0, NULL);
2154 
2155  // Show standalone window (set as default):
2156  AppendMenu(stdPopup, MF_STRING, STP_SHOW, "Show Window");
2157  SetMenuDefaultItem(stdPopup, STP_SHOW, FALSE);
2158 
2159  return stdPopup;
2160 }
2161 
2163 {
2164  switch (uMsg) {
2165  case WM_SYSCOMMAND: {
2166  if (wParam == SC_MINIMIZE) {
2167  standalone_do_systray(ST_MODE_CREATE);
2168  return TRUE;
2169  } else if (wParam == SC_RESTORE) {
2170  standalone_do_systray(ST_MODE_REMOVE);
2171  return TRUE;
2172  }
2173 
2174  break;
2175  }
2176 
2177  case MSG_SYSTRAYICON: {
2178  if (lParam == WM_LBUTTONDBLCLK) {
2179  standalone_do_systray(ST_MODE_REMOVE);
2180  return TRUE;
2181  } else if (lParam == WM_RBUTTONUP) {
2182  HMENU stdPopup = std_create_systray_menu();
2183 
2184  POINT cur_pos;
2185  GetCursorPos(&cur_pos);
2186 
2187  SetForegroundWindow(Standalone_hwnd);
2188 
2189  int choice = TrackPopupMenuEx(stdPopup, TPM_RETURNCMD | TPM_NONOTIFY, cur_pos.x, cur_pos.y, Standalone_hwnd, NULL);
2190 
2191  SendMessage(Standalone_hwnd, WM_NULL, 0, 0);
2192 
2193  DestroyMenu(stdPopup);
2194 
2195  // reset all (does not include fs2netd!)
2196  if (choice == STP_RESET_ALL) {
2198  }
2199  // reset fs2netd
2200  else if (choice == STP_RESET_FS2NETD) {
2202  }
2203  // shutdown
2204  else if (choice == STP_SHUTDOWN) {
2205  PostMessage(Psht, WM_DESTROY, 0, 0);
2206  }
2207  // restore window
2208  else if (choice == STP_SHOW) {
2209  SendMessage(Standalone_hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
2210  }
2211 
2212  return TRUE;
2213  }
2214 
2215  break;
2216  }
2217 
2218  case WM_CLOSE:
2219  PostMessage(Psht, WM_DESTROY, 0, 0);
2220  return TRUE;
2221 
2222  default:
2223  return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
2224  }
2225 
2226  return FALSE;
2227 }
2228 
2229 extern int Lighting_flag;
2230 
2232 {
2233  // create a hidden window that will process basic events for us (for the systray icon mainly)
2234  WNDCLASSEX wclass; // Huh?
2235  HINSTANCE hInst = GetModuleHandle(NULL);
2236 
2237  memset( &wclass, 0, sizeof(WNDCLASSEX) );
2238 
2239  wclass.hInstance = hInst;
2240  wclass.lpszClassName = "FS2StandaloneClass";
2241  wclass.lpfnWndProc = (WNDPROC)std_message_handler_proc;
2242  wclass.style = CS_OWNDC;
2243  wclass.cbSize = sizeof(WNDCLASSEX);
2244  wclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICON) );
2245  wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
2246  wclass.lpszMenuName = NULL;
2247  wclass.cbClsExtra = 0;
2248  wclass.cbWndExtra = 0;
2249  wclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
2250 
2251  if ( !RegisterClassEx(&wclass) ) {
2252  return FALSE;
2253  }
2254 
2255  Standalone_hwnd = CreateWindowEx(0, "FS2StandaloneClass", "FreeSpace2 Standalone",
2256  WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
2257  NULL, NULL, hInst, NULL);
2258 
2259  // create the propery sheet dialog itself
2261 
2262  // this is kind of a big-ass hack. But here's what it does. Property sheets only
2263  // initialize their individual pages the first time (and ONLY the first time) they
2264  // are selected. So before any of this happens, their control handles are bogus. So,
2265  // by calling PropSheet_SetCurSel for all the pages, WM_INITDIALOG is sent to all of
2266  // them, and their controls become valid. However, its kind of silly because each
2267  // page will blink into existence for a second. I can't see another way arount this
2268  // problem.
2269  int idx;
2270  for(idx=MAX_STANDALONE_PAGES-1;idx>=0;idx--){
2271  PropSheet_SetCurSel(Psht,(HPROPSHEETPAGE)&Pages[idx],idx);
2272  }
2273 
2274 // main_window_inited = 1;
2275 
2276  // turn off lighting effects
2277  Lighting_flag = 0;
2278 
2279  // turn off all sound and music
2282 
2283  // reset all standalone gui items
2285 
2286  // initialize the debug outwindow
2287 #ifndef NDEBUG
2288  outwnd_init();
2289 #endif
2290 
2291  Standalone_minimized = FALSE;
2292 
2293  return TRUE;
2294 }
2295 
2296 static void standalone_do_systray(int mode)
2297 {
2298  NOTIFYICONDATA nid;
2299  RECT stdRect;
2300  RECT trayRect;
2301 
2302  memset(&nid, 0, sizeof(nid));
2303 
2304  nid.cbSize = sizeof(nid);
2305  nid.hWnd = Standalone_hwnd;
2306  nid.uID = 999;
2307  nid.uCallbackMessage = MSG_SYSTRAYICON;
2308  nid.hIcon = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APP_ICON) );
2309  strncpy(nid.szTip, Netgame.name, sizeof(nid.szTip));
2310  nid.uFlags = (NIF_MESSAGE | NIF_ICON | NIF_TIP);
2311 
2312  if (mode == ST_MODE_CREATE) {
2313  if (Standalone_minimized) {
2314  return;
2315  }
2316 
2317  // add icon
2318  Shell_NotifyIcon(NIM_ADD, &nid);
2319 
2320  // do a window minimize animation
2321  GetWindowRect(GetDesktopWindow(), &trayRect);
2322  GetWindowRect(Psht, &stdRect);
2323 
2324  trayRect.left = trayRect.right;
2325  trayRect.top = trayRect.bottom;
2326 
2327  DrawAnimatedRects(Psht, IDANI_CAPTION, &stdRect, &trayRect);
2328 
2329  // hide the property sheet window
2330  ShowWindow(Psht, SW_HIDE);
2331  Standalone_minimized = TRUE;
2332  } else if (mode == ST_MODE_UPDATE) {
2333  if ( !Standalone_minimized ) {
2334  return;
2335  }
2336 
2337  Shell_NotifyIcon(NIM_MODIFY, &nid);
2338  } else if (mode == ST_MODE_REMOVE) {
2339  if ( !Standalone_minimized ) {
2340  return;
2341  }
2342 
2343  Shell_NotifyIcon(NIM_DELETE, &nid);
2344  ShowWindow(Psht, SW_RESTORE);
2345  SetForegroundWindow(Psht);
2346  Standalone_minimized = FALSE;
2347  }
2348 }
2349 
2350 // just like the osapi version for the nonstandalone mode of FreeSpace
2352 {
2353  MSG msg;
2354 
2356  return 0;
2357 
2358  while (1) {
2359 #if 0
2360  if(PropSheet_GetCurrentPageHwnd(Psht)==NULL){
2361  mprintf(("prop sheet is destroyed -- exiting\n"));
2362  DestroyWindow(Psht);
2363  PostQuitMessage(0);
2364  os_close();
2366  break;
2367  }
2368 #endif
2369  if ( WaitMessage() ) {
2370  while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) {
2371  // if the dialog should be destroyed, then exit.
2372  if ( msg.message == WM_DESTROY ) {
2373  standalone_do_systray(ST_MODE_REMOVE); // shouldn't be needed, but make sure it's gone
2374  DestroyWindow(Psht);
2375  DestroyWindow(Standalone_hwnd);
2376  PostQuitMessage(0);
2378  return 0;
2379  }
2380 
2381  // maybe the minimize button got hit
2382  if ( (msg.message == WM_NCLBUTTONDOWN) && (msg.wParam == HTMINBUTTON) ) {
2383  standalone_do_systray(ST_MODE_CREATE);
2384  continue;
2385  }
2386 
2387  // see if the message is destined for the edit control, and what the message is.
2388  // intercept if a return
2389  if ( msg.hwnd == Godstuff_broadcast_text ) {
2390  int virt_key;
2391 
2392  virt_key = (int)msg.wParam;
2393  if ( (msg.message == WM_KEYDOWN) && (virt_key == VK_RETURN) ) {
2395  continue;
2396  }
2397  }
2398 
2399  if ( !PropSheet_IsDialogMessage(Psht, &msg) ) {
2400  TranslateMessage(&msg);
2401  DispatchMessage(&msg);
2402  }
2403  }
2404  }
2405  }
2406  return 0;
2407 }
2408 
2410 {
2412 }
2413 
2414 
2415 // called when freespace initialized
2417 {
2418  // start the main thread
2419  Standalone_thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)standalone_process, NULL, 0, &Standalone_thread_id );
2420 
2421  // set the close functions
2422  atexit(std_deinit_standalone);
2423 }
2424 
2425 // called when freespace closes
2427 {
2428  if (Standalone_thread) {
2429  CloseHandle(Standalone_thread);
2430  Standalone_thread = NULL;
2431  }
2432 }
2433 
2434 #endif // !SCP_UNIX
#define GODSTUFF_PAGE
Definition: stand_gui.cpp:81
void std_connect_clear_controls()
Definition: stand_gui.cpp:359
#define STD_NG_UPDATE_TIME
Definition: stand_gui.cpp:69
GLenum GLsizei GLenum format
Definition: Gl.h:1509
#define IDD_GODSTUFF
#define IDC_MPPCT
uint respawn
Definition: multi.h:507
int timestamp(int delta_ms)
Definition: timer.cpp:226
void multi_update_valid_missions()
Definition: multiutil.cpp:3041
void * HWND
Definition: config.h:104
#define MY_NET_PLAYER_NUM
Definition: multi.h:127
#define IDC_PBHHITS
#define IDC_PHITS
int kill_count_ok
Definition: scoring.h:90
HWND Multi_std_host_passwd
Definition: stand_gui.cpp:197
void fs2netd_gameserver_start()
void std_do_gui_frame()
Definition: stand_gui.cpp:1761
void std_add_player(net_player *p)
Definition: stand_gui.cpp:1651
#define IDC_FIELD3
int cf_delete(const char *filename, int path_type)
Delete the specified file.
Definition: cfile.cpp:483
#define BONUS_GOAL
Definition: missiongoals.h:30
#define IDC_MSCORE
#define IDC_KICK_BUTTON
int ship_class
Definition: multi.h:451
void std_connect_handle_name_change()
Definition: stand_gui.cpp:407
int Cmdline_freespace_no_music
Definition: cmdline.cpp:271
#define IDC_FIELD1
void std_connect_set_host_connect_status()
Definition: stand_gui.cpp:235
void outwnd_init(int display_under_freespace_window)
Definition: outwnd.cpp:1165
Definition: config.h:286
#define MAX_PLAYER_STAT_FIELDS
Definition: stand_gui.cpp:1062
void std_debug_clear_controls()
Definition: stand_gui.cpp:1593
net_player * Net_player
Definition: multi.cpp:94
#define DEBUG_PAGE
Definition: stand_gui.cpp:82
#define IDB_GOAL_NONE
#define IDD_DEBUG_DIALOG
GLuint index
Definition: Glext.h:5608
player * m_player
Definition: multi.h:459
void std_gs_init_godstuff_controls(HWND hwndDlg)
Definition: stand_gui.cpp:1431
int security
Definition: multi.h:499
void std_tracker_login()
Definition: stand_gui.cpp:1794
HANDLE Standalone_thread
Definition: stand_gui.cpp:43
#define IDI_APP_ICON
int std_gen_is_active()
Definition: stand_gui.cpp:188
#define IDD_MULTI
#define MULTI_STANDALONE(np)
Definition: multi.h:139
void std_init_property_pages()
Definition: stand_gui.cpp:1970
#define IDC_MPBHPCT
#define STP_RESET_FS2NETD
Definition: stand_gui.cpp:60
#define STD_ADDSTRING(hwnd, val)
Definition: stand_gui.cpp:1070
void * HINSTANCE
Definition: config.h:105
BOOL CALLBACK player_info_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:1278
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
#define mprintf(args)
Definition: pstypes.h:238
#define MULTI_VALID_MISSION_FILE
Definition: multi.h:40
void std_multi_update_goals()
Definition: stand_gui.cpp:756
int std_connect_set_connect_count()
Definition: stand_gui.cpp:204
unsigned int mp_shots_fired
Definition: scoring.h:117
int res
Definition: 2d.h:370
void std_notify_tracker_login_fail()
Definition: stand_gui.cpp:1757
int Standalone_ban_count
Definition: stand_gui.cpp:102
#define CHATBOX_MAX_LEN
Definition: chatbox.h:18
unsigned int mp_bonehead_hits
Definition: scoring.h:121
#define IDC_MPSHOTS
#define FS_VERSION_MAJOR
Definition: version.h:37
GLclampf f
Definition: Glext.h:7097
void os_init_registry_stuff(const char *company, const char *app, const char *version)
Definition: osregistry.cpp:423
#define MULTI_HOST(np)
Definition: multi.h:137
#define TRUE
Definition: pstypes.h:399
#define IDC_HOST_IS
void std_debug_multilog_add_line(const char *str)
Definition: stand_gui.cpp:1545
#define PRIMARY_GOAL
Definition: missiongoals.h:28
int kill_count
Definition: scoring.h:89
int Standalone_ng_stamp
Definition: stand_gui.cpp:97
UINT WPARAM wParam
Definition: msacm.h:1064
void fs2netd_gameserver_disconnect()
#define IDC_STD_HOST_PASSWD
GLenum mode
Definition: Glext.h:5794
unsigned int ms_bonehead_hits
Definition: scoring.h:122
#define IDC_FIELD2
UINT WPARAM LPARAM lParam
Definition: msacm.h:1064
void std_pinfo_remove_player_list_item(net_player *p)
Definition: stand_gui.cpp:1161
#define IDC_MSECHITS
void std_connect_set_ip_string(char *lookup, char *string)
Definition: stand_gui.cpp:288
unsigned int UINT
Definition: config.h:82
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
unsigned int s_shots_fired
Definition: scoring.h:92
void std_pinfo_display_player_info(net_player *p)
Definition: stand_gui.cpp:1079
#define GODSTUFF_MAX_ITEMS
Definition: stand_gui.cpp:1339
#define STP_SHUTDOWN
Definition: stand_gui.cpp:58
#define IDC_PLAYER_LIST
GLenum GLint ref
Definition: Glext.h:5605
void std_pinfo_update_ping(net_player *p)
Definition: stand_gui.cpp:1175
#define IDC_PXO_REFRESH
char Standalone_ban_list[STANDALONE_MAX_BAN][CALLSIGN_LEN+1]
Definition: stand_gui.cpp:101
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define IDC_SBHHITS
mission_goal Mission_goals[MAX_GOALS]
void std_gs_send_godstuff_message()
Definition: stand_gui.cpp:1382
#define STP_RESET_ALL
Definition: stand_gui.cpp:57
char callsign[CALLSIGN_LEN+1]
Definition: player.h:91
unsigned int mp_shots_hit
Definition: scoring.h:119
#define ST_MODE_CREATE
Definition: stand_gui.cpp:48
long LPARAM
Definition: config.h:101
GLenum type
Definition: Gl.h:1492
#define IDC_RESET_MULTI
void std_gs_add_god_player(net_player *p)
Definition: stand_gui.cpp:1355
#define IDC_MULTILOG
#define IDC_STD_NAME
const char * Osreg_app_name
Definition: osregistry.cpp:35
void std_connect_update_ping(net_player *p)
Definition: stand_gui.cpp:328
void std_multi_clear_controls()
Definition: stand_gui.cpp:834
void std_multi_init_framecap_slider(HWND hwndDlg)
Definition: stand_gui.cpp:903
void os_close()
Definition: fredstubs.cpp:56
HWND DWORD code
Definition: vddraw.h:425
#define IDC_NG_SECURITY
#define IDC_SSHOTS
#define ST_MODE_REMOVE
Definition: stand_gui.cpp:50
unsigned int ms_shots_fired
Definition: scoring.h:118
char * LPSTR
Definition: config.h:107
int m_kill_count_ok
Definition: scoring.h:115
#define STANDALONE_MAX_BAN
Definition: stand_gui.cpp:100
void std_debug_init_debug_controls(HWND hwndDlg)
Definition: stand_gui.cpp:1600
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define IDC_MASSISTS
int multi_num_players()
Definition: multiutil.cpp:1799
BOOL CALLBACK multi_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:1020
void game_format_time(long, char *)
Definition: fredstubs.cpp:204
#define IDC_STANDALONE_MTIME
Definition: player.h:85
void multi_kick_player(int player_index, int ban, int reason)
Definition: multi_kick.cpp:82
net_player_info p_info
Definition: multi.h:473
#define IDC_MSPCT
unsigned int uint
Definition: pstypes.h:64
int ping_avg
Definition: multi_ping.h:32
void std_multi_init_multi_controls(HWND hwndDlg)
Definition: stand_gui.cpp:927
multi_server_options options
Definition: multi.h:514
int std_pinfo_maybe_update_player_info(net_player *p)
Definition: stand_gui.cpp:1134
char name[MAX_GAMENAME_LEN+1]
Definition: multi.h:487
BOOL CALLBACK godstuff_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:1460
void send_game_chat_packet(net_player *from, const char *msg, int msg_mode, net_player *to, const char *expr, int server_msg)
Definition: multimsgs.cpp:615
void fs2netd_reset_connection()
unsigned int p_shots_fired
Definition: scoring.h:91
char title_str[512]
Definition: stand_gui.cpp:104
#define IDC_FRAMECAP_STATIC
netgame_info Netgame
Definition: multi.cpp:97
void std_gen_set_text(char *str, int field_num)
Definition: stand_gui.cpp:162
#define IDC_MSSHOTS
DWORD standalone_process(WORD lparam)
Definition: stand_gui.cpp:2351
#define IDC_MISSION_NAME
void std_pinfo_init_player_info_controls(HWND hwndDlg)
Definition: stand_gui.cpp:1212
void std_pinfo_add_player_list_item(net_player *p)
Definition: stand_gui.cpp:1145
void std_reset_timestamps()
Definition: stand_gui.cpp:1799
int std_pinfo_player_is_active(net_player *p)
Definition: stand_gui.cpp:1257
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
void std_init_os()
Definition: stand_gui.cpp:2409
void std_connect_add_ip_string(char *string)
Definition: stand_gui.cpp:259
#define IDC_MKILL_COUNT_BH
void std_create_gen_dialog(char *title)
Definition: stand_gui.cpp:128
void std_multi_handle_framecap_scroll(HWND ctrl)
Definition: stand_gui.cpp:886
void std_multi_setup_goal_tree()
Definition: stand_gui.cpp:621
#define GOALVIEW_X
Definition: stand_gui.cpp:582
#define FS_VERSION_MINOR
Definition: version.h:38
void std_build_title_string(char *str)
Definition: stand_gui.cpp:2036
void std_add_ban(const char *name)
Definition: stand_gui.cpp:1953
net_player_server_info s_info
Definition: multi.h:472
#define IDC_CONPING
#define IDC_GOD_CHAT
#define MAX_PLAYERS
Definition: pstypes.h:32
char mission_name[NAME_LENGTH+1]
Definition: multi.h:488
#define IDC_CON_COUNT
#define IDB_GOAL_COMP
void std_connect_handle_passwd_change()
Definition: stand_gui.cpp:438
void std_multi_add_goals()
Definition: stand_gui.cpp:660
unsigned long DWORD
Definition: config.h:90
#define IDC_ASSISTS
int idx
Definition: multiui.cpp:761
void std_deinit_standalone()
Definition: stand_gui.cpp:2426
BOOL CALLBACK std_gen_dialog_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:113
void std_update_player_ping(net_player *p)
Definition: stand_gui.cpp:1715
#define IDD_GEN
BOOL CALLBACK debug_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:1614
int multi_find_player_by_callsign(const char *callsign)
Definition: multiutil.cpp:1291
#define IDC_MPHITS
long fix
Definition: pstypes.h:54
int std_player_is_banned(const char *name)
Definition: stand_gui.cpp:1937
int x
Definition: config.h:287
#define GOAL_TYPE_MASK
Definition: missiongoals.h:34
int Lighting_flag
Definition: lighting.cpp:63
void std_multi_set_standalone_missiontime(float mission_time)
Definition: stand_gui.cpp:600
#define MULTI_MSG_ALL
Definition: multi_pmsg.h:27
net_addr addr
Definition: multi.h:453
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
#define IDD_CONNECT
#define IDC_SPCT
#define SECONDARY_GOAL
Definition: missiongoals.h:29
void std_multi_update_netgame_info_controls()
Definition: stand_gui.cpp:862
UINT uMsg
Definition: msacm.h:1064
void std_gs_set_framerate(float f)
Definition: stand_gui.cpp:1405
#define IDC_SCORE
Definition: resource.h:776
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
void std_init_standalone()
Definition: stand_gui.cpp:2416
#define IDC_MPBHHITS
long LONG
Definition: config.h:95
#define CALLBACK
Definition: config.h:75
DWORD Standalone_thread_id
Definition: stand_gui.cpp:44
void std_add_chat_text(const char *text, int player_index, int add_id)
Definition: stand_gui.cpp:1809
void std_connect_set_gamename(char *name)
Definition: stand_gui.cpp:373
#define GOAL_INCOMPLETE
Definition: missiongoals.h:40
int Standalone_stats_stamp
Definition: stand_gui.cpp:94
#define IDB_GOAL_ORD
#define IDC_GODSTUFF_BROADCAST
GLuint const GLchar * name
Definition: Glext.h:5608
BOOL CALLBACK connect_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:487
#define PROMPT_NONE
Definition: multi_endgame.h:26
void std_mutate_sheet()
Definition: stand_gui.cpp:1865
GLuint GLfloat * val
Definition: Glext.h:6741
#define IDC_NG_RESPAWNS
int BOOL
Definition: config.h:80
#define IDD_PLAYER_DIALOG
const char * Osreg_company_name
Definition: osregistry.cpp:28
int multi_quit_game(int prompt, int notify_code, int err_code, int wsa_error)
#define CF_TYPE_DATA
Definition: cfile.h:46
HTREEITEM std_multi_get_goal_item(char *goal_string, int type)
Definition: stand_gui.cpp:988
ping_struct ping
Definition: multi.h:395
if(aifft_max_checks<=0)
Definition: aiturret.cpp:1581
#define IDC_MSBHPCT
#define IDC_STANDALONE_FPS
int std_remove_player(net_player *p)
Definition: stand_gui.cpp:1674
#define STD_PASSWD_LEN
Definition: multi_options.h:27
#define CALLSIGN_LEN
Definition: globals.h:31
unsigned short WORD
Definition: config.h:81
void std_debug_set_standalone_state_string(char *str)
Definition: stand_gui.cpp:1539
#define strcat_s(...)
Definition: safe_strings.h:68
HWND std_init_property_sheet(HWND hwndDlg)
Definition: stand_gui.cpp:2062
#define FS_VERSION_REVIS
Definition: version.h:40
#define NAME_LENGTH
Definition: globals.h:15
#define IDC_PLAYER_GOD_LIST
int Cmdline_freespace_no_sound
Definition: cmdline.cpp:272
#define MULTI_CONNECTED(np)
Definition: multi.h:136
#define IDC_NG_MAXOBSERVERS
#define STD_STATS_UPDATE_TIME
Definition: stand_gui.cpp:68
screen gr_screen
Definition: 2d.cpp:46
void std_multi_set_framerate(float f)
Definition: stand_gui.cpp:824
bool fs2netd_is_online()
#define GOALVIEW_H
Definition: stand_gui.cpp:585
#define IDC_MSBHHITS
#define ST_MODE_UPDATE
Definition: stand_gui.cpp:49
int Multi_std_namechange_force
Definition: stand_gui.cpp:198
#define IDC_PPCT
unsigned int p_shots_hit
Definition: scoring.h:94
#define MAX_GAMENAME_LEN
Definition: multi.h:88
#define IDC_NG_MAXPLAYERS
#define IDB_GOAL_INC
void std_gs_clear_controls()
Definition: stand_gui.cpp:1415
GLfloat GLfloat p
Definition: Glext.h:8373
unsigned int p_bonehead_hits
Definition: scoring.h:97
void Sleep(int mili)
#define IDC_PSHIP_TYPE
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define IDC_PING_TIME
#define IDC_SECHITS
char std_pname[STD_NAME_LEN+1]
Definition: multi_options.h:52
void std_connect_kick_player()
Definition: stand_gui.cpp:307
#define timestamp_elapsed(stamp)
Definition: timer.h:102
#define IDC_STANDALONE_STATE
#define GOALVIEW_Y
Definition: stand_gui.cpp:583
void std_connect_remove_ip_string(char *string)
Definition: stand_gui.cpp:269
hull_check pos
Definition: lua.cpp:5050
void std_reset_standalone_gui()
Definition: stand_gui.cpp:1725
void std_set_standalone_fps(float fps)
Definition: stand_gui.cpp:1705
#define IDC_GODSTUFF_SENDMESS
#define IDC_MKILL_COUNT
#define IDC_KILL_COUNT_BH
GLint GLsizei count
Definition: Gl.h:1491
#define FS_VERSION_BUILD
Definition: version.h:39
BOOL std_create_standalone_window()
Definition: stand_gui.cpp:2231
int temp
Definition: lua.cpp:4996
void std_pinfo_clear_controls()
Definition: stand_gui.cpp:1193
#define IDC_PBHPCT
#define IDC_SBHPCT
#define IDC_PSHOTS
#define PLAYER_INFO_PAGE
Definition: stand_gui.cpp:80
char * psnet_addr_to_string(char *text, net_addr *address)
Definition: psnet2.cpp:705
#define GOAL_COMPLETE
Definition: missiongoals.h:39
#define GOALVIEW_W
Definition: stand_gui.cpp:584
void * HANDLE
Definition: config.h:106
int Num_goals
void std_destroy_gen_dialog()
Definition: stand_gui.cpp:148
int y
Definition: config.h:287
int std_is_host_passwd()
Definition: stand_gui.cpp:1859
#define IDB_GOAL_FAIL
void std_multi_set_standalone_mission_name(char *mission_name)
Definition: stand_gui.cpp:614
#define CONNECT_PAGE
Definition: stand_gui.cpp:78
#define FALSE
Definition: pstypes.h:400
#define wp(p)
Definition: modelsinc.h:69
#define MULTI_IS_TRACKER_GAME
Definition: multi.h:146
int m_kill_count
Definition: scoring.h:114
net_player Net_players[MAX_PLAYERS]
Definition: multi.cpp:93
int max_players
Definition: multi.h:497
unsigned int ms_shots_hit
Definition: scoring.h:120
void gameseq_post_event(int event)
GLenum GLint GLuint mask
Definition: Glext.h:5605
#define IDC_KILL_COUNT
#define stricmp(s1, s2)
Definition: config.h:271
unsigned int s_shots_hit
Definition: scoring.h:95
multi_global_options Multi_options_g
#define MAX_STANDALONE_PAGES
Definition: stand_gui.cpp:66
#define STP_SHOW
Definition: stand_gui.cpp:59
unsigned int s_bonehead_hits
Definition: scoring.h:98
#define fl2f(fl)
Definition: floating.h:38
#define IDC_GODSTUFF_FPS
BOOL CALLBACK std_message_handler_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: stand_gui.cpp:2162
#define MULTIPLAYER_PAGE
Definition: stand_gui.cpp:79
scoring_struct stats
Definition: player.h:127
#define strcpy_s(...)
Definition: safe_strings.h:67
#define GOAL_FAILED
Definition: missiongoals.h:38
char std_passwd[STD_PASSWD_LEN+1]
Definition: multi_options.h:51
int std_connect_lindex_to_npindex(int index)
Definition: stand_gui.cpp:454
#define MSG_SYSTRAYICON
Definition: stand_gui.cpp:52
void std_gs_remove_god_player(net_player *p)
Definition: stand_gui.cpp:1368