1 /* $Id: gamerend.c,v 1.18 2005-07-30 09:16:25 chris Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Stuff for rendering the HUD
26 static char rcsid[] = "$Id: gamerend.c,v 1.18 2005-07-30 09:16:25 chris Exp $";
73 extern fix Cruise_speed;
74 extern int LinearSVGABuffer;
75 extern int Current_display_mode;
76 extern cvar_t r_framerate;
80 cockpit_span_line win_cockpit_mask[480];
81 void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest);
86 extern int Debug_pause; //John's debugging pause system
90 extern int Saving_movie_frames;
92 #define Saving_movie_frames 0
95 // Returns the length of the first 'n' characters of a string.
96 int string_width( char * s, int n )
102 gr_get_string_size( s, &w, &h, &aw );
107 // Draw string 's' centered on a canvas... if wider than
108 // canvas, then wrap it.
109 void draw_centered_text( int y, char * s )
116 if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w ) {
117 gr_string( 0x8000, y, s );
121 for (i=0; i<l; i++ ) {
122 if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) ) {
125 gr_string( 0x8000, y, s );
127 gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
133 extern ubyte DefiningMarkerMessage;
134 extern char Marker_input[];
136 #define MAX_MARKER_MESSAGE_LEN 120
137 void game_draw_marker_message()
139 char temp_string[MAX_MARKER_MESSAGE_LEN+25];
141 if ( DefiningMarkerMessage)
143 gr_set_curfont( GAME_FONT ); //GAME_FONT
144 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
145 sprintf( temp_string, "Marker: %s_", Marker_input );
146 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
152 void game_draw_multi_message()
154 char temp_string[MAX_MULTI_MESSAGE_LEN+25];
156 if ( (Game_mode&GM_MULTI) && (multi_sending_message)) {
157 gr_set_curfont( GAME_FONT ); //GAME_FONT );
158 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
159 sprintf( temp_string, "%s: %s_", TXT_MESSAGE, Network_message );
160 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
164 if ( (Game_mode&GM_MULTI) && (multi_defining_message)) {
165 gr_set_curfont( GAME_FONT ); //GAME_FONT );
166 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
167 sprintf( temp_string, "%s #%d: %s_", TXT_MACRO, multi_defining_message, Network_message );
168 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
173 //these should be in gr.h
174 #define cv_w cv_bitmap.bm_w
175 #define cv_h cv_bitmap.bm_h
177 fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
178 fix frame_time_total=0;
179 int frame_time_cntr=0;
181 void ftoa(char *string, fix f)
183 int decimal, fractional;
186 fractional = ((f & 0xffff)*100)/65536;
189 if (fractional > 99 ) fractional = 99;
190 sprintf( string, "%d.%02d", decimal, fractional );
193 void show_framerate()
199 int x = 8, y = 5; // position measured from lower right corner
201 frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
202 frame_time_list[frame_time_cntr] = RealFrameTime;
203 frame_time_cntr = (frame_time_cntr+1)%8;
205 rate = fixdiv(f1_0*8,frame_time_total);
207 gr_set_curfont( GAME_FONT );
208 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
210 ftoa( temp, rate ); // Convert fixed to string
211 if (Game_mode & GM_MULTI)
213 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 );
214 // if ( !( q++ % 30 ) )
215 // mprintf( (0,"fps: %s\n", temp ) );
220 fix Show_view_text_timer = -1;
222 void draw_window_label()
224 if ( Show_view_text_timer > 0 )
226 char *viewer_name,*control_name;
228 Show_view_text_timer -= FrameTime;
229 gr_set_curfont( GAME_FONT );
232 switch( Viewer->type )
234 case OBJ_FIREBALL: viewer_name = "Fireball"; break;
235 case OBJ_ROBOT: viewer_name = "Robot";
237 viewer_id = Robot_names[Viewer->id];
240 case OBJ_HOSTAGE: viewer_name = "Hostage"; break;
241 case OBJ_PLAYER: viewer_name = "Player"; break;
242 case OBJ_WEAPON: viewer_name = "Weapon"; break;
243 case OBJ_CAMERA: viewer_name = "Camera"; break;
244 case OBJ_POWERUP: viewer_name = "Powerup";
246 viewer_id = Powerup_names[Viewer->id];
249 case OBJ_DEBRIS: viewer_name = "Debris"; break;
250 case OBJ_CNTRLCEN: viewer_name = "Reactor"; break;
251 default: viewer_name = "Unknown"; break;
254 switch ( Viewer->control_type) {
255 case CT_NONE: control_name = "Stopped"; break;
256 case CT_AI: control_name = "AI"; break;
257 case CT_FLYING: control_name = "Flying"; break;
258 case CT_SLEW: control_name = "Slew"; break;
259 case CT_FLYTHROUGH: control_name = "Flythrough"; break;
260 case CT_MORPH: control_name = "Morphing"; break;
261 default: control_name = "Unknown"; break;
264 gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
265 gr_printf( 0x8000, 45, "%i: %s [%s] View - %s",Viewer-Objects, viewer_name, viewer_id, control_name );
271 extern int Game_window_x;
272 extern int Game_window_y;
273 extern int Game_window_w;
274 extern int Game_window_h;
275 extern int max_window_w;
276 extern int max_window_h;
278 void render_countdown_gauge()
280 if (!Endlevel_sequence && Control_center_destroyed && (Countdown_seconds_left>-1)) { // && (Countdown_seconds_left<127)) {
283 if (!is_D2_OEM && !is_MAC_SHARE && !is_SHAREWARE) // no countdown on registered only
285 // On last level, we don't want a countdown.
286 if (PLAYING_BUILTIN_MISSION && Current_level_num == Last_level)
288 if (!(Game_mode & GM_MULTI))
290 if (Game_mode & GM_MULTI_ROBOTS)
295 gr_set_curfont( SMALL_FONT );
296 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
297 y = SMALL_FONT->ft_h*4;
298 if (Cockpit_mode == CM_FULL_SCREEN)
299 y += SMALL_FONT->ft_h*2;
302 y += SMALL_FONT->ft_h*2;
304 //if (!((Cockpit_mode == CM_STATUS_BAR) && (Game_window_y >= 19)))
306 gr_printf(0x8000, y, "T-%d s", Countdown_seconds_left );
310 void game_draw_hud_stuff()
312 //mprintf ((0,"Linear is %d!\n",LinearSVGABuffer));
316 gr_set_curfont( MEDIUM1_FONT );
317 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
318 gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
327 game_draw_multi_message();
330 game_draw_marker_message();
332 // if (Game_mode & GM_MULTI)
334 // if (Netgame.PlayTimeAllowed)
335 // game_draw_time_left ();
338 if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
342 if (Newdemo_state == ND_STATE_PLAYBACK) {
343 if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
344 sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
346 sprintf (message, " ");
349 sprintf (message, TXT_DEMO_RECORDING);
351 gr_set_curfont( GAME_FONT ); //GAME_FONT );
352 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
354 gr_get_string_size(message, &w, &h, &aw );
355 if (Cockpit_mode == CM_FULL_COCKPIT) {
356 if (grd_curcanv->cv_bitmap.bm_h > 240)
360 } else if ( Cockpit_mode == CM_LETTERBOX )
362 if (Cockpit_mode != CM_REAR_VIEW && !Saving_movie_frames)
363 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
366 render_countdown_gauge();
368 if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num ) {
370 int y = grd_curcanv->cv_bitmap.bm_h;
372 gr_set_curfont( GAME_FONT );
373 gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
374 if (Cruise_speed > 0) {
375 int line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
377 mprintf((0,"line_spacing=%d ",line_spacing));
379 if (Cockpit_mode==CM_FULL_SCREEN) {
380 if (Game_mode & GM_MULTI)
381 y -= line_spacing * 11; //64
383 y -= line_spacing * 6; //32
384 } else if (Cockpit_mode == CM_STATUS_BAR) {
385 if (Game_mode & GM_MULTI)
386 y -= line_spacing * 8; //48
388 y -= line_spacing * 4; //24
390 y = line_spacing * 2; //12
394 gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
398 if (r_framerate.value)
401 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
402 Game_mode = Newdemo_game_mode;
406 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
407 Game_mode = GM_NORMAL;
409 if ( Player_is_dead )
410 player_dead_message();
413 extern int gr_bitblt_dest_step_shift;
414 extern int gr_wait_for_retrace;
415 extern int gr_bitblt_double;
418 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels );
419 #pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \
437 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels )
441 for (i = 0; i < num_src_pixels; i++) {
448 // doubles the size in x or y of a bitmap in place.
449 void game_expand_bitmap( grs_bitmap * bmp, uint flags )
452 ubyte * dptr, * sptr;
456 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
457 dptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
458 for (i=bmp->bm_h-1; i>=0; i-- ) {
459 expand_row( dptr, dptr, bmp->bm_w );
460 dptr -= bmp->bm_rowsize;
465 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
466 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
467 for (i=bmp->bm_h-1; i>=0; i-- ) {
468 memcpy( dptr, sptr, bmp->bm_w );
469 dptr -= bmp->bm_rowsize;
470 memcpy( dptr, sptr, bmp->bm_w );
471 dptr -= bmp->bm_rowsize;
472 sptr -= bmp->bm_rowsize;
476 case 3: // expand x & y
477 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
478 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
479 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
480 for (i=bmp->bm_h-1; i>=0; i-- ) {
481 expand_row( dptr, sptr, bmp->bm_w );
482 dptr -= bmp->bm_rowsize;
483 expand_row( dptr, sptr, bmp->bm_w );
484 dptr -= bmp->bm_rowsize;
485 sptr -= bmp->bm_rowsize;
493 extern int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
495 extern int Guided_in_big_window;
498 //render a frame for the game in stereo
499 void game_render_frame_stereo()
503 fix actual_eye_width;
504 int actual_eye_offset;
505 grs_canvas RenderCanvas[2];
508 save_aspect = grd_curscreen->sc_aspect;
509 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
511 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
512 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
514 if (VR_low_res & 1) {
516 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
518 if (VR_low_res & 2) {
520 grd_curscreen->sc_aspect /= 2; //Muck with aspect ratio
523 gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
524 gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
526 // Draw the left eye's view
528 actual_eye_width = -VR_eye_width;
529 actual_eye_offset = -VR_eye_offset;
531 actual_eye_width = VR_eye_width;
532 actual_eye_offset = VR_eye_offset;
535 if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID && Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num] && Guided_in_big_window)
536 actual_eye_offset = 0;
538 gr_set_current_canvas(&RenderCanvas[0]);
540 if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID && Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num] && Guided_in_big_window) {
541 char *msg = "Guided Missile View";
542 object *viewer_save = Viewer;
545 Viewer = Guided_missile[Player_num];
547 WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
549 update_rendered_data(0, Viewer, 0, 0);
552 wake_up_rendered_objects(Viewer, 0);
553 Viewer = viewer_save;
555 gr_set_curfont( GAME_FONT ); //GAME_FONT );
556 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
557 gr_get_string_size(msg, &w, &h, &aw );
559 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
561 draw_guided_crosshair();
563 WIN(DDGRUNLOCK(dd_grd_curcanv));
565 HUD_render_message_frame();
570 render_frame(actual_eye_width, 0); // switch eye positions for rear view
572 render_frame(-actual_eye_width, 0); // Left eye
575 game_expand_bitmap( &RenderCanvas[0].cv_bitmap, VR_low_res );
577 { //render small window into left eye's canvas
578 grs_canvas *save=grd_curcanv;
579 fix save_aspect2 = grd_curscreen->sc_aspect;
580 grd_curscreen->sc_aspect = save_aspect*2;
581 SW_drawn[0] = SW_drawn[1] = 0;
583 gr_set_current_canvas(save);
584 grd_curscreen->sc_aspect = save_aspect2;
588 if (actual_eye_offset > 0 ) {
589 gr_setcolor( gr_getcolor(0,0,0) );
590 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
591 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
592 } else if (actual_eye_offset < 0 ) {
593 gr_setcolor( gr_getcolor(0,0,0) );
594 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
597 if ( VR_show_hud && !no_draw_hud ) {
599 if (actual_eye_offset < 0 ) {
600 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 );
602 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 );
604 gr_set_current_canvas( &tmp );
605 game_draw_hud_stuff();
609 // Draw the right eye's view
610 gr_set_current_canvas(&RenderCanvas[1]);
612 if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID && Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num] && Guided_in_big_window)
613 gr_bitmap(0,0,&RenderCanvas[0].cv_bitmap);
616 render_frame(-actual_eye_width, 0); // switch eye positions for rear view
618 render_frame(actual_eye_width, 0); // Right eye
621 game_expand_bitmap( &RenderCanvas[1].cv_bitmap, VR_low_res );
625 { //copy small window from left eye
630 gr_init_sub_canvas(&temp,&RenderCanvas[0],SW_x[w],SW_y[w],SW_w[w],SW_h[w]);
631 gr_bitmap(SW_x[w]+actual_eye_offset*2,SW_y[w],&temp.cv_bitmap);
637 if (actual_eye_offset>0) {
638 gr_setcolor( gr_getcolor(0,0,0) );
639 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
640 } else if ( actual_eye_offset < 0 ) {
641 gr_setcolor( gr_getcolor(0,0,0) );
642 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
643 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
646 //NEWVR (Add the next 2 lines)
647 if ( VR_show_hud && !no_draw_hud ) {
649 if (actual_eye_offset > 0 ) {
650 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 );
652 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 );
654 gr_set_current_canvas( &tmp );
655 game_draw_hud_stuff();
659 // Draws white and black registration encoding lines
660 // and Accounts for pixel-shift adjustment in upcoming bitblts
661 if (VR_use_reg_code) {
662 int width, height, quarter;
664 width = RenderCanvas[0].cv_bitmap.bm_w;
665 height = RenderCanvas[0].cv_bitmap.bm_h;
668 // black out left-hand side of left page
670 // draw registration code for left eye
672 gr_set_current_canvas( &RenderCanvas[1] );
674 gr_set_current_canvas( &RenderCanvas[0] );
675 gr_setcolor( VR_WHITE_INDEX );
676 gr_scanline( 0, quarter, height-1 );
677 gr_setcolor( VR_BLACK_INDEX );
678 gr_scanline( quarter, width-1, height-1 );
681 gr_set_current_canvas( &RenderCanvas[0] );
683 gr_set_current_canvas( &RenderCanvas[1] );
684 gr_setcolor( VR_WHITE_INDEX );
685 gr_scanline( 0, quarter*3, height-1 );
686 gr_setcolor( VR_BLACK_INDEX );
687 gr_scanline( quarter*3, width-1, height-1 );
690 // Copy left eye, then right eye
691 if ( VR_screen_flags&VRF_USE_PAGING )
692 VR_current_page = !VR_current_page;
695 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
699 if ( VR_eye_offset_changed > 0 ) {
700 VR_eye_offset_changed--;
704 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
705 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
707 // Copy left eye, then right eye
708 gr_bitblt_dest_step_shift = 1; // Skip every other scanline.
710 if (VR_render_mode == VR_INTERLACED ) {
711 if ( actual_eye_offset > 0 ) {
712 int xoff = labs(actual_eye_offset);
713 gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
714 gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
715 } else if ( actual_eye_offset < 0 ) {
716 int xoff = labs(actual_eye_offset);
717 gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
718 gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
720 gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
721 gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
723 } else if (VR_render_mode == VR_AREA_DET) {
725 gr_bm_ubitblt( dw, dh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
726 gr_bm_ubitblt( dw, dh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
731 gr_bitblt_dest_step_shift = 0;
733 //if ( Game_vfx_flag )
734 // vfx_set_page(VR_current_page); // 0 or 1
736 if ( VR_screen_flags&VRF_USE_PAGING ) {
737 gr_wait_for_retrace = 0;
739 // Added by Samir from John's code
740 if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) ) {
741 int old_x, old_y, new_x;
742 old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
743 old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
744 new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
746 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
747 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
748 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
749 gr_show_canvas( &VR_screen_pages[VR_current_page] );
750 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
751 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
752 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
754 gr_show_canvas( &VR_screen_pages[VR_current_page] );
756 gr_wait_for_retrace = 1;
758 grd_curscreen->sc_aspect=save_aspect;
761 ubyte RenderingType=0;
762 ubyte DemoDoingRight=0,DemoDoingLeft=0;
763 extern ubyte DemoDoRight,DemoDoLeft;
764 extern object DemoRightExtra,DemoLeftExtra;
766 char DemoWBUType[]={0,WBU_MISSILE,WBU_MISSILE,WBU_REAR,WBU_ESCORT,WBU_MARKER,WBU_MISSILE};
767 char DemoRearCheck[]={0,0,0,1,0,0,0};
768 char *DemoExtraMessage[]={"PLAYER","GUIDED","MISSILE","REAR","GUIDE-BOT","MARKER","SHIP"};
770 extern char guidebot_name[];
772 void show_extra_views()
774 int did_missile_view=0;
775 int save_newdemo_state = Newdemo_state;
778 if (Newdemo_state==ND_STATE_PLAYBACK)
782 DemoDoingLeft=DemoDoLeft;
785 do_cockpit_window_view(0,ConsoleObject,1,WBU_REAR,"REAR");
787 do_cockpit_window_view(0,&DemoLeftExtra,DemoRearCheck[DemoDoLeft],DemoWBUType[DemoDoLeft],DemoExtraMessage[DemoDoLeft]);
790 do_cockpit_window_view(0,NULL,0,WBU_WEAPON,NULL);
794 DemoDoingRight=DemoDoRight;
797 do_cockpit_window_view(1,ConsoleObject,1,WBU_REAR,"REAR");
799 do_cockpit_window_view(1,&DemoRightExtra,DemoRearCheck[DemoDoRight],DemoWBUType[DemoDoRight],DemoExtraMessage[DemoDoRight]);
802 do_cockpit_window_view(1,NULL,0,WBU_WEAPON,NULL);
804 DemoDoLeft=DemoDoRight=0;
805 DemoDoingLeft=DemoDoingRight=0;
810 if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID && Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num]) {
811 if (Guided_in_big_window)
813 RenderingType=6+(1<<4);
814 do_cockpit_window_view(1,Viewer,0,WBU_MISSILE,"SHIP");
818 RenderingType=1+(1<<4);
819 do_cockpit_window_view(1,Guided_missile[Player_num],0,WBU_GUIDED,"GUIDED");
826 if (Guided_missile[Player_num]) { //used to be active
827 if (!Guided_in_big_window)
828 do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
829 Guided_missile[Player_num] = NULL;
832 if (Missile_viewer) { //do missile view
833 static int mv_sig=-1;
835 mv_sig = Missile_viewer->signature;
836 if (Missile_view_enabled && Missile_viewer->type!=OBJ_NONE && Missile_viewer->signature == mv_sig) {
837 RenderingType=2+(1<<4);
838 do_cockpit_window_view(1,Missile_viewer,0,WBU_MISSILE,"MISSILE");
842 Missile_viewer = NULL;
845 do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
852 if (w==1 && did_missile_view)
853 continue; //if showing missile view in right window, can't show anything else
855 //show special views if selected
856 switch (Cockpit_3d_view[w]) {
859 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
862 if (Rear_view) { //if big window is rear view, show front here
863 RenderingType=3+(w<<4);
864 do_cockpit_window_view(w,ConsoleObject,0,WBU_REAR,"FRONT");
866 else { //show normal rear view
867 RenderingType=3+(w<<4);
868 do_cockpit_window_view(w,ConsoleObject,1,WBU_REAR,"REAR");
873 buddy = find_escort();
875 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
876 Cockpit_3d_view[w] = CV_NONE;
879 RenderingType=4+(w<<4);
880 do_cockpit_window_view(w,buddy,0,WBU_ESCORT,guidebot_name);
886 int player = Coop_view_player[w];
888 RenderingType=255; // don't handle coop stuff
890 if (player!=-1 && Players[player].connected && ((Game_mode & GM_MULTI_COOP) || ((Game_mode & GM_TEAM) && (get_team(player) == get_team(Player_num)))))
891 do_cockpit_window_view(w,&Objects[Players[Coop_view_player[w]].objnum],0,WBU_COOP,Players[Coop_view_player[w]].callsign);
893 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
894 Cockpit_3d_view[w] = CV_NONE;
901 RenderingType=5+(w<<4);
902 if (Marker_viewer_num[w] == -1 || MarkerObject[Marker_viewer_num[w]] == -1) {
903 Cockpit_3d_view[w] = CV_NONE;
906 sprintf(label,"Marker %d",Marker_viewer_num[w]+1);
907 do_cockpit_window_view(w,&Objects[MarkerObject[Marker_viewer_num[w]]],0,WBU_MARKER,label);
911 Int3(); //invalid window type
915 Newdemo_state = save_newdemo_state;
918 int BigWindowSwitch=0;
919 extern int force_cockpit_redraw;
921 extern ubyte * Game_cockpit_copy_code;
923 extern ubyte Game_cockpit_copy_code;
926 void draw_guided_crosshair(void);
929 //render a frame for the game
931 // will render everything to dd_VR_render_sub_buffer
932 // which all leads to the dd_VR_offscreen_buffer
933 void game_render_frame_mono(void)
936 dd_grs_canvas Screen_3d_window,
937 grs_canvas Screen_3d_window
943 dd_gr_init_sub_canvas(&Screen_3d_window, &dd_VR_screen_pages[0],
944 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_x,
945 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_y,
946 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w,
947 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_h),
948 gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
949 VR_render_sub_buffer[0].cv_bitmap.bm_x,
950 VR_render_sub_buffer[0].cv_bitmap.bm_y,
951 VR_render_sub_buffer[0].cv_bitmap.bm_w,
952 VR_render_sub_buffer[0].cv_bitmap.bm_h)
955 if ( Game_double_buffer ) {
957 dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
958 gr_set_current_canvas(&VR_render_sub_buffer[0])
963 dd_gr_set_current_canvas(&Screen_3d_window),
964 gr_set_current_canvas(&Screen_3d_window)
968 if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID && Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num] && Guided_in_big_window) {
969 char *msg = "Guided Missile View";
970 object *viewer_save = Viewer;
973 if (Cockpit_mode==CM_FULL_COCKPIT)
976 force_cockpit_redraw=1;
977 Cockpit_mode=CM_STATUS_BAR;
981 Viewer = Guided_missile[Player_num];
983 WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
985 update_rendered_data(0, Viewer, 0, 0);
988 wake_up_rendered_objects(Viewer, 0);
989 Viewer = viewer_save;
991 gr_set_curfont( GAME_FONT ); //GAME_FONT );
992 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
993 gr_get_string_size(msg, &w, &h, &aw );
995 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
997 draw_guided_crosshair();
999 WIN(DDGRUNLOCK(dd_grd_curcanv));
1001 HUD_render_message_frame();
1007 if (BigWindowSwitch)
1009 force_cockpit_redraw=1;
1010 Cockpit_mode=CM_FULL_COCKPIT;
1014 WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
1015 update_rendered_data(0, Viewer, Rear_view, 0);
1017 WIN(DDGRUNLOCK(dd_grd_curcanv));
1020 if ( Game_double_buffer ) {
1022 dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
1023 gr_set_current_canvas(&VR_render_sub_buffer[0])
1028 dd_gr_set_current_canvas(&Screen_3d_window),
1029 gr_set_current_canvas(&Screen_3d_window)
1034 WIN(DDGRLOCK(dd_grd_curcanv));
1035 game_draw_hud_stuff();
1036 WIN(DDGRUNLOCK(dd_grd_curcanv));
1039 show_extra_views(); //missile view, buddy bot, etc.
1042 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
1043 extern char *Pause_msg;
1044 // LPDIRECTDRAWSURFACE save_dds = dd_VR_screen_pages[VR_current_page].lpdds;
1046 // dd_VR_screen_pages[VR_current_page].lpdds = dd_VR_render_buffer[VR_current_page].lpdds;
1047 show_boxed_message(Pause_msg);
1048 // dd_VR_screen_pages[VR_current_page].lpdds = save_dds;
1051 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
1052 extern char *Pause_msg;
1053 ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
1055 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
1056 show_boxed_message(Pause_msg);
1057 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
1061 if ( Game_double_buffer ) { //copy to visible screen
1062 if ( !Game_cockpit_copy_code ) {
1063 if ( VR_screen_flags&VRF_USE_PAGING ) {
1064 VR_current_page = !VR_current_page;
1066 dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]);
1069 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
1070 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 );
1071 gr_wait_for_retrace = 0;
1072 gr_show_canvas( &VR_screen_pages[VR_current_page] );
1073 gr_wait_for_retrace = 1;
1077 if (GRMODEINFO(emul) || GRMODEINFO(modex) || GRMODEINFO(dbuf))
1078 // From render buffer to screen buffer.
1079 dd_gr_blt_notrans(&dd_VR_render_sub_buffer[0],
1081 dd_VR_render_sub_buffer[0].canvas.cv_w,
1082 dd_VR_render_sub_buffer[0].canvas.cv_h,
1084 dd_VR_render_sub_buffer[0].xoff,
1085 dd_VR_render_sub_buffer[0].yoff,
1086 dd_VR_render_sub_buffer[0].canvas.cv_w,
1087 dd_VR_render_sub_buffer[0].canvas.cv_h);
1090 // Puts back canvas to front canvas by blt or flip
1091 if (GRMODEINFO(modex)) {
1092 //@@VR_current_page = !VR_current_page;
1097 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w,
1098 VR_render_sub_buffer[0].cv_h,
1099 VR_render_sub_buffer[0].cv_bitmap.bm_x,
1100 VR_render_sub_buffer[0].cv_bitmap.bm_y,
1102 &VR_render_sub_buffer[0].cv_bitmap,
1103 &VR_screen_pages[0].cv_bitmap );
1108 win_do_emul_ibitblt( &dd_VR_render_sub_buffer[0], dd_grd_screencanv);
1110 if (GRMODEINFO(modex)) {
1111 //@@VR_current_page = !VR_current_page;
1117 gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
1118 #else //def MACINTOSH
1119 gr_ibitblt( &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap );
1125 if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
1127 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
1128 Game_mode = Newdemo_game_mode;
1132 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
1133 Game_mode = GM_NORMAL;
1138 VR_current_page = !VR_current_page;
1151 void toggle_cockpit()
1155 switch (Cockpit_mode) {
1157 case CM_FULL_COCKPIT: {
1158 int max_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR+(Current_display_mode?(Num_cockpits/2):0)].index].bm_h;
1159 if (Game_window_h > max_h) //too big for statusbar
1160 new_mode = CM_FULL_SCREEN;
1162 new_mode = CM_STATUS_BAR;
1167 case CM_FULL_SCREEN:
1170 new_mode = CM_FULL_COCKPIT;
1176 return; //do nothing
1181 select_cockpit(new_mode);
1182 HUD_clear_messages();
1183 write_player_file();
1187 #define WINDOW_W_DELTA ((max_window_w / 16)&~1) //24 //20
1188 #define WINDOW_H_DELTA ((max_window_h / 16)&~1) //12 //10
1190 #define WINDOW_MIN_W ((max_window_w * 10) / 22) //160
1191 #define WINDOW_MIN_H ((max_window_h * 10) / 22)
1193 //#define WINDOW_W_DELTA 32
1194 //#define WINDOW_H_DELTA 16
1196 #define WINDOW_W_DELTA ((max_window_w / 16) & ~15) // double word aligned
1197 #define WINDOW_H_DELTA ((max_window_h / 16) & ~15) // double word aligned
1199 #define WINDOW_MIN_W (max_window_w-(WINDOW_W_DELTA*11))
1200 #define WINDOW_MIN_H (max_window_h-(WINDOW_H_DELTA*11))
1205 if (Cockpit_mode == CM_FULL_COCKPIT) {
1206 Game_window_h = max_window_h;
1207 Game_window_w = max_window_w;
1209 HUD_init_message("Press F3 to return to Cockpit mode");
1213 if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1216 if (Game_window_h>=max_window_h || Game_window_w>=max_window_w) {
1217 //Game_window_w = max_window_w;
1218 //Game_window_h = max_window_h;
1219 select_cockpit(CM_FULL_SCREEN);
1223 Game_window_w += WINDOW_W_DELTA;
1224 Game_window_h += WINDOW_H_DELTA;
1226 if (Game_window_h > max_window_h)
1227 Game_window_h = max_window_h;
1229 if (Game_window_w > max_window_w)
1230 Game_window_w = max_window_w;
1232 Game_window_x = (max_window_w - Game_window_w)/2;
1233 Game_window_y = (max_window_h - Game_window_h)/2;
1235 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
1238 HUD_clear_messages(); // @mk, 11/11/94
1240 write_player_file();
1243 // grs_bitmap background_bitmap; already declared in line 434 (samir 4/10/94)
1245 extern grs_bitmap background_bitmap;
1247 void copy_background_rect(int left,int top,int right,int bot)
1249 grs_bitmap *bm = &background_bitmap;
1251 int tile_left,tile_right,tile_top,tile_bot;
1255 if (right < left || bot < top)
1258 tile_left = left / bm->bm_w;
1259 tile_right = right / bm->bm_w;
1260 tile_top = top / bm->bm_h;
1261 tile_bot = bot / bm->bm_h;
1263 ofs_y = top % bm->bm_h;
1266 WIN(DDGRLOCK(dd_grd_curcanv))
1268 for (y=tile_top;y<=tile_bot;y++) {
1271 ofs_x = left % bm->bm_w;
1274 //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
1275 h = min(bot-dest_y+1,bm->bm_h-ofs_y);
1277 for (x=tile_left;x<=tile_right;x++) {
1279 //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
1280 w = min(right-dest_x+1,bm->bm_w-ofs_x);
1282 gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
1283 &background_bitmap,&grd_curcanv->cv_bitmap);
1293 WIN(DDGRUNLOCK(dd_grd_curcanv));
1298 int force_background_fill=0;
1301 //fills int the background surrounding the 3d window
1302 void fill_background()
1314 WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1315 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1317 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1318 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1319 copy_background_rect(x,y-dy,x+w-1,y-1);
1320 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1323 if (GRMODEINFO(modex)) {
1324 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1325 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1326 copy_background_rect(x,y-dy,x+w-1,y-1);
1327 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1331 if (VR_screen_flags & VRF_USE_PAGING) {
1332 WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
1333 gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
1335 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1336 copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
1337 copy_background_rect(x,y-dy,x+w-1,y-1);
1338 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1342 if (GRMODEINFO(modex) && force_background_fill==0) //double-buffered
1343 force_background_fill=2;
1347 void shrink_window()
1350 //When you shrink the window twice in two frames, the background doens't
1351 //restore properly. So this hack keeps you from shrinking the window
1352 //before two frames have been drawn
1353 static int last_shrink_framecount=-1;
1354 if (FrameCount - last_shrink_framecount < 2)
1356 last_shrink_framecount = FrameCount;
1359 mprintf((0,"%d ",FrameCount));
1361 // mprintf ((0,"W=%d H=%d\n",Game_window_w,Game_window_h));
1363 if (Cockpit_mode == CM_FULL_COCKPIT && (VR_screen_flags & VRF_ALLOW_COCKPIT)) {
1364 Game_window_h = max_window_h;
1365 Game_window_w = max_window_w;
1366 //!!toggle_cockpit();
1367 select_cockpit(CM_STATUS_BAR);
1370 HUD_init_message("Press F3 to return to Cockpit mode");
1371 write_player_file();
1375 if (Cockpit_mode == CM_FULL_SCREEN && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1377 //Game_window_w = max_window_w;
1378 //Game_window_h = max_window_h;
1379 select_cockpit(CM_STATUS_BAR);
1380 write_player_file();
1384 if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1387 mprintf ((0,"Cockpit mode=%d\n",Cockpit_mode));
1389 if (Game_window_w > WINDOW_MIN_W) {
1392 Game_window_w -= WINDOW_W_DELTA;
1393 Game_window_h -= WINDOW_H_DELTA;
1396 mprintf ((0,"NewW=%d NewH=%d VW=%d maxH=%d\n",Game_window_w,Game_window_h,max_window_w,max_window_h));
1398 if ( Game_window_w < WINDOW_MIN_W )
1399 Game_window_w = WINDOW_MIN_W;
1401 if ( Game_window_h < WINDOW_MIN_H )
1402 Game_window_h = WINDOW_MIN_H;
1404 Game_window_x = (max_window_w - Game_window_w)/2;
1405 Game_window_y = (max_window_h - Game_window_h)/2;
1409 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
1410 HUD_clear_messages();
1411 write_player_file();
1416 int last_drawn_cockpit[2] = { -1, -1 };
1418 // This actually renders the new cockpit onto the screen.
1419 void update_cockpits(int force_redraw)
1423 //Redraw the on-screen cockpit bitmaps
1424 if (VR_render_mode != VR_NONE ) return;
1426 switch( Cockpit_mode ) {
1427 case CM_FULL_COCKPIT:
1430 dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1431 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1433 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)]);
1435 WIN(DDGRLOCK(dd_grd_curcanv));
1436 gr_ubitmapm(0,0, &GameBitmaps[cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)].index]);
1437 WIN(DDGRUNLOCK(dd_grd_curcanv));
1440 case CM_FULL_SCREEN:
1441 Game_window_x = (max_window_w - Game_window_w)/2;
1442 Game_window_y = (max_window_h - Game_window_h)/2;
1448 WINDOS ( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1449 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1452 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)]);
1454 WIN(DDGRLOCK(dd_grd_curcanv));
1455 gr_ubitmapm(0,max_window_h,&GameBitmaps[cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)].index]);
1456 WIN(DDGRUNLOCK(dd_grd_curcanv));
1458 Game_window_x = (max_window_w - Game_window_w)/2;
1459 Game_window_y = (max_window_h - Game_window_h)/2;
1464 WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1465 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1467 WINDOS ( dd_gr_clear_canvas( BM_XRGB(0,0,0) ),
1468 gr_clear_canvas( BM_XRGB(0,0,0) ) );
1470 // In a modex mode, clear the other buffer.
1471 if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
1472 gr_set_current_canvas(&VR_screen_pages[VR_current_page^1]);
1473 gr_clear_canvas( BM_XRGB(0,0,0) );
1474 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1480 WINDOS ( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1481 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1484 if (Cockpit_mode != last_drawn_cockpit[VR_current_page] || force_redraw )
1485 last_drawn_cockpit[VR_current_page] = Cockpit_mode;
1489 if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
1495 void game_render_frame()
1497 set_screen_mode( SCREEN_GAME );
1502 if (force_background_fill) {
1504 force_background_fill--;
1508 play_homing_warning();
1510 if (VR_render_mode == VR_NONE )
1511 game_render_frame_mono();
1513 game_render_frame_stereo();
1516 // Make sure palette is faded in
1518 gr_palette_fade_in( gr_palette, 32, 0 );
1524 extern int Color_0_31_0;
1526 //draw a crosshair for the guided missile
1527 void draw_guided_crosshair(void)
1531 gr_setcolor(Color_0_31_0);
1533 w = grd_curcanv->cv_w>>5;
1537 h = i2f(w) / grd_curscreen->sc_aspect;
1539 x = grd_curcanv->cv_w / 2;
1540 y = grd_curcanv->cv_h / 2;
1542 gr_scanline(x-w/2,x+w/2,y);
1543 gr_uline(i2f(x),i2f(y-h/2),i2f(x),i2f(y+h/2));
1547 typedef struct bkg {
1548 short x, y, w, h; // The location of the menu.
1549 grs_bitmap * bmp; // The background under the menu.
1552 bkg bg = {0,0,0,0,NULL};
1554 #define BOX_BORDER (MenuHires?60:30)
1556 //show a message in a nice little box
1557 void show_boxed_message(char *msg)
1563 dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1564 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1566 gr_set_curfont( MEDIUM1_FONT );
1568 gr_get_string_size(msg,&w,&h,&aw);
1570 x = (grd_curscreen->sc_w-w)/2;
1571 y = (grd_curscreen->sc_h-h)/2;
1574 gr_free_bitmap(bg.bmp);
1578 // Save the background of the display
1579 bg.x=x; bg.y=y; bg.w=w; bg.h=h;
1581 bg.bmp = gr_create_bitmap( w+BOX_BORDER, h+BOX_BORDER );
1583 WIN( DDGRLOCK(dd_grd_curcanv));
1584 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 );
1585 WIN( DDGRUNLOCK(dd_grd_curcanv));
1587 nm_draw_background(x-BOX_BORDER/2,y-BOX_BORDER/2,x+w+BOX_BORDER/2-1,y+h+BOX_BORDER/2-1);
1589 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
1591 WIN( DDGRLOCK(dd_grd_curcanv));
1592 gr_ustring( 0x8000, y, msg );
1593 WIN( DDGRUNLOCK(dd_grd_curcanv));
1597 void clear_boxed_message()
1602 WIN(DDGRLOCK(dd_grd_curcanv));
1603 gr_bitmap(bg.x-BOX_BORDER/2, bg.y-BOX_BORDER/2, bg.bmp);
1604 WIN(DDGRUNLOCK(dd_grd_curcanv));
1607 gr_free_bitmap(bg.bmp);
1614 void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest)
1621 WIN(DDGRLOCK(csrc));
1622 WIN(DDGRLOCK(cdest));
1623 src_data = csrc->canvas.cv_bitmap.bm_data;
1624 dest_data = cdest->canvas.cv_bitmap.bm_data;
1626 // mprintf((0, "Render Ptr: %x; Dest Ptr: %x;\n",src_data, dest_data));
1628 for (line = 0; line < 480; line++,
1629 dest_data += cdest->canvas.cv_bitmap.bm_rowsize)
1631 cockpit_span_line *sline;
1633 sline = &win_cockpit_mask[line];
1635 if (!sline->num) continue;
1636 if (sline->num == 255) break;
1637 for (span = 0; span < sline->num; span++)
1639 if ((sline->span[span].xmax-sline->span[span].xmin+1) < 10) {
1640 gr_winckpit_blt_span(sline->span[span].xmin,
1641 sline->span[span].xmax,
1642 src_data, dest_data);
1645 gr_winckpit_blt_span_long(sline->span[span].xmin,
1646 sline->span[span].xmax,
1647 src_data, dest_data);
1650 src_data += csrc->canvas.cv_bitmap.bm_rowsize;
1652 WIN(DDGRUNLOCK(cdest));
1653 WIN(DDGRUNLOCK(csrc));
1657 //@@void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest)
1661 //@@ RECT srect, drect;
1663 //@@// Do Render Blt to Mask Surface (dest blt 1-255)
1664 //@@ bltfx.dwSize = sizeof(bltfx);
1665 //@@ bltfx.ddckDestColorkey.dwColorSpaceLowValue = 1;
1666 //@@ bltfx.ddckDestColorkey.dwColorSpaceHighValue = 255;
1667 //@@ SetRect(&srect, 0,0, csrc->canvas.cv_w, csrc->canvas.cv_h);
1668 //@@ SetRect(&drect, 0,0, csrc->canvas.cv_w, csrc->canvas.cv_h);
1670 //@@ res = IDirectDrawSurface_Blt(_lpDDSMask, &drect, csrc->lpdds, &srect,
1671 //@@ DDBLT_WAIT | DDBLT_KEYDESTOVERRIDE,
1673 //@@ if (res != DD_OK)
1674 //@@ Error("win_ibitblt: ddraw blt to mask err: %x.\n", res);
1676 //@@// Do Mask Blt to Screen (src blt !0)
1677 //@@ bltfx.dwSize = sizeof(bltfx);
1678 //@@ bltfx.ddckSrcColorkey.dwColorSpaceLowValue = 0;
1679 //@@ bltfx.ddckSrcColorkey.dwColorSpaceHighValue = 0;
1681 //@@ res = IDirectDrawSurface_Blt(cdest->lpdds, &drect, _lpDDSMask, &srect,
1682 //@@ DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE,
1684 //@@ if (res != DD_OK)
1685 //@@ Error("win_ibitblt: ddraw blt to screen err: %x.\n", res);