From 6bc3b33eabfbdb6767bfe8ff6624819fe3ecd4af Mon Sep 17 00:00:00 2001 From: zturtleman Date: Tue, 16 Oct 2018 17:48:51 +0000 Subject: [PATCH] ioquake3 resync to revision 3522 from 3511. Fix axis returned by IQM's LerpTag Calculate bounds for unanimated IQM models Fix loading favorites as initial source in server browser Improve finding obelisk entitynum for bot AI Fix SDL audio playback with surround sound Fix predicting entity origin on rotating mover Allow binds to use hex values for all key codes Disable pulseaudio capture regardless of SDL version Fix SDL audio playback with 16-bit stereo sound Make s_info command display channels instead of stereo Fix cross-compiling using mingw-w64 on Ubuntu 18.04 --- engine/Makefile | 15 ++++- engine/code/cgame/cg_ents.c | 50 +++++++++++++- engine/code/client/cl_keys.c | 10 ++- engine/code/client/snd_dma.c | 15 ++--- engine/code/client/snd_local.h | 1 + engine/code/client/snd_mix.c | 66 ++++++++++++------- engine/code/game/ai_dmq3.c | 38 +++++++++-- engine/code/q3_ui/ui_rally_servers.c | 15 ++--- engine/code/renderergl1/tr_model_iqm.c | 90 +++++++++++++------------- engine/code/renderergl2/tr_model_iqm.c | 90 +++++++++++++------------- engine/code/sdl/sdl_snd.c | 21 ++---- 11 files changed, 251 insertions(+), 160 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index 7e559910..ebddddcd 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -44,7 +44,7 @@ ifndef BUILD_DEFINES endif # ioquake3 svn version that this is based on -IOQ3_REVISION = 3444 +IOQ3_REVISION = 3522 ############################################################################# # @@ -292,7 +292,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) @@ -1394,6 +1404,7 @@ endif @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/engine/code/cgame/cg_ents.c b/engine/code/cgame/cg_ents.c index ea7571f4..bb72428b 100644 --- a/engine/code/cgame/cg_ents.c +++ b/engine/code/cgame/cg_ents.c @@ -844,6 +844,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 @@ -855,6 +893,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 ); @@ -878,9 +918,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/engine/code/client/cl_keys.c b/engine/code/client/cl_keys.c index b2bc9559..c786f526 100644 --- a/engine/code/client/cl_keys.c +++ b/engine/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/engine/code/client/snd_dma.c b/engine/code/client/snd_dma.c index 46d14fb7..141b53bb 100644 --- a/engine/code/client/snd_dma.c +++ b/engine/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); @@ -1242,9 +1242,6 @@ void S_GetSoundtime(void) int samplepos; static int buffers; static int oldsamplepos; - int fullsamples; - - fullsamples = dma.samples / dma.channels; if( CL_VideoRecording( ) ) { @@ -1268,13 +1265,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 @@ -1295,7 +1292,6 @@ void S_GetSoundtime(void) void S_Update_(void) { unsigned endtime; - int samps; static float lastTime = 0.0f; float ma, op; float thisTime, sane; @@ -1339,9 +1335,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/engine/code/client/snd_local.h b/engine/code/client/snd_local.h index 3b86d974..65392e36 100644 --- a/engine/code/client/snd_local.h +++ b/engine/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/engine/code/client/snd_mix.c b/engine/code/client/snd_mix.c index af0ba44a..8923b7cb 100644 --- a/engine/code/client/snd_mix.c +++ b/engine/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/engine/code/game/ai_dmq3.c b/engine/code/game/ai_dmq3.c index 5d24b5c1..26869d2f 100644 --- a/engine/code/game/ai_dmq3.c +++ b/engine/code/game/ai_dmq3.c @@ -5445,7 +5445,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); @@ -5526,21 +5552,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/engine/code/q3_ui/ui_rally_servers.c b/engine/code/q3_ui/ui_rally_servers.c index 4697f9b2..e8443f7b 100644 --- a/engine/code/q3_ui/ui_rally_servers.c +++ b/engine/code/q3_ui/ui_rally_servers.c @@ -104,6 +104,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 @@ -112,6 +113,7 @@ 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 // STONELANCE @@ -129,6 +131,7 @@ MULTIPLAYER MENU (SERVER BROWSER) #define GAMES_TEAM_RACING_DM 6 #define GAMES_TEAMPLAY 7 #define GAMES_CTF 8 +#define GAMES_NUM_GAMES 9 // END static const char *master_items[] = { @@ -1303,7 +1306,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; @@ -1906,16 +1909,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 ); -// STONELANCE -// g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer ); - g_gametype = Com_Clamp( 0, GT_MAX_GAME_TYPE, ui_browserGameType.integer ); -// END + 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/engine/code/renderergl1/tr_model_iqm.c b/engine/code/renderergl1/tr_model_iqm.c index bd256a98..02616469 100644 --- a/engine/code/renderergl1/tr_model_iqm.c +++ b/engine/code/renderergl1/tr_model_iqm.c @@ -58,11 +58,6 @@ static void Matrix34Multiply( float *a, float *b, float *out ) { out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10]; out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11]; } -static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) { - out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3]; - out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7]; - out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11]; -} static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) { float unLerp = 1.0f - lerp; @@ -571,6 +566,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na } if( header->ofs_bounds ) { size += header->num_frames * 6 * sizeof(float); // model bounds + } else if( header->num_meshes && header->num_frames == 0 ) { + size += 6 * sizeof(float); // model bounds } mod->type = MOD_IQM; @@ -646,6 +643,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na if( header->ofs_bounds ) { iqmData->bounds = (float*)dataPtr; dataPtr += header->num_frames * 6 * sizeof(float); // model bounds + } else if( header->num_meshes && header->num_frames == 0 ) { + iqmData->bounds = (float*)dataPtr; + dataPtr += 6 * sizeof(float); // model bounds } if( header->num_meshes ) @@ -912,6 +912,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na bounds++; } } + else if( header->num_meshes && header->num_frames == 0 ) + { + mat = iqmData->bounds; + + ClearBounds( &iqmData->bounds[0], &iqmData->bounds[3] ); + for ( i = 0 ; i < header->num_vertexes ; i++ ) { + AddPointToBounds( &iqmData->positions[i*3], &iqmData->bounds[0], &iqmData->bounds[3] ); + } + } return qtrue; } @@ -1124,18 +1133,6 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe, int *joint = data->jointParents; int i; - if ( data->num_poses == 0 ) { - for( i = 0; i < data->num_joints; i++, joint++ ) { - if( *joint >= 0 ) { - Matrix34Multiply( mat + 12 * *joint, - identityMatrix, mat + 12*i ); - } else { - Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) ); - } - } - return; - } - if ( oldframe == frame ) { mat1 = data->poseMats + 12 * data->num_poses * frame; for( i = 0; i < data->num_poses; i++, joint++ ) { @@ -1171,6 +1168,11 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe, float *mat1; int i; + if ( data->num_poses == 0 ) { + Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) ); + return; + } + ComputePoseMats( data, frame, oldframe, backlerp, mat ); for( i = 0; i < data->num_joints; i++ ) { @@ -1179,7 +1181,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe, Com_Memcpy(outmat, mat1, sizeof(outmat)); - Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 ); + Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 ); } } @@ -1194,7 +1196,7 @@ Compute vertices for this model surface void RB_IQMSurfaceAnim( surfaceType_t *surface ) { srfIQModel_t *surf = (srfIQModel_t *)surface; iqmData_t *data = surf->data; - float jointMats[IQM_MAX_JOINTS * 12]; + float poseMats[IQM_MAX_JOINTS * 12]; float influenceVtxMat[SHADER_MAX_VERTEXES * 12]; float influenceNrmMat[SHADER_MAX_VERTEXES * 9]; int i; @@ -1235,7 +1237,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { if ( data->num_poses > 0 ) { // compute interpolated joint matrices - ComputePoseMats( data, frame, oldframe, backlerp, jointMats ); + ComputePoseMats( data, frame, oldframe, backlerp, poseMats ); // compute vertex blend influence matricies for( i = 0; i < surf->num_influences; i++ ) { @@ -1273,32 +1275,32 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { } else { // compute the vertex matrix by blending the up to // four blend weights - vtxMat[0] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0]; - vtxMat[1] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1]; - vtxMat[2] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2]; - vtxMat[3] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3]; - vtxMat[4] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4]; - vtxMat[5] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5]; - vtxMat[6] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6]; - vtxMat[7] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7]; - vtxMat[8] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8]; - vtxMat[9] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9]; - vtxMat[10] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10]; - vtxMat[11] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11]; + vtxMat[0] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0]; + vtxMat[1] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1]; + vtxMat[2] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2]; + vtxMat[3] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3]; + vtxMat[4] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4]; + vtxMat[5] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5]; + vtxMat[6] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6]; + vtxMat[7] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7]; + vtxMat[8] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8]; + vtxMat[9] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9]; + vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10]; + vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11]; for( j = 1; j < numWeights; j++ ) { - vtxMat[0] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 0]; - vtxMat[1] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 1]; - vtxMat[2] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 2]; - vtxMat[3] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 3]; - vtxMat[4] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 4]; - vtxMat[5] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 5]; - vtxMat[6] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 6]; - vtxMat[7] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 7]; - vtxMat[8] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 8]; - vtxMat[9] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 9]; - vtxMat[10] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 10]; - vtxMat[11] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 11]; + vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0]; + vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1]; + vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2]; + vtxMat[3] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 3]; + vtxMat[4] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 4]; + vtxMat[5] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 5]; + vtxMat[6] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 6]; + vtxMat[7] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 7]; + vtxMat[8] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 8]; + vtxMat[9] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 9]; + vtxMat[10] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 10]; + vtxMat[11] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 11]; } } diff --git a/engine/code/renderergl2/tr_model_iqm.c b/engine/code/renderergl2/tr_model_iqm.c index 13b234fe..1a6e1e5a 100644 --- a/engine/code/renderergl2/tr_model_iqm.c +++ b/engine/code/renderergl2/tr_model_iqm.c @@ -58,11 +58,6 @@ static void Matrix34Multiply( float *a, float *b, float *out ) { out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10]; out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11]; } -static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) { - out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3]; - out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7]; - out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11]; -} static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) { float unLerp = 1.0f - lerp; @@ -574,6 +569,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na } if( header->ofs_bounds ) { size += header->num_frames * 6 * sizeof(float); // model bounds + } else if( header->num_meshes && header->num_frames == 0 ) { + size += 6 * sizeof(float); // model bounds } mod->type = MOD_IQM; @@ -649,6 +646,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na if( header->ofs_bounds ) { iqmData->bounds = (float*)dataPtr; dataPtr += header->num_frames * 6 * sizeof(float); // model bounds + } else if( header->num_meshes && header->num_frames == 0 ) { + iqmData->bounds = (float*)dataPtr; + dataPtr += 6 * sizeof(float); // model bounds } if( header->num_meshes ) @@ -915,6 +915,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na bounds++; } } + else if( header->num_meshes && header->num_frames == 0 ) + { + mat = iqmData->bounds; + + ClearBounds( &iqmData->bounds[0], &iqmData->bounds[3] ); + for ( i = 0 ; i < header->num_vertexes ; i++ ) { + AddPointToBounds( &iqmData->positions[i*3], &iqmData->bounds[0], &iqmData->bounds[3] ); + } + } // Create VAO surfaces if ( iqmData->num_surfaces && iqmData->num_joints <= glRefConfig.glslMaxAnimatedBones ) @@ -1302,18 +1311,6 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe, int *joint = data->jointParents; int i; - if ( data->num_poses == 0 ) { - for( i = 0; i < data->num_joints; i++, joint++ ) { - if( *joint >= 0 ) { - Matrix34Multiply( mat + 12 * *joint, - identityMatrix, mat + 12*i ); - } else { - Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) ); - } - } - return; - } - if ( oldframe == frame ) { mat1 = data->poseMats + 12 * data->num_poses * frame; for( i = 0; i < data->num_poses; i++, joint++ ) { @@ -1349,6 +1346,11 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe, float *mat1; int i; + if ( data->num_poses == 0 ) { + Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) ); + return; + } + ComputePoseMats( data, frame, oldframe, backlerp, mat ); for( i = 0; i < data->num_joints; i++ ) { @@ -1357,7 +1359,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe, Com_Memcpy(outmat, mat1, sizeof(outmat)); - Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 ); + Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 ); } } @@ -1372,7 +1374,7 @@ Compute vertices for this model surface void RB_IQMSurfaceAnim( surfaceType_t *surface ) { srfIQModel_t *surf = (srfIQModel_t *)surface; iqmData_t *data = surf->data; - float jointMats[IQM_MAX_JOINTS * 12]; + float poseMats[IQM_MAX_JOINTS * 12]; float influenceVtxMat[SHADER_MAX_VERTEXES * 12]; float influenceNrmMat[SHADER_MAX_VERTEXES * 9]; int i; @@ -1417,7 +1419,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { if ( data->num_poses > 0 ) { // compute interpolated joint matrices - ComputePoseMats( data, frame, oldframe, backlerp, jointMats ); + ComputePoseMats( data, frame, oldframe, backlerp, poseMats ); // compute vertex blend influence matricies for( i = 0; i < surf->num_influences; i++ ) { @@ -1455,32 +1457,32 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { } else { // compute the vertex matrix by blending the up to // four blend weights - vtxMat[0] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0]; - vtxMat[1] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1]; - vtxMat[2] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2]; - vtxMat[3] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3]; - vtxMat[4] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4]; - vtxMat[5] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5]; - vtxMat[6] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6]; - vtxMat[7] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7]; - vtxMat[8] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8]; - vtxMat[9] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9]; - vtxMat[10] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10]; - vtxMat[11] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11]; + vtxMat[0] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0]; + vtxMat[1] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1]; + vtxMat[2] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2]; + vtxMat[3] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3]; + vtxMat[4] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4]; + vtxMat[5] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5]; + vtxMat[6] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6]; + vtxMat[7] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7]; + vtxMat[8] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8]; + vtxMat[9] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9]; + vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10]; + vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11]; for( j = 1; j < numWeights; j++ ) { - vtxMat[0] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 0]; - vtxMat[1] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 1]; - vtxMat[2] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 2]; - vtxMat[3] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 3]; - vtxMat[4] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 4]; - vtxMat[5] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 5]; - vtxMat[6] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 6]; - vtxMat[7] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 7]; - vtxMat[8] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 8]; - vtxMat[9] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 9]; - vtxMat[10] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 10]; - vtxMat[11] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 11]; + vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0]; + vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1]; + vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2]; + vtxMat[3] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 3]; + vtxMat[4] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 4]; + vtxMat[5] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 5]; + vtxMat[6] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 6]; + vtxMat[7] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 7]; + vtxMat[8] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 8]; + vtxMat[9] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 9]; + vtxMat[10] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 10]; + vtxMat[11] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 11]; } } diff --git a/engine/code/sdl/sdl_snd.c b/engine/code/sdl/sdl_snd.c index e37b4d38..eb0dd58f 100644 --- a/engine/code/sdl/sdl_snd.c +++ b/engine/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) {