Разработка и ромхакинг > Ромхакинг и программирование
SGDK
<< < (20/40) > >>
bgr:
ALKOSHA, можешь что-нибудь про успехи в проектах рассказать?
Sharpnull:
ALKOSHA, что-то явно осталось, если упоминается jaws.o. Попробуйте в командой строке в папке проекта написать:

--- Код: ---%GDK_WIN%\bin\make -f %GDK_WIN%\makefile.gen clean
%GDK_WIN%\bin\make -f %GDK_WIN%\makefile.gen
--- Конец кода ---
Первая строка удалит лишние объектные файлы (*.o), вторая скомпилирует проект. Если ошибок не будет, а Code::Blocks будет ругаться, то что-то с ним не так.
worm:

--- Цитата: Sharpnull от 14 Июнь 2018, 00:14:19 ---что-то явно осталось, если упоминается jaws.o

--- Конец цитаты ---
Вот поэтому у меня каждая компиляция с чистого листа происходит. Без этого бывало такое, что поменяешь, к примеру, координаты спрайта, а в итоговом роме нчего не меняется. Почистил проект, собрал - все четко. Да и вообще, батники - наше все :D
Sharpnull:
worm, я замечал два случая: когда меняется .h-файл, когда меняется ресурс. В обоих случаях компилятор не видит изменения и оставляет старый объектный файл. Каждый раз чистить проект может быть долго.

На счёт jaws. По идее в Code::Blocks должна быть задана та же команда очистки, так что грешу на него.
ALKOSHA:

--- Цитата: bgr от 13 Июнь 2018, 22:14:47 --- можешь что-нибудь про успехи в проектах рассказать?
--- Конец цитаты ---


Нет таковых. Я НЕкодер от природы. Тяжко мне даётся это дело.
Segaman:
Кто-нить знает, почему последняя версия SGDK незапускает нормально звуковые драйвера?
Все дравины грузятся, но молчат, кроме XGM. этот вообще уводит в вечное ожидание инициализации, а в это время Z80 самовыпиливает свою память. :ohmy:

Добавлено позже:
sound.res

--- Код: ---XGM bgmInGame "Switchblade1.vgm.xgm"
XGM bgmDemo "bad_apple_pcm.vgm"

--- Конец кода ---

main.c

--- Код: ---int main()
{
VDP_setScreenWidth256();

VDP_drawText("Hello Genny World!", 10, 13);

    SND_startPlay_XGM( bgmInGame );

while(1)
{
//read input
//move sprite
//update score
//draw current screen (logo, start screen, settings, game, gameover, credits...)

//wait for screen refresh
VDP_waitVSync();
}

return (0);
}

--- Конец кода ---

Добавлено позже:
Я пробовал XGM и VGM
Обе уводят в переполнение стека

SGDK 1.34 (January 2018)

Добавлено позже:
вот версия SGDK 1.22a (September 2016) работает нормально, но на ней дольше собирается проект, плюс куча неприятных ошибок типа "надо определять переменные вне цикла for" и тп
попробовал SGDK 1.32 (October 2017) - тоже уходит в переполнение
Sharpnull:
Segaman,
Пара замечаний:
* Для VGM и XGM лучше использовать аналогичные функции из xgm.h, так как SND_startPlay_XGM() и прочие указаны как deprecated в документации.
* Лучше не использовать название sound.res, так как генерируется sound.h, а такой файл уже есть в SGDK, хотя компилируется нормально.

Посмотрел примеры из SGDK и выяснил, что если запускать в joyEvent, то проблем нет. Причём если написать вызов одной из функций XGM_* в joyEvent (например XGM_isPlaying(); ), то сразу будет работать ваш вызов XGM_startPlay() перед while (1).

Может баг, а может особенность архитектуры. Версия из github с таким же поведением.

Также, без использования XGM_set68KBUSProtection() остановка будет со звуковыми искажениями. Подробнее читайте в документации, не знаю почему.

Вот готовый пример, где музыка играет сразу и останавливается/воспроизводится по нажатию A (тестировал только sor2.xgm из SGDK):

--- Код: ---// main.c
#include <genesis.h>
#include "resources.h"

static void vintEvent();
static void joyEvent(u16 joy, u16 changed, u16 state);

int main()
{
    JOY_setEventHandler(joyEvent);
    VDP_setScreenWidth256();
    VDP_setHInterrupt(0);
    VDP_setHilightShadow(0);
    SYS_setVIntCallback(vintEvent);

    VDP_drawText("Hello Genny World!", 10, 13);

    XGM_startPlay(bgmInGame);

    while (TRUE)
    {
        VDP_waitVSync();
    }

    return 0;
}

