diff --git a/bindings/src/api.ts b/bindings/src/api.ts index 49944fd..3c7923b 100644 --- a/bindings/src/api.ts +++ b/bindings/src/api.ts @@ -1,4 +1,4 @@ -import { RayLibApi, RayLibFunction, RayLibStruct } from "./interfaces" +import { RayLibApi, RayLibFunction, RayLibStruct, RayLibType } from "./interfaces" export class ApiFunction{ constructor(private api: RayLibFunction){ @@ -9,6 +9,7 @@ export class ApiFunction{ get argc() { return this.api.params?.length || 0 } get params() { return this.api.params || [] } get returnType() { return this.api.returnType } + set returnType(v) { this.api.returnType = v } get description() { return this.api.description } } diff --git a/bindings/src/index.ts b/bindings/src/index.ts index 01f597b..98ef997 100644 --- a/bindings/src/index.ts +++ b/bindings/src/index.ts @@ -33,6 +33,12 @@ function main(){ writeFileSync("bindings/raylib_math_api.json", JSON.stringify(mathApi)) const api = JSON.parse(readFileSync("thirdparty/raylib/parser/output/raylib_api.json", 'utf8')) + api.functions.push({ + name: "SetModelMaterial", + description: "Replace material in slot materialIndex", + returnType: "void", + params: [{type: "Model *",name:"model"},{type:"int",name:"materialIndex"},{type:"Material",name:"material"}] + }) mathApi.forEach(x => api.functions.push(x)) const apiDesc = new ApiDescription(api) @@ -122,6 +128,17 @@ function main(){ properties: {}, createConstructor: false }) + core.addApiStructByName("NPatchInfo",{ + properties: { + source: { get: true, set: true }, + left: { get: true, set: true }, + top: { get: true, set: true }, + right: { get: true, set: true }, + bottom: { get: true, set: true }, + layout: { get: true, set: true }, + }, + createConstructor: true + }) core.addApiStructByName("Image", { properties: { width: { get: true }, @@ -129,7 +146,7 @@ function main(){ mipmaps: { get: true }, format: { get: true } }, - destructor: "UnloadImage" + //destructor: "UnloadImage" }) core.addApiStructByName("Wave", { properties: { @@ -138,45 +155,79 @@ function main(){ sampleSize: { get: true }, channels: { get: true } }, - destructor: "UnloadWave" + //destructor: "UnloadWave" }) core.addApiStructByName("Sound", { properties: { frameCount: { get: true } }, - destructor: "UnloadSound" + //destructor: "UnloadSound" }) core.addApiStructByName("Music", { properties: { frameCount: { get: true }, looping: { get: true, set: true } }, - destructor: "UnloadMusicStream" + //destructor: "UnloadMusicStream" }) core.addApiStructByName("Model", { properties: {}, - destructor: "UnloadModel" + //destructor: "UnloadModel" }) core.addApiStructByName("Mesh", { - properties: {}, - destructor: "UnloadMesh" + properties: { + vertexCount: { get: true, set: true }, + triangleCount: { get: true, set: true }, + // TODO: Free previous pointers before overwriting + vertices: { set: true }, + texcoords: { set: true }, + texcoords2: { set: true }, + normals: { set: true }, + tangents: { set: true }, + colors: { set: true }, + indices: { set: true }, + animVertices: { set: true }, + animNormals: { set: true }, + boneIds: { set: true }, + boneWeights: { set: true }, + }, + createEmptyConstructor: true + //destructor: "UnloadMesh" }) core.addApiStructByName("Shader", { properties: {}, - destructor: "UnloadShader" + //destructor: "UnloadShader" }) core.addApiStructByName("Texture", { properties: { width: { get: true }, height: { get: true } }, - destructor: "UnloadTexture" + //destructor: "UnloadTexture" }) core.addApiStructByName("Font", { properties: { baseSize: { get: true } }, - destructor: "UnloadFont" + //destructor: "UnloadFont" + }) + core.addApiStructByName("RenderTexture", { + properties: { }, + //destructor: "UnloadRenderTexture" + }) + core.addApiStructByName("MaterialMap", { + properties: { + texture: { set: true }, + color: { set: true, get: true }, + value: { get: true, set: true } + }, + //destructor: "UnloadMaterialMap" + }) + core.addApiStructByName("Material", { + properties: { + shader: { set: true } + }, + //destructor: "UnloadMaterial" }) // Window-related functions @@ -245,8 +296,8 @@ function main(){ core.addApiFunctionByName("EndMode2D") core.addApiFunctionByName("BeginMode3D") core.addApiFunctionByName("EndMode3D") - //core.addApiFunctionByName("BeginTextureMode") - //core.addApiFunctionByName("EndTextureMode") + core.addApiFunctionByName("BeginTextureMode") + core.addApiFunctionByName("EndTextureMode") core.addApiFunctionByName("BeginShaderMode") core.addApiFunctionByName("EndShaderMode") core.addApiFunctionByName("BeginBlendMode") @@ -297,7 +348,7 @@ function main(){ // core.addApiFunctionByName("SetShaderValueV") core.addApiFunctionByName("SetShaderValueMatrix") core.addApiFunctionByName("SetShaderValueTexture") - // "UnloadShader" called by finalizer + core.addApiFunctionByName("UnloadShader") // ScreenSpaceRelatedFunctions core.addApiFunctionByName("GetMouseRay") @@ -488,7 +539,7 @@ function main(){ core.addApiFunctionByName("LoadImageFromTexture") core.addApiFunctionByName("LoadImageFromScreen") core.addApiFunctionByName("IsImageReady") - // UnloadImage called by destructor + core.addApiFunctionByName("UnloadImage") core.addApiFunctionByName("ExportImage") // needed? // core.addApiFunctionByName("ExportImageAsCode") @@ -532,7 +583,15 @@ function main(){ core.addApiFunctionByName("ImageColorContrast") core.addApiFunctionByName("ImageColorBrightness") core.addApiFunctionByName("ImageColorReplace") - //core.addApiFunctionByName("LoadImageColors") + const lic = apiDesc.getFunction("LoadImageColors") + lic.returnType = "unsigned char *" + core.addApiFunction(lic, null, { body: (gen) => { + gen.jsToC("Image","image","argv[0]", core.structLookup) + gen.call("LoadImageColors", ["image"], {name:"colors",type:"Color *"}) + gen.statement("JSValue retVal = JS_NewArrayBufferCopy(ctx, (const uint8_t*)colors, image.width*image.height*sizeof(Color))") + gen.call("UnloadImageColors", ["colors"]) + gen.returnExp("retVal") + }}) //core.addApiFunctionByName("LoadImagePalette") //core.addApiFunctionByName("UnloadImageColors") //core.addApiFunctionByName("UnloadImagePalette") @@ -561,11 +620,11 @@ function main(){ core.addApiFunctionByName("LoadTexture") core.addApiFunctionByName("LoadTextureFromImage") core.addApiFunctionByName("LoadTextureCubemap") - // core.addApiFunctionByName("LoadRenderTexture") + core.addApiFunctionByName("LoadRenderTexture") core.addApiFunctionByName("IsTextureReady") - // "UnloadTexture" called by finalizer - // core.addApiFunctionByName("IsRenderTextureReady") - // core.addApiFunctionByName("UnloadRenderTexture") + core.addApiFunctionByName("UnloadTexture") + core.addApiFunctionByName("IsRenderTextureReady") + core.addApiFunctionByName("UnloadRenderTexture") // core.addApiFunctionByName("UpdateTexture") // core.addApiFunctionByName("UpdateTextureRec") @@ -580,7 +639,7 @@ function main(){ core.addApiFunctionByName("DrawTextureEx") core.addApiFunctionByName("DrawTextureRec") core.addApiFunctionByName("DrawTexturePro") - // core.addApiFunctionByName("DrawTextureNPatch") + core.addApiFunctionByName("DrawTextureNPatch") // Color/pixel related functions core.addApiFunctionByName("Fade") @@ -611,7 +670,7 @@ function main(){ // core.addApiFunctionByName("LoadFontData") // core.addApiFunctionByName("GenImageFontAtlas") // core.addApiFunctionByName("UnloadFontData") - // "UnloadFont" called by finalizer + core.addApiFunctionByName("UnloadFont") // core.addApiFunctionByName("ExportFontAsCode") // Text drawing functions @@ -668,12 +727,12 @@ function main(){ core.addApiFunctionByName("DrawPlane") core.addApiFunctionByName("DrawRay") core.addApiFunctionByName("DrawGrid") - + // model management functions core.addApiFunctionByName("LoadModel") core.addApiFunctionByName("LoadModelFromMesh") core.addApiFunctionByName("IsModelReady") - // "UnloadModel" called by finalizer + core.addApiFunctionByName("UnloadModel") core.addApiFunctionByName("GetModelBoundingBox") // model drawing functions @@ -689,10 +748,10 @@ function main(){ // Mesh management functions // TODO: Refcounting needed? core.addApiFunctionByName("UploadMesh") - // core.addApiFunctionByName("UpdateMeshBuffer") - // "UnloadMesh" called by finalizer - //core.addApiFunctionByName("DrawMesh") - // core.addApiFunctionByName("DrawMeshInstanced") + core.addApiFunctionByName("UpdateMeshBuffer") + core.addApiFunctionByName("UnloadMesh") + core.addApiFunctionByName("DrawMesh") + core.addApiFunctionByName("DrawMeshInstanced") core.addApiFunctionByName("ExportMesh") core.addApiFunctionByName("GetMeshBoundingBox") core.addApiFunctionByName("GenMeshTangents") @@ -712,11 +771,12 @@ function main(){ // Material loading/unloading functions // core.addApiFunctionByName("LoadMaterials") - // core.addApiFunctionByName("LoadMaterialDefault") - // core.addApiFunctionByName("IsMaterialReady") - // core.addApiFunctionByName("UnloadMaterial") - // core.addApiFunctionByName("SetMaterialTexture") - // core.addApiFunctionByName("SetModelMeshMaterial") + core.addApiFunctionByName("LoadMaterialDefault") + core.addApiFunctionByName("IsMaterialReady") + core.addApiFunctionByName("UnloadMaterial") + core.addApiFunctionByName("SetMaterialTexture") + core.addApiFunctionByName("SetModelMaterial") + core.addApiFunctionByName("SetModelMeshMaterial") // Model animations loading/unloading functions // core.addApiFunctionByName("LoadModelAnimations") @@ -751,8 +811,8 @@ function main(){ core.addApiFunctionByName("LoadSoundFromWave") core.addApiFunctionByName("IsSoundReady") // core.addApiFunctionByName("UpdateSound") - // "UnloadWave" called by finalizer - // "UnloadSound" called by finalizer + core.addApiFunctionByName("UnloadWave") + core.addApiFunctionByName("UnloadSound") core.addApiFunctionByName("ExportWave") // core.addApiFunctionByName("ExportWaveAsCode") @@ -775,7 +835,7 @@ function main(){ core.addApiFunctionByName("LoadMusicStream") // core.addApiFunctionByName("LoadMusicStreamFromMemory") core.addApiFunctionByName("IsMusicReady") - // "UnloadMusicStream" called by finalizer + core.addApiFunctionByName("UnloadMusicStream") core.addApiFunctionByName("PlayMusicStream") core.addApiFunctionByName("IsMusicStreamPlaying") core.addApiFunctionByName("UpdateMusicStream") @@ -941,6 +1001,9 @@ function main(){ api.enums.find(x => x.name === "CameraMode")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)) api.enums.find(x => x.name === "ShaderLocationIndex")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)) api.enums.find(x => x.name === "ShaderUniformDataType")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)) + api.enums.find(x => x.name === "MaterialMapIndex")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)) + core.exportGlobalConstant("MATERIAL_MAP_DIFFUSE", "Albedo material (same as: MATERIAL_MAP_DIFFUSE") + core.exportGlobalConstant("MATERIAL_MAP_SPECULAR", "Metalness material (same as: MATERIAL_MAP_SPECULAR)") core.writeTo("src/bindings/js_raylib_core.h") core.typings.writeTo("examples/lib.raylib.d.ts") } diff --git a/bindings/src/quickjs.ts b/bindings/src/quickjs.ts index b0e129b..1cba716 100644 --- a/bindings/src/quickjs.ts +++ b/bindings/src/quickjs.ts @@ -78,6 +78,19 @@ export abstract class GenericQuickJsGenerator extend jsToC(type: string, name: string, src: string, classIds: StructLookup = {}, supressDeclaration = false){ switch (type) { + // Array Buffer + case "const void *": + case "void *": + case "float *": + case "unsigned short *": + case "unsigned char *": + this.declare(name+"_size", "size_t") + this.declare(name+"_js", "void *", false, `(void *)JS_GetArrayBuffer(ctx, &${name}_size, ${src})`) + this.if(name+"_js == NULL").returnExp("JS_EXCEPTION") + this.declare(name, type, false, "malloc("+name+"_size)") + this.call("memcpy", ["(void *)"+name, "(const void *)"+name+"_js", name+"_size"]) + break; + // String case "const char *": case "char *": if(!supressDeclaration) this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`) @@ -111,6 +124,7 @@ export abstract class GenericQuickJsGenerator extend if(!supressDeclaration) this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`) else this.statement(`${name} = JS_ToBool(ctx, ${src})`) break; + // Structs / Struct * default: const isConst = type.startsWith('const') const isPointer = type.endsWith(' *') @@ -163,9 +177,17 @@ export abstract class GenericQuickJsGenerator extend jsCleanUpParameter(type: string, name: string) { switch (type) { + case "char *": case "const char *": this.statement(`JS_FreeCString(ctx, ${name})`) break; + case "const void *": + case "void *": + case "float *": + case "unsigned short *": + case "unsigned char *": + this.statement(`free((void *)${name})`) + break; default: break; } @@ -206,7 +228,7 @@ export abstract class GenericQuickJsGenerator extend const body = this.function(`js_${structName}_finalizer`, "void", args, true) body.statement(`${structName}* ptr = JS_GetOpaque(val, ${classId})`) body.if("ptr", cond => { - //cond.call("TraceLog", ["LOG_INFO",`"Finalize ${structName}"`]) + //cond.call("TraceLog", ["LOG_INFO",`"Finalize ${structName} %p"`,"ptr"]) if(onFinalize) onFinalize(cond, "ptr") cond.call("js_free_rt", ["rt","ptr"]) }) @@ -230,9 +252,6 @@ export abstract class GenericQuickJsGenerator extend 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})`) - fun.if("!ptr", cond => { - cond.returnExp("JS_EXCEPTION") - }) fun.declare(field, type, false, "ptr->"+field) fun.jsToJs(type, "ret", field, classIds) fun.returnExp("ret") @@ -243,9 +262,6 @@ export abstract class GenericQuickJsGenerator extend 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", classIds); fun.statement("ptr->"+field+" = value") fun.returnExp("JS_UNDEFINED") diff --git a/bindings/src/raylib-header.ts b/bindings/src/raylib-header.ts index 307ea63..60ee4fc 100644 --- a/bindings/src/raylib-header.ts +++ b/bindings/src/raylib-header.ts @@ -8,6 +8,7 @@ export interface StructBindingOptions { destructor?: string, construct?: string, createConstructor?: boolean + createEmptyConstructor?: boolean } export interface FuncBindingOptions { @@ -95,8 +96,8 @@ 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, this.structLookup) + if(options?.createConstructor || options?.createEmptyConstructor){ + const body = this.functions.jsStructConstructor(struct.name, options?.createEmptyConstructor ? [] : 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/bindings/src/typescript.ts b/bindings/src/typescript.ts index 09d5cee..b48a3dc 100644 --- a/bindings/src/typescript.ts +++ b/bindings/src/typescript.ts @@ -26,7 +26,7 @@ export class TypeScriptDeclaration { addStruct(api: ApiStruct, options: StructBindingOptions){ var fields = api.fields.filter(x => !!(options.properties || {})[x.name]).map(x => ({name: x.name, description: x.description, type: this.toJsType(x.type)})) this.structs.tsDeclareInterface(api.name, fields) - this.structs.tsDeclareType(api.name, !!options.createConstructor, fields) + this.structs.tsDeclareType(api.name, !!(options.createConstructor || options.createEmptyConstructor), options.createEmptyConstructor ? [] : fields) } private toJsType(type: string){ @@ -38,6 +38,10 @@ export class TypeScriptDeclaration { case "float": case "double": return "number" + case "unsigned char *": + case "unsigned short *": + case "float *": + return "ArrayBuffer" case "bool": return "boolean" case "const char *": @@ -47,14 +51,19 @@ export class TypeScriptDeclaration { case "const void *": return "any" case "Camera": + case "Camera *": return "Camera3D" case "Texture2D": + case "Texture2D *": case "TextureCubemap": return "Texture" + case "RenderTexture2D": + case "RenderTexture2D *": + return "RenderTexture" case "Quaternion": return "Vector4" default: - return type.replace(" *", "") + return type.replace(" *", "").replace("const ", "") } } diff --git a/doc/structs.drawio.png b/doc/structs.drawio.png new file mode 100644 index 0000000..45ed267 Binary files /dev/null and b/doc/structs.drawio.png differ diff --git a/examples/1st_person_maze.js b/examples/1st_person_maze.js new file mode 100644 index 0000000..356ceb7 --- /dev/null +++ b/examples/1st_person_maze.js @@ -0,0 +1,118 @@ +/******************************************************************************************* +* +* raylib [models] example - first person maze +* +* Example originally created with raylib 2.5, last time updated with raylib 3.5 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2019-2023 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ +// Initialization +//-------------------------------------------------------------------------------------- +const screenWidth = 800; +const screenHeight = 450; + +initWindow(screenWidth, screenHeight, "raylib [models] example - first person maze"); + +// Define the camera to look into our 3d world +const camera = new Camera3D(new Vector3(0.2, 0.4, 0.2),new Vector3(0.185, 0.4, 0.0),new Vector3(0,1,0), 45, CAMERA_PERSPECTIVE); +const position = new Vector3(0,0,0); // Set model position + +const imMap = loadImage("assets/cubicmap.png"); // Load cubicmap image (RAM) +const cubicmap = loadTextureFromImage(imMap); // Convert image to texture to display (VRAM) +const mesh = genMeshCubicmap(imMap, new Vector3(1.0, 1.0, 1.0)); +const model = loadModelFromMesh(mesh); + +// NOTE: By default each cube is mapped to one part of texture atlas +const texture = loadTexture("assets/cubicmap_atlas.png"); // Load map texture +//model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture +const mat = loadMaterialDefault() +setMaterialTexture(mat, MATERIAL_MAP_DIFFUSE, texture) +setModelMaterial(model,0,mat) + +// Get map image data to be used for collision detection +const mapPixels = new Uint8Array(loadImageColors(imMap)); +unloadImage(imMap); // Unload image from RAM + +let mapPosition = new Vector3( -16.0, 0.0, -8.0); // Set model position + +disableCursor(); // Limit cursor to relative movement inside the window + +setTargetFPS(60); // Set our game to run at 60 frames-per-second +//-------------------------------------------------------------------------------------- + +// Main game loop +while (!windowShouldClose()) // Detect window close button or ESC key +{ + // Update + //---------------------------------------------------------------------------------- + let oldCamPos = camera.position; // Store old camera position + + updateCamera(camera, CAMERA_FIRST_PERSON); + + // Check player collision (we simplify to 2D collision detection) + const playerPos = new Vector2(camera.position.x, camera.position.z); + const playerRadius = 0.1; // Collision radius (player is modelled as a cilinder for collision) + + let playerCellX = Math.floor(playerPos.x - mapPosition.x + 0.5); + let playerCellY = Math.floor(playerPos.y - mapPosition.z + 0.5); + + // Out-of-limits security check + if (playerCellX < 0) playerCellX = 0; + else if (playerCellX >= cubicmap.width) playerCellX = cubicmap.width - 1; + + if (playerCellY < 0) playerCellY = 0; + else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1; + + // Check map collisions using image data and player position + // TODO: Improvement: Just check player surrounding cells for collision + for (let y = 0; y < cubicmap.height; y++) + { + for (let x = 0; x < cubicmap.width; x++) + { + const pixelValR = mapPixels[((y*cubicmap.width + x)*4)] + if ((pixelValR == 255) && // Collision: white pixel, only check R channel + (checkCollisionCircleRec(playerPos, playerRadius, new Rectangle( + mapPosition.x - 0.5 + x*1.0, + mapPosition.z - 0.5 + y*1.0, 1.0, 1.0 )))) + { + // Collision detected, reset camera position + camera.position = oldCamPos; + } + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + beginDrawing(); + + clearBackground(RAYWHITE); + + beginMode3D(camera); + drawModel(model, mapPosition, 1.0, WHITE); // Draw maze map + endMode3D(); + + drawTextureEx(cubicmap, new Vector2(getScreenWidth() - cubicmap.width*4.0 - 20, 20.0), 0.0, 4.0, WHITE); + drawRectangleLines(getScreenWidth() - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN); + + // Draw player position radar + drawRectangle(getScreenWidth() - cubicmap.width*4 - 20 + playerCellX*4, 20 + playerCellY*4, 4, 4, RED); + + drawFPS(10, 10); + + endDrawing(); + //---------------------------------------------------------------------------------- +} + +// De-Initialization +//-------------------------------------------------------------------------------------- +unloadTexture(cubicmap); // Unload cubicmap texture +unloadTexture(texture); // Unload map texture +unloadModel(model); // Unload map model + +closeWindow(); // Close window and OpenGL context +//-------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/basic_window.js b/examples/basic_window.js index 0e3ce67..4d6fe8b 100644 --- a/examples/basic_window.js +++ b/examples/basic_window.js @@ -28,4 +28,8 @@ while (!windowShouldClose()) // Detect window close button or ESC key endDrawing(); //---------------------------------------------------------------------------------- } +// De-Initialization +//-------------------------------------------------------------------------------------- +closeWindow(); // Close window and OpenGL context +//-------------------------------------------------------------------------------------- diff --git a/examples/bunnymark.js b/examples/bunnymark.js index 5ee90a1..5aaaee8 100644 --- a/examples/bunnymark.js +++ b/examples/bunnymark.js @@ -83,5 +83,6 @@ while (!windowShouldClose()) // Detect window close button or ESC key // De-Initialization //-------------------------------------------------------------------------------------- +unloadTexture(texBunny); closeWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/js_mesh_generation.js b/examples/js_mesh_generation.js new file mode 100644 index 0000000..485f14b --- /dev/null +++ b/examples/js_mesh_generation.js @@ -0,0 +1,50 @@ +// Initialization +//-------------------------------------------------------------------------------------- +const screenWidth = 800; +const screenHeight = 450; + +initWindow(screenWidth, screenHeight, "raylib [core] example - javascript mesh generation"); + +const mesh = new Mesh() +mesh.vertexCount = 3 +mesh.triangleCount = 1 +const v1 = new Vector3(screenWidth/2, 0, 0) +const v2 = new Vector3(0, screenHeight, 0 ) +const v3 = new Vector3(screenWidth, screenHeight, 0) +mesh.indices = new Uint16Array([0,1,2]).buffer +mesh.vertices = new Float32Array([ + v1.x, v1.y, v1.z, + v2.x, v2.y, v2.z, + v3.x, v3.y, v3.z +]).buffer +uploadMesh(mesh, false) // If your forget to upload to GPU drawMesh will segfault +const material = loadMaterialDefault() +const matrix = matrixIdentity() + +setTargetFPS(60); // Set our game to run at 60 frames-per-second +//-------------------------------------------------------------------------------------- + +// Main game loop +while (!windowShouldClose()) // Detect window close button or ESC key +{ + // Update + //---------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + beginDrawing(); + + clearBackground(RAYWHITE); + drawMesh(mesh, material, matrix) + drawText("Mesh created from Javascript ArrayBuffers", 190, 200, 20, LIGHTGRAY); + + endDrawing(); + //---------------------------------------------------------------------------------- +} +// De-Initialization +//-------------------------------------------------------------------------------------- +unloadMaterial(material) +unloadMesh(mesh) +closeWindow(); // Close window and OpenGL context +//-------------------------------------------------------------------------------------- diff --git a/examples/lib.raylib.d.ts b/examples/lib.raylib.d.ts index 936cdd7..85602a1 100644 --- a/examples/lib.raylib.d.ts +++ b/examples/lib.raylib.d.ts @@ -122,6 +122,24 @@ interface Matrix { declare var Matrix: { prototype: Matrix; } +interface NPatchInfo { + /** Texture source rectangle */ + source: Rectangle, + /** Left border offset */ + left: number, + /** Top border offset */ + top: number, + /** Right border offset */ + right: number, + /** Bottom border offset */ + bottom: number, + /** Layout of the n-patch: 3x3, 1x3 or 3x1 */ + layout: number, +} +declare var NPatchInfo: { + prototype: NPatchInfo; + new(source: Rectangle, left: number, top: number, right: number, bottom: number, layout: number): NPatchInfo; +} interface Image { /** Image base width */ width: number, @@ -170,9 +188,36 @@ declare var Model: { prototype: Model; } interface Mesh { + /** Number of vertices stored in arrays */ + vertexCount: number, + /** Number of triangles stored (indexed or not) */ + triangleCount: number, + /** Vertex position (XYZ - 3 components per vertex) (shader-location = 0) */ + vertices: ArrayBuffer, + /** Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) */ + texcoords: ArrayBuffer, + /** Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) */ + texcoords2: ArrayBuffer, + /** Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) */ + normals: ArrayBuffer, + /** Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) */ + tangents: ArrayBuffer, + /** Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) */ + colors: ArrayBuffer, + /** Vertex indices (in case vertex data comes indexed) */ + indices: ArrayBuffer, + /** Animated vertex positions (after bones transformations) */ + animVertices: ArrayBuffer, + /** Animated normals (after bones transformations) */ + animNormals: ArrayBuffer, + /** Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) */ + boneIds: ArrayBuffer, + /** Vertex bone weight, up to 4 bones influence by vertex (skinning) */ + boneWeights: ArrayBuffer, } declare var Mesh: { prototype: Mesh; + new(): Mesh; } interface Shader { } @@ -195,6 +240,29 @@ interface Font { declare var Font: { prototype: Font; } +interface RenderTexture { +} +declare var RenderTexture: { + prototype: RenderTexture; +} +interface MaterialMap { + /** Material map texture */ + texture: Texture, + /** Material map color */ + color: Color, + /** Material map value */ + value: number, +} +declare var MaterialMap: { + prototype: MaterialMap; +} +interface Material { + /** Material shader */ + shader: Shader, +} +declare var Material: { + prototype: Material; +} /** Initialize window and OpenGL context */ declare function initWindow(width: number, height: number, title: string): void; /** Check if KEY_ESCAPE pressed or Close icon pressed */ @@ -307,6 +375,10 @@ declare function endMode2D(): void; declare function beginMode3D(camera: Camera3D): void; /** Ends 3D mode and returns to default 2D orthographic mode */ declare function endMode3D(): void; +/** Begin drawing to render texture */ +declare function beginTextureMode(target: RenderTexture): void; +/** Ends drawing to render texture */ +declare function endTextureMode(): void; /** Begin custom shader drawing */ declare function beginShaderMode(shader: Shader): void; /** End custom shader drawing (use default shader) */ @@ -333,6 +405,8 @@ declare function setShaderValue(shader: Shader, locIndex: number, value: any, un declare function setShaderValueMatrix(shader: Shader, locIndex: number, mat: Matrix): void; /** Set shader uniform value for texture (sampler2d) */ declare function setShaderValueTexture(shader: Shader, locIndex: number, texture: Texture): void; +/** Unload shader from GPU memory (VRAM) */ +declare function unloadShader(shader: Shader): void; /** Get a ray trace from mouse position */ declare function getMouseRay(mousePosition: Vector2, camera: Camera3D): Ray; /** Get camera transform matrix (view matrix) */ @@ -492,9 +566,9 @@ declare function getGesturePinchVector(): Vector2; /** Get gesture pinch angle */ declare function getGesturePinchAngle(): number; /** Update camera position for selected mode */ -declare function updateCamera(camera: Camera, mode: number): void; +declare function updateCamera(camera: Camera3D, mode: number): void; /** Update camera movement/rotation */ -declare function updateCameraPro(camera: Camera, movement: Vector3, rotation: Vector3, zoom: number): void; +declare function updateCameraPro(camera: Camera3D, movement: Vector3, rotation: Vector3, zoom: number): void; /** Draw a pixel */ declare function drawPixel(posX: number, posY: number, color: Color): void; /** Draw a pixel (Vector version) */ @@ -589,6 +663,8 @@ declare function loadImageFromTexture(texture: Texture): Image; declare function loadImageFromScreen(): Image; /** Check if an image is ready */ declare function isImageReady(image: Image): boolean; +/** Unload image from CPU memory (RAM) */ +declare function unloadImage(image: Image): void; /** Export image data to file, returns true on success */ declare function exportImage(image: Image, fileName: string): boolean; /** Generate image: plain color */ @@ -663,6 +739,8 @@ declare function imageColorContrast(image: Image, contrast: number): void; declare function imageColorBrightness(image: Image, brightness: number): void; /** Modify image color: replace color */ declare function imageColorReplace(image: Image, color: Color, replace: Color): void; +/** Load color data from image as a Color array (RGBA - 32bit) */ +declare function loadImageColors(image: Image): ArrayBuffer; /** Get image alpha border rectangle */ declare function getImageAlphaBorder(image: Image, threshold: number): Rectangle; /** Get image pixel color at (x, y) position */ @@ -705,10 +783,18 @@ declare function loadTexture(fileName: string): Texture; declare function loadTextureFromImage(image: Image): Texture; /** Load cubemap from image, multiple image cubemap layouts supported */ declare function loadTextureCubemap(image: Image, layout: number): Texture; +/** Load texture for rendering (framebuffer) */ +declare function loadRenderTexture(width: number, height: number): RenderTexture; /** Check if a texture is ready */ declare function isTextureReady(texture: Texture): boolean; +/** Unload texture from GPU memory (VRAM) */ +declare function unloadTexture(texture: Texture): void; +/** Check if a render texture is ready */ +declare function isRenderTextureReady(target: RenderTexture): boolean; +/** Unload render texture from GPU memory (VRAM) */ +declare function unloadRenderTexture(target: RenderTexture): void; /** Generate GPU mipmaps for a texture */ -declare function genTextureMipmaps(texture: Texture2D): void; +declare function genTextureMipmaps(texture: Texture): void; /** Set texture scaling filter mode */ declare function setTextureFilter(texture: Texture, filter: number): void; /** Set texture wrapping mode */ @@ -723,6 +809,8 @@ declare function drawTextureEx(texture: Texture, position: Vector2, rotation: nu declare function drawTextureRec(texture: Texture, source: Rectangle, position: Vector2, tint: Color): void; /** Draw a part of a texture defined by a rectangle with 'pro' parameters */ declare function drawTexturePro(texture: Texture, source: Rectangle, dest: Rectangle, origin: Vector2, rotation: number, tint: Color): void; +/** Draws a texture (or part of it) that stretches or shrinks nicely */ +declare function drawTextureNPatch(texture: Texture, nPatchInfo: NPatchInfo, dest: Rectangle, origin: Vector2, rotation: number, tint: Color): void; /** Get color with alpha applied, alpha goes from 0.0f to 1.0f */ declare function fade(color: Color, alpha: number): Color; /** Get hexadecimal value for a Color */ @@ -757,6 +845,8 @@ declare function loadFont(fileName: string): Font; declare function loadFontFromImage(image: Image, key: Color, firstChar: number): Font; /** Check if a font is ready */ declare function isFontReady(font: Font): boolean; +/** Unload font from GPU memory (VRAM) */ +declare function unloadFont(font: Font): void; /** Draw current FPS */ declare function drawFPS(posX: number, posY: number): void; /** Draw text (using default font) */ @@ -821,6 +911,8 @@ declare function loadModel(fileName: string): Model; declare function loadModelFromMesh(mesh: Mesh): Model; /** Check if a model is ready */ declare function isModelReady(model: Model): boolean; +/** Unload model (including meshes) from memory (RAM and/or VRAM) */ +declare function unloadModel(model: Model): void; /** Compute model bounding box limits (considers all meshes) */ declare function getModelBoundingBox(model: Model): BoundingBox; /** Draw a model (with texture if set) */ @@ -841,6 +933,14 @@ declare function drawBillboardRec(camera: Camera3D, texture: Texture, source: Re declare function drawBillboardPro(camera: Camera3D, texture: Texture, source: Rectangle, position: Vector3, up: Vector3, size: Vector2, origin: Vector2, rotation: number, tint: Color): void; /** Upload mesh vertex data in GPU and provide VAO/VBO ids */ declare function uploadMesh(mesh: Mesh, dynamic: boolean): void; +/** Update mesh vertex data in GPU for a specific buffer index */ +declare function updateMeshBuffer(mesh: Mesh, index: number, data: any, dataSize: number, offset: number): void; +/** Unload mesh data from CPU and GPU */ +declare function unloadMesh(mesh: Mesh): void; +/** Draw a 3d mesh with material and transform */ +declare function drawMesh(mesh: Mesh, material: Material, transform: Matrix): void; +/** Draw multiple mesh instances with material and different transforms */ +declare function drawMeshInstanced(mesh: Mesh, material: Material, transforms: Matrix, instances: number): void; /** Export mesh data to file, returns true on success */ declare function exportMesh(mesh: Mesh, fileName: string): boolean; /** Compute mesh bounding box limits */ @@ -869,6 +969,18 @@ declare function genMeshKnot(radius: number, size: number, radSeg: number, sides declare function genMeshHeightmap(heightmap: Image, size: Vector3): Mesh; /** Generate cubes-based map mesh from image data */ declare function genMeshCubicmap(cubicmap: Image, cubeSize: Vector3): Mesh; +/** Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) */ +declare function loadMaterialDefault(): Material; +/** Check if a material is ready */ +declare function isMaterialReady(material: Material): boolean; +/** Unload material from GPU memory (VRAM) */ +declare function unloadMaterial(material: Material): void; +/** Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) */ +declare function setMaterialTexture(material: Material, mapType: number, texture: Texture): void; +/** Replace material in slot materialIndex */ +declare function setModelMaterial(model: Model, materialIndex: number, material: Material): void; +/** Set material for a mesh */ +declare function setModelMeshMaterial(model: Model, meshId: number, materialId: number): void; /** Check collision between two spheres */ declare function checkCollisionSpheres(center1: Vector3, radius1: number, center2: Vector3, radius2: number): boolean; /** Check collision between two bounding boxes */ @@ -903,6 +1015,10 @@ declare function loadSound(fileName: string): Sound; declare function loadSoundFromWave(wave: Wave): Sound; /** Checks if a sound is ready */ declare function isSoundReady(sound: Sound): boolean; +/** Unload wave data */ +declare function unloadWave(wave: Wave): void; +/** Unload sound */ +declare function unloadSound(sound: Sound): void; /** Export wave data to file, returns true on success */ declare function exportWave(wave: Wave, fileName: string): boolean; /** Play a sound */ @@ -931,6 +1047,8 @@ declare function waveFormat(wave: Wave, sampleRate: number, sampleSize: number, declare function loadMusicStream(fileName: string): Music; /** Checks if a music stream is ready */ declare function isMusicReady(music: Music): boolean; +/** Unload music stream */ +declare function unloadMusicStream(music: Music): void; /** Start music playing */ declare function playMusicStream(music: Music): void; /** Check if music is playing */ @@ -1042,9 +1160,9 @@ declare function vector3CrossProduct(v1: Vector3, v2: Vector3): Vector3; /** */ declare function vector3Perpendicular(v: Vector3): Vector3; /** */ -declare function vector3Length(v: const Vector3): number; +declare function vector3Length(v: Vector3): number; /** */ -declare function vector3LengthSqr(v: const Vector3): number; +declare function vector3LengthSqr(v: Vector3): number; /** */ declare function vector3DotProduct(v1: Vector3, v2: Vector3): number; /** */ @@ -1667,3 +1785,29 @@ declare var SHADER_UNIFORM_IVEC3: number; declare var SHADER_UNIFORM_IVEC4: number; /** Shader uniform type: sampler2d */ declare var SHADER_UNIFORM_SAMPLER2D: number; +/** Albedo material (same as: MATERIAL_MAP_DIFFUSE) */ +declare var MATERIAL_MAP_ALBEDO: number; +/** Metalness material (same as: MATERIAL_MAP_SPECULAR) */ +declare var MATERIAL_MAP_METALNESS: number; +/** Normal material */ +declare var MATERIAL_MAP_NORMAL: number; +/** Roughness material */ +declare var MATERIAL_MAP_ROUGHNESS: number; +/** Ambient occlusion material */ +declare var MATERIAL_MAP_OCCLUSION: number; +/** Emission material */ +declare var MATERIAL_MAP_EMISSION: number; +/** Heightmap material */ +declare var MATERIAL_MAP_HEIGHT: number; +/** Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) */ +declare var MATERIAL_MAP_CUBEMAP: number; +/** Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) */ +declare var MATERIAL_MAP_IRRADIANCE: number; +/** Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) */ +declare var MATERIAL_MAP_PREFILTER: number; +/** Brdf material */ +declare var MATERIAL_MAP_BRDF: number; +/** Albedo material (same as: MATERIAL_MAP_DIFFUSE */ +declare var MATERIAL_MAP_DIFFUSE: number; +/** Metalness material (same as: MATERIAL_MAP_SPECULAR) */ +declare var MATERIAL_MAP_SPECULAR: number; diff --git a/examples/models_cubicmap.js b/examples/models_cubicmap.js index 3343687..0da5936 100644 --- a/examples/models_cubicmap.js +++ b/examples/models_cubicmap.js @@ -10,7 +10,6 @@ * Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) * ********************************************************************************************/ - // Initialization //-------------------------------------------------------------------------------------- const screenWidth = 800; @@ -26,19 +25,23 @@ const fovy = 45.0; // Camera field-of-view Y const projection = CAMERA_PERSPECTIVE; // Camera projection type const camera = new Camera3D(position, target, up, fovy, projection) -const image = loadImage("assets/cubicmap.png"); // Load cubicmap image (RAM) -const cubicmap = loadTextureFromImage(image); // Convert image to texture to display (VRAM) +let image = loadImage("assets/cubicmap.png"); // Load cubicmap image (RAM) +let cubicmap = loadTextureFromImage(image); // Convert image to texture to display (VRAM) const mesh = genMeshCubicmap(image, new Vector3(1.0, 1.0, 1.0)); const model = loadModelFromMesh(mesh); // NOTE: By default each cube is mapped to one part of texture atlas -const texture = loadTexture("assets/cubicmap_atlas.png"); // Load map texture +let texture = loadTexture("assets/cubicmap_atlas.png"); // Load map texture + //model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture +const mat = loadMaterialDefault() +setMaterialTexture(mat, MATERIAL_MAP_DIFFUSE, texture) +setModelMaterial(model,0,mat) const mapPosition = new Vector3(-16.0, 0.0, -8.0); // Set model position -image = null; // Unload cubesmap image from RAM, already uploaded to VRAM +unloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM setTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -50,7 +53,7 @@ while (!windowShouldClose()) // Detect window close button or ESC key //---------------------------------------------------------------------------------- updateCamera(camera, CAMERA_ORBITAL); //---------------------------------------------------------------------------------- - + // Draw //---------------------------------------------------------------------------------- beginDrawing(); @@ -77,9 +80,9 @@ while (!windowShouldClose()) // Detect window close button or ESC key // De-Initialization //-------------------------------------------------------------------------------------- -cubicmap = null // Unload cubicmap texture -texture = null // Unload map texture -model = null // Unload map model +unloadTexture(cubicmap); +unloadTexture(texture); +unloadModel(model); closeWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/raymarching.js b/examples/raymarching.js index 9ac6343..b1bdce2 100644 --- a/examples/raymarching.js +++ b/examples/raymarching.js @@ -23,7 +23,7 @@ const viewCenterLoc = getShaderLocation(shader, "viewCenter"); const runTimeLoc = getShaderLocation(shader, "runTime"); const resolutionLoc = getShaderLocation(shader, "resolution"); -let resolution = new Vector2(getRenderWidth(), getRenderHeight()); +let resolution = new Vector2(getRenderWidth()*2, getRenderHeight()*2); setShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2); let runTime = 0.0; @@ -75,5 +75,6 @@ while (!windowShouldClose()) // Detect window close button or ESC key // De-Initialization //-------------------------------------------------------------------------------------- +unloadShader(shader) closeWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/ts_game.js b/examples/ts_game.js new file mode 100644 index 0000000..f0b9ebc --- /dev/null +++ b/examples/ts_game.js @@ -0,0 +1,367 @@ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/examples.ts": +/*!*************************!*\ + !*** ./src/examples.ts ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.FirstPersonMaze = exports.GameController = void 0; +const systems_1 = __webpack_require__(/*! ./systems */ "./src/systems.ts"); +class GameController extends systems_1.SystemContainer { + constructor() { + super(...arguments); + this.systems = [ + new BasicWindow(), + new FirstPersonMaze() + ]; + } + load() { + super.load(); + this.currentIndex = 0; + this.currentId = this.addSystem(this.systems[this.currentIndex]); + } + update(dt) { + if (isKeyPressed(KEY_RIGHT)) { + this.removeSystem(this.currentId); + this.currentIndex = (this.currentIndex + 1) % this.systems.length; + this.currentId = this.addSystem(this.systems[this.currentIndex]); + } + super.update(dt); + } +} +exports.GameController = GameController; +class BasicWindow extends systems_1.SystemBase { + draw() { + super.draw(); + drawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); + } +} +class FirstPersonMaze extends systems_1.SystemBase { + load() { + super.load(); + // Define the camera to look into our 3d world + this.camera = new Camera3D(new Vector3(0.2, 0.4, 0.2), new Vector3(0.185, 0.4, 0.0), new Vector3(0, 1, 0), 45, CAMERA_PERSPECTIVE); + const position = new Vector3(0, 0, 0); // Set model position + const imMap = loadImage("assets/cubicmap.png"); // Load cubicmap image (RAM) + this.cubicmap = loadTextureFromImage(imMap); // Convert image to texture to display (VRAM) + const mesh = genMeshCubicmap(imMap, new Vector3(1.0, 1.0, 1.0)); + this.model = loadModelFromMesh(mesh); + // NOTE: By default each cube is mapped to one part of texture atlas + this.texture = loadTexture("assets/cubicmap_atlas.png"); // Load map texture + //model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture + const mat = loadMaterialDefault(); + setMaterialTexture(mat, MATERIAL_MAP_DIFFUSE, this.texture); + setModelMaterial(this.model, 0, mat); + // Get map image data to be used for collision detection + this.mapPixels = new Uint8Array(loadImageColors(imMap)); + unloadImage(imMap); // Unload image from RAM + this.mapPosition = new Vector3(-16.0, 0.0, -8.0); // Set model position + disableCursor(); + } + update(dt) { + super.update(dt); + let oldCamPos = this.camera.position; // Store old camera position + updateCamera(this.camera, CAMERA_FIRST_PERSON); + // Check player collision (we simplify to 2D collision detection) + const playerPos = new Vector2(this.camera.position.x, this.camera.position.z); + const playerRadius = 0.1; // Collision radius (player is modelled as a cilinder for collision) + this.playerCellX = Math.floor(playerPos.x - this.mapPosition.x + 0.5); + this.playerCellY = Math.floor(playerPos.y - this.mapPosition.z + 0.5); + // Out-of-limits security check + if (this.playerCellX < 0) + this.playerCellX = 0; + else if (this.playerCellX >= this.cubicmap.width) + this.playerCellX = this.cubicmap.width - 1; + if (this.playerCellY < 0) + this.playerCellY = 0; + else if (this.playerCellY >= this.cubicmap.height) + this.playerCellY = this.cubicmap.height - 1; + // Check map collisions using image data and player position + // TODO: Improvement: Just check player surrounding cells for collision + for (let y = 0; y < this.cubicmap.height; y++) { + for (let x = 0; x < this.cubicmap.width; x++) { + const pixelValR = this.mapPixels[((y * this.cubicmap.width + x) * 4)]; + if ((pixelValR == 255) && // Collision: white pixel, only check R channel + (checkCollisionCircleRec(playerPos, playerRadius, new Rectangle(this.mapPosition.x - 0.5 + x * 1.0, this.mapPosition.z - 0.5 + y * 1.0, 1.0, 1.0)))) { + // Collision detected, reset camera position + this.camera.position = oldCamPos; + } + } + } + } + draw() { + super.draw(); + beginMode3D(this.camera); + drawModel(this.model, this.mapPosition, 1.0, WHITE); // Draw maze map + endMode3D(); + drawTextureEx(this.cubicmap, new Vector2(getScreenWidth() - this.cubicmap.width * 4.0 - 20, 20.0), 0.0, 4.0, WHITE); + drawRectangleLines(getScreenWidth() - this.cubicmap.width * 4 - 20, 20, this.cubicmap.width * 4, this.cubicmap.height * 4, GREEN); + // Draw player position radar + drawRectangle(getScreenWidth() - this.cubicmap.width * 4 - 20 + this.playerCellX * 4, 20 + this.playerCellY * 4, 4, 4, RED); + drawFPS(10, 10); + } + unload() { + enableCursor(); + unloadTexture(this.cubicmap); // Unload cubicmap texture + unloadTexture(this.texture); // Unload map texture + unloadModel(this.model); // Unload map model + super.unload(); + } +} +exports.FirstPersonMaze = FirstPersonMaze; + + +/***/ }), + +/***/ "./src/game.ts": +/*!*********************!*\ + !*** ./src/game.ts ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.Game = void 0; +const systems_1 = __webpack_require__(/*! ./systems */ "./src/systems.ts"); +class Game { + constructor(width, height, title) { + this.width = width; + this.height = height; + this.title = title; + this.clearColor = RAYWHITE; + this.systemHost = new systems_1.SystemHost(); + this.quit = false; + } + run() { + initWindow(this.width, this.height, this.title); + setTargetFPS(60); + while (!(this.quit = windowShouldClose())) { + this.systemHost.loadSystems(); + this.systemHost.updateSystems(); + beginDrawing(); + clearBackground(this.clearColor); + this.systemHost.drawSystems(); + this.systemHost.unloadSystems(); + endDrawing(); + } + this.systemHost.requestShutdown(); + closeWindow(); + } + addSystem(system) { + return this.systemHost.addSystem(system); + } + removeSystem(id) { + return this.systemHost.removeSystem(id); + } +} +exports.Game = Game; + + +/***/ }), + +/***/ "./src/systems.ts": +/*!************************!*\ + !*** ./src/systems.ts ***! + \************************/ +/***/ ((__unused_webpack_module, exports) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SystemHost = exports.SystemContainer = exports.SystemBase = void 0; +class SystemBase { + constructor() { + this.isFinished = false; + } + load() { + this.promise = new Promise((res, rej) => this.complete = res); + } + unload() { + this.complete(); + } + draw() { } + update(dt) { } + stop() { + this.isFinished = true; + } +} +exports.SystemBase = SystemBase; +class SystemContainer extends SystemBase { + constructor() { + super(...arguments); + this.systemHost = new SystemHost(); + } + update(dt) { + this.systemHost.loadSystems(); + this.systemHost.updateSystems(); + } + draw() { + this.systemHost.drawSystems(); + this.systemHost.unloadSystems(); + } + unload() { + this.systemHost.requestShutdown(); + super.unload(); + } + addSystem(system) { + return this.systemHost.addSystem(system); + } + removeSystem(id) { + return this.systemHost.removeSystem(id); + } +} +exports.SystemContainer = SystemContainer; +class SystemHost { + constructor() { + this.systems = new Map(); + this.unloadQueue = new Set(); + this.loadQueue = new Set(); + this.updateOrder = []; + this.updateOrderRev = []; + this.systemPrio = 0; + } + addSystem(system) { + const id = this.systemPrio++; + this.systems.set(id, system); + this.loadQueue.add(id); + return id; + } + removeSystem(id) { + if (this.systems.has(id)) { + this.unloadQueue.add(id); + } + } + refreshUpdateOrder() { + this.updateOrder = Array.from(this.systems.keys()).sort((a, b) => a - b); + this.updateOrderRev = this.updateOrder.reverse(); + } + loadSystems() { + if (this.loadQueue.size === 0) + return; + this.refreshUpdateOrder(); + for (const id of this.updateOrder) { + if (this.loadQueue.has(id)) + this.systems.get(id)?.load(); + } + this.loadQueue.clear(); + } + unloadSystems() { + if (this.unloadQueue.size === 0) + return; + for (const id of this.updateOrderRev) { + if (this.unloadQueue.has(id)) { + this.systems.get(id)?.unload(); + this.systems.delete(id); + } + } + this.refreshUpdateOrder(); + this.unloadQueue.clear(); + } + updateSystems() { + for (const id of this.updateOrder) { + this.systems.get(id)?.update(getFrameTime()); + } + } + drawSystems() { + for (const id of this.updateOrder) { + const sys = this.systems.get(id); + sys?.draw(); + if (sys?.isFinished) + this.unloadQueue.add(id); + } + } + requestShutdown() { + for (const id of this.updateOrderRev) { + this.systems.get(id)?.unload(); + } + } +} +exports.SystemHost = SystemHost; + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +var exports = __webpack_exports__; +/*!**********************!*\ + !*** ./src/index.ts ***! + \**********************/ + +Object.defineProperty(exports, "__esModule", ({ value: true })); +const examples_1 = __webpack_require__(/*! ./examples */ "./src/examples.ts"); +const game_1 = __webpack_require__(/*! ./game */ "./src/game.ts"); +const systems_1 = __webpack_require__(/*! ./systems */ "./src/systems.ts"); +class MySys extends systems_1.SystemBase { + load() { + super.load(); + this.mesh = new Mesh(); + this.mesh.vertexCount = 3; + this.mesh.triangleCount = 1; + const v1 = new Vector3(400, 0, 0); + const v2 = new Vector3(0, 450, 0); + const v3 = new Vector3(800, 450, 0); + this.mesh.indices = new Uint16Array([0, 1, 2]).buffer; + this.mesh.vertices = new Float32Array([ + v1.x, v1.y, v1.z, + v2.x, v2.y, v2.z, + v3.x, v3.y, v3.z + ]).buffer; + // If your forget to upload to GPU draw will segfault + uploadMesh(this.mesh, false); + this.material = loadMaterialDefault(); + this.matrix = matrixIdentity(); + } + update(dt) { + this.matrix = matrixRotateZ(getTime()); + } + draw() { + drawMesh(this.mesh, this.material, this.matrix); + } + unload() { + super.unload(); + unloadMaterial(this.material); + unloadMesh(this.mesh); + } +} +const game = new game_1.Game(800, 450, "Typescript Game"); +game.addSystem(new examples_1.GameController()); +game.addSystem(new MySys()); +game.run(); + +})(); + +/******/ })() +; \ No newline at end of file diff --git a/examples/ts_game/.gitignore b/examples/ts_game/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/examples/ts_game/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/examples/ts_game/package-lock.json b/examples/ts_game/package-lock.json new file mode 100644 index 0000000..5f2afea --- /dev/null +++ b/examples/ts_game/package-lock.json @@ -0,0 +1,1689 @@ +{ + "name": "bindings", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "bindings", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "ts-loader": "^9.4.2", + "ts-node": "^10.9.1", + "typescript": "^5.0.4", + "webpack": "^5.82.0", + "webpack-cli": "^5.0.2" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "8.37.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz", + "integrity": "sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz", + "integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.4.tgz", + "integrity": "sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001488", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz", + "integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.401", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.401.tgz", + "integrity": "sha512-AswqHsYyEbfSn0x87n31Na/xttUqEAg7NUjpiyxC20MaWKLyadOYHMzyLdF78N1iw+FK8/2KHLpZxRdyRILgtA==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz", + "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", + "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", + "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.17.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.4.tgz", + "integrity": "sha512-jcEKZw6UPrgugz/0Tuk/PVyLAPfMBJf5clnGueo45wTweoV8yh7Q7PEkhkJ5uuUbC7zAxEcG3tqNr1bstkQ8nw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-loader": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.83.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.83.1.tgz", + "integrity": "sha512-TNsG9jDScbNuB+Lb/3+vYolPplCS3bbEaJf+Bj0Gw4DhP3ioAflBb1flcRt9zsWITyvOhM96wMQNRWlSX52DgA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.1.tgz", + "integrity": "sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.0", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.4", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/examples/ts_game/package.json b/examples/ts_game/package.json new file mode 100644 index 0000000..6ad7a2d --- /dev/null +++ b/examples/ts_game/package.json @@ -0,0 +1,20 @@ +{ + "name": "bindings", + "version": "1.0.0", + "description": "", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack --config webpack.config.js", + "watch": "webpack --watch --config webpack.config.js --mode development" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "ts-loader": "^9.4.2", + "ts-node": "^10.9.1", + "typescript": "^5.0.4", + "webpack": "^5.82.0", + "webpack-cli": "^5.0.2" + } +} diff --git a/examples/ts_game/src/examples.ts b/examples/ts_game/src/examples.ts new file mode 100644 index 0000000..18aa033 --- /dev/null +++ b/examples/ts_game/src/examples.ts @@ -0,0 +1,135 @@ +import { SystemBase, SystemContainer } from "./systems"; + +export class GameController extends SystemContainer { + private currentId!: number + private currentIndex!: number + private systems = [ + new BasicWindow(), + new FirstPersonMaze() + ] + + load(): void { + super.load() + this.currentIndex = 0 + this.currentId = this.addSystem(this.systems[this.currentIndex]) + } + + update(dt: number): void { + if(isKeyPressed(KEY_RIGHT)){ + this.removeSystem(this.currentId) + this.currentIndex = (this.currentIndex+1)%this.systems.length + this.currentId = this.addSystem(this.systems[this.currentIndex]) + } + super.update(dt) + } +} + +class BasicWindow extends SystemBase { + draw(): void { + super.draw() + drawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); + } +} + +export class FirstPersonMaze extends SystemBase { + + private camera!: Camera3D; + private playerCellX!: number; + private playerCellY!: number; + private cubicmap!: Texture; + private texture!: Texture; + private mapPixels!: Uint8Array; + private model!: Model; + private mapPosition!: Vector3; + + load(): void { + super.load() + // Define the camera to look into our 3d world + this.camera = new Camera3D(new Vector3(0.2, 0.4, 0.2), new Vector3(0.185, 0.4, 0.0), new Vector3(0, 1, 0), 45, CAMERA_PERSPECTIVE); + const position = new Vector3(0, 0, 0); // Set model position + + const imMap = loadImage("assets/cubicmap.png"); // Load cubicmap image (RAM) + this.cubicmap = loadTextureFromImage(imMap); // Convert image to texture to display (VRAM) + const mesh = genMeshCubicmap(imMap, new Vector3(1.0, 1.0, 1.0)); + this.model = loadModelFromMesh(mesh); + + // NOTE: By default each cube is mapped to one part of texture atlas + this.texture = loadTexture("assets/cubicmap_atlas.png"); // Load map texture + + //model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture + const mat = loadMaterialDefault(); + setMaterialTexture(mat, MATERIAL_MAP_DIFFUSE, this.texture); + setModelMaterial(this.model, 0, mat); + + // Get map image data to be used for collision detection + this.mapPixels = new Uint8Array(loadImageColors(imMap)); + unloadImage(imMap); // Unload image from RAM + + this.mapPosition = new Vector3(-16.0, 0.0, -8.0); // Set model position + + disableCursor(); + } + + update(dt: number): void { + super.update(dt); + let oldCamPos = this.camera.position; // Store old camera position + + updateCamera(this.camera, CAMERA_FIRST_PERSON); + + // Check player collision (we simplify to 2D collision detection) + const playerPos = new Vector2(this.camera.position.x, this.camera.position.z); + const playerRadius = 0.1; // Collision radius (player is modelled as a cilinder for collision) + + this.playerCellX = Math.floor(playerPos.x - this.mapPosition.x + 0.5); + this.playerCellY = Math.floor(playerPos.y - this.mapPosition.z + 0.5); + + // Out-of-limits security check + if (this.playerCellX < 0) + this.playerCellX = 0; + else if (this.playerCellX >= this.cubicmap.width) + this.playerCellX = this.cubicmap.width - 1; + + if (this.playerCellY < 0) + this.playerCellY = 0; + else if (this.playerCellY >= this.cubicmap.height) + this.playerCellY = this.cubicmap.height - 1; + + // Check map collisions using image data and player position + // TODO: Improvement: Just check player surrounding cells for collision + for (let y = 0; y < this.cubicmap.height; y++) { + for (let x = 0; x < this.cubicmap.width; x++) { + const pixelValR = this.mapPixels[((y * this.cubicmap.width + x) * 4)]; + if ((pixelValR == 255) && // Collision: white pixel, only check R channel + (checkCollisionCircleRec(playerPos, playerRadius, new Rectangle( + this.mapPosition.x - 0.5 + x * 1.0, + this.mapPosition.z - 0.5 + y * 1.0, 1.0, 1.0)))) { + // Collision detected, reset camera position + this.camera.position = oldCamPos; + } + } + } + } + + draw(): void { + super.draw() + beginMode3D(this.camera); + drawModel(this.model, this.mapPosition, 1.0, WHITE); // Draw maze map + endMode3D(); + + drawTextureEx(this.cubicmap, new Vector2(getScreenWidth() - this.cubicmap.width * 4.0 - 20, 20.0), 0.0, 4.0, WHITE); + drawRectangleLines(getScreenWidth() - this.cubicmap.width * 4 - 20, 20, this.cubicmap.width * 4, this.cubicmap.height * 4, GREEN); + + // Draw player position radar + drawRectangle(getScreenWidth() - this.cubicmap.width * 4 - 20 + this.playerCellX * 4, 20 + this.playerCellY * 4, 4, 4, RED); + + drawFPS(10, 10); + } + + unload(): void { + enableCursor(); + unloadTexture(this.cubicmap); // Unload cubicmap texture + unloadTexture(this.texture); // Unload map texture + unloadModel(this.model); // Unload map model + super.unload() + } +} diff --git a/examples/ts_game/src/game.ts b/examples/ts_game/src/game.ts new file mode 100644 index 0000000..d90c1ea --- /dev/null +++ b/examples/ts_game/src/game.ts @@ -0,0 +1,38 @@ +import { System, SystemHost } from "./systems" + +export class Game { + public clearColor = RAYWHITE + private systemHost = new SystemHost() + private quit = false + + constructor(public readonly width: number, + public readonly height: number, + public readonly title: string){ + } + + public run(){ + initWindow(this.width,this.height,this.title) + setTargetFPS(60) + while(!(this.quit = windowShouldClose())){ + this.systemHost.loadSystems() + this.systemHost.updateSystems() + beginDrawing() + clearBackground(this.clearColor) + this.systemHost.drawSystems() + this.systemHost.unloadSystems() + endDrawing() + } + this.systemHost.requestShutdown() + closeWindow() + } + + addSystem(system: System){ + return this.systemHost.addSystem(system) + } + + removeSystem(id: number){ + return this.systemHost.removeSystem(id) + } + + +} \ No newline at end of file diff --git a/examples/ts_game/src/index.ts b/examples/ts_game/src/index.ts new file mode 100644 index 0000000..1417c85 --- /dev/null +++ b/examples/ts_game/src/index.ts @@ -0,0 +1,46 @@ +import { GameController } from "./examples"; +import { Game } from "./game"; +import { SystemBase, SystemContainer } from "./systems"; + +class MySys extends SystemBase { + mesh!: Mesh; + material!: Material + matrix!: Matrix + + load(): void { + super.load() + this.mesh = new Mesh() + this.mesh.vertexCount = 3 + this.mesh.triangleCount = 1 + const v1 = new Vector3(400, 0, 0) + const v2 = new Vector3(0, 450, 0 ) + const v3 = new Vector3(800, 450, 0) + this.mesh.indices = new Uint16Array([0,1,2]).buffer + this.mesh.vertices = new Float32Array([ + v1.x, v1.y, v1.z, + v2.x, v2.y, v2.z, + v3.x, v3.y, v3.z + ]).buffer + // If your forget to upload to GPU draw will segfault + uploadMesh(this.mesh, false) + this.material = loadMaterialDefault() + this.matrix = matrixIdentity() + } + update(dt: number): void { + this.matrix = matrixRotateZ(getTime()) + } + draw(): void { + drawMesh(this.mesh, this.material, this.matrix) + } + unload(): void { + super.unload() + unloadMaterial(this.material) + unloadMesh(this.mesh) + } +} + + +const game = new Game(800,450,"Typescript Game") +game.addSystem(new GameController()) +game.addSystem(new MySys()) +game.run() \ No newline at end of file diff --git a/examples/ts_game/src/systems.ts b/examples/ts_game/src/systems.ts new file mode 100644 index 0000000..0b5915c --- /dev/null +++ b/examples/ts_game/src/systems.ts @@ -0,0 +1,122 @@ +export interface System { + isFinished: boolean; + load(): void; + unload(): void; + draw(): void; + update(dt: number): void; +} + +export abstract class SystemBase implements System { + + public promise!: Promise + private complete!: () => void + public isFinished = false + + load(): void { + this.promise = new Promise((res,rej) => this.complete = res) + } + + unload(): void { + this.complete() + } + draw(): void {} + update(dt: number): void {} + stop(){ + this.isFinished = true + } +} + +export class SystemContainer extends SystemBase { + private systemHost = new SystemHost() + + update(dt: number): void { + this.systemHost.loadSystems() + this.systemHost.updateSystems() + } + + draw(): void { + this.systemHost.drawSystems() + this.systemHost.unloadSystems() + } + + unload(): void { + this.systemHost.requestShutdown() + super.unload() + } + + addSystem(system: System){ + return this.systemHost.addSystem(system) + } + + removeSystem(id: number){ + return this.systemHost.removeSystem(id) + } +} + +export class SystemHost { + private systems = new Map() + private unloadQueue = new Set() + private loadQueue = new Set() + private updateOrder: number[] = [] + private updateOrderRev: number[] = [] + private systemPrio = 0 + + public addSystem(system: System){ + const id = this.systemPrio++ + this.systems.set(id, system) + this.loadQueue.add(id) + return id + } + + public removeSystem(id: number){ + if(this.systems.has(id)) { + this.unloadQueue.add(id) + } + } + + private refreshUpdateOrder(){ + this.updateOrder = Array.from(this.systems.keys()).sort((a, b) => a - b); + this.updateOrderRev = this.updateOrder.reverse() + } + + public loadSystems(){ + if(this.loadQueue.size === 0) return + this.refreshUpdateOrder() + for (const id of this.updateOrder) { + if(this.loadQueue.has(id)) this.systems.get(id)?.load() + } + this.loadQueue.clear() + } + + public unloadSystems(){ + if(this.unloadQueue.size === 0) return + for (const id of this.updateOrderRev) { + if(this.unloadQueue.has(id)) { + this.systems.get(id)?.unload() + this.systems.delete(id) + } + } + this.refreshUpdateOrder() + this.unloadQueue.clear() + } + + public updateSystems(){ + for (const id of this.updateOrder) { + this.systems.get(id)?.update(getFrameTime()) + } + } + + public drawSystems(){ + for (const id of this.updateOrder) { + const sys = this.systems.get(id) + sys?.draw() + if(sys?.isFinished) this.unloadQueue.add(id) + } + } + + public requestShutdown(){ + for (const id of this.updateOrderRev) { + this.systems.get(id)?.unload() + } + } +} \ No newline at end of file diff --git a/examples/ts_game/tsconfig.json b/examples/ts_game/tsconfig.json new file mode 100644 index 0000000..ec193a6 --- /dev/null +++ b/examples/ts_game/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "resolveJsonModule": true, + "strict": true, + "types": [ + "../lib.raylib" + ] + } + } + \ No newline at end of file diff --git a/examples/ts_game/webpack.config.js b/examples/ts_game/webpack.config.js new file mode 100644 index 0000000..516246c --- /dev/null +++ b/examples/ts_game/webpack.config.js @@ -0,0 +1,24 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.ts', + devtool: false, + target: "node", + mode: 'production', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'ts_game.js', + path: path.resolve(__dirname, '..'), + }, +}; diff --git a/generate-bindings.js b/generate-bindings.js index a9f11ba..f5ccccc 100644 --- a/generate-bindings.js +++ b/generate-bindings.js @@ -20,6 +20,7 @@ class ApiFunction { get argc() { return this.api.params?.length || 0; } get params() { return this.api.params || []; } get returnType() { return this.api.returnType; } + set returnType(v) { this.api.returnType = v; } get description() { return this.api.description; } } exports.ApiFunction = ApiFunction; @@ -378,6 +379,19 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { } jsToC(type, name, src, classIds = {}, supressDeclaration = false) { switch (type) { + // Array Buffer + case "const void *": + case "void *": + case "float *": + case "unsigned short *": + case "unsigned char *": + this.declare(name + "_size", "size_t"); + this.declare(name + "_js", "void *", false, `(void *)JS_GetArrayBuffer(ctx, &${name}_size, ${src})`); + this.if(name + "_js == NULL").returnExp("JS_EXCEPTION"); + this.declare(name, type, false, "malloc(" + name + "_size)"); + this.call("memcpy", ["(void *)" + name, "(const void *)" + name + "_js", name + "_size"]); + break; + // String case "const char *": case "char *": if (!supressDeclaration) @@ -422,6 +436,7 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { else this.statement(`${name} = JS_ToBool(ctx, ${src})`); break; + // Structs / Struct * default: const isConst = type.startsWith('const'); const isPointer = type.endsWith(' *'); @@ -474,9 +489,17 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { } jsCleanUpParameter(type, name) { switch (type) { + case "char *": case "const char *": this.statement(`JS_FreeCString(ctx, ${name})`); break; + case "const void *": + case "void *": + case "float *": + case "unsigned short *": + case "unsigned char *": + this.statement(`free((void *)${name})`); + break; default: break; } @@ -511,7 +534,7 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { const body = this.function(`js_${structName}_finalizer`, "void", args, true); body.statement(`${structName}* ptr = JS_GetOpaque(val, ${classId})`); body.if("ptr", cond => { - //cond.call("TraceLog", ["LOG_INFO",`"Finalize ${structName}"`]) + //cond.call("TraceLog", ["LOG_INFO",`"Finalize ${structName} %p"`,"ptr"]) if (onFinalize) onFinalize(cond, "ptr"); cond.call("js_free_rt", ["rt", "ptr"]); @@ -534,9 +557,6 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { 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})`); - fun.if("!ptr", cond => { - cond.returnExp("JS_EXCEPTION"); - }); fun.declare(field, type, false, "ptr->" + field); fun.jsToJs(type, "ret", field, classIds); fun.returnExp("ret"); @@ -546,9 +566,6 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { 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", classIds); fun.statement("ptr->" + field + " = value"); fun.returnExp("JS_UNDEFINED"); @@ -667,8 +684,8 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { classFuncList.jsPropStringDef("[Symbol.toStringTag]", struct.name); 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, this.structLookup); + if (options?.createConstructor || options?.createEmptyConstructor) { + const body = this.functions.jsStructConstructor(struct.name, options?.createEmptyConstructor ? [] : 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 + '"']); @@ -734,7 +751,7 @@ class TypeScriptDeclaration { addStruct(api, options) { var fields = api.fields.filter(x => !!(options.properties || {})[x.name]).map(x => ({ name: x.name, description: x.description, type: this.toJsType(x.type) })); this.structs.tsDeclareInterface(api.name, fields); - this.structs.tsDeclareType(api.name, !!options.createConstructor, fields); + this.structs.tsDeclareType(api.name, !!(options.createConstructor || options.createEmptyConstructor), options.createEmptyConstructor ? [] : fields); } toJsType(type) { switch (type) { @@ -745,6 +762,10 @@ class TypeScriptDeclaration { case "float": case "double": return "number"; + case "unsigned char *": + case "unsigned short *": + case "float *": + return "ArrayBuffer"; case "bool": return "boolean"; case "const char *": @@ -754,14 +775,19 @@ class TypeScriptDeclaration { case "const void *": return "any"; case "Camera": + case "Camera *": return "Camera3D"; case "Texture2D": + case "Texture2D *": case "TextureCubemap": return "Texture"; + case "RenderTexture2D": + case "RenderTexture2D *": + return "RenderTexture"; case "Quaternion": return "Vector4"; default: - return type.replace(" *", ""); + return type.replace(" *", "").replace("const ", ""); } } writeTo(filename) { @@ -891,6 +917,12 @@ function main() { const mathApi = parseMathHeader(); (0, fs_1.writeFileSync)("bindings/raylib_math_api.json", JSON.stringify(mathApi)); const api = JSON.parse((0, fs_1.readFileSync)("thirdparty/raylib/parser/output/raylib_api.json", 'utf8')); + api.functions.push({ + name: "SetModelMaterial", + description: "Replace material in slot materialIndex", + returnType: "void", + params: [{ type: "Model *", name: "model" }, { type: "int", name: "materialIndex" }, { type: "Material", name: "material" }] + }); mathApi.forEach(x => api.functions.push(x)); const apiDesc = new api_1.ApiDescription(api); const core = new raylib_header_1.RayLibHeader("raylib_core", apiDesc); @@ -979,6 +1011,17 @@ function main() { properties: {}, createConstructor: false }); + core.addApiStructByName("NPatchInfo", { + properties: { + source: { get: true, set: true }, + left: { get: true, set: true }, + top: { get: true, set: true }, + right: { get: true, set: true }, + bottom: { get: true, set: true }, + layout: { get: true, set: true }, + }, + createConstructor: true + }); core.addApiStructByName("Image", { properties: { width: { get: true }, @@ -986,7 +1029,7 @@ function main() { mipmaps: { get: true }, format: { get: true } }, - destructor: "UnloadImage" + //destructor: "UnloadImage" }); core.addApiStructByName("Wave", { properties: { @@ -995,45 +1038,79 @@ function main() { sampleSize: { get: true }, channels: { get: true } }, - destructor: "UnloadWave" + //destructor: "UnloadWave" }); core.addApiStructByName("Sound", { properties: { frameCount: { get: true } }, - destructor: "UnloadSound" + //destructor: "UnloadSound" }); core.addApiStructByName("Music", { properties: { frameCount: { get: true }, looping: { get: true, set: true } }, - destructor: "UnloadMusicStream" + //destructor: "UnloadMusicStream" }); core.addApiStructByName("Model", { properties: {}, - destructor: "UnloadModel" + //destructor: "UnloadModel" }); core.addApiStructByName("Mesh", { - properties: {}, - destructor: "UnloadMesh" + properties: { + vertexCount: { get: true, set: true }, + triangleCount: { get: true, set: true }, + // TODO: Free previous pointers before overwriting + vertices: { set: true }, + texcoords: { set: true }, + texcoords2: { set: true }, + normals: { set: true }, + tangents: { set: true }, + colors: { set: true }, + indices: { set: true }, + animVertices: { set: true }, + animNormals: { set: true }, + boneIds: { set: true }, + boneWeights: { set: true }, + }, + createEmptyConstructor: true + //destructor: "UnloadMesh" }); core.addApiStructByName("Shader", { properties: {}, - destructor: "UnloadShader" + //destructor: "UnloadShader" }); core.addApiStructByName("Texture", { properties: { width: { get: true }, height: { get: true } }, - destructor: "UnloadTexture" + //destructor: "UnloadTexture" }); core.addApiStructByName("Font", { properties: { baseSize: { get: true } }, - destructor: "UnloadFont" + //destructor: "UnloadFont" + }); + core.addApiStructByName("RenderTexture", { + properties: {}, + //destructor: "UnloadRenderTexture" + }); + core.addApiStructByName("MaterialMap", { + properties: { + texture: { set: true }, + color: { set: true, get: true }, + value: { get: true, set: true } + }, + //destructor: "UnloadMaterialMap" + }); + core.addApiStructByName("Material", { + properties: { + shader: { set: true } + }, + //destructor: "UnloadMaterial" }); // Window-related functions core.addApiFunctionByName("InitWindow"); @@ -1098,8 +1175,8 @@ function main() { core.addApiFunctionByName("EndMode2D"); core.addApiFunctionByName("BeginMode3D"); core.addApiFunctionByName("EndMode3D"); - //core.addApiFunctionByName("BeginTextureMode") - //core.addApiFunctionByName("EndTextureMode") + core.addApiFunctionByName("BeginTextureMode"); + core.addApiFunctionByName("EndTextureMode"); core.addApiFunctionByName("BeginShaderMode"); core.addApiFunctionByName("EndShaderMode"); core.addApiFunctionByName("BeginBlendMode"); @@ -1148,7 +1225,7 @@ function main() { // core.addApiFunctionByName("SetShaderValueV") core.addApiFunctionByName("SetShaderValueMatrix"); core.addApiFunctionByName("SetShaderValueTexture"); - // "UnloadShader" called by finalizer + core.addApiFunctionByName("UnloadShader"); // ScreenSpaceRelatedFunctions core.addApiFunctionByName("GetMouseRay"); core.addApiFunctionByName("GetCameraMatrix"); @@ -1322,7 +1399,7 @@ function main() { core.addApiFunctionByName("LoadImageFromTexture"); core.addApiFunctionByName("LoadImageFromScreen"); core.addApiFunctionByName("IsImageReady"); - // UnloadImage called by destructor + core.addApiFunctionByName("UnloadImage"); core.addApiFunctionByName("ExportImage"); // needed? // core.addApiFunctionByName("ExportImageAsCode") @@ -1364,7 +1441,15 @@ function main() { core.addApiFunctionByName("ImageColorContrast"); core.addApiFunctionByName("ImageColorBrightness"); core.addApiFunctionByName("ImageColorReplace"); - //core.addApiFunctionByName("LoadImageColors") + const lic = apiDesc.getFunction("LoadImageColors"); + lic.returnType = "unsigned char *"; + core.addApiFunction(lic, null, { body: (gen) => { + gen.jsToC("Image", "image", "argv[0]", core.structLookup); + gen.call("LoadImageColors", ["image"], { name: "colors", type: "Color *" }); + gen.statement("JSValue retVal = JS_NewArrayBufferCopy(ctx, (const uint8_t*)colors, image.width*image.height*sizeof(Color))"); + gen.call("UnloadImageColors", ["colors"]); + gen.returnExp("retVal"); + } }); //core.addApiFunctionByName("LoadImagePalette") //core.addApiFunctionByName("UnloadImageColors") //core.addApiFunctionByName("UnloadImagePalette") @@ -1391,11 +1476,11 @@ function main() { core.addApiFunctionByName("LoadTexture"); core.addApiFunctionByName("LoadTextureFromImage"); core.addApiFunctionByName("LoadTextureCubemap"); - // core.addApiFunctionByName("LoadRenderTexture") + core.addApiFunctionByName("LoadRenderTexture"); core.addApiFunctionByName("IsTextureReady"); - // "UnloadTexture" called by finalizer - // core.addApiFunctionByName("IsRenderTextureReady") - // core.addApiFunctionByName("UnloadRenderTexture") + core.addApiFunctionByName("UnloadTexture"); + core.addApiFunctionByName("IsRenderTextureReady"); + core.addApiFunctionByName("UnloadRenderTexture"); // core.addApiFunctionByName("UpdateTexture") // core.addApiFunctionByName("UpdateTextureRec") // Texture configuration functions @@ -1408,7 +1493,7 @@ function main() { core.addApiFunctionByName("DrawTextureEx"); core.addApiFunctionByName("DrawTextureRec"); core.addApiFunctionByName("DrawTexturePro"); - // core.addApiFunctionByName("DrawTextureNPatch") + core.addApiFunctionByName("DrawTextureNPatch"); // Color/pixel related functions core.addApiFunctionByName("Fade"); core.addApiFunctionByName("ColorToInt"); @@ -1436,7 +1521,7 @@ function main() { // core.addApiFunctionByName("LoadFontData") // core.addApiFunctionByName("GenImageFontAtlas") // core.addApiFunctionByName("UnloadFontData") - // "UnloadFont" called by finalizer + core.addApiFunctionByName("UnloadFont"); // core.addApiFunctionByName("ExportFontAsCode") // Text drawing functions core.addApiFunctionByName("DrawFPS"); @@ -1491,7 +1576,7 @@ function main() { core.addApiFunctionByName("LoadModel"); core.addApiFunctionByName("LoadModelFromMesh"); core.addApiFunctionByName("IsModelReady"); - // "UnloadModel" called by finalizer + core.addApiFunctionByName("UnloadModel"); core.addApiFunctionByName("GetModelBoundingBox"); // model drawing functions core.addApiFunctionByName("DrawModel"); @@ -1505,10 +1590,10 @@ function main() { // Mesh management functions // TODO: Refcounting needed? core.addApiFunctionByName("UploadMesh"); - // core.addApiFunctionByName("UpdateMeshBuffer") - // "UnloadMesh" called by finalizer - //core.addApiFunctionByName("DrawMesh") - // core.addApiFunctionByName("DrawMeshInstanced") + core.addApiFunctionByName("UpdateMeshBuffer"); + core.addApiFunctionByName("UnloadMesh"); + core.addApiFunctionByName("DrawMesh"); + core.addApiFunctionByName("DrawMeshInstanced"); core.addApiFunctionByName("ExportMesh"); core.addApiFunctionByName("GetMeshBoundingBox"); core.addApiFunctionByName("GenMeshTangents"); @@ -1526,11 +1611,12 @@ function main() { core.addApiFunctionByName("GenMeshCubicmap"); // Material loading/unloading functions // core.addApiFunctionByName("LoadMaterials") - // core.addApiFunctionByName("LoadMaterialDefault") - // core.addApiFunctionByName("IsMaterialReady") - // core.addApiFunctionByName("UnloadMaterial") - // core.addApiFunctionByName("SetMaterialTexture") - // core.addApiFunctionByName("SetModelMeshMaterial") + core.addApiFunctionByName("LoadMaterialDefault"); + core.addApiFunctionByName("IsMaterialReady"); + core.addApiFunctionByName("UnloadMaterial"); + core.addApiFunctionByName("SetMaterialTexture"); + core.addApiFunctionByName("SetModelMaterial"); + core.addApiFunctionByName("SetModelMeshMaterial"); // Model animations loading/unloading functions // core.addApiFunctionByName("LoadModelAnimations") // core.addApiFunctionByName("UpdateModelAnimation") @@ -1560,8 +1646,8 @@ function main() { core.addApiFunctionByName("LoadSoundFromWave"); core.addApiFunctionByName("IsSoundReady"); // core.addApiFunctionByName("UpdateSound") - // "UnloadWave" called by finalizer - // "UnloadSound" called by finalizer + core.addApiFunctionByName("UnloadWave"); + core.addApiFunctionByName("UnloadSound"); core.addApiFunctionByName("ExportWave"); // core.addApiFunctionByName("ExportWaveAsCode") // Wave/Sound management functions @@ -1582,7 +1668,7 @@ function main() { core.addApiFunctionByName("LoadMusicStream"); // core.addApiFunctionByName("LoadMusicStreamFromMemory") core.addApiFunctionByName("IsMusicReady"); - // "UnloadMusicStream" called by finalizer + core.addApiFunctionByName("UnloadMusicStream"); core.addApiFunctionByName("PlayMusicStream"); core.addApiFunctionByName("IsMusicStreamPlaying"); core.addApiFunctionByName("UpdateMusicStream"); @@ -1742,6 +1828,9 @@ function main() { api.enums.find(x => x.name === "CameraMode")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)); api.enums.find(x => x.name === "ShaderLocationIndex")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)); api.enums.find(x => x.name === "ShaderUniformDataType")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)); + api.enums.find(x => x.name === "MaterialMapIndex")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description)); + core.exportGlobalConstant("MATERIAL_MAP_DIFFUSE", "Albedo material (same as: MATERIAL_MAP_DIFFUSE"); + core.exportGlobalConstant("MATERIAL_MAP_SPECULAR", "Metalness material (same as: MATERIAL_MAP_SPECULAR)"); core.writeTo("src/bindings/js_raylib_core.h"); core.typings.writeTo("examples/lib.raylib.d.ts"); } diff --git a/src/bindings/js_raylib_core.h b/src/bindings/js_raylib_core.h index 426af00..284bd43 100644 --- a/src/bindings/js_raylib_core.h +++ b/src/bindings/js_raylib_core.h @@ -24,6 +24,7 @@ static JSClassID js_Camera2D_class_id; static JSClassID js_Camera3D_class_id; static JSClassID js_BoundingBox_class_id; static JSClassID js_Matrix_class_id; +static JSClassID js_NPatchInfo_class_id; static JSClassID js_Image_class_id; static JSClassID js_Wave_class_id; static JSClassID js_Sound_class_id; @@ -33,6 +34,9 @@ static JSClassID js_Mesh_class_id; static JSClassID js_Shader_class_id; static JSClassID js_Texture_class_id; static JSClassID js_Font_class_id; +static JSClassID js_RenderTexture_class_id; +static JSClassID js_MaterialMap_class_id; +static JSClassID js_Material_class_id; static void js_Color_finalizer(JSRuntime * rt, JSValue val) { Color* ptr = JS_GetOpaque(val, js_Color_class_id); @@ -43,9 +47,6 @@ static void js_Color_finalizer(JSRuntime * rt, JSValue val) { static JSValue js_Color_get_r(JSContext* ctx, JSValueConst this_val) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned char r = ptr->r; JSValue ret = JS_NewUint32(ctx, r); return ret; @@ -53,9 +54,6 @@ static JSValue js_Color_get_r(JSContext* ctx, JSValueConst this_val) { static JSValue js_Color_set_r(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int _int_value; JS_ToUint32(ctx, &_int_value, v); unsigned char value = (unsigned char)_int_value; @@ -65,9 +63,6 @@ static JSValue js_Color_set_r(JSContext* ctx, JSValueConst this_val, JSValueCons static JSValue js_Color_get_g(JSContext* ctx, JSValueConst this_val) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned char g = ptr->g; JSValue ret = JS_NewUint32(ctx, g); return ret; @@ -75,9 +70,6 @@ static JSValue js_Color_get_g(JSContext* ctx, JSValueConst this_val) { static JSValue js_Color_set_g(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int _int_value; JS_ToUint32(ctx, &_int_value, v); unsigned char value = (unsigned char)_int_value; @@ -87,9 +79,6 @@ static JSValue js_Color_set_g(JSContext* ctx, JSValueConst this_val, JSValueCons static JSValue js_Color_get_b(JSContext* ctx, JSValueConst this_val) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned char b = ptr->b; JSValue ret = JS_NewUint32(ctx, b); return ret; @@ -97,9 +86,6 @@ static JSValue js_Color_get_b(JSContext* ctx, JSValueConst this_val) { static JSValue js_Color_set_b(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int _int_value; JS_ToUint32(ctx, &_int_value, v); unsigned char value = (unsigned char)_int_value; @@ -109,9 +95,6 @@ static JSValue js_Color_set_b(JSContext* ctx, JSValueConst this_val, JSValueCons static JSValue js_Color_get_a(JSContext* ctx, JSValueConst this_val) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned char a = ptr->a; JSValue ret = JS_NewUint32(ctx, a); return ret; @@ -119,9 +102,6 @@ static JSValue js_Color_get_a(JSContext* ctx, JSValueConst this_val) { static JSValue js_Color_set_a(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Color* ptr = JS_GetOpaque2(ctx, this_val, js_Color_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int _int_value; JS_ToUint32(ctx, &_int_value, v); unsigned char value = (unsigned char)_int_value; @@ -156,9 +136,6 @@ static void js_Rectangle_finalizer(JSRuntime * rt, JSValue val) { 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; @@ -166,9 +143,6 @@ static JSValue js_Rectangle_get_x(JSContext* ctx, JSValueConst this_val) { 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; @@ -178,9 +152,6 @@ static JSValue js_Rectangle_set_x(JSContext* ctx, JSValueConst this_val, JSValue 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; @@ -188,9 +159,6 @@ static JSValue js_Rectangle_get_y(JSContext* ctx, JSValueConst this_val) { 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; @@ -200,9 +168,6 @@ static JSValue js_Rectangle_set_y(JSContext* ctx, JSValueConst this_val, JSValue 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; @@ -210,9 +175,6 @@ static JSValue js_Rectangle_get_width(JSContext* ctx, JSValueConst this_val) { 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; @@ -222,9 +184,6 @@ static JSValue js_Rectangle_set_width(JSContext* ctx, JSValueConst this_val, JSV 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; @@ -232,9 +191,6 @@ static JSValue js_Rectangle_get_height(JSContext* ctx, JSValueConst this_val) { 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; @@ -269,9 +225,6 @@ static void js_Vector2_finalizer(JSRuntime * rt, JSValue val) { static JSValue js_Vector2_get_x(JSContext* ctx, JSValueConst this_val) { Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float x = ptr->x; JSValue ret = JS_NewFloat64(ctx, x); return ret; @@ -279,9 +232,6 @@ static JSValue js_Vector2_get_x(JSContext* ctx, JSValueConst this_val) { static JSValue js_Vector2_set_x(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -291,9 +241,6 @@ static JSValue js_Vector2_set_x(JSContext* ctx, JSValueConst this_val, JSValueCo static JSValue js_Vector2_get_y(JSContext* ctx, JSValueConst this_val) { Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float y = ptr->y; JSValue ret = JS_NewFloat64(ctx, y); return ret; @@ -301,9 +248,6 @@ static JSValue js_Vector2_get_y(JSContext* ctx, JSValueConst this_val) { static JSValue js_Vector2_set_y(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -336,9 +280,6 @@ static void js_Vector3_finalizer(JSRuntime * rt, JSValue val) { 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; @@ -346,9 +287,6 @@ static JSValue js_Vector3_get_x(JSContext* ctx, JSValueConst this_val) { 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; @@ -358,9 +296,6 @@ static JSValue js_Vector3_set_x(JSContext* ctx, JSValueConst this_val, JSValueCo 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; @@ -368,9 +303,6 @@ static JSValue js_Vector3_get_y(JSContext* ctx, JSValueConst this_val) { 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; @@ -380,9 +312,6 @@ static JSValue js_Vector3_set_y(JSContext* ctx, JSValueConst this_val, JSValueCo 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; @@ -390,9 +319,6 @@ static JSValue js_Vector3_get_z(JSContext* ctx, JSValueConst this_val) { 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; @@ -426,9 +352,6 @@ static void js_Vector4_finalizer(JSRuntime * rt, JSValue val) { static JSValue js_Vector4_get_x(JSContext* ctx, JSValueConst this_val) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float x = ptr->x; JSValue ret = JS_NewFloat64(ctx, x); return ret; @@ -436,9 +359,6 @@ static JSValue js_Vector4_get_x(JSContext* ctx, JSValueConst this_val) { static JSValue js_Vector4_set_x(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -448,9 +368,6 @@ static JSValue js_Vector4_set_x(JSContext* ctx, JSValueConst this_val, JSValueCo static JSValue js_Vector4_get_y(JSContext* ctx, JSValueConst this_val) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float y = ptr->y; JSValue ret = JS_NewFloat64(ctx, y); return ret; @@ -458,9 +375,6 @@ static JSValue js_Vector4_get_y(JSContext* ctx, JSValueConst this_val) { static JSValue js_Vector4_set_y(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -470,9 +384,6 @@ static JSValue js_Vector4_set_y(JSContext* ctx, JSValueConst this_val, JSValueCo static JSValue js_Vector4_get_z(JSContext* ctx, JSValueConst this_val) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float z = ptr->z; JSValue ret = JS_NewFloat64(ctx, z); return ret; @@ -480,9 +391,6 @@ static JSValue js_Vector4_get_z(JSContext* ctx, JSValueConst this_val) { static JSValue js_Vector4_set_z(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -492,9 +400,6 @@ static JSValue js_Vector4_set_z(JSContext* ctx, JSValueConst this_val, JSValueCo static JSValue js_Vector4_get_w(JSContext* ctx, JSValueConst this_val) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float w = ptr->w; JSValue ret = JS_NewFloat64(ctx, w); return ret; @@ -502,9 +407,6 @@ static JSValue js_Vector4_get_w(JSContext* ctx, JSValueConst this_val) { static JSValue js_Vector4_set_w(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Vector4* ptr = JS_GetOpaque2(ctx, this_val, js_Vector4_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -539,9 +441,6 @@ static void js_Ray_finalizer(JSRuntime * rt, JSValue val) { 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; @@ -551,9 +450,6 @@ static JSValue js_Ray_set_position(JSContext* ctx, JSValueConst this_val, JSValu 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; @@ -586,9 +482,6 @@ static void js_RayCollision_finalizer(JSRuntime * rt, JSValue val) { static JSValue js_RayCollision_get_hit(JSContext* ctx, JSValueConst this_val) { RayCollision* ptr = JS_GetOpaque2(ctx, this_val, js_RayCollision_class_id); - if(!ptr) { - return JS_EXCEPTION; - } bool hit = ptr->hit; JSValue ret = JS_NewBool(ctx, hit); return ret; @@ -596,9 +489,6 @@ static JSValue js_RayCollision_get_hit(JSContext* ctx, JSValueConst this_val) { static JSValue js_RayCollision_get_distance(JSContext* ctx, JSValueConst this_val) { RayCollision* ptr = JS_GetOpaque2(ctx, this_val, js_RayCollision_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float distance = ptr->distance; JSValue ret = JS_NewFloat64(ctx, distance); return ret; @@ -629,9 +519,6 @@ static void js_Camera2D_finalizer(JSRuntime * rt, JSValue val) { 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; @@ -641,9 +528,6 @@ static JSValue js_Camera2D_set_offset(JSContext* ctx, JSValueConst this_val, JSV 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; @@ -653,9 +537,6 @@ static JSValue js_Camera2D_set_target(JSContext* ctx, JSValueConst this_val, JSV 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; @@ -663,9 +544,6 @@ static JSValue js_Camera2D_get_rotation(JSContext* ctx, JSValueConst this_val) { 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; @@ -675,9 +553,6 @@ static JSValue js_Camera2D_set_rotation(JSContext* ctx, JSValueConst this_val, J 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; @@ -685,9 +560,6 @@ static JSValue js_Camera2D_get_zoom(JSContext* ctx, JSValueConst this_val) { 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; @@ -722,9 +594,6 @@ static void js_Camera3D_finalizer(JSRuntime * rt, JSValue val) { static JSValue js_Camera3D_get_position(JSContext* ctx, JSValueConst this_val) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_class_id); - if(!ptr) { - return JS_EXCEPTION; - } Vector3 position = ptr->position; Vector3* ret_ptr = (Vector3*)js_malloc(ctx, sizeof(Vector3)); *ret_ptr = position; @@ -735,9 +604,6 @@ static JSValue js_Camera3D_get_position(JSContext* ctx, JSValueConst this_val) { static JSValue js_Camera3D_set_position(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_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; @@ -747,9 +613,6 @@ static JSValue js_Camera3D_set_position(JSContext* ctx, JSValueConst this_val, J static JSValue js_Camera3D_get_target(JSContext* ctx, JSValueConst this_val) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_class_id); - if(!ptr) { - return JS_EXCEPTION; - } Vector3 target = ptr->target; Vector3* ret_ptr = (Vector3*)js_malloc(ctx, sizeof(Vector3)); *ret_ptr = target; @@ -760,9 +623,6 @@ static JSValue js_Camera3D_get_target(JSContext* ctx, JSValueConst this_val) { static JSValue js_Camera3D_set_target(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_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; @@ -772,9 +632,6 @@ static JSValue js_Camera3D_set_target(JSContext* ctx, JSValueConst this_val, JSV static JSValue js_Camera3D_set_up(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_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; @@ -784,9 +641,6 @@ static JSValue js_Camera3D_set_up(JSContext* ctx, JSValueConst this_val, JSValue static JSValue js_Camera3D_get_fovy(JSContext* ctx, JSValueConst this_val) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_class_id); - if(!ptr) { - return JS_EXCEPTION; - } float fovy = ptr->fovy; JSValue ret = JS_NewFloat64(ctx, fovy); return ret; @@ -794,9 +648,6 @@ static JSValue js_Camera3D_get_fovy(JSContext* ctx, JSValueConst this_val) { static JSValue js_Camera3D_set_fovy(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_class_id); - if(!ptr) { - return JS_EXCEPTION; - } double _double_value; JS_ToFloat64(ctx, &_double_value, v); float value = (float)_double_value; @@ -806,9 +657,6 @@ static JSValue js_Camera3D_set_fovy(JSContext* ctx, JSValueConst this_val, JSVal static JSValue js_Camera3D_get_projection(JSContext* ctx, JSValueConst this_val) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int projection = ptr->projection; JSValue ret = JS_NewInt32(ctx, projection); return ret; @@ -816,9 +664,6 @@ static JSValue js_Camera3D_get_projection(JSContext* ctx, JSValueConst this_val) static JSValue js_Camera3D_set_projection(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Camera3D* ptr = JS_GetOpaque2(ctx, this_val, js_Camera3D_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int value; JS_ToInt32(ctx, &value, v); ptr->projection = value; @@ -886,19 +731,136 @@ static int js_declare_Matrix(JSContext * ctx, JSModuleDef * m) { return 0; } +static void js_NPatchInfo_finalizer(JSRuntime * rt, JSValue val) { + NPatchInfo* ptr = JS_GetOpaque(val, js_NPatchInfo_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_NPatchInfo_get_source(JSContext* ctx, JSValueConst this_val) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + Rectangle source = ptr->source; + Rectangle* ret_ptr = (Rectangle*)js_malloc(ctx, sizeof(Rectangle)); + *ret_ptr = source; + JSValue ret = JS_NewObjectClass(ctx, js_Rectangle_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_NPatchInfo_set_source(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + Rectangle* value_ptr = (Rectangle*)JS_GetOpaque2(ctx, v, js_Rectangle_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Rectangle value = *value_ptr; + ptr->source = value; + return JS_UNDEFINED; +} + +static JSValue js_NPatchInfo_get_left(JSContext* ctx, JSValueConst this_val) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int left = ptr->left; + JSValue ret = JS_NewInt32(ctx, left); + return ret; +} + +static JSValue js_NPatchInfo_set_left(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->left = value; + return JS_UNDEFINED; +} + +static JSValue js_NPatchInfo_get_top(JSContext* ctx, JSValueConst this_val) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int top = ptr->top; + JSValue ret = JS_NewInt32(ctx, top); + return ret; +} + +static JSValue js_NPatchInfo_set_top(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->top = value; + return JS_UNDEFINED; +} + +static JSValue js_NPatchInfo_get_right(JSContext* ctx, JSValueConst this_val) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int right = ptr->right; + JSValue ret = JS_NewInt32(ctx, right); + return ret; +} + +static JSValue js_NPatchInfo_set_right(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->right = value; + return JS_UNDEFINED; +} + +static JSValue js_NPatchInfo_get_bottom(JSContext* ctx, JSValueConst this_val) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int bottom = ptr->bottom; + JSValue ret = JS_NewInt32(ctx, bottom); + return ret; +} + +static JSValue js_NPatchInfo_set_bottom(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->bottom = value; + return JS_UNDEFINED; +} + +static JSValue js_NPatchInfo_get_layout(JSContext* ctx, JSValueConst this_val) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int layout = ptr->layout; + JSValue ret = JS_NewInt32(ctx, layout); + return ret; +} + +static JSValue js_NPatchInfo_set_layout(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + NPatchInfo* ptr = JS_GetOpaque2(ctx, this_val, js_NPatchInfo_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->layout = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_NPatchInfo_proto_funcs[] = { + JS_CGETSET_DEF("source",js_NPatchInfo_get_source,js_NPatchInfo_set_source), + JS_CGETSET_DEF("left",js_NPatchInfo_get_left,js_NPatchInfo_set_left), + JS_CGETSET_DEF("top",js_NPatchInfo_get_top,js_NPatchInfo_set_top), + JS_CGETSET_DEF("right",js_NPatchInfo_get_right,js_NPatchInfo_set_right), + JS_CGETSET_DEF("bottom",js_NPatchInfo_get_bottom,js_NPatchInfo_set_bottom), + JS_CGETSET_DEF("layout",js_NPatchInfo_get_layout,js_NPatchInfo_set_layout), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","NPatchInfo", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_NPatchInfo(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_NPatchInfo_class_id); + JSClassDef js_NPatchInfo_def = { .class_name = "NPatchInfo", .finalizer = js_NPatchInfo_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_NPatchInfo_class_id, &js_NPatchInfo_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_NPatchInfo_proto_funcs, countof(js_NPatchInfo_proto_funcs)); + JS_SetClassProto(ctx, js_NPatchInfo_class_id, proto); + return 0; +} + static void js_Image_finalizer(JSRuntime * rt, JSValue val) { Image* ptr = JS_GetOpaque(val, js_Image_class_id); if(ptr) { - UnloadImage(*ptr); js_free_rt(rt, ptr); } } static JSValue js_Image_get_width(JSContext* ctx, JSValueConst this_val) { Image* ptr = JS_GetOpaque2(ctx, this_val, js_Image_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int width = ptr->width; JSValue ret = JS_NewInt32(ctx, width); return ret; @@ -906,9 +868,6 @@ static JSValue js_Image_get_width(JSContext* ctx, JSValueConst this_val) { static JSValue js_Image_get_height(JSContext* ctx, JSValueConst this_val) { Image* ptr = JS_GetOpaque2(ctx, this_val, js_Image_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int height = ptr->height; JSValue ret = JS_NewInt32(ctx, height); return ret; @@ -916,9 +875,6 @@ static JSValue js_Image_get_height(JSContext* ctx, JSValueConst this_val) { static JSValue js_Image_get_mipmaps(JSContext* ctx, JSValueConst this_val) { Image* ptr = JS_GetOpaque2(ctx, this_val, js_Image_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int mipmaps = ptr->mipmaps; JSValue ret = JS_NewInt32(ctx, mipmaps); return ret; @@ -926,9 +882,6 @@ static JSValue js_Image_get_mipmaps(JSContext* ctx, JSValueConst this_val) { static JSValue js_Image_get_format(JSContext* ctx, JSValueConst this_val) { Image* ptr = JS_GetOpaque2(ctx, this_val, js_Image_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int format = ptr->format; JSValue ret = JS_NewInt32(ctx, format); return ret; @@ -955,16 +908,12 @@ static int js_declare_Image(JSContext * ctx, JSModuleDef * m) { static void js_Wave_finalizer(JSRuntime * rt, JSValue val) { Wave* ptr = JS_GetOpaque(val, js_Wave_class_id); if(ptr) { - UnloadWave(*ptr); js_free_rt(rt, ptr); } } static JSValue js_Wave_get_frameCount(JSContext* ctx, JSValueConst this_val) { Wave* ptr = JS_GetOpaque2(ctx, this_val, js_Wave_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int frameCount = ptr->frameCount; JSValue ret = JS_NewUint32(ctx, frameCount); return ret; @@ -972,9 +921,6 @@ static JSValue js_Wave_get_frameCount(JSContext* ctx, JSValueConst this_val) { static JSValue js_Wave_get_sampleRate(JSContext* ctx, JSValueConst this_val) { Wave* ptr = JS_GetOpaque2(ctx, this_val, js_Wave_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int sampleRate = ptr->sampleRate; JSValue ret = JS_NewUint32(ctx, sampleRate); return ret; @@ -982,9 +928,6 @@ static JSValue js_Wave_get_sampleRate(JSContext* ctx, JSValueConst this_val) { static JSValue js_Wave_get_sampleSize(JSContext* ctx, JSValueConst this_val) { Wave* ptr = JS_GetOpaque2(ctx, this_val, js_Wave_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int sampleSize = ptr->sampleSize; JSValue ret = JS_NewUint32(ctx, sampleSize); return ret; @@ -992,9 +935,6 @@ static JSValue js_Wave_get_sampleSize(JSContext* ctx, JSValueConst this_val) { static JSValue js_Wave_get_channels(JSContext* ctx, JSValueConst this_val) { Wave* ptr = JS_GetOpaque2(ctx, this_val, js_Wave_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int channels = ptr->channels; JSValue ret = JS_NewUint32(ctx, channels); return ret; @@ -1021,16 +961,12 @@ static int js_declare_Wave(JSContext * ctx, JSModuleDef * m) { static void js_Sound_finalizer(JSRuntime * rt, JSValue val) { Sound* ptr = JS_GetOpaque(val, js_Sound_class_id); if(ptr) { - UnloadSound(*ptr); js_free_rt(rt, ptr); } } static JSValue js_Sound_get_frameCount(JSContext* ctx, JSValueConst this_val) { Sound* ptr = JS_GetOpaque2(ctx, this_val, js_Sound_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int frameCount = ptr->frameCount; JSValue ret = JS_NewUint32(ctx, frameCount); return ret; @@ -1054,16 +990,12 @@ static int js_declare_Sound(JSContext * ctx, JSModuleDef * m) { static void js_Music_finalizer(JSRuntime * rt, JSValue val) { Music* ptr = JS_GetOpaque(val, js_Music_class_id); if(ptr) { - UnloadMusicStream(*ptr); js_free_rt(rt, ptr); } } static JSValue js_Music_get_frameCount(JSContext* ctx, JSValueConst this_val) { Music* ptr = JS_GetOpaque2(ctx, this_val, js_Music_class_id); - if(!ptr) { - return JS_EXCEPTION; - } unsigned int frameCount = ptr->frameCount; JSValue ret = JS_NewUint32(ctx, frameCount); return ret; @@ -1071,9 +1003,6 @@ static JSValue js_Music_get_frameCount(JSContext* ctx, JSValueConst this_val) { static JSValue js_Music_get_looping(JSContext* ctx, JSValueConst this_val) { Music* ptr = JS_GetOpaque2(ctx, this_val, js_Music_class_id); - if(!ptr) { - return JS_EXCEPTION; - } bool looping = ptr->looping; JSValue ret = JS_NewBool(ctx, looping); return ret; @@ -1081,9 +1010,6 @@ static JSValue js_Music_get_looping(JSContext* ctx, JSValueConst this_val) { static JSValue js_Music_set_looping(JSContext* ctx, JSValueConst this_val, JSValueConst v) { Music* ptr = JS_GetOpaque2(ctx, this_val, js_Music_class_id); - if(!ptr) { - return JS_EXCEPTION; - } bool value = JS_ToBool(ctx, v); ptr->looping = value; return JS_UNDEFINED; @@ -1108,7 +1034,6 @@ static int js_declare_Music(JSContext * ctx, JSModuleDef * m) { static void js_Model_finalizer(JSRuntime * rt, JSValue val) { Model* ptr = JS_GetOpaque(val, js_Model_class_id); if(ptr) { - UnloadModel(*ptr); js_free_rt(rt, ptr); } } @@ -1130,12 +1055,197 @@ static int js_declare_Model(JSContext * ctx, JSModuleDef * m) { static void js_Mesh_finalizer(JSRuntime * rt, JSValue val) { Mesh* ptr = JS_GetOpaque(val, js_Mesh_class_id); if(ptr) { - UnloadMesh(*ptr); js_free_rt(rt, ptr); } } +static JSValue js_Mesh_get_vertexCount(JSContext* ctx, JSValueConst this_val) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + int vertexCount = ptr->vertexCount; + JSValue ret = JS_NewInt32(ctx, vertexCount); + return ret; +} + +static JSValue js_Mesh_set_vertexCount(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->vertexCount = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_get_triangleCount(JSContext* ctx, JSValueConst this_val) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + int triangleCount = ptr->triangleCount; + JSValue ret = JS_NewInt32(ctx, triangleCount); + return ret; +} + +static JSValue js_Mesh_set_triangleCount(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + int value; + JS_ToInt32(ctx, &value, v); + ptr->triangleCount = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_vertices(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->vertices = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_texcoords(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->texcoords = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_texcoords2(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->texcoords2 = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_normals(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->normals = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_tangents(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->tangents = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_colors(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + unsigned char * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->colors = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_indices(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + unsigned short * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->indices = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_animVertices(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->animVertices = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_animNormals(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->animNormals = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_boneIds(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + unsigned char * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->boneIds = value; + return JS_UNDEFINED; +} + +static JSValue js_Mesh_set_boneWeights(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Mesh* ptr = JS_GetOpaque2(ctx, this_val, js_Mesh_class_id); + size_t value_size; + void * value_js = (void *)JS_GetArrayBuffer(ctx, &value_size, v); + if(value_js == NULL) { + return JS_EXCEPTION; + } + float * value = malloc(value_size); + memcpy((void *)value, (const void *)value_js, value_size); + ptr->boneWeights = value; + return JS_UNDEFINED; +} + static const JSCFunctionListEntry js_Mesh_proto_funcs[] = { + JS_CGETSET_DEF("vertexCount",js_Mesh_get_vertexCount,js_Mesh_set_vertexCount), + JS_CGETSET_DEF("triangleCount",js_Mesh_get_triangleCount,js_Mesh_set_triangleCount), + JS_CGETSET_DEF("vertices",NULL,js_Mesh_set_vertices), + JS_CGETSET_DEF("texcoords",NULL,js_Mesh_set_texcoords), + JS_CGETSET_DEF("texcoords2",NULL,js_Mesh_set_texcoords2), + JS_CGETSET_DEF("normals",NULL,js_Mesh_set_normals), + JS_CGETSET_DEF("tangents",NULL,js_Mesh_set_tangents), + JS_CGETSET_DEF("colors",NULL,js_Mesh_set_colors), + JS_CGETSET_DEF("indices",NULL,js_Mesh_set_indices), + JS_CGETSET_DEF("animVertices",NULL,js_Mesh_set_animVertices), + JS_CGETSET_DEF("animNormals",NULL,js_Mesh_set_animNormals), + JS_CGETSET_DEF("boneIds",NULL,js_Mesh_set_boneIds), + JS_CGETSET_DEF("boneWeights",NULL,js_Mesh_set_boneWeights), JS_PROP_STRING_DEF("[Symbol.toStringTag]","Mesh", JS_PROP_CONFIGURABLE), }; @@ -1152,7 +1262,6 @@ static int js_declare_Mesh(JSContext * ctx, JSModuleDef * m) { static void js_Shader_finalizer(JSRuntime * rt, JSValue val) { Shader* ptr = JS_GetOpaque(val, js_Shader_class_id); if(ptr) { - UnloadShader(*ptr); js_free_rt(rt, ptr); } } @@ -1174,16 +1283,12 @@ static int js_declare_Shader(JSContext * ctx, JSModuleDef * m) { static void js_Texture_finalizer(JSRuntime * rt, JSValue val) { Texture* ptr = JS_GetOpaque(val, js_Texture_class_id); if(ptr) { - UnloadTexture(*ptr); js_free_rt(rt, ptr); } } static JSValue js_Texture_get_width(JSContext* ctx, JSValueConst this_val) { Texture* ptr = JS_GetOpaque2(ctx, this_val, js_Texture_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int width = ptr->width; JSValue ret = JS_NewInt32(ctx, width); return ret; @@ -1191,9 +1296,6 @@ static JSValue js_Texture_get_width(JSContext* ctx, JSValueConst this_val) { static JSValue js_Texture_get_height(JSContext* ctx, JSValueConst this_val) { Texture* ptr = JS_GetOpaque2(ctx, this_val, js_Texture_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int height = ptr->height; JSValue ret = JS_NewInt32(ctx, height); return ret; @@ -1218,16 +1320,12 @@ static int js_declare_Texture(JSContext * ctx, JSModuleDef * m) { static void js_Font_finalizer(JSRuntime * rt, JSValue val) { Font* ptr = JS_GetOpaque(val, js_Font_class_id); if(ptr) { - UnloadFont(*ptr); js_free_rt(rt, ptr); } } static JSValue js_Font_get_baseSize(JSContext* ctx, JSValueConst this_val) { Font* ptr = JS_GetOpaque2(ctx, this_val, js_Font_class_id); - if(!ptr) { - return JS_EXCEPTION; - } int baseSize = ptr->baseSize; JSValue ret = JS_NewInt32(ctx, baseSize); return ret; @@ -1248,6 +1346,126 @@ static int js_declare_Font(JSContext * ctx, JSModuleDef * m) { return 0; } +static void js_RenderTexture_finalizer(JSRuntime * rt, JSValue val) { + RenderTexture* ptr = JS_GetOpaque(val, js_RenderTexture_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static const JSCFunctionListEntry js_RenderTexture_proto_funcs[] = { + JS_PROP_STRING_DEF("[Symbol.toStringTag]","RenderTexture", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_RenderTexture(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_RenderTexture_class_id); + JSClassDef js_RenderTexture_def = { .class_name = "RenderTexture", .finalizer = js_RenderTexture_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_RenderTexture_class_id, &js_RenderTexture_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_RenderTexture_proto_funcs, countof(js_RenderTexture_proto_funcs)); + JS_SetClassProto(ctx, js_RenderTexture_class_id, proto); + return 0; +} + +static void js_MaterialMap_finalizer(JSRuntime * rt, JSValue val) { + MaterialMap* ptr = JS_GetOpaque(val, js_MaterialMap_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_MaterialMap_set_texture(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + MaterialMap* ptr = JS_GetOpaque2(ctx, this_val, js_MaterialMap_class_id); + Texture2D* value_ptr = (Texture2D*)JS_GetOpaque2(ctx, v, js_Texture_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Texture2D value = *value_ptr; + ptr->texture = value; + return JS_UNDEFINED; +} + +static JSValue js_MaterialMap_get_color(JSContext* ctx, JSValueConst this_val) { + MaterialMap* ptr = JS_GetOpaque2(ctx, this_val, js_MaterialMap_class_id); + Color color = ptr->color; + Color* ret_ptr = (Color*)js_malloc(ctx, sizeof(Color)); + *ret_ptr = color; + JSValue ret = JS_NewObjectClass(ctx, js_Color_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_MaterialMap_set_color(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + MaterialMap* ptr = JS_GetOpaque2(ctx, this_val, js_MaterialMap_class_id); + Color* value_ptr = (Color*)JS_GetOpaque2(ctx, v, js_Color_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Color value = *value_ptr; + ptr->color = value; + return JS_UNDEFINED; +} + +static JSValue js_MaterialMap_get_value(JSContext* ctx, JSValueConst this_val) { + MaterialMap* ptr = JS_GetOpaque2(ctx, this_val, js_MaterialMap_class_id); + float value = ptr->value; + JSValue ret = JS_NewFloat64(ctx, value); + return ret; +} + +static JSValue js_MaterialMap_set_value(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + MaterialMap* ptr = JS_GetOpaque2(ctx, this_val, js_MaterialMap_class_id); + double _double_value; + JS_ToFloat64(ctx, &_double_value, v); + float value = (float)_double_value; + ptr->value = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_MaterialMap_proto_funcs[] = { + JS_CGETSET_DEF("texture",NULL,js_MaterialMap_set_texture), + JS_CGETSET_DEF("color",js_MaterialMap_get_color,js_MaterialMap_set_color), + JS_CGETSET_DEF("value",js_MaterialMap_get_value,js_MaterialMap_set_value), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","MaterialMap", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_MaterialMap(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_MaterialMap_class_id); + JSClassDef js_MaterialMap_def = { .class_name = "MaterialMap", .finalizer = js_MaterialMap_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_MaterialMap_class_id, &js_MaterialMap_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_MaterialMap_proto_funcs, countof(js_MaterialMap_proto_funcs)); + JS_SetClassProto(ctx, js_MaterialMap_class_id, proto); + return 0; +} + +static void js_Material_finalizer(JSRuntime * rt, JSValue val) { + Material* ptr = JS_GetOpaque(val, js_Material_class_id); + if(ptr) { + js_free_rt(rt, ptr); + } +} + +static JSValue js_Material_set_shader(JSContext* ctx, JSValueConst this_val, JSValueConst v) { + Material* ptr = JS_GetOpaque2(ctx, this_val, js_Material_class_id); + Shader* value_ptr = (Shader*)JS_GetOpaque2(ctx, v, js_Shader_class_id); + if(value_ptr == NULL) return JS_EXCEPTION; + Shader value = *value_ptr; + ptr->shader = value; + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_Material_proto_funcs[] = { + JS_CGETSET_DEF("shader",NULL,js_Material_set_shader), + JS_PROP_STRING_DEF("[Symbol.toStringTag]","Material", JS_PROP_CONFIGURABLE), +}; + +static int js_declare_Material(JSContext * ctx, JSModuleDef * m) { + JS_NewClassID(&js_Material_class_id); + JSClassDef js_Material_def = { .class_name = "Material", .finalizer = js_Material_finalizer }; + JS_NewClass(JS_GetRuntime(ctx), js_Material_class_id, &js_Material_def); + JSValue proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_Material_proto_funcs, countof(js_Material_proto_funcs)); + JS_SetClassProto(ctx, js_Material_class_id, proto); + return 0; +} + static JSValue js_Color_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { unsigned int _int_r; JS_ToUint32(ctx, &_int_r, argv[0]); @@ -1418,6 +1636,37 @@ static JSValue js_BoundingBox_constructor(JSContext * ctx, JSValueConst this_val return _return; } +static JSValue js_NPatchInfo_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Rectangle* source_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[0], js_Rectangle_class_id); + if(source_ptr == NULL) return JS_EXCEPTION; + Rectangle source = *source_ptr; + int left; + JS_ToInt32(ctx, &left, argv[1]); + int top; + JS_ToInt32(ctx, &top, argv[2]); + int right; + JS_ToInt32(ctx, &right, argv[3]); + int bottom; + JS_ToInt32(ctx, &bottom, argv[4]); + int layout; + JS_ToInt32(ctx, &layout, argv[5]); + NPatchInfo _struct = { source, left, top, right, bottom, layout }; + NPatchInfo* _return_ptr = (NPatchInfo*)js_malloc(ctx, sizeof(NPatchInfo)); + *_return_ptr = _struct; + JSValue _return = JS_NewObjectClass(ctx, js_NPatchInfo_class_id); + JS_SetOpaque(_return, _return_ptr); + return _return; +} + +static JSValue js_Mesh_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Mesh _struct = { }; + Mesh* _return_ptr = (Mesh*)js_malloc(ctx, sizeof(Mesh)); + *_return_ptr = _struct; + JSValue _return = JS_NewObjectClass(ctx, js_Mesh_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, &width, argv[0]); @@ -1794,6 +2043,19 @@ static JSValue js_endMode3D(JSContext * ctx, JSValueConst this_val, int argc, JS return JS_UNDEFINED; } +static JSValue js_beginTextureMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + RenderTexture2D* target_ptr = (RenderTexture2D*)JS_GetOpaque2(ctx, argv[0], js_RenderTexture_class_id); + if(target_ptr == NULL) return JS_EXCEPTION; + RenderTexture2D target = *target_ptr; + BeginTextureMode(target); + return JS_UNDEFINED; +} + +static JSValue js_endTextureMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + EndTextureMode(); + return JS_UNDEFINED; +} + static JSValue js_beginShaderMode(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Shader* shader_ptr = (Shader*)JS_GetOpaque2(ctx, argv[0], js_Shader_class_id); if(shader_ptr == NULL) return JS_EXCEPTION; @@ -1964,6 +2226,14 @@ static JSValue js_setShaderValueTexture(JSContext * ctx, JSValueConst this_val, return JS_UNDEFINED; } +static JSValue js_unloadShader(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Shader* shader_ptr = (Shader*)JS_GetOpaque2(ctx, argv[0], js_Shader_class_id); + if(shader_ptr == NULL) return JS_EXCEPTION; + Shader shader = *shader_ptr; + UnloadShader(shader); + return JS_UNDEFINED; +} + static JSValue js_getMouseRay(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Vector2* mousePosition_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[0], js_Vector2_class_id); if(mousePosition_ptr == NULL) return JS_EXCEPTION; @@ -2160,6 +2430,7 @@ static JSValue js_saveFileText(JSContext * ctx, JSValueConst this_val, int argc, char * text = (char *)JS_ToCString(ctx, argv[1]); bool returnVal = SaveFileText(fileName, text); JS_FreeCString(ctx, fileName); + JS_FreeCString(ctx, text); JSValue ret = JS_NewBool(ctx, returnVal); return ret; } @@ -3430,6 +3701,14 @@ static JSValue js_isImageReady(JSContext * ctx, JSValueConst this_val, int argc, return ret; } +static JSValue js_unloadImage(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Image* image_ptr = (Image*)JS_GetOpaque2(ctx, argv[0], js_Image_class_id); + if(image_ptr == NULL) return JS_EXCEPTION; + Image image = *image_ptr; + UnloadImage(image); + return JS_UNDEFINED; +} + static JSValue js_exportImage(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Image* image_ptr = (Image*)JS_GetOpaque2(ctx, argv[0], js_Image_class_id); if(image_ptr == NULL) return JS_EXCEPTION; @@ -3896,6 +4175,16 @@ static JSValue js_imageColorReplace(JSContext * ctx, JSValueConst this_val, int return JS_UNDEFINED; } +static JSValue js_loadImageColors(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Image* image_ptr = (Image*)JS_GetOpaque2(ctx, argv[0], js_Image_class_id); + if(image_ptr == NULL) return JS_EXCEPTION; + Image image = *image_ptr; + Color * colors = LoadImageColors(image); + JSValue retVal = JS_NewArrayBufferCopy(ctx, (const uint8_t*)colors, image.width*image.height*sizeof(Color)); + UnloadImageColors(colors); + return retVal; +} + static JSValue js_getImageAlphaBorder(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Image* image_ptr = (Image*)JS_GetOpaque2(ctx, argv[0], js_Image_class_id); if(image_ptr == NULL) return JS_EXCEPTION; @@ -4220,6 +4509,19 @@ static JSValue js_loadTextureCubemap(JSContext * ctx, JSValueConst this_val, int return ret; } +static JSValue js_loadRenderTexture(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]); + RenderTexture2D returnVal = LoadRenderTexture(width, height); + RenderTexture2D* ret_ptr = (RenderTexture2D*)js_malloc(ctx, sizeof(RenderTexture2D)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_RenderTexture_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + static JSValue js_isTextureReady(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Texture2D* texture_ptr = (Texture2D*)JS_GetOpaque2(ctx, argv[0], js_Texture_class_id); if(texture_ptr == NULL) return JS_EXCEPTION; @@ -4229,6 +4531,31 @@ static JSValue js_isTextureReady(JSContext * ctx, JSValueConst this_val, int arg return ret; } +static JSValue js_unloadTexture(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Texture2D* texture_ptr = (Texture2D*)JS_GetOpaque2(ctx, argv[0], js_Texture_class_id); + if(texture_ptr == NULL) return JS_EXCEPTION; + Texture2D texture = *texture_ptr; + UnloadTexture(texture); + return JS_UNDEFINED; +} + +static JSValue js_isRenderTextureReady(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + RenderTexture2D* target_ptr = (RenderTexture2D*)JS_GetOpaque2(ctx, argv[0], js_RenderTexture_class_id); + if(target_ptr == NULL) return JS_EXCEPTION; + RenderTexture2D target = *target_ptr; + bool returnVal = IsRenderTextureReady(target); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_unloadRenderTexture(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + RenderTexture2D* target_ptr = (RenderTexture2D*)JS_GetOpaque2(ctx, argv[0], js_RenderTexture_class_id); + if(target_ptr == NULL) return JS_EXCEPTION; + RenderTexture2D target = *target_ptr; + UnloadRenderTexture(target); + return JS_UNDEFINED; +} + static JSValue js_genTextureMipmaps(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Texture2D* texture = (Texture2D*)JS_GetOpaque2(ctx, argv[0], js_Texture_class_id); if(texture == NULL) return JS_EXCEPTION; @@ -4345,6 +4672,29 @@ static JSValue js_drawTexturePro(JSContext * ctx, JSValueConst this_val, int arg return JS_UNDEFINED; } +static JSValue js_drawTextureNPatch(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Texture2D* texture_ptr = (Texture2D*)JS_GetOpaque2(ctx, argv[0], js_Texture_class_id); + if(texture_ptr == NULL) return JS_EXCEPTION; + Texture2D texture = *texture_ptr; + NPatchInfo* nPatchInfo_ptr = (NPatchInfo*)JS_GetOpaque2(ctx, argv[1], js_NPatchInfo_class_id); + if(nPatchInfo_ptr == NULL) return JS_EXCEPTION; + NPatchInfo nPatchInfo = *nPatchInfo_ptr; + Rectangle* dest_ptr = (Rectangle*)JS_GetOpaque2(ctx, argv[2], js_Rectangle_class_id); + if(dest_ptr == NULL) return JS_EXCEPTION; + Rectangle dest = *dest_ptr; + Vector2* origin_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[3], js_Vector2_class_id); + if(origin_ptr == NULL) return JS_EXCEPTION; + Vector2 origin = *origin_ptr; + double _double_rotation; + JS_ToFloat64(ctx, &_double_rotation, argv[4]); + float rotation = (float)_double_rotation; + Color* tint_ptr = (Color*)JS_GetOpaque2(ctx, argv[5], js_Color_class_id); + if(tint_ptr == NULL) return JS_EXCEPTION; + Color tint = *tint_ptr; + DrawTextureNPatch(texture, nPatchInfo, dest, origin, rotation, tint); + 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; @@ -4570,6 +4920,14 @@ static JSValue js_isFontReady(JSContext * ctx, JSValueConst this_val, int argc, return ret; } +static JSValue js_unloadFont(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Font* font_ptr = (Font*)JS_GetOpaque2(ctx, argv[0], js_Font_class_id); + if(font_ptr == NULL) return JS_EXCEPTION; + Font font = *font_ptr; + UnloadFont(font); + return JS_UNDEFINED; +} + static JSValue js_drawFPS(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { int posX; JS_ToInt32(ctx, &posX, argv[0]); @@ -5096,6 +5454,14 @@ static JSValue js_isModelReady(JSContext * ctx, JSValueConst this_val, int argc, return ret; } +static JSValue js_unloadModel(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Model* model_ptr = (Model*)JS_GetOpaque2(ctx, argv[0], js_Model_class_id); + if(model_ptr == NULL) return JS_EXCEPTION; + Model model = *model_ptr; + UnloadModel(model); + return JS_UNDEFINED; +} + static JSValue js_getModelBoundingBox(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Model* model_ptr = (Model*)JS_GetOpaque2(ctx, argv[0], js_Model_class_id); if(model_ptr == NULL) return JS_EXCEPTION; @@ -5282,6 +5648,65 @@ static JSValue js_uploadMesh(JSContext * ctx, JSValueConst this_val, int argc, J return JS_UNDEFINED; } +static JSValue js_updateMeshBuffer(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Mesh* mesh_ptr = (Mesh*)JS_GetOpaque2(ctx, argv[0], js_Mesh_class_id); + if(mesh_ptr == NULL) return JS_EXCEPTION; + Mesh mesh = *mesh_ptr; + int index; + JS_ToInt32(ctx, &index, argv[1]); + size_t data_size; + void * data_js = (void *)JS_GetArrayBuffer(ctx, &data_size, argv[2]); + if(data_js == NULL) { + return JS_EXCEPTION; + } + const void * data = malloc(data_size); + memcpy((void *)data, (const void *)data_js, data_size); + int dataSize; + JS_ToInt32(ctx, &dataSize, argv[3]); + int offset; + JS_ToInt32(ctx, &offset, argv[4]); + UpdateMeshBuffer(mesh, index, data, dataSize, offset); + free((void *)data); + return JS_UNDEFINED; +} + +static JSValue js_unloadMesh(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Mesh* mesh_ptr = (Mesh*)JS_GetOpaque2(ctx, argv[0], js_Mesh_class_id); + if(mesh_ptr == NULL) return JS_EXCEPTION; + Mesh mesh = *mesh_ptr; + UnloadMesh(mesh); + return JS_UNDEFINED; +} + +static JSValue js_drawMesh(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Mesh* mesh_ptr = (Mesh*)JS_GetOpaque2(ctx, argv[0], js_Mesh_class_id); + if(mesh_ptr == NULL) return JS_EXCEPTION; + Mesh mesh = *mesh_ptr; + Material* material_ptr = (Material*)JS_GetOpaque2(ctx, argv[1], js_Material_class_id); + if(material_ptr == NULL) return JS_EXCEPTION; + Material material = *material_ptr; + Matrix* transform_ptr = (Matrix*)JS_GetOpaque2(ctx, argv[2], js_Matrix_class_id); + if(transform_ptr == NULL) return JS_EXCEPTION; + Matrix transform = *transform_ptr; + DrawMesh(mesh, material, transform); + return JS_UNDEFINED; +} + +static JSValue js_drawMeshInstanced(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Mesh* mesh_ptr = (Mesh*)JS_GetOpaque2(ctx, argv[0], js_Mesh_class_id); + if(mesh_ptr == NULL) return JS_EXCEPTION; + Mesh mesh = *mesh_ptr; + Material* material_ptr = (Material*)JS_GetOpaque2(ctx, argv[1], js_Material_class_id); + if(material_ptr == NULL) return JS_EXCEPTION; + Material material = *material_ptr; + const Matrix* transforms = (const Matrix*)JS_GetOpaque2(ctx, argv[2], js_Matrix_class_id); + if(transforms == NULL) return JS_EXCEPTION; + int instances; + JS_ToInt32(ctx, &instances, argv[3]); + DrawMeshInstanced(mesh, material, transforms, instances); + return JS_UNDEFINED; +} + static JSValue js_exportMesh(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Mesh* mesh_ptr = (Mesh*)JS_GetOpaque2(ctx, argv[0], js_Mesh_class_id); if(mesh_ptr == NULL) return JS_EXCEPTION; @@ -5497,6 +5922,67 @@ static JSValue js_genMeshCubicmap(JSContext * ctx, JSValueConst this_val, int ar return ret; } +static JSValue js_loadMaterialDefault(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Material returnVal = LoadMaterialDefault(); + Material* ret_ptr = (Material*)js_malloc(ctx, sizeof(Material)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Material_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_isMaterialReady(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Material* material_ptr = (Material*)JS_GetOpaque2(ctx, argv[0], js_Material_class_id); + if(material_ptr == NULL) return JS_EXCEPTION; + Material material = *material_ptr; + bool returnVal = IsMaterialReady(material); + JSValue ret = JS_NewBool(ctx, returnVal); + return ret; +} + +static JSValue js_unloadMaterial(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Material* material_ptr = (Material*)JS_GetOpaque2(ctx, argv[0], js_Material_class_id); + if(material_ptr == NULL) return JS_EXCEPTION; + Material material = *material_ptr; + UnloadMaterial(material); + return JS_UNDEFINED; +} + +static JSValue js_setMaterialTexture(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Material* material = (Material*)JS_GetOpaque2(ctx, argv[0], js_Material_class_id); + if(material == NULL) return JS_EXCEPTION; + int mapType; + JS_ToInt32(ctx, &mapType, argv[1]); + Texture2D* texture_ptr = (Texture2D*)JS_GetOpaque2(ctx, argv[2], js_Texture_class_id); + if(texture_ptr == NULL) return JS_EXCEPTION; + Texture2D texture = *texture_ptr; + SetMaterialTexture(material, mapType, texture); + return JS_UNDEFINED; +} + +static JSValue js_setModelMaterial(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Model* model = (Model*)JS_GetOpaque2(ctx, argv[0], js_Model_class_id); + if(model == NULL) return JS_EXCEPTION; + int materialIndex; + JS_ToInt32(ctx, &materialIndex, argv[1]); + Material* material_ptr = (Material*)JS_GetOpaque2(ctx, argv[2], js_Material_class_id); + if(material_ptr == NULL) return JS_EXCEPTION; + Material material = *material_ptr; + SetModelMaterial(model, materialIndex, material); + return JS_UNDEFINED; +} + +static JSValue js_setModelMeshMaterial(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Model* model = (Model*)JS_GetOpaque2(ctx, argv[0], js_Model_class_id); + if(model == NULL) return JS_EXCEPTION; + int meshId; + JS_ToInt32(ctx, &meshId, argv[1]); + int materialId; + JS_ToInt32(ctx, &materialId, argv[2]); + SetModelMeshMaterial(model, meshId, materialId); + return JS_UNDEFINED; +} + static JSValue js_checkCollisionSpheres(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Vector3* center1_ptr = (Vector3*)JS_GetOpaque2(ctx, argv[0], js_Vector3_class_id); if(center1_ptr == NULL) return JS_EXCEPTION; @@ -5714,6 +6200,22 @@ static JSValue js_isSoundReady(JSContext * ctx, JSValueConst this_val, int argc, return ret; } +static JSValue js_unloadWave(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Wave* wave_ptr = (Wave*)JS_GetOpaque2(ctx, argv[0], js_Wave_class_id); + if(wave_ptr == NULL) return JS_EXCEPTION; + Wave wave = *wave_ptr; + UnloadWave(wave); + return JS_UNDEFINED; +} + +static JSValue js_unloadSound(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Sound* sound_ptr = (Sound*)JS_GetOpaque2(ctx, argv[0], js_Sound_class_id); + if(sound_ptr == NULL) return JS_EXCEPTION; + Sound sound = *sound_ptr; + UnloadSound(sound); + return JS_UNDEFINED; +} + static JSValue js_exportWave(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Wave* wave_ptr = (Wave*)JS_GetOpaque2(ctx, argv[0], js_Wave_class_id); if(wave_ptr == NULL) return JS_EXCEPTION; @@ -5855,6 +6357,14 @@ static JSValue js_isMusicReady(JSContext * ctx, JSValueConst this_val, int argc, return ret; } +static JSValue js_unloadMusicStream(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Music* music_ptr = (Music*)JS_GetOpaque2(ctx, argv[0], js_Music_class_id); + if(music_ptr == NULL) return JS_EXCEPTION; + Music music = *music_ptr; + UnloadMusicStream(music); + return JS_UNDEFINED; +} + static JSValue js_playMusicStream(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { Music* music_ptr = (Music*)JS_GetOpaque2(ctx, argv[0], js_Music_class_id); if(music_ptr == NULL) return JS_EXCEPTION; @@ -7546,6 +8056,8 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("endMode2D",0,js_endMode2D), JS_CFUNC_DEF("beginMode3D",1,js_beginMode3D), JS_CFUNC_DEF("endMode3D",0,js_endMode3D), + JS_CFUNC_DEF("beginTextureMode",1,js_beginTextureMode), + JS_CFUNC_DEF("endTextureMode",0,js_endTextureMode), JS_CFUNC_DEF("beginShaderMode",1,js_beginShaderMode), JS_CFUNC_DEF("endShaderMode",0,js_endShaderMode), JS_CFUNC_DEF("beginBlendMode",1,js_beginBlendMode), @@ -7559,6 +8071,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("setShaderValue",4,js_setShaderValue), JS_CFUNC_DEF("setShaderValueMatrix",3,js_setShaderValueMatrix), JS_CFUNC_DEF("setShaderValueTexture",3,js_setShaderValueTexture), + JS_CFUNC_DEF("unloadShader",1,js_unloadShader), JS_CFUNC_DEF("getMouseRay",2,js_getMouseRay), JS_CFUNC_DEF("getCameraMatrix",1,js_getCameraMatrix), JS_CFUNC_DEF("getCameraMatrix2D",1,js_getCameraMatrix2D), @@ -7687,6 +8200,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("loadImageFromTexture",1,js_loadImageFromTexture), JS_CFUNC_DEF("loadImageFromScreen",0,js_loadImageFromScreen), JS_CFUNC_DEF("isImageReady",1,js_isImageReady), + JS_CFUNC_DEF("unloadImage",1,js_unloadImage), JS_CFUNC_DEF("exportImage",2,js_exportImage), JS_CFUNC_DEF("genImageColor",3,js_genImageColor), JS_CFUNC_DEF("genImageGradientV",4,js_genImageGradientV), @@ -7724,6 +8238,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("imageColorContrast",2,js_imageColorContrast), JS_CFUNC_DEF("imageColorBrightness",2,js_imageColorBrightness), JS_CFUNC_DEF("imageColorReplace",3,js_imageColorReplace), + JS_CFUNC_DEF("loadImageColors",1,js_loadImageColors), JS_CFUNC_DEF("getImageAlphaBorder",2,js_getImageAlphaBorder), JS_CFUNC_DEF("getImageColor",3,js_getImageColor), JS_CFUNC_DEF("imageClearBackground",2,js_imageClearBackground), @@ -7745,7 +8260,11 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("loadTexture",1,js_loadTexture), JS_CFUNC_DEF("loadTextureFromImage",1,js_loadTextureFromImage), JS_CFUNC_DEF("loadTextureCubemap",2,js_loadTextureCubemap), + JS_CFUNC_DEF("loadRenderTexture",2,js_loadRenderTexture), JS_CFUNC_DEF("isTextureReady",1,js_isTextureReady), + JS_CFUNC_DEF("unloadTexture",1,js_unloadTexture), + JS_CFUNC_DEF("isRenderTextureReady",1,js_isRenderTextureReady), + JS_CFUNC_DEF("unloadRenderTexture",1,js_unloadRenderTexture), JS_CFUNC_DEF("genTextureMipmaps",1,js_genTextureMipmaps), JS_CFUNC_DEF("setTextureFilter",2,js_setTextureFilter), JS_CFUNC_DEF("setTextureWrap",2,js_setTextureWrap), @@ -7754,6 +8273,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("drawTextureEx",5,js_drawTextureEx), JS_CFUNC_DEF("drawTextureRec",4,js_drawTextureRec), JS_CFUNC_DEF("drawTexturePro",6,js_drawTexturePro), + JS_CFUNC_DEF("drawTextureNPatch",6,js_drawTextureNPatch), JS_CFUNC_DEF("fade",2,js_fade), JS_CFUNC_DEF("colorToInt",1,js_colorToInt), JS_CFUNC_DEF("colorNormalize",1,js_colorNormalize), @@ -7771,6 +8291,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("loadFont",1,js_loadFont), JS_CFUNC_DEF("loadFontFromImage",3,js_loadFontFromImage), JS_CFUNC_DEF("isFontReady",1,js_isFontReady), + JS_CFUNC_DEF("unloadFont",1,js_unloadFont), JS_CFUNC_DEF("drawFPS",2,js_drawFPS), JS_CFUNC_DEF("drawText",5,js_drawText), JS_CFUNC_DEF("drawTextEx",6,js_drawTextEx), @@ -7803,6 +8324,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("loadModel",1,js_loadModel), JS_CFUNC_DEF("loadModelFromMesh",1,js_loadModelFromMesh), JS_CFUNC_DEF("isModelReady",1,js_isModelReady), + JS_CFUNC_DEF("unloadModel",1,js_unloadModel), JS_CFUNC_DEF("getModelBoundingBox",1,js_getModelBoundingBox), JS_CFUNC_DEF("drawModel",4,js_drawModel), JS_CFUNC_DEF("drawModelEx",6,js_drawModelEx), @@ -7813,6 +8335,10 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("drawBillboardRec",6,js_drawBillboardRec), JS_CFUNC_DEF("drawBillboardPro",9,js_drawBillboardPro), JS_CFUNC_DEF("uploadMesh",2,js_uploadMesh), + JS_CFUNC_DEF("updateMeshBuffer",5,js_updateMeshBuffer), + JS_CFUNC_DEF("unloadMesh",1,js_unloadMesh), + JS_CFUNC_DEF("drawMesh",3,js_drawMesh), + JS_CFUNC_DEF("drawMeshInstanced",4,js_drawMeshInstanced), JS_CFUNC_DEF("exportMesh",2,js_exportMesh), JS_CFUNC_DEF("getMeshBoundingBox",1,js_getMeshBoundingBox), JS_CFUNC_DEF("genMeshTangents",1,js_genMeshTangents), @@ -7827,6 +8353,12 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("genMeshKnot",4,js_genMeshKnot), JS_CFUNC_DEF("genMeshHeightmap",2,js_genMeshHeightmap), JS_CFUNC_DEF("genMeshCubicmap",2,js_genMeshCubicmap), + JS_CFUNC_DEF("loadMaterialDefault",0,js_loadMaterialDefault), + JS_CFUNC_DEF("isMaterialReady",1,js_isMaterialReady), + JS_CFUNC_DEF("unloadMaterial",1,js_unloadMaterial), + JS_CFUNC_DEF("setMaterialTexture",3,js_setMaterialTexture), + JS_CFUNC_DEF("setModelMaterial",3,js_setModelMaterial), + JS_CFUNC_DEF("setModelMeshMaterial",3,js_setModelMeshMaterial), JS_CFUNC_DEF("checkCollisionSpheres",4,js_checkCollisionSpheres), JS_CFUNC_DEF("checkCollisionBoxes",2,js_checkCollisionBoxes), JS_CFUNC_DEF("checkCollisionBoxSphere",3,js_checkCollisionBoxSphere), @@ -7844,6 +8376,8 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("loadSound",1,js_loadSound), JS_CFUNC_DEF("loadSoundFromWave",1,js_loadSoundFromWave), JS_CFUNC_DEF("isSoundReady",1,js_isSoundReady), + JS_CFUNC_DEF("unloadWave",1,js_unloadWave), + JS_CFUNC_DEF("unloadSound",1,js_unloadSound), JS_CFUNC_DEF("exportWave",2,js_exportWave), JS_CFUNC_DEF("playSound",1,js_playSound), JS_CFUNC_DEF("stopSound",1,js_stopSound), @@ -7858,6 +8392,7 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("waveFormat",4,js_waveFormat), JS_CFUNC_DEF("loadMusicStream",1,js_loadMusicStream), JS_CFUNC_DEF("isMusicReady",1,js_isMusicReady), + JS_CFUNC_DEF("unloadMusicStream",1,js_unloadMusicStream), JS_CFUNC_DEF("playMusicStream",1,js_playMusicStream), JS_CFUNC_DEF("isMusicStreamPlaying",1,js_isMusicStreamPlaying), JS_CFUNC_DEF("updateMusicStream",1,js_updateMusicStream), @@ -8011,15 +8546,23 @@ static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { JSValue BoundingBox_constr = JS_NewCFunction2(ctx, js_BoundingBox_constructor,"BoundingBox)", 2, JS_CFUNC_constructor_or_func, 0); JS_SetModuleExport(ctx, m, "BoundingBox", BoundingBox_constr); js_declare_Matrix(ctx, m); + js_declare_NPatchInfo(ctx, m); + JSValue NPatchInfo_constr = JS_NewCFunction2(ctx, js_NPatchInfo_constructor,"NPatchInfo)", 6, JS_CFUNC_constructor_or_func, 0); + JS_SetModuleExport(ctx, m, "NPatchInfo", NPatchInfo_constr); js_declare_Image(ctx, m); js_declare_Wave(ctx, m); js_declare_Sound(ctx, m); js_declare_Music(ctx, m); js_declare_Model(ctx, m); js_declare_Mesh(ctx, m); + JSValue Mesh_constr = JS_NewCFunction2(ctx, js_Mesh_constructor,"Mesh)", 15, JS_CFUNC_constructor_or_func, 0); + JS_SetModuleExport(ctx, m, "Mesh", Mesh_constr); js_declare_Shader(ctx, m); js_declare_Texture(ctx, m); js_declare_Font(ctx, m); + js_declare_RenderTexture(ctx, m); + js_declare_MaterialMap(ctx, m); + js_declare_Material(ctx, m); Color LIGHTGRAY_struct = { 200, 200, 200, 255 }; Color* LIGHTGRAY_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); *LIGHTGRAY_js_ptr = LIGHTGRAY_struct; @@ -8398,6 +8941,19 @@ static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { JS_SetModuleExport(ctx, m, "SHADER_UNIFORM_IVEC3", JS_NewInt32(ctx, SHADER_UNIFORM_IVEC3)); JS_SetModuleExport(ctx, m, "SHADER_UNIFORM_IVEC4", JS_NewInt32(ctx, SHADER_UNIFORM_IVEC4)); JS_SetModuleExport(ctx, m, "SHADER_UNIFORM_SAMPLER2D", JS_NewInt32(ctx, SHADER_UNIFORM_SAMPLER2D)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_ALBEDO", JS_NewInt32(ctx, MATERIAL_MAP_ALBEDO)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_METALNESS", JS_NewInt32(ctx, MATERIAL_MAP_METALNESS)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_NORMAL", JS_NewInt32(ctx, MATERIAL_MAP_NORMAL)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_ROUGHNESS", JS_NewInt32(ctx, MATERIAL_MAP_ROUGHNESS)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_OCCLUSION", JS_NewInt32(ctx, MATERIAL_MAP_OCCLUSION)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_EMISSION", JS_NewInt32(ctx, MATERIAL_MAP_EMISSION)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_HEIGHT", JS_NewInt32(ctx, MATERIAL_MAP_HEIGHT)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_CUBEMAP", JS_NewInt32(ctx, MATERIAL_MAP_CUBEMAP)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_IRRADIANCE", JS_NewInt32(ctx, MATERIAL_MAP_IRRADIANCE)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_PREFILTER", JS_NewInt32(ctx, MATERIAL_MAP_PREFILTER)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_BRDF", JS_NewInt32(ctx, MATERIAL_MAP_BRDF)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_DIFFUSE", JS_NewInt32(ctx, MATERIAL_MAP_DIFFUSE)); + JS_SetModuleExport(ctx, m, "MATERIAL_MAP_SPECULAR", JS_NewInt32(ctx, MATERIAL_MAP_SPECULAR)); return 0; } @@ -8415,6 +8971,8 @@ JSModuleDef * js_init_module_raylib_core(JSContext * ctx, const char * module_na JS_AddModuleExport(ctx, m, "Camera2D"); JS_AddModuleExport(ctx, m, "Camera3D"); JS_AddModuleExport(ctx, m, "BoundingBox"); + JS_AddModuleExport(ctx, m, "NPatchInfo"); + JS_AddModuleExport(ctx, m, "Mesh"); JS_AddModuleExport(ctx, m, "LIGHTGRAY"); JS_AddModuleExport(ctx, m, "GRAY"); JS_AddModuleExport(ctx, m, "DARKGRAY"); @@ -8663,6 +9221,19 @@ JSModuleDef * js_init_module_raylib_core(JSContext * ctx, const char * module_na JS_AddModuleExport(ctx, m, "SHADER_UNIFORM_IVEC3"); JS_AddModuleExport(ctx, m, "SHADER_UNIFORM_IVEC4"); JS_AddModuleExport(ctx, m, "SHADER_UNIFORM_SAMPLER2D"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_ALBEDO"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_METALNESS"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_NORMAL"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_ROUGHNESS"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_OCCLUSION"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_EMISSION"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_HEIGHT"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_CUBEMAP"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_IRRADIANCE"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_PREFILTER"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_BRDF"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_DIFFUSE"); + JS_AddModuleExport(ctx, m, "MATERIAL_MAP_SPECULAR"); return m; } diff --git a/src/quickjs.c b/src/quickjs.c index 9545dd4..73e7ed3 100644 --- a/src/quickjs.c +++ b/src/quickjs.c @@ -29,6 +29,13 @@ int app_update_quickjs(){ return 0; } +void SetModelMaterial(Model *model, int materialIndex, Material material) +{ + if(model->materialCount <= materialIndex) return; + UnloadMaterial(model->materials[materialIndex]); + model->materials[materialIndex] = material; +} + #include "bindings/js_raylib_core.h" int app_init_quickjs(int argc, char** argv){ diff --git a/thirdparty/raylib b/thirdparty/raylib index 5573f0f..a48bb6e 160000 --- a/thirdparty/raylib +++ b/thirdparty/raylib @@ -1 +1 @@ -Subproject commit 5573f0f1c7b29bfe46d0b70487e4adb4d01cba62 +Subproject commit a48bb6e1ed7b33190e486ba65b7875f0dff73701