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

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

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

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

Очередной Update. Теперь сворачиваются все eval, хотя if при этом местами получаются слишком длинными и необходима ручная правка, также if + goto превратились в while, плюс довольно много правок по мелочам, но главная убер фича - это вывод "чистого" кода, который включается флагом "-сс". В результате получается вот такое :)
Код: Выделить всё
auto func_033C(...)
{
    var1 = pressColorKey(arg1);
    if (var1)
    {
        playSoundEffect(104);
        while (isAnySoundPlaying())
        {
            update(1);
        }
        playSoundEffect(111);
        zanthiaChat("Here we go. There's probably a cover charge too.", 0);
        setGameFlag(180);
        playWanderScoreViaMap(14, 0);
        gVar20 = 0;
    }
    return;
}
Reflector
(2) Житель Милтонии
 
Сообщения: 162
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

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

Сообщение Малкольмович » 15 мар 2012, 22:29

классно! прямо хоть бери gcc и компиль)) только платформенный модуль нужен, который бы делал output в бинарник для платформы, допустим kyra =) И вперед, как-то так:
Код: Выделить всё
gcc -b kyra -mcpu=kyra_hof -o mystrm.emc mystrm.c


Только хотел предложить свертку такого
Код: Выделить всё
| 018A | eval (a == b)   | eval (gVar[4] == 51)
| 018C | pushVar 4       |
| 018E | push8 40        |
| 0190 | eval (a == b)   | eval (gVar[4] == 40)
| 0192 | eval (a || b)   | eval (a || b)
| 0194 | pushVar 4       |
| 0196 | push8 59        |
| 0198 | eval (a == b)   | eval (gVar[4] == 59)
| 019A | eval (a || b)   | eval (a || b)
| 019C | pushVar 4       |
| 019E | push8 73        |
| 01A0 | eval (a == b)   | eval (gVar[4] == 73)
| 01A2 | eval (a || b)   | eval (a || b)
| 01A4 | pushVar 4       |
| 01A6 | push8 74        |
| 01A8 | eval (a == b)   | eval (gVar[4] == 74)
| 01AA | eval (a || b)   | eval (a || b)
| 01AC | pushVar 4       |
| 01AE | push8 76        |
| 01B0 | eval (a == b)   | eval (gVar[4] == 76)
| 01B2 | eval (a || b)   |
| 01B4 | ifNotJmp 0x01C0 | if (a || b)
в нечто типа
Код: Выделить всё
if (  (gVar[4] == 51)
  || (gVar[4] == 40)
  || (gVar[4] == 59)
  || (gVar[4] == 73)
  || (gVar[4] == 74)
  || (gVar[4] == 76))
но как я чувствую, в этом билде оно уже есть)) сегодня вечером проверю)

или вот еще идея для свертки:
Код: Выделить всё
| 065E | eval (a == b)   |         eval (var[2] == 173)
| 0660 | push16 491      |         
| 0662 |                 |         
| 0664 | execOpcode 39   |         push queryGameFlag(491)
| 0666 | addSP 1         |         
| 0668 | pushRet         |         
| 066A | [SP] = ![SP]    |         
| 066C | eval (a && b)   |         
| 066E | ifNotJmp 0x068C |         if (a && !b)
в
Код: Выделить всё
if ((var[2] == 173) && !queryGameFlag(491))
такое тоже было бы круто) или оно уже есть?)

и еще немного маленьких пожеланий)
- backward-ссылки в виде комментариев, например:
Код: Выделить всё
| 01A4 | pushVar 4       |      // <---- 02A8, 02C8

- интересно, сколько в скриптах предусмотрено глобальных переменных (gVar)? надо будет попробовать посмотреть их назначение, но по крайней мере gVar[4] - это item, соответственно, где сравнение - там лучше писать не что-то типа "(gVar[4] == 1)", а "(gVar[4] == Items.Onion)";
- в строчках с вызовом функций было бы идеально писать в комменте прототип, типа такого:
Код: Выделить всё
push setInventorySlot(2, Items.BrokenFlask); // (slot_num, item_id): substitutes an item in specified inventory slot to specified and returns that item_id.

