initial add
This commit is contained in:
195
camera.c
Normal file
195
camera.c
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "cell.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include "sdl.h"
|
||||
|
||||
// Camera position enum to string
|
||||
static const char *camera_position_to_string(SDL_CameraPosition pos) {
|
||||
switch (pos) {
|
||||
case SDL_CAMERA_POSITION_FRONT_FACING: return "front";
|
||||
case SDL_CAMERA_POSITION_BACK_FACING: return "back";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// SDL_Camera class
|
||||
void SDL_Camera_free(JSRuntime *rt, SDL_Camera *camera) {
|
||||
if (camera) SDL_CloseCamera(camera);
|
||||
}
|
||||
|
||||
QJSCLASS(SDL_Camera,)
|
||||
|
||||
// SDL_GetNumCameraDrivers() -> number
|
||||
JSC_CCALL(camera_get_num_drivers,
|
||||
return JS_NewInt32(js, SDL_GetNumCameraDrivers());
|
||||
)
|
||||
|
||||
// SDL_GetCameraDriver(index) -> string
|
||||
JSC_CCALL(camera_get_driver,
|
||||
int index;
|
||||
JS_ToInt32(js, &index, argv[0]);
|
||||
const char *name = SDL_GetCameraDriver(index);
|
||||
return name ? JS_NewString(js, name) : JS_NULL;
|
||||
)
|
||||
|
||||
// SDL_GetCurrentCameraDriver() -> string
|
||||
JSC_CCALL(camera_get_current_driver,
|
||||
const char *name = SDL_GetCurrentCameraDriver();
|
||||
return name ? JS_NewString(js, name) : JS_NULL;
|
||||
)
|
||||
|
||||
// SDL_GetCameras() -> array of camera IDs
|
||||
JSC_CCALL(camera_get_cameras,
|
||||
int count = 0;
|
||||
SDL_CameraID *cameras = SDL_GetCameras(&count);
|
||||
if (!cameras) return JS_NewArray(js);
|
||||
|
||||
JSValue arr = JS_NewArray(js);
|
||||
for (int i = 0; i < count; i++) {
|
||||
JS_SetPropertyUint32(js, arr, i, JS_NewUint32(js, cameras[i]));
|
||||
}
|
||||
SDL_free(cameras);
|
||||
return arr;
|
||||
)
|
||||
|
||||
// SDL_GetCameraSupportedFormats(id) -> array of format objects
|
||||
JSC_CCALL(camera_get_supported_formats,
|
||||
uint32_t id;
|
||||
JS_ToUint32(js, &id, argv[0]);
|
||||
|
||||
int count = 0;
|
||||
SDL_CameraSpec **specs = SDL_GetCameraSupportedFormats(id, &count);
|
||||
if (!specs) return JS_NewArray(js);
|
||||
|
||||
JSValue arr = JS_NewArray(js);
|
||||
for (int i = 0; i < count; i++) {
|
||||
SDL_CameraSpec *spec = specs[i];
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "format", SDL_PixelFormat2js(js, spec->format));
|
||||
JS_SetPropertyStr(js, obj, "width", JS_NewInt32(js, spec->width));
|
||||
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, spec->height));
|
||||
JS_SetPropertyStr(js, obj, "framerate_numerator", JS_NewInt32(js, spec->framerate_numerator));
|
||||
JS_SetPropertyStr(js, obj, "framerate_denominator", JS_NewInt32(js, spec->framerate_denominator));
|
||||
JS_SetPropertyUint32(js, arr, i, obj);
|
||||
}
|
||||
SDL_free(specs);
|
||||
return arr;
|
||||
)
|
||||
|
||||
// SDL_GetCameraName(id) -> string
|
||||
JSC_CCALL(camera_get_name,
|
||||
uint32_t id;
|
||||
JS_ToUint32(js, &id, argv[0]);
|
||||
const char *name = SDL_GetCameraName(id);
|
||||
return name ? JS_NewString(js, name) : JS_NULL;
|
||||
)
|
||||
|
||||
// SDL_GetCameraPosition(id) -> string
|
||||
JSC_CCALL(camera_get_position,
|
||||
uint32_t id;
|
||||
JS_ToUint32(js, &id, argv[0]);
|
||||
SDL_CameraPosition pos = SDL_GetCameraPosition(id);
|
||||
return JS_NewString(js, camera_position_to_string(pos));
|
||||
)
|
||||
|
||||
// SDL_OpenCamera(id, spec) -> Camera object
|
||||
JSC_CCALL(camera_open,
|
||||
uint32_t id;
|
||||
JS_ToUint32(js, &id, argv[0]);
|
||||
|
||||
SDL_CameraSpec spec_val, *spec = NULL;
|
||||
if (argc > 1 && !JS_IsNull(argv[1])) {
|
||||
JSValue format_val = JS_GetPropertyStr(js, argv[1], "format");
|
||||
spec_val.format = js2SDL_PixelFormat(js, format_val);
|
||||
JS_FreeValue(js, format_val);
|
||||
|
||||
JS_GETATOM(js, spec_val.width, argv[1], width, number);
|
||||
JS_GETATOM(js, spec_val.height, argv[1], height, number);
|
||||
JS_GETATOM(js, spec_val.framerate_numerator, argv[1], framerate_numerator, number);
|
||||
JS_GETATOM(js, spec_val.framerate_denominator, argv[1], framerate_denominator, number);
|
||||
spec = &spec_val;
|
||||
}
|
||||
|
||||
SDL_Camera *camera = SDL_OpenCamera(id, spec);
|
||||
if (!camera) return JS_NULL;
|
||||
return SDL_Camera2js(js, camera);
|
||||
)
|
||||
|
||||
// Camera instance methods
|
||||
JSC_CCALL(camera_get_permission_state,
|
||||
SDL_Camera *camera = js2SDL_Camera(js, self);
|
||||
return JS_NewInt32(js, SDL_GetCameraPermissionState(camera));
|
||||
)
|
||||
|
||||
JSC_CCALL(camera_get_id,
|
||||
SDL_Camera *camera = js2SDL_Camera(js, self);
|
||||
return JS_NewUint32(js, SDL_GetCameraID(camera));
|
||||
)
|
||||
|
||||
JSC_CCALL(camera_get_format,
|
||||
SDL_Camera *camera = js2SDL_Camera(js, self);
|
||||
SDL_CameraSpec spec;
|
||||
if (!SDL_GetCameraFormat(camera, &spec)) return JS_NULL;
|
||||
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "format", SDL_PixelFormat2js(js, spec.format));
|
||||
JS_SetPropertyStr(js, obj, "width", JS_NewInt32(js, spec.width));
|
||||
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, spec.height));
|
||||
JS_SetPropertyStr(js, obj, "framerate_numerator", JS_NewInt32(js, spec.framerate_numerator));
|
||||
JS_SetPropertyStr(js, obj, "framerate_denominator", JS_NewInt32(js, spec.framerate_denominator));
|
||||
return obj;
|
||||
)
|
||||
|
||||
JSC_CCALL(camera_acquire_frame,
|
||||
SDL_Camera *camera = js2SDL_Camera(js, self);
|
||||
Uint64 timestamp;
|
||||
SDL_Surface *surface = SDL_AcquireCameraFrame(camera, ×tamp);
|
||||
if (!surface) return JS_NULL;
|
||||
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "surface", SDL_Surface2js(js, surface));
|
||||
JS_SetPropertyStr(js, obj, "timestamp", JS_NewInt64(js, timestamp));
|
||||
return obj;
|
||||
)
|
||||
|
||||
JSC_CCALL(camera_release_frame,
|
||||
SDL_Camera *camera = js2SDL_Camera(js, self);
|
||||
SDL_Surface *surface = js2SDL_Surface(js, argv[0]);
|
||||
SDL_ReleaseCameraFrame(camera, surface);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(camera_close,
|
||||
SDL_Camera *camera = js2SDL_Camera(js, self);
|
||||
SDL_CloseCamera(camera);
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_SDL_Camera_funcs[] = {
|
||||
MIST_FUNC_DEF(camera, get_permission_state, 0),
|
||||
MIST_FUNC_DEF(camera, get_id, 0),
|
||||
MIST_FUNC_DEF(camera, get_format, 0),
|
||||
MIST_FUNC_DEF(camera, acquire_frame, 0),
|
||||
MIST_FUNC_DEF(camera, release_frame, 1),
|
||||
MIST_FUNC_DEF(camera, close, 0),
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_camera_funcs[] = {
|
||||
MIST_FUNC_DEF(camera, get_num_drivers, 0),
|
||||
MIST_FUNC_DEF(camera, get_driver, 1),
|
||||
MIST_FUNC_DEF(camera, get_current_driver, 0),
|
||||
MIST_FUNC_DEF(camera, get_cameras, 0),
|
||||
MIST_FUNC_DEF(camera, get_supported_formats, 1),
|
||||
MIST_FUNC_DEF(camera, get_name, 1),
|
||||
MIST_FUNC_DEF(camera, get_position, 1),
|
||||
MIST_FUNC_DEF(camera, open, 2),
|
||||
};
|
||||
|
||||
CELL_USE_INIT(
|
||||
SDL_Init(SDL_INIT_CAMERA);
|
||||
QJSCLASSPREP_FUNCS(SDL_Camera);
|
||||
|
||||
JSValue ret = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js, ret, js_camera_funcs, countof(js_camera_funcs));
|
||||
|
||||
return ret;
|
||||
)
|
||||
Reference in New Issue
Block a user