From 943db8cf5ef91f25028ecd8ddc80c6bc1193b1af Mon Sep 17 00:00:00 2001 From: lif <> Date: Sun, 15 Dec 2024 21:09:00 -0800 Subject: [PATCH] camera selection menu --- main.c | 215 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 152 insertions(+), 63 deletions(-) diff --git a/main.c b/main.c index b754e32..929b799 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,8 @@ -#include "SDL3/SDL_camera.h" #define SDL_MAIN_USE_CALLBACKS 1 #include "SDL3/SDL_blendmode.h" +#include "SDL3/SDL_camera.h" #include "SDL3/SDL_error.h" +#include "SDL3/SDL_events.h" #include "SDL3/SDL_init.h" #include "SDL3/SDL_keycode.h" #include "SDL3/SDL_log.h" @@ -17,7 +18,8 @@ #include "mgba/core/core.h" #include "mgba/core/interface.h" #include "mgba/feature/commandline.h" -//#include "mgba-util/image.h" + +#include #define NUM_CHANNELS 3 #define FRAMESKIP_LIMIT 20 @@ -132,14 +134,156 @@ void myRequestImageBlue(struct mImageSource* self, const void** buf, size_t* str struct mImageSource gb_img_src[3]; -SDL_AppResult SDL_AppInit(void** appstate, int argc, char *argv[]) { +bool SelectCamera(SDL_Renderer* renderer) { + SDL_Event event; + int devcount = 0; + int cam_idx = 0, spec_idx = 0; + + while (camera == NULL) { + if (cam_idx >= devcount) { + cam_idx = 0; + } else if (cam_idx < 0) { + cam_idx = devcount - 1; + } + + SDL_CameraID *devices = SDL_GetCameras(&devcount); + if (!devices) { + SDL_Log("SDL_GetCameras failed: %s", SDL_GetError()); + return false; + } + + if (devcount == 0) { + SDL_free(devices); + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderDebugText(renderer, 4, 4, "connect a camera"); + + SDL_RenderPresent(renderer); + + if (!SDL_WaitEvent(&event)) { + SDL_Log("Error waiting for event: %s", SDL_GetError()); + return false; + } + if (event.type == SDL_EVENT_QUIT) { + SDL_Log("Quit!"); + return false; + } + + continue; + } + + const SDL_CameraID device = devices[cam_idx]; + const char *name = SDL_GetCameraName(device); + + const SDL_CameraPosition position = SDL_GetCameraPosition(device); + const char *posstr = ""; + + char snprintfbuf[20]; + + int formats_len = 0; + + SDL_CameraSpec** formats = SDL_GetCameraSupportedFormats(device, &formats_len); + if (spec_idx >= formats_len) { + spec_idx = 0; + } else if (spec_idx < 0) { + spec_idx = formats_len - 1; + } + SDL_CameraSpec* format = formats[spec_idx]; + const char* pixfmt_name = SDL_GetPixelFormatName(format->format); + if (strncmp("SDL_PIXELFORMAT_", pixfmt_name, 16) == 0) { + pixfmt_name += 16; + } + + if (position == SDL_CAMERA_POSITION_FRONT_FACING) { + front_camera = device; + posstr = "[frontfacing]"; + } else if (position == SDL_CAMERA_POSITION_BACK_FACING) { + back_camera = device; + posstr = "[backfacing]"; + } + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderDebugText(renderer, 4, 4, "camera: (up/down)"); + snprintf(snprintfbuf, sizeof(snprintfbuf), "%d. %s", cam_idx, posstr); + SDL_RenderDebugText(renderer, 8, 16, snprintfbuf); + SDL_RenderDebugText(renderer, 4, 28, name); + SDL_free((void*)name); + + SDL_RenderDebugText(renderer, 4, 52, "mode: (left/right)"); + snprintf( + snprintfbuf, + sizeof(snprintfbuf), + "%d.", + spec_idx + ); + SDL_RenderDebugText(renderer, 8, 64, snprintfbuf); + + snprintf( + snprintfbuf, + sizeof(snprintfbuf), + "%dx%d", + format->width, + format->height + ); + SDL_RenderDebugText(renderer, 4, 76, snprintfbuf); + + snprintf( + snprintfbuf, + sizeof(snprintfbuf), + "%.1f Hz", + ((float)format->framerate_numerator / (float)format->framerate_denominator) + ); + SDL_RenderDebugText(renderer, 4, 88, snprintfbuf); + SDL_RenderDebugText(renderer, 4, 100, pixfmt_name); + + SDL_RenderDebugText(renderer, 4, 124, "confirm: (enter)"); + + if (!SDL_WaitEvent(&event)) { + SDL_Log("Error waiting for event: %s", SDL_GetError()); + return false; + } + + switch (event.type) { + case SDL_EVENT_QUIT: + SDL_Log("Quit!"); + return false; + + case SDL_EVENT_KEY_DOWN: + switch (event.key.key) { + case SDLK_UP: cam_idx -= 1; break; + case SDLK_DOWN: cam_idx += 1; break; + case SDLK_LEFT: spec_idx -= 1; break; + case SDLK_RIGHT: spec_idx += 1; break; + case SDLK_RETURN: + camera = SDL_OpenCamera(device, format); + break; + default: break; + } + break; + + default: break; + } + + SDL_free(formats); + SDL_free(devices); + + SDL_RenderPresent(renderer); + } + + return true; +} + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char *argv[]) { int i; unsigned w, h; - SDL_CameraID *devices; - SDL_CameraID devid; - struct mArguments args; bool parsed = mArgumentsParse(&args, argc, argv, NULL, 0); @@ -208,62 +352,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char *argv[]) { SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE); - devices = SDL_GetCameras(&devcount); - if (!devices) { - SDL_Log("SDL_GetCameras failed: %s", SDL_GetError()); - return SDL_APP_FAILURE; - } - - SDL_Log("Saw %d camera devices.", devcount); - for (i = 0; i < devcount; i++) { - const SDL_CameraID device = devices[i]; - const char *name = SDL_GetCameraName(device); - const SDL_CameraPosition position = SDL_GetCameraPosition(device); - const char *posstr = ""; - int j, formats_len = 0; - SDL_CameraSpec** formats = SDL_GetCameraSupportedFormats(device, &formats_len); - - if (position == SDL_CAMERA_POSITION_FRONT_FACING) { - front_camera = device; - posstr = "[front-facing] "; - } else if (position == SDL_CAMERA_POSITION_BACK_FACING) { - back_camera = device; - posstr = "[back-facing] "; - } - SDL_Log(" - %sCamera #%d: %s", posstr, i, name); - SDL_free((void*)name); - - for (j = 0; j < formats_len; j++) { - SDL_CameraSpec* fmt = formats[j]; - SDL_Log(" - Format %d: %s %dx%d @ %d/%d", - j, - SDL_GetPixelFormatName(fmt->format), - fmt->width, - fmt->height, - fmt->framerate_numerator, - fmt->framerate_denominator - ); - spec = *fmt; - } - SDL_free(formats); - } - - /* HACK: no front-facing? just use hardcoded index til we have selection menu. */ - devid = front_camera ? front_camera : devices[0]; - SDL_free(devices); - - if (!devid) { - SDL_Log("No cameras available?"); - return SDL_APP_FAILURE; - } - - spec.format = SDL_PIXELFORMAT_XBGR1555; - //spec.width = 320; - //spec.height = 240; - spec.framerate_numerator = 30; - spec.framerate_denominator = 1; - camera = SDL_OpenCamera(devid, &spec); - if (!camera) { + if (!SelectCamera(renderer)) { SDL_Log("Failed to open camera device: %s", SDL_GetError()); return SDL_APP_FAILURE; } @@ -444,7 +533,7 @@ SDL_AppResult SDL_AppIterate(void* appstate) { } SDL_ReleaseCameraFrame(camera, frame); - + SDL_SetSurfaceColorMod(scaled, 255, 0, 0); SDL_BlitSurface(scaled, NULL, filtered[0], NULL); SDL_SetSurfaceColorMod(scaled, 0, 255, 0);