From 2d07a269fc76a729e6a49fdf445385e4b6c9523b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Apr 2023 03:40:39 -0700 Subject: [PATCH] Core: Add screenshotToImage scripting binding --- src/core/scripting.c | 30 +++++++++++++++++++++++++++++- src/core/test/scripting.c | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/core/scripting.c b/src/core/scripting.c index a67297598..ba0549dae 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -399,6 +400,7 @@ static int _mScriptCoreLoadStateFile(struct mCore* core, const char* path, int f vf->close(vf); return ok; } + static void _mScriptCoreTakeScreenshot(struct mCore* core, const char* filename) { if (filename) { struct VFile* vf = VFileOpen(filename, O_WRONLY | O_CREAT | O_TRUNC); @@ -412,6 +414,29 @@ static void _mScriptCoreTakeScreenshot(struct mCore* core, const char* filename) } } +static struct mScriptValue* _mScriptCoreTakeScreenshotToImage(struct mCore* core) { + size_t stride; + const void* pixels = 0; + unsigned width, height; + core->currentVideoSize(core, &width, &height); + core->getPixels(core, &pixels, &stride); + if (!pixels) { + return NULL; + } +#ifndef COLOR_16_BIT + struct mImage* image = mImageCreateFromConstBuffer(width, height, stride, mCOLOR_XBGR8, pixels); +#elif COLOR_5_6_5 + struct mImage* image = mImageCreateFromConstBuffer(width, height, stride, mCOLOR_RGB565, pixels); +#else + struct mImage* image = mImageCreateFromConstBuffer(width, height, stride, mCOLOR_BGR5, pixels); +#endif + + struct mScriptValue* result = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mImage)); + result->value.opaque = image; + result->flags = mSCRIPT_VALUE_FLAG_DEINIT; + return result; +} + // Loading functions mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadFile, mCoreLoadFile, 1, CHARP, path); mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, autoloadSave, mCoreAutoloadSave, 0); @@ -464,6 +489,7 @@ mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateFile, _mScript // Miscellaneous functions mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(mCore, screenshot, _mScriptCoreTakeScreenshot, 1, CHARP, filename); +mSCRIPT_DECLARE_STRUCT_METHOD(mCore, W(mImage), screenshotToImage, _mScriptCoreTakeScreenshotToImage, 0); mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_CLASS_DOCSTRING( @@ -549,8 +575,10 @@ mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_DOCSTRING("Load state from the given path. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateFile) - mSCRIPT_DEFINE_DOCSTRING("Save a screenshot") + mSCRIPT_DEFINE_DOCSTRING("Save a screenshot to a file") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, screenshot) + mSCRIPT_DEFINE_DOCSTRING("Get a screenshot in an struct::mImage") + mSCRIPT_DEFINE_STRUCT_METHOD(mCore, screenshotToImage) mSCRIPT_DEFINE_END; mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mCore, checksum) diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index b9cfa03e8..4ed2c2abd 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -310,6 +310,24 @@ M_TEST_DEFINE(logging) { mScriptContextDeinit(&context); } +M_TEST_DEFINE(screenshot) { + SETUP_LUA; + CREATE_CORE; + color_t* buffer = malloc(240 * 160 * sizeof(color_t)); + core->setVideoBuffer(core, buffer, 240); + core->reset(core); + core->runFrame(core); + + TEST_PROGRAM("im = emu:screenshotToImage()"); + TEST_PROGRAM("assert(im)"); + TEST_PROGRAM("assert(im.width >= 160)"); + TEST_PROGRAM("assert(im.height >= 144)"); + + TEARDOWN_CORE; + free(buffer); + mScriptContextDeinit(&context); +} + M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, cmocka_unit_test(globals), cmocka_unit_test(infoFuncs), @@ -318,4 +336,5 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, cmocka_unit_test(memoryRead), cmocka_unit_test(memoryWrite), cmocka_unit_test(logging), + cmocka_unit_test(screenshot), )