Pharaoh + Cleopatra

Pharaoh + Cleopatra

Ikke nok vurderinger
Pharaoh - Как редактировать Шрифт
Av Telariust
Для Caesar3 + Pharaoh + Zeus + Emperor
   
Utmerkelse
Favoritt
Favoritter
Fjern som favoritt
Вступление
(Обзор в стадии бетта версии, улучшаю)
(больше картинок, еще больше!)

Главный Советник, Telariust, приветствует Вас!



For FR, DE, IT, SE, ES, PT, PL, CN, KR,.. and other

Dear international readers!
Use GoogleChrome to automatically translate the article.



Жили-были RU фанаты, которые играли в Фараон.
Однажды скучный печатный Шрифт от RU (Fargus) совсем надоел.
И тут началось..



Этот обзор является дополнением к обзорам

https://steamcommunity.com/sharedfiles/filedetails/?id=2748181836

https://steamcommunity.com/sharedfiles/filedetails/?id=2770884452


Как редактировать Шрифт
"SGReader" для чтения текстур
(2008-2020, автор Pecunia/bvschaik/"Bianca van Schaik")
github.com/bvschaik/citybuilding-tools/releases/tag/sgreader-v1.1

"C3Modder_v2" для записи текстур
(2008-2012, автор Trium/"David Miller")
yadi . sk/d/OLeXXZOC3SG6w7

*.555 для хранения изображения и кадры анимации.
*.sg3 для хранения ID, offset, length, width, height, type, ..

Пример редактирования изображения в Caesar3
Dimitrius, 2012
web.archive.org/web/20191206223846/caesar-iii.ru/bibliotheca/mod_gfx.html





Наблюдаю баг, при вводе ID, он на 1 меньше указанного "SGReader v1.1"
(ну для программистов считать с нуля - это норма, а ошибки на единицу типичны)

В описании в "C3Modder" сказано, что индексация с "0" неверна, но такая только для совместимости с "SGReader v1.0".
(в "C3Modder" невозможно изменить изображение с ID=0)
В "SGReader v1.1" индексация исправлена и начинается с "1".



Наблюдаю баг, кнопка для указания пикселя для прозрачности не работает для маленьких изображений.
(а изображения букв в Шрифтах все мелкие)

Родной Paint (в Windows) при сохранении .png заменяет прозрачный фон белым.
Это делает его непригодным для редактирования.
Можно использовать Paint.NET, он сохраняет прозрачный фон.
(и даже понимает, что такое слои, так что Фотошоп здесь не нужен)



C3Modder может сохранять изображения с другой шириной и высотой.
Речь не идет о встроенном авторесайзере, который подгоняет изображение пользователя под размеры изображения ID.
А наоборот, сохранение изображения пользователя без изменений.

C3Modder берет ширину и высоту из файла .sg3, хотя мог бы спросить у пользователя.
(полагаю, это защита от дурака)

