Сегодня особо похвастаться нечем.
Я немного оптимизировал процесс отрисовки.
Для этого пришлось пожертвовать 1000 байт памяти. Если раньше у меня предрасчитанные значения индекса текстур лежали в одном байте попарно (от 0 до 15), то сейчас я их распределил по одному байту для каждого значения. Из-за этого теперь не приходится делать лишние операции сдвига.
Во-вторых, переписал функцию отрисовки пикселя на экране.
Раньше я брал первый блок строки и прибавлял к нему смещение по Y. Но сейчас я считаю блоки построчно, и к ним прибавляю индекс по Х. Получается без лишних 16 битных сложений.
Но все равно медленно!
Я немного оптимизировал процесс отрисовки.
Для этого пришлось пожертвовать 1000 байт памяти. Если раньше у меня предрасчитанные значения индекса текстур лежали в одном байте попарно (от 0 до 15), то сейчас я их распределил по одному байту для каждого значения. Из-за этого теперь не приходится делать лишние операции сдвига.
Во-вторых, переписал функцию отрисовки пикселя на экране.
Раньше я брал первый блок строки и прибавлял к нему смещение по Y. Но сейчас я считаю блоки построчно, и к ним прибавляю индекс по Х. Получается без лишних 16 битных сложений.
Но все равно медленно!
❤🔥1
https://www.youtube.com/watch?v=WZQ1FMWnG9w&t=15s
И вот офигенное видео о том, как устроена память в Commodore 64, и почему BASIC ограничен 38991 байтами
И вот офигенное видео о том, как устроена память в Commodore 64, и почему BASIC ограничен 38991 байтами
YouTube
38911 Bytes Free? Commodore 64's BASIC RAM
The Commodore 64's famous blue-on-blue boot message says "38911 BASIC BYTES FREE". But it's supposedly a 64K RAM system, so where did the rest of the RAM go? Is it a scam? We go through the origin of the name Commodore 64, discuss how 64K of RAM was a pretty…
❤🔥1
За эти выходные просто дофига новостей!
Во-первых, удалось увеличить скорость отрисовки почти на 50%.
И, внезапно, в этом мне помог Кирилл Лейфер. Благодаря ему я и Commodore купил, когда увидел видео про это на его YouTube канале.
Сейчас Кирилл сам делает игру про кота для C64:
https://t.me/paw_noir
Он посмотрел на мой код, кое-где оптимизировал, а потом я сам уже убрал возможность отрисовки "комнаты за комнатой".
Это сильно снижало скорость, а еще могли бы возникнуть конфликты цветов в одном знакоместе при коллоризации.
Во-первых, удалось увеличить скорость отрисовки почти на 50%.
И, внезапно, в этом мне помог Кирилл Лейфер. Благодаря ему я и Commodore купил, когда увидел видео про это на его YouTube канале.
Сейчас Кирилл сам делает игру про кота для C64:
https://t.me/paw_noir
Он посмотрел на мой код, кое-где оптимизировал, а потом я сам уже убрал возможность отрисовки "комнаты за комнатой".
Это сильно снижало скорость, а еще могли бы возникнуть конфликты цветов в одном знакоместе при коллоризации.
Telegram
Paw Noir C64 devlog
Кирилл и Тимофей портируют игру про котика на Commodore 64
❤🔥1
Во-вторых, я написал собственно функцию для колоризации.
В текстуре один пиксель может принимать значения: 01, 10, 11, 00.
11 - это цвет из Color RAM (1000 байт в одном месте памяти). Он у меня везде одинаковый - тёмно-серый.
00 - это цвет фона - черный.
А вот 10 и 01 могут быть любыми цветами, которые я помещу в третье место (еще 1000 байт в другом месте в памяти).
То есть текстура - это лишь набор ссылок на другие регистры.
Цветовую палитру для каждой текстуры пришлось хранить отдельно от самих текстур. Но таким образом цвета можно менять налету
В текстуре один пиксель может принимать значения: 01, 10, 11, 00.
11 - это цвет из Color RAM (1000 байт в одном месте памяти). Он у меня везде одинаковый - тёмно-серый.
00 - это цвет фона - черный.
А вот 10 и 01 могут быть любыми цветами, которые я помещу в третье место (еще 1000 байт в другом месте в памяти).
То есть текстура - это лишь набор ссылок на другие регистры.
Цветовую палитру для каждой текстуры пришлось хранить отдельно от самих текстур. Но таким образом цвета можно менять налету
❤🔥1
И, в-третьих, я добавил буфер экрана. Это лишние 2Кб памяти, в которое сохраняется изображение перед выводом на экран.
Цель у этого всего одна - избавиться от того, что процесс отрисовки виден на экране в реальном времени. Как мне кажется, это довольно сильно раздражает
Цель у этого всего одна - избавиться от того, что процесс отрисовки виден на экране в реальном времени. Как мне кажется, это довольно сильно раздражает
❤🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Сделал вчера игровую карту и функции перемещения (ну почти) и поворота.
При каждом изменении вызывается функция отрисовки экрана, а между этим экран очищается.
И вроде как это смотрится не так уж раздражающе медленно)
А еще в конце можно увидеть, что если зайти за пределы карты, то можно отправиться путешествовать по памяти компа)
При каждом изменении вызывается функция отрисовки экрана, а между этим экран очищается.
И вроде как это смотрится не так уж раздражающе медленно)
А еще в конце можно увидеть, что если зайти за пределы карты, то можно отправиться путешествовать по памяти компа)
👍3
Но как это путешествие работает, надо описать:
У игрока есть позиция Y и позиция X, а у каждой строки карты размером 24*24 байта есть свой адрес. Адреса забиты в таблицу указателей на адреса строк.
То есть позиция игрока высчитывается как текущий адрес строки из таблицы со смещением Y + смещение по X.
Если выйти за пределы карты, например позиция игрока станет не 24, а 40, то адрес строки будет равен "адрес начала таблицы + 40", а что хранится в этом месте неизвестно. Это может быть указатель хоть на самую первую страницу памяти.
Зато, если уйти за пределы карты вправо, то игрок перескочит на следующую строку в противоположном конце карты, и наоборот🙈
Думаю, это можно как-нибудь использовать для секретов, главное ничего не сломать:)
У игрока есть позиция Y и позиция X, а у каждой строки карты размером 24*24 байта есть свой адрес. Адреса забиты в таблицу указателей на адреса строк.
То есть позиция игрока высчитывается как текущий адрес строки из таблицы со смещением Y + смещение по X.
Если выйти за пределы карты, например позиция игрока станет не 24, а 40, то адрес строки будет равен "адрес начала таблицы + 40", а что хранится в этом месте неизвестно. Это может быть указатель хоть на самую первую страницу памяти.
Зато, если уйти за пределы карты вправо, то игрок перескочит на следующую строку в противоположном конце карты, и наоборот🙈
Думаю, это можно как-нибудь использовать для секретов, главное ничего не сломать:)
🤡1
This media is not supported in your browser
VIEW IN TELEGRAM
Немного доработал рендеринг. Теперь не требуется очищать полностью экран, а только экранный буфер.
Благодаря этому пропало раздражающее мерцание между кадрами
Благодаря этому пропало раздражающее мерцание между кадрами
😱1
Media is too big
VIEW IN TELEGRAM
Видео-отчет за последние несколько дней безудержного веселья.
Нет, серьезно, мне уже снятся эти байты.
Вчера мне приснилось, что для того, чтобы проснуться, надо поменять значение будильника в регистре памяти.
Я во сне написал программу на ассемблере и спокойно проснулся под будильник🤦♂
Нет, серьезно, мне уже снятся эти байты.
Вчера мне приснилось, что для того, чтобы проснуться, надо поменять значение будильника в регистре памяти.
Я во сне написал программу на ассемблере и спокойно проснулся под будильник🤦♂
😁2
Думаю, как реализовать триггеры.
Пока придумал такую штуку. Каждый триггер будет иметь такие параметры:
Позиция X и Y на карте;
Номер ключа (будет проверяться наличие ключа у игрока);
Флаги Single use и Available.
Первый флаг будет означать, что триггер срабатывает один/бесконечное количество раз и переключает флаг Available в ноль в первом случае.
Второй флаг будет означать, что в данный момент триггер можно/нельзя активировать.
Допустим, я хочу сделать триггер для двери. Так как я отказался от отрисовки "комнаты за комнатой", дверь будет обычным блоком. К этом блоку надо привязать два триггера. Первый будет телепортировать игрока в одну сторону, второй - в другую. К тому же каждый триггер будет Single use (то есть флаг Available будет выставляться в 0) и должен активировать противоположный триггер (флаг Available выставляется в 1).
Получится так:
00000001 - тип триггера "дверь".
00000011 - флаги выставлены в 1.
Два байта - позиция на карте.
Один байт - номер ключа.
Два байта - позиция для телепортации игрока.
Один байт - номер триггера, который нужно будет активировать после телепортации.
Пока что я предполагаю, что на 1 уровне будет как минимум 64 триггера. Один триггер занимает 8 байт, то есть в сумме 512 байт.
Пока придумал такую штуку. Каждый триггер будет иметь такие параметры:
Позиция X и Y на карте;
Номер ключа (будет проверяться наличие ключа у игрока);
Флаги Single use и Available.
Первый флаг будет означать, что триггер срабатывает один/бесконечное количество раз и переключает флаг Available в ноль в первом случае.
Второй флаг будет означать, что в данный момент триггер можно/нельзя активировать.
Допустим, я хочу сделать триггер для двери. Так как я отказался от отрисовки "комнаты за комнатой", дверь будет обычным блоком. К этом блоку надо привязать два триггера. Первый будет телепортировать игрока в одну сторону, второй - в другую. К тому же каждый триггер будет Single use (то есть флаг Available будет выставляться в 0) и должен активировать противоположный триггер (флаг Available выставляется в 1).
Получится так:
00000001 - тип триггера "дверь".
00000011 - флаги выставлены в 1.
Два байта - позиция на карте.
Один байт - номер ключа.
Два байта - позиция для телепортации игрока.
Один байт - номер триггера, который нужно будет активировать после телепортации.
Пока что я предполагаю, что на 1 уровне будет как минимум 64 триггера. Один триггер занимает 8 байт, то есть в сумме 512 байт.
😱1
Планируются такие триггеры:
— Телепортация (односторонняя);
— Дверь (телепортация + активация другого триггера);
— Смена видимости блока (выставляем флаг Textured на блоке в 0 или 1);
— Смена коллизии блока (флаг Solid в 1 или 0);
— Смена текстуры блока (меняется номер текстуры блока от 0 до 15);
— Смена флага Single use триггера (пока не придумал конкретные ситуации, где это можно использовать);
— Смена флага Available триггера (таким образом можно активировать будущие сюжетные триггеры, которые в начале уровне не будут доступны);
— Вывод текста на экран (будет определяться адрес текста в памяти)
— Триггер для смены уровня (тут будет номер следующего уровня, на основе которого уже будут считываться нужные файлы с дискеты. Осталось разобраться, как эти файлы считывать).
Как вариант, можно сделать триггер на смену параметров другого триггера, но конкретные примеры я пока тоже не придумал.
Чувствую. что большинство триггеров я буду придумать по ходу создания уровней для конкретных ситуаций.
— Телепортация (односторонняя);
— Дверь (телепортация + активация другого триггера);
— Смена видимости блока (выставляем флаг Textured на блоке в 0 или 1);
— Смена коллизии блока (флаг Solid в 1 или 0);
— Смена текстуры блока (меняется номер текстуры блока от 0 до 15);
— Смена флага Single use триггера (пока не придумал конкретные ситуации, где это можно использовать);
— Смена флага Available триггера (таким образом можно активировать будущие сюжетные триггеры, которые в начале уровне не будут доступны);
— Вывод текста на экран (будет определяться адрес текста в памяти)
— Триггер для смены уровня (тут будет номер следующего уровня, на основе которого уже будут считываться нужные файлы с дискеты. Осталось разобраться, как эти файлы считывать).
Как вариант, можно сделать триггер на смену параметров другого триггера, но конкретные примеры я пока тоже не придумал.
Чувствую. что большинство триггеров я буду придумать по ходу создания уровней для конкретных ситуаций.
🤡1
Немного о том, как я создаю текстуры для игры=)
Сперва я их рисую в Multipaint - программа, в которой можно рисовать для большого количества старых компьютеров, включая Commodore 64, VIC-20, ZX Spectrum и Amstrad.
Потом я своими руками переношу данные текстур попиксельно в Excel, где уже с помощью формул СЦЕП и ДВ.В.ШЕСТН создаю нужное представление последовательности байт для ассемблера.
Но я уже устал так делать😂 Пора бы что-нибудь на питоне написать для облегчения жизни
Сперва я их рисую в Multipaint - программа, в которой можно рисовать для большого количества старых компьютеров, включая Commodore 64, VIC-20, ZX Spectrum и Amstrad.
Потом я своими руками переношу данные текстур попиксельно в Excel, где уже с помощью формул СЦЕП и ДВ.В.ШЕСТН создаю нужное представление последовательности байт для ассемблера.
Но я уже устал так делать😂 Пора бы что-нибудь на питоне написать для облегчения жизни
❤🔥1
Media is too big
VIEW IN TELEGRAM
Ну и наконец видео-обновление. Перенес все текстуры в игру. Может быть потом еще придумаю, как это дело улучшить:)
🔥2
Раздумываю тут, как лучше сделать ролевую систему. Она должна быть простой - это главное условие.
И опять я обратился к Doom RPG.
Так же как и там я хочу добавить всего 4 параметра:
Attack - сила удара.
Defence - модификатор защиты.
Dexterity - ловкость (шанс уклониться).
Accuracy - точность (шанс попасть).
Плюс у игрока будет уровень здоровья и брони. И вот это все как-то надо совместить и выдать адекватные формулы расчетов при битвах.
Но еще в Doom RPG мне нравилось, что разные враги могут по разному реагировать на разное оружие. То есть, например, зомби очень быстро отлетает от дробовика, но почти не получет урон от автомата.
И я придумал, как довольно просто это сделать.
Всего будет 8 видов оружия, а у каждого монстра 1 байт будет отвечать за флаги подверженности конкретному виду.
Если, например, нулевой бит выставлен в 0, то враг получает пониженный урон от первого оружия. Если бит == 1, то двойной урон.
Ну или как-то так
И опять я обратился к Doom RPG.
Так же как и там я хочу добавить всего 4 параметра:
Attack - сила удара.
Defence - модификатор защиты.
Dexterity - ловкость (шанс уклониться).
Accuracy - точность (шанс попасть).
Плюс у игрока будет уровень здоровья и брони. И вот это все как-то надо совместить и выдать адекватные формулы расчетов при битвах.
Но еще в Doom RPG мне нравилось, что разные враги могут по разному реагировать на разное оружие. То есть, например, зомби очень быстро отлетает от дробовика, но почти не получет урон от автомата.
И я придумал, как довольно просто это сделать.
Всего будет 8 видов оружия, а у каждого монстра 1 байт будет отвечать за флаги подверженности конкретному виду.
Если, например, нулевой бит выставлен в 0, то враг получает пониженный урон от первого оружия. Если бит == 1, то двойной урон.
Ну или как-то так
👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Вышла очень дурацкая ситуация, когда я добавил триггер двери.
На словах это выглядело нормально, но когда дошло до дела, все оказалось иначе.
Дело в том, что у меня триггер прикрепляется к определенному блоку на карте по координатам.
Триггер двери перемещает игрока за дверь и включает второй триггер, который позволит перенести игрока обратно. Так должно было работать.
Но так как оба триггера прикреплены к одному блоку, то функция проверяет их оба в цикле.
Первый триггер срабатывает нормально. Он перемещает игрока и включает второй триггер.
А вот второй триггер перемещает игрока, включает первый триггер. Но тут же в цикле отрабатывает первый триггер, который переключает все обратно😂
Пока что единственное решение, которое я нашел - поставить две двери в ряд.
Второе решение - поставить один триггер на дверь и менять координаты, куда он будет вести.
Третье решение - забить на телепортацию и убирать блок-дверь полностью.
На словах это выглядело нормально, но когда дошло до дела, все оказалось иначе.
Дело в том, что у меня триггер прикрепляется к определенному блоку на карте по координатам.
Триггер двери перемещает игрока за дверь и включает второй триггер, который позволит перенести игрока обратно. Так должно было работать.
Но так как оба триггера прикреплены к одному блоку, то функция проверяет их оба в цикле.
Первый триггер срабатывает нормально. Он перемещает игрока и включает второй триггер.
А вот второй триггер перемещает игрока, включает первый триггер. Но тут же в цикле отрабатывает первый триггер, который переключает все обратно😂
Пока что единственное решение, которое я нашел - поставить две двери в ряд.
Второе решение - поставить один триггер на дверь и менять координаты, куда он будет вести.
Третье решение - забить на телепортацию и убирать блок-дверь полностью.
❤🔥1
Ну и четвертый вариант - забить на триггеры, привязанные к блокам и прикреплять их к граням блока. Но в таком случае придется проверять пересечения отрезков. Но пока неясно, насколько это замедлит работу программы
👍1