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

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

Оффлайн Segaman

  • Пользователь
  • Сообщений: 3240
  • Пол: Мужской
  • Blast Processing!
    • Youtube
    • Просмотр профиля
Настройка SGDK
« Ответ #390 : 19 Сентябрь 2018, 01:16:10 »
Кто-нить работал с движком Echo?
тут такое дело, не можем заставить PSG функционировать корректно.
note off не работает почему-то, а инструменты вообще эмулятор крашат.
юзали инструменты из демки, вроде
Instr_PSGFlat:
    dc.b    $FE,$00,$FF
Но не помогло. Эмуль Regen, на Kega просто артефакты и путаница каналов PSG с FM.
Музен делаем в XM а потом конвертим в ESF

Оффлайн Segaman

  • Пользователь
  • Сообщений: 3240
  • Пол: Мужской
  • Blast Processing!
    • Youtube
    • Просмотр профиля
Настройка SGDK
« Ответ #391 : 19 Сентябрь 2018, 16:14:27 »
короче с "note off" виноват конвертер xm2esf
он тупо игнорит на псг каналах эту ноут.
но вот глюк с инструментом пока не решен :-\

Оффлайн Segaman

  • Пользователь
  • Сообщений: 3240
  • Пол: Мужской
  • Blast Processing!
    • Youtube
    • Просмотр профиля
Настройка SGDK
« Ответ #392 : 27 Сентябрь 2018, 20:38:10 »
шлюк с инструментами решился добавлением в конец списка инструментов нескольких инструментов просто так :lol:
ибо иначе последние инструменты получают глюченные указатели, что и приводит к проблемам.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #393 : 24 Декабрь 2018, 22:40:02 »
Segaman, я проверил последний коммит SGDK и вроде всё исправлено с Z80/музыкой. Может кому-то ещё интересно.
Исправление было в этом коммите https://github.com/Stephane-D/SGDK/commit/82a4489c57d4534d2937ec90e1e711fb21a7b31b, ещё тогда заподозрил отсутствие volatile у некоторых переменных, но у меня не получилось исправить. Когда ошибка то появляется, то исчезает в зависимости от кода, который явно не участвует, то подозревать стоит оптимизации компилятора и volatile в частности.
Не забудьте собрать либу - build_lib.bat, как всегда.
« Последнее редактирование: 24 Декабрь 2018, 22:50:57 от Sharpnull »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #394 : 21 Январь 2019, 22:59:59 »
Не шарите, как быстро заполнить массивом тайлов экран ?

for(int i=0;i<40;i++)
{
for(int j=0;j<28;j++)
{
putTile(i,j,Type);
}
}

Что-то типа тайловой плазмы сделать (на самом деле хочу не только плазму, но начать с этого. Или хотя бы просто рандомом, только чтоб ФПС был порядка 60-ти).

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



А то когда делал это же на андроиде/ПК, по принципу блиттинга сортировать приоритет заколебался.
Тогда как на сеге нет постоянной перерисовки сцены с нуля.

Добавлено позже:
Попробую этот пример для тайлового рендерера.
https://github.com/Stephane-D/SGDK/wiki/Tuto-Background
« Последнее редактирование: 22 Январь 2019, 10:38:42 от ALKOSHA »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #395 : 22 Январь 2019, 04:32:19 »
ALKOSHA, если заранее заполнить VRAM данными тайлов (паттерн) (VDP_loadTileData(), VDP_loadTileSet()), а после менять на заранее рассчитанные тайлмэпы (VDP_setTileMapData(), VDP_setTileMapDataRect()), то должно быть максимально быстро, но даже так могут быть проблемы с полной сменой экрана, так как написано в документации:
Цитата
Transfert rate:
~90 bytes per scanline in software (during blanking)
~190 bytes per scanline in hardware (during blanking)
Но в этом я не уверен.

VDP_setTileMapData() умеет через DMA передавать, что должно быть быстрее, тогда экран нужно ставить шириной 256 и слой с тайлами также.
Я предполагаю, что нужно что-то типа этого (из видео):
205744-0

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #396 : 22 Январь 2019, 10:27:42 »
Я предполагаю, что нужно что-то типа этого

