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

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

Оффлайн nonamezerox

  • Пользователь
  • Сообщений: 322
    • Просмотр профиля
SGDK
« Ответ #660 : 01 Ноябрь 2021, 14:11:15 »
щё на счёт коллизий не совсем понятно.   Можно ли сделать коллизию с точностью до пиксела?

Эммм, градиус, ты логику от представления не можешь отделить?

Коллизии это привязанные к спрайтам и окружению  Box-Box и существуют в вообще отдельном программном слое от графики.

Сооотвественно, как ты эти самые хитбоксы сделаешь такая точность и будет.




Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #661 : 01 Ноябрь 2021, 15:01:54 »
Цитата
Сооотвественно, как ты эти самые хитбоксы сделаешь такая точность и будет.

На сеге есть игры и с per-pixel колижном.
Worms, sub-terrania, pugsy и прочее. Но эти игры с акцентом на физику.
Другой вопрос, зочем ему это нужно, если он делает кальку с контры, судя по всему. Там просто надо позу спрайта поменять при проверке краёв платформы. То есть по-тайловой проверки более чем достаточно.

Оффлайн lupus

  • Пользователь
  • Сообщений: 3828
  • Пол: Мужской
  • man with no face
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #662 : 01 Ноябрь 2021, 16:40:14 »
Вставлю свои 5 копеек: я при “переносе” Silent Hill: Play Novel с GBA на SMD активно использовал вышеупомянутый Retro Graphics Toolkit и его алгоритмы дизеринга, после чего ещё маленько в фотошопе поправлял. Оптимизировать от души пришлось, т.к. палитра ограничена и самой графики немало, а её надо было как-то в 4 метра уместить, вместе с непожатым звуком.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #663 : 01 Ноябрь 2021, 17:30:22 »
Коллизии это привязанные к спрайтам и окружению  Box-Box и существуют в вообще отдельном программном слое от графики.
Сооотвественно, как ты эти самые хитбоксы сделаешь такая точность и будет.

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

Для платформера желалась пиксельная точность. На учёт гравитации.  Чтобы ноги в воздухе не висели и чтоб не падал, когда перекрытие хотя бы на 1 пиксел.

В случае с сегой надо определить какие тайлы пересекаются и потом ещё проверить на локальное пересечение внутри тайлов.  Насколько это будет ресурсоёмко?  Как вообще в нормальных сеговских платформерах  это делается?   Чем обыгрывается?






Добавлено позже:
Оптимизировать от души пришлось

Я уже наигрался от души! :lol: Понял, что лучше перерисовать под требования сеги.   Только вот беда - не художник я.

Добавлено позже:
проверка коллизий откуда-то из примеров взята, или же свой велосипед?

Пока взял отсюда: https://under-prog.ru/sgdk-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d0%b5%d1%80%d0%b0-%d0%b4%d0%bb%d1%8f-sega-genesis/

Автор этого сайта здесь недавно был.


Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #664 : 01 Ноябрь 2021, 17:35:19 »
Цитата
Как вообще в нормальных сеговских платформерах  это делается? 

Как правило - по-тайлово.
Даже в сонике на наклонных плоскостях в таблички загнаны интерполированные значения оффсета.
Шоба чувачок не падал - делаешь шире колижн-бокс. Шоба нога не свисала в воздухе - меняешь кадры анимации... Та блин, ты ни разу не становился на край в том же сонике, флинке, ультра-коре и тд?
Тут чисто вопрос арт-исполнения, а не каких-то заумных алгоритмов.

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #665 : 01 Ноябрь 2021, 19:10:11 »
Как это сделать средствами SGDK ?

Пока приходят в голову 2 идеи:

1) Распилить атлас на отдельныве анимации и задать им разное время.
2) Сделать самостоятельно процедуры анимации - с нужными задержками и переходами между фреймами в одном большом атласе.
Ну в целом да, для одной задержки на отдельную анимацию сойдет и первый, для покадровой задержки 2ой.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #666 : 01 Ноябрь 2021, 20:34:08 »
Исходный фрагмент атласа (RGB 8:8:8):

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #667 : 02 Ноябрь 2021, 05:30:58 »

Глянул оба варианта на реальной сеге + ТВ.
Да, стало лучше:  более выделены груди, немного стали различимы детали лица.





