#include "quakedef.h"
+cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
+cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 10 - 170
+cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
+cvar_t scr_centertime = {0, "scr_centertime","2"};
+cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
+cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
+cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
+cvar_t scr_printspeed = {0, "scr_printspeed","8"};
+cvar_t scr_2dresolution = {CVAR_SAVE, "scr_2dresolution", "1"};
+
+qboolean scr_initialized; // ready to draw
+
+float scr_con_current;
+float scr_conlines; // lines of console to display
+
+int clearconsole;
+int clearnotify;
+
+qboolean scr_disabled_for_loading;
+//qboolean scr_drawloading;
+//float scr_disabled_time;
+
static byte menuplyr_pixels[4096];
+/*
+===============================================================================
+
+CENTER PRINTING
+
+===============================================================================
+*/
+
+char scr_centerstring[1024];
+float scr_centertime_start; // for slow victory printing
+float scr_centertime_off;
+int scr_center_lines;
+int scr_erase_lines;
+int scr_erase_center;
+
+/*
+==============
+SCR_CenterPrint
+
+Called for important messages that should stay in the center of the screen
+for a few moments
+==============
+*/
+void SCR_CenterPrint (char *str)
+{
+ strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
+ scr_centertime_off = scr_centertime.value;
+ scr_centertime_start = cl.time;
+
+// count the number of lines for centering
+ scr_center_lines = 1;
+ while (*str)
+ {
+ if (*str == '\n')
+ scr_center_lines++;
+ str++;
+ }
+}
+
+
+void SCR_DrawCenterString (void)
+{
+ char *start;
+ int l;
+ int x, y;
+ int remaining;
+
+// the finale prints the characters one at a time
+ if (cl.intermission)
+ remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
+ else
+ remaining = 9999;
+
+ scr_erase_center = 0;
+ start = scr_centerstring;
+
+ if (scr_center_lines <= 4)
+ y = vid.conheight*0.35;
+ else
+ y = 48;
+
+ do
+ {
+ // scan the width of the line
+ for (l=0 ; l<40 ; l++)
+ if (start[l] == '\n' || !start[l])
+ break;
+ x = (vid.conwidth - l*8)/2;
+ if (l > 0)
+ {
+ if (remaining < l)
+ l = remaining;
+ DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
+ remaining -= l;
+ if (remaining <= 0)
+ return;
+ }
+
+ y += 8;
+
+ while (*start && *start != '\n')
+ start++;
+
+ if (!*start)
+ break;
+ start++; // skip the \n
+ } while (1);
+}
+
+void SCR_CheckDrawCenterString (void)
+{
+ if (scr_center_lines > scr_erase_lines)
+ scr_erase_lines = scr_center_lines;
+
+ scr_centertime_off -= host_frametime;
+
+ if (scr_centertime_off <= 0 && !cl.intermission)
+ return;
+ if (key_dest != key_game)
+ return;
+
+ SCR_DrawCenterString ();
+}
+
+/*
+==============
+SCR_DrawRam
+==============
+*/
+void SCR_DrawRam (void)
+{
+// if (!scr_showram.integer)
+// return;
+// DrawQ_Pic (32, 0, "ram", 0, 0, 1, 1, 1, 1, 0);
+}
+
+/*
+==============
+SCR_DrawTurtle
+==============
+*/
+void SCR_DrawTurtle (void)
+{
+ static int count;
+
+ if (cls.state != ca_connected)
+ return;
+
+ if (!scr_showturtle.integer)
+ return;
+
+ if (host_frametime < 0.1)
+ {
+ count = 0;
+ return;
+ }
+
+ count++;
+ if (count < 3)
+ return;
+
+ DrawQ_Pic (0, 0, "turtle", 0, 0, 1, 1, 1, 1, 0);
+}
+
+/*
+==============
+SCR_DrawNet
+==============
+*/
+void SCR_DrawNet (void)
+{
+ if (cls.state != ca_connected)
+ return;
+ if (realtime - cl.last_received_message < 0.3)
+ return;
+ if (cls.demoplayback)
+ return;
+
+ DrawQ_Pic (64, 0, "net", 0, 0, 1, 1, 1, 1, 0);
+}
+
+/*
+==============
+DrawPause
+==============
+*/
+void SCR_DrawPause (void)
+{
+ cachepic_t *pic;
+
+ if (cls.state != ca_connected)
+ return;
+
+ if (!scr_showpause.integer) // turn off for screenshots
+ return;
+
+ if (!cl.paused)
+ return;
+
+ pic = Draw_CachePic ("gfx/pause.lmp");
+ DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/pause.lmp", 0, 0, 1, 1, 1, 1, 0);
+}
+
+
+
+/*
+==============
+SCR_DrawLoading
+==============
+*/
+/*
+void SCR_DrawLoading (void)
+{
+ cachepic_t *pic;
+
+ if (!scr_drawloading)
+ return;
+
+ pic = Draw_CachePic ("gfx/loading.lmp");
+ DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
+}
+*/
+
+
+
+//=============================================================================
+
+
+/*
+==================
+SCR_SetUpToDrawConsole
+==================
+*/
+void SCR_SetUpToDrawConsole (void)
+{
+ Con_CheckResize ();
+
+// decide on the height of the console
+ con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
+
+ if (con_forcedup)
+ {
+ scr_conlines = vid.conheight; // full screen
+ scr_con_current = scr_conlines;
+ }
+ else if (key_dest == key_console)
+ scr_conlines = vid.conheight/2; // half screen
+ else
+ scr_conlines = 0; // none visible
+
+ if (scr_conlines < scr_con_current)
+ {
+ scr_con_current -= scr_conspeed.value*host_realframetime;
+ if (scr_conlines > scr_con_current)
+ scr_con_current = scr_conlines;
+
+ }
+ else if (scr_conlines > scr_con_current)
+ {
+ scr_con_current += scr_conspeed.value*host_realframetime;
+ if (scr_conlines < scr_con_current)
+ scr_con_current = scr_conlines;
+ }
+}
+
+/*
+==================
+SCR_DrawConsole
+==================
+*/
+void SCR_DrawConsole (void)
+{
+ if (scr_con_current)
+ {
+ Con_DrawConsole (scr_con_current);
+ clearconsole = 0;
+ }
+ else
+ {
+ if (key_dest == key_game || key_dest == key_message)
+ Con_DrawNotify (); // only draw notify in game
+ }
+}
+
+/*
+===============
+SCR_BeginLoadingPlaque
+
+================
+*/
+/*
+void SCR_BeginLoadingPlaque (void)
+{
+ S_StopAllSounds (true);
+
+// if (cls.state != ca_connected)
+// return;
+// if (cls.signon != SIGNONS)
+// return;
+
+// redraw with no console and the loading plaque
+// Con_ClearNotify ();
+// scr_centertime_off = 0;
+// scr_con_current = 0;
+
+ scr_drawloading = true;
+ SCR_UpdateScreen ();
+
+// scr_disabled_for_loading = true;
+// scr_disabled_time = realtime;
+}
+*/
+
+/*
+===============
+SCR_EndLoadingPlaque
+
+================
+*/
+/*
+void SCR_EndLoadingPlaque (void)
+{
+// scr_disabled_for_loading = false;
+ scr_drawloading = false;
+ Con_ClearNotify ();
+}
+*/
+
+//=============================================================================
+
+char *scr_notifystring;
+
+void SCR_DrawNotifyString (void)
+{
+ char *start;
+ int l;
+ int x, y;
+
+ start = scr_notifystring;
+
+ y = vid.conheight*0.35;
+
+ do
+ {
+ // scan the width of the line
+ for (l=0 ; l<40 ; l++)
+ if (start[l] == '\n' || !start[l])
+ break;
+ x = (vid.conwidth - l*8)/2;
+ DrawQ_String (x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
+
+ y += 8;
+
+ while (*start && *start != '\n')
+ start++;
+
+ if (!*start)
+ break;
+ start++; // skip the \n
+ }
+ while (1);
+}
+
+void DrawCrosshair(int num);
+
+char r_speeds_string[1024];
+int speedstringcount, r_timereport_active;
+double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
+
+void R_TimeReport(char *desc)
+{
+ char tempbuf[256];
+ int length;
+ int t;
+
+ if (!r_timereport_active)
+ return;
+
+ r_timereport_temp = r_timereport_current;
+ r_timereport_current = Sys_DoubleTime();
+ t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0);
+
+ sprintf(tempbuf, "%8i %s", t, desc);
+ length = strlen(tempbuf);
+ while (length < 20)
+ tempbuf[length++] = ' ';
+ tempbuf[length] = 0;
+ if (speedstringcount + length > (vid.conwidth / 8))
+ {
+ strcat(r_speeds_string, "\n");
+ speedstringcount = 0;
+ }
+ // skip the space at the beginning if it's the first on the line
+ if (speedstringcount == 0)
+ {
+ strcat(r_speeds_string, tempbuf + 1);
+ speedstringcount = length - 1;
+ }
+ else
+ {
+ strcat(r_speeds_string, tempbuf);
+ speedstringcount += length;
+ }
+}
+
+void R_TimeReport_Start(void)
+{
+ r_timereport_active = r_speeds.integer && cl.worldmodel && cls.state == ca_connected;
+ r_speeds_string[0] = 0;
+ if (r_timereport_active)
+ {
+ speedstringcount = 0;
+ AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
+ //sprintf(r_speeds_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
+ // r_refdef.vieworg[0] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[0]), r_refdef.vieworg[1] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[1]), r_refdef.vieworg[2] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[2]),
+ // r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]),
+ // vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]),
+ sprintf(r_speeds_string,
+ "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
+ "world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
+ "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
+ "%6i modeltris%6i transmeshs%6i transtris%6i meshs%6i meshtris\n",
+ r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
+ c_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
+ c_models, c_bmodels, c_sprites, c_particles, c_dlights,
+ c_alias_polys, c_transmeshs, c_transtris, c_meshs, c_meshtris);
+
+ c_brush_polys = 0;
+ c_alias_polys = 0;
+ c_light_polys = 0;
+ c_faces = 0;
+ c_nodes = 0;
+ c_leafs = 0;
+ c_models = 0;
+ c_bmodels = 0;
+ c_sprites = 0;
+ c_particles = 0;
+ // c_dlights = 0;
+
+ r_timereport_start = Sys_DoubleTime();
+ }
+}
+
+void R_TimeReport_End(void)
+{
+ r_timereport_current = r_timereport_start;
+ R_TimeReport("total");
+
+ if (r_timereport_active)
+ {
+ int i, j, lines, y;
+ lines = 1;
+ for (i = 0;r_speeds_string[i];i++)
+ if (r_speeds_string[i] == '\n')
+ lines++;
+ y = vid.conheight - sb_lines - lines * 8/* - 8*/;
+ i = j = 0;
+ DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
+ while (r_speeds_string[i])
+ {
+ j = i;
+ while (r_speeds_string[i] && r_speeds_string[i] != '\n')
+ i++;
+ if (i - j > 0)
+ DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
+ if (r_speeds_string[i] == '\n')
+ i++;
+ y += 8;
+ }
+ }
+}
+
+/*
+=================
+SCR_SizeUp_f
+
+Keybinding command
+=================
+*/
+void SCR_SizeUp_f (void)
+{
+ Cvar_SetValue ("viewsize",scr_viewsize.value+10);
+}
+
+
+/*
+=================
+SCR_SizeDown_f
+
+Keybinding command
+=================
+*/
+void SCR_SizeDown_f (void)
+{
+ Cvar_SetValue ("viewsize",scr_viewsize.value-10);
+}
+
void CL_Screen_Init(void)
{
qpic_t *dat;
+ Cvar_RegisterVariable (&scr_fov);
+ Cvar_RegisterVariable (&scr_viewsize);
+ Cvar_RegisterVariable (&scr_conspeed);
+ Cvar_RegisterVariable (&scr_showram);
+ Cvar_RegisterVariable (&scr_showturtle);
+ Cvar_RegisterVariable (&scr_showpause);
+ Cvar_RegisterVariable (&scr_centertime);
+ Cvar_RegisterVariable (&scr_printspeed);
+ Cvar_RegisterVariable(&scr_2dresolution);
+
+ Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
+ Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
+
+ scr_initialized = true;
+
// HACK HACK HACK
// load the image data for the player image in the config menu
dat = (qpic_t *)COM_LoadFile ("gfx/menuplyr.lmp", false);
DrawQ_Pic(x, y, picname, 0, 0, 1, 1, 1, 1, 0);
}
-void V_CalcRefdef (void);
-void CL_UpdateScreen(void)
+
+/*
+====================
+CalcFov
+====================
+*/
+float CalcFov (float fov_x, float width, float height)
{
- DrawQ_Clear();
+ // calculate vision size and alter by aspect, then convert back to angle
+ return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
+}
- SHOWLMP_drawall();
+/*
+=================
+SCR_CalcRefdef
- V_UpdateBlends();
- V_CalcRefdef ();
+Must be called whenever vid changes
+Internal use only
+=================
+*/
+static void SCR_CalcRefdef (void)
+{
+ float size;
+ int contents;
- SCR_UpdateScreen();
-}
+//========================================
-void CL_Screen_NewMap(void)
-{
- SHOWLMP_clear();
+// bound viewsize
+ if (scr_viewsize.value < 30)
+ Cvar_Set ("viewsize","30");
+ if (scr_viewsize.value > 120)
+ Cvar_Set ("viewsize","120");
+
+// bound field of view
+ if (scr_fov.value < 10)
+ Cvar_Set ("fov","10");
+ if (scr_fov.value > 170)
+ Cvar_Set ("fov","170");
+
+// intermission is always full screen
+ if (cl.intermission)
+ {
+ size = 1;
+ sb_lines = 0;
+ }
+ else
+ {
+ if (scr_viewsize.value >= 120)
+ sb_lines = 0; // no status bar at all
+ else if (scr_viewsize.value >= 110)
+ sb_lines = 24; // no inventory
+ else
+ sb_lines = 24+16+8;
+ size = scr_viewsize.value * (1.0 / 100.0);
+ }
+
+ if (size >= 1)
+ {
+ r_refdef.width = vid.realwidth;
+ r_refdef.height = vid.realheight;
+ r_refdef.x = 0;
+ r_refdef.y = 0;
+ }
+ else
+ {
+ r_refdef.width = vid.realwidth * size;
+ r_refdef.height = vid.realheight * size;
+ r_refdef.x = (vid.realwidth - r_refdef.width)/2;
+ r_refdef.y = (vid.realheight - r_refdef.height)/2;
+ }
+
+ r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
+ r_refdef.height = bound(0, r_refdef.height, vid.realheight);
+ r_refdef.x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width) + vid.realx;
+ r_refdef.y = bound(0, r_refdef.y, vid.realheight - r_refdef.height) + vid.realy;
+
+ r_refdef.fov_x = scr_fov.value;
+ r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
+
+ if (cl.worldmodel)
+ {
+ Mod_CheckLoaded(cl.worldmodel);
+ contents = Mod_PointInLeaf(r_refdef.vieworg, cl.worldmodel)->contents;
+ if (contents != CONTENTS_EMPTY && contents != CONTENTS_SOLID)
+ {
+ r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.03 + 0.97);
+ r_refdef.fov_y *= (sin(cl.time * 3.0) * 0.03 + 0.97);
+ }
+ }
}
+
+void V_CalcRefdef (void);
+
//=============================================================================
// LordHavoc: SHOWLMP stuff
for (i = 0;i < SHOWLMP_MAXLABELS;i++)
showlmp[i].isactive = false;
}
+
+void CL_UpdateScreen(void)
+{
+ static float old2dresolution = -1;
+
+ if (scr_disabled_for_loading)
+ return;
+
+ if (!scr_initialized || !con_initialized)
+ return; // not initialized yet
+
+ R_TimeReport("other");
+
+ VID_GetWindowSize (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
+
+ VID_UpdateGamma(false);
+
+ if (scr_2dresolution.value != old2dresolution)
+ {
+ Cvar_SetValue("scr_2dresolution", bound(0.0f, scr_2dresolution.value, 1.0f));
+ old2dresolution = scr_2dresolution.value;
+ }
+
+ if (vid.realwidth > 320)
+ {
+ vid.conwidth = (vid.realwidth - 320) * scr_2dresolution.value + 320;
+ vid.conwidth = bound(320, vid.conwidth, vid.realwidth);
+ }
+ else
+ vid.conwidth = 320;
+
+ if (vid.realheight > 240)
+ {
+ vid.conheight = (vid.realheight - 240) * scr_2dresolution.value + 240;
+ vid.conheight = bound(240, vid.conheight, vid.realheight);
+ }
+ else
+ vid.conheight = 240;
+
+ SCR_SetUpToDrawConsole();
+
+ // determine size of refresh window
+ SCR_CalcRefdef();
+
+ DrawQ_Clear();
+
+ V_UpdateBlends();
+ V_CalcRefdef ();
+
+ R_TimeReport("setup");
+
+ SCR_DrawRam();
+ SCR_DrawNet();
+ SCR_DrawTurtle();
+ SCR_DrawPause();
+ SCR_CheckDrawCenterString();
+ Sbar_Draw();
+ SHOWLMP_drawall();
+
+ SCR_DrawConsole();
+
+ ui_draw();
+
+ R_TimeReport("2d");
+
+ // add r_speeds text to queue
+ R_TimeReport_End();
+
+ // start a new timing run
+ R_TimeReport_Start();
+
+ // make menu fade everything else on the screen
+ M_Draw();
+
+ SCR_UpdateScreen();
+}
+
+void CL_Screen_NewMap(void)
+{
+ SHOWLMP_clear();
+}
void SHOWLMP_drawall(void);
void SHOWLMP_clear(void);
+extern cvar_t scr_2dresolution;
+
void CL_Screen_NewMap(void);
void CL_Screen_Init(void);
void CL_UpdateScreen(void);
#include "quakedef.h"
+cvar_t r_render = {0, "r_render", "1"};
+cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering
+
+int lightscalebit;
+float lightscale;
+float overbrightscale;
+
+void SCR_ScreenShot_f (void);
+static void R_Envmap_f (void);
+
static int max_meshs;
static int max_batch;
static int max_verts; // always max_meshs * 3
void gl_backend_init(void)
{
int i;
+
+ Cvar_RegisterVariable (&r_render);
+ Cvar_RegisterVariable (&gl_dither);
+#ifdef NORENDER
+ Cvar_SetValue("r_render", 0);
+#endif
+
+ Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
+ Cmd_AddCommand ("envmap", R_Envmap_f);
+
Cvar_RegisterVariable(&gl_mesh_maxtriangles);
Cvar_RegisterVariable(&gl_mesh_batchtriangles);
Cvar_RegisterVariable(&gl_mesh_merge);
}
}
+static void MYgluPerspective(GLdouble fovx, GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar )
+{
+ GLdouble xmax, ymax;
+
+ xmax = zNear * tan( fovx * M_PI / 360.0 ) * aspect;
+ ymax = zNear * tan( fovy * M_PI / 360.0 );
+
+ glFrustum(-xmax, xmax, -ymax, ymax, zNear, zFar );
+}
+
+
+/*
+=============
+GL_SetupFrame
+=============
+*/
+static void GL_SetupFrame (void)
+{
+ if (!r_render.integer)
+ return;
+
+// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: moved to SCR_UpdateScreen
+ gldepthmin = 0;
+ gldepthmax = 1;
+ glDepthFunc (GL_LEQUAL);
+
+ glDepthRange (gldepthmin, gldepthmax);
+
+ // update farclip based on previous frame
+ r_farclip = r_newfarclip;
+
+ // set up viewpoint
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity ();
+
+ // y is weird beause OpenGL is bottom to top, we use top to bottom
+ glViewport(r_refdef.x, vid.realheight - (r_refdef.y + r_refdef.height), r_refdef.width, r_refdef.height);
+// yfov = 2*atan((float)r_refdef.height/r_refdef.width)*180/M_PI;
+ MYgluPerspective (r_refdef.fov_x, r_refdef.fov_y, r_refdef.width/r_refdef.height, 4, r_farclip);
+
+ glCullFace(GL_FRONT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity ();
+
+ glRotatef (-90, 1, 0, 0); // put Z going up
+ glRotatef (90, 0, 0, 1); // put Z going up
+ glRotatef (-r_refdef.viewangles[2], 1, 0, 0);
+ glRotatef (-r_refdef.viewangles[0], 0, 1, 0);
+ glRotatef (-r_refdef.viewangles[1], 0, 0, 1);
+ glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
+
+// glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
+
+ //
+ // set drawing parms
+ //
+// if (gl_cull.integer)
+ glEnable(GL_CULL_FACE);
+// else
+// glDisable(GL_CULL_FACE);
+
+ glEnable(GL_BLEND); // was Disable
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(1);
+}
+
static float viewdist;
int c_meshs, c_meshtris, c_transmeshs, c_transtris;
c_meshtris = 0;
c_transmeshs = 0;
c_transtris = 0;
+
+ GL_SetupFrame();
}
#ifdef DEBUGGL
if (overbright)
scaler *= 0.25f;
}
- if (lighthalf)
- scaler *= 0.5f;
+ scaler *= overbrightscale;
}
if (m->transparent)
if (overbright)
scaler *= 0.25f;
}
- if (lighthalf)
- scaler *= 0.5f;
+ scaler *= overbrightscale;
if (m->transparent)
{
// buf_texcoord_t must be the same size as the decal texcoord array (or vice versa)
memcpy(&texcoord[0].t[0], m->texcoords[0], 4 * sizeof(buf_texcoord_t));
}
+
+/*
+==============================================================================
+
+ SCREEN SHOTS
+
+==============================================================================
+*/
+
+float CalcFov (float fov_x, float width, float height);
+void R_ClearScreen(void);
+
+void SCR_ScreenShot(char *filename, int x, int y, int width, int height)
+{
+ int i;
+ byte *buffer;
+
+ buffer = Mem_Alloc(tempmempool, width*height*3);
+ glReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+ CHECKGLERROR
+
+ // LordHavoc: compensate for v_overbrightbits when using hardware gamma
+ if (v_hwgamma.integer)
+ for (i = 0;i < width * height * 3;i++)
+ buffer[i] <<= v_overbrightbits.integer;
+
+ Image_WriteTGARGB_preflipped(filename, width, height, buffer);
+
+ Mem_Free(buffer);
+}
+
+/*
+==================
+SCR_ScreenShot_f
+==================
+*/
+void SCR_ScreenShot_f (void)
+{
+ int i;
+ char filename[16];
+ char checkname[MAX_OSPATH];
+//
+// find a file name to save it to
+//
+ strcpy(filename, "dp0000.tga");
+
+ for (i=0 ; i<=9999 ; i++)
+ {
+ filename[2] = (i/1000)%10 + '0';
+ filename[3] = (i/ 100)%10 + '0';
+ filename[4] = (i/ 10)%10 + '0';
+ filename[5] = (i/ 1)%10 + '0';
+ sprintf (checkname, "%s/%s", com_gamedir, filename);
+ if (Sys_FileTime(checkname) == -1)
+ break; // file doesn't exist
+ }
+ if (i==10000)
+ {
+ Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
+ return;
+ }
+
+ SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight);
+ Con_Printf ("Wrote %s\n", filename);
+}
+
+/*
+===============
+R_Envmap_f
+
+Grab six views for environment mapping tests
+===============
+*/
+struct
+{
+ float angles[3];
+ char *name;
+}
+envmapinfo[6] =
+{
+ {{ 0, 0, 0}, "ft"},
+ {{ 0, 90, 0}, "rt"},
+ {{ 0, 180, 0}, "bk"},
+ {{ 0, 270, 0}, "lf"},
+ {{-90, 90, 0}, "up"},
+ {{ 90, 90, 0}, "dn"}
+};
+static void R_Envmap_f (void)
+{
+ int j, size;
+ char filename[256], basename[256];
+
+ if (Cmd_Argc() != 3)
+ {
+ Con_Printf ("envmap <basename> <size>: save out 6 cubic environment map images, usable with loadsky, note that size must one of 128, 256, 512, or 1024 and can't be bigger than your current resolution\n");
+ return;
+ }
+
+ if (!r_render.integer)
+ return;
+
+ strcpy(basename, Cmd_Argv(1));
+ size = atoi(Cmd_Argv(2));
+ if (size != 128 && size != 256 && size != 512 && size != 1024)
+ {
+ Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
+ return;
+ }
+ if (size > vid.realwidth || size > vid.realheight)
+ {
+ Con_Printf("envmap: your resolution is not big enough to render that size\n");
+ return;
+ }
+
+ envmap = true;
+
+ r_refdef.x = 0;
+ r_refdef.y = 0;
+ r_refdef.width = size;
+ r_refdef.height = size;
+
+ r_refdef.fov_x = 90;
+ r_refdef.fov_y = 90;
+
+ for (j = 0;j < 6;j++)
+ {
+ sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
+ VectorCopy(envmapinfo[j].angles, r_refdef.viewangles);
+ R_ClearScreen();
+ R_RenderView ();
+ SCR_ScreenShot(filename, vid.realx, vid.realy, size, size);
+ }
+
+ envmap = false;
+}
+
+//=============================================================================
+
+void R_ClearScreen(void)
+{
+ if (r_render.integer)
+ {
+ glClearColor(0,0,0,0);
+ CHECKGLERROR
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
+ CHECKGLERROR
+ if (gl_dither.integer)
+ glEnable(GL_DITHER);
+ else
+ glDisable(GL_DITHER);
+ CHECKGLERROR
+ }
+}
+
+/*
+==================
+SCR_UpdateScreen
+
+This is called every frame, and can also be called explicitly to flush
+text to the screen.
+==================
+*/
+void SCR_UpdateScreen (void)
+{
+ //Mem_CheckSentinelsGlobal();
+ //R_TimeReport("memtest");
+
+ glFinish ();
+ CHECKGLERROR
+
+ VID_Finish ();
+
+ R_TimeReport("finish");
+
+ if (gl_combine.integer && !gl_combine_extension)
+ Cvar_SetValue("gl_combine", 0);
+
+ lightscalebit = v_overbrightbits.integer;
+ if (gl_combine.integer && r_multitexture.integer)
+ lightscalebit += 2;
+
+ lightscale = 1.0f / (float) (1 << lightscalebit);
+ overbrightscale = 1.0f / (float) (1 << v_overbrightbits.integer);
+
+ R_TimeReport("setup");
+
+ R_ClearScreen();
+
+ R_TimeReport("clear");
+
+ if (scr_conlines < vid.conheight)
+ R_RenderView();
+
+ // draw 2D stuff
+ R_DrawQueue();
+}
R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
}
-void GL_BrightenScreen(void)
-{
- float f;
-
- if (r_brightness.value < 0.1f)
- Cvar_SetValue("r_brightness", 0.1f);
- if (r_brightness.value > 5.0f)
- Cvar_SetValue("r_brightness", 5.0f);
-
- if (r_contrast.value < 0.2f)
- Cvar_SetValue("r_contrast", 0.2f);
- if (r_contrast.value > 1.0f)
- Cvar_SetValue("r_contrast", 1.0f);
-
- if (!(lighthalf && !hardwaregammasupported) && r_brightness.value < 1.01f && r_contrast.value > 0.99f)
- return;
-
- if (!r_render.integer)
- return;
-
- glDisable(GL_TEXTURE_2D);
- CHECKGLERROR
- glEnable(GL_BLEND);
- CHECKGLERROR
- f = r_brightness.value;
- // only apply lighthalf using software color correction if hardware is not available (speed reasons)
- if (lighthalf && !hardwaregammasupported)
- f *= 2;
- if (f >= 1.01f)
- {
- glBlendFunc (GL_DST_COLOR, GL_ONE);
- CHECKGLERROR
- glBegin (GL_TRIANGLES);
- while (f >= 1.01f)
- {
- if (f >= 2)
- glColor3f (1, 1, 1);
- else
- glColor3f (f-1, f-1, f-1);
- glVertex2f (-5000, -5000);
- glVertex2f (10000, -5000);
- glVertex2f (-5000, 10000);
- f *= 0.5;
- }
- glEnd ();
- CHECKGLERROR
- }
- if (r_contrast.value <= 0.99f)
- {
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- CHECKGLERROR
- if (lighthalf && hardwaregammasupported)
- glColor4f (0.5, 0.5, 0.5, 1 - r_contrast.value);
- else
- glColor4f (1, 1, 1, 1 - r_contrast.value);
- CHECKGLERROR
- glBegin (GL_TRIANGLES);
- glVertex2f (-5000, -5000);
- glVertex2f (10000, -5000);
- glVertex2f (-5000, 10000);
- glEnd ();
- CHECKGLERROR
- }
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- CHECKGLERROR
-
- glEnable (GL_CULL_FACE);
- CHECKGLERROR
- glEnable (GL_DEPTH_TEST);
- CHECKGLERROR
- glDisable(GL_BLEND);
- CHECKGLERROR
- glEnable(GL_TEXTURE_2D);
- CHECKGLERROR
-}
-
void R_DrawQueue(void)
{
- int pos, num, chartexnum;
+ int pos, num, chartexnum, overbright;
float x, y, w, h, s, t, u, v;
cachepic_t *pic;
drawqueue_t *dq;
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
- glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
*/
+ overbright = v_overbrightbits.integer;
batch = false;
for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size)
{
if (color != dq->color)
{
color = dq->color;
- if (lighthalf)
- glColor4ub((byte)((color >> 25) & 0x7F), (byte)((color >> 17) & 0x7F), (byte)((color >> 9) & 0x7F), (byte)(color & 0xFF));
- else
- glColor4ub((byte)((color >> 24) & 0xFF), (byte)((color >> 16) & 0xFF), (byte)((color >> 8) & 0xFF), (byte)(color & 0xFF));
+ glColor4ub((byte)((color >> 24) & 0xFF) >> overbright, (byte)((color >> 16) & 0xFF) >> overbright, (byte)((color >> 8) & 0xFF) >> overbright, (byte)(color & 0xFF));
}
x = dq->x;
y = dq->y;
if (batch)
glEnd();
CHECKGLERROR
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- CHECKGLERROR
- GL_BrightenScreen();
+ if (!v_hwgamma.integer)
+ {
+ glDisable(GL_TEXTURE_2D);
+ CHECKGLERROR
+ t = v_contrast.value * (float) (1 << v_overbrightbits.integer);
+ if (t >= 1.01f)
+ {
+ glBlendFunc (GL_DST_COLOR, GL_ONE);
+ CHECKGLERROR
+ glBegin (GL_TRIANGLES);
+ while (t >= 1.01f)
+ {
+ if (t >= 2)
+ glColor3f (1, 1, 1);
+ else
+ glColor3f (t-1, t-1, t-1);
+ glVertex2f (-5000, -5000);
+ glVertex2f (10000, -5000);
+ glVertex2f (-5000, 10000);
+ t *= 0.5;
+ }
+ glEnd ();
+ CHECKGLERROR
+ }
+ else if (t <= 0.99f)
+ {
+ glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+ CHECKGLERROR
+ glBegin(GL_TRIANGLES);
+ glColor3f(t, t, t);
+ glVertex2f(-5000, -5000);
+ glVertex2f(10000, -5000);
+ glVertex2f(-5000, 10000);
+ glEnd();
+ CHECKGLERROR
+ }
+ if (v_brightness.value >= 0.01f)
+ {
+ glBlendFunc (GL_ONE, GL_ONE);
+ CHECKGLERROR
+ glColor3f (v_brightness.value, v_brightness.value, v_brightness.value);
+ CHECKGLERROR
+ glBegin (GL_TRIANGLES);
+ glVertex2f (-5000, -5000);
+ glVertex2f (10000, -5000);
+ glVertex2f (-5000, 10000);
+ glEnd ();
+ CHECKGLERROR
+ }
+ glEnable(GL_TEXTURE_2D);
+ CHECKGLERROR
+ }
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ CHECKGLERROR
+ glEnable (GL_CULL_FACE);
+ CHECKGLERROR
+ glEnable (GL_DEPTH_TEST);
+ CHECKGLERROR
+ glDisable(GL_BLEND);
+ CHECKGLERROR
glColor3f(1,1,1);
CHECKGLERROR
}
cvar_t r_waterripple = {CVAR_SAVE, "r_waterripple","0"};
cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
-cvar_t gl_lightmode = {CVAR_SAVE, "gl_lightmode", "1"}; // LordHavoc: overbright lighting
//cvar_t r_dynamicbothsides = {CVAR_SAVE, "r_dynamicbothsides", "1"}; // LordHavoc: can disable dynamic lighting of backfaces, but quake maps are weird so it doesn't always work right...
cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
goto loc0;
}
-qboolean lighthalf;
-
vec3_t fogcolor;
vec_t fogdensity;
float fog_density, fog_red, fog_green, fog_blue;
Cvar_RegisterVariable (&r_drawentities);
Cvar_RegisterVariable (&r_drawviewmodel);
Cvar_RegisterVariable (&r_speeds);
- Cvar_RegisterVariable (&gl_lightmode);
// Cvar_RegisterVariable (&r_dynamicwater);
// Cvar_RegisterVariable (&r_dynamicbothsides);
Cvar_RegisterVariable (&r_fullbrights);
extern void GL_Models_Init(void);
extern void R_Sky_Init(void);
extern void GL_Surf_Init(void);
-extern void GL_Screen_Init(void);
extern void R_Crosshairs_Init(void);
extern void R_Light_Init(void);
extern void R_Particles_Init(void);
GL_Models_Init();
R_Sky_Init();
GL_Surf_Init();
- GL_Screen_Init();
R_Crosshairs_Init();
R_Light_Init();
R_Particles_Init();
}
-static void MYgluPerspective(GLdouble fovx, GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar )
-{
- GLdouble xmax, ymax;
-
- xmax = zNear * tan( fovx * M_PI / 360.0 ) * aspect;
- ymax = zNear * tan( fovy * M_PI / 360.0 );
-
- if (r_viewleaf->contents != CONTENTS_EMPTY && r_viewleaf->contents != CONTENTS_SOLID)
- {
- xmax *= (sin(cl.time * 4.7) * 0.03 + 0.97);
- ymax *= (sin(cl.time * 3.0) * 0.03 + 0.97);
- }
-
- glFrustum(-xmax, xmax, -ymax, ymax, zNear, zFar );
-}
-
-
-/*
-=============
-R_SetupGL
-=============
-*/
-static void R_SetupGL (void)
-{
- if (!r_render.integer)
- return;
-
-// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: moved to SCR_UpdateScreen
- gldepthmin = 0;
- gldepthmax = 1;
- glDepthFunc (GL_LEQUAL);
-
- glDepthRange (gldepthmin, gldepthmax);
-
- // update farclip based on previous frame
- r_farclip = r_newfarclip;
-
- // set up viewpoint
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity ();
-
- // y is weird beause OpenGL is bottom to top, we use top to bottom
- glViewport(r_refdef.x, vid.realheight - (r_refdef.y + r_refdef.height), r_refdef.width, r_refdef.height);
-// yfov = 2*atan((float)r_refdef.height/r_refdef.width)*180/M_PI;
- MYgluPerspective (r_refdef.fov_x, r_refdef.fov_y, r_refdef.width/r_refdef.height, 4, r_farclip);
-
- glCullFace(GL_FRONT);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity ();
-
- glRotatef (-90, 1, 0, 0); // put Z going up
- glRotatef (90, 0, 0, 1); // put Z going up
- glRotatef (-r_refdef.viewangles[2], 1, 0, 0);
- glRotatef (-r_refdef.viewangles[0], 0, 1, 0);
- glRotatef (-r_refdef.viewangles[1], 0, 0, 1);
- glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
-
-// glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
-
- //
- // set drawing parms
- //
-// if (gl_cull.integer)
- glEnable(GL_CULL_FACE);
-// else
-// glDisable(GL_CULL_FACE);
-
- glEnable(GL_BLEND); // was Disable
- glEnable(GL_DEPTH_TEST);
- glDepthMask(1);
-}
+static int blendviewpolyindex[3] = {0, 1, 2};
static void R_BlendView(void)
{
+ rmeshinfo_t m;
+ float tvxyz[3][4];
+
if (!r_render.integer)
return;
if (r_refdef.viewblend[3] < 0.01f)
return;
+ memset(&m, 0, sizeof(m));
+ m.transparent = false;
+ m.blendfunc1 = GL_SRC_ALPHA;
+ m.blendfunc2 = GL_ONE;
+ m.depthdisable = true; // magic
+ m.numtriangles = 1;
+ m.numverts = 3;
+ m.index = blendviewpolyindex;
+ m.vertex = &tvxyz[0][0];
+ m.vertexstep = sizeof(float[4]);
+ m.cr = r_refdef.viewblend[0];
+ m.cg = r_refdef.viewblend[1];
+ m.cb = r_refdef.viewblend[2];
+ m.ca = r_refdef.viewblend[3];
+ tvxyz[0][0] = r_origin[0] + vpn[0] * 8 - vright[0] * 16 - vup[0] * 16;
+ tvxyz[0][1] = r_origin[1] + vpn[1] * 8 - vright[1] * 16 - vup[1] * 16;
+ tvxyz[0][2] = r_origin[2] + vpn[2] * 8 - vright[2] * 16 - vup[2] * 16;
+ tvxyz[1][0] = tvxyz[0][0] + vup[0] * 48;
+ tvxyz[1][1] = tvxyz[0][1] + vup[1] * 48;
+ tvxyz[1][2] = tvxyz[0][2] + vup[2] * 48;
+ tvxyz[2][0] = tvxyz[0][0] + vright[0] * 48;
+ tvxyz[2][1] = tvxyz[0][1] + vright[1] * 48;
+ tvxyz[2][2] = tvxyz[0][2] + vright[2] * 48;
+ R_Mesh_Draw(&m);
+
+ /*
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, 1, 1, 0, -99999, 99999);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin (GL_TRIANGLES);
- if (lighthalf)
- glColor4f (r_refdef.viewblend[0] * 0.5f, r_refdef.viewblend[1] * 0.5f, r_refdef.viewblend[2] * 0.5f, r_refdef.viewblend[3]);
- else
- glColor4fv (r_refdef.viewblend);
+ glColor4f (r_refdef.viewblend[0] * overbrightscale, r_refdef.viewblend[1] * overbrightscale, r_refdef.viewblend[2] * overbrightscale, r_refdef.viewblend[3]);
glVertex2f (-5, -5);
glVertex2f (10, -5);
glVertex2f (-5, 10);
glEnable (GL_DEPTH_TEST);
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
+ */
}
/*
R_SetupFrame();
R_SetFrustum();
- R_SetupGL();
R_SetupFog();
R_SkyStartFrame();
- R_Mesh_Clear();
if (r_ser.integer)
R_Clip_StartFrame();
R_BuildLightList();
+ R_Mesh_Clear();
+
R_TimeReport("setup");
R_DrawWorld();
R_DrawCoronas();
R_TimeReport("coronas");
+ R_BlendView();
+ R_TimeReport("blendview");
+
// render any queued meshs
R_Mesh_Render();
R_TimeReport("meshrender");
- R_BlendView();
- R_TimeReport("blendview");
-
//Mem_CheckSentinelsGlobal();
//R_TimeReport("memtest");
}
m.numtriangles = s->mesh.numtriangles;
m.numverts = s->mesh.numverts;
m.index = s->mesh.index;
- m.cr = 1;
- if (lighthalf)
- m.cr *= 2;
- if (gl_combine.integer)
- m.cr *= 4;
- m.cg = m.cr;
- m.cb = m.cr;
+ m.cr = m.cg = m.cb = (float) (1 << lightscalebit);
m.ca = currentrenderentity->alpha;
m.tex[0] = R_GetTexture(s->currenttexture->texture);
m.tex[1] = R_GetTexture(s->lightmaptexture);
m.numtriangles = s->mesh.numtriangles;
m.numverts = s->mesh.numverts;
m.index = s->mesh.index;
- if (lighthalf)
- {
- m.cr = 2;
- m.cg = 2;
- m.cb = 2;
- }
- else
- {
- m.cr = 1;
- m.cg = 1;
- m.cb = 1;
- }
+ m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer);
m.ca = 1;
m.tex[0] = R_GetTexture(s->currenttexture->texture);
m.texcoords[0] = &s->mesh.vertex->st[0];
m.numtriangles = s->mesh.numtriangles;
m.numverts = s->mesh.numverts;
m.index = s->mesh.index;
- m.cr = 1;
- if (lighthalf)
- m.cr *= 2.0f;
- m.cg = m.cr;
- m.cb = m.cr;
+ m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer);
m.ca = 1;
m.tex[0] = R_GetTexture(s->lightmaptexture);
m.texcoords[0] = &s->mesh.vertex->uv[0];
+++ /dev/null
-/*
-Copyright (C) 1996-1997 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-// screen.c -- master for refresh, status bar, console, chat, notify, etc
-
-#include "quakedef.h"
-
-/*
-
-background clear
-rendering
-turtle/net/ram icons
-sbar
-centerprint / slow centerprint
-notify lines
-intermission / finale overlay
-loading plaque
-console
-menu
-
-required background clears
-required update regions
-
-
-syncronous draw mode or async
-One off screen buffer, with updates either copied or xblited
-Need to double buffer?
-
-
-async draw will require the refresh area to be cleared, because it will be
-xblited, but sync draw can just ignore it.
-
-sync
-draw
-
-CenterPrint ()
-SlowPrint ()
-Screen_Update ();
-Con_Printf ();
-
-net
-turn off messages option
-
-the refresh is always rendered, unless the console is full screen
-
-
-console is:
- notify lines
- half
- full
-
-
-*/
-
-
-float scr_con_current;
-float scr_conlines; // lines of console to display
-
-float oldscreensize, oldfov;
-cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
-cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 10 - 170
-cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
-cvar_t scr_centertime = {0, "scr_centertime","2"};
-cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
-cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
-cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
-cvar_t scr_printspeed = {0, "scr_printspeed","8"};
-cvar_t r_render = {0, "r_render", "1"};
-cvar_t r_brightness = {CVAR_SAVE, "r_brightness", "1"}; // LordHavoc: a method of operating system independent color correction
-cvar_t r_contrast = {CVAR_SAVE, "r_contrast", "1"}; // LordHavoc: a method of operating system independent color correction
-cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering
-
-qboolean scr_initialized; // ready to draw
-
-int clearconsole;
-int clearnotify;
-
-int lightscalebit;
-float lightscale;
-
-qboolean scr_disabled_for_loading;
-//qboolean scr_drawloading;
-//float scr_disabled_time;
-
-void SCR_ScreenShot_f (void);
-
-/*
-===============================================================================
-
-CENTER PRINTING
-
-===============================================================================
-*/
-
-char scr_centerstring[1024];
-float scr_centertime_start; // for slow victory printing
-float scr_centertime_off;
-int scr_center_lines;
-int scr_erase_lines;
-int scr_erase_center;
-
-/*
-==============
-SCR_CenterPrint
-
-Called for important messages that should stay in the center of the screen
-for a few moments
-==============
-*/
-void SCR_CenterPrint (char *str)
-{
- strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
- scr_centertime_off = scr_centertime.value;
- scr_centertime_start = cl.time;
-
-// count the number of lines for centering
- scr_center_lines = 1;
- while (*str)
- {
- if (*str == '\n')
- scr_center_lines++;
- str++;
- }
-}
-
-
-void SCR_DrawCenterString (void)
-{
- char *start;
- int l;
- int x, y;
- int remaining;
-
-// the finale prints the characters one at a time
- if (cl.intermission)
- remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
- else
- remaining = 9999;
-
- scr_erase_center = 0;
- start = scr_centerstring;
-
- if (scr_center_lines <= 4)
- y = vid.conheight*0.35;
- else
- y = 48;
-
- do
- {
- // scan the width of the line
- for (l=0 ; l<40 ; l++)
- if (start[l] == '\n' || !start[l])
- break;
- x = (vid.conwidth - l*8)/2;
- if (l > 0)
- {
- if (remaining < l)
- l = remaining;
- DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
- remaining -= l;
- if (remaining <= 0)
- return;
- }
-
- y += 8;
-
- while (*start && *start != '\n')
- start++;
-
- if (!*start)
- break;
- start++; // skip the \n
- } while (1);
-}
-
-void SCR_CheckDrawCenterString (void)
-{
- if (scr_center_lines > scr_erase_lines)
- scr_erase_lines = scr_center_lines;
-
- scr_centertime_off -= host_frametime;
-
- if (scr_centertime_off <= 0 && !cl.intermission)
- return;
- if (key_dest != key_game)
- return;
-
- SCR_DrawCenterString ();
-}
-
-//=============================================================================
-
-/*
-====================
-CalcFov
-====================
-*/
-float CalcFov (float fov_x, float width, float height)
-{
- // calculate vision size and alter by aspect, then convert back to angle
- return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
-}
-
-/*
-=================
-SCR_CalcRefdef
-
-Must be called whenever vid changes
-Internal use only
-=================
-*/
-static void SCR_CalcRefdef (void)
-{
- float size;
-
-// vid.recalc_refdef = 0;
-
-//========================================
-
-// bound viewsize
- if (scr_viewsize.value < 30)
- Cvar_Set ("viewsize","30");
- if (scr_viewsize.value > 120)
- Cvar_Set ("viewsize","120");
-
-// bound field of view
- if (scr_fov.value < 10)
- Cvar_Set ("fov","10");
- if (scr_fov.value > 170)
- Cvar_Set ("fov","170");
-
-// intermission is always full screen
- if (cl.intermission)
- {
- size = 1;
- sb_lines = 0;
- }
- else
- {
- if (scr_viewsize.value >= 120)
- sb_lines = 0; // no status bar at all
- else if (scr_viewsize.value >= 110)
- sb_lines = 24; // no inventory
- else
- sb_lines = 24+16+8;
- size = scr_viewsize.value * (1.0 / 100.0);
- }
-
- if (size >= 1)
- {
- r_refdef.width = vid.realwidth;
- r_refdef.height = vid.realheight;
- r_refdef.x = 0;
- r_refdef.y = 0;
- }
- else
- {
- r_refdef.width = vid.realwidth * size;
- r_refdef.height = vid.realheight * size;
- r_refdef.x = (vid.realwidth - r_refdef.width)/2;
- r_refdef.y = (vid.realheight - r_refdef.height)/2;
- }
-
- r_refdef.fov_x = scr_fov.value;
- r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
-
- r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
- r_refdef.height = bound(0, r_refdef.height, vid.realheight);
- r_refdef.x = bound(0, r_refdef.x, vid.realwidth) + vid.realx;
- r_refdef.y = bound(0, r_refdef.y, vid.realheight) + vid.realy;
-}
-
-
-/*
-=================
-SCR_SizeUp_f
-
-Keybinding command
-=================
-*/
-void SCR_SizeUp_f (void)
-{
- Cvar_SetValue ("viewsize",scr_viewsize.value+10);
-}
-
-
-/*
-=================
-SCR_SizeDown_f
-
-Keybinding command
-=================
-*/
-void SCR_SizeDown_f (void)
-{
- Cvar_SetValue ("viewsize",scr_viewsize.value-10);
-}
-
-//============================================================================
-
-void gl_screen_start(void)
-{
-}
-
-void gl_screen_shutdown(void)
-{
-}
-
-void gl_screen_newmap(void)
-{
-}
-
-/*
-==================
-SCR_Init
-==================
-*/
-static void R_Envmap_f (void);
-void GL_Screen_Init (void)
-{
- Cvar_RegisterVariable (&scr_fov);
- Cvar_RegisterVariable (&scr_viewsize);
- Cvar_RegisterVariable (&scr_conspeed);
- Cvar_RegisterVariable (&scr_showram);
- Cvar_RegisterVariable (&scr_showturtle);
- Cvar_RegisterVariable (&scr_showpause);
- Cvar_RegisterVariable (&scr_centertime);
- Cvar_RegisterVariable (&scr_printspeed);
- Cvar_RegisterVariable (&r_render);
- Cvar_RegisterVariable (&r_brightness);
- Cvar_RegisterVariable (&r_contrast);
- Cvar_RegisterVariable (&gl_dither);
-#ifdef NORENDER
- Cvar_SetValue("r_render", 0);
-#endif
-
-//
-// register our commands
-//
- Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
- Cmd_AddCommand ("envmap", R_Envmap_f);
- Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
- Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
-
- scr_initialized = true;
-
- R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown, gl_screen_newmap);
-}
-
-
-
-/*
-==============
-SCR_DrawRam
-==============
-*/
-void SCR_DrawRam (void)
-{
-// if (!scr_showram.integer)
-// return;
-// DrawQ_Pic (32, 0, "ram", 0, 0, 1, 1, 1, 1, 0);
-}
-
-/*
-==============
-SCR_DrawTurtle
-==============
-*/
-void SCR_DrawTurtle (void)
-{
- static int count;
-
- if (cls.state != ca_connected)
- return;
-
- if (!scr_showturtle.integer)
- return;
-
- if (host_frametime < 0.1)
- {
- count = 0;
- return;
- }
-
- count++;
- if (count < 3)
- return;
-
- DrawQ_Pic (0, 0, "turtle", 0, 0, 1, 1, 1, 1, 0);
-}
-
-/*
-==============
-SCR_DrawNet
-==============
-*/
-void SCR_DrawNet (void)
-{
- if (cls.state != ca_connected)
- return;
- if (realtime - cl.last_received_message < 0.3)
- return;
- if (cls.demoplayback)
- return;
-
- DrawQ_Pic (64, 0, "net", 0, 0, 1, 1, 1, 1, 0);
-}
-
-/*
-==============
-DrawPause
-==============
-*/
-void SCR_DrawPause (void)
-{
- cachepic_t *pic;
-
- if (cls.state != ca_connected)
- return;
-
- if (!scr_showpause.integer) // turn off for screenshots
- return;
-
- if (!cl.paused)
- return;
-
- pic = Draw_CachePic ("gfx/pause.lmp");
- DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/pause.lmp", 0, 0, 1, 1, 1, 1, 0);
-}
-
-
-
-/*
-==============
-SCR_DrawLoading
-==============
-*/
-/*
-void SCR_DrawLoading (void)
-{
- cachepic_t *pic;
-
- if (!scr_drawloading)
- return;
-
- pic = Draw_CachePic ("gfx/loading.lmp");
- DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
-}
-*/
-
-
-
-//=============================================================================
-
-
-/*
-==================
-SCR_SetUpToDrawConsole
-==================
-*/
-void SCR_SetUpToDrawConsole (void)
-{
- Con_CheckResize ();
-
-// decide on the height of the console
- con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
-
- if (con_forcedup)
- {
- scr_conlines = vid.conheight; // full screen
- scr_con_current = scr_conlines;
- }
- else if (key_dest == key_console)
- scr_conlines = vid.conheight/2; // half screen
- else
- scr_conlines = 0; // none visible
-
- if (scr_conlines < scr_con_current)
- {
- scr_con_current -= scr_conspeed.value*host_realframetime;
- if (scr_conlines > scr_con_current)
- scr_con_current = scr_conlines;
-
- }
- else if (scr_conlines > scr_con_current)
- {
- scr_con_current += scr_conspeed.value*host_realframetime;
- if (scr_conlines < scr_con_current)
- scr_con_current = scr_conlines;
- }
-}
-
-/*
-==================
-SCR_DrawConsole
-==================
-*/
-void SCR_DrawConsole (void)
-{
- if (scr_con_current)
- {
- Con_DrawConsole (scr_con_current);
- clearconsole = 0;
- }
- else
- {
- if (key_dest == key_game || key_dest == key_message)
- Con_DrawNotify (); // only draw notify in game
- }
-}
-
-
-/*
-==============================================================================
-
- SCREEN SHOTS
-
-==============================================================================
-*/
-
-/*
-==================
-SCR_ScreenShot_f
-==================
-*/
-void SCR_ScreenShot_f (void)
-{
- byte *buffer, gamma[256];
- char filename[80];
- char checkname[MAX_OSPATH];
- int i;
-//
-// find a file name to save it to
-//
- strcpy(filename,"dp0000.tga");
-
- for (i=0 ; i<=9999 ; i++)
- {
- filename[2] = (i/1000)%10 + '0';
- filename[3] = (i/ 100)%10 + '0';
- filename[4] = (i/ 10)%10 + '0';
- filename[5] = (i/ 1)%10 + '0';
- sprintf (checkname, "%s/%s", com_gamedir, filename);
- if (Sys_FileTime(checkname) == -1)
- break; // file doesn't exist
- }
- if (i==10000)
- {
- Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
- return;
- }
-
- buffer = Mem_Alloc(tempmempool, vid.realwidth*vid.realheight*3);
- glReadPixels (vid.realx, vid.realy, vid.realwidth, vid.realheight, GL_RGB, GL_UNSIGNED_BYTE, buffer);
- CHECKGLERROR
-
- // apply hardware gamma to the image
- BuildGammaTable8((lighthalf && hardwaregammasupported) ? 2.0f : 1.0f, 1, 1, 0, gamma);
- Image_GammaRemapRGB(buffer, buffer, vid.realwidth*vid.realheight, gamma, gamma, gamma);
-
- Image_WriteTGARGB_preflipped(filename, vid.realwidth, vid.realheight, buffer);
-
- Mem_Free(buffer);
- Con_Printf ("Wrote %s\n", filename);
-}
-
-/*
-===============
-R_Envmap_f
-
-Grab six views for environment mapping tests
-===============
-*/
-float CalcFov (float fov_x, float width, float height);
-struct
-{
- float angles[3];
- char *name;
-}
-envmapinfo[6] =
-{
- {{ 0, 0, 0}, "ft"},
- {{ 0, 90, 0}, "rt"},
- {{ 0, 180, 0}, "bk"},
- {{ 0, 270, 0}, "lf"},
- {{-90, 90, 0}, "up"},
- {{ 90, 90, 0}, "dn"}
-};
-static void R_Envmap_f (void)
-{
- int i, size;
- char filename[256];
- char basename[256];
- byte *buffer, gamma[256];
-
- if (Cmd_Argc() != 3)
- {
- Con_Printf ("envmap <basename> <size>: save out 6 cubic environment map images, usable with loadsky, note that size must one of 128, 256, 512, or 1024 and can't be bigger than your current resolution\n");
- return;
- }
-
- if (!r_render.integer)
- return;
-
- strcpy(basename, Cmd_Argv(1));
- size = atoi(Cmd_Argv(2));
- if (size != 128 && size != 256 && size != 512 && size != 1024)
- {
- Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
- return;
- }
- if (size > vid.realwidth || size > vid.realheight)
- {
- Con_Printf("envmap: your resolution is not big enough to render that size\n");
- return;
- }
-
- buffer = Mem_Alloc(tempmempool, size*size*3);
- if (buffer == NULL)
- {
- Con_Printf("envmap: unable to allocate memory for image\n");
- return;
- }
-
- BuildGammaTable8((lighthalf && hardwaregammasupported) ? 2.0f : 1.0f, 1, 1, 0, gamma);
-
-// glDrawBuffer (GL_FRONT);
-// glReadBuffer (GL_FRONT);
- glDrawBuffer (GL_BACK);
- glReadBuffer (GL_BACK);
- envmap = true;
-
- r_refdef.x = 0;
- r_refdef.y = 0;
- r_refdef.width = size;
- r_refdef.height = size;
-
- r_refdef.fov_x = 90;
- r_refdef.fov_y = 90;
-
- for (i = 0;i < 6;i++)
- {
- VectorCopy(envmapinfo[i].angles, r_refdef.viewangles);
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
- R_RenderView ();
- glReadPixels (0, 0, size, size, GL_RGB, GL_UNSIGNED_BYTE, buffer);
- sprintf(filename, "env/%s%s.tga", basename, envmapinfo[i].name);
- Image_GammaRemapRGB(buffer, buffer, size * size, gamma, gamma, gamma);
- Image_WriteTGARGB_preflipped(filename, size, size, buffer);
- }
-
- envmap = false;
- glDrawBuffer (GL_BACK);
- glReadBuffer (GL_BACK);
-
- Mem_Free(buffer);
-
- // cause refdef to be fixed
-// vid.recalc_refdef = 1;
-}
-
-//=============================================================================
-
-
-/*
-===============
-SCR_BeginLoadingPlaque
-
-================
-*/
-/*
-void SCR_BeginLoadingPlaque (void)
-{
- S_StopAllSounds (true);
-
-// if (cls.state != ca_connected)
-// return;
-// if (cls.signon != SIGNONS)
-// return;
-
-// redraw with no console and the loading plaque
-// Con_ClearNotify ();
-// scr_centertime_off = 0;
-// scr_con_current = 0;
-
- scr_drawloading = true;
- SCR_UpdateScreen ();
-
-// scr_disabled_for_loading = true;
-// scr_disabled_time = realtime;
-}
-*/
-
-/*
-===============
-SCR_EndLoadingPlaque
-
-================
-*/
-/*
-void SCR_EndLoadingPlaque (void)
-{
-// scr_disabled_for_loading = false;
- scr_drawloading = false;
- Con_ClearNotify ();
-}
-*/
-
-//=============================================================================
-
-char *scr_notifystring;
-
-void SCR_DrawNotifyString (void)
-{
- char *start;
- int l;
- int x, y;
-
- start = scr_notifystring;
-
- y = vid.conheight*0.35;
-
- do
- {
- // scan the width of the line
- for (l=0 ; l<40 ; l++)
- if (start[l] == '\n' || !start[l])
- break;
- x = (vid.conwidth - l*8)/2;
- DrawQ_String (x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
-
- y += 8;
-
- while (*start && *start != '\n')
- start++;
-
- if (!*start)
- break;
- start++; // skip the \n
- }
- while (1);
-}
-
-//=============================================================================
-
-void DrawCrosshair(int num);
-
-char r_speeds_string[1024];
-int speedstringcount, r_timereport_active;
-double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
-
-void R_TimeReport(char *desc)
-{
- char tempbuf[256];
- int length;
- int t;
-
- if (!r_timereport_active)
- return;
-
- r_timereport_temp = r_timereport_current;
- r_timereport_current = Sys_DoubleTime();
- t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0);
-
- sprintf(tempbuf, "%8i %s", t, desc);
- length = strlen(tempbuf);
- while (length < 20)
- tempbuf[length++] = ' ';
- tempbuf[length] = 0;
- if (speedstringcount + length > (vid.conwidth / 8))
- {
- strcat(r_speeds_string, "\n");
- speedstringcount = 0;
- }
- // skip the space at the beginning if it's the first on the line
- if (speedstringcount == 0)
- {
- strcat(r_speeds_string, tempbuf + 1);
- speedstringcount = length - 1;
- }
- else
- {
- strcat(r_speeds_string, tempbuf);
- speedstringcount += length;
- }
-}
-
-void R_TimeReport_Start(void)
-{
- r_timereport_active = r_speeds.integer && cl.worldmodel && cls.state == ca_connected;
- r_speeds_string[0] = 0;
- if (r_timereport_active)
- {
- speedstringcount = 0;
- AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
- //sprintf(r_speeds_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
- // r_refdef.vieworg[0] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[0]), r_refdef.vieworg[1] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[1]), r_refdef.vieworg[2] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[2]),
- // r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]),
- // vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]),
- sprintf(r_speeds_string,
- "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
- "world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
- "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
- "%6i modeltris%6i transmeshs%6i transtris%6i meshs%6i meshtris\n",
- r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
- c_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
- c_models, c_bmodels, c_sprites, c_particles, c_dlights,
- c_alias_polys, c_transmeshs, c_transtris, c_meshs, c_meshtris);
-
- c_brush_polys = 0;
- c_alias_polys = 0;
- c_light_polys = 0;
- c_faces = 0;
- c_nodes = 0;
- c_leafs = 0;
- c_models = 0;
- c_bmodels = 0;
- c_sprites = 0;
- c_particles = 0;
- // c_dlights = 0;
-
- r_timereport_start = Sys_DoubleTime();
- }
-}
-
-void R_TimeReport_End(void)
-{
- r_timereport_current = r_timereport_start;
- R_TimeReport("total");
-
- if (r_timereport_active)
- {
- int i, j, lines, y;
- lines = 1;
- for (i = 0;r_speeds_string[i];i++)
- if (r_speeds_string[i] == '\n')
- lines++;
- y = vid.conheight - sb_lines - lines * 8/* - 8*/;
- i = j = 0;
- DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
- while (r_speeds_string[i])
- {
- j = i;
- while (r_speeds_string[i] && r_speeds_string[i] != '\n')
- i++;
- if (i - j > 0)
- DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
- if (r_speeds_string[i] == '\n')
- i++;
- y += 8;
- }
- }
-}
-
-/*
-==================
-SCR_UpdateScreen
-
-This is called every frame, and can also be called explicitly to flush
-text to the screen.
-
-LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
-==================
-*/
-void SCR_UpdateScreen (void)
-{
- VID_UpdateGamma(false);
-
- if (scr_disabled_for_loading)
- return;
-
- if (!scr_initialized || !con_initialized)
- return; // not initialized yet
-
- //Mem_CheckSentinelsGlobal();
- //R_TimeReport("memtest");
-
- R_TimeReport("other");
-
- glFinish ();
- CHECKGLERROR
-
- GL_EndRendering ();
-
- R_TimeReport("finish");
-
- GL_BeginRendering (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
-
- if (gl_combine.integer && !gl_combine_extension)
- Cvar_SetValue("gl_combine", 0);
-
- lighthalf = gl_lightmode.integer;
-
- lightscalebit = 0;
- if (lighthalf)
- lightscalebit += 1;
-
- if (gl_combine.integer && r_multitexture.integer)
- lightscalebit += 2;
-
- lightscale = 1.0f / (float) (1 << lightscalebit);
-
- R_TimeReport("setup");
-
- // determine size of refresh window
- SCR_CalcRefdef();
-
- R_TimeReport("calcrefdef");
-
- if (r_render.integer)
- {
- glClearColor(0,0,0,0);
- CHECKGLERROR
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
- CHECKGLERROR
- if (gl_dither.integer)
- glEnable(GL_DITHER);
- else
- glDisable(GL_DITHER);
- CHECKGLERROR
- }
-
- SCR_SetUpToDrawConsole();
-
- R_TimeReport("clear");
-
- if (scr_conlines < vid.conheight)
- R_RenderView();
-
- SCR_DrawRam();
- SCR_DrawNet();
- SCR_DrawTurtle();
- SCR_DrawPause();
- SCR_CheckDrawCenterString();
- Sbar_Draw();
- SHOWLMP_drawall();
-
- SCR_DrawConsole();
- M_Draw();
-
- ui_draw();
-
- R_TimeReport("2d");
-
- R_TimeReport_End();
-
- // draw 2D stuff
- R_DrawQueue();
-
- R_TimeReport_Start();
-}
extern qboolean isG200;
extern qboolean isRagePro;
-extern void GL_BeginRendering (int *x, int *y, int *width, int *height);
-extern void GL_EndRendering (void);
-
-extern float gldepthmin, gldepthmax;
+extern float gldepthmin, gldepthmax;
//====================================================
-extern const char *gl_vendor;
-extern const char *gl_renderer;
-extern const char *gl_version;
-extern const char *gl_extensions;
+extern const char *gl_vendor;
+extern const char *gl_renderer;
+extern const char *gl_version;
+extern const char *gl_extensions;
#ifndef _WIN32
#define APIENTRY /* */
#SND=snd_oss.o
#SOUNDLIB=
-OBJECTS= builddate.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o gl_screen.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_particles.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o
+OBJECTS= builddate.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_particles.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o
#K6/athlon optimizations
CPUOPTIMIZATIONS=-march=k6
menu_height = 200;
menu_x = (vid.conwidth - menu_width) * 0.5;
menu_y = (vid.conheight - menu_height) * 0.5;
- DrawQ_Fill(menu_x, menu_y, menu_width, menu_height, 0, 0, 0, 0.5, 0);
+ //DrawQ_Fill(menu_x, menu_y, menu_width, menu_height, 0, 0, 0, 0.5, 0);
+ DrawQ_Fill(0, 0, vid.conwidth, vid.conheight, 0, 0, 0, 0.5, 0);
}
/*
DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0);
}
+void M_ItemPrint (float cx, float cy, char *str, int unghosted)
+{
+ /*
+ while (*str)
+ {
+ M_DrawCharacter (cx, cy, (*str++)+128);
+ cx += 8;
+ }
+ */
+ if (unghosted)
+ DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0);
+ else
+ DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 0.7, 0.7, 0.7, 1, 0);
+}
+
void M_DrawPic (float cx, float cy, char *picname)
{
DrawQ_Pic (menu_x + cx, menu_y + cy, picname, 0, 0, 1, 1, 1, 1, 0);
//=============================================================================
/* OPTIONS MENU */
-#define OPTIONS_ITEMS (vid_menudrawfn ? 25 : 24)
+#define OPTIONS_ITEMS 26
#define SLIDER_RANGE 10
switch (options_cursor)
{
- case 3: // screen size
+ case 4:
+ Cvar_SetValue ("scr_2dresolution", bound(0, scr_2dresolution.value + dir * 0.2, 1));
+ break;
+ case 5:
Cvar_SetValue ("viewsize", bound(30, scr_viewsize.value + dir * 10, 120));
break;
- case 4:
+ case 6:
+ Cvar_SetValue ("r_skyquality", bound(0, r_skyquality.integer + dir, 2));
+ break;
+ case 7:
Cvar_SetValue ("r_ser", !r_ser.integer);
break;
-
- case 5: // overbright rendering
- Cvar_SetValue ("gl_lightmode", !gl_lightmode.integer);
+ case 8:
+ Cvar_SetValue ("v_overbrightbits", bound(0, v_overbrightbits.integer + dir, 4));
break;
-
- case 6: // dithering
+ case 9:
Cvar_SetValue ("gl_dither", !gl_dither.integer);
break;
-
- case 7: // sky quality
- Cvar_SetValue ("r_skyquality", bound(0, r_skyquality.integer + dir, 2));
- break;
-
- case 8: // hardware gamma
- Cvar_SetValue ("vid_gamma", bound(1, vid_gamma.value + dir * 0.25, 5));
- break;
-
- case 9: // hardware brightness
- Cvar_SetValue ("vid_brightness", bound(1, vid_brightness.value + dir * 0.25, 5));
+ case 10:
+ Cvar_SetValue ("v_hwgamma", !v_hwgamma.integer);
break;
-
- case 10: // hardware contrast
- Cvar_SetValue ("vid_contrast", bound(0.2, vid_contrast.value + dir * 0.08, 1));
+ case 11:
+ Cvar_SetValue ("v_gamma", bound(1, v_gamma.value + dir * 0.25, 5));
break;
-
- case 11: // software brightness
- Cvar_SetValue ("r_brightness", bound(1, r_brightness.value + dir * 0.25, 5));
+ case 12:
+ Cvar_SetValue ("v_contrast", bound(0.5, v_contrast.value + dir * 0.25, 5));
break;
-
- case 12: // software base brightness
- Cvar_SetValue ("r_contrast", bound(0.2, r_contrast.value + dir * 0.08, 1));
+ case 13:
+ Cvar_SetValue ("v_brightness", bound(0, v_brightness.value + dir * 0.05, 0.8));
break;
-
- case 13: // music volume
+ case 14: // music volume
#ifdef _WIN32
Cvar_SetValue ("bgmvolume", bound(0, bgmvolume.value + dir * 1.0, 1));
#else
Cvar_SetValue ("bgmvolume", bound(0, bgmvolume.value + dir * 0.1, 1));
#endif
break;
-
- case 14: // sfx volume
+ case 15: // sfx volume
Cvar_SetValue ("volume", bound(0, volume.value + dir * 0.1, 1));
break;
-
- case 15: // always run
+ case 16:
+ Cvar_SetValue ("crosshair", bound(0, crosshair.integer + dir, 5));
+ break;
+ case 17:
+ Cvar_SetValue ("crosshair_size", bound(1, crosshair_size.value + dir, 5));
+ break;
+ case 18: // show framerate
+ Cvar_SetValue ("showfps", !showfps.integer);
+ break;
+ case 19: // always run
if (cl_forwardspeed.value > 200)
{
Cvar_SetValue ("cl_forwardspeed", 200);
Cvar_SetValue ("cl_backspeed", 400);
}
break;
-
- case 16: // lookspring
+ case 20: // lookspring
Cvar_SetValue ("lookspring", !lookspring.integer);
break;
-
- case 17: // lookstrafe
+ case 21: // lookstrafe
Cvar_SetValue ("lookstrafe", !lookstrafe.integer);
break;
-
- case 18: // mouse speed
+ case 22: // mouse speed
Cvar_SetValue ("sensitivity", bound(1, sensitivity.value + dir * 0.5, 50));
break;
-
- case 19: // mouse look
+ case 23: // mouse look
Cvar_SetValue ("freelook", !freelook.integer);
break;
-
- case 20: // invert mouse
+ case 24: // invert mouse
Cvar_SetValue ("m_pitch", -m_pitch.value);
break;
-
- case 21: // windowed mouse
+ case 25: // windowed mouse
Cvar_SetValue ("vid_mouse", !vid_mouse.integer);
break;
-
- case 22:
- Cvar_SetValue ("crosshair", bound(0, crosshair.integer + dir, 5));
- break;
-
- case 23: // show framerate
- Cvar_SetValue ("showfps", !showfps.integer);
- break;
}
}
M_Print (x, y, "off");
}
+/*
+int m_2dres[] =
+{
+ 320, 200,
+ 320, 240,
+ 400, 300,
+ 512, 384,
+ 640, 480,
+ 800, 600,
+ 1024, 768,
+ 1280, 960,
+ 1600, 1200,
+ 2048, 1536
+};
+
+int M_Num2DResolutions(void)
+{
+ return sizeof(m_2dres) / sizeof(int[2]);
+};
+
+float M_Classify2DResolution(void)
+{
+ int i, num, *res, best, bestdist, diff[3];
+ num = M_Num2DResolutions();
+ best = -1;
+ bestdist = 1000000000;
+ for (i = 0;i < num;i++)
+ {
+ res = m_2dres + i * 2;
+ diff[0] = res[0] - vid.conwidth;
+ diff[1] = res[1] - vid.conheight;
+ diff[2] = 0;
+ dist = DotProduct(diff, diff);
+ if (bestdist > dist)
+ {
+ bestdist = dist;
+ best = i;
+ }
+ }
+ return i;
+}
+
+void M_Adjust2DResolution(int dir)
+{
+ int i, num;
+ i = M_Classify2DResolution() + dir;
+ num = M_Num2DResolutions() - 1;
+ i = bound(0, i, num);
+ Cvar_SetValue("v_2dwidth", m_2dres[i*2]);
+ Cvar_SetValue("v_2dheight", m_2dres[i*2+1]);
+}
+*/
+
void M_Options_Draw (void)
{
float y;
M_Print(16, y, " Customize controls");y += 8;
M_Print(16, y, " Go to console");y += 8;
M_Print(16, y, " Reset to defaults");y += 8;
+ M_ItemPrint(16, y, " Video Options", vid_menudrawfn != NULL);y += 8;
+ M_Print(16, y, " 2D Resolution");M_DrawSlider(220, y, scr_2dresolution.value);y += 8;
M_Print(16, y, " Screen size");M_DrawSlider(220, y, (scr_viewsize.value - 30) /(120 - 30));y += 8;
+ M_Print(16, y, " Sky Quality");M_DrawSlider(220, y, r_skyquality.value / 2);y += 8;
M_Print(16, y, "Hidden Surface Removal");M_DrawCheckbox(220, y, r_ser.integer);y += 8;
- M_Print(16, y, " Overbright Rendering");M_DrawCheckbox(220, y, gl_lightmode.integer);y += 8;
+ M_Print(16, y, " Overbright Bits");M_DrawSlider(220, y, (v_overbrightbits.value) / 4);y += 8;
M_Print(16, y, " Dithering");M_DrawCheckbox(220, y, gl_dither.integer);y += 8;
- M_Print(16, y, " Sky Quality");M_DrawSlider(220, y, r_skyquality.value / 2);y += 8;
- M_Print(16, y, " Hardware Gamma");M_DrawSlider(220, y, (vid_gamma.value - 1) / 4);y += 8;
- M_Print(16, y, " Hardware Brightness");M_DrawSlider(220, y, (vid_brightness.value - 1) / 4);y += 8;
- M_Print(16, y, " Hardware Contrast");M_DrawSlider(220, y, (vid_contrast.value - 0.2) / 0.8);y += 8;
- M_Print(16, y, " Software Brightness");M_DrawSlider(220, y, (r_brightness.value - 1) / 4);y += 8;
- M_Print(16, y, " Software Contrast");M_DrawSlider(220, y, (r_contrast.value - 0.2) / 0.8);y += 8;
- M_Print(16, y, " CD Music Volume");M_DrawSlider(220, y, bgmvolume.value);y += 8;
- M_Print(16, y, " Sound Volume");M_DrawSlider(220, y, volume.value);y += 8;
+ M_ItemPrint(16, y, "Hardware Gamma Control", hardwaregammasupported);M_DrawCheckbox(220, y, v_hwgamma.integer);y += 8;
+ M_ItemPrint(16, y, " Gamma", v_hwgamma.integer);M_DrawSlider(220, y, (v_gamma.value - 1) / 4);y += 8;
+ M_Print(16, y, " Contrast");M_DrawSlider(220, y, (v_contrast.value - 0.5) / (5 - 0.5));y += 8;
+ M_Print(16, y, " Brightness");M_DrawSlider(220, y, v_brightness.value / 0.8);y += 8;
+ M_ItemPrint(16, y, " CD Music Volume", Cvar_FindVar("bgmvolume") != NULL);M_DrawSlider(220, y, bgmvolume.value);y += 8;
+ M_ItemPrint(16, y, " Sound Volume", Cvar_FindVar("volume") != NULL);M_DrawSlider(220, y, volume.value);y += 8;
+ M_Print(16, y, " Crosshair");M_DrawSlider(220, y, crosshair.value / 5);y += 8;
+ M_Print(16, y, " Crosshair Size");M_DrawSlider(220, y, (crosshair_size.value - 1) / 4);y += 8;
+ M_Print(16, y, " Show Framerate");M_DrawCheckbox(220, y, showfps.integer);y += 8;
M_Print(16, y, " Always Run");M_DrawCheckbox(220, y, cl_forwardspeed.value > 200);y += 8;
M_Print(16, y, " Lookspring");M_DrawCheckbox(220, y, lookspring.integer);y += 8;
M_Print(16, y, " Lookstrafe");M_DrawCheckbox(220, y, lookstrafe.integer);y += 8;
M_Print(16, y, " Mouse Look");M_DrawCheckbox(220, y, freelook.integer);y += 8;
M_Print(16, y, " Invert Mouse");M_DrawCheckbox(220, y, m_pitch.value < 0);y += 8;
M_Print(16, y, " Use Mouse");M_DrawCheckbox(220, y, vid_mouse.integer);y += 8;
- M_Print(16, y, " Crosshair");M_DrawSlider(220, y, crosshair.value / 5);y += 8;
- M_Print(16, y, " Show Framerate");M_DrawCheckbox(220, y, showfps.integer);y += 8;
- if (vid_menudrawfn)
- M_Print(16, y, " Video Options");
- y += 8;
// cursor
M_DrawCharacter(200, 32 + options_cursor*8, 12+((int)(realtime*4)&1));
case 2:
Cbuf_AddText ("exec default.cfg\n");
break;
- default:
- // this is really just another case, but since it is calculated...
- if (vid_menudrawfn && options_cursor == (OPTIONS_ITEMS - 1))
+ case 3:
+ if (vid_menudrawfn)
M_Menu_Video_f ();
- else
- M_AdjustSliders (1);
+ break;
+ default:
+ M_AdjustSliders (1);
break;
}
return;
{
int count;
int j;
- int l;
char *b;
twokeys[0] = twokeys[1] = -1;
- l = strlen(command);
count = 0;
for (j=0 ; j<256 ; j++)
b = keybindings[j];
if (!b)
continue;
- if (!strncmp (b, command, l) )
+ if (!strcmp (b, command) )
{
twokeys[count] = j;
count++;
void M_UnbindCommand (char *command)
{
int j;
- int l;
char *b;
- l = strlen(command);
-
for (j=0 ; j<256 ; j++)
{
b = keybindings[j];
if (!b)
continue;
- if (!strncmp (b, command, l) )
+ if (!strcmp (b, command))
Key_SetBinding (j, "");
}
}
unsigned short cached_light[MAXLIGHTMAPS];
// if lightmap was lit by dynamic lights, force update on next frame
short cached_dlight;
- // to cause lightmap to be rerendered when lighthalf changes
+ // to cause lightmap to be rerendered when v_overbrightbits changes
short cached_lightscalebit;
// rerender lightmaps when r_ambient changes
float cached_ambient;
byte host_basepal[768];
byte texgamma[256];
-cvar_t vid_gamma = {CVAR_SAVE, "vid_gamma", "1"};
-cvar_t vid_brightness = {CVAR_SAVE, "vid_brightness", "1"};
-cvar_t vid_contrast = {CVAR_SAVE, "vid_contrast", "1"};
+cvar_t v_gamma = {CVAR_SAVE, "v_gamma", "1"};
+cvar_t v_contrast = {CVAR_SAVE, "v_contrast", "1"};
+cvar_t v_brightness = {CVAR_SAVE, "v_brightness", "0"};
+cvar_t v_overbrightbits = {CVAR_SAVE, "v_overbrightbits", "0"};
+cvar_t v_hwgamma = {0, "v_hwgamma", "1"};
void Palette_Setup8to24(void)
{
qboolean hardwaregammasupported = false;
void VID_UpdateGamma(qboolean force)
{
- static float cachegamma = -1, cachebrightness = -1, cachecontrast = -1, cachelighthalf = -1;
+ static float cachegamma = -1, cachebrightness = -1, cachecontrast = -1;
+ static int cacheoverbrightbits = -1, cachehwgamma = -1;
// LordHavoc: don't mess with gamma tables if running dedicated
if (cls.state == ca_dedicated)
return;
- if (!force && vid_gamma.value == cachegamma && vid_brightness.value == cachebrightness && vid_contrast.value == cachecontrast && lighthalf == cachelighthalf)
+ if (!force
+ && v_gamma.value == cachegamma
+ && v_contrast.value == cachecontrast
+ && v_brightness.value == cachebrightness
+ && v_overbrightbits.integer == cacheoverbrightbits
+ && v_hwgamma.value == cachehwgamma)
return;
- if (vid_gamma.value < 0.1)
- Cvar_SetValue("vid_gamma", 0.1);
- if (vid_gamma.value > 5.0)
- Cvar_SetValue("vid_gamma", 5.0);
+ if (v_gamma.value < 0.1)
+ Cvar_SetValue("v_gamma", 0.1);
+ if (v_gamma.value > 5.0)
+ Cvar_SetValue("v_gamma", 5.0);
- if (vid_brightness.value < 1.0)
- Cvar_SetValue("vid_brightness", 1.0);
- if (vid_brightness.value > 5.0)
- Cvar_SetValue("vid_brightness", 5.0);
+ if (v_contrast.value < 0.5)
+ Cvar_SetValue("v_contrast", 0.5);
+ if (v_contrast.value > 5.0)
+ Cvar_SetValue("v_contrast", 5.0);
- if (vid_contrast.value < 0.2)
- Cvar_SetValue("vid_contrast", 0.2);
- if (vid_contrast.value > 1)
- Cvar_SetValue("vid_contrast", 1);
+ if (v_brightness.value < 0)
+ Cvar_SetValue("v_brightness", 0);
+ if (v_brightness.value > 0.8)
+ Cvar_SetValue("v_brightness", 0.8);
- cachegamma = vid_gamma.value;
- cachebrightness = vid_brightness.value;
- cachecontrast = vid_contrast.value;
- cachelighthalf = lighthalf;
+ cachegamma = v_gamma.value;
+ cachecontrast = v_contrast.value;
+ cachebrightness = v_brightness.value;
+ cacheoverbrightbits = v_overbrightbits.integer;
- hardwaregammasupported = VID_SetGamma((cachelighthalf ? 2.0f : 1.0f), cachegamma, cachebrightness * cachecontrast, 1 - cachecontrast);
+ hardwaregammasupported = VID_SetGamma((float) (1 << cacheoverbrightbits), cachegamma, cachecontrast, cachebrightness);
if (!hardwaregammasupported)
+ {
Con_Printf("Hardware gamma not supported.\n");
+ Cvar_SetValue("v_hwgamma", 0);
+ }
+ cachehwgamma = v_hwgamma.integer;
}
void Gamma_Init(void)
{
- Cvar_RegisterVariable(&vid_gamma);
- Cvar_RegisterVariable(&vid_brightness);
- Cvar_RegisterVariable(&vid_contrast);
+ Cvar_RegisterVariable(&v_gamma);
+ Cvar_RegisterVariable(&v_brightness);
+ Cvar_RegisterVariable(&v_contrast);
+ Cvar_RegisterVariable(&v_hwgamma);
+ Cvar_RegisterVariable(&v_overbrightbits);
}
void Palette_Init(void)
-extern cvar_t vid_gamma;
-extern cvar_t vid_brightness;
-extern cvar_t vid_contrast;
+extern cvar_t v_gamma;
+extern cvar_t v_contrast;
+extern cvar_t v_brightness;
+extern cvar_t v_overbrightbits;
+extern cvar_t v_hwgamma;
extern unsigned int d_8to24table[256];
//extern byte d_15to8table[32768];
s->active = 0;
}
+// (server) clears the database to contain no frames (thus delta compression compresses against nothing)
+void EntityFrame_ClearDatabase(entity_database_t *d)
+{
+ memset(d, 0, sizeof(*d));
+ d->ackframe = -1;
+}
+
+// (server) acknowledge a frame as recieved by client (removes old frames from database, will use this new frame for delta compression)
+void EntityFrame_AckFrame(entity_database_t *d, int frame)
+{
+}
+
+// (server) clears frame, to prepare for adding entities
+void EntityFrame_Clear(entity_frame_t *f)
+{
+ memset(f, 0, sizeof(*f));
+}
+
+// (server) allocates an entity slot in frame, returns NULL if full
+entity_state_t *EntityFrame_NewEntity(entity_frame_t *f, int number)
+{
+ entity_state_t *e;
+ if (f->numentities >= MAX_ENTITY_DATABASE)
+ return NULL;
+ e = &f->entitydata[f->numentities++];
+ e->active = true;
+ e->number = number;
+ return e;
+}
+
+// (server) writes a frame to network stream
+void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, int deltaframe, int newframe, sizebuf_t *msg)
+{
+}
+
+// (client) reads a frame from network stream
+void EntityFrame_Read(entity_database_t *d, entity_frame_t *f)
+{
+}
+
+// (client) fetchs an entity from the database, read with _Read, fills in structs for current and previous state
+void EntityFrame_FetchEntity(entity_database_t *d, entity_state_t *previous, entity_state_t *current)
+{
+}
#define svc_stufftext 9 // [string] stuffed into client's console buffer
// the string should be \n terminated
#define svc_setangle 10 // [angle3] set the view angle to this absolute value
-
+
#define svc_serverinfo 11 // [long] version
// [string] signon string
// [string]..[0]model cache
#define svc_updatecolors 17 // [byte] [byte]
#define svc_particle 18 // [vec3] <variable>
#define svc_damage 19
-
+
#define svc_spawnstatic 20
// svc_spawnbinary 21
#define svc_spawnbaseline 22
-
+
#define svc_temp_entity 23
#define svc_setpause 24 // [byte] on / off
#define svc_sound2 54 // short soundindex instead of byte
#define svc_spawnbaseline2 55 // short modelindex instead of byte
#define svc_spawnstatic2 56 // short modelindex instead of byte
-#define svc_unusedlh2 57
+#define svc_entities 57 // [short] numentities [int] deltaframe [float vector] eye [variable length] entitydata
#define svc_unusedlh3 58
#define svc_spawnstaticsound2 59 // [coord3] [short] samp [byte] vol [byte] aten
typedef struct
{
double time; // time this state was built
+ vec3_t origin;
+ vec3_t angles;
+ int number; // entity number this state is for
unsigned short active; // true if a valid state
unsigned short modelindex;
unsigned short frame;
unsigned short effects;
- vec3_t origin;
- vec3_t angles;
byte colormap;
byte skin;
byte alpha;
byte glowsize;
byte glowcolor;
byte flags;
+ byte padding[3];
}
entity_state_t;
+typedef struct
+{
+ int framenum;
+ int firstentity; // index into entitydata, modulo MAX_ENTITY_DATABASE
+ int endentity; // index into entitydata, firstentity + numentities
+}
+entity_frameinfo_t;
+
+#define MAX_ENTITY_HISTORY 64
+#define MAX_ENTITY_DATABASE 4096
+
+typedef struct
+{
+ // note: these can be far out of range, modulo with MAX_ENTITY_DATABASE to get a valid range (which may wrap)
+ // start and end of used area, when adding a new update to database, store at endpos, and increment endpos
+ // when removing updates from database, nudge down frames array to only contain useful frames
+ // this logic should explain better:
+ // if (numframes >= MAX_ENTITY_HISTORY || (frames[numframes - 1].endentity - frames[0].firstentity) + entitiestoadd > MAX_ENTITY_DATABASE)
+ // flushdatabase();
+ // note: if numframes == 0, insert at start (0 in entitydata)
+ // the only reason this system is used is to avoid copying memory when frames are removed
+ int numframes;
+ int ackframe; // server only: last acknowledged frame
+ entity_frameinfo_t frames[MAX_ENTITY_HISTORY];
+ entity_state_t entitydata[MAX_ENTITY_DATABASE];
+}
+entity_database_t;
+
+// build entity data in this, to pass to entity read/write functions
+typedef struct
+{
+ int framenum;
+ int numentities;
+ entity_state_t entitydata[MAX_ENTITY_DATABASE];
+}
+entity_frame_t;
+
void ClearStateToDefault(entity_state_t *s);
+// (server) clears the database to contain no frames (thus delta compression compresses against nothing)
+void EntityFrame_ClearDatabase(entity_database_t *d);
+// (server) acknowledge a frame as recieved by client (removes old frames from database, will use this new frame for delta compression)
+void EntityFrame_AckFrame(entity_database_t *d, int frame);
+// (server) clears frame, to prepare for adding entities
+void EntityFrame_Clear(entity_frame_t *f);
+// (server) allocates an entity slot in frame, returns NULL if full
+entity_state_t *EntityFrame_NewEntity(entity_frame_t *f, int number);
+// (server) writes a frame to network stream
+void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, int deltaframe, int newframe, sizebuf_t *msg);
+// (client) reads a frame from network stream
+void EntityFrame_Read(entity_database_t *d, entity_frame_t *f);
+// (client) fetchs an entity from the database, read with _Read, fills in structs for current and previous state
+void EntityFrame_FetchEntity(entity_database_t *d, entity_state_t *previous, entity_state_t *current);
#include "quakedef.h"
-cvar_t crosshair_brightness = {CVAR_SAVE, "crosshair_brightness", "1.0"};
-cvar_t crosshair_alpha = {CVAR_SAVE, "crosshair_alpha", "1.0"};
+cvar_t crosshair_brightness = {CVAR_SAVE, "crosshair_brightness", "1"};
+cvar_t crosshair_alpha = {CVAR_SAVE, "crosshair_alpha", "1"};
cvar_t crosshair_flashspeed = {CVAR_SAVE, "crosshair_flashspeed", "2"};
cvar_t crosshair_flashrange = {CVAR_SAVE, "crosshair_flashrange", "0.1"};
+cvar_t crosshair_size = {CVAR_SAVE, "crosshair_size", "1"};
// must match NUMCROSSHAIRS in gl_draw.c
#define NUMCROSSHAIRS 5
Cvar_RegisterVariable(&crosshair_alpha);
Cvar_RegisterVariable(&crosshair_flashspeed);
Cvar_RegisterVariable(&crosshair_flashrange);
+ Cvar_RegisterVariable(&crosshair_size);
}
void DrawCrosshair(int num)
int i;
byte *color;
float scale, base;
+ char *picname;
+ cachepic_t *pic;
if (num < 0 || num >= NUMCROSSHAIRS)
num = 0;
if (cl.viewentity)
else
base = 0.0f;
scale = crosshair_brightness.value * (1.0f / 255.0f);
- DrawQ_Pic(vid.conwidth * 0.5f - 8.0f, vid.conheight * 0.5f - 8.0f, va("gfx/crosshair%i.tga", num + 1), 16.0f, 16.0f, color[0] * scale + base, color[1] * scale + base, color[2] * scale + base, crosshair_alpha.value, 0);
+ picname = va("gfx/crosshair%i.tga", num + 1);
+ pic = Draw_CachePic(picname);
+ if (pic)
+ DrawQ_Pic((vid.conwidth - pic->width * crosshair_size.value) * 0.5f, (vid.conheight - pic->height * crosshair_size.value) * 0.5f, picname, pic->width * crosshair_size.value, pic->height * crosshair_size.value, color[0] * scale + base, color[1] * scale + base, color[2] * scale + base, crosshair_alpha.value, 0);
}
#include "r_modules.h"
-extern qboolean lighthalf;
+extern float overbrightscale;
#include "r_lerpanim.h"
extern qboolean scr_skipupdate;
extern cvar_t scr_viewsize;
-extern cvar_t r_brightness;
-extern cvar_t r_contrast;
-extern cvar_t gl_lightmode;
extern cvar_t scr_viewsize;
extern cvar_t crosshair;
+extern cvar_t crosshair_size;
extern cvar_t showfps;
typedef struct
{
- // these are set with GL_BeginRendering and can change from frame to frame
+ // these are set with VID_GetWindowSize and can change from frame to frame
int realx;
int realy;
int realwidth;
// sets hardware gamma correction, returns false if the device does not support gamma control
int VID_SetGamma (float prescale, float gamma, float scale, float base);
+
+void VID_GetWindowSize (int *x, int *y, int *width, int *height);
+
+void VID_Finish (void);
/*
=================
-GL_BeginRendering
-
+VID_GetWindowSize
=================
*/
-void GL_BeginRendering (int *x, int *y, int *width, int *height)
+void VID_GetWindowSize (int *x, int *y, int *width, int *height)
{
*x = *y = 0;
*width = scr_width;
*height = scr_height;
-
-// if (!wglMakeCurrent( maindc, baseRC ))
-// Sys_Error ("wglMakeCurrent failed");
-
-// glViewport (*x, *y, *width, *height);
}
-
-void GL_EndRendering (void)
+void VID_Finish (void)
{
- if (!r_render.integer)
- return;
- glFlush();
- fxMesaSwapBuffers();
+ if (r_render.integer)
+ {
+ glFinish();
+ fxMesaSwapBuffers();
+ }
}
static int resolutions[][3]={
/*
=================
-GL_BeginRendering
-
+VID_GetWindowSize
=================
*/
-void GL_BeginRendering (int *x, int *y, int *width, int *height)
+void VID_GetWindowSize (int *x, int *y, int *width, int *height)
{
*x = *y = 0;
*width = scr_width;
*height = scr_height;
-
-// glViewport (*x, *y, *width, *height);
}
-
-void GL_EndRendering (void)
+void VID_Finish (void)
{
int usemouse;
- if (!r_render.integer)
- return;
- glFlush();
- glXSwapBuffers(vidx11_display, win);
+ if (r_render.integer)
+ {
+ glFinish();
+ glXSwapBuffers(vidx11_display, win);
+ }
// handle the mouse state when windowed if that's changed
usemouse = false;
/*
=================
-GL_BeginRendering
-
+VID_GetWindowSize
=================
*/
-void GL_BeginRendering (int *x, int *y, int *width, int *height)
+void VID_GetWindowSize (int *x, int *y, int *width, int *height)
{
*x = *y = 0;
*width = WindowRect.right - WindowRect.left;
*height = WindowRect.bottom - WindowRect.top;
-
-// if (!wglMakeCurrent( maindc, baseRC ))
-// Sys_Error ("wglMakeCurrent failed");
-
-// glViewport (*x, *y, *width, *height);
}
-void GL_EndRendering (void)
+void VID_Finish (void)
{
int usemouse;
if (r_render.integer && !scr_skipupdate)
+ {
+ glFinish();
SwapBuffers(maindc);
+ }
// handle the mouse state when windowed if that's changed
usemouse = false;