mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 05:11:35 +00:00
tweeks and changes for android.
audio mixer revamped to cope with threads. 'cache' memory functions no longer used for audio. added windows acm code to decode mp3 files. audio playback rates scale with game speed. snd_playbackrate added to control the rate of new samples. sv_gamespeed no longer needs a map change. fixed '=' on german keymaps and in_builtinkeymap 0 (and similar issues). bug: keybind names still use US keymap. added support for rmqe's 24bit network precision. fixed byterate reporting to no longer be protocol-dependant (nq rates are no longer wildly inaccurate). removed waterjumping when already dead. fixed model matrix for viewmodels (modelview unchanged), thus fixing rtlighting on viewmodels. Added bspx support for rgblighting, lightingdir, and (preliminary)brushlists. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4001 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
db9388a297
commit
4149c85ab6
62 changed files with 2453 additions and 1210 deletions
|
@ -57,6 +57,9 @@ DROID_NDK_PATH?=~/droid/android-ndk-r6b
|
|||
DROID_SDK_PATH?=~/droid/android-sdk-linux_x86
|
||||
ANT?=ant
|
||||
JAVATOOL="$(JAVA_HOME)"/bin/
|
||||
ifeq ($(DROID_ARCH),)
|
||||
DROID_ARCH=armeabi
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),droid)
|
||||
#if we're running under windows, then we want to run some other binary
|
||||
ifeq ($(shell uname -o 2>&1 | grep Cygwin),)
|
||||
|
@ -68,22 +71,34 @@ ifeq ($(FTE_TARGET),droid)
|
|||
#we're running upon windows
|
||||
NDK_PATH:=$(shell cygpath -m $(DROID_NDK_PATH))
|
||||
SDK_PATH:=$(shell cygpath -m $(DROID_SDK_PATH))
|
||||
TOOLCHAIN:=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-
|
||||
ifeq ($(DROID_ARCH),x86)
|
||||
TOOLCHAIN:=$(NDK_PATH)/toolchains/x86-4.4.3/prebuilt/windows/bin/i686-android-linux-
|
||||
else
|
||||
TOOLCHAIN:=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-
|
||||
endif
|
||||
#make can't cope with absolute paths in dependancy files
|
||||
NODEPS = 1
|
||||
endif
|
||||
|
||||
DROID_API_LEVEL=4
|
||||
|
||||
#there are 3 ABI targets
|
||||
#armv5 (works on all arm droids)
|
||||
#armv7 (more common on 2.2+ droids)
|
||||
#armv7+neon
|
||||
DROID_ABI?=-mfloat-abi=softfp
|
||||
ifeq ($(DROID_ARCH),x86)
|
||||
DROID_PLAT_INC=arch-x86
|
||||
#google fecked up. anything before api_level 9 will fail to compile on x86
|
||||
DROID_API_LEVEL=9
|
||||
else
|
||||
DROID_PLAT_INC=arch-arm
|
||||
|
||||
#there are 3 ABI targets
|
||||
#armv5 (works on all arm droids)
|
||||
#armv7 (more common on 2.2+ droids)
|
||||
#armv7+neon
|
||||
DROID_ABI?=-mfloat-abi=softfp
|
||||
endif
|
||||
|
||||
STRIP=$(TOOLCHAIN)strip
|
||||
CC=$(TOOLCHAIN)gcc -I$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm/usr/include/ -DANDROID $(DROID_ABI)
|
||||
DO_LD=$(CC) -Wl,-soname,libftedroid.so -shared -Wl,--no-undefined -Wl,-z,noexecstack --sysroot=$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm -L$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm/usr/lib -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS) -llog -lc -lz -lm
|
||||
CC=$(TOOLCHAIN)gcc -I$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)/usr/include/ -DANDROID $(DROID_ABI)
|
||||
DO_LD=$(CC) -Wl,-soname,libftedroid.so -shared -Wl,--no-undefined -Wl,-z,noexecstack --sysroot=$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC) -L$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)/usr/lib -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS) -llog -lc -lz -lm
|
||||
endif
|
||||
|
||||
#correct the gcc build when cross compiling
|
||||
|
@ -732,7 +747,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),)
|
|||
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_alsa.o snd_linux.o cd_linux.o sys_linux.o
|
||||
GL_EXE_NAME=../fteqw.gl$(BITS)
|
||||
GLCL_EXE_NAME=../fteqwcl.gl$(BITS)
|
||||
GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm -lXxf86dga
|
||||
GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm -lXxf86dga -lz
|
||||
GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include -DUSE_DGA
|
||||
GLB_DIR=gl_linux$(BITS)
|
||||
GLCL_DIR=glcl_linux$(BITS)
|
||||
|
@ -740,7 +755,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),)
|
|||
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o snd_alsa.o cd_linux.o sys_linux.o
|
||||
M_EXE_NAME=../fteqw$(BITS)
|
||||
MCL_EXE_NAME=../fteqwcl$(BITS)
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm -lXxf86dga
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm -lXxf86dga -lz
|
||||
M_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include
|
||||
MB_DIR=m_linux$(BITS)
|
||||
MCL_DIR=mcl_linux$(BITS)
|
||||
|
@ -852,17 +867,17 @@ endif
|
|||
ifeq ($(FTE_TARGET),droid)
|
||||
BASELDFLAGS=
|
||||
|
||||
SV_DIR=sv_droid
|
||||
SV_DIR=sv_droid-$(DROID_ARCH)
|
||||
SV_LDFLAGS=-lz
|
||||
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) svmodel.o sys_droid.o
|
||||
SV_EXE_NAME=../libftedroid.so
|
||||
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) svmodel.o sys_droid.o in_droid.o
|
||||
SV_EXE_NAME=libftedroid.so
|
||||
|
||||
SV_LDFLAGS=
|
||||
|
||||
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_viddroid.o sys_droid.o cd_null.o snd_droid.o
|
||||
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_viddroid.o sys_droid.o in_droid.o cd_null.o snd_droid.o
|
||||
GL_LDFLAGS=$(GLLDFLAGS)
|
||||
GLB_DIR=gl_droid
|
||||
GL_EXE_NAME=../libftedroid.so
|
||||
GLB_DIR=gl_droid-$(DROID_ARCH)
|
||||
GL_EXE_NAME=libftedroid.so
|
||||
endif
|
||||
|
||||
SV_DIR?=sv_sdl
|
||||
|
@ -1198,9 +1213,10 @@ droid/ftekeystore:
|
|||
$(JAVATOOL)keytool -genkey -v -keystore $@ -alias autogen -keyalg RSA -keysize 2048 -validity 10000
|
||||
|
||||
droid-rel: droid/build.xml droid/ftekeystore
|
||||
$(MAKE) FTE_TARGET=droid gl-rel
|
||||
mkdir -p droid/libs/armeabi
|
||||
@cp $(RELEASE_DIR)/libftedroid.so droid/libs/armeabi/
|
||||
$(foreach a, $(DROID_ARCH), $(MAKE) FTE_TARGET=droid gl-rel DROID_ARCH=$a; )
|
||||
@$(foreach a, $(DROID_ARCH), mkdir -p droid/libs/$a; )
|
||||
-@$(foreach a, $(DROID_ARCH), cp $(RELEASE_DIR)/gl_droid-$a/libftedroid.so droid/libs/$a/libftedroid.so; )
|
||||
|
||||
@cd droid && $(ANT) release
|
||||
ifneq ($(DROID_PACKSU),)
|
||||
@echo
|
||||
|
|
|
@ -538,9 +538,9 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
break;
|
||||
|
||||
case CG_UPDATESCREEN: //force a buffer swap cos loading won't refresh it soon.
|
||||
SCR_BeginLoadingPlaque();
|
||||
if (key_dest != key_console)
|
||||
scr_con_current = 0;
|
||||
SCR_UpdateScreen();
|
||||
SCR_EndLoadingPlaque();
|
||||
break;
|
||||
|
||||
case CG_FS_FOPENFILE: //fopen
|
||||
|
@ -844,7 +844,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
break;
|
||||
|
||||
case CG_S_STARTSOUND:// ( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx )
|
||||
S_StartSound(VM_LONG(arg[1]), VM_LONG(arg[2]), S_PrecacheSound(VM_FROMSTRCACHE(arg[3])), VM_POINTER(arg[0]), 1, 1, 0);
|
||||
S_StartSound(VM_LONG(arg[1]), VM_LONG(arg[2]), S_PrecacheSound(VM_FROMSTRCACHE(arg[3])), VM_POINTER(arg[0]), 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case CG_S_ADDLOOPINGSOUND:
|
||||
|
|
|
@ -1402,6 +1402,7 @@ void CLNQ_ParseEntity(unsigned int bits)
|
|||
if (!CL_CheckBaselines(num))
|
||||
Host_EndGame("CLNQ_ParseEntity: check baselines failed with size %i", num);
|
||||
base = cl_baselines + num;
|
||||
memcpy(state, base, sizeof(*state));
|
||||
|
||||
state->number = num;
|
||||
state->solid = ES_SOLID_BSP;
|
||||
|
@ -1410,68 +1411,47 @@ void CLNQ_ParseEntity(unsigned int bits)
|
|||
|
||||
if (bits & NQU_MODEL)
|
||||
state->modelindex = MSG_ReadByte ();
|
||||
else
|
||||
state->modelindex = base->modelindex;
|
||||
|
||||
if (bits & NQU_FRAME)
|
||||
state->frame = MSG_ReadByte();
|
||||
else
|
||||
state->frame = base->frame;
|
||||
|
||||
if (bits & NQU_COLORMAP)
|
||||
state->colormap = MSG_ReadByte();
|
||||
else
|
||||
state->colormap = base->colormap;
|
||||
|
||||
if (bits & NQU_SKIN)
|
||||
state->skinnum = MSG_ReadByte();
|
||||
else
|
||||
state->skinnum = base->skinnum;
|
||||
|
||||
if (bits & NQU_EFFECTS)
|
||||
state->effects = MSG_ReadByte();
|
||||
else
|
||||
state->effects = base->effects;
|
||||
|
||||
if (bits & NQU_ORIGIN1)
|
||||
state->origin[0] = MSG_ReadCoord ();
|
||||
else
|
||||
state->origin[0] = base->origin[0];
|
||||
if (bits & NQU_ANGLE1)
|
||||
state->angles[0] = MSG_ReadAngle();
|
||||
else
|
||||
state->angles[0] = base->angles[0];
|
||||
|
||||
if (bits & NQU_ORIGIN2)
|
||||
state->origin[1] = MSG_ReadCoord ();
|
||||
else
|
||||
state->origin[1] = base->origin[1];
|
||||
if (bits & NQU_ANGLE2)
|
||||
state->angles[1] = MSG_ReadAngle();
|
||||
else
|
||||
state->angles[1] = base->angles[1];
|
||||
|
||||
if (bits & NQU_ORIGIN3)
|
||||
state->origin[2] = MSG_ReadCoord ();
|
||||
else
|
||||
state->origin[2] = base->origin[2];
|
||||
if (bits & NQU_ANGLE3)
|
||||
state->angles[2] = MSG_ReadAngle();
|
||||
else
|
||||
state->angles[2] = base->angles[2];
|
||||
|
||||
if (cls.protocol_nq == CPNQ_FITZ666)
|
||||
{
|
||||
if (bits & FITZU_ALPHA)
|
||||
state->trans = MSG_ReadByte();
|
||||
else
|
||||
state->trans = base->trans;
|
||||
|
||||
if (bits & RMQU_SCALE)
|
||||
state->scale = MSG_ReadByte();
|
||||
|
||||
if (bits & FITZU_FRAME2)
|
||||
state->frame |= MSG_ReadByte() << 8;
|
||||
state->frame = (state->frame & 0xff) | (MSG_ReadByte() << 8);
|
||||
|
||||
if (bits & FITZU_MODEL2)
|
||||
state->modelindex |= MSG_ReadByte() << 8;
|
||||
state->modelindex = (state->modelindex & 0xff) | (MSG_ReadByte() << 8);
|
||||
|
||||
if (bits & FITZU_LERPFINISH)
|
||||
MSG_ReadByte();
|
||||
|
@ -1479,41 +1459,19 @@ void CLNQ_ParseEntity(unsigned int bits)
|
|||
else
|
||||
{
|
||||
if (bits & DPU_ALPHA)
|
||||
i = MSG_ReadByte();
|
||||
else
|
||||
i = -1;
|
||||
|
||||
#ifdef PEXT_TRANS
|
||||
if (i == -1)
|
||||
state->trans = base->trans;
|
||||
else
|
||||
state->trans = i;
|
||||
#endif
|
||||
state->trans = MSG_ReadByte();
|
||||
|
||||
if (bits & DPU_SCALE)
|
||||
i = MSG_ReadByte();
|
||||
else
|
||||
i = -1;
|
||||
|
||||
#ifdef PEXT_SCALE
|
||||
if (i == -1)
|
||||
state->scale = base->scale;
|
||||
else
|
||||
state->scale = i;
|
||||
#endif
|
||||
state->scale = MSG_ReadByte();
|
||||
|
||||
if (bits & DPU_EFFECTS2)
|
||||
state->effects |= MSG_ReadByte() << 8;
|
||||
|
||||
if (bits & DPU_GLOWSIZE)
|
||||
state->glowsize = MSG_ReadByte();
|
||||
else
|
||||
state->glowsize = base->glowsize;
|
||||
|
||||
if (bits & DPU_GLOWCOLOR)
|
||||
state->glowcolour = MSG_ReadByte();
|
||||
else
|
||||
state->glowcolour = base->glowcolour;
|
||||
|
||||
if (bits & DPU_COLORMOD)
|
||||
{
|
||||
|
@ -1522,12 +1480,6 @@ void CLNQ_ParseEntity(unsigned int bits)
|
|||
state->colormod[1] = (qbyte)(((i >> 2) & 7) * (32.0f / 7.0f));
|
||||
state->colormod[2] = (qbyte)((i & 3) * (32.0f / 3.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
state->colormod[0] = base->colormod[0];
|
||||
state->colormod[1] = base->colormod[1];
|
||||
state->colormod[2] = base->colormod[2];
|
||||
}
|
||||
|
||||
if (bits & DPU_FRAME2)
|
||||
state->frame |= MSG_ReadByte() << 8;
|
||||
|
@ -3333,7 +3285,7 @@ void CL_ParsePlayerinfo (void)
|
|||
int num;
|
||||
num = MSG_ReadByte();
|
||||
|
||||
if (cl.worldmodel->fromgame != fg_quake)
|
||||
if (!cl.worldmodel || cl.worldmodel->fromgame != fg_quake)
|
||||
{
|
||||
VectorScale(state->szmins, num/56.0f, state->szmins);
|
||||
VectorScale(state->szmaxs, num/56.0f, state->szmaxs);
|
||||
|
@ -4024,7 +3976,7 @@ void CL_SetSolidEntities (void)
|
|||
{
|
||||
case 0:
|
||||
break;
|
||||
case -16:
|
||||
case Q1CONTENTS_LADDER:
|
||||
pent->nonsolid = true;
|
||||
pent->forcecontentsmask = FTECONTENTS_LADDER;
|
||||
break;
|
||||
|
|
|
@ -1810,10 +1810,8 @@ void CL_InitInput (void)
|
|||
Cmd_AddCommand (vahunk("+p%i", sp+1), CL_Split_f);
|
||||
Cmd_AddCommand (vahunk("-p%i", sp+1), CL_Split_f);
|
||||
|
||||
/*default mlook to pressed, unless on android where we expect a touch-screen and wouldn't be able to move forwards*/
|
||||
#ifndef ANDROID
|
||||
/*default mlook to pressed, (on android we split the two sides of the screen)*/
|
||||
in_mlook.state[sp] = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*then alternative arged ones*/
|
||||
|
|
|
@ -265,7 +265,14 @@ char soundlist_name[] =
|
|||
|
||||
void CL_MakeActive(char *gamename)
|
||||
{
|
||||
extern int fs_finds;
|
||||
if (fs_finds)
|
||||
{
|
||||
Con_DPrintf("%i additional FS searches\n", fs_finds);
|
||||
fs_finds = 0;
|
||||
}
|
||||
cls.state = ca_active;
|
||||
S_Purge(true);
|
||||
if (VID_SetWindowCaption)
|
||||
VID_SetWindowCaption(va("FTE %s: %s", gamename, cls.servername));
|
||||
|
||||
|
@ -1028,6 +1035,7 @@ void CL_ClearState (void)
|
|||
CL_AllowIndependantSendCmd(false); //model stuff could be a problem.
|
||||
|
||||
S_StopAllSounds (true);
|
||||
S_UntouchAll();
|
||||
S_ResetFailedLoad();
|
||||
|
||||
Cvar_ApplyLatches(CVAR_SERVEROVERRIDE);
|
||||
|
@ -1644,6 +1652,9 @@ void CL_CheckServerInfo(void)
|
|||
else
|
||||
cl.fpd = atoi(Info_ValueForKey(cl.serverinfo, "fpd"));
|
||||
|
||||
cl.gamespeed = atof(Info_ValueForKey(cl.serverinfo, "*gamespeed"))/100.f;
|
||||
if (cl.gamespeed < 0.1)
|
||||
cl.gamespeed = 1;
|
||||
|
||||
s = Info_ValueForKey(cl.serverinfo, "status");
|
||||
oldstate = cl.matchstate;
|
||||
|
@ -1700,10 +1711,6 @@ void CL_FullServerinfo_f (void)
|
|||
}
|
||||
CL_CheckServerInfo();
|
||||
|
||||
cl.gamespeed = atof(Info_ValueForKey(cl.serverinfo, "*gamespeed"))/100.f;
|
||||
if (cl.gamespeed < 0.1)
|
||||
cl.gamespeed = 1;
|
||||
|
||||
cl.csqcdebug = atoi(Info_ValueForKey(cl.serverinfo, "*csqcdebug"));
|
||||
}
|
||||
|
||||
|
|
|
@ -3602,7 +3602,7 @@ void CL_ParseStartSoundPacket(void)
|
|||
if (!sound_num)
|
||||
S_StopSound(ent, channel);
|
||||
else
|
||||
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation, 0);
|
||||
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3680,11 +3680,11 @@ void CLQ2_ParseStartSoundPacket(void)
|
|||
*skin = '\0';
|
||||
if (*model)
|
||||
{
|
||||
S_StartSound (ent, channel, S_PrecacheSound(va("players/%s/%s", model, cl.sound_precache[sound_num]->name+1)), pos, volume, attenuation, 0);
|
||||
S_StartSound (ent, channel, S_PrecacheSound(va("players/%s/%s", model, cl.sound_precache[sound_num]->name+1)), pos, volume, attenuation, 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume, attenuation, 0);
|
||||
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume, attenuation, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3750,7 +3750,7 @@ void CLNQ_ParseStartSoundPacket(void)
|
|||
if (!sound_num)
|
||||
S_StopSound(ent, channel);
|
||||
else
|
||||
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation, pitchadj);
|
||||
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation, 0, pitchadj);
|
||||
}
|
||||
|
||||
if (ent == cl.playernum[0]+1)
|
||||
|
@ -4021,7 +4021,7 @@ void CL_ServerInfo (void)
|
|||
|
||||
Con_DPrintf("SERVERINFO: %s=%s\n", key, value);
|
||||
|
||||
Info_SetValueForKey (cl.serverinfo, key, value, MAX_SERVERINFO_STRING);
|
||||
Info_SetValueForStarKey (cl.serverinfo, key, value, MAX_SERVERINFO_STRING);
|
||||
|
||||
CL_CheckServerInfo();
|
||||
}
|
||||
|
@ -5225,6 +5225,7 @@ void CLQW_ParseServerMessage (void)
|
|||
case svcfte_setangledelta:
|
||||
for (i=0 ; i<3 ; i++)
|
||||
cl.viewangles[destsplit][i] += MSG_ReadAngle16 ();
|
||||
VectorCopy (cl.viewangles[destsplit], cl.simangles[destsplit]);
|
||||
break;
|
||||
case svc_setangle:
|
||||
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
||||
|
@ -5248,6 +5249,8 @@ void CLQW_ParseServerMessage (void)
|
|||
cl.fixangle[destsplit]=true;
|
||||
for (i=0 ; i<3 ; i++)
|
||||
cl.viewangles[destsplit][i] = cl.fixangles[destsplit][i] = MSG_ReadAngle ();
|
||||
|
||||
VectorCopy (cl.viewangles[destsplit], cl.simangles[destsplit]);
|
||||
// cl.viewangles[PITCH] = cl.viewangles[ROLL] = 0;
|
||||
break;
|
||||
|
||||
|
@ -5413,6 +5416,7 @@ void CLQW_ParseServerMessage (void)
|
|||
cl.simorg[destsplit][i] = MSG_ReadCoord ();
|
||||
for (i=0 ; i<3 ; i++)
|
||||
cl.simangles[destsplit][i] = MSG_ReadAngle ();
|
||||
VectorCopy (cl.simangles[destsplit], cl.fixangles[destsplit]);
|
||||
VectorClear (cl.simvel[destsplit]);
|
||||
break;
|
||||
|
||||
|
@ -5420,6 +5424,7 @@ void CLQW_ParseServerMessage (void)
|
|||
if (!cl.intermission)
|
||||
for (i = 0; i < MAX_SPLITS; i++)
|
||||
cl.simorg[i][2] += cl.viewheight[i];
|
||||
VectorCopy (cl.fixangles[destsplit], cl.simangles[destsplit]);
|
||||
|
||||
cl.intermission = 2;
|
||||
cl.completed_time = cl.gametime;
|
||||
|
@ -6209,6 +6214,10 @@ void CLNQ_ParseServerMessage (void)
|
|||
case svc_sound:
|
||||
CLNQ_ParseStartSoundPacket();
|
||||
break;
|
||||
case svc_stopsound:
|
||||
i = MSG_ReadShort();
|
||||
S_StopSound(i>>3, i&7);
|
||||
break;
|
||||
|
||||
case svc_temp_entity:
|
||||
CL_ParseTEnt (true);
|
||||
|
|
|
@ -796,6 +796,9 @@ void CL_PlayerFrameUpdated(player_state_t *plstate, entity_state_t *state, int s
|
|||
|
||||
plstate->pm_type = pmtype;
|
||||
VectorCopy(state->origin, plstate->origin);
|
||||
plstate->command.angles[0] = state->angles[0] * -3 *65536/360.0;
|
||||
plstate->command.angles[1] = state->angles[1] * 65536/360.0;
|
||||
plstate->command.angles[2] = state->angles[2] * 65536/360.0;
|
||||
VectorScale(state->u.q1.velocity, 1/8.0, plstate->velocity);
|
||||
plstate->messagenum = sequence;
|
||||
|
||||
|
@ -894,7 +897,7 @@ void CL_PredictMovePNum (int pnum)
|
|||
if (cl.paused && !(cls.demoplayback!=DPB_MVD && cls.demoplayback!=DPB_EZTV) && (!cl.spectator || !autocam[pnum]))
|
||||
return;
|
||||
|
||||
if (cl.intermission && cl.intermission != 3 && cls.protocol == CP_QUAKEWORLD)
|
||||
if (cl.intermission==1 && cls.protocol == CP_QUAKEWORLD)
|
||||
{
|
||||
cl.crouch[pnum] = 0;
|
||||
return;
|
||||
|
|
|
@ -1467,6 +1467,13 @@ void SCR_DrawLoading (void)
|
|||
//int mtype = M_GameType(); //unused variable
|
||||
y = vid.height/2;
|
||||
|
||||
if (*levelshotname)
|
||||
{
|
||||
pic = R2D_SafeCachePic (levelshotname);
|
||||
R2D_ImageColours(1, 1, 1, 1);
|
||||
R2D_ScalePic (0, 0, vid.width, vid.height, pic);
|
||||
}
|
||||
|
||||
qdepth = COM_FDepthFile("gfx/loading.lmp", true);
|
||||
h2depth = COM_FDepthFile("gfx/menu/loading.lmp", true);
|
||||
|
||||
|
@ -1563,6 +1570,7 @@ void SCR_DrawLoading (void)
|
|||
y = 104;
|
||||
}
|
||||
}
|
||||
R2D_ImageColours(1, 1, 1, 1);
|
||||
|
||||
if (cl.downloadlist || cls.downloadmethod)
|
||||
{
|
||||
|
@ -1669,7 +1677,8 @@ void SCR_ImageName (char *mapname)
|
|||
GL_BeginRendering ();
|
||||
SCR_DrawLoading();
|
||||
SCR_SetUpToDrawConsole();
|
||||
SCR_DrawConsole(!!*levelshotname);
|
||||
if (key_dest == key_console || !*levelshotname)
|
||||
SCR_DrawConsole(!!*levelshotname);
|
||||
GL_EndRendering();
|
||||
scr_drawloading = false;
|
||||
|
||||
|
|
|
@ -898,7 +898,7 @@ void CL_ParseTEnt (void)
|
|||
if (P_RunParticleEffectType(pos, NULL, 1, pt_wizspike))
|
||||
P_RunParticleEffect (pos, vec3_origin, 20, 30);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_wizhit, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_wizhit, pos, 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case TE_KNIGHTSPIKE: // spike hitting wall
|
||||
|
@ -911,7 +911,7 @@ void CL_ParseTEnt (void)
|
|||
if (P_RunParticleEffectType(pos, NULL, 1, pt_knightspike))
|
||||
P_RunParticleEffect (pos, vec3_origin, 226, 20);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case TEDP_SPIKEQUAD:
|
||||
|
@ -928,16 +928,16 @@ void CL_ParseTEnt (void)
|
|||
P_RunParticleEffect (pos, vec3_origin, 0, 10);
|
||||
|
||||
if ( rand() % 5 )
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0, 0);
|
||||
else
|
||||
{
|
||||
rnd = rand() & 3;
|
||||
if (rnd == 1)
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0, 0);
|
||||
else if (rnd == 2)
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case TE_SPIKE: // spike hitting wall
|
||||
|
@ -953,16 +953,16 @@ void CL_ParseTEnt (void)
|
|||
P_RunParticleEffect (pos, vec3_origin, 0, 10);
|
||||
|
||||
if ( rand() % 5 )
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0, 0);
|
||||
else
|
||||
{
|
||||
rnd = rand() & 3;
|
||||
if (rnd == 1)
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0, 0);
|
||||
else if (rnd == 2)
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case TEDP_SUPERSPIKEQUAD: // super spike hitting wall
|
||||
|
@ -980,16 +980,16 @@ void CL_ParseTEnt (void)
|
|||
P_RunParticleEffect (pos, vec3_origin, 0, 20);
|
||||
|
||||
if ( rand() % 5 )
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0, 0);
|
||||
else
|
||||
{
|
||||
rnd = rand() & 3;
|
||||
if (rnd == 1)
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0, 0);
|
||||
else if (rnd == 2)
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case TE_SUPERSPIKE: // super spike hitting wall
|
||||
|
@ -1006,16 +1006,16 @@ void CL_ParseTEnt (void)
|
|||
P_RunParticleEffect (pos, vec3_origin, 0, 20);
|
||||
|
||||
if ( rand() % 5 )
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0, 0);
|
||||
else
|
||||
{
|
||||
rnd = rand() & 3;
|
||||
if (rnd == 1)
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0, 0);
|
||||
else if (rnd == 2)
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1035,16 +1035,16 @@ void CL_ParseTEnt (void)
|
|||
P_RunParticleEffect (pos, vec3_origin, 0, 10);
|
||||
|
||||
if ( rand() % 5 )
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0, 0);
|
||||
else
|
||||
{
|
||||
rnd = rand() & 3;
|
||||
if (rnd == 1)
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0, 0);
|
||||
else if (rnd == 2)
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case TE_SUPERBULLET:
|
||||
|
@ -1061,16 +1061,16 @@ void CL_ParseTEnt (void)
|
|||
P_RunParticleEffect (pos, vec3_origin, 0, 20);
|
||||
|
||||
if ( rand() % 5 )
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_tink1, pos, 1, 1, 0, 0);
|
||||
else
|
||||
{
|
||||
rnd = rand() & 3;
|
||||
if (rnd == 1)
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric1, pos, 1, 1, 0, 0);
|
||||
else if (rnd == 2)
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric2, pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_ric3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -1105,7 +1105,7 @@ void CL_ParseTEnt (void)
|
|||
|
||||
|
||||
// sound
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
|
||||
// sprite
|
||||
if (cl_expsprite.ival) // temp hopefully
|
||||
|
@ -1145,7 +1145,7 @@ void CL_ParseTEnt (void)
|
|||
|
||||
|
||||
// sound
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
|
||||
// sprite
|
||||
if (cl_expsprite.ival && !nqprot) // temp hopefully
|
||||
|
@ -1184,7 +1184,7 @@ void CL_ParseTEnt (void)
|
|||
dl->channelfade[2] = 0;
|
||||
}
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case TEDP_TEI_BIGEXPLOSION:
|
||||
|
@ -1215,7 +1215,7 @@ void CL_ParseTEnt (void)
|
|||
dl->channelfade[2] = 0;
|
||||
}
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case TE_TAREXPLOSION: // tarbaby explosion
|
||||
|
@ -1224,7 +1224,7 @@ void CL_ParseTEnt (void)
|
|||
pos[2] = MSG_ReadCoord ();
|
||||
P_RunParticleEffectType(pos, NULL, 1, pt_tarexplosion);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case TE_LIGHTNING1: // lightning bolts
|
||||
|
@ -1989,7 +1989,7 @@ static qbyte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8};
|
|||
#define ATTN_STATIC 1
|
||||
void Q2S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol, float attenuation, float timeofs)
|
||||
{
|
||||
S_StartSoundDelayed(entnum, entchannel, sfx, origin, fvol, attenuation, timeofs);
|
||||
S_StartSound(entnum, entchannel, sfx, origin, fvol, attenuation, timeofs, 0);
|
||||
}
|
||||
void CLQ2_ParseTEnt (void)
|
||||
{
|
||||
|
@ -2052,7 +2052,7 @@ void CLQ2_ParseTEnt (void)
|
|||
else
|
||||
P_RunParticleEffect (pos, dir, 0xb0, 40);
|
||||
//FIXME : replace or remove this sound
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case Q2TE_SHOTGUN: // bullet hitting wall
|
||||
|
@ -2139,7 +2139,7 @@ void CLQ2_ParseTEnt (void)
|
|||
ex->angles[1] = 0;
|
||||
ex->angles[0]*=-1;
|
||||
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0, 0);
|
||||
|
||||
// light
|
||||
if (r_explosionlight.value)
|
||||
|
@ -2197,9 +2197,9 @@ void CLQ2_ParseTEnt (void)
|
|||
|
||||
// sound
|
||||
if (type == Q2TE_GRENADE_EXPLOSION_WATER)
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/xpld_wat.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/xpld_wat.wav"), pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/grenlx1a.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/grenlx1a.wav"), pos, 1, 1, 0, 0);
|
||||
|
||||
// sprite
|
||||
|
||||
|
@ -2293,9 +2293,9 @@ void CLQ2_ParseTEnt (void)
|
|||
|
||||
// sound
|
||||
if (type == Q2TE_ROCKET_EXPLOSION_WATER)
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/xpld_wat.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/xpld_wat.wav"), pos, 1, 1, 0, 0);
|
||||
else
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/rocklx1a.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/rocklx1a.wav"), pos, 1, 1, 0, 0);
|
||||
|
||||
// sprite
|
||||
// if (!R_ParticleExplosionHeart(pos))
|
||||
|
@ -2469,7 +2469,7 @@ void CLQ2_ParseTEnt (void)
|
|||
ex->angles[1] = 0;
|
||||
ex->angles[0]*=-1;
|
||||
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0, 0);
|
||||
|
||||
// light
|
||||
if (r_explosionlight.value)
|
||||
|
@ -2519,7 +2519,7 @@ void CLQ2_ParseTEnt (void)
|
|||
ex->angles[1] = 0;
|
||||
ex->angles[0]*=-1;
|
||||
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, 1, 1, 0, 0);
|
||||
|
||||
// light
|
||||
if (r_explosionlight.value)
|
||||
|
|
|
@ -981,7 +981,8 @@ void V_SetContentsColor (int contents);
|
|||
|
||||
//used directly by csqc
|
||||
void V_CalcRefdef (int pnum);
|
||||
void CalcGunAngle (int pnum);
|
||||
void V_CalcGunPositionAngle (int pnum, float bob);
|
||||
float V_CalcBob (int pnum, qboolean queryold);
|
||||
void DropPunchAngle (int pnum);
|
||||
|
||||
|
||||
|
|
295
engine/client/in_droid.c
Normal file
295
engine/client/in_droid.c
Normal file
|
@ -0,0 +1,295 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
extern qboolean mouse_active;
|
||||
|
||||
cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE);
|
||||
cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn.");
|
||||
|
||||
extern cvar_t _windowed_mouse;
|
||||
|
||||
int mousecursor_x, mousecursor_y; /*absolute position*/
|
||||
extern int mousemove_x, mousemove_y;
|
||||
static float mouse_x, mouse_y;
|
||||
static float mousestrafe_x, mousestrafe_y;
|
||||
static float old_mouse_x, old_mouse_y; /*for smoothing*/
|
||||
|
||||
|
||||
#define EVENTQUEUELENGTH 128
|
||||
struct eventlist_s
|
||||
{
|
||||
enum
|
||||
{
|
||||
IEV_KEYDOWN,
|
||||
IEV_KEYRELEASE,
|
||||
IEV_MOUSEABS
|
||||
} type;
|
||||
int devid;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float x, y;
|
||||
} mouse;
|
||||
struct
|
||||
{
|
||||
int scancode, unicode;
|
||||
} keyboard;
|
||||
};
|
||||
} eventlist[EVENTQUEUELENGTH];
|
||||
volatile int events_avail; /*volatile to make sure the cc doesn't try leaving these cached in a register*/
|
||||
volatile int events_used;
|
||||
|
||||
static struct eventlist_s *in_newevent(void)
|
||||
{
|
||||
if (events_avail >= events_used + EVENTQUEUELENGTH)
|
||||
return NULL;
|
||||
return &eventlist[events_avail & (EVENTQUEUELENGTH-1)];
|
||||
}
|
||||
|
||||
static void in_finishevent(void)
|
||||
{
|
||||
events_avail++;
|
||||
}
|
||||
|
||||
#define MAXPOINTERS 8
|
||||
struct
|
||||
{
|
||||
vec2_t oldpos;
|
||||
vec2_t downpos;
|
||||
float movedist;
|
||||
vec2_t move;
|
||||
int down;
|
||||
} ptr[MAXPOINTERS];
|
||||
|
||||
|
||||
|
||||
void IN_Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void IN_ReInit()
|
||||
{
|
||||
Cvar_Register (&m_filter, "input controls");
|
||||
Cvar_Register (&m_strafeonright, "input controls");
|
||||
}
|
||||
|
||||
void IN_Init(void)
|
||||
{
|
||||
IN_ReInit();
|
||||
}
|
||||
|
||||
/*on android, each 'pointer' is a separate touch location*/
|
||||
void IN_Commands(void)
|
||||
{
|
||||
struct eventlist_s *ev;
|
||||
while (events_used != events_avail)
|
||||
{
|
||||
ev = &eventlist[events_used & (EVENTQUEUELENGTH-1)];
|
||||
switch(ev->type)
|
||||
{
|
||||
case IEV_KEYDOWN:
|
||||
case IEV_KEYRELEASE:
|
||||
if (ev->keyboard.scancode == K_MOUSE1 && ev->devid < MAXPOINTERS)
|
||||
{
|
||||
if (Key_MouseShouldBeFree())
|
||||
ptr[ev->devid].down = false;
|
||||
else
|
||||
{
|
||||
if (ev->type == IEV_KEYDOWN)
|
||||
{
|
||||
ptr[ev->devid].down = true;
|
||||
ptr[ev->devid].movedist = 0;
|
||||
ptr[ev->devid].downpos[0] = ptr[ev->devid].oldpos[0];
|
||||
ptr[ev->devid].downpos[1] = ptr[ev->devid].oldpos[1];
|
||||
ptr[ev->devid].move[0] = 0;
|
||||
ptr[ev->devid].move[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptr[ev->devid].down)
|
||||
{
|
||||
if (ptr[ev->devid].movedist < 5)
|
||||
{
|
||||
/*if its on the right, make it a mouse2*/
|
||||
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE3:K_MOUSE1;
|
||||
Key_Event(ev->devid, key, 0, true);
|
||||
Key_Event(ev->devid, key, 0, false);
|
||||
}
|
||||
}
|
||||
ptr[ev->devid].down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, ev->type == IEV_KEYDOWN);
|
||||
break;
|
||||
case IEV_MOUSEABS:
|
||||
/*mouse cursors only really work with one pointer*/
|
||||
if (ev->devid == 0)
|
||||
{
|
||||
mousecursor_x = bound(0, ev->mouse.x, vid.width - 1);
|
||||
mousecursor_y = bound(0, ev->mouse.y, vid.height - 1);
|
||||
}
|
||||
|
||||
if (ev->devid < MAXPOINTERS)
|
||||
{
|
||||
ptr[ev->devid].move[0] += ev->mouse.x - ptr[ev->devid].oldpos[0];
|
||||
ptr[ev->devid].move[1] += ev->mouse.y - ptr[ev->devid].oldpos[1];
|
||||
|
||||
ptr[ev->devid].movedist += fabs(ev->mouse.x - ptr[ev->devid].oldpos[0]) + fabs(ev->mouse.y - ptr[ev->devid].oldpos[1]);
|
||||
|
||||
ptr[ev->devid].oldpos[0] = ev->mouse.x;
|
||||
ptr[ev->devid].oldpos[1] = ev->mouse.y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
events_used++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void IN_Update(qboolean ingame)
|
||||
{
|
||||
int i;
|
||||
//strafing speed is absolute
|
||||
mousestrafe_x = 0;
|
||||
mousestrafe_y = 0;
|
||||
|
||||
for (i = 0; i < MAXPOINTERS; i++)
|
||||
{
|
||||
/*ignore if no action, to avoid phantom csqc input events*/
|
||||
if (!ptr[i].down && !ptr[i].move[0] && !ptr[i].move[1])
|
||||
continue;
|
||||
|
||||
if (!CSQC_MousePosition(ptr[i].oldpos[0], ptr[i].oldpos[1], i))
|
||||
{
|
||||
if (!CSQC_MouseMove(ptr[i].move[0], ptr[i].move[1], i))
|
||||
{
|
||||
if (ptr[i].down && m_strafeonright.ival && ptr[i].downpos[0] > vid.pixelwidth/2 && ingame)
|
||||
{
|
||||
mousestrafe_x += ptr[i].oldpos[0] - ptr[i].downpos[0];
|
||||
mousestrafe_y += ptr[i].oldpos[1] - ptr[i].downpos[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_x += ptr[i].move[0];
|
||||
mouse_y += ptr[i].move[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr[i].move[0] = 0;
|
||||
ptr[i].move[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IN_Move (float *movements, int pnum)
|
||||
{
|
||||
qboolean ingame;
|
||||
extern int mousecursor_x, mousecursor_y;
|
||||
|
||||
if (pnum != 0)
|
||||
return; //we're lazy today.
|
||||
|
||||
ingame = movements != NULL && (key_dest == key_game);
|
||||
|
||||
IN_Update(ingame);
|
||||
|
||||
if (m_filter.value)
|
||||
{
|
||||
mouse_x = (mouse_x + old_mouse_x) * 0.5;
|
||||
mouse_y = (mouse_y + old_mouse_y) * 0.5;
|
||||
}
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
|
||||
if(in_xflip.value) mouse_x *= -1;
|
||||
|
||||
mousemove_x += mouse_x;
|
||||
mousemove_y += mouse_y;
|
||||
|
||||
if (!ingame)
|
||||
{
|
||||
mouse_x = mouse_y = 0;
|
||||
#ifdef VM_UI
|
||||
UI_MousePosition(mousecursor_x, mousecursor_y);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*if the look-mouse is set to always strafe instead...*/
|
||||
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
|
||||
{
|
||||
mousestrafe_x += mouse_x;
|
||||
mouse_x = 0;
|
||||
}
|
||||
if ( (in_strafe.state[pnum] & 1) || !(in_mlook.state[pnum] & 1))
|
||||
{
|
||||
mousestrafe_y += mouse_y;
|
||||
mouse_y = 0;
|
||||
}
|
||||
|
||||
/*handle strafes*/
|
||||
if (movements)
|
||||
{
|
||||
float scale;
|
||||
|
||||
scale = m_side.value * sensitivity.value;
|
||||
movements[1] += mousestrafe_x * scale;
|
||||
|
||||
scale = m_forward.value * sensitivity.value;
|
||||
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
|
||||
movements[2] -= mousestrafe_y * scale;
|
||||
else
|
||||
movements[0] -= mousestrafe_y * scale;
|
||||
}
|
||||
|
||||
if (in_mlook.state[pnum] & 1)
|
||||
V_StopPitchDrift (pnum);
|
||||
|
||||
/*handle looks*/
|
||||
cl.viewanglechange[pnum][YAW] -= m_yaw.value * mouse_x * sensitivity.value;
|
||||
cl.viewanglechange[pnum][PITCH] += m_pitch.value * mouse_y * sensitivity.value;
|
||||
|
||||
mouse_x = mouse_y = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_keypress(JNIEnv *env, jobject obj,
|
||||
jint down, jint keycode, jint unicode)
|
||||
{
|
||||
struct eventlist_s *ev = in_newevent();
|
||||
if (!ev)
|
||||
return;
|
||||
ev->type = down?IEV_KEYDOWN:IEV_KEYRELEASE;
|
||||
ev->devid = 0;
|
||||
ev->keyboard.scancode = keycode;
|
||||
ev->keyboard.unicode = unicode;
|
||||
in_finishevent();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_motion(JNIEnv *env, jobject obj,
|
||||
jint act, jint ptrid, jfloat x, jfloat y)
|
||||
{
|
||||
struct eventlist_s *ev = in_newevent();
|
||||
if (!ev)
|
||||
return;
|
||||
ev->devid = ptrid;
|
||||
if (act)
|
||||
{
|
||||
ev->type = (act==1)?IEV_KEYDOWN:IEV_KEYRELEASE;
|
||||
ev->keyboard.scancode = K_MOUSE1;
|
||||
ev->keyboard.unicode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev->type = IEV_MOUSEABS;
|
||||
ev->mouse.x = x;
|
||||
ev->mouse.y = y;
|
||||
}
|
||||
in_finishevent();
|
||||
}
|
|
@ -55,7 +55,7 @@ cvar_t m_accel = SCVAR("m_accel", "0");
|
|||
cvar_t m_forcewheel = SCVAR("m_forcewheel", "1");
|
||||
cvar_t m_forcewheel_threshold = SCVAR("m_forcewheel_threshold", "32");
|
||||
cvar_t in_dinput = SCVARF("in_dinput","0", CVAR_ARCHIVE);
|
||||
cvar_t in_builtinkeymap = SCVARF("in_builtinkeymap", "1", CVAR_ARCHIVE);
|
||||
cvar_t in_builtinkeymap = SCVARF("in_builtinkeymap", "0", CVAR_ARCHIVE);
|
||||
|
||||
cvar_t m_accel_noforce = SCVAR("m_accel_noforce", "0");
|
||||
cvar_t m_threshold_noforce = SCVAR("m_threshold_noforce", "0");
|
||||
|
@ -2385,9 +2385,10 @@ void IN_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdevi
|
|||
extern cvar_t in_builtinkeymap;
|
||||
int qcode;
|
||||
int unicode;
|
||||
extern int keyshift[256];
|
||||
extern int shift_down;
|
||||
|
||||
qcode = MapKey(lParam);
|
||||
unicode = (qcode < 128)?qcode:0;
|
||||
|
||||
if (WinNT && !in_builtinkeymap.value)
|
||||
{
|
||||
|
@ -2400,6 +2401,13 @@ void IN_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdevi
|
|||
// if (!wchars[1])
|
||||
unicode = wchars[0];
|
||||
}
|
||||
else unicode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unicode = (qcode < 128)?qcode:0;
|
||||
if (shift_down && unicode < K_MAX && keyshift[unicode])
|
||||
unicode = keyshift[unicode];
|
||||
}
|
||||
|
||||
Key_Event (qdeviceid, qcode, unicode, down);
|
||||
|
|
|
@ -1633,9 +1633,6 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
return;
|
||||
}
|
||||
|
||||
if (shift_down && unicode < K_MAX && keyshift[unicode])
|
||||
unicode = keyshift[unicode];
|
||||
|
||||
if (!down)
|
||||
{
|
||||
switch (key_dest)
|
||||
|
|
|
@ -178,7 +178,7 @@ extern char chat_buffer[];
|
|||
extern int chat_bufferlen;
|
||||
extern qboolean chat_team;
|
||||
|
||||
void Key_Event (int pnum, int key, unsigned int unicode, qboolean down);
|
||||
void Key_Event (int devid, int key, unsigned int unicode, qboolean down);
|
||||
void Key_Init (void);
|
||||
void Key_WriteBindings (vfsfile_t *f);
|
||||
void Key_SetBinding (int keynum, int modifier, char *binding, int cmdlevel);
|
||||
|
|
|
@ -10,6 +10,8 @@ qboolean bindingactive;
|
|||
extern cvar_t cl_cursor;
|
||||
extern cvar_t cl_cursorsize;
|
||||
extern cvar_t cl_cursorbias;
|
||||
menu_t *currentmenu;
|
||||
menu_t *firstmenu;
|
||||
|
||||
void Draw_TextBox (int x, int y, int width, int lines)
|
||||
{
|
||||
|
@ -192,7 +194,7 @@ int maxdots;
|
|||
int mindot;
|
||||
int dotofs;
|
||||
|
||||
void MenuTooltipSplit(menu_t *menu, const char *text)
|
||||
static void MenuTooltipSplit(menu_t *menu, const char *text)
|
||||
{
|
||||
char buf[1024];
|
||||
char *c, *space;
|
||||
|
@ -292,7 +294,7 @@ void MenuTooltipSplit(menu_t *menu, const char *text)
|
|||
menu->tooltip = mtt;
|
||||
}
|
||||
|
||||
qboolean MI_Selectable(menuoption_t *op)
|
||||
static qboolean MI_Selectable(menuoption_t *op)
|
||||
{
|
||||
switch(op->common.type)
|
||||
{
|
||||
|
@ -331,45 +333,76 @@ qboolean MI_Selectable(menuoption_t *op)
|
|||
}
|
||||
}
|
||||
|
||||
void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
|
||||
static void M_CheckMouseMove(void)
|
||||
{
|
||||
int i;
|
||||
mpic_t *p;
|
||||
|
||||
extern int mousecursor_x, mousecursor_y;
|
||||
qboolean foundexclusive = false;
|
||||
int mgt;
|
||||
menu_t *menu;
|
||||
menuoption_t *option;
|
||||
|
||||
mgt = M_GameType();
|
||||
if (omousex != mousecursor_x || omousey != mousecursor_y)
|
||||
mousemoved = true;
|
||||
else
|
||||
mousemoved = false;
|
||||
omousex = mousecursor_x;
|
||||
omousey = mousecursor_y;
|
||||
|
||||
while (option)
|
||||
if (mousemoved)
|
||||
{
|
||||
if (mousemoved && !bindingactive && !option->common.ishidden)
|
||||
{
|
||||
if (omousex > xpos+option->common.posx-option->common.extracollide && omousex < xpos+option->common.posx+option->common.width)
|
||||
{
|
||||
if (omousey > ypos+option->common.posy && omousey < ypos+option->common.posy+option->common.height)
|
||||
{
|
||||
if (MI_Selectable(option))
|
||||
{
|
||||
if (menu->selecteditem != option)
|
||||
{
|
||||
if (!option->common.noselectionsound)
|
||||
{
|
||||
if (mgt == MGT_HEXEN2)
|
||||
S_LocalSound ("raven/menu1.wav");
|
||||
else
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
}
|
||||
mgt = M_GameType();
|
||||
|
||||
menu->selecteditem = option;
|
||||
menu->tooltiptime = realtime + 1;
|
||||
MenuTooltipSplit(menu, menu->selecteditem->common.tooltip);
|
||||
for (menu = firstmenu; menu; menu = menu->parent)
|
||||
{
|
||||
if (menu->exclusive)
|
||||
{
|
||||
if (foundexclusive)
|
||||
continue;
|
||||
foundexclusive=true;
|
||||
}
|
||||
|
||||
for(option = menu->options; option; option = option = option->common.next)
|
||||
{
|
||||
if (mousemoved && !bindingactive && !option->common.ishidden)
|
||||
{
|
||||
if (mousecursor_x > menu->xpos+option->common.posx-option->common.extracollide && mousecursor_x < menu->xpos+option->common.posx+option->common.width)
|
||||
{
|
||||
if (mousecursor_y > menu->ypos+option->common.posy && mousecursor_y < menu->ypos+option->common.posy+option->common.height)
|
||||
{
|
||||
if (MI_Selectable(option))
|
||||
{
|
||||
if (menu->selecteditem != option)
|
||||
{
|
||||
if (!option->common.noselectionsound)
|
||||
{
|
||||
if (mgt == MGT_HEXEN2)
|
||||
S_LocalSound ("raven/menu1.wav");
|
||||
else
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
}
|
||||
|
||||
menu->selecteditem = option;
|
||||
menu->tooltiptime = realtime + 1;
|
||||
MenuTooltipSplit(menu, menu->selecteditem->common.tooltip);
|
||||
}
|
||||
if (menu->cursoritem)
|
||||
menu->cursoritem->common.posy = menu->selecteditem->common.posy;
|
||||
}
|
||||
}
|
||||
if (menu->cursoritem)
|
||||
menu->cursoritem->common.posy = menu->selecteditem->common.posy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
|
||||
{
|
||||
int i;
|
||||
mpic_t *p;
|
||||
|
||||
while (option)
|
||||
{
|
||||
if (!option->common.ishidden)
|
||||
switch(option->common.type)
|
||||
{
|
||||
|
@ -602,7 +635,7 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
|
|||
}
|
||||
}
|
||||
|
||||
void MenuDraw(menu_t *menu)
|
||||
static void MenuDraw(menu_t *menu)
|
||||
{
|
||||
if (menu->event)
|
||||
menu->event(menu);
|
||||
|
@ -1348,9 +1381,6 @@ changed:
|
|||
}
|
||||
}
|
||||
|
||||
menu_t *currentmenu;
|
||||
menu_t *firstmenu;
|
||||
|
||||
void M_AddMenuFront (menu_t *menu)
|
||||
{
|
||||
menu_t *pmenu;
|
||||
|
@ -1485,22 +1515,13 @@ void DrawCursor(int prydoncursornum)
|
|||
Font_DrawChar(x, y, '+' | 0xe000 | CON_WHITEMASK);
|
||||
Font_EndString(font_conchar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void M_Complex_Draw(void)
|
||||
{
|
||||
extern int mousecursor_x, mousecursor_y;
|
||||
menu_t *menu, *cmenu;
|
||||
qboolean foundexclusive = false;
|
||||
|
||||
if (omousex != mousecursor_x || omousey != mousecursor_y)
|
||||
mousemoved = true;
|
||||
else
|
||||
mousemoved = false;
|
||||
omousex = mousecursor_x;
|
||||
omousey = mousecursor_y;
|
||||
|
||||
if (!firstmenu)
|
||||
{
|
||||
key_dest = key_game;
|
||||
|
@ -1508,6 +1529,8 @@ void M_Complex_Draw(void)
|
|||
return;
|
||||
}
|
||||
|
||||
M_CheckMouseMove();
|
||||
|
||||
for (menu = firstmenu; menu; )
|
||||
{
|
||||
cmenu = menu;
|
||||
|
@ -1603,6 +1626,8 @@ void M_Complex_Key(int key, int unicode)
|
|||
if (!currentmenu)
|
||||
return; //erm...
|
||||
|
||||
M_CheckMouseMove();
|
||||
|
||||
if (currentmenu->key)
|
||||
if (currentmenu->key(key, currentmenu))
|
||||
return;
|
||||
|
|
|
@ -219,11 +219,27 @@ qboolean fakecdactive;
|
|||
qboolean Media_FakeTrack(int i, qboolean loop)
|
||||
{
|
||||
char trackname[512];
|
||||
qboolean found;
|
||||
|
||||
if (i > 0 && i <= 999)
|
||||
{
|
||||
sprintf(trackname, "sound/cdtracks/track%03i.ogg", i);
|
||||
if (COM_FCheckExists(trackname))
|
||||
found = false;
|
||||
if (!found)
|
||||
{
|
||||
sprintf(trackname, "sound/cdtracks/track%03i.ogg", i);
|
||||
found = COM_FCheckExists(trackname);
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
sprintf(trackname, "sound/cdtracks/track%03i.mp3", i);
|
||||
found = COM_FCheckExists(trackname);
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
sprintf(trackname, "sound/cdtracks/track%03i.wav", i);
|
||||
found = COM_FCheckExists(trackname);
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
Media_Clear();
|
||||
strcpy(currenttrack.filename, trackname+6);
|
||||
|
@ -2940,6 +2956,8 @@ void TTS_Say_f(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
|
||||
void Media_Init(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -2967,6 +2985,8 @@ void Media_Init(void)
|
|||
#if defined(WINAVI)
|
||||
Cvar_Register(&capturesoundbits, "AVI capture controls");
|
||||
Cvar_Register(&capturesoundchannels, "AVI capture controls");
|
||||
|
||||
S_RegisterSoundInputPlugin(S_LoadMP3Sound);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -2980,6 +3000,168 @@ void Media_Init(void)
|
|||
|
||||
|
||||
|
||||
#ifdef WINAVI
|
||||
typedef struct
|
||||
{
|
||||
HACMSTREAM acm;
|
||||
|
||||
unsigned int dstbuffer; /*in frames*/
|
||||
unsigned int dstcount; /*in frames*/
|
||||
unsigned int dststart; /*in frames*/
|
||||
qbyte *dstdata;
|
||||
|
||||
unsigned int srcspeed;
|
||||
unsigned int srcwidth;
|
||||
unsigned int srcchannels;
|
||||
unsigned int srcoffset; /*in bytes*/
|
||||
unsigned int srclen; /*in bytes*/
|
||||
qbyte srcdata[1];
|
||||
} mp3decoder_t;
|
||||
|
||||
/*must be thread safe*/
|
||||
sfxcache_t *S_MP3_Locate(sfx_t *sfx, sfxcache_t *buf, int start, int length)
|
||||
{
|
||||
int newlen;
|
||||
if (buf)
|
||||
{
|
||||
mp3decoder_t *dec = sfx->decoder.buf;
|
||||
ACMSTREAMHEADER strhdr;
|
||||
char buffer[8192];
|
||||
extern cvar_t snd_linearresample_stream;
|
||||
int framesz = (dec->srcwidth/8 * dec->srcchannels);
|
||||
|
||||
if (dec->dststart > start)
|
||||
{
|
||||
/*I don't know where the compressed data is for each sample. acm doesn't have a seek. so reset to start, for music this should be the most common rewind anyway*/
|
||||
dec->dststart = 0;
|
||||
dec->dstcount = 0;
|
||||
dec->srcoffset = 0;
|
||||
}
|
||||
|
||||
if (dec->dstcount > snd_speed*6)
|
||||
{
|
||||
int trim = dec->dstcount - snd_speed; //retain a second of buffer in case we have multiple sound devices
|
||||
// if (trim < 0)
|
||||
// trim = 0;
|
||||
/// if (trim > dec->dstcount)
|
||||
// trim = dec->dstcount;
|
||||
memmove(dec->dstdata, dec->dstdata + trim*framesz, (dec->dstcount - trim)*framesz);
|
||||
dec->dststart += trim;
|
||||
dec->dstcount -= trim;
|
||||
}
|
||||
|
||||
while(start+length >= dec->dststart+dec->dstcount)
|
||||
{
|
||||
memset(&strhdr, 0, sizeof(strhdr));
|
||||
strhdr.cbStruct = sizeof(strhdr);
|
||||
strhdr.pbSrc = dec->srcdata + dec->srcoffset;
|
||||
strhdr.cbSrcLength = dec->srclen - dec->srcoffset;
|
||||
strhdr.pbDst = buffer;
|
||||
strhdr.cbDstLength = sizeof(buffer);
|
||||
|
||||
qacmStreamPrepareHeader(dec->acm, &strhdr, 0);
|
||||
qacmStreamConvert(dec->acm, &strhdr, ACM_STREAMCONVERTF_BLOCKALIGN);
|
||||
qacmStreamUnprepareHeader(dec->acm, &strhdr, 0);
|
||||
dec->srcoffset += strhdr.cbSrcLengthUsed;
|
||||
if (!strhdr.cbDstLengthUsed)
|
||||
{
|
||||
if (strhdr.cbSrcLengthUsed)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
newlen = dec->dstcount + (strhdr.cbDstLengthUsed * ((float)snd_speed / dec->srcspeed))/framesz;
|
||||
if (dec->dstbuffer < newlen+64)
|
||||
{
|
||||
dec->dstbuffer = newlen+64 + snd_speed;
|
||||
dec->dstdata = BZ_Realloc(dec->dstdata, dec->dstbuffer*framesz);
|
||||
}
|
||||
|
||||
SND_ResampleStream(strhdr.pbDst,
|
||||
dec->srcspeed,
|
||||
dec->srcwidth/8,
|
||||
dec->srcchannels,
|
||||
strhdr.cbDstLengthUsed / framesz,
|
||||
dec->dstdata+dec->dstcount*framesz,
|
||||
snd_speed,
|
||||
dec->srcwidth/8,
|
||||
dec->srcchannels,
|
||||
snd_linearresample_stream.ival);
|
||||
dec->dstcount = newlen;
|
||||
}
|
||||
|
||||
buf->data = dec->dstdata;
|
||||
buf->length = dec->dstcount;
|
||||
buf->loopstart = -1;
|
||||
buf->numchannels = dec->srcchannels;
|
||||
buf->soundoffset = dec->dststart;
|
||||
buf->speed = snd_speed;
|
||||
buf->width = dec->srcwidth/8;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
{
|
||||
WAVEFORMATEX pcm_format;
|
||||
MPEGLAYER3WAVEFORMAT mp3format;
|
||||
HACMDRIVER drv = NULL;
|
||||
mp3decoder_t *dec;
|
||||
|
||||
char *ext = COM_FileExtension(s->name);
|
||||
if (stricmp(ext, "mp3"))
|
||||
return false;
|
||||
|
||||
dec = BZF_Malloc(sizeof(*dec) + datalen);
|
||||
if (!dec)
|
||||
return false;
|
||||
memcpy(dec->srcdata, data, datalen);
|
||||
dec->srclen = datalen;
|
||||
s->decoder.buf = dec;
|
||||
s->decoder.abort = NULL;
|
||||
s->decoder.decodedata = S_MP3_Locate;
|
||||
|
||||
dec->dstdata = NULL;
|
||||
dec->dstcount = 0;
|
||||
dec->dststart = 0;
|
||||
dec->dstbuffer = 0;
|
||||
dec->srcoffset = 0;
|
||||
|
||||
dec->srcspeed = 44100;
|
||||
dec->srcchannels = 2;
|
||||
dec->srcwidth = 16;
|
||||
|
||||
memset (&pcm_format, 0, sizeof(pcm_format));
|
||||
pcm_format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
pcm_format.nChannels = dec->srcchannels;
|
||||
pcm_format.nSamplesPerSec = dec->srcspeed;
|
||||
pcm_format.nBlockAlign = dec->srcwidth/8*dec->srcchannels;
|
||||
pcm_format.nAvgBytesPerSec = pcm_format.nSamplesPerSec*dec->srcwidth/8*dec->srcchannels;
|
||||
pcm_format.wBitsPerSample = dec->srcwidth;
|
||||
pcm_format.cbSize = 0;
|
||||
|
||||
mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
|
||||
mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
|
||||
mp3format.wfx.nChannels = dec->srcchannels;
|
||||
mp3format.wfx.nAvgBytesPerSec = 128 * (1024 / 8); // not really used but must be one of 64, 96, 112, 128, 160kbps
|
||||
mp3format.wfx.wBitsPerSample = 0; // MUST BE ZERO
|
||||
mp3format.wfx.nBlockAlign = 1; // MUST BE ONE
|
||||
mp3format.wfx.nSamplesPerSec = dec->srcspeed; // 44.1kHz
|
||||
mp3format.fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
|
||||
mp3format.nBlockSize = 522; // voodoo value #1
|
||||
mp3format.nFramesPerBlock = 1; // MUST BE ONE
|
||||
mp3format.nCodecDelay = 1393; // voodoo value #2
|
||||
mp3format.wID = MPEGLAYER3_ID_MPEG;
|
||||
|
||||
if (!qacmStartup() || 0!=qacmStreamOpen(&dec->acm, drv, (WAVEFORMATEX*)&mp3format, &pcm_format, NULL, 0, 0, 0))
|
||||
{
|
||||
Con_Printf("Couldn't init decoder\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
S_MP3_Locate(s, NULL, 0, 100);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ void M_Audio_StartSound (struct menu_s *menu)
|
|||
org[0] = mat[0][0] + 2*(mat[1][0]*(info->testsoundsource->common.posx-320/2) + mat[1][0]*(info->testsoundsource->common.posy-200/2));
|
||||
org[1] = mat[0][1] + 2*(mat[1][1]*(info->testsoundsource->common.posx-320/2) + mat[1][1]*(info->testsoundsource->common.posy-200/2));
|
||||
org[2] = mat[0][2] + 2*(mat[1][2]*(info->testsoundsource->common.posx-320/2) + mat[1][2]*(info->testsoundsource->common.posy-200/2));
|
||||
S_StartSound(-2, 0, S_PrecacheSound("player/pain3.wav"), org, 1, 4, 0);
|
||||
S_StartSound(-2, 0, S_PrecacheSound("player/pain3.wav"), org, 1, 4, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1388,8 +1388,7 @@ static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s
|
|||
|
||||
r_refdef.currentplayernum = csqc_lplayernum;
|
||||
|
||||
VectorCopy (r_refdef.vieworg, cl.viewent[csqc_lplayernum].origin);
|
||||
CalcGunAngle(csqc_lplayernum);
|
||||
V_CalcGunPositionAngle(csqc_lplayernum, V_CalcBob(csqc_lplayernum, true));
|
||||
|
||||
R_RenderView();
|
||||
|
||||
|
@ -2422,7 +2421,7 @@ static void QCBUILTIN PF_cs_sound(progfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
|
||||
sfx = S_PrecacheSound(sample);
|
||||
if (sfx)
|
||||
S_StartSound(-entity->entnum, channel, sfx, entity->v->origin, volume, attenuation, pitchpct);
|
||||
S_StartSound(-entity->entnum, channel, sfx, entity->v->origin, volume, attenuation, 0, pitchpct);
|
||||
};
|
||||
|
||||
static void QCBUILTIN PF_cs_pointsound(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -2446,7 +2445,7 @@ static void QCBUILTIN PF_cs_pointsound(progfuncs_t *prinst, struct globalvars_s
|
|||
|
||||
sfx = S_PrecacheSound(sample);
|
||||
if (sfx)
|
||||
S_StartSound(0, 0, sfx, origin, volume, attenuation, pitchpct);
|
||||
S_StartSound(0, 0, sfx, origin, volume, attenuation, 0, pitchpct);
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_cs_particle(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -2832,14 +2831,14 @@ static void QCBUILTIN PF_cl_te_explosion (progfuncs_t *prinst, struct globalvars
|
|||
|
||||
R_AddStain(pos, -1, -1, -1, 100);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
static void QCBUILTIN PF_cl_te_tarexplosion (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float *pos = G_VECTOR(OFS_PARM0);
|
||||
P_RunParticleEffectType(pos, NULL, 1, pt_tarexplosion);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
static void QCBUILTIN PF_cl_te_wizspike (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -2847,7 +2846,7 @@ static void QCBUILTIN PF_cl_te_wizspike (progfuncs_t *prinst, struct globalvars_
|
|||
if (P_RunParticleEffectType(pos, NULL, 1, pt_wizspike))
|
||||
P_RunParticleEffect (pos, vec3_origin, 20, 30);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0, 0);
|
||||
}
|
||||
static void QCBUILTIN PF_cl_te_knightspike (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -2855,7 +2854,7 @@ static void QCBUILTIN PF_cl_te_knightspike (progfuncs_t *prinst, struct globalva
|
|||
if (P_RunParticleEffectType(pos, NULL, 1, pt_knightspike))
|
||||
P_RunParticleEffect (pos, vec3_origin, 226, 20);
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0, 0);
|
||||
}
|
||||
static void QCBUILTIN PF_cl_te_lavasplash (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -2918,7 +2917,7 @@ static void QCBUILTIN PF_cl_te_explosionquad (progfuncs_t *prinst, struct global
|
|||
dl->channelfade[2] = 0.12;
|
||||
}
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0);
|
||||
}
|
||||
|
||||
//void(vector org, float radius, float lifetime, vector color) te_customflash
|
||||
|
@ -3029,7 +3028,7 @@ static void QCBUILTIN PF_cl_te_explosionrgb (progfuncs_t *prinst, struct globalv
|
|||
dl->channelfade[2] = 0;
|
||||
}
|
||||
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, org, 1, 1, 0);
|
||||
S_StartSound (-2, 0, cl_sfx_r_exp3, org, 1, 1, 0, 0);
|
||||
}
|
||||
static void QCBUILTIN PF_cl_te_particlerain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
|
|
@ -929,9 +929,18 @@ void QCBUILTIN PF_cl_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
{
|
||||
float *ret = G_VECTOR(OFS_RETURN);
|
||||
extern int mousemove_x, mousemove_y;
|
||||
extern int mousecursor_x, mousecursor_y;
|
||||
|
||||
ret[0] = mousemove_x;
|
||||
ret[1] = mousemove_y;
|
||||
if (Key_MouseShouldBeFree())
|
||||
{
|
||||
ret[0] = mousecursor_x;
|
||||
ret[1] = mousecursor_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret[0] = mousemove_x;
|
||||
ret[1] = mousemove_y;
|
||||
}
|
||||
|
||||
mousemove_x=0;
|
||||
mousemove_y=0;
|
||||
|
|
|
@ -139,6 +139,16 @@ static void DSOUND_Shutdown (soundcardinfo_t *sc)
|
|||
dshandle_t *dh = sc->handle;
|
||||
if (!dh)
|
||||
return;
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
if (sc->thread)
|
||||
{
|
||||
sc->selfpainting = false;
|
||||
Sys_WaitOnThread(sc->thread);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
sc->handle = NULL;
|
||||
#ifdef _IKsPropertySet_
|
||||
if (dh->EaxKsPropertiesSet)
|
||||
|
@ -516,8 +526,23 @@ static void DSOUND_Submit(soundcardinfo_t *sc, int start, int end)
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
int GetSoundtime(soundcardinfo_t *sc);
|
||||
static int DSOUND_Thread(void *arg)
|
||||
{
|
||||
soundcardinfo_t *sc = arg;
|
||||
while(sc->selfpainting)
|
||||
{
|
||||
S_MixerThread(sc);
|
||||
/* Quote:
|
||||
On NT (Win2K and XP) the cursors in SW buffers (and HW buffers on some devices) move in 10ms increments, so calling GetCurrentPosition() every 10ms is ideal.
|
||||
Calling it more often than every 5ms will cause some perf degradation.
|
||||
*/
|
||||
Sleep(9);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -895,6 +920,14 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
sc->selfpainting = true;
|
||||
sc->thread = Sys_CreateThread(DSOUND_Thread, sc, THREADP_HIGHEST, 0);
|
||||
if (!sc->thread)
|
||||
sc->selfpainting = false; /*oh well*/
|
||||
#endif
|
||||
|
||||
return SND_LOADED;
|
||||
}
|
||||
int (*pDSOUND_InitCard) (soundcardinfo_t *sc, int cardnum) = &DSOUND_InitCard;
|
||||
|
|
|
@ -21,14 +21,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
void S_Play(void);
|
||||
void S_PlayVol(void);
|
||||
void S_SoundList(void);
|
||||
void S_Update_(soundcardinfo_t *sc);
|
||||
static void S_Play(void);
|
||||
static void S_PlayVol(void);
|
||||
static void S_SoundList_f(void);
|
||||
static void S_Update_(soundcardinfo_t *sc);
|
||||
void S_StopAllSounds(qboolean clear);
|
||||
void S_StopAllSoundsC(void);
|
||||
static void S_StopAllSounds_f (void);
|
||||
|
||||
void S_UpdateCard(soundcardinfo_t *sc);
|
||||
static void S_UpdateCard(soundcardinfo_t *sc);
|
||||
static void S_ClearBuffer (soundcardinfo_t *sc);
|
||||
|
||||
// =======================================================================
|
||||
// Internal sound data & structures
|
||||
|
@ -59,7 +60,7 @@ int desired_bits = 16;
|
|||
|
||||
int sound_started=0;
|
||||
|
||||
cvar_t bgmvolume = CVARFD( "musicvolume", "0", CVAR_ARCHIVE,
|
||||
cvar_t bgmvolume = CVARAFD( "musicvolume", "0", "bgmvolume", CVAR_ARCHIVE,
|
||||
"Volume level for background music.");
|
||||
cvar_t volume = CVARFD( "volume", "0.7", CVAR_ARCHIVE,
|
||||
"Main volume level for all engine sound.");
|
||||
|
@ -101,6 +102,8 @@ cvar_t snd_playersoundvolume = CVARAFD( "s_localvolume", "1",
|
|||
"snd_localvolume", 0,
|
||||
"Sound level for sounds local or originating from the player such as firing and pain sounds."); //sugested by crunch
|
||||
|
||||
cvar_t snd_playbackrate = CVARFD( "snd_playbackrate", "1", CVAR_CHEAT, "Debugging cvar that changes the playback rate of all new sounds.");
|
||||
|
||||
cvar_t snd_linearresample = CVARAF( "s_linearresample", "1",
|
||||
"snd_linearresample", 0);
|
||||
cvar_t snd_linearresample_stream = CVARAF( "s_linearresample_stream", "0",
|
||||
|
@ -124,7 +127,24 @@ cvar_t cl_voip_micamp = CVARAFDC("cl_voip_micamp", "2", NULL, CVAR_ARCHIVE, "Amp
|
|||
#endif
|
||||
|
||||
extern vfsfile_t *rawwritefile;
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
void *mixermutex;
|
||||
void S_LockMixer(void)
|
||||
{
|
||||
Sys_LockMutex(mixermutex);
|
||||
}
|
||||
void S_UnlockMixer(void)
|
||||
{
|
||||
Sys_UnlockMutex(mixermutex);
|
||||
}
|
||||
#else
|
||||
void S_LockMixer(void)
|
||||
{
|
||||
}
|
||||
void S_UnlockMixer(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void S_AmbientOff (void)
|
||||
{
|
||||
|
@ -871,13 +891,12 @@ void SNDDMA_SetUnderWater(qboolean underwater)
|
|||
//so that the video code can call it directly without flushing the models it's just loaded.
|
||||
void S_DoRestart (void)
|
||||
{
|
||||
S_StopAllSounds (true);
|
||||
S_Shutdown();
|
||||
|
||||
if (nosound.ival)
|
||||
return;
|
||||
|
||||
S_StopAllSounds (true);
|
||||
|
||||
S_Shutdown();
|
||||
sound_started = 0;
|
||||
S_Startup();
|
||||
|
||||
ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav");
|
||||
|
@ -888,8 +907,6 @@ void S_DoRestart (void)
|
|||
|
||||
void S_Restart_f (void)
|
||||
{
|
||||
Cache_Flush();//forget the old sounds.
|
||||
|
||||
S_DoRestart();
|
||||
}
|
||||
|
||||
|
@ -1020,8 +1037,8 @@ void S_Init (void)
|
|||
Cmd_AddCommand("play", S_Play);
|
||||
Cmd_AddCommand("play2", S_Play);
|
||||
Cmd_AddCommand("playvol", S_PlayVol);
|
||||
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
|
||||
Cmd_AddCommand("soundlist", S_SoundList);
|
||||
Cmd_AddCommand("stopsound", S_StopAllSounds_f);
|
||||
Cmd_AddCommand("soundlist", S_SoundList_f);
|
||||
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
||||
|
||||
Cmd_AddCommand("snd_restart", S_Restart_f);
|
||||
|
@ -1044,6 +1061,7 @@ void S_Init (void)
|
|||
Cvar_Register(&snd_speakers, "Sound controls");
|
||||
Cvar_Register(&snd_buffersize, "Sound controls");
|
||||
Cvar_Register(&snd_samplebits, "Sound controls");
|
||||
Cvar_Register(&snd_playbackrate, "Sound controls");
|
||||
|
||||
#ifdef VOICECHAT
|
||||
Cvar_Register(&cl_voip_send, "Voice Chat");
|
||||
|
@ -1067,6 +1085,10 @@ void S_Init (void)
|
|||
Cvar_Register(&snd_linearresample, "Sound controls");
|
||||
Cvar_Register(&snd_linearresample_stream, "Sound controls");
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
mixermutex = Sys_CreateMutex();
|
||||
#endif
|
||||
|
||||
#ifdef AVAIL_OPENAL
|
||||
OpenAL_CvarInit();
|
||||
#endif
|
||||
|
@ -1164,6 +1186,7 @@ void S_Shutdown(void)
|
|||
}
|
||||
|
||||
sound_started = 0;
|
||||
S_Purge(false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1175,6 +1198,7 @@ void S_Shutdown(void)
|
|||
==================
|
||||
S_FindName
|
||||
|
||||
also touches it
|
||||
==================
|
||||
*/
|
||||
sfx_t *S_FindName (char *name)
|
||||
|
@ -1192,6 +1216,7 @@ sfx_t *S_FindName (char *name)
|
|||
for (i=0 ; i < num_sfx ; i++)
|
||||
if (!Q_strcmp(known_sfx[i].name, name))
|
||||
{
|
||||
known_sfx[i].touched = true;
|
||||
return &known_sfx[i];
|
||||
}
|
||||
|
||||
|
@ -1200,12 +1225,45 @@ sfx_t *S_FindName (char *name)
|
|||
|
||||
sfx = &known_sfx[i];
|
||||
strcpy (sfx->name, name);
|
||||
known_sfx[i].touched = true;
|
||||
|
||||
num_sfx++;
|
||||
|
||||
return sfx;
|
||||
}
|
||||
|
||||
void S_Purge(qboolean retaintouched)
|
||||
{
|
||||
sfx_t *sfx;
|
||||
int i;
|
||||
|
||||
S_LockMixer();
|
||||
for (i=0 ; i < num_sfx ; i++)
|
||||
{
|
||||
sfx = &known_sfx[i];
|
||||
|
||||
/*don't purge the file if its still relevent*/
|
||||
if (retaintouched && sfx->touched)
|
||||
continue;
|
||||
|
||||
/*nothing to do if there's no data within*/
|
||||
if (!sfx->decoder.buf)
|
||||
continue;
|
||||
|
||||
/*stop the decoder first*/
|
||||
if (sfx->decoder.abort)
|
||||
sfx->decoder.abort(sfx);
|
||||
|
||||
/*if there's any data associated still, kill it. if present, it should be a single sfxcache_t (with data in same alloc)*/
|
||||
if (sfx->decoder.buf)
|
||||
{
|
||||
BZ_Free(sfx->decoder.buf);
|
||||
sfx->decoder.buf = NULL;
|
||||
}
|
||||
}
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
void S_ResetFailedLoad(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -1213,6 +1271,12 @@ void S_ResetFailedLoad(void)
|
|||
known_sfx[i].failedload = false;
|
||||
}
|
||||
|
||||
void S_UntouchAll(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0 ; i < num_sfx ; i++)
|
||||
known_sfx[i].touched = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -1222,13 +1286,10 @@ S_TouchSound
|
|||
*/
|
||||
void S_TouchSound (char *name)
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
if (!sound_started)
|
||||
return;
|
||||
|
||||
sfx = S_FindName (name);
|
||||
Cache_Check (&sfx->cache);
|
||||
S_FindName (name);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1264,19 +1325,19 @@ SND_PickChannel
|
|||
channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel)
|
||||
{
|
||||
int ch_idx;
|
||||
int first_to_die;
|
||||
int life_left;
|
||||
int oldestpos;
|
||||
int oldest;
|
||||
|
||||
// Check for replacement sound, or find the best one to replace
|
||||
first_to_die = -1;
|
||||
life_left = 0x7fffffff;
|
||||
oldest = -1;
|
||||
oldestpos = -1;
|
||||
for (ch_idx=DYNAMIC_FIRST; ch_idx < DYNAMIC_STOP ; ch_idx++)
|
||||
{
|
||||
if (entchannel != 0 // channel 0 never overrides
|
||||
&& sc->channel[ch_idx].entnum == entnum
|
||||
&& (sc->channel[ch_idx].entchannel == entchannel || entchannel == -1))
|
||||
{ // always override sound from same entity
|
||||
first_to_die = ch_idx;
|
||||
oldest = ch_idx;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1284,22 +1345,27 @@ channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel)
|
|||
if (sc->channel[ch_idx].entnum == cl.playernum[0]+1 && entnum != cl.playernum[0]+1 && sc->channel[ch_idx].sfx)
|
||||
continue;
|
||||
|
||||
if (sc->channel[ch_idx].end < life_left)
|
||||
if (!sc->channel[ch_idx].sfx)
|
||||
{
|
||||
life_left = sc->channel[ch_idx].end;
|
||||
first_to_die = ch_idx;
|
||||
oldestpos = 0x7fffffff;
|
||||
oldest = ch_idx;
|
||||
}
|
||||
}
|
||||
else if (sc->channel[ch_idx].pos > oldestpos)
|
||||
{
|
||||
oldestpos = sc->channel[ch_idx].pos;
|
||||
oldest = ch_idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (first_to_die == -1)
|
||||
if (oldest == -1)
|
||||
return NULL;
|
||||
|
||||
if (sc->channel[first_to_die].sfx)
|
||||
sc->channel[first_to_die].sfx = NULL;
|
||||
if (sc->channel[oldest].sfx)
|
||||
sc->channel[oldest].sfx = NULL;
|
||||
|
||||
if (sc->total_chans <= first_to_die)
|
||||
sc->total_chans = first_to_die+1;
|
||||
return &sc->channel[first_to_die];
|
||||
if (sc->total_chans <= oldest)
|
||||
sc->total_chans = oldest+1;
|
||||
return &sc->channel[oldest];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1355,10 +1421,9 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch)
|
|||
// Start a sound effect
|
||||
// =======================================================================
|
||||
|
||||
void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, int startpos, float pitchadj)
|
||||
static void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, int startpos, float pitchadj)
|
||||
{
|
||||
channel_t *target_chan, *check;
|
||||
sfxcache_t *scache;
|
||||
int vol;
|
||||
int ch_idx;
|
||||
int skip;
|
||||
|
@ -1375,6 +1440,8 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
|
|||
if (pitchadj <= 0)
|
||||
pitchadj = 100;
|
||||
|
||||
pitchadj *= snd_playbackrate.value * (cls.state?cl.gamespeed:1);
|
||||
|
||||
vol = fvol*255;
|
||||
|
||||
// pick a channel to play on
|
||||
|
@ -1402,22 +1469,17 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
|
|||
return; // not audible at all
|
||||
|
||||
// new channel
|
||||
scache = S_LoadSound (sfx);
|
||||
if (!scache)
|
||||
if (!S_LoadSound (sfx))
|
||||
{
|
||||
target_chan->sfx = NULL;
|
||||
return; // couldn't load the sound's data
|
||||
}
|
||||
|
||||
if (scache->length > snd_speed*20 && !ruleset_allow_overlongsounds.ival)
|
||||
{
|
||||
Con_DPrintf("Shortening over-long sound effect\n");
|
||||
startpos = scache->length - snd_speed*10;
|
||||
}
|
||||
target_chan->sfx = sfx;
|
||||
target_chan->rate = ((1<<PITCHSHIFT) * pitchadj) / 100; /*pitchadj is a percentage*/
|
||||
if (target_chan->rate < 1) /*make sure the rate won't crash us*/
|
||||
target_chan->rate = 1;
|
||||
target_chan->pos = startpos*target_chan->rate;
|
||||
target_chan->end = sc->paintedtime + ((scache->length - startpos)<<PITCHSHIFT)/target_chan->rate;
|
||||
target_chan->looping = false;
|
||||
|
||||
// if an identical sound has also been started this frame, offset the pos
|
||||
|
@ -1430,10 +1492,7 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
|
|||
if (check->sfx == sfx && !check->pos)
|
||||
{
|
||||
skip = rand () % (int)(0.1*sc->sn.speed);
|
||||
if (skip >= target_chan->end)
|
||||
skip = target_chan->end - 1;
|
||||
target_chan->pos += skip*target_chan->rate;
|
||||
target_chan->end -= skip;
|
||||
target_chan->pos -= skip*target_chan->rate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1442,26 +1501,17 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
|
|||
sc->ChannelUpdate(sc, target_chan, true);
|
||||
}
|
||||
|
||||
void S_StartSoundDelayed(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, float timeofs)
|
||||
void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, float timeofs, float pitchadj)
|
||||
{
|
||||
soundcardinfo_t *sc;
|
||||
|
||||
if (!sfx || !*sfx->name) //no named sounds would need specific starting.
|
||||
return;
|
||||
|
||||
S_LockMixer();
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
S_StartSoundCard(sc, entnum, entchannel, sfx, origin, fvol, attenuation, -(int)(timeofs * sc->sn.speed), 0);
|
||||
}
|
||||
|
||||
void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, float pitchadj)
|
||||
{
|
||||
soundcardinfo_t *sc;
|
||||
|
||||
if (!sfx || !*sfx->name) //no named sounds would need specific starting.
|
||||
return;
|
||||
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
S_StartSoundCard(sc, entnum, entchannel, sfx, origin, fvol, attenuation, 0, pitchadj);
|
||||
S_StartSoundCard(sc, entnum, entchannel, sfx, origin, fvol, attenuation, -(int)(timeofs * sc->sn.speed), pitchadj);
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
qboolean S_IsPlayingSomewhere(sfx_t *s)
|
||||
|
@ -1477,7 +1527,7 @@ qboolean S_IsPlayingSomewhere(sfx_t *s)
|
|||
return false;
|
||||
}
|
||||
|
||||
void S_StopSoundCard(soundcardinfo_t *sc, int entnum, int entchannel)
|
||||
static void S_StopSoundCard(soundcardinfo_t *sc, int entnum, int entchannel)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1486,12 +1536,11 @@ void S_StopSoundCard(soundcardinfo_t *sc, int entnum, int entchannel)
|
|||
if (sc->channel[i].entnum == entnum
|
||||
&& (!entchannel || sc->channel[i].entchannel == entchannel))
|
||||
{
|
||||
sc->channel[i].end = 0;
|
||||
sc->channel[i].sfx = NULL;
|
||||
if (sc->ChannelUpdate)
|
||||
sc->ChannelUpdate(sc, &sc->channel[i], true);
|
||||
if (entchannel)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1499,8 +1548,10 @@ void S_StopSoundCard(soundcardinfo_t *sc, int entnum, int entchannel)
|
|||
void S_StopSound(int entnum, int entchannel)
|
||||
{
|
||||
soundcardinfo_t *sc;
|
||||
S_LockMixer();
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
S_StopSoundCard(sc, entnum, entchannel);
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
void S_StopAllSounds(qboolean clear)
|
||||
|
@ -1510,21 +1561,21 @@ void S_StopAllSounds(qboolean clear)
|
|||
|
||||
soundcardinfo_t *sc;
|
||||
|
||||
if (!sound_started)
|
||||
return;
|
||||
S_LockMixer();
|
||||
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
{
|
||||
if (!sound_started)
|
||||
return;
|
||||
|
||||
|
||||
for (i=0 ; i<sc->total_chans ; i++)
|
||||
if (sc->channel[i].sfx)
|
||||
{
|
||||
s = sc->channel[i].sfx;
|
||||
sc->channel[i].sfx = NULL;
|
||||
if (s->decoder)
|
||||
if (s->decoder.abort)
|
||||
if (!S_IsPlayingSomewhere(s)) //if we aint playing it elsewhere, free it compleatly.
|
||||
{
|
||||
s->decoder->abort(s);
|
||||
s->decoder.abort(s);
|
||||
}
|
||||
if (sc->ChannelUpdate)
|
||||
sc->ChannelUpdate(sc, &sc->channel[i], true);
|
||||
|
@ -1537,14 +1588,16 @@ void S_StopAllSounds(qboolean clear)
|
|||
if (clear)
|
||||
S_ClearBuffer (sc);
|
||||
}
|
||||
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
void S_StopAllSoundsC (void)
|
||||
static void S_StopAllSounds_f (void)
|
||||
{
|
||||
S_StopAllSounds (true);
|
||||
}
|
||||
|
||||
void S_ClearBuffer (soundcardinfo_t *sc)
|
||||
static void S_ClearBuffer (soundcardinfo_t *sc)
|
||||
{
|
||||
void *buffer;
|
||||
|
||||
|
@ -1574,12 +1627,13 @@ S_StaticSound
|
|||
void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
|
||||
{
|
||||
channel_t *ss;
|
||||
sfxcache_t *scache;
|
||||
soundcardinfo_t *scard;
|
||||
|
||||
if (!sfx)
|
||||
return;
|
||||
|
||||
S_LockMixer();
|
||||
|
||||
for (scard = sndcardinfo; scard; scard = scard->next)
|
||||
{
|
||||
if (scard->total_chans == MAX_CHANNELS)
|
||||
|
@ -1588,26 +1642,19 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!S_LoadSound (sfx))
|
||||
break;
|
||||
|
||||
ss = &scard->channel[scard->total_chans];
|
||||
scard->total_chans++;
|
||||
|
||||
scache = S_LoadSound (sfx);
|
||||
if (!scache)
|
||||
return;
|
||||
|
||||
if (scache->loopstart == -1)
|
||||
{
|
||||
Con_Printf ("Ambient sound %s not looped\n", sfx->name);
|
||||
scache->loopstart = 0;
|
||||
}
|
||||
|
||||
ss->entnum = -2;
|
||||
ss->sfx = sfx;
|
||||
ss->rate = 1<<PITCHSHIFT;
|
||||
VectorCopy (origin, ss->origin);
|
||||
ss->master_vol = vol;
|
||||
ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist;
|
||||
ss->end = scard->paintedtime + (scache->length<<PITCHSHIFT)/ss->rate;
|
||||
ss->pos = 0;
|
||||
ss->looping = true;
|
||||
|
||||
SND_Spatialize (scard, ss);
|
||||
|
@ -1615,6 +1662,8 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
|
|||
if (scard->ChannelUpdate)
|
||||
scard->ChannelUpdate(scard, ss, true);
|
||||
}
|
||||
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1637,16 +1686,16 @@ void S_Music_Clear(sfx_t *onlyifsample)
|
|||
if (onlyifsample && s != onlyifsample)
|
||||
continue;
|
||||
|
||||
sc->channel[i].end = 0;
|
||||
sc->channel[i].pos = 0;
|
||||
sc->channel[i].sfx = NULL;
|
||||
|
||||
if (s)
|
||||
if (s->decoder)
|
||||
if (s->decoder.abort)
|
||||
if (!S_IsPlayingSomewhere(s)) //if we aint playing it elsewhere, free it compleatly.
|
||||
{
|
||||
s->decoder->abort(s);
|
||||
if (s->cache.data)
|
||||
Cache_Free(&s->cache);
|
||||
s->decoder.abort(s);
|
||||
// if (s->cache.data)
|
||||
// Cache_Free(&s->cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1660,11 +1709,9 @@ void S_Music_Seek(float time)
|
|||
for (sc = sndcardinfo; sc; sc=sc->next)
|
||||
{
|
||||
sc->channel[i].pos += sc->sn.speed*time * sc->channel[i].rate;
|
||||
sc->channel[i].end += sc->sn.speed*time;
|
||||
|
||||
if (sc->channel[i].pos < 0)
|
||||
{ //clamp to the start of the track
|
||||
sc->channel[i].end -= sc->channel[i].pos/sc->channel[i].rate;
|
||||
sc->channel[i].pos=0;
|
||||
}
|
||||
//if we seek over the end, ignore it. The sound playing code will spot that.
|
||||
|
@ -1696,21 +1743,17 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc)
|
|||
if (!chan->sfx)
|
||||
{
|
||||
char *nexttrack = Media_NextTrack(i-MUSIC_FIRST);
|
||||
sfxcache_t *scache;
|
||||
sfx_t *newmusic;
|
||||
|
||||
if (nexttrack && *nexttrack)
|
||||
{
|
||||
newmusic = S_PrecacheSound(nexttrack);
|
||||
|
||||
|
||||
scache = S_LoadSound (newmusic);
|
||||
if (scache)
|
||||
if (!newmusic->failedload)
|
||||
{
|
||||
chan->sfx = newmusic;
|
||||
chan->rate = 1<<PITCHSHIFT;
|
||||
chan->pos = 0;
|
||||
chan->end = sc->paintedtime + ((scache->length+1000)<<PITCHSHIFT)/chan->rate;
|
||||
chan->vol[0] = chan->vol[1] = chan->vol[2] = chan->vol[3] = chan->vol[4] = chan->vol[5] = chan->master_vol = 100;
|
||||
}
|
||||
}
|
||||
|
@ -1799,7 +1842,7 @@ void S_GetListenerInfo(float *origin, float *forward, float *right, float *up)
|
|||
VectorCopy(listener_up, up);
|
||||
}
|
||||
|
||||
void S_UpdateCard(soundcardinfo_t *sc)
|
||||
static void S_UpdateCard(soundcardinfo_t *sc)
|
||||
{
|
||||
int i, j;
|
||||
int total;
|
||||
|
@ -1899,6 +1942,16 @@ void S_UpdateCard(soundcardinfo_t *sc)
|
|||
}
|
||||
|
||||
// mix some sound
|
||||
|
||||
if (sc->selfpainting)
|
||||
return;
|
||||
|
||||
if (snd_blocked > 0)
|
||||
{
|
||||
if (!sc->inactive_sound)
|
||||
return;
|
||||
}
|
||||
|
||||
S_Update_(sc);
|
||||
}
|
||||
|
||||
|
@ -1939,8 +1992,10 @@ void S_Update (void)
|
|||
{
|
||||
soundcardinfo_t *sc;
|
||||
|
||||
S_LockMixer();
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
S_UpdateCard(sc);
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
void S_ExtraUpdate (void)
|
||||
|
@ -1957,27 +2012,31 @@ void S_ExtraUpdate (void)
|
|||
if (snd_noextraupdate.ival)
|
||||
return; // don't pollute timings
|
||||
|
||||
S_LockMixer();
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
{
|
||||
if (sc->selfpainting)
|
||||
continue;
|
||||
|
||||
if (snd_blocked > 0)
|
||||
{
|
||||
if (!sc->inactive_sound)
|
||||
continue;
|
||||
}
|
||||
|
||||
S_Update_(sc);
|
||||
}
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void S_Update_(soundcardinfo_t *sc)
|
||||
static void S_Update_(soundcardinfo_t *sc)
|
||||
{
|
||||
int soundtime; /*in pairs*/
|
||||
unsigned endtime;
|
||||
int samps;
|
||||
|
||||
if (sc->selfpainting)
|
||||
return;
|
||||
|
||||
if (snd_blocked > 0)
|
||||
{
|
||||
if (!sc->inactive_sound)
|
||||
return;
|
||||
}
|
||||
|
||||
// Updates DMA time
|
||||
soundtime = GetSoundtime(sc);
|
||||
|
||||
|
@ -2016,6 +2075,17 @@ void S_Update_(soundcardinfo_t *sc)
|
|||
sc->Submit(sc, soundtime, endtime);
|
||||
}
|
||||
|
||||
/*
|
||||
called periodically by dedicated mixer threads.
|
||||
do any blocking calls AFTER this returns. note that this means you can't use the Submit/unlock method to submit blocking audio.
|
||||
*/
|
||||
void S_MixerThread(soundcardinfo_t *sc)
|
||||
{
|
||||
S_LockMixer();
|
||||
S_Update_(sc);
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -2026,7 +2096,6 @@ console functions
|
|||
|
||||
void S_Play(void)
|
||||
{
|
||||
// static int hash=345;
|
||||
int i;
|
||||
char name[256];
|
||||
sfx_t *sfx;
|
||||
|
@ -2042,15 +2111,13 @@ void S_Play(void)
|
|||
else
|
||||
Q_strncpyz(name, Cmd_Argv(i), sizeof(name));
|
||||
sfx = S_PrecacheSound(name);
|
||||
S_StartSound(cl.playernum[0]+1, -1, sfx, vec3_origin, 1.0, 0.0, 0);
|
||||
// hash++;
|
||||
S_StartSound(cl.playernum[0]+1, -1, sfx, vec3_origin, 1.0, 0.0, 0, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void S_PlayVol(void)
|
||||
{
|
||||
// static int hash=543;
|
||||
int i;
|
||||
float vol;
|
||||
char name[256];
|
||||
|
@ -2068,14 +2135,14 @@ void S_PlayVol(void)
|
|||
Q_strncpy(name, Cmd_Argv(i), sizeof(name));
|
||||
sfx = S_PrecacheSound(name);
|
||||
vol = Q_atof(Cmd_Argv(i+1));
|
||||
S_StartSound(cl.playernum[0]+1, -1, sfx, vec3_origin, vol, 0.0, 0);
|
||||
// hash;
|
||||
S_StartSound(cl.playernum[0]+1, -1, sfx, vec3_origin, vol, 0.0, 0, 0);
|
||||
i+=2;
|
||||
}
|
||||
}
|
||||
|
||||
void S_SoundList(void)
|
||||
void S_SoundList_f(void)
|
||||
{
|
||||
/*
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
sfxcache_t *sc;
|
||||
|
@ -2084,6 +2151,11 @@ void S_SoundList(void)
|
|||
total = 0;
|
||||
for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
|
||||
{
|
||||
if (!sfx->decoder)
|
||||
{
|
||||
Con_Printf("S( ) : %s\n", sfx->name);
|
||||
continue;
|
||||
}
|
||||
sc = Cache_Check (&sfx->cache);
|
||||
if (!sc)
|
||||
continue;
|
||||
|
@ -2093,9 +2165,10 @@ void S_SoundList(void)
|
|||
Con_Printf ("L");
|
||||
else
|
||||
Con_Printf (" ");
|
||||
Con_Printf("(%2db) %6i : %s\n",sc->width*8, size, sfx->name);
|
||||
Con_Printf("(%2db%2ic) %6i : %s\n",sc->width*8, sc->numchannels, size, sfx->name);
|
||||
}
|
||||
Con_Printf ("Total resident: %i\n", total);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -2114,27 +2187,10 @@ void S_LocalSound (char *sound)
|
|||
Con_Printf ("S_LocalSound: can't cache %s\n", sound);
|
||||
return;
|
||||
}
|
||||
S_StartSound (-1, -1, sfx, vec3_origin, 1, 1, 0);
|
||||
S_StartSound (-1, -1, sfx, vec3_origin, 1, 1, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void S_ClearPrecache (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void S_BeginPrecaching (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void S_EndPrecaching (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2145,10 +2201,16 @@ void S_EndPrecaching (void)
|
|||
|
||||
|
||||
typedef struct {
|
||||
sfxdecode_t decoder;
|
||||
|
||||
qboolean inuse;
|
||||
int id;
|
||||
sfx_t sfx;
|
||||
sfxcache_t *sfxcache;
|
||||
|
||||
int numchannels;
|
||||
int width;
|
||||
int length;
|
||||
void *data;
|
||||
} streaming_t;
|
||||
#define MAX_RAW_SOURCES (MAX_CLIENTS+1)
|
||||
streaming_t s_streamers[MAX_RAW_SOURCES];
|
||||
|
@ -2158,6 +2220,23 @@ void S_ClearRaw(void)
|
|||
memset(s_streamers, 0, sizeof(s_streamers));
|
||||
}
|
||||
|
||||
//returns an sfxcache_t stating where the data is
|
||||
sfxcache_t *S_Raw_Locate(sfx_t *sfx, sfxcache_t *buf, int start, int length)
|
||||
{
|
||||
streaming_t *s = sfx->decoder.buf;
|
||||
if (buf)
|
||||
{
|
||||
buf->data = s->data;
|
||||
buf->length = s->length;
|
||||
buf->loopstart = -1;
|
||||
buf->numchannels = s->numchannels;
|
||||
buf->soundoffset = 0;
|
||||
buf->speed = snd_speed;
|
||||
buf->width = s->width;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
//streaming audio. //this is useful when there is one source, and the sound is to be played with no attenuation
|
||||
void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, int width)
|
||||
{
|
||||
|
@ -2168,7 +2247,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
|||
int spare;
|
||||
int outsamples;
|
||||
double speedfactor;
|
||||
sfxcache_t *newcache;
|
||||
qbyte *newcache;
|
||||
streaming_t *s, *free=NULL;
|
||||
for (s = s_streamers, i = 0; i < MAX_RAW_SOURCES; i++, s++)
|
||||
{
|
||||
|
@ -2185,9 +2264,9 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
|||
{
|
||||
if (i == MAX_RAW_SOURCES)
|
||||
return; //wierd, it wasn't even playing.
|
||||
s->sfxcache->loopstart = -1; //stop mixing it
|
||||
s->inuse = false;
|
||||
|
||||
S_LockMixer();
|
||||
for (si = sndcardinfo; si; si=si->next)
|
||||
for (i = 0; i < si->total_chans; i++)
|
||||
if (si->channel[i].sfx == &s->sfx)
|
||||
|
@ -2195,43 +2274,47 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
|||
si->channel[i].sfx = NULL;
|
||||
break;
|
||||
}
|
||||
BZ_Free(s->sfxcache);
|
||||
BZ_Free(s->data);
|
||||
S_UnlockMixer();
|
||||
return;
|
||||
}
|
||||
if (i == MAX_RAW_SOURCES) //whoops.
|
||||
if (i == MAX_RAW_SOURCES || !s->inuse) //whoops.
|
||||
{
|
||||
if (!free)
|
||||
if (i == MAX_RAW_SOURCES)
|
||||
{
|
||||
Con_Printf("No free audio streams\n");
|
||||
return;
|
||||
if (!free)
|
||||
{
|
||||
Con_Printf("No free audio streams\n");
|
||||
return;
|
||||
}
|
||||
s = free;
|
||||
}
|
||||
s = free;
|
||||
free->id = sourceid;
|
||||
free->inuse = true;
|
||||
free->sfx.cache.fake = true;
|
||||
strcpy(free->sfx.name, "");
|
||||
free->sfxcache = BZ_Malloc(sizeof(sfxcache_t));
|
||||
free->sfx.cache.data = free->sfxcache;
|
||||
free->sfxcache->speed = snd_speed;
|
||||
free->sfxcache->numchannels = channels;
|
||||
free->sfxcache->width = width;
|
||||
free->sfxcache->loopstart = -1;
|
||||
free->sfxcache->length = 0;
|
||||
s->sfx.decoder.buf = s;
|
||||
s->sfx.decoder.decodedata = S_Raw_Locate;
|
||||
s->numchannels = channels;
|
||||
s->width = width;
|
||||
s->data = NULL;
|
||||
s->length = 0;
|
||||
|
||||
s->id = sourceid;
|
||||
s->inuse = true;
|
||||
strcpy(s->sfx.name, "raw stream");
|
||||
// Con_Printf("Added new raw stream\n");
|
||||
}
|
||||
if (s->sfxcache->width != width || s->sfxcache->numchannels != channels || s->sfxcache->speed != snd_speed)
|
||||
S_LockMixer();
|
||||
|
||||
if (s->width != width || s->numchannels != channels)
|
||||
{
|
||||
s->sfxcache->width = width;
|
||||
s->sfxcache->numchannels = channels;
|
||||
s->sfxcache->speed = snd_speed;
|
||||
s->sfxcache->length = 0;
|
||||
s->width = width;
|
||||
s->numchannels = channels;
|
||||
s->length = 0;
|
||||
// Con_Printf("Restarting raw stream\n");
|
||||
}
|
||||
|
||||
speedfactor = (double)speed/snd_speed;
|
||||
outsamples = samples/speedfactor;
|
||||
|
||||
oldlength = s->sfxcache->length;
|
||||
oldlength = s->length;
|
||||
|
||||
prepadl = 0x7fffffff;
|
||||
for (si = sndcardinfo; si; si=si->next) //make sure all cards are playing, and that we still get a prepad if just one is.
|
||||
|
@ -2261,7 +2344,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
|||
{
|
||||
if (prepadl < 0)
|
||||
prepadl = 0;
|
||||
spare = s->sfxcache->length - prepadl;
|
||||
spare = s->length - prepadl;
|
||||
if (spare < 0) //remaining samples since last time
|
||||
spare = 0;
|
||||
|
||||
|
@ -2272,18 +2355,17 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
|||
}
|
||||
}
|
||||
|
||||
newcache = BZ_Malloc(sizeof(sfxcache_t) + (spare+outsamples) * (s->sfxcache->numchannels) * s->sfxcache->width);
|
||||
memcpy(newcache, s->sfxcache, sizeof(sfxcache_t));
|
||||
memcpy(newcache->data, s->sfxcache->data + prepadl * (s->sfxcache->numchannels) * s->sfxcache->width, spare * (s->sfxcache->numchannels) * s->sfxcache->width);
|
||||
newcache = BZ_Malloc((spare+outsamples) * (s->numchannels) * s->width);
|
||||
memcpy(newcache, (qbyte*)s->data + prepadl * (s->numchannels) * s->width, spare * (s->numchannels) * s->width);
|
||||
|
||||
BZ_Free(s->sfxcache);
|
||||
s->sfxcache = s->sfx.cache.data = newcache;
|
||||
BZ_Free(s->data);
|
||||
s->data = newcache;
|
||||
|
||||
newcache->length = spare + outsamples;
|
||||
s->length = spare + outsamples;
|
||||
|
||||
{
|
||||
extern cvar_t snd_linearresample_stream;
|
||||
short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
|
||||
short *outpos = (short *)((char*)s->data + spare * (s->numchannels) * s->width);
|
||||
SND_ResampleStream(data,
|
||||
speed,
|
||||
width,
|
||||
|
@ -2291,32 +2373,36 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
|||
samples,
|
||||
outpos,
|
||||
snd_speed,
|
||||
s->sfxcache->width,
|
||||
s->sfxcache->numchannels,
|
||||
s->width,
|
||||
s->numchannels,
|
||||
snd_linearresample_stream.ival);
|
||||
}
|
||||
|
||||
s->sfxcache->loopstart = -1;//s->sfxcache->length;
|
||||
|
||||
for (si = sndcardinfo; si; si=si->next)
|
||||
{
|
||||
for (i = 0; i < si->total_chans; i++)
|
||||
if (si->channel[i].sfx == &s->sfx)
|
||||
{
|
||||
si->channel[i].pos -= prepadl*si->channel[i].rate;
|
||||
si->channel[i].end += outsamples;
|
||||
|
||||
if (si->channel[i].end < si->paintedtime)
|
||||
{
|
||||
if (si->channel[i].pos < 0)
|
||||
si->channel[i].pos = 0;
|
||||
si->channel[i].end = si->paintedtime + s->sfxcache->length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i == si->total_chans) //this one wasn't playing.
|
||||
{
|
||||
/*slight delay to try to avoid frame rate/etc stops/starts*/
|
||||
S_StartSoundCard(si, -1, 0, &s->sfx, r_origin, 1, 32767, -snd_speed*0.02, 0);
|
||||
channel_t *c = SND_PickChannel(si, -1, 0);
|
||||
c->entnum = -1;
|
||||
c->entchannel = 0;
|
||||
c->dist_mult = 0;
|
||||
c->looping = false;
|
||||
c->master_vol = 255;
|
||||
c->pos = 0;
|
||||
c->rate = 1<<PITCHSHIFT;
|
||||
c->sfx = &s->sfx;
|
||||
c->start = 0;
|
||||
SND_Spatialize(si, c);
|
||||
}
|
||||
}
|
||||
S_UnlockMixer();
|
||||
}
|
||||
|
|
|
@ -11,16 +11,22 @@ static soundcardinfo_t *sys_sc = NULL;
|
|||
|
||||
|
||||
|
||||
//transfer the 'dma' buffer into the buffer it requests, called from somewhere outside the game engine, prolly another thread.
|
||||
//transfer the 'dma' buffer into the buffer it requests, called from a dedicated sound thread created by the java code.
|
||||
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_paintaudio(JNIEnv *env, jclass this, jbyteArray stream, jint len)
|
||||
{
|
||||
int offset = 0;
|
||||
soundcardinfo_t *sc = sys_sc;
|
||||
int framesz;
|
||||
// if (!pthread_mutex_lock(&mutex))
|
||||
{
|
||||
soundcardinfo_t *sc = sys_sc;
|
||||
if (sc)
|
||||
{
|
||||
int buffersize = sc->sn.samples*(sc->sn.samplebits/8);
|
||||
int buffersize = sc->sn.samples*sc->sn.samplebits/8;
|
||||
|
||||
int curtime = GetSoundtime(sc);
|
||||
framesz = sc->sn.numchannels * sc->sn.samplebits/8;
|
||||
|
||||
S_PaintChannels (sc, curtime + (len / framesz));
|
||||
|
||||
if (len > buffersize)
|
||||
{
|
||||
|
@ -28,18 +34,21 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_paintaudio(JNIEnv *env, jcl
|
|||
}
|
||||
|
||||
if (len + sc->snd_sent%buffersize > buffersize)
|
||||
{ //buffer will wrap, fill in the rest
|
||||
{ //buffer will wrap, fill in the rest
|
||||
(*env)->SetByteArrayRegion(env, stream, offset, buffersize - (sc->snd_sent%buffersize), (char*)sc->sn.buffer + (sc->snd_sent%buffersize));
|
||||
offset += buffersize - sc->snd_sent%buffersize;
|
||||
sc->snd_sent += buffersize - sc->snd_sent%buffersize;
|
||||
offset += buffersize - (sc->snd_sent%buffersize);
|
||||
sc->snd_sent += buffersize - (sc->snd_sent%buffersize);
|
||||
len -= buffersize - (sc->snd_sent%buffersize);
|
||||
if (len < 0) /*this must be impossible, surely?*/
|
||||
len = 0;
|
||||
}
|
||||
//and finish from the start
|
||||
(*env)->SetByteArrayRegion(env, stream, offset, len, (char*)sc->sn.buffer + (sc->snd_sent%buffersize));
|
||||
offset += len;
|
||||
sc->snd_sent += len;
|
||||
}
|
||||
else
|
||||
offset = len; /*so the playback thread ends up blocked properly*/
|
||||
// pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
return offset;
|
||||
|
@ -58,8 +67,8 @@ static void Droid_Shutdown(soundcardinfo_t *sc)
|
|||
|
||||
static unsigned int Droid_GetDMAPos(soundcardinfo_t *sc)
|
||||
{
|
||||
sc->sn.samplepos = sc->snd_sent / (sc->sn.samplebits/8);
|
||||
return sc->sn.samplepos;
|
||||
sc->sn.samplepos = sc->snd_sent / (sc->sn.samplebits/8);
|
||||
return sc->sn.samplepos;
|
||||
}
|
||||
|
||||
static void Droid_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
|
||||
|
@ -77,7 +86,7 @@ static void Droid_SetUnderWater(soundcardinfo_t *sc, qboolean uw)
|
|||
{
|
||||
}
|
||||
|
||||
static void Droid_Submit(soundcardinfo_t *sc)
|
||||
static void Droid_Submit(soundcardinfo_t *sc, int start, int end)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -88,6 +97,7 @@ static int Droid_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
|
||||
// if (!pthread_mutex_lock(&mutex))
|
||||
{
|
||||
sc->selfpainting = true;
|
||||
sc->sn.speed = 11025;
|
||||
sc->sn.samplebits = 16;
|
||||
sc->sn.numchannels = 1;
|
||||
|
|
|
@ -543,7 +543,7 @@ void SND_ResampleStream (void *in, int inrate, int inwidth, int inchannels, int
|
|||
ResampleSfx
|
||||
================
|
||||
*/
|
||||
void ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int insamps, int inloopstart, qbyte *data)
|
||||
qboolean ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int insamps, int inloopstart, qbyte *data)
|
||||
{
|
||||
extern cvar_t snd_linearresample;
|
||||
double scale;
|
||||
|
@ -562,16 +562,18 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int insam
|
|||
outwidth = inwidth;
|
||||
len = outsamps * outwidth * inchannels;
|
||||
|
||||
sc = Cache_Alloc (&sfx->cache, len + sizeof(sfxcache_t), sfx->name);
|
||||
sfx->decoder.buf = sc = BZ_Malloc(len + sizeof(sfxcache_t));
|
||||
if (!sc)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
sc->numchannels = inchannels;
|
||||
sc->width = outwidth;
|
||||
sc->speed = snd_speed;
|
||||
sc->length = outsamps;
|
||||
sc->soundoffset = 0;
|
||||
sc->data = (qbyte*)(sc+1);
|
||||
if (inloopstart == -1)
|
||||
sc->loopstart = inloopstart;
|
||||
else
|
||||
|
@ -587,6 +589,8 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int insam
|
|||
sc->width,
|
||||
sc->numchannels,
|
||||
snd_linearresample.ival);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -703,19 +707,19 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
|||
}
|
||||
#endif
|
||||
|
||||
sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
qboolean S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
{
|
||||
wavinfo_t info;
|
||||
|
||||
if (datalen < 4 || strncmp(data, "RIFF", 4))
|
||||
return NULL;
|
||||
return false;
|
||||
|
||||
info = GetWavinfo (s->name, data, datalen);
|
||||
if (info.numchannels < 1 || info.numchannels > 2)
|
||||
{
|
||||
s->failedload = true;
|
||||
Con_Printf ("%s has an unsupported quantity of channels.\n",s->name);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.width == 1)
|
||||
|
@ -723,12 +727,10 @@ sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
|||
else if (info.width == 2)
|
||||
COM_SwapLittleShortBlock((short *)(data + info.dataofs), info.samples*info.numchannels);
|
||||
|
||||
ResampleSfx (s, info.rate, info.numchannels, info.width, info.samples, info.loopstart, data + info.dataofs);
|
||||
|
||||
return Cache_Check(&s->cache);
|
||||
return ResampleSfx (s, info.rate, info.numchannels, info.width, info.samples, info.loopstart, data + info.dataofs);
|
||||
}
|
||||
|
||||
sfxcache_t *S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
qboolean S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
|
||||
S_LoadSound_t AudioInputPlugins[10] =
|
||||
{
|
||||
|
@ -762,29 +764,21 @@ S_LoadSound
|
|||
==============
|
||||
*/
|
||||
|
||||
sfxcache_t *S_LoadSound (sfx_t *s)
|
||||
qboolean S_LoadSound (sfx_t *s)
|
||||
{
|
||||
char stackbuf[65536];
|
||||
char namebuffer[256];
|
||||
qbyte *data;
|
||||
sfxcache_t *sc;
|
||||
int i;
|
||||
size_t result;
|
||||
|
||||
char *name = s->name;
|
||||
|
||||
if (s->failedload)
|
||||
return NULL; //it failed to load once before, don't bother trying again.
|
||||
return false; //it failed to load once before, don't bother trying again.
|
||||
|
||||
// see if still in memory
|
||||
sc = Cache_Check (&s->cache);
|
||||
if (sc)
|
||||
return sc;
|
||||
|
||||
s->decoder = NULL;
|
||||
|
||||
|
||||
|
||||
if (s->decoder.buf)
|
||||
return true;
|
||||
|
||||
if (name[1] == ':' && name[2] == '\\')
|
||||
{
|
||||
|
@ -816,7 +810,7 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
else
|
||||
{
|
||||
Con_SafePrintf ("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -865,7 +859,7 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
//FIXME: check to see if queued for download.
|
||||
Con_DPrintf ("Couldn't load %s\n", namebuffer);
|
||||
s->failedload = true;
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
s->failedload = false;
|
||||
|
@ -874,10 +868,9 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
{
|
||||
if (AudioInputPlugins[i])
|
||||
{
|
||||
sc = AudioInputPlugins[i](s, data, com_filesize, snd_speed);
|
||||
if (sc)
|
||||
if (AudioInputPlugins[i](s, data, com_filesize, snd_speed))
|
||||
{
|
||||
return sc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -886,7 +879,7 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
Con_Printf ("Format not recognised: %s\n", namebuffer);
|
||||
|
||||
s->failedload = true;
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -117,15 +117,16 @@ void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count);
|
|||
|
||||
void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
int end;
|
||||
channel_t *ch;
|
||||
sfxcache_t scachebuf;
|
||||
sfxcache_t *scache;
|
||||
sfx_t *s;
|
||||
int ltime, count;
|
||||
int avail;
|
||||
unsigned int maxlen = ruleset_allow_overlongsounds.ival?0xffffffffu>>PITCHSHIFT:snd_speed*20;
|
||||
|
||||
// sc->rawstart += sc->paintedtime - sc->oldpaintedtime;
|
||||
// sc->oldpaintedtime = sc->paintedtime;
|
||||
while (sc->paintedtime < endtime)
|
||||
{
|
||||
// if paintbuffer is smaller than DMA buffer
|
||||
|
@ -140,67 +141,47 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
ch = sc->channel;
|
||||
for (i=0; i<sc->total_chans ; i++, ch++)
|
||||
{
|
||||
if (!ch->sfx)
|
||||
s = ch->sfx;
|
||||
if (!s)
|
||||
continue;
|
||||
if (!ch->vol[0] && !ch->vol[1] && !ch->vol[2] && !ch->vol[3] && !ch->vol[4] && !ch->vol[5])
|
||||
continue;
|
||||
|
||||
scache = S_LoadSound (ch->sfx);
|
||||
if (!scache)
|
||||
continue;
|
||||
|
||||
if ((ch->pos>>PITCHSHIFT) > scache->length) //cache was flushed and gamedir changed.
|
||||
{
|
||||
ch->pos = scache->length*ch->rate;
|
||||
ch->end = sc->paintedtime;
|
||||
}
|
||||
|
||||
|
||||
ltime = sc->paintedtime;
|
||||
|
||||
if (ch->sfx->decoder)
|
||||
{
|
||||
int len_diff;
|
||||
soundcardinfo_t *sndc;
|
||||
#define qmax(x, y) (x>y)?(x):(y)
|
||||
len_diff = scache->length;
|
||||
// start = ch->end - scache->length;
|
||||
// samples = end - start;
|
||||
|
||||
#ifdef warningmsg
|
||||
#pragma warningmsg("pitch fix needed")
|
||||
#endif
|
||||
ch->sfx->decoder->decodemore(ch->sfx,
|
||||
end - (ch->end - scache->length) + 1);
|
||||
// ch->pos + end-ltime+1);
|
||||
|
||||
scache = S_LoadSound (ch->sfx);
|
||||
if (!scache)
|
||||
continue;
|
||||
len_diff = scache->length - len_diff;
|
||||
|
||||
for (sndc = sndcardinfo; sndc; sndc=sndc->next)
|
||||
{
|
||||
for (j = 0; j < sndc->total_chans; j++)
|
||||
if (sndc->channel[j].sfx == ch->sfx) //extend all of these.
|
||||
ch->end += len_diff*ch->rate;
|
||||
}
|
||||
}
|
||||
|
||||
while (ltime < end)
|
||||
{ // paint up to end
|
||||
if (ch->end < end)
|
||||
count = ch->end - ltime;
|
||||
{
|
||||
if (s->decoder.decodedata)
|
||||
scache = s->decoder.decodedata(s, &scachebuf, ch->pos>>PITCHSHIFT, 1 + (((end - ltime) * ch->rate)>>PITCHSHIFT)); /*1 for luck - balances audio termination below*/
|
||||
else
|
||||
count = end - ltime;
|
||||
scache = s->decoder.buf;
|
||||
if (!scache)
|
||||
{
|
||||
ch->sfx = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
// find how many samples till the sample ends (clamp max length)
|
||||
avail = scache->length;
|
||||
if (avail > maxlen)
|
||||
avail = snd_speed*10;
|
||||
avail = (((int)(scache->soundoffset + avail)<<PITCHSHIFT) - ch->pos) / ch->rate;
|
||||
// mix the smaller of how much is available or the time left
|
||||
count = min(avail, end - ltime);
|
||||
|
||||
if (avail < 0)
|
||||
{
|
||||
Sys_Printf("sound already past end of buffer\n");
|
||||
avail = 0;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
if (ch->pos < 0) //delay the sound a little
|
||||
if (ch->pos < 0) //sounds with a pos of 0 are delay-start sounds
|
||||
{
|
||||
if (count > -ch->pos)
|
||||
count = -ch->pos;
|
||||
//don't progress past 0, so it actually starts properly at the right time with no clicks or anything
|
||||
if (count > (-ch->pos+255)>>PITCHSHIFT)
|
||||
count = ((-ch->pos+255)>>PITCHSHIFT);
|
||||
ltime += count;
|
||||
ch->pos += count*ch->rate;
|
||||
continue;
|
||||
|
@ -233,36 +214,35 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
SND_PaintChannelFrom16(ch, scache, count);
|
||||
}
|
||||
ltime += count;
|
||||
ch->pos += ch->rate * count;
|
||||
}
|
||||
|
||||
// if at end of loop, restart
|
||||
if (ltime >= ch->end)
|
||||
|
||||
if (count == avail)
|
||||
{
|
||||
if (scache->loopstart >= 0)
|
||||
if (scache->loopstart != -1) /*some wavs contain a loop offset directly in the sound file, such samples loop even if a non-looping builtin was used*/
|
||||
{
|
||||
if (scache->length == scache->loopstart)
|
||||
if (scache->length <= scache->loopstart)
|
||||
break;
|
||||
ch->pos = scache->loopstart*ch->rate;
|
||||
ch->end = ltime + ((scache->length - scache->loopstart)<<PITCHSHIFT)/ch->rate;
|
||||
ch->pos &= ~((-1)<<PITCHSHIFT); /*clear out all but the subsample offset*/
|
||||
ch->pos += scache->loopstart<<PITCHSHIFT;
|
||||
if (!scache->length)
|
||||
{
|
||||
scache->loopstart=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ch->looping && scache->length)
|
||||
else if (ch->looping && scache->length) /*(static)channels which are explicitly looping always loop from the start*/
|
||||
{
|
||||
/*restart it*/
|
||||
ch->pos = 0;
|
||||
ch->end = ltime + ((scache->length)<<PITCHSHIFT)/ch->rate;
|
||||
}
|
||||
else
|
||||
{ // channel just stopped
|
||||
s = ch->sfx;
|
||||
ch->sfx = NULL;
|
||||
if (s->decoder)
|
||||
if (s->decoder.abort)
|
||||
{
|
||||
if (!S_IsPlayingSomewhere(s))
|
||||
s->decoder->abort(s);
|
||||
s->decoder.abort(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -281,6 +261,7 @@ void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
int data;
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->vol[0] > 255)
|
||||
ch->vol[0] = 255;
|
||||
|
@ -292,22 +273,21 @@ void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[i];
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,6 +296,7 @@ void SND_PaintChannelFrom8Stereo (channel_t *ch, sfxcache_t *sc, int count)
|
|||
// int data;
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->vol[0] > 255)
|
||||
ch->vol[0] = 255;
|
||||
|
@ -327,20 +308,19 @@ void SND_PaintChannelFrom8Stereo (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[(ch->pos>>(PITCHSHIFT-1))&~1];
|
||||
paintbuffer[i].s[1] += ch->vol[1] * sfx[(ch->pos>>(PITCHSHIFT-1))|1];
|
||||
ch->pos += ch->rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
paintbuffer[i].s[1] += ch->vol[1] * sfx[(pos>>(PITCHSHIFT-1))|1];
|
||||
pos += ch->rate;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (ch->pos>>PITCHSHIFT)*2;
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[(i<<1)];
|
||||
paintbuffer[i].s[1] += ch->vol[1] * sfx[(i<<1)+1];
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,6 +328,7 @@ void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
{
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->vol[0] > 255)
|
||||
ch->vol[0] = 255;
|
||||
|
@ -364,8 +345,8 @@ void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
|
@ -374,7 +355,7 @@ void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[i];
|
||||
|
@ -382,7 +363,6 @@ void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[2] += ch->vol[2] * sfx[i];
|
||||
paintbuffer[i].s[3] += ch->vol[3] * sfx[i];
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,6 +370,7 @@ void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
{
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->vol[0] > 255)
|
||||
ch->vol[0] = 255;
|
||||
|
@ -410,8 +391,8 @@ void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
|
@ -422,7 +403,7 @@ void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[i];
|
||||
|
@ -432,7 +413,6 @@ void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[4] += ch->vol[4] * sfx[i];
|
||||
paintbuffer[i].s[5] += ch->vol[5] * sfx[i];
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,6 +420,7 @@ void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
{
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->vol[0] > 255)
|
||||
ch->vol[0] = 255;
|
||||
|
@ -464,8 +445,8 @@ void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
|
@ -478,7 +459,7 @@ void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[i];
|
||||
|
@ -490,7 +471,6 @@ void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[6] += ch->vol[6] * sfx[i];
|
||||
paintbuffer[i].s[7] += ch->vol[7] * sfx[i];
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,6 +482,7 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
int leftvol, rightvol;
|
||||
signed short *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
leftvol = ch->vol[0];
|
||||
rightvol = ch->vol[1];
|
||||
|
@ -512,15 +493,15 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += (leftvol * data)>>8;
|
||||
paintbuffer[i].s[1] += (rightvol * data)>>8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[i];
|
||||
|
@ -529,7 +510,6 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[0] += left;
|
||||
paintbuffer[i].s[1] += right;
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,6 +518,7 @@ void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count)
|
|||
int leftvol, rightvol;
|
||||
signed short *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
leftvol = ch->vol[0];
|
||||
rightvol = ch->vol[1];
|
||||
|
@ -548,22 +529,21 @@ void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
l = sfx[(ch->pos>>(PITCHSHIFT-1))&~1];
|
||||
r = sfx[(ch->pos>>(PITCHSHIFT-1))|1];
|
||||
ch->pos += ch->rate;
|
||||
l = sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
r = sfx[(pos>>(PITCHSHIFT-1))|1];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += (ch->vol[0] * l)>>8;
|
||||
paintbuffer[i].s[1] += (ch->vol[1] * r)>>8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (ch->pos>>PITCHSHIFT)*2;
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (*sfx++ * leftvol) >> 8;
|
||||
paintbuffer[i].s[1] += (*sfx++ * rightvol) >> 8;
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,6 +552,7 @@ void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
int vol[4];
|
||||
signed short *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
vol[0] = ch->vol[0];
|
||||
vol[1] = ch->vol[1];
|
||||
|
@ -584,8 +565,8 @@ void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
|
@ -594,7 +575,7 @@ void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + ch->pos;
|
||||
sfx = (signed short *)sc->data + pos;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]) >> 8;
|
||||
|
@ -602,7 +583,6 @@ void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[2] += (sfx[i] * vol[2]) >> 8;
|
||||
paintbuffer[i].s[3] += (sfx[i] * vol[3]) >> 8;
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,6 +591,7 @@ void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
int vol[6];
|
||||
signed short *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
vol[0] = ch->vol[0];
|
||||
vol[1] = ch->vol[1];
|
||||
|
@ -625,8 +606,8 @@ void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
|
@ -637,7 +618,7 @@ void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]) >> 8;
|
||||
|
@ -647,7 +628,6 @@ void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[4] += (sfx[i] * vol[4]) >> 8;
|
||||
paintbuffer[i].s[5] += (sfx[i] * vol[5]) >> 8;
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,6 +636,7 @@ void SND_PaintChannelFrom16_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
int vol[8];
|
||||
signed short *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
vol[0] = ch->vol[0];
|
||||
vol[1] = ch->vol[1];
|
||||
|
@ -672,8 +653,8 @@ void SND_PaintChannelFrom16_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[ch->pos>>PITCHSHIFT];
|
||||
ch->pos += ch->rate;
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
|
@ -686,7 +667,7 @@ void SND_PaintChannelFrom16_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (ch->pos>>PITCHSHIFT);
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]) >> 8;
|
||||
|
@ -698,6 +679,5 @@ void SND_PaintChannelFrom16_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
|
|||
paintbuffer[i].s[6] += (sfx[i] * vol[6]) >> 8;
|
||||
paintbuffer[i].s[7] += (sfx[i] * vol[7]) >> 8;
|
||||
}
|
||||
ch->pos += count<<PITCHSHIFT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,8 @@
|
|||
#define oggvorbislibrary VorbisFileBase
|
||||
struct Library *VorbisFileBase;
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#define WINDOWSDYNAMICLINK
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
HINSTANCE oggvorbislibrary;
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
void *oggvorbislibrary;
|
||||
dllhandle_t *oggvorbislibrary;
|
||||
#endif
|
||||
|
||||
#ifdef __MORPHOS__
|
||||
|
@ -39,6 +29,7 @@
|
|||
#define p_ov_comment ov_comment
|
||||
#define p_ov_pcm_total ov_pcm_total
|
||||
#define p_ov_read ov_read
|
||||
#define p_ov_pcm_seek ov_pcm_seek
|
||||
#else
|
||||
int (VARGS *p_ov_open_callbacks) (void *datasource, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks);
|
||||
int (VARGS *p_ov_clear)(OggVorbis_File *vf);
|
||||
|
@ -47,6 +38,7 @@
|
|||
ogg_int64_t (VARGS *p_ov_pcm_total)(OggVorbis_File *vf,int i);
|
||||
long (VARGS *p_ov_read)(OggVorbis_File *vf,char *buffer,int length,
|
||||
int bigendianp,int word,int sgned,int *bitstream);
|
||||
int (VARGS *p_ov_pcm_seek)(OggVorbis_File *vf,ogg_int64_t pos);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -55,177 +47,188 @@ typedef struct {
|
|||
unsigned long length;
|
||||
unsigned long pos;
|
||||
int srcspeed;
|
||||
int srcchannels;
|
||||
|
||||
qboolean failed;
|
||||
|
||||
sfxcache_t mediasc;
|
||||
char *mediaaswavdata;
|
||||
int mediaaswavpos;
|
||||
int mediaaswavbuflen;
|
||||
char *mediatemprecode;
|
||||
int mediatemprecodelen;
|
||||
char *tempbuffer;
|
||||
int tempbufferbytes;
|
||||
|
||||
char *decodedbuffer;
|
||||
int decodedbufferbytes;
|
||||
int decodedbytestart;
|
||||
int decodedbytecount;
|
||||
|
||||
OggVorbis_File vf;
|
||||
|
||||
sfx_t *s;
|
||||
} ovdecoderbuffer_t;
|
||||
|
||||
int OV_DecodeSome(sfx_t *s, int minlength);
|
||||
sfxcache_t *OV_DecodeSome(struct sfx_s *sfx, struct sfxcache_s *buf, int start, int length);
|
||||
void OV_CancelDecoder(sfx_t *s);
|
||||
qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuffer_t *buffer);
|
||||
|
||||
sfxcache_t *S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
qboolean S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
{
|
||||
//char namebuffer[MAX_OSPATH]; //unreferenced
|
||||
char *name;
|
||||
ovdecoderbuffer_t *buffer;
|
||||
//FILE *f; //unreferenced
|
||||
|
||||
//qboolean telluser; //unreferenced
|
||||
//int len; //unreferenced
|
||||
|
||||
if (datalen < 4 || strncmp(data, "OggS", 4))
|
||||
return NULL;
|
||||
return false;
|
||||
|
||||
name = s->name;
|
||||
|
||||
if (!s->decoder)
|
||||
s->decoder = Z_Malloc(sizeof(ovdecoderbuffer_t) + sizeof(sfxdecode_t));
|
||||
buffer = (ovdecoderbuffer_t*)(s->decoder+1);
|
||||
buffer = Z_Malloc(sizeof(ovdecoderbuffer_t));
|
||||
|
||||
buffer->mediaaswavpos=0;
|
||||
buffer->mediasc.length=0;
|
||||
buffer->decodedbytestart = 0;
|
||||
buffer->decodedbytecount = 0;
|
||||
buffer->s = s;
|
||||
s->decoder->buf = buffer;
|
||||
s->decoder->decodemore = OV_DecodeSome;
|
||||
s->decoder->abort = OV_CancelDecoder;
|
||||
s->decoder.buf = buffer;
|
||||
s->decoder.decodedata = OV_DecodeSome;
|
||||
s->decoder.abort = OV_CancelDecoder;
|
||||
|
||||
if (!OV_StartDecode(data, datalen, buffer))
|
||||
{
|
||||
if (buffer->mediaaswavdata)
|
||||
if (buffer->decodedbuffer)
|
||||
{
|
||||
BZ_Free(buffer->mediaaswavdata);
|
||||
buffer->mediaaswavdata = NULL;
|
||||
BZ_Free(buffer->decodedbuffer);
|
||||
buffer->decodedbuffer = NULL;
|
||||
}
|
||||
if (buffer->mediatemprecode)
|
||||
{
|
||||
BZ_Free(buffer->mediatemprecode);
|
||||
buffer->mediatemprecode = NULL;
|
||||
}
|
||||
Z_Free(s->decoder);
|
||||
s->decoder=NULL;
|
||||
buffer->decodedbufferbytes = 0;
|
||||
buffer->decodedbytestart = 0;
|
||||
buffer->decodedbytecount = 0;
|
||||
Z_Free(s->decoder.buf);
|
||||
s->decoder.buf = NULL;
|
||||
s->failedload = true;
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer->mediaaswavpos = sizeof(sfxcache_t);
|
||||
s->decoder.decodedata(s, NULL, 0, 100);
|
||||
|
||||
s->decoder->decodemore(s, 100);
|
||||
|
||||
s->cache.fake=true;
|
||||
return buffer->s->cache.data;
|
||||
return true;
|
||||
}
|
||||
|
||||
int OV_DecodeSome(sfx_t *s, int minlength)
|
||||
sfxcache_t *OV_DecodeSome(struct sfx_s *sfx, struct sfxcache_s *buf, int start, int length)
|
||||
{
|
||||
extern int snd_speed;
|
||||
extern cvar_t snd_linearresample_stream;
|
||||
int bigendianp = bigendian;
|
||||
int current_section = 0;
|
||||
sfxcache_t *sc;
|
||||
|
||||
ovdecoderbuffer_t *dec = s->decoder->buf;
|
||||
ovdecoderbuffer_t *dec = sfx->decoder.buf;
|
||||
int bytesread;
|
||||
|
||||
int outspeed = snd_speed;
|
||||
|
||||
// Con_Printf("Minlength = %03i ", minlength);
|
||||
|
||||
start *= 2*dec->srcchannels;
|
||||
length *= 2*dec->srcchannels;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (dec->mediaaswavbuflen < dec->mediaaswavpos+minlength+11050) //expand if needed.
|
||||
if (start < dec->decodedbytestart)
|
||||
{
|
||||
/*something rewound, purge clear the buffer*/
|
||||
dec->decodedbytecount = 0;
|
||||
dec->decodedbytestart = start;
|
||||
|
||||
//check pos
|
||||
p_ov_pcm_seek(&dec->vf, dec->decodedbytestart);
|
||||
}
|
||||
|
||||
if (start+length <= dec->decodedbytestart + dec->decodedbytecount)
|
||||
break;
|
||||
|
||||
if (dec->decodedbytecount > snd_speed*8)
|
||||
{
|
||||
/*everything is okay, but our buffer is getting needlessly large.
|
||||
keep anything after the 'new' position, but discard all before that
|
||||
trim shouldn't be able to go negative
|
||||
*/
|
||||
unsigned int trim = start - dec->decodedbytestart;
|
||||
//FIXME: retain an extra half-second for dual+ sound devices running slightly out of sync
|
||||
memmove(dec->decodedbuffer, dec->decodedbuffer + trim, dec->decodedbytecount - trim);
|
||||
dec->decodedbytecount -= trim;
|
||||
dec->decodedbytestart += trim;
|
||||
}
|
||||
|
||||
if (dec->decodedbufferbytes < start+length - dec->decodedbytestart + 128) //expand if needed.
|
||||
{
|
||||
// Con_Printf("Expand buffer\n");
|
||||
dec->mediaaswavbuflen += minlength+22100;
|
||||
dec->mediaaswavdata = BZ_Realloc(dec->mediaaswavdata, dec->mediaaswavbuflen);
|
||||
s->cache.data = dec->mediaaswavdata;
|
||||
s->cache.fake = true;
|
||||
|
||||
sc = s->cache.data;
|
||||
sc->numchannels = dec->mediasc.numchannels;
|
||||
sc->loopstart = -1;
|
||||
}
|
||||
else
|
||||
sc = s->cache.data;
|
||||
|
||||
if (minlength < sc->length)
|
||||
{
|
||||
// Con_Printf("No need for decode\n");
|
||||
//done enough for now, don't whizz through the lot
|
||||
return 0;
|
||||
dec->decodedbufferbytes = (start+length - dec->decodedbytestart) + snd_speed;
|
||||
dec->decodedbuffer = BZ_Realloc(dec->decodedbuffer, dec->decodedbufferbytes);
|
||||
}
|
||||
|
||||
if (snd_speed == dec->srcspeed)
|
||||
if (outspeed == dec->srcspeed)
|
||||
{
|
||||
bytesread = p_ov_read(&dec->vf, dec->mediaaswavdata+dec->mediaaswavpos, dec->mediaaswavbuflen-dec->mediaaswavpos, bigendianp, 2, 1, ¤t_section);
|
||||
bytesread = p_ov_read(&dec->vf, dec->decodedbuffer+dec->decodedbytecount, (start+length) - (dec->decodedbytestart+dec->decodedbytecount), bigendianp, 2, 1, ¤t_section);
|
||||
if (bytesread <= 0)
|
||||
{
|
||||
if (bytesread != 0) //0==eof
|
||||
{
|
||||
Con_Printf("ogg decoding failed\n");
|
||||
return 1;
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double scale = dec->srcspeed / (double)snd_speed;
|
||||
int decodesize = ceil((dec->mediaaswavbuflen-dec->mediaaswavpos) * scale);
|
||||
if (decodesize > dec->mediatemprecodelen)
|
||||
double scale = dec->srcspeed / (double)outspeed;
|
||||
int decodesize = ceil((dec->decodedbufferbytes-dec->decodedbytecount) * scale);
|
||||
/*round down...*/
|
||||
decodesize &= ~(2 * dec->srcchannels - 1);
|
||||
if (decodesize > dec->tempbufferbytes)
|
||||
{
|
||||
dec->mediatemprecode = BZ_Realloc(dec->mediatemprecode, decodesize);
|
||||
dec->mediatemprecodelen = decodesize;
|
||||
dec->tempbuffer = BZ_Realloc(dec->tempbuffer, decodesize);
|
||||
dec->tempbufferbytes = decodesize;
|
||||
}
|
||||
|
||||
bytesread = p_ov_read(&dec->vf, dec->mediatemprecode, decodesize, bigendianp, 2, 1, ¤t_section);
|
||||
bytesread = p_ov_read(&dec->vf, dec->tempbuffer, decodesize, bigendianp, 2, 1, ¤t_section);
|
||||
|
||||
if (bytesread <= 0)
|
||||
{
|
||||
if (bytesread != 0) //0==eof
|
||||
{
|
||||
Con_Printf("ogg decoding failed\n");
|
||||
return 1;
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SND_ResampleStream(dec->mediatemprecode,
|
||||
SND_ResampleStream(dec->tempbuffer,
|
||||
dec->srcspeed,
|
||||
2,
|
||||
dec->mediasc.numchannels,
|
||||
bytesread / (2 * dec->mediasc.numchannels),
|
||||
dec->mediaaswavdata+dec->mediaaswavpos,
|
||||
snd_speed,
|
||||
dec->srcchannels,
|
||||
bytesread / (2 * dec->srcchannels),
|
||||
dec->decodedbuffer+dec->decodedbytecount,
|
||||
outspeed,
|
||||
2,
|
||||
dec->mediasc.numchannels,
|
||||
dec->srcchannels,
|
||||
snd_linearresample_stream.ival);
|
||||
|
||||
bytesread = (int)floor(bytesread / scale) & ~0x1;
|
||||
}
|
||||
|
||||
dec->mediaaswavpos += bytesread;
|
||||
|
||||
sc->length = (dec->mediaaswavpos-sizeof(sfxcache_t))/(2*(dec->mediasc.numchannels));
|
||||
dec->mediasc.length = sc->length;
|
||||
|
||||
if (minlength<=sc->length)
|
||||
{
|
||||
// Con_Printf("Reached length\n");
|
||||
return 1;
|
||||
}
|
||||
dec->decodedbytecount += bytesread;
|
||||
}
|
||||
|
||||
if (buf)
|
||||
{
|
||||
buf->data = dec->decodedbuffer;
|
||||
buf->soundoffset = dec->decodedbytestart / (2 * dec->srcchannels);
|
||||
buf->length = dec->decodedbytecount;
|
||||
buf->loopstart = -1;
|
||||
buf->numchannels = dec->srcchannels;
|
||||
buf->speed = snd_speed;
|
||||
buf->width = 2;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
void OV_CancelDecoder(sfx_t *s)
|
||||
{
|
||||
/*
|
||||
sfxcache_t *src, *dest;
|
||||
ovdecoderbuffer_t *dec;
|
||||
|
||||
|
@ -241,14 +244,15 @@ void OV_CancelDecoder(sfx_t *s)
|
|||
memcpy(dest, src, dec->mediaaswavpos);
|
||||
BZ_Free(src);
|
||||
|
||||
if (dec->mediatemprecode)
|
||||
if (dec->tempbuffer)
|
||||
{
|
||||
BZ_Free(dec->mediatemprecode);
|
||||
dec->mediatemprecode = NULL;
|
||||
BZ_Free(dec->tempbuffer);
|
||||
dec->tempbufferbytes = NULL;
|
||||
}
|
||||
|
||||
Z_Free(s->decoder);
|
||||
s->decoder = NULL;
|
||||
*/
|
||||
|
||||
//and it's now indistinguisable from a wav
|
||||
}
|
||||
|
@ -305,6 +309,19 @@ static ov_callbacks callbacks = {
|
|||
qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuffer_t *buffer)
|
||||
{
|
||||
static qboolean tried;
|
||||
static dllfunction_t funcs[] =
|
||||
{
|
||||
{(void*)&p_ov_open_callbacks, "ov_open_callbacks"},
|
||||
{(void*)&p_ov_comment, "ov_comment"},
|
||||
{(void*)&p_ov_pcm_total, "ov_pcm_total"},
|
||||
{(void*)&p_ov_clear, "ov_clear"},
|
||||
{(void*)&p_ov_info, "ov_info"},
|
||||
{(void*)&p_ov_read, "ov_read"},
|
||||
{(void*)&p_ov_pcm_seek, "ov_pcm_seek"},
|
||||
{NULL}
|
||||
};
|
||||
static void *libhandle;
|
||||
|
||||
if (!oggvorbislibrary && !tried)
|
||||
#if defined(__MORPHOS__)
|
||||
{
|
||||
|
@ -314,41 +331,19 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
|
|||
Con_Printf("Unable to open vorbisfile.library version 2\n");
|
||||
}
|
||||
}
|
||||
#elif defined(WINDOWSDYNAMICLINK)
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
oggvorbislibrary = LoadLibrary("vorbisfile.dll");
|
||||
oggvorbislibrary = Sys_LoadLibrary("vorbisfile", funcs);
|
||||
if (!oggvorbislibrary)
|
||||
oggvorbislibrary = LoadLibrary("libvorbisfile.dll");
|
||||
oggvorbislibrary = Sys_LoadLibrary("libvorbisfile", funcs);
|
||||
if (!oggvorbislibrary)
|
||||
{
|
||||
Con_Printf("Couldn't load DLL: \"vorbisfile.dll\".\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
p_ov_open_callbacks = (void *)GetProcAddress(oggvorbislibrary, "ov_open_callbacks");
|
||||
p_ov_comment = (void *)GetProcAddress(oggvorbislibrary, "ov_comment");
|
||||
p_ov_pcm_total = (void *)GetProcAddress(oggvorbislibrary, "ov_pcm_total");
|
||||
p_ov_clear = (void *)GetProcAddress(oggvorbislibrary, "ov_clear");
|
||||
p_ov_info = (void *)GetProcAddress(oggvorbislibrary, "ov_info");
|
||||
p_ov_read = (void *)GetProcAddress(oggvorbislibrary, "ov_read");
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
oggvorbislibrary = dlopen("libvorbisfile.so", RTLD_LOCAL | RTLD_LAZY);
|
||||
oggvorbislibrary = Sys_LoadLibrary("libvorbisfile", funcs);
|
||||
if (!oggvorbislibrary)
|
||||
{
|
||||
Con_Printf("Couldn't load SO: \"libvorbisfile.so\".\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
p_ov_open_callbacks = (void *)dlsym(oggvorbislibrary, "ov_open_callbacks");
|
||||
p_ov_comment = (void *)dlsym(oggvorbislibrary, "ov_comment");
|
||||
p_ov_pcm_total = (void *)dlsym(oggvorbislibrary, "ov_pcm_total");
|
||||
p_ov_clear = (void *)dlsym(oggvorbislibrary, "ov_clear");
|
||||
p_ov_info = (void *)dlsym(oggvorbislibrary, "ov_info");
|
||||
p_ov_read = (void *)dlsym(oggvorbislibrary, "ov_read");
|
||||
}
|
||||
Con_Printf("Couldn't load library: \"libvorbisfile\".\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -381,8 +376,7 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
|
|||
return false;
|
||||
}
|
||||
|
||||
buffer->mediasc.numchannels = vi->channels;
|
||||
buffer->mediasc.loopstart = -1;
|
||||
buffer->srcchannels = vi->channels;
|
||||
buffer->srcspeed = vi->rate;
|
||||
/*
|
||||
while(*ptr){
|
||||
|
@ -394,8 +388,8 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
|
|||
(long)p_ov_pcm_total(&buffer->vf,-1));
|
||||
Con_Printf("Encoded by: %s\n\n",p_ov_comment(&buffer->vf,-1)->vendor);
|
||||
*/ }
|
||||
buffer->mediatemprecode = NULL;
|
||||
buffer->mediatemprecodelen = 0;
|
||||
buffer->tempbuffer = NULL;
|
||||
buffer->tempbufferbytes = 0;
|
||||
|
||||
buffer->start = BZ_Malloc(length);
|
||||
memcpy(buffer->start, start, length);
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct
|
|||
|
||||
typedef struct {
|
||||
int decodedlen;
|
||||
int (*decodemore) (struct sfx_s *sfx, int length); //retrurn true when done.
|
||||
struct sfxcache_s *(*decodedata) (struct sfx_s *sfx, struct sfxcache_s *buf, int start, int length); //retrurn true when done.
|
||||
void (*abort) (struct sfx_s *sfx); //it's not playing elsewhere. free entirly
|
||||
void *buf;
|
||||
} sfxdecode_t;
|
||||
|
@ -51,20 +51,21 @@ typedef struct sfx_s
|
|||
#ifdef AVAIL_OPENAL
|
||||
unsigned int openal_buffer;
|
||||
#endif
|
||||
qboolean failedload; //no more super-spammy
|
||||
cache_user_t cache;
|
||||
sfxdecode_t *decoder;
|
||||
qboolean failedload:1; //no more super-spammy
|
||||
qboolean touched:1; //if the sound is still relevent
|
||||
sfxdecode_t decoder;
|
||||
} sfx_t;
|
||||
|
||||
// !!! if this is changed, it much be changed in asm_i386.h too !!!
|
||||
typedef struct sfxcache_s
|
||||
{
|
||||
int length;
|
||||
int loopstart;
|
||||
int speed;
|
||||
int width;
|
||||
int numchannels;
|
||||
qbyte data[1]; // variable sized
|
||||
unsigned int length;
|
||||
unsigned int loopstart;
|
||||
unsigned int speed;
|
||||
unsigned int width;
|
||||
unsigned int numchannels;
|
||||
unsigned int soundoffset; //byte index into the sound
|
||||
qbyte *data; // variable sized
|
||||
} sfxcache_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -72,23 +73,23 @@ typedef struct
|
|||
// qboolean gamealive;
|
||||
// qboolean soundalive;
|
||||
// qboolean splitbuffer;
|
||||
int numchannels;
|
||||
int numchannels; // this many samples per frame
|
||||
int samples; // mono samples in buffer (individual, non grouped)
|
||||
// int submission_chunk; // don't mix less than this #
|
||||
int samplepos; // in mono samples
|
||||
int samplebits;
|
||||
int speed;
|
||||
unsigned char *buffer;
|
||||
int speed; // this many frames per second
|
||||
unsigned char *buffer; // pointer to mixed pcm buffer (not directly used by mixer)
|
||||
} dma_t;
|
||||
|
||||
#define PITCHSHIFT 8
|
||||
#define PITCHSHIFT 6 /*max audio file length = (1<<32>>PITCHSHIFT)/KHZ*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sfx_t *sfx; // sfx number
|
||||
int vol[MAXSOUNDCHANNELS]; // 0-255 volume
|
||||
// int delay[MAXSOUNDCHANNELS];
|
||||
int end; // end time in global paintsamples
|
||||
int start; // start time in global paintsamples
|
||||
int pos; // sample position in sfx, <0 means delay sound start (shifted up by 8)
|
||||
int rate; // 24.8 fixed point rate scaling
|
||||
int looping; // where to loop, -1 = no looping
|
||||
|
@ -115,8 +116,7 @@ typedef struct soundcardinfo_s soundcardinfo_t;
|
|||
void S_Init (void);
|
||||
void S_Startup (void);
|
||||
void S_Shutdown (void);
|
||||
void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, float pitchadj);
|
||||
void S_StartSoundDelayed(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, float timeofs);
|
||||
void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation, float timeofs, float pitchadj);
|
||||
void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation);
|
||||
void S_StopSound (int entnum, int entchannel);
|
||||
void S_StopAllSounds(qboolean clear);
|
||||
|
@ -124,6 +124,8 @@ void S_UpdateListener(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up);
|
|||
void S_GetListenerInfo(float *origin, float *forward, float *right, float *up);
|
||||
void S_Update (void);
|
||||
void S_ExtraUpdate (void);
|
||||
void S_MixerThread(soundcardinfo_t *sc);
|
||||
void S_Purge(qboolean retaintouched);
|
||||
|
||||
qboolean S_HaveOutput(void);
|
||||
|
||||
|
@ -132,17 +134,15 @@ void S_Music_Seek(float time);
|
|||
|
||||
sfx_t *S_PrecacheSound (char *sample);
|
||||
void S_TouchSound (char *sample);
|
||||
void S_UntouchAll(void);
|
||||
void S_ClearPrecache (void);
|
||||
void S_BeginPrecaching (void);
|
||||
void S_EndPrecaching (void);
|
||||
|
||||
void S_ClearBuffer (soundcardinfo_t *sc);
|
||||
|
||||
void S_PaintChannels(soundcardinfo_t *sc, int endtime);
|
||||
void S_InitPaintChannels (soundcardinfo_t *sc);
|
||||
|
||||
void S_ShutdownCard (soundcardinfo_t *sc);
|
||||
void S_StopSoundCard (soundcardinfo_t *sc, int entnum, int entchannel);
|
||||
|
||||
void S_DefaultSpeakerConfiguration(soundcardinfo_t *sc);
|
||||
void S_ResetFailedLoad(void);
|
||||
|
@ -164,7 +164,7 @@ void S_Voip_Ignore(unsigned int plno, qboolean ignore);
|
|||
#endif
|
||||
|
||||
qboolean S_IsPlayingSomewhere(sfx_t *s);
|
||||
void ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int insamps, int inloopstart, qbyte *data);
|
||||
qboolean ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int insamps, int inloopstart, qbyte *data);
|
||||
|
||||
// picks a channel based on priorities, empty slots, number of channels
|
||||
channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel);
|
||||
|
@ -240,9 +240,9 @@ extern cvar_t snd_usemultipledevices;
|
|||
extern int snd_blocked;
|
||||
|
||||
void S_LocalSound (char *s);
|
||||
sfxcache_t *S_LoadSound (sfx_t *s);
|
||||
qboolean S_LoadSound (sfx_t *s);
|
||||
|
||||
typedef sfxcache_t *(*S_LoadSound_t) (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
typedef qboolean (*S_LoadSound_t) (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc); //called to register additional sound input plugins
|
||||
|
||||
wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength);
|
||||
|
@ -279,7 +279,7 @@ 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 as last-written pos (in sample pairs)
|
||||
int paintedtime; //used in the mixer as last-written pos (in frames)
|
||||
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).
|
||||
|
@ -295,6 +295,7 @@ struct soundcardinfo_s { //windows has one defined AFTER directsound
|
|||
void (*ChannelUpdate) (soundcardinfo_t *sc, channel_t *channel, unsigned int schanged);
|
||||
|
||||
//driver -specific
|
||||
void *thread;
|
||||
void *handle;
|
||||
int snd_sent;
|
||||
int snd_completed;
|
||||
|
|
|
@ -90,65 +90,6 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
|
|||
sys_lastframe = Sys_Milliseconds();
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_keypress(JNIEnv *env, jobject obj,
|
||||
jint down, jint keycode, jint unicode)
|
||||
{
|
||||
Key_Event(0, keycode, unicode, down);
|
||||
}
|
||||
|
||||
int mousecursor_x, mousecursor_y;
|
||||
float mouse_x, mouse_y;
|
||||
static vec2_t omouse[8];
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_motion(JNIEnv *env, jobject obj,
|
||||
jint act, jint ptrid, jfloat x, jfloat y)
|
||||
{
|
||||
static float totalmoved[8];
|
||||
static qboolean down[8];
|
||||
float d[2];
|
||||
|
||||
if (!act && CSQC_MousePosition(x, y, ptrid))
|
||||
return;
|
||||
/*note that these events are not directly useful, so trigger mouse2 leaving mouse1 clean for tap events (and bypass any binds for it)*/
|
||||
if (act == 1 && CSQC_KeyPress(K_MOUSE2, 0, true, ptrid))
|
||||
return;
|
||||
if (act == 2 && CSQC_KeyPress(K_MOUSE2, 0, false, ptrid))
|
||||
return;
|
||||
|
||||
ptrid &= 7;
|
||||
|
||||
d[0] = x - omouse[ptrid][0];
|
||||
d[1] = y - omouse[ptrid][1];
|
||||
omouse[ptrid][0] = x;
|
||||
omouse[ptrid][1] = y;
|
||||
mousecursor_x = x;
|
||||
mousecursor_y = y;
|
||||
|
||||
if (down[ptrid])
|
||||
{
|
||||
mouse_x += d[0];
|
||||
mouse_y += d[1];
|
||||
totalmoved[ptrid] += fabs(d[0]) + fabs(d[1]);
|
||||
}
|
||||
|
||||
switch(act)
|
||||
{
|
||||
case 0: /*move*/
|
||||
break;
|
||||
case 1: /*down*/
|
||||
totalmoved[ptrid] = 0;
|
||||
down[ptrid] = true;
|
||||
break;
|
||||
case 2: /*up*/
|
||||
down[ptrid] = false;
|
||||
/*if it didn't move far, treat it as a regular click, if it did move a little then sorry if you just wanted a small turn!*/
|
||||
if (totalmoved[ptrid] < 3)
|
||||
{
|
||||
Key_Event(0, K_MOUSE1, 0, 1);
|
||||
Key_Event(0, K_MOUSE1, 0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int secbase;
|
||||
double Sys_DoubleTime(void)
|
||||
|
@ -248,6 +189,7 @@ void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
|
|||
}
|
||||
void *Sys_GetGameAPI (void *parms)
|
||||
{
|
||||
//don't implement - fix q2 code instead
|
||||
return NULL;
|
||||
}
|
||||
void Sys_UnloadGame(void)
|
||||
|
@ -265,6 +207,9 @@ qboolean Sys_remove (char *path)
|
|||
{
|
||||
return !unlink(path);
|
||||
}
|
||||
void Sys_SendKeyEvents(void)
|
||||
{
|
||||
}
|
||||
void Sys_Init(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -380,7 +380,7 @@ DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exception
|
|||
extern qboolean vid_initializing;
|
||||
qboolean oldval = vid_initializing;
|
||||
vid_initializing = true;
|
||||
ShowWindow(mainwindow, SW_MINIMIZE);
|
||||
// ShowWindow(mainwindow, SW_MINIMIZE);
|
||||
vid_initializing = oldval;
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
@ -2006,7 +2006,19 @@ DWORD WINAPI threadwrapper(void *args)
|
|||
tw.args = ((threadwrap_t *)args)->args;
|
||||
|
||||
free(args);
|
||||
tw.func(tw.args);
|
||||
|
||||
#ifdef CATCHCRASH
|
||||
__try
|
||||
{
|
||||
#endif
|
||||
tw.func(tw.args);
|
||||
#ifdef CATCHCRASH
|
||||
}
|
||||
__except (CrashExceptionHandler(GetExceptionCode(), GetExceptionInformation()))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32CRTDLL
|
||||
_endthreadex(0);
|
||||
|
@ -2065,7 +2077,7 @@ qboolean Sys_TryLockMutex(void *mutex)
|
|||
|
||||
qboolean Sys_LockMutex(void *mutex)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#if 0//def _DEBUG
|
||||
/*in debug builds, trigger a debug break if we sit on a mutex for longer than 20 secs*/
|
||||
if (WaitForSingleObject(mutex, 20000) == WAIT_OBJECT_0)
|
||||
return true;
|
||||
|
|
|
@ -139,7 +139,7 @@ V_CalcBob
|
|||
|
||||
===============
|
||||
*/
|
||||
float V_CalcBob (int pnum)
|
||||
float V_CalcBob (int pnum, qboolean queryold)
|
||||
{
|
||||
static double bobtime[MAX_SPLITS];
|
||||
static float bob[MAX_SPLITS];
|
||||
|
@ -148,7 +148,7 @@ float V_CalcBob (int pnum)
|
|||
if (cl.spectator)
|
||||
return 0;
|
||||
|
||||
if (!cl.onground[pnum] || cl.paused)
|
||||
if (!cl.onground[pnum] || cl.paused || queryold)
|
||||
return bob[pnum]; // just use old value
|
||||
|
||||
if (cl_bobcycle.value <= 0)
|
||||
|
@ -790,11 +790,12 @@ float angledelta (float a)
|
|||
CalcGunAngle
|
||||
==================
|
||||
*/
|
||||
void CalcGunAngle (int pnum)
|
||||
void V_CalcGunPositionAngle (int pnum, float bob)
|
||||
{
|
||||
float yaw, pitch, move;
|
||||
static float oldyaw = 0;
|
||||
static float oldpitch = 0;
|
||||
int i;
|
||||
|
||||
yaw = r_refdef.viewangles[YAW];
|
||||
pitch = -r_refdef.viewangles[PITCH];
|
||||
|
@ -836,12 +837,36 @@ void CalcGunAngle (int pnum)
|
|||
oldpitch = pitch;
|
||||
|
||||
cl.viewent[pnum].angles[YAW] = r_refdef.viewangles[YAW] + yaw;
|
||||
cl.viewent[pnum].angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch);
|
||||
cl.viewent[pnum].angles[PITCH] = r_refdef.viewangles[PITCH] + pitch;
|
||||
|
||||
cl.viewent[pnum].angles[YAW] = r_refdef.viewangles[YAW];
|
||||
cl.viewent[pnum].angles[PITCH] = r_refdef.viewangles[PITCH];
|
||||
cl.viewent[pnum].angles[ROLL] = r_refdef.viewangles[ROLL];
|
||||
|
||||
cl.viewent[pnum].angles[PITCH]*=-1;
|
||||
AngleVectors(cl.viewent[pnum].angles, cl.viewent[pnum].axis[0], cl.viewent[pnum].axis[1], cl.viewent[pnum].axis[2]);
|
||||
VectorInverse(cl.viewent[pnum].axis[1]);
|
||||
cl.viewent[pnum].angles[PITCH]*=-1;
|
||||
|
||||
|
||||
|
||||
VectorCopy (r_refdef.vieworg, cl.viewent[pnum].origin);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
cl.viewent[pnum].origin[i] += cl.viewent[pnum].axis[0][i]*bob*0.4;
|
||||
// cl.viewent[pnum].origin[i] += cl.viewent[pnum].axis[1][i]*sin(cl.time*5.5342452354235)*0.1;
|
||||
// cl.viewent[pnum].origin[i] += cl.viewent[pnum].axis[2][i]*bob*0.8;
|
||||
}
|
||||
|
||||
// fudge position around to keep amount of weapon visible
|
||||
// roughly equal with different FOV
|
||||
if (scr_viewsize.value == 110)
|
||||
cl.viewent[pnum].origin[2] += 1;
|
||||
else if (scr_viewsize.value == 100)
|
||||
cl.viewent[pnum].origin[2] += 2;
|
||||
else if (scr_viewsize.value == 90)
|
||||
cl.viewent[pnum].origin[2] += 1;
|
||||
else if (scr_viewsize.value == 80)
|
||||
cl.viewent[pnum].origin[2] += 0.5;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -988,7 +1013,6 @@ void V_CalcRefdef (int pnum)
|
|||
{
|
||||
entity_t *view;
|
||||
int i;
|
||||
vec3_t forward, right, up;
|
||||
float bob;
|
||||
|
||||
r_refdef.currentplayernum = pnum;
|
||||
|
@ -1012,7 +1036,7 @@ void V_CalcRefdef (int pnum)
|
|||
else if (v_viewheight.value)
|
||||
bob=v_viewheight.value;
|
||||
else
|
||||
bob = V_CalcBob (pnum);
|
||||
bob = V_CalcBob (pnum, false);
|
||||
|
||||
// refresh position from simulated origin
|
||||
VectorCopy (cl.simorg[pnum], r_refdef.vieworg);
|
||||
|
@ -1057,7 +1081,6 @@ void V_CalcRefdef (int pnum)
|
|||
{
|
||||
VectorCopy (cl.simangles[pnum], r_refdef.viewangles);
|
||||
}
|
||||
VectorCopy (r_refdef.viewangles, view->angles); //copy before it gets manipulatd
|
||||
V_CalcViewRoll (pnum);
|
||||
V_AddIdle (pnum);
|
||||
|
||||
|
@ -1087,28 +1110,7 @@ void V_CalcRefdef (int pnum)
|
|||
}
|
||||
|
||||
// set up gun position
|
||||
AngleVectors (view->angles, forward, right, up);
|
||||
CalcGunAngle (pnum);
|
||||
|
||||
VectorCopy (r_refdef.vieworg, view->origin);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
view->origin[i] += forward[i]*bob*0.4;
|
||||
// view->origin[i] += right[i]*sin(cl.time*5.5342452354235)*0.1;
|
||||
// view->origin[i] += up[i]*bob*0.8;
|
||||
}
|
||||
|
||||
// fudge position around to keep amount of weapon visible
|
||||
// roughly equal with different FOV
|
||||
if (scr_viewsize.value == 110)
|
||||
view->origin[2] += 1;
|
||||
else if (scr_viewsize.value == 100)
|
||||
view->origin[2] += 2;
|
||||
else if (scr_viewsize.value == 90)
|
||||
view->origin[2] += 1;
|
||||
else if (scr_viewsize.value == 80)
|
||||
view->origin[2] += 0.5;
|
||||
V_CalcGunPositionAngle (pnum, bob);
|
||||
|
||||
if (cl.stats[pnum][STAT_HEALTH] > 0 && (unsigned int)cl.stats[pnum][STAT_WEAPON] >= MAX_MODELS)
|
||||
view->model = NULL;
|
||||
|
|
|
@ -105,7 +105,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define AVAIL_FREETYPE
|
||||
#ifdef _WIN32
|
||||
//needs testing on other platforms
|
||||
#define AVAIL_OPENAL
|
||||
//#define AVAIL_OPENAL
|
||||
#endif
|
||||
|
||||
#define ODE_DYNAMIC
|
||||
|
|
|
@ -151,6 +151,8 @@ typedef struct
|
|||
#define Q1CONTENTS_SLIME -4
|
||||
#define Q1CONTENTS_LAVA -5
|
||||
#define Q1CONTENTS_SKY -6
|
||||
#define Q1CONTENTS_CLIP -8
|
||||
#define Q1CONTENTS_LADDER -16
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct
|
||||
|
|
|
@ -2099,7 +2099,7 @@ void Mod_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum
|
|||
if (skinfilename)
|
||||
strcpy(skinfilename, skinfilelist[skinnum]);
|
||||
|
||||
f = COM_LoadTempFile2(skinfilelist[skinnum]);
|
||||
f = COM_LoadTempMoreFile(skinfilelist[skinnum]);
|
||||
|
||||
while(f)
|
||||
{
|
||||
|
@ -4714,7 +4714,7 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer)
|
|||
|
||||
/*attempt to load a psa file. don't die if we can't find one*/
|
||||
COM_StripExtension(mod->name, basename, sizeof(basename));
|
||||
buffer = COM_LoadTempFile2(va("%s.psa", basename));
|
||||
buffer = COM_LoadTempMoreFile(va("%s.psa", basename));
|
||||
if (buffer)
|
||||
{
|
||||
pos = 0;
|
||||
|
@ -5666,10 +5666,10 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
|
|||
galiasinfo_t *gai;
|
||||
#ifndef SERVERONLY
|
||||
galiasskin_t *skin;
|
||||
shader_t **shaders;
|
||||
#endif
|
||||
galiasgroup_t *fgroup;
|
||||
galiasbone_t *bones;
|
||||
shader_t **shaders;
|
||||
index_t *idx;
|
||||
float basepose[12 * MAX_BONES];
|
||||
qboolean baseposeonly;
|
||||
|
@ -6662,7 +6662,7 @@ qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer)
|
|||
if (!strcmp(com_token, "model"))
|
||||
{
|
||||
buffer = COM_Parse(buffer);
|
||||
file = COM_LoadTempFile2(com_token);
|
||||
file = COM_LoadTempMoreFile(com_token);
|
||||
|
||||
if (!file) //FIXME: make non fatal somehow..
|
||||
{
|
||||
|
@ -6706,7 +6706,7 @@ qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer)
|
|||
grouplist = BZ_Realloc(grouplist, sizeof(galiasgroup_t)*(numgroups+1));
|
||||
poseofs = BZ_Realloc(poseofs, sizeof(*poseofs)*(numgroups+1));
|
||||
buffer = COM_Parse(buffer);
|
||||
file = COM_LoadTempFile2(com_token);
|
||||
file = COM_LoadTempMoreFile(com_token);
|
||||
if (file) //FIXME: make non fatal somehow..
|
||||
{
|
||||
char namebkup[MAX_QPATH];
|
||||
|
@ -6725,7 +6725,7 @@ qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer)
|
|||
grouplist = BZ_Realloc(grouplist, sizeof(galiasgroup_t)*(numgroups+1));
|
||||
poseofs = BZ_Realloc(poseofs, sizeof(*poseofs)*(numgroups+1));
|
||||
buffer = COM_Parse(buffer);
|
||||
file = COM_LoadTempFile2(com_token);
|
||||
file = COM_LoadTempMoreFile(com_token);
|
||||
if (file) //FIXME: make non fatal somehow..
|
||||
{
|
||||
char namebkup[MAX_QPATH];
|
||||
|
@ -6746,7 +6746,7 @@ qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer)
|
|||
void *np;
|
||||
|
||||
buffer = COM_Parse(buffer);
|
||||
file = COM_LoadTempFile2(com_token);
|
||||
file = COM_LoadTempMoreFile(com_token);
|
||||
if (file) //FIXME: make non fatal somehow..
|
||||
{
|
||||
char namebkup[MAX_QPATH];
|
||||
|
|
|
@ -857,6 +857,8 @@ float MSG_FromCoord(coorddata c, int bytes)
|
|||
{
|
||||
case 2: //encode 1/8th precision, giving -4096 to 4096 map sizes
|
||||
return LittleShort(c.b2)/8.0f;
|
||||
case 3:
|
||||
return LittleShort(c.b2) + (((unsigned char*)c.b)[2] * (1/255.0)); /*FIXME: RMQe uses 255, should be 256*/
|
||||
case 4:
|
||||
return LittleFloat(c.f);
|
||||
default:
|
||||
|
|
|
@ -387,7 +387,7 @@ char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
|
|||
int COM_filelength (FILE *f);
|
||||
qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize);
|
||||
qbyte *COM_LoadTempFile (const char *path);
|
||||
qbyte *COM_LoadTempFile2 (const char *path); //allocates a little bit more without freeing old temp
|
||||
qbyte *COM_LoadTempMoreFile (const char *path); //allocates a little bit more without freeing old temp
|
||||
qbyte *COM_LoadHunkFile (const char *path);
|
||||
qbyte *COM_LoadMallocFile (const char *path);
|
||||
void COM_LoadCacheFile (const char *path, struct cache_user_s *cu);
|
||||
|
|
|
@ -20,6 +20,7 @@ static unsigned int fs_restarts;
|
|||
extern cvar_t com_fs_cache;
|
||||
int active_fs_cachetype;
|
||||
static int fs_referencetype;
|
||||
int fs_finds;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -511,6 +512,7 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
|
|||
{
|
||||
for (search = com_purepaths ; search ; search = search->nextpure)
|
||||
{
|
||||
fs_finds++;
|
||||
if (search->funcs->FindFile(search->handle, loc, filename, pf))
|
||||
{
|
||||
if (loc)
|
||||
|
@ -533,6 +535,7 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
|
|||
//
|
||||
for (search = com_searchpaths ; search ; search = search->next)
|
||||
{
|
||||
fs_finds++;
|
||||
if (search->funcs->FindFile(search->handle, loc, filename, pf))
|
||||
{
|
||||
search->referenced |= fs_referencetype;
|
||||
|
@ -1156,7 +1159,7 @@ qbyte *COM_LoadTempFile (const char *path)
|
|||
{
|
||||
return COM_LoadFile (path, 2);
|
||||
}
|
||||
qbyte *COM_LoadTempFile2 (const char *path)
|
||||
qbyte *COM_LoadTempMoreFile (const char *path)
|
||||
{
|
||||
return COM_LoadFile (path, 6);
|
||||
}
|
||||
|
@ -1342,6 +1345,7 @@ static int FS_AddWildDataFiles (const char *descriptor, int size, void *vparam)
|
|||
|
||||
search = param->parentpath;
|
||||
|
||||
fs_finds++;
|
||||
if (!search->funcs->FindFile(search->handle, &loc, descriptor, NULL))
|
||||
return true; //not found..
|
||||
vfs = search->funcs->OpenVFS(search->handle, &loc, "rb");
|
||||
|
@ -1377,6 +1381,7 @@ static void FS_AddDataFiles(const char *purepath, const char *pathto, searchpath
|
|||
for (i=0 ; ; i++)
|
||||
{
|
||||
snprintf (pakfile, sizeof(pakfile), "pak%i.%s", i, extension);
|
||||
fs_finds++;
|
||||
if (!search->funcs->FindFile(search->handle, &loc, pakfile, NULL))
|
||||
break; //not found..
|
||||
snprintf (pakfile, sizeof(pakfile), "%spak%i.%s", pathto, i, extension);
|
||||
|
|
|
@ -3658,6 +3658,8 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
|
|||
map_faces = NULL;
|
||||
map_leaffaces = NULL;
|
||||
|
||||
Q1BSPX_Setup(loadmodel, mod_base, com_filesize, header.lumps, Q3LUMPS_TOTAL);
|
||||
|
||||
switch(qrenderer)
|
||||
{
|
||||
#if defined(GLQUAKE)
|
||||
|
@ -3812,6 +3814,8 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
|
|||
header.lumps[i].fileofs = LittleLong (header.lumps[i].fileofs);
|
||||
}
|
||||
|
||||
Q1BSPX_Setup(loadmodel, mod_base, com_filesize, header.lumps, Q2HEADER_LUMPS);
|
||||
|
||||
#ifndef SERVERONLY
|
||||
if (CM_GetQ2Palette())
|
||||
memcpy(d_q28to24table, host_basepal, 768);
|
||||
|
|
|
@ -132,6 +132,9 @@ typedef struct
|
|||
int drop_count; // dropped packets, cleared each level
|
||||
int good_count; // cleared each level
|
||||
|
||||
int bytesin;
|
||||
int bytesout;
|
||||
|
||||
netadr_t remote_address;
|
||||
netsrc_t sock;
|
||||
int qport;
|
||||
|
|
|
@ -313,7 +313,7 @@ qboolean Netchan_CanPacket (netchan_t *chan, int rate)
|
|||
return true; //don't ever drop packets due to possible routing problems when there is no routing.
|
||||
if (!rate)
|
||||
return true;
|
||||
if (chan->cleartime < realtime + MAX_BACKUP/(float)rate)
|
||||
if (chan->cleartime < realtime + 0.25)//(MAX_BACKUP/(float)rate))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ void Netchan_Block (netchan_t *chan, int bytes, int rate)
|
|||
if (rate)
|
||||
{
|
||||
if (chan->cleartime < realtime-0.25) //0.25 allows it to be a little bursty.
|
||||
chan->cleartime = realtime + bytes/(float)rate;
|
||||
chan->cleartime = realtime + (bytes/(float)rate);
|
||||
else
|
||||
chan->cleartime += bytes/(float)rate;
|
||||
}
|
||||
|
@ -355,6 +355,7 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
|
|||
int sequence;
|
||||
int drop;
|
||||
|
||||
chan->bytesin += net_message.cursize;
|
||||
MSG_BeginReading (chan->netprim);
|
||||
|
||||
header = LongSwap(MSG_ReadLong());
|
||||
|
@ -411,6 +412,13 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
|
|||
}
|
||||
chan->incoming_unreliable = sequence;
|
||||
|
||||
|
||||
|
||||
// chan->frame_latency = chan->frame_latency*OLD_AVG
|
||||
// + (chan->outgoing_sequence-sequence_ack)*(1.0-OLD_AVG);
|
||||
chan->frame_rate = chan->frame_rate*OLD_AVG
|
||||
+ (realtime-chan->last_received)*(1.0-OLD_AVG);
|
||||
|
||||
chan->last_received = realtime;
|
||||
|
||||
chan->incoming_acknowledged++;
|
||||
|
@ -534,8 +542,8 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
else
|
||||
*(int*)send_buf = BigLong(NETFLAG_DATA | send.cursize);
|
||||
NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address);
|
||||
chan->bytesout += send.cursize;
|
||||
|
||||
Netchan_Block(chan, send.cursize, rate);
|
||||
sentsize += send.cursize;
|
||||
|
||||
if (showpackets.value)
|
||||
|
@ -560,8 +568,6 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
|
||||
*(int*)send_buf = BigLong(NETFLAG_UNRELIABLE | send.cursize);
|
||||
NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address);
|
||||
|
||||
Netchan_Block(chan, send.cursize, rate);
|
||||
sentsize += send.cursize;
|
||||
|
||||
if (showpackets.value)
|
||||
|
@ -570,6 +576,8 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
, send.cursize);
|
||||
send.cursize = 0;
|
||||
}
|
||||
chan->bytesout += sentsize;
|
||||
Netchan_Block(chan, sentsize, rate);
|
||||
return sentsize;
|
||||
}
|
||||
#endif
|
||||
|
@ -700,6 +708,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
}
|
||||
}
|
||||
|
||||
chan->bytesout += send.cursize;
|
||||
Netchan_Block(chan, send.cursize, rate);
|
||||
#ifdef SERVERONLY
|
||||
if (ServerPaused())
|
||||
|
@ -742,6 +751,8 @@ qboolean Netchan_Process (netchan_t *chan)
|
|||
!NET_CompareAdr (net_from, chan->remote_address))
|
||||
return false;
|
||||
|
||||
chan->bytesin += net_message.cursize;
|
||||
|
||||
// get sequence numbers
|
||||
MSG_BeginReading (chan->netprim);
|
||||
sequence = MSG_ReadLong ();
|
||||
|
|
|
@ -2929,6 +2929,7 @@ int NET_LocalAddressForRemote(ftenet_connections_t *collection, netadr_t *remote
|
|||
|
||||
void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
|
||||
{
|
||||
char buffer[64];
|
||||
ftenet_connections_t *collection;
|
||||
int i;
|
||||
|
||||
|
@ -2975,7 +2976,7 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
|
|||
return;
|
||||
}
|
||||
|
||||
Con_Printf("No route - open some ports\n");
|
||||
Con_Printf("No route to %s - open some ports\n", NET_AdrToString(buffer, sizeof(buffer), to));
|
||||
}
|
||||
|
||||
qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char *host, qboolean islisten)
|
||||
|
|
|
@ -927,6 +927,8 @@ void PM_CheckWaterJump (void)
|
|||
|
||||
if (pmove.waterjumptime>0)
|
||||
return;
|
||||
if (pmove.pm_type == PM_DEAD)
|
||||
return;
|
||||
|
||||
// don't hop out if we just jumped in
|
||||
if (pmove.velocity[2] < -180)
|
||||
|
|
|
@ -616,6 +616,7 @@ enum clcq2_ops_e
|
|||
#define FITZU_FRAME2 (1<<17)
|
||||
#define FITZU_MODEL2 (1<<18)
|
||||
#define FITZU_LERPFINISH (1<<19)
|
||||
#define RMQU_SCALE (1<<20)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -346,9 +346,351 @@ qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
|||
}
|
||||
#endif
|
||||
|
||||
int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
|
||||
|
||||
/*
|
||||
the bsp tree we're walking through is the renderable hull
|
||||
we need to trace a box through the world.
|
||||
by its very nature, this will reach more nodes than we really want, and as we can follow a node sideways, the underlying bsp structure is no longer 100% reliable (meaning we cross planes that are entirely to one side, and follow its children too)
|
||||
so all contents and solidity must come from the brushes and ONLY the brushes.
|
||||
*/
|
||||
struct traceinfo_s
|
||||
{
|
||||
switch(Q1_HullPointContents(hull, hull->firstclipnode, p))
|
||||
unsigned int solidcontents;
|
||||
trace_t trace;
|
||||
|
||||
qboolean sphere;
|
||||
float radius;
|
||||
/*set even for sphere traces (used for bbox tests)*/
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
|
||||
vec3_t start;
|
||||
vec3_t end;
|
||||
};
|
||||
|
||||
#include "shader.h"
|
||||
void TestDrawPlane(float *normal, float dist, float r, float g, float b)
|
||||
{
|
||||
scenetris_t *t;
|
||||
if (cl_numstris == cl_maxstris)
|
||||
{
|
||||
cl_maxstris+=8;
|
||||
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
|
||||
}
|
||||
t = &cl_stris[cl_numstris++];
|
||||
t->shader = R_RegisterShader("testplane", "{\n{\nmap $whiteimage\nrgbgen vertex\nalphagen vertex\nblendfunc add\nnodepth\n}\n}\n");
|
||||
t->firstidx = cl_numstrisidx;
|
||||
t->firstvert = cl_numstrisvert;
|
||||
t->numvert = 0;
|
||||
t->numidx = 0;
|
||||
|
||||
if (cl_numstrisidx+6 > cl_maxstrisidx)
|
||||
{
|
||||
cl_maxstrisidx=cl_numstrisidx+6 + 64;
|
||||
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
|
||||
}
|
||||
if (cl_numstrisvert+4 > cl_maxstrisvert)
|
||||
{
|
||||
cl_maxstrisvert+=64;
|
||||
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
|
||||
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
|
||||
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
|
||||
}
|
||||
|
||||
{
|
||||
vec3_t tmp = {0,0.04,0.96};
|
||||
vec3_t right, forward;
|
||||
CrossProduct(normal, tmp, right);
|
||||
VectorNormalize(right);
|
||||
CrossProduct(normal, right, forward);
|
||||
VectorNormalize(forward);
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*build the triangles*/
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 0;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 1;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 2;
|
||||
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 0;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 2;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 3;
|
||||
|
||||
|
||||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
t->numvert += 4;
|
||||
}
|
||||
|
||||
static void Q1BSP_ClipToBrushes(struct traceinfo_s *traceinfo, mbrush_t *brush)
|
||||
{
|
||||
struct mbrushplane_s *plane;
|
||||
struct mbrushplane_s *enterplane;
|
||||
int i, j;
|
||||
vec3_t ofs;
|
||||
qboolean startout, endout;
|
||||
float d1,d2,dist,enterdist=0;
|
||||
float f, enterfrac, exitfrac;
|
||||
|
||||
for (; brush; brush = brush->next)
|
||||
{
|
||||
/*ignore if its not solid to us*/
|
||||
if (!(traceinfo->solidcontents & brush->contents))
|
||||
continue;
|
||||
|
||||
startout = false;
|
||||
endout = false;
|
||||
enterplane= NULL;
|
||||
enterfrac = -1;
|
||||
exitfrac = 10;
|
||||
for (i = brush->numplanes, plane = brush->planes; i; i--, plane++)
|
||||
{
|
||||
/*calculate the distance based upon the shape of the object we're tracing for*/
|
||||
if (traceinfo->sphere)
|
||||
{
|
||||
dist = plane->dist + traceinfo->radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
if (plane->normal[j] < 0)
|
||||
ofs[j] = traceinfo->maxs[j];
|
||||
else
|
||||
ofs[j] = traceinfo->mins[j];
|
||||
}
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
}
|
||||
|
||||
d1 = DotProduct (traceinfo->start, plane->normal) - dist;
|
||||
d2 = DotProduct (traceinfo->end, plane->normal) - dist;
|
||||
|
||||
if (d1 >= 0)
|
||||
startout = true;
|
||||
if (d2 > 0)
|
||||
endout = true;
|
||||
|
||||
//if we're fully outside any plane, then we cannot possibly enter the brush, skip to the next one
|
||||
if (d1 > 0 && d2 >= 0)
|
||||
goto nextbrush;
|
||||
|
||||
//if we're fully inside the plane, then whatever is happening is not relevent for this plane
|
||||
if (d1 < 0 && d2 <= 0)
|
||||
continue;
|
||||
|
||||
f = d1 / (d1-d2);
|
||||
if (d1 > d2)
|
||||
{
|
||||
//entered the brush. favour the furthest fraction to avoid extended edges (yay for convex shapes)
|
||||
if (enterfrac < f)
|
||||
{
|
||||
enterfrac = f;
|
||||
enterplane = plane;
|
||||
enterdist = dist;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//left the brush, favour the nearest plane (smallest frac)
|
||||
if (exitfrac > f)
|
||||
{
|
||||
exitfrac = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!startout)
|
||||
{
|
||||
traceinfo->trace.startsolid = true;
|
||||
if (!endout)
|
||||
traceinfo->trace.allsolid = true;
|
||||
traceinfo->trace.contents |= brush->contents;
|
||||
return;
|
||||
}
|
||||
if (enterfrac != -1 && enterfrac < exitfrac)
|
||||
{
|
||||
//impact!
|
||||
if (enterfrac < traceinfo->trace.fraction)
|
||||
{
|
||||
traceinfo->trace.fraction = enterfrac;
|
||||
traceinfo->trace.plane.dist = enterdist;
|
||||
VectorCopy(enterplane->normal, traceinfo->trace.plane.normal);
|
||||
traceinfo->trace.contents = brush->contents;
|
||||
}
|
||||
}
|
||||
nextbrush:
|
||||
;
|
||||
}
|
||||
}
|
||||
static void Q1BSP_InsertBrush(mnode_t *node, mbrush_t *brush, vec3_t bmins, vec3_t bmaxs)
|
||||
{
|
||||
vec3_t near, far;
|
||||
float nd, fd;
|
||||
int i;
|
||||
while(1)
|
||||
{
|
||||
if (node->contents < 0) /*leaf, so no smaller node to put it in (I'd be surprised if it got this far)*/
|
||||
{
|
||||
brush->next = node->brushes;
|
||||
node->brushes = brush;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (node->plane->normal[i] > 0)
|
||||
{
|
||||
near[i] = bmins[i];
|
||||
far[i] = bmaxs[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
near[i] = bmaxs[i];
|
||||
far[i] = bmins[i];
|
||||
}
|
||||
}
|
||||
|
||||
nd = DotProduct(node->plane->normal, near) - node->plane->dist;
|
||||
fd = DotProduct(node->plane->normal, far) - node->plane->dist;
|
||||
|
||||
/*if its fully on either side, continue walking*/
|
||||
if (nd < 0 && fd < 0)
|
||||
node = node->children[1];
|
||||
else if (nd > 0 && fd > 0)
|
||||
node = node->children[0];
|
||||
else
|
||||
{
|
||||
/*plane crosses bbox, so insert here*/
|
||||
brush->next = node->brushes;
|
||||
node->brushes = brush;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void Q1BSP_RecursiveBrushCheck (struct traceinfo_s *traceinfo, mnode_t *node, float p1f, float p2f, vec3_t p1, vec3_t p2)
|
||||
{
|
||||
mplane_t *plane;
|
||||
float t1, t2;
|
||||
float frac;
|
||||
int i;
|
||||
vec3_t mid;
|
||||
int side;
|
||||
float midf;
|
||||
float offset;
|
||||
|
||||
if (node->brushes)
|
||||
{
|
||||
Q1BSP_ClipToBrushes(traceinfo, node->brushes);
|
||||
}
|
||||
|
||||
if (traceinfo->trace.fraction < p1f)
|
||||
{
|
||||
//already hit something closer than this node
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->contents < 0)
|
||||
{
|
||||
//we're in a leaf
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// find the point distances
|
||||
//
|
||||
plane = node->plane;
|
||||
|
||||
if (plane->type < 3)
|
||||
{
|
||||
t1 = p1[plane->type] - plane->dist;
|
||||
t2 = p2[plane->type] - plane->dist;
|
||||
if (plane->normal[plane->type] < 0)
|
||||
offset = -traceinfo->mins[plane->type];
|
||||
else
|
||||
offset = traceinfo->maxs[plane->type];
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 = DotProduct (plane->normal, p1) - plane->dist;
|
||||
t2 = DotProduct (plane->normal, p2) - plane->dist;
|
||||
offset = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (plane->normal[i] < 0)
|
||||
offset += plane->normal[i] * -traceinfo->mins[i];
|
||||
else
|
||||
offset += plane->normal[i] * traceinfo->maxs[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*if we're fully on one side of the trace, go only down that side*/
|
||||
if (t1 >= offset && t2 >= offset)
|
||||
{
|
||||
Q1BSP_RecursiveBrushCheck (traceinfo, node->children[0], p1f, p2f, p1, p2);
|
||||
return;
|
||||
}
|
||||
if (t1 < -offset && t2 < -offset)
|
||||
{
|
||||
Q1BSP_RecursiveBrushCheck (traceinfo, node->children[1], p1f, p2f, p1, p2);
|
||||
return;
|
||||
}
|
||||
|
||||
// put the crosspoint DIST_EPSILON pixels on the near side
|
||||
if (t1 < 0)
|
||||
{
|
||||
frac = (t1 + DIST_EPSILON)/(t1-t2);
|
||||
side = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
frac = (t1 - DIST_EPSILON)/(t1-t2);
|
||||
side = 0;
|
||||
}
|
||||
if (frac < 0)
|
||||
frac = 0;
|
||||
if (frac > 1)
|
||||
frac = 1;
|
||||
|
||||
midf = p1f + (p2f - p1f)*frac;
|
||||
for (i=0 ; i<3 ; i++)
|
||||
mid[i] = p1[i] + frac*(p2[i] - p1[i]);
|
||||
|
||||
// move up to the node
|
||||
Q1BSP_RecursiveBrushCheck (traceinfo, node->children[side], p1f, midf, p1, mid);
|
||||
|
||||
// go past the node
|
||||
Q1BSP_RecursiveBrushCheck (traceinfo, node->children[side^1], midf, p2f, mid, p2);
|
||||
}
|
||||
|
||||
static unsigned int Q1BSP_TranslateContents(int contents)
|
||||
{
|
||||
switch(contents)
|
||||
{
|
||||
case Q1CONTENTS_EMPTY:
|
||||
return FTECONTENTS_EMPTY;
|
||||
|
@ -362,12 +704,19 @@ int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
|
|||
return FTECONTENTS_LAVA;
|
||||
case Q1CONTENTS_SKY:
|
||||
return FTECONTENTS_SKY;
|
||||
case Q1CONTENTS_LADDER:
|
||||
return FTECONTENTS_LADDER;
|
||||
default:
|
||||
Sys_Error("Q1_PointContents: Unknown contents type");
|
||||
Sys_Error("Q1BSP_TranslateContents: Unknown contents type - %i", contents);
|
||||
return FTECONTENTS_SOLID;
|
||||
}
|
||||
}
|
||||
|
||||
int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
|
||||
{
|
||||
return Q1BSP_TranslateContents(Q1_HullPointContents(hull, hull->firstclipnode, p));
|
||||
}
|
||||
|
||||
unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
|
||||
{
|
||||
if (axis)
|
||||
|
@ -381,6 +730,121 @@ unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
|
|||
return Q1BSP_HullPointContents(&model->hulls[0], point);
|
||||
}
|
||||
|
||||
void Q1BSP_LoadBrushes(model_t *model)
|
||||
{
|
||||
struct {
|
||||
unsigned int ver;
|
||||
unsigned int modelnum;
|
||||
unsigned int numbrushes;
|
||||
unsigned int numplanes;
|
||||
} *permodel;
|
||||
struct {
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
signed short contents;
|
||||
unsigned short numplanes;
|
||||
} *perbrush;
|
||||
/*
|
||||
Note to implementors:
|
||||
a pointy brush with angles pointier than 90 degrees will extend further than any adjacent brush, thus creating invisible walls with larger expansions.
|
||||
the engine inserts 6 axial planes acording to the bbox, thus the qbsp need not write any axial planes
|
||||
note that doing it this way probably isn't good if you want to query textures...
|
||||
*/
|
||||
struct {
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
} *perplane;
|
||||
|
||||
static vec3_t axis[3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||
int br, pl, remainingplanes;
|
||||
mbrush_t *brush;
|
||||
mnode_t *rootnode;
|
||||
unsigned int lumpsizeremaining;
|
||||
|
||||
model->engineflags &= ~MDLF_HASBRUSHES;
|
||||
|
||||
permodel = Q1BSPX_FindLump("BRUSHLIST", &lumpsizeremaining);
|
||||
if (!permodel)
|
||||
return;
|
||||
|
||||
while (lumpsizeremaining)
|
||||
{
|
||||
if (lumpsizeremaining < sizeof(*permodel))
|
||||
return;
|
||||
permodel->ver = LittleLong(permodel->ver);
|
||||
permodel->modelnum = LittleLong(permodel->modelnum);
|
||||
permodel->numbrushes = LittleLong(permodel->numbrushes);
|
||||
permodel->numplanes = LittleLong(permodel->numplanes);
|
||||
if (permodel->ver != 1 || lumpsizeremaining < sizeof(*permodel) + permodel->numbrushes*sizeof(*perbrush) + permodel->numplanes*sizeof(*perplane))
|
||||
return;
|
||||
|
||||
//find the correct rootnode for the model
|
||||
rootnode = model->nodes;
|
||||
if (permodel->modelnum > model->numsubmodels)
|
||||
return;
|
||||
if (permodel->modelnum)
|
||||
rootnode += model->submodels[permodel->modelnum-1].headnode[0];
|
||||
|
||||
brush = Hunk_Alloc((sizeof(*brush) - sizeof(brush->planes[0]))*permodel->numbrushes + sizeof(brush->planes[0])*(permodel->numbrushes*6+permodel->numplanes));
|
||||
remainingplanes = permodel->numplanes;
|
||||
perbrush = (void*)(permodel+1);
|
||||
for (br = 0; br < permodel->numbrushes; br++)
|
||||
{
|
||||
/*byteswap it all in place*/
|
||||
perbrush->mins[0] = LittleFloat(perbrush->mins[0]);
|
||||
perbrush->mins[1] = LittleFloat(perbrush->mins[1]);
|
||||
perbrush->mins[2] = LittleFloat(perbrush->mins[2]);
|
||||
perbrush->maxs[0] = LittleFloat(perbrush->maxs[0]);
|
||||
perbrush->maxs[1] = LittleFloat(perbrush->maxs[1]);
|
||||
perbrush->maxs[2] = LittleFloat(perbrush->maxs[2]);
|
||||
perbrush->contents = LittleShort(perbrush->contents);
|
||||
perbrush->numplanes = LittleShort(perbrush->numplanes);
|
||||
|
||||
/*make sure planes don't overflow*/
|
||||
if (perbrush->numplanes > remainingplanes)
|
||||
return;
|
||||
remainingplanes-=perbrush->numplanes;
|
||||
|
||||
/*set up the mbrush from the file*/
|
||||
brush->contents = Q1BSP_TranslateContents(perbrush->contents);
|
||||
brush->numplanes = perbrush->numplanes;
|
||||
for (pl = 0, perplane = (void*)(perbrush+1); pl < perbrush->numplanes; pl++, perplane++)
|
||||
{
|
||||
brush->planes[pl].normal[0] = LittleFloat(perplane->normal[0]);
|
||||
brush->planes[pl].normal[1] = LittleFloat(perplane->normal[1]);
|
||||
brush->planes[pl].normal[2] = LittleFloat(perplane->normal[2]);
|
||||
brush->planes[pl].dist = LittleFloat(perplane->dist);
|
||||
}
|
||||
|
||||
/*and add axial planes acording to the brush's bbox*/
|
||||
for (pl = 0; pl < 3; pl++)
|
||||
{
|
||||
VectorCopy(axis[pl], brush->planes[brush->numplanes].normal);
|
||||
brush->planes[brush->numplanes].dist = perbrush->maxs[pl];
|
||||
brush->numplanes++;
|
||||
}
|
||||
for (pl = 0; pl < 3; pl++)
|
||||
{
|
||||
VectorNegate(axis[pl], brush->planes[brush->numplanes].normal);
|
||||
brush->planes[brush->numplanes].dist = -perbrush->mins[pl];
|
||||
brush->numplanes++;
|
||||
}
|
||||
|
||||
/*link it in to the bsp tree*/
|
||||
Q1BSP_InsertBrush(rootnode, brush, perbrush->mins, perbrush->maxs);
|
||||
|
||||
/*set up for the next brush*/
|
||||
brush = (void*)&brush->planes[brush->numplanes];
|
||||
perbrush = (void*)perplane;
|
||||
}
|
||||
/*move on to the next model*/
|
||||
lumpsizeremaining -= sizeof(*permodel) + permodel->numbrushes*sizeof(*perbrush) + permodel->numplanes*sizeof(*perplane);
|
||||
permodel = (void*)((char*)permodel + sizeof(*permodel) + permodel->numbrushes*sizeof(*perbrush) + permodel->numplanes*sizeof(*perplane));
|
||||
}
|
||||
/*parsing was successful! flag it as okay*/
|
||||
model->engineflags |= MDLF_HASBRUSHES;
|
||||
}
|
||||
|
||||
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, trace_t *trace)
|
||||
{
|
||||
hull_t *hull;
|
||||
|
@ -388,11 +852,47 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3]
|
|||
vec3_t start_l, end_l;
|
||||
vec3_t offset;
|
||||
|
||||
VectorSubtract (maxs, mins, size);
|
||||
if ((model->engineflags & MDLF_HASBRUSHES))// && (size[0] || size[1] || size[2]))
|
||||
{
|
||||
struct traceinfo_s traceinfo;
|
||||
memset (&traceinfo.trace, 0, sizeof(trace_t));
|
||||
traceinfo.trace.fraction = 1;
|
||||
traceinfo.trace.allsolid = false;
|
||||
VectorCopy(mins, traceinfo.mins);
|
||||
VectorCopy(maxs, traceinfo.maxs);
|
||||
VectorCopy(start, traceinfo.start);
|
||||
VectorCopy(end, traceinfo.end);
|
||||
traceinfo.sphere = false;
|
||||
/* traceinfo.sphere = true;
|
||||
traceinfo.radius = 48;
|
||||
traceinfo.mins[0] = -traceinfo.radius;
|
||||
traceinfo.mins[1] = -traceinfo.radius;
|
||||
traceinfo.mins[2] = -traceinfo.radius;
|
||||
traceinfo.maxs[0] = traceinfo.radius;
|
||||
traceinfo.maxs[1] = traceinfo.radius;
|
||||
traceinfo.maxs[2] = traceinfo.radius;
|
||||
*/
|
||||
traceinfo.solidcontents = hitcontentsmask;
|
||||
Q1BSP_RecursiveBrushCheck(&traceinfo, model->nodes, 0, 1, start, end);
|
||||
memcpy(trace, &traceinfo.trace, sizeof(trace_t));
|
||||
if (trace->fraction < 1)
|
||||
{
|
||||
float d1 = DotProduct(start, trace->plane.normal) - trace->plane.dist;
|
||||
float d2 = DotProduct(end, trace->plane.normal) - trace->plane.dist;
|
||||
float f = (d1 - DIST_EPSILON) / (d1 - d2);
|
||||
if (f < 0)
|
||||
f = 0;
|
||||
trace->fraction = f;
|
||||
}
|
||||
VectorInterpolate(start, trace->fraction, end, trace->endpos);
|
||||
return trace->fraction != 1;
|
||||
}
|
||||
|
||||
memset (trace, 0, sizeof(trace_t));
|
||||
trace->fraction = 1;
|
||||
trace->allsolid = true;
|
||||
|
||||
VectorSubtract (maxs, mins, size);
|
||||
if (forcehullnum >= 1 && forcehullnum <= MAX_MAP_HULLSM && model->hulls[forcehullnum-1].available)
|
||||
hull = &model->hulls[forcehullnum-1];
|
||||
else
|
||||
|
@ -1375,11 +1875,79 @@ PVS type stuff
|
|||
Init stuff
|
||||
*/
|
||||
|
||||
|
||||
void Q1BSP_Init(void)
|
||||
{
|
||||
memset (mod_novis, 0xff, sizeof(mod_novis));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char lumpname[24]; // up to 23 chars, zero-padded
|
||||
int fileofs; // from file start
|
||||
int filelen;
|
||||
} bspx_lump_t;
|
||||
typedef struct {
|
||||
char id[4]; // 'BSPX'
|
||||
int numlumps;
|
||||
bspx_lump_t lumps[1];
|
||||
} bspx_header_t;
|
||||
static char *bspxbase;
|
||||
static bspx_header_t *bspxheader;
|
||||
//supported lumps:
|
||||
//RGBLIGHTING (.lit)
|
||||
//LIGHTINGDIR (.lux)
|
||||
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize)
|
||||
{
|
||||
int i;
|
||||
if (!bspxheader)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < bspxheader->numlumps; i++)
|
||||
{
|
||||
if (!strncmp(bspxheader->lumps[i].lumpname, lumpname, 24))
|
||||
{
|
||||
*lumpsize = bspxheader->lumps[i].filelen;
|
||||
return bspxbase + bspxheader->lumps[i].fileofs;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void Q1BSPX_Setup(model_t *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps)
|
||||
{
|
||||
int i;
|
||||
int offs = 0;
|
||||
bspx_header_t *h;
|
||||
|
||||
bspxbase = filebase;
|
||||
bspxheader = NULL;
|
||||
|
||||
for (i = 0; i < numlumps; i++, lumps++)
|
||||
{
|
||||
if (offs < lumps->fileofs + lumps->filelen)
|
||||
offs = lumps->fileofs + lumps->filelen;
|
||||
}
|
||||
offs = (offs + 3) & ~3;
|
||||
if (offs + sizeof(*bspxheader) > filelen)
|
||||
return; /*no space for it*/
|
||||
h = (bspx_header_t*)(filebase + offs);
|
||||
|
||||
i = LittleLong(h->numlumps);
|
||||
/*verify the header*/
|
||||
if (*(int*)h->id != *(int*)"BSPX" ||
|
||||
i < 0 ||
|
||||
offs + sizeof(*h) + sizeof(h->lumps[0])*(i-1) > filelen)
|
||||
return;
|
||||
h->numlumps = i;
|
||||
while(i-->0)
|
||||
{
|
||||
h->lumps[i].fileofs = LittleLong(h->lumps[i].fileofs);
|
||||
h->lumps[i].filelen = LittleLong(h->lumps[i].filelen);
|
||||
if (h->lumps[i].fileofs + h->lumps[i].filelen > filelen)
|
||||
return;
|
||||
}
|
||||
|
||||
bspxheader = h;
|
||||
}
|
||||
|
||||
//sets up the functions a server needs.
|
||||
//fills in bspfuncs_t
|
||||
|
|
|
@ -1677,6 +1677,7 @@ void *Cache_Check(cache_user_t *c)
|
|||
|
||||
void Cache_Flush(void)
|
||||
{
|
||||
S_Purge(false);
|
||||
while(cache_head)
|
||||
{
|
||||
Cache_Free(cache_head->user);
|
||||
|
|
|
@ -101,60 +101,151 @@ public class FTEDroidActivity extends Activity
|
|||
private class FTEView extends GLSurfaceView implements SensorEventListener
|
||||
{
|
||||
private final FTERenderer rndr;
|
||||
|
||||
private byte[] audbuf;
|
||||
private AudioTrack at;
|
||||
|
||||
private audiothreadclass audiothread;
|
||||
private class audiothreadclass extends Thread
|
||||
{
|
||||
boolean timetodie;
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
byte[] audbuf = new byte[2048];
|
||||
int avail;
|
||||
|
||||
int sspeed = 11025;
|
||||
int speakers = 1;
|
||||
int sz = 4*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
||||
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT, sz, AudioTrack.MODE_STREAM);
|
||||
|
||||
at.setStereoVolume(1, 1);
|
||||
at.play();
|
||||
|
||||
|
||||
while(!timetodie)
|
||||
{
|
||||
avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
|
||||
at.write(audbuf, 0, avail);
|
||||
}
|
||||
|
||||
at.stop();
|
||||
}
|
||||
public void killoff()
|
||||
{
|
||||
timetodie = true;
|
||||
try
|
||||
{
|
||||
join();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void audioInit()
|
||||
{
|
||||
final int notifframes = 2048;
|
||||
if (at != null)
|
||||
at.stop();
|
||||
int sspeed = 11025;
|
||||
int speakers = 1;
|
||||
int sz = 4*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT);
|
||||
if (sz < notifframes*2)
|
||||
sz = notifframes*2;
|
||||
|
||||
at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT, sz, AudioTrack.MODE_STREAM);
|
||||
final int framesz = 2; /*mono 16bit*/
|
||||
audbuf = new byte[notifframes*framesz];
|
||||
|
||||
at.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener()
|
||||
if (audiothread == null)
|
||||
{
|
||||
@Override
|
||||
public void onMarkerReached(AudioTrack track)
|
||||
{
|
||||
}
|
||||
@Override
|
||||
public void onPeriodicNotification(AudioTrack track)
|
||||
{
|
||||
int avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
|
||||
at.write(audbuf, 0, notifframes*framesz);
|
||||
}
|
||||
});
|
||||
at.setPositionNotificationPeriod(notifframes);
|
||||
|
||||
at.setStereoVolume(1, 1);
|
||||
|
||||
at.play();
|
||||
/*buffer needs to be completely full before it'll start playing*/
|
||||
while(sz > 0)
|
||||
{
|
||||
at.write(audbuf, 0, notifframes*framesz);
|
||||
sz -= notifframes;
|
||||
audiothread = new audiothreadclass();
|
||||
audiothread.start();
|
||||
}
|
||||
}
|
||||
public void resume()
|
||||
public void audioStop()
|
||||
{
|
||||
/*poke audio into submission*/
|
||||
if (at != null)
|
||||
at.play();
|
||||
if (audiothread != null)
|
||||
{
|
||||
audiothread.killoff();
|
||||
audiothread = null;
|
||||
}
|
||||
}
|
||||
public void audioResume()
|
||||
{
|
||||
audioStop();
|
||||
audioInit();
|
||||
}
|
||||
|
||||
private FTELegacyInputEvent inputevent;
|
||||
class FTEMultiTouchInputEvent extends FTELegacyInputEvent
|
||||
{
|
||||
/*Requires API level 5+ (android 2.0+)*/
|
||||
private void domove(MotionEvent event)
|
||||
{
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int i;
|
||||
for (i = 0; i < pointerCount; i++)
|
||||
FTEDroidEngine.motion(0, event.getPointerId(i), event.getX(i), event.getY(i));
|
||||
}
|
||||
|
||||
public boolean go(MotionEvent event)
|
||||
{
|
||||
int id;
|
||||
float x, y;
|
||||
final int act = event.getAction();
|
||||
|
||||
domove(event);
|
||||
|
||||
switch(act & event.ACTION_MASK)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(1, id, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(2, id, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
class FTELegacyInputEvent
|
||||
{
|
||||
public boolean go(MotionEvent event)
|
||||
{
|
||||
final int act = event.getAction();
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
|
||||
FTEDroidEngine.motion(0, 0, x, y);
|
||||
|
||||
switch(act)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
FTEDroidEngine.motion(1, 0, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
FTEDroidEngine.motion(2, 0, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public FTEView(FTEDroidActivity context)
|
||||
{
|
||||
super(context);
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 5)
|
||||
inputevent = new FTEMultiTouchInputEvent();
|
||||
else
|
||||
inputevent = new FTELegacyInputEvent();
|
||||
|
||||
rndr = new FTERenderer(context, context);
|
||||
// setEGLConfigChooser(new FTEEGLConfig());
|
||||
|
@ -169,90 +260,12 @@ public class FTEDroidActivity extends Activity
|
|||
|
||||
private void sendKey(final boolean presseddown, final int qcode, final int unicode)
|
||||
{
|
||||
queueEvent(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
FTEDroidEngine.keypress(presseddown?1:0, qcode, unicode);
|
||||
}
|
||||
});
|
||||
FTEDroidEngine.keypress(presseddown?1:0, qcode, unicode);
|
||||
}
|
||||
@Override
|
||||
public boolean onTouchEvent(final MotionEvent event)
|
||||
public boolean onTouchEvent(MotionEvent event)
|
||||
{
|
||||
/*the test itself requires android 4...*/
|
||||
if (android.os.Build.VERSION.SDK_INT >= 5)
|
||||
{
|
||||
/*Requires API level 5+ (android 2.0+)*/
|
||||
queueEvent(new Runnable()
|
||||
{
|
||||
private void domove()
|
||||
{
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int i;
|
||||
for (i = 0; i < pointerCount; i++)
|
||||
FTEDroidEngine.motion(0, event.getPointerId(i), event.getX(i), event.getY(i));
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
int id;
|
||||
float x, y;
|
||||
final int act = event.getAction();
|
||||
|
||||
domove();
|
||||
|
||||
switch(act & event.ACTION_MASK)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(1, id, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(2, id, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
queueEvent(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
final int act = event.getAction();
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
|
||||
FTEDroidEngine.motion(0, 0, x, y);
|
||||
|
||||
switch(act)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
FTEDroidEngine.motion(1, 0, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
FTEDroidEngine.motion(2, 0, x, y);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
return inputevent.go(event);
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
|
@ -323,6 +336,12 @@ public class FTEDroidActivity extends Activity
|
|||
}
|
||||
}
|
||||
|
||||
private boolean runningintheemulator()
|
||||
{
|
||||
android.util.Log.i("FTEDroid", "model: " + android.os.Build.MODEL + " product: " + android.os.Build.PRODUCT + " device: " + android.os.Build.DEVICE);
|
||||
return android.os.Build.MODEL.equals("sdk") && android.os.Build.PRODUCT.equals("sdk") && android.os.Build.DEVICE.equals("generic");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
|
@ -339,11 +358,21 @@ public class FTEDroidActivity extends Activity
|
|||
// setContentView(R.layout.main);
|
||||
|
||||
|
||||
android.util.Log.i("FTEDroid", "init sensor manager");
|
||||
sensorman = (SensorManager)getSystemService(SENSOR_SERVICE);
|
||||
android.util.Log.i("FTEDroid", "init accelerometer");
|
||||
if (runningintheemulator())
|
||||
{
|
||||
android.util.Log.i("FTEDroid", "emulator detected - skipping sensors to avoid emulator hangs");
|
||||
sensorman = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
android.util.Log.i("FTEDroid", "init sensor manager");
|
||||
sensorman = (SensorManager)getSystemService(SENSOR_SERVICE);
|
||||
}
|
||||
if (sensorman != null)
|
||||
{
|
||||
android.util.Log.i("FTEDroid", "init accelerometer");
|
||||
sensoracc = sensorman.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
}
|
||||
android.util.Log.i("FTEDroid", "done");
|
||||
}
|
||||
|
||||
|
@ -354,7 +383,7 @@ public class FTEDroidActivity extends Activity
|
|||
if (sensorman != null && sensoracc != null)
|
||||
sensorman.registerListener((SensorEventListener)view, sensoracc, SensorManager.SENSOR_DELAY_GAME);
|
||||
|
||||
view.resume();
|
||||
view.audioResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -362,6 +391,7 @@ public class FTEDroidActivity extends Activity
|
|||
{
|
||||
if (sensorman != null && sensoracc != null)
|
||||
sensorman.unregisterListener(view);
|
||||
view.audioStop();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
|
@ -370,6 +400,7 @@ public class FTEDroidActivity extends Activity
|
|||
{
|
||||
if (sensorman != null && sensoracc != null)
|
||||
sensorman.unregisterListener(view);
|
||||
view.audioStop();
|
||||
super.onPause();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2685,12 +2685,7 @@ void GLBE_SelectMode(backendmode_t mode)
|
|||
case BEM_STENCIL:
|
||||
GL_DeSelectProgram();
|
||||
|
||||
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
|
||||
{
|
||||
shaderstate.curpolyoffset.factor = 0;
|
||||
shaderstate.curpolyoffset.unit = 0;
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
BE_PushOffsetShadow(false);
|
||||
|
||||
/*BEM_STENCIL doesn't support mesh writing*/
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
|
|
|
@ -245,6 +245,7 @@ void RMod_Think (void)
|
|||
#endif
|
||||
if (relitsurface >= lightmodel->numsurfaces)
|
||||
{
|
||||
vfsfile_t *f;
|
||||
char filename[MAX_QPATH];
|
||||
Con_Printf("Finished lighting %s\n", lightmodel->name);
|
||||
|
||||
|
@ -266,14 +267,30 @@ void RMod_Think (void)
|
|||
{
|
||||
COM_StripExtension(lightmodel->name, filename, sizeof(filename));
|
||||
COM_DefaultExtension(filename, ".lux", sizeof(filename));
|
||||
FS_WriteFile(filename, lightmodel->deluxdata-8, numlightdata*3+8, FS_GAME);
|
||||
f = FS_OpenVFS(filename, "wb", FS_GAMEONLY);
|
||||
if (f)
|
||||
{
|
||||
VFS_WRITE(f, "QLIT\1\0\0\0", 8);
|
||||
VFS_WRITE(f, lightmodel->deluxdata, numlightdata*3);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
else
|
||||
Con_Printf("Unable to write \"%s\"\n", filename);
|
||||
}
|
||||
|
||||
if (writelitfile) //the user might already have a lit file (don't overwrite it).
|
||||
{
|
||||
COM_StripExtension(lightmodel->name, filename, sizeof(filename));
|
||||
COM_DefaultExtension(filename, ".lit", sizeof(filename));
|
||||
FS_WriteFile(filename, lightmodel->lightdata-8, numlightdata*3+8, FS_GAME);
|
||||
f = FS_OpenVFS(filename, "wb", FS_GAMEONLY);
|
||||
if (f)
|
||||
{
|
||||
VFS_WRITE(f, "QLIT\1\0\0\0", 8);
|
||||
VFS_WRITE(f, lightmodel->lightdata, numlightdata*3);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
else
|
||||
Con_Printf("Unable to write \"%s\"\n", filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1059,6 +1076,8 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
|
|||
|
||||
if (!l->filelen)
|
||||
{
|
||||
Con_Printf(CON_WARNING "warning: %s contains no texture data\n", loadmodel->name);
|
||||
|
||||
loadmodel->numtextures = 1;
|
||||
loadmodel->textures = Hunk_AllocName (1 * sizeof(*loadmodel->textures), loadname);
|
||||
|
||||
|
@ -1376,8 +1395,8 @@ void RMod_NowLoadExternal(void)
|
|||
if (!TEXVALID(tn.base))
|
||||
{
|
||||
tn.base = R_LoadHiResTexture(tx->name, "bmodels", IF_NOALPHA|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.base))
|
||||
tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA|IF_MIPCAP); //a fallback. :/
|
||||
// if (!TEXVALID(tn.base))
|
||||
// tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA|IF_MIPCAP); //a fallback. :/
|
||||
}
|
||||
}
|
||||
if (!TEXVALID(tn.bump) && *tx->name != '{' && r_loadbumpmapping)
|
||||
|
@ -1446,9 +1465,15 @@ Mod_LoadLighting
|
|||
=================
|
||||
*/
|
||||
void RMod_LoadLighting (lump_t *l)
|
||||
{
|
||||
{
|
||||
qboolean luxtmp = true;
|
||||
qboolean littmp = true;
|
||||
qbyte *luxdata = NULL;
|
||||
int mapcomeswith24bitcolouredlighting = false;
|
||||
qbyte *litdata = NULL;
|
||||
qbyte *lumdata = NULL;
|
||||
qbyte *out;
|
||||
unsigned int samples;
|
||||
|
||||
extern cvar_t gl_overbright;
|
||||
loadmodel->engineflags &= ~MDLF_RGBLIGHTING;
|
||||
|
||||
|
@ -1468,15 +1493,20 @@ void RMod_LoadLighting (lump_t *l)
|
|||
|
||||
loadmodel->lightdata = NULL;
|
||||
loadmodel->deluxdata = NULL;
|
||||
if (!l->filelen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadmodel->fromgame == fg_halflife || loadmodel->fromgame == fg_quake2 || loadmodel->fromgame == fg_quake3)
|
||||
mapcomeswith24bitcolouredlighting = true;
|
||||
{
|
||||
litdata = mod_base + l->fileofs;
|
||||
samples = l->filelen/3;
|
||||
}
|
||||
else
|
||||
{
|
||||
lumdata = mod_base + l->fileofs;
|
||||
samples = l->filelen;
|
||||
}
|
||||
if (!samples)
|
||||
return;
|
||||
|
||||
if (!mapcomeswith24bitcolouredlighting && r_loadlits.ival && r_deluxemapping.ival) //fixme: adjust the light intensities.
|
||||
if (!luxdata && r_loadlits.ival && r_deluxemapping.ival)
|
||||
{ //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous.
|
||||
char luxname[MAX_QPATH];
|
||||
if (!luxdata)
|
||||
|
@ -1485,6 +1515,7 @@ void RMod_LoadLighting (lump_t *l)
|
|||
COM_StripExtension(loadmodel->name, luxname, sizeof(luxname));
|
||||
COM_DefaultExtension(luxname, ".lux", sizeof(luxname));
|
||||
luxdata = COM_LoadHunkFile(luxname);
|
||||
luxtmp = false;
|
||||
}
|
||||
if (!luxdata)
|
||||
{
|
||||
|
@ -1493,15 +1524,24 @@ void RMod_LoadLighting (lump_t *l)
|
|||
strcat(luxname, ".lux");
|
||||
|
||||
luxdata = COM_LoadHunkFile(luxname);
|
||||
luxtmp = false;
|
||||
}
|
||||
if (!luxdata)
|
||||
if (!luxdata) //dp...
|
||||
{
|
||||
COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5, sizeof(luxname)-5);
|
||||
COM_DefaultExtension(luxname, ".dlit", sizeof(luxname));
|
||||
luxdata = COM_LoadHunkFile(luxname);
|
||||
luxtmp = false;
|
||||
}
|
||||
|
||||
if (luxdata)
|
||||
if (!luxdata)
|
||||
{
|
||||
int size;
|
||||
luxdata = Q1BSPX_FindLump("LIGHTINGDIR", &size);
|
||||
if (size != samples*3)
|
||||
luxdata = NULL;
|
||||
luxtmp = true;
|
||||
}
|
||||
else if (luxdata)
|
||||
{
|
||||
if (l->filelen && l->filelen != (com_filesize-8)/3)
|
||||
{
|
||||
|
@ -1529,9 +1569,8 @@ void RMod_LoadLighting (lump_t *l)
|
|||
}
|
||||
}
|
||||
|
||||
if (!mapcomeswith24bitcolouredlighting && r_loadlits.value)
|
||||
if (!litdata && r_loadlits.value)
|
||||
{
|
||||
qbyte *litdata = NULL;
|
||||
char *litname;
|
||||
char litnamemaps[MAX_QPATH];
|
||||
char litnamelits[MAX_QPATH];
|
||||
|
@ -1559,51 +1598,55 @@ void RMod_LoadLighting (lump_t *l)
|
|||
}
|
||||
|
||||
litdata = COM_LoadHunkFile(litname);
|
||||
COM_StripExtension(COM_SkipPath(loadmodel->name), litname+5, sizeof(litname)-5);
|
||||
strcat(litname, ".lit");
|
||||
if (litdata && (litdata[0] == 'Q' && litdata[1] == 'L' && litdata[2] == 'I' && litdata[3] == 'T'))
|
||||
littmp = false;
|
||||
if (!litdata)
|
||||
{
|
||||
if (LittleLong(*(int *)&litdata[4]) == 1 && l->filelen && l->filelen != (com_filesize-8)/3)
|
||||
int size;
|
||||
litdata = Q1BSPX_FindLump("RGBLIGHTING", &size);
|
||||
if (size != samples*3)
|
||||
litdata = NULL;
|
||||
littmp = true;
|
||||
}
|
||||
else if (litdata[0] == 'Q' && litdata[1] == 'L' && litdata[2] == 'I' && litdata[3] == 'T')
|
||||
{
|
||||
if (LittleLong(*(int *)&litdata[4]) == 1 && l->filelen && samples*3 != (com_filesize-8))
|
||||
Con_Printf("lit \"%s\" doesn't match level. Ignored.\n", litname);
|
||||
else if (LittleLong(*(int *)&litdata[4]) != 1)
|
||||
Con_Printf("lit \"%s\" isn't version 1.\n", litname);
|
||||
else
|
||||
else if (lumdata)
|
||||
{
|
||||
float prop;
|
||||
int i;
|
||||
qbyte *normal;
|
||||
|
||||
//load it
|
||||
loadmodel->lightdata = litdata+8;
|
||||
loadmodel->engineflags |= MDLF_RGBLIGHTING;
|
||||
qbyte *lum;
|
||||
qbyte *lit;
|
||||
|
||||
litdata += 8;
|
||||
|
||||
//now some cheat protection.
|
||||
lum = lumdata;
|
||||
lit = litdata;
|
||||
|
||||
normal = mod_base + l->fileofs;
|
||||
litdata = loadmodel->lightdata;
|
||||
|
||||
for (i = 0; i < l->filelen; i++) //force it to the same intensity. (or less, depending on how you see it...)
|
||||
for (i = 0; i < samples; i++) //force it to the same intensity. (or less, depending on how you see it...)
|
||||
{
|
||||
#define m(a, b, c) (a>(b>c?b:c)?a:(b>c?b:c))
|
||||
prop = (float)m(litdata[0], litdata[1], litdata[2]);
|
||||
prop = (float)m(lit[0], lit[1], lit[2]);
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
litdata[0] = lmgamma[*normal];
|
||||
litdata[1] = lmgamma[*normal];
|
||||
litdata[2] = lmgamma[*normal];
|
||||
lit[0] = *lum;
|
||||
lit[1] = *lum;
|
||||
lit[2] = *lum;
|
||||
}
|
||||
else
|
||||
{
|
||||
prop = lmgamma[*normal] / prop;
|
||||
litdata[0] *= prop;
|
||||
litdata[1] *= prop;
|
||||
litdata[2] *= prop;
|
||||
prop = *lum / prop;
|
||||
lit[0] *= prop;
|
||||
lit[1] *= prop;
|
||||
lit[2] *= prop;
|
||||
}
|
||||
|
||||
normal++;
|
||||
litdata+=3;
|
||||
lum++;
|
||||
lit+=3;
|
||||
}
|
||||
//end anti-cheat
|
||||
}
|
||||
|
@ -1613,84 +1656,86 @@ void RMod_LoadLighting (lump_t *l)
|
|||
// else
|
||||
//failed to find
|
||||
}
|
||||
if (mapcomeswith24bitcolouredlighting)
|
||||
loadmodel->engineflags |= MDLF_RGBLIGHTING;
|
||||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
else if (r_loadlits.value == 2 && !lightmodel && (!(loadmodel->engineflags & MDLF_RGBLIGHTING) || (!luxdata && r_deluxemapping.ival)))
|
||||
if (r_loadlits.value == 2 && !lightmodel && (!litdata || (!luxdata && r_deluxemapping.ival)))
|
||||
{
|
||||
qbyte *litdata = NULL;
|
||||
int i;
|
||||
qbyte *normal;
|
||||
writelitfile = !(loadmodel->engineflags & MDLF_RGBLIGHTING);
|
||||
loadmodel->engineflags |= MDLF_RGBLIGHTING;
|
||||
loadmodel->lightdata = Hunk_AllocName ( l->filelen*3+8, loadname);
|
||||
strcpy(loadmodel->lightdata, "QLIT");
|
||||
((int*)loadmodel->lightdata)[1] = LittleLong(1);
|
||||
loadmodel->lightdata += 8;
|
||||
|
||||
litdata = loadmodel->lightdata;
|
||||
normal = mod_base + l->fileofs;
|
||||
for (i = 0; i < l->filelen; i++)
|
||||
{
|
||||
*litdata++ = lmgamma[*normal];
|
||||
*litdata++ = lmgamma[*normal];
|
||||
*litdata++ = lmgamma[*normal];
|
||||
normal++;
|
||||
}
|
||||
|
||||
if (r_deluxemapping.ival)
|
||||
{
|
||||
loadmodel->deluxdata = Hunk_AllocName ( l->filelen*3+8, loadname);
|
||||
strcpy(loadmodel->deluxdata, "QLIT");
|
||||
((int*)loadmodel->deluxdata)[1] = LittleLong(1);
|
||||
loadmodel->deluxdata += 8;
|
||||
litdata = loadmodel->deluxdata;
|
||||
{
|
||||
for (i = 0; i < l->filelen; i++)
|
||||
{
|
||||
*litdata++ = 0.5f*255;
|
||||
*litdata++ = 0.5f*255;
|
||||
*litdata++ = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numlightdata = l->filelen;
|
||||
lightmodel = loadmodel;
|
||||
relitsurface = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (loadmodel->lightdata)
|
||||
{
|
||||
if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && r_lightmap_saturation.value != 1.0f)
|
||||
{
|
||||
// desaturate lightmap according to cvar
|
||||
SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);
|
||||
|
||||
/*if we're relighting, make sure there's the proper lit data to be updated*/
|
||||
if (lightmodel == loadmodel && !litdata)
|
||||
{
|
||||
int i;
|
||||
qbyte *in, *out;
|
||||
|
||||
in = mod_base + l->fileofs;
|
||||
out = loadmodel->lightdata;
|
||||
for (i = 0; i < l->filelen; i++)
|
||||
litdata = Hunk_AllocName(samples*3, "lit data");
|
||||
littmp = false;
|
||||
if (lumdata)
|
||||
{
|
||||
*out++ = lmgamma[*in++];
|
||||
for (i = 0; i < samples; i++)
|
||||
{
|
||||
litdata[i*3+0] = lumdata[i];
|
||||
litdata[i*3+1] = lumdata[i];
|
||||
litdata[i*3+2] = lumdata[i];
|
||||
}
|
||||
lumdata = NULL;
|
||||
}
|
||||
|
||||
if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && r_lightmap_saturation.value != 1.0f)
|
||||
SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value);
|
||||
}
|
||||
//memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
|
||||
/*if we're relighting, make sure there's the proper lux data to be updated*/
|
||||
if (lightmodel == loadmodel && r_deluxemapping.ival && !luxdata)
|
||||
{
|
||||
int i;
|
||||
luxdata = Hunk_AllocName(samples*3, "lux data");
|
||||
for (i = 0; i < samples; i++)
|
||||
{
|
||||
litdata[i*3+0] = 0.5f*255;
|
||||
litdata[i*3+0] = 0.5f*255;
|
||||
litdata[i*3+0] = 255;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (luxdata && luxtmp)
|
||||
{
|
||||
loadmodel->engineflags |= MDLF_RGBLIGHTING;
|
||||
loadmodel->deluxdata = Hunk_AllocName(samples*3, "lit data");
|
||||
memcpy(loadmodel->deluxdata, luxdata, samples*3);
|
||||
}
|
||||
else if (luxdata)
|
||||
{
|
||||
loadmodel->deluxdata = luxdata;
|
||||
}
|
||||
|
||||
if (litdata && littmp)
|
||||
{
|
||||
loadmodel->engineflags |= MDLF_RGBLIGHTING;
|
||||
loadmodel->lightdata = Hunk_AllocName(samples*3, "lit data");
|
||||
/*the memcpy is below*/
|
||||
samples*=3;
|
||||
}
|
||||
else if (litdata)
|
||||
{
|
||||
loadmodel->engineflags |= MDLF_RGBLIGHTING;
|
||||
loadmodel->lightdata = litdata;
|
||||
samples*=3;
|
||||
}
|
||||
else if (lumdata)
|
||||
{
|
||||
loadmodel->engineflags &= ~MDLF_RGBLIGHTING;
|
||||
loadmodel->lightdata = Hunk_AllocName(samples, "lit data");
|
||||
litdata = lumdata;
|
||||
}
|
||||
|
||||
/*apply lightmap gamma to the entire lightmap*/
|
||||
out = loadmodel->lightdata;
|
||||
while(samples-- > 0)
|
||||
{
|
||||
*out++ = lmgamma[*litdata++];
|
||||
}
|
||||
|
||||
if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && r_lightmap_saturation.value != 1.0f)
|
||||
SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3159,6 +3204,7 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
|
||||
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
|
||||
|
||||
Q1BSPX_Setup(loadmodel, mod_base, com_filesize, header->lumps, HEADER_LUMPS);
|
||||
|
||||
// checksum all of the map, except for entities
|
||||
mod->checksum = 0;
|
||||
|
@ -3258,6 +3304,7 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
return false;
|
||||
}
|
||||
|
||||
Q1BSP_LoadBrushes(mod);
|
||||
Q1BSP_SetModelFuncs(mod);
|
||||
mod->funcs.LightPointValues = GLQ1BSP_LightPointValues;
|
||||
mod->funcs.StainNode = Q1BSP_StainNode;
|
||||
|
@ -3856,7 +3903,7 @@ static void LoadDoomSpriteFrame(char *imagename, mspriteframedesc_t *pdesc, int
|
|||
}
|
||||
|
||||
palette = COM_LoadTempFile("wad/playpal");
|
||||
header = (doomimage_t *)COM_LoadTempFile2(imagename);
|
||||
header = (doomimage_t *)COM_LoadTempMoreFile(imagename);
|
||||
data = (qbyte *)header;
|
||||
pframe->up = +header->ypos;
|
||||
pframe->down = -header->height + header->ypos;
|
||||
|
|
|
@ -419,6 +419,18 @@ typedef struct msurface_s
|
|||
#endif
|
||||
} msurface_t;
|
||||
|
||||
typedef struct mbrush_s
|
||||
{
|
||||
struct mbrush_s *next;
|
||||
unsigned int contents;
|
||||
int numplanes;
|
||||
struct mbrushplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
} planes[1];
|
||||
} mbrush_t;
|
||||
|
||||
typedef struct mnode_s
|
||||
{
|
||||
// common with leaf
|
||||
|
@ -429,6 +441,7 @@ typedef struct mnode_s
|
|||
float minmaxs[6]; // for bounding box culling
|
||||
|
||||
struct mnode_s *parent;
|
||||
struct mbrush_s *brushes;
|
||||
|
||||
// node specific
|
||||
mplane_t *plane;
|
||||
|
@ -453,6 +466,7 @@ typedef struct mleaf_s
|
|||
float minmaxs[6]; // for bounding box culling
|
||||
|
||||
struct mnode_s *parent;
|
||||
struct mbrush_s *brushes;
|
||||
|
||||
// leaf specific
|
||||
qbyte *compressed_vis;
|
||||
|
@ -506,7 +520,10 @@ typedef struct hull_s
|
|||
|
||||
void Q1BSP_CheckHullNodes(hull_t *hull);
|
||||
void Q1BSP_SetModelFuncs(struct model_s *mod);
|
||||
void Q1BSP_LoadBrushes(struct model_s *model);
|
||||
void Q1BSP_Init(void);
|
||||
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize);
|
||||
void Q1BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps);
|
||||
|
||||
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out);
|
||||
|
||||
|
@ -953,6 +970,7 @@ typedef struct model_s
|
|||
#define MDLF_BOLT 0x080 // doesn't produce shadows
|
||||
#define MDLF_NOTREPLACEMENTS 0x100 // can be considered a cheat, disable texture replacements
|
||||
#define MDLF_EZQUAKEFBCHEAT 0x200 // this is a blatent cheat, one that can disadvantage us fairly significantly if we don't support it.
|
||||
#define MDLF_HASBRUSHES 0x400 // q1bsp has brush info for more precise traceboxes
|
||||
|
||||
//============================================================================
|
||||
/*
|
||||
|
|
|
@ -224,25 +224,76 @@ void GL_SetupSceneProcessingTextures (void)
|
|||
|
||||
void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const model_t *mod)
|
||||
{
|
||||
m[0] = e->axis[0][0];
|
||||
m[1] = e->axis[0][1];
|
||||
m[2] = e->axis[0][2];
|
||||
m[3] = 0;
|
||||
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0)
|
||||
{
|
||||
entity_t *view = &cl.viewent[r_refdef.currentplayernum];
|
||||
float em[16];
|
||||
float vm[16];
|
||||
|
||||
m[4] = e->axis[1][0];
|
||||
m[5] = e->axis[1][1];
|
||||
m[6] = e->axis[1][2];
|
||||
m[7] = 0;
|
||||
vm[0] = view->axis[0][0];
|
||||
vm[1] = view->axis[0][1];
|
||||
vm[2] = view->axis[0][2];
|
||||
vm[3] = 0;
|
||||
|
||||
m[8] = e->axis[2][0];
|
||||
m[9] = e->axis[2][1];
|
||||
m[10] = e->axis[2][2];
|
||||
m[11] = 0;
|
||||
vm[4] = view->axis[1][0];
|
||||
vm[5] = view->axis[1][1];
|
||||
vm[6] = view->axis[1][2];
|
||||
vm[7] = 0;
|
||||
|
||||
m[12] = e->origin[0];
|
||||
m[13] = e->origin[1];
|
||||
m[14] = e->origin[2];
|
||||
m[15] = 1;
|
||||
vm[8] = view->axis[2][0];
|
||||
vm[9] = view->axis[2][1];
|
||||
vm[10] = view->axis[2][2];
|
||||
vm[11] = 0;
|
||||
|
||||
vm[12] = view->origin[0];
|
||||
vm[13] = view->origin[1];
|
||||
vm[14] = view->origin[2];
|
||||
vm[15] = 1;
|
||||
|
||||
em[0] = e->axis[0][0];
|
||||
em[1] = e->axis[0][1];
|
||||
em[2] = e->axis[0][2];
|
||||
em[3] = 0;
|
||||
|
||||
em[4] = e->axis[1][0];
|
||||
em[5] = e->axis[1][1];
|
||||
em[6] = e->axis[1][2];
|
||||
em[7] = 0;
|
||||
|
||||
em[8] = e->axis[2][0];
|
||||
em[9] = e->axis[2][1];
|
||||
em[10] = e->axis[2][2];
|
||||
em[11] = 0;
|
||||
|
||||
em[12] = e->origin[0];
|
||||
em[13] = e->origin[1];
|
||||
em[14] = e->origin[2];
|
||||
em[15] = 1;
|
||||
|
||||
Matrix4_Multiply(vm, em, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
m[0] = e->axis[0][0];
|
||||
m[1] = e->axis[0][1];
|
||||
m[2] = e->axis[0][2];
|
||||
m[3] = 0;
|
||||
|
||||
m[4] = e->axis[1][0];
|
||||
m[5] = e->axis[1][1];
|
||||
m[6] = e->axis[1][2];
|
||||
m[7] = 0;
|
||||
|
||||
m[8] = e->axis[2][0];
|
||||
m[9] = e->axis[2][1];
|
||||
m[10] = e->axis[2][2];
|
||||
m[11] = 0;
|
||||
|
||||
m[12] = e->origin[0];
|
||||
m[13] = e->origin[1];
|
||||
m[14] = e->origin[2];
|
||||
m[15] = 1;
|
||||
}
|
||||
|
||||
if (e->scale != 1 && e->scale != 0) //hexen 2 stuff
|
||||
{
|
||||
|
@ -298,21 +349,7 @@ void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const mod
|
|||
VectorScale((m+8), mod->clampscale, (m+8));
|
||||
}
|
||||
|
||||
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0)
|
||||
{
|
||||
/*FIXME: no bob*/
|
||||
float simpleview[16];
|
||||
vec3_t ang;
|
||||
ang[0] = 0;
|
||||
ang[1] = 0;
|
||||
ang[2] = gl_screenangle.value;
|
||||
Matrix4x4_CM_ModelViewMatrix(simpleview, ang, vec3_origin);
|
||||
Matrix4_Multiply(simpleview, m, modelview);
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix4_Multiply(r_refdef.m_view, m, modelview);
|
||||
}
|
||||
Matrix4_Multiply(r_refdef.m_view, m, modelview);
|
||||
}
|
||||
|
||||
//==================================================================================
|
||||
|
|
|
@ -2908,7 +2908,7 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
|
|||
|
||||
if (dl->flags & LFLAG_CREPUSCULAR)
|
||||
Sh_DrawCrepuscularLight(dl, colour, mbatches);
|
||||
else if (((!dl->die)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
|
||||
else if (((i >= RTL_FIRST)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
|
||||
{
|
||||
Sh_DrawShadowlessLight(dl, colour, vis);
|
||||
}
|
||||
|
|
|
@ -220,112 +220,7 @@ void GLVID_ShiftPalette (unsigned char *palette)
|
|||
}
|
||||
}
|
||||
|
||||
void Sys_SendKeyEvents(void)
|
||||
{
|
||||
}
|
||||
|
||||
void GLVID_SetCaption(char *caption)
|
||||
{
|
||||
}
|
||||
|
||||
extern qboolean mouse_active;
|
||||
|
||||
cvar_t m_filter = CVARF("m_filter", "1", CVAR_ARCHIVE);
|
||||
|
||||
extern cvar_t _windowed_mouse;
|
||||
|
||||
float mouse_x, mouse_y;
|
||||
float old_mouse_x, old_mouse_y;
|
||||
|
||||
void IN_Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void IN_ReInit()
|
||||
{
|
||||
Cvar_Register (&m_filter, "input controls");
|
||||
}
|
||||
|
||||
void IN_Init(void)
|
||||
{
|
||||
IN_ReInit();
|
||||
}
|
||||
|
||||
void IN_Commands(void)
|
||||
{
|
||||
}
|
||||
|
||||
void IN_Move (float *movements, int pnum)
|
||||
{
|
||||
extern int mousecursor_x, mousecursor_y;
|
||||
extern int mousemove_x, mousemove_y;
|
||||
|
||||
if (pnum != 0)
|
||||
return; //we're lazy today.
|
||||
|
||||
if (m_filter.value)
|
||||
{
|
||||
mouse_x = (mouse_x + old_mouse_x) * 0.5;
|
||||
mouse_y = (mouse_y + old_mouse_y) * 0.5;
|
||||
}
|
||||
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
|
||||
if(in_xflip.value) mouse_x *= -1;
|
||||
|
||||
if (Key_MouseShouldBeFree())
|
||||
{
|
||||
mousemove_x += mouse_x;
|
||||
mousemove_y += mouse_y;
|
||||
|
||||
if (mousecursor_y<0)
|
||||
mousecursor_y=0;
|
||||
if (mousecursor_x<0)
|
||||
mousecursor_x=0;
|
||||
|
||||
if (mousecursor_x >= vid.width)
|
||||
mousecursor_x = vid.width - 1;
|
||||
|
||||
if (mousecursor_y >= vid.height)
|
||||
mousecursor_y = vid.height - 1;
|
||||
|
||||
mouse_x = mouse_y = 0;
|
||||
#ifdef VM_UI
|
||||
UI_MousePosition(mousecursor_x, mousecursor_y);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
mouse_x *= sensitivity.value;
|
||||
mouse_y *= sensitivity.value;
|
||||
|
||||
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
|
||||
{
|
||||
if (movements)
|
||||
movements[1] += m_side.value * mouse_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
cl.viewanglechange[pnum][YAW] -= m_yaw.value * mouse_x;
|
||||
}
|
||||
if (in_mlook.state[pnum] & 1)
|
||||
V_StopPitchDrift (pnum);
|
||||
|
||||
if ( (in_mlook.state[pnum] & 1) && !(in_strafe.state[pnum] & 1))
|
||||
{
|
||||
cl.viewanglechange[pnum][PITCH] += m_pitch.value * mouse_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (movements)
|
||||
{
|
||||
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
|
||||
movements[2] -= m_forward.value * mouse_y;
|
||||
else
|
||||
movements[0] -= m_forward.value * mouse_y;
|
||||
}
|
||||
}
|
||||
mouse_x = mouse_y = 0.0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1857,7 +1857,7 @@ static void Doom_LoadVerticies(char *name)
|
|||
std = (void *)COM_LoadTempFile (va("%s.vertexes", name));
|
||||
stdc = com_filesize/sizeof(*std);
|
||||
|
||||
gl2 = (void *)COM_LoadTempFile2 (va("%s.gl_vert", name));
|
||||
gl2 = (void *)COM_LoadTempMoreFile (va("%s.gl_vert", name));
|
||||
if (!gl2)
|
||||
{
|
||||
glc = 0;
|
||||
|
|
|
@ -2958,7 +2958,7 @@ static void QCBUILTIN PF_LocalSound(progfuncs_t *prinst, struct globalvars_s *pr
|
|||
if (!isDedicated)
|
||||
{
|
||||
if ((sfx = S_PrecacheSound(s)))
|
||||
S_StartSound(cl.playernum[0], chan, sfx, cl.simorg[0], vol, 0.0, 0);
|
||||
S_StartSound(cl.playernum[0], chan, sfx, cl.simorg[0], vol, 0.0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@ -9221,7 +9221,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
//DP_QC_WHICHPACK
|
||||
{"whichpack", PF_whichpack, 0, 0, 0, 503, "string(string filename)"},//
|
||||
//DP_CSQC_QUERYRENDERENTITY
|
||||
{"getentity", PF_Fixme, 0, 0, 0, 504, "__variant(float entnum, fload fieldnum)"},
|
||||
{"getentity", PF_Fixme, 0, 0, 0, 504, "__variant(float entnum, fload fieldnum)"},
|
||||
|
||||
//DP_QC_URI_ESCAPE
|
||||
{"uri_escape", PF_uri_escape, 0, 0, 0, 510, "string(string in)"},//
|
||||
|
|
|
@ -287,7 +287,7 @@ typedef struct
|
|||
double senttime; //time we sent this frame to the client, for ping calcs
|
||||
int sequence; //the outgoing sequence - without mask, meaning we know if its current or stale
|
||||
float ping_time; //how long it took for the client to ack it, may be negativ
|
||||
int move_msecs; //
|
||||
float move_msecs; //
|
||||
int packetsizein; //amount of data received for this frame
|
||||
int packetsizeout; //amount of data that was sent in the frame
|
||||
vec3_t playerpositions[MAX_CLIENTS]; //where each player was in this frame, for antilag
|
||||
|
@ -552,6 +552,10 @@ typedef struct client_s
|
|||
struct client_s *controller; /*first in splitscreen chain, NULL=nosplitscreen*/
|
||||
struct client_s *controlled; /*next in splitscreen chain*/
|
||||
|
||||
/*these are the current rates*/
|
||||
float ratetime;
|
||||
float inrate;
|
||||
float outrate;
|
||||
|
||||
int rate;
|
||||
int drate;
|
||||
|
|
|
@ -2871,7 +2871,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
|
|||
{
|
||||
//pvs and clent can be null, but only if the other is also null
|
||||
int e, i;
|
||||
edict_t *ent;
|
||||
edict_t *ent, *trackent;
|
||||
entity_state_t *state;
|
||||
#define DEPTHOPTIMISE
|
||||
#ifdef DEPTHOPTIMISE
|
||||
|
@ -2882,6 +2882,11 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
|
|||
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
||||
int pvsflags;
|
||||
|
||||
if (client->spectator)
|
||||
trackent = EDICT_NUM(svprogfuncs, client->spec_track);
|
||||
else
|
||||
trackent = PROG_TO_EDICT(svprogfuncs, clent->xv->view2);
|
||||
|
||||
if (client->viewent
|
||||
#ifdef NQPROT
|
||||
&& ISQWCLIENT(client)
|
||||
|
@ -2967,7 +2972,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
|
|||
continue;
|
||||
pvsflags = PVSF_IGNOREPVS;
|
||||
}
|
||||
else if (ent == clent)
|
||||
else if (ent == clent || ent == trackent)
|
||||
{
|
||||
pvsflags = PVSF_IGNOREPVS;
|
||||
}
|
||||
|
@ -2978,7 +2983,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
|
|||
continue;
|
||||
|
||||
pvsflags = ent->xv->pvsflags;
|
||||
if (pvs && ent != clent) //self doesn't get a pvs test, to cover teleporters
|
||||
if (pvs) //self doesn't get a pvs test, to cover teleporters
|
||||
{
|
||||
if ((int)ent->v->effects & EF_NODEPTHTEST)
|
||||
{
|
||||
|
|
|
@ -394,8 +394,21 @@ void SV_CalcPHS (void)
|
|||
rowwords = (num+31)>>5;
|
||||
rowbytes = rowwords*4;
|
||||
|
||||
if (developer.value)
|
||||
Con_TPrintf (STL_BUILDINGPHS);
|
||||
if (!sv_calcphs.ival || (sv_calcphs.ival == 2 && (rowbytes*num >= 0x100000 || (!deathmatch.ival && !coop.ival))))
|
||||
{
|
||||
sv.pvs = Hunk_AllocName (rowbytes*num, "pvs vis");
|
||||
scan = sv.pvs;
|
||||
for (i=0 ; i<num ; i++, scan+=rowbytes)
|
||||
{
|
||||
lf = sv.world.worldmodel->funcs.LeafPVS(sv.world.worldmodel, i, scan, rowbytes);
|
||||
if (lf != scan)
|
||||
memcpy (scan, lf, rowbytes);
|
||||
}
|
||||
|
||||
Con_DPrintf("Skipping PHS\n");
|
||||
sv.phs = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
sv.pvs = Hunk_AllocName (rowbytes*num, "phs vis");
|
||||
scan = sv.pvs;
|
||||
|
@ -415,13 +428,8 @@ void SV_CalcPHS (void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sv_calcphs.ival || (sv_calcphs.ival == 2 && (rowbytes*num >= 0x100000 || (!deathmatch.ival && !coop.ival))))
|
||||
{
|
||||
Con_DPrintf("Skipping PHS\n");
|
||||
sv.phs = NULL;
|
||||
return;
|
||||
}
|
||||
if (developer.value)
|
||||
Con_TPrintf (STL_BUILDINGPHS);
|
||||
|
||||
/*this routine takes an exponential amount of time, so cache it if its too big*/
|
||||
if (rowbytes*num >= 0x100000)
|
||||
|
@ -753,14 +761,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
Cvar_ApplyLatches(CVAR_LATCH);
|
||||
|
||||
//work out the gamespeed
|
||||
sv.gamespeed = sv_gamespeed.value;
|
||||
Info_SetValueForStarKey(svs.info, "*gamespeed", va("%i", (int)(sv.gamespeed*100)), MAX_SERVERINFO_STRING);
|
||||
sv.gamespeed = atof(Info_ValueForKey(svs.info, "*gamespeed"))/100;
|
||||
if (sv.gamespeed < 0.1 || sv.gamespeed == 1)
|
||||
{
|
||||
sv.gamespeed = 1;
|
||||
Info_SetValueForStarKey(svs.info, "*gamespeed", "", MAX_SERVERINFO_STRING);
|
||||
}
|
||||
//reset the server time.
|
||||
sv.time = 0.01; //some progs don't like time starting at 0.
|
||||
//cos of spawn funcs like self.nextthink = time...
|
||||
|
|
|
@ -3808,6 +3808,27 @@ float SV_Frame (void)
|
|||
oldpaused = sv.paused;
|
||||
}
|
||||
|
||||
|
||||
//work out the gamespeed
|
||||
if (sv.gamespeed != sv_gamespeed.value)
|
||||
{
|
||||
char *newspeed;
|
||||
sv.gamespeed = sv_gamespeed.value;
|
||||
if (sv.gamespeed < 0.1 || sv.gamespeed == 1)
|
||||
sv_gamespeed.value = sv.gamespeed = 1;
|
||||
|
||||
if (sv.gamespeed == 1)
|
||||
newspeed = "";
|
||||
else
|
||||
newspeed = va("%g", sv.gamespeed*100);
|
||||
Info_SetValueForStarKey(svs.info, "*gamespeed", newspeed, MAX_SERVERINFO_STRING);
|
||||
SV_SendServerInfoChange("*gamespeed", newspeed);
|
||||
|
||||
//correct sv.starttime
|
||||
sv.starttime = Sys_DoubleTime() - (sv.time/sv.gamespeed);
|
||||
}
|
||||
|
||||
|
||||
// decide the simulation time
|
||||
{
|
||||
oldtime = sv.time;
|
||||
|
@ -3824,7 +3845,7 @@ float SV_Frame (void)
|
|||
|
||||
if (sv.paused && sv.time > 1.5)
|
||||
{
|
||||
sv.starttime += sv.time - oldtime; //move the offset
|
||||
sv.starttime += (sv.time - oldtime)/sv.gamespeed; //move the offset
|
||||
sv.time = oldtime; //and keep time as it was.
|
||||
}
|
||||
}
|
||||
|
@ -4653,7 +4674,7 @@ void SV_ExtractFromUserinfo (client_t *cl)
|
|||
if (strlen(val))
|
||||
cl->rate = atoi(val);
|
||||
else
|
||||
cl->rate = 2500;
|
||||
cl->rate = ISNQCLIENT(cl)?10000:2500;
|
||||
|
||||
val = Info_ValueForKey (cl->userinfo, "drate");
|
||||
if (strlen(val))
|
||||
|
|
|
@ -2337,6 +2337,15 @@ void SV_SendClientMessages (void)
|
|||
}
|
||||
c->waschoked = false;
|
||||
|
||||
if (sv.time > c->ratetime + 1)
|
||||
{
|
||||
c->inrate = c->netchan.bytesin / (sv.time - c->ratetime);
|
||||
c->outrate = c->netchan.bytesout / (sv.time - c->ratetime);
|
||||
c->netchan.bytesin = 0;
|
||||
c->netchan.bytesout = 0;
|
||||
c->ratetime = sv.time;
|
||||
}
|
||||
|
||||
if (c->state == cs_spawned)
|
||||
SV_SendClientDatagram (c);
|
||||
else
|
||||
|
|
|
@ -241,7 +241,7 @@ Loads the game dll
|
|||
*/
|
||||
void *Sys_GetGameAPI (void *parms)
|
||||
{
|
||||
void *(*GetGameAPI) (void *);
|
||||
void *(VARGS *GetGameAPI) (void *);
|
||||
char name[MAX_OSPATH];
|
||||
char *path;
|
||||
char cwd[MAX_OSPATH];
|
||||
|
|
|
@ -3486,7 +3486,11 @@ void SV_Rate_f (void)
|
|||
{
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
SV_ClientPrintf (host_client, PRINT_HIGH, "Effective rate %i\n", SV_RateForClient(host_client));
|
||||
int rate = SV_RateForClient(host_client);
|
||||
if (!rate)
|
||||
SV_ClientPrintf (host_client, PRINT_HIGH, "Effective rate is unlimited\n", rate);
|
||||
else
|
||||
SV_ClientPrintf (host_client, PRINT_HIGH, "Effective rate %i\n", rate);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4280,7 +4284,7 @@ void Cmd_FPSList_f(void)
|
|||
int frames;
|
||||
int inbytes;
|
||||
int outbytes;
|
||||
int msecs;
|
||||
float msecs;
|
||||
|
||||
|
||||
for (c = 0; c < sv.allocated_client_slots; c++)
|
||||
|
@ -4328,9 +4332,9 @@ void Cmd_FPSList_f(void)
|
|||
}
|
||||
|
||||
if (frames)
|
||||
SV_ClientPrintf(host_client, PRINT_HIGH, "%s: %ffps (min%.2f max %.2f), in: %.2fbps, out: %.2fbps\n", cl->name, ftime/frames, minf, maxf, (1000.0f*inbytes)/msecs, (1000.0f*outbytes)/msecs);
|
||||
SV_ClientPrintf(host_client, PRINT_HIGH, "%s: %gfps (min%g max %g), in: %ibps, out: %ibps\n", cl->name, ftime/frames, minf, maxf, (int)cl->inrate, (int)cl->outrate);
|
||||
else
|
||||
SV_ClientPrintf(host_client, PRINT_HIGH, "%s: no information available\n", cl->name);
|
||||
SV_ClientPrintf(host_client, PRINT_HIGH, "%s: unknown framerate, in: %ibps, out: %ibps\n", cl->name, (int)cl->inrate, (int)cl->outrate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6674,6 +6678,7 @@ void SVNQ_ReadClientMove (usercmd_t *move)
|
|||
if (cltime < sv.time - 2) //if you do lag more than this, you won't get your free time.
|
||||
cltime = sv.time - 2;
|
||||
timesincelast = cltime - move->fservertime;
|
||||
|
||||
move->fservertime = cltime;
|
||||
move->servertime = move->fservertime;
|
||||
|
||||
|
@ -6693,10 +6698,8 @@ void SVNQ_ReadClientMove (usercmd_t *move)
|
|||
move->sidemove = MSG_ReadShort ();
|
||||
move->upmove = MSG_ReadShort ();
|
||||
|
||||
move->msec=timesincelast*1000;//MSG_ReadFloat;
|
||||
|
||||
|
||||
frame->move_msecs = move->msec;
|
||||
move->msec=timesincelast*1000;
|
||||
frame->move_msecs = timesincelast*1000;
|
||||
|
||||
// read buttons
|
||||
if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7)
|
||||
|
|
|
@ -1817,6 +1817,7 @@ qboolean Mod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
return false;
|
||||
}
|
||||
|
||||
Q1BSP_LoadBrushes(mod);
|
||||
Q1BSP_SetModelFuncs(mod);
|
||||
|
||||
if (mod->surfaces && mod->lightdata)
|
||||
|
|
|
@ -343,6 +343,7 @@ static qboolean VARGS PFQ2_inPVS (vec3_t p1, vec3_t p2)
|
|||
int area1, area2;
|
||||
qbyte *mask;
|
||||
|
||||
//FIXME: requires q2/q3 bsp
|
||||
leafnum = CM_PointLeafnum (sv.world.worldmodel, p1);
|
||||
cluster = CM_LeafCluster (sv.world.worldmodel, leafnum);
|
||||
area1 = CM_LeafArea (sv.world.worldmodel, leafnum);
|
||||
|
@ -373,6 +374,7 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2)
|
|||
int area1, area2;
|
||||
qbyte *mask;
|
||||
|
||||
//FIXME: requires q2/q3 bsp
|
||||
leafnum = CM_PointLeafnum (sv.world.worldmodel, p1);
|
||||
cluster = CM_LeafCluster (sv.world.worldmodel, leafnum);
|
||||
area1 = CM_LeafArea (sv.world.worldmodel, leafnum);
|
||||
|
@ -391,6 +393,7 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2)
|
|||
|
||||
qboolean VARGS PFQ2_AreasConnected(int area1, int area2)
|
||||
{
|
||||
//FIXME: requires q2/q3 bsp
|
||||
return CM_AreasConnected(sv.world.worldmodel, area1, area2);
|
||||
}
|
||||
|
||||
|
@ -536,19 +539,26 @@ static q2trace_t VARGS SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_
|
|||
{
|
||||
q2trace_t ret;
|
||||
trace_t tr;
|
||||
static vec3_t nullvec;
|
||||
if (!mins)
|
||||
mins = nullvec;
|
||||
mins = vec3_origin;
|
||||
if (!maxs)
|
||||
maxs = nullvec;
|
||||
maxs = vec3_origin;
|
||||
tr = WorldQ2_Move(&sv.world, start, mins, maxs, end, contentmask, passedict);
|
||||
memcpy(&ret, &tr, sizeof(q2trace_t));
|
||||
ret.allsolid = tr.allsolid;
|
||||
ret.startsolid = tr.startsolid;
|
||||
ret.contents = tr.contents;
|
||||
ret.surface = tr.surface;
|
||||
ret.fraction = tr.fraction;
|
||||
VectorCopy(tr.endpos, ret.endpos);
|
||||
VectorCopy(tr.plane.normal, ret.plane.normal);
|
||||
ret.plane.dist = tr.plane.dist;
|
||||
// memcpy(&ret, &tr, sizeof(q2trace_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int VARGS SVQ2_PointContents (vec3_t p)
|
||||
{
|
||||
q2trace_t tr = SVQ2_Trace(p, NULL, NULL, p, NULL, ~0);
|
||||
q2trace_t tr = SVQ2_Trace(p, vec3_origin, vec3_origin, p, NULL, ~0);
|
||||
return tr.contents;
|
||||
// return CM_PointContents(p, 0);
|
||||
}
|
||||
|
|
|
@ -1869,7 +1869,8 @@ trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t
|
|||
memset ( &clip, 0, sizeof ( moveclip_t ) );
|
||||
|
||||
// clip to world
|
||||
clip.trace = CM_BoxTrace(w->worldmodel, start, end, mins, maxs, hitcontentsmask);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end );
|
||||
w->worldmodel->funcs.NativeTrace(w->worldmodel, 0, 0, NULL, start, end, mins, maxs, hitcontentsmask, &clip.trace);
|
||||
// clip.trace = CM_BoxTrace(w->worldmodel, start, end, mins, maxs, hitcontentsmask);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end );
|
||||
clip.trace.ent = ge->edicts;
|
||||
|
||||
if (clip.trace.fraction == 0)
|
||||
|
|
Loading…
Reference in a new issue