diff --git a/build/gamesource/shaders/ppe/ppe_lens_flare2.ps b/build/gamesource/shaders/ppe/ppe_lens_flare2.ps index 8790fa88534cd218c1fd91329fc95567ce76a538..2fb0e3d95105fd991b1542eb2a4f136341e884d4 100644 --- a/build/gamesource/shaders/ppe/ppe_lens_flare2.ps +++ b/build/gamesource/shaders/ppe/ppe_lens_flare2.ps @@ -43,5 +43,5 @@ half4 main(vs_out_pp IN):COLOR0 } result /= half(NumSamples)*(LensFlareParam.z); - return half4(result+0.1,0.0); + return half4(result,0.0); } \ No newline at end of file diff --git a/build/sysconfig.cfg b/build/sysconfig.cfg index 595abcb14e782db5c72c44363f5e0911ff0a0386..7c73de96303ea8078e8845e7816643e846e7358b 100644 --- a/build/sysconfig.cfg +++ b/build/sysconfig.cfg @@ -46,7 +46,7 @@ grass_frec 100 green_lod0 50 green_lod1 100 green_less 20 -p_far 400 +r_far 400 r_s_filter 2 r_s_max_anisotropy 16 diff --git a/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj b/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj index ef9a54c1b3c7fc98c7dc10a596d1cdd865315ac0..58cd47a2476af37d1889f9cd03b976d6a8b9969b 100644 --- a/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj +++ b/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj @@ -95,11 +95,13 @@ </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="..\..\..\source\common\string.cpp" /> + <ClCompile Include="..\..\..\source\common\string_func.cpp" /> <ClCompile Include="..\..\..\source\skyxengine.cpp" /> <ClCompile Include="..\..\..\source\SkyXEngine_Build\SkyXEngine_Build.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\source\common\string.h" /> + <ClInclude Include="..\..\..\source\common\string_func.h" /> <ClInclude Include="..\..\..\source\gdefines.h" /> <ClInclude Include="..\..\..\source\GRegisterIndex.h" /> <ClInclude Include="..\..\..\source\SkyXEngine.h" /> diff --git a/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj.filters b/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj.filters index 087531ce94fd734db4a0c037ec5db57054c6b5e3..72e4611f7a8048d9fb4f743a7b750c962dee6cc5 100644 --- a/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj.filters +++ b/proj/SkyXEngine/vs2013/SkyXEngine.vcxproj.filters @@ -10,6 +10,9 @@ <ClCompile Include="..\..\..\source\skyxengine.cpp"> <Filter>Source</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\common\string_func.cpp"> + <Filter>Source</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <Filter Include="Header"> @@ -38,6 +41,9 @@ <ClInclude Include="..\..\..\source\GRegisterIndex.h"> <Filter>Header</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\common\string_func.h"> + <Filter>Header</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\..\source\SkyXEngine_Build\SkyXEngine.rc"> diff --git a/proj/sxscore/vs2013/sxscore.vcxproj b/proj/sxscore/vs2013/sxscore.vcxproj index fdc0b888f7270c2ff394451b01c24e8bf2cfb49d..d1bc03c5c7364043f1fb322b6a2e93ed3a7600c0 100644 --- a/proj/sxscore/vs2013/sxscore.vcxproj +++ b/proj/sxscore/vs2013/sxscore.vcxproj @@ -11,11 +11,15 @@ </ProjectConfiguration> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\..\source\common\string.cpp" /> + <ClCompile Include="..\..\..\source\common\string_func.cpp" /> <ClCompile Include="..\..\..\source\score\sound.cpp" /> <ClCompile Include="..\..\..\source\score\sxscore.cpp" /> <ClCompile Include="..\..\..\source\score\sxscore_dll.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\..\source\common\array.h" /> + <ClInclude Include="..\..\..\source\common\string_func.h" /> <ClInclude Include="..\..\..\source\score\sound.h" /> <ClInclude Include="..\..\..\source\score\sxscore.h" /> </ItemGroup> diff --git a/proj/sxscore/vs2013/sxscore.vcxproj.filters b/proj/sxscore/vs2013/sxscore.vcxproj.filters index 8af11aed22310378c8b210782c5499bc369e0a90..4a0cc44c93b8946e32cda4a89ec3607e351ef740 100644 --- a/proj/sxscore/vs2013/sxscore.vcxproj.filters +++ b/proj/sxscore/vs2013/sxscore.vcxproj.filters @@ -24,6 +24,12 @@ <ClCompile Include="..\..\..\source\score\sound.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\common\string.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\source\common\string_func.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\source\score\sxscore.h"> @@ -32,5 +38,11 @@ <ClInclude Include="..\..\..\source\score\sound.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\common\string_func.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\common\array.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/source/SkyXEngine.h b/source/SkyXEngine.h index 36810e6f94fdb1402609b062236c2e34dfa30b4f..449e335d7fc9a292ba4e7aaece36d6687b0c63a6 100644 --- a/source/SkyXEngine.h +++ b/source/SkyXEngine.h @@ -1,160 +1,160 @@ - -/*********************************************************** -Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2017, 2018 -See the license in LICENSE -***********************************************************/ - -/*! -\file -Заголовочный файл движка SkyXEngine, подключает все необходимые библиотеки -*/ - + +/*********************************************************** +Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2017, 2018 +See the license in LICENSE +***********************************************************/ + +/*! +\file +Заголовочный файл движка SkyXEngine, подключает все необходимые библиотеки +*/ + /*! \mainpage Документация SkyXEngine Это документация API (интерфейса программирования приложения) 3D движка real-time рендера SkyXEngine. \n Для того чтобы понять что такое SkyXEngine рекомендуем Вам ознакомится с \ref info_engine "кратким описанием движка". \n Также было бы крайне полезным узнать \ref general_info_libs "об организации библиотек". \n Дальнейшее ознакомление с движком SkyXEngine можно по <a href="./modules.html">документации, которая представлена модулями/подмодулями</a>. -*/ - -/*! \page info_engine Информация о движке SkyXEngine -\tableofcontents -\section ie_common Общее -\b SkyXEngine - движок для создания 3D игр с real-time рендером, использует технологии DirectX 9. \n -<small>Сразу уточнение, DirectX 9 мы используем в связи с личными предпочтениями, так как на наш взгляд эта технология является одной из лучших, хоть и считается устаревшей. -Все новое это забытое старое)) И как нам кажется ... нет ничего такого, чего нельзя было бы сделать на DirectX 9, но что можно сделать на другом GAPI, для создания игр любого жанра с real-time рендером. -Но это только точка зрения нашей команды и она может быть ошибочная. Однако в планах есть расширение поддерживаемых GAPI.</small> - -<b>Формирование уровня</b> осуществляется посредством: - - загрузки статических моделей формата dse, с их автоматическим разбиением на "куски рендера" как quad или octo дерево, возможны сохранение/загрузка в бинарный файл всей геометрии уровня - - генерации растительности по маске, возможны 2 вида: трава (чем дальше тем меньше размер объекта) и деревья (с возможностью загрузки лодов), возможны возможны сохранение/загрузка в бинарный файл всей растительности уровня. Ручная расстановка расстительности поддерживается. Редактирование поддерживается. - -<b>Освещение</b> представлено 3 видами источников света (опционально поддерживается генерация теней от каждого исчтоника света): - - глобальный (солнце), тени - PSSM - - локальный - точечный, тени - Cube Shadow Mapping - - локальный - направленный, тени - Shadow Mapping. - -HDR эффект присутсвует. - -<b>Система материалов</b> pbr, то есть построенная на физичеки корретных, но апроксимированных вычислениях. \n -Для формирования данных для освещения используется техника Deferred shading, что позволяет обрабатывать неограниченное количество источников света. \n -Поддерживаются отражения 2 видов: - - плоские (планарные) - - объемные (кубические). - -Поддерживается до 3 полупрозрачных поверхностей в кадре (пока только тестовый режим, в планах улучшения качества). \n -Поддерживаемые эффекты поверхностей: - - микрорельеф - - микрорельеф по маске (до 4 текстур) - - детальность - - детальность по маске (до 4 текстур) - - комбинированный микрорельеф с детальностью по маске (до 4 текстур) - - альфа тест - - просвечиваемость (для освещения тонких поверхностей, к примеру листвы и травы). - - Вся система материалов является открытой и практически любой функционал системы доступен для собственной интерпретации, посредством шейдеров. Имеется встроенный набор данных.\n - Поддерживаются различные пользовательские данные которые интерпретируются только создающим материалы. - Настрока физического материала доступна. - -<b>Постпроцесс</b> состоит из эффектов: - - черно-белое изображение - - эффект сепия - - коррекция изображения - - рендер солнца - - bloom - - lens flare, эффект восприятия яркого света линзами - - depth of field, глубина резкости - - linear fog, линейный туман - - space screen ambient occulusion, глобальное освещение (точнее затенение) в пространстве экрана - - motion blur, размытие в движении - - nfaa - - dlaa. - -<b>Декали</b> - следы от пуль, взрывов, трещины. Рисуются поверх основной геометрии. - -<b>Физика</b> - для симуляции физики используется физический движок Bullet. - -<b>Звуковой движок</b> поддерживает воспроизведение в пространстве и в фоне. Поддерживаемые форматы ogg, wav. Доступно создание инстансов без возможности управления. - -<b>Партиклы</b> с необходимым набором логики и с многочисленными и простыми настроками. - -<b>AI сетка</b> для навигации живых игровых объектов. - -<b>Игровой движок</b> - основа для построения игровой логики. Предоставляет набор игровых объектов и обеспечивает их взаимодействие. - -<b>Эффекты окружения</b> представлены фоновыми ambient звуками, погодой, определяемой для каждого уровня, с различными погодными эффектами. - -<b>Real-time конфигурация (cvars)</b> позволяет в режиме реального времени через консоль изменять разного рода установки движка - -<b>Редакторы:</b> - - \link level_editor SXLevelEditor - редактор уровней \endlink \n - - \link material_editor SXMaterialEditor - редактор материалов \endlink \n - - \link particles_editor SXParticlesEditor - редактор партиклов \endlink \n - -\section dogma_engine Идеология движка -Основной технической идеей при разработке движка была идея о том что программист должен иметь контроль над объектами которыми он оперирует, НО этот контроль должен быть в меру. \n -Основной идеей предназначения служила и служит идея о том чтобы предоставляемый инструментарий мог полностью удовлетворять потребностям разработчика, без необходимости со стороны разработчика вникать в детали реализации, но чтобы этот инструментарий имел прозрачную, открытую, свободную, бесплатную лицензию, и разработчик мог спокойно податься в стихию сотворения своего мира. \n -Также главенствовал принцип разделения функционала на логические блоки (библиотеки) и после окончания разработки очередного блока он бы выносился в dll (с глаз долой). -Однако существенным дополнением являлась идея о том что библиотеки не должны ничего значть о равнозначных себе библиотеках в общей иерархии. -К примеру \ref sxgeom "библиотека статической геометрии и растительности" ничего не знает о \ref sxmtllight "библиотеке материалов", и последняя ничего не знает о первой, однако первая использует функции из второй посредством графического ядра, а вторая осуществляется настройку материалов перед рендером первой.\n -Немаловажным моментом являлся ориентир на гибкость. К примеру \ref sxgcore_redefinition_func "переопредляемые функции" в графическом ядре, позволяют настроить на свой лад рендер. \n -Ну и пожалуй самая главная идея заключается в полноценной возможности разработки игр с видом от первого лица, с настройкой/перестройкой "под себя" всего рендера. Также к приправе к этому мы руководствовались мыслью о том что скриптеры (коих не мало) могли бы вести разработку игры на своем (доступном им) уровне, со всеми возможностями движка. - -\section struct_engine Структура движка -Весь движок состоит из \ref general_info_libs "подсистем", которые в некоторых случаях являются ядрами. \n -Иерархия подсистем:\n -\- \ref sxcore\n -\-- \ref sxgcore\n -\--- \ref sxgeom\n -\--- \ref sxanim\n -\--- \ref sxmtllight\n -\--- \ref sxpp\n -\- \ref sxinput\n -Все библиотеки представлены файлами dll, что позволяет разделить функционал и реализацию. Также в большинстве случаев библиотеки могут быть вычленены из самого движка и могут использоваться автономно.\n -В большинстве случаев весь функционал библиотек предоставляется интерфейсом функций, а идентификация объектов числовая, по типу #ID. -Это позволяет не беспокоится о типах и о существовании объектов - об этом заботятся сами библиотеки. -*/ - -/*! \page std_doc Стандарт документирования -\tableofcontents -\section std_doc_common Общее -Дабы создать удобочитаемые комментрии, которые легко бы трансформировались в документацию был создан данный стандарт документирования, следование которому является обязательным. -Так как для документирования был выбран Doxygen, то все что касается документирования будет в контексте именно этой программы. \n -Для более чектого структурирования необходимо разделять весь код на логические звенья, которые могут быть представлены модулями/подмодулями и группами как в модулях так и вне их. - -\section style_doc Стиль документирования +*/ + +/*! \page info_engine Информация о движке SkyXEngine +\tableofcontents +\section ie_common Общее +\b SkyXEngine - движок для создания 3D игр с real-time рендером, использует технологии DirectX 9. \n +<small>Сразу уточнение, DirectX 9 мы используем в связи с личными предпочтениями, так как на наш взгляд эта технология является одной из лучших, хоть и считается устаревшей. +Все новое это забытое старое)) И как нам кажется ... нет ничего такого, чего нельзя было бы сделать на DirectX 9, но что можно сделать на другом GAPI, для создания игр любого жанра с real-time рендером. +Но это только точка зрения нашей команды и она может быть ошибочная. Однако в планах есть расширение поддерживаемых GAPI.</small> + +<b>Формирование уровня</b> осуществляется посредством: + - загрузки статических моделей формата dse, с их автоматическим разбиением на "куски рендера" как quad или octo дерево, возможны сохранение/загрузка в бинарный файл всей геометрии уровня + - генерации растительности по маске, возможны 2 вида: трава (чем дальше тем меньше размер объекта) и деревья (с возможностью загрузки лодов), возможны возможны сохранение/загрузка в бинарный файл всей растительности уровня. Ручная расстановка расстительности поддерживается. Редактирование поддерживается. + +<b>Освещение</b> представлено 3 видами источников света (опционально поддерживается генерация теней от каждого исчтоника света): + - глобальный (солнце), тени - PSSM + - локальный - точечный, тени - Cube Shadow Mapping + - локальный - направленный, тени - Shadow Mapping. + +HDR эффект присутсвует. + +<b>Система материалов</b> pbr, то есть построенная на физичеки корретных, но апроксимированных вычислениях. \n +Для формирования данных для освещения используется техника Deferred shading, что позволяет обрабатывать неограниченное количество источников света. \n +Поддерживаются отражения 2 видов: + - плоские (планарные) + - объемные (кубические). + +Поддерживается до 3 полупрозрачных поверхностей в кадре (пока только тестовый режим, в планах улучшения качества). \n +Поддерживаемые эффекты поверхностей: + - микрорельеф + - микрорельеф по маске (до 4 текстур) + - детальность + - детальность по маске (до 4 текстур) + - комбинированный микрорельеф с детальностью по маске (до 4 текстур) + - альфа тест + - просвечиваемость (для освещения тонких поверхностей, к примеру листвы и травы). + + Вся система материалов является открытой и практически любой функционал системы доступен для собственной интерпретации, посредством шейдеров. Имеется встроенный набор данных.\n + Поддерживаются различные пользовательские данные которые интерпретируются только создающим материалы. + Настрока физического материала доступна. + +<b>Постпроцесс</b> состоит из эффектов: + - черно-белое изображение + - эффект сепия + - коррекция изображения + - рендер солнца + - bloom + - lens flare, эффект восприятия яркого света линзами + - depth of field, глубина резкости + - linear fog, линейный туман + - space screen ambient occulusion, глобальное освещение (точнее затенение) в пространстве экрана + - motion blur, размытие в движении + - nfaa + - dlaa. + +<b>Декали</b> - следы от пуль, взрывов, трещины. Рисуются поверх основной геометрии. + +<b>Физика</b> - для симуляции физики используется физический движок Bullet. + +<b>Звуковой движок</b> поддерживает воспроизведение в пространстве и в фоне. Поддерживаемые форматы ogg, wav. Доступно создание инстансов без возможности управления. + +<b>Партиклы</b> с необходимым набором логики и с многочисленными и простыми настроками. + +<b>AI сетка</b> для навигации живых игровых объектов. + +<b>Игровой движок</b> - основа для построения игровой логики. Предоставляет набор игровых объектов и обеспечивает их взаимодействие. + +<b>Эффекты окружения</b> представлены фоновыми ambient звуками, погодой, определяемой для каждого уровня, с различными погодными эффектами. + +<b>Real-time конфигурация (cvars)</b> позволяет в режиме реального времени через консоль изменять разного рода установки движка + +<b>Редакторы:</b> + - \link level_editor SXLevelEditor - редактор уровней \endlink \n + - \link material_editor SXMaterialEditor - редактор материалов \endlink \n + - \link particles_editor SXParticlesEditor - редактор партиклов \endlink \n + +\section dogma_engine Идеология движка +Основной технической идеей при разработке движка была идея о том что программист должен иметь контроль над объектами которыми он оперирует, НО этот контроль должен быть в меру. \n +Основной идеей предназначения служила и служит идея о том чтобы предоставляемый инструментарий мог полностью удовлетворять потребностям разработчика, без необходимости со стороны разработчика вникать в детали реализации, но чтобы этот инструментарий имел прозрачную, открытую, свободную, бесплатную лицензию, и разработчик мог спокойно податься в стихию сотворения своего мира. \n +Также главенствовал принцип разделения функционала на логические блоки (библиотеки) и после окончания разработки очередного блока он бы выносился в dll (с глаз долой). +Однако существенным дополнением являлась идея о том что библиотеки не должны ничего значть о равнозначных себе библиотеках в общей иерархии. +К примеру \ref sxgeom "библиотека статической геометрии и растительности" ничего не знает о \ref sxmtllight "библиотеке материалов", и последняя ничего не знает о первой, однако первая использует функции из второй посредством графического ядра, а вторая осуществляется настройку материалов перед рендером первой.\n +Немаловажным моментом являлся ориентир на гибкость. К примеру \ref sxgcore_redefinition_func "переопредляемые функции" в графическом ядре, позволяют настроить на свой лад рендер. \n +Ну и пожалуй самая главная идея заключается в полноценной возможности разработки игр с видом от первого лица, с настройкой/перестройкой "под себя" всего рендера. Также к приправе к этому мы руководствовались мыслью о том что скриптеры (коих не мало) могли бы вести разработку игры на своем (доступном им) уровне, со всеми возможностями движка. + +\section struct_engine Структура движка +Весь движок состоит из \ref general_info_libs "подсистем", которые в некоторых случаях являются ядрами. \n +Иерархия подсистем:\n +\- \ref sxcore\n +\-- \ref sxgcore\n +\--- \ref sxgeom\n +\--- \ref sxanim\n +\--- \ref sxmtllight\n +\--- \ref sxpp\n +\- \ref sxinput\n +Все библиотеки представлены файлами dll, что позволяет разделить функционал и реализацию. Также в большинстве случаев библиотеки могут быть вычленены из самого движка и могут использоваться автономно.\n +В большинстве случаев весь функционал библиотек предоставляется интерфейсом функций, а идентификация объектов числовая, по типу #ID. +Это позволяет не беспокоится о типах и о существовании объектов - об этом заботятся сами библиотеки. +*/ + +/*! \page std_doc Стандарт документирования +\tableofcontents +\section std_doc_common Общее +Дабы создать удобочитаемые комментрии, которые легко бы трансформировались в документацию был создан данный стандарт документирования, следование которому является обязательным. +Так как для документирования был выбран Doxygen, то все что касается документирования будет в контексте именно этой программы. \n +Для более чектого структурирования необходимо разделять весь код на логические звенья, которые могут быть представлены модулями/подмодулями и группами как в модулях так и вне их. + +\section style_doc Стиль документирования QT стиль документирования (!) и QT_AUTOBRIEF - короткая документация до точки в любом комментарии, а после точки идет подробное документирование если надо.\n Возможные виды: <pre> //! документирование того что идет за этой строкой //!< документирование того что предшествовало данному комментарию / *! документирование того что идет за этой строкой * / -/ *!< документирование того что предшествовало данному комментарию * / -</pre> -<b>Примечание:</b> здесь и далее / * и * / комментарий без пробелов! - +/ *!< документирование того что предшествовало данному комментарию * / +</pre> +<b>Примечание:</b> здесь и далее / * и * / комментарий без пробелов! + \section style_desc_file Описание файла (обязательно для каждого документируемого файла) <pre> / *! \\file Описание файла -\* / -</pre> - +\* / +</pre> + \section style_modules Модули/подмодули <pre> / *! \\defgroup имя_модуля описание модуля \@{ \* / ... код модуля -//!\@} имя_модуля -</pre> -В случае если модуль является подмодулем другого модуля то после описания модуля необходимо добавить: -<pre> - \\ingroup имя_модуля_которому_будет_принадлежать_данный_модуль -</pre> -Окончание модуля может быть любым удобным, но только окончание модуля должно включать в себя имя модуля для которого написан конец. - +//!\@} имя_модуля +</pre> +В случае если модуль является подмодулем другого модуля то после описания модуля необходимо добавить: +<pre> + \\ingroup имя_модуля_которому_будет_принадлежать_данный_модуль +</pre> +Окончание модуля может быть любым удобным, но только окончание модуля должно включать в себя имя модуля для которого написан конец. + \section style_group Группа (вложенные группы не поддерживаются) <pre> / *! \\name название группы, оно также будет размещено в документации @@ -163,55 +163,55 @@ QT стиль документирования (!) и QT_AUTOBRIEF - корот //! \@{ ... все кроме классов //! \@} -</pre> - -\section style_ref Ссылки -Для лучшей навигации необходимо использовать ссылки, которые могут указывать на структурные единицы (модули/подмодули, страницы, секции) так и на код. -Пример ссылки на структурные единицы: -<pre> -Весь движок состоит из \\ref general_info_libs "подсистем". -</pre> -Или без указания имени ссылки: -<pre> -\\ref sxcore -</pre> - -Пример ссылки на код: -<pre> -\#SCore_Create -</pre> - -\section style_page Страницы -<pre> -/ *! \\page идентификатор_только_латиница Заголовок страницы -\\tableofcontents -Для того чтобы разделить на разделы можно использовать секции: -\\section style_page Создание страниц -\* / -</pre> - -\section style_list Списки -<pre> - \- первый элемент - \- второй элемент -</pre> - -\section style_extra Дополнительно -\\n - для новой строки \n -Также можно использовать html теги. \n -\\note - заметка \n -\\warning - предупреждение \n -\\todo - пометка о том что надо сделать \n -*/ - -//############################################################################# - -/*! \page engine_cvar Движковые квары -\tableofcontents - -\section engine_cvar_naming Правила именования -Все имена кваров пишутся только в нижнем регистре, в качестве пробела используется _ (нижний пробел). -Если квар является дефолтным, относительно него буду происходит расчеты либо действия, то тогда prefix_default_cvar. +</pre> + +\section style_ref Ссылки +Для лучшей навигации необходимо использовать ссылки, которые могут указывать на структурные единицы (модули/подмодули, страницы, секции) так и на код. +Пример ссылки на структурные единицы: +<pre> +Весь движок состоит из \\ref general_info_libs "подсистем". +</pre> +Или без указания имени ссылки: +<pre> +\\ref sxcore +</pre> + +Пример ссылки на код: +<pre> +\#SCore_Create +</pre> + +\section style_page Страницы +<pre> +/ *! \\page идентификатор_только_латиница Заголовок страницы +\\tableofcontents +Для того чтобы разделить на разделы можно использовать секции: +\\section style_page Создание страниц +\* / +</pre> + +\section style_list Списки +<pre> + \- первый элемент + \- второй элемент +</pre> + +\section style_extra Дополнительно +\\n - для новой строки \n +Также можно использовать html теги. \n +\\note - заметка \n +\\warning - предупреждение \n +\\todo - пометка о том что надо сделать \n +*/ + +//############################################################################# + +/*! \page engine_cvar Движковые квары +\tableofcontents + +\section engine_cvar_naming Правила именования +Все имена кваров пишутся только в нижнем регистре, в качестве пробела используется _ (нижний пробел). +Если квар является дефолтным, относительно него буду происходит расчеты либо действия, то тогда prefix_default_cvar. - r_ - все, что связано с рендером непосредственно - cl_ - игрок управление - phy_ - физика @@ -224,21 +224,21 @@ QT стиль документирования (!) и QT_AUTOBRIEF - корот - nav_ - навигация - snd_ - звуки - ed_ - для редакторов - - pt_ - партиклы - - \section engine_cvar_camera Камера - - \b r_default_fov дефолтный fov - - \b r_near ближняя плоскость отсечения - - \b r_far дальняя плоскость отсечения - -\section engine_cvar_window Окно - - \b r_win_width размер окна по горизонтали (в пикселях) - - \b r_win_height размер окна по вертикали (в пикселях) - - \b r_win_windowed режим рендера true - оконный, false - полноэкранный - - \b r_final_image тип финального (выводимого в окно рендера) изображения из перечисления DS_RT - - \b r_resize тип изменения размеров окан рендера из перечисления RENDER_RESIZE - -\section engine_cvar_pp Post process + - pt_ - партиклы + + \section engine_cvar_camera Камера + - \b r_default_fov дефолтный fov + - \b r_near ближняя плоскость отсечения + - \b r_far дальняя плоскость отсечения + +\section engine_cvar_window Окно + - \b r_win_width размер окна по горизонтали (в пикселях) + - \b r_win_height размер окна по вертикали (в пикселях) + - \b r_win_windowed режим рендера true - оконный, false - полноэкранный + - \b r_final_image тип финального (выводимого в окно рендера) изображения из перечисления DS_RT + - \b r_resize тип изменения размеров окан рендера из перечисления RENDER_RESIZE + +\section engine_cvar_pp Post process - \b pp_ssao установка качества ssao (0 - не рисовать, 1 - среднее, 2 - хорошее, 3 - высокое) - \b pp_bloom рисовать ли эффект bloom (true/false) - \b pp_lensflare true рисовать ли эффект lens flare (true/false) @@ -262,270 +262,271 @@ QT стиль документирования (!) и QT_AUTOBRIEF - корот - \b r_green_lod0 дистанция от наблюдателя на которой заканчивается нулевой лод растительности (он же лод травы), то есть дальность отрисовки травы (0,100) - \b r_green_lod1 дистанция от наблюдателя на которой заканчивается первый лод растительности (50,150) - \b r_green_less дистанция от наблюдателя c которой начнет уменьшаться трава (0,green_lod0) - - \section engine_cvar_texfilter Фильтрация текстур + + \section engine_cvar_texfilter Фильтрация текстур - \b r_texfilter_type тип фильтрации текстур, 0 - точечная, 1 - линейная, 2 - анизотропная - \b r_texfilter_max_anisotropy максимальное значение анизотропной фильтрации (если включена) [1,16] - - \b r_texfilter_max_miplevel какой mip уровень текстур использовать? 0 - самый высокий, 1 - ниже на один уровень и т.д. - - \b r_stats показывать ли статистику? 0 - нет, 1 - fps и игровое время, 2 - показать полностью - -\section engine_cvar_env Окружение - - \b env_default_rain_density коэфициент плотности дождя (0,1] - - \b env_default_thunderbolt могут ли воспроизводится эффекты молнии? - - \b env_weather_snd_volume громкость звуков погоды [0,1] - - \b env_ambient_snd_volume громкость фоновых звуков на уровне [0,1] - -\section engine_cvar_game Игра - - \b g_time_run запущено ли игрвоое время?" - - \b g_time_speed скорость/соотношение течения игрового времени - -//########################################################################## - -\page editors Редакторы -\link level_editor SXLevelEditor - редактор уровней \endlink \n -\link material_editor SXMaterialEditor - редактор материалов \endlink \n -\link particles_editor SXParticlesEditor - редактор партиклов \endlink \n -*/ - -//############################################################################# - -#ifndef __SKYXENGINE_H -#define __SKYXENGINE_H - -#define SKYXENGINE_VERSION "0.9.3" - -#include <windows.h> -#include <ctime> -#include <gdefines.h> -#include <common/array.h> -#include <common/string.h> -#include <fstream> - -//ЗАГРУЗКА БИБЛИОТЕК -//{ -#if defined(_DEBUG) -#pragma comment(lib, "sxcore_d.lib") -#else -#pragma comment(lib, "sxcore.lib") -#endif -#include <core/sxcore.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxinput_d.lib") -#else -#pragma comment(lib, "sxinput.lib") -#endif -#include <input/sxinput.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxscore_d.lib") -#else -#pragma comment(lib, "sxscore.lib") -#endif -#include <score/sxscore.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxgcore_d.lib") -#else -#pragma comment(lib, "sxgcore.lib") -#endif -#include <gcore/sxgcore.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxgeom_d.lib") -#else -#pragma comment(lib, "sxgeom.lib") -#endif -#include <geom/sxgeom.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxmtllight_d.lib") -#else -#pragma comment(lib, "sxmtllight.lib") -#endif -#include <mtllight/sxmtllight.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxparticles_d.lib") -#else -#pragma comment(lib, "sxparticles.lib") -#endif -#include <particles/sxparticles.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxpp_d.lib") -#else -#pragma comment(lib, "sxpp.lib") -#endif -#include <pp/sxpp.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxanim_d.lib") -#else -#pragma comment(lib, "sxanim.lib") -#endif -#include <anim/sxanim.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxphysics_d.lib") -#else -#pragma comment(lib, "sxphysics.lib") -#endif -#include <physics/sxphysics.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxaigrid_d.lib") -#else -#pragma comment(lib, "sxaigrid.lib") -#endif -#include <aigrid/sxaigrid.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxdecals_d.lib") -#else -#pragma comment(lib, "sxdecals.lib") -#endif -#include <decals/sxdecals.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxlevel_d.lib") -#else -#pragma comment(lib, "sxlevel.lib") -#endif -#include <level/sxlevel.h> - -#if defined(_DEBUG) -#pragma comment(lib, "sxgame_d.lib") -#else -#pragma comment(lib, "sxgame.lib") -#endif -#include <game/sxgame.h> - + - \b r_texfilter_max_miplevel какой mip уровень текстур использовать? 0 - самый высокий, 1 - ниже на один уровень и т.д. + - \b r_stats показывать ли статистику? 0 - нет, 1 - fps и игровое время, 2 - показать полностью + +\section engine_cvar_env Окружение + - \b env_default_rain_density коэфициент плотности дождя (0,1] + - \b env_default_thunderbolt могут ли воспроизводится эффекты молнии? + - \b env_weather_snd_volume громкость звуков погоды [0,1] + - \b env_ambient_snd_volume громкость фоновых звуков на уровне [0,1] + +\section engine_cvar_game Игра + - \b g_time_run запущено ли игрвоое время?" + - \b g_time_speed скорость/соотношение течения игрового времени + +//########################################################################## + +\page editors Редакторы +\link level_editor SXLevelEditor - редактор уровней \endlink \n +\link material_editor SXMaterialEditor - редактор материалов \endlink \n +\link particles_editor SXParticlesEditor - редактор партиклов \endlink \n +*/ + +//############################################################################# + +#ifndef __SKYXENGINE_H +#define __SKYXENGINE_H + +#define SKYXENGINE_VERSION "0.9.3" + +#include <vld.h> +#include <windows.h> +#include <ctime> +#include <gdefines.h> +#include <common/array.h> +#include <common/string.h> +#include <fstream> + +//ЗАГРУЗКА БИБЛИОТЕК +//{ +#if defined(_DEBUG) +#pragma comment(lib, "sxcore_d.lib") +#else +#pragma comment(lib, "sxcore.lib") +#endif +#include <core/sxcore.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxinput_d.lib") +#else +#pragma comment(lib, "sxinput.lib") +#endif +#include <input/sxinput.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxscore_d.lib") +#else +#pragma comment(lib, "sxscore.lib") +#endif +#include <score/sxscore.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxgcore_d.lib") +#else +#pragma comment(lib, "sxgcore.lib") +#endif +#include <gcore/sxgcore.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxgeom_d.lib") +#else +#pragma comment(lib, "sxgeom.lib") +#endif +#include <geom/sxgeom.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxmtllight_d.lib") +#else +#pragma comment(lib, "sxmtllight.lib") +#endif +#include <mtllight/sxmtllight.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxparticles_d.lib") +#else +#pragma comment(lib, "sxparticles.lib") +#endif +#include <particles/sxparticles.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxpp_d.lib") +#else +#pragma comment(lib, "sxpp.lib") +#endif +#include <pp/sxpp.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxanim_d.lib") +#else +#pragma comment(lib, "sxanim.lib") +#endif +#include <anim/sxanim.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxphysics_d.lib") +#else +#pragma comment(lib, "sxphysics.lib") +#endif +#include <physics/sxphysics.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxaigrid_d.lib") +#else +#pragma comment(lib, "sxaigrid.lib") +#endif +#include <aigrid/sxaigrid.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxdecals_d.lib") +#else +#pragma comment(lib, "sxdecals.lib") +#endif +#include <decals/sxdecals.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxlevel_d.lib") +#else +#pragma comment(lib, "sxlevel.lib") +#endif +#include <level/sxlevel.h> + +#if defined(_DEBUG) +#pragma comment(lib, "sxgame_d.lib") +#else +#pragma comment(lib, "sxgame.lib") +#endif +#include <game/sxgame.h> + #if defined(SX_LEVEL_EDITOR) || defined(SX_MATERIAL_EDITOR) || defined(SX_PARTICLES_EDITOR) -#if defined(_DEBUG) -#pragma comment(lib, "sxguiwinapi_d.lib") -#else -#pragma comment(lib, "sxguiwinapi.lib") -#endif -#include <sxguiwinapi/sxgui.h> -#endif - -#if defined(_DEBUG) -#pragma comment(lib, "sxrender_d.lib") -#else -#pragma comment(lib, "sxrender.lib") -#endif -#include <render/sxrender.h> - -//} - -//############################################################################# - -#if defined(SX_GAME) -#include <SkyXEngine_Build/resource.h> -#endif - -#if defined(SX_LEVEL_EDITOR) -#include <SXLevelEditor/resource.h> -#include <SXLevelEditor/level_editor.h> -#endif - -#if defined(SX_MATERIAL_EDITOR) -#include <sxmaterialeditor/resource.h> -#include <sxmaterialeditor/material_editor.h> -#endif - -#if defined(SX_PARTICLES_EDITOR) -#include <sxparticleseditor/resource.h> -#include <sxparticleseditor/particles_editor.h> -#endif - -//############################################################################# - -/*! \defgroup skyxengine Функции и данные движка -@{*/ - -//! инициализация движка -void SkyXEngine_Init(HWND hWnd3D = 0, HWND hWndParent3D = 0); - -//! инициализация путей в регистрах -void SkyXEngine_InitPaths(); - -//! создание кваров и загрузка файлов настроек -void SkyXEngine_CreateLoadCVar(); - -//! обработчик для окна рендера -LRESULT CALLBACK SkyXEngine_WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam); - -//! создание окна рендера -HWND SkyXEngine_CreateWindow(const char *szName, const char *szCaption, int iWidth, int iHeight); - -//************************************************************************** - -//! перебор всех окон процесса для их сворачивания -BOOL CALLBACK SkyXEngine_EnumWindowsProc(HWND hwnd, LPARAM lParam); - -//! обработка ошибки -void SkyXEngine_HandlerError(const char *szFormat, ...); - -//! инициализация потока ведения лога -void SkyXEngine_InitOutLog(); - -//! функция ведения лога и обработки сообщений -void SkyXEngine_PrintfLog(int level, const char *szFormat, ...); - -//************************************************************************** - -//! кадр -void SkyXEngine_Frame(DWORD timeDelta); - -//! обновление данных кваром (реакция на обновление) -void SkyXEngind_UpdateDataCVar(); - -//! запуск основного цикла обработки -int SkyXEngine_CycleMain(); - -//! уничтожение данных движка, освобождение памяти +#if defined(_DEBUG) +#pragma comment(lib, "sxguiwinapi_d.lib") +#else +#pragma comment(lib, "sxguiwinapi.lib") +#endif +#include <sxguiwinapi/sxgui.h> +#endif + +#if defined(_DEBUG) +#pragma comment(lib, "sxrender_d.lib") +#else +#pragma comment(lib, "sxrender.lib") +#endif +#include <render/sxrender.h> + +//} + +//############################################################################# + +#if defined(SX_GAME) +#include <SkyXEngine_Build/resource.h> +#endif + +#if defined(SX_LEVEL_EDITOR) +#include <SXLevelEditor/resource.h> +#include <SXLevelEditor/level_editor.h> +#endif + +#if defined(SX_MATERIAL_EDITOR) +#include <sxmaterialeditor/resource.h> +#include <sxmaterialeditor/material_editor.h> +#endif + +#if defined(SX_PARTICLES_EDITOR) +#include <sxparticleseditor/resource.h> +#include <sxparticleseditor/particles_editor.h> +#endif + +//############################################################################# + +/*! \defgroup skyxengine Функции и данные движка +@{*/ + +//! инициализация движка +void SkyXEngine_Init(HWND hWnd3D = 0, HWND hWndParent3D = 0); + +//! инициализация путей в регистрах +void SkyXEngine_InitPaths(); + +//! создание кваров и загрузка файлов настроек +void SkyXEngine_CreateLoadCVar(); + +//! обработчик для окна рендера +LRESULT CALLBACK SkyXEngine_WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam); + +//! создание окна рендера +HWND SkyXEngine_CreateWindow(const char *szName, const char *szCaption, int iWidth, int iHeight); + +//************************************************************************** + +//! перебор всех окон процесса для их сворачивания +BOOL CALLBACK SkyXEngine_EnumWindowsProc(HWND hwnd, LPARAM lParam); + +//! обработка ошибки +void SkyXEngine_HandlerError(const char *szFormat, ...); + +//! инициализация потока ведения лога +void SkyXEngine_InitOutLog(); + +//! функция ведения лога и обработки сообщений +void SkyXEngine_PrintfLog(int level, const char *szFormat, ...); + +//************************************************************************** + +//! кадр +void SkyXEngine_Frame(DWORD timeDelta); + +//! обновление данных кваром (реакция на обновление) +void SkyXEngind_UpdateDataCVar(); + +//! запуск основного цикла обработки +int SkyXEngine_CycleMain(); + +//! уничтожение данных движка, освобождение памяти void SkyXEngine_Kill(); //************************************************************************** -/*! \name skyxengine_preview_wnd preview_wnd - Функции превью окна движка +/*! \name skyxengine_preview_wnd preview_wnd - Функции превью окна движка @{*/ //! обработчик для превьюокна LRESULT CALLBACK SkyXEngine_PreviewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - -//! создание превью окна -void SkyXEngine_PreviewCreate(); - -//! уничтожение превью окна -void SkyXEngine_PreviewKill(); - -//!@} - -//************************************************************************** - -/*! \name skyxengine_redefined_func redefined_func - Функции обертки, для передачи графическому ядру для замены стандартных + +//! создание превью окна +void SkyXEngine_PreviewCreate(); + +//! уничтожение превью окна +void SkyXEngine_PreviewKill(); + +//!@} + +//************************************************************************** + +/*! \name skyxengine_redefined_func redefined_func - Функции обертки, для передачи графическому ядру для замены стандартных @{*/ -//! функция отрисовки, в данной версии не назначается -void SkyXEngine_RFuncDIP(UINT type_primitive, long base_vertexIndex, UINT min_vertex_index, UINT num_vertices, UINT start_index, UINT prim_count); - -//! функция установки материала по id, world - мировая матрица -void SkyXEngine_RFuncMtlSet(ID id, float4x4* world); - -//! функция загрузки материала -ID SkyXEngine_RFuncMtlLoad(const char* name, int mtl_type); - -//! просчет физики для квада аи сетки -bool SkyXEngine_RFuncAIQuadPhyNavigate(float3_t * pos); - -//! просчет столкновения частицы с миром -bool SkyXEngine_RFuncParticlesPhyCollision(const float3 * lastpos, const float3* nextpos, float3* coll_pos, float3* coll_nrm); - -//!@} - -//!@} skyxengine - +//! функция отрисовки, в данной версии не назначается +void SkyXEngine_RFuncDIP(UINT type_primitive, long base_vertexIndex, UINT min_vertex_index, UINT num_vertices, UINT start_index, UINT prim_count); + +//! функция установки материала по id, world - мировая матрица +void SkyXEngine_RFuncMtlSet(ID id, float4x4* world); + +//! функция загрузки материала +ID SkyXEngine_RFuncMtlLoad(const char* name, int mtl_type); + +//! просчет физики для квада аи сетки +bool SkyXEngine_RFuncAIQuadPhyNavigate(float3_t * pos); + +//! просчет столкновения частицы с миром +bool SkyXEngine_RFuncParticlesPhyCollision(const float3 * lastpos, const float3* nextpos, float3* coll_pos, float3* coll_nrm); + +//!@} + +//!@} skyxengine + #endif \ No newline at end of file diff --git a/source/SkyXEngine_Build/SkyXEngine_Build.cpp b/source/SkyXEngine_Build/SkyXEngine_Build.cpp index af579d6be24a02613cd8ef75fb351fda860d0dc2..9b3747b761b2f18b98bb777e2705692d9f199252 100644 --- a/source/SkyXEngine_Build/SkyXEngine_Build.cpp +++ b/source/SkyXEngine_Build/SkyXEngine_Build.cpp @@ -7,6 +7,7 @@ See the license in LICENSE #define _CRT_SECURE_NO_WARNINGS #include <SkyXEngine.h> +//#include <common/string_func.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { diff --git a/source/core/concmd.cpp b/source/core/concmd.cpp index 0505613bf05d6a442cb54b9127811566f4acd00e..83d5dd55aeb288ff97e6d2ae6cc5bc6270d5486d 100644 --- a/source/core/concmd.cpp +++ b/source/core/concmd.cpp @@ -623,9 +623,9 @@ bool CommandConnect() struct addrinfo *result = NULL, *ptr = NULL, hints; - char recvbuf[2048]; + int iResult; - int recvbuflen = sizeof(recvbuf); + // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); diff --git a/source/core/sxcore.cpp b/source/core/sxcore.cpp index 81c9cdb7c3cb01445f1c5424923428938e3f81bd..46c3c26a22e958f9c65724c3f5df24d36ee4f051 100644 --- a/source/core/sxcore.cpp +++ b/source/core/sxcore.cpp @@ -86,7 +86,7 @@ SX_LIB_API UINT Core_0GetTimeLastModify(const char *szPath) if (hFile == INVALID_HANDLE_VALUE) return 0; - SYSTEMTIME stUTC, stLocal; + SYSTEMTIME stUTC; FILETIME ftCreate, ftAccess, ftWrite; GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite); FileTimeToSystemTime(&ftWrite, &stUTC); diff --git a/source/game/BaseTool.cpp b/source/game/BaseTool.cpp index 13eab5f9249adb5262a1ed6708675f98b3f88349..8727766bc58c0af04dec11b98a6c5acb3d2258e9 100644 --- a/source/game/BaseTool.cpp +++ b/source/game/BaseTool.cpp @@ -84,11 +84,11 @@ void CBaseTool::onPostLoad() if(m_szPrimaryActionSound[0]) { - m_iSoundAction1 = SSCore_SndCreate3dInst(m_szPrimaryActionSound, false, 0, 100); + m_iSoundAction1 = SSCore_SndCreate3dInst(m_szPrimaryActionSound, SX_SOUND_CHANNEL_GAME, 100); } if(m_szSecondaryActionSound[0]) { - m_iSoundAction2 = SSCore_SndCreate3dInst(m_szSecondaryActionSound, false, 0, 100); + m_iSoundAction2 = SSCore_SndCreate3dInst(m_szSecondaryActionSound, SX_SOUND_CHANNEL_GAME, 100); } if(m_szPrimaryActionMuzzleflash[0]) { @@ -122,7 +122,7 @@ void CBaseTool::primaryAction(BOOL st) } if(ID_VALID(m_iSoundAction1)) { - SSCore_SndInstancePlay3d(m_iSoundAction1, &getPos()); + SSCore_SndInstancePlay3d(m_iSoundAction1, false, false, &getPos()); } //((CPlayer*)m_pOwner)->is diff --git a/source/game/BaseWeapon.cpp b/source/game/BaseWeapon.cpp index 9dc7dd01ef53a8ad03e6b1d9b8b7ef170ba8cb74..1a60954b21cfc19b0d80d72e01097debfff4954f 100644 --- a/source/game/BaseWeapon.cpp +++ b/source/game/BaseWeapon.cpp @@ -121,27 +121,27 @@ void CBaseWeapon::onPostLoad() if(m_szSndDraw[0]) { - m_idSndDraw = SSCore_SndCreate3dInst(m_szSndDraw, false, 0, 100); + m_idSndDraw = SSCore_SndCreate3dInst(m_szSndDraw, SX_SOUND_CHANNEL_GAME, 100); } if(m_szSndHolster[0]) { - m_idSndHolster = SSCore_SndCreate3dInst(m_szSndHolster, false, 0, 100); + m_idSndHolster = SSCore_SndCreate3dInst(m_szSndHolster, SX_SOUND_CHANNEL_GAME, 100); } if(m_szSndShoot[0]) { - m_idSndShoot = SSCore_SndCreate3dInst(m_szSndShoot, false, 0, 100); + m_idSndShoot = SSCore_SndCreate3dInst(m_szSndShoot, SX_SOUND_CHANNEL_GAME, 100); } if(m_szSndEmpty[0]) { - m_idSndEmpty = SSCore_SndCreate3dInst(m_szSndEmpty, false, 0, 100); + m_idSndEmpty = SSCore_SndCreate3dInst(m_szSndEmpty, SX_SOUND_CHANNEL_GAME, 100); } if(m_szSndReload[0]) { - m_idSndReload = SSCore_SndCreate3dInst(m_szSndReload, false, 0, 100); + m_idSndReload = SSCore_SndCreate3dInst(m_szSndReload, SX_SOUND_CHANNEL_GAME, 100); } if(m_szSndSwitch[0]) { - m_idSndSwitch = SSCore_SndCreate3dInst(m_szSndSwitch, false, 0, 100); + m_idSndSwitch = SSCore_SndCreate3dInst(m_szSndSwitch, SX_SOUND_CHANNEL_GAME, 100); } } @@ -199,7 +199,7 @@ void CBaseWeapon::primaryAction(BOOL st) } if(ID_VALID(m_iSoundAction1)) { - SSCore_SndInstancePlay3d(m_iSoundAction1, &getPos()); + SSCore_SndInstancePlay3d(m_iSoundAction1, false, false, &getPos()); } //((CPlayer*)m_pOwner)->is @@ -258,7 +258,7 @@ void CBaseWeapon::reload() playAnimation("reload"); if(ID_VALID(m_idSndReload)) { - SSCore_SndInstancePlay3d(m_idSndReload, &getPos()); + SSCore_SndInstancePlay3d(m_idSndReload, false, false, &getPos()); } } } @@ -270,7 +270,7 @@ void CBaseWeapon::setFireMode(FIRE_MODE mode) m_fireMode = mode; if(ID_VALID(m_idSndReload)) { - SSCore_SndInstancePlay3d(m_idSndSwitch, &getPos()); + SSCore_SndInstancePlay3d(m_idSndSwitch, false, false, &getPos()); } } } diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp index 7e8544891f1d71cbbf23a70cba63e1f960c444fd..278467beb049fb12996f4b18b3d7cb4bd5e0936c 100644 --- a/source/game/GameData.cpp +++ b/source/game/GameData.cpp @@ -126,7 +126,7 @@ void GameData::playFootstepSound(MTLTYPE_PHYSIC mtl_type, const float3 &f3Pos) return; } ID idSound = m_pidFootstepSound[mtl_type][rand() % iCount]; - SSCore_SndInstancePlay3d(idSound, (float3*)&f3Pos); + SSCore_SndInstancePlay3d(idSound, false, false, (float3*)&f3Pos); } void GameData::loadFoostepsSounds() @@ -173,7 +173,7 @@ void GameData::loadFoostepsSounds() m_pidFootstepSound[i] = jl ? new ID[jl] : NULL; for(int j = 0; j < jl; ++j) { - m_pidFootstepSound[i][j] = SSCore_SndCreate3dInst(paSounds[0][j], false, 0, 100); + m_pidFootstepSound[i][j] = SSCore_SndCreate3dInst(paSounds[0][j], SX_SOUND_CHANNEL_GAME, 100); } } } diff --git a/source/game/NPCZombie.cpp b/source/game/NPCZombie.cpp index d4ccd413c81c8caca46baf5b58b87017f1089302..e9e647b0e4ab9e989c328f220b64425a6a9c3f9d 100644 --- a/source/game/NPCZombie.cpp +++ b/source/game/NPCZombie.cpp @@ -24,9 +24,9 @@ CNPCZombie::CNPCZombie(CEntityManager * pMgr) : m_fSpeedWalk = 0.07f; m_fSpeedRun = 0.12f; - m_idSndIdle = SSCore_SndCreate3d("mobs/zombie/zombie_idle_16.ogg", false, 0, 30); - m_idSndIdle2 = SSCore_SndCreate3d("mobs/zombie/zombie_idle_17.ogg", false, 0, 30); - m_idSndDeath = SSCore_SndCreate3d("mobs/zombie/zombie_die_1.ogg", false, 0, 45); + m_idSndIdle = SSCore_SndCreate3d("mobs/zombie/zombie_idle_16.ogg", SX_SOUND_CHANNEL_GAME, 0, 30); + m_idSndIdle2 = SSCore_SndCreate3d("mobs/zombie/zombie_idle_17.ogg", SX_SOUND_CHANNEL_GAME, 0, 30); + m_idSndDeath = SSCore_SndCreate3d("mobs/zombie/zombie_die_1.ogg", SX_SOUND_CHANNEL_GAME, 0, 45); } CNPCZombie::~CNPCZombie() @@ -38,9 +38,9 @@ void CNPCZombie::onSync() { BaseClass::onSync(); - SSCore_SndPosWSet(m_idSndIdle, &getPos()); - SSCore_SndPosWSet(m_idSndIdle2, &getPos()); - SSCore_SndPosWSet(m_idSndDeath, &getPos()); + SSCore_SndSetPosWorld(m_idSndIdle, &getPos()); + SSCore_SndSetPosWorld(m_idSndIdle2, &getPos()); + SSCore_SndSetPosWorld(m_idSndDeath, &getPos()); //если здоровье меньше нуля if (m_fHealth < 0.0f) diff --git a/source/gcore/shader.cpp b/source/gcore/shader.cpp index e81b4e176584bb24b3b2a0db013b266ad4c7c9ab..2de55a6e47aa6a1dbd925c2a15b08685a631f9f2 100644 --- a/source/gcore/shader.cpp +++ b/source/gcore/shader.cpp @@ -616,6 +616,7 @@ void CShaderManager::allLoad() if (m_aVS.size() == m_iLastAllLoadVS || m_aPS.size() == m_iLastAllLoadPS) return; + DWORD dwTime = GetTickCount(); LibReport(REPORT_MSG_LEVEL_NOTICE, "load shaders ...\n"); for (int i = 0, il = m_aVS.size(); i < il; ++i) @@ -639,7 +640,7 @@ void CShaderManager::allLoad() m_iLastAllLoadVS = m_aVS.size(); m_iLastAllLoadPS = m_aPS.size(); - LibReport(REPORT_MSG_LEVEL_NOTICE, "all loaded shaders\n"); + LibReport(REPORT_MSG_LEVEL_NOTICE, "all loaded shaders, time %d\n", GetTickCount() - dwTime); } void CShaderManager::update(SHADER_TYPE type_shader, const char *szName) diff --git a/source/gcore/sxgcore.cpp b/source/gcore/sxgcore.cpp index 6905957b693718b6a79b03aa8f86a5afef227317..01ed825cc6c21edbc6be29c7f49b33b52b5cdd58 100644 --- a/source/gcore/sxgcore.cpp +++ b/source/gcore/sxgcore.cpp @@ -457,7 +457,7 @@ SX_LIB_API ID SGCore_ShaderLoad(SHADER_TYPE type_shader, const char *szPath, con SX_LIB_API void SGCore_ShaderAllLoad() { - SG_PRECOND(); + SG_PRECOND(_VOID); return g_pManagerShaders->allLoad(); } diff --git a/source/gdefines.h b/source/gdefines.h index f5c235178c384eaa4b6c2845eea9adffeec854a8..a49977adf08e37e81ac0fa75f5f7c1b95ddcd122 100644 --- a/source/gdefines.h +++ b/source/gdefines.h @@ -103,6 +103,12 @@ struct IBaseObject #define CONFIG_SECTION_MAX_LEN 64 /*!< максимальная длина секции конфигурационного файла */ //!@} +/*! звуковой канал самой игры */ +#define SX_SOUND_CHANNEL_GAME 0 + +/*! звуковой канал главного меню */ +#define SX_SOUND_CHANNEL_MAIN_MENU 1 + /*! Пустые дефайны для визуальной идентификации аргументов функций @{ */ diff --git a/source/geom/green.cpp b/source/geom/green.cpp index ddf5720563f72f2e6ffc3ca1d7723cb9619045e7..5df2543a36e657a6ea100c0e2da3ee28740335ca 100644 --- a/source/geom/green.cpp +++ b/source/geom/green.cpp @@ -1871,7 +1871,6 @@ bool CGreen::traceBeam(const float3* start, const float3* dir, float3* _res, ID* return false; SXTriangle tmptri; - float dist; bool tmpiscom = true; float3 ip; float3 res; @@ -1955,7 +1954,6 @@ bool CGreen::traceBeam(const float3* start, const float3* dir, float3* _res, ID* void CGreen::getPartBB(float3* bbmin, float3 * bbmax, CSegment** arrsplits, int *count, CSegment* comsegment, ID curr_splits_ids_render) { float3 min,max; - float radius; comsegment->m_pBoundVolumeP->getMinMax(&min, &max); if (comsegment->m_iCountObj > 0 && SGCore_0InretsectBox(bbmin, bbmax, &min, &max)) diff --git a/source/geom/static_geom.cpp b/source/geom/static_geom.cpp index 42b1ee3d74c7dab91c64a2bc8185ff7f3b7f8bbe..3f69191926a9744e3974c29a98b9315b2d83dc7c 100644 --- a/source/geom/static_geom.cpp +++ b/source/geom/static_geom.cpp @@ -2959,7 +2959,6 @@ void CStaticGeom::applyTransform(ID id) applyTransformLod(id); vertex_static* pData; - float3_t* pData2; int idgroup; int idbuff; @@ -3298,7 +3297,6 @@ bool CStaticGeom::traceBeam(const float3* start, const float3* dir, float3* _res return false; SXTriangle tmptri; - float dist; bool tmpiscom = true; float3 ip; float3 res; diff --git a/source/level/AmbientSounds.cpp b/source/level/AmbientSounds.cpp index 3932a81b637e77bec9283218279e6d921a5acabe..055437021daba20be5b4c0da767cf9877da4e05a 100644 --- a/source/level/AmbientSounds.cpp +++ b/source/level/AmbientSounds.cpp @@ -19,7 +19,7 @@ CAmbientSounds::~CAmbientSounds() void CAmbientSounds::add(const char *szPath) { - ID id = SSCore_SndCreate2d(szPath); + ID id = SSCore_SndCreate2d(szPath, SX_SOUND_CHANNEL_GAME); if (id >= 0) m_aIDSnds.push_back(id); } @@ -28,7 +28,7 @@ void CAmbientSounds::get(ID id, char *szPath) { if (id >= 0 && id < m_aIDSnds.size()) { - SSCore_SndFileGet(m_aIDSnds[id], szPath); + SSCore_SndGetFile(m_aIDSnds[id], szPath); } } @@ -51,7 +51,7 @@ void CAmbientSounds::play() { if (m_iPlayingLast >= 0 && m_iPlayingLast < m_aIDSnds.size()) { - SSCore_SndVolumeSet(m_aIDSnds[m_iPlayingLast], 100); + SSCore_SndSetVolume(m_aIDSnds[m_iPlayingLast], 100); SSCore_SndPlay(m_aIDSnds[m_iPlayingLast]); m_isPlaying = true; } @@ -65,14 +65,14 @@ void CAmbientSounds::update() static const float * env_ambient_snd_volume = GET_PCVAR_FLOAT("env_ambient_snd_volume"); static float env_ambient_snd_volume_old = 1.f; - if (SSCore_SndStateGet(m_aIDSnds[m_iPlayingLast]) != SOUND_OBJSTATE_PLAY) + if (SSCore_SndGetState(m_aIDSnds[m_iPlayingLast]) != SOUND_OBJSTATE_PLAY) { if (m_iPlayingLast + 1 < m_aIDSnds.size()) ++m_iPlayingLast; else m_iPlayingLast = 0; - SSCore_SndVolumeSet(m_aIDSnds[m_iPlayingLast], env_ambient_snd_volume_old*100.f); + SSCore_SndSetVolume(m_aIDSnds[m_iPlayingLast], env_ambient_snd_volume_old*100.f); SSCore_SndPlay(m_aIDSnds[m_iPlayingLast]); } @@ -80,7 +80,7 @@ void CAmbientSounds::update() { env_ambient_snd_volume_old = *env_ambient_snd_volume; if (m_iPlayingLast >= 0) - SSCore_SndVolumeSet(m_aIDSnds[m_iPlayingLast], env_ambient_snd_volume_old*100.f); + SSCore_SndSetVolume(m_aIDSnds[m_iPlayingLast], env_ambient_snd_volume_old*100.f); } } diff --git a/source/level/weather.cpp b/source/level/weather.cpp index 85bd30871b6469a51c7b4ec7aa06a8dec843e92a..5fb9ccb16dc1c8e4156fad25e136dfa775c29d8f 100644 --- a/source/level/weather.cpp +++ b/source/level/weather.cpp @@ -77,7 +77,7 @@ void CWeatherRndSnd::addSound(const char *szPath) if (isunic) { - ID tmpid = SSCore_SndCreate2d(szPath); + ID tmpid = SSCore_SndCreate2d(szPath, SX_SOUND_CHANNEL_GAME); m_aArrSnds.push_back(CSnd(szPath, tmpid)); m_aCurrSndIDs.push_back(tmpid); } @@ -100,13 +100,13 @@ void CWeatherRndSnd::update() if((int)m_aCurrSndIDs.size() > tmpkeysnd && m_aCurrSndIDs[tmpkeysnd] && m_aCurrSndIDs[tmpkeysnd] >= 0) { m_idCurrPlay = m_aCurrSndIDs[tmpkeysnd]; - SSCore_SndPosCurrSet(m_idCurrPlay, 0); + SSCore_SndSetPosPlay(m_idCurrPlay, 0); int tmprndvol = (rand() % (m_iVolumeE - m_iVolumeB)) + m_iVolumeB; - SSCore_SndVolumeSet(m_idCurrPlay, (long)(env_weather_snd_volume ? (float)tmprndvol * (*env_weather_snd_volume) : tmprndvol), SOUND_VOL_PCT); + SSCore_SndSetVolume(m_idCurrPlay, ((float)(env_weather_snd_volume ? (float)tmprndvol * (*env_weather_snd_volume) : tmprndvol))*0.01f); SSCore_SndPlay(m_idCurrPlay); DWORD tmprnd = (rand() % (m_ulPeriodE - m_ulPeriodB)) + m_ulPeriodB; - m_ulNextPlay = TimeGetMls(Core_RIntGet(G_RI_INT_TIMER_RENDER)) + tmprnd + ((SSCore_SndLengthSecGet(m_idCurrPlay) + 1) * 1000); + m_ulNextPlay = TimeGetMls(Core_RIntGet(G_RI_INT_TIMER_RENDER)) + tmprnd + ((SSCore_SndGetLengthSec(m_idCurrPlay) + 1) * 1000); } } } @@ -118,7 +118,7 @@ void CWeatherRndSnd::play() m_isPlaying = true; - if (m_idCurrPlay >= 0 && SSCore_SndStateGet(m_idCurrPlay) == SOUND_OBJSTATE_PAUSE) + if (m_idCurrPlay >= 0 && SSCore_SndGetState(m_idCurrPlay) == SOUND_OBJSTATE_PAUSE) SSCore_SndPlay(m_idCurrPlay); } @@ -129,7 +129,7 @@ void CWeatherRndSnd::pause() m_isPlaying = false; - if (m_idCurrPlay >= 0 && SSCore_SndStateGet(m_idCurrPlay) == SOUND_OBJSTATE_PLAY) + if (m_idCurrPlay >= 0 && SSCore_SndGetState(m_idCurrPlay) == SOUND_OBJSTATE_PLAY) SSCore_SndPlay(SOUND_OBJSTATE_PAUSE); } @@ -176,8 +176,8 @@ CWeather::CWeather() m_idLightThunderbolt = SML_LigthsCreatePoint(&float3(0, 0, 0), 200, &float3(1, 1, 1), false, true); SML_LigthsSetEnable(m_idLightThunderbolt, false); - m_idSndRain = SSCore_SndCreate2d("nature/rain.ogg",true); - m_idSndThunder = SSCore_SndCreate2d("nature/thunder.ogg"); + m_idSndRain = SSCore_SndCreate2d("nature/rain.ogg", SX_SOUND_CHANNEL_GAME, true); + m_idSndThunder = SSCore_SndCreate2d("nature/thunder.ogg", SX_SOUND_CHANNEL_GAME); m_fRainVolume = 0; } @@ -646,8 +646,8 @@ void CWeather::update() SPE_EmitterSet(m_idEffRain, 0, ReCreateCount, env_default_rain_density_old * m_aTimeSections[m_iSectionCurr].m_DataSection.m_fRainDensity * float(WEATHER_RAIN_RECREATE_COUNT)); SPE_EffectEnableSet(m_idEffRain, true); - SSCore_SndPosCurrSet(m_idSndRain, 0); - SSCore_SndVolumeSet(m_idSndRain, 0, SOUND_VOL_PCT); + SSCore_SndSetPosPlay(m_idSndRain, 0); + SSCore_SndSetVolume(m_idSndRain, 0); if (m_isPlaying) SSCore_SndPlay(m_idSndRain); @@ -780,8 +780,8 @@ void CWeather::update() } else { - SSCore_SndPosCurrSet(m_idSndThunder, 0); - SSCore_SndVolumeSet(m_idSndThunder, (env_weather_snd_volume ? (*env_weather_snd_volume) : 1.f) * 100.f, SOUND_VOL_PCT); + SSCore_SndSetPosPlay(m_idSndThunder, 0); + SSCore_SndSetVolume(m_idSndThunder, (env_weather_snd_volume ? (*env_weather_snd_volume) : 1.f)); if (m_isPlaying) SSCore_SndPlay(m_idSndThunder); @@ -806,8 +806,8 @@ void CWeather::update() SML_LigthsSetEnable(m_idLightThunderbolt, false); //и заодно проиграть звук молнии - SSCore_SndPosCurrSet(m_idSndThunder, 0); - SSCore_SndVolumeSet(m_idSndThunder, clampf(m_fRainVolume*2.f*100.f,0.f,100.f), SOUND_VOL_PCT); + SSCore_SndSetPosPlay(m_idSndThunder, 0); + SSCore_SndSetVolume(m_idSndThunder, clampf(m_fRainVolume*2.f, 0.f, 1.f)); if (m_isPlaying) SSCore_SndPlay(m_idSndThunder); @@ -859,7 +859,7 @@ void CWeather::updateRainSound() } m_fRainVolume /= tmpcount / 4; - SSCore_SndVolumeSet(m_idSndRain, (env_weather_snd_volume ? (*env_weather_snd_volume) : 1.f) * m_fRainVolume * 100.f, SOUND_VOL_PCT); + SSCore_SndSetVolume(m_idSndRain, (env_weather_snd_volume ? (*env_weather_snd_volume) : 1.f) * m_fRainVolume); } float CWeather::getCurrRainDensity() @@ -878,10 +878,10 @@ void CWeather::sndPlay() m_isPlaying = true; m_RndSnd.play(); - if (m_idSndRain >= 0 && SSCore_SndStateGet(m_idSndRain) == SOUND_OBJSTATE_PAUSE) + if (m_idSndRain >= 0 && SSCore_SndGetState(m_idSndRain) == SOUND_OBJSTATE_PAUSE) SSCore_SndPlay(m_idSndRain); - if (m_idSndThunder >= 0 && SSCore_SndStateGet(m_idSndThunder) == SOUND_OBJSTATE_PAUSE) + if (m_idSndThunder >= 0 && SSCore_SndGetState(m_idSndThunder) == SOUND_OBJSTATE_PAUSE) SSCore_SndPlay(m_idSndThunder); } @@ -893,10 +893,10 @@ void CWeather::sndPause() m_isPlaying = false; m_RndSnd.pause(); - if (m_idSndRain >= 0 && SSCore_SndStateGet(m_idSndRain) == SOUND_OBJSTATE_PLAY) + if (m_idSndRain >= 0 && SSCore_SndGetState(m_idSndRain) == SOUND_OBJSTATE_PLAY) SSCore_SndPause(m_idSndRain); - if (m_idSndThunder >= 0 && SSCore_SndStateGet(m_idSndThunder) == SOUND_OBJSTATE_PLAY) + if (m_idSndThunder >= 0 && SSCore_SndGetState(m_idSndThunder) == SOUND_OBJSTATE_PLAY) SSCore_SndPause(m_idSndThunder); } diff --git a/source/mtllight/light.cpp b/source/mtllight/light.cpp index 74b59a158471d51923b2e5c3caab522410921c91..8ea957c2a80dd6fe5882dccbc9aea8d0df873397 100644 --- a/source/mtllight/light.cpp +++ b/source/mtllight/light.cpp @@ -265,7 +265,7 @@ bool Lights::getExists(ID id) const void Lights::DeleteLight(ID id) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->IsGlobal) GlobalLight = -1; @@ -285,7 +285,7 @@ char* Lights::GetLightName(ID id) void Lights::SetLightName(ID id, const char* name) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); sprintf(ArrLights[id]->Name, "%s", name); } @@ -443,7 +443,7 @@ ID Lights::CreateDirection(ID id, const float3* pos, float dist, const float3* c void Lights::Render(ID id, DWORD timeDelta) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); float4x4 tmpwmat = ArrLights[id]->WorldMat; MLSet::DXDevice->SetTransform(D3DTS_WORLD, &(ArrLights[id]->WorldMat.operator D3DXMATRIX())); @@ -468,21 +468,21 @@ void Lights::SetCastGlobalShadow(bool isShadowed) void Lights::GetLightColor(ID id, float3* vec) const { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); (*vec) = ArrLights[id]->Color; } void Lights::SetLightColor(ID id, const float3* vec) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->Color = *vec; } void Lights::GetLightPos(ID id, float3* vec, bool greal) const { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->IsGlobal && !greal) { @@ -527,7 +527,7 @@ float Lights::GetLightDist(ID id) const void Lights::SetLightDist(ID id, float radius_height, bool is_create) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->Dist = radius_height; if (ArrLights[id]->TypeLight == LTYPE_LIGHT_DIR && is_create) @@ -562,7 +562,7 @@ void Lights::SetLightDist(ID id, float radius_height, bool is_create) void Lights::SetLightPos(ID id, const float3* vec, bool greal) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->IsGlobal) { @@ -615,14 +615,14 @@ void Lights::SetLightPos(ID id, const float3* vec, bool greal) void Lights::GetLightOrient(ID id, SMQuaternion* q) const { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); *q = ArrLights[id]->Quaternion; } void Lights::SetLightOrient(ID id, const SMQuaternion* q) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->Quaternion = *q; @@ -634,7 +634,7 @@ void Lights::SetLightOrient(ID id, const SMQuaternion* q) void Lights::SetShadowBias(ID id, float val) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowSM) ArrLights[id]->ShadowSM->SetBias(val); @@ -733,7 +733,7 @@ bool Lights::GetLightEnable(ID id) const void Lights::SetLightEnable(ID id, bool val) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->IsEnable = val; LightCountUpdateNull(id); @@ -754,7 +754,7 @@ LTYPE_LIGHT Lights::GetLightType(ID id) const void Lights::ShadowRenderBegin(ID id) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowSM) ArrLights[id]->ShadowSM->Begin(); @@ -766,7 +766,7 @@ void Lights::ShadowRenderBegin(ID id) void Lights::ShadowRenderEnd(ID id) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowSM) ArrLights[id]->ShadowSM->End(); @@ -778,7 +778,7 @@ void Lights::ShadowRenderEnd(ID id) void Lights::ShadowRenderPre(ID id, int cube) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowCube) ArrLights[id]->ShadowCube->Pre(cube); @@ -788,7 +788,7 @@ void Lights::ShadowRenderPre(ID id, int cube) void Lights::ShadowRenderPost(ID id, int cube) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowCube) ArrLights[id]->ShadowCube->Post(cube); @@ -900,14 +900,14 @@ ISXFrustum* Lights::GetLightFrustumG(ID id, int split) const void Lights::UpdateLightGFrustums(ID id, int split, const float3* pos, const float3* dir) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->ShadowPSSM->UpdateFrustums(split, pos, dir); } void Lights::ShadowGen2(ID id) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowSM) ArrLights[id]->ShadowSM->GenShadow2(SGCore_RTGetTexture(ShadowMap)); @@ -945,7 +945,7 @@ void Lights::ShadowNull() void Lights::SetLightAngle(ID id, float angle, bool is_create) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->Angle = angle; if (ArrLights[id]->TypeLight == LTYPE_LIGHT_DIR && is_create) @@ -972,7 +972,7 @@ void Lights::SetLightAngle(ID id, float angle, bool is_create) void Lights::SetLightTopRadius(ID id, float top_radius) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->TypeLight == 1) { @@ -994,7 +994,7 @@ void Lights::SetLightTopRadius(ID id, float top_radius) void Lights::SetShadowBlurPixel(ID id, float blur_pixel) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowCube) ArrLights[id]->ShadowCube->SetBlurPixel(blur_pixel); @@ -1021,7 +1021,7 @@ float Lights::GetShadowBlurPixel(ID id) const void Lights::SetShadowLocalNear(ID id, float slnear) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowCube) ArrLights[id]->ShadowCube->SetNear(slnear); @@ -1044,7 +1044,7 @@ float Lights::GetShadowLocalNear(ID id) const void Lights::SetShadowLocalFar(ID id, float slfar) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowCube) { @@ -1077,7 +1077,7 @@ float Lights::GetShadowLocalFar(ID id) const void Lights::SetLightCubeEdgeEnable(ID id, int edge, bool enable) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowCube) ArrLights[id]->ShadowCube->SetEnableCubeEdge(edge, enable); @@ -1118,7 +1118,7 @@ ID Lights::GetLightIDArr(ID id, ID inid, int how) void Lights::SetLightIDArr(ID id, ID inid, int how, ID id_arr) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowSM) { @@ -1139,7 +1139,7 @@ void Lights::SetLightIDArr(ID id, ID inid, int how, ID id_arr) void Lights::SetLightTypeShadowed(ID id, LTYPE_SHADOW type) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); ArrLights[id]->TypeShadowed = type; @@ -1490,7 +1490,7 @@ void Lights::ToneMappingCom(DWORD timeDelta, float factor_adapted) void Lights::Set4Or3Splits(ID id, bool is4) { - LIGHTS_PRE_COND_ID(id); + LIGHTS_PRE_COND_ID(id, _VOID); if (ArrLights[id]->ShadowPSSM) ArrLights[id]->ShadowPSSM->Set4Or3Splits(is4); @@ -1521,7 +1521,7 @@ LTYPE_LIGHT Lights::DelGetType(ID key) void Lights::DelDel(ID key) { - LIGHTS_PRE_COND_KEY_DEL(key); + LIGHTS_PRE_COND_KEY_DEL(key, _VOID); mem_delete(ArrDelLights[key]); ArrDelLights.erase(key); } diff --git a/source/mtllight/material.cpp b/source/mtllight/material.cpp index 22b28f6daadf2065374ce70b9eb31fe033ae46cf..3a0b2ad9110f6d78c23cd9d51399c874f9378457 100644 --- a/source/mtllight/material.cpp +++ b/source/mtllight/material.cpp @@ -143,9 +143,9 @@ Materials::Material::Material() Type = MTLTYPE_MODEL_STATIC; - MainTexture - 1; - PreShaderVS - 1; - PreShaderPS - 1; + MainTexture = -1; + PreShaderVS = -1; + PreShaderPS = -1; } void Materials::Material::Nulling() @@ -160,9 +160,9 @@ void Materials::Material::Nulling() Type = MTLTYPE_MODEL_STATIC; - MainTexture-1; - PreShaderVS-1; - PreShaderPS-1; + MainTexture = -1; + PreShaderVS = -1; + PreShaderPS = -1; MicroDetail = MaterialMaskPM(); LightParam = MaterialLightParam(); @@ -399,7 +399,7 @@ MTLTYPE_MODEL Materials::GetTypeModel(ID id) void Materials::SetTypeModel(ID id, MTLTYPE_MODEL type_model) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->Type = type_model; } @@ -411,7 +411,7 @@ bool Materials::MtlGetUsingAlphaTest(ID id) void Materials::MtlSetUsingAlphaTest(ID id, bool is_using) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->IsAlphaTest = is_using; } @@ -426,7 +426,7 @@ MTLTYPE_REFLECT Materials::MtlTypeReflection(ID id) void Materials::MtlRefSetIDArr(ID id, ID inid, int cube, ID idarr) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->SetIDArr(inid, cube, idarr); } @@ -450,13 +450,13 @@ ID Materials::MtlRefGetIDArr(ID id, ID inid, int cube) void Materials::MtlRefPreRenderPlane(ID id, D3DXPLANE* plane) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->PreRenderRefPlane(plane); } ISXFrustum* Materials::MtlRefGetfrustum(ID id, int cube) { - MTL_REF_PRE_COND_ID(id,0); + MTL_REF_PRE_COND_ID(id, 0); if (cube == 0 || (cube > 0 && (ArrMaterials[id]->Reflect->GetTypeReflect() == MTLTYPE_REFLECT_CUBE_STATIC || ArrMaterials[id]->Reflect->GetTypeReflect() == MTLTYPE_REFLECT_CUBE_DYNAMIC))) return ArrMaterials[id]->Reflect->ReflectFrustum[cube]; return 0; @@ -464,26 +464,26 @@ ISXFrustum* Materials::MtlRefGetfrustum(ID id, int cube) void Materials::MtlRefPostRenderPlane(ID id) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->PostRenderRefPlane(); } IDirect3DTexture9* Materials::MtlRefPlaneGetTex(ID id) { - MTL_REF_PRE_COND_ID(id,0); + MTL_REF_PRE_COND_ID(id, 0); return ArrMaterials[id]->Reflect->GetRefPlaneTex(); } void Materials::MtlRefSetMinMax(ID id, float3_t* min, float3_t* max) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->SetMinMax(min,max); } bool Materials::MtlRefIsAllowedRender(ID id) { - MTL_REF_PRE_COND_ID(id,false); + MTL_REF_PRE_COND_ID(id, false); if (ArrMaterials[id]->Reflect) return ArrMaterials[id]->Reflect->AllowedRender(); @@ -493,43 +493,43 @@ bool Materials::MtlRefIsAllowedRender(ID id) void Materials::MtlRefCubeBeginRender(ID id, float3_t* center) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->BeginRenderRefCube(center); } void Materials::MtlRefCubePreRender(ID id, int cube, float4x4* world) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->PreRenderRefCube(cube, world); } void Materials::MtlRefCubePostRender(ID id, int cube) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->PostRenderRefCube(cube); } void Materials::MtlRefCubeEndRender(ID id, float3_t* viewpos) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->EndRenderRefCube(viewpos); } bool Materials::MtlRefUpdateCountUpdate( ID id, float3_t* viewpos) { - MTL_REF_PRE_COND_ID(id,false); + MTL_REF_PRE_COND_ID(id, false); return ArrMaterials[id]->Reflect->UpdateCountUpdate(viewpos); } void Materials::MtlRefNullingCountUpdate(ID id) { - MTL_REF_PRE_COND_ID(id); + MTL_REF_PRE_COND_ID(id, _VOID); ArrMaterials[id]->Reflect->NullingCountUpdate(); } IDirect3DCubeTexture9* Materials::RefCubeGetTex(ID id) { - MTL_REF_PRE_COND_ID(id,0); + MTL_REF_PRE_COND_ID(id, 0); return ArrMaterials[id]->Reflect->GetRefCubeTex(); } @@ -550,13 +550,13 @@ MTLTYPE_PHYSIC Materials::MtlGetPhysicMaterial(ID id) void Materials::MtlSetTexture(ID id, const char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->MainTexture = SGCore_LoadTexAddName(path_tex, LOAD_TEXTURE_TYPE_LOAD); } void Materials::MtlGetTexture(ID id, char* name) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (name && ArrMaterials[id]->mtl->MainTexture >= 0) SGCore_LoadTexGetName(ArrMaterials[id]->mtl->MainTexture, name); @@ -571,25 +571,25 @@ ID Materials::MtlGetTextureID(ID id) void Materials::MtlSetVS(ID id, const char* path_vs) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->PreShaderVS = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, path_vs, path_vs, SHADER_CHECKDOUBLE_PATH); } void Materials::MtlGetVS(ID id, char* name) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); SGCore_ShaderGetPath(SHADER_TYPE_VERTEX, ArrMaterials[id]->mtl->PreShaderVS, name); } void Materials::MtlSetPS(ID id, const char* path_ps) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->PreShaderPS = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, path_ps, path_ps, SHADER_CHECKDOUBLE_PATH); } void Materials::MtlGetPS(ID id, char* name) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); SGCore_ShaderGetPath(SHADER_TYPE_PIXEL, ArrMaterials[id]->mtl->PreShaderPS, name); } @@ -598,39 +598,39 @@ void Materials::MtlGetPS(ID id, char* name) void Materials::MtlSetLighting(ID id, bool is_lighting) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->IsUnlit = !is_lighting; } bool Materials::MtlGetLighting(ID id) { - MTL_PRE_COND_ID(id,false); + MTL_PRE_COND_ID(id, false); return !ArrMaterials[id]->mtl->IsUnlit; } void Materials::MtlSetIsTextureLighting(ID id, bool is_tex_lighting) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.IsTextureParam = is_tex_lighting; } bool Materials::MtlGetIsTextureLighting(ID id) { - MTL_PRE_COND_ID(id,false); + MTL_PRE_COND_ID(id, false); return ArrMaterials[id]->mtl->LightParam.IsTextureParam; } void Materials::MtlSetTextureLighting(ID id, const char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.ParamTex = SGCore_LoadTexAddName(path_tex, LOAD_TEXTURE_TYPE_LOAD); } void Materials::MtlGetTextureLighting(ID id, char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (path_tex && ArrMaterials[id]->mtl->LightParam.ParamTex >= 0) { SGCore_LoadTexGetName(ArrMaterials[id]->mtl->LightParam.ParamTex, path_tex); @@ -644,32 +644,32 @@ void Materials::MtlGetTextureLighting(ID id, char* path_tex) void Materials::MtlSetRoughness(ID id, float roughness) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.RoughnessValue = roughness; } float Materials::MtlGetRoughness(ID id) { - MTL_PRE_COND_ID(id,-1); + MTL_PRE_COND_ID(id, -1); return ArrMaterials[id]->mtl->LightParam.RoughnessValue; } void Materials::MtlSetF0(ID id, float f0) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.F0Value = f0; } float Materials::MtlGetF0(ID id) { - MTL_PRE_COND_ID(id,-1); + MTL_PRE_COND_ID(id, -1); return ArrMaterials[id]->mtl->LightParam.F0Value; } void Materials::MtlSetThickness(ID id, float thickness) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.ThicknessValue = thickness; } @@ -721,7 +721,7 @@ float Materials::MtlGetDensity(ID id) void Materials::MtlSetTypeTransparency(ID id, MTLTYPE_TRANSPARENCY type) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.TypeRefraction = type; } @@ -734,7 +734,7 @@ MTLTYPE_TRANSPARENCY Materials::MtlGetTypeTransparency(ID id) void Materials::MtlSetTypeReflection(ID id, MTLTYPE_REFLECT type) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->LightParam.TypeReflect = type; if (ArrMaterials[id]->mtl->LightParam.TypeReflect != MTLTYPE_REFLECT_NONE) @@ -757,13 +757,13 @@ MTLTYPE_REFLECT Materials::MtlGetTypeReflection(ID id) void Materials::MtlSetMaskTex(ID id, const char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->MicroDetail.Mask = SGCore_LoadTexAddName(path_tex, LOAD_TEXTURE_TYPE_LOAD); } void Materials::MtlGetMaskTex(ID id, char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (path_tex && ArrMaterials[id]->mtl->MicroDetail.Mask >= 0) SGCore_LoadTexGetName(ArrMaterials[id]->mtl->MicroDetail.Mask, path_tex); else if (path_tex) @@ -772,13 +772,13 @@ void Materials::MtlGetMaskTex(ID id, char* path_tex) void Materials::MtlSetMRTex(ID id, int channel, const char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->MicroDetail.ArrMicroDiffuse[channel] = SGCore_LoadTexAddName(path_tex, LOAD_TEXTURE_TYPE_LOAD); } void Materials::MtlGetMRTex(ID id, int channel, char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (path_tex && ArrMaterials[id]->mtl->MicroDetail.ArrMicroDiffuse[channel] >= 0) SGCore_LoadTexGetName(ArrMaterials[id]->mtl->MicroDetail.ArrMicroDiffuse[channel], path_tex); else if (path_tex) @@ -788,13 +788,13 @@ void Materials::MtlGetMRTex(ID id, int channel, char* path_tex) void Materials::MtlSetDTex(ID id, int channel, const char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->MicroDetail.ArrDeatail[channel] = SGCore_LoadTexAddName(path_tex, LOAD_TEXTURE_TYPE_LOAD); } void Materials::MtlGetDTex(ID id, int channel, char* path_tex) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (path_tex && ArrMaterials[id]->mtl->MicroDetail.ArrDeatail[channel] >= 0) SGCore_LoadTexGetName(ArrMaterials[id]->mtl->MicroDetail.ArrDeatail[channel], path_tex); else if (path_tex) @@ -805,7 +805,7 @@ void Materials::MtlGetDTex(ID id, int channel, char* path_tex) void Materials::MtlSetSTDVS(ID id, MTL_SHADERSTD type, bool is_send) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (type == MTL_SHADERSTD_MATRIX_WORLD) ArrMaterials[id]->mtl->VS.IsTransWorld = is_send; else if (type == MTL_SHADERSTD_MATRIX_VIEW) @@ -831,7 +831,7 @@ void Materials::MtlSetSTDVS(ID id, MTL_SHADERSTD type, bool is_send) bool Materials::MtlGetSTDVS(ID id, MTL_SHADERSTD type) { - MTL_PRE_COND_ID(id,false); + MTL_PRE_COND_ID(id, false); if (type == MTL_SHADERSTD_MATRIX_WORLD) return ArrMaterials[id]->mtl->VS.IsTransWorld; else if (type == MTL_SHADERSTD_MATRIX_VIEW) @@ -859,7 +859,7 @@ bool Materials::MtlGetSTDVS(ID id, MTL_SHADERSTD type) void Materials::MtlSetSTDPS(ID id, MTL_SHADERSTD type, bool is_send) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); if (type == MTL_SHADERSTD_MATRIX_WORLD) ArrMaterials[id]->mtl->PS.IsTransWorld = is_send; else if (type == MTL_SHADERSTD_MATRIX_VIEW) @@ -885,7 +885,7 @@ void Materials::MtlSetSTDPS(ID id, MTL_SHADERSTD type, bool is_send) bool Materials::MtlGetSTDPS(ID id, MTL_SHADERSTD type) { - MTL_PRE_COND_ID(id,false); + MTL_PRE_COND_ID(id, false); if (type == MTL_SHADERSTD_MATRIX_WORLD) return ArrMaterials[id]->mtl->PS.IsTransWorld; else if (type == MTL_SHADERSTD_MATRIX_VIEW) @@ -913,50 +913,50 @@ bool Materials::MtlGetSTDPS(ID id, MTL_SHADERSTD type) void Materials::MtlSetUDVS(ID id, int component, float val) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->VS.Param[component] = val; } float Materials::MtlGetUDVS(ID id, int component) { - MTL_PRE_COND_ID(id,-1); + MTL_PRE_COND_ID(id, -1); return ArrMaterials[id]->mtl->VS.Param[component]; } void Materials::MtlSetUDVS_InPS(ID id, bool is_send_ps) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->TransVSDataInPS = is_send_ps; } bool Materials::MtlGetUDVS_InPS(ID id) { - MTL_PRE_COND_ID(id,false); + MTL_PRE_COND_ID(id, false); return ArrMaterials[id]->mtl->TransVSDataInPS; } void Materials::MtlSetUDPS(ID id, int component, float val) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->PS.Param[component] = val; } float Materials::MtlGetUDPS(ID id, int component) { - MTL_PRE_COND_ID(id,-1); + MTL_PRE_COND_ID(id, -1); return ArrMaterials[id]->mtl->PS.Param[component]; } void Materials::MtlSetUDPS_InPS(ID id, bool is_send_vs) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); ArrMaterials[id]->mtl->TransPSDataInVS = is_send_vs; } bool Materials::MtlGetUDPS_InPS(ID id) { - MTL_PRE_COND_ID(id,false); + MTL_PRE_COND_ID(id, false); return ArrMaterials[id]->mtl->TransPSDataInVS; } @@ -1104,7 +1104,6 @@ bool Materials::LoadMtl(const char* name, Material** mtl) { char* ArrRGBA[4] = { "r", "g", "b", "a" }; - char tmpNameMtl[256]; char tmpVS[256]; char tmpPS[256]; @@ -1603,7 +1602,7 @@ void Materials::MtlReLoad(ID id, const char* name) void Materials::MtlSave(ID id) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); char tmp_path[256];//папка char tmp_name[256];//само им¤ текстыр с расширением @@ -1648,9 +1647,6 @@ void Materials::MtlSave(ID id) fprintf(file, "[%s]\n", mtrl->Name); - char tmpPathVS[1024]; - char tmpPathPS[1024]; - char tmpPathVSName[1024]; char tmpPathPSName[1024]; @@ -1932,7 +1928,7 @@ void Materials::RenderStd(MTLTYPE_MODEL type, float4x4* world, ID slot, ID id_mt void Materials::Render(ID id, float4x4* world) { - MTL_PRE_COND_ID(id); + MTL_PRE_COND_ID(id, _VOID); static const int *r_win_width = GET_PCVAR_INT("r_win_width"); static const int *r_win_height = GET_PCVAR_INT("r_win_height"); @@ -2173,7 +2169,7 @@ void Materials::Render(ID id, float4x4* world) void Materials::RenderLight(float4_t* color, float4x4* world) { - MTL_PRE_COND_ID(MtrlDefLight); + MTL_PRE_COND_ID(MtrlDefLight, _VOID); ArrMaterials[MtrlDefLight]->mtl->PS.Param = *color; Render(MtrlDefLight, world); diff --git a/source/mtllight/reflection.cpp b/source/mtllight/reflection.cpp index 71bbbec2f67d6185fd0ac2f4ee5a0f8e30d2c0a4..1001b0bb0c64f9b515f5c043171045bea4fd016f 100644 --- a/source/mtllight/reflection.cpp +++ b/source/mtllight/reflection.cpp @@ -291,8 +291,6 @@ void Reflection::PreRenderRefCube(int cube, float4x4* world) void Reflection::PostRenderRefCube(int cube) { - LPDIRECT3DSURFACE9 BackBuf; - mem_release_del(CubeReflectSurface[cube]); mem_release(SurfaceReflect); diff --git a/source/mtllight/sxmtllight.h b/source/mtllight/sxmtllight.h index ce66190873de830055105e2b184db3e4c1d535cb..dfbb1bb0d4759ed695db764c672b05fc1d1bf5f2 100644 --- a/source/mtllight/sxmtllight.h +++ b/source/mtllight/sxmtllight.h @@ -230,7 +230,7 @@ SX_LIB_API void SML_LigthsSetCastGlobalShadow(bool isShadowed); \note Предварительный просчет - просчет для всего света (к примеру в другом потоке) @{*/ -SX_LIB_API bool SML_LigthsComVisibleForFrustum(ID id, const const ISXFrustum *pFrustum); //!< виден ли свет в данном фрустуме frustum (отдельный просчет) +SX_LIB_API bool SML_LigthsComVisibleForFrustum(ID id, const ISXFrustum *pFrustum); //!< виден ли свет в данном фрустуме frustum (отдельный просчет) SX_LIB_API float SML_LigthsComDistFor(ID id, const float3 *pViewPos); //!< дистанция от viewpos до начала света (отдельный просчет) //! просчет видимости и расстояния от наблюдателя viewpos до начала света, для каждого света (предварительный просчет) diff --git a/source/pp/sxpp.cpp b/source/pp/sxpp.cpp index 54a490a6785c84d87ca42248120b783d9c0c8d2d..a45182bed15f025e66528ec9a2ff17dec78b5c24 100644 --- a/source/pp/sxpp.cpp +++ b/source/pp/sxpp.cpp @@ -865,12 +865,13 @@ SX_LIB_API void SPP_RenderLensFlare(float3_t* param, float4_t* sun_color, bool u RenderSurf->Release(); BackBuf->Release(); - if (GetKeyState('N')) + /*if (GetKeyState('N')) { + //MessageBox(0,"PP GetKeyState",0,0); char tmppath[1024]; - sprintf(tmppath, "%sbp.png", "C:\\1\\"); - D3DXSaveTextureToFile(tmppath, D3DXIFF_PNG, SGCore_RTGetTexture(PPSet::IDsRenderTargets::Bright), NULL); - } + sprintf(tmppath, "%sbp.jpg", "C:\\1\\"); + D3DXSaveTextureToFile(tmppath, D3DXIFF_JPG, SGCore_RTGetTexture(PPSet::IDsRenderTargets::Bright), NULL); + }*/ SGCore_RTGetTexture(PPSet::IDsRenderTargets::GetSendRT())->GetSurfaceLevel(0, &RenderSurf); diff --git a/source/render/render_func.cpp b/source/render/render_func.cpp index f0c3e7936e1afaa861d92e54fc59d8cf4491d9b0..ffb3a8a45693fb8e77bfd059d1cce3d2ea50478c 100644 --- a/source/render/render_func.cpp +++ b/source/render/render_func.cpp @@ -216,11 +216,8 @@ void SXRenderFunc::ComVisibleForLight() { for (int k = 0; k < 6; k++) { - ID idarr = -1; - - idarr = SGeom_ModelsAddArrForCom(); if (SML_LigthsGetIDArr(i, RENDER_IDARRCOM_GEOM, k) <= -1) - SML_LigthsSetIDArr(i, RENDER_IDARRCOM_GEOM, k, idarr); + SML_LigthsSetIDArr(i, RENDER_IDARRCOM_GEOM, k, SGeom_ModelsAddArrForCom()); if (SML_LigthsGetIDArr(i, RENDER_IDARRCOM_GREEN, k) <= -1) SML_LigthsSetIDArr(i, RENDER_IDARRCOM_GREEN, k, SGeom_GreenAddArrForCom()); diff --git a/source/score/sound.cpp b/source/score/sound.cpp index 41b5ce6b54326376347326c1455e16374fc424fd..4f676ad54ae5a7b4d7c2fd9363b63e5b355754d8 100644 --- a/source/score/sound.cpp +++ b/source/score/sound.cpp @@ -6,21 +6,22 @@ See the license in LICENSE #include "sound.h" -size_t ogg_read(void *ptr, size_t size, size_t nmemb, void *datasource) +//############################################################################ + +size_t OggCallbackRead(void *ptr, size_t size, size_t nmemb, void *datasource) { FILE* f = (FILE*)datasource; return fread(ptr, 1, size * nmemb, f); } -int ogg_close(void* datasource) +int OggCallbackClose(void* datasource) { FILE* f = (FILE*)datasource; fclose(f); return 0; } -//позиционирование -int ogg_seek(void *datasource, ogg_int64_t offset, int whence) +int OggCallbackSeek(void *datasource, ogg_int64_t offset, int whence) { FILE* f = (FILE*)datasource; switch (whence) @@ -33,8 +34,7 @@ int ogg_seek(void *datasource, ogg_int64_t offset, int whence) return 1; } -//размер файла -long ogg_tell(void* datasource) +long OggCallbackTell(void* datasource) { FILE* f = (FILE*)datasource; return ftell(f); @@ -42,55 +42,442 @@ long ogg_tell(void* datasource) //############################################################################ -MainSound::MainSound() +CSoundManager::CSoundManager() { - DeviceSound = 0; - DSPrimary = 0; + m_pDeviceSound = 0; + m_pPrimaryBuffer = 0; + + for (int i = 0; i < SOUND_CHANNELS_COUNT; ++i) + m_aChannels[i] = SOUND_CHANNEL_NONE; } -MainSound::~MainSound() +CSoundManager::~CSoundManager() { - Clear(); - mem_release_del(DSPrimary); - mem_release_del(DeviceSound); + clear(); + mem_release_del(m_pPrimaryBuffer); + mem_release_del(m_pDeviceSound); } -void MainSound::Clear() +void CSoundManager::clear() { - for(UINT i = 0; i < ArrSounds.size(); ++i) + for(UINT i = 0; i < m_aSounds.size(); ++i) { - mem_delete(ArrSounds[i]); + mem_delete(m_aSounds[i]); } } -MainSound::Sound::Sound() +CSoundManager::CSound::CSound() { - ZeroMemory(this, sizeof(MainSound::Sound)); - Id = -1; + ZeroMemory(this, sizeof(CSoundManager::CSound)); + m_id = SOUND_FAIL_ID; + m_fVolume = 1.f; } -MainSound::Sound::~Sound() +CSoundManager::CSound::~CSound() { - if (StreamFile) - fclose(StreamFile); + if (m_pStream) + fclose(m_pStream); - mem_release_del(DSBuffer); - if (VorbisFile) + //mem_release_del(m_pSoundBuffer); + if (m_pVorbisFile) { - ov_clear(VorbisFile); - mem_delete(VorbisFile); + ov_clear(m_pVorbisFile); + mem_delete(m_pVorbisFile); } } -void MainSound::Init(HWND hwnd) +//########################################################################## + +CSoundManager::СSoundKit::СSoundKit() +{ + m_szName[0] = 0; + m_idChannel = SOUND_FAIL_ID; + m_is3D = false; + m_fDistAudible = SOUND_DIST_AUDIBLE_DEFAULT; +} + +CSoundManager::СSoundKit::~СSoundKit() +{ + +} + +ID CSoundManager::sndkitCreate(const char *szName, ID idChannel, bool is3D, float fDistAudible) +{ + // список звуков подлежащаих загрузке + СSoundKit *pSndKit = new СSoundKit(); + pSndKit->m_idChannel = idChannel; + pSndKit->m_is3D = is3D; + pSndKit->m_fDistAudible = fDistAudible; + sprintf(pSndKit->m_szName, "%s", szName); + + m_aSoundKits.push_back(pSndKit); + + return m_aSoundKits.size() - 1; +} + +ID CSoundManager::sndkitCreateFromList(const char *szName, ID idChannel, Array<String> aStrings, bool is3D, float fDistAudible, float fVolume) { - if (FAILED(DirectSoundCreate8(NULL, &DeviceSound, NULL))) + СSoundKit *pSndKit = new СSoundKit(); + pSndKit->m_idChannel = idChannel; + pSndKit->m_is3D = is3D; + pSndKit->m_fDistAudible = fDistAudible; + sprintf(pSndKit->m_szName, "%s", szName); + m_aSoundKits.push_back(pSndKit); + ID idSndKit = m_aSoundKits.size() - 1; + + String sFileData; + float fDistAudibleData = -2.f; + float fVolumeData = -2.f; + Array<UINT> aDelaysData; + + for (int i = 0, il = aStrings.size(); i < il; ++i) + { + aDelaysData.clearFast(); + fDistAudibleData = -2.f; + fVolumeData = -2.f; + + if (SndGetDataFromStr(aStrings[i].c_str(), sFileData, fDistAudibleData, fVolumeData, aDelaysData)) + { + if (fDistAudibleData == -2.f) + fDistAudibleData = -1.f; + + if (fVolumeData == -2.f) + fVolumeData = fVolume; + + sndkitAddSound(idSndKit, sFileData.c_str(), fDistAudibleData, fVolumeData, (aDelaysData.size() > 0 ? &(aDelaysData[0]) : 0), aDelaysData.size()); + } + else + sndkitAddSound(idSndKit, StrTrim(aStrings[i].c_str()).c_str(), pSndKit->m_fDistAudible, fVolume); + } + + return idSndKit; +} + +void CSoundManager::sndkitAddSound(ID idSndKit, const char *szFile, float fDistAudible, float fVolume, UINT *pArrDelay, int iSizeArrDelay) +{ + SOUND_SNDKIT_PRECOND(idSndKit, _VOID); + + СSoundKit *pSndKit = m_aSoundKits[idSndKit]; + + ID idSnd = SOUND_FAIL_ID; + + if (pSndKit->m_is3D) + idSnd = soundCreate3dInst(szFile, pSndKit->m_idChannel, (fDistAudible > 0 ? fDistAudible : pSndKit->m_fDistAudible)); + else + idSnd = soundCreate2dInst(szFile, pSndKit->m_idChannel); + + СSoundKit::CSoundKitObject oSndKitObj; + oSndKitObj.m_id = idSnd; + oSndKitObj.m_fVolume = fVolume; + + for (int i = 0, il = iSizeArrDelay; i < il; ++i) + { + oSndKitObj.m_aDelays.push_back(pArrDelay[i]); + } + + pSndKit->m_aSounds.push_back(oSndKitObj); +} + + +ID CSoundManager::sndkitGetID(const char *szName) +{ + for (int i = 0, il = m_aSoundKits.size(); i < il; ++i) + { + if (stricmp(m_aSoundKits[i]->m_szName, szName) == 0) + return i; + } + + return SOUND_FAIL_ID; +} + +ID CSoundManager::sndkitGetChannel(ID idSndKit) +{ + SOUND_SNDKIT_PRECOND(idSndKit, SOUND_FAIL_ID); + + return m_aSoundKits[idSndKit]->m_idChannel; +} + + +void CSoundManager::sndkitGetName(ID idSndKit, char *szName) +{ + SOUND_SNDKIT_PRECOND(idSndKit, _VOID); + + strcpy(szName, m_aSoundKits[idSndKit]->m_szName); +} + + +void CSoundManager::sndkitDelete(ID idSndKit) +{ + SOUND_SNDKIT_PRECOND(idSndKit, _VOID); + + СSoundKit *pSndKit = m_aSoundKits[idSndKit]; + + for (int i = 0, il = pSndKit->m_aSounds.size(); i < il; ++i) + { + soundDelete(pSndKit->m_aSounds[i].m_id); + } + + mem_delete(m_aSoundKits[idSndKit]); +} + + +void CSoundManager::sndkitDeleteAll() +{ + for (int i = 0, il = m_aSoundKits.size(); i < il; ++i) + { + sndkitDelete(i); + } +} + + +uint64_t CSoundManager::sndkitPlay(ID idSndKit, uint64_t id2, const float3 *pPos, float fVolume, float fPan) +{ + SOUND_SNDKIT_PRECOND(idSndKit, SOUND_FAIL_ID); + + СSoundKit *pSndKit = m_aSoundKits[idSndKit]; + + // если канал проигрывается + SOUND_CHANNEL_PLAYING(pSndKit->m_idChannel, ((id2 != SOUND_SNDKIT_INSTANCE_BLOCK && id2 != SOUND_SNDKIT_INSTANCE_NOTBLOCK) ? id2 : SOUND_FAIL_ID)); + + // если id2 валиден и инстанс проигрывается + if ((id2 != SOUND_SNDKIT_INSTANCE_BLOCK && id2 != SOUND_SNDKIT_INSTANCE_NOTBLOCK) && soundInstancePlaying(pSndKit->m_aSounds[SOUND_DECODE2ID_HI(id2)].m_id, SOUND_DECODE2ID_LO(id2))) + return id2; + + // если id2 валиден то освобождаем инстанс + if (id2 != SOUND_SNDKIT_INSTANCE_BLOCK && id2 != SOUND_SNDKIT_INSTANCE_NOTBLOCK) + soundInstanceFree(pSndKit->m_aSounds[SOUND_DECODE2ID_HI(id2)].m_id, SOUND_DECODE2ID_LO(id2)); + + ID idRand = rand() % (pSndKit->m_aSounds.size()); + ID idSndInstance = -1; + + UINT *pArr = 0; + int iSizeArr = pSndKit->m_aSounds[idRand].m_aDelays.size(); + + if (iSizeArr > 0) + pArr = &(pSndKit->m_aSounds[idRand].m_aDelays[0]); + + if (pSndKit->m_is3D) + { + if (!pPos) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved call function playing 3d sound without position", GEN_MSG_LOCATION); + return SOUND_FAIL_ID; + } + + idSndInstance = soundInstancePlay(pSndKit->m_aSounds[idRand].m_id, id2 != SOUND_SNDKIT_INSTANCE_NOTBLOCK, false, pArr, iSizeArr, pPos, (fVolume < 0 ? pSndKit->m_aSounds[idRand].m_fVolume : fVolume)); + } + else + idSndInstance = soundInstancePlay(pSndKit->m_aSounds[idRand].m_id, id2 != SOUND_SNDKIT_INSTANCE_NOTBLOCK, false, pArr, iSizeArr, 0, (fVolume < 0 ? pSndKit->m_aSounds[idRand].m_fVolume : fVolume), fPan); + + /*if (idSndInstance > 0) + { + CSound* snd = m_aSounds[pSndKit->m_aSounds[SOUND_DECODE2ID_HI(id2)].m_id]; + SOUND_SNDINSTANCE_BUSY busy = snd->m_aInstances[SOUND_DECODE2ID_LO(id2)].m_busy; + int qwerty = 0; + }*/ + + //ibReport(REPORT_MSG_LEVEL_NOTICE, "idSndInstance = %d\n", idSndInstance); + return SOUND_ENCODE2ID(idRand, idSndInstance); +} + + +void CSoundManager::sndkitStop(ID idSndKit, uint64_t id2) +{ + SOUND_SNDKIT_PRECOND(idSndKit, _VOID); + + if (id2 == SOUND_SNDKIT_INSTANCE_BLOCK) + return; + + СSoundKit *pSndKit = m_aSoundKits[idSndKit]; + + soundInstanceStop(pSndKit->m_aSounds[SOUND_DECODE2ID_HI(id2)].m_id, SOUND_DECODE2ID_LO(id2)); +} + +//########################################################################## + +void CSoundManager::channelAdd(ID idChannel, bool isPlaying) +{ + SOUND_CHANNEL_PRECOND(idChannel, _VOID); + + if (m_aChannels[idChannel] == SOUND_CHANNEL_NONE) + m_aChannels[idChannel] = isPlaying; +} + +bool CSoundManager::channelExists(ID idChannel) +{ + SOUND_CHANNEL_PRECOND(idChannel, false); + + return (m_aChannels[idChannel] != SOUND_CHANNEL_NONE); +} + +int CSoundManager::channelGetSndCount(ID idChannel) +{ + SOUND_CHANNEL_PRECOND(idChannel, SOUND_CHANNEL_NONE); + + int iCount = 0; + for (int i = 0, il = m_aSounds.size(); i < il; ++i) + { + if (m_aSounds[i]->m_idChannel == idChannel) + ++iCount; + } + + return iCount; +} + +void CSoundManager::channelPlay(ID idChannel) +{ + SOUND_CHANNEL_PRECOND(idChannel, _VOID); + + for (int i = 0, il = m_aSounds.size(); i < il; ++i) + { + if (m_aSounds[i] && m_aSounds[i]->m_idChannel == idChannel) + { + channelSndPlay(idChannel, i); + } + } + + m_aChannels[idChannel] = SOUND_CHANNEL_PLAY; +} + +bool CSoundManager::channelPlaying(ID idChannel) +{ + SOUND_CHANNEL_PRECOND(idChannel, false); + + return m_aChannels[idChannel]; +} + +void CSoundManager::channelStop(ID idChannel) +{ + SOUND_CHANNEL_PRECOND(idChannel, _VOID); + + for (int i = 0, il = m_aSounds.size(); i < il; ++i) + { + if (m_aSounds[i] && m_aSounds[i]->m_idChannel == idChannel) + { + channelSndStop(idChannel, i); + } + } + + m_aChannels[idChannel] = SOUND_CHANNEL_STOP; +} + +void CSoundManager::channelPlayOnly(ID idChannel) +{ + SOUND_CHANNEL_PRECOND(idChannel, _VOID); + + for (int i = 0, il = m_aSounds.size(); i < il; ++i) + { + if (m_aSounds[i]) + { + if (m_aSounds[i]->m_idChannel == idChannel) + { + channelSndPlay(idChannel, i); + } + else + { + channelSndStop(idChannel, i); + } + } + } +} + +void CSoundManager::soundResumePlayDelay(CSoundBase *pSndBase) +{ + if (!pSndBase || !(pSndBase->m_isPlayDelay)) + return; + + //если ключ валиден + if (pSndBase->oPlayDelay.m_iCurrPlayDelay >= 0 && pSndBase->oPlayDelay.m_aPlayDelay.size() > pSndBase->oPlayDelay.m_iCurrPlayDelay) + { + //если текущее значение задержка + if (pSndBase->oPlayDelay.m_aPlayDelay[pSndBase->oPlayDelay.m_iCurrPlayDelay].m_isDelay) + pSndBase->oPlayDelay.m_uiPlayDelayStart = GetTickCount() - pSndBase->oPlayDelay.m_uiPlayDelayStart; + else + pSndBase->m_pSoundBuffer->Play(0, 0, 0); + } + //иначе ключ невалиден, просто доигрываем + else + pSndBase->m_pSoundBuffer->Play(0, 0, 0); +} + +void CSoundManager::channelSndPlay(ID idChannel, ID idSound) +{ + if (idSound < m_aSounds.size() && idSound >= 0 && m_aSounds[idSound] && m_aSounds[idSound]->m_idChannel == idChannel) + { + CSound *pSnd = m_aSounds[idSound]; + DWORD dwStatus = 0; + + if (!(pSnd->m_isPlayDelay) && SUCCEEDED(pSnd->m_pSoundBuffer->GetStatus(&dwStatus)) && !(dwStatus & DSBSTATUS_PLAYING) && pSnd->m_state == SOUND_OBJSTATE_PLAY) + pSnd->m_pSoundBuffer->Play(0, 0, (pSnd->m_uiStreamSize || pSnd->m_isLooping ? DSBPLAY_LOOPING : 0)); + //если воспроизведение с задержками + else if (pSnd->m_isPlayDelay && pSnd->m_state == SOUND_OBJSTATE_PLAY) + soundResumePlayDelay(pSnd); + + + for (int k = 0, kl = pSnd->m_aInstances.size(); k < kl; ++k) + { + //TODO: доделать восстановление проигрывания с задержками для инстансов + + if (pSnd->m_aInstances[k].m_state == SOUND_OBJSTATE_PAUSE) + { + pSnd->m_aInstances[k].m_state = SOUND_OBJSTATE_PLAY; + + if (!(pSnd->m_isPlayDelay)) + pSnd->m_aInstances[k].m_pSoundBuffer->Play(0, 0, (pSnd->m_aInstances[k].m_isLooping ? DSBPLAY_LOOPING : 0)); + else + soundResumePlayDelay(&(pSnd->m_aInstances[k])); + } + } + } +} + +void CSoundManager::channelSndStop(ID idChannel, ID idSound) +{ + if (idSound < m_aSounds.size() && idSound >= 0 && m_aSounds[idSound] && m_aSounds[idSound]->m_idChannel == idChannel) + { + CSound *pSnd = m_aSounds[idSound]; + + if (pSnd->m_isPlayDelay) + { + if (pSnd->oPlayDelay.m_iCurrPlayDelay >= 0 && pSnd->oPlayDelay.m_aPlayDelay.size() > pSnd->oPlayDelay.m_iCurrPlayDelay && pSnd->oPlayDelay.m_aPlayDelay[pSnd->oPlayDelay.m_iCurrPlayDelay].m_isDelay) + pSnd->oPlayDelay.m_uiPlayDelayStart = GetTickCount() - pSnd->oPlayDelay.m_uiPlayDelayStart; + } + + pSnd->m_pSoundBuffer->Stop(); + DWORD dwStatus = 0; + CSoundInstance *pSndInst = 0; + + for (int k = 0, kl = pSnd->m_aInstances.size(); k < kl; ++k) + { + pSndInst = &(pSnd->m_aInstances[k]); + dwStatus = 0; + + if (pSndInst->m_state == SOUND_OBJSTATE_PLAY && SUCCEEDED(pSndInst->m_pSoundBuffer->GetStatus(&dwStatus)) && (dwStatus & DSBSTATUS_PLAYING)) + { + pSndInst->m_pSoundBuffer->Stop(); + pSndInst->m_state = SOUND_OBJSTATE_PAUSE; + } + + if (pSndInst->m_isPlayDelay) + { + if (pSndInst->oPlayDelay.m_iCurrPlayDelay >= 0 && pSndInst->oPlayDelay.m_aPlayDelay.size() > pSndInst->oPlayDelay.m_iCurrPlayDelay && pSndInst->oPlayDelay.m_aPlayDelay[pSndInst->oPlayDelay.m_iCurrPlayDelay].m_isDelay) + pSndInst->oPlayDelay.m_uiPlayDelayStart = GetTickCount() - pSndInst->oPlayDelay.m_uiPlayDelayStart; + } + } + } +} + +//########################################################################## + +void CSoundManager::init(HWND hwnd) +{ + if (FAILED(DirectSoundCreate8(NULL, &m_pDeviceSound, NULL))) { LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create sound device", GEN_MSG_LOCATION); return;// SOUND_INIT_ERR_INIT; } - if (FAILED(DeviceSound->SetCooperativeLevel(hwnd, DSSCL_EXCLUSIVE))) + if (FAILED(m_pDeviceSound->SetCooperativeLevel(hwnd, DSSCL_EXCLUSIVE))) { LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create cooperative level", GEN_MSG_LOCATION); return;// SOUND_INIT_ERR_CL; @@ -104,7 +491,7 @@ void MainSound::Init(HWND hwnd) dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = 0; - if (FAILED(DeviceSound->CreateSoundBuffer(&dsbd, &DSPrimary, NULL))) + if (FAILED(m_pDeviceSound->CreateSoundBuffer(&dsbd, &m_pPrimaryBuffer, NULL))) { LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create primary buffer", GEN_MSG_LOCATION); return;// SOUND_INIT_ERR_PRIM_BUF; @@ -120,28 +507,28 @@ void MainSound::Init(HWND hwnd) wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; - if (FAILED(DSPrimary->SetFormat(&wfex))) + if (FAILED(m_pPrimaryBuffer->SetFormat(&wfex))) { LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not init format", GEN_MSG_LOCATION); return;// SOUND_INIT_ERR_SET_FORMAT; } - DSPrimary->SetVolume(0); - DSPrimary->Play(0, 0, DSBPLAY_LOOPING); + m_pPrimaryBuffer->SetVolume(0); + m_pPrimaryBuffer->Play(0, 0, DSBPLAY_LOOPING); } // -SOUND_FILEFORMAT MainSound::FileFormat(const char* file) +SOUND_FILEFORMAT CSoundManager::fileFormat(const char* file) { FILE *fp; if (!(fp = fopen(file, "rb"))) return SOUND_FILEFORMAT_UNKNOWN; - SoundWaveHeader Hdr; + CSoundWaveHeader Hdr; fseek(fp, 0, SEEK_SET); - fread(&Hdr, 1, sizeof(SoundWaveHeader), fp); + fread(&Hdr, 1, sizeof(CSoundWaveHeader), fp); if (memcmp(Hdr.RiffSig, "RIFF", 4) == 0 || memcmp(Hdr.Sig, "WAVE", 4) == 0 || memcmp(Hdr.FormatSig, "fmt ", 4) == 0) { @@ -162,76 +549,76 @@ SOUND_FILEFORMAT MainSound::FileFormat(const char* file) //############################################################################# -void MainSound::Load(Sound* snd, const char* fpath, SOUND_FILEFORMAT fmt) +void CSoundManager::load(CSound* snd, const char* fpath, SOUND_FILEFORMAT fmt) { if (fmt == SOUND_FILEFORMAT_OGG) - LoadOGG(snd, fpath); + loadOGG(snd, fpath); else if (fmt == SOUND_FILEFORMAT_WAV) - LoadWAV(snd, fpath); + loadWAV(snd, fpath); } -void MainSound::LoadWAV(Sound* snd, const char* fpath) +void CSoundManager::loadWAV(CSound* snd, const char* fpath) { - SoundWaveHeader Hdr; - snd->StreamFile = fopen(fpath, "rb"); + CSoundWaveHeader Hdr; + snd->m_pStream = fopen(fpath, "rb"); - fseek(snd->StreamFile, 0, SEEK_SET); - fread(&Hdr, 1, sizeof(SoundWaveHeader), snd->StreamFile); + fseek(snd->m_pStream, 0, SEEK_SET); + fread(&Hdr, 1, sizeof(CSoundWaveHeader), snd->m_pStream); - snd->SizeFull = (Hdr.ChunkSize + (sizeof(char)* 4 + sizeof(int32_t))) - sizeof(SoundWaveHeader); + snd->m_uiSizeFull = (Hdr.ChunkSize + (sizeof(char)* 4 + sizeof(int32_t))) - sizeof(CSoundWaveHeader); - if (snd->StreamSize == 0) - Hdr.DataSize = snd->SizeFull; + if (snd->m_uiStreamSize == 0) + Hdr.DataSize = snd->m_uiSizeFull; else - Hdr.DataSize = snd->StreamSize; + Hdr.DataSize = snd->m_uiStreamSize; - if (!(snd->DSBuffer = SoundBufferCreate(&Hdr))) + if (!(snd->m_pSoundBuffer = soundBufferCreate(&Hdr))) { - LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create sound buffer [%s]", GEN_MSG_LOCATION, snd->RPath); + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create sound buffer [%s]", GEN_MSG_LOCATION, snd->m_szRPath); return; } - fseek(snd->StreamFile, sizeof(SoundWaveHeader), SEEK_SET); + fseek(snd->m_pStream, sizeof(CSoundWaveHeader), SEEK_SET); - SoundDataWAVLoad(snd->DSBuffer, 0, snd->StreamFile, Hdr.DataSize, 0); + soundDataWAVLoad(snd->m_pSoundBuffer, 0, snd->m_pStream, Hdr.DataSize, 0); - snd->LengthSec = snd->StreamSize / (Hdr.BytesPerSec); - snd->ChannelsCount = Hdr.Channels; - snd->RateSample = Hdr.SampleRate; - snd->BitsPerSample = Hdr.BitsPerSample; - snd->BytesPerSec = ((snd->BitsPerSample / 8) * snd->ChannelsCount) * snd->RateSample; + snd->m_iLengthSec = snd->m_uiStreamSize / (Hdr.BytesPerSec); + snd->m_iChannelsCount = Hdr.Channels; + snd->m_iSampleRate = Hdr.SampleRate; + snd->m_iBitsPerSample = Hdr.BitsPerSample; + snd->m_uiBytesPerSec = ((snd->m_iBitsPerSample / 8) * snd->m_iChannelsCount) * snd->m_iSampleRate; - if (snd->StreamSize == 0) + if (snd->m_uiStreamSize == 0) { - fclose(snd->StreamFile); + fclose(snd->m_pStream); } else { - snd->Split1Size = snd->StreamSize / 4; - snd->Split2Size = snd->Split1Size * 2; - snd->Split3Size = snd->Split1Size * 3; + snd->m_uiSplit1Size = snd->m_uiStreamSize / 4; + snd->m_uiSplit2Size = snd->m_uiSplit1Size * 2; + snd->m_uiSplit3Size = snd->m_uiSplit1Size * 3; - snd->BF1 = false; - snd->BF2 = false; - snd->BF3 = false; - snd->BF4 = false; + snd->m_isWork1 = false; + snd->m_isWork2 = false; + snd->m_isWork3 = false; + snd->m_isWork4 = false; - snd->IsStarting = true; + snd->m_isStarting = true; - snd->RePlayCount = 0; - double tmpCRPE = double(snd->SizeFull) / double(snd->StreamSize); + snd->m_iRePlayCount = 0; + double tmpCRPE = double(snd->m_uiSizeFull) / double(snd->m_uiStreamSize); float Count = 0; while (1) { if (tmpCRPE > Count && tmpCRPE < Count + 1) { - snd->RePlayEndCount = Count + 1; + snd->m_iRePlayEndCount = Count + 1; break; } else if (tmpCRPE == Count) { - snd->RePlayEndCount = Count; + snd->m_iRePlayEndCount = Count; break; } Count++; @@ -239,10 +626,10 @@ void MainSound::LoadWAV(Sound* snd, const char* fpath) } } -IDirectSoundBuffer8* MainSound::SoundBufferCreate(SoundWaveHeader* hdr) +IDirectSoundBuffer8* CSoundManager::soundBufferCreate(CSoundWaveHeader* hdr) { IDirectSoundBuffer *DSB; - IDirectSoundBuffer8 *DSBuffer; + IDirectSoundBuffer8 *m_pSoundBuffer; DSBUFFERDESC dsbd; WAVEFORMATEX wfex; @@ -261,19 +648,19 @@ IDirectSoundBuffer8* MainSound::SoundBufferCreate(SoundWaveHeader* hdr) dsbd.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbd.dwBufferBytes = hdr->DataSize; dsbd.lpwfxFormat = &wfex; - if (FAILED(DeviceSound->CreateSoundBuffer(&dsbd, &DSB, NULL))) + if (FAILED(m_pDeviceSound->CreateSoundBuffer(&dsbd, &DSB, NULL))) return NULL; - if (FAILED(DSB->QueryInterface(IID_IDirectSoundBuffer8, (void**)&DSBuffer))) + if (FAILED(DSB->QueryInterface(IID_IDirectSoundBuffer8, (void**)&m_pSoundBuffer))) { DSB->Release(); return NULL; } - return DSBuffer; + return m_pSoundBuffer; } -void MainSound::SoundDataWAVLoad(IDirectSoundBuffer8* DSBuffer, long LockPos, FILE* data, long Size, DWORD flag) +void CSoundManager::soundDataWAVLoad(IDirectSoundBuffer8* m_pSoundBuffer, int LockPos, FILE* data, int Size, UINT flag) { BYTE *Ptr1, *Ptr2; DWORD Size1, Size2; @@ -281,113 +668,113 @@ void MainSound::SoundDataWAVLoad(IDirectSoundBuffer8* DSBuffer, long LockPos, FI if (!Size) return; - if (FAILED(DSBuffer->Lock(LockPos, Size, (void**)&Ptr1, &Size1, (void**)&Ptr2, &Size2, flag))) + if (FAILED(m_pSoundBuffer->Lock(LockPos, Size, (void**)&Ptr1, &Size1, (void**)&Ptr2, &Size2, flag))) return; fread(Ptr1, 1, Size1, data); if (Ptr2) fread(Ptr2, 1, Size2, data); - DSBuffer->Unlock(Ptr1, Size1, Ptr2, Size2); + m_pSoundBuffer->Unlock(Ptr1, Size1, Ptr2, Size2); } ///////////////////////////////////////////////////////////////////////////// -void MainSound::LoadOGG(Sound* snd, const char* fpath) +void CSoundManager::loadOGG(CSound* snd, const char* fpath) { OggVorbis_File ogg; - snd->StreamFile = fopen(fpath, "rb"); + snd->m_pStream = fopen(fpath, "rb"); - if (snd->StreamFile == NULL) + if (snd->m_pStream == NULL) return; if (ov_fopen(fpath, &ogg)) { - LibReport(REPORT_MSG_LEVEL_ERROR, "%s - error reading [%s]", GEN_MSG_LOCATION, snd->RPath); + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - error reading [%s]", GEN_MSG_LOCATION, snd->m_szRPath); return; } - snd->VorbisFile = new OggVorbis_File; + snd->m_pVorbisFile = new OggVorbis_File; ov_callbacks cb; - cb.close_func = ogg_close; - cb.read_func = ogg_read; - cb.seek_func = ogg_seek; - cb.tell_func = ogg_tell; + cb.close_func = OggCallbackClose; + cb.read_func = OggCallbackRead; + cb.seek_func = OggCallbackSeek; + cb.tell_func = OggCallbackTell; - ov_open_callbacks(snd->StreamFile, snd->VorbisFile, 0, 0, cb); + ov_open_callbacks(snd->m_pStream, snd->m_pVorbisFile, 0, 0, cb); vorbis_info *vi = ov_info(&ogg, -1); if (!vi) { - LibReport(REPORT_MSG_LEVEL_ERROR, "%s - error reading (info) [%s]", GEN_MSG_LOCATION, snd->RPath); + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - error reading (info) [%s]", GEN_MSG_LOCATION, snd->m_szRPath); return; } - snd->LengthSec = float(ov_pcm_total(snd->VorbisFile, -1)) / float(vi->rate); - snd->ChannelsCount = vi->channels; - snd->RateSample = vi->rate; - snd->BitsPerSample = SOUND_OGG_BITS_PER_SAMPLE; - snd->BytesPerSec = ((snd->BitsPerSample / 8) * snd->ChannelsCount) * snd->RateSample; - snd->SizeFull = ov_pcm_total(snd->VorbisFile, -1) * 2 * vi->channels; + snd->m_iLengthSec = float(ov_pcm_total(snd->m_pVorbisFile, -1)) / float(vi->rate); + snd->m_iChannelsCount = vi->channels; + snd->m_iSampleRate = vi->rate; + snd->m_iBitsPerSample = SOUND_OGG_BITS_PER_SAMPLE; + snd->m_uiBytesPerSec = ((snd->m_iBitsPerSample / 8) * snd->m_iChannelsCount) * snd->m_iSampleRate; + snd->m_uiSizeFull = ov_pcm_total(snd->m_pVorbisFile, -1) * 2 * vi->channels; - SoundWaveHeader hdr; + CSoundWaveHeader hdr; hdr.Channels = vi->channels; hdr.SampleRate = vi->rate; hdr.BitsPerSample = SOUND_OGG_BITS_PER_SAMPLE; - if (snd->StreamSize == 0) - hdr.DataSize = snd->SizeFull; + if (snd->m_uiStreamSize == 0) + hdr.DataSize = snd->m_uiSizeFull; else - hdr.DataSize = snd->StreamSize; + hdr.DataSize = snd->m_uiStreamSize; - snd->DSBuffer = SoundBufferCreate(&hdr); + snd->m_pSoundBuffer = soundBufferCreate(&hdr); - if (!snd->DSBuffer) + if (!snd->m_pSoundBuffer) { - LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create sound buffer [%s]", GEN_MSG_LOCATION, snd->RPath); + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - could not create sound buffer [%s]", GEN_MSG_LOCATION, snd->m_szRPath); return; } - SoundDataOGGLoad(snd->VorbisFile, snd->DSBuffer, 0, hdr.DataSize, 0); + soundDataOGGLoad(snd->m_pVorbisFile, snd->m_pSoundBuffer, 0, hdr.DataSize, 0); - if (snd->StreamSize == 0) + if (snd->m_uiStreamSize == 0) { - fclose(snd->StreamFile); + fclose(snd->m_pStream); ov_clear(&ogg); - ov_clear(snd->VorbisFile); - mem_delete(snd->VorbisFile); - snd->VorbisFile = 0; + ov_clear(snd->m_pVorbisFile); + mem_delete(snd->m_pVorbisFile); + snd->m_pVorbisFile = 0; } else { - snd->Split1Size = snd->StreamSize / 4; - snd->Split2Size = snd->Split1Size * 2; - snd->Split3Size = snd->Split1Size * 3; + snd->m_uiSplit1Size = snd->m_uiStreamSize / 4; + snd->m_uiSplit2Size = snd->m_uiSplit1Size * 2; + snd->m_uiSplit3Size = snd->m_uiSplit1Size * 3; - snd->BF1 = false; - snd->BF2 = false; - snd->BF3 = false; - snd->BF4 = false; + snd->m_isWork1 = false; + snd->m_isWork2 = false; + snd->m_isWork3 = false; + snd->m_isWork4 = false; - snd->IsStarting = true; + snd->m_isStarting = true; - snd->RePlayCount = 0; - double tmpCRPE = double(snd->SizeFull) / double(snd->StreamSize); + snd->m_iRePlayCount = 0; + double tmpCRPE = double(snd->m_uiSizeFull) / double(snd->m_uiStreamSize); float Count = 0; while (1) { if (tmpCRPE > Count && tmpCRPE < Count + 1) { - snd->RePlayEndCount = Count + 1; + snd->m_iRePlayEndCount = Count + 1; break; } else if (tmpCRPE == Count) { - snd->RePlayEndCount = Count; + snd->m_iRePlayEndCount = Count; break; } Count++; @@ -396,7 +783,7 @@ void MainSound::LoadOGG(Sound* snd, const char* fpath) //return SOUND_OK; } -void MainSound::SoundDataOGGLoad(OggVorbis_File* VorbisFile, IDirectSoundBuffer8 *DSBuffer, long LockPos, long Size, DWORD flag) +void CSoundManager::soundDataOGGLoad(OggVorbis_File* VorbisFile, IDirectSoundBuffer8 *m_pSoundBuffer, int LockPos, int Size, UINT flag) { char *Ptr1, *Ptr2; DWORD Size1, Size2; @@ -404,7 +791,7 @@ void MainSound::SoundDataOGGLoad(OggVorbis_File* VorbisFile, IDirectSoundBuffer8 if (!Size) return; - if (FAILED(DSBuffer->Lock(LockPos, Size, (void**)&Ptr1, &Size1, (void**)&Ptr2, &Size2, flag))) + if (FAILED(m_pSoundBuffer->Lock(LockPos, Size, (void**)&Ptr1, &Size1, (void**)&Ptr2, &Size2, flag))) return; DWORD total_read = 0; @@ -457,355 +844,489 @@ void MainSound::SoundDataOGGLoad(OggVorbis_File* VorbisFile, IDirectSoundBuffer8 } } - DSBuffer->Unlock(Ptr1, Size1, Ptr2, Size2); + m_pSoundBuffer->Unlock(Ptr1, Size1, Ptr2, Size2); } //############################################################################# -ID MainSound::SoundCreate2d(const char *file, bool looping, DWORD size_stream) +ID CSoundManager::soundCreate2d(const char *szFile, ID idChannel, UINT uiSizeStream) { - if (!file) - return -1; + if (!szFile) + return SOUND_FAIL_ID; + + String sFileData = szFile; + float fDistAudibleData = -1.f; + float fVolumeData = -1.f; + Array<UINT> aDelaysData; + + SndGetDataFromStr(szFile, sFileData, fDistAudibleData, fVolumeData, aDelaysData); char fullpath[SOUND_MAX_SIZE_STDPATH + SOUND_MAX_SIZE_PATH]; - sprintf(fullpath, "%s%s", Core_RStringGet(G_RI_STRING_PATH_GS_SOUNDS), file); + sprintf(fullpath, "%s%s", Core_RStringGet(G_RI_STRING_PATH_GS_SOUNDS), sFileData.c_str()); if (!Core_0FileExists(fullpath)) { LibReport(REPORT_MSG_LEVEL_ERROR, "%s - file not found [%s]", GEN_MSG_LOCATION, fullpath); - return -1; + return SOUND_FAIL_ID; } - SOUND_FILEFORMAT fmt = FileFormat(fullpath); + SOUND_FILEFORMAT fmt = fileFormat(fullpath); if (fmt == SOUND_FILEFORMAT_UNKNOWN) { - LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unknown format [%s]", GEN_MSG_LOCATION, file); - return -1; + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unknown format [%s]", GEN_MSG_LOCATION, sFileData.c_str()); + return SOUND_FAIL_ID; } - Sound* snd = new Sound(); - strcpy(snd->RPath, file); - snd->Format = fmt; - snd->IsLooping = looping; + channelAdd(idChannel); + + CSound *pSnd = new CSound(); + + if (fDistAudibleData > 0.f) + pSnd->m_fDistAudible = fDistAudibleData; - snd->StreamSize = 0; - if (size_stream > 0) + if (fVolumeData > -1.f) + pSnd->m_fVolume = fVolumeData; + + strcpy(pSnd->m_szRPath, szFile); + pSnd->m_format = fmt; + + pSnd->m_uiStreamSize = 0; + if (uiSizeStream > 0) { - if (size_stream < SOUND_MIN_SIZE_STREAM) - snd->StreamSize = SOUND_MIN_SIZE_STREAM; + if (uiSizeStream < SOUND_MIN_SIZE_STREAM) + pSnd->m_uiStreamSize = SOUND_MIN_SIZE_STREAM; else - snd->StreamSize = size_stream; + pSnd->m_uiStreamSize = uiSizeStream; } + + if (uiSizeStream == 0 && aDelaysData.size() > 0) + { + soundInitPlayDelay(pSnd, &(aDelaysData[0]), aDelaysData.size()); + } + + load(pSnd, fullpath, fmt); - Load(snd, fullpath, fmt); + DWORD dwFrec; + pSnd->m_pSoundBuffer->GetFrequency(&dwFrec); + pSnd->m_uiFrecOrigin = dwFrec; + pSnd->m_id = addSound(pSnd); + pSnd->m_idChannel = idChannel; + pSnd->m_iCountLoad = 1; - snd->DSBuffer->GetFrequency(&snd->FrecOrigin); - snd->Id = AddSound(snd); - return snd->Id; + return pSnd->m_id; } -ID MainSound::SoundCreate3d(const char *file, bool looping, DWORD size_stream, float dist, float shift_pan) +ID CSoundManager::soundCreate3d(const char *file, ID idChannel, UINT size_stream, float dist) { - ID sndid = SoundCreate2d(file, looping, size_stream); - Sound* snd = 0; + ID idSnd = soundCreate2d(file, idChannel, size_stream); + CSound* snd = 0; - if (sndid < 0) - return sndid; + if (idSnd < 0) + return idSnd; - snd = ArrSounds[sndid]; - snd->DistAudible = dist; - snd->Is3d = true; - snd->ShiftPan = shift_pan; + snd = m_aSounds[idSnd]; + + if (snd->m_fDistAudible <= 0.f) + snd->m_fDistAudible = dist; + + snd->m_is3d = true; + snd->m_fShiftPan = SOUND_SHIFTPAN_3D; + snd->m_idChannel = idChannel; - return sndid; + return idSnd; } -ID MainSound::SoundCreate2dInst(const char *file, bool looping, DWORD size_stream) +ID CSoundManager::soundCreate2dInst(const char *file, ID idChannel) { - ID idsnd = SoundFind2dInst(file); - if (idsnd >= 0) - return idsnd; - idsnd = SoundCreate2d(file, looping, size_stream); - AArr2dInst[file] = idsnd; - ArrSounds[idsnd]->IsInst = true; - return idsnd; + ID idSnd = soundFind2dInst(file, idChannel); + + if (idSnd >= 0) + { + ++(m_aSounds[idSnd]->m_iCountLoad); + return idSnd; + } + + idSnd = soundCreate2d(file, idChannel); + + char szStr[SOUND_MAX_SIZE_FULLPATH]; + szStr[0] = 0; + SOUND_CREATE_NAME(szStr, idChannel, file); + + m_a2dInst[szStr] = idSnd; + m_aSounds[idSnd]->m_isInst = true; + m_aSounds[idSnd]->m_idChannel = idChannel; + return idSnd; } -ID MainSound::SoundCreate3dInst(const char *file, bool looping, DWORD size_stream, float dist, float shift_pan) +ID CSoundManager::soundCreate3dInst(const char *file, ID idChannel, float dist) { - ID idsnd = SoundFind2dInst(file); - if (idsnd >= 0) - return idsnd; - idsnd = SoundCreate3d(file, looping, size_stream, dist, shift_pan); - AArr3dInst[file] = idsnd; - ArrSounds[idsnd]->IsInst = true; - return idsnd; + ID idSnd = soundFind3dInst(file, idChannel); + + if (idSnd >= 0) + { + ++(m_aSounds[idSnd]->m_iCountLoad); + return idSnd; + } + + idSnd = soundCreate3d(file, idChannel, 0, dist); + + char szStr[SOUND_MAX_SIZE_FULLPATH]; + szStr[0] = 0; + SOUND_CREATE_NAME(szStr, idChannel, file); + + m_a3dInst[szStr] = idSnd; + m_aSounds[idSnd]->m_isInst = true; + m_aSounds[idSnd]->m_idChannel = idChannel; + + return idSnd; } -ID MainSound::SoundFind2dInst(const char * file) +ID CSoundManager::soundFind2dInst(const char *file, ID idChannel) { - ID id = -1; + char szStr[SOUND_MAX_SIZE_FULLPATH]; + szStr[0] = 0; + SOUND_CREATE_NAME(szStr, idChannel, file); + + ID id = SOUND_FAIL_ID; const AssotiativeArray<AAStringNR, ID, false, 16>::Node* pNode = 0; - if (AArr2dInst.KeyExists(file, &pNode)) + if (m_a2dInst.KeyExists(szStr, &pNode)) id = *(pNode->Val); return id; } -ID MainSound::SoundFind3dInst(const char * file) +ID CSoundManager::soundFind3dInst(const char *file, ID idChannel) { - ID id = -1; + char szStr[SOUND_MAX_SIZE_FULLPATH]; + szStr[0] = 0; + SOUND_CREATE_NAME(szStr, idChannel, file); + + ID id = SOUND_FAIL_ID; const AssotiativeArray<AAStringNR, ID, false, 16>::Node* pNode = 0; - if (AArr3dInst.KeyExists(file, &pNode)) + if (m_a3dInst.KeyExists(szStr, &pNode)) id = *(pNode->Val); return id; } -void MainSound::SoundInstancePlay2d(ID id, int volume, int pan) +ID CSoundManager::soundInstancePlay(ID idSound, bool isBlocked, bool isLooping, UINT *pArrDelay, int iSizeArrDelay, const float3 *pPos, float fVolume, float fPan) { - SOUND_PRECOND(id, _VOID); + SOUND_PRECOND(idSound, SOUND_FAIL_ID); + + CSound *pSnd = m_aSounds[idSound]; - Sound* snd = ArrSounds[id]; + SOUND_CHANNEL_PLAYING(pSnd->m_idChannel, SOUND_FAIL_ID); - if (snd->StreamSize > 0) + if (pSnd->m_uiStreamSize > 0) { - LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create sound instance for streaming [%s]", GEN_MSG_LOCATION, snd->RPath); - return; + LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create sound instance for streaming [%s]", GEN_MSG_LOCATION, pSnd->m_szRPath); + return SOUND_FAIL_ID; } - if (snd->Is3d) + if (pSnd->m_is3d && !pPos) { - LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create 2d sound instance by 3d [%s]", GEN_MSG_LOCATION, snd->RPath); - return; + LibReport(REPORT_MSG_LEVEL_WARNING, "%s - not send position for 3d sound instance [%s]", GEN_MSG_LOCATION, pSnd->m_szRPath); + return SOUND_FAIL_ID; + } + + if (!(pSnd->m_is3d) && pPos) + { + LibReport(REPORT_MSG_LEVEL_WARNING, "%s - uresolved send position for 2d sound instance [%s]", GEN_MSG_LOCATION, pSnd->m_szRPath); + return SOUND_FAIL_ID; } - ID id_instance = -1; - for (UINT i = 0; i < snd->DataInstances.size(); ++i) + ID idInstance = -1; + for (int i = 0; i < pSnd->m_aInstances.size(); ++i) { - if (!snd->DataInstances[i].busy) + if (pSnd->m_aInstances[i].m_busy == SOUND_SNDINSTANCE_BUSY_FREE) { - id_instance = i; + idInstance = i; break; } } - if (id_instance < 0) + if (idInstance < 0) { IDirectSoundBuffer* tsb; IDirectSoundBuffer8* tsb8; - DeviceSound->DuplicateSoundBuffer(snd->DSBuffer, &tsb); + m_pDeviceSound->DuplicateSoundBuffer(pSnd->m_pSoundBuffer, &tsb); if (!tsb) { - LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create sound instance [%s], this is big problem", GEN_MSG_LOCATION, snd->RPath); - return; + LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create sound instance [%s], this is big problem", GEN_MSG_LOCATION, pSnd->m_szRPath); + return SOUND_FAIL_ID; } tsb->QueryInterface(IID_IDirectSoundBuffer8, (void**)&tsb8); - snd->DataInstances.push_back(Sound::SIData(tsb8, 0, true)); - id_instance = snd->DataInstances.size() - 1; + pSnd->m_aInstances.push_back(CSoundInstance(tsb8, pSnd->m_uiBytesPerSec, (pPos ? &float3_t(*pPos) : 0), SOUND_SNDINSTANCE_BUSY_TEMP)); + idInstance = pSnd->m_aInstances.size() - 1; } - if (id_instance >= 0) - { - long tvol; - snd->DSBuffer->GetVolume(&tvol); - snd->DataInstances[id_instance].busy = true; - //IDirectSoundBuffer8* tsb = snd->DataInstances[id_instance].sbuffer; - snd->DataInstances[id_instance].sbuffer->SetVolume((tvol > -5000 ? tvol - 5000 : tvol + 5000)); - snd->DataInstances[id_instance].sbuffer->SetCurrentPosition(0); - snd->DataInstances[id_instance].sbuffer->SetVolume(-10000 + (volume * 100)); - snd->DataInstances[id_instance].sbuffer->SetPan((pan > 0) ? (10000 - (pan * 100)) - 10000 : 10000 - (10000 + (pan * 100))); - snd->DataInstances[id_instance].sbuffer->Play(0, 0, 0); + if (idInstance >= 0) + { + if (isBlocked || isLooping) + pSnd->m_aInstances[idInstance].m_busy = SOUND_SNDINSTANCE_BUSY_LOCKED; + else + pSnd->m_aInstances[idInstance].m_busy = SOUND_SNDINSTANCE_BUSY_TEMP; + + //если установлены задержки воспроизведения + if (pArrDelay && iSizeArrDelay > 0 || iSizeArrDelay < 0) + soundInitPlayDelay(&(pSnd->m_aInstances[idInstance]), pArrDelay, iSizeArrDelay); + + pSnd->m_aInstances[idInstance].m_fVolume = saturatef(fVolume); + + //если 3д звук + if (pSnd->m_is3d && pPos) + { + pSnd->m_aInstances[idInstance].m_pSoundBuffer->SetVolume(lerpf(-10000, 0, pSnd->m_aInstances[idInstance].m_fVolume * Snd3dComVolume((*pPos), m_vOldViewPos, pSnd->m_fDistAudible))); + pSnd->m_aInstances[idInstance].m_pSoundBuffer->SetPan(Snd3dComPan((*pPos), m_vOldViewPos, m_vOldViewDir, pSnd->m_fDistAudible, pSnd->m_fShiftPan)); + } + //иначе фоновый + else + { + pSnd->m_aInstances[idInstance].m_pSoundBuffer->SetVolume(lerpf(-10000, 0, pSnd->m_aInstances[idInstance].m_fVolume)); + pSnd->m_aInstances[idInstance].m_pSoundBuffer->SetPan((fPan > 0) ? (10000 - (fPan * 100)) - 10000 : 10000 - (10000 + (fPan * 100))); + } + + pSnd->m_aInstances[idInstance].m_pSoundBuffer->SetCurrentPosition(0); + pSnd->m_aInstances[idInstance].m_isLooping = isLooping; + + if (!(pArrDelay && iSizeArrDelay > 0)) + pSnd->m_aInstances[idInstance].m_pSoundBuffer->Play(0, 0, ((pSnd->m_aInstances[idInstance].m_isLooping) ? DSBPLAY_LOOPING : 0)); + + pSnd->m_aInstances[idInstance].m_state = SOUND_OBJSTATE_PLAY; + + return idInstance; } + + return SOUND_FAIL_ID; } -void MainSound::SoundInstancePlay3d(ID id, const float3* pos) +bool CSoundManager::soundInstancePlaying(ID idSound, ID idInstance) { - SOUND_PRECOND(id, _VOID); - - if (!pos) - return; + SOUND_PRECOND(idSound, false); - Sound* snd = ArrSounds[id]; + CSound* snd = m_aSounds[idSound]; - if (snd->StreamSize > 0) + if (idInstance >= 0) { - LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create sound instance for streaming [%s]", GEN_MSG_LOCATION, snd->RPath); - return; + /*DWORD dwStatus; + snd->m_aInstances[idInstance].m_pSoundBuffer->GetStatus(&dwStatus); + return (dwStatus & DSBSTATUS_PLAYING);*/ + return (snd->m_aInstances[idInstance].m_state != SOUND_OBJSTATE_STOP); } - if (!snd->Is3d) - { - LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create 3d sound instance by 2d[%s]", GEN_MSG_LOCATION, snd->RPath); - return; - } + return false; +} - ID id_instance = -1; - for(UINT i = 0; i < snd->DataInstances.size(); ++i) - { - if(!snd->DataInstances[i].busy) - { - id_instance = i; - break; - } - } +void CSoundManager::soundInstanceStop(ID idSound, ID idInstance) +{ + SOUND_PRECOND(idSound, _VOID); + + CSound* snd = m_aSounds[idSound]; - if (id_instance < 0) + if (idInstance >= 0) { - IDirectSoundBuffer* tsb; - IDirectSoundBuffer8* tsb8; - DeviceSound->DuplicateSoundBuffer(snd->DSBuffer, &tsb); - if (!tsb) - { - LibReport(REPORT_MSG_LEVEL_WARNING, "%s - can not create sound instance [%s], this is big problem", GEN_MSG_LOCATION, snd->RPath); - return; - } - tsb->QueryInterface(IID_IDirectSoundBuffer8, (void**)&tsb8); - snd->DataInstances.push_back(Sound::SIData(tsb8, &float3_t(*pos), true)); - id_instance = snd->DataInstances.size() - 1; + snd->m_aInstances[idInstance].m_isLooping = false; + snd->m_aInstances[idInstance].m_pSoundBuffer->Stop(); + snd->m_aInstances[idInstance].m_state = SOUND_OBJSTATE_STOP; } +} - if (id_instance >= 0) - { - long tvol; - snd->DSBuffer->GetVolume(&tvol); - snd->DataInstances[id_instance].sbuffer->SetVolume((tvol > -5000 ? tvol - 5000 : tvol + 5000)); +void CSoundManager::soundInstanceFree(ID idSound, ID idInstance) +{ + SOUND_PRECOND(idSound, _VOID); + + CSound* snd = m_aSounds[idSound]; - snd->DataInstances[id_instance].sbuffer->SetVolume(SOUND_3D_COM_VOLUME((*pos), OldViewPos, snd->DistAudible)); - snd->DataInstances[id_instance].sbuffer->SetPan(SOUND_3D_COM_PAN((*pos), OldViewPos, OldViewDir, snd->DistAudible,snd->ShiftPan)); - snd->DataInstances[id_instance].sbuffer->SetCurrentPosition(0); - snd->DataInstances[id_instance].sbuffer->Play(0, 0, 0); + if (idInstance >= 0) + { + if (snd->m_aInstances[idInstance].m_busy == SOUND_SNDINSTANCE_BUSY_LOCKED) + snd->m_aInstances[idInstance].m_busy = SOUND_SNDINSTANCE_BUSY_TEMP; } } -ID MainSound::AddSound(Sound* snd) +ID CSoundManager::addSound(CSound* snd) { - for (int i = 0, l = ArrSounds.size(); i < l; ++i) + for (int i = 0, l = m_aSounds.size(); i < l; ++i) { - if (ArrSounds[i] == 0) + if (m_aSounds[i] == 0) { - ArrSounds[i] = snd; + m_aSounds[i] = snd; return i; } } - ArrSounds.push_back(snd); - return ArrSounds.size() - 1; + m_aSounds.push_back(snd); + return m_aSounds.size() - 1; } -bool MainSound::SoundIsInit(ID id) +bool CSoundManager::soundIsInit(ID id) { - return ((ID)ArrSounds.size() > id && ArrSounds[id] != 0); + return ((ID)m_aSounds.size() > id && m_aSounds[id] != 0); } -void MainSound::SoundDelete(ID id) +void CSoundManager::soundDelete(ID id) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; - if (snd->IsInst) + + CSound* snd = m_aSounds[id]; + --(snd->m_iCountLoad); + + if (snd->m_iCountLoad > 0) + return; + + if (snd->m_isInst) { - if (snd->Is3d) - AArr3dInst.erase(snd->RPath); + char szStr[SOUND_MAX_SIZE_FULLPATH]; + szStr[0] = 0; + SOUND_CREATE_NAME(szStr, snd->m_idChannel, snd->m_szRPath); + + if (snd->m_is3d) + m_a3dInst.erase(szStr); else - AArr2dInst.erase(snd->RPath); + m_a2dInst.erase(szStr); } mem_delete(snd); } //############################################################################# -void MainSound::SoundPlay(ID id, int looping) +void CSoundManager::soundPlay(ID id, bool isLooping, UINT *pArrDelay, int iSizeArrDelay) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; + CSound *pSnd = m_aSounds[id]; + + if (pSnd->m_uiStreamSize != 0 && pArrDelay && iSizeArrDelay > 0) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved play delay for streming playing, file %s", GEN_MSG_LOCATION, pSnd->m_szRPath); + return; + } + + if (!m_aChannels[pSnd->m_idChannel]) + return; + + if (pArrDelay && iSizeArrDelay > 0 || iSizeArrDelay < 0) + soundInitPlayDelay(pSnd, pArrDelay, iSizeArrDelay); + + pSnd->m_isLooping = isLooping; + + if (pSnd->m_pSoundBuffer) + { + if (pArrDelay && iSizeArrDelay > 0) + pSnd->m_pSoundBuffer->SetCurrentPosition(0); + else + pSnd->m_pSoundBuffer->Play(0, 0, (pSnd->m_uiStreamSize || pSnd->m_isLooping ? DSBPLAY_LOOPING : 0)); + + pSnd->m_state = SOUND_OBJSTATE_PLAY; + } +} - if (looping >= 0) - snd->IsLooping = looping != 0; +void CSoundManager::soundInitPlayDelay(CSoundBase *pSndbase, UINT *pArrDelay, int iSizeArrDelay) +{ + if (!pSndbase) + return; - if (snd->DSBuffer) + if (iSizeArrDelay < 0) { - snd->DSBuffer->Play(0, 0, (snd->StreamSize || snd->IsLooping ? DSBPLAY_LOOPING : 0)); - snd->State = SOUND_OBJSTATE_PLAY; + if (pSndbase->oPlayDelay.m_aPlayDelay.size() <= 0) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - previous delay data not init", GEN_MSG_LOCATION); + } + + pSndbase->oPlayDelay.m_iCurrPlayDelay = 0; + pSndbase->m_isPlayDelay = true; + return; + } + + if (pArrDelay == 0 || iSizeArrDelay == 0) + return; + + pSndbase->oPlayDelay.m_aPlayDelay.clearFast(); + pSndbase->oPlayDelay.m_iCurrPlayDelay = 0; + pSndbase->m_isPlayDelay = true; + pSndbase->oPlayDelay.m_uiPlayDelayStart = GetTickCount(); + + bool isEven = true; + for (int i = 0, il = iSizeArrDelay; i < il; ++i) + { + pSndbase->oPlayDelay.m_aPlayDelay.push_back(CPlayDelay::CTimeDelay(pArrDelay[i], isEven)); + isEven = !isEven; } } -void MainSound::SoundPause(ID id) +void CSoundManager::soundPause(ID id) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; + CSound* snd = m_aSounds[id]; + + if (!m_aChannels[snd->m_idChannel]) + return; - if (snd->DSBuffer) + if (snd->m_pSoundBuffer) { - snd->DSBuffer->Stop(); - snd->State = SOUND_OBJSTATE_PAUSE; + snd->m_pSoundBuffer->Stop(); + snd->m_state = SOUND_OBJSTATE_PAUSE; } } -void MainSound::SoundStop(ID id) +void CSoundManager::soundStop(ID id) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; + CSound* snd = m_aSounds[id]; + + if (!m_aChannels[snd->m_idChannel]) + return; - if (snd->DSBuffer) + if (snd->m_pSoundBuffer) { - snd->DSBuffer->Stop(); - snd->DSBuffer->SetCurrentPosition(0); - snd->State = SOUND_OBJSTATE_STOP; + snd->m_pSoundBuffer->Stop(); + snd->m_pSoundBuffer->SetCurrentPosition(0); + snd->m_state = SOUND_OBJSTATE_STOP; + snd->m_isLooping = false; + snd->m_isPlayDelay = false; } } -void MainSound::SoundStateSet(ID id, SOUND_OBJSTATE state) +void CSoundManager::soundSetState(ID id, SOUND_OBJSTATE state) { SOUND_PRECOND(id, _VOID); if (state == SOUND_OBJSTATE_PLAY) - SoundPlay(id); + soundPlay(id); else if (state == SOUND_OBJSTATE_PAUSE) - SoundPause(id); + soundPause(id); else if (state == SOUND_OBJSTATE_STOP) - SoundStop(id); + soundStop(id); } -SOUND_OBJSTATE MainSound::SoundStateGet(ID id) +SOUND_OBJSTATE CSoundManager::soundGetState(ID id) { SOUND_PRECOND(id, SOUND_OBJSTATE_STOP); - Sound* snd = ArrSounds[id]; - return snd->State; + CSound* snd = m_aSounds[id]; + return snd->m_state; } -void MainSound::SoundPosCurrSet(ID id, DWORD pos, int type) +void CSoundManager::soundSetPosPlay(ID id, UINT pos) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; + CSound* snd = m_aSounds[id]; DWORD PosInBytes = 0; - if (snd->DSBuffer) + if (snd->m_pSoundBuffer) { - if (type == SOUND_POS_BYTES) - { - PosInBytes = pos; - } - else if (type == SOUND_POS_SEC) - { - PosInBytes = pos * snd->BytesPerSec; - } - else if (type == SOUND_POS_MLS) - { - PosInBytes = pos * (snd->BytesPerSec / 1000); - } + PosInBytes = pos * (snd->m_uiBytesPerSec / 1000); - if (snd->StreamSize) + if (snd->m_uiStreamSize) { WORD HowCountRePlay = 0; - for (WORD i = 0; i <= snd->RePlayEndCount; i++) + for (WORD i = 0; i <= snd->m_iRePlayEndCount; i++) { - if ((i * snd->StreamSize <= PosInBytes && (i + 1) * snd->StreamSize >= PosInBytes) || i * snd->StreamSize == PosInBytes) + if ((i * snd->m_uiStreamSize <= PosInBytes && (i + 1) * snd->m_uiStreamSize >= PosInBytes) || i * snd->m_uiStreamSize == PosInBytes) { HowCountRePlay = i; break; @@ -813,392 +1334,463 @@ void MainSound::SoundPosCurrSet(ID id, DWORD pos, int type) } //wav - if (snd->Format == SOUND_FILEFORMAT_WAV) - fseek(snd->StreamFile, sizeof(SoundWaveHeader)+(HowCountRePlay * snd->StreamSize), SEEK_SET); + if (snd->m_format == SOUND_FILEFORMAT_WAV) + fseek(snd->m_pStream, sizeof(CSoundWaveHeader)+(HowCountRePlay * snd->m_uiStreamSize), SEEK_SET); //ogg - else if (snd->Format == SOUND_FILEFORMAT_OGG) - ov_pcm_seek(snd->VorbisFile, (HowCountRePlay * snd->StreamSize) / (2 * snd->ChannelsCount)); + else if (snd->m_format == SOUND_FILEFORMAT_OGG) + ov_pcm_seek(snd->m_pVorbisFile, (HowCountRePlay * snd->m_uiStreamSize) / (2 * snd->m_iChannelsCount)); - DWORD SizeCountRePlay = PosInBytes - (snd->StreamSize * HowCountRePlay); + DWORD SizeCountRePlay = PosInBytes - (snd->m_uiStreamSize * HowCountRePlay); - ReLoadSplit(id, 0, snd->StreamSize); + reLoadSplit(id, 0, snd->m_uiStreamSize); - snd->RePlayCount = HowCountRePlay; - snd->DSBuffer->SetCurrentPosition(SizeCountRePlay); + snd->m_iRePlayCount = HowCountRePlay; + snd->m_pSoundBuffer->SetCurrentPosition(SizeCountRePlay); for (WORD i = 0; i<4; i++) { - if (SizeCountRePlay >= snd->Split1Size * i && SizeCountRePlay < snd->Split1Size * (i + 1)) + if (SizeCountRePlay >= snd->m_uiSplit1Size * i && SizeCountRePlay < snd->m_uiSplit1Size * (i + 1)) { - snd->SplitActive = i + 1; + snd->m_iSplitActive = i + 1; break; } } - if (snd->SplitActive > 1) - snd->IsStarting = false; + if (snd->m_iSplitActive > 1) + snd->m_isStarting = false; else - snd->IsStarting = true; + snd->m_isStarting = true; - if (snd->SplitActive - 2 > 0 && snd->SplitActive - 2 < 5) + if (snd->m_iSplitActive - 2 > 0 && snd->m_iSplitActive - 2 < 5) { - for (WORD i = 0; i<snd->SplitActive - 2; i++) - ReLoadSplit(id, snd->Split1Size*i, snd->Split1Size); + for (WORD i = 0; i<snd->m_iSplitActive - 2; i++) + reLoadSplit(id, snd->m_uiSplit1Size*i, snd->m_uiSplit1Size); } - snd->BF1 = snd->BF2 = snd->BF3 = snd->BF4 = false; + snd->m_isWork1 = snd->m_isWork2 = snd->m_isWork3 = snd->m_isWork4 = false; } else - snd->DSBuffer->SetCurrentPosition(PosInBytes); + snd->m_pSoundBuffer->SetCurrentPosition(PosInBytes); } } -DWORD MainSound::SoundPosCurrGet(ID id, int type) +UINT CSoundManager::soundGetPosPlay(ID id) { SOUND_PRECOND(id, 0); - Sound* snd = ArrSounds[id]; - DWORD posinduff, Bytes, Pos = 0; - if (snd->DSBuffer) + CSound* snd = m_aSounds[id]; + DWORD dwPosBuff, dwBytes, dwPos = 0; + if (snd->m_pSoundBuffer) { - snd->DSBuffer->GetCurrentPosition(&posinduff, 0); + snd->m_pSoundBuffer->GetCurrentPosition(&dwPosBuff, 0); - if (snd->StreamSize) - Bytes = snd->RePlayCount * snd->StreamSize + posinduff; + if (snd->m_uiStreamSize) + dwBytes = snd->m_iRePlayCount * snd->m_uiStreamSize + dwPosBuff; else - Bytes = posinduff; - - if (type == SOUND_POS_BYTES) - Pos = Bytes; - else if (type == SOUND_POS_SEC) - Pos = Bytes / snd->BytesPerSec; - else if (type == SOUND_POS_MLS) - Pos = Bytes / (snd->BytesPerSec / 1000); + dwBytes = dwPosBuff; + + dwPos = dwBytes / (snd->m_uiBytesPerSec / 1000); } - return Pos; + return dwPos; } -void MainSound::SoundVolumeSet(ID id, long volume, int type) +void CSoundManager::soundSetVolume(ID id, float fVolume) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; - if (snd->DSBuffer) + CSound *pSnd = m_aSounds[id]; + pSnd->m_fVolume = saturatef(fVolume); + + if (pSnd->m_pSoundBuffer) { - if (type == SOUND_VOL_DB) - snd->Volume = volume; - else if (type == SOUND_VOL_PCT) - snd->Volume = -10000 + (volume * 100); + int iVolume = -10000 + (pSnd->m_fVolume * 10000); - if (!snd->Is3d) - snd->DSBuffer->SetVolume(snd->Volume); + if (!pSnd->m_is3d) + pSnd->m_pSoundBuffer->SetVolume(iVolume); } } -long MainSound::SoundVolumeGet(ID id, int type) +float CSoundManager::soundGetVolume(ID id) { SOUND_PRECOND(id, 0); - Sound* snd = ArrSounds[id]; - static long volume = 0; - if (snd->DSBuffer) - { - if (type == SOUND_VOL_DB) - { - if (snd->Is3d) - volume = snd->Volume; - else - snd->DSBuffer->GetVolume(&volume); - } - else if (type == SOUND_VOL_PCT) - { - if (snd->Is3d) - { - double one_percent = 100.0 / (-10000.0); - volume = double(snd->Volume) * one_percent; - } - else - { - double one_percent = 100.0 / (-10000.0); - snd->DSBuffer->GetVolume(&volume); - volume = double(volume) * one_percent; - } - } - } - return volume; + CSound *pSnd = m_aSounds[id]; + return pSnd->m_fVolume; } -void MainSound::SoundPanSet(ID id, long value, int type) +void CSoundManager::soundSetPan(ID id, float fPan) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; - static long Value = 0; - if (snd->DSBuffer) + CSound *pSnd = m_aSounds[id]; + + if (pSnd->m_is3d) + return; + + pSnd->m_fPan = clampf(fPan,-1.f,1.f); + + if (pSnd->m_pSoundBuffer) { - if (type == SOUND_VOL_DB || value == 0) - Value = value; - else if (type == SOUND_VOL_PCT && value != 0) - Value = (value > 0) ? (10000 - (value * 100)) - 10000 : 10000 - (10000 + (value * 100)); + long lValue = (pSnd->m_fPan > 0) ? (10000 - (pSnd->m_fPan * 100)) - 10000 : 10000 - (10000 + (pSnd->m_fPan * 100)); - snd->DSBuffer->SetPan(Value); + pSnd->m_pSoundBuffer->SetPan(lValue); } } -long MainSound::SoundPanGet(ID id, int type) +float CSoundManager::soundGetPan(ID id) { SOUND_PRECOND(id, 0); - Sound* snd = ArrSounds[id]; - static long Value = 0; - if (snd->DSBuffer) - { - if (type == SOUND_VOL_DB) - snd->DSBuffer->GetPan(&Value); - else - { - double coef_percent = 100.0 / (10000.0); - snd->DSBuffer->GetPan(&Value); - Value = double(Value) * coef_percent; - } - } - return Value; + CSound *pSnd = m_aSounds[id]; + + if (pSnd->m_is3d) + return 0; + + return pSnd->m_fPan; } -void MainSound::SoundFreqCurrSet(ID id, DWORD value) +void CSoundManager::soundSetFreqCurr(ID id, UINT value) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; - if (snd->DSBuffer) - snd->DSBuffer->SetFrequency(value); + CSound* snd = m_aSounds[id]; + if (snd->m_pSoundBuffer) + snd->m_pSoundBuffer->SetFrequency(value); } -DWORD MainSound::SoundFreqCurrGet(ID id) +UINT CSoundManager::soundGetFreqCurr(ID id) { SOUND_PRECOND(id, 0); - Sound* snd = ArrSounds[id]; + CSound* snd = m_aSounds[id]; static DWORD Value = 0; - if (snd->DSBuffer) - snd->DSBuffer->GetFrequency(&Value); + if (snd->m_pSoundBuffer) + snd->m_pSoundBuffer->GetFrequency(&Value); return Value; } -DWORD MainSound::SoundFreqOriginGet(ID id) +UINT CSoundManager::soundGetFreqOrigin(ID id) { SOUND_PRECOND(id, 0); - Sound* snd = ArrSounds[id]; - if (snd->DSBuffer) - return snd->FrecOrigin; + CSound* snd = m_aSounds[id]; + if (snd->m_pSoundBuffer) + return snd->m_uiFrecOrigin; return 0; } -void MainSound::SoundPosWSet(ID id, const float3* pos) +void CSoundManager::soundSetPosWorld(ID id, const float3* pos) { SOUND_PRECOND(id, _VOID); if (pos) - ArrSounds[id]->Position = *pos; + m_aSounds[id]->m_vPosition = *pos; } -void MainSound::SoundPosWGet(ID id, float3* pos) +void CSoundManager::soundGetPosWorld(ID id, float3* pos) { SOUND_PRECOND(id, _VOID); if (pos) - *pos = ArrSounds[id]->Position; + *pos = m_aSounds[id]->m_vPosition; } -int MainSound::SoundLengthSecGet(ID id) +int CSoundManager::soundGetLengthSec(ID id) { SOUND_PRECOND(id, 0); - return ArrSounds[id]->LengthSec; + return m_aSounds[id]->m_iLengthSec; } -DWORD MainSound::SoundBytesPerSecGet(ID id) +UINT CSoundManager::soundGetBytesPerSec(ID id) { SOUND_PRECOND(id, 0); - return ArrSounds[id]->BytesPerSec; + return m_aSounds[id]->m_uiBytesPerSec; } -DWORD MainSound::SoundSizeGet(ID id) +UINT CSoundManager::soundGetSize(ID id) { SOUND_PRECOND(id, 0); - return ArrSounds[id]->SizeFull; + return m_aSounds[id]->m_uiSizeFull; } -void MainSound::SoundFileGet(ID id, char* path) +void CSoundManager::soundGetFile(ID id, char* path) { SOUND_PRECOND(id, _VOID); if(path) - strcpy(path,ArrSounds[id]->RPath); + strcpy(path,m_aSounds[id]->m_szRPath); } -float MainSound::SoundDistAudibleGet(ID id) +float CSoundManager::soundGetDistAudible(ID id) { SOUND_PRECOND(id, 0); - return ArrSounds[id]->DistAudible; + return m_aSounds[id]->m_fDistAudible; } -void MainSound::SoundDistAudibleSet(ID id, float value) +void CSoundManager::soundSetDistAudible(ID id, float value) { SOUND_PRECOND(id, _VOID); - ArrSounds[id]->DistAudible = value; + m_aSounds[id]->m_fDistAudible = value; } //############################################################################# -void MainSound::ReLoadSplit(ID id, DWORD Pos, DWORD Size) +void CSoundManager::reLoadSplit(ID id, UINT Pos, UINT Size) { SOUND_PRECOND(id, _VOID); - Sound* snd = ArrSounds[id]; - if (snd->DSBuffer) + CSound* snd = m_aSounds[id]; + if (snd->m_pSoundBuffer) { //wav - if (snd->Format == SOUND_FILEFORMAT_WAV) - SoundDataWAVLoad(snd->DSBuffer, Pos, snd->StreamFile, Size, 0); + if (snd->m_format == SOUND_FILEFORMAT_WAV) + soundDataWAVLoad(snd->m_pSoundBuffer, Pos, snd->m_pStream, Size, 0); //ogg - else if (snd->Format == SOUND_FILEFORMAT_OGG) + else if (snd->m_format == SOUND_FILEFORMAT_OGG) { - SoundDataOGGLoad(snd->VorbisFile, snd->DSBuffer, Pos, Size, 0); + soundDataOGGLoad(snd->m_pVorbisFile, snd->m_pSoundBuffer, Pos, Size, 0); + } + } +} + +void CSoundManager::UpdatePlayDelay(CSoundBase *pSndBase) +{ + if (!pSndBase) + return; + + DWORD dwStatus = 0; + + //если вопроизведение с задержками + if (pSndBase->m_isPlayDelay) + { + if (pSndBase->m_state == SOUND_OBJSTATE_PLAY && pSndBase->m_isLooping && pSndBase->oPlayDelay.m_iCurrPlayDelay == -1 && SUCCEEDED(pSndBase->m_pSoundBuffer->GetStatus(&dwStatus)) && !(dwStatus & DSBSTATUS_PLAYING)) + { + pSndBase->oPlayDelay.m_iCurrPlayDelay = 0; + pSndBase->oPlayDelay.m_uiPlayDelayStart = 0; + pSndBase->m_pSoundBuffer->SetCurrentPosition(0); + pSndBase->m_pSoundBuffer->Play(0, 0, 0); + } + + dwStatus = 0; + + DWORD dwCurrPos = 0; + + pSndBase->m_pSoundBuffer->GetCurrentPosition(&dwCurrPos, 0); + dwCurrPos = dwCurrPos / (pSndBase->m_uiBytesPerSec / 1000); + + //если текущий ключ в массиве задержек валиден + if (pSndBase->oPlayDelay.m_iCurrPlayDelay >= 0 && pSndBase->oPlayDelay.m_aPlayDelay.size() > pSndBase->oPlayDelay.m_iCurrPlayDelay) + { + if ( + //если текущий ключ в массиве это не задержка и текущая время воспроизведения больше либо равно установленному + (!(pSndBase->oPlayDelay.m_aPlayDelay[pSndBase->oPlayDelay.m_iCurrPlayDelay].m_isDelay) && dwCurrPos >= pSndBase->oPlayDelay.m_aPlayDelay[pSndBase->oPlayDelay.m_iCurrPlayDelay].m_uiTime) || + + //если текущий ключ в массиве это задержка и время с засечки уже превысило установленное значение либо равно ему + (pSndBase->oPlayDelay.m_aPlayDelay[pSndBase->oPlayDelay.m_iCurrPlayDelay].m_isDelay && (GetTickCount() - pSndBase->oPlayDelay.m_uiPlayDelayStart) >= pSndBase->oPlayDelay.m_aPlayDelay[pSndBase->oPlayDelay.m_iCurrPlayDelay].m_uiTime) + ) + { + //инкрементируем текущий ключ + ++(pSndBase->oPlayDelay.m_iCurrPlayDelay); + + //если следующий ключ валиден + if (pSndBase->oPlayDelay.m_aPlayDelay.size() > pSndBase->oPlayDelay.m_iCurrPlayDelay) + { + //если задержка + if (pSndBase->oPlayDelay.m_aPlayDelay[pSndBase->oPlayDelay.m_iCurrPlayDelay].m_isDelay) + { + //естанавливаем и засекаем время + pSndBase->m_pSoundBuffer->Stop(); + pSndBase->oPlayDelay.m_uiPlayDelayStart = GetTickCount(); + } + else + { + //воспроизводим и обнуляем засечку + pSndBase->m_pSoundBuffer->Play(0, 0, 0); + pSndBase->oPlayDelay.m_uiPlayDelayStart = 0; + } + } + //иначе ключ в массиве задержек невалиден + else + { + //воспроизводим остаток и обнуляем данные настроек + pSndBase->m_pSoundBuffer->Play(0, 0, 0); + + if (!(pSndBase->m_isLooping)) + pSndBase->m_isPlayDelay = false; + + pSndBase->oPlayDelay.m_iCurrPlayDelay = -1; + pSndBase->oPlayDelay.m_uiPlayDelayStart = 0; + } + } } } } -void MainSound::Update(const float3* viewpos, const float3* viewdir) +void CSoundManager::update(const float3* viewpos, const float3* viewdir) { int tmpSoundsPlayCount = 0; int tmpSoundsLoadCount = 0; - Sound* snd; - DWORD status = 0; - for(UINT i = 0; i < ArrSounds.size(); ++i) + CSound *pSnd = 0; + DWORD dwStatus = 0; + for(UINT i = 0; i < m_aSounds.size(); ++i) { - snd = ArrSounds[i]; - if(snd) + pSnd = m_aSounds[i]; + + //если есть звук и его канал вопроизводится + if (pSnd && m_aChannels[pSnd->m_idChannel]) { - status = 0; - snd->DSBuffer->GetStatus(&status); - if(!(status & DSBSTATUS_PLAYING) && snd->State == SOUND_OBJSTATE_PLAY) - SoundStateSet(i, SOUND_OBJSTATE_STOP); + //если вопроизведение с задержками + if (pSnd->m_state == SOUND_OBJSTATE_PLAY && pSnd->m_uiStreamSize == 0 && pSnd->m_isPlayDelay) + { + UpdatePlayDelay((CSoundBase*)pSnd); + } + + dwStatus = 0; + + //если звук воспроизводится без задержек и буфер уже не прогирывается а состояние звука "проигрывается" тогда выключаем звук + if (!pSnd->m_isPlayDelay && SUCCEEDED(pSnd->m_pSoundBuffer->GetStatus(&dwStatus)) && !(dwStatus & DSBSTATUS_PLAYING) && pSnd->m_state == SOUND_OBJSTATE_PLAY) + soundSetState(i, SOUND_OBJSTATE_STOP); ++tmpSoundsLoadCount; - if(snd->State == SOUND_OBJSTATE_PLAY) + if(pSnd->m_state == SOUND_OBJSTATE_PLAY) ++tmpSoundsPlayCount; - if(snd->Is3d && snd->DSBuffer && viewpos && viewdir) + + //если анализируемый звук 3d + if(pSnd->m_is3d && pSnd->m_pSoundBuffer && viewpos && viewdir) { - snd->DSBuffer->SetVolume(SOUND_3D_COM_VOLUME(snd->Position, (*viewpos), snd->DistAudible)); - snd->DSBuffer->SetPan(SOUND_3D_COM_PAN(snd->Position, (*viewpos), (*viewdir), snd->DistAudible, snd->ShiftPan)); + //устанавливаем ему параметры воспроизведения + pSnd->m_pSoundBuffer->SetVolume(lerpf(-10000, 0, pSnd->m_fVolume * Snd3dComVolume(pSnd->m_vPosition, (*viewpos), pSnd->m_fDistAudible))); + pSnd->m_pSoundBuffer->SetPan(Snd3dComPan(pSnd->m_vPosition, (*viewpos), (*viewdir), pSnd->m_fDistAudible, pSnd->m_fShiftPan)); - if(snd->DataInstances.size() > 0) + //если есть инстансы + if(pSnd->m_aInstances.size() > 0) { - for(int k = 0, l = snd->DataInstances.size(); k < l; ++k) + //проходимся по всему массиву инстансов и устанавливаем параметры воспроизведения + for(int k = 0, l = pSnd->m_aInstances.size(); k < l; ++k) { - snd->DSBuffer->SetVolume(SOUND_3D_COM_VOLUME(snd->DataInstances[k].pos, (*viewpos), snd->DistAudible)); - snd->DSBuffer->SetPan(SOUND_3D_COM_PAN(snd->DataInstances[k].pos, (*viewpos), (*viewdir), snd->DistAudible, snd->ShiftPan)); + pSnd->m_pSoundBuffer->SetVolume(lerpf(-10000, 0, pSnd->m_fVolume * Snd3dComVolume(pSnd->m_aInstances[k].m_vPos, (*viewpos), pSnd->m_fDistAudible))); + pSnd->m_pSoundBuffer->SetPan(Snd3dComPan(pSnd->m_aInstances[k].m_vPos, (*viewpos), (*viewdir), pSnd->m_fDistAudible, pSnd->m_fShiftPan)); } } } - for(int k = 0, l = snd->DataInstances.size(); k < l; ++k) + for(int k = 0, kl = pSnd->m_aInstances.size(); k < kl; ++k) { - status = 0; - if(SUCCEEDED(snd->DataInstances[k].sbuffer->GetStatus(&status)) && !(status & DSBSTATUS_PLAYING)) - snd->DataInstances[k].busy = false; + //нужно ли это здесь? + /*if (pSnd->m_aInstances[k].m_state != SOUND_OBJSTATE_PLAY) + continue;*/ + + //если вопроизведение с задержками + if (pSnd->m_aInstances[k].m_isPlayDelay) + { + if (pSnd->m_aInstances[k].m_state == SOUND_OBJSTATE_PLAY) + UpdatePlayDelay(&(pSnd->m_aInstances[k])); + } + //иначе не установлено что звук воспроизводится с задержками + else + { + //обрабатываем состояния + dwStatus = 0; + + //если буфер не проигрывается и состояние инстанса "временно блокирован", тогда освобождаем инстанс + if (SUCCEEDED(pSnd->m_aInstances[k].m_pSoundBuffer->GetStatus(&dwStatus)) && !(dwStatus & DSBSTATUS_PLAYING) && pSnd->m_aInstances[k].m_busy != SOUND_SNDINSTANCE_BUSY_LOCKED) + pSnd->m_aInstances[k].m_busy = SOUND_SNDINSTANCE_BUSY_FREE; + + //если буфер инстанса не проигрывается а состояние инстанса "проигрывается", тогда устанавливаем состояние "непроигрывается" + if (pSnd->m_aInstances[k].m_state == SOUND_OBJSTATE_PLAY && !(dwStatus & DSBSTATUS_PLAYING)) + pSnd->m_aInstances[k].m_state = SOUND_OBJSTATE_STOP; + } } - if(snd->StreamSize && snd->DSBuffer != 0) + if(pSnd->m_uiStreamSize && pSnd->m_pSoundBuffer != 0) { DWORD pos; - snd->DSBuffer->GetCurrentPosition(&pos, 0); + pSnd->m_pSoundBuffer->GetCurrentPosition(&pos, 0); - if(pos >= snd->Split1Size && pos < snd->Split2Size && !snd->BF2) + if (pos >= pSnd->m_uiSplit1Size && pos < pSnd->m_uiSplit2Size && !pSnd->m_isWork2) { - ReLoadSplit(i, 0, snd->Split1Size); - snd->BF2 = true; - snd->BF1 = false; snd->BF3 = false; snd->BF4 = false; - snd->SplitActive = 2; + reLoadSplit(i, 0, pSnd->m_uiSplit1Size); + pSnd->m_isWork2 = true; + pSnd->m_isWork1 = false; pSnd->m_isWork3 = false; pSnd->m_isWork4 = false; + pSnd->m_iSplitActive = 2; } - else if(pos >= snd->Split2Size && pos < snd->Split3Size && !snd->BF3) + else if (pos >= pSnd->m_uiSplit2Size && pos < pSnd->m_uiSplit3Size && !pSnd->m_isWork3) { - snd->BF3 = true; - snd->BF1 = false; snd->BF2 = false; snd->BF4 = false; - ReLoadSplit(i, snd->Split1Size, snd->Split1Size); - snd->SplitActive = 3; + pSnd->m_isWork3 = true; + pSnd->m_isWork1 = false; pSnd->m_isWork2 = false; pSnd->m_isWork4 = false; + reLoadSplit(i, pSnd->m_uiSplit1Size, pSnd->m_uiSplit1Size); + pSnd->m_iSplitActive = 3; } - else if(pos >= snd->Split3Size && pos < snd->StreamSize && !snd->BF4) + else if (pos >= pSnd->m_uiSplit3Size && pos < pSnd->m_uiStreamSize && !pSnd->m_isWork4) { - snd->BF4 = true; - snd->BF1 = false; snd->BF2 = false; snd->BF3 = false; - ReLoadSplit(i, snd->Split2Size, snd->Split1Size); - snd->SplitActive = 4; + pSnd->m_isWork4 = true; + pSnd->m_isWork1 = false; pSnd->m_isWork2 = false; pSnd->m_isWork3 = false; + reLoadSplit(i, pSnd->m_uiSplit2Size, pSnd->m_uiSplit1Size); + pSnd->m_iSplitActive = 4; } - else if(pos < snd->Split1Size && !snd->BF1) + else if (pos < pSnd->m_uiSplit1Size && !pSnd->m_isWork1) { - snd->BF1 = true; - snd->BF2 = false; snd->BF3 = false; snd->BF4 = false; - if(!snd->IsStarting) + pSnd->m_isWork1 = true; + pSnd->m_isWork2 = false; pSnd->m_isWork3 = false; pSnd->m_isWork4 = false; + if(!pSnd->m_isStarting) { - ReLoadSplit(i, snd->Split3Size, snd->Split1Size); - snd->RePlayCount++; + reLoadSplit(i, pSnd->m_uiSplit3Size, pSnd->m_uiSplit1Size); + pSnd->m_iRePlayCount++; } - snd->SplitActive = 1; - snd->IsStarting = false; + pSnd->m_iSplitActive = 1; + pSnd->m_isStarting = false; } - if(snd->RePlayCount + 1 == snd->RePlayEndCount) + if(pSnd->m_iRePlayCount + 1 == pSnd->m_iRePlayEndCount) { - if(snd->SizeFull <= (snd->StreamSize * snd->RePlayCount + pos)) + if(pSnd->m_uiSizeFull <= (pSnd->m_uiStreamSize * pSnd->m_iRePlayCount + pos)) { - if(!snd->IsLooping) - SoundStop(i); + if(!pSnd->m_isLooping) + soundStop(i); //wav - if(snd->Format == SOUND_FILEFORMAT_WAV) - fseek(snd->StreamFile, sizeof(SoundWaveHeader), SEEK_SET); + if(pSnd->m_format == SOUND_FILEFORMAT_WAV) + fseek(pSnd->m_pStream, sizeof(CSoundWaveHeader), SEEK_SET); //ogg - else if(snd->Format == SOUND_FILEFORMAT_OGG) - ov_pcm_seek(snd->VorbisFile, 0); + else if(pSnd->m_format == SOUND_FILEFORMAT_OGG) + ov_pcm_seek(pSnd->m_pVorbisFile, 0); - ReLoadSplit(i, 0, snd->StreamSize); + reLoadSplit(i, 0, pSnd->m_uiStreamSize); - snd->DSBuffer->SetCurrentPosition(0); + pSnd->m_pSoundBuffer->SetCurrentPosition(0); - snd->RePlayCount = 0; - snd->IsStarting = true; + pSnd->m_iRePlayCount = 0; + pSnd->m_isStarting = true; - snd->BF1 = false; snd->BF2 = false; snd->BF3 = false; snd->BF4 = false; + pSnd->m_isWork1 = false; pSnd->m_isWork2 = false; pSnd->m_isWork3 = false; pSnd->m_isWork4 = false; } } } } } - SoundsPlayCount = tmpSoundsPlayCount; - SoundsLoadCount = tmpSoundsLoadCount; + m_iSoundsPlayCount = tmpSoundsPlayCount; + m_iSoundsLoadCount = tmpSoundsLoadCount; - OldViewPos = *viewpos; - OldViewDir = *viewdir; + m_vOldViewPos = *viewpos; + m_vOldViewDir = *viewdir; } -int MainSound::SoundsPlayCountGet() +int CSoundManager::soundsGetPlayCount() { - return SoundsPlayCount; + return m_iSoundsPlayCount; } -int MainSound::SoundsLoadCountGet() +int CSoundManager::soundsGetLoadCount() { - return SoundsLoadCount; + return m_iSoundsLoadCount; } diff --git a/source/score/sound.h b/source/score/sound.h index a5fe99dde8c8e2cb64cce4c565091fc602ec71fb..b2349a66a4b6648fd913a28a58b12f4a933f1ae9 100644 --- a/source/score/sound.h +++ b/source/score/sound.h @@ -1,31 +1,36 @@ - -/*********************************************************** -Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2017, 2018 -See the license in LICENSE -***********************************************************/ - -#ifndef __SOUND_H -#define __SOUND_H - -#pragma comment(lib, "dxguid.lib") -#pragma comment(lib, "dsound.lib") -#pragma comment(lib, "libogg_static.lib") -#pragma comment(lib, "libvorbis_static.lib") -#pragma comment(lib, "libvorbisfile_static.lib") -#include <gdefines.h> -#include <windows.h> -#include <mmsystem.h> -#include <dsound.h> -#include <stdint.h> -#include <vorbis/codec.h> -#include <vorbis/vorbisfile.h> -#include <common/aastring.h> -#include <common/array.h> -#include <common/assotiativearray.h> -#include "sxscore.h" - -struct AAStringNR : public AAString -{ + +/*********************************************************** +Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2017, 2018 +See the license in LICENSE +***********************************************************/ + +#ifndef __SOUND_H +#define __SOUND_H + +#pragma comment(lib, "dxguid.lib") +#pragma comment(lib, "dsound.lib") +#pragma comment(lib, "libogg_static.lib") +#pragma comment(lib, "libvorbis_static.lib") +#pragma comment(lib, "libvorbisfile_static.lib") +#include <gdefines.h> +#include <windows.h> +#include <mmsystem.h> +#include <dsound.h> +#include <stdint.h> +#include <vorbis/codec.h> +#include <vorbis/vorbisfile.h> +#include <common/aastring.h> +#include <common/array.h> +#include <common/string.h> +#include <common/string_func.h> +#include <common/assotiativearray.h> +#include "sxscore.h" + +//########################################################################## + +//перенести в common +struct AAStringNR : public AAString +{ __forceinline AAStringNR(const char * str) { tmpName = str; @@ -36,238 +41,613 @@ struct AAStringNR : public AAString { tmpName = NULL; Name[0] = 0; - } - + } + __forceinline bool operator==(const AAStringNR & str) const { return(stricmp(tmpName ? tmpName : Name, str.tmpName ? str.tmpName : str.Name) == 0); - } -}; - - -#define SOUND_PRECOND(id, retval) \ -if((UINT)id >= ArrSounds.size() || !(ArrSounds[id]))\ + } +}; + +//########################################################################## + +/*! проверка допустимости id звука, в случае провала вылет */ +#define SOUND_PRECOND(id, retval) \ +if (id >= m_aSounds.size() || id < 0 || !(m_aSounds[id]))\ {LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved address to sound %d", GEN_MSG_LOCATION, id); return retval; } - -inline long SOUND_3D_COM_VOLUME(const float3 & snd_pos, const float3 & view_pos, const float snd_distaudible) -{ - long vol = (SMVector3Distance(snd_pos, view_pos) / snd_distaudible) * (-10000); - - if (vol > 0) - vol = 0; - - if (vol < -10000) - vol = -10000; - - return vol; -} - -//чтение файла -size_t ogg_read(void *ptr, size_t size, size_t nmemb, void *datasource); -//закртытие файла -int ogg_close(void* datasource); -//позиционирование -int ogg_seek(void *datasource, ogg_int64_t offset, int whence); -//размер файла -long ogg_tell(void* datasource); - -inline long SOUND_3D_COM_PAN(const float3 & snd_pos, const float3 & view_pos, const float3 & view_dir, const float snd_distaudible, const float snd_shiftpan) -{ - float dist = SMVector3Distance(snd_pos, view_pos); - float3 vec = view_pos + view_dir; - - float str = (snd_pos.x - view_pos.x)*(snd_pos.z - vec.z) - (snd_pos.z - view_pos.z)*(snd_pos.x - vec.x); - return ((str * (dist / snd_distaudible)) * snd_shiftpan * (-10000)); -} - -//структура для загрузки wave файла -struct SoundWaveHeader -{ - char RiffSig[4]; - int32_t ChunkSize; - char Sig[4]; - char FormatSig[4]; - int32_t FormatChunkSize; - int16_t FormatTag; - int16_t Channels; - int32_t SampleRate; - int32_t BytesPerSec; - int16_t BlockAlign; - int16_t BitsPerSample; - char DataSig[4]; - int32_t DataSize; -}; - - -class MainSound -{ -public: - MainSound(); - ~MainSound(); - - SX_ALIGNED_OP_MEM - - void Clear(); - - void Init(HWND hwnd); - - struct Sound - { - Sound(); - ~Sound(); - SX_ALIGNED_OP_MEM - - char RPath[SOUND_MAX_SIZE_PATH]; - ID Id; - bool IsInst; - FILE* StreamFile; - IDirectSoundBuffer8* DSBuffer; //звуковой буфер - OggVorbis_File* VorbisFile; //поток для декодирования ogg - - struct SIData - { - SIData(){ sbuffer = 0; busy = false; } - SIData(IDirectSoundBuffer8* _sbuffer, float3_t* _pos, bool _busy) - { - sbuffer = _sbuffer; if (_pos) pos = *_pos; busy = _busy; - } - ~SIData() - { - mem_release(sbuffer); - } - - IDirectSoundBuffer8* sbuffer; - float3_t pos; - bool busy; - }; - - Array<SIData> DataInstances; - - SOUND_FILEFORMAT Format; //формат файла - DWORD SizeFull; //полный размер в байтах (для wav исключая заголовочную структуру) - - float3 Position; //позиция источника звука - //float Damping; //сброс громкости при отдалении на метр, т.е. count_volume = volume - dist * Damping % - - //изменение позиционирования звука, на сколько будет смещен звук при поворотах камеры к источнику звука - //чем ближе к объекту тем меньше разница в позиционировании при поворотах - float ShiftPan; - - SOUND_OBJSTATE State; - DWORD FrecOrigin; //оригинальная частота - - float DistAudible; - - DWORD StreamSize;//размер потока в байтах - int LengthSec; - int ChannelsCount; - int RateSample; - int BitsPerSample; - DWORD BytesPerSec; - long Volume; - - //размеры сплитов потока - DWORD Split1Size; - DWORD Split2Size; - DWORD Split3Size; - - //заглушки для работы апдейта на каждый сплит в отдельности - bool BF1; - bool BF2; - bool BF3; - bool BF4; - - bool IsLooping; //зацикливать воспроизведние? - bool IsStarting; //воспроизведение только началось? (для потока) - bool Is3d; - - short SplitActive; //активный сплит - int RePlayCount; //сколько раз был полностью перезагружен поток - int RePlayEndCount; //сколько раз нужно полностью перезагрузить поток чтоб дойти до конца - }; - - ID SoundCreate2d(const char *file, bool looping = false, DWORD size_stream = 0); - ID SoundCreate3d(const char *file, bool looping, DWORD size_stream, float dist, float shift_pan = 0.1f); - - ID SoundCreate2dInst(const char *file, bool looping = false, DWORD size_stream = 0); - ID SoundCreate3dInst(const char *file, bool looping, DWORD size_stream, float dist, float shift_pan = 0.1f); - - ID SoundFind2dInst(const char * file); - ID SoundFind3dInst(const char * file); - - void SoundInstancePlay2d(ID id, int volume=100, int pan = 0); - void SoundInstancePlay3d(ID id, const float3* pos); - - bool SoundIsInit(ID id); - void SoundDelete(ID id); - - void SoundPlay(ID id, int looping=-1); //проиграть - void SoundPause(ID id); //приостановить - void SoundStop(ID id); //остановить - - void SoundStateSet(ID id, SOUND_OBJSTATE state); - SOUND_OBJSTATE SoundStateGet(ID id); - - //текащая позиция проигрывания - void SoundPosCurrSet(ID id, DWORD pos, int type = SOUND_POS_BYTES); - DWORD SoundPosCurrGet(ID id, int type = SOUND_POS_BYTES); - - //громкость - void SoundVolumeSet(ID id, long volume, int type = SOUND_VOL_PCT); - long SoundVolumeGet(ID id, int type = SOUND_VOL_PCT); - - //позиционирование между динамиками - void SoundPanSet(ID id, long value, int type = SOUND_VOL_PCT); - long SoundPanGet(ID id, int type = SOUND_VOL_PCT); - - //частота - void SoundFreqCurrSet(ID id, DWORD value); - DWORD SoundFreqCurrGet(ID id); - DWORD SoundFreqOriginGet(ID id); - - void SoundPosWSet(ID id, const float3* pos); - void SoundPosWGet(ID id, float3* pos); - - int SoundLengthSecGet(ID id); //длина в секундах - DWORD SoundBytesPerSecGet(ID id); //байт в секунде - DWORD SoundSizeGet(ID id); //размер в байтах PCM данных - void SoundFileGet(ID id, char* path);//путь до звукового файла - - float SoundDistAudibleGet(ID id); - void SoundDistAudibleSet(ID id, float value); - - void Update(const float3* viewpos, const float3* viewdir); - - SOUND_FILEFORMAT FileFormat(const char* file); - - int SoundsPlayCountGet(); - int SoundsLoadCountGet(); - -private: - - void Load(Sound* snd, const char* fpath, SOUND_FILEFORMAT fmt); - - void LoadWAV(Sound* snd, const char* fpath); - void LoadOGG(Sound* snd, const char* fpath); - IDirectSoundBuffer8* SoundBufferCreate(SoundWaveHeader* hdr); - void SoundDataWAVLoad(IDirectSoundBuffer8* DSBuffer, long LockPos, FILE* data, long Size, DWORD flag = 0); - void SoundDataOGGLoad(OggVorbis_File* VorbisFile, IDirectSoundBuffer8 *DSBuffer, long LockPos, long Size, DWORD flag); - - void ReLoadSplit(ID id, DWORD Pos, DWORD Size); - - ID AddSound(Sound* snd); - - Array<Sound*> ArrSounds; //массив со всеми звуковыми объектами - AssotiativeArray<AAStringNR, ID, false, 16> AArr2dInst; - AssotiativeArray<AAStringNR, ID, false, 16> AArr3dInst; - - IDirectSound8* DeviceSound; //звуковое устройство - IDirectSoundBuffer* DSPrimary; //первичный буфер - int SoundsPlayCount; //количество проигрываемых звуков - int SoundsLoadCount; //количество загруженных звуков (с учетом как проигрывающихся так и простаивающих) - - float3 OldViewPos; - float3 OldViewDir; -}; - -#endif + +/*! создание имени звука (нужно для разделения между каналами */ +#define SOUND_CREATE_NAME(szStr, szFile, idChannel) sprintf(szStr, "%d|%s", idChannel, szFile); + +/*! проверка допустимости id канала, в случае провала вылет */ +#define SOUND_CHANNEL_PRECOND(id, retval) \ +if (!(id >= 0 && id < SOUND_CHANNELS_COUNT)) \ +{LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved id channel %d", GEN_MSG_LOCATION, id); return retval; } + +/*! проверка проигрываемости канала */ +#define SOUND_CHANNEL_PLAYING(id, retval) \ +if (m_aChannels[id] != 1) \ +{return retval; } + +/*! проверка допустимости id набора звуков, в случае провала вылет */ +#define SOUND_SNDKIT_PRECOND(id, retval) \ +if (!(id >= 0 && id < m_aSoundKits.size() && m_aSoundKits[id])) \ +{LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved id sound kit %d", GEN_MSG_LOCATION, id); return retval; } + +//########################################################################## + +//! просчет громкости звука, пределы [0, 1] +inline float Snd3dComVolume( + const float3 &vSndPos, //!< позиция звука + const float3 &vViewPos, //!< позиция слушателя + const float fDistAudible //!< дистанция слышимости + ) +{ + float fVolume = 1.f - (SMVector3Distance(vSndPos, vViewPos) / fDistAudible);// *(-10000); + + return saturatef(fVolume); +} + +//! просчет смещения звука между ушами слушателя +inline int Snd3dComPan( + const float3 &vSndPos, //!< позиция звука + const float3 &vViewPos, //!< позиция слушателя + const float3 &vViewDir, //!< направление взгляда слушателя + const float fDistAudible, //!< дистанция слышимости + const float fShiftPan //!< коэфициент смещения между ушами слушателя + ) +{ + float fDist = SMVector3Distance(vSndPos, vViewPos); + float3 fVec = vViewPos + vViewDir; + + float str = (vSndPos.x - vViewPos.x)*(vSndPos.z - fVec.z) - (vSndPos.z - vViewPos.z)*(vSndPos.x - fVec.x); + return ((str * (fDist / fDistAudible)) * fShiftPan * float(-10000)); +} + +//! парсинг строки szSrcStr на составляющие элементы (если есть): путь до звука и параметры воспроизведения +inline bool SndGetDataFromStr(const char *szSrcStr, String &sFile, float &fDistAudible, float &fVolume, Array<UINT> &aDelays) +{ + bool existsData = false; + + Array<String> aStrConfig = StrExplode(szSrcStr, " ", false); + + if (aStrConfig[0].length() == 0) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - invalid file", GEN_MSG_LOCATION); + return false; + } + + sFile = StrTrim(aStrConfig[0].c_str()); + + if (aStrConfig.size() >= 2) + { + if (aStrConfig[1][0] == 'd' || aStrConfig[1][0] == 'v') + existsData = true; + + if (aStrConfig[1][0] == 'd') + sscanf(aStrConfig[1].c_str() + 1, "%f", &fDistAudible); + else if (aStrConfig[1][0] == 'v') + sscanf(aStrConfig[1].c_str() + 1, "%f", &fVolume); + } + + if (aStrConfig.size() >= 3) + { + if (aStrConfig[2][0] == 'd' && fDistAudible > -2.f) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved double instruction for 'distance of audibility'", GEN_MSG_LOCATION); + return false; + } + + if (aStrConfig[2][0] == 'v' && fVolume > -2.f) + { + LibReport(REPORT_MSG_LEVEL_ERROR, "%s - unresolved double instruction for 'volume'", GEN_MSG_LOCATION); + return false; + } + + if (aStrConfig[2][0] == 'd' || aStrConfig[2][0] == 'v') + existsData = true; + + if (aStrConfig[2][0] == 'd') + sscanf(aStrConfig[2].c_str() + 1, "%f", &fDistAudible); + else if (aStrConfig[2][0] == 'v') + sscanf(aStrConfig[2].c_str() + 1, "%f", &fVolume); + } + + for (int k = 3, kl = aStrConfig.size(); k < kl; ++k) + { + String str = aStrConfig[k]; + aDelays.push_back(aStrConfig[k].ToUnsLongInt()); + } + + if (aDelays.size() > 0) + existsData = true; + + return existsData; +} + +//########################################################################## + +/*! \name Обработчики ogg +@{*/ + +//! чтение файла +size_t OggCallbackRead(void *ptr, size_t size, size_t nmemb, void *datasource); + +//! закртытие файла +int OggCallbackClose(void* datasource); + +//! позиционирование +int OggCallbackSeek(void *datasource, ogg_int64_t offset, int whence); + +//! размер файла +long OggCallbackTell(void* datasource); + +//!@} + +//########################################################################## + +//структура для загрузки wave файла +struct CSoundWaveHeader +{ + char RiffSig[4]; + int32_t ChunkSize; + char Sig[4]; + char FormatSig[4]; + int32_t FormatChunkSize; + int16_t FormatTag; + int16_t Channels; + int32_t SampleRate; + int32_t BytesPerSec; + int16_t BlockAlign; + int16_t BitsPerSample; + char DataSig[4]; + int32_t DataSize; +}; + +//########################################################################## + +//! менеджер звуков +class CSoundManager +{ +public: + CSoundManager(); + ~CSoundManager(); + + SX_ALIGNED_OP_MEM + + void clear(); + + void init(HWND hWnd); + + //! структура данных для воспроизведения с задержками + struct CPlayDelay + { + CPlayDelay() + { + m_iCurrPlayDelay = 0; + m_uiPlayDelayStart = 0; + } + + //! структура для хранения данных о текущей настройке проигрывания + struct CTimeDelay + { + CTimeDelay(){ m_uiTime = 0; m_isDelay = false; } + CTimeDelay(UINT uiTime, bool isDelay) + { + m_uiTime = uiTime; m_isDelay = isDelay; + } + + //! время в млсек + UINT m_uiTime; + + //! это время задержки в проигрывании или нет? + bool m_isDelay; + }; + + //! массив настроек прогирывания + Array<CTimeDelay> m_aPlayDelay; + + //! текущий индекс в #m_aPlayDelay + int m_iCurrPlayDelay; + + //! стартовое время задержки в млсек (если засекали время) + UINT m_uiPlayDelayStart; + + }; + + //! структура данных базового понятия звука + struct CSoundBase + { + CSoundBase() + { + m_pSoundBuffer = 0; m_state = SOUND_OBJSTATE_STOP; m_isLooping = false; m_isPlayDelay = false; m_uiBytesPerSec = 0; m_fVolume = 1.f; m_fPan = 0; + } + + ~CSoundBase() + { + mem_release(m_pSoundBuffer); + } + + //! звуковой буфер инстанса + IDirectSoundBuffer8 *m_pSoundBuffer; + + //! количество байт в секунде + UINT m_uiBytesPerSec; + + //! состояние воспроизведения + SOUND_OBJSTATE m_state; + + //! зацикливать ли воспроизведение + bool m_isLooping; + + //! используется ли воспроизведение с задержками + bool m_isPlayDelay; + + //! объект с данными проигрывания + CPlayDelay oPlayDelay; + + //! громкость [0, 1] + float m_fVolume; + + //! смещение между ушами слушателя [-1, 1] + float m_fPan; + }; + + //! структура данных инстанса звука + struct CSoundInstance : public CSoundBase + { + CSoundInstance(){ m_pSoundBuffer = 0; m_uiBytesPerSec = 0; m_busy = SOUND_SNDINSTANCE_BUSY_FREE; m_state = SOUND_OBJSTATE_STOP; m_isPlayDelay = false; } + CSoundInstance(IDirectSoundBuffer8 *pBuffer, UINT uiBytesPerSec, const float3_t *vPos, SOUND_SNDINSTANCE_BUSY busy) + { + m_pSoundBuffer = pBuffer; + m_uiBytesPerSec = uiBytesPerSec; + if (vPos) + m_vPos = *vPos; + m_busy = busy; + m_state = SOUND_OBJSTATE_STOP; + m_isPlayDelay = false; + } + + //! позиция воспроизведения (если надо) + float3_t m_vPos; + + //! занят ли инстанс в данный момент #SOUND_SNDINSTANCE_BUSY + SOUND_SNDINSTANCE_BUSY m_busy; + }; + + //! расширенное понятие звука + struct CSound : public CSoundBase + { + CSound(); + ~CSound(); + SX_ALIGNED_OP_MEM + + //! путь загруженного звука + char m_szRPath[SOUND_MAX_SIZE_PATH]; + + //! идентификатор (номер в общем массиве звуков) + ID m_id; + + //! канал + ID m_idChannel; + + //! 3д воспроизвдеение звука? + bool m_is3d; + + /*! количество загрузок звука, в основном сделано для инстансовых, если один и тот же звук загружался несколько раз то он будет загружен единожды, но счетчик будет показывать колиество, + и звук удалиться только тогда когда последний объект его удалит + */ + int m_iCountLoad; + + //! изменение позиционирования звука, на сколько будет смещен звук при поворотах камеры к источнику звука, чем ближе к объекту тем меньше разница в позиционировании при поворотах + float m_fShiftPan; + + //! дистанция слышимости + float m_fDistAudible; + + //! разрешено ли создавать инстансы звука (false по дефолту) + bool m_isInst; + + //! потом чтения файла + FILE *m_pStream; + + //! поток для декодирования ogg + OggVorbis_File *m_pVorbisFile; + + //! массив инстансов + Array<CSoundInstance> m_aInstances; + + //! формат файла + SOUND_FILEFORMAT m_format; + + //! полный размер в байтах (для wav исключая заголовочную структуру) + UINT m_uiSizeFull; + + //! позиция источника звука (если используется без инстансов, хотя устанавливается главному и при инстансах) + float3 m_vPosition; + + //сброс громкости при отдалении на метр, т.е. count_volume = volume - dist * Damping % + //float Damping; + + //! оригинальная частота + UINT m_uiFrecOrigin; + + //! размер потока в байтах + UINT m_uiStreamSize; + + //! длина звука в секундах + int m_iLengthSec; + + //! количество каналов + int m_iChannelsCount; + + //! частота дискретизации + int m_iSampleRate; + + //! количество бит в сэмпле + int m_iBitsPerSample; + + //размеры сплитов потока + UINT m_uiSplit1Size; + UINT m_uiSplit2Size; + UINT m_uiSplit3Size; + + //заглушки для работы апдейта на каждый сплит в отдельности + bool m_isWork1; + bool m_isWork2; + bool m_isWork3; + bool m_isWork4; + + //! воспроизведение только началось? (для потока) + bool m_isStarting; + + //! номер текущего активного сплита + int m_iSplitActive; + + //! сколько раз был полностью перезагружен поток + int m_iRePlayCount; + + //! сколько раз нужно полностью перезагрузить поток чтоб дойти до конца + int m_iRePlayEndCount; + }; + + //********************************************************************** + + //! набор звуков, для случайного воспроизведения звуков из массива однотипных звуков + struct СSoundKit + { + СSoundKit(); + ~СSoundKit(); + + //! имя набора + char m_szName[SOUND_MAX_SIZE_SNDKIT_NAME]; + + //! объект набора + struct CSoundKitObject + { + //! идентификатор звука + ID m_id; + + //! массив задержек + Array<UINT> m_aDelays; + + //! громкость звука [0,1] + float m_fVolume; + }; + + //! массив звуков + Array<CSoundKitObject> m_aSounds; + + //! канал набора звуков + ID m_idChannel; + + //! 3d (true) или 2d (false) набор? + bool m_is3D; + + //! общая дистанция слышимости для 3д звуков + float m_fDistAudible; + }; + + //! создать набор + ID sndkitCreate(const char *szName, ID idChannel, bool is3D, float fDistAudible = SOUND_DIST_AUDIBLE_DEFAULT); + + ID sndkitCreateFromList(const char *szName, ID idChannel, Array<String> aStrings, bool is3D, float fDistAudible = SOUND_DIST_AUDIBLE_DEFAULT, float fVolume = 1.f); + + //! добавить звук в набор, если fDistAudible < 0 то будут задействованы настройки самого набора + void sndkitAddSound(ID idSndKit, const char *szFile, float fDistAudible, float fVolume = 1.f, UINT *pArrDelay = 0, int iSizeArrDelay = 0); + + //! получить id по имени набора + ID sndkitGetID(const char *szName); + + //! получить номер канала + ID sndkitGetChannel(ID idSndKit); + + //! получить имя по id набора + void sndkitGetName(ID idSndKit, char *szName); + + //! удалить набор + void sndkitDelete(ID idSndKit); + + //! удалить все наборы + void sndkitDeleteAll(); + + /*! проиграть случайный звук + \note если набор 3д звуков, то позиция обязательна + \note id2 должен принимать либо #SOUND_SNDKIT_INSTANCE_BLOCK либо #SOUND_SNDKIT_INSTANCE_NOTBLOCK либо должен быть упакованным значением идентификаторов заблокированного инстанса звука + если инстанс воспроизводимого звука заблокирован, то он не будет использоваться другими пока владелец его не разблокирует + \return возвращает упакованные значения порядкового номера звука (в массиве набора) в 32 старших битах и id инстанса звука в 32 младших битах + */ + uint64_t sndkitPlay(ID idSndKit, uint64_t id2, const float3 *pPos = 0, float fVolume = -1.f, float fPan = 0.f); + + //! остановить проигрывание звуков в наборе + void sndkitStop(ID idSndKit, uint64_t id2); + + //********************************************************************** + + //! добавить канал + void channelAdd(ID idChannel, bool isPlaying = false); + + //! существует ил канал + bool channelExists(ID idChannel); + + //! количество звуков в канале + int channelGetSndCount(ID idChannel); + + //! проигрывать звуки канала + void channelPlay(ID idChannel); + + //! проигрывается ли канал? + bool channelPlaying(ID idChannel); + + //! остановить проигрывание звуков канала + void channelStop(ID idChannel); + + //! проигрывать звуки только этого канала + void channelPlayOnly(ID idChannel); + + //! воспроизвести звук канала (используется внутри функций каналов для воспроизведения каналов) + void channelSndPlay(ID idChannel, ID idSound); + + //! остановить звук канала (используется внутри функций каналов для воспроизведения каналов) + void channelSndStop(ID idChannel, ID idSound); + + //********************************************************************** + + ID soundCreate2d(const char *szFile, ID idChannel, UINT uiSizeStream = 0); + ID soundCreate3d(const char *szFile, ID idChannel, UINT uiSizeStream, float fDist); + + ID soundCreate2dInst(const char *szFile, ID idChannel); + ID soundCreate3dInst(const char *szFile, ID idChannel, float fDist); + + ID soundFind2dInst(const char *szFile, ID idChannel); + ID soundFind3dInst(const char *szFile, ID idChannel); + + /*! воспроизведение инстанса звука, если нужны задержки то надо их указывать в pArrDelay и iSizeArrDelay, иначе в обоих 0, + если нужен 3д звук (если это на самом деле 3д звук) то надо указать pPos, иначе 0 и будет 2д, для 2д по желанию можно указать громкость iVolume и смещение между ушами iPan + */ + ID soundInstancePlay(ID idSound, bool isBlocked, bool isLooping, UINT *pArrDelay, int iSizeArrDelay, const float3 *pPos, float fVolume = 1.f, float fPan = 0.f); + + bool soundInstancePlaying(ID idSound, ID idInstance); + void soundInstanceStop(ID idSound, ID idInstance); + void soundInstanceFree(ID idSound, ID idInstance); + + bool soundIsInit(ID idSound); + void soundDelete(ID idSound); + + //! проиграть + void soundPlay(ID idSound, bool isLooping = false, UINT *pArrDelay = 0, int iSizeArrDelay = 0); + + //! инициализация масисва задержек для воспроизведения звука, если указать iSizeArrDelay = -1 тогда будут задействованы прошлые настройки + void soundInitPlayDelay(CSoundBase *pSndbase, UINT *pArrDelay, int iSizeArrDelay); + + //! продолжить воспроизведение (с задержками) остановленного звука + void soundResumePlayDelay(CSoundBase *pSndBase); + + //! приостановить + void soundPause(ID idSound); + + //! остановить + void soundStop(ID idSound); + + void soundSetState(ID idSound, SOUND_OBJSTATE state); + SOUND_OBJSTATE soundGetState(ID idSound); + + //текащая позиция проигрывания + void soundSetPosPlay(ID idSound, UINT uiPos); + UINT soundGetPosPlay(ID idSound); + + //громкость + void soundSetVolume(ID idSound, float fVolume); + float soundGetVolume(ID idSound); + + //позиционирование между динамиками + void soundSetPan(ID idSound, float fPan); + float soundGetPan(ID idSound); + + //частота + void soundSetFreqCurr(ID idSound, UINT uiFrec); + UINT soundGetFreqCurr(ID idSound); + UINT soundGetFreqOrigin(ID idSound); + + void soundSetPosWorld(ID idSound, const float3 *pPos); + void soundGetPosWorld(ID idSound, float3 *pPos); + + + //длина в секундах + int soundGetLengthSec(ID idSound); + + //байт в секунде + UINT soundGetBytesPerSec(ID idSound); + + //размер в байтах PCM данных + UINT soundGetSize(ID idSound); + + //путь до звукового файла + void soundGetFile(ID idSound, char *szPath); + + float soundGetDistAudible(ID idSound); + void soundSetDistAudible(ID idSound, float fDistAudible); + + void UpdatePlayDelay(CSoundBase *pSndBase); + + void update(const float3 *pViewPos, const float3 *pViewDir); + + SOUND_FILEFORMAT fileFormat(const char *szFile); + + int soundsGetPlayCount(); + int soundsGetLoadCount(); + +private: + + void load(CSound *pSnd, const char *szPath, SOUND_FILEFORMAT fmt); + + void loadWAV(CSound *pSnd, const char *szPath); + + void loadOGG(CSound *pSnd, const char *szPath); + + IDirectSoundBuffer8* soundBufferCreate(CSoundWaveHeader *pHeader); + + void soundDataWAVLoad(IDirectSoundBuffer8 *pBuffer, int iLockPos, FILE *pData, int iSize, UINT uiFlag = 0); + void soundDataOGGLoad(OggVorbis_File *pVorbisFile, IDirectSoundBuffer8 *pBuffer, int iLockPos, int iSize, UINT uiFlag); + + void reLoadSplit(ID id, UINT Pos, UINT Size); + + ID addSound(CSound *pSnd); + + //********************************************************************** + + //! массив со всеми звуковыми объектами + Array<CSound*> m_aSounds; + + //! ассоциативный массив всех 2д звуков arr[name] = id; + AssotiativeArray<AAStringNR, ID, false, 16> m_a2dInst; + + //! ассоциативный массив всех 3д звуков arr[name] = id; + AssotiativeArray<AAStringNR, ID, false, 16> m_a3dInst; + + //! массив наборов звуков + Array<СSoundKit*> m_aSoundKits; + + //! массив каналов + int m_aChannels[SOUND_CHANNELS_COUNT]; + + //! звуковое устройство + IDirectSound8 *m_pDeviceSound; + + //! первичный буфер + IDirectSoundBuffer *m_pPrimaryBuffer; + + //! количество проигрываемых звуков + int m_iSoundsPlayCount; + + //! количество загруженных звуков (с учетом как проигрывающихся так и простаивающих) + int m_iSoundsLoadCount; + + //! предыдущая позиция наблюдателя + float3 m_vOldViewPos; + + //! предыдущее направление взгляда наблюдателя + float3 m_vOldViewDir; +}; + +#endif diff --git a/source/score/sxscore.cpp b/source/score/sxscore.cpp index 31197743bc4f962a26158c20ad0dba38b8edc33e..6c8842c988aec793bb28de2a00a4953618d43ab7 100644 --- a/source/score/sxscore.cpp +++ b/source/score/sxscore.cpp @@ -14,7 +14,7 @@ See the license in LICENSE report_func g_fnReportf = DefReport; #endif -MainSound *g_pManagerSound = 0; +CSoundManager *g_pManagerSound = 0; #define SCORE_PRECOND(retval) if(!g_pManagerSound){LibReport(-1, "%s - sxsound is not init", GEN_MSG_LOCATION); return retval;} @@ -44,14 +44,14 @@ SX_LIB_API void SSCore_0Create(const char *szName, HWND hWnd, bool isUnic) } else { - g_pManagerSound = new MainSound(); - g_pManagerSound->Init(hWnd); + g_pManagerSound = new CSoundManager(); + g_pManagerSound->init(hWnd); } } else { - g_pManagerSound = new MainSound(); - g_pManagerSound->Init(hWnd); + g_pManagerSound = new CSoundManager(); + g_pManagerSound->init(hWnd); } } else @@ -69,7 +69,7 @@ SX_LIB_API void SSCore_Clear() { SCORE_PRECOND(_VOID); - g_pManagerSound->Clear(); + g_pManagerSound->clear(); } @@ -77,77 +77,174 @@ SX_LIB_API void SSCore_Update(const float3 *pViewPos, const float3 *pViewDir) { SCORE_PRECOND(_VOID); - g_pManagerSound->Update(pViewPos, pViewDir); + g_pManagerSound->update(pViewPos, pViewDir); } -SX_LIB_API int SSCore_SndsPlayCountGet() +SX_LIB_API int SSCore_SndsGetCountPlay() { SCORE_PRECOND(0); - return g_pManagerSound->SoundsPlayCountGet(); + return g_pManagerSound->soundsGetPlayCount(); } -SX_LIB_API int SSCore_SndsLoadCountGet() +SX_LIB_API int SSCore_SndsGetCountLoad() { SCORE_PRECOND(0); - return g_pManagerSound->SoundsLoadCountGet(); + return g_pManagerSound->soundsGetLoadCount(); } -SX_LIB_API ID SSCore_SndCreate2d(const char *szFile, bool isLooping, UINT uiSizeStream) +//########################################################################## + +SX_LIB_API void SSCore_ChannelAdd(ID idChannel, bool isPlaying) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->channelAdd(idChannel, isPlaying); +} + +SX_LIB_API bool SSCore_ChannelExists(ID idChannel) +{ + SCORE_PRECOND(false); + + return g_pManagerSound->channelExists(idChannel); +} + +SX_LIB_API int SSCore_ChannelGetSndCount(ID idChannel) { SCORE_PRECOND(-1); - return g_pManagerSound->SoundCreate2d(szFile, isLooping, uiSizeStream); + return g_pManagerSound->channelGetSndCount(idChannel); } -SX_LIB_API ID SSCore_SndCreate3d(const char *szFile, bool isLooping, UINT uiSizeStream, float fDist, float fShiftPan) +SX_LIB_API void SSCore_ChannelPlay(ID idChannel) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->channelPlay(idChannel); +} + +SX_LIB_API void SSCore_ChannelPlayOnly(ID idChannel) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->channelPlayOnly(idChannel); +} + +SX_LIB_API bool SSCore_ChannelPlaying(ID idChannel) +{ + SCORE_PRECOND(false); + + return g_pManagerSound->channelPlaying(idChannel); +} + +SX_LIB_API void SSCore_ChannelStop(ID idChannel) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->channelStop(idChannel); +} + +//########################################################################## + +SX_LIB_API ID SSCore_SndCreate2d(const char *szFile, ID idChannel, UINT uiSizeStream) { SCORE_PRECOND(-1); - return g_pManagerSound->SoundCreate3d(szFile, isLooping, uiSizeStream, fDist, fShiftPan); + return g_pManagerSound->soundCreate2d(szFile, idChannel, uiSizeStream); } -SX_LIB_API ID SSCore_SndCreate2dInst(const char *szFile, bool isLooping, UINT uiSizeStream) +SX_LIB_API ID SSCore_SndCreate3d(const char *szFile, ID idChannel, UINT uiSizeStream, float fDist) { SCORE_PRECOND(-1); - return g_pManagerSound->SoundCreate2dInst(szFile, isLooping, uiSizeStream); + return g_pManagerSound->soundCreate3d(szFile, idChannel, uiSizeStream, fDist); } -SX_LIB_API ID SSCore_SndCreate3dInst(const char *szFile, bool isLooping, UINT uiSizeStream, float fDist, float fShiftPan) +SX_LIB_API ID SSCore_SndCreate2dInst(const char *szFile, ID idChannel) { SCORE_PRECOND(-1); - return g_pManagerSound->SoundCreate3dInst(szFile, isLooping, uiSizeStream, fDist, fShiftPan); + return g_pManagerSound->soundCreate2dInst(szFile, idChannel); } -SX_LIB_API ID SSCore_SndFind2dInst(const char *szFile) +SX_LIB_API ID SSCore_SndCreate3dInst(const char *szFile, ID idChannel, float fDist) { SCORE_PRECOND(-1); - return g_pManagerSound->SoundFind2dInst(szFile); + return g_pManagerSound->soundCreate3dInst(szFile, idChannel, fDist); } -SX_LIB_API ID SSCore_SndFind3dInst(const char *szFile) +SX_LIB_API ID SSCore_SndFind2dInst(const char *szFile, ID idChannel) { SCORE_PRECOND(-1); - return g_pManagerSound->SoundFind3dInst(szFile); + return g_pManagerSound->soundFind2dInst(szFile, idChannel); +} + +SX_LIB_API ID SSCore_SndFind3dInst(const char *szFile, ID idChannel) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->soundFind3dInst(szFile, idChannel); +} + + +SX_LIB_API ID SSCore_SndInstancePlay(ID idSound, bool isBlocked, bool isLooping, UINT *pArrDelay, int iSizeArrDelay, const float3 *pPos, float fVolume, float fPan) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->soundInstancePlay(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, pPos, fVolume, fPan); +} + +/*SX_LIB_API ID SSCore_SndInstancePlay2d(ID idSound, bool isBlocked, bool isLooping, int iVolume, int iPan) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->soundInstancePlay(idSound, isBlocked, isLooping, 0, 0, 0, iVolume, iPan); +} + +SX_LIB_API ID SSCore_SndInstancePlayDelay2d(ID idSound, bool isBlocked, bool isLooping, UINT *pArrDelay, int iSizeArrDelay, int iVolume, int iPan) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->soundInstancePlay(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, 0, iVolume, iPan); +} + +SX_LIB_API ID SSCore_SndInstancePlay3d(ID idSound, bool isBlocked, bool isLooping, const float3 *pPos) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->soundInstancePlay(idSound, isBlocked, isLooping, 0, 0, pPos); +} + +SX_LIB_API ID SSCore_SndInstancePlayDelay3d(ID idSound, bool isBlocked, bool isLooping, UINT *pArrDelay, int iSizeArrDelay, const float3 *pPos) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->soundInstancePlay(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, pPos); +}*/ + + +SX_LIB_API bool SSCore_SndInstancePlaying(ID idSound, ID idInstance) +{ + SCORE_PRECOND(false); + + return g_pManagerSound->soundInstancePlaying(idSound, idInstance); } -SX_LIB_API void SSCore_SndInstancePlay2d(ID idSound, int iVolume, int iPan) +SX_LIB_API void SSCore_SndInstanceStop(ID idSound, ID idInstance) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundInstancePlay2d(idSound, iVolume, iPan); + g_pManagerSound->soundInstanceStop(idSound, idInstance); } -SX_LIB_API void SSCore_SndInstancePlay3d(ID idSound, const float3 *pPos) +SX_LIB_API void SSCore_SndInstanceFree(ID idSound, ID idInstance) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundInstancePlay3d(idSound, pPos); + g_pManagerSound->soundInstanceStop(idSound, idInstance); } @@ -155,173 +252,290 @@ SX_LIB_API bool SSCore_SndIsInit(ID idSound) { SCORE_PRECOND(false); - return g_pManagerSound->SoundIsInit(idSound); + return g_pManagerSound->soundIsInit(idSound); } SX_LIB_API void SSCore_SndDelete(ID idSound) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundDelete(idSound); + g_pManagerSound->soundDelete(idSound); } -SX_LIB_API void SSCore_SndPlay(ID idSound, int isLooping) +SX_LIB_API void SSCore_SndPlay(ID idSound, bool isLooping, UINT *pArrDelay, int iSizeArrDelay) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundPlay(idSound, isLooping); + g_pManagerSound->soundPlay(idSound, isLooping, pArrDelay, iSizeArrDelay); } +/*SX_LIB_API void SSCore_SndPlayDelay(ID idSound, bool isLooping, UINT *pArrDelay, int iSizeArrDelay) +{ + SCORE_PRECOND(_VOID);*/ + + /*Array<UINT> aValues; + + UINT uiCurrVal = 0; + va_list va; + va_start(va, isLooping); + + uiCurrVal = va_arg(va, UINT); + while (uiCurrVal > 0) + { + aValues.push_back(uiCurrVal); + uiCurrVal = va_arg(va, UINT); + } + + va_end(va);*/ + + /*g_pManagerSound->soundPlayDelay(idSound, isLooping, pArrDelay, iSizeArrDelay); +}*/ + SX_LIB_API void SSCore_SndPause(ID idSound) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundPause(idSound); + g_pManagerSound->soundPause(idSound); } SX_LIB_API void SSCore_SndStop(ID idSound) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundStop(idSound); + g_pManagerSound->soundStop(idSound); } -SX_LIB_API void SSCore_SndStateSet(ID idSound, SOUND_OBJSTATE state) +SX_LIB_API void SSCore_SndSetState(ID idSound, SOUND_OBJSTATE state) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundStateSet(idSound, state); + g_pManagerSound->soundSetState(idSound, state); } -SX_LIB_API SOUND_OBJSTATE SSCore_SndStateGet(ID idSound) +SX_LIB_API SOUND_OBJSTATE SSCore_SndGetState(ID idSound) { SCORE_PRECOND(SOUND_OBJSTATE_STOP); - return g_pManagerSound->SoundStateGet(idSound); + return g_pManagerSound->soundGetState(idSound); } -SX_LIB_API void SSCore_SndPosCurrSet(ID idSound, UINT uiPos, int iType) +SX_LIB_API void SSCore_SndSetPosPlay(ID idSound, UINT uiPosMls) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundPosCurrSet(idSound, uiPos, iType); + g_pManagerSound->soundSetPosPlay(idSound, uiPosMls); } -SX_LIB_API UINT SSCore_SndPosCurrGet(ID idSound, int iType) +SX_LIB_API UINT SSCore_SndGetPosPlay(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundPosCurrGet(idSound, iType); + return g_pManagerSound->soundGetPosPlay(idSound); } -SX_LIB_API void SSCore_SndVolumeSet(ID idSound, int iVolume, int iType) +SX_LIB_API void SSCore_SndSetVolume(ID idSound, float fVolume) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundVolumeSet(idSound, iVolume, iType); + g_pManagerSound->soundSetVolume(idSound, fVolume); } -SX_LIB_API int SSCore_SndVolumeGet(ID idSound, int iType) +SX_LIB_API float SSCore_SndGetVolume(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundVolumeGet(idSound, iType); + return g_pManagerSound->soundGetVolume(idSound); } -SX_LIB_API void SSCore_SndPanSet(ID idSound, int iValue, int iType) +SX_LIB_API void SSCore_SndSetPan(ID idSound, float fValue) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundPanSet(idSound, iValue, iType); + g_pManagerSound->soundSetPan(idSound, fValue); } -SX_LIB_API int SSCore_SndPanGet(ID idSound, int iType) +SX_LIB_API float SSCore_SndGetPan(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundPanGet(idSound, iType); + return g_pManagerSound->soundGetPan(idSound); } -SX_LIB_API void SSCore_SndFreqCurrSet(ID idSound, UINT fValue) +SX_LIB_API void SSCore_SndSetCurrFreq(ID idSound, UINT fValue) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundFreqCurrSet(idSound, fValue); + g_pManagerSound->soundSetFreqCurr(idSound, fValue); } -SX_LIB_API UINT SSCore_SndFreqCurrGet(ID idSound) +SX_LIB_API UINT SSCore_SndGetCurrFreq(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundFreqCurrGet(idSound); + return g_pManagerSound->soundGetFreqCurr(idSound); } -SX_LIB_API UINT SSCore_SndFreqOriginGet(ID idSound) +SX_LIB_API UINT SSCore_SndGetOriginFreq(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundFreqOriginGet(idSound); + return g_pManagerSound->soundGetFreqOrigin(idSound); } -SX_LIB_API void SSCore_SndPosWSet(ID idSound, const float3 *pPos) +SX_LIB_API void SSCore_SndSetPosWorld(ID idSound, const float3 *pPos) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundPosWSet(idSound, pPos); + g_pManagerSound->soundSetPosWorld(idSound, pPos); } -SX_LIB_API void SSCore_SndPosWGet(ID idSound, float3 *pPos) +SX_LIB_API void SSCore_SndGetPosWorld(ID idSound, float3 *pPos) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundPosWGet(idSound, pPos); + g_pManagerSound->soundGetPosWorld(idSound, pPos); } -SX_LIB_API int SSCore_SndLengthSecGet(ID idSound) +SX_LIB_API int SSCore_SndGetLengthSec(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundLengthSecGet(idSound); + return g_pManagerSound->soundGetLengthSec(idSound); } -SX_LIB_API UINT SSCore_SndBytesPerSecGet(ID idSound) +SX_LIB_API UINT SSCore_SndGetBytesPerSec(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundBytesPerSecGet(idSound); + return g_pManagerSound->soundGetBytesPerSec(idSound); } -SX_LIB_API UINT SSCore_SndSizeGet(ID idSound) +SX_LIB_API UINT SSCore_SndGetSize(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundSizeGet(idSound); + return g_pManagerSound->soundGetSize(idSound); } -SX_LIB_API void SSCore_SndFileGet(ID idSound, char *szPath) +SX_LIB_API void SSCore_SndGetFile(ID idSound, char *szPath) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundFileGet(idSound, szPath); + g_pManagerSound->soundGetFile(idSound, szPath); } -SX_LIB_API float SSCore_SndDistAudibleGet(ID idSound) +SX_LIB_API float SSCore_SndGetDistAudible(ID idSound) { SCORE_PRECOND(0); - return g_pManagerSound->SoundDistAudibleGet(idSound); + return g_pManagerSound->soundGetDistAudible(idSound); +} + +SX_LIB_API void SSCore_SndSetDistAudible(ID idSound, float fValue) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->soundSetDistAudible(idSound, fValue); +} + +//########################################################################## + +SX_LIB_API ID SSCore_SndkitCreate(const char *szName, ID idChannel, bool is3D, float fDistAudible) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->sndkitCreate(szName, idChannel, is3D, fDistAudible); +} + +SX_LIB_API ID SSCore_SndkitCreateFromList(const char *szName, ID idChannel, bool is3D, float fDistAudible, float fVolume, const char *szFileOrList, ...) +{ + SCORE_PRECOND(-1); + + Array<String> aStrings; + // если в первой строке есть запятые тогда будем парсить строку + if (strstr(szFileOrList, ",")) + { + aStrings = StrExplode(szFileOrList, ","); + } + // иначе считываем все строчные аргументы + else if (szFileOrList) + { + const char *szStrCurr = 0; + va_list va; + va_start(va, szFileOrList); + + szStrCurr = szFileOrList; + while (szStrCurr) + { + aStrings.push_back(szStrCurr); + szStrCurr = va_arg(va, const char *); + } + + va_end(va); + } + + return g_pManagerSound->sndkitCreateFromList(szName, idChannel, aStrings, is3D, fDistAudible, fVolume); } -SX_LIB_API void SSCore_SndDistAudibleSet(ID idSound, float fValue) +SX_LIB_API void SSCore_SndkitAddSound(ID idSndKit, const char *szFile, float fDistAudible, float fVolume, UINT *pArrDelay, int iSizeArrDelay) { SCORE_PRECOND(_VOID); - g_pManagerSound->SoundDistAudibleSet(idSound, fValue); + g_pManagerSound->sndkitAddSound(idSndKit, szFile, fDistAudible, fVolume, pArrDelay, iSizeArrDelay); } + +SX_LIB_API uint64_t SSCore_SndkitPlay(ID idSndKit, uint64_t id2, const float3 *pPos, float fVolume, float fPan) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->sndkitPlay(idSndKit, id2, pPos, fVolume, fPan); +} + +SX_LIB_API void SSCore_SndkitStop(ID idSndKit, uint64_t id2) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->sndkitStop(idSndKit, id2); +} + +SX_LIB_API ID SSCore_SndkitGetID(const char *szName) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->sndkitGetID(szName); +} + +SX_LIB_API ID SSCore_SndkitGetChannel(ID idSndKit) +{ + SCORE_PRECOND(-1); + + return g_pManagerSound->sndkitGetChannel(idSndKit); +} + +SX_LIB_API void SSCore_SndkitGetName(ID idSndKit, char *szName) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->sndkitGetName(idSndKit, szName); +} + +SX_LIB_API void SSCore_SndkitDelete(ID idSndKit) +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->sndkitDelete(idSndKit); +} + +SX_LIB_API void SSCore_SndkitDeleteAll() +{ + SCORE_PRECOND(_VOID); + + g_pManagerSound->sndkitDeleteAll(); +} \ No newline at end of file diff --git a/source/score/sxscore.h b/source/score/sxscore.h index 05472b192f826f93ca89438953b55c8265245ca9..720b23952a27f0aa5e20fd74a9f9cf6f82f87513 100644 --- a/source/score/sxscore.h +++ b/source/score/sxscore.h @@ -16,9 +16,15 @@ See the license in LICENSE - "Ogg Vorbis" (загрузка ogg файлов). \note Загружаемые звуки wav и ogg формата (автоматическое определение и загрузка нужных данных). \note Поддерживаются 2d и 3d звуки, полная загрузка и потоковое воспроизвдение. - \note Также для полностью загруженных (не потоковое воспроизведение) доступно воспроизвдение инстансов (копий), без выдеения дополнительной равноценной памяти, и без дополнительных возможностей управления инстансом. + \note Также для полностью загруженных (не потоковое воспроизведение) доступно воспроизвдение инстансов (копий), без выделения дополнительной равноценной памяти, и без дополнительных возможностей управления инстансом. Однако источник выдачи инстансов должен быть создан одной из функций #SSCore_SndInstancePlay2d #SSCore_SndInstancePlay3d \note Идентификация звука происходит на основании его числового идентификатора выдаваемого создаваемыми функциями (#SSCore_SndCreate2d/#SSCore_SndCreate2dInst #SSCore_SndCreate3d/#SSCore_SndCreate3dInst) и является константной, идентификатор является порядковым номером + \note каждый звук, который проигрывается не потоково, может проигрываться с задержками + \note каждый звук может загружаться с настройками прямо в строке, при этом настройки в строке будут приоритетными, формат строки следующий: +путь_до_файла_без_пробелов dдистанция_слышимости_в_метрах vгромкость_от_0_до_1 задержка_перед_проигрыванием_в_млсек задержка2_в_млсек ... \n +данные громкости и дальности должны быть первыми (но между собой у них нет правила), и только после них идут задержки \n +на пример: messages/artefact_lead.ogg d100 v1.0 300 300 300 \n +парсинг строки осуществляется на основании пробелов, то есть в имени файла недопустимы пробелы @{*/ #ifndef __SXSCORE_H @@ -67,15 +73,52 @@ SX_LIB_API void SSCore_AKill(); //############################################################################# -/*! абсолюный путь до директории с файлами */ +/*! размер абсолюного пути до директории с файлами */ #define SOUND_MAX_SIZE_STDPATH 256 -/*! относительный путь до файла со звуком */ +/*! размер относительного пути до файла со звуком */ #define SOUND_MAX_SIZE_PATH 128 +/*! размер полного пути до файла со звуком */ +#define SOUND_MAX_SIZE_FULLPATH (SOUND_MAX_SIZE_STDPATH + SOUND_MAX_SIZE_PATH) + /*! минимально возможный размер потока для воспроизведения */ #define SOUND_MIN_SIZE_STREAM 1024*64 +/*! ошибочный идентификатор */ +#define SOUND_FAIL_ID -1 + + +/*! коэффициент смещения между ушами слушателя для 3d звуков */ +#define SOUND_SHIFTPAN_3D 0.1f + +/*! дистанция слышимости по умолчанию, в метрах */ +#define SOUND_DIST_AUDIBLE_DEFAULT 100 + + +/*! максимальное количество каналов */ +#define SOUND_CHANNELS_COUNT 100 + + +/*! упаковка двух int32_t в uint64_t */ +#define SOUND_ENCODE2ID(id1, id2)( (((uint64_t)((uint32_t)id1))<<32) | (uint32_t)id2 ) + +/*! извлечение первого int32_t из uint64_t из старших битов */ +#define SOUND_DECODE2ID_HI(id)( (int32_t)(uint32_t)(((uint64_t)id) >> 32) ) + +/*! извлечение первого int32_t из uint64_t из младших битов */ +#define SOUND_DECODE2ID_LO(id)( (int32_t)(uint32_t)(((uint64_t)id) & 0xFFFFFFFF) ) + + +/*! масимальная длина имени набора звуков */ +#define SOUND_MAX_SIZE_SNDKIT_NAME 128 + +/*! блокировать инстанс набора */ +#define SOUND_SNDKIT_INSTANCE_BLOCK -1 + +/*! не блокировать инстанс набора */ +#define SOUND_SNDKIT_INSTANCE_NOTBLOCK -2 + //************************************************************************** /*! \name Данные для первичного буфера @@ -92,25 +135,12 @@ SX_LIB_API void SSCore_AKill(); //!@} -//************************************************************************** - /*! количество бит на сэмпл для ogg, возможно 8 или 16 */ #define SOUND_OGG_BITS_PER_SAMPLE 16 /*! тип количества бит на сэмпл для ogg, 1 - для 8 бит, 2 - для 16 */ #define SOUND_OGG_BITS_PER_SAMPLE_WORD SOUND_OGG_BITS_PER_SAMPLE/8 -#define SOUND_POS_BYTES 0 /*!< байты */ -#define SOUND_POS_SEC 1 /*!< секунды */ -#define SOUND_POS_MLS 2 /*!< млсек */ - -#define SOUND_VOL_DB 0 /*!< децибелы */ -#define SOUND_VOL_PCT 1 /*!< проценты */ - -#define SOUND_EFF_ON 1 /*!< включение эффекта */ -#define SOUND_EFF_OFF 0 /*!< выключение эффекта */ -#define SOUND_EFF_INVALID_KEY -1 /*!< неверно указан ключ при обращении к функциям эффектов */ - //############################################################################# //! форматы звукрвых файлов @@ -129,6 +159,22 @@ enum SOUND_OBJSTATE SOUND_OBJSTATE_PLAY, //!< проигрывается }; +//! остояние занятости инстансов +enum SOUND_SNDINSTANCE_BUSY +{ + SOUND_SNDINSTANCE_BUSY_FREE, /*!< свободный */ + SOUND_SNDINSTANCE_BUSY_TEMP, /*!< времено занятый */ + SOUND_SNDINSTANCE_BUSY_LOCKED, /*!< заблокированный владельцем */ +}; + +//! значения каналов +enum SOUND_CHANNEL +{ + SOUND_CHANNEL_NONE = -1, /*!< значение не инициализованного канала */ + SOUND_CHANNEL_STOP = 0, /*!< значение не проигрывающегося в данный момент канала */ + SOUND_CHANNEL_PLAY = 1, /*!< значение проигрывающегося в данный момент канала */ +}; + //############################################################################# //! очистка всего списка звуков (полное их удаление) @@ -141,52 +187,110 @@ SX_LIB_API void SSCore_Update( ); //! количество проигрываемых на данный момент звуков -SX_LIB_API int SSCore_SndsPlayCountGet(); +SX_LIB_API int SSCore_SndsGetCountPlay(); //! количество загруженных на данный момент звуков -SX_LIB_API int SSCore_SndsLoadCountGet(); +SX_LIB_API int SSCore_SndsGetCountLoad(); + +//########################################################################## + +//! добавить канал +SX_LIB_API void SSCore_ChannelAdd(ID idChannel, bool isPlaying = false); + +//! существует ли канал +SX_LIB_API bool SSCore_ChannelExists(ID idChannel); + +//! количество звуков в канале +SX_LIB_API int SSCore_ChannelGetSndCount(ID idChannel); + +//! проигрывать звуки канала +SX_LIB_API void SSCore_ChannelPlay(ID idChannel); + +//! проигрывать звуки только этого канала +SX_LIB_API void SSCore_ChannelPlayOnly(ID idChannel); + +//! проигрывается ли канал? +SX_LIB_API bool SSCore_ChannelPlaying(ID idChannel); + +//! остановить проигрывание звуков канала +SX_LIB_API void SSCore_ChannelStop(ID idChannel); + +//############################################################################### //! загрузка 2d (фонового) звука SX_LIB_API ID SSCore_SndCreate2d( const char *szFile, //!< путь до файла, относительно стандартного - bool isLooping = false, //!< зацикливать ли воспроизведение + ID idChannel, //!< идентификатор канала UINT uiSizeStream = 0 //!< размер потока в байтах для потокового воспроизведения, если 0 тогда полностью грузить в память ); //! загрузка 3d звука SX_LIB_API ID SSCore_SndCreate3d( const char *szFile, //!< путь до файла, относительно стандартного - bool isLooping, //!< зацикливать ли воспроизведение + ID idChannel, //!< идентификатор канала UINT uiSizeStream, //!< размер потока в байтах для потокового воспроизведения, если 0 тогда полностью грузить в память - float fDist, //!< радиус слышимости в метрах - float fShiftPan = 0.1f //!< изменение позиционирования звука [0-1], на сколько будет смещен звук (между ушами слушателя) при поворотах камеры к источнику звука, чем ближе к объекту тем меньше разница в позиционировании при поворотах + float fDist //!< радиус слышимости в метрах ); -//! воспроизведение инстанса 2d звука -SX_LIB_API void SSCore_SndInstancePlay2d( - ID idSound, //!< идентификатор звука - int iVolume = 100, //!< громкость [0-100] - int iPan = 0 //!< смещение между ушами [-100 - 100] - ); - -//! воспроизведение инстанса 3d звука -SX_LIB_API void SSCore_SndInstancePlay3d( - ID idSound, //!< идентификатор звука - const float3 *pPos //!< позиция воспроизведения инстанса - ); +//############################################################################### //! загрузка 2d звукового файла и пометка его как объект выдающий инстансы, аргументы аналогичны #SSCore_SndCreate2d -SX_LIB_API ID SSCore_SndCreate2dInst(const char *szFile, bool isLooping = false, UINT uiSizeStream = 0); +SX_LIB_API ID SSCore_SndCreate2dInst(const char *szFile, ID idChannel); //! загрузка 3d звукового файла и пометка его как объект выдающий инстансы, аргументы аналогичны #SSCore_SndCreate3d -SX_LIB_API ID SSCore_SndCreate3dInst(const char *szFile, bool isLooping, UINT uiSizeStream, float fDist, float fShiftPan = 0.1f); +SX_LIB_API ID SSCore_SndCreate3dInst(const char *szFile, ID idChannel, float fDist); + +//************************************************************************** //! поиск 2d звука (выдающего инстансы) по относительному пути загрузки,возвращает его ID (в случае успеха) иначе <0 -SX_LIB_API ID SSCore_SndFind2dInst(const char *szFile); +SX_LIB_API ID SSCore_SndFind2dInst(const char *szFile, ID idChannel); //! поиск 3d звука (выдающего инстансы) по относительному пути загрузки,возвращает его ID (в случае успеха) иначе <0 -SX_LIB_API ID SSCore_SndFind3dInst(const char *szFile); +SX_LIB_API ID SSCore_SndFind3dInst(const char *szFile, ID idChannel); + +//************************************************************************** + +/*! воспроизведение инстанса звука, если нужны задержки то надо их указывать в pArrDelay и iSizeArrDelay, иначе в обоих 0, если указать iSizeArrDelay = -1 тогда будут задействованы предыдущие настройки +если нужен 3д звук (если это на самом деле 3д звук) то надо указать pPos, иначе 0 и будет 2д, для 2д по желанию можно указать громкость iVolume и смещение между ушами iPan +*/ +SX_LIB_API ID SSCore_SndInstancePlay( + ID idSound, //!< идентификатор звука + bool isBlocked, //!< блокировать ли файл? если true то вернет id который будет занят до тех пор пока его не освободит владалец через #SSCore_SndInstanceFree + bool isLooping, //!< зацикливать ли воспроизведение звука? если да то звук будет заблокирован, а возвращенный id будет приндалежать вызывавшему и именно он несет ответсвенность за остановку и освобождение инстанса + UINT *pArrDelay, //!< массив задержек в млсек, первое значение задержка перед воспроизведением + int iSizeArrDelay, //!< размер #pArrDelay + const float3 *pPos, //!< если это 3д звук то позиция обязательна, если 2д то нужно указать NULL + float fVolume = 1.f, //!< громкость [0, 1] + float fPan = 0.f //!< смещение между ушами [-1, 1] + ); + +//! воспроизведение инстанса 2d звука, аргументы аналогичны #SSCore_SndInstancePlay +#define SSCore_SndInstancePlay2d(idSound, isBlocked, isLooping, iVolume, iPan) (SSCore_SndInstancePlay(idSound, isBlocked, isLooping, 0, 0, 0, iVolume, iPan)) + +//! воспроизведение инстанса 2d звука с задержками, аргументы аналогичны #SSCore_SndInstancePlay +#define SSCore_SndInstancePlayDelay2d(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, iVolume, iPan) (SSCore_SndInstancePlay(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, 0, iVolume, iPan)) +//! воспроизведение инстанса 3d звука, аргументы аналогичны #SSCore_SndInstancePlay +#define SSCore_SndInstancePlay3d(idSound, isBlocked, isLooping, pPos) (SSCore_SndInstancePlay(idSound, isBlocked, isLooping, 0, 0, pPos)) + +//! воспроизведение инстанса 3d звука с задержками, аргументы аналогичны #SSCore_SndInstancePlay +#define SSCore_SndInstancePlayDelay3d(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, pPos) (SSCore_SndInstancePlay(idSound, isBlocked, isLooping, pArrDelay, iSizeArrDelay, pPos)) + +//************************************************************************** + +//! проигрывается ли инстанс звука с id idInstance +SX_LIB_API bool SSCore_SndInstancePlaying( + ID idSound, //!< идентификатор звука + ID idInstance //!< идентификатор инстанса звука который был возвращен функцией #SSCore_SndInstancePlay2d или #SSCore_SndInstancePlay3d + ); + +//! остановка инстанса звука с id idInstance +SX_LIB_API void SSCore_SndInstanceStop(ID idSound, ID idInstance); + +//! освобождает инстанс звука с id idInstance, будет иметь статус занятости #SOUND_SNDINSTANCE_BUSY_TEMP если был #SOUND_SNDINSTANCE_BUSY_LOCKED, а при следующем обновлении если инстанс не проигрывается статус поменяется на #SOUND_SNDINSTANCE_BUSY_FREE +SX_LIB_API void SSCore_SndInstanceFree(ID idSound, ID idInstance); + +//############################################################################### //! инициализирован ли звук с идентификатором id SX_LIB_API bool SSCore_SndIsInit(ID idSound); @@ -194,9 +298,15 @@ SX_LIB_API bool SSCore_SndIsInit(ID idSound); //! удалить звук по его id SX_LIB_API void SSCore_SndDelete(ID idSound); +//############################################################################### -//! воспроизвести звук, looping зацикливать ли воспроизведение, 0 - нет, >0 да, <0 не учитывать данное значение -SX_LIB_API void SSCore_SndPlay(ID idSound, int looping = -1); +//! воспроизвести звук, isLooping зацикливать ли воспроизведение +SX_LIB_API void SSCore_SndPlay( + ID idSound, //!< идентификатор звука + bool isLooping = false, //!< зацикливать ли воспроизведение? + UINT *pArrDelay = 0, //!< массив задержек в млсек, первое значение задержка перед воспроизведением + int iSizeArrDelay = 0 //!< размер массива pArrDelay, если указать iSizeArrDelay = -1 тогда будут задействованы предыдущие настройки + ); //! приостановить SX_LIB_API void SSCore_SndPause(ID idSound); @@ -206,89 +316,177 @@ SX_LIB_API void SSCore_SndStop(ID idSound); //! устанавливает состояние проигрывания звука -SX_LIB_API void SSCore_SndStateSet(ID idSound, SOUND_OBJSTATE state); +SX_LIB_API void SSCore_SndSetState(ID idSound, SOUND_OBJSTATE state); //! возвращает состояние проигрывания звука на данный момент -SX_LIB_API SOUND_OBJSTATE SSCore_SndStateGet(ID idSound); +SX_LIB_API SOUND_OBJSTATE SSCore_SndGetState(ID idSound); + +//************************************************************************** //! устанавить позицию проигрывания -SX_LIB_API void SSCore_SndPosCurrSet( - ID idSound, //!< идентификатор звука - UINT uiPos, //!< значение позиции исходя из параметра type - int iType = SOUND_POS_BYTES //!< тип значения pos, SOUND_POS_ +SX_LIB_API void SSCore_SndSetPosPlay( + ID idSound, //!< идентификатор звука + UINT uiPosMls //!< значение позиции в млсек ); //! возвращает позицию проигрывания -SX_LIB_API UINT SSCore_SndPosCurrGet( - ID idSound, //!< идентификатор звука - int iType = SOUND_POS_BYTES //!< тип возвращаемого значения, SOUND_POS_ - ); +SX_LIB_API UINT SSCore_SndGetPosPlay(ID idSound); //! устанавить громкость -SX_LIB_API void SSCore_SndVolumeSet( - ID idSound, //!< идентификатор звука - int iVolume, //!< значение громкости исходя из параметра type - int iType = SOUND_VOL_PCT //!< тип значения volume, SOUND_VOL_ +SX_LIB_API void SSCore_SndSetVolume( + ID idSound, //!< идентификатор звука + float fVolume //!< значение громкости [0, 1] ); -//! возвращает громкость -SX_LIB_API int SSCore_SndVolumeGet( - ID idSound, //!< идентификатор звука - int iType = SOUND_VOL_PCT //!< тип возвращаемого значения, SOUND_VOL_ - ); +//! возвращает громкость [0, 1] +SX_LIB_API float SSCore_SndGetVolume(ID idSound); //! установка позиционирования между ушами -SX_LIB_API void SSCore_SndPanSet( - ID idSound, //!< идентификатор звука - int iValue, //!< значение позиционирования исходя из параметра type - int iType = SOUND_VOL_PCT //!< тип значения value, SOUND_VOL_ +SX_LIB_API void SSCore_SndSetPan( + ID idSound, //!< идентификатор звука + float fValue //!< значение позиционирования [-1, 1] ); -//! возвращает позиционирование между ушами -SX_LIB_API int SSCore_SndPanGet( - ID idSound, //!< идентификатор звука - int type = SOUND_VOL_PCT //!< тип возвращаемого значения, SOUND_VOL_ - ); +//! возвращает позиционирование между ушами [-1, 1] +SX_LIB_API float SSCore_SndGetPan(ID idSound); //! установка частоты воспроизведения -SX_LIB_API void SSCore_SndFreqCurrSet(ID idSound, UINT uiValue); +SX_LIB_API void SSCore_SndSetCurrFreq(ID idSound, UINT uiValue); //! возвращает текущую частоту воспроизведения -SX_LIB_API UINT SSCore_SndFreqCurrGet(ID idSound); +SX_LIB_API UINT SSCore_SndGetCurrFreq(ID idSound); //! возвращает оригинальную частоту воспроизведения -SX_LIB_API UINT SSCore_SndFreqOriginGet(ID idSound); +SX_LIB_API UINT SSCore_SndGetOriginFreq(ID idSound); //! установка мировой позиции звука (только для 3d звуков) -SX_LIB_API void SSCore_SndPosWSet(ID idSound, const float3 *pPos); +SX_LIB_API void SSCore_SndSetPosWorld(ID idSound, const float3 *pPos); //! возвращает мировую позицию звука (только для 3d звуков) -SX_LIB_API void SSCore_SndPosWGet(ID idSound, float3 *pPos); +SX_LIB_API void SSCore_SndGetPosWorld(ID idSound, float3 *pPos); //! длина в секундах -SX_LIB_API int SSCore_SndLengthSecGet(ID idSound); +SX_LIB_API int SSCore_SndGetLengthSec(ID idSound); //! количество байт в секунде -SX_LIB_API UINT SSCore_SndBytesPerSecGet(ID idSound); +SX_LIB_API UINT SSCore_SndGetBytesPerSec(ID idSound); //! размер в байтах PCM данных -SX_LIB_API UINT SSCore_SndSizeGet(ID idSound); +SX_LIB_API UINT SSCore_SndGetSize(ID idSound); //! относительный путь до звукового файла -SX_LIB_API void SSCore_SndFileGet(ID idSound, char *szPath); +SX_LIB_API void SSCore_SndGetFile(ID idSound, char *szPath); //! возвращает дистанцию слышимости -SX_LIB_API float SSCore_SndDistAudibleGet(ID idSound); +SX_LIB_API float SSCore_SndGetDistAudible(ID idSound); //! установка дистанции слышимости в метрах -SX_LIB_API void SSCore_SndDistAudibleSet(ID idSound, float fVfalue); +SX_LIB_API void SSCore_SndSetDistAudible(ID idSound, float fVfalue); + +//!@} + +//############################################################################### + +/*! \name Наборы звуков для воспроизведения случайного звука из набора + \note Все звуки создаются инстансовыми +@{*/ + +//! создать набор звуков +SX_LIB_API ID SSCore_SndkitCreate( + const char *szName, //!< имя набора + ID idChannel, //!< id канала + bool is3D, //!< набор 3д звуков? + float fDistAudible = SOUND_DIST_AUDIBLE_DEFAULT //!< дистанция слышимости + ); + +//! загрузить список звуков (с настройками) из строки либо из строк +SX_LIB_API ID SSCore_SndkitCreateFromList( + const char *szName, //!< имя набора + ID idChannel, //!< id канала + bool is3D, //!< набор 3д звуков? + float fDistAudible, //!< дистанция слышимости + float fVolume, //!< громкость [0, 1] + const char *szFileOrList, //!< строка с первым файлом и настройками (последующие аргументы учитываются), либо строка со всеми файлами (через запятую) и настройками (последующие аргументы не учитываются) + ... //!< если #szFileOrList один файл тогда здесь должны быть строки с файлами до звуков (с настройками) + ); + +//************************************************************************** + +//! добавить звук в набор +SX_LIB_API void SSCore_SndkitAddSound( + ID idSndKit, //!< id набора + const char *szFile, //!< путь к файлу звука + float fDistAudible, //!< дистанция слышимости для 3d звуков, для 2d можно просто 0, если < 0 тогда установит то значение которое было передано в #SSCore_SndkitCreate + float fVolume = 1.f, //!< громскость [0, 1] + UINT *pArrDelay = 0, //!< массив задержек + int iSizeArrDelay = 0 //!< количество элементов в #pArrDelay + ); + +//! добавить в набор 2d звук +#define SSCore_SndkitAddSound2d(idSndKit, szFile, fVolume) (SSCore_SndkitAddSound(idSndKit, szFile, 0, fVolume, 0, 0)) + +//! добавить в набор 2d звук с задержками при воспроизведении +#define SSCore_SndkitAddSoundDelay2d(idSndKit, szFile, fVolume, pArrDelay, iSizeArrDelay) (SSCore_SndkitAddSound(idSndKit, szFile, 0, fVolume, pArrDelay, iSizeArrDelay)) + +//! добавить в набор 3d звук +#define SSCore_SndkitAddSound3d(idSndKit, szFile, fDistAudible, fVolume) (SSCore_SndkitAddSound(idSndKit, szFile, fDistAudible, fVolume, 0, 0)) + +//! добавить в набор 3d звук с задержками при воспроизведении +#define SSCore_SndkitAddSoundDelay3d(idSndKit, szFile, fDistAudible, fVolume, pArrDelay, iSizeArrDelay) (SSCore_SndkitAddSound(idSndKit, szFile, fDistAudible, fVolume, pArrDelay, iSizeArrDelay)) + +//************************************************************************** + +/*! проиграть случайны звук + \note если набор 3д звуков, то позиция обязательна + \note id2 должен принимать либо #SOUND_SNDKIT_INSTANCE_BLOCK либо #SOUND_SNDKIT_INSTANCE_NOTBLOCK либо должен быть упакованным значением идентификаторов заблокированного инстанса звука +если инстанс воспроизводимого звука заблокирован, то он не будет использоваться другими пока владелец его не разблокирует +если было передано упакованное значение, и инстанс уже отыграл свое, значит он разблокируется и будет воспроизведен другой инстанс и заблокируется + \return возвращает упакованные значения порядкового номера звука (в массиве набора) в 32 старших битах и id инстанса звука в 32 младших битах +*/ +SX_LIB_API uint64_t SSCore_SndkitPlay( + ID idSndKit, //!< id набора + uint64_t id2, //!< либо #SOUND_SNDKIT_INSTANCE_BLOCK либо #SOUND_SNDKIT_INSTANCE_NOTBLOCK либо должен быть упакованным значением идентификаторов заблокированного инстанса звука + const float3 *pPos = 0, //!< если 3d, позиция звука в пространстве + float fVolume = -1.f, //!< громкость [0, 1], если <0 тогда будет использовано ранее заданное значение + float fPan = 0.f //!< если 2d, смещение между ушами [-1, 1] + ); + +//! проиграть случайны звук из 2d набора, аргументы аналогичны #SSCore_SndkitPlay +#define SSCore_SndkitPlay2d(idSndKit, id2, fVolume, fPan) (SSCore_SndkitPlay(idSndKit, id2, 0, fVolume, fPan)) + +//! проиграть случайны звук из 3d набора, аргументы аналогичны #SSCore_SndkitPlay +#define SSCore_SndkitPlay3d(idSndKit, id2, pPos) (SSCore_SndkitPlay(idSndKit, id2, pPos)) + +//! остановить проигрывание звуков в наборе +SX_LIB_API void SSCore_SndkitStop( + ID idSndKit, //!< id набора + uint64_t id2 //!< результат SSCore_SndkitPlay если параметр id2 имел значение отличное от #SOUND_SNDKIT_INSTANCE_NOTBLOCK + ); + +//************************************************************************** + +//! получить id по имени набора +SX_LIB_API ID SSCore_SndkitGetID(const char *szName); + +//! получить номер канала +SX_LIB_API ID SSCore_SndkitGetChannel(ID idSndKit); + +//! получить имя по id набора +SX_LIB_API void SSCore_SndkitGetName(ID idSndKit, char *szName); + +//! удалить набор +SX_LIB_API void SSCore_SndkitDelete(ID idSndKit); + +//! удалить все наборы +SX_LIB_API void SSCore_SndkitDeleteAll(); //!@} + #endif //!@} sxscore diff --git a/source/skyxengine.cpp b/source/skyxengine.cpp index b2e1b62e1d1a92d3e7a12049744b221aa6b6f3c4..3390f448595f28b49363e3173e993ac3d52b979e 100644 --- a/source/skyxengine.cpp +++ b/source/skyxengine.cpp @@ -193,6 +193,8 @@ void SkyXEngine_Init(HWND hWnd3D, HWND hWndParent3D) SSCore_0Create("sxsound", hWnd3DCurr, false); SSCore_Dbg_Set(SkyXEngine_PrintfLog); + SSCore_ChannelAdd(SX_SOUND_CHANNEL_GAME, true); + //SSCore_SndkitCreateFromList("test", SX_SOUND_CHANNEL_GAME, false, 0, 1.f, " messages/artefact_lead.ogg d100 v1.0 300 300 300 , messages/artefact_lose.ogg d50 v0.7 400 400 400, messages/artefact_lost.ogg d30 v1.0 200 200 200, messages/artefact_new.ogg d35 v0.9 250 250 250"); SGCore_0Create("sxgcore", hWnd3DCurr, *r_win_width, *r_win_height, *r_win_windowed, 0, false); SGCore_Dbg_Set(SkyXEngine_PrintfLog); @@ -668,7 +670,8 @@ void SkyXEngine_Frame(DWORD timeDelta) #if defined(SX_GAME) ttime = TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER)); - SRender_RenderPostProcess(timeDelta); + if (!SSInput_GetKeyState(SIK_P)) + SRender_RenderPostProcess(timeDelta); DelayPostProcess += TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER)) - ttime; #endif @@ -803,11 +806,11 @@ void SkyXEngine_Frame(DWORD timeDelta) SPE_EffectComputeAll(); SPE_EffectComputeLightingAll(); DelayUpdateParticles += TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER)) - ttime; - + ttime = TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER)); pDXDevice->Present(0, 0, 0, 0); DelayPresent += TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER)) - ttime; - + SkyXEngind_UpdateDataCVar(); } @@ -1024,6 +1027,7 @@ void SkyXEngind_UpdateDataCVar() int SkyXEngine_CycleMain() { + //ID idSnd = SSCore_SndCreate2dInst("ak74_reload.ogg",SX_SOUND_CHANNEL_GAME); MSG msg; ::ZeroMemory(&msg, sizeof(MSG)); @@ -1046,8 +1050,28 @@ int SkyXEngine_CycleMain() } else { - SGCore_LoadTexAllLoad(); SGCore_ShaderAllLoad(); + SGCore_LoadTexAllLoad(); + + /*if (SSInput_GetKeyState(SIK_BACKSPACE)) + SSCore_ChannelPlay(SX_SOUND_CHANNEL_GAME); + else if (SSInput_GetKeyState(SIK_ENTER)) + SSCore_ChannelStop(SX_SOUND_CHANNEL_GAME); + + UINT arr[] = {3000, 350, 1000, 800, 300 }; + if (SSInput_GetKeyState(SIK_RSHIFT)) + SSCore_SndInstancePlayDelay2d(idSnd, false, true, arr, 5, 1, 0); + + if (SSInput_GetKeyState(SIK_RCONTROL)) + SSCore_SndStop(idSnd); + + // + static uint64_t id2 = SOUND_SNDKIT_INSTANCE_BLOCK; + id2 = SSCore_SndkitPlay(0, id2); + if (SSInput_GetKeyState(SIK_TAB)) + SSCore_SndkitStop(0, id2);*/ + + Core_TimesUpdate(); Core_0ConsoleUpdate(); SSInput_Update();