Watch
2
0
Fork
You've already forked raylib-cs
0

Added severial examples. Corrected towards the correct return type and add utilities to prevent working with pointers

This commit is contained in:
Meatcorps 2026-05-21 06:08:27 +02:00
commit 6c94ffb0cc
21 changed files with 1252 additions and 205 deletions

View file

@ -1,21 +1,28 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Basic window * raylib [core] example - basic window
*
* Example complexity rating: [] 1/4
* *
* Welcome to raylib! * Welcome to raylib!
* *
* To test examples, just press F6 and execute raylib_compile_execute script * To test examples, just press F6 and execute 'raylib_compile_execute' script
* Note that compiled executable is placed in the same folder as .c file * Note that compiled executable is placed in the same folder as .c file
* *
* To test the examples on Web, press F6 and execute 'raylib_compile_execute_web' script
* Web version of the program is generated in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or * You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com * raylib official webpage: www.raylib.com
* *
* Enjoy using raylib. :) * Enjoy using raylib. :)
* *
* This example has been created using raylib 1.0 (www.raylib.com) * Example originally created with raylib 1.0, last time updated with raylib 1.0
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -53,7 +60,7 @@ public class BasicWindow
BeginDrawing(); BeginDrawing();
ClearBackground(Color.RayWhite); ClearBackground(Color.RayWhite);
DrawText("Congrats! You created your first window!", 190, 200, 20, Color.Maroon); DrawText("Congrats! You created your first window!", 190, 200, 20, Color.LightGray);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View file

@ -2,10 +2,14 @@
* *
* raylib [core] example - 2d camera * raylib [core] example - 2d camera
* *
* This example has been created using raylib 1.5 (www.raylib.com) * Example complexity rating: [] 2/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2016 Ramon Santamaria (@raysan5) * Example originally created with raylib 1.5, last time updated with raylib 3.0
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View file

@ -50,7 +50,7 @@ public unsafe class CustomLogging
// First thing we do is setting our custom logger to ensure everything raylib logs // First thing we do is setting our custom logger to ensure everything raylib logs
// will use our own logger instead of its internal one // will use our own logger instead of its internal one
Raylib.SetTraceLogCallback(&LogCustom); SetTraceLogCallback(&LogCustom);
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging"); InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");
@ -79,7 +79,7 @@ public unsafe class CustomLogging
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
CloseWindow(); CloseWindow();
Raylib.SetTraceLogCallback(&Logging.LogConsole); SetTraceLogCallback(&Logging.LogConsole);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;

129
Examples/Core/DeltaTime.cs Normal file
View file

