Так уж сложилось, что продержавшись на
NES мало времени и не сделав ни одного публичного перевода я переехал на более молодые консоли. Почему то я выбрал именно GC и Wii, может из-за того, что там почти нет русских игр? Может и из-за этого. Но суть не в этом.
Основной формат хранения графики у
GC и
Wii одинаков, связано это с тем, что архитектура
Wii - это просто улучшенная версия
GC. Так что эти 2 консоли можно считать почти одинаковыми по файлам. Правда, в
Wii добавили n-ое количество новых форматов, но их, пока, обсуждать не будем.
Перейдём к самой сути данной темы, способы хранения графики на
Wii и
GC во многих играх одинаковы, и чаще графика скрывается под
TPL файлами. Но это не говорит о том, что так в каждой игре. Так же, на
GC, как я знаю, в играх серии
The Legend of Zelda используется
BTI, а на
Wii в
BRRES файлах используется ещё одна разновидность файла с текстурами
TEX0. Так же, в
BRFNT файлах(шрифты
Wii) используются тот же способ хранения графики, как и в выше описанных файлах.
Почитав о способах хранения графики, я и решил написать эту статью.
Сделаем маленькую табличку, в которой и будут описаны все наши форматы хранения графики.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-27238600-1431463908.png)
Для начала, мы попытаемся разобрать все форматы хранения графики. А уже позже разберём 3 типа контейнеров:
И немного о самой архитектуре
GC и
Wii:
Что
GC, что
Wii работают на процессоре от фирмы
IBM -
PowerPC. В данных консолях эти процессоры работают в
Big-Endian. То бишь, если смотреть файлы в HEX редакторе, то указатели и другие значения не надо переворачивать, как это делается у
Little-Endian.
К примеру, число 8307 в
Big-Endian будет выглядеть как 0x2073, а у
Little-Endian 0x7320. Думаю, разницу вы поняли.
Ссылки на посты с описанием форматов:
I4 - Оттенки серого (http://pscd.ru/forum/index.php?/topic/362-osnovnye-formaty-khraneniia-grafiki-v-gcwii/?p=3723)
I8 - Оттенки серого (http://pscd.ru/forum/index.php?/topic/362-osnovnye-formaty-khraneniia-grafiki-v-gcwii/?p=3847)
IA4 - Оттенки серого с прозрачностью (http://pscd.ru/forum/index.php?/topic/362-osnovnye-formaty-khraneniia-grafiki-v-gcwii/?p=4301)
Извиняюсь за наглость, когда ждать продолжение?
Цитата: SPOT от 14 мая 2015, 12:37Извиняюсь за наглость, когда ждать продолжение?
Скоро будет, я хочу с каждым типом изображения поставлять исходный код программы, которая сможет открывать тот тип, про который будет рассказываться. Но у меня, пока что, не получается написать программу:(
Цитата: TTEMMA от 14 мая 2015, 14:47Но у меня, пока что, не получается написать программу :(
И в чём именно трудность? Или попросту не хватает времени?
Изображение поделено на блоки - это не проблема. Когда я его "декодирую", то надо создать цикл сначала от 0 до Высота, в этом цикле от 0 до Ширина, а в этом цикле пробежаться по блокам.
Проблема в том, что у меня программа вообще не пробегается по циклу Высота, по циклу с шириной пробежался и остановился.
Пишу на Delphi, использую циклы While, ибо в For к числу, которое задается началом, нельзя прибавлять числа. А мне надо в каждом цикле по высота и ширине прибавлять по 8.
Не знаю, что уже делать.
Цитата: TTEMMA от 15 мая 2015, 10:18Изображение поделено на блоки - это не проблема. Когда я его "декодирую", то надо создать цикл сначала от 0 до Высота, в этом цикле от 0 до Ширина, а в этом цикле пробежаться по блокам.
Проблема в том, что у меня программа вообще не пробегается по циклу Высота, по циклу с шириной пробежался и остановился.
Возможно где-то ошибка в коде. Попробуй отдельно пройти "по циклу Высота".
Цитата: TTEMMA от 15 мая 2015, 10:18Пишу на Delphi, использую циклы While, ибо в For к числу, которое задается началом, нельзя прибавлять числа. А мне надо в каждом цикле по высота и ширине прибавлять по 8.
Не знаю, что уже делать.
Так с
for () можно сделать всё что угодно.
for (int a = i; a<b; a++){} //стандартfor (int a = i; a<b; ){
a+=8;
}for (;;){
a+=8;
if (a>=b)break;
}Способов куча.
Это в C можно так, но не в delphi.
Я совершил самую глупейшую ошибку - не обнулял счётчик по ширине. Поэтому цикл по высоте и ширине проходил 1 раз, а дальше шёл цикл только по высоте, от которого смысла 0. Разобрался, скоро опишу I4.
'Изображение'
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-67538500-1431700706.png)
I4 - Оттенки серого
Как можно понять по названия формата хранения графики, изображение у нас 4 битное. То есть, на 1 пиксель выделяется 4 бита, следственно 1 байт - 2 пикселя.
Для данного урока я подготовил изображение размером 256х256, оно будет прикреплено к данному посту.
Выглядит оно таким вот образом:
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-44764600-1431799916.png)
Так, начнём, как я уже говорил, один пиксель занимает 4 бита. 4 бита - это половина 1 байта.
Все изображения в GC\Wii делятся на блоки, в нашем случае каждый блок имеет размер 8*8.
Так как у нас в одном байте аж 2 пикселя, то мы ширину блока(8) можем смело поделить на 2. Правда, если писать программу, то мы будем не делить данное значение, а в цикле к счётчику прибавлять 2:
//Наглядный пример на C++
for (int x1 = x;x1<Width+8;x+=2)
{
//здесь читаем 2 пикселя и бла бла бла
}Давайте подробно разберём хранение пикселей. К примеру, возьмём байт 0xF3.
Для начала, надо разбить байт по 4 бита. Следовательно, значение первого пикселя = F(15), а значение второго пикселя = 3.
Но это не всё, полученные значения надо умножить на 17 и мы получим
1 пиксель : F*17 = 255
2 пиксель : 3*17 = 51
Дальше всё просто, значение RGB 1-го пикселя будет:
R = 255
G = 255
B = 255
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-43091000-1431801348.png)
Следовательно, 2-го пикселя:
R = 51
G = 51
B = 51
Впрочем, это всё. Надеюсь, всё было понятно.
P.S. Пока программ не будет, если сможем разобрать все форматы хранения, то напишу подобие библиотеки для работы с этими изображениями и тогда будем клепать просмотрищики BTI, TPL.Так же, если было написано мало или что-то не понятно, пишите, попытаюсь разжевать ещё больше.
Цитата: TTEMMA от 16 мая 2015, 21:41Но это не всё, полученные значения надо умножить на 17 и мы получим
Почему на
17?
Цитата: SPOT от 18 мая 2015, 10:12
Цитата: TTEMMA от 16 мая 2015, 21:41Но это не всё, полученные значения надо умножить на 17 и мы получим
Почему на 17?
Вообще, надо умножить на 255(общее кол-во цветов в 8 битной кодировке) и полученное число поделить на 15(максимальное кол-во цветов в 4 битной кодировке). Так мы сможем получить 1 байт(8 битный) отвечающий за все 3 цвета в оттенках серого.
Но вместо (Value*255)/15 можно использовать 17.
TTEMMA, Стоит ждать продолжение?
Цитата: SPOT от 29 мая 2015, 21:56TTEMMA, Стоит ждать продолжение?
Стоит, просто, пока что, времени нет.
Давай пости нужные темы, как все будет готово, надо полностью собрать в один пост и перевезти все в "Как умеем".
I8 - Оттенки серого
Различий у данного формата от I4 лишь в том, что на цвет выделяется 8 бит - 1 байт.
Я взял тоже изображения, что брали и у I4, выглядит оно так:
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-44764600-1431799916.png)
В данном типе изображения, 1 пиксель занимает 8 байт. Один блок имеет размер 8х4.
Примерно, если писать программу, то считываются пиксели в каждом блоке так:
//Наглядный пример на C++
for (int y1 = y;y1<y+4;y++)
{
for (int x1 = x;x1<x+8;x++)
{
//здесь читаем 1 пиксель и бла бла бла
}
}Так как у нас на каждый пиксель используется один байт, то мы спокойной считываем один байт и задаём его как RGB.
К примеру, FF:
R = 255
G = 255
B = 255
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-43091000-1431801348.png)
Вот так прост данный формат хранения графики.
Цитата: TTEMMA от 03 июня 2015, 19:18К примеру, FF:
R = 255
G = 255
B = 255
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-43091000-1431801348.png)
Вот так прост данный формат хранения графики.
Можно на примере другого цвета объяснить как мы получили
RGB?
Цитата: Alon от 04 июня 2015, 11:04
Цитата: TTEMMA от 03 июня 2015, 19:18К примеру, FF:
R = 255
G = 255
B = 255
(http://pscd.ru/forum/uploads/monthly_05_2015/post-268-0-43091000-1431801348.png)
Вот так прост данный формат хранения графики.
Можно на примере другого цвета объяснить как мы получили RGB?
Да, конечно. К примеру, байт 0х44, в десятичной это будет 68, следовательно
R = 68
G = 68
B = 68
(http://s7.hostingkartinok.com/uploads/images/2015/06/24e4a98db2f1efb0e0d4ecbb9db71b97.png)
IA4 - Оттенки серого с прозрачностью
Как понятно по названию, данный тип хранения графики предоставляет из себя оттенки серого с прозрачностью.
Один цвет занимает 1 байт - 8 бит: 4 бита - прозрачность, 4 бита - цвет.
Размер блока имеет 8х4.
Для примера возьмём нашу старую картинку:
(http://s7.hostingkartinok.com/uploads/images/2015/09/10fae9d400fc99083a7a84b20e2c19dc.png)
Выглядит, как-то, хреново, но да ладно.
Итак, в HEX редакторе изображение выглядит так:
(http://s7.hostingkartinok.com/uploads/images/2015/09/d4231d6ef4f373b682a4a03f025ad66f.png)
Как мы помним,
1 пиксель = 1 байт.Для примера, возьмём байт
0x57Первые 4 бита выступают за байт прозрачности, то есть биты
0101 выступают за прозрачность. Но ещё не всё, надо это значение умножить на
255 и поделить на
15:
Alpha =
5 * 255 / 15 =
85 (0101 = 5 в десятичной)Умножаем на общее кол-во цветов и делим на возможное кол-во цветов.По тому же способу получаем и RGB, только берём теперь
последние 4 байта -
0111. С этим значением надо сделать тоже самое, что и со значением
Alpha:
RGB =
7 * 255 / 15 =
119 (0111 = 7 в десятичной) Следовательно, в байте
0x57:
Альфа канал равен
85 Красный цвет равен
119 Зелёный цвет равен
119 И синий цвет равен
119 (http://s7.hostingkartinok.com/uploads/images/2015/09/dd326cd0541f67b4c13efd24654475fc.png) Вот, собственно, и всё. Как видите, очень простой формат.
Спасибо за статью, будет ли пример файла "IA4 - Оттенки серого с прозрачностью" ? ждать ли продолжение по форматам GC\Wii ?