KSP все о нем

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

Поднакопилось вопросов. Вопросов не_много, но они есть.

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

Возникла вот такая каверзная ситуация и в связи с ней вопрос.

Оригинальный файл бэкграунда:
16I2FFhv6s.png


То, что выдаёт Контакт в результате изменения структуры папки Resources:
cnO76O4Lq4.jpg


Почему кнопки стали отображаться так? Стали серыми, будто из внутреннего контактовского редактора.)

И (возможно) вытекающий из предыдущего вопроса вопрос:
Где указывается путь к файлам Resources? В самом инструменте можно выбрать только Instrument Wallpaper, но это, как я понимаю, не единственное место указания пути к ресурсам. Ещё в инструменте можно выбрать некий контейнер ресурсов (к которому неизвестно, как подступиться). И если, допустим, невозможно "распотрошить" уже созданную библиотеку, то где указать путь к файлам Resources в созданной собственной библиотеке?
 
@PianoIst, в том-то и дело, что ресурс-койнтейнер указан, но вот структуру папок, на которые ссылается данный инструмент, я изменил. Вопрос в том, где (в контейнере или, возможно, в скрипте самого инструмента) указывается ссылка на папку с картинками / сами картинки. :)

Скрипт данного инструмента таков (см. вложение).

Единственное возникшее предположение заключалось в том, что
set_control_par_str($INST_ICON_ID,$CONTROL_PAR_PICTURE,"icon")
отвечает за этот путь, но оно (вроде бы) оказалось неверно.
 

Вложения

Последнее редактирование:
@arkaine, когда жмете кнопку create nkr, он сам создает правильную структуру папок, можно этим воспользоваться. Вообще про nkr есть пара страничек в мануале по KSP
Если структуру папок меняли непосредственно в nkr, бросьте это занятие, просто создаете папку Resources со вложенными
2017-09-15_12-01-20.png

и пихаете в нее нововведения. В финальной упаковке контакт вложенные папки не понимает и не пакует (вложенные в те, что на картинке)
 
  • Like
Реакции: arkaine
просто создаете папку Resources со вложенными
Именно с целью унификации библиотек и удобства при дальнейшей работе с ними (напр., Batch Resave или перемещение библиотеки с последующим указанием файлов к инструментам в ней) я и попытался воссоздать такую (стандартную) структуру папок, ибо изначально в некоторых (слишком во многих) других библиотеках структура отличная от неё.

В данной библиотеке разработчик, кажется (уже забыл, каковой была структура), умудрился засунуть картинки в папку Pictures, которую он "заботливо" в папке Data. :)

Спасибо за развёрнутый ответ, попробую пересоздать контейнер ресурсов, а также поперемещаю картинки, глядишь и удастся восстановить полноценную загрузку скина данного инструмента.
 
Последнее редактирование:
@arkaine, Пересобирание библиотек, особенно защищенных - гиблое дело.
Даже у нас в незащищенной библе в данный момент используются дополнительное дерево каталогов для дополнительных ресурсов. Защищенные же библиотеки с файлами обращаются совсем иначе, и это зашито внутрь инструментов, помимо самого скрипта. Теоретически, можно прошерстить скрипт и переписать пути, но, кмк, лишняя трата ресурсов.
Лучше собирать мульти, на мульти-скриптах.
Можно немного почитать про скриптовый роутинг миди здесь
 
  • Like
Реакции: arkaine
Приветствую, программисты!
Подскажите, пжст, где можно подробно почитать про операторы KSP?
Я прочитал что было на http://nilsliberg.se/ksp/(тут все понятно), есть так же reference manual, но там как то не хватает информации для понимания. Есть какие то еще материалы? Хочется что то типа словаря.
 
@Bborisss, Если еще вдруг не читали - KSPReference, лежит в папке с мануалами контакта на диске C:/Program Files.
Вообще, честно говоря, не знаю, чего можно писать про операторы, т.к. все они помещаются на строчку:
:=(присваивание), =(сравнение), + - / * >= <= mod cell floor and or
вроде все. Может еще что-то забыл
 
@Bborisss,
Вообще, честно говоря, не знаю, чего можно писать про операторы, т.к. все они помещаются на строчку:
:=(присваивание), =(сравнение), + - / * >= <= mod cell floor and or
вроде все. Может еще что-то забыл

@PianoIst , не операторы, а скорее встроенные переменные и функции и правила их применеия. Например вот самое первое из ref manual NI_CALLBACK_TYPE, что это, мне не понятно. Я правда не програмист, а просто представление имею, но как правило с примерами и объяснениями все бывает понятно.
[DOUBLEPOST=1509785601][/DOUBLEPOST]Я немного на javascript програмировл, а KSP, я так понимаю, на основе php сделано?
 
@Bborisss, тоже все очень хорошо в мануале описано. Прочитайте его, он не длинный)
конкретно NI_CALLBACK_TYPE выдает тип каллбека, они тоже запакованы во вшитые переменные, типа NI_CALLBACK_TYPE_INIT и т.д.
есть еще CALLBACK_ID, это порядковый номер исполнения каллбека, условно говоря. То есть дважды раз исполненный один и тот же один каллбек будет иметь разные ID
 
@PianoIst это он? У меня просто в этой папке нет ничего... отдельно скачивал
 

Вложения

  • IMG_1293.PNG
    IMG_1293.PNG
    156,5 KB · Просмотры: 167
@PianoIst, поможете разобраться с stop_wait?

Не пойму как он действует.

on init
message(" ")
end on

on note
if ($EVENT_NOTE = 55)
message ("hey")
wait(3000000)
message("hey again")
end if

if ($EVENT_NOTE = 60)
stop_wait($NI_CALLBACK_ID, 0)
end if

end on

/Жму ($EVENT_NOTE = 55) потом ($EVENT_NOTE = 60)/

По моему представлению здесь либо после ($EVENT_NOTE = 60) зразу должно написаться ("hey again"), либо ничего не написаться. А получается что ($EVENT_NOTE = 60) никак не влияет на выполнение предыдущего Call_backэ'а.

А вообще, как можно остановить выполнение определенных предыдущих выполняющихся Call_back'ов при определенных условиях?
 
@Bborisss, На эти грабли легко наступить :)
То есть дважды раз исполненный один и тот же один каллбек будет иметь разные ID
соответственно, надо сделать что-то вроде:

Код:
on init
message(" ")
declare $new_callback
declare $prev_callback
end on

on note
$prev_callback := $new_callback
$new_callback := $NI_CALLBACK_ID
if ($EVENT_NOTE = 55)
message ("hey")
wait(3000000)
message("hey again")
end if

if ($EVENT_NOTE = 60)
stop_wait($prev_callback, 0)
end if

end on

Но вообще это пока сферический код в вакууме. Каллбек on note обычно перегружен событиями. поэтому для сообщения между разными on init лучше выбирать не ID каллбека, а что-нибудь попроще и понадежнее. Как правило, массивы в 128 ячеек для хранения параметров для каждой ноты (в смысле питча)
[DOUBLEPOST=1510074086][/DOUBLEPOST]
А вообще, как можно остановить выполнение определенных предыдущих выполняющихся Call_back'ов при определенных условиях?
да как угодно, ессчестно.
допустим (псевдокод):
Код:
on note
  $stop := 0
  ignore_event ($EVENT_ID)
  $new_id := play_note ($EVENT_NOTE, $EVENT_VELOCITY,0,0)
  $i := 0
  while ($stop # 1)
    inc($i)
    wait (100)
    if ($i = 100000)
      exit
    end if
  end while
  note_off ($new_id)
end on

on release
  $stop := 1
end on

совершенно бесполезный код, который по идее должен провоцировать залипание ноты, если мы ее слишком долго держим (ок секунды, если не просчитался).
Естессно, работает на одной ноте за раз)
 
@PianoIst Спасибо, к массивам потихонечку прихожу. Щас буду разбираться в ваших кодах, это для меня пока не быстро)
Тут еще одна странность возникла.

Задача что бы нажатие педали сустейна сняло ноту, а снимает почему то отпускание (т.е. нажал и отпустил). При чем попробовал сыграть ноту от нажатия, тут все ок.

Код:
on init
declare %new_id[10]
message("")
declare $i := 0
declare %sustain_notes[10]
end on

on note
if (%CC[64] = 127)
ignore_event($EVENT_ID)
%sustain_notes[$i] := $EVENT_NOTE
%new_id[$i] := play_note(%sustain_notes[$i],30,0,0)
$i := $i + 1
end if
end on

on controller
    if (%CC[64] = 127)
    $i := 0
end if
    while ($i < 10)
     note_off(%new_id[$i])
     $i := $i + 1
    message("muting note")
end while
$i := 0
   
end on

Вообще тут идея такая что при нажатии педали сустейна он их запоминает и они звучат даже после того как педаль отпущена, а потом когда педаль повторно нажимается ноты звучать прекращают. И все в целом работает кроме того, что заглушаются они при отпускании, а не при нажатии.
 
@Bborisss, вообще в коде много логических ошибок.
Я нарисую пример, но завтра, сейчас работы много...
Пока советую проверить настройки иснтрумента. в данном случае режим cc64 должен стоять controller only
 
@Bborisss, вообще в коде много логических ошибок.
Интересно...
Спасибо, что помогаете.
[DOUBLEPOST=1510080048][/DOUBLEPOST]
@Bborisss,
Пока советую проверить настройки иснтрумента. в данном случае режим cc64 должен стоять controller only

Все заработало!
 
  • Like
Реакции: PianoIst
@PianoIst , не могу пнять одну вещь...
На входе нота. Первым делом ее игнорируем и делаем своютакую же. Играем так несколько нот и все их пока держим и все они звучат. Потом одну отпускаем. Вопрос: как на on release получить параметр какую именно мы отпустили, что б ее заглушть?
 
