Автор Тема: SGDK  (Прочитано 99529 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Онлайн Sharpnull

  • Пользователь
  • Сообщений: 5499
    • Просмотр профиля
SGDK
« Ответ #780 : 18 Июль 2022, 21:26:58 »
Ничего не поменялось. Оффсет адреса тот же.
Вы передали указатель на указатель: SPR_setVRAMTileIndex(sprites,ind);, а у вас массив из указателей, нужно SPR_setVRAMTileIndex(sprites[0], ind);. Включите как можно больше предупреждений компилятора, читайте их и исправляйте.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #781 : 18 Июль 2022, 21:59:27 »
Оо, дело сдвинулось с мёртвой точки.
Но будто бы графика спрайта задевает состояние регистров сдвига слоя.
Хотя тут вроде бы с запасом впереди после графики спрайта ещё char-set есть, а дальше уже каша из состояний сдвига, разве не так?
странно покосило слой прокрутки


Добавлено позже:
непонятно, чё то за пара рядов из пикселей над буквой "a".
Не похоже, что это должно быть графикой спрайта, ибо сам спрайт по ширине и высоте кратен 8-ми.

Оффлайн Segaman

  • Пользователь
  • Сообщений: 3247
  • Пол: Мужской
  • Blast Processing!
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #782 : 21 Июль 2022, 06:41:16 »
Вы передали указатель на указатель: SPR_setVRAMTileIndex(sprites,ind);, а у вас массив из указателей, нужно SPR_setVRAMTileIndex(sprites[0], ind);. Включите как можно больше предупреждений компилятора, читайте их и исправляйте.
тут ты не прав.
Sprite sprites[8] - тут sprites это указатель на первый обьект Sprite в массиве
а sprites[0] - это уже экземплаяр самого Sprite

так что передать sprites в качестве указателя на первый объект в массиве это вполне правильно

можно даже на второй и третий передавать вот так: sprites + 1, sprites + 2, вместо &sprites[1] и &sprites[2]
и разницы к тому же никакой нет, компилятор одинаково представит и sprites, и &sprites[0]

Онлайн Sharpnull

  • Пользователь
  • Сообщений: 5499
    • Просмотр профиля
SGDK
« Ответ #783 : 21 Июль 2022, 06:54:14 »
Sprite sprites[8] - тут sprites это указатель на первый обьект Sprite в массиве
Там Sprite *sprites[80];, а Sprite sprites[80] не получится, ведь SPR_addSprite() возвращает указатель на Sprite.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #784 : 27 Август 2022, 19:55:32 »
Я изначально использую квадовую топологию. И вот щас думаю, а не поторопился ли я с таким решением. Может два триангла СДК закрашивает быстрее, чем один квад? Как думаете? Или там один универсальный алгоритм на любой тип многоугольников, и роли не играет?

Оффлайн lupus

  • Пользователь
  • Сообщений: 3858
  • Пол: Мужской
  • man with no face
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #785 : 28 Август 2022, 17:14:49 »
Чили-Вилли выложил свой набор для разработки:
https://segaxtreme.net/threads/my-current-devkit-for-md-cd-32x.25273/

Оффлайн GremLinN

  • Пользователь
  • Сообщений: 2
  • sega-mega
    • Просмотр профиля
SGDK
« Ответ #786 : 07 Сентябрь 2022, 23:07:03 »
Всем привет! вливаюсь в sgdk. сам я нубас в программировании, и у меня возникла куча вопросов по базовым вещам.

первое это память.

1. как в SGDK следить за загрузкой оперативной памяти, чтобы не превышать её?
2. как вообще разделяется память на то что лежит в роме и что сейчас находится в ОП.
Допустим, вот рекомпайлер компилирует картинку. он генерирует константу в которой есть палитра, тайлсет, тайлмап. и записывает ее объявление в заголовок resources.h( кстати, где в проекте, и  в какой форме у этой картинки после компиляции хранится реализация?)
Я так понимаю что все это как то отправится в ром.  а вот если я объявлю массив в теле программы.
u8 array[MAX_NUM] = {1,0,1,0,1,0,0,0....};
то он сразу займет место в оперативной памяти? как сделать так чтобы этот массив тоже сначала в ром записался, а я его потом по ссылке мог вызвать?
3 сгдк сам то жрет ченить по памяти? или он начинает жрать после объявления функций типа SPR_init();?


Добавлено позже:
Я изначально использую квадовую топологию. И вот щас думаю, а не поторопился ли я с таким решением. Может два триангла СДК закрашивает быстрее, чем один квад? Как думаете? Или там один универсальный алгоритм на любой тип многоугольников, и роли не играет?

обычно в 3д производительность зависит от количества точек (векторов) в модели и площади заполнения.
топология с квадами используется только для качественного сабдивижна.
« Последнее редактирование: 08 Сентябрь 2022, 02:13:07 от GremLinN »

Онлайн Sharpnull

  • Пользователь
  • Сообщений: 5499
    • Просмотр профиля
SGDK
« Ответ #787 : 08 Сентябрь 2022, 02:28:34 »
1. как в SGDK следить за загрузкой оперативной памяти, чтобы не превышать её?
Глобальную память должен отслеживать компилятор и выдать ошибку на этапе компиляции, но я не пробовал. Поэтому глобальную память нужно беречь, туда же относится static память в функциях, она ведь глобальная. Переменные определённые в функциях исчезнуть после вызова, это обычная логика языка C и не только.
В memory.c есть динамическое выделение памяти, которую также использует сам SGDK, там есть MEM_getFree(), чтобы узнать свободное место и MEM_alloc() вернёт NULL, если не получилось выделить. Также можно узнать о нехватке памяти, не проверяя возврат MEM_alloc(), через просмотр лога в эмуляторе, который поддерживает KDebug (KLog), например, видно использование KLog_*(): https://github.com/Stephane-D/SGDK/blob/868f2d55f3d28270750a924e275c0e53e4d6ec67/src/memory.c#L270. Также в pool.c, но не вижу KLog.
кстати, где в проекте, и  в какой форме у этой картинки после компиляции хранится реализация?
В out хранятся временные файлы, если был res\resources.res, то после компиляции будет res\resources.h и out\res\resources.o с данными, но всё что в out вас не должно волновать и можно удалить.
вот если я объявлю массив в теле программы.
u8 array[MAX_NUM] = {1,0,1,0,1,0,0,0....};
то он сразу займет место в оперативной памяти? как сделать так чтобы этот массив тоже сначала в ром записался, а я его потом по ссылке мог вызвать?
Да, скорее всего. Нужно объявлять глобальные переменные как const, чтобы они были в роме, при этом, если вы делаете массив из константных указателей на константные данные, то const нужно указывать 2 раза. Локальные переменные в main() очевидно тоже будут занимать память на протяжении всей игры.
сгдк сам то жрет ченить по памяти? или он начинает жрать после объявления функций типа SPR_init();?
Он будет жрать и так, конечно, но вы правильно заметили, что инициализация подсистем будет отнимать память, в некоторых случаях в документации указано, сколько примерно будет съедено памяти. Лучше всего смотреть исходный код. Например, SPR_init() это SPR_initEx(420), где 420 - сколько будет зарезервировано тайлов в VRAM, а в исходном коде SGDK будет видно, что сразу выделяется RAM для спрайтов через POOL_create(MAX_SPRITE, sizeof(Sprite)). Кстати, только сейчас узнал у новом pool.h, как там и написано, это например подходит для пуль, в играх для современных систем (ПК, консоли) без пула объектов никуда, каждый раз выделять память очень медленно.

Вот небольшая инструкция по установке SGDK и сборке проекта, которую я писал для одного человека:
Но вообще я не эксперт.

UPD: Не знаю как делают профи в SGDK, но получение свободной RAM во время игры думаю возможно, хотя бы частично, силами эмулятора (Lua или сам эмулятор), если разобрать как выделяется память в SGDK.
« Последнее редактирование: 08 Сентябрь 2022, 04:33:36 от Sharpnull »

Оффлайн GremLinN

  • Пользователь
  • Сообщений: 2
  • sega-mega
    • Просмотр профиля
SGDK
« Ответ #788 : 08 Сентябрь 2022, 18:39:25 »
спасибо за ответ!
В memory.c есть динамическое выделение памяти, которую также использует сам SGDK, там есть MEM_getFree(), чтобы узнать свободное место и MEM_alloc() вернёт NULL, если не получилось выделить. Также можно узнать о нехватке памяти, не проверяя возврат MEM_alloc()

а я правильно понимаю что эти команды это аналог стандартных malloc(); calloc();realloc(); free() ?  то есть стандартные библиотеки си в CGDK работать не будут вообще, и стеф все переписал?

раз уж вы затронули тему настройки и сборки проекта. У меня тут тоже прям гора вопросов. которые я не знаю как правильно сформулировать, чтобы хотя бы начать поиск информации.

значит поставил я сгдк по этому туториалу https://www.ohsat.com/tutorial/megapong/megapong-2/ на VScode. там есть спец плагин gencode, все очень удобно включается, но я совершенно не понимаю как это все работает в связке.

моя цель понять общие правила работы с фреймворками(сдгк ведь считается фреймворком? или это просто библиотека?), исходным кодом, и вообще как проекты настраиваются в популярных IDE. Есть ли общие правила для всех IDE или для каждой IDE все индивидуально? допустим в VScode добавляет в проект какие то папки с файлами настройки .vscode в которых я наощупь прописал пути. Но в других семплах для сгдк ,которые я скачивал для обучения, нет ничего подобного. ну или лежат какие то фалы настройки вообще в другом месте  и в другом формате. как тут разобраться?

Я начал смотреть как программы компилируются. и чето прям все не то что надо. по си  справочники про это говорят как то вскользь , делают упор на самом языке.
вот на хабре нашел общую информацию
что есть прекомпайлер , котом компайлер в ассемблер, потом подключается линковщик, после собирается файл. Где это все относительно сгдк смотреть? а есть еще какие то сборщики. вот что делает make.exe в сгдк? почему он создает libmd с расширением .a? если это статическая библиотека под виндоус она же должна иметь расширение . lib?
как вообще это гуглить? у меня полный сумбур в голове. Я раньше разбирался в юнити там все просто было, там одно средство и одни правила поведения.

Вот например компилятор.  Есть расширение с\с++ для VScode,  без него не будет возможности программировать под си. в настройках этого расширения нужно принудительно указать компилятор из большой визуал студии. (да я поставил еще и саму студию 19 лол).
и все вроде бы идет нормально. но тут я читаю форумы и люди пишут что Стэф использует какой то свой компилятор. Бдыщь. ну правильно думаю, нужен же компилятор под 68к, ан нет он использует какойто стандартный gcc старой версии. но он же для для х86? он что поставляется вместе с сгдк?  а как он тогда прописывается в VScode у меня же в настройках стоит от визуал студии?

еще в VScode  есть терминал. там можно выбирать профиль терминала. то есть получается для каждого компилятора свои терминал? их можно как-то настраивать. с сгдк у меня работает только профиль gen code  просто если я выбираю какой-нибудь повершелл, компиляция не проходит сыпет ошибками.


кароче вот такой сумбур. Мне в идеале нужна информация понятная нубу, чтобы я, допустим, получил исходники без инструкции по сборке,  смог подобрать компиляторы и прочие средства и смог их правильно скомпилировать через любую доступную иде.  просто пошлите меня по адресу че курить кароч по этой теме)



