add sdl cursor support
This commit is contained in:
@@ -59,7 +59,8 @@ var resources = {
|
|||||||
window: {},
|
window: {},
|
||||||
renderer: {},
|
renderer: {},
|
||||||
texture: {},
|
texture: {},
|
||||||
surface: {}
|
surface: {},
|
||||||
|
cursor: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ID counter for resource allocation
|
// ID counter for resource allocation
|
||||||
@@ -93,6 +94,9 @@ $_.receiver(function(msg) {
|
|||||||
case 'surface':
|
case 'surface':
|
||||||
response = handle_surface(msg);
|
response = handle_surface(msg);
|
||||||
break;
|
break;
|
||||||
|
case 'cursor':
|
||||||
|
response = handle_cursor(msg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
response = {error: "Unknown kind: " + msg.kind};
|
response = {error: "Unknown kind: " + msg.kind};
|
||||||
}
|
}
|
||||||
@@ -605,6 +609,39 @@ function handle_surface(msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cursor operations
|
||||||
|
function handle_cursor(msg) {
|
||||||
|
switch (msg.op) {
|
||||||
|
case 'create':
|
||||||
|
var surf = new surface(msg.data)
|
||||||
|
|
||||||
|
var hotspot = msg.data.hotspot || [0, 0];
|
||||||
|
var cursor = prosperon.endowments.createCursor(surf, hotspot);
|
||||||
|
|
||||||
|
var cursor_id = allocate_id();
|
||||||
|
resources.cursor[cursor_id] = cursor;
|
||||||
|
return {id: cursor_id};
|
||||||
|
|
||||||
|
case 'set':
|
||||||
|
var cursor = null;
|
||||||
|
if (msg.id && resources.cursor[msg.id]) {
|
||||||
|
cursor = resources.cursor[msg.id];
|
||||||
|
}
|
||||||
|
prosperon.endowments.setCursor(cursor);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'destroy':
|
||||||
|
if (!msg.id || !resources.cursor[msg.id]) {
|
||||||
|
return {error: "Invalid cursor id: " + msg.id};
|
||||||
|
}
|
||||||
|
delete resources.cursor[msg.id];
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return {error: "Unknown cursor operation: " + msg.op};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Utility function to create window and renderer
|
// Utility function to create window and renderer
|
||||||
prosperon.endowments = prosperon.endowments || {};
|
prosperon.endowments = prosperon.endowments || {};
|
||||||
|
|
||||||
|
|||||||
@@ -429,11 +429,6 @@ graphics.cull_sprites[prosperon.DOC] = `
|
|||||||
Filter an array of sprites to only those visible in the provided camera’s view.
|
Filter an array of sprites to only those visible in the provided camera’s view.
|
||||||
`
|
`
|
||||||
|
|
||||||
graphics.make_cursor[prosperon.DOC] = `
|
|
||||||
:param opts: An object with {surface, hotx, hoty} or similar.
|
|
||||||
:return: An SDL_Cursor object referencing the given surface for a custom mouse cursor.
|
|
||||||
`
|
|
||||||
|
|
||||||
graphics.make_font[prosperon.DOC] = `
|
graphics.make_font[prosperon.DOC] = `
|
||||||
:param data: TTF/OTF file data as an ArrayBuffer.
|
:param data: TTF/OTF file data as an ArrayBuffer.
|
||||||
:param size: Pixel size for rendering glyphs.
|
:param size: Pixel size for rendering glyphs.
|
||||||
|
|||||||
@@ -1199,19 +1199,6 @@ JSC_CCALL(os_make_aseprite,
|
|||||||
cute_aseprite_free(ase);
|
cute_aseprite_free(ase);
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// TODO: Implement this correctly
|
|
||||||
JSC_CCALL(os_make_cursor,
|
|
||||||
/*if (SDL_GetCurrentThreadID() != main_thread)
|
|
||||||
return JS_ThrowInternalError(js, "This can only be called from the root actor.");
|
|
||||||
|
|
||||||
SDL_Surface *s = js2SDL_Surface(js,argv[0]);
|
|
||||||
HMM_Vec2 hot = js2vec2(js,argv[1]);
|
|
||||||
SDL_Cursor *c = SDL_CreateColorCursor(s, hot.x, hot.y);
|
|
||||||
if (!c) return JS_ThrowReferenceError(js,"couldn't make cursor: %s", SDL_GetError());
|
|
||||||
return SDL_Cursor2js(js,c);*/
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(os_make_font,
|
JSC_CCALL(os_make_font,
|
||||||
size_t len;
|
size_t len;
|
||||||
void *data = JS_GetArrayBuffer(js,&len,argv[0]);
|
void *data = JS_GetArrayBuffer(js,&len,argv[0]);
|
||||||
@@ -1501,7 +1488,6 @@ static const JSCFunctionListEntry js_graphics_funcs[] = {
|
|||||||
MIST_FUNC_DEF(os, make_gif, 1),
|
MIST_FUNC_DEF(os, make_gif, 1),
|
||||||
MIST_FUNC_DEF(os, make_aseprite, 1),
|
MIST_FUNC_DEF(os, make_aseprite, 1),
|
||||||
MIST_FUNC_DEF(os, cull_sprites, 2),
|
MIST_FUNC_DEF(os, cull_sprites, 2),
|
||||||
MIST_FUNC_DEF(os, make_cursor, 1),
|
|
||||||
MIST_FUNC_DEF(os, make_font, 2),
|
MIST_FUNC_DEF(os, make_font, 2),
|
||||||
MIST_FUNC_DEF(os, make_line_prim, 5),
|
MIST_FUNC_DEF(os, make_line_prim, 5),
|
||||||
MIST_FUNC_DEF(graphics, hsl_to_rgb, 3),
|
MIST_FUNC_DEF(graphics, hsl_to_rgb, 3),
|
||||||
|
|||||||
@@ -10,17 +10,11 @@ void SDL_Camera_free(JSRuntime *rt, SDL_Camera *cam)
|
|||||||
SDL_CloseCamera(cam);
|
SDL_CloseCamera(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_Cursor_free(JSRuntime *rt, SDL_Cursor *c)
|
|
||||||
{
|
|
||||||
SDL_DestroyCursor(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDL_AudioStream_free(JSRuntime *rt, SDL_AudioStream *st) {
|
void SDL_AudioStream_free(JSRuntime *rt, SDL_AudioStream *st) {
|
||||||
SDL_DestroyAudioStream(st);
|
SDL_DestroyAudioStream(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class definitions for SDL types
|
// Class definitions for SDL types
|
||||||
QJSCLASS(SDL_Cursor,)
|
|
||||||
QJSCLASS(SDL_Camera,)
|
QJSCLASS(SDL_Camera,)
|
||||||
QJSCLASS(SDL_AudioStream,)
|
QJSCLASS(SDL_AudioStream,)
|
||||||
|
|
||||||
@@ -59,12 +53,6 @@ JSC_CCALL(input_mouse_show,
|
|||||||
SDL_HideCursor();
|
SDL_HideCursor();
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(input_cursor_set,
|
|
||||||
SDL_Cursor *c = js2SDL_Cursor(js,argv[0]);
|
|
||||||
if (!SDL_SetCursor(c))
|
|
||||||
return JS_ThrowReferenceError(js, "could not set cursor: %s", SDL_GetError());
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(input_keyname,
|
JSC_CCALL(input_keyname,
|
||||||
return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0])));
|
return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0])));
|
||||||
)
|
)
|
||||||
@@ -97,7 +85,6 @@ JSC_CCALL(input_mousestate,
|
|||||||
static const JSCFunctionListEntry js_input_funcs[] = {
|
static const JSCFunctionListEntry js_input_funcs[] = {
|
||||||
MIST_FUNC_DEF(input, mouse_show, 1),
|
MIST_FUNC_DEF(input, mouse_show, 1),
|
||||||
MIST_FUNC_DEF(input, mouse_lock, 1),
|
MIST_FUNC_DEF(input, mouse_lock, 1),
|
||||||
MIST_FUNC_DEF(input, cursor_set, 1),
|
|
||||||
MIST_FUNC_DEF(input, keyname, 1),
|
MIST_FUNC_DEF(input, keyname, 1),
|
||||||
MIST_FUNC_DEF(input, keymod, 0),
|
MIST_FUNC_DEF(input, keymod, 0),
|
||||||
MIST_FUNC_DEF(input, mousestate, 0),
|
MIST_FUNC_DEF(input, mousestate, 0),
|
||||||
@@ -109,7 +96,6 @@ JSValue js_input_use(JSContext *js) {
|
|||||||
|
|
||||||
// Initialize SDL cursor class (no functions)
|
// Initialize SDL cursor class (no functions)
|
||||||
JSValue c_types = JS_GetPropertyStr(js, JS_GetGlobalObject(js), "c_types");
|
JSValue c_types = JS_GetPropertyStr(js, JS_GetGlobalObject(js), "c_types");
|
||||||
QJSCLASSPREP_NO_FUNCS(SDL_Cursor)
|
|
||||||
JS_FreeValue(js, c_types);
|
JS_FreeValue(js, c_types);
|
||||||
|
|
||||||
return mod;
|
return mod;
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ QJSCLASS(SDL_Texture,
|
|||||||
QJSCLASS(SDL_Renderer,)
|
QJSCLASS(SDL_Renderer,)
|
||||||
QJSCLASS(SDL_Window,)
|
QJSCLASS(SDL_Window,)
|
||||||
|
|
||||||
|
void SDL_Cursor_free(JSRuntime *rt, SDL_Cursor *c)
|
||||||
|
{
|
||||||
|
SDL_DestroyCursor(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJSCLASS(SDL_Cursor,)
|
||||||
|
|
||||||
// External function declarations
|
// External function declarations
|
||||||
extern JSValue rect2js(JSContext *js, rect r);
|
extern JSValue rect2js(JSContext *js, rect r);
|
||||||
extern rect js2rect(JSContext *js, JSValue v);
|
extern rect js2rect(JSContext *js, JSValue v);
|
||||||
@@ -1555,6 +1562,29 @@ static const JSCFunctionListEntry js_sdl_video_funcs[] = {
|
|||||||
JS_PROP_INT32_DEF("BLENDMODE_MUL", SDL_BLENDMODE_MUL, JS_PROP_CONFIGURABLE),
|
JS_PROP_INT32_DEF("BLENDMODE_MUL", SDL_BLENDMODE_MUL, JS_PROP_CONFIGURABLE),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cursor creation function
|
||||||
|
JSC_CCALL(sdl_create_cursor,
|
||||||
|
SDL_Surface *surf = js2SDL_Surface(js, argv[0]);
|
||||||
|
if (!surf) return JS_ThrowReferenceError(js, "Invalid surface");
|
||||||
|
|
||||||
|
HMM_Vec2 hot = {0, 0};
|
||||||
|
if (argc > 1) hot = js2vec2(js, argv[1]);
|
||||||
|
|
||||||
|
SDL_Cursor *cursor = SDL_CreateColorCursor(surf, hot.x, hot.y);
|
||||||
|
if (!cursor) return JS_ThrowReferenceError(js, "Failed to create cursor: %s", SDL_GetError());
|
||||||
|
|
||||||
|
return SDL_Cursor2js(js, cursor);
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set cursor function
|
||||||
|
JSC_CCALL(sdl_set_cursor,
|
||||||
|
SDL_Cursor *cursor = js2SDL_Cursor(js, argv[0]);
|
||||||
|
|
||||||
|
if (!cursor) return JS_ThrowReferenceError(js, "Invalid cursor");
|
||||||
|
|
||||||
|
SDL_SetCursor(cursor);
|
||||||
|
)
|
||||||
|
|
||||||
// Texture getter/setter functions
|
// Texture getter/setter functions
|
||||||
|
|
||||||
// Alpha mod getter/setter
|
// Alpha mod getter/setter
|
||||||
@@ -1759,6 +1789,7 @@ static void video_actor_hook(JSContext *js) {
|
|||||||
QJSCLASSPREP_FUNCS(SDL_Window)
|
QJSCLASSPREP_FUNCS(SDL_Window)
|
||||||
QJSCLASSPREP_FUNCS(SDL_Renderer)
|
QJSCLASSPREP_FUNCS(SDL_Renderer)
|
||||||
QJSCLASSPREP_FUNCS(SDL_Texture)
|
QJSCLASSPREP_FUNCS(SDL_Texture)
|
||||||
|
QJSCLASSPREP_NO_FUNCS(SDL_Cursor)
|
||||||
|
|
||||||
JS_FreeValue(js, c_types);
|
JS_FreeValue(js, c_types);
|
||||||
|
|
||||||
@@ -1789,6 +1820,12 @@ static void video_actor_hook(JSContext *js) {
|
|||||||
JS_SetPropertyStr(js, endowments, "createWindowAndRenderer",
|
JS_SetPropertyStr(js, endowments, "createWindowAndRenderer",
|
||||||
JS_NewCFunction(js, js_sdl_createWindowAndRenderer, "createWindowAndRenderer", 4));
|
JS_NewCFunction(js, js_sdl_createWindowAndRenderer, "createWindowAndRenderer", 4));
|
||||||
|
|
||||||
|
// Add cursor functions
|
||||||
|
JS_SetPropertyStr(js, endowments, "createCursor",
|
||||||
|
JS_NewCFunction(js, js_sdl_create_cursor, "createCursor", 2));
|
||||||
|
JS_SetPropertyStr(js, endowments, "setCursor",
|
||||||
|
JS_NewCFunction(js, js_sdl_set_cursor, "setCursor", 1));
|
||||||
|
|
||||||
JS_FreeValue(js, endowments);
|
JS_FreeValue(js, endowments);
|
||||||
JS_FreeValue(js, prosperon);
|
JS_FreeValue(js, prosperon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,13 +56,11 @@ function start_drawing() {
|
|||||||
var start_time = os.now();
|
var start_time = os.now();
|
||||||
|
|
||||||
// Load an image
|
// Load an image
|
||||||
var bunny_image = null;
|
var bunny_image = graphics.texture('tests/bunny.png')
|
||||||
try {
|
|
||||||
bunny_image = graphics.texture('tests/bunny.png');
|
send(video_actor, {kind: "cursor", op: "create", data: bunny_image.cpu}, ({id}) => {
|
||||||
} catch (e) {
|
send(video_actor, {kind:"cursor", op: "set", id})
|
||||||
console.log("Failed to load bunny image:", e);
|
})
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw_frame() {
|
function draw_frame() {
|
||||||
frame++;
|
frame++;
|
||||||
|
|||||||
Reference in New Issue
Block a user