Для сравнения:


Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #668 : 02 Ноябрь 2021, 19:34:49 »
Да, стало лучше:  более выделены груди, немного стали различимы детали лица.
scolor_gen.exe in.png 16 out.png 0.1 3 3
но есть нюанс -  там каждый раз разные результаты выдаёт, поэтому все спрайты надо разом конвертить.  несколько раз прогнать и выбрать лучший вариант. как-то так.
Ссылки тут:
http://gendev.spritesmind.net/forum/viewtopic.php?p=20105#p2010

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #669 : 03 Ноябрь 2021, 04:50:03 »
scolor_gen.exe in.png 16 out.png 0.1 3 3
но есть нюанс -  там каждый раз разные результаты выдаёт, поэтому все спрайты надо разом конвертить.  несколько раз прогнать и выбрать лучший вариант. как-то так.
Ссылки тут:
http://gendev.spritesmind.net/forum/viewtopic.php?p=20105#p2010

Интересная программа, спасибо!  :) Да и вся ветка того форума интересная.

Несколько раз прогнать - это как?  Результат загонять в качестве исходного?

Было бы неплохо понять смысл параметров:  уровень дизеринга, размер фильтра и режим GEN.

Почему-то  генерит пустой белый прямоугольник, когда размер фильтра =1.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #670 : 03 Ноябрь 2021, 08:40:54 »
Несколько раз прогнать - это как?  Результат загонять в качестве исходного?

Было бы неплохо понять смысл параметров:  уровень дизеринга, размер фильтра и режим GEN.
нет, исходный один:
gen - от названия sega genesis. то есть адаптация под её палитру. 
дизеринг это просто его величина, чем больше, тем сильнее. 0 не ставится.
по фильтру не знаю.


Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #671 : 04 Ноябрь 2021, 15:46:49 »
нет, исходный один:

Глянул сорец этой программы. Да, там действительно random() используется. Поэтому результат каждый раз разный. Интересно, зачем так сделано?

---

Начал изобретать свой велосипед с коллизиями, так как примеры из интернета меня не впечатлили: либо всё в общем и ни о чём, либо неприменимо к СЕГе.

Итак, мне понадобились точные коллизии спрайта с тайловой плоскостью. Весь гемор в том, что маска таловой плоскостью задана массивом клеток кратных 8.  Эта же плоскость должна плавно скролиться по двум осям,  ну и спрайт естественно тоже.

Мало определить индексы i,j   массива клеток, ещё нужно пиксельные смещения взаимно учесть : движение спрайта и скролы плоскости.

Ну и конечно, ограничение приращения координат спрайта, если шаг приращения больше дистанции до стены (когда спрайт близко к стене) чтобы не впечатывался в стену.

Скажу, что был мощный брэйн-фак, но мне удалось родить рабочий код: сделал 4 коллизии спрайта с тайлами плоскости.

Код:

#define STEP 3 /* шаг приращения координат спрайта */

//Координаты спрайта
s16 RegionX=0;
s16 RegionY=0;

//Скроллы:
s16 ScrollX=0;
s16 ScrollY=0;

bool CollisionU(s16 rx,s16 ry)
{
 rx+=ScrollX;
 ry+=ScrollY;

 s16 i=rx>>3;
 s16 j=ry>>3;

         if(LevelMask[j][i  ])return TRUE;
 if(rx&7)if(LevelMask[j][i+1])return TRUE;

 return FALSE;
}

bool CollisionD(s16 rx,s16 ry)
{
 rx+=ScrollX;
 ry+=ScrollY -1;

 s16 i= rx>>3;
 s16 j=(ry>>3)+1;

         if(LevelMask[j][i  ])return TRUE;
 if(rx&7)if(LevelMask[j][i+1])return TRUE;

 return FALSE;
}

bool CollisionL(s16 rx,s16 ry)
{
 rx+=ScrollX;
 ry+=ScrollY;

 s16 i=rx>>3;
 s16 j=ry>>3;

         if(LevelMask[j  ][i])return TRUE;
 if(ry&7)if(LevelMask[j+1][i])return TRUE;

 return FALSE;
}

bool CollisionR(s16 rx,s16 ry)
{
 rx+=ScrollX  -1;
 ry+=ScrollY;

 s16 i=(rx>>3)+1;
 s16 j= ry>>3;

         if(LevelMask[j  ][i])return TRUE;
 if(ry&7)if(LevelMask[j+1][i])return TRUE;

 return FALSE;
}