То для начала.
Хочу сделать рекастинг-движок на основе тайлов. (на полноценный вульфенштайн гасеги рассчитывать уже не стоит, ибо забил он на проект окончательно. И вроде бы продал сорсы Пико Интерактиву )
Очень впечатлила эта тема на ЗХ

Со стороны оно выглядит деревянно, но когда сам непосредственно гоняешь - очень даже круто ощущается шутан.

А теперь представьте это же, но с учётом сеговского железа. Вместо 32*24 тайла - 40*28. Вместо двух цветов на ячейку - 16.
+ дополнительный слой для имитации пола/потолка/"скайбокса", + аппаратные спрайты. Да и сам вывод тайлов аппаратный, тогда как на хз-спермыче каждый пиксель выводится усилиями проца.

Гипотетически должно смотреться очень круто.

Добавлено позже:
Только мне не совсем понятно, как тут автор сделал анимацию краёв  стен чётные/нечётные полосочки во время ходьбы.
Чтоб не было статично.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #397 : 22 Январь 2019, 15:06:31 »
Хочу сделать рекастинг-движок на основе тайлов
Я бы портировал например этот простой движок, а дальше смотрел что по скорости.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #398 : 23 Январь 2019, 08:15:17 »
Вчера просто попробовал в бесконечном цикле заполнять экран 40*28 VDP_setTileMapXY(PLAN_A, PAL0, i, j);
экран при старте единожды моргнул набором тайлов, после чего выдаёт чёрный экран смерти illegal instruction.


Не понял. 

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #399 : 23 Январь 2019, 09:43:52 »
ALKOSHA, может индексы не те и передавать нужно вторым аргументом информацию о тайле. Вот случайное заполнение красными тайлами (в начале VRAM sgdk добавляет 16 однородных тайлов, поэтому разные оттенки):
#include <genesis.h>

int main()
{
    SYS_disableInts();

    VDP_setScreenWidth320();
    VDP_setScreenHeight224();

    SYS_enableInts();

    while (TRUE)
    {
        VDP_showFPS(TRUE);
        for (int y = 0; y < 28; y++) {
            for (int x = 0; x < 40; x++) {
                u16 tileIndex = random() % 16;
                VDP_setTileMapXY(PLAN_B, TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, tileIndex), x, y);
            }
        }
        VDP_waitVSync();
    }

    return 0;
}
15 FPS :( Даже если вызывать random() один раз на кадр.
Вот так выдаёт 60 FPS, но здесь 256x224, если заполнять 64x28 тайлов, то будет 30 FPS. Если random() вызывать для каждого тайла - тоже 30 FPS:
#include <genesis.h>

u16 tileAttrs[32 * 28];

int main()
{
    SYS_disableInts();

    VDP_setScreenWidth256();
    VDP_setScreenHeight224();
    VDP_setPlanSize(32, 32);

    SYS_enableInts();

    while (TRUE)
    {
        VDP_showFPS(TRUE);
        u16 rand = random() % 16;
        for (int i = 0; i < 32 * 28; i++) {
            u16 tileIndex = (rand + i) % 16;
            tileAttrs[i] = TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, tileIndex);
        }
        VDP_setTileMapData(VDP_PLAN_B, tileAttrs, 0, 32 * 28, DMA_QUEUE);
        VDP_waitVSync();
    }

    return 0;
}
Если вместо DMA_QUEUE использовать DMA или CPU, видны разрывы экрана.
Я думал, что всё-таки будет 60 FPS для такого простого кода. Может знающие ASM и архитектуру сделают лучше.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #400 : 23 Январь 2019, 10:01:17 »
если заполнять 64x28 тайлов, то будет 30 FPS.

так ведь 64 тайла - это 512 пикселей. Зачем рисовать лишнее за пределами экранной области?

Кстать, похоже, что в Ред зоне фон крутится теми же самыми тайлами. Довольно плавно причём. В 320*224.
И, судя по всему, есть даже векторные (попиксельные) элементы (как например граница с водой, либо здания в виде полигональных кубиков).

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #401 : 23 Январь 2019, 11:48:15 »
так ведь 64 тайла - это 512 пикселей. Зачем рисовать лишнее за пределами экранной области?
Это если делать один вызов VDP_setTileMapData(), размер слоя 64x32, там же память должна идти линейно. Можно вызывать 28 раз по 40 тайлов и смотреть на скорость.

