1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Пожалуйста, внимательно прочитайте правила раздела.
  3. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

format pl8

Тема в разделе "Мастерская", создана пользователем Strategus, 6 мар 2024.

Метки:
  1. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Давно хотелось расковырять графику из Лордс 2(Lords of the Realm), вчер весь вечер вертел файлы в шестнадцатеричном редакторе и в GBS. А сегодня дошло ))
    Пока понятно что первые 8 байт - это заголовок файла, там 3,4 байты это количество картинок спрятанных в файле. Начиная с 9 байта идут данные, по 16 байт на картинку. Первая пара из которых это ширина, дальше 2 байта идут на высоту картинки, потом 4 байта смещение, от начала файла, до массива пикселей. Палитра хранится в отдельном файле файле, с таким же названием, как и файл с картинками. Но Палитр меньше, значит часть используется для многих файлов.
    Вот нашёл картину вил (оружие крестьян), я вроде нигде в игре не встречал этот вид оружия для выбора найма армии или покупки. Он ка бы автоматом крестьян вооружает ))
    ARMITEMS14.png
    Но не могу понять, за что отвечают еще 6 байт в заголовке, и оставшиеся 8 байт в каждом блоке каждой картинки...
     
    Последнее редактирование: 7 мар 2024
    PavelDAS и mcrstar нравится это.
  2.  
  3. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Уже два файла попались, которые дают сбой по моей схеме открытия ))
    После количества картинок, всегда идёт число меньшее (возможно это число показывает сколько надо загружать из них)ю В шрифтах полно пустых картинок 2х2 пикселя - которые не используются видимо вовсе... В шрифте 150 картинок, а второе число 75, хотя по факту там 79 символов нарисовано...
     
  4. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    16 байтный блок спрайта:
    • Ширина спрайта(2 байта)
    • Высота спрайта(2 байта)
    • Смещение в файле, до массива пикселей (4 байта)
    • Координаты спрайта по Х (2 байта)
    • Координаты спрайта по Y (2 байта)
    • Видимо резерв (4 байта)
    Координаты спрайты, видимо нужны, для восстановления PL8-файла обратно, для редактирования. В Игре они не используются, пробовал менять - результата ноль!
    Вот на основе этих координат собрал атлас, из ARMITEMS.PL8:
    ARM.png

    Зелёный цвет это прозрачный в игре. Возможно весь атлас имеет смысл заливать, перед рисованием туда картинок. Да итоговой ПНГ вышел больше в два раза, но там было уже 400+ цветов, я не заморачивался с оптимизациями. Но потом в редакторе перегнал картинку в палитру и вышло чуть меньше уже ))
     
    AndyFox, mcrstar, Gamerun и ещё 1-му нравится это.
  5. Jordan 63

    Jordan 63

    Регистрация:
    26 янв 2010
    Сообщения:
    480
    @Strategus, будете выкладывать наработки на github? Код утилиты и т.д
     
  6. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Можно и выложить, там 100 строк кода, если убрать вывод инфы, которая мне нужна для экспериментов )) Можно прямо сюда запостить, ка пример даже ))

    Jordan, тебе лучше не смотреть это. Так не эффективно использовали дисковое пространство - столько дублирующей графики ))
    Файл с которого я начал ARMITEMS.PL8 содержит точную копию графики из файла ARM_IT_B.PL8, но используют разные палитры Думаю изначально был план, что-то там с палитрой творить и менять цвет юнитам, согласно цвету игрока. Но потом нарисовали для каждого цвет свой файл (ARM_IT_цвет одной буквой.PL8), окраской нужным цветом нужных мест у юнитов )) Мне кажется, что там полно файлов, которые не используются игрой вовсе. TOWN1A.PL8 полная копия TOWN1C.PL8, но я так и не понял что там - не подобрал палитру , да и картинки там занимают на 260 байт больше, чем инфы в файле - вот думаю сейчас над этим...

    Но куча файлов пока не хочет нормально открываться, или они не правильные или еще что. Но я не все магические цифры пока разгадал ))

    Вот думаю сделать, так чтобы автоматом цепляло все палитры и выводило все 27 вариантов файла. В моём варианте лордс 27 палитр валяется в папке.
     
  7. Jordan 63

    Jordan 63

    Регистрация:
    26 янв 2010
    Сообщения:
    480
    В данную игру я играл на 386sx mhz и 6мб ОЗУ, на стратегической карте норм, в бою точно помню юниты прям как улитки двигались.
    Я за эффективность, я думаю, что они не стали чистить ресурсы перед релизом игры, что бы новых багов не поймать. Игра выходила на CD там места много.

    Я ратую за то, что такую информацию лучше сохранять, что бы повторно не приходилось ковырять форматы. К примеру много утилит для модификации Arcanum шли без исходников, когда я взялся за написание движка, нашёл выложенные сорцы по графике и смог за пару вечеров сделать вывод графики Arcanum. Иначе пришлось бы искать инфу по крупицам, ковырять формат и т.д Вообщем как ты сейчас. Поэтому открытый код рулит. Та же ситуация была с моддингом Disciples 2. Есть утилиты по редактированию карт, но без исходников и моддеры заново вскрывали продолжительное время форматы карт и саг, хотя лет 20 назад программист Serg, уже писал утилиты для моддинга, но не выкладывал исходники.
    --- добавлено 9 мар 2024, предыдущее сообщение размещено: 9 мар 2024 ---
    Странный подход, если есть 8 цветов и 8 текстур по данному цвету, то в игру придётся грузить всё текстуры, что будет заниматься место. А если сделать одну текстуру и допустим, те места которые можно окрашивать задать специальным цветом, который можно менять при рисовании в игре, можно сэкономить место в ОЗУ. Пример таких игр это, stronghold и fallout tactics. На спрайтах есть опрелеленные участки которым можно задать определённый цвет.
    Опять же это предположение, может там как то хитро всё используется или графика настолько мало весит.
     
  8. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Тут формат то простой, 6 байт осталось разгадать. Если расписать, что да ка - любой сделает за полчаса сам ))

    Ну, это же что видит игрок в своём месте найма войск, значит грузится в начале игры - один файл с нужными картинками - остальные видимо просто лежат на диске... Да и там 5 цветов всего, для пяти игроков. Хотя всё равно, большая часть картинок идентична, вон на скрине видно,что только 7 квадратиков будут отличатся...
     
  9. Jordan 63

    Jordan 63

    Регистрация:
    26 янв 2010
    Сообщения:
    480
    Ага. Ты делаешь за пол часа со среды, а сегодня уже вечер субботы:)
    Описание формата пригодилось бы потомкам.
    --- добавлено 9 мар 2024, предыдущее сообщение размещено: 9 мар 2024 ---
    Ты не связан с разработкой движка Stratagus?
    --- добавлено 9 мар 2024 ---
    Ещё вопрос. А для чего тебе формат графики данной игры? Будешь писать новый двиг?
     
  10. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Не в коем разе, просто ник Stratego был занят ))
    --- добавлено 9 мар 2024, предыдущее сообщение размещено: 9 мар 2024 ---
    Просто хотелось под капот заглянуть, давно мечтал, но думал это будет сложно. Пробовал искать в инете, но не нашёл...
     
  11. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Сделал на свою голову, список палитр и список файлов можно передать. А потом передал туда все фалы из папки, ну прога вроде справилась, но посмотреть - у меня теперь там хрен что сдвинешь, выделишь или удалишь. Так тормозят эти несколько тысяч файлов в одной папке ))
     
  12. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Почти все файлы, связанные с битвой - выглядят повреждёнными, по факту размер файла меньше, чем данных там должно быть. Видимо там используется какой то алгоритм сжатия.
    Ну и что интересно, есть дублирующие файлы, содержат одну и туже картинку,есть которых нет в игре, есть те которым не подходит не одна палитра (это из тех что смог открыть)...
    DEMO2.PL8_ARMITEMS.256.png

    Это DEMO2.PL8, я вообще такого в игре не припомню - сразу видно, что это разрабы что-то оставили. Есть еще три картинки 640х480, к которым не подошла не одна палитра.

    Мои идеи пока иссякли, так что придётся забросить ((
     
    Последнее редактирование: 10 мар 2024
    AndyFox нравится это.
  13. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Закину сюда, текущий вариант - с этим гитхабом замучаешься пароль восстанавливать - всё им не подходит мой новый вариант )) stb - это такая библиотека, которая состоит только из заголовочных файлов, кидаете его к проекту и ничего не надо подключать, для ленивых )) Она нужна для сохранения картинок в формате png.
    Код:
    #include <iostream>
    #include <fstream>
    
    #define STB_IMAGE_WRITE_IMPLEMENTATION
    #include "stb_image.h"
    
    #define STB_IMAGE_WRITE_IMPLEMENTATION
    #include "stb_image_write.h"
    
    using namespace std;
    
    int main(int argc, char** argv)
    {
        if(argc < 3)
            cout << "\033[38;2;255;0;0m < Требуется указать, минимум 1 файл PL8 и минимум 1 палитру >\033[0m" << endl;
    
        string* listNamePal = new string[argc];
        string* listNamePl8 = new string[argc];
        size_t maxPal = 0;
        size_t maxPl8 = 0;
    
        for(int i = 1; i < argc; i++)
        {
            string temp(argv[i]);
            if(temp.length() < 5)
                continue;
    
            string subTemp (temp.substr(temp.length() - 4));
            if(subTemp == string(".256"))
                listNamePal[maxPal++] = temp;
            if(subTemp == string(".PL8") || subTemp == string(".pl8") )
                listNamePl8[maxPl8++] = temp;
        }
    
        if(maxPal == 0)
        {
            cout << "\033[38;2;255;0;0m < Не указано не одной палитры >\033[0m" << endl;
            return 0;
        }
    
        if(maxPl8 == 0)
        {
            cout << "\033[38;2;255;0;0m < Нет файлов для распаовки >\033[0m" << endl;
            return 0;
        }
        // Выводим списи используемых файлов
        cout << "\033[38;2;0;255;125m" << endl;
        cout << "Палитры: " << endl;
        for(size_t i = 0; i < maxPal; i++)
            cout << "\t" << listNamePal[i] << endl;
    
        cout << "\033[38;2;125;255;0m" << endl;
        cout << "pl8-files: " << endl;
        for(size_t i = 0; i < maxPl8; i++)
            cout << "\t" << listNamePl8[i] << endl;
        cout << "\033[0m" << endl;
    
    
    // ===============================================================================
        for(size_t p = 0; p < maxPal; p++)
        {
            // Открываем очередную палитру
            ifstream filePal(listNamePal[p], ios::binary);
            if(!filePal.is_open())
            {
                cout << "\033[38;2;255;0;0m < файл " << listNamePal[p] << " палитры не удалось открыть >\033[0m" << endl;
                continue;
            }
    
            uint8_t color = 0;
            uint8_t Palette[256 * 3];
            // =========== Заполняем рпалитру ==============
    
            for(int i = 0; i < (256 * 3); i++)
            {
                char ch;
                filePal.get(ch);
                    color = ch;
                    color = (color << 2) | (color >> 4);
                Palette[i] = color;
            }
            // ==============================================
            filePal.close();
    
            // Создаём Атласы для каждого файла и записываем на диск, с текущей палитрой
            for(size_t f =0 ; f < maxPl8; f++)
            {
                uint16_t wAtlas = 640;
                uint16_t hAtlas = 480;
                size_t whAtlas = wAtlas * hAtlas * 3;
                uint8_t mapAtlas[whAtlas];
    
                // Заполняем атлас нулевым цветом, это цвет прозрачности
                for(size_t i =0; i < whAtlas; i += 3)
                {
                    mapAtlas[i] = Palette[0];
                    mapAtlas[i + 1] = Palette[1];
                    mapAtlas[i + 2] = Palette[2];
                }
    
                ifstream fileImg(listNamePl8[f], ios::binary);
                    if(!fileImg.is_open())
                    {
                        cout << "\033[38;2;255;0;0m < " << listNamePl8[f] << " файл не найден >\033[0m" << endl;
                        continue;
                    }
                // Получаем размер файла
                fileImg.seekg(0, ios::end);
                    size_t fileSize = fileImg.tellg();
                // fileImg.seekg(0, ios::beg);
    
                // Получаем данные о количестве картинок в файле
                uint16_t countImg = 0; // оличество артинок
                uint32_t offsetData = 8; // Смещение к следущему блоку
                uint32_t offsetImg = 0;  // Смещение к даным скартинкой
                fileImg.seekg(2, ios::beg);
                fileImg.read((char*)&countImg, 2);
                    cout << "\033[38;2;0;208;67m Количество картинок в файле: " << countImg << "\033[0m" << endl;
    
                // Работаем с текущей картинкой
                for(uint16_t i = 0; i < countImg; i++)
                {
                    fileImg.seekg(offsetData, ios::beg);
                        offsetData += 16;
                    uint16_t w = 0;
                        fileImg.read((char*)&w, 2);
                    uint16_t h = 0;
                        fileImg.read((char*)&h, 2);
    
                    if( w*h == 0)
                    {
                        cout << "\033[38;2;255;0;0m" << i << " (" << w << "X" << h << ") " << " < не коректный размер картинки, пропускаем > \033[0m" << endl;
                        continue;
                    }
    
                    // получаем смещение до даных картинки
                    fileImg.read((char*)&offsetImg, 4);
                    if((offsetImg + w * h) > fileSize)
                    {
                        cout << "\033[38;2;255;0;0m  <Картинка № " << i << " выходит за пределы файла, пропусаем> \033[0m" << endl;
                        continue;
                    }
    
                    uint16_t xx = 0;
                        fileImg.read((char*)&xx, 2);
    
                    uint16_t yy = 0;
                        fileImg.read((char*)&yy, 2);
    
                    if( (wAtlas < (xx + w)) || (hAtlas < (yy + h)) )
                    {
                        cout << "\033[38;2;255;0;0m < Картинка " << i << "  не влезает в атлас, пропускаем > \033[0m" << endl;
                        continue;
                    }
                    // Прыгаем к даным картини
                    fileImg.seekg(offsetImg, ios::beg);
                    for(size_t y = 0; y < h; y++)
                        for(size_t x = 0; x < w; x++)
                        {
                            size_t index = ( (y+yy) * wAtlas + (x+xx) ) * 3;
                            fileImg.read((char*)&color, 1);
                                //color = color - 13;
                                size_t col = (size_t)color * 3;
                                mapAtlas[index] = Palette[col];
                                mapAtlas[index + 1] = Palette[col + 1];
                                mapAtlas[index + 2] = Palette[col + 2];
                                //mapAtlas[index + 3] = 255;
                        }
    
                } // Завершаем с текущей картинкой
    
                fileImg.close();
    
                string str = listNamePl8[f] + string("_") + listNamePal[p] + string(".png");
                    cout << "\033[38;2;0;180;57m Записываем даанные в файле: " << str << "\033[0m" << endl;
                stbi_write_png(str.c_str(), wAtlas, hAtlas, 3, mapAtlas, 0);
            } // Завершение работы с конретным файлом pl8
        } // Завершение работы с палитрой
    
        return 0;
    }
    --- добавлено 12 мар 2024, предыдущее сообщение размещено: 12 мар 2024 ---
    Да, можно передавать несколько палитр и несколько файлов, в любом порядке
    В линуксе это будет выглядеть примерно так
    Код:
    ~/PL8$ ./pl8_png A2_MISS.PL8 DOS.256 DEMO.PL8 old.256 DEMO.256
    
    В результате, будет создано из каждого пл файла новый файл, с каждой палитрой. Так что не увлекайтесь )) Для истинных самураев, можно попробовать в папке с ПЛ файлами сделать ./pl8_png * ls -1, но надо сначла собрать программку, а потом её положить в нужную папку...
     
    AndyFox, Neresar, Jordan 63 и ещё 1-му нравится это.
  14. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Если вдруг кто будет пробовать, вариант от Фаргуса ковырять, то ребята из Фаргуса часть файлов переделывали, например часть шрифтов, они не сохранятся адекватно, там не прописано куда класть буквы в атласе, так что увидите только последнюю букву по факту. Там надо отдельными картинками выводить или разрабатывать свой алгоритм раскладывания по атласу. Не знаю на сколько критично, но в стандартных критично шрифтов, для букв разные цвета используются, 0 - прозрачный, а для самой буквы там 13 или 4 может еще какой номер из палитры. А у Фаргуса 0 и 255...

    Ну, и вдогонку в первых Лордах, другой формат pl8-файлов, там основной заголовок 4 байта, а дальше (предположительно по 8 байтов на картинку), но в целом я пока там тоже не понял...
     
    Последнее редактирование: 18 мар 2024
    AndyFox нравится это.
  15. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Глянул во втором цезаре тоже эти пл8, открываются все без проблем, только палитры надо подбирать - в Цезаре их еще больше чем в Лордах... Вообще у этого разработчика могут и в других играх эти форматы быть.
     
  16. Strategus

    Strategus

    Регистрация:
    1 мар 2024
    Сообщения:
    71
    Удалось открыть тайлы территории:
    BASE1C.PL8_BASE1A.256.png

    Изображение не сжатое, так что зря я пытался приладить алгоритмы сжатия. Простой принцип (я лет цать назад читал что-то про такое), суть в том, что записаны только пиксели картинки, а прозрачные пиксели не пишутся вовсе и сохраняется только ромб. Читаются построчно, 2 пикселя, дальше 6, потом 10... и так пока ромб не достигнет полной ширины, дальше на убывание...

    Можно посчитать, что всего используется 48 видов тайлов, для самых частых сделаны дубли, чтобы картинка смотрелась не однообразно. Всего 4 текстурки, на каждый сезон года. Это Осень... первые 6 тайлов - не знаю для чего. Внизу, по 4 на зотоплеие и засуху угодий, а так же 9 неиспользуемых клеток...

    Как понять какой алгоритм использовать для чтения конкретного файла не понятно... Возможно оно вовсе прописано в исполняемом файле... Или я зависимость не вижу...
     
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление