TIM файлы – Формат хранения графики PSX

Автор SPOT, 10 мая 2015, 10:16

« назад - далее »

SPOT

Ранее я уже публиковал информацию по хранению несжатой графики на различных игровых системах. Теперь подошла очередь и до Sony PlayStation.
Сам я начал недавно разбираться, как же всё же устроены TIM файлы для PlayStation. Поэтому надеюсь на помощь экспертов, если я где-то что-то упущу или перепутаю. Так же буду приводить свои догадки, какие могут оказаться не верными.
Для начала немного общей информации
 
В файлах формата *.TIM чаше всего в играх и программах для PSX хранится графическое изображение, проще говоря, картинка / рисунок / фотография. Судя по всему, имеется четыре распространенных формата хранения данных:
 
4-bit (color indices)
8-bit (color indices)
16-bit (actual colors)
24-bit (actual colors)
 
Возможно, есть и другие, так сказать авторские.
 
Заголовок занимает 20 байт, дальше идут данные изображения. Байты хранятся в перевёрнутом виде.
 
TIM 4-bit (color indices)
TIM 8-bit (color indices)
TIM 16-bit (actual colors) [TBGR / A1B5G5R5]
TIM 24-bit (actual colors) [RGB / R8G8B8]
TIM файл с несколькими палитрами (4-bit и 8-bit)
 
Дополнительная информация:
Quake II Текстуры (Графика) [PSX]

SPOT

TIM 16-bit (actual colors) [TBGR / A1B5G5R5]
В самом устройстве TIM нет ничего сложного, кроме формата хранения (присвоения) палитры пикселю.
В качестве примера будем рассматривать прикрепленный файл SPIN.TIM. Это изображение размером 188x24.
 
Вид в Hex-редакторе.
 
Константа (постоянное значение), видимо для обозначения, что это формат TIM.
Первые 4 байта можно назвать константой = 0x10000000. (Дополнение от TTEMMA)
 
 
Следующие 4 байта, обозначают какого типа (формата) будут данные (будет TIM файл). В нашем случае это 16-bit (A1B5G5R5).
Следующие 4 байта = тип изображения: (Дополнение от TTEMMA)

  • 0x08 = 4-bit
  • 0x09 = 8-bit
  • 0x02 = 16-bit
  • 0x03 = 24-bit
 
Размер файла. Отсчёт начинает с 8h. То есть с того место, где начинается информация об изображении. Данные хранятся в перевёрнутом виде. Размер данных составляет 0x234C (отсчёт с $8 до $2353 включительно). В файле данные имеют вид 4C 23. Для нормального восприятия нужно переставить байты местами. Сделав это, мы получим 23 4C, собственно говоря, это и есть размер данных.
 
Ширина (длинна) изображения в пикселях по X. У нас оно составляет 188 пикселей. Что соответствует в байтах 00 BC. В файле данное значение записано как BC 00. То есть в перевёрнутом виде.
 
Высота изображения в пикселях по Y. У нас оно составляет 24 пикселя. Что соответствует в байтах 00 18. В файле данное значение записано как 18 00. То есть в перевёрнутом виде.
 
Всё остальное данные (с 14h) это пиксели идущие друг за другом.
 
Один пиксель состоит из двух байт.
 
Дальше начинается самое сложное. Данные хранятся в  виде (порядке) TBGR (Transparency, Blue, Green, Red (Прозрачность, Синий, Зелёный, Красный)) / A1B5G5R5. Сначала идёт бит устанавливающий прозрачность. Затем на каждый из цветов приходится по 5 бит. Таким образом, мы имеем 15-bit RGB (R5 G5 B5).
 
Поскольку данные в файле хранятся в перевёрнутом виде, чтобы с ними работать их нужно перевести в нормальный вид. В файле один пиксель записан как 18 63. Меняем байты местами и получаем 63 18. С этими данными нам и предстоит работать.
 
