#1 07-06-2010 18:16

Alien
Registered: 12-10-2008
Posts: 564

[CLEO4]0AA5-0AA8. Передача scm-строк и указателей на scm-переменные.

[large]Часть 1.[/large]
[Все, что написано ниже, актуально для версии игры US 1.0, CLEO 4.1.1.20 или выше.]   
Недавно в CLEO 4 появилась одна малоосвещенная, но полезная возможность. Со времен CLEO 3 остались опкоды 0AA5-0AA8, которые используются для вызова x86 native функций напрямую из скрипта. В CLEO 4 они приобрели возможность передавать в качестве параметра scm-строки как обыкновенные C-строки!
Приведем пример:

0AA5: call 0x588BE0 num_params 4 pop 4 0 permanent_flag 1 0 "permanent text box"

Он выводит на экран перманентный текст-бокс с произвольной строкой. Раньше такого эффекта приходилось добиваться грязными способами, действуя через память напрямую таким образом:

0AC7: 0@ = var 1@v offset
1@v = "permanent text box"
0AA5: call 0x588BE0 num_params 4 pop 4 0 permanent_flag 1 0 0@

или таким:

0AC6: 0@ = label @damn_text_there offset
0AA5: call 0x588BE0 num_params 4 pop 4 0 permanent_flag 1 0 0@
...
:damn_text_there
hex
"permanent" 20 "text" 20 "box" 00
end

Думаю, это нововведение многие найдут полезным...
[large]Часть 2.[/large]
[Все, что написано ниже, актуально для версии игры US 1.0, CLEO 4.1.1.22 или выше.]
Переходим к следующему пункту. Согласно стандарту языка C++ (на котором написана игра), при передаче в функцию массивов (в частности массивов символов, т.е. строк), передается не весь массив, а лишь указатель на него. В приведенном ниже коде передается указатель на локальную строковую переменную 0@v потока.

0@v = "permanent text box"
0AA5: call 0x588BE0 num_params 4 pop 4 0 permanent_flag 1 0 0@v

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

{$CLEO}
wait 0
while true
    wait 0
    if 
        player.Defined(0)
    then
        0AA5: call 0x56E010 num_params 2 pop 2 -1 0@v
        0AD0: show_formatted_text_lowpriority "player pos: (%g, %g, %g)" time 2000 0@ 1@ 2@
    
    end
end

Функция 0x56E010 получает координаты игрока, записывая их в буфер, переданный по указателю. Если передать указатель на переменную 0@, координаты запишутся в переменные 0@, 1@, 2@.

Offline

#2 07-06-2010 19:10

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [CLEO4]0AA5-0AA8. Передача scm-строк и указателей на scm-переменные.

Вау, класс!

Offline

#3 26-09-2014 07:34

kenking
From: Казахстан
Registered: 28-06-2010
Posts: 253

Re: [CLEO4]0AA5-0AA8. Передача scm-строк и указателей на scm-переменные.

А в VC можно как-то вывести текст из хекс буфера?

Offline

#4 26-09-2014 08:45

mfisto
From: Russia Perm
Registered: 01-02-2008
Posts: 558
Website

Re: [CLEO4]0AA5-0AA8. Передача scm-строк и указателей на scm-переменные.

Такой возможности в VC нет. В клео для III DK разрабатывает такую возможность.


I know everything and nothing...

Offline

Board footer

Powered by FluxBB