From 4fb854e261e7f025a8f63aac0656881aa852c5dd Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 29 Jan 2011 19:53:38 +0000 Subject: [PATCH] Fix a couple of things I noticed while playing in linux. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3727 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 2 +- engine/client/cl_cg.c | 4 +- engine/client/cl_demo.c | 2 +- engine/client/cl_input.c | 4 +- engine/client/cl_main.c | 2 +- engine/client/cl_ui.c | 4 +- engine/client/clq2_cin.c | 2 +- engine/client/clq3_parse.c | 4 +- engine/client/keys.c | 2 +- engine/client/merged.h | 14 +- engine/client/p_classic.c | 4 +- engine/client/renderer.c | 2 +- engine/client/snd_alsa.c | 153 +++++++++++++++------ engine/client/snd_dma.c | 74 ++++++++--- engine/client/snd_linux.c | 266 ++++++++++++++++++++++++++++++------- engine/client/sound.h | 5 +- engine/client/sys_linux.c | 120 ++++++++++++++++- engine/common/bothdefs.h | 2 +- engine/common/q1bsp.c | 4 +- engine/gl/gl_rmisc.c | 6 +- engine/gl/gl_shader.c | 2 +- engine/gl/gl_vidcommon.c | 26 ++-- engine/gl/gl_vidlinuxglx.c | 31 ++++- engine/gl/shader.h | 12 -- engine/qclib/initlib.c | 7 +- engine/server/pr_cmds.c | 12 +- engine/server/svq3_game.c | 4 +- 27 files changed, 593 insertions(+), 177 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index 8facc6c40..7e3d4b7d3 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -852,7 +852,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),) SV_LDFLAGS=-lz SV_EXE_NAME=../fteqw.sv$(BITS) - GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_alsa.o cd_linux.o sys_linux.o + GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_alsa.o snd_linux.o cd_linux.o sys_linux.o ifeq ($(USEASM),true) GLCL_OBJS+= sys_dosa.o endif diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index dfc29cf5a..a24075558 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -451,7 +451,7 @@ void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname); -#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to cgame trap %i passes invalid pointer\n", fn); //out of bounds. +#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to cgame trap %u passes invalid pointer\n", (unsigned int)fn); //out of bounds. static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg) { @@ -1038,7 +1038,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con pe->DelinkTrailstate(VM_POINTER(arg[0])); break; default: - Con_Printf("Q3CG: Bad system trap: %d\n", fn); + Con_Printf("Q3CG: Bad system trap: %i\n", (int)fn); } return ret; diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index e2953284c..4486e2b67 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -2012,7 +2012,7 @@ void CL_QTVPlay_f (void) { connrequest = "QTV_EZQUAKE_EXT: 3\n"; VFS_WRITE(newf, connrequest, strlen(connrequest)); - connrequest = va("USERINFO: %s\n", cls.userinfo); + connrequest = va("USERINFO: %s\n", cls.userinfo[0]); VFS_WRITE(newf, connrequest, strlen(connrequest)); } else if (raw) diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 99188b461..8004fa1b5 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -688,7 +688,7 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum) void CL_DrawPrydonCursor(void) { - if (cursor_active && cl_prydoncursor.ival) + if (cursor_active && cl_prydoncursor.ival > 0) { SCR_DrawCursor(cl_prydoncursor.ival); V_StopPitchDrift (0); @@ -1362,7 +1362,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) cl.frames[curframe].receivedtime = -1; // we haven't gotten a reply yet - if ((cls.fteprotocolextensions2 & PEXT2_PRYDONCURSOR) && *cl_prydoncursor.string && cls.state == ca_active) + if ((cls.fteprotocolextensions2 & PEXT2_PRYDONCURSOR) && (*cl_prydoncursor.string && cl_prydoncursor.ival >= 0) && cls.state == ca_active) { vec3_t cursor_start, cursor_impact; int cursor_entitynumber = 0; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 420cb6daa..ad27a2185 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -541,7 +541,7 @@ void CL_SendConnectPacket ( //userinfo 0 + zquake extension info. if (cls.protocol == CP_QUAKEWORLD) - Q_strncatz(data, va(" \"%s\\*z_ext\\%i\"", cls.userinfo, SUPPORTED_Z_EXTENSIONS), sizeof(data)); + Q_strncatz(data, va(" \"%s\\*z_ext\\%i\"", cls.userinfo[0], SUPPORTED_Z_EXTENSIONS), sizeof(data)); else Q_strncatz(data, va(" \"%s\"", cls.userinfo[0]), sizeof(data)); for (c = 1; c < clients; c++) diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index c8fcfea92..b59355849 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -677,7 +677,7 @@ void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font) -#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to ui trap %i passes invalid pointer\n", fn); //out of bounds. +#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to ui trap %i passes invalid pointer\n", (int)fn); //out of bounds. static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg) { @@ -1310,7 +1310,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; default: - Con_Printf("Q3UI: Not implemented system trap: %d\n", fn); + Con_Printf("Q3UI: Not implemented system trap: %i\n", (int)fn); return 0; } diff --git a/engine/client/clq2_cin.c b/engine/client/clq2_cin.c index e85c03be2..075abe708 100644 --- a/engine/client/clq2_cin.c +++ b/engine/client/clq2_cin.c @@ -273,7 +273,7 @@ static cblock_t Huff1Decompress (cinematics_t *cin, cblock_t in) if (input - in.data != in.count && input - in.data != in.count+1) { - Con_Printf ("Decompression overread by %i", (input - in.data) - in.count); + Con_Printf ("Decompression overread by %i\n", (int)(input - in.data) - in.count); } out.count = out_p - out.data; diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index 2e5e8afa0..88366d964 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -876,7 +876,7 @@ void CLQ3_SendCmd(usercmd_t *cmd) if (cls.resendinfo) { cls.resendinfo = false; - CLQ3_SendClientCommand("userinfo \"%s\"", cls.userinfo); + CLQ3_SendClientCommand("userinfo \"%s\"", cls.userinfo[0]); } ccs.serverTime = ccs.snap.serverTime + (Sys_Milliseconds()-ccs.snap.localTime); @@ -1024,7 +1024,7 @@ void CLQ3_SendConnectPacket(netadr_t to) msg.overflowed = msg.allowoverflow = 0; msg.maxsize = sizeof(data); MSG_WriteLong(&msg, -1); - MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", cls.challenge, cls.qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), net_local_cl_ipadr), cls.userinfo)); + MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", cls.challenge, cls.qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), net_local_cl_ipadr), cls.userinfo[0])); Huff_EncryptPacket(&msg, 12); Huff_PreferedCompressionCRC(); NET_SendPacket (NS_CLIENT, msg.cursize, msg.data, to); diff --git a/engine/client/keys.c b/engine/client/keys.c index 447f2d29d..12f9688e1 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -1643,7 +1643,7 @@ void Key_Event (int pnum, int key, unsigned int unicode, qboolean down) } else { - sprintf (cmd, "p%i %s\n", pnum+1, kb, key+oldstate*256); + sprintf (cmd, "p%i %s\n", pnum+1, kb); Cbuf_AddText (cmd, bindcmdlevel[key][keystate]); } } diff --git a/engine/client/merged.h b/engine/client/merged.h index a6fa1c4df..d4e1e6f93 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -161,7 +161,17 @@ typedef union { #endif } texid_t; typedef enum uploadfmt uploadfmt_t; -typedef enum backendmode_e backendmode_t; +//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented) +typedef enum backendmode_e +{ + BEM_STANDARD, //regular mode to draw surfaces akin to q3 (aka: legacy mode). lightmaps+delux+ambient + BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps). + BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer. + BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal. + BEM_LIGHT, //we have a valid light + BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap + BEM_SMAPLIGHT //we have a light using a shadowmap +} backendmode_t; typedef struct rendererinfo_s { char *description; @@ -282,4 +292,4 @@ typedef struct rendererinfo_s { #define BE_DrawMesh_List rf->BE_DrawMesh_List #define BE_DrawMesh_Single rf->BE_DrawMesh_Single #define BE_SubimtMeshes rf->BE_SubimtMeshes -#define BE_DrawWorld rf->BE_DrawWorld \ No newline at end of file +#define BE_DrawWorld rf->BE_DrawWorld diff --git a/engine/client/p_classic.c b/engine/client/p_classic.c index b3af30a0c..f7b316f9c 100644 --- a/engine/client/p_classic.c +++ b/engine/client/p_classic.c @@ -372,7 +372,7 @@ static void PClassic_DrawParticles(void) p->color = ramp1[(int) p->ramp]; for (i = 0; i < 3; i++) p->vel[i] += p->vel[i] * dvel; - p->vel[2] -= grav * 30; + p->vel[2] -= grav*10; break; case pt_explode2: p->ramp += time3; @@ -382,7 +382,7 @@ static void PClassic_DrawParticles(void) p->color = ramp2[(int) p->ramp]; for (i = 0; i < 3; i++) p->vel[i] -= p->vel[i] * frametime; - p->vel[2] -= grav * 30; + p->vel[2] -= grav*10; break; case pt_blob: for (i = 0; i < 3; i++) diff --git a/engine/client/renderer.c b/engine/client/renderer.c index d7b41872e..3351e762e 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1666,6 +1666,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n")); #ifdef PLUGINS Plug_ResChanged(); #endif + Cvar_ForceCallback(&r_particlesystem); TRACE(("dbg: R_ApplyRenderer: starting on client state\n")); if (cl.worldmodel) @@ -1769,7 +1770,6 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); } else { - Cvar_ForceCallback(&r_particlesystem); #ifdef VM_UI UI_Reset(); #endif diff --git a/engine/client/snd_alsa.c b/engine/client/snd_alsa.c index 8b5f5d44b..d6a36c2bd 100755 --- a/engine/client/snd_alsa.c +++ b/engine/client/snd_alsa.c @@ -54,17 +54,20 @@ int (*psnd_pcm_sw_params) (snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int (*psnd_pcm_hw_params_get_buffer_size) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); int (*psnd_pcm_hw_params_set_buffer_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); snd_pcm_sframes_t (*psnd_pcm_avail_update) (snd_pcm_t *pcm); -int (*psnd_pcm_mmap_begin) (snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); -snd_pcm_sframes_t (*psnd_pcm_mmap_commit) (snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t frames); snd_pcm_state_t (*psnd_pcm_state) (snd_pcm_t *pcm); int (*psnd_pcm_start) (snd_pcm_t *pcm); size_t (*psnd_pcm_hw_params_sizeof) (void); size_t (*psnd_pcm_sw_params_sizeof) (void); +int (*psnd_pcm_mmap_begin) (snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); +snd_pcm_sframes_t (*psnd_pcm_mmap_commit) (snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t frames); + +snd_pcm_sframes_t (*psnd_pcm_writei) (snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); +int (*psnd_pcm_prepare) (snd_pcm_t *pcm); -static unsigned int ALSA_GetDMAPos (soundcardinfo_t *sc) +static unsigned int ALSA_MMap_GetDMAPos (soundcardinfo_t *sc) { const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset; @@ -79,16 +82,10 @@ static unsigned int ALSA_GetDMAPos (soundcardinfo_t *sc) return sc->sn.samplepos; } -static void ALSA_Shutdown (soundcardinfo_t *sc) +static void ALSA_MMap_Submit (soundcardinfo_t *sc, int start, int end) { - psnd_pcm_close (sc->handle); -} - -static void ALSA_Submit (soundcardinfo_t *sc) -{ - extern int soundtime; int state; - int count = sc->paintedtime - soundtime; + int count = end - start; const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t nframes; snd_pcm_uframes_t offset; @@ -112,6 +109,63 @@ static void ALSA_Submit (soundcardinfo_t *sc) break; } } +static unsigned int ALSA_RW_GetDMAPos (soundcardinfo_t *sc) +{ + int frames; + frames = psnd_pcm_avail_update(sc->handle); + if (frames >= 0) + { + sc->sn.samplepos = (sc->snd_sent + frames) * sc->sn.numchannels; + } + return sc->sn.samplepos; +} +static void ALSA_RW_Submit (soundcardinfo_t *sc, int start, int end) +{ + int state; + unsigned int frames, offset, ringsize; + unsigned chunk; + int result; + int stride = sc->sn.numchannels * (sc->sn.samplebits/8); + + /*we can't change the data that was already written*/ + frames = end - sc->snd_sent; + if (!frames) + return; + + state = psnd_pcm_state (sc->handle); + + ringsize = sc->sn.samples / sc->sn.numchannels; + + chunk = frames; + offset = sc->snd_sent % ringsize; + + if (offset + chunk >= ringsize) + chunk = ringsize - offset; + result = psnd_pcm_writei(sc->handle, sc->sn.buffer + offset*stride, chunk); + if (result < chunk) + { + if (result >= 0) + sc->snd_sent += result; + return; + } + sc->snd_sent += chunk; + + chunk = frames - chunk; + if (chunk) + { + result = psnd_pcm_writei(sc->handle, sc->sn.buffer, chunk); + if (result > 0) + sc->snd_sent += result; + } + + if (state == SND_PCM_STATE_PREPARED) + psnd_pcm_start (sc->handle); +} + +static void ALSA_Shutdown (soundcardinfo_t *sc) +{ + psnd_pcm_close (sc->handle); +} static void *ALSA_LockBuffer(soundcardinfo_t *sc) { @@ -162,14 +216,18 @@ static qboolean Alsa_InitAlsa(void) psnd_pcm_sw_params = dlsym(alsasharedobject, "snd_pcm_sw_params"); psnd_pcm_hw_params_get_buffer_size = dlsym(alsasharedobject, "snd_pcm_hw_params_get_buffer_size"); psnd_pcm_avail_update = dlsym(alsasharedobject, "snd_pcm_avail_update"); - psnd_pcm_mmap_begin = dlsym(alsasharedobject, "snd_pcm_mmap_begin"); psnd_pcm_state = dlsym(alsasharedobject, "snd_pcm_state"); - psnd_pcm_mmap_commit = dlsym(alsasharedobject, "snd_pcm_mmap_commit"); psnd_pcm_start = dlsym(alsasharedobject, "snd_pcm_start"); psnd_pcm_hw_params_sizeof = dlsym(alsasharedobject, "snd_pcm_hw_params_sizeof"); psnd_pcm_sw_params_sizeof = dlsym(alsasharedobject, "snd_pcm_sw_params_sizeof"); psnd_pcm_hw_params_set_buffer_size_near = dlsym(alsasharedobject, "snd_pcm_hw_params_set_buffer_size_near"); + psnd_pcm_mmap_begin = dlsym(alsasharedobject, "snd_pcm_mmap_begin"); + psnd_pcm_mmap_commit = dlsym(alsasharedobject, "snd_pcm_mmap_commit"); + + psnd_pcm_writei = dlsym(alsasharedobject, "snd_pcm_writei"); + psnd_pcm_prepare = dlsym(alsasharedobject, "snd_pcm_prepare"); + alsaworks = psnd_pcm_open && psnd_pcm_close && psnd_strerror @@ -186,13 +244,15 @@ static qboolean Alsa_InitAlsa(void) && psnd_pcm_sw_params && psnd_pcm_hw_params_get_buffer_size && psnd_pcm_avail_update - && psnd_pcm_mmap_begin && psnd_pcm_state - && psnd_pcm_mmap_commit && psnd_pcm_start && psnd_pcm_hw_params_sizeof && psnd_pcm_sw_params_sizeof - && psnd_pcm_hw_params_set_buffer_size_near; + && psnd_pcm_hw_params_set_buffer_size_near + && psnd_pcm_mmap_begin + && psnd_pcm_mmap_commit + && psnd_pcm_writei && psnd_pcm_prepare + ; return alsaworks; } @@ -212,6 +272,7 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum) snd_pcm_hw_params_t *hw; snd_pcm_sw_params_t *sw; snd_pcm_uframes_t frag_size; + qboolean mmap = false; if (!Alsa_InitAlsa()) { @@ -257,11 +318,10 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum) goto error; } - err = psnd_pcm_hw_params_set_access (pcm, hw, SND_PCM_ACCESS_MMAP_INTERLEAVED); + err = psnd_pcm_hw_params_set_access (pcm, hw, mmap?SND_PCM_ACCESS_MMAP_INTERLEAVED:SND_PCM_ACCESS_RW_INTERLEAVED); if (0 > err) { - Con_Printf (CON_ERROR "ALSA: Failure to set noninterleaved PCM access. %s\n" - "Note: Interleaved is not supported\n", + Con_Printf (CON_ERROR "ALSA: Failure to set interleaved PCM access. %s\n", psnd_strerror (err)); goto error; } @@ -396,32 +456,51 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum) goto error; } - sc->Lock = ALSA_LockBuffer; - sc->Unlock = ALSA_UnlockBuffer; - sc->SetWaterDistortion = ALSA_SetUnderWater; - sc->Submit = ALSA_Submit; - sc->Shutdown = ALSA_Shutdown; - sc->GetDMAPos = ALSA_GetDMAPos; - sc->sn.samples = buffer_size * sc->sn.numchannels; // mono samples in buffer sc->sn.speed = rate; sc->handle = pcm; - ALSA_GetDMAPos (sc); // sets shm->buffer - - //alsa doesn't seem to like high mixahead values - //(maybe it tells us above somehow...) - //so force it lower - //quake's default of 0.2 was for 10fps rendering anyway - //so force it down to 0.1 which is the default for halflife at least, and should give better latency + sc->Lock = ALSA_LockBuffer; + sc->Unlock = ALSA_UnlockBuffer; + sc->SetWaterDistortion = ALSA_SetUnderWater; + sc->Shutdown = ALSA_Shutdown; + if (mmap) { - extern cvar_t _snd_mixahead; - if (_snd_mixahead.value >= 0.2) + sc->GetDMAPos = ALSA_MMap_GetDMAPos; + sc->Submit = ALSA_MMap_Submit; + sc->GetDMAPos(sc); // sets shm->buffer + + //alsa doesn't seem to like high mixahead values + //(maybe it tells us above somehow...) + //so force it lower + //quake's default of 0.2 was for 10fps rendering anyway + //so force it down to 0.1 which is the default for halflife at least, and should give better latency { - Con_Printf("Alsa Hack: _snd_mixahead forced lower\n"); - _snd_mixahead.value = 0.1; + extern cvar_t _snd_mixahead; + if (_snd_mixahead.value >= 0.2) + { + Con_Printf("Alsa Hack: _snd_mixahead forced lower\n"); + _snd_mixahead.value = 0.1; + } } } + else + { + sc->GetDMAPos = ALSA_RW_GetDMAPos; + sc->Submit = ALSA_RW_Submit; + + sc->samplequeue = sc->sn.samples; + sc->sn.buffer = malloc(sc->sn.samples * (sc->sn.samplebits/8)); + + err = psnd_pcm_prepare(pcm); + if (0 > err) + { + Con_Printf (CON_ERROR "ALSA: unable to prepare for use. %s\n", + psnd_strerror (err)); + goto error; + } + } + return true; error: diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index cc600909b..587732c42 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -48,9 +48,6 @@ vec3_t listener_up = {0, 0, 1}; vec3_t listener_velocity; vec_t sound_nominal_clip_dist=1000.0; -int soundtime; // sample PAIRS - - #define MAX_SFX 512 sfx_t *known_sfx; // hunk allocated [MAX_SFX] int num_sfx; @@ -105,6 +102,8 @@ cvar_t snd_linearresample_stream = CVARAF( "s_linearresample_stream", "0", cvar_t snd_usemultipledevices = CVARAF( "s_multipledevices", "0", "snd_multipledevices", 0); +cvar_t snd_driver = CVARAF( "s_driver", "", + "snd_driver", 0); #ifdef VOICECHAT static void S_Voip_Play_Callback(cvar_t *var, char *oldval); @@ -243,6 +242,7 @@ static dllfunction_t qspeexdspfuncs[] = }; snd_capture_driver_t DSOUND_Capture; +snd_capture_driver_t OSS_Capture; static qboolean S_Speex_Init(void) { @@ -419,8 +419,10 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) return; /*Add new drivers in order of priority*/ - if (!s_speex.driver) + if (!s_speex.driver || !s_speex.driver->Init) s_speex.driver = &DSOUND_Capture; + if (!s_speex.driver || !s_speex.driver->Init) + s_speex.driver = &OSS_Capture; /*no way to capture audio, give up*/ if (!s_speex.driver) @@ -670,7 +672,16 @@ static int SNDDMA_Init(soundcardinfo_t *sc, int *cardnum, int *drivernum) else sc->sn.samples = 0; - sd = &drivers[*drivernum]; + if (*snd_driver.string) + { + if (*drivernum) + return 2; + for (sd = drivers; sd->name; sd++) + if (!Q_strcasecmp(sd->name, snd_driver.string)) + break; + } + else + sd = &drivers[*drivernum]; if (!sd->ptr) return 2; //no more cards. if (!*sd->ptr) //driver not loaded @@ -1011,6 +1022,7 @@ void S_Init (void) Cvar_Register(&snd_playersoundvolume, "Sound controls"); Cvar_Register(&snd_usemultipledevices, "Sound controls"); + Cvar_Register(&snd_driver, "Sound controls"); Cvar_Register(&snd_linearresample, "Sound controls"); Cvar_Register(&snd_linearresample_stream, "Sound controls"); @@ -1847,7 +1859,7 @@ void S_UpdateCard(soundcardinfo_t *sc) S_Update_(sc); } -void GetSoundtime(soundcardinfo_t *sc) +int GetSoundtime(soundcardinfo_t *sc) { int samplepos; int fullsamples; @@ -1858,6 +1870,12 @@ void GetSoundtime(soundcardinfo_t *sc) // calls to S_Update. Oh well. samplepos = sc->GetDMAPos(sc); + samplepos -= sc->samplequeue; + + if (samplepos < 0) + { + samplepos = 0; + } if (samplepos < sc->oldsamplepos) { sc->buffers++; // buffer wrapped @@ -1871,7 +1889,7 @@ void GetSoundtime(soundcardinfo_t *sc) } sc->oldsamplepos = samplepos; - soundtime = sc->buffers*fullsamples + samplepos/sc->sn.numchannels; + return sc->buffers*fullsamples + samplepos/sc->sn.numchannels; } void S_Update (void) @@ -1904,41 +1922,55 @@ void S_ExtraUpdate (void) void S_Update_(soundcardinfo_t *sc) { + int soundtime; /*in pairs*/ unsigned endtime; int samps; if (sc->selfpainting) return; - if ((snd_blocked > 0)) + if (snd_blocked > 0) { if (!sc->inactive_sound) return; } // Updates DMA time - GetSoundtime(sc); + soundtime = GetSoundtime(sc); -// check to make sure that we haven't overshot - if (sc->paintedtime < soundtime) + if (sc->samplequeue) { - //Con_Printf ("S_Update_ : overflow\n"); - sc->paintedtime = soundtime; + /*device uses a write-once queue*/ + endtime = soundtime + sc->samplequeue/sc->sn.numchannels; + soundtime = sc->paintedtime; + samps = sc->samplequeue / sc->sn.numchannels; + } + else + { + /*device uses memory-mapped output*/ + // check to make sure that we haven't overshot + if (sc->paintedtime < soundtime) + { + //Con_Printf ("S_Update_ : overflow\n"); + sc->paintedtime = soundtime; + } + + // mix ahead of current position + endtime = soundtime + (int)(_snd_mixahead.value * sc->sn.speed); + samps = sc->sn.samples / sc->sn.numchannels; + } + if (endtime - soundtime > samps) + { + endtime = soundtime + samps; } -// mix ahead of current position - endtime = soundtime + (int)(_snd_mixahead.value * sc->sn.speed); -// samps = shm->samples >> (shm->numchannels-1); - samps = sc->sn.samples / sc->sn.numchannels; - if (endtime - soundtime > samps) - endtime = soundtime + samps; - + /*DirectSound may have killed us to give priority to another app, ask to restore it*/ if (sc->Restore) sc->Restore(sc); S_PaintChannels (sc, endtime); - sc->Submit(sc); + sc->Submit(sc, soundtime, endtime); } /* diff --git a/engine/client/snd_linux.c b/engine/client/snd_linux.c index 3ff3b5e92..400144b11 100644 --- a/engine/client/snd_linux.c +++ b/engine/client/snd_linux.c @@ -10,44 +10,106 @@ #include #include "quakedef.h" +#ifdef __linux__ +#include +#endif + static int tryrates[] = { 11025, 22051, 44100, 8000, 48000 }; static void OSS_SetUnderWater(soundcardinfo_t *sc, qboolean underwater) //simply a stub. Any ideas how to actually implement this properly? { } -static unsigned int OSS_GetDMAPos(soundcardinfo_t *sc) +static unsigned int OSS_MMap_GetDMAPos(soundcardinfo_t *sc) { struct count_info count; - if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1) + if (sc->audio_fd != -1) { - perror("/dev/dsp"); - Con_Printf("Uh, sound dead.\n"); - close(sc->audio_fd); - return 0; + if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1) + { + perror("/dev/dsp"); + Con_Printf("Uh, sound dead.\n"); + close(sc->audio_fd); + sc->audio_fd = -1; + return 0; + } +// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); +// fprintf(stderr, "%d \r", count.ptr); + sc->sn.samplepos = count.ptr / (sc->sn.samplebits / 8); } -// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); -// fprintf(stderr, "%d \r", count.ptr); - sc->sn.samplepos = count.ptr / (sc->sn.samplebits / 8); - return sc->sn.samplepos; } +static void OSS_MMap_Submit(soundcardinfo_t *sc, int start, int end) +{ +} + +static unsigned int OSS_Alsa_GetDMAPos(soundcardinfo_t *sc) +{ + struct audio_buf_info info; + unsigned int bytes; + if (ioctl (sc->audio_fd, SNDCTL_DSP_GETOSPACE, &info) != -1) + { + bytes = sc->snd_sent + info.bytes; + sc->sn.samplepos = bytes / (sc->sn.samplebits / 8); + } + return sc->sn.samplepos; +} + + +static void OSS_Alsa_Submit(soundcardinfo_t *sc, int start, int end) +{ + unsigned int bytes, offset, ringsize; + unsigned chunk; + int result; + + /*we can't change the data that was already written*/ + bytes = end * sc->sn.numchannels * (sc->sn.samplebits/8); + bytes -= sc->snd_sent; + if (!bytes) + return; + + ringsize = sc->sn.samples * (sc->sn.samplebits/8); + + chunk = bytes; + offset = sc->snd_sent % ringsize; + + if (offset + chunk >= ringsize) + chunk = ringsize - offset; + result = write(sc->audio_fd, sc->sn.buffer + offset, chunk); + if (result < chunk) + { + if (result >= 0) + sc->snd_sent += result; + printf("full?\n"); + return; + } + sc->snd_sent += chunk; + + chunk = bytes - chunk; + if (chunk) + { + result = write(sc->audio_fd, sc->sn.buffer, chunk); + if (result > 0) + sc->snd_sent += result; + } +} static void OSS_Shutdown(soundcardinfo_t *sc) { if (sc->sn.buffer) //close it properly, so we can go and restart it later. - munmap(sc->sn.buffer, sc->sn.samples * (sc->sn.samplebits/8)); - if (sc->audio_fd) + { + if (sc->Submit == OSS_Alsa_Submit) + free(sc->sn.buffer); /*if using alsa-compat, just free the buffer*/ + else + munmap(sc->sn.buffer, sc->sn.samples * (sc->sn.samplebits/8)); + } + if (sc->audio_fd != -1) close(sc->audio_fd); *sc->name = '\0'; } -static void OSS_Submit(soundcardinfo_t *sc) -{ -} - static void *OSS_Lock(soundcardinfo_t *sc) { return sc->sn.buffer; @@ -67,6 +129,13 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) int caps; char *snddev = NULL; cvar_t *devname; + qboolean alsadetected = false; + +#ifdef __linux__ + struct stat sb; + if (stat("/proc/asound", &sb) != -1) + alsadetected = true; +#endif devname = Cvar_Get(va("snd_devicename%i", cardnum+1), cardnum?"":"/dev/dsp", 0, "Sound controls"); snddev = devname->string; @@ -80,7 +149,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) Con_Printf("Initing OSS sound device %s\n", snddev); - sc->audio_fd = open(snddev, O_RDWR | O_NONBLOCK); //try the primary device + sc->audio_fd = open(snddev, O_WRONLY | O_NONBLOCK); //try the primary device if (sc->audio_fd < 0) { perror(snddev); @@ -89,7 +158,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) return 0; } Q_strncpyz(sc->name, snddev, sizeof(sc->name)); - + //reset it rc = ioctl(sc->audio_fd, SNDCTL_DSP_RESET, 0); if (rc < 0) @@ -108,12 +177,6 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) OSS_Shutdown(sc); return 0; } - if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) - { - Con_Printf(CON_ERROR "OSS: Sorry but your soundcard can't do this\n"); - OSS_Shutdown(sc); - return 0; - } //choose channels #ifdef SNDCTL_DSP_CHANNELS /*I'm paranoid, okay?*/ @@ -221,33 +284,60 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) /*samples is the number of samples*channels */ // memory map the dma buffer - sc->sn.buffer = (unsigned char *) mmap(NULL, sc->sn.samples*(sc->sn.samplebits/8), PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0); - if (!sc->sn.buffer) + sc->sn.buffer = MAP_FAILED; + if (alsadetected) { - perror(snddev); - Con_Printf(CON_ERROR "OSS: Could not mmap %s\n", snddev); - OSS_Shutdown(sc); - return 0; + Con_Printf("Alsa detected. Refusing to mmap.\n"); } + else if ((caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP)) + { + sc->sn.buffer = (unsigned char *) mmap(NULL, sc->sn.samples*(sc->sn.samplebits/8), PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0); + if (sc->sn.buffer == MAP_FAILED) + { + Con_Printf("%s: device reported mmap capability, but mmap failed.\n", snddev); + if (alsadetected) + { + char *f, *n; + f = com_argv[0]; + while((n = strchr(f, '/'))) + f = n + 1; + Con_Printf("Your system is running alsa.\nTry: sudo echo \"%s 0 0 direct\" > /proc/asound/card0/pcm0p/oss\n", f); + } + } + } + if (sc->sn.buffer == MAP_FAILED) + { + sc->sn.buffer = NULL; -// toggle the trigger & start her up - tmp = 0; - rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); - if (rc < 0) - { - perror(snddev); - Con_Printf(CON_ERROR "OSS: Could not toggle.\n"); - OSS_Shutdown(sc); - return 0; + sc->samplequeue = info.bytes / (sc->sn.samplebits/8); + sc->sn.samples*=2; + sc->sn.buffer = malloc(sc->sn.samples*(sc->sn.samplebits/8)); + sc->Submit = OSS_Alsa_Submit; + sc->GetDMAPos = OSS_Alsa_GetDMAPos; } - tmp = PCM_ENABLE_OUTPUT; - rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); - if (rc < 0) + else { - perror(snddev); - Con_Printf(CON_ERROR "OSS: Could not toggle.\n"); - OSS_Shutdown(sc); - return 0; + // toggle the trigger & start her up + tmp = 0; + rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); + if (rc < 0) + { + perror(snddev); + Con_Printf(CON_ERROR "OSS: Could not toggle.\n"); + OSS_Shutdown(sc); + return 0; + } + tmp = PCM_ENABLE_OUTPUT; + rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); + if (rc < 0) + { + perror(snddev); + Con_Printf(CON_ERROR "OSS: Could not toggle.\n"); + OSS_Shutdown(sc); + return 0; + } + sc->Submit = OSS_MMap_Submit; + sc->GetDMAPos = OSS_MMap_GetDMAPos; } sc->sn.samplepos = 0; @@ -255,12 +345,92 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) sc->Lock = OSS_Lock; sc->Unlock = OSS_Unlock; sc->SetWaterDistortion = OSS_SetUnderWater; - sc->Submit = OSS_Submit; sc->Shutdown = OSS_Shutdown; - sc->GetDMAPos = OSS_GetDMAPos; return 1; } int (*pOSS_InitCard) (soundcardinfo_t *sc, int cardnum) = &OSS_InitCard; + + +#if 0//I'm unable to test due to alsa def VOICECHAT +#include +void *OSS_Capture_Init(int rate) +{ + int tmp; + intptr_t fd; + char *snddev = "/dev/dsp"; + fd = open(snddev, O_RDONLY | O_NONBLOCK); //try the primary device + if (fd == -1) + return NULL; + +#ifdef SNDCTL_DSP_CHANNELS + tmp = 1; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &tmp) != 0) +#else + tmp = 0; + if (ioctl(fd, SNDCTL_DSP_STEREO, &tmp) != 0) +#endif + { + Con_Printf("Couldn't set mono\n"); + perror(snddev); + } + + tmp = AFMT_S16_LE; + if (ioctl(fd, SNDCTL_DSP_SETFMT, &tmp) != 0) + { + Con_Printf("Couldn't set sample bits\n"); + perror(snddev); + } + + tmp = rate; + if (ioctl(fd, SNDCTL_DSP_SPEED, &tmp) != 0) + { + Con_Printf("Couldn't set capture rate\n"); + perror(snddev); + } + + fd++; + return (void*)fd; +} +void OSS_Capture_Start(void *ctx) +{ + /*oss will automagically restart it when we next read*/ +} + +void OSS_Capture_Stop(void *ctx) +{ + intptr_t fd = ((intptr_t)ctx)-1; + + ioctl(fd, SNDCTL_DSP_RESET, NULL); +} + +void OSS_Capture_Shutdown(void *ctx) +{ + intptr_t fd = ((intptr_t)ctx)-1; + + close(fd); +} + +unsigned int OSS_Capture_Update(void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) +{ + intptr_t fd = ((intptr_t)ctx)-1; + ssize_t res; + + res = read(fd, buffer, maxbytes); + if (res < 0) + return 0; + return res; +} + +snd_capture_driver_t OSS_Capture = +{ + OSS_Capture_Init, + OSS_Capture_Start, + OSS_Capture_Update, + OSS_Capture_Stop, + OSS_Capture_Shutdown +}; +#endif + diff --git a/engine/client/sound.h b/engine/client/sound.h index 5b368b5cd..48d815351 100644 --- a/engine/client/sound.h +++ b/engine/client/sound.h @@ -277,14 +277,15 @@ struct soundcardinfo_s { //windows has one defined AFTER directsound qboolean inactive_sound; //continue mixing for this card even when the window isn't active. qboolean selfpainting; //allow the sound code to call the right functions when it feels the need (not properly supported). - int paintedtime; //used in the mixer + int paintedtime; //used in the mixer as last-written pos (in sample pairs) int oldsamplepos; //this is used to track buffer wraps int buffers; //used to keep track of how many buffer wraps for consistant sound + int samplequeue; //this is the number of samples the device can enqueue. if set, DMAPos returns the write point (rather than hardware read point) (in samplepairs). //callbacks void *(*Lock) (soundcardinfo_t *sc); void (*Unlock) (soundcardinfo_t *sc, void *buffer); - void (*Submit) (soundcardinfo_t *sc); + void (*Submit) (soundcardinfo_t *sc, int start, int end); void (*Shutdown) (soundcardinfo_t *sc); unsigned int (*GetDMAPos) (soundcardinfo_t *sc); void (*SetWaterDistortion) (soundcardinfo_t *sc, qboolean underwater); diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index 9b74204f7..4aa2d021d 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -78,6 +78,119 @@ qboolean isDedicated; // General routines // ======================================================================= +#if 1 +static int ansiremap[8] = {0, 4, 2, 6, 1, 5, 3, 7}; +static void ApplyColour(unsigned int chr) +{ + static int oldchar = CON_WHITEMASK; + int bg, fg; + chr &= CON_FLAGSMASK; + + if (oldchar == chr) + return; + oldchar = chr; + + printf("\e[0;"); // reset + + if (chr & CON_BLINKTEXT) + printf("5;"); // set blink + + bg = (chr & CON_BGMASK) >> CON_BGSHIFT; + fg = (chr & CON_FGMASK) >> CON_FGSHIFT; + + // don't handle intensive bit for background + // as terminals differ too much in displaying \e[1;7;3?m + bg &= 0x7; + + if (chr & CON_NONCLEARBG) + { + if (fg & 0x8) // intensive bit set for foreground + { + printf("1;"); // set bold/intensity ansi flag + fg &= 0x7; // strip intensive bit + } + + // set foreground and background colors + printf("3%i;4%im", ansiremap[fg], ansiremap[bg]); + } + else + { + switch(fg) + { + //to get around wierd defaults (like a white background) we have these special hacks for colours 0 and 7 + case COLOR_BLACK: + printf("7m"); // set inverse + break; + case COLOR_GREY: + printf("1;30m"); // treat as dark grey + break; + case COLOR_WHITE: + printf("m"); // set nothing else + break; + default: + if (fg & 0x8) // intensive bit set for foreground + { + printf("1;"); // set bold/intensity ansi flag + fg &= 0x7; // strip intensive bit + } + + printf("3%im", ansiremap[fg]); // set foreground + break; + } + } +} + +#include +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + char text[2048]; + conchar_t ctext[2048]; + conchar_t *c, *e; + wchar_t w; + + if (nostdout) + return; + + va_start (argptr,fmt); + _vsnprintf (text,sizeof(text)-1, fmt,argptr); + va_end (argptr); + + if (strlen(text) > sizeof(text)) + Sys_Error("memory overwrite in Sys_Printf"); + + e = COM_ParseFunString(CON_WHITEMASK, text, ctext, sizeof(ctext), false); + + for (c = ctext; c < e; c++) + { + ApplyColour(*c); + w = *c & 0x0ffff; + if (w >= 0xe000 && w < 0xe100) + { + putc(w&0x7f, stdout); + } + 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 void Sys_Printf (char *fmt, ...) { va_list argptr; @@ -100,6 +213,7 @@ void Sys_Printf (char *fmt, ...) else putc(*p, stdout); } +#endif void Sys_Quit (void) { @@ -405,7 +519,11 @@ dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) int i; dllhandle_t lib; - lib = dlopen (name, RTLD_LAZY); + lib = NULL; + if (!lib) + lib = dlopen (name, RTLD_LAZY); + if (!lib) + lib = dlopen (va("%s.so", name), RTLD_LAZY); if (!lib) return NULL; diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index d5c2a7930..6167b443e 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -80,9 +80,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //#define DYNAMIC_LIBPNG //#define DYNAMIC_LIBJPEG +#define AVAIL_FREETYPE #ifdef _WIN32 //needs testing on other platforms -#define AVAIL_FREETYPE #define AVAIL_OPENAL #endif diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 1cfe50fd7..2f91d7a9a 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -1174,6 +1174,7 @@ unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned return fatbytes; } +#endif qboolean Q1BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs) { int i; @@ -1242,7 +1243,6 @@ void Q1BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, f Q1BSP_RFindTouchedLeafs (mod, ent, mod->nodes, mins, maxs); } -#endif /* Server only functions @@ -1384,9 +1384,9 @@ void Q1BSP_SetModelFuncs(model_t *mod) { #ifndef CLIENTONLY mod->funcs.FatPVS = Q1BSP_FatPVS; +#endif mod->funcs.EdictInFatPVS = Q1BSP_EdictInFatPVS; mod->funcs.FindTouchedLeafs = Q1BSP_FindTouchedLeafs; -#endif mod->funcs.LightPointValues = NULL; mod->funcs.StainNode = NULL; mod->funcs.MarkLights = NULL; diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index 3637ad776..1b87ad53f 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -901,9 +901,9 @@ static void R_SaveRTLights_f(void) (light->flags & LFLAG_NOSHADOWS)?"!":"", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style-1, - "", 0, - 0, 0, 0, - 0, 0, 0, light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE) + "", 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE) )); } VFS_CLOSE(f); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 99701453b..d8e20ab4f 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -3126,7 +3126,7 @@ void Shader_DefaultCinematic(char *shortname, shader_t *s, const void *args) "videomap %s\n" "}\n" "}\n" - , args) + , (const char*)args) ); } diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 9b1370d18..6132f32d6 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -412,7 +412,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) { qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_config.ext_texture_filter_anisotropic); - Con_SafePrintf("Anisotropic filter extension found (%dx max).\n",gl_config.ext_texture_filter_anisotropic); + Con_DPrintf("Anisotropic filter extension found (%dx max).\n",gl_config.ext_texture_filter_anisotropic); } if (GL_CheckExtension("GL_ARB_texture_non_power_of_two")) @@ -455,7 +455,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) } else { - Con_SafePrintf("ARB Multitexture extensions found. Use -noamtex to disable.\n"); + Con_DPrintf("ARB Multitexture extensions found. Use -noamtex to disable.\n"); } } @@ -535,17 +535,6 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) qglUnmapBufferARB = (void *)getglext("glUnmapBufferARB"); } -/* - if (GL_CheckExtension("GL_ARB_fragment_program")) - { - gl_config.arb_fragment_program = true; - qglProgramStringARB = (void *)getglext("glProgramStringARB"); - qglGetProgramivARB = (void *)getglext("glGetProgramivARB"); - qglBindProgramARB = (void *)getglext("glBindProgramARB"); - qglGenProgramsARB = (void *)getglext("glGenProgramsARB"); - } -*/ - // glslang //the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects. //but our code kinda requires both for clean workings. @@ -580,9 +569,12 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) qglUniform3fvARB = (void *)getglext("glUniform3fvARB"); qglUniform1iARB = (void *)getglext("glUniform1iARB"); qglUniform1fARB = (void *)getglext("glUniform1fARB"); + + Con_DPrintf("GLSL available\n"); } else if (gl_config.gles && gl_config.glversion >= 2) { + /*core names are different from extension names (more functions too)*/ gl_config.arb_shader_objects = true; qglCreateProgramObjectARB = (void *)getglext( "glCreateProgram"); qglDeleteProgramObject_ = (void *)getglext( "glDeleteProgram"); @@ -610,6 +602,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) qglUniform3fvARB = (void *)getglext("glUniform3fv"); qglUniform1iARB = (void *)getglext("glUniform1i"); qglUniform1fARB = (void *)getglext("glUniform1f"); + Con_DPrintf("GLSL available\n"); } if (GL_CheckExtension("GL_EXT_framebuffer_object")) @@ -650,7 +643,7 @@ GLhandleARB GLSlang_CreateShader (char **precompilerconstants, char *shadersourc GLhandleARB shader; GLint compiled; char str[1024]; - int loglen; + int loglen, i; char *prstrings[3+16]; int strings = 0; @@ -679,7 +672,6 @@ GLhandleARB GLSlang_CreateShader (char **precompilerconstants, char *shadersourc qglGetShaderParameteriv_(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); if(!compiled) { - Con_DPrintf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]); qglGetShaderInfoLog_(shader, sizeof(str), NULL, str); qglDeleteShaderObject_(shader); switch (shadertype) @@ -705,7 +697,9 @@ GLhandleARB GLSlang_CreateShader (char **precompilerconstants, char *shadersourc qglGetShaderInfoLog_(shader, sizeof(str), NULL, str); if (strstr(str, "WARNING")) { - Con_Printf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]); + Con_Printf("Shader source:\n"); + for (i = 0; i < strings; i++) + Con_Printf("%s", prstrings[i]); Con_Printf("%s\n", str); } } diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index 88c0a8511..0e68c7d08 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -534,6 +534,26 @@ static void GetEvent(void) ActiveApp = false; ClearAllStates(); + break; + case ClientMessage: + { + char *name = XGetAtomName(vid_dpy, event.xclient.message_type); + if (!strcmp(name, "WM_PROTOCOLS") && event.xclient.format == 32) + { + char *protname = XGetAtomName(vid_dpy, event.xclient.data.l[0]); + if (!strcmp(protname, "WM_DELETE_WINDOW")) + Cmd_ExecuteString("menu_quit", RESTRICT_LOCAL); + else + Con_Printf("Got message %s\n", protname); + XFree(protname); + } + else + Con_Printf("Got message %s\n", name); + XFree(name); + } + break; + default: +// Con_Printf("%x\n", event.type); break; } @@ -739,6 +759,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) Window root; XVisualInfo *visinfo; qboolean fullscreen = false; + Atom prots[1]; #ifdef WITH_VMODE int MajorVersion, MinorVersion; @@ -876,9 +897,16 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) vid_window = XCreateWindow(vid_dpy, root, 0, 0, info->width, info->height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); + /*ask the window manager to stop triggering bugs in Xlib*/ + prots[0] = XInternAtom(vid_dpy, "WM_DELETE_WINDOW", False); + XSetWMProtocols(vid_dpy, vid_window, prots, sizeof(prots)/sizeof(prots[0])); + /*set caption*/ + XStoreName(vid_dpy, vid_window, "FTE QuakeWorld"); + /*make it visibl*/ XMapWindow(vid_dpy, vid_window); - + /*put it somewhere*/ XMoveWindow(vid_dpy, vid_window, 0, 0); + #ifdef WITH_VMODE if (vidmode_active) { XRaiseWindow(vid_dpy, vid_window); @@ -888,7 +916,6 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) XF86VidModeSetViewPort(vid_dpy, scrnum, 0, 0); } #endif - XStoreName(vid_dpy, vid_window, "FTE QuakeWorld"); //hide the cursor. XDefineCursor(vid_dpy, vid_window, CreateNullCursor(vid_dpy, vid_window)); diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 71efbe9f3..73eef1011 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -396,18 +396,6 @@ void Shader_NeedReload(void); mfog_t *CM_FogForOrigin(vec3_t org); -//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented) -enum backendmode_e -{ - BEM_STANDARD, //regular mode to draw surfaces akin to q3 (aka: legacy mode). lightmaps+delux+ambient - BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps). - BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer. - BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal. - BEM_LIGHT, //we have a valid light - BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap - BEM_SMAPLIGHT //we have a light using a shadowmap -}; - #define BEF_FORCEDEPTHWRITE 1 #define BEF_FORCEDEPTHTEST 2 #define BEF_FORCEADDITIVE 4 //blend dest = GL_ONE diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 1f42a611c..a043420f0 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -308,12 +308,9 @@ char *PR_VarString (progfuncs_t *progfuncs, int first) if (G_STRING(OFS_PARM0+i*3)) { s=G_STRING((OFS_PARM0+i*3)) + progfuncs->stringtable; + if (strlen(out) + strlen(s) + 1 >= sizeof(out)) + return out; strcat (out, s); - -//#ifdef PARANOID - if (strlen(out)+1 >= sizeof(out)) - Sys_Error("VarString (builtin call ending with strings) exceeded maximum string length of %i chars", sizeof(out)); -//#endif } } return out; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 1a31821d8..8ff29bc9a 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -6588,7 +6588,7 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s //wait = G_FLOAT(OFS_PARM7); /*FIXME: not spawned - this persistant effect is created by a map object, all attributes are custom.*/ - Con_Printf("FTE-H2 FIXME: ce_rain not supported!\n", efnum); + Con_Printf("FTE-H2 FIXME: ce_rain not supported!\n"); return; break; case ce_snow: @@ -6598,7 +6598,7 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s //dir = G_VECTOR(OFS_PARM4); //count = G_FLOAT(OFS_PARM5); /*FIXME: not spawned - this persistant effect is created by a map object (might be delay-spawned), all attributes are custom.*/ - Con_Printf("FTE-H2 FIXME: ce_snow not supported!\n", efnum); + Con_Printf("FTE-H2 FIXME: ce_snow not supported!\n"); return; break; case ce_fountain: @@ -6608,7 +6608,7 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s //colour = G_FLOAT(OFS_PARM4); //count = G_FLOAT(OFS_PARM5); /*FIXME: not spawned - this persistant effect is created by a map object, all attributes are custom.*/ - Con_Printf("FTE-H2 FIXME: ce_fountain not supported!\n", efnum); + Con_Printf("FTE-H2 FIXME: ce_fountain not supported!\n"); return; break; case ce_quake: @@ -6786,7 +6786,7 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s return; } - Con_Printf("FTE-H2 FIXME: ce_chunk not supported!\n", efnum); + Con_Printf("FTE-H2 FIXME: ce_chunk not supported!\n"); return; @@ -6924,7 +6924,7 @@ static void QCBUILTIN PF_h2rain_go(progfuncs_t *prinst, struct globalvars_s *pr_ float colour = G_FLOAT(OFS_PARM4); float count = G_FLOAT(OFS_PARM5); */ - Con_DPrintf("rain go\n", (int)G_FLOAT(OFS_PARM0)); + Con_DPrintf("rain go\n"); } static void QCBUILTIN PF_h2StopSound(progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -6949,7 +6949,7 @@ static void QCBUILTIN PF_h2whiteflash(progfuncs_t *prinst, struct globalvars_s * broadcast a stuffcmd, I guess, to flash the screen white Only seen this occur once: after killing pravus. */ - Con_DPrintf("white flash\n", (int)G_FLOAT(OFS_PARM0)); + Con_DPrintf("white flash\n"); } static void QCBUILTIN PF_h2getstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index 4999458dc..24eb4d857 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -695,7 +695,7 @@ static void SVQ3_Adjust_Area_Portal_State(q3sharedEntity_t *ge, qboolean open) CMQ3_SetAreaPortalState(se->areanum, se->areanum2, open); } -#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) SV_Error("Call to game trap %i passes invalid pointer\n", fn); //out of bounds. +#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) SV_Error("Call to game trap %u passes invalid pointer\n", (unsigned int)fn); //out of bounds. static qintptr_t Q3G_SystemCalls(void *offset, unsigned int mask, qintptr_t fn, const qintptr_t *arg) { int ret = 0; @@ -1392,7 +1392,7 @@ static qintptr_t Q3G_SystemCalls(void *offset, unsigned int mask, qintptr_t fn, // notimplemented: default: - Con_Printf("builtin %i is not implemented\n", fn); + Con_Printf("builtin %i is not implemented\n", (int)fn); } return ret; }