Para||elix — платформа демосцены
19 subscribers
14 photos
7 links
Parallelix — demoscene platform for multithreaded native intros
Чат: @parallelix_chat
Автор: @jin_x
Download Telegram
Салют, друзья! 💥
Некоторое время подумываю о создании новой платформы для демосцены. До вчерашнего дня я только размышлял об её особенностях, возможностях, продумывал заголовок (опциональный, но с кучей настроек), некоторые технические нюансы (организацию API, структуру памяти). И вот, наконец, вчера открыл Visual Studio, создал проект и написал немного кода 🙂

💻 Ни для кого не секрет, что помимо аппаратных платформ существуют и искусственно созданные: PICO-8, TIC-80, недавно появившаяся MicroW8 и др.
Каждая платформа имеет ограничения: по разрешению экрана, набору цветов, возможностям воспроизведения звука, производительности, наконец. Ограничения — неотъемлемая часть демосцены. Однако даже мощнейший современный компьютер с видеокартой RTX 4090 тоже имеет ограничения, но конечно, другого уровня, нежели ретрокомпьютеры. Вместе с тем, смотреть 64K или 4K intro на шейдерах не менее интересно, чем демо/интро под ZX Spectrum, написанные на чистом ассемблере Z80, или интро под TIC-80 на Lua. Во всём есть свои фишки, своя романтика и свои челленджи.

Поскольку я любитель Newskool-платформ, ассемблера и Sizecoding'а, моя платформа ориентирована на полноцветный hi-res, максимальную скорость и нативный код x86 под Windows. А ещё я люблю многопоточность, и именно она легла с основу новой платформы.
👉 Минутка рекламы в тему: обязательно подписывайтесь на мой канал и чат о параллельном и асинхронном программировании, GPGPU и оптимизации.

Каковы особенности моей платформы?

🔹 Нативный исполняемый код x86. Интро пишется под процессор Intel IA-32 / AMD x86. Никакого байт-кода, никакого Lua, JavaScript, Python или GLSL. Только ассемблер, только хардкор! 😁 И никаких тормозных DOSBox'ов, код запускается внутри процесса среды исполнения под Windows. Помимо всего прочего, вам доступны все прелести современных процессоров: 32-битная адресация, SIMD (вплоть до AVX-512) и прочие наборы инструкций. Возможно, позже будет поддержка 64-битного кода, но я не обещаю.

🔹 Опциональный заголовок. Да, это почти как COM-файл под DOS. Вам не нужно тратить драгоценные байты (десятки и сотни) на ненужную информацию о вашем интро. Заголовок, если он нужен, будет иметь разную длину в зависимости от тех данных, которые вы хотите там разместить. Вы даже можете спрятать заголовок в имя файла. Так что, под новую платформу вполне возможно создавать даже 32 или 64-байтные интро.

🔹 Среда исполнения с унифицированным API. Проблема DOS в том, что на работу вашего intro влияет множество внешних факторов, которые сложно (а иногда и невозможно) контролировать. Начиная от загруженных драйверов и резидентных программ, заканчивая особенностями реализации DOS и BIOS (в т.ч. различные номера видеорежимов VESA на каждой системе, разное состояние Unreal Mode и поддержки SSE). Кому-то наверняка это даже нравится, но лично я считаю это излишним неудобством. Если ваше аппаратное обеспечение не соответствует каким-то требованиям intro, среда исполнения Para\\e/ Para||elix выдаст соответствующее сообщение, в DOS же, скорее всего, система просто зависнет, либо intro будет глючить.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🔹 Разнообразие видеорежимов, режимов воспроизведения звука. Вы можете установить практически любое разрешение экрана с нужной вам цветностью (даже аппаратно неподдерживаемое — в этом случае картинка будет натягиваться на стандартное разрешение). Генерация звука может осуществляться в отдельной callback-функции и выдавать как семплы в стиле bytebeat, так и использовать MIDI.

🔹 Вам доступно до 512 МБ 1 ГБ оперативной памяти. Кроме того, память программы (код и данные) выровнена по границе 16 МБ, как и видеопамять, которая организована в виде массива идущих друг за другом пикселей (при этом каждая строка может быть дополнительно выровнена при необходимости).

