From b91033966317d4d6a2a6bdf2952291fc88e3f7c4 Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Fri, 25 Jan 2002 00:45:55 +0000 Subject: [PATCH] added cl_screen.c/h (eventually most 2D stuff should be moved here) removed view.h (merged into client.h) cleaned up the animation interpolation code (CL_LerpUpdate) a bit more increased interpolation 'teleport' tolerance from 400 units to 1000 units per frame changed calls to Mod_ForName to not use checkdisk (except for viewthing model changes and map changes) added viewent to r_refdef moved v_blend to r_refdef all 2D art now goes through Draw_CachePic cachepic replaced qpic (in all non-wad code) moved all engine generated pics (mousepointer, crosshairs) to gl_draw.c (they are called by Draw_CachePic) cachepic now uses a hash lookup instead of just a string search added drawqueue to r_refdef all 2D art now goes through DrawQ_ functions (drawqueue) DrawQ_String now stretchs the character texture a tiny bit, and always uses default filtering cleaned out some old cruft in console drawing code fixed some silly bugs in showfps made showfps display use only 4 characters, and made the text larger, and moved it down a little moved showfps from gl_screen.c to sbar.c moved Draw_ConsoleBackground to console.c removed drawinput parameter from Con_DrawConsole (it was always true) c_alias_polys now counts all meshs rendered (a model may be rendered multiple times), not just the total number of triangles in the model, much more accurate r_speeds2 renamed to r_speeds disabled all Mem_CheckSentinelsGlobal calls during gameplay (they were wasting time) r_speeds now displays time spent throughout SCR_UpdateScreen code, not just R_RenderView frame is now rendered in 'finish begin render' order instead of 'begin render finish' order in SCR_Updatescreen - not sure if this is a speedup or not BLOCK_SIZE in gl_textures.c renamed to block_size and now adjustable (r_max_scrapsize cvar), r_restart for changes to take effect, 1024 (default) or less recommended menu, r_speeds, and showfps now have a darkened (50% black) background beneath them to improve readability menu is now centered on the screen menu text is now white translatepic code now updates texture rather than constantly cache mismatching cleaned up cshift code cleaned up viewent setup code W_GetLumpinfo failing to find a lump is no longer fatal added R_Mesh_DrawDecal for the highly specialized task of adding decals/particles/sprites to the mesh system (trying to get a minor speed gain) decals, particles, and sprites now use R_Mesh_DrawDecal git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1391 d7cf8633-e32d-0410-b094-e92efae38249 --- buildnumber.c | 2 +- cl_main.c | 32 +- cl_parse.c | 12 +- cl_screen.c | 249 ++++++++++++++ cl_screen.h | 33 ++ cl_tent.c | 8 +- client.h | 26 +- console.c | 81 ++--- console.h | 2 +- draw.h | 28 +- gl_backend.c | 357 ++++++++++++++----- gl_backend.h | 4 +- gl_draw.c | 915 ++++++++++++++++++++++++------------------------- gl_models.c | 5 +- gl_rmain.c | 29 +- gl_screen.c | 373 ++++++-------------- gl_textures.c | 30 +- glquake.h | 2 +- host.c | 2 +- host_cmd.c | 5 - keys.c | 4 +- makefile | 2 +- menu.c | 225 ++++++------ model_brush.c | 8 +- model_shared.c | 62 ++-- net_dgrm.c | 6 +- pr_cmds.c | 46 ++- quakedef.h | 1 - r_crosshairs.c | 136 +------- r_decals.c | 353 ++++++++++++++++--- r_particles.c | 123 +++---- r_sky.c | 20 +- r_sprites.c | 35 +- render.h | 3 +- sbar.c | 261 ++++++-------- sv_main.c | 2 +- ui.c | 90 ++--- ui.h | 4 +- vid_wgl.c | 14 +- view.c | 633 ++++++++++------------------------ view.h | 32 -- wad.c | 2 +- 42 files changed, 2144 insertions(+), 2113 deletions(-) create mode 100644 cl_screen.c create mode 100644 cl_screen.h delete mode 100644 view.h diff --git a/buildnumber.c b/buildnumber.c index 649c6ece..479b26a8 100644 --- a/buildnumber.c +++ b/buildnumber.c @@ -1,4 +1,4 @@ -#define BUILDNUMBER 716 +#define BUILDNUMBER 958 int buildnumber = BUILDNUMBER; diff --git a/cl_main.c b/cl_main.c index 5eb85160..f06057c2 100644 --- a/cl_main.c +++ b/cl_main.c @@ -106,6 +106,7 @@ void CL_ClearState (void) memset(cl_beams, 0, sizeof(cl_beams)); memset(cl_dlights, 0, sizeof(cl_dlights)); memset(cl_effect, 0, sizeof(cl_effect)); + CL_Screen_NewMap(); CL_Particles_Clear(); CL_Decals_Clear(); // LordHavoc: have to set up the baseline info for alpha and other stuff @@ -117,27 +118,27 @@ void CL_ClearState (void) } } -void CL_LerpUpdate(entity_t *e, int frame, int modelindex) +void CL_LerpUpdate(entity_t *e) { entity_persistent_t *p; entity_render_t *r; p = &e->persistent; r = &e->render; - if (p->modelindex != modelindex) + if (p->modelindex != e->state_current.modelindex) { // reset all interpolation information - p->modelindex = modelindex; - p->frame1 = p->frame2 = frame; + p->modelindex = e->state_current.modelindex; + p->frame1 = p->frame2 = e->state_current.frame; p->frame1time = p->frame2time = cl.time; p->framelerp = 1; } - else if (p->frame2 != frame) + else if (p->frame2 != e->state_current.frame) { // transition to new frame p->frame1 = p->frame2; p->frame1time = p->frame2time; - p->frame2 = frame; + p->frame2 = e->state_current.frame; p->frame2time = cl.time; p->framelerp = 0; } @@ -148,6 +149,9 @@ void CL_LerpUpdate(entity_t *e, int frame, int modelindex) p->framelerp = bound(0, p->framelerp, 1); } + r->model = cl.model_precache[e->state_current.modelindex]; + Mod_CheckLoaded(r->model); + r->frame = e->state_current.frame; r->frame1 = p->frame1; r->frame2 = p->frame2; r->framelerp = p->framelerp; @@ -430,8 +434,8 @@ static void CL_RelinkNetworkEntities() // if the delta is large, assume a teleport and don't lerp VectorSubtract(ent->state_current.origin, ent->state_previous.origin, delta); - // LordHavoc: increased tolerance from 100 to 200 - if ((sv.active && svs.maxclients == 1 && !(ent->state_current.flags & RENDER_STEP)) || cls.timedemo || DotProduct(delta, delta) > 200*200 || cl_nolerp.integer) + // LordHavoc: increased tolerance from 100 to 200, and now to 1000 + if ((sv.active && svs.maxclients == 1 && !(ent->state_current.flags & RENDER_STEP)) || cls.timedemo || DotProduct(delta, delta) > 1000*1000 || cl_nolerp.integer) lerp = 1; else { @@ -461,15 +465,12 @@ static void CL_RelinkNetworkEntities() VectorCopy (neworg, ent->persistent.trail_origin); // persistent.modelindex will be updated by CL_LerpUpdate - if (ent->state_current.modelindex != ent->persistent.modelindex || !ent->state_previous.active) + if (ent->state_current.modelindex != ent->persistent.modelindex) VectorCopy(neworg, oldorg); VectorCopy (neworg, ent->render.origin); ent->render.flags = ent->state_current.flags; ent->render.effects = effects = ent->state_current.effects; - ent->render.model = cl.model_precache[ent->state_current.modelindex]; - Mod_CheckLoaded(ent->render.model); - ent->render.frame = ent->state_current.frame; if (cl.scores == NULL || !ent->state_current.colormap) ent->render.colormap = -1; // no special coloring else @@ -477,11 +478,9 @@ static void CL_RelinkNetworkEntities() ent->render.skinnum = ent->state_current.skin; ent->render.alpha = ent->state_current.alpha * (1.0f / 255.0f); // FIXME: interpolate? ent->render.scale = ent->state_current.scale * (1.0f / 16.0f); // FIXME: interpolate? - glowsize = ent->state_current.glowsize * 4.0f; // FIXME: interpolate? - glowcolor = ent->state_current.glowcolor; // update interpolation info - CL_LerpUpdate(ent, ent->state_current.frame, ent->state_current.modelindex); + CL_LerpUpdate(ent); // handle effects now... dlightradius = 0; @@ -602,6 +601,8 @@ static void CL_RelinkNetworkEntities() } } // LordHavoc: customizable glow + glowsize = ent->state_current.glowsize * 4.0f; // FIXME: interpolate? + glowcolor = ent->state_current.glowcolor; if (glowsize) { byte *tempcolor = (byte *)&d_8to24table[glowcolor]; @@ -977,4 +978,5 @@ void CL_Init (void) CL_Parse_Init(); CL_Particles_Init(); CL_Decals_Init(); + CL_Screen_Init(); } diff --git a/cl_parse.c b/cl_parse.c index d7661dd4..d8d7702c 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -405,8 +405,6 @@ void CL_ParseServerInfo (void) Mod_ClearUsed(); - Mem_CheckSentinelsGlobal(); - // precache models memset (cl.model_precache, 0, sizeof(cl.model_precache)); for (nummodels=1 ; ; nummodels++) @@ -416,7 +414,7 @@ void CL_ParseServerInfo (void) break; if (nummodels==MAX_MODELS) { - Con_Printf ("Server sent too many model precaches\n"); + Host_Error ("Server sent too many model precaches\n"); return; } if (strlen(str) >= MAX_QPATH) @@ -434,7 +432,7 @@ void CL_ParseServerInfo (void) break; if (numsounds==MAX_SOUNDS) { - Con_Printf ("Server sent too many sound precaches\n"); + Host_Error ("Server sent too many sound precaches\n"); return; } if (strlen(str) >= MAX_QPATH) @@ -443,8 +441,6 @@ void CL_ParseServerInfo (void) S_TouchSound (str); } - Mem_CheckSentinelsGlobal(); - Mod_PurgeUnused(); // @@ -456,11 +452,11 @@ void CL_ParseServerInfo (void) for (i=1 ; iwidth*dat->height <= 4096) + memcpy (menuplyr_pixels, dat->data, dat->width * dat->height); + else + Con_Printf("gfx/menuplyr.lmp larger than 4k buffer"); + free(dat); +} + +void DrawQ_Clear(void) +{ + r_refdef.drawqueuesize = 0; +} + +void DrawQ_Pic(float x, float y, char *picname, float width, float height, float red, float green, float blue, float alpha, int flags) +{ + int size; + drawqueue_t *dq; + if (alpha < (1.0f / 255.0f)) + return; + size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3); + if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + return; + red = bound(0, red, 1); + green = bound(0, green, 1); + blue = bound(0, blue, 1); + alpha = bound(0, alpha, 1); + dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize); + dq->size = size; + dq->command = DRAWQUEUE_PIC; + dq->flags = flags; + dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f)); + dq->x = x; + dq->y = y; + // if these are not zero, they override the pic's size + dq->scalex = width; + dq->scaley = height; + strcpy((char *)(dq + 1), picname); + r_refdef.drawqueuesize += dq->size; +} + +void DrawQ_String(float x, float y, char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags) +{ + int size, len; + drawqueue_t *dq; + char *out; + if (alpha < (1.0f / 255.0f)) + return; + if (maxlen < 1) + len = strlen(string); + else + for (len = 0;len < maxlen && string[len];len++); + for (;len > 0 && string[0] == ' ';string++, x += scalex, len--); + for (;len > 0 && string[len - 1] == ' ';len--); + if (len < 1) + return; + if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley)) + return; + size = sizeof(*dq) + ((len + 1 + 3) & ~3); + if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + return; + red = bound(0, red, 1); + green = bound(0, green, 1); + blue = bound(0, blue, 1); + alpha = bound(0, alpha, 1); + dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize); + dq->size = size; + dq->command = DRAWQUEUE_STRING; + dq->flags = flags; + dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f)); + dq->x = x; + dq->y = y; + dq->scalex = scalex; + dq->scaley = scaley; + out = (char *)(dq + 1); + memcpy(out, string, len); + out[len] = 0; + r_refdef.drawqueuesize += dq->size; +} + +void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags) +{ + int size; + drawqueue_t *dq; + if (alpha < (1.0f / 255.0f)) + return; + size = sizeof(*dq) + 4; + if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + return; + red = bound(0, red, 1); + green = bound(0, green, 1); + blue = bound(0, blue, 1); + alpha = bound(0, alpha, 1); + dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize); + dq->size = size; + dq->command = DRAWQUEUE_PIC; + dq->flags = flags; + dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f)); + dq->x = x; + dq->y = y; + dq->scalex = w; + dq->scaley = h; + // empty pic name + *((char *)(dq + 1)) = 0; + r_refdef.drawqueuesize += dq->size; +} + +//only used for the player color selection menu +void DrawQ_PicTranslate (int x, int y, char *picname, byte *translation) +{ + int i, c; + unsigned int trans[4096]; + cachepic_t *pic; + + pic = Draw_CachePic(picname); + if (pic == NULL) + return; + + c = pic->width * pic->height; + if (c > 4096) + { + Con_Printf("DrawQ_PicTranslate: image larger than 4k buffer\n"); + return; + } + + for (i = 0;i < c;i++) + trans[i] = d_8to24table[translation[menuplyr_pixels[i]]]; + + // FIXME: this is renderer stuff? + R_UpdateTexture (pic->tex, (byte *)trans); + + DrawQ_Pic(x, y, picname, 0, 0, 1, 1, 1, 1, 0); +} + +void V_CalcRefdef (void); +void CL_UpdateScreen(void) +{ + DrawQ_Clear(); + + SHOWLMP_drawall(); + + V_UpdateBlends(); + V_CalcRefdef (); + + SCR_UpdateScreen(); +} + +void CL_Screen_NewMap(void) +{ + SHOWLMP_clear(); +} + +//============================================================================= + +// LordHavoc: SHOWLMP stuff +#define SHOWLMP_MAXLABELS 256 +typedef struct showlmp_s +{ + qboolean isactive; + float x; + float y; + char label[32]; + char pic[128]; +} +showlmp_t; + +showlmp_t showlmp[SHOWLMP_MAXLABELS]; + +void SHOWLMP_decodehide(void) +{ + int i; + byte *lmplabel; + lmplabel = MSG_ReadString(); + for (i = 0;i < SHOWLMP_MAXLABELS;i++) + if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0) + { + showlmp[i].isactive = false; + return; + } +} + +void SHOWLMP_decodeshow(void) +{ + int i, k; + byte lmplabel[256], picname[256]; + float x, y; + strcpy(lmplabel,MSG_ReadString()); + strcpy(picname, MSG_ReadString()); + if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk + { + x = MSG_ReadByte(); + y = MSG_ReadByte(); + } + else + { + x = MSG_ReadShort(); + y = MSG_ReadShort(); + } + k = -1; + for (i = 0;i < SHOWLMP_MAXLABELS;i++) + if (showlmp[i].isactive) + { + if (strcmp(showlmp[i].label, lmplabel) == 0) + { + k = i; + break; // drop out to replace it + } + } + else if (k < 0) // find first empty one to replace + k = i; + if (k < 0) + return; // none found to replace + // change existing one + showlmp[k].isactive = true; + strcpy(showlmp[k].label, lmplabel); + strcpy(showlmp[k].pic, picname); + showlmp[k].x = x; + showlmp[k].y = y; +} + +void SHOWLMP_drawall(void) +{ + int i; + if (cl.worldmodel) + for (i = 0;i < SHOWLMP_MAXLABELS;i++) + if (showlmp[i].isactive) + DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0); +} + +void SHOWLMP_clear(void) +{ + int i; + for (i = 0;i < SHOWLMP_MAXLABELS;i++) + showlmp[i].isactive = false; +} diff --git a/cl_screen.h b/cl_screen.h new file mode 100644 index 00000000..21e3e951 --- /dev/null +++ b/cl_screen.h @@ -0,0 +1,33 @@ + +// drawqueue stuff for use by client to feed 2D art to renderer +#define MAX_DRAWQUEUE 1048576 + +#define DRAWQUEUE_PIC 0 +#define DRAWQUEUE_STRING 1 + +typedef struct drawqueue_s +{ + unsigned short size; + byte command, flags; + unsigned int color; + float x, y, scalex, scaley; +} +drawqueue_t; + +#define DRAWFLAG_ADDITIVE 1 + +void DrawQ_Clear(void); +void DrawQ_Pic(float x, float y, char *picname, float width, float height, float red, float green, float blue, float alpha, int flags); +void DrawQ_String(float x, float y, char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags); +void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags); +// only used for player config menu +void DrawQ_PicTranslate (int x, int y, char *picname, byte *translation); + +void SHOWLMP_decodehide(void); +void SHOWLMP_decodeshow(void); +void SHOWLMP_drawall(void); +void SHOWLMP_clear(void); + +void CL_Screen_NewMap(void); +void CL_Screen_Init(void); +void CL_UpdateScreen(void); diff --git a/cl_tent.c b/cl_tent.c index a4f72932..1cdc8e04 100644 --- a/cl_tent.c +++ b/cl_tent.c @@ -366,26 +366,26 @@ void CL_ParseTEnt (void) case TE_LIGHTNING1: // lightning bolts if (!cl_model_bolt) - cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, true, false); + cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false); CL_ParseBeam (cl_model_bolt); break; case TE_LIGHTNING2: // lightning bolts if (!cl_model_bolt2) - cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, true, false); + cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false); CL_ParseBeam (cl_model_bolt2); break; case TE_LIGHTNING3: // lightning bolts if (!cl_model_bolt3) - cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, true, false); + cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false); CL_ParseBeam (cl_model_bolt3); break; // PGM 01/21/97 case TE_BEAM: // grappling hook beam if (!cl_model_beam) - cl_model_beam = Mod_ForName("progs/beam.mdl", true, true, false); + cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false); CL_ParseBeam (cl_model_beam); break; // PGM 01/21/97 diff --git a/client.h b/client.h index 97379bcd..7d29a988 100644 --- a/client.h +++ b/client.h @@ -362,7 +362,7 @@ void CL_InitInput (void); void CL_SendCmd (void); void CL_SendMove (usercmd_t *cmd); -void CL_LerpUpdate(entity_t *e, int frame, int modelindex); +void CL_LerpUpdate(entity_t *e); void CL_ParseTEnt (void); void CL_UpdateTEnts (void); @@ -406,11 +406,10 @@ void CL_BitProfile_f(void); void V_StartPitchDrift (void); void V_StopPitchDrift (void); -void V_RenderView (void); +void V_Init (void); +float V_CalcRoll (vec3_t angles, vec3_t velocity); void V_UpdateBlends (void); -void V_Register (void); void V_ParseDamage (void); -void V_SetContentsColor (int contents); // @@ -490,17 +489,25 @@ void CL_Decal(vec3_t origin, int tex, float scale, float red, float green, float extern int traceline_endcontents; // set by TraceLine float TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents); +#include "cl_screen.h" + #define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES) typedef struct { // area to render in - int x, y, width, height; - float fov_x, fov_y; + int x, y, width, height; + float fov_x, fov_y; // view point - vec3_t vieworg; - vec3_t viewangles; + vec3_t vieworg; + vec3_t viewangles; + + // fullscreen color blend + float viewblend[4]; + + // weapon model + entity_render_t viewent; int numdecals; renderdecal_t *decals; @@ -510,6 +517,9 @@ typedef struct int numparticles; struct renderparticle_s *particles; + + byte drawqueue[MAX_DRAWQUEUE]; + int drawqueuesize; } refdef_t; diff --git a/console.c b/console.c index d8654f31..e99181e9 100644 --- a/console.c +++ b/console.c @@ -284,7 +284,7 @@ void Con_Print (char *txt) int c, l; static int cr; int mask; - + con_backscroll = 0; if (txt[0] == 1) @@ -441,7 +441,7 @@ void Con_DPrintf (char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; - + if (!developer.integer) return; // don't confuse non-developers with techie stuff... @@ -497,16 +497,13 @@ Modified by EvilTypeGuy eviltypeguy@qeradiant.com */ void Con_DrawInput (void) { - int y; - char *text; - char editlinecopy[256]; + char editlinecopy[256], *text; if (key_dest != key_console && !con_forcedup) return; // don't draw anything text = strcpy(editlinecopy, key_lines[edit_line]); - y = strlen(text); - + // Advanced Console Editing by Radix radix@planetquake.com // Added/Modified by EvilTypeGuy eviltypeguy@qeradiant.com // use strlen of edit_line instead of key_linepos to allow editing @@ -515,27 +512,15 @@ void Con_DrawInput (void) // add the cursor frame if ((int)(realtime*con_cursorspeed) & 1) // cursor is visible text[key_linepos] = 11 + 130 * key_insert; // either solid or triangle facing right - - text[key_linepos + 1] = 0; // LordHavoc: null terminate, rather than padding with spaces - // text[key_linepos] = 10 + ((int)(realtime*con_cursorspeed) & 1); - - // fill out remainder with spaces - // for (i=key_linepos+1 ; i< con_linewidth ; i++) - // text[i] = ' '; - - // prestep if horizontally scrolling + text[key_linepos + 1] = 0; + + // prestep if horizontally scrolling if (key_linepos >= con_linewidth) text += 1 + key_linepos - con_linewidth; - - // draw it - y = con_vislines - 16; - // for (i=0 ; i con_notifytime.value) continue; text = con_text + (i % con_totallines)*con_linewidth; - + clearnotify = 0; -// for (x = 0 ; x < con_linewidth ; x++) -// Draw_Character ( (x+1)<<3, v, text[x]); - // LordHavoc: speedup - Draw_String(8, v, text, con_linewidth); + DrawQ_String(8, v, text, con_linewidth, 8, 8, 1, 1, 1, 1, 0); v += 8; } @@ -585,9 +567,9 @@ void Con_DrawNotify (void) if (key_dest == key_message) { clearnotify = 0; - + x = 0; - + // LordHavoc: speedup, and other improvements if (team_message) sprintf(temptext, "say_team:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1)); @@ -595,25 +577,17 @@ void Con_DrawNotify (void) sprintf(temptext, "say:%s%c", chat_buffer, (int) 10+((int)(realtime*con_cursorspeed)&1)); while (strlen(temptext) >= con_linewidth) { - Draw_String (8, v, temptext, con_linewidth); + DrawQ_String (8, v, temptext, con_linewidth, 8, 8, 1, 1, 1, 1, 0); strcpy(temptext, &temptext[con_linewidth]); v += 8; } if (strlen(temptext) > 0) { - Draw_String (8, v, temptext, 0); + DrawQ_String (8, v, temptext, 0, 8, 8, 1, 1, 1, 1, 0); v += 8; } -// Draw_String (8, v, "say:", 0); -// while(chat_buffer[x]) -// { -// Draw_Character ( (x+5)<<3, v, chat_buffer[x]); -// x++; -// } -// Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1)); -// v += 8; } - + if (v > con_notifylines) con_notifylines = v; } @@ -626,18 +600,21 @@ Draws the console with the solid background The typing input line at the bottom should only be drawn if typing is allowed ================ */ -void Con_DrawConsole (int lines, qboolean drawinput) +extern cvar_t scr_conalpha; +extern char engineversion[40]; +void Con_DrawConsole (int lines) { int i, y; int rows; char *text; int j; - + if (lines <= 0) return; // draw the background - Draw_ConsoleBackground (lines); + DrawQ_Pic(0, lines - vid.conheight, "gfx/conback", vid.conwidth, vid.conheight, 1, 1, 1, scr_conalpha.value * lines / vid.conheight, 0); + DrawQ_String(vid.conwidth - strlen(engineversion) * 8 - 8, lines - 8, engineversion, 0, 8, 8, 1, 0, 0, 1, 0); // draw the text con_vislines = lines; @@ -645,22 +622,16 @@ void Con_DrawConsole (int lines, qboolean drawinput) rows = (lines-16)>>3; // rows of text to draw y = lines - 16 - (rows<<3); // may start slightly negative - for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 ) + for (i = con_current - rows + 1;i <= con_current;i++, y += 8) { - j = i - con_backscroll; - if (j<0) - j = 0; + j = max(i - con_backscroll, 0); text = con_text + (j % con_totallines)*con_linewidth; -// for (x=0 ; xblendfunc2 == GL_SRC_COLOR) + { + if (m->blendfunc1 == GL_DST_COLOR) // 2x modulate with framebuffer + scaler *= 0.5f; + } + else + { + if (m->tex[0]) + { + overbright = gl_combine.integer; + if (overbright) + scaler *= 0.25f; + } + if (lighthalf) + scaler *= 0.5f; + } if (m->transparent) { @@ -801,7 +820,7 @@ void R_Mesh_Draw(const rmeshinfo_t *m) { if (!transranout) { - Con_Printf("R_DrawMesh: ran out of room for transparent meshs\n"); + Con_Printf("R_Mesh_Draw: ran out of room for transparent meshs\n"); transranout = true; } return; @@ -812,12 +831,45 @@ void R_Mesh_Draw(const rmeshinfo_t *m) bcolor = &buf_transbcolor[currenttransvertex]; for (i = 0;i < backendunits;i++) texcoord[i] = &buf_transtexcoord[i][currenttransvertex]; + + // transmesh is only for storage of transparent meshs until they + // are inserted into the main mesh array + mesh = &buf_transmesh[currenttransmesh++]; + mesh->blendfunc1 = m->blendfunc1; + mesh->blendfunc2 = m->blendfunc2; + mesh->depthmask = false; + mesh->depthtest = !m->depthdisable; + j = -1; + for (i = 0;i < backendunits;i++) + { + if ((mesh->textures[i] = m->tex[i])) + j = i; + mesh->texturergbscale[i] = m->texrgbscale[i]; + if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4) + mesh->texturergbscale[i] = 1; + } + if (overbright && j >= 0) + mesh->texturergbscale[j] = 4; + + // transparent meshs are broken up into individual triangles which can + // be sorted by depth + index = m->index; + for (i = 0;i < m->numtriangles;i++) + { + tri = &buf_transtri[currenttranstriangle++]; + tri->mesh = mesh; + tri->index[0] = *index++ + currenttransvertex; + tri->index[1] = *index++ + currenttransvertex; + tri->index[2] = *index++ + currenttransvertex; + } + + currenttransvertex += m->numverts; } else { if (m->numtriangles > max_meshs || m->numverts > max_verts) { - Con_Printf("R_DrawMesh: mesh too big for buffers\n"); + Con_Printf("R_Mesh_Draw: mesh too big for buffers\n"); return; } @@ -829,37 +881,63 @@ void R_Mesh_Draw(const rmeshinfo_t *m) bcolor = &buf_bcolor[currentvertex]; for (i = 0;i < backendunits;i++) texcoord[i] = &buf_texcoord[i][currentvertex]; + + mesh = &buf_mesh[currentmesh++]; + mesh->blendfunc1 = m->blendfunc1; + mesh->blendfunc2 = m->blendfunc2; + mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite); + mesh->depthtest = !m->depthdisable; + mesh->firsttriangle = currenttriangle; + mesh->triangles = m->numtriangles; + j = -1; + for (i = 0;i < backendunits;i++) + { + if ((mesh->textures[i] = m->tex[i])) + j = i; + mesh->texturergbscale[i] = m->texrgbscale[i]; + if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4) + mesh->texturergbscale[i] = 1; + } + if (overbright && j >= 0) + mesh->texturergbscale[j] = 4; + + // opaque meshs are rendered directly + index = (int *)&buf_tri[currenttriangle]; + for (i = 0;i < m->numtriangles * 3;i++) + index[i] = m->index[i] + currentvertex; + mesh->firstvert = currentvertex; + currenttriangle += m->numtriangles; + currentvertex += m->numverts; + mesh->lastvert = currentvertex - 1; } // vertex array code is shared for transparent and opaque meshs - for (i = 0, in = m->vertex;i < m->numverts;i++, (int)in += m->vertexstep) - { - vert[i].v[0] = in[0]; - vert[i].v[1] = in[1]; - vert[i].v[2] = in[2]; - // push out farclip based on vertices encountered - c = DotProduct(vert[i].v, vpn); - if (meshfarclip < c) - meshfarclip = c; - } + c_meshtris += m->numtriangles; - scaler = 1; - if (m->blendfunc2 == GL_SRC_COLOR) + if (m->vertexstep != sizeof(buf_vertex_t)) { - if (m->blendfunc1 == GL_DST_COLOR) // 2x modulate with framebuffer - scaler *= 0.5f; + for (i = 0, in = m->vertex;i < m->numverts;i++, (int)in += m->vertexstep) + { + vert[i].v[0] = in[0]; + vert[i].v[1] = in[1]; + vert[i].v[2] = in[2]; + // push out farclip based on vertices encountered + c = DotProduct(vert[i].v, vpn); + if (meshfarclip < c) + meshfarclip = c; + } } else { - if (m->tex[0]) + memcpy(vert, m->vertex, m->numverts * sizeof(buf_vertex_t)); + // push out farclip based on vertices encountered + for (i = 0;i < m->numverts;i++) { - overbright = gl_combine.integer; - if (overbright) - scaler *= 0.25f; + c = DotProduct(vert[i].v, vpn); + if (meshfarclip < c) + meshfarclip = c; } - if (lighthalf) - scaler *= 0.5f; } if (floatcolors) @@ -922,104 +1000,221 @@ void R_Mesh_Draw(const rmeshinfo_t *m) for (j = 0;j < MAX_TEXTUREUNITS && m->tex[j];j++) { if (j >= backendunits) - Sys_Error("R_DrawMesh: texture %i supplied when there are only %i texture units\n", j + 1, backendunits); - for (i = 0, in = m->texcoords[j];i < m->numverts;i++, (int)in += m->texcoordstep[j]) + Sys_Error("R_Mesh_Draw: texture %i supplied when there are only %i texture units\n", j + 1, backendunits); + if (m->texcoordstep[j] != sizeof(buf_texcoord_t)) { - texcoord[j][i].t[0] = in[0]; - texcoord[j][i].t[1] = in[1]; + for (i = 0, in = m->texcoords[j];i < m->numverts;i++, (int)in += m->texcoordstep[j]) + { + texcoord[j][i].t[0] = in[0]; + texcoord[j][i].t[1] = in[1]; + } } + else + memcpy(&texcoord[j][0].t[0], m->texcoords[j], m->numverts * sizeof(buf_texcoord_t)); } + #if 0 for (;j < backendunits;j++) + memset(&texcoord[j][0].t[0], 0, m->numverts * sizeof(buf_texcoord_t)); + #endif +} + +void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts) +{ + m->index = polyindexarray; + m->numverts = numverts; + m->numtriangles = numverts - 2; + if (m->numtriangles < 1) { - for (i = 0;i < m->numverts;i++) - { - texcoord[j][i].t[0] = 0; - texcoord[j][i].t[1] = 0; - } + Con_Printf("R_Mesh_DrawPolygon: invalid vertex count\n"); + return; + } + if (m->numtriangles >= 256) + { + Con_Printf("R_Mesh_DrawPolygon: only up to 256 triangles (258 verts) supported\n"); + return; } + R_Mesh_Draw(m); +} + +// LordHavoc: this thing is evil, but necessary because decals account for so much overhead +void R_Mesh_DrawDecal(const rmeshinfo_t *m) +{ + // these are static because gcc runs out of virtual registers otherwise + static int i, j, *index, overbright; + static float c, *in, scaler, cr, cg, cb, ca; + static buf_mesh_t *mesh; + static buf_vertex_t *vert; + static buf_fcolor_t *fcolor; + static buf_bcolor_t *bcolor; + static buf_texcoord_t *texcoord; + static buf_transtri_t *tri; + static byte br, bg, bb, ba; + + if (!backendactive) + Sys_Error("R_Mesh_Draw: called when backend is not active\n"); + + scaler = 1; + if (m->tex[0]) + { + overbright = gl_combine.integer; + if (overbright) + scaler *= 0.25f; + } + if (lighthalf) + scaler *= 0.5f; if (m->transparent) { - // transmesh is only for storage of tranparent meshs until they + if (currenttransmesh >= max_meshs || (currenttranstriangle + 2) > max_meshs || (currenttransvertex + 4) > max_verts) + { + if (!transranout) + { + Con_Printf("R_Mesh_Draw: ran out of room for transparent meshs\n"); + transranout = true; + } + return; + } + + vert = &buf_transvertex[currenttransvertex]; + fcolor = &buf_transfcolor[currenttransvertex]; + bcolor = &buf_transbcolor[currenttransvertex]; + texcoord = &buf_transtexcoord[0][currenttransvertex]; + + // transmesh is only for storage of transparent meshs until they // are inserted into the main mesh array mesh = &buf_transmesh[currenttransmesh++]; mesh->blendfunc1 = m->blendfunc1; mesh->blendfunc2 = m->blendfunc2; mesh->depthmask = false; - mesh->depthtest = !m->depthdisable; - j = -1; - for (i = 0;i < backendunits;i++) + mesh->depthtest = true; + mesh->textures[0] = m->tex[0]; + mesh->texturergbscale[0] = overbright ? 4 : 1; + for (i = 1;i < backendunits;i++) { - if ((mesh->textures[i] = m->tex[i])) - j = i; - mesh->texturergbscale[i] = m->texrgbscale[i]; - if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4) - mesh->texturergbscale[i] = 1; + mesh->textures[i] = 0; + mesh->texturergbscale[i] = 1; } - if (overbright && j >= 0) - mesh->texturergbscale[j] = 4; // transparent meshs are broken up into individual triangles which can // be sorted by depth index = m->index; - for (i = 0;i < m->numtriangles;i++) - { - tri = &buf_transtri[currenttranstriangle++]; - tri->mesh = mesh; - tri->index[0] = *index++ + currenttransvertex; - tri->index[1] = *index++ + currenttransvertex; - tri->index[2] = *index++ + currenttransvertex; - } - currenttransvertex += m->numverts; + tri = &buf_transtri[currenttranstriangle++]; + tri->mesh = mesh; + tri->index[0] = 0 + currenttransvertex; + tri->index[1] = 1 + currenttransvertex; + tri->index[2] = 2 + currenttransvertex; + tri = &buf_transtri[currenttranstriangle++]; + tri->mesh = mesh; + tri->index[0] = 0 + currenttransvertex; + tri->index[1] = 2 + currenttransvertex; + tri->index[2] = 3 + currenttransvertex; + + currenttransvertex += 4; } else { + if (2 > max_meshs || 4 > max_verts) + { + Con_Printf("R_Mesh_Draw: mesh too big for buffers\n"); + return; + } + + if (currentmesh >= max_meshs || (currenttriangle + 2) > max_batch || (currentvertex + 4) > max_verts) + R_Mesh_Render(); + + vert = &buf_vertex[currentvertex]; + fcolor = &buf_fcolor[currentvertex]; + bcolor = &buf_bcolor[currentvertex]; + texcoord = &buf_texcoord[0][currentvertex]; + mesh = &buf_mesh[currentmesh++]; mesh->blendfunc1 = m->blendfunc1; mesh->blendfunc2 = m->blendfunc2; - mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite); + mesh->depthmask = false; mesh->depthtest = !m->depthdisable; mesh->firsttriangle = currenttriangle; - mesh->triangles = m->numtriangles; - j = -1; - for (i = 0;i < backendunits;i++) + mesh->triangles = 2; + mesh->textures[0] = m->tex[0]; + mesh->texturergbscale[0] = overbright ? 4 : 1; + for (i = 1;i < backendunits;i++) { - if ((mesh->textures[i] = m->tex[i])) - j = i; - mesh->texturergbscale[i] = m->texrgbscale[i]; - if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4) - mesh->texturergbscale[i] = 1; + mesh->textures[i] = 0; + mesh->texturergbscale[i] = 1; } - if (overbright && j >= 0) - mesh->texturergbscale[j] = 4; // opaque meshs are rendered directly index = (int *)&buf_tri[currenttriangle]; - for (i = 0;i < m->numtriangles * 3;i++) - index[i] = m->index[i] + currentvertex; + index[0] = 0 + currentvertex; + index[1] = 1 + currentvertex; + index[2] = 2 + currentvertex; + index[3] = 0 + currentvertex; + index[4] = 2 + currentvertex; + index[5] = 3 + currentvertex; mesh->firstvert = currentvertex; - currenttriangle += m->numtriangles; - currentvertex += m->numverts; + currenttriangle += 2; + currentvertex += 4; mesh->lastvert = currentvertex - 1; } - c_meshtris += m->numtriangles; -} + // vertex array code is shared for transparent and opaque meshs -void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts) -{ - m->index = polyindexarray; - m->numverts = numverts; - m->numtriangles = numverts - 2; - if (m->numtriangles < 1) + c_meshtris += 2; + + // buf_vertex_t must match the size of the decal vertex array (or vice versa) + memcpy(vert, m->vertex, 4 * sizeof(buf_vertex_t)); + // push out farclip based on vertices encountered + c = DotProduct(vert[0].v, vpn);if (meshfarclip < c) meshfarclip = c; + c = DotProduct(vert[1].v, vpn);if (meshfarclip < c) meshfarclip = c; + c = DotProduct(vert[2].v, vpn);if (meshfarclip < c) meshfarclip = c; + c = DotProduct(vert[3].v, vpn);if (meshfarclip < c) meshfarclip = c; + + if (floatcolors) { - Con_Printf("R_Mesh_DrawPolygon: invalid vertex count\n"); - return; + cr = m->cr * scaler; + cg = m->cg * scaler; + cb = m->cb * scaler; + ca = m->ca; + fcolor[0].c[0] = cr; + fcolor[0].c[1] = cg; + fcolor[0].c[2] = cb; + fcolor[0].c[3] = ca; + fcolor[1].c[0] = cr; + fcolor[1].c[1] = cg; + fcolor[1].c[2] = cb; + fcolor[1].c[3] = ca; + fcolor[2].c[0] = cr; + fcolor[2].c[1] = cg; + fcolor[2].c[2] = cb; + fcolor[2].c[3] = ca; + fcolor[3].c[0] = cr; + fcolor[3].c[1] = cg; + fcolor[3].c[2] = cb; + fcolor[3].c[3] = ca; } - if (m->numtriangles >= 256) + else { - Con_Printf("R_Mesh_DrawPolygon: only up to 256 triangles (258 verts) supported\n"); - return; + c = in[0] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;br = (byte) j; + c = in[1] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bg = (byte) j; + c = in[2] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bb = (byte) j; + c = in[3] + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;ba = (byte) j; + bcolor[0].c[0] = br; + bcolor[0].c[1] = bg; + bcolor[0].c[2] = bb; + bcolor[0].c[3] = ba; + bcolor[1].c[0] = br; + bcolor[1].c[1] = bg; + bcolor[1].c[2] = bb; + bcolor[1].c[3] = ba; + bcolor[2].c[0] = br; + bcolor[2].c[1] = bg; + bcolor[2].c[2] = bb; + bcolor[2].c[3] = ba; + bcolor[3].c[0] = br; + bcolor[3].c[1] = bg; + bcolor[3].c[2] = bb; + bcolor[3].c[3] = ba; } - R_Mesh_Draw(m); + + // 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)); } diff --git a/gl_backend.h b/gl_backend.h index bde446bb..9d130921 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -38,5 +38,5 @@ void R_Mesh_Draw(const rmeshinfo_t *m); void R_Mesh_AddTransparent(void); // ease-of-use frontend to R_Mesh_Draw, set up meshinfo, except for index and numtriangles and numverts, then call this void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts); -// ease-of-use frontend to R_Mesh_Draw for particles, no speed gain -void R_Mesh_DrawParticle(vec3_t org, vec3_t right, vec3_t up, vec_t scale, int texnum, float cr, float cg, float cb, float ca, float s1, float t1, float s2, float t2, float fs1, float ft1, float fs2, float ft2); \ No newline at end of file +// faster hardwired version of R_Mesh_Draw specifically for decals (has close ties to decal code) +void R_Mesh_DrawDecal(const rmeshinfo_t *m); diff --git a/gl_draw.c b/gl_draw.c index d9eebeb4..45180401 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -22,100 +22,246 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //#define GL_COLOR_INDEX8_EXT 0x80E5 -cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"}; +cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"}; -rtexture_t *char_texture; - -typedef struct -{ - rtexture_t *tex; -} glpic_t; - -rtexture_t *conbacktex; +static rtexture_t *char_texture; //============================================================================= /* Support Routines */ -typedef struct cachepic_s -{ - char name[MAX_QPATH]; - // FIXME: qpic is evil - qpic_t pic; - byte padding[32]; // for appended glpic -} -cachepic_t; +#define MAX_CACHED_PICS 256 +#define CACHEPICHASHSIZE 256 +static cachepic_t *cachepichash[CACHEPICHASHSIZE]; +static cachepic_t cachepics[MAX_CACHED_PICS]; +static int numcachepics; -#define MAX_CACHED_PICS 256 -cachepic_t menu_cachepics[MAX_CACHED_PICS]; -int menu_numcachepics; +static rtexturepool_t *drawtexturepool; -byte menuplyr_pixels[4096]; +static byte pointerimage[256] = +{ + "333333332......." + "26777761........" + "2655541........." + "265541.........." + "2654561........." + "26414561........" + "251.14561......." + "21...14561......" + "1.....141......." + ".......1........" + "................" + "................" + "................" + "................" + "................" + "................" +}; + +static rtexture_t *draw_generatemousepointer(void) +{ + int i; + byte buffer[256][4]; + for (i = 0;i < 256;i++) + { + if (pointerimage[i] == '.') + { + buffer[i][0] = 0; + buffer[i][1] = 0; + buffer[i][2] = 0; + buffer[i][3] = 0; + } + else + { + buffer[i][0] = (pointerimage[i] - '0') * 16; + buffer[i][1] = (pointerimage[i] - '0') * 16; + buffer[i][2] = (pointerimage[i] - '0') * 16; + buffer[i][3] = 255; + } + } + return R_LoadTexture(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE); +} -int pic_texels; -int pic_count; +// must match NUMCROSSHAIRS in r_crosshairs.c +#define NUMCROSSHAIRS 5 -rtexturepool_t *drawtexturepool; +static byte *crosshairtexdata[NUMCROSSHAIRS] = +{ + "................" + "................" + "................" + "...33......33..." + "...355....553..." + "....577..775...." + ".....77..77....." + "................" + "................" + ".....77..77....." + "....577..775...." + "...355....553..." + "...33......33..." + "................" + "................" + "................" + , + "................" + "................" + "................" + "...3........3..." + "....5......5...." + ".....7....7....." + "......7..7......" + "................" + "................" + "......7..7......" + ".....7....7....." + "....5......5...." + "...3........3..." + "................" + "................" + "................" + , + "................" + ".......77......." + ".......77......." + "................" + "................" + ".......44......." + ".......44......." + ".77..44..44..77." + ".77..44..44..77." + ".......44......." + ".......44......." + "................" + ".......77......." + ".......77......." + "................" + "................" + , + "................" + "................" + "................" + "................" + "................" + "................" + "................" + "................" + "........7777777." + "........752....." + "........72......" + "........7......." + "........7......." + "........7......." + "................" + "................" + , + "................" + "................" + "................" + "................" + "................" + "........7......." + "................" + "........4......." + ".....7.4.4.7...." + "........4......." + "................" + "........7......." + "................" + "................" + "................" + "................" +}; + +static rtexture_t *draw_generatecrosshair(int num) +{ + int i; + char *in; + byte data[16*16][4]; + in = crosshairtexdata[num]; + for (i = 0;i < 16*16;i++) + { + if (in[i] == '.') + { + data[i][0] = 255; + data[i][1] = 255; + data[i][2] = 255; + data[i][3] = 0; + } + else + { + data[i][0] = 255; + data[i][1] = 255; + data[i][2] = 255; + data[i][3] = (byte) ((int) (in[i] - '0') * 255 / 7); + } + } + return R_LoadTexture(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE); +} /* ================ Draw_CachePic ================ */ -// FIXME: qpic is evil -qpic_t *Draw_CachePic (char *path) +// FIXME: move this to client somehow +cachepic_t *Draw_CachePic (char *path) { - cachepic_t *pic; - int i; - qpic_t *dat; - glpic_t *gl; - rtexture_t *tex; + int i, crc, hashkey; + cachepic_t *pic; + qpic_t *p; - for (pic = menu_cachepics, i = 0;i < menu_numcachepics;pic++, i++) + crc = CRC_Block(path, strlen(path)); + hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE; + for (pic = cachepichash[hashkey];pic;pic = pic->chain) if (!strcmp (path, pic->name)) - return &pic->pic; - - if (menu_numcachepics == MAX_CACHED_PICS) - Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); - menu_numcachepics++; + return pic; + //for (pic = cachepics, i = 0;i < numcachepics;pic++, i++) + // if (!strcmp (path, pic->name)) + // return pic; + + if (numcachepics == MAX_CACHED_PICS) + Sys_Error ("numcachepics == MAX_CACHED_PICS"); + pic = cachepics + (numcachepics++); strcpy (pic->name, path); - - // FIXME: move this to menu code - // HACK HACK HACK --- we need to keep the bytes for - // the translatable player picture just for the menu - // configuration dialog - if (!strcmp (path, "gfx/menuplyr.lmp")) - { - dat = (qpic_t *)COM_LoadFile (path, false); - if (!dat) - Sys_Error("unable to load gfx/menuplyr.lmp"); - SwapPic (dat); - - memcpy (menuplyr_pixels, dat->data, dat->width*dat->height); - } + // link into list + pic->chain = cachepichash[hashkey]; + cachepichash[hashkey] = pic; // load the pic from disk - if ((tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true))) - { - // load the pic from an image file - pic->pic.width = image_width; - pic->pic.height = image_height; - gl = (glpic_t *)pic->pic.data; - gl->tex = tex; - return &pic->pic; - } - else + pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true); + if (pic->tex == NULL && (p = W_GetLumpName (path))) { - qpic_t *p; - // load the pic from gfx.wad - p = W_GetLumpName (path); - if (!p) - Sys_Error ("Draw_CachePic: failed to load %s", path); - pic->pic.width = p->width; - pic->pic.height = p->height; - gl = (glpic_t *)pic->pic.data; - gl->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); - return &pic->pic; + if (!strcmp(path, "conchars")) + { + byte *pix; + // conchars is a raw image and with the wrong transparent color + pix = (byte *)p; + for (i = 0;i < 128 * 128;i++) + if (pix[i] == 0) + pix[i] = 255; + pic->tex = R_LoadTexture (drawtexturepool, path, 128, 128, pix, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); + } + else + pic->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); } + if (pic->tex == NULL && !strcmp(path, "ui/mousepointer.tga")) + pic->tex = draw_generatemousepointer(); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1.tga")) + pic->tex = draw_generatecrosshair(0); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2.tga")) + pic->tex = draw_generatecrosshair(1); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3.tga")) + pic->tex = draw_generatecrosshair(2); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4.tga")) + pic->tex = draw_generatecrosshair(3); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5.tga")) + pic->tex = draw_generatecrosshair(4); + if (pic->tex == NULL) + Sys_Error ("Draw_CachePic: failed to load %s", path); + + pic->width = R_TextureWidth(pic->tex); + pic->height = R_TextureHeight(pic->tex); + return pic; } /* @@ -125,472 +271,311 @@ Draw_Init */ static void gl_draw_start(void) { - int i; - byte *draw_chars; - - menu_numcachepics = 0; - drawtexturepool = R_AllocTexturePool(); - char_texture = loadtextureimage (drawtexturepool, "conchars", 0, 0, false, false, true); - if (!char_texture) - { - draw_chars = W_GetLumpName ("conchars"); - // convert font to proper transparent color - for (i = 0;i < 128 * 128;i++) - if (draw_chars[i] == 0) - draw_chars[i] = 255; - - // now turn into texture - char_texture = R_LoadTexture (drawtexturepool, "charset", 128, 128, draw_chars, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); - } - conbacktex = loadtextureimage(drawtexturepool, "gfx/conback", 0, 0, false, false, true); + numcachepics = 0; + memset(cachepichash, 0, sizeof(cachepichash)); + + char_texture = Draw_CachePic("conchars")->tex; } static void gl_draw_shutdown(void) { R_FreeTexturePool(&drawtexturepool); - menu_numcachepics = 0; + numcachepics = 0; + memset(cachepichash, 0, sizeof(cachepichash)); } -void SHOWLMP_clear(void); static void gl_draw_newmap(void) { - SHOWLMP_clear(); } -extern char engineversion[40]; -int engineversionx, engineversiony; - void GL_Draw_Init (void) { - int i; Cvar_RegisterVariable (&scr_conalpha); - for (i = 0;i < 40 && engineversion[i];i++) - engineversion[i] |= 0x80; // shift to orange - engineversionx = vid.conwidth - strlen(engineversion) * 8 - 8; - engineversiony = vid.conheight - 8; - - menu_numcachepics = 0; + numcachepics = 0; + memset(cachepichash, 0, sizeof(cachepichash)); R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap); } -/* -================ -Draw_Character - -Draws one 8*8 graphics character with 0 being transparent. -It can be clipped to the top of the screen to allow the console to be -smoothly scrolled off. -================ -*/ -void Draw_Character (int x, int y, int num) +void GL_BrightenScreen(void) { - int row, col; - float frow, fcol, size; + float f; - if (num == 32) - return; // space + if (r_brightness.value < 0.1f) + Cvar_SetValue("r_brightness", 0.1f); + if (r_brightness.value > 5.0f) + Cvar_SetValue("r_brightness", 5.0f); - num &= 255; - - if (y <= -8) - return; // totally off screen + if (r_contrast.value < 0.2f) + Cvar_SetValue("r_contrast", 0.2f); + if (r_contrast.value > 1.0f) + Cvar_SetValue("r_contrast", 1.0f); - row = num>>4; - col = num&15; - - frow = row*0.0625; - fcol = col*0.0625; - size = 0.0625; + if (!(lighthalf && !hardwaregammasupported) && r_brightness.value < 1.01f && r_contrast.value > 0.99f) + return; if (!r_render.integer) return; - glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture)); - CHECKGLERROR - // LordHavoc: NEAREST mode on text if not scaling up - if (vid.realwidth <= (int) vid.conwidth) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - CHECKGLERROR - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - CHECKGLERROR - } - if (lighthalf) - glColor3f(0.5f,0.5f,0.5f); - else - glColor3f(1.0f,1.0f,1.0f); + glDisable(GL_TEXTURE_2D); CHECKGLERROR - glBegin (GL_QUADS); - glTexCoord2f (fcol, frow); - glVertex2f (x, y); - glTexCoord2f (fcol + size, frow); - glVertex2f (x+8, y); - glTexCoord2f (fcol + size, frow + size); - glVertex2f (x+8, y+8); - glTexCoord2f (fcol, frow + size); - glVertex2f (x, y+8); - glEnd (); + glEnable(GL_BLEND); CHECKGLERROR - - // LordHavoc: revert to LINEAR mode -// if (vid.realwidth <= (int) vid.conwidth) -// { -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// } -} - -/* -================ -Draw_String -================ -*/ -// LordHavoc: sped this up a lot, and added maxlen -void Draw_String (int x, int y, char *str, int maxlen) -{ - int num; - float frow, fcol; - if (!r_render.integer) - return; - if (y <= -8 || y >= (int) vid.conheight || x >= (int) vid.conwidth || *str == 0) // completely offscreen or no text to print - return; - if (maxlen < 1) - maxlen = strlen(str); - else if (maxlen > (int) strlen(str)) - maxlen = strlen(str); - glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture)); - - // LordHavoc: NEAREST mode on text if not scaling up - if (vid.realwidth <= (int) vid.conwidth) + 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) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glBlendFunc (GL_DST_COLOR, GL_ONE); CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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 } - else + if (r_contrast.value <= 0.99f) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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 } - - if (lighthalf) - glColor3f(0.5f,0.5f,0.5f); - else - glColor3f(1.0f,1.0f,1.0f); - CHECKGLERROR - glBegin (GL_QUADS); - while (maxlen-- && x < (int) vid.conwidth) // stop rendering when out of characters or room - { - if ((num = *str++) != 32) // skip spaces - { - frow = (float) ((int) num >> 4)*0.0625; - fcol = (float) ((int) num & 15)*0.0625; - glTexCoord2f (fcol , frow );glVertex2f (x, y); - glTexCoord2f (fcol + 0.0625, frow );glVertex2f (x+8, y); - glTexCoord2f (fcol + 0.0625, frow + 0.0625);glVertex2f (x+8, y+8); - glTexCoord2f (fcol , frow + 0.0625);glVertex2f (x, y+8); - } - x += 8; - } - glEnd (); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CHECKGLERROR - // LordHavoc: revert to LINEAR mode -// if (vid.realwidth < (int) vid.conwidth) -// { -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// } -} - -void Draw_AdditiveString (int x, int y, char *str, int maxlen) -{ - if (!r_render.integer) - return; - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnable (GL_CULL_FACE); CHECKGLERROR - Draw_String(x, y, str, maxlen); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_DEPTH_TEST); CHECKGLERROR -} - -void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height) -{ - if (!r_render.integer) - return; - if (lighthalf) - glColor4f(red * 0.5f, green * 0.5f, blue * 0.5f, alpha); - else - glColor4f(red, green, blue, alpha); + glDisable(GL_BLEND); CHECKGLERROR - glBindTexture(GL_TEXTURE_2D, R_GetTexture(tex)); - CHECKGLERROR - glBegin (GL_QUADS); - glTexCoord2f (0, 0);glVertex2f (x, y); - glTexCoord2f (1, 0);glVertex2f (x+width, y); - glTexCoord2f (1, 1);glVertex2f (x+width, y+height); - glTexCoord2f (0, 1);glVertex2f (x, y+height); - glEnd (); + glEnable(GL_TEXTURE_2D); CHECKGLERROR } -/* -============= -Draw_AlphaPic -============= -*/ -void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha) -{ - if (pic) - Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,alpha, x,y,pic->width, pic->height); -} - - -/* -============= -Draw_Pic -============= -*/ -void Draw_Pic (int x, int y, qpic_t *pic) -{ - if (pic) - Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height); -} - - -void Draw_AdditivePic (int x, int y, qpic_t *pic) -{ - if (pic) - { - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - CHECKGLERROR - Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - CHECKGLERROR - } -} - - -/* -============= -Draw_PicTranslate - -Only used for the player color selection menu -============= -*/ -void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation) +void R_DrawQueue(void) { - int i, c; - byte *trans, *src, *dest; - rtexture_t *rt; - - if (pic == NULL) - return; + int pos, num, chartexnum; + float x, y, w, h, s, t, u, v; + cachepic_t *pic; + drawqueue_t *dq; + char *str, *currentpic; + int batch, additive; + unsigned int color; - c = pic->width * pic->height; - src = menuplyr_pixels; - dest = trans = Mem_Alloc(tempmempool, c); - for (i = 0;i < c;i++) - *dest++ = translation[*src++]; - - rt = R_LoadTexture (drawtexturepool, "translatedplayerpic", pic->width, pic->height, trans, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); - Mem_Free(trans); - - if (!r_render.integer) - return; - Draw_GenericPic (rt, 1,1,1,1, x, y, pic->width, pic->height); -} - - -/* -================ -Draw_ConsoleBackground - -================ -*/ -void Draw_ConsoleBackground (int lines) -{ - Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value * lines / vid.conheight, 0, lines - vid.conheight, vid.conwidth, vid.conheight); - // LordHavoc: draw version - Draw_String(engineversionx, lines - vid.conheight + engineversiony, engineversion, 9999); -} - -/* -============= -Draw_Fill - -Fills a box of pixels with a single color -============= -*/ -void Draw_Fill (int x, int y, int w, int h, int c) -{ if (!r_render.integer) return; - glDisable (GL_TEXTURE_2D); - CHECKGLERROR - if (lighthalf) - { - byte *tempcolor = (byte *)&d_8to24table[c]; - glColor4ub ((byte) (tempcolor[0] >> 1), (byte) (tempcolor[1] >> 1), (byte) (tempcolor[2] >> 1), tempcolor[3]); - } - else - glColor4ubv ((byte *)&d_8to24table[c]); - CHECKGLERROR - - glBegin (GL_QUADS); - - glVertex2f (x,y); - glVertex2f (x+w, y); - glVertex2f (x+w, y+h); - glVertex2f (x, y+h); - - glEnd (); - CHECKGLERROR - glColor3f(1,1,1); - CHECKGLERROR - glEnable (GL_TEXTURE_2D); - CHECKGLERROR -} -//============================================================================= -//============================================================================= - -/* -================ -GL_Set2D - -Setup as if the screen was 320*200 -================ -*/ -void GL_Set2D (void) -{ - if (!r_render.integer) - return; - glViewport (vid.realx, vid.realy, vid.realwidth, vid.realheight); - CHECKGLERROR + glViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight); glMatrixMode(GL_PROJECTION); - CHECKGLERROR - glLoadIdentity (); - CHECKGLERROR - glOrtho (0, vid.conwidth, vid.conheight, 0, -99999, 99999); - CHECKGLERROR + glLoadIdentity(); + glOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999); glMatrixMode(GL_MODELVIEW); - CHECKGLERROR - glLoadIdentity (); - CHECKGLERROR + glLoadIdentity(); - glDisable (GL_DEPTH_TEST); - CHECKGLERROR - glDisable (GL_CULL_FACE); - CHECKGLERROR - glEnable (GL_BLEND); - CHECKGLERROR + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); - CHECKGLERROR - - // LordHavoc: added this - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - CHECKGLERROR glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - CHECKGLERROR - - glColor3f(1,1,1); - CHECKGLERROR -} - -// LordHavoc: SHOWLMP stuff -#define SHOWLMP_MAXLABELS 256 -typedef struct showlmp_s -{ - qboolean isactive; - float x; - float y; - char label[32]; - char pic[128]; -} showlmp_t; -showlmp_t showlmp[SHOWLMP_MAXLABELS]; + chartexnum = R_GetTexture(char_texture); -void SHOWLMP_decodehide(void) -{ - int i; - byte *lmplabel; - lmplabel = MSG_ReadString(); - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0) - { - showlmp[i].isactive = false; - return; - } -} + additive = false; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + currentpic = ""; + pic = NULL; + glBindTexture(GL_TEXTURE_2D, 0); + color = 0; + glColor4ub(0,0,0,0); -void SHOWLMP_decodeshow(void) -{ - int i, k; - byte lmplabel[256], picname[256]; - float x, y; - strcpy(lmplabel,MSG_ReadString()); - strcpy(picname, MSG_ReadString()); - if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk + // LordHavoc: NEAREST mode on text if not scaling up + /* + if (vid.realwidth <= (int) vid.conwidth) { - x = MSG_ReadByte(); - y = MSG_ReadByte(); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + CHECKGLERROR + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + CHECKGLERROR } else { - x = MSG_ReadShort(); - y = MSG_ReadShort(); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + CHECKGLERROR + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + CHECKGLERROR } - k = -1; - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - if (showlmp[i].isactive) + */ + + batch = false; + for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size) + { + dq = (drawqueue_t *)(r_refdef.drawqueue + pos); + if (dq->flags & DRAWFLAG_ADDITIVE) { - if (strcmp(showlmp[i].label, lmplabel) == 0) + if (!additive) { - k = i; - break; // drop out to replace it + if (batch) + { + batch = false; + glEnd(); + } + additive = true; + glBlendFunc(GL_SRC_ALPHA, GL_ONE); } } - else if (k < 0) // find first empty one to replace - k = i; - if (k < 0) - return; // none found to replace - // change existing one - showlmp[k].isactive = true; - strcpy(showlmp[k].label, lmplabel); - strcpy(showlmp[k].pic, picname); - showlmp[k].x = x; - showlmp[k].y = y; -} + else + { + if (additive) + { + if (batch) + { + batch = false; + glEnd(); + } + additive = false; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } + if (color != dq->color) + { + color = dq->color; + if (lighthalf) + glColor4ub((color >> 25) & 0x7F, (color >> 17) & 0x7F, (color >> 9) & 0x7F, color & 0xFF); + else + glColor4ub((color >> 24) & 0xFF, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); + } + x = dq->x; + y = dq->y; + w = dq->scalex; + h = dq->scaley; + switch(dq->command) + { + case DRAWQUEUE_PIC: + str = (char *)(dq + 1); + if (*str) + { + if (strcmp(str, currentpic)) + { + if (batch) + { + batch = false; + glEnd(); + } + currentpic = str; + pic = Draw_CachePic(str); + glBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex)); + } + if (w == 0) + w = pic->width; + if (h == 0) + h = pic->height; + if (!batch) + { + batch = true; + glBegin(GL_QUADS); + } + //DrawQuad(dq->x, dq->y, w, h, 0, 0, 1, 1); + glTexCoord2f (0, 0);glVertex2f (x , y ); + glTexCoord2f (1, 0);glVertex2f (x+w, y ); + glTexCoord2f (1, 1);glVertex2f (x+w, y+h); + glTexCoord2f (0, 1);glVertex2f (x , y+h); + } + else + { + if (currentpic[0]) + { + if (batch) + { + batch = false; + glEnd(); + } + currentpic = ""; + glBindTexture(GL_TEXTURE_2D, 0); + } + if (!batch) + { + batch = true; + glBegin(GL_QUADS); + } + //DrawQuad(dq->x, dq->y, dq->scalex, dq->scaley, 0, 0, 1, 1); + glTexCoord2f (0, 0);glVertex2f (x , y ); + glTexCoord2f (1, 0);glVertex2f (x+w, y ); + glTexCoord2f (1, 1);glVertex2f (x+w, y+h); + glTexCoord2f (0, 1);glVertex2f (x , y+h); + } + break; + case DRAWQUEUE_STRING: + str = (char *)(dq + 1); + if (strcmp("conchars", currentpic)) + { + if (batch) + { + batch = false; + glEnd(); + } + currentpic = "conchars"; + glBindTexture(GL_TEXTURE_2D, chartexnum); + } + if (!batch) + { + batch = true; + glBegin(GL_QUADS); + } + while ((num = *str++) && x < vid.conwidth) + { + if (num != ' ') + { + s = (num & 15)*0.0625f + (0.5f / 256.0f); + t = (num >> 4)*0.0625f + (0.5f / 256.0f); + u = 0.0625f - (1.0f / 256.0f); + v = 0.0625f - (1.0f / 256.0f); + //DrawQuad(x, y, w, h, (num & 15)*0.0625f + (0.5f / 256.0f), (num >> 4)*0.0625f + (0.5f / 256.0f), 0.0625f - (1.0f / 256.0f), 0.0625f - (1.0f / 256.0f)); + glTexCoord2f (s , t );glVertex2f (x , y ); + glTexCoord2f (s+u, t );glVertex2f (x+w, y ); + glTexCoord2f (s+u, t+v);glVertex2f (x+w, y+h); + glTexCoord2f (s , t+v);glVertex2f (x , y+h); + } + x += w; + } + break; + } + } + if (batch) + glEnd(); + CHECKGLERROR + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + CHECKGLERROR -void SHOWLMP_drawall(void) -{ - int i; - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - if (showlmp[i].isactive) - Draw_Pic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic)); -} + GL_BrightenScreen(); -void SHOWLMP_clear(void) -{ - int i; - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - showlmp[i].isactive = false; + glColor3f(1,1,1); + CHECKGLERROR } diff --git a/gl_models.c b/gl_models.c index b3c4879e..3fc648b0 100644 --- a/gl_models.c +++ b/gl_models.c @@ -277,6 +277,7 @@ void GL_DrawModelMesh(rtexture_t *skin, float *colors, float cred, float cgreen, aliasmeshinfo.ca = currentrenderentity->alpha; } + c_alias_polys += aliasmeshinfo.numtriangles; R_Mesh_Draw(&aliasmeshinfo); // leave it in a state for additional passes @@ -463,6 +464,7 @@ void R_DrawQ1AliasModel (void) aliasmeshinfo.cb = fogcolor[2]; aliasmeshinfo.ca = currentrenderentity->alpha * fog; + c_alias_polys += aliasmeshinfo.numtriangles; R_Mesh_Draw(&aliasmeshinfo); } } @@ -880,6 +882,7 @@ void GL_DrawZymoticModelMesh(zymtype1header_t *m) } aliasmeshinfo.numtriangles = *renderlist++; aliasmeshinfo.index = renderlist; + c_alias_polys += aliasmeshinfo.numtriangles; R_Mesh_Draw(&aliasmeshinfo); renderlist += aliasmeshinfo.numtriangles * 3; } @@ -907,6 +910,7 @@ void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m) { aliasmeshinfo.numtriangles = *renderlist++; aliasmeshinfo.index = renderlist; + c_alias_polys += aliasmeshinfo.numtriangles; R_Mesh_Draw(&aliasmeshinfo); renderlist += aliasmeshinfo.numtriangles * 3; } @@ -940,7 +944,6 @@ void R_DrawAliasModel (void) c_models++; - c_alias_polys += currentrenderentity->model->numtris; if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM) R_DrawZymoticModel (); else if (currentrenderentity->model->aliastype == ALIASTYPE_MD2) diff --git a/gl_rmain.c b/gl_rmain.c index 49005435..cb620784 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -61,7 +61,6 @@ unsigned short d_lightstylevalue[256]; // 8.8 fraction of base light value cvar_t r_drawentities = {0, "r_drawentities","1"}; cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"}; cvar_t r_speeds = {0, "r_speeds","0"}; -cvar_t r_speeds2 = {0, "r_speeds2","0"}; cvar_t r_fullbright = {0, "r_fullbright","0"}; //cvar_t r_lightmap = {0, "r_lightmap","0"}; cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"}; @@ -256,7 +255,6 @@ void GL_Main_Init(void) Cvar_RegisterVariable (&r_drawentities); Cvar_RegisterVariable (&r_drawviewmodel); Cvar_RegisterVariable (&r_speeds); - Cvar_RegisterVariable (&r_speeds2); Cvar_RegisterVariable (&gl_lightmode); // Cvar_RegisterVariable (&r_dynamicwater); // Cvar_RegisterVariable (&r_dynamicbothsides); @@ -541,23 +539,8 @@ static void R_SetupFrame (void) r_oldviewleaf = r_viewleaf; r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); - V_SetContentsColor (r_viewleaf->contents); - V_CalcBlend (); - // r_cache_thrash = false; - 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_AnimateLight (); } @@ -640,7 +623,7 @@ static void R_BlendView(void) if (!r_render.integer) return; - if (v_blend[3] < 0.01f) + if (r_refdef.viewblend[3] < 0.01f) return; glMatrixMode(GL_PROJECTION); @@ -655,9 +638,9 @@ static void R_BlendView(void) glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_TRIANGLES); if (lighthalf) - glColor4f (v_blend[0] * 0.5f, v_blend[1] * 0.5f, v_blend[2] * 0.5f, v_blend[3]); + 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 (v_blend); + glColor4fv (r_refdef.viewblend); glVertex2f (-5, -5); glVertex2f (10, -5); glVertex2f (-5, 10); @@ -731,7 +714,7 @@ void R_RenderView (void) } // don't let sound skip if going slow - if (!intimerefresh && !r_speeds2.integer) + if (!intimerefresh && !r_speeds.integer) S_ExtraUpdate (); R_DrawViewModel(); @@ -758,6 +741,6 @@ void R_RenderView (void) R_BlendView(); R_TimeReport("blendview"); - Mem_CheckSentinelsGlobal(); - R_TimeReport("memtest"); + //Mem_CheckSentinelsGlobal(); + //R_TimeReport("memtest"); } diff --git a/gl_screen.c b/gl_screen.c index dc542a1c..6eaf808f 100644 --- a/gl_screen.c +++ b/gl_screen.c @@ -8,7 +8,7 @@ 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. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -82,7 +82,6 @@ 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 showfps = {CVAR_SAVE, "showfps", "0"}; 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 @@ -170,25 +169,16 @@ void SCR_DrawCenterString (void) if (start[l] == '\n' || !start[l]) break; x = (vid.conwidth - l*8)/2; - // LordHavoc: speedup if (l > 0) { if (remaining < l) l = remaining; - Draw_String(x, y, start, l); + DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0); remaining -= l; if (remaining <= 0) return; } - /* - for (j=0 ; jwidth)/2, (vid.conheight - pic->height)/2, pic); + DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/pause.lmp", 0, 0, 1, 1, 1, 1, 0); } @@ -460,13 +455,13 @@ SCR_DrawLoading /* void SCR_DrawLoading (void) { - qpic_t *pic; + cachepic_t *pic; if (!scr_drawloading) return; - + pic = Draw_CachePic ("gfx/loading.lmp"); - Draw_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, pic); + DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0); } */ @@ -483,9 +478,6 @@ SCR_SetUpToDrawConsole void SCR_SetUpToDrawConsole (void) { Con_CheckResize (); - - //if (scr_drawloading) - // return; // never a console with loading plaque // decide on the height of the console con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; @@ -524,7 +516,7 @@ void SCR_DrawConsole (void) { if (scr_con_current) { - Con_DrawConsole (scr_con_current, true); + Con_DrawConsole (scr_con_current); clearconsole = 0; } else @@ -536,12 +528,12 @@ void SCR_DrawConsole (void) /* -============================================================================== +============================================================================== - SCREEN SHOTS + SCREEN SHOTS -============================================================================== -*/ +============================================================================== +*/ /* ================== @@ -753,10 +745,7 @@ void SCR_DrawNotifyString (void) if (start[l] == '\n' || !start[l]) break; x = (vid.conwidth - l*8)/2; - // LordHavoc: speedup -// for (j=0 ; j 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 -} -char r_speeds2_string[1024]; +char r_speeds_string[1024]; int speedstringcount, r_timereport_active; double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0; @@ -874,33 +787,85 @@ void R_TimeReport(char *desc) tempbuf[length] = 0; if (speedstringcount + length > (vid.conwidth / 8)) { - strcat(r_speeds2_string, "\n"); + 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_speeds2_string, tempbuf + 1); + strcat(r_speeds_string, tempbuf + 1); speedstringcount = length - 1; } else { - strcat(r_speeds2_string, tempbuf); + strcat(r_speeds_string, tempbuf); speedstringcount += length; } } void R_TimeReport_Start(void) { - r_timereport_active = r_speeds2.integer && cl.worldmodel && cls.state == ca_connected; + 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%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], 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_brush_polys, c_light_polys, c_alias_polys, c_meshtris, + c_faces, c_nodes, c_leafs, + c_models, c_bmodels, c_sprites, c_particles, c_dlights); + + 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; + } + } } /* @@ -913,49 +878,24 @@ text to the screen. LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :) ================== */ -void GL_Finish(void); -void R_Clip_DisplayBuffer(void); void SCR_UpdateScreen (void) { - double time1 = 0, time2; - - if (r_speeds.integer) - time1 = Sys_DoubleTime (); - VID_UpdateGamma(false); if (scr_disabled_for_loading) - { - /* - if (realtime - scr_disabled_time > 60) - { - scr_disabled_for_loading = false; - Con_Printf ("load failed.\n"); - } - else - */ - return; - } + return; if (!scr_initialized || !con_initialized) return; // not initialized yet - r_speeds2_string[0] = 0; - if (r_speeds2.integer) - { - speedstringcount = 0; - sprintf(r_speeds2_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_origin[0] < 0 ? '-' : ' ', fabs(r_origin[0]), r_origin[1] < 0 ? '-' : ' ', fabs(r_origin[1]), r_origin[2] < 0 ? '-' : ' ', fabs(r_origin[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]), - c_brush_polys, c_light_polys, c_alias_polys, c_meshtris, - c_faces, c_nodes, c_leafs, - c_models, c_bmodels, c_sprites, c_particles, c_dlights); - R_TimeReport_Start(); - } + //Mem_CheckSentinelsGlobal(); + //R_TimeReport("memtest"); - Mem_CheckSentinelsGlobal(); - R_TimeReport("memtest"); + R_TimeReport("other"); + + glFinish (); + CHECKGLERROR - GL_Finish(); GL_EndRendering (); R_TimeReport("finish"); @@ -976,23 +916,10 @@ void SCR_UpdateScreen (void) lightscale = 1.0f / (float) (1 << lightscalebit); - // - // determine size of refresh window - // - if (oldfov != scr_fov.value) - { - oldfov = scr_fov.value; -// vid.recalc_refdef = true; - } + R_TimeReport("setup"); - if (oldscreensize != scr_viewsize.value) - { - oldscreensize = scr_viewsize.value; -// vid.recalc_refdef = true; - } - -// if (vid.recalc_refdef) - SCR_CalcRefdef(); + // determine size of refresh window + SCR_CalcRefdef(); R_TimeReport("calcrefdef"); @@ -1002,30 +929,19 @@ void SCR_UpdateScreen (void) 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 } - R_TimeReport("clear"); - - if (gl_dither.integer) - glEnable(GL_DITHER); - else - glDisable(GL_DITHER); - CHECKGLERROR - -// -// do 3D refresh drawing, and then update the screen -// SCR_SetUpToDrawConsole(); - R_TimeReport("setupconsole"); - - V_RenderView(); - - V_UpdateBlends(); - - GL_Set2D(); + R_TimeReport("clear"); - R_Clip_DisplayBuffer(); + if (scr_conlines < vid.conheight) + R_RenderView(); SCR_DrawRam(); SCR_DrawNet(); @@ -1035,96 +951,17 @@ void SCR_UpdateScreen (void) Sbar_Draw(); SHOWLMP_drawall(); - if (crosshair.integer) - DrawCrosshair(crosshair.integer - 1); - - if (cl.intermission == 1) - Sbar_IntermissionOverlay(); - else if (cl.intermission == 2) - Sbar_FinaleOverlay(); - SCR_DrawConsole(); M_Draw(); ui_draw(); -// if (scr_drawloading) -// SCR_DrawLoading(); - - if (showfps.integer) - { - static double currtime, frametimes[32]; - double newtime, total; - char temp[32]; - int calc, count, i; - static int framecycle = 0; - newtime = Sys_DoubleTime(); - frametimes[framecycle] = newtime - currtime; - framecycle++; - framecycle &= 31; - total = 0; - count = 0; - for (i = 0;i < 32;i++) - { - if (frametimes[i]) - { - total += frametimes[i]; - count++; - // limit how far back we look - if (total >= 0.25) - break; - } - } - if (showfps.integer == 1) - calc = (int) ((count / total) + 0.5); - else // showfps 2, rapid update - calc = (int) ((1.0 / (newtime - currtime)) + 0.5); - sprintf(temp, "%4i fps", calc); - currtime = newtime; - Draw_String(vid.conwidth - (8*8), vid.conheight - sb_lines - 8, temp, 9999); - } - R_TimeReport("2d"); R_TimeReport_End(); - if (r_speeds2_string[0] && cls.state == ca_connected && cl.worldmodel) - { - int i, j, lines, y; - lines = 1; - for (i = 0;r_speeds2_string[i];i++) - if (r_speeds2_string[i] == '\n') - lines++; - y = vid.conheight - sb_lines - lines * 8 - 8; - i = j = 0; - while (r_speeds2_string[i]) - { - j = i; - while (r_speeds2_string[i] && r_speeds2_string[i] != '\n') - i++; - if (i - j > 0) - Draw_String(0, y, r_speeds2_string + j, i - j); - if (r_speeds2_string[i] == '\n') - i++; - y += 8; - } - } - - GL_BrightenScreen(); + // draw 2D stuff + R_DrawQueue(); - if (r_speeds.integer) - { - time2 = Sys_DoubleTime (); - Con_Printf ("%3i ms %4i wpoly %4i epoly %6i meshtris %4i lightpoly %4i BSPnodes %4i BSPleafs %4i BSPfaces %4i models %4i bmodels %4i sprites %4i particles %3i dlights\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, c_meshtris, c_light_polys, c_nodes, c_leafs, c_faces, c_models, c_bmodels, c_sprites, c_particles, c_dlights); - } + R_TimeReport_Start(); } - -// for profiling, this is separated -void GL_Finish(void) -{ - if (!r_render.integer) - return; - glFinish (); - CHECKGLERROR -} - diff --git a/gl_textures.c b/gl_textures.c index ef719e4c..2725277e 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -1,6 +1,7 @@ #include "quakedef.h" cvar_t r_max_size = {0, "r_max_size", "2048"}; +cvar_t r_max_scrapsize = {0, "r_max_scrapsize", "1024"}; cvar_t r_picmip = {0, "r_picmip", "0"}; cvar_t r_lerpimages = {CVAR_SAVE, "r_lerpimages", "1"}; cvar_t r_precachetextures = {CVAR_SAVE, "r_precachetextures", "1"}; @@ -22,7 +23,8 @@ static mempool_t *texturemempool; #define GLTEXF_DESTROYED 0x00040000 // size of images which hold fragment textures, ignores picmip and max_size -#define BLOCK_SIZE 256 +//#define BLOCK_SIZE 256 +static int block_size; // really this number only governs gltexnuminuse #define MAX_GLTEXTURES 65536 @@ -455,6 +457,9 @@ static void r_textures_start(void) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &realmaxsize); CHECKGLERROR + // use the largest scrap texture size we can (not sure if this is really a good idea) + for (block_size = 1;block_size < realmaxsize && block_size < r_max_scrapsize.integer;block_size <<= 1); + texturemempool = Mem_AllocPool("Textures"); gltexnuminuse = Mem_Alloc(texturemempool, MAX_GLTEXTURES); //memset(gltexnuminuse, 0, MAX_GLTEXTURES); @@ -497,6 +502,7 @@ void R_Textures_Init (void) { Cmd_AddCommand ("gl_texturemode", &GL_TextureMode_f); Cmd_AddCommand("r_texturestats", R_TextureStats_f); + Cvar_RegisterVariable (&r_max_scrapsize); Cvar_RegisterVariable (&r_max_size); Cvar_RegisterVariable (&r_picmip); Cvar_RegisterVariable (&r_lerpimages); @@ -1139,8 +1145,8 @@ static void R_FindImageForTexture(gltexture_t *glt) continue; // got a fragments texture, find a place in it if we can - best = BLOCK_SIZE; - for (best = BLOCK_SIZE, i = 0;i < BLOCK_SIZE - w;i += texinfo->align) + best = block_size; + for (best = block_size, i = 0;i < block_size - w;i += texinfo->align) { for (best2 = 0, j = 0;j < w;j++) { @@ -1157,7 +1163,7 @@ static void R_FindImageForTexture(gltexture_t *glt) } } - if (best + h > BLOCK_SIZE) + if (best + h > block_size) continue; for (i = 0;i < w;i++) @@ -1175,10 +1181,10 @@ static void R_FindImageForTexture(gltexture_t *glt) Sys_Error("R_FindImageForTexture: ran out of memory\n"); //memset(image, 0, sizeof(*image)); image->type = GLIMAGETYPE_FRAGMENTS; - image->width = BLOCK_SIZE; - image->height = BLOCK_SIZE; - image->blockallocation = Mem_Alloc(texturemempool, BLOCK_SIZE * sizeof(short)); - memset(image->blockallocation, 0, BLOCK_SIZE * sizeof(short)); + image->width = block_size; + image->height = block_size; + image->blockallocation = Mem_Alloc(texturemempool, block_size * sizeof(short)); + memset(image->blockallocation, 0, block_size * sizeof(short)); x = 0; y = 0; @@ -1332,8 +1338,8 @@ rtexture_t *R_LoadTexture (rtexturepool_t *rtexturepool, char *identifier, int w if (flags & TEXF_FRAGMENT) { - if (width > BLOCK_SIZE || height > BLOCK_SIZE) - Host_Error("R_LoadTexture: fragment too big, must be no more than %dx%d\n", BLOCK_SIZE, BLOCK_SIZE); + if (width > block_size || height > block_size) + Host_Error("R_LoadTexture: fragment too big, must be no more than %dx%d\n", block_size, block_size); if ((width * texinfo->internalbytesperpixel) & 3) Host_Error("R_LoadTexture: incompatible width for fragment"); } @@ -1411,8 +1417,8 @@ rtexture_t *R_ProceduralTexture (rtexturepool_t *rtexturepool, char *identifier, // Host_Error("R_ProceduralTexture: \"%s\" has no generate function\n", identifier); if (flags & TEXF_FRAGMENT) { - if (width > BLOCK_SIZE || height > BLOCK_SIZE) - Host_Error("R_ProceduralTexture: fragment too big, must be no more than %dx%d\n", BLOCK_SIZE, BLOCK_SIZE); + if (width > block_size || height > block_size) + Host_Error("R_ProceduralTexture: fragment too big, must be no more than %dx%d\n", block_size, block_size); if ((width * texinfo->internalbytesperpixel) & 3) Host_Error("R_ProceduralTexture: incompatible width for fragment"); } diff --git a/glquake.h b/glquake.h index 40b44063..f510c1bf 100644 --- a/glquake.h +++ b/glquake.h @@ -146,7 +146,7 @@ extern cvar_t gl_combine; #endif -//#define DEBUGGL +#define DEBUGGL #ifdef DEBUGGL #define CHECKGLERROR if ((errornumber = glGetError())) GL_PrintError(errornumber, __FILE__, __LINE__); diff --git a/host.c b/host.c index b404789e..7dbd6320 100644 --- a/host.c +++ b/host.c @@ -703,7 +703,7 @@ void _Host_Frame (float time) if (host_speeds.integer) time1 = Sys_DoubleTime (); - SCR_UpdateScreen (); + CL_UpdateScreen (); if (host_speeds.integer) time2 = Sys_DoubleTime (); diff --git a/host_cmd.c b/host_cmd.c index a97af9f6..cd5b8521 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -548,11 +548,6 @@ void Host_Loadgame_f (void) sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); COM_DefaultExtension (name, ".sav"); - // LordHavoc: made SCR_UpdateScreen use a great deal less stack space, no longer an issue - //// we can't call SCR_BeginLoadingPlaque, because too much stack space has - //// been used. The menu calls it before stuffing loadgame command -// SCR_BeginLoadingPlaque (); - Con_Printf ("Loading game from %s...\n", name); f = Qopen (name, "rz"); if (!f) diff --git a/keys.c b/keys.c index 6fe4a86f..4cd6d4b3 100644 --- a/keys.c +++ b/keys.c @@ -169,9 +169,9 @@ void Key_Console (int key) key_lines[edit_line][0] = ']'; key_lines[edit_line][1] = 0; // EvilTypeGuy: null terminate key_linepos = 1; + // force an update, because the command may take some time if (cls.state == ca_disconnected) - SCR_UpdateScreen (); // force an update, because the command - // may take some time + CL_UpdateScreen (); return; } diff --git a/makefile b/makefile index 1599a066..a49a543e 100644 --- a/makefile +++ b/makefile @@ -9,7 +9,7 @@ SOUNDLIB=-lasound #SND=snd_oss.o #SOUNDLIB= -OBJECTS= buildnumber.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 r_decals.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_decals.o +OBJECTS= buildnumber.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 r_decals.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_decals.o cl_screen.o #K6/athlon optimizations CPUOPTIMIZATIONS=-march=k6 diff --git a/menu.c b/menu.c index 2d5ba98e..f1fc1331 100644 --- a/menu.c +++ b/menu.c @@ -87,7 +87,6 @@ void M_ServerList_Key (int key); qboolean m_entersound; // play after drawing a frame, so caching // won't disrupt the sound -//qboolean m_recursiveDraw; int m_return_state; qboolean m_return_onerror; @@ -110,6 +109,17 @@ typedef struct demonames_t Demos[35]; +float menu_x, menu_y, menu_width, menu_height; + +void M_DrawBackground(void) +{ + menu_width = 320; + 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); +} + /* ================ M_DrawCharacter @@ -117,34 +127,34 @@ M_DrawCharacter Draws one solid graphics character ================ */ -void M_DrawCharacter (int cx, int line, int num) +void M_DrawCharacter (float cx, float cy, int num) { - Draw_Character ( cx + ((vid.conwidth - 320)>>1), line, num); + char temp[2]; + temp[0] = num; + temp[1] = 0; + DrawQ_String(menu_x + cx, menu_y + cy, temp, 1, 8, 8, 1, 1, 1, 1, 0); } -void M_Print (int cx, int cy, char *str) +void M_Print (float cx, float cy, char *str) { + /* while (*str) { - M_DrawCharacter (cx, cy, (*str)+128); - str++; + M_DrawCharacter (cx, cy, (*str++)+128); cx += 8; } + */ + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0); } -void M_PrintWhite (int cx, int cy, char *str) +void M_PrintWhite (float cx, float cy, char *str) { - while (*str) - { - M_DrawCharacter (cx, cy, *str); - str++; - cx += 8; - } + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0); } -void M_DrawPic (int x, int y, qpic_t *pic) +void M_DrawPic (float cx, float cy, char *picname) { - Draw_Pic (x + ((vid.conwidth - 320)>>1), y, pic); + DrawQ_Pic (menu_x + cx, menu_y + cy, picname, 0, 0, 1, 1, 1, 1, 0); } byte identityTable[256]; @@ -177,65 +187,56 @@ void M_BuildTranslationTable(int top, int bottom) } -void M_DrawPicTranslate (int x, int y, qpic_t *pic) +void M_DrawPicTranslate (float cx, float cy, char *picname) { - Draw_PicTranslate (x + ((vid.conwidth - 320)>>1), y, pic, translationTable); + DrawQ_PicTranslate (menu_x + cx, menu_y + cy, picname, translationTable); } -void M_DrawTextBox (int x, int y, int width, int lines) +void M_DrawTextBox (float x, float y, float width, float height) { - qpic_t *p; - int cx, cy; - int n; + int n; + float cx, cy; // draw left side cx = x; cy = y; - p = Draw_CachePic ("gfx/box_tl.lmp"); - M_DrawPic (cx, cy, p); - p = Draw_CachePic ("gfx/box_ml.lmp"); - for (n = 0; n < lines; n++) + M_DrawPic (cx, cy, "gfx/box_tl.lmp"); + for (n = 0; n < height; n++) { cy += 8; - M_DrawPic (cx, cy, p); + M_DrawPic (cx, cy, "gfx/box_ml.lmp"); } - p = Draw_CachePic ("gfx/box_bl.lmp"); - M_DrawPic (cx, cy+8, p); + M_DrawPic (cx, cy+8, "gfx/box_bl.lmp"); // draw middle cx += 8; while (width > 0) { cy = y; - p = Draw_CachePic ("gfx/box_tm.lmp"); - M_DrawPic (cx, cy, p); - p = Draw_CachePic ("gfx/box_mm.lmp"); - for (n = 0; n < lines; n++) + M_DrawPic (cx, cy, "gfx/box_tm.lmp"); + for (n = 0; n < height; n++) { cy += 8; - if (n == 1) - p = Draw_CachePic ("gfx/box_mm2.lmp"); - M_DrawPic (cx, cy, p); + if (n >= 1) + M_DrawPic (cx, cy, "gfx/box_mm2.lmp"); + else + M_DrawPic (cx, cy, "gfx/box_mm.lmp"); } - p = Draw_CachePic ("gfx/box_bm.lmp"); - M_DrawPic (cx, cy+8, p); + M_DrawPic (cx, cy+8, "gfx/box_bm.lmp"); width -= 2; cx += 16; } // draw right side cy = y; - p = Draw_CachePic ("gfx/box_tr.lmp"); - M_DrawPic (cx, cy, p); - p = Draw_CachePic ("gfx/box_mr.lmp"); - for (n = 0; n < lines; n++) + M_DrawPic (cx, cy, "gfx/box_tr.lmp"); + for (n = 0; n < height; n++) { cy += 8; - M_DrawPic (cx, cy, p); + M_DrawPic (cx, cy, "gfx/box_mr.lmp"); } - p = Draw_CachePic ("gfx/box_br.lmp"); - M_DrawPic (cx, cy+8, p); + M_DrawPic (cx, cy+8, "gfx/box_br.lmp"); } //============================================================================= @@ -307,9 +308,8 @@ void menuitem_text_drawfunc(struct menuitem_s *item) void menuitem_image_drawfunc(struct menuitem_s *item) { - qpic_t *p = Draw_CachePic (item->string); // FIXME: handle color flashs and such when selected - M_DrawPic (item->x, item->y, p); + M_DrawPic (item->x, item->y, item->string); } void menuitem_command_usefunc(struct menuitem_s *item) @@ -446,27 +446,27 @@ void M_Menu_Main_f (void) void M_Main_Draw (void) { int f; - qpic_t *p; + cachepic_t *p; - M_DrawPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + M_DrawPic (16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic ("gfx/ttl_main.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/ttl_main.lmp"); // Nehahra if (gamemode == GAME_NEHAHRA) { if (NehGameType == TYPE_BOTH) - M_DrawPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp")); + M_DrawPic (72, 32, "gfx/mainmenu.lmp"); else if (NehGameType == TYPE_GAME) - M_DrawPic (72, 32, Draw_CachePic ("gfx/gamemenu.lmp")); + M_DrawPic (72, 32, "gfx/gamemenu.lmp"); else - M_DrawPic (72, 32, Draw_CachePic ("gfx/demomenu.lmp")); + M_DrawPic (72, 32, "gfx/demomenu.lmp"); } else - M_DrawPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp")); + M_DrawPic (72, 32, "gfx/mainmenu.lmp"); f = (int)(realtime * 10)%6; - M_DrawPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + M_DrawPic (54, 32 + m_main_cursor * 20, va("gfx/menudot%i.lmp", f+1)); } @@ -630,16 +630,16 @@ void M_Menu_SinglePlayer_f (void) void M_SinglePlayer_Draw (void) { int f; - qpic_t *p; + cachepic_t *p; - M_DrawPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + M_DrawPic (16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic ("gfx/ttl_sgl.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); - M_DrawPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") ); + M_DrawPic ( (320-p->width)/2, 4, "gfx/ttl_sgl.lmp"); + M_DrawPic (72, 32, "gfx/sp_menu.lmp"); f = (int)(realtime * 10)%6; - M_DrawPic (54, 32 + m_singleplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + M_DrawPic (54, 32 + m_singleplayer_cursor * 20, va("gfx/menudot%i.lmp", f+1)); } @@ -756,10 +756,10 @@ void M_Menu_Save_f (void) void M_Load_Draw (void) { int i; - qpic_t *p; + cachepic_t *p; p = Draw_CachePic ("gfx/p_load.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_load.lmp"); for (i=0 ; i< MAX_SAVEGAMES; i++) M_Print (16, 32 + 8*i, m_filenames[i]); @@ -772,10 +772,10 @@ void M_Load_Draw (void) void M_Save_Draw (void) { int i; - qpic_t *p; + cachepic_t *p; p = Draw_CachePic ("gfx/p_save.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_save.lmp"); for (i=0 ; iwidth)/2, 4, p); - M_DrawPic (72, 32, Draw_CachePic ("gfx/mp_menu.lmp") ); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_multi.lmp"); + M_DrawPic (72, 32, "gfx/mp_menu.lmp"); f = (int)(realtime * 10)%6; - M_DrawPic (54, 32 + m_multiplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + M_DrawPic (54, 32 + m_multiplayer_cursor * 20, va("gfx/menudot%i.lmp", f+1)); if (ipxAvailable || tcpipAvailable) return; @@ -965,11 +965,11 @@ void M_Menu_Setup_f (void) void M_Setup_Draw (void) { - qpic_t *p; + cachepic_t *p; - M_DrawPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + M_DrawPic (16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic ("gfx/p_multi.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_multi.lmp"); M_Print (64, 40, "Hostname"); M_DrawTextBox (160, 32, 16, 1); @@ -985,11 +985,9 @@ void M_Setup_Draw (void) M_DrawTextBox (64, 140-8, 14, 1); M_Print (72, 140, "Accept Changes"); - p = Draw_CachePic ("gfx/bigbox.lmp"); - M_DrawPic (160, 64, p); - p = Draw_CachePic ("gfx/menuplyr.lmp"); + M_DrawPic (160, 64, "gfx/bigbox.lmp"); M_BuildTranslationTable(setup_top*16, setup_bottom*16); - M_DrawPicTranslate (172, 72, p); + M_DrawPicTranslate (172, 72, "gfx/menuplyr.lmp"); M_DrawCharacter (56, setup_cursor_table [setup_cursor], 12+((int)(realtime*4)&1)); @@ -1148,32 +1146,29 @@ void M_Menu_Net_f (void) void M_Net_Draw (void) { int f; - qpic_t *p; + cachepic_t *p; - M_DrawPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + M_DrawPic (16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic ("gfx/p_multi.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_multi.lmp"); f = 32; if (ipxAvailable) - p = Draw_CachePic ("gfx/netmen3.lmp"); + M_DrawPic (72, f, "gfx/netmen3.lmp"); else - p = Draw_CachePic ("gfx/dim_ipx.lmp"); - M_DrawPic (72, f, p); + M_DrawPic (72, f, "gfx/dim_ipx.lmp"); f += 19; if (tcpipAvailable) - p = Draw_CachePic ("gfx/netmen4.lmp"); + M_DrawPic (72, f, "gfx/netmen4.lmp"); else - p = Draw_CachePic ("gfx/dim_tcp.lmp"); - M_DrawPic (72, f, p); + M_DrawPic (72, f, "gfx/dim_tcp.lmp"); if (m_net_items == 5) // JDC, could just be removed { f += 19; - p = Draw_CachePic ("gfx/netmen5.lmp"); - M_DrawPic (72, f, p); + M_DrawPic (72, f, "gfx/netmen5.lmp"); } f = (320-26*8)/2; @@ -1183,7 +1178,7 @@ void M_Net_Draw (void) M_Print (f, 150, net_helpMessage[m_net_cursor*4+1]); f = (int)(realtime * 10)%6; - M_DrawPic (54, 32 + m_net_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + M_DrawPic (54, 32 + m_net_cursor * 20, va("gfx/menudot%i.lmp", f+1)); } @@ -1387,11 +1382,11 @@ void M_DrawCheckbox (int x, int y, int on) void M_Options_Draw (void) { float y; - qpic_t *p; + cachepic_t *p; - M_DrawPic(16, 4, Draw_CachePic("gfx/qplaque.lmp") ); + M_DrawPic(16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic("gfx/p_option.lmp"); - M_DrawPic((320-p->width)/2, 4, p); + M_DrawPic((320-p->width)/2, 4, "gfx/p_option.lmp"); y = 32; M_Print(16, y, " Customize controls");y += 8; @@ -1572,10 +1567,10 @@ void M_Keys_Draw (void) int keys[2]; char *name; int x, y; - qpic_t *p; + cachepic_t *p; p = Draw_CachePic ("gfx/ttl_cstm.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/ttl_cstm.lmp"); if (bind_grab) M_Print (12, 32, "Press a key or button for this action"); @@ -1718,7 +1713,7 @@ void M_Menu_Help_f (void) void M_Help_Draw (void) { - M_DrawPic (0, 0, Draw_CachePic ( va("gfx/help%i.lmp", help_page)) ); + M_DrawPic (0, 0, va("gfx/help%i.lmp", help_page)); } @@ -1870,14 +1865,6 @@ void M_Quit_Key (int key) void M_Quit_Draw (void) { - if (wasInMenus) - { - m_state = m_quit_prevstate; -// m_recursiveDraw = true; - M_Draw (); - m_state = m_quit; - } - /* #ifdef _WIN32 M_DrawTextBox (0, 0, 38, 23); @@ -1947,15 +1934,15 @@ void M_Menu_LanConfig_f (void) void M_LanConfig_Draw (void) { - qpic_t *p; + cachepic_t *p; int basex; char *startJoin; char *protocol; - M_DrawPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + M_DrawPic (16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic ("gfx/p_multi.lmp"); basex = (320-p->width)/2; - M_DrawPic (basex, 4, p); + M_DrawPic (basex, 4, "gfx/p_multi.lmp"); if (StartingGame) startJoin = "New Game"; @@ -2318,12 +2305,12 @@ int gameoptions_cursor; void M_GameOptions_Draw (void) { - qpic_t *p; + cachepic_t *p; int x; - M_DrawPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + M_DrawPic (16, 4, "gfx/qplaque.lmp"); p = Draw_CachePic ("gfx/p_multi.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_multi.lmp"); M_DrawTextBox (152, 32, 10, 1); M_Print (160, 40, "begin game"); @@ -2655,11 +2642,11 @@ void M_Menu_Search_f (void) void M_Search_Draw (void) { - qpic_t *p; + cachepic_t *p; int x; p = Draw_CachePic ("gfx/p_multi.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_multi.lmp"); x = (320/2) - ((12*8)/2) + 4; M_DrawTextBox (x-8, 32, 12, 1); M_Print (x, 40, "Searching..."); @@ -2716,7 +2703,7 @@ void M_ServerList_Draw (void) { int n; char string [64]; - qpic_t *p; + cachepic_t *p; if (!slist_sorted) { @@ -2737,7 +2724,7 @@ void M_ServerList_Draw (void) } p = Draw_CachePic ("gfx/p_multi.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/p_multi.lmp"); for (n = 0; n < hostCacheCount; n++) { if (hostcache[n].maxusers) @@ -2848,26 +2835,12 @@ void M_Init (void) } } - void M_Draw (void) { if (m_state == m_none || key_dest != key_menu) return; - /* - if (!m_recursiveDraw) - { - if (scr_con_current) - { - Draw_ConsoleBackground (vid.conheight); - S_ExtraUpdate (); - } - } - else - { - m_recursiveDraw = false; - } - */ + M_DrawBackground(); switch (m_state) { diff --git a/model_brush.c b/model_brush.c index fd872c89..34e1726a 100644 --- a/model_brush.c +++ b/model_brush.c @@ -27,7 +27,7 @@ cvar_t halflifebsp = {0, "halflifebsp", "0"}; cvar_t r_novis = {0, "r_novis", "0"}; cvar_t r_miplightmaps = {CVAR_SAVE, "r_miplightmaps", "0"}; cvar_t r_lightmaprgba = {0, "r_lightmaprgba", "1"}; -cvar_t r_vertexsurfacesthreshold = {CVAR_SAVE, "r_vertexsurfacesthreshold", "48"}; +cvar_t r_vertexsurfacesthreshold = {CVAR_SAVE, "r_vertexsurfacesthreshold", "0"}; /* =============== @@ -1806,7 +1806,7 @@ static winding_t *ClipWinding (winding_t *in, mplane_t *split, int keepon) FreeWinding (in); // debugging - Mem_CheckSentinels(neww); + //Mem_CheckSentinels(neww); return neww; } @@ -1922,8 +1922,8 @@ static void DivideWinding (winding_t *in, mplane_t *split, winding_t **front, wi } // debugging - Mem_CheckSentinels(f); - Mem_CheckSentinels(b); + //Mem_CheckSentinels(f); + //Mem_CheckSentinels(b); } typedef struct portal_s diff --git a/model_shared.c b/model_shared.c index 6ed7273a..fe7cff0b 100644 --- a/model_shared.c +++ b/model_shared.c @@ -104,46 +104,48 @@ static model_t *Mod_LoadModel (model_t *mod, qboolean crash, qboolean checkdisk, { int crc; void *buf; - char tempname[MAX_QPATH]; mod->used = true; if (mod->name[0] == '*') // submodel return mod; - if (checkdisk) + crc = 0; + buf = NULL; + if (!mod->needload) { - // load the file - buf = COM_LoadFile (mod->name, false); - if (!buf) + if (checkdisk) { - if (crash) - Host_Error ("Mod_LoadModel: %s not found", mod->name); // LordHavoc: Sys_Error was *ANNOYING* - return NULL; - } + buf = COM_LoadFile (mod->name, false); + if (!buf) + { + if (crash) + Host_Error ("Mod_LoadModel: %s not found", mod->name); // LordHavoc: Sys_Error was *ANNOYING* + return NULL; + } - crc = CRC_Block(buf, com_filesize); + crc = CRC_Block(buf, com_filesize); + } + else + crc = mod->crc; - if (!mod->needload && mod->crc == crc && mod->isworldmodel == isworldmodel) + if (mod->crc == crc && mod->isworldmodel == isworldmodel) { - Mem_Free(buf); + if (buf) + Mem_Free(buf); return mod; // already loaded } - - Con_DPrintf("loading model %s\n", mod->name); } - else - { - if (!mod->needload && mod->isworldmodel == isworldmodel) - return mod; // already loaded - Con_DPrintf("loading model %s\n", mod->name); + Con_DPrintf("loading model %s\n", mod->name); + if (!buf) + { buf = COM_LoadFile (mod->name, false); if (!buf) { if (crash) - Host_Error ("Mod_LoadModel: %s not found", mod->name); // LordHavoc: Sys_Error was *ANNOYING* + Host_Error ("Mod_LoadModel: %s not found", mod->name); return NULL; } crc = CRC_Block(buf, com_filesize); @@ -155,11 +157,8 @@ static model_t *Mod_LoadModel (model_t *mod, qboolean crash, qboolean checkdisk, // allocate a new model loadmodel = mod; - // LordHavoc: clear the model struct - strcpy(tempname, mod->name); - Mod_FreeModel(mod); - - strcpy(mod->name, tempname); + // LordHavoc: unload the existing model in this slot (if there is one) + Mod_UnloadModel(mod); mod->isworldmodel = isworldmodel; mod->needload = false; mod->used = true; @@ -190,15 +189,15 @@ void Mod_CheckLoaded (model_t *mod) { if (mod) { - if (!mod->needload) + if (mod->needload) + Mod_LoadModel(mod, true, true, mod->isworldmodel); + else { if (mod->type == mod_invalid) Host_Error("Mod_CheckLoaded: invalid model\n"); mod->used = true; return; } - - Mod_LoadModel(mod, true, true, mod->isworldmodel); } } @@ -307,12 +306,7 @@ Loads in a model for the given name */ model_t *Mod_ForName (char *name, qboolean crash, qboolean checkdisk, qboolean isworldmodel) { - model_t *mod; - - mod = Mod_FindName (name); - mod->used = true; - - return Mod_LoadModel (mod, crash, checkdisk, isworldmodel); + return Mod_LoadModel (Mod_FindName (name), crash, checkdisk, isworldmodel); } byte *mod_base; diff --git a/net_dgrm.c b/net_dgrm.c index 35916fad..6b89add7 100644 --- a/net_dgrm.c +++ b/net_dgrm.c @@ -1237,7 +1237,7 @@ static qsocket_t *_Datagram_Connect (char *host) goto ErrorReturn; // send the connection request - Con_Printf("trying...\n"); SCR_UpdateScreen (); + Con_Printf("trying...\n"); CL_UpdateScreen (); start_time = net_time; for (reps = 0; reps < 3; reps++) @@ -1264,7 +1264,7 @@ static qsocket_t *_Datagram_Connect (char *host) Con_DPrintf("wrong reply address\n"); Con_DPrintf("Expected: %s\n", StrAddr (&sendaddr)); Con_DPrintf("Received: %s\n", StrAddr (&readaddr)); - SCR_UpdateScreen (); + CL_UpdateScreen (); //#endif ret = 0; continue; @@ -1301,7 +1301,7 @@ static qsocket_t *_Datagram_Connect (char *host) while (ret == 0 && (SetNetTime() - start_time) < 2.5); if (ret) break; - Con_Printf("still trying...\n"); SCR_UpdateScreen (); + Con_Printf("still trying...\n"); CL_UpdateScreen (); start_time = SetNetTime(); } diff --git a/pr_cmds.c b/pr_cmds.c index 08a1368e..38364ccb 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -1096,22 +1096,36 @@ void PF_dprint (void) Con_DPrintf ("%s",PF_VarString(0)); } -char pr_string_temp[128]; +// LordHavoc: added this to semi-fix the problem of using many ftos calls in a print +#define STRINGTEMP_BUFFERS 16 +#define STRINGTEMP_LENGTH 128 +static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH]; +static int pr_string_tempindex = 0; + +static char *PR_GetTempString(void) +{ + char *s; + s = pr_string_temp[pr_string_tempindex]; + pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS; + return s; +} void PF_ftos (void) { - float v; + float v; + char *s; v = G_FLOAT(OFS_PARM0); - // LordHavoc: ftos improvement - sprintf (pr_string_temp, "%g", v); + s = PR_GetTempString(); /* if (v == (int)v) - sprintf (pr_string_temp, "%d",(int)v); + sprintf (s, "%d",(int)v); else - sprintf (pr_string_temp, "%5.1f",v); + sprintf (s, "%5.1f",v); */ - G_INT(OFS_RETURN) = pr_string_temp - pr_strings; + // LordHavoc: ftos improvement + sprintf (s, "%g", v); + G_INT(OFS_RETURN) = s - pr_strings; } void PF_fabs (void) @@ -1123,14 +1137,18 @@ void PF_fabs (void) void PF_vtos (void) { - sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); - G_INT(OFS_RETURN) = pr_string_temp - pr_strings; + char *s; + s = PR_GetTempString(); + sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); + G_INT(OFS_RETURN) = s - pr_strings; } void PF_etos (void) { - sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0)); - G_INT(OFS_RETURN) = pr_string_temp - pr_strings; + char *s; + s = PR_GetTempString(); + sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0)); + G_INT(OFS_RETURN) = s - pr_strings; } void PF_Spawn (void) @@ -1156,7 +1174,7 @@ void PF_Remove (void) // entity (entity start, .string field, string match) find = #5; void PF_Find (void) { - int e; + int e; int f; char *s, *t; edict_t *ed; @@ -1169,7 +1187,7 @@ void PF_Find (void) RETURN_EDICT(sv.edicts); return; } - + for (e++ ; e < sv.num_edicts ; e++) { ed = EDICT_NUM(e); @@ -1336,7 +1354,7 @@ void PF_precache_model (void) if (!sv.model_precache[i]) { sv.model_precache[i] = s; - sv.models[i] = Mod_ForName (s, true, true, false); + sv.models[i] = Mod_ForName (s, true, false, false); return; } if (!strcmp(sv.model_precache[i], s)) diff --git a/quakedef.h b/quakedef.h index bba4b238..8b1cec02 100644 --- a/quakedef.h +++ b/quakedef.h @@ -215,7 +215,6 @@ typedef enum {false, true} qboolean; #include "world.h" #include "keys.h" #include "console.h" -#include "view.h" #include "menu.h" #include "crc.h" #include "cdaudio.h" diff --git a/r_crosshairs.c b/r_crosshairs.c index a628b71d..6ab2619a 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -5,162 +5,40 @@ cvar_t crosshair_alpha = {CVAR_SAVE, "crosshair_alpha", "1.0"}; cvar_t crosshair_flashspeed = {CVAR_SAVE, "crosshair_flashspeed", "2"}; cvar_t crosshair_flashrange = {CVAR_SAVE, "crosshair_flashrange", "0.1"}; +// must match NUMCROSSHAIRS in gl_draw.c #define NUMCROSSHAIRS 5 -static rtexturepool_t *crosshairtexturepool; - -static rtexture_t *crosshairtex[NUMCROSSHAIRS]; - -static byte *crosshairtexdata[NUMCROSSHAIRS] = -{ - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0003300000033000" - "0003550000553000" - "0000577007750000" - "0000077007700000" - "0000000000000000" - "0000000000000000" - "0000077007700000" - "0000577007750000" - "0003550000553000" - "0003300000033000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - , - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0003000000003000" - "0000500000050000" - "0000070000700000" - "0000007007000000" - "0000000000000000" - "0000000000000000" - "0000007007000000" - "0000070000700000" - "0000500000050000" - "0003000000003000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - , - "0000000000000000" - "0000000770000000" - "0000000770000000" - "0000000000000000" - "0000000000000000" - "0000000440000000" - "0000000440000000" - "0770044004400770" - "0770044004400770" - "0000000440000000" - "0000000440000000" - "0000000000000000" - "0000000770000000" - "0000000770000000" - "0000000000000000" - "0000000000000000" - , - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000077777770" - "0000000075200000" - "0000000072000000" - "0000000070000000" - "0000000070000000" - "0000000070000000" - "0000000000000000" - "0000000000000000" - , - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000070000000" - "0000000000000000" - "0000000040000000" - "0000070404070000" - "0000000040000000" - "0000000000000000" - "0000000070000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" - "0000000000000000" -}; - -static void crosshairload(int num, byte *in) -{ - int i; - byte data[16*16][4]; - for (i = 0;i < 16*16;i++) - { - data[i][0] = data[i][1] = data[i][2] = 255; - data[i][3] = (in[i] - '0') * 255 / 7; - } - crosshairtex[num] = R_LoadTexture(crosshairtexturepool, va("crosshair%02d", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE); -} - -static void r_crosshairs_start(void) -{ - int i; - crosshairtexturepool = R_AllocTexturePool(); - for (i = 0;i < NUMCROSSHAIRS;i++) - crosshairload(i, crosshairtexdata[i]); -// crosshairtex[1] = crosshairload(crosshairtex2); -} - -static void r_crosshairs_shutdown(void) -{ - R_FreeTexturePool(&crosshairtexturepool); -} - -static void r_crosshairs_newmap(void) -{ -} - void R_Crosshairs_Init(void) { Cvar_RegisterVariable(&crosshair_brightness); Cvar_RegisterVariable(&crosshair_alpha); Cvar_RegisterVariable(&crosshair_flashspeed); Cvar_RegisterVariable(&crosshair_flashrange); - R_RegisterModule("R_Crosshairs", r_crosshairs_start, r_crosshairs_shutdown, r_crosshairs_newmap); } void DrawCrosshair(int num) { + int i; byte *color; float scale, base; if (num < 0 || num >= NUMCROSSHAIRS) num = 0; if (cl.viewentity) { - int i = (cl.scores[cl.viewentity-1].colors & 0xF) << 4; + i = (cl.scores[cl.viewentity-1].colors & 0xF) << 4; if (i >= 208 && i < 224) // blue i += 8; else if (i < 128 || i >= 224) // 128-224 are backwards ranges (bright to dark, rather than dark to bright) i += 15; - color = (byte *) &d_8to24table[i]; } else - color = (byte *) &d_8to24table[15]; + i = 15; + color = (byte *) &d_8to24table[i]; if (crosshair_flashspeed.value >= 0.01f) -// scale = (sin(realtime * crosshair_flashspeed.value * (M_PI*2.0f)) * crosshair_flashrange.value + 1.0f) * (1.0f / 255.0f); base = (sin(realtime * crosshair_flashspeed.value * (M_PI*2.0f)) * crosshair_flashrange.value); else base = 0.0f; - scale = crosshair_brightness.value / 255.0f; - Draw_GenericPic(crosshairtex[num], color[0] * scale + base, color[1] * scale + base, color[2] * scale + base, crosshair_alpha.value, vid.conwidth * 0.5f - 8.0f, vid.conheight * 0.5f - 8.0f, 16.0f, 16.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); } diff --git a/r_decals.c b/r_decals.c index 05861c17..74a9b35d 100644 --- a/r_decals.c +++ b/r_decals.c @@ -41,17 +41,271 @@ void R_Decals_Init(void) R_RegisterModule("R_Decals", r_decals_start, r_decals_shutdown, r_decals_newmap); } +/* static int decalindexarray[2*3] = { 0, 1, 2, 0, 2, 3, }; +*/ void R_DrawDecals (void) { renderdecal_t *r; int i, j, lightmapstep, ds, dt; - float fscale, fr, fg, fb, dist, f, ifog, impact[3], v[3], org[3], dir[3], right[3], up[3], tvertex[4][5]; + float fscale, fr, fg, fb, dist, f, fog, ifog, fogvec[3], impact[3], v[3], org[3], dir[3], right[3], up[3], tvxyz[4][4], tvst[4][2]; + particletexture_t *tex, *texfog; + byte *lightmap; + msurface_t *surf; + rdlight_t *rd; + rmeshinfo_t m; + + if (!r_drawdecals.integer) + return; + + fog = 0; + ifog = 1; + + Mod_CheckLoaded(cl.worldmodel); + + // LordHavoc: this meshinfo must match up with R_Mesh_DrawDecal + // LordHavoc: the commented out lines are hardwired behavior in R_Mesh_DrawDecal + memset(&m, 0, sizeof(m)); + m.blendfunc1 = GL_SRC_ALPHA; + m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + //m.numtriangles = 2; + //m.numverts = 4; + //m.index = decalindexarray; + m.vertex = &tvxyz[0][0]; + //m.vertexstep = sizeof(float[4]); + m.tex[0] = R_GetTexture(particlefonttexture); + m.texcoords[0] = &tvst[0][0]; + //m.texcoordstep[0] = sizeof(float[2]); + + for (i = 0, r = r_refdef.decals;i < r_refdef.numdecals;i++, r++) + { + if (r->ent) + { + if (r->ent->visframe != r_framecount) + continue; + + Mod_CheckLoaded(r->ent->model); + if (r->ent->model->type != mod_brush) + continue; + + surf = r->ent->model->surfaces + r->surface; + + // skip decals on surfaces that aren't visible in this frame + if (surf->visframe != r_framecount) + continue; + + softwaretransformforentity(r->ent); + softwaretransform(r->org, org); + softwaretransformdirection(r->dir, dir); + + // do not render if the view origin is behind the decal + VectorSubtract(org, r_origin, fogvec); + if (DotProduct(dir, fogvec) < 0) + continue; + } + else + { + surf = cl.worldmodel->surfaces + r->surface; + + // skip decals on surfaces that aren't visible in this frame + if (surf->visframe != r_framecount) + continue; + + // do not render if the view origin is behind the decal + VectorSubtract(r->org, r_origin, fogvec); + if (DotProduct(r->dir, fogvec) < 0) + continue; + + VectorCopy(r->org, org); + VectorCopy(r->dir, dir); + } + + dist = -PlaneDiff(r->org, surf->plane); + VectorMA(r->org, dist, surf->plane->normal, impact); + + ds = (int) (DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) - surf->texturemins[0]; + dt = (int) (DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) - surf->texturemins[1]; + + if (ds < 0 || dt < 0 || ds > surf->extents[0] || dt > surf->extents[1]) + { + // this should never happen + continue; + } + + tex = &particletexture[r->tex][0]; + VectorVectors(dir, right, up); + VectorScale(right, r->scale, right); + VectorScale(up, r->scale, up); + tvxyz[0][0] = org[0] - right[0] - up[0]; + tvxyz[0][1] = org[1] - right[1] - up[1]; + tvxyz[0][2] = org[2] - right[2] - up[2]; + tvxyz[1][0] = org[0] - right[0] + up[0]; + tvxyz[1][1] = org[1] - right[1] + up[1]; + tvxyz[1][2] = org[2] - right[2] + up[2]; + tvxyz[2][0] = org[0] + right[0] + up[0]; + tvxyz[2][1] = org[1] + right[1] + up[1]; + tvxyz[2][2] = org[2] + right[2] + up[2]; + tvxyz[3][0] = org[0] + right[0] - up[0]; + tvxyz[3][1] = org[1] + right[1] - up[1]; + tvxyz[3][2] = org[2] + right[2] - up[2]; + tvst[0][0] = tex->s1; + tvst[0][1] = tex->t1; + tvst[1][0] = tex->s1; + tvst[1][1] = tex->t2; + tvst[2][0] = tex->s2; + tvst[2][1] = tex->t2; + tvst[3][0] = tex->s2; + tvst[3][1] = tex->t1; + + // lighting + fr = fg = fb = 0.0f; + + if ((lightmap = surf->samples)) + { + if (surf->styles[0] != 255) + { + lightmap += ((dt >> 4) * ((surf->extents[0] >> 4) + 1) + (ds >> 4)) * 3; + fscale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f); + fr += lightmap[0] * fscale; + fg += lightmap[1] * fscale; + fb += lightmap[2] * fscale; + if (surf->styles[1] != 255) + { + lightmapstep = (((surf->extents[0] >> 4) + 1) * ((surf->extents[1] >> 4) + 1)) * 3; + lightmap += lightmapstep; + fscale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f); + fr += lightmap[0] * fscale; + fg += lightmap[1] * fscale; + fb += lightmap[2] * fscale; + if (surf->styles[2] != 255) + { + lightmap += lightmapstep; + fscale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f); + fr += lightmap[0] * fscale; + fg += lightmap[1] * fscale; + fb += lightmap[2] * fscale; + if (surf->styles[3] != 255) + { + lightmap += lightmapstep; + fscale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f); + fr += lightmap[0] * fscale; + fg += lightmap[1] * fscale; + fb += lightmap[2] * fscale; + } + } + } + } + } + + if (surf->dlightframe == r_framecount) + { + for (j = 0;j < r_numdlights;j++) + { + if (surf->dlightbits[j >> 5] & (1 << (j & 31))) + { + rd = &r_dlight[j]; + VectorSubtract(r->org, rd->origin, v); + dist = DotProduct(v, v) + LIGHTOFFSET; + if (dist < rd->cullradius2) + { + f = (1.0f / dist) - rd->lightsubtract; + if (f > 0) + { + fr += f * rd->light[0]; + fg += f * rd->light[1]; + fb += f * rd->light[2]; + } + } + } + } + } + + // if the surface is transparent, render as transparent + m.transparent = !(surf->flags & SURF_CLIPSOLID); + m.cr = r->color[0] * fr; + m.cg = r->color[1] * fg; + m.cb = r->color[2] * fb; + m.ca = r->color[3]; + + if (fogenabled) + { + fog = exp(fogdensity/DotProduct(fogvec,fogvec)); + texfog = &particletexture[r->tex][1]; + if (fog >= (1.0f / 64.0f)) + { + if (fog >= (1.0f - (1.0f / 64.0f))) + { + // fully fogged, just use the fog texture and render as alpha + m.cr = fogcolor[0]; + m.cg = fogcolor[1]; + m.cb = fogcolor[2]; + m.ca = r->color[3]; + tvst[0][0] = texfog->s1; + tvst[0][1] = texfog->t1; + tvst[1][0] = texfog->s1; + tvst[1][1] = texfog->t2; + tvst[2][0] = texfog->s2; + tvst[2][1] = texfog->t2; + tvst[3][0] = texfog->s2; + tvst[3][1] = texfog->t1; + R_Mesh_DrawDecal(&m); + } + else + { + // partially fogged, darken the first pass + ifog = 1 - fog; + m.cr *= ifog; + m.cg *= ifog; + m.cb *= ifog; + if (tex->s1 == texfog->s1 && tex->t1 == texfog->t1) + { + // fog texture is the same as the base, just change the color + m.cr += fogcolor[0] * fog; + m.cg += fogcolor[1] * fog; + m.cb += fogcolor[2] * fog; + R_Mesh_DrawDecal(&m); + } + else + { + // render the first pass (alpha), then do additive fog + R_Mesh_DrawDecal(&m); + m.blendfunc2 = GL_ONE; + m.cr = fogcolor[0]; + m.cg = fogcolor[1]; + m.cb = fogcolor[2]; + m.ca = r->color[3] * fog; + tvst[0][0] = texfog->s1; + tvst[0][1] = texfog->t1; + tvst[1][0] = texfog->s1; + tvst[1][1] = texfog->t2; + tvst[2][0] = texfog->s2; + tvst[2][1] = texfog->t2; + tvst[3][0] = texfog->s2; + tvst[3][1] = texfog->t1; + R_Mesh_DrawDecal(&m); + m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + } + } + else + R_Mesh_DrawDecal(&m); + } + else + R_Mesh_DrawDecal(&m); + } +} + +/* +void R_DrawDecals (void) +{ + renderdecal_t *r; + int i, j, lightmapstep, ds, dt; + float fscale, fr, fg, fb, dist, f, fog, ifog, impact[3], v[3], org[3], dir[3], right[3], up[3], tv[4][5]; particletexture_t *tex; byte *lightmap; msurface_t *surf; @@ -71,10 +325,10 @@ void R_DrawDecals (void) m.numtriangles = 2; m.numverts = 4; m.index = decalindexarray; - m.vertex = &tvertex[0][0]; + m.vertex = &tv[0][0]; m.vertexstep = sizeof(float[5]); m.tex[0] = R_GetTexture(particlefonttexture); - m.texcoords[0] = &tvertex[0][3]; + m.texcoords[0] = &tv[0][3]; m.texcoordstep[0] = sizeof(float[5]); for (i = 0, r = r_refdef.decals;i < r_refdef.numdecals;i++, r++) @@ -133,32 +387,35 @@ void R_DrawDecals (void) } if (fogenabled) + { ifog = 1 - exp(fogdensity/DotProduct(v,v)); + ifog = bound(0, ifog, 1); + } tex = &particletexture[r->tex][0]; VectorVectors(dir, right, up); VectorScale(right, r->scale, right); VectorScale(up, r->scale, up); - tvertex[0][0] = org[0] - right[0] - up[0]; - tvertex[0][1] = org[1] - right[1] - up[1]; - tvertex[0][2] = org[2] - right[2] - up[2]; - tvertex[0][3] = tex->s1; - tvertex[0][4] = tex->t1; - tvertex[1][0] = org[0] - right[0] + up[0]; - tvertex[1][1] = org[1] - right[1] + up[1]; - tvertex[1][2] = org[2] - right[2] + up[2]; - tvertex[1][3] = tex->s1; - tvertex[1][4] = tex->t2; - tvertex[2][0] = org[0] + right[0] + up[0]; - tvertex[2][1] = org[1] + right[1] + up[1]; - tvertex[2][2] = org[2] + right[2] + up[2]; - tvertex[2][3] = tex->s2; - tvertex[2][4] = tex->t2; - tvertex[3][0] = org[0] + right[0] - up[0]; - tvertex[3][1] = org[1] + right[1] - up[1]; - tvertex[3][2] = org[2] + right[2] - up[2]; - tvertex[3][3] = tex->s2; - tvertex[3][4] = tex->t1; + tv[0][0] = org[0] - right[0] - up[0]; + tv[0][1] = org[1] - right[1] - up[1]; + tv[0][2] = org[2] - right[2] - up[2]; + tv[0][3] = tex->s1; + tv[0][4] = tex->t1; + tv[1][0] = org[0] - right[0] + up[0]; + tv[1][1] = org[1] - right[1] + up[1]; + tv[1][2] = org[2] - right[2] + up[2]; + tv[1][3] = tex->s1; + tv[1][4] = tex->t2; + tv[2][0] = org[0] + right[0] + up[0]; + tv[2][1] = org[1] + right[1] + up[1]; + tv[2][2] = org[2] + right[2] + up[2]; + tv[2][3] = tex->s2; + tv[2][4] = tex->t2; + tv[3][0] = org[0] + right[0] - up[0]; + tv[3][1] = org[1] + right[1] - up[1]; + tv[3][2] = org[2] + right[2] - up[2]; + tv[3][3] = tex->s2; + tv[3][4] = tex->t1; // lighting fr = fg = fb = 0.0f; @@ -237,7 +494,7 @@ void R_DrawDecals (void) m.cb *= ifog; } - R_Mesh_Draw(&m); + R_Mesh_DrawDecal(&m); } if (!fogenabled) @@ -289,7 +546,9 @@ void R_DrawDecals (void) VectorCopy(r->dir, dir); } - m.ca = r->color[3] * exp(fogdensity/DotProduct(v,v)); + fog = exp(fogdensity/DotProduct(v,v)); + fog = bound(0, fog, 1); + m.ca = r->color[3] * fog; if (m.ca >= 0.01f) { @@ -309,31 +568,31 @@ void R_DrawDecals (void) VectorVectors(dir, right, up); VectorScale(right, r->scale, right); VectorScale(up, r->scale, up); - tvertex[0][0] = org[0] - right[0] - up[0]; - tvertex[0][1] = org[1] - right[1] - up[1]; - tvertex[0][2] = org[2] - right[2] - up[2]; - tvertex[0][3] = tex->s1; - tvertex[0][4] = tex->t1; - tvertex[1][0] = org[0] - right[0] + up[0]; - tvertex[1][1] = org[1] - right[1] + up[1]; - tvertex[1][2] = org[2] - right[2] + up[2]; - tvertex[1][3] = tex->s1; - tvertex[1][4] = tex->t2; - tvertex[2][0] = org[0] + right[0] + up[0]; - tvertex[2][1] = org[1] + right[1] + up[1]; - tvertex[2][2] = org[2] + right[2] + up[2]; - tvertex[2][3] = tex->s2; - tvertex[2][4] = tex->t2; - tvertex[3][0] = org[0] + right[0] - up[0]; - tvertex[3][1] = org[1] + right[1] - up[1]; - tvertex[3][2] = org[2] + right[2] - up[2]; - tvertex[3][3] = tex->s2; - tvertex[3][4] = tex->t1; + tv[0][0] = org[0] - right[0] - up[0]; + tv[0][1] = org[1] - right[1] - up[1]; + tv[0][2] = org[2] - right[2] - up[2]; + tv[0][3] = tex->s1; + tv[0][4] = tex->t1; + tv[1][0] = org[0] - right[0] + up[0]; + tv[1][1] = org[1] - right[1] + up[1]; + tv[1][2] = org[2] - right[2] + up[2]; + tv[1][3] = tex->s1; + tv[1][4] = tex->t2; + tv[2][0] = org[0] + right[0] + up[0]; + tv[2][1] = org[1] + right[1] + up[1]; + tv[2][2] = org[2] + right[2] + up[2]; + tv[2][3] = tex->s2; + tv[2][4] = tex->t2; + tv[3][0] = org[0] + right[0] - up[0]; + tv[3][1] = org[1] + right[1] - up[1]; + tv[3][2] = org[2] + right[2] - up[2]; + tv[3][3] = tex->s2; + tv[3][4] = tex->t1; // if the surface is transparent, render as transparent m.transparent = !(surf->flags & SURF_CLIPSOLID); - R_Mesh_Draw(&m); + R_Mesh_DrawDecal(&m); } } } - +*/ diff --git a/r_particles.c b/r_particles.c index dbd3f003..16458108 100644 --- a/r_particles.c +++ b/r_particles.c @@ -291,13 +291,13 @@ void R_Particles_Init (void) R_RegisterModule("R_Particles", r_part_start, r_part_shutdown, r_part_newmap); } -int partindexarray[6] = {0, 1, 2, 0, 2, 3}; +//int partindexarray[6] = {0, 1, 2, 0, 2, 3}; void R_DrawParticles (void) { renderparticle_t *r; int i, lighting; - float minparticledist, org[3], uprightangles[3], up2[3], right2[3], v[3], right[3], up[3], tv[4][5], fog, diff[3]; + float minparticledist, org[3], uprightangles[3], up2[3], right2[3], v[3], right[3], up[3], tvxyz[4][4], tvst[4][2], fog, ifog, fogvec[3]; mleaf_t *leaf; particletexture_t *tex, *texfog; rmeshinfo_t m; @@ -319,18 +319,20 @@ void R_DrawParticles (void) minparticledist = DotProduct(r_origin, vpn) + 16.0f; + // LordHavoc: this meshinfo must match up with R_Mesh_DrawDecal + // LordHavoc: the commented out lines are hardwired behavior in R_Mesh_DrawDecal memset(&m, 0, sizeof(m)); m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - m.numtriangles = 2; - m.index = partindexarray; - m.numverts = 4; - m.vertex = &tv[0][0]; - m.vertexstep = sizeof(float[5]); + //m.numtriangles = 2; + //m.index = partindexarray; + //m.numverts = 4; + m.vertex = &tvxyz[0][0]; + //m.vertexstep = sizeof(float[4]); m.tex[0] = R_GetTexture(particlefonttexture); - m.texcoords[0] = &tv[0][3]; - m.texcoordstep[0] = sizeof(float[5]); + m.texcoords[0] = &tvst[0][0]; + //m.texcoordstep[0] = sizeof(float[2]); for (i = 0, r = r_refdef.particles;i < r_refdef.numparticles;i++, r++) { @@ -383,93 +385,94 @@ void R_DrawParticles (void) } tex = &particletexture[r->tex][0]; - texfog = &particletexture[r->tex][1]; - - tv[0][0] = org[0] - right[0] - up[0]; - tv[0][1] = org[1] - right[1] - up[1]; - tv[0][2] = org[2] - right[2] - up[2]; - tv[0][3] = tex->s1; - tv[0][4] = tex->t1; - tv[1][0] = org[0] - right[0] + up[0]; - tv[1][1] = org[1] - right[1] + up[1]; - tv[1][2] = org[2] - right[2] + up[2]; - tv[1][3] = tex->s1; - tv[1][4] = tex->t2; - tv[2][0] = org[0] + right[0] + up[0]; - tv[2][1] = org[1] + right[1] + up[1]; - tv[2][2] = org[2] + right[2] + up[2]; - tv[2][3] = tex->s2; - tv[2][4] = tex->t2; - tv[3][0] = org[0] + right[0] - up[0]; - tv[3][1] = org[1] + right[1] - up[1]; - tv[3][2] = org[2] + right[2] - up[2]; - tv[3][3] = tex->s2; - tv[3][4] = tex->t1; + + tvxyz[0][0] = org[0] - right[0] - up[0]; + tvxyz[0][1] = org[1] - right[1] - up[1]; + tvxyz[0][2] = org[2] - right[2] - up[2]; + tvxyz[1][0] = org[0] - right[0] + up[0]; + tvxyz[1][1] = org[1] - right[1] + up[1]; + tvxyz[1][2] = org[2] - right[2] + up[2]; + tvxyz[2][0] = org[0] + right[0] + up[0]; + tvxyz[2][1] = org[1] + right[1] + up[1]; + tvxyz[2][2] = org[2] + right[2] + up[2]; + tvxyz[3][0] = org[0] + right[0] - up[0]; + tvxyz[3][1] = org[1] + right[1] - up[1]; + tvxyz[3][2] = org[2] + right[2] - up[2]; + tvst[0][0] = tex->s1; + tvst[0][1] = tex->t1; + tvst[1][0] = tex->s1; + tvst[1][1] = tex->t2; + tvst[2][0] = tex->s2; + tvst[2][1] = tex->t2; + tvst[3][0] = tex->s2; + tvst[3][1] = tex->t1; fog = 0; if (fogenabled) { - VectorSubtract(org, r_origin, diff); - fog = exp(fogdensity/DotProduct(diff,diff)); - if (fog >= 0.01f) + texfog = &particletexture[r->tex][1]; + VectorSubtract(org, r_origin, fogvec); + fog = exp(fogdensity/DotProduct(fogvec,fogvec)); + if (fog >= (1.0f / 64.0f)) { - if (fog >= 0.99f) + if (fog >= (1.0f - (1.0f / 64.0f))) { // fully fogged, just use the fog texture and render as alpha m.cr = fogcolor[0]; m.cg = fogcolor[1]; m.cb = fogcolor[2]; m.ca = r->color[3]; - tv[0][3] = texfog->s1; - tv[0][4] = texfog->t1; - tv[1][3] = texfog->s1; - tv[1][4] = texfog->t2; - tv[2][3] = texfog->s2; - tv[2][4] = texfog->t2; - tv[3][3] = texfog->s2; - tv[3][4] = texfog->t1; - R_Mesh_Draw(&m); + tvst[0][0] = texfog->s1; + tvst[0][1] = texfog->t1; + tvst[1][0] = texfog->s1; + tvst[1][1] = texfog->t2; + tvst[2][0] = texfog->s2; + tvst[2][1] = texfog->t2; + tvst[3][0] = texfog->s2; + tvst[3][1] = texfog->t1; + R_Mesh_DrawDecal(&m); } else { // partially fogged, darken the first pass - m.cr *= 1 - fog; - m.cg *= 1 - fog; - m.cb *= 1 - fog; + ifog = 1 - fog; + m.cr *= ifog; + m.cg *= ifog; + m.cb *= ifog; if (tex->s1 == texfog->s1 && tex->t1 == texfog->t1) { // fog texture is the same as the base, just change the color m.cr += fogcolor[0] * fog; m.cg += fogcolor[1] * fog; m.cb += fogcolor[2] * fog; - R_Mesh_Draw(&m); + R_Mesh_DrawDecal(&m); } else { // render the first pass (alpha), then do additive fog - R_Mesh_Draw(&m); + R_Mesh_DrawDecal(&m); m.blendfunc2 = GL_ONE; m.cr = fogcolor[0]; m.cg = fogcolor[1]; m.cb = fogcolor[2]; m.ca = r->color[3] * fog; - tv[0][3] = texfog->s1; - tv[0][4] = texfog->t1; - tv[1][3] = texfog->s1; - tv[1][4] = texfog->t2; - tv[2][3] = texfog->s2; - tv[2][4] = texfog->t2; - tv[3][3] = texfog->s2; - tv[3][4] = texfog->t1; - R_Mesh_Draw(&m); + tvst[0][0] = texfog->s1; + tvst[0][1] = texfog->t1; + tvst[1][0] = texfog->s1; + tvst[1][1] = texfog->t2; + tvst[2][0] = texfog->s2; + tvst[2][1] = texfog->t2; + tvst[3][0] = texfog->s2; + tvst[3][1] = texfog->t1; + R_Mesh_DrawDecal(&m); m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; } } } else - R_Mesh_Draw(&m); + R_Mesh_DrawDecal(&m); } else - R_Mesh_Draw(&m); + R_Mesh_DrawDecal(&m); } } diff --git a/r_sky.c b/r_sky.c index fbf9e420..fb991b56 100644 --- a/r_sky.c +++ b/r_sky.c @@ -184,14 +184,14 @@ void LoadSky_f (void) vert[i][0] = (x) * 1024.0f + r_origin[0];\ vert[i][1] = (y) * 1024.0f + r_origin[1];\ vert[i][2] = (z) * 1024.0f + r_origin[2];\ - vert[i][4] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\ - vert[i][5] = (t) * (254.0f/256.0f) + (1.0f/256.0f); + st[i][0] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\ + st[i][1] = (t) * (254.0f/256.0f) + (1.0f/256.0f); int skyboxindex[6] = {0, 1, 2, 0, 2, 3}; static void R_SkyBox(void) { - float vert[4][6]; + float vert[4][4], st[4][2]; rmeshinfo_t m; memset(&m, 0, sizeof(m)); m.transparent = false; @@ -201,13 +201,13 @@ static void R_SkyBox(void) m.numverts = 4; m.index = skyboxindex; m.vertex = &vert[0][0]; - m.vertexstep = sizeof(float[6]); + m.vertexstep = sizeof(float[4]); m.cr = 1; m.cg = 1; m.cb = 1; m.ca = 1; - m.texcoords[0] = &vert[0][4]; - m.texcoordstep[0] = sizeof(float[6]); + m.texcoords[0] = &st[0][0]; + m.texcoordstep[0] = sizeof(float[2]); m.tex[0] = R_GetTexture(skyboxside[3]); // front R_SkyBoxPolyVec(0, 1, 0, 1, -1, 1); R_SkyBoxPolyVec(1, 1, 1, 1, -1, -1); @@ -441,6 +441,14 @@ void R_InitSky (byte *src, int bytesperpixel) unsigned *rgba; strcpy(skyworldname, loadmodel->name); + + // flush skytexturepool so we won't build up a leak from uploading textures multiple times + R_FreeTexturePool(&skytexturepool); + skytexturepool = R_AllocTexturePool(); + mergeskytexture = NULL; + solidskytexture = NULL; + alphaskytexture = NULL; + if (bytesperpixel == 4) { for (i = 0;i < 128;i++) diff --git a/r_sprites.c b/r_sprites.c index e72a1116..19e67671 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -107,10 +107,14 @@ void R_ClipSprite (void) R_ClipSpriteImage(org, right, up); } +//int spritepolyindex[6] = {0, 1, 2, 0, 2, 3}; + void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec3_t origin, vec3_t up, vec3_t right, float red, float green, float blue, float alpha) { rmeshinfo_t m; - float v[4][5]; + float v[4][4], st[4][2]; + // LordHavoc: this meshinfo must match up with R_Mesh_DrawDecal + // LordHavoc: the commented out lines are hardwired behavior in R_Mesh_DrawDecal memset(&m, 0, sizeof(m)); m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -119,38 +123,41 @@ void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec3_t ori || (currentrenderentity->model->flags & EF_ADDITIVE) || fog) m.blendfunc2 = GL_ONE; + //m.numtriangles = 2; + //m.index = spritepolyindex; + //m.numverts = 4; m.vertex = &v[0][0]; - m.vertexstep = sizeof(float[5]); + //m.vertexstep = sizeof(float[4]); m.cr = red; m.cg = green; m.cb = blue; m.ca = alpha; m.tex[0] = texture; - m.texcoords[0] = &v[0][3]; - m.texcoordstep[0] = sizeof(float[5]); + m.texcoords[0] = &st[0][0]; + //m.texcoordstep[0] = sizeof(float[2]); v[0][0] = origin[0] + frame->down * up[0] + frame->left * right[0]; v[0][1] = origin[1] + frame->down * up[1] + frame->left * right[1]; v[0][2] = origin[2] + frame->down * up[2] + frame->left * right[2]; - v[0][3] = 0; - v[0][4] = 1; v[1][0] = origin[0] + frame->up * up[0] + frame->left * right[0]; v[1][1] = origin[1] + frame->up * up[1] + frame->left * right[1]; v[1][2] = origin[2] + frame->up * up[2] + frame->left * right[2]; - v[1][3] = 0; - v[1][4] = 0; v[2][0] = origin[0] + frame->up * up[0] + frame->right * right[0]; v[2][1] = origin[1] + frame->up * up[1] + frame->right * right[1]; v[2][2] = origin[2] + frame->up * up[2] + frame->right * right[2]; - v[2][3] = 1; - v[2][4] = 0; v[3][0] = origin[0] + frame->down * up[0] + frame->right * right[0]; v[3][1] = origin[1] + frame->down * up[1] + frame->right * right[1]; v[3][2] = origin[2] + frame->down * up[2] + frame->right * right[2]; - v[3][3] = 1; - v[3][4] = 1; - - R_Mesh_DrawPolygon(&m, 4); + st[0][0] = 0; + st[0][1] = 1; + st[1][0] = 0; + st[1][1] = 0; + st[2][0] = 1; + st[2][1] = 0; + st[3][0] = 1; + st[3][1] = 1; + + R_Mesh_DrawDecal(&m); } /* diff --git a/render.h b/render.h index bd136319..febe3caf 100644 --- a/render.h +++ b/render.h @@ -50,8 +50,7 @@ extern void SHOWLMP_clear(void); // render profiling stuff extern qboolean intimerefresh; -extern cvar_t r_speeds2; -extern char r_speeds2_string[1024]; +extern char r_speeds_string[1024]; // lighting stuff extern vec3_t lightspot; diff --git a/sbar.c b/sbar.c index 683fcd3d..8df370c6 100644 --- a/sbar.c +++ b/sbar.c @@ -24,7 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef struct { char name[16]; - qpic_t *qpic; } sbarpic_t; @@ -34,24 +33,12 @@ static int numsbarpics; static sbarpic_t *Sbar_NewPic(char *name) { strcpy(sbarpics[numsbarpics].name, name); - sbarpics[numsbarpics].qpic = NULL; + // precache it + // FIXME: precache on every renderer restart (or move this to client) + Draw_CachePic(name); return sbarpics + (numsbarpics++); } -static qpic_t *Sbar_GetQPic(sbarpic_t *p) -{ - if (!p->qpic) - p->qpic = Draw_CachePic(p->name); - return p->qpic; -} - -static void Sbar_ClearPics(void) -{ - int i; - for (i = 0;i < numsbarpics;i++) - sbarpics[i].qpic = NULL; -} - sbarpic_t *sb_disc; #define STAT_MINUS 10 // num frame for '-' stats digit @@ -93,6 +80,8 @@ int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BI //MED 01/04/97 added hipnotic items array sbarpic_t *hsb_items[2]; +cvar_t showfps = {CVAR_SAVE, "showfps", "0"}; + void Sbar_MiniDeathmatchOverlay (void); void Sbar_DeathmatchOverlay (void); @@ -122,20 +111,6 @@ void Sbar_DontShowScores (void) sb_showscores = false; } -void sbar_start(void) -{ - Sbar_ClearPics(); -} - -void sbar_shutdown(void) -{ - Sbar_ClearPics(); -} - -void sbar_newmap(void) -{ -} - /* =============== Sbar_Init @@ -147,6 +122,7 @@ void Sbar_Init (void) Cmd_AddCommand ("+showscores", Sbar_ShowScores); Cmd_AddCommand ("-showscores", Sbar_DontShowScores); + Cvar_RegisterVariable (&showfps); numsbarpics = 0; @@ -281,8 +257,6 @@ void Sbar_Init (void) rsb_ammo[1] = Sbar_NewPic ("r_ammomulti"); rsb_ammo[2] = Sbar_NewPic ("r_ammoplasma"); } - - R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap); } @@ -299,13 +273,12 @@ Sbar_DrawPic */ void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic) { - Draw_Pic (sbar_x + x, sbar_y + y, Sbar_GetQPic(sbarpic)); + DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, 1, 0); } -void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha); void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha) { - Draw_AlphaPic (sbar_x + x, sbar_y + y, Sbar_GetQPic(sbarpic), alpha); + DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha, 0); } /* @@ -317,7 +290,7 @@ Draws one solid graphics character */ void Sbar_DrawCharacter (int x, int y, int num) { - Draw_Character (sbar_x + x + 4 , sbar_y + y, num); + DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, 1, 0); } /* @@ -327,60 +300,9 @@ Sbar_DrawString */ void Sbar_DrawString (int x, int y, char *str) { - Draw_String (sbar_x + x, sbar_y + y, str, 0); + DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, 1, 0); } -int pow10table[10] = -{ - 1, - 10, - 100, - 1000, - 10000, - 100000, - 1000000, - 10000000, - 100000000, - 1000000000, -}; - -/* -============= -Sbar_itoa -============= -*/ -int Sbar_itoa (int num, char *buf) -{ - int i; - char *str; - - str = buf; - - if (num < 0) - { - *str++ = '-'; - num = -num; - } - - for (i = 9;i > 0 && num < pow10table[i];i--); - - for (;i >= 0;i--) - { - *str = '0'; - while (num >= pow10table[i]) - { - num -= pow10table[i]; - (*str)++; - } - str++; - } - - *str = 0; - - return str - buf; -} - - /* ============= Sbar_DrawNum @@ -388,11 +310,10 @@ Sbar_DrawNum */ void Sbar_DrawNum (int x, int y, int num, int digits, int color) { - char str[16]; - char *ptr; - int l, frame; + char str[32], *ptr; + int l, frame; - l = Sbar_itoa (num, str); + l = sprintf(str, "%i", num); ptr = str; if (l > digits) ptr += (l-digits); @@ -683,15 +604,14 @@ Sbar_DrawFrags */ void Sbar_DrawFrags (void) { - int i, k, l; - int top, bottom; - int x, f; - char num[12]; - scoreboard_t *s; + int i, k, l, x, f; + char num[12]; + scoreboard_t *s; + byte *c; Sbar_SortFrags (); -// draw the text + // draw the text l = scoreboardlines <= 4 ? scoreboardlines : 4; x = 23 * 8; @@ -703,14 +623,13 @@ void Sbar_DrawFrags (void) if (!s->name[0]) continue; - // draw background - top = (s->colors & 0xf0) + 8; - bottom = ((s->colors & 15)<<4) + 8; - - Draw_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, top); - Draw_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, bottom); + // draw background + c = (byte *)&d_8to24table[(s->colors & 0xf0) + 8]; + DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); + c = (byte *)&d_8to24table[((s->colors & 15)<<4) + 8]; + DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); - // draw number + // draw number f = s->frags; sprintf (num, "%3i",f); @@ -743,24 +662,23 @@ void Sbar_DrawFace (void) // PGM 03/02/97 - fixed so color swatch only appears in CTF modes if (gamemode == GAME_ROGUE && (cl.maxclients != 1) && (teamplay.integer > 3) && (teamplay.integer < 7)) { - int top, bottom; - char num[12]; - scoreboard_t *s; + char num[12]; + scoreboard_t *s; + byte *c; s = &cl.scores[cl.viewentity - 1]; // draw background - top = (s->colors & 0xf0) + 8; - bottom = ((s->colors & 15)<<4) + 8; - Sbar_DrawPic (112, 0, rsb_teambord); - Draw_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+3, 22, 9, top); - Draw_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+12, 22, 9, bottom); + c = (byte *)&d_8to24table[(s->colors & 0xf0) + 8]; + DrawQ_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+3, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); + c = (byte *)&d_8to24table[((s->colors & 15)<<4) + 8]; + DrawQ_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+12, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); // draw number f = s->frags; sprintf (num, "%3i",f); - if (top==8) + if ((s->colors & 0xf0)==0) { if (num[0] != ' ') Sbar_DrawCharacter(109, 3, 18 + num[0] - '0'); @@ -796,11 +714,51 @@ void Sbar_DrawFace (void) } } +void Sbar_ShowFPS(void) +{ + if (showfps.integer) + { + static double currtime, frametimes[32]; + double newtime, total; + char temp[32]; + int calc, count, i; + static int framecycle = 0; + float fps_x, fps_y, fps_scalex, fps_scaley; + + newtime = Sys_DoubleTime(); + frametimes[framecycle] = newtime - currtime; + total = 0; + count = 0; + while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31]) + { + total += frametimes[i]; + count++; + } + framecycle++; + framecycle &= 31; + if (showfps.integer == 1) + calc = (int) (((double) count / total) + 0.5); + else // showfps 2, rapid update + calc = (int) ((1.0 / (newtime - currtime)) + 0.5); + sprintf(temp, "%4i", calc); + currtime = newtime; + fps_scalex = 12; + fps_scaley = 12; + fps_x = vid.conwidth - (fps_scalex * strlen(temp)); + fps_y = vid.conheight - sb_lines/* - 8*/; // yes this might draw over the sbar + if (fps_y > vid.conheight - fps_scaley) + fps_y = vid.conheight - fps_scaley; + DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(temp), fps_scaley, 0, 0, 0, 0.5, 0); + DrawQ_String(fps_x, fps_y, temp, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0); + } +} + /* =============== Sbar_Draw =============== */ +void DrawCrosshair(int num); void Sbar_Draw (void) { if (scr_con_current == vid.conheight) @@ -908,6 +866,11 @@ void Sbar_Draw (void) if (vid.conwidth > 320 && cl.gametype == GAME_DEATHMATCH) Sbar_MiniDeathmatchOverlay (); + + if (crosshair.integer >= 1) + DrawCrosshair(crosshair.integer - 1); + + Sbar_ShowFPS(); } //============================================================================= @@ -920,13 +883,14 @@ Sbar_DeathmatchOverlay */ void Sbar_DeathmatchOverlay (void) { - qpic_t *pic; - int i, k, l, top, bottom, x, y, total, n, minutes, tens, units, fph; - char num[128]; - scoreboard_t *s; + cachepic_t *pic; + int i, k, l, x, y, total, n, minutes, tens, units, fph; + char num[128]; + scoreboard_t *s; + byte *c; pic = Draw_CachePic ("gfx/ranking.lmp"); - Draw_Pic ((vid.conwidth - pic->width)/2, 8, pic); + DrawQ_Pic ((vid.conwidth - pic->width)/2, 8, "gfx/ranking.lmp", 0, 0, 1, 1, 1, 1, 0); // scores Sbar_SortFrags (); @@ -944,11 +908,10 @@ void Sbar_DeathmatchOverlay (void) continue; // draw background - top = (s->colors & 0xf0) + 8; - bottom = ((s->colors & 15)<<4) + 8; - - Draw_Fill ( x, y+1, 88, 3, top); - Draw_Fill ( x, y+4, 88, 3, bottom); + c = (byte *)&d_8to24table[(s->colors & 0xf0) + 8]; + DrawQ_Fill ( x, y+1, 88, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); + c = (byte *)&d_8to24table[((s->colors & 15)<<4) + 8]; + DrawQ_Fill ( x, y+4, 88, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); total = cl.time - s->entertime; minutes = (int)total/60; @@ -962,7 +925,7 @@ void Sbar_DeathmatchOverlay (void) // put it together sprintf (num, "%c %4i:%4i %4i:%c%c %s", k == cl.viewentity - 1 ? 12 : ' ', (int) s->frags, fph, minutes, tens, units, s->name); - Draw_String(x - 8, y, num, 0); + DrawQ_String(x - 8, y, num, 0, 8, 8, 1, 1, 1, 1, 0); y += 8; } @@ -976,17 +939,18 @@ Sbar_DeathmatchOverlay */ void Sbar_MiniDeathmatchOverlay (void) { - int i, l, k, top, bottom, x, y, fph, numlines; - char num[128]; - scoreboard_t *s; + int i, l, k, x, y, fph, numlines; + char num[128]; + scoreboard_t *s; + byte *c; if (vid.conwidth < 512 || !sb_lines) return; -// scores + // scores Sbar_SortFrags (); -// draw the text + // draw the text l = scoreboardlines; y = vid.conheight - sb_lines; numlines = sb_lines/8; @@ -998,15 +962,15 @@ void Sbar_MiniDeathmatchOverlay (void) if (fragsort[i] == cl.viewentity - 1) break; - if (i == scoreboardlines) // we're not there - i = 0; - else // figure out start - i = i - numlines/2; + if (i == scoreboardlines) // we're not there + i = 0; + else // figure out start + i = i - numlines/2; - if (i > scoreboardlines - numlines) - i = scoreboardlines - numlines; - if (i < 0) - i = 0; + if (i > scoreboardlines - numlines) + i = scoreboardlines - numlines; + if (i < 0) + i = 0; x = 324; for (;i < scoreboardlines && y < vid.conheight - 8;i++) @@ -1016,12 +980,11 @@ void Sbar_MiniDeathmatchOverlay (void) if (!s->name[0]) continue; - // draw background - top = (s->colors & 0xf0) + 8; - bottom = ((s->colors & 15)<<4) + 8; - - Draw_Fill ( x, y+1, 72, 3, top); - Draw_Fill ( x, y+4, 72, 3, bottom); + // draw background + c = (byte *)&d_8to24table[(s->colors & 0xf0) + 8]; + DrawQ_Fill ( x, y+1, 72, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); + c = (byte *)&d_8to24table[((s->colors & 15)<<4) + 8]; + DrawQ_Fill ( x, y+4, 72, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0); fph = (cl.time - s->entertime) ? (int) ((float) s->frags * 3600.0 / (cl.time - s->entertime)) : 0; if (fph < -999) fph = -999; @@ -1029,7 +992,7 @@ void Sbar_MiniDeathmatchOverlay (void) // put it together sprintf (num, "%c%4i:%4i%c %s", k == cl.viewentity - 1 ? 16 : ' ', (int) s->frags, fph, k == cl.viewentity - 1 ? 17 : ' ', s->name); - Draw_String(x - 8, y, num, 0); + DrawQ_String(x - 8, y, num, 0, 8, 8, 1, 1, 1, 1, 0); y += 8; } @@ -1055,8 +1018,8 @@ void Sbar_IntermissionOverlay (void) sbar_x = 0; sbar_y = 0; - Draw_Pic (64, 24, Draw_CachePic ("gfx/complete.lmp")); - Draw_Pic (0, 56, Draw_CachePic ("gfx/inter.lmp")); + DrawQ_Pic (64, 24, "gfx/complete.lmp", 0, 0, 1, 1, 1, 1, 0); + DrawQ_Pic (0, 56, "gfx/inter.lmp", 0, 0, 1, 1, 1, 1, 0); // time dig = cl.completed_time/60; @@ -1085,8 +1048,8 @@ Sbar_FinaleOverlay */ void Sbar_FinaleOverlay (void) { - qpic_t *pic; + cachepic_t *pic; pic = Draw_CachePic ("gfx/finale.lmp"); - Draw_Pic((vid.conwidth - pic->width)/2, 16, pic); + DrawQ_Pic((vid.conwidth - pic->width)/2, 16, "gfx/finale.lmp", 0, 0, 1, 1, 1, 1, 0); } diff --git a/sv_main.c b/sv_main.c index a46d87d2..ddf57d3e 100644 --- a/sv_main.c +++ b/sv_main.c @@ -1414,7 +1414,7 @@ void SV_SpawnServer (char *server) for (i = 1;i < sv.worldmodel->numsubmodels;i++) { sv.model_precache[i+1] = localmodels[i]; - sv.models[i+1] = Mod_ForName (localmodels[i], false, true, false); + sv.models[i+1] = Mod_ForName (localmodels[i], false, false, false); } // diff --git a/ui.c b/ui.c index 9097aaf5..e00fd7d6 100644 --- a/ui.c +++ b/ui.c @@ -14,63 +14,16 @@ cvar_t ui_showname = {0, "ui_showname", "0"}; #define UI_MOUSEBUTTONS 3 -static int ui_alive, ui_active; -static float ui_mouse_x, ui_mouse_y; -static int ui_mousebutton[UI_MOUSEBUTTONS], ui_mouseclick; -static int ui_keyui, ui_keyitem; -static ui_item_t *ui_keyrealitem; +static int ui_alive, ui_active; +static float ui_mouse_x, ui_mouse_y; +static int ui_mousebutton[UI_MOUSEBUTTONS], ui_mouseclick; +static int ui_keyui, ui_keyitem; +static ui_item_t *ui_keyrealitem; static ui_t *ui_list[MAX_UI_COUNT]; -//static qpic_t *ui_mousepointer; -static rtexture_t *ui_mousepointertexture; - -static byte pointerimage[256] = -{ - "333333332......." - "26777761........" - "2655541........." - "265541.........." - "2654561........." - "26414561........" - "251.14561......." - "21...14561......" - "1.....141......." - ".......1........" - "................" - "................" - "................" - "................" - "................" - "................" -}; - -static rtexturepool_t *uitexturepool; - static void ui_start(void) { - int i; - byte buffer[256][4]; - uitexturepool = R_AllocTexturePool(); -// ui_mousepointer = Draw_CachePic("ui/mousepointer.lmp"); - for (i = 0;i < 256;i++) - { - if (pointerimage[i] == '.') - { - buffer[i][0] = 0; - buffer[i][1] = 0; - buffer[i][2] = 0; - buffer[i][3] = 0; - } - else - { - buffer[i][0] = (pointerimage[i] - '0') * 16; - buffer[i][1] = (pointerimage[i] - '0') * 16; - buffer[i][2] = (pointerimage[i] - '0') * 16; - buffer[i][3] = 255; - } - } - ui_mousepointertexture = R_LoadTexture(uitexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE); ui_mouse_x = vid.conwidth * 0.5; ui_mouse_y = vid.conheight * 0.5; ui_alive = true; @@ -78,10 +31,7 @@ static void ui_start(void) static void ui_shutdown(void) { -// ui_mousepointer = NULL; - ui_mousepointertexture = NULL; ui_alive = false; - R_FreeTexturePool(&uitexturepool); } static void ui_newmap(void) @@ -142,7 +92,7 @@ void ui_clear(ui_t *ui) void ui_item ( ui_t *ui, char *basename, int number, - float x, float y, qpic_t *pic, char *string, + float x, float y, char *picname, char *string, float left, float top, float width, float height, void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2), void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2), @@ -170,10 +120,10 @@ void ui_item memset(it, 0, sizeof(ui_item_t)); strncpy(it->name, itemname, 32); it->flags = 0; - if (pic || string) + if (picname || string) { it->flags |= ITEM_DRAWABLE; - it->draw_pic = pic; + it->draw_picname = picname; it->draw_string = string; it->draw_x = x; it->draw_y = y; @@ -432,29 +382,29 @@ void ui_draw(void) for (i = 0, it = ui->items;i < ui->item_count;i++, it++) if (it->flags & ITEM_DRAWABLE) { - if (it->draw_pic) - Draw_Pic(it->draw_x, it->draw_y, it->draw_pic); + if (it->draw_picname) + DrawQ_Pic(it->draw_x, it->draw_y, it->draw_picname, 0, 0, 1, 1, 1, 1, 0); if (it->draw_string) - Draw_String(it->draw_x, it->draw_y, it->draw_string, 9999); + DrawQ_String(it->draw_x, it->draw_y, it->draw_string, 0, 8, 8, 1, 1, 1, 1, 0); } if ((it = ui_hititem(ui_mouse_x, ui_mouse_y))) { - if (it->draw_pic) - Draw_AdditivePic(it->draw_x, it->draw_y, it->draw_pic); + if (it->draw_picname) + DrawQ_Pic(it->draw_x, it->draw_y, it->draw_picname, 0, 0, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); if (it->draw_string) - Draw_AdditiveString(it->draw_x, it->draw_y, it->draw_string, 9999); + DrawQ_String(it->draw_x, it->draw_y, it->draw_string, 0, 8, 8, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); if (ui_showname.integer) - Draw_String(ui_mouse_x, ui_mouse_y + 16, it->name, 9999); + DrawQ_String(ui_mouse_x, ui_mouse_y + 16, it->name, 0, 8, 8, 1, 1, 1, 1, 0); } it = ui_keyrealitem; - if (it->draw_pic) - Draw_AdditivePic(it->draw_x, it->draw_y, it->draw_pic); + if (it->draw_picname) + DrawQ_Pic(it->draw_x, it->draw_y, it->draw_picname, 0, 0, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); if (it->draw_string) - Draw_AdditiveString(it->draw_x, it->draw_y, it->draw_string, 9999); + DrawQ_String(it->draw_x, it->draw_y, it->draw_string, 0, 8, 8, 1, 1, 1, 1, DRAWFLAG_ADDITIVE); -// Draw_Pic(ui_mouse_x, ui_mouse_y, ui_mousepointer); - Draw_GenericPic(ui_mousepointertexture, 1, 1, 1, 1, ui_mouse_x, ui_mouse_y, 16, 16); + DrawQ_Pic(ui_mouse_x, ui_mouse_y, "ui/mousepointer.tga", 0, 0, 1, 1, 1, 1, 0); + //Draw_GenericPic(ui_mousepointertexture, 1, 1, 1, 1, ui_mouse_x, ui_mouse_y, 16, 16); } } diff --git a/ui.h b/ui.h index a9b94688..71b4ec91 100644 --- a/ui.h +++ b/ui.h @@ -11,7 +11,7 @@ typedef struct { char name[32]; int flags; - qpic_t *draw_pic; + char *draw_picname; char *draw_string; int draw_x, draw_y; int click_x, click_y, click_x2, click_y2; @@ -65,7 +65,7 @@ void ui_clear(ui_t *ui); void ui_item ( ui_t *ui, char *basename, int number, - float x, float y, qpic_t *pic, char *string, + float x, float y, char *picname, char *string, float left, float top, float width, float height, void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2), void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2), diff --git a/vid_wgl.c b/vid_wgl.c index 5da80a2c..6a78bb0b 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -1458,7 +1458,7 @@ extern void M_Menu_Options_f (void); extern void M_Print (int cx, int cy, char *str); extern void M_PrintWhite (int cx, int cy, char *str); extern void M_DrawCharacter (int cx, int line, int num); -extern void M_DrawPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, char *picname); static int vid_line, vid_wmodes; @@ -1482,17 +1482,17 @@ VID_MenuDraw */ void VID_MenuDraw (void) { - qpic_t *p; - char *ptr; - int lnummodes, i, k, column, row; - vmode_t *pv; + cachepic_t *p; + char *ptr; + int lnummodes, i, k, column, row; + vmode_t *pv; p = Draw_CachePic ("gfx/vidmodes.lmp"); - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawPic ( (320-p->width)/2, 4, "gfx/vidmodes.lmp"); vid_wmodes = 0; lnummodes = VID_NumModes (); - + for (i=1 ; (i 4) - bob = 4; - else if (bob < -7) - bob = -7; + bob = bound(-7, bob, 4); return bob; - -} - - -//============================================================================= +} void V_StartPitchDrift (void) { @@ -168,7 +153,7 @@ Drifting is enabled when the center view key is hit, mlook is released and lookspring is non 0, or when =============== */ -void V_DriftPitch (void) +static void V_DriftPitch (void) { float delta, move; @@ -186,14 +171,14 @@ void V_DriftPitch (void) cl.driftmove = 0; else cl.driftmove += cl.frametime; - + if ( cl.driftmove > v_centermove.value) { V_StartPitchDrift (); } return; } - + delta = cl.idealpitch - cl.viewangles[PITCH]; if (!delta) @@ -204,7 +189,7 @@ void V_DriftPitch (void) move = cl.frametime * cl.pitchvel; cl.pitchvel += cl.frametime * v_centerspeed.value; - + //Con_Printf ("move: %f (%f)\n", move, cl.frametime); if (delta > 0) @@ -232,21 +217,13 @@ void V_DriftPitch (void) /* -============================================================================== - - SCREEN FLASHES - -============================================================================== -*/ - - -cshift_t cshift_empty = { {130,80,50}, 0 }; -cshift_t cshift_water = { {130,80,50}, 128 }; -cshift_t cshift_slime = { {0,25,5}, 150 }; -cshift_t cshift_lava = { {255,80,0}, 150 }; - -byte ramps[3][256]; -float v_blend[4]; // rgba 0.0 - 1.0 +============================================================================== + + SCREEN FLASHES + +============================================================================== +*/ + /* =============== @@ -255,14 +232,11 @@ V_ParseDamage */ void V_ParseDamage (void) { - int armor, blood; - vec3_t from; - int i; - vec3_t forward, right; - entity_t *ent; - float side; - float count; - + int i, armor, blood; + vec3_t from, forward, right; + entity_t *ent; + float side, count; + armor = MSG_ReadByte (); blood = MSG_ReadByte (); for (i=0 ; i<3 ; i++) @@ -274,65 +248,63 @@ void V_ParseDamage (void) cl.faceanimtime = cl.time + 0.2; // put sbar face into pain frame - if (gl_polyblend.value) - { - cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; - if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) - cl.cshifts[CSHIFT_DAMAGE].percent = 0; - if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) - cl.cshifts[CSHIFT_DAMAGE].percent = 150; + cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; + if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) + cl.cshifts[CSHIFT_DAMAGE].percent = 150; - if (armor > blood) - { - cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; - cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; - cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; - } - else if (armor) - { - cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; - cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; - cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; - } - else - { - cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; - cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; - cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; - } + if (armor > blood) + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; + } + else if (armor) + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; } // // calculate view angle kicks // ent = &cl_entities[cl.viewentity]; - + VectorSubtract (from, ent->render.origin, from); VectorNormalize (from); - + AngleVectors (ent->render.angles, forward, right, NULL); side = DotProduct (from, right); v_dmg_roll = count*side*v_kickroll.value; - + side = DotProduct (from, forward); v_dmg_pitch = count*side*v_kickpitch.value; v_dmg_time = v_kicktime.value; } +static cshift_t v_cshift; /* ================== V_cshift_f ================== */ -void V_cshift_f (void) +static void V_cshift_f (void) { - cshift_empty.destcolor[0] = atoi(Cmd_Argv(1)); - cshift_empty.destcolor[1] = atoi(Cmd_Argv(2)); - cshift_empty.destcolor[2] = atoi(Cmd_Argv(3)); - cshift_empty.percent = atoi(Cmd_Argv(4)); + v_cshift.destcolor[0] = atoi(Cmd_Argv(1)); + v_cshift.destcolor[1] = atoi(Cmd_Argv(2)); + v_cshift.destcolor[2] = atoi(Cmd_Argv(3)); + v_cshift.percent = atoi(Cmd_Argv(4)); } @@ -343,78 +315,76 @@ V_BonusFlash_f When you run over an item, the server sends this command ================== */ -void V_BonusFlash_f (void) +static void V_BonusFlash_f (void) { - if (gl_polyblend.value) - { - cl.cshifts[CSHIFT_BONUS].destcolor[0] = 215; - cl.cshifts[CSHIFT_BONUS].destcolor[1] = 186; - cl.cshifts[CSHIFT_BONUS].destcolor[2] = 69; - cl.cshifts[CSHIFT_BONUS].percent = 50; - } + cl.cshifts[CSHIFT_BONUS].destcolor[0] = 215; + cl.cshifts[CSHIFT_BONUS].destcolor[1] = 186; + cl.cshifts[CSHIFT_BONUS].destcolor[2] = 69; + cl.cshifts[CSHIFT_BONUS].percent = 50; } /* ============= -V_SetContentsColor - -Underwater, lava, etc each has a color shift +V_UpdateBlends ============= */ -void V_SetContentsColor (int contents) +void V_UpdateBlends (void) { - cshift_t* c; - c = &cl.cshifts[CSHIFT_CONTENTS]; // just to shorten the code below - if (!gl_polyblend.value) + float r, g, b, a, a2; + int j; + + if (cl.worldmodel == NULL) { - c->percent = 0; + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + cl.cshifts[CSHIFT_BONUS].percent = 0; + cl.cshifts[CSHIFT_CONTENTS].percent = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 0; + r_refdef.viewblend[0] = 0; + r_refdef.viewblend[1] = 0; + r_refdef.viewblend[2] = 0; + r_refdef.viewblend[3] = 0; return; } - switch (contents) + + // drop the damage value + cl.cshifts[CSHIFT_DAMAGE].percent -= (cl.time - cl.oldtime)*150; + if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + + // drop the bonus value + cl.cshifts[CSHIFT_BONUS].percent -= (cl.time - cl.oldtime)*100; + if (cl.cshifts[CSHIFT_BONUS].percent <= 0) + cl.cshifts[CSHIFT_BONUS].percent = 0; + + // set contents color + switch (Mod_PointInLeaf (r_refdef.vieworg, cl.worldmodel)->contents) { case CONTENTS_EMPTY: case CONTENTS_SOLID: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; - c->destcolor[0] = cshift_empty.destcolor[0]; - c->destcolor[1] = cshift_empty.destcolor[1]; - c->destcolor[2] = cshift_empty.destcolor[2]; - c->percent = cshift_empty.percent; + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = v_cshift.destcolor[0]; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = v_cshift.destcolor[1]; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = v_cshift.destcolor[2]; + cl.cshifts[CSHIFT_CONTENTS].percent = v_cshift.percent; break; case CONTENTS_LAVA: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_lava; - c->destcolor[0] = cshift_lava.destcolor[0]; - c->destcolor[1] = cshift_lava.destcolor[1]; - c->destcolor[2] = cshift_lava.destcolor[2]; - c->percent = cshift_lava.percent; + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 255; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0; + cl.cshifts[CSHIFT_CONTENTS].percent = 150; break; case CONTENTS_SLIME: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_slime; - c->destcolor[0] = cshift_slime.destcolor[0]; - c->destcolor[1] = cshift_slime.destcolor[1]; - c->destcolor[2] = cshift_slime.destcolor[2]; - c->percent = cshift_slime.percent; + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 25; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 5; + cl.cshifts[CSHIFT_CONTENTS].percent = 150; break; default: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_water; - c->destcolor[0] = cshift_water.destcolor[0]; - c->destcolor[1] = cshift_water.destcolor[1]; - c->destcolor[2] = cshift_water.destcolor[2]; - c->percent = cshift_water.percent; + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 130; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 50; + cl.cshifts[CSHIFT_CONTENTS].percent = 128; } -} -/* -============= -V_CalcPowerupCshift -============= -*/ -void V_CalcPowerupCshift (void) -{ - if (!gl_polyblend.value) - { - cl.cshifts[CSHIFT_POWERUP].percent = 0; - return; - } if (cl.items & IT_QUAD) { cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; @@ -445,159 +415,48 @@ void V_CalcPowerupCshift (void) } else cl.cshifts[CSHIFT_POWERUP].percent = 0; -} - -/* -============= -V_CalcBlend -============= -*/ -// LordHavoc: fixed V_CalcBlend -void V_CalcBlend (void) -{ - float r, g, b, a, a2; - int j; + // LordHavoc: fixed V_CalcBlend r = 0; g = 0; b = 0; a = 0; -// if (gl_cshiftpercent.value) -// { - for (j=0 ; j 1) - a2 = 1; - r += (cl.cshifts[j].destcolor[0]-r) * a2; - g += (cl.cshifts[j].destcolor[1]-g) * a2; - b += (cl.cshifts[j].destcolor[2]-b) * a2; - a = 1 - (1 - a) * (1 - a2); // correct alpha multiply... took a while to find it on the web - } - // saturate color (to avoid blending in black) - if (a) - { - a2 = 1 / a; - r *= a2; - g *= a2; - b *= a2; - } -// } - - v_blend[0] = bound(0, r * (1.0/255.0), 1); - v_blend[1] = bound(0, g * (1.0/255.0), 1); - v_blend[2] = bound(0, b * (1.0/255.0), 1); - v_blend[3] = bound(0, a , 1); -} - -/* -============= -V_UpdateBlends -============= -*/ -void V_UpdateBlends (void) -{ - int i, j; - qboolean new; - - V_CalcPowerupCshift (); - - new = false; - - for (i=0 ; i 1) + a2 = 1; + r += (cl.cshifts[j].destcolor[0]-r) * a2; + g += (cl.cshifts[j].destcolor[1]-g) * a2; + b += (cl.cshifts[j].destcolor[2]-b) * a2; + a = 1 - (1 - a) * (1 - a2); // correct alpha multiply... took a while to find it on the web + } + // saturate color (to avoid blending in black) + if (a) + { + a2 = 1 / a; + r *= a2; + g *= a2; + b *= a2; } - -// drop the damage value - cl.cshifts[CSHIFT_DAMAGE].percent -= (cl.time - cl.oldtime)*150; - if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0) - cl.cshifts[CSHIFT_DAMAGE].percent = 0; - -// drop the bonus value - cl.cshifts[CSHIFT_BONUS].percent -= (cl.time - cl.oldtime)*100; - if (cl.cshifts[CSHIFT_BONUS].percent <= 0) - cl.cshifts[CSHIFT_BONUS].percent = 0; - - if (!new) - return; - - V_CalcBlend (); -} - -/* -============================================================================== - - VIEW RENDERING - -============================================================================== -*/ -float angledelta (float a) -{ - a = ANGLEMOD(a); - if (a > 180) - a -= 360; - return a; + r_refdef.viewblend[0] = bound(0, r * (1.0/255.0), 1); + r_refdef.viewblend[1] = bound(0, g * (1.0/255.0), 1); + r_refdef.viewblend[2] = bound(0, b * (1.0/255.0), 1); + r_refdef.viewblend[3] = bound(0, a , 1); } /* -================== -CalcGunAngle -================== -*/ -void CalcGunAngle (void) -{ - cl.viewent.render.angles[YAW] = r_refdef.viewangles[YAW]; - cl.viewent.render.angles[PITCH] = -r_refdef.viewangles[PITCH]; +============================================================================== - cl.viewent.render.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; - cl.viewent.render.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; - cl.viewent.render.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; -} + VIEW RENDERING -/* -============== -V_BoundOffsets -============== +============================================================================== */ -void V_BoundOffsets (void) -{ - entity_t *ent; - - ent = &cl_entities[cl.viewentity]; - -// absolutely bound refresh relative to entity clipping hull -// so the view can never be inside a solid wall - - if (r_refdef.vieworg[0] < ent->render.origin[0] - 14) - r_refdef.vieworg[0] = ent->render.origin[0] - 14; - else if (r_refdef.vieworg[0] > ent->render.origin[0] + 14) - r_refdef.vieworg[0] = ent->render.origin[0] + 14; - if (r_refdef.vieworg[1] < ent->render.origin[1] - 14) - r_refdef.vieworg[1] = ent->render.origin[1] - 14; - else if (r_refdef.vieworg[1] > ent->render.origin[1] + 14) - r_refdef.vieworg[1] = ent->render.origin[1] + 14; - if (r_refdef.vieworg[2] < ent->render.origin[2] - 22) - r_refdef.vieworg[2] = ent->render.origin[2] - 22; - else if (r_refdef.vieworg[2] > ent->render.origin[2] + 30) - r_refdef.vieworg[2] = ent->render.origin[2] + 30; -} /* ============== @@ -606,71 +465,14 @@ V_AddIdle Idle swaying ============== */ -void V_AddIdle (void) +static void V_AddIdle (float idle) { - r_refdef.viewangles[ROLL] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; - r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; - r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; -} - - -/* -============== -V_CalcViewRoll - -Roll is induced by movement and damage -============== -*/ -void V_CalcViewRoll (void) -{ - float side; - - side = V_CalcRoll (cl_entities[cl.viewentity].render.angles, cl.velocity); - r_refdef.viewangles[ROLL] += side; - - if (v_dmg_time > 0) - { - r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; - r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; - v_dmg_time -= cl.frametime; - } - - if (cl.stats[STAT_HEALTH] <= 0) - { - r_refdef.viewangles[ROLL] = 80; // dead view angle - return; - } - + r_refdef.viewangles[ROLL] += idle * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + r_refdef.viewangles[PITCH] += idle * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + r_refdef.viewangles[YAW] += idle * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; } -/* -================== -V_CalcIntermissionRefdef - -================== -*/ -void V_CalcIntermissionRefdef (void) -{ - entity_t *ent, *view; - float old; - -// ent is the player model (visible when out of body) - ent = &cl_entities[cl.viewentity]; -// view is the weapon model (only visible from inside body) - view = &cl.viewent; - - VectorCopy (ent->render.origin, r_refdef.vieworg); - VectorCopy (ent->render.angles, r_refdef.viewangles); - view->render.model = NULL; - -// always idle in intermission - old = v_idlescale.value; - v_idlescale.value = 1; - V_AddIdle (); - v_idlescale.value = old; -} - /* ================== V_CalcRefdef @@ -680,143 +482,86 @@ V_CalcRefdef void V_CalcRefdef (void) { entity_t *ent, *view; - int i; vec3_t forward; vec3_t angles; float bob; -// static float oldz = 0; - - V_DriftPitch (); + float side; -// ent is the player model (visible when out of body) + // ent is the player model (visible when out of body) ent = &cl_entities[cl.viewentity]; -// view is the weapon model (only visible from inside body) + // view is the weapon model (only visible from inside body) view = &cl.viewent; + V_DriftPitch (); - if (chase_active.value) - { - VectorCopy (ent->render.origin, r_refdef.vieworg); + VectorCopy (ent->render.origin, r_refdef.vieworg); + if (!intimerefresh) VectorCopy (cl.viewangles, r_refdef.viewangles); + + if (cl.intermission) + { + view->render.model = NULL; + V_AddIdle (1); + } + else if (chase_active.value) + { Chase_Update (); - V_AddIdle (); + V_AddIdle (v_idlescale.value); } else { - // transform the view offset by the model's matrix to get the offset from model origin for the view - // if (!chase_active.value) // LordHavoc: get rid of angle problems in chase_active mode - // { - // ent->render.angles[YAW] = cl.viewangles[YAW]; // the model should face the view dir - // ent->render.angles[PITCH] = -cl.viewangles[PITCH]; // the model should face the view dir - // } - - bob = V_CalcBob (); + side = V_CalcRoll (cl_entities[cl.viewentity].render.angles, cl.velocity); + r_refdef.viewangles[ROLL] += side; - // refresh position - VectorCopy (ent->render.origin, r_refdef.vieworg); - r_refdef.vieworg[2] += cl.viewheight + bob; + if (v_dmg_time > 0) + { + r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; + r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; + v_dmg_time -= cl.frametime; + } - // LordHavoc: the protocol has changed... so this is an obsolete approach - // never let it sit exactly on a node line, because a water plane can - // dissapear when viewed with the eye exactly on it. - // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis - // r_refdef.vieworg[0] += 1.0/32; - // r_refdef.vieworg[1] += 1.0/32; - // r_refdef.vieworg[2] += 1.0/32; + if (cl.stats[STAT_HEALTH] <= 0) + r_refdef.viewangles[ROLL] = 80; // dead view angle - if (!intimerefresh) - VectorCopy (cl.viewangles, r_refdef.viewangles); - V_CalcViewRoll (); - V_AddIdle (); + V_AddIdle (v_idlescale.value); - // offsets + // offsets angles[PITCH] = -ent->render.angles[PITCH]; // because entity pitches are actually backward angles[YAW] = ent->render.angles[YAW]; angles[ROLL] = ent->render.angles[ROLL]; AngleVectors (angles, forward, NULL, NULL); - V_BoundOffsets (); - - // set up gun position - VectorCopy (ent->render.origin, view->render.origin); - view->render.origin[2] += cl.viewheight; - VectorCopy (cl.viewangles, view->render.angles); - - CalcGunAngle (); - - for (i=0 ; i<3 ; i++) - { - view->render.origin[i] += forward[i]*bob*0.4; - // view->render.origin[i] += right[i]*bob*0.4; - // view->render.origin[i] += up[i]*bob*0.8; - } - view->render.origin[2] += bob; + bob = V_CalcBob (); - // FIXME: this setup code is somewhat evil (CL_LerpUpdate should be private) - CL_LerpUpdate(view, cl.stats[STAT_WEAPONFRAME], cl.stats[STAT_WEAPON]); + r_refdef.vieworg[2] += cl.viewheight + bob; - view->render.model = cl.model_precache[cl.stats[STAT_WEAPON]]; - view->render.frame = cl.stats[STAT_WEAPONFRAME]; + // set up gun + view->state_current.modelindex = cl.stats[STAT_WEAPON]; + view->state_current.frame = cl.stats[STAT_WEAPONFRAME]; + view->render.origin[0] = ent->render.origin[0] + bob * 0.4 * forward[0]; + view->render.origin[1] = ent->render.origin[1] + bob * 0.4 * forward[1]; + view->render.origin[2] = ent->render.origin[2] + bob * 0.4 * forward[2] + cl.viewheight + bob; + view->render.angles[PITCH] = -r_refdef.viewangles[PITCH] - v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; + view->render.angles[YAW] = r_refdef.viewangles[YAW] - v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + view->render.angles[ROLL] = r_refdef.viewangles[ROLL] - v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + // FIXME: this setup code is somewhat evil (CL_LerpUpdate should be private?) + CL_LerpUpdate(view); view->render.colormap = -1; // no special coloring view->render.alpha = ent->render.alpha; // LordHavoc: if the player is transparent, so is the gun view->render.effects = ent->render.effects; view->render.scale = 1; - // set up the refresh position - - // LordHavoc: this never looked all that good to begin with... - /* - // smooth out stair step ups - if (cl.onground && ent->render.origin[2] - oldz > 0) - { - float steptime; - - steptime = cl.time - cl.oldtime; - if (steptime < 0) - //FIXME I_Error ("steptime < 0"); - steptime = 0; - - oldz += steptime * 80; - if (oldz > ent->render.origin[2]) - oldz = ent->render.origin[2]; - if (ent->render.origin[2] - oldz > 12) - oldz = ent->render.origin[2] - 12; - r_refdef.vieworg[2] += oldz - ent->render.origin[2]; - view->render.origin[2] += oldz - ent->render.origin[2]; - } - else - oldz = ent->render.origin[2]; - */ - - // LordHavoc: origin view kick added - if (!intimerefresh && v_punch.value) + // LordHavoc: origin view kick added + if (!intimerefresh) { VectorAdd(r_refdef.viewangles, cl.punchangle, r_refdef.viewangles); VectorAdd(r_refdef.vieworg, cl.punchvector, r_refdef.vieworg); } - } -} -/* -================== -V_RenderView - -The player's clipping box goes from (-16 -16 -24) to (16 16 32) from -the entity origin, so any view position inside that will be valid -================== -*/ -void V_RenderView (void) -{ - if (scr_con_current >= vid.conheight) - return; - - if (cl.intermission) - V_CalcIntermissionRefdef (); - else - V_CalcRefdef (); - - R_RenderView (); + // copy to refdef + r_refdef.viewent = view->render; + } } //============================================================================ @@ -828,7 +573,7 @@ V_Init */ void V_Init (void) { - Cmd_AddCommand ("v_cshift", V_cshift_f); + Cmd_AddCommand ("v_cshift", V_cshift_f); Cmd_AddCommand ("bf", V_BonusFlash_f); Cmd_AddCommand ("centerview", V_StartPitchDrift); @@ -844,8 +589,6 @@ void V_Init (void) Cvar_RegisterVariable (&v_idlescale); Cvar_RegisterVariable (&crosshair); -// Cvar_RegisterVariable (&gl_cshiftpercent); - Cvar_RegisterVariable (&gl_polyblend); Cvar_RegisterVariable (&cl_rollspeed); Cvar_RegisterVariable (&cl_rollangle); @@ -855,9 +598,7 @@ void V_Init (void) Cvar_RegisterVariable (&v_kicktime); Cvar_RegisterVariable (&v_kickroll); - Cvar_RegisterVariable (&v_kickpitch); - - Cvar_RegisterVariable (&v_punch); + Cvar_RegisterVariable (&v_kickpitch); } diff --git a/view.h b/view.h deleted file mode 100644 index ab069251..00000000 --- a/view.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -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. - -*/ -// view.h - -extern float v_blend[4]; - -extern cvar_t brightness; - - -void V_Init (void); -void V_RenderView (void); -float V_CalcRoll (vec3_t angles, vec3_t velocity); -void V_UpdateBlends (void); -void V_CalcBlend (void); - diff --git a/wad.c b/wad.c index bba4c97a..5eba9d35 100644 --- a/wad.c +++ b/wad.c @@ -117,7 +117,7 @@ void *W_GetLumpName (char *name) if (!strcmp(clean, lump->name)) return (void *)(wad_base + lump->filepos); - Sys_Error ("W_GetLumpinfo: %s not found", name); + //Sys_Error ("W_GetLumpinfo: %s not found", name); return NULL; } -- 2.39.2