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