- и еще, в третьей кирандии все языкозависимые текстовые строки вынесены из EMC/FMC/GMC в соответствующий TRE/TRF/TRG-файл, а сам скрипт теперь только EMC. Я попробую разобраться, как реализовать вытяжку строк из него, тогда можно будет декомпиляцию делать, допустим, командой типа
Код: Выделить всё
kyrExtractor -k3 -cc -L bluff.tre bluff.emc
(-L можно считать опциональным, если указан язык, а имя TR?-файла совпадает с именем EMC-файла);
-ну и хотелось параметр -o, который позволял бы задать имя или расположение результирующего файла, например, так:
Код: Выделить всё
kyrExtractor -k2 -o ..\decompiled volc_a.emc
Аватара пользователя
Малкольмович
(4) помощник Мистика
 
Сообщения: 293
Зарегистрирован: 22 дек 2011, 22:09
Любимая часть Кирандии: Hand of Fate, а точнее, Darkmoor Swamp из неё =)
Любимые персонажи Кирандии: Занечка всех порулит =)
Почему Вы любите Легенду о Кирандии?: это мир, в котором можно жить, а не в который играть)

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

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

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

Такое уже есть, но в одну строку. Собственно я про это и писал когда говорил, что некоторые if-ы требуют ручной правки, т.е. для удобства чтения желательно разбивать их на несколько строк.

или вот еще идея для свертки:
такое тоже было бы круто) или оно уже есть?)

Есть, условие в if может быть хоть на весь экран :)

и еще немного маленьких пожеланий)
- backward-ссылки в виде комментариев

Смысла нет, ifNotJmp все превратились в if/while, из goto остались только "goto 0", те goto которые стали вызовами локальных функций я все отслеживаю и именно по адресам переходов происходит выделение этих функций, хотя не только, т.к. в скриптах есть и неиспользуемые функции. "auto func_033C(...)" из моего предыдущего поста одна из таких функций, если бы на какую-то команду внутри нее был переход, то где-то должна была бы быть "goto !0", а ее нет, или функцию бы разбило на две :)

- интересно, сколько в скриптах предусмотрено глобальных переменных (gVar)? надо будет попробовать посмотреть их назначение, но по крайней мере gVar[4] - это item, соответственно, где сравнение - там лучше писать не что-то типа "(gVar[4] == 1)", а "(gVar[4] == Items.Onion)";

Я видел gVar25 и пока знаю только что gVar1 и gVar2 - это координаты курсора в K1. Если будет известно какая переменная за что отвечает, то можно будет переименовать и параметры и их самих...

- в строчках с вызовом функций было бы идеально писать в комменте прототип, типа такого:
Код: Выделить всё
push setInventorySlot(2, Items.BrokenFlask); // (slot_num, item_id): substitutes an item in specified inventory slot to specified and returns that item_id.


Cначала сделаю чтоб можно было подхватывать внешние файлы с описаниями, вместо тех которые встроены как ресурсы, а вообще без проблем...

- и еще, в третьей кирандии все языкозависимые текстовые строки вынесены из EMC/FMC/GMC в соответствующий TRE/TRF/TRG-файл, а сам скрипт теперь только EMC. Я попробую разобраться, как реализовать вытяжку строк из него, тогда можно будет декомпиляцию делать, допустим, командой типа
Код: Выделить всё
kyrExtractor -k3 -cc -L bluff.tre bluff.emc
(-L можно считать опциональным, если указан язык, а имя TR?-файла совпадает с именем EMC-файла);

Оно само подхватит tre если найдет с подходящим именем, формат у tre тоже вроде не сложный, нужны еще команды которые работают с индексами из этих файлов, потому что в скуме команды в которых встречались stackPosString() работают исключительно с текстом из emc, нужно глубже в исходниках копаться, а я это не очень люблю :) Из K3 еще и графика не вытягивается, там еще улучшать и улучшать, с другой стороны есть еще .tim из K2, а это еще один скриптовый движок на два десятка команд :)

