2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/MenuUI/TechMenu.cpp $
15 * C module that contains functions to drive the Tech Menu user interface
18 * Revision 1.4 2002/06/09 04:41:22 relnev
19 * added copyright header
21 * Revision 1.3 2002/06/02 04:26:34 relnev
24 * Revision 1.2 2002/05/07 03:16:46 theoddone33
25 * The Great Newline Fix
27 * Revision 1.1.1.1 2002/05/03 03:28:09 root
31 * 43 11/02/99 3:22p Jefff
32 * translate ship names in tech room
34 * 42 10/25/99 5:47p Jefff
35 * reassigned some xstr ids
37 * 41 10/12/99 4:50p Jefff
39 * 40 9/08/99 11:09a Dave
40 * Use stills for intel and weapon stuff in the techroom if animations
43 * 39 9/05/99 11:19p Dave
44 * Made d3d texture cache much more safe. Fixed training scoring bug where
45 * it would backout scores without ever having applied them in the first
48 * 38 9/03/99 11:19a Jefff
49 * fixed double render of intel descriptions
51 * 37 9/03/99 1:32a Dave
52 * CD checking by act. Added support to play 2 cutscenes in a row
53 * seamlessly. Fixed super low level cfile bug related to files in the
54 * root directory of a CD. Added cheat code to set campaign mission # in
57 * 36 9/01/99 5:12p Jefff
58 * Fixed bad scroll bug
60 * 35 8/25/99 3:03p Jefff
61 * 'more' indicator, lotsa coord changes for new background, disabling of
62 * buttons in trackball mode, list follows selected item when prev/next
65 * 34 8/24/99 8:55p Dave
66 * Make sure nondimming pixels work properly in tech menu.
68 * 33 8/24/99 10:47a Jefff
69 * tech room weapon anims. added tech anim field to weapons.tbl
71 * 32 8/10/99 5:29p Jefff
72 * use new tech_title field in weapons array
74 * 31 8/10/99 3:45p Jefff
75 * Put the smack down on the tech room. Its all new, but tastefully done.
77 * 30 8/09/99 5:53p Jefff
79 * 29 8/02/99 10:27a Jefff
80 * removed a warning for the time being
82 * 28 8/02/99 10:13a Jefff
83 * started scrubbing, waiting till after demo to continue
85 * 27 7/28/99 1:02p Jefff
86 * Changed "Species" to "Intelligence" -- also changed in strings.tbl.
88 * 26 7/26/99 4:33p Jordonr
89 * Don't need techroom palette
91 * 25 7/20/99 1:49p Dave
92 * Peter Drake build. Fixed some release build warnings.
94 * 24 7/19/99 2:13p Dave
95 * Added some new strings for Heiko.
97 * 23 7/14/99 9:42a Dave
98 * Put in clear_color debug function. Put in base for 3dnow stuff / P3
101 * 22 6/16/99 4:06p Dave
102 * New pilot info popup. Added new draw-bitmap-as-poly function.
104 * 21 5/09/99 8:57p Dave
105 * Final E3 build preparations.
107 * 20 5/09/99 6:00p Dave
108 * Lots of cool new effects. E3 build tweaks.
110 * 19 4/29/99 2:16p Neilk
111 * added a 2nd callback for slider so its model is not loaded on mouselock
112 * until mouse button is released
114 * 18 4/26/99 5:05p Neilk
115 * updated to new artwork, added slider support
117 * 17 4/25/99 3:02p Dave
118 * Build defines for the E3 build.
120 * 16 4/23/99 12:01p Johnson
121 * Added SIF_HUGE_SHIP
123 * 15 4/12/99 10:07p Dave
124 * Made network startup more forgiving. Added checkmarks to dogfight
125 * screen for players who hit commit.
127 * 14 4/08/99 2:10a Dave
128 * Numerous bug fixes for the beta. Added builtin mission info for the
131 * 13 2/19/99 11:42a Dave
132 * Put in model rendering autocentering.
134 * 12 2/01/99 5:55p Dave
135 * Removed the idea of explicit bitmaps for buttons. Fixed text
136 * highlighting for disabled gadgets.
138 * 11 1/30/99 5:08p Dave
139 * More new hi-res stuff.Support for nice D3D textures.
141 * 10 1/29/99 3:56p Neilk
142 * Converted tech_infos screens to multiresolution
144 * 9 1/29/99 3:54p Neilk
146 * 8 1/29/99 12:47a Dave
147 * Put in sounds for beam weapon. A bunch of interface screens (tech
150 * 7 11/30/98 1:07p Dave
151 * 16 bit conversion, first run.
153 * 6 10/23/98 3:51p Dave
154 * Full support for tstrings.tbl and foreign languages. All that remains
155 * is to make it active in Fred.
157 * 5 10/16/98 9:40a Andsager
158 * Remove ".h" files from model.h
160 * 4 10/13/98 2:47p Andsager
161 * Remove reference to Tech_shivan_species_avail
163 * 3 10/13/98 9:28a Dave
164 * Started neatening up freespace.h. Many variables renamed and
165 * reorganized. Added AlphaColors.[h,cpp]
167 * 2 10/07/98 10:53a Dave
170 * 1 10/07/98 10:49a Dave
172 * 67 9/21/98 10:02p Dave
173 * Last minute changes to techroom weapon/ship/species stuff.
175 * 66 9/07/98 2:49p Dan
176 * Removed spurious Assert
178 * 65 7/06/98 2:42p Hoffoss
179 * Fixed bug with weapons shown in tech database.
181 * 64 6/10/98 11:48a Lawrance
182 * fix bug with trying to free NULL anims
184 * 63 6/05/98 9:54a Lawrance
187 * 62 6/01/98 11:43a John
188 * JAS & MK: Classified all strings for localization.
190 * 61 5/26/98 11:10a Lawrance
191 * Fix bug where window controls get disabled when F1 pressed twice
193 * 60 5/23/98 10:38p Lawrance
194 * Avoid doing a cfile refresh when running debug
196 * 59 5/23/98 6:49p Lawrance
197 * Fix problems with refreshing the file list when a CD is inserted
199 * 58 5/22/98 11:15a Lawrance
200 * Tweak how CD gets asked for
202 * 57 5/22/98 1:06a Hoffoss
203 * Made Fred not use OLE.
205 * 56 5/21/98 6:57p Lawrance
206 * Only ask for the CD once
208 * 55 5/21/98 12:46a Hoffoss
209 * Made text offset reset when new description is loaded.
211 * 54 5/20/98 9:46p John
212 * added code so the places in code that change half the palette don't
213 * have to clear the screen.
215 * 53 5/20/98 3:28p Sandeep
216 * Fixed bug where in multi only discovered weapons show up, and in single
217 * all weapons showed up (backwards).
219 * 52 5/20/98 2:11p Hoffoss
220 * Fixed some species description problems.
222 * 51 5/18/98 6:45p Hoffoss
223 * Added species descriptions to species database in techroom.
225 * 50 5/17/98 6:13p Hoffoss
226 * Fixed scrolling of info text area.
232 #include "gamesequence.h"
233 #include "techmenu.h"
236 #include "snazzyui.h"
237 #include "managepilot.h"
241 #include "missioncampaign.h"
242 #include "missionshipchoice.h"
243 #include "freespace.h"
244 #include "mainhallmenu.h"
245 #include "missionscreencommon.h"
251 #include "contexthelp.h"
252 #include "alphacolors.h"
253 #include "animplay.h"
254 #include "localize.h"
255 #include "lighting.h"
257 #define REVOLUTION_RATE 5.2f
259 #define NUM_BUTTONS 16
261 #define LIST_BUTTONS_MAX 41
263 #define SHIPS_DATA_MODE (1<<0)
264 #define WEAPONS_DATA_MODE (1<<1)
265 #define SPECIES_DATA_MODE (1<<2)
266 #define WEAPONS_SPECIES_DATA_MODE (WEAPONS_DATA_MODE | SPECIES_DATA_MODE)
268 #define SHIPS_DATA_TAB 0
269 #define WEAPONS_DATA_TAB 1
270 #define INTEL_DATA_TAB 2
271 #define TECH_DATABASE_TAB 3
272 #define SIMULATOR_TAB 4
273 #define CUTSCENES_TAB 5
274 #define CREDITS_TAB 6
276 #define SCROLL_LIST_UP 7
277 #define SCROLL_LIST_DOWN 8
278 #define SCROLL_INFO_UP 9
279 #define SCROLL_INFO_DOWN 10
281 #define PREV_ENTRY_BUTTON 11
282 #define NEXT_ENTRY_BUTTON 12
284 #define HELP_BUTTON 13
285 #define OPTIONS_BUTTON 14
286 #define EXIT_BUTTON 15
288 //#define PREV_ENTRY_BUTTON2 16
289 //#define NEXT_ENTRY_BUTTON2 17
292 #define REPEAT (1<<0)
293 #define NO_MOUSE_OVER_SOUND (1<<1)
295 // indicies for coords
296 #define SHIP_X_COORD 0
297 #define SHIP_Y_COORD 1
298 #define SHIP_W_COORD 2
299 #define SHIP_H_COORD 3
301 // background filename for species
302 // note weapon filename is now same as ship filename
303 char *Tech_background_filename[GR_NUM_RESOLUTIONS] = {
307 char *Tech_mask_filename[GR_NUM_RESOLUTIONS] = {
311 char *Tech_slider_filename[GR_NUM_RESOLUTIONS] = {
316 int Tech_list_coords[GR_NUM_RESOLUTIONS][4] = {
325 int Tech_ship_display_coords[GR_NUM_RESOLUTIONS][4] = {
334 int Tech_desc_coords[GR_NUM_RESOLUTIONS][4] = {
343 int Tech_ani_coords[GR_NUM_RESOLUTIONS][2] = {
352 /*int Tech_desc_coords[GR_NUM_RESOLUTIONS][4] = {
361 int Tech_slider_coords[GR_NUM_RESOLUTIONS][4] = {
371 int Tech_detail_backup;
372 int Tech_texture_backup;
374 #define MAX_TEXT_LINES 100
375 #define MAX_TEXT_LINE_LEN 256
377 struct techroom_buttons {
383 UI_BUTTON button; // because we have a class inside this struct, we need the constructor below..
385 techroom_buttons(char *name, int x1, int y1, int xt1, int yt1, int h, int t, int f = 0) : filename(name), x(x1), y(y1), xt(xt1), yt(yt1), hotspot(h), tab(t), flags(f) {}
388 static techroom_buttons Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
390 techroom_buttons("TDB_04", 406, 384, 447, 393, 4, -1), // ship data tab
391 techroom_buttons("TDB_05", 404, 418, 447, 429, 5, -1), // weapons data tab
392 techroom_buttons("TDB_06", 404, 447, 447, 461, 6, -1), // species data tab
393 techroom_buttons("TDB_00", 7, 3, 37, 7, 0, -1), // technical database tab
394 techroom_buttons("TDB_01", 7, 18, 37, 23, 1, -1), // mission simulator tab
395 techroom_buttons("TDB_02", 7, 34, 37, 38, 2, -1), // cutscenes tab
396 techroom_buttons("TDB_03", 7, 49, 37, 54, 3, -1), // credits tab
397 techroom_buttons("TDB_07", 1, 86, -1, -1, 7, SHIPS_DATA_MODE, REPEAT), // prev data entry
398 techroom_buttons("TDB_08", 1, 317, -1, -1, 8, SHIPS_DATA_MODE, REPEAT), // next data entry
399 techroom_buttons("TDB_09", 1, 406, -1, -1, 9, SHIPS_DATA_MODE, REPEAT), // prev data entry
400 techroom_buttons("TDB_10", 1, 447, -1, -1, 10, SHIPS_DATA_MODE, REPEAT), // next data entry
401 //techroom_buttons("TDB_11", 558, 272, -1, -1, 11, WEAPONS_SPECIES_DATA_MODE), // prev data entry
402 //techroom_buttons("TDB_12", 606, 272, -1, -1, 12, WEAPONS_SPECIES_DATA_MODE), // next data entry
403 techroom_buttons("TDB_11a",559, 323, -1, -1, 11, SHIPS_DATA_MODE, REPEAT), // prev data entry
404 techroom_buttons("TDB_12a",609, 323, -1, -1, 12, SHIPS_DATA_MODE, REPEAT), // next data entry
405 techroom_buttons("TDB_13", 533, 425, 500, 440, 13, -1), // help
406 techroom_buttons("TDB_14", 533, 455, 479, 464, 14, -1), // options
407 techroom_buttons("TDB_15a",571, 425, 588, 413, 15, -1), // exit
410 techroom_buttons("2_TDB_04", 649, 614, 717, 630, 4, -1), // ship data tab
411 techroom_buttons("2_TDB_05", 646, 669, 717, 687, 5, -1), // weapons data tab
412 techroom_buttons("2_TDB_06", 646, 716, 717, 739, 6, -1), // species data tab
413 techroom_buttons("2_TDB_00", 12, 5, 59, 12, 0, -1), // technical database tab
414 techroom_buttons("2_TDB_01", 12, 31, 59, 37, 1, -1), // mission simulator tab
415 techroom_buttons("2_TDB_02", 12, 56, 59, 62, 2, -1), // cutscenes tab
416 techroom_buttons("2_TDB_03", 12, 81, 59, 88, 3, -1), // credits tab
417 techroom_buttons("2_TDB_07", 1, 138, -1, -1, 7, SHIPS_DATA_MODE, REPEAT), // prev data entry
418 techroom_buttons("2_TDB_08", 1, 507, -1, -1, 8, SHIPS_DATA_MODE, REPEAT), // next data entry
419 techroom_buttons("2_TDB_09", 1, 649, -1, -1, 9, SHIPS_DATA_MODE, REPEAT), // prev data entry
420 techroom_buttons("2_TDB_10", 1, 716, -1, -1, 10, SHIPS_DATA_MODE, REPEAT), // next data entry
421 //techroom_buttons("2_TDB_11", 893, 436, -1, -1, 11, WEAPONS_SPECIES_DATA_MODE), // prev data entry
422 //techroom_buttons("2_TDB_12", 970, 436, -1, -1, 12, WEAPONS_SPECIES_DATA_MODE), // next data entry
423 techroom_buttons("2_TDB_11a", 895, 518, -1, -1, 11, SHIPS_DATA_MODE, REPEAT), // prev data entry
424 techroom_buttons("2_TDB_12a", 974, 518, -1, -1, 12, SHIPS_DATA_MODE, REPEAT), // next data entry
425 techroom_buttons("2_TDB_13", 854, 681, 800, 704, 13, -1), // help
426 techroom_buttons("2_TDB_14", 854, 728, 780, 743, 14, -1), // options
427 techroom_buttons("2_TDB_15a", 914, 681, 930, 660, 15, -1), // exit
431 static UI_WINDOW Ui_window;
432 static UI_BUTTON View_window;
433 //static int Background_bitmap;
434 static int Tech_background_bitmap;
436 // static int List_size;
437 static int List_offset;
438 static int Select_tease_line;
439 static int Trackball_mode = 1;
440 static int Trackball_active = 0;
441 static matrix Techroom_ship_orient = IDENTITY_MATRIX;
442 // static int Tech_room_ask_for_cd;
444 static int Text_size;
445 static int Text_offset;
446 static int Text_line_size[MAX_TEXT_LINES];
447 static char *Text_lines[MAX_TEXT_LINES];
449 static int Cur_entry; // this is the current entry selected, using entry indexing
450 static int Cur_entry_index; // this is the current entry selected, using master list indexing
451 static int Techroom_ship_modelnum;
452 static float Techroom_ship_rot;
453 static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list
454 static int Anim_playing_id = -1;
455 static anim_instance *Cur_anim_instance = NULL;
456 static int Palette_bmp;
457 //static int ShipWin01;
458 //static int ShipWin02;
459 //static int ShipWin03;
460 //static int ShipWin04;
461 static ubyte Palette[768];
462 static char Palette_name[128];
464 static int Ships_loaded = 0;
465 static int Weapons_loaded = 0;
466 static int Intel_loaded = 0;
468 // out entry data struct & vars
470 int index; // index into the master table that its in (ie Ship_info[])
471 char* name; // ptr to name string
472 char* desc; // ptr to description string
473 anim* animation; // ptr to the animation
474 int bitmap; // bitmap handle
475 int has_anim; // flag to indicate the presence of an animation for this item
478 static tech_list_entry Ship_list[MAX_SHIP_TYPES];
479 static int Ship_list_size = 0;
480 static tech_list_entry Weapon_list[MAX_WEAPON_TYPES];
481 static int Weapon_list_size = 0;
482 static tech_list_entry Intel_list[MAX_INTEL_ENTRIES];
483 static int Intel_list_size = 0;
484 static tech_list_entry *Current_list; // points to currently valid display list
485 static int Current_list_size = 0;
489 static UI_SLIDER2 Tech_slider;
493 static char *Intel_anim_filenames[MAX_INTEL_ENTRIES] = {
501 // Intelligence master data structs (these get inited @ game startup from species.tbl)
502 intel_data Intel_info[MAX_INTEL_ENTRIES];
503 int Intel_info_size = 0;
505 // some prototypes to make you happy
506 int techroom_load_ani(anim **animpp, char *name);
507 void tech_common_render();
508 void techroom_start_anim();
509 void tech_scroll_list_up();
510 void tech_scroll_list_down();
515 ////////////////////////////////////////////////////
516 // like, functions and stuff
518 void techroom_init_desc(char *src, int w)
520 Text_size = Text_offset = 0;
525 Text_size = split_str(src, w, Text_line_size, Text_lines, MAX_TEXT_LINES);
526 Assert(Text_size >= 0 && Text_size < MAX_TEXT_LINES);
529 void techroom_select_new_entry()
531 Assert(Current_list != NULL);
532 if (Current_list == NULL) return;
534 Cur_entry_index = Current_list[Cur_entry].index;
536 // if we are in the ships tab, load the ship model
537 if (Tab == SHIPS_DATA_TAB) {
538 ship_info *sip = &Ship_info[Cur_entry_index];
540 #ifdef MULTIPLAYER_BETA_BUILD
541 // don't load supercaps in the beta
542 if((sip->flags & SIF_SUPERCAP) || (sip->flags & SIF_DRYDOCK)){
543 Techroom_ship_modelnum = -1;
545 Techroom_ship_modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
548 // page in ship textures properly (takes care of nondimming pixels)
549 model_page_in_textures(Techroom_ship_modelnum, Cur_entry_index);
551 Techroom_ship_modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
553 // page in ship textures properly (takes care of nondimming pixels)
554 model_page_in_textures(Techroom_ship_modelnum, Cur_entry_index);
557 Techroom_ship_modelnum = -1;
561 // Techroom_ship_rot = PI;
563 techroom_init_desc(Current_list[Cur_entry].desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
564 techroom_start_anim();
567 // write out the current description in the bottom window
568 void techroom_render_desc(int xo, int yo, int h)
570 int y, z, len, font_height;
571 char line[MAX_TEXT_LINE_LEN + 1];
573 font_height = gr_get_font_height();
577 while (y + font_height <= h) {
582 len = Text_line_size[z];
583 if (len > MAX_TEXT_LINE_LEN){
584 len = MAX_TEXT_LINE_LEN;
587 strncpy(line, Text_lines[z], len);
589 gr_string(xo, yo + y, line);
595 // maybe output 'more' indicator
596 if ( z < Text_size ) {
597 // can be scrolled down
598 int more_txt_x = Tech_desc_coords[gr_screen.res][0] + (Tech_desc_coords[gr_screen.res][2]/2) - 10; // FIXME should move these to constants since they dont move
599 int more_txt_y = Tech_desc_coords[gr_screen.res][1] + Tech_desc_coords[gr_screen.res][3]; // located below brief text, centered
601 gr_get_string_size(&w, &h, XSTR("more", 1469), strlen(XSTR("more", 1469)));
602 gr_set_color_fast(&Color_black);
603 gr_rect(more_txt_x-2, more_txt_y, w+3, h);
604 gr_set_color_fast(&Color_red);
605 gr_string(more_txt_x, more_txt_y, XSTR("more", 1469)); // base location on the input x and y?
610 // new version of weapons
611 void techroom_weapons_render2(float frametime)
613 // render common stuff
614 tech_common_render();
616 // render the animation
618 // JAS: This code is hacked to allow the animation to use all 256 colors
619 extern int Palman_allow_any_color;
620 Palman_allow_any_color = 1;
621 anim_render_all(0, frametime);
622 Palman_allow_any_color = 0;
625 // if our active item has a bitmap instead of an animation, draw it
626 if((Cur_entry > 0) && (Current_list[Cur_entry].animation == NULL) && (Current_list[Cur_entry].bitmap >= 0)){
627 gr_set_bitmap(Current_list[Cur_entry].bitmap);
628 gr_bitmap(Tech_ani_coords[gr_screen.res][0], Tech_ani_coords[gr_screen.res][1]);
632 // renders the stuff common to all 3 tech room tabs
633 void tech_common_render()
636 int y, z, font_height;
638 // render description in its box
639 gr_set_color_fast(&Color_text_normal);
640 techroom_render_desc(Tech_desc_coords[gr_screen.res][SHIP_X_COORD], Tech_desc_coords[gr_screen.res][SHIP_Y_COORD], Tech_desc_coords[gr_screen.res][SHIP_H_COORD]);
642 font_height = gr_get_font_height();
644 // draw the list of entries
647 while (y + font_height <= Tech_list_coords[gr_screen.res][SHIP_H_COORD]) {
648 if (z >= Current_list_size) {
652 if (z == Cur_entry) {
653 gr_set_color_fast(&Color_text_selected);
654 } else if (z == Select_tease_line) {
655 gr_set_color_fast(&Color_text_subselected);
657 gr_set_color_fast(&Color_text_normal);
660 strcpy(buf, Current_list[z].name);
662 lcl_translate_ship_name(buf);
665 gr_force_fit_string(buf, 255, Tech_list_coords[gr_screen.res][SHIP_W_COORD]);
666 gr_string(Tech_list_coords[gr_screen.res][SHIP_X_COORD], Tech_list_coords[gr_screen.res][SHIP_Y_COORD] + y, buf);
668 List_buttons[z - List_offset].update_dimensions(Tech_list_coords[gr_screen.res][SHIP_X_COORD], Tech_list_coords[gr_screen.res][SHIP_Y_COORD] + y, Tech_list_coords[gr_screen.res][SHIP_W_COORD], font_height);
669 List_buttons[z - List_offset].enable(1);
675 // disable the rest of the list buttons
677 while (z < LIST_BUTTONS_MAX) {
678 List_buttons[z++].disable();
682 void techroom_ships_render(float frametime)
684 // render all the common stuff
685 tech_common_render();
687 // now render the trackball ship, which is unique to the ships tab
689 angles rot_angles, view_angles;
691 ship_info *sip = &Ship_info[Cur_entry_index];
693 // get correct revolution rate
694 rev_rate = REVOLUTION_RATE;
696 if (z & SIF_BIG_SHIP) {
699 if (z & SIF_HUGE_SHIP) {
703 // rotate the ship as much as required for this frame
704 Techroom_ship_rot += PI2 * frametime / rev_rate;
705 while (Techroom_ship_rot > PI2){
706 Techroom_ship_rot -= PI2;
710 gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
713 if (Trackball_active) {
717 if (Trackball_active) {
718 mouse_get_delta(&dx, &dy);
720 vm_trackball(-dx, -dy, &mat1);
721 vm_matrix_x_matrix(&mat2, &mat1, &Techroom_ship_orient);
722 Techroom_ship_orient = mat2;
727 // setup stuff needed to render the ship
728 view_angles.p = -0.6f;
729 view_angles.b = 0.0f;
730 view_angles.h = 0.0f;
731 vm_angles_2_matrix(&Techroom_ship_orient, &view_angles);
735 rot_angles.h = Techroom_ship_rot;
736 vm_rotate_matrix_by_angles(&Techroom_ship_orient, &rot_angles);
739 gr_set_clip(Tech_ship_display_coords[gr_screen.res][SHIP_X_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_Y_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_W_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_H_COORD]);
742 #ifdef MULTIPLAYER_BETA_BUILD
743 if((sip->flags & SIF_SUPERCAP) || (sip->flags & SIF_DRYDOCK)) {
744 gr_set_color_fast(&Color_bright);
745 gr_string(Tech_ship_display_coords[gr_screen.res][SHIP_X_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_Y_COORD] + 50, NOX("No soup for you!"));
749 g3_set_view_matrix(&sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom * 1.3f);
751 // lighting for techroom
753 vector light_dir = vmd_zero_vector;
755 light_add_directional(&light_dir, 0.85f, 1.0f, 1.0f, 1.0f);
756 // light_filter_reset();
758 // lighting for techroom
760 model_clear_instance(Techroom_ship_modelnum);
761 model_set_detail_level(0);
762 model_render(Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector, MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER);
769 g3_set_view_matrix(&sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom * 1.3f);
771 // lighting for techroom
773 vector light_dir = vmd_zero_vector;
775 light_add_directional(&light_dir, 0.85f, 1.0f, 1.0f, 1.0f);
776 // light_filter_reset();
778 // lighting for techroom
780 model_clear_instance(Techroom_ship_modelnum);
781 model_set_detail_level(0);
782 model_render(Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector, MR_LOCK_DETAIL | MR_AUTOCENTER);
790 // select previous entry in current list
791 void tech_prev_entry()
795 Cur_entry = Current_list_size - 1;
797 // scroll to end of list
798 List_offset = Cur_entry - Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() + 1;
799 if (List_offset < 0) {
800 // this happens when there are not enough items to scroll
803 Tech_slider.force_currentItem(Tech_slider.get_numberItems());
805 // maybe adjust list position by 1
806 if (List_offset > Cur_entry) {
807 tech_scroll_list_up();
808 Tech_slider.forceUp();
812 techroom_select_new_entry();
813 gamesnd_play_iface(SND_SCROLL);
816 // select next entry in current list
817 void tech_next_entry()
820 if (Cur_entry >= Current_list_size) {
823 // scroll to beginning of list
825 Tech_slider.force_currentItem(Cur_entry);
827 // maybe adjust list position by 1
828 if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() <= Cur_entry) {
829 tech_scroll_list_down();
830 Tech_slider.forceDown();
834 techroom_select_new_entry();
835 gamesnd_play_iface(SND_SCROLL);
838 void tech_scroll_info_up()
842 gamesnd_play_iface(SND_SCROLL);
844 gamesnd_play_iface(SND_GENERAL_FAIL);
848 void tech_scroll_info_down()
852 if (Tab == SHIPS_DATA_TAB){
853 h = Tech_desc_coords[gr_screen.res][SHIP_H_COORD];
855 h = Tech_desc_coords[gr_screen.res][3];
858 if (Text_offset + h / gr_get_font_height() < Text_size) {
860 gamesnd_play_iface(SND_SCROLL);
862 gamesnd_play_iface(SND_GENERAL_FAIL);
866 void tech_scroll_list_up()
870 if (List_offset > 0) {
872 //last = List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() - 1;
873 gamesnd_play_iface(SND_SCROLL);
875 gamesnd_play_iface(SND_GENERAL_FAIL);
879 void tech_scroll_list_down()
881 if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < Current_list_size) {
883 gamesnd_play_iface(SND_SCROLL);
885 gamesnd_play_iface(SND_GENERAL_FAIL);
889 // this doesnt do a damn thing...
890 void tech_ship_scroll_capture()
892 techroom_select_new_entry();
896 // this is obsolete - see techroom_weapons_render2(...)
897 void techroom_weapons_render(float frametime)
899 gr_set_color_fast(&Color_text_normal);
900 techroom_render_desc(Tech_desc_coords[gr_screen.res][0], Tech_desc_coords[gr_screen.res][1], Tech_desc_coords[gr_screen.res][3]);
903 // JAS: This code is hacked to allow the animation to use all 256 colors
904 extern int Palman_allow_any_color;
905 Palman_allow_any_color = 1;
906 anim_render_all(0, frametime);
907 Palman_allow_any_color = 0;
910 // if our active item has a bitmap instead of an animation, draw it
911 if((Cur_entry >= 0) && (Current_list[Cur_entry].animation == NULL) && (Current_list[Cur_entry].bitmap >= 0)){
912 gr_set_bitmap(Current_list[Cur_entry].bitmap);
913 gr_bitmap(Tech_ani_coords[gr_screen.res][0], Tech_ani_coords[gr_screen.res][1]);
917 void techroom_intel_render(float frametime)
919 tech_common_render();
922 // JAS: This code is hacked to allow the animation to use all 256 colors
923 extern int Palman_allow_any_color;
924 Palman_allow_any_color = 1;
925 anim_render_all(0, frametime);
926 Palman_allow_any_color = 0;
929 // if our active item has a bitmap instead of an animation, draw it
930 if((Cur_entry >= 0) && (Current_list[Cur_entry].animation == NULL) && (Current_list[Cur_entry].bitmap >= 0)){
931 gr_set_bitmap(Current_list[Cur_entry].bitmap);
932 gr_bitmap(Tech_ani_coords[gr_screen.res][0], Tech_ani_coords[gr_screen.res][1]);
936 void techroom_stop_anim(int id)
938 if (Cur_anim_instance && (id != Anim_playing_id)) {
939 anim_stop_playing(Cur_anim_instance);
940 Cur_anim_instance = NULL;
944 void techroom_start_anim()
948 anim_play_struct aps;
951 techroom_stop_anim(-1);
952 Anim_playing_id = -1;
955 if (Tab == WEAPONS_DATA_TAB) {
958 id = Cur_entry + 2000; // this offset is arbitrary?
961 techroom_stop_anim(id);
963 // if we actually have an animation
964 if(Current_list[Cur_entry].animation != NULL){
965 animp = Current_list[Cur_entry].animation;
967 if (id != Anim_playing_id) {
968 Anim_playing_id = -1;
970 anim_play_init(&aps, animp, Tech_ani_coords[gr_screen.res][0], Tech_ani_coords[gr_screen.res][1]);
972 Cur_anim_instance = anim_play(&aps);
973 Anim_playing_id = id;
977 memcpy(Palette, animp->palette, 384);
978 gr_set_palette(animp->name, Palette, 1);
985 void techroom_change_tab(int num)
987 int i, multi = 0, mask, font_height, max_num_entries_viewable;
990 // Assert(Current_list_size >= 0);
993 multi = Player->flags & PLAYER_FLAGS_IS_MULTI;
995 for (i=0; i<LIST_BUTTONS_MAX; i++){
996 List_buttons[i].disable();
999 // disable some stuff in multiplayer
1000 if (Player->flags & PLAYER_FLAGS_IS_MULTI) {
1001 Buttons[gr_screen.res][SIMULATOR_TAB].button.disable();
1002 Buttons[gr_screen.res][CUTSCENES_TAB].button.disable();
1006 case SHIPS_DATA_TAB:
1007 mask = multi ? SIF_IN_TECH_DATABASE_M : SIF_IN_TECH_DATABASE;
1009 // load ship info if necessary
1010 if (Ships_loaded == 0) {
1012 for (i=0; i<Num_ship_types; i++) {
1013 if (Ship_info[i].flags & mask) {
1014 // this ship should be displayed, fill out the entry struct
1015 Ship_list[Ship_list_size].bitmap = -1;
1016 Ship_list[Ship_list_size].index = i;
1017 Ship_list[Ship_list_size].animation = NULL; // no anim for ships
1018 Ship_list[Ship_list_size].has_anim = 0; // no anim for ships
1019 Ship_list[Ship_list_size].name = Ship_info[i].name;
1020 Ship_list[Ship_list_size].desc = Ship_info[i].tech_desc;
1027 Current_list = Ship_list;
1028 Current_list_size = Ship_list_size;
1030 font_height = gr_get_font_height();
1031 max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
1032 Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
1034 // no anim to start here
1037 case WEAPONS_DATA_TAB:
1039 // load weapon info & anims if necessary
1040 if (Weapons_loaded == 0) {
1041 Weapon_list_size = 0;
1042 mask = multi ? WIF_PLAYER_ALLOWED : WIF_IN_TECH_DATABASE;
1044 for (i=0; i<MAX_WEAPON_TYPES; i++) {
1045 if (Weapon_info[i].wi_flags & mask) {
1046 // note: hack here to exclude dogfight weapons -- dont put weapon in if it has same description as pvs weapon
1047 if ((Weapon_list_size > 0) && (!strcmp(Weapon_info[i].tech_desc, Weapon_list[Weapon_list_size-1].desc))) {
1051 // we have a weapon that should be in the tech db, so fill out the entry struct
1052 Weapon_list[Weapon_list_size].index = i;
1053 Weapon_list[Weapon_list_size].desc = Weapon_info[i].tech_desc;
1054 Weapon_list[Weapon_list_size].has_anim = 1;
1055 Weapon_list[Weapon_list_size].name = Weapon_info[i].tech_title;
1056 Weapon_list[Weapon_list_size].bitmap = -1;
1057 if (Weapon_list[Weapon_list_size].name[0] == 0) {
1058 Weapon_list[Weapon_list_size].name = Weapon_info[i].name;
1061 // load the weapon animation
1062 if(!techroom_load_ani(&Weapon_list[Weapon_list_size].animation, Weapon_info[i].tech_anim_filename)){
1063 Weapon_list[Weapon_list_size].has_anim = 0;
1064 Weapon_list[Weapon_list_size].animation = NULL;
1066 // hmm. try a bitmap instead
1067 Weapon_list[Weapon_list_size].bitmap = bm_load(Weapon_info[i].tech_anim_filename);
1077 Current_list = Weapon_list;
1078 Current_list_size = Weapon_list_size;
1080 font_height = gr_get_font_height();
1081 max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
1082 Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
1084 techroom_start_anim();
1087 case INTEL_DATA_TAB:
1089 // load intel if necessary
1090 if ( Intel_loaded == 0 ) {
1091 // now populate the entry structs
1092 Intel_list_size = 0;
1093 for (i=0; i<Intel_info_size; i++) {
1095 if (Intel_info[i].in_tech_db != 0) {
1096 // leave option for no animation if string == "none"
1097 if (!strcmp(Intel_info[i].anim_filename, "none")) {
1098 Intel_list[Intel_list_size].has_anim = 0;
1099 Intel_list[Intel_list_size].animation = NULL;
1101 // try and load as an animation
1102 Intel_list[Intel_list_size].has_anim = 0;
1103 Intel_list[Intel_list_size].bitmap = -1;
1104 if(techroom_load_ani(&Intel_list[Intel_list_size].animation, Intel_info[i].anim_filename)){
1105 Intel_list[Intel_list_size].has_anim = 1;
1107 Intel_list[Intel_list_size].bitmap = bm_load(Intel_info[i].anim_filename);
1111 Intel_list[Intel_list_size].desc = Intel_info[i].desc;
1112 Intel_list[Intel_list_size].index = i;
1113 Intel_list[Intel_list_size].name = Intel_info[i].name;
1120 // index lookup on intel is a pretty pointless, but it keeps everything
1121 // consistent and doesnt really hurt anything
1122 Current_list = Intel_list;
1123 Current_list_size = Intel_list_size;
1125 font_height = gr_get_font_height();
1126 max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
1127 Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
1129 techroom_start_anim();
1135 techroom_select_new_entry();
1139 int techroom_button_pressed(int num)
1142 case SHIPS_DATA_TAB:
1143 case WEAPONS_DATA_TAB:
1144 case INTEL_DATA_TAB:
1145 techroom_change_tab(num);
1149 #if !defined(E3_BUILD) && !defined(PD_BUILD)
1150 gamesnd_play_iface(SND_SWITCH_SCREENS);
1151 gameseq_post_event(GS_EVENT_SIMULATOR_ROOM);
1158 #if !defined(E3_BUILD) && !defined(PD_BUILD)
1159 gamesnd_play_iface(SND_SWITCH_SCREENS);
1160 gameseq_post_event(GS_EVENT_GOTO_VIEW_CUTSCENES_SCREEN);
1167 #if !defined(E3_BUILD) && !defined(PD_BUILD)
1168 gamesnd_play_iface(SND_SWITCH_SCREENS);
1169 gameseq_post_event(GS_EVENT_CREDITS);
1175 case PREV_ENTRY_BUTTON:
1179 case NEXT_ENTRY_BUTTON:
1183 case SCROLL_LIST_UP:
1184 tech_scroll_list_up();
1185 Tech_slider.forceUp();
1188 case SCROLL_LIST_DOWN:
1189 tech_scroll_list_down();
1190 Tech_slider.forceDown();
1193 case SCROLL_INFO_UP:
1194 tech_scroll_info_up();
1197 case SCROLL_INFO_DOWN:
1198 tech_scroll_info_down();
1202 launch_context_help();
1203 gamesnd_play_iface(SND_HELP_PRESSED);
1206 case OPTIONS_BUTTON:
1207 gamesnd_play_iface(SND_SWITCH_SCREENS);
1208 gameseq_post_event(GS_EVENT_OPTIONS_MENU);
1212 gamesnd_play_iface(SND_COMMIT_PRESSED);
1213 gameseq_post_event(GS_EVENT_MAIN_MENU);
1220 int techroom_load_ani(anim **animpp, char *name)
1222 int load_attempts = 0;
1223 char anim_filename[64] = "2_";
1226 // (i dont think there are any hi-res anims for these tho)
1227 if (gr_screen.res == GR_1024) {
1228 strcat(anim_filename, name);
1230 strcpy(anim_filename, name);
1234 if ( load_attempts++ > 5 ) {
1235 // Tech_room_ask_for_cd = 0;
1239 *animpp = anim_load(anim_filename, 1);
1242 } else if (gr_screen.res == GR_1024) {
1243 // try to load low-res version if hi-res failed
1244 *animpp = anim_load(name, 1);
1250 // couldn't load animation, ask user to insert CD (if necessary)
1251 // if ( Tech_room_ask_for_cd ) {
1252 // if ( game_do_cd_check() == 0 ) {
1253 // Tech_room_ask_for_cd = 0;
1264 void techroom_intel_init()
1267 static int inited = 0;
1269 // open localization
1273 if ((rval = setjmp(parse_abort)) != 0) {
1274 // close localization
1279 read_file_text("species.tbl");
1282 Intel_info_size = 0;
1284 while (optional_string("$Entry:")) {
1285 Assert(Intel_info_size < MAX_INTEL_ENTRIES);
1286 if (Intel_info_size >= MAX_INTEL_ENTRIES) break;
1288 required_string("$Name:");
1289 stuff_string(Intel_info[Intel_info_size].name, F_NAME, NULL, 32);
1290 required_string("$Anim:");
1291 stuff_string(Intel_info[Intel_info_size].anim_filename, F_NAME, NULL, 32);
1292 required_string("$AlwaysInTechRoom:");
1293 stuff_int(&Intel_info[Intel_info_size].in_tech_db);
1294 required_string("$Description:");
1295 stuff_string(Intel_info[Intel_info_size].desc, F_MULTITEXT, NULL, TECH_INTEL_DESC_LEN);
1304 // close localization
1308 void techroom_init()
1311 techroom_buttons *b;
1323 // Tech_room_ask_for_cd = 1;
1325 // backup and bash detail level stuff
1326 Tech_detail_backup = Detail.detail_distance;
1327 Detail.detail_distance = MAX_DETAIL_LEVEL;
1328 Tech_texture_backup = Detail.hardware_textures;
1329 Detail.hardware_textures = MAX_DETAIL_LEVEL;
1332 Palette_bmp = bm_load("TechDataPalette");
1333 Assert(Palette_bmp);
1334 bm_get_palette(Palette_bmp, Palette, Palette_name); // get the palette for this bitmap
1335 gr_set_palette(Palette_name, Palette, 1);
1339 The_mission.flags &= ~MISSION_FLAG_FULLNEB;
1342 Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
1343 Ui_window.set_mask_bmap(Tech_mask_filename[gr_screen.res]);
1345 Tech_background_bitmap = bm_load(Tech_background_filename[gr_screen.res]);
1346 if (Tech_background_bitmap < 0) {
1347 // failed to load bitmap, not a good thing
1351 for (i=0; i<NUM_BUTTONS; i++) {
1352 b = &Buttons[gr_screen.res][i];
1354 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, b->flags & REPEAT, 1);
1355 // set up callback for when a mouse first goes over a button
1357 b->button.set_bmaps(b->filename);
1358 // if ( !(b->flags & NO_MOUSE_OVER_SOUND) ) {
1359 b->button.set_highlight_action(common_play_highlight_sound);
1366 b->button.link_hotspot(b->hotspot);
1369 // common tab button text
1370 Ui_window.add_XSTR("Technical Database", 1055, Buttons[gr_screen.res][TECH_DATABASE_TAB].xt, Buttons[gr_screen.res][TECH_DATABASE_TAB].yt, &Buttons[gr_screen.res][TECH_DATABASE_TAB].button, UI_XSTR_COLOR_GREEN);
1371 Ui_window.add_XSTR("Mission Simulator", 1056, Buttons[gr_screen.res][SIMULATOR_TAB].xt, Buttons[gr_screen.res][SIMULATOR_TAB].yt, &Buttons[gr_screen.res][SIMULATOR_TAB].button, UI_XSTR_COLOR_GREEN);
1372 Ui_window.add_XSTR("Cutscenes", 1057, Buttons[gr_screen.res][CUTSCENES_TAB].xt, Buttons[gr_screen.res][CUTSCENES_TAB].yt, &Buttons[gr_screen.res][CUTSCENES_TAB].button, UI_XSTR_COLOR_GREEN);
1373 Ui_window.add_XSTR("Credits", 1058, Buttons[gr_screen.res][CREDITS_TAB].xt, Buttons[gr_screen.res][CREDITS_TAB].yt, &Buttons[gr_screen.res][CREDITS_TAB].button, UI_XSTR_COLOR_GREEN);
1375 // common ship/weapon/intel text
1376 Ui_window.add_XSTR("Ships", 293, Buttons[gr_screen.res][SHIPS_DATA_TAB].xt, Buttons[gr_screen.res][SHIPS_DATA_TAB].yt, &Buttons[gr_screen.res][SHIPS_DATA_TAB].button, UI_XSTR_COLOR_GREEN);
1377 Ui_window.add_XSTR("Weapons", 1553, Buttons[gr_screen.res][WEAPONS_DATA_TAB].xt, Buttons[gr_screen.res][WEAPONS_DATA_TAB].yt, &Buttons[gr_screen.res][WEAPONS_DATA_TAB].button, UI_XSTR_COLOR_GREEN);
1378 Ui_window.add_XSTR("Intelligence", 1066, Buttons[gr_screen.res][INTEL_DATA_TAB].xt, Buttons[gr_screen.res][INTEL_DATA_TAB].yt, &Buttons[gr_screen.res][INTEL_DATA_TAB].button, UI_XSTR_COLOR_GREEN);
1380 // common help/options/commit text
1382 // NK: removed these two text labels on Tech screen update 4/26/99
1383 // 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);
1384 // 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);
1385 Ui_window.add_XSTR("Exit", 1418, Buttons[gr_screen.res][EXIT_BUTTON].xt, Buttons[gr_screen.res][EXIT_BUTTON].yt, &Buttons[gr_screen.res][EXIT_BUTTON].button, UI_XSTR_COLOR_PINK);
1387 if (Player->flags & PLAYER_FLAGS_IS_MULTI) {
1388 Buttons[gr_screen.res][SIMULATOR_TAB].button.disable();
1389 Buttons[gr_screen.res][CUTSCENES_TAB].button.disable();
1393 Buttons[gr_screen.res][PREV_ENTRY_BUTTON].button.set_hotkey(KEY_LEFT);
1394 Buttons[gr_screen.res][NEXT_ENTRY_BUTTON].button.set_hotkey(KEY_RIGHT);
1395 Buttons[gr_screen.res][SCROLL_INFO_UP].button.set_hotkey(KEY_UP);
1396 Buttons[gr_screen.res][SCROLL_INFO_DOWN].button.set_hotkey(KEY_DOWN);
1399 for (i=0; i<LIST_BUTTONS_MAX; i++) {
1400 List_buttons[i].create(&Ui_window, "", 0, 0, 60, 30, 0, 1);
1401 List_buttons[i].hide();
1402 List_buttons[i].disable();
1405 View_window.create(&Ui_window, "", Tech_ship_display_coords[gr_screen.res][SHIP_X_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_Y_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_W_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_H_COORD], 1, 1);
1409 ShipWin01 = bm_load(NOX("ShipWin01"));
1410 ShipWin02 = bm_load(NOX("ShipWin02"));
1411 ShipWin03 = bm_load(NOX("ShipWin03"));
1412 ShipWin04 = bm_load(NOX("ShipWin04"));
1415 Buttons[gr_screen.res][HELP_BUTTON].button.set_hotkey(KEY_F1);
1416 Buttons[gr_screen.res][EXIT_BUTTON].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
1417 Buttons[gr_screen.res][SCROLL_LIST_UP].button.set_hotkey(KEY_PAGEUP);
1418 Buttons[gr_screen.res][SCROLL_LIST_DOWN].button.set_hotkey(KEY_PAGEDOWN);
1420 // init help overlay states
1421 help_overlay_set_state(TECH_ROOM_OVERLAY, 0);
1424 Tech_slider.create(&Ui_window, Tech_slider_coords[gr_screen.res][SHIP_X_COORD], Tech_slider_coords[gr_screen.res][SHIP_Y_COORD], Tech_slider_coords[gr_screen.res][SHIP_W_COORD], Tech_slider_coords[gr_screen.res][SHIP_H_COORD], Num_ship_types, Tech_slider_filename[gr_screen.res], &tech_scroll_list_up, &tech_scroll_list_down, &tech_ship_scroll_capture);
1426 Cur_anim_instance = NULL;
1428 // zero weapon and intel anim/bitmap stuff
1429 for(idx=0; idx<MAX_WEAPON_TYPES; idx++){
1430 Weapon_list[idx].animation = NULL;
1431 Weapon_list[idx].bitmap = -1;
1433 for(idx=0; idx<MAX_INTEL_ENTRIES; idx++){
1434 Intel_list[idx].animation = NULL;
1435 Intel_list[idx].bitmap = -1;
1438 Anim_playing_id = -1;
1439 techroom_change_tab(Tab);
1442 void techroom_close()
1446 techroom_stop_anim(-1);
1447 for (i=0; i<MAX_WEAPON_TYPES; i++) {
1448 if ( Weapon_list[i].animation ) {
1449 anim_free(Weapon_list[i].animation);
1450 Weapon_list[i].animation = NULL;
1452 if( Weapon_list[i].bitmap >= 0 ){
1453 bm_unload(Weapon_list[i].bitmap);
1454 Weapon_list[i].bitmap = -1;
1458 for (i=0; i<MAX_INTEL_ENTRIES; i++){
1459 if (Intel_list[i].animation != NULL) {
1460 anim_free(Intel_list[i].animation);
1461 Intel_list[i].animation = NULL;
1463 if( Intel_list[i].bitmap >= 0 ){
1464 bm_unload(Intel_list[i].bitmap);
1465 Intel_list[i].bitmap = -1;
1475 bm_unload(ShipWin01);
1478 bm_unload(ShipWin02);
1481 bm_unload(ShipWin03);
1484 bm_unload(ShipWin04);
1488 if (Tech_background_bitmap) {
1489 bm_unload(Tech_background_bitmap);
1492 Ui_window.destroy();
1493 common_free_interface_palette(); // restore game palette
1495 bm_unload(Palette_bmp);
1498 // restore detail settings
1499 Detail.detail_distance = Tech_detail_backup;
1500 Detail.hardware_textures = Tech_texture_backup;
1503 void techroom_do_frame(float frametime)
1507 // turn off controls when overlay is on
1508 if ( help_overlay_active(TECH_ROOM_OVERLAY) ) {
1509 Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
1510 Ui_window.set_ignore_gadgets(1);
1513 // turn off controls in trackball mode
1514 if (Trackball_active) {
1515 Ui_window.set_ignore_gadgets(1);
1517 Ui_window.set_ignore_gadgets(0);
1520 k = Ui_window.process() & ~KEY_DEBUGGED;
1522 if ( (k > 0) || B1_JUST_RELEASED ) {
1523 if ( help_overlay_active(TECH_ROOM_OVERLAY) ) {
1524 help_overlay_set_state(TECH_ROOM_OVERLAY, 0);
1525 Ui_window.set_ignore_gadgets(0);
1530 if ( !help_overlay_active(TECH_ROOM_OVERLAY) ) {
1531 Ui_window.set_ignore_gadgets(0);
1535 case KEY_SHIFTED | KEY_TAB: // activate previous tab
1541 techroom_change_tab(i);
1544 case KEY_TAB: // activate next tab
1546 if (i >= NUM_TABS) {
1550 techroom_change_tab(i);
1553 case KEY_CTRLED | KEY_DOWN:
1554 if ( !(Player->flags & PLAYER_FLAGS_IS_MULTI) ) {
1555 techroom_button_pressed(SIMULATOR_TAB);
1560 case KEY_CTRLED | KEY_UP:
1561 techroom_button_pressed(CREDITS_TAB);
1572 case KEY_CTRLED | KEY_ENTER:
1574 gameseq_post_event(GS_EVENT_MAIN_MENU);
1578 // check ship model window for activity
1579 if (View_window.pressed()) {
1580 Trackball_active = 1;
1584 Trackball_active = 0;
1587 // check all da buttons
1588 for (i=0; i<NUM_BUTTONS; i++) {
1589 if (Buttons[gr_screen.res][i].button.pressed()) {
1590 if (techroom_button_pressed(i)) {
1596 // check for mouseovers/clicks on the selection list
1597 Select_tease_line = -1;
1598 for (i=0; i<LIST_BUTTONS_MAX; i++) {
1599 if (List_buttons[i].is_mouse_on()) {
1600 Select_tease_line = i + List_offset;
1603 if (List_buttons[i].pressed()) {
1604 Cur_entry = i + List_offset;
1605 gamesnd_play_iface(SND_USER_SELECT);
1606 techroom_select_new_entry();
1610 // clear & draw bg bitmap
1611 GR_MAYBE_CLEAR_RES(Tech_background_bitmap);
1612 if (Tech_background_bitmap >= 0) {
1613 gr_set_bitmap(Tech_background_bitmap);
1619 case SHIPS_DATA_TAB:
1620 techroom_ships_render(frametime);
1624 gr_set_bitmap(ShipWin01);
1625 gr_bitmap(223, 104);
1629 gr_set_bitmap(ShipWin02);
1630 gr_bitmap(621, 124);
1634 gr_set_bitmap(ShipWin03);
1635 gr_bitmap(223, 338);
1639 gr_set_bitmap(ShipWin04);
1640 gr_bitmap(218, 124);
1646 case WEAPONS_DATA_TAB:
1647 techroom_weapons_render2(frametime);
1650 case INTEL_DATA_TAB:
1651 techroom_intel_render(frametime);
1657 for (i=TECH_DATABASE_TAB; i<=CREDITS_TAB; i++) {
1658 if (Buttons[gr_screen.res][i].button.button_down()) {
1662 if (i > CREDITS_TAB) {
1663 Buttons[gr_screen.res][TECH_DATABASE_TAB].button.draw_forced(2);
1666 for (i=0; i<NUM_TABS; i++){
1667 if (Buttons[gr_screen.res][i].button.button_down()){
1672 Buttons[gr_screen.res][Tab].button.draw_forced(2);
1675 // blit help overlay if active
1676 help_overlay_maybe_blit(TECH_ROOM_OVERLAY);