Как я искал (и нашёл! =) рецепт секретного поушена))

Поведайте, какие тайны вы раскрыли в Кирандии.

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 29 фев 2012, 00:14

Малкольмович писал(а):это будет хорошо))
и заодно надо сделать возможность подстановки названий функций-сисколлов MR, ибо оригинальная dekyra знает только LoK и HoF =)

В общем загнал я количество и тип аргументов для функций из K1(на очереди K2). Ругается только на одной функции(o1_fatPrint) которая используется всего один раз в одном скрипте, причем в исходниках скумма написано, что авторы не понимают как эту функцию обрабатывать, потому согласно скумму у нее 6 аргументов, а стек увеличивается на 7. В остальных случаях если аргументы вообще есть, то за вызовом функции, причем следующей командой, всегда следует AddSP с приращением равным числу параметров. Так что наверно я эти лишние AddSP вообще из листинга уберу, а функциям добавлю список параметров...
А вот MR я не воспринимаю, раза 4 пытался играть и бросал в начале, но если ты сделаешь список, то я без проблем добавлю :)

интересно, а у бывших Westwood-овцев остались ли примеры исходников этих скриптов? Интересно было бы посмотреть, с чего все компилилось)

Сомневаюсь, когда-то пытался искать и ничего не нашел...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 29 фев 2012, 14:37

так этот список, на самом деле, легко выцепляется из исходников скумма, но я попытаюсь тогда в ближайшее время выковырять))
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 29 фев 2012, 17:08

Малкольмович писал(а):так этот список, на самом деле, легко выцепляется из исходников скумма, но я попытаюсь тогда в ближайшее время выковырять))

Из script_mr.cpp легко выковыривается просто список функций, это я и сам могу сделать за несколько минут, а вот с прописыванием аргументов придется помучаться, т.к. функций под две сотни :) Глянь как делалось для K1: kyra1_funcs.

Формат такой:
имя_функции типы_аргументов(s - строка, i - целое, r - возвращаемое значение, если есть), после ';' комментарий, опять же если есть.
# ... - сюда я запихнул функции из скумма, думаю используемые выводить отдельным блоков в конце, чтоб в исходниках не ковыряться. Не обязательно...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 29 фев 2012, 18:22

А поддержка второй Кирандии в dekyra совсем слабенькая, скорее на раннюю бетку похожа. Во-первых, там прописано на 7 функций меньше и вызовы этих недостающих функций определяются как tries to call illegal opcode param. Во-вторых, многие из прописанных функций помечены как "unk..." или имеют совершенно другие имена. Например, в тулсах drawShapeFrame, а в самом скумме - setCharacterPos. И таких мест полно...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 01 мар 2012, 14:38

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

ну я имею в виду не просто список опкодов и названий (там и минут не надо - несколько секунд =), а список прототипов врапперов этих опкодов.
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 01 мар 2012, 15:33

Проверяй :)
Прописал функции из K2 и запихнул список MD5 для файлов из K1, по ним экстрактор пытается автодетектить версии. Кроме того вывод теперь в UTF-8 и нормально обрабатывают немецкий с французским, т.е. вместо 'Ђa doit €tre la Vo–te du Kyra!' выдаваемых dekyr-ой получаем нормальные 'Ça doit être la Voûte du Kyra!'. Но язык определяется по расширению(emc, gmc, fmc), что не всегда соответствует действительности, нужно еще пару ключей добавить...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 01 мар 2012, 20:37

о, сегодня проверю)

ба, дотнет четвертый...

PS. сегодня же и поковыряю список функций MR)
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 02 мар 2012, 00:35

Малкольмович писал(а):ба, дотнет четвертый...

А на чем еще утилиты писать? :)

ps. Обновил, добавил список функций(без аргументов) для К3, автодетект для K2(если не 1 и не 2, то 3), а также ключи для принудительного выбора версий и языков.

pps. И убрал из листинга лишние AddSP после Call...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 02 мар 2012, 19:13