Дальше нам предстоит работать с битами.
В битах данные имеют следующий вид:
0 11000 11000 11000
 
Теперь нужно преобразовать эту информацию в RGB.
Для лучшего восприятия 5 битам приписываем 3 нулевых бита в начало.
 
Было:
11000
 
Стало:
00011000
 
Теперь 8 бит, преобразовываем в цифры.
 
00011000 = 24
 
И это число нужно умножить на 8.
 
24 * 8 = 192
 
Теперь остаётся вписать данные на своё место и мы получим цвет пикселя. В данном случае это один из оттенков серого.

Diablo

SPOT, большое спасибо за предоставленную информацию, даже я понял, о чём идёт речь. Информация подана очень хорошо и понятно. Продолжайте в том же духе.

TTEMMA

В начале слегка неверно, первые 4 байта можно назвать константой = 0x10000000
Следующие 4 байта = тип изображения:
  • 0x08 = 4-bit
  • 0x09 = 8-bit
  • 0x02 = 16-bit
  • 0x03 = 24-bit
Дальше идёт информация либо о палитре(если 4 или 8 битное изображение), либо о самом изображение(16 или 24 битное изображение).
Структура палитры такова:
  • 4 байта = размер палитры + 0x0C
  • 2 байта = VramX
  • 2 байта = VramY
  • 2 байта = Ширина
  • 2 байта = Высота
  • Сама палитра
Следом после палитры идёт информация о изображении:
  • 4 байта = размер изображения + 0x0C
  • 2 байта = VramX
  • 2 байта = VramY
  • 2 байта = Ширина
  • 2 байта = Высота
  • Само изображение
Так же, кол-во палитр в файле означает высота.(Если 4 или 8 битное изображение).
Есть ещё нюансы по ширине и изображения:
4 битное изображение
  • Ширина = Ширина * 4
8 битное изображение
  • Ширина = Ширина * 2

Вроде, пока что, всё :)

SPOT

TTEMMA, спасибо за информацию. Внёс правки.
 
Что такое VramX и VramY? Это типа куда в видеопамять записать данный элемент, так почему по осям? Или потому что в PSX данные во Vram хранятся в пикселях, а не в тайлах как например в SMD.

SPOT

TIM 4-bit (color indices)
Этот принцип хранения данных и построения изображения схож с принципом хранения графических данных в 16-битных игровых системах.
В качестве примера мы будем рассматривать TIM файл CALLSIGN.TIM из игры Twisted Metal 2. Данный файл я прикреплю к сообщению. Это изображение размером 128x64.
Вид в Hex-редакторе.
 
Константа дающая понять, что это TIM файл.
 
Следующие 4 байта, обозначают какого типа (формата) будет TIM файл. В нашем случае это 4-bit (color indices).
 
Далее идёт информация о палитре. (Напомню, что данные хранятся в перевёрнутом виде)
Структура палитры такова:

  • 4 байта = размер палитры + 0x0C
  • 2 байта = VramX
  • 2 байта = VramY
  • 2 байта = Ширина
  • 2 байта = Высота
  • Сама палитра
 
Размер данных относящихся к палитре. 0x2C то есть 44 байта, 32 байта из которых занимает сама палитра. По 2 байта на 1 цвет. Всего 16 цветов. Скорее всего, 0x2C000000 можно считать константой. Не думаю, что тут может быть какое-то другое значение.
 
2 байта = VramX
 
2 байта = VramY
 
2 байта = Ширина
 
Количество палитр. В данном случае одна палитра.
(2 байта = Высота)
 
Палитра. Данные занимают 32 байта. По 2 байта на один цвет. Палитра хранится в формате TBGR / A1B5G5R5. Данные хранятся в перевёрнутом виде.
 
Первый цвет.
 
Поскольку данные хранятся в перевёрнутом виде, для визуального восприятия их нужно перевернуть. То есть было FF 7F, а мы его перевернули и получили 7F FF.
 