static void vintEvent()
{
    u16 in;

    // set BUS protection for XGM driver
    XGM_set68KBUSProtection(TRUE);

    in = GET_VCOUNTER;

    if ((in >= 224) && (in <= 230))
    {
        // u16 i;
        // switch(dmaMethod)
        // {
            // case 1:
                DMA_doDma(VDP_DMA_VRAM, 0, 0x8000, (6 * 1024) / 2, 2);
                //break;

            // case 2:
                // for(i = 0; i < 6; i++)
                // {
                    // DMA_doDma(VDP_DMA_VRAM, 0, 0x8000, 1024 / 2, 2);
                    // waitSubTick(1);
                // }
                // break;

            // case 3:
                // for(i = 0; i < 16; i++)
                // {
                    // DMA_doDma(VDP_DMA_VRAM, 0, 0x8000, 256 / 2, 2);
                    // waitSubTick(1);
                // }
                // break;
        // }
    }

    // remove BUS protection for XGM driver
    XGM_set68KBUSProtection(FALSE);
}

static void joyEvent(u16 joy, u16 changed, u16 state)
{
    if (changed & state & BUTTON_A)
    {
        if (XGM_isPlaying()) XGM_stopPlay();
        else XGM_startPlay(bgmInGame);
    }
}
--- Конец кода ---
--------
Если joyEvent не нужен, можно написать:

--- Код: ---static void joyEvent(u16 joy, u16 changed, u16 state)
{
    XGM_isPlaying();
}
--- Конец кода ---
Костыль, но работает. Конечно нужна проверка в нескольких эмуляторах и на железе.
Segaman:
у меня XGM всё равно самовыпиливается после загрузки в Z80  :-\

Добавлено позже:
вот здесь вроде пишут про различия в драйверах, хоть код и идентичен, всё равно ничего не работает, даже когда я гружу дравину вручную.
разве что после последнего дравина не уходит сразу в харакири, а только после вызова startPlay_XGM :neznayu:
Sharpnull:
Segaman, напишите об ошибке на гитхаб. Что интересно, пример что я кидал, при убирании коллбека джоя, работает в Fusion, но не работает в старом Gens. Может у них всё работает, потому что пользуются определёнными эмуляторами и может на железе также работает. Баг явно есть, в исходниках ассемблер, без спецов не разобраться.
--------
Можете ещё попробовать заменить старые файлы для работы с Z80, если повезёт и не будет конфликта. После замены либу нужно пересобрать build_lib.bat.
Segaman:
Sharpnull, я уже заюзал движок Echo :lol:
Segaman:
Кто-нить работал с движком Echo?
тут такое дело, не можем заставить PSG функционировать корректно.
note off не работает почему-то, а инструменты вообще эмулятор крашат.
юзали инструменты из демки, вроде

--- Код: ---Instr_PSGFlat:
    dc.b    $FE,$00,$FF
--- Конец кода ---
Но не помогло. Эмуль Regen, на Kega просто артефакты и путаница каналов PSG с FM.
Музен делаем в XM а потом конвертим в ESF
Segaman:
короче с "note off" виноват конвертер xm2esf
он тупо игнорит на псг каналах эту ноут.
но вот глюк с инструментом пока не решен :-\
Segaman:
шлюк с инструментами решился добавлением в конец списка инструментов нескольких инструментов просто так :lol:
ибо иначе последние инструменты получают глюченные указатели, что и приводит к проблемам.
Sharpnull:
Segaman, я проверил последний коммит SGDK и вроде всё исправлено с Z80/музыкой. Может кому-то ещё интересно.
Исправление было в этом коммите https://github.com/Stephane-D/SGDK/commit/82a4489c57d4534d2937ec90e1e711fb21a7b31b, ещё тогда заподозрил отсутствие volatile у некоторых переменных, но у меня не получилось исправить. Когда ошибка то появляется, то исчезает в зависимости от кода, который явно не участвует, то подозревать стоит оптимизации компилятора и volatile в частности.
Не забудьте собрать либу - build_lib.bat, как всегда.
ALKOSHA:
Не шарите, как быстро заполнить массивом тайлов экран ?

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
Sharpnull:
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 и слой с тайлами также.
Я предполагаю, что нужно что-то типа этого (из видео):
ALKOSHA:

--- Цитата: Sharpnull от 22 Январь 2019, 04:32:19 ---Я предполагаю, что нужно что-то типа этого
--- Конец цитаты ---

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

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

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

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

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

--- Цитата: ALKOSHA от 22 Январь 2019, 10:27:42 ---Хочу сделать рекастинг-движок на основе тайлов
--- Конец цитаты ---
Я бы портировал например этот простой движок, а дальше смотрел что по скорости.
ALKOSHA:
Вчера просто попробовал в бесконечном цикле заполнять экран 40*28 VDP_setTileMapXY(PLAN_A, PAL0, i, j);
экран при старте единожды моргнул набором тайлов, после чего выдаёт чёрный экран смерти illegal instruction.


Не понял. 
Sharpnull:
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 и архитектуру сделают лучше.
Навигация
Главная страница сообщений
Следующая страница
Предыдущая страница

Перейти к полной версии