Автор Тема: [SMD] Палитра в Genesis  (Прочитано 1384 раз)

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

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« : 28 Октябрь 2022, 22:48:50 »
Здравствуйте! Назрел вопрос по поводу палитры на SMD/Genesis.

Прочитав в интернете информацию выяснил следующее:
- Формат палитры 9bit RGB;
- Палитра хранится в CRAM VDP;
- Цвет в палитре имеет формат: uint16 0000BBB0GGG0RRR0;

Запустил Gens Tracer, открыл ROM, нажал `.`, сдампил CRAM, RAM, SRAM, VRAM, VSRAM.

Открываю CRAM в хексе, вижу следующее:

253061-0

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

В хексе это 0x0888
В бинаре это 0000 100 0 100 0 100 0

Соответственно получаем:

R: 100 (4)
G: 100 (4)
B: 100 (4)

Проверил палитру в Tile Molester, он показывает на этом цвете 128 128 128. Где я что не так понимаю?

253063-1
« Последнее редактирование: 29 Октябрь 2022, 13:39:30 от bqio »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #1 : 29 Октябрь 2022, 00:22:53 »
На 32 (0x20) умножить надо, потому что 3 бита отображают значения от 0 до 255. В эмуляторах могут делать поярче, потому что 7*32=224, а не чистый 255.

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2538
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #2 : 29 Октябрь 2022, 09:20:24 »
картинки не показывает :( чтоб тебе икалось за то как ты картинки в текст вставлял...

палитра это 2 байта (это не точно, я давно уже не в теме). типа 0BGR. вот берем и потом превращаем эти по отдельности B, G и R в нормальный RGB:
    Select inp
      Case 0
        out = 0
      Case 2
        out = 36
      Case 4
        out = 72
      Case 6
        out = 109
      Case 8
        out = 145
      Case $A
        out = 181
      Case $C
        out = 219
      Case $E
        out = 255
    EndSelect

где взял соответствие цветов - не знаю. кто-то давал... не помню уже. так что точность передачи цвета тоже из разряда: это не точно :)

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #3 : 29 Октябрь 2022, 12:44:41 »
где взял соответствие цветов - не знаю
Это обычное линейное отображение с отбрасыванием дробной части: floor(255/7*index), только 181 и 219 не совпадают (182 и 218). Вообще, близкие к реальным значениям нелинейные https://gendev.spritesmind.net/forum/viewtopic.php?t=2188:
Nonlinear levels derived from hardware measurements :
Normal :   0  52  87 116 144 172 206 255
Shadow :   0  29  52  70  87 101 116 130
HiLite : 130 144 158 172 187 206 228 255
Там ещё варианты и линейная запись как 0 36 72 108 144 180 216 252/255. Кому как нравится.
В Genesis Plus GX получается вообще 0 34 68 102 136 170 204 238.

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #4 : 29 Октябрь 2022, 13:12:38 »
То есть значения цветов будут разниться в зависимости от окружения (эмулятора)?

В моём случае вообще такая формула выходит:

r = (i >> 1) & 7;
g = (i >> 5) & 7;
b = (i >> 9) & 7;

Genesis Save State Viewer вообще 146 показывает...

253059-0
« Последнее редактирование: 29 Октябрь 2022, 13:35:41 от bqio »

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1186
    • ВКонтакте
    • Steam
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #5 : 29 Октябрь 2022, 15:15:16 »
Замудрёная палитра Сеги была одной из причин создания темы "Вопросы новичков" :lol:

Оффлайн SPOT

  • Пользователь
  • Сообщений: 574
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #6 : 29 Октябрь 2022, 18:07:22 »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #7 : 29 Октябрь 2022, 19:58:38 »
Sega MegaDrive палитра
У вас там вообще написано, что 12 бит, а не 9 бит.

Посмотрел документацию (https://segaretro.org/Mega_Drive_official_documentation), там нарисовали нелинейный график и долбитесь как хотите:
253079-0
UPD: Они его похоже от балды нарисовали, по оси X криво, а по Y два первых перехода по 48 пикселей, а остальные по 61/62 :) Пытались видимо показать линейно.

