1 /* $Id: gamerend.c,v 1.17 2005-07-30 07:46:03 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.17 2005-07-30 07:46:03 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()
313 int odisplay_mode = Current_display_mode;
314 if (Scanline_double) {
316 Current_display_mode = 0;
321 //mprintf ((0,"Linear is %d!\n",LinearSVGABuffer));
325 gr_set_curfont( MEDIUM1_FONT );
326 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
327 gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
336 game_draw_multi_message();
339 game_draw_marker_message();
341 // if (Game_mode & GM_MULTI)
343 // if (Netgame.PlayTimeAllowed)
344 // game_draw_time_left ();
347 if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
351 if (Newdemo_state == ND_STATE_PLAYBACK) {
352 if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
353 sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
355 sprintf (message, " ");
358 sprintf (message, TXT_DEMO_RECORDING);
360 gr_set_curfont( GAME_FONT ); //GAME_FONT );
361 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
363 gr_get_string_size(message, &w, &h, &aw );
365 if (Scanline_double) // double height if scanline doubling since we have the correct
366 h += h; // font for printing, but the wrong height.
368 if (Cockpit_mode == CM_FULL_COCKPIT) {
369 if (grd_curcanv->cv_bitmap.bm_h > 240)
373 } else if ( Cockpit_mode == CM_LETTERBOX )
375 if (Cockpit_mode != CM_REAR_VIEW && !Saving_movie_frames)
376 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
379 render_countdown_gauge();
381 if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num ) {
383 int y = grd_curcanv->cv_bitmap.bm_h;
385 gr_set_curfont( GAME_FONT );
386 gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
387 if (Cruise_speed > 0) {
388 int line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
390 mprintf((0,"line_spacing=%d ",line_spacing));
392 if (Cockpit_mode==CM_FULL_SCREEN) {
393 if (Game_mode & GM_MULTI)
394 y -= line_spacing * 11; //64
396 y -= line_spacing * 6; //32
397 } else if (Cockpit_mode == CM_STATUS_BAR) {
398 if (Game_mode & GM_MULTI)
399 y -= line_spacing * 8; //48
401 y -= line_spacing * 4; //24
403 y = line_spacing * 2; //12
407 gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
411 if (r_framerate.value)
414 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
415 Game_mode = Newdemo_game_mode;
419 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
420 Game_mode = GM_NORMAL;
422 if ( Player_is_dead )
423 player_dead_message();
426 if (Scanline_double) {
428 Current_display_mode = odisplay_mode;
433 extern int gr_bitblt_dest_step_shift;
434 extern int gr_wait_for_retrace;
435 extern int gr_bitblt_double;
438 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels );
439 #pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \
457 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels )
461 for (i = 0; i < num_src_pixels; i++) {
468 // doubles the size in x or y of a bitmap in place.
469 void game_expand_bitmap( grs_bitmap * bmp, uint flags )
472 ubyte * dptr, * sptr;
476 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
477 dptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
478 for (i=bmp->bm_h-1; i>=0; i-- ) {
479 expand_row( dptr, dptr, bmp->bm_w );
480 dptr -= bmp->bm_rowsize;
485 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
486 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
487 for (i=bmp->bm_h-1; i>=0; i-- ) {
488 memcpy( dptr, sptr, bmp->bm_w );
489 dptr -= bmp->bm_rowsize;
490 memcpy( dptr, sptr, bmp->bm_w );
491 dptr -= bmp->bm_rowsize;
492 sptr -= bmp->bm_rowsize;
496 case 3: // expand x & y
497 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
498 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
499 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
500 for (i=bmp->bm_h-1; i>=0; i-- ) {
501 expand_row( dptr, sptr, bmp->bm_w );
502 dptr -= bmp->bm_rowsize;
503 expand_row( dptr, sptr, bmp->bm_w );
504 dptr -= bmp->bm_rowsize;
505 sptr -= bmp->bm_rowsize;
513 extern int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
515 extern int Guided_in_big_window;
518 //render a frame for the game in stereo
519 void game_render_frame_stereo()
523 fix actual_eye_width;
524 int actual_eye_offset;
525 grs_canvas RenderCanvas[2];
528 save_aspect = grd_curscreen->sc_aspect;
529 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
531 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
532 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
534 if (VR_low_res & 1) {
536 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
538 if (VR_low_res & 2) {
540 grd_curscreen->sc_aspect /= 2; //Muck with aspect ratio
543 gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
544 gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
546 // Draw the left eye's view
548 actual_eye_width = -VR_eye_width;
549 actual_eye_offset = -VR_eye_offset;
551 actual_eye_width = VR_eye_width;
552 actual_eye_offset = VR_eye_offset;
555 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)
556 actual_eye_offset = 0;
558 gr_set_current_canvas(&RenderCanvas[0]);
560 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) {
561 char *msg = "Guided Missile View";
562 object *viewer_save = Viewer;
565 Viewer = Guided_missile[Player_num];
567 WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
573 update_rendered_data(0, Viewer, 0, 0);
576 wake_up_rendered_objects(Viewer, 0);
577 Viewer = viewer_save;
579 gr_set_curfont( GAME_FONT ); //GAME_FONT );
580 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
581 gr_get_string_size(msg, &w, &h, &aw );
583 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
585 draw_guided_crosshair();
587 WIN(DDGRUNLOCK(dd_grd_curcanv));
589 HUD_render_message_frame();
598 render_frame(actual_eye_width, 0); // switch eye positions for rear view
600 render_frame(-actual_eye_width, 0); // Left eye
603 game_expand_bitmap( &RenderCanvas[0].cv_bitmap, VR_low_res );
605 { //render small window into left eye's canvas
606 grs_canvas *save=grd_curcanv;
607 fix save_aspect2 = grd_curscreen->sc_aspect;
608 grd_curscreen->sc_aspect = save_aspect*2;
609 SW_drawn[0] = SW_drawn[1] = 0;
611 gr_set_current_canvas(save);
612 grd_curscreen->sc_aspect = save_aspect2;
616 if (actual_eye_offset > 0 ) {
617 gr_setcolor( gr_getcolor(0,0,0) );
618 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
619 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
620 } else if (actual_eye_offset < 0 ) {
621 gr_setcolor( gr_getcolor(0,0,0) );
622 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
625 if ( VR_show_hud && !no_draw_hud ) {
627 if (actual_eye_offset < 0 ) {
628 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 );
630 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 );
632 gr_set_current_canvas( &tmp );
633 game_draw_hud_stuff();
637 // Draw the right eye's view
638 gr_set_current_canvas(&RenderCanvas[1]);
640 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)
641 gr_bitmap(0,0,&RenderCanvas[0].cv_bitmap);
644 render_frame(-actual_eye_width, 0); // switch eye positions for rear view
646 render_frame(actual_eye_width, 0); // Right eye
649 game_expand_bitmap( &RenderCanvas[1].cv_bitmap, VR_low_res );
653 { //copy small window from left eye
658 gr_init_sub_canvas(&temp,&RenderCanvas[0],SW_x[w],SW_y[w],SW_w[w],SW_h[w]);
659 gr_bitmap(SW_x[w]+actual_eye_offset*2,SW_y[w],&temp.cv_bitmap);
665 if (actual_eye_offset>0) {
666 gr_setcolor( gr_getcolor(0,0,0) );
667 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
668 } else if ( actual_eye_offset < 0 ) {
669 gr_setcolor( gr_getcolor(0,0,0) );
670 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
671 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
674 //NEWVR (Add the next 2 lines)
675 if ( VR_show_hud && !no_draw_hud ) {
677 if (actual_eye_offset > 0 ) {
678 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 );
680 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 );
682 gr_set_current_canvas( &tmp );
683 game_draw_hud_stuff();
687 // Draws white and black registration encoding lines
688 // and Accounts for pixel-shift adjustment in upcoming bitblts
689 if (VR_use_reg_code) {
690 int width, height, quarter;
692 width = RenderCanvas[0].cv_bitmap.bm_w;
693 height = RenderCanvas[0].cv_bitmap.bm_h;
696 // black out left-hand side of left page
698 // draw registration code for left eye
700 gr_set_current_canvas( &RenderCanvas[1] );
702 gr_set_current_canvas( &RenderCanvas[0] );
703 gr_setcolor( VR_WHITE_INDEX );
704 gr_scanline( 0, quarter, height-1 );
705 gr_setcolor( VR_BLACK_INDEX );
706 gr_scanline( quarter, width-1, height-1 );
709 gr_set_current_canvas( &RenderCanvas[0] );
711 gr_set_current_canvas( &RenderCanvas[1] );
712 gr_setcolor( VR_WHITE_INDEX );
713 gr_scanline( 0, quarter*3, height-1 );
714 gr_setcolor( VR_BLACK_INDEX );
715 gr_scanline( quarter*3, width-1, height-1 );
718 // Copy left eye, then right eye
719 if ( VR_screen_flags&VRF_USE_PAGING )
720 VR_current_page = !VR_current_page;
723 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
727 if ( VR_eye_offset_changed > 0 ) {
728 VR_eye_offset_changed--;
732 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
733 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
735 // Copy left eye, then right eye
736 gr_bitblt_dest_step_shift = 1; // Skip every other scanline.
738 if (VR_render_mode == VR_INTERLACED ) {
739 if ( actual_eye_offset > 0 ) {
740 int xoff = labs(actual_eye_offset);
741 gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
742 gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
743 } else if ( actual_eye_offset < 0 ) {
744 int xoff = labs(actual_eye_offset);
745 gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
746 gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
748 gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
749 gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
751 } else if (VR_render_mode == VR_AREA_DET) {
753 gr_bm_ubitblt( dw, dh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
754 gr_bm_ubitblt( dw, dh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
759 gr_bitblt_dest_step_shift = 0;
761 //if ( Game_vfx_flag )
762 // vfx_set_page(VR_current_page); // 0 or 1
764 if ( VR_screen_flags&VRF_USE_PAGING ) {
765 gr_wait_for_retrace = 0;
767 // Added by Samir from John's code
768 if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) ) {
769 int old_x, old_y, new_x;
770 old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
771 old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
772 new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
774 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
775 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
776 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
777 gr_show_canvas( &VR_screen_pages[VR_current_page] );
778 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
779 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
780 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
782 gr_show_canvas( &VR_screen_pages[VR_current_page] );
784 gr_wait_for_retrace = 1;
786 grd_curscreen->sc_aspect=save_aspect;
789 ubyte RenderingType=0;
790 ubyte DemoDoingRight=0,DemoDoingLeft=0;
791 extern ubyte DemoDoRight,DemoDoLeft;
792 extern object DemoRightExtra,DemoLeftExtra;
794 char DemoWBUType[]={0,WBU_MISSILE,WBU_MISSILE,WBU_REAR,WBU_ESCORT,WBU_MARKER,WBU_MISSILE};
795 char DemoRearCheck[]={0,0,0,1,0,0,0};
796 char *DemoExtraMessage[]={"PLAYER","GUIDED","MISSILE","REAR","GUIDE-BOT","MARKER","SHIP"};
798 extern char guidebot_name[];
800 void show_extra_views()
802 int did_missile_view=0;
803 int save_newdemo_state = Newdemo_state;
806 if (Newdemo_state==ND_STATE_PLAYBACK)
810 DemoDoingLeft=DemoDoLeft;
813 do_cockpit_window_view(0,ConsoleObject,1,WBU_REAR,"REAR");
815 do_cockpit_window_view(0,&DemoLeftExtra,DemoRearCheck[DemoDoLeft],DemoWBUType[DemoDoLeft],DemoExtraMessage[DemoDoLeft]);
818 do_cockpit_window_view(0,NULL,0,WBU_WEAPON,NULL);
822 DemoDoingRight=DemoDoRight;
825 do_cockpit_window_view(1,ConsoleObject,1,WBU_REAR,"REAR");
827 do_cockpit_window_view(1,&DemoRightExtra,DemoRearCheck[DemoDoRight],DemoWBUType[DemoDoRight],DemoExtraMessage[DemoDoRight]);
830 do_cockpit_window_view(1,NULL,0,WBU_WEAPON,NULL);
832 DemoDoLeft=DemoDoRight=0;
833 DemoDoingLeft=DemoDoingRight=0;
838 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]) {
839 if (Guided_in_big_window)
841 RenderingType=6+(1<<4);
842 do_cockpit_window_view(1,Viewer,0,WBU_MISSILE,"SHIP");
846 RenderingType=1+(1<<4);
847 do_cockpit_window_view(1,Guided_missile[Player_num],0,WBU_GUIDED,"GUIDED");
854 if (Guided_missile[Player_num]) { //used to be active
855 if (!Guided_in_big_window)
856 do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
857 Guided_missile[Player_num] = NULL;
860 if (Missile_viewer) { //do missile view
861 static int mv_sig=-1;
863 mv_sig = Missile_viewer->signature;
864 if (Missile_view_enabled && Missile_viewer->type!=OBJ_NONE && Missile_viewer->signature == mv_sig) {
865 RenderingType=2+(1<<4);
866 do_cockpit_window_view(1,Missile_viewer,0,WBU_MISSILE,"MISSILE");
870 Missile_viewer = NULL;
873 do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
880 if (w==1 && did_missile_view)
881 continue; //if showing missile view in right window, can't show anything else
883 //show special views if selected
884 switch (Cockpit_3d_view[w]) {
887 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
890 if (Rear_view) { //if big window is rear view, show front here
891 RenderingType=3+(w<<4);
892 do_cockpit_window_view(w,ConsoleObject,0,WBU_REAR,"FRONT");
894 else { //show normal rear view
895 RenderingType=3+(w<<4);
896 do_cockpit_window_view(w,ConsoleObject,1,WBU_REAR,"REAR");
901 buddy = find_escort();
903 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
904 Cockpit_3d_view[w] = CV_NONE;
907 RenderingType=4+(w<<4);
908 do_cockpit_window_view(w,buddy,0,WBU_ESCORT,guidebot_name);
914 int player = Coop_view_player[w];
916 RenderingType=255; // don't handle coop stuff
918 if (player!=-1 && Players[player].connected && ((Game_mode & GM_MULTI_COOP) || ((Game_mode & GM_TEAM) && (get_team(player) == get_team(Player_num)))))
919 do_cockpit_window_view(w,&Objects[Players[Coop_view_player[w]].objnum],0,WBU_COOP,Players[Coop_view_player[w]].callsign);
921 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
922 Cockpit_3d_view[w] = CV_NONE;
929 RenderingType=5+(w<<4);
930 if (Marker_viewer_num[w] == -1 || MarkerObject[Marker_viewer_num[w]] == -1) {
931 Cockpit_3d_view[w] = CV_NONE;
934 sprintf(label,"Marker %d",Marker_viewer_num[w]+1);
935 do_cockpit_window_view(w,&Objects[MarkerObject[Marker_viewer_num[w]]],0,WBU_MARKER,label);
939 Int3(); //invalid window type
943 Newdemo_state = save_newdemo_state;
946 int BigWindowSwitch=0;
947 extern int force_cockpit_redraw;
949 extern ubyte * Game_cockpit_copy_code;
951 extern ubyte Game_cockpit_copy_code;
954 void draw_guided_crosshair(void);
957 //render a frame for the game
959 // will render everything to dd_VR_render_sub_buffer
960 // which all leads to the dd_VR_offscreen_buffer
961 void game_render_frame_mono(void)
964 dd_grs_canvas Screen_3d_window,
965 grs_canvas Screen_3d_window
971 dd_gr_init_sub_canvas(&Screen_3d_window, &dd_VR_screen_pages[0],
972 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_x,
973 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_y,
974 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w,
975 dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_h),
976 gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
977 VR_render_sub_buffer[0].cv_bitmap.bm_x,
978 VR_render_sub_buffer[0].cv_bitmap.bm_y,
979 VR_render_sub_buffer[0].cv_bitmap.bm_w,
980 VR_render_sub_buffer[0].cv_bitmap.bm_h)
983 if ( Game_double_buffer ) {
985 dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
986 gr_set_current_canvas(&VR_render_sub_buffer[0])
991 dd_gr_set_current_canvas(&Screen_3d_window),
992 gr_set_current_canvas(&Screen_3d_window)
996 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) {
997 char *msg = "Guided Missile View";
998 object *viewer_save = Viewer;
1001 if (Cockpit_mode==CM_FULL_COCKPIT)
1004 force_cockpit_redraw=1;
1005 Cockpit_mode=CM_STATUS_BAR;
1009 Viewer = Guided_missile[Player_num];
1011 WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
1014 if (Scanline_double)
1017 update_rendered_data(0, Viewer, 0, 0);
1020 wake_up_rendered_objects(Viewer, 0);
1021 Viewer = viewer_save;
1023 gr_set_curfont( GAME_FONT ); //GAME_FONT );
1024 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
1025 gr_get_string_size(msg, &w, &h, &aw );
1027 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
1029 draw_guided_crosshair();
1031 WIN(DDGRUNLOCK(dd_grd_curcanv));
1033 HUD_render_message_frame();
1035 if (Scanline_double)
1043 if (BigWindowSwitch)
1045 force_cockpit_redraw=1;
1046 Cockpit_mode=CM_FULL_COCKPIT;
1050 WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
1051 update_rendered_data(0, Viewer, Rear_view, 0);
1053 WIN(DDGRUNLOCK(dd_grd_curcanv));
1056 if ( Game_double_buffer ) {
1058 dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
1059 gr_set_current_canvas(&VR_render_sub_buffer[0])
1064 dd_gr_set_current_canvas(&Screen_3d_window),
1065 gr_set_current_canvas(&Screen_3d_window)
1070 WIN(DDGRLOCK(dd_grd_curcanv));
1071 game_draw_hud_stuff();
1072 WIN(DDGRUNLOCK(dd_grd_curcanv));
1075 show_extra_views(); //missile view, buddy bot, etc.
1078 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
1079 extern char *Pause_msg;
1080 // LPDIRECTDRAWSURFACE save_dds = dd_VR_screen_pages[VR_current_page].lpdds;
1082 // dd_VR_screen_pages[VR_current_page].lpdds = dd_VR_render_buffer[VR_current_page].lpdds;
1083 show_boxed_message(Pause_msg);
1084 // dd_VR_screen_pages[VR_current_page].lpdds = save_dds;
1087 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
1088 extern char *Pause_msg;
1089 ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
1091 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
1092 show_boxed_message(Pause_msg);
1093 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
1097 if ( Game_double_buffer ) { //copy to visible screen
1098 if ( !Game_cockpit_copy_code ) {
1099 if ( VR_screen_flags&VRF_USE_PAGING ) {
1100 VR_current_page = !VR_current_page;
1102 dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]);
1105 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
1106 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 );
1107 gr_wait_for_retrace = 0;
1108 gr_show_canvas( &VR_screen_pages[VR_current_page] );
1109 gr_wait_for_retrace = 1;
1113 if (Scanline_double)
1114 gr_bm_ubitblt_double( 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[0].cv_bitmap );
1116 #endif // NOTE LINK TO ABOVE IF
1118 if (GRMODEINFO(emul) || GRMODEINFO(modex) || GRMODEINFO(dbuf))
1119 // From render buffer to screen buffer.
1120 dd_gr_blt_notrans(&dd_VR_render_sub_buffer[0],
1122 dd_VR_render_sub_buffer[0].canvas.cv_w,
1123 dd_VR_render_sub_buffer[0].canvas.cv_h,
1125 dd_VR_render_sub_buffer[0].xoff,
1126 dd_VR_render_sub_buffer[0].yoff,
1127 dd_VR_render_sub_buffer[0].canvas.cv_w,
1128 dd_VR_render_sub_buffer[0].canvas.cv_h);
1131 // Puts back canvas to front canvas by blt or flip
1132 if (GRMODEINFO(modex)) {
1133 //@@VR_current_page = !VR_current_page;
1138 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w,
1139 VR_render_sub_buffer[0].cv_h,
1140 VR_render_sub_buffer[0].cv_bitmap.bm_x,
1141 VR_render_sub_buffer[0].cv_bitmap.bm_y,
1143 &VR_render_sub_buffer[0].cv_bitmap,
1144 &VR_screen_pages[0].cv_bitmap );
1148 #if 1 //def MACINTOSH
1149 gr_ibitblt( &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Scanline_double );
1152 gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
1154 win_do_emul_ibitblt( &dd_VR_render_sub_buffer[0], dd_grd_screencanv);
1156 if (GRMODEINFO(modex)) {
1157 //@@VR_current_page = !VR_current_page;
1166 if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
1168 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
1169 Game_mode = Newdemo_game_mode;
1173 if ( (Newdemo_state == ND_STATE_PLAYBACK) )
1174 Game_mode = GM_NORMAL;
1179 VR_current_page = !VR_current_page;
1192 void toggle_cockpit()
1196 switch (Cockpit_mode) {
1198 case CM_FULL_COCKPIT: {
1199 int max_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR+(Current_display_mode?(Num_cockpits/2):0)].index].bm_h;
1200 if (Game_window_h > max_h) //too big for statusbar
1201 new_mode = CM_FULL_SCREEN;
1203 new_mode = CM_STATUS_BAR;
1208 case CM_FULL_SCREEN:
1211 new_mode = CM_FULL_COCKPIT;
1217 return; //do nothing
1222 select_cockpit(new_mode);
1223 HUD_clear_messages();
1224 write_player_file();
1228 #define WINDOW_W_DELTA ((max_window_w / 16)&~1) //24 //20
1229 #define WINDOW_H_DELTA ((max_window_h / 16)&~1) //12 //10
1231 #define WINDOW_MIN_W ((max_window_w * 10) / 22) //160
1232 #define WINDOW_MIN_H ((max_window_h * 10) / 22)
1234 //#define WINDOW_W_DELTA 32
1235 //#define WINDOW_H_DELTA 16
1237 #define WINDOW_W_DELTA ((max_window_w / 16) & ~15) // double word aligned
1238 #define WINDOW_H_DELTA ((max_window_h / 16) & ~15) // double word aligned
1240 #define WINDOW_MIN_W (max_window_w-(WINDOW_W_DELTA*11))
1241 #define WINDOW_MIN_H (max_window_h-(WINDOW_H_DELTA*11))
1246 if (Cockpit_mode == CM_FULL_COCKPIT) {
1247 Game_window_h = max_window_h;
1248 Game_window_w = max_window_w;
1250 HUD_init_message("Press F3 to return to Cockpit mode");
1254 if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1257 if (Game_window_h>=max_window_h || Game_window_w>=max_window_w) {
1258 //Game_window_w = max_window_w;
1259 //Game_window_h = max_window_h;
1260 select_cockpit(CM_FULL_SCREEN);
1264 Game_window_w += WINDOW_W_DELTA;
1265 Game_window_h += WINDOW_H_DELTA;
1267 #ifdef MACINTOSH // horrible hack to ensure that height is even to satisfy pixel doubling blitter
1268 if ( Scanline_double && (Game_window_h & 1) )
1272 if (Game_window_h > max_window_h)
1273 Game_window_h = max_window_h;
1275 if (Game_window_w > max_window_w)
1276 Game_window_w = max_window_w;
1278 Game_window_x = (max_window_w - Game_window_w)/2;
1279 Game_window_y = (max_window_h - Game_window_h)/2;
1281 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
1284 HUD_clear_messages(); // @mk, 11/11/94
1286 write_player_file();
1289 // grs_bitmap background_bitmap; already declared in line 434 (samir 4/10/94)
1291 extern grs_bitmap background_bitmap;
1293 void copy_background_rect(int left,int top,int right,int bot)
1295 grs_bitmap *bm = &background_bitmap;
1297 int tile_left,tile_right,tile_top,tile_bot;
1301 if (right < left || bot < top)
1304 tile_left = left / bm->bm_w;
1305 tile_right = right / bm->bm_w;
1306 tile_top = top / bm->bm_h;
1307 tile_bot = bot / bm->bm_h;
1309 ofs_y = top % bm->bm_h;
1312 WIN(DDGRLOCK(dd_grd_curcanv))
1314 for (y=tile_top;y<=tile_bot;y++) {
1317 ofs_x = left % bm->bm_w;
1320 //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
1321 h = min(bot-dest_y+1,bm->bm_h-ofs_y);
1323 for (x=tile_left;x<=tile_right;x++) {
1325 //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
1326 w = min(right-dest_x+1,bm->bm_w-ofs_x);
1328 gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
1329 &background_bitmap,&grd_curcanv->cv_bitmap);
1339 WIN(DDGRUNLOCK(dd_grd_curcanv));
1344 int force_background_fill=0;
1347 //fills int the background surrounding the 3d window
1348 void fill_background()
1360 WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1361 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1363 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1364 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1365 copy_background_rect(x,y-dy,x+w-1,y-1);
1366 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1369 if (GRMODEINFO(modex)) {
1370 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1371 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1372 copy_background_rect(x,y-dy,x+w-1,y-1);
1373 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1377 if (VR_screen_flags & VRF_USE_PAGING) {
1378 WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
1379 gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
1381 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1382 copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
1383 copy_background_rect(x,y-dy,x+w-1,y-1);
1384 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1388 if (GRMODEINFO(modex) && force_background_fill==0) //double-buffered
1389 force_background_fill=2;
1393 void shrink_window()
1396 //When you shrink the window twice in two frames, the background doens't
1397 //restore properly. So this hack keeps you from shrinking the window
1398 //before two frames have been drawn
1399 static int last_shrink_framecount=-1;
1400 if (FrameCount - last_shrink_framecount < 2)
1402 last_shrink_framecount = FrameCount;
1405 mprintf((0,"%d ",FrameCount));
1407 // mprintf ((0,"W=%d H=%d\n",Game_window_w,Game_window_h));
1409 if (Cockpit_mode == CM_FULL_COCKPIT && (VR_screen_flags & VRF_ALLOW_COCKPIT)) {
1410 Game_window_h = max_window_h;
1411 Game_window_w = max_window_w;
1412 //!!toggle_cockpit();
1413 select_cockpit(CM_STATUS_BAR);
1416 HUD_init_message("Press F3 to return to Cockpit mode");
1417 write_player_file();
1421 if (Cockpit_mode == CM_FULL_SCREEN && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1423 //Game_window_w = max_window_w;
1424 //Game_window_h = max_window_h;
1425 select_cockpit(CM_STATUS_BAR);
1426 write_player_file();
1430 if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1433 mprintf ((0,"Cockpit mode=%d\n",Cockpit_mode));
1435 if (Game_window_w > WINDOW_MIN_W) {
1438 Game_window_w -= WINDOW_W_DELTA;
1439 Game_window_h -= WINDOW_H_DELTA;
1442 mprintf ((0,"NewW=%d NewH=%d VW=%d maxH=%d\n",Game_window_w,Game_window_h,max_window_w,max_window_h));
1444 if ( Game_window_w < WINDOW_MIN_W )
1445 Game_window_w = WINDOW_MIN_W;
1447 if ( Game_window_h < WINDOW_MIN_H )
1448 Game_window_h = WINDOW_MIN_H;
1450 #ifdef MACINTOSH // horrible hack to ensure that height is even to satisfy pixel doubling blitter
1451 if ( Scanline_double && (Game_window_h & 1) )
1455 Game_window_x = (max_window_w - Game_window_w)/2;
1456 Game_window_y = (max_window_h - Game_window_h)/2;
1460 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
1461 HUD_clear_messages();
1462 write_player_file();
1467 int last_drawn_cockpit[2] = { -1, -1 };
1469 // This actually renders the new cockpit onto the screen.
1470 void update_cockpits(int force_redraw)
1474 //Redraw the on-screen cockpit bitmaps
1475 if (VR_render_mode != VR_NONE ) return;
1477 switch( Cockpit_mode ) {
1478 case CM_FULL_COCKPIT:
1481 dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1482 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1484 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)]);
1486 WIN(DDGRLOCK(dd_grd_curcanv));
1487 gr_ubitmapm(0,0, &GameBitmaps[cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)].index]);
1488 WIN(DDGRUNLOCK(dd_grd_curcanv));
1491 case CM_FULL_SCREEN:
1492 Game_window_x = (max_window_w - Game_window_w)/2;
1493 Game_window_y = (max_window_h - Game_window_h)/2;
1499 WINDOS ( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1500 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1503 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)]);
1505 WIN(DDGRLOCK(dd_grd_curcanv));
1506 gr_ubitmapm(0,max_window_h,&GameBitmaps[cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)].index]);
1507 WIN(DDGRUNLOCK(dd_grd_curcanv));
1509 #ifdef MACINTOSH // hideously horrible hack to put grey line 1 scanline above because of pixel doubling "oddness"
1510 if (Scanline_double)
1512 gr_setcolor(BM_XRGB(13,13,13)); // color of top of status bar
1513 gr_uscanline( 0, grd_curcanv->cv_w, max_window_h-1 );
1517 Game_window_x = (max_window_w - Game_window_w)/2;
1518 Game_window_y = (max_window_h - Game_window_h)/2;
1523 WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1524 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1526 WINDOS ( dd_gr_clear_canvas( BM_XRGB(0,0,0) ),
1527 gr_clear_canvas( BM_XRGB(0,0,0) ) );
1529 // In a modex mode, clear the other buffer.
1530 if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
1531 gr_set_current_canvas(&VR_screen_pages[VR_current_page^1]);
1532 gr_clear_canvas( BM_XRGB(0,0,0) );
1533 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1539 WINDOS ( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1540 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1543 if (Cockpit_mode != last_drawn_cockpit[VR_current_page] || force_redraw )
1544 last_drawn_cockpit[VR_current_page] = Cockpit_mode;
1548 if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
1554 void game_render_frame()
1556 set_screen_mode( SCREEN_GAME );
1561 if (force_background_fill) {
1563 force_background_fill--;
1567 play_homing_warning();
1569 if (VR_render_mode == VR_NONE )
1570 game_render_frame_mono();
1572 game_render_frame_stereo();
1575 // Make sure palette is faded in
1577 gr_palette_fade_in( gr_palette, 32, 0 );
1583 extern int Color_0_31_0;
1585 //draw a crosshair for the guided missile
1586 void draw_guided_crosshair(void)
1590 gr_setcolor(Color_0_31_0);
1592 w = grd_curcanv->cv_w>>5;
1596 h = i2f(w) / grd_curscreen->sc_aspect;
1598 x = grd_curcanv->cv_w / 2;
1599 y = grd_curcanv->cv_h / 2;
1601 gr_scanline(x-w/2,x+w/2,y);
1602 gr_uline(i2f(x),i2f(y-h/2),i2f(x),i2f(y+h/2));
1606 typedef struct bkg {
1607 short x, y, w, h; // The location of the menu.
1608 grs_bitmap * bmp; // The background under the menu.
1611 bkg bg = {0,0,0,0,NULL};
1613 #define BOX_BORDER (MenuHires?60:30)
1615 //show a message in a nice little box
1616 void show_boxed_message(char *msg)
1622 dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
1623 gr_set_current_canvas(&VR_screen_pages[VR_current_page])
1625 gr_set_curfont( MEDIUM1_FONT );
1627 gr_get_string_size(msg,&w,&h,&aw);
1629 x = (grd_curscreen->sc_w-w)/2;
1630 y = (grd_curscreen->sc_h-h)/2;
1633 gr_free_bitmap(bg.bmp);
1637 // Save the background of the display
1638 bg.x=x; bg.y=y; bg.w=w; bg.h=h;
1640 bg.bmp = gr_create_bitmap( w+BOX_BORDER, h+BOX_BORDER );
1642 WIN( DDGRLOCK(dd_grd_curcanv));
1643 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 );
1644 WIN( DDGRUNLOCK(dd_grd_curcanv));
1646 nm_draw_background(x-BOX_BORDER/2,y-BOX_BORDER/2,x+w+BOX_BORDER/2-1,y+h+BOX_BORDER/2-1);
1648 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
1650 WIN( DDGRLOCK(dd_grd_curcanv));
1651 gr_ustring( 0x8000, y, msg );
1652 WIN( DDGRUNLOCK(dd_grd_curcanv));
1656 void clear_boxed_message()
1661 WIN(DDGRLOCK(dd_grd_curcanv));
1662 gr_bitmap(bg.x-BOX_BORDER/2, bg.y-BOX_BORDER/2, bg.bmp);
1663 WIN(DDGRUNLOCK(dd_grd_curcanv));
1666 gr_free_bitmap(bg.bmp);
1673 void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest)
1680 WIN(DDGRLOCK(csrc));
1681 WIN(DDGRLOCK(cdest));
1682 src_data = csrc->canvas.cv_bitmap.bm_data;
1683 dest_data = cdest->canvas.cv_bitmap.bm_data;
1685 // mprintf((0, "Render Ptr: %x; Dest Ptr: %x;\n",src_data, dest_data));
1687 for (line = 0; line < 480; line++,
1688 dest_data += cdest->canvas.cv_bitmap.bm_rowsize)
1690 cockpit_span_line *sline;
1692 sline = &win_cockpit_mask[line];
1694 if (!sline->num) continue;
1695 if (sline->num == 255) break;
1696 for (span = 0; span < sline->num; span++)
1698 if ((sline->span[span].xmax-sline->span[span].xmin+1) < 10) {
1699 gr_winckpit_blt_span(sline->span[span].xmin,
1700 sline->span[span].xmax,
1701 src_data, dest_data);
1704 gr_winckpit_blt_span_long(sline->span[span].xmin,
1705 sline->span[span].xmax,
1706 src_data, dest_data);
1709 src_data += csrc->canvas.cv_bitmap.bm_rowsize;
1711 WIN(DDGRUNLOCK(cdest));
1712 WIN(DDGRUNLOCK(csrc));
1716 //@@void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest)
1720 //@@ RECT srect, drect;
1722 //@@// Do Render Blt to Mask Surface (dest blt 1-255)
1723 //@@ bltfx.dwSize = sizeof(bltfx);
1724 //@@ bltfx.ddckDestColorkey.dwColorSpaceLowValue = 1;
1725 //@@ bltfx.ddckDestColorkey.dwColorSpaceHighValue = 255;
1726 //@@ SetRect(&srect, 0,0, csrc->canvas.cv_w, csrc->canvas.cv_h);
1727 //@@ SetRect(&drect, 0,0, csrc->canvas.cv_w, csrc->canvas.cv_h);
1729 //@@ res = IDirectDrawSurface_Blt(_lpDDSMask, &drect, csrc->lpdds, &srect,
1730 //@@ DDBLT_WAIT | DDBLT_KEYDESTOVERRIDE,
1732 //@@ if (res != DD_OK)
1733 //@@ Error("win_ibitblt: ddraw blt to mask err: %x.\n", res);
1735 //@@// Do Mask Blt to Screen (src blt !0)
1736 //@@ bltfx.dwSize = sizeof(bltfx);
1737 //@@ bltfx.ddckSrcColorkey.dwColorSpaceLowValue = 0;
1738 //@@ bltfx.ddckSrcColorkey.dwColorSpaceHighValue = 0;
1740 //@@ res = IDirectDrawSurface_Blt(cdest->lpdds, &drect, _lpDDSMask, &srect,
1741 //@@ DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE,
1743 //@@ if (res != DD_OK)
1744 //@@ Error("win_ibitblt: ddraw blt to screen err: %x.\n", res);