Автор Тема: Вызов скриптовых функций  (Прочитано 5883 раз)

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 102
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Вызов скриптовых функций
« : Март 19, 2015, 08:30:48 pm »
Давно мучает вопрос, как вызывать скриптовые функции, пользуясь опкодом 05F5? Если кто пользовался - разберите по пунктам, что и зачем нужно :)
« Последнее редактирование: Март 19, 2015, 08:37:29 pm от Prographer »

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: Вызов скриптовых функций
« Ответ #1 : Март 19, 2015, 10:46:28 pm »
FIXED!(спс mfisto)

Это своеобразный аналог gosub - return

05F5: call_scm_func @QSILVER_GRAVITY_01 params_count 2 7@ 8@ 9@ 10@ 11@где
@QSILVER_GRAVITY_01 - метка потока scm функции
2 - количество передаваемых/принимаемых переменных
7@ и 8@ - передаваемые переменные
далее идут сразу
9@, 10@ и 11@ - возвращаемые переменные.

В новом потоке(функции) передаваемые переменные запишутся в 0@ и 1@ соответственно.

Далее после окончания работы потока QSILVER_GRAVITY_01 в конце пишется
05F6: ret 3 12@ 13@ 14@где
3 - количество возвращаемых переменных
12@, 13@ и 14@ - возвращаемые переменные, которые запишутся в 9@, 10@ и 11@ из предыдущего пункта


Т.е. по сути этот тот же gosub, только с возможностью передавать в потоки-функции различные переменные.

Можно вызывать scm-функцию без передаваемых/получаемых параметров:
05F5: call_scm_func @QSILVER_GRAVITY_01 params_count 0и возвращать также без переменных
05F6: ret 0
Также можно вызывать функцию с передачей в неё переменных, а возвращать пустой 05F6: ret 0
Можно возвращать не переменные, а конкретное числа:
05F6: ret 3 25 42 12- возвратились 3 числа: 25, 42 и 12.

Главное - помнить правило: число возвращаемых параметров должно быть равно их числу в опкоде 05F5, либо нулю.

В чем же отличие от gosub при вызове функции БЕЗ передачи/возвращения переменных?
Дело в том, что scm-функция ведет себя как самостоятельный поток, а это значит, что локальные переменные в ней отсчитываются заного.
Т.е. если в основном коде у тебя занята переменная 4@ - в scm-функции ты сможешь спокойно использовать переменную 4@, т.к. она будет уникальной для неё.
Это позволяет не хило сэкономить на переменных в CLEO-скриптах(т.к. в скриптах под вайс доступно всего 16 локальных переменных), разделив работу отдельного скрипта на мини-функции, затратные по части переменных.

P.S. Когда я разобрался с этим опкодом, я смог оптимизировать несколько своих больших наработок, и объединить свои задумки вроде quicksilver(с очень громоздким кодом) в единые скрипты, так что знать принцип работы этой вещицы нужно обязательно, если хочешь облегчить работу с большими задумками.
« Последнее редактирование: Март 20, 2015, 09:05:56 am от Shaggy »

Оффлайн mfisto

  • Скриптер
  • Главный Модератор
  • Новичок
  • *****
  • Сообщений: 176
  • Репутация: +19/-0
  • Не пью, не курю, за компьютером сижу...
    • mfistof
    • Просмотр профиля
    • Empire of CJ
Re: Вызов скриптовых функций
« Ответ #2 : Март 20, 2015, 08:35:16 am »
Ты немного некорректно объяснил товарищу, либо сам до конца не понял, в данной функции должно быть вот так по твоему примеру

05F5: call_scm_func @QSILVER_GRAVITY_01 params_count 2 7@ 8@ 7@ 8@
Здесь 2 передаваемых параметра и 2 возвращаемых, фишка в том что в твоем примере компилятор ищет на возврате две возвращаемые переменные и находит те же что и возвращаемые и ему по барабану, что они те же. Но так не верно, должно быть отдельно! Таким образом можно передавать одно а получать совершенно другое.
I know everything and nothing...

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: Вызов скриптовых функций
« Ответ #3 : Март 20, 2015, 08:59:13 am »
Да, спс, протупил  ;D - я просто самой опцией возврата переменных не пользовался(не было необходимости, поэтому всегда ret 0 ставил), и недопонял это. В остальном же вроде правильно всё расписал(по крайней мере у меня всё ок работает)