ну я на сишнике пишу, допустим)) максимум, что нужно - это runtime-либа, которая весит несколько метров, вроде, а тут фреймворк 40 мегов) ну это ладно, на вкус, на цвет и на эффект все поушены разные)

кстати, я сделал список функций для 3 кирандии (в начале файла я выписал те функции, которые MR получил в наследство от движков v1 и v2).

Кстати, я проверил декомпилятор, для начала уже вполне хорошо)) Радует то, что теперь всякие PushRetOrPos нормально расшифровываются) Единственное - dekyra пихала backward-ссылки (в нужном месте кода упоминание о том, что сюда с адреса такого-то существует jmp), их вот как-то не хватает...

и я бы конструкции типа

0x0A4E: 4405 push 5
0x0A50: 4405 push 5
0x0A52: 4EA9 k2_zanthiaChat() //"si"
0x0A54: 4C02 SP += 2

транслировал бы в подобное:

k2_zanthiaChat("My what a vibrant light.", 5);
0x0A4E: 4405 push 5
0x0A50: 4405 push 5
0x0A52: 4EA9 call k2_zanthiaChat(string text, int num) // Says something
0x0A54: 4C02 SP += 2

то есть пытался бы перевести по максимуму в высокоуровневые команды, в том числе подставляя строки)

Зато вот дальше идет какая-то магия, которую, вероятно, так просто не транслируешь(

0x0A56: 4C01 SP += 1
0x0A58: 4801 popPos
0x0A5A: 4407 push 7
0x0A5C: 4701 pushBPAdd 1
0x0A5E: 5108 [SP] = a + b
0x0A60: 4E94 k2_getHiddenItemsEntry() //"ir"
0x0A62: 4C01 SP += 1
0x0A64: 4200 pushRet

тут даже я с трудом разбираюсь с этим стековым волшебством, не то что декомпилятор)
Вложения
kyra3_funcs.rar
(4.77 КБ) Скачиваний: 175
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 02 мар 2012, 19:53

Малкольмович писал(а):ну я на сишнике пишу, допустим)) максимум, что нужно - это runtime-либа, которая весит несколько метров, вроде, а тут фреймворк 40 мегов) ну это ладно, на вкус, на цвет и на эффект все поушены разные)

Списал вчера бетку 11-й студии, под XP она уже не компилит С++ код, а на Висте уже стоит .Net 3.5 :) С другой стороны экстрактор ведь не только со скриптами работает, хотя даже с ними были бы проблемы(т.к. UTF-8 С++ не понимает и для MD5 стандартных функций нет), там же еще и графика, а на C# я спокойно открываю и сохраняю те же png без лишних библиотек...

кстати, я сделал список функций для 3 кирандии (в начале файла я выписал те функции, которые MR получил в наследство от движков v1 и v2).

Сегодня-завтра добавлю.

Кстати, я проверил декомпилятор, для начала уже вполне хорошо)) Радует то, что теперь всякие PushRetOrPos нормально расшифровываются) Единственное - dekyra пихала backward-ссылки (в нужном месте кода упоминание о том, что сюда с адреса такого-то существует jmp), их вот как-то не хватает...

Это я планировал следующим этапом, ведь нельзя сворачивать команды если нет уверенности, что они атомарные и между ними откуда-то не осуществляется переход.

и я бы конструкции типа

0x0A4E: 4405 push 5
0x0A50: 4405 push 5
0x0A52: 4EA9 k2_zanthiaChat() //"si"
0x0A54: 4C02 SP += 2

транслировал бы в подобное:

k2_zanthiaChat("My what a vibrant light.", 5);
0x0A4E: 4405 push 5
0x0A50: 4405 push 5
0x0A52: 4EA9 call k2_zanthiaChat(string text, int num) // Says something
0x0A54: 4C02 SP += 2

то есть пытался бы перевести по максимуму в высокоуровневые команды, в том числе подставляя строки)

