From ab1d780e3342dd25172484448bee83ae8ad727c8 Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 13 May 2013 13:43:18 +0000 Subject: [PATCH] various linux tweaks that make it run a little better in debian. Added the handy stack dump code for debug client builds too. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4357 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 8 +- engine/client/snd_directx.c | 3 + engine/client/sys_linux.c | 98 +++++++++++++++++- engine/gl/gl_backend.c | 6 ++ engine/gl/gl_vidcommon.c | 191 +++++++++++++++++++++++++++++++++++- engine/gl/gl_vidlinuxglx.c | 108 +++++++++----------- engine/server/sv_sys_unix.c | 170 +++++++++++--------------------- 7 files changed, 406 insertions(+), 178 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index 6dba3a5e5..7e9e43dbb 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -340,7 +340,7 @@ BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(CO CLIENT_ONLY_CFLAGS=-DCLIENTONLY SERVER_ONLY_CFLAGS=-DSERVERONLY JOINT_CFLAGS= -DEBUG_CFLAGS=-ggdb -g +DEBUG_CFLAGS=-ggdb -g -DDEBUG RELEASE_CFLAGS?=-O3 -ffast-math $(CPUOPTIMIZATIONS) #incase our compiler doesn't support it (mingw) @@ -972,7 +972,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),) GL_EXE_NAME=../fteqw.gl$(BITS) GLCL_EXE_NAME=../fteqwcl.gl$(BITS) GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) -lz - GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DLIBVORBISFILE_STATIC + GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DLIBVORBISFILE_STATIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG GLB_DIR=gl_linux$(BITS) GLCL_DIR=glcl_linux$(BITS) @@ -980,10 +980,12 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),) M_EXE_NAME=../fteqw$(BITS) MCL_EXE_NAME=../fteqwcl$(BITS) M_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) -lz - M_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DLIBVORBISFILE_STATIC + M_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DLIBVORBISFILE_STATIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG MB_DIR=m_linux$(BITS) MCL_DIR=mcl_linux$(BITS) + IMAGELDFLAGS= + MINGL_EXE_NAME=../fteqw.mingl$(BITS) diff --git a/engine/client/snd_directx.c b/engine/client/snd_directx.c index 6d384d068..1a6104a1b 100644 --- a/engine/client/snd_directx.c +++ b/engine/client/snd_directx.c @@ -954,6 +954,9 @@ static int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) if (COM_CheckParm("-wavonly")) return SND_NOMORE; + if (cardnum > 5) + return SND_NOMORE; + #ifdef MULTITHREAD if (snd_mixerthread.ival) { diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index 6d4923b24..03b340038 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //well, linux or cygwin (windows with posix emulation layer), anyway... - +#define _GNU_SOURCE #include #include #include @@ -539,6 +539,89 @@ void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname) return dlsym(module, exportname); } +// ======================================================================= +//friendly way to crash, including stack traces. should help reduce gdb use. +#ifdef __linux__ /*should probably be GNUC but whatever*/ +#include +#ifdef __i386__ +#include +#endif +#ifdef DEBUG +void DumpGLState(void); +#endif +static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext) +{ + int fd; + void *array[64]; + size_t size; + int firstframe = 0; + char signame[32]; + + switch(sig) + { + case SIGILL: strcpy(signame, "SIGILL"); break; + case SIGFPE: strcpy(signame, "SIGFPE"); break; + case SIGBUS: strcpy(signame, "SIGBUS"); break; + case SIGSEGV: Q_snprintfz(signame, sizeof(signame), "SIGSEGV (%p)", info->si_addr); break; + default: Q_snprintfz(signame, sizeof(signame), "%i", sig); break; + } + + // get void*'s for all entries on the stack + size = backtrace(array, sizeof(array)/sizeof(array[0])); + +#if defined(__i386__) + //x86 signals don't leave the stack in a clean state, so replace the signal handler with the real crash address, and hide this function + ucontext_t *uc = vcontext; + array[1] = (void*)uc->uc_mcontext.gregs[REG_EIP]; + firstframe = 1; +#elif defined(__amd64__) + //amd64 is sane enough, but this function and the libc signal handler are on the stack, and should be ignored. + firstframe = 2; +#endif + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %s:\n", signame); + backtrace_symbols_fd(array+firstframe, size-firstframe, 2); + + fd = open("crash.log", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP); + if (fd != -1) + { + time_t rawtime; + struct tm * timeinfo; + char buffer [80]; + + time (&rawtime); + timeinfo = localtime (&rawtime); + strftime (buffer, sizeof(buffer), "Time: %Y-%m-%d %H:%M:%S\n",timeinfo); + write(fd, buffer, strlen(buffer)); + + Q_snprintfz(buffer, sizeof(buffer), "Binary: "__DATE__" "__TIME__"\n"); + write(fd, buffer, strlen(buffer)); + Q_snprintfz(buffer, sizeof(buffer), "Ver: %i.%02i%s\n", FTE_VER_MAJOR, FTE_VER_MINOR, +#ifdef OFFICIAL_RELEASE + " (official)"); +#else + ""); +#endif + write(fd, buffer, strlen(buffer)); +#ifdef SVNREVISION + if (strcmp(STRINGIFY(SVNREVISION), "-")) + { + Q_snprintfz(buffer, sizeof(buffer), "Revision: %s\n", STRINGIFY(SVNREVISION)); + write(fd, buffer, strlen(buffer)); + } +#endif + + backtrace_symbols_fd(array + firstframe, size - firstframe, fd); + write(fd, "\n", 1); + close(fd); + } +#ifdef DEBUG + DumpGLState(); +#endif + exit(1); +} +#endif // ======================================================================= // Sleeps for microseconds // ======================================================================= @@ -601,6 +684,19 @@ int main (int c, const char **v) COM_InitArgv(parms.argc, parms.argv); TL_InitLanguages(); +#ifdef __linux__ + if (!COM_CheckParm("-nodumpstack")) + { + struct sigaction act; + memset(&act, 0, sizeof(act)); + act.sa_sigaction = Friendly_Crash_Handler; + act.sa_flags = SA_SIGINFO | SA_RESTART; + sigaction(SIGILL, &act, NULL); + sigaction(SIGSEGV, &act, NULL); + sigaction(SIGBUS, &act, NULL); + } +#endif + parms.memsize = 64*1024*1024; j = COM_CheckParm("-mem"); diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 0f6e526e0..2473b195d 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1327,6 +1327,9 @@ void GLBE_Init(void) //only do this where we have to. if (qglBufferDataARB && gl_config.nofixedfunc) { + memset(&shaderstate.streamvbo, 0, sizeof(shaderstate.streamvbo)); + memset(&shaderstate.streamebo, 0, sizeof(shaderstate.streamebo)); + memset(&shaderstate.streamvao, 0, sizeof(shaderstate.streamvao)); qglGenBuffersARB(sizeof(shaderstate.streamvbo)/sizeof(shaderstate.streamvbo[0]), shaderstate.streamvbo); qglGenBuffersARB(sizeof(shaderstate.streamebo)/sizeof(shaderstate.streamebo[0]), shaderstate.streamebo); if (qglGenVertexArrays) @@ -1568,6 +1571,7 @@ static void GenerateTCMods(const shaderpass_t *pass, int passnum) GL_DeselectVAO(); if (!shaderstate.vbo_texcoords[passnum]) { + shaderstate.vbo_texcoords[passnum] = 0; qglGenBuffersARB(1, &shaderstate.vbo_texcoords[passnum]); } GL_SelectVBO(shaderstate.vbo_texcoords[passnum]); @@ -4610,6 +4614,8 @@ void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize) ctx->fallback = NULL; if (qglBufferDataARB) { + ctx->vboid[0] = 0; + ctx->vboid[1] = 0; qglGenBuffersARB(2, ctx->vboid); GL_SelectVBO(ctx->vboid[0]); //WARNING: in emscripten/webgl, we should probably not pass null. diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 8daa55c08..97121a9ec 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -55,6 +55,7 @@ FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray; FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray; void (APIENTRY *qglStencilOpSeparateATI) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); void (APIENTRY *qglGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +void (APIENTRY *qglGetVertexAttribPointerv) (GLuint index, GLenum pname, GLvoid* *pointer); //quick hack that made quake work on both 1+ext and 1.1 gl implementations. BINDTEXFUNCPTR qglBindTexture; @@ -109,6 +110,7 @@ void (APIENTRY *qglEnd) (void); void (APIENTRY *qglEndList) (void); void (APIENTRY *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLuint (APIENTRY *qglGenLists) (GLsizei range); +GLboolean (APIENTRY *qglIsEnabled) (GLenum cap); void (APIENTRY *qglLoadIdentity) (void); void (APIENTRY *qglLoadMatrixf) (const GLfloat *m); void (APIENTRY *qglNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz); @@ -138,6 +140,7 @@ void (APIENTRY *qglVertex2f) (GLfloat x, GLfloat y); void (APIENTRY *qglVertex3f) (GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *qglVertex3fv) (const GLfloat *v); void (APIENTRY *qglGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params); +void (APIENTRY *qglGetTexEnviv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *qglDrawRangeElements) (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); void (APIENTRY *qglArrayElement) (GLint i); @@ -167,6 +170,7 @@ void (APIENTRY *qglGenVertexArrays)(GLsizei n, GLuint *arrays); void (APIENTRY *qglBindVertexArray)(GLuint vaoarray); const GLubyte * (APIENTRY * qglGetStringi) (GLenum name, GLuint index); +void (APIENTRY * qglGetPointerv) (GLenum pname, GLvoid **parms); void (APIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint* ids); void (APIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint id); @@ -752,6 +756,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglGetAttribLocationARB = NULL; qglVertexAttribPointer = NULL; qglGetVertexAttribiv = NULL; + qglGetVertexAttribPointerv = NULL; qglEnableVertexAttribArray = NULL; qglDisableVertexAttribArray = NULL; qglGetUniformLocationARB = NULL; @@ -811,6 +816,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglUniform1fARB = (void *)getglext("glUniform1f"); qglVertexAttribPointer = (void *)getglext("glVertexAttribPointer"); qglGetVertexAttribiv = (void *)getglext("glGetVertexAttribiv"); + qglGetVertexAttribPointerv = (void *)getglext("glGetVertexAttribPointerv"); qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArray"); qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArray"); Con_DPrintf("GLSL available\n"); @@ -837,6 +843,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglGetAttribLocationARB = (void *)getglext("glGetAttribLocationARB"); qglVertexAttribPointer = (void *)getglext("glVertexAttribPointerARB"); qglGetVertexAttribiv = (void *)getglext("glGetVertexAttribivARB"); + qglGetVertexAttribPointerv = (void *)getglext("glGetVertexAttribPointervARB"); qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArrayARB"); qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArrayARB"); qglGetUniformLocationARB = (void *)getglext("glGetUniformLocationARB"); @@ -854,8 +861,11 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) Con_DPrintf("GLSL available\n"); } #endif - //we only use vao with shaders anyway. - if (!gl_config.arb_shader_objects) + //we only use vao if we don't have a choice. + //certain drivers (*cough* mesa *cough*) update vao0 state even when a different vao is bound. + //they also don't support client arrays, so are unusable without glsl or vertex streaming (which is *really* hard to optimise for - especially with webgl etc) + //so only use them with gl3+ core contexts where vbo is mandatory anyway. + if (!gl_config.nofixedfunc) { //don't bother if we've no glsl qglGenVertexArrays = NULL; @@ -1584,6 +1594,10 @@ void GL_Init(void *(*getglfunction) (char *name)) qglFogfv = (void *)getglcore("glFogfv"); + qglGetTexEnviv = (void *)getglext("glGetTexEnviv"); + qglGetPointerv = (void *)getglext("glGetPointerv"); + qglIsEnabled = (void *)getglext("glIsEnabled"); + qglGetStringi = (void *)getglext("glGetStringi"); //used by heightmaps @@ -1655,6 +1669,179 @@ void GL_Init(void *(*getglfunction) (char *name)) } +#ifdef DEBUG +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_CURRENT_PROGRAM 0x8B8D + +char *DecodeGLEnum(GLenum num) +{ + switch(num) + { + case GL_CW: return "GL_CW"; + case GL_CCW: return "GL_CCW"; + case GL_NEVER: return "GL_NEVER"; + case GL_LESS: return "GL_LESS"; + case GL_EQUAL: return "GL_EQUAL"; + case GL_LEQUAL: return "GL_LEQUAL"; + case GL_GREATER: return "GL_GREATER"; + case GL_NOTEQUAL: return "GL_NOTEQUAL"; + case GL_GEQUAL: return "GL_GEQUAL"; + case GL_ALWAYS: return "GL_ALWAYS"; + case GL_FRONT: return "GL_FRONT"; + case GL_BACK: return "GL_BACK"; + case GL_FRONT_AND_BACK: return "GL_FRONT_AND_BACK"; + case GL_COMBINE_ARB: return "GL_COMBINE"; + case GL_MODULATE: return "GL_MODULATE"; + case GL_REPLACE: return "GL_REPLACE"; + case GL_ZERO: return "GL_ZERO"; + case GL_ONE: return "GL_ONE"; + case GL_SRC_COLOR: return "GL_SRC_COLOR"; + case GL_ONE_MINUS_SRC_COLOR: return "GL_ONE_MINUS_SRC_COLOR"; + case GL_SRC_ALPHA: return "GL_SRC_ALPHA"; + case GL_ONE_MINUS_SRC_ALPHA: return "GL_ONE_MINUS_SRC_ALPHA"; + case GL_DST_ALPHA: return "GL_DST_ALPHA"; + case GL_ONE_MINUS_DST_ALPHA: return "GL_ONE_MINUS_DST_ALPHA"; + case GL_DST_COLOR: return "GL_DST_COLOR"; + case GL_ONE_MINUS_DST_COLOR: return "GL_ONE_MINUS_DST_COLOR"; + case GL_SRC_ALPHA_SATURATE: return "GL_SRC_ALPHA_SATURATE"; + default: return va("0x%x", num); + } +} +void DumpGLState(void) +{ + int rval; + void *ptr; + int i; + GLint glint; + GLint glint4[4]; + + if (qglGetVertexAttribiv) + { + qglGetIntegerv(GL_VERTEX_ARRAY_BINDING, &rval); + Sys_Printf("VERTEX_ARRAY_BINDING: %i\n", rval); + qglGetIntegerv(GL_ARRAY_BUFFER_BINDING, &rval); + Sys_Printf("GL_ARRAY_BUFFER_BINDING: %i\n", rval); + if (qglIsEnabled(GL_COLOR_ARRAY)) + { + qglGetIntegerv(GL_COLOR_ARRAY_BUFFER_BINDING, &rval); + qglGetPointerv(GL_COLOR_ARRAY_POINTER, &ptr); + Sys_Printf("GL_COLOR_ARRAY: %s %i:%p\n", qglIsEnabled(GL_COLOR_ARRAY)?"en":"dis", rval, ptr); + } +// if (qglIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT)) +// { +// qglGetPointerv(GL_FOG_COORD_ARRAY_POINTER, &ptr); +// Sys_Printf("GL_FOG_COORDINATE_ARRAY_EXT: %i (%lx)\n", (int) qglIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT), (int) ptr); +// } +// if (qglIsEnabled(GL_INDEX_ARRAY)) + { + qglGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &rval); + qglGetPointerv(GL_INDEX_ARRAY_POINTER, &ptr); + Sys_Printf("GL_INDEX_ARRAY: %s %i:%p\n", qglIsEnabled(GL_INDEX_ARRAY)?"en":"dis", rval, ptr); + } + if (qglIsEnabled(GL_NORMAL_ARRAY)) + { + qglGetIntegerv(GL_NORMAL_ARRAY_BUFFER_BINDING, &rval); + qglGetPointerv(GL_NORMAL_ARRAY_POINTER, &ptr); + Sys_Printf("GL_NORMAL_ARRAY: %s %i:%p\n", qglIsEnabled(GL_NORMAL_ARRAY)?"en":"dis", rval, ptr); + } + // qglGetPointerv(GL_SECONDARY_COLOR_ARRAY_POINTER, &ptr); + // Sys_Printf("GL_SECONDARY_COLOR_ARRAY: %i (%lx)\n", (int) qglIsEnabled(GL_SECONDARY_COLOR_ARRAY), (int) ptr); + for (i = 0; i < 4; i++) + { + qglClientActiveTextureARB(mtexid0 + i); + if (qglIsEnabled(GL_TEXTURE_COORD_ARRAY)) + { + qglGetIntegerv(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &rval); + qglGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &ptr); + Sys_Printf("GL_TEXTURE_COORD_ARRAY %i: %s %i:%p\n", i, qglIsEnabled(GL_TEXTURE_COORD_ARRAY)?"en":"dis", rval, ptr); + } + } + if (qglIsEnabled(GL_VERTEX_ARRAY)) + { + qglGetIntegerv(GL_VERTEX_ARRAY_BUFFER_BINDING, &rval); + qglGetPointerv(GL_VERTEX_ARRAY_POINTER, &ptr); + Sys_Printf("GL_VERTEX_ARRAY: %s %i:%p\n", qglIsEnabled(GL_VERTEX_ARRAY)?"en":"dis", rval, ptr); + } + + for (i = 0; i < 16; i++) + { + int en, bo, as, st, ty, no; + + qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &en); + if (!en) + continue; + qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &bo); + qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &as); + qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &st); + qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &ty); + qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &no); + qglGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr); + + Sys_Printf("attrib%i: %s as:%i st:%i ty:%0x %s%i:%p\n", i, en?"en":"dis", as, st,ty,no?"norm ":"", bo, ptr); + } + + qglGetIntegerv(GL_CURRENT_PROGRAM, &glint); + Sys_Printf("GL_CURRENT_PROGRAM: %i\n", glint); + + qglGetIntegerv(GL_BLEND, &glint); + Sys_Printf("GL_BLEND: %i\n", glint); + qglGetIntegerv(GL_BLEND_SRC, &glint); + Sys_Printf("GL_BLEND_SRC: %i\n", DecodeGLEnum(glint)); + qglGetIntegerv(GL_BLEND_DST, &glint); + Sys_Printf("GL_BLEND_DST: %i\n", DecodeGLEnum(glint)); + + qglGetIntegerv(GL_DEPTH_WRITEMASK, &glint); + Sys_Printf("GL_DEPTH_WRITEMASK: %i\n", glint); + qglGetIntegerv(GL_DEPTH_TEST, &glint); + Sys_Printf("GL_DEPTH_TEST: %i\n", glint); + qglGetIntegerv(GL_DEPTH_FUNC, &glint); + Sys_Printf("GL_DEPTH_FUNC: %s\n", DecodeGLEnum(glint)); + qglGetIntegerv(GL_CULL_FACE, &glint); + Sys_Printf("GL_CULL_FACE: %i\n", glint); + qglGetIntegerv(GL_CULL_FACE_MODE, &glint); + Sys_Printf("GL_CULL_FACE_MODE: %s\n", DecodeGLEnum(glint)); + qglGetIntegerv(GL_FRONT_FACE, &glint); + Sys_Printf("GL_FRONT_FACE: %s\n", DecodeGLEnum(glint)); + qglGetIntegerv(GL_SCISSOR_TEST, &glint); + Sys_Printf("GL_SCISSOR_TEST: %i\n", glint); + qglGetIntegerv(GL_STENCIL_TEST, &glint); + Sys_Printf("GL_STENCIL_TEST: %i\n", glint); + qglGetIntegerv(GL_COLOR_WRITEMASK, glint4); + Sys_Printf("GL_COLOR_WRITEMASK: %i %i %i %i\n", glint4[0], glint4[1], glint4[2], glint4[3]); + + GL_SelectTexture(0); + qglGetIntegerv(GL_TEXTURE_2D, &glint); + Sys_Printf("GL_TEXTURE_2D: %i\n", glint); + qglGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint); + Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); + GL_SelectTexture(1); + qglGetIntegerv(GL_TEXTURE_2D, &glint); + Sys_Printf("GL_TEXTURE_2D: %i\n", glint); + qglGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint); + Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); + GL_SelectTexture(2); + qglGetIntegerv(GL_TEXTURE_2D, &glint); + Sys_Printf("GL_TEXTURE_2D: %i\n", glint); + qglGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint); + Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); + } +} +#endif diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index f55ab0147..7b9a7d09a 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -203,7 +203,9 @@ static qboolean x11_initlib(void) if (!x11.lib) { - x11.lib = Sys_LoadLibrary("libX11", x11_functable); + x11.lib = Sys_LoadLibrary("libX11.so.6", x11_functable); + if (!x11.lib) + x11.lib = Sys_LoadLibrary("libX11", x11_functable); //these ones are extensions, and the reason we're doing this. if (x11.lib) @@ -211,6 +213,10 @@ static qboolean x11_initlib(void) x11.pXGetEventData = Sys_GetAddressForName(x11.lib, "XGetEventData"); x11.pXFreeEventData = Sys_GetAddressForName(x11.lib, "XFreeEventData"); } + else + { + Con_Printf("Unable to load libX11\n"); + } } @@ -419,7 +425,9 @@ static qboolean XI2_Init(void) if (!xi2.libxi) { - xi2.libxi = Sys_LoadLibrary("libXi", xi2_functable); + xi2.libxi = Sys_LoadLibrary("libXi.so.6", xi2_functable); + if (!xi2.libxi) + xi2.libxi = Sys_LoadLibrary("libXi", xi2_functable); if (!xi2.libxi) Con_Printf("XInput library not available or too old.\n"); } @@ -531,9 +539,16 @@ static int XLateKey(XKeyEvent *ev, unsigned int *unicode) key = 0; keysym = x11.pXLookupKeysym(ev, 0); - x11.pXLookupString(ev, buf, sizeof buf, &shifted, 0); if (unicode) - *unicode = buf[0]; + { + if ((keysym & 0xff000000) == 0x01000000) + *unicode = keysym & 0x00ffffff; + else + { + x11.pXLookupString(ev, buf, sizeof buf, &shifted, 0); + *unicode = (unsigned char)buf[0]; + } + } switch(keysym) { @@ -645,8 +660,12 @@ static int XLateKey(XKeyEvent *ev, unsigned int *unicode) #endif default: - key = *(unsigned char*)buf; - if (key >= 'A' && key <= 'Z') + key = keysym; + if (key < 32) + key = 0; + else if (key > 127) + key = 0; + else if (key >= 'A' && key <= 'Z') key = key - 'A' + 'a'; break; } @@ -1086,12 +1105,6 @@ void GLVID_DeInit(void) //FIXME:.... } -void signal_handler(int sig) -{ - printf("Received signal %d, exiting...\n", sig); - Sys_Quit(); - exit(0); -} void signal_handler_graceful(int sig) { gracefulexit = true; @@ -1100,18 +1113,7 @@ void signal_handler_graceful(int sig) void InitSig(void) { - signal(SIGHUP, signal_handler); signal(SIGINT, signal_handler_graceful); - signal(SIGQUIT, signal_handler); - signal(SIGILL, signal_handler); - signal(SIGTRAP, signal_handler); -#ifndef __CYGWIN__ - signal(SIGIOT, signal_handler); -#endif - signal(SIGBUS, signal_handler); - signal(SIGFPE, signal_handler); - signal(SIGSEGV, signal_handler); - signal(SIGTERM, signal_handler); } static Cursor CreateNullCursor(Display *display, Window root) @@ -1136,53 +1138,38 @@ static Cursor CreateNullCursor(Display *display, Window root) return cursor; } -void GLVID_ShiftPalette (unsigned char *palette) +qboolean GLVID_ApplyGammaRamps(unsigned short *ramps) { extern qboolean gammaworks; extern cvar_t vid_hardwaregamma; - extern unsigned short ramps[3][256]; -// VID_SetPalette (palette); + //if we don't know the original ramps yet, don't allow changing them, because we're probably invalid anyway, and even if it worked, it'll break something later. + if (!vm.originalapplied) + return false; - if (vm.originalapplied && ActiveApp && vid_hardwaregamma.value) //this is needed because ATI drivers don't work properly (or when task-switched out). + if (ramps) { + //hardwaregamma==1 skips hardware gamma when we're not fullscreen, in favour of software glsl based gamma. +// if (vid_hardwaregamma.value == 1 && !ActiveApp && !(fullscreenflags & FULLSCREEN_ACTIVE)) +// return false; +// if (!ActiveApp) +// return false; +// if (!vid_hardwaregamma.value) +// return false; + + //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma if it randomly fails (yuck) if (gammaworks) - { //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck) - vm.pXF86VidModeSetGammaRamp (vid_dpy, scrnum, 256, ramps[0], ramps[1], ramps[2]); - return; - } - gammaworks = !!vm.pXF86VidModeSetGammaRamp (vid_dpy, scrnum, 256, ramps[0], ramps[1], ramps[2]); + vm.pXF86VidModeSetGammaRamp (vid_dpy, scrnum, 256, &ramps[0], &ramps[256], &ramps[512]); + else + gammaworks = !!vm.pXF86VidModeSetGammaRamp (vid_dpy, scrnum, 256, &ramps[0], &ramps[256], &ramps[512]); + + return gammaworks; } else - gammaworks = false; -} - -void GLVID_SetPalette (unsigned char *palette) -{ - qbyte *pal; - unsigned r,g,b; - unsigned short i; - unsigned *table; - extern qbyte gammatable[256]; - -// -// 8 8 8 encoding -// - Con_DPrintf("Converting 8to24\n"); - - pal = palette; - table = d_8to24rgbtable; - for (i=0 ; i<256 ; i++) { - r = gammatable[pal[0]]; - g = gammatable[pal[1]]; - b = gammatable[pal[2]]; - pal += 3; - - *table++ = BigLong((r<<24)|(g<<16)|(b<<8)|255); + vm.pXF86VidModeSetGammaRamp(vid_dpy, scrnum, 256, vm.originalramps[0], vm.originalramps[1], vm.originalramps[2]); + return true; } - - d_8to24rgbtable[255] &= BigLong(0xffffff00); // 255 is transparent } /* @@ -1649,9 +1636,6 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl) break; } - GLVID_SetPalette(palette); - GLVID_ShiftPalette(palette); - InitSig(); // trap evil signals //probably going to be resized in the event handler diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index 05f696168..70b9923e7 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -51,7 +51,7 @@ 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_colorconsole = CVAR("sys_colorconsole", "0"); +cvar_t sys_colorconsole = CVAR("sys_colorconsole", "1"); cvar_t sys_linebuffer = CVARC("sys_linebuffer", "1", Sys_Linebuffer_Callback); qboolean stdin_ready; @@ -300,6 +300,7 @@ void Sys_Printf (char *fmt, ...) vsnprintf (msg,sizeof(msg)-1, fmt,argptr); va_end (argptr); + //if we're not linebuffered, kill the currently displayed input line, add the new text, and add more output. if (!sys_linebuffer.value) { int i; @@ -316,127 +317,75 @@ void Sys_Printf (char *fmt, ...) } - for (t = (unsigned char*)msg; *t; t++) + if (sys_colorconsole.value) { - if (*t >= 146 && *t < 156) - *t = *t - 146 + '0'; - if (*t >= 0x12 && *t <= 0x1b) - *t = *t - 0x12 + '0'; - if (*t == 143) - *t = '.'; - if (*t == 157 || *t == 158 || *t == 159) - *t = '-'; - if (*t >= 128) - *t -= 128; - if (*t == 16) - *t = '['; - if (*t == 17) - *t = ']'; - if (*t == 0x1c) - *t = 249; - } - - if (sys_colorconsole.value) - { - int ext = CON_WHITEMASK; - int extstack[4]; - int extstackdepth = 0; - unsigned char *str = (unsigned char*)msg; - - - while(*str) + wchar_t w; + conchar_t *e, *c; + conchar_t ctext[MAXPRINTMSG]; + e = COM_ParseFunString(CON_WHITEMASK, msg, ctext, sizeof(ctext), false); + for (c = ctext; c < e; c++) { - if (*str == '^') + if (*c & CON_HIDDEN) + continue; + + ApplyColour(*c); + w = *c & 0x0ffff; + if (w >= 0xe000 && w < 0xe100) { - str++; - if (*str >= '0' && *str <= '9') + /*not all quake chars are ascii compatible, so map those control chars to safe ones so we don't mess up anyone's xterm*/ + if ((w & 0x7f) > 0x20) + putc(w&0x7f, stdout); + else if (w & 0x80) { - ext = q3codemasks[*str++-'0'] | (ext&~CON_Q3MASK); //change colour only. - continue; - } - else if (*str == '&') // extended code - { - if (isextendedcode(str[1]) && isextendedcode(str[2])) - { - str++; // foreground char - if (*str == '-') // default for FG - ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~CON_FGMASK); - else if (*str >= 'A') - ext = ((*str - ('A' - 10)) << CON_FGSHIFT) | (ext&~CON_FGMASK); - else - ext = ((*str - '0') << CON_FGSHIFT) | (ext&~CON_FGMASK); - str++; // background char - if (*str == '-') // default (clear) for BG - ext &= ~CON_BGMASK & ~CON_NONCLEARBG; - else if (*str >= 'A') - ext = ((*str - ('A' - 10)) << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG; - else - ext = ((*str - '0') << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG; - str++; - continue; - } - Sys_PrintColouredChar('^' | ext); - // else invalid code - } - else if (*str == 'a') - { - str++; - ext ^= CON_2NDCHARSETTEXT; - continue; - } - else if (*str == 'b') - { - str++; - ext ^= CON_BLINKTEXT; - continue; - } - else if (*str == 'h') - { - str++; - ext ^= CON_HALFALPHA; - continue; - } - else if (*str == 's') //store on stack (it's great for names) - { - str++; - if (extstackdepth < sizeof(extstack)/sizeof(extstack[0])) - { - extstack[extstackdepth] = ext; - extstackdepth++; - } - continue; - } - else if (*str == 'r') //restore from stack (it's great for names) - { - str++; - if (extstackdepth) - { - extstackdepth--; - ext = extstack[extstackdepth]; - } - continue; - } - else if (*str == '^') - { - Sys_PrintColouredChar('^' | ext); - str++; + static char tab[32] = "---#@.@@@@ # >.." "[]0123456789.---"; + putc(tab[w&31], stdout); } else { - Sys_PrintColouredChar('^' | ext); - Sys_PrintColouredChar ((*str++) | ext); + static char tab[32] = ".####.#### # >.." "[]0123456789.---"; + putc(tab[w&31], stdout); } - continue; } - Sys_PrintColouredChar ((*str++) | ext); + else + { + /*putwc doesn't like me. force it in utf8*/ + if (w >= 0x80) + { + if (w > 0x800) + { + putc(0xe0 | ((w>>12)&0x0f), stdout); + putc(0x80 | ((w>>6)&0x3f), stdout); + } + else + putc(0xc0 | ((w>>6)&0x1f), stdout); + putc(0x80 | (w&0x3f), stdout); + } + else + putc(w, stdout); + } } - - ApplyColour(CON_WHITEMASK); } else { - for (t = msg; *t; t++) + for (t = (unsigned char*)msg; *t; t++) { + if (*t >= 146 && *t < 156) + *t = *t - 146 + '0'; + if (*t >= 0x12 && *t <= 0x1b) + *t = *t - 0x12 + '0'; + if (*t == 143) + *t = '.'; + if (*t == 157 || *t == 158 || *t == 159) + *t = '-'; + if (*t >= 128) + *t -= 128; + if (*t == 16) + *t = '['; + if (*t == 17) + *t = ']'; + if (*t == 0x1c) + *t = 249; + *t &= 0x7f; if ((*t > 128 || *t < 32) && *t != 10 && *t != 13 && *t != 9) printf("[%02x]", *t); @@ -445,6 +394,7 @@ void Sys_Printf (char *fmt, ...) } } + //and put the input line back if (!sys_linebuffer.value) { if (coninput_len) @@ -484,8 +434,8 @@ void Sys_Printf (char *fmt, ...) if (strlen(text) > sizeof(text)) Sys_Error("memory overwrite in Sys_Printf"); - if (sys_nostdout.value) - return; + if (sys_nostdout.value) + return; for (p = (unsigned char *)text; *p; p++) { *p &= 0x7f;