А еще я долго размышлял, как лучше сделать переключения оружия.
Все оружие будет в левой части экрана в квадратиках.
Сперва я думал сделать это спрайтами, но у меня уже занято 4 спрайта. Пришлось бы их размножать, вовремя переключать цвета и т.д.
Потом я подумал, что можно было бы рисовывать оружие попиксельно. Но одна зона для каждого оружия занимает 72 байта, что в сумме дает 576 байт (если не учитывать, что должно быть несколько состояний: оружие доступно/оружие выбрано/оружие недоступно).
Поэтому самый оптимальным решением я вижу банальную смену цветов в знакоместах.
Например:
серый/серый - оружие недоступно;
игрок подбирает оружие - меняем на белый/белый - оружие доступно;
игрок выбирает оружие - меняем на синий/красный - оружие выбрано.
Это позволит моментально выбирать нужное оружие и переключать его отображение в HUD без изменения пикселей.
Все оружие будет в левой части экрана в квадратиках.
Сперва я думал сделать это спрайтами, но у меня уже занято 4 спрайта. Пришлось бы их размножать, вовремя переключать цвета и т.д.
Потом я подумал, что можно было бы рисовывать оружие попиксельно. Но одна зона для каждого оружия занимает 72 байта, что в сумме дает 576 байт (если не учитывать, что должно быть несколько состояний: оружие доступно/оружие выбрано/оружие недоступно).
Поэтому самый оптимальным решением я вижу банальную смену цветов в знакоместах.
Например:
серый/серый - оружие недоступно;
игрок подбирает оружие - меняем на белый/белый - оружие доступно;
игрок выбирает оружие - меняем на синий/красный - оружие выбрано.
Это позволит моментально выбирать нужное оружие и переключать его отображение в HUD без изменения пикселей.
🔥3
Сегодня я написал генератор случайных чисел.
Нууу.. как написал. Скорее спер отсюда:
https://codebase64.org/doku.php?id=base:ax_tinyrand8
Единственное, что я поменял - это процесс генерации зерна. Вместо того, чтобы брать значение из регистра A (аккумулятор) для последующей генерации, я взял значения таймера.
Нижний байт таймера лежит в регистре $dc04, а верхний - в регистре $dc05. Банальным XOR этих двух чисел получаем нужное зерно.
А дальше сделал все по инструкции и проверил на 27 тысячах итераций. Паттернов как будто особо не видно, да и вероятностное распределение по полученным числам тоже в пределах нормы.
Есть и второй вариант, и он довольно специфический.
Дело в том, что в Commodore есть звуковой чип, и один из каналов этого чипа умеет генерировать шумы. А шумы - это ничто иное, как псевдослучайные числа. Но такой подход я использовать не хочу, все таки звуковой канал есть звуковой канал.
Нууу.. как написал. Скорее спер отсюда:
https://codebase64.org/doku.php?id=base:ax_tinyrand8
Единственное, что я поменял - это процесс генерации зерна. Вместо того, чтобы брать значение из регистра A (аккумулятор) для последующей генерации, я взял значения таймера.
Нижний байт таймера лежит в регистре $dc04, а верхний - в регистре $dc05. Банальным XOR этих двух чисел получаем нужное зерно.
А дальше сделал все по инструкции и проверил на 27 тысячах итераций. Паттернов как будто особо не видно, да и вероятностное распределение по полученным числам тоже в пределах нормы.
Есть и второй вариант, и он довольно специфический.
Дело в том, что в Commodore есть звуковой чип, и один из каналов этого чипа умеет генерировать шумы. А шумы - это ничто иное, как псевдослучайные числа. Но такой подход я использовать не хочу, все таки звуковой канал есть звуковой канал.
🔥4
Продолжаю описывать всякие полезные для будущей ролевой системы функции.
И сейчас написал функцию для конвертации бинарных значений в так называемое Binary Coded Decimal (BCD).
BCD - это довольно полезная штука, например, для вывода на экран числовых значений.
В стандартном виде числа хранятся в одном байте памяти в диапазоне $00 — $FF в шестнадцатеричной системе, то есть от 0 до 255 в десятичной. А BCD позволяет представить десятичные числа в шестнадцатеричном формате.
Для этого один байт надо разбить на две части по 4 бита: 0000 0000.
4 бита могут хранить значения от 0 до 15 (то есть от $00 до $0F). Но в десятичной системе нет цифр A,B,C,D,E,F, поэтому нужно ограничиться значениями от 0 до 9 на каждые 4 бита.
Например, при использовании BCD значение $87 будет непосредственно равно 87, а не 135, как в шестнадцатеричной системе.
И как удобно, что процессор 6502 поддерживает такой формат чисел на аппаратном уровне.
Для того, чтобы процессор считал в десятичном формате надо поставить флаг D (decimal) в регистре статусов. например, чтобы сложить два числа, надо сделать так:
На выходе в регистре A будет значение $69
И сейчас написал функцию для конвертации бинарных значений в так называемое Binary Coded Decimal (BCD).
BCD - это довольно полезная штука, например, для вывода на экран числовых значений.
В стандартном виде числа хранятся в одном байте памяти в диапазоне $00 — $FF в шестнадцатеричной системе, то есть от 0 до 255 в десятичной. А BCD позволяет представить десятичные числа в шестнадцатеричном формате.
Для этого один байт надо разбить на две части по 4 бита: 0000 0000.
4 бита могут хранить значения от 0 до 15 (то есть от $00 до $0F). Но в десятичной системе нет цифр A,B,C,D,E,F, поэтому нужно ограничиться значениями от 0 до 9 на каждые 4 бита.
Например, при использовании BCD значение $87 будет непосредственно равно 87, а не 135, как в шестнадцатеричной системе.
И как удобно, что процессор 6502 поддерживает такой формат чисел на аппаратном уровне.
Для того, чтобы процессор считал в десятичном формате надо поставить флаг D (decimal) в регистре статусов. например, чтобы сложить два числа, надо сделать так:
sed ; выставляем флаг
clc
lda #$49
adc #$20
cld ; убираем флаг
На выходе в регистре A будет значение $69
👍3🔥1
И возникает закономерный вопрос: А почему бы не хранить в таком виде все значения?
Во-первых, в одном байте в таком случае можно хранить всего до 100 значений: от $00 до $99.
Во-вторых, процессор 6502 в таком режиме может только вычитать и складывать числа. Все другие операции будут производиться в обычном двоичном формате.
Например, для увеличения адреса на 1, я уже не могу сделать так:
Вместо этого придется делать что-то такое:
Это не очень удобно.
Зато очень удобно выводить числа на экран. Числа в экранной памяти кодируются значениями от $30 до $39. Просто прибавляем BCD значение (левую и правую части байта) к $30 и выводим на экран нужную цифру.
Поэтому я и решил написать функцию, которая конвертирует бинарные числа в BCD.
Во-первых, в одном байте в таком случае можно хранить всего до 100 значений: от $00 до $99.
Во-вторых, процессор 6502 в таком режиме может только вычитать и складывать числа. Все другие операции будут производиться в обычном двоичном формате.
Например, для увеличения адреса на 1, я уже не могу сделать так:
inc $nnnn
Вместо этого придется делать что-то такое:
sed
clc
lda $nnnn
adc #$01
sta $nnnn
cld
Это не очень удобно.
Зато очень удобно выводить числа на экран. Числа в экранной памяти кодируются значениями от $30 до $39. Просто прибавляем BCD значение (левую и правую части байта) к $30 и выводим на экран нужную цифру.
Поэтому я и решил написать функцию, которая конвертирует бинарные числа в BCD.
Получилось что-то такое:
В аккумуляторе хранится двоичное число, например $1000 1001 (136 в десятичной)
Сдвигаем все биты влево в цикле. И каждый бит при этом попадает в carry (флаг переноса).
Если carry равен 1, то надо просто прибавить к результату соответствующий разряд:
0 бит — 1
1 бит — 2
2 бит — 4
3 бит — 8
4 бит — 16
5 бит — 32
6 бит — 64
7 бит — 128
В итоге, полученное число окажется в адресах результата:
decimal_result — $01
decimal_result+1 — $36
И эти значения можно уже без проблем вывести на экран
binary_to_bcd_converter
pha
lda #0
sta decimal_result
sta decimal_result+1
sed
ldx #8
@dec_loop
pla
dex
bmi @end
asl
pha
bcc @dec_loop
clc
lda decimal_result+1
adc decimal_tb_lo,x
sta decimal_result+1
lda decimal_result
adc decimal_tb_hi,x
sta decimal_result
jmp @dec_loop
@end
cld
rts
decimal_result
byte $00,$00
decimal_tb_lo
byte $01,$02,$04,$08,$16,$32,$64,$28
decimal_tb_hi
byte $00,$00,$00,$00,$00,$00,$00,$01
В аккумуляторе хранится двоичное число, например $1000 1001 (136 в десятичной)
Сдвигаем все биты влево в цикле. И каждый бит при этом попадает в carry (флаг переноса).
Если carry равен 1, то надо просто прибавить к результату соответствующий разряд:
0 бит — 1
1 бит — 2
2 бит — 4
3 бит — 8
4 бит — 16
5 бит — 32
6 бит — 64
7 бит — 128
В итоге, полученное число окажется в адресах результата:
decimal_result — $01
decimal_result+1 — $36
И эти значения можно уже без проблем вывести на экран
❤1🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Как-то в последнее время разработка туго идет. Но я сделал случайные встречи с врагами с вероятностью в 10% при каждом движении (при этом, если игрок упирается в стену, то случайная встреча не просчитывается). Враг при этом тоже выбирается случайным образом из четырех доступных на одном уровне.
При столкновении появляется текстовое окно с параметрами противника и его именем.
Ну, в данный момент у меня нарисован только один спрайт, поэтому единственный враг - это компьютер😄 Но главное, что работает=)
При столкновении появляется текстовое окно с параметрами противника и его именем.
Ну, в данный момент у меня нарисован только один спрайт, поэтому единственный враг - это компьютер😄 Но главное, что работает=)
🔥4
Начал рисовать персонажей)
Но сразу же возникла проблема. Из-за того, что все персонажи у меня помещаются в 4 спрайта, то два цвета на каждый спрайт должны быть одинаковыми.
Но можно указать и третий цвет - уникальный для каждого спрайта.
Вот и получается, что я могу:
— сделать высокого персонажа и указать всего 3 цвета (коричневый и телесный - общие, синий - уникальный для каждого спрайта). И у меня не получится, например, сделать штаны другого цвета.
— нарисовать персонажа-карлика (чтобы вся одежда поместилась в два квадрата) и добавить еще один цвет😂
В общем, надо потренироваться рисовать все так, чтобы можно было использовать хотя бы 4 цвета из 6 возможных=)
Но сразу же возникла проблема. Из-за того, что все персонажи у меня помещаются в 4 спрайта, то два цвета на каждый спрайт должны быть одинаковыми.
Но можно указать и третий цвет - уникальный для каждого спрайта.
Вот и получается, что я могу:
— сделать высокого персонажа и указать всего 3 цвета (коричневый и телесный - общие, синий - уникальный для каждого спрайта). И у меня не получится, например, сделать штаны другого цвета.
— нарисовать персонажа-карлика (чтобы вся одежда поместилась в два квадрата) и добавить еще один цвет😂
В общем, надо потренироваться рисовать все так, чтобы можно было использовать хотя бы 4 цвета из 6 возможных=)
Что ж...
Я думал, это будет более устрашающе😅
Но, к сожалению, при текущем подходе можно сделать только так.
Конечно, можно увеличить количество спрайтов, например, до 6.
Сейчас планируется 8 изображений оружия, 6 изображений патронов, аптечка и броня. А это уже 4 Кб.
Прибавляем сюда спрайты на уровне - 8 изображений - 2 Кб.
Очень уж затратны эти спрайты в плане памяти.
Я думал, это будет более устрашающе😅
Но, к сожалению, при текущем подходе можно сделать только так.
Конечно, можно увеличить количество спрайтов, например, до 6.
Сейчас планируется 8 изображений оружия, 6 изображений патронов, аптечка и броня. А это уже 4 Кб.
Прибавляем сюда спрайты на уровне - 8 изображений - 2 Кб.
Очень уж затратны эти спрайты в плане памяти.
🔥3👏1
Так, ну я решил проблему со спрайтами врагов.
Вспомнил, что спрайты в Commodore можно увеличивать в два раза на аппаратном уровне. То есть сами пиксели остаются теми же, но изображение становится больше.
Я включил оставшиеся 4 аппаратных спрайта, выставил им новые координаты и увеличил. Таким образом все объекты на уровне теперь будут маленького размера, а вот враги будут более крупными и устрашающими (если можно так сказать).
Теперь остается надеяться, что мне больше не понадобятся аппаратные спрайты для чего-либо еще, а то придется писать функции для их мультиплексинга (размножения)...
Вспомнил, что спрайты в Commodore можно увеличивать в два раза на аппаратном уровне. То есть сами пиксели остаются теми же, но изображение становится больше.
Я включил оставшиеся 4 аппаратных спрайта, выставил им новые координаты и увеличил. Таким образом все объекты на уровне теперь будут маленького размера, а вот враги будут более крупными и устрашающими (если можно так сказать).
Теперь остается надеяться, что мне больше не понадобятся аппаратные спрайты для чего-либо еще, а то придется писать функции для их мультиплексинга (размножения)...
🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Я так и не нашел софт, который позволял бы правильно выставить цвета для каждого знакоместа при рисовании в режиме Multicolor Bitmap.
Поэтому приходится все делать самому.
Начал писать программу на Python.
На данный момент она позволяет:
— выбрать для каждого знакоместа три цвета (желтый квадрат можно перемещать по холсту и выставлять цвета). Потом добавлю отдельные квадраты, в которых будут отображаться цвета в текущем знакоместе.
— рисовать попиксельно (потом планирую добавить отрисовку линиями, квадратами и т.д.)
— выключать/отключать сетку и квадрат для выбора цвета.
— увеличивать/уменьшать холст и перемещать его.
Ну и конечно нужно будет написать скрипт для сохранения изображения в формат ассемблера
Поэтому приходится все делать самому.
Начал писать программу на Python.
На данный момент она позволяет:
— выбрать для каждого знакоместа три цвета (желтый квадрат можно перемещать по холсту и выставлять цвета). Потом добавлю отдельные квадраты, в которых будут отображаться цвета в текущем знакоместе.
— рисовать попиксельно (потом планирую добавить отрисовку линиями, квадратами и т.д.)
— выключать/отключать сетку и квадрат для выбора цвета.
— увеличивать/уменьшать холст и перемещать его.
Ну и конечно нужно будет написать скрипт для сохранения изображения в формат ассемблера
🔥2❤🔥1
В общем, основные функции редактора уже готовы.
Можно выбрать для каждого знакоместа три цвета (при этом можно копировать цвета из одного знакоместа в другой). Каждый цвет выставляется левой, правой и средней кнопками мыши.
Ну и написал функции для сохранения изображения в JSON, загрузки из JSON и импорта в формат ассемблера.
И вроде все работает.
Не скажу, что рисовать по одному пикселю очень удобно, но зато не приходится вручную выставлять цвета для 2000 байт и пиксели для 8000 байт=)
Возможно потом напишу функции для отрисовки линями, квадратами и для заливки
Можно выбрать для каждого знакоместа три цвета (при этом можно копировать цвета из одного знакоместа в другой). Каждый цвет выставляется левой, правой и средней кнопками мыши.
Ну и написал функции для сохранения изображения в JSON, загрузки из JSON и импорта в формат ассемблера.
И вроде все работает.
Не скажу, что рисовать по одному пикселю очень удобно, но зато не приходится вручную выставлять цвета для 2000 байт и пиксели для 8000 байт=)
Возможно потом напишу функции для отрисовки линями, квадратами и для заливки
🔥3❤🔥1
Вот это очень хорошо)
Были идеи что-то такое сделать, но я так и не постиг процессорную магию
Были идеи что-то такое сделать, но я так и не постиг процессорную магию
❤🔥1
Forwarded from Limowski' Precious Little Life (Limows 0xDD)
YouTube
I built my own 16-Bit CPU in Excel
To try everything Brilliant has to offer—free—for a full 30 days, visit https://brilliant.org/Inkbox. The first 200 of you will get 20% off Brilliant’s annual premium subscription.
I designed my own 16-Bit Computer in Microsoft Excel without using Visual…
I designed my own 16-Bit Computer in Microsoft Excel without using Visual…
This media is not supported in your browser
VIEW IN TELEGRAM
Начал добавлять в игру оружие.
Пока готовы только три штуки: газовый ключ, пистолет и нейлер.
Если оружие недоступно, то отрисовывется его силуэт. А если игрок подобрал оружие, то иконка становится цветной.
Выбирать оружие можно только в бою, и при этом окантовка иконки меняет цвет (а в память загружаются параметры нового оружия).
Ну и из мелочей:
Полностью дописал скрипт для конвертации карты из Tiled. Теперь он сохраняет не только триггеры и саму карту, но и спрайты
Разработка стала немного нестабильной.
Из-за того, что все сейчас связано друг с другом: оружие, битвы, враги и т.д., то приходится одновременно писать все везде и сразу=)
Пока готовы только три штуки: газовый ключ, пистолет и нейлер.
Если оружие недоступно, то отрисовывется его силуэт. А если игрок подобрал оружие, то иконка становится цветной.
Выбирать оружие можно только в бою, и при этом окантовка иконки меняет цвет (а в память загружаются параметры нового оружия).
Ну и из мелочей:
Полностью дописал скрипт для конвертации карты из Tiled. Теперь он сохраняет не только триггеры и саму карту, но и спрайты
Разработка стала немного нестабильной.
Из-за того, что все сейчас связано друг с другом: оружие, битвы, враги и т.д., то приходится одновременно писать все везде и сразу=)
🔥4❤🔥1