Кому не трудно, выделите , пожалуйста, минут 10-15 своего времени... с этим вопросом уже обращался, с тех пор вычитал немерено разной инфы, скачал много модулей, но недостаточно моих знаний, чтоб это понять! а курсовик сделать надо... нужно сделать, чтоб при нажатии клавиши клавиатуры воспроизводился звук, например sound(200), а при отпускании клавиши прекращался...
Я находил несколько модулей, в которых есть такая возможность... но как конкретно - не могу понять...
не кидайте, пожалуйста, ссылки на какой-нибудь очередной модуль или типа того... помогите, пожалуйста, для конкретно моей работы.
volvo
6.06.2007 23:29
Я же по-моему тебе говорил (или не тебе?), как это можно сделать: читаешь скан-код клавиши, если он меньше 128, значит, клавиша нажата - запускаешь звук... Если же скан-код больше 128, значит клавиша отпущена, звук надо останавливать...
Capitan Nemo
6.06.2007 23:31
сканкод считывается через readkey?
volvo
6.06.2007 23:35
Нет... Для этого надо писать или обработчик прерывания, или через массив Port ...
Capitan Nemo
6.06.2007 23:37
а прерывание, как я понимаю через asm?
volvo
6.06.2007 23:47
Совсем не обязательно... Вот тут, например, смотри в аттаче, как получают скан-код: прерывания
Capitan Nemo
7.06.2007 0:18
пытаюсь разобраться с кодом - но многое непонятно... не смог понять что делает процедура New9... что необходимо сделать мне для считывания скан-кода?
Scan := Port[ $60 ] - здесь что-то инициализируется?
ЗЫ был бы безумно признателен, если б кто-нибудь набросал код необходимый мне... ну не как ен могу разобраться... не мой это уровень... мне препод сказал: "не сделаешь это - больше 4 не поставлю"... но он когда это говорил - был уверен, что функция keypressed возвращает состояние клавиши (нажата или нет в данный момент)... Возможно, завтра у меня все и так разрулится... а возможно нет... поэтому очень необходимо все-таки реализовать поставленную задачу...
volvo
7.06.2007 0:36
Цитата
Scan := Port[ $60 ] - здесь что-то инициализируется?
Здесь Скан-код нажатой (или отпущенной) клавиши записывается в переменную Scan... Все, его можно анализировать! Только делать это желательно в основной программе, и уж тем более включать/выключать звук - это довольно длительные действия, а процедура обработки прерывания должна как можно быстрее возвращать управление...
Поэтому переменную Scan описывай глобально, и как только действия по нажатию/отпусканию произведены (т.е., ты поймал момент и включил/выключил звук), Scan обнуляй... Сейчас покажу...
{$f+} { Ну, это - собственно процедура - обработчик прерывания, здесь все понятно } Procedure New9; Interrupt; Begin Scan := Port[ $60 ]; { запоминаем скан-код нажатой клавиши в глобальной переменной } do_exit := (scan = $01); { и смотрим, не нажат ли Escape, для выхода из программы }
Inline( $9C ); { здесь - вызываем старый обработчик прерывания } KbdIntVec; End; {$f-}
var checked: boolean;
BEGIN { запоминаем вектор прерывания 9H... причем, это делаем дважды: } GetIntVec($9, @KbdIntVec); { Здесь - для удобного вызова с использованием процедурного типа } GetIntVec($9, Old_09); { а здесь - чтобы потом иметь возможность восстановить текущее значение } SetIntVec($9, Addr(New9)); { заменяем стандартную процедуру обработки на свою }
Scan := 128; checked := false; { начальные значения }
repeat { проверяем значения scan-кода } case scan of 1 .. 127: { если здесь - то кнопка нажата } begin { для того, чтобы не производить лишних действий - если кнопка ДО ЭТОГО еще не была нажата, то устанавливаем флажок, и производим необходимое действие один раз... Если же факт нажатия кнопки уже зафиксирован установленным флагом - то ничего не надо делать, только сбросить Scan в начальное значение } if not checked then begin checked := true; writeln('key pressed ... '); { sound(200); } end; Scan := 128; end; 129 .. 255: { если здесь - то клавиша была отпущена (скан-код увеличен на 128) } begin { в принципе, эту проверку можно было бы и не производить, но я уже сделал по аналогии с обработкой нажатия клавиши... } if checked then begin checked := false; writeln('key released ... '); { nosound; } end; Scan := 128; end; end;
until do_exit; { цикл закончится только тогда, когда будет нажата кнопка Escape }
{ восстанавливаем ранее сохраненный вектор прерывания перед выходом из программы } SetIntVec($9, Old_09); END.
Жми кнопку, выйдет сообщение, что нажал. Пока не отпустишь - больше никаких сообщений не будет. Вместо вывода сообщения поставь то, что закомментировано. Вот и все...
P.S. Могут быть проблемы с F11, F12 - у них разные скан-коды на разных клавиатурах...
Capitan Nemo
7.06.2007 1:13
огромнейшее спасибо!!!!!
наберусь наглости попросить несколько комментариев по основным этапам сего действия... Чтоб я хоть мог объяснить как я это сделал)
volvo
7.06.2007 2:49
Комментарии добавлены...
Capitan Nemo
7.06.2007 2:51
Огромнейшее спасибо!!! Вы спасли брянского студента от мозголюбства от препода))
Capitan Nemo
7.06.2007 5:17
встроил эту штуку в свою программу... все работает. но с багом... иногда, когда нажму на клавишу - звук начинается, отпускаю - он не прерывается... если еще раз нажму на эту клавишу и подержу подольше - все нормально становится... что это может быть, не знаете?
Capitan Nemo
8.06.2007 3:03
все, разобрался, все исправно работает)
только один нюанс: почему, когда нажимаешь клавиши раз в пятый в колонках раздается звук... кстати, так же и с программой, описанной выше volvo
Добавлено через 3 мин. и еще вопрос. на этот раз уж точно последний) как установить задержку на определенное число миллисекунд, кроме как через delay?
volvo
8.06.2007 3:11
Потому, что я совсем забыл чистить буфер клавиатуры... Когда ты нажимаешь клавишу, ее Ascii-код попадает в буфер, однако оттуда ничем не читается. Буфер переполняется, и начинается писк.
Capitan Nemo
8.06.2007 3:13
и как это исправить? как очистить буфер?
Добавлено через 11 мин. readkey, по ходу)
Добавлено через 2 мин. а насчет задержки вот что мне нужно: при входе в цикл, если клавиша нажата - я засекаю системное время, при выходе - когда клавиша отжата - засекаю время... отнимаю от конечного начальное, умножаю секунды, прибавляю миллисек, в общем, получаю длительность в миллисекундах.... затем, в другой процедуре я использую эту длительность для воспроизведения... если ставлю delay(кол-во миллисекунд) он делает не такую паузу, как надо... слишком быстро он, не по кол-ву миллисекунд... что можно сделать?