1988 lines
53 KiB
C
1988 lines
53 KiB
C
/*
|
|
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
|
|
SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
|
|
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
|
|
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
|
|
IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
|
|
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
|
|
FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
|
|
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
|
|
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
|
|
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <conf.h>
|
|
#endif
|
|
|
|
#ifdef RCS
|
|
static char rcsid[] = "$Id: gamerend.c,v 1.7 2003-03-01 01:51:15 btb Exp $";
|
|
#endif
|
|
|
|
#ifdef WINDOWS
|
|
#include "desw.h"
|
|
#include "winapp.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "pstypes.h"
|
|
#include "console.h"
|
|
#include "pa_enabl.h" //$$POLY_ACC
|
|
#include "inferno.h"
|
|
#include "error.h"
|
|
#include "mono.h"
|
|
#include "gr.h"
|
|
#include "palette.h"
|
|
#include "ibitblt.h"
|
|
#include "bm.h"
|
|
#include "player.h"
|
|
#include "render.h"
|
|
#include "menu.h"
|
|
#include "newmenu.h"
|
|
#include "screens.h"
|
|
#include "fix.h"
|
|
#include "robot.h"
|
|
#include "game.h"
|
|
#include "gauges.h"
|
|
#include "gamefont.h"
|
|
#include "newdemo.h"
|
|
#include "text.h"
|
|
#include "multi.h"
|
|
#include "endlevel.h"
|
|
#include "cntrlcen.h"
|
|
#include "powerup.h"
|
|
#include "laser.h"
|
|
#include "playsave.h"
|
|
#include "automap.h"
|
|
#include "mission.h"
|
|
#include "gameseq.h"
|
|
|
|
#if defined(POLY_ACC)
|
|
#include "poly_acc.h"
|
|
#endif
|
|
|
|
#ifdef OGL
|
|
#include "ogl_init.h"
|
|
#endif
|
|
|
|
extern fix Cruise_speed;
|
|
extern int LinearSVGABuffer;
|
|
extern int Current_display_mode;
|
|
extern cvar_t r_framerate;
|
|
|
|
|
|
#ifdef WINDOWS
|
|
cockpit_span_line win_cockpit_mask[480];
|
|
void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest);
|
|
#endif
|
|
|
|
|
|
#ifndef NDEBUG
|
|
extern int Debug_pause; //John's debugging pause system
|
|
#endif
|
|
|
|
#ifndef RELEASE
|
|
extern int Saving_movie_frames;
|
|
#else
|
|
#define Saving_movie_frames 0
|
|
#endif
|
|
|
|
// Returns the length of the first 'n' characters of a string.
|
|
int string_width( char * s, int n )
|
|
{
|
|
int w,h,aw;
|
|
char p;
|
|
p = s[n];
|
|
s[n] = 0;
|
|
gr_get_string_size( s, &w, &h, &aw );
|
|
s[n] = p;
|
|
return w;
|
|
}
|
|
|
|
// Draw string 's' centered on a canvas... if wider than
|
|
// canvas, then wrap it.
|
|
void draw_centered_text( int y, char * s )
|
|
{
|
|
int i, l;
|
|
char p;
|
|
|
|
l = strlen(s);
|
|
|
|
if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w ) {
|
|
gr_string( 0x8000, y, s );
|
|
return;
|
|
}
|
|
|
|
for (i=0; i<l; i++ ) {
|
|
if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) ) {
|
|
p = s[i];
|
|
s[i] = 0;
|
|
gr_string( 0x8000, y, s );
|
|
s[i] = p;
|
|
gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern ubyte DefiningMarkerMessage;
|
|
extern char Marker_input[];
|
|
|
|
#define MAX_MARKER_MESSAGE_LEN 120
|
|
void game_draw_marker_message()
|
|
{
|
|
char temp_string[MAX_MARKER_MESSAGE_LEN+25];
|
|
|
|
if ( DefiningMarkerMessage)
|
|
{
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT
|
|
gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
|
|
sprintf( temp_string, "Marker: %s_", Marker_input );
|
|
draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef NETWORK
|
|
void game_draw_multi_message()
|
|
{
|
|
char temp_string[MAX_MULTI_MESSAGE_LEN+25];
|
|
|
|
if ( (Game_mode&GM_MULTI) && (multi_sending_message)) {
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
|
|
sprintf( temp_string, "%s: %s_", TXT_MESSAGE, Network_message );
|
|
draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
|
|
|
|
}
|
|
|
|
if ( (Game_mode&GM_MULTI) && (multi_defining_message)) {
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
|
|
sprintf( temp_string, "%s #%d: %s_", TXT_MACRO, multi_defining_message, Network_message );
|
|
draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//these should be in gr.h
|
|
#define cv_w cv_bitmap.bm_w
|
|
#define cv_h cv_bitmap.bm_h
|
|
|
|
fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
|
|
fix frame_time_total=0;
|
|
int frame_time_cntr=0;
|
|
|
|
void ftoa(char *string, fix f)
|
|
{
|
|
int decimal, fractional;
|
|
|
|
decimal = f2i(f);
|
|
fractional = ((f & 0xffff)*100)/65536;
|
|
if (fractional < 0 )
|
|
fractional *= -1;
|
|
if (fractional > 99 ) fractional = 99;
|
|
sprintf( string, "%d.%02d", decimal, fractional );
|
|
}
|
|
|
|
void show_framerate()
|
|
{
|
|
char temp[50];
|
|
//static int q;
|
|
|
|
fix rate;
|
|
|
|
frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
|
|
frame_time_list[frame_time_cntr] = RealFrameTime;
|
|
frame_time_cntr = (frame_time_cntr+1)%8;
|
|
|
|
rate = fixdiv(f1_0*8,frame_time_total);
|
|
|
|
gr_set_curfont( GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
|
|
|
|
ftoa( temp, rate ); // Convert fixed to string
|
|
gr_printf(grd_curcanv->cv_w-(8*GAME_FONT->ft_w),grd_curcanv->cv_h-5*(GAME_FONT->ft_h+GAME_FONT->ft_h/4),"FPS: %s ", temp );
|
|
// if ( !( q++ % 30 ) )
|
|
// mprintf( (0,"fps: %s\n", temp ) );
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
|
|
fix Show_view_text_timer = -1;
|
|
|
|
void draw_window_label()
|
|
{
|
|
if ( Show_view_text_timer > 0 )
|
|
{
|
|
char *viewer_name,*control_name;
|
|
char *viewer_id;
|
|
Show_view_text_timer -= FrameTime;
|
|
gr_set_curfont( GAME_FONT );
|
|
|
|
viewer_id = "";
|
|
switch( Viewer->type )
|
|
{
|
|
case OBJ_FIREBALL: viewer_name = "Fireball"; break;
|
|
case OBJ_ROBOT: viewer_name = "Robot";
|
|
#ifdef EDITOR
|
|
viewer_id = Robot_names[Viewer->id];
|
|
#endif
|
|
break;
|
|
case OBJ_HOSTAGE: viewer_name = "Hostage"; break;
|
|
case OBJ_PLAYER: viewer_name = "Player"; break;
|
|
case OBJ_WEAPON: viewer_name = "Weapon"; break;
|
|
case OBJ_CAMERA: viewer_name = "Camera"; break;
|
|
case OBJ_POWERUP: viewer_name = "Powerup";
|
|
#ifdef EDITOR
|
|
viewer_id = Powerup_names[Viewer->id];
|
|
#endif
|
|
break;
|
|
case OBJ_DEBRIS: viewer_name = "Debris"; break;
|
|
case OBJ_CNTRLCEN: viewer_name = "Reactor"; break;
|
|
default: viewer_name = "Unknown"; break;
|
|
}
|
|
|
|
switch ( Viewer->control_type) {
|
|
case CT_NONE: control_name = "Stopped"; break;
|
|
case CT_AI: control_name = "AI"; break;
|
|
case CT_FLYING: control_name = "Flying"; break;
|
|
case CT_SLEW: control_name = "Slew"; break;
|
|
case CT_FLYTHROUGH: control_name = "Flythrough"; break;
|
|
case CT_MORPH: control_name = "Morphing"; break;
|
|
default: control_name = "Unknown"; break;
|
|
}
|
|
|
|
gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
|
|
gr_printf( 0x8000, 45, "%i: %s [%s] View - %s",Viewer-Objects, viewer_name, viewer_id, control_name );
|
|
|
|
}
|
|
}
|
|
#endif
|
|
|
|
extern int Game_window_x;
|
|
extern int Game_window_y;
|
|
extern int Game_window_w;
|
|
extern int Game_window_h;
|
|
extern int max_window_w;
|
|
extern int max_window_h;
|
|
|
|
void render_countdown_gauge()
|
|
{
|
|
if (!Endlevel_sequence && Control_center_destroyed && (Countdown_seconds_left>-1)) { // && (Countdown_seconds_left<127)) {
|
|
int y;
|
|
|
|
#if !defined(D2_OEM) && !defined(SHAREWARE) // no countdown on registered only
|
|
// On last level, we don't want a countdown.
|
|
if ((Current_mission_num == Builtin_mission_num) && (Current_level_num == Last_level))
|
|
{
|
|
if (!(Game_mode & GM_MULTI))
|
|
return;
|
|
if (Game_mode & GM_MULTI_ROBOTS)
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
gr_set_curfont( SMALL_FONT );
|
|
gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
|
|
y = SMALL_FONT->ft_h*4;
|
|
if (Cockpit_mode == CM_FULL_SCREEN)
|
|
y += SMALL_FONT->ft_h*2;
|
|
|
|
if (Player_is_dead)
|
|
y += SMALL_FONT->ft_h*2;
|
|
|
|
//if (!((Cockpit_mode == CM_STATUS_BAR) && (Game_window_y >= 19)))
|
|
// y += 5;
|
|
gr_printf(0x8000, y, "T-%d s", Countdown_seconds_left );
|
|
}
|
|
}
|
|
|
|
void game_draw_hud_stuff()
|
|
{
|
|
#ifdef MACINTOSH
|
|
int odisplay_mode = Current_display_mode;
|
|
if (Scanline_double) {
|
|
FontHires = 0;
|
|
Current_display_mode = 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
//mprintf ((0,"Linear is %d!\n",LinearSVGABuffer));
|
|
|
|
#ifndef NDEBUG
|
|
if (Debug_pause) {
|
|
gr_set_curfont( MEDIUM1_FONT );
|
|
gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
|
|
gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
|
|
}
|
|
#endif
|
|
|
|
#ifndef NDEBUG
|
|
draw_window_label();
|
|
#endif
|
|
|
|
#ifdef NETWORK
|
|
game_draw_multi_message();
|
|
#endif
|
|
|
|
game_draw_marker_message();
|
|
|
|
// if (Game_mode & GM_MULTI)
|
|
// {
|
|
// if (Netgame.PlayTimeAllowed)
|
|
// game_draw_time_left ();
|
|
// }
|
|
|
|
if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
|
|
char message[128];
|
|
int h,w,aw;
|
|
|
|
if (Newdemo_state == ND_STATE_PLAYBACK) {
|
|
if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
|
|
sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
|
|
} else {
|
|
sprintf (message, " ");
|
|
}
|
|
} else
|
|
sprintf (message, TXT_DEMO_RECORDING);
|
|
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
|
|
|
|
gr_get_string_size(message, &w, &h, &aw );
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double) // double height if scanline doubling since we have the correct
|
|
h += h; // font for printing, but the wrong height.
|
|
#endif
|
|
if (Cockpit_mode == CM_FULL_COCKPIT) {
|
|
if (grd_curcanv->cv_bitmap.bm_h > 240)
|
|
h += 40;
|
|
else
|
|
h += 15;
|
|
} else if ( Cockpit_mode == CM_LETTERBOX )
|
|
h += 7;
|
|
if (Cockpit_mode != CM_REAR_VIEW && !Saving_movie_frames)
|
|
gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
|
|
}
|
|
|
|
render_countdown_gauge();
|
|
|
|
if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num ) {
|
|
int x = 3;
|
|
int y = grd_curcanv->cv_bitmap.bm_h;
|
|
|
|
gr_set_curfont( GAME_FONT );
|
|
gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
|
|
if (Cruise_speed > 0) {
|
|
int line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
|
|
|
|
mprintf((0,"line_spacing=%d ",line_spacing));
|
|
|
|
if (Cockpit_mode==CM_FULL_SCREEN) {
|
|
if (Game_mode & GM_MULTI)
|
|
y -= line_spacing * 11; //64
|
|
else
|
|
y -= line_spacing * 6; //32
|
|
} else if (Cockpit_mode == CM_STATUS_BAR) {
|
|
if (Game_mode & GM_MULTI)
|
|
y -= line_spacing * 8; //48
|
|
else
|
|
y -= line_spacing * 4; //24
|
|
} else {
|
|
y = line_spacing * 2; //12
|
|
x = 20+2;
|
|
}
|
|
|
|
gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
|
|
}
|
|
}
|
|
|
|
if (r_framerate.value)
|
|
show_framerate();
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
Game_mode = Newdemo_game_mode;
|
|
|
|
draw_hud();
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
Game_mode = GM_NORMAL;
|
|
|
|
if ( Player_is_dead )
|
|
player_dead_message();
|
|
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double) {
|
|
FontHires = 1;
|
|
Current_display_mode = odisplay_mode;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
extern int gr_bitblt_dest_step_shift;
|
|
extern int gr_wait_for_retrace;
|
|
extern int gr_bitblt_double;
|
|
|
|
#if 0
|
|
void expand_row(ubyte * dest, ubyte * src, int num_src_pixels );
|
|
#pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \
|
|
"add esi, ecx" \
|
|
"dec esi" \
|
|
"add edi, ecx" \
|
|
"add edi, ecx" \
|
|
"dec edi" \
|
|
"dec edi" \
|
|
"nextpixel:" \
|
|
"mov al,[esi]" \
|
|
"mov ah, al" \
|
|
"dec esi" \
|
|
"mov [edi], ax" \
|
|
"dec edi" \
|
|
"dec edi" \
|
|
"dec ecx" \
|
|
"jnz nextpixel" \
|
|
"done:"
|
|
#else
|
|
void expand_row(ubyte * dest, ubyte * src, int num_src_pixels )
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < num_src_pixels; i++) {
|
|
*dest++ = *src;
|
|
*dest++ = *src++;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// doubles the size in x or y of a bitmap in place.
|
|
void game_expand_bitmap( grs_bitmap * bmp, uint flags )
|
|
{
|
|
int i;
|
|
ubyte * dptr, * sptr;
|
|
|
|
switch(flags & 3) {
|
|
case 2: // expand x
|
|
Assert( bmp->bm_rowsize == bmp->bm_w*2 );
|
|
dptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
|
|
for (i=bmp->bm_h-1; i>=0; i-- ) {
|
|
expand_row( dptr, dptr, bmp->bm_w );
|
|
dptr -= bmp->bm_rowsize;
|
|
}
|
|
bmp->bm_w *= 2;
|
|
break;
|
|
case 1: // expand y
|
|
dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
|
|
sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
|
|
for (i=bmp->bm_h-1; i>=0; i-- ) {
|
|
memcpy( dptr, sptr, bmp->bm_w );
|
|
dptr -= bmp->bm_rowsize;
|
|
memcpy( dptr, sptr, bmp->bm_w );
|
|
dptr -= bmp->bm_rowsize;
|
|
sptr -= bmp->bm_rowsize;
|
|
}
|
|
bmp->bm_h *= 2;
|
|
break;
|
|
case 3: // expand x & y
|
|
Assert( bmp->bm_rowsize == bmp->bm_w*2 );
|
|
dptr = &bmp->bm_data[(2*(bmp->bm_h-1)+1)*bmp->bm_rowsize];
|
|
sptr = &bmp->bm_data[(bmp->bm_h-1)*bmp->bm_rowsize];
|
|
for (i=bmp->bm_h-1; i>=0; i-- ) {
|
|
expand_row( dptr, sptr, bmp->bm_w );
|
|
dptr -= bmp->bm_rowsize;
|
|
expand_row( dptr, sptr, bmp->bm_w );
|
|
dptr -= bmp->bm_rowsize;
|
|
sptr -= bmp->bm_rowsize;
|
|
}
|
|
bmp->bm_w *= 2;
|
|
bmp->bm_h *= 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
extern int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
|
|
|
|
extern int Guided_in_big_window;
|
|
|
|
#if 0
|
|
//render a frame for the game in stereo
|
|
void game_render_frame_stereo()
|
|
{
|
|
int dw,dh,sw,sh;
|
|
fix save_aspect;
|
|
fix actual_eye_width;
|
|
int actual_eye_offset;
|
|
grs_canvas RenderCanvas[2];
|
|
int no_draw_hud=0;
|
|
|
|
save_aspect = grd_curscreen->sc_aspect;
|
|
grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
|
|
|
|
sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
|
|
sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
|
|
|
|
if (VR_low_res & 1) {
|
|
sh /= 2;
|
|
grd_curscreen->sc_aspect *= 2; //Muck with aspect ratio
|
|
}
|
|
if (VR_low_res & 2) {
|
|
sw /= 2;
|
|
grd_curscreen->sc_aspect /= 2; //Muck with aspect ratio
|
|
}
|
|
|
|
gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
|
|
gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
|
|
|
|
// Draw the left eye's view
|
|
if (VR_eye_switch) {
|
|
actual_eye_width = -VR_eye_width;
|
|
actual_eye_offset = -VR_eye_offset;
|
|
} else {
|
|
actual_eye_width = VR_eye_width;
|
|
actual_eye_offset = VR_eye_offset;
|
|
}
|
|
|
|
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)
|
|
actual_eye_offset = 0;
|
|
|
|
gr_set_current_canvas(&RenderCanvas[0]);
|
|
|
|
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) {
|
|
char *msg = "Guided Missile View";
|
|
object *viewer_save = Viewer;
|
|
int w,h,aw;
|
|
|
|
Viewer = Guided_missile[Player_num];
|
|
|
|
WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
|
|
{
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double)
|
|
FontHires = 0;
|
|
#endif
|
|
update_rendered_data(0, Viewer, 0, 0);
|
|
render_frame(0, 0);
|
|
#if defined(POLY_ACC) && !defined(MACINTOSH) // dma stuff not support on mac via RAVE
|
|
pa_dma_poll();
|
|
#endif
|
|
|
|
wake_up_rendered_objects(Viewer, 0);
|
|
Viewer = viewer_save;
|
|
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
|
|
gr_get_string_size(msg, &w, &h, &aw );
|
|
|
|
gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
|
|
|
|
draw_guided_crosshair();
|
|
}
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
|
|
HUD_render_message_frame();
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double)
|
|
FontHires = 1;
|
|
#endif
|
|
|
|
no_draw_hud=1;
|
|
}
|
|
else if (Rear_view)
|
|
render_frame(actual_eye_width, 0); // switch eye positions for rear view
|
|
else
|
|
render_frame(-actual_eye_width, 0); // Left eye
|
|
|
|
if ( VR_low_res )
|
|
game_expand_bitmap( &RenderCanvas[0].cv_bitmap, VR_low_res );
|
|
|
|
{ //render small window into left eye's canvas
|
|
grs_canvas *save=grd_curcanv;
|
|
fix save_aspect2 = grd_curscreen->sc_aspect;
|
|
grd_curscreen->sc_aspect = save_aspect*2;
|
|
SW_drawn[0] = SW_drawn[1] = 0;
|
|
show_extra_views();
|
|
gr_set_current_canvas(save);
|
|
grd_curscreen->sc_aspect = save_aspect2;
|
|
}
|
|
|
|
//NEWVR
|
|
if (actual_eye_offset > 0 ) {
|
|
gr_setcolor( gr_getcolor(0,0,0) );
|
|
gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
|
|
grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
|
|
} else if (actual_eye_offset < 0 ) {
|
|
gr_setcolor( gr_getcolor(0,0,0) );
|
|
gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
|
|
}
|
|
|
|
if ( VR_show_hud && !no_draw_hud ) {
|
|
grs_canvas tmp;
|
|
if (actual_eye_offset < 0 ) {
|
|
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 );
|
|
} else {
|
|
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 );
|
|
}
|
|
gr_set_current_canvas( &tmp );
|
|
game_draw_hud_stuff();
|
|
}
|
|
|
|
|
|
// Draw the right eye's view
|
|
gr_set_current_canvas(&RenderCanvas[1]);
|
|
|
|
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)
|
|
gr_bitmap(0,0,&RenderCanvas[0].cv_bitmap);
|
|
else {
|
|
if (Rear_view)
|
|
render_frame(-actual_eye_width, 0); // switch eye positions for rear view
|
|
else
|
|
render_frame(actual_eye_width, 0); // Right eye
|
|
|
|
if ( VR_low_res )
|
|
game_expand_bitmap( &RenderCanvas[1].cv_bitmap, VR_low_res );
|
|
}
|
|
|
|
|
|
{ //copy small window from left eye
|
|
grs_canvas temp;
|
|
int w;
|
|
for (w=0;w<2;w++) {
|
|
if (SW_drawn[w]) {
|
|
gr_init_sub_canvas(&temp,&RenderCanvas[0],SW_x[w],SW_y[w],SW_w[w],SW_h[w]);
|
|
gr_bitmap(SW_x[w]+actual_eye_offset*2,SW_y[w],&temp.cv_bitmap);
|
|
}
|
|
}
|
|
}
|
|
|
|
//NEWVR
|
|
if (actual_eye_offset>0) {
|
|
gr_setcolor( gr_getcolor(0,0,0) );
|
|
gr_rect( 0, 0, labs(actual_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
|
|
} else if ( actual_eye_offset < 0 ) {
|
|
gr_setcolor( gr_getcolor(0,0,0) );
|
|
gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(actual_eye_offset)*2, 0,
|
|
grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
|
|
}
|
|
|
|
//NEWVR (Add the next 2 lines)
|
|
if ( VR_show_hud && !no_draw_hud ) {
|
|
grs_canvas tmp;
|
|
if (actual_eye_offset > 0 ) {
|
|
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 );
|
|
} else {
|
|
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 );
|
|
}
|
|
gr_set_current_canvas( &tmp );
|
|
game_draw_hud_stuff();
|
|
}
|
|
|
|
|
|
// Draws white and black registration encoding lines
|
|
// and Accounts for pixel-shift adjustment in upcoming bitblts
|
|
if (VR_use_reg_code) {
|
|
int width, height, quarter;
|
|
|
|
width = RenderCanvas[0].cv_bitmap.bm_w;
|
|
height = RenderCanvas[0].cv_bitmap.bm_h;
|
|
quarter = width / 4;
|
|
|
|
// black out left-hand side of left page
|
|
|
|
// draw registration code for left eye
|
|
if ( VR_eye_switch )
|
|
gr_set_current_canvas( &RenderCanvas[1] );
|
|
else
|
|
gr_set_current_canvas( &RenderCanvas[0] );
|
|
gr_setcolor( VR_WHITE_INDEX );
|
|
gr_scanline( 0, quarter, height-1 );
|
|
gr_setcolor( VR_BLACK_INDEX );
|
|
gr_scanline( quarter, width-1, height-1 );
|
|
|
|
if ( VR_eye_switch )
|
|
gr_set_current_canvas( &RenderCanvas[0] );
|
|
else
|
|
gr_set_current_canvas( &RenderCanvas[1] );
|
|
gr_setcolor( VR_WHITE_INDEX );
|
|
gr_scanline( 0, quarter*3, height-1 );
|
|
gr_setcolor( VR_BLACK_INDEX );
|
|
gr_scanline( quarter*3, width-1, height-1 );
|
|
}
|
|
|
|
// Copy left eye, then right eye
|
|
if ( VR_screen_flags&VRF_USE_PAGING )
|
|
VR_current_page = !VR_current_page;
|
|
else
|
|
VR_current_page = 0;
|
|
gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
|
|
|
|
//NEWVR
|
|
|
|
if ( VR_eye_offset_changed > 0 ) {
|
|
VR_eye_offset_changed--;
|
|
gr_clear_canvas(0);
|
|
}
|
|
|
|
sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
|
|
sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
|
|
|
|
// Copy left eye, then right eye
|
|
gr_bitblt_dest_step_shift = 1; // Skip every other scanline.
|
|
|
|
if (VR_render_mode == VR_INTERLACED ) {
|
|
if ( actual_eye_offset > 0 ) {
|
|
int xoff = labs(actual_eye_offset);
|
|
gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
|
|
gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
|
|
} else if ( actual_eye_offset < 0 ) {
|
|
int xoff = labs(actual_eye_offset);
|
|
gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
|
|
gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
|
|
} else {
|
|
gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
|
|
gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
|
|
}
|
|
} else if (VR_render_mode == VR_AREA_DET) {
|
|
// VFX copy
|
|
gr_bm_ubitblt( dw, dh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
|
|
gr_bm_ubitblt( dw, dh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
|
|
} else {
|
|
Int3(); // Huh?
|
|
}
|
|
|
|
gr_bitblt_dest_step_shift = 0;
|
|
|
|
//if ( Game_vfx_flag )
|
|
// vfx_set_page(VR_current_page); // 0 or 1
|
|
//else
|
|
if ( VR_screen_flags&VRF_USE_PAGING ) {
|
|
gr_wait_for_retrace = 0;
|
|
|
|
// Added by Samir from John's code
|
|
if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) ) {
|
|
int old_x, old_y, new_x;
|
|
old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
|
|
old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
|
|
new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
|
|
new_x += old_x/4;
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
|
|
gr_show_canvas( &VR_screen_pages[VR_current_page] );
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
|
|
} else {
|
|
gr_show_canvas( &VR_screen_pages[VR_current_page] );
|
|
}
|
|
gr_wait_for_retrace = 1;
|
|
}
|
|
grd_curscreen->sc_aspect=save_aspect;
|
|
}
|
|
#endif
|
|
ubyte RenderingType=0;
|
|
ubyte DemoDoingRight=0,DemoDoingLeft=0;
|
|
extern ubyte DemoDoRight,DemoDoLeft;
|
|
extern object DemoRightExtra,DemoLeftExtra;
|
|
|
|
char DemoWBUType[]={0,WBU_MISSILE,WBU_MISSILE,WBU_REAR,WBU_ESCORT,WBU_MARKER,WBU_MISSILE};
|
|
char DemoRearCheck[]={0,0,0,1,0,0,0};
|
|
char *DemoExtraMessage[]={"PLAYER","GUIDED","MISSILE","REAR","GUIDE-BOT","MARKER","SHIP"};
|
|
|
|
extern char guidebot_name[];
|
|
|
|
void show_extra_views()
|
|
{
|
|
int did_missile_view=0;
|
|
int save_newdemo_state = Newdemo_state;
|
|
int w;
|
|
|
|
if (Newdemo_state==ND_STATE_PLAYBACK)
|
|
{
|
|
if (DemoDoLeft)
|
|
{
|
|
DemoDoingLeft=DemoDoLeft;
|
|
|
|
if (DemoDoLeft==3)
|
|
do_cockpit_window_view(0,ConsoleObject,1,WBU_REAR,"REAR");
|
|
else
|
|
do_cockpit_window_view(0,&DemoLeftExtra,DemoRearCheck[DemoDoLeft],DemoWBUType[DemoDoLeft],DemoExtraMessage[DemoDoLeft]);
|
|
}
|
|
else
|
|
do_cockpit_window_view(0,NULL,0,WBU_WEAPON,NULL);
|
|
|
|
if (DemoDoRight)
|
|
{
|
|
DemoDoingRight=DemoDoRight;
|
|
|
|
if (DemoDoRight==3)
|
|
do_cockpit_window_view(1,ConsoleObject,1,WBU_REAR,"REAR");
|
|
else
|
|
do_cockpit_window_view(1,&DemoRightExtra,DemoRearCheck[DemoDoRight],DemoWBUType[DemoDoRight],DemoExtraMessage[DemoDoRight]);
|
|
}
|
|
else
|
|
do_cockpit_window_view(1,NULL,0,WBU_WEAPON,NULL);
|
|
|
|
DemoDoLeft=DemoDoRight=0;
|
|
DemoDoingLeft=DemoDoingRight=0;
|
|
|
|
return;
|
|
}
|
|
|
|
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]) {
|
|
if (Guided_in_big_window)
|
|
{
|
|
RenderingType=6+(1<<4);
|
|
do_cockpit_window_view(1,Viewer,0,WBU_MISSILE,"SHIP");
|
|
}
|
|
else
|
|
{
|
|
RenderingType=1+(1<<4);
|
|
do_cockpit_window_view(1,Guided_missile[Player_num],0,WBU_GUIDED,"GUIDED");
|
|
}
|
|
|
|
did_missile_view=1;
|
|
}
|
|
else {
|
|
|
|
if (Guided_missile[Player_num]) { //used to be active
|
|
if (!Guided_in_big_window)
|
|
do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
|
|
Guided_missile[Player_num] = NULL;
|
|
}
|
|
|
|
if (Missile_viewer) { //do missile view
|
|
static int mv_sig=-1;
|
|
if (mv_sig == -1)
|
|
mv_sig = Missile_viewer->signature;
|
|
if (Missile_view_enabled && Missile_viewer->type!=OBJ_NONE && Missile_viewer->signature == mv_sig) {
|
|
RenderingType=2+(1<<4);
|
|
do_cockpit_window_view(1,Missile_viewer,0,WBU_MISSILE,"MISSILE");
|
|
did_missile_view=1;
|
|
}
|
|
else {
|
|
Missile_viewer = NULL;
|
|
mv_sig = -1;
|
|
RenderingType=255;
|
|
do_cockpit_window_view(1,NULL,0,WBU_STATIC,NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (w=0;w<2;w++) {
|
|
|
|
if (w==1 && did_missile_view)
|
|
continue; //if showing missile view in right window, can't show anything else
|
|
|
|
//show special views if selected
|
|
switch (Cockpit_3d_view[w]) {
|
|
case CV_NONE:
|
|
RenderingType=255;
|
|
do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
|
|
break;
|
|
case CV_REAR:
|
|
if (Rear_view) { //if big window is rear view, show front here
|
|
RenderingType=3+(w<<4);
|
|
do_cockpit_window_view(w,ConsoleObject,0,WBU_REAR,"FRONT");
|
|
}
|
|
else { //show normal rear view
|
|
RenderingType=3+(w<<4);
|
|
do_cockpit_window_view(w,ConsoleObject,1,WBU_REAR,"REAR");
|
|
}
|
|
break;
|
|
case CV_ESCORT: {
|
|
object *buddy;
|
|
buddy = find_escort();
|
|
if (buddy == NULL) {
|
|
do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
|
|
Cockpit_3d_view[w] = CV_NONE;
|
|
}
|
|
else {
|
|
RenderingType=4+(w<<4);
|
|
do_cockpit_window_view(w,buddy,0,WBU_ESCORT,guidebot_name);
|
|
}
|
|
break;
|
|
}
|
|
#ifdef NETWORK
|
|
case CV_COOP: {
|
|
int player = Coop_view_player[w];
|
|
|
|
RenderingType=255; // don't handle coop stuff
|
|
|
|
if (player!=-1 && Players[player].connected && ((Game_mode & GM_MULTI_COOP) || ((Game_mode & GM_TEAM) && (get_team(player) == get_team(Player_num)))))
|
|
do_cockpit_window_view(w,&Objects[Players[Coop_view_player[w]].objnum],0,WBU_COOP,Players[Coop_view_player[w]].callsign);
|
|
else {
|
|
do_cockpit_window_view(w,NULL,0,WBU_WEAPON,NULL);
|
|
Cockpit_3d_view[w] = CV_NONE;
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
case CV_MARKER: {
|
|
char label[10];
|
|
RenderingType=5+(w<<4);
|
|
if (Marker_viewer_num[w] == -1 || MarkerObject[Marker_viewer_num[w]] == -1) {
|
|
Cockpit_3d_view[w] = CV_NONE;
|
|
break;
|
|
}
|
|
sprintf(label,"Marker %d",Marker_viewer_num[w]+1);
|
|
do_cockpit_window_view(w,&Objects[MarkerObject[Marker_viewer_num[w]]],0,WBU_MARKER,label);
|
|
break;
|
|
}
|
|
default:
|
|
Int3(); //invalid window type
|
|
}
|
|
}
|
|
RenderingType=0;
|
|
Newdemo_state = save_newdemo_state;
|
|
}
|
|
|
|
int BigWindowSwitch=0;
|
|
extern int force_cockpit_redraw;
|
|
#ifndef MACINTOSH
|
|
extern ubyte * Game_cockpit_copy_code;
|
|
#else
|
|
extern ubyte Game_cockpit_copy_code;
|
|
#endif
|
|
|
|
void draw_guided_crosshair(void);
|
|
|
|
#ifdef MACINTOSH
|
|
// special code to render a frame w/hw acceleration
|
|
|
|
// next routine is called as a callback from the current hardware engine being used. The
|
|
// routine is called once all of the accelerated drawing is done. We now overlay the
|
|
// backbuffer with hud stuff.
|
|
|
|
void pa_mac_render_extras( void )
|
|
{
|
|
grs_canvas Screen_3d_window;
|
|
|
|
gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_x,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_y,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_w,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_h);
|
|
|
|
gr_set_current_canvas( &Screen_3d_window ); // set to current screen
|
|
|
|
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)
|
|
{
|
|
char *msg = "Guided Missile View";
|
|
int w,h,aw;
|
|
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
|
|
gr_get_string_size(msg, &w, &h, &aw );
|
|
|
|
gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
|
|
|
|
draw_guided_crosshair();
|
|
|
|
HUD_render_message_frame();
|
|
}
|
|
else
|
|
{
|
|
game_draw_hud_stuff(); // draw hud stuff when not doing missle view in big window
|
|
}
|
|
|
|
if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
|
|
extern char *Pause_msg;
|
|
ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
|
|
|
|
WIN(Int3()); // Not supported yet.
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
|
|
show_boxed_message(Pause_msg);
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void pa_mac_game_render_frame( void )
|
|
{
|
|
Assert ( !Scanline_double );
|
|
Assert ( PAEnabled );
|
|
|
|
gr_set_current_canvas(&VR_render_sub_buffer[0]); // set up the right canvas so rendering is done to correct size
|
|
|
|
pa_render_start();
|
|
|
|
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)
|
|
{
|
|
char *msg = "Guided Missile View";
|
|
object *viewer_save = Viewer;
|
|
int w,h,aw;
|
|
|
|
if (Cockpit_mode==CM_FULL_COCKPIT) {
|
|
BigWindowSwitch=1;
|
|
force_cockpit_redraw=1;
|
|
Cockpit_mode=CM_STATUS_BAR;
|
|
pa_render_end();
|
|
return;
|
|
}
|
|
|
|
Viewer = Guided_missile[Player_num];
|
|
update_rendered_data(0, Viewer, 0, 0);
|
|
render_frame(0, 0);
|
|
wake_up_rendered_objects(Viewer, 0);
|
|
Viewer = viewer_save;
|
|
}
|
|
else
|
|
{
|
|
if (BigWindowSwitch)
|
|
{
|
|
force_cockpit_redraw=1;
|
|
Cockpit_mode=CM_FULL_COCKPIT;
|
|
BigWindowSwitch=0;
|
|
pa_render_end();
|
|
return;
|
|
}
|
|
|
|
update_rendered_data(0, Viewer, Rear_view, 0);
|
|
render_frame(0, 0);
|
|
}
|
|
|
|
if (Cockpit_mode == CM_FULL_SCREEN)
|
|
{
|
|
show_extra_views();
|
|
}
|
|
|
|
|
|
pa_render_end();
|
|
|
|
// NOTE: Hud stuff is drawn using a RAVE call back which draws onto the back buffer
|
|
// after rendering finishes but before the page flip
|
|
|
|
if (Cockpit_mode != CM_FULL_SCREEN)
|
|
{
|
|
show_extra_views(); //missile view, buddy bot, etc.
|
|
}
|
|
|
|
// Draw Gauges straight to screen
|
|
if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
|
|
{
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
{
|
|
Game_mode = Newdemo_game_mode;
|
|
}
|
|
|
|
Current_display_mode = 1;
|
|
render_gauges();
|
|
Current_display_mode = -1;
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
{
|
|
Game_mode = GM_NORMAL;
|
|
}
|
|
}
|
|
}
|
|
#endif // MACINTOSH
|
|
|
|
|
|
//render a frame for the game
|
|
// WINDOWS:
|
|
// will render everything to dd_VR_render_sub_buffer
|
|
// which all leads to the dd_VR_offscreen_buffer
|
|
void game_render_frame_mono(void)
|
|
{
|
|
WINDOS (
|
|
dd_grs_canvas Screen_3d_window,
|
|
grs_canvas Screen_3d_window
|
|
);
|
|
int no_draw_hud=0;
|
|
|
|
#if defined(MACINTOSH)
|
|
if ( PAEnabled ) {
|
|
pa_mac_game_render_frame();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
WINDOS (
|
|
dd_gr_init_sub_canvas(&Screen_3d_window, &dd_VR_screen_pages[0],
|
|
dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_x,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_y,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_h),
|
|
gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_x,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_y,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_w,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_h)
|
|
);
|
|
|
|
if ( Game_double_buffer ) {
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
|
|
gr_set_current_canvas(&VR_render_sub_buffer[0])
|
|
);
|
|
}
|
|
else {
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&Screen_3d_window),
|
|
gr_set_current_canvas(&Screen_3d_window)
|
|
);
|
|
}
|
|
|
|
#if defined(POLY_ACC) && !defined(MACINTOSH) // begin s3 relocation of cockpit drawing.
|
|
|
|
pa_flush();
|
|
|
|
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)
|
|
no_draw_hud = 1;
|
|
|
|
if (!no_draw_hud) {
|
|
WIN(DDGRLOCK(dd_grd_curcanv));
|
|
game_draw_hud_stuff();
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
}
|
|
|
|
show_extra_views(); //missile view, buddy bot, etc.
|
|
pa_dma_poll();
|
|
|
|
if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
|
|
extern char *Pause_msg;
|
|
ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
|
|
|
|
WIN(Int3()); // Not supported yet.
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
|
|
show_boxed_message(Pause_msg);
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
|
|
}
|
|
|
|
if ( Game_double_buffer ) { //copy to visible screen
|
|
if ( !Game_cockpit_copy_code ) {
|
|
if ( VR_screen_flags&VRF_USE_PAGING ) {
|
|
VR_current_page = !VR_current_page;
|
|
gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
|
|
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 );
|
|
gr_wait_for_retrace = 0;
|
|
gr_show_canvas( &VR_screen_pages[VR_current_page] );
|
|
gr_wait_for_retrace = 1;
|
|
} else {
|
|
#ifdef POLY_ACC //$$
|
|
pa_about_to_flip();
|
|
#endif
|
|
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,
|
|
VR_render_sub_buffer[0].cv_bitmap.bm_x, VR_render_sub_buffer[0].cv_bitmap.bm_y,
|
|
&VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap
|
|
);
|
|
}
|
|
} else {
|
|
#ifdef POLY_ACC //$$
|
|
pa_about_to_flip();
|
|
#endif
|
|
gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
|
|
}
|
|
}
|
|
|
|
if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
Game_mode = Newdemo_game_mode;
|
|
|
|
render_gauges();
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
Game_mode = GM_NORMAL;
|
|
}
|
|
|
|
// restore current canvas.
|
|
if ( Game_double_buffer ) {
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
|
|
gr_set_current_canvas(&VR_render_sub_buffer[0])
|
|
);
|
|
}
|
|
else {
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&Screen_3d_window),
|
|
gr_set_current_canvas(&Screen_3d_window)
|
|
);
|
|
}
|
|
|
|
#endif // end s3 relocation of cockpit drawing.
|
|
|
|
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) {
|
|
char *msg = "Guided Missile View";
|
|
object *viewer_save = Viewer;
|
|
int w,h,aw;
|
|
|
|
if (Cockpit_mode==CM_FULL_COCKPIT)
|
|
{
|
|
BigWindowSwitch=1;
|
|
force_cockpit_redraw=1;
|
|
Cockpit_mode=CM_STATUS_BAR;
|
|
return;
|
|
}
|
|
|
|
Viewer = Guided_missile[Player_num];
|
|
|
|
WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
|
|
{
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double)
|
|
FontHires = 0;
|
|
#endif
|
|
update_rendered_data(0, Viewer, 0, 0);
|
|
render_frame(0, 0);
|
|
|
|
wake_up_rendered_objects(Viewer, 0);
|
|
Viewer = viewer_save;
|
|
|
|
gr_set_curfont( GAME_FONT ); //GAME_FONT );
|
|
gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
|
|
gr_get_string_size(msg, &w, &h, &aw );
|
|
|
|
gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, 3, msg );
|
|
|
|
draw_guided_crosshair();
|
|
}
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
|
|
HUD_render_message_frame();
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double)
|
|
FontHires = 1;
|
|
#endif
|
|
|
|
no_draw_hud=1;
|
|
}
|
|
else
|
|
{
|
|
if (BigWindowSwitch)
|
|
{
|
|
force_cockpit_redraw=1;
|
|
Cockpit_mode=CM_FULL_COCKPIT;
|
|
BigWindowSwitch=0;
|
|
return;
|
|
}
|
|
WIN(DDGRLOCK(dd_grd_curcanv)); // Must lock DD canvas!!!
|
|
update_rendered_data(0, Viewer, Rear_view, 0);
|
|
render_frame(0, 0);
|
|
#if defined(POLY_ACC) && !defined(MACINTOSH) // dma stuff not supported on mac via RAVE
|
|
pa_dma_poll();
|
|
#endif
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
}
|
|
|
|
if ( Game_double_buffer ) {
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&dd_VR_render_sub_buffer[0]),
|
|
gr_set_current_canvas(&VR_render_sub_buffer[0])
|
|
);
|
|
}
|
|
else {
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&Screen_3d_window),
|
|
gr_set_current_canvas(&Screen_3d_window)
|
|
);
|
|
}
|
|
|
|
#if !defined(POLY_ACC) || defined(MACINTOSH)
|
|
|
|
if (!no_draw_hud) {
|
|
WIN(DDGRLOCK(dd_grd_curcanv));
|
|
game_draw_hud_stuff();
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
}
|
|
|
|
show_extra_views(); //missile view, buddy bot, etc.
|
|
|
|
#ifdef WINDOWS
|
|
if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
|
|
extern char *Pause_msg;
|
|
// LPDIRECTDRAWSURFACE save_dds = dd_VR_screen_pages[VR_current_page].lpdds;
|
|
|
|
// dd_VR_screen_pages[VR_current_page].lpdds = dd_VR_render_buffer[VR_current_page].lpdds;
|
|
show_boxed_message(Pause_msg);
|
|
// dd_VR_screen_pages[VR_current_page].lpdds = save_dds;
|
|
}
|
|
#else
|
|
if (Game_paused) { //render pause message over off-screen 3d (to minimize flicker)
|
|
extern char *Pause_msg;
|
|
ubyte *save_data = VR_screen_pages[VR_current_page].cv_bitmap.bm_data;
|
|
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_data=VR_render_buffer[VR_current_page].cv_bitmap.bm_data;
|
|
show_boxed_message(Pause_msg);
|
|
VR_screen_pages[VR_current_page].cv_bitmap.bm_data=save_data;
|
|
}
|
|
#endif
|
|
|
|
if ( Game_double_buffer ) { //copy to visible screen
|
|
if ( !Game_cockpit_copy_code ) {
|
|
if ( VR_screen_flags&VRF_USE_PAGING ) {
|
|
VR_current_page = !VR_current_page;
|
|
#ifdef WINDOWS
|
|
dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]);
|
|
dd_gr_flip();
|
|
#else
|
|
gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
|
|
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 );
|
|
gr_wait_for_retrace = 0;
|
|
gr_show_canvas( &VR_screen_pages[VR_current_page] );
|
|
gr_wait_for_retrace = 1;
|
|
#endif
|
|
} else {
|
|
#ifdef MACINTOSH
|
|
if (Scanline_double)
|
|
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 );
|
|
else
|
|
#endif // NOTE LINK TO ABOVE IF
|
|
#ifdef WINDOWS
|
|
if (GRMODEINFO(emul) || GRMODEINFO(modex) || GRMODEINFO(dbuf))
|
|
// From render buffer to screen buffer.
|
|
dd_gr_blt_notrans(&dd_VR_render_sub_buffer[0],
|
|
0,0,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_w,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_h,
|
|
dd_grd_screencanv,
|
|
dd_VR_render_sub_buffer[0].xoff,
|
|
dd_VR_render_sub_buffer[0].yoff,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_w,
|
|
dd_VR_render_sub_buffer[0].canvas.cv_h);
|
|
|
|
DDGRRESTORE;
|
|
// Puts back canvas to front canvas by blt or flip
|
|
if (GRMODEINFO(modex)) {
|
|
//@@VR_current_page = !VR_current_page;
|
|
//@@dd_gr_flip();
|
|
win_flip = 1;
|
|
}
|
|
#else
|
|
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[0].cv_bitmap );
|
|
#endif
|
|
|
|
#ifdef _3DFX
|
|
_3dfx_BufferSwap();
|
|
#endif
|
|
#ifdef OGL
|
|
ogl_swap_buffers();
|
|
#endif
|
|
|
|
}
|
|
} else {
|
|
#if 1 //def MACINTOSH
|
|
gr_ibitblt( &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Scanline_double );
|
|
#else
|
|
#ifndef WINDOWS
|
|
gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
|
|
#else
|
|
win_do_emul_ibitblt( &dd_VR_render_sub_buffer[0], dd_grd_screencanv);
|
|
DDGRRESTORE;
|
|
if (GRMODEINFO(modex)) {
|
|
//@@VR_current_page = !VR_current_page;
|
|
//@@dd_gr_flip();
|
|
win_flip = 1;
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
Game_mode = Newdemo_game_mode;
|
|
|
|
render_gauges();
|
|
|
|
if ( (Newdemo_state == ND_STATE_PLAYBACK) )
|
|
Game_mode = GM_NORMAL;
|
|
}
|
|
|
|
#ifdef WINDOWS
|
|
if (win_flip) {
|
|
VR_current_page = !VR_current_page;
|
|
dd_gr_flip();
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
gr_update();
|
|
}
|
|
|
|
void toggle_cockpit()
|
|
{
|
|
int new_mode;
|
|
|
|
switch (Cockpit_mode) {
|
|
|
|
case CM_FULL_COCKPIT: {
|
|
int max_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR+(Current_display_mode?(Num_cockpits/2):0)].index].bm_h;
|
|
if (Game_window_h > max_h) //too big for statusbar
|
|
new_mode = CM_FULL_SCREEN;
|
|
else
|
|
new_mode = CM_STATUS_BAR;
|
|
break;
|
|
}
|
|
|
|
case CM_STATUS_BAR:
|
|
case CM_FULL_SCREEN:
|
|
if (Rear_view)
|
|
return;
|
|
new_mode = CM_FULL_COCKPIT;
|
|
break;
|
|
|
|
case CM_REAR_VIEW:
|
|
case CM_LETTERBOX:
|
|
default:
|
|
return; //do nothing
|
|
break;
|
|
|
|
}
|
|
|
|
select_cockpit(new_mode);
|
|
HUD_clear_messages();
|
|
write_player_file();
|
|
}
|
|
|
|
#ifndef MACINTOSH
|
|
#define WINDOW_W_DELTA ((max_window_w / 16)&~1) //24 //20
|
|
#define WINDOW_H_DELTA ((max_window_h / 16)&~1) //12 //10
|
|
|
|
#define WINDOW_MIN_W ((max_window_w * 10) / 22) //160
|
|
#define WINDOW_MIN_H ((max_window_h * 10) / 22)
|
|
#else
|
|
//#define WINDOW_W_DELTA 32
|
|
//#define WINDOW_H_DELTA 16
|
|
|
|
#define WINDOW_W_DELTA ((max_window_w / 16) & ~15) // double word aligned
|
|
#define WINDOW_H_DELTA ((max_window_h / 16) & ~15) // double word aligned
|
|
|
|
#define WINDOW_MIN_W (max_window_w-(WINDOW_W_DELTA*11))
|
|
#define WINDOW_MIN_H (max_window_h-(WINDOW_H_DELTA*11))
|
|
#endif
|
|
|
|
void grow_window()
|
|
{
|
|
if (Cockpit_mode == CM_FULL_COCKPIT) {
|
|
Game_window_h = max_window_h;
|
|
Game_window_w = max_window_w;
|
|
toggle_cockpit();
|
|
HUD_init_message("Press F3 to return to Cockpit mode");
|
|
return;
|
|
}
|
|
|
|
if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
|
|
return;
|
|
|
|
if (Game_window_h>=max_window_h || Game_window_w>=max_window_w) {
|
|
//Game_window_w = max_window_w;
|
|
//Game_window_h = max_window_h;
|
|
select_cockpit(CM_FULL_SCREEN);
|
|
} else {
|
|
//int x,y;
|
|
|
|
Game_window_w += WINDOW_W_DELTA;
|
|
Game_window_h += WINDOW_H_DELTA;
|
|
|
|
#ifdef MACINTOSH // horrible hack to ensure that height is even to satisfy pixel doubling blitter
|
|
if ( Scanline_double && (Game_window_h & 1) )
|
|
Game_window_h--;
|
|
#endif
|
|
|
|
if (Game_window_h > max_window_h)
|
|
Game_window_h = max_window_h;
|
|
|
|
if (Game_window_w > max_window_w)
|
|
Game_window_w = max_window_w;
|
|
|
|
Game_window_x = (max_window_w - Game_window_w)/2;
|
|
Game_window_y = (max_window_h - Game_window_h)/2;
|
|
|
|
game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
|
|
}
|
|
|
|
HUD_clear_messages(); // @mk, 11/11/94
|
|
|
|
write_player_file();
|
|
}
|
|
|
|
// grs_bitmap background_bitmap; already declared in line 434 (samir 4/10/94)
|
|
|
|
extern grs_bitmap background_bitmap;
|
|
|
|
void copy_background_rect(int left,int top,int right,int bot)
|
|
{
|
|
grs_bitmap *bm = &background_bitmap;
|
|
int x,y;
|
|
int tile_left,tile_right,tile_top,tile_bot;
|
|
int ofs_x,ofs_y;
|
|
int dest_x,dest_y;
|
|
|
|
if (right < left || bot < top)
|
|
return;
|
|
|
|
tile_left = left / bm->bm_w;
|
|
tile_right = right / bm->bm_w;
|
|
tile_top = top / bm->bm_h;
|
|
tile_bot = bot / bm->bm_h;
|
|
|
|
ofs_y = top % bm->bm_h;
|
|
dest_y = top;
|
|
|
|
WIN(DDGRLOCK(dd_grd_curcanv))
|
|
{
|
|
for (y=tile_top;y<=tile_bot;y++) {
|
|
int w,h;
|
|
|
|
ofs_x = left % bm->bm_w;
|
|
dest_x = left;
|
|
|
|
//h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
|
|
h = min(bot-dest_y+1,bm->bm_h-ofs_y);
|
|
|
|
for (x=tile_left;x<=tile_right;x++) {
|
|
|
|
//w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
|
|
w = min(right-dest_x+1,bm->bm_w-ofs_x);
|
|
|
|
gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
|
|
&background_bitmap,&grd_curcanv->cv_bitmap);
|
|
|
|
ofs_x = 0;
|
|
dest_x += w;
|
|
}
|
|
|
|
ofs_y = 0;
|
|
dest_y += h;
|
|
}
|
|
}
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
|
|
}
|
|
|
|
#ifdef WINDOWS
|
|
int force_background_fill=0;
|
|
#endif
|
|
|
|
//fills int the background surrounding the 3d window
|
|
void fill_background()
|
|
{
|
|
int x,y,w,h,dx,dy;
|
|
|
|
x = Game_window_x;
|
|
y = Game_window_y;
|
|
w = Game_window_w;
|
|
h = Game_window_h;
|
|
|
|
dx = x;
|
|
dy = y;
|
|
|
|
WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page])
|
|
);
|
|
copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
|
|
copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
|
|
copy_background_rect(x,y-dy,x+w-1,y-1);
|
|
copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
|
|
|
|
#ifdef WINDOWS
|
|
if (GRMODEINFO(modex)) {
|
|
copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
|
|
copy_background_rect(x+w,y-dy,grd_curcanv->cv_w-1,y+h+dy-1);
|
|
copy_background_rect(x,y-dy,x+w-1,y-1);
|
|
copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
|
|
}
|
|
#endif
|
|
|
|
if (VR_screen_flags & VRF_USE_PAGING) {
|
|
WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
|
|
);
|
|
copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
|
|
copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
|
|
copy_background_rect(x,y-dy,x+w-1,y-1);
|
|
copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
|
|
}
|
|
|
|
#ifdef WINDOWS
|
|
if (GRMODEINFO(modex) && force_background_fill==0) //double-buffered
|
|
force_background_fill=2;
|
|
#endif
|
|
}
|
|
|
|
void shrink_window()
|
|
{
|
|
#ifdef WINDOWS
|
|
//When you shrink the window twice in two frames, the background doens't
|
|
//restore properly. So this hack keeps you from shrinking the window
|
|
//before two frames have been drawn
|
|
static int last_shrink_framecount=-1;
|
|
if (FrameCount - last_shrink_framecount < 2)
|
|
return;
|
|
last_shrink_framecount = FrameCount;
|
|
#endif
|
|
|
|
mprintf((0,"%d ",FrameCount));
|
|
|
|
// mprintf ((0,"W=%d H=%d\n",Game_window_w,Game_window_h));
|
|
|
|
if (Cockpit_mode == CM_FULL_COCKPIT && (VR_screen_flags & VRF_ALLOW_COCKPIT)) {
|
|
Game_window_h = max_window_h;
|
|
Game_window_w = max_window_w;
|
|
//!!toggle_cockpit();
|
|
select_cockpit(CM_STATUS_BAR);
|
|
// shrink_window();
|
|
// shrink_window();
|
|
HUD_init_message("Press F3 to return to Cockpit mode");
|
|
write_player_file();
|
|
return;
|
|
}
|
|
|
|
if (Cockpit_mode == CM_FULL_SCREEN && (VR_screen_flags & VRF_ALLOW_COCKPIT))
|
|
{
|
|
//Game_window_w = max_window_w;
|
|
//Game_window_h = max_window_h;
|
|
select_cockpit(CM_STATUS_BAR);
|
|
write_player_file();
|
|
return;
|
|
}
|
|
|
|
if (Cockpit_mode != CM_STATUS_BAR && (VR_screen_flags & VRF_ALLOW_COCKPIT))
|
|
return;
|
|
|
|
mprintf ((0,"Cockpit mode=%d\n",Cockpit_mode));
|
|
|
|
if (Game_window_w > WINDOW_MIN_W) {
|
|
//int x,y;
|
|
|
|
Game_window_w -= WINDOW_W_DELTA;
|
|
Game_window_h -= WINDOW_H_DELTA;
|
|
|
|
|
|
mprintf ((0,"NewW=%d NewH=%d VW=%d maxH=%d\n",Game_window_w,Game_window_h,max_window_w,max_window_h));
|
|
|
|
if ( Game_window_w < WINDOW_MIN_W )
|
|
Game_window_w = WINDOW_MIN_W;
|
|
|
|
if ( Game_window_h < WINDOW_MIN_H )
|
|
Game_window_h = WINDOW_MIN_H;
|
|
|
|
#ifdef MACINTOSH // horrible hack to ensure that height is even to satisfy pixel doubling blitter
|
|
if ( Scanline_double && (Game_window_h & 1) )
|
|
Game_window_h--;
|
|
#endif
|
|
|
|
Game_window_x = (max_window_w - Game_window_w)/2;
|
|
Game_window_y = (max_window_h - Game_window_h)/2;
|
|
|
|
fill_background();
|
|
|
|
game_init_render_sub_buffers( Game_window_x, Game_window_y, Game_window_w, Game_window_h );
|
|
HUD_clear_messages();
|
|
write_player_file();
|
|
}
|
|
|
|
}
|
|
|
|
int last_drawn_cockpit[2] = { -1, -1 };
|
|
|
|
// This actually renders the new cockpit onto the screen.
|
|
void update_cockpits(int force_redraw)
|
|
{
|
|
//int x, y, w, h;
|
|
|
|
if (Cockpit_mode != last_drawn_cockpit[VR_current_page] || force_redraw )
|
|
last_drawn_cockpit[VR_current_page] = Cockpit_mode;
|
|
else
|
|
return;
|
|
|
|
//Redraw the on-screen cockpit bitmaps
|
|
if (VR_render_mode != VR_NONE ) return;
|
|
|
|
switch( Cockpit_mode ) {
|
|
case CM_FULL_COCKPIT:
|
|
case CM_REAR_VIEW:
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page])
|
|
);
|
|
PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)]);
|
|
|
|
WIN(DDGRLOCK(dd_grd_curcanv));
|
|
gr_ubitmapm(0,0, &GameBitmaps[cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)].index]);
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
break;
|
|
|
|
case CM_FULL_SCREEN:
|
|
Game_window_x = (max_window_w - Game_window_w)/2;
|
|
Game_window_y = (max_window_h - Game_window_h)/2;
|
|
fill_background();
|
|
break;
|
|
|
|
case CM_STATUS_BAR:
|
|
|
|
WINDOS ( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page])
|
|
);
|
|
|
|
PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)]);
|
|
|
|
WIN(DDGRLOCK(dd_grd_curcanv));
|
|
gr_ubitmapm(0,max_window_h,&GameBitmaps[cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)].index]);
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
|
|
#ifdef MACINTOSH // hideously horrible hack to put grey line 1 scanline above because of pixel doubling "oddness"
|
|
if (Scanline_double)
|
|
{
|
|
gr_setcolor(BM_XRGB(13,13,13)); // color of top of status bar
|
|
gr_uscanline( 0, grd_curcanv->cv_w, max_window_h-1 );
|
|
}
|
|
#endif
|
|
|
|
Game_window_x = (max_window_w - Game_window_w)/2;
|
|
Game_window_y = (max_window_h - Game_window_h)/2;
|
|
fill_background();
|
|
break;
|
|
|
|
case CM_LETTERBOX:
|
|
WINDOS( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page])
|
|
);
|
|
WINDOS ( dd_gr_clear_canvas( BM_XRGB(0,0,0) ),
|
|
gr_clear_canvas( BM_XRGB(0,0,0) ) );
|
|
|
|
// In a modex mode, clear the other buffer.
|
|
if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page^1]);
|
|
gr_clear_canvas( BM_XRGB(0,0,0) );
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
WINDOS ( dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page])
|
|
);
|
|
|
|
if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
|
|
init_gauges();
|
|
|
|
}
|
|
|
|
|
|
void game_render_frame()
|
|
{
|
|
set_screen_mode( SCREEN_GAME );
|
|
|
|
update_cockpits(0);
|
|
|
|
#ifdef WINDOWS
|
|
if (force_background_fill) {
|
|
fill_background();
|
|
force_background_fill--;
|
|
}
|
|
#endif
|
|
|
|
play_homing_warning();
|
|
|
|
if (VR_render_mode == VR_NONE )
|
|
game_render_frame_mono();
|
|
/* else
|
|
game_render_frame_stereo();
|
|
*/
|
|
|
|
// Make sure palette is faded in
|
|
stop_time();
|
|
gr_palette_fade_in( gr_palette, 32, 0 );
|
|
start_time();
|
|
|
|
FrameCount++;
|
|
}
|
|
|
|
extern int Color_0_31_0;
|
|
|
|
//draw a crosshair for the guided missile
|
|
void draw_guided_crosshair(void)
|
|
{
|
|
int x,y,w,h;
|
|
|
|
gr_setcolor(Color_0_31_0);
|
|
|
|
w = grd_curcanv->cv_w>>5;
|
|
if (w < 5)
|
|
w = 5;
|
|
|
|
h = i2f(w) / grd_curscreen->sc_aspect;
|
|
|
|
x = grd_curcanv->cv_w / 2;
|
|
y = grd_curcanv->cv_h / 2;
|
|
|
|
gr_scanline(x-w/2,x+w/2,y);
|
|
gr_uline(i2f(x),i2f(y-h/2),i2f(x),i2f(y+h/2));
|
|
|
|
}
|
|
|
|
typedef struct bkg {
|
|
short x, y, w, h; // The location of the menu.
|
|
grs_bitmap * bmp; // The background under the menu.
|
|
} bkg;
|
|
|
|
bkg bg = {0,0,0,0,NULL};
|
|
|
|
#define BOX_BORDER (MenuHires?60:30)
|
|
|
|
//show a message in a nice little box
|
|
void show_boxed_message(char *msg)
|
|
{
|
|
int w,h,aw;
|
|
int x,y;
|
|
|
|
WINDOS(
|
|
dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
|
|
gr_set_current_canvas(&VR_screen_pages[VR_current_page])
|
|
);
|
|
gr_set_curfont( MEDIUM1_FONT );
|
|
|
|
gr_get_string_size(msg,&w,&h,&aw);
|
|
|
|
x = (grd_curscreen->sc_w-w)/2;
|
|
y = (grd_curscreen->sc_h-h)/2;
|
|
|
|
if (bg.bmp) {
|
|
gr_free_bitmap(bg.bmp);
|
|
bg.bmp = NULL;
|
|
}
|
|
|
|
// Save the background of the display
|
|
bg.x=x; bg.y=y; bg.w=w; bg.h=h;
|
|
|
|
#if defined(POLY_ACC)
|
|
bg.bmp = gr_create_bitmap2( w+BOX_BORDER, h+BOX_BORDER, grd_curcanv->cv_bitmap.bm_type, NULL );
|
|
#else
|
|
bg.bmp = gr_create_bitmap( w+BOX_BORDER, h+BOX_BORDER );
|
|
#endif
|
|
|
|
WIN( DDGRLOCK(dd_grd_curcanv));
|
|
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 );
|
|
WIN( DDGRUNLOCK(dd_grd_curcanv));
|
|
|
|
nm_draw_background(x-BOX_BORDER/2,y-BOX_BORDER/2,x+w+BOX_BORDER/2-1,y+h+BOX_BORDER/2-1);
|
|
|
|
gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
|
|
|
|
WIN( DDGRLOCK(dd_grd_curcanv));
|
|
gr_ustring( 0x8000, y, msg );
|
|
WIN( DDGRUNLOCK(dd_grd_curcanv));
|
|
WIN( DDGRRESTORE);
|
|
}
|
|
|
|
void clear_boxed_message()
|
|
{
|
|
|
|
if (bg.bmp) {
|
|
|
|
WIN(DDGRLOCK(dd_grd_curcanv));
|
|
gr_bitmap(bg.x-BOX_BORDER/2, bg.y-BOX_BORDER/2, bg.bmp);
|
|
WIN(DDGRUNLOCK(dd_grd_curcanv));
|
|
WIN(DDGRRESTORE);
|
|
|
|
gr_free_bitmap(bg.bmp);
|
|
bg.bmp = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef WINDOWS
|
|
void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest)
|
|
{
|
|
ubyte *src_data;
|
|
ubyte *dest_data;
|
|
int line, span;
|
|
|
|
|
|
WIN(DDGRLOCK(csrc));
|
|
WIN(DDGRLOCK(cdest));
|
|
src_data = csrc->canvas.cv_bitmap.bm_data;
|
|
dest_data = cdest->canvas.cv_bitmap.bm_data;
|
|
|
|
// mprintf((0, "Render Ptr: %x; Dest Ptr: %x;\n",src_data, dest_data));
|
|
|
|
for (line = 0; line < 480; line++,
|
|
dest_data += cdest->canvas.cv_bitmap.bm_rowsize)
|
|
{
|
|
cockpit_span_line *sline;
|
|
|
|
sline = &win_cockpit_mask[line];
|
|
|
|
if (!sline->num) continue;
|
|
if (sline->num == 255) break;
|
|
for (span = 0; span < sline->num; span++)
|
|
{
|
|
if ((sline->span[span].xmax-sline->span[span].xmin+1) < 10) {
|
|
gr_winckpit_blt_span(sline->span[span].xmin,
|
|
sline->span[span].xmax,
|
|
src_data, dest_data);
|
|
}
|
|
else {
|
|
gr_winckpit_blt_span_long(sline->span[span].xmin,
|
|
sline->span[span].xmax,
|
|
src_data, dest_data);
|
|
}
|
|
}
|
|
src_data += csrc->canvas.cv_bitmap.bm_rowsize;
|
|
}
|
|
WIN(DDGRUNLOCK(cdest));
|
|
WIN(DDGRUNLOCK(csrc));
|
|
}
|
|
|
|
|
|
//@@void win_do_emul_ibitblt(dd_grs_canvas *csrc, dd_grs_canvas *cdest)
|
|
//@@{
|
|
//@@ HRESULT res;
|
|
//@@ DDBLTFX bltfx;
|
|
//@@ RECT srect, drect;
|
|
//@@
|
|
//@@// Do Render Blt to Mask Surface (dest blt 1-255)
|
|
//@@ bltfx.dwSize = sizeof(bltfx);
|
|
//@@ bltfx.ddckDestColorkey.dwColorSpaceLowValue = 1;
|
|
//@@ bltfx.ddckDestColorkey.dwColorSpaceHighValue = 255;
|
|
//@@ SetRect(&srect, 0,0, csrc->canvas.cv_w, csrc->canvas.cv_h);
|
|
//@@ SetRect(&drect, 0,0, csrc->canvas.cv_w, csrc->canvas.cv_h);
|
|
//@@
|
|
//@@ res = IDirectDrawSurface_Blt(_lpDDSMask, &drect, csrc->lpdds, &srect,
|
|
//@@ DDBLT_WAIT | DDBLT_KEYDESTOVERRIDE,
|
|
//@@ &bltfx);
|
|
//@@ if (res != DD_OK)
|
|
//@@ Error("win_ibitblt: ddraw blt to mask err: %x.\n", res);
|
|
//@@
|
|
//@@// Do Mask Blt to Screen (src blt !0)
|
|
//@@ bltfx.dwSize = sizeof(bltfx);
|
|
//@@ bltfx.ddckSrcColorkey.dwColorSpaceLowValue = 0;
|
|
//@@ bltfx.ddckSrcColorkey.dwColorSpaceHighValue = 0;
|
|
//@@
|
|
//@@ res = IDirectDrawSurface_Blt(cdest->lpdds, &drect, _lpDDSMask, &srect,
|
|
//@@ DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE,
|
|
//@@ NULL);
|
|
//@@ if (res != DD_OK)
|
|
//@@ Error("win_ibitblt: ddraw blt to screen err: %x.\n", res);
|
|
//@@}
|
|
#endif
|
|
|