diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index b7d99f039..dc1cd72d5 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -3410,7 +3410,7 @@ float Host_Frame (double time) else { maxfpsignoreserver = false; - maxfps = (cl_maxfps.ival>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:cl_netfps.value; + maxfps = (cl_maxfps.ival>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:((cl_netfps.value>0)?cl_netfps.value:cls.maxfps); /*gets buggy at times longer than 250ms (and 0/negative, obviously)*/ if (maxfps < 4) maxfps = 4; diff --git a/engine/client/image.c b/engine/client/image.c index 9648c66ab..8f3698656 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -191,8 +191,11 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey { return ReadGreyTargaFile(data, length, &tgaheader, asgrey); } - else if (tgaheader.version == 10 || tgaheader.version == 11) + else if (tgaheader.version == 10 || tgaheader.version == 9 || tgaheader.version == 11) { + //9:paletted + //10:bgr(a) + //11:greyscale #undef getc #define getc(x) *data++ unsigned row, rows=tgaheader.height, column, columns=tgaheader.width, packetHeader, packetSize, j; @@ -200,8 +203,62 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey qbyte blue, red, green, alphabyte; - if (tgaheader.version == 10 && tgaheader.bpp == 8) return NULL; - if (tgaheader.version == 11 && tgaheader.bpp != 8) return NULL; + byte_vec4_t palette[256]; + + if (tgaheader.version == 9) + { + for (row = 0; row < 256; row++) + { + palette[row][0] = row; + palette[row][1] = row; + palette[row][2] = row; + palette[row][3] = 255; + } + if (tgaheader.bpp != 8) + return NULL; + } + if (tgaheader.version == 10) + { + if (tgaheader.bpp == 8) + return NULL; + } + if (tgaheader.version == 11) + { + for (row = 0; row < 256; row++) + { + palette[row][0] = row; + palette[row][1] = row; + palette[row][2] = row; + palette[row][3] = 255; + } + if (tgaheader.bpp != 8) + return NULL; + } + + if (tgaheader.cm_type) + { + switch(tgaheader.cm_size) + { + case 24: + for (row = 0; row < tgaheader.cm_len; row++) + { + palette[row][0] = *data++; + palette[row][1] = *data++; + palette[row][2] = *data++; + palette[row][3] = 255; + } + break; + case 32: + for (row = 0; row < tgaheader.cm_len; row++) + { + palette[row][0] = *data++; + palette[row][1] = *data++; + palette[row][2] = *data++; + palette[row][3] = *data++; + } + break; + } + } for(row=rows-1; row>=0; row--) { @@ -218,8 +275,11 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey switch (tgaheader.bpp) { case 8: //we made sure this was version 11 - blue = green = red = *data++; - alphabyte = 255; + blue = palette[*data][0]; + green = palette[*data][1]; + red = palette[*data][2]; + alphabyte = palette[*data][3]; + data++; break; case 16: @@ -303,11 +363,14 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey switch (tgaheader.bpp) { case 8: - blue = green = red = *data++; + blue = palette[*data][0]; + green = palette[*data][1]; + red = palette[*data][2]; *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; - *pixbuf++ = 255; + *pixbuf++ = palette[*data][3]; + data++; break; case 16: inrow = data; @@ -370,7 +433,11 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey switch (tgaheader.bpp) { case 8: - *pixbuf++ = *data++; + blue = palette[*data][0]; + green = palette[*data][1]; + red = palette[*data][2]; + *pixbuf++ = (blue + green + red)/3; + data++; break; case 16: inrow = data; @@ -525,6 +592,8 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey return initbuf; } + else + Con_Printf("Unsupported version\n"); return NULL; } @@ -2410,6 +2479,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) } else { + Con_Printf("Unable to read file %s (format unsupported)\n", fname); BZ_Free(buf); continue; } diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 67d4dae55..b6b7247b1 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -1391,7 +1391,9 @@ void MasterInfo_Begin(void) // if (q2servers) //q2 { Master_AddMaster("255.255.255.255:27910", MT_BCASTQ2, "Nearby Quake2 UDP servers."); +#ifdef USEIPX Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers."); +#endif Master_AddMaster("192.246.40.37:27900", MT_MASTERQ2, "id q2 Master."); } diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 55f6f5e70..b45e5d680 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -129,6 +129,7 @@ void R2D_Init(void) shader_draw_fill = R_RegisterShader("fill_opaque", "{\n" + "program defaultfill\n" "{\n" "map $whiteimage\n" "rgbgen vertex\n" @@ -136,6 +137,7 @@ void R2D_Init(void) "}\n"); shader_draw_fill_trans = R_RegisterShader("fill_trans", "{\n" + "program defaultfill\n" "{\n" "map $whiteimage\n" "rgbgen vertex\n" @@ -145,6 +147,7 @@ void R2D_Init(void) "}\n"); shader_brighten = R_RegisterShader("constrastshader", "{\n" + "program defaultfill\n" "{\n" "map $whiteimage\n" "blendfunc gl_dst_color gl_one\n" @@ -155,6 +158,7 @@ void R2D_Init(void) ); shader_polyblend = R_RegisterShader("polyblendshader", "{\n" + "program defaultfill\n" "{\n" "map $whiteimage\n" "blendfunc gl_src_alpha gl_one_minus_src_alpha\n" @@ -171,9 +175,6 @@ void R2D_Init(void) "{\n" "#ifdef VERTEX_SHADER\n" "\ - uniform mat4 m_view;\ - uniform mat4 m_projection;\ - attribute vec3 v_position;\ attribute vec2 v_texcoord;\ varying vec2 texcoord;\ uniform vec3 rendertexturescale;\ @@ -181,7 +182,7 @@ void R2D_Init(void) {\ texcoord.x = v_texcoord.x*rendertexturescale.x;\ texcoord.y = (1.0-v_texcoord.y)*rendertexturescale.y;\ - gl_Position = m_projection * m_view * vec4(v_position, 1.0);\ + gl_Position = ftetransform();\ }\ \n" "#endif\n" diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 5f884ccd3..d8f9671b4 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1700,17 +1700,21 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); switch (qrenderer) { case QR_NONE: - Con_Printf( "Dedicated console created\n"); + Con_Printf( "\n" + "-----------------------------\n" + "Dedicated console created\n"); break; -#ifdef GLQUAKE case QR_OPENGL: - Con_Printf( "OpenGL renderer initialized\n"); + Con_Printf( "\n" + "-----------------------------\n" + "OpenGL renderer initialized\n"); break; -#endif case QR_DIRECT3D: - Con_Printf( "Direct3d renderer initialized\n"); + Con_Printf( "\n" + "-----------------------------\n" + "Direct3d renderer initialized\n"); break; } diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 4fdc3703e..439dd16ef 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -255,14 +255,14 @@ static qboolean S_Speex_Init(void) s_speex.speexlib = Sys_LoadLibrary("libspeex", qspeexfuncs); if (!s_speex.speexlib) { - Con_Printf("libspeex not found. Voice chat not available.\n"); + Con_Printf("libspeex not found. Voice chat is not available.\n"); return false; } s_speex.speexdsplib = Sys_LoadLibrary("libspeexdsp", qspeexdspfuncs); if (!s_speex.speexdsplib) { - Con_Printf("libspeexdsp not found. Voice chat not available.\n"); + Con_Printf("libspeexdsp not found. Voice chat is not available.\n"); return false; } diff --git a/engine/client/sys_sdl.c b/engine/client/sys_sdl.c index 0a6c0905b..bbb02f87f 100644 --- a/engine/client/sys_sdl.c +++ b/engine/client/sys_sdl.c @@ -471,6 +471,7 @@ int main(int argc, char **argv) float time, newtime, oldtime; quakeparms_t parms; int t; + int delay = 1; parms.argv = argv; @@ -529,14 +530,14 @@ int main(int argc, char **argv) #ifndef CLIENTONLY if (isDedicated) { - NET_Sleep(100, false); + NET_Sleep(delay, false); // find time passed since last cycle newtime = Sys_DoubleTime (); time = newtime - oldtime; oldtime = newtime; - SV_Frame (); + delay = SV_Frame()*1000; } else #endif diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index cf568b8f5..808b06408 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -1448,6 +1448,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin double time, oldtime, newtime; char cwd[1024]; const char *qtvfile = NULL; + int delay = 0; /* previous instances do not exist in Win32 */ if (hPrevInstance) @@ -1635,16 +1636,18 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin #ifndef CLIENTONLY if (isDedicated) //compleate denial to switch to anything else - many of the client structures are not initialized. { + int delay; + SV_Init (&parms); - SV_Frame (); + delay = SV_Frame()*1000; while (1) { if (!isDedicated) Sys_Error("Dedicated was cleared"); - NET_Sleep(100, false); - SV_Frame (); + NET_Sleep(delay, false); + delay = SV_Frame()*1000; } return TRUE; } @@ -1701,14 +1704,14 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin if (isDedicated) { #ifndef CLIENTONLY - NET_Sleep(50, false); + NET_Sleep(delay, false); // find time passed since last cycle newtime = Sys_DoubleTime (); time = newtime - oldtime; oldtime = newtime; - SV_Frame (); + delay = 1000*SV_Frame (); #else Sys_Error("wut?"); #endif diff --git a/engine/d3d/d3d_image.c b/engine/d3d/d3d_image.c index 31f39717b..65135f502 100644 --- a/engine/d3d/d3d_image.c +++ b/engine/d3d/d3d_image.c @@ -20,7 +20,7 @@ static d3dtexture_t *d3d_lookup_texture(char *ident) { d3dtexture_t *tex; - if (ident) + if (ident && *ident) { for (tex = d3dtextures; tex; tex = tex->next) if (!strcmp(tex->name, ident)) @@ -401,6 +401,8 @@ texid_t D3D9_LoadTexture (char *identifier, int width, int height, enum uploadfm case TF_TRANS8_FULLBRIGHT: tid.ptr = D3D9_LoadTexture_8(tex, data, d_8to24rgbtable, width, height, flags, fmt); return tid; + case TF_RGBX32: + flags |= IF_NOALPHA; case TF_RGBA32: tid.ptr = D3D9_LoadTexture_32(tex, data, width, height, flags); return tid; diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 9ed711a7e..7eb666b0d 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -514,8 +514,15 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, frac += fracstep; } } - texnums->base = R_AllocNewTexture(scaled_width, scaled_height); - R_Upload(texnums->base, "", h2playertranslations?TF_RGBA32:TF_RGBX32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP); + if (qrenderer == QR_OPENGL) + { + texnums->base = R_AllocNewTexture(scaled_width, scaled_height); + R_Upload(texnums->base, "", h2playertranslations?TF_RGBA32:TF_RGBX32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP); + } + else + { + texnums->base = R_LoadTexture(NULL, scaled_width, scaled_height, h2playertranslations?TF_RGBA32:TF_RGBX32, pixels, 0); + } if (!h2playertranslations) { @@ -533,8 +540,15 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, frac += fracstep; } } - texnums->fullbright = R_AllocNewTexture(scaled_width, scaled_height); - R_Upload(texnums->fullbright, "", TF_RGBA32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP); + if (qrenderer == QR_OPENGL) + { + texnums->fullbright = R_AllocNewTexture(scaled_width, scaled_height); + R_Upload(texnums->fullbright, "", TF_RGBA32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP); + } + else + { + texnums->fullbright = R_LoadTexture(NULL, scaled_width, scaled_height, h2playertranslations?TF_RGBA32:TF_RGBX32, pixels, 0); + } } } else diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index bc6dfdb54..7c7e65b29 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -36,8 +36,6 @@ uniform vec3 lightposition;\n\ uniform vec3 eyeposition;\n\ #endif\n\ \ -uniform mat4 m_modelview, m_projection;\n\ -attribute vec3 v_position;\n\ attribute vec2 v_texcoord;\n\ attribute vec3 v_normal;\n\ attribute vec3 v_svector;\n\ @@ -45,7 +43,7 @@ attribute vec3 v_tvector;\n\ \ void main (void)\n\ {\n\ - gl_Position = m_projection * m_modelview * vec4(v_position, 1);\n\ + gl_Position = ftetransform();\n\ \ tcbase = v_texcoord; //pass the texture coords straight through\n\ \ @@ -510,6 +508,8 @@ void GL_SetShaderState2D(qboolean is2d) else qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif + if (is2d) + memcpy(shaderstate.modelviewmatrix, r_refdef.m_view, sizeof(shaderstate.modelviewmatrix)); BE_SelectMode(BEM_STANDARD); } @@ -638,16 +638,9 @@ void GL_LazyBind(int tmu, int target, texid_t texnum, qboolean arrays) static void BE_EnableShaderAttributes(unsigned int newm) { unsigned int i; - - i = 0; - if (newm & (1u<nofixedcompat) { qglDisableClientState(GL_COLOR_ARRAY); - qglDisableClientState(GL_VERTEX_ARRAY); BE_EnableShaderAttributes(attr); for (i = 0; i < pass->numMergedPasses; i++) { @@ -2582,6 +2574,12 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas GL_LazyBind(i, 0, r_nulltex, false); } shaderstate.lastpasstmus = pass->numMergedPasses; + + if (!gl_config.nofixedfunc) + { + qglEnableClientState(GL_VERTEX_ARRAY); + GL_ApplyVertexPointer(); + } } else { diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 7e84211ff..98567d818 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -449,8 +449,6 @@ void GL_Set2D (void) float *Matrix4_NewTranslation(float x, float y, float z); float w = vid.width, h = vid.height; - GL_SetShaderState2D(true); - ang = (gl_screenangle.value>0?(gl_screenangle.value+45):(gl_screenangle.value-45))/90; ang = (int)ang * 90; if (ang) @@ -483,6 +481,8 @@ void GL_Set2D (void) qglMatrixMode(GL_MODELVIEW); qglLoadMatrixf(r_refdef.m_view); } + + GL_SetShaderState2D(true); } //==================================================================== diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 52644b655..3c8c1e1ef 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -141,9 +141,6 @@ void GL_InitSceneProcessingShaders_WaterWarp (void) "{\n" "#ifdef VERTEX_SHADER\n" "\ - uniform mat4 m_view;\ - uniform mat4 m_projection;\ - attribute vec3 v_position;\ attribute vec2 v_texcoord;\ varying vec2 v_stc;\ varying vec2 v_warp;\ @@ -151,7 +148,7 @@ void GL_InitSceneProcessingShaders_WaterWarp (void) uniform float e_time;\ void main (void)\ {\ - gl_Position = m_projection * m_view * vec4(v_position, 1.0);\ + gl_Position = ftetransform();\ v_stc = (1.0+(gl_Position.xy / gl_Position.w))/2.0;\ v_warp.s = e_time * 0.25 + v_texcoord.s;\ v_warp.t = e_time * 0.25 + v_texcoord.t;\ @@ -247,7 +244,10 @@ void GL_InitFisheyeFov(void) gl_FragColor = textureCube(source, tc);\ }"; - scenepp_fisheye_program = GLSlang_CreateProgram("#version 110\n", NULL, vshader, fisheyefshader); + if (gl_config.gles) + return; + + scenepp_fisheye_program = GLSlang_CreateProgram("fisheye", "#version 110\n", NULL, vshader, fisheyefshader); if (scenepp_fisheye_program) { GLSlang_UseProgram(scenepp_fisheye_program); @@ -256,7 +256,7 @@ void GL_InitFisheyeFov(void) GLSlang_UseProgram(0); } - scenepp_panorama_program = GLSlang_CreateProgram("#version 110\n", NULL, vshader, panoramafshader); + scenepp_panorama_program = GLSlang_CreateProgram("panorama", "#version 110\n", NULL, vshader, panoramafshader); if (scenepp_panorama_program) { GLSlang_UseProgram(scenepp_panorama_program); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index eaa53e304..1b9655bdd 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -744,7 +744,7 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char * static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames); /*program text is already loaded, this function parses the 'header' of it to see which permutations it provides, and how many times we need to recompile it*/ -static void Shader_LoadPermutations(program_t *prog, char *script, int qrtype, int ver) +static void Shader_LoadPermutations(char *name, program_t *prog, char *script, int qrtype, int ver) { static char *permutationname[] = { @@ -838,7 +838,7 @@ static void Shader_LoadPermutations(program_t *prog, char *script, int qrtype, i permutationdefines[pn++] = permutationname[n]; } permutationdefines[pn++] = NULL; - prog->handle[p].glsl = GLSlang_CreateProgram(vers, permutationdefines, script, script); + prog->handle[p].glsl = GLSlang_CreateProgram(name, vers, permutationdefines, script, script); } #endif #ifdef D3DQUAKE @@ -886,11 +886,32 @@ struct sbuiltin_s with gl4, versions are meant to match the gl version more closely, so gl4.0 uses 400.*/ /*glsl es shaders require precisions to be defined for fragment shader variables more precision for shaders would be a good candidate for a cvar */ + +/*defaultfill is a simple shader for block-filling with vertex colours. note that the blendfunc stuff is done after the shader anyway.*/ + {QR_OPENGL/*ES*/, 100, "defaultfill", + "#ifdef VERTEX_SHADER\n" + "attribute vec2 v_texcoord;\n" + "attribute vec4 v_colour;\n" + "varying vec4 vc;\n" + + "void main (void)\n" + "{\n" + " vc = v_colour;\n" + " gl_Position = ftetransform();\n" + "}\n" + "#endif\n" + + "#ifdef FRAGMENT_SHADER\n" + "varying vec4 vc;\n" + "void main (void)\n" + "{\n" + " gl_FragColor = vc;\n" + "}\n" + "#endif\n" + }, +/*default2d is a simple shader to draw the 2d elements. simple copying of a texture image to its dest (with vertex colour blending)*/ {QR_OPENGL/*ES*/, 100, "default2d", "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_view;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "attribute vec4 v_colour;\n" "varying vec2 tc;\n" @@ -900,7 +921,7 @@ struct sbuiltin_s "{\n" " tc = v_texcoord;\n" " vc = v_colour;\n" - " gl_Position = m_projection * m_view * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -917,9 +938,6 @@ struct sbuiltin_s }, {QR_OPENGL, 110, "default2d", "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_view;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "attribute vec4 v_colour;\n" "varying vec2 tc;\n" @@ -929,7 +947,7 @@ struct sbuiltin_s "{\n" " tc = v_texcoord;\n" " vc = v_colour;\n" - " gl_Position = m_projection * m_view * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -944,12 +962,10 @@ struct sbuiltin_s "}\n" "#endif\n" }, +/*draws a wall, with lightmap.*/ {QR_OPENGL/*ES*/, 100, "defaultwall", "!!cvarf gl_overbright\n" "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "attribute vec2 v_lmcoord;\n" "varying vec2 tc, lm;\n" @@ -958,7 +974,7 @@ struct sbuiltin_s "{\n" " tc = v_texcoord;\n" " lm = v_lmcoord;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -981,8 +997,6 @@ struct sbuiltin_s {QR_OPENGL, 110, "defaultwall", "!!cvarf gl_overbright\n" "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview, m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "attribute vec2 v_lmcoord;\n" "varying vec2 tc, lm;\n" @@ -991,7 +1005,7 @@ struct sbuiltin_s "{\n" " tc = v_texcoord;\n" " lm = v_lmcoord;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1011,18 +1025,16 @@ struct sbuiltin_s "}\n" "#endif\n" }, +/*defaultwarp: draws a water surface*/ {QR_OPENGL/*ES*/, 100, "defaultwarp", "!!cvarf r_wateralpha\n" "varying mediump vec2 tc;\n" "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "void main (void)\n" "{\n" " tc = v_texcoord;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1046,14 +1058,11 @@ struct sbuiltin_s "!!cvarf r_wateralpha\n" "varying vec2 tc;\n" "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "void main (void)\n" "{\n" " tc = v_texcoord.st;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1073,17 +1082,15 @@ struct sbuiltin_s "}\n" "#endif\n" }, +/*defautsky projects the texture in order to match q1 skies, along with two separate layers scrolling at separate speeds*/ {QR_OPENGL/*ES*/, 100, "defaultsky", "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "varying vec3 pos;\n" "void main (void)\n" "{\n" " pos = v_position.xyz;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1117,15 +1124,12 @@ struct sbuiltin_s }, {QR_OPENGL, 110, "defaultsky", "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "varying vec3 pos;\n" "void main (void)\n" "{\n" " pos = v_position.xyz;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1156,14 +1160,12 @@ struct sbuiltin_s "}\n" "#endif\n" }, +/*draws a model. there's lots of extra stuff for light shading calcs and upper/lower textures*/ {QR_OPENGL/*ES*/, 100, "defaultskin", "!!permu FULLBRIGHT\n" "!!permu LOWER\n" "!!permu UPPER\n" "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "varying vec2 tc;\n" @@ -1177,7 +1179,7 @@ struct sbuiltin_s "{\n" " light = e_light_ambient + (dot(v_normal,e_light_dir)*e_light_mul);\n" " tc = v_texcoord;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1224,9 +1226,6 @@ struct sbuiltin_s "!!permu LOWER\n" "!!permu UPPER\n" "#ifdef VERTEX_SHADER\n" - "uniform mat4 m_modelview;\n" - "uniform mat4 m_projection;\n" - "attribute vec3 v_position;\n" "attribute vec2 v_texcoord;\n" "varying vec2 tc;\n" @@ -1240,7 +1239,7 @@ struct sbuiltin_s "{\n" " light = e_light_ambient + (dot(v_normal,e_light_dir)*e_light_mul);\n" " tc = v_texcoord;\n" - " gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n" + " gl_Position = ftetransform();\n" "}\n" "#endif\n" @@ -1336,6 +1335,26 @@ struct sbuiltin_s {QR_NONE} }; static sgeneric_t *sgenerics; +void Shader_UnloadGeneric(program_t *prog) +{ + int p; + if (prog->refs == 1) + { +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL) + { + for (p = 0; p < PERMUTATIONS; p++) + { + if (prog->handle[p].glsl) + qglDeleteProgramObject_(prog->handle[p].glsl); + } + } +#endif + free(prog); + } + else + prog->refs--; +} static void Shader_FlushGenerics(void) { sgeneric_t *g; @@ -1380,7 +1399,7 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype) FS_LoadFile(name, &file); if (file) { - Shader_LoadPermutations(&g->prog, file, qrtype, 0); + Shader_LoadPermutations(name, &g->prog, file, qrtype, 0); FS_FreeFile(file); g->prog.refs++; @@ -1404,7 +1423,7 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype) continue; } #endif - Shader_LoadPermutations(&g->prog, sbuiltins[i].body, sbuiltins[i].qrtype, sbuiltins[i].apiver); + Shader_LoadPermutations(name, &g->prog, sbuiltins[i].body, sbuiltins[i].qrtype, sbuiltins[i].apiver); g->prog.refs++; return &g->prog; @@ -1577,7 +1596,7 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p shader->prog = malloc(sizeof(*shader->prog)); memset(shader->prog, 0, sizeof(*shader->prog)); shader->prog->refs = 1; - Shader_LoadPermutations(shader->prog, programbody, qrtype, 0); + Shader_LoadPermutations(shader->name, shader->prog, programbody, qrtype, 0); BZ_Free(programbody); } @@ -2525,23 +2544,10 @@ void Shader_Free (shader_t *shader) Hash_RemoveData(&shader_active_hash, shader->name, shader); shader->bucket.data = NULL; -#ifdef GLQUAKE - if (qrenderer == QR_OPENGL && shader->prog) - { - program_t *prog = shader->prog; - int p; - if (--prog->refs == 0) - { - for (p = 0; p < PERMUTATIONS; p++) - { - if (prog->handle[p].glsl) - qglDeleteProgramObject_(prog->handle[p].glsl); - } - free(prog); - } - shader->prog = NULL; - } -#endif + if (shader->prog) + Shader_UnloadGeneric(shader->prog); + shader->prog = NULL; + if (shader->skydome) { Z_Free (shader->skydome); @@ -2570,23 +2576,20 @@ int Shader_InitCallback (const char *name, int size, void *param) qboolean Shader_Init (void) { - int i; shaderbuflen = 0; - r_shaders = calloc(MAX_SHADERS, sizeof(shader_t)); - - shader_hash = calloc (HASH_SIZE, sizeof(*shader_hash)); - - shader_active_hash_mem = malloc(Hash_BytesForBuckets(1024)); - memset(shader_active_hash_mem, 0, Hash_BytesForBuckets(1024)); - Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem); - - for (i = 0; i < MAX_SHADERS; i++) + if (!r_shaders) { - if (r_shaders[i].uses) - Shader_Free(&r_shaders[i]); + r_shaders = calloc(MAX_SHADERS, sizeof(shader_t)); + + shader_hash = calloc (HASH_SIZE, sizeof(*shader_hash)); + + shader_active_hash_mem = malloc(Hash_BytesForBuckets(1024)); + memset(shader_active_hash_mem, 0, Hash_BytesForBuckets(1024)); + Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem); + + Shader_FlushGenerics(); } - Shader_FlushGenerics(); shader_rescan_needed = true; Shader_NeedReload(); Shader_DoReload(); @@ -2680,7 +2683,7 @@ char *Shader_Skip ( char *ptr ) return ptr; } -static void Shader_GetPathAndOffset ( char *name, char **path, unsigned int *offset ) +static void Shader_GetPathAndOffset(char *name, char **path, unsigned int *offset) { unsigned int key; shadercache_t *cache; @@ -2731,21 +2734,21 @@ void Shader_Shutdown (void) return; /*nothing needs freeing yet*/ for (i = 0; i < MAX_SHADERS; i++, shader++) { - if ( !shader->uses ) + if (!shader->uses) continue; - Shader_Free ( shader ); + Shader_Free(shader); } - for ( i = 0; i < HASH_SIZE; i++ ) + for (i = 0; i < HASH_SIZE; i++) { cache = shader_hash[i]; - for ( ; cache; cache = cache_next ) + for (; cache; cache = cache_next) { cache_next = cache->hash_next; cache->hash_next = NULL; - Z_Free ( cache ); + Z_Free(cache); } } diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 41b97b876..3bc1990b9 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -2054,6 +2054,15 @@ void Sh_DrawLights(qbyte *vis) if (!r_shadow_realtime_world.ival && !r_shadow_realtime_dlight.ival) return; + /*no stencil?*/ + if (gl_config.nofixedfunc) + { + Con_Printf("FTE does not support stencil shadows without a fixed-function pipeline\n"); + r_shadow_realtime_world.ival = 0; + r_shadow_realtime_dlight.ival = 0; + return; + } + if (!gl_config.arb_shader_objects) { Con_Printf("Missing GL extensions: switching off realtime lighting.\n"); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index ae835db56..c1e9a3c9a 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -360,7 +360,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) /*in gl3.0 things are depricated but not removed*/ /*in gl3.1 depricated things are removed unless compatibility is present*/ /*in gl3.2 there's a profile flag we can query*/ - if (gl_config.glversion > 3.1) + if (gl_config.glversion >= 3.2) { GLint profile = 0; #define GL_CONTEXT_PROFILE_MASK 0x9126 @@ -671,13 +671,13 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) // glslang helper api function definitions // type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB -GLhandleARB GLSlang_CreateShader (char *versionline, char **precompilerconstants, char *shadersource, GLenum shadertype) +GLhandleARB GLSlang_CreateShader (char *name, char *versionline, char **precompilerconstants, char *shadersource, GLenum shadertype) { GLhandleARB shader; GLint compiled; char str[1024]; int loglen, i; - char *prstrings[4+16]; + char *prstrings[6+16]; int strings = 0; if (versionline) @@ -688,9 +688,33 @@ GLhandleARB GLSlang_CreateShader (char *versionline, char **precompilerconstants { case GL_FRAGMENT_SHADER_ARB: prstrings[strings++] = "#define FRAGMENT_SHADER\n"; + if (gl_config.gles) + { + prstrings[strings++] = "precision mediump float;\n"; + } break; case GL_VERTEX_SHADER_ARB: prstrings[strings++] = "#define VERTEX_SHADER\n"; + if (gl_config.gles) + { + prstrings[strings++] = "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" + "precision highp float;\n" + "#else\n" + "precision mediump float;\n" + "#endif\n"; + } + if (gl_config.nofixedfunc) + { + prstrings[strings++] = "#define ftetransform() (m_projection * m_modelview * vec4(v_position, 1.0))\n" + "uniform mat4 m_modelview, m_projection;\n" + "attribute vec3 v_position;\n"; + } + else + { + prstrings[strings++] = "#define ftetransform() ftransform()\n" + "#define v_position gl_Vertex\n"; + } + break; default: prstrings[strings++] = "#define UNKNOWN_SHADER\n"; @@ -722,6 +746,10 @@ GLhandleARB GLSlang_CreateShader (char *versionline, char **precompilerconstants Con_Printf("Shader_CreateShader: This shouldn't happen ever\n"); break; } + Con_Printf("Shader \"%s\" source:\n", name); + for (i = 0; i < strings; i++) + Con_Printf("%s", prstrings[i]); + Con_Printf("%s\n", str); return 0; } @@ -754,7 +782,7 @@ GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag) qglAttachObjectARB(program, vert); qglAttachObjectARB(program, frag); - qglBindAttribLocationARB(program, 0, "v_position"); + qglBindAttribLocationARB(program, gl_config.nofixedfunc?0:7, "v_position"); qglBindAttribLocationARB(program, 1, "v_colour"); qglBindAttribLocationARB(program, 2, "v_texcoord"); qglBindAttribLocationARB(program, 3, "v_lmcoord"); @@ -791,7 +819,7 @@ bucket_t *compiledshadersbuckets[64]; static hashtable_t compiledshaderstable; #endif -GLhandleARB GLSlang_CreateProgram(char *versionline, char **precompilerconstants, char *vert, char *frag) +GLhandleARB GLSlang_CreateProgram(char *name, char *versionline, char **precompilerconstants, char *vert, char *frag) { GLhandleARB handle; GLhandleARB vs; @@ -825,8 +853,8 @@ GLhandleARB GLSlang_CreateProgram(char *versionline, char **precompilerconstants } #endif - vs = GLSlang_CreateShader(versionline, precompilerconstants, vert, GL_VERTEX_SHADER_ARB); - fs = GLSlang_CreateShader(versionline, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB); + vs = GLSlang_CreateShader(name, versionline, precompilerconstants, vert, GL_VERTEX_SHADER_ARB); + fs = GLSlang_CreateShader(name, versionline, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB); if (!vs || !fs) handle = 0; diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index c696be3ca..71da91b9e 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -788,7 +788,7 @@ extern FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB; extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB; //glslang helper api -GLhandleARB GLSlang_CreateProgram(char *versionline, char **precompilerconstants, char *vert, char *frag); +GLhandleARB GLSlang_CreateProgram(char *name, char *versionline, char **precompilerconstants, char *vert, char *frag); GLint GLSlang_GetUniformLocation (int prog, char *name); void GL_SelectProgram(int program); #define GLSlang_UseProgram(prog) GL_SelectProgram(prog) diff --git a/engine/server/server.h b/engine/server/server.h index 9bb313ed3..39a8ae4ef 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -918,7 +918,7 @@ extern vfsfile_t *sv_fraglogfile; // NORETURN void VARGS SV_Error (char *error, ...) LIKEPRINTF(1); void SV_Shutdown (void); -void SV_Frame (void); +float SV_Frame (void); void SV_FinalMessage (char *message); void SV_DropClient (client_t *drop); struct quakeparms_s; diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index f14e5260c..d166b5e9f 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -3048,7 +3048,7 @@ SV_ReadPackets qboolean SV_GetPacket (void); #endif -qboolean SV_ReadPackets (void) +qboolean SV_ReadPackets (float *delay) { int i; client_t *cl; @@ -3060,36 +3060,46 @@ qboolean SV_ReadPackets (void) for (i = 0; i < MAX_CLIENTS; i++) //fixme: shouldn't we be using svs.allocated_client_slots ? { cl = &svs.clients[i]; - while (cl->laggedpacket && cl->laggedpacket->time < realtime) + while (cl->laggedpacket) { - lp = cl->laggedpacket; - cl->laggedpacket = lp->next; - if (cl->laggedpacket_last == lp) - cl->laggedpacket_last = lp->next; + //schedule a wakeup so minping is more consistant + if (cl->laggedpacket->time > realtime) + { + if (*delay > cl->laggedpacket->time - realtime) + *delay = cl->laggedpacket->time - realtime; + break; + } + else + { + lp = cl->laggedpacket; + cl->laggedpacket = lp->next; + if (cl->laggedpacket_last == lp) + cl->laggedpacket_last = lp->next; - lp->next = svs.free_lagged_packet; - svs.free_lagged_packet = lp; + lp->next = svs.free_lagged_packet; + svs.free_lagged_packet = lp; - SZ_Clear(&net_message); - memcpy(net_message.data, lp->data, lp->length); - net_message.cursize = lp->length; + SZ_Clear(&net_message); + memcpy(net_message.data, lp->data, lp->length); + net_message.cursize = lp->length; - net_from = cl->netchan.remote_address; //not sure if anything depends on this, but lets not screw them up willynilly + net_from = cl->netchan.remote_address; //not sure if anything depends on this, but lets not screw them up willynilly - if (Netchan_Process(&cl->netchan)) - { // this is a valid, sequenced packet, so process it - received++; - svs.stats.packets++; - if (cl->state > cs_zombie) - { //make sure they didn't already disconnect - cl->send_message = true; // reply at end of frame + if (Netchan_Process(&cl->netchan)) + { // this is a valid, sequenced packet, so process it + received++; + svs.stats.packets++; + if (cl->state > cs_zombie) + { //make sure they didn't already disconnect + cl->send_message = true; // reply at end of frame -#ifdef Q2SERVER - if (cl->protocol == SCP_QUAKE2) - SVQ2_ExecuteClientMessage(cl); - else -#endif - SV_ExecuteClientMessage (cl); + #ifdef Q2SERVER + if (cl->protocol == SCP_QUAKE2) + SVQ2_ExecuteClientMessage(cl); + else + #endif + SV_ExecuteClientMessage (cl); + } } } } @@ -3482,7 +3492,7 @@ SV_Frame ================== */ -void SV_Frame (void) +float SV_Frame (void) { extern cvar_t pr_imitatemvdsv; static double start, end, idletime; @@ -3490,6 +3500,7 @@ void SV_Frame (void) qboolean isidle; static int oldpaused; float timedelta; + float delay; start = Sys_DoubleTime (); svs.stats.idle += start - end; @@ -3500,6 +3511,8 @@ void SV_Frame (void) if (svs.framenum > 0x10000) svs.framenum = 0; + delay = sv_maxtic.value; + // keep the random time dependent rand (); @@ -3567,7 +3580,7 @@ void SV_MVDStream_Poll(void); SV_GetConsoleCommands (); Cbuf_Execute (); } - return; + return delay; } // check timeouts @@ -3579,13 +3592,13 @@ void SV_MVDStream_Poll(void); SV_CheckLog (); // get packets - isidle = !SV_ReadPackets (); + isidle = !SV_ReadPackets (&delay); if (pr_imitatemvdsv.ival) { Cbuf_Execute (); if (sv.state < ss_active) //whoops... - return; + return delay; } if (sv.multicast.cursize) @@ -3656,7 +3669,7 @@ void SV_MVDStream_Poll(void); } if (sv.state < ss_active) //whoops... - return; + return delay; SV_CheckVars (); @@ -3693,6 +3706,7 @@ void SV_MVDStream_Poll(void); svs.stats.packets = 0; svs.stats.count = 0; } + return delay; } /* diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index 69af4d197..df9db8d83 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -46,7 +46,6 @@ void Sys_Linebuffer_Callback (struct cvar_s *var, char *oldvalue); cvar_t sys_nostdout = CVAR("sys_nostdout","0"); cvar_t sys_extrasleep = CVAR("sys_extrasleep","0"); -cvar_t sys_maxtic = CVAR("sys_maxtic", "100"); cvar_t sys_colorconsole = CVAR("sys_colorconsole", "0"); cvar_t sys_linebuffer = CVARC("sys_linebuffer", "1", Sys_Linebuffer_Callback); @@ -629,7 +628,6 @@ void Sys_Init (void) { Cvar_Register (&sys_nostdout, "System configuration"); Cvar_Register (&sys_extrasleep, "System configuration"); - Cvar_Register (&sys_maxtic, "System configuration"); Cvar_Register (&sys_colorconsole, "System configuration"); Cvar_Register (&sys_linebuffer, "System configuration"); @@ -646,6 +644,7 @@ main */ int main(int argc, char *argv[]) { + int maxsleep; quakeparms_t parms; // fd_set fdset; // extern int net_socket; @@ -676,7 +675,7 @@ int main(int argc, char *argv[]) SV_Init (&parms); // run one frame immediately for first heartbeat - SV_Frame (); + maxsleep = SV_Frame()*1000; // // main loop @@ -684,14 +683,14 @@ int main(int argc, char *argv[]) while (1) { if (do_stdin) - stdin_ready = NET_Sleep(sys_maxtic.value, true); + stdin_ready = NET_Sleep(maxsleep, true); else { - NET_Sleep(sys_maxtic.value, false); + NET_Sleep(maxsleep, false); stdin_ready = false; } - SV_Frame (); + maxsleep = SV_Frame()*1000; // extrasleep is just a way to generate a fucked up connection on purpose if (sys_extrasleep.value) diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 1ccbab18e..a43e961d3 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -353,7 +353,6 @@ void CreateSampleService(qboolean create); void PR_Deinit(void); cvar_t sys_nostdout = {"sys_nostdout","0"}; -cvar_t sys_maxtic = {"sys_maxtic", "100"}; cvar_t sys_colorconsole = {"sys_colorconsole", "1"}; HWND consolewindowhandle; @@ -1073,7 +1072,6 @@ is marked void Sys_Init (void) { Cvar_Register (&sys_nostdout, "System controls"); - Cvar_Register (&sys_maxtic, "System controls"); Cvar_Register (&sys_colorconsole, "System controls"); Cmd_AddCommand("hide", Sys_HideConsole); @@ -1141,19 +1139,20 @@ int servicecontrol; void ServerMainLoop(void) { double newtime, time, oldtime; + int delay = 1; // // main loop // oldtime = Sys_DoubleTime () - 0.1; while (1) { - NET_Sleep(sys_maxtic.value, false); + NET_Sleep(delay, false); // find time passed since last cycle newtime = Sys_DoubleTime (); time = newtime - oldtime; oldtime = newtime; - SV_Frame (); + delay = SV_Frame()*1000; #ifdef USESERVICE