@Bborisss, как правило, мы не отпускаем дважды одну и ту же ноту, предварительно ее не взяв.
По этому в релизе спокойно используем переменную EVENT_NOTE.
!НО!
Релиз иногда вызывается по десять раз на дню, допустим: при игре легато с сэмплами транзиций мы проигрываем сэмпл транзиций в on note, потом проигрываем сэмпл сустейна (а часто и во время звучания сэмпла транзиции). И вот тут начинают вылезать косяки как раз по причине того, что одна и та же нота была взята дважды, без единого эвента note_off. Поэтому надо либо фильтровать по EVENT_ID (проверять на соответсвие new_id и иже с ними), или еще как-то по ситуации.
А когда делается какой-то арпеджиатор вообще катавасия начинается с контролем вызова каллбеков.
Я люблю отключать релиз способом типа:
Код:
on note
release_off := 1
<кой-какой код со снятием нот>
release_off := 0
end on

on release
  if (release_off = 1)
    exit
  end if
end on
Еще можно проверять какие клавиши нажаты, но надо учитывать, что если мы игнорим эвент снятия ноты в принципе (в смысле, покидаем каллбек через exit в самом начале) ноты могут "залипать".
 
  • Like
Реакции: Bborisss
@Bborisss, как правило, мы не отпускаем дважды одну и ту же ноту, предварительно ее не взяв.
По этому в релизе спокойно используем переменную EVENT_NOTE.

А как ее использовать? Ведь в note_off параметр не EVENT_NOTE, а EVENT_ID?
[DOUBLEPOST=1510299174][/DOUBLEPOST]Можно, конечно, связать EVENT_NOTE и EVENT_ID, а потом на релизе релизе опрашивать какой EVENT_ID соответствует конкретноой отпущеной EVENT_NOTE... Но как то это усложненно мне кажется.
 
Последнее редактирование:
@Bborisss, ну дsr это... про то, что note_off принимает event_note я и не говорил :) Эта функция выключает ноту по ID, а не номеру.
Но вообще в релизе использовать event_note можно.
тут так должно быть
Код:
on note
  if (EVENT_NOTE = (60))
    new_id := play_note бла бла
  end if
end on

on release
   if (EVENT_NOTE = 60)
    note_off (new_id)
  end if
end on
 
  • Like
Реакции: Bborisss
@PianoIst , а вы пробовали использовать "заскриптованный" Контакт как источник миди сигнала для других инструментов?
 
@PianoIst, у меня вопрос, не касающийся напрямую KSP.
В общем, суть такова - давно хочу сделать конструктор интерфейсов, естественно, только для основных элементов.
То есть - кнобы, слайдеры, чекбоксы, поля для текста и прочее.
Насколько удобнее задавать параметры по отдельности - либо проще кучку аргументов прописать?
Это вопрос к Вам, как к человеку в курсе и KSP, и JS, потому что, я один раз глянул всего KSP.
 
@EUGEN27771, честно говоря, мне кажется, тут все от языка зависит.
Я по лету пытался написать библиотеку адаптивного дизайна для контакта. На тот момент наилучшей архитектурой показалось - изначально интерфейс строить на функциях (или методах, хз) комбайнах, в которых определяешь все параметры сразу. Но чтобы потом адекватно работала привязка к контейнерам и была возможность делать "доводку" позиций в стиле Button.x += value, пришлось городить огород из дополнительной здоровой функции. (Она еще попутно решала вопрос слишком большого кода).
Но библиотека не взлетела в итоге (использовалл в двух проектах, и понял, что надо переписывать кардинально, на питоне :) ), потому что я гнался за тем, чтобы была и автоматизация, и псевдо-ООП, и простота написания кода в процедурном стиле. Все это привело к жуткому раздуванию кода при компиляции.
Вообще много вещей получились хорошо, если интересно, могу архитерктуру нарисовать вечером. Но все-таки я не конструктор делал, а приблуду, вроде библиотеки Lokasenna_GUI
 
  • Like
Реакции: EUGEN27771 и Bborisss
@PianoIst У меня как то не корректно работает. Вот например в данном коде другой инструмент не получает cообщене note_off.
Код:
on init
  declare $new_id
end on

on note
  ignore_event($EVENT_ID)
  if ($EVENT_NOTE = $EVENT_NOTE)
    $new_id := play_note($EVENT_NOTE, 100, 0, 0)
  end if
end on

on release
   if ($EVENT_NOTE = $EVENT_NOTE)
    note_off ($new_id)
  end if
end on

@Bborisss, в принципе, работает. Но это как кувалдой гвозди забивать

А где это лучше делать? Т.е. если нужно что бы видоизмененный скриптами миди сигнал попадал на другие инструменты?
Например, знаю, в лоджике X есть Skriptor, но не пробовал.
И не уверен что сигнал можно направить на другие каналы...
 
Последнее редактирование:

Сейчас просматривают