more bindings, examples

This commit is contained in:
Alexander Klingenbeck 2023-05-14 22:19:47 +02:00
parent 619b854795
commit bdb5b740e6
25 changed files with 8990 additions and 705 deletions

BIN
assets/wabbit_alpha.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

File diff suppressed because it is too large Load Diff

View File

@ -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 }
get description() { return this.api.description }
}
export class ApiStruct{
@ -21,8 +22,12 @@ export class ApiStruct{
}
export class ApiDescription{
constructor(private api: RayLibApi){
constructor(private api: RayLibApi){
}
getAliases(name: string) {
return this.api.aliases.filter(x => x.type === name).map(x => x.name)
}
getFunction(name: string){

View File

@ -65,7 +65,8 @@ enum Token {
export interface FunctionArgument {
type: string,
name: string
name: string,
description?: string
}

View File

@ -1,14 +1,41 @@
import { readFileSync, writeFileSync } from "fs";
import { RayLibApi } from "./interfaces";
import { ApiDescription } from "./api";
import { RayLibApi, RayLibFunction, RayLibType } from "./interfaces";
import { ApiDescription, ApiFunction } from "./api";
import { RayLibHeader } from "./raylib-header";
function parseMathHeader(): RayLibFunction[] {
return readFileSync("thirdparty/raylib/src/raymath.h", 'utf8')
.split("\n")
.filter(x => x.startsWith("RMAPI"))
.map(inputString => {
const matches = inputString.match(/^RMAPI\s+([\w<>]+)\s+([\w<>]+)\((.*)\)$/);
if(!matches) throw new Error("Unable to match " + inputString)
const args = matches[3].split(',').filter(x => x !== 'void').map(arg => {
arg = arg.trim().replace(" *", "* ")
const frags = arg.split(' ')
const name = frags.pop()
const type = frags.join(' ').replace("*", " *")
console.log({ name: name || "", type: type })
return { name: name || "", type: type }
})
return {
name: matches[2],
returnType: matches[1],
params: args,
description: ""
}
});
}
function main(){
const mathApi = parseMathHeader();
writeFileSync("bindings/raylib_math_api.json", JSON.stringify(mathApi))
const api = <RayLibApi>JSON.parse(readFileSync("thirdparty/raylib/parser/output/raylib_api.json", 'utf8'))
const apiDesc = new ApiDescription(api)
const core_gen = new RayLibHeader("raylib_core", apiDesc)
core_gen.addApiStructByName("Color", {
const core = new RayLibHeader("raylib_core", apiDesc)
core.addApiStructByName("Color", {
properties: {
r: { get: true, set: true },
g: { get: true, set: true },
@ -17,7 +44,7 @@ function main(){
},
createConstructor: true
})
core_gen.addApiStructByName("Rectangle", {
core.addApiStructByName("Rectangle", {
properties: {
x: { get: true, set: true },
y: { get: true, set: true },
@ -26,14 +53,14 @@ function main(){
},
createConstructor: true
})
core_gen.addApiStructByName("Vector2", {
core.addApiStructByName("Vector2", {
properties: {
x: { get: true, set: true },
y: { get: true, set: true },
},
createConstructor: true
})
core_gen.addApiStructByName("Vector3", {
core.addApiStructByName("Vector3", {
properties: {
x: { get: true, set: true },
y: { get: true, set: true },
@ -41,14 +68,32 @@ function main(){
},
createConstructor: true
})
core_gen.addApiStructByName("Ray", {
core.addApiStructByName("Vector4", {
properties: {
x: { get: true, set: true },
y: { get: true, set: true },
z: { get: true, set: true },
w: { get: true, set: true },
},
createConstructor: true
})
core.addApiStructByName("Ray", {
properties: {
position: { get: false, set: true },
direction: { get: false, set: true },
},
createConstructor: true
})
core_gen.addApiStructByName("Camera2D",{
core.addApiStructByName("RayCollision", {
properties: {
hit: { get: true, set: false },
distance: { get: true, set: false },
//point: { get: true, set: false },
//normal: { get: true, set: false },
},
createConstructor: false
})
core.addApiStructByName("Camera2D",{
properties: {
offset: { get: false, set: true },
target: { get: false, set: true },
@ -57,220 +102,718 @@ function main(){
},
createConstructor: true
})
core_gen.addApiStructByName("Matrix",{
core.addApiStructByName("Camera3D",{
properties: {
position: { get: false, set: true },
target: { get: false, set: true },
up: { get: false, set: true },
fovy: { get: true, set: true },
projection: { get: true, set: true },
},
createConstructor: true
})
core.addApiStructByName("BoundingBox",{
properties: {},
createConstructor: true
})
core.addApiStructByName("Matrix",{
properties: {},
createConstructor: false
})
core.addApiStructByName("Image", {
properties: {
width: { get: true },
height: { get: true },
mipmaps: { get: true },
format: { get: true }
},
destructor: "UnloadImage"
})
core.addApiStructByName("Wave", {
properties: {
frameCount: { get: true },
sampleRate: { get: true },
sampleSize: { get: true },
channels: { get: true }
},
destructor: "UnloadWave"
})
core.addApiStructByName("Sound", {
properties: {
frameCount: { get: true }
},
destructor: "UnloadSound"
})
core.addApiStructByName("Music", {
properties: {
frameCount: { get: true },
looping: { get: true, set: true }
},
destructor: "UnloadMusicStream"
})
core.addApiStructByName("Model", {
properties: {},
destructor: "UnloadModel"
})
core.addApiStructByName("Mesh", {
properties: {},
destructor: "UnloadMesh"
})
core.addApiStructByName("Shader", {
properties: {},
destructor: "UnloadShader"
})
core.addApiStructByName("Texture", {
properties: {
width: { get: true },
height: { get: true }
},
destructor: "UnloadTexture"
})
core.addApiStructByName("Font", {
properties: {
baseSize: { get: true }
},
destructor: "UnloadFont"
})
// Window-related functions
core_gen.addApiFunctionByName("InitWindow")
core_gen.addApiFunctionByName("WindowShouldClose")
core_gen.addApiFunctionByName("CloseWindow")
core_gen.addApiFunctionByName("IsWindowReady")
core_gen.addApiFunctionByName("IsWindowFullscreen")
core_gen.addApiFunctionByName("IsWindowHidden")
core_gen.addApiFunctionByName("IsWindowMinimized")
core_gen.addApiFunctionByName("IsWindowMaximized")
core_gen.addApiFunctionByName("IsWindowFocused")
core_gen.addApiFunctionByName("IsWindowResized")
core_gen.addApiFunctionByName("IsWindowState")
core_gen.addApiFunctionByName("SetWindowState")
core_gen.addApiFunctionByName("ClearWindowState")
core_gen.addApiFunctionByName("ToggleFullscreen")
core_gen.addApiFunctionByName("MaximizeWindow")
core_gen.addApiFunctionByName("MinimizeWindow")
core_gen.addApiFunctionByName("RestoreWindow")
core.addApiFunctionByName("InitWindow")
core.addApiFunctionByName("WindowShouldClose")
core.addApiFunctionByName("CloseWindow")
core.addApiFunctionByName("IsWindowReady")
core.addApiFunctionByName("IsWindowFullscreen")
core.addApiFunctionByName("IsWindowHidden")
core.addApiFunctionByName("IsWindowMinimized")
core.addApiFunctionByName("IsWindowMaximized")
core.addApiFunctionByName("IsWindowFocused")
core.addApiFunctionByName("IsWindowResized")
core.addApiFunctionByName("IsWindowState")
core.addApiFunctionByName("SetWindowState")
core.addApiFunctionByName("ClearWindowState")
core.addApiFunctionByName("ToggleFullscreen")
core.addApiFunctionByName("MaximizeWindow")
core.addApiFunctionByName("MinimizeWindow")
core.addApiFunctionByName("RestoreWindow")
// SetWindowIcon
// SetWindowIcons
core_gen.addApiFunctionByName("SetWindowTitle")
core_gen.addApiFunctionByName("SetWindowPosition")
core_gen.addApiFunctionByName("SetWindowMonitor")
core_gen.addApiFunctionByName("SetWindowMinSize")
core_gen.addApiFunctionByName("SetWindowSize")
core_gen.addApiFunctionByName("SetWindowOpacity")
core.addApiFunctionByName("SetWindowTitle")
core.addApiFunctionByName("SetWindowPosition")
core.addApiFunctionByName("SetWindowMonitor")
core.addApiFunctionByName("SetWindowMinSize")
core.addApiFunctionByName("SetWindowSize")
core.addApiFunctionByName("SetWindowOpacity")
// GetWindowHandle
core_gen.addApiFunctionByName("GetScreenWidth")
core_gen.addApiFunctionByName("GetScreenHeight")
core_gen.addApiFunctionByName("GetRenderWidth")
core_gen.addApiFunctionByName("GetRenderHeight")
core_gen.addApiFunctionByName("GetMonitorCount")
core_gen.addApiFunctionByName("GetCurrentMonitor")
core_gen.addApiFunctionByName("GetMonitorPosition")
core_gen.addApiFunctionByName("GetMonitorWidth")
core_gen.addApiFunctionByName("GetMonitorHeight")
core_gen.addApiFunctionByName("GetMonitorPhysicalWidth")
core_gen.addApiFunctionByName("GetMonitorPhysicalHeight")
core_gen.addApiFunctionByName("GetMonitorRefreshRate")
core_gen.addApiFunctionByName("GetWindowPosition")
core_gen.addApiFunctionByName("GetWindowScaleDPI")
core_gen.addApiFunctionByName("GetMonitorName")
core_gen.addApiFunctionByName("SetClipboardText")
core_gen.addApiFunctionByName("GetClipboardText")
core_gen.addApiFunctionByName("EnableEventWaiting")
core_gen.addApiFunctionByName("DisableEventWaiting")
core.addApiFunctionByName("GetScreenWidth")
core.addApiFunctionByName("GetScreenHeight")
core.addApiFunctionByName("GetRenderWidth")
core.addApiFunctionByName("GetRenderHeight")
core.addApiFunctionByName("GetMonitorCount")
core.addApiFunctionByName("GetCurrentMonitor")
core.addApiFunctionByName("GetMonitorPosition")
core.addApiFunctionByName("GetMonitorWidth")
core.addApiFunctionByName("GetMonitorHeight")
core.addApiFunctionByName("GetMonitorPhysicalWidth")
core.addApiFunctionByName("GetMonitorPhysicalHeight")
core.addApiFunctionByName("GetMonitorRefreshRate")
core.addApiFunctionByName("GetWindowPosition")
core.addApiFunctionByName("GetWindowScaleDPI")
core.addApiFunctionByName("GetMonitorName")
core.addApiFunctionByName("SetClipboardText")
core.addApiFunctionByName("GetClipboardText")
core.addApiFunctionByName("EnableEventWaiting")
core.addApiFunctionByName("DisableEventWaiting")
// Custom frame control functions
// NOT SUPPORTED BECAUSE NEEDS COMPILER FLAG
// Cursor-related functions
core_gen.addApiFunctionByName("ShowCursor")
core_gen.addApiFunctionByName("HideCursor")
core_gen.addApiFunctionByName("IsCursorHidden")
core_gen.addApiFunctionByName("EnableCursor")
core_gen.addApiFunctionByName("DisableCursor")
core_gen.addApiFunctionByName("IsCursorOnScreen")
core.addApiFunctionByName("ShowCursor")
core.addApiFunctionByName("HideCursor")
core.addApiFunctionByName("IsCursorHidden")
core.addApiFunctionByName("EnableCursor")
core.addApiFunctionByName("DisableCursor")
core.addApiFunctionByName("IsCursorOnScreen")
// Drawing related functions
core_gen.addApiFunctionByName("ClearBackground")
core_gen.addApiFunctionByName("BeginDrawing")
core_gen.addApiFunctionByName("EndDrawing", null, { before: fun => fun.call("app_update_quickjs", []) })
core_gen.addApiFunctionByName("BeginMode2D")
core_gen.addApiFunctionByName("EndMode2D")
//core_gen.addApiFunctionByName("BeginMode3D")
//core_gen.addApiFunctionByName("EndMode3D")
//core_gen.addApiFunctionByName("BeginTextureMode")
//core_gen.addApiFunctionByName("EndTextureMode")
//core_gen.addApiFunctionByName("BeginShaderMode")
//core_gen.addApiFunctionByName("EndShaderMode")
core_gen.addApiFunctionByName("BeginBlendMode")
core_gen.addApiFunctionByName("EndBlendMode")
core_gen.addApiFunctionByName("BeginScissorMode")
core_gen.addApiFunctionByName("EndScissorMode")
//core_gen.addApiFunctionByName("BeginVrStereoMode")
//core_gen.addApiFunctionByName("EndVrStereoMode")
core.addApiFunctionByName("ClearBackground")
core.addApiFunctionByName("BeginDrawing")
core.addApiFunctionByName("EndDrawing", null, { before: fun => fun.call("app_update_quickjs", []) })
core.addApiFunctionByName("BeginMode2D")
core.addApiFunctionByName("EndMode2D")
core.addApiFunctionByName("BeginMode3D")
core.addApiFunctionByName("EndMode3D")
//core.addApiFunctionByName("BeginTextureMode")
//core.addApiFunctionByName("EndTextureMode")
//core.addApiFunctionByName("BeginShaderMode")
//core.addApiFunctionByName("EndShaderMode")
core.addApiFunctionByName("BeginBlendMode")
core.addApiFunctionByName("EndBlendMode")
core.addApiFunctionByName("BeginScissorMode")
core.addApiFunctionByName("EndScissorMode")
//core.addApiFunctionByName("BeginVrStereoMode")
//core.addApiFunctionByName("EndVrStereoMode")
// VR Stereo config options
//core_gen.addApiFunctionByName("LoadVrStereoConfig")
//core_gen.addApiFunctionByName("UnloadVrStereoConfig")
//core.addApiFunctionByName("LoadVrStereoConfig")
//core.addApiFunctionByName("UnloadVrStereoConfig")
// Shader Management
// core_gen.addApiFunctionByName("LoadShader")
// core_gen.addApiFunctionByName("LoadShaderFromMemory")
// core_gen.addApiFunctionByName("IsShaderReady")
// core_gen.addApiFunctionByName("GetShaderLocation")
// core_gen.addApiFunctionByName("GetShaderLocationAttrib")
// core_gen.addApiFunctionByName("SetShaderValue")
// core_gen.addApiFunctionByName("SetShaderValueV")
// core_gen.addApiFunctionByName("SetShaderValueMatrix")
// core_gen.addApiFunctionByName("SetShaderValueTexture")
// core.addApiFunctionByName("LoadShader")
// core.addApiFunctionByName("LoadShaderFromMemory")
// core.addApiFunctionByName("IsShaderReady")
// core.addApiFunctionByName("GetShaderLocation")
// core.addApiFunctionByName("GetShaderLocationAttrib")
// core.addApiFunctionByName("SetShaderValue")
// core.addApiFunctionByName("SetShaderValueV")
// core.addApiFunctionByName("SetShaderValueMatrix")
// core.addApiFunctionByName("SetShaderValueTexture")
// // "UnloadShader" is destructor
// ScreenSpaceRelatedFunctions
//core_gen.addApiFunctionByName("GetMouseRay")
//core_gen.addApiFunctionByName("GetCameraMatrix")
core_gen.addApiFunctionByName("GetCameraMatrix2D")
//core_gen.addApiFunctionByName("GetWorldToScreen")
core_gen.addApiFunctionByName("GetScreenToWorld2D")
//core_gen.addApiFunctionByName("GetScreenToWorldEx")
core_gen.addApiFunctionByName("GetWorldToScreen2D")
//core.addApiFunctionByName("GetMouseRay")
//core.addApiFunctionByName("GetCameraMatrix")
core.addApiFunctionByName("GetCameraMatrix2D")
//core.addApiFunctionByName("GetWorldToScreen")
core.addApiFunctionByName("GetScreenToWorld2D")
//core.addApiFunctionByName("GetScreenToWorldEx")
core.addApiFunctionByName("GetWorldToScreen2D")
// Timing related functions
core_gen.addApiFunctionByName("SetTargetFPS")
core_gen.addApiFunctionByName("GetFPS")
core_gen.addApiFunctionByName("GetFrameTime")
core_gen.addApiFunctionByName("GetTime")
core.addApiFunctionByName("SetTargetFPS")
core.addApiFunctionByName("GetFPS")
core.addApiFunctionByName("GetFrameTime")
core.addApiFunctionByName("GetTime")
// Misc functions
core_gen.addApiFunctionByName("GetRandomValue")
core_gen.addApiFunctionByName("SetRandomSeed")
core_gen.addApiFunctionByName("TakeScreenshot")
core_gen.addApiFunctionByName("SetConfigFlags")
core.addApiFunctionByName("GetRandomValue")
core.addApiFunctionByName("SetRandomSeed")
core.addApiFunctionByName("TakeScreenshot")
core.addApiFunctionByName("SetConfigFlags")
const traceLog = apiDesc.getFunction("TraceLog")
if(!traceLog) throw new Error("TraceLog not found")
traceLog.params.pop()
core_gen.addApiFunction(traceLog)
core_gen.addApiFunctionByName("SetTraceLogLevel")
core.addApiFunction(traceLog)
core.addApiFunctionByName("SetTraceLogLevel")
// Memory functions not supported on JS
core_gen.addApiFunctionByName("OpenURL")
core.addApiFunctionByName("OpenURL")
// Callbacks not supported on JS
// Files management functions
//core_gen.addApiFunctionByName("LoadFileData")
//core_gen.addApiFunctionByName("UnloadLoadFileData")
//core_gen.addApiFunctionByName("SaveFileData")
//core.addApiFunctionByName("LoadFileData")
//core.addApiFunctionByName("UnloadLoadFileData")
//core.addApiFunctionByName("SaveFileData")
// Export data as code not needed
core_gen.addApiFunctionByName("LoadFileText", null, { after: gen => gen.call("UnloadFileText", ["returnVal"]) })
core_gen.addApiFunctionByName("SaveFileText")
core_gen.addApiFunctionByName("FileExists")
core_gen.addApiFunctionByName("DirectoryExists")
core_gen.addApiFunctionByName("IsFileExtension")
core.addApiFunctionByName("LoadFileText", null, { after: gen => gen.call("UnloadFileText", ["returnVal"]) })
core.addApiFunctionByName("SaveFileText")
core.addApiFunctionByName("FileExists")
core.addApiFunctionByName("DirectoryExists")
core.addApiFunctionByName("IsFileExtension")
// TODO: Who needs to clean memory here?
core_gen.addApiFunctionByName("GetFileLength")
core_gen.addApiFunctionByName("GetFileExtension")
core_gen.addApiFunctionByName("GetFileName")
core_gen.addApiFunctionByName("GetFileNameWithoutExt")
core_gen.addApiFunctionByName("GetDirectoryPath")
core_gen.addApiFunctionByName("GetPrevDirectoryPath")
core_gen.addApiFunctionByName("GetWorkingDirectory")
core_gen.addApiFunctionByName("GetApplicationDirectory")
core_gen.addApiFunctionByName("ChangeDirectory")
core_gen.addApiFunctionByName("IsPathFile")
//core_gen.addApiFunctionByName("LoadPathFiles")
//core_gen.addApiFunctionByName("LoadPathFilesEx")
core.addApiFunctionByName("GetFileLength")
core.addApiFunctionByName("GetFileExtension")
core.addApiFunctionByName("GetFileName")
core.addApiFunctionByName("GetFileNameWithoutExt")
core.addApiFunctionByName("GetDirectoryPath")
core.addApiFunctionByName("GetPrevDirectoryPath")
core.addApiFunctionByName("GetWorkingDirectory")
core.addApiFunctionByName("GetApplicationDirectory")
core.addApiFunctionByName("ChangeDirectory")
core.addApiFunctionByName("IsPathFile")
//core.addApiFunctionByName("LoadPathFiles")
//core.addApiFunctionByName("LoadPathFilesEx")
// UnloadDirectoryFiles
core_gen.addApiFunctionByName("IsFileDropped")
//core_gen.addApiFunctionByName("LoadDroppedFiles")
core.addApiFunctionByName("IsFileDropped")
//core.addApiFunctionByName("LoadDroppedFiles")
// UnloadDroppedFiles
core_gen.addApiFunctionByName("GetFileModTime")
core.addApiFunctionByName("GetFileModTime")
// Compression/encodeing functionality
//core_gen.addApiFunctionByName("CompressData")
//core_gen.addApiFunctionByName("DecompressData")
//core_gen.addApiFunctionByName("EncodeDataBase64")
//core_gen.addApiFunctionByName("DecodeDataBase64")
//core.addApiFunctionByName("CompressData")
//core.addApiFunctionByName("DecompressData")
//core.addApiFunctionByName("EncodeDataBase64")
//core.addApiFunctionByName("DecodeDataBase64")
// input handling functions
core_gen.addApiFunctionByName("IsKeyPressed")
core_gen.addApiFunctionByName("IsKeyDown")
core_gen.addApiFunctionByName("IsKeyReleased")
core_gen.addApiFunctionByName("IsKeyUp")
core_gen.addApiFunctionByName("SetExitKey")
core_gen.addApiFunctionByName("GetKeyPressed")
core_gen.addApiFunctionByName("GetCharPressed")
core.addApiFunctionByName("IsKeyPressed")
core.addApiFunctionByName("IsKeyDown")
core.addApiFunctionByName("IsKeyReleased")
core.addApiFunctionByName("IsKeyUp")
core.addApiFunctionByName("SetExitKey")
core.addApiFunctionByName("GetKeyPressed")
core.addApiFunctionByName("GetCharPressed")
// input-related functions
core_gen.addApiFunctionByName("IsGamepadAvailable")
core_gen.addApiFunctionByName("GetGamepadName")
core_gen.addApiFunctionByName("IsGamepadButtonPressed")
core_gen.addApiFunctionByName("IsGamepadButtonDown")
core_gen.addApiFunctionByName("IsGamepadButtonReleased")
core_gen.addApiFunctionByName("IsGamepadButtonUp")
core_gen.addApiFunctionByName("GetGamepadButtonPressed")
core_gen.addApiFunctionByName("GetGamepadAxisCount")
core_gen.addApiFunctionByName("GetGamepadAxisMovement")
core_gen.addApiFunctionByName("SetGamepadMappings")
// input-related functions: gamepads
core.addApiFunctionByName("IsGamepadAvailable")
core.addApiFunctionByName("GetGamepadName")
core.addApiFunctionByName("IsGamepadButtonPressed")
core.addApiFunctionByName("IsGamepadButtonDown")
core.addApiFunctionByName("IsGamepadButtonReleased")
core.addApiFunctionByName("IsGamepadButtonUp")
core.addApiFunctionByName("GetGamepadButtonPressed")
core.addApiFunctionByName("GetGamepadAxisCount")
core.addApiFunctionByName("GetGamepadAxisMovement")
core.addApiFunctionByName("SetGamepadMappings")
core_gen.addApiFunctionByName("DrawText")
core_gen.addApiFunctionByName("DrawLine")
core_gen.addApiFunctionByName("DrawCircleV")
core_gen.addApiFunctionByName("GetMousePosition")
core_gen.addApiFunctionByName("IsMouseButtonPressed")
core_gen.addApiFunctionByName("GetMouseWheelMove")
core_gen.addApiFunctionByName("DrawRectangle")
core_gen.addApiFunctionByName("DrawRectangleRec")
core_gen.addApiFunctionByName("DrawRectangleLines")
core_gen.addApiFunctionByName("Fade")
api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => {
core_gen.exportGlobalStruct("Color", x.name, x.values)
// input-related functions: mouse
core.addApiFunctionByName("IsMouseButtonPressed")
core.addApiFunctionByName("IsMouseButtonDown")
core.addApiFunctionByName("IsMouseButtonReleased")
core.addApiFunctionByName("IsMouseButtonUp")
core.addApiFunctionByName("GetMouseX")
core.addApiFunctionByName("GetMouseY")
core.addApiFunctionByName("GetMousePosition")
core.addApiFunctionByName("GetMouseDelta")
core.addApiFunctionByName("SetMousePosition")
core.addApiFunctionByName("SetMouseOffset")
core.addApiFunctionByName("SetMouseScale")
core.addApiFunctionByName("GetMouseWheelMove")
core.addApiFunctionByName("GetMouseWheelMoveV")
core.addApiFunctionByName("SetMouseCursor")
// input-related functions: touch
core.addApiFunctionByName("GetTouchX")
core.addApiFunctionByName("GetTouchY")
core.addApiFunctionByName("GetTouchPosition")
core.addApiFunctionByName("GetTouchPointId")
core.addApiFunctionByName("GetTouchPointCount")
// Gesture and touch handling functions
core.addApiFunctionByName("SetGesturesEnabled")
core.addApiFunctionByName("IsGestureDetected")
core.addApiFunctionByName("GetGestureDetected")
core.addApiFunctionByName("GetGestureHoldDuration")
core.addApiFunctionByName("GetGestureDragVector")
core.addApiFunctionByName("GetGestureDragAngle")
core.addApiFunctionByName("GetGesturePinchVector")
core.addApiFunctionByName("GetGesturePinchAngle")
// Camera system functions
// core.addApiFunctionByName("UpdateCamera")
// core.addApiFunctionByName("UpdateCameraPro")
//api.functions.forEach(x => console.log(`core.addApiFunctionByName("${x.name}")`))
// module: rshapes
// TODO: Do we need ref-counting here?
//core.addApiFunctionByName("SetShapesTexture")
// Basic shapes drawing functions
core.addApiFunctionByName("DrawPixel")
core.addApiFunctionByName("DrawPixelV")
core.addApiFunctionByName("DrawLine")
core.addApiFunctionByName("DrawLineV")
core.addApiFunctionByName("DrawLineEx")
core.addApiFunctionByName("DrawLineBezier")
core.addApiFunctionByName("DrawLineBezierQuad")
core.addApiFunctionByName("DrawLineBezierCubic")
// core.addApiFunctionByName("DrawLineStrip")
core.addApiFunctionByName("DrawCircle")
core.addApiFunctionByName("DrawCircleSector")
core.addApiFunctionByName("DrawCircleSectorLines")
core.addApiFunctionByName("DrawCircleGradient")
core.addApiFunctionByName("DrawCircleV")
core.addApiFunctionByName("DrawCircleLines")
core.addApiFunctionByName("DrawEllipse")
core.addApiFunctionByName("DrawEllipseLines")
core.addApiFunctionByName("DrawRing")
core.addApiFunctionByName("DrawRingLines")
core.addApiFunctionByName("DrawRectangle")
core.addApiFunctionByName("DrawRectangleV")
core.addApiFunctionByName("DrawRectangleRec")
core.addApiFunctionByName("DrawRectanglePro")
core.addApiFunctionByName("DrawRectangleGradientV")
core.addApiFunctionByName("DrawRectangleGradientH")
core.addApiFunctionByName("DrawRectangleGradientEx")
core.addApiFunctionByName("DrawRectangleLines")
core.addApiFunctionByName("DrawRectangleLinesEx")
core.addApiFunctionByName("DrawRectangleRounded")
core.addApiFunctionByName("DrawRectangleRoundedLines")
core.addApiFunctionByName("DrawTriangle")
core.addApiFunctionByName("DrawTriangleLines")
//core.addApiFunctionByName("DrawTriangleFan")
//core.addApiFunctionByName("DrawTriangleStrip")
core.addApiFunctionByName("DrawPoly")
core.addApiFunctionByName("DrawPolyLines")
core.addApiFunctionByName("DrawPolyLinesEx")
// Basic shapes collision detection functions
core.addApiFunctionByName("CheckCollisionRecs")
core.addApiFunctionByName("CheckCollisionCircles")
core.addApiFunctionByName("CheckCollisionCircleRec")
core.addApiFunctionByName("CheckCollisionPointRec")
core.addApiFunctionByName("CheckCollisionPointCircle")
core.addApiFunctionByName("CheckCollisionPointTriangle")
// core.addApiFunctionByName("CheckCollisionPointPoly")
// core.addApiFunctionByName("CheckCollisionLines")
core.addApiFunctionByName("CheckCollisionPointLine")
core.addApiFunctionByName("GetCollisionRec")
// Image loading functions
core.addApiFunctionByName("LoadImage")
core.addApiFunctionByName("LoadImageRaw")
// core.addApiFunctionByName("LoadImageAnim")
// core.addApiFunctionByName("LoadImageFromMemory")
core.addApiFunctionByName("LoadImageFromTexture")
core.addApiFunctionByName("LoadImageFromScreen")
core.addApiFunctionByName("IsImageReady")
// UnloadImage called by destructor
core.addApiFunctionByName("ExportImage")
// needed?
// core.addApiFunctionByName("ExportImageAsCode")
// Image generation functions
core.addApiFunctionByName("GenImageColor")
core.addApiFunctionByName("GenImageGradientV")
core.addApiFunctionByName("GenImageGradientH")
core.addApiFunctionByName("GenImageGradientRadial")
core.addApiFunctionByName("GenImageChecked")
core.addApiFunctionByName("GenImageWhiteNoise")
core.addApiFunctionByName("GenImagePerlinNoise")
core.addApiFunctionByName("GenImageCellular")
core.addApiFunctionByName("GenImageText")
// Image manipulations functions
core.addApiFunctionByName("ImageCopy")
core.addApiFunctionByName("ImageFromImage")
core.addApiFunctionByName("ImageText")
// core.addApiFunctionByName("ImageTextEx")
// core.addApiFunctionByName("ImageFormat")
// core.addApiFunctionByName("ImageToPOT")
// core.addApiFunctionByName("ImageCrop")
// core.addApiFunctionByName("ImageAlphaCrop")
// core.addApiFunctionByName("ImageAlphaClear")
// core.addApiFunctionByName("ImageAlphaMask")
// core.addApiFunctionByName("ImageAlphaPremultiply")
// core.addApiFunctionByName("ImageBlurGaussian")
// core.addApiFunctionByName("ImageResize")
// core.addApiFunctionByName("ImageResizeNN")
// core.addApiFunctionByName("ImageResizeCanvas")
// core.addApiFunctionByName("ImageMipmaps")
// core.addApiFunctionByName("ImageDither")
// core.addApiFunctionByName("ImageFlipVertical")
// core.addApiFunctionByName("ImageFlipHorizontal")
// core.addApiFunctionByName("ImageRotateCW")
// core.addApiFunctionByName("ImageRotateCCW")
// core.addApiFunctionByName("ImageColorTint")
// core.addApiFunctionByName("ImageColorInvert")
// core.addApiFunctionByName("ImageColorGrayscale")
// core.addApiFunctionByName("ImageColorContrast")
// core.addApiFunctionByName("ImageColorBrightness")
// core.addApiFunctionByName("ImageColorReplace")
// core.addApiFunctionByName("LoadImageColors")
// core.addApiFunctionByName("LoadImagePalette")
// core.addApiFunctionByName("UnloadImageColors")
// core.addApiFunctionByName("UnloadImagePalette")
core.addApiFunctionByName("GetImageAlphaBorder")
core.addApiFunctionByName("GetImageColor")
// Image drawing functions
// core.addApiFunctionByName("ImageClearBackground")
// core.addApiFunctionByName("ImageDrawPixel")
// core.addApiFunctionByName("ImageDrawPixelV")
// core.addApiFunctionByName("ImageDrawLine")
// core.addApiFunctionByName("ImageDrawLineV")
// core.addApiFunctionByName("ImageDrawCircle")
// core.addApiFunctionByName("ImageDrawCircleV")
// core.addApiFunctionByName("ImageDrawCircleLines")
// core.addApiFunctionByName("ImageDrawCircleLinesV")
// core.addApiFunctionByName("ImageDrawRectangle")
// core.addApiFunctionByName("ImageDrawRectangleV")
// core.addApiFunctionByName("ImageDrawRectangleRec")
// core.addApiFunctionByName("ImageDrawRectangleLines")
// core.addApiFunctionByName("ImageDraw")
// core.addApiFunctionByName("ImageDrawText")
// core.addApiFunctionByName("ImageDrawTextEx")
// Texture loading functions
core.addApiFunctionByName("LoadTexture")
core.addApiFunctionByName("LoadTextureFromImage")
core.addApiFunctionByName("LoadTextureCubemap")
// core.addApiFunctionByName("LoadRenderTexture")
core.addApiFunctionByName("IsTextureReady")
// "UnloadTexture" called by finalizer
// core.addApiFunctionByName("IsRenderTextureReady")
// core.addApiFunctionByName("UnloadRenderTexture")
// core.addApiFunctionByName("UpdateTexture")
// core.addApiFunctionByName("UpdateTextureRec")
// Texture configuration functions
// core.addApiFunctionByName("GenTextureMipmaps")
core.addApiFunctionByName("SetTextureFilter")
core.addApiFunctionByName("SetTextureWrap")
// Texture drawing functions
core.addApiFunctionByName("DrawTexture")
core.addApiFunctionByName("DrawTextureV")
core.addApiFunctionByName("DrawTextureEx")
core.addApiFunctionByName("DrawTextureRec")
core.addApiFunctionByName("DrawTexturePro")
// core.addApiFunctionByName("DrawTextureNPatch")
// Color/pixel related functions
core.addApiFunctionByName("Fade")
core.addApiFunctionByName("ColorToInt")
core.addApiFunctionByName("ColorNormalize")
core.addApiFunctionByName("ColorFromNormalized")
core.addApiFunctionByName("ColorToHSV")
core.addApiFunctionByName("ColorFromHSV")
core.addApiFunctionByName("ColorTint")
core.addApiFunctionByName("ColorBrightness")
core.addApiFunctionByName("ColorContrast")
core.addApiFunctionByName("ColorAlpha")
core.addApiFunctionByName("ColorAlphaBlend")
core.addApiFunctionByName("GetColor")
// core.addApiFunctionByName("GetPixelColor")
// core.addApiFunctionByName("SetPixelColor")
core.addApiFunctionByName("GetPixelDataSize")
// module: rtext
// Font loading/unloading
core.addApiFunctionByName("GetFontDefault")
core.addApiFunctionByName("LoadFont")
// core.addApiFunctionByName("LoadFontEx")
core.addApiFunctionByName("LoadFontFromImage")
// core.addApiFunctionByName("LoadFontFromMemory")
core.addApiFunctionByName("IsFontReady")
// core.addApiFunctionByName("LoadFontData")
// core.addApiFunctionByName("GenImageFontAtlas")
// core.addApiFunctionByName("UnloadFontData")
// "UnloadFont" called by finalizer
// core.addApiFunctionByName("ExportFontAsCode")
// Text drawing functions
core.addApiFunctionByName("DrawFPS")
core.addApiFunctionByName("DrawText")
core.addApiFunctionByName("DrawTextEx")
core.addApiFunctionByName("DrawTextPro")
core.addApiFunctionByName("DrawTextCodepoint")
//core.addApiFunctionByName("DrawTextCodepoints")
// Text font info functions
core.addApiFunctionByName("MeasureText")
core.addApiFunctionByName("MeasureTextEx")
core.addApiFunctionByName("GetGlyphIndex")
// core.addApiFunctionByName("GetGlyphInfo")
core.addApiFunctionByName("GetGlyphAtlasRec")
// Text codepoints management functions (unicode characters)
// Is this needed?
// core.addApiFunctionByName("LoadUTF8")
// core.addApiFunctionByName("UnloadUTF8")
// core.addApiFunctionByName("LoadCodepoints")
// core.addApiFunctionByName("UnloadCodepoints")
// core.addApiFunctionByName("GetCodepointCount")
// core.addApiFunctionByName("GetCodepoint")
// core.addApiFunctionByName("GetCodepointNext")
// core.addApiFunctionByName("GetCodepointPrevious")
// core.addApiFunctionByName("CodepointToUTF8")
// Text strings management functions (no UTF-8 strings, only byte chars)
// Probably not needed
// core.addApiFunctionByName("TextCopy")
// core.addApiFunctionByName("TextIsEqual")
// core.addApiFunctionByName("TextLength")
// core.addApiFunctionByName("TextFormat")
// core.addApiFunctionByName("TextSubtext")
// core.addApiFunctionByName("TextReplace")
// core.addApiFunctionByName("TextInsert")
// core.addApiFunctionByName("TextJoin")
// core.addApiFunctionByName("TextSplit")
// core.addApiFunctionByName("TextAppend")
// core.addApiFunctionByName("TextFindIndex")
// core.addApiFunctionByName("TextToUpper")
// core.addApiFunctionByName("TextToLower")
// core.addApiFunctionByName("TextToPascal")
// core.addApiFunctionByName("TextToInteger")
// module: rmodels
// Basic geometric 3D shapes drawing functions
core.addApiFunctionByName("DrawLine3D")
core.addApiFunctionByName("DrawPoint3D")
core.addApiFunctionByName("DrawCircle3D")
core.addApiFunctionByName("DrawTriangle3D")
//core.addApiFunctionByName("DrawTriangleStrip3D")
core.addApiFunctionByName("DrawCube")
core.addApiFunctionByName("DrawCubeV")
core.addApiFunctionByName("DrawCubeWires")
core.addApiFunctionByName("DrawCubeWiresV")
core.addApiFunctionByName("DrawSphere")
core.addApiFunctionByName("DrawSphereEx")
core.addApiFunctionByName("DrawSphereWires")
core.addApiFunctionByName("DrawCylinder")
core.addApiFunctionByName("DrawCylinderEx")
core.addApiFunctionByName("DrawCylinderWires")
core.addApiFunctionByName("DrawCylinderWiresEx")
core.addApiFunctionByName("DrawCapsule")
core.addApiFunctionByName("DrawCapsuleWires")
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("GetModelBoundingBox")
// model drawing functions
core.addApiFunctionByName("DrawModel")
core.addApiFunctionByName("DrawModelEx")
core.addApiFunctionByName("DrawModelWires")
core.addApiFunctionByName("DrawModelWiresEx")
core.addApiFunctionByName("DrawBoundingBox")
core.addApiFunctionByName("DrawBillboard")
core.addApiFunctionByName("DrawBillboardRec")
core.addApiFunctionByName("DrawBillboardPro")
// Mesh management functions
// core.addApiFunctionByName("UploadMesh")
// core.addApiFunctionByName("UpdateMeshBuffer")
// "UnloadMesh" called by finalizer
//core.addApiFunctionByName("DrawMesh")
// core.addApiFunctionByName("DrawMeshInstanced")
core.addApiFunctionByName("ExportMesh")
core.addApiFunctionByName("GetMeshBoundingBox")
// core.addApiFunctionByName("GenMeshTangents")
// Mesh generation functions
core.addApiFunctionByName("GenMeshPoly")
core.addApiFunctionByName("GenMeshPlane")
core.addApiFunctionByName("GenMeshCube")
core.addApiFunctionByName("GenMeshSphere")
core.addApiFunctionByName("GenMeshHemiSphere")
core.addApiFunctionByName("GenMeshCylinder")
core.addApiFunctionByName("GenMeshCone")
core.addApiFunctionByName("GenMeshTorus")
core.addApiFunctionByName("GenMeshKnot")
core.addApiFunctionByName("GenMeshHeightmap")
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")
// Model animations loading/unloading functions
// core.addApiFunctionByName("LoadModelAnimations")
// core.addApiFunctionByName("UpdateModelAnimation")
// core.addApiFunctionByName("UnloadModelAnimation")
// core.addApiFunctionByName("UnloadModelAnimations")
// core.addApiFunctionByName("IsModelAnimationValid")
// Collision detection functions
core.addApiFunctionByName("CheckCollisionSpheres")
core.addApiFunctionByName("CheckCollisionBoxes")
core.addApiFunctionByName("CheckCollisionBoxSphere")
core.addApiFunctionByName("GetRayCollisionSphere")
core.addApiFunctionByName("GetRayCollisionBox")
core.addApiFunctionByName("GetRayCollisionMesh")
core.addApiFunctionByName("GetRayCollisionTriangle")
core.addApiFunctionByName("GetRayCollisionQuad")
// module: raudio
// Audio device management functions
core.addApiFunctionByName("InitAudioDevice")
core.addApiFunctionByName("CloseAudioDevice")
core.addApiFunctionByName("IsAudioDeviceReady")
core.addApiFunctionByName("SetMasterVolume")
// Wave/Sound loading/unloading functions
core.addApiFunctionByName("LoadWave")
// core.addApiFunctionByName("LoadWaveFromMemory")
core.addApiFunctionByName("IsWaveReady")
core.addApiFunctionByName("LoadSound")
core.addApiFunctionByName("LoadSoundFromWave")
core.addApiFunctionByName("IsSoundReady")
// core.addApiFunctionByName("UpdateSound")
// "UnloadWave" called by finalizer
// "UnloadSound" called by finalizer
core.addApiFunctionByName("ExportWave")
// core.addApiFunctionByName("ExportWaveAsCode")
// Wave/Sound management functions
core.addApiFunctionByName("PlaySound")
core.addApiFunctionByName("StopSound")
core.addApiFunctionByName("PauseSound")
core.addApiFunctionByName("ResumeSound")
core.addApiFunctionByName("IsSoundPlaying")
core.addApiFunctionByName("SetSoundVolume")
core.addApiFunctionByName("SetSoundPitch")
core.addApiFunctionByName("SetSoundPan")
core.addApiFunctionByName("WaveCopy")
// core.addApiFunctionByName("WaveCrop")
// core.addApiFunctionByName("WaveFormat")
// core.addApiFunctionByName("LoadWaveSamples")
// core.addApiFunctionByName("UnloadWaveSamples")
// Music management functions
core.addApiFunctionByName("LoadMusicStream")
// core.addApiFunctionByName("LoadMusicStreamFromMemory")
core.addApiFunctionByName("IsMusicReady")
// "UnloadMusicStream" called by finalizer
core.addApiFunctionByName("PlayMusicStream")
core.addApiFunctionByName("IsMusicStreamPlaying")
core.addApiFunctionByName("UpdateMusicStream")
core.addApiFunctionByName("StopMusicStream")
core.addApiFunctionByName("PauseMusicStream")
core.addApiFunctionByName("ResumeMusicStream")
core.addApiFunctionByName("SeekMusicStream")
core.addApiFunctionByName("SetMusicVolume")
core.addApiFunctionByName("SetMusicPitch")
core.addApiFunctionByName("SetMusicPan")
core.addApiFunctionByName("GetMusicTimeLength")
core.addApiFunctionByName("GetMusicTimePlayed")
// AudioStream management functions
// core.addApiFunctionByName("LoadAudioStream")
// core.addApiFunctionByName("IsAudioStreamReady")
// core.addApiFunctionByName("UnloadAudioStream")
// core.addApiFunctionByName("UpdateAudioStream")
// core.addApiFunctionByName("IsAudioStreamProcessed")
// core.addApiFunctionByName("PlayAudioStream")
// core.addApiFunctionByName("PauseAudioStream")
// core.addApiFunctionByName("ResumeAudioStream")
// core.addApiFunctionByName("IsAudioStreamPlaying")
// core.addApiFunctionByName("StopAudioStream")
// core.addApiFunctionByName("SetAudioStreamVolume")
// core.addApiFunctionByName("SetAudioStreamPitch")
// core.addApiFunctionByName("SetAudioStreamPan")
// core.addApiFunctionByName("SetAudioStreamBufferSizeDefault")
// core.addApiFunctionByName("SetAudioStreamCallback")
// core.addApiFunctionByName("AttachAudioStreamProcessor")
// core.addApiFunctionByName("DetachAudioStreamProcessor")
// core.addApiFunctionByName("AttachAudioMixedProcessor")
// core.addApiFunctionByName("DetachAudioMixedProcessor")
// module: raymath
//mathApi.forEach(x => console.log(`core.addApi`))
api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, description: x.description, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => {
core.exportGlobalStruct("Color", x.name, x.values, x.description)
})
api.enums.find(x => x.name === "KeyboardKey")?.values.forEach(x => core_gen.exportGlobalConstant(x.name))
api.enums.find(x => x.name === "MouseButton")?.values.forEach(x => core_gen.exportGlobalConstant(x.name))
api.enums.find(x => x.name === "ConfigFlags")?.values.forEach(x => core_gen.exportGlobalConstant(x.name))
api.enums.find(x => x.name === "BlendMode")?.values.forEach(x => core_gen.exportGlobalConstant(x.name))
api.enums.find(x => x.name === "TraceLogLevel")?.values.forEach(x => core_gen.exportGlobalConstant(x.name))
core_gen.writeTo("src/bindings/js_raylib_core.h")
const texture_gen = new RayLibHeader("raylib_texture", apiDesc)
texture_gen.addApiStructByName("Image", {
properties: {
width: { get: true },
height: { get: true }
},
destructor: "UnloadImage"
})
texture_gen.addApiFunctionByName("LoadImage")
texture_gen.writeTo("src/bindings/js_raylib_texture.h")
api.enums.find(x => x.name === "KeyboardKey")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "MouseButton")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "ConfigFlags")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "BlendMode")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "TraceLogLevel")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "MouseCursor")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "PixelFormat")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
api.enums.find(x => x.name === "CameraProjection")?.values.forEach(x => core.exportGlobalConstant(x.name, x.description))
core.writeTo("src/bindings/js_raylib_core.h")
core.typings.writeTo("examples/lib.raylib.d.ts")
}
main()

View File

@ -32,18 +32,25 @@ export interface RayLibEnum {
}
export interface RayLibParamDescription {
type: RayLibType,
type: RayLibType | string,
name: string
}
export interface RayLibFunction {
name: string,
description: string,
returnType: RayLibType,
returnType: RayLibType | string,
params?: RayLibParamDescription[]
}
export interface RayLibAlias {
type: string
name: string,
description: string,
}
export interface RayLibApi {
aliases: RayLibAlias[],
defines: RayLibDefine[],
structs: RayLibStruct[],
enums: RayLibEnum[],

View File

@ -12,7 +12,7 @@ export class QuickJsHeader {
public readonly functions: QuickJsGenerator
public readonly moduleInit: QuickJsGenerator
public readonly moduleEntry: QuickJsGenerator
public readonly declarations: QuickJsGenerator
public readonly definitions: QuickJsGenerator
public readonly body: QuickJsGenerator
public readonly includes: QuickJsGenerator
private readonly root: QuickJsGenerator
@ -31,7 +31,7 @@ export class QuickJsHeader {
body.line("#define countof(x) (sizeof(x) / sizeof((x)[0]))")
body.line("#endif")
body.breakLine()
this.declarations = body.child()
this.definitions = body.child()
body.breakLine()
this.structs = body.child()
this.functions = body.child()
@ -83,23 +83,34 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend
this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`)
this.statement(`if(${name} == NULL) return JS_EXCEPTION`)
break;
case "double":
this.statement(`${type} ${name}`)
this.statement(`JS_ToFloat64(ctx, &${name}, ${src})`)
break;
case "float":
this.statement("double _double_"+name)
this.statement(`JS_ToFloat64(ctx, &_double_${name}, ${src})`)
this.statement(`${type} ${name} = (${type})_double_${name}`)
break;
case "int":
this.statement(`${type} ${name}`)
this.statement(`JS_ToInt32(ctx, &${name}, ${src})`)
break;
case "unsigned int":
this.statement(`${type} ${name}`)
this.statement(`JS_ToInt32(ctx, (int *)&${name}, ${src})`)
this.statement(`JS_ToUint32(ctx, &${name}, ${src})`)
break;
case "unsigned char":
this.statement("int _int_"+name)
this.statement(`JS_ToInt32(ctx, &_int_${name}, ${src})`)
this.statement("unsigned int _int_"+name)
this.statement(`JS_ToUint32(ctx, &_int_${name}, ${src})`)
this.statement(`${type} ${name} = (${type})_int_${name}`)
break;
case "bool":
this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`)
break;
default:
const classId = classIds[type]
const isConst = type.startsWith('const')
const classId = classIds[type.replace("const ", "")]
if(!classId) throw new Error("Cannot convert into parameter type: " + type)
this.jsOpqToStructPtr(type, name+"_ptr", src, classId)
this.statement(`if(${name}_ptr == NULL) return JS_EXCEPTION`)
@ -110,10 +121,16 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend
jsToJs(type: string, name: string, src: string, classIds: StructLookup = {}){
switch (type) {
case "int":
case "unsigned char":
case "long":
this.declare(name,'JSValue', false, `JS_NewInt32(ctx, ${src})`)
break;
case "long":
this.declare(name,'JSValue', false, `JS_NewInt64(ctx, ${src})`)
break;
case "unsigned int":
case "unsigned char":
this.declare(name,'JSValue', false, `JS_NewUint32(ctx, ${src})`)
break;
case "bool":
this.declare(name, 'JSValue', false, `JS_NewBool(ctx, ${src})`)
break;

View File

@ -1,6 +1,7 @@
import { ApiDescription, ApiFunction, ApiStruct } from "./api"
import { CodeGenerator } from "./generation"
import { QuickJsGenerator, QuickJsHeader } from "./quickjs"
import { TypeScriptDeclaration } from "./typescript"
export interface StructBindingOptions {
properties?: { [key:string]: { get?:boolean, set?:boolean } },
@ -17,6 +18,8 @@ export interface FuncBindingOptions {
export class RayLibHeader extends QuickJsHeader {
typings = new TypeScriptDeclaration()
constructor(name: string, private api: ApiDescription){
super(name)
this.includes.include("raylib.h")
@ -49,6 +52,7 @@ export class RayLibHeader extends QuickJsHeader {
// add binding to function declaration
this.moduleFunctionList.jsFuncDef(jName, api.argc, fun.getTag("_name"))
this.typings.addFunction(jName,api)
}
addApiFunctionByName(name: string, jsName: string | null = null, options: FuncBindingOptions = {}){
@ -58,8 +62,9 @@ export class RayLibHeader extends QuickJsHeader {
}
addApiStruct(struct: ApiStruct, destructor: ApiFunction | null, options?: StructBindingOptions){
const classId = this.declarations.jsClassId(`js_${struct.name}_class_id`)
const classId = this.definitions.jsClassId(`js_${struct.name}_class_id`)
this.registerStruct(struct.name, classId)
this.api.getAliases(struct.name).forEach(x => this.registerStruct(x, classId))
const finalizer = this.structs.jsStructFinalizer(classId, struct.name, (gen,ptr) => destructor && gen.call(destructor.name, ["*"+ptr]))
const propDeclarations = this.structs.createGenerator()
@ -91,20 +96,23 @@ export class RayLibHeader extends QuickJsHeader {
this.moduleEntry.call("JS_AddModuleExport", ["ctx","m",'"'+struct.name+'"'])
}
this.typings.addStruct(struct, options || {})
}
exportGlobalStruct(structName: string, exportName: string, values: string[]){
exportGlobalStruct(structName: string, exportName: string, values: string[], description: string){
this.moduleInit.declareStruct(structName,exportName+"_struct", values)
const classId = this.structLookup[structName]
if(!classId) throw new Error("Struct "+structName+" not found in register")
this.moduleInit.jsStructToOpq(structName, exportName+"_js", exportName+"_struct", classId)
this.moduleInit.call("JS_SetModuleExport", ["ctx","m",`"${exportName}"`, exportName+"_js"])
this.moduleEntry.call("JS_AddModuleExport", ["ctx","m",`"${exportName}"`])
this.typings.constants.tsDeclareConstant(exportName, structName, description)
}
exportGlobalConstant(name: string){
exportGlobalConstant(name: string, description: string){
this.moduleInit.statement(`JS_SetModuleExport(ctx, m, "${name}", JS_NewInt32(ctx, ${name}))`)
this.moduleEntry.statement(`JS_AddModuleExport(ctx, m, "${name}")`)
this.typings.constants.tsDeclareConstant(name, "number", description)
}
addApiStructByName(structName: string, options?: StructBindingOptions){

100
bindings/src/typescript.ts Normal file
View File

@ -0,0 +1,100 @@
import { ApiFunction, ApiStruct } from "./api";
import { GenericCodeGenerator, FunctionArgument, CodeWriter } from "./generation"
import { writeFileSync } from "fs";
import { StructBindingOptions } from "./raylib-header";
export class TypeScriptDeclaration {
root = new TypescriptGenerator()
structs: TypescriptGenerator;
functions: TypescriptGenerator;
constants: TypescriptGenerator;
constructor(){
this.structs = this.root.child()
this.functions = this.root.child()
this.constants = this.root.child()
}
addFunction(name: string, api: ApiFunction){
const para = api.params.map(x => ({ name: x.name, type: this.toJsType(x.type)}))
const returnType = this.toJsType(api.returnType)
this.functions.tsDeclareFunction(name, para, returnType, api.description)
}
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)
}
private toJsType(type: string){
switch(type){
case "int":
case "long":
case "unsigned int":
case "unsigned char":
case "float":
case "double":
return "number"
case "bool":
return "boolean"
case "const char *":
case "char *":
return "string"
default:
return type
}
}
public writeTo(filename: string){
const writer = new CodeWriter()
writer.writeGenerator(this.root)
writeFileSync(filename, writer.toString())
}
}
export abstract class GenericTypescriptGenerator<T extends TypescriptGenerator> extends GenericCodeGenerator<T> {
tsDeclareFunction(name: string, parameters: FunctionArgument[], returnType: string, description: string){
this.tsDocComment(description)
this.statement(`declare function ${name}(${parameters.map(x => x.name + ': '+x.type).join(', ')}): ${returnType}`)
}
tsDeclareConstant(name: string, type: string, description: string){
this.tsDocComment(description)
this.statement(`declare var ${name}: ${type}`)
}
tsDeclareType(name: string, hasConstructor: boolean, parameters: FunctionArgument[]){
this.line(`declare var ${name}: {`)
this.indent()
this.statement("prototype: "+name)
if(hasConstructor) this.statement(`new(${parameters.map(x => x.name+": "+x.type).join(', ')}): ${name}`)
this.unindent()
this.line("}")
}
tsDeclareInterface(name: string, fields: FunctionArgument[]){
this.line(`interface ${name} {`)
this.indent()
for (const field of fields) {
if(field.description) this.tsDocComment(field.description)
this.line(field.name + ": "+field.type+",")
}
this.unindent()
this.line("}")
}
tsDocComment(comment: string){
this.line(`/** ${comment} */`)
}
}
export class TypescriptGenerator extends GenericTypescriptGenerator<TypescriptGenerator> {
createGenerator(): TypescriptGenerator {
return new TypescriptGenerator()
}
}

View File

@ -1,14 +1,12 @@
import * as rlc from "raylib.core"
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
const MAX_BUILDINGS = 100
rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
initWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
const player = new rlc.Rectangle(400, 280, 40, 40);
const player = new Rectangle(400, 280, 40, 40);
const buildings = new Array(MAX_BUILDINGS);
const buildColors = new Array(MAX_BUILDINGS);
@ -16,52 +14,52 @@ let spacing = 0;
for (let i = 0; i < MAX_BUILDINGS; i++)
{
const height = rlc.getRandomValue(100, 800)
buildings[i] = new rlc.Rectangle(
const height = getRandomValue(100, 800)
buildings[i] = new Rectangle(
-6000.0 + spacing,
screenHeight - 130.0 - height,
rlc.getRandomValue(50, 200),
getRandomValue(50, 200),
height)
spacing += buildings[i].width;
buildColors[i] = new rlc.Color(rlc.getRandomValue(200, 240), rlc.getRandomValue(200, 240), rlc.getRandomValue(200, 250), 255);
buildColors[i] = new Color(getRandomValue(200, 240), getRandomValue(200, 240), getRandomValue(200, 250), 255);
}
const camera = new rlc.Camera2D(new rlc.Vector2(screenWidth/2.0, screenHeight/2.0),new rlc.Vector2(player.x + 20.0, player.y + 20.0), 0, 1)
const camera = new Camera2D(new Vector2(screenWidth/2.0, screenHeight/2.0),new Vector2(player.x + 20.0, player.y + 20.0), 0, 1)
rlc.setTargetFPS(60); // Set our game to run at 60 frames-per-second
setTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!rlc.windowShouldClose()) // Detect window close button or ESC key
while (!windowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Player movement
if (rlc.isKeyDown(rlc.KEY_RIGHT)) player.x += 2;
else if (rlc.isKeyDown(rlc.KEY_LEFT)) player.x -= 2;
if (isKeyDown(KEY_RIGHT)) player.x += 2;
else if (isKeyDown(KEY_LEFT)) player.x -= 2;
// Camera target follows player
const cameraTarget = new rlc.Vector2(player.x + 20, player.y + 20);
const cameraTarget = new Vector2(player.x + 20, player.y + 20);
camera.target = cameraTarget;
// Camera rotation controls
if (rlc.isKeyDown(rlc.KEY_A)) camera.rotation--;
else if (rlc.isKeyDown(rlc.KEY_S)) camera.rotation++;
if (isKeyDown(KEY_A)) camera.rotation--;
else if (isKeyDown(KEY_S)) camera.rotation++;
// Limit camera rotation to 80 degrees (-40 to 40)
if (camera.rotation > 40) camera.rotation = 40;
else if (camera.rotation < -40) camera.rotation = -40;
// Camera zoom controls
camera.zoom += (rlc.getMouseWheelMove()*0.05);
camera.zoom += (getMouseWheelMove()*0.05);
if (camera.zoom > 3.0) camera.zoom = 3.0;
else if (camera.zoom < 0.1) camera.zoom = 0.1;
// Camera reset (zoom and rotation)
if (rlc.isKeyPressed(rlc.KEY_R))
if (isKeyPressed(KEY_R))
{
camera.zoom = 1.0;
camera.rotation = 0.0;
@ -70,44 +68,44 @@ while (!rlc.windowShouldClose()) // Detect window close button or ESC key
// Draw
//----------------------------------------------------------------------------------
rlc.beginDrawing();
beginDrawing();
rlc.clearBackground(rlc.RAYWHITE);
clearBackground(RAYWHITE);
rlc.beginMode2D(camera);
beginMode2D(camera);
rlc.drawRectangle(-6000, 320, 13000, 8000, rlc.DARKGRAY);
drawRectangle(-6000, 320, 13000, 8000, DARKGRAY);
for (let i = 0; i < MAX_BUILDINGS; i++) rlc.drawRectangleRec(buildings[i], buildColors[i]);
for (let i = 0; i < MAX_BUILDINGS; i++) drawRectangleRec(buildings[i], buildColors[i]);
rlc.drawRectangleRec(player, rlc.RED);
drawRectangleRec(player, RED);
rlc.drawLine(cameraTarget.x, -screenHeight*10, cameraTarget.x, screenHeight*10, rlc.GREEN);
rlc.drawLine(-screenWidth*10, cameraTarget.y, screenWidth*10, cameraTarget.y, rlc.GREEN);
drawLine(cameraTarget.x, -screenHeight*10, cameraTarget.x, screenHeight*10, GREEN);
drawLine(-screenWidth*10, cameraTarget.y, screenWidth*10, cameraTarget.y, GREEN);
rlc.endMode2D();
endMode2D();
rlc.drawText("SCREEN AREA", 640, 10, 20, rlc.RED);
drawText("SCREEN AREA", 640, 10, 20, RED);
rlc.drawRectangle(0, 0, screenWidth, 5, rlc.RED);
rlc.drawRectangle(0, 5, 5, screenHeight - 10, rlc.RED);
rlc.drawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, rlc.RED);
rlc.drawRectangle(0, screenHeight - 5, screenWidth, 5, rlc.RED);
drawRectangle(0, 0, screenWidth, 5, RED);
drawRectangle(0, 5, 5, screenHeight - 10, RED);
drawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, RED);
drawRectangle(0, screenHeight - 5, screenWidth, 5, RED);
rlc.drawRectangle( 10, 10, 250, 113, rlc.fade(rlc.SKYBLUE, 0.5));
rlc.drawRectangleLines( 10, 10, 250, 113, rlc.BLUE);
drawRectangle( 10, 10, 250, 113, fade(SKYBLUE, 0.5));
drawRectangleLines( 10, 10, 250, 113, BLUE);
rlc.drawText("Free 2d camera controls:", 20, 20, 10, rlc.BLACK);
rlc.drawText("- Right/Left to move Offset", 40, 40, 10, rlc.DARKGRAY);
rlc.drawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, rlc.DARKGRAY);
rlc.drawText("- A / S to Rotate", 40, 80, 10, rlc.DARKGRAY);
rlc.drawText("- R to reset Zoom and Rotation", 40, 100, 10, rlc.DARKGRAY);
drawText("Free 2d camera controls:", 20, 20, 10, BLACK);
drawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY);
drawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
drawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
drawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);
rlc.endDrawing();
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlc.closeWindow(); // Close window and OpenGL context
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -0,0 +1,86 @@
import * as rl from "raylib"
for (const key in rl) {
globalThis[key] = rl[key]
}
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
initWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera mouse zoom");
const camera = new Camera2D(new Vector2(), new Vector2(), 0, 1);
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
//----------------------------------------------------------------------------------
// Translate based on mouse right click
if (isMouseButtonDown(MOUSE_BUTTON_RIGHT))
{
const delta = getMouseDelta();
delta = vector2Scale(delta, -1.0/camera.zoom);
camera.target = vector2Add(camera.target, delta);
}
// Zoom based on mouse wheel
let wheel = getMouseWheelMove();
if (wheel != 0)
{
// Get the world point that is under the mouse
const mouseWorldPos = getScreenToWorld2D(getMousePosition(), camera);
// Set the offset to where the mouse is
camera.offset = getMousePosition();
// Set the target to match, so that the camera maps the world space point
// under the cursor to the screen space point under the cursor at any zoom
camera.target = mouseWorldPos;
// Zoom increment
const zoomIncrement = 0.125;
camera.zoom += (wheel*zoomIncrement);
if (camera.zoom < zoomIncrement) camera.zoom = zoomIncrement;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
beginDrawing();
clearBackground(BLACK);
beginMode2D(camera);
// Draw the 3d grid, rotated 90 degrees and centered around 0,0
// just so we have something in the XY plane
rlPushMatrix();
rlTranslatef(0, 25*50, 0);
rlRotatef(90, 1, 0, 0);
drawGrid(100, 50);
rlPopMatrix();
// Draw a reference circle
drawCircle(100, 100, 50, YELLOW);
endMode2D();
drawText("Mouse right button drag to move, mouse wheel to zoom", 10, 10, 20, WHITE);
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -0,0 +1,53 @@
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
initWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera mode");
// Define the camera to look into our 3d world
const position = new Vector3(0,10,10);
const target = new Vector3(0,0,0);
const up = new Vector3(0,1,0);
const camera = new Camera3D(position,target,up, 45, CAMERA_PERSPECTIVE);
const cubePosition = new Vector3(0,0,0);
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
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
beginDrawing();
clearBackground(RAYWHITE);
beginMode3D(camera);
drawCube(cubePosition, 2.0, 2.0, 2.0, RED);
drawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON);
drawGrid(10, 1.0);
endMode3D();
drawText("Welcome to the third dimension!", 10, 40, 20, DARKGRAY);
drawFPS(10, 10);
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -1,18 +1,16 @@
import * as rlc from "raylib.core"
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
initWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
rlc.setTargetFPS(60); // Set our game to run at 60 frames-per-second
setTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!rlc.windowShouldClose()) // Detect window close button or ESC key
while (!windowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
@ -21,13 +19,13 @@ while (!rlc.windowShouldClose()) // Detect window close button or ESC key
// Draw
//----------------------------------------------------------------------------------
rlc.beginDrawing();
beginDrawing();
rlc.clearBackground(rlc.RAYWHITE);
clearBackground(RAYWHITE);
rlc.drawText("Congrats! You created your first window!", 190, 200, 20, rlc.LIGHTGRAY);
drawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
rlc.endDrawing();
endDrawing();
//----------------------------------------------------------------------------------
}

87
examples/bunnymark.js Normal file
View File

@ -0,0 +1,87 @@
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
const MAX_BUNNIES = 50000
const MAX_BATCH_ELEMENTS = 8192
initWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark");
// Load bunny texture
const texBunny = loadTexture("assets/wabbit_alpha.png");
const bunnies = new Array(MAX_BUNNIES)
let bunniesCount = 0; // Bunnies counter
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
//----------------------------------------------------------------------------------
if (isMouseButtonDown(MOUSE_BUTTON_LEFT))
{
// Create more bunnies
for (let i = 0; i < 100; i++)
{
if (bunniesCount < MAX_BUNNIES)
{
const bunny = {
position: getMousePosition(),
speed: new Vector2(getRandomValue(-250, 250)/60.0, getRandomValue(-250, 250)/60.0),
color: new Color(getRandomValue(50, 240), getRandomValue(80, 240), getRandomValue(100, 240), 255)
}
bunnies[bunniesCount] = bunny
bunniesCount++;
}
}
}
// Update bunnies
for (let i = 0; i < bunniesCount; i++)
{
bunnies[i].position.x += bunnies[i].speed.x;
bunnies[i].position.y += bunnies[i].speed.y;
if (((bunnies[i].position.x + texBunny.width/2) > getScreenWidth()) ||
((bunnies[i].position.x + texBunny.width/2) < 0)) bunnies[i].speed.x *= -1;
if (((bunnies[i].position.y + texBunny.height/2) > getScreenHeight()) ||
((bunnies[i].position.y + texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
beginDrawing();
clearBackground(RAYWHITE);
for (let i = 0; i < bunniesCount; i++)
{
// NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
// a draw call is launched and buffer starts being filled again;
// before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
// Process of sending data is costly and it could happen that GPU data has not been completely
// processed for drawing while new data is tried to be sent (updating current in-use buffers)
// it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies
drawTexture(texBunny, bunnies[i].position.x, bunnies[i].position.y, bunnies[i].color);
}
drawRectangle(0, 0, screenWidth, 40, BLACK);
drawText("bunnies: " + bunniesCount, 120, 10, 20, GREEN);
drawText("batched draw calls: " + (1 + bunniesCount/MAX_BATCH_ELEMENTS), 320, 10, 20, MAROON);
drawFPS(10, 10);
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

23
examples/common/timers.js Normal file
View File

@ -0,0 +1,23 @@
export class Timers {
_timeouts_ = {}
_timeout_ctr_ = 0
_time = 0
setTimeout(cb, ms){
var ctr = this._timeout_ctr_++
this._timeouts_[ctr] = [this._time+ms,cb]
return ctr
}
update(deltaTime){
this._time += (deltaTime*1000)
for (var key in this._timeouts_) {
var to = this._timeouts_[key]
if(to[0] <= this._time){
delete this._timeouts_[key]
to[1]()
}
}
}
}

View File

@ -1,43 +1,41 @@
import * as rlc from "raylib.core"
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - keyboard input");
initWindow(screenWidth, screenHeight, "raylib [core] example - keyboard input");
const ballPosition = new rlc.Vector2(screenWidth/2, screenHeight/2);
const ballPosition = new Vector2(screenWidth/2, screenHeight/2);
rlc.setTargetFPS(60); // Set our game to run at 60 frames-per-second
setTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!rlc.windowShouldClose()) // Detect window close button or ESC key
while (!windowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (rlc.isKeyDown(rlc.KEY_RIGHT)) ballPosition.x += 2;
if (rlc.isKeyDown(rlc.KEY_LEFT)) ballPosition.x -= 2;
if (rlc.isKeyDown(rlc.KEY_UP)) ballPosition.y -= 2;
if (rlc.isKeyDown(rlc.KEY_DOWN)) ballPosition.y += 2;
if (isKeyDown(KEY_RIGHT)) ballPosition.x += 2;
if (isKeyDown(KEY_LEFT)) ballPosition.x -= 2;
if (isKeyDown(KEY_UP)) ballPosition.y -= 2;
if (isKeyDown(KEY_DOWN)) ballPosition.y += 2;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rlc.beginDrawing();
beginDrawing();
rlc.clearBackground(rlc.RAYWHITE);
clearBackground(RAYWHITE);
rlc.drawText("move the ball with arrow keys", 10, 10, 20, rlc.DARKGRAY);
drawText("move the ball with arrow keys", 10, 10, 20, DARKGRAY);
rlc.drawCircleV(ballPosition, 50, rlc.MAROON);
drawCircleV(ballPosition, 50, MAROON);
rlc.endDrawing();
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlc.closeWindow(); // Close window and OpenGL context
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -1,49 +1,47 @@
import * as rlc from "raylib.core"
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - mouse input");
initWindow(screenWidth, screenHeight, "raylib [core] example - mouse input");
let ballPosition = new rlc.Vector2(-100.0, -100.0);
let ballColor = rlc.DARKBLUE;
let ballPosition = new Vector2(-100.0, -100.0);
let ballColor = DARKBLUE;
rlc.setTargetFPS(60); // Set our game to run at 60 frames-per-second
setTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
// Main game loop
while (!rlc.windowShouldClose()) // Detect window close button or ESC key
while (!windowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
ballPosition = rlc.getMousePosition();
ballPosition = getMousePosition();
if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_LEFT)) ballColor = rlc.MAROON;
else if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_MIDDLE)) ballColor = rlc.LIME;
else if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_RIGHT)) ballColor = rlc.DARKBLUE;
else if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_SIDE)) ballColor = rlc.PURPLE;
else if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_EXTRA)) ballColor = rlc.YELLOW;
else if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_FORWARD)) ballColor = rlc.ORANGE;
else if (rlc.isMouseButtonPressed(rlc.MOUSE_BUTTON_BACK)) ballColor = rlc.BEIGE;
if (isMouseButtonPressed(MOUSE_BUTTON_LEFT)) ballColor = MAROON;
else if (isMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) ballColor = LIME;
else if (isMouseButtonPressed(MOUSE_BUTTON_RIGHT)) ballColor = DARKBLUE;
else if (isMouseButtonPressed(MOUSE_BUTTON_SIDE)) ballColor = PURPLE;
else if (isMouseButtonPressed(MOUSE_BUTTON_EXTRA)) ballColor = YELLOW;
else if (isMouseButtonPressed(MOUSE_BUTTON_FORWARD)) ballColor = ORANGE;
else if (isMouseButtonPressed(MOUSE_BUTTON_BACK)) ballColor = BEIGE;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rlc.beginDrawing();
beginDrawing();
rlc.clearBackground(rlc.RAYWHITE);
clearBackground(RAYWHITE);
rlc.drawCircleV(ballPosition, 40, ballColor);
drawCircleV(ballPosition, 40, ballColor);
rlc.drawText("move ball with mouse and click mouse button to change color", 10, 10, 20, rlc.DARKGRAY);
drawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
rlc.endDrawing();
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlc.closeWindow(); // Close window and OpenGL context
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -1,42 +1,40 @@
import * as rlc from "raylib.core"
// Initialization
//--------------------------------------------------------------------------------------
const screenWidth = 800;
const screenHeight = 450;
rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel");
initWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel");
let boxPositionY = screenHeight/2 - 40;
let scrollSpeed = 4; // Scrolling speed in pixels
rlc.setTargetFPS(60); // Set our game to run at 60 frames-per-second
setTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!rlc.windowShouldClose()) // Detect window close button or ESC key
while (!windowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
boxPositionY -= (rlc.getMouseWheelMove()*scrollSpeed);
boxPositionY -= (getMouseWheelMove()*scrollSpeed);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rlc.beginDrawing();
beginDrawing();
rlc.clearBackground(rlc.RAYWHITE);
clearBackground(RAYWHITE);
rlc.drawRectangle(screenWidth/2 - 40, boxPositionY, 80, 80, rlc.MAROON);
drawRectangle(screenWidth/2 - 40, boxPositionY, 80, 80, MAROON);
rlc.drawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, rlc.GRAY);
rlc.drawText("Box position Y: " + boxPositionY, 10, 40, 20, rlc.LIGHTGRAY);
drawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, GRAY);
drawText("Box position Y: " + boxPositionY, 10, 40, 20, LIGHTGRAY);
rlc.endDrawing();
endDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlc.closeWindow(); // Close window and OpenGL context
closeWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

20
examples/js_example.js Normal file
View File

@ -0,0 +1,20 @@
import { Timers } from "./examples/common/timers.js"
const timers = new Timers()
initWindow(640, 480, "Javascript Tests")
const pos = new Vector2(getScreenWidth()/2,getScreenHeight()/2)
const radius = 100
timers.setTimeout(() => pos.x += 200, 2000)
while(!windowShouldClose()){
timers.update(getFrameTime())
beginDrawing()
clearBackground(RAYWHITE)
drawCircle(pos.x,pos.y, radius, LIME)
endDrawing()
}
closeWindow()

1251
examples/lib.raylib.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

8
examples/tsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"allowJs": true,
"target": "es2020",
"lib": ["ES2020"]
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +0,0 @@
#ifndef JS_raylib_texture_GUARD
#define JS_raylib_texture_GUARD
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <quickjs.h>
#include <raylib.h>
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
static JSClassID js_Image_class_id;
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;
}
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;
}
static const JSCFunctionListEntry js_Image_proto_funcs[] = {
JS_CGETSET_DEF("width",js_Image_get_width,NULL),
JS_CGETSET_DEF("height",js_Image_get_height,NULL),
JS_PROP_STRING_DEF("[Symbol.toStringTag]","Image", JS_PROP_CONFIGURABLE),
};
static int js_declare_Image(JSContext * ctx, JSModuleDef * m) {
JS_NewClassID(&js_Image_class_id);
JSClassDef js_Image_def = { .class_name = "Image", .finalizer = js_Image_finalizer };
JS_NewClass(JS_GetRuntime(ctx), js_Image_class_id, &js_Image_def);
JSValue proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, proto, js_Image_proto_funcs, countof(js_Image_proto_funcs));
JS_SetClassProto(ctx, js_Image_class_id, proto);
return 0;
}
static JSValue js_loadImage(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) {
const char * fileName = (const char *)JS_ToCString(ctx, argv[0]);
if(fileName == NULL) return JS_EXCEPTION;
Image returnVal = LoadImage(fileName);
JS_FreeCString(ctx, fileName);
Image* ret_ptr = (Image*)js_malloc(ctx, sizeof(Image));
*ret_ptr = returnVal;
JSValue ret = JS_NewObjectClass(ctx, js_Image_class_id);
JS_SetOpaque(ret, ret_ptr);
return ret;
}
static const JSCFunctionListEntry js_raylib_texture_funcs[] = {
JS_CFUNC_DEF("loadImage",1,js_loadImage),
};
static int js_raylib_texture_init(JSContext * ctx, JSModuleDef * m) {
JS_SetModuleExportList(ctx, m,js_raylib_texture_funcs,countof(js_raylib_texture_funcs));
js_declare_Image(ctx, m);
return 0;
}
JSModuleDef * js_init_module_raylib_texture(JSContext * ctx, const char * module_name) {
JSModuleDef *m;
m = JS_NewCModule(ctx, module_name, js_raylib_texture_init);
if(!m) return NULL;
JS_AddModuleExportList(ctx, m, js_raylib_texture_funcs, countof(js_raylib_texture_funcs));
return m;
}
#endif // JS_raylib_texture_GUARD

View File

@ -30,7 +30,6 @@ int app_update_quickjs(){
}
#include "bindings/js_raylib_core.h"
#include "bindings/js_raylib_texture.h"
int app_init_quickjs(int argc, char** argv){
rt = JS_NewRuntime();
@ -51,11 +50,14 @@ int app_init_quickjs(int argc, char** argv){
js_std_add_helpers(ctx, argc, argv);
const char *str = "import * as rl from 'raylib'\n"
"for (const key in rl) { globalThis[key] = rl[key] }\n";
// const char *str = "import * as std from 'std';\n"
// "import * as os from 'os';\n"
// "globalThis.std = std;\n"
// "globalThis.os = os;\n";
// eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
const char* filename = argc > 1 ? argv[1] : "main.js";
const char* buf = LoadFileText(filename);
@ -92,8 +94,7 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
/* system modules */
js_init_module_std(ctx, "std");
//js_init_module_os(ctx, "os");
js_init_module_raylib_core(ctx, "raylib.core");
js_init_module_raylib_texture(ctx, "raylib.texture");
js_init_module_raylib_core(ctx, "raylib");
return ctx;
}