🔹 Вишенка на торте: МНОГОПОТОЧНОСТЬ!!! Да, друзья, вы можете вызывать API-функции среды исполнения, которые в многопоточном режиме будут вызывать вашу callback-функцию отрисовки строк или даже отдельных пикселей (или групп пикселей по 2, 4, 8, 16, 32 или 64 шт для использования SIMD). Вы можете запросить вызов и любых других функций в многопоточном режиме, делать многопоточные циклы и пр. Разумеется, будут и барьеры и прочие средства синхронизации.

🔹 Различные мелочи вроде возможности остановить или перемотать intro, запустить с нужной секунды (удобно для отладки), завершить через нужное время (удобно для показа на пати зацикленных intro), замедлить/ускорить, воспроизвести задом наперёд (разумеется, для использования этих фишек intro должно быть специальным образом организовано). Расширенный функционал среды исполнения включается и отключается в конфиг-файле, который можно распространять вместе с правилами участия в компо (например, на нашем пати запрещено записывать заголовки в имена файлов, вызывать GDI-функции для рисования фигур, использовать более 64 Мб памяти и т.д.).

⚡️ Сейчас пишется самая-самая первая версия. Так сказать, MVP (минимально жизнеспособный продукт). Многого в ней не будет. Но в ней точно будет многопоточность и точно не будет заголовков исполняемых файлов intro. Я буду счастлив, если успею сделать её к Lovebyte Party 2023 (к февралю). К сожалению, дел всегда много, особенно под Новый Год, так что работать над платформой каждый день (и тем более по много часов) я не смогу. Но я буду стараться выделять на работу над платформой хоть какое-то время. И буду безмерно рад, если вы станете следить за ходом работы и поддерживать меня идеями, советами и реакциями 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
Продолжаю думать над организацией памяти.

Примерный Memory Map 32-битного процесса в Windows:
0x00000000 - 0x0000FFFF (64K) — резервная область (область нулевых указателей).
0x00010000 - 0x7FFDFFFF (почти 2 ГБ) — память, доступная процессу, включая DLL-ки в верхней части этой области.
0x7FFE0000 - 0x7FFFFFFF (128K) — системная область вперемешку с юзерской.
0x80000000 - 0xBFFFFFFF / почти 0xFFFFFFFF (1-2 ГБ) — память, доступная юзеру (соответственно в режиме PAE для 32-битной системы и в 64-битной системе), в 32-битной системе без PAE (или с отключенным битом 4G в PE недоступна).

Хочу сделать так, чтобы интра начиналась с фиксированного адреса.
Скорее всего, это будет адрес 0x10000000 (256 МБ от начала), потому что мне нужно от 64 до 80 МБ на API (ниже объясню почему) + память для самой среды запуска + адрес красивый и удобный :))

Если брать резерв доступной интре памяти в 1 ГБ для (включая сам код), то следующий свободный блок начнётся с адреса 0x50000000. Здесь, собственно, может начинаться видеопамять. Даже при 8K-разрешении 8192*8192*32 bpp на это нужно не более 256 МБ, т.е. на 0x60000000 всё закончится. Под DLL-ки оставшегося пространства хватит с лихвой.

Буферы под звук и пр. могут начинаться с любого адреса — это не шибко важно.

Теперь расскажу, зачем под API нужно аж 64-80 мегабайт. При старте интры регистр ebp будет указывать на область API-адресов: непосредственно по адресу ebp будет находиться 2-байтный jmp short (или 5-байтный jmp near, а пока думаю как лучше сделать, тут есть некоторые нюансы) на обработчик API, который выполняет функцию по её номеру в регистре ah, т.е. вызов API потребует всего 2 байта (call ebp), не считая загрузки номера в ah. По адресам [ebp-N] (N = -128...0, кроме 2-5 номеров) будут находиться 4-байтные адреса обработчиков API-функций. Чтобы все адреса были корректными, они должны содержать разные (неповторяющиеся) сочетания из 4-х цифр (к примеру, в 8 числах 1,1,1,1,2,1,1,3 у нас 5 валидных адресов: 0x01010101, 0x02010101, 0x01020101, 0x01010201, 0x03010102). Для 128 таких комбинаций диапазон адресов будет около 64 МБ. И такая организация позволит делать вызовы API-функций 3-мя байтами (call dword [ebp-N]) :)

В расширенной версии API с диапазоном в почти 256 адресов (позволяющей создавать соответственно около 256 функций) потребуется 80 МБ, т.к. 4-х цифр уже не хватит, нужно 5. Само собой, тут будет много пустых областей, которые не будут расходовать память. Ну и 1 ГБ + 256 МБ я выделять сразу не буду, достаточно только зарезервировать адресное пространство.
1