diff --git a/build/engine/shaders/base/static.vs b/build/engine/shaders/base/static.vs index 7519f8a490b02ee9ec8f401c5d6f3bcd0c43941b..c32007f63c091087b164bca512f03cc11a3dd8a7 100644 --- a/build/engine/shaders/base/static.vs +++ b/build/engine/shaders/base/static.vs @@ -45,10 +45,15 @@ VSO_SceneCommon main(VSI_Geometry IN // OUT.vPosition = float4(IN.vPosition, 1.0f); OUT.vNormal = RotateVec(qRot, IN.vNormal); + OUT.vTangent = RotateVec(qRot, IN.vTangent); + OUT.vBinormal = RotateVec(qRot, IN.vBinormal); // OUT.vNormal = IN.vNormal; #else OUT.vPosition = mul(float4(IN.vPosition, 1.0f), g_mW); - OUT.vNormal = mul(IN.vNormal, (float3x3)g_mW); + OUT.vNormal = /*normalize(*/mul(IN.vNormal, (float3x3)g_mW)/*)*/; + OUT.vTangent = /*normalize(*/mul(IN.vTangent, (float3x3)g_mW)/*)*/; + OUT.vBinormal = /*normalize(*/mul(IN.vBinormal, (float3x3)g_mW)/*)*/; + #endif diff --git a/build/engine/shaders/default/default.ps b/build/engine/shaders/default/default.ps index 0d851c06e47f08a5ef0a8d91ed5be796950c7b44..1ea443127ff45d4963e394e10742c2c4f1047b05 100644 --- a/build/engine/shaders/default/default.ps +++ b/build/engine/shaders/default/default.ps @@ -26,9 +26,9 @@ XMaterial MainGBuffer(PSI_XMaterial IN) #endif #ifdef HAS_NORMALMAP - OUT.vNormal = MixNormalMicro(IN.vNormal, - Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight - ); + float3 vNormalMap = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight; + OUT.vNormal = MixNormalMicro(vNormalMap, IN.vTangent, IN.vBinormal, IN.vNormal); + //OUT.vNormal = normalize((IN.vNormal + float3(vNormalMap.xy,IN.vNormal.z))); #else OUT.vNormal = IN.vNormal; #endif @@ -58,9 +58,8 @@ XMaterial MainIllimination(PSI_XMaterial IN) OUT.vEmissiveColor = fColor.xyz * fColor.w * g_xMaterialConstants.em_multiplier; #ifdef HAS_NORMALMAP - OUT.vNormal = MixNormalMicro(IN.vNormal, - Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight - ); + float3 vNormalMap = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight; + OUT.vNormal = MixNormalMicro(vNormalMap, IN.vTangent, IN.vBinormal, IN.vNormal); #else OUT.vNormal = IN.vNormal; #endif diff --git a/build/engine/shaders/default/terrain.ps b/build/engine/shaders/default/terrain.ps index 162b155bf09a4a216c6b95bb8deee300808d6e0e..ae3138e70d41701e4a39934ad6bd3cc4c534dfdc 100644 --- a/build/engine/shaders/default/terrain.ps +++ b/build/engine/shaders/default/terrain.ps @@ -84,7 +84,9 @@ XMaterial MainGBuffer(PSI_XMaterial IN) OUT.fThickness = vParams.z; OUT.fAO = vParams.w; - OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal); + //OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal); + OUT.vNormal = MixNormalMicro(vNormal, IN.vTangent, IN.vBinormal, IN.vNormal); + //OUT.vNormal = normalize((IN.vNormal + float3(vNormal.xy,IN.vNormal.z))); OUT.f0 = 0.004; diff --git a/build/engine/shaders/default/transparent.ps b/build/engine/shaders/default/transparent.ps index fd011224335bfa099544d4df084bb846e81b379d..8bd5ee96a2858bb61cc020f42c2fcb19b0cf53f0 100644 --- a/build/engine/shaders/default/transparent.ps +++ b/build/engine/shaders/default/transparent.ps @@ -13,9 +13,9 @@ XMaterial MainTransparency(PSI_XMaterial IN) #ifdef HAS_NORMALMAP float3 vNormal = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight; - OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal); + //OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal); // float2 vDuDv = vNormal.xy; - + OUT.vNormal = MixNormalMicro(vNormal, IN.vTangent, IN.vBinormal, IN.vNormal); #ifdef HAS_REFRACTION // float2 vDuDv = OUT.vNormal.xy; @@ -84,9 +84,8 @@ XMaterial MainIllimination(PSI_XMaterial IN) OUT.vEmissiveColor = fColor.xyz; #ifdef HAS_NORMALMAP - OUT.vNormal = MixNormalMicro(IN.vNormal, - Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight - ); + float3 vNormalMap = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight; + OUT.vNormal = MixNormalMicro(vNormalMap, IN.vTangent, IN.vBinormal, IN.vNormal); #else OUT.vNormal = IN.vNormal; #endif diff --git a/build/engine/shaders/mtrl.h b/build/engine/shaders/mtrl.h index a39b98a71f7234456dad02b064db575ca6d26369..fc8d9108d47ef32e35eaf5cc569a93eea9194dc2 100644 --- a/build/engine/shaders/mtrl.h +++ b/build/engine/shaders/mtrl.h @@ -192,9 +192,15 @@ float GetLerpFactorDetail(float fDistance) } //! смешивание макронормали (модели) с микронормалью (из normal map) -float3 MixNormalMicro(float3 vMacroNormal, float3 vMicroNormal) +/*float3 MixNormalMicro(float3 vMacroNormal, float3 vMicroNormal) { return normalize((vMacroNormal + float3(vMicroNormal.xy,vMacroNormal.z))); +}*/ + +float3 MixNormalMicro(float3 vNormalMap, float3 vTangent, float3 vBinormal, float3 vNormal) +{ + float3x3 mTBN = float3x3(vTangent, vBinormal, vNormal); + return normalize(mul(vNormalMap, mTBN)); } //! смешивание 2 детальных текстур по маске, где r канал маски для первой детальной текстуры, а g для второй diff --git a/build/engine/shaders/struct.h b/build/engine/shaders/struct.h index 1fd16aceeb265abb259099c53b690581e5e9d89b..586f6c2e8b8c6d3d048726ba7ce167caf5a4e8bd 100644 --- a/build/engine/shaders/struct.h +++ b/build/engine/shaders/struct.h @@ -68,6 +68,8 @@ struct VSI_Geometry float3 vPosition :POSITION0; float2 vTexUV :TEXCOORD0; float3 vNormal :NORMAL0; + float3 vTangent : TANGENT0; + float3 vBinormal : BINORMAL0; }; @@ -112,6 +114,8 @@ struct VSO_SceneCommon float2 vTexUV :TEXCOORD0; float3 vNormal :TEXCOORD1; float4 vPos :TEXCOORD2; + float3 vTangent :TEXCOORD3; + float3 vBinormal :TEXCOORD4; }; struct GSO_SceneShadows diff --git a/build/engine/sounds/actor/step/default1.ogg b/build/engine/sounds/actor/step/default1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..10bddbf3524db9d5baa225f54dbb1b7b1567be47 Binary files /dev/null and b/build/engine/sounds/actor/step/default1.ogg differ diff --git a/build/engine/sounds/actor/step/default2.ogg b/build/engine/sounds/actor/step/default2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..10bddbf3524db9d5baa225f54dbb1b7b1567be47 Binary files /dev/null and b/build/engine/sounds/actor/step/default2.ogg differ diff --git a/build/engine/sounds/actor/step/default3.ogg b/build/engine/sounds/actor/step/default3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..73a09e6a81665bd572d304d2b150b45ea63fe1d2 Binary files /dev/null and b/build/engine/sounds/actor/step/default3.ogg differ diff --git a/build/engine/sounds/actor/step/default4.ogg b/build/engine/sounds/actor/step/default4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3f2e4af404716328ecf97ce14dd1b8936bae4698 Binary files /dev/null and b/build/engine/sounds/actor/step/default4.ogg differ diff --git a/build/engine/sounds/actor/step/earth1.ogg b/build/engine/sounds/actor/step/earth1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..35be9058f776be270fc07b29c21256af2a2d08cf Binary files /dev/null and b/build/engine/sounds/actor/step/earth1.ogg differ diff --git a/build/engine/sounds/actor/step/earth2.ogg b/build/engine/sounds/actor/step/earth2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2c86be24cdfe51c1b827992981fa468603206cc9 Binary files /dev/null and b/build/engine/sounds/actor/step/earth2.ogg differ diff --git a/build/engine/sounds/actor/step/earth3.ogg b/build/engine/sounds/actor/step/earth3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a61dd0549a6f6167863832251477bc1a5d4804ee Binary files /dev/null and b/build/engine/sounds/actor/step/earth3.ogg differ diff --git a/build/engine/sounds/actor/step/earth4.ogg b/build/engine/sounds/actor/step/earth4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fe7ba8a7f10da38a5bb688d73f5df1d781473dfe Binary files /dev/null and b/build/engine/sounds/actor/step/earth4.ogg differ diff --git a/build/engine/sounds/actor/step/grass1.ogg b/build/engine/sounds/actor/step/grass1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f038d57c7acabb79c2b535e8f47f861fa80937e3 Binary files /dev/null and b/build/engine/sounds/actor/step/grass1.ogg differ diff --git a/build/engine/sounds/actor/step/grass2.ogg b/build/engine/sounds/actor/step/grass2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f3d4b55338dd8b27fa8017685c595c0380dbabda Binary files /dev/null and b/build/engine/sounds/actor/step/grass2.ogg differ diff --git a/build/engine/sounds/actor/step/grass3.ogg b/build/engine/sounds/actor/step/grass3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..329af390d67654b88daf923f2b079a0b85dca254 Binary files /dev/null and b/build/engine/sounds/actor/step/grass3.ogg differ diff --git a/build/engine/sounds/actor/step/grass4.ogg b/build/engine/sounds/actor/step/grass4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..989c27d6d14dde7a7d7435d1abd6ef0c08776c01 Binary files /dev/null and b/build/engine/sounds/actor/step/grass4.ogg differ diff --git a/build/engine/sounds/actor/step/gravel1.ogg b/build/engine/sounds/actor/step/gravel1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c85b6f54783885149cb551f0b451e0f5ee3f62eb Binary files /dev/null and b/build/engine/sounds/actor/step/gravel1.ogg differ diff --git a/build/engine/sounds/actor/step/gravel2.ogg b/build/engine/sounds/actor/step/gravel2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2e0aa06f236aa1a2cadf30a8dc485091381cdc3e Binary files /dev/null and b/build/engine/sounds/actor/step/gravel2.ogg differ diff --git a/build/engine/sounds/actor/step/metal_plate1.ogg b/build/engine/sounds/actor/step/metal_plate1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fed2f89c008b638eaa51de437aa094c8df607b35 Binary files /dev/null and b/build/engine/sounds/actor/step/metal_plate1.ogg differ diff --git a/build/engine/sounds/actor/step/metal_plate2.ogg b/build/engine/sounds/actor/step/metal_plate2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3c34feb6bb8f124952662c44f3f30ea77dd88453 Binary files /dev/null and b/build/engine/sounds/actor/step/metal_plate2.ogg differ diff --git a/build/engine/sounds/actor/step/metal_plate3.ogg b/build/engine/sounds/actor/step/metal_plate3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..10f64e0ed1697a0e3bf2a0b2a95848c6cf38344d Binary files /dev/null and b/build/engine/sounds/actor/step/metal_plate3.ogg differ diff --git a/build/engine/sounds/actor/step/metal_plate4.ogg b/build/engine/sounds/actor/step/metal_plate4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..70a87c80702b5878707e3ff9229a608069d50ce4 Binary files /dev/null and b/build/engine/sounds/actor/step/metal_plate4.ogg differ diff --git a/build/engine/sounds/actor/step/new_wood1.ogg b/build/engine/sounds/actor/step/new_wood1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..47c65ba7dc20fd5662b26dbf2006251f306aa76b Binary files /dev/null and b/build/engine/sounds/actor/step/new_wood1.ogg differ diff --git a/build/engine/sounds/actor/step/new_wood2.ogg b/build/engine/sounds/actor/step/new_wood2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8b3a7ef404310275c0c001fbed24ae3f04242306 Binary files /dev/null and b/build/engine/sounds/actor/step/new_wood2.ogg differ diff --git a/build/engine/sounds/actor/step/new_wood3.ogg b/build/engine/sounds/actor/step/new_wood3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bc86b78d3a5ca0bf2740cb2fceec9f245d316ec2 Binary files /dev/null and b/build/engine/sounds/actor/step/new_wood3.ogg differ diff --git a/build/engine/sounds/actor/step/new_wood4.ogg b/build/engine/sounds/actor/step/new_wood4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1b4f161016511b0c11cb5bcfa0382288cb1fcf5a Binary files /dev/null and b/build/engine/sounds/actor/step/new_wood4.ogg differ diff --git a/build/engine/sounds/actor/step/t_water1.ogg b/build/engine/sounds/actor/step/t_water1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9f4439fa1374a449553e27cace2e27529a628f16 Binary files /dev/null and b/build/engine/sounds/actor/step/t_water1.ogg differ diff --git a/build/engine/sounds/actor/step/t_water2.ogg b/build/engine/sounds/actor/step/t_water2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6917fc69f77e70d3d5e8530a72e6855a983b2397 Binary files /dev/null and b/build/engine/sounds/actor/step/t_water2.ogg differ diff --git a/build/engine/sounds/actor/step/tin1.ogg b/build/engine/sounds/actor/step/tin1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3f46493f0495972c6dd575da3965a4dc40cc7103 Binary files /dev/null and b/build/engine/sounds/actor/step/tin1.ogg differ diff --git a/build/engine/sounds/actor/step/tin2.ogg b/build/engine/sounds/actor/step/tin2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f24e21407c78a4cc3062e38d9f47e9f34edfb638 Binary files /dev/null and b/build/engine/sounds/actor/step/tin2.ogg differ diff --git a/build/engine/sounds/actor/step/tin3.ogg b/build/engine/sounds/actor/step/tin3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..29e734b64bec62da25d71e30a0fe33c7b0654eb2 Binary files /dev/null and b/build/engine/sounds/actor/step/tin3.ogg differ diff --git a/build/engine/sounds/actor/step/tin4.ogg b/build/engine/sounds/actor/step/tin4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0939da1dedf474b6bed20e32b3b52f2de386fb89 Binary files /dev/null and b/build/engine/sounds/actor/step/tin4.ogg differ diff --git a/build/engine/sounds/actor/step/wpn_large1.ogg b/build/engine/sounds/actor/step/wpn_large1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6eaa45b21f4569f11addc776c38f26bf5b815b9d Binary files /dev/null and b/build/engine/sounds/actor/step/wpn_large1.ogg differ diff --git a/build/engine/sounds/actor/step/wpn_large2.ogg b/build/engine/sounds/actor/step/wpn_large2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..acff58e339b5aa1897bd419a349909c0b466a496 Binary files /dev/null and b/build/engine/sounds/actor/step/wpn_large2.ogg differ diff --git a/build/engine/sounds/actor/step/wpn_small1.ogg b/build/engine/sounds/actor/step/wpn_small1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7fdca9aa57ded3ee490280c575ae828f70887b4b Binary files /dev/null and b/build/engine/sounds/actor/step/wpn_small1.ogg differ diff --git a/build/engine/sounds/actor/step/wpn_small2.ogg b/build/engine/sounds/actor/step/wpn_small2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f960ee93b63f7a65179278c8da1fecda9cff536d Binary files /dev/null and b/build/engine/sounds/actor/step/wpn_small2.ogg differ diff --git a/proj/SkyXEngine/vs2013/SkyXEngine.sln b/proj/SkyXEngine/vs2013/SkyXEngine.sln index 88198265392df05fdfa6e792f88097f191277951..78df0cfb6eb3a499f4809fd3df03a26959a9ff06 100644 --- a/proj/SkyXEngine/vs2013/SkyXEngine.sln +++ b/proj/SkyXEngine/vs2013/SkyXEngine.sln @@ -15,6 +15,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkyXEngine", "SkyXEngine.vc {709D8A7A-D3E0-4070-A493-EFDF7A8E9D73} = {709D8A7A-D3E0-4070-A493-EFDF7A8E9D73} {16D78A7B-8EE9-4FD3-84C9-B71D8723E718} = {16D78A7B-8EE9-4FD3-84C9-B71D8723E718} {6A402480-C09B-4CBF-A6BD-115CE4BFF2D8} = {6A402480-C09B-4CBF-A6BD-115CE4BFF2D8} + {4A77FC81-98F6-4ABF-A489-B6F427354E5B} = {4A77FC81-98F6-4ABF-A489-B6F427354E5B} {2B3BA583-D5EC-4DC2-91CF-42B1C7ADFD9D} = {2B3BA583-D5EC-4DC2-91CF-42B1C7ADFD9D} {5145958A-F75F-4F6D-9793-7384B616CF76} = {5145958A-F75F-4F6D-9793-7384B616CF76} {3A5449A3-DCE7-4557-9C9F-DEEAFBAAC763} = {3A5449A3-DCE7-4557-9C9F-DEEAFBAAC763} @@ -362,6 +363,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oggplugin", "..\..\oggplugi EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wavplugin", "..\..\wavplugin\vs2013\wavplugin.vcxproj", "{3DB7AC42-6141-417D-B2E6-7D62F08A2246}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xSound", "..\..\xSound\vs2013\xSound.vcxproj", "{4A77FC81-98F6-4ABF-A489-B6F427354E5B}" + ProjectSection(ProjectDependencies) = postProject + {3DB7AC42-6141-417D-B2E6-7D62F08A2246} = {3DB7AC42-6141-417D-B2E6-7D62F08A2246} + {C1C1F046-C839-4602-AF70-923CDD237C1B} = {C1C1F046-C839-4602-AF70-923CDD237C1B} + {8D0540EE-F8A5-44AB-8023-AD75251167E4} = {8D0540EE-F8A5-44AB-8023-AD75251167E4} + {F926F7FA-099E-499C-ABC9-743BCAB919C4} = {F926F7FA-099E-499C-ABC9-743BCAB919C4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mital", "..\..\..\sdks\mital\proj\vs2013\mital\mital.vcxproj", "{8D0540EE-F8A5-44AB-8023-AD75251167E4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "xSound", "xSound", "{3B9DBCFA-CFB6-459D-BE24-2EECB2E3042C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms @@ -872,6 +885,7 @@ Global {02E4C411-4802-4522-A2D6-00094A4CD14B}.Debug|Win32.ActiveCfg = Debug|Win32 {02E4C411-4802-4522-A2D6-00094A4CD14B}.Debug|Win32.Build.0 = Debug|Win32 {02E4C411-4802-4522-A2D6-00094A4CD14B}.Debug|x64.ActiveCfg = Debug|x64 + {02E4C411-4802-4522-A2D6-00094A4CD14B}.Debug|x64.Build.0 = Debug|x64 {02E4C411-4802-4522-A2D6-00094A4CD14B}.Release|Mixed Platforms.ActiveCfg = Release|x64 {02E4C411-4802-4522-A2D6-00094A4CD14B}.Release|Mixed Platforms.Build.0 = Release|x64 {02E4C411-4802-4522-A2D6-00094A4CD14B}.Release|Win32.ActiveCfg = Release|Win32 @@ -882,6 +896,7 @@ Global {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Debug|Win32.ActiveCfg = Debug|Win32 {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Debug|Win32.Build.0 = Debug|Win32 {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Debug|x64.ActiveCfg = Debug|x64 + {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Debug|x64.Build.0 = Debug|x64 {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Release|Mixed Platforms.Build.0 = Release|Win32 {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Release|Win32.ActiveCfg = Release|Win32 @@ -889,14 +904,40 @@ Global {F926F7FA-099E-499C-ABC9-743BCAB919C4}.Release|x64.ActiveCfg = Release|x64 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|Win32.ActiveCfg = Debug|x64 - {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|Win32.Build.0 = Debug|x64 - {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|x64.ActiveCfg = Debug|Win32 + {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|Win32.ActiveCfg = Debug|Win32 + {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|Win32.Build.0 = Debug|Win32 + {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|x64.ActiveCfg = Debug|x64 + {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Debug|x64.Build.0 = Debug|x64 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|Mixed Platforms.Build.0 = Release|Win32 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|Win32.ActiveCfg = Release|Win32 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|Win32.Build.0 = Release|Win32 {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|x64.ActiveCfg = Release|x64 + {3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|x64.Build.0 = Release|x64 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Win32.Build.0 = Debug|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|x64.ActiveCfg = Debug|x64 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|x64.Build.0 = Debug|x64 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|Mixed Platforms.Build.0 = Release|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|Win32.ActiveCfg = Release|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|Win32.Build.0 = Release|Win32 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|x64.ActiveCfg = Release|x64 + {4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|x64.Build.0 = Release|x64 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Win32.ActiveCfg = Debug|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Win32.Build.0 = Debug|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|x64.ActiveCfg = Debug|x64 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|x64.Build.0 = Debug|x64 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Release|Mixed Platforms.Build.0 = Release|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Release|Win32.ActiveCfg = Release|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Release|Win32.Build.0 = Release|Win32 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Release|x64.ActiveCfg = Release|x64 + {8D0540EE-F8A5-44AB-8023-AD75251167E4}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -961,5 +1002,8 @@ Global {02E4C411-4802-4522-A2D6-00094A4CD14B} = {602837DA-C6C8-4D51-97A1-770224A52693} {F926F7FA-099E-499C-ABC9-743BCAB919C4} = {602837DA-C6C8-4D51-97A1-770224A52693} {3DB7AC42-6141-417D-B2E6-7D62F08A2246} = {7C1F0E50-7A19-4AB4-B559-11EF078F4787} + {4A77FC81-98F6-4ABF-A489-B6F427354E5B} = {3B9DBCFA-CFB6-459D-BE24-2EECB2E3042C} + {8D0540EE-F8A5-44AB-8023-AD75251167E4} = {3B9DBCFA-CFB6-459D-BE24-2EECB2E3042C} + {3B9DBCFA-CFB6-459D-BE24-2EECB2E3042C} = {4408F4BE-1F9D-4861-881A-AF9869C3D663} EndGlobalSection EndGlobal diff --git a/proj/oggplugin/vs2013/oggplugin.vcxproj b/proj/oggplugin/vs2013/oggplugin.vcxproj index a484c17e8ee1f38046bbd39081643b01c5e798be..8a51092afe8f54308d9774c70e59123f2a31bd31 100644 --- a/proj/oggplugin/vs2013/oggplugin.vcxproj +++ b/proj/oggplugin/vs2013/oggplugin.vcxproj @@ -98,7 +98,7 @@ </PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> </ClCompile> <Link> @@ -114,7 +114,7 @@ </PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> </ClCompile> <Link> @@ -132,7 +132,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> </ClCompile> <Link> @@ -152,7 +152,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> </ClCompile> <Link> diff --git a/proj/sxgame/vs2013/sxgame.vcxproj b/proj/sxgame/vs2013/sxgame.vcxproj index 68c8350f5c9ecd251f00065532e92a422c0bcefa..a867ed7d5d6d21a2bac09eec943028b698ef42e8 100644 --- a/proj/sxgame/vs2013/sxgame.vcxproj +++ b/proj/sxgame/vs2013/sxgame.vcxproj @@ -230,6 +230,7 @@ <ClCompile Include="..\..\..\source\game\BaseTool.cpp" /> <ClCompile Include="..\..\..\source\game\BaseWeapon.cpp" /> <ClCompile Include="..\..\..\source\game\SettingsWriter.cpp" /> + <ClCompile Include="..\..\..\source\game\SoundPlayer.cpp" /> <ClCompile Include="..\..\..\source\game\sxgame_dll.cpp" /> <ClCompile Include="..\..\..\source\game\Player.cpp" /> <ClCompile Include="..\..\..\source\game\PlayerSpawn.cpp" /> @@ -296,6 +297,7 @@ <ClInclude Include="..\..\..\source\game\BaseTool.h" /> <ClInclude Include="..\..\..\source\game\BaseWeapon.h" /> <ClInclude Include="..\..\..\source\game\SettingsWriter.h" /> + <ClInclude Include="..\..\..\source\game\SoundPlayer.h" /> <ClInclude Include="..\..\..\source\game\sxgame.h" /> <ClInclude Include="..\..\..\source\game\Player.h" /> <ClInclude Include="..\..\..\source\game\PlayerSpawn.h" /> diff --git a/proj/sxgame/vs2013/sxgame.vcxproj.filters b/proj/sxgame/vs2013/sxgame.vcxproj.filters index 14e94410a9924cfda60a057cba1fc8cae9f108fa..71f76362f986dc8aadad08bdd70e8444ce6fbbf2 100644 --- a/proj/sxgame/vs2013/sxgame.vcxproj.filters +++ b/proj/sxgame/vs2013/sxgame.vcxproj.filters @@ -267,6 +267,9 @@ <ClCompile Include="..\..\..\source\game\FuncTrain.cpp"> <Filter>Source Files\ents\func</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\game\SoundPlayer.cpp"> + <Filter>Header Files\ents</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\source\game\sxgame.h"> @@ -464,5 +467,8 @@ <ClInclude Include="..\..\..\source\game\FuncTrain.h"> <Filter>Header Files\ents\func</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\game\SoundPlayer.h"> + <Filter>Header Files\ents</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/proj/wavplugin/vs2013/wavplugin.vcxproj b/proj/wavplugin/vs2013/wavplugin.vcxproj index 596d94b967382dff5d945be64717b699d5392719..eaa6250f062cd0b8851d34bfc0f0fe0ff049f5bd 100644 --- a/proj/wavplugin/vs2013/wavplugin.vcxproj +++ b/proj/wavplugin/vs2013/wavplugin.vcxproj @@ -94,7 +94,7 @@ </PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> </ClCompile> <Link> @@ -110,7 +110,7 @@ </PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> </ClCompile> <Link> @@ -128,7 +128,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> </ClCompile> <Link> @@ -148,7 +148,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> </ClCompile> <Link> diff --git a/proj/xSound/vs2013/xSound.vcxproj b/proj/xSound/vs2013/xSound.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..2c29048701da7f6a0e105fbe93654c78fda3fc6d --- /dev/null +++ b/proj/xSound/vs2013/xSound.vcxproj @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4A77FC81-98F6-4ABF-A489-B6F427354E5B}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>xSound</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../sdks/;../../../source;../../../sdks/mital/source/;</IncludePath> + <OutDir>../../../build/bin/plugins/</OutDir> + <TargetName>$(ProjectName)_d</TargetName> + <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../libs;../../../sdks/mital/lib/;</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>$(ProjectName)_d</TargetName> + <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../libs64;../../../sdks/mital/lib64/;</LibraryPath> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;../../../sdks/;</IncludePath> + <OutDir>../../../build/bin64/plugins/</OutDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>../../../build/bin/plugins/</OutDir> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../sdks/;../../../source;../../../sdks/mital/source/;</IncludePath> + <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../libs;../../../sdks/mital/lib/;</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../sdks/;../../../source;../../../sdks/mital/source/;</IncludePath> + <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../libs64;../../../sdks/mital/lib64/;</LibraryPath> + <LinkIncremental>false</LinkIncremental> + <OutDir>../../../build/bin64/plugins/</OutDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;XSOUND_EXPORTS;SX_LIB_NAME="XSOUND";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(ProjectDir)../../../pdb/$(TargetName).pdb</ProgramDatabaseFile> + <ImportLibrary>../../../libs/$(TargetName).lib</ImportLibrary> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;XSOUND_EXPORTS;SX_LIB_NAME="XSOUND";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(ProjectDir)../../../pdb64/$(TargetName).pdb</ProgramDatabaseFile> + <ImportLibrary>../../../libs64/$(TargetName)_d.lib</ImportLibrary> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;XSOUND_EXPORTS;SX_LIB_NAME="XSOUND";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ImportLibrary>../../../libs/$(TargetName).lib</ImportLibrary> + <ProgramDatabaseFile>$(ProjectDir)../../../pdb/$(TargetName).pdb</ProgramDatabaseFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;XSOUND_EXPORTS;SX_LIB_NAME="XSOUND";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ImportLibrary>../../../libs64/$(TargetName).lib</ImportLibrary> + <ProgramDatabaseFile>$(ProjectDir)../../../pdb64/$(TargetName).pdb</ProgramDatabaseFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\source\xSound\dllmain.cpp" /> + <ClCompile Include="..\..\..\source\xSound\plugin_main.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundBase.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundEmitter.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundLayer.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundLoader.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundPlayer.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundSystem.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\source\xSound\AudioConverter.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundBase.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundEmitter.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundLayer.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundLoader.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundPlayer.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundSystem.h" /> + <ClInclude Include="..\..\..\source\xSound\SoundTypes.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/proj/xSound/vs2013/xSound.vcxproj.filters b/proj/xSound/vs2013/xSound.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..1694219529c308d88f499888443c3faf4169f419 --- /dev/null +++ b/proj/xSound/vs2013/xSound.vcxproj.filters @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\source\xSound\SoundSystem.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\xSound\dllmain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\xSound\plugin_main.cpp" /> + <ClCompile Include="..\..\..\source\xSound\SoundBase.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\xSound\SoundLayer.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\xSound\SoundPlayer.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\xSound\SoundEmitter.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\xSound\SoundLoader.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\source\xSound\SoundSystem.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\SoundBase.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\SoundLayer.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\SoundPlayer.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\SoundEmitter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\AudioConverter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\SoundLoader.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\xSound\SoundTypes.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/sdks/mital b/sdks/mital index 41da9d03a8f00b8e8aec9f434e9bf9b33e589653..d0cbed91d28e1816044820a77902b37ed33b4596 160000 --- a/sdks/mital +++ b/sdks/mital @@ -1 +1 @@ -Subproject commit 41da9d03a8f00b8e8aec9f434e9bf9b33e589653 +Subproject commit d0cbed91d28e1816044820a77902b37ed33b4596 diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp index 3826ab7d5366efcc526e764a4db09207ef06bf25..ac4ca03a5a0d3e42b65f3ba25949924746f6fe86 100644 --- a/source/anim/DynamicModelProvider.cpp +++ b/source/anim/DynamicModelProvider.cpp @@ -188,8 +188,6 @@ CDynamicModelProvider::~CDynamicModelProvider() mem_release(m_pOpaqueQuery); mem_release(m_pTransparentQuery); mem_release(m_pSelfillumQuery); - mem_release(m_pObjectType); - mem_release(m_pScene); } IGXVertexDeclaration *CDynamicModelProvider::getVertexDeclaration() diff --git a/source/core/ResourceManager.cpp b/source/core/ResourceManager.cpp index 8c2dbfb016ebcb8ea6496a6842d8b20809df669b..8a07980a2eba96de5df742df5e0b379edb79100b 100644 --- a/source/core/ResourceManager.cpp +++ b/source/core/ResourceManager.cpp @@ -11,6 +11,7 @@ #include <xcommon/resource/IXModelProvider.h> #include <xcommon/resource/IXResourceManager.h> #include <xcommon/resource/IXResourceModel.h> +#include <xcommon/IXAudioCodec.h> #endif @@ -65,6 +66,28 @@ CResourceManager::CResourceManager(IXCore *pCore): } } } + + { + IXAudioCodec *pAudioCodec; + UINT ic = 0; + while ((pAudioCodec = (IXAudioCodec*)pPluginManager->getInterface(IXAUDIOCODEC_GUID, ic++))) + { + if (pAudioCodec->getVersion() == IXAUDIOCODEC_VERSION) + { + //LibReport(REPORT_MSG_LEVEL_NOTICE, "Registered sound loader:\n %s\n By %s\n %s\n", pAudioCodec->getDescription(), pAudioCodec->getAuthor(), pAudioCodec->getCopyright()); + + for (UINT i = 0, l = pAudioCodec->getExtCount(); i < l; ++i) + { + AAString sExt; + sExt.setName(pAudioCodec->getExt(i)); + strlwr(const_cast<char*>(sExt.getName())); + m_aSoundExts.push_back({ pAudioCodec->getExt(i), pAudioCodec->getExt(i) }); + LibReport(REPORT_MSG_LEVEL_NOTICE, " Ext: " COLOR_LCYAN "%s" COLOR_RESET ": " COLOR_WHITE "%s" COLOR_RESET "\n", pAudioCodec->getExt(i), pAudioCodec->getExt(i)); + } + LibReport(REPORT_MSG_LEVEL_NOTICE, " \n"); + } + } + } } bool XMETHODCALLTYPE CResourceManager::getModel(const char *szName, IXResourceModel **ppOut, bool bForceReload) @@ -339,7 +362,21 @@ void XMETHODCALLTYPE CResourceManager::addModel(const char *szName, IXResourceMo pResource->setFileName(m_mpModels.TmpNode->Key.c_str()); } +//########################################################################## + +UINT XMETHODCALLTYPE CResourceManager::getSoundSupportedFormats() +{ + return(m_aSoundExts.size()); +} + +const XFormatName* XMETHODCALLTYPE CResourceManager::getSoundSupportedFormat(UINT uIndex) +{ + assert(uIndex < m_aSoundExts.size()); + + return(&m_aSoundExts[uIndex]); +} +//########################################################################## diff --git a/source/core/ResourceManager.h b/source/core/ResourceManager.h index 26da34a11c3afae9a7507bd9cb3046343e5bd92c..de08f5a2960beb18786363ef807387451d05b83d 100644 --- a/source/core/ResourceManager.h +++ b/source/core/ResourceManager.h @@ -54,6 +54,9 @@ public: } } + UINT XMETHODCALLTYPE getSoundSupportedFormats() override; + const XFormatName* XMETHODCALLTYPE getSoundSupportedFormat(UINT uIndex) override; + protected: IXCore *m_pCore; @@ -69,6 +72,8 @@ protected: Array<XFormatName> m_aTextureExts; const char* getExtension(const char *szName); + + Array<XFormatName> m_aSoundExts; }; #endif diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp index f311d9e6ca6622a0f09ba897b1c91654bafab347..bb38523c4041be8ab4366d66a3a01bb3704db9d4 100644 --- a/source/game/GameData.cpp +++ b/source/game/GameData.cpp @@ -1190,8 +1190,10 @@ GameData::~GameData() for(int i = 0; i < MPT_COUNT; ++i) { - // @TODO: SSCore_SndDelete3dInst() - mem_delete_a(m_pidFootstepSound[i]); + int iCount = m_iFootstepSoundCount[i]; + for (int j = 0; j < iCount; ++j) + mem_release(m_aFootstepSound[i][j]); + mem_delete_a(m_aFootstepSound[i]); } } @@ -1401,55 +1403,65 @@ void GameData::playFootstepSound(MTLTYPE_PHYSIC mtl_type, const float3 &f3Pos) { return; } - ID idSound = m_pidFootstepSound[mtl_type][rand() % iCount]; - SSCore_SndInstancePlay3d(idSound, false, false, (float3*)&f3Pos); + /*ID idSound = m_pidFootstepSound[mtl_type][rand() % iCount]; + SSCore_SndInstancePlay3d(idSound, false, false, (float3*)&f3Pos);*/ + IXSoundEmitter *pEmitter = m_aFootstepSound[mtl_type][rand() % iCount]; + if (pEmitter) + pEmitter->play(); } void GameData::loadFoostepsSounds() { Array<const char*> aSounds[MPT_COUNT]; - aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("actor/step/default1.ogg"); - aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("actor/step/default2.ogg"); - aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("actor/step/default3.ogg"); - aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("actor/step/default4.ogg"); + aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("sounds/actor/step/default1.ogg"); + aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("sounds/actor/step/default2.ogg"); + aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("sounds/actor/step/default3.ogg"); + aSounds[MTLTYPE_PHYSIC_CONCRETE].push_back("sounds/actor/step/default4.ogg"); - aSounds[MTLTYPE_PHYSIC_METAL].push_back("actor/step/metal_plate1.ogg"); - aSounds[MTLTYPE_PHYSIC_METAL].push_back("actor/step/metal_plate2.ogg"); - aSounds[MTLTYPE_PHYSIC_METAL].push_back("actor/step/metal_plate3.ogg"); - aSounds[MTLTYPE_PHYSIC_METAL].push_back("actor/step/metal_plate4.ogg"); + aSounds[MTLTYPE_PHYSIC_METAL].push_back("sounds/actor/step/metal_plate1.ogg"); + aSounds[MTLTYPE_PHYSIC_METAL].push_back("sounds/actor/step/metal_plate2.ogg"); + aSounds[MTLTYPE_PHYSIC_METAL].push_back("sounds/actor/step/metal_plate3.ogg"); + aSounds[MTLTYPE_PHYSIC_METAL].push_back("sounds/actor/step/metal_plate4.ogg"); - aSounds[MTLTYPE_PHYSIC_TREE].push_back("actor/step/new_wood1.ogg"); - aSounds[MTLTYPE_PHYSIC_TREE].push_back("actor/step/new_wood2.ogg"); - aSounds[MTLTYPE_PHYSIC_TREE].push_back("actor/step/new_wood3.ogg"); - aSounds[MTLTYPE_PHYSIC_TREE].push_back("actor/step/new_wood4.ogg"); + aSounds[MTLTYPE_PHYSIC_TREE].push_back("sounds/actor/step/new_wood1.ogg"); + aSounds[MTLTYPE_PHYSIC_TREE].push_back("sounds/actor/step/new_wood2.ogg"); + aSounds[MTLTYPE_PHYSIC_TREE].push_back("sounds/actor/step/new_wood3.ogg"); + aSounds[MTLTYPE_PHYSIC_TREE].push_back("sounds/actor/step/new_wood4.ogg"); - aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("actor/step/earth1.ogg"); - aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("actor/step/earth2.ogg"); - aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("actor/step/earth3.ogg"); - aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("actor/step/earth4.ogg"); + aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("sounds/actor/step/earth1.ogg"); + aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("sounds/actor/step/earth2.ogg"); + aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("sounds/actor/step/earth3.ogg"); + aSounds[MTLTYPE_PHYSIC_GROUD_SAND].push_back("sounds/actor/step/earth4.ogg"); - aSounds[MTLTYPE_PHYSIC_WATER].push_back("actor/step/t_water1.ogg"); - aSounds[MTLTYPE_PHYSIC_WATER].push_back("actor/step/t_water2.ogg"); + aSounds[MTLTYPE_PHYSIC_WATER].push_back("sounds/actor/step/t_water1.ogg"); + aSounds[MTLTYPE_PHYSIC_WATER].push_back("sounds/actor/step/t_water2.ogg"); - aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("actor/step/grass1.ogg"); - aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("actor/step/grass2.ogg"); - aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("actor/step/grass3.ogg"); - aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("actor/step/grass4.ogg"); + aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("sounds/actor/step/grass1.ogg"); + aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("sounds/actor/step/grass2.ogg"); + aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("sounds/actor/step/grass3.ogg"); + aSounds[MTLTYPE_PHYSIC_LEAF_GRASS].push_back("sounds/actor/step/grass4.ogg"); //aSounds[MTLTYPE_PHYSIC_GLASS].push_back("actor/step/.ogg"); //aSounds[MTLTYPE_PHYSIC_PLASTIC].push_back("actor/step/.ogg"); //aSounds[MTLTYPE_PHYSIC_FLESH].push_back("actor/step/.ogg"); + IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID)); + IXSoundLayer *pMasterLayer = pSound->findLayer("master"); + + if (!pMasterLayer) + return; + for(int i = 0; i < MPT_COUNT; ++i) { Array<const char*> *paSounds = &aSounds[i]; int jl = paSounds->size(); m_iFootstepSoundCount[i] = jl; - m_pidFootstepSound[i] = jl ? new ID[jl] : NULL; + m_aFootstepSound[i] = (jl ? new IXSoundEmitter*[jl] : NULL); for(int j = 0; j < jl; ++j) { - m_pidFootstepSound[i][j] = SSCore_SndCreate3dInst(paSounds[0][j], SX_SOUND_CHANNEL_GAME, 100); + m_aFootstepSound[i][j] = pMasterLayer->newSoundEmitter(paSounds[0][j], SOUND_DTYPE_3D); + //m_aFootstepSound[i][j] = SSCore_SndCreate3dInst(paSounds[0][j], SX_SOUND_CHANNEL_GAME, 100); } } } diff --git a/source/game/GameData.h b/source/game/GameData.h index 3a858aebeb01d7bde4d052e60d3bd2e80d0d2dc2..af9f47b8620dcc90182420f9613d5d97b358b839 100644 --- a/source/game/GameData.h +++ b/source/game/GameData.h @@ -15,6 +15,7 @@ See the license in LICENSE #include "HUDcontroller.h" #include "GameStateManager.h" #include <light/IXLightSystem.h> +#include <xcommon/IXSoundSystem.h> class GameData { @@ -50,7 +51,8 @@ protected: void loadFoostepsSounds(); - ID *m_pidFootstepSound[MPT_COUNT]; + //ID *m_pidFootstepSound[MPT_COUNT]; + IXSoundEmitter **m_aFootstepSound[MPT_COUNT]; int m_iFootstepSoundCount[MPT_COUNT]; static void ccmd_forward_on(); diff --git a/source/game/SoundPlayer.cpp b/source/game/SoundPlayer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17491fd4a92b613ae4c3d1a46b2112ad277c320e --- /dev/null +++ b/source/game/SoundPlayer.cpp @@ -0,0 +1,47 @@ + +#include "SoundPlayer.h" + +/*! \skydocent sound_player + +*/ + +BEGIN_PROPTABLE(CSoundPlayer) + +DEFINE_FIELD_STRINGFN(m_szPathSound, 0, "file", "Sound file", setSound, EDITOR_SOUND) + +DEFINE_FIELD_FLOAT(m_fDist, 0, "distance", "Hearing distance", EDITOR_TEXTFIELD) + +END_PROPTABLE() + +REGISTER_ENTITY(CSoundPlayer, sound_player); + +//########################################################################## + +CSoundPlayer::CSoundPlayer(CEntityManager *pMgr): + BaseClass(pMgr), + m_pPlayer(NULL) +{ + +} + +void CSoundPlayer::setSound(const char *szSound) +{ + mem_release(m_pPlayer); + IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID)); + IXSoundLayer *pMasterLayer = pSound->findLayer("master"); + m_pPlayer = pMasterLayer->newSoundPlayer(szSound, SOUND_DTYPE_3D); + if (m_pPlayer) + { + m_pPlayer->setLoop(SOUND_LOOP_SIMPLE); + m_pPlayer->play(); + } +} + +void CSoundPlayer::onSync() +{ + if (!m_pPlayer) + return; + + float3 vPos = getPos(); + m_pPlayer->setWorldPos(vPos); +} \ No newline at end of file diff --git a/source/game/SoundPlayer.h b/source/game/SoundPlayer.h new file mode 100644 index 0000000000000000000000000000000000000000..58d463da065e65c05d0d3bd4053c4aeed2fb3744 --- /dev/null +++ b/source/game/SoundPlayer.h @@ -0,0 +1,45 @@ +/***************************************************** +Copyright � DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +/*! + \file + ����� ��������� ������ +*/ +#ifndef __SOUND_PLAYER_H +#define __SOUND_PLAYER_H + +#include "PointEntity.h" +#include <xcommon/IXSoundSystem.h> + + +/*! ����� ��������� ������ + \ingroup cpointentity +*/ +class CSoundPlayer : public CPointEntity +{ + DECLARE_CLASS(CSoundPlayer, CPointEntity); + DECLARE_PROPTABLE(); +public: + //CSoundPlayer() = default; + CSoundPlayer(CEntityManager * pMgr); + + virtual void setSound(const char *szSound); + + void onSync() override; + + void stop(); + + void play(); + +protected: + + IXSoundPlayer *m_pPlayer = NULL; + const char *m_szPathSound = ""; + + float m_fDist = 10.f; +}; + +#endif diff --git a/source/game/proptable.h b/source/game/proptable.h index 4f18c2f55b9fac0c9d8bc3c3e7646d0bcc4acb01..b59a1e2c4c7e75c0cfd95b4736a68d2ce43060a6 100644 --- a/source/game/proptable.h +++ b/source/game/proptable.h @@ -397,6 +397,7 @@ const char * GetEmptyString(); #define EDITOR_YESNO EDITOR_COMBOBOX COMBO_OPTION("Yes", "1") COMBO_OPTION("No", "0") EDITOR_COMBO_END() #define EDITOR_MODEL EDITOR_FILEFIELD FILE_OPTION("Select model", "dse") EDITOR_FILE_END() +#define EDITOR_SOUND EDITOR_FILEFIELD FILE_OPTION("Select sound", "ogg") EDITOR_FILE_END() #define DEFINE_FIELD_STRING(field, flags, keyname, edname, editor) , {propdata_t::ToFieldType<const char* DataClass::*>(&DataClass::field), PDF_STRING, flags, keyname, edname, NULL, editor #define DEFINE_FIELD_VECTOR(field, flags, keyname, edname, editor) , {propdata_t::ToFieldType<float3_t DataClass::*>(&DataClass::field), PDF_VECTOR, flags, keyname, edname, NULL, editor diff --git a/source/oggplugin/AudioCodecOgg.cpp b/source/oggplugin/AudioCodecOgg.cpp index 749bcb6dea315fc820755b76aee69e1542903f8d..8e1085b657a51facec6ec9dc0c7244af54b53239 100644 --- a/source/oggplugin/AudioCodecOgg.cpp +++ b/source/oggplugin/AudioCodecOgg.cpp @@ -3,44 +3,75 @@ //########################################################################## -size_t OggCallbackRead(void *ptr, size_t size, size_t nmemb, void *datasource) +size_t OggCallbackRead(void *pDataDest, size_t size, size_t nmemb, void *pDataFile) { - FILE* f = (FILE*)datasource; - return fread(ptr, 1, size * nmemb, f); + IFile *pFile = (IFile*)pDataFile; + return pFile->readBin(pDataDest, size * nmemb); } -int OggCallbackClose(void* datasource) +//************************************************************************** + +int OggCallbackClose(void *pDataFile) { - FILE* f = (FILE*)datasource; - fclose(f); + IFile *pFile = (IFile*)pDataFile; + //эту функци. вызывает ov_clear, но надо чтобы владалец обьекта сам закрывал файл + //mem_release(pFile); return 0; } -int OggCallbackSeek(void *datasource, ogg_int64_t offset, int whence) +//************************************************************************** + +int OggCallbackSeek(void *pDataFile, ogg_int64_t offset, int whence) { - FILE* f = (FILE*)datasource; + IFile *pFile = (IFile*)pDataFile; switch (whence) { - case SEEK_SET: return fseek(f, offset, SEEK_SET); - case SEEK_CUR: return fseek(f, offset, SEEK_CUR); - case SEEK_END: return fseek(f, offset, SEEK_END); - default: return -1; + case SEEK_SET: + { + if (offset < 0 || offset > pFile->getSize()) + return 1; + pFile->setPos(offset); + return 0; + } + case SEEK_CUR: + { + size_t uPos = pFile->getPos() + offset; + if (uPos < 0 || uPos > pFile->getSize()) + return 1; + + pFile->setPos(uPos); + return 0; + } + case SEEK_END: + { + size_t uPos = pFile->getSize() + offset; + if (uPos < 0 || uPos > pFile->getSize()) + return 1; + + pFile->setPos(uPos); + return 0; + } + default: + return -1; } return 1; } -long OggCallbackTell(void* datasource) +//************************************************************************** + +long OggCallbackTell(void *pDataFile) { - FILE* f = (FILE*)datasource; - return ftell(f); + IFile *pFile = (IFile*)pDataFile; + return pFile->getPos(); } //########################################################################## //########################################################################## //########################################################################## -CAudioCodecOgg::CAudioCodecOgg() +CAudioCodecOgg::CAudioCodecOgg(IFileSystem *pFileSystem) { + m_pFileSystem = pFileSystem; m_oCB.close_func = OggCallbackClose; m_oCB.read_func = OggCallbackRead; m_oCB.seek_func = OggCallbackSeek; @@ -68,9 +99,9 @@ UINT XMETHODCALLTYPE CAudioCodecOgg::getExtCount() const bool XMETHODCALLTYPE CAudioCodecOgg::open(const char *szFile, const char *szArg, IXAudioCodecTarget **ppTarget, bool forSave) { - FILE *pFile = fopen(szFile, (forSave ? "wb" : "rb")); + IFile *pFile = m_pFileSystem->openFile(szFile, (forSave ? FILE_MODE_WRITE : FILE_MODE_READ)); - if (!pFile || !ppTarget) + if (!pFile || !ppTarget || (forSave && (!szArg && strcasecmp(szArg, getFormat()) != 0))) return false; OggVorbis_File *pVoFile = NULL; @@ -126,11 +157,13 @@ CAudioCodecTargetOgg::~CAudioCodecTargetOgg() ov_clear(m_pVoFile); mem_delete(m_pVoFile); } + + mem_release(m_pFile); } //************************************************************************** -void CAudioCodecTargetOgg::init(FILE *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave) +void CAudioCodecTargetOgg::init(IFile *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave) { m_pFile = pFile; m_pVoFile = pVoFile; @@ -156,7 +189,7 @@ int64_t XMETHODCALLTYPE CAudioCodecTargetOgg::getPos() const if (!m_pFile || !m_pVoFile) return 0; - return ov_pcm_tell(m_pVoFile); + return ov_pcm_tell(m_pVoFile)*OGG_BYTES_PER_SAMPLE; } //************************************************************************** @@ -166,7 +199,7 @@ void XMETHODCALLTYPE CAudioCodecTargetOgg::setPos(int64_t iPos) if (!m_pFile || !m_pVoFile) return; - ov_pcm_seek(m_pVoFile, iPos); + ov_pcm_seek(m_pVoFile, iPos / OGG_BYTES_PER_SAMPLE); } //************************************************************************** @@ -251,16 +284,14 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw //инициализация кодировщика (статических данных) с переменным битрейтом (variable bitrate) vorbis_info_init(&oVoInfo); - iRetCode = vorbis_encode_init_vbr(&oVoInfo, pOutDesc->u8Channels, pOutDesc->uSampleRate, 0.1); + if ((iRetCode = vorbis_encode_init_vbr(&oVoInfo, pOutDesc->u8Channels, pOutDesc->uSampleRate, 0.2))) + return false; /* можно заюзать усредненный битрейт (average bitrate): - iRetCode = vorbis_encode_init(&vi,pOutDesc->u8Channels, pOutDesc->uSampleRate,-1,128000,-1); - * но в данной реализации пусть кодировщик сам разбирается :) + iRetCode = vorbis_encode_init(&vi,pOutDesc->u8Channels, pOutDesc->uSampleRate,-1,128000,-1); + но в данной реализации пусть кодировщик сам разбирается :) */ - if(iRetCode) - return false; - //инициализируем комментарий vorbis_comment_init(&oVoComment); vorbis_comment_add_tag(&oVoComment, "ENCODER", "SkyXEngine plugin [class 'codec_ogg']"); @@ -282,39 +313,50 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw //************************************************** //сброс заголовков в логический поток данных - while(!iEndOfStream) + while (ogg_stream_flush(&oOggStream, &oOggPage)) { - iRetCode = ogg_stream_flush(&oOggStream, &oOggPage); - if(iRetCode == 0) - break; - fwrite(oOggPage.header, 1, oOggPage.header_len, m_pFile); - fwrite(oOggPage.body, 1, oOggPage.body_len, m_pFile); + m_pFile->writeBin(oOggPage.header, oOggPage.header_len); + m_pFile->writeBin(oOggPage.body, oOggPage.body_len); } //************************************************** // инициализация семплов + //количество блоков семплов (количество каналов * байт на семпл) int iCountBlocks = uSize/ (pOutDesc->u8BlockAlign); + //по сколько блоков записывать за один раз + int iPartBlocks = 1024; + + //количество уже записанных блоков + int iCountReadedBlocks = 0; + + /*в общем процесс записи сэмлов выглядит как показано в закомментированном коде ниже + но так делать не надо, потому что внутри vorbis_analysis_wrote выделяется память на стеке по общему количеству блоков + это может привести к переполнению стека + */ + /* но разделять на блоки и передавать таким образом данные тоже нельзя + */ /* получаем выделенный массив (по количеству каналов) массивов (по количеству семплов) aaBuffer[iChannel][iSample] */ - float **aaBuffer = vorbis_analysis_buffer(&oVoMainState, iCountBlocks); + /*float **aaBuffer = vorbis_analysis_buffer(&oVoMainState, iCountBlocks); + int iCurrSample = 0; //заполняем выделенный float массив нормализованными данными [-1.0, 1.0] for(int i = 0; i < iCountBlocks ; ++i) { for(int iChannels = 0; iChannels<pOutDesc->u8Channels; ++iChannels) { - int16_t i16Sample = ((int16_t*)pData)[i]; - aaBuffer[iChannels][i]=float(i16Sample)/32768.f; + iCurrSample = i * pOutDesc->u8Channels + iChannels; + int16_t i16Sample = ((int16_t*)pData)[iCurrSample]; + aaBuffer[iChannels][i] = float(i16Sample) / 32768.f; } } //сообщаем кодировщику что поступили данные для записи - vorbis_analysis_wrote(&oVoMainState, iCountBlocks); - + vorbis_analysis_wrote(&oVoMainState, iCountBlocks);*/ //************************************************** // запись семплов @@ -322,34 +364,72 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw //если еще не дошли до конца битового потока, тогда продолжаем запись while(!iEndOfStream) { - /*разбивка несжатых данных на блоки, если не удалось, тогда сообщаем что данных больше не будет - если не сообщить об этом, то не все данные будут записаны, не получится дойти до конца битового потока, потому что запись идет постраничная и последняя неполня страница не будет записана - */ - if(vorbis_analysis_blockout(&oVoMainState, &oVoDataBlock)!=1) - vorbis_analysis_wrote(&oVoMainState, 0); + //количество прочитанных семплов + uint32_t uCountReadedSamples = (iCountReadedBlocks*pOutDesc->u8Channels); + //количество блоков для текущей итерации + int iCurrBlocks = iPartBlocks; + if (iCountBlocks - iCountReadedBlocks < iPartBlocks) + iCurrBlocks = iCountBlocks - iCountReadedBlocks; + + //если есть блоки для записи + if (iCurrBlocks > 0) + { + /* получаем выделенный массив (по количеству каналов) массивов (по количеству семплов) + aaBuffer[iChannel][iSample] + */ + float **aaBuffer = vorbis_analysis_buffer(&oVoMainState, iCurrBlocks); + int iCurrSample = 0; + + //запись блоков + for (int i = 0; i < iCurrBlocks; ++i) + { + for (int iChannels = 0; iChannels < pOutDesc->u8Channels; ++iChannels) + { + iCurrSample = uCountReadedSamples + i * pOutDesc->u8Channels + iChannels; + int16_t i16Sample = ((int16_t*)pData)[iCurrSample]; + aaBuffer[iChannels][i] = float(i16Sample) / 32768.f; + } + } - //поиск режима кодирования и отправка блока на кодировку - vorbis_analysis(&oVoDataBlock, NULL); - vorbis_bitrate_addblock(&oVoDataBlock); + //сообщаем кодировщику что поступили данные для записи + vorbis_analysis_wrote(&oVoMainState, iCurrBlocks); + iCountReadedBlocks += iCurrBlocks; + } + else + { + /* сообщаем что данных больше не будет + если не сообщить об этом, то не все данные будут записаны, не получится дойти до конца битового потока, + потому что запись идет постраничная и последняя неполная страница не будет записана + */ + vorbis_analysis_wrote(&oVoMainState, 0); + } - //получение следующего доступного пакета - while(vorbis_bitrate_flushpacket(&oVoMainState, &oOggPacket)) + while (vorbis_analysis_blockout(&oVoMainState, &oVoDataBlock) == 1) { - //отправка пакета в битовый поток - ogg_stream_packetin(&oOggStream, &oOggPacket); + //поиск режима кодирования и отправка блока на кодировку + vorbis_analysis(&oVoDataBlock, NULL); + vorbis_bitrate_addblock(&oVoDataBlock); - while(!iEndOfStream) + //получение следующего доступного пакета + while (vorbis_bitrate_flushpacket(&oVoMainState, &oOggPacket)) { - //формирование пакетов в страницы и отправка в битовый поток - int result=ogg_stream_pageout(&oOggStream, &oOggPage); - if(result==0) - break; - fwrite(oOggPage.header, 1, oOggPage.header_len, m_pFile); - fwrite(oOggPage.body, 1, oOggPage.body_len, m_pFile); - - //если все записано (находимся в конце битового потока), сообщаем о завершении - if(ogg_page_eos(&oOggPage)) - iEndOfStream=1; + //отправка пакета в битовый поток + ogg_stream_packetin(&oOggStream, &oOggPacket); + + while (!iEndOfStream) + { + //формирование пакетов в страницы и отправка в битовый поток + int result = ogg_stream_pageout(&oOggStream, &oOggPage); + if (result == 0) + break; + + m_pFile->writeBin(oOggPage.header, oOggPage.header_len); + m_pFile->writeBin(oOggPage.body, oOggPage.body_len); + + //если все записано (находимся в конце битового потока), сообщаем о завершении + if (ogg_page_eos(&oOggPage)) + iEndOfStream = 1; + } } } } diff --git a/source/oggplugin/AudioCodecOgg.h b/source/oggplugin/AudioCodecOgg.h index e1c46973dc8d553e8eb411ebcac7674a47666b80..727c5bd697be2c5e0045fb027bbfc23a1771a078 100644 --- a/source/oggplugin/AudioCodecOgg.h +++ b/source/oggplugin/AudioCodecOgg.h @@ -15,16 +15,22 @@ See the license in LICENSE #include <common/string.h> +#include <xcommon/IFileSystem.h> +#include <core/IFile.h> + //! количество байт на семпл #define OGG_BYTES_PER_SAMPLE 2 +//########################################################################## class CAudioCodecOgg: public IXUnknownImplementation<IXAudioCodec> { public: - CAudioCodecOgg(); + CAudioCodecOgg(IFileSystem *pFileSystem); ~CAudioCodecOgg(){} + XIMPLEMENT_VERSION(IXAUDIOCODEC_VERSION); + virtual const char* XMETHODCALLTYPE getFormat() const override; virtual const char* XMETHODCALLTYPE getExt(UINT uIndex=0) const override; virtual UINT XMETHODCALLTYPE getExtCount() const override; @@ -34,6 +40,7 @@ public: protected: ov_callbacks m_oCB; Array<String> m_aExts; + IFileSystem *m_pFileSystem = NULL; }; //########################################################################## @@ -52,9 +59,9 @@ protected: friend CAudioCodecOgg; - void init(FILE *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave); + void init(IFile *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave); - FILE *m_pFile = NULL; + IFile *m_pFile = NULL; OggVorbis_File *m_pVoFile; AudioRawDesc m_oDesc; bool m_forSave = false; diff --git a/source/oggplugin/plugin_main.cpp b/source/oggplugin/plugin_main.cpp index 6b65fafa96b408bee5a3d02d3248278af90b460a..a9943aae09075c421bc7fceb3f7aadaa7d3a0cbe 100644 --- a/source/oggplugin/plugin_main.cpp +++ b/source/oggplugin/plugin_main.cpp @@ -20,6 +20,7 @@ class CAudioCodecOggPlugin: public IXUnknownImplementation<IXPlugin> public: void XMETHODCALLTYPE startup(IXCore *pCore) override { + m_pCore = pCore; } void XMETHODCALLTYPE shutdown() override @@ -47,10 +48,13 @@ public: { if (guid == IXAUDIOCODEC_GUID) { - return(new CAudioCodecOgg()); + return(new CAudioCodecOgg(m_pCore->getFileSystem())); } return(NULL); } + +protected: + IXCore *m_pCore = NULL; }; DECLARE_XPLUGIN(CAudioCodecOggPlugin); diff --git a/source/render/RenderPipeline.cpp b/source/render/RenderPipeline.cpp index 16f67b33b154e589aa280d35c5e7ddafea0d8d79..30bbfdd1dc85cde1b8e4c8b3066e931a2c3349da 100644 --- a/source/render/RenderPipeline.cpp +++ b/source/render/RenderPipeline.cpp @@ -33,6 +33,8 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): {"vTexUV", GXDECLTYPE_FLOAT2, GXDECLUSAGE_TEXCOORD}, {"vNormal", GXDECLTYPE_FLOAT3, GXDECLUSAGE_TEXCOORD1}, {"vPos", GXDECLTYPE_FLOAT4, GXDECLUSAGE_TEXCOORD2}, + {"vTangent", GXDECLTYPE_FLOAT3, GXDECLUSAGE_TEXCOORD3}, + {"vBinormal", GXDECLTYPE_FLOAT3, GXDECLUSAGE_TEXCOORD4}, XVERTEX_OUTPUT_DECL_END() }; XVertexFormatHandler *pVertexFormatSceneGeneric = m_pMaterialSystem->registerVertexFormat("xSceneGeneric", voelGeneric); diff --git a/source/terrax/PropertyWindow.cpp b/source/terrax/PropertyWindow.cpp index 76aa87e87df4ecdd158a8b9bb44fd3f3fb092559..f36b28edfb302a1bb3c03612eb42b2122a897858 100644 --- a/source/terrax/PropertyWindow.cpp +++ b/source/terrax/PropertyWindow.cpp @@ -353,11 +353,28 @@ INT_PTR CALLBACK CPropertyWindow::dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP } else if(!fstrcmp(szCurrentFileType, "sound")) { - szTmp += swprintf(szTmp, L"All supported formats") + 1; + /*szTmp += swprintf(szTmp, L"All supported formats") + 1; szTmp += swprintf(szTmp, L"*.ogg") + 1; szTmp += swprintf(szTmp, L"Ogg Vorbis (*.ogg)") + 1; - szTmp += swprintf(szTmp, L"*.ogg") + 1; + szTmp += swprintf(szTmp, L"*.ogg") + 1;*/ + + auto pMgr = Core_GetIXCore()->getResourceManager(); + UINT uFormatCount = pMgr->getSoundSupportedFormats(); + + szTmp += swprintf(szTmp, L"All supported formats") + 1; + for (UINT i = 0; i < uFormatCount; ++i) + { + auto pFmt = pMgr->getSoundSupportedFormat(i); + szTmp += swprintf(szTmp, L"*.%S;", pFmt->szExtension); + } + szTmp[-1] = 0; + for (UINT i = 0; i < uFormatCount; ++i) + { + auto pFmt = pMgr->getSoundSupportedFormat(i); + szTmp += swprintf(szTmp, L"%S (*.%S)", pFmt->szDescription, pFmt->szExtension) + 1; + szTmp += swprintf(szTmp, L"*.%S", pFmt->szExtension) + 1; + } } else { diff --git a/source/terrax/mainWindow.cpp b/source/terrax/mainWindow.cpp index a7f9dfa4e2c0148f318443efc5db893acc56e728..2c15065db680632eac365235174123d8c5aba314 100644 --- a/source/terrax/mainWindow.cpp +++ b/source/terrax/mainWindow.cpp @@ -2182,6 +2182,10 @@ LRESULT CALLBACK RenderWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP DeleteObject(hcRotate); break; + case WM_SETTITLEASYNC: + SetWindowTextA(hWnd, (LPCSTR)lParam); + break; + default: return DefWindowProc(hWnd, message, wParam, lParam); } @@ -2276,7 +2280,7 @@ void XInitViewportLayout(X_VIEWPORT_LAYOUT layout) break; } - SendMessage(g_hWndMain, WM_COMMAND, MAKEWPARAM(ID_VIEW_AUTOSIZEVIEWS, 0), 0); + PostMessage(g_hWndMain, WM_COMMAND, MAKEWPARAM(ID_VIEW_AUTOSIZEVIEWS, 0), 0); g_xConfig.m_xViewportLayout = layout; SetMenuItemInfoA(g_hMenu, uMenuId, FALSE, &mii); diff --git a/source/terrax/terrax.cpp b/source/terrax/terrax.cpp index c7eb03005ef91db34250c27d11a511b87f480879..88eca8c7a7a4a96170b96d477e33422db4dc64f5 100644 --- a/source/terrax/terrax.cpp +++ b/source/terrax/terrax.cpp @@ -1609,7 +1609,7 @@ bool XIsMouseInSelection(X_WINDOW_POS wnd) void XUpdateWindowTitle() { const char *szLevelName = g_sLevelName.c_str(); - char szCaption[256]; + static char szCaption[256]; bool isDirty = g_pUndoManager->isDirty(); if(szLevelName && szLevelName[0]) { @@ -1619,5 +1619,6 @@ void XUpdateWindowTitle() { sprintf(szCaption, "%s%s | %s", MAIN_WINDOW_TITLE, isDirty ? " - *" : "", SKYXENGINE_VERSION4EDITORS); } - SetWindowText(g_hWndMain, szCaption); + PostMessageA(g_hWndMain, WM_SETTITLEASYNC, 0, (LPARAM)szCaption); + // SetWindowText(g_hWndMain, szCaption); } diff --git a/source/terrax/terrax.h b/source/terrax/terrax.h index f334b9129a266c34266b1ac2e9c7f3835ccd06fa..7d9877817d1627f1ef3ebd2f76c88be708226547 100644 --- a/source/terrax/terrax.h +++ b/source/terrax/terrax.h @@ -26,6 +26,9 @@ #define AB_BUTTON_HEIGHT 40 #define OBJECT_TREE_HEIGHT 300 + +#define WM_SETTITLEASYNC (WM_USER + 1) + #include "Grid.h" enum X_VIEWPORT_LAYOUT diff --git a/source/wavplugin/AudioCodecWave.cpp b/source/wavplugin/AudioCodecWave.cpp index 4bc4229df7fba3e339603b4bc1eacf076107208c..3f4330601577e19fc66dd791319127c25d2d6f98 100644 --- a/source/wavplugin/AudioCodecWave.cpp +++ b/source/wavplugin/AudioCodecWave.cpp @@ -3,16 +3,17 @@ //########################################################################## -CAudioCodecWave::CAudioCodecWave() +CAudioCodecWave::CAudioCodecWave(IFileSystem *pFileSystem) { + m_pFileSystem = pFileSystem; m_aExts.push_back("wav"); } bool XMETHODCALLTYPE CAudioCodecWave::open(const char *szFile, const char *szArg, IXAudioCodecTarget **ppTarget, bool forSave) { - FILE *pFile = fopen(szFile, (forSave ? "wb" : "rb")); + IFile *pFile = m_pFileSystem->openFile(szFile, (forSave ? FILE_MODE_WRITE : FILE_MODE_READ)); - if (!pFile || !ppTarget) + if (!pFile || !ppTarget && (forSave && (!szArg && strcasecmp(szArg, getFormat()) != 0))) return false; AudioRawDesc oDesc; @@ -20,10 +21,10 @@ bool XMETHODCALLTYPE CAudioCodecWave::open(const char *szFile, const char *szArg if(!forSave) { - uint32_t uCurrPos = ftell(pFile); - fseek(pFile, 0, SEEK_SET); - fread(&oHeader, 1, sizeof(CWaveHeader), pFile); - fseek(pFile, 0, uCurrPos); + size_t uCurrPos = pFile->getPos(); + pFile->setPos(0); + pFile->readBin(&oHeader, sizeof(CWaveHeader)); + pFile->setPos(uCurrPos); bool can = memcmp(oHeader.aRiff, "RIFF", 4) == 0 && @@ -33,7 +34,7 @@ bool XMETHODCALLTYPE CAudioCodecWave::open(const char *szFile, const char *szArg if(!can) { - fclose(pFile); + mem_release(pFile); return false; } @@ -87,12 +88,12 @@ UINT XMETHODCALLTYPE CAudioCodecWave::getExtCount() const CAudioCodecTargetWave::~CAudioCodecTargetWave() { - fclose(m_pFile); + mem_release(m_pFile); } //************************************************************************** -void CAudioCodecTargetWave::init(FILE *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave) +void CAudioCodecTargetWave::init(IFile *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave) { m_pFile = pFile; @@ -122,7 +123,7 @@ int64_t XMETHODCALLTYPE CAudioCodecTargetWave::getPos() const if(!m_pFile || m_forSave) return 0; - return ftell(m_pFile) - sizeof(CWaveHeader); + return m_pFile->getPos() - sizeof(CWaveHeader); } //************************************************************************** @@ -132,7 +133,7 @@ void XMETHODCALLTYPE CAudioCodecTargetWave::setPos(int64_t iPos) if(!m_pFile || m_forSave) return; - fseek(m_pFile, sizeof(CWaveHeader) + iPos, SEEK_SET); + m_pFile->setPos(sizeof(CWaveHeader) + iPos); } //************************************************************************** @@ -144,7 +145,7 @@ size_t XMETHODCALLTYPE CAudioCodecTargetWave::decode(int64_t iPos, uint64_t uLen setPos(iPos); - size_t sizeRead = fread(*ppData, 1, uLen, m_pFile); + size_t sizeRead = m_pFile->readBin(*ppData, uLen); return sizeRead; } @@ -156,7 +157,7 @@ bool XMETHODCALLTYPE CAudioCodecTargetWave::encode(IXBuffer *pBufferPCM, AudioRa if (!pBufferPCM || !pOutDesc) return false; - fseek(m_pFile, 0, SEEK_SET); + m_pFile->setPos(0); CWaveHeader oOutHeader; oOutHeader.iSampleRate = pOutDesc->uSampleRate; @@ -173,8 +174,8 @@ bool XMETHODCALLTYPE CAudioCodecTargetWave::encode(IXBuffer *pBufferPCM, AudioRa oOutHeader.i16FormatCode = (pOutDesc->fmtSample > AUDIO_SAMPLE_FMT_SINT32 ? WAVE_FORMAT_PCM_FLOAT : WAVE_FORMAT_PCM_INT); oOutHeader.uFormatChunkSize = 16; - fwrite(&oOutHeader, sizeof(oOutHeader), 1, m_pFile); - fwrite(pBufferPCM->get(), 1, pBufferPCM->size(), m_pFile); + m_pFile->writeBin(&oOutHeader, sizeof(oOutHeader)); + m_pFile->writeBin(pBufferPCM->get(), pBufferPCM->size()); return true; } diff --git a/source/wavplugin/AudioCodecWave.h b/source/wavplugin/AudioCodecWave.h index 8dbc13d68bf743b110dd11dc0514cead3bd2fd82..b608972ed059dff44c8b350bcca48584ab30075b 100644 --- a/source/wavplugin/AudioCodecWave.h +++ b/source/wavplugin/AudioCodecWave.h @@ -9,6 +9,8 @@ See the license in LICENSE #include <xcommon/IXAudioCodec.h> #include <common/string.h> +#include <xcommon/IFileSystem.h> +#include <core/IFile.h> //########################################################################## @@ -40,7 +42,9 @@ struct CWaveHeader class CAudioCodecWave: public IXUnknownImplementation<IXAudioCodec> { public: - CAudioCodecWave(); + CAudioCodecWave(IFileSystem *pFileSystem); + + XIMPLEMENT_VERSION(IXAUDIOCODEC_VERSION); virtual const char* XMETHODCALLTYPE getFormat() const override; virtual const char* XMETHODCALLTYPE getExt(UINT uIndex=0) const override; @@ -50,6 +54,7 @@ public: protected: Array<String> m_aExts; + IFileSystem *m_pFileSystem = NULL; }; //########################################################################## @@ -68,9 +73,9 @@ protected: friend CAudioCodecWave; - void init(FILE *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave); + void init(IFile *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave); - FILE *m_pFile = NULL; + IFile *m_pFile = NULL; CWaveHeader m_oHeader; AudioRawDesc m_oDesc; bool m_forSave = false; diff --git a/source/wavplugin/plugin_main.cpp b/source/wavplugin/plugin_main.cpp index aa4a37729f84118137101dc2b8ba72f703eaa5fe..67f4c9a1b1749607d9dfc58694668f11eb3fab15 100644 --- a/source/wavplugin/plugin_main.cpp +++ b/source/wavplugin/plugin_main.cpp @@ -14,6 +14,7 @@ class CAudioCodecWav: public IXUnknownImplementation<IXPlugin> public: void XMETHODCALLTYPE startup(IXCore *pCore) override { + m_pCore = pCore; } void XMETHODCALLTYPE shutdown() override @@ -41,10 +42,13 @@ public: { if (guid == IXAUDIOCODEC_GUID) { - return(new CAudioCodecWave()); + return(new CAudioCodecWave(m_pCore->getFileSystem())); } return(NULL); } + +protected: + IXCore *m_pCore = NULL; }; DECLARE_XPLUGIN(CAudioCodecWav); diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp index a562c741f329795b40ab4be4aad3cf14c7f70071..2984a6709e3ea16b62c748c13f7668dc106aae79 100644 --- a/source/xEngine/Engine.cpp +++ b/source/xEngine/Engine.cpp @@ -6,6 +6,8 @@ #include "SkyXEngine.h" +#include <xcommon/IXSoundSystem.h> + #ifdef _DEBUG # pragma comment(lib, "sxcore_d.lib") #else @@ -121,6 +123,7 @@ CEngine::CEngine(int argc, char **argv, const char *szName) INIT_OUTPUT_STREAM(m_pCore); LibReport(REPORT_MSG_LEVEL_NOTICE, "LIB core initialized\n"); + m_pObserverChangedEventChannel = m_pCore->getEventChannel<XEventObserverChanged>(EVENT_OBSERVER_CHANGED_GUID); Core_0RegisterCVarString("engine_version", SKYXENGINE_VERSION, "Текущая версия движка", FCVAR_READONLY); @@ -159,6 +162,49 @@ bool XMETHODCALLTYPE CEngine::initGraphics(XWINDOW_OS_HANDLE hWindow, IXEngineCa SSInput_0Create("sxinput", (HWND)hWindow, false); LibReport(REPORT_MSG_LEVEL_NOTICE, "LIB input initialized\n"); + + + // init sound + AudioRawDesc oAudioDesc; + oAudioDesc.u8Channels = 2; + oAudioDesc.fmtSample = AUDIO_SAMPLE_FMT_SINT16; + oAudioDesc.uSampleRate = 44100; + oAudioDesc.calc(); + + IXSoundSystem *pSound = (IXSoundSystem*)(m_pCore->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID)); + IXSoundLayer *pMasterLayer = pSound->createMasterLayer(&oAudioDesc, "master"); + pMasterLayer->play(true); + /*IXSoundPlayer *pPlayer = pMasterLayer->newSoundPlayer("sounds/guitar_10.ogg", SOUND_DTYPE_3D); + pPlayer->setWorldPos(float3(-11.084, 0.435, -18.707)); + pPlayer->setLoop(SOUND_LOOP_SIMPLE); + pPlayer->play();*/ + /*IXSoundEmitter *pEmitter = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_2D); + //pEmitter->play(); + + IXSoundEmitter *pEmitter2 = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_2D); + //pEmitter2->play(); + + while (1) + { + if (GetAsyncKeyState('I')) + { + pEmitter2->play(); + Sleep(100); + } + + if (GetAsyncKeyState('Q')) + pMasterLayer->play(false); + + if (GetAsyncKeyState('W')) + pMasterLayer->play(true); + + float3 v; + pSound->update(v,v,v); + }*/ + LibReport(REPORT_MSG_LEVEL_NOTICE, "LIB sound initialized\n"); + + + // init graphics Core_0RegisterCVarInt("r_win_width", 800, "Размер окна по горизонтали (в пикселях)", FCVAR_NOTIFY_OLD); Core_0RegisterCVarInt("r_win_height", 600, "Размер окна по вертикали (в пикселях)", FCVAR_NOTIFY_OLD); @@ -198,6 +244,10 @@ bool XMETHODCALLTYPE CEngine::initGraphics(XWINDOW_OS_HANDLE hWindow, IXEngineCa LibReport(REPORT_MSG_LEVEL_NOTICE, "LIB render initialized\n"); + + + + // init game SGame_0Create((HWND)hWindow, true); LibReport(REPORT_MSG_LEVEL_NOTICE, "LIB game initialized\n"); @@ -347,9 +397,14 @@ bool CEngine::runFrame() if(pRenderContext) { - SRender_SetCamera(m_pCallback->getCameraForFrame()); + ICamera *pCamera = m_pCallback->getCameraForFrame(); + SRender_SetCamera(pCamera); SRender_UpdateView(); + XEventObserverChanged ev; + ev.pCamera = pCamera; + m_pObserverChangedEventChannel->broadcastEvent(&ev); + IXRenderPipeline *pRenderPipeline; m_pCore->getRenderPipeline(&pRenderPipeline); diff --git a/source/xEngine/Engine.h b/source/xEngine/Engine.h index 1333bed8601f2f4aa846bdbd500203d156a1ef9f..e865577703204300b148985c086e9344be4818fc 100644 --- a/source/xEngine/Engine.h +++ b/source/xEngine/Engine.h @@ -55,6 +55,8 @@ protected: IXUI *m_pXUI = NULL; + IEventChannel<XEventObserverChanged> *m_pObserverChangedEventChannel = NULL; + #ifdef USE_BREAKPAD google_breakpad::ExceptionHandler *m_pBreakpadHandler = NULL; #endif diff --git a/source/xSound/AudioConverter.h b/source/xSound/AudioConverter.h new file mode 100644 index 0000000000000000000000000000000000000000..1284fb95bc4563cc1452fa2829742fc1c4a32a6f --- /dev/null +++ b/source/xSound/AudioConverter.h @@ -0,0 +1,165 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __AUDIOCONVERTER_H +#define __AUDIOCONVERTER_H + +#include "SoundTypes.h" + +#include <mital_fn.h> + +//########################################################################## + +inline bool AudioResampling(void *pIn, AudioRawDesc *pInDesc, IXBuffer *pOut, AudioRawDesc *pToDesc) +{ + if (pToDesc->uSampleRate == pInDesc->uSampleRate) + return false; + + /*pOut->alloc(pInDesc->uSize); + memcpy(pOut->get(), pIn, pInDesc->uSize); + return true;*/ + + + BYTE *pSrcData = 0; + + if (pOut->size() > 0) + pSrcData = pOut->get(); + else + pSrcData = (BYTE*)pIn; + + int iCountElem = pInDesc->uSize / AudioGetFormatBytes(pInDesc->fmtSample); + double fCoef = double(pToDesc->uSampleRate) / double(pInDesc->uSampleRate); + int iNewCountElem = (int)ceil(double(iCountElem) * fCoef); + + uint32_t uSize = AudioGetFormatBytes(pInDesc->fmtSample) * iNewCountElem; + BYTE *pDestData = new BYTE[uSize]; + + //считаем коэффициент добавления на каждом семпле + double fAdd = double(iCountElem) / double(iNewCountElem); + + //проход по каналам + for (auto iChannels = 0u; iChannels < pInDesc->u8Channels; ++iChannels) + { + int iCurrNewpos = 0; + int iLast = 0; + uint32_t iKey; + + //проход по количеству семплов в каждом канале + for (auto i = 0, il = iNewCountElem / pInDesc->u8Channels; i < il; ++i) + { + //текущая позиция до которой надо дойти в исходном массиве + int iCurr = (int)ceil(fAdd*((i + 1) * pInDesc->u8Channels)); + + //сколько элементов из исходного массива надо смешать + int iCount = (int)max(iCurr - iLast, (int)max(fAdd, 1.0)); + + double fCountMixed = 0; + + //берем данные из исходного массива и смешиваем + for (auto k = 0; k < iCount; ++k) + { + iKey = iChannels + ((iLast + k) / pInDesc->u8Channels) * pInDesc->u8Channels; + iKey = clamp<int>(iKey, 0, iCountElem - 1); + + double fOrigin = RawDataRead(pSrcData, iKey, pInDesc->fmtSample); + fCountMixed += fOrigin; + } + + //записываем микс в целевой массив + iCurrNewpos = iChannels + i * pInDesc->u8Channels; + RawDataWrite(pDestData, iCurrNewpos, pInDesc->fmtSample, (fCountMixed / double(iCount))); + + //запоминаем до куда дошли в этой итреации + iLast = iCurr; + } + + int iSub = iCountElem - iLast; + int iSub3 = (int)(iNewCountElem * fAdd); + int qwerty = 0; + } + + int qwerty = 0; + + if (pOut->size() > 0) + pOut->free(); + + pOut->alloc(uSize); + memcpy(pOut->get(), pDestData, uSize); + + mem_delete_a(pDestData); + + return true; +} + +//************************************************************************** + +inline bool AudioRechannels(void *pIn, AudioRawDesc *pInDesc, IXBuffer *pOut, AudioRawDesc *pToDesc) +{ + return false; + /*BYTE *pSrcData = 0; + + if (pOut->size() > 0) + pSrcData = pOut->get(); + else + pSrcData = (BYTE*)pIn; + + uint32_t uSize = 0; + + if (pInDesc->u8Channels )*/ +} + +//************************************************************************** + +inline bool AudioReformat(void *pIn, AudioRawDesc *pInDesc, IXBuffer *pOut, AudioRawDesc *pToDesc) +{ + if (pInDesc->fmtSample == pToDesc->fmtSample) + return false; + + BYTE *pSrcData = 0; + + if (pOut->size() > 0) + pSrcData = pOut->get(); + else + pSrcData = (BYTE*)pIn; + + uint32_t uCountElem = (pInDesc->uSize / AudioGetFormatBytes(pInDesc->fmtSample)); + uint32_t uSize = AudioGetFormatBytes(pToDesc->fmtSample) * uCountElem; + BYTE *pDestData = new BYTE[uSize]; + + for (auto i = 0u; i < uCountElem; ++i) + { + double fSample = RawDataRead(pSrcData, i, pInDesc->fmtSample); + RawDataWrite(pDestData, i, pToDesc->fmtSample, fSample); + } + + if (pOut->size() > 0) + pOut->free(); + + pOut->alloc(uSize); + memcpy(pOut->get(), pDestData, uSize); + + mem_delete_a(pDestData); + + return true; +} + +//************************************************************************** + +inline bool AudioConverter(void *pIn, AudioRawDesc *pInDesc, IXBuffer *pOut, AudioRawDesc *pToDesc) +{ + if (pInDesc->uSampleRate != pToDesc->uSampleRate) + AudioResampling(pIn, pInDesc, pOut, pToDesc); + + if (pInDesc->u8Channels != pToDesc->u8Channels && pToDesc->u8Channels <= 2 && pToDesc->u8Channels >= 1) + AudioRechannels(pIn, pInDesc, pOut, pToDesc); + + if (pInDesc->fmtSample != pToDesc->fmtSample) + AudioReformat(pIn, pInDesc, pOut, pToDesc); + + return true; +} + +#endif \ No newline at end of file diff --git a/source/xSound/SoundBase.cpp b/source/xSound/SoundBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8b28f7f1664347d22e4ad17e3a6e64b760c913f6 --- /dev/null +++ b/source/xSound/SoundBase.cpp @@ -0,0 +1,49 @@ + +#include "SoundBase.h" + +//########################################################################## + +SOUND_DTYPE XMETHODCALLTYPE CSoundBase::getType() +{ + return m_dtype; +} + +void XMETHODCALLTYPE CSoundBase::setVolume(float fVolume) +{ + m_fVolume = fVolume; +} + +float XMETHODCALLTYPE CSoundBase::getVolume() const +{ + return m_fVolume; +} + +void XMETHODCALLTYPE CSoundBase::setPan(float fPan) +{ + m_fPan = fPan; +} + +float XMETHODCALLTYPE CSoundBase::getPan() const +{ + return m_fPan; +} + +const float3& XMETHODCALLTYPE CSoundBase::getWorldPos() const +{ + return m_vWorldPos; +} + +void XMETHODCALLTYPE CSoundBase::setWorldPos(const float3 &vPos) +{ + m_vWorldPos = vPos; +} + +float XMETHODCALLTYPE CSoundBase::getDistance() const +{ + return m_fDist; +} + +void XMETHODCALLTYPE CSoundBase::setDistance(float fDist) +{ + m_fDist = fDist; +} diff --git a/source/xSound/SoundBase.h b/source/xSound/SoundBase.h new file mode 100644 index 0000000000000000000000000000000000000000..b6de20455067cc5a644c4d349da116808d2e05ca --- /dev/null +++ b/source/xSound/SoundBase.h @@ -0,0 +1,77 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDBASE_H +#define __SOUNDBASE_H + +#include <common/types.h> +#include <common/math.h> +#include <common/string.h> +#include <xcommon/IXSoundSystem.h> +#include <mital.h> + +#include "SoundTypes.h" + +//########################################################################## + +class CSoundBase: public IXUnknownVirtualImplementation<IXSoundBase> +{ +public: + + SX_ALIGNED_OP_MEM + + virtual SOUND_DTYPE XMETHODCALLTYPE getType() final; + + virtual void XMETHODCALLTYPE setVolume(float fVolume) final; + virtual float XMETHODCALLTYPE getVolume() const final; + + virtual void XMETHODCALLTYPE setPan(float fPan) final; + virtual float XMETHODCALLTYPE getPan() const final; + + virtual const float3& XMETHODCALLTYPE getWorldPos() const final; + virtual void XMETHODCALLTYPE setWorldPos(const float3 &vPos) final; + + virtual float XMETHODCALLTYPE getDistance() const final; + virtual void XMETHODCALLTYPE setDistance(float fDist) final; + +protected: + + friend CSoundLayer; + + void update(); + + bool create(SOUND_DTYPE type, const char *szName, CSoundLayer *pLayer, CSoundSystem *pSoundSystem); + + //************************************************************************ + + float m_fVolume = 1.f; + float m_fPan = 0.f; + + //! аудио буфер + //IAudioBuffer *m_pAB = NULL; + + //! дистанция слышимости + float m_fDist = 10.f; + + //! мировая позиция звука + float3 m_vWorldPos; + + //! тип звука + SOUND_DTYPE m_dtype = SOUND_DTYPE_2D; + + //! состояние проигрывания + SOUND_STATE m_state = SOUND_STATE_STOP; + + //! строковый идентификатор звука + String m_sName = ""; + + //! слой владелец + CSoundLayer *m_pLayer = NULL; + + //CSoundSystem *m_pSoundSystem = NULL; +}; + +#endif diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1536107900c2500a040da7656b8a81894faee83d --- /dev/null +++ b/source/xSound/SoundEmitter.cpp @@ -0,0 +1,133 @@ + +#include "SoundEmitter.h" + +#include "SoundLoader.h" +#include "SoundLayer.h" + +//########################################################################## + +CSoundEmitter::~CSoundEmitter() +{ + m_pLayer->delSndEmitter(this); + +} + +//************************************************************************** + +CSoundEmitter* CSoundEmitter::newInstance() +{ + CSoundEmitter *pEmitter = new CSoundEmitter(); + + pEmitter->m_aInstances[0].pAB = m_aInstances[0].pAB->newInstance(); + pEmitter->m_dtype = this->m_dtype; + pEmitter->m_state = SOUND_STATE_STOP; + pEmitter->m_sName = this->m_sName; + pEmitter->m_pLayer = this->m_pLayer; + pEmitter->m_fDist = this->m_fDist; + pEmitter->m_vWorldPos = this->m_vWorldPos; + return pEmitter; +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundEmitter::play() +{ + //если родительский слой не проигрывается, тогда не запускаем проигрывание + if (!m_pLayer->isPlaying()) + return; + + float3 vPos, vLook, vUp; + m_pLayer->getObserverParam(&vPos, &vLook, &vUp); + + IAudioBuffer *pAB = NULL; + + //проход по массиву инстансов звука, если есть первый попавшийся не проигрываемые тогда его проигрываем + for (int i = 0, il = m_aInstances.size(); i<il; ++i) + { + if (!(m_aInstances[i].pAB->isPlaying())) + { + pAB = m_aInstances[i].pAB; + continue; + } + } + + if (!pAB) + { + //если пришли сюда, значит нет свободных инстансов, создаем новый и проигрыаем + IAudioBuffer *pInst = m_aInstances[0].pAB->newInstance(); + pAB = pInst; + m_aInstances.push_back(pInst); + } + + Com3D(pAB, m_fDist, m_vWorldPos, vPos, vLook, vUp); + pAB->play(true); +} + +//************************************************************************** + +void CSoundEmitter::resume() +{ + //если инстансы проигрывались тогда включаем проигрывание + for (int i = 0, il = m_aInstances.size(); i < il; ++i) + { + if(m_aInstances[i].isPlaying) + m_aInstances[i].pAB->play(true); + } +} + +void CSoundEmitter::pause() +{ + //записываем состояния инстансов и останавливаем + for (int i = 0, il = m_aInstances.size(); i < il; ++i) + { + m_aInstances[i].isPlaying = m_aInstances[i].pAB->isPlaying(); + m_aInstances[i].pAB->play(false); + } +} + +//************************************************************************** + +bool CSoundEmitter::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype) +{ + if (!pCodecTarget || !pLayer) + return false; + + m_dtype = dtype; + AudioRawDesc oDesc; + pCodecTarget->getDesc(&oDesc); + m_pLayer = pLayer; + + IAudioBuffer *pAB = pLayer->createAudioBuffer(AB_TYPE_SECOND, &oDesc); + BYTE *pData = new BYTE[oDesc.uSize]; + pCodecTarget->decode(0, oDesc.uSize, (void**)&pData); + + BYTE *pData2; + pAB->lock(AB_LOCK_WRITE, (void**)&pData2); + memcpy(pData2, pData, oDesc.uSize); + pAB->unlock(); + + mem_delete_a(pData); + mem_release(pCodecTarget); + + pAB->setLoop(AB_LOOP_NONE); + + m_aInstances.push_back(Instance(pAB)); + + return true; +} + +//########################################################################## + +void CSoundEmitter::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) +{ + if (m_dtype == SOUND_DTYPE_2D) + return; + + for (int i = 0, il = m_aInstances.size(); i < il; ++i) + { + if (m_aInstances[i].pAB->isPlaying()) + { + Com3D(m_aInstances[i].pAB, m_fDist, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp); + } + } +} \ No newline at end of file diff --git a/source/xSound/SoundEmitter.h b/source/xSound/SoundEmitter.h new file mode 100644 index 0000000000000000000000000000000000000000..318fe788508b13b01c80c87f6692a9f113c285e8 --- /dev/null +++ b/source/xSound/SoundEmitter.h @@ -0,0 +1,55 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDEMITTER_H +#define __SOUNDEMITTER_H + +#include <xcommon/IXSoundSystem.h> +#include "SoundBase.h" +#include <mital.h> + +#include "SoundTypes.h" +#include "SoundSystem.h" + +//########################################################################## + +class CSoundEmitter : public CSoundBase, public virtual IXSoundEmitter +{ +public: + ~CSoundEmitter(); + + //! создание нового инстанса CSoundEmitter + CSoundEmitter* newInstance(); + + virtual void XMETHODCALLTYPE play() override; + + //! продолжить проигрывание инстансов, если они проигрывались + void resume(); + + //! остановка проигрывания + void pause(); + + void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp); + +protected: + + friend CSoundLayer; + + bool create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype); + + struct Instance + { + Instance() = default; + Instance(IAudioBuffer *pBuffer) { pAB = pBuffer; } + ~Instance() { mem_release(pAB); } + IAudioBuffer *pAB = NULL; + bool isPlaying = false; + }; + + Array<Instance> m_aInstances; +}; + +#endif diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88ef9d7594ccbcbd6537ffdc423c026a6cd1b164 --- /dev/null +++ b/source/xSound/SoundLayer.cpp @@ -0,0 +1,320 @@ + +#include "SoundLayer.h" + +#include "SoundEmitter.h" +#include "SoundPlayer.h" +#include "SoundSystem.h" + +//########################################################################## + +CSoundLayer::~CSoundLayer() +{ + if (m_pParent) + m_pParent->delLayer(this); + + for (maplayer::Iterator i = m_mapLayers.begin(); i; i++) + { + mem_release(m_mapLayers[i.first]); + m_mapLayers.erase(i.first); + } + + for (mapsoundplayer::Iterator i = m_mapSndPlayers.begin(); i; i++) + { + mem_release(m_mapSndPlayers[i.first]); + m_mapSndPlayers.erase(i.first); + } + + int iCount0 = m_mapSndEmitters.Size(); + for (mapsoundemitter::Iterator i = m_mapSndEmitters.begin(); i; i++) + { + mem_release(m_mapSndEmitters[i.first]); + m_mapSndEmitters.erase(i.first); + } + + mem_release_del(m_pPrimaryBuffer); +} + +//************************************************************************** + +bool CSoundLayer::init(CSoundSystem *pSoundSystem, CSoundLayer *pParent, const AudioRawDesc *pDesc, const char *szName) +{ + if (!pDesc || !pSoundSystem) + return false; + + if (m_mapLayers.KeyExists(szName)) + { + return false; + } + + AudioRawDesc oDesc = *pDesc; + oDesc.uSize = 0; + + if (pParent == NULL) + m_pPrimaryBuffer = pSoundSystem->createMasterBuffer(&oDesc); + else + m_pPrimaryBuffer = dynamic_cast<IAudioBufferEx*>(createAudioBuffer(AB_TYPE_PRIMARY, &oDesc)); + + m_sName = szName; + m_pParent = pParent; + m_pSoundSystem = pSoundSystem; + + return true; +} + +//************************************************************************** + +void CSoundLayer::addLayer(CSoundLayer *pLayer, const char *szName) +{ + m_mapLayers[szName] = pLayer; +} + +void CSoundLayer::delLayer(const CSoundLayer *pLayer) +{ + for (maplayer::Iterator i = m_mapLayers.begin(); i; i++) + { + if (m_mapLayers[i.first] == pLayer) + { + m_mapLayers.erase(i.first); + break; + } + } +} + +//************************************************************************** + +void CSoundLayer::addSndPlayer(CSoundPlayer *pSndPlayer, const char *szName) +{ + m_mapSndPlayers[szName] = pSndPlayer; +} + +void CSoundLayer::delSndPlayer(const CSoundPlayer *pSndPlayer) +{ + for (mapsoundplayer::Iterator i = m_mapSndPlayers.begin(); i; i++) + { + if (m_mapSndPlayers[i.first] == pSndPlayer) + { + m_mapSndPlayers[i.first] = NULL; + m_mapSndPlayers.erase(i.first); + break; + } + } +} + +//************************************************************************** + +void CSoundLayer::addSndEmitter(CSoundEmitter *pSndEmitter, const char *szName) +{ + m_mapSndEmitters[szName] = pSndEmitter; +} + +void CSoundLayer::delSndEmitter(const CSoundEmitter *pSndEmitter) +{ + int iCount0 = m_mapSndEmitters.Size(); + for (mapsoundemitter::Iterator i = m_mapSndEmitters.begin(); i; i++) + { + if (m_mapSndEmitters[i.first] == pSndEmitter) + { + m_mapSndEmitters[i.first] = NULL; + m_mapSndEmitters.erase(i.first); + break; + } + } + int iCount1 = m_mapSndEmitters.Size(); + int qwerty = 0; +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundLayer::getDesc(AudioRawDesc *pDesc) const +{ + if (!m_pPrimaryBuffer) + return; + + m_pPrimaryBuffer->getDesc(pDesc); +} + +//************************************************************************** + +const char* XMETHODCALLTYPE CSoundLayer::getName() const +{ + return m_sName.c_str(); +} + +//************************************************************************** + +IXSoundLayer* XMETHODCALLTYPE CSoundLayer::findLayer(const char *szName) +{ + if (!szName) + return NULL; + + if (strcasecmp(this->getName(), szName) == 0) + return this; + + IXSoundLayer *pFound = NULL; + + for (maplayer::Iterator i = m_mapLayers.begin(); i; i++) + { + if ((pFound = m_mapLayers[i.first]->findLayer(szName))) + break; + } + + return pFound; +} + +//************************************************************************** + +uint32_t CSoundLayer::getStreamChunkSize(AudioRawDesc *pDesc) const +{ + return m_pPrimaryBuffer->getStreamChunkSize(pDesc); +} + +IAudioBuffer* CSoundLayer::createAudioBuffer(AB_TYPE type, const AudioRawDesc *pDesc) +{ + return m_pPrimaryBuffer->createAudioBuffer(type, pDesc); +} + +//************************************************************************** + +IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const AudioRawDesc *pDesc, const char *szName) +{ + if (!pDesc) + return NULL; + + if (!matchPrimaryLayer(pDesc)) + return NULL; + + CSoundLayer *pLayer = new CSoundLayer(); + pLayer->init(m_pSoundSystem, this, pDesc, szName); + + addLayer(pLayer, szName); + + return pLayer; +} + +IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName, SOUND_DTYPE dtype) +{ + if (!szName) + return NULL; + + CSoundEmitter *pEmitter = NULL; + + if (m_mapSndEmitters.KeyExists(szName)) + { + CSoundEmitter *pEmitterOrigin = m_mapSndEmitters[szName]; + pEmitter = pEmitterOrigin->newInstance(); + } + else + { + IXAudioCodecTarget *pCodecTarget = m_pSoundSystem->getCodecTarget(szName); + if (!pCodecTarget) + return NULL; + + pEmitter = new CSoundEmitter(); + pEmitter->create(this, pCodecTarget, dtype); + } + + addSndEmitter(pEmitter, szName); + + return pEmitter; +} + +IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, SOUND_DTYPE dtype) +{ + if (!szName) + return NULL; + + CSoundPlayer *pPlayer = NULL; + + if (m_mapSndPlayers.KeyExists(szName)) + { + if (m_mapSndPlayers[szName]) + pPlayer = m_mapSndPlayers[szName]; + //return pPlayer->newInstance(); + } + else + { + IXAudioCodecTarget *pCodecTarget = m_pSoundSystem->getCodecTarget(szName); + if (!pCodecTarget) + return NULL; + + pPlayer = new CSoundPlayer(); + pPlayer->create(this, pCodecTarget, dtype); + } + + addSndPlayer(pPlayer, szName); + + return pPlayer; +} + +//########################################################################## + +void XMETHODCALLTYPE CSoundLayer::play(bool canPlay) +{ + if (m_isPlaying == canPlay || (m_pParent && !m_pParent->isPlaying() && canPlay)) + return; + + m_isPlaying = canPlay; + + for (maplayer::Iterator i = m_mapLayers.begin(); i; i++) + m_mapLayers[i.first]->play(canPlay); + + for (mapsoundplayer::Iterator i = m_mapSndPlayers.begin(); i; i++) + { + if (canPlay) + m_mapSndPlayers[i.first]->resume(); + else + m_mapSndPlayers[i.first]->pause(); + } + + for (mapsoundemitter::Iterator i = m_mapSndEmitters.begin(); i; i++) + { + if (canPlay) + m_mapSndEmitters[i.first]->resume(); + else + m_mapSndEmitters[i.first]->pause(); + } + + m_pPrimaryBuffer->play(canPlay); +} + +bool XMETHODCALLTYPE CSoundLayer::isPlaying() const +{ + return m_isPlaying; +} + +void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) +{ + for (maplayer::Iterator i = m_mapLayers.begin(); i; i++) + { + if (m_mapLayers[i.first]) + m_mapLayers[i.first]->update(vListenerPos, vListenerDir, vListenerUp); + } + + for (mapsoundplayer::Iterator i = m_mapSndPlayers.begin(); i; i++) + { + if (m_mapSndPlayers[i.first]) + m_mapSndPlayers[i.first]->update(vListenerPos, vListenerDir, vListenerUp); + } + + for (mapsoundemitter::Iterator i = m_mapSndEmitters.begin(); i; i++) + { + if (m_mapSndEmitters[i.first]) + m_mapSndEmitters[i.first]->update(vListenerPos, vListenerDir, vListenerUp); + } +} + +void CSoundLayer::getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp) +{ + m_pSoundSystem->getObserverParam(pPos, pLook, pUp); +} + +bool CSoundLayer::matchPrimaryLayer(const AudioRawDesc *pDesc) +{ + if (!pDesc || !m_pPrimaryBuffer) + return false; + + AudioRawDesc oPrimaryDesc; + m_pPrimaryBuffer->getDesc(&oPrimaryDesc); + + return (oPrimaryDesc.uSampleRate == pDesc->uSampleRate); +} diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h new file mode 100644 index 0000000000000000000000000000000000000000..06b901608f63450394188ee5cfb8fe29ea765f62 --- /dev/null +++ b/source/xSound/SoundLayer.h @@ -0,0 +1,92 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDLAYER_H +#define __SOUNDLAYER_H + +#include <common/assotiativearray.h> +#include <xcommon/IXSoundSystem.h> +#include "SoundBase.h" +#include <mital.h> + +#include "SoundTypes.h" + +//########################################################################## + +class CSoundLayer: public IXUnknownImplementation<IXSoundLayer> +{ +public: + + ~CSoundLayer(); + + virtual void XMETHODCALLTYPE play(bool canPlay) override; + virtual bool XMETHODCALLTYPE isPlaying() const override; + virtual const char* XMETHODCALLTYPE getName() const override; + + virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) override; + + virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const AudioRawDesc *pDesc, const char *szName) override; + virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_DTYPE dtype) override; + virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_DTYPE dtype) override; + + virtual void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const override; + + uint32_t getStreamChunkSize(AudioRawDesc *pDesc) const; + IAudioBuffer* createAudioBuffer(AB_TYPE type, const AudioRawDesc *pDesc); + + void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp); + + void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp); + +protected: + + friend CSoundSystem; + friend CSoundPlayer; + friend CSoundEmitter; + + bool init(CSoundSystem *pSoundSystem, CSoundLayer *pParent, const AudioRawDesc *pDesc, const char *szName); + + //************************************************************************ + + void addLayer(CSoundLayer *pLayer, const char *szName); + void delLayer(const CSoundLayer *pLayer); + + void addSndPlayer(CSoundPlayer *pSndPlayer, const char *szName); + void delSndPlayer(const CSoundPlayer *pSndPlayer); + + void addSndEmitter(CSoundEmitter *pSndEmitter, const char *szName); + void delSndEmitter(const CSoundEmitter *pSndEmitter); + + //************************************************************************ + + //! соответствует ли описание (его критические элементы) аудио буфера первичному буферу + bool matchPrimaryLayer(const AudioRawDesc *pDesc); + + void setStateLayers(SOUND_STATE state); + void setStateSounds(SOUND_STATE state); + + SOUND_STATE m_state = SOUND_STATE_STOP; + + bool m_isPlaying = false; + + CSoundLayer *m_pParent = NULL; + + IAudioBufferEx *m_pPrimaryBuffer = NULL; + CSoundSystem *m_pSoundSystem = NULL; + + String m_sName = ""; + + typedef AssotiativeArray<String, CSoundLayer*> maplayer; + maplayer m_mapLayers; + + typedef AssotiativeArray<String, CSoundPlayer*> mapsoundplayer; + mapsoundplayer m_mapSndPlayers; + + typedef AssotiativeArray<String, CSoundEmitter*> mapsoundemitter; + mapsoundemitter m_mapSndEmitters; +}; + +#endif diff --git a/source/xSound/SoundLoader.cpp b/source/xSound/SoundLoader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..51039cbb13ce1e7d932c2a083fe8729cc0fe2799 --- /dev/null +++ b/source/xSound/SoundLoader.cpp @@ -0,0 +1,57 @@ + +#include "SoundLoader.h" + +#include "SoundSystem.h" + +//########################################################################## + +bool CSoundLoader::can() const +{ + return (bool)m_pCodecTarget; +} + +void CSoundLoader::init(CSoundSystem *pSoundSystem) +{ + m_pSoundSystem = pSoundSystem; +} + +bool CSoundLoader::load(const char *szPath, AudioRawDesc *pDesc) +{ + if (!m_pSoundSystem) + return false; + + m_pCodecTarget = m_pSoundSystem->getCodecTarget(szPath); + if (!m_pCodecTarget) + return false; + + m_pCodecTarget->getDesc(pDesc); + + return true; +} + +size_t CSoundLoader::getPCM(void **ppData, uint32_t uLen, int32_t iPos) +{ + if (!can()) + return 0; + + if (iPos < 0) + iPos = getPos(); + + return m_pCodecTarget->decode(iPos, uLen, ppData); +} + +void CSoundLoader::setPos(uint32_t uPos) +{ + if (!can()) + return; + + m_pCodecTarget->setPos(uPos); +} + +int32_t CSoundLoader::getPos() const +{ + if (!can()) + return 0; + + return m_pCodecTarget->getPos(); +} diff --git a/source/xSound/SoundLoader.h b/source/xSound/SoundLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..6372307387125f716ca48cd01a13414bd9a154cf --- /dev/null +++ b/source/xSound/SoundLoader.h @@ -0,0 +1,75 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDLOADER_H +#define __SOUNDLOADER_H + +#include <common/string.h> + +#include "SoundTypes.h" + +//########################################################################## + +//! количество частей буфера потоковой загрузки +#define STREAM_DATA_COUNT_PARTS 4 + +//! минимальное количество частей для потоковой загрузки, чтобы была выбрана потоковая загрузка +#define STREAM_COUNT_MIN_PARTS 100 + +//! структура данных для потоковой загрузки +struct CStreamData +{ + //! сколько частей уже проиграно (для определения позиции в звуке) + uint32_t uCountPlayed = 0; + + //! размер одной части в байтах + uint32_t uPartSize = 0; + + //! структура части + struct CPart + { + uint32_t uStart = 0; //!< стартовая позиция + uint32_t uEnd = 0; //!< конечная позиция + bool isPlay = false; //!< воспроизводится ли сейчас часть + bool isLoaded = false; //!< загружена ли эта часть + }; + + //! массив частей + CPart aParts[STREAM_DATA_COUNT_PARTS]; + + struct CRawData + { + BYTE *pData = 0; + uint32_t uSize = 0; + } oData; +}; + +//########################################################################## + +class CSoundLoader +{ +public: + ~CSoundLoader(){} + + void init(CSoundSystem *pSoundSystem); + + /*! загружает звук через подходящий декодер + */ + bool load(const char *szPath, AudioRawDesc *pDesc); + size_t getPCM(void **ppData, uint32_t uLen, int32_t iPos = -1); + void setPos(uint32_t uPos); + int32_t getPos() const; + +protected: + + bool can() const; + IXAudioCodecTarget *m_pCodecTarget = NULL; + CSoundSystem *m_pSoundSystem = NULL; + + String m_sPath = ""; +}; + +#endif diff --git a/source/xSound/SoundPlayer.cpp b/source/xSound/SoundPlayer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..648532c1f5d6e717bd6bd460971b7e6b31ed49a4 --- /dev/null +++ b/source/xSound/SoundPlayer.cpp @@ -0,0 +1,313 @@ + +#include "SoundPlayer.h" + +#include "SoundLoader.h" +#include "SoundLayer.h" + +//########################################################################## + +CSoundPlayer::~CSoundPlayer() +{ + m_pLayer->delSndPlayer(this); + mem_release_del(m_pAB); + + mem_delete(m_pCodecTarget); + mem_delete(m_pStream); +} + +//************************************************************************** + +CSoundPlayer* CSoundPlayer::newInstance() +{ + if (m_pStream) + return NULL; + + CSoundPlayer *pPlayer = new CSoundPlayer(); + + pPlayer->m_pAB = m_pAB->newInstance(); + pPlayer->m_uLengthBytes = this->m_uLengthBytes; + pPlayer->m_fLengthMls = this->m_fLengthMls; + pPlayer->m_loop = this->m_loop; + pPlayer->m_dtype = this->m_dtype; + pPlayer->m_state = SOUND_STATE_STOP; + pPlayer->m_sName = this->m_sName; + pPlayer->m_pLayer = this->m_pLayer; + pPlayer->m_fDist = this->m_fDist; + pPlayer->m_vWorldPos = this->m_vWorldPos; + return pPlayer; +} + +//************************************************************************** + +bool CSoundPlayer::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype) +{ + if (!pCodecTarget || !pLayer) + return false; + + m_dtype = dtype; + m_pLayer = pLayer; + m_pCodecTarget = pCodecTarget; + AudioRawDesc oDesc; + pCodecTarget->getDesc(&oDesc); + m_uLengthBytes = oDesc.uSize; + m_fLengthMls = (uint32_t)(double(oDesc.uSize * 1000) / double(oDesc.uBytesPerSec)); + + uint32_t uChunkSize = m_pLayer->getStreamChunkSize(&oDesc); + + + if (oDesc.uSize / uChunkSize > STREAM_COUNT_MIN_PARTS) + { + oDesc.uSize = uChunkSize * 4; + m_pAB = m_pLayer->createAudioBuffer(AB_TYPE_SECOND, &oDesc); + m_pStream = new CStreamData(); + m_pStream->uPartSize = oDesc.uSize / STREAM_DATA_COUNT_PARTS; + m_pStream->oData.uSize = m_pStream->uPartSize; + m_pStream->oData.pData = new BYTE[m_pStream->oData.uSize]; + for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i) + { + m_pStream->aParts[i].uStart = i * m_pStream->uPartSize; + m_pStream->aParts[i].uEnd = m_pStream->aParts[i].uStart + m_pStream->uPartSize; + } + m_pAB->setLoop(AB_LOOP_SIMPLE); + } + else + { + m_pAB = m_pLayer->createAudioBuffer(AB_TYPE_SECOND, &oDesc); + BYTE *pData = new BYTE[oDesc.uSize]; + m_pCodecTarget->decode(0, oDesc.uSize, (void**)&pData); + + BYTE *pData2; + m_pAB->lock(AB_LOCK_WRITE, (void**)&pData2); + memcpy(pData2, pData, oDesc.uSize); + m_pAB->unlock(); + + mem_delete_a(pData); + } + + setTime(0); + + return true; +} + +//########################################################################## + +void XMETHODCALLTYPE CSoundPlayer::play() +{ + if (!m_pLayer->isPlaying()) + return; + + float3 vPos, vLook, vUp; + m_pLayer->getObserverParam(&vPos, &vLook, &vUp); + + Com3D(m_pAB, m_fDist, m_vWorldPos, vPos, vLook, vUp); + m_pAB->play(true); + m_state = SOUND_STATE_PLAY; +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundPlayer::resume() +{ + if (!m_pLayer->isPlaying() || m_state != SOUND_STATE_PAUSE) + return; + + m_pAB->play(true); +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundPlayer::pause() +{ + m_pAB->play(false); + m_state = SOUND_STATE_PAUSE; +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundPlayer::stop() +{ + m_pAB->play(false); + setTime(0.f); + m_state = SOUND_STATE_STOP; +} + +//************************************************************************** + +bool XMETHODCALLTYPE CSoundPlayer::isPlaying() const +{ + return m_pAB->isPlaying(); +} + +//########################################################################## + +void XMETHODCALLTYPE CSoundPlayer::setLoop(SOUND_LOOP loop) +{ + m_loop = loop; + if (!m_pStream) + m_pAB->setLoop((AB_LOOP)m_loop); +} + +//************************************************************************** + +SOUND_LOOP XMETHODCALLTYPE CSoundPlayer::getLoop() const +{ + return m_loop; +} + +//########################################################################## + +float XMETHODCALLTYPE CSoundPlayer::getTime() const +{ + uint32_t uPos = getPosBytes(); + + if (m_pStream) + { + AudioRawDesc oDesc; + m_pAB->getDesc(&oDesc); + uPos = (uint64_t(uPos) * uint64_t(1000)) / uint64_t(oDesc.uBytesPerSec); + } + + return float(uPos) / 1000.f; +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundPlayer::setTime(float fTime) +{ + AudioRawDesc oDesc; + m_pAB->getDesc(&oDesc); + uint32_t uPosBytes = (uint64_t(fTime * 1000.f) * uint64_t(oDesc.uBytesPerSec)) / uint64_t(1000); + + if (m_uLengthBytes < uPosBytes) + return; + + if (m_pStream) + setPosStream(uPosBytes); + else + m_pAB->setPos(uPosBytes); +} + +//************************************************************************** + +float XMETHODCALLTYPE CSoundPlayer::getLength() const +{ + return double(m_fLengthMls) / 1000.f; +} + +//########################################################################## + +void CSoundPlayer::setPosStream(uint32_t uPos) +{ + uint32_t uCountParts = STREAM_DATA_COUNT_PARTS; + uint32_t uParts = uPos / (m_pStream->uPartSize * uCountParts); + if (uParts * m_pStream->uPartSize * uCountParts > uPos) + --uParts; + + uint32_t uPosAB = (uPos - (uParts * m_pStream->uPartSize * uCountParts)); + uint32_t uCurrPart = uPosAB / m_pStream->uPartSize; + m_pStream->uCountPlayed = uParts * uCountParts + uCurrPart; + + uint32_t uPosLoader = uPos - (uCurrPart * m_pStream->uPartSize); + m_pCodecTarget->setPos(uPosLoader); + for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i) + { + if (i >= uCurrPart) + { + size_t sizeRead = m_pCodecTarget->decode(m_pCodecTarget->getPos(), m_pStream->oData.uSize, (void**)&(m_pStream->oData.pData)); + if (sizeRead <= 0) + continue; + + BYTE *pData = 0; + uint32_t uLocked = m_pAB->lock(AB_LOCK_WRITE, (void**)&pData, m_pStream->aParts[i].uStart, m_pStream->aParts[i].uEnd - m_pStream->aParts[i].uStart); + memcpy(pData, m_pStream->oData.pData, sizeRead); + m_pAB->unlock(); + + m_pStream->aParts[i].isLoaded = true; + } + else + { + m_pStream->aParts[i].isPlay = false; + m_pStream->aParts[i].isLoaded = false; + } + } + + int qwerty = 0; +} + +//************************************************************************** + +uint32_t CSoundPlayer::getPosBytes() const +{ + uint32_t uPos = m_pAB->getPos(); + + if (m_pStream) + uPos = (uint64_t(uPos) + uint64_t(m_pStream->uPartSize) * uint64_t(m_pStream->uCountPlayed)); + + return uPos; +} + +//########################################################################## + +void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) +{ + if (!m_pLayer->isPlaying()) + return; + + if (m_dtype == SOUND_DTYPE_3D) + { + Com3D(m_pAB, m_fDist, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp); + } + + if (!m_pStream) + return; + + uint32_t uGPosBytes = getPosBytes(); + uint32_t uGPosBytes2 = m_pCodecTarget->getPos(); + + /*static uint32_t uMax = 0; + if (uMax < uGPosBytes) + { + uMax = uGPosBytes; + printf("uMax = %d\n", uMax); + }*/ + + if (uGPosBytes >= m_uLengthBytes) + { + if (m_loop == AB_LOOP_NONE) + m_pAB->play(false); + else + setTime(0.f); + } + + if (!isPlaying()) + return; + + uint32_t uPos = m_pAB->getPos(); + + for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i) + { + if (m_pStream->aParts[i].uStart <= uPos && uPos <= m_pStream->aParts[i].uEnd) + m_pStream->aParts[i].isPlay = true; + else + { + if (m_pStream->aParts[i].isPlay) + { + m_pStream->aParts[i].isPlay = false; + m_pStream->aParts[i].isLoaded = false; + + size_t sizeRead = m_pCodecTarget->decode(m_pCodecTarget->getPos(), m_pStream->oData.uSize, (void**)&(m_pStream->oData.pData)); + ++(m_pStream->uCountPlayed); + if (sizeRead == 0) + continue; + + BYTE *pData = 0; + uint32_t uLocked = m_pAB->lock(AB_LOCK_WRITE, (void**)&pData, m_pStream->aParts[i].uStart, m_pStream->aParts[i].uEnd - m_pStream->aParts[i].uStart); + memset(pData, 0, uLocked); + memcpy(pData, m_pStream->oData.pData, sizeRead); + m_pAB->unlock(); + + m_pStream->aParts[i].isLoaded = true; + } + } + } +} diff --git a/source/xSound/SoundPlayer.h b/source/xSound/SoundPlayer.h new file mode 100644 index 0000000000000000000000000000000000000000..e21098dd48cc669deb91af4c154e82a1a99af274 --- /dev/null +++ b/source/xSound/SoundPlayer.h @@ -0,0 +1,80 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDPLAYER_H +#define __SOUNDPLAYER_H + +#include <xcommon/IXSoundSystem.h> +#include "SoundBase.h" +#include <mital.h> + +#include "SoundTypes.h" +#include "SoundSystem.h" + +//########################################################################## + +class CSoundPlayer : public CSoundBase, public virtual IXSoundPlayer +{ +public: + SX_ALIGNED_OP_MEM + + ~CSoundPlayer(); + + CSoundPlayer* newInstance(); + + virtual void XMETHODCALLTYPE play() override; + virtual void XMETHODCALLTYPE resume() override; + virtual void XMETHODCALLTYPE pause() override; + virtual void XMETHODCALLTYPE stop() override; + + virtual bool XMETHODCALLTYPE isPlaying() const override; + + virtual SOUND_LOOP XMETHODCALLTYPE getLoop() const override; + virtual void XMETHODCALLTYPE setLoop(SOUND_LOOP loop) override; + + virtual float XMETHODCALLTYPE getTime() const override; + virtual void XMETHODCALLTYPE setTime(float fTime) override; + + virtual float XMETHODCALLTYPE getLength() const override; + +protected: + + friend CSoundLayer; + + void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp); + + bool create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype); + + //! возвращает текущую позицию проигрывания звука в байтах + uint32_t getPosBytes() const; + + /*! установка позиции при потоковом воспроизведении + @param uPos позиция в байтах + */ + void setPosStream(uint32_t uPos); + + //************************************************************************ + + //! аудио буфер + IAudioBuffer *m_pAB = NULL; + + //! зацикливать ли воспроизведение + SOUND_LOOP m_loop = SOUND_LOOP_NONE; + + //! длина звука в байтах + uint32_t m_uLengthBytes = 0; + + //! длина звука в секундах + uint32_t m_fLengthMls = 0; + + //! кодек + IXAudioCodecTarget *m_pCodecTarget = NULL; + + //! данные потоковой загрузки + CStreamData *m_pStream = NULL; +}; + +#endif diff --git a/source/xSound/SoundSystem.cpp b/source/xSound/SoundSystem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7109a7ce15a4cd4ce9788905557b132c430b1acd --- /dev/null +++ b/source/xSound/SoundSystem.cpp @@ -0,0 +1,294 @@ + +#include "SoundSystem.h" +#include "AudioConverter.h" + +#include "SoundLayer.h" + +#include <ctime> +#include <sys/stat.h> + +#ifdef _MSC_VER +#include <direct.h> +#endif + +//########################################################################## + +CSoundSystem::CSoundSystem(IXCore *pXCore) +{ +#ifdef _MSC_VER + mkdir(SOUND_CACHE); +#else + mkdir(SOUND_CACHE, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + + m_pXCore = pXCore; + + auto pPluginManager = m_pXCore->getPluginManager(); + + IXAudioCodec *pAudioCodec; + UINT ic = 0; + while ((pAudioCodec = (IXAudioCodec*)(pPluginManager->getInterface(IXAUDIOCODEC_GUID, ic++)))) + { + if (pAudioCodec->getVersion() == IXAUDIOCODEC_VERSION) + { + LibReport(REPORT_MSG_LEVEL_NOTICE, "Registered audio codec: %s\n", pAudioCodec->getFormat()); + + addCodec(pAudioCodec->getFormat(), pAudioCodec); + } + } + + m_pAudio = MitAl_InitAudio(); +} + +CSoundSystem::~CSoundSystem() +{ + mem_release(m_pMasterLayer); +} + +//************************************************************************** + +void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) +{ + std::lock_guard<std::mutex> guard(m_oMutexUpdate); + + if(m_pMasterLayer) + m_pMasterLayer->update(vListenerPos, vListenerDir, vListenerUp); + + m_vObserverPos = vListenerPos; m_vObserverLook = vListenerDir; m_vObserverUp = vListenerUp; +} + +//************************************************************************** + +IXSoundLayer* XMETHODCALLTYPE CSoundSystem::createMasterLayer(const AudioRawDesc *pDesc, const char *szName) +{ + if(m_pMasterLayer) + return m_pMasterLayer; + + if(!pDesc) + return NULL; + + if (!supportedDesc(pDesc, AB_TYPE_PRIMARY)) + { + printf("unsupported audio buffer description"); + return NULL; + } + + CSoundLayer *pLayer = new CSoundLayer(); + pLayer->init(this, NULL, pDesc, szName); + + m_pMasterLayer = pLayer; + + return pLayer; +} + +//************************************************************************** + +IXCore* CSoundSystem::getCore() const +{ + return m_pXCore; +} + +//************************************************************************** + +IXAudioCodecTarget* CSoundSystem::getCodecTarget(const char *szName) +{ + if(!m_pMasterLayer) + return NULL; + + if (!szName) + return NULL; + + const char *szPath = szName; + + if (!m_pXCore->getFileSystem()->fileExists(szPath)) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "File '%s' not found\n", szPath); + return NULL; + } + + IXAudioCodec *pCodec = NULL; + IXAudioCodecTarget *pTarget = NULL; + IXAudioCodecTarget *pTarget2 = NULL; + + for (mapcodec::Iterator i = m_mapCodecs.begin(); i != m_mapCodecs.end(); i++) + { + if (m_mapCodecs[i.first]->open(szPath, "", &pTarget, false)) + { + pCodec = m_mapCodecs[i.first]; + break; + } + } + + if(!pCodec || !pTarget) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "Unsupported audio format '%s'\n", szPath); + return NULL; + } + + AudioRawDesc oDescMaster, oDescSnd, oDescCache; + m_pMasterLayer->getDesc(&oDescMaster); + pTarget->getDesc(&oDescSnd); + + //если звук соответствует требования мастер буфера, тогда не надо конвертировать, возвращает целевой кодек + if(oDescSnd.uSampleRate == oDescMaster.uSampleRate) + return pTarget; + + + //если кодек может сохранять, тогда пересохраняем файл + if(pCodec->canSave()) + { + //выдергиваем pcm данные из таргета и удаляем его + IXBuffer *pBufferIn = m_pXCore->newBuffer(); + IXBuffer *pBufferOut = m_pXCore->newBuffer(); + pBufferIn->alloc(oDescSnd.uSize); + BYTE *pData = pBufferIn->get(); + pTarget->decode(0, pBufferIn->size(), (void**)&pData); + pTarget->Release(); + + //открываем файл на запись + if(!pCodec->open(szPath, "", &pTarget, true)) + return NULL; + + //создаем нужное описание и конвертируем pcm данные + AudioRawDesc oDescOut = oDescSnd; + oDescOut.uSampleRate = oDescMaster.uSampleRate; + oDescOut.calc(); + if (!AudioConverter(pData, &oDescSnd, pBufferOut, &oDescOut)) + return NULL; + + //записываем новые данные и сносим таргет + pTarget->encode(pBufferOut, &oDescOut); + pTarget->Release(); + + //открываем файл на чтение + if(!pCodec->open(szPath, "", &pTarget, false)) + return NULL; + + return pTarget; + } + + //ищем первый попавшийся кодек который может записывать + IXAudioCodec *pFullCodec = getCodecSave(); + if (!pFullCodec) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "Not found codec for coding, file '%s' does not match of parameters master buffer\n", szPath); + return NULL; + } + + //создаем путь до файла в кэше + String sCachePath = String(SOUND_CACHE) + "/"+ szPath; + sCachePath = PathSetExt(sCachePath.c_str(), pFullCodec->getExt()); + + //берем инфу о файлах (оригинал и кэш) + struct stat stOrigin, stCache; + stat(szPath, &stOrigin); + stat(sCachePath.c_str(), &stCache); + + //нужно ли конвертировать файл + bool canConvert = false; + + //если есть разница по времени (изменения/модификации), тогда надо конвертировать +#ifdef _MSC_VER + if (stOrigin.st_ctime > stCache.st_ctime || stOrigin.st_mtime > stCache.st_mtime) +#else + if(stOrigin.st_ctim.tv_sec > stCache.st_ctim.tv_sec || stOrigin.st_mtim.tv_sec > stCache.st_mtim.tv_sec) +#endif + canConvert = true; + else + { + //если не удается открыть файл кэша, то надо конвертировать + if(!pFullCodec->open(sCachePath.c_str(), "", &pTarget2, false)) + canConvert = true; + else + { + //если файл кэша не соответствует, тогда надо конвертировать + pTarget2->getDesc(&oDescCache); + if(oDescCache.uSampleRate != oDescMaster.uSampleRate) + canConvert = true; + } + } + + //если конвертирование не требуется, возвращаем целевой кодек + if(!canConvert) + return pTarget2; + + mem_release(pTarget2); + + //выдергиваем pcm данные из таргета и удаляем его + IXBuffer *pBufferIn = m_pXCore->newBuffer(); + IXBuffer *pBufferOut = m_pXCore->newBuffer(); + pBufferIn->alloc(oDescSnd.uSize); + BYTE *pData = pBufferIn->get(); + pTarget->decode(0, pBufferIn->size(), (void**)&pData); + pTarget->Release(); + + //создаем нужное описание и конвертируем pcm данные + AudioRawDesc oDescOut = oDescSnd; + oDescOut.uSampleRate = oDescMaster.uSampleRate; + oDescOut.calc(); + if (!AudioConverter(pData, &oDescSnd, pBufferOut, &oDescOut)) + return NULL; + + //открываем файл на запись + if(!pFullCodec->open(sCachePath.c_str(), "", &pTarget2, true)) + return NULL; + + pTarget2->encode(pBufferOut, &oDescOut); + pTarget2->Release(); + + if(!pFullCodec->open(sCachePath.c_str(), "", &pTarget2, false)) + return NULL; + + return pTarget2; +} + +//************************************************************************** + +void CSoundSystem::addCodec(const char *szFmt, IXAudioCodec *pCodec) +{ + if(!szFmt || !pCodec) + return; + + m_mapCodecs[szFmt] = pCodec; +} + +//************************************************************************** + +IAudioBufferEx* CSoundSystem::createMasterBuffer(AudioRawDesc *pDesc) +{ + return m_pAudio->createMasterBuffer(pDesc); +} + +//************************************************************************** + +bool CSoundSystem::supportedDesc(const AudioRawDesc *pDesc, AB_TYPE type) +{ + return m_pAudio->supportedDesc(pDesc, type); +} + +//************************************************************************** + +IXSoundLayer* XMETHODCALLTYPE CSoundSystem::findLayer(const char *szName) +{ + if(!szName) + return NULL; + + if(strcasecmp(m_pMasterLayer->getName(), szName) == 0) + return m_pMasterLayer; + + return m_pMasterLayer->findLayer(szName); +} + +//************************************************************************** + +IXAudioCodec* CSoundSystem::getCodecSave() +{ + for (mapcodec::Iterator i = m_mapCodecs.begin(); i != m_mapCodecs.end(); i++) + { + if (m_mapCodecs[i.first]->canSave()) + return m_mapCodecs[i.first]; + } + + return NULL; +} + diff --git a/source/xSound/SoundSystem.h b/source/xSound/SoundSystem.h new file mode 100644 index 0000000000000000000000000000000000000000..62ffad2c74decfb24ee6ee4cfe48bf59e99c00cc --- /dev/null +++ b/source/xSound/SoundSystem.h @@ -0,0 +1,95 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDSYSTEM_H +#define __SOUNDSYSTEM_H + +#include <common/assotiativearray.h> +#include <common/string.h> +#include <common/path_utils.h> +#include <common/math.h> + +#include <xcommon/IXCore.h> +#include <xcommon/IPluginManager.h> +#include <xcommon/IXSoundSystem.h> +#include <xcommon/IXAudioCodec.h> + +#include "SoundTypes.h" + +//########################################################################## + +inline float Com3DPan(const float3 &vSnd, const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) +{ + float3 side = SMVector3Cross(vListenerUp, vListenerDir); + SMVector3Normalize(side); + float x = SMVector3Dot(vSnd - vListenerPos, side); + float z = SMVector3Dot(vSnd - vListenerPos, vListenerDir); + float angle = atan2(x, z); + float pan = sin(angle); + return pan; +} + +inline void Com3D(IAudioBuffer *pAB, float fDist, const float3 &vSnd, const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) +{ + float fPan = Com3DPan(vSnd, vListenerPos, vListenerDir, vListenerUp); + float fVolume = 1.f - saturatef(SMVector3Distance(vSnd, vListenerPos) / fDist); + fPan = lerpf(fPan, 0.f, fVolume); + pAB->setPan(fPan); + pAB->setVolume(fVolume); +} + +//########################################################################## + +class CSoundSystem: public IXUnknownImplementation<IXSoundSystem> +{ +public: + SX_ALIGNED_OP_MEM + + CSoundSystem(IXCore *pXCore); + ~CSoundSystem(); + + virtual IXSoundLayer* XMETHODCALLTYPE createMasterLayer(const AudioRawDesc *pDesc, const char *szName) override; + virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) override; + + virtual void XMETHODCALLTYPE update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp) override; + + IXAudioCodecTarget* getCodecTarget(const char *szName); + + IXCore* getCore() const; + + void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp) + { + while (!m_oMutexUpdate.try_lock()){} + m_oMutexUpdate.unlock(); + + *pPos = m_vObserverPos; *pLook = m_vObserverLook; *pUp = m_vObserverUp; + } + +protected: + + friend CSoundLayer; + + IAudioBufferEx* createMasterBuffer(AudioRawDesc *pDesc); + bool supportedDesc(const AudioRawDesc *pDesc, AB_TYPE type); + + void addCodec(const char *szFmt, IXAudioCodec *pCodec); + + IXCore *m_pXCore = NULL; + + IAudio *m_pAudio = NULL; + + IXAudioCodec* getCodecSave(); + + CSoundLayer *m_pMasterLayer = NULL; + + typedef AssotiativeArray<String, IXAudioCodec*> mapcodec; + mapcodec m_mapCodecs; + + float3 m_vObserverPos, m_vObserverLook, m_vObserverUp; + std::mutex m_oMutexUpdate; +}; + +#endif diff --git a/source/xSound/SoundTypes.h b/source/xSound/SoundTypes.h new file mode 100644 index 0000000000000000000000000000000000000000..5c4c77482db1e05e86c2ac643c665f889cb21def --- /dev/null +++ b/source/xSound/SoundTypes.h @@ -0,0 +1,37 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +#ifndef __SOUNDTYPES_H +#define __SOUNDTYPES_H + +#include <xcommon/IXSoundSystem.h> +#include <xcommon/IXAudioCodec.h> + +#include <mital.h> + +//########################################################################## + +class CStreamData; + +class CSoundBase; +class CSoundLoader; +class CSoundEmitter; +class CSoundPlayer; +class CSoundLayer; +class CSoundSystem; + +//########################################################################## + +//! состояния воспроизведения звукового объекта +enum SOUND_STATE +{ + SOUND_STATE_STOP, //!< остановлен + SOUND_STATE_PAUSE, //!< приостановлен + SOUND_STATE_PLAY, //!< проигрывается +}; + + +#endif \ No newline at end of file diff --git a/source/xSound/dllmain.cpp b/source/xSound/dllmain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fdece5b079edcec13c692b45e9101170ba1093d4 --- /dev/null +++ b/source/xSound/dllmain.cpp @@ -0,0 +1,24 @@ + +/*********************************************************** +Copyright � Vitaliy Buturlin, Evgeny Danilovich, 2017, 2018 +See the license in LICENSE +***********************************************************/ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +BOOL APIENTRY DllMain(HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch(ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} diff --git a/source/xSound/plugin_main.cpp b/source/xSound/plugin_main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f21f993d4857a09e75dac5bd9dccbc1f9032b3f3 --- /dev/null +++ b/source/xSound/plugin_main.cpp @@ -0,0 +1,173 @@ + +#include <xcommon/IXPlugin.h> +#include <xcommon/IXUpdatable.h> +#include "SoundSystem.h" +#include <Audio.h> +#include <gcore/sxgcore.h> + +#if defined(_DEBUG) +#pragma comment(lib, "mital_d.lib") +#else +#pragma comment(lib, "mital.lib") +#endif + +//########################################################################## + +class CObserverChangedEventListener : public IEventListener<XEventObserverChanged> +{ +public: + SX_ALIGNED_OP_MEM + + CObserverChangedEventListener(IXCore *pCore) + { + m_pObserverChangedEventChannel = pCore->getEventChannel<XEventObserverChanged>(EVENT_OBSERVER_CHANGED_GUID); + m_pObserverChangedEventChannel->addListener(this); + } + + ~CObserverChangedEventListener() + { + m_pObserverChangedEventChannel->removeListener(this); + } + + void onEvent(const XEventObserverChanged *pData) override + { + std::lock_guard<std::mutex> guard(m_oMutex); + pData->pCamera->getPosition(&m_vPos); + pData->pCamera->getUp(&m_vUp); + pData->pCamera->getLook(&m_vLook); + } + + void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp) + { + std::lock_guard<std::mutex> guard(m_oMutex); + *pPos = m_vPos; *pLook = m_vLook; *pUp = m_vUp; + } + +protected: + IEventChannel<XEventObserverChanged> *m_pObserverChangedEventChannel = NULL; + float3 m_vPos, m_vLook, m_vUp; + std::mutex m_oMutex; +}; + +//########################################################################## + +class CUpdatableSoundSystem : public IXUnknownImplementation<IXUpdatable> +{ +public: + SX_ALIGNED_OP_MEM + + CUpdatableSoundSystem(CSoundSystem *pSoundSystem, CObserverChangedEventListener *pObserverListener) + { + m_pSoundSystem = pSoundSystem; + m_pObserverListener = pObserverListener; + } + + UINT startup() override + { + return 1; + } + void shutdown() override + { + mem_release(m_pSoundSystem); + } + + ID run(float fDelta) override + { + float3 vPos, vLook, vUp; + + if (m_pObserverListener) + m_pObserverListener->getObserverParam(&vPos, &vLook, &vUp); + + if (m_pSoundSystem) + m_pSoundSystem->update(vPos, vLook, vUp); + + /*if (!m_pEmitter) + { + IXSoundLayer *pMasterLayer = m_pSoundSystem->findLayer("master"); + if (pMasterLayer) + { + m_pEmitter = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_3D); + m_pEmitter->setWorldPos(float3(-11.084, 0.435, -18.707)); + m_pEmitter->setDistance(50); + //pEmitter->play(); + } + } + else + { + if (GetAsyncKeyState('I')) + { + m_pEmitter->play(); + //Sleep(100); + } + }*/ + + return -1; + } + + void sync() override + { + + } + +protected: + CSoundSystem *m_pSoundSystem = NULL; + CObserverChangedEventListener *m_pObserverListener = NULL; + IXSoundEmitter *m_pEmitter = NULL; +}; + +//########################################################################## + +class CSoundSystemPlugin : public IXUnknownImplementation<IXPlugin> +{ +public: + + void XMETHODCALLTYPE startup(IXCore *pCore) override + { + m_pCore = pCore; + m_pSoundSystem = new CSoundSystem(m_pCore); + m_pObserverListener = new CObserverChangedEventListener(m_pCore); + m_pUpdatableSoundSystem = new CUpdatableSoundSystem(m_pSoundSystem, m_pObserverListener); + } + + void XMETHODCALLTYPE shutdown() override + { + } + + UINT XMETHODCALLTYPE getInterfaceCount() override + { + return(2); + } + const XGUID* XMETHODCALLTYPE getInterfaceGUID(UINT id) override + { + static XGUID s_guid; + switch(id) + { + case 0: + s_guid = IXSOUNDSYSTEM_GUID; + break; + case 1: + s_guid = IXUPDATABLE_GUID; + break; + default: + return(NULL); + } + return(&s_guid); + } + IXUnknown* XMETHODCALLTYPE getInterface(const XGUID &guid) override + { + if (guid == IXSOUNDSYSTEM_GUID) + return m_pSoundSystem; + else if (guid == IXUPDATABLE_GUID) + return m_pUpdatableSoundSystem; + + return(NULL); + } + +protected: + IXCore *m_pCore; + CSoundSystem *m_pSoundSystem = NULL; + CUpdatableSoundSystem *m_pUpdatableSoundSystem = NULL; + CObserverChangedEventListener *m_pObserverListener = NULL; +}; + +DECLARE_XPLUGIN(CSoundSystemPlugin); diff --git a/source/xcommon/XEvents.h b/source/xcommon/XEvents.h index a3fbfc39dc08aa727498e90f3d0b99e5ce01a94e..0d33ec29ad8f0a288dbc3071444ff7d8ff0c1226 100644 --- a/source/xcommon/XEvents.h +++ b/source/xcommon/XEvents.h @@ -222,4 +222,14 @@ struct XEventCvarChanged const void *pCvar; }; + +// {5CEC2355-1F1E-4A1D-8E69-5B92850B62D2} +#define EVENT_OBSERVER_CHANGED_GUID DEFINE_XGUID(0x5cec2355, 0x1f1e, 0x4a1d, 0x8e, 0x69, 0x5b, 0x92, 0x85, 0xb, 0x62, 0xd2) + +class ICamera; +struct XEventObserverChanged +{ + ICamera *pCamera; +}; + #endif diff --git a/source/xcommon/resource/IXResourceManager.h b/source/xcommon/resource/IXResourceManager.h index 37c30eb6b1873c52b57dfa8ef2161bfa7eb12717..30f20064c0a588b465d07b6bf82ceb12731ad777 100644 --- a/source/xcommon/resource/IXResourceManager.h +++ b/source/xcommon/resource/IXResourceManager.h @@ -45,6 +45,9 @@ public: virtual IXResourceTexture2D* XMETHODCALLTYPE newResourceTexture2D() = 0; virtual IXResourceTextureCube* XMETHODCALLTYPE newResourceTextureCube() = 0; virtual void XMETHODCALLTYPE addTexture(const char *szName, IXResourceTexture *pTexture) = 0; + + virtual UINT XMETHODCALLTYPE getSoundSupportedFormats() = 0; + virtual const XFormatName* XMETHODCALLTYPE getSoundSupportedFormat(UINT uIndex) = 0; }; #endif