*/}}

la_input_mapping.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. #include "../la_5.h"
  2. extern LA MAIN;
  3. extern struct _tnsMain *T;
  4. laBaseNodeType LA_IDN_KEYBOARD;
  5. laBaseNodeType LA_IDN_MOUSE;
  6. laBaseNodeType LA_IDN_CONTROLLER;
  7. laBaseNodeType LA_IDN_VISUALIZER;
  8. laBaseNodeType LA_IDN_SPLIT;
  9. laBaseNodeType LA_IDN_SWITCH;
  10. laPropContainer* LA_PC_IDN_GENERIC;
  11. laPropContainer* LA_PC_IDN_KEYBOARD;
  12. laPropContainer* LA_PC_IDN_MOUSE;
  13. laPropContainer* LA_PC_IDN_CONTROLLER;
  14. laPropContainer* LA_PC_IDN_VISUALIZER;
  15. laPropContainer* LA_PC_IDN_SPLIT;
  16. laPropContainer* LA_PC_IDN_SWITCH;
  17. #define LA_IDN_CONTROLLER_RESET_SOCKET(ns)\
  18. {ns->IntVal[0]=0; ns->Out->DataType=LA_PROP_INT; ns->Offset=0; ns->Out->Data=&ns->IntVal;}
  19. void IDN_ControllerInit(laInputControllerNode* n){
  20. for(int i=0;i<8;i++){ n->Sockets[i].Out=laCreateOutSocket(n, "out", 0); n->Sockets[i].Parent=n; }
  21. strSafeSet(&n->Base.Name,"Controller Output");
  22. }
  23. void IDN_ControllerDestroy(laInputControllerNode* n){
  24. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Sockets[i].Out); }
  25. strSafeDestroy(&n->Base.Name);
  26. }
  27. int IDN_ControllerVisit(laInputControllerNode* n, laListHandle* l){
  28. laController* c=la_FindControllerWithID(n->UserID);
  29. if(!c){ for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i]; LA_IDN_CONTROLLER_RESET_SOCKET(ns); } return LA_DAG_FLAG_PERM; }
  30. else{
  31. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i];
  32. if(!ns->Which || !ns->Which->Ptr){ LA_IDN_CONTROLLER_RESET_SOCKET(ns); continue; }
  33. laPropContainer*pc=la_EnsureSubTarget(LA_PROP_CONTROLLER, c);
  34. laProp* p=la_PropLookup(&pc->Props, n->Sockets[i].Which->Ptr);
  35. if((!p)||(!p->Offset)||
  36. ((p->PropertyType!=LA_PROP_INT)&&(p->PropertyType!=LA_PROP_ENUM)&&
  37. (p->PropertyType!=(LA_PROP_INT|LA_PROP_ARRAY))&&(p->PropertyType!=(LA_PROP_ENUM|LA_PROP_ARRAY)))){ LA_IDN_CONTROLLER_RESET_SOCKET(ns); continue; }
  38. if(p->PropertyType==LA_PROP_INT){ ns->Out->DataType=LA_PROP_FLOAT; ns->Out->Data=&ns->RealVal; ns->Out->ArrLen=1; }
  39. elif(p->PropertyType==(LA_PROP_INT|LA_PROP_ARRAY)){ ns->Out->DataType=(LA_PROP_FLOAT|LA_PROP_ARRAY); ns->Out->Data=&ns->RealVal; ns->Out->ArrLen=p->Len; }
  40. elif(p->PropertyType==LA_PROP_ENUM){ ns->Out->DataType=LA_PROP_ENUM; ns->Out->Data=&ns->IntVal; ns->Out->ArrLen=1; }
  41. elif(p->PropertyType==(LA_PROP_ENUM|LA_PROP_ARRAY)){ ns->Out->DataType=(LA_PROP_ENUM|LA_PROP_ARRAY); ns->Out->Data=&ns->IntVal; ns->Out->ArrLen=p->Len; }
  42. ns->Offset=p->Offset;
  43. }
  44. }
  45. n->Base.Eval=LA_DAG_FLAG_PERM;
  46. lstAppendPointer(l, n);
  47. return LA_DAG_FLAG_PERM;
  48. }
  49. int IDN_ControllerEval(laInputControllerNode* n){
  50. laNotifyInstanceUsers(n);
  51. laController* c=la_FindControllerWithID(n->UserID); if(!c){
  52. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i]; LA_IDN_CONTROLLER_RESET_SOCKET(ns); } return 1;
  53. }
  54. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i];
  55. int *addr=((char*)c)+ns->Offset; char* addc=addr;
  56. if(ns->Out->DataType==LA_PROP_FLOAT){ ns->RealVal[0]=(real)(*addr)/32767.0; }
  57. if(ns->Out->DataType==(LA_PROP_FLOAT|LA_PROP_ARRAY)){ for(int a=0;a<ns->Out->ArrLen;a++) ns->RealVal[a]=((real)addr[a])/32767.0; }
  58. elif(ns->Out->DataType==LA_PROP_ENUM){ ns->IntVal[0]=(*addc); }
  59. elif(ns->Out->DataType==(LA_PROP_ENUM|LA_PROP_ARRAY)){ for(int a=0;a<ns->Out->ArrLen;a++) ns->IntVal[a]=addc[a]; }
  60. }
  61. return 1;
  62. }
  63. void laui_ControllerNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  64. laColumn* c=laFirstColumn(uil); laInputControllerNode*n=This->EndInstance;
  65. laColumn* cl,*cr; laSplitColumn(uil,c,0.3); cl=laLeftColumn(c,0); cr=laRightColumn(c,0);
  66. laUiItem* b=laBeginRow(uil,c,0,0);
  67. laShowHeightAdjuster(uil,c,This,"base.__gap",0);
  68. laShowItem(uil,c,This,"base.name")->Expand=1;
  69. laShowItem(uil,c,This,"user_id");
  70. laEndRow(uil,b);
  71. char* buf[128],buf2[128];
  72. for(int i=0;i<8;i++){
  73. sprintf(buf,"out%d.which",i); laShowItem(uil,cl,This,buf);
  74. laUiItem* b=laBeginRow(uil,cr,0,0);
  75. sprintf(buf2,"out%d.out.data_type",i);
  76. laUiItem* b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,buf2),laIntExpression(LA_PROP_FLOAT)));{
  77. sprintf(buf,"out%d.axis",i); laShowItem(uil,cr,This,buf)->Expand=1;
  78. }laElse(uil,b2);{
  79. laUiItem* b3=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,buf2),laIntExpression(LA_PROP_FLOAT|LA_PROP_ARRAY)));{
  80. sprintf(buf,"out%d.axis2d",i); laUiItem* aui=laShowItem(uil,cr,This,buf);aui->Expand=1;aui->Flags|=LA_UI_FLAGS_TRANSPOSE;aui->Extra->HeightCoeff=1;
  81. }laElse(uil,b3);{
  82. sprintf(buf,"out%d.switch",i); laUiItem* sui=laShowItem(uil,cr,This,buf);sui->Expand=1;sui->Flags|=LA_UI_FLAGS_TRANSPOSE;
  83. }laEndCondition(uil,b3);
  84. }laEndCondition(uil,b2);
  85. sprintf(buf,"out%d.out",i); laShowNodeSocket(uil,cr,This,buf,0);
  86. laEndRow(uil,b);
  87. }
  88. }
  89. void IDN_InputVisualizeInit(laInputVisualizerNode* n){
  90. n->In=laCreateInSocket("in", 0);
  91. strSafeSet(&n->Base.Name,"Input Visualizer");
  92. }
  93. void IDN_InputVisualizeDestroy(laInputVisualizerNode* n){
  94. laDestroyInSocket(n->In);
  95. strSafeDestroy(&n->Base.Name);
  96. }
  97. int IDN_InputVisualizeVisit(laInputVisualizerNode* n, laListHandle* l){
  98. n->Base.Eval=LA_DAG_FLAG_TEMP;
  99. if(n->In->Source){ int result;
  100. laBaseNode* sn=n->In->Source->Parent; result=sn->Type->Visit(sn,l); if(result==LA_DAG_FLAG_TEMP) return LA_DAG_FLAG_ERR;
  101. }
  102. n->Base.Eval=LA_DAG_FLAG_PERM;
  103. lstAppendPointer(l, n);
  104. return LA_DAG_FLAG_PERM;
  105. }
  106. int IDN_InputVisualizerEval(laInputVisualizerNode* n){
  107. if(!n->In->Source) return 0;
  108. laNodeOutSocket* os=n->In->Source; int arrlen=1;
  109. switch(os->DataType){
  110. case LA_PROP_FLOAT|LA_PROP_ARRAY:
  111. case LA_PROP_FLOAT: if(os->ArrLen)arrlen=os->ArrLen; memcpy(n->RealVal,os->Data,sizeof(real)*arrlen); n->In->ArrLen=arrlen; break;
  112. case LA_PROP_ENUM|LA_PROP_ARRAY:
  113. case LA_PROP_ENUM: if(os->ArrLen)arrlen=os->ArrLen; memcpy(n->IntVal,os->Data,sizeof(int)*arrlen); n->In->ArrLen=arrlen; break;
  114. default: n->IntVal[0]=0; n->In->ArrLen=1; break;
  115. }
  116. n->In->DataType=os->DataType;
  117. laNotifyInstanceUsers(n);
  118. return 1;
  119. }
  120. void laui_InputVisualizeNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  121. laColumn* c=laFirstColumn(uil); laInputVisualizerNode*n=This->EndInstance;
  122. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  123. laUiItem* b=laBeginRow(uil,c,0,0);
  124. laShowHeightAdjuster(uil,c,This,"base.__gap",0);
  125. laShowItem(uil,c,This,"base.name");
  126. laEndRow(uil,b);
  127. laShowNodeSocket(uil,cl,This,"in",0);
  128. laUiItem* b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,"in.data_type"),laIntExpression(LA_PROP_FLOAT)));{
  129. laShowItem(uil,cr,This,"axis");
  130. }laElse(uil,b2);{
  131. laUiItem* b3=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,"in.data_type"),laIntExpression(LA_PROP_FLOAT|LA_PROP_ARRAY)));{
  132. laUiItem* aui=laShowItem(uil,cr,This,"axis2d");
  133. }laElse(uil,b3);{
  134. laUiItem* sui=laShowItem(uil,cr,This,"switch");
  135. }laEndCondition(uil,b3);
  136. }laEndCondition(uil,b2);
  137. }
  138. void IDN_InputSplitInit(laInputSplitNode* n){
  139. n->In=laCreateInSocket("in", 0); strSafeSet(&n->Base.Name,"Split");
  140. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->Out[i].Out=laCreateOutSocket(n,str,0); }
  141. }
  142. void IDN_InputSplitDestroy(laInputSplitNode* n){
  143. laDestroyInSocket(n->In); strSafeDestroy(&n->Base.Name);
  144. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
  145. }
  146. int IDN_InputSplitVisit(laInputSplitNode* n, laListHandle* l){
  147. if(n->Base.Eval==LA_DAG_FLAG_TEMP||n->Base.Eval==LA_DAG_FLAG_PERM) return LA_DAG_FLAG_ERR;
  148. n->Base.Eval=LA_DAG_FLAG_TEMP;
  149. if(n->In->Source){ int result;
  150. laBaseNode* sn=n->In->Source->Parent; result=sn->Type->Visit(sn,l); if(result==LA_DAG_FLAG_TEMP) return LA_DAG_FLAG_ERR;
  151. }
  152. n->Base.Eval=LA_DAG_FLAG_PERM;
  153. lstAppendPointer(l, n);
  154. return LA_DAG_FLAG_PERM;
  155. }
  156. int IDN_InputSplitEval(laInputSplitNode* n){
  157. if(!n->In->Source) return 0;
  158. laNodeOutSocket* os=n->In->Source; int arrlen=1;
  159. switch(os->DataType){
  160. case LA_PROP_FLOAT|LA_PROP_ARRAY:
  161. case LA_PROP_FLOAT: if(os->ArrLen) n->ArrLen=os->ArrLen;
  162. for(int i=0;i<TNS_MIN2(n->ArrLen,8);i++){ n->Out[i].Out->DataType=LA_PROP_FLOAT; n->Out[i].Out->Data=&n->RealVal[i]; }
  163. memcpy(n->RealVal,os->Data,sizeof(real)*n->ArrLen); n->In->ArrLen=arrlen; break;
  164. case LA_PROP_ENUM|LA_PROP_ARRAY:
  165. case LA_PROP_ENUM: if(os->ArrLen) n->ArrLen=os->ArrLen;
  166. for(int i=0;i<TNS_MIN2(n->ArrLen,8);i++){ n->Out[i].Out->DataType=LA_PROP_ENUM; n->Out[i].Out->Data=&n->IntVal[i]; }
  167. memcpy(n->IntVal,os->Data,sizeof(int)*n->ArrLen); n->In->ArrLen=arrlen; break;
  168. default:
  169. for(int i=0;i<TNS_MIN2(n->ArrLen,8);i++){ n->Out[i].Out->DataType=LA_PROP_ENUM; n->Out[i].Out->Data=&n->IntVal[i]; }
  170. n->IntVal[0]=0; n->In->ArrLen=1; break;
  171. }
  172. n->In->DataType=os->DataType;
  173. return 1;
  174. }
  175. void laui_InputSplitNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  176. laColumn* c=laFirstColumn(uil); laInputSplitNode*n=This->EndInstance;
  177. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  178. laUiItem* b=laBeginRow(uil,c,0,0);
  179. laShowHeightAdjuster(uil,c,This,"base.__gap",0);
  180. laShowItem(uil,c,This,"base.name");
  181. laEndRow(uil,b);
  182. b=laBeginRow(uil,c,0,0);
  183. laShowNodeSocket(uil,c,This,"in",0);laShowSeparator(uil,c)->Expand=1;
  184. laShowItemFull(uil,c,This,"array_length",LA_WIDGET_INT_PLAIN,0,0,0);
  185. for(int i=0;i<8;i++){
  186. char* buf[128]; sprintf(buf,"out%d.out",i); laShowNodeSocket(uil,cr,This,buf,0);
  187. }
  188. laEndRow(uil,b);
  189. }
  190. void IDN_InputSwitchInit(laInputSwitchNode* n){
  191. n->SwitchIn=laCreateInSocket("sw in",0); n->Out=laCreateOutSocket(n,"out",0); strSafeSet(&n->Base.Name,"Switch");
  192. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->In[i].In=laCreateInSocket(n,str); }
  193. }
  194. void IDN_InputSwitchDestroy(laInputSwitchNode* n){
  195. laDestroyInSocket(n->SwitchIn); laDestroyOutSocket(n->Out); strSafeDestroy(&n->Base.Name);
  196. for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
  197. }
  198. int IDN_InputSwitchVisit(laInputSwitchNode* n, laListHandle* l){
  199. if(n->Base.Eval==LA_DAG_FLAG_TEMP||n->Base.Eval==LA_DAG_FLAG_PERM) return LA_DAG_FLAG_ERR;
  200. n->Base.Eval=LA_DAG_FLAG_TEMP;
  201. for(int i=0;i<8;i++){
  202. if(n->In[i].In->Source){ int result;
  203. laBaseNode* sn=n->In[i].In->Source->Parent; result=sn->Type->Visit(sn,l); if(result==LA_DAG_FLAG_TEMP) return LA_DAG_FLAG_ERR;
  204. }
  205. }
  206. laBaseNode* sw=n->SwitchIn->Source?n->SwitchIn->Source->Parent:0; if(sw){
  207. int result=sw->Type->Visit(sw,l); if(result==LA_DAG_FLAG_TEMP) return LA_DAG_FLAG_ERR;
  208. }
  209. n->Base.Eval=LA_DAG_FLAG_PERM;
  210. lstAppendPointer(l, n);
  211. return LA_DAG_FLAG_PERM;
  212. }
  213. int IDN_InputSwitchEval(laInputSwitchNode* n){
  214. int sw=n->Switch;
  215. if(n->SwitchIn->Source){ laNodeOutSocket* os=n->SwitchIn->Source; int* id; real* fd;
  216. switch(os->DataType){
  217. case LA_PROP_ARRAY|LA_PROP_ENUM:
  218. id=os->Data; for(int i=0;i<os->ArrLen;i++){ if(id[i]){sw=i; break;} } break;
  219. case LA_PROP_ENUM: case LA_PROP_INT: case LA_PROP_INT|LA_PROP_ARRAY:
  220. id=os->Data; sw=*id; break;
  221. case LA_PROP_FLOAT: case LA_PROP_FLOAT|LA_PROP_ARRAY:
  222. fd=os->Data; sw=(int)(*fd); break;
  223. default: sw=0; break;
  224. }
  225. }
  226. TNS_CLAMP(sw,0,7);
  227. laInputSwitchNodeInSocket *is=&n->In[sw];
  228. if(is->In->Source){ n->Out->Data=is->In->Source->Data; n->Out->DataType=is->In->Source->DataType; n->Out->ArrLen=is->In->Source->ArrLen; }
  229. else{ n->Out->Data=&n->TempVal; n->Out->DataType=LA_PROP_FLOAT; n->Out->ArrLen=1; }
  230. return 1;
  231. }
  232. void laui_InputSwitchNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  233. laColumn* c=laFirstColumn(uil); laInputSwitchNode*n=This->EndInstance;
  234. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  235. laUiItem* b=laBeginRow(uil,c,0,0);
  236. laShowHeightAdjuster(uil,c,This,"base.__gap",0);
  237. laShowItem(uil,c,This,"base.name");
  238. laEndRow(uil,b);
  239. b=laBeginRow(uil,c,0,0);
  240. for(int i=0;i<8;i++){
  241. char* buf[128]; sprintf(buf,"in%d.in",i); laShowNodeSocket(uil,cr,This,buf,0);
  242. } laShowSeparator(uil,c)->Expand=1;
  243. laEndRow(uil,b);
  244. b=laBeginRow(uil,c,0,0);
  245. laShowItem(uil,c,This,"switch_in");
  246. laUiItem* b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"switch_in.source")));{
  247. laShowItem(uil,c,This,"switch");
  248. };laEndCondition(uil,b2);
  249. laShowSeparator(uil,c)->Expand=1;
  250. laShowNodeSocket(uil,c,This,"out",0);
  251. laEndRow(uil,b);
  252. }
  253. int OPINV_AddInputMapperRack(laOperator* a, laEvent *e){
  254. laInputRack* pivot=a->This?a->This->EndInstance:0;
  255. laInputRack* ir=memAcquire(sizeof(laInputRack));
  256. if(strSame(strGetArgumentString(a->ExtraInstructionsP,"before"),"true")){
  257. if(pivot){ lstInsertItemBefore(&MAIN.InputMappingRacks,ir,pivot); }else{ lstPushItem(&MAIN.InputMappingRacks,ir); }
  258. }else { if(pivot){ lstInsertItemAfter(&MAIN.InputMappingRacks,ir,pivot); }else{ lstAppendItem(&MAIN.InputMappingRacks,ir); } }
  259. laNotifyUsers("la.input_racks");
  260. return LA_FINISHED;
  261. }
  262. laBaseNode* la_CreateInputMapperNode(laInputRack* ir, laBaseNodeType* NodeType){
  263. laBaseNode* bn=memAcquire(NodeType->NodeSize);
  264. bn->Type=NodeType; NodeType->Init(bn); lstAppendItem(&ir->Nodes, bn); bn->InRack=ir;
  265. laNotifyUsers("la.input_racks");
  266. return bn;
  267. }
  268. void la_DestroyInputMapperNode(laBaseNode* bn){
  269. lstRemoveItem(bn->InRack, bn); bn->Type->Destroy(bn);
  270. laNotifyUsers("la.input_racks");
  271. memFree(bn);
  272. }
  273. int OPINV_AddInputMapperNode(laOperator* a, laEvent *e){
  274. laInputRack* ir=a->This?a->This->EndInstance:0; if(!ir) return LA_CANCELED;
  275. char* type=strGetArgumentString(a->ExtraInstructionsP,"type");
  276. if(!type){ laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e); return LA_RUNNING; }
  277. elif(strSame(type, "KEYBOARD")){}
  278. elif(strSame(type, "MOUSE")){}
  279. elif(strSame(type, "CONTROLLER")){ la_CreateInputMapperNode(ir, &LA_IDN_CONTROLLER); }
  280. elif(strSame(type, "VISUALIZER")){ la_CreateInputMapperNode(ir, &LA_IDN_VISUALIZER); }
  281. elif(strSame(type, "SPLIT")){ la_CreateInputMapperNode(ir, &LA_IDN_SPLIT); }
  282. elif(strSame(type, "SWITCH")){ la_CreateInputMapperNode(ir, &LA_IDN_SWITCH); }
  283. return LA_FINISHED;
  284. }
  285. void laui_AddInputMapperNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  286. laColumn* c=laFirstColumn(uil);
  287. laShowItemFull(uil,c,This,"add_node",0,"type=KEYBOARD;text=Keyboard",0,0);
  288. laShowItemFull(uil,c,This,"add_node",0,"type=MOUSE;text=Mouse",0,0);
  289. laShowItemFull(uil,c,This,"add_node",0,"type=CONTROLLER;text=Controller",0,0);
  290. laShowSeparator(uil,c);
  291. laShowItemFull(uil,c,This,"add_node",0,"type=SPLIT;text=Split",0,0);
  292. laShowItemFull(uil,c,This,"add_node",0,"type=SWITCH;text=Switch",0,0);
  293. laShowItemFull(uil,c,This,"add_node",0,"type=VISUALIZER;text=Visualizer",0,0);
  294. }
  295. laPropContainer* laget_InputNodeType(laBaseNode* bn){
  296. if(bn->Type==&LA_IDN_CONTROLLER) return LA_PC_IDN_CONTROLLER;
  297. if(bn->Type==&LA_IDN_VISUALIZER) return LA_PC_IDN_VISUALIZER;
  298. if(bn->Type==&LA_IDN_SPLIT) return LA_PC_IDN_SPLIT;
  299. if(bn->Type==&LA_IDN_SWITCH) return LA_PC_IDN_SWITCH;
  300. return LA_PC_IDN_GENERIC;
  301. }
  302. int laget_InputNodeGap(laInputRack* rack_unused, laBaseNode* n){
  303. return n->Gap;
  304. }
  305. void laset_InputNodeGap(laBaseNode* n, int gap){
  306. if(gap<0){
  307. int done=0;
  308. laBaseNode* nn=n; while(nn){ if(nn->Gap>0){ nn->Gap--; done=1; break; } nn=nn->Item.pPrev; }
  309. if(done){ nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap++; break; } nn=nn->Item.pNext; } }
  310. }
  311. if(gap>0){
  312. n->Gap+=gap;
  313. laBaseNode* nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap--; break; } nn=nn->Item.pNext; }
  314. }
  315. }
  316. void laset_InputNodeUserID(laInputControllerNode* n, int i){
  317. laNotifyUsers("la.input_racks");
  318. }
  319. void laset_InputControllerNodeSocketWhich(laInputControllerNodeSocket* s, char* str){
  320. strSafeSet(&s->Which, str);
  321. laNotifyUsers("la.input_racks"); laMappingRequestRebuild();
  322. }
  323. int laget_SocketEnumArrayLength(laInputControllerNodeSocket* s){
  324. return s->Out->ArrLen?s->Out->ArrLen:1;
  325. }
  326. int laget_VisualizerArrayLength(laInputVisualizerNode* s){
  327. return s->In->ArrLen?s->In->ArrLen:1;
  328. }
  329. #define LA_IDN_REGISTER(a,init,destroy,visit,eval,type)\
  330. {a.Init = init; a.Destroy = destroy; a.Visit=visit; a.Eval=eval; a.NodeSize=sizeof(type);}
  331. void la_RegisterInputMapperOperators(){
  332. laPropContainer *pc; laProp *p;
  333. laOperatorType *at;
  334. laEnumProp *ep;
  335. LA_IDN_REGISTER(LA_IDN_CONTROLLER, IDN_ControllerInit, IDN_ControllerDestroy, IDN_ControllerVisit, IDN_ControllerEval, laInputControllerNode);
  336. LA_IDN_REGISTER(LA_IDN_VISUALIZER, IDN_InputVisualizeInit, IDN_InputVisualizeDestroy, IDN_InputVisualizeVisit, IDN_InputVisualizerEval, laInputVisualizerNode);
  337. LA_IDN_REGISTER(LA_IDN_SPLIT, IDN_InputSplitInit, IDN_InputSplitDestroy, IDN_InputSplitVisit, IDN_InputSplitEval, laInputSplitNode);
  338. LA_IDN_REGISTER(LA_IDN_SWITCH, IDN_InputSwitchInit, IDN_InputSwitchDestroy, IDN_InputSwitchVisit, IDN_InputSwitchEval, laInputSwitchNode);
  339. laCreateOperatorType("LA_add_input_mapper_rack", "Add Rack", "Add a rack for input mapper nodes", 0,0,0,OPINV_AddInputMapperRack,0,'+',0);
  340. at=laCreateOperatorType("LA_add_input_mapper_node", "Add Node", "Add a input mapper node",0,0,0,OPINV_AddInputMapperNode,OPMOD_FinishOnData,'+',0);
  341. at->UiDefine=laui_AddInputMapperNode;
  342. pc=laAddPropertyContainer("la_input_rack", "Input Rack", "Input rack for putting input mapping nodes",0,0,sizeof(laInputRack),0,0,1);
  343. laAddStringProperty(pc,"name","Name","Name of this rack",0,0,0,0,1,offsetof(laInputRack,Name),0,0,0,0,LA_AS_IDENTIFIER);
  344. p=laAddSubGroup(pc,"nodes","Nodes","Nodes under this rack","la_input_node",laget_InputNodeType,0,0,-1,0,0,0,0,0,0,offsetof(laInputRack,Nodes),0);
  345. laSubGroupExtraFunctions(p,0,0,laget_InputNodeGap);
  346. laAddOperatorProperty(pc,"add_node","Add Node","Add a node into this rack","LA_add_input_mapper_node",'+',0);
  347. pc=laAddPropertyContainer("la_input_node", "Input Node", "Input logic node",0,0,sizeof(laBaseNode),0,0,1);
  348. LA_PC_IDN_GENERIC=pc;
  349. laAddStringProperty(pc,"name","Name","Name of this input node",0,0,0,0,1,offsetof(laBaseNode,Name),0,0,0,0,LA_AS_IDENTIFIER);
  350. laAddIntProperty(pc,"__gap", "Gap", "Gap of the node", 0,0,0,0,0,0,0,0,offsetof(laBaseNode,Gap),0,laset_InputNodeGap,0,0,0,0,0,0,0,0,0);
  351. pc=laAddPropertyContainer("la_input_controller_node", "Controller output", "Output controller values",0,laui_ControllerNode,sizeof(laInputControllerNode),0,0,1);
  352. LA_PC_IDN_CONTROLLER=pc;
  353. laAddSubGroup(pc,"base","Base","Base node","la_input_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  354. laAddIntProperty(pc,"user_id", "User ID", "Which controller should the data come from", 0,0,0,0,0,0,0,0,offsetof(laInputControllerNode,UserID),0,0,0,0,0,0,0,0,0,0,0);
  355. laAddSubGroup(pc,"out0","Out 0","Output 0","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  356. laAddSubGroup(pc,"out1","Out 1","Output 1","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  357. laAddSubGroup(pc,"out2","Out 2","Output 2","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  358. laAddSubGroup(pc,"out3","Out 3","Output 3","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  359. laAddSubGroup(pc,"out4","Out 4","Output 4","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  360. laAddSubGroup(pc,"out5","Out 5","Output 5","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  361. laAddSubGroup(pc,"out6","Out 6","Output 6","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  362. laAddSubGroup(pc,"out7","Out 7","Output 7","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  363. pc=laAddPropertyContainer("la_input_controller_node_socket", "Controller Socket", "One value from a controller output",0,0,sizeof(laInputControllerNodeSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  364. laAddStringProperty(pc,"which","Which","Select which output from the controller",0,0,0,0,1,offsetof(laInputControllerNodeSocket,Which),0,0,laset_InputControllerNodeSocketWhich,0,LA_AS_IDENTIFIER);
  365. laAddFloatProperty(pc,"axis", "🡘", "Axis value", LA_WIDGET_VALUE_METER,0,0,1,-1,0,0,0,offsetof(laInputControllerNodeSocket,RealVal),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
  366. laAddFloatProperty(pc,"axis2d", "2D Axis", "2D Axis value", LA_WIDGET_VALUE_METER,0,0,1,-1,0,0,0,offsetof(laInputControllerNodeSocket,RealVal),0,0,2,0,0,0,0,0,0,0,LA_READ_ONLY);
  367. p=laAddEnumProperty(pc,"switch", "SW", "Switch value", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laInputControllerNodeSocket,IntVal),0,0,0,laget_SocketEnumArrayLength,0,0,0,0,0,LA_READ_ONLY);
  368. laAddEnumItemAs(p,"IDLE", "Idle", "Button is not pressed", 0, 0);
  369. laAddEnumItemAs(p,"ACTIVE", "Active", "Button is pressed", 1, 0);
  370. laAddSubGroup(pc, "out", "Out","Output value","la_out_socket",0,0,0,offsetof(laInputControllerNodeSocket,Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  371. pc=laAddPropertyContainer("la_input_visualizer_node", "Visualizer", "Visualizer node",0,laui_InputVisualizeNode,sizeof(laInputVisualizerNode),0,0,1);
  372. LA_PC_IDN_VISUALIZER=pc;
  373. laAddSubGroup(pc,"base","Base","Base node","la_input_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  374. laAddSubGroup(pc, "in", "In","Input value","la_in_socket",0,0,0,offsetof(laInputVisualizerNode,In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  375. laAddFloatProperty(pc,"axis", "🡘", "Axis value", LA_WIDGET_VALUE_METER,0,0,1,-1,0,0,0,offsetof(laInputVisualizerNode,RealVal),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
  376. laAddFloatProperty(pc,"axis2d", "2D Axis", "2D Axis value", LA_WIDGET_VALUE_METER_2D,0,0,1,-1,0,0,0,offsetof(laInputVisualizerNode,RealVal),0,0,2,0,0,0,0,0,0,0,LA_READ_ONLY);
  377. p=laAddEnumProperty(pc,"switch", "SW", "Switch value", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laInputVisualizerNode,IntVal),0,0,0,laget_VisualizerArrayLength,0,0,0,0,0,LA_READ_ONLY);
  378. laAddEnumItemAs(p,"IDLE", "Idle", "Button is not pressed", 0, 0);
  379. laAddEnumItemAs(p,"ACTIVE", "Active", "Button is pressed", 1, 0);
  380. pc=laAddPropertyContainer("la_input_split_node", "Split", "Split node",0,laui_InputSplitNode,sizeof(laInputSplitNode),0,0,1);
  381. LA_PC_IDN_SPLIT=pc;
  382. laAddSubGroup(pc,"base","Base","Base node","la_input_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  383. laAddSubGroup(pc,"in", "In","Input value","la_in_socket",0,0,0,offsetof(laInputSplitNode,In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  384. laAddSubGroup(pc,"out0","Out 0","Output 0","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  385. laAddSubGroup(pc,"out1","Out 1","Output 1","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  386. laAddSubGroup(pc,"out2","Out 2","Output 2","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  387. laAddSubGroup(pc,"out3","Out 3","Output 3","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  388. laAddSubGroup(pc,"out4","Out 4","Output 4","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  389. laAddSubGroup(pc,"out5","Out 5","Output 5","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  390. laAddSubGroup(pc,"out6","Out 6","Output 6","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  391. laAddSubGroup(pc,"out7","Out 7","Output 7","la_input_split_node_out_socket",0,0,0,offsetof(laInputSplitNode, Out[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  392. laAddIntProperty(pc, "array_length", "Array Length", "Array length of data", 0, 0, 0, 0, 0, 0, 0, 0, offsetof(laInputSplitNode, ArrLen), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);
  393. pc=laAddPropertyContainer("la_input_split_node_out_socket", "Split Out", "One value from an array input",0,0,sizeof(laInputSplitNodeOutSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  394. laAddSubGroup(pc, "out", "Out","Output value","la_out_socket",0,0,0,offsetof(laInputSplitNodeOutSocket,Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  395. pc=laAddPropertyContainer("la_input_switch_node", "Switch", "Switch node",0,laui_InputSwitchNode,sizeof(laInputSwitchNode),0,0,1);
  396. LA_PC_IDN_SWITCH=pc;
  397. laAddSubGroup(pc,"base","Base","Base node","la_input_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  398. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laInputSwitchNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  399. laAddSubGroup(pc,"in0","In 0","Input 0","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  400. laAddSubGroup(pc,"in1","In 1","Input 1","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  401. laAddSubGroup(pc,"in2","In 2","Input 2","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  402. laAddSubGroup(pc,"in3","In 3","Input 3","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  403. laAddSubGroup(pc,"in4","In 4","Input 4","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  404. laAddSubGroup(pc,"in5","In 5","Input 5","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  405. laAddSubGroup(pc,"in6","In 6","Input 6","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  406. laAddSubGroup(pc,"in7","In 7","Input 7","la_input_switch_node_in_socket",0,0,0,offsetof(laInputSwitchNode, In[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  407. laAddIntProperty(pc, "switch", "Switch", "Switch which input to use", 0, 0, 0, 0, 0, 0, 0, 0, offsetof(laInputSwitchNode, Switch), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  408. laAddSubGroup(pc,"switch_in", "Switch In","Switch control","la_in_socket",0,0,0,offsetof(laInputSwitchNode,SwitchIn),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  409. pc=laAddPropertyContainer("la_input_switch_node_in_socket", "Switch In", "Input of many values",0,0,sizeof(laInputSwitchNodeInSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  410. laAddSubGroup(pc, "in", "In","Input value","la_in_socket",0,0,0,offsetof(laInputSwitchNodeInSocket,In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  411. }
  412. void laMappingRequestRebuild(){ MAIN.MappingNeedRebuild=1; }
  413. void laMappingRequestEval(){ MAIN.MappingNeedEval=1; }
  414. int la_RunInputMapping(){
  415. MAIN.MappingNeedEval = 0;
  416. for(laListItemPointer*lip=MAIN.InputMappingEval.pFirst;lip;lip=lip->pNext){
  417. laBaseNode* n=lip->p; n->Type->Eval(n);
  418. }
  419. return 1;
  420. }
  421. int la_RebuildInputMapping(){
  422. MAIN.MappingNeedRebuild = 0;
  423. while(lstPopPointer(&MAIN.InputMappingEval));
  424. laListHandle pending={0};
  425. for(laInputRack* ir=MAIN.InputMappingRacks.pFirst;ir;ir=ir->Item.pNext){
  426. for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ lstAppendPointer(&pending,bn); bn->Eval=0; }
  427. }
  428. laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
  429. for(laListItemPointer*lip=pending.pFirst;lip;lip=NextLip){ n=lip->p; NextLip=lip->pNext;
  430. if(n->Eval&LA_DAG_FLAG_PERM) continue;
  431. result=n->Type->Visit(n,&MAIN.InputMappingEval); if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&pending)); break; }
  432. }
  433. if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&MAIN.InputMappingEval)); return LA_DAG_FLAG_ERR; }
  434. return LA_DAG_FLAG_PERM;
  435. }