diff --git a/Makefile b/Makefile index 1c05b7ec..f74df245 100644 --- a/Makefile +++ b/Makefile @@ -332,7 +332,17 @@ bin_path=$(shell which $(1) 2> /dev/null) # set PKG_CONFIG_PATH or PKG_CONFIG to influence this, e.g. # PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig or # PKG_CONFIG=arm-linux-gnueabihf-pkg-config -PKG_CONFIG ?= pkg-config +ifeq ($(CROSS_COMPILING),0) + PKG_CONFIG ?= pkg-config +else +ifneq ($(PKG_CONFIG_PATH),) + PKG_CONFIG ?= pkg-config +else + # Don't use host pkg-config when cross-compiling. + # (unknown-pkg-config is meant to be a non-existant command.) + PKG_CONFIG ?= unknown-pkg-config +endif +endif ifneq ($(call bin_path, $(PKG_CONFIG)),) CURL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl) @@ -1457,6 +1467,7 @@ targets: makedirs @echo " COMPILE_PLATFORM: $(COMPILE_PLATFORM)" @echo " COMPILE_ARCH: $(COMPILE_ARCH)" @echo " HAVE_VM_COMPILED: $(HAVE_VM_COMPILED)" + @echo " PKG_CONFIG: $(PKG_CONFIG)" @echo " CC: $(CC)" ifeq ($(PLATFORM),mingw32) @echo " WINDRES: $(WINDRES)" diff --git a/code/cgame/cg_ents.c b/code/cgame/cg_ents.c index 7629f0b8..ec8b02ff 100644 --- a/code/cgame/cg_ents.c +++ b/code/cgame/cg_ents.c @@ -664,6 +664,44 @@ static void CG_Portal( centity_t *cent ) { } +/* +================ +CG_CreateRotationMatrix +================ +*/ +void CG_CreateRotationMatrix(vec3_t angles, vec3_t matrix[3]) { + AngleVectors(angles, matrix[0], matrix[1], matrix[2]); + VectorInverse(matrix[1]); +} + +/* +================ +CG_TransposeMatrix +================ +*/ +void CG_TransposeMatrix(vec3_t matrix[3], vec3_t transpose[3]) { + int i, j; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + transpose[i][j] = matrix[j][i]; + } + } +} + +/* +================ +CG_RotatePoint +================ +*/ +void CG_RotatePoint(vec3_t point, vec3_t matrix[3]) { + vec3_t tvec; + + VectorCopy(point, tvec); + point[0] = DotProduct(matrix[0], tvec); + point[1] = DotProduct(matrix[1], tvec); + point[2] = DotProduct(matrix[2], tvec); +} + /* ========================= CG_AdjustPositionForMover @@ -675,6 +713,8 @@ void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int centity_t *cent; vec3_t oldOrigin, origin, deltaOrigin; vec3_t oldAngles, angles, deltaAngles; + vec3_t matrix[3], transpose[3]; + vec3_t org, org2, move2; if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) { VectorCopy( in, out ); @@ -698,9 +738,17 @@ void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int VectorSubtract( origin, oldOrigin, deltaOrigin ); VectorSubtract( angles, oldAngles, deltaAngles ); + // origin change when on a rotating object + CG_CreateRotationMatrix( deltaAngles, transpose ); + CG_TransposeMatrix( transpose, matrix ); + VectorSubtract( in, oldOrigin, org ); + VectorCopy( org, org2 ); + CG_RotatePoint( org2, matrix ); + VectorSubtract( org2, org, move2 ); + VectorAdd( deltaOrigin, move2, deltaOrigin ); + VectorAdd( in, deltaOrigin, out ); VectorAdd( angles_in, deltaAngles, angles_out ); - // FIXME: origin change when on a rotating object } diff --git a/code/cgame/cg_newdraw.c b/code/cgame/cg_newdraw.c index b21b1ad4..ecb230f8 100644 --- a/code/cgame/cg_newdraw.c +++ b/code/cgame/cg_newdraw.c @@ -150,7 +150,7 @@ void CG_SelectNextPlayer( void ) { void CG_SelectPrevPlayer( void ) { CG_CheckOrderPending(); - if (cg_currentSelectedPlayer.integer > 0 && cg_currentSelectedPlayer.integer < numSortedTeamPlayers) { + if (cg_currentSelectedPlayer.integer > 0 && cg_currentSelectedPlayer.integer <= numSortedTeamPlayers) { cg_currentSelectedPlayer.integer--; } else { cg_currentSelectedPlayer.integer = numSortedTeamPlayers; diff --git a/code/client/cl_keys.c b/code/client/cl_keys.c index 41002f20..fc3992bf 100644 --- a/code/client/cl_keys.c +++ b/code/client/cl_keys.c @@ -825,6 +825,7 @@ to be configured even if they don't have defined names. */ int Key_StringToKeynum( char *str ) { keyname_t *kn; + int n; if ( !str || !str[0] ) { return -1; @@ -834,12 +835,9 @@ int Key_StringToKeynum( char *str ) { } // check for hex code - if ( strlen( str ) == 4 ) { - int n = Com_HexStrToInt( str ); - - if ( n >= 0 ) { - return n; - } + n = Com_HexStrToInt( str ); + if ( n >= 0 && n < MAX_KEYS ) { + return n; } // scan for a text match diff --git a/code/client/snd_dma.c b/code/client/snd_dma.c index af6b57bd..afd28a04 100644 --- a/code/client/snd_dma.c +++ b/code/client/snd_dma.c @@ -98,7 +98,7 @@ void S_Base_SoundInfo(void) { if (!s_soundStarted) { Com_Printf ("sound system not started\n"); } else { - Com_Printf("%5d stereo\n", dma.channels - 1); + Com_Printf("%5d channels\n", dma.channels); Com_Printf("%5d samples\n", dma.samples); Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int"); Com_Printf("%5d submission_chunk\n", dma.submission_chunk); @@ -1256,9 +1256,6 @@ void S_GetSoundtime(void) int samplepos; static int buffers; static int oldsamplepos; - int fullsamples; - - fullsamples = dma.samples / dma.channels; if( CL_VideoRecording( ) ) { @@ -1282,13 +1279,13 @@ void S_GetSoundtime(void) if (s_paintedtime > 0x40000000) { // time to chop things off to avoid 32 bit limits buffers = 0; - s_paintedtime = fullsamples; + s_paintedtime = dma.fullsamples; S_Base_StopAllSounds (); } } oldsamplepos = samplepos; - s_soundtime = buffers*fullsamples + samplepos/dma.channels; + s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels; #if 0 // check to make sure that we haven't overshot @@ -1309,7 +1306,6 @@ void S_GetSoundtime(void) void S_Update_(void) { unsigned endtime; - int samps; static float lastTime = 0.0f; float ma, op; float thisTime, sane; @@ -1353,9 +1349,8 @@ void S_Update_(void) { & ~(dma.submission_chunk-1); // never mix more than the complete buffer - samps = dma.samples >> (dma.channels-1); - if (endtime - s_soundtime > samps) - endtime = s_soundtime + samps; + if (endtime - s_soundtime > dma.fullsamples) + endtime = s_soundtime + dma.fullsamples; diff --git a/code/client/snd_local.h b/code/client/snd_local.h index 3b86d974..65392e36 100644 --- a/code/client/snd_local.h +++ b/code/client/snd_local.h @@ -65,6 +65,7 @@ typedef struct sfx_s { typedef struct { int channels; int samples; // mono samples in buffer + int fullsamples; // samples with all channels in buffer (samples divided by channels) int submission_chunk; // don't mix less than this # int samplebits; int isfloat; diff --git a/code/client/snd_mix.c b/code/client/snd_mix.c index af0ba44a..8923b7cb 100644 --- a/code/client/snd_mix.c +++ b/code/client/snd_mix.c @@ -119,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime) while (ls_paintedtime < endtime) { // handle recirculating buffer issues - lpos = ls_paintedtime & ((dma.samples>>1)-1); + lpos = ls_paintedtime % dma.fullsamples; - snd_out = (short *) pbuf + (lpos<<1); + snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels - snd_linear_count = (dma.samples>>1) - lpos; + snd_linear_count = dma.fullsamples - lpos; if (ls_paintedtime + snd_linear_count > endtime) snd_linear_count = endtime - ls_paintedtime; - snd_linear_count <<= 1; + snd_linear_count <<= 1; // snd_linear_count *= dma.channels // write a linear blast of samples S_WriteLinearBlastStereo16 (); snd_p += snd_linear_count; - ls_paintedtime += (snd_linear_count>>1); + ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels if( CL_VideoRecording( ) ) - CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); + CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8) } } @@ -150,18 +150,16 @@ void S_TransferPaintBuffer(int endtime) { int out_idx; int count; - int out_mask; int *p; int step; int val; + int i; unsigned long *pbuf; pbuf = (unsigned long *)dma.buffer; if ( s_testsound->integer ) { - int i; - // write a fixed sine wave count = (endtime - s_paintedtime); for (i=0 ; i> 8; - p+= step; + if ((i % dma.channels) >= 2) + { + val = 0; + } + else + { + val = *p >> 8; + p+= step; + } if (val > 0x7fff) val = 0x7fff; else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */ val = -32767; out[out_idx] = ((float) val) / 32767.0f; - out_idx = (out_idx + 1) & out_mask; + out_idx = (out_idx + 1) % dma.samples; } } else if (dma.samplebits == 16) { short *out = (short *) pbuf; - while (count--) + for (i=0 ; i> 8; - p+= step; + if ((i % dma.channels) >= 2) + { + val = 0; + } + else + { + val = *p >> 8; + p+= step; + } if (val > 0x7fff) val = 0x7fff; else if (val < -32768) val = -32768; out[out_idx] = val; - out_idx = (out_idx + 1) & out_mask; + out_idx = (out_idx + 1) % dma.samples; } } else if (dma.samplebits == 8) { unsigned char *out = (unsigned char *) pbuf; - while (count--) + for (i=0 ; i> 8; - p+= step; + if ((i % dma.channels) >= 2) + { + val = 0; + } + else + { + val = *p >> 8; + p+= step; + } if (val > 0x7fff) val = 0x7fff; else if (val < -32768) val = -32768; out[out_idx] = (val>>8) + 128; - out_idx = (out_idx + 1) & out_mask; + out_idx = (out_idx + 1) % dma.samples; } } } diff --git a/code/game/ai_dmq3.c b/code/game/ai_dmq3.c index dbc68b4a..30df7acb 100644 --- a/code/game/ai_dmq3.c +++ b/code/game/ai_dmq3.c @@ -5346,7 +5346,33 @@ void BotSetEntityNumForGoal(bot_goal_t *goal, char *classname) { if ( !ent->inuse ) { continue; } - if ( !Q_stricmp(ent->classname, classname) ) { + if ( Q_stricmp(ent->classname, classname) != 0 ) { + continue; + } + VectorSubtract(goal->origin, ent->s.origin, dir); + if (VectorLengthSquared(dir) < Square(10)) { + goal->entitynum = i; + return; + } + } +} + +/* +================== +BotSetEntityNumForGoalWithActivator +================== +*/ +void BotSetEntityNumForGoalWithActivator(bot_goal_t *goal, char *classname) { + gentity_t *ent; + int i; + vec3_t dir; + + ent = &g_entities[0]; + for (i = 0; i < level.num_entities; i++, ent++) { + if ( !ent->inuse || !ent->activator ) { + continue; + } + if ( Q_stricmp(ent->activator->classname, classname) != 0 ) { continue; } VectorSubtract(goal->origin, ent->s.origin, dir); @@ -5427,21 +5453,21 @@ void BotSetupDeathmatchAI(void) { else if (gametype == GT_OBELISK) { if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) BotAI_Print(PRT_WARNING, "Overload without Red Obelisk\n"); - BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); + BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk"); if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) BotAI_Print(PRT_WARNING, "Overload without Blue Obelisk\n"); - BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); + BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk"); } else if (gametype == GT_HARVESTER) { if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) BotAI_Print(PRT_WARNING, "Harvester without Red Obelisk\n"); - BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); + BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk"); if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) BotAI_Print(PRT_WARNING, "Harvester without Blue Obelisk\n"); - BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); + BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk"); if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n"); - BotSetEntityNumForGoal(&neutralobelisk, "team_neutralobelisk"); + BotSetEntityNumForGoalWithActivator(&neutralobelisk, "team_neutralobelisk"); } #endif diff --git a/code/q3_ui/ui_servers2.c b/code/q3_ui/ui_servers2.c index e709925e..49c3a04b 100644 --- a/code/q3_ui/ui_servers2.c +++ b/code/q3_ui/ui_servers2.c @@ -88,6 +88,7 @@ MULTIPLAYER MENU (SERVER BROWSER) #define UIAS_GLOBAL4 5 #define UIAS_GLOBAL5 6 #define UIAS_FAVORITES 7 +#define UIAS_NUM_SOURCES 8 #define UI_MAX_MASTER_SERVERS 6 @@ -96,12 +97,14 @@ MULTIPLAYER MENU (SERVER BROWSER) #define SORT_CLIENTS 2 #define SORT_GAME 3 #define SORT_PING 4 +#define SORT_NUM_SORTS 5 #define GAMES_ALL 0 #define GAMES_FFA 1 #define GAMES_TEAMPLAY 2 #define GAMES_TOURNEY 3 #define GAMES_CTF 4 +#define GAMES_NUM_GAMES 5 static const char *master_items[] = { "Local", @@ -1104,7 +1107,7 @@ int ArenaServers_SetType( int type ) char masterstr[2], cvarname[sizeof("sv_master1")]; int direction; - if (type == g_servertype || type == ((g_servertype+1) % (ARRAY_LEN(master_items)-1))) { + if (type == g_servertype || type == ((g_servertype+1) % UIAS_NUM_SOURCES)) { direction = 1; } else { direction = -1; @@ -1585,12 +1588,12 @@ static void ArenaServers_MenuInit( void ) { ArenaServers_LoadFavorites(); - g_arenaservers.master.curvalue = g_servertype = Com_Clamp( 0, 6, ui_browserMaster.integer ); + g_arenaservers.master.curvalue = g_servertype = Com_Clamp( 0, UIAS_NUM_SOURCES-1, ui_browserMaster.integer ); - g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer ); + g_gametype = Com_Clamp( 0, GAMES_NUM_GAMES-1, ui_browserGameType.integer ); g_arenaservers.gametype.curvalue = g_gametype; - g_sortkey = Com_Clamp( 0, 4, ui_browserSortKey.integer ); + g_sortkey = Com_Clamp( 0, SORT_NUM_SORTS-1, ui_browserSortKey.integer ); g_arenaservers.sortkey.curvalue = g_sortkey; g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer ); diff --git a/code/sdl/sdl_snd.c b/code/sdl/sdl_snd.c index e37b4d38..eb0dd58f 100644 --- a/code/sdl/sdl_snd.c +++ b/code/sdl/sdl_snd.c @@ -188,9 +188,6 @@ qboolean SNDDMA_Init(void) SDL_AudioSpec desired; SDL_AudioSpec obtained; int tmp; -#ifdef USE_SDL_AUDIO_CAPTURE - SDL_version sdlVersion; -#endif if (snd_inited) return qtrue; @@ -267,20 +264,15 @@ qboolean SNDDMA_Init(void) if (!tmp) tmp = (obtained.samples * obtained.channels) * 10; - if (tmp & (tmp - 1)) // not a power of two? Seems to confuse something. - { - int val = 1; - while (val < tmp) - val <<= 1; - - tmp = val; - } + // samples must be divisible by number of channels + tmp -= tmp % obtained.channels; dmapos = 0; dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format); dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format); dma.channels = obtained.channels; dma.samples = tmp; + dma.fullsamples = dma.samples / dma.channels; dma.submission_chunk = 1; dma.speed = obtained.freq; dmasize = (dma.samples * (dma.samplebits/8)); @@ -289,11 +281,10 @@ qboolean SNDDMA_Init(void) #ifdef USE_SDL_AUDIO_CAPTURE // !!! FIXME: some of these SDL_OpenAudioDevice() values should be cvars. s_sdlCapture = Cvar_Get( "s_sdlCapture", "1", CVAR_ARCHIVE | CVAR_LATCH ); - // !!! FIXME: hopefully pulseaudio capture will be fixed in SDL 2.0.9... https://bugzilla.libsdl.org/show_bug.cgi?id=4087 - SDL_GetVersion(&sdlVersion); - if (sdlVersion.major == 2 && sdlVersion.minor == 0 && sdlVersion.patch < 9 && Q_stricmp(SDL_GetCurrentAudioDriver(), "pulseaudio") == 0) + // !!! FIXME: pulseaudio capture records audio the entire time the program is running. https://bugzilla.libsdl.org/show_bug.cgi?id=4087 + if (Q_stricmp(SDL_GetCurrentAudioDriver(), "pulseaudio") == 0) { - Com_Printf("SDL audio capture support disabled (pulseaudio capture does not work correctly with SDL %d.%d.%d)\n", sdlVersion.major, sdlVersion.minor, sdlVersion.patch); + Com_Printf("SDL audio capture support disabled for pulseaudio (https://bugzilla.libsdl.org/show_bug.cgi?id=4087)\n"); } else if (!s_sdlCapture->integer) {