Дальше мне лень повторяться и писать, как узнать какому цвету соответствует данное значение. Нужно просто действовать точно так же как и в случае с TIM 16-bit (actual colors) [TBGR / A1B5G5R5].
 
Размер, занимаемый данными изображения плюс 0x0C.
4 байта = размер изображения + 0x0C
Данные хранятся в перевёрнутом виде 0C 10 00 00. Для нормального восприятия их нужно перевернуть. Перевернув их, мы получим 00 00 10 0C.
 
2 байта = VramX
 
2 байта = VramY
 
Ширина (длинна) изображения в пикселях по X. У нас оно составляет 128 пикселей. В файле данное значение записано как 20 00. То есть в перевёрнутом виде. Мы должны перевернуть это значение 00 20. Преобразовав 00 20 в десятичную систему счисления, мы получим значение 32. Теперь данное значение нужно умножить на 4.
 
32 * 4 = 128
 
Вот мы и получили ширину в пикселях.
 
Высота изображения в пикселях по Y. У нас оно составляет 64 пикселя. Что соответствует в байтах 00 40. В файле данное значение записано как 40 00. То есть в перевёрнутом виде.
 
Начиная с 40h идут данные самого изображения. Метод хранения схож с методом хранения несжатой графики в GBA.
 
Один пиксель занимает пол байта, то есть 4 бита. Значение от 0 до F, что соответствует от 1 до 16. Палитра состоит из 16 цветов. Каждому цвету соответствует значение из 4 бит.
 
Данные хранятся в перевёрнутом виде. Сначала идёт второй пиксель, а потом первый.

TTEMMA

Честно, точно не знаю для чего VramX, VramY. Вроде, расположение TIM в видеопамяти, но я не уверен.
Потом, в статье о 16-bit 2 раза повторяется "Следующие 4 байта".
Потом в статье по 4 байта, где вы говорите, мол размер палитры можно считать константой - надо исправить, ибо размер палитры может быть и меньше, это зависит от изображения. Так же, не забывайте, что в файле может быть несколько палитр. На кол-во палитр указывают последние 2 байта(Высота).
К примеру, возьмём шрифт из RE2.
1.png
0xAC - Размер палитры в целом, то бишь 0х14+A0 = начала блока с информацией об изображении.(размер, высота, ширина и т.д.)
0x05 - Кол-во палитр в файле.
Следовательно, 0x20 на каждую палитру.
К примеру, если выбрать 2 палитру, то цвет текста с белого меняется на зелёный.
2.png

SPOT

TIM 8-bit (color indices)
В качестве примера мы будем рассматривать TIM файл CAB_CARD.TIM из игры Twisted Metal 2. Данный файл я прикреплю к сообщению. Это изображение размером 128x64.
 
Вид в Hex-редакторе.
 
Константа дающая понять, что это TIM файл.
 
Следующие 4 байта, обозначают какого типа (формата) будет TIM файл. В данном случае это 8-bit (color indices).
 
Размер данных относящихся к палитре. 0x2C то есть 524 байта, 512 байта из которых занимает сама палитра. По 2 байта на 1 цвет. Всего 256 цветов.
 
2 байта = VramX (для палитры)
 
2 байта = VramY (для палитры)
 
2 байта = Ширина (для палитры)
 
Количество палитр. В данном случае одна палитра.
(2 байта = Высота (для палитры))
 
Палитра. Данные занимают 200 байта. По 2 байта на один цвет. Всего 256 цветов. Палитра хранится в формате TBGR / A1B5G5R5. Данные хранятся в перевёрнутом виде.
 
Первый цвет.
 
Как определить какому цвету соответствуют данные читайте в TIM 16-bit (actual colors) [TBGR / A1B5G5R5].
 
