Посмотрел немного исходники. До конца не разобрался, но как понял используется waveOut, и привязка к реальному времени происходит путем ожидания окончания звучания фрейма?
При этом действительно возникает треск при использовании буфера аудио слишком малого размера.
Одно из решений: уменьшить размер фрейма до 20 мс, оставив размер аудиобуфера прежним: задержка звука не так заметна, как задержка реакции на клавиатуру. Я применял подобный способ в 3-й версии emu80.
Цикл при этом будет выглядеть примерно так:
- фрейм 20 мс
- задежка до 20 мс
- рисуем экран и опрашиваем клавиатуру
- фрейм 20 мс
- ждем окончания проигрывания 40 мс звука
- рисуем экран и опрашиваем клавиатуру
Последний раз редактировалось Pyk; 18.03.2018 в 23:02.
что-то вроде:
при эмуляции спека еще проще, не нужно обрабатывать изменение как событие, портов только многоКод:// вызывается один раз в начале фрейма old_portX_value = new_portX_value; new_portX_value = 0xFF; // ничего не нажато kb_state = getKeyboardState(); // что сейчас нажато на пц-клаве if (kb_state[some_key]) new_portX_value &= some_key_mask; // и так далее // обработка изменения состояния, тоже однократно if (old_portX_value != new_portX_value) { ... } // и далее в течение фрейма при любых чтениях порта X подставляем new_portX_value
БК знаю плохо, но, вероятно, эмуляция лишь одного события по началу фрейма сильно упростит жизнь,
субъективных ощущений не вызывая (всё равно человек так быстро кнопки не долбит)
Прихожу без разрешения, сею смерть и разрушение...
Функция GetKeyboardState возвращает массив размером 256 байтов, для состояний каждой из 256 виртуальных клавиш.
Чтобы узнать, какая клавиша нажата, надо пробежаться по массиву и определить их состояние. Но при этом если нажато несколько клавиш одновременно, невозможно определить, какую клавишу для БК надо считать нажатой, т.к. в любой момент времени на БК считается нажатой только одна клавиша, сколько бы их не нажимали одновременно, нажатой считается первая из всех нажатых. Если считать нажатой первую найденную в массиве, мы рискуем не угадать.
Особенностью клавиатуры на БК является то, что никакие другие коды и вообще ничего не обрабатывается, пока все одновременно нажатые клавиши не будет отпущены. После этого ожидается нажатие клавиш. Т.е. требуется отслеживать именно факт нажатия и факт отжатия клавиш клавиатуры.
А вот такую функцию, которая бы сообщала, что вот сейчас что-то нажато на клавиатуре, я не нашёл.
gid, а почему бы не использовать сообщения клавиатуры (WM_KEYUP, WM_KEYDOWN)? Они же приходят именно в том порядке, в каком были нажаты клавиши...
Потому что Lethargeek против такого метода. А у меня как раз такой и используется.
Какую любою? Я не ухитрился, я просто предполагаю, что нажатие на клавишу может быть сделано в абсолютно любой момент времени. И нажато может быть абсолютно любое количество клавиш. И некоторые из них могут оказаться теми, которые не должны восприниматься эмулятором ни в каком случае, он их должен просто игнорировать.
Мне совершенно не хочется смешивать обработку клавиатуры по событиям и по опросу состояния, т.к. обработчик событий и так уже делает всю работу за меня - определяет, что нажато, формирует скан коды и флаги управляющих клавиш и выдаёт их мне.
А вообще, я не знаю, чем hobot не доволен. В игре Boulderdash эмулятор БК ведёт себя именно так, как и настоящий БК-0010 с дубовой кнопочной клавиатурой. По моим детским воспоминаниям. Жмёшь на кнопку - а она не нажимается. Или нажалась, а реакции нету. Или наоборот, ты уже нажал другую кнопку, а игра всё ещё думает, что нажата предыдущая и человечек вечно бежит не туда. Помню, как в школе, на таких БКшках играл в игру Клад, пройти первый уровень было уже большим достижением.
В общем, я сдаюсь. Пусть кто может - сделает больше.
любую любую (из нажатых, можно случайную)
значит, если эмулируем нажатие не в любой момент, то ничего не меняется
ииии что? еще раз: в промежутке 20мс человек не способен проконтролировать, какая из нескольких клавиш нажмётся первой, так что можно смело выбрать любую
ну и кто мешает их игнорировать?
насколько я понял, бит 6 порта 177716 определяет именно состояние
Прихожу без разрешения, сею смерть и разрушение...
Ещёб. Даже мне приходится прибегать к помощи средств вижуалстудии, чтобы разобраться в той каше, что наворочена за всё это время.
У меня не получается сделать такой цикл. Тот, что используется сейчас мне не нравится, я давно хочу изменить его, но как бы я ни ухищрялся, что бы ни придумывал, всё равно в конце-концов прихожу к тому, с чего начал. К этому же виду цикла.
Звуковые буферы заполняются на лету с заданной частотой дискретизации звука во время исполнения фрейма. Потом по мере заполнения буфера, он отправляется на звучание. Если сделать звуковой буфер длиной 40мс, то при работе эмулятора получается чудовищное отставание звука в 40мс. Даже отставание в 20мс заметно. Поэтому всю работу с выводом звука на устройство я взял из BKBTL, с небольшой модификацией. Дополнительно фрейм разбивается ещё на 4 части. Т.е. звуковой фрейм на самом деле ещё в 4 раза меньше процессорного.
Lethargeek, а напишите какой-нибудь тестовый проект, который покажет преимущества вашего метода. Просто окошко с кнопками старт/стоп, цикл выполнения фреймов, и заглушку процессора в виде конечного автомата, каждый этап которого - одна команда с каким-либо временем исполнения, который будет просто фиксировать наличие/отсутствие факта нажатия на клавиатуру в какой-нибудь расшаренной переменной и визуализировать это каким-нибудь значком рядом с кнопками старт/стоп.
Возни будет много, результат - не определён.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)