tlang-c/libtlang/src/wpad-wii.c

223 lines
7.2 KiB
C
Raw Normal View History

2023-04-24 18:41:46 +00:00
#if defined(HW_RVL)
#include "tlang.h"
#include <wiiuse/wpad.h>
tobject_t* wpad=NULL;
bool init=false;
struct {
list_tobject_t down_handler;
list_tobject_t up_handler;
} wpad_data[4];
typedef struct {
tobject_t* obj;
int chan;
} eventctx_t;
int* channels = {WPAD_CHAN_0,WPAD_CHAN_1,WPAD_CHAN_2,WPAD_CHAN_3};
tobject_t* __wpad_get_buttons_down_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
u32 b = WPAD_ButtonsDown(*((int*)ptr));
return tobject_number(rt,b);
}
void __free_eventctx(tobject_t* o)
{
free(o->data.external_method.data);
}
tobject_t* __wpad_get_buttons_up_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
u32 b = WPAD_ButtonsUp(*((int*)ptr));
return tobject_number(rt,b);
}
tobject_t* __wpad_init_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(!init)
{
int i;
for(i = 0;i<4;i++){
list_create(rt,&wpad_data[i].down_handler,0);
list_create(rt,&wpad_data[i].up_handler,0);
}
return tobject_number(rt,WPAD_Init());
}
}
tobject_t* __wpad_remove_up_handler(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 0)
{
eventctx_t* ctx = (eventctx_t*)ptr;
list_remove(&wpad_data[ctx->chan].up_handler,args->items[0]);
return ctx->obj;
}
return tobject_basic(rt,tnull);
}
tobject_t* __wpad_add_up_handler(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 0)
{
eventctx_t* ctx = (eventctx_t*)ptr;
list_add(&wpad_data[ctx->chan].up_handler,args->items[0]);
return ctx->obj;
}
return tobject_basic(rt,tnull);
}
tobject_t* __wpad_remove_down_handler(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 0)
{
eventctx_t* ctx = (eventctx_t*)ptr;
list_remove(&wpad_data[ctx->chan].down_handler,args->items[0]);
return ctx->obj;
}
return tobject_basic(rt,tnull);
}
tobject_t* __wpad_add_down_handler(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 0)
{
eventctx_t* ctx = (eventctx_t*)ptr;
list_add(&wpad_data[ctx->chan].down_handler,args->items[0]);
return ctx->obj;
}
return tobject_basic(rt,tnull);
}
void wpad_send_up_command(runtime_t* rt)
{
int i;
for(i=0;i<4;i++)
{
tobject_t* o = tobject_create(rt);
o->type = tdict;
o->data.dict = dict_create();
kvp_t kvp0;
kvp0.key = "channel";
kvp0.value = tobject_number(rt,i);
dict_setkvp(o->data.dict,kvp0);
kvp0.key = "buttons";
kvp0.value = tobject_number(rt,WPAD_ButtonsUp(i));
dict_setkvp(o->data.dict,kvp0);
int j;
list_tobject_t myArgs;
list_add(&myArgs,wpad);
list_add(&myArgs,o);
for(j=0;j<wpad_data[i].up_handler.length;i++)
{
tobject_t* res=wpad_data[i].up_handler.items[j];
if(res->type == texternalmethod || res->type == tinternalmethod)
{
tobject_call(rt->globals,res,&myArgs);
}
}
list_free(&myArgs);
}
}
void wpad_send_down_command(runtime_t* rt)
{
int i;
for(i=0;i<4;i++)
{
tobject_t* o = tobject_create(rt);
o->type = tdict;
o->data.dict = dict_create();
kvp_t kvp0;
kvp0.key = "channel";
kvp0.value = tobject_number(rt,i);
dict_setkvp(o->data.dict,kvp0);
kvp0.key = "buttons";
kvp0.value = tobject_number(rt,WPAD_ButtonsDown(i));
dict_setkvp(o->data.dict,kvp0);
int j;
list_tobject_t myArgs;
list_add(&myArgs,wpad);
list_add(&myArgs,o);
for(j=0;j<wpad_data[i].down_handler.length;i++)
{
tobject_t* res=wpad_data[i].down_handler.items[j];
if(res->type == texternalmethod || res->type == tinternalmethod)
{
tobject_call(rt->globals,res,&myArgs);
}
}
list_free(&myArgs);
}
}
tobject_t* __wpad_scanpads_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
s32 s =WPAD_ScanPads();
wpad_send_down_command(rt);
wpad_send_up_command(rt);
return tobject_number(rt,s);
}
tobject_t* __wpad_at_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
//at(i)
if(args->length > 0 && args->items[0]->type == tnumber && args->items[0]->data.number >= 0 && args->items[0]->data.number < 4)
{
tobject_t* wpad_chan = tobject_create(rt);
wpad_chan->type = tdict;
wpad_chan->data.dict = dict_create();
runtime_create_method_on_dict(wpad->data.dict,"getbuttonsdown",rt,&channels[(int)args->items[0]->data.number],__wpad_get_buttons_down_external_method,NULL);
runtime_create_method_on_dict(wpad->data.dict,"getbuttonsup",rt,&channels[(int)args->items[0]->data.number],__wpad_get_buttons_up_external_method,NULL);
tobject_t* downEvent = tobject_create(rt);
downEvent->type = tdict;
downEvent->data.dict = dict_create();
tobject_t* upEvent = tobject_create(rt);
upEvent->type = tdict;
upEvent->data.dict = dict_create();
eventctx_t* addObjDown = (eventctx_t*)malloc(sizeof(eventctx_t));
addObjDown->chan = (int)args->items[0]->data.number;
addObjDown->obj = downEvent;
eventctx_t* subObjDown = (eventctx_t*)malloc(sizeof(eventctx_t));
subObjDown->chan = (int)args->items[0]->data.number;
subObjDown->obj = downEvent;
eventctx_t* addObjUp = (eventctx_t*)malloc(sizeof(eventctx_t));
addObjUp->chan = (int)args->items[0]->data.number;
addObjUp->obj = upEvent;
eventctx_t* subObjUp = (eventctx_t*)malloc(sizeof(eventctx_t));
subObjDown->chan = (int)args->items[0]->data.number;
subObjUp->obj = upEvent;
runtime_create_method_on_dict(downEvent->data.dict,"add",rt,addObjDown,__wpad_add_down_handler,__free_eventctx);
runtime_create_method_on_dict(downEvent->data.dict,"sub",rt,subObjDown,__wpad_remove_down_handler,__free_eventctx);
runtime_create_method_on_dict(upEvent->data.dict,"add",rt,addObjUp,__wpad_add_up_handler,__free_eventctx);
runtime_create_method_on_dict(upEvent->data.dict,"sub",rt,subObjUp,__wpad_remove_up_handler,__free_eventctx);
kvp_t kvp;
kvp.key = "down";
kvp.value = downEvent;
dict_setkvp(wpad_chan->data.dict,kvp);
kvp.key = "up";
kvp.value = upEvent;
dict_setkvp(wpad_chan->data.dict,kvp);
return wpad_chan;
}
return tobject_basic(rt,tundef);
}
void __reg_wpad(runtime_t* rt)
{
if(wpad ==NULL){
wpad = tobject_create(rt);
wpad->type = tdict;
wpad->data.dict = dict_create();
wpad->count = 1;
runtime_create_method_on_dict(wpad->data.dict,"init",rt,NULL,__wpad_init_external_method,NULL);
runtime_create_method_on_dict(wpad->data.dict,"scanpads",rt,NULL,__wpad_scanpads_external_method,NULL);
runtime_create_method_on_dict(wpad->data.dict,"at",rt,NULL,__wpad_at_external_method,NULL);
}
//dict_setkvp(wpad->data.dict,);
rt->globals->setvariable(rt->globals,"wpad",wpad);
}
#endif