void Joystick(void)
{
 u16 J=JOY_readJoypad(JOY_1);

 if(J&BUTTON_UP   )
 {
  for(s16 s=STEP;s>0;s--)if(!CollisionU(RegionX,RegionY-s))
  {
   RegionY-=s;
   break;
  }
 }
 else
 if(J&BUTTON_DOWN )
 {
  for(s16 s=STEP;s>0;s--)if(!CollisionD(RegionX,RegionY+s))
  {
   RegionY+=s;
   break;
  }
 }

 if(J&BUTTON_LEFT )
 {
  for(s16 s=STEP;s>0;s--)if(!CollisionL(RegionX-s,RegionY))
  {
   RegionX-=s;
   break;
  }
 }
 else
 if(J&BUTTON_RIGHT)
 {
  for(s16 s=STEP;s>0;s--)if(!CollisionR(RegionX+s,RegionY))
  {
   RegionX+=s;
   break;
  }
 }

 static u8 t=0;

 if(!t)
 {
  if(J&BUTTON_A)ScrollX--;
  if(J&BUTTON_B)ScrollX++;
  if(J&BUTTON_X)ScrollY--;
  if(J&BUTTON_Y)ScrollY++;
 }

 t++;
 if(t==8)t=0;
}

#define LEVEL_W 40
#define LEVEL_H 28

const u8 LevelMask[LEVEL_H][LEVEL_W] = {   //маска тайлов: 0 - свободно,  1 - cтена
{ 0, 0, 1,1,1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
....

Скроллы двигаются кнопками: A,B,X,Y.
Спрайт двигается: Up,Down,Left,Right

Протестировал - всё чётко.  Спрайт при тесном контакте со стенами не осциллирует.


« Последнее редактирование: 04 Ноябрь 2021, 15:55:39 от rep-stosw »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #672 : 05 Ноябрь 2021, 05:16:53 »
Прикрутил прыжок и гравитацию.  Пока без ускорения.

Кстати, какая механика более правильная? :

1) В прыжке отжатие влево-вправо приводит к остановке перемещения игрока по горизонтали

2) В прыжке отжатие влево-вправо НЕ приводит к остановке перемещения игрока по горизонтали

На видео, сделан способ (1).


 
 
И как побороть этот треш?  При этом все ресурсы вроде как собираются...


Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #673 : 05 Ноябрь 2021, 09:12:53 »
И как побороть этот треш?  При этом все ресурсы вроде как собираются...

Пофиксил этот придурошный баг: https://allthe.codes/mirror/sgdk/commit/13b13e37d98e5e876befbc55120cee2cb418cff2

Прикрепил пофикшенный Jar (класть в bin).

* sizebnd(fixed).zip (2.5 КБ - загружено 42 раз.)

P.S. Чё-то я не понял... Релиз 1.65 у Стефа без фикса: https://allthe.codes/mirror/sgdk/src/tag/v1.65/tools/sizebnd/src/sgdk/sizebnd/Launcher.java

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #674 : 05 Ноябрь 2021, 09:51:57 »
P.S. Чё-то я не понял... Релиз 1.65 у Стефа без фикса:
Потому что фикс закомичен после релиза 1.65, ваш КО.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #675 : 05 Ноябрь 2021, 12:40:25 »
Приделал ускорение при прыжке и падении.

Скорость линейно убывает при прыжке: V-=A
И линейно возрастает при падении: V+=A
Максимальная скорость S
Максимальная высота прыжка H

Необходимо было один раз просчитать ускорение (насколько увеличивать/уменьшать скорость).

Реккурентная формула:   S + S-A + S-2A + ... +S-nA = H

Граничное условие сверху:   S-nA = V = 1  (минимальная скорость)

Граничное условие снизу:  V= S (максимальная скорость)

Решая, получил:  A = (S-1)(S+1)/(2H-S-1)

Загоняем в код, получим:

#define JUMP_H 32    /* максимальная высота прыжка                          */
#define JUMP_S 5.0F  /* начальная скорость прыжка/конечная скорость падения */

//#define JUMP_A FIX16((JUMP_S*JUMP_S)/((2.0F*JUMP_H)-JUMP_S))                  /* ускорение прыжка/падения (скорость уменьшается до 0) */
#define JUMP_A FIX16(((JUMP_S-1.0F)*(JUMP_S+1.0F))/((2.0F*JUMP_H)-JUMP_S-1.0F)) /* ускорение прыжка/падения (скорость уменьшается до 1) */