Добавлено позже:
Чили-Вилли выложил свой набор для разработки:
https://segaxtreme.net/threads/my-current-devkit-for-md-cd-32x.25273/

например, как мне взять эти тулзы и настроить их с VScode под виндоус? там нет четкой инструкции. что делать в такой ситуации?

Оффлайн Born_Free

  • Пользователь
  • Сообщений: 13
    • Просмотр профиля
SGDK
« Ответ #789 : 02 Март 2024, 19:25:19 »
Ведь в туториал для SGDK указано, что он под Си язык.. Разве это Си? У меня при создании нового проекта вышло так. Ну, я недавно начал изучать и может не до конца разобрался..
int main()
{
VDP_drawText("Hello World!!", 10,13);
while(1)
{
//For versions prior to SGDK 1.60 use VDP_waitVSync instead.
SYS_doVBlankProcess();

Разве не так должно быть? 🤷🏼‍♂️
int main()
printf("Hello World");
return 0;

Онлайн Sharpnull

  • Пользователь
  • Сообщений: 5499
    • Просмотр профиля
SGDK
« Ответ #790 : 02 Март 2024, 19:37:16 »
Разве не так должно быть?
Вы путаете функции и язык. Если добавить фигурные скобки, то оба куска кода на языке C. В SGDK нет функции printf(), для вывода текста используется своя. Ещё учитывайте, что в разных версиях SGDK некоторые функции меняют имя и набор аргументов, а также константы меняются.

Оффлайн Born_Free

  • Пользователь
  • Сообщений: 13
    • Просмотр профиля
SGDK
« Ответ #791 : 02 Март 2024, 21:56:44 »
Вы путаете функции и язык. Если добавить фигурные скобки, то оба куска кода на языке C. В SGDK нет функции printf(), для вывода текста используется своя. Ещё учитывайте, что в разных версиях SGDK некоторые функции меняют имя и набор аргументов, а также константы меняются.


Ужас! 😮 Возникает тогда вопрос, а чем это тогда упрощает процесс создания игрушки с нуля?

Последняя у меня версия SGDK 2.00 (January 2024).

Оффлайн Cyneprepou4uk

  • Пользователь
  • Сообщений: 210
  • Пол: Мужской
  • Самый лысый ромхакер
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #792 : 03 Март 2024, 00:49:30 »
Born_Free, сега это не консольное приложение, там свои приколы. И никто тебе не запрещает писать игру непосредственно на ассемблере, если думаешь что это проще.

Оффлайн Talking_Sword

  • Пользователь
  • Сообщений: 984
  • Happy Games Only!
    • Просмотр профиля
SGDK
« Ответ #793 : 03 Март 2024, 07:41:36 »
Кстати, не совсем понимаю, для чего нужно "while(1)"?

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1325
    • ВКонтакте
    • Steam
    • Просмотр профиля
SGDK
« Ответ #794 : 03 Март 2024, 13:29:16 »
Обычно ожидание ответа, в данном случае от SYS_doVBlankProcess();. Наверно, ждёт возвращения луча или что-то такое, а пока программа далее не пойдёт.
Красивее делать while(true), т.к. 1 - это уже "магическое", непонятное число.

Онлайн Sharpnull

  • Пользователь
  • Сообщений: 5499
    • Просмотр профиля
SGDK
« Ответ #795 : 03 Март 2024, 16:13:32 »
чем это тогда упрощает процесс создания игрушки с нуля?
Смысл использования языка C для разработки игр для MD такой же как и смысл его существования. На C для MD можно писать не только с помощью SGDK, но SGDK включает много полезных функций и возможностей. В SGDK есть как "низкоуровневые" функции, так и "высокоуровневые", которые используют низкоуровневые и позволяют меньше тратить времени, но для продвинутой или специфичной игры придётся использовать низкоуровневые.
UPD: Кстати, в SGDK есть имитация консоли, но без printf. Есть отдельно похожие функции из библиотеки C такие как strlen(), strcmp() и sprintf(), которая заменяет printf(), например:
char str[16];
sprintf(str, "%u/%u", currentImageIndex + 1, (u16)ARRAY_SIZE(images));
VDP_drawTextEx(BG_B, str, TILE_ATTR(PAL1, 0, 0, 0), 2, 2, CPU);
для чего нужно "while(1)"?
Если это весь кусок, то только для отображения текста, нет смысла выходить из main(). Обычно в играх есть основной игровой цикл, для SGDK это выглядит как бесконечный цикл после инициализации, в котором ожидают VBlank через SYS_doVBlankProcess() (там происходит и доп. работа, в доках написано), туда ещё добавляют чтение ввода и остальную логику игры. Не обязательно делать один цикл и можно делать ожидание VBlank внутри этого цикла или можно в бесконечном цикле вызывать только функцию по указателю, который содержит разные функции во время игры, ожидающие VBlank сами. Возможно по аналогии с NES играми можно весь код засунуть в обработчик VBlank, тогда в main() будет просто бесконечный цикл.
Красивее делать while(true)
В случае с SGDK - while (TRUE). Мне ещё нравится for (;;) {}, а для непонятливых можно while ("the cartridge is inserted") {} - ром будет точно такой же как с while (TRUE) {}, я проверил, тривиальная оптимизация работает.
« Последнее редактирование: 03 Март 2024, 16:26:25 от Sharpnull »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #796 : 09 Сентябрь 2025, 22:01:51 »
Есть идеи, как подготовить ресурсы/прописать процедурку для реализации такого скейла?





Походу таким макаром сделано масштабирование спрайтов в Road Rash, Scitchin, в заставках BT&DD (текст и приближающаяся Земля).

Добавлено позже:
Я щас как раз озадачился реализацией псевдо-недо-3д движка на сегу.
И пока вот думаю, или таким вот растягиванием-скукоживанием тайлов каждого спрайта скейлить объекты. Ну или рисовать мип-мапы сразу тайлами BG_A или BG_B

https://t.me/sega_punk/150

Онлайн Sharpnull

  • Пользователь
  • Сообщений: 5499
    • Просмотр профиля
SGDK
« Ответ #797 : 10 Сентябрь 2025, 15:21:31 »
Есть идеи, как подготовить ресурсы/прописать процедурку для реализации такого скейла?
Про ресурсы не знаю, видно, что нужно создать изображения кратные 8 px, это делается как удобнее. В коде можно вручную задать смещения для каждого размера в массиве (по осям X и Y почему-то отличаются смещениями в данном пример), по данным координатам и размерам на выходе координаты каждого тайла.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #798 : 10 Сентябрь 2025, 22:16:45 »
Про ресурсы не знаю, видно, что нужно создать изображения кратные 8 px, это делается как удобнее. В коде можно вручную задать смещения для каждого размера в массиве (по осям X и Y почему-то отличаются смещениями в данном пример), по данным координатам и размерам на выходе координаты каждого тайла.

Ну это муторно для каждого тайла создавать по целому файлу, а затем ещё и инициализировать по-тайлово... думал, может можно как-то автоматизировать сей процесс.

Добавлено позже:
по осям X и Y почему-то отличаются смещениями в данном пример
Та вроде линейная итерация. 
« Последнее редактирование: 10 Сентябрь 2025, 22:23:56 от ALKOSHA »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #799 : 11 Сентябрь 2025, 10:38:44 »
 Yu Yu Hakusho: Makyo Toitsusen тоже таким же способом скейлит спрайты.
Но там сегменты не 8х8, а кастомные. И без мип-мапинга, ибо диапазон скейла сильно ограничен.





Но мне без мип-мапинга никак. У меня галубокое три дэээ... Пока тренюсь на строго фронтальном перемещении Z, без тригонометрии. Но мечтаю добавить ещë cos sin поворот камеры, чтоб реализовать сëрд-пëрсон 3д графон на спрайто-тайлах.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #800 : 13 Сентябрь 2025, 13:26:53 »
Таки решил рендерить объекты мип-мапами на одном из слоёв, ибо объекты достаточно крупные, и спрайт-генератор вряд ли вывезет... Но блин... врагов и фаерболлы для плавности хотел таки спрайтами, и тут возникают сложности с Z-сортировкой с объектами на плейне.
Походу всё  на плейн придётся переносить. Посмотрим.
А, и ещё... Rescomp анализирует дубли по тайлам, если оные встречаются в разных файлах ресурсов типа IMAGE для компактной упаковки в VRAM ?
У ГПТшки спросил, фиг знает, где он это вычитал или додумал, но слишком хорошо, чтоб быть правдой
298141-0

Добавлено позже:
п.с. у меня последняя версия. То он за 1.12 воспринял из-за старых каталогов, в которых я обновлял файлы.

Просьба не размещать с помощью тэга img изображение со стороной более 700 пикселей. ghostdog3
« Последнее редактирование: 16 Сентябрь 2025, 19:20:06 от ghostdog3 »

Оффлайн Werton

  • Пользователь
  • Сообщений: 991
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #801 : 13 Сентябрь 2025, 16:22:47 »
Rescomp анализирует дубли по тайлам, если оные встречаются в разных файлах ресурсов типа IMAGE для компактной упаковки в VRAM ?
У ГПТшки спросил, фиг знает, где он это вычитал или додумал, но слишком хорошо, чтоб быть правдой
Нет в rescomp нет никакой крос оптимизации между ресурсами (знаю это, потому ковырял его когда добавлял поддержку перекрестных сылок между ресурсами Object), гптшка как ему и положено нафантазировал :biggrin:

Про аргумент BEST он тоже насвистел, это не для оптимизации тайлов и экономии VRAM, а для сжатия и экономии места в ROM, но его тогда нужно будет для использования расжимать, а во VRAM оно займет столько же места.

Расшарить тайлы можно только через общий Tileset между разными Tilemap, а для Image нельзя, тайлсет уже вшит во внутрь его структуры.

Добавлено позже:
А вообще зря ты тут такие вопросы задаешь, тут спецов по sgdk нет, с такими вопросами лучше напрямую к разрабу на официальный дискорд.
« Последнее редактирование: 13 Сентябрь 2025, 16:31:57 от Werton »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Re: SGDK
« Ответ #802 : 13 Сентябрь 2025, 16:37:51 »
Расшарить тайлы можно только через общий Tileset между разными Tilemap, а для Image нельзя, тайлсет уже вшит во внутрь его структуры.

Получается... для раскадровки мне нужно все кадры анимации с дублирующимися тайлами хранить в едином атласе, а рядом к нему тайлсет прилагать.
Я видел чёто такое в примерах с анимированными тайлами фона соника. Но пока на уровне теории. На практике ещё не догнал, как там это прописать,  чтоб пахало как положено.

Оффлайн Werton

  • Пользователь
  • Сообщений: 991
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #803 : 13 Сентябрь 2025, 16:44:44 »
Я видел чёто такое в примерах с анимированными тайлами фона соника. Но пока на уровне теории. На практике ещё не догнал, как там это прописать,  чтоб пахало как положено.
Это мой пример, могу пояснить, если есть вопросы.
Получается... для раскадровки мне нужно все кадры анимации с дублирующимися тайлами хранить в едином атласе, а рядом к нему тайлсет прилагать.
3 раза прочитал и не понял, что ты хотел сказать :biggrin:

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #804 : 13 Сентябрь 2025, 16:52:54 »
3 раза прочитал и не понял, что ты хотел сказать

Ну смари... Есть такая деревянная древняя игра thunder blade.
Приближающиеся здания типа - это кадры анимации, которые я должен в один монолитный png загнать, дабы rescomp у них определил все дубли 8х8 меж разными кадрами.
Каждое здание состоит из тайлов условного тайлсета, например, есть в тайлсете один экземпляр окна, один экземпляр бетона.
Нужно рескомпу указать на этот тайлсет, чтоб он его использовал в VRAM как собственно тайлсет. А кадры анимации в Vram будут как тайл-мап  (2д массив ссылок указателей на окно или бетон из тайлсета)... наверное опять непонятно пояснил...

Добавлено позже:
Вроде рескомп понимает tmx-формат.
« Последнее редактирование: 13 Сентябрь 2025, 17:00:33 от ALKOSHA »

Оффлайн Werton

  • Пользователь
  • Сообщений: 991
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #805 : 13 Сентябрь 2025, 17:18:59 »
наверное опять непонятно пояснил...
да.

Я понял, что ты хочешь сделать анимацию на задниках (что уж там будет рисоваться не столь важно). Анимацию можно сделать путем подмены тайлов в vram, но немного по-костыльному, т.к. встроенной функциональности для анимации тайлов в sgdk нет, а сам ты не знаешь в какую ячейку в vram sgdk засунет конкретный тайл.
Поэтому тайлсет нужно подготовить так, чтобы можно было это предсказать:
- в исходном тайлсете все тайлы подлежащие замене/анимации располагаешь в начале тайлсета
- исходный тайлсет должен быть оптимизирован и не содержать дубли, зеркальные тайлы и пустоту между тайлами
- готовишь тайлсеты под анимацию (1 тайлсет на кадр)
- в тайлсетах под анимацию, тайлы которые будут замещать/анимировать исходные тайлы располагаешь ровно в тех же позиция, что и на исходном тайлсете (если в кадре анимации есть дубли тайлов, то оптимизацию тайлсета можно отключить, иначе позиции съедут), остальные тайлы которые не анимируются туда не суешь
- с помощью исходного тайлсета рисуешь исходную мапу/картинку (Map или TileMap)
- в рантайме подгружаешь в vram нужный тайлсет (следующий по кадру) на позицию исходного тайлсета, затирая/подменяя при этом только тайлы, которые должны быть анимированы

В примере так сделано, возможно есть способ получше.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #806 : 13 Сентябрь 2025, 20:35:25 »
(1 тайлсет на кадр)

Ну вот если раскадровка будет в атласе, то там 1 тайлсет на все кадры... Тут сложность в том, чтоб выцепить указатель на нужный кадр, чтоб всё не посыпалось.

Добавлено позже:
- в рантайме подгружаешь в vram нужный тайлсет (следующий по кадру) на позицию исходного тайлсета, затирая/подменяя при этом только тайлы, которые должны быть анимированы
А... До меня дошло, что именно непонятного я пишу.
Не. В том и прикол, что в моём случае тайлсет должен кешироваться в VRAM однократно, и висеть там статично.
Нужно маняпулировать исключительно тайл-мапом (массивом ссылок-указателей на тайлсет), процедурно раскидывающим этот тайлсет по экрану.

Добавлено позже:
И вот я думал, что рескомпу можно как-то указать отдельно файл статичного тайлсета, а отдельно файлы для тайл-мапы, которые можно щёлкать туда-сюда.
И я глянул чендж-логи, таки да. Есть поддержка TMX формата. Терь бы обуздать сию фитчу. (опыт работы с ним уже имеется, но на libgdx, sdl, godot).
« Последнее редактирование: 13 Сентябрь 2025, 23:20:48 от ALKOSHA »

Оффлайн Werton

  • Пользователь
  • Сообщений: 991
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #807 : 14 Сентябрь 2025, 02:44:46 »
В том и прикол, что в моём случае тайлсет должен кешироваться в VRAM однократно, и висеть там статично.
В этом не особо много смысла, т.к. если не стримить тайлы анимации на лету из rom, а загружать все тайлы во vram сразу, то она быстро кончится (даже с учётом, что все дубли и зеркальные тайлы удалены, тем более, что в описанном мною способе они тоже удалены). А тебе ещё под спрайты место нужно, если разве, только, у тебя совсем простая анимация на задниках в пару-тройку кадров на несколько тайлов.
Нужно маняпулировать исключительно тайл-мапом (массивом ссылок-указателей на тайлсет), процедурно раскидывающим этот тайлсет по экрану.
Это будет сделать не просто, т.к. когда sgdk грузит тайлсет (без разницы из изображения или tmx файла), он его оптимизирует (а если отключить оптимизацию, то vram не хватит), и на каких позициях тайлы окажутся в vram ты не знаешь, поэтому манипулировать тайлами в тайлмапе ты не сможешь (точнее сможешь, но на угад). Поэтому тебе всё равно придётся заранее подготовить оптимизированный и отсортированный в нужном порядке тайлсет и для tmx тоже (как и в моем примере), чтобы ты мог гарантировать себе позиции тайлов в vram. Но, опять же я не вижу никакого профита от этого способа анимации, а гемора с ручной работой, как по мне, в нём ещё больше.
И я глянул чендж-логи, таки да. Есть поддержка TMX формата. Терь бы обуздать сию фитчу
Я там буквально неделю назад в дев версию (master ветка на GitHub) отправил пример загрузки карты из Tiled tmx (смотри sample/basics/tmx-map), может это чуть ускорит твои изыскания.
« Последнее редактирование: 14 Сентябрь 2025, 03:51:03 от Werton »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #808 : 18 Сентябрь 2025, 01:14:48 »
Очень нравится вид из глаз в Sword of Vermilinon.
Мечта повторить и улучшить. Убрать дискретность, сделать фуллскрин.

https://youtu.be/HNxjS7XwU8o?t=232

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 811
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #809 : 01 Октябрь 2025, 15:03:08 »
А вот чисто на уровне теории можете пояснить, что за сатана происходит в мозгах VDP в игре Lawnmowerman на уровнях вида из глаз?
Как я понимаю, там всë те же мип-мапы пререндером приближаются, но хранятся они в виде покадрового X-скейла, а по Y их растягивает уже H-Blank.(таким же образом скейлится морда в финального босса)... но блин... как же сделана слоëнка в 4 слоя? Чëт в голове не укладывается, как оно так... тоже какой-то прикол со скроллами по H-blank? в VRAM там тока два слоя как будто изображены в моменте... в общем, нипанятна...
На снес-то из коробки есть режим в 4 слоя (сама процедура скейла походу тем же алгоритмом сделана, что и на сеге, ведь MODE7 распространяется лишь на один слой).
По уровням, где действительно юзается MODE7, на сеге используют palette shifting, там тоже всë предельно просто и понятно. Но 4 слоя - магия какая-то.