Для type=0 (несжатое) and type=256 (сжатое)
Посмотрим смещение (offset) изображения (SGReader).
Откроем калькулятор (нажать Win+R =>calc)
Переключите Вид =>Программист
Убедитесь что переключатель в положении (*)Dec (decimal, 10base)
Введем смещение и кликаем на (*)Hex (hex, 16base)
Например, это будет "1F319"
Теперь нужно перевести в Обратный Порядок Байт (Big Byte Order).
Это будет "19F301" (добавляем ноль слева до четности, 1 байт это 2 разряда 16base)
Открываем файл .sg3 в HEX-редакторе и ищем в HEX строку "19F301"
Для каждого изображения выделено #64 байта для описания.
Измените Ширину(#21байт) и Высоту(#23байт) (не забывайте переводить Dec<=>Hex)
Сохраняем.

Только для type=256 (сжатое)
Посмотрим смещение (offset) и длину(length) изображения (SGReader).
Откроем калькулятор (нажать Win+R =>calc)
Переключите Вид =>Программист
Убедитесь что переключатель в положении (*)Dec (decimal, 10base)
Введем смещение и кликаем на (*)Hex (hex, 16base)
Например, это будет "1F319"
Открываем файл .555 в HEX-редакторе и переходим по смещению "1F319"
Длина (length) это число байт для замены. Заменяем их на "00".
Сохраняем.

Теперь это изображение не откроется в SGReader (или будет отображено неверно)
В C3Modder сохраняем новое изображение с новыми шириной и высотой.
Переоткрываем SGReader и проверяем - теперь отображается правильно.



Об инструкциях выше по изменению ширины и высоты.
type это формат хранения, разработанный Sierra (.sg2/.sg3/.555)
В файле .sg3 выделено #64 байта описания для каждого изображения.
Недостаточно просто подменить type (#51,#52 байты).

Если type подменен, В Игре вместо изображения - артефакт.

Если type подменен, C3Modder прерывается с ошибкой.
При сохранении C3Modder сначала запрашивает подтверждение, читая и отображая изображение (как SGReader).
Если type не соответствует реальному содержимому, это приводит к ошибке.
Возможно, он даже может сохранить, но до этого не доходит.
Функция подтверждения может быть отключена, нужно понять, как это сделать.
(также можно исправить изображение заменив содержимое на 00 в файле .555, чтобы избежать ошибки)

Статья от создателя CaesarAI (клон Caesar3)
habr.com/en/post/221913/
..изображения делятся на три типа:
- простые (bmp);
- изометрические (isometric);
- с альфа каналом;

Для "isometric" используется type=30
Шрифты не используют это.
(заметка, C3Modder_v2 имеет несовместимости при изменении изометрических изображений, отличных от фиксированных размеров Ширины в Caesar3)

Косвенным признаком альфа-канала является использование 72 байт на изображение (+4 alpha_offset, +4 alpha_length, вместо обычных 64 байт) в файле *.sg3.
Шрифты не используют это.

Остаются "простые (bmp)", хотя они совсем не простые.
Есть флаг ".compr_flag", который указывает на сжатие (основано на прозрачности).
Два изображения имеют одинаковый размер и схожи по содержанию.
Здесь видно, как их длина отличается почти в два раза.

Потому что формат type=256 использует сжатие, а type=0 — нет.
По этой причине возникает ошибка при подмене type.


Про прозрачность
Статья от создателя CaesarAI (клон Caesar3)
habr.com/ru/post/221913/
В игре Сaesar III текстуры с прозрачностью не используются, они будут задействованы позже в этой серии игр (Pharaoh, Cleopatra и др)
..так вот почему в старых Шрифтах розовый фон, но в Игре он отображается прозрачным.
Тогда (1999) прозрачности еще не было, и розовый использовали как костыль.

Похоже, розовый как прозрачный оставили для обратной совместимости, и он как и ранее может использоваться как аналог прозрачности.
(только для type=0)




Наблюдаю баг, C3Modder не может правильно сохранить прозрачные изображения с type=0 (несжатые)

Демонстрация с польским Шрифтом от Pharaoh (PL или EN - без разницы).
Выберем буквы "a" и "c", они имеют одинаковые ширину и высоту, но разное type (сжатие).
"a" имеет type=256 (сжатые), "c" имеет type=0 (несжатые).

Изображения букв были извлечены с помощью SGReader.
Они оба имеют прозрачный фон.
Теперь попробуем сохранить их обратно в Шрифт с помощью C3Modder_v2.

Перед сохранением C3Modder запрашивает подтверждение и показывает изображение.
Здесь видно, что у изображения type=256 прозрачный фон, но у изображения type=0 розовый фон!
Значит, либо SGReader либо C3Modder неправильно извлекают изображения.

Четыре предосмотра до замены показывают, что изображение от пользователя не влияет, значение имеет только type изображения, ID которого читается из .sg3/.555.

Далее, после сохранения изображения type=0 его прозрачность превращается в черный цвет, "1F F8" стало "00 00".
Содержимое _Fonts.555 до и после сохранения изображения type=0.

Можно подумать, что проблема в C3Modder.
Однако, C3Modder следует строго по стандарту - для type=0 (несжатое) изображения не существует прозрачности (костыль с розовым в Игре это причуда, а не стандарт), а значит 00 это черный цвет!

Таким образом, чтобы сохранить изображение с прозрачностью в ячейку type=0 , придется предварительно изменить прозрачные пиксели на розовые.
Или нужно дописать код для type=0, прозрачность через розовый, заменить "00 00" на "1F F8".



..Но тогда как SGReader понимает, что розовый это прозрачный?
github.com/bvschaik/citybuilding-tools/blob/master/sgreader/sgimage.cpp void SgImage::set555Pixel(QImage *img, int x, int y, quint16 color) { if (color == 0xf81f) { return; }
Оказывается, SGReader имеет правило, замена всех розовых (F8) пикселей на прозрачные.
..Однако, эта замена осуществляется и для сжатых изображений, которые уже имеют собственную прозрачность и используют розовый по назначению.
Тоесть SGReader при извлечении исправляет изображение, и показывает/сохраняет его не таким какое оно было!

Чтобы сохранить такое исправленное изображение назад в Игру (несжатое, type=0), необходимо отредактировать его назад, заменив прозрачные пиксели на розовые.
Редактировать назад 1500 изображений (после пакетного извлечения SGReader) очень весело.
Придется связаться с Автором или выпустить исправленную версию SGReader самому.
А пока - остерегайтесь, SGReader везде заменяет розовый (F8) цвет на прозрачный!



..Но тогда почему SGReader сохранил мне розовые буквы "к" "К" (первая картинка в начале раздела "Про прозрачность") не заменив розовый на прозрачный???

..Как выяснилось, в Шрифтах розовый встречается двух оттенков F8(Caesar3) и FC(RU).
Игра(Фараон) оба цвета считает прозрачными (возможно, эти близкие 32битные цвета одинаковы в 16битной Цветности).


- Игра считает оба розовых прозрачными;
- SGReader для розового F8 делает вид что он прозрачный, а для розового FC нет;
- C3Modder честно отображает оба розовых как они есть;

Честность и соблюдение стандарта это замечательно.
Однако не помешает прикрутить розовый костыль для C3Modder, чтобы можно было сохранять прозрачные изображения в ячейку type=0 для старых несжатых изображений с костылем прозрачности через розовый.



Когда вы сохраняете изображение с другими размерами, то используется авторесайзер для подгонки размеров, при этом непредсказуемо меняется прозрачность, основанная на розовом костыле.
(Это происходит из-за изменения цвета пикселей при интерполяции.)

C3Modder для Emperor
История событий

Под Emperor подразумевается 4я Игра из серии
"Emperor: Rise of the Middle Kingdom" (2002г, про Китай)

Как известно, C3Modder_v2 не может изменять изометрические изображения в Императоре.
vk.com/wall-18455403_850



(спустя время) (2022)
Воспроизвел ошибку C3Modder_v2 при попытке замены изометрической текстуры, на примере Горы (ID=1442).

C3Modder v1 был создан для .sg2 (Caesar3), затем улучшен до v2 чтобы корректно обрабатывать прозрачность в Pharaoh.
Но он совсем ничего не знает о новшествах в Zeus и Emperor.

ID=1442, это не изображение с альфа-каналом.
В .sg файле используется стандартные 64 байта на каждое изображение.
А для изображений с альфа-каналом требуется 72 байта (64+8).

ID=1442, флаг внешнего ресурса (#53byte, external) равен нулю, а значит это не такой случай.

ID=1442, это изображение изометрической проекции, на что указывает ромбовидность и явное указание type=30 (#51,#52 байты).
@ README
"..Что касается изометрии, вы не можете заменить 2х2 на 3х3. Игра может захотеть сохранить графику, но она упадет, когда попытается сопоставить 3x3 с пространством, занимаемым зданием 2x2. Эти изображения должны иметь фиксированную ширину — 58 пикселей для одной плитки, 118 пикселей для 2x2, 178 для 3x3, 238 для 4x4 и 298 для 5x5. C3Modder рассмотрит свойства заменяемой вами графики и подгонит вашу по ширине. Высота не имеет значения (в пределах разумного), поэтому пропорции оригинала будут сохранены.."

Есть вот такая великолепная статья от русского разраба, который в 2014 начал разработку CaesarAI (клон Caesar3).
(он так и не довел проект до конца, забросив в 2015, но ему помогал Pecunia/bvschaik, который в 2018 доделал его проект известный всем как Julius)
habr . com/ru/post/221913/
Если посмотрите в "Много кода" то обнаружите что 2/3 кода посвящено обработке именно изометрическим изображениям.
Причем там куча привязок к статическим значениям Ширины из Caesar3
width=10,26,58,118,178,238,298
Напомню, Ширина Горы (ID=1442) равна 398 (и такого числа там нет)
Этот код получен путем обратного инженеринга (восстановлен из машинного кода Caesar3 через отладчик), а значит это не костыли от Автора CaesarAI, а реальные сложные случаи, требующие индивидуальной обработки.

Файлы C3Modder содержат скрипты в формате XML.
Интерпретатор скриптов (в отличии от бинарного кода .EXE) позволяет пользователю самостоятельно в блокноте изменять скрипты.
(именно отсюда эта вычурность с тремя окнами и выделение имени скрипта мышью для его запуска)

Общее сообщение об ошибке упоминает visual.sou, но реальная проблема не в нем.

Я полагаю, в С3Modder просто отсутствует код для обработки других Ширин изометрических изображений.



(спустя время)
..и содержится этот код в файле C3M.cha и C3M.im
где C3M.cha это исходный код в виде скриптов.
где C3M.im бинарный образ, созданый из .cha .

Вращение колеса мыши меняет размеры изометрического ромба произвольно, а не фиксированными шагами "58,118,178,238,298".
Но скорее всего это недоделанное наследие от Rectangle прямоугольника, который не ограничен.

В C3M.cha из "58,118,178,238,298" есть только "58".
..а значит эти значения либо в base16 либо вычисляются интерактивно по формуле..

Совсем недавно я выяснил, как вручную изменять размер и тип любого изображения.
Напоминаю, это было необходимо для редактирования Шрифтов, статья обновлена.
Поскольку в Шрифте около 1500изображений, то править их руками сомнительное удовольствие.
Уже сейчас, лишь бегло посмотрев на C3M.cha, я точно знаю что можно отключить подтверждение(превью) и авторесайз размера входящего изображения, и мне не придется больше мучиться с HEX-редактором.

Чтобы проверить набор "58,118,178,238,298", я заменил нулями Гору (ID=1442).
Это позволило обойти ошибку на подтверждение(превью) и успешно сохранить новую Гору.
Новое изображение оказалось повреждено, потому что было преобразовано для Ширины 298.
Вопрос теперь как добавить в набор Ширину 398.

Алгоритм хранения изометрических изображений особенный.
Ромб (автор зовет его diamond) отделяется и хранится отдельно.
"Вычислите вершины полилинии, которая представляет собой ромбовидную форму соответствующего размера для моего размера в экранной графике и ограничивающего прямоугольника, и инициализируйте экземпляры соответствующих классов для хранения в переменных моего экземпляра"

.. а вот и формула
tilesForSize: n midOffset := n*60-2/2 -1.
Казалось, почему бы не написать "n*60-2", зачем этот прикол с "2/2".
По моему опыту программирования именно такими хаками косвенно определяют тип для переменной во всяких полуСишных недоязыках.
Никогда не трогайте подобное, полагая, что вы сильно умнее того, кто это написал.
058=1*60-2
118=2*60-2
178=3*60-2
238=4*60-2
298=5*60-2

В Императоре изменили размер Тайла? (Тайл/Клетка/Ячейка)
(в Caesar3 60пикселей, а в Императоре 80пикселей)
(...и вот тут мне вспоминается про увеличение качества графики в Императоре на 25%)
078=1*80-2
158=2*80-2
238=3*80-2
318=4*80-2
398=5*80-2

В .sg3 для ID=1442 в #56 байте указано 5тайлов.
C3Modder считает 5*60-2=298 вместо 5*80-2=398 , пытается открыть изображение на предосмотре и падает.
При подмене нулями не падает и сохраняет новое изображение как 298.
SGReader пытается прочесть ширину 398 с 298 ромбом и отображает кривое изображение.

Ватсон! Телеграфируйте в Баскервиль Холл, йа разгадал это дело! :D

Поскольку 60пикселей на Тайл считался нерушимой константой при разработке, то в коде просто дофига так называемых "магических" констант, которые так или иначе "волшебным" образом завязаны на 60.
(60/30/15/14/29/1800) ..исправляю.. (80/40/20/19/39/3200) и, о чудо, оно работает!

wdfiles . ru/d0153e



(спустя время)
багрепорт от Вадима
"..Кстати, без некоторых проблем все же не обошлось. Все элитные дома содержат в себе небольшой баг с какой-то мелкой чертой ровно посередине. Она появляется после экспорта спрайта в игру.."
Спасибо за баг-репорт, и я ожидал чего-то подобного.
Похоже на баг единицы при вычислении Высоты поли-линии.
Высота этих изображений нечетная? (тогда деление с округлением приводит к потере единицы)
Возможно, этот баг был начиная с Цезарь3, но там разрабы никогда не использовали нечетную высоту, а в Императоре начали использовать.
Подождите пока с редактированием таких изображений.




Я продолжаю изучать и менять код C3Modder, чтобы облегчить себе же дальнейшую работу при редактировании Шрифтов.
Разбираюсь как работает язык и сам скриптовый фраемворк.
В идеале нужно добавить в графический интерфейс возможность замены размера, типа, и прочее.
Чтобы был один С3Modder, а не куча разных модификаций.
(в процессе)


Про формат .sg2/.sg3 и .555
*.555 stores pictures and animation frames.
*.sg3 stores ID, offset, length, width, height, type, ..

C3Modder v1 - понимает только .sg2 (Caesar3)
(мне так и не удалось найти его)

C3Modder v2 - понимает .sg3 (Pharaoh, Zeus, Emperor)
(но не все, внешние изображения не поддерживает)

Про разницу форматов - старый .sg2 и новый .sg3
  • сжатие основанное на прозрачности;
    @ README
    "..C3Modder теперь должен обрабатывать прозрачную графику.."
    "..Другой вопрос, с которым нужно иметь дело, — это прозрачность. Это доставило мне больше хлопот, чем любая другая часть программы, и я все еще не доволен на 100%.."
  • альфа-канал (связано с прозрачностью и наложением);
    @ README
    "..Файлы изображений используют разные методы для указания того, какие пиксели должны быть прозрачными .. иногда используется запасной канал 32-битных изображений (альфа-канал) ... Если не возвращается ни одна используемая маска, она пытается создать ее из альфа-канала. Многие изображения не используют альфа-канал и устанавливают все нули, и в этом случае мы получаем одну большую бесполезную маску без отверстий, поэтому все изображение бесполезно прозрачно. Но нам может повезти.."
  • внешние изображения из других .sg3/.555 файлов;
    @ README
    "..До тех пор он будет работать только с 555, имеющими связанный SG2, и не будет обрабатывать внешние изображения, т. е. те, которые указаны в SG2, но не хранятся в том же 555. Однако большая часть, если не вся графика, отображаемая на карта исходит от внутренних 555, и это ограничение не должно серьезно повлиять на ваши планы.."
    (верно для Caesar3, для остальных Игр серии неизвестно)

Pecunia(bvschaik, Bianca van Schaik) и другие обсуждают как сделать SGWriter.
(они пока еще не знают о существовании C3Modder)
caesar3.heavengames.com/cgi-bin/forums/display.cgi?action=st&fn=1&tn=7451&st=25

@ Pecunia
..в файлах .sg2/3 хранится намного больше информации, помимо данных изображения: размеры, смещения анимации, может ли анимация также работать в обратном направлении и т. д.

@ user3
..sgreader не сохраняет полную структуру каталогов 555 и даже не пытается разархивировать структуру каталогов sg.

@ Pelagius_II
..каждый файл .SG ссылается на один или несколько файлов .555 для хранения данных изображения, а в случае «внешних» ссылок несколько файлов .SG могут ссылаться на один и тот же файл .555. Это влечет за собой то, что любые модификации данного файла .555 потребуют перезаписи всех файлов .SG, которые ссылаются на него, и вы не можете быть уверены , какие файлы .SG делают это, пока не проанализируете все файлы .SG.их. (Сами файлы .555 представляют собой просто тупой набор сжатых изображений — сами по себе они не имеют структурных метаданных, указывающих, кому они принадлежат.)

@ Pelagius_II
..Во многих случаях на определенный фрагмент данных изображения ссылается только один файл .SG, но из-за кодирования длин серий для прозрачности многие изображения с одинаковой шириной/высотой будут сжиматься до разных размеров, поэтому вы не можете просто заменить старое изображение новым и полагаться на то, что втиснете его в тот же слот. Файлы .555 похожи на стопку книг, где каждая «книга» представляет собой определенное изображение, спрайт или анимационный кадр. Если вы хотите добавить/удалить/заменить книгу на полпути вниз, вы также должны поднять или опустить все книги сверху. И поскольку все файлы .SG относятся к данной книге по высоте, что также требует обновления их данных.


Как править код C3Modder
Cincom's Smalltalk environment, VisualWorks
Он также называется как Pharo (Фаро?)
https://en.wikipedia.org/wiki/VisualWorks

Smalltalk - это объектно-ориентированный язык программирования.
Производительность и пропускная способность могут приблизиться к производительности C++, Fortran , Pascal или Ada.

VisualWorks - это программа запуска, Launcher, центр управления, стартовая площадка.
Позволяет очень быстро разрабатывать приложения, компиляция занимает меньше секунды.

В C3M.cha - исходный код программы, классы, методы, переменные;
В C3M.im - скомпилированный бинарный образ программы;

Можно в Системе ассоциировать открытие всех .im с C3M.exe.
Но когда запускаете C3M.exe , то он подгружает одноименный файл с расширением .im
Поэтому лучше сделать несколько вариантов .exe и .im с разными именами.

Когда запускаете C3M.exe , то он подгружает одноименный файл с расширением .cha , который является источником имен для классов/методов/переменных.
Без .cha работать будет, но при редактировании в "System Browser" будет потеря имен, а потому использование неговорящих названий.

Файл .cha содержит исходный код, но реально является логом для исправлений кода.
Он быстро засоряется, поэтому хранить и редактировать в нем программу нежелательно.
Также, смещения на имена в .cha прописываются в .im при компиляции, и если после компиляции .im вы меняете что-то в .cha, то в "System Browser" будет потеря имен и использование неговорящих названий.

Исходный код можно редактировать в "System Browser" и выгружать класс в файл .st.

А можно править прямо в файле .cha (но переименовать) и загружать в "System Browser".
Как открыть "System Browser", загрузить обновленный .cha и скомпилировать .im


Какие бывают проблемы при программировании
progi.pro/pharo-t5300/1


Про ошибку visual.sou
Про ошибку "ERROR_FILE_NOT_FOUND" в файле "visual.sou"



Это общее сообщение об ошибке.
Общее сообщение об ошибке упоминает visual.sou, но реальная проблема не в нем.
Просто исключение приходит из него, поэтому типо он и виноват, но реально - нет.


Заключение
Отредактированный Шрифт обретает Вечную Жизнь в Загробном Мире! :D