f32 js=FIX16(JUMP_S); //скорость прыжка/падения с учётом ускорения

u8 BF=1;    //разрешено нажатие кнопки "B"
u8 JF=0;    //прыжок запрещён
s16 Ground; //уровень земли

void MoveControl(void)
{
 u16 J=JOY_readJoypad(JOY_1);

 if(BF==1)if(J&BUTTON_B) //если разрешено нажатие кноки "B" и нажата кнопка "B"
 {
  BF=0;             //запретить следующие нажатия кнопки "B"
  JF=1;             //разрешаем прыжок (движение вверх)
  Ground=RegionY;   //запоминаем уровень земли
//  js=FIX16(JUMP_S); //начальная скорость прыжка/падения
 }

// if(BF==0)if(!(J&BUTTON_B))BF=1; //если запрещено нажатие кнопки "B" и если кнопка "B" отжата, то разрешаем следующее нажатие кнопки "B" (запрет TURBO-нажатия)

 if(JF==0) //если прыжок запрещён, то движение вниз (гравитация)
 {
  for(s16 s=fix16ToInt(js);s>0;s--)if(!CollisionD(RegionX,RegionY+s)) //если нет коллизии вниз...
  {
   RegionY+=s; //...то движемся вниз
   break;
  }
  else BF=1; //...в противном случае разрешаем нажатие кнопки "B" (убрать, если используется запрет TURBO-нажатия)

  js+=JUMP_A;                           //увеличиваем скорость
  if(js>FIX16(JUMP_S))js=FIX16(JUMP_S); //ограничение
 }
 else //если прыжок разрешён, то движение вверх
 {
  for(s16 s=fix16ToInt(js);s>0;s--)if(!CollisionU(RegionX,RegionY-s)) //если нет коллизии вверх...
  {
   RegionY-=s; //...то движемся вверх

   if(RegionY<=Ground-JUMP_H)JF=0; //если высота превысила длину прыжка, то запрещаем прыжок

   break;
  }
  else JF=0; //...в противном случае запрещаем прыжок

  js-=JUMP_A;                       //уменьшаем скорость
  if(js<FIX16(1.0F))js=FIX16(1.0F); //ограничение
 }

Все скорости - [пиксели/c],  расстояния - [пиксели]

Вот весь автомат прыжка  без движка! :lol:


Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #676 : 06 Ноябрь 2021, 15:53:50 »
Есть ли способ в SGDK  обращаться к отдельным спрайтам из спрайтового атласа?

К примеру, у меня есть один большой спрайтовый атлас со сгруппированными спрайтами (выровнены на фрейм) каждый спрайт M x N  тайлов.

Необходимо выборочно дёргать произвольный спрайт и отображать его со своими: палитрой, координатами, атрибутами отзеркаливания.

Стандартную функцию анимации использовать не хочу по причинам, изложенным ранее здесь в форуме.

Как в этом случае описать ресурс в res-файле и какими функциями выводить спрайты-устанавливать параметры?

Хочу создать свою анимацию - со своими последовательностями цепочек спрайтов  и со  своими атрибутами.

 Через железо сеги я и сам могу это сделать.   Интересует как это сделать ИМЕННО средствами SGDK через отрисов спрайта и установку атласа спрайтов.

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #677 : 06 Ноябрь 2021, 16:21:03 »
Все что можно описано в справке и в rescomp.txt, никаких секретных техник там нет.

Добавлено позже:
Есть ли способ в SGDK  обращаться к отдельным спрайтам из спрайтового атласа?
стандартные
SPR_setAnim (Sprite *sprite, s16 anim)
SPR_setFrame (Sprite *sprite, s16 frame)
Необходимо выборочно дёргать произвольный спрайт и отображать его со своими: палитрой, координатами, атрибутами отзеркаливания.
SPR_addSprite (const SpriteDefinition *spriteDef, s16 x, s16 y, u16 attribut)
используй макрос TILE_ATTR(pal, prio, flipV, flipH) как параметр attribut

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

Добавлено позже:
Как в этом случае описать ресурс в res-файле
SPRITE name img_file width heigth [compression [time [collision [opt [iteration]]]]]
установи параметр time в 0, чтобы отключить автопроигрывание анимации
и какими функциями выводить спрайты-устанавливать параметры?
стандартными
« Последнее редактирование: 06 Ноябрь 2021, 16:55:32 от Werton »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #678 : 06 Ноябрь 2021, 17:12:11 »
Werton,  спасибо! 

Забыл отключить авто-анимацию, из-за этого мои анимации артефачили.

Можно ли заставить rescompiler выкидывать повторяющиеся тайлы в атласах спрайтов?

Спрайты-то он выкидывает.  Ещё хотелось бы оптимизации на уровне тайлов.

Ещё на счёт палитры вопрос.  Я сохраняю PNG как 16-цветный.  Но иногда цвет прозрачности в СЕГЕ не совпадает с прозрачностью в PNG.  Из-за этого изображение выводится с одним потеряным цветом и без прозрачности.   Что я делаю не так и как следует конвертить?

Использую IrfanView или GIMP.

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #679 : 06 Ноябрь 2021, 18:21:28 »
Ещё на счёт палитры вопрос.  Я сохраняю PNG как 16-цветный.  Но иногда цвет прозрачности в СЕГЕ не совпадает с прозрачностью в PNG.  Из-за этого изображение выводится с одним потеряным цветом и без прозрачности.   Что я делаю не так и как следует конвертить?
Альфа канал png тут не применим, нужно конвертить в png с индексированной палитрой. Первый цвет палитры и будет считаться прозрачным (либо же можно задать индекс прозрачного цвета вручную через VDP_setBackgroundColor (u8 value), но нужно знать индекс цвета). Для работы с индексированной палитрой я юзаю Graphics Gale, Aseprite, Pro Motion NG.
« Последнее редактирование: 06 Ноябрь 2021, 18:29:03 от Werton »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #680 : 13 Ноябрь 2021, 18:41:12 »
Цитата
Ещё на счёт палитры вопрос.  Я сохраняю PNG как 16-цветный.  Но иногда цвет прозрачности в СЕГЕ не совпадает с прозрачностью в PNG.  Из-за этого изображение выводится с одним потеряным цветом и без прозрачности.   Что я делаю не так и как следует конвертить?

Лично я когда маялся сегою, перетасовывал индексы в Гимпе. (Но для рисования этот убогий редактор никудышный. Все мои пиксел-арты сделаны в пэинт дот нете, оттуда же есть опция сохранения в 4bpp).
« Последнее редактирование: 13 Ноябрь 2021, 18:47:36 от ALKOSHA »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #681 : 18 Ноябрь 2021, 13:44:33 »
Лично я когда маялся сегою, перетасовывал индексы в Гимпе. (Но для рисования этот убогий редактор никудышный. Все мои пиксел-арты сделаны в пэинт дот нете, оттуда же есть опция сохранения в 4bpp).

Я вообще ничего не рисую с нуля :  работаю с готовым или рипаю с эмуляторов или покупаю новое.  Делаю только цвето-коррекцию. И может немного дорисовываю по мере своих способностей.

Делаю тоже самое: использую GIMP, открываю 16-цветный PNG.  Далее Цвет => Карта => Перераспределить цветовую карту.  Вылазит окошко со всеми цветами палитры,  перетасовываю,  чтобы нулевой - был цвет фона. 

Цвета подстраиваю Genny Optimizer Palette.  Результат на реальном телеке устраивает, и с SGDK-шным rescomiper-ом дружит. Цвета вижу 1-в-1 как нарисовал.



Новый вопрос:

как средствами SGDK  делать анимирующийся TileMap ? 

Не скролить полоски, а менять отдельные тайлы в TileMap?   Типа как крутящиеся болтики на корабле в 1-м уровне  BattleToads and Double Dragon.

На голом железе лазил напрямую ручками в VRAM Plane и менял отдельные байты (номера тайлов)

« Последнее редактирование: 18 Ноябрь 2021, 13:52:45 от rep-stosw »

Оффлайн Марат

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
SGDK
« Ответ #682 : 20 Ноябрь 2021, 19:58:08 »
Не скролить полоски, а менять отдельные тайлы в TileMap? 
Просто менять графику нужного тайла во время кадрового прерывания, например, пересылкой посредством DMA.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #683 : 21 Ноябрь 2021, 03:59:29 »
У меня было чутка говнокодерски
 :blush:

Шлёпал имейджи по заданным координатам (пульсирующая бадяга на фоне).
На производительности особо не сказалось.




Но в идеале, да, надо как-то через TILE_USERINDEX грузить графон по нужному адресу. Оффсет, видимо, надо самому смотреть через просмотрщик VRAM.



Добавлено позже:
А прикол. До сих пор среди примеров идущих в комплекте нет такой банальной штуки, как тайл-анимашка. Даже в примере с Саником фон статичен [даже стеф не осилил ^_^]

Добавлено позже:
Я вот чё ещё думаю. Наверн шлёпанье пикч (предварительно распакованных в VRAM) таки быстрее будет, чем трансфер оных из картриджа  по DMA. Ведь в данном случае содержимое памяти остаётся статичным.
Но тут заморочка с вычислением координат позиций каждого тайла. Так что надо смотреть по обстоятельствам. Если у тебя анимашка тайлов идёт в ряд, что можно в цикле бахнуть, то быстрее как в моём случае. А если рандомно раскиданы по локации, то лучше всё же менять графику в  VRAM на лету.
« Последнее редактирование: 21 Ноябрь 2021, 05:31:20 от ALKOSHA »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #684 : 21 Ноябрь 2021, 15:41:05 »
А прикол. До сих пор среди примеров идущих в комплекте нет такой банальной штуки, как тайл-анимашка. Даже в примере с Саником фон статичен [даже стеф не осилил ^_^]

Да, это бы не помешало!  :)

