From 0fe4f5133052b6778dc8679c42ca6b8daaeccbde Mon Sep 17 00:00:00 2001 From: Alexander Klingenbeck Date: Sat, 13 May 2023 14:49:05 +0200 Subject: [PATCH] Add a lot of bindings --- bindings/src/index.ts | 189 ++++- bindings/src/quickjs.ts | 24 +- bindings/src/raylib-header.ts | 6 +- examples/2d_camera.js | 89 ++- generate-bindings.js | 208 ++++- src/bindings/js_raylib_core.h | 1341 ++++++++++++++++++++++++++++++++- 6 files changed, 1744 insertions(+), 113 deletions(-) diff --git a/bindings/src/index.ts b/bindings/src/index.ts index a8de41f..3803419 100644 --- a/bindings/src/index.ts +++ b/bindings/src/index.ts @@ -33,28 +33,207 @@ function main(){ }, createConstructor: true }) + core_gen.addApiStructByName("Vector3", { + properties: { + x: { get: true, set: true }, + y: { get: true, set: true }, + z: { get: true, set: true }, + }, + createConstructor: true + }) + core_gen.addApiStructByName("Ray", { + properties: { + position: { get: false, set: true }, + direction: { get: false, set: true }, + }, + createConstructor: true + }) + core_gen.addApiStructByName("Camera2D",{ + properties: { + offset: { get: false, set: true }, + target: { get: false, set: true }, + rotation: { get: true, set: true }, + zoom: { get: true, set: true }, + }, + createConstructor: true + }) + core_gen.addApiStructByName("Matrix",{ + properties: {}, + createConstructor: false + }) + // Window-related functions + core_gen.addApiFunctionByName("InitWindow") + core_gen.addApiFunctionByName("WindowShouldClose") + core_gen.addApiFunctionByName("CloseWindow") + core_gen.addApiFunctionByName("IsWindowReady") + core_gen.addApiFunctionByName("IsWindowFullscreen") + core_gen.addApiFunctionByName("IsWindowHidden") + core_gen.addApiFunctionByName("IsWindowMinimized") + core_gen.addApiFunctionByName("IsWindowMaximized") + core_gen.addApiFunctionByName("IsWindowFocused") + core_gen.addApiFunctionByName("IsWindowResized") + core_gen.addApiFunctionByName("IsWindowState") + core_gen.addApiFunctionByName("SetWindowState") + core_gen.addApiFunctionByName("ClearWindowState") + core_gen.addApiFunctionByName("ToggleFullscreen") + core_gen.addApiFunctionByName("MaximizeWindow") + core_gen.addApiFunctionByName("MinimizeWindow") + core_gen.addApiFunctionByName("RestoreWindow") + // SetWindowIcon + // SetWindowIcons core_gen.addApiFunctionByName("SetWindowTitle") core_gen.addApiFunctionByName("SetWindowPosition") + core_gen.addApiFunctionByName("SetWindowMonitor") + core_gen.addApiFunctionByName("SetWindowMinSize") + core_gen.addApiFunctionByName("SetWindowSize") + core_gen.addApiFunctionByName("SetWindowOpacity") + // GetWindowHandle + core_gen.addApiFunctionByName("GetScreenWidth") + core_gen.addApiFunctionByName("GetScreenHeight") + core_gen.addApiFunctionByName("GetRenderWidth") + core_gen.addApiFunctionByName("GetRenderHeight") + core_gen.addApiFunctionByName("GetMonitorCount") + core_gen.addApiFunctionByName("GetCurrentMonitor") + core_gen.addApiFunctionByName("GetMonitorPosition") + core_gen.addApiFunctionByName("GetMonitorWidth") + core_gen.addApiFunctionByName("GetMonitorHeight") + core_gen.addApiFunctionByName("GetMonitorPhysicalWidth") + core_gen.addApiFunctionByName("GetMonitorPhysicalHeight") + core_gen.addApiFunctionByName("GetMonitorRefreshRate") + core_gen.addApiFunctionByName("GetWindowPosition") + core_gen.addApiFunctionByName("GetWindowScaleDPI") + core_gen.addApiFunctionByName("GetMonitorName") + core_gen.addApiFunctionByName("SetClipboardText") + core_gen.addApiFunctionByName("GetClipboardText") + core_gen.addApiFunctionByName("EnableEventWaiting") + core_gen.addApiFunctionByName("DisableEventWaiting") + + // Custom frame control functions + // NOT SUPPORTED BECAUSE NEEDS COMPILER FLAG + + // Cursor-related functions + core_gen.addApiFunctionByName("ShowCursor") + core_gen.addApiFunctionByName("HideCursor") + core_gen.addApiFunctionByName("IsCursorHidden") + core_gen.addApiFunctionByName("EnableCursor") + core_gen.addApiFunctionByName("DisableCursor") + core_gen.addApiFunctionByName("IsCursorOnScreen") + + // Drawing related functions + core_gen.addApiFunctionByName("ClearBackground") core_gen.addApiFunctionByName("BeginDrawing") core_gen.addApiFunctionByName("EndDrawing", null, { before: fun => fun.call("app_update_quickjs", []) }) - core_gen.addApiFunctionByName("InitWindow") + core_gen.addApiFunctionByName("BeginMode2D") + core_gen.addApiFunctionByName("EndMode2D") + //core_gen.addApiFunctionByName("BeginMode3D") + //core_gen.addApiFunctionByName("EndMode3D") + //core_gen.addApiFunctionByName("BeginTextureMode") + //core_gen.addApiFunctionByName("EndTextureMode") + //core_gen.addApiFunctionByName("BeginShaderMode") + //core_gen.addApiFunctionByName("EndShaderMode") + core_gen.addApiFunctionByName("BeginBlendMode") + core_gen.addApiFunctionByName("EndBlendMode") + core_gen.addApiFunctionByName("BeginScissorMode") + core_gen.addApiFunctionByName("EndScissorMode") + //core_gen.addApiFunctionByName("BeginVrStereoMode") + //core_gen.addApiFunctionByName("EndVrStereoMode") + + // VR Stereo config options + //core_gen.addApiFunctionByName("LoadVrStereoConfig") + //core_gen.addApiFunctionByName("UnloadVrStereoConfig") + + // Shader Management + // core_gen.addApiFunctionByName("LoadShader") + // core_gen.addApiFunctionByName("LoadShaderFromMemory") + // core_gen.addApiFunctionByName("IsShaderReady") + // core_gen.addApiFunctionByName("GetShaderLocation") + // core_gen.addApiFunctionByName("GetShaderLocationAttrib") + // core_gen.addApiFunctionByName("SetShaderValue") + // core_gen.addApiFunctionByName("SetShaderValueV") + // core_gen.addApiFunctionByName("SetShaderValueMatrix") + // core_gen.addApiFunctionByName("SetShaderValueTexture") + // // "UnloadShader" is destructor + + // ScreenSpaceRelatedFunctions + //core_gen.addApiFunctionByName("GetMouseRay") + //core_gen.addApiFunctionByName("GetCameraMatrix") + core_gen.addApiFunctionByName("GetCameraMatrix2D") + //core_gen.addApiFunctionByName("GetWorldToScreen") + core_gen.addApiFunctionByName("GetScreenToWorld2D") + //core_gen.addApiFunctionByName("GetScreenToWorldEx") + core_gen.addApiFunctionByName("GetWorldToScreen2D") + + // Timing related functions core_gen.addApiFunctionByName("SetTargetFPS") - core_gen.addApiFunctionByName("WindowShouldClose") - core_gen.addApiFunctionByName("ClearBackground") - core_gen.addApiFunctionByName("CloseWindow") + core_gen.addApiFunctionByName("GetFPS") + core_gen.addApiFunctionByName("GetFrameTime") + core_gen.addApiFunctionByName("GetTime") + + // Misc functions + core_gen.addApiFunctionByName("GetRandomValue") + core_gen.addApiFunctionByName("SetRandomSeed") + core_gen.addApiFunctionByName("TakeScreenshot") + core_gen.addApiFunctionByName("SetConfigFlags") + + const traceLog = apiDesc.getFunction("TraceLog") + if(!traceLog) throw new Error("TraceLog not found") + traceLog.params.pop() + core_gen.addApiFunction(traceLog) + core_gen.addApiFunctionByName("SetTraceLogLevel") + // Memory functions not supported on JS + core_gen.addApiFunctionByName("OpenURL") + + // Callbacks not supported on JS + + // Files management functions + //core_gen.addApiFunctionByName("LoadFileData") + //core_gen.addApiFunctionByName("UnloadLoadFileData") + //core_gen.addApiFunctionByName("SaveFileData") + // Export data as code not needed + core_gen.addApiFunctionByName("LoadFileText", null, { after: gen => gen.call("UnloadFileText", ["returnVal"]) }) + core_gen.addApiFunctionByName("SaveFileText") + core_gen.addApiFunctionByName("FileExists") + core_gen.addApiFunctionByName("DirectoryExists") + core_gen.addApiFunctionByName("IsFileExtension") + // TODO: Who needs to clean memory here? + core_gen.addApiFunctionByName("GetFileLength") + core_gen.addApiFunctionByName("GetFileExtension") + core_gen.addApiFunctionByName("GetFileName") + core_gen.addApiFunctionByName("GetFileNameWithoutExt") + core_gen.addApiFunctionByName("GetDirectoryPath") + core_gen.addApiFunctionByName("GetPrevDirectoryPath") + core_gen.addApiFunctionByName("GetWorkingDirectory") + core_gen.addApiFunctionByName("GetApplicationDirectory") + core_gen.addApiFunctionByName("ChangeDirectory") + core_gen.addApiFunctionByName("IsPathFile") + //core_gen.addApiFunctionByName("LoadPathFiles") + //core_gen.addApiFunctionByName("LoadPathFilesEx") + // UnloadDirectoryFiles + core_gen.addApiFunctionByName("IsFileDropped") + //core_gen.addApiFunctionByName("LoadDroppedFiles") + // UnloadDroppedFiles + core_gen.addApiFunctionByName("GetFileModTime") + core_gen.addApiFunctionByName("DrawText") + core_gen.addApiFunctionByName("DrawLine") core_gen.addApiFunctionByName("DrawCircleV") core_gen.addApiFunctionByName("IsKeyDown") + core_gen.addApiFunctionByName("IsKeyPressed") core_gen.addApiFunctionByName("GetMousePosition") core_gen.addApiFunctionByName("IsMouseButtonPressed") core_gen.addApiFunctionByName("GetMouseWheelMove") core_gen.addApiFunctionByName("DrawRectangle") - core_gen.addApiFunctionByName("GetRandomValue") + core_gen.addApiFunctionByName("DrawRectangleRec") + core_gen.addApiFunctionByName("DrawRectangleLines") + core_gen.addApiFunctionByName("Fade") api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => { core_gen.exportGlobalStruct("Color", x.name, x.values) }) api.enums.find(x => x.name === "KeyboardKey")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)) api.enums.find(x => x.name === "MouseButton")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)) + api.enums.find(x => x.name === "ConfigFlags")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)) + api.enums.find(x => x.name === "BlendMode")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)) + api.enums.find(x => x.name === "TraceLogLevel")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)) core_gen.writeTo("src/bindings/js_raylib_core.h") const texture_gen = new RayLibHeader("raylib_texture", apiDesc) diff --git a/bindings/src/quickjs.ts b/bindings/src/quickjs.ts index 980b47a..8020039 100644 --- a/bindings/src/quickjs.ts +++ b/bindings/src/quickjs.ts @@ -79,7 +79,8 @@ export abstract class GenericQuickJsGenerator extend jsToC(type: string, name: string, src: string, classIds: StructLookup = {}){ switch (type) { case "const char *": - this.statement(`${type} ${name} = JS_ToCString(ctx, ${src})`) + case "char *": + this.statement(`${type} ${name} = JS_ToCString(ctx, (const char *)${src})`) this.statement(`if(${name} == NULL) return JS_EXCEPTION`) break; case "float": @@ -88,8 +89,9 @@ export abstract class GenericQuickJsGenerator extend this.statement(`${type} ${name} = (${type})_double_${name}`) break; case "int": + case "unsigned int": this.statement(`${type} ${name}`) - this.statement(`JS_ToInt32(ctx, &${name}, ${src})`) + this.statement(`JS_ToInt32(ctx, (int *)&${name}, ${src})`) break; case "unsigned char": this.statement("int _int_"+name) @@ -109,14 +111,20 @@ export abstract class GenericQuickJsGenerator extend switch (type) { case "int": case "unsigned char": + case "long": this.declare(name,'JSValue', false, `JS_NewInt32(ctx, ${src})`) break; case "bool": this.declare(name, 'JSValue', false, `JS_NewBool(ctx, ${src})`) break; case "float": + case "double": this.declare(name, 'JSValue', false, `JS_NewFloat64(ctx, ${src})`) break; + case "const char *": + case "char *": + this.declare(name, 'JSValue', false, `JS_NewString(ctx, ${src})`) + break; default: const classId = classIds[type] if(!classId) throw new Error("Cannot convert parameter type to Javascript: " + type) @@ -196,7 +204,7 @@ export abstract class GenericQuickJsGenerator extend return body } - jsStructGetter(structName: string, classId: string, field: string, type: string){ + jsStructGetter(structName: string, classId: string, field: string, type: string, classIds: StructLookup){ const args = [{type: "JSContext*", name: "ctx" }, {type: "JSValueConst", name: "this_val"}] const fun = this.function(`js_${structName}_get_${field}`,"JSValue",args,true) fun.declare("ptr", structName+"*", false, `JS_GetOpaque2(ctx, this_val, ${classId})`) @@ -204,19 +212,19 @@ export abstract class GenericQuickJsGenerator extend cond.returnExp("JS_EXCEPTION") }) fun.declare(field, type, false, "ptr->"+field) - fun.jsToJs(type, "ret", field) + fun.jsToJs(type, "ret", field, classIds) fun.returnExp("ret") return fun } - jsStructSetter(structName: string, classId: string, field: string, type: string){ + jsStructSetter(structName: string, classId: string, field: string, type: string, classIds: StructLookup){ const args = [{type: "JSContext*", name: "ctx" }, {type: "JSValueConst", name: "this_val"},{type: "JSValueConst", name: "v"}] const fun = this.function(`js_${structName}_set_${field}`,"JSValue",args,true) fun.declare("ptr", structName+"*", false, `JS_GetOpaque2(ctx, this_val, ${classId})`) fun.if("!ptr", cond => { cond.returnExp("JS_EXCEPTION") }) - fun.jsToC(type, "value", "v"); + fun.jsToC(type, "value", "v", classIds); fun.statement("ptr->"+field+" = value") fun.returnExp("JS_UNDEFINED") return fun @@ -226,11 +234,11 @@ export abstract class GenericQuickJsGenerator extend this.declare(structVar, structType+"*", false, `(${structType}*)JS_GetOpaque2(ctx, ${srcVar}, ${classId})`) } - jsStructConstructor(structName: string, fields: FunctionArgument[], classId: string){ + jsStructConstructor(structName: string, fields: FunctionArgument[], classId: string, classIds: StructLookup){ const body = this.jsBindingFunction(structName + "_constructor") for (let i = 0; i < fields.length; i++) { const para = fields[i] - body.jsToC(para.type,para.name,"argv["+i+"]") + body.jsToC(para.type,para.name,"argv["+i+"]", classIds) } body.declareStruct(structName, "_struct", fields.map(x => x.name)) body.jsStructToOpq(structName,"_return","_struct", classId) diff --git a/bindings/src/raylib-header.ts b/bindings/src/raylib-header.ts index e5d5c06..664921b 100644 --- a/bindings/src/raylib-header.ts +++ b/bindings/src/raylib-header.ts @@ -70,8 +70,8 @@ export class RayLibHeader extends QuickJsHeader { const el = options.properties[field] let _get: CodeGenerator | undefined = undefined let _set: CodeGenerator | undefined = undefined - if(el.get) _get = this.structs.jsStructGetter(struct.name, classId, field, type) - if(el.set) _set = this.structs.jsStructSetter(struct.name, classId, field, type) + if(el.get) _get = this.structs.jsStructGetter(struct.name, classId, field, type, /*Be carefull when allocating memory in a getter*/{}) + if(el.set) _set = this.structs.jsStructSetter(struct.name, classId, field, type, this.structLookup) propDeclarations.jsGetSetDef(field, _get?.getTag("_name"), _set?.getTag("_name")) } } @@ -84,7 +84,7 @@ export class RayLibHeader extends QuickJsHeader { this.moduleInit.call(classDecl.getTag("_name"), ["ctx", "m"]) if(options?.createConstructor){ - const body = this.functions.jsStructConstructor(struct.name, struct.fields, classId) + const body = this.functions.jsStructConstructor(struct.name, struct.fields, classId, this.structLookup) this.moduleInit.statement(`JSValue ${struct.name}_constr = JS_NewCFunction2(ctx, ${body.getTag("_name")},"${struct.name})", ${struct.fields.length}, JS_CFUNC_constructor_or_func, 0)`) this.moduleInit.call("JS_SetModuleExport", ["ctx","m", `"${struct.name}"`, struct.name+"_constr"]) diff --git a/examples/2d_camera.js b/examples/2d_camera.js index 95db2cc..e8c5451 100644 --- a/examples/2d_camera.js +++ b/examples/2d_camera.js @@ -16,99 +16,98 @@ let spacing = 0; for (let i = 0; i < MAX_BUILDINGS; i++) { - buildings[i].width = rlc.getRandomValue(50, 200); - buildings[i].height = rlc.getRandomValue(100, 800); - buildings[i].y = screenHeight - 130.0 - buildings[i].height; - buildings[i].x = -6000.0 + spacing; + const height = rlc.getRandomValue(100, 800) + buildings[i] = new rlc.Rectangle( + -6000.0 + spacing, + screenHeight - 130.0 - height, + rlc.getRandomValue(50, 200), + height) spacing += buildings[i].width; buildColors[i] = new rlc.Color(rlc.getRandomValue(200, 240), rlc.getRandomValue(200, 240), rlc.getRandomValue(200, 250), 255); } -Camera2D camera = { 0 }; -camera.target = (Vector2){ player.x + 20.0f, player.y + 20.0f }; -camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f }; -camera.rotation = 0.0f; -camera.zoom = 1.0f; +const camera = new rlc.Camera2D(new rlc.Vector2(screenWidth/2.0, screenHeight/2.0),new rlc.Vector2(player.x + 20.0, player.y + 20.0), 0, 1) -SetTargetFPS(60); // Set our game to run at 60 frames-per-second +rlc.setTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop -while (!WindowShouldClose()) // Detect window close button or ESC key +while (!rlc.windowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- // Player movement - if (IsKeyDown(KEY_RIGHT)) player.x += 2; - else if (IsKeyDown(KEY_LEFT)) player.x -= 2; + if (rlc.isKeyDown(rlc.KEY_RIGHT)) player.x += 2; + else if (rlc.isKeyDown(rlc.KEY_LEFT)) player.x -= 2; // Camera target follows player - camera.target = (Vector2){ player.x + 20, player.y + 20 }; + const cameraTarget = new rlc.Vector2(player.x + 20, player.y + 20); + camera.target = cameraTarget; // Camera rotation controls - if (IsKeyDown(KEY_A)) camera.rotation--; - else if (IsKeyDown(KEY_S)) camera.rotation++; + if (rlc.isKeyDown(rlc.KEY_A)) camera.rotation--; + else if (rlc.isKeyDown(rlc.KEY_S)) camera.rotation++; // Limit camera rotation to 80 degrees (-40 to 40) if (camera.rotation > 40) camera.rotation = 40; else if (camera.rotation < -40) camera.rotation = -40; // Camera zoom controls - camera.zoom += ((float)GetMouseWheelMove()*0.05f); + camera.zoom += (rlc.getMouseWheelMove()*0.05); - if (camera.zoom > 3.0f) camera.zoom = 3.0f; - else if (camera.zoom < 0.1f) camera.zoom = 0.1f; + if (camera.zoom > 3.0) camera.zoom = 3.0; + else if (camera.zoom < 0.1) camera.zoom = 0.1; // Camera reset (zoom and rotation) - if (IsKeyPressed(KEY_R)) + if (rlc.isKeyPressed(rlc.KEY_R)) { - camera.zoom = 1.0f; - camera.rotation = 0.0f; + camera.zoom = 1.0; + camera.rotation = 0.0; } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- - BeginDrawing(); + rlc.beginDrawing(); - ClearBackground(RAYWHITE); + rlc.clearBackground(rlc.RAYWHITE); - BeginMode2D(camera); + rlc.beginMode2D(camera); - DrawRectangle(-6000, 320, 13000, 8000, DARKGRAY); + rlc.drawRectangle(-6000, 320, 13000, 8000, rlc.DARKGRAY); - for (int i = 0; i < MAX_BUILDINGS; i++) DrawRectangleRec(buildings[i], buildColors[i]); + for (let i = 0; i < MAX_BUILDINGS; i++) rlc.drawRectangleRec(buildings[i], buildColors[i]); - DrawRectangleRec(player, RED); + rlc.drawRectangleRec(player, rlc.RED); - DrawLine((int)camera.target.x, -screenHeight*10, (int)camera.target.x, screenHeight*10, GREEN); - DrawLine(-screenWidth*10, (int)camera.target.y, screenWidth*10, (int)camera.target.y, GREEN); + rlc.drawLine(cameraTarget.x, -screenHeight*10, cameraTarget.x, screenHeight*10, rlc.GREEN); + rlc.drawLine(-screenWidth*10, cameraTarget.y, screenWidth*10, cameraTarget.y, rlc.GREEN); - EndMode2D(); + rlc.endMode2D(); - DrawText("SCREEN AREA", 640, 10, 20, RED); + rlc.drawText("SCREEN AREA", 640, 10, 20, rlc.RED); - DrawRectangle(0, 0, screenWidth, 5, RED); - DrawRectangle(0, 5, 5, screenHeight - 10, RED); - DrawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, RED); - DrawRectangle(0, screenHeight - 5, screenWidth, 5, RED); + rlc.drawRectangle(0, 0, screenWidth, 5, rlc.RED); + rlc.drawRectangle(0, 5, 5, screenHeight - 10, rlc.RED); + rlc.drawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, rlc.RED); + rlc.drawRectangle(0, screenHeight - 5, screenWidth, 5, rlc.RED); - DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f)); - DrawRectangleLines( 10, 10, 250, 113, BLUE); + rlc.drawRectangle( 10, 10, 250, 113, rlc.fade(rlc.SKYBLUE, 0.5)); + rlc.drawRectangleLines( 10, 10, 250, 113, rlc.BLUE); - DrawText("Free 2d camera controls:", 20, 20, 10, BLACK); - DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY); - DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY); - DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY); - DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY); + rlc.drawText("Free 2d camera controls:", 20, 20, 10, rlc.BLACK); + rlc.drawText("- Right/Left to move Offset", 40, 40, 10, rlc.DARKGRAY); + rlc.drawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, rlc.DARKGRAY); + rlc.drawText("- A / S to Rotate", 40, 80, 10, rlc.DARKGRAY); + rlc.drawText("- R to reset Zoom and Rotation", 40, 100, 10, rlc.DARKGRAY); - EndDrawing(); + rlc.endDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- -CloseWindow(); // Close window and OpenGL context +rlc.closeWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/generate-bindings.js b/generate-bindings.js index 68f1f0d..57d3dd2 100644 --- a/generate-bindings.js +++ b/generate-bindings.js @@ -344,7 +344,8 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { jsToC(type, name, src, classIds = {}) { switch (type) { case "const char *": - this.statement(`${type} ${name} = JS_ToCString(ctx, ${src})`); + case "char *": + this.statement(`${type} ${name} = JS_ToCString(ctx, (const char *)${src})`); this.statement(`if(${name} == NULL) return JS_EXCEPTION`); break; case "float": @@ -353,8 +354,9 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { this.statement(`${type} ${name} = (${type})_double_${name}`); break; case "int": + case "unsigned int": this.statement(`${type} ${name}`); - this.statement(`JS_ToInt32(ctx, &${name}, ${src})`); + this.statement(`JS_ToInt32(ctx, (int *)&${name}, ${src})`); break; case "unsigned char": this.statement("int _int_" + name); @@ -374,14 +376,20 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { switch (type) { case "int": case "unsigned char": + case "long": this.declare(name, 'JSValue', false, `JS_NewInt32(ctx, ${src})`); break; case "bool": this.declare(name, 'JSValue', false, `JS_NewBool(ctx, ${src})`); break; case "float": + case "double": this.declare(name, 'JSValue', false, `JS_NewFloat64(ctx, ${src})`); break; + case "const char *": + case "char *": + this.declare(name, 'JSValue', false, `JS_NewString(ctx, ${src})`); + break; default: const classId = classIds[type]; if (!classId) @@ -453,7 +461,7 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { body.statement("return 0"); return body; } - jsStructGetter(structName, classId, field, type) { + jsStructGetter(structName, classId, field, type, classIds) { const args = [{ type: "JSContext*", name: "ctx" }, { type: "JSValueConst", name: "this_val" }]; const fun = this.function(`js_${structName}_get_${field}`, "JSValue", args, true); fun.declare("ptr", structName + "*", false, `JS_GetOpaque2(ctx, this_val, ${classId})`); @@ -461,18 +469,18 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { cond.returnExp("JS_EXCEPTION"); }); fun.declare(field, type, false, "ptr->" + field); - fun.jsToJs(type, "ret", field); + fun.jsToJs(type, "ret", field, classIds); fun.returnExp("ret"); return fun; } - jsStructSetter(structName, classId, field, type) { + jsStructSetter(structName, classId, field, type, classIds) { const args = [{ type: "JSContext*", name: "ctx" }, { type: "JSValueConst", name: "this_val" }, { type: "JSValueConst", name: "v" }]; const fun = this.function(`js_${structName}_set_${field}`, "JSValue", args, true); fun.declare("ptr", structName + "*", false, `JS_GetOpaque2(ctx, this_val, ${classId})`); fun.if("!ptr", cond => { cond.returnExp("JS_EXCEPTION"); }); - fun.jsToC(type, "value", "v"); + fun.jsToC(type, "value", "v", classIds); fun.statement("ptr->" + field + " = value"); fun.returnExp("JS_UNDEFINED"); return fun; @@ -480,11 +488,11 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { jsOpqToStructPtr(structType, structVar, srcVar, classId) { this.declare(structVar, structType + "*", false, `(${structType}*)JS_GetOpaque2(ctx, ${srcVar}, ${classId})`); } - jsStructConstructor(structName, fields, classId) { + jsStructConstructor(structName, fields, classId, classIds) { const body = this.jsBindingFunction(structName + "_constructor"); for (let i = 0; i < fields.length; i++) { const para = fields[i]; - body.jsToC(para.type, para.name, "argv[" + i + "]"); + body.jsToC(para.type, para.name, "argv[" + i + "]", classIds); } body.declareStruct(structName, "_struct", fields.map(x => x.name)); body.jsStructToOpq(structName, "_return", "_struct", classId); @@ -568,9 +576,9 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { let _get = undefined; let _set = undefined; if (el.get) - _get = this.structs.jsStructGetter(struct.name, classId, field, type); + _get = this.structs.jsStructGetter(struct.name, classId, field, type, /*Be carefull when allocating memory in a getter*/ {}); if (el.set) - _set = this.structs.jsStructSetter(struct.name, classId, field, type); + _set = this.structs.jsStructSetter(struct.name, classId, field, type, this.structLookup); propDeclarations.jsGetSetDef(field, _get?.getTag("_name"), _set?.getTag("_name")); } } @@ -580,7 +588,7 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { const classDecl = this.structs.jsClassDeclaration(struct.name, classId, finalizer.getTag("_name"), classFuncList.getTag("_name")); this.moduleInit.call(classDecl.getTag("_name"), ["ctx", "m"]); if (options?.createConstructor) { - const body = this.functions.jsStructConstructor(struct.name, struct.fields, classId); + const body = this.functions.jsStructConstructor(struct.name, struct.fields, classId, this.structLookup); this.moduleInit.statement(`JSValue ${struct.name}_constr = JS_NewCFunction2(ctx, ${body.getTag("_name")},"${struct.name})", ${struct.fields.length}, JS_CFUNC_constructor_or_func, 0)`); this.moduleInit.call("JS_SetModuleExport", ["ctx", "m", `"${struct.name}"`, struct.name + "_constr"]); this.moduleEntry.call("JS_AddModuleExport", ["ctx", "m", '"' + struct.name + '"']); @@ -695,28 +703,196 @@ function main() { }, createConstructor: true }); + core_gen.addApiStructByName("Vector3", { + properties: { + x: { get: true, set: true }, + y: { get: true, set: true }, + z: { get: true, set: true }, + }, + createConstructor: true + }); + core_gen.addApiStructByName("Ray", { + properties: { + position: { get: false, set: true }, + direction: { get: false, set: true }, + }, + createConstructor: true + }); + core_gen.addApiStructByName("Camera2D", { + properties: { + offset: { get: false, set: true }, + target: { get: false, set: true }, + rotation: { get: true, set: true }, + zoom: { get: true, set: true }, + }, + createConstructor: true + }); + core_gen.addApiStructByName("Matrix", { + properties: {}, + createConstructor: false + }); + // Window-related functions + core_gen.addApiFunctionByName("InitWindow"); + core_gen.addApiFunctionByName("WindowShouldClose"); + core_gen.addApiFunctionByName("CloseWindow"); + core_gen.addApiFunctionByName("IsWindowReady"); + core_gen.addApiFunctionByName("IsWindowFullscreen"); + core_gen.addApiFunctionByName("IsWindowHidden"); + core_gen.addApiFunctionByName("IsWindowMinimized"); + core_gen.addApiFunctionByName("IsWindowMaximized"); + core_gen.addApiFunctionByName("IsWindowFocused"); + core_gen.addApiFunctionByName("IsWindowResized"); + core_gen.addApiFunctionByName("IsWindowState"); + core_gen.addApiFunctionByName("SetWindowState"); + core_gen.addApiFunctionByName("ClearWindowState"); + core_gen.addApiFunctionByName("ToggleFullscreen"); + core_gen.addApiFunctionByName("MaximizeWindow"); + core_gen.addApiFunctionByName("MinimizeWindow"); + core_gen.addApiFunctionByName("RestoreWindow"); + // SetWindowIcon + // SetWindowIcons core_gen.addApiFunctionByName("SetWindowTitle"); core_gen.addApiFunctionByName("SetWindowPosition"); + core_gen.addApiFunctionByName("SetWindowMonitor"); + core_gen.addApiFunctionByName("SetWindowMinSize"); + core_gen.addApiFunctionByName("SetWindowSize"); + core_gen.addApiFunctionByName("SetWindowOpacity"); + // GetWindowHandle + core_gen.addApiFunctionByName("GetScreenWidth"); + core_gen.addApiFunctionByName("GetScreenHeight"); + core_gen.addApiFunctionByName("GetRenderWidth"); + core_gen.addApiFunctionByName("GetRenderHeight"); + core_gen.addApiFunctionByName("GetMonitorCount"); + core_gen.addApiFunctionByName("GetCurrentMonitor"); + core_gen.addApiFunctionByName("GetMonitorPosition"); + core_gen.addApiFunctionByName("GetMonitorWidth"); + core_gen.addApiFunctionByName("GetMonitorHeight"); + core_gen.addApiFunctionByName("GetMonitorPhysicalWidth"); + core_gen.addApiFunctionByName("GetMonitorPhysicalHeight"); + core_gen.addApiFunctionByName("GetMonitorRefreshRate"); + core_gen.addApiFunctionByName("GetWindowPosition"); + core_gen.addApiFunctionByName("GetWindowScaleDPI"); + core_gen.addApiFunctionByName("GetMonitorName"); + core_gen.addApiFunctionByName("SetClipboardText"); + core_gen.addApiFunctionByName("GetClipboardText"); + core_gen.addApiFunctionByName("EnableEventWaiting"); + core_gen.addApiFunctionByName("DisableEventWaiting"); + // Custom frame control functions + // NOT SUPPORTED BECAUSE NEEDS COMPILER FLAG + // Cursor-related functions + core_gen.addApiFunctionByName("ShowCursor"); + core_gen.addApiFunctionByName("HideCursor"); + core_gen.addApiFunctionByName("IsCursorHidden"); + core_gen.addApiFunctionByName("EnableCursor"); + core_gen.addApiFunctionByName("DisableCursor"); + core_gen.addApiFunctionByName("IsCursorOnScreen"); + // Drawing related functions + core_gen.addApiFunctionByName("ClearBackground"); core_gen.addApiFunctionByName("BeginDrawing"); core_gen.addApiFunctionByName("EndDrawing", null, { before: fun => fun.call("app_update_quickjs", []) }); - core_gen.addApiFunctionByName("InitWindow"); + core_gen.addApiFunctionByName("BeginMode2D"); + core_gen.addApiFunctionByName("EndMode2D"); + //core_gen.addApiFunctionByName("BeginMode3D") + //core_gen.addApiFunctionByName("EndMode3D") + //core_gen.addApiFunctionByName("BeginTextureMode") + //core_gen.addApiFunctionByName("EndTextureMode") + //core_gen.addApiFunctionByName("BeginShaderMode") + //core_gen.addApiFunctionByName("EndShaderMode") + core_gen.addApiFunctionByName("BeginBlendMode"); + core_gen.addApiFunctionByName("EndBlendMode"); + core_gen.addApiFunctionByName("BeginScissorMode"); + core_gen.addApiFunctionByName("EndScissorMode"); + //core_gen.addApiFunctionByName("BeginVrStereoMode") + //core_gen.addApiFunctionByName("EndVrStereoMode") + // VR Stereo config options + //core_gen.addApiFunctionByName("LoadVrStereoConfig") + //core_gen.addApiFunctionByName("UnloadVrStereoConfig") + // Shader Management + // core_gen.addApiFunctionByName("LoadShader") + // core_gen.addApiFunctionByName("LoadShaderFromMemory") + // core_gen.addApiFunctionByName("IsShaderReady") + // core_gen.addApiFunctionByName("GetShaderLocation") + // core_gen.addApiFunctionByName("GetShaderLocationAttrib") + // core_gen.addApiFunctionByName("SetShaderValue") + // core_gen.addApiFunctionByName("SetShaderValueV") + // core_gen.addApiFunctionByName("SetShaderValueMatrix") + // core_gen.addApiFunctionByName("SetShaderValueTexture") + // // "UnloadShader" is destructor + // ScreenSpaceRelatedFunctions + //core_gen.addApiFunctionByName("GetMouseRay") + //core_gen.addApiFunctionByName("GetCameraMatrix") + core_gen.addApiFunctionByName("GetCameraMatrix2D"); + //core_gen.addApiFunctionByName("GetWorldToScreen") + core_gen.addApiFunctionByName("GetScreenToWorld2D"); + //core_gen.addApiFunctionByName("GetScreenToWorldEx") + core_gen.addApiFunctionByName("GetWorldToScreen2D"); + // Timing related functions core_gen.addApiFunctionByName("SetTargetFPS"); - core_gen.addApiFunctionByName("WindowShouldClose"); - core_gen.addApiFunctionByName("ClearBackground"); - core_gen.addApiFunctionByName("CloseWindow"); + core_gen.addApiFunctionByName("GetFPS"); + core_gen.addApiFunctionByName("GetFrameTime"); + core_gen.addApiFunctionByName("GetTime"); + // Misc functions + core_gen.addApiFunctionByName("GetRandomValue"); + core_gen.addApiFunctionByName("SetRandomSeed"); + core_gen.addApiFunctionByName("TakeScreenshot"); + core_gen.addApiFunctionByName("SetConfigFlags"); + const traceLog = apiDesc.getFunction("TraceLog"); + if (!traceLog) + throw new Error("TraceLog not found"); + traceLog.params.pop(); + core_gen.addApiFunction(traceLog); + core_gen.addApiFunctionByName("SetTraceLogLevel"); + // Memory functions not supported on JS + core_gen.addApiFunctionByName("OpenURL"); + // Callbacks not supported on JS + // Files management functions + //core_gen.addApiFunctionByName("LoadFileData") + //core_gen.addApiFunctionByName("UnloadLoadFileData") + //core_gen.addApiFunctionByName("SaveFileData") + // Export data as code not needed + core_gen.addApiFunctionByName("LoadFileText", null, { after: gen => gen.call("UnloadFileText", ["returnVal"]) }); + core_gen.addApiFunctionByName("SaveFileText"); + core_gen.addApiFunctionByName("FileExists"); + core_gen.addApiFunctionByName("DirectoryExists"); + core_gen.addApiFunctionByName("IsFileExtension"); + // TODO: Who needs to clean memory here? + core_gen.addApiFunctionByName("GetFileLength"); + core_gen.addApiFunctionByName("GetFileExtension"); + core_gen.addApiFunctionByName("GetFileName"); + core_gen.addApiFunctionByName("GetFileNameWithoutExt"); + core_gen.addApiFunctionByName("GetDirectoryPath"); + core_gen.addApiFunctionByName("GetPrevDirectoryPath"); + core_gen.addApiFunctionByName("GetWorkingDirectory"); + core_gen.addApiFunctionByName("GetApplicationDirectory"); + core_gen.addApiFunctionByName("ChangeDirectory"); + core_gen.addApiFunctionByName("IsPathFile"); + //core_gen.addApiFunctionByName("LoadPathFiles") + //core_gen.addApiFunctionByName("LoadPathFilesEx") + // UnloadDirectoryFiles + core_gen.addApiFunctionByName("IsFileDropped"); + //core_gen.addApiFunctionByName("LoadDroppedFiles") + // UnloadDroppedFiles + core_gen.addApiFunctionByName("GetFileModTime"); core_gen.addApiFunctionByName("DrawText"); + core_gen.addApiFunctionByName("DrawLine"); core_gen.addApiFunctionByName("DrawCircleV"); core_gen.addApiFunctionByName("IsKeyDown"); + core_gen.addApiFunctionByName("IsKeyPressed"); core_gen.addApiFunctionByName("GetMousePosition"); core_gen.addApiFunctionByName("IsMouseButtonPressed"); core_gen.addApiFunctionByName("GetMouseWheelMove"); core_gen.addApiFunctionByName("DrawRectangle"); - core_gen.addApiFunctionByName("GetRandomValue"); + core_gen.addApiFunctionByName("DrawRectangleRec"); + core_gen.addApiFunctionByName("DrawRectangleLines"); + core_gen.addApiFunctionByName("Fade"); api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => { core_gen.exportGlobalStruct("Color", x.name, x.values); }); api.enums.find(x => x.name === "KeyboardKey")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)); api.enums.find(x => x.name === "MouseButton")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)); + api.enums.find(x => x.name === "ConfigFlags")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)); + api.enums.find(x => x.name === "BlendMode")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)); + api.enums.find(x => x.name === "TraceLogLevel")?.values.forEach(x => core_gen.exportGlobalConstant(x.name)); core_gen.writeTo("src/bindings/js_raylib_core.h"); const texture_gen = new raylib_header_1.RayLibHeader("raylib_texture", apiDesc); texture_gen.addApiStructByName("Image", { diff --git a/src/bindings/js_raylib_core.h b/src/bindings/js_raylib_core.h index 4ae6a1e..0aa55af 100644 --- a/src/bindings/js_raylib_core.h +++ b/src/bindings/js_raylib_core.h @@ -13,7 +13,12 @@ #endif static JSClassID js_Color_class_id; +static JSClassID js_Rectangle_class_id; static JSClassID js_Vector2_class_id; +static JSClassID js_Vector3_class_id; +static JSClassID js_Ray_class_id; +static JSClassID js_Camera2D_class_id; +static JSClassID js_Matrix_class_id; static void js_Color_finalizer(JSRuntime * rt, JSValue val) { Color* ptr = JS_GetOpaque(val, js_Color_class_id); @@ -128,6 +133,119 @@ static int js_declare_Color(JSContext * ctx, JSModuleDef * m) { return 0; } +static void js_Rectangle_finalizer(JSRuntime * rt, JSValue val) { + Rectangle* ptr = JS_GetOpaque(val, js_Rectangle_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_Rectangle_get_x(JSContext* ctx, JSValueConst this_val) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float x = ptr->x; + JSValue ret = JS_NewFloat64(ctx, x); + return ret; +} + +static JSValue js_Rectangle_set_x(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->x = value; + return JS_UNDEFINED; +} + +static JSValue js_Rectangle_get_y(JSContext* ctx, JSValueConst this_val) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float y = ptr->y; + JSValue ret = JS_NewFloat64(ctx, y); + return ret; +} + +static JSValue js_Rectangle_set_y(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->y = value; + return JS_UNDEFINED; +} + +static JSValue js_Rectangle_get_width(JSContext* ctx, JSValueConst this_val) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float width = ptr->width; + JSValue ret = JS_NewFloat64(ctx, width); + return ret; +} + +static JSValue js_Rectangle_set_width(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->width = value; + return JS_UNDEFINED; +} + +static JSValue js_Rectangle_get_height(JSContext* ctx, JSValueConst this_val) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float height = ptr->height; + JSValue ret = JS_NewFloat64(ctx, height); + return ret; +} + +static JSValue js_Rectangle_set_height(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Rectangle* ptr = JS_GetOpaque2(ctx, this_val, js_Rectangle_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->height = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_Rectangle_proto_funcs[] = { + JS_CGETSET_DEF("x",js_Rectangle_get_x,js_Rectangle_set_x), + JS_CGETSET_DEF("y",js_Rectangle_get_y,js_Rectangle_set_y), + JS_CGETSET_DEF("width",js_Rectangle_get_width,js_Rectangle_set_width), + JS_CGETSET_DEF("height",js_Rectangle_get_height,js_Rectangle_set_height), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","Rectangle", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_Rectangle(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_Rectangle_class_id); + JSClassDef js_Rectangle_def = { .class_name = "Rectangle", .finalizer = js_Rectangle_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_Rectangle_class_id, &js_Rectangle_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_Rectangle_proto_funcs, countof(js_Rectangle_proto_funcs)); + JS_SetClassProto(ctx, js_Rectangle_class_id, proto); + return 0; +} + static void js_Vector2_finalizer(JSRuntime * rt, JSValue val) { Vector2* ptr = JS_GetOpaque(val, js_Vector2_class_id); if(ptr) { @@ -195,6 +313,257 @@ static int js_declare_Vector2(JSContext * ctx, JSModuleDef * m) { return 0; } +static void js_Vector3_finalizer(JSRuntime * rt, JSValue val) { + Vector3* ptr = JS_GetOpaque(val, js_Vector3_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_Vector3_get_x(JSContext* ctx, JSValueConst this_val) { + Vector3* ptr = JS_GetOpaque2(ctx, this_val, js_Vector3_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float x = ptr->x; + JSValue ret = JS_NewFloat64(ctx, x); + return ret; +} + +static JSValue js_Vector3_set_x(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Vector3* ptr = JS_GetOpaque2(ctx, this_val, js_Vector3_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->x = value; + return JS_UNDEFINED; +} + +static JSValue js_Vector3_get_y(JSContext* ctx, JSValueConst this_val) { + Vector3* ptr = JS_GetOpaque2(ctx, this_val, js_Vector3_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float y = ptr->y; + JSValue ret = JS_NewFloat64(ctx, y); + return ret; +} + +static JSValue js_Vector3_set_y(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Vector3* ptr = JS_GetOpaque2(ctx, this_val, js_Vector3_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->y = value; + return JS_UNDEFINED; +} + +static JSValue js_Vector3_get_z(JSContext* ctx, JSValueConst this_val) { + Vector3* ptr = JS_GetOpaque2(ctx, this_val, js_Vector3_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float z = ptr->z; + JSValue ret = JS_NewFloat64(ctx, z); + return ret; +} + +static JSValue js_Vector3_set_z(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Vector3* ptr = JS_GetOpaque2(ctx, this_val, js_Vector3_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->z = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_Vector3_proto_funcs[] = { + JS_CGETSET_DEF("x",js_Vector3_get_x,js_Vector3_set_x), + JS_CGETSET_DEF("y",js_Vector3_get_y,js_Vector3_set_y), + JS_CGETSET_DEF("z",js_Vector3_get_z,js_Vector3_set_z), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","Vector3", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_Vector3(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_Vector3_class_id); + JSClassDef js_Vector3_def = { .class_name = "Vector3", .finalizer = js_Vector3_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_Vector3_class_id, &js_Vector3_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_Vector3_proto_funcs, countof(js_Vector3_proto_funcs)); + JS_SetClassProto(ctx, js_Vector3_class_id, proto); + return 0; +} + +static void js_Ray_finalizer(JSRuntime * rt, JSValue val) { + Ray* ptr = JS_GetOpaque(val, js_Ray_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_Ray_set_position(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Ray* ptr = JS_GetOpaque2(ctx, this_val, js_Ray_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + Vector3* value_ptr = (Vector3*)JS_GetOpaque2(ctx, v, js_Vector3_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Vector3 value = *value_ptr; + ptr->position = value; + return JS_UNDEFINED; +} + +static JSValue js_Ray_set_direction(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Ray* ptr = JS_GetOpaque2(ctx, this_val, js_Ray_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + Vector3* value_ptr = (Vector3*)JS_GetOpaque2(ctx, v, js_Vector3_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Vector3 value = *value_ptr; + ptr->direction = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_Ray_proto_funcs[] = { + JS_CGETSET_DEF("position",NULL,js_Ray_set_position), + JS_CGETSET_DEF("direction",NULL,js_Ray_set_direction), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","Ray", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_Ray(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_Ray_class_id); + JSClassDef js_Ray_def = { .class_name = "Ray", .finalizer = js_Ray_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_Ray_class_id, &js_Ray_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_Ray_proto_funcs, countof(js_Ray_proto_funcs)); + JS_SetClassProto(ctx, js_Ray_class_id, proto); + return 0; +} + +static void js_Camera2D_finalizer(JSRuntime * rt, JSValue val) { + Camera2D* ptr = JS_GetOpaque(val, js_Camera2D_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_Camera2D_set_offset(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Camera2D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera2D_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + Vector2* value_ptr = (Vector2*)JS_GetOpaque2(ctx, v, js_Vector2_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Vector2 value = *value_ptr; + ptr->offset = value; + return JS_UNDEFINED; +} + +static JSValue js_Camera2D_set_target(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Camera2D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera2D_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + Vector2* value_ptr = (Vector2*)JS_GetOpaque2(ctx, v, js_Vector2_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Vector2 value = *value_ptr; + ptr->target = value; + return JS_UNDEFINED; +} + +static JSValue js_Camera2D_get_rotation(JSContext* ctx, JSValueConst this_val) { + Camera2D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera2D_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float rotation = ptr->rotation; + JSValue ret = JS_NewFloat64(ctx, rotation); + return ret; +} + +static JSValue js_Camera2D_set_rotation(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Camera2D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera2D_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->rotation = value; + return JS_UNDEFINED; +} + +static JSValue js_Camera2D_get_zoom(JSContext* ctx, JSValueConst this_val) { + Camera2D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera2D_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + float zoom = ptr->zoom; + JSValue ret = JS_NewFloat64(ctx, zoom); + return ret; +} + +static JSValue js_Camera2D_set_zoom(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Camera2D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera2D_class_id); + if(!ptr) { + return JS_EXCEPTION; + } + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->zoom = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_Camera2D_proto_funcs[] = { + JS_CGETSET_DEF("offset",NULL,js_Camera2D_set_offset), + JS_CGETSET_DEF("target",NULL,js_Camera2D_set_target), + JS_CGETSET_DEF("rotation",js_Camera2D_get_rotation,js_Camera2D_set_rotation), + JS_CGETSET_DEF("zoom",js_Camera2D_get_zoom,js_Camera2D_set_zoom), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","Camera2D", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_Camera2D(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_Camera2D_class_id); + JSClassDef js_Camera2D_def = { .class_name = "Camera2D", .finalizer = js_Camera2D_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_Camera2D_class_id, &js_Camera2D_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_Camera2D_proto_funcs, countof(js_Camera2D_proto_funcs)); + JS_SetClassProto(ctx, js_Camera2D_class_id, proto); + return 0; +} + +static void js_Matrix_finalizer(JSRuntime * rt, JSValue val) { + Matrix* ptr = JS_GetOpaque(val, js_Matrix_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static const JSCFunctionListEntry js_Matrix_proto_funcs[] = { + JS_PROP_STRING_DEF("[Symbol.toStringTag]","Matrix", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_Matrix(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_Matrix_class_id); + JSClassDef js_Matrix_def = { .class_name = "Matrix", .finalizer = js_Matrix_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_Matrix_class_id, &js_Matrix_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_Matrix_proto_funcs, countof(js_Matrix_proto_funcs)); + JS_SetClassProto(ctx, js_Matrix_class_id, proto); + return 0; +} + static JSValue js_Color_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int _int_r; JS_ToInt32(ctx, &_int_r, argv[0]); @@ -216,6 +585,27 @@ static JSValue js_Color_constructor(JSContext * ctx, JSValueConst this_val, int return _return; } +static JSValue js_Rectangle_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + double _double_x; + JS_ToFloat64(ctx, &_double_x, argv[0]); + float x = (float)_double_x; + double _double_y; + JS_ToFloat64(ctx, &_double_y, argv[1]); + float y = (float)_double_y; + double _double_width; + JS_ToFloat64(ctx, &_double_width, argv[2]); + float width = (float)_double_width; + double _double_height; + JS_ToFloat64(ctx, &_double_height, argv[3]); + float height = (float)_double_height; + Rectangle _struct = { x, y, width, height }; + Rectangle* _return_ptr = (Rectangle*)js_malloc(ctx, sizeof(Rectangle)); + *_return_ptr = _struct; + JSValue _return = JS_NewObjectClass(ctx, js_Rectangle_class_id); + JS_SetOpaque(_return, _return_ptr); + return _return; +} + static JSValue js_Vector2_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { double _double_x; JS_ToFloat64(ctx, &_double_x, argv[0]); @@ -231,6 +621,167 @@ static JSValue js_Vector2_constructor(JSContext * ctx, JSValueConst this_val, in return _return; } +static JSValue js_Vector3_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + double _double_x; + JS_ToFloat64(ctx, &_double_x, argv[0]); + float x = (float)_double_x; + double _double_y; + JS_ToFloat64(ctx, &_double_y, argv[1]); + float y = (float)_double_y; + double _double_z; + JS_ToFloat64(ctx, &_double_z, argv[2]); + float z = (float)_double_z; + Vector3 _struct = { x, y, z }; + Vector3* _return_ptr = (Vector3*)js_malloc(ctx, sizeof(Vector3)); + *_return_ptr = _struct; + JSValue _return = JS_NewObjectClass(ctx, js_Vector3_class_id); + JS_SetOpaque(_return, _return_ptr); + return _return; +} + +static JSValue js_Ray_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Vector3* position_ptr = (Vector3*)JS_GetOpaque2(ctx, argv[0], js_Vector3_class_id); + if(position_ptr == NULL) return JS_EXCEPTION; + Vector3 position = *position_ptr; + Vector3* direction_ptr = (Vector3*)JS_GetOpaque2(ctx, argv[1], js_Vector3_class_id); + if(direction_ptr == NULL) return JS_EXCEPTION; + Vector3 direction = *direction_ptr; + Ray _struct = { position, direction }; + Ray* _return_ptr = (Ray*)js_malloc(ctx, sizeof(Ray)); + *_return_ptr = _struct; + JSValue _return = JS_NewObjectClass(ctx, js_Ray_class_id); + JS_SetOpaque(_return, _return_ptr); + return _return; +} + +static JSValue js_Camera2D_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Vector2* offset_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[0], js_Vector2_class_id); + if(offset_ptr == NULL) return JS_EXCEPTION; + Vector2 offset = *offset_ptr; + Vector2* target_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[1], js_Vector2_class_id); + if(target_ptr == NULL) return JS_EXCEPTION; + Vector2 target = *target_ptr; + double _double_rotation; + JS_ToFloat64(ctx, &_double_rotation, argv[2]); + float rotation = (float)_double_rotation; + double _double_zoom; + JS_ToFloat64(ctx, &_double_zoom, argv[3]); + float zoom = (float)_double_zoom; + Camera2D _struct = { offset, target, rotation, zoom }; + Camera2D* _return_ptr = (Camera2D*)js_malloc(ctx, sizeof(Camera2D)); + *_return_ptr = _struct; + JSValue _return = JS_NewObjectClass(ctx, js_Camera2D_class_id); + JS_SetOpaque(_return, _return_ptr); + return _return; +} + +static JSValue js_initWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int width; + JS_ToInt32(ctx, (int *)&width, argv[0]); + int height; + JS_ToInt32(ctx, (int *)&height, argv[1]); + const char * title = JS_ToCString(ctx, argv[2]); + if(title == NULL) return JS_EXCEPTION; + InitWindow(width, height, title); + JS_FreeCString(ctx, title); + return JS_UNDEFINED; +} + +static JSValue js_windowShouldClose(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = WindowShouldClose(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_closeWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + CloseWindow(); + return JS_UNDEFINED; +} + +static JSValue js_isWindowReady(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowReady(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowFullscreen(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowFullscreen(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowHidden(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowHidden(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowMinimized(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowMinimized(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowMaximized(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowMaximized(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowFocused(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowFocused(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowResized(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsWindowResized(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isWindowState(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + unsigned int flag; + JS_ToInt32(ctx, (int *)&flag, argv[0]); + bool returnVal = IsWindowState(flag); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_setWindowState(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + unsigned int flags; + JS_ToInt32(ctx, (int *)&flags, argv[0]); + SetWindowState(flags); + return JS_UNDEFINED; +} + +static JSValue js_clearWindowState(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + unsigned int flags; + JS_ToInt32(ctx, (int *)&flags, argv[0]); + ClearWindowState(flags); + return JS_UNDEFINED; +} + +static JSValue js_toggleFullscreen(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + ToggleFullscreen(); + return JS_UNDEFINED; +} + +static JSValue js_maximizeWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + MaximizeWindow(); + return JS_UNDEFINED; +} + +static JSValue js_minimizeWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + MinimizeWindow(); + return JS_UNDEFINED; +} + +static JSValue js_restoreWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + RestoreWindow(); + return JS_UNDEFINED; +} + static JSValue js_setWindowTitle(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { const char * title = JS_ToCString(ctx, argv[0]); if(title == NULL) return JS_EXCEPTION; @@ -241,13 +792,223 @@ static JSValue js_setWindowTitle(JSContext * ctx, JSValueConst this_val, int arg static JSValue js_setWindowPosition(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int x; - JS_ToInt32(ctx, &x, argv[0]); + JS_ToInt32(ctx, (int *)&x, argv[0]); int y; - JS_ToInt32(ctx, &y, argv[1]); + JS_ToInt32(ctx, (int *)&y, argv[1]); SetWindowPosition(x, y); return JS_UNDEFINED; } +static JSValue js_setWindowMonitor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + SetWindowMonitor(monitor); + return JS_UNDEFINED; +} + +static JSValue js_setWindowMinSize(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int width; + JS_ToInt32(ctx, (int *)&width, argv[0]); + int height; + JS_ToInt32(ctx, (int *)&height, argv[1]); + SetWindowMinSize(width, height); + return JS_UNDEFINED; +} + +static JSValue js_setWindowSize(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int width; + JS_ToInt32(ctx, (int *)&width, argv[0]); + int height; + JS_ToInt32(ctx, (int *)&height, argv[1]); + SetWindowSize(width, height); + return JS_UNDEFINED; +} + +static JSValue js_setWindowOpacity(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + double _double_opacity; + JS_ToFloat64(ctx, &_double_opacity, argv[0]); + float opacity = (float)_double_opacity; + SetWindowOpacity(opacity); + return JS_UNDEFINED; +} + +static JSValue js_getScreenWidth(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetScreenWidth(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getScreenHeight(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetScreenHeight(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getRenderWidth(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetRenderWidth(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getRenderHeight(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetRenderHeight(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getMonitorCount(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetMonitorCount(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getCurrentMonitor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetCurrentMonitor(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getMonitorPosition(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + Vector2 returnVal = GetMonitorPosition(monitor); + Vector2* ret_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector2_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getMonitorWidth(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + int returnVal = GetMonitorWidth(monitor); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getMonitorHeight(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + int returnVal = GetMonitorHeight(monitor); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getMonitorPhysicalWidth(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + int returnVal = GetMonitorPhysicalWidth(monitor); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getMonitorPhysicalHeight(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + int returnVal = GetMonitorPhysicalHeight(monitor); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getMonitorRefreshRate(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + int returnVal = GetMonitorRefreshRate(monitor); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getWindowPosition(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Vector2 returnVal = GetWindowPosition(); + Vector2* ret_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector2_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getWindowScaleDPI(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Vector2 returnVal = GetWindowScaleDPI(); + Vector2* ret_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector2_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getMonitorName(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int monitor; + JS_ToInt32(ctx, (int *)&monitor, argv[0]); + const char * returnVal = GetMonitorName(monitor); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_setClipboardText(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * text = JS_ToCString(ctx, argv[0]); + if(text == NULL) return JS_EXCEPTION; + SetClipboardText(text); + JS_FreeCString(ctx, text); + return JS_UNDEFINED; +} + +static JSValue js_getClipboardText(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * returnVal = GetClipboardText(); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_enableEventWaiting(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + EnableEventWaiting(); + return JS_UNDEFINED; +} + +static JSValue js_disableEventWaiting(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + DisableEventWaiting(); + return JS_UNDEFINED; +} + +static JSValue js_showCursor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + ShowCursor(); + return JS_UNDEFINED; +} + +static JSValue js_hideCursor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + HideCursor(); + return JS_UNDEFINED; +} + +static JSValue js_isCursorHidden(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsCursorHidden(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_enableCursor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + EnableCursor(); + return JS_UNDEFINED; +} + +static JSValue js_disableCursor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + DisableCursor(); + return JS_UNDEFINED; +} + +static JSValue js_isCursorOnScreen(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsCursorOnScreen(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_clearBackground(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[0], js_Color_class_id); + if(color_ptr == NULL) return JS_EXCEPTION; + Color color = *color_ptr; + ClearBackground(color); + return JS_UNDEFINED; +} + static JSValue js_beginDrawing(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { BeginDrawing(); return JS_UNDEFINED; @@ -259,53 +1020,332 @@ static JSValue js_endDrawing(JSContext * ctx, JSValueConst this_val, int argc, J return JS_UNDEFINED; } -static JSValue js_initWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { - int width; - JS_ToInt32(ctx, &width, argv[0]); - int height; - JS_ToInt32(ctx, &height, argv[1]); - const char * title = JS_ToCString(ctx, argv[2]); - if(title == NULL) return JS_EXCEPTION; - InitWindow(width, height, title); - JS_FreeCString(ctx, title); +static JSValue js_beginMode2D(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera2D* camera_ptr = (Camera2D*)JS_GetOpaque2(ctx, argv[0], js_Camera2D_class_id); + if(camera_ptr == NULL) return JS_EXCEPTION; + Camera2D camera = *camera_ptr; + BeginMode2D(camera); return JS_UNDEFINED; } +static JSValue js_endMode2D(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + EndMode2D(); + return JS_UNDEFINED; +} + +static JSValue js_beginBlendMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int mode; + JS_ToInt32(ctx, (int *)&mode, argv[0]); + BeginBlendMode(mode); + return JS_UNDEFINED; +} + +static JSValue js_endBlendMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + EndBlendMode(); + return JS_UNDEFINED; +} + +static JSValue js_beginScissorMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int x; + JS_ToInt32(ctx, (int *)&x, argv[0]); + int y; + JS_ToInt32(ctx, (int *)&y, argv[1]); + int width; + JS_ToInt32(ctx, (int *)&width, argv[2]); + int height; + JS_ToInt32(ctx, (int *)&height, argv[3]); + BeginScissorMode(x, y, width, height); + return JS_UNDEFINED; +} + +static JSValue js_endScissorMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + EndScissorMode(); + return JS_UNDEFINED; +} + +static JSValue js_getCameraMatrix2D(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera2D* camera_ptr = (Camera2D*)JS_GetOpaque2(ctx, argv[0], js_Camera2D_class_id); + if(camera_ptr == NULL) return JS_EXCEPTION; + Camera2D camera = *camera_ptr; + Matrix returnVal = GetCameraMatrix2D(camera); + Matrix* ret_ptr = (Matrix*)js_malloc(ctx, sizeof(Matrix)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Matrix_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getScreenToWorld2D(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Vector2* position_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[0], js_Vector2_class_id); + if(position_ptr == NULL) return JS_EXCEPTION; + Vector2 position = *position_ptr; + Camera2D* camera_ptr = (Camera2D*)JS_GetOpaque2(ctx, argv[1], js_Camera2D_class_id); + if(camera_ptr == NULL) return JS_EXCEPTION; + Camera2D camera = *camera_ptr; + Vector2 returnVal = GetScreenToWorld2D(position, camera); + Vector2* ret_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector2_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getWorldToScreen2D(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Vector2* position_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[0], js_Vector2_class_id); + if(position_ptr == NULL) return JS_EXCEPTION; + Vector2 position = *position_ptr; + Camera2D* camera_ptr = (Camera2D*)JS_GetOpaque2(ctx, argv[1], js_Camera2D_class_id); + if(camera_ptr == NULL) return JS_EXCEPTION; + Camera2D camera = *camera_ptr; + Vector2 returnVal = GetWorldToScreen2D(position, camera); + Vector2* ret_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector2_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + static JSValue js_setTargetFPS(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int fps; - JS_ToInt32(ctx, &fps, argv[0]); + JS_ToInt32(ctx, (int *)&fps, argv[0]); SetTargetFPS(fps); return JS_UNDEFINED; } -static JSValue js_windowShouldClose(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { - bool returnVal = WindowShouldClose(); +static JSValue js_getFPS(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int returnVal = GetFPS(); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getFrameTime(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + float returnVal = GetFrameTime(); + JSValue ret = JS_NewFloat64(ctx, returnVal); + return ret; +} + +static JSValue js_getTime(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + double returnVal = GetTime(); + JSValue ret = JS_NewFloat64(ctx, returnVal); + return ret; +} + +static JSValue js_getRandomValue(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int min; + JS_ToInt32(ctx, (int *)&min, argv[0]); + int max; + JS_ToInt32(ctx, (int *)&max, argv[1]); + int returnVal = GetRandomValue(min, max); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_setRandomSeed(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + unsigned int seed; + JS_ToInt32(ctx, (int *)&seed, argv[0]); + SetRandomSeed(seed); + return JS_UNDEFINED; +} + +static JSValue js_takeScreenshot(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + TakeScreenshot(fileName); + JS_FreeCString(ctx, fileName); + return JS_UNDEFINED; +} + +static JSValue js_setConfigFlags(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + unsigned int flags; + JS_ToInt32(ctx, (int *)&flags, argv[0]); + SetConfigFlags(flags); + return JS_UNDEFINED; +} + +static JSValue js_traceLog(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int logLevel; + JS_ToInt32(ctx, (int *)&logLevel, argv[0]); + const char * text = JS_ToCString(ctx, argv[1]); + if(text == NULL) return JS_EXCEPTION; + TraceLog(logLevel, text); + JS_FreeCString(ctx, text); + return JS_UNDEFINED; +} + +static JSValue js_setTraceLogLevel(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int logLevel; + JS_ToInt32(ctx, (int *)&logLevel, argv[0]); + SetTraceLogLevel(logLevel); + return JS_UNDEFINED; +} + +static JSValue js_openURL(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * url = JS_ToCString(ctx, argv[0]); + if(url == NULL) return JS_EXCEPTION; + OpenURL(url); + JS_FreeCString(ctx, url); + return JS_UNDEFINED; +} + +static JSValue js_loadFileText(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + char * returnVal = LoadFileText(fileName); + JS_FreeCString(ctx, fileName); + UnloadFileText(returnVal); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_saveFileText(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + char * text = JS_ToCString(ctx, argv[1]); + if(text == NULL) return JS_EXCEPTION; + bool returnVal = SaveFileText(fileName, text); + JS_FreeCString(ctx, fileName); JSValue ret = JS_NewBool(ctx, returnVal); return ret; } -static JSValue js_clearBackground(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { - Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[0], js_Color_class_id); - if(color_ptr == NULL) return JS_EXCEPTION; - Color color = *color_ptr; - ClearBackground(color); - return JS_UNDEFINED; +static JSValue js_fileExists(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + bool returnVal = FileExists(fileName); + JS_FreeCString(ctx, fileName); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; } -static JSValue js_closeWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { - CloseWindow(); - return JS_UNDEFINED; +static JSValue js_directoryExists(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * dirPath = JS_ToCString(ctx, argv[0]); + if(dirPath == NULL) return JS_EXCEPTION; + bool returnVal = DirectoryExists(dirPath); + JS_FreeCString(ctx, dirPath); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isFileExtension(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + const char * ext = JS_ToCString(ctx, argv[1]); + if(ext == NULL) return JS_EXCEPTION; + bool returnVal = IsFileExtension(fileName, ext); + JS_FreeCString(ctx, fileName); + JS_FreeCString(ctx, ext); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_getFileLength(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + int returnVal = GetFileLength(fileName); + JS_FreeCString(ctx, fileName); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; +} + +static JSValue js_getFileExtension(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + const char * returnVal = GetFileExtension(fileName); + JS_FreeCString(ctx, fileName); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_getFileName(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * filePath = JS_ToCString(ctx, argv[0]); + if(filePath == NULL) return JS_EXCEPTION; + const char * returnVal = GetFileName(filePath); + JS_FreeCString(ctx, filePath); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_getFileNameWithoutExt(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * filePath = JS_ToCString(ctx, argv[0]); + if(filePath == NULL) return JS_EXCEPTION; + const char * returnVal = GetFileNameWithoutExt(filePath); + JS_FreeCString(ctx, filePath); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_getDirectoryPath(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * filePath = JS_ToCString(ctx, argv[0]); + if(filePath == NULL) return JS_EXCEPTION; + const char * returnVal = GetDirectoryPath(filePath); + JS_FreeCString(ctx, filePath); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_getPrevDirectoryPath(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * dirPath = JS_ToCString(ctx, argv[0]); + if(dirPath == NULL) return JS_EXCEPTION; + const char * returnVal = GetPrevDirectoryPath(dirPath); + JS_FreeCString(ctx, dirPath); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_getWorkingDirectory(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * returnVal = GetWorkingDirectory(); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_getApplicationDirectory(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * returnVal = GetApplicationDirectory(); + JSValue ret = JS_NewString(ctx, returnVal); + return ret; +} + +static JSValue js_changeDirectory(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * dir = JS_ToCString(ctx, argv[0]); + if(dir == NULL) return JS_EXCEPTION; + bool returnVal = ChangeDirectory(dir); + JS_FreeCString(ctx, dir); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isPathFile(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * path = JS_ToCString(ctx, argv[0]); + if(path == NULL) return JS_EXCEPTION; + bool returnVal = IsPathFile(path); + JS_FreeCString(ctx, path); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_isFileDropped(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + bool returnVal = IsFileDropped(); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_getFileModTime(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + const char * fileName = JS_ToCString(ctx, argv[0]); + if(fileName == NULL) return JS_EXCEPTION; + long returnVal = GetFileModTime(fileName); + JS_FreeCString(ctx, fileName); + JSValue ret = JS_NewInt32(ctx, returnVal); + return ret; } static JSValue js_drawText(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { const char * text = JS_ToCString(ctx, argv[0]); if(text == NULL) return JS_EXCEPTION; int posX; - JS_ToInt32(ctx, &posX, argv[1]); + JS_ToInt32(ctx, (int *)&posX, argv[1]); int posY; - JS_ToInt32(ctx, &posY, argv[2]); + JS_ToInt32(ctx, (int *)&posY, argv[2]); int fontSize; - JS_ToInt32(ctx, &fontSize, argv[3]); + JS_ToInt32(ctx, (int *)&fontSize, argv[3]); Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[4], js_Color_class_id); if(color_ptr == NULL) return JS_EXCEPTION; Color color = *color_ptr; @@ -314,6 +1354,22 @@ static JSValue js_drawText(JSContext * ctx, JSValueConst this_val, int argc, JSV return JS_UNDEFINED; } +static JSValue js_drawLine(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int startPosX; + JS_ToInt32(ctx, (int *)&startPosX, argv[0]); + int startPosY; + JS_ToInt32(ctx, (int *)&startPosY, argv[1]); + int endPosX; + JS_ToInt32(ctx, (int *)&endPosX, argv[2]); + int endPosY; + JS_ToInt32(ctx, (int *)&endPosY, argv[3]); + Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[4], js_Color_class_id); + if(color_ptr == NULL) return JS_EXCEPTION; + Color color = *color_ptr; + DrawLine(startPosX, startPosY, endPosX, endPosY, color); + return JS_UNDEFINED; +} + static JSValue js_drawCircleV(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Vector2* center_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[0], js_Vector2_class_id); if(center_ptr == NULL) return JS_EXCEPTION; @@ -330,12 +1386,20 @@ static JSValue js_drawCircleV(JSContext * ctx, JSValueConst this_val, int argc, static JSValue js_isKeyDown(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int key; - JS_ToInt32(ctx, &key, argv[0]); + JS_ToInt32(ctx, (int *)&key, argv[0]); bool returnVal = IsKeyDown(key); JSValue ret = JS_NewBool(ctx, returnVal); return ret; } +static JSValue js_isKeyPressed(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int key; + JS_ToInt32(ctx, (int *)&key, argv[0]); + bool returnVal = IsKeyPressed(key); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + static JSValue js_getMousePosition(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Vector2 returnVal = GetMousePosition(); Vector2* ret_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); @@ -347,7 +1411,7 @@ static JSValue js_getMousePosition(JSContext * ctx, JSValueConst this_val, int a static JSValue js_isMouseButtonPressed(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int button; - JS_ToInt32(ctx, &button, argv[0]); + JS_ToInt32(ctx, (int *)&button, argv[0]); bool returnVal = IsMouseButtonPressed(button); JSValue ret = JS_NewBool(ctx, returnVal); return ret; @@ -361,13 +1425,13 @@ static JSValue js_getMouseWheelMove(JSContext * ctx, JSValueConst this_val, int static JSValue js_drawRectangle(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int posX; - JS_ToInt32(ctx, &posX, argv[0]); + JS_ToInt32(ctx, (int *)&posX, argv[0]); int posY; - JS_ToInt32(ctx, &posY, argv[1]); + JS_ToInt32(ctx, (int *)&posY, argv[1]); int width; - JS_ToInt32(ctx, &width, argv[2]); + JS_ToInt32(ctx, (int *)&width, argv[2]); int height; - JS_ToInt32(ctx, &height, argv[3]); + JS_ToInt32(ctx, (int *)&height, argv[3]); Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[4], js_Color_class_id); if(color_ptr == NULL) return JS_EXCEPTION; Color color = *color_ptr; @@ -375,23 +1439,149 @@ static JSValue js_drawRectangle(JSContext * ctx, JSValueConst this_val, int argc return JS_UNDEFINED; } +static JSValue js_drawRectangleRec(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Rectangle* rec_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id); + if(rec_ptr == NULL) return JS_EXCEPTION; + Rectangle rec = *rec_ptr; + Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[1], js_Color_class_id); + if(color_ptr == NULL) return JS_EXCEPTION; + Color color = *color_ptr; + DrawRectangleRec(rec, color); + return JS_UNDEFINED; +} + +static JSValue js_drawRectangleLines(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + int posX; + JS_ToInt32(ctx, (int *)&posX, argv[0]); + int posY; + JS_ToInt32(ctx, (int *)&posY, argv[1]); + int width; + JS_ToInt32(ctx, (int *)&width, argv[2]); + int height; + JS_ToInt32(ctx, (int *)&height, argv[3]); + Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[4], js_Color_class_id); + if(color_ptr == NULL) return JS_EXCEPTION; + Color color = *color_ptr; + DrawRectangleLines(posX, posY, width, height, color); + return JS_UNDEFINED; +} + +static JSValue js_fade(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[0], js_Color_class_id); + if(color_ptr == NULL) return JS_EXCEPTION; + Color color = *color_ptr; + double _double_alpha; + JS_ToFloat64(ctx, &_double_alpha, argv[1]); + float alpha = (float)_double_alpha; + Color returnVal = Fade(color, alpha); + Color* ret_ptr = (Color*)js_malloc(ctx, sizeof(Color)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Color_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + static const JSCFunctionListEntry js_raylib_core_funcs[] = { + JS_CFUNC_DEF("initWindow",3,js_initWindow), + JS_CFUNC_DEF("windowShouldClose",0,js_windowShouldClose), + JS_CFUNC_DEF("closeWindow",0,js_closeWindow), + JS_CFUNC_DEF("isWindowReady",0,js_isWindowReady), + JS_CFUNC_DEF("isWindowFullscreen",0,js_isWindowFullscreen), + JS_CFUNC_DEF("isWindowHidden",0,js_isWindowHidden), + JS_CFUNC_DEF("isWindowMinimized",0,js_isWindowMinimized), + JS_CFUNC_DEF("isWindowMaximized",0,js_isWindowMaximized), + JS_CFUNC_DEF("isWindowFocused",0,js_isWindowFocused), + JS_CFUNC_DEF("isWindowResized",0,js_isWindowResized), + JS_CFUNC_DEF("isWindowState",1,js_isWindowState), + JS_CFUNC_DEF("setWindowState",1,js_setWindowState), + JS_CFUNC_DEF("clearWindowState",1,js_clearWindowState), + JS_CFUNC_DEF("toggleFullscreen",0,js_toggleFullscreen), + JS_CFUNC_DEF("maximizeWindow",0,js_maximizeWindow), + JS_CFUNC_DEF("minimizeWindow",0,js_minimizeWindow), + JS_CFUNC_DEF("restoreWindow",0,js_restoreWindow), JS_CFUNC_DEF("setWindowTitle",1,js_setWindowTitle), JS_CFUNC_DEF("setWindowPosition",2,js_setWindowPosition), + JS_CFUNC_DEF("setWindowMonitor",1,js_setWindowMonitor), + JS_CFUNC_DEF("setWindowMinSize",2,js_setWindowMinSize), + JS_CFUNC_DEF("setWindowSize",2,js_setWindowSize), + JS_CFUNC_DEF("setWindowOpacity",1,js_setWindowOpacity), + JS_CFUNC_DEF("getScreenWidth",0,js_getScreenWidth), + JS_CFUNC_DEF("getScreenHeight",0,js_getScreenHeight), + JS_CFUNC_DEF("getRenderWidth",0,js_getRenderWidth), + JS_CFUNC_DEF("getRenderHeight",0,js_getRenderHeight), + JS_CFUNC_DEF("getMonitorCount",0,js_getMonitorCount), + JS_CFUNC_DEF("getCurrentMonitor",0,js_getCurrentMonitor), + JS_CFUNC_DEF("getMonitorPosition",1,js_getMonitorPosition), + JS_CFUNC_DEF("getMonitorWidth",1,js_getMonitorWidth), + JS_CFUNC_DEF("getMonitorHeight",1,js_getMonitorHeight), + JS_CFUNC_DEF("getMonitorPhysicalWidth",1,js_getMonitorPhysicalWidth), + JS_CFUNC_DEF("getMonitorPhysicalHeight",1,js_getMonitorPhysicalHeight), + JS_CFUNC_DEF("getMonitorRefreshRate",1,js_getMonitorRefreshRate), + JS_CFUNC_DEF("getWindowPosition",0,js_getWindowPosition), + JS_CFUNC_DEF("getWindowScaleDPI",0,js_getWindowScaleDPI), + JS_CFUNC_DEF("getMonitorName",1,js_getMonitorName), + JS_CFUNC_DEF("setClipboardText",1,js_setClipboardText), + JS_CFUNC_DEF("getClipboardText",0,js_getClipboardText), + JS_CFUNC_DEF("enableEventWaiting",0,js_enableEventWaiting), + JS_CFUNC_DEF("disableEventWaiting",0,js_disableEventWaiting), + JS_CFUNC_DEF("showCursor",0,js_showCursor), + JS_CFUNC_DEF("hideCursor",0,js_hideCursor), + JS_CFUNC_DEF("isCursorHidden",0,js_isCursorHidden), + JS_CFUNC_DEF("enableCursor",0,js_enableCursor), + JS_CFUNC_DEF("disableCursor",0,js_disableCursor), + JS_CFUNC_DEF("isCursorOnScreen",0,js_isCursorOnScreen), + JS_CFUNC_DEF("clearBackground",1,js_clearBackground), JS_CFUNC_DEF("beginDrawing",0,js_beginDrawing), JS_CFUNC_DEF("endDrawing",0,js_endDrawing), - JS_CFUNC_DEF("initWindow",3,js_initWindow), + JS_CFUNC_DEF("beginMode2D",1,js_beginMode2D), + JS_CFUNC_DEF("endMode2D",0,js_endMode2D), + JS_CFUNC_DEF("beginBlendMode",1,js_beginBlendMode), + JS_CFUNC_DEF("endBlendMode",0,js_endBlendMode), + JS_CFUNC_DEF("beginScissorMode",4,js_beginScissorMode), + JS_CFUNC_DEF("endScissorMode",0,js_endScissorMode), + JS_CFUNC_DEF("getCameraMatrix2D",1,js_getCameraMatrix2D), + JS_CFUNC_DEF("getScreenToWorld2D",2,js_getScreenToWorld2D), + JS_CFUNC_DEF("getWorldToScreen2D",2,js_getWorldToScreen2D), JS_CFUNC_DEF("setTargetFPS",1,js_setTargetFPS), - JS_CFUNC_DEF("windowShouldClose",0,js_windowShouldClose), - JS_CFUNC_DEF("clearBackground",1,js_clearBackground), - JS_CFUNC_DEF("closeWindow",0,js_closeWindow), + JS_CFUNC_DEF("getFPS",0,js_getFPS), + JS_CFUNC_DEF("getFrameTime",0,js_getFrameTime), + JS_CFUNC_DEF("getTime",0,js_getTime), + JS_CFUNC_DEF("getRandomValue",2,js_getRandomValue), + JS_CFUNC_DEF("setRandomSeed",1,js_setRandomSeed), + JS_CFUNC_DEF("takeScreenshot",1,js_takeScreenshot), + JS_CFUNC_DEF("setConfigFlags",1,js_setConfigFlags), + JS_CFUNC_DEF("traceLog",2,js_traceLog), + JS_CFUNC_DEF("setTraceLogLevel",1,js_setTraceLogLevel), + JS_CFUNC_DEF("openURL",1,js_openURL), + JS_CFUNC_DEF("loadFileText",1,js_loadFileText), + JS_CFUNC_DEF("saveFileText",2,js_saveFileText), + JS_CFUNC_DEF("fileExists",1,js_fileExists), + JS_CFUNC_DEF("directoryExists",1,js_directoryExists), + JS_CFUNC_DEF("isFileExtension",2,js_isFileExtension), + JS_CFUNC_DEF("getFileLength",1,js_getFileLength), + JS_CFUNC_DEF("getFileExtension",1,js_getFileExtension), + JS_CFUNC_DEF("getFileName",1,js_getFileName), + JS_CFUNC_DEF("getFileNameWithoutExt",1,js_getFileNameWithoutExt), + JS_CFUNC_DEF("getDirectoryPath",1,js_getDirectoryPath), + JS_CFUNC_DEF("getPrevDirectoryPath",1,js_getPrevDirectoryPath), + JS_CFUNC_DEF("getWorkingDirectory",0,js_getWorkingDirectory), + JS_CFUNC_DEF("getApplicationDirectory",0,js_getApplicationDirectory), + JS_CFUNC_DEF("changeDirectory",1,js_changeDirectory), + JS_CFUNC_DEF("isPathFile",1,js_isPathFile), + JS_CFUNC_DEF("isFileDropped",0,js_isFileDropped), + JS_CFUNC_DEF("getFileModTime",1,js_getFileModTime), JS_CFUNC_DEF("drawText",5,js_drawText), + JS_CFUNC_DEF("drawLine",5,js_drawLine), JS_CFUNC_DEF("drawCircleV",3,js_drawCircleV), JS_CFUNC_DEF("isKeyDown",1,js_isKeyDown), + JS_CFUNC_DEF("isKeyPressed",1,js_isKeyPressed), JS_CFUNC_DEF("getMousePosition",0,js_getMousePosition), JS_CFUNC_DEF("isMouseButtonPressed",1,js_isMouseButtonPressed), JS_CFUNC_DEF("getMouseWheelMove",0,js_getMouseWheelMove), JS_CFUNC_DEF("drawRectangle",5,js_drawRectangle), + JS_CFUNC_DEF("drawRectangleRec",2,js_drawRectangleRec), + JS_CFUNC_DEF("drawRectangleLines",5,js_drawRectangleLines), + JS_CFUNC_DEF("fade",2,js_fade), }; static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { @@ -399,9 +1589,22 @@ static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { js_declare_Color(ctx, m); JSValue Color_constr = JS_NewCFunction2(ctx, js_Color_constructor,"Color)", 4, JS_CFUNC_constructor_or_func, 0); JS_SetModuleExport(ctx, m, "Color", Color_constr); + js_declare_Rectangle(ctx, m); + JSValue Rectangle_constr = JS_NewCFunction2(ctx, js_Rectangle_constructor,"Rectangle)", 4, JS_CFUNC_constructor_or_func, 0); + JS_SetModuleExport(ctx, m, "Rectangle", Rectangle_constr); js_declare_Vector2(ctx, m); JSValue Vector2_constr = JS_NewCFunction2(ctx, js_Vector2_constructor,"Vector2)", 2, JS_CFUNC_constructor_or_func, 0); JS_SetModuleExport(ctx, m, "Vector2", Vector2_constr); + js_declare_Vector3(ctx, m); + JSValue Vector3_constr = JS_NewCFunction2(ctx, js_Vector3_constructor,"Vector3)", 3, JS_CFUNC_constructor_or_func, 0); + JS_SetModuleExport(ctx, m, "Vector3", Vector3_constr); + js_declare_Ray(ctx, m); + JSValue Ray_constr = JS_NewCFunction2(ctx, js_Ray_constructor,"Ray)", 2, JS_CFUNC_constructor_or_func, 0); + JS_SetModuleExport(ctx, m, "Ray", Ray_constr); + js_declare_Camera2D(ctx, m); + JSValue Camera2D_constr = JS_NewCFunction2(ctx, js_Camera2D_constructor,"Camera2D)", 4, JS_CFUNC_constructor_or_func, 0); + JS_SetModuleExport(ctx, m, "Camera2D", Camera2D_constr); + js_declare_Matrix(ctx, m); Color LIGHTGRAY_struct = { 200, 200, 200, 255 }; Color* LIGHTGRAY_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); *LIGHTGRAY_js_ptr = LIGHTGRAY_struct; @@ -675,6 +1878,37 @@ static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { JS_SetModuleExport(ctx, m, "MOUSE_BUTTON_EXTRA", JS_NewInt32(ctx, MOUSE_BUTTON_EXTRA)); JS_SetModuleExport(ctx, m, "MOUSE_BUTTON_FORWARD", JS_NewInt32(ctx, MOUSE_BUTTON_FORWARD)); JS_SetModuleExport(ctx, m, "MOUSE_BUTTON_BACK", JS_NewInt32(ctx, MOUSE_BUTTON_BACK)); + JS_SetModuleExport(ctx, m, "FLAG_VSYNC_HINT", JS_NewInt32(ctx, FLAG_VSYNC_HINT)); + JS_SetModuleExport(ctx, m, "FLAG_FULLSCREEN_MODE", JS_NewInt32(ctx, FLAG_FULLSCREEN_MODE)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_RESIZABLE", JS_NewInt32(ctx, FLAG_WINDOW_RESIZABLE)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_UNDECORATED", JS_NewInt32(ctx, FLAG_WINDOW_UNDECORATED)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_HIDDEN", JS_NewInt32(ctx, FLAG_WINDOW_HIDDEN)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_MINIMIZED", JS_NewInt32(ctx, FLAG_WINDOW_MINIMIZED)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_MAXIMIZED", JS_NewInt32(ctx, FLAG_WINDOW_MAXIMIZED)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_UNFOCUSED", JS_NewInt32(ctx, FLAG_WINDOW_UNFOCUSED)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_TOPMOST", JS_NewInt32(ctx, FLAG_WINDOW_TOPMOST)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_ALWAYS_RUN", JS_NewInt32(ctx, FLAG_WINDOW_ALWAYS_RUN)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_TRANSPARENT", JS_NewInt32(ctx, FLAG_WINDOW_TRANSPARENT)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_HIGHDPI", JS_NewInt32(ctx, FLAG_WINDOW_HIGHDPI)); + JS_SetModuleExport(ctx, m, "FLAG_WINDOW_MOUSE_PASSTHROUGH", JS_NewInt32(ctx, FLAG_WINDOW_MOUSE_PASSTHROUGH)); + JS_SetModuleExport(ctx, m, "FLAG_MSAA_4X_HINT", JS_NewInt32(ctx, FLAG_MSAA_4X_HINT)); + JS_SetModuleExport(ctx, m, "FLAG_INTERLACED_HINT", JS_NewInt32(ctx, FLAG_INTERLACED_HINT)); + JS_SetModuleExport(ctx, m, "BLEND_ALPHA", JS_NewInt32(ctx, BLEND_ALPHA)); + JS_SetModuleExport(ctx, m, "BLEND_ADDITIVE", JS_NewInt32(ctx, BLEND_ADDITIVE)); + JS_SetModuleExport(ctx, m, "BLEND_MULTIPLIED", JS_NewInt32(ctx, BLEND_MULTIPLIED)); + JS_SetModuleExport(ctx, m, "BLEND_ADD_COLORS", JS_NewInt32(ctx, BLEND_ADD_COLORS)); + JS_SetModuleExport(ctx, m, "BLEND_SUBTRACT_COLORS", JS_NewInt32(ctx, BLEND_SUBTRACT_COLORS)); + JS_SetModuleExport(ctx, m, "BLEND_ALPHA_PREMULTIPLY", JS_NewInt32(ctx, BLEND_ALPHA_PREMULTIPLY)); + JS_SetModuleExport(ctx, m, "BLEND_CUSTOM", JS_NewInt32(ctx, BLEND_CUSTOM)); + JS_SetModuleExport(ctx, m, "BLEND_CUSTOM_SEPARATE", JS_NewInt32(ctx, BLEND_CUSTOM_SEPARATE)); + JS_SetModuleExport(ctx, m, "LOG_ALL", JS_NewInt32(ctx, LOG_ALL)); + JS_SetModuleExport(ctx, m, "LOG_TRACE", JS_NewInt32(ctx, LOG_TRACE)); + JS_SetModuleExport(ctx, m, "LOG_DEBUG", JS_NewInt32(ctx, LOG_DEBUG)); + JS_SetModuleExport(ctx, m, "LOG_INFO", JS_NewInt32(ctx, LOG_INFO)); + JS_SetModuleExport(ctx, m, "LOG_WARNING", JS_NewInt32(ctx, LOG_WARNING)); + JS_SetModuleExport(ctx, m, "LOG_ERROR", JS_NewInt32(ctx, LOG_ERROR)); + JS_SetModuleExport(ctx, m, "LOG_FATAL", JS_NewInt32(ctx, LOG_FATAL)); + JS_SetModuleExport(ctx, m, "LOG_NONE", JS_NewInt32(ctx, LOG_NONE)); return 0; } @@ -684,7 +1918,11 @@ JSModuleDef * js_init_module_raylib_core(JSContext * ctx, const char * module_na if(!m) return NULL; JS_AddModuleExportList(ctx, m, js_raylib_core_funcs, countof(js_raylib_core_funcs)); JS_AddModuleExport(ctx, m, "Color"); + JS_AddModuleExport(ctx, m, "Rectangle"); JS_AddModuleExport(ctx, m, "Vector2"); + JS_AddModuleExport(ctx, m, "Vector3"); + JS_AddModuleExport(ctx, m, "Ray"); + JS_AddModuleExport(ctx, m, "Camera2D"); JS_AddModuleExport(ctx, m, "LIGHTGRAY"); JS_AddModuleExport(ctx, m, "GRAY"); JS_AddModuleExport(ctx, m, "DARKGRAY"); @@ -828,6 +2066,37 @@ JSModuleDef * js_init_module_raylib_core(JSContext * ctx, const char * module_na JS_AddModuleExport(ctx, m, "MOUSE_BUTTON_EXTRA"); JS_AddModuleExport(ctx, m, "MOUSE_BUTTON_FORWARD"); JS_AddModuleExport(ctx, m, "MOUSE_BUTTON_BACK"); + JS_AddModuleExport(ctx, m, "FLAG_VSYNC_HINT"); + JS_AddModuleExport(ctx, m, "FLAG_FULLSCREEN_MODE"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_RESIZABLE"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_UNDECORATED"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_HIDDEN"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_MINIMIZED"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_MAXIMIZED"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_UNFOCUSED"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_TOPMOST"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_ALWAYS_RUN"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_TRANSPARENT"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_HIGHDPI"); + JS_AddModuleExport(ctx, m, "FLAG_WINDOW_MOUSE_PASSTHROUGH"); + JS_AddModuleExport(ctx, m, "FLAG_MSAA_4X_HINT"); + JS_AddModuleExport(ctx, m, "FLAG_INTERLACED_HINT"); + JS_AddModuleExport(ctx, m, "BLEND_ALPHA"); + JS_AddModuleExport(ctx, m, "BLEND_ADDITIVE"); + JS_AddModuleExport(ctx, m, "BLEND_MULTIPLIED"); + JS_AddModuleExport(ctx, m, "BLEND_ADD_COLORS"); + JS_AddModuleExport(ctx, m, "BLEND_SUBTRACT_COLORS"); + JS_AddModuleExport(ctx, m, "BLEND_ALPHA_PREMULTIPLY"); + JS_AddModuleExport(ctx, m, "BLEND_CUSTOM"); + JS_AddModuleExport(ctx, m, "BLEND_CUSTOM_SEPARATE"); + JS_AddModuleExport(ctx, m, "LOG_ALL"); + JS_AddModuleExport(ctx, m, "LOG_TRACE"); + JS_AddModuleExport(ctx, m, "LOG_DEBUG"); + JS_AddModuleExport(ctx, m, "LOG_INFO"); + JS_AddModuleExport(ctx, m, "LOG_WARNING"); + JS_AddModuleExport(ctx, m, "LOG_ERROR"); + JS_AddModuleExport(ctx, m, "LOG_FATAL"); + JS_AddModuleExport(ctx, m, "LOG_NONE"); return m; }