Автор Тема: PVSnesLib (библиотека для разработки игр под SNES на языке C)  (Прочитано 4465 раз)

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

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
Взбрело мне, значит, в голову пощупать SNES - начал гуглить. Наткнулся на некий аналог SGDK. В настройке прост, все демки собираются без ошибок (редкость для такого искателя новых ощущений, как я).

Ссылка на библиотеку

Пока все, что у меня  получается - это вывести глючную половину картинки на экран и поглумиться над hello, world'ом, вписав туда слово sega :lol:
« Последнее редактирование: 24 Апрель 2018, 19:01:50 от worm »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
На сеге подобное обусловлено нехваткой вдп или выделенной памяти, но снес - это не сега и по части видео она должна тащить.
У сеги и снес по 64KB VRAM. Скорее всего вы просто съели всю VRAM, потому что видно, что на картинке много цветов, а тайлы не повторяются. Даже в Ultimate Mortal Kombat 3 на SNES такое красивое лого не выводят, а используют более скромное (либо просто из-за размеров).
Если выложите исходник, сразу всё станет понятно.
« Последнее редактирование: 25 Апрель 2018, 01:12:57 от Sharpnull »

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
У сеги и снес по 64KB VRAM.
Спасибо, что пролили свет на истину. Я всегда думал, что снес - это очень мощная махина, которая превосходит сежку как минимум в 2 раза. :(

Скорее всего вы просто съели всю VRAM
Выходит, что так. Моему разочерованию нет предела :lol:

Если выложите исходник, сразу всё станет понятно.
Я использую код демки СДК, вывод изображения по 3-му режиму, вот ее код...
#include <snes.h>

extern char patterns,patterns1,patterns1_end;
extern char palette;
extern char map, map_end;

//---------------------------------------------------------------------------------
int main(void) {
    // Initialize SNES
consoleInit();

// Read tiles to VRAM in 2 phases because we are more than 32k
bgInitTileSet(0, &patterns, &palette, 0, 0x8000, 256*2, BG_256COLORS, 0x0000);
WaitForVBlank();
dmaCopyVram(&patterns1, 0x4000, (&patterns1_end-&patterns1));

// Copy Map to VRAM
bgInitMapSet(0, &map, (&map_end - &map),SC_32x32, 0x6000);

// Now Put in 256 color mode and disable other BGs except 1st one
setMode(BG_MODE3,0);; bgSetDisable(1);
setScreenOn();

// Wait for nothing :P
while(1) {
WaitForVBlank();
}
return 0;
}

Кстати, довольно странный этот СДК - теперь если я пытаюсь прилепить свой 256-цветный bmp, то компилятор выдает
data.asm:5: INCBIN_FILE: Overreading file "pvsneslib.pic".
data.asm:5: ERROR: Couldn't parse ".incbin".

Ранее такого не наблюдалось - может руки стали еще более кривыми? :lol:

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
worm, код такой же значит. Пример с оригинальной картинкой правильно выводился? Я предположил что съедается VRAM, но вообще её должно хватить на отображение картинки, остаётся вариант с форматом картинки.
Про ошибку, может нужно сделать make clean? Там как раз удаление этих файлов: @rm -f $(OFILES) $(TARGET).sfc *.pic *.pal *.map
Установил SDK, bmp должен быть без сжатия.
--------
Всё ещё хуже, этот криворукий SDK чувствителен к формату bmp, нужно как-то специфически подготавливать файл.
« Последнее редактирование: 25 Апрель 2018, 10:39:18 от Sharpnull »

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
bmp должен быть без сжатия
Разве у bitmap есть сжатие? Ни одна графическая программа, что я знаю, не показывает параметры сжатия bmp перед output'ом изображения. Как же ее "разжать"?

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
worm, проблема не только с сжатием. Но если что, фотошоп при сохранении даёт опцию Compress (RLE). В XnView можно изменять настройку сохранения тоже.
Проблема глубже, я беру файл из примера, открывают в фотошопе. Рисую тонкую линию карандашом из цвета, который уже есть в файл. Сохраняю/компилирую, не отображается несколько тайлов внизу. Снова редактирую в фотошопе, теперь рисую большой прямоугольник из того же цвета. Сохраняю, но уже не компилируется. В общем, ему важен набор тайлов. Я сначала думал проблема в метаданных (размер при печати), но это не так.
--------
Может это нормальное поведение и нужно просто читать спецификацию :)
« Последнее редактирование: 25 Апрель 2018, 11:05:13 от Sharpnull »

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
фотошоп при сохранении даёт опцию Compress (RLE)
Это видел, но она была выключена изначально, что и сбило меня с толку.