Добавлено позже:
Открываю CRAM в хексе, вижу следующее:
Порядок байтов у вас неверный в CRAM (GR 0B, а должно быть 0B GR) и размер должен быть 0x80 (128) байт (не знаю почему у Gens больше, VSRAM впихнуть могли). Это из-за создателя Gens, который для удобства везде менял порядок байтов, теперь эта путаница везде встречается и в некоторых форках Gens могли исправить.
UPD3: Посмотрел CRAM в BizHawk, они там накосячили и выводят белый цвет (0E EE) как 01 FF. Похоже объединили биты и получилось 0000 000B BBGG GRRR.
« Последнее редактирование: 29 Октябрь 2022, 20:34:03 от Sharpnull »

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #8 : 10 Март 2023, 14:47:30 »
Порядок байтов у вас неверный в CRAM (GR 0B, а должно быть 0B GR) и размер должен быть 0x80 (128) байт (не знаю почему у Gens больше, VSRAM впихнуть могли). Это из-за создателя Gens, который для удобства везде менял порядок байтов, теперь эта путаница везде встречается и в некоторых форках Gens могли исправить.
UPD3: Посмотрел CRAM в BizHawk, они там накосячили и выводят белый цвет (0E EE) как 01 FF. Похоже объединили биты и получилось 0000 000B BBGG GRRR.
Так какой лучше эмулятор использовать для корректного дампа CRAM и VRAM?

Regen вроде правильный порядок дампит уже. Размер правда, всё также, 512 байт, вместо 128.
« Последнее редактирование: 10 Март 2023, 15:07:37 от bqio »

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

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #9 : 10 Март 2023, 15:52:46 »
Gens by Shell. У него правильная палитра, а ещё он может дампить палитру в формате RGB888.

Добавлено позже:
Regen вроде правильный порядок дампит уже. Размер правда, всё также, 512 байт, вместо 128
Потому что размер CRAM 512 байт

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
Re: [SMD] Палитра в Genesis
« Ответ #10 : 10 Март 2023, 15:55:32 »
Как-то так вышло в итоге. Ничего не упустил?

https://gist.github.com/bqio/768a7bb9a805c9c45c614b27aef82cf4

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

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #11 : 10 Март 2023, 16:12:42 »
У меня вот так
      rgbBlue:= (Value shr 4) and $F0;
      rgbGreen:= Value and $F0;
      rgbRed:= (Value shl 4) and $F0;
Никаких лишних констант.

