From 27ce4cd9e24f9cc07fbad7f3076c1fab827f20b7 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Fri, 13 Dec 2024 14:35:46 -0600 Subject: [PATCH] windows build --- meson.build | 17 +++-- mingw32.cross | 3 +- scripts/debug.js | 9 +++ scripts/engine.js | 17 +++-- scripts/prosperon.js | 145 ++++++++++++++++++++--------------------- scripts/render.js | 60 +++++++++-------- scripts/sound.js | 3 +- scripts/std.js | 21 ------ source/cute_aseprite.h | 59 ++++++++++++++--- source/cv.cpp | 108 ------------------------------ source/cv.hpp | 15 ----- source/jsffi.c | 65 ++++++++++++------ 12 files changed, 230 insertions(+), 292 deletions(-) delete mode 100644 source/cv.cpp delete mode 100644 source/cv.hpp diff --git a/meson.build b/meson.build index c4441a1a..f64a2659 100644 --- a/meson.build +++ b/meson.build @@ -12,6 +12,8 @@ endif add_project_arguments('-Wno-incompatible-pointer-types', language: 'c') add_project_arguments('-Wno-narrowing', language: 'cpp') add_project_arguments('-Wno-missing-braces', language:'c') +add_project_arguments('-Wl,--disable-new-dtags', language:'cpp') +add_project_arguments('-Wl,--disable-new-dtags', language:'c') deps = [] @@ -24,14 +26,12 @@ if host_machine.system() == 'darwin' endif cc = meson.get_compiler('c') - deps += dependency('sdl3') +deps += dependency('sdl3') + if host_machine.system() == 'darwin' deps += dependency('appleframeworks', modules: 'accelerate') add_project_arguments('-DACCELERATE_NEW_LAPACK=1', language:'c') add_project_arguments('-DACCELERATE_LAPACK_ILP64=1', language:'c') -else - deps += dependency('cblas') - endif if host_machine.system() == 'linux' @@ -43,7 +43,7 @@ endif if host_machine.system() == 'windows' deps += cc.find_library('d3d11') # these are for tracy - deps += cc.find_library('ws2_32') + deps += cc.find_library('ws2_32', required:true) deps += cc.find_library('dbghelp') #end link += '-static' # Required to pack in mingw dlls on cross compilation @@ -74,10 +74,9 @@ deps += dependency('qjs-nota',static:true) deps += dependency('qjs-miniz',static:true) deps += dependency('qjs-soloud',static:true) -deps += dependency('physfs',static:true) +deps += dependency('physfs') - -deps += dependency('opencv4') +#deps += dependency('opencv4') #deps += cc.find_library('opencv') deps += dependency('threads') @@ -91,7 +90,7 @@ if get_option('enet') endif sources = [] -src += ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c', 'timer.c', 'transform.c','warp.c','yugine.c', 'wildmatch.c', 'cv.cpp'] +src += ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c', 'timer.c', 'transform.c','warp.c','yugine.c', 'wildmatch.c'] imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp', 'imgui_impl_sdlrenderer3.cpp', 'imgui_impl_sdl3.cpp'] diff --git a/mingw32.cross b/mingw32.cross index 68686a7e..265af500 100644 --- a/mingw32.cross +++ b/mingw32.cross @@ -14,6 +14,5 @@ cpu = 'x86_64' endian = 'little' [properties] -link_args = ['-static'] needs_exe_wrapper = false -pkg_config_libdir = '/usr/local/lib64/pkgconfig' + diff --git a/scripts/debug.js b/scripts/debug.js index 4615360f..5b36ff29 100644 --- a/scripts/debug.js +++ b/scripts/debug.js @@ -258,6 +258,15 @@ debug.break_var = function(obj,vars) }); } +debug.try = function(fn) +{ + try { + fn(); + } catch(e) { + console.error(e) + } +} + return { debug, Gizmos, diff --git a/scripts/engine.js b/scripts/engine.js index b0f2a0fd..11c7b0bb 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -151,6 +151,12 @@ Resources.is_image = function (path) { return Resources.images.some(x => x === ext); }; +Resources.shaders = ["hlsl", "glsl", "cg"] +Resources.is_shader = function(path) { + var ext = path.ext(); + return Resources.shaders.some(x => x === ext) +} + var res_cache = {}; // ext is a list of extensions to search @@ -268,11 +274,14 @@ console.info = function info(msg) { console.warn = function warn(msg) { console.pprint(msg, 3); }; -console.error = function error (msg) { - console.pprint(msg + "\n" + console.stackstr(2), 4); +console.error = function error (e) { + console.log(e); + console.log(e.stack); }; -console.panic = function (msg) { - console.pprint(msg + "\n" + console.stackstr(2), 5); +console.panic = function (e) { + console.log("PANIC!") + console.error(e); + os.quit(); }; console.stackstr = function (skip = 0) { var err = new Error(); diff --git a/scripts/prosperon.js b/scripts/prosperon.js index 2fcd04e6..7d5d7dd6 100644 --- a/scripts/prosperon.js +++ b/scripts/prosperon.js @@ -169,42 +169,75 @@ function calc_image_size(img) return [img.texture.width*img.rect.width, img.texture.height*img.rect.height]; } +function create_image(path) +{ + var data = io.slurpbytes(path); + var newimg; + switch(path.ext()) { + case 'gif': + newimg = os.make_gif(data); + if (newimg.surface) { + newimg.texture = render._main.load_texture(newimg.surface); + newimg.texture.mode(0); + } + else + for (var frame of newimg.frames) { + frame.texture = render._main.load_texture(frame.surface); + frame.texture.mode(0); + } + break; + case 'ase': + case 'aseprite': + console.log(`loading aseprite file ${path}`) + console.log(`buffer size is ${data.byteLength}`) + newimg = os.make_aseprite(data); + if (newimg.surface) { + newimg.texture = render._main.load_texture(newimg.surface); + newimg.texture.mode(0); + } else { + for (var anim in newimg) { + var a = newimg[anim]; + for (var frame of a.frames) { + frame.texture = render._main.load_texture(frame.surface); + frame.texture.mode(0) + } + } + } + break; + default: + newimg = { + surface: os.make_texture(data) + }; + newimg.texture = render._main.load_texture(newimg.surface); + newimg.texture.mode(0); + break; + } + return newimg; +} + +function merge_objects(oldobj,newobj, properties) { + function recursive_merge(target,src) { + for (var key of Object.keys(src)) { + if (properties.includes(key)) { + target[key] = src[key]; + continue; + } + if (src[key] && typeof src[key] === 'object' && target[key] && typeof target[key] === 'object') + recursive_merge(target[key],src[key]) + } + } + recursive_merge(oldobj,newobj); +} + game.tex_hotreload = function tex_hotreload(file) { if (!(file in game.texture.cache)) return; - var data = io.slurpbytes(file); - var tex; - if (file.endsWith('.gif')) { - var anim = os.make_gif(data); - if (anim.frames.length !== 1) return; - console.info(json.encode(anim)); - tex = anim.frames[0].texture; - } else if (file.endsWith('.ase') || file.endsWith('.aseprite')) { - var anim = os.make_aseprite(data); - if (anim.texture) // single picture - tex = anim.texture; - else { - var oldanim = game.texture.cache[file]; - // load all into gpu - for (var a in anim) { - oldanim[a] = anim[a]; - for (let frame of anim[a].frames) - frame.texture.load_gpu(); - } - return; - } - } else - tex = os.make_texture(data); - - var img = game.texture.cache[file]; - tex.load_gpu(); - console.info(`replacing ${json.encode(img)}`) - img.texture = tex; - img.rect = { - x:0, - y:0, - width:1, - height:1 - }; + + var img = create_image(file); + var oldimg = game.texture.cache[file]; + console.log(json.encode(img)) + + merge_objects(oldimg,img, ['surface', 'texture', 'loop', 'time']); + game.texture.cache[file] = img; }; var image = {}; @@ -264,48 +297,8 @@ game.texture = function texture(path) { var parts = path.split(':'); path = Resources.find_image(parts[0]); - if (game.texture.cache[path]) return game.texture.cache[path]; - var data = io.slurpbytes(path); - var newimg; - switch(path.ext()) { - case 'gif': - newimg = os.make_gif(data); - if (newimg.surface) { - newimg.texture = render._main.load_texture(newimg.surface); - newimg.texture.mode(0); - } - else - for (var frame of newimg.frames) { - frame.texture = render._main.load_texture(frame.surface); - frame.texture.mode(0); - } - break; - case 'ase': - case 'aseprite': - newimg = os.make_aseprite(data); - if (newimg.surface) { - newimg.texture = render._main.load_texture(newimg.surface); - newimg.texture.mode(0); - } else { - for (var anim in newimg) { - var a = newimg[anim]; - for (var frame of a.frames) { - frame.texture = render._main.load_texture(frame.surface); - frame.texture.mode(0) - } - } - } - break; - default: - newimg = { - surface: os.make_texture(data) - }; - newimg.texture = render._main.load_texture(newimg.surface); - newimg.texture.mode(0); - break; - } - game.texture.cache[path] = newimg; - return newimg; + game.texture.cache[path] ??= create_image(path); + return game.texture.cache[path]; // Look for a cached version var frame; diff --git a/scripts/render.js b/scripts/render.js index 1a95d47c..222450af 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -1053,7 +1053,7 @@ render.tile = function tile(image, rect = [0,0], color = Color.white) return; } -render.geometry = function(material, geometry) +render.geometry = function geometry(material, geometry) { render._main.geometry(material.diffuse.texture, geometry); } @@ -1395,20 +1395,27 @@ var imgui_fn = function imgui_fn() { prosperon.menu_hook?.(); }); +/* if (observed_tex) { imgui.window("texture", _ => { - imgui.image(observed_tex.texture); + imgui.image(observed_tex); }); } + var texs = {}; + for (var path in game.texture.cache) { + var image = game.texture.cache[path]; + if (image.texture && !texs[image.texture]) + texs[image.texture] = image.texture; + } imgui.window("textures", _ => { - for (var img in game.texture.cache) { + for (var img in texs) { imgui.button(img, _ => { - observed_tex = game.texture.cache[img]; + observed_tex = texs[img]; }); } }); - +*/ prosperon.imgui(); imgui.endframe(render._main); }; @@ -1433,17 +1440,15 @@ var present_thread = undefined; var clearcolor = [100,149,237,255].scale(1/255); prosperon.render = function prosperon_render() { try{ - render._main.draw_color(clearcolor); render._main.clear(); - // render each camera - prosperon.camera.render(); -// prosperon.app(); - if (debug.show) imgui_fn(); + +try { prosperon.camera.render(); } catch(e) { console.error(e) } +try { prosperon.app(); } catch(e) { console.error(e) } +if (debug.show) try { imgui_fn(); } catch(e) { console.error(e) } + } catch(e) { - console.log(e); - console.log(e.stack) -// throw e; + console.error(e) } finally { if (present_thread) present_thread.wait(); present_thread = render._main.present(); @@ -1455,38 +1460,40 @@ if (dmon) dmon.watch('.'); function dmon_cb(e) { - io.invalidated(); - +try { + io.invalidate(); if (e.file.startsWith('.')) return; if (e.file.endsWith('.js')) actor.hotreload(e.file); else if (Resources.is_image(e.file)) game.tex_hotreload(e.file); - else if (e.file.endsWith('.cg')) // shader - render.hotreload(e.file); +} catch(e) { console.error(e); } } // Ran once per frame prosperon.process = function process() { +try { layout.newframe(); // check for hot reloading if (dmon) dmon.poll(dmon_cb); var dt = profile.now() - frame_t; frame_t = profile.now(); - prosperon.appupdate(dt); - - input.procdown(); - game.engine_input(e => { prosperon[e.type]?.(e); }); - + +try { prosperon.appupdate(dt); } catch(e) { console.error(e) } + + input.procdown(); + +try { update_emitters(dt * game.timescale); os.update_timers(dt * game.timescale); - prosperon.update(dt*game.timescale); - if (sim.mode === "step") sim.pause(); + prosperon.update(dt*game.timescale); +} catch(e) { console.error(e) } + if (sim.mode === "step") sim.pause(); if (sim.mode === "play" || sim.mode === "step") { /* physlag += dt; @@ -1501,8 +1508,9 @@ prosperon.process = function process() { prosperon.render(); // tracy.gpu_zone(prosperon.render); +} catch(e) { + console.error(e) +} }; - - return { render }; diff --git a/scripts/sound.js b/scripts/sound.js index b83de007..520b64b5 100644 --- a/scripts/sound.js +++ b/scripts/sound.js @@ -1,7 +1,6 @@ -/* This file runs after the audio system is initiated */ +soloud.init(); var audio = {}; -soloud.init(); var pcms = {}; audio.pcm = function pcm(file) diff --git a/scripts/std.js b/scripts/std.js index 19172d67..e91f2f24 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -232,27 +232,6 @@ Cmdline.register_order( prosperon.width = 1280; prosperon.height = 720; prosperon.size = [1280, 720]; - prosperon.cleanup = function(){} - prosperon.event = function(e){ - console.log(json.encode(e)) - prosperon[e.type]?.(e); - switch(e.type) { - case "key_down": - prosperon.keydown(e.key_code, e.key_repeat); - break; - case "key_up": - prosperon.keyup(e.key_code); - break; - case "quit_requested": - os.exit(0); - break; - case "files_dropped": - console.log(json.encode(e)); - break; - } - } - - prosperon.frame = prosperon.process; prosperon.icon = os.make_texture(io.slurpbytes('core/icons/moon.gif')); prosperon.high_dpi = 0; prosperon.alpha = 1; diff --git a/source/cute_aseprite.h b/source/cute_aseprite.h index 216f3808..63ca7cae 100644 --- a/source/cute_aseprite.h +++ b/source/cute_aseprite.h @@ -306,12 +306,32 @@ struct ase_t void* mem_ctx; }; +#define ASEPRITE_ERROR_MAX 256 +static char aseprite_error[ASEPRITE_ERROR_MAX] = {0}; + +static const char *aseprite_GetError() { + return aseprite_error; +} + +static void aseprite_clear_error() { + aseprite_error[0] = 0; +} + +static void aseprite_set_error(const char *msg) { + if (msg) { + strncpy(aseprite_error, msg, ASEPRITE_ERROR_MAX-1); + aseprite_error[ASEPRITE_ERROR_MAX-1] = 0; + } else + aseprite_error[0] = 0; +} + #endif // CUTE_ASEPRITE_H #ifdef CUTE_ASEPRITE_IMPLEMENTATION #ifndef CUTE_ASEPRITE_IMPLEMENTATION_ONCE #define CUTE_ASEPRITE_IMPLEMENTATION_ONCE + #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif @@ -925,9 +945,12 @@ static ase_color_t s_color(ase_t* ase, void* src, int index) ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ctx) { - ase_t* ase = (ase_t*)CUTE_ASEPRITE_ALLOC(sizeof(ase_t), mem_ctx); - CUTE_ASEPRITE_MEMSET(ase, 0, sizeof(*ase)); - + aseprite_clear_error(); + if (!memory || size < 6) { + aseprite_set_error("Invalid memory buffer or size too small."); + return NULL; + } + ase_state_t state = { 0, 0, 0 }; ase_state_t* s = &state; s->in = (uint8_t*)memory; @@ -936,7 +959,19 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct s_skip(s, sizeof(uint32_t)); // File size. int magic = (int)s_read_uint16(s); - CUTE_ASEPRITE_ASSERT(magic == 0xA5E0); + if (magic != 0xA5E0) { + aseprite_set_error("Incorrect magic number. Not a valid Aseprite file."); + return NULL; + } + + #define LOAD_ERROR(msg) { aseprite_set_error(msg); cute_aseprite_free(ase); return NULL; } + + ase_t* ase = (ase_t*)CUTE_ASEPRITE_ALLOC(sizeof(ase_t), mem_ctx); + if (!ase) { + aseprite_set_error("Failed to allocate memory for aseprite import."); + return NULL; + } + CUTE_ASEPRITE_MEMSET(ase, 0, sizeof(*ase)); ase->frame_count = (int)s_read_uint16(s); ase->w = s_read_uint16(s); @@ -944,10 +979,11 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct uint16_t bpp = s_read_uint16(s) / 8; if (bpp == 4) ase->mode = ASE_MODE_RGBA; else if (bpp == 2) ase->mode = ASE_MODE_GRAYSCALE; - else { - CUTE_ASEPRITE_ASSERT(bpp == 1); - ase->mode = ASE_MODE_INDEXED; - } + else if (bpp == 1) + ase->mode = ASE_MODE_INDEXED; + else + LOAD_ERROR("Unsupported bits per pixel."); + uint32_t valid_layer_opacity = s_read_uint32(s) & 1; int speed = s_read_uint16(s); s_skip(s, sizeof(uint32_t) * 2); // Spec says skip these bytes, as they're zero'd. @@ -963,6 +999,9 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct s_skip(s, 84); // For future use (set to zero). ase->frames = (ase_frame_t*)CUTE_ASEPRITE_ALLOC((int)(sizeof(ase_frame_t)) * ase->frame_count, mem_ctx); + if (!ase->frames) + LOAD_ERROR("Failed to allocate memory for frames."); + CUTE_ASEPRITE_MEMSET(ase->frames, 0, sizeof(ase_frame_t) * (size_t)ase->frame_count); ase_udata_t* last_udata = NULL; @@ -977,7 +1016,9 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct frame->ase = ase; s_skip(s, sizeof(uint32_t)); // Frame size. magic = (int)s_read_uint16(s); - CUTE_ASEPRITE_ASSERT(magic == 0xF1FA); + if (magic != 0xF1FA) + LOAD_ERROR("Frame is not an aseprite magic number."); + int chunk_count = (int)s_read_uint16(s); frame->duration_milliseconds = s_read_uint16(s); if (frame->duration_milliseconds == 0) frame->duration_milliseconds = speed; diff --git a/source/cv.cpp b/source/cv.cpp deleted file mode 100644 index e0a505cd..00000000 --- a/source/cv.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "cv.hpp" -#include -#include -#include -#include -cv::Mat SDL_SurfaceToMat(SDL_Surface* surface) { - if (!surface) { - throw std::invalid_argument("SDL_Surface pointer is null."); - } - - // Convert the surface to a known pixel format (e.g., RGBA32) - SDL_Surface* convertedSurface = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32); - if (!convertedSurface) { - throw std::runtime_error("Failed to convert SDL_Surface to RGBA32 format."); - } - - // Create a cv::Mat with the same size and type - cv::Mat mat(convertedSurface->h, convertedSurface->w, CV_8UC4, convertedSurface->pixels, convertedSurface->pitch); - - // Convert RGBA to BGR - cv::Mat matBGR; - cv::cvtColor(mat, matBGR, cv::COLOR_RGBA2BGR); - - // Free the converted surface - SDL_DestroySurface(convertedSurface); - - return matBGR; -} - -cv::Mat SDL_SurfaceToMat_YUY2(SDL_Surface* surface) { - if (!surface) { - throw std::invalid_argument("SDL_Surface pointer is null."); - } - - // Ensure the surface format is YUY2 - if (surface->format!= SDL_PIXELFORMAT_YUY2) { - throw std::runtime_error("SDL_Surface is not in YUY2 format."); - } - - // Create a cv::Mat with the raw data from the SDL_Surface - // YUY2 format has 2 bytes per pixel - cv::Mat yuy2Mat(surface->h, surface->w, CV_8UC2, surface->pixels, surface->pitch); - - // Convert YUY2 to BGR format - cv::Mat bgrMat; - cv::cvtColor(yuy2Mat, bgrMat, cv::COLOR_YUV2BGR_YUY2); - - return bgrMat; -} - - - -// Function to perform feature matching - -extern "C" { - int detectImageInWebcam(SDL_Surface* webcamSurface, SDL_Surface* targetSurface) { - // Convert SDL_Surface to cv::Mat - cv::Mat webcamMat = SDL_SurfaceToMat(webcamSurface); - cv::Mat targetMat = SDL_SurfaceToMat(targetSurface); - - // Initialize ORB detector - cv::Ptr orb = cv::ORB::create(); - - // Detect keypoints and compute descriptors - std::vector keypointsWebcam, keypointsTarget; - cv::Mat descriptorsWebcam, descriptorsTarget; - - orb->detectAndCompute(webcamMat, cv::noArray(), keypointsWebcam, descriptorsWebcam); - orb->detectAndCompute(targetMat, cv::noArray(), keypointsTarget, descriptorsTarget); - - // Check if descriptors are found - if (descriptorsWebcam.empty() || descriptorsTarget.empty()) { - fprintf(stderr, "No descriptors found. On webcam? %d. On input image? %d.\n", - !descriptorsWebcam.empty(), !descriptorsTarget.empty()); - return NULL; - } - - // Initialize BFMatcher without crossCheck - cv::BFMatcher matcher(cv::NORM_HAMMING); - - // Perform k-NN matching with k=2 - std::vector> matches; - matcher.knnMatch(descriptorsTarget, descriptorsWebcam, matches, 2); - - // Check if any matches are found - if (matches.empty()) { - return NULL; - } - - // Apply Lowe's ratio test to filter good matches - const float ratioThresh = 0.75f; - std::vector goodMatches; - for (size_t i = 0; i < matches.size(); i++) { - if (matches[i].size() < 2) - continue; // Not enough matches - const cv::DMatch& bestMatch = matches[i][0]; - const cv::DMatch& betterMatch = matches[i][1]; - - float ratio = bestMatch.distance / betterMatch.distance; - if (ratio < ratioThresh) { - goodMatches.push_back(bestMatch); - } - } - - // Determine if enough good matches are found - return goodMatches.size(); - } -} diff --git a/source/cv.hpp b/source/cv.hpp deleted file mode 100644 index 1e69b391..00000000 --- a/source/cv.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef CV_H -#define CV_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - int detectImageInWebcam(SDL_Surface *webcam, SDL_Surface *img); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/jsffi.c b/source/jsffi.c index f87d1e7f..65c4419f 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -32,12 +32,10 @@ #include #include -#include - #ifdef __APPLE__ #include -#else -#include +//#else +//#include #endif static JSAtom width_atom; @@ -244,10 +242,6 @@ void SDL_Renderer_free(JSRuntime *rt, SDL_Renderer *r) SDL_DestroyRenderer(r); } -void SDL_Texture_free(JSRuntime *rt, SDL_Texture *t){ - TracyCFreeN(t, "vram"); - SDL_DestroyTexture(t); -} void SDL_Surface_free(JSRuntime *rt, SDL_Surface *s) { if (s->flags & SDL_SURFACE_PREALLOCATED) free(s->pixels); @@ -298,11 +292,18 @@ QJSCLASS(skin) QJSCLASS(SDL_Window) QJSCLASS(SDL_Renderer) QJSCLASS(SDL_Camera) + +void SDL_Texture_free(JSRuntime *rt, SDL_Texture *t){ + TracyCFreeN(t, "vram"); + SDL_DestroyTexture(t); +} + QJSCLASS(SDL_Texture, TracyCAllocN(n, n->w*n->h*4, "vram"); JS_SetProperty(js, j, width_atom, number2js(js,n->w)); JS_SetProperty(js,j,height_atom,number2js(js,n->h)); ) + QJSCLASS(SDL_Surface, TracyCAllocN(n, n->pitch*n->h, "texture memory"); JS_SetProperty(js, j, width_atom, number2js(js,n->w)); @@ -883,10 +884,10 @@ JSValue js_vector_dot(JSContext *js, JSValue self, int argc, JSValue *argv) { size_t alen, blen; float *a = js2floats(js,argv[0], &alen); float *b = js2floats(js,argv[1], &blen); - JSValue ret = number2js(js, cblas_sdot(alen, a, 1, b,1)); +// JSValue ret = number2js(js, cblas_sdot(alen, a, 1, b,1)); free(a); free(b); - return ret; + return JS_UNDEFINED; }; JSC_CCALL(vector_project, return vec22js(js,HMM_ProjV2(js2vec2(js,argv[0]), js2vec2(js,argv[1])))) @@ -967,10 +968,12 @@ JSC_CCALL(vector_rotate, double angle = js2angle(js, argv[1]); HMM_Vec2 pivot = JS_IsUndefined(argv[2]) ? v2zero : js2vec2(js,argv[2]); // vec = vec - pivot - cblas_saxpy(2, -1.0f, pivot.e, 1, vec.e, 1); +// cblas_saxpy(2, -1.0f, pivot.e, 1, vec.e, 1); + vec = HMM_SubV2(vec,pivot); // Length of the vector (r) - float r = sqrtf(cblas_sdot(2, vec.e, 1, vec.e, 1)); +// float r = sqrtf(cblas_sdot(2, vec.e, 1, vec.e, 1)); + float r = HMM_LenV2(vec); // Update angle angle += atan2f(vec.y, vec.x); @@ -980,7 +983,8 @@ JSC_CCALL(vector_rotate, vec.y = r * sinf(angle); // vec = vec + pivot - cblas_saxpy(2, 1.0f, pivot.e, 1, vec.e, 1); +// cblas_saxpy(2, 1.0f, pivot.e, 1, vec.e, 1); + vec = HMM_AddV2(vec,pivot); // Convert back to JS and return return vec22js(js, vec); @@ -1140,7 +1144,7 @@ JSC_CCALL(vector_fastsum, float sum = 0.0; size_t len; float *a = get_typed_buffer(js, argv[0], &len); - sum = cblas_sasum(len, a,1); +// sum = cblas_sasum(len, a,1); ret = number2js(js,sum); ) @@ -1224,7 +1228,7 @@ JSC_CCALL(vector_float32add, size_t len; float *vec_a = get_typed_buffer(js,self, &len); float *vec_b = get_typed_buffer(js,argv[0], &len); - cblas_saxpy(len,1.0f,vec_b,1,vec_a,1); +// cblas_saxpy(len,1.0f,vec_b,1,vec_a,1); JSValue tstack[3]; tstack[0] = JS_NewArrayBufferCopy(js,vec_a,sizeof(float)*4); tstack[1] = JS_UNDEFINED; @@ -1738,6 +1742,10 @@ static JSValue event2js(JSContext *js, SDL_Event event) JS_SetPropertyStr(js,e,"sensor", number2js(js,event.gsensor.sensor)); JS_SetPropertyStr(js,e,"sensor_timestamp", number2js(js,event.gsensor.sensor_timestamp)); break; + case SDL_EVENT_USER: + JS_SetPropertyStr(js,e,"cb", JS_DupValue(js,*(JSValue*)event.user.data1)); + JS_FreeValue(js,*(JSValue*)event.user.data1); + break; } return e; } @@ -2533,9 +2541,22 @@ JSC_SCALL(prosperon_openurl, ret = JS_ThrowReferenceError(js, "unable to open url %s: %s\n", str, SDL_GetError()); ) +JSC_CCALL(prosperon_push_event, + SDL_UserEvent e; + SDL_zero(e); + e.type = SDL_EVENT_USER; + e.timestamp = SDL_GetTicksNS(); + e.code = 0; + JSValue fn = JS_DupValue(js,argv[0]); + e.data1 = malloc(sizeof(JSValue)); + *(JSValue*)e.data1 = fn; + SDL_PushEvent(&e); +) + static const JSCFunctionListEntry js_prosperon_funcs[] = { MIST_FUNC_DEF(prosperon, guid, 0), MIST_FUNC_DEF(prosperon, openurl, 1), + MIST_FUNC_DEF(prosperon, push_event, 1), }; JSC_CCALL(time_now, @@ -2993,7 +3014,9 @@ JSC_CCALL(geometry_rect_pos, JSC_CCALL(geometry_rect_move, rect r = js2rect(js,argv[0]); HMM_Vec2 move = js2vec2(js,argv[1]); - cblas_saxpy(2, 1.0f, move.e, 1, &r, 1); +// cblas_saxpy(2, 1.0f, move.e, 1, &r, 1); + r.x += move.x; + r.y += move.y; return rect2js(js,r); ) @@ -3294,10 +3317,12 @@ JSValue aseframe2js(JSContext *js, ase_frame_t aframe) JSC_CCALL(os_make_aseprite, size_t rawlen; void *raw = JS_GetArrayBuffer(js,&rawlen,argv[0]); - if (!raw) return JS_ThrowReferenceError(js, "could not load aseprite from supplied array buffer"); ase_t *ase = cute_aseprite_load_from_memory(raw, rawlen, NULL); + if (!ase) + return JS_ThrowReferenceError(js, "could not load aseprite from supplied array buffer: %s", aseprite_GetError()); + int w = ase->w; int h = ase->h; @@ -3700,13 +3725,13 @@ JSC_CCALL(os_make_sprite_mesh, ) int detectImageInWebcam(SDL_Surface *a, SDL_Surface *b); -JSC_CCALL(os_match_img, +/*JSC_CCALL(os_match_img, SDL_Surface *img1 = js2SDL_Surface(js,argv[0]); SDL_Surface *img2 = js2SDL_Surface(js,argv[1]); int n = detectImageInWebcam(img1,img2); return number2js(js,n); ) - +*/ JSC_CCALL(os_sleep, double time = js2number(js,argv[0]); time *= 1000000000.; @@ -3768,7 +3793,7 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, gltf_skin, 1), MIST_FUNC_DEF(os, skin_calculate, 1), MIST_FUNC_DEF(os, kill, 1), - MIST_FUNC_DEF(os, match_img, 2), +// MIST_FUNC_DEF(os, match_img, 2), MIST_FUNC_DEF(os, sleep, 1), };