Умные люди плавучку уже выцепили (синтаксис z80). В принципе и в дизассембере 2.5 (синтаксис 8080), который я выкладывал примерно оно, но тут причесано и с комментариями.
Вид для печати
Умные люди плавучку уже выцепили (синтаксис z80). В принципе и в дизассембере 2.5 (синтаксис 8080), который я выкладывал примерно оно, но тут причесано и с комментариями.
В целом то что задумал сделать похоже получается (хотя и со скрипом, я думал на Бейсике быстрее будет, но оказалось при незнании тонкостей Бейсика на Вектор можно подолгу застрять на всякой ерунде) - т.е. сделать что-нибудь необычное-интересное используя только штатные команды Бейсика. Возможно и будут вставки машинных кодов, но пока надеюсь без них обойтись. Однако встречаются моменты, которые я не знаю пока как можно решить, например:
1. Команда INKEY¤ оказывается сохраняет нажатые клавиши в некий буфер и соответственно когда игрок нажимает клавишу например ВПРАВО то всё время пока она нажата код этой клавиши пишется в буфер - это приводит к тому что когда игрок нажимает ВЛЕВО то персонаж попрежнему бежит ВПРАВО т.к. INKEY¤ выдаёт из буфера всё что накопилось до этого, поэтому актуально поменять направление не получается.
Конечно с таким управлением невозможно нормально играть.
На данный момент я решил использовать такой подход
1100 V=ASC(INKEY¤):IF V<>255 THEN 1100
таким образом "выкачивается"-обнуляется буфер перед тем как начнётся новый опрос клавиатуры.
Это немного помогает, но всё равно хочется чего-то получше.
Есть ли способ побороть эту проблему с помощью команд Бейсика ?
Например я подумал что вероятно через команду PEEK можно где-то в памяти прочитать именно то какая клавиша СЕЙЧАС нажата. Кто-нибудь знает адресс этой ячейки ?
2. По замыслу проекта главный герой должен улететь на ракете в космос. И тут без аппаратного скрола не обойтись. Возможно команда POKE по адресу ячеки скроллинга будет решением. Кто-нибудь знает адресс этой ячейки ?
Если ограничиться командами бейсика, то есть два частичных решения:
1. Опрашивать клавиши СС и РУС/ЛАТ с использованием INP(1). Еще там клавиша УС, но, насколько помню, она приостановит выполнение программы.
2. Опрашивать джойстик (тоже INP).
В детстве я для себя радикально решил эту проблему машиннокодовой вставкой.
Ячейки бейсика описаны в vector-user 1 (сдвиг экрана - 771). Еще кажется в информационной бейсиковской программе, но тут надо уточнить.
С INKEY$ Бейсика не получается нормально читать клавиатуру.
Пришлось машинный код использовать. Однако программа виснет.
Вот код Бейсика:
4 HIMEM &7FF0
5 RESTORE 900 : REM ЗАГРУЗКА МАШИННЫХ КОДОВ
6 AD=&7FF1
7 FOR I=1 TO 9
8 READ B:POKE AD,B:AD=AD+1
9 NEXT I
..................
215 V=USR(&7FF1): REM ОПРОС КЛАВИАТУРЫ
220 IF V=239 THEN RX=RX-1:GOTO 250
221 IF V=191 THEN RX=RX+1:GOTO 250
222 IF V=223 THEN RY=RY-1:GOTO 266
223 IF V=127 THEN RY=RY+1:GOTO 266
.................
900 DATA &F3,&3E,&FE,&D3,&03,&DB,&02,&FB,&C9
Это код подпрограммы (которая прописана в строке 900)
F3 DI
3E FE MVI A,0FEH ; ПРОВЕРКА НАЖАТИЯ НА КЛАВИШИ ИГРОВОГО РЯДА.
D3 03 OUT 03
DB 02 IN 02
FB EI
C9 RET
Насколько я понял (прочитал) в переменную V заносится значение аккумулятора при выходе из подпрограммы по USR.
Что не так с моей подпрограммой ?
Нужно опрашивать клавиатуру с привязкой к прерыванию и задавать режим ВВ55. Можно например как в baskeys - один раз внедряемся в прерывание и потом берем коды клавиш из 7FF8 (курсор) и 7FF9 (пробел и компания)
metamorpho, На векторе нельзя так просто взять и опросить клавиатуру, т.к. порты клавиатуры по совместительству еще являются портами видеоконтроллера (отвечают за скролинг и цвет палитры), поэтому опрос клавы приведет к артифактам на экране. клаву опрашивают во время обратного хода луча т.е. в обработчике прерывания, к тому же порт B ВВ55 на время опроса клавы надо переключать направление порта, а потом возвращать в прежнее состояние.
Запускаю baskeys она выдаёт мерцающие точки и тире-артефакты и перестаёт реагировать на клавишу F12 (похоже виснет).
..................
......................... прошло несколько минут
А нет ВСЁ РАБОТАЕТ - настроил (вставил задержку между выводом print и палитру немного поменял) вроде как.
Интересно, что проблему выявил только VV (в v06x-godot не так просто попробовать, а в emu и emu80 было нормально). Надеюсь исправленный вариант будет нормально работать везде.
- - - Добавлено - - -
Забыл дополнить, что адреса для PEEK сдвинулись - 7FFC и 7FFD
Upd: поправил проверку повторного запуска
Upd 01.03.2023: добавил архив с BAS и TXT полученными конверсией в Vector06CBasic.exe
ivagor, спасибо !!
Да я использую VV.
Теперь управление более менее играбельное. Хотя скорости не хватает (для разнообразия переключаю на 12 Мгц и всё летает :) )
Заметил интересную особенность baskeys - после первого запуска всё работает, потом нажимаю F12 и снова RUN и на втором запуске программа красиво (из эффекта зависания можно делать демку :) ) виснет.
Забыл, что после доработки сместились не только ячейки с данными клавиатуры, но и адрес команды перехода. Проверку в строке 25 исправил
- - - Добавлено - - -
Кстати, кроме отсутствия буферизации дополнительная фича - возможность опрашивать несколько клавиш одновременно, правда тут надо аккуратно, в байте писали про ограничения реала.
В обсуждении BASCOM не хватало цифр, для примера Мандельброт ускоряется компилятором примерно в 3 раза.
Краткая история моих пробований:
1. Конверснул baskeys.txt в baskeys.bas с использованием Vector06CBasic.exe. Попробовал загрузить в v06x_3-theydo-win64, там в комплекте шли скрипты и все что нужно. Файл при загрузке выдал ошибку, там что-то не то с последней строкой. Кто виноват - Vector06CBasic или скрипты я не разбирался.
2. Попробовал конверснуть baskeys.txt в baskeys.bas с использованием bas2asc.py. Выдает какую-то ошибку, подробно не разбирался (все же конверсии в cas в других эмуляторах запускались). Возможно стоило взять для конверсии последний exe.
3. Можно было еще записать .bas на образ дискеты и запустить дисковым бейсиком, но это я не пробовал.
Проще всего для пользователя было бы перехватывать cload или bload в бейсике. Если это сложно для реализации, то хотя бы приложить набор скриптов, как в v06x_3-theydo-win64 (но тут еще надо разобраться с конверсией в bas, по крайней мере это касается лично меня и baskeys)
Спасибо за подробный список проблем! Похоже тут потребуется работа мысли, может быть даже неоднократная.
Записал baskeys.bas изготовленный с использованием Vector06CBasic на образ fdd и попробовал в v06x-godot-8 - работает.
Могу выложить, но наверно уже не надо, я понял, на чем спотыкался bas2asc. Vector06CBasic.exe при сохранении в txt добавляет в начале байты EF BB BF. Если их удалить, то bas2asc нормально конвертит txt->bas (в cas не пробовал, но наверняка тоже нормально). txt (и bas) я не выкладывал, т.к. думал, что конвертером из cas можно получить и bas и txt. И это правда, но, как оказалось, есть нюанс.
Ставлю эксперименты - пытаясь найти самый быстрый вариант вывода уровня на экран.
Протестировал три следующих варианта:
вариант_1 = вывод спрайта 8Х8 используя рисование прямоугольника с маской (в одну плоскость)
вариант_2 = вывод спрайта 8Х8 используя прямую запись в экран через POKE (в одну плоскость)
вариант_3 = вывод спрайта 8Х8 используя подпрограмму в машинных кодах и её вызов через USR (в одну плоскость)
Оказалось что все три варианта практически почти равны по скорости - все работают медленно.
Пробовал отключать строку 103 - во всех вариантах это ничего не меняло в скорости.
Думал второй вариант будет быстрее первого, т.к. прямая запись в экран без лишних команд, но увы.
Далее возлагал надежды на вариант третий поскольку машинные коды используются, но к удивлению
тормоза такие же, я так предполагаю сам вызов USR в Бейсике громоздкий. Выходит если подпрограмма в
машинном коде очень короткая в смысле в отношении графики вывод 8х8 точек, то выгоды при использовании USR, от неё нет.
Вывод пока такой - либо продолжать делать без машинных кодов и принять тормоза как есть.
Либо переходить на более объёмные машинные коды, но тогда кажется потеряется смысл написания программы в Бейсике.
90 REM --------- программа вывода уровня на экран
98 CLS:FAN=2:RESTORE 650
вариант_1 99 XT=0:YT=248
вариант_2 99 BD=33015:CD=BD
вариант_3 99 BD=128:TY=247:CD=BD
100 FOR I=0 TO 31
102 FOR J=0 TO 31
103 READ A:GROT(J,I)=A
106 IF A=0 THEN GOTO 201: REM ----------- ПУСТО
вариант_1 107 IF A=1 THEN SCREEN 2,8:COLOR 8:SCREEN 3,0,239,239,239,0,254,254,254:GOTO 200:REM СТЕНА
вариант_2 107 IF A=1 THEN POKE BD,0,239,239,239,0,254,254,254:GOTO 201: REM СТЕНА
вариант_3 107 IF A=1 THEN POKE 32578,TY:POKE 32579,BD:KB=USR(&7F40):GOTO 201: REM СТЕНА
200 PLOT XT,YT,2:LINE STEP 7,7,BF: REM --- РИСУЕМ ЭЛЕМЕНТЫ SCREEN 2,15:
вариант_1 201 XT=XT+8
вариант_2 201 BD=BD+256
вариант_3 201 BD=BD+1
204 NEXT J
вариант_1 205 XT=0:YT=YT-8
вариант_2 205 BD=CD:BD=BD-8:CD=BD
вариант_3 205 BD=CD:TY=TY-8
206 NEXT I
Все таки программа на бейсике должна быть на бейсике, а не в машинных кодах, иначе теряется весь ее смысл, исключение может быть разве что опрос клавиатуры ибо по другому ни как. И весь челендж как раз сделать быстро (на сколько возможно) именно операторами бейсика.
После того, как разобрался с конверсией txt->bas с использованием bas2asc оставался последний вопрос
Тот bas, который делает bas2asc нормально грузится скриптом в v06x_3-theydo-win64. Единственная разница, которую вижу в basах bas2asc и Vector06CBasic - bas2asc добавляет больше нулей. Не разбирался, как работает загрузочный скрипт v06x, вероятно он ожидает, что 3 нуля в конце программы будут в составе bas (и это пожалуй правильно), а Vector06CBasic этого не обеспечивает.
metamorpho, немного бустануть программу можно используя basic 2.62
2.62 даст проценты ускорения, на глаз незаметно.
Если оставаясь в рамках бейсика говорить например о рисовании лабиринта 32x32, то быстрее сделать можно, но быстро все равно не будет. Если разных видов тайлов немного, например 4, то можно объединить их по 2 и сделать 16 вариантов рисования. При выводе с использованием POKE удобно объединить 2 по вертикали, если тайлы одинаковые, то можно нарисовать 2 одним POKE.
В детстве я проходил этот путь когда делал редактор спрайтов и "мегаигру". Постепенно перекладывал медленные операции на машиннокодовые процедуры, в частности и рисование уровня. Редактор в принципе и на бейсике+коды получился нормально, а вот игру надо было полностью перевести на ассемблер. Это было возможно, но проблема была с графикой и анимацией главного героя, красиво или хотя бы приемлемо у меня не получалось.
- - - Добавлено - - -
2.62 более ценен тем, что там исправлены известные баги.
Я деталей тоже не помню, но bas25hook.chai дописывает 0 0 0 d3 d3 d3 0 в конец виртуального .cas-файла перед контрольной суммой.
@metamorpho а есть где-то текст твоей программы целиком, чтобы запустить?
Оишбся, не в конец, а после имени. Три нуля подряд интерпретируются как признак конца bas-файла. Видимо ты клонишь к тому, что если в конце .bas файла не нашлось трех нулей, их стоит додумать. Это можно сделать, просто мне не встречалось таких bas-файлов раньше. Пришли плс.
Добавил архив с BAS и TXT.
BAS, насколько я понимаю, был в свое время форматом для хранения на дискетах, поэтому контрольная сумма там не требовалась. На тему тонкостей BAS надо бы посмотреть BT.COM от авторов вектора.
Спасибо, пока я не добрался сделать чего-то полноценно, можно вставить
в bas25hook.chai в строке 59. И тогда твой .bas загружается.Код:for (var i = zeroseq; i > 0; --i) {
this.cas.push_back(0)
}
cs &= 0xffff // это было
В bas файлах контрольной суммы нет, это все про cas.
Ещё протестировал вариант вывода графики уровня с командой PUT, скорость тоже медленная.
Прежде чем выводить через PUT нужно резервировать массив (- память), потом нарисовать спрайт (- память) и потом
запоминать это в GET и только потом использовать PUT. Минусы - затраты памяти и много лишних движений.
Над плюсами ещё думаю есть ли они.
Запускал программу в Бейсик 2.62 - если мерить строго на глаз то ощущение что есть небольшой прирост скорости, но
в целом всё так же медленно.
Вариант с машинными кодами - решил не использовать (кроме опроса клавиатуры), чтобы было чисто на Бейсике.
Сейчас решаю какой вариант из оставшихся трёх выбрать - возможно будет комбинированное решение.
Пока что нигде нету. После завершения проекта выложу здесь.
Скорее всего в этой игре будет один уровень в конце которого главный герой на чём-то куда-то улетает.
Этот проект задумывался мной как небольшое исследование и как результат демонстрация того какие можно было делать игры чисто на Бейсике с использованием некоторых специфичных моментов Вектора.
....и вот что получается - нарисовал с помощью LINE ракету и вылетает надпись "памяти больше нет". Как так нет, я же "почти" ничего ещё не рисовал :)
Однако быстро память кончилась, а я не успел внедрить и половины того что хотел. Придётся ужимать код программы и использовать другой вариант вывода персонажа игры (сейчас он через ресурсоёмкий PUT выводится).
Игра и на базовом этапе (уровень и человечек бегает - типа LodeRunner) была довольно медленная, а с прибавлением каждого нового элемента скорость падает уже до неиграбельности. Однако меня подкупает включение режима 12Мгц - всё прекрасно летает и парит (может сделаю настройки под режим 12Мгц). Вообщем хочется ещё немного поэксперементировать с некоторыми идеями, но уже сейчас понятно что на стандартном режиме 3Мгц на Бейсике мало что можно выжать в отношении скорости.
На данный момент в ходе экспериментов с Бейсиком удалось реализовать идею (она конечно не новая, но думаю немного в новой форме) анимации различных объектов (в основном статичных) с помощью программирования палитры. Т.е. можно хоть весь экран привести в движение без особых нагрузок на процессор, всё что нужно сделать это заранее правильно нарисовать графику, а потом в ходе игрового цикла менять только палитру.
Есть ещё идея сделать скроллинг уровня вверх-вниз, но это наверное совсем уничтожит скорость игры :)
Хотя на 12Мгц думаю всё будет неплохо работать.
Вообщем процесс создания пока продолжается, но память в Бейсике всё же коротка и сколько не ужимай программу довольно скоро упрёшься в потолок - а значит скоро (наверное) будет выдан результат моих экспериментов :)
С нехваткой памяти можно бороться несколькими способами:
1. Отключать плоскости, но что-то мне подсказывает, что в данном случае этот вариант не подойдет.
2. Более экономно хранить данные
2.1. Разделить программу на основной блок (загружаем по cload"") и блок данных, подгружаемый по bload"".
2.2. Компромиссный вариант - упаковывать данные в строки после REM и читать оттуда по PEEK.
А что если использовать бейсик для ПК-6128ц, там, вроде, памяти под программу можно больше выделить? Или тут вопрос "спортивного интереса", запустить игру именно на Векторе?
Мне неприятно быть негативным занудой, но вижу тут противоречие: игра для вектора, но для нормальной работы нужно 12 МГц. Стоить подумать над радикальным изменением игрового процесса, пусть графика будет попроще и движения поменьше, но хотя бы как-то приемлемо играется. Повторю свое мнение - нормальные динамические игры на basic 2.5 невозможны. Еще вариант - на бейсике сделать что-то очень-очень упрощенное, а на ассемблере полную версию.
----Да не, 12Мгц это не требование к игре, это скорее всего видение того "как бы это работало на ассемблере".
Этот проект задумывался мной как небольшое исследование и эксперимент и как результат выйдет демонстрация того что получилось именно на Бейсике с использованием некоторых специфичных моментов Вектора.
А конструктивные предложения и критика всегда приветствуются :)
-- Да тут и так всё самое простое (наверное) - никакой особой динамики нет. Тут даже врагов движущихся нет. Всё это чисто эксперимент.
-- В этом и была одна из целей этого эксперимента - проверить идею - проверил - она оказалась рабочей.
Далее эту идею можно будет использовать в игре на ассемблере (если таковая будет). Но идея пока что захватывает - программируемая палитра - это может быть мощно и многогранно.
Тут важны границы этой нормальности, как мы их понимаем. Вообще, может мои воспоминания о бейсике рафинировались за долгие годы, но я помню, что на бейсике тоже были динамические игры, в некоторых главный герой игры вырождался в один пиксель для скорости перемещения, в других применялись ассемблерные вставки ("Торпедная атака", например), даже змейки-питоны были всякие, достаточно динамичные ( в том числе и самописные :)), а в некоторых играх обновление картинки раз в секунду не считалось криминалом -- всё зависит от сюжета и фантазии. Да и вспомните те годы, тогда даже минутная отрисовка заставки игры, или того же крокодила в "рекламе" бейсика, была чем-то вроде компьютерной магии, а не признаком тормозов. Да куда уж там, даже на МК-61 играли в динамические игры. В общем, если не ставить современные требования по графике, то динамику на бейсике тоже можно сочинить, я думаю. А насколько они будут нормальные -- это всё субъективно.
Да, критерии качества в данном случае субъективны и вероятно у меня планка слишком высоко.
Хороший пример - ассемблер используется, а толку (на мой взгляд) мало, играбельность очень низкая.
В детстве делал и своего питона на бейсике и тогда он мне казался нормальным. Но если сейчас оглянуться, то там не было никакого запаса быстродействия. Помню шустрого питона как бы на бейсике (публиковали в Радиолюбителе) - так там основной игровой цикл ассемблерной вставкой.
Если картинка красивая, то я готов и минуту подождать. Готов подождать, когда логическая игрушка думает над ответным ходом. А когда игра с невероятными тормозами реагирует на нажатия клавиш - вот это для меня неприемлемо.
Глянь игру "Искатель Алмазов" (Радиолюбитель 04-06 1994г) на бейсике, там тоже все очень медленно. Как тут предлагали уже урезается память для экрана в пользу памяти программы.
ПЗУшный бейсик 6128 не позволяет прозрачно использовать 16-цветную графику, если бейсиковская программа залезает за 8000h. Basic48k для 6128 позволяет, но есть техническая возможность сделать аналогичный бейсик и для 06Ц с квазом Баркаря.
ivagor, по большому счёту, уже почти назрела такая необходимость. Думаю, оптимальным для разработки был бы вариант одного универсального бейсика с автодетектом оборудования, т.е. при старте проверяется, если есть память 6128 -- используем её, если есть КД баркаря -- то его... А нет ни того, ни другого -- будет просто бейсик 2.62. :)
"Единый самонастраивающийся бейсик" удобнее для использования, но в нем пришлось бы пойти на компромиссы. Например в Basic48k для ускорения и сокращения немного используются недокументированные команды 8085, в унифицированном варианте проще было бы от них отказаться. На мой взгляд необходимость в бейсике48 для 06Ц назреет тогда, когда появится хотя бы одна программа для него (написать и отладить можно и в варианте для 6128).
Более нужная вещь - run262 или basd262 для запуска с диска. С самого начала собирался, пока так и не собрался.
Ну а самым интересным был бы компилятор для 2.5, но мне сложновато.