ПРОФИКСИЛ
« Последнее редактирование: Март 20, 2015, 09:06:52 am от Shaggy »

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 102
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Re: Вызов скриптовых функций
« Ответ #4 : Март 20, 2015, 10:28:27 am »
Да, спс, протупил  ;D - я просто самой опцией возврата переменных не пользовался(не было необходимости, поэтому всегда ret 0 ставил), и недопонял это. В остальном же вроде правильно всё расписал(по крайней мере у меня всё ок работает)

ПРОФИКСИЛ
С функциями я знаком уже относительно давно, с тех пор, когда начала изучать C++ и JavaScript, но в Cleo меня смущает, наверно, непонятный синтаксис. Можно продемонстрировать работу функции в каком-нибудь простом скрипте? :)

P.S. Вопрос, собственно, поднят потому, мой скрипт на замену надписей радиостанций на изображения является говнокодом из "else if"ов
https://yadi.sk/d/mxiqGuRXfNw9f

Оффлайн mfisto

  • Скриптер
  • Главный Модератор
  • Новичок
  • *****
  • Сообщений: 176
  • Репутация: +19/-0
  • Не пью, не курю, за компьютером сижу...
    • mfistof
    • Просмотр профиля
    • Empire of CJ
Re: Вызов скриптовых функций
« Ответ #5 : Март 20, 2015, 01:42:11 pm »
В этом скрипте не хватает только вырубание функции показа радиостанции, а как написано не имеет значения, главное результат. Способ написания важен только для самого программиста, чтоб ему было понятно и просто все. Ну и может для тех еще, кто будет читать данный скрипт.
I know everything and nothing...

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 102
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Re: Вызов скриптовых функций
« Ответ #6 : Март 20, 2015, 03:24:20 pm »
В этом скрипте не хватает только вырубание функции показа радиостанции, а как написано не имеет значения, главное результат. Способ написания важен только для самого программиста, чтоб ему было понятно и просто все. Ну и может для тех еще, кто будет читать данный скрипт.
Ну нет, чувак, тут ты не прав. Написание хорошего кода - это уже дело принципа. К тому же, хороший код выполняется быстрее и не заставляет процессор особо напрягаться.
Кстати, раз уж на то пошло, было бы неплохо узнать как выйти из цикла рисовании текстуры. Честно говоря, уже не знаю как исхитриться так, чтобы рисовать текстуру какое-то определённое количество времени. Была идея создать параллельный цикл с счётчиком N. Как только счётчик доходит до определённого значения, цикл будет завершаться, но как правильно записать это никак не получается.

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: Вызов скриптовых функций
« Ответ #7 : Март 20, 2015, 04:39:01 pm »
Хз, скрипты жрут предельно мало ресурсов, так что если немножко не оптимизированно - не страшно. Это во-первых.
Во-вторых, конечно, громоздкие конструкции и неоптимизированный по размеру код нагружает лишь оперативку, а это - пару килобайт в итоге в самых тяжелых случаях и +10-20 ms к задержке загрузки в наитяжелейших случаях(утверждаю, основываясь на многочисленных тестах).
Конечно, я могу не корректно изъясняться, но я сейчас веду речь именно про само устройство кода скрипта, а не оптимизацию переменных и т.д.
В-третьих, исходя из предыдущих пунктов, писать "высокоуровневым способом" имеет смысл лишь если это тебе в кайф(думай в первую очередь о себе), но если ты ратуешь за оптимизацию, то декомпилируй свой скрипт и ужаснись количеством бессмысленных jump-ов, а особенно - замечательной концовкой:
:SOME_1051
jump @SOME_87
jump @SOME_87
end_thread
Я сейчас ни в коем случае не наезжаю(что-что, а я наезжать со своей криворукостью просто не имею права), и может даже где-то ошибаюсь, но просто даю дельный совет для упрощения жизни тебе в первую очередь(для меня поэтому скриптинг - сплошное удовольствие, включая даже поиск багов), а именно:
В-четвертых - низкоуровневый скриптинг позволяет за пару мгновений проследить логику скрипта(чужого или своего, если подзабыл) - конечно, если скрипт был написан низкоуровневым способом. Также в этом случае не возникает путаниц с else-ами, jump-ами, gosub-ами и прочим.

