Хранение текстур (графики / изображения)
Графика в игре хранится в пожатом виде. Скорее всего это какой-то аналог LZ77.
Текстуры (графика) хранятся в файле LEGO.JAM. Судя по всему, исходными файлами были *.BMP. В качестве примера мы рассмотрим «DSHOCK».
Адрес: $139982
Размер: $19F (415 байт)
Для удобства мы извлечём данный архив в отдельный файл. Он будет прикреплён к этой статье.
Для начала нужно сказать пару строк об особенности вывода графики.
Как рисунок выглядит в игре.
Как рисунок выглядит в распакованном виде (оригинал).
Конечно рисунки маленькие и разницу между ними сложно заметить, но в игре дублируется пиксель поверху и с левого края. На рисунке эта область обозначена красным цветом. За счёт этого изображение сдвигается и часть его попадает в невидимую область (на рисунке обозначена зелёным цветом).
Такой вид имеет «архив» в hex-редакторе.
Первый байт (04) – указывает на тип изображения. 04 - то сколько будет занимать один пиксель бит. В нашем случае это 4 бита или пол байта.
Если встречаем значение 08, то один пиксель будет равен 1 байту.
Второй байт (06) – указывает на количество цветов в рисунке. Проще говоря сколько цветов будет содержать палитра. В нашем случае это 7 цветов, так как ноль учитывается.
Ширина (длинна) изображения в пикселях по X. У нас оно составляет 52 пикселей.
Высота изображения в пикселях по Y. У нас оно составляет 32 пикселя.
Палитра – занимает 15 байт.
7 * 3 = 15.
7 – количество цветов
3 – сколько байт занимает один цвет.
Один цвет занимает 3 байта.
Палитра хранится в формате RGB, права в перевёрнутом виде.
(40 03) - сколько байт данные занимают в распакованном виде. В нашем случае это 832
байта. Это так же блок, в пределах которого будет идти отсчёт сжатия.
Следующие два байта (80 01) - размер блока (сжатых данных). Он равен 384 (0x0180) байта.
Если размер запакованных данных равен размеру распакованных, то это значит, что данные не сжаты.
Размер сжатой графики, как написано выше, 384 байта.
00 – два пикселя цвета 0 и 0. При чём вывод пикселей идёт справа налево.
8C – служебный байт. В битах данный байт имеет следующий вид 10001100.
1 – данные сжаты.
0 – считывает не сжатые данные.
Для начала начнём с простых примеров.
00 – служебный байт. В битах имеет вид 00000000. Это значит, что сжатых данных не содержится. Считываем следующие 8 байт.
Напомню, что один пиксель равен 4 байтам. То есть данные будут иметь следующий вид.
5 5 4 6 6 6 6 2 4 1 6 2 3 2 1 4
98 – следующий служебный байт, но сейчас мы его рассматривать не будем.
Теперь рассмотрим пример содержащий сжатые данные.
80 – служебный байт. В битах имеет вид 10000000.
1 – обозначает сжатые данные, считываем их. (Сжатые данные обозначены оранжевым цветом)
0F 4D - сжатые данные имеют вид. Данные нужно преобразовать следующим образом
F 04D
F – Сколько байт считывать. В данном случае это 3 байта, что равно 6 пикселям.
Расчёт производится по следующей формуле.
0x0f-XX+3
Таким образом подставив вместо XX значение F мы получим 3.
0x0f-0x0f+3=3
04D – на сколько байт нам нужно вернуться в изображение. В нашем случае это 77 байт. Хочу обратить ваше внимание, что возврат происходит именно в изображение (но в пределах блока).
Далее идут не сжатые данные.
80 – следующий служебный байт
Теперь вернёмся в самое начало и рассмотрим данный пример.
8C – служебный байт. В битах данный байт имеет следующий вид 10001100.
00 01 44 – Мы ещё не рассматривали данный способ сжатия. Тут всё намного сложнее и запутаннее.
Данные 4 бита (пол байта) (равны нулю) говорят нам о том, что это другой способ сжатия и он занимает 3 байта.
Тут в принципе всё тоже самое что и в предыдущем случае, но с небольшим дополнением.
Переворачиваем данные
0 44 001
0 – Сколько байт считывать. В данном случае это 18 байт, что равно 36 пикселям.
Расчёт производится по следующей формуле.
0x0f-XX+3
Таким образом подставив вместо XX значение 0 мы получим 36.
0x0f-0x00+3=18
Но это ещё не всё, к этому числу (18) нужно прибавить 0x44 (68)
18 + 68 = 86 байт.
Вот теперь мы получили окончательное значение сколько байт считывать.
001 – на сколько байт нам нужно вернуться в изображение. В нашем случае это 1 байт.
06 – следующий служебный байт
FF 00 00 – что-то вроде стоп байт.
Прикрепленные изображения