mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
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
This commit is contained in:
parent
a8c4f7f4c1
commit
4fb854e261
27 changed files with 593 additions and 177 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
#define BE_DrawWorld rf->BE_DrawWorld
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -10,44 +10,106 @@
|
|||
#include <stdio.h>
|
||||
#include "quakedef.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/stat.h>
|
||||
#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 <stdint.h>
|
||||
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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <wchar.h>
|
||||
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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3126,7 +3126,7 @@ void Shader_DefaultCinematic(char *shortname, shader_t *s, const void *args)
|
|||
"videomap %s\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
, args)
|
||||
, (const char*)args)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue