Как претворить в жизнь идею компьютерной игры? Приходилось ли вам, играя в свою любимую игру, мечтать о том, как можно было бы ее улучшить

Вид материалаДокументы

Содержание


Функция № 1: UnloadMidPak
Функция № 2: DigPakAvailable
Функция № 3 PlaySequence
Функция № 4: SegueSequence
Функция № 5: RegisterXmidi
Функция № 6: MidiStop
Функция № 9: ResetTriggerCount
Функция № 13: SequenceStatus
Функция № 14: RegisterXmidiFile
Функция № 15: RelativeVolume
Функция № 16: SetRelativeVolume
Функция № 18: PollMidPak
Функция № 19: MidpakClock
Функция № 20: TriggerCountAddress
Функция № 21: EventIDAddress
Функция № 23: ReportSequenceNumber
"Test1.snd", "test2.snd", "pend.3nd", "test.snd" }
Подобный материал:
1   ...   20   21   22   23   24   25   26   27   ...   37

^ Функция № 1: UnloadMidPak

Эта функция освобождает память, занятую резидентной частью MIDPAK, и на должна использоваться прикладной программой! Используется MIDPAK для внутренних целей и приведена здесь только для полноты картины.

ВХОД: AX=700h Номер команды.

ВЫХОД: Ничего

^ Функция № 2: DigPakAvailable

Функция определяет доступность драйвера DIGPAK под драйвером MIDPAK.

ВХОД: AX=701h Номер команды.

ВЫХОД: АХ=0 DIGPAK не доступен.

АХ=1 DIGPAK доступен.

^ Функция № 3 PlaySequence

Функция исполняет последовательность из текущего зарегистрированного XMIDI-файла.

ВХОД: AX=702h Номер команды,

BX=SEQ Номер последовательности, начиная с нуля,

ВЫХОД: АХ=1 Последовательность проигрывается.

АХ=0 Последовательность не доступна.

^ Функция № 4: SegueSequence

Функция регистрирует с указанием кода активации новую последовательность Для исполнения по триггерному событию. Если значение кода активации -1, то переход к данной последовательности будет осуществлен по ближайшему триггеру. Триггер с указанием кода события помещается в поток данных MIDI с помощью Контроллера 119. Контроллеры 119 могут быть помещены в любое место потока данных MIDI для передачи программе информации о текуацей позиций в MIDI-последовательности.

ВХОД: AX=703h Номер команды.

ВХ = SEQ Номер регистрируемой последовательности.

СХ= ACT Код активации события, -1 означает следующий триггер.

^ Функция № 5: RegisterXmidi

Функция регистрирует адрес файла XMIDI для исполнения.

ВХОД: AX=704h Номер команды,

BX=Offset Смещение в дальнем адресе данных XMIDI.

CX=Segment Сегмент в дальнем адресе данных XMIDI.

SI=Low len Младшее слово значения длины данных XMIDI.

DI=High len Старшее слово значения длины данных XMIDI.

ВЫХОД: АХ=0 Ошибка регистрации данных XMIDI.

АХ=1 Файл XMIDI зарегистрирован резидентно. Это означает, что файл полностью поместился во внутренний буфер MIDPAK. Ваша программа может освободить память, связанную с файлом XMIDI, так как MIDPAK создал для себя его, копию. Это очень полезно в средах с виртуальной памятью, где прикладная программа не всегда имеет фиксированный адрес в памяти. Это также позволяет MIDPAK исполнять музыку в фоновом режиме под DOS.

АХ=2 Файл XMIDI зарегистрирован. Прикладная программа ответственна за то, чтобы указанный фиксированный адрес в памяти всегда содержал соответствующие данные XMIDI.

^ Функция № 6: MidiStop

Функция, останавливает воспроизведение текущей последовательности MIDI.

ВХОД: AX=705h Номер команды.

ВЫХОД: Ничего

Функция № 8: ReportTriggerCount

Функция возвращает счетчик триггерных событий и код последнего события.

ВХОД: AX=707h Номер команды.

ВЫХОД: AX=COUNT Количество событий со времени последнего сброса счетчика.

DX=ID Код последнего события. Коды событий вы можете найти в спецификации XMIDI..

^ Функция № 9: ResetTriggerCount

Функция сбрасывает счетчик событий в ноль.

ВХОД: AX=708h Номер команды.

ВЫХОД: Ничего

Функция № 12: ResumePlaying

Функция продолжает исполнение остановленной последовательности.

ВХОД: АХ-70Вh Номер команды.

^ Функция № 13: SequenceStatus

Функция возвращает состояние последовательности.

ВХОД: АХ=70Сh Номер команды.

ВЫХОД: АХ=Статус

SEQ_STOPPED 0 Воспроизведение последовательности остановлено.

SEQ_PLAYING 1 Последовательность исполняется в настоящий момент.

SEQ_DONE 2 Исполнение последовательности завершено.

^ Функция № 14: RegisterXmidiFile

Функция регистрирует файл по его имени.

ВХОД: AX=70Dh Номер команды.

BX=Offset Смещение адреса имени файла.

CX=Segment Сегмент адреса имени файла.

^ Функция № 15: RelativeVolume

Функция возвращает относительную громкость музыки в процентах.

ВХОД: АХ=70Еh Номер команды.

ВЫХОД: АХ= VOL Текущая относительная громкость в процентах 0-100.

^ Функция № 16: SetRelativeVolume

Функция устанавливает относительную громкость в процентах.

ВХОД: AX=70Fh Номер команды.

Функция № 17: BootstrapMidPak

Функция позволяет приложению устанавливать драйвер MIDPAK.

ВХОД: АХ-710h Номер команды.

ВХ:СХ СЕГМЕНТ:СМЕЩЕНИЕ драйвера ADV.

DX:SI СЕГМЕНТ:СМЕЩЕНИЕ файла AD.

^ Функция № 18: PollMidPak

ВХОД; AX=710h

Функция используется в сочетании с PMIDPAK.COM. Это версия MIDPAK, работающая по опросу. Обычный MIDPAK перехватывает прерывание либо от таймера, либо от часов реального времени и обслуживает его с частотой 120 раз в минуту. Однако некоторые сложные прикладные программы сами обслуживают аппаратные прерывания и требуют исполнения фоновой музыки с иной частотой дискретизации, или синхронизируют по таймеру графические функции, чтобы избежать возможного прерывания музыкой графических процедур.

После того как MIDPAK установлен, он восстанавливает вектор прерывания таймера и не проявляет себя до- тех пор, пока программа, не выполнит прерывание 66h с командой 0711h. Вы должны вызывать это прерывание с частотой 120 раз в минуту или с частотой дискретизации, указанной при запуске MIDIFORM. При запуске MIDIFORM вы можете указать частоту дискретизации для вашей музыки, отличную от принятого по умолчанию значения 120. При снижении частоты дискретизации вы услышите ухудшение качества музыки, так как ASDR не будет реагировать достаточно быстро. Снижение ее, например, до 60 раз в минуту не будет сильно заметным, однако уменьшение частоты до 30 или 15 вызовет значительное ухудшение качества звучания. Очевидно, что исполнение многоканальной MIDI-музыки на таком частотном синтезаторе, как Adiib, потребует определенных ресурсов процессора. Переквантовывая свою музыку и задавая MIDPAK удобные для вас частоты, вы можете добиться хорошего баланса использования ресурсов компьютера.

^ Функция № 19: MidpakClock

Функция возвращает текущее значение счетчика MIDPAK.

ВХОД: AX=7l2h

ВЫХОД: AX:DX Текущее значение счетчика с момента старта MIDPAK. Счетчик обновляется 120 раз в минуту, и ваше приложение может использовать его как таймер.

ВХ:СХ Образует дальний указатель на счетчик.

ВХ Смещение, СХ Сегмент.

Функция возвращает значение внутреннего счетчика MIDPAK. При старте счетчик, представляющий собой двойное слово, имеет нулевое значение, которое увеличивается каждую минуту на 120, и ваше приложение может использовать его как таймер, просто опрашивая эту функцию.

^ Функция № 20: TriggerCountAddress

Функция возвращает адрес размещения счетчика триггеров.

ВХОД: АХ=713h

ВЫХОД: AX:DX Образует адрес целого значения счетчика триггеров. Значение этого счетчика увеличивается на единицу при каждом появлении Контроллера 119 в файле MIDI.

^ Функция № 21: EventIDAddress

Функция возвращает адрес размещения кода события.

ВХОД: AX=714h

ВЫХОД: AX:DX Образует адрес целого значения кода события. В этой ячейке памяти хранится код последнего события вызванного Контроллером 119.

^ Функция № 23: ReportSequenceNumber

Функция возвращает номер исполняемой в данный момент последовательности.

ВХОД: AX=716h

ВЫХОД: Возвращает номер исполняемой в данный момент последовательности.

extern short cdecl CheckMidiIn (void);

// Возвращает 1, если MIDPAK установлен, 0 - если нет.

extern short cdecl DigpakAvailable (void) ;

// Возвращает 1, если DIGPAK установлен, 0 - если нет. /****************************•*************************************

/** Эти флаги возвращает функция регистрации данных XMIDI ***

/****************************************************************/

#define FAILURE_TO_REGISTER 0 // Ошибка регистрации XMIDI файла.

#define REGISTERED RESIDENT 1 // Резидентный драйвер полностью

// содержит данные XMIDI. Приложение

// может освободить память, которую

// они занимали.

#define REGISTERED_APPLICATION 1 //Драйвер не имеет настолько

// большого буфера, чтобы полностью

// загрузить в него данные XMIDI.

// Приложение обязано обеспечить

// сохранение в памяти по указанному

// адресу данные XMIDI.

extern short cdecl PlaySequence (short seqnum);

// исполняет последовательность с данным номером

// из зарегистрированного файла XMIDI

#define NEXT_CALLBACK - 1 // активизация по ближайшему событию

extern short cdecl SegueSequence (short seqnum, short activate) ;

// Переключает исполнение последовательности на

// указанную последовательность по наступлению

// события с кодом, равным указанному коду активации.

// Если код активации равен -1, переключение

// произойдет по ближайшему событию.

extern short cdecl RegisterXmidi (char *xmidi, long int size) ;

// Регистрирует XMIDI файл для воспроизведения.

// Этот вызов зарегистрирует все последовательности.

extern short cdecl MidiStop (void);

// остановка воспроизведения текущей последовательности

extern long int cdecl ReportCallbackTrigger (void);

// младшее слово - счетчик триггеров

// старшее слово - идентификатор последнего события

extern void cdecl ResetCallbackCounter (void);

// сбрасывает счетчик триггеров в ноль

extern void cdecl ResumePlaying (void) ;

// продолжает воспроизведение прерванной последовательности

#define SEQ_STOPPED 0 // возвращаемые значения

#define SEQ_PLAYING 1 // функции SequenceStatus()

#define SEQ_DONE 2

extern short cdecl SequenceStatus (void) ;

// возвращает состояние текущей последовательности

extern short cdecl RelativeVolume (short vol);

// возвращает текущую громкость

extern void cdecl SetRelativeVolume (short vol, short time);

// устанавливает громкость на заданный период времени

#define NOBUFFER 1 // нет резидентного буфера

#define FILENOTFOUND 2 // файл не найден

#define FILETOBIG 3 // файл превышает размер

// зарезервированного буфера

#define REGISTRATIONERROR 4 // ошибка регистрации файла XMI

extern short cdecl RegisterXmidiFile (char *fname);

// регистрирует файл по имени

extern void cdecl PollMidPak (void);

// запрос MIDPAK на исполнение музыки

extern long int cdecl MidPakClock (void);

// возвращает значение внутреннего счетчика MIDPAK

extern long int * cdecl MidPakClockAddress (void);

// возвращает адрес таймера MIDPAK

extern short * cdecl TriggerCountAddress (void) ;

// возвращает адрес счетчика триггеров

extern short * cdecl EventIDAddress (void);

// возвращает адрес идентификатора события

extern short cdecl ReportSequenceNumber (void) ;

extern short cdecl InitMP (char *midpak, char *adv, char *ad) ;

// инициализирует драйвер MIDPAK

extern void cdecl DeInitMP (char *midpak);

// выгружает драйвер MIDPAK

Завтрак с Толстяком - музыка в программах

Я попросил моего друга, Джорджа Алистара Зангера, известного под псевдонимом Толстяк, порассуждать о том, как, когда и почему музыка должна использоваться в программах. Толстяк — популярный композитор, предоставляющий широкий диапазон услуг в индустрии мультимедиа.

Толстяк создает музыку в своем доме в Остине, штат Техас для клиентов от Лос-Анджелеса до Нью-Йорка и Гонконга. Среди его клиентов Warner/Elektra/Atlantic, Cannon Films и Southwest Airlines. Он участвовал в создании музыкального оформления для десятка программных продуктов, включая Wing Commander фирмы Origin Systems, The 7th Guest фирмы Virgm/Trilobyte и SSN-21 Seawolf фирмы Electronic Arts.

Почему?

Почему музыкальные и звуковые эффекты должны использоваться в компьютерных программах? По той же самой причине, по которой все окружающие пользуются пиктограммами, — потому что это следующий логический шаг в разработке компьютерных программ. Пиктограммы и графика избавляют пользователя от необходимости представлять себе, что же они должны увидеть, музыка же говорит им, что они должны почувствовать.

Я бы не хотел принижать интеллект среднего пользователя, но чтение требует определенной аналитической работы. Чтение медленный процесс, оно не соответствует нашему естественному восприятию мира, и пользователи не очень-то любят читать. Вот тут на помощь и приходят пиктограммы. Уже установлено, что они повышают производительность, предлагая нам образы из «реального мира» (что бы это ни значило) и позволяют нам связать свои представления, например, о книжном шкафе или волшебнике с тем, что мы видим на экране. Музыка и звук продвигают все это на следующую логическую ступень.

Графика у пользователя ассоциируется с чувствами, вызываемыми объектом реального мира. Музыка и звук действуют еще более непосредственно. Они вызывают ассоциативные чувства — пользователь теперь уже может представить себе злого волшебника или удобный шкаф. И эти ассоциации могут оказаться очень мощным инструментом. В PC Magazine, в обзорной статье о мультимедиа, ветеран интерактивного видео предположил, что эмоции, вызываемые информацией, могут являться основной причиной информационных перегpyзoк и таким образом оказаться даже более важными, чем сама информация.

Звук и музыка могут:
  • Повысить информативность;
  • Сделать общение с компьютером более приятным;
  • Повысить развлекательную ценность программы.

Когда?

Музыка и звук должны использоваться не только в играх.

Несмотря на то, что компьютерные программы Достаточно сильно отличаются от фильмов, разработчикам полезно быть в курсе последних новинок кинематографа и рассматривать фильмы как модели некоторых аспектов будущих компьютерных программ. Причем примеры можно найти не только в художественных фильмах, но и в рекламных роликах, учебных программах, новостях — в общем, во всем, что снимается на кино- или видеопленку.

Основное правило состоит в том, что музыка и звук используются тогда и только тогда, когда необходимо подчеркнуть эмоции, испытываемые зрителем. Следовательно, в случае компьютерных программ имеет смысл использовать музыку и звук в следующих ситуациях:
  • Для усиления уже существующих эмоций. Многим нравится веселая рожица или что-либо подобное при запуске компьютера — с помощью веселой мелодии можно достигнуть того же эффекта. Логотип фирмы может быть подчеркнут звуковым эффектом. Подвижные игры могут рассматриваться как приключенческие фильмы, ну а стратегическим играм больше подойдет музыкальное оформление мистических или документальных лент;
  • Для создания новых эмоций. Если вам действительно необходимо привлечь внимание пользователя, представьте себе, насколько звук клаксона будет эффективнее слова «ВНИМАНИЕ» в диалоговом окне. Писк при нажатии клавиши тоже для многих может сделать жизнь комфортнее. Если интересной графикой вы можете развеять скуку и пробудить интерес, то музыка может многократно усилить эти эмоции;
  • Для манипулирования уже существующими эмоциями. Программа по детской безопасности может показывать изображение симпатичного ребенка возле бассейна. Тревожная мелодия поможет воспрепятствовать концентра ции внимания пользователя только на ребенке. Простая незамысловатая мелодия поможет сделать восприятие программы баз данных не таким пугающе сложным. В случае диалогового окна с «плохими новостями», насколько приятнее услышать приятный звуковой эффект, чем звук взрыва бомбы. С помощью звука разработчик так же, как режиссер в кино, можетконтролировать уровень эмоций, испытываемый пользователем.

Кроме того, не стоит использовать музыку и звук, если:
  • Они вызывают не соответствующий обстоятельствам эмоциональный отклик. Это происходит, когда музыка не несет никакой смысловой нагрузки, просто плохо написана, или не адекватна задачам программного продукта. Такая музыка вызывает у пользователя лишь досаду и снижает ценность программного продукта;
  • Они являются просто фоном.

Все это приводит нас к следующему вопросу...

Как?

Как и графика, музыка и звук должны быть хорошо написаны. Нельзя создать стоящую программу, просто заполнив свободное место на экране халтурной графикой, сделанной «другом-художником» (у всех нас есть такие). Абсолютно то же самое можно сказать и о музыке. На самом деле выбор подходящей музыки для программы ничуть не легче, чем для фильма. Но это слишком непростой вопрос, поэтому мы не будем на нем здесь останавливаться подробно.

Приведу лишь простое правило, воспользовавшись которым вы сможете себя проверить. Чтобы оценить качество вашего звука, вне зависимости от вашей аппаратной платформы, ответьте на три вопроса:

  1. Поддерживает ли каждая нота эмоциональную направленность программы?
  2. Повышает ли музыка интерес к программе?
  3. Можете ли вы под нее танцевать?

Ну что ж, неплохо посидели. Надо бы встречаться почаще.

Создание пользовательского интерфейса с системой распознавания голоса

Я бы хотел немного остановиться на новых формах пользовательского интерфейса, базирующихся на звуке. Сейчас уже очевидно, что мы в состоянии использовать системы распознавания голоса в разработке интерфейса программы. Я бы хотел дать несколько общих советов тем, кто собирается включить распознавание голоса в свои прикладные программы.

Управление голосом является наиболее естественным способом общения с компьютером. Почему же до сих пор это не очень получается? Большинство современных голосовых систем пассивны; они работают на заднем плане, пытаясь угадать, что же вы хотели им сказать. Проявившись же, они стирают файл или делают что-нибудь похожее по идиотизму.

Большинство скажет, что проблема в самих программах распознавания голоса. Но это не так. Проблема в дизайне пользовательского интерфейса.

Интерфейс с распознаванием голоса должен быть активным. Он должен переспрашивать пользователя при сомнениях и подтверждать получение команды. Он так же должен персонифицироваться через технику общения и используемые выражения.

Попробуйте пообщаться с приятелем, который никогда не отвечает - у вас появится ощущение, что вас игнорируют. Как минимум, вам нужно иногда услышать «Да-а» или «Ага», чтобы знать, что вас слушают. Или возьмите другой пример. Отец просит ребенка что-то сделать, а в ответ не слышит:

«Хорошо, папа». В таком случае папа обычно начинает злиться и кричать: «Эй, ты меня слышишь?!» (так, по крайней мере, происходит в моем доме.) При разговоре нам необходима ответная реакция, чтобы знать, что нас поняли. Интерфейс с распознаванием голоса должен использовать реплики типа: «Конечно», «Хорошо, шеф», «Простите?»

Несколько подобных фраз могут сделать интерфейс более естественным и позволят нам управлять сложными системами набором нескольких простых голосовых команд. Сегодня не существует реальной проблемы с системами распознавания голоса. Обычно они распознают отдельные слова достаточно аккуратно. Существующие коммерческие программы позволяют нам совершать очень сложные действия, используя несколько меню и пиктограмм. Хорошо разработанная система с голосовым меню может быть не менее мощной и быть гораздо привлекательнее в использований.

И, наконец, последнее замечание о голосовом взаимодействии с компыотером. Говорящие машины заслужили плохую репутацию в начале 80-х из-за японских говорящих автомобилей: «Дверь открыта! Дверь открыта!». Все их ненавидели. Люди гордились тем, что им удалось «сломать» свои новые машины и выключить надоедливый голос. Заметьте, что проблема состояла не в плохом произношении машины, а в плохом пользовательском интерфейсе. Многих из нас еще в детстве научили, что не следует заговаривать с кем-либо, пока к вам не обратились. То же относится и к говорящим машинам. Если машина надоедает вам, прерывает ход ваших мыслей и мешает тому, что вы сейчас делаете, это очень раздражает. Однако если вы можете о чем-либо спросить машину и получить от нее ответ, это очень классная машина. Если машина хочет сообщить вам что-то действительно важное, она не должна врываться без приглашения, прерывая ваши мысли или разговор. Нет, она должна вежливо сказать «Гхм» или «Простите» либо просто прочистить свое электронное горло. Когда вы найдете время ответить и скажете: «Да, Саймон», компьютер может выдать накопившуюся информацию. Если системы с распознаванием голоса не являются достаточно естественными, они практически бесполезны. Мы будем продолжать использовать клавиатуру и мышь там, где это необходимо, но системы с распознаванием голоса должны стать более общительными, интерактивными и, самое главное, естественными.

Для персонификации машины одинаково подходит и использование разговорного языка, и акцент, и юмор. Обычно юмора боятся, вдруг кто-то подумает, что программа несерье;й1ая. Но кому понравится в очередной раз слушать идеальный, безжизненный голос «голосовой почты». Вместо этого, ваш компьютер мог бы сказать; «ОК, босс, все что пожелаете!» или «Конечно, Пап, нет проблем!» или «Инициализирую последовательность сохранения файла, доволен?» Конечно, это только примеры, и их не надо понимать буквально, просто они показывают, что общение с компьютером тоже может быть веселым. А ведь сделать общение с компьютером более естественным, простым, менее пугающим — и есть основная цель хорошо продуманного интерфейса.

В заключение, я хочу сказать, что приведенные здесь примеры представлены только для подстегиваиия вашей изобретательности. При разработке голосового интерфейса, просто задайте себе один вопрос: «Как бы это выглядело, если б я разговаривал с живым человеком?» Затем, учитывая технические ограничения, сделайте нечто максимально похожее на живую речь. Помните, что хотя машина может «слышать» лишь ограниченное число слов, «сказать» же она может все, что угодно. Составьте простой набор команд, и сделайте его минимально подверженным ошибкам. Старайтесь по возможности учитывать пожелания пользователя. Пусть ваши голосовые ответы варьируются и, самое главное, будут естественными.

Демонстрационная программа Test.c

Ниже приводится демонстрационная программа на языке Си, которая показы­вает, как загружать и работать с драйверами DIGPAK и MIDPAK.

/* */

/* TEST.C Демонстрационная программа работы с драйверами DIGPAK */

/* и MIDPAK. Динамически загружает драйверы DIGPAK и MIDPAK, */

/* SOUNDRV.COM и MIDPAK.COM/MIDPAK.ADV/MIDPAK.AD. Затем */

/* воспроизводит MIDI-файл TEST.XMI, позволяя вам исполнять */

/* звуковые эффекты TEST1.SND и TEST2.SND */ /****************************************************************/

/* Автор: John W. Ratcliff (с) 1994 */

/* CompuServe: 70253,3237 */

/* Genie: J.RATCLIFF3 */

/* BBS: 1-314-939-0200 */

/* Адрес: */

/* 747 Napa Lane */

/* St. Charles, МО 63304 */

/* */

/* */

/*********************************************'******************/

#include

#include

#include

#include "keys.h" // Включает определения для

// клавиатурных команд

#include "support.h" // Включает файл заголовка базовых

// функций поддержки

#include "loader.h" // Включает файл заголовка динамического

// загрузчика MIDPAK/DIGPAK

#include "midpak.h" // Включает файл заголовка функций

// нижнего уровня MIDPAK

#include "digplay.h" // Включает файл заголовка функций

// нижнего уровня DIGPAK

#include "doscalls.h" // Включает файл заголовка

// DOS-функций поддержки

#define NOBJ 4 // число загружаемых звуковых эффектов

static char *Names [NOBJ]= // имена файлов звуковых эффектов

{

^ "TEST1.SND", "TEST2.SND", "PEND.3ND", "TEST.SND" };

static SNDSTRUC *snd; // Структура звуковых данных DIGPAK

static char *soundbuffer=0; // Адрес буфера звуковых данных

static long int ssize[NOBJ]; // Длина загружаемого звукового эффекта

static int NALLOC=0;

char *Sounds[NOBJ]; // адреса всех звуковых эффектов

void UnloadSounds(void); // Выгрузка звуковых эффектов из памяти

int LoadSounds(void); // Загрузка звуковых эффектов в память

void PlaySound(int sound); // Воспроизведение звукового эффекта

void TestDigPak(void); // Тестирование функций

// воспроизведения DIGPAK

// Приложение должно обеспечить функции резервирования памяти. Они

// используются загрузчиком и DOS функциями поддержки. Вы можете

// заменить эти функции любой другой системой управления памятью.

unsigned char far * far memalloc(long int siz) {

unsigned char far *mem;

mem = farmalloc(siz) ; // функция Си для резервирования

// памяти по дальнему адресу return(mem);

}

void far memfree(char far *тетогу)

farfree(memory); // функция Си для освобождения памяти по

// дальнему адресу

}

void main(void)

{

long int siz;

char *fname;

// Вызов загрузчика для начальной загруаки стандартного

// драйвера DIGPAK

if ( !LoadDigPak("SOUNDRV.COM") )

{

printf("Failed to load sound driver.\n");

exit(l);

} if ( !InitDigPak() ) // Инициализация драйвера DIGPAK

{

// Выгрузка драйвера из памяти в случае неудачной

// инициализации и завершение работы программы.

UnLoadDigPak();

printf("Failed to initialize sound driver.\n") ;

exit(l);

}

if ( LoadMidPak('MIDPAK.COM", "MIDPAK.ADV", "MIDPAK.AD") ) // Загрузка компонентов MIDPAK {

printf("Loaded MIDPAK.СОМ MIDPAK.ADV and MIDPAK.AD into Low Men\n");

if ( InitMidPak() )

{

printf("MIDPAK driver initialized.\n");

fname = floadlow("TEST.XMI",&siz); // Загрузка музыки

if ( fname }

{

printf("Loaded TEST.XMI %d bytes long.\n",siz);

RegisterXmidi(fname,siz); // Регистрация XMIDI

// последовательности

printf("Sequence registered, now playing.\n") ;

PlaySequence(0); // Исполнить первую

// последовательность

SegueSequence (1,-1); // Зарегистрировать вторую

// последовательность на

// исполнение сразу же по

// достижении первого

// Контроллера 119

}

} else

printf("Failed to initialize MIDPAK driver.\n");

}

TestDigPak(); // Тестирование/демонстрация возможностей функций

// DIGPAK

UnLoadMidPak(); // Выгрузка MIDPAK из памяти,

// освобождение аппаратуры

UnLoadDigPak(); // Выгрузка DIGPAK из памяти,

// освобождение аппаратуры

RemoveVectorLoader() ;

}

void TestDigPak(void)

{

int i,key,sound;

printf("Loading digital sound effects.\n");

if ( LoadSounds() ) // Загрузка звуковых эффектов в память

{

// Создание меню звуковых эффектов

printf("Select an sound effect to play. [ESC] when finished playing around.\n");

for (i=0; i
{

printf("%c %s\n",i+'A',Names[i]) ;

}

do

{

if ( keystat() ) // если клавиша нажата

{

key = getkey(); // получить нажатую клавишу

if ( key >= ' a' && key <= ' z') key-=32;

// преобразовать нижний регистр к верхнему

if ( key >= 'А' && key <= 'Z')

{

sound = key-'A';

if ( sound < NOBJ ) PlaySound(sound);

}

} while ( key != 27 );

UnloadSounds(} ;

}

}

// загрузить все звуковые эффекты в память

int LoadSounds(void)

{

int fph;

long int siz.end;

int i, handler;

int select;

for (i=0; i
{

Sounds[i] = fload(Names[i], &siz);;

if ( !Sounds[i] )

{

printf("File '%s' not found.\n"/Names[i]) ;

return(0) ;

}

ssize[i] = siz;

snd.frequency = 11000;

snci. sound = Sounds [i];

snd.sndlen = ssize[i]; // задает длину звукового эффекта

//в байтах

MassageAudio(&snd) ;

printf("Sound Loaded '%s'.\n",Names[i]);

}

return(1) ;

}

void UnloadSounds(void) {

int i;

for (i=0; i < nalloc; i++) memfree(Sounds[i]);

if ( soundbuffer )

{

realfree(snd) ;

realfree(soundbuffer);

}

NALLOC=0 ;

}

void PlaySound(int sound)

{

if ( !soundbuffer }

{

snd = (SNDSTRUC *) realalloc(sizeof(SNDSTRUC));

snd->frequency = 11000;

soundbuffer = realalloc(65535);

}

StopSound(); // ожидать до окончания предыдущего звукового эффекта

snd.frequency = 11000;

snd.sound = Sounds[i];

snd.sndlen = ssize[i]; // задает длину звукового эффекта

//в байтах

DigPlay2(&snd); // воспроизвести эффект

//в аппаратно-зависимом формате

}