В общем, ему важен набор тайлов.
Иными словами, я вляпался в кое-что нехорошее (образно, конечно, не в адрес СДК - скорее, самоирония) :lol:

Сейчас попробую нарисовать картинку из нескольких одинаковых тайлов...

upd. нет. нарисовал ему pixel-perfect картинку, все равно недоволен. Ошибка и все тут.

Ладно, может со временем прояснится ситуация. Будет здорово, если людей заинтересует эта библиотека и тема разовьется.
« Последнее редактирование: 25 Апрель 2018, 11:18:38 от worm »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
worm, можно не мучиться с bmp, в Makefile изменить pvsneslib.bmp на pvsneslib.png и -fbmp на -fpng здесь:
pvsneslib.pic: pvsneslib.bmp
@echo convert bitmap ... $(notdir $@)
$(GFXCONV) -pc256 -n -gs8 -pe0 -fbmp -m $<
Там сжатие поддерживается, но такой же печальный результат, если картинка неверно сформирована.

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
такой же печальный результат, если картинка неверно сформирована.
Напишу автору библиотеки на гитхаб. Интересно, чем он рисует.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
worm, судя по скрину из https://github.com/alekmaul/pvsneslib/wiki/Sprites он рисует в GraphicsGale.

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
worm, судя по скрину из https://github.com/alekmaul/pvsneslib/wiki/Sprites он рисует в GraphicsGale.
И на ней как раз очень убогая индексация изображений :( Хотя можно в ней переиндексировать уже готовый вариант...
upd. и она тоже неподходящий формат выдает.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
worm, я разобрался. В общем, если тайлов (разных) мало в файле, то размер pvsneslib.pic меньше 32KB, а в data.asm идёт разбивка на два каких-то раздела. Если файл меньше 32KB, нужно в data.asm написать такое, по аналогии из Mode1Png:
.include "hdr.asm"

.section ".rodata1" superfree

patterns: .incbin "pvsneslib.pic"
patterns_end:

.ends

.section ".rodata2" superfree

map: .incbin "pvsneslib.map"
map_end:

palette: .incbin "pvsneslib.pal"

.ends
И такой код Mode3.c:
#include <snes.h>

extern char patterns,patterns_end;
extern char palette;
extern char map, map_end;

//---------------------------------------------------------------------------------
int main(void) {
    // Initialize SNES
consoleInit();

bgInitTileSet(0, &patterns, &palette, 0, (&patterns_end - &patterns), 256*2, BG_256COLORS, 0x0000);

// Copy Map to VRAM
bgInitMapSet(0, &map, (&map_end - &map),SC_32x32, 0x6000);

// Now Put in 256 color mode and disable other BGs except 1st one
setMode(BG_MODE3,0);; bgSetDisable(1);
setScreenOn();

// Wait for nothing :P
while(1) {
WaitForVBlank();
}
return 0;
}
Если файл больше 32KB, то оставляете как было, но вместо 6976 в data.asm:
patterns1: .incbin "pvsneslib.pic" skip 32768 read 6976вставляете: N - 32768, где N - размер файла pvsneslib.pic, который получите после make clean, make.
--------
То есть нужно подбирать под каждую картинку размер в data.asm :)
--------
По-моему rodata2 и rodata3 можно заменить на rodata1 и rodata2.
SGDK всё-таки попроще будет, там не заставляют делать такие непристойности.

--------

Пара замечаний по установке PVSnesLib:
Если Python 2 уже установлен по пути с пробелами, шебанг не позволяет вставлять такие пути, то можно просто скопировать папку с установленным Python в место без пробелов, например в ту же папку с PVSnesLib.
Прописывать msys/bin в PATH необязательно, даже не стоит, потому что у меня возник конфликт с другими SDK. Я просто создал bat-файл где написал:
SET PATH=C:\snesdev\msys\bin
C:\Windows\System32\cmd.exe
Таким образом устанавливается путь и убираются остальные пути, конечно это работает только в пределах этой консоли.

--------
Обновил код для файла с картинкой меньше 32KB, почти как в Mode1Png, только размер палитры (256*2) вводится вручную, и особенности режима Mode3.
« Последнее редактирование: 25 Апрель 2018, 14:08:15 от Sharpnull »

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
И правда - когда пихаешь жирный файл с кучей разных тайлов, компилится без проблем.
Спасибо :) Надеюсь, что в будущем, разраб автоматизирует это дело...

upd. я так понимаю, что у снес еще меньше VDP, чем у сеги. Одну и ту же картинку выставил на снес и на сеге. 16 и 16 цветов. При том, что я обрезал часть изображения для снес, чтобы подходило под 256x224, снес все равно загрузила ее неполноценно, сега же справилась без проблем. Единственное, чем снес порадовала - палитра. По части палитры сеге со снес действительно не тягаться :)
« Последнее редактирование: 25 Апрель 2018, 16:48:23 от worm »

