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
63 extern fix Cruise_speed;
64 extern int LinearSVGABuffer;
65 extern cvar_t r_framerate;
69 extern int Debug_pause; //John's debugging pause system
73 extern int Saving_movie_frames;
75 #define Saving_movie_frames 0
78 // Returns the length of the first 'n' characters of a string.
79 int string_width( char * s, int n )
85 gr_get_string_size( s, &w, &h, &aw );
90 // Draw string 's' centered on a canvas... if wider than
91 // canvas, then wrap it.
92 void draw_centered_text( int y, char * s )
99 if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w ) {
100 gr_string( 0x8000, y, s );
104 for (i=0; i<l; i++ ) {
105 if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) ) {
108 gr_string( 0x8000, y, s );
110 gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
116 extern ubyte DefiningMarkerMessage;
117 extern char Marker_input[];
119 #define MAX_MARKER_MESSAGE_LEN 120
120 void game_draw_marker_message()
122 char temp_string[MAX_MARKER_MESSAGE_LEN+25];
124 if ( DefiningMarkerMessage)
126 gr_set_curfont( GAME_FONT ); //GAME_FONT
127 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
128 sprintf( temp_string, "Marker: %s_", Marker_input );
129 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
135 void game_draw_multi_message()
137 char temp_string[MAX_MULTI_MESSAGE_LEN+25];
139 if ( (Game_mode&GM_MULTI) && (multi_sending_message)) {
140 gr_set_curfont( GAME_FONT ); //GAME_FONT );
141 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
142 sprintf( temp_string, "%s: %s_", TXT_MESSAGE, Network_message );
143 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
147 if ( (Game_mode&GM_MULTI) && (multi_defining_message)) {
148 gr_set_curfont( GAME_FONT ); //GAME_FONT );
149 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
150 sprintf( temp_string, "%s #%d: %s_", TXT_MACRO, multi_defining_message, Network_message );
151 draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
156 //these should be in gr.h
157 #define cv_w cv_bitmap.bm_w
158 #define cv_h cv_bitmap.bm_h
160 fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
161 fix frame_time_total=0;
162 int frame_time_cntr=0;
164 void ftoa(char *string, fix f)
166 int decimal, fractional;
169 fractional = ((f & 0xffff)*100)/65536;
172 if (fractional > 99 ) fractional = 99;
173 sprintf( string, "%d.%02d", decimal, fractional );
176 void show_framerate()
182 int x = 8, y = 5; // position measured from lower right corner
184 frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
185 frame_time_list[frame_time_cntr] = RealFrameTime;
186 frame_time_cntr = (frame_time_cntr+1)%8;
188 rate = fixdiv(f1_0*8,frame_time_total);
190 gr_set_curfont( GAME_FONT );
191 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
193 ftoa( temp, rate ); // Convert fixed to string
194 if (Game_mode & GM_MULTI)
196 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 );
197 // if ( !( q++ % 30 ) )
198 // mprintf( (0,"fps: %s\n", temp ) );
203 fix Show_view_text_timer = -1;
205 void draw_window_label()
207 if ( Show_view_text_timer > 0 )
209 char *viewer_name,*control_name;
211 Show_view_text_timer -= FrameTime;
212 gr_set_curfont( GAME_FONT );
215 switch( Viewer->type )
217 case OBJ_FIREBALL: viewer_name = "Fireball"; break;
218 case OBJ_ROBOT: viewer_name = "Robot";
220 viewer_id = Robot_names[Viewer->id];
223 case OBJ_HOSTAGE: viewer_name = "Hostage"; break;
224 case OBJ_PLAYER: viewer_name = "Player"; break;
225 case OBJ_WEAPON: viewer_name = "Weapon"; break;
226 case OBJ_CAMERA: viewer_name = "Camera"; break;
227 case OBJ_POWERUP: viewer_name = "Powerup";
229 viewer_id = Powerup_names[Viewer->id];
232 case OBJ_DEBRIS: viewer_name = "Debris"; break;
233 case OBJ_CNTRLCEN: viewer_name = "Reactor"; break;
234 default: viewer_name = "Unknown"; break;
237 switch ( Viewer->control_type) {
238 case CT_NONE: control_name = "Stopped"; break;
239 case CT_AI: control_name = "AI"; break;
240 case CT_FLYING: control_name = "Flying"; break;
241 case CT_SLEW: control_name = "Slew"; break;
242 case CT_FLYTHROUGH: control_name = "Flythrough"; break;
243 case CT_MORPH: control_name = "Morphing"; break;
244 default: control_name = "Unknown"; break;
247 gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
248 gr_printf( 0x8000, 45, "%i: %s [%s] View - %s", OBJECT_NUMBER(Viewer), viewer_name, viewer_id, control_name );
254 extern int Game_window_x;
255 extern int Game_window_y;
256 extern int Game_window_w;
257 extern int Game_window_h;
258 extern int max_window_w;
259 extern int max_window_h;
261 void render_countdown_gauge()
263 if (!Endlevel_sequence && Control_center_destroyed && (Countdown_seconds_left>-1)) { // && (Countdown_seconds_left<127)) {
266 if (!is_D2_OEM && !is_MAC_SHARE && !is_SHAREWARE) // no countdown on registered only
268 // On last level, we don't want a countdown.
269 if (PLAYING_BUILTIN_MISSION && Current_level_num == Last_level)
271 if (!(Game_mode & GM_MULTI))
273 if (Game_mode & GM_MULTI_ROBOTS)
278 gr_set_curfont( SMALL_FONT );
279 gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
280 y = SMALL_FONT->ft_h*4;
281 if (Cockpit_mode == CM_FULL_SCREEN)
282 y += SMALL_FONT->ft_h*2;
285 y += SMALL_FONT->ft_h*2;
287 //if (!((Cockpit_mode == CM_STATUS_BAR) && (Game_window_y >= 19)))
289 gr_printf(0x8000, y, "T-%d s", Countdown_seconds_left );
293 void game_draw_hud_stuff()
295 //mprintf ((0,"Linear is %d!\n",LinearSVGABuffer));
299 gr_set_curfont( MEDIUM1_FONT );
300 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
301 gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
310 game_draw_multi_message();
313 game_draw_marker_message();
315 // if (Game_mode & GM_MULTI)
317 // if (Netgame.PlayTimeAllowed)
318 // game_draw_time_left ();
321 if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
325 if (Newdemo_state == ND_STATE_PLAYBACK) {
326 if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
327 sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
329 sprintf (message, " ");
332 sprintf (message, "%s", TXT_DEMO_RECORDING);
334 gr_set_curfont( GAME_FONT ); //GAME_FONT );
335 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
337 gr_get_string_size(message, &w, &h, &aw );
338 if (Cockpit_mode == CM_FULL_COCKPIT) {
339 if (grd_curcanv->cv_bitmap.bm_h > 240)
343 } else if ( Cockpit_mode == CM_LETTERBOX )
345 if (Cockpit_mode != CM_REAR_VIEW && !Saving_movie_frames)
346 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
349 render_countdown_gauge();
351 if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num ) {
353 int y = grd_curcanv->cv_bitmap.bm_h;
355 gr_set_curfont( GAME_FONT );
356 gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
357 if (Cruise_speed > 0) {
358 int line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
360 mprintf((0,"line_spacing=%d ",line_spacing));
362 if (Cockpit_mode==CM_FULL_SCREEN) {
363 if (Game_mode & GM_MULTI)
364 y -= line_spacing * 11; //64
366 y -= line_spacing * 6; //32
367 } else if (Cockpit_mode == CM_STATUS_BAR) {
368 if (Game_mode & GM_MULTI)
369 y -= line_spacing * 8; //48
371 y -= line_spacing * 4; //24
373 y = line_spacing * 2; //12
377 gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
381 if (r_framerate.intval)
384 if ( Newdemo_state == ND_STATE_PLAYBACK )
385 Game_mode = Newdemo_game_mode;
389 if ( Newdemo_state == ND_STATE_PLAYBACK )
390 Game_mode = GM_NORMAL;
392 if ( Player_is_dead )
393 player_dead_message();
396 extern int gr_bitblt_dest_step_shift;
397 extern int gr_wait_for_retrace;
398 extern int gr_bitblt_double;
401 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels );
402 #pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \
420 void expand_row(ubyte * dest, ubyte * src, int num_src_pixels )
424 for (i = 0; i < num_src_pixels; i++) {
431 // doubles the size in x or y of a bitmap in place.
432 void game_expand_bitmap( grs_bitmap * bmp, uint flags )
435 ubyte * dptr, * sptr;
439 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
440 dptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
441 for (i=bmp->bm_h-1; i>=0; i-- ) {
442 expand_row( dptr, dptr, bmp->bm_w );
443 dptr -= bmp->bm_rowsize;
448 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
449 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
450 for (i=bmp->bm_h-1; i>=0; i-- ) {
451 memcpy( dptr, sptr, bmp->bm_w );
452 dptr -= bmp->bm_rowsize;
453 memcpy( dptr, sptr, bmp->bm_w );
454 dptr -= bmp->bm_rowsize;
455 sptr -= bmp->bm_rowsize;
459 case 3: // expand x & y
460 Assert( bmp->bm_rowsize == bmp->bm_w*2 );
461 dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
462 sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
463 for (i=bmp->bm_h-1; i>=0; i-- ) {
464 expand_row( dptr, sptr, bmp->bm_w );
465 dptr -= bmp->bm_rowsize;
466 expand_row( dptr, sptr, bmp->bm_w );
467 dptr -= bmp->bm_rowsize;
468 sptr -= bmp->bm_rowsize;
476 extern int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
478 extern int Guided_in_big_window;
481 //render a frame for the game in stereo
482 void game_render_frame_stereo()
486 fix actual_eye_width;
487 int actual_eye_offset;
488 grs_canvas RenderCanvas[2];
491 save_aspect = grd_curscreen->sc_aspect;
492 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
494 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
495 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
497 if (VR_low_res & 1) {
499 grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
501 if (VR_low_res & 2) {
503 grd_curscreen->sc_aspect /= 2; //Muck with aspect ratio
506 gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
507 gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
509 // Draw the left eye's view
511 actual_eye_width = -VR_eye_width;
512 actual_eye_offset = -VR_eye_offset;
514 actual_eye_width = VR_eye_width;
515 actual_eye_offset = VR_eye_offset;
518 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)
519 actual_eye_offset = 0;
521 gr_set_current_canvas(&RenderCanvas[0]);
523 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) {
524 char *msg = "Guided Missile View";
525 object *viewer_save = Viewer;
528 Viewer = Guided_missile[Player_num];
531 update_rendered_data(0, Viewer, 0, 0);
534 wake_up_rendered_objects(Viewer, 0);
535 Viewer = viewer_save;
537 gr_set_curfont( GAME_FONT ); //GAME_FONT );
538 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
539 gr_get_string_size(msg, &w, &h, &aw );
541 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
543 draw_guided_crosshair();
546 HUD_render_message_frame();
551 render_frame(actual_eye_width, 0); // switch eye positions for rear view
553 render_frame(-actual_eye_width, 0); // Left eye
556 game_expand_bitmap( &RenderCanvas[0].cv_bitmap, VR_low_res );
558 { //render small window into left eye's canvas
559 grs_canvas *save=grd_curcanv;
560 fix save_aspect2 = grd_curscreen->sc_aspect;
561 grd_curscreen->sc_aspect = save_aspect*2;
562 SW_drawn[0] = SW_drawn[1] = 0;
564 gr_set_current_canvas(save);
565 grd_curscreen->sc_aspect = save_aspect2;
569 if (actual_eye_offset > 0 ) {
570 gr_setcolor( gr_getcolor(0,0,0) );
571 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
572 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
573 } else if (actual_eye_offset < 0 ) {
574 gr_setcolor( gr_getcolor(0,0,0) );
575 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
578 if ( VR_show_hud && !no_draw_hud ) {
580 if (actual_eye_offset < 0 ) {
581 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 );
583 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 );
585 gr_set_current_canvas( &tmp );
586 game_draw_hud_stuff();
590 // Draw the right eye's view
591 gr_set_current_canvas(&RenderCanvas[1]);
593 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)
594 gr_bitmap(0,0,&RenderCanvas[0].cv_bitmap);
597 render_frame(-actual_eye_width, 0); // switch eye positions for rear view
599 render_frame(actual_eye_width, 0); // Right eye
602 game_expand_bitmap( &RenderCanvas[1].cv_bitmap, VR_low_res );
606 { //copy small window from left eye
611 gr_init_sub_canvas(&temp,&RenderCanvas[0],SW_x[w],SW_y[w],SW_w[w],SW_h[w]);
612 gr_bitmap(SW_x[w]+actual_eye_offset*2,SW_y[w],&temp.cv_bitmap);
618 if (actual_eye_offset>0) {
619 gr_setcolor( gr_getcolor(0,0,0) );
620 gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
621 } else if ( actual_eye_offset < 0 ) {
622 gr_setcolor( gr_getcolor(0,0,0) );
623 gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
624 grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
627 //NEWVR (Add the next 2 lines)
628 if ( VR_show_hud && !no_draw_hud ) {
630 if (actual_eye_offset > 0 ) {
631 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 );
633 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 );
635 gr_set_current_canvas( &tmp );
636 game_draw_hud_stuff();
640 // Draws white and black registration encoding lines
641 // and Accounts for pixel-shift adjustment in upcoming bitblts
642 if (VR_use_reg_code) {
643 int width, height, quarter;
645 width = RenderCanvas[0].cv_bitmap.bm_w;
646 height = RenderCanvas[0].cv_bitmap.bm_h;
649 // black out left-hand side of left page
651 // draw registration code for left eye
653 gr_set_current_canvas( &RenderCanvas[1] );
655 gr_set_current_canvas( &RenderCanvas[0] );
656 gr_setcolor( VR_WHITE_INDEX );
657 gr_scanline( 0, quarter, height-1 );
658 gr_setcolor( VR_BLACK_INDEX );
659 gr_scanline( quarter, width-1, height-1 );
662 gr_set_current_canvas( &RenderCanvas[0] );
664 gr_set_current_canvas( &RenderCanvas[1] );
665 gr_setcolor( VR_WHITE_INDEX );
666 gr_scanline( 0, quarter*3, height-1 );
667 gr_setcolor( VR_BLACK_INDEX );
668 gr_scanline( quarter*3, width-1, height-1 );
671 // Copy left eye, then right eye
672 if ( VR_screen_flags&VRF_USE_PAGING )
673 VR_current_page = !VR_current_page;
676 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
680 if ( VR_eye_offset_changed > 0 ) {
681 VR_eye_offset_changed--;
685 sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
686 sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
688 // Copy left eye, then right eye
689 gr_bitblt_dest_step_shift = 1; // Skip every other scanline.
691 if (VR_render_mode == VR_INTERLACED ) {
692 if ( actual_eye_offset > 0 ) {
693 int xoff = labs(actual_eye_offset);
694 gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
695 gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
696 } else if ( actual_eye_offset < 0 ) {
697 int xoff = labs(actual_eye_offset);
698 gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
699 gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
701 gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
702 gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
704 } else if (VR_render_mode == VR_AREA_DET) {
706 gr_bm_ubitblt( dw, dh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
707 gr_bm_ubitblt( dw, dh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
712 gr_bitblt_dest_step_shift = 0;
714 //if ( Game_vfx_flag )
715 // vfx_set_page(VR_current_page); // 0 or 1
717 if ( VR_screen_flags&VRF_USE_PAGING ) {
718 gr_wait_for_retrace = 0;
720 // Added by Samir from John's code
721 if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) ) {
722 int old_x, old_y, new_x;
723 old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
724 old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
725 new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
727 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
728 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
729 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
730 gr_show_canvas( &VR_screen_pages[VR_current_page] );
731 VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
732 VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
733 VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
735 gr_show_canvas( &VR_screen_pages[VR_current_page] );
737 gr_wait_for_retrace = 1;
739 grd_curscreen->sc_aspect=save_aspect;
742 ubyte RenderingType=0;
743 ubyte DemoDoingRight=0,DemoDoingLeft=0;
744 extern ubyte DemoDoRight,DemoDoLeft;
745 extern object DemoRightExtra,DemoLeftExtra;
747 char DemoWBUType[]={0,WBU_MISSILE,WBU_MISSILE,WBU_REAR,WBU_ESCORT,WBU_MARKER,WBU_MISSILE};
748 char DemoRearCheck[]={0,0,0,1,0,0,0};
749 char *DemoExtraMessage[]={"PLAYER","GUIDED","MISSILE","REAR","GUIDE-BOT","MARKER","SHIP"};
751 extern char guidebot_name[];
753 void show_extra_views()
755 int did_missile_view=0;
756 int save_newdemo_state = Newdemo_state;
759 if (Newdemo_state==ND_STATE_PLAYBACK)
763 DemoDoingLeft=DemoDoLeft;
766 do_cockpit_window_view(0,ConsoleObject,1,WBU_REAR,"REAR");
768 do_cockpit_window_view(0,&DemoLeftExtra,DemoRearCheck[DemoDoLeft],DemoWBUType[DemoDoLeft],DemoExtraMessage[DemoDoLeft]);
771 do_cockpit_window_view(0,NULL,0,WBU_WEAPON,NULL);
775 DemoDoingRight=DemoDoRight;
778 do_cockpit_window_view(1,ConsoleObject,1,WBU_REAR,"REAR");
780 do_cockpit_window_view(1,&DemoRightExtra,DemoRearCheck[DemoDoRight],DemoWBUType[DemoDoRight],DemoExtraMessage[DemoDoRight]);
783 do_cockpit_window_view(1,NULL,0,WBU_WEAPON,NULL);
785 DemoDoLeft=DemoDoRight=0;
786 DemoDoingLeft=DemoDoingRight=0;
791 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]) {
792 if (Guided_in_big_window)
794 RenderingType=6+(1<<4);
795 do_cockpit_window_view(1,Viewer,0,WBU_MISSILE,"SHIP");
799 RenderingType=1+(1<<4);
800 do_cockpit_window_view(1,Guided_missile[Player_num],0,WBU_GUIDED,"GUIDED");
807 if (Guided_missile[Player_num]) { //used to be active
808 if (!Guided_in_big_window)
809 do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
810 Guided_missile[Player_num] = NULL;
813 if (Missile_viewer) { //do missile view
814 static int mv_sig=-1;
816 mv_sig = Missile_viewer->signature;
817 if (Missile_view_enabled && Missile_viewer->type!=OBJ_NONE && Missile_viewer->signature == mv_sig) {
818 RenderingType=2+(1<<4);
819 do_cockpit_window_view(1,Missile_viewer,0,WBU_MISSILE,"MISSILE");
823 Missile_viewer = NULL;
826 do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
833 if (w==1 && did_missile_view)
834 continue; //if showing missile view in right window, can't show anything else
836 //show special views if selected
837 switch (Cockpit_3d_view[w]) {
840 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
843 if (Rear_view) { //if big window is rear view, show front here
844 RenderingType=3+(w<<4);
845 do_cockpit_window_view(w,ConsoleObject,0,WBU_REAR,"FRONT");
847 else { //show normal rear view
848 RenderingType=3+(w<<4);
849 do_cockpit_window_view(w,ConsoleObject,1,WBU_REAR,"REAR");
854 buddy = find_escort();
856 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
857 Cockpit_3d_view[w] = CV_NONE;
860 RenderingType=4+(w<<4);
861 do_cockpit_window_view(w,buddy,0,WBU_ESCORT,guidebot_name);
867 int player = Coop_view_player[w];
869 RenderingType=255; // don't handle coop stuff
871 if (player!=-1 && Players[player].connected && ((Game_mode & GM_MULTI_COOP) || ((Game_mode & GM_TEAM) && (get_team(player) == get_team(Player_num)))))
872 do_cockpit_window_view(w,&Objects[Players[Coop_view_player[w]].objnum],0,WBU_COOP,Players[Coop_view_player[w]].callsign);
874 do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
875 Cockpit_3d_view[w] = CV_NONE;
882 RenderingType=5+(w<<4);
883 if (Marker_viewer_num[w] == -1 || MarkerObject[Marker_viewer_num[w]] == -1) {
884 Cockpit_3d_view[w] = CV_NONE;
887 sprintf(label,"Marker %d",Marker_viewer_num[w]+1);
888 do_cockpit_window_view(w,&Objects[MarkerObject[Marker_viewer_num[w]]],0,WBU_MARKER,label);
892 Int3(); //invalid window type
896 Newdemo_state = save_newdemo_state;
899 int BigWindowSwitch=0;
900 extern int force_cockpit_redraw;
902 void draw_guided_crosshair(void);
903 void update_cockpits(int force_redraw);
906 //render a frame for the game
907 void game_render_frame_mono(void)
909 grs_canvas Screen_3d_window;
913 gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
914 VR_render_sub_buffer[0].cv_bitmap.bm_x,
915 VR_render_sub_buffer[0].cv_bitmap.bm_y,
916 VR_render_sub_buffer[0].cv_bitmap.bm_w,
917 VR_render_sub_buffer[0].cv_bitmap.bm_h);
919 if ( Game_double_buffer )
920 gr_set_current_canvas(&VR_render_sub_buffer[0]);
922 gr_set_current_canvas(&Screen_3d_window);
924 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) {
925 char *msg = "Guided Missile View";
926 object *viewer_save = Viewer;
929 if (Cockpit_mode==CM_FULL_COCKPIT)
932 force_cockpit_redraw=1;
933 Cockpit_mode=CM_STATUS_BAR;
937 Viewer = Guided_missile[Player_num];
940 update_rendered_data(0, Viewer, 0, 0);
943 wake_up_rendered_objects(Viewer, 0);
944 Viewer = viewer_save;
946 gr_set_curfont( GAME_FONT ); //GAME_FONT );
947 gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
948 gr_get_string_size(msg, &w, &h, &aw );
950 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
952 draw_guided_crosshair();
955 HUD_render_message_frame();
963 force_cockpit_redraw=1;
964 Cockpit_mode=CM_FULL_COCKPIT;
968 update_rendered_data(0, Viewer, Rear_view, 0);
972 if ( Game_double_buffer )
973 gr_set_current_canvas(&VR_render_sub_buffer[0]);
975 gr_set_current_canvas(&Screen_3d_window);
978 game_draw_hud_stuff();
980 if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
981 extern char *Pause_msg;
982 ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
984 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
985 show_boxed_message(Pause_msg);
986 VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
989 if ( Game_double_buffer ) { //copy to visible screen
990 // if ( !Game_cockpit_copy_code ) {
991 if ( VR_screen_flags&VRF_USE_PAGING ) {
992 VR_current_page = !VR_current_page;
993 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
994 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 );
995 gr_wait_for_retrace = 0;
996 gr_show_canvas( &VR_screen_pages[VR_current_page] );
997 gr_wait_for_retrace = 1;
999 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w,
1000 VR_render_sub_buffer[0].cv_h,
1001 VR_render_sub_buffer[0].cv_bitmap.bm_x,
1002 VR_render_sub_buffer[0].cv_bitmap.bm_y,
1004 &VR_render_sub_buffer[0].cv_bitmap,
1005 &VR_screen_pages[0].cv_bitmap );
1011 gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
1012 #else //def MACINTOSH
1013 gr_ibitblt( &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap );
1021 show_extra_views(); //missile view, buddy bot, etc.
1023 if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
1025 if ( Newdemo_state == ND_STATE_PLAYBACK )
1026 Game_mode = Newdemo_game_mode;
1030 if ( Newdemo_state == ND_STATE_PLAYBACK )
1031 Game_mode = GM_NORMAL;
1042 void toggle_cockpit()
1046 switch (Cockpit_mode) {
1048 case CM_FULL_COCKPIT: {
1049 int max_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR + (SM_HIRES?(Num_cockpits/2):0)].index].bm_h;
1050 if (Game_window_h > max_h) //too big for statusbar
1051 new_mode = CM_FULL_SCREEN;
1053 new_mode = CM_STATUS_BAR;
1058 case CM_FULL_SCREEN:
1061 new_mode = CM_FULL_COCKPIT;
1067 return; //do nothing
1072 select_cockpit(new_mode);
1073 HUD_clear_messages();
1074 write_player_file();
1078 #define WINDOW_W_DELTA ((max_window_w / 16)&~1) //24 //20
1079 #define WINDOW_H_DELTA ((max_window_h / 16)&~1) //12 //10
1081 #define WINDOW_MIN_W ((max_window_w * 10) / 22) //160
1082 #define WINDOW_MIN_H ((max_window_h * 10) / 22)
1084 //#define WINDOW_W_DELTA 32
1085 //#define WINDOW_H_DELTA 16
1087 #define WINDOW_W_DELTA ((max_window_w / 16) & ~15) // double word aligned
1088 #define WINDOW_H_DELTA ((max_window_h / 16) & ~15) // double word aligned
1090 #define WINDOW_MIN_W (max_window_w-(WINDOW_W_DELTA*11))
1091 #define WINDOW_MIN_H (max_window_h-(WINDOW_H_DELTA*11))
1096 if (Cockpit_mode == CM_FULL_COCKPIT) {
1097 Game_window_h = max_window_h;
1098 Game_window_w = max_window_w;
1100 HUD_init_message("Press F3 to return to Cockpit mode");
1104 if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1107 if (Game_window_h>=max_window_h || Game_window_w>=max_window_w) {
1108 //Game_window_w = max_window_w;
1109 //Game_window_h = max_window_h;
1110 select_cockpit(CM_FULL_SCREEN);
1114 Game_window_w += WINDOW_W_DELTA;
1115 Game_window_h += WINDOW_H_DELTA;
1117 if (Game_window_h > max_window_h)
1118 Game_window_h = max_window_h;
1120 if (Game_window_w > max_window_w)
1121 Game_window_w = max_window_w;
1123 Game_window_x = (max_window_w - Game_window_w)/2;
1124 Game_window_y = (max_window_h - Game_window_h)/2;
1126 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
1129 HUD_clear_messages(); // @mk, 11/11/94
1131 write_player_file();
1134 // grs_bitmap background_bitmap; already declared in line 434 (samir 4/10/94)
1136 extern grs_bitmap background_bitmap;
1138 void copy_background_rect(int left,int top,int right,int bot)
1140 grs_bitmap *bm = &background_bitmap;
1142 int tile_left,tile_right,tile_top,tile_bot;
1146 if (right < left || bot < top)
1149 tile_left = left / bm->bm_w;
1150 tile_right = right / bm->bm_w;
1151 tile_top = top / bm->bm_h;
1152 tile_bot = bot / bm->bm_h;
1154 ofs_y = top % bm->bm_h;
1157 for (y=tile_top;y<=tile_bot;y++) {
1160 ofs_x = left % bm->bm_w;
1163 //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
1164 h = min(bot-dest_y+1,bm->bm_h-ofs_y);
1166 for (x=tile_left;x<=tile_right;x++) {
1168 //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
1169 w = min(right-dest_x+1,bm->bm_w-ofs_x);
1171 gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
1172 &background_bitmap,&grd_curcanv->cv_bitmap);
1183 //fills int the background surrounding the 3d window
1184 void fill_background()
1196 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1197 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1198 copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
1199 copy_background_rect(x,y-dy,x+w-1,y-1);
1200 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1202 if (VR_screen_flags & VRF_USE_PAGING) {
1203 gr_set_current_canvas(&VR_screen_pages[!VR_current_page]);
1204 copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
1205 copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
1206 copy_background_rect(x,y-dy,x+w-1,y-1);
1207 copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
1211 void shrink_window()
1213 mprintf((0,"%d ",FrameCount));
1215 // mprintf ((0,"W=%d H=%d\n",Game_window_w,Game_window_h));
1217 if (Cockpit_mode == CM_FULL_COCKPIT && (VR_screen_flags & VRF_ALLOW_COCKPIT)) {
1218 Game_window_h = max_window_h;
1219 Game_window_w = max_window_w;
1220 //!!toggle_cockpit();
1221 select_cockpit(CM_STATUS_BAR);
1224 HUD_init_message("Press F3 to return to Cockpit mode");
1225 write_player_file();
1229 if (Cockpit_mode == CM_FULL_SCREEN && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1231 //Game_window_w = max_window_w;
1232 //Game_window_h = max_window_h;
1233 select_cockpit(CM_STATUS_BAR);
1234 write_player_file();
1238 if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
1241 mprintf ((0,"Cockpit mode=%d\n",Cockpit_mode));
1243 if (Game_window_w > WINDOW_MIN_W) {
1246 Game_window_w -= WINDOW_W_DELTA;
1247 Game_window_h -= WINDOW_H_DELTA;
1250 mprintf ((0,"NewW=%d NewH=%d VW=%d maxH=%d\n",Game_window_w,Game_window_h,max_window_w,max_window_h));
1252 if ( Game_window_w < WINDOW_MIN_W )
1253 Game_window_w = WINDOW_MIN_W;
1255 if ( Game_window_h < WINDOW_MIN_H )
1256 Game_window_h = WINDOW_MIN_H;
1258 Game_window_x = (max_window_w - Game_window_w)/2;
1259 Game_window_y = (max_window_h - Game_window_h)/2;
1263 game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
1264 HUD_clear_messages();
1265 write_player_file();
1270 int last_drawn_cockpit[2] = { -1, -1 };
1271 extern void ogl_loadbmtexture(grs_bitmap *bm);
1273 // This actually renders the new cockpit onto the screen.
1274 void update_cockpits(int force_redraw)
1278 //Redraw the on-screen cockpit bitmaps
1279 if (VR_render_mode != VR_NONE ) return;
1281 switch( Cockpit_mode ) {
1282 case CM_FULL_COCKPIT:
1284 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1285 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode + (SM_HIRES?(Num_cockpits/2):0)]);
1286 gr_ubitmapm(0,0, &GameBitmaps[cockpit_bitmap[Cockpit_mode + (SM_HIRES?(Num_cockpits/2):0)].index]);
1289 case CM_FULL_SCREEN:
1290 Game_window_x = (max_window_w - Game_window_w)/2;
1291 Game_window_y = (max_window_h - Game_window_h)/2;
1297 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1299 PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode + (SM_HIRES?(Num_cockpits/2):0)]);
1300 gr_ubitmapm(0,max_window_h,&GameBitmaps[cockpit_bitmap[Cockpit_mode + (SM_HIRES?(Num_cockpits/2):0)].index]);
1302 Game_window_x = (max_window_w - Game_window_w)/2;
1303 Game_window_y = (max_window_h - Game_window_h)/2;
1308 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1310 // Clear the top and bottom of the screen
1311 gr_setcolor(BM_XRGB(0,0,0));
1313 VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_y + VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_h,
1314 GWIDTH-1,GHEIGHT-1);
1315 gr_rect(0,0,GWIDTH-1,VR_render_sub_buffer[VR_current_page].cv_bitmap.bm_y);
1317 // In a modex mode, clear the other buffer.
1318 if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
1319 gr_set_current_canvas(&VR_screen_pages[VR_current_page^1]);
1320 gr_clear_canvas( BM_XRGB(0,0,0) );
1321 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1327 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1329 if (Cockpit_mode != last_drawn_cockpit[VR_current_page] || force_redraw )
1330 last_drawn_cockpit[VR_current_page] = Cockpit_mode;
1334 if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
1340 void game_render_frame()
1342 set_screen_mode( SCREEN_GAME );
1344 // update_cockpits(0);
1346 play_homing_warning();
1348 if (VR_render_mode == VR_NONE )
1349 game_render_frame_mono();
1351 game_render_frame_stereo();
1354 // Make sure palette is faded in
1356 gr_palette_fade_in( gr_palette, 32, 0 );
1362 extern int Color_0_31_0;
1364 //draw a crosshair for the guided missile
1365 void draw_guided_crosshair(void)
1369 gr_setcolor(Color_0_31_0);
1371 w = grd_curcanv->cv_w>>5;
1375 h = i2f(w) / grd_curscreen->sc_aspect;
1377 x = grd_curcanv->cv_w / 2;
1378 y = grd_curcanv->cv_h / 2;
1380 gr_scanline(x-w/2,x+w/2,y);
1381 gr_uline(i2f(x),i2f(y-h/2),i2f(x),i2f(y+h/2));
1385 typedef struct bkg {
1386 short x, y, w, h; // The location of the menu.
1387 grs_bitmap * bmp; // The background under the menu.
1390 bkg bg = {0,0,0,0,NULL};
1392 #define BOX_BORDER (MenuHires?60:30)
1394 //show a message in a nice little box
1395 void show_boxed_message(char *msg)
1400 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
1401 gr_set_curfont( MEDIUM1_FONT );
1403 gr_get_string_size(msg,&w,&h,&aw);
1405 x = (grd_curscreen->sc_w-w)/2;
1406 y = (grd_curscreen->sc_h-h)/2;
1409 gr_free_bitmap(bg.bmp);
1413 // Save the background of the display
1414 bg.x=x; bg.y=y; bg.w=w; bg.h=h;
1416 bg.bmp = gr_create_bitmap( w+BOX_BORDER, h+BOX_BORDER );
1418 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 );
1420 nm_draw_background(x-BOX_BORDER/2,y-BOX_BORDER/2,x+w+BOX_BORDER/2-1,y+h+BOX_BORDER/2-1);
1422 gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
1424 gr_ustring( 0x8000, y, msg );
1427 void clear_boxed_message()
1432 gr_bitmap(bg.x-BOX_BORDER/2, bg.y-BOX_BORDER/2, bg.bmp);
1434 gr_free_bitmap(bg.bmp);