Хранение текстур (графики / изображения)
Графика в игре хранится в пожатом виде. Скорее всего это какой-то аналог LZ77.
Текстуры (графика) хранятся в файле LEGO.JAM. Судя по всему, исходными файлами были *.BMP. В качестве примера мы рассмотрим «DSHOCK».
Адрес: $139982
Размер: $19F (415 байт)
Для удобства мы извлечём данный архив в отдельный файл. Он будет прикреплён к этой статье.
Для начала нужно сказать пару строк об особенности вывода графики.
![post-1-0-66232700-1481461332.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-66232700-1481461332.png)
Как рисунок выглядит в игре.
![post-1-0-98009000-1481461332.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-98009000-1481461332.png)
Как рисунок выглядит в распакованном виде (оригинал).
![post-1-0-47385500-1481461332.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-47385500-1481461332.png)
Конечно рисунки маленькие и разницу между ними сложно заметить, но в игре дублируется пиксель поверху и с левого края. На рисунке эта область обозначена красным цветом. За счёт этого изображение сдвигается и часть его попадает в невидимую область (на рисунке обозначена зелёным цветом).
![post-1-0-13295800-1481461332.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-13295800-1481461332.png)
Такой вид имеет «архив» в hex-редакторе.
![post-1-0-56364100-1481461583.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-56364100-1481461583.png)
Первый байт (04) – указывает на тип изображения. 04 - то сколько будет занимать один пиксель бит. В нашем случае это 4 бита или пол байта.
Если встречаем значение 08, то один пиксель будет равен 1 байту.
![post-1-0-76676000-1481461583.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-76676000-1481461583.png)
Второй байт (06) – указывает на количество цветов в рисунке. Проще говоря сколько цветов будет содержать палитра. В нашем случае это 7 цветов, так как ноль учитывается.
![post-1-0-97236600-1481461583.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-97236600-1481461583.png)
Ширина (длинна) изображения в пикселях по X. У нас оно составляет 52 пикселей.
![post-1-0-16289800-1481461584.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-16289800-1481461584.png)
Высота изображения в пикселях по Y. У нас оно составляет 32 пикселя.
![post-1-0-32341800-1481461584.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-32341800-1481461584.png)
Палитра – занимает 15 байт.
7 * 3 = 15.
7 – количество цветов
3 – сколько байт занимает один цвет.
![post-1-0-49399300-1481461584.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-49399300-1481461584.png)
Один цвет занимает 3 байта.
![post-1-0-85497900-1481461584.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-85497900-1481461584.png)
Палитра хранится в формате RGB, права в перевёрнутом виде.
![post-1-0-21864300-1481461886.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-21864300-1481461886.png)
(40 03) - сколько байт данные занимают в распакованном виде. В нашем случае это 832
байта. Это так же блок, в пределах которого будет идти отсчёт сжатия.
![post-1-0-41230500-1481461886.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-41230500-1481461886.png)
Следующие два байта (80 01) - размер блока (сжатых данных). Он равен 384 (0x0180) байта.
Если размер запакованных данных равен размеру распакованных, то это значит, что данные не сжаты.
![post-1-0-74447400-1481461886.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-74447400-1481461886.png)
Размер сжатой графики, как написано выше, 384 байта.
![post-1-0-06980400-1481461887.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-06980400-1481461887.png)
00 – два пикселя цвета 0 и 0. При чём вывод пикселей идёт справа налево.
![post-1-0-38429100-1481461887.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-38429100-1481461887.png)
8C – служебный байт. В битах данный байт имеет следующий вид 10001100.
1 – данные сжаты.
0 – считывает не сжатые данные.
![post-1-0-93367800-1481462066.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-93367800-1481462066.png)
Для начала начнём с простых примеров.
00 – служебный байт. В битах имеет вид 00000000. Это значит, что сжатых данных не содержится. Считываем следующие 8 байт.
Напомню, что один пиксель равен 4 байтам. То есть данные будут иметь следующий вид.
5 5 4 6 6 6 6 2 4 1 6 2 3 2 1 4
98 – следующий служебный байт, но сейчас мы его рассматривать не будем.
![post-1-0-22324200-1481462067.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-22324200-1481462067.png)
Теперь рассмотрим пример содержащий сжатые данные.
80 – служебный байт. В битах имеет вид 10000000.
1 – обозначает сжатые данные, считываем их. (Сжатые данные обозначены оранжевым цветом)
0F 4D - сжатые данные имеют вид. Данные нужно преобразовать следующим образом
![post-1-0-66940700-1481462066.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-66940700-1481462066.png)
F 04D
F – Сколько байт считывать. В данном случае это 3 байта, что равно 6 пикселям.
Расчёт производится по следующей формуле.
0x0f-XX+3
Таким образом подставив вместо XX значение F мы получим 3.
0x0f-0x0f+3=3
04D – на сколько байт нам нужно вернуться в изображение. В нашем случае это 77 байт. Хочу обратить ваше внимание, что возврат происходит именно в изображение (но в пределах блока).
Далее идут не сжатые данные.
80 – следующий служебный байт
![post-1-0-38234500-1481462067.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-38234500-1481462067.png)
Теперь вернёмся в самое начало и рассмотрим данный пример.
8C – служебный байт. В битах данный байт имеет следующий вид 10001100.
00 01 44 – Мы ещё не рассматривали данный способ сжатия. Тут всё намного сложнее и запутаннее.
![post-1-0-55158100-1481462067.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-55158100-1481462067.png)
Данные 4 бита (пол байта) (равны нулю) говорят нам о том, что это другой способ сжатия и он занимает 3 байта.
Тут в принципе всё тоже самое что и в предыдущем случае, но с небольшим дополнением.
Переворачиваем данные
![post-1-0-45989400-1481462066.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-45989400-1481462066.png)
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 – следующий служебный байт
![post-1-0-73379800-1481462067.png](http://pscd.ru/forum/uploads/monthly_12_2016/post-1-0-73379800-1481462067.png)
FF 00 00 – что-то вроде стоп байт.
Прикрепленные изображения