-ну и хотелось параметр -o, который позволял бы задать имя или расположение результирующего файла, например, так:
Код: Выделить всё
kyrExtractor -k2 -o ..\decompiled volc_a.emc


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

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

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

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

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

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

Pre-S. (то есть тот же P.S., но сначала =) Мне кажется, что большую часть этой темы уже стоит отделить в тему "декомпилятор скриптов" =))

А теперь по существу) Я посмотрел предпоследнюю версию декомпилятора, а также немного порылся в скриптах, и вот что выяснил.

Насчет глобальных переменных, я поискал все их вхождения в исходниках скумма и увидел вот что:

Код: Выделить всё
kyra_lok.cpp(867):   _scriptClick.regs[0] = _currentCharacter->sceneId;
kyra_lok.cpp(928):   _npcScript.regs[0] = _currentCharacter->sceneId;
scene_lok.cpp(413):   _scriptClick.regs[0] = _currentCharacter->sceneId;
kyra_lok.cpp(726):   _scriptClick.regs[1] = xpos;
kyra_lok.cpp(868):   _scriptClick.regs[1] = mouse.x;
script_lok.cpp(1334):   script->regs[1] = _mouseX;
kyra_lok.cpp(727):   _scriptClick.regs[2] = ypos;
kyra_lok.cpp(869):   _scriptClick.regs[2] = mouse.y;
script_lok.cpp(1335):   script->regs[2] = _mouseY;
gui_lok.cpp(122):   _scriptClick.regs[3] = 0;
gui_lok.cpp(129):   if (_scriptClick.regs[3])
kyra_lok.cpp(728):   _scriptClick.regs[3] = 0;
kyra_lok.cpp(735):   return _scriptClick.regs[3];
kyra_lok.cpp(729):   _scriptClick.regs[4] = _itemInHand;
kyra_lok.cpp(870):   _scriptClick.regs[4] = _itemInHand;
kyra_lok.cpp(929):   _npcScript.regs[4] = _itemInHand;
scene_lok.cpp(581):   _scriptClick.regs[4] = _itemInHand;
kyra_lok.cpp(930):   _npcScript.regs[5] = func;
gui_lok.cpp(123):   _scriptClick.regs[6] = jewel;
scene_lok.cpp(414):   _scriptClick.regs[7] = brandonAlive;
scene_lok.cpp(582):   _scriptClick.regs[7] = brandonAlive;
scene_lok.cpp(809):   _scriptClick.regs[7] = brandonAlive;
Код: Выделить всё
scene_hof.cpp(447):   _sceneScriptState.regs[0] = sceneId;
scene_v2.cpp(71):   _sceneScriptState.regs[0] = _mainCharacter.sceneId;
script_hof.cpp(922):   tmpScript.regs[0] = _mainCharacter.sceneId;
kyra_hof.cpp(635):   _sceneScriptState.regs[1] = x;
scene_v2.cpp(72):   _sceneScriptState.regs[1] = _mouseX;
script_v2.cpp(166):   _sceneScriptState.regs[1] = _mouseX;
script_v2.cpp(175):   _sceneScriptState.regs[1] = _mouseX;
kyra_hof.cpp(636):   _sceneScriptState.regs[2] = y;
scene_v2.cpp(73):   _sceneScriptState.regs[2] = _mouseY;
script_v2.cpp(167):   _sceneScriptState.regs[2] = _mouseY;
script_v2.cpp(176):   _sceneScriptState.regs[2] = _mouseY;
kyra_hof.cpp(637):   _sceneScriptState.regs[3] = 0;
kyra_hof.cpp(652):   return _sceneScriptState.regs[3] != 0;
scene_hof.cpp(135):   _sceneScriptState.regs[3] = 1;
kyra_hof.cpp(638):   _sceneScriptState.regs[4] = _itemInHand;
scene_hof.cpp(472):   _sceneScriptState.regs[4] = _itemInHand;
scene_hof.cpp(480):   _sceneScriptState.regs[4] = _itemInHand;
scene_v2.cpp(74):   _sceneScriptState.regs[4] = _itemInHand;
script_hof.cpp(921):   tmpScript.regs[4] = _itemInHand;
scene_hof.cpp(448):   _sceneScriptState.regs[5] = unk1;
scene_hof.cpp(481):   _sceneScriptState.regs[5] = unk1;
scene_hof.cpp(678):   _sceneScriptState.regs[5] = unk1;
kyra_hof.cpp(1045):   scriptState.regs[6] = unk1;
Код: Выделить всё
scene_mr.cpp(415):   _sceneScriptState.regs[0] = _mainCharacter.sceneId;
scene_mr.cpp(707):   _sceneScriptState.regs[1] = x;
scene_mr.cpp(720):   _sceneScriptState.regs[1] = _mouseX;
timer_mr.cpp(50):   _sceneScriptState.regs[1] = _mouseX;
scene_mr.cpp(708):   _sceneScriptState.regs[2] = y;
scene_mr.cpp(721):   _sceneScriptState.regs[2] = _mouseY;
timer_mr.cpp(51):   _sceneScriptState.regs[2] = _mouseY;
scene_mr.cpp(141):   _sceneScriptState.regs[3] = 1;
scene_mr.cpp(709):   _sceneScriptState.regs[3] = 0;
scene_mr.cpp(722):   _sceneScriptState.regs[3] = 0;
scene_mr.cpp(735):   _sceneScriptState.regs[3] = 0;
scene_mr.cpp(742):   if (_sceneScriptState.regs[3])
timer_mr.cpp(52):   _sceneScriptState.regs[3] = 0;
scene_mr.cpp(710):   _sceneScriptState.regs[4] = _itemInHand;
scene_mr.cpp(723):   _sceneScriptState.regs[4] = _itemInHand;
scene_mr.cpp(733):   _sceneScriptState.regs[4] = _itemInHand;
timer_mr.cpp(53):   _sceneScriptState.regs[4] = _itemInHand;
scene_mr.cpp(416):   _sceneScriptState.regs[5] = unk1;
scene_mr.cpp(583):   _sceneScriptState.regs[5] = unk1;
scene_mr.cpp(734):   _sceneScriptState.regs[5] = unk1;
kyra_mr.cpp(688):   state.regs[6] = unk1;