Оффлайн gegmopo3

  • Пользователь
  • Сообщений: 196
  • Пол: Мужской
  • sk8
    • Просмотр профиля
Пол картинки занимает больше 32 кб, а DMA за один сканлайн может отправить только 32 кб (0x8000), по тому и картинка не корректна.
По мне, так лучше на асме писать, и код твой и оптимизировано, а то после С, он такой хлам не нужный выдает. Если дебажить начинаешь, то охота плакать.
VPD такой же, как у сеги, 64кб. Но в сеги в VPD еще таблица спрайтов хранится, а вот в снес ее нет (в врам), так-что на несколько сот байт больше.

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
По мне, так лучше на асме писать
Это, конечно, в идеале, но С примечателен тем, что универсален и чертовски удобен (в ущерб оптимизации, правда  :( )

Если дебажить начинаешь, то охота плакать.
Все верно. Я, к примеру когда свои SGDK ромы вскрываю ради любопытства, начинаю фейспалмить...

Новая платформа для изучения - это всегда новый мир неизведанного. Все таки язык С не зря придумали. Да, он генерит ужасный код, полный мусора и костылей, но все же это работает, да и разрабам игр легче - не нужно 100500 асмов учить  :lol:

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5111
    • Просмотр профиля
он генерит ужасный код
Не он.

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
Не он.
Генерит то он, а вот код для этой генерации уже пишет "прекрасный" программист :lol:

Оффлайн Werton

  • Пользователь
  • Сообщений: 884
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
Генерит то он
Или все-таки компилятор?

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
Что-то автор забросил библиотеку свою - печально... :(

Или все-таки компилятор?
По словам многих моих знакомых программистов, сейчас компиляторы генерят такой крутой код, что не каждый программист так сможет написать. В особенности, хвалят C++. Один мой друг на нем даже игру на сегу писать начал, а был заядлым приверженцем ассемблера.

Оффлайн megavolt85

  • Пользователь
  • Сообщений: 1464
  • Пол: Мужской
    • Просмотр профиля
worm, да компиляторы конечно сейчас на высоте, но зачастую невозможно написать всё на сях или си++, как ни крути но без асмы никак
ну и для ретро консолей С++ не лучший выбор, не берусь говорить за все консоли, но CPP компиляторы для megadrive и dreamcast убоги и лучше их не использовать

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
зачастую невозможно написать всё на сях или си++
Что ты имеешь в виду? Структура языка не позволяет применять некоторые "манёвры", доступные только асму или просто дело в скорости?

Оффлайн megavolt85

  • Пользователь
  • Сообщений: 1464
  • Пол: Мужской
    • Просмотр профиля
worm, да тут ка бы оба фактора играют свою роль, в случае когда надо выдержать тайминги асма просто не заменима, ну и с "манёврами" есть порой заморочки, взять к примеру тот же HDD загрузчик для дримкаста, он напополам написан на асме, и все те финты что творятся в ассемблерной части просто не реально воссоздать на языке более высокого уровня
ну к примеру есть две практически идентичных функции, разница между ними минимальна, я просто беру и размещаю всю разницу  несколькими асмовыми командами и делаю прыжок на вторую, в случае с сями мой код разросся бы по самое мама не горюй, и влезть в отведённые 16 килобайт было бы проблематично

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

.align 2
_gd_pioread_stream:
mov #0, r0
mov.l r0, @(8, r4)
_gd_pioread_stream2:
mov #0, r1
mov #4, r6
mov #80, r0

mov.l r1, @(r0, r5)
add #4, r0
mov.l r1, @(r0, r5)

mov.l r6, @(4, r5)
mov.l @(4, r4), r0
shll8 r0
shll2 r0
shll r0
mov.l r0, @(56, r5)

mov.l .gd_execute_cmd_pio_adress, r0
jmp @r0
mov r5, r4

.align 2
.gd_execute_cmd_pio_adress:
.long _pio_stream_internal
« Последнее редактирование: 27 Октябрь 2019, 20:29:55 от megavolt85 »

Оффлайн Takamura-kun

  • Пользователь
  • Сообщений: 1091
  • Пол: Мужской
  • Закалён и плечист.
    • ВКонтакте
    • Просмотр профиля
megavolt85, аа, это да - сам иногда вскрываю ром и поражаюсь, нафига эта тонна кода, когда можно написать в 3 раза компактнее, просто используя кусок дополнительного кода в 2-3 инструкции) и компактно и быстрее в выполнении.