diff --git a/manual/config_guide.md b/manual/config_guide.md index 84d2eae..a7b9779 100644 --- a/manual/config_guide.md +++ b/manual/config_guide.md @@ -103,6 +103,18 @@ DrawLineStrip/points DrawTriangleFan/points ``` +#### HiddenRefParameters + +Hides pointer semantics by using the `.byref` pragma. + +```ini +[HiddenRefParameters] +GetCameraForward/camera +GetCameraUp/camera +GetCameraRight/camera +GetCameraViewMatrix/camera +``` + #### TypeReplacements Allows manual type conversion in cases where C types don’t map well to Nim types: diff --git a/src/raylib.nim b/src/raylib.nim index ef7cbff..919dbe8 100644 --- a/src/raylib.nim +++ b/src/raylib.nim @@ -2739,9 +2739,7 @@ proc loadFontFromMemory*(fileType: string; fileData: openArray[uint8]; fontSize: proc loadFontFromData*(chars: sink RArray[GlyphInfo]; baseSize, padding: int32, packMethod: int32): Font = ## Load font using chars info - result.baseSize = baseSize - result.glyphCount = chars.len.int32 - result.glyphs = chars.data + result = Font(baseSize: baseSize, glyphCount: chars.len.int32, glyphs: chars.data) wasMoved(chars) let atlas = genImageFontAtlasImpl(result.glyphs, addr result.recs, result.glyphCount, baseSize, padding, packMethod) diff --git a/src/rcamera.nim b/src/rcamera.nim index 24f4b8a..88f4a73 100644 --- a/src/rcamera.nim +++ b/src/rcamera.nim @@ -1,10 +1,4 @@ from raylib import CameraMode, CameraProjection, Vector2, Vector3, Matrix, Camera3D, Camera -from std/math import degToRad -import raymath - -# ----------------------------------------------------------------------------------------- -# Defines and Macros -# ----------------------------------------------------------------------------------------- const CameraMoveSpeed* = 5.4'f32 # Units per second @@ -20,170 +14,18 @@ const CameraCullDistanceNear* = 0.01 CameraCullDistanceFar* = 1000.0 -# ----------------------------------------------------------------------------------------- -# Module Functions Definition -# ----------------------------------------------------------------------------------------- - -func getCameraForward*(camera: Camera): Vector3 = - ## Returns the camera's forward vector (normalized) - normalize(camera.target - camera.position) - -func getCameraUp*(camera: Camera): Vector3 = - ## Returns the camera's up vector (normalized) - ## Note: The up vector might not be perpendicular to the forward vector - normalize(camera.up) - -func getCameraRight*(camera: Camera): Vector3 = - ## Returns the camera's right vector (normalized) - let forward = getCameraForward(camera) - let up = getCameraUp(camera) - normalize(crossProduct(forward, up)) - -func moveForward*(camera: var Camera, distance: float32, moveInWorldPlane: bool) = - ## Moves the camera in its forward direction - var forward = getCameraForward(camera) - - if moveInWorldPlane: - # Project vector onto world plane - forward.y = 0 - forward = normalize(forward) - - # Scale by distance - forward *= distance - - # Move position and target - camera.position += forward - camera.target += forward - -func moveUp*(camera: var Camera, distance: float32) = - ## Moves the camera in its up direction - var up = getCameraUp(camera) - - # Scale by distance - up *= distance - - # Move position and target - camera.position += up - camera.target += up - -func moveRight*(camera: var Camera, distance: float32, moveInWorldPlane: bool) = - ## Moves the camera target in its current right direction - var right = getCameraRight(camera) - - if moveInWorldPlane: - # Project vector onto world plane - right.y = 0 - right = normalize(right) - - # Scale by distance - right *= distance - - # Move position and target - camera.position += right - camera.target += right - -func moveToTarget*(camera: var Camera, delta: float32) = - ## Moves the camera position closer/farther to/from the camera target - var distance = distance(camera.position, camera.target) - - # Apply delta - distance += delta - - # Distance must be greater than 0 - if distance <= 0: distance = 0.001'f32 - - # Set new distance by moving the position along the forward vector - let forward = getCameraForward(camera) - camera.position = camera.target + (forward * -distance) - -func yaw*(camera: var Camera, angle: float32, rotateAroundTarget: bool) = - ## Rotates the camera around its up vector - ## Yaw is "looking left and right" - ## If rotateAroundTarget is false, the camera rotates around its position - ## Note: angle must be provided in radians - # Rotation axis - let up = getCameraUp(camera) - - # View vector - var targetPosition = camera.target - camera.position - - # Rotate view vector around up axis - targetPosition = rotateByAxisAngle(targetPosition, up, angle) - - if rotateAroundTarget: - # Move position relative to target - camera.position = camera.target - targetPosition - else: - # Move target relative to position - camera.target = camera.position + targetPosition - -func pitch*(camera: var Camera, angle: float32, lockView, rotateAroundTarget, rotateUp: bool) = - ## Rotates the camera around its right vector, pitch is "looking up and down" - ## - lockView prevents camera overrotation (aka "somersaults") - ## - rotateAroundTarget defines if rotation is around target or around its position - ## - rotateUp rotates the up direction as well (typically only useful in CAMERA_FREE) - ## NOTE: angle must be provided in radians - # Up direction - var angle = angle - let up = getCameraUp(camera) - - # View vector - var targetPosition = camera.target - camera.position - - if lockView: - # In these camera modes we clamp the Pitch angle - # to allow only viewing straight up or down. - - # Clamp view up - var maxAngleUp = angle(up, targetPosition) - maxAngleUp -= 0.001'f32 # avoid numerical errors - if angle > maxAngleUp: angle = maxAngleUp - - # Clamp view down - var maxAngleDown = angle(-up, targetPosition) - maxAngleDown *= -1.0'f32 # downwards angle is negative - maxAngleDown += 0.001'f32 # avoid numerical errors - if angle < maxAngleDown: angle = maxAngleDown - - # Rotation axis - let right = getCameraRight(camera) - - # Rotate view vector around right axis - targetPosition = rotateByAxisAngle(targetPosition, right, angle) - - if rotateAroundTarget: - # Move position relative to target - camera.position = camera.target - targetPosition - else: - # Move target relative to position - camera.target = camera.position + targetPosition - - if rotateUp: - # Rotate up direction around right axis - camera.up = rotateByAxisAngle(camera.up, right, angle) - -func roll*(camera: var Camera, angle: float32) = - ## Rotates the camera around its forward vector - ## Roll is "turning your head sideways to the left or right" - ## Note: angle must be provided in radians - # Rotation axis - let forward = getCameraForward(camera) - - # Rotate up direction around forward axis - camera.up = rotateByAxisAngle(camera.up, forward, angle) - -func getCameraViewMatrix*(camera: Camera): Matrix = - ## Returns the camera view matrix - lookAt(camera.position, camera.target, camera.up) +{.push callconv: cdecl, header: "rcamera.h".} +func getCameraForward*(camera {.byref.}: Camera): Vector3 {.importc: "GetCameraForward".} +func getCameraUp*(camera {.byref.}: Camera): Vector3 {.importc: "GetCameraUp".} +func getCameraRight*(camera {.byref.}: Camera): Vector3 {.importc: "GetCameraRight".} +func moveForward*(camera: var Camera, distance: float32, moveInWorldPlane: bool) {.importc: "CameraMoveForward".} +func moveUp*(camera: var Camera, distance: float32) {.importc: "CameraMoveUp".} +func moveRight*(camera: var Camera, distance: float32, moveInWorldPlane: bool) {.importc: "CameraMoveRight".} +func moveToTarget*(camera: var Camera, delta: float32) {.importc: "CameraMoveToTarget".} +func yaw*(camera: var Camera, angle: float32, rotateAroundTarget: bool) {.importc: "CameraYaw".} +func pitch*(camera: var Camera, angle: float32, lockView: bool, rotateAroundTarget: bool, rotateUp: bool) {.importc: "CameraPitch".} +func roll*(camera: var Camera, angle: float32) {.importc: "CameraRoll".} +func getCameraViewMatrix*(camera {.byref.}: Camera): Matrix {.importc: "GetCameraViewMatrix".} +func getCameraProjectionMatrix*(camera {.byref.}: Camera, aspect: float32): Matrix {.importc: "GetCameraProjectionMatrix".} +{.pop.} -func getCameraProjectionMatrix*(camera: Camera, aspect: float32): Matrix = - # Returns the camera projection matrix - case camera.projection - of Perspective: - perspective(degToRad(camera.fovy), aspect, CameraCullDistanceNear, CameraCullDistanceFar) - of Orthographic: - let top = camera.fovy / 2.0 - let right = top * aspect - ortho(-right, right, -top, top, CameraCullDistanceNear, CameraCullDistanceFar) - else: - identity(Matrix) diff --git a/tests/basic_window.nim b/tests/basic_window.nim index e6c0b0e..3ff2a2b 100644 --- a/tests/basic_window.nim +++ b/tests/basic_window.nim @@ -22,7 +22,7 @@ # # **************************************************************************************** -import raylib, rlgl, raymath, rmem, reasings +import raylib, rlgl, raymath, rmem, reasings, rcamera # ---------------------------------------------------------------------------------------- # Global Variables Definition diff --git a/tests/basic_window_web.nim b/tests/basic_window_web.nim index 5bc45c7..43337e7 100644 --- a/tests/basic_window_web.nim +++ b/tests/basic_window_web.nim @@ -20,7 +20,7 @@ # # **************************************************************************************** -import raylib, rlgl, raymath, rmem, reasings +import raylib, rlgl, raymath, rmem, reasings, rcamera # ---------------------------------------------------------------------------------------- # Global Variables Definition diff --git a/tools/wrapper/api/raylib.json b/tools/wrapper/api/raylib.json index 0921ed4..8561bc3 100644 --- a/tools/wrapper/api/raylib.json +++ b/tools/wrapper/api/raylib.json @@ -15,7 +15,7 @@ { "name": "RAYLIB_VERSION_MINOR", "type": "INT", - "value": 5, + "value": 6, "description": "" }, { @@ -27,7 +27,7 @@ { "name": "RAYLIB_VERSION", "type": "STRING", - "value": "5.5", + "value": "5.6-dev", "description": "" }, { diff --git a/tools/wrapper/builder.nim b/tools/wrapper/builder.nim index 9299205..02d0f8d 100644 --- a/tools/wrapper/builder.nim +++ b/tools/wrapper/builder.nim @@ -139,6 +139,8 @@ proc generateProc*(b: var Builder, fnc: FunctionInfo) = if i > 0: b.addRaw ", " b.addIdent param.name + if isPrivate notin fnc.flags and isHiddenRefParam in param.flags: + b.addRaw " {.byref.}" b.addRaw ": " b.addRaw param.`type` b.addRaw ")" @@ -165,10 +167,12 @@ proc generateWrappedProc*(b: var Builder, fnc: FunctionInfo) = if i > 0: b.addRaw ", " b.addIdent param.name + if isHiddenRefParam in param.flags: + b.addRaw " {.byref.}" b.addRaw ": " if isString in param.flags: b.addRaw "string" - elif {isOpenArray, isVarParam} * param.flags != {}: + elif {isOpenArray, isVarParam, isHiddenRefParam} * param.flags != {}: b.addRaw param.dirty # stores native nim type else: b.addRaw param.`type` diff --git a/tools/wrapper/config.nim b/tools/wrapper/config.nim index e1aff77..f368e34 100644 --- a/tools/wrapper/config.nim +++ b/tools/wrapper/config.nim @@ -15,6 +15,7 @@ type privateSymbols*: HashSet[SymbolPair] ignoredSymbols*: HashSet[SymbolPair] openArrayParameters*: HashSet[SymbolPair] + hiddenRefParameters*: HashSet[SymbolPair] discardReturn*: HashSet[string] boolReturn*: HashSet[string] wrappedFuncs*: HashSet[string] @@ -62,6 +63,8 @@ proc processKeyWithoutValue(config: var ConfigData; section: string, key: string config.ignoredSymbols.incl(sp) of "OpenArrayParameters": config.openArrayParameters.incl(sp) + of "HiddenRefParameters": + config.hiddenRefParameters.incl(sp) of "DiscardReturn": config.discardReturn.incl(key) of "BoolReturn": diff --git a/tools/wrapper/config/rcamera.cfg b/tools/wrapper/config/rcamera.cfg index b2017c8..5423e78 100644 --- a/tools/wrapper/config/rcamera.cfg +++ b/tools/wrapper/config/rcamera.cfg @@ -5,9 +5,7 @@ cHeader = rcamera.h [ Snippets ] -moduleHeader = """ -from raylib import CameraMode, CameraProjection, Vector2, Vector3, Matrix, Camera3D, Camera -""" +moduleHeader = snippets/rcamera_header.nim [ IgnoredSymbols ] @@ -23,6 +21,14 @@ Camera Camera +[ HiddenRefParameters ] + +GetCameraForward/camera +GetCameraUp/camera +GetCameraRight/camera +GetCameraViewMatrix/camera +GetCameraProjectionMatrix/camera + [ NoSideEffectsFuncs ] GetCameraForward diff --git a/tools/wrapper/ctypes.nim b/tools/wrapper/ctypes.nim index 262318e..33e13bf 100644 --- a/tools/wrapper/ctypes.nim +++ b/tools/wrapper/ctypes.nim @@ -65,6 +65,7 @@ type ptOut ptArray ptOpenArray + ptHidden proc convertPointerType(s: sink string, pointerType: PointerType): string = result = s @@ -72,9 +73,9 @@ proc convertPointerType(s: sink string, pointerType: PointerType): string = let pointerDepth = result.count('*') result = result.replace(" *", "") result = result.replace("*", "") - for i in 1..pointerDepth - ord(pointerType in {ptVar, ptOut, ptOpenArray}): + for i in 1..pointerDepth - ord(pointerType in {ptVar, ptOut, ptOpenArray, ptHidden}): case pointerType: - of ptPtr, ptVar, ptOut, ptOpenArray: + of ptPtr, ptVar, ptOut, ptOpenArray, ptHidden: result = "ptr " & result of ptArray: result = "ptr UncheckedArray[" & result & "]" @@ -119,6 +120,7 @@ proc convertType*(s: string; prefix = ""; pointerType = ptPtr): string = when isMainModule: import std/assertions + assert convertType("Camera *", pointerType = ptHidden) == "Camera" assert convertType("rlDrawCall", "rl") == "DrawCall" assert convertType("BorderlessWindowed", prefix = "rl") == "BorderlessWindowed" assert convertType("int[RL_MAX_GAMEPADS]", "RL_") == "array[MaxGamepads, int32]" diff --git a/tools/wrapper/processor.nim b/tools/wrapper/processor.nim index b4abd0d..459e230 100644 --- a/tools/wrapper/processor.nim +++ b/tools/wrapper/processor.nim @@ -76,6 +76,9 @@ proc checkCstringType(fnc: FunctionInfo, kind: string, config: ConfigData): bool proc isOpenArrayParameter(x, y: string, config: ConfigData): bool = (x, y) in config.openArrayParameters +proc isHiddenRefParameter(x, y: string, config: ConfigData): bool = + (x, y) in config.hiddenRefParameters + proc isVarargsParam(param: ParamInfo): bool = param.name == "args" and param.`type` == "..." @@ -194,8 +197,11 @@ proc processParameters(fnc: var FunctionInfo, config: ConfigData) = for i, param in enumerate(fnc.params.mitems): if isArray(fnc.name, param.name, config): param.flags.incl isPtArray + if isHiddenRefParameter(fnc.name, param.name, config): + param.flags.incl isHiddenRefParam let pointerType = if isPtArray in param.flags: ptArray + elif isHiddenRefParam in param.flags: ptHidden elif isOutParameter(fnc.name, param.name, config): ptOut elif isPrivate notin fnc.flags: ptVar else: ptPtr @@ -213,6 +219,8 @@ proc processParameters(fnc: var FunctionInfo, config: ConfigData) = if paramType.startsWith("var "): param.flags.incl isVarParam param.dirty = paramType + if isHiddenRefParam in param.flags: + param.dirty = paramType proc processReturnType(fnc: var FunctionInfo, config: ConfigData) = if fnc.returnType != "void": @@ -234,6 +242,7 @@ proc updateParameterTypes(fnc: var FunctionInfo, config: ConfigData) = let pointerType = if isPtArray in param.flags: ptArray elif isOutParameter(fnc.name, param.name, config): ptOut + elif isHiddenRefParam in param.flags: (if isPrivate in fnc.flags: ptPtr else: ptHidden) elif isPrivate notin fnc.flags: ptVar else: ptPtr updateType(param.`type`, fnc.name, param.name, pointerType, config) diff --git a/tools/wrapper/schema.nim b/tools/wrapper/schema.nim index 79a9934..7640d95 100644 --- a/tools/wrapper/schema.nim +++ b/tools/wrapper/schema.nim @@ -10,7 +10,7 @@ type InfoFlags* = enum isPrivate, isWrappedFunc, isAutoWrappedFunc, hasVarargs, isOpenArray, isPtArray, isVarParam, isDistinct, isCompleteStruct, isString, isFunc, isArrayLen, isNilIfEmpty, - isDiscardable, isBoolReturn + isDiscardable, isBoolReturn, isHiddenRefParam TopLevel* = object defines*: seq[DefineInfo] diff --git a/tools/wrapper/snippets/raylib_funcs.nim b/tools/wrapper/snippets/raylib_funcs.nim index 31e3579..c57fb47 100644 --- a/tools/wrapper/snippets/raylib_funcs.nim +++ b/tools/wrapper/snippets/raylib_funcs.nim @@ -285,9 +285,7 @@ proc loadFontFromMemory*(fileType: string; fileData: openArray[uint8]; fontSize: proc loadFontFromData*(chars: sink RArray[GlyphInfo]; baseSize, padding: int32, packMethod: int32): Font = ## Load font using chars info - result.baseSize = baseSize - result.glyphCount = chars.len.int32 - result.glyphs = chars.data + result = Font(baseSize: baseSize, glyphCount: chars.len.int32, glyphs: chars.data) wasMoved(chars) let atlas = genImageFontAtlasImpl(result.glyphs, addr result.recs, result.glyphCount, baseSize, padding, packMethod) diff --git a/update_bindings.nims b/update_bindings.nims index c934483..e84e485 100644 --- a/update_bindings.nims +++ b/update_bindings.nims @@ -72,13 +72,13 @@ task buildTools, "Build raylib_parser and naylib_wrapper": task genApi, "Generate API JSON files": buildParser() genApiJson("raylib", "RLAPI", "") - # genApiJson("rcamera", "RLAPI", "#endif // RCAMERA_H") + genApiJson("rcamera", "RLAPI", "#endif // RCAMERA_H") genApiJson("raymath", "RMAPI", "") genApiJson("rlgl", "", "#endif // RLGL_H") task genWrappers, "Generate Nim wrappers": genWrapper("raylib") - # genWrapper("rcamera") + genWrapper("rcamera") genWrapper("raymath") genWrapper("rlgl") @@ -96,7 +96,7 @@ task mangle, "Mangle identifiers in raylib source": task wrap, "Produce all raylib Nim wrappers": buildToolsTask() wrapRaylib("raylib", "RLAPI", "") - # wrapRaylib("rcamera", "RLAPI", "#endif // RCAMERA_H") + wrapRaylib("rcamera", "RLAPI", "#endif // RCAMERA_H") wrapRaylib("raymath", "RMAPI", "") wrapRaylib("rlgl", "", "#endif // RLGL_H")