Значит, gVar0 (sceneId) следует маппить к названию сцены, gVar1, gVar2 - как и в предыдущих кирандиях, будут mouseX и mouseY, gVar3 - неизвестно что, но похоже на возможность пользователя вмешаться в ход действий или показывание курсора мыши (очевидно, bool), надо копать дальше; gVar4 - очевидно, содержимое мышки, 5, 6 и 7 - неизвестно, надо парсить функции (в первой кирандии есть присваивания им неких func, jewel и brandonAlive).

Если есть инфа о том, в каких скриптах используются gVar больше 4, то можно попробовать вручную определить тип и смысл каждой из оставшихся переменных =)

Я попробую сегодня это поделать)

Насчет TR? (TRE, TRF, TRG). Формат там простой:

short NumItems;
short StringIds[NumItems];
short StringOffsets[NumItems];
stream asciiz Strings[NumItems];

Каждый TR? хранит таблицу из NumItems "ID-строка". ID содержится в StringIds, строки в формате ASCIIZ в потоке Strings (т.е. друг за другом без промежутков). StringOffsets[i] - это смещение i-й строки в данном файле.

"при сравнении с gVar4 теперь выводятся имена предметов" - а при присваивании? Если да, то это отлично)

"с другой стороны есть еще .tim из K2, а это еще один скриптовый движок на два десятка команд" - а разве там есть какие-то отличия в структуре, по сравнеию с emc? Вроде как не должно быть, просто набор сисколлов разный)

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

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

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

Малкольмович писал(а):Значит, gVar0 (sceneId) следует маппить к названию сцены, gVar1, gVar2 - как и в предыдущих кирандиях, будут mouseX и mouseY, gVar3 - неизвестно что, но похоже на возможность пользователя вмешаться в ход действий или показывание курсора мыши (очевидно, bool), надо копать дальше; gVar4 - очевидно, содержимое мышки, 5, 6 и 7 - неизвестно, надо парсить функции (в первой кирандии есть присваивания им неких func, jewel и brandonAlive).

Это я все уже понял, теперь вместо gVar выводятся gScene, gMouse.x, gMouse.y, и gMouse.item. Кроме того я прописал имена всех сцен, персонажей и некоторых флагов для K1, плюс в описаниях параметров теперь можно писать не только их тип... Например, раньше было
"CharacterSays isii", а стало "CharacterSays vrm S A chatDuration", где большие одиночные буквы - это старые типы, а остальной текст выводится напрямую:
Код: Выделить всё
SetCharacterFacing(Char.Brandon, facing: 3, newAnimFrame: -1);
if (!QueryGameFlag(Flag.AltarFixed))
{
    CharacterSays(vrm: 6, "Is it missing a piece?", Char.Brandon, chatDuration: -2);
}

Но это все тоже большей частью для K1 прописано пока...

Если есть инфа о том, в каких скриптах используются gVar больше 4, то можно попробовать вручную определить тип и смысл каждой из оставшихся переменных =)

Я попробую сегодня это поделать)

Дерзай :)

Насчет TR? (TRE, TRF, TRG). Формат там простой:

Для tre, trf и trg, а также dle, dlg и dlf из K2, работает распаковка, в скрипты пока текст не подставляется. Можешь и тут поразбираться, я только знаю, что в тунстраке, где те же emc и tre, функции вывода текста берут его просто по ключу из tre, а если он больше 1000, то она отнимается и берется текст из глобального файла с текстом.

"при сравнении с gVar4 теперь выводятся имена предметов" - а при присваивании? Если да, то это отлично)

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

"с другой стороны есть еще .tim из K2, а это еще один скриптовый движок на два десятка команд" - а разве там есть какие-то отличия в структуре, по сравнеию с emc? Вроде как не должно быть, просто набор сисколлов разный)

Похоже там все другое. Другие команды, иначе закодированы...

кстати, что значит ключ -fc ? И да, ключ -ru по смыслу все же -en =) особенно для третьей кирандии, где русификация сделана вместо немецкого текста, а не английского)

-fc - это то же что и -сс, но наоборот :) Используется когда я компилю с по умолчанию включенным выводом "чистого кода". А ключ -ru задает кодовую страницу или таблицу перекодировки, с -en его связывает только то, что 1251 включается в себя английские буквы, но ibm850(теперь по умолчанию) работает с английским, немецким и французским, так что английский текст нормально распакуется с любым ключом.

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

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

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

Это я все уже понял, теперь вместо gVar выводятся gScene, gMouse.x, gMouse.y, и gMouse.item. Кроме того я прописал имена всех сцен, персонажей и некоторых флагов для K1, плюс в описаниях параметров теперь можно писать не только их тип... Например, раньше было
"CharacterSays isii", а стало "CharacterSays vrm S A chatDuration", где большие одиночные буквы - это старые типы, а остальной текст выводится напрямую
о, это все чудесно =)

Вроде нигде нет присваивания, есть сравнение и передача в функции
а, видимо там не присваивание делается, а setHandItem =)

Похоже там все другое. Другие команды, иначе закодированы...
странно... посмотрю сегодня тоже, пожалуй)

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

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

Сообщение Reflector » 01 апр 2012, 14:53

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

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

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

эхх, у меня тут загруз небольшой, но я-таки нашел время покопаться немного с декомпилером =)