@ -0,0 +1,129 @@
using System.Numerics;
namespace Examples.Core;
/*******************************************************************************************
*
* raylib [core] example - delta time
*
* Example complexity rating: [] 1/4
*
* Example originally created with raylib 5.5, last time updated with raylib 6.0
*
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025 Robin (@RobinsAviary)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
public class DeltaTime
{
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - delta time");
int currentFps = 60;
Vector2 deltaCircle = new Vector2(0, (float)screenHeight / 3.0f);
Vector2 frameCircle = new Vector2(0, (float)screenHeight * (2.0f / 3.0f));
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
const float speed = 10.0f;
const float circleRadius = 32.0f;
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
// Adjust the FPS target based on the mouse wheel
float mouseWheel = GetMouseWheelMove();
if (mouseWheel != 0)
{
currentFps += (int)mouseWheel;
if (currentFps < 0)
{
currentFps = 0;
}
SetTargetFPS(currentFps);
}
// GetFrameTime() returns the time it took to draw the last frame, in seconds (usually called delta time)
// Uses the delta time to make the circle look like it's moving at a "consistent" speed regardless of FPS
// Multiply by 6.0 (an arbitrary value) in order to make the speed
// visually closer to the other circle (at 60 fps), for comparison
deltaCircle.X += GetFrameTime() * 6.0f * speed;
// This circle can move faster or slower visually depending on the FPS
frameCircle.X += 0.1f * speed;
// If either circle is off the screen, reset it back to the start
if (deltaCircle.X > screenWidth)
{
deltaCircle.X = 0;
}
if (frameCircle.X > screenWidth)
{
frameCircle.X = 0;
}
// Reset both circles positions
if (IsKeyPressed(KeyboardKey.R))
{
deltaCircle.X = 0;
frameCircle.X = 0;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw both circles to the screen
DrawCircleV(deltaCircle, circleRadius, Color.Red);
DrawCircleV(frameCircle, circleRadius, Color.Blue);
// Draw the help text
// Determine what help text to show depending on the current FPS target
var fpsText = "";
if (currentFps <= 0)
{
fpsText = $"FPS: unlimited ({GetFPS()})";
}
else
{
fpsText = $"FPS: {GetFPS()} (target: {currentFps})";
}
DrawText(fpsText, 10, 10, 20, Color.DarkGray);
DrawText($"Frame time: {GetFrameTime():F2} ms", 10, 30, 20, Color.DarkGray);
DrawText("Use the scroll wheel to change the fps limit, r to reset", 10, 50, 20, Color.DarkGray);
// Draw the text above the circles
DrawText("FUNC: x += GetFrameTime()*speed", 10, 90, 20, Color.Red);
DrawText("FUNC: x += speed", 10, 240, 20, Color.Blue);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow();
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,19 +1,24 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Gamepad input * raylib [core] example - input gamepad
* *
* NOTE: This example requires a Gamepad connected to the system * Example complexity rating: [] 1/4
* raylib is configured to work with the following gamepads: *
* - Xbox 360 Controller (Xbox 360, Xbox One) * NOTE: This example requires a Gamepad connected to the system
* - PLAYSTATION(R)3 Controller * raylib is configured to work with the following gamepads:
* Check raylib.h for buttons configuration * - Xbox 360 Controller (Xbox 360, Xbox One)
* * - PLAYSTATION(R)3 Controller
* This example has been created using raylib 1.6 (www.raylib.com) * Check raylib.h for buttons configuration
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) *
* * Example originally created with raylib 1.1, last time updated with raylib 4.2
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) *
* * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
********************************************************************************************/ * BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics; using System.Numerics;
using Raylib_cs; using Raylib_cs;
@ -25,10 +30,10 @@ public class InputGamepad
{ {
// NOTE: Gamepad name ID depends on drivers and OS // NOTE: Gamepad name ID depends on drivers and OS
// These are some possible names the gamepads could have. // These are some possible names the gamepads could have.
public const string XBOX360_LEGACY_NAME_ID = "Xbox Controller"; public const string XBOX_ALIAS_1 = "xbox";
public const string XBOX360_NAME_ID = "Xbox 360 Controller"; public const string XBOX_ALIAS_2 = "x-box";
public const string XBOX360_NAME_ID_RPI = "Microsoft X-Box 360 pad"; public const string PS_ALIAS_1 = "playstation";
public const string PS3_NAME_ID = "PLAYSTATION(R)3 Controller"; public const string PS_ALIAS_2 = "sony";
public static int Main() public static int Main()
{ {
@ -47,12 +52,32 @@ public class InputGamepad
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
int gamepad = 0;
Rectangle vibrateButton = new Rectangle();
// Main game loop // Main game loop
while (!WindowShouldClose()) while (!WindowShouldClose())
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// ... if (IsKeyPressed(KeyboardKey.Left) && gamepad > 0)
{
gamepad--;
}
if (IsKeyPressed(KeyboardKey.Right))
{
gamepad++;
}
Vector2 mousePosition = GetMousePosition();
vibrateButton = new Rectangle(10, 70.0f + 20 * GetGamepadAxisCount(gamepad) + 20, 75, 24);
if (IsMouseButtonPressed(MouseButton.Left) && CheckCollisionPointRec(mousePosition, vibrateButton))
{
SetGamepadVibration(gamepad, 1.0f, 1.0f, 1.0f);
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -60,50 +85,49 @@ public class InputGamepad
BeginDrawing(); BeginDrawing();
ClearBackground(Color.RayWhite); ClearBackground(Color.RayWhite);
if (IsGamepadAvailable(0)) if (IsGamepadAvailable(gamepad))
{ {
string gamepadName = GetGamepadName_(0); string gamepadName = GetGamepadName_(gamepad);
DrawText($"GP1: {gamepadName}", 10, 10, 10, Color.Black); DrawText($"GP{gamepad}: {gamepadName}", 10, 10, 10, Color.Black);
if (gamepadName == XBOX360_LEGACY_NAME_ID || if (gamepadName.Contains(XBOX_ALIAS_1, StringComparison.OrdinalIgnoreCase)||
gamepadName == XBOX360_NAME_ID || gamepadName.Contains(XBOX_ALIAS_2, StringComparison.OrdinalIgnoreCase))
gamepadName == XBOX360_NAME_ID_RPI)
{ {
DrawTexture(texXboxPad, 0, 0, Color.DarkGray); DrawTexture(texXboxPad, 0, 0, Color.DarkGray);
// Draw buttons: xbox home // Draw buttons: xbox home
if (IsGamepadButtonDown(0, GamepadButton.Middle)) if (IsGamepadButtonDown(gamepad, GamepadButton.Middle))
{ {
DrawCircle(394, 89, 19, Color.Red); DrawCircle(394, 89, 19, Color.Red);
} }
// Draw buttons: basic // Draw buttons: basic
if (IsGamepadButtonDown(0, GamepadButton.MiddleRight)) if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleRight))
{ {
DrawCircle(436, 150, 9, Color.Red); DrawCircle(436, 150, 9, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.MiddleLeft)) if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleLeft))
{ {
DrawCircle(352, 150, 9, Color.Red); DrawCircle(352, 150, 9, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceLeft)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceLeft))
{ {
DrawCircle(501, 151, 15, Color.Blue); DrawCircle(501, 151, 15, Color.Blue);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceDown)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceDown))
{ {
DrawCircle(536, 187, 15, Color.Lime); DrawCircle(536, 187, 15, Color.Lime);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceRight)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceRight))
{ {
DrawCircle(572, 151, 15, Color.Maroon); DrawCircle(572, 151, 15, Color.Maroon);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceUp)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceUp))
{ {
DrawCircle(536, 115, 15, Color.Gold); DrawCircle(536, 115, 15, Color.Gold);
} }
@ -111,33 +135,33 @@ public class InputGamepad
// Draw buttons: d-pad // Draw buttons: d-pad
DrawRectangle(317, 202, 19, 71, Color.Black); DrawRectangle(317, 202, 19, 71, Color.Black);
DrawRectangle(293, 228, 69, 19, Color.Black); DrawRectangle(293, 228, 69, 19, Color.Black);
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceUp)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceUp))
{ {
DrawRectangle(317, 202, 19, 26, Color.Red); DrawRectangle(317, 202, 19, 26, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceDown)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceDown))
{ {
DrawRectangle(317, 202 + 45, 19, 26, Color.Red); DrawRectangle(317, 202 + 45, 19, 26, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceLeft)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceLeft))
{ {
DrawRectangle(292, 228, 25, 19, Color.Red); DrawRectangle(292, 228, 25, 19, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceRight)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceRight))
{ {
DrawRectangle(292 + 44, 228, 26, 19, Color.Red); DrawRectangle(292 + 44, 228, 26, 19, Color.Red);
} }
// Draw buttons: left-right back // Draw buttons: left-right back
if (IsGamepadButtonDown(0, GamepadButton.LeftTrigger1)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftTrigger1))
{ {
DrawCircle(259, 61, 20, Color.Red); DrawCircle(259, 61, 20, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightTrigger1)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightTrigger1))
{ {
DrawCircle(536, 61, 20, Color.Red); DrawCircle(536, 61, 20, Color.Red);
} }
@ -146,8 +170,8 @@ public class InputGamepad
DrawCircle(259, 152, 39, Color.Black); DrawCircle(259, 152, 39, Color.Black);
DrawCircle(259, 152, 34, Color.LightGray); DrawCircle(259, 152, 34, Color.LightGray);
DrawCircle( DrawCircle(
259 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftX) * 20), 259 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftX) * 20),
152 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftY) * 20), 152 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftY) * 20),
25, 25,
Color.Black Color.Black
); );
@ -156,36 +180,36 @@ public class InputGamepad
DrawCircle(461, 237, 38, Color.Black); DrawCircle(461, 237, 38, Color.Black);
DrawCircle(461, 237, 33, Color.LightGray); DrawCircle(461, 237, 33, Color.LightGray);
DrawCircle( DrawCircle(
461 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightX) * 20), 461 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightX) * 20),
237 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightY) * 20), 237 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightY) * 20),
25, Color.Black 25, Color.Black
); );
// Draw axis: left-right triggers // Draw axis: left-right triggers
float leftTriggerX = GetGamepadAxisMovement(0, GamepadAxis.LeftTrigger); float leftTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.LeftTrigger);
float rightTriggerX = GetGamepadAxisMovement(0, GamepadAxis.RightTrigger); float rightTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.RightTrigger);
DrawRectangle(170, 30, 15, 70, Color.Gray); DrawRectangle(170, 30, 15, 70, Color.Gray);
DrawRectangle(604, 30, 15, 70, Color.Gray); DrawRectangle(604, 30, 15, 70, Color.Gray);
DrawRectangle(170, 30, 15, (int)(((1.0f + leftTriggerX) / 2.0f) * 70), Color.Red); DrawRectangle(170, 30, 15, (int)(((1.0f + leftTriggerX) / 2.0f) * 70), Color.Red);
DrawRectangle(604, 30, 15, (int)(((1.0f + rightTriggerX) / 2.0f) * 70), Color.Red); DrawRectangle(604, 30, 15, (int)(((1.0f + rightTriggerX) / 2.0f) * 70), Color.Red);
} }
else if (gamepadName == PS3_NAME_ID) else if (gamepadName.Contains(PS_ALIAS_1, StringComparison.OrdinalIgnoreCase) || gamepadName.Contains(PS_ALIAS_2, StringComparison.OrdinalIgnoreCase))
{ {
DrawTexture(texPs3Pad, 0, 0, Color.DarkGray); DrawTexture(texPs3Pad, 0, 0, Color.DarkGray);
// Draw buttons: ps // Draw buttons: ps
if (IsGamepadButtonDown(0, GamepadButton.Middle)) if (IsGamepadButtonDown(gamepad, GamepadButton.Middle))
{ {
DrawCircle(396, 222, 13, Color.Red); DrawCircle(396, 222, 13, Color.Red);
} }
// Draw buttons: basic // Draw buttons: basic
if (IsGamepadButtonDown(0, GamepadButton.MiddleLeft)) if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleLeft))
{ {
DrawRectangle(328, 170, 32, 13, Color.Red); DrawRectangle(328, 170, 32, 13, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.MiddleRight)) if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleRight))
{ {
DrawTriangle( DrawTriangle(
new Vector2(436, 168), new Vector2(436, 168),
@ -195,22 +219,22 @@ public class InputGamepad
); );
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceUp)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceUp))
{ {
DrawCircle(557, 144, 13, Color.Lime); DrawCircle(557, 144, 13, Color.Lime);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceRight)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceRight))
{ {
DrawCircle(586, 173, 13, Color.Red); DrawCircle(586, 173, 13, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceDown)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceDown))
{ {
DrawCircle(557, 203, 13, Color.Violet); DrawCircle(557, 203, 13, Color.Violet);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightFaceLeft)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceLeft))
{ {
DrawCircle(527, 173, 13, Color.Pink); DrawCircle(527, 173, 13, Color.Pink);
} }
@ -218,33 +242,33 @@ public class InputGamepad
// Draw buttons: d-pad // Draw buttons: d-pad
DrawRectangle(225, 132, 24, 84, Color.Black); DrawRectangle(225, 132, 24, 84, Color.Black);
DrawRectangle(195, 161, 84, 25, Color.Black); DrawRectangle(195, 161, 84, 25, Color.Black);
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceUp)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceUp))
{ {
DrawRectangle(225, 132, 24, 29, Color.Red); DrawRectangle(225, 132, 24, 29, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceDown)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceDown))
{ {
DrawRectangle(225, 132 + 54, 24, 30, Color.Red); DrawRectangle(225, 132 + 54, 24, 30, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceLeft)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceLeft))
{ {
DrawRectangle(195, 161, 30, 25, Color.Red); DrawRectangle(195, 161, 30, 25, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceRight)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceRight))
{ {
DrawRectangle(195 + 54, 161, 30, 25, Color.Red); DrawRectangle(195 + 54, 161, 30, 25, Color.Red);
} }
// Draw buttons: left-right back buttons // Draw buttons: left-right back buttons
if (IsGamepadButtonDown(0, GamepadButton.LeftTrigger1)) if (IsGamepadButtonDown(gamepad, GamepadButton.LeftTrigger1))
{ {
DrawCircle(239, 82, 20, Color.Red); DrawCircle(239, 82, 20, Color.Red);
} }
if (IsGamepadButtonDown(0, GamepadButton.RightTrigger1)) if (IsGamepadButtonDown(gamepad, GamepadButton.RightTrigger1))
{ {
DrawCircle(557, 82, 20, Color.Red); DrawCircle(557, 82, 20, Color.Red);
} }
@ -253,8 +277,8 @@ public class InputGamepad
DrawCircle(319, 255, 35, Color.Black); DrawCircle(319, 255, 35, Color.Black);
DrawCircle(319, 255, 31, Color.LightGray); DrawCircle(319, 255, 31, Color.LightGray);
DrawCircle( DrawCircle(
319 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftX) * 20), 319 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftX) * 20),
255 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftY) * 20), 255 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftY) * 20),
25, 25,
Color.Black Color.Black
); );
@ -263,15 +287,15 @@ public class InputGamepad
DrawCircle(475, 255, 35, Color.Black); DrawCircle(475, 255, 35, Color.Black);
DrawCircle(475, 255, 31, Color.LightGray); DrawCircle(475, 255, 31, Color.LightGray);
DrawCircle( DrawCircle(
475 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightX) * 20), 475 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightX) * 20),
255 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightY) * 20), 255 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightY) * 20),
25, 25,
Color.Black Color.Black
); );
// Draw axis: left-right triggers // Draw axis: left-right triggers
float leftTriggerX = GetGamepadAxisMovement(0, GamepadAxis.LeftTrigger); float leftTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.LeftTrigger);
float rightTriggerX = GetGamepadAxisMovement(0, GamepadAxis.RightTrigger); float rightTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.RightTrigger);
DrawRectangle(169, 48, 15, 70, Color.Gray); DrawRectangle(169, 48, 15, 70, Color.Gray);
DrawRectangle(611, 48, 15, 70, Color.Gray); DrawRectangle(611, 48, 15, 70, Color.Gray);
DrawRectangle(169, 48, 15, (int)(((1.0f - leftTriggerX) / 2.0f) * 70), Color.Red); DrawRectangle(169, 48, 15, (int)(((1.0f - leftTriggerX) / 2.0f) * 70), Color.Red);
@ -283,12 +307,12 @@ public class InputGamepad
// TODO: Draw generic gamepad // TODO: Draw generic gamepad
} }
DrawText($"DETECTED AXIS [{GetGamepadAxisCount(0)}]:", 10, 50, 10, Color.Maroon); DrawText($"DETECTED AXIS [{GetGamepadAxisCount(gamepad)}]:", 10, 50, 10, Color.Maroon);
for (int i = 0; i < GetGamepadAxisCount(0); i++) for (int i = 0; i < GetGamepadAxisCount(gamepad); i++)
{ {
DrawText( DrawText(
$"AXIS {i}: {GetGamepadAxisMovement(0, (GamepadAxis)i)}", $"AXIS {i}: {GetGamepadAxisMovement(gamepad, (GamepadAxis)i)}",
20, 20,
70 + 20 * i, 70 + 20 * i,
10, 10,
@ -296,6 +320,10 @@ public class InputGamepad
); );
} }
DrawRectangleRec(vibrateButton, Color.SkyBlue);
DrawText("VIBRATE", (int)(vibrateButton.X + 14), (int)(vibrateButton.Y + 1), 10, Color.DarkGray);
if (GetGamepadButtonPressed() != (int)GamepadButton.Unknown) if (GetGamepadButtonPressed() != (int)GamepadButton.Unknown)
{ {
DrawText($"DETECTED BUTTON: {GetGamepadButtonPressed()}", 10, 430, 10, Color.Red); DrawText($"DETECTED BUTTON: {GetGamepadButtonPressed()}", 10, 430, 10, Color.Red);
@ -307,7 +335,7 @@ public class InputGamepad
} }
else else
{ {
DrawText("GP1: NOT DETECTED", 10, 10, 10, Color.Gray); DrawText($"GP{gamepad}: NOT DETECTED", 10, 10, 10, Color.Gray);
DrawTexture(texXboxPad, 0, 0, Color.LightGray); DrawTexture(texXboxPad, 0, 0, Color.LightGray);
} }