В случае с анимациями придётся наверное свой велосипед делать.  Две стратегии:

1. Перезаписывать весь тайл. DMA поможет.
2. Перезаписывать  участок VRAM, отведённый под TileMap (1 байт)

Первый способ более медленный, зато есть возможность подгружать тайлы с ROM.

---

Столкнулся с такой проблемой. Делаю переключение персов (1 перс - свой атлас анимаций, своя палитра, свои спрайты).  Список спрайтов заполняется(идёт вниз) до конца по мере переключения между персами.  В настоящее время нужен только один перс.

Спасла дефрагментация Sprite VRAM.  С ней перс пересоздаётся в той же VRAM и перерасхода нет:

void Person_Create(struct Person *p,const SpriteDefinition *sd)
{
 SPR_releaseSprite(p->sprite);

 SPR_defragVRAM();

 p->sprite=SPR_addSprite(sd,p->X,p->Y,TILE_ATTR(PAL0,FALSE,FALSE,p->H));

 SPR_setAnim(p->sprite,0);   //always 0
 SPR_setFrame(p->sprite,27); //IDLE

 SPR_update();
 SYS_doVBlankProcess();

 VDP_setPalette(PAL0,sd->palette->data);
}

Ещё пришлось костыль поставить перед переключением палитры:

SPR_update();
 SYS_doVBlankProcess();