кстати, на К3 он работает не очень стабильно:
- не распаковывает TLK (что объяснимо - у них теперь другой формат, не PAK - без имен файлов внутри)
- при попытке распаковать fmc/gmc: говорит о Exception RestoreAllObjectBackgrounds(System.Collections.Generic.List`1[System.String]) != 5 args
- почему-то остаются push-и в скриптах MR (например, в darms_emc.c):
Код: Выделить всё
    push 198
    setGameFlag();
    push 199
    resetGameFlag();
    push 200
    resetGameFlag();
    push 201
    resetGameFlag();


А из пожеланий - было бы круто, если бы было автоопределение типов параметров авто-функций. Например, в таком участке кода
Код: Выделить всё
auto func_033C(...)
{
    if ((((CountItemInInventory(unk: 0, item: arg1) || CheckForItem(Scene.Bridge, item: arg1)) || CheckForItem(Scene.Tree, item: arg1)) || CheckForItem(Scene.Foot, item: arg1)) || CheckForItem(Scene.Tram, item: arg1))
    {
        return 1;
    }
    return 0;
}

auto func_0388(...)
{
    if (!gVar5)
    {
        if (!func_033C(168) && !QueryGameFlag(Flag.477))
        {
            DefineItem(Item.Pinecone, x: 173, y: 55, Scene.Tree);
        }
    }
    return;
}
можно, проанализировав аргументы каждой функции, посмотреть, какой тип имеет этот аргумент при обращении к системному вызову: в func_033C видно, что есть один аргумент, причем в сисколлы он передается на месте параметра "item", имеющий, очевидно, тип Item. Так что прототип func_033C() можно зарегистрировать как func_033C(item), а не func_033C(short), и тогда при декомпилинге func_0388() вызов func_033С(168) в if-е можно будет упростить, подставив туда что-то из набора Items.

А, вот еще)) сравнения типа GetZanthiaScene() == 8 можно маппить к названиям сцен =)

Теперь о том, что я планировал сделать и что сделал)
до tim-скриптов я пока не добрался, зато проглядел все глобальные переменные и места, где они встречаются.
Вот какие переменные есть в скриптах (кроме gScene и подобных):
K1: 3, 6, 7, 8, 15-19
K2: 3, 5, 6, 15-20, 27, 28
K3: 3, 5, 6, 15-25
gVar3 - это очень часто используемый bool. Вероятно, он как-то связан с диалогами или видео, например, блокирует действия пользователя во время диалога или что-то подобное;
gVar5 в К2 - bool, похоже, это shareware-режим, но не факт;
gVar5 в К3 - bool, проверяется только в одном месте - в тюрьме, где зачем-то перекладываются ножницы в их исходное место;
gVar6 в К1 - это нажатый камень на амулете, имеет 4 значения: Heal, Invis, Will-o-Wisp, Dispell;
gVar6 в К2 - bool, если при старте игры не 0, то блуберрей в доме и вне дома не будет. Зачем это нужно, я не знаю));
gVar6 в К3 - bool, в зависимости от него, если он 0, то в начале игры генерятся ножницы, резак в тюрьмах, флакончик где-то и мачете в форте; при load game делается 1, во всех остальных случаях - 0;
gVar7 в K1 - bool? Никогда ничего не присваивается в emc; всегда ноль, но в scumme упоминается как некое brandonAlive, меняется в enterNewScene;
gVar15 и более - это, например счетчики, чтобы персонаж говорил разные слова при кликании на один предмет, или вот например gVar18 в alley.emc (но не в других файлах - там он reused) запоминает, что было положено осьминогу в ракушку. gVar27 определяет реакцию Занции на ножницы, а gVar28 - объект, соответствующий одному из Фаунов в доме Занции (их там 4, но одновременно есть только один). В K3 gVar21-25 используются только на пиратском корабле, 17-20 редко, особо широко юзаются 15 и 16.
gVar8 в K1 - это тоже счетчик, используется при смерти в пещерах.

Насчет TRE/TRF/TRG: формат я описывал выше (там short кол-во элементов, затем таблицы ID, смещений и собственно asciiz-строк), и в следующих функциях (это выдержка из моего kyra_funcs.txt):
Код: Выделить всё
o3_showSceneFileMessage i ; (string_id) may be mapped to _scenesFile[id]
o3_objectChat i ; (string_id) may be mapped to _actorFile[id] (only for _ACTOR.EMC) or _sceneStrings[id] (any other script)
o3_npcChatSequence ii ; (seq_id?, string_id) - last may be mapped to _sceneStrings[id]
o3_badConscienceChat i ;  (string_id) can be mapped to a string in some buffer
o3_updateScore rii ; (score_id, score_string_id) last parameter could be mapped to strings in SCORE.TRE(TRF,TRD); returns 1 if score is o3_showSceneStringsMessage i ; (string_id) can be mapped to _sceneStrings[id]
o3_goodConscienceChat i ; (string_id)  may be mapped to _actorFile[id] (only for _ACTOR.EMC) or _sceneStrings[id] (any other script)
o3_customChat ii ; (string_id, object) - first may be mapped to _sceneStrings[id]
строки подставляются по ID в соответствующих параметрах.

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

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

Сообщение Reflector » 18 апр 2012, 14:09

Малкольмович писал(а):- не распаковывает TLK (что объяснимо - у них теперь другой формат, не PAK - без имен файлов внутри)

Для K3 я специально добавлял только поддержку скриптов, а в tlk не просто заголовок другой, там сами звуки иначе закодированы...

- при попытке распаковать fmc/gmc: говорит о Exception RestoreAllObjectBackgrounds(System.Collections.Generic.List`1[System.String]) != 5 args