View file

@ -1,11 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Gestures Detection * raylib [core] example - input gestures
* *
* This example has been created using raylib 1.4 (www.raylib.com) * Example complexity rating: [] 2/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2016 Ramon Santamaria (@raysan5) * Example originally created with raylib 1.4, last time updated with raylib 4.2
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -25,7 +29,7 @@ public class InputGestures
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - gestures detection"); InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures");
Vector2 touchPosition = new(0, 0); Vector2 touchPosition = new(0, 0);
Rectangle touchArea = new(220, 10, screenWidth - 230, screenHeight - 20); Rectangle touchArea = new(220, 10, screenWidth - 230, screenHeight - 20);

View file

@ -0,0 +1,434 @@
/*******************************************************************************************
*
* raylib [core] example - input gestures testbed
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 5.0, last time updated with raylib 6.0
*
* Example contributed by ubkp (@ubkp) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2023-2025 ubkp (@ubkp)
*
********************************************************************************************/
using System.Numerics;
namespace Examples.Core;
using static Raylib_cs.Raylib;
public class InputGesturesTestBed
{
public const int GESTURE_LOG_SIZE = 20;
public const int MAX_TOUCH_COUNT = 32;
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures testbed");
Vector2 messagePosition = new Vector2( 160, 7 );
// Last gesture variables definitions
Gesture lastGesture = 0;
Vector2 lastGesturePosition = new Vector2( 165, 130 );
// Gesture log variables definitions
// NOTE: The gesture log uses an array (as an inverted circular queue) to store the performed gestures
string[] gestureLog = new string[GESTURE_LOG_SIZE + 1];
for (int i= 0; i < GESTURE_LOG_SIZE; i++)
{
gestureLog[i] = new string(new char[12]);
}
;
// NOTE: The index for the inverted circular queue (moving from last to first direction, then looping around)
int gestureLogIndex = GESTURE_LOG_SIZE;
Gesture previousGesture = 0;
// Log mode values:
// - 0 shows repeated events
// - 1 hides repeated events
// - 2 shows repeated events but hide hold events
// - 3 hides repeated events and hide hold events
int logMode = 1;
Color gestureColor = new Color(0, 0, 0, 255 );
Rectangle logButton1 = new Rectangle( 53, 7, 48, 26 );
Rectangle logButton2 = new Rectangle( 108, 7, 36, 26 );
Vector2 gestureLogPosition = new Vector2( 10, 10 );
// Protractor variables definitions
float angleLength = 90.0f;
float currentAngleDegrees = 0.0f;
Vector2 finalVector = new Vector2( 0.0f, 0.0f );
Vector2 protractorPosition = new Vector2( 266.0f, 315.0f );
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
//--------------------------------------------------------------------------------------
// Handle common gestures data
int i, ii; // Iterators that will be reused by all for loops
Gesture currentGesture = GetGestureDetected();
float currentDragDegrees = GetGestureDragAngle();
float currentPitchDegrees = GetGesturePinchAngle();
int touchCount = GetTouchPointCount();
// Handle last gesture
if ((currentGesture != 0) && ((int)currentGesture != 4) && (currentGesture != previousGesture))
{
lastGesture = currentGesture; // Filter the meaningful gestures (1, 2, 8 to 512) for the display
}
// Handle gesture log
if (IsMouseButtonReleased(MouseButton.Left))
{
if (CheckCollisionPointRec(GetMousePosition(), logButton1))
{
switch (logMode)
{
case 3: logMode = 2; break;
case 2: logMode = 3; break;
case 1: logMode = 0; break;
default: logMode = 1; break;
}
}
else if (CheckCollisionPointRec(GetMousePosition(), logButton2))
{
switch (logMode)
{
case 3: logMode = 1; break;
case 2: logMode = 0; break;
case 1: logMode = 3; break;
default: logMode = 2; break;
}
}
}
int fillLog = 0; // Gate variable to be used to allow or not the gesture log to be filled
if (currentGesture != 0)
{
if (logMode == 3) // 3 hides repeated events and hide hold events
{
if ((((int)currentGesture != 4) && (currentGesture != previousGesture)) || ((int)currentGesture < 3))
{
fillLog = 1;
}
}
else if (logMode == 2) // 2 shows repeated events but hide hold events
{
if ((int)currentGesture != 4)
{
fillLog = 1;
}
}
else if (logMode == 1) // 1 hides repeated events
{
if (currentGesture != previousGesture)
{
fillLog = 1;
}
}
else // 0 shows repeated events
{
fillLog = 1;
}
}
if (fillLog > 0) // If one of the conditions from logMode was met, fill the gesture log
{
previousGesture = currentGesture;
gestureColor = GetGestureColor((int)currentGesture);
if (gestureLogIndex <= 0)
{
gestureLogIndex = GESTURE_LOG_SIZE;
}
gestureLogIndex--;
// Copy the gesture respective name to the gesture log array
gestureLog[gestureLogIndex] = GetGestureName((int)currentGesture);
}
// Handle protractor
if ((int)currentGesture > 255)
{
currentAngleDegrees = currentPitchDegrees; // Pinch In and Pinch Out
}
else if ((int)currentGesture > 15)
{
currentAngleDegrees = currentDragDegrees; // Swipe Right, Swipe Left, Swipe Up and Swipe Down
}
else if (currentGesture > 0)
{
currentAngleDegrees = 0.0f; // Tap, Doubletap, Hold and Grab
}
float currentAngleRadians =
((currentAngleDegrees + 90.0f) * MathF.PI / 180); // Convert the current angle to Radians
// Calculate the final vector for display
finalVector = new Vector2(
(angleLength * MathF.Sin(currentAngleRadians)) + protractorPosition.X,
(angleLength * MathF.Cos(currentAngleRadians)) + protractorPosition.Y
)
;
// Handle touch and mouse pointer points
Vector2[] touchPosition = new Vector2[MAX_TOUCH_COUNT];
Vector2 mousePosition = Vector2.Zero;
if (currentGesture != Gesture.None)
{
if (touchCount != 0)
{
for (i = 0; i < touchCount; i++)
{
touchPosition[i] = GetTouchPosition(i); // Fill the touch positions
}
}
else
{
mousePosition = GetMousePosition();
}
}
//--------------------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw common elements
DrawText("*", (int)messagePosition.X + 5, (int)messagePosition.Y + 5, 10, Color.Black);
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", (int)messagePosition.X + 15,
(int)messagePosition.Y + 5, 10, Color.Black);
DrawText("*", (int)messagePosition.X + 5, (int)messagePosition.Y + 35, 10, Color.Black);
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.",
(int)messagePosition.X + 15, (int)messagePosition.Y + 35, 10, Color.Black);
// Draw last gesture
DrawText("Last gesture", (int)lastGesturePosition.X + 33, (int)lastGesturePosition.Y - 47, 20, Color.Black);
DrawText("Swipe Tap Pinch Touch", (int)lastGesturePosition.X + 17,
(int)lastGesturePosition.Y - 18, 10, Color.Black);
DrawRectangle((int)lastGesturePosition.X + 20, (int)lastGesturePosition.Y, 20, 20,
lastGesture == Gesture.SwipeUp ? Color.Red : Color.LightGray);
DrawRectangle((int)lastGesturePosition.X, (int)lastGesturePosition.Y + 20, 20, 20,
lastGesture == Gesture.SwipeLeft ? Color.Red : Color.LightGray);
DrawRectangle((int)lastGesturePosition.X + 40, (int)lastGesturePosition.Y + 20, 20, 20,
lastGesture == Gesture.SwipeRight ? Color.Red : Color.LightGray);
DrawRectangle((int)lastGesturePosition.X + 20, (int)lastGesturePosition.Y + 40, 20, 20,
lastGesture == Gesture.SwipeDown ? Color.Red : Color.LightGray);
DrawCircle((int)lastGesturePosition.X + 80, (int)lastGesturePosition.Y + 16, 10,
lastGesture == Gesture.Tap ? Color.Blue : Color.LightGray);
DrawRing(new Vector2(
lastGesturePosition.X + 103, lastGesturePosition.Y + 16
), 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == Gesture.Drag ? Color.Lime : Color.LightGray);
DrawCircle((int)lastGesturePosition.X + 80, (int)lastGesturePosition.Y + 43, 10,
lastGesture == Gesture.DoubleTap ? Color.SkyBlue : Color.LightGray);
DrawCircle((int)lastGesturePosition.X + 103, (int)lastGesturePosition.Y + 43, 10,
lastGesture == Gesture.DoubleTap ? Color.SkyBlue : Color.LightGray);
DrawTriangle(new Vector2(
lastGesturePosition.X + 122, lastGesturePosition.Y + 16
), new Vector2(
lastGesturePosition.X + 137, lastGesturePosition.Y + 26
), new Vector2(
lastGesturePosition.X + 137, lastGesturePosition.Y + 6
), lastGesture == Gesture.PinchOut ? Color.Orange : Color.LightGray);
DrawTriangle(new Vector2(
lastGesturePosition.X + 147, lastGesturePosition.Y + 6
), new Vector2(
lastGesturePosition.X + 147, lastGesturePosition.Y + 26
), new Vector2(
lastGesturePosition.X + 162, lastGesturePosition.Y + 16
), lastGesture == Gesture.PinchOut ? Color.Orange : Color.Gray);
DrawTriangle(new Vector2(
lastGesturePosition.X + 125, lastGesturePosition.Y + 33
), new Vector2(
lastGesturePosition.X + 125, lastGesturePosition.Y + 53
), new Vector2(
lastGesturePosition.X + 140, lastGesturePosition.Y + 43
), lastGesture == Gesture.PinchIn ? Color.Violet : Color.LightGray);
DrawTriangle(new Vector2(
lastGesturePosition.X + 144, lastGesturePosition.Y + 43
), new Vector2(
lastGesturePosition.X + 159, lastGesturePosition.Y + 53
), new Vector2(
lastGesturePosition.X + 159, lastGesturePosition.Y + 33
), lastGesture == Gesture.PinchIn ? Color.Violet : Color.LightGray);
for (i = 0; i < 4; i++)
{
DrawCircle((int)lastGesturePosition.X + 180, (int)lastGesturePosition.Y + 7 + i * 15, 5,
touchCount <= i ? Color.LightGray : gestureColor);
}
// Draw gesture log
DrawText("Log", (int)gestureLogPosition.X, (int)gestureLogPosition.Y, 20, Color.Black);
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE)
{
DrawText(gestureLog[ii], (int)gestureLogPosition.X, (int)gestureLogPosition.Y + 410 - i * 20, 20,
(i == 0 ? gestureColor : Color.LightGray));
}
Color logButton1Color, logButton2Color;
switch (logMode)
{
case 3:
logButton1Color = Color.Maroon;
logButton2Color = Color.Maroon;
break;
case 2:
logButton1Color = Color.Gray;
logButton2Color = Color.Maroon;
break;
case 1:
logButton1Color = Color.Maroon;
logButton2Color = Color.Gray;
break;
default:
logButton1Color = Color.Gray;
logButton2Color = Color.Gray;
break;
}
DrawRectangleRec(logButton1, logButton1Color);
DrawText("Hide", (int)logButton1.X + 7, (int)logButton1.Y + 3, 10, Color.White);
DrawText("Repeat", (int)logButton1.X + 7, (int)logButton1.Y + 13, 10, Color.White);
DrawRectangleRec(logButton2, logButton2Color);
DrawText("Hide", (int)logButton1.X + 62, (int)logButton1.Y + 3, 10, Color.White);
DrawText("Hold", (int)logButton1.X + 62, (int)logButton1.Y + 13, 10, Color.White);
// Draw protractor
DrawText("Angle", (int)protractorPosition.X + 55, (int)protractorPosition.Y + 76, 10, Color.Black);
// Note: Official it's using raylibs functions for string manipulation. But in C# it will end up in an unsafe handling.
string angleString = currentAngleDegrees.ToString("F3");
int angleStringDot = angleString.IndexOf('.');
string angleStringTrim = angleString.Substring(0, angleStringDot + 3);
DrawText(angleStringTrim, (int)protractorPosition.X + 55, (int)protractorPosition.Y + 92, 20, gestureColor);
DrawCircleV(protractorPosition, 80.0f, Color.White);
DrawLineEx(new Vector2(
protractorPosition.X - 90, protractorPosition.Y
), new Vector2(
protractorPosition.X + 90, protractorPosition.Y
), 3.0f, Color.LightGray);
DrawLineEx(new Vector2(
protractorPosition.X, protractorPosition.Y - 90
), new Vector2(
protractorPosition.X, protractorPosition.Y + 90
), 3.0f, Color.LightGray);
DrawLineEx(new Vector2(
protractorPosition.X - 80, protractorPosition.Y - 45
), new Vector2(
protractorPosition.X + 80, protractorPosition.Y + 45
), 3.0f, Color.Green);
DrawLineEx(new Vector2(
protractorPosition.X - 80, protractorPosition.Y + 45
), new Vector2(
protractorPosition.X + 80, protractorPosition.Y - 45
), 3.0f, Color.Green);
DrawText("0", (int)protractorPosition.X + 96, (int)protractorPosition.Y - 9, 20, Color.Black);
DrawText("30", (int)protractorPosition.X + 74, (int)protractorPosition.Y - 68, 20, Color.Black);
DrawText("90", (int)protractorPosition.X - 11, (int)protractorPosition.Y - 110, 20, Color.Black);
DrawText("150", (int)protractorPosition.X - 100, (int)protractorPosition.Y - 68, 20, Color.Black);
DrawText("180", (int)protractorPosition.X - 124, (int)protractorPosition.Y - 9, 20, Color.Black);
DrawText("210", (int)protractorPosition.X - 100, (int)protractorPosition.Y + 50, 20, Color.Black);
DrawText("270", (int)protractorPosition.X - 18, (int)protractorPosition.Y + 92, 20, Color.Black);
DrawText("330", (int)protractorPosition.X + 72, (int)protractorPosition.Y + 50, 20, Color.Black);
if (currentAngleDegrees != 0.0f)
{
DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
}
// Draw touch and mouse pointer points
if (currentGesture != Gesture.None)
{
if (touchCount != 0)
{
for (i = 0; i < touchCount; i++)
{
DrawCircleV(touchPosition[i], 50.0f, Fade(gestureColor, 0.5f));
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
}
if (touchCount == 2)
{
DrawLineEx(touchPosition[0], touchPosition[1], (((int)currentGesture == 512) ? 8.0f : 12.0f),
gestureColor);
}
}
else
{
DrawCircleV(mousePosition, 35.0f, Fade(gestureColor, 0.5f));
DrawCircleV(mousePosition, 5.0f, gestureColor);
}
}
EndDrawing();
//--------------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
static string GetGestureName(int gesture)
{
switch (gesture)
{
case 0: return "None"; break;
case 1: return "Tap"; break;
case 2: return "Double Tap"; break;
case 4: return "Hold"; break;
case 8: return "Drag"; break;
case 16: return "Swipe Right"; break;
case 32: return "Swipe Left"; break;
case 64: return "Swipe Up"; break;
case 128: return "Swipe Down"; break;
case 256: return "Pinch In"; break;
case 512: return "Pinch Out"; break;
default: return "Unknown"; break;
}
}
// Get color for gesture value
static Color GetGestureColor(int gesture)
{
switch (gesture)
{
case 0: return Color.Black; break;
case 1: return Color.Blue; break;
case 2: return Color.SkyBlue; break;
case 4: return Color.Black; break;
case 8: return Color.Lime; break;
case 16: return Color.Red; break;
case 32: return Color.Red; break;
case 64: return Color.Red; break;
case 128: return Color.Red; break;
case 256: return Color.Violet; break;
case 512: return Color.Orange; break;
default: return Color.Black; break;
}
}
}

