#include #include #include #include #include #include #ifdef WITH_AUDIO #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WITH_NETWORKING #include #include "httprequest.h" #include "websocket_config.h" #include "socket_bridge.h" #include "socket_v8_bindings.h" #ifdef WITH_UWS #include "uws_websocket_bridge.h" #include "uws_websocket_v8_bindings.h" #else #include "websocket_bridge.h" #include "websocket_v8_bindings.h" #include "websocket.h" #endif #ifdef WITH_BENCHMARK #include "BENCHMARK/websocket_benchmark.h" extern "C" void websocket_run_benchmark(); extern "C" void websocket_run_groupchat_test(int rate, int duration); #endif #endif //#include "socket_connection_test.cpp" #include #include #include #include #include #include #include #ifdef WITH_COMPUTE #include #endif #include #define STB_IMAGE_IMPLEMENTATION #include #ifdef KORE_DIRECT3D11 #include #endif #include #ifdef KORE_LINUX // xlib defines conflicting with v8 #undef True #undef False #undef None #undef Status #endif #include #include #ifdef KORE_WINDOWS #include // AttachConsole #include #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #endif extern "C" struct HWND__ *kinc_windows_window_handle(int window_index); // Kore/Windows.h bool show_window = false; // Enable visual styles for ui controls #pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #ifdef WITH_WORKER #include "worker.h" #endif #ifdef WITH_VIEWPORT #include "viewport_server.h" #endif // TODO //#ifdef KINC_KONG //#include //#endif #include #include #include using namespace v8; #ifdef KORE_MACOS extern "C" const char *macgetresourcepath(); #endif namespace { int _argc; char **_argv; bool enable_window = true; #ifdef WITH_AUDIO bool enable_audio = true; #endif bool snapshot = false; bool stderr_created = false; bool in_background = false; int paused_frames = 0; #ifdef WITH_VIEWPORT bool viewport_server_mode = false; char viewport_shmem_name[256] = VIEWPORT_SHMEM_NAME; int viewport_width = 1920; int viewport_height = 1080; #endif Isolate *isolate; std::unique_ptr plat; Global global_context; Global update_func; Global drop_files_func; Global cut_func; Global copy_func; Global paste_func; Global foreground_func; Global resume_func; Global pause_func; Global background_func; Global shutdown_func; Global keyboard_down_func; Global keyboard_up_func; Global keyboard_press_func; Global mouse_down_func; Global mouse_up_func; Global mouse_move_func; Global touch_down_func; Global touch_up_func; Global touch_move_func; Global mouse_wheel_func; Global pen_down_func; Global pen_up_func; Global pen_move_func; Global gamepad_axis_func; Global gamepad_button_func; Global save_and_quit_func; #ifdef WITH_AUDIO Global audio_func; kinc_mutex_t mutex; kinc_a2_buffer_t audio_buffer; int audio_read_location = 0; void update_audio(kinc_a2_buffer_t *buffer, int samples); #endif bool save_and_quit_func_set = false; void update(void *data); void drop_files(wchar_t *file_path, void *data); char *cut(void *data); char *copy(void *data); void paste(char *text, void *data); void foreground(void *data); void resume(void *data); void pause(void *data); void background(void *data); void shutdown(void *data); void key_down(int code, void *data); void key_up(int code, void *data); void key_press(unsigned int character, void *data); void mouse_move(int window, int x, int y, int mx, int my, void *data); void mouse_down(int window, int button, int x, int y, void *data); void mouse_up(int window, int button, int x, int y, void *data); void mouse_wheel(int window, int delta, void *data); void touch_move(int index, int x, int y); void touch_down(int index, int x, int y); void touch_up(int index, int x, int y); void pen_down(int window, int x, int y, float pressure); void pen_up(int window, int x, int y, float pressure); void pen_move(int window, int x, int y, float pressure); void gamepad_axis(int gamepad, int axis, float value); void gamepad_button(int gamepad, int button, float value); char temp_string[4096]; char temp_string_vs[1024 * 1024]; char temp_string_fs[1024 * 1024]; char temp_string_vstruct[4][32][32]; std::string assetsdir; #ifdef KORE_WINDOWS wchar_t temp_wstring[1024]; wchar_t temp_wstring1[1024]; #endif class RunTCallbackdata { public: int32_t size; Global func; }; void write_stack_trace(const char *stack_trace) { kinc_log(KINC_LOG_LEVEL_INFO, "Trace: %s", stack_trace); #ifdef KORE_WINDOWS FILE *file = fopen("stderr.txt", stderr_created ? "a" : "w"); if (file == nullptr) { // Running from protected path strcpy(temp_string, kinc_internal_save_path()); strcat(temp_string, "\\stderr.txt"); file = fopen(temp_string, stderr_created ? "a" : "w"); } if (file != nullptr) { stderr_created = true; fwrite(stack_trace, 1, strlen(stack_trace), file); fwrite("\n", 1, 1, file); fclose(file); } #endif } void handle_exception(TryCatch *try_catch) { MaybeLocal trace = try_catch->StackTrace(isolate->GetCurrentContext()); if (trace.IsEmpty()) { String::Utf8Value stack_trace(isolate, try_catch->Message()->Get()); write_stack_trace(*stack_trace); } else { String::Utf8Value stack_trace(isolate, trace.ToLocalChecked()); write_stack_trace(*stack_trace); } } void runt_log(const FunctionCallbackInfo &args); void runt_set_timeout(const FunctionCallbackInfo &args); void runt_set_interval(const FunctionCallbackInfo &args); void runt_clear_timeout(const FunctionCallbackInfo &args); void runt_clear_interval(const FunctionCallbackInfo &args); void execute_timers(); void runt_init(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; String::Utf8Value title(isolate, arg); int width = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int height = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int samples_per_pixel = args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); bool vertical_sync = args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int window_mode = args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int window_features = args[6]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); // int api_version = args[7]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int x = -1; int y = -1; int frequency = 60; kinc_window_options_t win; win.title = *title; win.x = x; win.y = y; win.width = width; win.height = height; win.display_index = -1; #ifdef KORE_WINDOWS win.visible = false; // Prevent white flicker when opening the window #else win.visible = enable_window; #endif win.window_features = window_features; win.mode = (kinc_window_mode_t)window_mode; kinc_framebuffer_options_t frame; frame.frequency = frequency; frame.vertical_sync = vertical_sync; frame.color_bits = 32; frame.depth_bits = 0; frame.stencil_bits = 0; frame.samples_per_pixel = samples_per_pixel; kinc_init(*title, width, height, &win, &frame); kinc_random_init((int)(kinc_time() * 1000)); #ifdef KORE_WINDOWS // Maximized window has x < -1, prevent window centering done by kinc if (x < -1 && y < -1) { kinc_window_move(0, x, y); } char vdata[4]; DWORD cbdata = 4 * sizeof(char); RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, vdata, &cbdata); BOOL use_dark_mode = int(vdata[3] << 24 | vdata[2] << 16 | vdata[1] << 8 | vdata[0]) != 1; DwmSetWindowAttribute(kinc_windows_window_handle(0), DWMWA_USE_IMMERSIVE_DARK_MODE, &use_dark_mode, sizeof(use_dark_mode)); show_window = true; #endif #ifdef WITH_AUDIO if (enable_audio) { kinc_mutex_init(&mutex); kinc_a1_init(); kinc_a2_init(); kinc_a2_set_callback(update_audio); audio_buffer.read_location = 0; audio_buffer.write_location = 0; audio_buffer.data_size = 128 * 1024; audio_buffer.data = new uint8_t[audio_buffer.data_size]; } #endif kinc_set_update_callback(update, NULL); kinc_set_drop_files_callback(drop_files, NULL); kinc_set_copy_callback(copy, NULL); kinc_set_cut_callback(cut, NULL); kinc_set_paste_callback(paste, NULL); kinc_set_foreground_callback(foreground, NULL); kinc_set_resume_callback(resume, NULL); kinc_set_pause_callback(pause, NULL); kinc_set_background_callback(background, NULL); kinc_set_shutdown_callback(shutdown, NULL); kinc_keyboard_set_key_down_callback(key_down, NULL); kinc_keyboard_set_key_up_callback(key_up, NULL); kinc_keyboard_set_key_press_callback(key_press, NULL); kinc_mouse_set_move_callback(mouse_move, NULL); kinc_mouse_set_press_callback(mouse_down, NULL); kinc_mouse_set_release_callback(mouse_up, NULL); kinc_mouse_set_scroll_callback(mouse_wheel, NULL); kinc_surface_set_move_callback(touch_move); kinc_surface_set_touch_start_callback(touch_down); kinc_surface_set_touch_end_callback(touch_up); kinc_pen_set_press_callback(pen_down); kinc_pen_set_move_callback(pen_move); kinc_pen_set_release_callback(pen_up); kinc_gamepad_set_axis_callback(gamepad_axis); kinc_gamepad_set_button_callback(gamepad_button); } void runt_set_application_name(const FunctionCallbackInfo &args) { // Name used by kinc_internal_save_path() HandleScope scope(args.GetIsolate()); String::Utf8Value name(isolate, args[0]); kinc_set_application_name(*name); } void runt_log(const FunctionCallbackInfo &args) { Isolate* current_isolate = args.GetIsolate(); HandleScope scope(current_isolate); if (args.Length() == 0) { return; } Local arg = args[0]; String::Utf8Value value(current_isolate, arg); size_t len = strlen(*value); if (len < 2048) { kinc_log(KINC_LOG_LEVEL_INFO, *value); } else { int pos = 0; while (pos < len) { strncpy(temp_string, *value + pos, 2047); temp_string[2047] = 0; kinc_log(KINC_LOG_LEVEL_INFO, temp_string); pos += 2047; } } } void runt_clear_fast(Local receiver, int flags, int color, float depth, int stencil) { kinc_g4_clear(flags, color, depth, stencil); } void runt_clear(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int flags = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int color = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float depth = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int stencil = args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); runt_clear_fast(args.This(), flags, color, depth, stencil); } void runt_set_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); update_func.Reset(isolate, func); } void runt_set_drop_files_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); drop_files_func.Reset(isolate, func); } void runt_set_cut_copy_paste_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local cutArg = args[0]; Local cutFunc = Local::Cast(cutArg); cut_func.Reset(isolate, cutFunc); Local copyArg = args[1]; Local copyFunc = Local::Cast(copyArg); copy_func.Reset(isolate, copyFunc); Local pasteArg = args[2]; Local pasteFunc = Local::Cast(pasteArg); paste_func.Reset(isolate, pasteFunc); } void runt_set_application_state_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local foregroundArg = args[0]; Local foregroundFunc = Local::Cast(foregroundArg); foreground_func.Reset(isolate, foregroundFunc); Local resumeArg = args[1]; Local resumeFunc = Local::Cast(resumeArg); resume_func.Reset(isolate, resumeFunc); Local pauseArg = args[2]; Local pauseFunc = Local::Cast(pauseArg); pause_func.Reset(isolate, pauseFunc); Local backgroundArg = args[3]; Local backgroundFunc = Local::Cast(backgroundArg); background_func.Reset(isolate, backgroundFunc); Local shutdownArg = args[4]; Local shutdownFunc = Local::Cast(shutdownArg); shutdown_func.Reset(isolate, shutdownFunc); } void runt_set_keyboard_down_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); keyboard_down_func.Reset(isolate, func); } void runt_set_keyboard_up_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); keyboard_up_func.Reset(isolate, func); } void runt_set_keyboard_press_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); keyboard_press_func.Reset(isolate, func); } void runt_set_mouse_down_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); mouse_down_func.Reset(isolate, func); } void runt_set_mouse_up_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); mouse_up_func.Reset(isolate, func); } void runt_set_mouse_move_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); mouse_move_func.Reset(isolate, func); } void runt_set_touch_down_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); touch_down_func.Reset(isolate, func); } void runt_set_touch_up_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); touch_up_func.Reset(isolate, func); } void runt_set_touch_move_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); touch_move_func.Reset(isolate, func); } void runt_set_mouse_wheel_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); mouse_wheel_func.Reset(isolate, func); } void runt_set_pen_down_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); pen_down_func.Reset(isolate, func); } void runt_set_pen_up_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); pen_up_func.Reset(isolate, func); } void runt_set_pen_move_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); pen_move_func.Reset(isolate, func); } void runt_set_gamepad_axis_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); gamepad_axis_func.Reset(isolate, func); } void runt_set_gamepad_button_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); gamepad_button_func.Reset(isolate, func); } void runt_lock_mouse_fast(Local receiver) { kinc_mouse_lock(0); } void runt_lock_mouse(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); runt_lock_mouse_fast(args.This()); } void runt_unlock_mouse_fast(Local receiver) { kinc_mouse_unlock(); } void runt_unlock_mouse(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); runt_unlock_mouse_fast(args.This()); } int runt_can_lock_mouse_fast(Local receiver) { return kinc_mouse_can_lock(); } void runt_can_lock_mouse(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Int32::New(isolate, runt_can_lock_mouse_fast(args.This()))); } int runt_is_mouse_locked_fast(Local receiver) { return kinc_mouse_is_locked(); } void runt_is_mouse_locked(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Int32::New(isolate, runt_is_mouse_locked_fast(args.This()))); } void runt_set_mouse_position_fast(Local receiver, int windowId, int x, int y) { kinc_mouse_set_position(windowId, x, y); } void runt_set_mouse_position(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int x = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int y = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); runt_set_mouse_position_fast(args.This(), windowId, x, y); } void runt_show_mouse_fast(Local receiver, int show) { show ? kinc_mouse_show() : kinc_mouse_hide(); } void runt_show_mouse(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int show = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); runt_show_mouse_fast(args.This(), show); } void runt_show_keyboard_fast(Local receiver, int show) { show ? kinc_keyboard_show() : kinc_keyboard_hide(); } void runt_show_keyboard(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int show = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); runt_show_keyboard_fast(args.This(), show); } void runt_create_indexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); kinc_g4_index_buffer_t *buffer = (kinc_g4_index_buffer_t *)malloc(sizeof(kinc_g4_index_buffer_t)); kinc_g4_index_buffer_init(buffer, args[0]->Int32Value(isolate->GetCurrentContext()).FromJust(), KINC_G4_INDEX_BUFFER_FORMAT_32BIT, KINC_G4_USAGE_STATIC); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, buffer)); args.GetReturnValue().Set(obj); } void runt_delete_indexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_index_buffer_t *buffer = (kinc_g4_index_buffer_t *)field->Value(); kinc_g4_index_buffer_destroy(buffer); free(buffer); } void runt_lock_indexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_index_buffer_t *buffer = (kinc_g4_index_buffer_t *)field->Value(); int *vertices = (int *)kinc_g4_index_buffer_lock_all(buffer); std::unique_ptr backing = v8::ArrayBuffer::NewBackingStore((void *)vertices, kinc_g4_index_buffer_count(buffer) * sizeof(int), [](void *, size_t, void *) {}, nullptr); Local abuffer = ArrayBuffer::New(isolate, std::move(backing)); args.GetReturnValue().Set(Uint32Array::New(abuffer, 0, kinc_g4_index_buffer_count(buffer))); } void runt_unlock_indexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_index_buffer_t *buffer = (kinc_g4_index_buffer_t *)field->Value(); kinc_g4_index_buffer_unlock_all(buffer); } void runt_set_indexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_index_buffer_t *buffer = (kinc_g4_index_buffer_t *)field->Value(); kinc_g4_set_index_buffer(buffer); } kinc_g4_vertex_data_t convert_vertex_data(int num) { switch (num) { case 0: // Float32_1X return KINC_G4_VERTEX_DATA_F32_1X; case 1: // Float32_2X return KINC_G4_VERTEX_DATA_F32_2X; case 2: // Float32_3X return KINC_G4_VERTEX_DATA_F32_3X; case 3: // Float32_4X return KINC_G4_VERTEX_DATA_F32_4X; case 4: // Float32_4X4 return KINC_G4_VERTEX_DATA_F32_4X4; case 5: // Int8_1X return KINC_G4_VERTEX_DATA_I8_1X; case 6: // UInt8_1X return KINC_G4_VERTEX_DATA_U8_1X; case 7: // Int8_1X_Normalized return KINC_G4_VERTEX_DATA_I8_1X_NORMALIZED; case 8: // UInt8_1X_Normalized return KINC_G4_VERTEX_DATA_U8_1X_NORMALIZED; case 9: // Int8_2X return KINC_G4_VERTEX_DATA_I8_2X; case 10: // UInt8_2X return KINC_G4_VERTEX_DATA_U8_2X; case 11: // Int8_2X_Normalized return KINC_G4_VERTEX_DATA_I8_2X_NORMALIZED; case 12: // UInt8_2X_Normalized return KINC_G4_VERTEX_DATA_U8_2X_NORMALIZED; case 13: // Int8_4X return KINC_G4_VERTEX_DATA_I8_4X; case 14: // UInt8_4X return KINC_G4_VERTEX_DATA_U8_4X; case 15: // Int8_4X_Normalized return KINC_G4_VERTEX_DATA_I8_4X_NORMALIZED; case 16: // UInt8_4X_Normalized return KINC_G4_VERTEX_DATA_U8_4X_NORMALIZED; case 17: // Int16_1X return KINC_G4_VERTEX_DATA_I16_1X; case 18: // UInt16_1X return KINC_G4_VERTEX_DATA_U16_1X; case 19: // Int16_1X_Normalized return KINC_G4_VERTEX_DATA_I16_1X_NORMALIZED; case 20: // UInt16_1X_Normalized return KINC_G4_VERTEX_DATA_U16_1X_NORMALIZED; case 21: // Int16_2X return KINC_G4_VERTEX_DATA_I16_2X; case 22: // UInt16_2X return KINC_G4_VERTEX_DATA_U16_2X; case 23: // Int16_2X_Normalized return KINC_G4_VERTEX_DATA_I16_2X_NORMALIZED; case 24: // UInt16_2X_Normalized return KINC_G4_VERTEX_DATA_U16_2X_NORMALIZED; case 25: // Int16_4X return KINC_G4_VERTEX_DATA_I16_4X; case 26: // UInt16_4X return KINC_G4_VERTEX_DATA_U16_4X; case 27: // Int16_4X_Normalized return KINC_G4_VERTEX_DATA_I16_4X_NORMALIZED; case 28: // UInt16_4X_Normalized return KINC_G4_VERTEX_DATA_U16_4X_NORMALIZED; case 29: // Int32_1X return KINC_G4_VERTEX_DATA_I32_1X; case 30: // UInt32_1X return KINC_G4_VERTEX_DATA_U32_1X; case 31: // Int32_2X return KINC_G4_VERTEX_DATA_I32_2X; case 32: // UInt32_2X return KINC_G4_VERTEX_DATA_U32_2X; case 33: // Int32_3X return KINC_G4_VERTEX_DATA_I32_3X; case 34: // UInt32_3X return KINC_G4_VERTEX_DATA_U32_3X; case 35: // Int32_4X return KINC_G4_VERTEX_DATA_I32_4X; case 36: // UInt32_4X return KINC_G4_VERTEX_DATA_U32_4X; } return KINC_G4_VERTEX_DATA_NONE; } void runt_create_vertexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); Local jsstructure = args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); int32_t length = jsstructure->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "length").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_vertex_structure_t structure; kinc_g4_vertex_structure_init(&structure); for (int32_t i = 0; i < length; ++i) { Local element = jsstructure->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local str = element->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked()).ToLocalChecked(); String::Utf8Value utf8_value(isolate, str); int32_t data = element->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "data").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); strcpy(temp_string_vstruct[0][i], *utf8_value); kinc_g4_vertex_structure_add(&structure, temp_string_vstruct[0][i], convert_vertex_data(data)); } kinc_g4_vertex_buffer_t *buffer = (kinc_g4_vertex_buffer_t *)malloc(sizeof(kinc_g4_vertex_buffer_t)); kinc_g4_vertex_buffer_init(buffer, args[0]->Int32Value(isolate->GetCurrentContext()).FromJust(), &structure, (kinc_g4_usage_t)args[2]->Int32Value(isolate->GetCurrentContext()).FromJust(), args[3]->Int32Value(isolate->GetCurrentContext()).FromJust()); obj->SetInternalField(0, External::New(isolate, buffer)); args.GetReturnValue().Set(obj); } void runt_delete_vertexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_vertex_buffer_t *buffer = (kinc_g4_vertex_buffer_t *)field->Value(); kinc_g4_vertex_buffer_destroy(buffer); free(buffer); } void runt_lock_vertex_buffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_vertex_buffer_t *buffer = (kinc_g4_vertex_buffer_t *)field->Value(); int start = args[1]->Int32Value(isolate->GetCurrentContext()).FromJust(); int count = args[2]->Int32Value(isolate->GetCurrentContext()).FromJust(); float *vertices = kinc_g4_vertex_buffer_lock(buffer, start, count); std::unique_ptr backing = v8::ArrayBuffer::NewBackingStore((void *)vertices, (uint32_t)(count * kinc_g4_vertex_buffer_stride(buffer)), [](void *, size_t, void *) {}, nullptr); Local abuffer = ArrayBuffer::New(isolate, std::move(backing)); args.GetReturnValue().Set(abuffer); } void runt_unlock_vertex_buffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_vertex_buffer_t *buffer = (kinc_g4_vertex_buffer_t *)field->Value(); int count = args[1]->Int32Value(isolate->GetCurrentContext()).FromJust(); kinc_g4_vertex_buffer_unlock(buffer, count); } void runt_set_vertexbuffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_vertex_buffer_t *buffer = (kinc_g4_vertex_buffer_t *)field->Value(); kinc_g4_set_vertex_buffer(buffer); } void runt_set_vertexbuffers(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_g4_vertex_buffer_t *vertex_buffers[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; Local jsarray = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); int32_t length = jsarray->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "length").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); for (int32_t i = 0; i < length; ++i) { Local bufferobj = jsarray->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "buffer").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local bufferfield = Local::Cast(bufferobj->GetInternalField(0)); kinc_g4_vertex_buffer_t *buffer = (kinc_g4_vertex_buffer_t *)bufferfield->Value(); vertex_buffers[i] = buffer; } kinc_g4_set_vertex_buffers(vertex_buffers, length); } void runt_draw_indexed_vertices_fast(Local receiver, int start, int count) { if (count < 0) kinc_g4_draw_indexed_vertices(); else kinc_g4_draw_indexed_vertices_from_to(start, count); } void runt_draw_indexed_vertices(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int start = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int count = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); runt_draw_indexed_vertices_fast(args.This(), start, count); } void runt_draw_indexed_vertices_instanced_fast(Local receiver, int instance_count, int start, int count) { if (count < 0) kinc_g4_draw_indexed_vertices_instanced(instance_count); else kinc_g4_draw_indexed_vertices_instanced_from_to(instance_count, start, count); } void runt_draw_indexed_vertices_instanced(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int instance_count = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int start = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int count = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); runt_draw_indexed_vertices_instanced_fast(args.This(), instance_count, start, count); } void runt_create_vertex_shader(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, content->Data(), (int)content->ByteLength(), KINC_G4_SHADER_TYPE_VERTEX); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), args[1]); args.GetReturnValue().Set(obj); } void runt_create_vertex_shader_from_source(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); char *source = new char[strlen(*utf8_value) + 1]; strcpy(source, *utf8_value); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, source, strlen(source), KINC_G4_SHADER_TYPE_VERTEX); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); Local name = String::NewFromUtf8(isolate, "").ToLocalChecked(); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), name); args.GetReturnValue().Set(obj); } void runt_create_fragment_shader(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, content->Data(), (int)content->ByteLength(), KINC_G4_SHADER_TYPE_FRAGMENT); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), args[1]); args.GetReturnValue().Set(obj); } void runt_create_fragment_shader_from_source(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); char *source = new char[strlen(*utf8_value) + 1]; strcpy(source, *utf8_value); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, source, strlen(source), KINC_G4_SHADER_TYPE_FRAGMENT); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); Local name = String::NewFromUtf8(isolate, "").ToLocalChecked(); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), name); args.GetReturnValue().Set(obj); } void runt_create_geometry_shader(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, content->Data(), (int)content->ByteLength(), KINC_G4_SHADER_TYPE_GEOMETRY); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), args[1]); args.GetReturnValue().Set(obj); } void runt_create_tessellation_control_shader(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, content->Data(), (int)content->ByteLength(), KINC_G4_SHADER_TYPE_TESSELLATION_CONTROL); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), args[1]); args.GetReturnValue().Set(obj); } void runt_create_tessellation_evaluation_shader(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t)); kinc_g4_shader_init(shader, content->Data(), (int)content->ByteLength(), KINC_G4_SHADER_TYPE_TESSELLATION_EVALUATION); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked(), args[1]); args.GetReturnValue().Set(obj); } void runt_delete_shader(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_shader_t *shader = (kinc_g4_shader_t *)field->Value(); kinc_g4_shader_destroy(shader); free(shader); } void runt_create_pipeline(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)malloc(sizeof(kinc_g4_pipeline_t)); kinc_g4_pipeline_init(pipeline); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(8); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, pipeline)); args.GetReturnValue().Set(obj); } void runt_delete_pipeline(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local pipeobj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local pipefield = Local::Cast(pipeobj->GetInternalField(0)); kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)pipefield->Value(); kinc_g4_pipeline_destroy(pipeline); free(pipeline); } void runt_compile_pipeline(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local pipeobj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local pipefield = Local::Cast(pipeobj->GetInternalField(0)); kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)pipefield->Value(); kinc_g4_vertex_structure_t s0, s1, s2, s3; kinc_g4_vertex_structure_init(&s0); kinc_g4_vertex_structure_init(&s1); kinc_g4_vertex_structure_init(&s2); kinc_g4_vertex_structure_init(&s3); kinc_g4_vertex_structure_t *structures[4] = { &s0, &s1, &s2, &s3 }; int32_t size = args[5]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); for (int32_t i1 = 0; i1 < size; ++i1) { Local jsstructure = args[i1 + 1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); structures[i1]->instanced = jsstructure->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "instanced").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); Local elements = jsstructure->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "elements").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); int32_t length = elements->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "length").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); for (int32_t i2 = 0; i2 < length; ++i2) { Local element = elements->Get(isolate->GetCurrentContext(), i2).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local str = element->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "name").ToLocalChecked()).ToLocalChecked(); String::Utf8Value utf8_value(isolate, str); int32_t data = element->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "data").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); strcpy(temp_string_vstruct[i1][i2], *utf8_value); kinc_g4_vertex_structure_add(structures[i1], temp_string_vstruct[i1][i2], convert_vertex_data(data)); } } pipeobj->SetInternalField(1, External::New(isolate, structures)); pipeobj->SetInternalField(2, External::New(isolate, &size)); Local vsfield = Local::Cast(args[6]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_shader_t *vertexShader = (kinc_g4_shader_t *)vsfield->Value(); pipeobj->SetInternalField(3, External::New(isolate, vertexShader)); Local fsfield = Local::Cast(args[7]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_shader_t *fragmentShader = (kinc_g4_shader_t *)fsfield->Value(); pipeobj->SetInternalField(4, External::New(isolate, fragmentShader)); pipeline->vertex_shader = vertexShader; pipeline->fragment_shader = fragmentShader; if (!args[8]->IsNullOrUndefined()) { Local gsfield = Local::Cast(args[8]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_shader_t *geometryShader = (kinc_g4_shader_t *)gsfield->Value(); pipeobj->SetInternalField(5, External::New(isolate, geometryShader)); pipeline->geometry_shader = geometryShader; } if (!args[9]->IsNullOrUndefined()) { Local tcsfield = Local::Cast(args[9]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_shader_t *tessellationControlShader = (kinc_g4_shader_t *)tcsfield->Value(); pipeobj->SetInternalField(6, External::New(isolate, tessellationControlShader)); pipeline->tessellation_control_shader = tessellationControlShader; } if (!args[10]->IsNullOrUndefined()) { Local tesfield = Local::Cast(args[10]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_shader_t *tessellationEvaluationShader = (kinc_g4_shader_t *)tesfield->Value(); pipeobj->SetInternalField(7, External::New(isolate, tessellationEvaluationShader)); pipeline->tessellation_evaluation_shader = tessellationEvaluationShader; } for (int i = 0; i < size; ++i) { pipeline->input_layout[i] = structures[i]; } pipeline->input_layout[size] = nullptr; Local args11 = args[11]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); pipeline->cull_mode = (kinc_g4_cull_mode_t)args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "cullMode").ToLocalChecked()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); pipeline->depth_write = args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "depthWrite").ToLocalChecked()).ToLocalChecked()->BooleanValue(isolate); pipeline->depth_mode = (kinc_g4_compare_mode_t)args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "depthMode").ToLocalChecked()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); pipeline->blend_source = (kinc_g4_blending_factor_t)args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "blendSource").ToLocalChecked()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); pipeline->blend_destination = (kinc_g4_blending_factor_t)args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "blendDestination").ToLocalChecked()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); pipeline->alpha_blend_source = (kinc_g4_blending_factor_t)args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "alphaBlendSource").ToLocalChecked()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); pipeline->alpha_blend_destination = (kinc_g4_blending_factor_t)args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "alphaBlendDestination").ToLocalChecked()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); Local maskRedArray = args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "colorWriteMaskRed").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local maskGreenArray = args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "colorWriteMaskGreen").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local maskBlueArray = args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "colorWriteMaskBlue").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local maskAlphaArray = args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "colorWriteMaskAlpha").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); for (int i = 0; i < 8; ++i) { pipeline->color_write_mask_red[i] = maskRedArray->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->BooleanValue(isolate); pipeline->color_write_mask_green[i] = maskGreenArray->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->BooleanValue(isolate); pipeline->color_write_mask_blue[i] = maskBlueArray->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->BooleanValue(isolate); pipeline->color_write_mask_alpha[i] = maskAlphaArray->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->BooleanValue(isolate); } pipeline->conservative_rasterization = args11->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "conservativeRasterization").ToLocalChecked()).ToLocalChecked()->BooleanValue(isolate); kinc_g4_pipeline_compile(pipeline); } void runt_set_pipeline(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local pipeobj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local pipefield = Local::Cast(pipeobj->GetInternalField(0)); kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)pipefield->Value(); kinc_g4_set_pipeline(pipeline); } bool ends_with(const char *str, const char *suffix) { if (!str || !suffix) return 0; size_t lenstr = strlen(str); size_t lensuffix = strlen(suffix); if (lensuffix > lenstr) return 0; return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; } bool load_image(kinc_file_reader_t &reader, const char *filename, unsigned char *&output, int &width, int &height, kinc_image_format_t &format) { format = KINC_IMAGE_FORMAT_RGBA32; int size = (int)kinc_file_reader_size(&reader); int comp; bool success = true; unsigned char *data = (unsigned char *)malloc(size); kinc_file_reader_read(&reader, data, size); kinc_file_reader_close(&reader); if (ends_with(filename, "k")) { width = kinc_read_s32le(data); height = kinc_read_s32le(data + 4); char fourcc[5]; fourcc[0] = data[8]; fourcc[1] = data[9]; fourcc[2] = data[10]; fourcc[3] = data[11]; fourcc[4] = 0; int compressedSize = size - 12; if (strcmp(fourcc, "LZ4 ") == 0) { int outputSize = width * height * 4; output = (unsigned char *)malloc(outputSize); LZ4_decompress_safe((char *)(data + 12), (char *)output, compressedSize, outputSize); } else if (strcmp(fourcc, "LZ4F") == 0) { int outputSize = width * height * 16; output = (unsigned char *)malloc(outputSize); LZ4_decompress_safe((char *)(data + 12), (char *)output, compressedSize, outputSize); format = KINC_IMAGE_FORMAT_RGBA128; } else { success = false; } } else if (ends_with(filename, "hdr")) { output = (unsigned char *)stbi_loadf_from_memory(data, size, &width, &height, &comp, 4); if (output == nullptr) { kinc_log(KINC_LOG_LEVEL_ERROR, stbi_failure_reason()); success = false; } format = KINC_IMAGE_FORMAT_RGBA128; } else { // jpg, png, .. output = stbi_load_from_memory(data, size, &width, &height, &comp, 4); if (output == nullptr) { kinc_log(KINC_LOG_LEVEL_ERROR, stbi_failure_reason()); success = false; } } free(data); return success; } void runt_load_image(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); bool readable = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); bool success = true; kinc_image_t *image = (kinc_image_t *)malloc(sizeof(kinc_image_t)); // if (armorcore) { kinc_file_reader_t reader; if (kinc_file_reader_open(&reader, *utf8_value, KINC_FILE_TYPE_ASSET)) { unsigned char *image_data; int image_width; int image_height; kinc_image_format_t image_format; success = load_image(reader, *utf8_value, image_data, image_width, image_height, image_format); if (success) { kinc_image_init(image, image_data, image_width, image_height, image_format); } } else { success = false; } // } // else { // // TODO: make kinc_image load faster // size_t byte_size = kinc_image_size_from_file(*utf8_value); // if (byte_size == 0) { // success = false; // } // else { // void *memory = malloc(byte_size); // kinc_image_init_from_file(image, memory, *utf8_value); // } // } if (!success) { free(image); return; } kinc_g4_texture_t *texture = (kinc_g4_texture_t *)malloc(sizeof(kinc_g4_texture_t)); kinc_g4_texture_init_from_image(texture, image); if (!readable) { free(image->data); kinc_image_destroy(image); free(image); // free(memory); } Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(readable ? 2 : 1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, texture)); if (readable) obj->SetInternalField(1, External::New(isolate, image)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "realWidth").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "realHeight").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); args.GetReturnValue().Set(obj); } void runt_unload_image(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); if (args[0]->IsNullOrUndefined()) return; Local image = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local tex = image->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "texture_").ToLocalChecked()).ToLocalChecked(); Local rt = image->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "renderTarget_").ToLocalChecked()).ToLocalChecked(); if (tex->IsObject()) { Local texfield = Local::Cast(tex->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)texfield->Value(); kinc_g4_texture_destroy(texture); free(texture); } else if (rt->IsObject()) { Local rtfield = Local::Cast(rt->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); kinc_g4_render_target_destroy(render_target); free(render_target); } } #ifdef WITH_AUDIO void runt_set_audio_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); audio_func.Reset(isolate, func); } void runt_audio_thread(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); bool lock = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); if (lock) kinc_mutex_lock(&mutex); //Locker::Locker(isolate); else kinc_mutex_unlock(&mutex); //Unlocker(args.GetIsolate()); } void runt_load_sound(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); kinc_a1_sound_t *sound = kinc_a1_sound_create(*utf8_value); if (sound == nullptr) { return; } Local buffer = ArrayBuffer::New(isolate, sound->size * 2 * sizeof(float)); std::shared_ptr content = buffer->GetBackingStore(); float *to = (float *)content->Data(); int16_t *left = (int16_t *)&sound->left[0]; int16_t *right = (int16_t *)&sound->right[0]; for (int i = 0; i < sound->size; i += 1) { to[i * 2 ] = (float)(left [i] / 32767.0); to[i * 2 + 1] = (float)(right[i] / 32767.0); } args.GetReturnValue().Set(buffer); kinc_a1_sound_destroy(sound); } void runt_write_audio_buffer(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); int samples = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); for (int i = 0; i < samples; ++i) { float *values = (float *)content->Data(); float value = values[audio_read_location / 4]; audio_read_location += 4; if (audio_read_location >= content->ByteLength()) audio_read_location = 0; *(float *)&audio_buffer.data[audio_buffer.write_location] = value; audio_buffer.write_location += 4; if (audio_buffer.write_location >= audio_buffer.data_size) audio_buffer.write_location = 0; } } int runt_get_samples_per_second_fast(Local receiver) { kinc_log(KINC_LOG_LEVEL_INFO, "Samples per second: %d Hz.", kinc_a2_samples_per_second); return kinc_a2_samples_per_second; } void runt_get_samples_per_second(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Int32::New(isolate, runt_get_samples_per_second_fast(args.This()))); } void update_audio(kinc_a2_buffer_t *buffer, int samples) { if (!isolate || isolate->IsExecutionTerminating()) { // TODO: Re-investigate fill buffer with silence during shutdown for (int i = 0; i < samples; ++i) { *(float *)&buffer->data[buffer->write_location] = 0.0f; buffer->write_location += 4; if (buffer->write_location >= buffer->data_size) { buffer->write_location = 0; } } return; } kinc_mutex_lock(&mutex); Locker locker{isolate}; Isolate::Scope isolate_scope(isolate); MicrotasksScope microtasks_scope(isolate, MicrotasksScope::kRunMicrotasks); HandleScope handle_scope(isolate); if (global_context.IsEmpty()) { kinc_mutex_unlock(&mutex); // TODO: re-investigate for (int i = 0; i < samples; ++i) { *(float *)&buffer->data[buffer->write_location] = 0.0f; buffer->write_location += 4; if (buffer->write_location >= buffer->data_size) { buffer->write_location = 0; } } return; } Local context = Local::New(isolate, global_context); Context::Scope context_scope(context); TryCatch try_catch(isolate); Local func = Local::New(isolate, audio_func); Local result; const int argc = 1; Local argv[argc] = {Int32::New(isolate, samples)}; if (!func->Call(context, context->Global(), argc, argv).ToLocal(&result)) { handle_exception(&try_catch); } for (int i = 0; i < samples; ++i) { float sample = *(float *)&audio_buffer.data[audio_buffer.read_location]; audio_buffer.read_location += 4; if (audio_buffer.read_location >= audio_buffer.data_size) { audio_buffer.read_location = 0; } *(float *)&buffer->data[buffer->write_location] = sample; buffer->write_location += 4; if (buffer->write_location >= buffer->data_size) { buffer->write_location = 0; } } kinc_mutex_unlock(&mutex); } #else void runt_set_audio_callback(const FunctionCallbackInfo &args) { } void runt_audio_thread(const FunctionCallbackInfo &args) { } void runt_load_sound(const FunctionCallbackInfo &args) { } void runt_write_audio_buffer(const FunctionCallbackInfo &args) { } void runt_get_samples_per_second(const FunctionCallbackInfo &args) { } #endif void runt_load_blob(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); kinc_file_reader_t reader; if (!kinc_file_reader_open(&reader, *utf8_value, KINC_FILE_TYPE_ASSET)) return; uint32_t reader_size = (uint32_t)kinc_file_reader_size(&reader); Local buffer = ArrayBuffer::New(isolate, reader_size); std::shared_ptr content = buffer->GetBackingStore(); kinc_file_reader_read(&reader, content->Data(), reader_size); kinc_file_reader_close(&reader); args.GetReturnValue().Set(buffer); } void runt_load_url(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); kinc_load_url(*utf8_value); } void runt_copy_to_clipboard(const FunctionCallbackInfo& args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); kinc_copy_to_clipboard(*utf8_value); } void runt_get_constant_location(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local pipefield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)pipefield->Value(); String::Utf8Value utf8_value(isolate, args[1]); kinc_g4_constant_location_t location = kinc_g4_pipeline_get_constant_location(pipeline, *utf8_value); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); kinc_g4_constant_location_t *location_copy = (kinc_g4_constant_location_t *)malloc(sizeof(kinc_g4_constant_location_t)); memcpy(location_copy, &location, sizeof(kinc_g4_constant_location_t)); // TODO obj->SetInternalField(0, External::New(isolate, location_copy)); args.GetReturnValue().Set(obj); } void runt_get_texture_unit(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local pipefield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)pipefield->Value(); String::Utf8Value utf8_value(isolate, args[1]); kinc_g4_texture_unit_t unit = kinc_g4_pipeline_get_texture_unit(pipeline, *utf8_value); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); kinc_g4_texture_unit_t *unit_copy = (kinc_g4_texture_unit_t *)malloc(sizeof(kinc_g4_texture_unit_t)); memcpy(unit_copy, &unit, sizeof(kinc_g4_texture_unit_t)); // TODO obj->SetInternalField(0, External::New(isolate, unit_copy)); args.GetReturnValue().Set(obj); } void runt_set_texture(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); Local texfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)texfield->Value(); kinc_g4_set_texture(*unit, texture); } void runt_set_render_target(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); Local rtfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); kinc_g4_render_target_use_color_as_texture(render_target, *unit); } void runt_set_texture_depth(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); Local rtfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); kinc_g4_render_target_use_depth_as_texture(render_target, *unit); } void runt_set_image_texture(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); Local texfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)texfield->Value(); kinc_g4_set_image_texture(*unit, texture); } void runt_set_texture_parameters(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); kinc_g4_set_texture_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_U, (kinc_g4_texture_addressing_t)args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_V, (kinc_g4_texture_addressing_t)args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture_minification_filter(*unit, (kinc_g4_texture_filter_t)args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture_magnification_filter(*unit, (kinc_g4_texture_filter_t)args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture_mipmap_filter(*unit, (kinc_g4_mipmap_filter_t)args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); } void runt_set_texture3d_parameters(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); kinc_g4_set_texture3d_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_U, (kinc_g4_texture_addressing_t)args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture3d_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_V, (kinc_g4_texture_addressing_t)args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture3d_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_W, (kinc_g4_texture_addressing_t)args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture3d_minification_filter(*unit, (kinc_g4_texture_filter_t)args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture3d_magnification_filter(*unit, (kinc_g4_texture_filter_t)args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_g4_set_texture3d_mipmap_filter(*unit, (kinc_g4_mipmap_filter_t)args[6]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); } void runt_set_texture_compare_mode(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); kinc_g4_set_texture_compare_mode(*unit, args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); } void runt_set_cube_map_compare_mode(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)unitfield->Value(); kinc_g4_set_cubemap_compare_mode(*unit, args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); } void runt_set_bool(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); int32_t value = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_set_bool(*location, value != 0); } void runt_set_int(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); int32_t value = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_set_int(*location, value); } void runt_set_float(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); float value = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_set_float(*location, value); } void runt_set_float2(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); float value1 = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value2 = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_set_float2(*location, value1, value2); } void runt_set_float3(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); float value1 = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value2 = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value3 = (float)args[3]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_set_float3(*location, value1, value2, value3); } void runt_set_float4(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); float value1 = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value2 = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value3 = (float)args[3]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value4 = (float)args[4]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_set_float4(*location, value1, value2, value3, value4); } void runt_set_floats(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); float *from = (float *)content->Data(); kinc_g4_set_floats(*location, from, int(content->ByteLength() / 4)); } void runt_set_matrix(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); float *from = (float *)content->Data(); kinc_g4_set_matrix4(*location, (kinc_matrix4x4_t *)from); } void runt_set_matrix3(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)locationfield->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); float *from = (float *)content->Data(); kinc_g4_set_matrix3(*location, (kinc_matrix3x3_t *)from); } double runt_get_time_fast(Local receiver) { return kinc_time(); } void runt_get_time(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Number::New(isolate, runt_get_time_fast(args.This()))); } int runt_window_width_fast(Local receiver, int windowId) { return kinc_window_width(windowId); } void runt_window_width(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, runt_window_width_fast(args.This(), windowId))); } int runt_window_height_fast(Local receiver, int windowId) { return kinc_window_height(windowId); } void runt_window_height(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, runt_window_height_fast(args.This(), windowId))); } void runt_set_window_title(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); String::Utf8Value title(isolate, args[1]); kinc_window_set_title(windowId, *title); } void runt_get_window_mode(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_window_get_mode(windowId))); } void runt_set_window_mode(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_window_mode_t windowMode = (kinc_window_mode_t)args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_window_change_mode(windowId, windowMode); } void runt_resize_window(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int width = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int height = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_window_resize(windowId, width, height); } void runt_move_window(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int x = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int y = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_window_move(windowId, x, y); } void runt_screen_dpi(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int ppi = kinc_display_current_mode(kinc_primary_display()).pixels_per_inch; args.GetReturnValue().Set(Int32::New(isolate, ppi)); } void runt_system_id(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(String::NewFromUtf8(isolate, kinc_system_id()).ToLocalChecked()); } void runt_request_shutdown(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_stop(); } void runt_display_count(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Int32::New(isolate, kinc_count_displays())); } void runt_display_width(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_display_current_mode(index).width)); } void runt_display_height(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_display_current_mode(index).height)); } void runt_display_x(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_display_current_mode(index).x)); } void runt_display_y(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_display_current_mode(index).y)); } void runt_display_frequency(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_display_current_mode(index).frequency)); } void runt_display_is_primary(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); #ifdef KORE_LINUX // TODO: Primary display detection broken in Kinc args.GetReturnValue().Set(Int32::New(isolate, true)); #else args.GetReturnValue().Set(Int32::New(isolate, index == kinc_primary_display())); #endif } void runt_write_storage(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_name(isolate, args[0]); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); kinc_file_writer_t writer; kinc_file_writer_open(&writer, *utf8_name); kinc_file_writer_write(&writer, content->Data(), (int)content->ByteLength()); kinc_file_writer_close(&writer); } void runt_read_storage(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_name(isolate, args[0]); kinc_file_reader_t reader; if (!kinc_file_reader_open(&reader, *utf8_name, KINC_FILE_TYPE_SAVE)) return; int reader_size = (int)kinc_file_reader_size(&reader); Local buffer = ArrayBuffer::New(isolate, reader_size); std::shared_ptr content = buffer->GetBackingStore(); kinc_file_reader_read(&reader, content->Data(), reader_size); kinc_file_reader_close(&reader); args.GetReturnValue().Set(buffer); } void runt_create_render_target(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)malloc(sizeof(kinc_g4_render_target_t)); kinc_g4_render_target_init(render_target, args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), (kinc_g4_render_target_format_t)args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, render_target)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, render_target->width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, render_target->height)); args.GetReturnValue().Set(obj); } void runt_create_render_target_cube_map(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)malloc(sizeof(kinc_g4_render_target_t)); kinc_g4_render_target_init_cube(render_target, args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), (kinc_g4_render_target_format_t)args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, render_target)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, render_target->width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, render_target->height)); args.GetReturnValue().Set(obj); } void runt_create_texture(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)malloc(sizeof(kinc_g4_texture_t)); kinc_g4_texture_init(texture, args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), (kinc_image_format_t)args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, texture)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "realWidth").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "realHeight").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); args.GetReturnValue().Set(obj); } void runt_create_texture3d(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)malloc(sizeof(kinc_g4_texture_t)); kinc_g4_texture_init3d(texture, args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), (kinc_image_format_t)args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, texture)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "depth").ToLocalChecked(), Int32::New(isolate, texture->tex_depth)); args.GetReturnValue().Set(obj); } void runt_create_texture_from_bytes(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)malloc(sizeof(kinc_g4_texture_t)); kinc_image_t *image = (kinc_image_t *)malloc(sizeof(kinc_image_t)); bool readable = args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); void *image_data; if (readable) { image_data = malloc(content->ByteLength()); memcpy(image_data, content->Data(), content->ByteLength()); } else { image_data = content->Data(); } kinc_image_init(image, image_data, args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), (kinc_image_format_t)args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); kinc_g4_texture_init_from_image(texture, image); if (!readable) { kinc_image_destroy(image); free(image); } Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(readable ? 2 : 1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, texture)); if (readable) obj->SetInternalField(1, External::New(isolate, image)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "realWidth").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "realHeight").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); args.GetReturnValue().Set(obj); } void runt_create_texture_from_bytes3d(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)malloc(sizeof(kinc_g4_texture_t)); kinc_image_t *image = (kinc_image_t*)malloc(sizeof(kinc_image_t)); bool readable = args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); void *image_data; if (readable) { image_data = malloc(content->ByteLength()); memcpy(image_data, content->Data(), content->ByteLength()); } else { image_data = content->Data(); } kinc_image_init3d(image, image_data, args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(), (kinc_image_format_t)args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); kinc_g4_texture_init_from_image3d(texture, image); if (!readable) { kinc_image_destroy(image); free(image); } Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(readable ? 2 : 1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, texture)); if (readable) obj->SetInternalField(1, External::New(isolate, image)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "depth").ToLocalChecked(), Int32::New(isolate, texture->tex_depth)); args.GetReturnValue().Set(obj); } void runt_create_texture_from_encoded_bytes(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); String::Utf8Value format(isolate, args[1]); bool readable = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)malloc(sizeof(kinc_g4_texture_t)); kinc_image_t *image = (kinc_image_t *)malloc(sizeof(kinc_image_t)); unsigned char *content_data = (unsigned char *)content->Data(); int content_length = (int)content->ByteLength(); unsigned char *image_data; kinc_image_format_t image_format; int image_width; int image_height; if (ends_with(*format, "k")) { image_width = kinc_read_s32le(content_data); image_height = kinc_read_s32le(content_data + 4); char fourcc[5]; fourcc[0] = content_data[8]; fourcc[1] = content_data[9]; fourcc[2] = content_data[10]; fourcc[3] = content_data[11]; fourcc[4] = 0; int compressedSize = (int)content->ByteLength() - 12; if (strcmp(fourcc, "LZ4 ") == 0) { int outputSize = image_width * image_height * 4; image_data = (unsigned char *)malloc(outputSize); LZ4_decompress_safe((char *)content_data + 12, (char *)image_data, compressedSize, outputSize); image_format = KINC_IMAGE_FORMAT_RGBA32; } else if (strcmp(fourcc, "LZ4F") == 0) { int outputSize = image_width * image_height * 16; image_data = (unsigned char *)malloc(outputSize); LZ4_decompress_safe((char *)content_data + 12, (char *)image_data, compressedSize, outputSize); image_format = KINC_IMAGE_FORMAT_RGBA128; } } else if (ends_with(*format, "hdr")) { int comp; image_data = (unsigned char *)stbi_loadf_from_memory(content_data, content_length, &image_width, &image_height, &comp, 4); image_format = KINC_IMAGE_FORMAT_RGBA128; } else { // jpg, png, .. int comp; image_data = stbi_load_from_memory(content_data, content_length, &image_width, &image_height, &comp, 4); image_format = KINC_IMAGE_FORMAT_RGBA32; } kinc_image_init(image, image_data, image_width, image_height, image_format); kinc_g4_texture_init_from_image(texture, image); if (!readable) { free(image->data); kinc_image_destroy(image); free(image); } Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(readable ? 2 : 1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, texture)); if (readable) obj->SetInternalField(1, External::New(isolate, image)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "width").ToLocalChecked(), Int32::New(isolate, texture->tex_width)); (void) obj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "height").ToLocalChecked(), Int32::New(isolate, texture->tex_height)); args.GetReturnValue().Set(obj); } int format_byte_size(kinc_image_format_t format) { switch (format) { case KINC_IMAGE_FORMAT_RGBA128: return 16; case KINC_IMAGE_FORMAT_RGBA64: return 8; case KINC_IMAGE_FORMAT_RGB24: return 4; case KINC_IMAGE_FORMAT_A32: return 4; case KINC_IMAGE_FORMAT_A16: return 2; case KINC_IMAGE_FORMAT_GREY8: return 1; case KINC_IMAGE_FORMAT_BGRA32: case KINC_IMAGE_FORMAT_RGBA32: default: return 4; } } void runt_get_texture_pixels(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(1)); kinc_image_t *image = (kinc_image_t *)field->Value(); uint8_t *data = kinc_image_get_pixels(image); int byteLength = format_byte_size(image->format) * image->width * image->height * image->depth; std::unique_ptr backing = v8::ArrayBuffer::NewBackingStore((void *)data, byteLength, [](void *, size_t, void *) {}, nullptr); Local buffer = ArrayBuffer::New(isolate, std::move(backing)); args.GetReturnValue().Set(buffer); } void runt_get_render_target_pixels(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)field->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); uint8_t *b = (uint8_t *)content->Data(); kinc_g4_render_target_get_pixels(rt, b); } void runt_lock_texture(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local textureobj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local field = Local::Cast(textureobj->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)field->Value(); uint8_t *tex = kinc_g4_texture_lock(texture); int stride = kinc_g4_texture_stride(texture); (void) textureobj->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "stride").ToLocalChecked(), Int32::New(isolate, stride)); int byteLength = stride * texture->tex_height * texture->tex_depth; std::unique_ptr backing = v8::ArrayBuffer::NewBackingStore((void *)tex, byteLength, [](void *, size_t, void *) {}, nullptr); Local abuffer = ArrayBuffer::New(isolate, std::move(backing)); args.GetReturnValue().Set(abuffer); } void runt_unlock_texture(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)field->Value(); kinc_g4_texture_unlock(texture); } void runt_clear_texture(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)field->Value(); int x = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int y = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int z = args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int width = args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int height = args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int depth = args[6]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int color = args[7]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_g4_texture_clear(texture, x, y, z, width, height, depth, color); } void runt_generate_texture_mipmaps(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)field->Value(); kinc_g4_texture_generate_mipmaps(texture, args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); } void runt_generate_render_target_mipmaps(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)field->Value(); kinc_g4_render_target_generate_mipmaps(rt, args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value()); } void runt_set_mipmaps(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local field = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)field->Value(); Local jsarray = args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); int32_t length = jsarray->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "length").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); for (int32_t i = 0; i < length; ++i) { Local mipmapobj = jsarray->Get(isolate->GetCurrentContext(), i).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "texture_").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local mipmapfield = Local::Cast(mipmapobj->GetInternalField(1)); kinc_image_t *mipmap = (kinc_image_t *)mipmapfield->Value(); kinc_g4_texture_set_mipmap(texture, mipmap, i + 1); } } void runt_set_depth_stencil_from(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local targetfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)targetfield->Value(); Local sourcefield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *source_target = (kinc_g4_render_target_t *)sourcefield->Value(); kinc_g4_render_target_set_depth_stencil_from(render_target, source_target); } void runt_viewport_fast(Local receiver, int x, int y, int w, int h) { kinc_g4_viewport(x, y, w, h); } void runt_viewport(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int x = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); int y = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); int w = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); int h = args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); runt_viewport_fast(args.This(), x, y, w, h); } void runt_scissor_fast(Local receiver, int x, int y, int w, int h) { kinc_g4_scissor(x, y, w, h); } void runt_scissor(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int x = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); int y = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); int w = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); int h = args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); runt_scissor_fast(args.This(), x, y, w, h); } void runt_disable_scissor_fast(Local receiver) { kinc_g4_disable_scissor(); } void runt_disable_scissor(const FunctionCallbackInfo &args) { runt_disable_scissor_fast(args.This()); } int runt_render_targets_inverted_y_fast(Local receiver) { return kinc_g4_render_targets_inverted_y(); } void runt_render_targets_inverted_y(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Int32::New(isolate, runt_render_targets_inverted_y_fast(args.This()))); } void runt_begin(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); if (args[0]->IsNullOrUndefined()) { kinc_g4_restore_render_target(); } else { Local obj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "renderTarget_").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local rtfield = Local::Cast(obj->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); int32_t length = 1; kinc_g4_render_target_t *render_targets[8] = { render_target, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; if (!args[1]->IsNullOrUndefined()) { Local jsarray = args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); length = jsarray->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "length").ToLocalChecked()).ToLocalChecked()->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value() + 1; if (length > 8) length = 8; for (int32_t i = 1; i < length; ++i) { Local artobj = jsarray->Get(isolate->GetCurrentContext(), i - 1).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "renderTarget_").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local artfield = Local::Cast(artobj->GetInternalField(0)); kinc_g4_render_target_t *art = (kinc_g4_render_target_t *)artfield->Value(); render_targets[i] = art; } } kinc_g4_set_render_targets(render_targets, length); } } void runt_begin_face(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local obj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "renderTarget_").ToLocalChecked()).ToLocalChecked()->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local rtfield = Local::Cast(obj->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); int face = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); kinc_g4_set_render_target_face(render_target, face); } void runt_end(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); } void runt_file_save_bytes(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_path(isolate, args[0]); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); bool hasLengthArg = args.Length() > 2 && !args[2]->IsNullOrUndefined(); int byteLength = hasLengthArg ? args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value() : (int)content->ByteLength(); if (byteLength > (int)content->ByteLength()) byteLength = (int)content->ByteLength(); #ifdef KORE_WINDOWS MultiByteToWideChar(CP_UTF8, 0, *utf8_path, -1, temp_wstring, 1024); FILE *file = _wfopen(temp_wstring, L"wb"); #else FILE *file = fopen(*utf8_path, "wb"); #endif if (file == nullptr) return; fwrite(content->Data(), 1, byteLength, file); fclose(file); } int sys_command(const char *cmd) { #ifdef KORE_WINDOWS int wlen = MultiByteToWideChar(CP_UTF8, 0, cmd, -1, NULL, 0); wchar_t *wstr = new wchar_t[wlen]; MultiByteToWideChar(CP_UTF8, 0, cmd, -1, wstr, wlen); int result = _wsystem(wstr); delete[] wstr; #else int result = system(cmd); #endif return result; } void runt_sys_command(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_cmd(isolate, args[0]); int result = sys_command(*utf8_cmd); args.GetReturnValue().Set(Int32::New(isolate, result)); } void runt_save_path(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(String::NewFromUtf8(isolate, kinc_internal_save_path()).ToLocalChecked()); } void runt_get_arg_count(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(Int32::New(isolate, _argc)); } void runt_get_arg(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int index = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(String::NewFromUtf8(isolate, _argv[index]).ToLocalChecked()); } void runt_get_files_location(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); #ifdef KORE_MACOS char path[1024]; strcpy(path, macgetresourcepath()); strcat(path, "/"); strcat(path, KORE_DEBUGDIR); strcat(path, "/"); args.GetReturnValue().Set(String::NewFromUtf8(isolate, path).ToLocalChecked()); #else args.GetReturnValue().Set(String::NewFromUtf8(isolate, kinc_internal_get_files_location()).ToLocalChecked()); #endif } void runt_http_callback(int error, int response, const char *body, void *callbackdata) { #if defined(KORE_MACOS) Locker locker{isolate}; #endif Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); Local context = Local::New(isolate, global_context); Context::Scope context_scope(context); TryCatch try_catch(isolate); Local result; Local argv[1]; RunTCallbackdata *cbd = (RunTCallbackdata *)callbackdata; if (body != NULL) { std::unique_ptr backing = v8::ArrayBuffer::NewBackingStore((void *)body, cbd->size > 0 ? cbd->size : strlen(body), [](void *, size_t, void *) {}, nullptr); argv[0] = ArrayBuffer::New(isolate, std::move(backing)); } Local func = Local::New(isolate, cbd->func); if (!func->Call(context, context->Global(), body != NULL ? 1 : 0, argv).ToLocal(&result)) { handle_exception(&try_catch); } delete cbd; } void runt_http_request(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value url(isolate, args[0]); RunTCallbackdata *cbd = new RunTCallbackdata(); cbd->size = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); Local func = Local::Cast(args[2]); cbd->func.Reset(isolate, func); char url_base[512]; char url_path[512]; const char *curl = *url; int i = 0; for (; i < strlen(curl) - 8; ++i) { if (curl[i + 8] == '/') break; url_base[i] = curl[i + 8]; // Strip https:// } url_base[i] = 0; int j = 0; if (strlen(url_base) < strlen(curl) - 8) ++i; // Skip / for (; j < strlen(curl) - 8 - i; ++j) { if (curl[i + 8 + j] == 0) break; url_path[j] = curl[i + 8 + j]; } url_path[j] = 0; kinc_http_request(url_base, url_path, NULL, 443, true, 0, NULL, &runt_http_callback, cbd); } #ifdef WITH_COMPUTE void runt_set_bool_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); int32_t value = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute_set_bool(*location, value != 0); } void runt_set_int_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); int32_t value = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute_set_int(*location, value); } void runt_set_float_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); float value = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute_set_float(*location, value); } void runt_set_float2_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); float value1 = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value2 = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute_set_float2(*location, value1, value2); } void runt_set_float3_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); float value1 = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value2 = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value3 = (float)args[3]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute_set_float3(*location, value1, value2, value3); } void runt_set_float4_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); float value1 = (float)args[1]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value2 = (float)args[2]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value3 = (float)args[3]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); float value4 = (float)args[4]->ToNumber(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute_set_float4(*location, value1, value2, value3, value4); } void runt_set_floats_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); float *from = (float *)content->Data(); kinc_compute_set_floats(*location, from, int(content->ByteLength() / 4)); } void runt_set_matrix_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); float *from = (float *)content->Data(); kinc_compute_set_matrix4(*location, (kinc_matrix4x4_t *)from); } void runt_set_matrix3_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local locationfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)locationfield->Value(); Local buffer = Local::Cast(args[1]); std::shared_ptr content = buffer->GetBackingStore(); float *from = (float *)content->Data(); kinc_compute_set_matrix3(*location, (kinc_matrix3x3_t *)from); } void runt_set_texture_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); Local texfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)texfield->Value(); int access = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); kinc_compute_set_texture(*unit, texture, (kinc_compute_access_t)access); } void runt_set_render_target_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); Local rtfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); int access = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust(); kinc_compute_set_render_target(*unit, render_target, (kinc_compute_access_t)access); } void runt_set_sampled_texture_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); Local texfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_texture_t *texture = (kinc_g4_texture_t *)texfield->Value(); kinc_compute_set_sampled_texture(*unit, texture); } void runt_set_sampled_render_target_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); Local rtfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); kinc_compute_set_sampled_render_target(*unit, render_target); } void runt_set_sampled_depth_texture_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); Local rtfield = Local::Cast(args[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_g4_render_target_t *render_target = (kinc_g4_render_target_t *)rtfield->Value(); kinc_compute_set_sampled_depth_from_render_target(*unit, render_target); } void runt_set_texture_parameters_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); kinc_compute_set_texture_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_U, (kinc_g4_texture_addressing_t)args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_V, (kinc_g4_texture_addressing_t)args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture_minification_filter(*unit, (kinc_g4_texture_filter_t)args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture_magnification_filter(*unit, (kinc_g4_texture_filter_t)args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture_mipmap_filter(*unit, (kinc_g4_mipmap_filter_t)args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); } void runt_set_texture3d_parameters_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local unitfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)unitfield->Value(); kinc_compute_set_texture3d_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_U, (kinc_g4_texture_addressing_t)args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture3d_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_V, (kinc_g4_texture_addressing_t)args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture3d_addressing(*unit, KINC_G4_TEXTURE_DIRECTION_W, (kinc_g4_texture_addressing_t)args[3]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture3d_minification_filter(*unit, (kinc_g4_texture_filter_t)args[4]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture3d_magnification_filter(*unit, (kinc_g4_texture_filter_t)args[5]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); kinc_compute_set_texture3d_mipmap_filter(*unit, (kinc_g4_mipmap_filter_t)args[6]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).FromJust()); } void runt_set_shader_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local shaderfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_shader *shader = (kinc_compute_shader *)shaderfield->Value(); kinc_compute_set_shader(shader); } void runt_create_shader_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local buffer = Local::Cast(args[0]); std::shared_ptr content = buffer->GetBackingStore(); kinc_compute_shader *shader = (kinc_compute_shader *)malloc(sizeof(kinc_compute_shader)); kinc_compute_shader_init(shader, content->Data(), (int)content->ByteLength()); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetInternalField(0, External::New(isolate, shader)); args.GetReturnValue().Set(obj); } void runt_delete_shader_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local shaderobj = args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked(); Local shaderfield = Local::Cast(shaderobj->GetInternalField(0)); kinc_compute_shader *shader = (kinc_compute_shader *)shaderfield->Value(); kinc_compute_shader_destroy(shader); free(shader); } void runt_get_constant_location_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local shaderfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_shader *shader = (kinc_compute_shader *)shaderfield->Value(); String::Utf8Value utf8_value(isolate, args[1]); kinc_compute_constant_location_t location = kinc_compute_shader_get_constant_location(shader, *utf8_value); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); kinc_compute_constant_location_t *location_copy = (kinc_compute_constant_location_t *)malloc(sizeof(kinc_compute_constant_location_t)); // TODO memcpy(location_copy, &location, sizeof(kinc_compute_constant_location_t)); obj->SetInternalField(0, External::New(isolate, location_copy)); args.GetReturnValue().Set(obj); } void runt_get_texture_unit_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local shaderfield = Local::Cast(args[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked()->GetInternalField(0)); kinc_compute_shader *shader = (kinc_compute_shader *)shaderfield->Value(); String::Utf8Value utf8_value(isolate, args[1]); kinc_compute_texture_unit_t unit = kinc_compute_shader_get_texture_unit(shader, *utf8_value); Local templ = ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); Local obj = templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); kinc_compute_texture_unit_t *unit_copy = (kinc_compute_texture_unit_t *)malloc(sizeof(kinc_compute_texture_unit_t)); // TODO memcpy(unit_copy, &unit, sizeof(kinc_compute_texture_unit_t)); obj->SetInternalField(0, External::New(isolate, unit_copy)); args.GetReturnValue().Set(obj); } void runt_compute(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int x = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int y = args[1]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); int z = args[2]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_compute(x, y, z); } #endif bool window_close_callback(void *data) { return true; } void runt_set_save_and_quit_callback(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); Local arg = args[0]; Local func = Local::Cast(arg); save_and_quit_func.Reset(isolate, func); save_and_quit_func_set = true; kinc_window_set_close_callback(0, window_close_callback, NULL); } void runt_set_mouse_cursor(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int id = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_mouse_set_cursor(id); #ifdef KORE_WINDOWS // Set hand icon for drag even when mouse button is pressed if (id == 1) SetCursor(LoadCursor(NULL, IDC_HAND)); #endif } void runt_delay_idle_sleep_fast(Local receiver) { paused_frames = 0; } void runt_delay_idle_sleep(const FunctionCallbackInfo &args) { runt_delay_idle_sleep_fast(args.This()); } void runt_file_exists(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); bool exists = false; String::Utf8Value utf8_value(isolate, args[0]); kinc_file_reader_t reader; if (kinc_file_reader_open(&reader, *utf8_value, KINC_FILE_TYPE_ASSET)) { exists = true; kinc_file_reader_close(&reader); } args.GetReturnValue().Set(Int32::New(isolate, exists)); } void runt_delete_file(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); String::Utf8Value utf8_value(isolate, args[0]); #if defined(KORE_WINDOWS) char path[1024]; strcpy(path, "del /f \""); strcat(path, *utf8_value); strcat(path, "\""); sys_command(path); #else char path[1024]; strcpy(path, "rm \""); strcat(path, *utf8_value); strcat(path, "\""); sys_command(path); #endif } void runt_window_x(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_window_x(windowId))); } void runt_window_y(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); args.GetReturnValue().Set(Int32::New(isolate, kinc_window_y(windowId))); } void runt_language(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); args.GetReturnValue().Set(String::NewFromUtf8(isolate, kinc_language()).ToLocalChecked()); } void runt_viewport_set_camera(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); float pos_x = (float)args[0]->NumberValue(isolate->GetCurrentContext()).FromMaybe(0.0); float pos_y = (float)args[1]->NumberValue(isolate->GetCurrentContext()).FromMaybe(0.0); float pos_z = (float)args[2]->NumberValue(isolate->GetCurrentContext()).FromMaybe(0.0); float rot_x = (float)args[3]->NumberValue(isolate->GetCurrentContext()).FromMaybe(0.0); float rot_y = (float)args[4]->NumberValue(isolate->GetCurrentContext()).FromMaybe(0.0); float rot_z = (float)args[5]->NumberValue(isolate->GetCurrentContext()).FromMaybe(0.0); float rot_w = (float)args[6]->NumberValue(isolate->GetCurrentContext()).FromMaybe(1.0); viewport_server_set_camera(pos_x, pos_y, pos_z, rot_x, rot_y, rot_z, rot_w); } void runt_window_set_foreground(const FunctionCallbackInfo &args) { HandleScope scope(args.GetIsolate()); int windowId = args[0]->ToInt32(isolate->GetCurrentContext()).ToLocalChecked()->Value(); kinc_window_set_foreground(windowId); } #define SET_FUNCTION_FAST(object, name, fn)\ CFunction fn ## _ = CFunction::Make(fn ## _fast);\ object->Set(String::NewFromUtf8(isolate, name).ToLocalChecked(),\ FunctionTemplate::New(isolate, fn, Local(), Local(), 0,\ v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasNoSideEffect, &fn ## _)) #define SET_FUNCTION(object, name, fn)\ object->Set(String::NewFromUtf8(isolate, name).ToLocalChecked(),\ FunctionTemplate::New(isolate, fn, Local(), Local(), 0,\ v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasNoSideEffect, nullptr)) void start_v8(char *runt_bin, int runt_bin_size) { plat = platform::NewDefaultPlatform(); V8::InitializePlatform(plat.get()); // std::string flags = ""; std::string flags = "--max-old-space-size=1024 --initial-old-space-size=128 --max-semi-space-size=64 " "--gc-interval=100 --optimize-for-size --turbo-fast-api-calls --concurrent-marking " "--parallel-scavenge --use-idle-notification --incremental-marking"; V8::SetFlagsFromString(flags.c_str(), (int)flags.size()); V8::Initialize(); Isolate::CreateParams create_params; create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator(); StartupData blob; if (runt_bin_size > 0) { blob.data = runt_bin; blob.raw_size = runt_bin_size; create_params.snapshot_blob = &blob; } isolate = Isolate::New(create_params); Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); Local runt = ObjectTemplate::New(isolate); SET_FUNCTION(runt, "init", runt_init); SET_FUNCTION(runt, "setApplicationName", runt_set_application_name); SET_FUNCTION(runt, "log", runt_log); SET_FUNCTION_FAST(runt, "clear", runt_clear); SET_FUNCTION(runt, "setCallback", runt_set_callback); SET_FUNCTION(runt, "setDropFilesCallback", runt_set_drop_files_callback); SET_FUNCTION(runt, "setCutCopyPasteCallback", runt_set_cut_copy_paste_callback); //// SET_FUNCTION(runt, "setApplicationStateCallback", runt_set_application_state_callback); SET_FUNCTION(runt, "setKeyboardDownCallback", runt_set_keyboard_down_callback); SET_FUNCTION(runt, "setKeyboardUpCallback", runt_set_keyboard_up_callback); SET_FUNCTION(runt, "setKeyboardPressCallback", runt_set_keyboard_press_callback); SET_FUNCTION(runt, "setMouseDownCallback", runt_set_mouse_down_callback); SET_FUNCTION(runt, "setMouseUpCallback", runt_set_mouse_up_callback); SET_FUNCTION(runt, "setMouseMoveCallback", runt_set_mouse_move_callback); SET_FUNCTION(runt, "setTouchDownCallback", runt_set_touch_down_callback); SET_FUNCTION(runt, "setTouchUpCallback", runt_set_touch_up_callback); SET_FUNCTION(runt, "setTouchMoveCallback", runt_set_touch_move_callback); SET_FUNCTION(runt, "setMouseWheelCallback", runt_set_mouse_wheel_callback); SET_FUNCTION(runt, "setPenDownCallback", runt_set_pen_down_callback); SET_FUNCTION(runt, "setPenUpCallback", runt_set_pen_up_callback); SET_FUNCTION(runt, "setPenMoveCallback", runt_set_pen_move_callback); SET_FUNCTION(runt, "setGamepadAxisCallback", runt_set_gamepad_axis_callback); SET_FUNCTION(runt, "setGamepadButtonCallback", runt_set_gamepad_button_callback); SET_FUNCTION_FAST(runt, "lockMouse", runt_lock_mouse); SET_FUNCTION_FAST(runt, "unlockMouse", runt_unlock_mouse); SET_FUNCTION_FAST(runt, "canLockMouse", runt_can_lock_mouse); SET_FUNCTION_FAST(runt, "isMouseLocked", runt_is_mouse_locked); SET_FUNCTION_FAST(runt, "setMousePosition", runt_set_mouse_position); SET_FUNCTION_FAST(runt, "showMouse", runt_show_mouse); SET_FUNCTION_FAST(runt, "showKeyboard", runt_show_keyboard); SET_FUNCTION(runt, "createIndexBuffer", runt_create_indexbuffer); SET_FUNCTION(runt, "deleteIndexBuffer", runt_delete_indexbuffer); SET_FUNCTION(runt, "lockIndexBuffer", runt_lock_indexbuffer); SET_FUNCTION(runt, "unlockIndexBuffer", runt_unlock_indexbuffer); SET_FUNCTION(runt, "setIndexBuffer", runt_set_indexbuffer); SET_FUNCTION(runt, "createVertexBuffer", runt_create_vertexbuffer); SET_FUNCTION(runt, "deleteVertexBuffer", runt_delete_vertexbuffer); SET_FUNCTION(runt, "lockVertexBuffer", runt_lock_vertex_buffer); SET_FUNCTION(runt, "unlockVertexBuffer", runt_unlock_vertex_buffer); SET_FUNCTION(runt, "setVertexBuffer", runt_set_vertexbuffer); SET_FUNCTION(runt, "setVertexBuffers", runt_set_vertexbuffers); SET_FUNCTION_FAST(runt, "drawIndexedVertices", runt_draw_indexed_vertices); SET_FUNCTION_FAST(runt, "drawIndexedVerticesInstanced", runt_draw_indexed_vertices_instanced); SET_FUNCTION(runt, "createVertexShader", runt_create_vertex_shader); SET_FUNCTION(runt, "createVertexShaderFromSource", runt_create_vertex_shader_from_source); SET_FUNCTION(runt, "createFragmentShader", runt_create_fragment_shader); SET_FUNCTION(runt, "createFragmentShaderFromSource", runt_create_fragment_shader_from_source); SET_FUNCTION(runt, "createGeometryShader", runt_create_geometry_shader); SET_FUNCTION(runt, "createTessellationControlShader", runt_create_tessellation_control_shader); SET_FUNCTION(runt, "createTessellationEvaluationShader", runt_create_tessellation_evaluation_shader); SET_FUNCTION(runt, "deleteShader", runt_delete_shader); SET_FUNCTION(runt, "createPipeline", runt_create_pipeline); SET_FUNCTION(runt, "deletePipeline", runt_delete_pipeline); SET_FUNCTION(runt, "compilePipeline", runt_compile_pipeline); SET_FUNCTION(runt, "setPipeline", runt_set_pipeline); SET_FUNCTION(runt, "loadImage", runt_load_image); SET_FUNCTION(runt, "unloadImage", runt_unload_image); #ifdef WITH_AUDIO SET_FUNCTION(runt, "loadSound", runt_load_sound); SET_FUNCTION(runt, "setAudioCallback", runt_set_audio_callback); SET_FUNCTION(runt, "audioThread", runt_audio_thread); SET_FUNCTION(runt, "writeAudioBuffer", runt_write_audio_buffer); SET_FUNCTION(runt, "getSamplesPerSecond", runt_get_samples_per_second); #endif SET_FUNCTION(runt, "loadBlob", runt_load_blob); SET_FUNCTION(runt, "loadUrl", runt_load_url); SET_FUNCTION(runt, "copyToClipboard", runt_copy_to_clipboard); SET_FUNCTION(runt, "getConstantLocation", runt_get_constant_location); SET_FUNCTION(runt, "getTextureUnit", runt_get_texture_unit); SET_FUNCTION(runt, "setTexture", runt_set_texture); SET_FUNCTION(runt, "setRenderTarget", runt_set_render_target); SET_FUNCTION(runt, "setTextureDepth", runt_set_texture_depth); SET_FUNCTION(runt, "setImageTexture", runt_set_image_texture); SET_FUNCTION(runt, "setTextureParameters", runt_set_texture_parameters); SET_FUNCTION(runt, "setTexture3DParameters", runt_set_texture3d_parameters); SET_FUNCTION(runt, "setTextureCompareMode", runt_set_texture_compare_mode); SET_FUNCTION(runt, "setCubeMapCompareMode", runt_set_cube_map_compare_mode); SET_FUNCTION(runt, "setBool", runt_set_bool); SET_FUNCTION(runt, "setInt", runt_set_int); SET_FUNCTION(runt, "setFloat", runt_set_float); SET_FUNCTION(runt, "setFloat2", runt_set_float2); SET_FUNCTION(runt, "setFloat3", runt_set_float3); SET_FUNCTION(runt, "setFloat4", runt_set_float4); SET_FUNCTION(runt, "setFloats", runt_set_floats); SET_FUNCTION(runt, "setMatrix", runt_set_matrix); SET_FUNCTION(runt, "setMatrix3", runt_set_matrix3); SET_FUNCTION_FAST(runt, "getTime", runt_get_time); SET_FUNCTION_FAST(runt, "windowWidth", runt_window_width); SET_FUNCTION_FAST(runt, "windowHeight", runt_window_height); SET_FUNCTION(runt, "setWindowTitle", runt_set_window_title); SET_FUNCTION(runt, "getWindowMode", runt_get_window_mode); SET_FUNCTION(runt, "setWindowMode", runt_set_window_mode); SET_FUNCTION(runt, "resizeWindow", runt_resize_window); SET_FUNCTION(runt, "moveWindow", runt_move_window); SET_FUNCTION(runt, "screenDpi", runt_screen_dpi); SET_FUNCTION(runt, "systemId", runt_system_id); SET_FUNCTION(runt, "requestShutdown", runt_request_shutdown); SET_FUNCTION(runt, "displayCount", runt_display_count); SET_FUNCTION(runt, "displayWidth", runt_display_width); SET_FUNCTION(runt, "displayHeight", runt_display_height); SET_FUNCTION(runt, "displayX", runt_display_x); SET_FUNCTION(runt, "displayY", runt_display_y); SET_FUNCTION(runt, "displayFrequency", runt_display_frequency); SET_FUNCTION(runt, "displayIsPrimary", runt_display_is_primary); SET_FUNCTION(runt, "writeStorage", runt_write_storage); SET_FUNCTION(runt, "readStorage", runt_read_storage); SET_FUNCTION(runt, "createRenderTarget", runt_create_render_target); SET_FUNCTION(runt, "createRenderTargetCubeMap", runt_create_render_target_cube_map); SET_FUNCTION(runt, "createTexture", runt_create_texture); SET_FUNCTION(runt, "createTexture3D", runt_create_texture3d); SET_FUNCTION(runt, "createTextureFromBytes", runt_create_texture_from_bytes); SET_FUNCTION(runt, "createTextureFromBytes3D", runt_create_texture_from_bytes3d); SET_FUNCTION(runt, "createTextureFromEncodedBytes", runt_create_texture_from_encoded_bytes); SET_FUNCTION(runt, "getTexturePixels", runt_get_texture_pixels); SET_FUNCTION(runt, "getRenderTargetPixels", runt_get_render_target_pixels); SET_FUNCTION(runt, "lockTexture", runt_lock_texture); SET_FUNCTION(runt, "unlockTexture", runt_unlock_texture); SET_FUNCTION(runt, "clearTexture", runt_clear_texture); SET_FUNCTION(runt, "generateTextureMipmaps", runt_generate_texture_mipmaps); SET_FUNCTION(runt, "generateRenderTargetMipmaps", runt_generate_render_target_mipmaps); SET_FUNCTION(runt, "setMipmaps", runt_set_mipmaps); SET_FUNCTION(runt, "setDepthStencilFrom", runt_set_depth_stencil_from); SET_FUNCTION_FAST(runt, "viewport", runt_viewport); SET_FUNCTION_FAST(runt, "scissor", runt_scissor); SET_FUNCTION_FAST(runt, "disableScissor", runt_disable_scissor); SET_FUNCTION_FAST(runt, "renderTargetsInvertedY", runt_render_targets_inverted_y); SET_FUNCTION(runt, "begin", runt_begin); SET_FUNCTION(runt, "beginFace", runt_begin_face); SET_FUNCTION(runt, "end", runt_end); SET_FUNCTION(runt, "fileSaveBytes", runt_file_save_bytes); SET_FUNCTION(runt, "sysCommand", runt_sys_command); SET_FUNCTION(runt, "savePath", runt_save_path); SET_FUNCTION(runt, "getArgCount", runt_get_arg_count); SET_FUNCTION(runt, "getArg", runt_get_arg); SET_FUNCTION(runt, "getFilesLocation", runt_get_files_location); SET_FUNCTION(runt, "httpRequest", runt_http_request); SET_FUNCTION(runt, "viewportSetCamera", runt_viewport_set_camera); SET_FUNCTION(runt, "windowSetForeground", runt_window_set_foreground); #ifdef WITH_NETWORKING SET_FUNCTION(runt, "socketCreate", v8_runt_socket_create); SET_FUNCTION(runt, "socketBind", v8_runt_socket_bind); SET_FUNCTION(runt, "socketListen", v8_runt_socket_listen); SET_FUNCTION(runt, "socketAccept", v8_runt_socket_accept); SET_FUNCTION(runt, "socketConnect", v8_runt_socket_connect); SET_FUNCTION(runt, "socketSend", v8_runt_socket_send); SET_FUNCTION(runt, "socketRecv", v8_runt_socket_recv); SET_FUNCTION(runt, "socketClose", v8_runt_socket_close); SET_FUNCTION(runt, "socketSetBlocking", v8_runt_socket_set_blocking); SET_FUNCTION(runt, "socketSelect", v8_runt_socket_select); SET_FUNCTION(runt, "socketIsConnected", v8_runt_socket_is_connected); #ifdef WITH_SSL SET_FUNCTION(runt, "socketEnableSsl", v8_runt_socket_enable_ssl); #endif SET_FUNCTION(runt, "websocketCreate", runt_websocket_create); SET_FUNCTION(runt, "websocketSend", runt_websocket_send); SET_FUNCTION(runt, "websocketSendBinary", runt_websocket_send_binary); SET_FUNCTION(runt, "websocketClose", runt_websocket_close); SET_FUNCTION(runt, "websocketGetReadyState", runt_websocket_get_ready_state); SET_FUNCTION(runt, "websocketGetUrl", runt_websocket_get_url); SET_FUNCTION(runt, "websocketGetBufferedAmount", runt_websocket_get_buffered_amount); SET_FUNCTION(runt, "websocketSetOnOpen", runt_websocket_set_onopen); SET_FUNCTION(runt, "websocketSetOnMessage", runt_websocket_set_onmessage); SET_FUNCTION(runt, "websocketSetOnError", runt_websocket_set_onerror); SET_FUNCTION(runt, "websocketSetOnClose", runt_websocket_set_onclose); SET_FUNCTION(runt, "websocketServerCreate", v8_runt_websocket_server_create); SET_FUNCTION(runt, "websocketServerStart", v8_runt_websocket_server_start); SET_FUNCTION(runt, "websocketServerStop", v8_runt_websocket_server_stop); SET_FUNCTION(runt, "websocketServerTick", v8_runt_websocket_server_tick); SET_FUNCTION(runt, "websocketServerSendAll", v8_runt_websocket_server_send_all); SET_FUNCTION(runt, "websocketServerSendClient", v8_runt_websocket_server_send_client); SET_FUNCTION(runt, "httpRequestCreate", runt_httprequest_create); SET_FUNCTION(runt, "httpRequestOpen", runt_httprequest_open); SET_FUNCTION(runt, "httpRequestSend", runt_httprequest_send); SET_FUNCTION(runt, "httpRequestAbort", runt_httprequest_abort); SET_FUNCTION(runt, "httpRequestSetRequestHeader", runt_httprequest_set_request_header); SET_FUNCTION(runt, "httpRequestGetAllResponseHeaders", runt_httprequest_get_all_response_headers); SET_FUNCTION(runt, "httpRequestGetResponseHeader", runt_httprequest_get_response_header); SET_FUNCTION(runt, "httpRequestGetReadyState", runt_httprequest_get_ready_state); SET_FUNCTION(runt, "httpRequestGetStatus", runt_httprequest_get_status); SET_FUNCTION(runt, "httpRequestGetStatusText", runt_httprequest_get_status_text); SET_FUNCTION(runt, "httpRequestGetResponseText", runt_httprequest_get_response_text); SET_FUNCTION(runt, "httpRequestGetResponseURL", runt_httprequest_get_response_url); SET_FUNCTION(runt, "httpRequestSetTimeout", runt_httprequest_set_timeout); SET_FUNCTION(runt, "httpRequestSetResponseType", runt_httprequest_set_response_type); SET_FUNCTION(runt, "httpRequestSetWithCredentials", runt_httprequest_set_with_credentials); SET_FUNCTION(runt, "httpRequestSetOnReadyStateChange", runt_httprequest_set_onreadystatechange); SET_FUNCTION(runt, "httpRequestSetOnLoad", runt_httprequest_set_onload); SET_FUNCTION(runt, "httpRequestSetOnError", runt_httprequest_set_onerror); SET_FUNCTION(runt, "httpRequestSetOnTimeout", runt_httprequest_set_ontimeout); SET_FUNCTION(runt, "httpRequestSetOnAbort", runt_httprequest_set_onabort); SET_FUNCTION(runt, "httpRequestSetOnProgress", runt_httprequest_set_onprogress); SET_FUNCTION(runt, "httpRequestSetOnLoadStart", runt_httprequest_set_onloadstart); SET_FUNCTION(runt, "httpRequestSetOnLoadEnd", runt_httprequest_set_onloadend); #endif #ifdef WITH_COMPUTE SET_FUNCTION(runt, "setBoolCompute", runt_set_bool_compute); SET_FUNCTION(runt, "setIntCompute", runt_set_int_compute); SET_FUNCTION(runt, "setFloatCompute", runt_set_float_compute); SET_FUNCTION(runt, "setFloat2Compute", runt_set_float2_compute); SET_FUNCTION(runt, "setFloat3Compute", runt_set_float3_compute); SET_FUNCTION(runt, "setFloat4Compute", runt_set_float4_compute); SET_FUNCTION(runt, "setFloatsCompute", runt_set_floats_compute); SET_FUNCTION(runt, "setMatrixCompute", runt_set_matrix_compute); SET_FUNCTION(runt, "setMatrix3Compute", runt_set_matrix3_compute); SET_FUNCTION(runt, "setTextureCompute", runt_set_texture_compute); SET_FUNCTION(runt, "setRenderTargetCompute", runt_set_render_target_compute); SET_FUNCTION(runt, "setSampledTextureCompute", runt_set_sampled_texture_compute); SET_FUNCTION(runt, "setSampledRenderTargetCompute", runt_set_sampled_render_target_compute); SET_FUNCTION(runt, "setSampledDepthTextureCompute", runt_set_sampled_depth_texture_compute); SET_FUNCTION(runt, "setTextureParametersCompute", runt_set_texture_parameters_compute); SET_FUNCTION(runt, "setTexture3DParametersCompute", runt_set_texture3d_parameters_compute); SET_FUNCTION(runt, "setShaderCompute", runt_set_shader_compute); SET_FUNCTION(runt, "deleteShaderCompute", runt_delete_shader_compute); SET_FUNCTION(runt, "createShaderCompute", runt_create_shader_compute); SET_FUNCTION(runt, "getConstantLocationCompute", runt_get_constant_location_compute); SET_FUNCTION(runt, "getTextureUnitCompute", runt_get_texture_unit_compute); SET_FUNCTION(runt, "compute", runt_compute); #endif SET_FUNCTION(runt, "setSaveAndQuitCallback", runt_set_save_and_quit_callback); SET_FUNCTION(runt, "setMouseCursor", runt_set_mouse_cursor); SET_FUNCTION_FAST(runt, "delayIdleSleep", runt_delay_idle_sleep); SET_FUNCTION(runt, "fileExists", runt_file_exists); SET_FUNCTION(runt, "deleteFile", runt_delete_file); SET_FUNCTION(runt, "windowX", runt_window_x); SET_FUNCTION(runt, "windowY", runt_window_y); SET_FUNCTION(runt, "language", runt_language); Local global = ObjectTemplate::New(isolate); global->Set(String::NewFromUtf8(isolate, "RunT").ToLocalChecked(), runt); global->Set(String::NewFromUtf8(isolate, "runt").ToLocalChecked(), runt); // lowercase alias for JavaScript compatibility // additional common APIs Local window_template = ObjectTemplate::New(isolate); window_template->Set(String::NewFromUtf8(isolate, "innerWidth").ToLocalChecked(), Integer::New(isolate, kinc_window_width(0))); window_template->Set(String::NewFromUtf8(isolate, "innerHeight").ToLocalChecked(), Integer::New(isolate, kinc_window_height(0))); window_template->Set(String::NewFromUtf8(isolate, "devicePixelRatio").ToLocalChecked(), Number::New(isolate, 1.0)); global->Set(String::NewFromUtf8(isolate, "window").ToLocalChecked(), window_template); global->Set(String::NewFromUtf8(isolate, "global").ToLocalChecked(), window_template); global->Set(String::NewFromUtf8(isolate, "globalThis").ToLocalChecked(), window_template); Local console_template = ObjectTemplate::New(isolate); console_template->Set(String::NewFromUtf8(isolate, "log").ToLocalChecked(), FunctionTemplate::New(isolate, runt_log)); console_template->Set(String::NewFromUtf8(isolate, "warn").ToLocalChecked(), FunctionTemplate::New(isolate, runt_log)); console_template->Set(String::NewFromUtf8(isolate, "error").ToLocalChecked(), FunctionTemplate::New(isolate, runt_log)); console_template->Set(String::NewFromUtf8(isolate, "info").ToLocalChecked(), FunctionTemplate::New(isolate, runt_log)); console_template->Set(String::NewFromUtf8(isolate, "debug").ToLocalChecked(), FunctionTemplate::New(isolate, runt_log)); global->Set(String::NewFromUtf8(isolate, "console").ToLocalChecked(), console_template); window_template->Set(String::NewFromUtf8(isolate, "console").ToLocalChecked(), console_template); #ifdef WITH_NETWORKING setupNativeWebSocketClass(isolate, global); setupNativeEventClasses(isolate, global); setupNativeXMLHttpRequestClass(isolate, global); #endif Local context = Context::New(isolate, NULL, global); global_context.Reset(isolate, context); // needs self scope to add more browser APIs { Context::Scope context_scope(context); Local global_obj = context->Global(); Local window_obj = global_obj->Get(context, String::NewFromUtf8(isolate, "window").ToLocalChecked()).ToLocalChecked(); if (window_obj->IsObject()) { Local window = window_obj->ToObject(context).ToLocalChecked(); window->Set(context, String::NewFromUtf8(isolate, "window").ToLocalChecked(), window); window->Set(context, String::NewFromUtf8(isolate, "self").ToLocalChecked(), window); window->Set(context, String::NewFromUtf8(isolate, "top").ToLocalChecked(), window); window->Set(context, String::NewFromUtf8(isolate, "parent").ToLocalChecked(), window); Local location = Object::New(isolate); location->Set(context, String::NewFromUtf8(isolate, "href").ToLocalChecked(), String::NewFromUtf8(isolate, "runt://localhost/").ToLocalChecked()); location->Set(context, String::NewFromUtf8(isolate, "origin").ToLocalChecked(), String::NewFromUtf8(isolate, "runt://localhost").ToLocalChecked()); location->Set(context, String::NewFromUtf8(isolate, "protocol").ToLocalChecked(), String::NewFromUtf8(isolate, "runt:").ToLocalChecked()); location->Set(context, String::NewFromUtf8(isolate, "host").ToLocalChecked(), String::NewFromUtf8(isolate, "localhost").ToLocalChecked()); location->Set(context, String::NewFromUtf8(isolate, "hostname").ToLocalChecked(), String::NewFromUtf8(isolate, "localhost").ToLocalChecked()); window->Set(context, String::NewFromUtf8(isolate, "location").ToLocalChecked(), location); Local navigator = Object::New(isolate); navigator->Set(context, String::NewFromUtf8(isolate, "userAgent").ToLocalChecked(), String::NewFromUtf8(isolate, "RunT/1.0").ToLocalChecked()); navigator->Set(context, String::NewFromUtf8(isolate, "platform").ToLocalChecked(), String::NewFromUtf8(isolate, "RunT").ToLocalChecked()); window->Set(context, String::NewFromUtf8(isolate, "navigator").ToLocalChecked(), navigator); Local document = Object::New(isolate); document->Set(context, String::NewFromUtf8(isolate, "title").ToLocalChecked(), String::NewFromUtf8(isolate, "Leenkx Application").ToLocalChecked()); window->Set(context, String::NewFromUtf8(isolate, "document").ToLocalChecked(), document); window->Set(context, String::NewFromUtf8(isolate, "localStorage").ToLocalChecked(), Null(isolate)); window->Set(context, String::NewFromUtf8(isolate, "sessionStorage").ToLocalChecked(), Null(isolate)); window->Set(context, String::NewFromUtf8(isolate, "indexedDB").ToLocalChecked(), Null(isolate)); window->Set(context, String::NewFromUtf8(isolate, "setTimeout").ToLocalChecked(), Function::New(context, runt_set_timeout).ToLocalChecked()).Check(); window->Set(context, String::NewFromUtf8(isolate, "clearTimeout").ToLocalChecked(), Function::New(context, runt_clear_timeout).ToLocalChecked()).Check(); window->Set(context, String::NewFromUtf8(isolate, "setInterval").ToLocalChecked(), Function::New(context, runt_set_interval).ToLocalChecked()).Check(); window->Set(context, String::NewFromUtf8(isolate, "clearInterval").ToLocalChecked(), Function::New(context, runt_clear_interval).ToLocalChecked()).Check(); global_obj->Set(context, String::NewFromUtf8(isolate, "location").ToLocalChecked(), location); global_obj->Set(context, String::NewFromUtf8(isolate, "navigator").ToLocalChecked(), navigator); global_obj->Set(context, String::NewFromUtf8(isolate, "document").ToLocalChecked(), document); global_obj->Set(context, String::NewFromUtf8(isolate, "setTimeout").ToLocalChecked(), Function::New(context, runt_set_timeout).ToLocalChecked()).Check(); global_obj->Set(context, String::NewFromUtf8(isolate, "clearTimeout").ToLocalChecked(), Function::New(context, runt_clear_timeout).ToLocalChecked()).Check(); global_obj->Set(context, String::NewFromUtf8(isolate, "setInterval").ToLocalChecked(), Function::New(context, runt_set_interval).ToLocalChecked()).Check(); global_obj->Set(context, String::NewFromUtf8(isolate, "clearInterval").ToLocalChecked(), Function::New(context, runt_clear_interval).ToLocalChecked()).Check(); } } #ifdef WITH_NETWORKING WebSocketWrapper::initialize(); //kinc_log(KINC_LOG_LEVEL_INFO, "WebSocket client support initialized successfully"); HttpRequestWrapper::initialize(); //kinc_log(KINC_LOG_LEVEL_INFO, "Initializing native HTTP request support"); #endif } void start_runt(char *scriptfile) { Locker locker{isolate}; Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); Local context = Local::New(isolate, global_context); Context::Scope context_scope(context); if (scriptfile != NULL) { Local source = String::NewFromUtf8(isolate, scriptfile, NewStringType::kNormal).ToLocalChecked(); TryCatch try_catch(isolate); Local