Добавлено позже:
Хотя там должно быть and $E0. Как-то проглядел этот момент.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #12 : 10 Март 2023, 16:25:26 »
Потому что размер CRAM 512 байт
С вами не согласны BizHawk (Genesis Plus GX), MAME, а также руководство (https://segaretro.org/index.php?title=File%3AGenesis_Software_Manual.pdf&page=29): "The CRAM contains 128 bytes".
Так какой лучше эмулятор использовать для корректного дампа CRAM и VRAM?
Для CRAM используйте что удобно, просто узнайте правильный порядок и учитывайте это.

UPD:
Gens by Shell
Только Gens r57shell mod чудовищно медленный, если открыть HEX-редактор, по крайней мере на Win10 с FX-8300 и Ryzen 5600X, чем выше окно, тем больше просадка, на FX-8300 было меньше 30FPS из 60, на 5600X лучше, но всё равно. Вроде на Win7 было лучше, думаю дело в отрисовки (API и код плохой), например, на HxD плохо меняет размер на 5600X тоже. Его пилить и пилить, переписывать GUI.
« Последнее редактирование: 10 Март 2023, 16:47:45 от Sharpnull »

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #13 : 10 Март 2023, 16:41:26 »
Для CRAM используйте что удобно, просто узнайте правильной порядок и учитывайте это.

Как я понял правильный, это LittleEndian?  :)

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #14 : 10 Март 2023, 16:57:39 »
Как я понял правильный, это LittleEndian?  :)
Тот который в байтах "0B GR", т. е. для белого "0E EE". Тут обычный Big-Endian, так будет записано в самом роме. Я имел в виду узнать какой порядок в нужном эмуляторе, например по игре, или будет видно по формату по чётным позициям в CRAM: "0x xx" - правильно, "xx 0x" - обратный, или как BizHawk - особый, потом конвертируйте туда-сюда.

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #15 : 10 Март 2023, 17:04:09 »
Тот который в байтах "0B GR", т. е. для белого "0E EE". Тут обычный Big-Endian, так будет записано в самом роме. Я имел в виду узнать какой порядок в нужном эмуляторе, например по игре, или будет видно по формату по чётным позициям в CRAM: "0x xx" - правильно, "xx 0x" - обратный, или как BizHawk - особый, потом конвертируйте туда-сюда.
Ну моя конечная цель стоит в ручной распаковке некоторых изображений из VRAM, приведением их в RGB формат "скрестив" с палитрой и превращением в 16x16 bmp. Потому что в игре спрайты персонажей чанками поделены на 8x8.  ^_^

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #16 : 10 Март 2023, 17:09:30 »
моя конечная цель
Это легко и полностью делается на Python + PIL (Pillow). Палитру можно читать из рома. Для VRAM не знаю какой порядок, но там тоже не сложно.

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #17 : 10 Март 2023, 17:10:59 »
Это легко и полностью делается на Python + PIL (Pillow). Палитру можно читать из рома. Для VRAM не знаю какой порядок, но там тоже не сложно.

Оффсет палитры внутри рома не подскажите? Или он индивидуален у каждой игры?

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #18 : 10 Март 2023, 17:17:19 »
Или он индивидуален у каждой игры?
Конечно, и может генерироваться, а не лежать как есть. Так что этот совет только для некоторых случаев.
На счёт кода на Python, вашу convert_color() можно заменить на (на любом другом языке также):
convert_color = lambda x: (0,49,87,119,146,174,206,255)[x>>1]

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

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #19 : 10 Март 2023, 17:53:52 »
Только Gens r57shell mod чудовищно медленный, если открыть HEX-редактор, по крайней мере на Win10 с FX-8300 и Ryzen 5600X, чем выше окно, тем больше просадка, на FX-8300 было меньше 30FPS из 60, на 5600X лучше, но всё равно. Вроде на Win7 было лучше, думаю дело в отрисовки (API и код плохой), например, на HxD плохо меняет размер на 5600X тоже. Его пилить и пилить, переписывать GUI.
Для дампы палитра не особо важно. Палитру в формат RGB888 он правильно дампит.

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #20 : 11 Март 2023, 05:58:58 »
Не знаете, что может быть не так? На первом скрине то, что вытаскивается у меня, на втором оригинал.

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

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #21 : 11 Март 2023, 06:56:40 »
Что здесь не так можно сказать, только увидев код. Возможно, ты читаешь данные не побайтно, о по словам или лонгами и у тебя байты переворачиваются. Так видится по крайней мере

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #22 : 11 Март 2023, 07:19:17 »
Что здесь не так можно сказать, только увидев код. Возможно, ты читаешь данные не побайтно, о по словам или лонгами и у тебя байты переворачиваются. Так видится по крайней мере
https://github.com/bqio/langrisser-sprites

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

  • Пользователь
  • Сообщений: 556
  • Пол: Мужской
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #23 : 11 Март 2023, 08:53:10 »
Не силён в питоне. Но вроде ничего такого в коде нет, что переворачивает байты. Может дамп кривой и в нём байты перевёрнуты. Попробуй открыть vram.bin в тайловом редакторе, если там всё нормально, то значит где-то в коде ошибка.

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #24 : 11 Март 2023, 09:31:16 »
Не силён в питоне. Но вроде ничего такого в коде нет, что переворачивает байты. Может дамп кривой и в нём байты перевёрнуты. Попробуй открыть vram.bin в тайловом редакторе, если там всё нормально, то значит где-то в коде ошибка.
Вы оказались правы, оказывается у меня был повреждён vram.bin. Правда каким образом, не понятно. Сдампил через Gens 11 r57shell mod и всё корректно достаётся.  :neznayu:

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #25 : 11 Март 2023, 14:08:04 »
bqio, по коду могу добавить.
CRAM_PATH = join("data", "cram.bin") можно записать как CRAM_PATH = "data/cram.bin", косая черта работает везде (Win, Linux) в отличие от обратной косой (возможно есть нюансы), ещё удобно использовать pathlib вместо os.path: CRAM_PATH = Path("data") / "cram.bin".
Вместо:
    _tile.write(pk("<B", pixel[0]))
    _tile.write(pk("<B", pixel[1]))
    _tile.write(pk("<B", pixel[2]))