Потому что палитра меняется сразу,  а спрайты только после SPR_Update.
Иначе видно переключение палитры во время смены персонажа и старого персонажа с новой палитрой.

Переключение персонажей сделал - так же как в Bucky O'Hare. По нажатию кнопки.

Есть ли в SGDK способ отложенно апдейтнуть палитру  синхронно с SPR_Update ?  Просто у меня уже один SPR_Update в цикле есть, а при пересоздании перса приходится его вызывать ещё раз, чтобы избежать артефактов с палитрой.

Можно конечно, программными флагами, но а вдруг есть более красивое решение?  :D

ИМХО немного нелогично получается:  палитра перезаписывается сразу, а спрайты после SPR_Update.


« Последнее редактирование: 21 Ноябрь 2021, 15:48:18 от rep-stosw »

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #685 : 21 Ноябрь 2021, 20:18:33 »
Потому что палитра меняется сразу,  а спрайты только после SPR_Update.
ну на экране то спрайт перерисуется только после SYS_doVBlankProcess(), а не SPR_Update().
VDP_setPalette(PAL0,sd->palette->data);
Есть ли в SGDK способ отложенно апдейтнуть палитру  синхронно с SPR_Update ?  Просто у меня уже один SPR_Update в цикле есть, а при пересоздании перса приходится его вызывать ещё раз, чтобы избежать артефактов с палитрой.
VDP_setPalette() - устарела, вместо нее лучше юзать PAL_setPalette(u16 numPal, const u16* pal, TransferMethod tm), а для изменения палитры с задержкой до vblank используй с аргументом DMA_QUEUE в качестве TransferMethod.
зы: там еще есть PAL_setPaletteDMA (u16 numPal, const u16 *pal), но она тоже устарела и работает почему то криво.
« Последнее редактирование: 21 Ноябрь 2021, 20:26:15 от Werton »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #686 : 22 Ноябрь 2021, 14:38:48 »
вместо нее лучше юзать PAL_setPalette(u16 numPal, const u16* pal, TransferMethod tm), а для изменения палитры с задержкой до vblank используй с аргументом DMA_QUEUE в качестве TransferMethod.