View file

@ -1,11 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Keyboard input * raylib [core] example - input keys
* *
* This example has been created using raylib 1.0 (www.raylib.com) * Example complexity rating: [] 1/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2014 Ramon Santamaria (@raysan5) * Example originally created with raylib 1.0, last time updated with raylib 1.0
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View file

@ -1,14 +1,19 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Mouse input * raylib [core] example - input mouse
* *
* This example has been created using raylib 1.0 (www.raylib.com) * Example complexity rating: [] 1/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2014 Ramon Santamaria (@raysan5) * Example originally created with raylib 1.0, last time updated with raylib 5.5
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
using System.Numerics; using System.Numerics;
using static Raylib_cs.Raylib; using static Raylib_cs.Raylib;
@ -36,6 +41,19 @@ public class InputMouse
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
if (IsKeyPressed(KeyboardKey.H))
{
if (IsCursorHidden())
{
ShowCursor();
}
else
{
HideCursor();
}
}
ballPosition = GetMousePosition(); ballPosition = GetMousePosition();
if (IsMouseButtonPressed(MouseButton.Left)) if (IsMouseButtonPressed(MouseButton.Left))
@ -50,6 +68,18 @@ public class InputMouse
{ {
ballColor = Color.DarkBlue; ballColor = Color.DarkBlue;
} }
else if (IsMouseButtonPressed(MouseButton.Extra))
{
ballColor = Color.Yellow;
}
else if (IsMouseButtonPressed(MouseButton.Forward))
{
ballColor = Color.Orange;
}
else if (IsMouseButtonPressed(MouseButton.Back))
{
ballColor = Color.Beige;
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -60,6 +90,16 @@ public class InputMouse
DrawCircleV(ballPosition, 40, ballColor); DrawCircleV(ballPosition, 40, ballColor);
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, Color.DarkGray); DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, Color.DarkGray);
DrawText("Press 'H' to toggle cursor visibility", 10, 30, 20, Color.DarkGray);
if (IsCursorHidden())
{
DrawText("CURSOR HIDDEN", 20, 60, 20, Color.Red);
}
else
{
DrawText("CURSOR VISIBLE", 20, 60, 20, Color.Lime);
}
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View file

