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
41 extern fix Cruise_speed;
42 extern int LinearSVGABuffer;
43 extern cvar_t r_framerate;
47 extern int Debug_pause; // John's debugging pause system
51 extern int Saving_movie_frames;
53 #define Saving_movie_frames 0
56 // Returns the length of the first 'n' characters of a string.
57 int string_width( char * s, int n )
63 gr_get_string_size( s, &w, &h, &aw );
68 // Draw string 's' centered on a canvas... if wider than
69 // canvas, then wrap it.
70 void draw_centered_text( int y, char * s )
77 if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w ) {
78 gr_string( 0x8000, y, s );
82 for (i=0; i<l; i++ ) {
83 if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) ) {
86 gr_string( 0x8000, y, s );
88 gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
94 extern ubyte DefiningMarkerMessage;
95 extern char Marker_input[];
97 #define MAX_MARKER_MESSAGE_LEN 120
98 void game_draw_marker_message()
100 char temp_string[MAX_MARKER_MESSAGE_LEN+25];
102 if ( DefiningMarkerMessage)
104 gr_set_curfont( GAME_FONT ); //GAME_FONT
105 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
106 sprintf( temp_string, "Marker: %s_", Marker_input );
107 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
113 void game_draw_multi_message()
115 char temp_string[MAX_MULTI_MESSAGE_LEN+25];
117 if ( (Game_mode&GM_MULTI) && (multi_sending_message)) {
118 gr_set_curfont( GAME_FONT ); //GAME_FONT );
119 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
120 sprintf( temp_string, "%s: %s_", TXT_MESSAGE, Network_message );
121 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
125 if ( (Game_mode&GM_MULTI) && (multi_defining_message)) {
126 gr_set_curfont( GAME_FONT ); //GAME_FONT );
127 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
128 sprintf( temp_string, "%s #%d: %s_", TXT_MACRO, multi_defining_message, Network_message );
129 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
134 //these should be in gr.h
135 #define cv_w cv_bitmap.bm_w
136 #define cv_h cv_bitmap.bm_h
138 fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
139 fix frame_time_total=0;
140 int frame_time_cntr=0;
142 void ftoa(char *string, fix f)
144 int decimal, fractional;
147 fractional = ((f & 0xffff)*100)/65536;
150 if (fractional > 99 ) fractional = 99;
151 sprintf( string, "%d.%02d", decimal, fractional );
154 void show_framerate()
160 int x = 8, y = 5; // position measured from lower right corner
162 frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
163 frame_time_list[frame_time_cntr] = RealFrameTime;
164 frame_time_cntr = (frame_time_cntr+1)%8;
166 rate = fixdiv(f1_0*8,frame_time_total);
168 gr_set_curfont( GAME_FONT );
169 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
171 ftoa( temp, rate ); // Convert fixed to string
172 if (Game_mode & GM_MULTI)
174 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 );
175 // if ( !( q++ % 30 ) )
176 // mprintf( (0,"fps: %s\n", temp ) );
181 fix Show_view_text_timer = -1;
183 void draw_window_label()
185 if ( Show_view_text_timer > 0 )
187 char *viewer_name,*control_name;
189 Show_view_text_timer -= FrameTime;
190 gr_set_curfont( GAME_FONT );
193 switch( Viewer->type )
195 case OBJ_FIREBALL: viewer_name = "Fireball"; break;
196 case OBJ_ROBOT: viewer_name = "Robot";
198 viewer_id = Robot_names[Viewer->id];
201 case OBJ_HOSTAGE: viewer_name = "Hostage"; break;
202 case OBJ_PLAYER: viewer_name = "Player"; break;
203 case OBJ_WEAPON: viewer_name = "Weapon"; break;
204 case OBJ_CAMERA: viewer_name = "Camera"; break;
205 case OBJ_POWERUP: viewer_name = "Powerup";
207 viewer_id = Powerup_names[Viewer->id];
210 case OBJ_DEBRIS: viewer_name = "Debris"; break;
211 case OBJ_CNTRLCEN: viewer_name = "Reactor"; break;
212 default: viewer_name = "Unknown"; break;
215 switch ( Viewer->control_type) {
216 case CT_NONE: control_name = "Stopped"; break;
217 case CT_AI: control_name = "AI"; break;
218 case CT_FLYING: control_name = "Flying"; break;
219 case CT_SLEW: control_name = "Slew"; break;
220 case CT_FLYTHROUGH: control_name = "Flythrough"; break;
221 case CT_MORPH: control_name = "Morphing"; break;
222 default: control_name = "Unknown"; break;
225 gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
226 gr_printf( 0x8000, 45, "%i: %s [%s] View - %s", OBJECT_NUMBER(Viewer), viewer_name, viewer_id, control_name );
232 extern int Game_window_x;
233 extern int Game_window_y;
234 extern int max_window_w;
235 extern int max_window_h;
237 void render_countdown_gauge()
239 if (!Endlevel_sequence && Control_center_destroyed && (Countdown_seconds_left>-1)) { // && (Countdown_seconds_left<127)) {
242 if (!is_D2_OEM && !is_MAC_SHARE && !is_SHAREWARE) // no countdown on registered only
244 // On last level, we don't want a countdown.
245 if (PLAYING_BUILTIN_MISSION && Current_level_num == Last_level)
247 if (!(Game_mode & GM_MULTI))
249 if (Game_mode & GM_MULTI_ROBOTS)
254 gr_set_curfont( SMALL_FONT );
255 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
256 y = SMALL_FONT->ft_h*4;
257 if (Cockpit_mode.intval == CM_FULL_SCREEN)
258 y += SMALL_FONT->ft_h*2;
261 y += SMALL_FONT->ft_h*2;
263 //if (!((Cockpit_mode.intval == CM_STATUS_BAR) && (Game_window_y >= 19)))
265 gr_printf(0x8000, y, "T-%d s", Countdown_seconds_left );
269 void game_draw_hud_stuff()
271 //mprintf ((0,"Linear is %d!\n",LinearSVGABuffer));
275 gr_set_curfont( MEDIUM1_FONT );
276 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
277 gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
286 game_draw_multi_message();
289 game_draw_marker_message();
291 // if (Game_mode & GM_MULTI)
293 // if (Netgame.PlayTimeAllowed)
294 // game_draw_time_left ();
297 if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
301 if (Newdemo_state == ND_STATE_PLAYBACK) {
302 if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
303 sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
305 sprintf (message, " ");
308 sprintf (message, "%s", TXT_DEMO_RECORDING);
310 gr_set_curfont( GAME_FONT ); //GAME_FONT );
311 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
313 gr_get_string_size(message, &w, &h, &aw );
314 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
315 if (grd_curcanv->cv_bitmap.bm_h > 240)
319 } else if ( Cockpit_mode.intval == CM_LETTERBOX )
321 if (Cockpit_mode.intval != CM_REAR_VIEW && !Saving_movie_frames)
322 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
325 render_countdown_gauge();
327 if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num ) {
329 int y = grd_curcanv->cv_bitmap.bm_h;
331 gr_set_curfont( GAME_FONT );
332 gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
333 if (Cruise_speed > 0) {
334 int line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
336 mprintf((0,"line_spacing=%d ",line_spacing));
338 if (Cockpit_mode.intval == CM_FULL_SCREEN) {
339 if (Game_mode & GM_MULTI)
340 y -= line_spacing * 11; //64
342 y -= line_spacing * 6; //32
343 } else if (Cockpit_mode.intval == CM_STATUS_BAR) {
344 if (Game_mode & GM_MULTI)
345 y -= line_spacing * 8; //48
347 y -= line_spacing * 4; //24
349 y = line_spacing * 2; //12
353 gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
357 if (r_framerate.intval)
360 if ( Newdemo_state == ND_STATE_PLAYBACK )
361 Game_mode = Newdemo_game_mode;
365 if ( Newdemo_state == ND_STATE_PLAYBACK )
366 Game_mode = GM_NORMAL;
368 if ( Player_is_dead )
369 player_dead_message();
372 extern int gr_bitblt_dest_step_shift;
373 extern int gr_wait_for_retrace;
374 extern int gr_bitblt_double;
377 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels );
378 #pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \
396 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels )
400 for (i = 0; i < num_src_pixels; i++) {
407 // doubles the size in x or y of a bitmap in place.
408 void game_expand_bitmap( grs_bitmap * bmp, uint flags )
411 ubyte * dptr, * sptr;
415 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
416 dptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
417 for (i=bmp->bm_h-1; i>=0; i-- ) {
418 expand_row( dptr, dptr, bmp->bm_w );
419 dptr -= bmp->bm_rowsize;
424 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
425 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
426 for (i=bmp->bm_h-1; i>=0; i-- ) {
427 memcpy( dptr, sptr, bmp->bm_w );
428 dptr -= bmp->bm_rowsize;
429 memcpy( dptr, sptr, bmp->bm_w );
430 dptr -= bmp->bm_rowsize;
431 sptr -= bmp->bm_rowsize;
435 case 3: // expand x & y
436 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
437 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
438 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
439 for (i=bmp->bm_h-1; i>=0; i-- ) {
440 expand_row( dptr, sptr, bmp->bm_w );
441 dptr -= bmp->bm_rowsize;
442 expand_row( dptr, sptr, bmp->bm_w );
443 dptr -= bmp->bm_rowsize;
444 sptr -= bmp->bm_rowsize;
452 extern int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
456 //render a frame for the game in stereo
457 void game_render_frame_stereo()
461 fix actual_eye_width;
462 int actual_eye_offset;
463 grs_canvas RenderCanvas[2];
466 save_aspect = grd_curscreen->sc_aspect;
467 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
469 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
470 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
472 if (VR_low_res & 1) {
474 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
476 if (VR_low_res & 2) {
478 grd_curscreen->sc_aspect /= 2; //Muck with aspect ratio
481 gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
482 gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
484 // Draw the left eye's view
486 actual_eye_width = -VR_eye_width;
487 actual_eye_offset = -VR_eye_offset;
489 actual_eye_width = VR_eye_width;
490 actual_eye_offset = VR_eye_offset;
493 if (Guided_missile[Player_num] &&
494 Guided_missile[Player_num]->type == OBJ_WEAPON &&
495 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
496 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
497 Guided_in_big_window.intval)
498 actual_eye_offset = 0;
500 gr_set_current_canvas(&RenderCanvas[0]);
502 if (Guided_missile[Player_num] &&
503 Guided_missile[Player_num]->type == OBJ_WEAPON &&
504 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
505 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
506 Guided_in_big_window.intval)
508 char *msg = "Guided Missile View";
509 object *viewer_save = Viewer;
512 Viewer = Guided_missile[Player_num];
515 update_rendered_data(0, Viewer, 0, 0);
518 wake_up_rendered_objects(Viewer, 0);
519 Viewer = viewer_save;
521 gr_set_curfont( GAME_FONT ); //GAME_FONT );
522 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
523 gr_get_string_size(msg, &w, &h, &aw );
525 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
527 draw_guided_crosshair();
530 HUD_render_message_frame();
535 render_frame(actual_eye_width, 0); // switch eye positions for rear view
537 render_frame(-actual_eye_width, 0); // Left eye
540 game_expand_bitmap( &RenderCanvas[0].cv_bitmap, VR_low_res );
542 { //render small window into left eye's canvas
543 grs_canvas *save=grd_curcanv;
544 fix save_aspect2 = grd_curscreen->sc_aspect;
545 grd_curscreen->sc_aspect = save_aspect*2;
546 SW_drawn[0] = SW_drawn[1] = 0;
548 gr_set_current_canvas(save);
549 grd_curscreen->sc_aspect = save_aspect2;
553 if (actual_eye_offset > 0 ) {
554 gr_setcolor( gr_getcolor(0,0,0) );
555 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
556 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
557 } else if (actual_eye_offset < 0 ) {
558 gr_setcolor( gr_getcolor(0,0,0) );
559 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
562 if ( VR_show_hud && !no_draw_hud ) {
564 if (actual_eye_offset < 0 ) {
565 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 );
567 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 );
569 gr_set_current_canvas( &tmp );
570 game_draw_hud_stuff();
574 // Draw the right eye's view
575 gr_set_current_canvas(&RenderCanvas[1]);
577 if (Guided_missile[Player_num] &&
578 Guided_missile[Player_num]->type == OBJ_WEAPON &&
579 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
580 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
581 Guided_in_big_window.intval)
582 gr_bitmap(0,0,&RenderCanvas[0].cv_bitmap);
585 render_frame(-actual_eye_width, 0); // switch eye positions for rear view
587 render_frame(actual_eye_width, 0); // Right eye
590 game_expand_bitmap( &RenderCanvas[1].cv_bitmap, VR_low_res );
594 { //copy small window from left eye
599 gr_init_sub_canvas(&temp,&RenderCanvas[0],SW_x[w],SW_y[w],SW_w[w],SW_h[w]);
600 gr_bitmap(SW_x[w]+actual_eye_offset*2,SW_y[w],&temp.cv_bitmap);
606 if (actual_eye_offset>0) {
607 gr_setcolor( gr_getcolor(0,0,0) );
608 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
609 } else if ( actual_eye_offset < 0 ) {
610 gr_setcolor( gr_getcolor(0,0,0) );
611 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
612 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
615 //NEWVR (Add the next 2 lines)
616 if ( VR_show_hud && !no_draw_hud ) {
618 if (actual_eye_offset > 0 ) {
619 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 );
621 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 );
623 gr_set_current_canvas( &tmp );
624 game_draw_hud_stuff();
628 // Draws white and black registration encoding lines
629 // and Accounts for pixel-shift adjustment in upcoming bitblts
630 if (VR_use_reg_code) {
631 int width, height, quarter;
633 width = RenderCanvas[0].cv_bitmap.bm_w;
634 height = RenderCanvas[0].cv_bitmap.bm_h;
637 // black out left-hand side of left page
639 // draw registration code for left eye
641 gr_set_current_canvas( &RenderCanvas[1] );
643 gr_set_current_canvas( &RenderCanvas[0] );
644 gr_setcolor( VR_WHITE_INDEX );
645 gr_scanline( 0, quarter, height-1 );
646 gr_setcolor( VR_BLACK_INDEX );
647 gr_scanline( quarter, width-1, height-1 );
650 gr_set_current_canvas( &RenderCanvas[0] );
652 gr_set_current_canvas( &RenderCanvas[1] );
653 gr_setcolor( VR_WHITE_INDEX );
654 gr_scanline( 0, quarter*3, height-1 );
655 gr_setcolor( VR_BLACK_INDEX );
656 gr_scanline( quarter*3, width-1, height-1 );
659 // Copy left eye, then right eye
660 if ( VR_screen_flags&VRF_USE_PAGING )
661 VR_current_page = !VR_current_page;
664 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
668 if ( VR_eye_offset_changed > 0 ) {
669 VR_eye_offset_changed--;
673 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
674 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
676 // Copy left eye, then right eye
677 gr_bitblt_dest_step_shift = 1; // Skip every other scanline.
679 if (VR_render_mode == VR_INTERLACED ) {
680 if ( actual_eye_offset > 0 ) {
681 int xoff = labs(actual_eye_offset);
682 gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
683 gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
684 } else if ( actual_eye_offset < 0 ) {
685 int xoff = labs(actual_eye_offset);
686 gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
687 gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
689 gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
690 gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
692 } else if (VR_render_mode == VR_AREA_DET) {
694 gr_bm_ubitblt( dw, dh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
695 gr_bm_ubitblt( dw, dh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
700 gr_bitblt_dest_step_shift = 0;
702 //if ( Game_vfx_flag )
703 // vfx_set_page(VR_current_page); // 0 or 1
705 if ( VR_screen_flags&VRF_USE_PAGING ) {
706 gr_wait_for_retrace = 0;
708 // Added by Samir from John's code
709 if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) ) {
710 int old_x, old_y, new_x;
711 old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
712 old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
713 new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
715 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
716 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
717 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
718 gr_show_canvas( &VR_screen_pages[VR_current_page] );
719 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
720 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
721 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
723 gr_show_canvas( &VR_screen_pages[VR_current_page] );
725 gr_wait_for_retrace = 1;
727 grd_curscreen->sc_aspect=save_aspect;
730 ubyte RenderingType=0;
731 ubyte DemoDoingRight=0,DemoDoingLeft=0;
732 extern ubyte DemoDoRight,DemoDoLeft;
733 extern object DemoRightExtra,DemoLeftExtra;
735 char DemoWBUType[]={0,WBU_MISSILE,WBU_MISSILE,WBU_REAR,WBU_ESCORT,WBU_MARKER,WBU_MISSILE};
736 char DemoRearCheck[]={0,0,0,1,0,0,0};
737 char *DemoExtraMessage[]={"PLAYER","GUIDED","MISSILE","REAR","GUIDE-BOT","MARKER","SHIP"};
739 extern char guidebot_name[];
741 void show_extra_views()
743 int did_missile_view = 0;
744 int save_newdemo_state = Newdemo_state;
747 if (Newdemo_state == ND_STATE_PLAYBACK) {
749 DemoDoingLeft = DemoDoLeft;
752 do_cockpit_window_view(0, ConsoleObject, 1, WBU_REAR, "REAR");
754 do_cockpit_window_view(0, &DemoLeftExtra, DemoRearCheck[DemoDoLeft], DemoWBUType[DemoDoLeft], DemoExtraMessage[DemoDoLeft]);
756 do_cockpit_window_view(0, NULL, 0, WBU_WEAPON, NULL);
759 DemoDoingRight = DemoDoRight;
761 if (DemoDoRight == 3)
762 do_cockpit_window_view(1, ConsoleObject, 1, WBU_REAR, "REAR");
764 do_cockpit_window_view(1, &DemoRightExtra, DemoRearCheck[DemoDoRight], DemoWBUType[DemoDoRight], DemoExtraMessage[DemoDoRight]);
766 do_cockpit_window_view(1, NULL, 0, WBU_WEAPON, NULL);
768 DemoDoLeft = DemoDoRight = 0;
769 DemoDoingLeft = DemoDoingRight = 0;
774 if (Guided_missile[Player_num] &&
775 Guided_missile[Player_num]->type == OBJ_WEAPON &&
776 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
777 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num])
779 if (Guided_in_big_window.intval) {
780 RenderingType = 6 + (1<<4);
781 do_cockpit_window_view(1, Viewer, 0, WBU_MISSILE, "SHIP");
783 RenderingType = 1 + (1<<4);
784 do_cockpit_window_view(1, Guided_missile[Player_num], 0, WBU_GUIDED, "GUIDED");
787 did_missile_view = 1;
790 if (Guided_missile[Player_num]) { // used to be active
791 if (!Guided_in_big_window.intval)
792 do_cockpit_window_view(1, NULL, 0, WBU_STATIC, NULL);
793 Guided_missile[Player_num] = NULL;
796 if (Missile_viewer) { // do missile view
797 static int mv_sig = -1;
799 mv_sig = Missile_viewer->signature;
800 if (Missile_view_enabled.intval &&
801 Missile_viewer->type != OBJ_NONE &&
802 Missile_viewer->signature == mv_sig)
804 RenderingType = 2 + (1<<4);
805 do_cockpit_window_view(1, Missile_viewer, 0, WBU_MISSILE, "MISSILE");
806 did_missile_view = 1;
808 Missile_viewer = NULL;
811 do_cockpit_window_view(1, NULL, 0, WBU_STATIC, NULL);
816 for (w = 0; w < 2; w++) {
818 if (w == 1 && did_missile_view)
819 continue; // if showing missile view in right window, can't show anything else
821 // show special views if selected
822 switch (Cockpit_3d_view[w].intval) {
825 do_cockpit_window_view(w, NULL, 0, WBU_WEAPON, NULL);
828 if (Rear_view) { // if big window is rear view, show front here
829 RenderingType = 3 + (w<<4);
830 do_cockpit_window_view(w, ConsoleObject, 0, WBU_REAR, "FRONT");
831 } else { // show normal rear view
832 RenderingType = 3 + (w<<4);
833 do_cockpit_window_view(w, ConsoleObject, 1, WBU_REAR, "REAR");
838 buddy = find_escort();
840 do_cockpit_window_view(w, NULL, 0, WBU_WEAPON, NULL);
841 cvar_setint(&Cockpit_3d_view[w], CV_NONE);
843 RenderingType = 4 + (w<<4);
844 do_cockpit_window_view(w, buddy, 0, WBU_ESCORT, guidebot_name);
850 int player = Coop_view_player[w];
852 RenderingType = 255; // don't handle coop stuff
855 Players[player].connected &&
856 ((Game_mode & GM_MULTI_COOP) || ((Game_mode & GM_TEAM) && (get_team(player) == get_team(Player_num)))))
857 do_cockpit_window_view(w, &Objects[Players[Coop_view_player[w]].objnum], 0, WBU_COOP, Players[Coop_view_player[w]].callsign);
859 do_cockpit_window_view(w, NULL, 0, WBU_WEAPON, NULL);
860 cvar_setint(&Cockpit_3d_view[w], CV_NONE);
868 RenderingType = 5 + (w<<4);
869 if (Marker_viewer_num[w] == -1 || MarkerObject[Marker_viewer_num[w]] == -1) {
870 cvar_setint(&Cockpit_3d_view[w], CV_NONE);
873 sprintf(label, "Marker %d", Marker_viewer_num[w] + 1);
874 do_cockpit_window_view(w, &Objects[MarkerObject[Marker_viewer_num[w]]], 0, WBU_MARKER, label);
878 Int3(); // invalid window type
882 Newdemo_state = save_newdemo_state;
885 int BigWindowSwitch = 0;
886 extern int force_cockpit_redraw;
888 void draw_guided_crosshair(void);
889 void update_cockpits(int force_redraw);
892 //render a frame for the game
893 void game_render_frame_mono(void)
895 grs_canvas Screen_3d_window;
899 gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
900 VR_render_sub_buffer[0].cv_bitmap.bm_x,
901 VR_render_sub_buffer[0].cv_bitmap.bm_y,
902 VR_render_sub_buffer[0].cv_bitmap.bm_w,
903 VR_render_sub_buffer[0].cv_bitmap.bm_h);
905 if ( Game_double_buffer )
906 gr_set_current_canvas(&VR_render_sub_buffer[0]);
908 gr_set_current_canvas(&Screen_3d_window);
910 if (Guided_missile[Player_num] &&
911 Guided_missile[Player_num]->type == OBJ_WEAPON &&
912 Guided_missile[Player_num]->id == GUIDEDMISS_ID &&
913 Guided_missile[Player_num]->signature == Guided_missile_sig[Player_num] &&
914 Guided_in_big_window.intval)
916 char *msg = "Guided Missile View";
917 object *viewer_save = Viewer;
920 if (Cockpit_mode.intval == CM_FULL_COCKPIT)
923 force_cockpit_redraw=1;
924 cvar_setint(&Cockpit_mode, CM_STATUS_BAR);
928 Viewer = Guided_missile[Player_num];
931 update_rendered_data(0, Viewer, 0, 0);
934 wake_up_rendered_objects(Viewer, 0);
935 Viewer = viewer_save;
937 gr_set_curfont( GAME_FONT ); //GAME_FONT );
938 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
939 gr_get_string_size(msg, &w, &h, &aw );
941 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
943 draw_guided_crosshair();
946 HUD_render_message_frame();
954 force_cockpit_redraw=1;
955 cvar_setint(&Cockpit_mode, CM_FULL_COCKPIT);
959 update_rendered_data(0, Viewer, Rear_view, 0);
963 if ( Game_double_buffer )
964 gr_set_current_canvas(&VR_render_sub_buffer[0]);
966 gr_set_current_canvas(&Screen_3d_window);
969 game_draw_hud_stuff();
971 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
972 extern char *Pause_msg;
973 ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
975 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
976 show_boxed_message(Pause_msg);
977 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
980 if ( Game_double_buffer ) { //copy to visible screen
981 // if ( !Game_cockpit_copy_code ) {
982 if ( VR_screen_flags&VRF_USE_PAGING ) {
983 VR_current_page = !VR_current_page;
984 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
985 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 );
986 gr_wait_for_retrace = 0;
987 gr_show_canvas( &VR_screen_pages[VR_current_page] );
988 gr_wait_for_retrace = 1;
990 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w,
991 VR_render_sub_buffer[0].cv_h,
992 VR_render_sub_buffer[0].cv_bitmap.bm_x,
993 VR_render_sub_buffer[0].cv_bitmap.bm_y,
995 &VR_render_sub_buffer[0].cv_bitmap,
996 &VR_screen_pages[0].cv_bitmap );
1002 gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
1003 #else //def MACINTOSH
1004 gr_ibitblt( &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap );
1012 show_extra_views(); //missile view, buddy bot, etc.
1014 if (Cockpit_mode.intval == CM_FULL_COCKPIT || Cockpit_mode.intval == CM_STATUS_BAR) {
1016 if ( Newdemo_state == ND_STATE_PLAYBACK )
1017 Game_mode = Newdemo_game_mode;
1021 if ( Newdemo_state == ND_STATE_PLAYBACK )
1022 Game_mode = GM_NORMAL;
1033 void toggle_cockpit()
1037 switch (Cockpit_mode.intval) {
1039 case CM_FULL_COCKPIT: {
1040 int max_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR + (SM_HIRES?(Num_cockpits/2):0)].index].bm_h;
1041 if (Game_window_h.intval > max_h) //too big for statusbar
1042 new_mode = CM_FULL_SCREEN;
1044 new_mode = CM_STATUS_BAR;
1049 case CM_FULL_SCREEN:
1052 new_mode = CM_FULL_COCKPIT;
1058 return; //do nothing
1063 select_cockpit(new_mode);
1064 HUD_clear_messages();
1069 #define WINDOW_W_DELTA ((max_window_w / 16)&~1) //24 //20
1070 #define WINDOW_H_DELTA ((max_window_h / 16)&~1) //12 //10
1072 #define WINDOW_MIN_W ((max_window_w * 10) / 22) //160
1073 #define WINDOW_MIN_H ((max_window_h * 10) / 22)
1075 //#define WINDOW_W_DELTA 32
1076 //#define WINDOW_H_DELTA 16
1078 #define WINDOW_W_DELTA ((max_window_w / 16) & ~15) // double word aligned
1079 #define WINDOW_H_DELTA ((max_window_h / 16) & ~15) // double word aligned
1081 #define WINDOW_MIN_W (max_window_w-(WINDOW_W_DELTA*11))
1082 #define WINDOW_MIN_H (max_window_h-(WINDOW_H_DELTA*11))
1087 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
1088 cvar_setint(&Game_window_h, max_window_h);
1089 cvar_setint(&Game_window_w, max_window_w);
1091 HUD_init_message("Press F3 to return to Cockpit mode");
1095 if (Cockpit_mode.intval != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1098 if (Game_window_h.intval >= max_window_h || Game_window_w.intval >= max_window_w) {
1099 //cvar_setint(&Game_window_w, max_window_w);
1100 //cvar_setint(&Game_window_h, max_window_h);
1101 select_cockpit(CM_FULL_SCREEN);
1105 cvar_setint(&Game_window_w, Game_window_w.intval + WINDOW_W_DELTA);
1106 cvar_setint(&Game_window_h, Game_window_h.intval + WINDOW_H_DELTA);
1108 if (Game_window_h.intval > max_window_h)
1109 cvar_setint(&Game_window_h, max_window_h);
1111 if (Game_window_w.intval > max_window_w)
1112 cvar_setint(&Game_window_w, max_window_w);
1114 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1115 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1117 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w.intval, Game_window_h.intval );
1120 HUD_clear_messages(); // @mk, 11/11/94
1125 // grs_bitmap background_bitmap; already declared in line 434 (samir 4/10/94)
1127 extern grs_bitmap background_bitmap;
1129 void copy_background_rect(int left,int top,int right,int bot)
1131 grs_bitmap *bm = &background_bitmap;
1133 int tile_left,tile_right,tile_top,tile_bot;
1137 if (right < left || bot < top)
1140 tile_left = left / bm->bm_w;
1141 tile_right = right / bm->bm_w;
1142 tile_top = top / bm->bm_h;
1143 tile_bot = bot / bm->bm_h;
1145 ofs_y = top % bm->bm_h;
1148 for (y=tile_top;y<=tile_bot;y++) {
1151 ofs_x = left % bm->bm_w;
1154 //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
1155 h = min(bot-dest_y+1,bm->bm_h-ofs_y);
1157 for (x=tile_left;x<=tile_right;x++) {
1159 //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
1160 w = min(right-dest_x+1,bm->bm_w-ofs_x);
1162 gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
1163 &background_bitmap,&grd_curcanv->cv_bitmap);
1174 //fills int the background surrounding the 3d window
1175 void fill_background()
1181 w = Game_window_w.intval;
1182 h = Game_window_h.intval;
1187 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1188 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1189 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1190 copy_background_rect(x,y-dy,x+w-1,y-1);
1191 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1193 if (VR_screen_flags & VRF_USE_PAGING) {
1194 gr_set_current_canvas(&VR_screen_pages[!VR_current_page]);
1195 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1196 copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
1197 copy_background_rect(x,y-dy,x+w-1,y-1);
1198 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1202 void shrink_window()
1204 mprintf((0,"%d ",FrameCount));
1206 // mprintf((0, "W=%d H=%d\n", Game_window_w.intval, Game_window_h.intval));
1208 if (Cockpit_mode.intval == CM_FULL_COCKPIT && (VR_screen_flags & VRF_ALLOW_COCKPIT)) {
1209 cvar_setint(&Game_window_h, max_window_h);
1210 cvar_setint(&Game_window_w, max_window_w);
1211 //!!toggle_cockpit();
1212 select_cockpit(CM_STATUS_BAR);
1215 HUD_init_message("Press F3 to return to Cockpit mode");
1220 if (Cockpit_mode.intval == CM_FULL_SCREEN && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1222 //cvar_setint(&Game_window_w, max_window_w);
1223 //cvar_setint(&Game_window_h, max_window_h);
1224 select_cockpit(CM_STATUS_BAR);
1229 if (Cockpit_mode.intval != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1232 mprintf((0, "Cockpit mode=%d\n", Cockpit_mode.intval));
1234 if (Game_window_w.intval > WINDOW_MIN_W) {
1237 cvar_setint(&Game_window_w, Game_window_w.intval - WINDOW_W_DELTA);
1238 cvar_setint(&Game_window_h, Game_window_h.intval - WINDOW_H_DELTA);
1240 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));
1242 if ( Game_window_w.intval < WINDOW_MIN_W )
1243 cvar_setint(&Game_window_w, WINDOW_MIN_W);
1245 if ( Game_window_h.intval < WINDOW_MIN_H )
1246 cvar_setint(&Game_window_h, WINDOW_MIN_H);
1248 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1249 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1253 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w.intval, Game_window_h.intval );
1254 HUD_clear_messages();
1260 int last_drawn_cockpit[2] = { -1, -1 };
1261 extern void ogl_loadbmtexture(grs_bitmap *bm);
1263 // This actually renders the new cockpit onto the screen.
1264 void update_cockpits(int force_redraw)
1268 //Redraw the on-screen cockpit bitmaps
1269 if (VR_render_mode != VR_NONE ) return;
1271 switch( Cockpit_mode.intval ) {
1272 case CM_FULL_COCKPIT:
1274 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1275 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)]);
1276 gr_ubitmapm(0, 0, &GameBitmaps[cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)].index]);
1279 case CM_FULL_SCREEN:
1280 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1281 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1287 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1289 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)]);
1290 gr_ubitmapm(0, max_window_h, &GameBitmaps[cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES?(Num_cockpits/2):0)].index]);
1292 Game_window_x = (max_window_w - Game_window_w.intval) / 2;
1293 Game_window_y = (max_window_h - Game_window_h.intval) / 2;
1298 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1300 // Clear the top and bottom of the screen
1301 gr_setcolor(BM_XRGB(0,0,0));
1303 VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_y + VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_h,
1304 GWIDTH-1,GHEIGHT-1);
1305 gr_rect(0,0,GWIDTH-1,VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_y);
1307 // In a modex mode, clear the other buffer.
1308 if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
1309 gr_set_current_canvas(&VR_screen_pages[VR_current_page^1]);
1310 gr_clear_canvas( BM_XRGB(0,0,0) );
1311 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1317 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1319 if (Cockpit_mode.intval != last_drawn_cockpit[VR_current_page] || force_redraw )
1320 last_drawn_cockpit[VR_current_page] = Cockpit_mode.intval;
1324 if (Cockpit_mode.intval == CM_FULL_COCKPIT || Cockpit_mode.intval == CM_STATUS_BAR)
1330 void game_render_frame()
1332 set_screen_mode( SCREEN_GAME );
1334 // update_cockpits(0);
1336 play_homing_warning();
1338 if (VR_render_mode == VR_NONE )
1339 game_render_frame_mono();
1341 game_render_frame_stereo();
1344 // Make sure palette is faded in
1346 gr_palette_fade_in( gr_palette, 32, 0 );
1352 extern int Color_0_31_0;
1354 //draw a crosshair for the guided missile
1355 void draw_guided_crosshair(void)
1359 gr_setcolor(Color_0_31_0);
1361 w = grd_curcanv->cv_w>>5;
1365 h = i2f(w) / grd_curscreen->sc_aspect;
1367 x = grd_curcanv->cv_w / 2;
1368 y = grd_curcanv->cv_h / 2;
1370 gr_scanline(x-w/2,x+w/2,y);
1371 gr_uline(i2f(x),i2f(y-h/2),i2f(x),i2f(y+h/2));
1375 typedef struct bkg {
1376 short x, y, w, h; // The location of the menu.
1377 grs_bitmap * bmp; // The background under the menu.
1380 bkg bg = {0,0,0,0,NULL};
1382 #define BOX_BORDER (MenuHires?60:30)
1384 //show a message in a nice little box
1385 void show_boxed_message(char *msg)
1390 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1391 gr_set_curfont( MEDIUM1_FONT );
1393 gr_get_string_size(msg,&w,&h,&aw);
1395 x = (grd_curscreen->sc_w-w)/2;
1396 y = (grd_curscreen->sc_h-h)/2;
1399 gr_free_bitmap(bg.bmp);
1403 // Save the background of the display
1404 bg.x=x; bg.y=y; bg.w=w; bg.h=h;
1406 bg.bmp = gr_create_bitmap( w+BOX_BORDER, h+BOX_BORDER );
1408 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 );
1410 nm_draw_background(x-BOX_BORDER/2,y-BOX_BORDER/2,x+w+BOX_BORDER/2-1,y+h+BOX_BORDER/2-1);
1412 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
1414 gr_ustring( 0x8000, y, msg );
1417 void clear_boxed_message()
1422 gr_bitmap(bg.x-BOX_BORDER/2, bg.y-BOX_BORDER/2, bg.bmp);
1424 gr_free_bitmap(bg.bmp);