Да сам так хочу, но даже в относительно простых случаях вместо аргументов может быть не "push 5", а "push 5; push 5; [SP] = (a * b)", т.е. "push 25" так что сначала нужно разобраться с математикой... Кстати, у тебя старая версия, в новой не должно быть SP += 2.
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 03 мар 2012, 13:29

Уф, с MR все несколько сложнее, там emc трех типов. Обычно в паке лежит одноименный emc, он обрабатывается как обычно, но иногда есть еще другие, более мелкие диалоговые скрипты, для них нужно загружать другой набор функций. А еще бывают анимационные скрипты управляющие анимацией в *.shp, для для них нужен третий набор. Так что опять пришлось играться с хешами чтобы различать кто есть кто :) Кстати в HoF тоже три набора функций: для *.tim, с которым я еще не разбирался, и для анимации, но пока непонятно где именно они хранятся...
KyrExtractor
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 03 мар 2012, 19:11

Добавил тестовую поддержку основных математических операций(+, -, *, /) и подстановку аргументов в функции, если их удалось свернуть до простых чисел. Теперь вот такой кусок кода:
Код: Выделить всё
push 15
push 120
push 60
[SP] = a - b
push 166
push 4
push 2
k1_customPrintTalkString()  //"isiii"
SP += 5

выглядит как:
Код: Выделить всё
k1_customPrintTalkString(2, "Let go of the branch, Merith.", 166, 60, 15)  //"isiii"

Кроме того появился ключ "-so", который отключает оптимизацию кода, и ключ "-all", который позволяет распаковать сразу все pak или emc находящиеся в текущем каталоге.
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 05 мар 2012, 17:52

да, в Scumm-e под эти скрипты даже выделены отдельные группы опкодов, что свидетельствует о том, что хотя бы формат у этих скриптов должен быть похож (за исключением, собственно, номеров и параметров сисколлов)

во, а такая свертка - это круто, это то, о чем можно было только мечтать при чтении декомпиленного dekyr-ой кода)

хотя логика сумрачного вествудовского гения, делающего куски кода типа
Код: Выделить всё
push 1
push 2
[SP] = a + b
и почему они это не заменили
Код: Выделить всё
push 3
мне оказывается непонятна)))
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 05 мар 2012, 19:52

Малкольмович писал(а):и почему они это не заменили

Это мелочи, там в одном месте складывается подряд 13 раз и получается "push 24" :) Может они вообще всю математику в скрипты перенесли...
Я сейчас думаю как свернуть if-ы и можно ли нормально детектить локальные функции и переменные...
Последний раз редактировалось Reflector 06 мар 2012, 01:37, всего редактировалось 1 раз.
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 05 мар 2012, 22:27

Ха, это было легче чем я думал :)
Теперь вместо:
Код: Выделить всё
[SP] = (a > b)
ifNotJmp 0x0CC2
pushBPNeg 4
push 27
[SP] = (a == b)
ifNotJmp 0x0CB8
push 151
k3_setGameFlag()  //"i"
SP += 1
goto 0x0CC0
pushBPNeg 4
push 0
k3_setInventorySlot()  //"iir"
SP += 2
k3_removeHandItem()  //""
push 0
push 30
k3_delay()  //"ii"

выдает:
Код: Выделить всё
if (a > b)
   pushBPNeg 4
   push 27
   if (a == b)
      k3_setGameFlag(151)  //"i"
   else
      pushBPNeg 4
      push 0
      k3_setInventorySlot()  //"iir"
   k3_removeHandItem()  //""
k3_delay(30, 0)  //"ii"

Для всех пяти сотен скриптов закрываются все открывающиеся скобки, только в одном goto, который я принимаю за начало else, прыгает слишком далеко и видимо является вызовом функции(добавил в исключения).
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 07 мар 2012, 18:00

о! вот это круто!
и кстати, это свидетельствует о том, что компилер неоптимизирующий, и к тому же шаблонно-основанный (т.е. не разбрасывает куски кода по адресам, а просто заменяет условия, if, else и т.п. на соответствующие куски байткода =)

