2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Stuff for rendering the HUD
39 extern fix Cruise_speed;
40 extern int LinearSVGABuffer;
41 extern cvar_t r_framerate;
45 extern int Debug_pause; // John's debugging pause system
49 extern int Saving_movie_frames;
51 #define Saving_movie_frames 0
54 // Returns the length of the first 'n' characters of a string.
55 int string_width( char * s, int n )
61 gr_get_string_size( s, &w, &h, &aw );
66 // Draw string 's' centered on a canvas... if wider than
67 // canvas, then wrap it.
68 void draw_centered_text( int y, char * s )
75 if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w ) {
76 gr_string( 0x8000, y, s );
80 for (i=0; i<l; i++ ) {
81 if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) ) {
84 gr_string( 0x8000, y, s );
86 gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
92 extern ubyte DefiningMarkerMessage;
93 extern char Marker_input[];
95 #define MAX_MARKER_MESSAGE_LEN 120
96 void game_draw_marker_message()
98 char temp_string[MAX_MARKER_MESSAGE_LEN+25];
100 if ( DefiningMarkerMessage)
102 gr_set_curfont( GAME_FONT ); //GAME_FONT
103 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
104 sprintf( temp_string, "Marker: %s_", Marker_input );
105 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
111 void game_draw_multi_message()
113 char temp_string[MAX_MULTI_MESSAGE_LEN+25];
115 if ( (Game_mode&GM_MULTI) && (multi_sending_message)) {
116 gr_set_curfont( GAME_FONT ); //GAME_FONT );
117 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
118 sprintf( temp_string, "%s: %s_", TXT_MESSAGE, Network_message );
119 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
123 if ( (Game_mode&GM_MULTI) && (multi_defining_message)) {
124 gr_set_curfont( GAME_FONT ); //GAME_FONT );
125 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
126 sprintf( temp_string, "%s #%d: %s_", TXT_MACRO, multi_defining_message, Network_message );
127 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
132 //these should be in gr.h
133 #define cv_w cv_bitmap.bm_w
134 #define cv_h cv_bitmap.bm_h
136 fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
137 fix frame_time_total=0;
138 int frame_time_cntr=0;
140 void ftoa(char *string, fix f)
142 int decimal, fractional;
145 fractional = ((f & 0xffff)*100)/65536;
148 if (fractional > 99 ) fractional = 99;
149 sprintf( string, "%d.%02d", decimal, fractional );
152 void show_framerate()
158 int x = 8, y = 5; // position measured from lower right corner
160 frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
161 frame_time_list[frame_time_cntr] = RealFrameTime;
162 frame_time_cntr = (frame_time_cntr+1)%8;
164 rate = fixdiv(f1_0*8,frame_time_total);
166 gr_set_curfont( GAME_FONT );
167 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
169 ftoa( temp, rate ); // Convert fixed to string
170 if (Game_mode & GM_MULTI)
172 gr_printf(grd_curcanv->cv_w-(x*GAME_FONT->ft_w),grd_curcanv->cv_h-y*(GAME_FONT->ft_h+GAME_FONT->ft_h/4),"FPS: %s ", temp );
173 // if ( !( q++ % 30 ) )
174 // mprintf( (0,"fps: %s\n", temp ) );
179 fix Show_view_text_timer = -1;
181 void draw_window_label()
183 if ( Show_view_text_timer > 0 )
185 char *viewer_name,*control_name;
187 Show_view_text_timer -= FrameTime;
188 gr_set_curfont( GAME_FONT );
191 switch( Viewer->type )
193 case OBJ_FIREBALL: viewer_name = "Fireball"; break;
194 case OBJ_ROBOT: viewer_name = "Robot";
196 viewer_id = Robot_names[Viewer->id];
199 case OBJ_HOSTAGE: viewer_name = "Hostage"; break;
200 case OBJ_PLAYER: viewer_name = "Player"; break;
201 case OBJ_WEAPON: viewer_name = "Weapon"; break;
202 case OBJ_CAMERA: viewer_name = "Camera"; break;
203 case OBJ_POWERUP: viewer_name = "Powerup";
205 viewer_id = Powerup_names[Viewer->id];
208 case OBJ_DEBRIS: viewer_name = "Debris"; break;
209 case OBJ_CNTRLCEN: viewer_name = "Reactor"; break;
210 default: viewer_name = "Unknown"; break;
213 switch ( Viewer->control_type) {
214 case CT_NONE: control_name = "Stopped"; break;
215 case CT_AI: control_name = "AI"; break;
216 case CT_FLYING: control_name = "Flying"; break;
217 case CT_SLEW: control_name = "Slew"; break;
218 case CT_FLYTHROUGH: control_name = "Flythrough"; break;
219 case CT_MORPH: control_name = "Morphing"; break;
220 default: control_name = "Unknown"; break;
223 gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
224 gr_printf( 0x8000, 45, "%i: %s [%s] View - %s", OBJECT_NUMBER(Viewer), viewer_name, viewer_id, control_name );
230 extern int Game_window_x;
231 extern int Game_window_y;
232 extern int max_window_w;
233 extern int max_window_h;
235 void render_countdown_gauge()
237 if (!Endlevel_sequence && Control_center_destroyed && (Countdown_seconds_left>-1)) { // && (Countdown_seconds_left<127)) {
240 if (!is_D2_OEM && !is_MAC_SHARE && !is_SHAREWARE) // no countdown on registered only
242 // On last level, we don't want a countdown.
243 if (PLAYING_BUILTIN_MISSION && Current_level_num == Last_level)
245 if (!(Game_mode & GM_MULTI))
247 if (Game_mode & GM_MULTI_ROBOTS)
252 gr_set_curfont( SMALL_FONT );
253 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
254 y = SMALL_FONT->ft_h*4;
255 if (Cockpit_mode.intval == CM_FULL_SCREEN)
256 y += SMALL_FONT->ft_h*2;
259 y += SMALL_FONT->ft_h*2;
261 //if (!((Cockpit_mode.intval == CM_STATUS_BAR) && (Game_window_y >= 19)))
263 gr_printf(0x8000, y, "T-%d s", Countdown_seconds_left );
267 void game_draw_hud_stuff()
269 //mprintf ((0,"Linear is %d!\n",LinearSVGABuffer));
273 gr_set_curfont( MEDIUM1_FONT );
274 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
275 gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
284 game_draw_multi_message();
287 game_draw_marker_message();
289 // if (Game_mode & GM_MULTI)
291 // if (Netgame.PlayTimeAllowed)
292 // game_draw_time_left ();
295 if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
299 if (Newdemo_state == ND_STATE_PLAYBACK) {
300 if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
301 sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
303 sprintf (message, " ");
306 sprintf (message, "%s", TXT_DEMO_RECORDING);
308 gr_set_curfont( GAME_FONT ); //GAME_FONT );
309 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
311 gr_get_string_size(message, &w, &h, &aw );
312 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
313 if (grd_curcanv->cv_bitmap.bm_h > 240)
317 } else if ( Cockpit_mode.intval == CM_LETTERBOX )
319 if (Cockpit_mode.intval != CM_REAR_VIEW && !Saving_movie_frames)
320 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
323 render_countdown_gauge();
325 if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num ) {
327 int y = grd_curcanv->cv_bitmap.bm_h;
329 gr_set_curfont( GAME_FONT );
330 gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
331 if (Cruise_speed > 0) {
332 int line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
334 mprintf((0,"line_spacing=%d ",line_spacing));
336 if (Cockpit_mode.intval == CM_FULL_SCREEN) {
337 if (Game_mode & GM_MULTI)
338 y -= line_spacing * 11; //64
340 y -= line_spacing * 6; //32
341 } else if (Cockpit_mode.intval == CM_STATUS_BAR) {
342 if (Game_mode & GM_MULTI)
343 y -= line_spacing * 8; //48
345 y -= line_spacing * 4; //24
347 y = line_spacing * 2; //12
351 gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
355 if (r_framerate.intval)
358 if ( Newdemo_state == ND_STATE_PLAYBACK )
359 Game_mode = Newdemo_game_mode;
363 if ( Newdemo_state == ND_STATE_PLAYBACK )
364 Game_mode = GM_NORMAL;
366 if ( Player_is_dead )
367 player_dead_message();
370 extern int gr_bitblt_dest_step_shift;
371 extern int gr_wait_for_retrace;
372 extern int gr_bitblt_double;
375 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels );
376 #pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \
394 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels )
398 for (i = 0; i < num_src_pixels; i++) {
405 // doubles the size in x or y of a bitmap in place.
406 void game_expand_bitmap( grs_bitmap * bmp, uint flags )
409 ubyte * dptr, * sptr;
413 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
414 dptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
415 for (i=bmp->bm_h-1; i>=0; i-- ) {
416 expand_row( dptr, dptr, bmp->bm_w );
417 dptr -= bmp->bm_rowsize;
422 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
423 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
424 for (i=bmp->bm_h-1; i>=0; i-- ) {
425 memcpy( dptr, sptr, bmp->bm_w );
426 dptr -= bmp->bm_rowsize;
427 memcpy( dptr, sptr, bmp->bm_w );
428 dptr -= bmp->bm_rowsize;
429 sptr -= bmp->bm_rowsize;
433 case 3: // expand x & y
434 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
435 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
436 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
437 for (i=bmp->bm_h-1; i>=0; i-- ) {
438 expand_row( dptr, sptr, bmp->bm_w );
439 dptr -= bmp->bm_rowsize;
440 expand_row( dptr, sptr, bmp->bm_w );
441 dptr -= bmp->bm_rowsize;
442 sptr -= bmp->bm_rowsize;
450 extern int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
454 //render a frame for the game in stereo
455 void game_render_frame_stereo()
459 fix actual_eye_width;
460 int actual_eye_offset;
461 grs_canvas RenderCanvas[2];
464 save_aspect = grd_curscreen->sc_aspect;
465 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
467 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
468 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
470 if (VR_low_res & 1) {
472 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
474 if (VR_low_res & 2) {
476 grd_curscreen->sc_aspect /= 2; //Muck with aspect ratio
479 gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
480 gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
482 // Draw the left eye's view
484 actual_eye_width = -VR_eye_width;
485 actual_eye_offset = -VR_eye_offset;
487 actual_eye_width = VR_eye_width;
488 actual_eye_offset = VR_eye_offset;
491 if (Guided_missile[Player_num] &&
492 Guided_missile[Player_num]->type == OBJ_WEAPON &&
493 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
494 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
495 Guided_in_big_window.intval)
496 actual_eye_offset = 0;
498 gr_set_current_canvas(&RenderCanvas[0]);
500 if (Guided_missile[Player_num] &&
501 Guided_missile[Player_num]->type == OBJ_WEAPON &&
502 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
503 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
504 Guided_in_big_window.intval)
506 char *msg = "Guided Missile View";
507 object *viewer_save = Viewer;
510 Viewer = Guided_missile[Player_num];
513 update_rendered_data(0, Viewer, 0, 0);
516 wake_up_rendered_objects(Viewer, 0);
517 Viewer = viewer_save;
519 gr_set_curfont( GAME_FONT ); //GAME_FONT );
520 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
521 gr_get_string_size(msg, &w, &h, &aw );
523 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
525 draw_guided_crosshair();
528 HUD_render_message_frame();
533 render_frame(actual_eye_width, 0); // switch eye positions for rear view
535 render_frame(-actual_eye_width, 0); // Left eye
538 game_expand_bitmap( &RenderCanvas[0].cv_bitmap, VR_low_res );
540 { //render small window into left eye's canvas
541 grs_canvas *save=grd_curcanv;
542 fix save_aspect2 = grd_curscreen->sc_aspect;
543 grd_curscreen->sc_aspect = save_aspect*2;
544 SW_drawn[0] = SW_drawn[1] = 0;
546 gr_set_current_canvas(save);
547 grd_curscreen->sc_aspect = save_aspect2;
551 if (actual_eye_offset > 0 ) {
552 gr_setcolor( gr_getcolor(0,0,0) );
553 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
554 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
555 } else if (actual_eye_offset < 0 ) {
556 gr_setcolor( gr_getcolor(0,0,0) );
557 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
560 if ( VR_show_hud && !no_draw_hud ) {
562 if (actual_eye_offset < 0 ) {
563 gr_init_sub_canvas( &tmp, grd_curcanv, labs(actual_eye_offset*2), 0, grd_curcanv->cv_bitmap.bm_w-(labs(actual_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
565 gr_init_sub_canvas( &tmp, grd_curcanv, 0, 0, grd_curcanv->cv_bitmap.bm_w-(labs(actual_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
567 gr_set_current_canvas( &tmp );
568 game_draw_hud_stuff();
572 // Draw the right eye's view
573 gr_set_current_canvas(&RenderCanvas[1]);
575 if (Guided_missile[Player_num] &&
576 Guided_missile[Player_num]->type == OBJ_WEAPON &&
577 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
578 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
579 Guided_in_big_window.intval)
580 gr_bitmap(0,0,&RenderCanvas[0].cv_bitmap);
583 render_frame(-actual_eye_width, 0); // switch eye positions for rear view
585 render_frame(actual_eye_width, 0); // Right eye
588 game_expand_bitmap( &RenderCanvas[1].cv_bitmap, VR_low_res );
592 { //copy small window from left eye
597 gr_init_sub_canvas(&temp,&RenderCanvas[0],SW_x[w],SW_y[w],SW_w[w],SW_h[w]);
598 gr_bitmap(SW_x[w]+actual_eye_offset*2,SW_y[w],&temp.cv_bitmap);
604 if (actual_eye_offset>0) {
605 gr_setcolor( gr_getcolor(0,0,0) );
606 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
607 } else if ( actual_eye_offset < 0 ) {
608 gr_setcolor( gr_getcolor(0,0,0) );
609 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
610 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
613 //NEWVR (Add the next 2 lines)
614 if ( VR_show_hud && !no_draw_hud ) {
616 if (actual_eye_offset > 0 ) {
617 gr_init_sub_canvas( &tmp, grd_curcanv, labs(actual_eye_offset*2), 0, grd_curcanv->cv_bitmap.bm_w-(labs(actual_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
619 gr_init_sub_canvas( &tmp, grd_curcanv, 0, 0, grd_curcanv->cv_bitmap.bm_w-(labs(actual_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
621 gr_set_current_canvas( &tmp );
622 game_draw_hud_stuff();
626 // Draws white and black registration encoding lines
627 // and Accounts for pixel-shift adjustment in upcoming bitblts
628 if (VR_use_reg_code) {
629 int width, height, quarter;
631 width = RenderCanvas[0].cv_bitmap.bm_w;
632 height = RenderCanvas[0].cv_bitmap.bm_h;
635 // black out left-hand side of left page
637 // draw registration code for left eye
639 gr_set_current_canvas( &RenderCanvas[1] );
641 gr_set_current_canvas( &RenderCanvas[0] );
642 gr_setcolor( VR_WHITE_INDEX );
643 gr_scanline( 0, quarter, height-1 );
644 gr_setcolor( VR_BLACK_INDEX );
645 gr_scanline( quarter, width-1, height-1 );
648 gr_set_current_canvas( &RenderCanvas[0] );
650 gr_set_current_canvas( &RenderCanvas[1] );
651 gr_setcolor( VR_WHITE_INDEX );
652 gr_scanline( 0, quarter*3, height-1 );
653 gr_setcolor( VR_BLACK_INDEX );
654 gr_scanline( quarter*3, width-1, height-1 );
657 // Copy left eye, then right eye
658 if ( VR_screen_flags&VRF_USE_PAGING )
659 VR_current_page = !VR_current_page;
662 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
666 if ( VR_eye_offset_changed > 0 ) {
667 VR_eye_offset_changed--;
671 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
672 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
674 // Copy left eye, then right eye
675 gr_bitblt_dest_step_shift = 1; // Skip every other scanline.
677 if (VR_render_mode == VR_INTERLACED ) {
678 if ( actual_eye_offset > 0 ) {
679 int xoff = labs(actual_eye_offset);
680 gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
681 gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
682 } else if ( actual_eye_offset < 0 ) {
683 int xoff = labs(actual_eye_offset);
684 gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
685 gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
687 gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
688 gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
690 } else if (VR_render_mode == VR_AREA_DET) {
692 gr_bm_ubitblt( dw, dh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
693 gr_bm_ubitblt( dw, dh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
698 gr_bitblt_dest_step_shift = 0;
700 //if ( Game_vfx_flag )
701 // vfx_set_page(VR_current_page); // 0 or 1
703 if ( VR_screen_flags&VRF_USE_PAGING ) {
704 gr_wait_for_retrace = 0;
706 // Added by Samir from John's code
707 if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) ) {
708 int old_x, old_y, new_x;
709 old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
710 old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
711 new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
713 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
714 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
715 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
716 gr_show_canvas( &VR_screen_pages[VR_current_page] );
717 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
718 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
719 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
721 gr_show_canvas( &VR_screen_pages[VR_current_page] );
723 gr_wait_for_retrace = 1;
725 grd_curscreen->sc_aspect=save_aspect;
728 ubyte RenderingType=0;
729 ubyte DemoDoingRight=0,DemoDoingLeft=0;
730 extern ubyte DemoDoRight,DemoDoLeft;
731 extern object DemoRightExtra,DemoLeftExtra;
733 char DemoWBUType[]={0,WBU_MISSILE,WBU_MISSILE,WBU_REAR,WBU_ESCORT,WBU_MARKER,WBU_MISSILE};
734 char DemoRearCheck[]={0,0,0,1,0,0,0};
735 char *DemoExtraMessage[]={"PLAYER","GUIDED","MISSILE","REAR","GUIDE-BOT","MARKER","SHIP"};
737 extern char guidebot_name[];
739 void show_extra_views()
741 int did_missile_view = 0;
742 int save_newdemo_state = Newdemo_state;
745 if (Newdemo_state == ND_STATE_PLAYBACK) {
747 DemoDoingLeft = DemoDoLeft;
750 do_cockpit_window_view(0, ConsoleObject, 1, WBU_REAR, "REAR");
752 do_cockpit_window_view(0, &DemoLeftExtra, DemoRearCheck[DemoDoLeft], DemoWBUType[DemoDoLeft], DemoExtraMessage[DemoDoLeft]);
754 do_cockpit_window_view(0, NULL, 0, WBU_WEAPON, NULL);
757 DemoDoingRight = DemoDoRight;
759 if (DemoDoRight == 3)
760 do_cockpit_window_view(1, ConsoleObject, 1, WBU_REAR, "REAR");
762 do_cockpit_window_view(1, &DemoRightExtra, DemoRearCheck[DemoDoRight], DemoWBUType[DemoDoRight], DemoExtraMessage[DemoDoRight]);
764 do_cockpit_window_view(1, NULL, 0, WBU_WEAPON, NULL);
766 DemoDoLeft = DemoDoRight = 0;
767 DemoDoingLeft = DemoDoingRight = 0;
772 if (Guided_missile[Player_num] &&
773 Guided_missile[Player_num]->type == OBJ_WEAPON &&
774 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
775 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num])
777 if (Guided_in_big_window.intval) {
778 RenderingType = 6 + (1<<4);
779 do_cockpit_window_view(1, Viewer, 0, WBU_MISSILE, "SHIP");
781 RenderingType = 1 + (1<<4);
782 do_cockpit_window_view(1, Guided_missile[Player_num], 0, WBU_GUIDED, "GUIDED");
785 did_missile_view = 1;
788 if (Guided_missile[Player_num]) { // used to be active
789 if (!Guided_in_big_window.intval)
790 do_cockpit_window_view(1, NULL, 0, WBU_STATIC, NULL);
791 Guided_missile[Player_num] = NULL;
794 if (Missile_viewer) { // do missile view
795 static int mv_sig = -1;
797 mv_sig = Missile_viewer->signature;
798 if (Missile_view_enabled.intval &&
799 Missile_viewer->type != OBJ_NONE &&
800 Missile_viewer->signature == mv_sig)
802 RenderingType = 2 + (1<<4);
803 do_cockpit_window_view(1, Missile_viewer, 0, WBU_MISSILE, "MISSILE");
804 did_missile_view = 1;
806 Missile_viewer = NULL;
809 do_cockpit_window_view(1, NULL, 0, WBU_STATIC, NULL);
814 for (w = 0; w < 2; w++) {
816 if (w == 1 && did_missile_view)
817 continue; // if showing missile view in right window, can't show anything else
819 // show special views if selected
820 switch (Cockpit_3d_view[w].intval) {
823 do_cockpit_window_view(w, NULL, 0, WBU_WEAPON, NULL);
826 if (Rear_view) { // if big window is rear view, show front here
827 RenderingType = 3 + (w<<4);
828 do_cockpit_window_view(w, ConsoleObject, 0, WBU_REAR, "FRONT");
829 } else { // show normal rear view
830 RenderingType = 3 + (w<<4);
831 do_cockpit_window_view(w, ConsoleObject, 1, WBU_REAR, "REAR");
836 buddy = find_escort();
838 do_cockpit_window_view(w, NULL, 0, WBU_WEAPON, NULL);
839 cvar_setint(&Cockpit_3d_view[w], CV_NONE);
841 RenderingType = 4 + (w<<4);
842 do_cockpit_window_view(w, buddy, 0, WBU_ESCORT, guidebot_name);
848 int player = Coop_view_player[w];
850 RenderingType = 255; // don't handle coop stuff
853 Players[player].connected &&
854 ((Game_mode & GM_MULTI_COOP) || ((Game_mode & GM_TEAM) && (get_team(player) == get_team(Player_num)))))
855 do_cockpit_window_view(w, &Objects[Players[Coop_view_player[w]].objnum], 0, WBU_COOP, Players[Coop_view_player[w]].callsign);
857 do_cockpit_window_view(w, NULL, 0, WBU_WEAPON, NULL);
858 cvar_setint(&Cockpit_3d_view[w], CV_NONE);
866 RenderingType = 5 + (w<<4);
867 if (Marker_viewer_num[w] == -1 || MarkerObject[Marker_viewer_num[w]] == -1) {
868 cvar_setint(&Cockpit_3d_view[w], CV_NONE);
871 sprintf(label, "Marker %d", Marker_viewer_num[w] + 1);
872 do_cockpit_window_view(w, &Objects[MarkerObject[Marker_viewer_num[w]]], 0, WBU_MARKER, label);
876 Int3(); // invalid window type
880 Newdemo_state = save_newdemo_state;
883 int BigWindowSwitch = 0;
884 extern int force_cockpit_redraw;
886 void draw_guided_crosshair(void);
887 void update_cockpits(int force_redraw);
890 //render a frame for the game
891 void game_render_frame_mono(void)
893 grs_canvas Screen_3d_window;
897 gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
898 VR_render_sub_buffer[0].cv_bitmap.bm_x,
899 VR_render_sub_buffer[0].cv_bitmap.bm_y,
900 VR_render_sub_buffer[0].cv_bitmap.bm_w,
901 VR_render_sub_buffer[0].cv_bitmap.bm_h);
903 if ( Game_double_buffer )
904 gr_set_current_canvas(&VR_render_sub_buffer[0]);
906 gr_set_current_canvas(&Screen_3d_window);
908 if (Guided_missile[Player_num] &&
909 Guided_missile[Player_num]->type == OBJ_WEAPON &&
910 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
911 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
912 Guided_in_big_window.intval)
914 char *msg = "Guided Missile View";
915 object *viewer_save = Viewer;
918 if (Cockpit_mode.intval == CM_FULL_COCKPIT)
921 force_cockpit_redraw=1;
922 cvar_setint(&Cockpit_mode, CM_STATUS_BAR);
926 Viewer = Guided_missile[Player_num];
929 update_rendered_data(0, Viewer, 0, 0);
932 wake_up_rendered_objects(Viewer, 0);
933 Viewer = viewer_save;
935 gr_set_curfont( GAME_FONT ); //GAME_FONT );
936 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
937 gr_get_string_size(msg, &w, &h, &aw );
939 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
941 draw_guided_crosshair();
944 HUD_render_message_frame();
952 force_cockpit_redraw=1;
953 cvar_setint(&Cockpit_mode, CM_FULL_COCKPIT);
957 update_rendered_data(0, Viewer, Rear_view, 0);
961 if ( Game_double_buffer )
962 gr_set_current_canvas(&VR_render_sub_buffer[0]);
964 gr_set_current_canvas(&Screen_3d_window);
967 game_draw_hud_stuff();
969 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
970 extern char *Pause_msg;
971 ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
973 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
974 show_boxed_message(Pause_msg);
975 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
978 if ( Game_double_buffer ) { //copy to visible screen
979 // if ( !Game_cockpit_copy_code ) {
980 if ( VR_screen_flags&VRF_USE_PAGING ) {
981 VR_current_page = !VR_current_page;
982 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
983 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w, VR_render_sub_buffer[0].cv_h, VR_render_sub_buffer[0].cv_bitmap.bm_x, VR_render_sub_buffer[0].cv_bitmap.bm_y, 0, 0, &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap );
984 gr_wait_for_retrace = 0;
985 gr_show_canvas( &VR_screen_pages[VR_current_page] );
986 gr_wait_for_retrace = 1;
988 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w,
989 VR_render_sub_buffer[0].cv_h,
990 VR_render_sub_buffer[0].cv_bitmap.bm_x,
991 VR_render_sub_buffer[0].cv_bitmap.bm_y,
993 &VR_render_sub_buffer[0].cv_bitmap,
994 &VR_screen_pages[0].cv_bitmap );
1000 gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
1001 #else //def MACINTOSH
1002 gr_ibitblt( &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap );
1010 show_extra_views(); //missile view, buddy bot, etc.
1012 if (Cockpit_mode.intval == CM_FULL_COCKPIT || Cockpit_mode.intval == CM_STATUS_BAR) {
1014 if ( Newdemo_state == ND_STATE_PLAYBACK )
1015 Game_mode = Newdemo_game_mode;
1019 if ( Newdemo_state == ND_STATE_PLAYBACK )
1020 Game_mode = GM_NORMAL;
1031 void toggle_cockpit()
1035 switch (Cockpit_mode.intval) {
1037 case CM_FULL_COCKPIT: {
1038 int max_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR + (SM_HIRES?(Num_cockpits/2):0)].index].bm_h;
1039 if (Game_window_h.intval > max_h) //too big for statusbar
1040 new_mode = CM_FULL_SCREEN;
1042 new_mode = CM_STATUS_BAR;
1047 case CM_FULL_SCREEN:
1050 new_mode = CM_FULL_COCKPIT;
1056 return; //do nothing
1061 select_cockpit(new_mode);
1062 HUD_clear_messages();
1067 #define WINDOW_W_DELTA ((max_window_w / 16)&~1) //24 //20
1068 #define WINDOW_H_DELTA ((max_window_h / 16)&~1) //12 //10
1070 #define WINDOW_MIN_W ((max_window_w * 10) / 22) //160
1071 #define WINDOW_MIN_H ((max_window_h * 10) / 22)
1073 //#define WINDOW_W_DELTA 32
1074 //#define WINDOW_H_DELTA 16
1076 #define WINDOW_W_DELTA ((max_window_w / 16) & ~15) // double word aligned
1077 #define WINDOW_H_DELTA ((max_window_h / 16) & ~15) // double word aligned
1079 #define WINDOW_MIN_W (max_window_w-(WINDOW_W_DELTA*11))
1080 #define WINDOW_MIN_H (max_window_h-(WINDOW_H_DELTA*11))
1085 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
1086 cvar_setint(&Game_window_h, max_window_h);
1087 cvar_setint(&Game_window_w, max_window_w);
1089 HUD_init_message("Press F3 to return to Cockpit mode");
1093 if (Cockpit_mode.intval != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1096 if (Game_window_h.intval >= max_window_h || Game_window_w.intval >= max_window_w) {
1097 //cvar_setint(&Game_window_w, max_window_w);
1098 //cvar_setint(&Game_window_h, max_window_h);
1099 select_cockpit(CM_FULL_SCREEN);
1103 cvar_setint(&Game_window_w, Game_window_w.intval + WINDOW_W_DELTA);
1104 cvar_setint(&Game_window_h, Game_window_h.intval + WINDOW_H_DELTA);
1106 if (Game_window_h.intval > max_window_h)
1107 cvar_setint(&Game_window_h, max_window_h);
1109 if (Game_window_w.intval > max_window_w)
1110 cvar_setint(&Game_window_w, max_window_w);
1112 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1113 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1115 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w.intval, Game_window_h.intval );
1118 HUD_clear_messages(); // @mk, 11/11/94
1123 // grs_bitmap background_bitmap; already declared in line 434 (samir 4/10/94)
1125 extern grs_bitmap background_bitmap;
1127 void copy_background_rect(int left,int top,int right,int bot)
1129 grs_bitmap *bm = &background_bitmap;
1131 int tile_left,tile_right,tile_top,tile_bot;
1135 if (right < left || bot < top)
1138 tile_left = left / bm->bm_w;
1139 tile_right = right / bm->bm_w;
1140 tile_top = top / bm->bm_h;
1141 tile_bot = bot / bm->bm_h;
1143 ofs_y = top % bm->bm_h;
1146 for (y=tile_top;y<=tile_bot;y++) {
1149 ofs_x = left % bm->bm_w;
1152 //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
1153 h = min(bot-dest_y+1,bm->bm_h-ofs_y);
1155 for (x=tile_left;x<=tile_right;x++) {
1157 //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
1158 w = min(right-dest_x+1,bm->bm_w-ofs_x);
1160 gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
1161 &background_bitmap,&grd_curcanv->cv_bitmap);
1172 //fills int the background surrounding the 3d window
1173 void fill_background()
1179 w = Game_window_w.intval;
1180 h = Game_window_h.intval;
1185 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1186 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1187 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1188 copy_background_rect(x,y-dy,x+w-1,y-1);
1189 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1191 if (VR_screen_flags & VRF_USE_PAGING) {
1192 gr_set_current_canvas(&VR_screen_pages[!VR_current_page]);
1193 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1194 copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
1195 copy_background_rect(x,y-dy,x+w-1,y-1);
1196 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1200 void shrink_window()
1202 mprintf((0,"%d ",FrameCount));
1204 // mprintf((0, "W=%d H=%d\n", Game_window_w.intval, Game_window_h.intval));
1206 if (Cockpit_mode.intval == CM_FULL_COCKPIT && (VR_screen_flags & VRF_ALLOW_COCKPIT)) {
1207 cvar_setint(&Game_window_h, max_window_h);
1208 cvar_setint(&Game_window_w, max_window_w);
1209 //!!toggle_cockpit();
1210 select_cockpit(CM_STATUS_BAR);
1213 HUD_init_message("Press F3 to return to Cockpit mode");
1218 if (Cockpit_mode.intval == CM_FULL_SCREEN && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1220 //cvar_setint(&Game_window_w, max_window_w);
1221 //cvar_setint(&Game_window_h, max_window_h);
1222 select_cockpit(CM_STATUS_BAR);
1227 if (Cockpit_mode.intval != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1230 mprintf((0, "Cockpit mode=%d\n", Cockpit_mode.intval));
1232 if (Game_window_w.intval > WINDOW_MIN_W) {
1235 cvar_setint(&Game_window_w, Game_window_w.intval - WINDOW_W_DELTA);
1236 cvar_setint(&Game_window_h, Game_window_h.intval - WINDOW_H_DELTA);
1238 mprintf((0, "NewW=%d NewH=%d VW=%d maxH=%d\n", Game_window_w.intval, Game_window_h.intval, max_window_w, max_window_h));
1240 if ( Game_window_w.intval < WINDOW_MIN_W )
1241 cvar_setint(&Game_window_w, WINDOW_MIN_W);
1243 if ( Game_window_h.intval < WINDOW_MIN_H )
1244 cvar_setint(&Game_window_h, WINDOW_MIN_H);
1246 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1247 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1251 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w.intval, Game_window_h.intval );
1252 HUD_clear_messages();
1258 int last_drawn_cockpit[2] = { -1, -1 };
1259 extern void ogl_loadbmtexture(grs_bitmap *bm);
1261 // This actually renders the new cockpit onto the screen.
1262 void update_cockpits(int force_redraw)
1266 //Redraw the on-screen cockpit bitmaps
1267 if (VR_render_mode != VR_NONE ) return;
1269 switch( Cockpit_mode.intval ) {
1270 case CM_FULL_COCKPIT:
1272 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1273 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)]);
1274 gr_ubitmapm(0, 0, &GameBitmaps[cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)].index]);
1277 case CM_FULL_SCREEN:
1278 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1279 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1285 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1287 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)]);
1288 gr_ubitmapm(0, max_window_h, &GameBitmaps[cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)].index]);
1290 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1291 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1296 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1298 // Clear the top and bottom of the screen
1299 gr_setcolor(BM_XRGB(0,0,0));
1301 VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_y + VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_h,
1302 GWIDTH-1,GHEIGHT-1);
1303 gr_rect(0,0,GWIDTH-1,VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_y);
1305 // In a modex mode, clear the other buffer.
1306 if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
1307 gr_set_current_canvas(&VR_screen_pages[VR_current_page^1]);
1308 gr_clear_canvas( BM_XRGB(0,0,0) );
1309 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1315 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1317 if (Cockpit_mode.intval != last_drawn_cockpit[VR_current_page] || force_redraw )
1318 last_drawn_cockpit[VR_current_page] = Cockpit_mode.intval;
1322 if (Cockpit_mode.intval == CM_FULL_COCKPIT || Cockpit_mode.intval == CM_STATUS_BAR)
1328 void game_render_frame()
1330 set_screen_mode( SCREEN_GAME );
1332 // update_cockpits(0);
1334 play_homing_warning();
1336 if (VR_render_mode == VR_NONE )
1337 game_render_frame_mono();
1339 game_render_frame_stereo();
1342 // Make sure palette is faded in
1344 gr_palette_fade_in( gr_palette, 32, 0 );
1350 extern int Color_0_31_0;
1352 //draw a crosshair for the guided missile
1353 void draw_guided_crosshair(void)
1357 gr_setcolor(Color_0_31_0);
1359 w = grd_curcanv->cv_w>>5;
1363 h = i2f(w) / grd_curscreen->sc_aspect;
1365 x = grd_curcanv->cv_w / 2;
1366 y = grd_curcanv->cv_h / 2;
1368 gr_scanline(x-w/2,x+w/2,y);
1369 gr_uline(i2f(x),i2f(y-h/2),i2f(x),i2f(y+h/2));
1373 typedef struct bkg {
1374 short x, y, w, h; // The location of the menu.
1375 grs_bitmap * bmp; // The background under the menu.
1378 bkg bg = {0,0,0,0,NULL};
1380 #define BOX_BORDER (MenuHires?60:30)
1382 //show a message in a nice little box
1383 void show_boxed_message(char *msg)
1388 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1389 gr_set_curfont( MEDIUM1_FONT );
1391 gr_get_string_size(msg,&w,&h,&aw);
1393 x = (grd_curscreen->sc_w-w)/2;
1394 y = (grd_curscreen->sc_h-h)/2;
1397 gr_free_bitmap(bg.bmp);
1401 // Save the background of the display
1402 bg.x=x; bg.y=y; bg.w=w; bg.h=h;
1404 bg.bmp = gr_create_bitmap( w+BOX_BORDER, h+BOX_BORDER );
1406 gr_bm_ubitblt(w+BOX_BORDER, h+BOX_BORDER, 0, 0, x-BOX_BORDER/2, y-BOX_BORDER/2, &(grd_curcanv->cv_bitmap), bg.bmp );
1408 nm_draw_background(x-BOX_BORDER/2,y-BOX_BORDER/2,x+w+BOX_BORDER/2-1,y+h+BOX_BORDER/2-1);
1410 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
1412 gr_ustring( 0x8000, y, msg );
1415 void clear_boxed_message()
1420 gr_bitmap(bg.x-BOX_BORDER/2, bg.y-BOX_BORDER/2, bg.bmp);
1422 gr_free_bitmap(bg.bmp);