diff --git a/build.zig b/build.zig index 0f6f29755..b67ff49d9 100644 --- a/build.zig +++ b/build.zig @@ -179,7 +179,11 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. raylib.addIncludePath(b.path("src/platforms")); switch (target.result.os.tag) { .windows => { - try c_source_files.append("src/rglfw.c"); + switch (options.platform) { + .glfw => try c_source_files.append("src/rglfw.c"), + .rgfw, .sdl, .drm => {}, + } + raylib.linkSystemLibrary("winmm"); raylib.linkSystemLibrary("gdi32"); raylib.linkSystemLibrary("opengl32"); @@ -406,6 +410,16 @@ pub fn build(b: *std.Build) !void { lib.installHeader(b.path("src/rlgl.h"), "rlgl.h"); b.installArtifact(lib); + + const examples = b.step("examples", "Build/Install all examples"); + examples.dependOn(try addExamples("audio", b, target, optimize, lib)); + examples.dependOn(try addExamples("core", b, target, optimize, lib)); + examples.dependOn(try addExamples("models", b, target, optimize, lib)); + examples.dependOn(try addExamples("others", b, target, optimize, lib)); + examples.dependOn(try addExamples("shaders", b, target, optimize, lib)); + examples.dependOn(try addExamples("shapes", b, target, optimize, lib)); + examples.dependOn(try addExamples("text", b, target, optimize, lib)); + examples.dependOn(try addExamples("textures", b, target, optimize, lib)); } fn waylandGenerate( @@ -430,3 +444,110 @@ fn waylandGenerate( raylib.step.dependOn(&client_step.step); raylib.step.dependOn(&private_step.step); } + +fn addExamples( + comptime module: []const u8, + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + raylib: *std.Build.Step.Compile, +) !*std.Build.Step { + if (target.result.os.tag == .emscripten) { + @panic("Emscripten building via Zig unsupported"); + } + + const all = b.step(module, "All " ++ module ++ " examples"); + const module_subpath = b.pathJoin(&.{ "examples", module }); + var dir = try std.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true }); + defer if (comptime builtin.zig_version.minor >= 12) dir.close(); + + var iter = dir.iterate(); + while (try iter.next()) |entry| { + if (entry.kind != .file) continue; + const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue; + const name = entry.name[0..extension_idx]; + const path = b.pathJoin(&.{ module_subpath, entry.name }); + + // zig's mingw headers do not include pthread.h + if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue; + + const exe = b.addExecutable(.{ + .name = name, + .target = target, + .optimize = optimize, + }); + exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} }); + exe.linkLibC(); + + // special examples that test using these external dependencies directly + // alongside raylib + if (std.mem.eql(u8, name, "rlgl_standalone")) { + exe.addIncludePath(b.path("src")); + exe.addIncludePath(b.path("src/external/glfw/include")); + if (!hasCSource(raylib.root_module, "rglfw.c")) { + exe.addCSourceFile(.{ .file = b.path("src/rglfw.c"), .flags = &.{} }); + } + } + if (std.mem.eql(u8, name, "raylib_opengl_interop")) { + exe.addIncludePath(b.path("src/external")); + } + + exe.linkLibrary(raylib); + + switch (target.result.os.tag) { + .windows => { + exe.linkSystemLibrary("winmm"); + exe.linkSystemLibrary("gdi32"); + exe.linkSystemLibrary("opengl32"); + + exe.root_module.addCMacro("PLATFORM_DESKTOP", ""); + }, + .linux => { + exe.linkSystemLibrary("GL"); + exe.linkSystemLibrary("rt"); + exe.linkSystemLibrary("dl"); + exe.linkSystemLibrary("m"); + exe.linkSystemLibrary("X11"); + + exe.root_module.addCMacro("PLATFORM_DESKTOP", ""); + }, + .macos => { + exe.linkFramework("Foundation"); + exe.linkFramework("Cocoa"); + exe.linkFramework("OpenGL"); + exe.linkFramework("CoreAudio"); + exe.linkFramework("CoreVideo"); + exe.linkFramework("IOKit"); + + exe.root_module.addCMacro("PLATFORM_DESKTOP", ""); + }, + else => { + @panic("Unsupported OS"); + }, + } + + const install_cmd = b.addInstallArtifact(exe, .{}); + + const run_cmd = b.addRunArtifact(exe); + run_cmd.cwd = b.path(module_subpath); + run_cmd.step.dependOn(&install_cmd.step); + + const run_step = b.step(name, name); + run_step.dependOn(&run_cmd.step); + + all.dependOn(&install_cmd.step); + } + return all; +} + +fn hasCSource(module: *std.Build.Module, name: []const u8) bool { + for (module.link_objects.items) |o| switch (o) { + .c_source_file => |c| if (switch (c.file) { + .src_path => |s| std.ascii.endsWithIgnoreCase(s.sub_path, name), + .generated, .cwd_relative, .dependency => false, + }) return true, + .c_source_files => |s| for (s.files) |c| if (std.ascii.endsWithIgnoreCase(c, name)) return true, + else => {}, + }; + return false; +} diff --git a/build.zig.zon b/build.zig.zon index 73866321b..f18d9db84 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -22,5 +22,6 @@ "build.zig", "build.zig.zon", "src", + "examples", }, } diff --git a/examples/build.zig b/examples/build.zig deleted file mode 100644 index 301381df3..000000000 --- a/examples/build.zig +++ /dev/null @@ -1,110 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); - -// This has been tested to work with zig 0.12.0 -fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) !*std.Build.Step { - if (target.result.os.tag == .emscripten) { - @panic("Emscripten building via Zig unsupported"); - } - - const all = b.step(module, "All " ++ module ++ " examples"); - var dir = try std.fs.cwd().openDir(module, .{ .iterate = true }); - defer if (comptime builtin.zig_version.minor >= 12) dir.close(); - - var iter = dir.iterate(); - while (try iter.next()) |entry| { - if (entry.kind != .file) continue; - const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue; - const name = entry.name[0..extension_idx]; - const path = try std.fs.path.join(b.allocator, &.{ module, entry.name }); - - // zig's mingw headers do not include pthread.h - if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue; - - const exe = b.addExecutable(.{ - .name = name, - .target = target, - .optimize = optimize, - }); - exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} }); - exe.linkLibC(); - exe.addObjectFile(switch (target.result.os.tag) { - .windows => b.path("../zig-out/lib/raylib.lib"), - .linux => b.path("../zig-out/lib/libraylib.a"), - .macos => b.path("../zig-out/lib/libraylib.a"), - .emscripten => b.path("../zig-out/lib/libraylib.a"), - else => @panic("Unsupported OS"), - }); - - exe.addIncludePath(b.path("../src")); - exe.addIncludePath(b.path("../src/external")); - exe.addIncludePath(b.path("../src/external/glfw/include")); - - switch (target.result.os.tag) { - .windows => { - exe.linkSystemLibrary("winmm"); - exe.linkSystemLibrary("gdi32"); - exe.linkSystemLibrary("opengl32"); - - exe.root_module.addCMacro("PLATFORM_DESKTOP", ""); - }, - .linux => { - exe.linkSystemLibrary("GL"); - exe.linkSystemLibrary("rt"); - exe.linkSystemLibrary("dl"); - exe.linkSystemLibrary("m"); - exe.linkSystemLibrary("X11"); - - exe.root_module.addCMacro("PLATFORM_DESKTOP", ""); - }, - .macos => { - exe.linkFramework("Foundation"); - exe.linkFramework("Cocoa"); - exe.linkFramework("OpenGL"); - exe.linkFramework("CoreAudio"); - exe.linkFramework("CoreVideo"); - exe.linkFramework("IOKit"); - - exe.root_module.addCMacro("PLATFORM_DESKTOP", ""); - }, - else => { - @panic("Unsupported OS"); - }, - } - - const install_cmd = b.addInstallArtifact(exe, .{}); - - const run_cmd = b.addRunArtifact(exe); - run_cmd.cwd = b.path(module); - run_cmd.step.dependOn(&install_cmd.step); - - const run_step = b.step(name, name); - run_step.dependOn(&run_cmd.step); - - all.dependOn(&install_cmd.step); - } - return all; -} - -pub fn build(b: *std.Build) !void { - // Standard target options allows the person running `zig build` to choose - // what target to build for. Here we do not override the defaults, which - // means any target is allowed, and the default is native. Other options - // for restricting supported target set are available. - const target = b.standardTargetOptions(.{}); - // Standard optimization options allow the person running `zig build` to select - // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not - // set a preferred release mode, allowing the user to decide how to optimize. - const optimize = b.standardOptimizeOption(.{}); - - const all = b.getInstallStep(); - - all.dependOn(try add_module("audio", b, target, optimize)); - all.dependOn(try add_module("core", b, target, optimize)); - all.dependOn(try add_module("models", b, target, optimize)); - all.dependOn(try add_module("others", b, target, optimize)); - all.dependOn(try add_module("shaders", b, target, optimize)); - all.dependOn(try add_module("shapes", b, target, optimize)); - all.dependOn(try add_module("text", b, target, optimize)); - all.dependOn(try add_module("textures", b, target, optimize)); -} diff --git a/examples/core/core_custom_frame_control.c b/examples/core/core_custom_frame_control.c index 0d149ce9d..a9b98b039 100644 --- a/examples/core/core_custom_frame_control.c +++ b/examples/core/core_custom_frame_control.c @@ -95,7 +95,10 @@ int main(void) DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 60, 20, GRAY); DrawText("PRESS UP | DOWN to CHANGE TARGET FPS", 10, GetScreenHeight() - 30, 20, GRAY); DrawText(TextFormat("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME); - DrawText(TextFormat("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN); + if (deltaTime != 0) + { + DrawText(TextFormat("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN); + } EndDrawing(); diff --git a/examples/core/core_window_flags.c b/examples/core/core_window_flags.c index ec4f6aac6..bb5543b1d 100644 --- a/examples/core/core_window_flags.c +++ b/examples/core/core_window_flags.c @@ -52,7 +52,7 @@ int main(void) int framesCounter = 0; - //SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //---------------------------------------------------------- // Main game loop @@ -97,7 +97,10 @@ int main(void) if (IsWindowState(FLAG_WINDOW_MINIMIZED)) { framesCounter++; - if (framesCounter >= 240) RestoreWindow(); // Restore window after 3 seconds + if (framesCounter >= 240) { + RestoreWindow(); // Restore window after 3 seconds + framesCounter = 0; + } } if (IsKeyPressed(KEY_M)) @@ -163,9 +166,9 @@ int main(void) if (IsWindowState(FLAG_WINDOW_UNDECORATED)) DrawText("[D] FLAG_WINDOW_UNDECORATED: on", 10, 120, 10, LIME); else DrawText("[D] FLAG_WINDOW_UNDECORATED: off", 10, 120, 10, MAROON); if (IsWindowState(FLAG_WINDOW_HIDDEN)) DrawText("[H] FLAG_WINDOW_HIDDEN: on", 10, 140, 10, LIME); - else DrawText("[H] FLAG_WINDOW_HIDDEN: off", 10, 140, 10, MAROON); + else DrawText("[H] FLAG_WINDOW_HIDDEN: off (hides for 3 seconds)", 10, 140, 10, MAROON); if (IsWindowState(FLAG_WINDOW_MINIMIZED)) DrawText("[N] FLAG_WINDOW_MINIMIZED: on", 10, 160, 10, LIME); - else DrawText("[N] FLAG_WINDOW_MINIMIZED: off", 10, 160, 10, MAROON); + else DrawText("[N] FLAG_WINDOW_MINIMIZED: off (restores after 3 seconds)", 10, 160, 10, MAROON); if (IsWindowState(FLAG_WINDOW_MAXIMIZED)) DrawText("[M] FLAG_WINDOW_MAXIMIZED: on", 10, 180, 10, LIME); else DrawText("[M] FLAG_WINDOW_MAXIMIZED: off", 10, 180, 10, MAROON); if (IsWindowState(FLAG_WINDOW_UNFOCUSED)) DrawText("[G] FLAG_WINDOW_UNFOCUSED: on", 10, 200, 10, LIME); diff --git a/parser/output/raylib_api.json b/parser/output/raylib_api.json index f5872ec8a..567f9d980 100644 --- a/parser/output/raylib_api.json +++ b/parser/output/raylib_api.json @@ -3280,7 +3280,7 @@ }, { "name": "RestoreWindow", - "description": "Set window state: not minimized/maximized", + "description": "Restore window from being minimized/maximized", "returnType": "void" }, { diff --git a/parser/output/raylib_api.lua b/parser/output/raylib_api.lua index 81dd7f932..75c328da6 100644 --- a/parser/output/raylib_api.lua +++ b/parser/output/raylib_api.lua @@ -3223,7 +3223,7 @@ return { }, { name = "RestoreWindow", - description = "Set window state: not minimized/maximized", + description = "Restore window from being minimized/maximized", returnType = "void" }, { diff --git a/parser/output/raylib_api.txt b/parser/output/raylib_api.txt index c74a79a5f..0b0bf86c1 100644 --- a/parser/output/raylib_api.txt +++ b/parser/output/raylib_api.txt @@ -1085,7 +1085,7 @@ Function 017: MinimizeWindow() (0 input parameters) Function 018: RestoreWindow() (0 input parameters) Name: RestoreWindow Return type: void - Description: Set window state: not minimized/maximized + Description: Restore window from being minimized/maximized No input parameters Function 019: SetWindowIcon() (1 input parameters) Name: SetWindowIcon diff --git a/parser/output/raylib_api.xml b/parser/output/raylib_api.xml index b7af0c41a..ed6880dec 100644 --- a/parser/output/raylib_api.xml +++ b/parser/output/raylib_api.xml @@ -720,7 +720,7 @@ - + diff --git a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml index 0fada9c4f..4c6362162 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +++ b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml @@ -65,7 +65,7 @@ - + diff --git a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h index c6b34b777..89cce66f9 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +++ b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h @@ -20,7 +20,7 @@ RLAPI void ToggleFullscreen(void); // Toggle wind RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable -RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized +RLAPI void RestoreWindow(void); // Restore window from being minimized/maximized RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit) RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit) RLAPI void SetWindowTitle(const char *title); // Set title for window diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index eac7f3256..ddf7802ba 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -337,7 +337,7 @@ void MinimizeWindow(void) TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform"); } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform"); diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 19ee78bf4..a08033a93 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -292,7 +292,7 @@ void MinimizeWindow(void) glfwIconifyWindow(platform.handle); } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index aafe28a66..9a5841c83 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -339,7 +339,7 @@ void MinimizeWindow(void) RGFW_window_minimize(platform.window); } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { if (!(CORE.Window.flags & FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 97145b9dd..6e62838e3 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -508,7 +508,7 @@ void MinimizeWindow(void) if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { SDL_RestoreWindow(platform.window); @@ -1670,7 +1670,7 @@ void PollInputEvents(void) { int jid = event.jdevice.which; // Joystick device index - if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) + if (CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) { platform.gamepad[jid] = SDL_GameControllerOpen(jid); platform.gamepadId[jid] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[jid])); diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index baa51a8d8..74af3d453 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -277,7 +277,7 @@ void MinimizeWindow(void) TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform"); } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform"); diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index 42c243746..36629fc69 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -114,7 +114,7 @@ void MinimizeWindow(void) TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform"); } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform"); diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 0972e9680..b3bb43b5b 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -350,7 +350,7 @@ void MinimizeWindow(void) TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform"); } -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized void RestoreWindow(void) { if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) diff --git a/src/raylib.h b/src/raylib.h index 7919db775..fc949a02d 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -987,7 +987,7 @@ RLAPI void ToggleFullscreen(void); // Toggle wind RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable -RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized +RLAPI void RestoreWindow(void); // Restore window from being minimized/maximized RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit) RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit) RLAPI void SetWindowTitle(const char *title); // Set title for window diff --git a/src/rlgl.h b/src/rlgl.h index 27ce8f9e3..1516354e3 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3684,7 +3684,7 @@ unsigned char *rlReadScreenPixels(int width, int height) // Flip image vertically! // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! - for (int y = height - 1; y >= height / 2; y--) + for (int y = height - 1; y >= height/2; y--) { for (int x = 0; x < (width*4); x += 4) {