В Red Zone заранее рассчитанные тайлы. Попиксельно меняется только мини-карта. Вода + часть объектов на слое A, земля на слое B, у обоих при повороте приходится переставлять все тайлы и по-моему это делается не каждый кадр, вода точно каждый второй кадр обновляется при макс. скорости поворота. При перемещении вверх/вниз было бы необязательно переставлять тайлы, но вертолёт шатает, поэтому как минимум вода обновляется. Арки, которые кажутся трёхмерными, и большинство других объектов - просто спрайты. Вывод фактически в 256x224.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #402 : 23 Январь 2019, 11:58:35 »
Вывод фактически в 256x224.

А, ну да. Забыл, что справа ещё интерфейс.

 
Арки, которые кажутся трёхмерными, и большинство других объектов - просто спрайты.
Ну эт я в курсе. Однако параллакс стен внутри зданий - полигоны, как  мне кажется. Ещё внутри зданий 3 слоя этажей бывает местами, тоже довольно интересная фишка.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #403 : 23 Январь 2019, 12:50:39 »
ALKOSHA, я забыл, что MD поддерживает 3D полигоны. Возможно там и используются.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #404 : 23 Январь 2019, 13:19:57 »
что MD поддерживает 3D полигоны

"поддерживает" эт сильно сказано. Ведь для переброски хотя бы одного пиксела в позицию XY, процу нужно выполнить кучу лишних операций. бенчмарк в SGDK - предел оптимизации в этом плане, позволяет залить экран с филл-рейтом 15-20 кадров в секунду. И это при шакальном разрешении 256*160.

15 FPS  Даже если вызывать random() один раз на кадр.

я тут подумал, при такой дискретности даже 15-ти кадров должно хватить. Там, где для per-pixel вывода нужно 60 кадров, в потайловом выводе достаточно 60/8. Тем паче при трассировке стен зачастую одна треть экрана пустует (если не смотреть на стенку в упор). Так что, вполне неплохой результат, имхо.
Но оптимизация хотя бы до 30-ти кадров не будет лишней, конечно же.

Добавлено позже:
например этот простой движок
По объёму строк он вроде бы и прост.
Но некоторые ф-ции высокоуровневые JS непонятно как перенести в сишку.
К примеру ray = map.cast(player, player.direction + angle, this.range);
или
? inspect(stepX, 1, 0, origin.distance, stepX.y)
    : inspect(stepY, 0, 1, origin.distance, stepY.x);


и с JS я практически не знаком.


Тут тоже кажется простым на первый взгляд.

Но тоже есть свои подводные камни.
Как например класс векторов надо в массив структур переделать
vector<pair<float, float>> p;

Или как быть с этим?
sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; });

Уже готовая ф-ция сортировки.

 более доходчивые примеры пытаюсь найти.
« Последнее редактирование: 23 Январь 2019, 14:52:35 от ALKOSHA »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #405 : 23 Январь 2019, 15:40:01 »
ALKOSHA, там внизу статьи порты, например на Java.
К примеру ray = map.cast(player, player.direction + angle, this.range);
или
? inspect(stepX, 1, 0, origin.distance, stepX.y)
    : inspect(stepY, 0, 1, origin.distance, stepY.x);
map.cast - это метод у map, а inspect функция. Тернарный операция ?: работает как в C/C++. Да, в JS нужно привыкнуть к ООП через прототипы и функции и к замыканиям.
sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; });
Обычная функция сортировки: начало, конец и функция сравнения. В SGDK есть сортировка qsort(), но возможно придётся свою реализовать.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #406 : 23 Январь 2019, 15:55:18 »
ALKOSHA, там внизу статьи порты, например на Java.

О, это жы LibGDX.
На нём я нынче пишу Кровавого мяча под андроид/ПК. (сега-версия слишком утомила непредсказуемыми багами, поэтому решил, не пропадать же добру - перенесу на мобилки хотя бы)