Все работает, просто для K2 нужно принудительно указать версию, там файлы в списки автоопределения не добавлены.

- почему-то остаются push-и в скриптах MR

Исправил.

А из пожеланий - было бы круто, если бы было автоопределение типов параметров авто-функций.

Такого точно не будет, но я экспериментировал с вручную составленными списками, тогда можно и имена функций подменять. Доработаю и добавлю чуть позже...

А, вот еще)) сравнения типа GetZanthiaScene() == 8 можно маппить к названиям сцен =)

Сделал.

gVar6 в К1 - это нажатый камень на амулете, имеет 4 значения: Heal, Invis, Will-o-Wisp, Dispell;

Переименовал в gAmuleteState, с остальными нужно разбираться более основательно...

Насчет tre: теперь из них подставляется текст в objectChat, badConscienceChat, goodConscienceChat и customChat(для objectChat есть 5 исключений, когда индексы ни на что не указывают). В updateScore всегда подставляет одна и та же строка "Score", так что я ничего не менял, а npcChatSequence и showSceneFileMessage видимо имеют дело с другими таблицами... Tre/trg/trf можно передавать в качестве параметра, как палитру, но по умолчанию ищется *.tre с именем как у скрипта.
Reflector
(2) Житель Милтонии
 
Сообщения: 162
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

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

Сообщение Reflector » 20 апр 2012, 19:01

Переименовал остальные глобальные функции для K1, теперь помимо OnMouseClick есть еще OnSceneStart, OnInitSceneScreen, OnInitSceneData, OnAmuleteClick(в который и передается gAmuleteState), OnEnterNewScene и ничем принципиально не отличающийся OnMouseClick2.
Также добавились списки переопределения локальных функций. В K1 он совсем мелкий, в K2 я добавил только часть... Выглядит это так:
Код: Выделить всё
0278 A func_0278 x y w h
043A +incave func_043A E x y flag shape shape
04B4 +incave func_04B4 S vocLow
033C +inhome func_033C S I vocLow
...
Reflector
(2) Житель Милтонии
 
Сообщения: 162
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

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

Сообщение Reflector » 24 апр 2012, 21:45

Update! Добавил поддержку .dat из K1. Кроме всякой мелочи там оказались описания объектов которые выводятся по индексу посредством DrawSceneAnimShape и анимация задаваемая тремя десятками команд:
Код: Выделить всё
SetDefaultXCoordinateOfSprite(99)
SetDefaultYCoordinateOfSprite(22)
Begin_For_Loop(iteration: 11)
SetSpriteImageUsingDefaultXandY(index: 3)
SetTimeToWait(ticks: 3)
WaitUntilTimeHasElapsed()
IncreaseDefaultYCoordinate(inc: 8)
End_For_Loop()
PlayRandomSoundAtCertainPercentageOfTime(snd: 57, percent: 20)
Reflector
(2) Житель Милтонии
 
Сообщения: 162
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

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

Сообщение Reflector » 13 июл 2012, 01:00