@ -1,11 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] examples - Mouse wheel input * raylib [core] example - input mouse wheel
* *
* This test has been created using raylib 1.1 (www.raylib.com) * Example complexity rating: [] 1/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2014 Ramon Santamaria (@raysan5) * Example originally created with raylib 1.1, last time updated with raylib 1.3
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -24,10 +28,8 @@ public class InputMouseWheel
InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel"); InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel");
int boxPositionY = screenHeight / 2 - 40; int boxPositionY = screenHeight/2 - 40;
int scrollSpeed = 4; // Scrolling speed in pixels
// Scrolling speed in pixels
int scrollSpeed = 4;
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

View file

@ -1,13 +1,17 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Input multitouch * raylib [core] example - input multitouch
* *
* This example has been created using raylib 2.1 (www.raylib.com) * Example complexity rating: [] 1/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) *
* Example originally created with raylib 2.1, last time updated with raylib 2.5
* *
* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5) * Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5)
* *
* Copyright (c) 2019 Berni (@Berni8k) and Ramon Santamaria (@raysan5) * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2019-2025 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View file

@ -0,0 +1,216 @@
/*******************************************************************************************
*
* raylib [core] example - input virtual controls
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.0, last time updated with raylib 5.0
*
* Example contributed by GreenSnakeLinux (@GreenSnakeLinux),
* reviewed by Ramon Santamaria (@raysan5), oblerion (@oblerion) and danilwhale (@danilwhale)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2024-2025 GreenSnakeLinux (@GreenSnakeLinux) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
namespace Examples.Core;
using static Raylib_cs.Raylib;
public enum PadButton
{
BUTTON_NONE = -1,
BUTTON_UP,
BUTTON_LEFT,
BUTTON_RIGHT,
BUTTON_DOWN,
BUTTON_MAX
}
public class InputVirtualControls
{
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
Vector2 padPosition = new Vector2(100, 350);
float buttonRadius = 30;
Vector2[] buttonPositions =
[
new Vector2(
padPosition.X,padPosition.Y - buttonRadius * 1.5f
), // Up
new Vector2(
padPosition.X - buttonRadius * 1.5f, padPosition.Y
), // Left
new Vector2(
padPosition.X + buttonRadius * 1.5f, padPosition.Y
), // Right
new Vector2(
padPosition.X, padPosition.Y + buttonRadius * 1.5f
) // Down
];
Vector2[][] arrowTris = [
// Up
[
new Vector2(
buttonPositions[0].X, buttonPositions[0].Y - 12
),
new Vector2(
buttonPositions[0].X - 9, buttonPositions[0].Y + 9
),
new Vector2(
buttonPositions[0].X + 9, buttonPositions[0].Y + 9
)
],
// Left
[
new Vector2(
buttonPositions[1].X + 9, buttonPositions[1].Y - 9
),
new Vector2(
buttonPositions[1].X - 12, buttonPositions[1].Y
),
new Vector2(
buttonPositions[1].X + 9, buttonPositions[1].Y + 9
)
],
// Right
[
new Vector2(
buttonPositions[2].X + 12, buttonPositions[2].Y
),
new Vector2(
buttonPositions[2].X - 9, buttonPositions[2].Y - 9
),
new Vector2(
buttonPositions[2].X - 9, buttonPositions[2].Y + 9
)
],
// Down
[
new Vector2(
buttonPositions[3].X - 9, buttonPositions[3].Y - 9
),
new Vector2(
buttonPositions[3].X, buttonPositions[3].Y + 12
),
new Vector2(
buttonPositions[3].X + 9, buttonPositions[3].Y - 9
)
]
]
;
Color[] buttonLabelColors = [
Color.Yellow, // Up
Color.Blue, // Left
Color.Red, // Right
Color.Green // Down
];
int pressedButton = (int)PadButton.BUTTON_NONE;
Vector2 inputPosition = new Vector2( 0, 0 );
Vector2 playerPosition = new Vector2( (float)screenWidth / 2, (float)screenHeight / 2 );
float playerSpeed = 75f;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//--------------------------------------------------------------------------
if ((GetTouchPointCount() > 0))
{
inputPosition = GetTouchPosition(0); // Use touch position
}
else
{
inputPosition = GetMousePosition(); // Use mouse position
}
// Reset pressed button to none
pressedButton = (int)PadButton.BUTTON_NONE;
// Make sure user is pressing left mouse button if they're from desktop
if ((GetTouchPointCount() > 0) ||
((GetTouchPointCount() == 0) && IsMouseButtonDown(MouseButton.Left)))
{
// Find nearest D-Pad button to the input position
for (int i = 0; i < (int)PadButton.BUTTON_MAX; i++)
{
float distX = MathF.Abs(buttonPositions[i].X - inputPosition.X);
float distY = MathF.Abs(buttonPositions[i].Y - inputPosition.Y);
if ((distX + distY < buttonRadius))
{
pressedButton = i;
break;
}
}
}
// Move player according to pressed button
switch ((PadButton)pressedButton)
{
case PadButton.BUTTON_UP: playerPosition.Y -= playerSpeed * GetFrameTime(); break;
case PadButton.BUTTON_LEFT: playerPosition.X -= playerSpeed * GetFrameTime(); break;
case PadButton.BUTTON_RIGHT: playerPosition.X += playerSpeed * GetFrameTime(); break;
case PadButton.BUTTON_DOWN: playerPosition.Y += playerSpeed * GetFrameTime(); break;
default: break;
}
;
//--------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw world
DrawCircleV(playerPosition, 50, Color.Maroon);
// Draw GUI
for (int i = 0; i < (int)PadButton.BUTTON_MAX; i++)
{
DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton) ? Color.DarkGray : Color.Black);
DrawTriangle(
arrowTris[i][0],
arrowTris[i][1],
arrowTris[i][2],
buttonLabelColors[i]
);
}
DrawText("move the player with D-Pad buttons", 10, 10, 20, Color.DarkGray);
EndDrawing();
//--------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,28 +1,31 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [models] example - Load 3d model with animations and play them * raylib [models] example - loading iqm
* *
* This example has been created using raylib 2.5 (www.raylib.com) * Example complexity rating: [] 2/4
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) *
* Example originally created with raylib 2.5, last time updated with raylib 3.5
* *
* Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5) * Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5)
* *
* Copyright (c) 2019 Culacant (@culacant) and Ramon Santamaria (@raysan5) * NOTES: To export an IQM model from blender, make sure it is not posed, the vertices need
* to be in the same position as they would be in edit mode and the scale of the models is
* set to 0; scaling can be set from the export menu
* *
******************************************************************************************** * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
* *
* To export a model from blender, make sure it is not posed, the vertices need to be in the * Copyright (c) 2019-2025 Culacant (@culacant) and Ramon Santamaria (@raysan5)
* same position as they would be in edit mode.
* and that the scale of your models is set to 0. Scaling can be done from the export menu.
* *
********************************************************************************************/ ********************************************************************************************/
using System.Numerics; using System.Numerics;
using System.Runtime.InteropServices;
using static Raylib_cs.Raylib; using static Raylib_cs.Raylib;
namespace Examples.Models; namespace Examples.Models;
public class AnimationDemo public class LoadingIqm
{ {
public unsafe static int Main() public unsafe static int Main()
{ {
@ -36,20 +39,22 @@ public class AnimationDemo
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera3D camera = new(); Camera3D camera = new();
camera.Position = new Vector3(10.0f, 10.0f, 10.0f); camera.Position = new Vector3(10.0f, 10.0f, 10.0f);
camera.Target = new Vector3(0.0f, 0.0f, 0.0f); camera.Target = new Vector3(0.0f, 4.0f, 0.0f);
camera.Up = new Vector3(0.0f, 1.0f, 0.0f); camera.Up = new Vector3(0.0f, 1.0f, 0.0f);
camera.FovY = 45.0f; camera.FovY = 45.0f;
camera.Projection = CameraProjection.Perspective; camera.Projection = CameraProjection.Perspective;
Model model = LoadModel("resources/models/iqm/guy.iqm"); Model model = LoadModel("resources/models/iqm/guy.iqm");
Texture2D texture = LoadTexture("resources/models/iqm/guytex.png"); Texture2D texture = LoadTexture("resources/models/iqm/guytex.png");
Raylib.SetMaterialTexture(ref model, 0, MaterialMapIndex.Albedo, ref texture); Raylib.SetMaterialTexture(ref model, 0, MaterialMapIndex.Diffuse, ref texture);
Vector3 position = new(0.0f, 0.0f, 0.0f); Vector3 position = new(0.0f, 0.0f, 0.0f);
// Load animation data // Load animation data
int animsCount = 0; var anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm");
var anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", ref animsCount);
int animFrameCounter = 0; // Animation playing variables
int animIndex = 0;
float animCurrentFrame = 0.0f;
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -59,17 +64,15 @@ public class AnimationDemo
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateCamera(ref camera, CameraMode.Free); UpdateCamera(ref camera, CameraMode.Orbital);
// Play animation when spacebar is held down // Play animation when spacebar is held down
if (IsKeyDown(KeyboardKey.Space)) animCurrentFrame += 1.0f;
UpdateModelAnimation(model, anims[0], animCurrentFrame);
if (animCurrentFrame >= anims[0].KeyFrameCount)
{ {
animFrameCounter++; animCurrentFrame = 0;
UpdateModelAnimation(model, anims[0], animFrameCounter);
if (animFrameCounter >= anims[0].FrameCount)
{
animFrameCounter = 0;
}
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -89,17 +92,10 @@ public class AnimationDemo
Color.White Color.White
); );
for (int i = 0; i < model.BoneCount; i++)
{
var framePoses = anims[0].FramePoses;
DrawCube(framePoses[animFrameCounter][i].Translation, 0.2f, 0.2f, 0.2f, Color.Red);
}
DrawGrid(10, 1.0f); DrawGrid(10, 1.0f);
EndMode3D(); EndMode3D();
DrawText($"Current animation: {anims[animIndex].NameToString()}", 10, 10, 20, Color.Maroon);
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, Color.Maroon);
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, Color.Gray); DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
EndDrawing(); EndDrawing();
@ -109,9 +105,7 @@ public class AnimationDemo
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadTexture(texture); UnloadTexture(texture);
UnloadModelAnimations(anims);
UnloadModelAnimations(anims, animsCount);
UnloadModel(model); UnloadModel(model);
CloseWindow(); CloseWindow();

View file

@ -1,4 +1,3 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using Examples.Core; using Examples.Core;
using Examples.Shapes; using Examples.Shapes;
@ -34,6 +33,9 @@ public class ExampleList
public static ExampleInfo[] AllExamples = new[] public static ExampleInfo[] AllExamples = new[]
{ {
// Core // Core
new ExampleInfo("DeltaTime", DeltaTime.Main),
new ExampleInfo("InputGesturesTestBed", InputGesturesTestBed.Main),
new ExampleInfo("InputVirtualControls", InputVirtualControls.Main),
new ExampleInfo("Camera2dPlatformer", Camera2dPlatformer.Main), new ExampleInfo("Camera2dPlatformer", Camera2dPlatformer.Main),
new ExampleInfo("Camera2dDemo", Camera2dDemo.Main), new ExampleInfo("Camera2dDemo", Camera2dDemo.Main),
new ExampleInfo("Camera3dFirstPerson", Camera3dFirstPerson.Main), new ExampleInfo("Camera3dFirstPerson", Camera3dFirstPerson.Main),
@ -110,7 +112,7 @@ public class ExampleList
new ExampleInfo("WritingAnim", WritingAnim.Main), new ExampleInfo("WritingAnim", WritingAnim.Main),
// Models // Models
new ExampleInfo("AnimationDemo", AnimationDemo.Main), new ExampleInfo("LoadingIqm", LoadingIqm.Main),
new ExampleInfo("BillboardDemo", BillboardDemo.Main), new ExampleInfo("BillboardDemo", BillboardDemo.Main),
new ExampleInfo("BoxCollisions", BoxCollisions.Main), new ExampleInfo("BoxCollisions", BoxCollisions.Main),
new ExampleInfo("CubicmapDemo", CubicmapDemo.Main), new ExampleInfo("CubicmapDemo", CubicmapDemo.Main),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

View file

@ -820,32 +820,32 @@ public static unsafe partial class Raylib
/// <summary>Rename file (if exists)</summary> /// <summary>Rename file (if exists)</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileRename(sbyte* fileName, sbyte* fileRename); public static partial int FileRename(sbyte* fileName, sbyte* fileRename);
/// <summary>Remove file (if exists)</summary> /// <summary>Remove file (if exists)</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileRemove(sbyte* fileName); public static partial int FileRemove(sbyte* fileName);
/// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary> /// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileCopy(sbyte* srcPath, sbyte* dstPath); public static partial int FileCopy(sbyte* srcPath, sbyte* dstPath);
/// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary> /// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileMove(sbyte* srcPath, sbyte* dstPath); public static partial int FileMove(sbyte* srcPath, sbyte* dstPath);
/// <summary>Replace text in an existing file</summary> /// <summary>Replace text in an existing file</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileTextReplace(sbyte* fileName, sbyte* search, sbyte* replacement); public static partial int FileTextReplace(sbyte* fileName, sbyte* search, sbyte* replacement);
/// <summary>Find text in existing file</summary> /// <summary>Find text in existing file</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileTextFindIndex(sbyte* fileName, sbyte* search); public static partial int FileTextFindIndex(sbyte* fileName, sbyte* search);
/// <summary>Check if file exists</summary> /// <summary>Check if file exists</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
@ -962,7 +962,7 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial FilePathList GetDirectoryFileCount(sbyte* dirPath); public static partial FilePathList GetDirectoryFileCount(sbyte* dirPath);
/// <summary>Get the file count in a directory</summary> /// <summary>Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"</summary>
[LibraryImport(NativeLibName)] [LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial FilePathList GetDirectoryFileCountEx(sbyte* dirPath, sbyte* filter, CBool scanSubdirs); public static partial FilePathList GetDirectoryFileCountEx(sbyte* dirPath, sbyte* filter, CBool scanSubdirs);

View file

@ -248,4 +248,6 @@ public unsafe struct Mesh
public const int VboIdIndexIndices = 6; public const int VboIdIndexIndices = 6;
#endregion #endregion
} }

View file

@ -19,6 +19,14 @@ public unsafe struct BoneInfo
/// Bone parent /// Bone parent
/// </summary> /// </summary>
public int Parent; public int Parent;
public string NameToString()
{
fixed (sbyte* name = Name)
{
return Utf8StringUtils.GetUTF8String(name);
}
}
} }
/// <summary> /// <summary>
@ -41,6 +49,16 @@ public unsafe struct ModelSkeleton
/// Bones base transformation (Transform[]) /// Bones base transformation (Transform[])
/// </summary> /// </summary>
public Transform* ModelAnimPose; public Transform* ModelAnimPose;
public Span<Transform> ModelAnimPoseAsSpan()
{
return new Span<Transform>(ModelAnimPose, BoneCount);
}
public Span<BoneInfo> BonesAsSpan()
{
return new Span<BoneInfo>(Bones, BoneCount);
}
} }
// Note: // Note:
@ -84,29 +102,52 @@ public unsafe struct Model
public int* MeshMaterial; public int* MeshMaterial;
/// <summary> /// <summary>
/// Number of bones /// Skeleton for animation
/// </summary> /// </summary>
public int BoneCount; ModelSkeleton Skeleton;
//TODO: Span
/// <summary> /// <summary>
/// Bones information (skeleton, BoneInfo *) /// Current animation pose (Transform[])
/// </summary> /// </summary>
public BoneInfo* Bones; public Transform* CurrentPose;
//TODO: Span
/// <summary> /// <summary>
/// Bones base transformation (pose, Transform *) /// Bones animated transformation matrices
/// </summary> /// </summary>
public Transform* BindPose; public Matrix4x4* BoneMatrices;
public Span<Matrix4x4> BoneMatricesAsSpan()
{
return new Span<Matrix4x4>(BoneMatrices, Skeleton.BoneCount);
}
public Span<Transform> CurrentPoseAsSpan()
{
return new Span<Transform>(CurrentPose, Skeleton.BoneCount);
}
public Span<int> MeshMaterialAsSpan()
{
return new Span<int>(MeshMaterial, MeshCount);
}
public Span<Mesh> MeshesAsSpan()
{
return new Span<Mesh>(Meshes, MeshCount);
}
} }
/// <summary> /// <summary>
/// Model animation /// ModelAnimation, contains a full animation sequence
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public unsafe struct ModelAnimation public unsafe struct ModelAnimation
{ {
/// <summary>
/// Animation name (char[32])
/// </summary>
public fixed sbyte Name[32];
/// <summary> /// <summary>
/// Number of bones /// Number of bones
/// </summary> /// </summary>
@ -115,61 +156,23 @@ public unsafe struct ModelAnimation
/// <summary> /// <summary>
/// Number of animation frames /// Number of animation frames
/// </summary> /// </summary>
public readonly int FrameCount; public readonly int KeyFrameCount;
/// <summary> /// <summary>
/// Bones information (skeleton, BoneInfo *) /// Animation sequence keyframe poses [keyframe][pose]
/// </summary> /// </summary>
public readonly BoneInfo* Bones; public Transform* KeyframePoses;
/// <inheritdoc cref="Bones"/> public Span<Transform> KeyFramePosesAsSpan()
public readonly ReadOnlySpan<BoneInfo> BoneInfo => new ReadOnlySpan<BoneInfo>(Bones, BoneCount);
/// <summary>
/// Poses array by frame (Transform **)
/// </summary>
public readonly Transform** FramePoses;
/// <summary>
/// Animation name (char[32])
/// </summary>
public fixed sbyte Name[32];
/// <inheritdoc cref="FramePoses"/>
public readonly FramePosesCollection FramePosesColl => new FramePosesCollection(FramePoses, FrameCount, BoneCount);
public readonly struct FramePosesCollection
{ {
readonly Transform** _framePoses; return new Span<Transform>(KeyframePoses, KeyFrameCount);
}
readonly int _frameCount; public string NameToString()
readonly int _boneCount;
public readonly FramePoses this[int index] => new FramePoses(_framePoses[index], _boneCount);
public readonly Transform this[int index1, int index2] => new FramePoses(_framePoses[index1], _boneCount)[index2];
internal FramePosesCollection(Transform** framePoses, int frameCount, int boneCount)
{ {
this._framePoses = framePoses; fixed (sbyte* name = Name)
this._frameCount = frameCount; {
this._boneCount = boneCount; return Utf8StringUtils.GetUTF8String(name);
} }
} }
} }
public readonly unsafe struct FramePoses
{
readonly Transform* _poses;
readonly int _count;
public readonly ref Transform this[int index] => ref _poses[index];
internal FramePoses(Transform* poses, int count)
{
this._poses = poses;
this._count = count;
}
}