Размер, занимаемый данными изображения плюс 0x0C.
4 байта = размер изображения + 0x0C
Данные хранятся в перевёрнутом виде 0C 20 00 00. Для нормального восприятия их нужно перевернуть. Перевернув их, мы получим 00 00 20 0C.
 
2 байта = VramX (для изображения)
 
2 байта = VramY (для изображения)
 
Ширина (длинна) изображения в пикселях по X. У нас оно составляет 128 пикселей. В файле данное значение записано как 40 00. То есть в перевёрнутом виде. Мы должны перевернуть это значение 00 40. Преобразовав 00 40 в десятичную систему счисления, мы получим значение 64. Теперь данное значение нужно умножить на 2.
 
32 * 2 = 128
 
Вот мы и получили ширину в пикселях.
 
Высота изображения в пикселях по Y. У нас оно составляет 64 пикселя. Что соответствует в байтах 00 40. В файле данное значение записано как 40 00. То есть в перевёрнутом виде.
 
Один пиксель занимает 8 бит или, проще говоря, равен одному байту.
 
Счёт идёт от 00 до FF, то есть всего 256 значений.

SPOT

Цитата: TTEMMA от 12 мая 2015, 17:44мол размер палитры можно считать константой - надо исправить, ибо размер палитры может быть и меньше,
Мне кажется, что размер всё же фиксированный. Для 4-bit (color indices) это палитра из 16 цветов. Для 8-bit (color indices) это 256 цветов.
 
 

Цитата: TTEMMA от 12 мая 2015, 17:44Так же, не забывайте, что в файле может быть несколько палитр.
Вот это нужно изучить :)
 
Кто знает в какой игре есть TIM в формате 24-bit (actual colors)?

TTEMMA

ЦитироватьМне кажется, что размер всё же фиксированный.
Только кажется, размер зависит от кол-во палитр и типа изображения.

SPOT

TTEMMA, Скинь (залей) файл из RE2, где несколько палитр используется. Если не сложно.

TTEMMA

Да, конечно.
1 файл - 4 битное
2 файл - 8 битное
font0.zip

SPOT

TIM файл с несколькими палитрами (4-bit и 8-bit)
Кратко рассмотрим вариант с несколькими палитрами в TIM файлах. В начале идёт значение указывающие на количество палитры в файле, затем разными цветами выделена палитра.
 
4-bit (color indices)
 
8-bit (color indices)

SPOT

Ещё раз повторю вопрос:
 
Кто знает в какой игре есть TIM в формате 24-bit (actual colors)?

TTEMMA


SPOT

Цитата: TTEMMA от 15 мая 2015, 10:12Вот пример.
Благодарю.
А данный формат (24-bit (actual colors)) в играх для PSX встречается? Или он для PS2?

TTEMMA

Встречается, редко, но встречается.
В PS2 идёт уже tm2(TIM2)

SPOT

24-bit (actual colors) [RGB / R8G8B8]
Заголовок (первые 20 байт) имеют точно такое же значение, как и в случае с TIM 16-bit (actual colors). Поэтому рассматривать данные значения не будем.
 
За исключением обозначения ($4) 0x03000000. Данные байты указывает на то, что это 24-bit (actual colors).
 
С 14h ($14) хранится набор пикселей. Один пиксель занимает 3 байта. В отличие от предыдущих вариантов. Данные здесь хранятся не в перевёрнутом виде.
 
По сравнению с 16-bit (actual colors) тут всё просто. Данные идут подряд в RGB и на каждый из цветов приходится по 8 бит (R8 G8 B8), то есть по одному байту.
 
Переводим байты в десятичную систему счисления.
E9 = 233
D4 = 212
B5 = 181
 
Теперь вписываем данные на свои места и получаем исходный цвет.

zetper

Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть rutracker.org/forum/viewtopic.php?t=4514120
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.

TTEMMA

Цитата: zetper от 29 августа 2015, 15:39Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть rutracker.org/forum/viewtopic.php?t=4514120
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
gtamodding.ru/wiki/TIM2