mirror of https://github.com/mgba-emu/mgba.git
Scripting: Export current image API
This commit is contained in:
parent
ed69b9f741
commit
2fca2f4395
|
@ -11,8 +11,12 @@
|
|||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/script/macros.h>
|
||||
#include <mgba-util/image.h>
|
||||
|
||||
mSCRIPT_DECLARE_STRUCT(mImage)
|
||||
|
||||
struct mScriptContext;
|
||||
void mScriptContextAttachImage(struct mScriptContext* context);
|
||||
void mScriptContextAttachStdlib(struct mScriptContext* context);
|
||||
void mScriptContextAttachSocket(struct mScriptContext* context);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ include(ExportDirectory)
|
|||
set(SOURCE_FILES
|
||||
context.c
|
||||
input.c
|
||||
image.c
|
||||
socket.c
|
||||
stdlib.c
|
||||
types.c)
|
||||
|
@ -18,6 +19,7 @@ if(USE_LUA)
|
|||
list(APPEND SOURCE_FILES engines/lua.c)
|
||||
list(APPEND TEST_FILES
|
||||
test/context.c
|
||||
test/image.c
|
||||
test/input.c
|
||||
test/lua.c
|
||||
test/stdlib.c)
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
#include <mgba/core/scripting.h>
|
||||
#include <mgba/core/version.h>
|
||||
#include <mgba/internal/script/types.h>
|
||||
#include <mgba/script/base.h>
|
||||
#include <mgba/script/context.h>
|
||||
#include <mgba/script/input.h>
|
||||
#include <mgba/script/storage.h>
|
||||
#include <mgba/script.h>
|
||||
#include <mgba-util/string.h>
|
||||
|
||||
struct mScriptContext context;
|
||||
|
@ -473,9 +470,10 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
mScriptContextInit(&context);
|
||||
mScriptContextAttachStdlib(&context);
|
||||
mScriptContextAttachImage(&context);
|
||||
mScriptContextAttachInput(&context);
|
||||
mScriptContextAttachSocket(&context);
|
||||
mScriptContextAttachStorage(&context);
|
||||
mScriptContextAttachInput(&context);
|
||||
mScriptContextSetTextBufferFactory(&context, NULL, NULL);
|
||||
|
||||
initTypes();
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/script.h>
|
||||
|
||||
static struct mScriptValue* _mImageNew(unsigned width, unsigned height) {
|
||||
// For various reasons, it's probably a good idea to limit the maximum image size scripts can make
|
||||
if (width >= 10000 || height >= 10000) {
|
||||
return NULL;
|
||||
}
|
||||
struct mImage* image = mImageCreate(width, height, mCOLOR_ABGR8);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
struct mScriptValue* result = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mImage));
|
||||
result->value.opaque = image;
|
||||
result->flags = mSCRIPT_VALUE_FLAG_DEINIT;
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct mScriptValue* _mImageLoad(const char* path) {
|
||||
struct mImage* image = mImageLoad(path);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
struct mScriptValue* result = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mImage));
|
||||
result->value.opaque = image;
|
||||
result->flags = mSCRIPT_VALUE_FLAG_DEINIT;
|
||||
return result;
|
||||
}
|
||||
|
||||
mSCRIPT_DECLARE_STRUCT_C_METHOD(mImage, U32, getPixel, mImageGetPixel, 2, U32, x, U32, y);
|
||||
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, setPixel, mImageSetPixel, 3, U32, x, U32, y, U32, color);
|
||||
mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(mImage, BOOL, save, mImageSave, 2, CHARP, path, CHARP, format);
|
||||
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, _deinit, mImageDestroy, 0);
|
||||
|
||||
mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, save)
|
||||
mSCRIPT_NO_DEFAULT,
|
||||
mSCRIPT_CHARP("PNG")
|
||||
mSCRIPT_DEFINE_DEFAULTS_END;
|
||||
|
||||
mSCRIPT_DEFINE_STRUCT(mImage)
|
||||
mSCRIPT_DEFINE_CLASS_DOCSTRING(
|
||||
"A single, static image."
|
||||
)
|
||||
mSCRIPT_DEFINE_STRUCT_DEINIT(mImage)
|
||||
mSCRIPT_DEFINE_DOCSTRING("Save the image to a file. Currently, only `PNG` format is supported")
|
||||
mSCRIPT_DEFINE_STRUCT_METHOD(mImage, save)
|
||||
mSCRIPT_DEFINE_DOCSTRING("Get the ARGB value of the pixel at a given coordinate")
|
||||
mSCRIPT_DEFINE_STRUCT_METHOD(mImage, getPixel)
|
||||
mSCRIPT_DEFINE_DOCSTRING("Set the ARGB value of the pixel at a given coordinate")
|
||||
mSCRIPT_DEFINE_STRUCT_METHOD(mImage, setPixel)
|
||||
mSCRIPT_DEFINE_DOCSTRING("The width of the image, in pixels")
|
||||
mSCRIPT_DEFINE_STRUCT_CONST_MEMBER(mImage, U32, width)
|
||||
mSCRIPT_DEFINE_DOCSTRING("The height of the image, in pixels")
|
||||
mSCRIPT_DEFINE_STRUCT_CONST_MEMBER(mImage, U32, height)
|
||||
mSCRIPT_DEFINE_END;
|
||||
|
||||
mSCRIPT_BIND_FUNCTION(mImageNew_Binding, W(mImage), _mImageNew, 2, U32, width, U32, height);
|
||||
mSCRIPT_BIND_FUNCTION(mImageLoad_Binding, W(mImage), _mImageLoad, 1, CHARP, path);
|
||||
|
||||
void mScriptContextAttachImage(struct mScriptContext* context) {
|
||||
mScriptContextExportNamespace(context, "image", (struct mScriptKVPair[]) {
|
||||
mSCRIPT_KV_PAIR(new, &mImageNew_Binding),
|
||||
mSCRIPT_KV_PAIR(load, &mImageLoad_Binding),
|
||||
mSCRIPT_KV_SENTINEL
|
||||
});
|
||||
mScriptContextSetDocstring(context, "image", "Methods for creating struct::mImage instances");
|
||||
mScriptContextSetDocstring(context, "image.new", "Create a new image with the given dimensions");
|
||||
mScriptContextSetDocstring(context, "image.load", "Load an image from a path. Currently, only `PNG` format is supported");
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "util/test/suite.h"
|
||||
|
||||
#include <mgba/internal/script/lua.h>
|
||||
#include <mgba/script.h>
|
||||
|
||||
#include "script/test.h"
|
||||
|
||||
#define SETUP_LUA \
|
||||
struct mScriptContext context; \
|
||||
mScriptContextInit(&context); \
|
||||
struct mScriptEngineContext* lua = mScriptContextRegisterEngine(&context, mSCRIPT_ENGINE_LUA); \
|
||||
mScriptContextAttachStdlib(&context); \
|
||||
mScriptContextAttachImage(&context)
|
||||
|
||||
M_TEST_SUITE_SETUP(mScriptImage) {
|
||||
if (mSCRIPT_ENGINE_LUA->init) {
|
||||
mSCRIPT_ENGINE_LUA->init(mSCRIPT_ENGINE_LUA);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
M_TEST_SUITE_TEARDOWN(mScriptImage) {
|
||||
if (mSCRIPT_ENGINE_LUA->deinit) {
|
||||
mSCRIPT_ENGINE_LUA->deinit(mSCRIPT_ENGINE_LUA);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(members) {
|
||||
SETUP_LUA;
|
||||
|
||||
TEST_PROGRAM("assert(image)");
|
||||
TEST_PROGRAM("assert(image.new)");
|
||||
TEST_PROGRAM("assert(image.load)");
|
||||
TEST_PROGRAM("im = image.new(1, 1)");
|
||||
TEST_PROGRAM("assert(im)");
|
||||
TEST_PROGRAM("assert(im.width == 1)");
|
||||
TEST_PROGRAM("assert(im.height == 1)");
|
||||
TEST_PROGRAM("assert(im.save)");
|
||||
TEST_PROGRAM("assert(im.save)");
|
||||
TEST_PROGRAM("assert(im.getPixel)");
|
||||
TEST_PROGRAM("assert(im.setPixel)");
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(zeroDim) {
|
||||
SETUP_LUA;
|
||||
|
||||
TEST_PROGRAM("im = image.new(0, 0)");
|
||||
TEST_PROGRAM("assert(not im)");
|
||||
TEST_PROGRAM("im = image.new(1, 0)");
|
||||
TEST_PROGRAM("assert(not im)");
|
||||
TEST_PROGRAM("im = image.new(0, 1)");
|
||||
TEST_PROGRAM("assert(not im)");
|
||||
TEST_PROGRAM("im = image.new(1, 1)");
|
||||
TEST_PROGRAM("assert(im)");
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(pixelColorDefault) {
|
||||
SETUP_LUA;
|
||||
|
||||
TEST_PROGRAM("im = image.new(1, 1)");
|
||||
TEST_PROGRAM("assert(im:getPixel(0, 0) == 0)");
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(pixelColorRoundTrip) {
|
||||
SETUP_LUA;
|
||||
|
||||
TEST_PROGRAM("im = image.new(1, 1)");
|
||||
TEST_PROGRAM("im:setPixel(0, 0, 0xFF123456)");
|
||||
TEST_PROGRAM("assert(im:getPixel(0, 0) == 0xFF123456)");
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
#ifdef USE_PNG
|
||||
M_TEST_DEFINE(saveLoadRoundTrip) {
|
||||
SETUP_LUA;
|
||||
|
||||
unlink("tmp.png");
|
||||
TEST_PROGRAM("im = image.new(1, 1)");
|
||||
TEST_PROGRAM("im:setPixel(0, 0, 0xFF123456)");
|
||||
TEST_PROGRAM("assert(im:save('tmp.png'))");
|
||||
TEST_PROGRAM("im = image.load('tmp.png')");
|
||||
TEST_PROGRAM("assert(im)");
|
||||
TEST_PROGRAM("assert(im:getPixel(0, 0) == 0xFF123456)");
|
||||
unlink("tmp.png");
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
#endif
|
||||
|
||||
M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptImage,
|
||||
cmocka_unit_test(members),
|
||||
cmocka_unit_test(zeroDim),
|
||||
cmocka_unit_test(pixelColorDefault),
|
||||
cmocka_unit_test(pixelColorRoundTrip),
|
||||
#ifdef USE_PNG
|
||||
cmocka_unit_test(saveLoadRoundTrip),
|
||||
#endif
|
||||
)
|
Loading…
Reference in New Issue