View file

@ -1085,6 +1085,24 @@ public static unsafe partial class Raylib
} }
} }
/// <summary>Load model animations from file</summary>
public static Span<ModelAnimation> LoadModelAnimations(string fileName)
{
using AnsiBuffer str1 = fileName.ToAnsiBuffer();
int count;
ModelAnimation* result = LoadModelAnimations(str1.AsPointer(), &count);
return new Span<ModelAnimation>(result, count);
}
public static void UnloadModelAnimations(Span<ModelAnimation> animations)
{
fixed (ModelAnimation* ptr = animations)
{
UnloadModelAnimations(ptr, animations.Length);
}
}
/// <summary>Compute mesh tangents</summary> /// <summary>Compute mesh tangents</summary>
public static void GenMeshTangents(ref Mesh mesh) public static void GenMeshTangents(ref Mesh mesh)
{ {
@ -1549,6 +1567,155 @@ public static unsafe partial class Raylib
SaveFileText(fileBuffer.AsPointer(), textBuffer.AsPointer()); SaveFileText(fileBuffer.AsPointer(), textBuffer.AsPointer());
} }
/// <summary>Rename file (if exists)</summary>
public static int FileRename(string filename, string fileRename)
{
using AnsiBuffer fileBuffer = filename.ToAnsiBuffer();
using AnsiBuffer textBuffer = fileRename.ToAnsiBuffer();
return FileRename(fileBuffer.AsPointer(), textBuffer.AsPointer());
}
/// <summary>Remove file (if exists)</summary>
public static int FileRemove(string filename)
{
using AnsiBuffer fileBuffer = filename.ToAnsiBuffer();
return FileRemove(fileBuffer.AsPointer());
}
/// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary>
public static int FileCopy(string srcPath, string dstPath)
{
using AnsiBuffer srcBuffer = srcPath.ToAnsiBuffer();
using AnsiBuffer dstBuffer = dstPath.ToAnsiBuffer();
return FileCopy(srcBuffer.AsPointer(), dstBuffer.AsPointer());
}
/// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary>
public static int FileMove(string srcPath, string dstPath)
{
using AnsiBuffer srcBuffer = srcPath.ToAnsiBuffer();
using AnsiBuffer dstBuffer = dstPath.ToAnsiBuffer();
return FileMove(srcBuffer.AsPointer(), dstBuffer.AsPointer());
}
/// <summary>Replace text in an existing file</summary>
public static int FileTextReplace(string fileName, string search, string replacement)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
using AnsiBuffer searchBuffer = search.ToAnsiBuffer();
using AnsiBuffer replaceBuffer = replacement.ToAnsiBuffer();
return FileTextReplace(fileBuffer.AsPointer(), searchBuffer.AsPointer(), replaceBuffer.AsPointer());
}
/// <summary>Find text in existing file</summary>
public static int FileTextFindIndex(string fileName, string search)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
using AnsiBuffer searchBuffer = search.ToAnsiBuffer();
return FileTextFindIndex(fileBuffer.AsPointer(), searchBuffer.AsPointer());
}
/// <summary>Check if file exists</summary>
public static CBool FileExists(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return FileExists(fileBuffer.AsPointer());
}
/// <summary>Check if a directory path exists</summary>
public static CBool DirectoryExists(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return DirectoryExists(dirBuffer.AsPointer());
}
/// <summary>Get file length in bytes</summary>
public static int GetFileLength(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return GetFileLength(fileBuffer.AsPointer());
}
/// <summary>Get string to extension for a filename string (includes dot: '.png')</summary>
public static string GetFileExtension(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return new string(GetFileExtension(fileBuffer.AsPointer()));
}
/// <summary>Get string to filename for a path string</summary>
public static string GetFileName(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return new string(GetFileName(fileBuffer.AsPointer()));
}
/// <summary>Get filename string without extension </summary>
public static string GetFileNameWithoutExt(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return new string(GetFileNameWithoutExt(fileBuffer.AsPointer()));
}
/// <summary>Get full path for a given fileName with path</summary>
public static string GetDirectoryPath(string filePath)
{
using AnsiBuffer fileBuffer = filePath.ToAnsiBuffer();
return new string(GetDirectoryPath(fileBuffer.AsPointer()));
}
/// <summary>Get previous directory path for a given path</summary>
public static string GetPrevDirectoryPath(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return new string(GetPrevDirectoryPath(dirBuffer.AsPointer()));
}
/// <summary>Get current working directory</summary>
public static string GetWorkingDirectoryAsString()
{
return new string(GetWorkingDirectory());
}
/// <summary>Get the directory of the running application</summary>
public static string GetApplicationDirectoryAsString()
{
return new string(GetApplicationDirectory());
}
/// <summary>Change working directory, return true on success</summary>
public static CBool ChangeDirectory(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return ChangeDirectory(dirBuffer.AsPointer());
}
/// <summary>Check if a given path is a file or a directory</summary>
public static CBool IsPathFile(string path)
{
using AnsiBuffer pathBuffer = path.ToAnsiBuffer();
return IsPathFile(pathBuffer.AsPointer());
}
/// <summary>Load directory filepaths</summary>
public static FilePathList LoadDirectoryFiles(string dirPath, out int count)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
int c = 0;
var result = LoadDirectoryFiles(dirBuffer.AsPointer(), &c);
count = c;
return result;
}
/// <summary>Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"</summary>
public static FilePathList LoadDirectoryFilesEx(string basePath, string filter, CBool scanSubDirs)
{
using AnsiBuffer baseBuffer = basePath.ToAnsiBuffer();
using AnsiBuffer filterBuffer = filter.ToAnsiBuffer();
return LoadDirectoryFilesEx(baseBuffer.AsPointer(), filterBuffer.AsPointer(), scanSubDirs);
}
/// <summary> /// <summary>
/// Loads text from a file, reads it, saves it, unloads the file, and returns the loaded text. /// Loads text from a file, reads it, saves it, unloads the file, and returns the loaded text.
/// </summary> /// </summary>
@ -1569,4 +1736,5 @@ public static unsafe partial class Raylib
center.Y = GetScreenHeight() / 2.0f; center.Y = GetScreenHeight() / 2.0f;
return center; return center;
} }
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Raylib_cs; namespace Raylib_cs;

View file

@ -21,6 +21,11 @@ public readonly ref struct Utf8Buffer
return (sbyte*)_data.ToPointer(); return (sbyte*)_data.ToPointer();
} }
public unsafe byte* AsBytePointer()
{
return (byte*)_data.ToPointer();
}
public void Dispose() public void Dispose()
{ {
Marshal.ZeroFreeCoTaskMemUTF8(_data); Marshal.ZeroFreeCoTaskMemUTF8(_data);