Проще _tile.write(pk("<BBB", *pixel)) или _tile.write(bytes(pixel)), а bytearray() вместо BytesIO() в данном случае, но по скорости не знаю.
Если записывать в tile_apply_pallete() не [(R,G,B),(R,G,B),...], а [R, G, B, R, G, B, ...], то вместо tile_to_buf() остаётся tile_buf = bytes(tile), в таком случае можно хранить цвета палитры как bytes, тогда в tile_apply_pallete() можно _tile = bytearray(); for pal_idx in tile: _tile += pallete[pal_idx >> 4] + pallete[pal_idx & 0xF]; return _tile, или сделать палитру сразу для двух цветов, чтобы _tile += pallete[pal_idx].
Можно не применять палитру вручную, а сохранять как индексированный PNG, тогда остаётся сделать преобразование индексов 0b12345678 > 0b00001234 0b00005678 и указать палитру.
UPD: Ещё заметил pallete_4bpp_to_rgb(up("<H", fp.read(2))[0]), т. е. в файле у вас палитра неправильная, потому что: hex(unpack("<H", b"\x01\x23")[0]) # = 0x2301.
Я бы всё писал проще в одном файле, для одноразового кода нормально :)

Оффлайн bqio

  • Пользователь
  • Сообщений: 20
  • Dark Master
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #26 : 11 Март 2023, 14:54:40 »
Я бы всё писал проще в одном файле, для одноразового кода нормально
У меня фобия на распределение кода. Во всём остальном спасибо, посмотрю позже.  :)

Оффлайн Werton

  • Пользователь
  • Сообщений: 876
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #27 : 11 Март 2023, 16:06:24 »
CRAM_PATH = join("data", "cram.bin") можно записать как CRAM_PATH = "data/cram.bin", косая черта работает везде (Win, Linux) в отличие от обратной косой (возможно есть нюансы)
Можно, но не нужно :) на винде не рекомендуется это делать, хоть сам питон это прожёвывает, но сторонние библиотеки могут не поддерживать замену слэша на обратный.
« Последнее редактирование: 11 Март 2023, 16:18:40 от Werton »

Оффлайн Yoti

  • Пользователь
  • Сообщений: 4477
  • Пол: Мужской
  • Не тро-гай ме-ня
    • Steam
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #28 : 11 Март 2023, 22:44:19 »
косая черта работает везде (Win, Linux)
os.sep то отменили уже?

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5138
    • Просмотр профиля
[SMD] Палитра в Genesis
« Ответ #29 : 11 Март 2023, 23:13:57 »
os.sep то отменили уже?
Если вопрос без издёвки, то os.sep работает и для совместимости со старыми версиями Python пригодится, но здесь вопрос удобства, через pathlib можно написать с таким результатом под Win:
>>> from pathlib import Path
>>> p = Path("data") / "1.bin"
>>> p
WindowsPath('data/1.bin')
>>> str(p)
'data\\1.bin'
Т. е. можно использовать и для пакетов, которые не работают с '/' или не должны, если вызовы Windows API или использование обычных DLL, или т. п. Я пишу для себя под Win, а '\\' - не удобно.
Вообще я не слежу за развитием Python, много чего добавляют.