1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-27 16:39:29 +00:00
ctruLua/source/cam.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

751 lines
16 KiB
C

/***
The `cam` module.
@module ctr.cam
@usage local cam = require("ctr.cam")
*/
#include <3ds.h>
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/services/cam.h>
#include <sf2d.h>
#include <lua.h>
#include <lauxlib.h>
#include <malloc.h>
#include "texture.h"
/***
Initialize the camera module.
@function init
*/
static int cam_init(lua_State *L) {
Result ret = camInit();
if (ret) {
lua_pushboolean(L, false);
lua_pushinteger(L, ret);
return 2;
}
lua_pushboolean(L, true);
return 1;
}
/***
Disable the camera module.
@function shutdown
*/
static int cam_shutdown(lua_State *L) {
camExit();
return 0;
}
/***
Activate a camera.
@function activate
@tparam number camera camera to activate (`SELECT_x`)
*/
static int cam_activate(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
CAMU_Activate(cam);
return 0;
}
/***
Set the exposure of a camera.
@function setExposure
@tparam number camera (`SELECT_x`)
@tparam number exposure (from `-128` to `127`)
*/
static int cam_setExposure(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
s8 expo = luaL_checkinteger(L, 2);
CAMU_SetExposure(cam, expo);
return 0;
}
/***
Set the white balance of a camera.
@function setWhiteBalance
@tparam number camera (`SELECT_x`)
@tparam number white white balance (`WHITE_BALANCE_x`)
*/
static int cam_setWhiteBalance(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
u8 bal = luaL_checkinteger(L, 2);
CAMU_SetWhiteBalance(cam, bal);
return 0;
}
/***
Set the sharpness of a camera.
@function setSharpness
@tparam number camera (`SELECT_x`)
@tparam number sharpness from (from `-128` to `127`)
*/
static int cam_setSharpness(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
s8 sharp = luaL_checkinteger(L, 2);
CAMU_SetSharpness(cam, sharp);
return 0;
}
/***
Set the auto exposure mode of a camera.
@function setAutoExposure
@tparam number camera (`SELECT_x`)
@tparam boolean auto `true` to enable, `false` to disable
*/
static int cam_setAutoExposure(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
bool expo = lua_toboolean(L, 2);
CAMU_SetAutoExposure(cam, expo);
return 0;
}
/***
Check if the auto exposure mode is enabled for a camera.
@function isAutoExposure
@tparam number camera (`SELECT_x`)
@treturn boolean `true` if enabled, `false` if not
*/
static int cam_isAutoExposure(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
bool expo = false;
CAMU_IsAutoExposure(&expo, cam);
lua_pushboolean(L, expo);
return 1;
}
/***
Set the auto white balance mode for a camera.
@function setAutoWhiteBalance
@tparam number camera (`SELECT_x`)
@tparam boolean auto `true` to enable, `false` to disable
*/
static int cam_setAutoWhiteBalance(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
bool bal = lua_toboolean(L, 2);
CAMU_SetAutoWhiteBalance(cam, bal);
return 0;
}
/***
Check if the auto white balance mode is enabled for a camera.
@function isAutoWhiteBalance
@tparam number camera (`SELECT_x`)
@treturn boolean `true` if enabled, `false` if not
*/
static int cam_isAutoWhiteBalance(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
bool bal = false;
CAMU_IsAutoWhiteBalance(&bal, cam);
lua_pushboolean(L, bal);
return 1;
}
/***
Set the contrast on a camera.
@function setContrast
@tparam number camera (`SELECT_x`)
@tparam number contrast (`CONTRAST_x`)
*/
static int cam_setContrast(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
u8 cont = luaL_checkinteger(L, 2);
CAMU_SetContrast(cam, cont);
return 0;
}
/***
Set the lens correction of a camera.
@function setLensCorrection
@tparam number camera (`SELECT_x`)
@tparam number correction lens correction (`LENS_CORRECTION_x`)
*/
static int cam_setLensCorrection(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
u8 corr = luaL_checkinteger(L, 2);
CAMU_SetLensCorrection(cam, corr);
return 0;
}
/***
Set the window where the exposure will be check.
@function setAutoExposureWindow
@tparam number x x starting position of the window
@tparam number y y starting position of the window
@tparam number w width of the window
@tparam number h height of the window
*/
static int cam_setAutoExposureWindow(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
s16 x = luaL_checkinteger(L, 2);
s16 y = luaL_checkinteger(L, 3);
s16 w = luaL_checkinteger(L, 4);
s16 h = luaL_checkinteger(L, 5);
CAMU_SetAutoExposureWindow(cam, x, y, w, h);
return 0;
}
/***
Set the window where the white balance will be check.
@function setAutoWhiteBalanceWindow
@tparam number x x starting position of the window
@tparam number y y starting position of the window
@tparam number w width of the window
@tparam number h height of the window
*/
static int cam_setAutoWhiteBalanceWindow(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
s16 x = luaL_checkinteger(L, 2);
s16 y = luaL_checkinteger(L, 3);
s16 w = luaL_checkinteger(L, 4);
s16 h = luaL_checkinteger(L, 5);
CAMU_SetAutoWhiteBalanceWindow(cam, x, y, w, h);
return 0;
}
/***
Enable or disable the noise filter on a camera.
@function setNoiseFilter
@tparam number camera (`SELECT_x`)
@tparam boolean filter `true` to enable, `false` to disable
*/
static int cam_setNoiseFilter(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
bool fil = lua_toboolean(L, 2);
CAMU_SetNoiseFilter(cam, fil);
return 0;
}
/***
Play a shutter sound.
@function playShutterSound
@tparam number sound shutter sound type (`SHUTTER_x`)
*/
static int cam_playShutterSound(lua_State *L) {
u8 shut = luaL_checkinteger(L, 1);
CAMU_PlayShutterSound(shut);
return 0;
}
/***
Set the size of the base camera image.
@function setSize
@tparam number camera (`SELECT_x`)
@tparam number size (`SIZE_x`)
@tparam number context (`CONTEXT_x`)
*/
static int cam_setSize(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
u8 size = luaL_checkinteger(L, 2);
u8 context = luaL_checkinteger(L, 3);
CAMU_SetSize(cam, size, context);
return 0;
}
/***
Set the effect applied on the image.
@function setEffect
@tparam number camera (`SELECT_x`)
@tparam number effect (`EFFECT_x`)
@tparam number context (`CONTEXT_x`)
*/
static int cam_setEffect(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
u8 effect = luaL_checkinteger(L, 2);
u8 context = luaL_checkinteger(L, 3);
CAMU_SetEffect(cam, effect, context);
return 0;
}
/***
Set the frame rate of a camera.
@function setFrameRate
@tparam number camera (`SELECT_x`)
@tparam number rate frame rate (`FRAME_RATE_x`)
*/
static int cam_setFrameRate(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
u8 rate = luaL_checkinteger(L, 2);
CAMU_SetFrameRate(cam, rate);
return 0;
}
/***
Take a picture and put it in a texture.
@function takePicture
@tparam number camera should be PORT_CAM1 if you have only 1 camera activated (`PORT_x`)
@tparam number w width of the picture
@tparam number h height of the picture
@tparam[opt=PLACE_RAM] number place where to put the texture
@treturn texture the texture object
*/
static int cam_takePicture(lua_State *L) {
u8 cam = luaL_checkinteger(L, 1);
s16 w = luaL_optinteger(L, 2, 640);
s16 h = luaL_optinteger(L, 3, 480);
u32 bufSize = 0;
// Take the actual picture
CAMU_GetMaxBytes(&bufSize, w, h);
u8* buf = malloc(bufSize);
CAMU_SetTransferBytes(cam, bufSize, w, h);
Handle camReceiveEvent = 0;
CAMU_ClearBuffer(cam);
CAMU_StartCapture(cam);
CAMU_SetReceiving(&camReceiveEvent, buf, cam, bufSize, (s16)bufSize);
svcWaitSynchronization(camReceiveEvent, 300000000ULL);
CAMU_StopCapture(cam);
// Load it in a texture
u8 place = luaL_optinteger(L, 4, SF2D_PLACE_RAM);
texture_userdata *texture;
texture = (texture_userdata *)lua_newuserdata(L, sizeof(*texture));
luaL_getmetatable(L, "LTexture");
lua_setmetatable(L, -2);
texture->texture = sf2d_create_texture_mem_RGBA8(buf, w, h, TEXFMT_RGB565, place);
sf2d_texture_tile32(texture->texture);
texture->scaleX = 1.0f;
texture->scaleY = 1.0f;
texture->blendColor = 0xffffffff;
return 1;
}
// Functions
static const struct luaL_Reg cam_lib[] = {
{"init", cam_init },
{"shutdown", cam_shutdown },
{"activate", cam_activate },
{"setExposure", cam_setExposure },
{"setWhiteBalance", cam_setWhiteBalance },
{"setSharpness", cam_setSharpness },
{"setAutoExposure", cam_setAutoExposure },
{"isAutoExposure", cam_isAutoExposure },
{"setAutoWhiteBalance", cam_setAutoWhiteBalance },
{"isAutoWhiteBalance", cam_isAutoWhiteBalance },
{"setContrast", cam_setContrast },
{"setLensCorrection", cam_setLensCorrection },
{"setAutoExposureWindow", cam_setAutoExposureWindow },
{"setAutoWhiteBalanceWindow", cam_setAutoWhiteBalanceWindow},
{"setNoiseFilter", cam_setNoiseFilter },
{"playShutterSound", cam_playShutterSound },
{"setSize", cam_setSize },
{"setEffect", cam_setEffect },
{"setFrameRate", cam_setFrameRate },
{"takePicture", cam_takePicture },
{NULL, NULL}
};
struct { char *name; int value; } cam_constants[] = {
/***
First camera activated.
@field PORT_CAM1
*/
{"PORT_CAM1", PORT_CAM1},
/***
Second camera activated.
@field PORT_CAM2
*/
{"PORT_CAM2", PORT_CAM2},
/***
The two activated camera. Should not be used ATM.
@field PORT_BOTH
*/
{"PORT_BOTH", PORT_BOTH},
/***
@field SELECT_NONE
*/
{"SELECT_NONE", SELECT_NONE },
/***
@field SELECT_OUT1
*/
{"SELECT_OUT1", SELECT_OUT1 },
/***
@field SELECT_IN1
*/
{"SELECT_IN1", SELECT_IN1 },
/***
@field SELECT_OUT2
*/
{"SELECT_OUT2", SELECT_OUT2 },
/***
@field SELECT_IN1_OUT1
*/
{"SELECT_IN1_OUT1", SELECT_IN1_OUT1 },
/***
@field SELECT_OUT1_OUT2
*/
{"SELECT_OUT1_OUT2", SELECT_OUT1_OUT2},
/***
@field SELECT_IN1_OUT2
*/
{"SELECT_IN1_OUT2", SELECT_IN1_OUT2 },
/***
@field SELECT_ALL
*/
{"SELECT_ALL", SELECT_ALL },
/***
@field CONTEXT_NONE
*/
{"CONTEXT_NONE", CONTEXT_NONE},
/***
@field CONTEXT_A
*/
{"CONTEXT_A", CONTEXT_A },
/***
@field CONTEXT_B
*/
{"CONTEXT_B", CONTEXT_B },
/***
@field CONTEXT_BOTH
*/
{"CONTEXT_BOTH", CONTEXT_BOTH},
/***
@field FLIP_NONE
*/
{"FLIP_NONE", FLIP_NONE },
/***
@field FLIP_HORIZONTAL
*/
{"FLIP_HORIZONTAL", FLIP_HORIZONTAL},
/***
@field FLIP_VERTICAL
*/
{"FLIP_VERTICAL", FLIP_VERTICAL },
/***
@field FLIP_REVERSE
*/
{"FLIP_REVERSE", FLIP_REVERSE },
/***
640x480
@field SIZE_VGA
*/
{"SIZE_VGA", SIZE_VGA },
/***
320x240
@field SIZE_QVGA
*/
{"SIZE_QVGA", SIZE_QVGA },
/***
160x120
@field SIZE_QQVGA
*/
{"SIZE_QQVGA", SIZE_QQVGA },
/***
352x288
@field SIZE_CIF
*/
{"SIZE_CIF", SIZE_CIF },
/***
176x144
@field SIZE_QCIF
*/
{"SIZE_QCIF", SIZE_QCIF },
/***
256x192
@field SIZE_DS_LCD
*/
{"SIZE_DS_LCD", SIZE_DS_LCD },
/***
512x384
@field SIZE_DS_LCDx4
*/
{"SIZE_DS_LCDx4", SIZE_DS_LCDx4 },
/***
400x240
@field SIZE_CTR_TOP_LCD
*/
{"SIZE_CTR_TOP_LCD", SIZE_CTR_TOP_LCD },
/***
320x240
@field SIZE_BOTTOM_LCD
*/
{"SIZE_CTR_BOTTOM_LCD", SIZE_CTR_BOTTOM_LCD},
/***
@field FRAME_RATE_15
*/
{"FRAME_RATE_15", FRAME_RATE_15 },
/***
@field FRAME_RATE_15_TO_5
*/
{"FRAME_RATE_15_TO_5", FRAME_RATE_15_TO_5 },
/***
@field FRAME_RATE_15_TO_2
*/
{"FRAME_RATE_15_To_2", FRAME_RATE_15_TO_2 },
/***
@field FRAME_RATE_10
*/
{"FRAME_RATE_10", FRAME_RATE_10 },
/***
@field FRAME_RATE_8_5
*/
{"FRAME_RATE_8_5", FRAME_RATE_8_5 },
/***
@field FRAME_RATE_5
*/
{"FRAME_RATE_5", FRAME_RATE_5 },
/***
@field FRAME_RATE_20
*/
{"FRAME_RATE_20", FRAME_RATE_20 },
/***
@field FRAME_RATE_20_TO_5
*/
{"FRAME_RATE_20_TO_5", FRAME_RATE_20_TO_5 },
/***
@field FRAME_RATE_30
*/
{"FRAME_RATE_30", FRAME_RATE_30 },
/***
@field FRAME_RATE_TO_5
*/
{"FRAME_RATE_30_TO_5", FRAME_RATE_30_TO_5 },
/***
@field FRAME_RATE_15_TO_10
*/
{"FRAME_RATE_15_TO_10", FRAME_RATE_15_TO_10},
/***
@field FRAME_RATE_20_TO_10
*/
{"FRAME_RATE_20_TO_10", FRAME_RATE_20_TO_10},
/***
@field FRAME_RATE_30_TO_10
*/
{"FRAME_RATE_30_TO_10", FRAME_RATE_30_TO_10},
/***
@field WHITe_BALANCE_AUTO
*/
{"WHITE_BALANCE_AUTO", WHITE_BALANCE_AUTO },
/***
@field WHITE_BALANCE_3200K
*/
{"WHITE_BALANCE_3200K", WHITE_BALANCE_3200K},
/***
@field WHITE_BALANCE_4150K
*/
{"WHITE_BALANCE_4150K", WHITE_BALANCE_4150K},
/***
@field WHITE_BALANCE_5200K
*/
{"WHITE_BALANCE_5200K", WHITE_BALANCE_5200K},
/***
@field WHITE_BALANCE_6000K
*/
{"WHITE_BALANCE_6000K", WHITE_BALANCE_6000K},
/***
@field WHITE_BALANCE_7000K
*/
{"WHITE_BALANCE_7000K", WHITE_BALANCE_7000K},
/***
@field WHITE_BALANCE_TUNGSTEN
*/
{"WHITE_BALANCE_TUNGSTEN", WHITE_BALANCE_TUNGSTEN },
/***
@field WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT
*/
{"WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT", WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT},
/***
@field WHITE_BALANCE_DAYLIGHT
*/
{"WHITE_BALANCE_DAYLIGHT", WHITE_BALANCE_DAYLIGHT },
/***
@field WHITE_BALANCE_CLOUDY
*/
{"WHITE_BALANCE_CLOUDY", WHITE_BALANCE_CLOUDY },
/***
@field WHITE_BALANCE_HORIZON
*/
{"WHITE_BALANCE_HORIZON", WHITE_BALANCE_HORIZON },
/***
@field WHITE_BALANCE_SHADE
*/
{"WHITE_BALANCE_SHADE", WHITE_BALANCE_SHADE },
/***
@field PHOTO_MODE_NORMAL
*/
{"PHOTO_MODE_NORMAL", PHOTO_MODE_NORMAL },
/***
@field PHOTO_MODE_PORTRAIT
*/
{"PHOTO_MODE_PORTRAIT", PHOTO_MODE_PORTRAIT },
/***
@field PHOTO_MODE_LANDSCAPE
*/
{"PHOTO_MODE_LANDSCAPE", PHOTO_MODE_LANDSCAPE},
/***
@field PHOTO_MODE_NIGHTVIEW
*/
{"PHOTO_MODE_NIGHTVIEW", PHOTO_MODE_NIGHTVIEW},
/***
@field PHOTO_MODE_LETTER
*/
{"PHOTO_MODE_LETTER", PHOTO_MODE_LETTER },
/***
@field EFFECT_NONE
*/
{"EFFECT_NONE", EFFECT_NONE },
/***
@field EFFECT_MONO
*/
{"EFFECT_MONO", EFFECT_MONO },
/***
@field EFFECT_SEPIA
*/
{"EFFECT_SEPIA", EFFECT_SEPIA },
/***
@field EFFECT_NEGATIVE
*/
{"EFFECT_NEGATIVE", EFFECT_NEGATIVE},
/***
@field EFFECT_NEGAFILM
*/
{"EFFECT_NEGAFILM", EFFECT_NEGAFILM},
/***
@field EFFECT_SEPIA01
*/
{"EFFECT_SEPIA01", EFFECT_SEPIA01 },
/***
@field CONTRAST_01
*/
{"CONTRAST_01", CONTRAST_PATTERN_01},
/***
@field CONTRAST_02
*/
{"CONTRAST_02", CONTRAST_PATTERN_02},
/***
@field CONTRAST_03
*/
{"CONTRAST_03", CONTRAST_PATTERN_03},
/***
@field CONTRAST_04
*/
{"CONTRAST_04", CONTRAST_PATTERN_04},
/***
@field CONTRAST_05
*/
{"CONTRAST_05", CONTRAST_PATTERN_05},
/***
@field CONTRAST_06
*/
{"CONTRAST_06", CONTRAST_PATTERN_06},
/***
@field CONTRAST_07
*/
{"CONTRAST_07", CONTRAST_PATTERN_07},
/***
@field CONTRAST_08
*/
{"CONTRAST_08", CONTRAST_PATTERN_08},
/***
@field CONTRAST_09
*/
{"CONTRAST_09", CONTRAST_PATTERN_09},
/***
@field CONTRAST_10
*/
{"CONTRAST_10", CONTRAST_PATTERN_10},
/***
@field CONTRAST_11
*/
{"CONTRAST_11", CONTRAST_PATTERN_11},
/***
@field CONTRAST_LOW
*/
{"CONTRAST_LOW", CONTRAST_LOW },
/***
@field CONTRAST_NORMAL
*/
{"CONTRAST_NORMAL", CONTRAST_NORMAL },
/***
@field CONTRAST_HIGH
*/
{"CONTRAST_HIGH", CONTRAST_HIGH },
/***
@field LENS_CORRECTION_OFF
*/
{"LENS_CORRECTION_OFF", LENS_CORRECTION_OFF },
/***
@field LENS_CORRECTION_NORMAL
*/
{"LENS_CORRECTION_NORMAL", LENS_CORRECTION_NORMAL},
/***
@field LENS_CORRECTION_BRIGHT
*/
{"LENS_CORRECTION_BRIGHT", LENS_CORRECTION_BRIGHT},
/***
@field SHUTTER_NORMAL
*/
{"SHUTTER_NORMAL", SHUTTER_SOUND_TYPE_NORMAL },
/***
@field SHUTTER_MOVIE
*/
{"SHUTTER_MOVIE", SHUTTER_SOUND_TYPE_MOVIE },
/***
@field SHUTTER_MOVIE_END
*/
{"SHUTTER_MOVIE_END", SHUTTER_SOUND_TYPE_MOVIE_END},
{NULL, 0}
};
int luaopen_cam_lib(lua_State *L) {
luaL_newlib(L, cam_lib);
for (int i = 0; cam_constants[i].name; i++) {
lua_pushinteger(L, cam_constants[i].value);
lua_setfield(L, -2, cam_constants[i].name);
}
return 1;
}
void load_cam_lib(lua_State *L) {
luaL_requiref(L, "ctr.cam", luaopen_cam_lib, false);
}