Теперь всё чётко, как и хотел! Спасибо! :)

SGDK позволяет отлавливать номер отрисовываемой строки, чтобы щёлкнуть палитру?  HBlank.  Хочу во время обратного хода луча по строке поменять палитру, так как штатных 4-х слотов явно не хватает.

Оффлайн Марат

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
SGDK
« Ответ #687 : 23 Ноябрь 2021, 06:09:05 »
Заведи счётчик, который будешь обнулять во время vblank, и инкрементировать во время hblank.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #688 : 25 Ноябрь 2021, 12:27:08 »
Накопилось несколько вопросов по музыкальной части:

1) Есть трекер Deflemask последней версии.  Какие есть подводные камни при экспорте трека с Дефлемаска в формат XGM, пригодный для запуска не сеге?

2) Есть ли трекеры для сеги лучше, чем Deflemask?  С условием получения на выходе формата, нужного для сеги (каналы YM2612, DAC, PSG).

3) Реально ли перенести XM, IT, MOD, S3M и им подобные на XGM/VGM ?  Можно ли автоматизировать процесс?  Например, с OpenMPT перенести нотки на Deflemask, а потом вручную подобрать инструменты.

4) Пишут ли новую музыку для игр сеги или выдирают /конвертируют/каверят  уже существующие композиции?

5) Драйвер звука XGM.  Какие у него подводные камни?  Можно ли мне быть уверенным, что музыка будет хорошо играть на 5 FM каналах + 4 PSG,  а озвучки в игре (просто семплы) - в 4-х каналах , каждый семпл 14 кГц моно 8 бит.   Такая раскладка - насколько хороша в играх на практике?

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #689 : 25 Ноябрь 2021, 17:28:23 »
Есть ли трекеры для сеги лучше, чем Deflemask?  С условием получения на выходе формата, нужного для сеги (каналы YM2612, DAC, PSG).

YM2612, DAC, PSG используется и в VGMmusicMaker'e. Насколько он хуже/лучше ДефектМаска - не смею судить, так как последнее не пробувал.

Реально ли перенести XM, IT, MOD, S3M и им подобные на XGM/VGM ?

В этих форматах, точно нет. Да и на сеге с этим тот ещё гимор, ведь у Z80 в распоряжении всего-то 8 кб, где помимо сэмплов и паттернов нужно ещё хранить и сам плеер. Вообще трекерная музыка использовалась только в ToyStory (интро/эндинг) и Демосцене Stuck Somewhere in Time (где очень примитивные семплы с закосом под SID), ВСЁ! больше примеров нет.


4) Пишут ли новую музыку для игр сеги или выдирают /конвертируют/каверят  уже существующие композиции?

Всё это возможно при нынешнем инструментарии. Savaged Regime так и вовсе реаранжирует олдовые треки в более качественном виде.

Добавлено позже:
5) Драйвер звука XGM.  Какие у него подводные камни?  Можно ли мне быть уверенным, что музыка будет хорошо играть на 5 FM каналах + 4 PSG,  а озвучки в игре (просто семплы) - в 4-х каналах , каждый семпл 14 кГц моно 8 бит.   Такая раскладка - насколько хороша в играх на практике?

Ну там среди примеров есть же. Вроде норм играется всё.
В играх на практике у каждого был свой драйвер, у кого-то были около-биперные 1-2 бита сэмплы (Altered Beast, Golden Axe 1), у кого-то микшировалось несколько каналов с DPCM сжатием (MK3, EWJ).

Добавлено позже:
К слову, встречал даж VST для фруктов, где можно писать чиптюн на сегу. Именно не фейковый, а с возможностью дальнейшего экспорта в VGM. Но ломанной версии так и не нашёл, поэтому побаловаться не удалось.
« Последнее редактирование: 25 Ноябрь 2021, 17:40:18 от ALKOSHA »