[ English | Español | Pyccκuú ] |
uFMOD - это компактная, шустрая, надёжная, мультиплатформенная библиотека для качественного воспроизведения аудио в формате XM, разработанная полностью на ассемблере. XM может храниться в отдельном файле, в ресурсах или предварительно загружен в память. Поддерживаются также битые и не совсем стандартные файлы. Библиотека распространяется с открытым исходным кодом и примерами для следующих компиляторов: Visual C++, C#, Visual Basic, PureBasic, FreeBASIC, BlitzMax, Emergence BASIC, Delphi, Borland C++ Builder, Dev-C++ (MingW), FreePascal, MASM32, FASM, NASM и TASM.
WINMM, DirectSound или OpenAL?
uFMOD для Win32 поддерживает WINMM, DirectX® DirectSound и OpenAL. Все 3 подсистемы имеют свои плюсы и минусы. DirectX предоставляет возможность использовать звуковые эффекты, позволяет проигрывать одновременно несколько звуковых сигналов, поддерживает трёхмерный звук, спроектирован более надёжно чем WINMM. Зато WINMM поддерживается даже в Windows 95. OpenAL кроссплатформенна (доступны версии для Windows, Linux, Macintosh и т.д.), поддерживает аппаратное ускорение эффектов 3D-окружения, что очень полезно для разработчиков игр. Тем не менее, OpenAL не поставляется предустановленной в Windows XP и более ранних версиях, за исключением OEM машин со звуковыми карточками Creative. Таким образом, Вам скорее всего придётся скачать и установить OpenAL самостоятельно. В зависимости от аппаратуры и драйверов, качество звука может быть лучше в DirectSound или WINMM, хотя среднестатистический пользователь вряд ли почувствует разницу. Если вы не уверены какую версию uFMOD выбрать для своего проекта, скорее всего вам больше подойдёт стандартная версия с WINMM, так как она проще в использовании: для воспроизведения звука достаточно добавить всего лишь пару строчек кода.
В комплект включена пара бесплатных утилит для использования совместно с uFMOD: XMStrip и Eff. Обе утилиты совмещают в себе консольный и графический (GUI) интерфейсы. Если присутствуют параметры командной строки, включается консольный режим. Режим GUI интуитивно понятен, так что дальнейшее описание касается только консольного.
SVN | Исходники доступны через SVN | |
XMStrip обрабатывает заданный XM файл с целью уменьшения размера, без потери качества звучания. В процессе обработки, XMStrip удаляет неиспользующиеся инструменты и партитуры, вырезает комментарии и перепаковывает внутренние структуры файла для уменьшения размера и повышения скорости загрузки. Для начала, откроем командный интерпретатор и введём xmstrip /h
чтобы получить следующее сообщение:
uFMOD XMSTRIP USAGE: xmstrip [options] file [output] file - input file name, which can contain wildcards (* and ?) for batch processing. output - optional output file name options: /c - clean only (don't strip) When [output] is not specified, XMSTRIP attempts to overwrite the input. If file name contains spaces, enclose it in "". |
Если имя сохраняемого файла не указано, XMStrip перезапишет заданный файл. Если имя файла содержит пробелы, его необходимо заключить в кавычки (""). XMStrip поддерживает пакетную обработку файлов (символы * и ?).
Имейте в виду, что другие проигрыватели XM файлов, возможно, откажутся воспроизводить файл, обработанный XMStrip. Опция /c предусмотрена для восстановления таких файлов или обработки обычных XM файлов, которые планируется проигрывать не только в uFMOD.
Eff предназначается для опытных кодеров, желающих сэкономить каждый байт в своих приложениях. Для этого нужно выделить только те функции uFMOD, которые действительно будут использованы в целевом приложении, перекомпилировать библиотеку и получить наименьший возможный размер. Вот, что выдаёт eff /h
:
uFMOD XM effects extractor USAGE: eff [options] file file - input file name options: /Dm - generate a masm32/tasm dump /Dd - generate a Pascal (Delphi) dump /Dc - generate a C/C++ dump /Ds - generate an RCDATA resource dump /Di - disable infoAPI: uFMOD_GetStats, uFMOD_GetRowOrder, uFMOD_GetTitle and uFMOD_GetTime /Dp - disable uFMOD_Pause, uFMOD_Resume and XM_SUSPENDED /Dv - disable volume control /Dj - disable Jump2Pattern /Df - disable loading XM from file /Dr - disable loading XM from resource /Dl - disable XM_NOLOOP /M - mark & clear unused chunks of data in a masm32/tasm compatible dump |
Последний параметр - имя XM файла, на использование которого ориентируются следующие параметры оптимизации:
id RCDATA "имя_файла"
. Поэтому приходится использовать дампы для совместимости, например, со старыми версиями компилятора ресурсов GNU, вроде того, что входит в состав Dev-C++.eff /Dmpvjfrl /M file.xm
eff /M /Dm /Dp /Dv /Dj /Df /Dr /Dl file.xm
eff -M -Dmpvjfrl file.xm
Любой из предыдущих примеров создаст дамп для MASM32/TASM, выделит "дыры" и предварительно заполнит их нулями. Файл EFF.INC содержит список эффектов XM, которые действительно используются в заданном файле, и некоторые дополнительные флаги для отключения pause/resume, регулятора громкости, Jump2Pattern, поддержки файлов и ресурсов и XM_NOLOOP. Поместите этот новый EFF.INC в ufmodlib\src\ и перекомпилируйте библиотеку (в следующем разделе освещены некоторые вопросы касающиеся компиляции исходников библиотеки). Теперь у Вас имеется свой собственный оптимизированный билд uFMOD, но имейте в виду, что в этом билде включены не все эффекты XM. Поэтому, не следует использовать его для проигрывания других XM файлов, отличных от обработанного утилитой Eff!
Необходимость компиляции исходников библиотеки uFMOD возникает при использовании утилиты Eff, а также для включения особых режимов и опций, которые отключены в сборке по умолчанию (см. таблицу Опции ниже). Для тех, кто хочет попрактиковаться в ассемблере и/или разобраться в библиотеке на самом низком уровне (в хорошем смысле), и предназначен данный раздел.
Исходники uFMOD расположены в ufmodlib\src\:
ufmodlib\import\ содержит исходники библиотек импорта, которые используются совместно с uFMOD в различных примерах. Некоторые из них используются самой библиотекой в Visual Basic 6 и FreePascal. Уже собранные версии данных библиотек импорта хранятся в ufmodlib\lib\. Исходники полных библиотек импорта для DirectSound и OpenAL под разные компиляторы также находятся тут. Все эти библиотеки можно пересобрать с помощью ImpLib SDK. ufmodlib\import\buildall.bat - батник, который перекомпилирует все вышеописанные библиотеки импорта.
При создании библиотеки в формате OMF для совместимости с Delphi используется утилита, которая находится в ufmodlib\bin\. Хотя данная утилита и уступает по мощности OMF2D EliCZ'а, она вполне справляется с задачей создания библиотеки uFMOD совместимой с Delphi. При компиляции библиотеки в формате OMF при помощи NASM, используется o4delphi.
SVN | Исходники доступны через SVN | |
Следующим, после внесения изменений в исходники, шагом является компиляция. Выберите один из батников в ufmodlib\, в зависимости от целевого компилятора, для которого нужно собрать библиотеку. Следующая таблица поможет сделать выбор:
Батник | Компилятор(ы) | Комментарии |
mk_coff | Visual C/C++, Dev-C++ (MingW), FASM, NASM, MASM32, FreeBASIC | Рекомендуется использовать FASM для сборки библиотеки в формате COFF. |
mk_omf | Borland Delphi, Borland C++ Builder, TASM | Пользователи Borland C++ Builder и TASM должны установить значение LIB в опции UF_FMT перед сборкой. Пользователи Delphi должны установить значение OBJ. |
mk_vb6 | Visual Basic 6 | |
mk_pbas | PureBasic | |
mk_bmax | BlitzMax | |
mk_fpas | FreePascal | |
mk_ebas | Emergence BASIC | |
Теперь откройте выбранный батник в текстовом редакторе. Всё, что находится между следующих строк:
rem *** CONFIG STARTи
rem *** CONFIG ENDподлежит настройке. Первым делом обратите внимание на секцию
Pathes
, в которой прописаны все пути к утилитам, используемым в процессе компиляции. Там может попасться такая опция:SET UF_MASM=C:\masm32Если у Вас установлен MASM32, удостоверьтесь, что путь в данной опции указывает точно туда, где находится MASM32. Допустим, MASM32 установлен в
D:\TOOLS\MASM32
. В таком случае, необходимо скорректировать опцию следующим образом:SET UF_MASM=D:\TOOLS\MASM32Не все пути необходимы для успешной компиляции. Например, если Вы намерены использовать FASM, не нужно настраивать UF_MASM. Некоторые пути содержат имена исполнимых файлов. Например:
SET UF_ARCH=arar.exe должен находиться в одном из каталогов в списке переменной окружения PATH. Если это не так, необходимо указать полный путь. Предположим, ar.exe находится в
C:\Program files\BlitzMax\bin
. Тогда опцию UF_ARCH нужно определить следующим образом:SET UF_ARCH=C:\Program files\BlitzMax\bin\ar.exeПроверьте правильность остальных путей, необходимых для компиляции. Далее, настройте параметры конфигурации, согласно следующей таблице:
Опция* | Описание | Значения* |
UF_RAMP | Данная опция позволяет настроить механизм интерполяции, который предназначен для погашения щелчков - резкие перепады амплитуды сигнала, характерные для трекерской музыки. С другой стороны, интерполяция вносит искажение в высокочастотные спектральные составляющие сигнала, что иногда бывает заметно. STRONG - это значение по умолчанию, рекомендуемое для большинства приложений. В данном режиме миксер сглаживает резкие перепады амплитуды, применяя линейную 64-ступенчатую интерполяцию. WEAK накладывает лишь 16 ступеней - этот режим менее эффективен, чем STRONG, но зато вероятность деградации сигнала в этом режиме ниже. NONE вообще отключает интерполяцию. Без сглаживания не будет и деградации, но большинство композиций без сглаживания будет звучать заметно хуже из-за наложения щелчков. Особым образом сбалансированные композиции без сглаживания могут звучать лучше. | NONE, WEAK, STRONG |
UF_FREQ | Частота дискретизации (в Гц). 44100 было значением по умолчанию до версии 1.20. При использовании значения 48КГц воспроизводится более чистый звук на большинстве звуковых карточек и потребляется меньше системных ресурсов. Поэтому, 48000 является новым значением по умолчанию, рекомендуемым для большинства приложений. 22050 предусмотрено для тех, кто ещё помнит славные деньки Amiga. | 22050, 44100, 48000 |
UF_UFS | Формат кодирования текста. Юникодовые приложения должны устанавливать значение UNICODE, за исключением BlitzMax, PureBasic и Visual Basic 6, так как опция UNICODE в этих случаях не поддерживается. Имейте в виду, что юникодовые приложения работают значительно быстрее на машинах линейки NT/XP. Опция UNICODE обязательна при компиляции uFMOD для .NET. | ANSI, UNICODE |
UF_FMT | Создать статическую библиотеку, просто обьектный файл или же DLL с соответствующими библиотеками импорта. Например, Delphi не поддерживает статические библиотеки. Поэтому для совместимости с Delphi нужно указать значение OBJ. Компиляторы C/C++ и ассемблеры поддерживают оба формата. Некоторые компиляторы вообще не поддерживают статическую линковку. В таких случаях приходится использовать DLL. Как раз для этого и предусмотрена последняя опция. | OBJ, LIB, DLL |
UF_ASM | Ассемблер. Да, uFMOD можно собирать разными ассемблерами - выбирайте тот, который больше нравится :) | MASM, NASM, FASM, TASM |
UF_MODE | NORMAL - это значение по умолчанию. Ничего особенного. UNSAFE отключает проверку правильности формата XM перед загрузкой композиции. Если Вы уверены, что все композиции, которые будут проигрываться в вашем приложении, корректны (правильность формата XM-файла можно проверить в Eff или XMStrip), можете пересобрать библиотеку в режиме UNSAFE, чтобы выйграть в размере и скорости загрузки. Имейте в виду, что загрузка неправильного XM-файла в режиме UNSAFE может привести к краху! В режиме BENCHMARK доступен счётчик производительности, который хранит точное количество тактов, которое уходит на синтез чуть более 21 мс звука при частоте в 48 КГц. Данный режим предназначен для сравнения производительности различных версий библиотеки. За дополнительной информацией обращайтесь к примерам на C (см. описание флага BENCHMARK). Режим BENCHMARK доступен только в C, MASM, FASM, NASM и TASM. | NORMAL, UNSAFE, BENCHMARK |
Запустите батник, чтобы собрать все доступные версии библиотеки: WINMM, OpenAL и DirectX DirectSound. Вот и всё!
В каждом из каталогов представлены примеры с использованием как WINMM, так и DirectX-версий uFMOD. Под большинство компиляторов доступны также примеры с использованием OpenAL-версии uFMOD. Некоторые примеры сопровождаются откомпилированными экзешниками, чтобы показать минимальный размер, характерный для данного компилятора. Заметьте, что экзешники представлены без сжатия.
Каталог | Компилятор | Автор(ы) | Комментарии |
BCB | Borland C++ Builder | dododo | |
Delphi | Borland Delphi | * | Пользователи Delphi 5 - 7 могут собрать примеры с помощью предоставленных батников для дополнительного уменьшения размера экзешников. Пользователи Delphi 9 или новее могут собрать примеры только из IDE, так как некоторые особенности компилятора, используемые в батниках, претерпели изменения в последних версиях. Вы также найдёте здесь полные версии юнитов DirectSound и OpenAL для Delphi. Библиотеки uFMOD под DirectX DirectSound и OpenAL используют данные юниты, но Вы можете задействовать их и в сторонних проектах. |
Fasm | Flat Assembler | bogrus, * | Примеры для FASM, как с использованием линкера от MS или Polink, так и без. |
Masm32 | MASM32 | * | Примеры показывают возможности "экстремальной" оптимизации с размещением кода и/или данных приложения прямо внутри аудио-потока для сокращения размера экзешника. Поэтому, данные примеры рассчитаны исключительно на фанатов оптимизации. Прилагаются файлы проектов для RadASM IDE. |
Nasm | Netwide Assembler | * | С использованием линкера от MS или Polink. |
Tasm | Borland Turbo Assembler | * | Прилагаются файлы проектов для RadASM IDE. |
PureBasic | PureBasic | flaith, chris_b | Требуется компилятор версии 3.50 или новее. Поместите соответствующие библиотеки в формате PureLibrary в каталог [PureBasic]\PureLibraries\UserLibraries перед компиляцией примеров. Документация для API-функций uFMOD в PureBasic доступна в подкаталоге HELP. Можете поместить данный CHM в каталог [PureBasic]\Help для использования прямо из среды разработки. Пример использования под OpenAL опирается на PureBasic OpenAL SDK, который можно найти на официальном сайте ImpLib SDK. |
VisualBasic6 | Visual Basic 6 | * | Обязательно прочитайте сопутствующий README-файл перед использованием! |
C | Visual C/C++, Dev-C++ | * | Компактные плееры XM-файлов на чистом C. Load / stop, pause / resume, muting, регулятор громкости, индикатор прогресса, индикатор уровней громкости (VU meter), поддержка перетаскивания (drag&drop) и даже некоторые эффекты DX. И всё это в 15Кб! Оба примера полностью поддерживают Юникод и специальный режим BENCHMARK (предварительно нужно пересобрать саму библиотеку в режиме BENCHMARK). Проверено в Visual C++ 6.0, Visual C++ 2005/2008 Express Edition и Dev-C++ 4.9.9.2. Здесь также находится пример использования функции Jump2Pattern. В этом примере проигрывается композитный XM, любезно предоставленный товарищем Kim (он же norki). Описание техники создания и использования подобных композиций можно найти в следующем разделе. Ещё здесь находится пример динамической загрузки библиотеки OpenAL, который таким образом способен запускаться и в отсутствии openal32.dll. |
BlitzMax | BlitzMax | *, flaith | Полная документация (на английском). Вы также найдёте здесь полные версии модулей DirectSound и OpenAL для BlitzMax. Библиотеки uFMOD под DirectX DirectSound и OpenAL используют данные модули, но Вы можете задействовать их и в сторонних проектах. |
FreeBASIC | FreeBASIC | voodooattack, antarman | Используется визуализация товарища rel, именуемая Torus. Прилагаются файлы проектов для FbEdit IDE. |
FreePascal | FreePascal | * | Проверено на FPC версии 2.0.4. Вы также найдёте здесь полные версии юнитов DirectSound и OpenAL для FreePascal. Библиотеки uFMOD под DirectX DirectSound и OpenAL используют данные юниты, но Вы можете задействовать их и в сторонних проектах. |
EBASIC | Emergence BASIC | ts-soft | |
C# | .NET SDK | * | Несколько примеров на C#, опробованных на .NET Framework 2.0. Примеры собираются в экзешник со смешанным управляемым/нативным содержимым. Чтобы портировать API uFMOD в C# мы собрали оболочку на C++, которая играет роль переходника между CLI и нативным кодом. Полные исходники прилагаются. |
Дополнительное уменьшение размера
Утилита Eff предназначена для оптимизации и уменьшения размера библиотеки uFMOD.
Если Вы собираетесь включить XM статически в экзешник или в качестве ресурса, можете попробовать оптимизировать сначала сам XM. Modplug Player умеет сжимать XM-композиции по схеме APDCM, но учтите, что этот тип сжатия пагубно влияет на качество звучания! Утилита XMStrip перепаковывает XM файлы без потери качества.
Если Вы уверены в корректности формата всех композиций, которые будут использованы в приложении, можете пересобрать библиотеку в режиме UNSAFE.
При компиляции исполнимого модуля в VC++ или MASM32 включите директиву /opt:nowin98
в аргументы командной строки линкера для уменьшения выравнивания секций до минимума. Секции .rdata (read-only data, где хранятся символы IAT и некоторые константы) и .text (код приложения) можно совместить для ещё большего уменьшения размера. Для этого достаточно добавить в опции MS LINK.EXE или POLINK.EXE следующую директиву: /MERGE:.rdata=.text
Ещё один казус связан с линкером MS: link.exe добавляет в имидж экзешника некоторую лишнюю информацию, где-то между заглушкой DOS и началом PE заголовка. Балласт легко обнаруживается в хекс-редакторе по магическому слову 'Rich', за которым следует закодированный compid вашей машины. Если Вы против того, чтобы экзешники носили подпись машины, на которой были собраны, или просто не желаете тратить пол килобайта на эту самую подпись, можете поменять линкер :) Или найдите на wasm.ru документ, в котором подробно описан процесс патчинга link.exe.
Delphi любит создавать таблицу Relocation Table (секция .reloc) в обычных экзешниках (не DLL), где эта таблица зачастую абсолютно не нужна. Эту секцию можно убрать вручную или с помощью утилит StripReloc Джордана Расселя, PE Optimizer Dr. Golova и т.п.
Visual Basic и Delphi создают секцию ресурсов (.rsrc), даже если им нечего действительно полезного в неё поместить. Если в этой секции нет форм, XM-ов или других нужных ресурсов, можете попробовать её удалить, только осторожно! Аналогично для секции .flat в экзешниках созданных в PureBasic.
Упаковщики, вроде FSG и UPX, умеют ужимать экзешники. Тем не менее, для наглядности, все примеры предоставлены без сжатия!
При использовании библиотек импорта в формате MS-COFF (вроде kernel32.lib, libkernel32.a и т.д.), тратится определённое количество байт в экзешнике на размещение таблиц с оригинальными санками (original thunks). Данные переходники нужны только при наложении "байндинга" (связывания импорта утилитой bind.exe из SDK Visual Studio). Если Вы не собираетесь "байндить" ваши экзешники, можете избавиться от санков и сэкономить до 512 байт, а то и пары килобайт при использовании большого количества импортируемых функций. Для этого необходимо заменить стандартные библиотеки импорта, которые поставляются вместе с SDK компилятора (Visual Studio, masm32, ...) на модифицированные и пересобрать нужные проекты. Модифицированные библиотеки импорта можно создать с помощью ImpLib SDK.
Вот, собственно, и всё, что нужно знать об оптимизации размера экзешника. Давайте вернёмся к теме сокращения размера XM-файлов:
Есть ещё один хитрый способ оптимизации размера XM-файлов, который заключается в совмещении сразу нескольких композиций в одном файле. При этом можно удалять лишние экземпляры повторяющихся инструментов, если таковые имеются, что очень заметно сказывается на размере конечного файла. Даже без оптимизации инструментов размер композитного файла должен получиться меньше суммы размеров отдельных файлов, так как заголовки всех файлов заменяются одним общим. Давайте рассмотрим пример с тремя файлами:
Файл 1 : XM1_HEADER P11 P12 P13 I11 I12 Файл 2 : XM2_HEADER P21 P22 P23 P24 I21 I22 I23 I24 Файл 3 : XM3_HEADER P31 I31Пояснение: XMn_HEADER - это заголовок n-ного файла. Pnm - это m-ная партитура n-ного файла. Inm - это m-ный инструмент n-ного файла.
Для начала, совместим все 3 композиции без оптимизации инструментов:
Файл 4 : XM4_HEADER P11 P12 P13 P21 P22 P23 P24 P31 I11 I12 I21 I22 I23 I24 I31Представьте, что I12 очень похож или идентичен I23; I24 и I31 тоже практически одинаковы. Мы можем заставить партитуры P2n использовать I12 вместо I23, а P31 переключить на I24. Тогда мы сможем удалить I23 и I31:
Файл 4 : XM4_HEADER P11 P12 P13 P21 P22 P23 P24 P31 I11 I12 I21 I22 I24Необходимо скорректировать команды зацикливания и ссылки на партитуры в композициях 2 и 3 после совмещения. Конечно, можно совмещать и большее количество композиций, но формат XM имеет ограничения на максимальное количество партитур и инструментов в файле. Все операции над XM-файлами надлежит проводить в специальном ПО - трекере. Для проигрывания композитного файла достаточно одного вызова функции uFMOD_PlaySong. Далее нужно использовать функцию uFMOD_Jump2Pattern для проигрывания отдельных композиций из общего файла в произвольной последовательности. Например, uFMOD_Jump2Pattern(3) переключится на вторую композицию, uFMOD_Jump2Pattern(7) начнёт проигрывать третью, а uFMOD_Jump2Pattern(0) вернётся обратно к первой. Точные значения индексов стартовых партитур каждой композиции после совмещения легко вычислить в уме, но можно и в трекере подсмотреть :) C\WINMM\ содержит реальный пример всего вышесказанного.
В использовании Jump2Pattern есть ещё один плюс - переключение происходит гораздо быстрее (практически моментально) чем при остановке текущей композиции и последующей загрузке новой. Можете брать на вооружение эту фишку для реализации решений, требующих максимально быстрого переключения музыкального фона.
В: Библиотека uFMOD действительно бесплатна для любого использования, включая коммерческое?
О: Да, текущая версия абсолютно бесплатна для использования в любых целях.
В: Где бы достать композиции в формате XM?
О: The Mod Archive содержит внушительных размеров архив с бесплатными трекерскими композициями в формате XM, IT, S3M и MOD. Open Modplug Tracker умеет конвертировать IT, S3M и MOD в XM без потери качества. В сети много талантливых композиторов, которые бесплатно выкладывают свои работы. Не забывайте указывать соответствующие пометки об авторстве!
В: Существует ли какая-либо связь между проектом uFMOD и разработками Firelight Technologies®: FMOD и miniFMOD?
О: На данный момент никакой связи уже нет. До 2004го года включительно проект uFMOD основывался на исходных кодах библиотеки miniFMOD. С тех пор, код uFMOD был полностью переписан, оснащён новыми функциями, оптимизирован и отлажен. Таким образом, uFMOD более не связан ни с FMOD, ни с miniFMOD.
В: Некоторые разработчики утверждают, что их библиотеки увеличивают экзешники на N-ное количество килобайт. На сколько килобайт увеличивается размер экзешника при использовании uFMOD?
О: Точного ответа на этот вопрос нет, так как этот размер зависит от многих факторов: используемые характеристики библиотеки (особенно при использовании утилиты Eff), основной код программы, размер XM-файла (если XM включается в EXE). Размер также зависит от опций линкера. Пример MASM32\minimal.exe занимает 5632 байт без сжатия, модификации экзешника и прочих "грязных" способов уменьшить размер.
В: Где можно раздобыть официальное описание формата XM?
О: Полного официального описания современного формата XM нет. Позвольте предложить взамен этот документ: "The Unofficial XM File Format Specification: FastTracker II, ADPCM and Stripped Module Subformats" (только на англ.). В данном документе описаны многие тонкости работы с форматом XM, включая все нестандартные расширения, которые на данный момент поддерживает uFMOD. К тому же, из исходников ModPlug (на C++) можно почерпнуть массу полезной информации по трекерским форматам файлов.
antarman, Barracuda, bogrus, chris_b, cresta, dododo, flaith, Four-F, GL#0M, norki, q_q, ReSampled, S_T_A_S_, ts-soft, voodooattack и yoxola за помощь в устранении ошибок, предложения по улучшению библиотеки, примеры использования под разные компиляторы и всё остальное, так или иначе помогающее нам в развитии проекта.
[WASM.RU], CelerSMS и SourceForge.net за поддержку и хостинг.
Автор©тво
Исходные коды uFMOD и сопровождающие утилитарные приложения © 2005 - 2022 Asterix и Quantum.
Все права защищены.
Композиции:
Нашли ошибку? Желаете задать вопрос разработчикам или высказать предложение по улучшению библиотеки? Разрабатываете интересный проект с использованием uFMOD? Вам сюда: ufmod@users.sf.net |