https://vk.com/wall-145919754_381

https://vk.com/wall-145919754_229

https://vk.com/wall-145919754_278

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

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #407 : 23 Январь 2019, 16:08:55 »
ALKOSHA, посмотрел код с консолью, в принципе проблем не должно быть. Вместо sqrt для расчёта длины можно использовать упрощённое вычисление, в SGDK уже есть: u32 getApproximatedDistance (s32 dx, s32 dy).
vector там не нужен, всегда 4 элемента :lol:, а pair заменить на структуру.
pair<float, float> p[4];

// Test each corner of hit tile, storing the distance from
// the player, and the calculated dot product of the two rays
int i = 0;
for (int tx = 0; tx < 2; tx++)
    for (int ty = 0; ty < 2; ty++)
    {
        // Angle of corner to eye
        float vy = (float)nTestY + ty - fPlayerY;
        float vx = (float)nTestX + tx - fPlayerX;
        float d = sqrt(vx*vx + vy * vy);
        float dot = (fEyeX * vx / d) + (fEyeY * vy / d);
        p[i] = make_pair(d, dot); //.push_back(make_pair(d, dot));
        i++;
    }

// Sort Pairs from closest to farthest
sort(&p[0], &p[4], [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; });

// First two/three are closest (we will never see all four)
float fBound = 0.01f;
if (acos(p[0].second) < fBound) bBoundary = true;
if (acos(p[1].second) < fBound) bBoundary = true;
if (acos(p[2].second) < fBound) bBoundary = true;
--------
Ошибся с sort(&p[0], &p[4], здесь второй аргумент это элемент после последнего.
« Последнее редактирование: 23 Январь 2019, 16:22:40 от Sharpnull »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #408 : 23 Январь 2019, 20:44:33 »
Попробовал реализовать этот код из видео, оказалось что там вместо нормального вычисления шага для проверки стены, делается шаг постоянный 0.1, что медленно, а если его увеличить до 1.0, будет 30 FPS на 256x224, но тогда будут неточные высоты. В общем, лучше код из моего примера реализовывать.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #409 : 24 Январь 2019, 09:36:58 »
Если вместо DMA_QUEUE использовать DMA или CPU, видны разрывы экрана.
Я думал, что всё-таки будет 60 FPS для такого простого кода. Может знающие ASM и архитектуру сделают лучше.

А если перед циклом рендеринга отрубить прерывания? Может побыстрее будет?

Я проверить смогу только вечером.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #410 : 24 Январь 2019, 13:46:54 »
ALKOSHA, я не понял о каком коде речь, в том примере, если изменить на CPU разрывы не уйдут и будет даже меньше FPS - 56.2:
VDP_showFPS(TRUE);
SYS_disableInts();
u16 rand = random() % 16;
for (int i = 0; i < 32 * 28; i++) {
    u16 tileIndex = (rand + i) % 16;
    tileAttrs[i] = TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, tileIndex);
}
VDP_setTileMapData(VDP_PLAN_B, tileAttrs, 0, 32 * 28, CPU);
SYS_enableInts();
VDP_waitVSync();
Я так и не узнал, что будет, если не отключать прерывания во время доступа к VDP. Может только на реальном железе заметно.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #411 : 24 Январь 2019, 20:56:37 »
Если чё, там ф-ция рандома неоптимизированная.
http://gendev.spritesmind.net/forum/viewtopic.php?f=19&t=2968

Добавлено позже:
Вот только как бы это линейное заполнение преобразовать в X Y ?
  *dst++ = TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, rand() & 0xF);
« Последнее редактирование: 24 Январь 2019, 21:15:52 от ALKOSHA »

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #412 : 25 Январь 2019, 11:07:46 »
u16 x,y;

x=10;
y=10;

dst = x*y;

эмм.. .пытаюсь сообразить.. ээ.. там же  24 неиспользующихся тайла за экраном.
поэтому...  :shifty: щас...
dst = x*y*24 ? Не... чёт многовато, мне кажется.
Думай, галава, думай.  :wall:
если
Y
равен 1
то
dst = x+y+24;
 да?
или...
dst= x+y+24*y;
« Последнее редактирование: 25 Январь 2019, 11:36:49 от ALKOSHA »

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2536
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
Настройка SGDK
« Ответ #413 : 25 Январь 2019, 11:32:01 »
в моем случае экран это 64х28 тайлов. для чтения их нумеров тайлов используется массив в массиве и соответственно два цикла. не знаю есть ли в твоей среде разработки сложные массивы...

Structure constr
  Y.l[28]
EndStructure
Global Dim CoordX.constr(64)

; в итоге это выглядит примерно так

CoordX(5)\Y[5] = 123 ; типа в координатах 5:5 рисовать номер 123

; чтение
If ReadFile(#File, PathFile$)
 
 
  For y = 1 To 28   ; y выше так как построчно х1, х2, х3... y+1, x1, x2...
    For x = 1 To 64
      CoordX(5)\Y[5] = ReadUnicodeCharacter(#File)
    Next
  Next
 
  CloseFile(#File)
EndIf

; но это случай, когда весь экран на 64 по х забитый.
; там просто начиная с 41 нули

; в твоем случае должно быть что-то типа:
dst = y * 64 + x

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
Настройка SGDK
« Ответ #414 : 29 Январь 2019, 22:25:19 »
Моё видение тайлового рейкастинга на СМД.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5127
    • Просмотр профиля
Настройка SGDK
« Ответ #415 : 30 Январь 2019, 12:11:09 »
ALKOSHA, вот код того парня с ютюба. Он там к тому же перепутал синусы и косинусы, но всё работало правильно, так как и карта, и углы были в другую сторону. Теперь карта записанная в коде отображается на обычную координатную плоскость: ноль слева внизу, x - вправо, y - вверх. Исправления от "рыбьего глаза" добавил. Всё ещё нужно определять stepX, stepY, так как из-за шага в 0.1 и дальности 16 происходит 160 проверок на одну колонку и FPS может падать до 8. Если шаг увеличить - fStepSize, то расстояния будут с большой погрешностью. В книге Game Engine Black Book: Wolfenstein 3D есть про рейкастинг, но не очень подробно, автор реализовал вульфа под винду (код рейкастинга), но там код сложнее чем у A first-person engine in 265 lines (нужный код в Map.prototype.cast = function(point, angle, range)).
Напомню, что в SGDK у sin/cos входные значения от 0 до 1023 (0 - 2PI). У Fusion скорость эмуляции выше, чем в других эмуляторах, так что нужно ориентироваться на другие.

Оффлайн Skay

  • Пользователь
  • Сообщений: 4120
  • Пол: Мужской
    • Просмотр профиля
Настройка SGDK
« Ответ #416 : 30 Январь 2019, 12:38:05 »
В книге Game Engine Black Book: Wolfenstein 3D есть про рейкастинг, но не очень подробно
про рейкастинг вроде бы неплохо рассказывается у Е.В. Шишкин, А.В. Боресков - Компьютерная графика - 2001 (по матчасти лучше и более полного руководства, с таким уровнем вхождения не встречал), там и теория и тоже на примере волфстейна, дума
« Последнее редактирование: 30 Январь 2019, 12:46:43 от Skay »

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
Настройка SGDK
« Ответ #417 : 30 Январь 2019, 14:24:06 »
вот код того парня с ютюба
Работает прыкольна :) но фпс маловато, наверное не обойтись без уменьшения области рендера, да и без текстур все как то грустно.

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
Re: Настройка SGDK
« Ответ #418 : 30 Январь 2019, 15:23:32 »
Работает прыкольна :) но фпс маловато, наверное не обойтись без уменьшения области рендера, да и без текстур все как то грустно.
Ну тут уж ничего не поделаешь - не тянет сежка псевдо 3д на адекватном уровне. Лучше играть в качественные 2д игры, чем в пиксельное слайд-шоу.

Оффлайн SPOT

  • Пользователь
  • Сообщений: 574
    • Просмотр профиля
Настройка SGDK
« Ответ #419 : 30 Январь 2019, 18:29:50 »
Помню KRIKzz делал рейкастинг и вроде бы даже были какие-то исходники.