Это всё, конечно, при условии, если пишешь большие скрипты и влом выискивать баги. В низкоуровневом коде легко отключать нужные секции, ставить wait-ы там где надо, чтобы выловить ошибку и т.д.
А еще в этом случае будет удобно не делать параллельный поток, а сделать продолжение потока, в котором будет запускаться автоматический таймер 16@ = 0, создаваться другой цикл с проверкой значения таймера.
А так в угоду красивому исходнику и созданию единого цикла с одним wait-ом прибавляется куча гемора. - это я не конкретно про твой скрипт, а вообще про типичные высокоуровневые исходники, что я видел.

Повторюсь, это конечно на любителя, но ты должен понимать, что высокоуровневый код добавляет мусора в скрипт(если ты ратуешь за производительность).
По факту конечно, опять же - повторюсь: все эти "замедления работы" столь не значительны, что можно наплевать на это(реальный "бич" производительности - лишние wait-ы).

Ну и в-пятых, в справке SB есть подробное описание вызова scm-функции с примерами в описании аналогичного опкода в SA: 0AB1.
« Последнее редактирование: Март 20, 2015, 04:51:22 pm от Shaggy »

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 102
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Re: Вызов скриптовых функций
« Ответ #8 : Март 21, 2015, 01:19:20 pm »
Ну и в-пятых, в справке SB есть подробное описание вызова scm-функции с примерами в описании аналогичного опкода в SA: 0AB1.
Я прочитал, но всё равно не до конца понял принцип. Можно прямо по полочкам разложить, что и зачем необходимо? Я знаю строку, использующуюся в одном скрипте, и она совершенно не похожа на тот пример, который написан в справке
05F5: call_scm_func @headlight_right_pos params_count 1 car_handle 0@ store position to 10@ 11@ 12@Я не понимаю, какую роль играют слова "car_handle" и "store position to"

Оффлайн Sektor

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 521
  • Репутация: +34/-0
    • Просмотр профиля
Re: Вызов скриптовых функций
« Ответ #9 : Март 21, 2015, 01:22:38 pm »
Так называемый SCM интерпретатор, довольно шустрый по своим параметрам. Для тех годов, когда железки были простенькие, он себя хорошо показал, в том числе еще портировался на PS. А писать как уже раньше обсуждалось, лучше все по мере надобности, не чего лишнего.


Prographer
store position to 10@ 11@ 12@, ну в эти 3 переменные, мы сохраняем значения координат от автомобиля, если я не ошибаюсь. А хендл авто, это понятное дело, созданный автомобиль ранее, типа указателя на нее, но хендл это уже не что другое. Создали к примеру авто, в переменную записался хендл, дальше можем обращаться к нему разными опкодами, например установить здоровье авто и.т.п...
« Последнее редактирование: Март 21, 2015, 01:27:23 pm от Sektor »

Оффлайн mfisto

  • Скриптер
  • Главный Модератор
  • Новичок
  • *****
  • Сообщений: 176
  • Репутация: +19/-0
  • Не пью, не курю, за компьютером сижу...
    • mfistof
    • Просмотр профиля
    • Empire of CJ
Re: Вызов скриптовых функций
« Ответ #10 : Март 21, 2015, 03:17:48 pm »
Я не понимаю, какую роль играют слова "car_handle" и "store position to"

Дело в том что это всего лишь слова, они никакой роли не играют, так как компилятор их все равно не использует, ему важны только параметры и опкод. Ты можешь написать там все что хочешь для удобства. Внимание следует уделять оригиналу опкода, а именно
05F5: где первый параметр это офсет метки, второй кол-во передаваемых параметров, остальные парметры не фиксированы их может быть сколько угодно, они зависят от 2 -го параметра (кол-во передаваемых параметров) и также от концовки scm функции (ret 2 1@ 2)
где, в концовке содержится в первом параметре кол-во отдающих параметров и сами параметры. в результате получаешь следующее-> например
05f5: @label 3 2@ 34.0 347 3@ 5@ 7@ 11@

...

:label

...

05f6: ret 4 57.0 3@ 6@ 127

Как видишь параметров в 05f5 получилось 9, где первый - метка, второй - кол-во передаваемых параметров, с третьего по 5 уже сами передаваемые параметры, а остальные параметры в том же кол-ве что и в ret будут возвращены.
I know everything and nothing...

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 102
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Re: Вызов скриптовых функций
« Ответ #11 : Март 21, 2015, 03:59:07 pm »
Спасибо, mfisto. Теперь, вроде бы, стало более понятно. Отпишусь как только всё получится или возникнут другие вопросы :)