1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-27 16:39:29 +00:00
ctruLua/source/hid.c
Firew0lf 2e782ed9ea Updated to the latest ctrulib, Fixed some minor bugs.
Working with citra, untested on real hardware but should be OK.
IR should now work.
Let's add some 3D drawing and sound now !
2015-12-14 23:11:45 +01:00

268 lines
5.8 KiB
C

/***
The `hid` module.
The circle pad pro is supported, it's keys replace de "3ds only" keys
@module ctr.hid
@usage local hid = require("ctr.hid")
*/
#include <3ds/types.h>
#include <3ds/services/hid.h>
#include <lua.h>
#include <lauxlib.h>
/***
Keys list
@table keys
@field a A
@field b B
@field select Select
@field start Start
@field dRight D-Pad right
@field dLeft D-Pad Left
@field dUp D-Pad Up
@field dDown D-Pad Down
@field r R trigger
@field l L trigger
@field x X
@field y Y
@field zl ZL trigger (new3ds only)
@field zr ZR trigger (new3ds only)
@field touch
@field cstickRight C-Stick right (new3ds only)
@field cstickLeft C-Stick left (new3ds only)
@field cstickUp C-Stick up (new3ds only)
@field cstickDown C-Stick down (new3ds only)
@field cpadRight Circle pad right
@field cpadLeft Circle pad left
@field cpadUp Circle pad up
@field cpadDown Circle pad down
@field up Generic up
@field down Generic down
@field left Generic left
@field right Generic right
*/
/***
Keys states
@table states
@field down keys which have been just pressed
@field held keys which are held down
@field up keys whick are been just released
*/
// Key list based on hid.h from the ctrulib by smealum
struct { u32 key; char *name; } hid_keys_name[] = {
{ KEY_A , "a" },
{ KEY_B , "b" },
{ KEY_SELECT , "select" },
{ KEY_START , "start" },
{ KEY_DRIGHT , "dRight" },
{ KEY_DLEFT , "dLeft" },
{ KEY_DUP , "dUp" },
{ KEY_DDOWN , "dDown" },
{ KEY_R , "r" },
{ KEY_L , "l" },
{ KEY_X , "x" },
{ KEY_Y , "y" },
{ KEY_ZL , "zl" }, // (new 3DS only)
{ KEY_ZR , "zr" }, // (new 3DS only)
{ KEY_TOUCH , "touch" }, // Not actually provided by HID
{ KEY_CSTICK_RIGHT , "cstickRight"}, // c-stick (new 3DS only)
{ KEY_CSTICK_LEFT , "cstickLeft" }, // c-stick (new 3DS only)
{ KEY_CSTICK_UP , "cstickUp" }, // c-stick (new 3DS only)
{ KEY_CSTICK_DOWN , "cstickDown" }, // c-stick (new 3DS only)
{ KEY_CPAD_RIGHT , "cpadRight" }, // circle pad
{ KEY_CPAD_LEFT , "cpadLeft" }, // circle pad
{ KEY_CPAD_UP , "cpadUp" }, // circle pad
{ KEY_CPAD_DOWN , "cpadDown" }, // circle pad
// Generic catch-all directions
{ KEY_UP , "up" },
{ KEY_DOWN , "down" },
{ KEY_LEFT , "left" },
{ KEY_RIGHT , "right" },
{ 0, NULL }
};
/***
Refresh the HID state.
@function read
*/
static int hid_read(lua_State *L) {
hidScanInput();
return 0;
}
/***
Return the keys states as `state.key` in a table.
@function keys
@treturn table keys states
@usage
-- Just an example
hid.read()
local keys = hid.keys()
if keys.held.a then
-- do stuff
end
*/
static int hid_keys(lua_State *L) {
u32 kDown = hidKeysDown();
u32 kHeld = hidKeysHeld();
u32 kUp = hidKeysUp();
lua_createtable(L, 0, 3);
lua_newtable(L); // down table
lua_newtable(L); // held table
lua_newtable(L); // up table
for (int i = 0; hid_keys_name[i].key; i++) {
u32 key = hid_keys_name[i].key;
char *name = hid_keys_name[i].name;
if (kDown & key) {
lua_pushboolean(L, true);
lua_setfield(L, -4, name);
}
if (kHeld & key) {
lua_pushboolean(L, true);
lua_setfield(L, -3, name);
}
if (kUp & key) {
lua_pushboolean(L, true);
lua_setfield(L, -2, name);
}
}
lua_setfield(L, -4, "up");
lua_setfield(L, -3, "held");
lua_setfield(L, -2, "down");
return 1;
}
/***
Return the touch position on the touch screen.
`0,0` is the top-left corner.
@function touch
@treturn number X position
@treturn number Y position
*/
static int hid_touch(lua_State *L) {
touchPosition pos;
hidTouchRead(&pos);
lua_pushinteger(L, pos.px);
lua_pushinteger(L, pos.py);
return 2;
}
/***
Return the circle pad position.
`0,0` is the center position. Warning: the circle pad doesn't always go back to `0,0`.
@function circle
@treturn number X position
@treturn number Y position
*/
static int hid_circle(lua_State *L) {
circlePosition pos;
hidCircleRead(&pos);
lua_pushinteger(L, pos.dx);
lua_pushinteger(L, pos.dy);
return 2;
}
/***
Return the accelerometer vector
@function accel
@treturn number X acceleration
@treturn number Y acceleration
@treturn number Z acceleration
*/
static int hid_accel(lua_State *L) {
accelVector pos;
hidAccelRead(&pos);
lua_pushinteger(L, pos.x);
lua_pushinteger(L, pos.y);
lua_pushinteger(L, pos.z);
return 3;
}
/***
Return the gyroscope rate.
@function gyro
@treturn number roll
@treturn number pitch
@treturn number yaw
*/
static int hid_gyro(lua_State *L) {
angularRate pos;
hidGyroRead(&pos);
lua_pushinteger(L, pos.x);
lua_pushinteger(L, pos.y);
lua_pushinteger(L, pos.z);
return 3;
}
/***
Return the sound volume.
@function volume
@treturn number volume (`0` to `63`)
*/
static int hid_volume(lua_State *L) {
u8 volume = 0;
HIDUSER_GetSoundVolume(&volume);
lua_pushinteger(L, volume);
return 1;
}
/***
Return the 3D cursor position.
@function pos3d
@treturn number 3d cursor position (`0` to `1`)
*/
static int hid_3d(lua_State *L) {
float slider = (*(float*)0x1FF81080);
lua_pushnumber(L, slider);
return 1;
}
static const struct luaL_Reg hid_lib[] = {
{ "read", hid_read },
{ "keys", hid_keys },
{ "touch", hid_touch },
{ "circle", hid_circle },
{ "accel", hid_accel },
{ "gyro", hid_gyro },
{ "volume", hid_volume },
{ "pos3d", hid_3d },
{ NULL, NULL }
};
int luaopen_hid_lib(lua_State *L) {
luaL_newlib(L, hid_lib);
return 1;
}
void load_hid_lib(lua_State *L) {
HIDUSER_EnableAccelerometer();
HIDUSER_EnableGyroscope();
luaL_requiref(L, "ctr.hid", luaopen_hid_lib, false);
}
void unload_hid_lib(lua_State *L) {
HIDUSER_DisableAccelerometer();
HIDUSER_DisableGyroscope();
}