Мда, несмотря на 20+ скумовских команд для *.tim, реально в K2 используются парочка для стандартной инициализации и одна для задания номера фрейма, индекса анимации и задежки, т.е. фактически все выглядит как простой список:
Код: Выделить всё
0x0119: 1, frame: 21, id: 1, 6, delay: 9
0x0119: 1, frame: 22, id: 1, 5, delay: 0
0x0119: 3, frame: 61, 6, delay: 9
0x0119: 1, frame: 23, id: 1, 6, delay: 9
0x0119: 1, frame: 24, id: 1, 6, delay: 9
Reflector
(2) Житель Милтонии
 
Сообщения: 162
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

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

Сообщение Малкольмович » 13 июл 2012, 23:48

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

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

Сообщение Reflector » 14 июл 2012, 00:02

Поддержку dat я добавил еще в конце апреля :)

ps. Пришлось до комплекта добавить и поддержку Chx.eng, C_code.eng и Options.eng, для 4-х языков. Там были названия локаций, предметов, пунктов меню и т.п.... Эх, если бы это все кто-то сделал лет 10 назад, когда еще попадались энтузиасты в гораздо больших количествах :)
Reflector
(2) Житель Милтонии
 
Сообщения: 162
Зарегистрирован: 11 сен 2010, 16:44
Любимая часть Кирандии: 2
Любимые персонажи Кирандии: Занция
Почему Вы любите Легенду о Кирандии?: Ностальгия...

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

Сообщение Малкольмович » 15 июл 2012, 18:55

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

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

Сообщение Reflector » 15 июл 2012, 20:40

Малкольмович писал(а):а что там, в dat-ах?)

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

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

Сообщение Малкольмович » 17 июл 2012, 21:39

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

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

Сообщение Reflector » 29 сен 2012, 16:50

Опять тишина, позанудствовать что ли :) Значит в последнем билде экстрактора поменялась распаковка файлов диалогов для K2, теперь они выглядят так:
Код: Выделить всё
6:
0016  [ZANT] Прошу прощения...
0017  [ZANT] Эта лодка - случайно не новый паром?
0018  [FSH1] Тс-с! У меня клюёт!
7:
0019  [FSH2] Тс-с! Поклёвка!
8:
0020  [FSH1] Тс-с! Наверно, уже на крючке.

0016 и т.д. - это то, что в скриптах именуется как vocLow, если умножить это число на 10 и скомбинировать с vocHigh, который для каждого игрового экрана свой, то получится 0910160.voc, т.е. имя файла с речью из Ch1voc.tlk. С *.voc все просто, с мидишками посложнее, т.к. функции PlaySoundEffect и PlayWanderScoreViaMap имеют дело с таблицами и раньше из скриптов невозможно было понять какой звук соответствует определенному индексу. Сейчас берется аргумент PlaySoundEffect, по нему получается другой индекс в таблице и в зависимости от результата подставляется или имя файла из voc.pak, например, PlaySoundEffect("crunch1.voc"), или пару индексов(от 0) для K2sfx.с55 и K2sfx.xmi: PlaySoundEffect(gm: 30 = mt32: 48). GeneralMidi - это *.с55, MT32 - *.xmi, открыть их можно в Awave Studio. Для PlayWanderScoreViaMap в таблицах лежит пара индексов, второй для определения файла. Например, строка PlayWanderScoreViaMap([7:3], restart: 0) говорит о том, что 7 указывает на один из файлов K2test1..15.c55, в данном случае на K2test8.c55, а 3 - это уже индекс самого звука в нем. Кстати, если взять отюда утилитку smf2wav и добавить туда MT32 ромы, то можно конвертить mid из xmi в wav...

ps. Это уже совсем не по теме, но на днях доработал утилитку для текстурных атласов, теперь на автомате можно взять анимацию и она найдет отличия между кадрами, удалит лишнее и сгруппирует на текстуре. 185 кадров(320*128) интро из K1 после обработки выглядят вот так. Размер png в 2 раза меньше оригинального wsa, площадь текстуры в 14 раз меньше, если сравнивать с необрезанными фреймами.

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

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

Сообщение Малкольмович » 02 окт 2012, 23:10

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

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

Пред.След.

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

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

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

cron