diff --git a/build.zig b/build.zig index 3511427..c0a65f2 100644 --- a/build.zig +++ b/build.zig @@ -82,6 +82,21 @@ pub fn build(b: *std.Build) !void { .path = "examples/audio/raw_stream.zig", .desc = "Plays a sine wave", }, + .{ + .name = "music_stream", + .path = "examples/audio/music_stream.zig", + .desc = "Use music stream to play an audio file", + }, + .{ + .name = "sound_loading", + .path = "examples/audio/sound_loading.zig", + .desc = "Load and play a song", + }, + .{ + .name = "module_playing", + .path = "examples/audio/module_playing.zig", + .desc = "Module playing (streaming)", + }, .{ .name = "basic_screen_manager", .path = "examples/core/basic_screen_manager.zig", @@ -142,6 +157,11 @@ pub fn build(b: *std.Build) !void { .path = "examples/core/window_flags.zig", .desc = "Demonstrates various flags used during and after window creation", }, + .{ + .name = "raymarching", + .path = "examples/shaders/raymarching.zig", + .desc = "Uses a raymarching in a shader to render shapes", + }, .{ .name = "texture_outline", .path = "examples/shaders/texture_outline.zig", @@ -222,17 +242,27 @@ pub fn build(b: *std.Build) !void { .path = "examples/text/text_format_text.zig", .desc = "Renders variables as text", }, + .{ + .name = "text_raylib_fonts", + .path = "examples/text/text_raylib_fonts.zig", + .desc = "Show fonts included with raylib", + }, + .{ + .name = "text_writing_anim", + .path = "examples/text/text_writing_anim.zig", + .desc = "Simple text animation", + }, .{ .name = "textures_image_loading", .path = "examples/textures/textures_image_loading.zig", .desc = "Image loading and texture creation", }, - // .{ - // .name = "models_loading", - // .path = "examples/models/models_loading.zig", - // .desc = "Loads a model and renders it", - // }, + .{ + .name = "models_heightmap", + .path = "examples/models/models_heightmap.zig", + .desc = "Heightmap loading and drawing", + }, // .{ // .name = "shaders_basic_lighting", // .path = "examples/shaders/shaders_basic_lighting.zig", diff --git a/examples/audio/module_playing.zig b/examples/audio/module_playing.zig new file mode 100644 index 0000000..9016557 --- /dev/null +++ b/examples/audio/module_playing.zig @@ -0,0 +1,141 @@ +const rl = @import("raylib"); + +const MAX_CIRCLES = 64; + +const CircleWave = struct { + position: rl.Vector2, + radius: f32, + alpha: f32, + speed: f32, + color: rl.Color, +}; + +const screenWidth = 800; +const screenHeight = 450; + +const colors = [14]rl.Color{ rl.Color.orange, rl.Color.red, rl.Color.gold, rl.Color.lime, rl.Color.blue, rl.Color.violet, rl.Color.brown, rl.Color.light_gray, rl.Color.pink, rl.Color.yellow, rl.Color.green, rl.Color.sky_blue, rl.Color.purple, rl.Color.beige }; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() !void { + // Initialization + //-------------------------------------------------------------------------------------- + rl.setConfigFlags(rl.ConfigFlags{ .msaa_4x_hint = true }); // NOTE: Try to enable MSAA 4X + + rl.initWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)"); + defer rl.closeWindow(); // Close window and OpenGL context + + rl.initAudioDevice(); // Initialize audio device + defer rl.closeAudioDevice(); // Close audio device (music streaming is automatically stopped) + + // Creates some circles for visual effect + var circles: [MAX_CIRCLES]CircleWave = undefined; + + for (&circles) |*circle| { + initCircle(circle); + } + + var music: rl.Music = try rl.loadMusicStream("resources/audio/mini1111.xm"); + defer rl.unloadMusicStream(music); // Unload music stream buffers from RAM + + music.looping = false; + var pitch: f32 = 1; + + rl.playMusicStream(music); + + var timePlayed: f32 = 0; + var pause: bool = false; + + rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) { // Detect window close button or ESC key + // Update + //---------------------------------------------------------------------------------- + rl.updateMusicStream(music); // Update music buffer with new stream data + + // Restart music playing (stop and play) + if (rl.isKeyPressed(rl.KeyboardKey.space)) { + rl.stopMusicStream(music); + rl.playMusicStream(music); + pause = false; + } + + // Pause/Resume music playing + if (rl.isKeyPressed(rl.KeyboardKey.p)) { + pause = !pause; + + if (pause) { + rl.pauseMusicStream(music); + } else { + rl.resumeMusicStream(music); + } + } + + if (rl.isKeyDown(rl.KeyboardKey.down)) { + pitch -= 0.01; + } else if (rl.isKeyDown(rl.KeyboardKey.up)) { + pitch += 0.01; + } + + rl.setMusicPitch(music, pitch); + + // Get timePlayed scaled to bar dimensions + timePlayed = rl.getMusicTimePlayed(music) / rl.getMusicTimeLength(music) * (screenWidth - 40); + + if (!pause) { + for (&circles) |*circle| { + circle.alpha += circle.speed; + circle.radius += circle.speed * 10.0; + + if (circle.alpha > 1.0) circle.speed *= -1; + + if (circle.alpha <= 0.0) { + initCircle(circle); + } + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + + rl.clearBackground(rl.Color.white); + + for (circles) |circle| { + rl.drawCircleV(circle.position, circle.radius, rl.fade(circle.color, circle.alpha)); + } + + // Draw time bar + rl.drawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, rl.Color.light_gray); + rl.drawRectangle(20, screenHeight - 20 - 12, @intFromFloat(timePlayed), 12, rl.Color.maroon); + rl.drawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, rl.Color.gray); + + // Draw help instructions + rl.drawRectangle(20, 20, 425, 145, rl.Color.white); + rl.drawRectangleLines(20, 20, 425, 145, rl.Color.gray); + rl.drawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, rl.Color.black); + rl.drawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, rl.Color.black); + rl.drawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, rl.Color.black); + rl.drawText(rl.textFormat("SPEED: %f", .{pitch}), 40, 130, 20, rl.Color.maroon); + + rl.endDrawing(); + //---------------------------------------------------------------------------------- + } +} + +fn initCircle(circle: *CircleWave) void { + circle.alpha = 0.0; + circle.radius = getRandomValuef32(10, 40); + circle.position.x = getRandomValuef32(@intFromFloat(circle.radius), @intFromFloat(screenWidth - circle.radius)); + circle.position.y = getRandomValuef32(@intFromFloat(circle.radius), @intFromFloat(screenHeight - circle.radius)); + circle.speed = getRandomValuef32(1, 100) / 2000.0; + circle.color = colors[@intCast(rl.getRandomValue(0, 13))]; +} + +fn getRandomValuef32(min: i32, max: i32) f32 { + return @as(f32, @floatFromInt(rl.getRandomValue(min, max))); +} diff --git a/examples/audio/music_stream.zig b/examples/audio/music_stream.zig new file mode 100644 index 0000000..66eef97 --- /dev/null +++ b/examples/audio/music_stream.zig @@ -0,0 +1,78 @@ +const rl = @import("raylib"); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() !void { + // Initialization + //-------------------------------------------------------------------------------------- + const screenWidth = 800; + const screenHeight = 450; + + rl.initWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)"); + defer rl.closeWindow(); // Close window and OpenGL context + + rl.initAudioDevice(); // Initialize audio device + defer rl.closeAudioDevice(); // Close audio device (music streaming is automatically stopped) + + const music: rl.Music = try rl.loadMusicStream("resources/audio/country.mp3"); + defer rl.unloadMusicStream(music); // Unload music stream buffers from RAM + + rl.playMusicStream(music); + + var timePlayed: f32 = 0; // Time played normalized [0.0f..1.0f] + var pause: bool = false; // Music playing paused + + rl.setTargetFPS(30); // Set our game to run at 30 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + rl.updateMusicStream(music); // Update music buffer with new stream data + + // Restart music playing (stop and play) + if (rl.isKeyPressed(rl.KeyboardKey.space)) { + rl.stopMusicStream(music); + rl.playMusicStream(music); + } + + // Pause/Resume music playing + if (rl.isKeyPressed(rl.KeyboardKey.p)) { + pause = !pause; + + if (pause) { + rl.pauseMusicStream(music); + } else { + rl.resumeMusicStream(music); + } + } + + // Get normalized time played for current music stream + timePlayed = rl.getMusicTimePlayed(music) / rl.getMusicTimeLength(music); + + if (timePlayed > 1.0) { + timePlayed = 1.0; // Make sure time played is no longer than music + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + defer rl.endDrawing(); + + rl.clearBackground(rl.Color.white); + + rl.drawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, rl.Color.light_gray); + + rl.drawRectangle(200, 200, 400, 12, rl.Color.light_gray); + rl.drawRectangle(200, 200, @intFromFloat(timePlayed * 400), 12, rl.Color.maroon); + rl.drawRectangleLines(200, 200, 400, 12, rl.Color.gray); + + rl.drawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, rl.Color.light_gray); + rl.drawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, rl.Color.light_gray); + //---------------------------------------------------------------------------------- + } +} diff --git a/examples/audio/sound_loading.zig b/examples/audio/sound_loading.zig new file mode 100644 index 0000000..faba5b8 --- /dev/null +++ b/examples/audio/sound_loading.zig @@ -0,0 +1,46 @@ +const rl = @import("raylib"); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() !void { + // Initialization + //-------------------------------------------------------------------------------------- + const screenWidth = 800; + const screenHeight = 450; + + rl.initWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing"); + defer rl.closeWindow(); // Close window and OpenGL context + + rl.initAudioDevice(); // Initialize audio device + defer rl.closeAudioDevice(); // Close audio device + + const fxWav: rl.Sound = try rl.loadSound("resources/audio/sound.wav"); // Load WAV audio file + const fxOgg: rl.Sound = try rl.loadSound("resources/audio/target.ogg"); // Load OGG audio file + defer rl.unloadSound(fxWav); // Unload sound data + defer rl.unloadSound(fxOgg); // Unload sound data + + rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (rl.isKeyPressed(rl.KeyboardKey.space)) rl.playSound(fxWav); // Play WAV sound + if (rl.isKeyPressed(rl.KeyboardKey.enter)) rl.playSound(fxOgg); // Play OGG sound + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + defer rl.endDrawing(); + + rl.clearBackground(rl.Color.white); + + rl.drawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, rl.Color.light_gray); + rl.drawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, rl.Color.light_gray); + //---------------------------------------------------------------------------------- + } +} diff --git a/examples/models/models_heightmap.zig b/examples/models/models_heightmap.zig new file mode 100644 index 0000000..425bf83 --- /dev/null +++ b/examples/models/models_heightmap.zig @@ -0,0 +1,49 @@ +const rl = @import("raylib"); + +pub fn main() anyerror!void { + const screenWidth: i32 = 800; + const screenHeight: i32 = 450; + + rl.initWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing"); + const cameraPosition: rl.Vector3 = .{ .x = 18, .y = 21, .z = 18 }; + const cameraTarget: rl.Vector3 = .{ .x = 0, .y = 0, .z = 0 }; + const cameraUp: rl.Vector3 = .{ .x = 0, .y = 1, .z = 0 }; + const cameraProjection = rl.CameraProjection.perspective; + var camera = rl.Camera{ .fovy = 45.0, .position = cameraPosition, .up = cameraUp, .projection = cameraProjection, .target = cameraTarget }; + + const image: rl.Image = try rl.loadImage("examples/models/resources/heightmap.png"); + + const texture: rl.Texture2D = try rl.loadTextureFromImage(image); + + const meshSize = rl.Vector3{ .x = 16, .y = 8, .z = 16 }; + const mesh = rl.genMeshHeightmap(image, meshSize); + + var model = try rl.loadModelFromMesh(mesh); + model.materials[0].maps[@intFromEnum(rl.MATERIAL_MAP_DIFFUSE)].texture = texture; + + const mapPosition = rl.Vector3{ .x = -8.0, .y = 0.0, .z = -8.0 }; + + rl.unloadImage(image); + + rl.setTargetFPS(60); + + while (!rl.windowShouldClose()) { + rl.updateCamera(&camera, rl.CameraMode.orbital); + rl.beginDrawing(); + + rl.clearBackground(rl.Color.ray_white); + rl.beginMode3D(camera); + rl.drawModel(model, mapPosition, 1, rl.Color.red); + rl.drawGrid(20, 1.0); + rl.endMode3D(); + rl.drawTexture(texture, screenWidth - texture.width - 20, 20, rl.Color.white); + rl.drawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, rl.Color.green); + rl.drawFPS(10, 10); + + rl.endDrawing(); + } + rl.unloadTexture(texture); + rl.unloadModel(model); + + rl.closeWindow(); +} diff --git a/examples/models/resources/heightmap.png b/examples/models/resources/heightmap.png new file mode 100644 index 0000000..474db87 Binary files /dev/null and b/examples/models/resources/heightmap.png differ diff --git a/examples/shaders/raymarching.zig b/examples/shaders/raymarching.zig new file mode 100644 index 0000000..d97b6b8 --- /dev/null +++ b/examples/shaders/raymarching.zig @@ -0,0 +1,117 @@ +// raylib [shaders] example - Raymarching shapes generation +// +// Example complexity rating: [★★★★] 4/4 +// +// NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330 +// is currently supported. OpenGL ES 2.0 platforms are not supported at the moment. +// +// Example originally created with raylib 2.0, 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) 2018-2025 Ramon Santamaria (@raysan5) + +const rl = @import("raylib"); +const std = @import("std"); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() anyerror!void { + // Initialization + //-------------------------------------------------------------------------------------- + const screenWidth = 800; + const screenHeight = 450; + + rl.setConfigFlags(rl.ConfigFlags{ .window_resizable = true }); + rl.initWindow(screenWidth, screenHeight, "raylib [shaders] example - raymarching shapes"); + defer rl.closeWindow(); // Close window and OpenGL context + + // Define the camera to look into our 3d world + var camera = rl.Camera3D{ + .position = .{ .x = 2.5, .y = 2.5, .z = 3.0 }, // Camera position + .target = .{ .x = 0.0, .y = 0.0, .z = 0.7 }, // Camera looking at point + .up = .{ .x = 0.0, .y = 1.0, .z = 0.0 }, // Camera up vector (rotation towards target) + .fovy = 65.0, // Camera field-of-view Y + .projection = .perspective, // Camera projection type + }; + + // Load raymarching shader + const shader = try rl.loadShader(null, "resources/shaders/glsl330/raymarching.fs"); + defer rl.unloadShader(shader); + + // Get shader locations for required uniforms + const viewEyeLoc = rl.getShaderLocation(shader, "viewEye"); + const viewCenterLoc = rl.getShaderLocation(shader, "viewCenter"); + const runTimeLoc = rl.getShaderLocation(shader, "runTime"); + const resolutionLoc = rl.getShaderLocation(shader, "resolution"); + + var resolution = [2]f32{ @floatFromInt(screenWidth), @floatFromInt(screenHeight) }; + rl.setShaderValue(shader, resolutionLoc, &resolution, .vec2); + + var runTime: f32 = 0.0; + + rl.disableCursor(); // Limit cursor to relative movement inside the window + rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) { // Detect window close button or ESC key + // Update + //---------------------------------------------------------------------------------- + rl.updateCamera(&camera, .first_person); + + const cameraPos = [3]f32{ camera.position.x, camera.position.y, camera.position.z }; + const cameraTarget = [3]f32{ camera.target.x, camera.target.y, camera.target.z }; + + const deltaTime = rl.getFrameTime(); + runTime += deltaTime; + + // Set shader required uniform values + rl.setShaderValue(shader, viewEyeLoc, &cameraPos, .vec3); + rl.setShaderValue(shader, viewCenterLoc, &cameraTarget, .vec3); + rl.setShaderValue(shader, runTimeLoc, &runTime, .float); + + // Check if screen is resized + if (rl.isWindowResized()) { + resolution = [2]f32{ + @floatFromInt(rl.getScreenWidth()), + @floatFromInt(rl.getScreenHeight()), + }; + rl.setShaderValue(shader, resolutionLoc, &resolution, .vec2); + } + + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + defer rl.endDrawing(); + + rl.clearBackground(rl.Color.ray_white); + + // We only draw a white full-screen rectangle, + // frame is generated in shader using raymarching + { + rl.beginShaderMode(shader); + defer rl.endShaderMode(); + + rl.drawRectangle( + 0, + 0, + rl.getScreenWidth(), + rl.getScreenHeight(), + rl.Color.white, + ); + } + + rl.drawText( + "(c) Raymarching shader by Iñigo Quilez. MIT License.", + rl.getScreenWidth() - 280, + rl.getScreenHeight() - 20, + 10, + rl.Color.black, + ); + //---------------------------------------------------------------------------------- + } +} + diff --git a/examples/shapes/colors_palette.zig b/examples/shapes/colors_palette.zig index 1d7bc37..09763a3 100644 --- a/examples/shapes/colors_palette.zig +++ b/examples/shapes/colors_palette.zig @@ -43,7 +43,7 @@ pub fn main() anyerror!void { rl.Color.beige, }; - const colorNames = [maxColorCount][*:0]const u8{ + const colorNames = [maxColorCount][:0]const u8{ "DARKGRAY", "MAROON", "ORANGE", diff --git a/examples/text/text_raylib_fonts.zig b/examples/text/text_raylib_fonts.zig new file mode 100644 index 0000000..9028a60 --- /dev/null +++ b/examples/text/text_raylib_fonts.zig @@ -0,0 +1,89 @@ +const rl = @import("raylib"); +const Color = rl.Color; + +const MAX_FONTS = 8; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() !void { + // Initialization + //-------------------------------------------------------------------------------------- + const screenWidth = 800; + const screenHeight = 450; + + rl.initWindow(screenWidth, screenHeight, "raylib [text] example - raylib fonts"); + defer rl.closeWindow(); // Close window and OpenGL context + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + var fonts: [MAX_FONTS]rl.Font = undefined; + + fonts[0] = try rl.loadFont("resources/text/fonts/alagard.png"); + fonts[1] = try rl.loadFont("resources/text/fonts/pixelplay.png"); + fonts[2] = try rl.loadFont("resources/text/fonts/mecha.png"); + fonts[3] = try rl.loadFont("resources/text/fonts/setback.png"); + fonts[4] = try rl.loadFont("resources/text/fonts/romulus.png"); + fonts[5] = try rl.loadFont("resources/text/fonts/pixantiqua.png"); + fonts[6] = try rl.loadFont("resources/text/fonts/alpha_beta.png"); + fonts[7] = try rl.loadFont("resources/text/fonts/jupiter_crash.png"); + + // Fonts unloading + defer for (fonts) |font| { + rl.unloadFont(font); + }; + + const messages = [MAX_FONTS][:0]const u8{ + "ALAGARD FONT designed by Hewett Tsoi", + "PIXELPLAY FONT designed by Aleksander Shevchuk", + "MECHA FONT designed by Captain Falcon", + "SETBACK FONT designed by Brian Kent (AEnigma)", + "ROMULUS FONT designed by Hewett Tsoi", + "PIXANTIQUA FONT designed by Gerhard Grossmann", + "ALPHA_BETA FONT designed by Brian Kent (AEnigma)", + "JUPITER_CRASH FONT designed by Brian Kent (AEnigma)", + }; + + const spacings = [_]i32{ 2, 4, 8, 4, 3, 4, 4, 1 }; + + var positions: [MAX_FONTS]rl.Vector2 = undefined; + for (0..MAX_FONTS) |i| { + const font_base_size = @as(f32, @floatFromInt(fonts[i].baseSize)); + positions[i].x = screenWidth / 2.0 - rl.measureTextEx(fonts[i], messages[i], font_base_size * 2.0, @floatFromInt(spacings[i])).x / 2.0; + positions[i].y = 60.0 + font_base_size + 45.0 * @as(f32, @floatFromInt(i)); + } + + // Small Y position corrections + positions[3].y += 8; + positions[4].y += 2; + positions[7].y -= 8; + + const colors = [MAX_FONTS]Color{ Color.maroon, Color.orange, Color.dark_green, Color.dark_blue, Color.dark_purple, Color.lime, Color.gold, Color.red }; + + rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) { // Detect window close button or ESC key + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + + rl.clearBackground(Color.white); + + rl.drawText("free fonts included with raylib", 250, 20, 20, Color.dark_gray); + rl.drawLine(220, 50, 590, 50, Color.dark_gray); + + for (0..MAX_FONTS) |i| { + const font_base_size = @as(f32, @floatFromInt(fonts[i].baseSize)); + rl.drawTextEx(fonts[i], messages[i], positions[i], font_base_size * 2.0, @floatFromInt(spacings[i]), colors[i]); + } + + rl.endDrawing(); + //---------------------------------------------------------------------------------- + } +} diff --git a/examples/text/text_writing_anim.zig b/examples/text/text_writing_anim.zig new file mode 100644 index 0000000..941ee71 --- /dev/null +++ b/examples/text/text_writing_anim.zig @@ -0,0 +1,46 @@ +const rl = @import("raylib"); +const Color = rl.Color; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() void { + // Initialization + //-------------------------------------------------------------------------------------- + const screenWidth = 800; + const screenHeight = 450; + + rl.initWindow(screenWidth, screenHeight, "raylib [text] example - text writing anim"); + defer rl.closeWindow(); // Close window and OpenGL context + + const message = "This sample illustrates a text writing\nanimation effect! Check it out! ;)"; + + var framesCounter: i32 = 0; + + rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + framesCounter += if (rl.isKeyDown(rl.KeyboardKey.space)) 8 else 1; + + if (rl.isKeyPressed(rl.KeyboardKey.enter)) framesCounter = 0; + //---------------------------------------------------------------------------------- + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + + rl.clearBackground(Color.white); + + rl.drawText(rl.textSubtext(message, 0, @divFloor(framesCounter, 10)), 210, 160, 20, Color.maroon); + + rl.drawText("PRESS [ENTER] to RESTART!", 240, 260, 20, Color.light_gray); + rl.drawText("HOLD [SPACE] to SPEED UP!", 239, 300, 20, Color.light_gray); + + rl.endDrawing(); + //---------------------------------------------------------------------------------- + } +} diff --git a/lib/generate_functions.py b/lib/generate_functions.py index d347817..0cee1c1 100755 --- a/lib/generate_functions.py +++ b/lib/generate_functions.py @@ -73,7 +73,7 @@ def ziggify_type(name: str, t: str, func_name) -> str: string = False if name == "text" and t == "[*c][*c]const u8": - return "[][*:0]const u8" + return "[][:0]const u8" if t.startswith("[*c]") and name not in single and name not in multi: if (t == "[*c]const u8" or t == "[*c]u8") and name not in NO_STRINGS: # Strings are multis. @@ -85,7 +85,7 @@ def ziggify_type(name: str, t: str, func_name) -> str: while t.startswith("[*c]"): t = t[4:] if string and not t.startswith("[*c]"): - pre += "[*:0]" + pre += "[:0]" elif name in single: pre += "*" else: @@ -366,6 +366,7 @@ def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str, "ComputeSHA1", "SetWindowIcons", "CheckCollisionPointPoly", + "ColorToInt", "GetFontDefault", "LoadFont", "LoadFontEx", diff --git a/lib/preludes/raylib-prelude.zig b/lib/preludes/raylib-prelude.zig index 7985ab8..eb4671d 100644 --- a/lib/preludes/raylib-prelude.zig +++ b/lib/preludes/raylib-prelude.zig @@ -850,17 +850,17 @@ pub const Image = extern struct { format: PixelFormat, /// Load image from file into CPU memory (RAM) - pub fn init(fileName: [*:0]const u8) RaylibError!Image { + pub fn init(fileName: [:0]const u8) RaylibError!Image { return rl.loadImage(fileName); } /// Load image from RAW file data - pub fn initRaw(fileName: [*:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { + pub fn initRaw(fileName: [:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { return rl.loadImageRaw(fileName, width, height, format, headerSize); } /// Load image sequence from file (frames appended to image.data) - pub fn initAnim(fileName: [*:0]const u8, frames: *i32) RaylibError!Image { + pub fn initAnim(fileName: [:0]const u8, frames: *i32) RaylibError!Image { return rl.loadImageAnim(fileName, frames); } @@ -880,12 +880,12 @@ pub const Image = extern struct { } /// Create an image from text (default font) - pub fn initText(text: [*:0]const u8, fontSize: i32, color: Color) RaylibError!Image { + pub fn initText(text: [:0]const u8, fontSize: i32, color: Color) RaylibError!Image { return rl.imageText(text, fontSize, color); } /// Create an image from text (custom sprite font) - pub fn initTextEx(font: Font, text: [*:0]const u8, fontSize: f32, spacing: f32, t: Color) RaylibError!Image { + pub fn initTextEx(font: Font, text: [:0]const u8, fontSize: f32, spacing: f32, t: Color) RaylibError!Image { return rl.imageTextEx(font, text, fontSize, spacing, t); } @@ -930,7 +930,7 @@ pub const Image = extern struct { } /// Generate image: grayscale image from text data - pub fn genText(width: i32, height: i32, text: [*:0]const u8) Image { + pub fn genText(width: i32, height: i32, text: [:0]const u8) Image { return rl.genImageText(width, height, text); } @@ -1145,22 +1145,22 @@ pub const Image = extern struct { } /// Draw text (using default font) within an image (destination) - pub fn drawText(self: *Image, text: [*:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { + pub fn drawText(self: *Image, text: [:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { rl.imageDrawText(self, text, posX, posY, fontSize, color); } /// Draw text (custom sprite font) within an image (destination) - pub fn drawTextEx(self: *Image, font: Font, text: [*:0]const u8, position: Vector2, fontSize: f32, spacing: f32, t: Color) void { + pub fn drawTextEx(self: *Image, font: Font, text: [:0]const u8, position: Vector2, fontSize: f32, spacing: f32, t: Color) void { rl.imageDrawTextEx(self, font, text, position, fontSize, spacing, t); } /// Export image data to file, returns true on success - pub fn exportToFile(self: Image, fileName: [*:0]const u8) bool { + pub fn exportToFile(self: Image, fileName: [:0]const u8) bool { return rl.exportImage(self, fileName); } /// Export image as code file defining an array of bytes, returns true on success - pub fn exportAsCode(self: Image, fileName: [*:0]const u8) bool { + pub fn exportAsCode(self: Image, fileName: [:0]const u8) bool { return rl.exportImageAsCode(self, fileName); } @@ -1186,7 +1186,7 @@ pub const Texture = extern struct { mipmaps: c_int, format: PixelFormat, - pub fn init(fileName: [*:0]const u8) RaylibError!Texture { + pub fn init(fileName: [:0]const u8) RaylibError!Texture { return rl.loadTexture(fileName); } @@ -1290,12 +1290,12 @@ pub const Font = extern struct { glyphs: [*c]GlyphInfo, /// Load font from file into GPU memory (VRAM) - pub fn init(fileName: [*:0]const u8) RaylibError!Font { + pub fn init(fileName: [:0]const u8) RaylibError!Font { return rl.loadFont(fileName); } /// Load font from file with extended parameters, use null for fontChars to load the default character set - pub fn initEx(fileName: [*:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { + pub fn initEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { return rl.loadFontEx(fileName, fontSize, fontChars); } @@ -1305,7 +1305,7 @@ pub const Font = extern struct { } /// Load font from memory buffer, fileType refers to extension: i.e. '.ttf' - pub fn fromMemory(fileType: [*:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { + pub fn fromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { return rl.loadFontFromMemory(fileType, fileData, fontSize, fontChars); } @@ -1320,7 +1320,7 @@ pub const Font = extern struct { } /// Export font as code file, returns true on success - pub fn exportAsCode(self: Font, fileName: [*:0]const u8) bool { + pub fn exportAsCode(self: Font, fileName: [:0]const u8) bool { return rl.exportFontAsCode(self, fileName); } }; @@ -1456,7 +1456,7 @@ pub const Model = extern struct { bindPose: [*c]Transform, /// Load model from file (meshes and materials) - pub fn init(fileName: [*:0]const u8) RaylibError!Model { + pub fn init(fileName: [:0]const u8) RaylibError!Model { return rl.loadModel(fileName); } @@ -1993,7 +1993,7 @@ pub fn setWindowIcons(images: []Image) void { } /// Load shader from files and bind default locations -pub fn loadShader(vsFileName: ?[*:0]const u8, fsFileName: ?[*:0]const u8) RaylibError!Shader { +pub fn loadShader(vsFileName: ?[:0]const u8, fsFileName: ?[:0]const u8) RaylibError!Shader { var vsFileNameFinal = @as([*c]const u8, 0); var fsFileNameFinal = @as([*c]const u8, 0); if (vsFileName) |vsFileNameSure| { @@ -2008,7 +2008,7 @@ pub fn loadShader(vsFileName: ?[*:0]const u8, fsFileName: ?[*:0]const u8) Raylib } /// Load shader from code strings and bind default locations -pub fn loadShaderFromMemory(vsCode: ?[*:0]const u8, fsCode: ?[*:0]const u8) RaylibError!Shader { +pub fn loadShaderFromMemory(vsCode: ?[:0]const u8, fsCode: ?[:0]const u8) RaylibError!Shader { var vsCodeFinal = @as([*c]const u8, 0); var fsCodeFinal = @as([*c]const u8, 0); if (vsCode) |vsCodeSure| { @@ -2023,7 +2023,7 @@ pub fn loadShaderFromMemory(vsCode: ?[*:0]const u8, fsCode: ?[*:0]const u8) Rayl } /// Load file data as byte array (read) -pub fn loadFileData(fileName: [*:0]const u8) RaylibError![]u8 { +pub fn loadFileData(fileName: [:0]const u8) RaylibError![]u8 { var bytesRead: i32 = 0; var res: []u8 = undefined; @@ -2036,12 +2036,12 @@ pub fn loadFileData(fileName: [*:0]const u8) RaylibError![]u8 { } /// Save data to file from byte array (write), returns true on success -pub fn saveFileData(fileName: [*:0]const u8, data: []u8) bool { +pub fn saveFileData(fileName: [:0]const u8, data: []u8) bool { return cdef.SaveFileData(@as([*c]const u8, @ptrCast(fileName)), @as(*anyopaque, @ptrCast(data.ptr)), @as(c_int, @intCast(data.len))); } /// Export data to code (.h), returns true on success -pub fn exportDataAsCode(data: []const u8, fileName: [*:0]const u8) bool { +pub fn exportDataAsCode(data: []const u8, fileName: [:0]const u8) bool { return cdef.ExportDataAsCode(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]const u8, @ptrCast(fileName))); } @@ -2096,21 +2096,21 @@ pub fn computeSHA1(data: []u8) [5]u32 { } /// Load image from file into CPU memory (RAM) -pub fn loadImage(fileName: [*:0]const u8) RaylibError!Image { +pub fn loadImage(fileName: [:0]const u8) RaylibError!Image { const image = cdef.LoadImage(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Load image from RAW file data -pub fn loadImageRaw(fileName: [*:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { +pub fn loadImageRaw(fileName: [:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { const image = cdef.LoadImageRaw(@as([*c]const u8, @ptrCast(fileName)), @as(c_int, width), @as(c_int, height), format, @as(c_int, headerSize)); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Load image sequence from file (frames appended to image.data) -pub fn loadImageAnim(fileName: [*:0]const u8, frames: *i32) RaylibError!Image { +pub fn loadImageAnim(fileName: [:0]const u8, frames: *i32) RaylibError!Image { const image = cdef.LoadImageAnim(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(frames))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; @@ -2130,21 +2130,21 @@ pub fn loadImageFromScreen() RaylibError!Image { return if (isValid) image else RaylibError.LoadImage; } -pub fn loadImageAnimFromMemory(fileType: [*:0]const u8, fileData: []const u8, frames: *i32) RaylibError!Image { +pub fn loadImageAnimFromMemory(fileType: [:0]const u8, fileData: []const u8, frames: *i32) RaylibError!Image { const image = cdef.LoadImageAnimFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len)), @as([*c]c_int, @ptrCast(frames))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Load image from memory buffer, fileType refers to extension: i.e. '.png' -pub fn loadImageFromMemory(fileType: [*:0]const u8, fileData: []const u8) RaylibError!Image { +pub fn loadImageFromMemory(fileType: [:0]const u8, fileData: []const u8) RaylibError!Image { const image = cdef.LoadImageFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Create an image from text (default font) -pub fn imageText(text: [*:0]const u8, fontSize: i32, color: Color) RaylibError!Image { +pub fn imageText(text: [:0]const u8, fontSize: i32, color: Color) RaylibError!Image { // TODO: ImageText requires SUPPORT_MODULE_RTEXT. Error out if not loaded. const image = cdef.ImageText(@as([*c]const u8, @ptrCast(text)), @as(c_int, fontSize), color); const isValid = cdef.IsImageValid(image); @@ -2152,7 +2152,7 @@ pub fn imageText(text: [*:0]const u8, fontSize: i32, color: Color) RaylibError!I } /// Create an image from text (custom sprite font) -pub fn imageTextEx(font: Font, text: [*:0]const u8, fontSize: f32, spacing: f32, tint: Color) RaylibError!Image { +pub fn imageTextEx(font: Font, text: [:0]const u8, fontSize: f32, spacing: f32, tint: Color) RaylibError!Image { // TODO: ImageTextEx requires SUPPORT_MODULE_RTEXT. Error out if not loaded. const image = cdef.ImageTextEx(font, @as([*c]const u8, @ptrCast(text)), fontSize, spacing, tint); const isValid = cdef.IsImageValid(image); @@ -2185,7 +2185,7 @@ pub fn loadImagePalette(image: Image, maxPaletteSize: i32) RaylibError![]Color { } /// Load texture from file into GPU memory (VRAM) -pub fn loadTexture(fileName: [*:0]const u8) RaylibError!Texture2D { +pub fn loadTexture(fileName: [:0]const u8) RaylibError!Texture2D { const texture = cdef.LoadTexture(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsTextureValid(texture); return if (isValid) texture else RaylibError.LoadTexture; @@ -2212,6 +2212,13 @@ pub fn loadRenderTexture(width: i32, height: i32) RaylibError!RenderTexture2D { return if (isValid) render_texture else RaylibError.LoadRenderTexture; } +pub fn colorToInt(color: Color) i32 { + return if (@inComptime()) + (@as(i32, color.r) << 24) | (@as(i32, color.g) << 16) | (@as(i32, color.b) << 8) | @as(i32, color.a) + else + @as(i32, cdef.ColorToInt(color)); +} + /// Get the default Font pub fn getFontDefault() RaylibError!Font { // TODO: GetFontDefault requires SUPPORT_DEFAULT_FONT. Error out if unset. @@ -2221,14 +2228,14 @@ pub fn getFontDefault() RaylibError!Font { } /// Load font from file into GPU memory (VRAM) -pub fn loadFont(fileName: [*:0]const u8) RaylibError!Font { +pub fn loadFont(fileName: [:0]const u8) RaylibError!Font { const font = cdef.LoadFont(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsFontValid(font); return if (isValid) font else RaylibError.LoadFont; } /// Load font from file with extended parameters, use null for fontChars to load the default character set -pub fn loadFontEx(fileName: [*:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { +pub fn loadFontEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { var fontCharsFinal = @as([*c]c_int, 0); var fontCharsLen: c_int = @as(c_int, 0); if (fontChars) |fontCharsSure| { @@ -2241,7 +2248,7 @@ pub fn loadFontEx(fileName: [*:0]const u8, fontSize: i32, fontChars: ?[]i32) Ray } /// Load font from memory buffer, fileType refers to extension: i.e. '.ttf' -pub fn loadFontFromMemory(fileType: [*:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { +pub fn loadFontFromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { var fileDataFinal = @as([*c]const u8, 0); var fileDataLen: i32 = 0; if (fileData) |fileDataSure| { @@ -2274,7 +2281,7 @@ pub fn loadFontData(fileData: []const u8, fontSize: i32, fontChars: []i32, ty: F } /// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter -pub fn loadCodepoints(text: [*:0]const u8) RaylibError![]i32 { +pub fn loadCodepoints(text: [:0]const u8) RaylibError![]i32 { if (@sizeOf(c_int) != @sizeOf(i32)) { @compileError("Can't cast pointer to c_int array to i32 because they don't have the same size"); } @@ -2290,7 +2297,7 @@ pub fn loadCodepoints(text: [*:0]const u8) RaylibError![]i32 { } /// Text formatting with variables (sprintf() style) -pub fn textFormat(text: [*:0]const u8, args: anytype) [*:0]const u8 { +pub fn textFormat(text: [:0]const u8, args: anytype) [:0]const u8 { comptime { const info = @typeInfo(@TypeOf(args)); switch (info) { @@ -2308,7 +2315,7 @@ pub fn textFormat(text: [*:0]const u8, args: anytype) [*:0]const u8 { } /// Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) -pub fn traceLog(logLevel: TraceLogLevel, text: [*:0]const u8, args: anytype) void { +pub fn traceLog(logLevel: TraceLogLevel, text: [:0]const u8, args: anytype) void { comptime { const info = @typeInfo(@TypeOf(args)); switch (info) { @@ -2326,10 +2333,10 @@ pub fn traceLog(logLevel: TraceLogLevel, text: [*:0]const u8, args: anytype) voi } /// Split text into multiple strings -pub fn textSplit(text: [*:0]const u8, delimiter: u8) [][*:0]const u8 { +pub fn textSplit(text: [:0]const u8, delimiter: u8) [][:0]const u8 { var count: i32 = 0; - var res: [][*:0]const u8 = undefined; - res.ptr = @as([*][*:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count))))); + var res: [][:0]const u8 = undefined; + res.ptr = @as([*][:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count))))); res.len = @as(usize, @intCast(count)); return res; } @@ -2347,7 +2354,7 @@ pub fn loadMaterialDefault() RaylibError!Material { } /// Load materials from model file -pub fn loadMaterials(fileName: [*:0]const u8) RaylibError![]Material { +pub fn loadMaterials(fileName: [:0]const u8) RaylibError![]Material { var materialCount: i32 = 0; var res: []Material = undefined; @@ -2366,7 +2373,7 @@ pub fn loadMaterials(fileName: [*:0]const u8) RaylibError![]Material { } /// Load model from files (meshes and materials) -pub fn loadModel(fileName: [*:0]const u8) RaylibError!Model { +pub fn loadModel(fileName: [:0]const u8) RaylibError!Model { const model = cdef.LoadModel(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsModelValid(model); return if (isValid) model else RaylibError.LoadModel; @@ -2380,7 +2387,7 @@ pub fn loadModelFromMesh(mesh: Mesh) RaylibError!Model { } /// Load model animations from file -pub fn loadModelAnimations(fileName: [*:0]const u8) RaylibError![]ModelAnimation { +pub fn loadModelAnimations(fileName: [:0]const u8) RaylibError![]ModelAnimation { var animCount: i32 = 0; var res: []ModelAnimation = undefined; @@ -2398,21 +2405,21 @@ pub fn unloadModelAnimations(animations: []ModelAnimation) void { } /// Load sound from file -pub fn loadSound(fileName: [*:0]const u8) RaylibError!Sound { +pub fn loadSound(fileName: [:0]const u8) RaylibError!Sound { const sound = cdef.LoadSound(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsSoundValid(sound); return if (isValid) sound else RaylibError.LoadSound; } /// Load wave data from file -pub fn loadWave(fileName: [*:0]const u8) RaylibError!Wave { +pub fn loadWave(fileName: [:0]const u8) RaylibError!Wave { const wave = cdef.LoadWave(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsWaveValid(wave); return if (isValid) wave else RaylibError.LoadWave; } /// Load wave from memory buffer, fileType refers to extension: i.e. '.wav' -pub fn loadWaveFromMemory(fileType: [*:0]const u8, fileData: []const u8) RaylibError!Wave { +pub fn loadWaveFromMemory(fileType: [:0]const u8, fileData: []const u8) RaylibError!Wave { const wave = cdef.LoadWaveFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len))); const isValid = cdef.IsWaveValid(wave); return if (isValid) wave else RaylibError.LoadWave; @@ -2427,14 +2434,14 @@ pub fn loadWaveSamples(wave: Wave) []f32 { } /// Load music stream from file -pub fn loadMusicStream(fileName: [*:0]const u8) RaylibError!Music { +pub fn loadMusicStream(fileName: [:0]const u8) RaylibError!Music { const music = cdef.LoadMusicStream(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsMusicValid(music); return if (isValid) music else RaylibError.LoadMusic; } /// Load music stream from data -pub fn loadMusicStreamFromMemory(fileType: [*:0]const u8, data: []const u8) RaylibError!Music { +pub fn loadMusicStreamFromMemory(fileType: [:0]const u8, data: []const u8) RaylibError!Music { const music = cdef.LoadMusicStreamFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len))); const isValid = cdef.IsMusicValid(music); return if (isValid) music else RaylibError.LoadMusic; @@ -2514,12 +2521,12 @@ pub fn drawTextCodepoints(font: Font, codepoints: []const c_int, position: Vecto } /// Load UTF-8 text encoded from codepoints array -pub fn loadUTF8(codepoints: []const c_int) [*:0]u8 { +pub fn loadUTF8(codepoints: []const c_int) [:0]u8 { return std.mem.span(cdef.LoadUTF8(@as([*c]const c_int, @ptrCast(codepoints)), @as(c_int, @intCast(codepoints.len)))); } /// Join text strings with delimiter -pub fn textJoin(textList: [][*:0]u8, delimiter: [*:0]const u8) [*:0]const u8 { +pub fn textJoin(textList: [][:0]u8, delimiter: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.TextJoin(@as([*c][*c]u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter)))); } diff --git a/lib/raygui.zig b/lib/raygui.zig index 725b49a..e5590a3 100644 --- a/lib/raygui.zig +++ b/lib/raygui.zig @@ -550,7 +550,7 @@ pub fn guiGetFont() Font { } /// Load style file over global style variable (.rgs) -pub fn guiLoadStyle(fileName: [*:0]const u8) void { +pub fn guiLoadStyle(fileName: [:0]const u8) void { cdef.GuiLoadStyle(@as([*c]const u8, @ptrCast(fileName))); } @@ -570,12 +570,12 @@ pub fn guiDisableTooltip() void { } /// Set tooltip string -pub fn guiSetTooltip(tooltip: [*:0]const u8) void { +pub fn guiSetTooltip(tooltip: [:0]const u8) void { cdef.GuiSetTooltip(@as([*c]const u8, @ptrCast(tooltip))); } /// Get text with icon id prepended (if supported) -pub fn guiIconText(iconId: i32, text: [*:0]const u8) [*:0]const u8 { +pub fn guiIconText(iconId: i32, text: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.GuiIconText(@as(c_int, iconId), @as([*c]const u8, @ptrCast(text)))); } @@ -590,156 +590,156 @@ pub fn guiDrawIcon(iconId: i32, posX: i32, posY: i32, pixelSize: i32, color: Col } /// Window Box control, shows a window that can be closed -pub fn guiWindowBox(bounds: Rectangle, title: [*:0]const u8) i32 { +pub fn guiWindowBox(bounds: Rectangle, title: [:0]const u8) i32 { return @as(i32, cdef.GuiWindowBox(bounds, @as([*c]const u8, @ptrCast(title)))); } /// Group Box control with text name -pub fn guiGroupBox(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiGroupBox(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiGroupBox(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Line separator control, could contain text -pub fn guiLine(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiLine(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiLine(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Label control -pub fn guiLabel(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiLabel(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiLabel(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Button control, returns true when clicked -pub fn guiButton(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiButton(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiButton(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Label button control, returns true when clicked -pub fn guiLabelButton(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiLabelButton(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiLabelButton(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Toggle Button control -pub fn guiToggle(bounds: Rectangle, text: [*:0]const u8, active: *bool) i32 { +pub fn guiToggle(bounds: Rectangle, text: [:0]const u8, active: *bool) i32 { return @as(i32, cdef.GuiToggle(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]bool, @ptrCast(active)))); } /// Toggle Group control -pub fn guiToggleGroup(bounds: Rectangle, text: [*:0]const u8, active: *i32) i32 { +pub fn guiToggleGroup(bounds: Rectangle, text: [:0]const u8, active: *i32) i32 { return @as(i32, cdef.GuiToggleGroup(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(active)))); } /// Toggle Slider control -pub fn guiToggleSlider(bounds: Rectangle, text: [*:0]const u8, active: *i32) i32 { +pub fn guiToggleSlider(bounds: Rectangle, text: [:0]const u8, active: *i32) i32 { return @as(i32, cdef.GuiToggleSlider(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(active)))); } /// Check Box control, returns true when active -pub fn guiCheckBox(bounds: Rectangle, text: [*:0]const u8, checked: *bool) i32 { +pub fn guiCheckBox(bounds: Rectangle, text: [:0]const u8, checked: *bool) i32 { return @as(i32, cdef.GuiCheckBox(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]bool, @ptrCast(checked)))); } /// Combo Box control -pub fn guiComboBox(bounds: Rectangle, text: [*:0]const u8, active: *i32) i32 { +pub fn guiComboBox(bounds: Rectangle, text: [:0]const u8, active: *i32) i32 { return @as(i32, cdef.GuiComboBox(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(active)))); } /// Dropdown Box control -pub fn guiDropdownBox(bounds: Rectangle, text: [*:0]const u8, active: *i32, editMode: bool) i32 { +pub fn guiDropdownBox(bounds: Rectangle, text: [:0]const u8, active: *i32, editMode: bool) i32 { return @as(i32, cdef.GuiDropdownBox(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(active)), editMode)); } /// Spinner control -pub fn guiSpinner(bounds: Rectangle, text: [*:0]const u8, value: *i32, minValue: i32, maxValue: i32, editMode: bool) i32 { +pub fn guiSpinner(bounds: Rectangle, text: [:0]const u8, value: *i32, minValue: i32, maxValue: i32, editMode: bool) i32 { return @as(i32, cdef.GuiSpinner(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(value)), @as(c_int, minValue), @as(c_int, maxValue), editMode)); } /// Value Box control, updates input text with numbers -pub fn guiValueBox(bounds: Rectangle, text: [*:0]const u8, value: *i32, minValue: i32, maxValue: i32, editMode: bool) i32 { +pub fn guiValueBox(bounds: Rectangle, text: [:0]const u8, value: *i32, minValue: i32, maxValue: i32, editMode: bool) i32 { return @as(i32, cdef.GuiValueBox(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(value)), @as(c_int, minValue), @as(c_int, maxValue), editMode)); } /// Value box control for float values -pub fn guiValueBoxFloat(bounds: Rectangle, text: [*:0]const u8, textValue: [*:0]u8, value: *f32, editMode: bool) i32 { +pub fn guiValueBoxFloat(bounds: Rectangle, text: [:0]const u8, textValue: [:0]u8, value: *f32, editMode: bool) i32 { return @as(i32, cdef.GuiValueBoxFloat(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]u8, @ptrCast(textValue)), @as([*c]f32, @ptrCast(value)), editMode)); } /// Text Box control, updates input text -pub fn guiTextBox(bounds: Rectangle, text: [*:0]u8, textSize: i32, editMode: bool) i32 { +pub fn guiTextBox(bounds: Rectangle, text: [:0]u8, textSize: i32, editMode: bool) i32 { return @as(i32, cdef.GuiTextBox(bounds, @as([*c]u8, @ptrCast(text)), @as(c_int, textSize), editMode)); } /// Slider control -pub fn guiSlider(bounds: Rectangle, textLeft: [*:0]const u8, textRight: [*:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { +pub fn guiSlider(bounds: Rectangle, textLeft: [:0]const u8, textRight: [:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { return @as(i32, cdef.GuiSlider(bounds, @as([*c]const u8, @ptrCast(textLeft)), @as([*c]const u8, @ptrCast(textRight)), @as([*c]f32, @ptrCast(value)), minValue, maxValue)); } /// Slider Bar control -pub fn guiSliderBar(bounds: Rectangle, textLeft: [*:0]const u8, textRight: [*:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { +pub fn guiSliderBar(bounds: Rectangle, textLeft: [:0]const u8, textRight: [:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { return @as(i32, cdef.GuiSliderBar(bounds, @as([*c]const u8, @ptrCast(textLeft)), @as([*c]const u8, @ptrCast(textRight)), @as([*c]f32, @ptrCast(value)), minValue, maxValue)); } /// Progress Bar control -pub fn guiProgressBar(bounds: Rectangle, textLeft: [*:0]const u8, textRight: [*:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { +pub fn guiProgressBar(bounds: Rectangle, textLeft: [:0]const u8, textRight: [:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { return @as(i32, cdef.GuiProgressBar(bounds, @as([*c]const u8, @ptrCast(textLeft)), @as([*c]const u8, @ptrCast(textRight)), @as([*c]f32, @ptrCast(value)), minValue, maxValue)); } /// Status Bar control, shows info text -pub fn guiStatusBar(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiStatusBar(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiStatusBar(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Dummy control for placeholders -pub fn guiDummyRec(bounds: Rectangle, text: [*:0]const u8) i32 { +pub fn guiDummyRec(bounds: Rectangle, text: [:0]const u8) i32 { return @as(i32, cdef.GuiDummyRec(bounds, @as([*c]const u8, @ptrCast(text)))); } /// Grid control -pub fn guiGrid(bounds: Rectangle, text: [*:0]const u8, spacing: f32, subdivs: i32, mouseCell: *Vector2) i32 { +pub fn guiGrid(bounds: Rectangle, text: [:0]const u8, spacing: f32, subdivs: i32, mouseCell: *Vector2) i32 { return @as(i32, cdef.GuiGrid(bounds, @as([*c]const u8, @ptrCast(text)), spacing, @as(c_int, subdivs), @as([*c]Vector2, @ptrCast(mouseCell)))); } /// List View control -pub fn guiListView(bounds: Rectangle, text: [*:0]const u8, scrollIndex: *i32, active: *i32) i32 { +pub fn guiListView(bounds: Rectangle, text: [:0]const u8, scrollIndex: *i32, active: *i32) i32 { return @as(i32, cdef.GuiListView(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(scrollIndex)), @as([*c]c_int, @ptrCast(active)))); } /// Message Box control, displays a message -pub fn guiMessageBox(bounds: Rectangle, title: [*:0]const u8, message: [*:0]const u8, buttons: [*:0]const u8) i32 { +pub fn guiMessageBox(bounds: Rectangle, title: [:0]const u8, message: [:0]const u8, buttons: [:0]const u8) i32 { return @as(i32, cdef.GuiMessageBox(bounds, @as([*c]const u8, @ptrCast(title)), @as([*c]const u8, @ptrCast(message)), @as([*c]const u8, @ptrCast(buttons)))); } /// Text Input Box control, ask for text, supports secret -pub fn guiTextInputBox(bounds: Rectangle, title: [*:0]const u8, message: [*:0]const u8, buttons: [*:0]const u8, text: [*:0]u8, textMaxSize: i32, secretViewActive: *bool) i32 { +pub fn guiTextInputBox(bounds: Rectangle, title: [:0]const u8, message: [:0]const u8, buttons: [:0]const u8, text: [:0]u8, textMaxSize: i32, secretViewActive: *bool) i32 { return @as(i32, cdef.GuiTextInputBox(bounds, @as([*c]const u8, @ptrCast(title)), @as([*c]const u8, @ptrCast(message)), @as([*c]const u8, @ptrCast(buttons)), @as([*c]u8, @ptrCast(text)), @as(c_int, textMaxSize), @as([*c]bool, @ptrCast(secretViewActive)))); } /// Color Picker control (multiple color controls) -pub fn guiColorPicker(bounds: Rectangle, text: [*:0]const u8, color: *Color) i32 { +pub fn guiColorPicker(bounds: Rectangle, text: [:0]const u8, color: *Color) i32 { return @as(i32, cdef.GuiColorPicker(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]Color, @ptrCast(color)))); } /// Color Panel control -pub fn guiColorPanel(bounds: Rectangle, text: [*:0]const u8, color: *Color) i32 { +pub fn guiColorPanel(bounds: Rectangle, text: [:0]const u8, color: *Color) i32 { return @as(i32, cdef.GuiColorPanel(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]Color, @ptrCast(color)))); } /// Color Bar Alpha control -pub fn guiColorBarAlpha(bounds: Rectangle, text: [*:0]const u8, alpha: *f32) i32 { +pub fn guiColorBarAlpha(bounds: Rectangle, text: [:0]const u8, alpha: *f32) i32 { return @as(i32, cdef.GuiColorBarAlpha(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]f32, @ptrCast(alpha)))); } /// Color Bar Hue control -pub fn guiColorBarHue(bounds: Rectangle, text: [*:0]const u8, value: *f32) i32 { +pub fn guiColorBarHue(bounds: Rectangle, text: [:0]const u8, value: *f32) i32 { return @as(i32, cdef.GuiColorBarHue(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]f32, @ptrCast(value)))); } /// Color Picker control that avoids conversion to RGB on each call (multiple color controls) -pub fn guiColorPickerHSV(bounds: Rectangle, text: [*:0]const u8, colorHsv: *Vector3) i32 { +pub fn guiColorPickerHSV(bounds: Rectangle, text: [:0]const u8, colorHsv: *Vector3) i32 { return @as(i32, cdef.GuiColorPickerHSV(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]Vector3, @ptrCast(colorHsv)))); } /// Color Panel control that updates Hue-Saturation-Value color value, used by GuiColorPickerHSV() -pub fn guiColorPanelHSV(bounds: Rectangle, text: [*:0]const u8, colorHsv: *Vector3) i32 { +pub fn guiColorPanelHSV(bounds: Rectangle, text: [:0]const u8, colorHsv: *Vector3) i32 { return @as(i32, cdef.GuiColorPanelHSV(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]Vector3, @ptrCast(colorHsv)))); } diff --git a/lib/raylib.zig b/lib/raylib.zig index 416a2f0..f03dc08 100644 --- a/lib/raylib.zig +++ b/lib/raylib.zig @@ -850,17 +850,17 @@ pub const Image = extern struct { format: PixelFormat, /// Load image from file into CPU memory (RAM) - pub fn init(fileName: [*:0]const u8) RaylibError!Image { + pub fn init(fileName: [:0]const u8) RaylibError!Image { return rl.loadImage(fileName); } /// Load image from RAW file data - pub fn initRaw(fileName: [*:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { + pub fn initRaw(fileName: [:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { return rl.loadImageRaw(fileName, width, height, format, headerSize); } /// Load image sequence from file (frames appended to image.data) - pub fn initAnim(fileName: [*:0]const u8, frames: *i32) RaylibError!Image { + pub fn initAnim(fileName: [:0]const u8, frames: *i32) RaylibError!Image { return rl.loadImageAnim(fileName, frames); } @@ -880,12 +880,12 @@ pub const Image = extern struct { } /// Create an image from text (default font) - pub fn initText(text: [*:0]const u8, fontSize: i32, color: Color) RaylibError!Image { + pub fn initText(text: [:0]const u8, fontSize: i32, color: Color) RaylibError!Image { return rl.imageText(text, fontSize, color); } /// Create an image from text (custom sprite font) - pub fn initTextEx(font: Font, text: [*:0]const u8, fontSize: f32, spacing: f32, t: Color) RaylibError!Image { + pub fn initTextEx(font: Font, text: [:0]const u8, fontSize: f32, spacing: f32, t: Color) RaylibError!Image { return rl.imageTextEx(font, text, fontSize, spacing, t); } @@ -930,7 +930,7 @@ pub const Image = extern struct { } /// Generate image: grayscale image from text data - pub fn genText(width: i32, height: i32, text: [*:0]const u8) Image { + pub fn genText(width: i32, height: i32, text: [:0]const u8) Image { return rl.genImageText(width, height, text); } @@ -1145,22 +1145,22 @@ pub const Image = extern struct { } /// Draw text (using default font) within an image (destination) - pub fn drawText(self: *Image, text: [*:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { + pub fn drawText(self: *Image, text: [:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { rl.imageDrawText(self, text, posX, posY, fontSize, color); } /// Draw text (custom sprite font) within an image (destination) - pub fn drawTextEx(self: *Image, font: Font, text: [*:0]const u8, position: Vector2, fontSize: f32, spacing: f32, t: Color) void { + pub fn drawTextEx(self: *Image, font: Font, text: [:0]const u8, position: Vector2, fontSize: f32, spacing: f32, t: Color) void { rl.imageDrawTextEx(self, font, text, position, fontSize, spacing, t); } /// Export image data to file, returns true on success - pub fn exportToFile(self: Image, fileName: [*:0]const u8) bool { + pub fn exportToFile(self: Image, fileName: [:0]const u8) bool { return rl.exportImage(self, fileName); } /// Export image as code file defining an array of bytes, returns true on success - pub fn exportAsCode(self: Image, fileName: [*:0]const u8) bool { + pub fn exportAsCode(self: Image, fileName: [:0]const u8) bool { return rl.exportImageAsCode(self, fileName); } @@ -1186,7 +1186,7 @@ pub const Texture = extern struct { mipmaps: c_int, format: PixelFormat, - pub fn init(fileName: [*:0]const u8) RaylibError!Texture { + pub fn init(fileName: [:0]const u8) RaylibError!Texture { return rl.loadTexture(fileName); } @@ -1290,12 +1290,12 @@ pub const Font = extern struct { glyphs: [*c]GlyphInfo, /// Load font from file into GPU memory (VRAM) - pub fn init(fileName: [*:0]const u8) RaylibError!Font { + pub fn init(fileName: [:0]const u8) RaylibError!Font { return rl.loadFont(fileName); } /// Load font from file with extended parameters, use null for fontChars to load the default character set - pub fn initEx(fileName: [*:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { + pub fn initEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { return rl.loadFontEx(fileName, fontSize, fontChars); } @@ -1305,7 +1305,7 @@ pub const Font = extern struct { } /// Load font from memory buffer, fileType refers to extension: i.e. '.ttf' - pub fn fromMemory(fileType: [*:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { + pub fn fromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { return rl.loadFontFromMemory(fileType, fileData, fontSize, fontChars); } @@ -1320,7 +1320,7 @@ pub const Font = extern struct { } /// Export font as code file, returns true on success - pub fn exportAsCode(self: Font, fileName: [*:0]const u8) bool { + pub fn exportAsCode(self: Font, fileName: [:0]const u8) bool { return rl.exportFontAsCode(self, fileName); } }; @@ -1456,7 +1456,7 @@ pub const Model = extern struct { bindPose: [*c]Transform, /// Load model from file (meshes and materials) - pub fn init(fileName: [*:0]const u8) RaylibError!Model { + pub fn init(fileName: [:0]const u8) RaylibError!Model { return rl.loadModel(fileName); } @@ -1993,7 +1993,7 @@ pub fn setWindowIcons(images: []Image) void { } /// Load shader from files and bind default locations -pub fn loadShader(vsFileName: ?[*:0]const u8, fsFileName: ?[*:0]const u8) RaylibError!Shader { +pub fn loadShader(vsFileName: ?[:0]const u8, fsFileName: ?[:0]const u8) RaylibError!Shader { var vsFileNameFinal = @as([*c]const u8, 0); var fsFileNameFinal = @as([*c]const u8, 0); if (vsFileName) |vsFileNameSure| { @@ -2008,7 +2008,7 @@ pub fn loadShader(vsFileName: ?[*:0]const u8, fsFileName: ?[*:0]const u8) Raylib } /// Load shader from code strings and bind default locations -pub fn loadShaderFromMemory(vsCode: ?[*:0]const u8, fsCode: ?[*:0]const u8) RaylibError!Shader { +pub fn loadShaderFromMemory(vsCode: ?[:0]const u8, fsCode: ?[:0]const u8) RaylibError!Shader { var vsCodeFinal = @as([*c]const u8, 0); var fsCodeFinal = @as([*c]const u8, 0); if (vsCode) |vsCodeSure| { @@ -2023,7 +2023,7 @@ pub fn loadShaderFromMemory(vsCode: ?[*:0]const u8, fsCode: ?[*:0]const u8) Rayl } /// Load file data as byte array (read) -pub fn loadFileData(fileName: [*:0]const u8) RaylibError![]u8 { +pub fn loadFileData(fileName: [:0]const u8) RaylibError![]u8 { var bytesRead: i32 = 0; var res: []u8 = undefined; @@ -2036,12 +2036,12 @@ pub fn loadFileData(fileName: [*:0]const u8) RaylibError![]u8 { } /// Save data to file from byte array (write), returns true on success -pub fn saveFileData(fileName: [*:0]const u8, data: []u8) bool { +pub fn saveFileData(fileName: [:0]const u8, data: []u8) bool { return cdef.SaveFileData(@as([*c]const u8, @ptrCast(fileName)), @as(*anyopaque, @ptrCast(data.ptr)), @as(c_int, @intCast(data.len))); } /// Export data to code (.h), returns true on success -pub fn exportDataAsCode(data: []const u8, fileName: [*:0]const u8) bool { +pub fn exportDataAsCode(data: []const u8, fileName: [:0]const u8) bool { return cdef.ExportDataAsCode(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]const u8, @ptrCast(fileName))); } @@ -2096,21 +2096,21 @@ pub fn computeSHA1(data: []u8) [5]u32 { } /// Load image from file into CPU memory (RAM) -pub fn loadImage(fileName: [*:0]const u8) RaylibError!Image { +pub fn loadImage(fileName: [:0]const u8) RaylibError!Image { const image = cdef.LoadImage(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Load image from RAW file data -pub fn loadImageRaw(fileName: [*:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { +pub fn loadImageRaw(fileName: [:0]const u8, width: i32, height: i32, format: PixelFormat, headerSize: i32) RaylibError!Image { const image = cdef.LoadImageRaw(@as([*c]const u8, @ptrCast(fileName)), @as(c_int, width), @as(c_int, height), format, @as(c_int, headerSize)); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Load image sequence from file (frames appended to image.data) -pub fn loadImageAnim(fileName: [*:0]const u8, frames: *i32) RaylibError!Image { +pub fn loadImageAnim(fileName: [:0]const u8, frames: *i32) RaylibError!Image { const image = cdef.LoadImageAnim(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(frames))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; @@ -2130,21 +2130,21 @@ pub fn loadImageFromScreen() RaylibError!Image { return if (isValid) image else RaylibError.LoadImage; } -pub fn loadImageAnimFromMemory(fileType: [*:0]const u8, fileData: []const u8, frames: *i32) RaylibError!Image { +pub fn loadImageAnimFromMemory(fileType: [:0]const u8, fileData: []const u8, frames: *i32) RaylibError!Image { const image = cdef.LoadImageAnimFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len)), @as([*c]c_int, @ptrCast(frames))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Load image from memory buffer, fileType refers to extension: i.e. '.png' -pub fn loadImageFromMemory(fileType: [*:0]const u8, fileData: []const u8) RaylibError!Image { +pub fn loadImageFromMemory(fileType: [:0]const u8, fileData: []const u8) RaylibError!Image { const image = cdef.LoadImageFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len))); const isValid = cdef.IsImageValid(image); return if (isValid) image else RaylibError.LoadImage; } /// Create an image from text (default font) -pub fn imageText(text: [*:0]const u8, fontSize: i32, color: Color) RaylibError!Image { +pub fn imageText(text: [:0]const u8, fontSize: i32, color: Color) RaylibError!Image { // TODO: ImageText requires SUPPORT_MODULE_RTEXT. Error out if not loaded. const image = cdef.ImageText(@as([*c]const u8, @ptrCast(text)), @as(c_int, fontSize), color); const isValid = cdef.IsImageValid(image); @@ -2152,7 +2152,7 @@ pub fn imageText(text: [*:0]const u8, fontSize: i32, color: Color) RaylibError!I } /// Create an image from text (custom sprite font) -pub fn imageTextEx(font: Font, text: [*:0]const u8, fontSize: f32, spacing: f32, tint: Color) RaylibError!Image { +pub fn imageTextEx(font: Font, text: [:0]const u8, fontSize: f32, spacing: f32, tint: Color) RaylibError!Image { // TODO: ImageTextEx requires SUPPORT_MODULE_RTEXT. Error out if not loaded. const image = cdef.ImageTextEx(font, @as([*c]const u8, @ptrCast(text)), fontSize, spacing, tint); const isValid = cdef.IsImageValid(image); @@ -2185,7 +2185,7 @@ pub fn loadImagePalette(image: Image, maxPaletteSize: i32) RaylibError![]Color { } /// Load texture from file into GPU memory (VRAM) -pub fn loadTexture(fileName: [*:0]const u8) RaylibError!Texture2D { +pub fn loadTexture(fileName: [:0]const u8) RaylibError!Texture2D { const texture = cdef.LoadTexture(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsTextureValid(texture); return if (isValid) texture else RaylibError.LoadTexture; @@ -2212,6 +2212,13 @@ pub fn loadRenderTexture(width: i32, height: i32) RaylibError!RenderTexture2D { return if (isValid) render_texture else RaylibError.LoadRenderTexture; } +pub fn colorToInt(color: Color) i32 { + return if (@inComptime()) + (@as(i32, color.r) << 24) | (@as(i32, color.g) << 16) | (@as(i32, color.b) << 8) | @as(i32, color.a) + else + @as(i32, cdef.ColorToInt(color)); +} + /// Get the default Font pub fn getFontDefault() RaylibError!Font { // TODO: GetFontDefault requires SUPPORT_DEFAULT_FONT. Error out if unset. @@ -2221,14 +2228,14 @@ pub fn getFontDefault() RaylibError!Font { } /// Load font from file into GPU memory (VRAM) -pub fn loadFont(fileName: [*:0]const u8) RaylibError!Font { +pub fn loadFont(fileName: [:0]const u8) RaylibError!Font { const font = cdef.LoadFont(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsFontValid(font); return if (isValid) font else RaylibError.LoadFont; } /// Load font from file with extended parameters, use null for fontChars to load the default character set -pub fn loadFontEx(fileName: [*:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { +pub fn loadFontEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { var fontCharsFinal = @as([*c]c_int, 0); var fontCharsLen: c_int = @as(c_int, 0); if (fontChars) |fontCharsSure| { @@ -2241,7 +2248,7 @@ pub fn loadFontEx(fileName: [*:0]const u8, fontSize: i32, fontChars: ?[]i32) Ray } /// Load font from memory buffer, fileType refers to extension: i.e. '.ttf' -pub fn loadFontFromMemory(fileType: [*:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { +pub fn loadFontFromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font { var fileDataFinal = @as([*c]const u8, 0); var fileDataLen: i32 = 0; if (fileData) |fileDataSure| { @@ -2274,7 +2281,7 @@ pub fn loadFontData(fileData: []const u8, fontSize: i32, fontChars: []i32, ty: F } /// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter -pub fn loadCodepoints(text: [*:0]const u8) RaylibError![]i32 { +pub fn loadCodepoints(text: [:0]const u8) RaylibError![]i32 { if (@sizeOf(c_int) != @sizeOf(i32)) { @compileError("Can't cast pointer to c_int array to i32 because they don't have the same size"); } @@ -2290,7 +2297,7 @@ pub fn loadCodepoints(text: [*:0]const u8) RaylibError![]i32 { } /// Text formatting with variables (sprintf() style) -pub fn textFormat(text: [*:0]const u8, args: anytype) [*:0]const u8 { +pub fn textFormat(text: [:0]const u8, args: anytype) [:0]const u8 { comptime { const info = @typeInfo(@TypeOf(args)); switch (info) { @@ -2308,7 +2315,7 @@ pub fn textFormat(text: [*:0]const u8, args: anytype) [*:0]const u8 { } /// Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) -pub fn traceLog(logLevel: TraceLogLevel, text: [*:0]const u8, args: anytype) void { +pub fn traceLog(logLevel: TraceLogLevel, text: [:0]const u8, args: anytype) void { comptime { const info = @typeInfo(@TypeOf(args)); switch (info) { @@ -2326,10 +2333,10 @@ pub fn traceLog(logLevel: TraceLogLevel, text: [*:0]const u8, args: anytype) voi } /// Split text into multiple strings -pub fn textSplit(text: [*:0]const u8, delimiter: u8) [][*:0]const u8 { +pub fn textSplit(text: [:0]const u8, delimiter: u8) [][:0]const u8 { var count: i32 = 0; - var res: [][*:0]const u8 = undefined; - res.ptr = @as([*][*:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count))))); + var res: [][:0]const u8 = undefined; + res.ptr = @as([*][:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count))))); res.len = @as(usize, @intCast(count)); return res; } @@ -2347,7 +2354,7 @@ pub fn loadMaterialDefault() RaylibError!Material { } /// Load materials from model file -pub fn loadMaterials(fileName: [*:0]const u8) RaylibError![]Material { +pub fn loadMaterials(fileName: [:0]const u8) RaylibError![]Material { var materialCount: i32 = 0; var res: []Material = undefined; @@ -2366,7 +2373,7 @@ pub fn loadMaterials(fileName: [*:0]const u8) RaylibError![]Material { } /// Load model from files (meshes and materials) -pub fn loadModel(fileName: [*:0]const u8) RaylibError!Model { +pub fn loadModel(fileName: [:0]const u8) RaylibError!Model { const model = cdef.LoadModel(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsModelValid(model); return if (isValid) model else RaylibError.LoadModel; @@ -2380,7 +2387,7 @@ pub fn loadModelFromMesh(mesh: Mesh) RaylibError!Model { } /// Load model animations from file -pub fn loadModelAnimations(fileName: [*:0]const u8) RaylibError![]ModelAnimation { +pub fn loadModelAnimations(fileName: [:0]const u8) RaylibError![]ModelAnimation { var animCount: i32 = 0; var res: []ModelAnimation = undefined; @@ -2398,21 +2405,21 @@ pub fn unloadModelAnimations(animations: []ModelAnimation) void { } /// Load sound from file -pub fn loadSound(fileName: [*:0]const u8) RaylibError!Sound { +pub fn loadSound(fileName: [:0]const u8) RaylibError!Sound { const sound = cdef.LoadSound(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsSoundValid(sound); return if (isValid) sound else RaylibError.LoadSound; } /// Load wave data from file -pub fn loadWave(fileName: [*:0]const u8) RaylibError!Wave { +pub fn loadWave(fileName: [:0]const u8) RaylibError!Wave { const wave = cdef.LoadWave(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsWaveValid(wave); return if (isValid) wave else RaylibError.LoadWave; } /// Load wave from memory buffer, fileType refers to extension: i.e. '.wav' -pub fn loadWaveFromMemory(fileType: [*:0]const u8, fileData: []const u8) RaylibError!Wave { +pub fn loadWaveFromMemory(fileType: [:0]const u8, fileData: []const u8) RaylibError!Wave { const wave = cdef.LoadWaveFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len))); const isValid = cdef.IsWaveValid(wave); return if (isValid) wave else RaylibError.LoadWave; @@ -2427,14 +2434,14 @@ pub fn loadWaveSamples(wave: Wave) []f32 { } /// Load music stream from file -pub fn loadMusicStream(fileName: [*:0]const u8) RaylibError!Music { +pub fn loadMusicStream(fileName: [:0]const u8) RaylibError!Music { const music = cdef.LoadMusicStream(@as([*c]const u8, @ptrCast(fileName))); const isValid = cdef.IsMusicValid(music); return if (isValid) music else RaylibError.LoadMusic; } /// Load music stream from data -pub fn loadMusicStreamFromMemory(fileType: [*:0]const u8, data: []const u8) RaylibError!Music { +pub fn loadMusicStreamFromMemory(fileType: [:0]const u8, data: []const u8) RaylibError!Music { const music = cdef.LoadMusicStreamFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len))); const isValid = cdef.IsMusicValid(music); return if (isValid) music else RaylibError.LoadMusic; @@ -2514,12 +2521,12 @@ pub fn drawTextCodepoints(font: Font, codepoints: []const c_int, position: Vecto } /// Load UTF-8 text encoded from codepoints array -pub fn loadUTF8(codepoints: []const c_int) [*:0]u8 { +pub fn loadUTF8(codepoints: []const c_int) [:0]u8 { return std.mem.span(cdef.LoadUTF8(@as([*c]const c_int, @ptrCast(codepoints)), @as(c_int, @intCast(codepoints.len)))); } /// Join text strings with delimiter -pub fn textJoin(textList: [][*:0]u8, delimiter: [*:0]const u8) [*:0]const u8 { +pub fn textJoin(textList: [][:0]u8, delimiter: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.TextJoin(@as([*c][*c]u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter)))); } @@ -2565,7 +2572,7 @@ pub const mem = std.mem.Allocator{ }; /// Initialize window and OpenGL context -pub fn initWindow(width: i32, height: i32, title: [*:0]const u8) void { +pub fn initWindow(width: i32, height: i32, title: [:0]const u8) void { cdef.InitWindow(@as(c_int, width), @as(c_int, height), @as([*c]const u8, @ptrCast(title))); } @@ -2660,7 +2667,7 @@ pub fn setWindowIcon(image: Image) void { } /// Set title for window -pub fn setWindowTitle(title: [*:0]const u8) void { +pub fn setWindowTitle(title: [:0]const u8) void { cdef.SetWindowTitle(@as([*c]const u8, @ptrCast(title))); } @@ -2775,17 +2782,17 @@ pub fn getWindowScaleDPI() Vector2 { } /// Get the human-readable, UTF-8 encoded name of the specified monitor -pub fn getMonitorName(monitor: i32) [*:0]const u8 { +pub fn getMonitorName(monitor: i32) [:0]const u8 { return std.mem.span(cdef.GetMonitorName(@as(c_int, monitor))); } /// Set clipboard text content -pub fn setClipboardText(text: [*:0]const u8) void { +pub fn setClipboardText(text: [:0]const u8) void { cdef.SetClipboardText(@as([*c]const u8, @ptrCast(text))); } /// Get clipboard text content -pub fn getClipboardText() [*:0]const u8 { +pub fn getClipboardText() [:0]const u8 { return std.mem.span(cdef.GetClipboardText()); } @@ -2935,12 +2942,12 @@ pub fn isShaderValid(shader: Shader) bool { } /// Get shader uniform location -pub fn getShaderLocation(shader: Shader, uniformName: [*:0]const u8) i32 { +pub fn getShaderLocation(shader: Shader, uniformName: [:0]const u8) i32 { return @as(i32, cdef.GetShaderLocation(shader, @as([*c]const u8, @ptrCast(uniformName)))); } /// Get shader attribute location -pub fn getShaderLocationAttrib(shader: Shader, attribName: [*:0]const u8) i32 { +pub fn getShaderLocationAttrib(shader: Shader, attribName: [:0]const u8) i32 { return @as(i32, cdef.GetShaderLocationAttrib(shader, @as([*c]const u8, @ptrCast(attribName)))); } @@ -3060,7 +3067,7 @@ pub fn unloadRandomSequence(sequence: []i32) void { } /// Takes a screenshot of current screen (filename extension defines format) -pub fn takeScreenshot(fileName: [*:0]const u8) void { +pub fn takeScreenshot(fileName: [:0]const u8) void { cdef.TakeScreenshot(@as([*c]const u8, @ptrCast(fileName))); } @@ -3070,7 +3077,7 @@ pub fn setConfigFlags(flags: ConfigFlags) void { } /// Open URL with default system browser (if available) -pub fn openURL(url: [*:0]const u8) void { +pub fn openURL(url: [:0]const u8) void { cdef.OpenURL(@as([*c]const u8, @ptrCast(url))); } @@ -3120,102 +3127,102 @@ pub fn unloadFileData(data: []u8) void { } /// Load text data from file (read), returns a '\0' terminated string -pub fn loadFileText(fileName: [*:0]const u8) [*:0]u8 { +pub fn loadFileText(fileName: [:0]const u8) [:0]u8 { return std.mem.span(cdef.LoadFileText(@as([*c]const u8, @ptrCast(fileName)))); } /// Unload file text data allocated by LoadFileText() -pub fn unloadFileText(text: [*:0]u8) void { +pub fn unloadFileText(text: [:0]u8) void { cdef.UnloadFileText(@as([*c]u8, @ptrCast(text))); } /// Save text data to file (write), string must be '\0' terminated, returns true on success -pub fn saveFileText(fileName: [*:0]const u8, text: [*:0]u8) bool { +pub fn saveFileText(fileName: [:0]const u8, text: [:0]u8) bool { return cdef.SaveFileText(@as([*c]const u8, @ptrCast(fileName)), @as([*c]u8, @ptrCast(text))); } /// Check if file exists -pub fn fileExists(fileName: [*:0]const u8) bool { +pub fn fileExists(fileName: [:0]const u8) bool { return cdef.FileExists(@as([*c]const u8, @ptrCast(fileName))); } /// Check if a directory path exists -pub fn directoryExists(dirPath: [*:0]const u8) bool { +pub fn directoryExists(dirPath: [:0]const u8) bool { return cdef.DirectoryExists(@as([*c]const u8, @ptrCast(dirPath))); } /// Check file extension (including point: .png, .wav) -pub fn isFileExtension(fileName: [*:0]const u8, ext: [*:0]const u8) bool { +pub fn isFileExtension(fileName: [:0]const u8, ext: [:0]const u8) bool { return cdef.IsFileExtension(@as([*c]const u8, @ptrCast(fileName)), @as([*c]const u8, @ptrCast(ext))); } /// Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) -pub fn getFileLength(fileName: [*:0]const u8) i32 { +pub fn getFileLength(fileName: [:0]const u8) i32 { return @as(i32, cdef.GetFileLength(@as([*c]const u8, @ptrCast(fileName)))); } /// Get pointer to extension for a filename string (includes dot: '.png') -pub fn getFileExtension(fileName: [*:0]const u8) [*:0]const u8 { +pub fn getFileExtension(fileName: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.GetFileExtension(@as([*c]const u8, @ptrCast(fileName)))); } /// Get pointer to filename for a path string -pub fn getFileName(filePath: [*:0]const u8) [*:0]const u8 { +pub fn getFileName(filePath: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.GetFileName(@as([*c]const u8, @ptrCast(filePath)))); } /// Get filename string without extension (uses static string) -pub fn getFileNameWithoutExt(filePath: [*:0]const u8) [*:0]const u8 { +pub fn getFileNameWithoutExt(filePath: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.GetFileNameWithoutExt(@as([*c]const u8, @ptrCast(filePath)))); } /// Get full path for a given fileName with path (uses static string) -pub fn getDirectoryPath(filePath: [*:0]const u8) [*:0]const u8 { +pub fn getDirectoryPath(filePath: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.GetDirectoryPath(@as([*c]const u8, @ptrCast(filePath)))); } /// Get previous directory path for a given path (uses static string) -pub fn getPrevDirectoryPath(dirPath: [*:0]const u8) [*:0]const u8 { +pub fn getPrevDirectoryPath(dirPath: [:0]const u8) [:0]const u8 { return std.mem.span(cdef.GetPrevDirectoryPath(@as([*c]const u8, @ptrCast(dirPath)))); } /// Get current working directory (uses static string) -pub fn getWorkingDirectory() [*:0]const u8 { +pub fn getWorkingDirectory() [:0]const u8 { return std.mem.span(cdef.GetWorkingDirectory()); } /// Get the directory of the running application (uses static string) -pub fn getApplicationDirectory() [*:0]const u8 { +pub fn getApplicationDirectory() [:0]const u8 { return std.mem.span(cdef.GetApplicationDirectory()); } /// Create directories (including full path requested), returns 0 on success -pub fn makeDirectory(dirPath: [*:0]const u8) i32 { +pub fn makeDirectory(dirPath: [:0]const u8) i32 { return @as(i32, cdef.MakeDirectory(@as([*c]const u8, @ptrCast(dirPath)))); } /// Change working directory, return true on success -pub fn changeDirectory(dir: [*:0]const u8) bool { +pub fn changeDirectory(dir: [:0]const u8) bool { return cdef.ChangeDirectory(@as([*c]const u8, @ptrCast(dir))); } /// Check if a given path is a file or a directory -pub fn isPathFile(path: [*:0]const u8) bool { +pub fn isPathFile(path: [:0]const u8) bool { return cdef.IsPathFile(@as([*c]const u8, @ptrCast(path))); } /// Check if fileName is valid for the platform/OS -pub fn isFileNameValid(fileName: [*:0]const u8) bool { +pub fn isFileNameValid(fileName: [:0]const u8) bool { return cdef.IsFileNameValid(@as([*c]const u8, @ptrCast(fileName))); } /// Load directory filepaths -pub fn loadDirectoryFiles(dirPath: [*:0]const u8) FilePathList { +pub fn loadDirectoryFiles(dirPath: [:0]const u8) FilePathList { return cdef.LoadDirectoryFiles(@as([*c]const u8, @ptrCast(dirPath))); } /// Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result -pub fn loadDirectoryFilesEx(basePath: [*:0]const u8, filter: [*:0]const u8, scanSubdirs: bool) FilePathList { +pub fn loadDirectoryFilesEx(basePath: [:0]const u8, filter: [:0]const u8, scanSubdirs: bool) FilePathList { return cdef.LoadDirectoryFilesEx(@as([*c]const u8, @ptrCast(basePath)), @as([*c]const u8, @ptrCast(filter)), scanSubdirs); } @@ -3240,12 +3247,12 @@ pub fn unloadDroppedFiles(files: FilePathList) void { } /// Get file modification time (last write time) -pub fn getFileModTime(fileName: [*:0]const u8) i64 { +pub fn getFileModTime(fileName: [:0]const u8) i64 { return @as(i64, cdef.GetFileModTime(@as([*c]const u8, @ptrCast(fileName)))); } /// Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS -pub fn loadAutomationEventList(fileName: [*:0]const u8) AutomationEventList { +pub fn loadAutomationEventList(fileName: [:0]const u8) AutomationEventList { return cdef.LoadAutomationEventList(@as([*c]const u8, @ptrCast(fileName))); } @@ -3255,7 +3262,7 @@ pub fn unloadAutomationEventList(list: AutomationEventList) void { } /// Export automation events list as text file -pub fn exportAutomationEventList(list: AutomationEventList, fileName: [*:0]const u8) bool { +pub fn exportAutomationEventList(list: AutomationEventList, fileName: [:0]const u8) bool { return cdef.ExportAutomationEventList(list, @as([*c]const u8, @ptrCast(fileName))); } @@ -3320,7 +3327,7 @@ pub fn getCharPressed() i32 { } /// Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard) -pub fn getKeyName(key: KeyboardKey) [*:0]const u8 { +pub fn getKeyName(key: KeyboardKey) [:0]const u8 { return std.mem.span(cdef.GetKeyName(key)); } @@ -3335,7 +3342,7 @@ pub fn isGamepadAvailable(gamepad: i32) bool { } /// Get gamepad internal name id -pub fn getGamepadName(gamepad: i32) [*:0]const u8 { +pub fn getGamepadName(gamepad: i32) [:0]const u8 { return std.mem.span(cdef.GetGamepadName(@as(c_int, gamepad))); } @@ -3375,7 +3382,7 @@ pub fn getGamepadAxisMovement(gamepad: i32, axis: GamepadAxis) f32 { } /// Set internal gamepad mappings (SDL_GameControllerDB) -pub fn setGamepadMappings(mappings: [*:0]const u8) i32 { +pub fn setGamepadMappings(mappings: [:0]const u8) i32 { return @as(i32, cdef.SetGamepadMappings(@as([*c]const u8, @ptrCast(mappings)))); } @@ -3825,17 +3832,17 @@ pub fn unloadImage(image: Image) void { } /// Export image data to file, returns true on success -pub fn exportImage(image: Image, fileName: [*:0]const u8) bool { +pub fn exportImage(image: Image, fileName: [:0]const u8) bool { return cdef.ExportImage(image, @as([*c]const u8, @ptrCast(fileName))); } /// Export image to memory buffer -pub fn exportImageToMemory(image: Image, fileType: [*:0]const u8, fileSize: *i32) [*:0]u8 { +pub fn exportImageToMemory(image: Image, fileType: [:0]const u8, fileSize: *i32) [:0]u8 { return std.mem.span(cdef.ExportImageToMemory(image, @as([*c]const u8, @ptrCast(fileType)), @as([*c]c_int, @ptrCast(fileSize)))); } /// Export image as code file defining an array of bytes, returns true on success -pub fn exportImageAsCode(image: Image, fileName: [*:0]const u8) bool { +pub fn exportImageAsCode(image: Image, fileName: [:0]const u8) bool { return cdef.ExportImageAsCode(image, @as([*c]const u8, @ptrCast(fileName))); } @@ -3880,7 +3887,7 @@ pub fn genImageCellular(width: i32, height: i32, tileSize: i32) Image { } /// Generate image: grayscale image from text data -pub fn genImageText(width: i32, height: i32, text: [*:0]const u8) Image { +pub fn genImageText(width: i32, height: i32, text: [:0]const u8) Image { return cdef.GenImageText(@as(c_int, width), @as(c_int, height), @as([*c]const u8, @ptrCast(text))); } @@ -4140,12 +4147,12 @@ pub fn imageDraw(dst: *Image, src: Image, srcRec: Rectangle, dstRec: Rectangle, } /// Draw text (using default font) within an image (destination) -pub fn imageDrawText(dst: *Image, text: [*:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { +pub fn imageDrawText(dst: *Image, text: [:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { cdef.ImageDrawText(@as([*c]Image, @ptrCast(dst)), @as([*c]const u8, @ptrCast(text)), @as(c_int, posX), @as(c_int, posY), @as(c_int, fontSize), color); } /// Draw text (custom sprite font) within an image (destination) -pub fn imageDrawTextEx(dst: *Image, font: Font, text: [*:0]const u8, position: Vector2, fontSize: f32, spacing: f32, tint: Color) void { +pub fn imageDrawTextEx(dst: *Image, font: Font, text: [:0]const u8, position: Vector2, fontSize: f32, spacing: f32, tint: Color) void { cdef.ImageDrawTextEx(@as([*c]Image, @ptrCast(dst)), font, @as([*c]const u8, @ptrCast(text)), position, fontSize, spacing, tint); } @@ -4234,11 +4241,6 @@ pub fn fade(color: Color, alpha: f32) Color { return cdef.Fade(color, alpha); } -/// Get hexadecimal value for a Color (0xRRGGBBAA) -pub fn colorToInt(color: Color) i32 { - return @as(i32, cdef.ColorToInt(color)); -} - /// Get Color normalized as float [0..1] pub fn colorNormalize(color: Color) Vector4 { return cdef.ColorNormalize(color); @@ -4320,7 +4322,7 @@ pub fn unloadFont(font: Font) void { } /// Export font as code file, returns true on success -pub fn exportFontAsCode(font: Font, fileName: [*:0]const u8) bool { +pub fn exportFontAsCode(font: Font, fileName: [:0]const u8) bool { return cdef.ExportFontAsCode(font, @as([*c]const u8, @ptrCast(fileName))); } @@ -4330,17 +4332,17 @@ pub fn drawFPS(posX: i32, posY: i32) void { } /// Draw text (using default font) -pub fn drawText(text: [*:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { +pub fn drawText(text: [:0]const u8, posX: i32, posY: i32, fontSize: i32, color: Color) void { cdef.DrawText(@as([*c]const u8, @ptrCast(text)), @as(c_int, posX), @as(c_int, posY), @as(c_int, fontSize), color); } /// Draw text using font and additional parameters -pub fn drawTextEx(font: Font, text: [*:0]const u8, position: Vector2, fontSize: f32, spacing: f32, tint: Color) void { +pub fn drawTextEx(font: Font, text: [:0]const u8, position: Vector2, fontSize: f32, spacing: f32, tint: Color) void { cdef.DrawTextEx(font, @as([*c]const u8, @ptrCast(text)), position, fontSize, spacing, tint); } /// Draw text using Font and pro parameters (rotation) -pub fn drawTextPro(font: Font, text: [*:0]const u8, position: Vector2, origin: Vector2, rotation: f32, fontSize: f32, spacing: f32, tint: Color) void { +pub fn drawTextPro(font: Font, text: [:0]const u8, position: Vector2, origin: Vector2, rotation: f32, fontSize: f32, spacing: f32, tint: Color) void { cdef.DrawTextPro(font, @as([*c]const u8, @ptrCast(text)), position, origin, rotation, fontSize, spacing, tint); } @@ -4355,12 +4357,12 @@ pub fn setTextLineSpacing(spacing: i32) void { } /// Measure string width for default font -pub fn measureText(text: [*:0]const u8, fontSize: i32) i32 { +pub fn measureText(text: [:0]const u8, fontSize: i32) i32 { return @as(i32, cdef.MeasureText(@as([*c]const u8, @ptrCast(text)), @as(c_int, fontSize))); } /// Measure string size for Font -pub fn measureTextEx(font: Font, text: [*:0]const u8, fontSize: f32, spacing: f32) Vector2 { +pub fn measureTextEx(font: Font, text: [:0]const u8, fontSize: f32, spacing: f32) Vector2 { return cdef.MeasureTextEx(font, @as([*c]const u8, @ptrCast(text)), fontSize, spacing); } @@ -4380,7 +4382,7 @@ pub fn getGlyphAtlasRec(font: Font, codepoint: i32) Rectangle { } /// Unload UTF-8 text encoded from codepoints array -pub fn unloadUTF8(text: [*:0]u8) void { +pub fn unloadUTF8(text: [:0]u8) void { cdef.UnloadUTF8(@as([*c]u8, @ptrCast(text))); } @@ -4390,102 +4392,102 @@ pub fn unloadCodepoints(codepoints: []i32) void { } /// Get total number of codepoints in a UTF-8 encoded string -pub fn getCodepointCount(text: [*:0]const u8) i32 { +pub fn getCodepointCount(text: [:0]const u8) i32 { return @as(i32, cdef.GetCodepointCount(@as([*c]const u8, @ptrCast(text)))); } /// Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -pub fn getCodepoint(text: [*:0]const u8, codepointSize: *i32) i32 { +pub fn getCodepoint(text: [:0]const u8, codepointSize: *i32) i32 { return @as(i32, cdef.GetCodepoint(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(codepointSize)))); } /// Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -pub fn getCodepointNext(text: [*:0]const u8, codepointSize: *i32) i32 { +pub fn getCodepointNext(text: [:0]const u8, codepointSize: *i32) i32 { return @as(i32, cdef.GetCodepointNext(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(codepointSize)))); } /// Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -pub fn getCodepointPrevious(text: [*:0]const u8, codepointSize: *i32) i32 { +pub fn getCodepointPrevious(text: [:0]const u8, codepointSize: *i32) i32 { return @as(i32, cdef.GetCodepointPrevious(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(codepointSize)))); } /// Encode one codepoint into UTF-8 byte array (array length returned as parameter) -pub fn codepointToUTF8(codepoint: i32, utf8Size: *i32) [*:0]const u8 { +pub fn codepointToUTF8(codepoint: i32, utf8Size: *i32) [:0]const u8 { return std.mem.span(cdef.CodepointToUTF8(@as(c_int, codepoint), @as([*c]c_int, @ptrCast(utf8Size)))); } /// Copy one string to another, returns bytes copied -pub fn textCopy(dst: *u8, src: [*:0]const u8) i32 { +pub fn textCopy(dst: *u8, src: [:0]const u8) i32 { return @as(i32, cdef.TextCopy(@as([*c]u8, @ptrCast(dst)), @as([*c]const u8, @ptrCast(src)))); } /// Check if two text string are equal -pub fn textIsEqual(text1: [*:0]const u8, text2: [*:0]const u8) bool { +pub fn textIsEqual(text1: [:0]const u8, text2: [:0]const u8) bool { return cdef.TextIsEqual(@as([*c]const u8, @ptrCast(text1)), @as([*c]const u8, @ptrCast(text2))); } /// Get text length, checks for '\0' ending -pub fn textLength(text: [*:0]const u8) u32 { +pub fn textLength(text: [:0]const u8) u32 { return @as(u32, cdef.TextLength(@as([*c]const u8, @ptrCast(text)))); } /// Get a piece of a text string -pub fn textSubtext(text: [*:0]const u8, position: i32, length: i32) [*:0]const u8 { +pub fn textSubtext(text: [:0]const u8, position: i32, length: i32) [:0]const u8 { return std.mem.span(cdef.TextSubtext(@as([*c]const u8, @ptrCast(text)), @as(c_int, position), @as(c_int, length))); } /// Replace text string (WARNING: memory must be freed!) -pub fn textReplace(text: [*:0]const u8, replace: [*:0]const u8, by: [*:0]const u8) [*:0]u8 { +pub fn textReplace(text: [:0]const u8, replace: [:0]const u8, by: [:0]const u8) [:0]u8 { return std.mem.span(cdef.TextReplace(@as([*c]const u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(replace)), @as([*c]const u8, @ptrCast(by)))); } /// Insert text in a position (WARNING: memory must be freed!) -pub fn textInsert(text: [*:0]const u8, insert: [*:0]const u8, position: i32) [*:0]u8 { +pub fn textInsert(text: [:0]const u8, insert: [:0]const u8, position: i32) [:0]u8 { return std.mem.span(cdef.TextInsert(@as([*c]const u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(insert)), @as(c_int, position))); } /// Append text at specific position and move cursor! -pub fn textAppend(text: [*:0]u8, append: [*:0]const u8, position: *i32) void { +pub fn textAppend(text: [:0]u8, append: [:0]const u8, position: *i32) void { cdef.TextAppend(@as([*c]u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(append)), @as([*c]c_int, @ptrCast(position))); } /// Find first text occurrence within a string -pub fn textFindIndex(text: [*:0]const u8, find: [*:0]const u8) i32 { +pub fn textFindIndex(text: [:0]const u8, find: [:0]const u8) i32 { return @as(i32, cdef.TextFindIndex(@as([*c]const u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(find)))); } /// Get upper case version of provided string -pub fn textToUpper(text: [*:0]const u8) [*:0]u8 { +pub fn textToUpper(text: [:0]const u8) [:0]u8 { return std.mem.span(cdef.TextToUpper(@as([*c]const u8, @ptrCast(text)))); } /// Get lower case version of provided string -pub fn textToLower(text: [*:0]const u8) [*:0]u8 { +pub fn textToLower(text: [:0]const u8) [:0]u8 { return std.mem.span(cdef.TextToLower(@as([*c]const u8, @ptrCast(text)))); } /// Get Pascal case notation version of provided string -pub fn textToPascal(text: [*:0]const u8) [*:0]u8 { +pub fn textToPascal(text: [:0]const u8) [:0]u8 { return std.mem.span(cdef.TextToPascal(@as([*c]const u8, @ptrCast(text)))); } /// Get Snake case notation version of provided string -pub fn textToSnake(text: [*:0]const u8) [*:0]u8 { +pub fn textToSnake(text: [:0]const u8) [:0]u8 { return std.mem.span(cdef.TextToSnake(@as([*c]const u8, @ptrCast(text)))); } /// Get Camel case notation version of provided string -pub fn textToCamel(text: [*:0]const u8) [*:0]u8 { +pub fn textToCamel(text: [:0]const u8) [:0]u8 { return std.mem.span(cdef.TextToCamel(@as([*c]const u8, @ptrCast(text)))); } /// Get integer value from text -pub fn textToInteger(text: [*:0]const u8) i32 { +pub fn textToInteger(text: [:0]const u8) i32 { return @as(i32, cdef.TextToInteger(@as([*c]const u8, @ptrCast(text)))); } /// Get float value from text -pub fn textToFloat(text: [*:0]const u8) f32 { +pub fn textToFloat(text: [:0]const u8) f32 { return cdef.TextToFloat(@as([*c]const u8, @ptrCast(text))); } @@ -4685,12 +4687,12 @@ pub fn genMeshTangents(mesh: *Mesh) void { } /// Export mesh data to file, returns true on success -pub fn exportMesh(mesh: Mesh, fileName: [*:0]const u8) bool { +pub fn exportMesh(mesh: Mesh, fileName: [:0]const u8) bool { return cdef.ExportMesh(mesh, @as([*c]const u8, @ptrCast(fileName))); } /// Export mesh as code file (.h) defining multiple arrays of vertex attributes -pub fn exportMeshAsCode(mesh: Mesh, fileName: [*:0]const u8) bool { +pub fn exportMeshAsCode(mesh: Mesh, fileName: [:0]const u8) bool { return cdef.ExportMeshAsCode(mesh, @as([*c]const u8, @ptrCast(fileName))); } @@ -4895,12 +4897,12 @@ pub fn unloadSoundAlias(alias: Sound) void { } /// Export wave data to file, returns true on success -pub fn exportWave(wave: Wave, fileName: [*:0]const u8) bool { +pub fn exportWave(wave: Wave, fileName: [:0]const u8) bool { return cdef.ExportWave(wave, @as([*c]const u8, @ptrCast(fileName))); } /// Export wave sample data to code (.h), returns true on success -pub fn exportWaveAsCode(wave: Wave, fileName: [*:0]const u8) bool { +pub fn exportWaveAsCode(wave: Wave, fileName: [:0]const u8) bool { return cdef.ExportWaveAsCode(wave, @as([*c]const u8, @ptrCast(fileName))); } diff --git a/lib/rlgl.zig b/lib/rlgl.zig index 17f65de..010539a 100644 --- a/lib/rlgl.zig +++ b/lib/rlgl.zig @@ -845,7 +845,7 @@ pub fn rlGetGlTextureFormats(format: i32, glInternalFormat: *u32, glFormat: *u32 } /// Get name string for pixel format -pub fn rlGetPixelFormatName(format: u32) [*:0]const u8 { +pub fn rlGetPixelFormatName(format: u32) [:0]const u8 { return std.mem.span(cdef.rlGetPixelFormatName(@as(c_uint, format))); } @@ -865,7 +865,7 @@ pub fn rlReadTexturePixels(id: u32, width: i32, height: i32, format: i32) *anyop } /// Read screen pixel data (color buffer) -pub fn rlReadScreenPixels(width: i32, height: i32) [*:0]u8 { +pub fn rlReadScreenPixels(width: i32, height: i32) [:0]u8 { return std.mem.span(cdef.rlReadScreenPixels(@as(c_int, width), @as(c_int, height))); } @@ -890,12 +890,12 @@ pub fn rlUnloadFramebuffer(id: u32) void { } /// Load shader from code strings -pub fn rlLoadShaderCode(vsCode: [*:0]const u8, fsCode: [*:0]const u8) u32 { +pub fn rlLoadShaderCode(vsCode: [:0]const u8, fsCode: [:0]const u8) u32 { return @as(u32, cdef.rlLoadShaderCode(@as([*c]const u8, @ptrCast(vsCode)), @as([*c]const u8, @ptrCast(fsCode)))); } /// Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) -pub fn rlCompileShader(shaderCode: [*:0]const u8, ty: i32) u32 { +pub fn rlCompileShader(shaderCode: [:0]const u8, ty: i32) u32 { return @as(u32, cdef.rlCompileShader(@as([*c]const u8, @ptrCast(shaderCode)), @as(c_int, ty))); } @@ -910,12 +910,12 @@ pub fn rlUnloadShaderProgram(id: u32) void { } /// Get shader location uniform -pub fn rlGetLocationUniform(shaderId: u32, uniformName: [*:0]const u8) i32 { +pub fn rlGetLocationUniform(shaderId: u32, uniformName: [:0]const u8) i32 { return @as(i32, cdef.rlGetLocationUniform(@as(c_uint, shaderId), @as([*c]const u8, @ptrCast(uniformName)))); } /// Get shader location attribute -pub fn rlGetLocationAttrib(shaderId: u32, attribName: [*:0]const u8) i32 { +pub fn rlGetLocationAttrib(shaderId: u32, attribName: [:0]const u8) i32 { return @as(i32, cdef.rlGetLocationAttrib(@as(c_uint, shaderId), @as([*c]const u8, @ptrCast(attribName)))); } diff --git a/resources/audio/country.mp3 b/resources/audio/country.mp3 new file mode 100644 index 0000000..91066cc Binary files /dev/null and b/resources/audio/country.mp3 differ diff --git a/resources/audio/mini1111.xm b/resources/audio/mini1111.xm new file mode 100644 index 0000000..a185c1a Binary files /dev/null and b/resources/audio/mini1111.xm differ diff --git a/resources/audio/sound.wav b/resources/audio/sound.wav new file mode 100644 index 0000000..b5d01c9 Binary files /dev/null and b/resources/audio/sound.wav differ diff --git a/resources/audio/target.ogg b/resources/audio/target.ogg new file mode 100644 index 0000000..2b73e1c Binary files /dev/null and b/resources/audio/target.ogg differ diff --git a/resources/shaders/glsl330/raymarching.fs b/resources/shaders/glsl330/raymarching.fs new file mode 100644 index 0000000..15a6612 --- /dev/null +++ b/resources/shaders/glsl330/raymarching.fs @@ -0,0 +1,431 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +uniform vec3 viewEye; +uniform vec3 viewCenter; +uniform float runTime; +uniform vec2 resolution; + +// The MIT License +// Copyright © 2013 Inigo Quilez +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// A list of useful distance function to simple primitives, and an example on how to +// do some interesting boolean operations, repetition and displacement. +// +// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm + +#define AA 1 // make this 1 is your machine is too slow + +//------------------------------------------------------------------ + +float sdPlane( vec3 p ) +{ + return p.y; +} + +float sdSphere( vec3 p, float s ) +{ + return length(p)-s; +} + +float sdBox( vec3 p, vec3 b ) +{ + vec3 d = abs(p) - b; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); +} + +float sdEllipsoid( in vec3 p, in vec3 r ) +{ + return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z); +} + +float udRoundBox( vec3 p, vec3 b, float r ) +{ + return length(max(abs(p)-b,0.0))-r; +} + +float sdTorus( vec3 p, vec2 t ) +{ + return length( vec2(length(p.xz)-t.x,p.y) )-t.y; +} + +float sdHexPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); +#if 0 + return max(q.z-h.y,max((q.x*0.866025+q.y*0.5),q.y)-h.x); +#else + float d1 = q.z-h.y; + float d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x; + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +#endif +} + +float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) +{ + vec3 pa = p-a, ba = b-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ) - r; +} + +float sdEquilateralTriangle( in vec2 p ) +{ + const float k = sqrt(3.0); + p.x = abs(p.x) - 1.0; + p.y = p.y + 1.0/k; + if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0; + p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 ); + return -length(p)*sign(p.y); +} + +float sdTriPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); + float d1 = q.z-h.y; +#if 1 + // distance bound + float d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5; +#else + // correct distance + h.x *= 0.866025; + float d2 = sdEquilateralTriangle(p.xy/h.x)*h.x; +#endif + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdCylinder( vec3 p, vec2 h ) +{ + vec2 d = abs(vec2(length(p.xz),p.y)) - h; + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +float sdCone( in vec3 p, in vec3 c ) +{ + vec2 q = vec2( length(p.xz), p.y ); + float d1 = -q.y-c.z; + float d2 = max( dot(q,c.xy), q.y); + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdConeSection( in vec3 p, in float h, in float r1, in float r2 ) +{ + float d1 = -p.y - h; + float q = p.y - h; + float si = 0.5*(r1-r2)/h; + float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q ); + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height } +{ + // Tetrahedron = Octahedron - Cube + float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) ); + + float d = 0.0; + d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) )); + d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) )); + d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) )); + d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) )); + float octa = d - h.z; + return max(-box,octa); // Subtraction + } + +float length2( vec2 p ) +{ + return sqrt( p.x*p.x + p.y*p.y ); +} + +float length6( vec2 p ) +{ + p = p*p*p; p = p*p; + return pow( p.x + p.y, 1.0/6.0 ); +} + +float length8( vec2 p ) +{ + p = p*p; p = p*p; p = p*p; + return pow( p.x + p.y, 1.0/8.0 ); +} + +float sdTorus82( vec3 p, vec2 t ) +{ + vec2 q = vec2(length2(p.xz)-t.x,p.y); + return length8(q)-t.y; +} + +float sdTorus88( vec3 p, vec2 t ) +{ + vec2 q = vec2(length8(p.xz)-t.x,p.y); + return length8(q)-t.y; +} + +float sdCylinder6( vec3 p, vec2 h ) +{ + return max( length6(p.xz)-h.x, abs(p.y)-h.y ); +} + +//------------------------------------------------------------------ + +float opS( float d1, float d2 ) +{ + return max(-d2,d1); +} + +vec2 opU( vec2 d1, vec2 d2 ) +{ + return (d1.x0.0 ) tmax = min( tmax, tp1 ); + float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 ); + else tmax = min( tmax, tp2 ); } +#endif + + float t = tmin; + float m = -1.0; + for( int i=0; i<64; i++ ) + { + float precis = 0.0005*t; + vec2 res = map( ro+rd*t ); + if( res.xtmax ) break; + t += res.x; + m = res.y; + } + + if( t>tmax ) m=-1.0; + return vec2( t, m ); +} + + +float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) +{ + float res = 1.0; + float t = mint; + for( int i=0; i<16; i++ ) + { + float h = map( ro + rd*t ).x; + res = min( res, 8.0*h/t ); + t += clamp( h, 0.02, 0.10 ); + if( h<0.001 || t>tmax ) break; + } + return clamp( res, 0.0, 1.0 ); +} + +vec3 calcNormal( in vec3 pos ) +{ + vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; + return normalize( e.xyy*map( pos + e.xyy ).x + + e.yyx*map( pos + e.yyx ).x + + e.yxy*map( pos + e.yxy ).x + + e.xxx*map( pos + e.xxx ).x ); + /* + vec3 eps = vec3( 0.0005, 0.0, 0.0 ); + vec3 nor = vec3( + map(pos+eps.xyy).x - map(pos-eps.xyy).x, + map(pos+eps.yxy).x - map(pos-eps.yxy).x, + map(pos+eps.yyx).x - map(pos-eps.yyx).x ); + return normalize(nor); + */ +} + +float calcAO( in vec3 pos, in vec3 nor ) +{ + float occ = 0.0; + float sca = 1.0; + for( int i=0; i<5; i++ ) + { + float hr = 0.01 + 0.12*float(i)/4.0; + vec3 aopos = nor * hr + pos; + float dd = map( aopos ).x; + occ += -(dd-hr)*sca; + sca *= 0.95; + } + return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ); +} + +// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm +float checkersGradBox( in vec2 p ) +{ + // filter kernel + vec2 w = fwidth(p) + 0.001; + // analytical integral (box filter) + vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; + // xor pattern + return 0.5 - 0.5*i.x*i.y; +} + +vec3 render( in vec3 ro, in vec3 rd ) +{ + vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; + vec2 res = castRay(ro,rd); + float t = res.x; + float m = res.y; + if( m>-0.5 ) + { + vec3 pos = ro + t*rd; + vec3 nor = calcNormal( pos ); + vec3 ref = reflect( rd, nor ); + + // material + col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); + if( m<1.5 ) + { + + float f = checkersGradBox( 5.0*pos.xz ); + col = 0.3 + f*vec3(0.1); + } + + // lighting + float occ = calcAO( pos, nor ); + vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); + vec3 hal = normalize( lig-rd ); + float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); + float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); + float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); + float dom = smoothstep( -0.1, 0.1, ref.y ); + float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 ); + + dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); + dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); + + float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* + dif * + (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); + + vec3 lin = vec3(0.0); + lin += 1.30*dif*vec3(1.00,0.80,0.55); + lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ; + lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ; + lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ; + lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ; + col = col*lin; + col += 10.00*spe*vec3(1.00,0.90,0.70); + + col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); + } + + return vec3( clamp(col,0.0,1.0) ); +} + +mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) +{ + vec3 cw = normalize(ta-ro); + vec3 cp = vec3(sin(cr), cos(cr),0.0); + vec3 cu = normalize( cross(cw,cp) ); + vec3 cv = normalize( cross(cu,cw) ); + return mat3( cu, cv, cw ); +} + +void main() +{ + vec3 tot = vec3(0.0); +#if AA>1 + for( int m=0; m1 + } + tot /= float(AA*AA); +#endif + + finalColor = vec4( tot, 1.0 ); +} + diff --git a/resources/text/fonts/alagard.png b/resources/text/fonts/alagard.png new file mode 100644 index 0000000..e8d15ee Binary files /dev/null and b/resources/text/fonts/alagard.png differ diff --git a/resources/text/fonts/alpha_beta.png b/resources/text/fonts/alpha_beta.png new file mode 100644 index 0000000..6b880bd Binary files /dev/null and b/resources/text/fonts/alpha_beta.png differ diff --git a/resources/text/fonts/jupiter_crash.png b/resources/text/fonts/jupiter_crash.png new file mode 100644 index 0000000..064df10 Binary files /dev/null and b/resources/text/fonts/jupiter_crash.png differ diff --git a/resources/text/fonts/mecha.png b/resources/text/fonts/mecha.png new file mode 100644 index 0000000..88c2df7 Binary files /dev/null and b/resources/text/fonts/mecha.png differ diff --git a/resources/text/fonts/pixantiqua.png b/resources/text/fonts/pixantiqua.png new file mode 100644 index 0000000..d9d3dfa Binary files /dev/null and b/resources/text/fonts/pixantiqua.png differ diff --git a/resources/text/fonts/pixelplay.png b/resources/text/fonts/pixelplay.png new file mode 100644 index 0000000..5d5d563 Binary files /dev/null and b/resources/text/fonts/pixelplay.png differ diff --git a/resources/text/fonts/romulus.png b/resources/text/fonts/romulus.png new file mode 100644 index 0000000..37b8f63 Binary files /dev/null and b/resources/text/fonts/romulus.png differ diff --git a/resources/text/fonts/setback.png b/resources/text/fonts/setback.png new file mode 100644 index 0000000..7331c95 Binary files /dev/null and b/resources/text/fonts/setback.png differ