FS2_Open
Open source remastering of the Freespace 2 engine
readyroom.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 #include <ctype.h>
13 
14 #include "cfile/cfile.h"
15 #include "freespace2/freespace.h"
16 #include "gamehelp/contexthelp.h"
18 #include "gamesnd/gamesnd.h"
19 #include "globalincs/alphacolors.h"
20 #include "graphics/font.h"
21 #include "io/key.h"
22 #include "menuui/mainhallmenu.h"
23 #include "menuui/readyroom.h"
24 #include "menuui/techmenu.h" // for tech menu reset stuff
27 #include "parse/parselo.h"
28 #include "pilotfile/pilotfile.h"
29 #include "playerman/managepilot.h"
30 #include "playerman/player.h"
31 #include "popup/popup.h"
32 #include "ui/ui.h"
33 #include "ui/uidefs.h"
34 
35 
36 
37 #define MAX_MISSIONS 1024
38 
40  { // GR_640
41  33, 108, 402, 279
42  },
43  { // GR_1024
44  43, 175, 402, 459
45  }
46 };
47 
49  { // GR_640
50  491, 108, 115, 279
51  },
52  { // GR_1024
53  491, 175, 115, 459
54  }
55 };
56 
57 
58 #define C_SUBTEXT_X 19
59 // x coordinate offsets for data when campaign tab active
60 #define C_TEXT_X 0
61 
62 // x coordinate offsets for data when mission tab active
63 #define M_TEXT_X C_SUBTEXT_X //0
64 
65 #define MODE_CAMPAIGNS 0
66 #define MODE_MISSIONS 1
67 
68 #define MAX_LINES 200
69 #define MAX_DESC_LINES 200
70 #define NUM_BUTTONS 11
71 #define LIST_BUTTONS_MAX 42
72 
73 #define SCROLL_UP_BUTTON 0
74 #define SCROLL_DOWN_BUTTON 1
75 #define MISSION_TAB 2
76 #define CAMPAIGN_TAB 3
77 #define HELP_BUTTON 4
78 #define COMMIT_BUTTON 5
79 #define OPTIONS_BUTTON 6
80 #define TECH_DATABASE_BUTTON 7
81 #define SIMULATOR_BUTTON 8
82 #define CUTSCENES_BUTTON 9
83 #define CREDITS_BUTTON 10
84 
85 #define X_COORD 0
86 #define Y_COORD 1
87 #define W_COORD 2
88 #define H_COORD 3
89 
90 #define CAMPAIGN_MISSION_HASH_SIZE 307
91 
93  char *filename;
94  int x, y, xt, yt;
95  int hotspot;
96  UI_BUTTON button; // because we have a class inside this struct, we need the constructor below..
97 
98  sim_room_buttons(char *name, int x1, int y1, int xt1, int yt1, int h) : filename(name), x(x1), y(y1), xt(xt1), yt(yt1), hotspot(h) {}
99 };
100 
102 //XSTR:OFF
103  { // GR_640
104  sim_room_buttons("LMB_04", 1, 99, -1, -1, 4),
105  sim_room_buttons("LMB_05", 1, 381, -1, -1, 5),
106  sim_room_buttons("LMB_06", 6, 438, 40, 445, 6),
107  sim_room_buttons("LMB_07", 6, 457, 40, 462, 7),
108  sim_room_buttons("LMB_08", 534, 426, 500, 440, 8),
109  sim_room_buttons("LMB_09", 571, 426, 572, 413, 9),
110  sim_room_buttons("LMB_10", 534, 455, 480, 462, 10),
111 
112  sim_room_buttons("TDB_00", 7, 3, 37, 7, 0),
113  sim_room_buttons("TDB_01", 7, 18, 37, 23, 1),
114  sim_room_buttons("TDB_02", 7, 34, 37, 38, 2),
115  sim_room_buttons("TDB_03", 7, 49, 37, 54, 3),
116  },
117  { // GR_1024
118  sim_room_buttons("2_LMB_04", 2, 159, -1, -1, 4),
119  sim_room_buttons("2_LMB_05", 2, 609, -1, -1, 5),
120  sim_room_buttons("2_LMB_06", 10, 701, 64, 712, 6),
121  sim_room_buttons("2_LMB_07", 10, 732, 64, 739, 7),
122  sim_room_buttons("2_LMB_08", 854, 681, 800, 704, 8),
123  sim_room_buttons("2_LMB_09", 914, 681, 915, 660, 9),
124  sim_room_buttons("2_LMB_10", 854, 728, 780, 736, 10),
125 
126  sim_room_buttons("2_TDB_00", 12, 5, 59, 12, 0),
127  sim_room_buttons("2_TDB_01", 12, 31, 59, 37, 1),
128  sim_room_buttons("2_TDB_02", 12, 56, 59, 62, 2),
129  sim_room_buttons("2_TDB_03", 12, 81, 59, 88, 3),
130  }
131 //XSTR:ON
132 };
133 
135  "LoadMission",
136  "2_LoadMission"
137 };
139  "LoadMission-m",
140  "2_LoadMission-m"
141 };
142 
144  "Campaign",
145  "2_Campaign"
146 };
148  "Campaign-m",
149  "2_Campaign-m"
150 };
151 
153  "slider",
154  "2_slider"
155 };
156 
157 // misc text. ("Mission" and "Filename"
158 #define NUM_SIM_MISC_TEXT 2
159 #define SIM_MISC_TEXT_MISSION 0
160 #define SIM_MISC_TEXT_FILENAME 1
162  { // GR_640
163  {33, 95},
164  {491, 95}
165  },
166  { // GR_1024
167  {43, 155},
168  {491, 155}
169  }
170 };
171 
173  { // GR_640
174  4, 131, 20, 245
175  },
176  { // GR_1024
177  5, 209, 32, 392
178  }
179 };
180 
181 // readyroom text line stuff
182 #define READYROOM_LINE_CAMPAIGN 1
183 #define READYROOM_LINE_CMISSION 2
184 #define READYROOM_LINE_MISSION 3
185 
186 #define READYROOM_FLAG_FROM_VOLITION (1<<0) // volition made
187 static struct {
188  int type; // see READYROOM_LINE_* defines above
189  char *name;
190  char *filename;
191  int x; // X coordinate of line
192  int y; // Y coordinate of line
193  int flags; // special flags, see READYROOM_FLAG_* defines above
194 } sim_room_lines[MAX_LINES];
195 
196 static char Cur_campaign[MAX_FILENAME_LEN];
197 static char *Mission_filenames[MAX_MISSIONS] = { NULL };
198 static char *Standalone_mission_names[MAX_MISSIONS] = { NULL };
199 static int Standalone_mission_flags[MAX_MISSIONS];
200 static char *Campaign_missions[MAX_MISSIONS] = { NULL };
201 static char *Campaign_mission_names[MAX_CAMPAIGN_MISSIONS] = { NULL };
202 static int Campaign_mission_flags[MAX_MISSIONS];
203 static int Simroom_show_all = 0;
204 static int Standalone_mission_names_inited = 0;
205 static int Campaign_mission_names_inited = 0;
206 static int Num_standalone_missions;
207 static int Num_campaign_missions;
208 //static int Num_player_missions;
209 static int Scroll_offset;
210 static int Selected_line;
211 static int Num_lines;
212 static int Num_campaign_missions_with_info = 0;
213 static int Num_standalone_missions_with_info = 0;
214 static int list_x1;
215 static int list_x2;
216 static int list_y;
217 static int list_w1;
218 static int list_w2;
219 static int list_h;
220 static int Background_bitmap;
221 static UI_WINDOW Ui_window;
222 static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list
223 
226 
227 // globals
229 
230 // slider stuff
231 static UI_SLIDER2 Sim_room_slider;
232 
233 typedef struct hash_node {
235  char *filename;
236 } hash_node;
237 
238 static hash_node *Campaign_mission_hash_table[CAMPAIGN_MISSION_HASH_SIZE];
239 static int Hash_table_inited;
240 
241 // special icons (1.04 + stuff)
242 #define NUM_MISSION_ICONS 1
243 #define MISSION_ICON_VOLITION 0 // mini volition death's head :)
244 
245 // icon offsets (see LIST_ defines above
246 //#define MISSION_ICON_VOLITION_X (46)
247 #define MISSION_ICON_VOLITION_Y_OFFSET (-1)
248 
249 // icon offsets
250 static int Sim_volition_icon_x[GR_NUM_RESOLUTIONS] = {
251  38,
252  49
253 };
254 
255 // special icons themselves
257 //XSTR:OFF
259  "icon-volition"
260 };
261 //XSTR:ON
264 void sim_room_blit_icons(int line_index, int y_start, fs_builtin_mission *fb = NULL, int is_md = 0);
265 
266 // Finds a hash value for mission filename
267 //
268 // returns hash value
269 int hash_filename(const char *filename) {
270  ulonglong hash_val = 0;
271  const char *ptr = filename;
272 
273  // Don't hash .fsm extension, convert all to upper case
274  for (int i=0; i < ((signed int)(strlen(filename)) - 4); i++) {
275  hash_val = (hash_val << 4) + toupper(*ptr++);
276  }
277 
278  return int(hash_val % CAMPAIGN_MISSION_HASH_SIZE);
279 }
280 
281 // insert filename into Campaign_mission_hash_table
282 //
283 // returns 1 if successful, 0 if could not allocate memory
284 int hash_insert(char *filename) {
285  int hash_val = hash_filename(filename);
286  hash_node *cur_node;
287 
288  // Check if table empty
289  if (Campaign_mission_hash_table[hash_val] == NULL) {
290  Campaign_mission_hash_table[hash_val] = new hash_node;
291 
292  cur_node = Campaign_mission_hash_table[hash_val];
293 
294  if (cur_node == NULL) {
295  // Unable to allocate memory
296  return 0;
297  }
298  } else {
299  // Walk down list to first empty node
300  cur_node = Campaign_mission_hash_table[hash_val];
301  while (cur_node->next != NULL) {
302  cur_node = cur_node->next;
303  }
304 
305  // Create new node
306  cur_node->next = new hash_node;
307 
308  if (cur_node->next == NULL) {
309  // unable to allocate memory
310  return 0;
311  } else {
312  cur_node = cur_node->next;
313  }
314  }
315 
316  // Initialize data
317  cur_node->next = NULL;
318  cur_node->filename = filename;
319 
320  // Return successs
321  return 1;
322 }
323 
324 // Checks if a filename already exitst in the hash table
325 //
326 // returns 1 if found (collision), 0 if no collision
328 {
329  int hash_val = hash_filename(filename);
330  hash_node *cur_node = Campaign_mission_hash_table[hash_val];
331 
332  if (cur_node == NULL) {
333  return 0;
334  }
335 
336  do {
337  if (!stricmp(filename, cur_node->filename)) {
338  return 1;
339  }
340 
341  cur_node = cur_node->next;
342  } while (cur_node != NULL);
343 
344  // Ran out of stuff to check
345  return 0;
346 }
347 
348 // builds hash table of campaign mission filenames
349 //
350 // returns 1 if successful, 0 if not successful
352 {
353  int rval;
354  // Go through all campaign missions
355  for (int i=0; i<Num_campaign_missions; i++) {
356  rval = hash_insert(Campaign_missions[i]);
357  if (rval == 0) {
358  return 0;
359  }
360  }
361 
362  // successful
363  return 1;
364 }
365 
366 // deletes hash table nodes
367 //
369 {
370  hash_node *cur_node;
371 
372  for (int i=0; i<CAMPAIGN_MISSION_HASH_SIZE; i++) {
373  // Look for entries into array
374  if (Campaign_mission_hash_table[i] != NULL) {
375  cur_node = Campaign_mission_hash_table[i];
376 
377  // Walk down the list deleting self
378  while (cur_node->next != NULL) {
379  hash_node *temp = cur_node->next;
380  delete cur_node;
381  cur_node = temp;
382  }
383 
384  // Delete last node
385  delete cur_node;
386  Campaign_mission_hash_table[i] = NULL;
387  }
388  }
389 }
390 
391 
392 // add a line of sim_room smuck to end of list
393 int sim_room_line_add(int type, char *name, char *filename, int x, int y, int flags)
394 {
395  if (Num_lines >= MAX_LINES)
396  return 0;
397 
398  sim_room_lines[Num_lines].type = type;
399  sim_room_lines[Num_lines].name = name;
400  sim_room_lines[Num_lines].filename = filename;
401  sim_room_lines[Num_lines].x = x;
402  sim_room_lines[Num_lines].y = y;
403  sim_room_lines[Num_lines].flags = flags;
404  return Num_lines++;
405 }
406 
407 // build up a list of all missions in all campaigns.
409 {
410  int num;
411 
412  num = mission_campaign_get_mission_list(filename, &Campaign_missions[Num_campaign_missions], MAX_MISSIONS - Num_campaign_missions);
413  if (num < 0)
414  return 0;
415 
416  Num_campaigns++;
417  Num_campaign_missions += num;
418  return 1;
419 }
420 
421 // filter out all missions already used in existing campaigns
423 {
424  int type;
425  char mission_name[255];
426 
427  // Check if a campaign mission (single and multi)
428  if (campaign_mission_hash_collision(filename)) {
429  return 0;
430  }
431 
432  // Check if a standalone multi mission OR Mdisk mission with data
433  type = mission_parse_is_multi(filename, mission_name);
434  if (type && !(type & MISSION_TYPE_SINGLE))
435  return 0;
436 
437  return 1;
438 }
439 
440 // builds up list of standalone missions and adds them to missions simulator
441 // processes one mission per frame
442 //
443 // returns 1 if finished with all missions, 0 otherwise
444 //
446 {
447  int font_height = gr_get_font_height();
449  char str[256];
450 
451  // When no standalone missions in data directory
452  if (Num_standalone_missions == 0) {
453  Standalone_mission_names_inited = 1;
454  return 1;
455  }
456 
457  // Set global variable so we we'll have list available next time
458  Standalone_mission_names[Num_standalone_missions_with_info] = NULL;
459  Standalone_mission_flags[Num_standalone_missions_with_info] = 0;
460 
461  if (Num_standalone_missions > 0) { // sanity check
462  if (strlen(Mission_filenames[Num_standalone_missions_with_info]) < MAX_FILENAME_LEN - 4) { // sanity check?
463  strcpy_s(filename, Mission_filenames[Num_standalone_missions_with_info]);
464 
465  // update popup
466  memset(str, 0, 256);
467  sprintf(str, XSTR("Single Mission\n\n%s",989), filename);
468  popup_change_text(str);
469 
470  // tack on an extension
471  strcat_s(filename, FS_MISSION_FILE_EXT);
472  if (!get_mission_info(filename)) {
473  Standalone_mission_names[Num_standalone_missions_with_info] = vm_strdup(The_mission.name);
474  Standalone_mission_flags[Num_standalone_missions_with_info] = The_mission.game_type;
475  int y = Num_lines * (font_height + 2);
476 
477  // determine some extra information
478  int flags = 0;
480  if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)){
482  }
483 
484  // add the line
485  sim_room_line_add(READYROOM_LINE_MISSION, Standalone_mission_names[Num_standalone_missions_with_info], Mission_filenames[Num_standalone_missions_with_info], list_x1 + M_TEXT_X, y, flags);
486  }
487  }
488 
489  Num_standalone_missions_with_info++;
490  }
491 
492  if (Num_standalone_missions_with_info == Num_standalone_missions) {
493  Standalone_mission_names_inited = 1;
494  return 1;
495  } else {
496  return 0;
497  }
498 }
499 
500 // builds up list of already played missions in a campaign and adds them to missions simulator
501 // processes one mission per frame
502 //
503 // returns 1 if finished with all missions, 0 otherwise
504 //
506 {
507  int font_height = gr_get_font_height();
508  char str[256];
509  static int valid_missions_with_info = 0; // we use this to avoid blank entries in the mission list
510 
511  // When no campaign files in data directory
512  if (Campaign.num_missions == 0) {
513  Campaign_mission_names_inited = 1;
514  return 1;
515  }
516 
517  // change popup
518  memset(str, 0, 256);
519  sprintf(str, XSTR("Campaign Mission\n\n%s",990), Campaign.missions[Num_campaign_missions_with_info].name);
520  popup_change_text(str);
521 
522  // Set global variable so we we'll have list available next time
523  Campaign_mission_names[Num_campaign_missions_with_info] = NULL;
524  Campaign_mission_flags[Num_campaign_missions_with_info] = 0;
525 
526  // Only allow missions already completed
527  if (Campaign.missions[Num_campaign_missions_with_info].completed || Simroom_show_all)
528  {
529  if (!get_mission_info(Campaign.missions[Num_campaign_missions_with_info].name))
530  {
531  // add to list
532  Campaign_mission_names[Num_campaign_missions_with_info] = vm_strdup(The_mission.name);
533  Campaign_mission_flags[Num_campaign_missions_with_info] = The_mission.game_type;
534  int y = valid_missions_with_info * (font_height + 2);
535 
536  // determine some extra information
537  int flags = 0;
538  fs_builtin_mission *fb = game_find_builtin_mission(Campaign.missions[Num_campaign_missions_with_info].name);
539  if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION))
540  {
542  }
543 
544  sim_room_line_add(READYROOM_LINE_CMISSION, Campaign_mission_names[Num_campaign_missions_with_info], Campaign.missions[Num_campaign_missions_with_info].name, list_x1 + C_SUBTEXT_X, y, flags);
545  valid_missions_with_info++;
546  }
547  }
548 
549  Num_campaign_missions_with_info++;
550 
551  if (Num_campaign_missions_with_info == Campaign.num_missions) {
552  valid_missions_with_info = 0;
553  Campaign_mission_names_inited = 1;
554  return 1;
555  } else {
556  return 0;
557  }
558 }
559 
560 // Builds list of either (1) standalone missions or (2) already played missions in current campaign
561 // First time through, it builds list, next time it uses precompiled list
563 {
564  int i, y, max_num_entries_viewable;
565  int font_height = gr_get_font_height();
566  char full_filename[256];
567 
568  Num_lines = y = 0;
569  list_y = Mission_list_coords[gr_screen.res][1];
570  list_h = Mission_list_coords[gr_screen.res][3];
571 
572  // Stand alone single player missions.
574  if (Hash_table_inited) {
575  if (!Standalone_mission_names_inited) { // Is this the first time through
576  // build_list_do_frame builds list and adds sim room line and sets Standalone_mission_names_inited
578  } else {
579  for (i=0; i<Num_standalone_missions_with_info; i++) {
580  if (Standalone_mission_names[i]) {
581  // determine some extra information
582  int flags = 0;
583  memset(full_filename, 0, 256);
584  strcpy_s(full_filename, cf_add_ext(Mission_filenames[i], FS_MISSION_FILE_EXT));
585  fs_builtin_mission *fb = game_find_builtin_mission(full_filename);
586  if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)){
588  }
589 
590  sim_room_line_add(READYROOM_LINE_MISSION, Standalone_mission_names[i], Mission_filenames[i], list_x1 + M_TEXT_X, y, flags);
591  y += font_height + 2;
592  }
593  }
594  }
595  }
596  } else {
597  // Campaign missions
598  list_y += font_height + 2;
599  list_h -= font_height - 2;
600 
601  if (!Campaign_mission_names_inited) { // Is this the first time through
602  // builds list, adds sim room line and sets Campaign_mission_names_inited
604  } else {
605  for (i=0; i<Num_campaign_missions_with_info; i++) {
606  if (Campaign_mission_names[i]) {
607  // determine some extra information
608  int flags = 0;
609  memset(full_filename, 0, 256);
611  fs_builtin_mission *fb = game_find_builtin_mission(full_filename);
612  if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)){
614  }
615 
616  sim_room_line_add(READYROOM_LINE_CMISSION, Campaign_mission_names[i], Campaign.missions[i].name, list_x1 + C_SUBTEXT_X, y, flags);
617  y += font_height + 2; // Goober5000 - added +2 to conform with above
618  }
619  }
620  }
621  }
622 
623  // free up memory from parsing all of those missions
624  stop_parse();
625 
626  // set appropriate slider size
627  max_num_entries_viewable = list_h / (font_height + 2);
628  Sim_room_slider.set_numberItems((Num_lines > max_num_entries_viewable) ? (Num_lines - max_num_entries_viewable) : 0);
629 }
630 
632 {
633  // only reset if we got fully inited in the first place
634  if (!Campaign_mission_names_inited)
635  return;
636 
637 
638  for (int i=0; i<Campaign.num_missions; i++) {
639  if (Campaign_mission_names[i]) {
640  vm_free(Campaign_mission_names[i]);
641  Campaign_mission_names[i] = NULL;
642  }
643  }
644 
645  Campaign_mission_names_inited = 0;
646  Num_campaign_missions_with_info = 0;
647 
649 }
650 
652 {
653  int y;
654 
655  if ((n < 0) || (n >= Num_lines))
656  return 0;
657 
658  y = sim_room_lines[n].y - sim_room_lines[Scroll_offset].y;
659  if ((y < 0) || (y + gr_get_font_height() > list_h))
660  return 0;
661 
662  return 1;
663 }
664 
666 {
667  if (Scroll_offset > 0) {
668  Scroll_offset--;
669 
671  {
672  Assert(Selected_line > Scroll_offset);
673  while (!sim_room_line_query_visible(Selected_line))
674  {
675  Selected_line--;
676  }
677  }
678 
680 
681  } else
683 }
684 
686 {
687  if (Selected_line) {
688  Selected_line--;
689  if (Selected_line < Scroll_offset)
690  {
691  Scroll_offset = Selected_line;
692  Sim_room_slider.forceUp();
693  }
694 
696 
697  } else
699 }
700 
702 {
703  if (sim_room_lines[Num_lines - 1].y + gr_get_font_height() > sim_room_lines[Scroll_offset].y + list_h) {
704  Scroll_offset++;
705 
707  {
708  while (!sim_room_line_query_visible(Selected_line))
709  {
710  Selected_line++;
711  Assert(Selected_line < Num_lines);
712  }
713  }
714 
716 
717  } else
719 }
720 
722 {
723  if (Selected_line < Num_lines - 1) {
724  Selected_line++;
725 
726  Assert(Selected_line > Scroll_offset);
727  while (!sim_room_line_query_visible(Selected_line))
728  {
729  Scroll_offset++;
730  Sim_room_slider.forceDown();
731  }
732 
734 
735  } else
737 }
738 
739 /* Goober5000 - why are there two nearly identical functions?
740  (campaign_room_reset_campaign and sim_room_reset_campaign)
741  Looks like this function should be deprecated...
742 
743 // returns: 0 = success, !0 = aborted or failed
744 int sim_room_reset_campaign()
745 {
746  int z, rval = 1;
747 
748  z = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_CANCEL, POPUP_OK, XSTR( "Warning\nThis will cause all progress in your\ncurrent campaign to be lost", 110) );
749 
750  if (z) {
751  mission_campaign_savefile_delete(Campaign.filename);
752  mission_campaign_load(Campaign.filename);
753 
754  rval = 0;
755  }
756 
757  return rval;
758 }
759 */
760 
761 // Decide if we should offer choice to resume this savegame
762 int sim_room_can_resume_savegame(char *savegame_filename)
763 {
764  #ifdef FREESPACE_SAVERESTORE_SYSTEM
765  char savegame_mission[MAX_FILENAME_LEN];
766 
767  if (state_read_description(savegame_filename, NULL, savegame_mission)) {
768  return 0;
769  }
770 
771  if (stricmp(Game_current_mission_filename, savegame_mission)) {
772  return 0;
773  }
774 
775  return 1;
776  #else
777  return 0;
778  #endif
779 }
780 
781 // Decide wether to resume a save game or not
782 // exit: 1 => savegame has been restored
783 // 0 => no restore, proceed to briefing
784 // -1 => don't start mission at all
786 {
787  // MWA -- 3/26/98 -- removed all savegame references in game
788  return 0;
789 
790  /*
791  char savegame_filename[_MAX_FNAME];
792  int popup_rval = -1, resume_savegame = 0;
793 
794  // Generate the save-game filename for this campaign
795  memset(savegame_filename, 0, _MAX_FNAME);
796  mission_campaign_savefile_generate_root(savegame_filename);
797  strcat_s(savegame_filename, NOX("svg"));
798 
799  // Decide if we should offer choice to resume this savegame
800  if ( sim_room_can_resume_savegame(savegame_filename) ) {
801  popup_rval = popup(0, 3, XSTR("&Cancel",-1), XSTR("&Overwrite",-1), XSTR("&Resume",-1), XSTR("A save game for this mission exists.", -1));
802  switch ( popup_rval ) {
803  case 0:
804  case -1:
805  resume_savegame = -1;
806  break;
807  case 1:
808  resume_savegame = 0;
809  break;
810  case 2:
811  resume_savegame = 1;
812  break;
813  default:
814  Int3();
815  resume_savegame = -1;
816  break;
817  }
818  } else {
819  resume_savegame = 0;
820  }
821 
822  if (resume_savegame == 1) {
823  if ( state_restore_all(savegame_filename) == -1 ) {
824  popup_rval = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_NO, POPUP_YES, XSTR("Error\nSaved misison could not be loaded.\nDo you wish to start this mission from the beginning?", -1));
825  if (popup_rval == 1) {
826  resume_savegame = 0;
827  } else {
828  resume_savegame = -1;
829  }
830 
831  } else {
832  resume_savegame = 1;
833  }
834  }
835 
836  // If we are resuming this savegame, then delete the file
837  if (resume_savegame == 1) {
838  cf_delete(savegame_filename);
839  }
840 
841  return resume_savegame;
842  */
843 }
844 
846 {
847  // check for possible mission loop, need to do this before calling mission_campaign_next_mission()!
849  (Campaign.prev_mission != -1) && (Campaign.next_mission != -1) )
850  {
852  // NOTE: the order of these calls is *very* important
853 
854  // we must manually set the current mission to the *previous* mission and the mission name.
855  // this isn't the same thing that is done in mission_campaign_next_mission(), but it's
856  // cleaner to do this here than it is to hack that function to do the same thing
859 
860  // set the bit for campaign mode
862 
863  // eval the mission (may be needed to setup loop mission stuff)
866 
867  // only proceed to loop if we have a loop
868  if (Campaign.loop_mission > 0) {
870  return 0;
871  }
872  }
873  }
874 
875  int mc_rval = mission_campaign_next_mission();
876  if (mc_rval == -1)
877  { // is campaign and next mission valid?
879  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The campaign is over. To replay the campaign, either create a new pilot or restart the campaign in the campaign room.", 112) );
880  return -1;
881  }
882  else if(mc_rval == -2)
883  {
885  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, NOX("The current campaign has no missions") );
886  return -1;
887  }
888 
889  // set the bit for campaign mode
892 
893  return 0;
894 }
895 
897 {
898  if ((Selected_line >= Num_lines) || !sim_room_lines[Selected_line].filename) {
900  return;
901  }
902 
903  strcpy_s(Game_current_mission_filename, sim_room_lines[Selected_line].filename);
904 
905  Game_mode &= ~(GM_CAMPAIGN_MODE); // be sure this bit is clear
906 
909 }
910 
912 {
913  switch (n) {
914  case SCROLL_UP_BUTTON:
916  Sim_room_slider.forceUp();
917  break;
918 
919  case SCROLL_DOWN_BUTTON:
921  Sim_room_slider.forceDown();
922  break;
923 
924  case MISSION_TAB:
925  Simroom_show_all = 0;
927  Selected_line = Scroll_offset = 0;
930  break;
931 
932  case CAMPAIGN_TAB:
933  if ( !strlen(Campaign.filename) ) {
934  popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found, unable to switch to campaign mode!", 1612));
935  break;
936  }
937 
939  Simroom_show_all = 0;
940 
942  Scroll_offset = 0;
945  break;
946 
947  case COMMIT_BUTTON:
948  sim_room_commit();
949  break;
950 
951  case HELP_BUTTON:
954  break;
955 
956  case OPTIONS_BUTTON:
959  return 1;
960 
964  return 1;
965 
966  case CUTSCENES_BUTTON:
969  return 1;
970 
971  case CREDITS_BUTTON:
974  return 1;
975  }
976 
977  return 0;
978 }
979 
980 // do nothing
982 {
983 }
984 
985 // ---------------------------------------------------------------------
986 // mission_sim_room_init()
987 //
988 // Initialize the sim_room assignment screen system. Called when GS_STATE_sim_room_SCREEN
989 // is entered.
990 //
991 
993 {
994  int i;
996  char wild_card[256];
997 
998  list_x1 = Mission_list_coords[gr_screen.res][0];
999  list_x2 = Campaign_list_coords[gr_screen.res][0];
1000  list_y = Mission_list_coords[gr_screen.res][1];
1001  list_w1 = Mission_list_coords[gr_screen.res][2];
1002  list_w2 = Campaign_list_coords[gr_screen.res][2];
1003  list_h = Mission_list_coords[gr_screen.res][3];
1004 
1005  // force mode to valid range. I once had a bogus value here. Don't know how that happened, though.
1008 
1010  common_set_interface_palette("InterfacePalette"); // set the interface palette
1013 
1014  for (i=0; i<NUM_BUTTONS; i++) {
1015  b = &Buttons[gr_screen.res][i];
1016 
1017  b->button.create(&Ui_window, "", b->x, b->y, 60, 30, (i < 2), 1);
1018  // set up callback for when a mouse first goes over a button
1020  b->button.set_bmaps(b->filename);
1021  b->button.link_hotspot(b->hotspot);
1022  }
1023 
1024  // screen/button specific text
1025  Ui_window.add_XSTR("Single Missions", 1060, Buttons[gr_screen.res][MISSION_TAB].xt, Buttons[gr_screen.res][MISSION_TAB].yt, &Buttons[gr_screen.res][MISSION_TAB].button, UI_XSTR_COLOR_GREEN);
1026  Ui_window.add_XSTR("Campaign Missions", 1061, Buttons[gr_screen.res][CAMPAIGN_TAB].xt, Buttons[gr_screen.res][CAMPAIGN_TAB].yt, &Buttons[gr_screen.res][CAMPAIGN_TAB].button, UI_XSTR_COLOR_GREEN);
1027  Ui_window.add_XSTR("Help", 928, Buttons[gr_screen.res][HELP_BUTTON].xt, Buttons[gr_screen.res][HELP_BUTTON].yt, &Buttons[gr_screen.res][HELP_BUTTON].button, UI_XSTR_COLOR_GREEN);
1028  Ui_window.add_XSTR("Commit", 1062, Buttons[gr_screen.res][COMMIT_BUTTON].xt, Buttons[gr_screen.res][COMMIT_BUTTON].yt, &Buttons[gr_screen.res][COMMIT_BUTTON].button, UI_XSTR_COLOR_PINK);
1029  Ui_window.add_XSTR("Options", 1036, Buttons[gr_screen.res][OPTIONS_BUTTON].xt, Buttons[gr_screen.res][OPTIONS_BUTTON].yt, &Buttons[gr_screen.res][OPTIONS_BUTTON].button, UI_XSTR_COLOR_GREEN);
1030 
1031  // common tab button text
1032  Ui_window.add_XSTR("Technical Database", 1055, Buttons[gr_screen.res][TECH_DATABASE_BUTTON].xt, Buttons[gr_screen.res][TECH_DATABASE_BUTTON].yt, &Buttons[gr_screen.res][TECH_DATABASE_BUTTON].button, UI_XSTR_COLOR_GREEN);
1033  Ui_window.add_XSTR("Mission Simulator", 1056, Buttons[gr_screen.res][SIMULATOR_BUTTON].xt, Buttons[gr_screen.res][SIMULATOR_BUTTON].yt, &Buttons[gr_screen.res][SIMULATOR_BUTTON].button, UI_XSTR_COLOR_GREEN);
1034  Ui_window.add_XSTR("Cutscenes", 1057, Buttons[gr_screen.res][CUTSCENES_BUTTON].xt, Buttons[gr_screen.res][CUTSCENES_BUTTON].yt, &Buttons[gr_screen.res][CUTSCENES_BUTTON].button, UI_XSTR_COLOR_GREEN);
1035  Ui_window.add_XSTR("Credits", 1058, Buttons[gr_screen.res][CREDITS_BUTTON].xt, Buttons[gr_screen.res][CREDITS_BUTTON].yt, &Buttons[gr_screen.res][CREDITS_BUTTON].button, UI_XSTR_COLOR_GREEN);
1036 
1037  // misc text - not associated with any buttons
1038  Ui_window.add_XSTR("Mission", 1063, Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_MISSION][0], Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_MISSION][1], NULL, UI_XSTR_COLOR_GREEN);
1039  Ui_window.add_XSTR("Filename", 1064, Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_FILENAME][0], Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_FILENAME][1], NULL, UI_XSTR_COLOR_GREEN);
1040 
1041  for (i=0; i<LIST_BUTTONS_MAX; i++) {
1042  List_buttons[i].create(&Ui_window, "", 0, 0, 60, 30, 0, 1);
1043  List_buttons[i].hide();
1044  List_buttons[i].disable();
1045  }
1046 
1047  // set up sim_rooms for buttons so we draw the correct animation frame when a key is pressed
1051 
1052  Background_bitmap = bm_load(Sim_filename[gr_screen.res]);
1053 
1054  // load in help overlay bitmap
1057 
1058  Scroll_offset = Selected_line = 0;
1059 
1060  strcpy_s(Cur_campaign, Player->current_campaign);
1061  if ( !mission_load_up_campaign() ) {
1063  } else {
1064  Campaign.filename[0] = 0;
1065  Campaign.num_missions = 0;
1066 
1068  }
1069 
1070  Num_campaign_missions = 0;
1072 
1073  mission_campaign_build_list(false, false); // no descs, no sorting
1074 
1075  Hash_table_inited = 0;
1077  Hash_table_inited = 1;
1078  }
1079 
1080  // if there is no campaign available then force the use of mode_missions only
1081  if ( !strlen(Campaign.filename) )
1083 
1084  // HACK
1085  GR_MAYBE_CLEAR_RES(Background_bitmap);
1086  if(Background_bitmap != -1){
1087  gr_set_bitmap(Background_bitmap);
1088  gr_bitmap(0, 0, GR_RESIZE_MENU);
1089  }
1090  Ui_window.draw();
1091  gr_flip();
1092 
1094  memset(wild_card, 0, 256);
1095  strcpy_s(wild_card, NOX("*"));
1096  strcat_s(wild_card, FS_MISSION_FILE_EXT);
1097  Num_standalone_missions = cf_get_file_list(MAX_MISSIONS, Mission_filenames, CF_TYPE_MISSIONS, wild_card, CF_SORT_NAME);
1098 
1099  // set up slider with 0 items to start
1101 
1102  Num_campaign_missions_with_info = Num_standalone_missions_with_info = Standalone_mission_names_inited = Campaign_mission_names_inited = 0;
1103  Simroom_show_all = 0;
1105 
1106  // load special mission icons
1108 }
1109 
1110 // ---------------------------------------------------------------------
1111 // sim_room_close()
1112 //
1113 // Cleanup the sim_room assignment screen system. Called when GS_STATE_sim_room_SCREEN
1114 // is left.
1115 //
1117 {
1118  int i;
1119 
1120  for (i=0; i<Num_campaign_missions; i++) {
1121  if (Campaign_missions[i]) {
1122  vm_free(Campaign_missions[i]);
1123  Campaign_missions[i] = NULL;
1124  }
1125  }
1126 
1127  if (Background_bitmap >= 0)
1128  bm_release(Background_bitmap);
1129 
1130  if (Standalone_mission_names_inited){
1131  for (i=0; i<Num_standalone_missions; i++){
1132  if (Standalone_mission_names[i] != NULL){
1133  vm_free(Standalone_mission_names[i]);
1134  Standalone_mission_names[i] = NULL;
1135  }
1136  Standalone_mission_flags[i] = 0;
1137  }
1138  }
1139 
1140  if (Campaign_mission_names_inited) {
1141  for (i=0; i<Campaign.num_missions; i++) {
1142  if (Campaign_mission_names[i]) {
1143  vm_free(Campaign_mission_names[i]);
1144  Campaign_mission_names[i] = NULL;
1145  }
1146  }
1147  }
1148 
1149  for (i=0; i<Num_standalone_missions; i++) {
1150  vm_free(Mission_filenames[i]);
1151  Mission_filenames[i] = NULL;
1152  }
1153 
1154  // free global Campaign_* list stuff
1156 
1158 
1159  Ui_window.destroy();
1160  common_free_interface_palette(); // restore game palette
1161  Pilot.save_player();
1162 
1163  // unload special mission icons
1165 }
1166 
1167 // ---------------------------------------------------------------------
1168 // sim_room_do_frame()
1169 //
1170 // Called once per frame to process user input for the sim_room Assignment Screen
1171 //
1172 void sim_room_do_frame(float frametime)
1173 {
1174  char buf[256];
1175  int i, k, y, line;
1176  int font_height = gr_get_font_height();
1177  int select_tease_line = -1; // line mouse is down on, but won't be selected until button released
1178 
1181  Ui_window.set_ignore_gadgets(1);
1182  }
1183 
1184  k = Ui_window.process() & ~KEY_DEBUGGED;
1185 
1186  if ( (k > 0) || B1_JUST_RELEASED ) {
1189  Ui_window.set_ignore_gadgets(0);
1190  k = 0;
1191  }
1192  }
1193 
1195  Ui_window.set_ignore_gadgets(0);
1196  }
1197 
1198  switch (k) {
1199  case KEY_DOWN: // scroll list down
1201  break;
1202 
1203  case KEY_UP: // scroll list up
1205  break;
1206 
1207  case KEY_ESC:
1209  break;
1210 
1211  case KEY_CTRLED | KEY_UP:
1213  break;
1214 
1215  case KEY_CTRLED | KEY_DOWN:
1217  break;
1218 
1219  case KEY_TAB:
1222  else if ( strlen(Campaign.filename) )
1224  else
1226 
1227  Selected_line = Scroll_offset = Simroom_show_all = 0;
1230  break;
1231 
1232  case KEY_F2:
1235  break;
1236 
1237  case KEY_CTRLED | KEY_SHIFTED | KEY_S:
1239  Simroom_show_all = !Simroom_show_all;
1241  }
1242  break;
1243  } // end switch
1244 
1245  for (i=0; i<NUM_BUTTONS; i++){
1246  if (Buttons[gr_screen.res][i].button.pressed()){
1247  if (sim_room_button_pressed(i)){
1248  return;
1249  }
1250  }
1251  }
1252 
1253  for (i=0; i<LIST_BUTTONS_MAX; i++) {
1254  if (List_buttons[i].is_mouse_on())
1255  select_tease_line = i + Scroll_offset;
1256 
1257  if (List_buttons[i].pressed()) {
1258  Selected_line = i + Scroll_offset;
1260  }
1261  }
1262 
1263  GR_MAYBE_CLEAR_RES(Background_bitmap);
1264  if (Background_bitmap >= 0) {
1265  gr_set_bitmap(Background_bitmap);
1266  gr_bitmap(0, 0, GR_RESIZE_MENU);
1267  }
1268 
1269  Ui_window.draw();
1270 
1271  for (i=TECH_DATABASE_BUTTON; i<=CREDITS_BUTTON; i++){
1272  if (Buttons[gr_screen.res][i].button.button_down()){
1273  break;
1274  }
1275  }
1276 
1277  if (i > CREDITS_BUTTON){
1279  }
1280 
1286  }
1287  }
1288 
1289  gr_set_font(FONT1);
1292  strcpy_s(buf, Campaign.name);
1293  gr_force_fit_string(buf, 255, list_w1);
1294  gr_printf_menu(list_x1, Mission_list_coords[gr_screen.res][1], buf);
1295 
1296  if (Campaign.filename[0] != '\0') {
1298  gr_force_fit_string(buf, 255, list_w2);
1299  gr_printf_menu(list_x2, Mission_list_coords[gr_screen.res][1], buf);
1300 
1301  // blit the proper icons if necessary
1302  char full_name[256];
1303  memset(full_name, 0, 256);
1306  if(fb != NULL){
1307  // sim_room_blit_icons(0, Mission_list_coords[gr_screen.res][1], fb, 0);
1308  }
1309  }
1310  }
1311 
1312  line = Scroll_offset;
1313  while (sim_room_line_query_visible(line)) {
1314  y = list_y + sim_room_lines[line].y - sim_room_lines[Scroll_offset].y;
1315 
1316  if (sim_room_lines[line].type != READYROOM_LINE_CAMPAIGN) {
1317  List_buttons[line - Scroll_offset].update_dimensions(list_x1, y, list_x2 + list_w2 - list_x1, font_height);
1318  List_buttons[line - Scroll_offset].enable();
1319 
1320  } else
1321  List_buttons[line - Scroll_offset].disable();
1322 
1323  if (line == Selected_line)
1325  else if (line == select_tease_line)
1327  else
1329 
1330  strcpy_s(buf, sim_room_lines[line].name);
1331  gr_force_fit_string(buf, 255, list_x1 + list_w1 - sim_room_lines[line].x);
1332  gr_printf_menu(sim_room_lines[line].x, y, buf);
1333 
1334  if (sim_room_lines[line].filename) {
1335  strcpy_s(buf, sim_room_lines[line].filename);
1336  gr_force_fit_string(buf, 255, list_w2);
1337  gr_printf_menu(list_x2, y, buf);
1338  }
1339 
1340  // blit additional icon information
1341  sim_room_blit_icons(line, y);
1342 
1343  line++;
1344  }
1345 
1346  i = line - Scroll_offset;
1347  while (i < LIST_BUTTONS_MAX)
1348  List_buttons[i++].disable();
1349 
1350  // blit help overlay if active
1352 
1353  gr_flip();
1354 }
1355 
1356 void sim_room_blit_icons(int line_index, int y_start, fs_builtin_mission *fb, int is_md)
1357 {
1358  int is_from_volition = 0;
1359 
1360  // determine icon status
1361  if(fb == NULL){
1362  is_from_volition = (sim_room_lines[line_index].flags & READYROOM_FLAG_FROM_VOLITION) ? 1 : 0;
1363  } else {
1364  is_from_volition = (fb->flags & FSB_FROM_VOLITION) ? 1 : 0;
1365  }
1366 
1367  // if the line is flagged as a volition file
1368  if(is_from_volition && (Mission_icon_bitmaps[MISSION_ICON_VOLITION] >= 0)){
1370  gr_bitmap(Sim_volition_icon_x[gr_screen.res], y_start + MISSION_ICON_VOLITION_Y_OFFSET, GR_RESIZE_MENU);
1371  }
1372 }
1373 
1376  { // GR_640
1377  47, 21, 565, 233
1378  },
1379  { // GR_1024
1380  64, 34, 916, 459
1381  }
1382 };
1383 
1385  { // GR_640
1386  28, 267, 476, 103
1387  },
1388  { // GR_1024
1389  45, 427, 761, 165
1390  },
1391 };
1392 
1393 #define CR_NUM_BUTTONS 6
1394 
1395 #define CR_SCROLL_UP_BUTTON 0
1396 #define CR_SCROLL_DOWN_BUTTON 1
1397 #define CR_SCROLL_INFO_UP_BUTTON 2
1398 #define CR_SCROLL_INFO_DOWN_BUTTON 3
1399 #define CR_RESET_BUTTON 4
1400 #define CR_COMMIT_BUTTON 5
1401 
1402 #define MAX_INFO_LINES 20
1403 
1404 #define MAX_INFO_LINE_LEN 256
1405 
1407  { // GR_640
1408  ui_button_info("CAB_00", 2, 42, -1, -1, 0),
1409  ui_button_info("CAB_01", 2, 89, -1, -1, 1),
1410  ui_button_info("CAB_02", 2, 279, -1, -1, 2),
1411  ui_button_info("CAB_03", 2, 325, -1, -1, 3),
1412  ui_button_info("CAB_04", 579, 353, -1, -1, 4),
1413  ui_button_info("CAB_05", 575, 434, -1, -1, 5),
1414  },
1415  { // GR_1024
1416  ui_button_info("2_CAB_00", 3, 68, -1, -1, 0),
1417  ui_button_info("2_CAB_01", 3, 142, -1, -1, 1),
1418  ui_button_info("2_CAB_02", 3, 446, -1, -1, 2),
1419  ui_button_info("2_CAB_03", 3, 520, -1, -1, 3),
1420  ui_button_info("2_CAB_04", 927, 565, -1, -1, 4),
1421  ui_button_info("2_CAB_05", 920, 694, -1, -1, 5),
1422  }
1423 };
1424 
1425 // text
1426 #define CR_NUM_TEXT 3
1428  { // GR_640
1429  { "Restart", 1403, 569, 326, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[0][CR_RESET_BUTTON].button },
1430  { "Campaign", 1404, 569, 337, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[0][CR_RESET_BUTTON].button },
1431  { "Select", 1409, 568, 413, UI_XSTR_COLOR_PINK, -1, &Cr_buttons[0][CR_COMMIT_BUTTON].button },
1432  },
1433  { // GR_1024
1434  { "Restart", 1403, 922, 523, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[1][CR_RESET_BUTTON].button },
1435  { "Campaign", 1404, 922, 538, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[1][CR_RESET_BUTTON].button },
1436  { "Select", 1409, 921, 665, UI_XSTR_COLOR_PINK, -1, &Cr_buttons[1][CR_COMMIT_BUTTON].button },
1437  }
1438 };
1439 
1440 /*
1441 static struct {
1442  char *text;
1443  int len;
1444 } campaign_desc_lines[MAX_DESC_LINES];
1445 */
1446 
1447 static int Num_desc_lines;
1448 static int Desc_scroll_offset;
1449 static int Selected_campaign_index;
1450 static int Active_campaign_index;
1451 
1454 
1456 {
1457  int font_height = gr_get_font_height();
1458  int i, y;
1459 
1460  Num_lines = y = 0;
1461 
1462  for (i = 0; i < Num_campaigns; i++) {
1463  if (Campaign_names[i] != NULL) {
1464  // determine some extra information
1465  int flags = 0;
1467 
1468  if (fb != NULL) {
1469  if (fb->flags & FSB_FROM_VOLITION) {
1471  }
1472  }
1473 
1475  y += font_height + 2;
1476  }
1477  }
1478 }
1479 
1481 {
1482  char *str;
1483 
1484  Selected_campaign_index = n;
1485  str = Campaign_descs[Selected_campaign_index];
1486  Num_info_lines = 0;
1487  if (str) {
1489  Assert(Num_info_lines >= 0);
1490  }
1491 
1492  Desc_scroll_offset = 0;
1493 }
1494 
1496 {
1497  if (Desc_scroll_offset) {
1498  Desc_scroll_offset--;
1500 
1501  } else
1503 }
1504 
1506 {
1507  if ( (Num_info_lines - Desc_scroll_offset) * gr_get_font_height() > Cr_info_coords[gr_screen.res][3]) {
1508  Desc_scroll_offset++;
1510 
1511  } else
1513 }
1514 
1515 // returns: 0 = success, !0 = aborted or failed
1517 {
1518  char *filename;
1519  int z;
1520 
1521  // z = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_CANCEL, POPUP_OK, XSTR( "Warning\nThis will cause all progress in your\ncurrent campaign to be lost", 110), Campaign_names[n]);
1522  z = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_CANCEL, POPUP_OK, XSTR( "Warning\nThis will cause all progress in your\ncurrent campaign to be lost", 110));
1523  if (z == 1) {
1524  filename = (char *) vm_malloc(strlen(Campaign_file_names[n]) + 5);
1525  strcpy(filename, Campaign_file_names[n]);
1526  strcat(filename, FS_CAMPAIGN_FILE_EXT);
1527 
1529  mission_campaign_load(filename, NULL, 1 , false); // retail doesn't reset stats when resetting the campaign
1531 
1532  vm_free(filename);
1533 
1534  return 0;
1535  }
1536 
1537  return 1;
1538 }
1539 
1541 {
1542  if (Selected_campaign_index < 0) {
1544  return;
1545  }
1546 
1547  if (stricmp(Campaign_file_names[Selected_campaign_index], Campaign.filename)) { // new campaign selected
1548  /* This is all that's stopping us from switching campaigns without restarting - taylor
1549  if ((Active_campaign_index >= 0) && campaign_room_reset_campaign(Active_campaign_index)) {
1550  gamesnd_play_iface(SND_GENERAL_FAIL);
1551  return;
1552  }
1553 
1554  mission_campaign_savefile_delete(Campaign_file_names[Selected_campaign_index]);
1555  */
1556 
1557  // Goober5000 - reinitialize tech database if needed
1558  if ( (Campaign.flags & CF_CUSTOM_TECH_DATABASE) || !stricmp(Campaign.filename, "freespace2") )
1559  {
1560  // reset tech database to what's in the tables
1562  }
1563 
1564  mission_campaign_load(Campaign_file_names[Selected_campaign_index]);
1565  strcpy_s(Player->current_campaign, Campaign.filename); // track new campaign for player
1566  }
1567 
1568  if (mission_campaign_next_mission()) { // is campaign and next mission valid?
1570  return;
1571  }
1572 
1575 }
1576 
1578 {
1579  switch (n) {
1580  case CR_SCROLL_UP_BUTTON:
1582  break;
1583 
1584  case CR_SCROLL_DOWN_BUTTON:
1586  break;
1587 
1590  break;
1591 
1594  break;
1595 
1596  case CR_COMMIT_BUTTON:
1598  break;
1599 
1600  /*
1601  case CR_HELP_BUTTON:
1602  launch_context_help();
1603  gamesnd_play_iface(SND_HELP_PRESSED);
1604  break;
1605 
1606  case CR_OPTIONS_BUTTON:
1607  gamesnd_play_iface(SND_SWITCH_SCREENS);
1608  gameseq_post_event(GS_EVENT_OPTIONS_MENU);
1609  return 1;
1610  */
1611 
1612  case CR_RESET_BUTTON:
1613  if ( (Active_campaign_index < 0) || (Active_campaign_index >= Num_campaigns) )
1615  else if (campaign_room_reset_campaign(Active_campaign_index))
1617  else
1618  {
1620 
1621  // Goober5000 - reinitialize tech database if needed
1622  if ( (Campaign.flags & CF_CUSTOM_TECH_DATABASE) || !stricmp(Campaign.filename, "freespace2") )
1623  {
1624  // reset tech database to what's in the tables
1626  }
1627  }
1628 
1629  break;
1630  }
1631 
1632  return 0;
1633 }
1634 
1636 {
1637  int i, load_failed;
1638  ui_button_info *b;
1639 
1640  list_h = Mission_list_coords[gr_screen.res][3];
1641 
1644 
1645  for (i=0; i<CR_NUM_BUTTONS; i++) {
1646  b = &Cr_buttons[gr_screen.res][i];
1647 
1648  b->button.create(&Ui_window, "", b->x, b->y, 60, 30, (i < 2), 1);
1649  // set up callback for when a mouse first goes over a button
1651  b->button.set_bmaps(b->filename);
1652  b->button.link_hotspot(b->hotspot);
1653  }
1654 
1655  for (i=0; i<LIST_BUTTONS_MAX; i++) {
1656  List_buttons[i].create(&Ui_window, "", 0, 0, 60, 30, 0, 1);
1657  List_buttons[i].hide();
1658  List_buttons[i].disable();
1659  }
1660 
1661  // add xstrs
1662  for(i=0; i<CR_NUM_TEXT; i++){
1663  Ui_window.add_XSTR(&Cr_text[gr_screen.res][i]);
1664  }
1665 
1666  // set up sim_rooms for buttons so we draw the correct animation frame when a key is pressed
1671  // Cr_buttons[gr_screen.res][CR_HELP_BUTTON].button.set_hotkey(KEY_F2);
1672 
1673  Background_bitmap = bm_load(Campaign_filename[gr_screen.res]);
1674 
1675  // load in help overlay bitmap
1678 
1679  Num_desc_lines = 0;
1680  Desc_scroll_offset = Scroll_offset = 0;
1681 
1682  // this stuff needs to happen before the mission_campaign_build_list() call
1683  load_failed = mission_load_up_campaign();
1684  if (!load_failed) {
1686  } else {
1687  Campaign.filename[0] = 0;
1688  Campaign.num_missions = 0;
1689 
1691  }
1692 
1693  // we need descriptions too, so "true" it
1695 
1697 
1698  Selected_campaign_index = Active_campaign_index = -1;
1699  if (!load_failed) {
1700  for (i=0; i<Num_campaigns; i++)
1703  Active_campaign_index = i;
1704  break;
1705  }
1706  }
1707 
1709 }
1710 
1712 {
1713  if (Background_bitmap >= 0)
1714  bm_release(Background_bitmap);
1715 
1716  // free the global Campaign_* list stuff
1718 
1719  Ui_window.destroy();
1720  common_free_interface_palette(); // restore game palette
1721  Pilot.save_player();
1722 }
1723 
1724 void campaign_room_do_frame(float frametime)
1725 {
1726  char buf[256];
1727  char line_text[MAX_INFO_LINE_LEN];
1728  int i, k, y, line;
1729  int font_height = gr_get_font_height();
1730  int select_tease_line = -1; // line mouse is down on, but won't be selected until button released
1731 
1733  // Cr_buttons[gr_screen.res][CR_HELP_BUTTON].button.reset_status();
1734  Ui_window.set_ignore_gadgets(1);
1735  }
1736 
1737  k = Ui_window.process() & ~KEY_DEBUGGED;
1738 
1739  if ( (k > 0) || B1_JUST_RELEASED ) {
1742  Ui_window.set_ignore_gadgets(0);
1743  k = 0;
1744  }
1745  }
1746 
1748  Ui_window.set_ignore_gadgets(0);
1749  }
1750 
1751  switch (k) {
1752  case KEY_DOWN: // scroll list down
1753  if (Selected_campaign_index < Num_campaigns - 1) {
1754  set_new_campaign_line(Selected_campaign_index + 1);
1756 
1757  } else
1759 
1760  break;
1761 
1762  case KEY_UP: // scroll list up
1763  if (Selected_campaign_index < 0)
1764  Selected_campaign_index = 1;
1765 
1766  if (Selected_campaign_index) {
1767  set_new_campaign_line(Selected_campaign_index - 1);
1769 
1770  } else
1772 
1773  break;
1774 
1775  case KEY_ESC:
1777  break;
1778  } // end switch
1779 
1780  for (i=0; i<CR_NUM_BUTTONS; i++){
1781  if (Cr_buttons[gr_screen.res][i].button.pressed()){
1783  return;
1784  }
1785  }
1786  }
1787 
1788  for (i=0; i<LIST_BUTTONS_MAX; i++) {
1789  if (List_buttons[i].is_mouse_on()){
1790  select_tease_line = i + Scroll_offset;
1791  }
1792 
1793  if (List_buttons[i].pressed()) {
1794  set_new_campaign_line(i + Scroll_offset);
1796  }
1797  }
1798 
1799  GR_MAYBE_CLEAR_RES(Background_bitmap);
1800  if (Background_bitmap >= 0) {
1801  gr_set_bitmap(Background_bitmap);
1802  gr_bitmap(0, 0, GR_RESIZE_MENU);
1803  }
1804 
1805  Ui_window.draw();
1806 
1807  gr_set_font(FONT1);
1808  line = Scroll_offset;
1809  while (sim_room_line_query_visible(line)) {
1810  y = Cr_list_coords[gr_screen.res][1] + sim_room_lines[line].y - sim_room_lines[Scroll_offset].y;
1811 
1812  List_buttons[line - Scroll_offset].update_dimensions(Cr_list_coords[gr_screen.res][0], y, Cr_list_coords[gr_screen.res][2], font_height);
1813  List_buttons[line - Scroll_offset].enable();
1814 
1815  if (!stricmp(sim_room_lines[line].filename, Campaign.filename)) {
1817  i = y + font_height / 2 - 1;
1819 
1822  gr_line(Cr_list_coords[gr_screen.res][0] - 6, i - 4, Cr_list_coords[gr_screen.res][0] - 6, i - 2, GR_RESIZE_MENU);
1824  gr_line(Cr_list_coords[gr_screen.res][0] - 6, i + 2, Cr_list_coords[gr_screen.res][0] - 6, i + 4, GR_RESIZE_MENU);
1825  }
1826 
1827  if (line == Selected_campaign_index)
1829  else if (line == select_tease_line)
1831  else
1833 
1834  strcpy_s(buf, sim_room_lines[line].name);
1835  gr_force_fit_string(buf, 255, Cr_list_coords[gr_screen.res][0] + Cr_list_coords[gr_screen.res][2] - sim_room_lines[line].x);
1836  gr_printf_menu(sim_room_lines[line].x, y, buf);
1837  line++;
1838  }
1839 
1840  i = line - Scroll_offset;
1841  while (i < LIST_BUTTONS_MAX)
1842  List_buttons[i++].disable();
1843 
1844  y = 0;
1845  i = Desc_scroll_offset;
1847 
1848  while (y + font_height <= Cr_info_coords[gr_screen.res][3]) {
1849  if (i >= Num_info_lines)
1850  break;
1851 
1853  strncpy(line_text, Info_text_ptrs[i], Info_text_line_size[i]);
1854  line_text[Info_text_line_size[i]] = 0;
1855  drop_white_space(line_text);
1857  y += font_height;
1858  i++;
1859  }
1860 
1861  if (Num_campaigns < 1) {
1862  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "No campaigns are available!", 1613));
1865  }
1866 
1867  // blit help overlay if active
1869 
1870  gr_flip();
1871 }
1872 
1874 {
1875  int idx;
1876 
1877  // load all bitmaps
1878  for(idx=0; idx<NUM_MISSION_ICONS; idx++){
1879  Mission_icon_bitmaps[idx] = -1;
1881  }
1882 }
1883 
1885 {
1886  int idx;
1887 
1888  // unload all bitmaps
1889  for(idx=0; idx<NUM_MISSION_ICONS; idx++){
1890  if(Mission_icon_bitmaps[idx] >= 0){
1891  // don't bm_release() here, used in multiple places - taylor
1893  Mission_icon_bitmaps[idx] = -1;
1894  }
1895  }
1896 }
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
void set_highlight_action(void(*_user_function)(void))
Definition: button.cpp:375
pilotfile Pilot
Definition: pilotfile.cpp:7
#define SIM_MISC_TEXT_FILENAME
Definition: readyroom.cpp:160
int Mission_icon_bitmaps[NUM_MISSION_ICONS]
Definition: readyroom.cpp:256
#define FS_MISSION_FILE_EXT
Definition: missionparse.h:25
#define SCROLL_UP_BUTTON
Definition: readyroom.cpp:73
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
#define SIM_MISC_TEXT_MISSION
Definition: readyroom.cpp:159
void add_XSTR(char *string, int _xstr_id, int _x, int _y, UI_GADGET *_assoc, int _color_type, int _font_id=-1)
Definition: window.cpp:476
char * Campaign_names[MAX_CAMPAIGNS]
const char * Info_text_ptrs[MAX_INFO_LINES]
Definition: readyroom.cpp:1452
void reset_status()
Definition: button.cpp:78
void campaign_room_init()
Definition: readyroom.cpp:1635
#define MAX_INFO_LINES
Definition: readyroom.cpp:1402
void sim_room_scroll_screen_up()
Definition: readyroom.cpp:665
#define KEY_DOWN
Definition: key.h:180
int Game_mode
Definition: systemvars.cpp:24
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
int game_type
Definition: missionparse.h:138
void gr_flip()
Definition: 2d.cpp:2113
commit pressed
Definition: gamesnd.h:294
int x
Definition: ui.h:658
int Cr_info_coords[GR_NUM_RESOLUTIONS][4]
Definition: readyroom.cpp:1384
char Game_current_mission_filename[MAX_FILENAME_LEN]
Definition: fredstubs.cpp:26
#define KEY_PAGEDOWN
Definition: key.h:178
#define GR_RESIZE_MENU
Definition: 2d.h:684
void campaign_room_do_frame(float frametime)
Definition: readyroom.cpp:1724
#define C_SUBTEXT_X
Definition: readyroom.cpp:58
#define MISSION_TAB
Definition: readyroom.cpp:75
#define NUM_SIM_MISC_TEXT
Definition: readyroom.cpp:158
int y
Definition: ui.h:658
char name[NAME_LENGTH]
Definition: missionparse.h:131
char name[NAME_LENGTH]
#define CUTSCENES_BUTTON
Definition: readyroom.cpp:82
int Num_info_lines
Definition: readyroom.cpp:1453
__inline void gr_circle(int xc, int yc, int d, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:774
int sim_room_maybe_resume_savegame()
Definition: readyroom.cpp:785
void campaign_room_commit()
Definition: readyroom.cpp:1540
int Campaign_list_coords[GR_NUM_RESOLUTIONS][4]
Definition: readyroom.cpp:48
Assert(pm!=NULL)
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
void sim_room_unload_mission_icons()
Definition: readyroom.cpp:1884
__inline void gr_string(int x, int y, const char *string, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:769
void campaign_mission_hash_table_delete()
Definition: readyroom.cpp:368
char * Campaign_descs[MAX_CAMPAIGNS]
general failure sound for any event
Definition: gamesnd.h:297
help pressed
Definition: gamesnd.h:293
int res
Definition: 2d.h:370
char * drop_white_space(char *str)
Definition: parselo.cpp:159
int max_h_unscaled
Definition: 2d.h:361
void tech_reset_to_default()
Definition: techmenu.cpp:1438
int x
Definition: readyroom.cpp:191
void forceUp()
Definition: slider2.cpp:309
hash_node * next
Definition: readyroom.cpp:234
char * Sim_mask_filename[GR_NUM_RESOLUTIONS]
Definition: readyroom.cpp:138
#define GR_MAYBE_CLEAR_RES(bmap)
Definition: 2d.h:639
void help_overlay_set_state(int overlay_id, int resolution_index, int state)
void set_ignore_gadgets(int state)
Definition: window.cpp:471
virtual void hide(int n)
Definition: gadget.cpp:207
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
#define KEY_PAGEUP
Definition: key.h:175
Definition: ui.h:195
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
int max_w_unscaled
Definition: 2d.h:361
#define KEY_DELETE
Definition: key.h:176
#define CAMPAIGN_MISSION_HASH_SIZE
Definition: readyroom.cpp:90
#define CR_SCROLL_DOWN_BUTTON
Definition: readyroom.cpp:1396
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define CREDITS_BUTTON
Definition: readyroom.cpp:83
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
bool Campaign_room_no_campaigns
Definition: readyroom.cpp:228
void forceDown()
Definition: slider2.cpp:302
char * name
UI_XSTR Cr_text[GR_NUM_RESOLUTIONS][CR_NUM_TEXT]
Definition: readyroom.cpp:1427
GLenum type
Definition: Gl.h:1492
#define B1_JUST_RELEASED
Definition: uidefs.h:50
#define READYROOM_LINE_MISSION
Definition: readyroom.cpp:184
#define READYROOM_FLAG_FROM_VOLITION
Definition: readyroom.cpp:186
void common_set_interface_palette(char *filename)
void draw_forced(int frame_num)
Definition: button.cpp:104
int sim_room_line_add(int type, char *name, char *filename, int x, int y, int flags)
Definition: readyroom.cpp:393
#define LIST_BUTTONS_MAX
Definition: readyroom.cpp:71
#define MAX_MISSIONS
Definition: readyroom.cpp:37
#define FS_CAMPAIGN_FILE_EXT
Definition: freespace.h:26
void destroy()
Definition: window.cpp:189
#define SIMULATOR_BUTTON
Definition: readyroom.cpp:81
int Sim_room_slider_coords[GR_NUM_RESOLUTIONS][4]
Definition: readyroom.cpp:172
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
void set_mask_bmap(char *fname)
Definition: window.cpp:75
int set_bmaps(char *ani_filename, int nframes=3, int start_frame=1)
Definition: gadget.cpp:71
#define MISSION_TYPE_SINGLE
Definition: missionparse.h:61
int hash_insert(char *filename)
Definition: readyroom.cpp:284
void sim_room_build_listing()
Definition: readyroom.cpp:562
void common_free_interface_palette()
void set_numberItems(int _numberItems, int _reset=1)
Definition: slider2.cpp:217
char * Mission_icon_bitmap_filenames[NUM_MISSION_ICONS]
Definition: readyroom.cpp:258
int sim_room_line_query_visible(int n)
Definition: readyroom.cpp:651
void campaign_room_close()
Definition: readyroom.cpp:1711
int build_campaign_mission_list_do_frame()
Definition: readyroom.cpp:505
#define CR_COMMIT_BUTTON
Definition: readyroom.cpp:1400
int build_standalone_mission_list_do_frame()
Definition: readyroom.cpp:445
int flags
Definition: readyroom.cpp:193
int mission_parse_is_multi(const char *filename, char *mission_name)
#define GM_MULTIPLAYER
Definition: systemvars.h:18
char current_campaign[MAX_FILENAME_LEN+1]
Definition: player.h:101
char * filename
Definition: readyroom.cpp:235
char * Sim_filename[GR_NUM_RESOLUTIONS]
Definition: readyroom.cpp:134
ui_button_info Cr_buttons[GR_NUM_RESOLUTIONS][CR_NUM_BUTTONS]
Definition: readyroom.cpp:1406
char * filename
Definition: readyroom.cpp:190
void create(UI_WINDOW *wnd, int _x, int _y, int _w, int _h, int _numberItems, char *_bitmapSliderControl, void(*_upCallback)(), void(*_downCallback)(), void(*_captureCallback)())
Definition: slider2.cpp:21
int readyroom_listing_mode
Definition: player.h:102
int hotspot
Definition: ui.h:659
int sim_room_standalone_mission_filter(const char *filename)
Definition: readyroom.cpp:422
int build_campaign_mission_filename_hash_table()
Definition: readyroom.cpp:351
int pressed()
Definition: button.cpp:325
Switching to a new screen, but not commit.
Definition: gamesnd.h:292
#define KEY_SHIFTED
Definition: key.h:62
#define H_COORD
Definition: readyroom.cpp:88
unsigned __int64 ulonglong
Definition: pstypes.h:61
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
#define OPTIONS_BUTTON
Definition: readyroom.cpp:79
int y
Definition: readyroom.cpp:192
GLdouble GLdouble z
Definition: Glext.h:5451
#define KEY_ENTER
Definition: key.h:125
#define W_COORD
Definition: readyroom.cpp:87
int campaign_mission_hash_collision(const char *filename)
Definition: readyroom.cpp:327
#define vm_strdup(ptr)
Definition: pstypes.h:549
#define CAMPAIGN_ROOM_OVERLAY
Definition: contexthelp.h:33
void sim_room_do_frame(float frametime)
Definition: readyroom.cpp:1172
#define Y_COORD
Definition: readyroom.cpp:86
Definition: ui.h:428
int split_str(const char *src, int max_pixel_w, int *n_chars, const char **p_str, int max_lines, char ignore_char)
Definition: parselo.cpp:3412
int Info_text_line_size[MAX_INFO_LINES]
Definition: readyroom.cpp:1453
UI_BUTTON button
Definition: ui.h:660
#define MODE_CAMPAIGNS
Definition: readyroom.cpp:65
#define CF_CUSTOM_TECH_DATABASE
void sim_room_init()
Definition: readyroom.cpp:992
bool save_player(player *_p=NULL)
Definition: plr.cpp:935
int idx
Definition: multiui.cpp:761
char * name
Definition: readyroom.cpp:189
int type
Definition: readyroom.cpp:188
int sim_room_button_pressed(int n)
Definition: readyroom.cpp:911
#define TECH_DATABASE_BUTTON
Definition: readyroom.cpp:80
void mission_campaign_savefile_delete(char *cfilename)
void campaign_room_scroll_info_down()
Definition: readyroom.cpp:1505
GLint GLint GLint GLint GLint x
Definition: Glext.h:5182
#define M_TEXT_X
Definition: readyroom.cpp:63
GLclampd n
Definition: Glext.h:7286
void sim_room_scroll_line_up()
Definition: readyroom.cpp:685
int get_mission_info(const char *filename, mission *mission_p, bool basic)
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
int sim_room_campaign_mission_filter(const char *filename)
Definition: readyroom.cpp:408
void campaign_room_build_listing()
Definition: readyroom.cpp:1455
int mission_load_up_campaign(player *pl)
user_click (mouse selects a control)
Definition: gamesnd.h:305
#define NOX(s)
Definition: pstypes.h:473
void sim_room_reset_campaign_listing()
Definition: readyroom.cpp:631
int Mission_list_coords[GR_NUM_RESOLUTIONS][4]
Definition: readyroom.cpp:39
int sim_room_can_resume_savegame(char *savegame_filename)
Definition: readyroom.cpp:762
#define MAX_INFO_LINE_LEN
Definition: readyroom.cpp:1404
GLbitfield flags
Definition: Glext.h:6722
#define vm_malloc(size)
Definition: pstypes.h:547
void set_hotkey(int keycode)
Definition: gadget.cpp:280
void sim_room_scroll_line_down()
Definition: readyroom.cpp:721
int hash_filename(const char *filename)
Definition: readyroom.cpp:269
int readyroom_continue_campaign()
Definition: readyroom.cpp:845
GLuint const GLchar * name
Definition: Glext.h:5608
__inline void gr_line(int x1, int y1, int x2, int y2, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:791
void sim_room_blit_icons(int line_index, int y_start, fs_builtin_mission *fb=NULL, int is_md=0)
Definition: readyroom.cpp:1356
char * cf_add_ext(const char *filename, const char *ext)
Definition: cfile.cpp:458
int current_mission
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
color Color_text_subselected
Definition: alphacolors.cpp:26
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
struct hash_node hash_node
#define CR_RESET_BUTTON
Definition: readyroom.cpp:1399
int Campaign_room_overlay_id
Definition: readyroom.cpp:225
int campaign_room_reset_campaign(int n)
Definition: readyroom.cpp:1516
#define NUM_BUTTONS
Definition: readyroom.cpp:70
void update_dimensions(int _x, int _y, int _w, int _h)
Definition: gadget.cpp:187
color Color_text_selected
Definition: alphacolors.cpp:26
#define CR_SCROLL_UP_BUTTON
Definition: readyroom.cpp:1395
GLuint GLuint num
Definition: Glext.h:9089
color Color_bright_white
Definition: alphacolors.cpp:32
void mission_campaign_eval_next_mission()
#define FONT1
Definition: font.h:65
#define SIM_ROOM_OVERLAY
Definition: contexthelp.h:34
scroll pressed (and scroll)
Definition: gamesnd.h:296
color Color_white
Definition: alphacolors.cpp:32
void sim_room_scroll_screen_down()
Definition: readyroom.cpp:701
void link_hotspot(int num)
Definition: gadget.cpp:50
campaign Campaign
#define strcat_s(...)
Definition: safe_strings.h:68
void create(UI_WINDOW *wnd, char *_text, int _x, int _y, int _w, int _h, int do_repeat=0, int ignore_focus=0)
Definition: button.cpp:26
#define KEY_ESC
Definition: key.h:124
int mission_campaign_load(char *filename, player *pl, int load_savefile, bool reset_stats)
#define UI_XSTR_COLOR_PINK
Definition: ui.h:161
void stop_parse()
Definition: parselo.cpp:2071
int button_down()
Definition: button.cpp:363
void create(int _x, int _y, int _w, int _h, int _flags, int _f_id=-1)
Definition: window.cpp:140
player * Player
int Sim_misc_text_coords[GR_NUM_RESOLUTIONS][NUM_SIM_MISC_TEXT][2]
Definition: readyroom.cpp:161
UI_BUTTON button
Definition: readyroom.cpp:96
int gr_force_fit_string(char *str, int max_str, int max_width)
Definition: font.cpp:48
void sim_room_scroll_capture()
Definition: readyroom.cpp:981
Definition: ui.h:584
void sim_room_commit()
Definition: readyroom.cpp:896
screen gr_screen
Definition: 2d.cpp:46
#define CR_NUM_TEXT
Definition: readyroom.cpp:1426
#define CF_SORT_NAME
Definition: cfile.h:93
#define CR_SCROLL_INFO_DOWN_BUTTON
Definition: readyroom.cpp:1398
Definition: ui.h:162
#define FSB_FROM_VOLITION
Definition: freespace.h:76
void enable(int n=1)
Definition: gadget.cpp:440
#define KEY_F2
Definition: key.h:144
int gr_get_font_height()
Definition: font.cpp:187
#define CF_TYPE_MISSIONS
Definition: cfile.h:74
#define KEY_DEBUGGED
Definition: key.h:65
int mission_campaign_get_mission_list(const char *filename, char **list, int max)
#define READYROOM_LINE_CMISSION
Definition: readyroom.cpp:183
int campaign_room_button_pressed(int n)
Definition: readyroom.cpp:1577
void common_play_highlight_sound()
Definition: gamesnd.cpp:1151
#define CR_SCROLL_INFO_UP_BUTTON
Definition: readyroom.cpp:1397
#define READYROOM_LINE_CAMPAIGN
Definition: readyroom.cpp:182
int mission_campaign_next_mission()
#define KEY_CTRLED
Definition: key.h:64
#define KEY_TAB
Definition: key.h:127
char * filename
Definition: ui.h:657
char * Campaign_mask_filename[GR_NUM_RESOLUTIONS]
Definition: readyroom.cpp:147
#define MAX_CAMPAIGN_MISSIONS
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
#define CAMPAIGN_LOOP_MISSION_UNINITIALIZED
#define KEY_UP
Definition: key.h:179
#define X_COORD
Definition: readyroom.cpp:85
#define UI_XSTR_COLOR_GREEN
Definition: ui.h:160
void campaign_room_scroll_info_up()
Definition: readyroom.cpp:1495
color Color_text_normal
Definition: alphacolors.cpp:26
sim_room_buttons(char *name, int x1, int y1, int xt1, int yt1, int h)
Definition: readyroom.cpp:98
char filename[MAX_FILENAME_LEN]
int temp
Definition: lua.cpp:4996
char * Sim_room_slider_filename[GR_NUM_RESOLUTIONS]
Definition: readyroom.cpp:152
int Cr_list_coords[GR_NUM_RESOLUTIONS][4]
Campaign room stuff below.
Definition: readyroom.cpp:1375
void mission_campaign_build_list(bool desc, bool sort, bool multiplayer)
#define SCROLL_DOWN_BUTTON
Definition: readyroom.cpp:74
#define MAX_LINES
Definition: readyroom.cpp:68
color Color_text_heading
Definition: alphacolors.cpp:28
#define MISSION_ICON_VOLITION
Definition: readyroom.cpp:243
int bm_unload(int handle, int clear_render_targets, bool nodebug)
Unloads a bitmap's data, but not the bitmap info.
Definition: bmpman.cpp:2890
void launch_context_help()
void gamesnd_play_iface(int n)
Definition: gamesnd.cpp:260
mission The_mission
int Num_campaigns
void disable()
Definition: gadget.cpp:432
void draw()
Definition: window.cpp:220
#define COMMIT_BUTTON
Definition: readyroom.cpp:78
struct ui_button_info ui_button_info
void gr_set_font(int fontnum)
Definition: font.cpp:566
#define KEY_S
Definition: key.h:100
void sim_room_close()
Definition: readyroom.cpp:1116
#define MISSION_ICON_VOLITION_Y_OFFSET
Definition: readyroom.cpp:247
int cf_get_file_list(SCP_vector< SCP_string > &list, int pathtype, const char *filter, int sort=CF_SORT_NONE, SCP_vector< file_list_info > *info=NULL)
char * Campaign_filename[GR_NUM_RESOLUTIONS]
Definition: readyroom.cpp:143
int process(int key_in=-1, int process_mouse=1)
Definition: window.cpp:401
int help_overlay_get_index(const char *overlay_name)
void _cdecl gr_printf_menu(int x, int y, const char *format,...)
Definition: font.cpp:314
void gameseq_post_event(int event)
#define CMISSION_FLAG_HAS_LOOP
void sim_room_load_mission_icons()
Definition: readyroom.cpp:1873
#define GM_CAMPAIGN_MODE
Definition: systemvars.h:29
char * Campaign_file_names[MAX_CAMPAIGNS]
#define stricmp(s1, s2)
Definition: config.h:271
#define CR_NUM_BUTTONS
Definition: readyroom.cpp:1393
void help_overlay_maybe_blit(int overlay_id, int resolution_index)
#define MODE_MISSIONS
Definition: readyroom.cpp:66
#define NUM_MISSION_ICONS
Definition: readyroom.cpp:242
int help_overlay_active(int overlay_id)
void mission_campaign_free_list()
cmission missions[MAX_CAMPAIGN_MISSIONS]
#define HELP_BUTTON
Definition: readyroom.cpp:77
GLint y
Definition: Gl.h:1505
int(* Get_file_list_filter)(const char *filename)
#define strcpy_s(...)
Definition: safe_strings.h:67
void mission_campaign_load_failure_popup()
struct fs_builtin_mission * game_find_builtin_mission(char *)
Definition: fredstubs.cpp:203
#define CAMPAIGN_TAB
Definition: readyroom.cpp:76
void set_new_campaign_line(int n)
Definition: readyroom.cpp:1480
int Sim_room_overlay_id
Definition: readyroom.cpp:224