и, наверное,
Код: Выделить всё
   push 27
   if (a == b)
можно свернуть до
Код: Выделить всё
   if (a == 27)
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 07 мар 2012, 20:24

Малкольмович писал(а):о! вот это круто!
и кстати, это свидетельствует о том, что компилер неоптимизирующий, и к тому же шаблонно-основанный (т.е. не разбрасывает куски кода по адресам, а просто заменяет условия, if, else и т.п. на соответствующие куски байткода =)

Так я сразу сказал, что компилятор простейший :)

и, наверное,
Код: Выделить всё
   push 27
   if (a == b)
можно свернуть до
Код: Выделить всё
   if (a == 27)


В новом билде сворачивается даже до:
Код: Выделить всё
 if (gvar[15] == 27)
или
 if (gvar[7] && !b)
или
if (![SP])

Доразберусь с локальными функциями и вечером постараюсь обновить...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 07 мар 2012, 22:09

Готово! Теперь в листинге одновременно выводятся обычные команды и свернутые, чтобы проще было искать ошибки. Кроме того последовательность "pushPos; goto" теперь трактуется как вызов локальных функций func_xxxx() с подстановкой аргументов, если за goto идет addSP. Соответственно popPop превратилась в return или "return k", если можно получить возвращаемое значение. Ну и по мелочам довольно много изменений, теперь нужно заняться аргументами локальных функций, они по индексу получаются так что можно получить что-то типа "var[n]"...
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Reflector » 09 мар 2012, 15:57

Update, это уже практически финальная версия, теперь код выглядит так:
Код: Выделить всё
| 0000 | pushVar 2       |
| 0002 | pushVar 1       |
| 0004 | pushBPAdd 4     |
| 0006 | pushBPAdd 3     |
| 0008 | pushBPAdd 2     |
| 000A | pushBPAdd 1     |
| 000C | execOpcode 64   |
| 000E | addSP 6         |
| 0010 | pushRet         |
| 0012 | popRet          |
| 0014 | popPos          |
| 0016 | popPos          | return checkInRect(arg[1], arg[2], arg[3], arg[4], gVar[1], gVar[2])

| 0018 | pushVar 1       |
| 001A | execOpcode 4    |
| 001C | pushRet         |
| 001E | eval (a < b)    |
| 0020 | ifNotJmp 0x0030 | if (gVar[1] < getCharacterX())
| 0022 |                 |     
| 0024 | push8 1         |     
| 0026 | push8 5         |     
| 0028 | push8 50        |     
| 002A | execOpcode 3    |     refreshCharacter(50, 5, 1)
| 002C | addSP 3         |     
| 002E | goto 0x003A     | else
| 0030 | push8 1         |     
| 0032 | push8 3         |     
| 0034 | push8 51        |     
| 0036 | execOpcode 3    |     refreshCharacter(51, 3, 1)
| 0038 | addSP 3         |     
| 003A | push8 0         |
| 003C | popRet          |
| 003E | popPos          |
| 0040 | popPos          | return 0

Добавился доступ к аргументам функций(pushBPAdd/PopBPAdd), а также появились локальные переменные(PushBPNeg/PopBPNeg). Первые обозначаются как arg[n], вторые как var[n]. Для переменных компилятор в начале функций резервируется место посредством subSP и затем вставляет addSP перед каждым return, но все subSP/addSP во всех скриптах в итоге свернулись, теперь этих команд нет вообще. Также не осталось ни одной pushRet/popRet. В общем остались мелочи и отлавливание возможных багов, так что если надумаешь раскрывать очередной секрет Кирандии, то следи одним глазом за правильностью преобразований :)
Reflector
(2) Житель Милтонии
 
Сообщения: 163
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

Re: Как я искал (и нашёл! =) рецепт секретного поушена))

Сообщение Малкольмович » 11 мар 2012, 21:30

чудесно! сегодня попотрошу еще какие-нибудь скрипты и расскажу о впечатлениях))
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

Пред.След.

Вернуться в Секреты Кирандии

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1